/* * Interactive disassembler (IDA). * Copyright (c) 1990-99 by Ilfak Guilfanov. * ALL RIGHTS RESERVED. * E-mail: ig@datarescue.com * * Texas Instruments's TMS5320C54 * */ #include "tms320c54.hpp" #include //-------------------------------------------------------------------------- static int get_signed(int byte, int mask) { int bits = mask >> 1; int sign = bits + 1; if ( byte & sign ) // offset < 0 { byte = ( byte & bits ) - sign; } else // offset >= 0 { byte = byte & mask; } return byte; } //-------------------------------------------------------------------------- static void op_reg_word(insn_t &insn, int op, ushort reg) { if ( op <= 3 ) { insn.ops[op-1].type = o_reg; insn.ops[op-1].dtype = dt_byte; insn.ops[op-1].reg = reg; } else { insn.Op4_type = o_reg; insn.Op4_value = (uchar)reg; } } //-------------------------------------------------------------------------- static void op_bit(op_t &op, char value, bool NoCardinal = true) { op.type = o_bit; op.dtype = dt_byte; op.value = value; op.NoCardinal = NoCardinal; } //-------------------------------------------------------------------------- static void op_imm(op_t &op, int value, bool Signed = false, bool NoCardinal = false) { op.type = o_imm; op.dtype = dt_byte; op.value = value; op.Signed = Signed; op.NoCardinal = NoCardinal; } //-------------------------------------------------------------------------- static void op_mem(insn_t &insn, op_t &op, char dtype, int byte, bool mmr = false) { op.dtype = dtype; if ( (byte & 0x80) == 0 ) // Direct addressing mode { op.addr = byte & 0x7F; if ( !mmr ) { sel_t cpl = get_sreg(insn.ea, CPL); if ( cpl == BADSEL ) cpl = 0; if ( !cpl ) // check ST1:CPL op.type = o_mem; // use DP else op.type = o_local; // use SP if CPL is set } else // MMR (Memory-Mapped Registers) op.type = o_mmr; } else // Indirect addressing mode { // Single-Operand Addressing op.type = o_displ; op.reg = AR0 + (byte & 0x07); op.IndirectAddressingMOD = (byte>>3) & 0xF; if ( op.IndirectAddressingMOD >= 0xC ) // 16-bit long offset (lk) { if ( !mmr ) { if ( op.IndirectAddressingMOD == ABSOLUTE_INDIRECT_ADRESSING ) op.type = o_farmem; op.addr = get_wide_byte(insn.ea+insn.size); insn.size++; } else // invalide indirect addressing modes (p141) { insn.itype = TMS320C54_null; } } } } #define op_Smem(insn, OP, BYTE) op_mem(insn, OP, dt_byte, BYTE, false) #define op_MMR(insn, OP, BYTE) op_mem(insn, OP, dt_byte, BYTE, true) #define op_Lmem(insn, OP, BYTE) op_mem(insn, OP, dt_word, BYTE, false) //-------------------------------------------------------------------------- static void op_MMRxy(insn_t &insn, const op_t &op, ushort byte) { byte &= 0x0F; if ( byte <= 7 ) op_reg_word(insn, op.n+1, AR0+byte); else op_reg_word(insn, op.n+1, SP); } #define op_MMRx(insn, OP, BYTE) op_MMRxy(insn, OP, (BYTE)>>4) #define op_MMRy(insn, OP, BYTE) op_MMRxy(insn, OP, BYTE) //-------------------------------------------------------------------------- static void op_XYmem(op_t &op, int four) { four &= 0xF; op.type = o_displ; op.reg = AR2 + (four & 0x3); // map Dual-Operand Indirect Addressing Types to Single-Operand Indirect Addressing Types four = (four>>2) & 0x3; if ( four < 3 ) op.IndirectAddressingMOD = (uchar)four; else op.IndirectAddressingMOD = 11; } #define op_Xmem(OP,BYTE) op_XYmem(OP, (BYTE)>>4) #define op_Ymem(OP,BYTE) op_XYmem(OP, BYTE) //-------------------------------------------------------------------------- static void op_src_dst(insn_t &insn, int op, int src_dst) { op_reg_word(insn, op, (src_dst & 1) ? B : A); } //-------------------------------------------------------------------------- static void op_lk(insn_t &insn, op_t &op) { op_imm(op, get_wide_byte(insn.ea+insn.size), false, false); insn.size++; } //-------------------------------------------------------------------------- static void op_pmad(insn_t &insn, op_t &op) { op.type = o_near; op.dtype = dt_code; op.addr = get_wide_byte(insn.ea+insn.size); insn.size++; } //-------------------------------------------------------------------------- static void op_pmad_data(insn_t &insn, op_t &op) { op.type = o_near; op.dtype = dt_byte; // o_near with dt_byte - rare combination! op.addr = get_wide_byte(insn.ea+insn.size); insn.size++; } //-------------------------------------------------------------------------- static void op_extpmad(insn_t &insn, op_t &op, int byte) { op.type = o_far; op.dtype = dt_code; op.addr = ((byte & 0x7F) << 16) | get_wide_byte(insn.ea+insn.size); insn.size++; } //-------------------------------------------------------------------------- static void op_dmad(insn_t &insn, op_t &op) { op.type = o_farmem; op.dtype = dt_byte; op.addr = get_wide_byte(insn.ea+insn.size); insn.size++; } //-------------------------------------------------------------------------- static void op_PA(insn_t &insn, op_t &op) { op.type = o_imm; op.dtype = dt_byte; op.value = get_wide_byte(insn.ea+insn.size); op.NoCardinal = true; op.IOimm = true; insn.size++; } //-------------------------------------------------------------------------- static void op_cond8(insn_t &insn, op_t &op, uchar byte) { if ( get_cond8(byte) == NULL ) { insn.itype = TMS320C54_null; return; } op.type = o_cond8; op.value = byte; } //-------------------------------------------------------------------------- static void op_cond8(insn_t &insn, uchar op, uchar byte) { if ( get_cond8(byte) == NULL ) { insn.itype = TMS320C54_null; } else if ( op <= 3 && op > 0 ) { op_cond8(insn, insn.ops[op-1], byte); } else { insn.Op4_type = o_cond8; insn.Op4_value = byte; } } //-------------------------------------------------------------------------- static void op_cond4(insn_t &insn, op_t &op, uchar quart) { quart &= 0xF; // map cond4 to cond8 op_cond8(insn, op, COND8_FROM_COND4 | quart); } //-------------------------------------------------------------------------- static void op_cond2(op_t &op, int cond) { op.type = o_cond2; op.value = cond & 0x3; } //-------------------------------------------------------------------------- // insn.itype must be set to operands static void ops_conds(insn_t &insn, uchar op, int byte) { byte &= 0xFF; int bits7_6 = (byte >> 6) & 0x3; uchar n = 0; // number of operands added if ( bits7_6 == 1 ) // Group 1, = 01?? ???? { if ( byte & 0x7 ) // Category A, 01?? ?MMM with MMM != 0 op_cond8(insn, op+n++, byte & 0xCF); // & 1100 1111 if ( byte & 0x30 ) // Category B, 01MM ???? with MM != 0 op_cond8(insn, op+n++, byte & 0xF8); // & 1111 1000 } else if ( bits7_6 == 0 ) // Group 2, = 00?? ???? { if ( byte & 0x30 ) // Category A, & 0011 0000 op_cond8(insn, op+n++, byte & 0x30); // & 0011 0000 if ( byte & 0x0C ) // Category B, & 0000 1100 op_cond8(insn, op+n++, byte & 0x0C); // & 0000 1100 if ( byte & 0x03 ) // Category C, & 0000 0011 op_cond8(insn, op+n++, byte & 0x03); // & 0000 0011 } else insn.itype = TMS320C54_null; if ( insn.itype != TMS320C54_null ) { if ( n == 0 ) op_cond8(insn, op+n++, COND8_UNC); // modify insn.itype if ( op-1+n <= 3 ) insn.itype += n-1; else insn.itype += 3-op; } } //-------------------------------------------------------------------------- void ana_TMS320C54(insn_t *_insn) { insn_t &insn = *_insn; ushort code = (ushort)get_wide_byte(insn.ea); insn.size = 1; uchar bits7_0 = code & 0xFF; uchar bits4_0 = code & 0x1F; uchar bits3_0 = code & 0xF; uchar bits2_0 = code & 0x7; uchar bits1_0 = code & 0x3; bool bit0 = code & 1; uchar bits8_3 = (code >> 3) & 0x3F; ushort bits15_4 = code >> 4; uchar bits7_4 = bits15_4 & 0xF; uchar bits7_5 = bits7_4 >> 1; uchar bits6_5 = bits7_5 & 0x3; uchar bit7 = bits7_0 >> 7; uchar bits15_8 = code >> 8; uchar bits11_8 = bits15_8 & 0xF; uchar bits9_8 = bits11_8 & 0x3; bool bit8 = bits9_8 & 1; uchar bits15_9 = code >> 9; uchar bits11_9 = bits15_9 & 0x7; uchar bits10_9 = bits11_9 & 0x3; bool bit9 = bits10_9 & 1; uchar bits15_10 = code >> 10; uchar bits12_10 = bits15_10 & 0x7; uchar bits11_10 = bits12_10 & 0x3; uchar bits15_12 = code >> 12; if ( bits15_8 <= 0x2F ) // <= 0010 11RS // 0000 000S IAAA AAAA ADD Smem, src // 0000 001S IAAA AAAA ADDS Smem, src // 0000 010S IAAA AAAA ADD Smem, TS, src // 0000 011S IAAA AAAA ADDC Smem, src // 0000 100S IAAA AAAA SUB Smem, src // 0000 101S IAAA AAAA SUBS Smem, src // 0000 110S IAAA AAAA SUB Smem, TS, src // 0000 111S IAAA AAAA SUBB Smem, src // 0001 000D IAAA AAAA LD Smem, dst // 0001 001D IAAA AAAA LDU Smem, dst // 0001 010D IAAA AAAA LD Smem, TS, dst // 0001 011D IAAA AAAA LDR Smem, dst // 0001 100S IAAA AAAA AND Smem, src // 0001 101S IAAA AAAA OR Smem, src // 0001 110S IAAA AAAA XOR Smem, src // 0001 111S IAAA AAAA SUBC Smem, src // 0010 00RD IAAA AAAA MPY[R] Smem, dst // 0010 010D IAAA AAAA MPYU Smem, dst // 0010 011D IAAA AAAA SQUR Smem, dst // 0010 10RS IAAA AAAA MAC[R] Smem, src // 0010 11RS IAAA AAAA MAS[R] Smem, src { static const ushort codes[24] = { TMS320C54_add2, TMS320C54_adds, TMS320C54_add3, TMS320C54_addc, TMS320C54_sub2, TMS320C54_subs, TMS320C54_sub3, TMS320C54_subb, TMS320C54_ld2, TMS320C54_ldu, TMS320C54_ld3, TMS320C54_ldr, TMS320C54_and2, TMS320C54_or2, TMS320C54_xor2, TMS320C54_subc, TMS320C54_mpy2, TMS320C54_mpyr2, TMS320C54_mpyu, TMS320C54_squr, TMS320C54_mac2, TMS320C54_macr2, TMS320C54_mas2, TMS320C54_masr2 }; insn.itype = codes[bits15_9]; op_Smem(insn, insn.Op1, code); if ( insn.itype != TMS320C54_add3 && insn.itype != TMS320C54_sub3 && insn.itype != TMS320C54_ld3 ) { op_src_dst(insn, 2, bit8); } else { op_reg_word(insn, 2, TS); op_src_dst(insn, 3, bit8); } } else if ( bits15_8 == 0x30 ) // == 0011 0000 { // 0011 0000 IAAA AAAA LD Smem, T insn.itype = TMS320C54_ld2; op_Smem(insn, insn.Op1, code); op_reg_word(insn, 2, T); } else if ( bits15_8 == 0x32 ) // == 0011 0010 { // 0011 0010 IAAA AAAA LD Smem, ASM insn.itype = TMS320C54_ld2; op_Smem(insn, insn.Op1, code); op_reg_word(insn, 2, ASM); } else if ( bits15_8 <= 0x37 ) // <= 0011 01R1 // 0011 0001 IAAA AAAA MPYA Smem // 0011 0011 IAAA AAAA MASA Smem [,B] // 0011 0100 IAAA AAAA BITT Smem // 0011 0110 IAAA AAAA POLY Smem // 0011 01R1 IAAA AAAA MACA[R] Smem [,B] { static const ushort codes[8] = { TMS320C54_null, TMS320C54_mpya, TMS320C54_null, TMS320C54_masa1, TMS320C54_bitt, TMS320C54_maca1, TMS320C54_poly, TMS320C54_macar1 }; insn.itype = codes[bits11_8]; if ( insn.itype != TMS320C54_null ) op_Smem(insn, insn.Op1, code); } else if ( bits15_8 <= 0x3B ) // <= 0011 101S // 0011 100S IAAA AAAA SQURA Smem, src // 0011 101S IAAA AAAA SQURS Smem, src { insn.itype = bit9 ? TMS320C54_squrs : TMS320C54_squra; op_Smem(insn, insn.Op1, code); op_src_dst(insn, 2, bit8); } else if ( bits15_8 <= 0x45 ) // <= 0100 0101 { // 0011 11SD IAAA AAAA ADD Smem, 16, src [,dst] // 0100 00SD IAAA AAAA SUB Smem, 16, src [,dst] // 0100 010D IAAA AAAA LD Smem, 16, dst static const ushort codes[4] = { TMS320C54_sub3, TMS320C54_ld3, TMS320C54_null, TMS320C54_add3 }; insn.itype = codes[bits11_10]; if ( insn.itype != TMS320C54_null ) { op_Smem(insn, insn.Op1, code); op_bit(insn.Op2, 16); if ( insn.itype != TMS320C54_ld3 ) { op_src_dst(insn, 3, bit9); if ( bit8 != bit9 ) op_src_dst(insn, 4, bit8); } else op_src_dst(insn, 3, bit8); } } else if ( bits15_8 == 0x46 ) // <= 0100 0110 { // 0100 0110 IAAA AAAA LD Smem, DP insn.itype = TMS320C54_ld2; op_Smem(insn, insn.Op1, code); op_reg_word(insn, 2, DP); } else if ( bits15_8 == 0x47 ) // <= 0100 0111 // 0100 0111 IAAA AAAA RPT Smem { insn.itype = TMS320C54_rpt; op_Smem(insn, insn.Op1, code); } else if ( bits15_8 <= 0x4A ) // <= 0100 1010 // 0100 100D IAAA AAAA LDM MMR, dst // 0100 1010 IAAA AAAA PSHM MMR { insn.itype = bit9 ? TMS320C54_pshm : TMS320C54_ldm; op_MMR(insn, insn.Op1, code); if ( insn.itype == TMS320C54_ldm ) op_src_dst(insn, 2, bit8); } else if ( bits15_8 <= 0x4D ) // <= 0100 1101 // 0100 1011 IAAA AAAA PSHD Smem // 0100 1100 IAAA AAAA LTD Smem // 0100 1101 IAAA AAAA DELAY Smem { static const ushort codes[4] = { TMS320C54_ltd, TMS320C54_delay, TMS320C54_null, TMS320C54_pshd }; insn.itype = codes[bits9_8]; if ( insn.itype != TMS320C54_null ) op_Smem(insn, insn.Op1, code); } else if ( bits15_8 <= 0x4F ) // <= 0100 111S // 0100 111S IAAA AAAA DST src, Lmem { insn.itype = TMS320C54_dst; op_src_dst(insn, 1, bit8); op_Lmem(insn, insn.Op2, code); } else if ( bits15_8 <= 0x5F ) // <= 0101 111D // 0101 00SD IAAA AAAA DADD Lmem, src [,dst] // 0101 010S IAAA AAAA DSUB Lmem, src // 0101 011D IAAA AAAA DLD Lmem, dst // 0101 100S IAAA AAAA DRSUB Lmem, src // 0101 101D IAAA AAAA DADST Lmem, dst // 0101 110D IAAA AAAA DSUBT Lmem, dst // 0101 111D IAAA AAAA DSADT Lmem, dst { static const ushort codes[8] = { TMS320C54_dadd2, TMS320C54_dadd2, TMS320C54_dsub, TMS320C54_dld, TMS320C54_drsub, TMS320C54_dadst, TMS320C54_dsubt, TMS320C54_dsadt }; insn.itype = codes[bits11_9]; op_Lmem(insn, insn.Op1, code); if ( insn.itype != TMS320C54_dadd2 ) { op_src_dst(insn, 2, bit8); } else { op_src_dst(insn, 2, bit9); if ( bit8 != bit9 ) { op_src_dst(insn, 3, bit8); insn.itype++; } } } else if ( bits15_8 <= 0x67 ) // <= 0110 01SD // 0110 0000 IAAA AAAA 16-bit constant CMPM Smem, #lk // 0110 0001 IAAA AAAA 16-bit constant BITF Smem, #lk // 0110 001D IAAA AAAA 16-bit constant MPY Smem, #lk, dst // 0110 01SD IAAA AAAA 16-bit constant MAC Smem, #lk, src [,dst] { static const ushort codes[8] = { TMS320C54_cmpm, TMS320C54_bitf, TMS320C54_mpy3, TMS320C54_mpy3, TMS320C54_mac3, TMS320C54_mac3, TMS320C54_mac3, TMS320C54_mac3 }; insn.itype = codes[bits11_8]; op_Smem(insn, insn.Op1, code); op_lk(insn, insn.Op2); // constant always = last word if ( insn.itype == TMS320C54_mpy3 ) { op_src_dst(insn, 3, bit8); } else if ( insn.itype == TMS320C54_mac3 ) { op_src_dst(insn, 3, bit9); if ( bit8 != bit9 ) op_src_dst(insn, 4, bit8); } } else if ( bits15_8 <= 0x6B ) // <= 0110 1011 // 0110 1000 IAAA AAAA 16-bit constant ANDM #lk, Smem // 0110 1001 IAAA AAAA 16-bit constant ORM #lk, Smem // 0110 1010 IAAA AAAA XORM #lk, Smem // 0110 1011 IAAA AAAA 16-bit constant ADDM #lk, Smem { static const ushort codes[4] = { TMS320C54_andm, TMS320C54_orm, TMS320C54_xorm, TMS320C54_addm }; insn.itype = codes[bits9_8]; op_Smem(insn, insn.Op2, code); op_lk(insn, insn.Op1); // constant always = last word } else if ( bits15_8 == 0x6D ) // == 0110 1101 // 0110 1101 IAAA AAAA MAR Smem { insn.itype = TMS320C54_mar; op_Smem(insn, insn.Op1, code); } else if ( bits15_8 == 0x6F ) // == 0110 1111 // 0110 1111 IAAA AAAA 0000 110D 010S HIFT LD Smem [,SHIFT], dst // 0110 1111 IAAA AAAA 0000 110S 011S HIFT STH src [,SHIFT], Smem // 0110 1111 IAAA AAAA 0000 110S 100S HIFT STL src [,SHIFT], Smem // 0110 1111 IAAA AAAA 0000 11SD 000S HIFT ADD Smem [,SHIFT], src [,dst] // 0110 1111 IAAA AAAA 0000 11SD 001S HIFT SUB Smem [,SHIFT], src [,dst] { op_t op; op = insn.Op1; op_Smem(insn, op, code); // IAAA AAAA/Smem eventual offset must be read before 2nd opcode byte! int code2 = get_wide_byte(insn.ea+insn.size); insn.size += 1; int mask1 = code2 & 0xFEE0; //-V537 not misprint int mask2 = code2 & 0xFCE0; if ( mask1 == 0x0C40 ) insn.itype = TMS320C54_ld2; else if ( mask1 == 0x0C60 ) insn.itype = TMS320C54_sth2; else if ( mask1 == 0x0C80 ) insn.itype = TMS320C54_stl2; else if ( mask2 == 0x0C00 ) insn.itype = TMS320C54_add2; else if ( mask2 == 0x0C20 ) insn.itype = TMS320C54_sub2; else insn.itype = TMS320C54_null; if ( insn.itype != TMS320C54_null ) { uchar n = 2; // current operand uchar shift = (uchar)get_signed(code2, 0x1F); if ( shift != 0 ) { op_bit(insn.Op2, shift); n++; insn.itype++; } if ( insn.itype == TMS320C54_ld2 || insn.itype == TMS320C54_ld3 ) { op.n = 0; insn.Op1 = op; // op_Smem(insn, insn.Op1, code); op_src_dst(insn, n, code2>>8); } else if ( insn.itype == TMS320C54_sth2 || insn.itype == TMS320C54_stl2 || insn.itype == TMS320C54_sth3 || insn.itype == TMS320C54_stl3 ) { op_src_dst(insn, 1, code2>>8); op.n = n-1; insn.ops[n-1] = op; // op_Smem(insn, insn.ops[n-1], code); } else if ( insn.itype == TMS320C54_add2 || insn.itype == TMS320C54_sub2 || insn.itype == TMS320C54_add3 || insn.itype == TMS320C54_sub3 ) { int code2_bit9 = (code2>>9) & 1; int code2_bit8 = (code2>>8) & 1; op.n = 0; insn.Op1 = op; // op_Smem(insn, insn.Op1, code); op_src_dst(insn, n, code2_bit9); if ( code2_bit8 != code2_bit9 ) { n++; op_src_dst(insn, n, code2_bit8); if ( n < 4 ) insn.itype++; } } } } else if ( (bits15_8 & 0xFD) == 0x6C ) // == 0110 11Z0 // 0110 11Z0 IAAA AAAA 16-bit constant BANZ[D] pmad, Sind { insn.itype = bit9 ? TMS320C54_banzd : TMS320C54_banz; op_Smem(insn, insn.Op2, code); op_pmad(insn, insn.Op1); if ( insn.Op2.type == o_mem ) { // Sind = Smem to code insn.Op2.type = o_near; insn.Op2.dtype = dt_code; } } else if ( bits15_12 < 0x7 ) // < 0111 insn.itype = TMS320C54_null; else if ( bits15_8 <= 0x73 ) // <= 0111 0000 // 0111 0000 IAAA AAAA 16-bit constant MVKD dmad, Smem // 0111 0001 IAAA AAAA 16-bit constant MVDK Smem, dmad // 0111 0010 IAAA AAAA 16-bit constant MVDM dmad, MMR // 0111 0011 IAAA AAAA 16-bit constant MVMD MMR, dmad { static const ushort codes[4] = { TMS320C54_mvkd, TMS320C54_mvdk, TMS320C54_mvdm, TMS320C54_mvmd }; insn.itype = codes[bits9_8]; switch ( insn.itype ) { case TMS320C54_mvkd: op_Smem(insn, insn.Op2, code); op_dmad(insn, insn.Op1); break; case TMS320C54_mvdk: op_Smem(insn, insn.Op1, code); op_dmad(insn, insn.Op2); break; case TMS320C54_mvdm: op_dmad(insn, insn.Op1); op_MMR(insn, insn.Op2, code); break; case TMS320C54_mvmd: op_MMR(insn, insn.Op1, code); op_dmad(insn, insn.Op2); break; } } else if ( bits15_8 <= 0x75 ) // <= 0111 0101 // 0111 0100 IAAA AAAA Port address PORTR PA, Smem // 0111 0101 IAAA AAAA Port address PORTW Smem, PA { insn.itype = bit8 ? TMS320C54_portw : TMS320C54_portr; op_Smem(insn, insn.ops[1-bit8], code); op_PA(insn, insn.ops[bit8]); } else if ( bits15_8 <= 0x77 ) // <= 0111 0111 // 0111 0110 IAAA AAAA 16-bit constant ST #lk, Smem // 0111 0111 IAAA AAAA 16-bit constant STM #lk, MMR { insn.itype = bit8 ? TMS320C54_stm : TMS320C54_st; op_mem(insn, insn.Op2, dt_byte, code, bit8); op_lk(insn, insn.Op1); // constant always = last word } else if ( bits15_8 <= 0x7B ) // <= 0111 101S // 0111 100S IAAA AAAA 16-bit constant MACP Smem, pmad, src // 0111 101S IAAA AAAA 16-bit constant MACD Smem, pmad, src { insn.itype = bit9 ? TMS320C54_macd : TMS320C54_macp; op_Smem(insn, insn.Op1, code); op_pmad_data(insn, insn.Op2); op_src_dst(insn, 3, bit8); } else if ( bits15_8 <= 0x7D ) // <= 0111 1101 // 0111 1100 IAAA AAAA 16-bit constant MVPD pmad, Smem // 0111 1101 IAAA AAAA 16-bit constant MVDP Smem, pmad { insn.itype = bit8 ? TMS320C54_mvdp : TMS320C54_mvpd; op_Smem(insn, insn.ops[1-bit8], code); op_pmad_data(insn, insn.ops[bit8]); } else if ( bits15_8 <= 0x7F ) // <= 0111 1111 // 0111 1110 IAAA AAAA READA Smem // 0111 1111 IAAA AAAA WRITA Smem { insn.itype = bit8 ? TMS320C54_writa : TMS320C54_reada; op_Smem(insn, insn.Op1, code); } else if ( bits15_8 <= 0x83 ) // <= 1000 001S // 1000 000S IAAA AAAA STL src, Smem // 1000 001S IAAA AAAA STH src, Smem { insn.itype = bit9 ? TMS320C54_sth2 : TMS320C54_stl2; op_src_dst(insn, 1, bit8); op_Smem(insn, insn.Op2, code); } else if ( bits15_8 <= 0x87 ) // <= 1000 001S // 1000 010S IAAA AAAA STL src, ASM, Smem // 1000 011S IAAA AAAA STH src, ASM, Smem { insn.itype = bit9 ? TMS320C54_sth3 : TMS320C54_stl3; op_src_dst(insn, 1, bit8); op_reg_word(insn, 2, ASM); op_Smem(insn, insn.Op3, code); } else if ( bits15_8 <= 0x89 ) // <= 1000 100S // 1000 100S IAAA AAAA STLM src, MMR { insn.itype = TMS320C54_stlm; op_src_dst(insn, 1, bit8); op_MMR(insn, insn.Op2, code); } else if ( bits15_8 == 0x8A ) // == 1000 1010 // 1000 1010 IAAA AAAA POPM MMR { insn.itype = TMS320C54_popm; op_MMR(insn, insn.Op1, code); } else if ( bits15_8 == 0x8B ) // == 1000 1011 // 1000 1011 IAAA AAAA POPD Smem { insn.itype = TMS320C54_popd; op_Smem(insn, insn.Op1, code); } else if ( bits15_8 <= 0x8D ) // <= 1000 1101 // 1000 1100 IAAA AAAA ST T, Smem // 1000 1101 IAAA AAAA ST TRN, Smem { insn.itype = TMS320C54_st; op_reg_word(insn, 1, bit8 ? TRN : T); op_Smem(insn, insn.Op2, code); } else if ( bits15_8 <= 0x8F ) // <= 1000 111S // 1000 111S IAAA AAAA CMPS src, Smem { insn.itype = TMS320C54_cmps; op_src_dst(insn, 1, bit8); op_Smem(insn, insn.Op2, code); } else if ( bits15_8 <= 0x96 ) // <= 1001 0110 // 1001 000S XXXX SHFT ADD Xmem, SHFT, src // 1001 001S XXXX SHFT SUB Xmem, SHFT, src // 1001 010D XXXX SHFT LD Xmem, SHFT, dst // 1001 0110 XXXX BITC BIT Xmem, BITC { static const ushort codes[4] = { TMS320C54_add3, TMS320C54_sub3, TMS320C54_ld3, TMS320C54_bit }; insn.itype = codes[bits10_9]; op_Xmem(insn.Op1, code); op_bit(insn.Op2, code & 0x0F); if ( insn.itype != TMS320C54_bit ) op_src_dst(insn, 3, bit8); } else if ( bits15_8 == 0x97 ) // == 1001 0111 { insn.itype = TMS320C54_null; } else if ( bits15_8 <= 0x9B ) // <= 1001 101S // 1001 100S XXXX SHFT STL src, SHFT, Xmem // 1001 101S XXXX SHFT STH src, SHFT, Xmem { insn.itype = bit9 ? TMS320C54_sth3 : TMS320C54_stl3; op_src_dst(insn, 1, bit8); op_bit(insn.Op2, code & 0x0F); op_Xmem(insn.Op3, code); } else if ( bits15_8 <= 0x9D ) // <= 1001 1101 // 1001 1100 XXXX COND STRCD Xmem, cond // 1001 1101 XXXX COND SRCCD Xmem, cond { insn.itype = bit8 ? TMS320C54_srccd : TMS320C54_strcd; op_Xmem(insn.Op1, code); op_cond4(insn, insn.Op2, (uchar)code); } else if ( bits15_8 <= 0x9F ) // <= 1001 111S // 1001 111S XXXX COND SACCD src, Xmem, cond { insn.itype = TMS320C54_saccd; op_src_dst(insn, 1, bit8); op_Xmem(insn.Op2, code); op_cond4(insn, insn.Op3, (uchar)code); } else if ( bits15_8 <= 0xA7 ) // <= 1010 011S // 1010 000D XXXX YYYY ADD Xmem, Ymem, dst // 1010 001D XXXX YYYY SUB Xmem, Ymem, dst // 1010 010D XXXX YYYY MPY Xmem, Ymem, dst // 1010 011S XXXX YYYY MACSU Xmem, Ymem, src { static const ushort codes[4] = { TMS320C54_add3, TMS320C54_sub3, TMS320C54_mpy3, TMS320C54_macsu }; insn.itype = codes[bits10_9]; op_Xmem(insn.Op1, code); op_Ymem(insn.Op2, code); op_src_dst(insn, 3, bit8); } else if ( bits15_8 <= 0xAF ) // <= 1010 11RD // 1010 10RD XXXX YYYY LD Xmem, dst || MAC[R] Ymem [,dst_] // 1010 11RD XXXX YYYY LD Xmem, dst || MAS[R] Ymem [,dst_] { static const ushort codes[4] = { TMS320C54_ld_mac, TMS320C54_ld_macr, TMS320C54_ld_mas, TMS320C54_ld_masr }; insn.itype = codes[bits10_9]; insn.IsParallel = 1; op_Xmem(insn.Op1, code); op_src_dst(insn, 2, bit8); op_Ymem(insn.Op3, code); op_src_dst(insn, 4, 1-bit8); // dst_ } else if ( bits15_8 <= 0xBF ) // <= 1010 11RD // 1011 0RSD XXXX YYYY MAC[R] Xmem, Ymem, src [,dst] // 1011 1RSD XXXX YYYY MAS[R] Xmem, Ymem, src [,dst] { static const ushort codes[4] = { TMS320C54_mac3, TMS320C54_macr3, TMS320C54_mas3, TMS320C54_masr3 }; insn.itype = codes[bits11_10]; op_Xmem(insn.Op1, code); op_Ymem(insn.Op2, code); op_src_dst(insn, 3, bit9); if ( bit8 != bit9 ) op_src_dst(insn, 4, bit8); } else if ( bits15_8 <= 0xDF ) // <= 1101 1RSD // 1100 00SD XXXX YYYY ST src, Ymem || ADD Xmem, dst // 1100 01SD XXXX YYYY ST src, Ymem || SUB Xmem, dst // 1100 10SD XXXX YYYY ST src, Ymem || LD Xmem, dst // 1100 11SD XXXX YYYY ST src, Ymem || MPY Xmem, dst // 1101 0RSD XXXX YYYY ST src, Ymem || MAC[R] Xmem, dst // 1101 1RSD XXXX YYYY ST src, Ymem || MAS[R] Xmem, dst { static const ushort codes[8] = { TMS320C54_st_add, TMS320C54_st_sub, TMS320C54_st_ld, TMS320C54_st_mpy, TMS320C54_st_mac, TMS320C54_st_macr, TMS320C54_st_mas, TMS320C54_st_masr }; insn.itype = codes[bits12_10]; insn.IsParallel = 1; op_src_dst(insn, 1, bit9); op_Ymem(insn.Op2, code); op_Xmem(insn.Op3, code); op_src_dst(insn, 4, bit8); } else if ( bits15_8 <= 0xE3 ) // <= 1101 1RSD // 1110 0000 XXXX YYYY 16-bit constant FIRS Xmem, Ymem, pmad // 1110 0001 XXXX YYYY LMS Xmem, Ymem // 1110 0010 XXXX YYYY SQDST Xmem, Ymem // 1110 0011 XXXX YYYY ABDST Xmem, Ymem { static const ushort codes[4] = { TMS320C54_firs, TMS320C54_lms, TMS320C54_sqdst, TMS320C54_abdst }; insn.itype = codes[bits9_8]; op_Xmem(insn.Op1, code); op_Ymem(insn.Op2, code); if ( insn.itype == TMS320C54_firs ) op_pmad_data(insn, insn.Op3); } else if ( bits15_8 == 0xE5 ) // == 1110 0101 // 1110 0101 XXXX YYYY MVDD Xmem, Ymem { insn.itype = TMS320C54_mvdd; op_Xmem(insn.Op1, code); op_Ymem(insn.Op2, code); } else if ( bits15_8 <= 0xE6 ) // <= 1110 01S0 // 1110 01S0 XXXX YYYY ST src, Ymem || LD Xmem, T { insn.itype = TMS320C54_st_ld; insn.IsParallel = 1; op_src_dst(insn, 1, bit9); op_Ymem(insn.Op2, code); op_Xmem(insn.Op3, code); op_reg_word(insn, 4, T); } else if ( bits15_8 == 0xE7 ) // == 1110 0111 // 1110 0111 MMRX MMRY MVMM MMRx, MMRy { insn.itype = TMS320C54_mvmm; op_MMRx(insn, insn.Op1, code); op_MMRy(insn, insn.Op2, code); } else if ( bits15_8 <= 0xE9 ) // <= 1110 100D // 1110 100D KKKK KKKK LD #K, dst { insn.itype = TMS320C54_ld2; op_imm(insn.Op1, code & 0xFF); op_src_dst(insn, 2, bit8); } else if ( bits15_8 <= 0xEB ) // <= 1110 101k // 1110 101K KKKK KKKK LD #k9, DP { insn.itype = TMS320C54_ld2; op_imm(insn.Op1, code & 0x1FF); op_reg_word(insn, 2, DP); } else if ( bits15_8 == 0xEC ) // == 1110 1100 // 1110 1100 KKKK KKKK RPT #K { insn.itype = TMS320C54_rpt; op_imm(insn.Op1, code & 0xFF); } else if ( bits15_8 == 0xED ) // == 1110 1101 // 1110 1101 000K KKKK LD #k5, ASM { insn.itype = TMS320C54_ld2; op_bit(insn.Op1, (uchar)get_signed(code, 0x1F), false); op_reg_word(insn, 2, ASM); } else if ( bits15_8 == 0xEE ) // == 1110 1110 // 1110 1110 KKKK KKKK FRAME k { insn.itype = TMS320C54_frame; op_imm(insn.Op1, get_signed(code, 0xFF), true, true); } else if ( bits15_12 < 0xF ) insn.itype = TMS320C54_null; else if ( code == 0xF070 ) // == 1111 0000 0111 0000 // 1111 0000 0111 0000 16-bit constant RPT #lk { insn.itype = TMS320C54_rpt; op_lk(insn, insn.Op1); } else if ( (bits15_4 & 0xFEF) == 0xF02 ) // == 1111 000D 0010 // 1111 000D 0010 SHFT 16-bit constant LD #lk [,SHFT], dst { insn.itype = TMS320C54_ld3; op_lk(insn, insn.Op1); op_bit(insn.Op2, code & 0x0F); op_src_dst(insn, 3, bit8); } else if ( (code & 0xFEFF) == 0xF062 ) // == 1111 000D 0110 0010 // 1111 000D 0110 0010 16-bit constant LD #lk, 16, dst { insn.itype = TMS320C54_ld3; op_lk(insn, insn.Op1); op_bit(insn.Op2, 16); op_src_dst(insn, 3, bit8); } else if ( (code & 0xFEFF) == 0xF066 ) // == 1111 000D 0110 0110 // 1111 000D 0110 0110 16-bit constant MPY #lk, dst { insn.itype = TMS320C54_mpy2; op_lk(insn, insn.Op1); op_src_dst(insn, 2, bit8); } else if ( (code & 0xFEFF) == 0xF071 ) // == 1111 000D 0111 0001 // 1111 000D 0111 0001 16-bit constant RPTZ dst, #lk { insn.itype = TMS320C54_rptz; op_src_dst(insn, 1, bit8); op_lk(insn, insn.Op2); } else if ( bits15_10 == 0x3C ) // == 1111 00xx { if ( bits7_4 <= 0x5 ) // 1111 00SD 0000 SHFT 16-bit constant ADD #lk [,SHFT], src [,dst] // 1111 00SD 0001 SHFT 16-bit constant SUB #lk [,SHFT], src [,dst] // 1111 00SD 0011 SHFT 16-bit constant AND #lk [,SHFT] ,src [,dst] // 1111 00SD 0100 SHFT 16-bit constant OR #lk [,SHFT], src [,dst] // 1111 00SD 0101 SHFT 16-bit constant XOR #lk [,SHFT], src [,dst] { static const ushort codes[6] = { TMS320C54_add3, TMS320C54_sub3, TMS320C54_null, TMS320C54_and3, TMS320C54_or3, TMS320C54_xor3 }; insn.itype = codes[bits7_4]; if ( insn.itype != TMS320C54_null ) { op_lk(insn, insn.Op1); if ( bits3_0 != 0 ) { op_bit(insn.Op2, bits3_0); op_src_dst(insn, 3, bit9); if ( bit8 != bit9 ) op_src_dst(insn, 4, bit8); } else { op_src_dst(insn, 2, bit9); if ( bit8 != bit9 ) op_src_dst(insn, 3, bit8); else insn.itype--; } } } else if ( bits7_4 == 0x6 && bits3_0 <= 0x5 ) // 1111 00SD 0110 0000 16-bit constant ADD #lk, 16, src [,dst] // 1111 00SD 0110 0001 16-bit constant SUB #lk, 16, src [,dst] // 1111 00SD 0110 0011 16-bit constant AND #lk, 16, src [,dst] // 1111 00SD 0110 0100 16-bit constant OR #lk, 16, src [,dst] // 1111 00SD 0110 0101 16-bit constant XOR #lk, 16, src [,dst] { static const ushort codes[6] = { TMS320C54_add3, TMS320C54_sub3, TMS320C54_null, TMS320C54_and3, TMS320C54_or3, TMS320C54_xor3 }; insn.itype = codes[bits3_0]; if ( insn.itype != TMS320C54_null ) { op_lk(insn, insn.Op1); op_bit(insn.Op2, 16); op_src_dst(insn, 3, bit9); if ( bit8 != bit9 ) op_src_dst(insn, 4, bit8); } } else if ( bits7_4 == 0x6 && bits3_0 == 0x7 ) // 1111 00SD 0110 0111 16-bit constant MAC #lk, src [,dst] { insn.itype = TMS320C54_mac2; op_lk(insn, insn.Op1); op_src_dst(insn, 2, bit9); if ( bit8 != bit9 ) { op_src_dst(insn, 3, bit8); insn.itype++; } } else if ( bits7_5 >= 0x4 ) // 1111 00SD 100S HIFT AND src [,SHIFT] [,dst] // 1111 00SD 101S HIFT OR src [,SHIFT] [,dst] // 1111 00SD 110S HIFT XOR src [,SHIFT] [,dst] // 1111 00SD 111S HIFT SFTL src, SHIFT [,dst] { static const ushort codes[4] = { TMS320C54_and1, TMS320C54_or1, TMS320C54_xor1, TMS320C54_sftl2, }; insn.itype = codes[bits6_5]; op_src_dst(insn, 1, bit9); uchar shift = (uchar)get_signed(code, 0x1F); int n = 2; // current operand if ( insn.itype == TMS320C54_sftl2 || shift != 0 ) { op_bit(insn.ops[n-1], shift); n++; if ( insn.itype != TMS320C54_sftl2 ) insn.itype++; } if ( bit8 != bit9 ) { op_src_dst(insn, n, bit8); insn.itype++; } } else if ( bits8_3 == 0xE ) // == 0 0111 0 // 1111 00Z0 0111 0010 16-bit constant RPTB[D] pmad // 1111 00Z0 0111 0011 16-bit constant B[D] pmad // 1111 00Z0 0111 0100 16-bit constant CALL[D] pmad { static const ushort codes[8] = { TMS320C54_null, TMS320C54_null, TMS320C54_rptb, TMS320C54_b, TMS320C54_call, TMS320C54_null, TMS320C54_null, TMS320C54_null }; insn.itype = codes[bits2_0]; if ( insn.itype != TMS320C54_null ) { if ( bit9 ) { switch ( insn.itype ) { case TMS320C54_rptb: insn.itype = TMS320C54_rptbd; break; case TMS320C54_b: insn.itype = TMS320C54_bd; break; case TMS320C54_call: insn.itype = TMS320C54_calld; break; } } op_pmad(insn, insn.Op1); } } else insn.itype = TMS320C54_null; } else if ( bits15_10 == 0x3D ) // == 1111 01xx { if ( code == 0xF495 ) // == 1111 0100 1001 0101 // 1111 0100 1001 0101 NOP insn.itype = TMS320C54_nop; else if ( (code & 0xFFF8) == 0xF4A0 ) // == 1111 0100 1010 0KKK // 1111 0100 1010 0KKK LD #k3, ARP { insn.itype = TMS320C54_ld2; op_imm(insn.Op1, code & 0x7); op_reg_word(insn, 2, ARP); } else if ( (code & 0xFFE0) == 0xF4C0 ) // == 1111 0100 110K KKKK // 1111 0100 110K KKKK TRAP K { insn.itype = TMS320C54_trap; op_imm(insn.Op1, code & 0x001F, false, true); } else if ( bits7_4 <= 0x7 ) // 1111 01SD 000S HIFT ADD src [,SHIFT] [,dst] // 1111 01SD 001S HIFT SUB src [,SHIFT] [,dst] // 1111 01SD 010S HIFT LD src [,SHIFT], dst // 1111 01SD 011S HIFT SFTA src, SHIFT [,dst] { static const ushort codes[4] = { TMS320C54_add1, TMS320C54_sub1, TMS320C54_ld1, TMS320C54_sfta2 }; insn.itype = codes[bits7_5]; op_src_dst(insn, 1, bit9); uchar shift = (uchar)get_signed(code, 0x1F); int n = 2; // current operand if ( insn.itype == TMS320C54_sfta2 || shift != 0 ) { op_bit(insn.ops[n-1], shift); n++; if ( insn.itype != TMS320C54_sfta2 ) insn.itype++; } if ( insn.itype == TMS320C54_ld1 || insn.itype == TMS320C54_ld2 || bit8 != bit9 ) { op_src_dst(insn, n, bit8); insn.itype++; } } else if ( bits7_0 < 0x80 ) // < 1000 0000 { insn.itype = TMS320C54_null; } else if ( bits7_0 <= 0x82 ) // <= 1000 0010 // 1111 01SD 1000 0000 ADD src, ASM [,dst] // 1111 01SD 1000 0001 SUB src, ASM [,dst] // 1111 01SD 1000 0010 LD src, ASM [,dst] { static const ushort codes[3] = { TMS320C54_add2, TMS320C54_sub2, TMS320C54_ld2 }; insn.itype = codes[bits2_0]; op_src_dst(insn, 1, bit9); op_reg_word(insn, 2, ASM); if ( bit8 != bit9 ) { op_src_dst(insn, 3, bit8); insn.itype++; } } else if ( bit9 == 0 && bits7_0 == 0x83 ) // == 1111 010S 1000 0011 // 1111 010S 1000 0011 SAT src { insn.itype = TMS320C54_sat; op_src_dst(insn, 1, bit8); } else if ( bits7_0 <= 0x85 ) // <= 1000 0101 // 1111 01SD 1000 0100 NEG src [,dst] // 1111 01SD 1000 0101 ABS src [,dst] { insn.itype = bit0 ? TMS320C54_abs1 : TMS320C54_neg1; op_src_dst(insn, 1, bit9); if ( bit8 != bit9 ) { op_src_dst(insn, 2, bit8); insn.itype++; } } else if ( bit9 == 0 && bits7_0 <= 0x87 ) // <= 1000 0111 // 1111 010D 1000 0110 MAX dst // 1111 010D 1000 0111 MIN dst { insn.itype = bit0 ? TMS320C54_min : TMS320C54_max; op_src_dst(insn, 1, bit8); } else if ( bits7_0 <= 0x8B ) // <= 1000 101R // 1111 01SD 1000 100R MACA[R] T, src [,dst] // 1111 01SD 1000 101R MASA[R] T, src [,dst] { static const ushort codes[4] = { TMS320C54_maca2, TMS320C54_macar2, TMS320C54_masa2, TMS320C54_masar2 }; insn.itype = codes[bits1_0]; op_reg_word(insn, 1, T); op_src_dst(insn, 2, bit9); if ( bit8 != bit9 ) { op_src_dst(insn, 3, bit8); insn.itype++; } } else if ( bits7_0 <= 0x94 ) // <= 1001 0100 // 1111 010D 1000 1100 MPYA dst // 1111 010D 1000 1101 SQUR A, dst // 1111 010S 1000 1110 EXP src // 1111 01SD 1000 1111 NORM src [,dst] // 1111 010S 1001 0000 ROR src // 1111 010S 1001 0001 ROL src // 1111 010S 1001 0010 ROLTC src // 1111 01SD 1001 0011 CMPL src [,dst] // 1111 010S 1001 0100 SFTC src { static const ushort codes[9] = { TMS320C54_mpya, TMS320C54_squr, TMS320C54_exp, TMS320C54_norm1, TMS320C54_ror, TMS320C54_rol, TMS320C54_roltc, TMS320C54_cmpl1, TMS320C54_sftc }; insn.itype = codes[bits4_0-0xC]; //lint !e676 possibly indexing before the beginning of an allocation if ( insn.itype == TMS320C54_squr ) { if ( !bit9 ) { op_reg_word(insn, 1, A); op_src_dst(insn, 2, bit8); } else insn.itype = TMS320C54_null; } else if ( insn.itype == TMS320C54_norm1 || insn.itype == TMS320C54_cmpl1 ) { op_src_dst(insn, 1, bit9); if ( bit8 != bit9 ) { op_src_dst(insn, 2, bit8); insn.itype++; } } else { if ( !bit9 ) op_src_dst(insn, 1, bit8); else insn.itype = TMS320C54_null; } } else if ( bit8 == 0 && bits7_0 == 0x9B ) // == 1111 01Z0 1001 1011 // 1111 01Z0 1001 1011 RETF[D] insn.itype = bit9 ? TMS320C54_retfd : TMS320C54_retf; else if ( bits7_0 == 0x9F ) // == 1001 1111 // 1111 01SD 1001 1111 RND src [,dst] { insn.itype = TMS320C54_rnd1; op_src_dst(insn, 1, bit9); if ( bit8 != bit9 ) { op_src_dst(insn, 2, bit8); insn.itype++; } } else if ( bits7_4 == 0xA ) // == 1010 1ARX // 1111 01CC 1010 1ARX CMPR CC, ARx { insn.itype = TMS320C54_cmpr; op_cond2(insn.Op1, bits15_8); op_reg_word(insn, 2, AR0+bits2_0); } else if ( bits7_4 == 0xB ) // == 1111 01N0 1011 SBIT // 1111 01N0 1011 SBIT RSBX N, SBIT // 1111 01N1 1011 SBIT SSBX N, SBIT { uchar reg = rnone; if ( bit9 == 0 ) // ST0 { switch ( bits3_0 ) { case 9 : reg = OVB; break; case 10 : reg = OVA; break; case 11 : reg = C; break; case 12 : reg = TC; break; } } else // ST1 { switch ( bits3_0 ) { case 5 : reg = CMPT; break; case 6 : reg = FRCT; break; case 7 : reg = C16; break; case 8 : reg = SXM; break; case 9 : reg = OVM; break; case 11 : reg = INTM; break; case 12 : reg = HM; break; case 13 : reg = XF; break; case 14 : reg = CPL; break; case 15 : reg = BRAF; break; } } if ( reg != rnone ) { insn.itype = bit8 ? TMS320C54_ssbx1 : TMS320C54_rsbx1; op_reg_word(insn, 1, reg); } else { insn.itype = bit8 ? TMS320C54_ssbx2 : TMS320C54_rsbx2; op_bit(insn.Op1, bit9); op_bit(insn.Op2, bits3_0); } } else if ( (code & 0xFFE0) == 0xF7C0 ) // == 1111 0111 110K KKKK // 1111 0111 110K KKKK INTR k { insn.itype = TMS320C54_intr; op_imm(insn.Op1, bits4_0, false, true); } else if ( code == 0xF7E0 ) // == 1111 0111 1110 0000 // 1111 0111 1110 0000 RESET insn.itype = TMS320C54_reset; else if ( bits7_0 == 0xE1 ) // == 1111 01NN 1110 0001 // 1111 01NN 1110 0001 IDLE k { insn.itype = TMS320C54_idle; op_bit(insn.Op1, 1+bit9+(bit8<<1)); } else if ( bits7_4 == 0xE ) // == 1111 01ZS 1110 nnnn // 1111 01ZS 1110 0010 BACC[D] src // 1111 01ZS 1110 0011 CALA[D] src // 1111 01Z0 1110 0100 FRET[D] // 1111 01Z0 1110 0101 FRETE[D] // 1111 01ZS 1110 0110 FBACC[D] src // 1111 01ZS 1110 0111 FCALA[D] src // 1111 01Z0 1110 1011 RETE[D] { static const ushort codes[16] = { TMS320C54_null, TMS320C54_null, TMS320C54_bacc, TMS320C54_cala, TMS320C54_fret, TMS320C54_frete, TMS320C54_fbacc, TMS320C54_fcala, TMS320C54_null, TMS320C54_null, TMS320C54_null, TMS320C54_rete, TMS320C54_null, TMS320C54_null, TMS320C54_null, TMS320C54_null }; insn.itype = codes[bits3_0]; if ( insn.itype != TMS320C54_null ) { if ( insn.itype == TMS320C54_bacc || insn.itype == TMS320C54_cala || insn.itype == TMS320C54_fbacc || insn.itype == TMS320C54_fcala ) { op_src_dst(insn, 1, bit8); } else if ( bit8 ) { insn.itype = TMS320C54_null; } if ( insn.itype != TMS320C54_null && bit9 ) insn.itype++; } } else insn.itype = TMS320C54_null; } else if ( bits15_10 == 0x3E ) // == 1111 10xx { if ( bit7 ) // 1111 10Z0 1 7bit constant=pmad(22-16) 16-bit constant=pmad(15-0) FB[D] extpmad // 1111 10Z1 1 7bit constant=pmad(22-16) 16-bit constant=pmad(15-0) FCALL[D] extpmad { static const ushort codes[4] = { TMS320C54_fb, TMS320C54_fcall, TMS320C54_fbd, TMS320C54_fcalld }; insn.itype = codes[bits9_8]; op_extpmad(insn, insn.Op1, code); } else // 1111 10Z0 CCCC CCCC 16-bit constant BC[D] pmad, cond [,cond] [,cond] // 1111 10Z1 CCCC CCCC 16-bit constant CC[D] pmad, cond [,cond] [,cond] { static const ushort codes[4] = { TMS320C54_bc2, TMS320C54_cc2, TMS320C54_bcd2, TMS320C54_ccd2 }; insn.itype = codes[bits9_8]; op_pmad(insn, insn.Op1); ops_conds(insn, 2, code); } } else if ( bits15_10 == 0x3F ) // == 1111 11xx { if ( bit8 ) // 1111 11N1 CCCC CCCC XC n, cond [,cond] [,cond] { insn.itype = TMS320C54_xc2; uchar n = bit9+1; op_bit(insn.Op1, n); ops_conds(insn, 2, code); /* ea_t ea = insn.ea + insn.size; for ( int i=0; iitype == TMS320C54_null ) return 0; return insn->size; }