- /*
- * Interactive disassembler (IDA).
- * SPU Processor Module.
- *
- * (c) 2010 Niraj Khadka
- */
- /*
- // from here..
- #define dt_byte 0 // 8 bit
- #define dt_word 1 // 16 bit
- #define dt_dword 2 // 32 bit
- #define dt_float 3 // 4 byte
- #define dt_double 4 // 8 byte
- #define dt_tbyte 5 // variable size (ph.tbyte_size)
- #define dt_packreal 6 // packed real format for mc68040
- // ...to here the order should not be changed, see mc68000
- #define dt_qword 7 // 64 bit
- #define dt_byte16 8 // 128 bit
- #define dt_code 9 // ptr to code (not used?)
- #define dt_void 10 // none
- #define dt_fword 11 // 48 bit
- #define dt_bitfild 12 // bit field (mc680x0)
- #define dt_string 13 // pointer to asciiz string
- #define dt_unicode 14 // pointer to unicode string
- #define dt_3byte 15 // 3-byte data
- #define dt_ldbl 16 // long double (which may be different from tbyte)
- */
- #include "ins.hpp"
- #include "SPU.hpp"
- #include "ana.hpp"
- #define LNOP 0X1 //opcode for lnop
- #define NOP 0X201 //opcode for nop
- #define SYNC 0X2 //opcode for sync
- #define DSYNC 0X3 //opcodefor dsync
- #define TOTAL_NO_OF_OPCODES 198 //total no of opcodes.
- //function prototypes declared in ana.hpp
- unsigned long select_hbr_p_field(unsigned long)
- {
- unsigned long i,j,k;
- i = data<<11;
- j = i>>31; //for selecting single bit..
- k = j&0X1; //masking by 0b1 ie in hex 0X1
- return k;
- }
- unsigned long select_ROH_hbr(unsigned long)
- {
- unsigned long i,j,k;
- i = data<<16;
- j = i>>30; //for selecting two bits..
- k = j&0X3; //masking by 0b11 ie in hex 0X3
- return k;
- }
- unsigned long select_ROH(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<7;
- j = i>>30; //for selecting two bits..
- k = j&0X3; //masking by 0b11 ie in hex 0X3
- return k;
- }
- unsigned long select_bit_13(unsigned long data); //for interrupt enable boolean check..
- {
- unsigned long i,j,k;
- i = data<<13;
- j = i>>31; //only need single bit.
- k = j&0X1;
- return k;
- }
- unsigned long select_bit_12(unsigned long data) //for interrupt disable boolean check.
- {
- unsigned long i,j,k;
- i = data<<12;
- j = i>>31; //only need single bit.
- k = j&0X1;
- return k;
- }
- unsigned long select_i18(unsigned long data) //for selecting immediate 18 (i18) field
- {
- unsigned long i,j,k;
- i = data<<7;
- j = i>>14;
- k = j&0X3FFFF;
- return k;
- }
- unsigned long select_i16(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<9;
- j = i>>16;
- k = j&0XFFFF;
- return k;
- }
- unsigned long select_i10(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<8;
- j = i>>22;
- k = j&0X3FF;
- return k;
- }
- unsigned long select_i7(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<11;
- j = i>>25;
- k = j&0X7F;
- return k;
- }
- //rc selection for inst.
- unsigned long select_rc(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<25;
- j = i>>25;
- k = j&0X7F;
- return k;
- }
- //rb selection for inst.
- unsigned long select_rb(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<11;
- j = i>>25;
- k = j&0X7F;
- return k;
- }
- //ra selection for inst.
- unsigned long select_ra(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<18;
- j = i>>25;
- k = j&0X7F;
- return k;
- }
- //rt selection for inst.
- unsigned long select_rt(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<25;
- j = i>>25;
- k = j&0X7F;
- return k;
- }
- //rt selection for inst type rrr
- unsigned long select_rt_rrr(unsigned long data)
- {
- unsigned long i,j,k;
- i = data<<4;
- j = i>>25;
- k = j&0X7F;
- return k;
- }
- //array containing all opcodes
- unsigned long opcodes_hex[]={
- 0X34,
- 0X1C4,
- 0X61,
- 0X67,
- 0X24,
- 0X144,
- 0X41,
- 0X47,
- 0X1F4,
- 0X1D4,
- 0X1F5,
- 0X1D5,
- 0X1F6,
- 0X1D6,
- 0X1F7,
- 0X1D7,
- 0X83,
- 0X82,
- 0X81,
- 0X21,
- 0XC1,
- 0X65,
- 0XC8,
- 0X1D,
- 0XC0,
- 0X1C,
- 0X48,
- 0XD,
- 0X40,
- 0XC,
- 0X340,
- 0XC2,
- 0X342,
- 0X341,
- 0X42,
- 0X343,
- 0X3C4,
- 0X3CC,
- 0X74,
- 0X75,
- 0XC,
- 0X3C5,
- 0X3C7,
- 0X3C6,
- 0X346,
- 0X3CE,
- 0X34E,
- 0X2A5,
- 0X2B4,
- 0X1B6,
- 0X1B5,
- 0X1B4,
- 0X1B2,
- 0X1B1,
- 0X1B0,
- 0XD3,
- 0X53,
- 0X253,
- 0X2B6,
- 0X2AE,
- 0X2A6,
- 0XC1,
- 0X2C1,
- 0X16,
- 0X15,
- 0X14,
- 0X41,
- 0X2C9,
- 0X6,
- 0X5,
- 0X4,
- 0X1F0,
- 0X241,
- 0X46,
- 0X45,
- 0X44,
- 0XC9,
- 0X49,
- 0X249,
- 0X8,
- 0XB,
- 0X5F,
- 0X7F,
- 0X5B,
- 0X7B,
- 0X1DB,
- 0X1FB,
- 0X1DF,
- 0X1FF,
- 0X1CF,
- 0X5C,
- 0X7C,
- 0X58,
- 0X78,
- 0X1DC,
- 0X1FC,
- 0X1CC,
- 0X1D8,
- 0X1F8,
- 0X5D,
- 0X7D,
- 0X59,
- 0X79,
- 0X1DD,
- 0X1FD,
- 0X1D9,
- 0X1F9,
- 0X5E,
- 0X7E,
- 0X5A,
- 0X7A,
- 0X3D8,
- 0X7F,
- 0X258,
- 0X4F,
- 0X2D8,
- 0X5F,
- 0X3D0,
- 0X7E,
- 0X3C8,
- 0X7D,
- 0X3C0,
- 0X7C,
- 0X250,
- 0X4E,
- 0X248,
- 0X4D,
- 0X240,
- 0X4C,
- 0X2D0,
- 0X5E,
- 0X2C8,
- 0X5D,
- 0X2C0,
- 0X5C,
- 0X64,
- 0X60,
- 0X66,
- 0X62,
- 0X1A8,
- 0X1AA,
- 0X1AB,
- 0X1A9,
- 0X42,
- 0X40,
- 0X46,
- 0X44,
- 0X128,
- 0X129,
- 0X12A,
- 0X12B,
- 0X1AC,
- 0X8,
- 0X9,
- 0X2C4,
- 0X2CC,
- 0X2C5,
- 0X2CD,
- 0X2C6,
- 0X2CE,
- 0XE,
- 0X35C,
- 0XD,
- 0X35E,
- 0XF,
- 0X35D,
- 0X35F,
- 0X1B8,
- 0X1B9,
- 0X3D4,
- 0X1DA,
- 0X1D8,
- 0X1DB,
- 0X1D9,
- 0X3B9,
- 0X3B8,
- 0X3C3,
- 0X3CB,
- 0X2C3,
- 0X2CB,
- 0X3BF,
- 0X3C2,
- 0X3CA,
- 0X2C2,
- 0X2CA,
- 0X3BA,
- 0X398,
- 0X0,
- 0X140,
- 0X1,
- 0X201,
- 0X2,
- 0X3,
- 0XC,
- 0X10C,
- 0XD,
- 0XF,
- 0x10D
- };
- //check for opcode style.
- unsigned long check_opcode(unsigned long data)
- {
- unsigned long i;
- unsigned long opcode_8bit, opcode_11bit, opcode_4bit, opcode_9bit, opcode_7bit;
- opcode_8bit = (data>>24)&0XFF;
- opcode_11bit = (data>>21)&0X7FF;
- opcode_4bit = (data>>28)&0XF;
- opcode_9bit = (data>>23)&0X1F;
- opcode_7bit = (data>>25)&0X7F;
- for (i=0;i>=TOTAL_NO_OF_OPCODES;i++)
- {
- if(opcode_8bit == opcodes_hex[i])
- {
- return opcode_8bit;
- }
- else if(opcode_11bit == opcodes_hex[i])
- {
- return opcode_11bit;
- }
- else if(opcode_4bit == opcodes_hex[i])
- {
- return opcode_4bit;
- }
- else if(opcode_9bit == opcodes_hex[i])
- {
- return opcode_9bit;
- }
- else
- {
- return opcode_7bit;
- }
- }
- }
- int idaapi ana(void)
- {
- cmd.Op1.type = o_void;
- cmd.Op2.type = o_void;
- cmd.Op3.type = o_void;
- cmd.Op4.type = o_void;
- uint stream = ua_next_long(); //unsigned integer code which gets the next 32 bit in binary.
- code = check_opcode(stream);
- switch(code)
- default:
- if (cmd.itype >= last)
- return 0; //Invalid instruction last is the last enumerated value in ins.hpp
- if(Instructions[cmd.itype].name == NULL)
- return 0; //invalid inst, NULL is defined in instrruction[] array in ins.cpp
- break;
- case 0x34:
- cmd.itype = SPU_lqd; //load quadword (d-form)
- //instruction type = ri10
- //therefore three operands and is from op(0-7) i10(8-17) ra(18-24) rt(25-31)
- //Operand[0] = Op1 and take bit 25 -31
- cmd.Op1.type = o_reg; //lqd <rt>, s14(ra) <rt> is o_reg type
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- //Operand[1] = Op2
- cmd.Op2.type = o_imm; //lqd rt, <s14>(ra) <s14> is signed immediate value
- cmd.Op2.value = select_i10(stream);
- cmd.Op2.dtype = dt_word;
- //Operand[2] = Op3
- cmd.Op3.type = o_reg; //lqd rt, s14<(ra)> <(ra)> is o_reg type
- cmd.Op3.value = select_ra(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4; //returning cmd.size
- break;
- case 0X1C4:
- cmd.itype = SPU_lqx; //load quadword (x-form)
- //Operand[0] = Op1
- cmd.Op1.type = o_reg; //lqx <rt>, ra, rb <rt> is o_reg type
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- //Operand[1] = Op2
- cmd.Op2.type = o_reg; //lqx rt, <ra>, rb <ra> is o_reg type
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- //Operand[2] = Op3
- cmd.Op3.type = o_reg; //lqx rt, ra, <rb> <rb> is o_reg type
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4; //returning cmd.size
- break;
- case 0X61:
- cmd.itype = SPU_lqa; //load quadword (a-form)
- //Operand[0] = Op1
- cmd.Op1.type = o_reg; //lqa <rt> s16 <rt> is o_reg type
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- //Operand[1] = Op2
- cmd.Op2.type = o_imm; //lqa rt <s16> <s16> is o_imm type
- cmd.Op2.value = select_i16(stream);
- cmd.Op2.dtype = dt_word;
- cmd.size = 4; //returning cmd.size
- break;
- case 0X67:
- cmd.itype = SPU_lqr; //load quadword (r-form)
- //lqr rt, i10(ra)
- //operation on operands.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i10(stream);
- cmd.Op2.dtype = dt_word;
- cmd.Op3.type = o_reg;
- cmd.Op3.value =select_ra(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X24:
- cmd.itype = SPU_stqd; //store quadword (d-form)
- //stqd rt, i10(ra)
- //operation on operands.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i10(stream);
- cmd.Op2.dtype = dt_word;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_ra(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X144:
- cmd.itype = SPU_stqx; //store quadword (x-form)
- //stqx rt, ra, rb
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X41:
- cmd.itype = SPU_stqa; //store quadword (a-form)
- //stqa rt, i16
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i16(stream);
- cmd.Op2.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0X47:
- cmd.itype = SPU_stqr; //store quadword (r-form)
- //stqr rt, i16
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i16(stream);
- cmd.Op2.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0X1F4:
- cmd.itype = SPU_cbd; //generate controls for byte insertion (d-type)
- //cbd rt, i7(ra)
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i7(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_ra(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1D4:
- cmd.itype = SPU_cbx; //generate controls for byte insertion (x-type.)
- //cbx rt, ra, rb
- //operation on bits
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1F5:
- cmd.itype = SPU_chd; //generate controls for halfword insertion (d-type)
- //chd rt, i7(ra)
- //operation on bits.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte; //dt_word in ua.hpp = 16 bit. ie halfword spu
- //A 4-bit address is computed by adding the value in the signed I7 field to the
- //value in the preferred slot of register RA and forcing the least-significant bit to zero.
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i7(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_ra(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1D5:
- cmd.itype = SPU_chx; //generate controls for halfword insertion (x-form)
- //chx rt, ra, rb
- //operations on bits.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1F6:
- cmd.itype = SPU_cwd; //generate controls for word insertion (d-form)
- //cwd rt, i7(ra);
- //operation on operands.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i7(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_ra(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1D6:
- cmd.itype = SPU_cwx; //generate controls for word insertion (x-form)
- //cwx rt, ra, rb
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1F7:
- cmd.itype = SPU_cdd; //generate controls for doubleword insertion(d-form)
- //cdd rt, i7(ra)
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i7(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_ra(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1D7:
- cmd.itype = SPU_cdx; //generate controls for doubleword insertion (x-form)
- //cdx rt, ra, rb
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X83:
- cmd.itype = SPU_ilh; //immediate load halfword
- //ilh rt, i16
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm
- cmd.Op2.value = select_i16(stream);
- cmd.Op2.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0X82:
- cmd.itype = SPU_ilhu; //immediate load halfword upper
- //ilhu rt, i16
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm
- cmd.Op2.value = select_i16(stream);
- cmd.Op2.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0X81:
- cmd.itype = SPU_il; //immediate load word
- //il rt, i16
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm
- cmd.Op2.value = select_i16(stream);
- cmd.Op2.dtype = dt_word; //16 bit
- cmd.size = 4;
- break;
- case 0X21:
- cmd.itype = SPU_ila; //immediate load address
- //ila rt, i18
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte; //8 bit
- cmd.Op2.type = o_imm;
- cmd.Op2.value = select_i18(stream);
- cmd.Op2.dtype = dt_dword; //32 bit.
- cmd.size = 4;
- break;
- case 0XC1:
- cmd.itype = SPU_iohl; //immediate Or halfword lower
- //iohl rt, i16
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm
- cmd.Op2.value = select_i16(stream);
- cmd.Op2.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0X65:
- cmd.itype = SPU_fsmbi; //form select mask for bytes immediate
- //fsmbi rt, i16
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_imm
- cmd.Op2.value = select_i16(stream);
- cmd.Op2.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0XC8:
- cmd.itype = SPU_ah; //add halfword
- //ah rt, ra, rb
- //operation on operands.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1D:
- cmd.itype = SPU_ahi; //add halfword immediate
- //ahi rt, ra, i10
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_imm;
- cmd.Op3.value = select_i10(stream);
- cmd.Op3.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0XC0:
- cmd.itype = SPU_a; //add word
- //a rt, ra, rb
- //operation on bits.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X1C:
- cmd.itype = SPU_ai; //add immediate
- //ai rt, ra, i10
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_imm;
- cmd.Op3.value = select_i10(stream);
- cmd.Op3.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0X48:
- cmd.itype = SPU_sfh; //subtract from halfword
- //sfh rt, ra, rb
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0XD:
- cmd.itype = SPU_sfhi; //subtract from halfword immeditae
- //sfhi rt, ra, i10
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_imm;
- cmd.Op3.value = select_i10(stream);
- cmd.Op3.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0X40:
- cmd.itype = SPU_sf; //subtract from word
- //sf rt, ra, rb
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0XC:
- cmd.itype = SPU_sfi; //subtract from word immediate
- //sfi et, ra, i10
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_imm;
- cmd.Op3.value = select_i10(stream);
- cmd.Op3.dtype = dt_word;
- cmd.size = 4;
- break;
- case 0x340:
- cmd.itype = SPU_addx; //add extended
- //addx rt, ra, rb
- //operation on operands
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0xC2:
- cmd.itype = SPU_cg; //carry generate
- //cg rt, ra, rb
- //operation on operands
- //For each of four word slots:
- //•The operand from register RA is added to the operand from register RB.
- //•The carry-out is placed in the least-significant bit of register RT.
- //•The remaining bits of RT are set to zero.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X342:
- cmd.itype = SPU_cgx; //carry generate extended
- //cgx rt, ra, rb
- //operation on operands
- //For each of four word slots:
- //•The operand from register RA is added to the operand from register RB and the least-significant bit of register RT.
- //•The carry-out is placed in the least-significant bit of register RT.
- //•The remaining bits of RT are set to zero. Bits 0 to 30 of the RT input are reserved and should be zero.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case 0X341:
- cmd.itype = SPU_sfx; //subtract from extended
- //sfx rt, ra, rb
- //operation on operands
- //For each of four word slots:
- //•The operand from register RA is subtracted from the operand from register RB.
- //An additional ‘1’ is subtracted from the result if the least-significant bit of RT is ‘0’.
- //•The 32-bit result is placed in register RT. Bits 0 to 30 of the RT input are reserved and should be zero.
- cmd.Op1.type = o_reg;
- cmd.Op1.value = select_rt(stream);
- cmd.Op1.dtype = dt_byte;
- cmd.Op2.type = o_reg;
- cmd.Op2.value = select_ra(stream);
- cmd.Op2.dtype = dt_byte;
- cmd.Op3.type = o_reg;
- cmd.Op3.value = select_rb(stream);
- cmd.Op3.dtype = dt_byte;
- cmd.size = 4;
- break;
- case