// SPDX-FileCopyrightText: 2026 RizinOrg <info@rizin.re>
// SPDX-License-Identifier: LGPL-3.0-only

#ifndef RZ_TMS320_C54X_H
#define RZ_TMS320_C54X_H

#include "../c55_ir.h"
#include <rz_analysis.h>

#ifdef __cplusplus
extern "C" {
#endif

/// TMS320C54x instruction identifiers (the C55Insn.id / RzAnalysisOp.id values).
enum {
	C54X_INS_INVALID = 0,
	C54X_INS_NOP,
	C54X_INS_B,
	C54X_INS_BACC,
	C54X_INS_CALL,
	C54X_INS_CC,
	C54X_INS_RET,
	C54X_INS_RETE,
	C54X_INS_RETF,
	C54X_INS_FB,
	C54X_INS_FBACC,
	C54X_INS_FCALL,
	C54X_INS_FRET,
	C54X_INS_FRETE,
	C54X_INS_RESET,
	C54X_INS_TRAP,
	C54X_INS_INTR,
	C54X_INS_IDLE,
	C54X_INS_SSBX,
	C54X_INS_RSBX,
	C54X_INS_RPT,
	C54X_INS_RPTB,
	C54X_INS_RPTZ,
	C54X_INS_LD,
	C54X_INS_ADD,
	C54X_INS_SUB,
	C54X_INS_PSHM,
	C54X_INS_POPM,
	C54X_INS_PSHD,
	C54X_INS_POPD,
	C54X_INS_STL,
	C54X_INS_STH,
	C54X_INS_STLM,
	C54X_INS_ST,
	C54X_INS_STM,
	C54X_INS_AND,
	C54X_INS_OR,
	C54X_INS_XOR,
	C54X_INS_MVDD,
	C54X_INS_MVDK,
	C54X_INS_MVDM,
	C54X_INS_MVKD,
	C54X_INS_MVMD,
	C54X_INS_MVMM,
	C54X_INS_MVPD,
	C54X_INS_MAR,
	C54X_INS_DELAY,
	C54X_INS_BC,
	C54X_INS_BANZ,
	C54X_INS_CALA,
	C54X_INS_FRAME,
	C54X_INS_BITF,
	C54X_INS_CMPM,
	C54X_INS_MPY,
	C54X_INS_BD,
	C54X_INS_CALLD,
	C54X_INS_RETD,
	C54X_INS_RETED,
	C54X_INS_RETFD,
	C54X_INS_FBD,
	C54X_INS_FCALLD,
	C54X_INS_FRETD,
	C54X_INS_FRETED,
	C54X_INS_BCD,
	C54X_INS_CCD,
	C54X_INS_BANZD,
	C54X_INS_RPTBD,
	C54X_INS_BACCD,
	C54X_INS_CALAD,
	C54X_INS_LDM,
	C54X_INS_LTD,
	C54X_INS_DST,
	C54X_INS_DADD,
	C54X_INS_DSUB,
	C54X_INS_DSUBT,
	C54X_INS_DLD,
	C54X_INS_MAC,
	C54X_INS_MACD,
	C54X_INS_MAS,
	C54X_INS_ADDC,
	C54X_INS_SUBB,
	C54X_INS_NEG,
	C54X_INS_ABS,
	C54X_INS_EXP,
	C54X_INS_NORM,
	C54X_INS_SFTL,
	C54X_INS_SFTA,
	C54X_INS_CMPR,
	C54X_INS_ABDST,
	C54X_INS_ADDM,
	C54X_INS_ANDM,
	C54X_INS_ORM,
	C54X_INS_XORM,
	C54X_INS_FIRS,
	C54X_INS_LMS,
	C54X_INS_MAX,
	C54X_INS_MIN,
	C54X_INS_MPYA,
	C54X_INS_MVDP,
	C54X_INS_POLY,
	C54X_INS_READA,
	C54X_INS_WRITA,
	C54X_INS_RND,
	C54X_INS_ROL,
	C54X_INS_ROLTC,
	C54X_INS_ROR,
	C54X_INS_SAT,
	C54X_INS_SFTC,
	C54X_INS_SQDST,
	C54X_INS_SQUR,
	C54X_INS_SQURA,
	C54X_INS_SQURS,
	C54X_INS_BITT,
	C54X_INS_CMPL,
	C54X_INS_FCALA,
	C54X_INS_FCALAD,
	C54X_INS_MPYU,
	C54X_INS_MASA,
	C54X_INS_BIT,
	C54X_INS_SACCD,
	C54X_INS_SRCCD,
	C54X_INS_STRCD,
	C54X_INS_PORTR,
	C54X_INS_PORTW,
	C54X_INS_MASAR,
	C54X_INS_ADDS,
	C54X_INS_SUBS,
	C54X_INS_SUBC,
	C54X_INS_LDU,
	C54X_INS_LDR,
	C54X_INS_CMPS,
	C54X_INS_DADST,
	C54X_INS_DRSUB,
	C54X_INS_DSADT,
	C54X_INS_MACA,
	C54X_INS_MACAR,
	C54X_INS_MACP,
	C54X_INS_MACSU,
	C54X_INS_MACR,
	C54X_INS_MASR,
	C54X_INS_RC,
	C54X_INS_RCD,
	C54X_INS_XC,
};

/// TMS320C54x special-register indices: the order of the \ref c54x_special_ri
/// table (BRC/RSA/REA, IMR/IFR, the AL/AH/AG and BL/BH/BG accumulator slices,
/// XPC). Shared by the decoder (operand resolution) and the lifter (which
/// recognises the accumulator-slice registers via these ids).
enum {
	C54X_SPR_BRC = 0,
	C54X_SPR_RSA,
	C54X_SPR_REA,
	C54X_SPR_IMR,
	C54X_SPR_IFR,
	C54X_SPR_AL,
	C54X_SPR_AH,
	C54X_SPR_AG,
	C54X_SPR_BL,
	C54X_SPR_BH,
	C54X_SPR_BG,
	C54X_SPR_XPC,
	C54X_SPR_COUNT
};

/// TMS320C54x disassembly, plugged into the shared C55 decode engine.
extern const C55ArchDesc c54x_arch_desc;

/// Analysis entry point: decode once, fill the RzAnalysisOp (disasm only, no IL).
RZ_IPI int tms320_c54x_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr,
	const ut8 *buf, int len, RzAnalysisOpMask mask);

/// RzIL VM configuration (register bindings) for the C54x core.
RZ_IPI RzAnalysisILConfig *tms320_c54x_il_config(RZ_NONNULL RzAnalysis *analysis);

/// Per-instruction RzIL lifter: the C55ArchDesc::lift hook wired into
/// \ref c54x_arch_desc and dispatched by c55_lift. Defined in c54x_il.c;
/// returns NULL for instructions that are not (yet) lifted.
RZ_IPI RzILOpEffect *c54x_lift(const C55Insn *insn, ut64 pc);

#ifdef __cplusplus
}
#endif

#endif /* RZ_TMS320_C54X_H */
