// -*- C -*- // // // MIPS Architecture: // // CPU Instruction Set (mips16) // // The instructions in this section are ordered according // to http://www.sgi.com/MIPS/arch/MIPS16/mips16.pdf. // The MIPS16 codes registers in a special way, map from one to the other. // ::::::: :compute:::int:TRX:RX:((RX < 2) ? (16 + RX) \: RX) :compute:::int:TRY:RY:((RY < 2) ? (16 + RY) \: RY) :compute:::int:TRZ:RZ:((RZ < 2) ? (16 + RZ) \: RZ) :compute:::int:SHIFT:SHAMT:((SHAMT == 0) ? 8 \: SHAMT) :compute:::int:SHAMT:SHAMT_4_0,S5:(LSINSERTED (S5, 5, 5) | SHAMT_4_0) :compute:::address_word:IMMEDIATE:IMM_25_21,IMM_20_16,IMMED_15_0:(LSINSERTED (IMM_25_21, 25, 21) | LSINSERTED (IMM_20_16, 20, 16) | LSINSERTED (IMMED_15_0, 15, 0)) :compute:::int:R32:R32L,R32H:((R32H << 3) | R32L) :compute:::address_word:IMMEDIATE:IMM_10_5,IMM_15_11,IMM_4_0:(LSINSERTED (IMM_10_5, 10, 5) | LSINSERTED (IMM_15_11, 15, 11) | LSINSERTED (IMM_4_0, 4, 0)) :compute:::address_word:IMMEDIATE:IMM_10_4,IMM_14_11,IMM_3_0:(LSINSERTED (IMM_10_4, 10, 4) | LSINSERTED (IMM_14_11, 14, 11) | LSINSERTED (IMM_3_0, 3, 0)) // Load and Store Instructions 10000,3.RX,3.RY,5.IMMED:RRI:16::LB "lb r, (r)" *mips16: *vr4100: { GPR[TRY] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[TRX], IMMED)); } 11110,6.IMM_10_5,5.IMM_15_11 + 10000,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LB "lb r, (r)" *mips16: *vr4100: { GPR[TRY] = EXTEND8 (do_load (SD_, AccessLength_BYTE, GPR[TRX], EXTEND16 (IMMEDIATE))); } 10100,3.RX,3.RY,5.IMMED:RRI:16::LBU "lbu r, (r)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_BYTE, GPR[TRX], IMMED); } 11110,6.IMM_10_5,5.IMM_15_11 + 10100,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LBU "lbu r, (r)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_BYTE, GPR[TRX], EXTEND16 (IMMEDIATE)); } 10001,3.RX,3.RY,5.IMMED:RRI:16::LH "lh r, (r)" *mips16: *vr4100: { GPR[TRY] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[TRX], IMMED << 1)); } 11110,6.IMM_10_5,5.IMM_15_11 + 10001,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LH "lh r, (r)" *mips16: *vr4100: { GPR[TRY] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[TRX], EXTEND16 (IMMEDIATE))); } 10101,3.RX,3.RY,5.IMMED:RRI:16::LHU "lhu r, (r)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_HALFWORD, GPR[TRX], IMMED << 1); } 11110,6.IMM_10_5,5.IMM_15_11 + 10101,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LHU "lhu r, (r)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_HALFWORD, GPR[TRX], EXTEND16 (IMMEDIATE)); } 10011,3.RX,3.RY,5.IMMED:RRI:16::LW "lw r, (r)" *mips16: *vr4100: { GPR[TRY] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[TRX], IMMED << 2)); } 11110,6.IMM_10_5,5.IMM_15_11 + 10011,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LW "lw r, (r)" *mips16: *vr4100: { GPR[TRY] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[TRX], EXTEND16 (IMMEDIATE))); } 10110,3.RX,8.IMMED:RI:16::LWPC "lw r, (PC)" *mips16: *vr4100: { GPR[TRX] = EXTEND32 (do_load (SD_, AccessLength_WORD, basepc (SD_) & ~3, IMMED << 2)); } 11110,6.IMM_10_5,5.IMM_15_11 + 10110,3.RX,000,5.IMM_4_0:EXT-RI:16::LWPC "lw r, (PC)" *mips16: *vr4100: { GPR[TRX] = EXTEND32 (do_load (SD_, AccessLength_WORD, basepc (SD_) & ~3, EXTEND16 (IMMEDIATE))); } 10010,3.RX,8.IMMED:RI:16::LWSP "lw r, (SP)" *mips16: *vr4100: { GPR[TRX] = EXTEND32 (do_load (SD_, AccessLength_WORD, SP, IMMED << 2)); } 11110,6.IMM_10_5,5.IMM_15_11 + 10010,3.RX,000,5.IMM_4_0:EXT-RI:16::LWSP "lw r, (SP)" *mips16: *vr4100: { GPR[TRX] = EXTEND32 (do_load (SD_, AccessLength_WORD, SP, EXTEND16 (IMMEDIATE))); } 10111,3.RX,3.RY,5.IMMED:RRI:16::LWU "lwu r, (r)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_WORD, GPR[TRX], IMMED << 2); } 11110,6.IMM_10_5,5.IMM_15_11 + 10111,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LWU "lwu r, (r)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_WORD, GPR[TRX], EXTEND16 (IMMEDIATE)); } 00111,3.RX,3.RY,5.IMMED:RRI:16::LD "ld r, (r)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, GPR[TRX], IMMED << 3); } 11110,6.IMM_10_5,5.IMM_15_11 + 00111,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::LD "ld r, (r)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, GPR[TRX], EXTEND16 (IMMEDIATE)); } 11111,100,3.RY,5.IMMED:RI64:16::LDPC "ld r, (PC)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, basepc (SD_) & ~7, IMMED << 3); } 11110,6.IMM_10_5,5.IMM_15_11 + 11111,100,3.RY,5.IMM_4_0:EXT-RI64:16::LDPC "ld r, (PC)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, basepc (SD_) & ~7, EXTEND16 (IMMEDIATE)); } 11111,000,3.RY,5.IMMED:RI64:16::LDSP "ld r, (SP)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, SP, IMMED << 3); } 11110,6.IMM_10_5,5.IMM_15_11 + 11111,000,3.RY,5.IMM_4_0:EXT-RI64:16::LDSP "ld r, (SP)" *mips16: *vr4100: { GPR[TRY] = do_load (SD_, AccessLength_DOUBLEWORD, SP, EXTEND16 (IMMEDIATE)); } 11000,3.RX,3.RY,5.IMMED:RRI:16::SB "sb r, (r)" *mips16: *vr4100: { do_store (SD_, AccessLength_BYTE, GPR[TRX], IMMED, GPR[TRY]); } 11110,6.IMM_10_5,5.IMM_15_11 + 11000,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::SB "sb r, (r)" *mips16: *vr4100: { do_store (SD_, AccessLength_BYTE, GPR[TRX], EXTEND16 (IMMEDIATE), GPR[TRY]); } 11001,3.RX,3.RY,5.IMMED:RRI:16::SH "sh r, (r)" *mips16: *vr4100: { do_store (SD_, AccessLength_HALFWORD, GPR[TRX], IMMED << 1, GPR[TRY]); } 11110,6.IMM_10_5,5.IMM_15_11 + 11001,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::SH "sh r, (r)" *mips16: *vr4100: { do_store (SD_, AccessLength_HALFWORD, GPR[TRX], EXTEND16 (IMMEDIATE), GPR[TRY]); } 11011,3.RX,3.RY,5.IMMED:RRI:16::SW "sw r, (r)" *mips16: *vr4100: { do_store (SD_, AccessLength_WORD, GPR[TRX], IMMED << 2, GPR[TRY]); } 11110,6.IMM_10_5,5.IMM_15_11 + 11011,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::SW "sw r, (r)" *mips16: *vr4100: { do_store (SD_, AccessLength_WORD, GPR[TRX], EXTEND16 (IMMEDIATE), GPR[TRY]); } 11010,3.RX,8.IMMED:RI:16::SWSP "sw r, (SP)" *mips16: *vr4100: { do_store (SD_, AccessLength_WORD, SP, IMMED << 2, GPR[TRX]); } 11110,6.IMM_10_5,5.IMM_15_11 + 11010,3.RX,000,5.IMM_4_0:EXT-RI:16::SWSP "sw r, (SP)" *mips16: *vr4100: { do_store (SD_, AccessLength_WORD, SP, EXTEND16 (IMMEDIATE), GPR[TRX]); } 01100,010,8.IMMED:I8:16::SWRASP "sw r, (SP)" *mips16: *vr4100: { do_store (SD_, AccessLength_WORD, SP, IMMED << 2, RA); } 11110,6.IMM_10_5,5.IMM_15_11 + 01100,010,000,5.IMM_4_0:EXT-I8:16::SWRASP "sw r, (SP)" *mips16: *vr4100: { do_store (SD_, AccessLength_WORD, SP, EXTEND16 (IMMEDIATE), RA); } 01111,3.RX,3.RY,5.IMMED:RRI:16::SD "sd r, (r)" *mips16: *vr4100: { do_store (SD_, AccessLength_DOUBLEWORD, GPR[TRX], IMMED << 3, GPR[TRY]); } 11110,6.IMM_10_5,5.IMM_15_11 + 01111,3.RX,3.RY,5.IMM_4_0:EXT-RRI:16::SD "sd r, (r)" *mips16: *vr4100: { do_store (SD_, AccessLength_DOUBLEWORD, GPR[TRX], EXTEND16 (IMMEDIATE), GPR[TRY]); } 11111,001,3.RY,5.IMMED:RI64:16::SDSP "sd r, (SP)" *mips16: *vr4100: { do_store (SD_, AccessLength_DOUBLEWORD, SP, IMMED << 3, GPR[TRY]); } 11110,6.IMM_10_5,5.IMM_15_11 + 11111,001,3.RY,5.IMM_4_0:EXT-RI64:16::SDSP "sd r, (SP)" *mips16: *vr4100: { do_store (SD_, AccessLength_DOUBLEWORD, SP, EXTEND16 (IMMEDIATE), GPR[TRY]); } 11111,010,8.IMMED:I64:16::SDRASP "sd r, (SP)" *mips16: *vr4100: { do_store (SD_, AccessLength_DOUBLEWORD, SP, IMMED << 3, RA); } 11110,6.IMM_10_5,5.IMM_15_11 + 11111,010,000,5.IMM_4_0:EXT-I64:16::SDRASP "sd r, (SP)" *mips16: *vr4100: { do_store (SD_, AccessLength_DOUBLEWORD, SP, EXTEND16 (IMMEDIATE), RA); } // ALU Immediate Instructions 01101,3.RX,8.IMMED:RI:16::LI "li r, " *mips16: *vr4100: { do_ori (SD_, 0, TRX, IMMED); } 11110,6.IMM_10_5,5.IMM_15_11 + 01101,3.RX,000,5.IMM_4_0:EXT-RI:16::LI "li r, " *mips16: *vr4100: { do_ori (SD_, 0, TRX, IMMEDIATE); } 01000,3.RX,3.RY,0,4.IMMED:RRI-A:16::ADDIU "addiu r, r, " *mips16: *vr4100: { do_addiu (SD_, TRX, TRY, EXTEND4 (IMMED)); } 11110,7.IMM_10_4,4.IMM_14_11 + 01000,3.RX,3.RY,0,4.IMM_3_0:EXT-RRI-A:16::ADDIU "addiu r, r, " *mips16: *vr4100: { do_addiu (SD_, TRX, TRY, EXTEND15 (IMMEDIATE)); } 01001,3.RX,8.IMMED:RI:16::ADDIU8 "addiu r, " *mips16: *vr4100: { do_addiu (SD_, TRX, TRX, EXTEND8 (IMMED)); } 11110,6.IMM_10_5,5.IMM_15_11 + 01001,3.RX,000,5.IMM_4_0:EXT-RI:16::ADDIU8 "addiu r, " *mips16: *vr4100: { do_addiu (SD_, TRX, TRX, EXTEND16 (IMMEDIATE)); } 01100,011,8.IMMED:I8:16::ADJSP "addiu SP, " *mips16: *vr4100: { do_addiu (SD_, SPIDX, SPIDX, EXTEND8 (IMMED) << 3); } 11110,6.IMM_10_5,5.IMM_15_11 + 01100,011,000,5.IMM_4_0:EXT-I8:16::ADJSP "addiu SP, " *mips16: *vr4100: { do_addiu (SD_, SPIDX, SPIDX, EXTEND16 (IMMEDIATE)); } 00001,3.RX,8.IMMED:RI:16::ADDIUPC "addiu r, PC, " *mips16: *vr4100: { unsigned32 temp = (basepc (SD_) & ~3) + (IMMED << 2); GPR[TRX] = EXTEND32 (temp); } 11110,6.IMM_10_5,5.IMM_15_11 + 00001,3.RX,000,5.IMM_4_0:EXT-RI:16::ADDIUPC "addiu r, PC, " *mips16: *vr4100: { unsigned32 temp = (basepc (SD_) & ~3) + EXTEND16 (IMMEDIATE); GPR[TRX] = EXTEND32 (temp); } 00000,3.RX,8.IMMED:RI:16::ADDIUSP "addiu r, SP, " *mips16: *vr4100: { do_addiu (SD_, SPIDX, TRX, IMMED << 2); } 11110,6.IMM_10_5,5.IMM_15_11 + 00000,3.RX,000,5.IMM_4_0:EXT-RI:16::ADDIUSP "addiu r, SP, " *mips16: *vr4100: { do_addiu (SD_, SPIDX, TRX, EXTEND16 (IMMEDIATE)); } 01000,3.RX,3.RY,1,4.IMMED:RRI-A:16::DADDIU "daddiu r, r, " *mips16: *vr4100: { do_daddiu (SD_, TRX, TRY, EXTEND4 (IMMED)); } 11110,7.IMM_10_4,4.IMM_14_11 + 01000,3.RX,3.RY,1,4.IMM_3_0:EXT-RRI-A:16::DADDIU "daddiu r, r, " *mips16: *vr4100: { do_daddiu (SD_, TRX, TRY, EXTEND15 (IMMEDIATE)); } 11111,101,3.RY,5.IMMED:RI64:16::DADDIU5 "daddiu r, " *mips16: *vr4100: { do_daddiu (SD_, TRY, TRY, EXTEND5 (IMMED)); } 11110,6.IMM_10_5,5.IMM_15_11 + 11111,101,3.RY,5.IMM_4_0:EXT-RI64:16::DADDIU5 "daddiu r, " *mips16: *vr4100: { do_daddiu (SD_, TRY, TRY, EXTEND16 (IMMEDIATE)); } 11111,011,8.IMMED:I64:16::DADJSP "daddiu SP, " *mips16: *vr4100: { do_daddiu (SD_, SPIDX, SPIDX, EXTEND8 (IMMED) << 3); } 11110,6.IMM_10_5,5.IMM_15_11 + 11111,011,000,5.IMM_4_0:EXT-I64:16::DADJSP "daddiu SP, " *mips16: *vr4100: { do_daddiu (SD_, SPIDX, SPIDX, EXTEND16 (IMMEDIATE)); } 11111,110,3.RY,5.IMMED:RI64:16::DADDIUPC "daddiu r, PC, " *mips16: *vr4100: { GPR[TRY] = (basepc (SD_) & ~3) + (IMMED << 2); } 11110,6.IMM_10_5,5.IMM_15_11 + 11111,110,3.RY,5.IMM_4_0:EXT-RI64:16::DADDIUPC "daddiu r, PC, " *mips16: *vr4100: { GPR[TRY] = (basepc (SD_) & ~3) + EXTEND16 (IMMEDIATE); } 11111,111,3.RY,5.IMMED:RI64:16::DADDIUSP "daddiu r, SP, " *mips16: *vr4100: { do_daddiu (SD_, SPIDX, TRY, IMMED << 2); } 11110,6.IMM_10_5,5.IMM_15_11 + 11111,111,3.RY,5.IMM_4_0:EXT-RI64:16::DADDIUSP "daddiu r, SP, " *mips16: *vr4100: { do_daddiu (SD_, SPIDX, TRY, EXTEND16 (IMMEDIATE)); } 01010,3.RX,8.IMMED:RI:16::SLTI "slti r, " *mips16: *vr4100: { do_slti (SD_, TRX, T8IDX, IMMED); } 11110,6.IMM_10_5,5.IMM_15_11 + 01010,3.RX,000,5.IMM_4_0:EXT-RI:16::SLTI "slti r, " *mips16: *vr4100: { do_slti (SD_, TRX, T8IDX, IMMEDIATE); } 01011,3.RX,8.IMMED:RI:16::SLTIU "sltiu r, " *mips16: *vr4100: { do_sltiu (SD_, TRX, T8IDX, IMMED); } 11110,6.IMM_10_5,5.IMM_15_11 + 01011,3.RX,000,5.IMM_4_0:EXT-RI:16::SLTIU "sltiu r, " *mips16: *vr4100: { do_sltiu (SD_, TRX, T8IDX, IMMEDIATE); } 11101,3.RX,3.RY,01010:RR:16::CMP "cmp r, r" *mips16: *vr4100: { do_xor (SD_, TRX, TRY, T8IDX); } 01110,3.RX,8.IMMED:RI:16::CMPI "cmpi r, " *mips16: *vr4100: { do_xori (SD_, TRX, T8IDX, IMMED); } 11110,6.IMM_10_5,5.IMM_15_11 + 01110,3.RX,000,5.IMM_4_0:EXT-RI:16::CMPI "sltiu r, " *mips16: *vr4100: { do_xori (SD_, TRX, T8IDX, IMMEDIATE); } // Two/Three Operand, Register-Type 11100,3.RX,3.RY,3.RZ,01:RRR:16::ADDU "addu r, r, r" *mips16: *vr4100: { do_addu (SD_, TRX, TRY, TRZ); } 11100,3.RX,3.RY,3.RZ,11:RRR:16::SUBU "subu r, r, r" *mips16: *vr4100: { do_subu (SD_, TRX, TRY, TRZ); } 11100,3.RX,3.RY,3.RZ,00:RRR:16::DADDU "daddu r, r, r" *mips16: *vr4100: { do_daddu (SD_, TRX, TRY, TRZ); } 11100,3.RX,3.RY,3.RZ,10:RRR:16::DSUBU "dsubu r, r, r" *mips16: *vr4100: { do_dsubu (SD_, TRX, TRY, TRZ); } 11101,3.RX,3.RY,00010:RR:16::SLT "slt r, r" *mips16: *vr4100: { do_slt (SD_, TRX, TRY, T8IDX); } 11101,3.RX,3.RY,00011:RR:16::SLTU "sltu r, r" *mips16: *vr4100: { do_sltu (SD_, TRX, TRY, T8IDX); } 11101,3.RX,3.RY,01011:RR:16::NEG "neg r, r" *mips16: *vr4100: { do_subu (SD_, 0, TRY, TRX); } 11101,3.RX,3.RY,01100:RR:16::AND "and r, r" *mips16: *vr4100: { do_and (SD_, TRX, TRY, TRX); } 11101,3.RX,3.RY,01101:RR:16::OR "or r, r" *mips16: *vr4100: { do_or (SD_, TRX, TRY, TRX); } 11101,3.RX,3.RY,01110:RR:16::XOR "xor r, r" *mips16: *vr4100: { do_xor (SD_, TRX, TRY, TRX); } 11101,3.RX,3.RY,01111:RR:16::NOT "not r, r" *mips16: *vr4100: { do_nor (SD_, 0, TRY, TRX); } 01100,111,3.RY,5.R32:I8_MOVR32:16::MOVR32 "move r, r" *mips16: *vr4100: { do_or (SD_, R32, 0, TRY); } 01100,101,3.R32L,2.R32H,3.RZ:I8_MOV32R:16::MOV32R "move r, r" *mips16: *vr4100: { do_or (SD_, TRZ, 0, R32); } 00110,3.RX,3.RY,3.SHAMT,00:SHIFT:16::SLL "sll r, r, " *mips16: *vr4100: { do_sll (SD_, TRY, TRX, SHIFT); } 11110,5.SHAMT,0,00000 + 00110,3.RX,3.RY,000,00:EXT-SHIFT:16::SLL "sll r, r, " *mips16: *vr4100: { do_sll (SD_, TRY, TRX, SHAMT); } 00110,3.RX,3.RY,3.SHAMT,10:SHIFT:16::SRL "srl r, r, " *mips16: *vr4100: { do_srl (SD_, TRY, TRX, SHIFT); } 11110,5.SHAMT,0,00000 + 00110,3.RX,3.RY,000,10:EXT-SHIFT:16::SRL "srl r, r, " *mips16: *vr4100: { do_srl (SD_, TRY, TRX, SHAMT); } 00110,3.RX,3.RY,3.SHAMT,11:SHIFT:16::SRA "sra r, r, " *mips16: *vr4100: { do_sra (SD_, TRY, TRX, SHIFT); } 11110,5.SHAMT,0,00000 + 00110,3.RX,3.RY,000,11:EXT-SHIFT:16::SRA "sra r, r, " *mips16: *vr4100: { do_sra (SD_, TRY, TRX, SHAMT); } 11101,3.RX,3.RY,00100:RR:16::SLLV "sllv r, r" *mips16: *vr4100: { do_sllv (SD_, TRX, TRY, TRY); } 11101,3.RX,3.RY,00110:RR:16::SRLV "srlv r, r" *mips16: *vr4100: { do_srlv (SD_, TRX, TRY, TRY); } 11101,3.RX,3.RY,00111:RR:16::SRAV "srav r, r" *mips16: *vr4100: { do_srav (SD_, TRX, TRY, TRY); } 00110,3.RX,3.RY,3.SHAMT,01:SHIFT:16::DSLL "dsll r, r, " *mips16: *vr4100: { do_dsll (SD_, TRY, TRX, SHIFT); } 11110,5.SHAMT_4_0,1.S5,00000 + 00110,3.RX,3.RY,000,01:EXT-SHIFT:16::DSLL "dsll r, r, " *mips16: *vr4100: { do_dsll (SD_, TRY, TRX, SHAMT); } 11101,3.SHAMT,3.RY,01000:SHIFT64:16::DSRL "dsrl r, " *mips16: *vr4100: { do_dsrl (SD_, TRY, TRY, SHIFT); } 11110,5.SHAMT_4_0,1.S5,00000 + 11101,000,3.RY,01000:EXT-SHIFT64:16::DSRL "dsrl r, " *mips16: *vr4100: { do_dsrl (SD_, TRY, TRY, SHAMT); } 11101,3.SHAMT,3.RY,10011:SHIFT64:16::DSRA "dsra r, " *mips16: *vr4100: { do_dsra (SD_, TRY, TRY, SHIFT); } 11110,5.SHAMT_4_0,1.S5,00000 + 11101,000,3.RY,10011:EXT-SHIFT64:16::DSRA "dsra r, " *mips16: *vr4100: { do_dsra (SD_, TRY, TRY, SHAMT); } 11101,3.RX,3.RY,10100:RR:16::DSLLV "dsllv r, r" *mips16: *vr4100: { do_dsllv (SD_, TRX, TRY, TRY); } 11101,3.RX,3.RY,10110:RR:16::DSRLV "dsrlv r, r" *mips16: *vr4100: { do_dsrlv (SD_, TRX, TRY, TRY); } 11101,3.RX,3.RY,10111:RR:16::DSRAV "dsrav r, r" *mips16: *vr4100: { do_dsrav (SD_, TRX, TRY, TRY); } // Multiply /Divide Instructions 11101,3.RX,3.RY,11000:RR:16::MULT "mult r, r" *mips16: *vr4100: { do_mult (SD_, TRX, TRY, 0); } 11101,3.RX,3.RY,11001:RR:16::MULTU "multu r, r" *mips16: *vr4100: { do_multu (SD_, TRX, TRY, 0); } 11101,3.RX,3.RY,11010:RR:16::DIV "div r, r" *mips16: *vr4100: { do_div (SD_, TRX, TRY); } 11101,3.RX,3.RY,11011:RR:16::DIVU "divu r, r" *mips16: *vr4100: { do_divu (SD_, TRX, TRY); } 11101,3.RX,000,10000:RR:16::MFHI "mfhi r" *mips16: *vr4100: { do_mfhi (SD_, TRX); } 11101,3.RX,000,10010:RR:16::MFLO "mflo r" *mips16: *vr4100: { do_mflo (SD_, TRX); } 11101,3.RX,3.RY,11100:RR:16::DMULT "dmult r, r" *mips16: *vr4100: { do_dmult (SD_, TRX, TRY, 0); } 11101,3.RX,3.RY,11101:RR:16::DMULTU "dmultu r, r" *mips16: *vr4100: { do_dmultu (SD_, TRX, TRY, 0); } 11101,3.RX,3.RY,11110:RR:16::DDIV "ddiv r, r" *mips16: *vr4100: { do_ddiv (SD_, TRX, TRY); } 11101,3.RX,3.RY,11111:RR:16::DDIVU "ddivu r, r" *mips16: *vr4100: { do_ddivu (SD_, TRX, TRY); } // Jump and Branch Instructions // Issue instruction in delay slot of branch :function:::address_word:delayslot16:address_word nia, address_word target { instruction_word delay_insn; sim_events_slip (SD, 1); DSPC = CIA; /* save current PC somewhere */ STATE |= simDELAYSLOT; delay_insn = IMEM16 (nia); /* NOTE: mips16 */ idecode_issue (CPU_, delay_insn, (nia)); STATE &= ~simDELAYSLOT; return target; } // compute basepc dependant on us being in a delay slot :function:::address_word:basepc: { if (STATE & simDELAYSLOT) { return DSPC; /* return saved address of preceeding jmp */ } else { return CIA; } } // JAL 00011,0,5.IMM_20_16,5.IMM_25_21 + 16.IMMED_15_0:JAL:16::JAL "jal " *mips16: *vr4100: { address_word region = (NIA & MASK (63, 28)); RA = NIA + 2; /* skip 16 bit delayslot insn */ NIA = delayslot16 (SD_, NIA, (region | (IMMEDIATE << 2))) | 1; } // JALX - 32 and 16 bit versions. 011101,26.IMMED:JALX:32::JALX32 "jalx " *mips32: *mips64: *mips32r2: *mips64r2: *mips16: *vr4100: { address_word region = (NIA & MASK (63, 28)); RA = NIA + 4; /* skip 32 bit delayslot insn */ NIA = delayslot32 (SD_, (region | (IMMED << 2)) | 1); } 00011,1,5.IMM_20_16,5.IMM_25_21 + 16.IMMED_15_0:JALX:16::JALX16 "jalx " *mips16: *vr4100: { address_word region = (NIA & MASK (63, 28)); RA = NIA + 2; /* 16 bit INSN */ NIA = delayslot16 (SD_, NIA, (region | (IMMEDIATE << 2)) & ~1); } 11101,3.RX,000,00000:RR:16::JR "jr r" *mips16: *vr4100: { NIA = delayslot16 (SD_, NIA, GPR[TRX]); } 11101,000,001,00000:RR:16::JRRA "jrra" *mips16: *vr4100: { NIA = delayslot16 (SD_, NIA, RA); } 11101,3.RX,010,00000:RR:16::JALR "jalr r" *mips16: *vr4100: { RA = NIA + 2; NIA = delayslot16 (SD_, NIA, GPR[TRX]); } 00100,3.RX,8.IMMED:RI:16::BEQZ "beqz r, " *mips16: *vr4100: { if (GPR[TRX] == 0) NIA = (NIA + (EXTEND8 (IMMED) << 1)); } 11110,6.IMM_10_5,5.IMM_15_11 + 00100,3.RX,000,5.IMM_4_0:EXT-RI:16::BEQZ "beqz r, " *mips16: *vr4100: { if (GPR[TRX] == 0) NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1)); } 00101,3.RX,8.IMMED:RI:16::BNEZ "bnez r, " *mips16: *vr4100: { if (GPR[TRX] != 0) NIA = (NIA + (EXTEND8 (IMMED) << 1)); } 11110,6.IMM_10_5,5.IMM_15_11 + 00101,3.RX,000,5.IMM_4_0:EXT-RI:16::BNEZ "bnez r, " *mips16: *vr4100: { if (GPR[TRX] != 0) NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1)); } 01100,000,8.IMMED:I8:16::BTEQZ "bteqz " *mips16: *vr4100: { if (T8 == 0) NIA = (NIA + (EXTEND8 (IMMED) << 1)); } 11110,6.IMM_10_5,5.IMM_15_11 + 01100,000,000,5.IMM_4_0:EXT-I8:16::BTEQZ "bteqz " *mips16: *vr4100: { if (T8 == 0) NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1)); } 01100,001,8.IMMED:I8:16::BTNEZ "btnez " *mips16: *vr4100: { if (T8 != 0) NIA = (NIA + (EXTEND8 (IMMED) << 1)); } 11110,6.IMM_10_5,5.IMM_15_11 + 01100,001,000,5.IMM_4_0:EXT-I8:16::BTNEZ "btnez " *mips16: *vr4100: { if (T8 != 0) NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1)); } 00010,11.IMMED:I:16::B "b " *mips16: *vr4100: { NIA = (NIA + (EXTEND11 (IMMED) << 1)); } 11110,6.IMM_10_5,5.IMM_15_11 + 00010,6.0,5.IMM_4_0:EXT-I:16::B "b " *mips16: *vr4100: { NIA = (NIA + (EXTEND16 (IMMEDIATE) << 1)); } 11101,3.RX,3.RY,00101:RR:16::BREAK "break" *mips16: *vr4100: { do_break16 (SD_, instruction_0); }