rizin/test/db/analysis/tms320.c55x+_32
Anton Kochkov 9ff9a48c4a arch/tms320: extend C55x/C55x+ RzIL coverage (returns, addressing, sub-register and bit ops)
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.
2026-06-15 23:31:05 +08:00

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