diff --git a/librz/arch/isa/tms320/README.md b/librz/arch/isa/tms320/README.md index 2185313798..833670f4f5 100644 --- a/librz/arch/isa/tms320/README.md +++ b/librz/arch/isa/tms320/README.md @@ -55,9 +55,10 @@ so its numbers differ from Rizin's by design. In C2000 ELF, `sh_addr`, Native engine under `c28x/`, decoding from a mask/match table generated against TI's `dis2000`: of the 62518 opcode words `dis2000` decodes as instructions, it -agrees on 61641 (98.6%). 782 of the rest are the VCU co-processor set; most of -the others are spellings `dis2000` prefers, such as `MOVL *SP++,ACC` where this -engine writes `PUSH ACC`. +agrees on 62405 (99.8%). Most of the rest are spellings `dis2000` prefers, such +as `MOVL *SP++,ACC` where this engine writes `PUSH ACC`. The others are VCU +parallel forms whose second half the comparison lacks, because the parser that +made it dropped `dis2000`'s `||` lines. Most core instructions are lifted to RzIL. These are not, and leave `op->il_op` unset: @@ -78,6 +79,16 @@ Accumulator arithmetic follows SPRU430's *Flags and Modes*. `V` is sticky, and `OVC` counts overflows while `OVM` is clear; with `OVM` set the result saturates instead. `SXM` selects sign or zero extension of a 16-bit source. +The VCU co-processor of the F2806x and F2837x parts -- Viterbi, complex +arithmetic, FFT and CRC, documented in **SPRUHS1** -- decodes as well, parallel +forms included. Its instructions work on `VR0`-`VR8`, `VT0`-`VT1`, the Viterbi +state metrics and the CRC registers. The encodings were checked against +`dis2000`, and the VCU-I core set also against TI's assembler. The status, +clear, move, shift, increment, bit-reversal and CRC instructions are lifted to +RzIL, except with a register operand such as `@AL` in place of memory. The +other arithmetic, `VPACK4`, `VSHLMB`, and the complex, Viterbi, FFT and +Galois-field instructions are not lifted. + ## c55x Variable-length (1-7 byte) instructions, little-endian, 16-bit word. @@ -147,6 +158,8 @@ as `c28x`, from COFF and from ELF with `e_machine` set to `EM_TI_C2000`. Guide (calling convention) - TI [SPRAC71C][sprac71c] -- C28x Embedded Application Binary Interface (DWARF register numbers and ELF relocations) +- TI [SPRUHS1C][spruhs1c] -- TMS320C28x Extended Instruction Sets Technical + Reference Manual (the VCU) - TI SWPU086 -- TMS320C55x 'C55x+' CPU Reference Guide, Preliminary, May 2005 - TI SWPU104 -- TMS320C55x+ DSP Algebraic Instruction Set Reference @@ -161,3 +174,4 @@ as `c28x`, from COFF and from ELF with `e_machine` set to `EM_TI_C2000`. [sprueo2b]: https://web.archive.org/web/20240513043003/https://www.ti.com/lit/ug/sprueo2b/sprueo2b.pdf [spru514aa]: https://web.archive.org/web/20261006050208/https://www.ti.com/lit/ug/spru514aa/spru514aa.pdf [sprac71c]: https://web.archive.org/web/20261006050055/https://www.ti.com/lit/an/sprac71c/sprac71c.pdf +[spruhs1c]: https://web.archive.org/web/20250127171200/https://www.ti.com/lit/ug/spruhs1c/spruhs1c.pdf diff --git a/librz/arch/isa/tms320/c28x/c28x.h b/librz/arch/isa/tms320/c28x/c28x.h index df0c18bcf8..6f52d237f2 100644 --- a/librz/arch/isa/tms320/c28x/c28x.h +++ b/librz/arch/isa/tms320/c28x/c28x.h @@ -66,6 +66,19 @@ typedef enum { C28X_REG_IFR, ///< interrupt flag register C28X_REG_DBGIER, ///< debug interrupt enable register C28X_REG_OVC, ///< overflow counter (ST0 field) + // VCU (SPRUHS1): eight result registers and two status/shift registers, + // present on the F2806x and F2837x parts that carry the co-processor + C28X_REG_VR0, + C28X_REG_VR1, + C28X_REG_VR2, + C28X_REG_VR3, + C28X_REG_VR4, + C28X_REG_VR5, + C28X_REG_VR6, + C28X_REG_VR7, + C28X_REG_VR8, + C28X_REG_VT0, + C28X_REG_VT1, C28X_REG_PM, ///< product shift mode (ST0 field) C28X_REG_ARP, ///< auxiliary register pointer (ST1 field) C28X_REG_ACC_P, ///< the ACC:P 64-bit pair @@ -84,6 +97,13 @@ typedef enum { C28X_REG_XF, C28X_REG_NMI, C28X_REG_EMUINT, + // VCU registers that only moves and CRC set-up name + C28X_REG_VCRC, + C28X_REG_VSTATUS, + C28X_REG_VCRCPOLY, + C28X_REG_VCRCDSIZE, + C28X_REG_VCRCPSIZE, + C28X_REG_VCRCSIZE, } C28xReg; /** loc16/loc32 addressing modes, AMODE = 0 (SPRU430F Table 5-1). */ @@ -117,6 +137,7 @@ typedef enum { /** Operand kind within a decoded instruction. */ typedef enum { C28X_OP_NONE = 0, + C28X_OP_REG_LOW, ///< low half of a VCU register, spelled VRnL C28X_OP_REG, ///< named register in \ref C28xOperand::reg C28X_OP_MEM, ///< loc16/loc32 access (see \ref C28xAddrMode) C28X_OP_IMM, ///< immediate constant in \ref C28xOperand::imm @@ -130,6 +151,13 @@ typedef enum { C28X_OP_PORT, ///< I/O space port address, rendered as "*(PA)" C28X_OP_MODE, ///< ST0/ST1 mode bit mask for SETC/CLRC C28X_OP_INTR, ///< interrupt selector for INTR, rendered by name + C28X_OP_PAR, ///< start of the parallel half; its \ref C28xInsnId in \ref C28xOperand::imm + C28X_OP_REG_HIGH, ///< high half of a VCU register, spelled VRnH + C28X_OP_VSMPAIR, ///< state-metric pair VSM(2n+1):VSM(2n), n in \ref C28xOperand::imm + C28X_OP_VSHL, ///< "<< #n" after the register it shifts, zero included + C28X_OP_VSHR, ///< ">> #n" after the register it shifts, zero included + C28X_OP_IMMDEC, ///< immediate written in decimal + C28X_OP_IMMCOLON, ///< decimal immediate joined to the one before it by ":" } C28xOpKind; /** One decoded operand. */ @@ -147,10 +175,10 @@ typedef struct { } C28xOperand; /** - * \brief Enough for the widest rows: BAR, with its target, two registers and - * condition. + * \brief Enough for the widest rows: a VCU FFT butterfly with its parallel + * VMOV32. */ -#define C28X_MAX_OPS 4 +#define C28X_MAX_OPS 10 /** * \brief Every C28x mnemonic, in alphabetical order, as X(ID, "name"). @@ -159,6 +187,8 @@ typedef struct { * so the two cannot drift apart. */ #define C28X_INSN_LIST(X) \ + X(A_VCLROVFI, "a_vclrovfi") \ + X(A_VCLROVFR, "a_vclrovfr") \ X(ABORTI, "aborti") \ X(ABS, "abs") \ X(ABSTC, "abstc") \ @@ -302,6 +332,101 @@ typedef struct { X(TRAP, "trap") \ X(TSET, "tset") \ X(UOUT, "uout") \ + X(VASHL32, "vashl32") \ + X(VASHR32, "vashr32") \ + X(VBITFLIP, "vbitflip") \ + X(VCADD, "vcadd") \ + X(VCCMAC, "vccmac") \ + X(VCCMPY, "vccmpy") \ + X(VCCON, "vccon") \ + X(VCDADD16, "vcdadd16") \ + X(VCDSUB16, "vcdsub16") \ + X(VCFFT1, "vcfft1") \ + X(VCFFT10, "vcfft10") \ + X(VCFFT2, "vcfft2") \ + X(VCFFT3, "vcfft3") \ + X(VCFFT4, "vcfft4") \ + X(VCFFT5, "vcfft5") \ + X(VCFFT6, "vcfft6") \ + X(VCFFT7, "vcfft7") \ + X(VCFFT8, "vcfft8") \ + X(VCFFT9, "vcfft9") \ + X(VCFLIP, "vcflip") \ + X(VCLEAR, "vclear") \ + X(VCLEARALL, "vclearall") \ + X(VCLRCPACK, "vclrcpack") \ + X(VCLRCRCMSGFLIP, "vclrcrcmsgflip") \ + X(VCLRDIVE, "vclrdive") \ + X(VCLROPACK, "vclropack") \ + X(VCMAC, "vcmac") \ + X(VCMAG, "vcmag") \ + X(VCMPY, "vcmpy") \ + X(VCRC16P1H_1, "vcrc16p1h_1") \ + X(VCRC16P1L_1, "vcrc16p1l_1") \ + X(VCRC16P2H_1, "vcrc16p2h_1") \ + X(VCRC16P2L_1, "vcrc16p2l_1") \ + X(VCRC24H_1, "vcrc24h_1") \ + X(VCRC24L_1, "vcrc24l_1") \ + X(VCRC32H_1, "vcrc32h_1") \ + X(VCRC32L_1, "vcrc32l_1") \ + X(VCRC32P2H_1, "vcrc32p2h_1") \ + X(VCRC32P2L_1, "vcrc32p2l_1") \ + X(VCRC8H_1, "vcrc8h_1") \ + X(VCRC8L_1, "vcrc8l_1") \ + X(VCRCCLR, "vcrcclr") \ + X(VCRCH, "vcrch") \ + X(VCRCL, "vcrcl") \ + X(VCSHL16, "vcshl16") \ + X(VCSHR16, "vcshr16") \ + X(VCSUB, "vcsub") \ + X(VDEC, "vdec") \ + X(VGFACC, "vgfacc") \ + X(VGFADD4, "vgfadd4") \ + X(VGFINIT, "vgfinit") \ + X(VGFMAC4, "vgfmac4") \ + X(VGFMPY4, "vgfmpy4") \ + X(VINC, "vinc") \ + X(VITBM2, "vitbm2") \ + X(VITBM3, "vitbm3") \ + X(VITDHADDSUB, "vitdhaddsub") \ + X(VITDHSUBADD, "vitdhsubadd") \ + X(VITDLADDSUB, "vitdladdsub") \ + X(VITDLSUBADD, "vitdlsubadd") \ + X(VITHSEL, "vithsel") \ + X(VITLSEL, "vitlsel") \ + X(VITSTAGE, "vitstage") \ + X(VLSHL32, "vlshl32") \ + X(VLSHR32, "vlshr32") \ + X(VMOD32, "vmod32") \ + X(VMOV16, "vmov16") \ + X(VMOV32, "vmov32") \ + X(VMOVD32, "vmovd32") \ + X(VMOVIX, "vmovix") \ + X(VMOVXI, "vmovxi") \ + X(VMOVZI, "vmovzi") \ + X(VMPYADD, "vmpyadd") \ + X(VNEG, "vneg") \ + X(VNOP, "vnop") \ + X(VPACK4, "vpack4") \ + X(VREVB, "vrevb") \ + X(VRNDOFF, "vrndoff") \ + X(VRNDON, "vrndon") \ + X(VSATOFF, "vsatoff") \ + X(VSATON, "vsaton") \ + X(VSETCPACK, "vsetcpack") \ + X(VSETCRCMSGFLIP, "vsetcrcmsgflip") \ + X(VSETCRCSIZE, "vsetcrcsize") \ + X(VSETK, "vsetk") \ + X(VSETOPACK, "vsetopack") \ + X(VSETSHL, "vsetshl") \ + X(VSETSHR, "vsetshr") \ + X(VSHLMB, "vshlmb") \ + X(VSMINIT, "vsminit") \ + X(VSWAP32, "vswap32") \ + X(VSWAPCRC, "vswapcrc") \ + X(VTCLEAR, "vtclear") \ + X(VTRACE, "vtrace") \ + X(VXORMOV32, "vxormov32") \ X(XB, "xb") \ X(XBANZ, "xbanz") \ X(XCALL, "xcall") \ @@ -394,6 +519,7 @@ RZ_IPI RZ_BORROW const char *c28x_reg_name(C28xReg reg); RZ_IPI RZ_BORROW const char *c28x_cond_name(ut8 cond); +RZ_IPI RZ_BORROW const char *c28x_insn_name(C28xInsnId id); RZ_IPI RZ_OWN RzPVector /**/ *c28x_mnemonics(void); #ifdef __cplusplus diff --git a/librz/arch/isa/tms320/c28x/c28x_analysis.c b/librz/arch/isa/tms320/c28x/c28x_analysis.c index fd93e738b3..a90eaa4c5c 100644 --- a/librz/arch/isa/tms320/c28x/c28x_analysis.c +++ b/librz/arch/isa/tms320/c28x/c28x_analysis.c @@ -90,6 +90,7 @@ RZ_IPI void c28x_fill_analysis(RZ_NONNULL const C28xInsn *insn, ut64 addr, } static const char *const c28x_opkind_names[] = { + [C28X_OP_REG_LOW] = "reg_low", [C28X_OP_REG] = "reg", [C28X_OP_MEM] = "mem", [C28X_OP_IMM] = "imm", @@ -103,6 +104,13 @@ static const char *const c28x_opkind_names[] = { [C28X_OP_PORT] = "port", [C28X_OP_MODE] = "mode", [C28X_OP_INTR] = "intr", + [C28X_OP_PAR] = "par", + [C28X_OP_REG_HIGH] = "reg_high", + [C28X_OP_VSMPAIR] = "vsm_pair", + [C28X_OP_VSHL] = "vshl", + [C28X_OP_VSHR] = "vshr", + [C28X_OP_IMMDEC] = "imm_dec", + [C28X_OP_IMMCOLON] = "imm_colon", }; static const char *const c28x_addrmode_names[] = { @@ -202,6 +210,16 @@ RZ_IPI RZ_OWN RzStructuredData *c28x_opex(RZ_NONNULL const C28xInsn *insn) { rz_structured_data_map_add_string(ent, "value", c28x_cond_name((ut8)o->imm)); break; + case C28X_OP_REG_LOW: + case C28X_OP_REG_HIGH: + rz_structured_data_map_add_string(ent, "value", c28x_reg_name(o->reg)); + rz_structured_data_map_add_string(ent, "part", + o->kind == C28X_OP_REG_LOW ? "low" : "high"); + break; + case C28X_OP_PAR: + rz_structured_data_map_add_string(ent, "value", + c28x_insn_name((C28xInsnId)o->imm)); + break; case C28X_OP_PCREL: case C28X_OP_PMA: case C28X_OP_DMA: diff --git a/librz/arch/isa/tms320/c28x/c28x_decode.c b/librz/arch/isa/tms320/c28x/c28x_decode.c index 79eeb4bf53..fd69aebb89 100644 --- a/librz/arch/isa/tms320/c28x/c28x_decode.c +++ b/librz/arch/isa/tms320/c28x/c28x_decode.c @@ -33,6 +33,10 @@ typedef enum { C28X_OD_SHIFTFIX, ///< fixed shift amount held in param C28X_OD_COND, ///< 4-bit condition code C28X_OD_PCREL, ///< signed word displacement from the instruction address + C28X_OD_REGSEL, ///< register chosen by a field, added to a base register + C28X_OD_REGSEL_LOW, ///< as REGSEL, but naming the register's low half + C28X_OD_IMM_SPLIT, ///< 16-bit immediate split across the opcode and parameter words + C28X_OD_IMMV, ///< immediate the opcode fixes, carried in the row itself C28X_OD_PMA, ///< absolute program-memory word address C28X_OD_PMA_IND, ///< the same, read as data and wrapped C28X_OD_PMA_DP, ///< the same, through the page pointer @@ -43,6 +47,13 @@ typedef enum { C28X_OD_BITNUM, ///< bit number for TBIT/TSET/TCLR C28X_OD_INTR, ///< interrupt selector for INTR C28X_OD_IND, ///< fixed indirect operand, mode in param and register in lo + C28X_OD_PAR, ///< parallel half begins; param is its C28xInsnId + C28X_OD_REGSEL_HIGH, ///< as REGSEL, but naming the register's high half + C28X_OD_REGSEL_SPLIT, ///< VR0-VR7, low bits at lo and the rest at param + C28X_OD_VSMPAIR, ///< VSM register pair from a field + C28X_OD_VSHIFT, ///< shift amount that is always written; param 1 shifts right + C28X_OD_IMMDEC, ///< immediate written in decimal + C28X_OD_IMMCOLON, ///< decimal immediate joined to the one before it by ":" } C28xOpndKind; typedef struct { @@ -65,6 +76,7 @@ typedef struct { #include "c28x_rowdefs.h" static const C28xInsnDef c28x_table[] = { #include "c28x_rows.inc" +#include "c28x_rows_vcu.inc" }; #include "c28x_rowundefs.h" @@ -186,6 +198,35 @@ static st64 c28x_sext(ut32 v, ut8 width) { return (st64)(v ^ sign) - (st64)sign; } +/** + * \brief Registers a register-select field can name, by the field's base + * register. + * + * Field values past these are reserved and leave the operand empty, as dis2000 + * prints them. + */ +static const ut8 c28x_regsel_counts[] = { + [C28X_REG_VR0] = 9, + [C28X_REG_VT0] = 2, +}; + +/** + * \brief How many registers a register-select field based at \p base can name. + */ +static ut32 c28x_regsel_count(ut16 base) { + if (base >= RZ_ARRAY_SIZE(c28x_regsel_counts) || !c28x_regsel_counts[base]) { + rz_warn_if_reached(); + return 0; + } + return c28x_regsel_counts[base]; +} + +static const C28xOpKind c28x_regsel_kinds[] = { + [C28X_OD_REGSEL] = C28X_OP_REG, + [C28X_OD_REGSEL_LOW] = C28X_OP_REG_LOW, + [C28X_OD_REGSEL_HIGH] = C28X_OP_REG_HIGH, +}; + static void c28x_decode_operand(const C28xOpndDef *def, ut32 packed, ut64 pc, RZ_OUT C28xOperand *out) { const ut32 f = def->width ? BITS(packed, def->lo, def->width) : 0; @@ -246,6 +287,36 @@ static void c28x_decode_operand(const C28xOpndDef *def, ut32 packed, ut64 pc, out->kind = C28X_OP_PCREL; out->imm = (st64)pc + c28x_sext(f, def->width) * C28X_WORD_BYTES; break; + case C28X_OD_IMMV: + out->kind = C28X_OP_IMM; + out->imm = (st64)def->param; + break; + case C28X_OD_IMM_SPLIT: { + // the low part sits in the parameter word and the high part in the + // opcode word, so neither half is contiguous with the other + const ut32 lo = f; + const ut32 hi_w = 16 - def->width; + const ut32 hi = BITS(packed, def->param, hi_w); + out->kind = C28X_OP_IMM; + out->imm = (st64)((hi << def->width) | lo); + break; + } + case C28X_OD_REGSEL_LOW: + case C28X_OD_REGSEL_HIGH: + case C28X_OD_REGSEL: { + // the field selects one of a contiguous run of registers; values past + // the named ones are reserved and left unrendered, as dis2000 does + const ut32 n = f; + // a zero-width field names the register in param itself: a fixed VRnL or VRnH + const ut32 named = def->width ? c28x_regsel_count(def->param) : 1; + if (n >= named) { + out->kind = C28X_OP_NONE; + break; + } + out->kind = c28x_regsel_kinds[def->kind]; + out->reg = (C28xReg)(def->param + n); + break; + } case C28X_OD_PMA: out->kind = C28X_OP_PMA; // param is the 64K page a 16-bit C2xLP address lies in @@ -284,6 +355,32 @@ static void c28x_decode_operand(const C28xOpndDef *def, ut32 packed, ut64 pc, out->kind = C28X_OP_INTR; out->imm = f; break; + case C28X_OD_PAR: + out->kind = C28X_OP_PAR; + out->imm = def->param; + break; + case C28X_OD_REGSEL_SPLIT: + // VGFACC and friends keep the register's low bit in the opcode word + out->kind = C28X_OP_REG; + out->reg = (C28xReg)(C28X_REG_VR0 + + (f | BITS(packed, def->param, 3 - def->width) << def->width)); + break; + case C28X_OD_VSMPAIR: + out->kind = C28X_OP_VSMPAIR; + out->imm = f; + break; + case C28X_OD_VSHIFT: + out->kind = def->param ? C28X_OP_VSHR : C28X_OP_VSHL; + out->imm = f; + break; + case C28X_OD_IMMDEC: + out->kind = C28X_OP_IMMDEC; + out->imm = f; + break; + case C28X_OD_IMMCOLON: + out->kind = C28X_OP_IMMCOLON; + out->imm = f; + break; case C28X_OD_IND: out->kind = C28X_OP_MEM; out->mode = (C28xAddrMode)def->param; @@ -466,6 +563,14 @@ RZ_IPI bool c28x_decode(RZ_NONNULL const C28xIndex *idx, RZ_NONNULL const ut8 *b return true; } +/** + * \brief The mnemonic of an instruction id. + * \return the lower-case name, or "" for an id outside the list + */ +RZ_IPI RZ_BORROW const char *c28x_insn_name(C28xInsnId id) { + return id > C28X_INS_INVALID && id < C28X_INS_COUNT ? c28x_insn_names[id] : ""; +} + RZ_IPI RZ_OWN RzPVector /**/ *c28x_mnemonics(void) { RzPVector *vec = rz_pvector_new(NULL); if (!vec) { diff --git a/librz/arch/isa/tms320/c28x/c28x_format.c b/librz/arch/isa/tms320/c28x/c28x_format.c index fbfcae657a..ba5261cc38 100644 --- a/librz/arch/isa/tms320/c28x/c28x_format.c +++ b/librz/arch/isa/tms320/c28x/c28x_format.c @@ -41,6 +41,23 @@ static const char *const c28x_reg_names[] = { [C28X_REG_IFR] = "ifr", [C28X_REG_DBGIER] = "dbgier", [C28X_REG_OVC] = "ovc", + [C28X_REG_VR0] = "vr0", + [C28X_REG_VR1] = "vr1", + [C28X_REG_VR2] = "vr2", + [C28X_REG_VR3] = "vr3", + [C28X_REG_VR4] = "vr4", + [C28X_REG_VR5] = "vr5", + [C28X_REG_VR6] = "vr6", + [C28X_REG_VR7] = "vr7", + [C28X_REG_VR8] = "vr8", + [C28X_REG_VT0] = "vt0", + [C28X_REG_VCRC] = "vcrc", + [C28X_REG_VSTATUS] = "vstatus", + [C28X_REG_VCRCPOLY] = "vcrcpoly", + [C28X_REG_VCRCDSIZE] = "vcrcdsize", + [C28X_REG_VCRCPSIZE] = "vcrcpsize", + [C28X_REG_VCRCSIZE] = "vcrcsize", + [C28X_REG_VT1] = "vt1", [C28X_REG_PM] = "pm", [C28X_REG_ARP] = "arp", [C28X_REG_ACC_P] = "acc:p", @@ -191,6 +208,18 @@ static void c28x_format_mode(RzStrBuf *sb, ut32 mask) { static void c28x_format_operand(RzStrBuf *sb, const C28xInsn *insn, const C28xOperand *op) { switch (op->kind) { + case C28X_OP_REG_LOW: + rz_strbuf_appendf(sb, "%sl", c28x_reg_name(op->reg)); + break; + case C28X_OP_REG_HIGH: + rz_strbuf_appendf(sb, "%sh", c28x_reg_name(op->reg)); + break; + case C28X_OP_VSMPAIR: + rz_strbuf_appendf(sb, "vsm%u:vsm%u", (ut32)op->imm * 2 + 1, (ut32)op->imm * 2); + break; + case C28X_OP_IMMDEC: + rz_strbuf_appendf(sb, "#%u", (ut32)op->imm); + break; case C28X_OP_REG: if (op->reg == C28X_REG_ARP) { rz_strbuf_appendf(sb, "arp%d", (int)op->imm); @@ -292,8 +321,14 @@ RZ_IPI RZ_OWN char *c28x_format(RZ_NONNULL const C28xInsn *insn, ut64 pc) { return rz_strbuf_drain_nofree(&sb); } + bool par_start = false; for (ut8 i = 0; i < insn->nops; i++) { const C28xOperand *op = &insn->ops[i]; + // a reserved register number leaves the slot empty rather than naming + // something that does not exist; dis2000 drops the operand the same way + if (op->kind == C28X_OP_NONE) { + continue; + } const bool suffix_shift = i > 1; if (op->kind == C28X_OP_SHIFT) { if (!suffix_shift) { @@ -310,8 +345,21 @@ RZ_IPI RZ_OWN char *c28x_format(RZ_NONNULL const C28xInsn *insn, ut64 pc) { rz_strbuf_append(&sb, " << "); rz_strbuf_append(&sb, c28x_reg_name(op->reg)); continue; + } else if (op->kind == C28X_OP_VSHL || op->kind == C28X_OP_VSHR) { + // the VCU shifts write their count after the register, zero included + rz_strbuf_appendf(&sb, " %s #%u", op->kind == C28X_OP_VSHR ? ">>" : "<<", + (ut32)op->imm); + continue; + } else if (op->kind == C28X_OP_IMMCOLON) { + rz_strbuf_appendf(&sb, ":#%u", (ut32)op->imm); + continue; + } else if (op->kind == C28X_OP_PAR) { + rz_strbuf_appendf(&sb, " || %s", c28x_insn_name((C28xInsnId)op->imm)); + par_start = true; + continue; } else { - rz_strbuf_append(&sb, i ? ", " : " "); + rz_strbuf_append(&sb, i && !par_start ? ", " : " "); + par_start = false; } c28x_format_operand(&sb, insn, op); } diff --git a/librz/arch/isa/tms320/c28x/c28x_il.c b/librz/arch/isa/tms320/c28x/c28x_il.c index aa6689f1a1..2d2152437e 100644 --- a/librz/arch/isa/tms320/c28x/c28x_il.c +++ b/librz/arch/isa/tms320/c28x/c28x_il.c @@ -3239,10 +3239,12 @@ static const C28xLifter c28x_lifters[] = { */ RZ_IPI RZ_OWN RzILOpEffect *c28x_lift(RZ_NONNULL const C28xInsn *insn, ut64 pc) { rz_return_val_if_fail(insn, NULL); - if ((size_t)insn->id >= RZ_ARRAY_SIZE(c28x_lifters) || !c28x_lifters[insn->id]) { - return NULL; + RzILOpEffect *eff = NULL; + if ((size_t)insn->id < RZ_ARRAY_SIZE(c28x_lifters) && c28x_lifters[insn->id]) { + eff = c28x_lifters[insn->id](insn, pc); } - return c28x_lifters[insn->id](insn, pc); + // the VCU lifts its own instructions + return eff ? eff : c28x_lift_vcu(insn, pc); } /** diff --git a/librz/arch/isa/tms320/c28x/c28x_il.h b/librz/arch/isa/tms320/c28x/c28x_il.h index a0775abe9b..1ae1c18613 100644 --- a/librz/arch/isa/tms320/c28x/c28x_il.h +++ b/librz/arch/isa/tms320/c28x/c28x_il.h @@ -36,4 +36,6 @@ static inline RzILOpEffect *c28x_with_mem(const C28xOperand *m, bool wide, RzILO return c28x_with_ea(&acc, body); } +RZ_IPI RzILOpEffect *c28x_lift_vcu(const C28xInsn *insn, ut64 pc); + #endif // C28X_IL_H diff --git a/librz/arch/isa/tms320/c28x/c28x_il_vcu.c b/librz/arch/isa/tms320/c28x/c28x_il_vcu.c new file mode 100644 index 0000000000..05372f94bb --- /dev/null +++ b/librz/arch/isa/tms320/c28x/c28x_il_vcu.c @@ -0,0 +1,741 @@ +// SPDX-FileCopyrightText: 2026 RizinOrg +// SPDX-License-Identifier: LGPL-3.0-only + +/* + * RzIL for the C28x VCU and VCU-II (SPRUHS1C chapters 3 to 5). VSTATUS is one + * register whose fields the instructions set, laid out as on VCU-II, whose + * bits 13-0 are VCU-I's. + */ + +#include "c28x_il.h" + +#include + +typedef RzILOpEffect *(*C28xVcuLifter)(const C28xInsn *insn); + +typedef enum { + C28X_VS_SHIFTR, + C28X_VS_SHIFTL, + C28X_VS_SAT, + C28X_VS_RND, + C28X_VS_OVFR, + C28X_VS_OVFI, + C28X_VS_CPACK, + C28X_VS_OPACK, + C28X_VS_GFPOLY, + C28X_VS_GFORDER, + C28X_VS_K, + C28X_VS_DIVE, + C28X_VS_CRCMSGFLIP, +} C28xVstatusField; + +/** \brief Each VSTATUS field's lowest bit and width (SPRUHS1C figure 5-3). */ +static const struct { + ut8 lo; + ut8 width; +} c28x_vstatus[] = { + [C28X_VS_SHIFTR] = { 0, 5 }, + [C28X_VS_SHIFTL] = { 5, 5 }, + [C28X_VS_SAT] = { 10, 1 }, + [C28X_VS_RND] = { 11, 1 }, + [C28X_VS_OVFR] = { 12, 1 }, + [C28X_VS_OVFI] = { 13, 1 }, + [C28X_VS_CPACK] = { 14, 1 }, + [C28X_VS_OPACK] = { 15, 1 }, + [C28X_VS_GFPOLY] = { 16, 8 }, + [C28X_VS_GFORDER] = { 24, 3 }, + [C28X_VS_K] = { 27, 3 }, + [C28X_VS_DIVE] = { 30, 1 }, + [C28X_VS_CRCMSGFLIP] = { 31, 1 }, +}; + +/** + * \brief Set VSTATUS field \p f to \p v, keeping the others. + */ +static RzILOpEffect *c28x_vs_set(C28xVstatusField f, RzILOpPure *v) { + const ut32 mask = ((1U << c28x_vstatus[f].width) - 1) << c28x_vstatus[f].lo; + RzILOpPure *keep = LOGAND(VARG("vstatus"), UN(32, ~mask)); + RzILOpPure *field = SHIFTL0(UNSIGNED(32, v), UN(8, c28x_vstatus[f].lo)); + return SETG("vstatus", LOGOR(keep, LOGAND(field, UN(32, mask)))); +} + +/** + * \brief The instructions that set one VSTATUS field: to their immediate, or + * to a constant. + * + * A_VCLROVFI clears OVFI: SPRUHS1C's VCU-II page says "real", but its VCU-I + * page and the VSTATUS description name the imaginary flag. + */ +static const struct { + bool set; + bool imm; + ut8 value; + C28xVstatusField field; +} c28x_vcu_sets[] = { + [C28X_INS_VSETSHL] = { true, true, 0, C28X_VS_SHIFTL }, + [C28X_INS_VSETSHR] = { true, true, 0, C28X_VS_SHIFTR }, + [C28X_INS_VSETK] = { true, true, 0, C28X_VS_K }, + [C28X_INS_VSATON] = { true, false, 1, C28X_VS_SAT }, + [C28X_INS_VSATOFF] = { true, false, 0, C28X_VS_SAT }, + [C28X_INS_VRNDON] = { true, false, 1, C28X_VS_RND }, + [C28X_INS_VRNDOFF] = { true, false, 0, C28X_VS_RND }, + [C28X_INS_A_VCLROVFI] = { true, false, 0, C28X_VS_OVFI }, + [C28X_INS_A_VCLROVFR] = { true, false, 0, C28X_VS_OVFR }, + [C28X_INS_VSETCPACK] = { true, false, 1, C28X_VS_CPACK }, + [C28X_INS_VCLRCPACK] = { true, false, 0, C28X_VS_CPACK }, + [C28X_INS_VSETOPACK] = { true, false, 1, C28X_VS_OPACK }, + [C28X_INS_VCLROPACK] = { true, false, 0, C28X_VS_OPACK }, + [C28X_INS_VSETCRCMSGFLIP] = { true, false, 1, C28X_VS_CRCMSGFLIP }, + [C28X_INS_VCLRCRCMSGFLIP] = { true, false, 0, C28X_VS_CRCMSGFLIP }, + [C28X_INS_VCLRDIVE] = { true, false, 0, C28X_VS_DIVE }, +}; + +static RzILOpEffect *c28x_vcu_set(const C28xInsn *insn) { + if ((size_t)insn->id >= RZ_ARRAY_SIZE(c28x_vcu_sets) || !c28x_vcu_sets[insn->id].set) { + return NULL; + } + const C28xVstatusField field = c28x_vcu_sets[insn->id].field; + if (!c28x_vcu_sets[insn->id].imm) { + return c28x_vs_set(field, UN(8, c28x_vcu_sets[insn->id].value)); + } + if (insn->nops != 1 || insn->ops[0].kind != C28X_OP_IMM) { + return NULL; + } + return c28x_vs_set(field, UN(8, insn->ops[0].imm & 0xff)); +} + +static const char *c28x_vr_names[] = { + "vr0", + "vr1", + "vr2", + "vr3", + "vr4", + "vr5", + "vr6", + "vr7", + "vr8", +}; + +/** + * \brief The IL global of VRa operand \p o. + */ +static const char *c28x_vr_name(const C28xOperand *o) { + if (o->kind != C28X_OP_REG || o->reg < C28X_REG_VR0 || o->reg > C28X_REG_VR0 + 8) { + return NULL; + } + return c28x_vr_names[o->reg - C28X_REG_VR0]; +} + +/** + * \brief VCLEAR VRa, VCLEARALL, VTCLEAR and VCRCCLR. + * + * VCLEARALL clears VR0-VR8, VT0 and VT1 as its description says; a VCU-II + * example's comment also names VSM0-VSM63, which the description doesn't. + */ +static RzILOpEffect *c28x_vcu_clear(const C28xInsn *insn) { + if (insn->id == C28X_INS_VCLEAR) { + const char *n = insn->nops == 1 ? c28x_vr_name(&insn->ops[0]) : NULL; + return n ? SETG(n, UN(32, 0)) : NULL; + } + if (insn->id == C28X_INS_VCRCCLR) { + return SETG("vcrc", UN(32, 0)); + } + RzILOpEffect *eff = SEQ2(SETG("vt0", UN(32, 0)), SETG("vt1", UN(32, 0))); + if (insn->id == C28X_INS_VCLEARALL) { + for (size_t i = 0; i < RZ_ARRAY_SIZE(c28x_vr_names); i++) { + eff = SEQ2(eff, SETG(c28x_vr_names[i], UN(32, 0))); + } + } + return eff; +} + +static const char *c28x_vsm_names[] = { + "vsm0", + "vsm1", + "vsm2", + "vsm3", + "vsm4", + "vsm5", + "vsm6", + "vsm7", + "vsm8", + "vsm9", + "vsm10", + "vsm11", + "vsm12", + "vsm13", + "vsm14", + "vsm15", + "vsm16", + "vsm17", + "vsm18", + "vsm19", + "vsm20", + "vsm21", + "vsm22", + "vsm23", + "vsm24", + "vsm25", + "vsm26", + "vsm27", + "vsm28", + "vsm29", + "vsm30", + "vsm31", + "vsm32", + "vsm33", + "vsm34", + "vsm35", + "vsm36", + "vsm37", + "vsm38", + "vsm39", + "vsm40", + "vsm41", + "vsm42", + "vsm43", + "vsm44", + "vsm45", + "vsm46", + "vsm47", + "vsm48", + "vsm49", + "vsm50", + "vsm51", + "vsm52", + "vsm53", + "vsm54", + "vsm55", + "vsm56", + "vsm57", + "vsm58", + "vsm59", + "vsm60", + "vsm61", + "vsm62", + "vsm63", +}; + +/** + * \brief The IL global of a whole 32-bit VCU register operand. + */ +static const char *c28x_vcu_reg32(const C28xOperand *o) { + if (o->kind != C28X_OP_REG) { + return NULL; + } + switch (o->reg) { + case C28X_REG_VT0: return "vt0"; + case C28X_REG_VT0 + 1: return "vt1"; + case C28X_REG_VSTATUS: return "vstatus"; + case C28X_REG_VCRC: return "vcrc"; + case C28X_REG_VCRCPOLY: return "vcrcpoly"; + case C28X_REG_VCRCSIZE: return "vcrcsize"; + default: return c28x_vr_name(o); + } +} + +/** + * \brief Read VCU register operand \p o: a whole register, VRaL or VRaH, or the + * state-metric pair VSM(2n+1):VSM(2n), VSM(2n+1) in the high half. + */ +static RzILOpPure *c28x_vcu_read(const C28xOperand *o) { + if (o->kind == C28X_OP_VSMPAIR) { + const ut32 n = (ut32)o->imm & 31; + return APPEND(VARG(c28x_vsm_names[2 * n + 1]), VARG(c28x_vsm_names[2 * n])); + } + if (o->kind == C28X_OP_REG_LOW || o->kind == C28X_OP_REG_HIGH) { + const C28xOperand whole = { .kind = C28X_OP_REG, .reg = o->reg }; + const char *n = c28x_vr_name(&whole); + if (!n) { + return NULL; + } + RzILOpPure *v = VARG(n); + return UNSIGNED(16, o->kind == C28X_OP_REG_HIGH ? SHIFTR0(v, UN(8, 16)) : v); + } + const char *n = c28x_vcu_reg32(o); + return n ? VARG(n) : NULL; +} + +/** + * \brief Write \p v to VCU register operand \p o, keeping the other half of + * VRa. + */ +static RzILOpEffect *c28x_vcu_write(const C28xOperand *o, RzILOpPure *v) { + if (o->kind == C28X_OP_VSMPAIR) { + const ut32 n = (ut32)o->imm & 31; + RzILOpPure *high = UNSIGNED(16, SHIFTR0(v, UN(8, 16))); + RzILOpEffect *hi = SETG(c28x_vsm_names[2 * n + 1], high); + return SEQ2(hi, SETG(c28x_vsm_names[2 * n], UNSIGNED(16, DUP(v)))); + } + if (o->kind == C28X_OP_REG_LOW || o->kind == C28X_OP_REG_HIGH) { + const C28xOperand whole = { .kind = C28X_OP_REG, .reg = o->reg }; + const char *n = c28x_vr_name(&whole); + if (!n) { + rz_il_op_pure_free(v); + return NULL; + } + RzILOpPure *w = UNSIGNED(32, v); + if (o->kind == C28X_OP_REG_HIGH) { + RzILOpPure *low = LOGAND(VARG(n), UN(32, 0xffff)); + return SETG(n, LOGOR(low, SHIFTL0(w, UN(8, 16)))); + } + return SETG(n, LOGOR(LOGAND(VARG(n), UN(32, 0xffff0000)), w)); + } + const char *n = c28x_vcu_reg32(o); + if (!n) { + rz_il_op_pure_free(v); + return NULL; + } + return SETG(n, v); +} + +/** + * \brief Set a VCRCSIZE field: DSIZE is bits 2:0, PSIZE bits 20:16 (SPRUHS1C + * table 5-8). + */ +static RzILOpEffect *c28x_vcrcsize_set(bool psize, RzILOpPure *v) { + const ut32 lo = psize ? 16 : 0; + const ut32 mask = (psize ? 0x1fU : 0x7U) << lo; + RzILOpPure *field = LOGAND(SHIFTL0(UNSIGNED(32, v), UN(8, lo)), UN(32, mask)); + return SETG("vcrcsize", LOGOR(LOGAND(VARG("vcrcsize"), UN(32, ~mask)), field)); +} + +/** + * \brief A move's source other than memory: a VCU register, a 16-bit data + * address or a CPU register. + */ +static RzILOpPure *c28x_vcu_src(const C28xOperand *o, bool wide) { + if (o->kind == C28X_OP_DMA) { + return LOADW(wide ? 32 : 16, c28x_byte(UN(32, (ut64)o->imm / C28X_WORD_BYTES))); + } + if (o->kind == C28X_OP_MEM) { + const char *cpu = c28x_reg32(o); + return cpu ? VARG(cpu) : NULL; + } + return c28x_vcu_read(o); +} + +/** + * \brief A move's destination other than memory. + * + * VMOV16 VCRCDSIZE/VCRCPSIZE,mem16 set their VCRCSIZE fields, as their + * pseudocode says, rather than the whole halves their titles mention. + */ +static RzILOpEffect *c28x_vcu_dst(const C28xOperand *o, RzILOpPure *v) { + const bool psize = o->kind == C28X_OP_REG && o->reg == C28X_REG_VCRCPSIZE; + if (psize || (o->kind == C28X_OP_REG && o->reg == C28X_REG_VCRCDSIZE)) { + return c28x_vcrcsize_set(psize, v); + } + if (o->kind == C28X_OP_DMA) { + return STOREW(c28x_byte(UN(32, (ut64)o->imm / C28X_WORD_BYTES)), v); + } + if (o->kind == C28X_OP_MEM) { + const char *cpu = c28x_reg32(o); + if (!cpu) { + rz_il_op_pure_free(v); + return NULL; + } + return SETG(cpu, v); + } + return c28x_vcu_write(o, v); +} + +/** + * \brief VMOV32 and VMOV16 between VCU registers, their halves, VSM pairs and + * memory, and VMOV32 between a loc32 and a 16-bit data address. The access + * width is the mnemonic's, whatever width the row renders mem32 with. + */ +static RzILOpEffect *c28x_vcu_mov(const C28xInsn *insn) { + if (insn->nops != 2) { + return NULL; + } + const bool wide = insn->id == C28X_INS_VMOV32; + const C28xOperand *dst = &insn->ops[0]; + const C28xOperand *src = &insn->ops[1]; + if (c28x_is_mem(dst)) { + RzILOpPure *v = c28x_vcu_src(src, wide); + return v ? c28x_with_mem(dst, wide, c28x_ea_store(v)) : NULL; + } + if (c28x_is_mem(src)) { + RzILOpEffect *wr = c28x_vcu_dst(dst, VARL("mv")); + RzILOpEffect *load = wr ? SETL("mv", c28x_ea_load(wide ? 32 : 16)) : NULL; + return load ? c28x_with_mem(src, wide, SEQ2(load, wr)) : NULL; + } + RzILOpPure *v = c28x_vcu_src(src, wide); + return v ? c28x_vcu_dst(dst, v) : NULL; +} + +/** + * \brief VMOVZI, VMOVXI and VMOVIX: VRa or VCRCPOLY takes a 16-bit immediate in + * its low half (VMOVZI clearing the high one) or its high half. + */ +static RzILOpEffect *c28x_vcu_movi(const C28xInsn *insn) { + if (insn->nops != 2 || insn->ops[1].kind != C28X_OP_IMM) { + return NULL; + } + RzILOpPure *cur = c28x_vcu_read(&insn->ops[0]); + if (!cur) { + return NULL; + } + const ut32 imm = (ut32)insn->ops[1].imm & 0xffff; + RzILOpPure *v; + if (insn->id == C28X_INS_VMOVZI) { + rz_il_op_pure_free(cur); + v = UN(32, imm); + } else if (insn->id == C28X_INS_VMOVXI) { + v = LOGOR(LOGAND(cur, UN(32, 0xffff0000)), UN(32, imm)); + } else { + v = LOGOR(LOGAND(cur, UN(32, 0xffff)), UN(32, imm << 16)); + } + return c28x_vcu_write(&insn->ops[0], v); +} + +/** + * \brief VMOVD32 VRa,mem32 loads VRa and, as its pseudocode says, copies + * [mem32] two words up; its prose says the copy goes the other way. + */ +static RzILOpEffect *c28x_vcu_movd32(const C28xInsn *insn) { + if (insn->nops != 2 || !c28x_is_mem(&insn->ops[1])) { + return NULL; + } + RzILOpEffect *wr = c28x_vcu_write(&insn->ops[0], VARL("mv")); + if (!wr) { + return NULL; + } + RzILOpPure *above = c28x_byte(ADD(VARL(C28X_EA_LOCAL), UN(32, 2))); + RzILOpEffect *body = SEQ3(SETL("mv", c28x_ea_load(32)), wr, STOREW(above, VARL("mv"))); + return c28x_with_mem(&insn->ops[1], true, body); +} + +/** + * \brief VSWAP32 VRb,VRa. + */ +static RzILOpEffect *c28x_vcu_swap(const C28xInsn *insn) { + const char *a = insn->nops == 2 ? c28x_vr_name(&insn->ops[0]) : NULL; + const char *b = a ? c28x_vr_name(&insn->ops[1]) : NULL; + if (!b) { + return NULL; + } + return SEQ3(SETL("sa", VARG(a)), SETG(a, VARG(b)), SETG(b, VARL("sa"))); +} + +/** + * \brief VXORMOV32 VRa,mem32: a 32-bit access, though the row renders mem32 as + * loc16. + */ +static RzILOpEffect *c28x_vcu_xormov(const C28xInsn *insn) { + const char *a = insn->nops == 2 ? c28x_vr_name(&insn->ops[0]) : NULL; + if (!a || !c28x_is_mem(&insn->ops[1])) { + return NULL; + } + return c28x_with_mem(&insn->ops[1], true, SETG(a, LOGXOR(VARG(a), c28x_ea_load(32)))); +} + +/** + * \brief VSETCRCSIZE #5I:#3i sets PSIZE and DSIZE. + */ +static RzILOpEffect *c28x_vcu_setcrcsize(const C28xInsn *insn) { + const C28xOperand *op = insn->ops; + if (insn->nops != 2 || op[0].kind != C28X_OP_IMMDEC || op[1].kind != C28X_OP_IMMCOLON) { + return NULL; + } + RzILOpEffect *p = c28x_vcrcsize_set(true, UN(8, insn->ops[0].imm & 0x1f)); + return SEQ2(p, c28x_vcrcsize_set(false, UN(8, insn->ops[1].imm & 0x7))); +} + +/* + * CRC: MSB-first CRCs over bytes, or over bit strings VCRCSIZE configures, + * accumulated in VCRC from bit 0 up. TI's linker's CRC tables (CRC8_PRIME, + * CRC16_ALT, CRC16_802_15_4, CRC24_FLEXRAY, CRC32_PRIME and CRC32_C) are these + * CRCs from zero over each word's low byte, then its high one. + */ + +/** + * \brief The fixed-polynomial CRC instructions: CRC width and polynomial, and + * whether they take mem16's high byte. + * + * SPRUHS1C's VCRC32P2 pages repeat polynomial 1; TI's CRC application note + * SPRACR3 gives 0x1EDC6F41, as TI's linker's CRC32_C tables confirm. + */ +static const struct { + ut8 width; + bool high; + ut32 poly; +} c28x_vcrcs[] = { + [C28X_INS_VCRC8L_1] = { 8, false, 0x07 }, + [C28X_INS_VCRC8H_1] = { 8, true, 0x07 }, + [C28X_INS_VCRC16P1L_1] = { 16, false, 0x8005 }, + [C28X_INS_VCRC16P1H_1] = { 16, true, 0x8005 }, + [C28X_INS_VCRC16P2L_1] = { 16, false, 0x1021 }, + [C28X_INS_VCRC16P2H_1] = { 16, true, 0x1021 }, + [C28X_INS_VCRC24L_1] = { 24, false, 0x5d6dcb }, + [C28X_INS_VCRC24H_1] = { 24, true, 0x5d6dcb }, + [C28X_INS_VCRC32L_1] = { 32, false, 0x04c11db7 }, + [C28X_INS_VCRC32H_1] = { 32, true, 0x04c11db7 }, + [C28X_INS_VCRC32P2L_1] = { 32, false, 0x1edc6f41 }, + [C28X_INS_VCRC32P2H_1] = { 32, true, 0x1edc6f41 }, +}; + +static RzILOpBool *c28x_vs_bit(C28xVstatusField f) { + return NON_ZERO(LOGAND(VARG("vstatus"), UN(32, 1U << c28x_vstatus[f].lo))); +} + +/** + * \brief The low eight bits of the value in \p local in reverse order. + */ +static RzILOpPure *c28x_rev8(const char *local) { + RzILOpPure *r = UN(32, 0); + for (ut32 i = 0; i < 8; i++) { + RzILOpPure *bit = LOGAND(SHIFTR0(VARL(local), UN(8, i)), UN(32, 1)); + r = LOGOR(r, SHIFTL0(bit, UN(8, 7 - i))); + } + return r; +} + +/** + * \brief Latch mem16's low or high byte in "cd", reversed when \p flip and + * CRCMSGFLIP is set; mem16 is read in "cb". + */ +static RzILOpEffect *c28x_crc_byte(bool high, bool flip) { + RzILOpPure *lane = high ? SHIFTR0(VARL("cb"), UN(8, 8)) : VARL("cb"); + RzILOpEffect *load = SETL("cb", UNSIGNED(32, c28x_ea_load(16))); + RzILOpEffect *byte = SETL("cd", LOGAND(lane, UN(32, 0xff))); + if (!flip) { + return SEQ2(load, byte); + } + RzILOpPure *flipped = ITE(c28x_vs_bit(C28X_VS_CRCMSGFLIP), c28x_rev8("cd"), VARL("cd")); + return SEQ3(load, byte, SETL("cd", flipped)); +} + +/** + * \brief The VCRC8/16/24/32 instructions, each feeding one byte, MSB first. + */ +static RzILOpEffect *c28x_vcu_crc(const C28xInsn *insn) { + if ((size_t)insn->id >= RZ_ARRAY_SIZE(c28x_vcrcs) || !c28x_vcrcs[insn->id].width) { + return NULL; + } + if (insn->nops != 1 || !c28x_is_mem(&insn->ops[0])) { + return NULL; + } + const ut32 w = c28x_vcrcs[insn->id].width; + const ut32 mask = (ut32)((1ULL << w) - 1); + RzILOpPure *seed = LOGAND(VARG("vcrc"), UN(32, mask)); + RzILOpEffect *body = SEQ2(c28x_crc_byte(c28x_vcrcs[insn->id].high, true), + SETL("cr", LOGXOR(seed, SHIFTL0(VARL("cd"), UN(8, w - 8))))); + for (ut32 i = 0; i < 8; i++) { + RzILOpPure *shifted = LOGAND(SHIFTL0(VARL("cr"), UN(8, 1)), UN(32, mask)); + RzILOpBool *top = NON_ZERO(LOGAND(VARL("cr"), UN(32, 1U << (w - 1)))); + RzILOpPure *poly = UN(32, c28x_vcrcs[insn->id].poly); + RzILOpPure *next = ITE(top, LOGXOR(shifted, poly), DUP(shifted)); + body = SEQ2(body, SETL("cr", next)); + } + RzILOpPure *keep = LOGAND(VARG("vcrc"), UN(32, ~mask)); + body = SEQ2(body, SETG("vcrc", LOGOR(keep, VARL("cr")))); + return c28x_with_mem(&insn->ops[0], false, body); +} + +/** + * \brief VCRCL and VCRCH: the CRC of DSIZE + 1 bits from mem16's low or high + * byte, right justified, with the PSIZE + 1 bit polynomial in VCRCPOLY + * (SPRUHS1C tables 4-3 and 4-4), fed MSB first. + */ +static RzILOpEffect *c28x_vcu_crcgen(const C28xInsn *insn) { + if (insn->nops != 1 || !c28x_is_mem(&insn->ops[0])) { + return NULL; + } + // gd: data bits, gw: CRC bits, gm: the CRC's mask, gp: the polynomial + RzILOpPure *d = ADD(LOGAND(VARG("vcrcsize"), UN(32, 7)), UN(32, 1)); + RzILOpPure *w = ADD(LOGAND(SHIFTR0(VARG("vcrcsize"), UN(8, 16)), UN(32, 0x1f)), UN(32, 1)); + RzILOpPure *m = UNSIGNED(32, SUB(SHIFTL0(UN(64, 1), VARL("gw")), UN(64, 1))); + RzILOpEffect *sizes = SEQ4(SETL("gd", d), SETL("gw", w), SETL("gm", m), + SETL("gp", LOGAND(VARG("vcrcpoly"), VARL("gm")))); + // CRCMSGFLIP reverses the data bits alone: reversing the byte leaves them on top + RzILOpPure *flipped = SHIFTR0(c28x_rev8("cd"), SUB(UN(32, 8), VARL("gd"))); + RzILOpPure *dmask = SUB(SHIFTL0(UN(32, 1), VARL("gd")), UN(32, 1)); + RzILOpBool *flip = c28x_vs_bit(C28X_VS_CRCMSGFLIP); + RzILOpEffect *data = SETL("cd", LOGAND(ITE(flip, flipped, VARL("cd")), dmask)); + RzILOpEffect *body = SEQ4(sizes, c28x_crc_byte(insn->id == C28X_INS_VCRCH, false), data, + SETL("cr", LOGAND(VARG("vcrc"), VARL("gm")))); + for (ut32 j = 0; j < 8; j++) { + RzILOpPure *at = SUB(SUB(VARL("gd"), UN(32, 1)), UN(32, j)); + RzILOpPure *bit = LOGAND(SHIFTR0(VARL("cd"), at), UN(32, 1)); + RzILOpPure *msb = SUB(VARL("gw"), UN(32, 1)); + RzILOpPure *top = LOGAND(SHIFTR0(VARL("cr"), msb), UN(32, 1)); + RzILOpPure *shifted = LOGAND(SHIFTL0(VARL("cr"), UN(8, 1)), VARL("gm")); + RzILOpBool *fb = NON_ZERO(LOGXOR(bit, top)); + RzILOpPure *next = ITE(fb, LOGXOR(shifted, VARL("gp")), DUP(shifted)); + RzILOpBool *active = ULT(UN(32, j), VARL("gd")); + body = SEQ2(body, SETL("cr", ITE(active, next, VARL("cr")))); + } + RzILOpPure *keep = LOGAND(VARG("vcrc"), LOGNOT(VARL("gm"))); + body = SEQ2(body, SETG("vcrc", LOGOR(keep, VARL("cr")))); + return c28x_with_mem(&insn->ops[0], false, body); +} + +/** + * \brief VSWAPCRC swaps VCRC's low two bytes. + */ +static RzILOpEffect *c28x_vcu_swapcrc(RZ_UNUSED const C28xInsn *insn) { + RzILOpPure *low = SHIFTL0(LOGAND(VARG("vcrc"), UN(32, 0xff)), UN(8, 8)); + RzILOpPure *high = LOGAND(SHIFTR0(VARG("vcrc"), UN(8, 8)), UN(32, 0xff)); + return SETG("vcrc", LOGOR(LOGAND(VARG("vcrc"), UN(32, 0xffff0000)), LOGOR(low, high))); +} + +/** + * \brief VLSHL32, VLSHR32, VASHL32 and VASHR32 VRa by a 5-bit immediate. + * + * VASHL32 latches OVFR when the signed result overflows, whatever SAT says, + * and saturates it when SAT is set; VASHR32 adds half of the last place + * shifted out before truncating when RND is set (SPRUHS1C section 5.6). + */ +static RzILOpEffect *c28x_vcu_shift(const C28xInsn *insn) { + const char *a = insn->nops == 2 ? c28x_vr_name(&insn->ops[0]) : NULL; + const C28xOpKind k = insn->ops[1].kind; + if (!a || (k != C28X_OP_VSHL && k != C28X_OP_VSHR)) { + return NULL; + } + const ut32 n = (ut32)insn->ops[1].imm & 31; + if (insn->id == C28X_INS_VLSHL32) { + return SETG(a, SHIFTL0(VARG(a), UN(8, n))); + } + if (insn->id == C28X_INS_VLSHR32) { + return SETG(a, SHIFTR0(VARG(a), UN(8, n))); + } + if (insn->id == C28X_INS_VASHR32) { + RzILOpPure *half = UN(64, n ? 1ULL << (n - 1) : 0); + RzILOpPure *rnd = UNSIGNED(32, SHIFTRA(ADD(SIGNED(64, VARG(a)), half), UN(8, n))); + RzILOpPure *trunc = UNSIGNED(32, SHIFTRA(SIGNED(64, VARG(a)), UN(8, n))); + return SETG(a, ITE(c28x_vs_bit(C28X_VS_RND), rnd, trunc)); + } + if (insn->id != C28X_INS_VASHL32) { + return NULL; + } + RzILOpPure *wide = SHIFTL0(SIGNED(64, VARG(a)), UN(8, n)); + RzILOpBool *ov = INV(EQ(VARL("sw"), SIGNED(64, UNSIGNED(32, VARL("sw"))))); + RzILOpPure *limit = ITE(MSB(VARG(a)), UN(32, 0x80000000), UN(32, 0x7fffffff)); + RzILOpBool *clamp = AND(c28x_vs_bit(C28X_VS_SAT), VARL("so")); + RzILOpPure *res = ITE(clamp, limit, UNSIGNED(32, VARL("sw"))); + RzILOpBool *ovfr = OR(c28x_vs_bit(C28X_VS_OVFR), VARL("so")); + RzILOpEffect *flag = c28x_vs_set(C28X_VS_OVFR, ITE(ovfr, UN(8, 1), UN(8, 0))); + return SEQ4(SETL("sw", wide), SETL("so", ov), flag, SETG(a, res)); +} + +/** + * \brief VINC and VDEC VRaL, alone or with a parallel VMOV32 VRb,mem32: VRaL + * wraps, and no flag changes. + */ +static RzILOpEffect *c28x_vcu_incdec(const C28xInsn *insn) { + const bool par = insn->nops == 4 && insn->ops[1].kind == C28X_OP_PAR; + if (insn->nops != 1 && !par) { + return NULL; + } + RzILOpPure *v = c28x_vcu_read(&insn->ops[0]); + if (!v || insn->ops[0].kind != C28X_OP_REG_LOW) { + rz_il_op_pure_free(v); + return NULL; + } + RzILOpPure *step = insn->id == C28X_INS_VINC ? ADD(v, UN(16, 1)) : SUB(v, UN(16, 1)); + RzILOpEffect *wr = c28x_vcu_write(&insn->ops[0], step); + if (!par) { + return wr; + } + RzILOpEffect *load = NULL; + if (c28x_is_mem(&insn->ops[3])) { + load = c28x_vcu_write(&insn->ops[2], c28x_ea_load(32)); + } + if (!wr || !load) { + rz_il_op_effect_free(wr); + rz_il_op_effect_free(load); + return NULL; + } + return c28x_with_mem(&insn->ops[3], true, SEQ2(wr, load)); +} + +/** + * \brief VBITFLIP reverses VRa's bits, VREVB its bytes. + */ +static RzILOpEffect *c28x_vcu_reverse(const C28xInsn *insn) { + const char *a = insn->nops == 1 ? c28x_vr_name(&insn->ops[0]) : NULL; + if (!a) { + return NULL; + } + // swap ever wider neighbouring groups: bits, pairs, nibbles, then bytes and halves + static const ut32 masks[] = { 0x55555555, 0x33333333, 0x0f0f0f0f, 0x00ff00ff, 0x0000ffff }; + const size_t from = insn->id == C28X_INS_VREVB ? 3 : 0; + RzILOpEffect *eff = SETL("rv", VARG(a)); + for (size_t i = from; i < RZ_ARRAY_SIZE(masks); i++) { + const ut32 s = 1U << i; + RzILOpPure *lo = SHIFTL0(LOGAND(VARL("rv"), UN(32, masks[i])), UN(8, s)); + RzILOpPure *hi = LOGAND(SHIFTR0(VARL("rv"), UN(8, s)), UN(32, masks[i])); + eff = SEQ2(eff, SETL("rv", LOGOR(lo, hi))); + } + return SEQ2(eff, SETG(a, VARL("rv"))); +} + +static RzILOpEffect *c28x_vcu_nop(RZ_UNUSED const C28xInsn *insn) { + return NOP(); +} + +static const C28xVcuLifter c28x_vcu_lifters[] = { + [C28X_INS_VSETSHL] = c28x_vcu_set, + [C28X_INS_VSETSHR] = c28x_vcu_set, + [C28X_INS_VSETK] = c28x_vcu_set, + [C28X_INS_VSATON] = c28x_vcu_set, + [C28X_INS_VSATOFF] = c28x_vcu_set, + [C28X_INS_VRNDON] = c28x_vcu_set, + [C28X_INS_VRNDOFF] = c28x_vcu_set, + [C28X_INS_A_VCLROVFI] = c28x_vcu_set, + [C28X_INS_A_VCLROVFR] = c28x_vcu_set, + [C28X_INS_VSETCPACK] = c28x_vcu_set, + [C28X_INS_VCLRCPACK] = c28x_vcu_set, + [C28X_INS_VSETOPACK] = c28x_vcu_set, + [C28X_INS_VCLROPACK] = c28x_vcu_set, + [C28X_INS_VSETCRCMSGFLIP] = c28x_vcu_set, + [C28X_INS_VCLRCRCMSGFLIP] = c28x_vcu_set, + [C28X_INS_VCLRDIVE] = c28x_vcu_set, + [C28X_INS_VCLEAR] = c28x_vcu_clear, + [C28X_INS_VCLEARALL] = c28x_vcu_clear, + [C28X_INS_VTCLEAR] = c28x_vcu_clear, + [C28X_INS_VCRCCLR] = c28x_vcu_clear, + [C28X_INS_VNOP] = c28x_vcu_nop, + [C28X_INS_VMOV32] = c28x_vcu_mov, + [C28X_INS_VMOV16] = c28x_vcu_mov, + [C28X_INS_VMOVZI] = c28x_vcu_movi, + [C28X_INS_VMOVXI] = c28x_vcu_movi, + [C28X_INS_VMOVIX] = c28x_vcu_movi, + [C28X_INS_VMOVD32] = c28x_vcu_movd32, + [C28X_INS_VSWAP32] = c28x_vcu_swap, + [C28X_INS_VXORMOV32] = c28x_vcu_xormov, + [C28X_INS_VSETCRCSIZE] = c28x_vcu_setcrcsize, + [C28X_INS_VCRC8L_1] = c28x_vcu_crc, + [C28X_INS_VCRC8H_1] = c28x_vcu_crc, + [C28X_INS_VCRC16P1L_1] = c28x_vcu_crc, + [C28X_INS_VCRC16P1H_1] = c28x_vcu_crc, + [C28X_INS_VCRC16P2L_1] = c28x_vcu_crc, + [C28X_INS_VCRC16P2H_1] = c28x_vcu_crc, + [C28X_INS_VCRC24L_1] = c28x_vcu_crc, + [C28X_INS_VCRC24H_1] = c28x_vcu_crc, + [C28X_INS_VCRC32L_1] = c28x_vcu_crc, + [C28X_INS_VCRC32H_1] = c28x_vcu_crc, + [C28X_INS_VCRC32P2L_1] = c28x_vcu_crc, + [C28X_INS_VCRC32P2H_1] = c28x_vcu_crc, + [C28X_INS_VCRCL] = c28x_vcu_crcgen, + [C28X_INS_VCRCH] = c28x_vcu_crcgen, + [C28X_INS_VSWAPCRC] = c28x_vcu_swapcrc, + [C28X_INS_VLSHL32] = c28x_vcu_shift, + [C28X_INS_VLSHR32] = c28x_vcu_shift, + [C28X_INS_VASHL32] = c28x_vcu_shift, + [C28X_INS_VASHR32] = c28x_vcu_shift, + [C28X_INS_VINC] = c28x_vcu_incdec, + [C28X_INS_VDEC] = c28x_vcu_incdec, + [C28X_INS_VBITFLIP] = c28x_vcu_reverse, + [C28X_INS_VREVB] = c28x_vcu_reverse, +}; + +/** \brief Lift the VCU instruction \p insn; NULL while it has no IL yet. */ +RZ_IPI RzILOpEffect *c28x_lift_vcu(const C28xInsn *insn, RZ_UNUSED ut64 pc) { + if ((size_t)insn->id >= RZ_ARRAY_SIZE(c28x_vcu_lifters) || !c28x_vcu_lifters[insn->id]) { + return NULL; + } + return c28x_vcu_lifters[insn->id](insn); +} diff --git a/librz/arch/isa/tms320/c28x/c28x_rowdefs.h b/librz/arch/isa/tms320/c28x/c28x_rowdefs.h index f308b4d540..0e7cf91378 100644 --- a/librz/arch/isa/tms320/c28x/c28x_rowdefs.h +++ b/librz/arch/isa/tms320/c28x/c28x_rowdefs.h @@ -18,16 +18,32 @@ // operand extractors; \p lo is the low bit inside the packed opcode #define REG(r_) { C28X_OD_REG, 0, 0, C28X_REG_##r_ } -#define AXREG { C28X_OD_AX, 24, 1, 0 } +// VCU registers are picked by a field rather than fixed, so the base is stored +// in the extra slot and the field index is added to it when decoding +#define VRREG(lo_) { C28X_OD_REGSEL, (lo_), 4, C28X_REG_VR0 } +// three-bit form: the VCU's multi-register instructions reach VR0-VR7 only +#define VRREG3(lo_) { C28X_OD_REGSEL, (lo_), 3, C28X_REG_VR0 } +// the low half of a VCU register, which VDEC names +#define VRREGL(lo_) { C28X_OD_REGSEL_LOW, (lo_), 3, C28X_REG_VR0 } +#define VTREG(lo_) { C28X_OD_REGSEL, (lo_), 1, C28X_REG_VT0 } +#define VTREG2(lo_) { C28X_OD_REGSEL, (lo_), 2, C28X_REG_VT0 } +#define VRLFIX(n_) { C28X_OD_REGSEL_LOW, 0, 0, C28X_REG_VR##n_ } +#define VRHFIX(n_) { C28X_OD_REGSEL_HIGH, 0, 0, C28X_REG_VR##n_ } +#define AXREG { C28X_OD_AX, 24, 1, 0 } // AX addressed as its low or high byte ("AL.LSB", "AH.MSB") -#define AXLSB { C28X_OD_AX, 24, 1, 1 } -#define AXMSB { C28X_OD_AX, 24, 1, 2 } -#define XARN(lo_) { C28X_OD_XAR, (lo_), 3, 0 } -#define ARN(lo_) { C28X_OD_AR, (lo_), 3, 0 } -#define ARPN(lo_) { C28X_OD_ARP, (lo_), 3, 0 } -#define LOC16(lo_) { C28X_OD_LOC, (lo_), 8, 0 } -#define LOC32(lo_) { C28X_OD_LOC, (lo_), 8, 1 } -#define IMMU(lo_, w_) { C28X_OD_IMM, (lo_), (w_), 0 } +#define AXLSB { C28X_OD_AX, 24, 1, 1 } +#define AXMSB { C28X_OD_AX, 24, 1, 2 } +#define XARN(lo_) { C28X_OD_XAR, (lo_), 3, 0 } +#define ARN(lo_) { C28X_OD_AR, (lo_), 3, 0 } +#define ARPN(lo_) { C28X_OD_ARP, (lo_), 3, 0 } +#define LOC16(lo_) { C28X_OD_LOC, (lo_), 8, 0 } +#define LOC32(lo_) { C28X_OD_LOC, (lo_), 8, 1 } +#define IMMU(lo_, w_) { C28X_OD_IMM, (lo_), (w_), 0 } +// A 16-bit immediate split across both words: \p lo_ and \p w_ locate the low +// part, \p hi_ the low bit of the remaining high bits (VMOVXI and friends) +#define IMMSPLIT(lo_, w_, hi_) { C28X_OD_IMM_SPLIT, (lo_), (w_), (hi_) } +// An immediate the opcode fixes rather than encodes (the VCFFT stage number) +#define IMMV(v_) { C28X_OD_IMMV, 0, 0, (v_) } #define IMMS(lo_, w_) { C28X_OD_IMM, (lo_), (w_), 1 } #define IMMC(v_) { C28X_OD_IMMFIX, 0, 0, (v_) } #define SHIFT(lo_, w_) { C28X_OD_SHIFT, (lo_), (w_), 0 } @@ -61,4 +77,13 @@ { C28X_OD_INTR, (lo_), 4, 0 } // A row is repeatable under RPT, which the analysis layer reports as a hint. -#define RPTABLE .repeatable = true +#define RPTABLE .repeatable = true +#define PAR(id_) { C28X_OD_PAR, 0, 0, C28X_INS_##id_ } +#define VRREGH(lo_) { C28X_OD_REGSEL_HIGH, (lo_), 3, C28X_REG_VR0 } +#define VRREGL4(lo_) { C28X_OD_REGSEL_LOW, (lo_), 4, C28X_REG_VR0 } +#define VRSPLIT(lo_, w_, hi_) { C28X_OD_REGSEL_SPLIT, (lo_), (w_), (hi_) } +#define VSMPAIR(lo_, w_) { C28X_OD_VSMPAIR, (lo_), (w_), 0 } +#define VSHIFT(lo_, w_, right_) { C28X_OD_VSHIFT, (lo_), (w_), (right_) } +#define VRREGH4(lo_) { C28X_OD_REGSEL_HIGH, (lo_), 4, C28X_REG_VR0 } +#define IMMDEC(lo_, w_) { C28X_OD_IMMDEC, (lo_), (w_), 0 } +#define IMMCOLON(lo_, w_) { C28X_OD_IMMCOLON, (lo_), (w_), 0 } diff --git a/librz/arch/isa/tms320/c28x/c28x_rows_vcu.inc b/librz/arch/isa/tms320/c28x/c28x_rows_vcu.inc new file mode 100644 index 0000000000..c1bee36f38 --- /dev/null +++ b/librz/arch/isa/tms320/c28x/c28x_rows_vcu.inc @@ -0,0 +1,208 @@ +// SPDX-FileCopyrightText: 2026 RizinOrg +// SPDX-License-Identifier: LGPL-3.0-only + +// VCU (SPRUHS1) rows, generated against the dis2000 sweep. Do not edit by hand. + +// clang-format off + { OP(0xffff0000, 0xe5020000), .mnem = "vcadd", RZTYPE(MOV), .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2) } }, + { OP(0xffff0000, 0xe5010000), .mnem = "vcmac", RZTYPE(MOV), .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR1), REG(VR0) } }, + { OP(0xffff0000, 0xe50f0000), .mnem = "vccmac", RZTYPE(MOV), .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR1), REG(VR0) } }, + { OP(0xfffffff8, 0xe6f20b08), .mnem = "vdec", RZTYPE(SUB), .len = 4, .ops = { VRREGL(0) } }, + { OP(0xfffffe00, 0xe6810400), .mnem = "vgfacc", RZTYPE(MOV), .len = 4, .ops = { VRREG3(3), VRREG3(0), REG(VR7) } }, + { OP(0xfffffe00, 0xe6802200), .mnem = "vgfmac4", RZTYPE(MOV), .len = 4, .ops = { VRREG3(6), VRREG3(3), VRREG3(0) } }, + { OP(0xfffffe00, 0xe6802000), .mnem = "vgfmpy4", RZTYPE(MOV), .len = 4, .ops = { VRREG3(6), VRREG3(3), VRREG3(0) } }, + { OP(0xfff00000, 0xe5700000), .mnem = "vitdhaddsub", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), VRREG(16) } }, + { OP(0xfff00000, 0xe5f00000), .mnem = "vitdhsubadd", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), VRREG(16) } }, + { OP(0xfff00000, 0xe5300000), .mnem = "vitdladdsub", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), VRREG(16) } }, + { OP(0xfff00000, 0xe5e00000), .mnem = "vitdlsubadd", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), VRREG(16) } }, + { OP(0xffff0000, 0xe52b0000), .mnem = "vcfft1", RZTYPE(MOV), .ops = { REG(VR2), REG(VR5), REG(VR4) } }, + { OP(0xffff0000, 0xe5f30000), .mnem = "vitdhsubadd", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), REG(VR3) } }, + { OP(0xffff0000, 0xe5310000), .mnem = "vitdladdsub", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), REG(VR1) } }, + { OP(0xffff0000, 0xe5330000), .mnem = "vitdladdsub", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), REG(VR3) } }, + { OP(0xffff0000, 0xe5350000), .mnem = "vitdladdsub", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), REG(VR5) } }, + { OP(0xffff0000, 0xe5370000), .mnem = "vitdladdsub", RZTYPE(MOV), .ops = { REG(VR4), REG(VR3), REG(VR2), REG(VR7) } }, + { OP(0xffff0000, 0xe5410000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(1) } }, + { OP(0xffff0000, 0xe54b0000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(11) } }, + { OP(0xffff0000, 0xe54d0000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(13) } }, + { OP(0xffff0000, 0xe54f0000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(15) } }, + { OP(0xffff0000, 0xe5510000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(17) } }, + { OP(0xffff0000, 0xe5530000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(19) } }, + { OP(0xffff0000, 0xe5550000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(21) } }, + { OP(0xffff0000, 0xe5570000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(23) } }, + { OP(0xffff0000, 0xe5590000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(25) } }, + { OP(0xffff0000, 0xe55b0000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(27) } }, + { OP(0xffff0000, 0xe55d0000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(29) } }, + { OP(0xffff0000, 0xe5430000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(3) } }, + { OP(0xffff0000, 0xe5450000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(5) } }, + { OP(0xffff0000, 0xe5470000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(7) } }, + { OP(0xffff0000, 0xe5490000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(9) } }, + { OP(0xffff0000, 0xe52b0000), .mnem = "vcfft1", RZTYPE(MOV), .ops = { REG(VR2), REG(VR5), REG(VR4) } }, + { OP(0xffff0000, 0xe52d0000), .mnem = "vclrcrcmsgflip", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5410000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(1) } }, + { OP(0xffff0000, 0xe54b0000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(11) } }, + { OP(0xffff0000, 0xe54d0000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(13) } }, + { OP(0xffff0000, 0xe5570000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(23) } }, + { OP(0xffff0000, 0xe5430000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(3) } }, + { OP(0xffff0000, 0xe5450000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(5) } }, + { OP(0xffff0000, 0xe5470000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(7) } }, + { OP(0xffff0000, 0xe5490000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMV(9) } }, + { OP(0xfff00000, 0xe7700000), .mnem = "vmovxi", RZTYPE(MOV), .len = 4, .ops = { VRREG(0), IMMSPLIT(4, 12, 16) } }, + { OP(0xfff00000, 0xe7e00000), .mnem = "vmovix", RZTYPE(MOV), .len = 4, .ops = { VRREG(0), IMMSPLIT(4, 12, 16) } }, + { OP(0xfff00000, 0xe7f00000), .mnem = "vmovzi", RZTYPE(MOV), .len = 4, .ops = { VRREG(0), IMMSPLIT(4, 12, 16) } }, + { OP(0xfff00000, 0xa1000000), .mnem = "vcflip", RZTYPE(MOV), .ops = { VRREG(16) } }, + { OP(0xfff00000, 0xa1100000), .mnem = "vccon", RZTYPE(MOV), .ops = { VRREG(16) } }, + { OP(0xfff00000, 0xa1200000), .mnem = "vbitflip", RZTYPE(MOV), .ops = { VRREG(16) } }, + { OP(0xff000000, 0xbd000000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { DMA(0, 16), LOC32(16) } }, + { OP(0xff000000, 0xbf000000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { LOC32(16), DMA(0, 16) } }, + { OP(0xffff0000, 0xe5060000), .mnem = "vsaton", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5070000), .mnem = "vsatoff", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5080000), .mnem = "vrndon", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5090000), .mnem = "vrndoff", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe50c0000), .mnem = "vitbm2", RZTYPE(MOV), .ops = { REG(VR0) } }, + { OP(0xffff0000, 0xe50d0000), .mnem = "vitbm3", RZTYPE(MOV), .ops = { REG(VR0), REG(VR1), REG(VR2) } }, + { OP(0xfff00000, 0xe5100000), .mnem = "vneg", RZTYPE(MOV), .ops = { VRREG(16) } }, + { OP(0xffff0000, 0xe5200000), .mnem = "vclrdive", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5210000), .mnem = "vsetcpack", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5220000), .mnem = "vclrcpack", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5230000), .mnem = "vsetopack", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5240000), .mnem = "vcrcclr", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5250000), .mnem = "vclropack", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5260000), .mnem = "vitstage", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5270000), .mnem = "vnop", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe5290000), .mnem = "vtclear", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe52c0000), .mnem = "vsetcrcmsgflip", RZTYPE(MOV), .ops = { } }, + { OP(0xffff0000, 0xe52d0000), .mnem = "vclrcrcmsgflip", RZTYPE(MOV), .ops = { } }, + { OP(0xffe00000, 0xe5400000), .mnem = "vsetshr", RZTYPE(MOV), .ops = { IMMU(16, 5) } }, + { OP(0xffe00000, 0xe5c00000), .mnem = "vsetshl", RZTYPE(MOV), .ops = { IMMU(16, 5) } }, + +// Rows the first derivation missed, derived with the FPU32 rows from dis2000 +// (C2000 CGT 20.2.6.LTS): the parallel forms, which dis2000 prints on their own +// "||" line, and forms whose operands live in the second word, among them the +// VMOV32 loads and stores. + { OP(0xfffe0000, 0xa1300000), .mnem = "vcfft2", RZTYPE(MOV), .ops = { REG(VR7), REG(VR6), REG(VR4), REG(VR2), REG(VR1), REG(VR0), IMMU(16, 1) } }, // VCFFT2 VR7,VR6,VR4,VR2,VR1,VR0,#1bit + { OP(0xfffe0000, 0xa1320000), .mnem = "vcfft3", RZTYPE(MOV), .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR0), IMMU(16, 1) } }, // VCFFT3 VR5,VR4,VR3,VR2,VR0,#1bit + { OP(0xfffe0000, 0xa1340000), .mnem = "vcfft4", RZTYPE(MOV), .ops = { REG(VR4), REG(VR2), REG(VR1), REG(VR0), IMMU(16, 1) } }, // VCFFT4 VR4,VR2,VR1,VR0,#1bit + { OP(0xfffe0000, 0xa1360000), .mnem = "vcfft8", RZTYPE(MOV), .ops = { REG(VR3), REG(VR2), IMMU(16, 1) } }, // VCFFT8 VR3,VR2,#1bit + { OP(0xfffe0000, 0xa1380000), .mnem = "vcfft9", RZTYPE(MOV), .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR1), REG(VR0), IMMU(16, 1) } }, // VCFFT9 VR5,VR4,VR3,VR2,VR1,VR0,#1bit + { OP(0xfffe0000, 0xa13a0000), .mnem = "vcfft10", RZTYPE(MOV), .ops = { REG(VR7), REG(VR6), REG(VR3), REG(VR2), REG(VR1), REG(VR0), IMMU(16, 1) } }, // VCFFT10 VR7,VR6,VR3,VR2,VR1,VR0,#1bit + { OP(0xfffff000, 0xe2040000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { LOC32(0), VRREG(8) } }, // VMOV32 mem32,VRa + { OP(0xfffffc00, 0xe2050000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { LOC32(0), VTREG2(8) } }, // VMOV32 mem32,VTa + { OP(0xffffff00, 0xe2060000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { LOC32(0), REG(VCRC) } }, // VMOV32 mem32,VCRC + { OP(0xffffff00, 0xe2060100), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { LOC16(0), REG(VCRCPOLY) } }, // VMOV32 mem16,VCRCPOLY + { OP(0xffffff00, 0xe2060200), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { LOC16(0), REG(VCRCSIZE) } }, // VMOV32 mem16,VCRCSIZE + { OP(0xfffff000, 0xe2070000), .mnem = "vcmpy", RZTYPE(MOV), .len = 4, .ops = { REG(VR3), REG(VR2), REG(VR1), REG(VR0), PAR(VMOV32), LOC32(0), VRREG(8) } }, // VCMPY VR3,VR2,VR1,VR0 || VMOV32 mem32,VRa + { OP(0xfffff000, 0xe2071000), .mnem = "vccmpy", RZTYPE(MOV), .len = 4, .ops = { REG(VR3), REG(VR2), REG(VR1), REG(VR0), PAR(VMOV32), LOC32(0), VRREG(8) } }, // VCCMPY VR3,VR2,VR1,VR0 || VMOV32 mem32,VRa + { OP(0xfffffe00, 0xe2072000), .mnem = "vcfft2", RZTYPE(MOV), .len = 4, .ops = { REG(VR7), REG(VR6), REG(VR4), REG(VR2), REG(VR1), REG(VR0), IMMU(8, 1), PAR(VMOV32), LOC32(0), REG(VR1) } }, // VCFFT2 VR7,VR6,VR4,VR2,VR1,VR0,#1bit || VMOV32 mem32,VR1 + { OP(0xfffffe00, 0xe2072200), .mnem = "vcfft5", RZTYPE(MOV), .len = 4, .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR1), REG(VR0), IMMU(8, 1), PAR(VMOV32), LOC32(0), REG(VR1) } }, // VCFFT5 VR5,VR4,VR3,VR2,VR1,VR0,#1bit || VMOV32 mem32,VR1 + { OP(0xfffffe00, 0xe2072400), .mnem = "vcfft6", RZTYPE(MOV), .len = 4, .ops = { REG(VR3), REG(VR2), REG(VR1), REG(VR0), IMMU(8, 1), PAR(VMOV32), LOC32(0), REG(VR1) } }, // VCFFT6 VR3,VR2,VR1,VR0,#1bit || VMOV32 mem32,VR1 + { OP(0xfffffe00, 0xe2072600), .mnem = "vcfft8", RZTYPE(MOV), .len = 4, .ops = { REG(VR3), REG(VR2), IMMU(8, 1), PAR(VMOV32), LOC32(0), REG(VR4) } }, // VCFFT8 VR3,VR2,#1bit || VMOV32 mem32,VR4 + { OP(0xfffffe00, 0xe2072800), .mnem = "vcfft9", RZTYPE(MOV), .len = 4, .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR1), REG(VR0), IMMU(8, 1), PAR(VMOV32), LOC32(0), REG(VR5) } }, // VCFFT9 VR5,VR4,VR3,VR2,VR1,VR0,#1bit || VMOV32 mem32,VR5 + { OP(0xffff0000, 0xe2080000), .mnem = "vitdladdsub", RZTYPE(MOV), .len = 4, .ops = { REG(VR4), REG(VR3), REG(VR2), VRREG(8), PAR(VMOV32), LOC32(0), VRREG(12) } }, // VITDLADDSUB VR4,VR3,VR2,VRa || VMOV32 mem32,VRb + { OP(0xffff0000, 0xe2090000), .mnem = "vitdhaddsub", RZTYPE(MOV), .len = 4, .ops = { REG(VR4), REG(VR3), REG(VR2), VRREG(8), PAR(VMOV32), LOC32(0), VRREG(12) } }, // VITDHADDSUB VR4,VR3,VR2,VRa || VMOV32 mem32,VRb + { OP(0xffff0000, 0xe20a0000), .mnem = "vitdlsubadd", RZTYPE(MOV), .len = 4, .ops = { REG(VR4), REG(VR3), REG(VR2), VRREG(8), PAR(VMOV32), LOC32(0), VRREG(12) } }, // VITDLSUBADD VR4,VR3,VR2,VRa || VMOV32 mem32,VRb + { OP(0xffff0000, 0xe20b0000), .mnem = "vitdhsubadd", RZTYPE(MOV), .len = 4, .ops = { REG(VR4), REG(VR3), REG(VR2), VRREG(8), PAR(VMOV32), LOC32(0), VRREG(12) } }, // VITDHSUBADD VR4,VR3,VR2,VRa || VMOV32 mem32,VRb + { OP(0xffffff00, 0xe20c0000), .mnem = "vtrace", RZTYPE(MOV), .len = 4, .ops = { LOC32(0), REG(VR0), REG(VT0), REG(VT1) } }, // VTRACE mem32,VR0,VT0,VT1 + { OP(0xffffff00, 0xe20d0000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { LOC32(0), REG(VSTATUS) } }, // VMOV32 mem32,VSTATUS + { OP(0xffffe000, 0xe20e0000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { LOC32(0), VSMPAIR(8, 5) } }, // VMOV32 mem32,VSMn+1:VSMn + { OP(0xfffff000, 0xe2180000), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { LOC16(0), VRREGL4(8) } }, // VMOV16 mem16,VRaL + { OP(0xfffff000, 0xe2181000), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { LOC16(0), VRREGH4(8) } }, // VMOV16 mem16,VRaH + { OP(0xfffff000, 0xe2240000), .mnem = "vmovd32", RZTYPE(MOV), .len = 4, .ops = { VRREG(8), LOC32(0) } }, // VMOVD32 VRa,mem32 + { OP(0xffffff00, 0xe2510000), .mnem = "vcmac", RZTYPE(MOV), .len = 4, .ops = { REG(VR7), REG(VR6), REG(VR5), REG(VR4), LOC32(0), INDR(XAR_POSTINC, 7) } }, // VCMAC VR7,VR6,VR5,VR4,mem32,*XAR7++ + { OP(0xffffff00, 0xe2800100), .mnem = "vitbm2", RZTYPE(MOV), .len = 4, .ops = { REG(VR0), LOC32(0) } }, // VITBM2 VR0,mem32 + { OP(0xffffff00, 0xe2800200), .mnem = "vitstage", RZTYPE(MOV), .len = 4, .ops = { PAR(VITBM2), REG(VR0), LOC32(0) } }, // VITSTAGE || VITBM2 VR0,mem32 + { OP(0xffffe000, 0xe2802000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { VSMPAIR(8, 5), LOC32(0) } }, // VMOV32 VSMn+1:VSMn,mem32 + { OP(0xffffc000, 0xe2810000), .mnem = "vinc", RZTYPE(MOV), .len = 4, .ops = { VRREGL(8), PAR(VMOV32), VRREG3(11), LOC32(0) } }, // VINC VRaL || VMOV32 VRb,mem32 + { OP(0xffffc000, 0xe2814000), .mnem = "vdec", RZTYPE(SUB), .len = 4, .ops = { VRREGL(8), PAR(VMOV32), VRREG3(11), LOC32(0) } }, // VDEC VRaL || VMOV32 VRb,mem32 + { OP(0xffffff00, 0xe2b00000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { REG(VSTATUS), LOC32(0) } }, // VMOV32 VSTATUS,mem32 + { OP(0xffffff00, 0xe2b00100), .mnem = "vtrace", RZTYPE(MOV), .len = 4, .ops = { REG(VR1), REG(VR0), REG(VT0), REG(VT1), PAR(VMOV32), REG(VT0), LOC32(0) } }, // VTRACE VR1,VR0,VT0,VT1 || VMOV32 VT0,mem32 + { OP(0xfffffe00, 0xe2b00200), .mnem = "vcfft3", RZTYPE(MOV), .len = 4, .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR0), IMMU(8, 1), PAR(VMOV32), REG(VR5), LOC32(0) } }, // VCFFT3 VR5,VR4,VR3,VR2,VR0,#1bit || VMOV32 VR5,mem32 + { OP(0xfffffe00, 0xe2b00400), .mnem = "vcfft4", RZTYPE(MOV), .len = 4, .ops = { REG(VR4), REG(VR2), REG(VR1), REG(VR0), IMMU(8, 1), PAR(VMOV32), REG(VR7), LOC32(0) } }, // VCFFT4 VR4,VR2,VR1,VR0,#1bit || VMOV32 VR7,mem32 + { OP(0xfffffe00, 0xe2b00600), .mnem = "vcfft7", RZTYPE(MOV), .len = 4, .ops = { REG(VR1), REG(VR0), IMMU(8, 1), PAR(VMOV32), REG(VR2), LOC32(0) } }, // VCFFT7 VR1,VR0,#1bit || VMOV32 VR2,mem32 + { OP(0xfffffe00, 0xe2b00800), .mnem = "vcfft10", RZTYPE(MOV), .len = 4, .ops = { REG(VR7), REG(VR6), REG(VR3), REG(VR2), REG(VR1), REG(VR0), IMMU(8, 1), PAR(VMOV32), REG(VR0), LOC32(0) } }, // VCFFT10 VR7,VR6,VR3,VR2,VR1,VR0,#1bit || VMOV32 VR0,mem32 + { OP(0xffffe000, 0xe2b10000), .mnem = "vpack4", RZTYPE(MOV), .len = 4, .ops = { VRREG3(10), LOC32(0), IMMU(8, 2) } }, // VPACK4 VRa,mem32,#2bit + { OP(0xfffe0000, 0xe2b40000), .mnem = "vgfmpy4", RZTYPE(MOV), .len = 4, .ops = { VRSPLIT(16, 1, 14), VRREG3(11), VRREG3(8), PAR(VMOV32), REG(VR0), LOC32(0) } }, // VGFMPY4 VRa,VRb,VRc || VMOV32 VR0,mem32 + { OP(0xfffe0000, 0xe2b60000), .mnem = "vgfacc", RZTYPE(MOV), .len = 4, .ops = { VRSPLIT(16, 1, 14), VRREG3(11), REG(VR7), PAR(VMOV32), VRREG3(8), LOC32(0) } }, // VGFACC VRa,VRb,VR7 || VMOV32 VRc,mem32 + { OP(0xfff80000, 0xe2b80000), .mnem = "vgfmac4", RZTYPE(MOV), .len = 4, .ops = { VRSPLIT(16, 1, 14), VRREG3(11), VRREG3(8), PAR(VPACK4), REG(VR0), LOC32(0), IMMU(17, 2) } }, // VGFMAC4 VRa,VRb,VRc || VPACK4 VR0,mem32,#2bit + { OP(0xffffff00, 0xe2c10000), .mnem = "vcrc32l_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC32L_1 mem16 + { OP(0xffffff00, 0xe2c20000), .mnem = "vcrc32h_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC32H_1 mem16 + { OP(0xffffff00, 0xe2c50000), .mnem = "vgfinit", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VGFINIT mem16 + { OP(0xffffff00, 0xe2c50100), .mnem = "vsminit", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VSMINIT mem16 + { OP(0xffffff00, 0xe2c50200), .mnem = "vitbm3", RZTYPE(MOV), .len = 4, .ops = { VRLFIX(0), VRLFIX(1), LOC32(0) } }, // VITBM3 VR0L,VR1L,mem32 + { OP(0xffffff00, 0xe2c50300), .mnem = "vitstage", RZTYPE(MOV), .len = 4, .ops = { PAR(VMOV16), VRLFIX(0), LOC32(0) } }, // VITSTAGE || VMOV16 VR0L,mem32 + { OP(0xfffff000, 0xe2c90000), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { VRREGL4(8), LOC16(0) } }, // VMOV16 VRaL,mem16 + { OP(0xfffff000, 0xe2c91000), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { VRREGH4(8), LOC16(0) } }, // VMOV16 VRaH,mem16 + { OP(0xffffff00, 0xe2cb0000), .mnem = "vcrc8l_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC8L_1 mem16 + { OP(0xffffff00, 0xe2cb0100), .mnem = "vcrc24l_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC24L_1 mem16 + { OP(0xffffff00, 0xe2cb0200), .mnem = "vcrc24h_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC24H_1 mem16 + { OP(0xffffff00, 0xe2cb0300), .mnem = "vcrc32p2l_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC32P2L_1 mem16 + { OP(0xffffff00, 0xe2cb0400), .mnem = "vcrc32p2h_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC32P2H_1 mem16 + { OP(0xffffff00, 0xe2cb0500), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { REG(VCRCDSIZE), LOC16(0) } }, // VMOV16 VCRCDSIZE,mem16 + { OP(0xffffff00, 0xe2cb0600), .mnem = "vcrcl", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRCL mem16 + { OP(0xffffff00, 0xe2cb0700), .mnem = "vcrch", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRCH mem16 + { OP(0xffffff00, 0xe2cb0800), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { REG(VCRCPSIZE), LOC16(0) } }, // VMOV16 VCRCPSIZE,mem16 + { OP(0xffffff00, 0xe2cc0000), .mnem = "vcrc8h_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC8H_1 mem16 + { OP(0xffffff00, 0xe2ce0000), .mnem = "vcrc16p1l_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC16P1L_1 mem16 + { OP(0xffffff00, 0xe2ce1000), .mnem = "vcrc16p2l_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC16P2L_1 mem16 + { OP(0xffffff00, 0xe2cf0000), .mnem = "vcrc16p1h_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC16P1H_1 mem16 + { OP(0xffffff00, 0xe2cf1000), .mnem = "vcrc16p2h_1", RZTYPE(MOV), .len = 4, .ops = { LOC16(0) } }, // VCRC16P2H_1 mem16 + { OP(0xfffff000, 0xe3f00000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { VRREG(8), LOC32(0) } }, // VMOV32 VRa,mem32 + { OP(0xfffff000, 0xe3f01000), .mnem = "vxormov32", RZTYPE(MOV), .len = 4, .ops = { VRREG(8), LOC16(0) } }, // VXORMOV32 VRa,mem16 + { OP(0xfffffc00, 0xe3f10000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { VTREG2(8), LOC32(0) } }, // VMOV32 VTa,mem32 + { OP(0xffffff00, 0xe3f20000), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { REG(VCRC), LOC32(0) } }, // VMOV32 VCRC,mem32 + { OP(0xffffff00, 0xe3f20100), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { REG(VCRCPOLY), LOC16(0) } }, // VMOV32 VCRCPOLY,mem16 + { OP(0xffffff00, 0xe3f20200), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { REG(VCRCSIZE), LOC16(0) } }, // VMOV32 VCRCSIZE,mem16 + { OP(0xfffff000, 0xe3f60000), .mnem = "vcmpy", RZTYPE(MOV), .len = 4, .ops = { REG(VR3), REG(VR2), REG(VR1), REG(VR0), PAR(VMOV32), VRREG(8), LOC32(0) } }, // VCMPY VR3,VR2,VR1,VR0 || VMOV32 VRa,mem32 + { OP(0xfffff000, 0xe3f61000), .mnem = "vccmpy", RZTYPE(MOV), .len = 4, .ops = { REG(VR3), REG(VR2), REG(VR1), REG(VR0), PAR(VMOV32), VRREG(8), LOC32(0) } }, // VCCMPY VR3,VR2,VR1,VR0 || VMOV32 VRa,mem32 + { OP(0xfffff000, 0xe3f70000), .mnem = "vcmac", RZTYPE(MOV), .len = 4, .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR1), REG(VR0), PAR(VMOV32), VRREG(8), LOC32(0) } }, // VCMAC VR5,VR4,VR3,VR2,VR1,VR0 || VMOV32 VRa,mem32 + { OP(0xfffff000, 0xe3f71000), .mnem = "vccmac", RZTYPE(MOV), .len = 4, .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), REG(VR1), REG(VR0), PAR(VMOV32), VRREG(8), LOC32(0) } }, // VCCMAC VR5,VR4,VR3,VR2,VR1,VR0 || VMOV32 VRa,mem32 + { OP(0xfffff000, 0xe3f80000), .mnem = "vcadd", RZTYPE(MOV), .len = 4, .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), PAR(VMOV32), VRREG(8), LOC32(0) } }, // VCADD VR5,VR4,VR3,VR2 || VMOV32 VRa,mem32 + { OP(0xfffff000, 0xe3f90000), .mnem = "vcsub", RZTYPE(MOV), .len = 4, .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), PAR(VMOV32), VRREG(8), LOC32(0) } }, // VCSUB VR5,VR4,VR3,VR2 || VMOV32 VRa,mem32 + { OP(0xfffff000, 0xe3fa0000), .mnem = "vcdadd16", RZTYPE(MOV), .len = 4, .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2), PAR(VMOV32), VRREG(8), LOC32(0) } }, // VCDADD16 VR5,VR4,VR3,VR2 || VMOV32 VRa,mem32 + { OP(0xfffff000, 0xe3fb0000), .mnem = "vcdsub16", RZTYPE(MOV), .len = 4, .ops = { REG(VR6), REG(VR4), REG(VR3), REG(VR2), PAR(VMOV32), VRREG(8), LOC32(0) } }, // VCDSUB16 VR6,VR4,VR3,VR2 || VMOV32 VRa,mem32 + { OP(0xffffff00, 0xe3fc0000), .mnem = "vitbm2", RZTYPE(MOV), .len = 4, .ops = { REG(VR0), PAR(VMOV32), REG(VR2), LOC32(0) } }, // VITBM2 VR0 || VMOV32 VR2,mem32 + { OP(0xffffff00, 0xe3fd0000), .mnem = "vitbm3", RZTYPE(MOV), .len = 4, .ops = { REG(VR0), REG(VR1), REG(VR2), PAR(VMOV32), REG(VR2), LOC32(0) } }, // VITBM3 VR0,VR1,VR2 || VMOV32 VR2,mem32 + { OP(0xffff0000, 0xe3fe0000), .mnem = "vitlsel", RZTYPE(MOV), .len = 4, .ops = { VRREG(8), VRREG(12), REG(VR4), REG(VR3), PAR(VMOV32), REG(VR2), LOC32(0) } }, // VITLSEL VRa,VRb,VR4,VR3 || VMOV32 VR2,mem32 + { OP(0xffff0000, 0xe3ff0000), .mnem = "vithsel", RZTYPE(MOV), .len = 4, .ops = { VRREG(8), VRREG(12), REG(VR4), REG(VR3), PAR(VMOV32), REG(VR2), LOC32(0) } }, // VITHSEL VRa,VRb,VR4,VR3 || VMOV32 VR2,mem32 + { OP(0xffff0000, 0xe5000000), .mnem = "vcmpy", RZTYPE(MOV), .ops = { REG(VR3), REG(VR2), REG(VR1), REG(VR0) } }, // VCMPY VR3,VR2,VR1,VR0 + { OP(0xffff0000, 0xe5030000), .mnem = "vcsub", RZTYPE(MOV), .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2) } }, // VCSUB VR5,VR4,VR3,VR2 + { OP(0xffff0000, 0xe5040000), .mnem = "vcdadd16", RZTYPE(MOV), .ops = { REG(VR5), REG(VR4), REG(VR3), REG(VR2) } }, // VCDADD16 VR5,VR4,VR3,VR2 + { OP(0xffff0000, 0xe5050000), .mnem = "vcdsub16", RZTYPE(MOV), .ops = { REG(VR6), REG(VR4), REG(VR3), REG(VR2) } }, // VCDSUB16 VR6,VR4,VR3,VR2 + { OP(0xffff0000, 0xe50a0000), .mnem = "a_vclrovfr", RZTYPE(MOV) }, // A_VCLROVFR + { OP(0xffff0000, 0xe50b0000), .mnem = "a_vclrovfi", RZTYPE(MOV) }, // A_VCLROVFI + { OP(0xffff0000, 0xe50e0000), .mnem = "vccmpy", RZTYPE(MOV), .ops = { REG(VR3), REG(VR2), REG(VR1), REG(VR0) } }, // VCCMPY VR3,VR2,VR1,VR0 + { OP(0xffff0000, 0xe5280000), .mnem = "vtrace", RZTYPE(MOV), .ops = { REG(VR1), REG(VR0), REG(VT0), REG(VT1) } }, // VTRACE VR1,VR0,VT0,VT1 + { OP(0xffff0000, 0xe52a0000), .mnem = "vcadd", RZTYPE(MOV), .ops = { REG(VR7), REG(VR6), REG(VR5), REG(VR4) } }, // VCADD VR7,VR6,VR5,VR4 + { OP(0xffff0000, 0xe52e0000), .mnem = "vswapcrc", RZTYPE(MOV) }, // VSWAPCRC + { OP(0xffffe000, 0xe6800000), .mnem = "vgfadd4", RZTYPE(MOV), .len = 4, .ops = { VRREG3(10), VRREG3(7), VRREG3(4), IMMU(0, 4) } }, // VGFADD4 VRa,VRb,VRc,#4bit + { OP(0xfffffff8, 0xe6802400), .mnem = "vrevb", RZTYPE(MOV), .len = 4, .ops = { VRREG3(0) } }, // VREVB VRa + { OP(0xffffffc0, 0xe6802440), .mnem = "vshlmb", RZTYPE(MOV), .len = 4, .ops = { VRREG3(3), VRREG3(0) } }, // VSHLMB VRa,VRb + { OP(0xfffffe00, 0xe6802600), .mnem = "vmod32", RZTYPE(MOV), .len = 4, .ops = { VRREGH(6), VRREG3(3), VRREGL(0) } }, // VMOD32 VRaH,VRb,VRcL + { OP(0xfffffe00, 0xe6802800), .mnem = "vmod32", RZTYPE(MOV), .len = 4, .ops = { VRREGH(6), VRREG3(3), VRREGH(0) } }, // VMOD32 VRaH,VRb,VRcH + { OP(0xfffffc00, 0xe6810000), .mnem = "vgfacc", RZTYPE(MOV), .len = 4, .ops = { VRREG3(7), VRREG3(4), IMMU(0, 4) } }, // VGFACC VRa,VRb,#4bit + { OP(0xffffff00, 0xe6f20000), .mnem = "vcshl16", RZTYPE(MOV), .len = 4, .ops = { VRREG(0), VSHIFT(4, 4, 0) } }, // VCSHL16 VRa << #shift + { OP(0xffffff00, 0xe6f20100), .mnem = "vcshr16", RZTYPE(MOV), .len = 4, .ops = { VRREG(0), VSHIFT(4, 4, 1) } }, // VCSHR16 VRa >> #shift + { OP(0xffffff00, 0xe6f20200), .mnem = "vmov32", RZTYPE(MOV), .len = 4, .ops = { VRREG(4), VRREG(0) } }, // VMOV32 VRa,VRb + { OP(0xffffff00, 0xe6f20300), .mnem = "vswap32", RZTYPE(MOV), .len = 4, .ops = { VRREG(4), VRREG(0) } }, // VSWAP32 VRa,VRb + { OP(0xffffff00, 0xe6f20400), .mnem = "vcmag", RZTYPE(MOV), .len = 4, .ops = { VRREG(4), VRREG(0) } }, // VCMAG VRa,VRb + { OP(0xffffff00, 0xe6f20500), .mnem = "vlshl32", RZTYPE(MOV), .len = 4, .ops = { VRREG3(0), VSHIFT(3, 5, 0) } }, // VLSHL32 VRa << #shift + { OP(0xffffff00, 0xe6f20600), .mnem = "vlshr32", RZTYPE(MOV), .len = 4, .ops = { VRREG3(0), VSHIFT(3, 5, 1) } }, // VLSHR32 VRa >> #shift + { OP(0xffffff00, 0xe6f20700), .mnem = "vashl32", RZTYPE(MOV), .len = 4, .ops = { VRREG3(0), VSHIFT(3, 5, 0) } }, // VASHL32 VRa << #shift + { OP(0xffffff00, 0xe6f20800), .mnem = "vashr32", RZTYPE(MOV), .len = 4, .ops = { VRREG3(0), VSHIFT(3, 5, 1) } }, // VASHR32 VRa >> #shift + { OP(0xfffffff8, 0xe6f20900), .mnem = "vsetk", RZTYPE(MOV), .len = 4, .ops = { IMMU(0, 3) } }, // VSETK #3bit + { OP(0xffffffc0, 0xe6f20a00), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { VRREGL(0), VRREGH(3) } }, // VMOV16 VRaL,VRbH + { OP(0xffffffc0, 0xe6f20a40), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { VRREGH(0), VRREGL(3) } }, // VMOV16 VRaH,VRbL + { OP(0xffffffc0, 0xe6f20a80), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { VRREGH(0), VRREGH(3) } }, // VMOV16 VRaH,VRbH + { OP(0xffffffc0, 0xe6f20ac0), .mnem = "vmov16", RZTYPE(MOV), .len = 4, .ops = { VRREGL(0), VRREGL(3) } }, // VMOV16 VRaL,VRbL + { OP(0xfffffff8, 0xe6f20b00), .mnem = "vinc", RZTYPE(MOV), .len = 4, .ops = { VRREGL(0) } }, // VINC VRaL + { OP(0xffffffc0, 0xe6f20c00), .mnem = "vmpyadd", RZTYPE(MOV), .len = 4, .ops = { VRREG3(0), VRREGL(0), VRREGH(0), VRREGH(3) } }, // VMPYADD VRa,VRbL,VRcH,VRdH + { OP(0xffffffc0, 0xe6f20c40), .mnem = "vmpyadd", RZTYPE(MOV), .len = 4, .ops = { VRREG3(0), VRREGL(0), VRREGH(0), VRREGL(3) } }, // VMPYADD VRa,VRbL,VRcH,VRdL + { OP(0xffff8000, 0xe6f30000), .mnem = "vmod32", RZTYPE(MOV), .len = 4, .ops = { VRREGH(0), VRREG3(3), VRREGL(6), PAR(VMOV32), VRREG3(9), VRREG3(12) } }, // VMOD32 VRaH,VRb,VRcL || VMOV32 VRd,VRe + { OP(0xffff8000, 0xe6f38000), .mnem = "vmod32", RZTYPE(MOV), .len = 4, .ops = { VRREGH(0), VRREG3(3), VRREGH(6), PAR(VMOV32), VRREG3(9), VRREG3(12) } }, // VMOD32 VRaH,VRb,VRcH || VMOV32 VRd,VRe + { OP(0xffffff00, 0xe6f60000), .mnem = "vitlsel", RZTYPE(MOV), .len = 4, .ops = { VRREG(0), VRREG(4), REG(VR4), REG(VR3) } }, // VITLSEL VRa,VRb,VR4,VR3 + { OP(0xffffff00, 0xe6f70000), .mnem = "vithsel", RZTYPE(MOV), .len = 4, .ops = { VRREG(0), VRREG(4), REG(VR4), REG(VR3) } }, // VITHSEL VRa,VRb,VR4,VR3 + { OP(0xfffffff0, 0xe6f80000), .mnem = "vclear", RZTYPE(MOV), .len = 4, .ops = { VRREG(0) } }, // VCLEAR VRa + { OP(0xffffffff, 0xe6f90000), .mnem = "vclearall", RZTYPE(MOV), .len = 4 }, // VCLEARALL + { OP(0xffff0000, 0xe7540000), .mnem = "vmovzi", RZTYPE(MOV), .len = 4, .ops = { REG(VCRCPOLY), IMMU(0, 16) } }, // VMOVZI VCRCPOLY,#16bit + { OP(0xffff0000, 0xe7550000), .mnem = "vmovix", RZTYPE(MOV), .len = 4, .ops = { REG(VCRCPOLY), IMMU(0, 16) } }, // VMOVIX VCRCPOLY,#16bit + { OP(0xffff0000, 0xe7560000), .mnem = "vsetcrcsize", RZTYPE(MOV), .len = 4, .ops = { IMMDEC(0, 5), IMMCOLON(8, 3) } }, // VSETCRCSIZE #a:#b + // clang-format on diff --git a/librz/arch/isa/tms320/c28x/c28x_rowundefs.h b/librz/arch/isa/tms320/c28x/c28x_rowundefs.h index f36598ffce..5acc065886 100644 --- a/librz/arch/isa/tms320/c28x/c28x_rowundefs.h +++ b/librz/arch/isa/tms320/c28x/c28x_rowundefs.h @@ -5,6 +5,10 @@ #undef OP #undef REG +#undef VRREG +#undef VRREG3 +#undef VRREGL +#undef VTREG #undef AXREG #undef XARN #undef ARN @@ -12,6 +16,8 @@ #undef LOC16 #undef LOC32 #undef IMMU +#undef IMMSPLIT +#undef IMMV #undef IMMS #undef IMMC #undef SHIFT @@ -31,3 +37,15 @@ #undef AXAT #undef INTRN #undef RPTABLE +#undef PAR +#undef VRREGH +#undef VRREGL4 +#undef VRSPLIT +#undef VSMPAIR +#undef VSHIFT +#undef IMMDEC +#undef IMMCOLON +#undef VRREGH4 +#undef VTREG2 +#undef VRLFIX +#undef VRHFIX diff --git a/librz/arch/meson.build b/librz/arch/meson.build index fff53a7a65..a7f56e2c7e 100644 --- a/librz/arch/meson.build +++ b/librz/arch/meson.build @@ -341,6 +341,7 @@ arch_isa_sources = [ 'isa/tms320/c28x/c28x_format.c', 'isa/tms320/c28x/c28x_analysis.c', 'isa/tms320/c28x/c28x_il.c', + 'isa/tms320/c28x/c28x_il_vcu.c', 'isa/tms320/tms320c55x_insn.c', 'isa/v810/v810_disas.c', 'isa/v810/v810_il.c', diff --git a/librz/arch/p/analysis/analysis_tms320.c b/librz/arch/p/analysis/analysis_tms320.c index dcfe9aa0bb..a6905d03a6 100644 --- a/librz/arch/p/analysis/analysis_tms320.c +++ b/librz/arch/p/analysis/analysis_tms320.c @@ -566,6 +566,85 @@ static char *get_reg_profile(RZ_BORROW RzAnalysis *a) { "gpr spa .1 81.0 0\n" // Stack-pointer alignment record "gpr pm .3 82.0 0\n" // Product shift mode "gpr ovc .6 83.0 0\n" // Overflow counter + "gpr vr0 .32 88 0\n" // VCU result register 0 + "gpr vr1 .32 92 0\n" // VCU result register 1 + "gpr vr2 .32 96 0\n" // VCU result register 2 + "gpr vr3 .32 100 0\n" // VCU result register 3 + "gpr vr4 .32 104 0\n" // VCU result register 4 + "gpr vr5 .32 108 0\n" // VCU result register 5 + "gpr vr6 .32 112 0\n" // VCU result register 6 + "gpr vr7 .32 116 0\n" // VCU result register 7 + "gpr vr8 .32 120 0\n" // VCU result register 8 + "gpr vt0 .32 124 0\n" // VCU shift/status + "gpr vt1 .32 128 0\n" + "gpr vstatus .32 280 0\n" // VCU status and configuration + "gpr vcrc .32 284 0\n" // CRC result + "gpr vcrcpoly .32 288 0\n" // CRC polynomial (VCU-II) + "gpr vcrcsize .32 292 0\n" // CRC polynomial and data sizes (VCU-II) + "gpr vsm0 .16 296 0\n" // Viterbi state metric (VCU-II) + "gpr vsm1 .16 298 0\n" + "gpr vsm2 .16 300 0\n" + "gpr vsm3 .16 302 0\n" + "gpr vsm4 .16 304 0\n" + "gpr vsm5 .16 306 0\n" + "gpr vsm6 .16 308 0\n" + "gpr vsm7 .16 310 0\n" + "gpr vsm8 .16 312 0\n" + "gpr vsm9 .16 314 0\n" + "gpr vsm10 .16 316 0\n" + "gpr vsm11 .16 318 0\n" + "gpr vsm12 .16 320 0\n" + "gpr vsm13 .16 322 0\n" + "gpr vsm14 .16 324 0\n" + "gpr vsm15 .16 326 0\n" + "gpr vsm16 .16 328 0\n" + "gpr vsm17 .16 330 0\n" + "gpr vsm18 .16 332 0\n" + "gpr vsm19 .16 334 0\n" + "gpr vsm20 .16 336 0\n" + "gpr vsm21 .16 338 0\n" + "gpr vsm22 .16 340 0\n" + "gpr vsm23 .16 342 0\n" + "gpr vsm24 .16 344 0\n" + "gpr vsm25 .16 346 0\n" + "gpr vsm26 .16 348 0\n" + "gpr vsm27 .16 350 0\n" + "gpr vsm28 .16 352 0\n" + "gpr vsm29 .16 354 0\n" + "gpr vsm30 .16 356 0\n" + "gpr vsm31 .16 358 0\n" + "gpr vsm32 .16 360 0\n" + "gpr vsm33 .16 362 0\n" + "gpr vsm34 .16 364 0\n" + "gpr vsm35 .16 366 0\n" + "gpr vsm36 .16 368 0\n" + "gpr vsm37 .16 370 0\n" + "gpr vsm38 .16 372 0\n" + "gpr vsm39 .16 374 0\n" + "gpr vsm40 .16 376 0\n" + "gpr vsm41 .16 378 0\n" + "gpr vsm42 .16 380 0\n" + "gpr vsm43 .16 382 0\n" + "gpr vsm44 .16 384 0\n" + "gpr vsm45 .16 386 0\n" + "gpr vsm46 .16 388 0\n" + "gpr vsm47 .16 390 0\n" + "gpr vsm48 .16 392 0\n" + "gpr vsm49 .16 394 0\n" + "gpr vsm50 .16 396 0\n" + "gpr vsm51 .16 398 0\n" + "gpr vsm52 .16 400 0\n" + "gpr vsm53 .16 402 0\n" + "gpr vsm54 .16 404 0\n" + "gpr vsm55 .16 406 0\n" + "gpr vsm56 .16 408 0\n" + "gpr vsm57 .16 410 0\n" + "gpr vsm58 .16 412 0\n" + "gpr vsm59 .16 414 0\n" + "gpr vsm60 .16 416 0\n" + "gpr vsm61 .16 418 0\n" + "gpr vsm62 .16 420 0\n" + "gpr vsm63 .16 422 0\n" "gpr arp .3 84.0 0\n" // Auxiliary register pointer "gpr rptc .8 85.0 0\n" // Repeat counter "gpr eallow .1 86.0 0\n" // Protected-register write enable diff --git a/test/db/asm/tms320_c28x_32 b/test/db/asm/tms320_c28x_32 index 3705d04804..987e951b5f 100644 --- a/test/db/asm/tms320_c28x_32 +++ b/test/db/asm/tms320_c28x_32 @@ -116,3 +116,158 @@ d "sbf 0x20, tc" 10ee 0x0 (branch (var tc) (jmp (bv 32 0x20)) nop) d "sbf 0x20, ntc" 10ef 0x0 (branch (! (var tc)) (jmp (bv 32 0x20)) nop) d "bar 0x0, ar0, ar0, eq" 808f0000 0x0 (branch (== (cast 16 false (var xar0)) (cast 16 false (var xar0))) (jmp (bv 32 0x0)) nop) d "bar 0x0, ar1, ar1, neq" c98f0000 0x0 (branch (! (== (cast 16 false (var xar1)) (cast 16 false (var xar1)))) (jmp (bv 32 0x0)) nop) + +# VCU (SPRUHS1), the co-processor on F2806x and F2837x parts. The result +# register is selected by a field, and dis2000 leaves the operand off for the +# reserved numbers above VR8, which these pin. VMOV32 reaches memory through the +# ordinary loc16 byte rather than anything VCU-specific. +d "vmov32 *(0:0xee00), @0x0d" 0dbd0077 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0xd))) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (storew 0 (* (cast 32 false (bv 32 0x7700)) (bv 32 0x2)) (var mv))) +d "vmov32 *(0:0xee00), ?" adbd0077 0x0 +d "vmov32 ?, *(0:0xee00)" adbf0077 0x0 +d "vmov32 @0x00, *(0:0xee00)" 00bf0077 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x0))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (loadw 0 32 (* (cast 32 false (bv 32 0x7700)) (bv 32 0x2))))) +d "vmov32 *(0:0x1e1e), @acc" a9bd0f0f 0x0 (storew 0 (* (cast 32 false (bv 32 0xf0f)) (bv 32 0x2)) (var acc)) +d "vmov32 *(0:0x1e60), @acc" a9bd300f 0x0 (storew 0 (* (cast 32 false (bv 32 0xf30)) (bv 32 0x2)) (var acc)) +d "vcflip vr0" 00a1 0x0 +d "vcflip vr8" 08a1 0x0 +d "vcflip" 09a1 0x0 +d "vmovzi vr0, #0xc770" fce70077 0x0 (set vr0 (bv 32 0xc770)) +d "vmovxi vr0, #0x770" 70e70077 0x0 (set vr0 (| (& (var vr0) (bv 32 0xffff0000)) (bv 32 0x770))) +d "vitdladdsub vr4, vr3, vr2, vr1" 31e5 0x0 +d "vitdladdsub vr4, vr3, vr2, vr8" 38e5 0x0 +d "vitdladdsub vr4, vr3, vr2" 3fe5 0x0 +d "vgfmac4 vr0, vr1, vr7" 80e60f22 0x0 +d "vgfmpy4 vr2, vr6, vr7" 80e6b720 0x0 +d "vgfacc vr0, vr1, vr7" 81e60104 0x0 +d "vdec vr3l" f2e60b0b 0x0 (set vr3 (| (& (var vr3) (bv 32 0xffff0000)) (cast 32 false (- (cast 16 false (var vr3)) (bv 16 0x1))))) +d "vcadd vr5, vr4, vr3, vr2" 02e5 0x0 +d "vcmac vr5, vr4, vr3, vr2, vr1, vr0" 01e5 0x0 +d "vccmac vr5, vr4, vr3, vr2, vr1, vr0" 0fe5 0x0 +d "vitbm2 vr0" 0ce5 0x0 +d "vitbm3 vr0, vr1, vr2" 0de5 0x0 +# VCU parallel forms, second-word operands, FFT and CRC; texts agree with TI dis2000 20.2.6.LTS +d "vcfft2 vr7, vr6, vr4, vr2, vr1, vr0, #0x1" 31a1 0x0 +d "vcfft3 vr5, vr4, vr3, vr2, vr0, #0x1" 33a1 0x0 +d "vcfft4 vr4, vr2, vr1, vr0, #0x0" 34a1 0x0 +d "vcfft8 vr3, vr2, #0x0" 36a1 0x0 +d "vcfft9 vr5, vr4, vr3, vr2, vr1, vr0, #0x1" 39a1 0x0 +d "vcfft10 vr7, vr6, vr3, vr2, vr1, vr0, #0x0" 3aa1 0x0 +d "vmov32 *+xar6[5], vr1" 04e2ee01 0x0 (seq (set _ea (+ (var xar6) (bv 32 0x5))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (var vr1))) +d "vmov32 @0x00" 05e20002 0x0 +d "vmov32 *+xar0[7], vcrc" 06e2f800 0x0 (seq (set _ea (+ (var xar0) (bv 32 0x7))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (var vcrc))) +d "vmov32 *+xar6[3], vcrcpoly" 06e2de01 0x0 (seq (set _ea (+ (var xar6) (bv 32 0x3))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (var vcrcpoly))) +d "vmov32 *+xar1[6], vcrcsize" 06e2f102 0x0 (seq (set _ea (+ (var xar1) (bv 32 0x6))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (var vcrcsize))) +d "vcmpy vr3, vr2, vr1, vr0 || vmov32 *xar4++, vr7" 07e28407 0x0 +d "vccmpy vr3, vr2, vr1, vr0 || vmov32 *arp2, vr5" 07e2b215 0x0 +d "vcfft2 vr7, vr6, vr4, vr2, vr1, vr0, #0x1 || vmov32 *+xar5[3], vr1" 07e2dd21 0x0 +d "vcfft5 vr5, vr4, vr3, vr2, vr1, vr0, #0x1 || vmov32 *+xar6[1], vr1" 07e2ce23 0x0 +d "vcfft6 vr3, vr2, vr1, vr0, #0x1 || vmov32 *-sp[26], vr1" 07e25a25 0x0 +d "vcfft8 vr3, vr2, #0x0 || vmov32 *+xar3[4], vr4" 07e2e326 0x0 +d "vcfft9 vr5, vr4, vr3, vr2, vr1, vr0, #0x1 || vmov32 @0x22, vr5" 07e22229 0x0 +d "vitdladdsub vr4, vr3, vr2, vr2 || vmov32 *+xar4[2], vr3" 08e2d432 0x0 +d "vitdhaddsub vr4, vr3, vr2, vr7 || vmov32 *+xar2[1], vr5" 09e2ca57 0x0 +d "vitdlsubadd vr4, vr3, vr2, vr5 || vmov32 *arp3, vr2" 0ae2b325 0x0 +d "vitdhsubadd vr4, vr3, vr2, vr5 || vmov32 *--xar5, vr1" 0be28d15 0x0 +d "vtrace *--xar6, vr0, vt0, vt1" 0ce28e00 0x0 +d "vmov32 @0x3a, vstatus" 0de23a00 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x3a))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (var vstatus))) +d "vmov32 *-sp[1], vsm25:vsm24" 0ee2410c 0x0 (seq (set _ea (cast 32 false (- (var sp) (bv 16 0x1)))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (append (var vsm25) (var vsm24)))) +d "vmov16 *0++, vr0l" 18e2bb00 0x0 (seq (set _ea (ite (== (var arp) (bv 3 0x0)) (var xar0) (ite (== (var arp) (bv 3 0x1)) (var xar1) (ite (== (var arp) (bv 3 0x2)) (var xar2) (ite (== (var arp) (bv 3 0x3)) (var xar3) (ite (== (var arp) (bv 3 0x4)) (var xar4) (ite (== (var arp) (bv 3 0x5)) (var xar5) (ite (== (var arp) (bv 3 0x6)) (var xar6) (var xar7))))))))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (cast 16 false (var vr0))) (set ao (ite (== (var arp) (bv 3 0x0)) (var xar0) (ite (== (var arp) (bv 3 0x1)) (var xar1) (ite (== (var arp) (bv 3 0x2)) (var xar2) (ite (== (var arp) (bv 3 0x3)) (var xar3) (ite (== (var arp) (bv 3 0x4)) (var xar4) (ite (== (var arp) (bv 3 0x5)) (var xar5) (ite (== (var arp) (bv 3 0x6)) (var xar6) (var xar7))))))))) (set an (+ (var ao) (cast 32 false (cast 16 false (var xar0))))) (branch (== (var arp) (bv 3 0x0)) (set xar0 (var an)) (branch (== (var arp) (bv 3 0x1)) (set xar1 (var an)) (branch (== (var arp) (bv 3 0x2)) (set xar2 (var an)) (branch (== (var arp) (bv 3 0x3)) (set xar3 (var an)) (branch (== (var arp) (bv 3 0x4)) (set xar4 (var an)) (branch (== (var arp) (bv 3 0x5)) (set xar5 (var an)) (branch (== (var arp) (bv 3 0x6)) (set xar6 (var an)) (set xar7 (var an)))))))))) +d "vmov16 *-sp[15], vr8h" 18e24f18 0x0 (seq (set _ea (cast 32 false (- (var sp) (bv 16 0xf)))) (storew 0 (* (cast 32 false (var _ea)) (bv 32 0x2)) (cast 16 false (>> (var vr8) (bv 8 0x10) false)))) +d "vmovd32 vr4, *+xar5[3]" 24e2dd04 0x0 (seq (set _ea (+ (var xar5) (bv 32 0x3))) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vr4 (var mv)) (storew 0 (* (cast 32 false (+ (var _ea) (bv 32 0x2))) (bv 32 0x2)) (var mv))) +d "vcmac vr7, vr6, vr5, vr4, *-sp[28], *xar7++" 51e25c00 0x0 +d "vitbm2 vr0, *+xar0[1]" 80e2c801 0x0 +d "vitstage || vitbm2 vr0, @0x38" 80e23802 0x0 +d "vmov32 vsm47:vsm46, *xar5++" 80e28537 0x0 (seq (set _ea (var xar5)) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vsm47 (cast 16 false (>> (var mv) (bv 8 0x10) false))) (set vsm46 (cast 16 false (var mv))) (set xar5 (+ (var xar5) (bv 32 0x2)))) +d "vinc vr1l || vmov32 vr1, *+xar3[1]" 81e2cb09 0x0 (seq (set _ea (+ (var xar3) (bv 32 0x1))) (set vr1 (| (& (var vr1) (bv 32 0xffff0000)) (cast 32 false (+ (cast 16 false (var vr1)) (bv 16 0x1))))) (set vr1 (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2))))) +d "vdec vr2l || vmov32 vr7, @0x3f" 81e23f7a 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x3f))) (set vr2 (| (& (var vr2) (bv 32 0xffff0000)) (cast 32 false (- (cast 16 false (var vr2)) (bv 16 0x1))))) (set vr7 (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2))))) +d "vmov32 vstatus, @0x19" b0e21900 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x19))) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vstatus (var mv))) +d "vtrace vr1, vr0, vt0, vt1 || vmov32 vt0, @0x28" b0e22801 0x0 +d "vcfft3 vr5, vr4, vr3, vr2, vr0, #0x1 || vmov32 vr5, *-sp[19]" b0e25303 0x0 +d "vcfft4 vr4, vr2, vr1, vr0, #0x0 || vmov32 vr7, *+xar0[7]" b0e2f804 0x0 +d "vcfft7 vr1, vr0, #0x0 || vmov32 vr2, *-sp[19]" b0e25306 0x0 +d "vcfft10 vr7, vr6, vr3, vr2, vr1, vr0, #0x0 || vmov32 vr0, *+xar0[2]" b0e2d008 0x0 +d "vpack4 vr4, *-sp[48], #0x1" b1e27011 0x0 +d "vgfmpy4 vr0, vr6, vr2 || vmov32 vr0, *xar1++" b4e28132 0x0 +d "vgfacc vr2, vr1, vr7 || vmov32 vr0, *+xar0[ar0]" b6e29048 0x0 +d "vgfmac4 vr1, vr6, vr4 || vpack4 vr0, *+xar1[7], #0x1" bbe2f934 0x0 +d "vcrc32l_1 *+xar5[1]" c1e2cd00 0x0 (seq (set _ea (+ (var xar5) (bv 32 0x1))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (var cb) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffffffff)) (<< (var cd) (bv 8 0x18) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set vcrc (| (& (var vcrc) (bv 32 0x0)) (var cr)))) +d "vcrc32h_1 @0x36" c2e23600 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x36))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (>> (var cb) (bv 8 0x8) false) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffffffff)) (<< (var cd) (bv 8 0x18) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x4c11db7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set vcrc (| (& (var vcrc) (bv 32 0x0)) (var cr)))) +d "vgfinit *+xar6[7]" c5e2fe00 0x0 +d "vsminit *+xar3[1]" c5e2cb01 0x0 +d "vitbm3 vr0l, vr1l, *+xar4[ar1]" c5e29c02 0x0 +d "vitstage || vmov16 vr0l, *-sp[55]" c5e27703 0x0 +d "vmov16 vr5l, @0x12" c9e21205 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x12))) (set mv (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vr5 (| (& (var vr5) (bv 32 0xffff0000)) (cast 32 false (var mv))))) +d "vmov16 vr2h, @0x20" c9e22012 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x20))) (set mv (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vr2 (| (& (var vr2) (bv 32 0xffff)) (<< (cast 32 false (var mv)) (bv 8 0x10) false)))) +d "vcrc8l_1 *+xar1[2]" cbe2d100 0x0 (seq (set _ea (+ (var xar1) (bv 32 0x2))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (var cb) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xff)) (<< (var cd) (bv 8 0x0) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set vcrc (| (& (var vcrc) (bv 32 0xffffff00)) (var cr)))) +d "vcrc24l_1 @0x18" cbe21801 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x18))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (var cb) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffffff)) (<< (var cd) (bv 8 0x10) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set vcrc (| (& (var vcrc) (bv 32 0xff000000)) (var cr)))) +d "vcrc24h_1 *+xar0[ar0]" cbe29002 0x0 (seq (set _ea (+ (var xar0) (cast 32 false (cast 16 false (var xar0))))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (>> (var cb) (bv 8 0x8) false) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffffff)) (<< (var cd) (bv 8 0x10) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x800000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)) (bv 32 0x5d6dcb)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffff)))) (set vcrc (| (& (var vcrc) (bv 32 0xff000000)) (var cr)))) +d "vcrc32p2l_1 *+xar1[6]" cbe2f103 0x0 (seq (set _ea (+ (var xar1) (bv 32 0x6))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (var cb) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffffffff)) (<< (var cd) (bv 8 0x18) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set vcrc (| (& (var vcrc) (bv 32 0x0)) (var cr)))) +d "vcrc32p2h_1 @0x35" cbe23504 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x35))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (>> (var cb) (bv 8 0x8) false) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffffffff)) (<< (var cd) (bv 8 0x18) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80000000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)) (bv 32 0x1edc6f41)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffffffff)))) (set vcrc (| (& (var vcrc) (bv 32 0x0)) (var cr)))) +d "vmov16 vcrcdsize, *-sp[45]" cbe26d05 0x0 (seq (set _ea (cast 32 false (- (var sp) (bv 16 0x2d)))) (set mv (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vcrcsize (| (& (var vcrcsize) (bv 32 0xfffffff8)) (& (<< (cast 32 false (var mv)) (bv 8 0x0) false) (bv 32 0x7))))) +d "vcrcl *-sp[38]" cbe26606 0x0 (seq (set _ea (cast 32 false (- (var sp) (bv 16 0x26)))) (set gd (+ (& (var vcrcsize) (bv 32 0x7)) (bv 32 0x1))) (set gw (+ (& (>> (var vcrcsize) (bv 8 0x10) false) (bv 32 0x1f)) (bv 32 0x1))) (set gm (cast 32 false (- (<< (bv 64 0x1) (var gw) false) (bv 64 0x1)))) (set gp (& (var vcrcpoly) (var gm))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (var cb) (bv 32 0xff))) (set cd (& (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (>> (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (- (bv 32 0x8) (var gd)) false) (var cd)) (- (<< (bv 32 0x1) (var gd) false) (bv 32 0x1)))) (set cr (& (var vcrc) (var gm))) (set cr (ite (&& (ule (bv 32 0x0) (var gd)) (! (== (bv 32 0x0) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x0)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x1) (var gd)) (! (== (bv 32 0x1) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x1)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x2) (var gd)) (! (== (bv 32 0x2) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x2)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x3) (var gd)) (! (== (bv 32 0x3) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x3)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x4) (var gd)) (! (== (bv 32 0x4) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x4)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x5) (var gd)) (! (== (bv 32 0x5) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x5)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x6) (var gd)) (! (== (bv 32 0x6) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x6)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x7) (var gd)) (! (== (bv 32 0x7) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x7)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set vcrc (| (& (var vcrc) (~ (var gm))) (var cr)))) +d "vcrch *-sp[6]" cbe24607 0x0 (seq (set _ea (cast 32 false (- (var sp) (bv 16 0x6)))) (set gd (+ (& (var vcrcsize) (bv 32 0x7)) (bv 32 0x1))) (set gw (+ (& (>> (var vcrcsize) (bv 8 0x10) false) (bv 32 0x1f)) (bv 32 0x1))) (set gm (cast 32 false (- (<< (bv 64 0x1) (var gw) false) (bv 64 0x1)))) (set gp (& (var vcrcpoly) (var gm))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (>> (var cb) (bv 8 0x8) false) (bv 32 0xff))) (set cd (& (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (>> (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (- (bv 32 0x8) (var gd)) false) (var cd)) (- (<< (bv 32 0x1) (var gd) false) (bv 32 0x1)))) (set cr (& (var vcrc) (var gm))) (set cr (ite (&& (ule (bv 32 0x0) (var gd)) (! (== (bv 32 0x0) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x0)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x1) (var gd)) (! (== (bv 32 0x1) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x1)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x2) (var gd)) (! (== (bv 32 0x2) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x2)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x3) (var gd)) (! (== (bv 32 0x3) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x3)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x4) (var gd)) (! (== (bv 32 0x4) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x4)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x5) (var gd)) (! (== (bv 32 0x5) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x5)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x6) (var gd)) (! (== (bv 32 0x6) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x6)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set cr (ite (&& (ule (bv 32 0x7) (var gd)) (! (== (bv 32 0x7) (var gd)))) (ite (! (is_zero (^ (& (>> (var cd) (- (- (var gd) (bv 32 0x1)) (bv 32 0x7)) false) (bv 32 0x1)) (& (>> (var cr) (- (var gw) (bv 32 0x1)) false) (bv 32 0x1))))) (^ (& (<< (var cr) (bv 8 0x1) false) (var gm)) (var gp)) (& (<< (var cr) (bv 8 0x1) false) (var gm))) (var cr))) (set vcrc (| (& (var vcrc) (~ (var gm))) (var cr)))) +d "vmov16 vcrcpsize, *+xar1[3]" cbe2d908 0x0 (seq (set _ea (+ (var xar1) (bv 32 0x3))) (set mv (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vcrcsize (| (& (var vcrcsize) (bv 32 0xffe0ffff)) (& (<< (cast 32 false (var mv)) (bv 8 0x10) false) (bv 32 0x1f0000))))) +d "vcrc8h_1 *+xar7[5]" cce2ef00 0x0 (seq (set _ea (+ (var xar7) (bv 32 0x5))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (>> (var cb) (bv 8 0x8) false) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xff)) (<< (var cd) (bv 8 0x0) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x80)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)) (bv 32 0x7)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xff)))) (set vcrc (| (& (var vcrc) (bv 32 0xffffff00)) (var cr)))) +d "vcrc16p1l_1 @0x0c" cee20c00 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0xc))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (var cb) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffff)) (<< (var cd) (bv 8 0x8) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set vcrc (| (& (var vcrc) (bv 32 0xffff0000)) (var cr)))) +d "vcrc16p2l_1 @0x27" cee22710 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x27))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (var cb) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffff)) (<< (var cd) (bv 8 0x8) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set vcrc (| (& (var vcrc) (bv 32 0xffff0000)) (var cr)))) +d "vcrc16p1h_1 @0x3a" cfe23a00 0x0 (seq (set _ea (| (<< (cast 32 false (var dp)) (bv 32 0x6) false) (bv 32 0x3a))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (>> (var cb) (bv 8 0x8) false) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffff)) (<< (var cd) (bv 8 0x8) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x8005)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set vcrc (| (& (var vcrc) (bv 32 0xffff0000)) (var cr)))) +d "vcrc16p2h_1 *-sp[13]" cfe24d10 0x0 (seq (set _ea (cast 32 false (- (var sp) (bv 16 0xd)))) (set cb (cast 32 false (loadw 0 16 (* (cast 32 false (var _ea)) (bv 32 0x2))))) (set cd (& (>> (var cb) (bv 8 0x8) false) (bv 32 0xff))) (set cd (ite (! (is_zero (& (var vstatus) (bv 32 0x80000000)))) (| (| (| (| (| (| (| (| (bv 32 0x0) (<< (& (>> (var cd) (bv 8 0x0) false) (bv 32 0x1)) (bv 8 0x7) false)) (<< (& (>> (var cd) (bv 8 0x1) false) (bv 32 0x1)) (bv 8 0x6) false)) (<< (& (>> (var cd) (bv 8 0x2) false) (bv 32 0x1)) (bv 8 0x5) false)) (<< (& (>> (var cd) (bv 8 0x3) false) (bv 32 0x1)) (bv 8 0x4) false)) (<< (& (>> (var cd) (bv 8 0x4) false) (bv 32 0x1)) (bv 8 0x3) false)) (<< (& (>> (var cd) (bv 8 0x5) false) (bv 32 0x1)) (bv 8 0x2) false)) (<< (& (>> (var cd) (bv 8 0x6) false) (bv 32 0x1)) (bv 8 0x1) false)) (<< (& (>> (var cd) (bv 8 0x7) false) (bv 32 0x1)) (bv 8 0x0) false)) (var cd))) (set cr (^ (& (var vcrc) (bv 32 0xffff)) (<< (var cd) (bv 8 0x8) false))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set cr (ite (! (is_zero (& (var cr) (bv 32 0x8000)))) (^ (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)) (bv 32 0x1021)) (& (<< (var cr) (bv 8 0x1) false) (bv 32 0xffff)))) (set vcrc (| (& (var vcrc) (bv 32 0xffff0000)) (var cr)))) +d "vmov32 vr4, *+xar7[0]" f0e3c704 0x0 (seq (set _ea (+ (var xar7) (bv 32 0x0))) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vr4 (var mv))) +d "vxormov32 vr8, *+xar3[6]" f0e3f318 0x0 (seq (set _ea (+ (var xar3) (bv 32 0x6))) (set vr8 (^ (var vr8) (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))))) +d "vmov32 vt0, *-sp[3]" f1e34300 0x0 (seq (set _ea (cast 32 false (- (var sp) (bv 16 0x3)))) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vt0 (var mv))) +d "vmov32 vcrc, *+xar4[0]" f2e3c400 0x0 (seq (set _ea (+ (var xar4) (bv 32 0x0))) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vcrc (var mv))) +d "vmov32 vcrcpoly, *+xar1[ar0]" f2e39101 0x0 (seq (set _ea (+ (var xar1) (cast 32 false (cast 16 false (var xar0))))) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vcrcpoly (var mv))) +d "vmov32 vcrcsize, *-sp[2]" f2e34202 0x0 (seq (set _ea (cast 32 false (- (var sp) (bv 16 0x2)))) (set mv (loadw 0 32 (* (cast 32 false (var _ea)) (bv 32 0x2)))) (set vcrcsize (var mv))) +d "vcmpy vr3, vr2, vr1, vr0 || vmov32 vr5, *-sp[30]" f6e35e05 0x0 +d "vccmpy vr3, vr2, vr1, vr0 || vmov32 vr5, *+xar5[6]" f6e3f515 0x0 +d "vcmac vr5, vr4, vr3, vr2, vr1, vr0 || vmov32 vr6, *+xar1[3]" f7e3d906 0x0 +d "vccmac vr5, vr4, vr3, vr2, vr1, vr0 || vmov32 vr8, @0x0c" f7e30c18 0x0 +d "vcadd vr5, vr4, vr3, vr2 || vmov32 vr1, *+xar7[4]" f8e3e701 0x0 +d "vcsub vr5, vr4, vr3, vr2 || vmov32 vr4, @0x2f" f9e32f04 0x0 +d "vcdadd16 vr5, vr4, vr3, vr2 || vmov32 vr7, @0x1b" fae31b07 0x0 +d "vcdsub16 vr6, vr4, vr3, vr2 || vmov32 vr7, @0x23" fbe32307 0x0 +d "vitbm2 vr0 || vmov32 vr2, *xar3++" fce38300 0x0 +d "vitbm3 vr0, vr1, vr2 || vmov32 vr2, @0x17" fde31700 0x0 +d "vitlsel vr1, vr8, vr4, vr3 || vmov32 vr2, *arp0" fee3b081 0x0 +d "vithsel vr4, vr5, vr4, vr3 || vmov32 vr2, @0x25" ffe32554 0x0 +d "vcmpy vr3, vr2, vr1, vr0" 00e5 0x0 +d "vcsub vr5, vr4, vr3, vr2" 03e5 0x0 +d "vcdadd16 vr5, vr4, vr3, vr2" 04e5 0x0 +d "vcdsub16 vr6, vr4, vr3, vr2" 05e5 0x0 +d "a_vclrovfr" 0ae5 0x0 (set vstatus (| (& (var vstatus) (bv 32 0xffffefff)) (& (<< (cast 32 false (bv 8 0x0)) (bv 8 0xc) false) (bv 32 0x1000)))) +d "a_vclrovfi" 0be5 0x0 (set vstatus (| (& (var vstatus) (bv 32 0xffffdfff)) (& (<< (cast 32 false (bv 8 0x0)) (bv 8 0xd) false) (bv 32 0x2000)))) +d "vccmpy vr3, vr2, vr1, vr0" 0ee5 0x0 +d "vtrace vr1, vr0, vt0, vt1" 28e5 0x0 +d "vcadd vr7, vr6, vr5, vr4" 2ae5 0x0 +d "vswapcrc" 2ee5 0x0 (set vcrc (| (& (var vcrc) (bv 32 0xffff0000)) (| (<< (& (var vcrc) (bv 32 0xff)) (bv 8 0x8) false) (& (>> (var vcrc) (bv 8 0x8) false) (bv 32 0xff))))) +d "vgfadd4 vr4, vr0, vr2, #0x8" 80e62810 0x0 +d "vrevb vr7" 80e60724 0x0 (seq (set rv (var vr7)) (set rv (| (<< (& (var rv) (bv 32 0xff00ff)) (bv 8 0x8) false) (& (>> (var rv) (bv 8 0x8) false) (bv 32 0xff00ff)))) (set rv (| (<< (& (var rv) (bv 32 0xffff)) (bv 8 0x10) false) (& (>> (var rv) (bv 8 0x10) false) (bv 32 0xffff)))) (set vr7 (var rv))) +d "vshlmb vr7, vr4" 80e67c24 0x0 +d "vmod32 vr7h, vr6, vr5l" 80e6f527 0x0 +d "vmod32 vr7h, vr3, vr4h" 80e6dc29 0x0 +d "vgfacc vr7, vr0, #0x0" 81e68003 0x0 +d "vcshl16 vr8 << #7" f2e67800 0x0 +d "vcshr16 vr0 >> #2" f2e62001 0x0 +d "vmov32 vr8, vr3" f2e68302 0x0 (set vr8 (var vr3)) +d "vswap32 vr5, vr7" f2e65703 0x0 (seq (set sa (var vr5)) (set vr5 (var vr7)) (set vr7 (var sa))) +d "vcmag vr2, vr4" f2e62404 0x0 +d "vlshl32 vr1 << #13" f2e66905 0x0 (set vr1 (<< (var vr1) (bv 8 0xd) false)) +d "vlshr32 vr5 >> #14" f2e67506 0x0 (set vr5 (>> (var vr5) (bv 8 0xe) false)) +d "vashl32 vr6 << #19" f2e69e07 0x0 (seq (set sw (<< (cast 64 (msb (var vr6)) (var vr6)) (bv 8 0x13) false)) (set so (! (== (var sw) (cast 64 (msb (cast 32 false (var sw))) (cast 32 false (var sw)))))) (set vstatus (| (& (var vstatus) (bv 32 0xffffefff)) (& (<< (cast 32 false (ite (|| (! (is_zero (& (var vstatus) (bv 32 0x1000)))) (var so)) (bv 8 0x1) (bv 8 0x0))) (bv 8 0xc) false) (bv 32 0x1000)))) (set vr6 (ite (&& (! (is_zero (& (var vstatus) (bv 32 0x400)))) (var so)) (ite (msb (var vr6)) (bv 32 0x80000000) (bv 32 0x7fffffff)) (cast 32 false (var sw))))) +d "vashr32 vr7 >> #9" f2e64f08 0x0 (set vr7 (ite (! (is_zero (& (var vstatus) (bv 32 0x800)))) (cast 32 false (>> (+ (cast 64 (msb (var vr7)) (var vr7)) (bv 64 0x100)) (bv 8 0x9) (msb (+ (cast 64 (msb (var vr7)) (var vr7)) (bv 64 0x100))))) (cast 32 false (>> (cast 64 (msb (var vr7)) (var vr7)) (bv 8 0x9) (msb (cast 64 (msb (var vr7)) (var vr7))))))) +d "vsetk #0x6" f2e60609 0x0 (set vstatus (| (& (var vstatus) (bv 32 0xc7ffffff)) (& (<< (cast 32 false (bv 8 0x6)) (bv 8 0x1b) false) (bv 32 0x38000000)))) +d "vmov16 vr5l, vr4h" f2e6250a 0x0 (set vr5 (| (& (var vr5) (bv 32 0xffff0000)) (cast 32 false (cast 16 false (>> (var vr4) (bv 8 0x10) false))))) +d "vmov16 vr1h, vr3l" f2e6590a 0x0 (set vr1 (| (& (var vr1) (bv 32 0xffff)) (<< (cast 32 false (cast 16 false (var vr3))) (bv 8 0x10) false))) +d "vmov16 vr7h, vr5h" f2e6af0a 0x0 (set vr7 (| (& (var vr7) (bv 32 0xffff)) (<< (cast 32 false (cast 16 false (>> (var vr5) (bv 8 0x10) false))) (bv 8 0x10) false))) +d "vmov16 vr7l, vr2l" f2e6d70a 0x0 (set vr7 (| (& (var vr7) (bv 32 0xffff0000)) (cast 32 false (cast 16 false (var vr2))))) +d "vinc vr2l" f2e6020b 0x0 (set vr2 (| (& (var vr2) (bv 32 0xffff0000)) (cast 32 false (+ (cast 16 false (var vr2)) (bv 16 0x1))))) +d "vmpyadd vr4, vr4l, vr4h, vr5h" f2e62c0c 0x0 +d "vmpyadd vr1, vr1l, vr1h, vr6l" f2e6710c 0x0 +d "vmod32 vr2h, vr0, vr1l || vmov32 vr0, vr5" f3e64250 0x0 +d "vmod32 vr5h, vr6, vr4h || vmov32 vr1, vr0" f3e63583 0x0 +d "vitlsel vr6, vr6, vr4, vr3" f6e66600 0x0 +d "vithsel vr8, vr4, vr4, vr3" f7e64800 0x0 +d "vclear vr0" f8e60000 0x0 (set vr0 (bv 32 0x0)) +d "vclearall" f9e60000 0x0 (seq (set vt0 (bv 32 0x0)) (set vt1 (bv 32 0x0)) (set vr0 (bv 32 0x0)) (set vr1 (bv 32 0x0)) (set vr2 (bv 32 0x0)) (set vr3 (bv 32 0x0)) (set vr4 (bv 32 0x0)) (set vr5 (bv 32 0x0)) (set vr6 (bv 32 0x0)) (set vr7 (bv 32 0x0)) (set vr8 (bv 32 0x0))) +d "vmovzi vcrcpoly, #0x24d0" 54e7d024 0x0 (set vcrcpoly (bv 32 0x24d0)) +d "vmovix vcrcpoly, #0x2d12" 55e7122d 0x0 (set vcrcpoly (| (& (var vcrcpoly) (bv 32 0xffff)) (bv 32 0x2d120000))) +d "vsetcrcsize #3:#2" 56e7238a 0x0 (seq (set vcrcsize (| (& (var vcrcsize) (bv 32 0xffe0ffff)) (& (<< (cast 32 false (bv 8 0x3)) (bv 8 0x10) false) (bv 32 0x1f0000)))) (set vcrcsize (| (& (var vcrcsize) (bv 32 0xfffffff8)) (& (<< (cast 32 false (bv 8 0x2)) (bv 8 0x0) false) (bv 32 0x7))))) diff --git a/test/db/rzil/tms320_c28x b/test/db/rzil/tms320_c28x index 89175f3f1d..9a785ab1c6 100644 --- a/test/db/rzil/tms320_c28x +++ b/test/db/rzil/tms320_c28x @@ -2112,3 +2112,929 @@ acc = 0x00780034 xar2 = 0x00000104 EOF RUN + +# VCU + +NAME=C28x RzIL VM: VCU status fields and clears +FILE=malloc://8192 +CMDS=<> #4 +-- VLSHR32 VR14 +vr1 = 0x01234567 +vashr32 vr1 >> #3 +-- VASHR32 133 truncates to 1 +vr1 = 0x00000001 +vashr32 vr1 >> #3 +-- VASHR32 133 rounds to 2 SPRUHS1C 1.625 +vr1 = 0x00000002 +vashr32 vr1 >> #3 +-- VASHR32 -133 rounds to -2 +vr1 = 0xfffffffe +vashl32 vr1 << #4 +-- VASHL32 overflow wraps, OVFR +vr1 = 0x80000000 +vstatus = 0x00001000 +vashl32 vr1 << #4 +-- VASHL32 overflow saturates with SAT +vr1 = 0x7fffffff +vstatus = 0x00001400 +vashl32 vr1 << #4 +-- VASHL32 negative saturates +vr1 = 0x80000000 +vstatus = 0x00001400 +vashl32 vr1 << #4 +-- VASHL32 no overflow +vr1 = 0x01000000 +vstatus = 0x00000000 +vinc vr1l +-- VINC VR1L wraps +vr1 = 0x12340000 +vdec vr1l +-- VDEC VR1L wraps +vr1 = 0x1234ffff +vinc vr1l || vmov32 vr2, *xar4++ +-- VINC VR1L par VMOV32 VR2,XAR4++ +vr1 = 0x00000006 +vr2 = 0x12345678 +xar4 = 0x00000042 +vbitflip vr1 +-- VBITFLIP VR1 +vr1 = 0x1e6a2c48 +vrevb vr1 +-- VREVB VR1 +vr1 = 0x78563412 +EOF +RUN