Builds on the shared decode-IR engine to lift a broad set of common C55x and
C55x+ (Ryujin) instruction forms that were previously left without RzIL,
deriving the exact semantics from the TI C55x+ references (SWPU104 / SWPU086).
Control flow and addressing:
- ret / reti / retcc: return address read from the top of stack, SP popped by
two words, control transferred to it (retcc guarded by its predicate).
- 24-bit XAR correctness on C55x+ (XAR0-15, XSP, XSSP, XDP, XCDP) in the
register table, the IL-VM profile and the pointer-arithmetic width, enabling
the 24-bit amov address immediate; classic C55x keeps its 23-bit file.
- long constant-index and 16-bit-absolute addressing modes, memory-to-memory
copy, shifted memory loads (uns()/signed, immediate shift), and the
memory-mapped-register moves mov reg,mmap(@reg) / mov mmap(@reg),reg.
- push/pop of accumulator sub-register halves and dbl(xarN) pointer pairs.
Arithmetic, logical, shift and bit operations:
- sub-register add/sub on a 16-bit accumulator slice, for the immediate and
register forms: a .L destination updates [15:0], a .H destination updates
[39:16] sign-extended through the guard (SWPU104 1.5.1).
- bitwise and/or/xor with a 16-bit source (half or AR/T) into a full
accumulator, zero-extending the operands to 40 bits (SWPU104 6.6.1); the
memory-source bitwise forms into full and half destinations; and the
shift-ALU forms <op> ACx.<sub> << #S6, ACy.<sub> on the 16-bit slice.
- memory-source add (including a 16-bit half addend and the reverse-subtract
sub ACx.<sub>, Smem, ACy.<sub>), the 32-bit dbl(Lmem) add/sub forms
(ACy = ACx +/- dbl(Lmem) and the reversed ACy = dbl(Lmem) - ACx), and the
memory-destination immediate RMW add/sub #k, Smem.
- register bit ops bclr / bset / bnot @#k, ACx[.h/.l] / ARx: clear, set or
toggle bit k of the register, the bit number taken relative to the
addressed sub-register (a .h operand targets bit k+16, the guard k+32).
- bitwise not ACx.<sub>/ARx into an accumulator half or a 16-bit register
(not ACx.l, ARy), the half-register and short (0x7b #1/#-1) sftl/sfts
including register-count shifts, and btst @#k, ACx.l/.h, TCy.
This also corrects an op_type-fallback mis-lift: on C55x+ several non-move
instructions (round, sat/satr, the mant/nexp helper) and the bit-field
extract/expand bfxtr/bfxpa were typed as a move and so were lifted as a plain
register copy. round and sat/satr now carry their lops and reach the existing
rounding / saturation handlers (matching C55x); mant/nexp, bfxtr/bfxpa, the
operand-less sat and the register-indexed memory bit ops (bclr/bset/bnot Baddr)
are marked decode-only (no modelled data effect) so the fallback can no longer
guess at them.
Also fixes a FIRSADD/FIRSSUB lifting bug: the Cmem operand was not converted
from AR to XAR before emitting its pointer post-modify, so a post-modified Cmem
(e.g. firssub *ar3-, *ar5-, *ar6-, ...) produced an invalid 16-bit-vs-24-bit
subtract that failed IL validation; Cmem is now widened like Xmem/Ymem.
The multiply/MAC family stays unlifted by design, as do the flag-predicate
retcc forms (whose condition register field is not represented by the decoder)
and the software-interrupt intr (which would need the interrupt-vector base);
the correct-or-NULL contract test asserts a representative deferred form.
The disassembler tests for both variants are extended with the expected IL for
every form that lifts -- previously the optional IL field was omitted on many
lines whose lift already existed, leaving the lifting unchecked -- so the asm
suite now validates RzIL for all lifted C55x / C55x+ instructions, not just a
subset.
Measured on a 5 MB C55x+ firmware image (16k-instruction sample) RzIL coverage
rises from 82% to 99.4% of decoded instructions, the remaining tail being the
multiply/MAC family and the deferred forms above.
790 lines
15 KiB
Text
790 lines
15 KiB
Text
NAME=c55x+ analysis: register profile (PC alias resolves)
|
|
FILE==
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
arp~^=PC
|
|
EOF
|
|
EXPECT=<<EOF
|
|
=PC pc
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis: opcode classification (batched)
|
|
FILE=malloc://64
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
wx 20 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^size
|
|
wx 21 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^size
|
|
wx 2021 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^size
|
|
ao 1 @ 1~^type
|
|
ao 1 @ 0~^size
|
|
wx 68002d @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
wx 690028 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
ao 1 @ 0~^fail
|
|
wx 6a2320 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
ao 1 @ 0~^fail
|
|
wx 9a000020 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
ao 1 @ 0~^fail
|
|
wx 9b000020 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
wx 9c000020 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
wx 9d000020 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
wx d800000020 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
ao 1 @ 0~^fail
|
|
wx d900000020 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
wx dba0210010 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^fail
|
|
wx 0240 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^fail
|
|
wx 0280 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^fail
|
|
wx 740020 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 7b0001 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 740081 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 770030 @ 0
|
|
ao 1 @ 0~^type
|
|
wx c5000000ff @ 0
|
|
ao 1 @ 0~^type
|
|
wx c50181000f @ 0
|
|
ao 1 @ 0~^type
|
|
wx c5a3230001 @ 0
|
|
ao 1 @ 0~^type
|
|
wx a4323300 @ 0
|
|
ao 1 @ 0~^type
|
|
wx a6818133 @ 0
|
|
ao 1 @ 0~^type
|
|
wx a7810131 @ 0
|
|
ao 1 @ 0~^type
|
|
wx c832803400 @ 0
|
|
ao 1 @ 0~^type
|
|
wx c832003400 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 2461e400 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 713233 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0d25 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 621240 @ 0
|
|
ao 1 @ 0~^type
|
|
wx ae21000b @ 0
|
|
ao 1 @ 0~^type
|
|
wx 760000 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 760080 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 768100 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 768180 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0020 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 00c0 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0305 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0344 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0a2a @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0a0a @ 0
|
|
ao 1 @ 0~^type
|
|
wx ff @ 0
|
|
ao 1 @ 0~^type
|
|
wx 6a0500200000000000 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^jump
|
|
ao 1 @ 0~^fail
|
|
wx 0380 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 03c0 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^family
|
|
wx 035f @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^val
|
|
wx 5811223344 @ 0
|
|
ao 1 @ 0~^type
|
|
wx ac010005 @ 0
|
|
ao 1 @ 0~^type
|
|
wx b401020304 @ 0
|
|
ao 1 @ 0~^type
|
|
wx b600112233 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 8c80112233 @ 0
|
|
ao 1 @ 0~^type
|
|
wx c000010002 @ 0
|
|
ao 1 @ 0~^type
|
|
wx d000abcd12 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 2e10 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0b11 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^family
|
|
wx 2300 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^family
|
|
wx c6112233 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0380 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 03c0 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^family
|
|
wx 035f @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^val
|
|
wx 5811223344 @ 0
|
|
ao 1 @ 0~^type
|
|
wx ac010005 @ 0
|
|
ao 1 @ 0~^type
|
|
wx b401020304 @ 0
|
|
ao 1 @ 0~^type
|
|
wx b600112233 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 8c80112233 @ 0
|
|
ao 1 @ 0~^type
|
|
wx c000010002 @ 0
|
|
ao 1 @ 0~^type
|
|
wx d000abcd12 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 2e10 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 0b11 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^family
|
|
wx 2300 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^family
|
|
wx c6112233 @ 0
|
|
ao 1 @ 0~^type
|
|
EOF
|
|
EXPECT=<<EOF
|
|
type: nop
|
|
size: 1
|
|
type: ret
|
|
size: 1
|
|
type: nop
|
|
size: 1
|
|
type: ret
|
|
size: 1
|
|
type: jmp
|
|
jump: 0x00000030
|
|
type: call
|
|
jump: 0x0000002b
|
|
fail: 0x00000003
|
|
type: cjmp
|
|
jump: 0x00000026
|
|
fail: 0x00000003
|
|
type: cjmp
|
|
jump: 0x00000004
|
|
fail: 0x00000004
|
|
type: ccall
|
|
jump: 0x00000004
|
|
type: jmp
|
|
jump: 0x00000020
|
|
type: call
|
|
jump: 0x00000020
|
|
type: cjmp
|
|
jump: 0x00000000
|
|
fail: 0x00000005
|
|
type: ccall
|
|
jump: 0x00000000
|
|
type: cjmp
|
|
fail: 0x00000005
|
|
type: ujmp
|
|
fail: 0x00000002
|
|
type: ucall
|
|
fail: 0x00000002
|
|
type: add
|
|
type: add
|
|
type: sub
|
|
type: mov
|
|
type: and
|
|
type: or
|
|
type: xor
|
|
type: cmp
|
|
type: shl
|
|
type: shl
|
|
type: mul
|
|
type: mul
|
|
type: push
|
|
type: pop
|
|
type: push
|
|
type: lea
|
|
type: lea
|
|
type: null
|
|
type: sub
|
|
type: cmp
|
|
type: cmp
|
|
type: nop
|
|
type: ret
|
|
type: swi
|
|
type: trap
|
|
type: mov
|
|
type: mov
|
|
type: ill
|
|
type: cjmp
|
|
jump: 0x00000008
|
|
fail: 0x00000003
|
|
type: ill
|
|
type: trap
|
|
family: cpu
|
|
type: trap
|
|
val: 0x0000001f
|
|
type: mov
|
|
type: mov
|
|
type: mov
|
|
type: add
|
|
type: add
|
|
type: add
|
|
type: mov
|
|
type: ill
|
|
type: trap
|
|
family: cpu
|
|
type: trap
|
|
family: cpu
|
|
type: ill
|
|
type: ill
|
|
type: trap
|
|
family: cpu
|
|
type: trap
|
|
val: 0x0000001f
|
|
type: mov
|
|
type: mov
|
|
type: mov
|
|
type: add
|
|
type: add
|
|
type: add
|
|
type: mov
|
|
type: ill
|
|
type: trap
|
|
family: cpu
|
|
type: trap
|
|
family: cpu
|
|
type: ill
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis (no debug): 18_full_program.obj -- 6-function callgraph, stack tracking
|
|
FILE=bins/tms320/coff2/18_full_program.obj
|
|
ARGS=-A
|
|
CMDS=<<EOF
|
|
iI~^arch
|
|
iI~^cpu
|
|
afl~?
|
|
afs @ sym._main
|
|
avgl~?
|
|
afb @ sym._main~?
|
|
afi @ sym._main~^num-bbs
|
|
afi @ sym._main~^stackframe
|
|
afi @ sym._main~^call-refs
|
|
EOF
|
|
EXPECT=<<EOF
|
|
arch tms320
|
|
cpu c55x+
|
|
6
|
|
int main(int argc, char **argv, char **envp);
|
|
0
|
|
1
|
|
num-bbs: 1
|
|
stackframe: 6
|
|
call-refs: 0x00000034 C 0x00000042 C 0x0000004c C
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis (no debug): 19_emulateme_nostd.obj -- multi-BB cyclomatic > 1
|
|
FILE=bins/tms320/coff2/19_emulateme_nostd.obj
|
|
ARGS=-A
|
|
CMDS=<<EOF
|
|
iI~^cpu
|
|
afl~?
|
|
afs @ sym._main
|
|
avgl~?
|
|
afb @ sym._main~?
|
|
afi @ sym._main~^num-bbs
|
|
afi @ sym._main~^stackframe
|
|
afi @ sym._main~^cyclomatic-complexity
|
|
EOF
|
|
EXPECT=<<EOF
|
|
cpu c55x+
|
|
5
|
|
int main(int argc, char **argv, char **envp);
|
|
0
|
|
5
|
|
num-bbs: 5
|
|
stackframe: 6
|
|
cyclomatic-complexity: 5
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis (no debug): 17_data_layout.obj -- section table + functions
|
|
FILE=bins/tms320/coff2/17_data_layout.obj
|
|
ARGS=-A
|
|
CMDS=<<EOF
|
|
iI~^cpu
|
|
afl~?
|
|
iSq~^0x~?
|
|
iSq~^0x~text~?
|
|
iSq~^0x~bss~?
|
|
iSq~^0x~const~?
|
|
avgl~?
|
|
EOF
|
|
EXPECT=<<EOF
|
|
cpu c55x+
|
|
4
|
|
5
|
|
1
|
|
1
|
|
1
|
|
0
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis (no debug): 15_fir_filter.obj -- pdf reflines and MAC classification
|
|
FILE=bins/tms320/coff2/15_fir_filter.obj
|
|
ARGS=-A
|
|
CMDS=<<EOF
|
|
iI~^cpu
|
|
afl~?
|
|
afs @ sym._fir_step
|
|
afb @ sym._fir_step~?
|
|
afi @ sym._fir_step~^cyclomatic-cost
|
|
afi @ sym._fir_step~^cyclomatic-complexity
|
|
EOF
|
|
EXPECT=<<EOF
|
|
cpu c55x+
|
|
4
|
|
void sym._fir_step();
|
|
1
|
|
cyclomatic-cost: 0
|
|
cyclomatic-complexity: 1
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis: RzAnalysisOp operand fields (reg / ireg / disp / direction)
|
|
FILE==
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
# B AC0 -- 0x02 with bit 7 clear, low 2 bits select AC; reg=none, ireg=ac0
|
|
wx 0200 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^ireg
|
|
ao 1 @ 0~^direction
|
|
# CALL AC2 -- 0x02 with bit 7 set; ireg=ac2, stackptr=2
|
|
wx 0282 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^ireg
|
|
ao 1 @ 0~^stackptr
|
|
ao 1 @ 0~^direction
|
|
# INTR 5 -- 0x03 with high 2 bits=00; val=5, family=cpu
|
|
wx 0305 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^val
|
|
ao 1 @ 0~^family
|
|
# TRAP 7 -- 0x03 with high 2 bits=01; val=7, family=cpu
|
|
wx 0347 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^val
|
|
ao 1 @ 0~^family
|
|
# RETCC -- 0x08; stackptr=-2, reg=sp
|
|
wx 0840 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^reg
|
|
ao 1 @ 0~^stackptr
|
|
# PSHBOTH -- 0x0d; reg=sp, direction=write, stackptr=2
|
|
wx 0d25 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^reg
|
|
ao 1 @ 0~^direction
|
|
ao 1 @ 0~^stackptr
|
|
# PSH dbl -- 0x0e; stackptr=2
|
|
wx 0e25 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^reg
|
|
ao 1 @ 0~^direction
|
|
ao 1 @ 0~^stackptr
|
|
# POP dbl -- 0x0f; stackptr=-2
|
|
wx 0f25 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^reg
|
|
ao 1 @ 0~^direction
|
|
ao 1 @ 0~^stackptr
|
|
# RET -- 0x21; reg=sp, stackptr=-2
|
|
wx 21 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^reg
|
|
ao 1 @ 0~^stackptr
|
|
# RETI -- 0x00 0xc0; reg=sp, stackptr=-2
|
|
wx 00c0 @ 0
|
|
ao 1 @ 0~^type
|
|
ao 1 @ 0~^reg
|
|
ao 1 @ 0~^stackptr
|
|
EOF
|
|
EXPECT=<<EOF
|
|
type: ujmp
|
|
ireg: ac0
|
|
direction: exec
|
|
type: ucall
|
|
ireg: ac2
|
|
stackptr: 2
|
|
direction: exec
|
|
type: swi
|
|
val: 0x00000005
|
|
family: cpu
|
|
type: trap
|
|
val: 0x00000007
|
|
family: cpu
|
|
type: cret
|
|
reg: sp
|
|
stackptr: -2
|
|
type: push
|
|
reg: sp
|
|
direction: write
|
|
stackptr: 2
|
|
type: push
|
|
reg: sp
|
|
direction: write
|
|
stackptr: 2
|
|
type: pop
|
|
reg: sp
|
|
direction: read
|
|
stackptr: -2
|
|
type: ret
|
|
reg: sp
|
|
stackptr: -2
|
|
type: ret
|
|
reg: sp
|
|
stackptr: -2
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis: stackframe tracking propagates to afi (high-level summariser picks up stackptr)
|
|
FILE=bins/tms320/coff2/16_compiler_style.obj
|
|
ARGS=-A
|
|
CMDS=<<EOF
|
|
# Each function's prologue/epilogue should produce the right stackframe.
|
|
# This verifies the analyzer's stackop/stackptr fields on AADD K8,SP
|
|
# (case 0x0c) and PSH/POP families reach the function summariser.
|
|
afi @ sym._w~^stackframe:0
|
|
afi @ sym._setup_locals~^stackframe:0
|
|
afi @ sym._three_arg_caller~^stackframe:0
|
|
afi @ sym._no_locals~^stackframe:0
|
|
EOF
|
|
EXPECT=<<EOF
|
|
stackframe: 0
|
|
stackframe: 2
|
|
stackframe: 6
|
|
stackframe: 0
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis: named instruction id (op->id = TMS320C55_INS_*)
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
# op->id carries the named TMS320C55InsID resolved by the C55x+ token
|
|
# decoder (positions in tms320_insn.h): AADD=3, INTR=41, NOP=61, POP=64,
|
|
# PSH=66, RET=69, RETI=71, TRAP=98.
|
|
wx 21 @ 0
|
|
ao 1 @ 0~id
|
|
wx 0e00 @ 0
|
|
ao 1 @ 0~id
|
|
wx 0f00 @ 0
|
|
ao 1 @ 0~id
|
|
wx 0310 @ 0
|
|
ao 1 @ 0~id
|
|
wx 0350 @ 0
|
|
ao 1 @ 0~id
|
|
wx 00c0 @ 0
|
|
ao 1 @ 0~id
|
|
wx 20 @ 0
|
|
ao 1 @ 0~id
|
|
wx 0c10 @ 0
|
|
ao 1 @ 0~id
|
|
EOF
|
|
EXPECT=<<EOF
|
|
id: 69
|
|
id: 66
|
|
id: 64
|
|
id: 41
|
|
id: 98
|
|
id: 71
|
|
id: 61
|
|
id: 1
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis: regression - decoded-id type override
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
# These leading bytes encode multiple instructions disambiguated by
|
|
# operand bits; the decoded TMS320C55_INS_* id drives the final type.
|
|
# 0x7B byte1 bit7 set -> LD (mov); clear -> add/sub by byte2 bit7
|
|
# (TI SWPU104 Table 7-2, opcode 01111011).
|
|
wx 7b8000 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 7b3000 @ 0
|
|
ao 1 @ 0~^type
|
|
wx 7b3081 @ 0
|
|
ao 1 @ 0~^type
|
|
# 0xD2 mar(XDAa op k24): address-register modify, classified lea like
|
|
# AADD/AMOV (TI SWPU104 Table 7-2, opcode 11010010). amov and asub forms
|
|
# both resolve to lea.
|
|
wx d280000000 @ 0
|
|
ao 1 @ 0~^type
|
|
wx d200000000 @ 0
|
|
ao 1 @ 0~^type
|
|
EOF
|
|
EXPECT=<<EOF
|
|
type: mov
|
|
type: add
|
|
type: sub
|
|
type: lea
|
|
type: lea
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis: pdf render - _c_strlen (loop, fwd+back bcc reflines)
|
|
FILE=bins/tms320/coff2/19_emulateme_nostd.obj
|
|
ARGS=-A
|
|
CMDS=<<EOF
|
|
e analysis.cpu=c55x+
|
|
pdf @ sym._c_strlen
|
|
EOF
|
|
EXPECT=<<EOF
|
|
; CALL XREF from sym._main @ 0xc9
|
|
/ sym._c_strlen();
|
|
| 0x00000056 mov #0x0, t0
|
|
| .-> 0x00000059 copy *ar0+, t1
|
|
| ,==< 0x0000005c bcc #0x000008, t1 == #0
|
|
| |: 0x0000005f add #0x1, t0
|
|
| |`=< 0x00000062 bcc #0x00fff2, t0 < #0x7f
|
|
\ `--> 0x00000067 ret
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis: pdf render - _main (nested branches, two call refs)
|
|
FILE=bins/tms320/coff2/19_emulateme_nostd.obj
|
|
ARGS=-A
|
|
CMDS=<<EOF
|
|
e analysis.cpu=c55x+
|
|
pdf @ sym._main
|
|
EOF
|
|
EXPECT=<<EOF
|
|
/ int sym._main(int argc, char **argv, char **envp);
|
|
| 0x000000ba psh t1
|
|
| ,=< 0x000000bc bcc #0x00001c, t0 != #0x2
|
|
| | 0x000000c1 mov *ar0(#1), ac0
|
|
| | 0x000000c6 mov ac0, xar0
|
|
| | 0x000000c9 call #0x00ff8a ; sym._c_strlen
|
|
| ,==< 0x000000cc bcc #0x00000c, t0 != #0x10
|
|
| || 0x000000d1 call #0x00ff94 ; sym._decrypt
|
|
| ,===< 0x000000d4 bcc #0x000006, t0 == #0
|
|
| ||| 0x000000d7 mov #0x0, t0
|
|
| ||| 0x000000da pop t1
|
|
| ||| 0x000000dc ret
|
|
| ```-> 0x000000dd mov #0x1, t0
|
|
| 0x000000e0 pop t1
|
|
\ 0x000000e2 ret
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ analysis: Smem k16/k24 offset operands extend op->size
|
|
FILE=malloc://64
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
# MOV *ARn(#K16), ACx and COPY dbl(*ARn(#K16)), ACx carry a 16-bit
|
|
# offset after the 3-byte base encoding -> op->size must be 5, not 3.
|
|
# Regression guard for the reg_len_dec propagation fix; a short size
|
|
# would leak the offset bytes back as a spurious following instruction.
|
|
wx 5880400001 @ 0
|
|
ao 1 @ 0~^size
|
|
wx 5480711234 @ 0
|
|
ao 1 @ 0~^size
|
|
# A plain mm==0 Smem mode stays at the base length.
|
|
wx 580000 @ 0
|
|
ao 1 @ 0~^size
|
|
EOF
|
|
EXPECT=<<EOF
|
|
size: 5
|
|
size: 5
|
|
size: 3
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ IL: nop and unconditional branch lift to RzIL
|
|
FILE=malloc://64
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
wx 20 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 00 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 680400 @ 0
|
|
ao 1 @ 0~rzil
|
|
EOF
|
|
EXPECT=<<EOF
|
|
rzil: nop
|
|
rzil: nop
|
|
rzil: (jmp (bv 24 0x403))
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ IL: mov, bitwise, 16-bit arith, and xar-move lift to RzIL
|
|
FILE=malloc://64
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
wx ac000042 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 772120 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 77a422 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 750100 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 758300 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 7b3009 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 743332 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 7b3381 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx c5a3230001 @ 0
|
|
ao 1 @ 0~rzil
|
|
EOF
|
|
EXPECT=<<EOF
|
|
rzil: (set ac0 (bv 40 0x42))
|
|
rzil: (set ar1 (var ar0))
|
|
rzil: (set xar4 (var xar2))
|
|
rzil: (set ac1 (& (var ac1) (var ac0)))
|
|
rzil: (set ac3 (^ (var ac3) (var ac0)))
|
|
rzil: (set t0 (+ (var t0) (bv 16 0x9)))
|
|
rzil: (set t3 (+ (var t3) (var t2)))
|
|
rzil: (set t3 (- (var t3) (bv 16 0x1)))
|
|
rzil: (set ar3 (^ (var ar3) (bv 16 0x1)))
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ IL: memory load/store, post-modify, accumulator arith lift to RzIL
|
|
FILE=malloc://64
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
wx 580280 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 581301 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 5105a0 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 501631 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 740001 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 740030 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 770030 @ 0
|
|
ao 1 @ 0~rzil
|
|
EOF
|
|
EXPECT=<<EOF
|
|
rzil: (set ac0 (cast 40 (msb (loadw 0 16 (* (cast 24 false (var xar2)) (bv 24 0x2)))) (loadw 0 16 (* (cast 24 false (var xar2)) (bv 24 0x2)))))
|
|
rzil: (seq (set ac1 (cast 40 (msb (loadw 0 16 (* (cast 24 false (var xar3)) (bv 24 0x2)))) (loadw 0 16 (* (cast 24 false (var xar3)) (bv 24 0x2))))) (set xar3 (+ (var xar3) (bv 24 0x1))))
|
|
rzil: (storew 0 (* (cast 24 false (var xar5)) (bv 24 0x2)) (cast 16 false (var ac0)))
|
|
rzil: (seq (storew 0 (* (cast 24 false (var xar6)) (bv 24 0x2)) (var t1)) (set xar6 (+ (var xar6) (bv 24 0x1))))
|
|
rzil: (set ac0 (+ (var ac0) (var ac1)))
|
|
rzil: (set ac0 (+ (var ac0) (cast 40 (msb (var t0)) (var t0))))
|
|
rzil: (set ac0 (cast 40 (msb (var t0)) (var t0)))
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ IL: amov/aadd/asub, amar, neg, mov half->reg, bitwise half forms lift to RzIL
|
|
FILE=malloc://64
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
wx 72a427 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 7220a1 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 722023 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 760382 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 770162 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 6383c0 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx c5626000ff @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 75c060 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx db604000fe @ 0
|
|
ao 1 @ 0~rzil
|
|
wx db60c0004d @ 0
|
|
ao 1 @ 0~rzil
|
|
EOF
|
|
EXPECT=<<EOF
|
|
rzil: (set xar4 (var xar7))
|
|
rzil: (set xar0 (+ (var xar0) (var xar1)))
|
|
rzil: (set xar0 (- (var xar0) (var xar3)))
|
|
rzil: (set ac3 (- (bv 40 0x0) (var ac2)))
|
|
rzil: (set ac1 (cast 40 (msb (cast 16 false (var ac2))) (cast 16 false (var ac2))))
|
|
rzil: (set xar0 (cast 24 false (+ (cast 24 false (var sp)) (bv 24 0x3))))
|
|
rzil: (set ac2 (| (& (var ac2) (bv 40 0xffffff0000)) (cast 40 false (& (cast 16 false (var ac0)) (bv 16 0xff)))))
|
|
rzil: (set ac0 (| (& (var ac0) (bv 40 0xff0000ffff)) (<< (cast 40 false (^ (cast 16 false (>> (var ac0) (bv 8 0x10) false)) (cast 16 false (var ac0)))) (bv 6 0x10) false)))
|
|
rzil: (branch (== (cast 16 false (var ac0)) (cast 16 false (>> (var ac0) (bv 8 0x10) false))) (jmp (bv 24 0x103)) nop)
|
|
rzil: (branch (! (== (cast 16 false (var ac0)) (cast 16 false (>> (var ac0) (bv 8 0x10) false)))) (jmp (bv 24 0x52)) nop)
|
|
EOF
|
|
RUN
|
|
|
|
NAME=c55x+ IL: deferred forms stay unlifted (correct-or-NULL contract)
|
|
FILE=malloc://64
|
|
CMDS=<<EOF
|
|
e asm.arch=tms320
|
|
e analysis.cpu=c55x+
|
|
wx ee00006100b8 @ 0
|
|
ao 1 @ 0~rzil
|
|
wx 610080 @ 0
|
|
ao 1 @ 0~rzil
|
|
EOF
|
|
EXPECT=<<EOF
|
|
EOF
|
|
RUN
|