* arch/tms320: add TMS320C54x disassembly support
Add a C54x instruction decoder that reuses the shared C55x decode engine
(c55_decode/c55_format) via the C55ArchDesc plug-in interface, rather than
duplicating the matcher/formatter. Disassembly only for now (.lift = NULL).
Engine changes (c55_ir.c/.h):
- add C55ArchDesc.words_le so the decoder can byte-swap the little-endian
16-bit instruction words used by the C54x COFF object format;
- add a self-contained C54x memory-operand renderer (direct @dma, MMR,
indirect *ARx with all post-modify modes, *ARx(lk) const-index, *(lk)
ABS16 absolute and circular '%' addressing) and bare-hex immediates;
- add C55Operand.circular for the '%' suffix and C55Operand.space_join
for the space-separated second half of a C54x parallel instruction;
- extend the data-memory operand-field analysis (register, base pointer,
displacement, direction, referenced size) to the LOAD/STORE op types the
C54x ld/st family uses, in addition to the C55x MOV form.
The C54x decoder (isa/tms320/c54x/c54x.c) covers the complete documented
instruction set - all 117 mnemonics of the SPRU172 opcode map, in every
documented encoding form:
- load/store/move, integer and logical ALU ops in every addressing form
(Smem, #lk, dual-accumulator, Xmem/Ymem, TS/ASM/SHIFT-shifted, the
shift-by-16 and #lk,16 long-immediate forms, and the two-word
Smem,SHIFT form whose operation selector lives in the second word);
- the full multiply/MAC family: Smem, #lk, program-memory, squaring,
multiply-by-A, signed-unsigned and the dual-operand MAC[R]/MAS[R]
Xmem,Ymem forms;
- the parallel (dual-operation) class rendered "op1 .. || op2 .." -
ST||ADD/SUB/LD/MPY/MAC[R]/MAS[R], ST||LD T and LD||MAC[R]/MAS[R];
- double/long-word (Lmem) add/subtract, the unary accumulator ops
(exp/norm/abs/neg/rnd/sat/min/max/rol/ror/sftc/cmpl/...);
- control flow with the separate delayed (bd/calld/bcd/banzd/fcalad/...)
variants, conditional return/execute (rc[d]/xc) and the multi-condition
"tc, c"-style combinable condition fields, repeats (incl. rpt #lk),
conditional stores, I/O port access, status-bit set/clear and the
non-linear idle encoding.
Operands resolve to their architectural names - the full memory-mapped
register file (AR0-AR7, the accumulator AL/AH/AG/BL/BH/BG halves, T, TRN,
SP, BK, BRC/RSA/REA, IMR/IFR, PMST, XPC), the ST0/ST1 status bits and the
named condition codes; the memory-mapped-register operand is kept single
word (its long-offset modes are not legal). The analyzer classifies every
instruction (op->type, op->id), resolves branch/call targets and the stack
effect of calls/returns/pushes, and exposes operand details: the register,
base pointer, displacement and access direction of data-memory loads and
stores, and the target register of indirect branches/calls.
All encodings were verified byte-exact against the TI asm500 assembler,
and every decoded instruction re-assembles to an identical encoding (a
full-opcode-space disassemble/reassemble round-trip is stable). A 297-case
disasm test suite and an analysis test suite (opcode classification, branch
and call targets, stack effects, memory-operand fields, data-immediate values, the register
profile, named instruction ids and COFF binary-fixture function discovery)
are added, and the real-world emulateme C54x .text decodes cleanly.
* arch/tms320: add TMS320C54x RzIL lifting
Lift the C54x integer core to RzIL so emulation and IL-based analysis work
for C54x as they already do for C55x/C55x+.
- Register profile: C54x previously fell through to the C64x profile
(a0-a31, =PC pce1), wrong for the A/B accumulator core. Add a proper
C54x profile: the two 40-bit accumulators A/B (with the L/H 16-bit and
G 8-bit guard slices overlapping their parent), AR0-AR7, T/TRN, SP, DP,
BK, ST0/ST1/PMST, BRC/RSA/REA, IMR/IFR, XPC and a 24-bit PC.
- IL VM config: tms320_c54x_il_config() binds the canonical registers; the
accumulator slices stay unbound, the lifter expresses them as bit-slices
of A/B so they never desynchronise.
- Lifter (C55ArchDesc::lift hook, dispatched by c55_lift): the no-shift
forms of LD/LDU/LDR/LDM, ADD/SUB/AND/OR/XOR, STL/STH/STLM/STM, the mvd*
memory-to-memory moves, the DLD/DST 32-bit double-word load/store (high
word at the lower address), PSHM/POPM and RET. Shift/round/saturate
variants are left unlifted (their shift count is carried only as a
display string); the engine's generic EA/read/write/post-modify helpers
are reused for the addressing modes.
Tested via two new RzIL VM blocks in test/db/rzil/tms320: a register/
immediate/memory execute test, and an end-to-end emulation of the
emulateme binary's _decrypt (a UART hex-writer) showing the IL VM emits
the hex digits and advances the write position.
---------
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>