/* ABS.fmt Abs - Floating Point Absolute Value */ 010001 fmt(5) 00000 fs(5) fd(5) 000101: StoreFPR(fd, fmt, float_abs(ValueFPR(fs, fmt))); /* ADD Add Word */ 000000 rs(5) rt(5) rd(5) 00000 100000: uint64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt]) ) { UNPREDICTABLE; } temp = (bit(GPR[rs],31) << 32) | GPR[rs]; temp += (bit(GPR[rt],31) << 32) | GPR[rt]; if (bit(temp,32) != bit(temp,31)) { SignalException(IntegerOverflow); } else { GPR[rd] = sign_extend(temp, 32); } /* ADDI Add immediate */ 001000 rs(5) rt(5) immediate(16): uint64_t temp; if (NotWordValue(GPR[rs])) { UNPREDICTABLE; } temp = (bit(GPR[rs],31) << 32) | GPR[rs]; temp += sign_extend(immediate,16); if (bit(temp,32) != bit(temp,31)) { SignalException(IntegerOverflow); } else { GPR[rt] = sign_extend(temp, 32); } /* ADDIU Add immediate, unsigned */ 001001 rs(5) rt(5) immediate(16): uint64_t temp; if (NotWordValue(GPR[rs])) { UNPREDICTABLE; } temp = GPR[rs] + sign_extend(immediate, 16); GPR[rt] = sign_extend(temp, 32); /* ADDU Add unsigned word */ 000000 rs(5) rt(5) rd(5) 00000 100001: uint64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = GPR[rs] + GPR[rt]; GPR[rd] = sign_extend(temp, 32); /* ALNV.PS Floating point align */ 010011 rs(5) ft(5) fs(5) fd(5) 011110: if (bits(GPR[rs],0,2) == 0) { StoreFPR(fd, PS, ValueFPR(fd, PS)); } else if (bits(GPR[rs],0,2) != 4) { UNPREDICTABLE; } else if (BigEndianCPU) { StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),0,31) << 32) | bits(ValueFPR(ft, PS), 32, 63)); } else { StoreFPR(fd, PS, (bits(ValueFPR(ft, PS),0,31) << 32) | bits(ValueFPR(fs, PS), 32, 63)); } /* AND And */ 000000 rs(5) rt(5) rd(5) 00000 100100: GPR[rd] = GPR[rs] & GPR[rt]; /* ANDI And Immediate */ 001100 rs(5) rt(5) immediate(16): GPR[rt] = GPR[rs] & zero_extend(immediate, 16); /* B Unconditional branch */ 000100 00000 00000 offset(16): uint64_t target_offset; /* I: */ target_offset = sign_extend(offset << 2, 18); NextInstruction(); /* I+1: */ PC = PC + target_offset - 4; /* BAL Branch and Link */ 000001 00000 10001 offset(16): uint64_t target_offset; /* I: */ target_offset = sign_extend(offset << 2, 18); GPR[31] = PC + 4; NextInstruction(); /* I+1: */ PC = PC + target_offset - 4; /* BC1F/T Branch on FP False/True */ 010001 01000 cc(3) 0 tf(1) offset(16): uint64_t target_offset; int condition; /* I: */ condition=FPConditionCode(cc) == tf; target_offset = sign_extend(offset << 2, 18); NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BC1F/TL Branch on FP False/True Likely */ 010001 01000 cc(3) 1 tf(1) offset(16): uint64_t target_offset; int condition; /* I: */ condition=FPConditionCode(cc) == tf; target_offset = sign_extend(offset << 2, 18); /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BC2F/T Branch on COP2 False/True */ 010010 01000 cc(3) 0 tf(1) offset(16): SignalException(Unimplemented); /* BC2F/TL Branch on COP2 False/True Likely */ 010001 01000 cc(3) 1 tf(1) offset(16): SignalException(Unimplemented); /* BEQ Branch on Equal */ 000100 rs(5) rt(5) offset(16): uint64_t target_offset; int condition; /* I: */ condition = (GPR[rs] == GPR[rt]); target_offset = sign_extend(offset << 2, 18); NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BEQL branch on Equal Likely */ 010100 rs(5) rt(5) offset(16): uint64_t target_offset; int condition; /* I: */ condition = (GPR[rs] == GPR[rt]); target_offset = sign_extend(offset << 2, 18); /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BGEZ Branch on Equal or Greater Than Zero */ 000001 rs(5) 00001 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] >= 0); target_offset = sign_extend(offset << 2, 18); NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BGEZL Branch on Equal or Greater Than Zero Likely */ 000001 rs(5) 00011 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] >= 0); target_offset = sign_extend(offset << 2, 18); /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BGEZAL Branch on greater Than or Equal to Zero and Link */ 000001 rs(5) 10001 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] >= 0); target_offset = sign_extend(offset << 2, 18); GPR[31] = PC + 4; NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BGEZALL Branch on greater Than or Equal to Zero and Link Likely */ 000001 rs(5) 10011 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] >= 0); target_offset = sign_extend(offset << 2, 18); GPR[31] = PC + 4; /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BGTZ Branch on Greater Than Zero */ 000111 rs(5) 00000 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] > 0); target_offset = sign_extend(offset << 2, 18); NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BGTZL Branch on Greater Than Zero Likely */ 010111 rs(5) 00000 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] > 0); target_offset = sign_extend(offset << 2, 18); /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BLEZ Branch on Less Than or Equal to Zero */ 000110 rs(5) 00000 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] <= 0); target_offset = sign_extend(offset << 2, 18); NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BLEZL Branch on Less Than or Equal to Zero Likely */ 010110 rs(5) 00000 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] <= 0); target_offset = sign_extend(offset << 2, 18); /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BLTZ Branch on Less Than Zero */ 000001 rs(5) 00000 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] < 0); target_offset = sign_extend(offset << 2, 18); NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BLTZL Branch on Less Than Zero Likely */ 000001 rs(5) 00010 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] < 0); target_offset = sign_extend(offset << 2, 18); /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BLTZAL Branch on Less Than Zero and Link */ 000001 rs(5) 10000 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] < 0); target_offset = sign_extend(offset << 2, 18); GPR[31] = PC + 4; NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BLTZALL Branch on Less Than Zero and Link Likely */ 000001 rs(5) 10010 offset(16): uint64_t target_offset; int condition; /* I: */ condition = ((int64_t)GPR[rs] < 0); target_offset = sign_extend(offset << 2, 18); GPR[31] = PC + 4; /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BNE Branch on Not Equal */ 000101 rs(5) rt(5) offset(16): uint64_t target_offset; int condition; /* I: */ condition = (GPR[rs] != GPR[rt]); target_offset = sign_extend(offset << 2, 18); NextInstruction(); /* I+1: */ if (condition) { PC = PC + target_offset - 4; } /* BNEL Branch on Not Equal Likely */ 010101 rs(5) rt(5) offset(16): uint64_t target_offset; int condition; /* I: */ condition = (GPR[rs] != GPR[rt]); target_offset = sign_extend(offset << 2, 18); /* I+1: */ if (condition) { NextInstruction(); PC = PC + target_offset - 4; } /* BREAK Breakpoint */ 000000 code(20) 001101: SignalException(Breakpoint); /* C.cond.fmt Floating Point Compare */ 010001 fmt(5) ft(5) fs(5) cc(3) 0 0 11 cond(4): int less, equal, unordered, condition; if (SNaN(ValueFPR(fs, fmt)) || SNaN(ValueFPR(ft, fmt)) || QNaN(ValueFPR(fs, fmt)) || QNaN(ValueFPR(ft, fmt))) { less = 0; equal = 0; unordered = 1; if (SNaN(ValueFPR(fs,fmt)) || SNaN(ValueFPR(ft, fmt)) || (bit(cond,3) && (QNaN(ValueFPR(fs, fmt) || QNaN(ValueFPR(ft, fmt)))))) { SignalException(InvalidOperation); } } else { less = float_less_than(ValueFPR(fs, fmt),ValueFPR(ft, fmt)); equal = float_equal_to(ValueFPR(fs, fmt),ValueFPR(ft, fmt)); unordered = 0; } condition = (bit(cond,2) && less) || (bit(cond,1) && equal) || (bit(cond,0) && unordered); SetFPConditionCode(condition); /* CACHE Perform Cache Operation */ 101111 base(5) op(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset, 16); /* (pAddr, uncached) = AddressTranslation(vAddr, DataReadReference); */ /* CacheOp(op, vAddr, pAddr); */ /* CEIL.L.fmt Fixed Point Ceiling Convert to Long Fixed Point */ 010001 fmt(5) 00000 fs(5) fd(5) 001010: StoreFPR(fd, L, ConvertFmt(ValueFPR(fs, fmt), fmt, L)); /* CEIL.W.fmt Floating Point Ceiling Convert to Word Fixed Point */ 010001 fmt(5) 00000 fs(5) fd(5) 001110: StoreFPR(fd, W, ConvertFmt(ValueFPR(fs, fmt), fmt, W)); /* CFC1 Move Control Word From Floating Point * This has to be before ADD.fmt. */ 010001 00010 rt(5) fs(5) 00000 000000: uint32_t temp; if (fs == 0) { temp = FIR; } else if (fs == 25) { temp = (bits(FCSR,25,31) << 1) | bit(FCSR,23); } else if (fs == 26) { temp = (bits(FCSR,12,17) << 12) | (bits(FCSR,2,6) << 2); } else if (fs == 28) { temp = (bits(FCSR,7,11) << 7) | (bit(FCSR,24) << 2) | bits(FCSR,0,1); } else if (fs == 31) { temp = FCSR; } else { temp = 0; } GPR[rt] = sign_extend(temp, 32); /* CFC2 Move Control Word From Coprocessor 2 */ 010010 00010 rt(5) Impl(16): /* GPR[rt] = sign_extend(CP2CCR[Impl], 32); */ GPR[rt] = 0; /* CLO/Z Count Leading Ones/Zeros in Word */ 011100 rs(5) rt(5) rd(5) 00000 10000 one_zero(1): int temp, i; if (NotWordValue(GPR[rs])) { UNPREDICTABLE; } temp = 32; for (i = 31; i >= 0; i--) { if (bit(GPR[rs],i) != one_zero) { temp = 31 - i; break; } } GPR[rd] = temp; /* COP2 Coprocessor Operation to Coprocessor 2 */ 010010 1 cofun(25): SignalException(Unimplemented); /* CTC1 Move Control Word To Floating Point */ 010001 00110 rt(5) fs(5) 00000 000000: uint32_t temp; temp=bits(GPR[rt],0,31); if (fs == 25) { if (bits(temp,8,31) != 0) { UNPREDICTABLE; } else { FCSR = (bits(temp,1,7) << 25) | (bit(FCSR,24) << 24) | (bit(temp,0) << 23) | bits(FCSR,0,22); } } else if (fs == 26) { if (bits(temp,18,22) != 0) { UNPREDICTABLE; } else { FCSR = (bits(FCSR,18,31) << 18) | (bits(temp,12,17) << 12) | (bits(FCSR,7,11) << 7) | (bits(temp,2,6) << 2) | bits(FCSR,0,1); } } else if (fs == 28) { if (bits(temp,18,22) != 0) { UNPREDICTABLE; } else { FCSR = (bits(FCSR,25,31) << 25) | (bit(temp,2) << 24) | (bits(FCSR,12,23) << 12) | (bits(temp,7,11) << 7) | (bits(FCSR,2,6) << 2) | bits(temp,0,1); } } else if (fs == 31) { if (bits(temp,18,22) != 0) { UNPREDICTABLE; } else { FCSR = temp; } } else { UNPREDICTABLE; } /* CTC2 Move Control Word to Coprocessor 2 */ 010010 00110 rt(5) Impl(16): /* CP2CCR[Impl] = bits(GPR[rt],0,31); */ /* CVT.D.fmt Floating Point Convert to Double Floating Point */ 010001 fmt(5) 00000 fs(5) fd(5) 100001: StoreFPR(fd, D, ConvertFmt(ValueFPR(fs, fmt), fmt, D)); /* CVT.L.fmt Floating Point Convert to Long Fixed Format */ 010001 fmt(5) 00000 fs(5) fd(5) 100101: StoreFPR(fd, L, ConvertFmt(ValueFPR(fs, fmt), fmt, L)); /* CVT.PS.S Floating Point Convert Pair to Paired Single */ 010001 10000 ft(5) fs(5) fd(5) 100110: StoreFPR(fd, S, (ValueFPR(fs, S) << 32) | ValueFPR(ft, S)); /* CVT.S.fmt Floating Point Convert to Single Floating Point */ 010001 fmt(5) 00000 fs(5) fd(5) 100000: StoreFPR(fd, S, ConvertFmt(ValueFPR(fs, fmt), fmt, S)); /* CVT.S.PL Floating Point Convert Pair Lower to Single Floating Point */ 010001 10110 00000 fs(5) fd(5) 101000: StoreFPR(fd, S, ConvertFmt(ValueFPR(fs, PS), PL, S)); /* CVT.S.PU Floating Point Convert Pair Upper to Single Floating Point */ 010001 10110 00000 fs(5) fd(5) 100000: StoreFPR(fd, S, ConvertFmt(ValueFPR(fs, PS), PU, S)); /* CVT.W.fmt Floating Point Convert to Word Fixed Point */ 010001 fmt(5) 00000 fs(5) fd(5) 100100: StoreFPR(fd, W, ConvertFmt(ValueFPR(fs, fmt), fmt, W)); /* DADD Doubleword Add */ 000000 rs(5) rt(5) rd(5) 00000 101100: uint64_t temp; int carry; temp = add_carry64(GPR[rs], GPR[rt], &carry); if (carry) { SignalException(IntegerOverflow); } else { GPR[rd] = temp; } /* DADDI Doubleword Add Immediate */ 011000 rs(5) rt(5) immediate(16): uint64_t temp; int carry; temp = add_carry64(GPR[rs], sign_extend(immediate, 16), &carry); if (carry) { SignalException(IntegerOverflow); } else { GPR[rt] = temp; } /* DADDIU Doubleword Add Immediate Unsigned */ 011001 rs(5) rt(5) immediate(16): GPR[rt] = GPR[rs] + sign_extend(immediate, 16); /* DADDU Doubleword Add Unsigned */ 000000 rs(5) rt(5) rd(5) 00000 101101: GPR[rd] = GPR[rs] + GPR[rt]; /* DCLO/Z Count Leading Ones/Zeros in Doubleword */ 011100 rs(5) rt(5) rd(5) 00000 10010 is_one(1): int temp, i; temp = 64; for (i = 63; i >= 0; i--) { if (bit(GPR[rs],i) == is_one) { temp = 63 - i; break; } } GPR[rd] = temp; /* DDIV Doubleword Divide */ 000000 rs(5) rt(5) 00000 00000 011110: LO = (int64_t)GPR[rs] / (int64_t)GPR[rt]; HI = (int64_t)GPR[rs] % (int64_t)GPR[rt]; /* DDIVU Doubleword Divide Unsigned */ 000000 rs(5) rt(5) 00000 00000 011111: LO = (uint64_t)GPR[rs] / (uint64_t)GPR[rt]; HI = (uint64_t)GPR[rs] % (uint64_t)GPR[rt]; /* DERET Debug Exception Return */ 010000 1 0000 00000 00000 00000 011111: Debug.DM=0; Debug.IEXI=0; PC = DEPC; /* DIV Divide Word */ 000000 rs(5) rt(5) 00000 00000 011010: int64_t q,r; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } q = (int32_t)GPR[rs] / (int32_t)GPR[rt]; r = (int32_t)GPR[rs] % (int32_t)GPR[rt]; LO = sign_extend(q, 32); HI = sign_extend(r, 32); /* DIV.fmt Floating Point Divide */ 010001 fmt(5) ft(5) fs(5) fd(5) 000011: StoreFPR(fd, fmt, float_div(ValueFPR(fs, fmt),ValueFPR(ft, fmt))); /* DIVU Divide Unsigned Word */ 000000 rs(5) rt(5) 00000 00000 011011: uint32_t q,r; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } q = (uint32_t)GPR[rs] / (uint32_t)GPR[rt]; r = (uint32_t)GPR[rs] % (uint32_t)GPR[rt]; LO = sign_extend(q, 32); HI = sign_extend(r, 32); /* DMFC0 Doubleword Move from Coprocessor 0 */ 010000 00001 rt(5) rd(5) 00000 000 sel(3): SignalException(Unimplemented); /* DMFC1 Doubleword Move from Floting Point */ 010001 00001 rt(5) fs(5) 00000 000000: GPR[rt] = ValueFPR(fs, UNINTERPRETED_DOUBLEWORD); /* DMFC2 Doubleword Move from Coprocessor 2 */ 010010 00001 rt(5) Impl(16): SignalException(Unimplemented); /* DMTC0 Doubleword Move to Coprocessor 0 */ 010000 00101 rt(5) rd(5) 00000 000 sel(3): SignalException(Unimplemented); /* DMTC1 Doubleword Move to Floating Point */ 010001 00101 rt(5) fs(5) 00000 000000: StoreFPR(fs, UNINTERPRETED_DOUBLEWORD, GPR[rt]); /* DMTC2 Doubleword Move to Coprocessor 2 */ 010010 00101 rt(5) Impl(16): SignalException(Unimplemented); /* DMULT Doubleword Multiply */ 000000 rs(5) rt(5) 00000 00000 011100: mult64(GPR[rs],GPR[rt],&LO,&HI); /* DMULTU Doubleword Multiply Unsigned */ 000000 rs(5) rt(5) 00000 00000 011101: umult64(GPR[rs],GPR[rt],&LO,&HI); /* DSLL Doubleword Shift Left Logical */ 000000 00000 rt(5) rd(5) sa(5) 111000: GPR[rd] = GPR[rt] << sa; /* DSLL32 Doubleword Shift Left Logical Plus 32 */ 000000 00000 rt(5) rd(5) sa(5) 111100: GPR[rd] = GPR[rt] << (32+sa); /* DSLLV Doubleword Shift Left Logical Variable */ 000000 rs(5) rt(5) rd(5) 00000 010100: GPR[rd] = GPR[rt] << bits(GPR[rs],0,5); /* DSRA Doubleword Shift Right Arithmetic */ 000000 00000 rt(5) rd(5) sa(5) 111011: GPR[rd] = ((int64_t)GPR[rt]) >> sa; /* DSRA32 Doubleword Shift Right Arithmetic Plus 32 */ 000000 00000 rt(5) rd(5) sa(5) 111111: sa += 32; GPR[rd] = ((int64_t)GPR[rt]) >> sa; /* DSRAV Doubleword Shift Right Arithmetic Variable */ 000000 rs(5) rt(5) rd(5) 00000 010111: int sa; sa = bits(GPR[rs],0,5); GPR[rd] = ((int64_t)GPR[rt]) >> sa; /* DSLR Doubleword Shift Right Logical */ 000000 00000 rt(5) rd(5) sa(5) 111010: GPR[rd] = ((uint64_t)GPR[rt]) >> sa; /* DSLR32 Doubleword Shift Right Logical Plus 32 */ 000000 00000 rt(5) rd(5) sa(5) 111110: sa += 32; GPR[rd] = ((uint64_t)GPR[rt]) >> sa; /* DSRLV Doubleword Shift Right Logical Variable */ 000000 rs(5) rt(5) rd(5) 00000 010110: int sa; sa = bits(GPR[rs],0,5); GPR[rd] = ((uint64_t)GPR[rt]) >> sa; /* DSUB Doubleword Subtract */ 000000 rs(5) rt(5) rd(5) 00000 101110: int carry; int64_t temp; temp = sub_carry64(GPR[rs],GPR[rt],&carry); if (carry) { SignalException(IntegerOverflow); } else { GPR[rd] = temp; } /* DSUBU Doubleword Subtract Unsigned */ 000000 rs(5) rt(5) rd(5) 00000 101111: GPR[rd] = GPR[rs] - GPR[rt]; /* ERET Exception Return */ 010000 1 0000 00000 00000 00000 011000: uint64_t temp; if (Status.ERL == 1) { temp = ErrorEPC; Status.ERL = 0; } else { temp = EPC; Status.EXL = 0; } PC = temp; LLbit = 0; /* FLOOR.L.fmt Floting Point Convert to Long Fixed Point */ 010001 fmt(5) 00000 fs(5) fd(5) 001011: StoreFPR(fd, L, ConvertFmt(ValueFPR(fs, fmt), fmt, L)); /* FLOOR.W.fmt Floating Point Floor Convert to Word Fixed Point */ 010001 fmt(5) 00000 fs(5) fd(5) 001111: StoreFPR(fd, W, ConvertFmt(ValueFPR(fs, fmt), fmt, W)); /* J Jump */ 000010 instr_index(26): /* I: */ NextInstruction(); /* I+1: */ PC = (PC & ((1 << 28)-1)) | (instr_index << 2); /* JAL Jump and Link */ 000011 instr_index(26): /* I: */ GPR[31] = PC + 4; NextInstruction(); /* I+1: */ PC = (PC & ((1 << 28)-1)) | (instr_index << 2); /* JALR Jump and Link Register */ 000000 rs(5) 00000 rd(5) hint(5) 001001: uint64_t temp; /* I: */ temp = GPR[rs]; GPR[rd] = PC + 4; NextInstruction(); /* I+1: */ PC = temp; /* JR Jump Register */ 000000 rs(5) 00000 00000 hint(5) 001000: uint64_t temp; /* I: */ temp = GPR[rs]; NextInstruction(); /* I+1: */ PC=temp; /* LB Load Byte */ 100000 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; vAddr = GPR[base] + sign_extend(offset, 16); doubleword = LoadMemory(vAddr, BYTE); GPR[rt] = sign_extend(doubleword,8); /* LBU Load Byte Unsigned */ 100100 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset, 16); GPR[rt] = LoadMemory(vAddr, BYTE); /* LD Load Doubleword */ 110111 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset, 16); if (bits(vAddr,0,2) != 0) { SignalException(AddressError); } GPR[rt] = LoadMemory(vAddr, DOUBLEWORD); /* LDC1 Load Doubleword to Floating Point */ 110101 base(5) ft(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset, 16); if (bits(vAddr,0,2) != 0) { SignalException(AddressError); } StoreFPR(ft, UNINTERPRETED_DOUBLEWORD, LoadMemory(vAddr, DOUBLEWORD)); /* LDC2 Load Doubleword to Coprocessor 2 */ 110110 base(5) rt(5) offset(16): SignalException(Unimplemented); /* LDL Load Doubleword Left */ 011010 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; int byte; vAddr = GPR[base] + sign_extend(offset, 16); byte = bits(vAddr,0,2); doubleword = LoadMemory(vAddr, DOUBLEWORD); GPR[rt] = (bits(doubleword,0,7+8*byte) << (64-8*byte)) | (bits(GPR[rt],0,63-8*byte)); /* LDR Load Doubleword Right */ 011011 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; int byte; vAddr = GPR[base] + sign_extend(offset, 16); byte = bits(vAddr,0,2); doubleword = LoadMemory(vAddr, DOUBLEWORD); GPR[rt] = (bits(GPR[rt],64-8*byte,63) << (64-8*byte)) | bits(doubleword,8*byte,63); /* LDXC1 Load Doubleword Indexed to Floating Point */ 010011 base(5) index(5) 00000 fd(5) 000001: uint64_t vAddr; vAddr = GPR[base] + GPR[index]; if (bits(vAddr,0,2) != 0) { SignalException(AddressError); } StoreFPR(fd, UNINTERPRETED_DOUBLEWORD, LoadMemory(vAddr, DOUBLEWORD)); /* LH Load Halfword */ 100001 base(5) rt(5) offset(16): uint64_t vAddr, doubleword; vAddr = GPR[base] + sign_extend(offset, 16); if (bit(vAddr,0) != 0) { SignalException(AddressError); } doubleword = LoadMemory(vAddr, HALFWORD); GPR[rt] = sign_extend(doubleword,16); /* LHU Load Halfword Unsigned */ 100101 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset, 16); if (bit(vAddr,0) != 0) { SignalException(AddressError); } GPR[rt] = LoadMemory(vAddr, HALFWORD); /* LL Load Linked Word */ 110000 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset, 16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } GPR[rt] = LoadMemory(vAddr, WORD); LLbit = 1; /* LLD Load Linked Doubleword */ 110100 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset, 16); if (bits(vAddr,0,2) != 0) { SignalException(AddressError); } GPR[rt] = LoadMemory(vAddr, DOUBLEWORD); LLbit = 1; /* LUI Load Upper Immediate */ 001111 00000 rt(5) immediate(16): GPR[rt] = sign_extend(immediate, 16) << 16; /* LUXC1 Load Doubleword Indexed Unaligned to Floring Point */ 010011 base(5) index(5) 00000 fd(5) 000101: uint64_t vAddr; vAddr = (GPR[base]+GPR[index]) & ~(7LL); StoreFPR(fd, UNINTERPRETED_DOUBLEWORD, LoadMemory(vAddr, DOUBLEWORD)); /* LW Load Word */ 100011 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; vAddr = GPR[base] + sign_extend(offset, 16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } doubleword = LoadMemory(vAddr, WORD); GPR[rt] = sign_extend(doubleword,32); /* LWC1 Load Word to Floating Point */ 110001 base(5) ft(5) offset(16): uint64_t vAddr,doubleword; vAddr = GPR[base] + sign_extend(offset, 16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } doubleword = LoadMemory(vAddr, WORD); StoreFPR(ft, UNINTERPRETED_WORD, sign_extend(doubleword,32)); /* LWC2 Load Word to Coprocessor 2 */ 110010 base(5) rt(5) offset(16): SignalException(Unimplemented); /* LWL Load Word Left */ 100010 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; int byte; vAddr = GPR[base] + sign_extend(offset, 16); byte = WORD - bits(vAddr,0,1); doubleword = LoadMemory(vAddr, byte); doubleword = (bits(doubleword,0,31-8*byte) << (8*byte)) | bits(GPR[rt],0,8*byte); GPR[rt]=sign_extend(doubleword,32); /* LWR Load Word Right */ 100110 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; int byte,word; vAddr = GPR[base] + sign_extend(offset, 16); byte = bits(vAddr,0,1) + 1; doubleword = LoadMemory(vAddr & ~3, byte); doubleword = (bits(GPR[rt],8*byte,31) << (8*byte)) | bits(doubleword,0,8*byte); if (byte == WORD) sign_extend(doubleword,32); GPR[rt]=doubleword; /* LWU Load Word Unsigned */ 100111 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset,16); GPR[rt] = LoadMemory(vAddr, WORD); /* LWXC1 Load Word Indexed to Floating Point */ 010011 base(5) index(5) 00000 fd(5) 000000: uint64_t vAddr,doubleword; vAddr = GPR[base] + GPR[index]; doubleword = LoadMemory(vAddr, WORD); StoreFPR(fd, UNINTERPRETED_DOUBLEWORD, sign_extend(doubleword, 32)); /* MADD Multiply and Add Word to Hi,Lo */ 011100 rs(5) rt(5) 00000 00000 000000: uint64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = (bits(HI,0,31) << 32) | bits(LO,0,31); temp += mult32(bits(GPR[rs],0,31),bits(GPR[rt],0,31)); HI = sign_extend(bits(temp,32,63),32); LO = sign_extend(bits(temp,0,31),32); /* MADD.fmt Floating Point Multiply Add */ 010011 fr(5) ft(5) fs(5) fd(5) 100 fmt(3): uint64_t vfr,vfs,vft; vfr = ValueFPR(fr, fmt); vfs = ValueFPR(fs, fmt); vft = ValueFPR(ft, fmt); StoreFPR(fd, fmt, float_add(float_mult(vfs,vft),vfr)); /* MADDU Multiply and Add Unsigned Word to Hi,Lo */ 011100 rs(5) rt(5) 00000 00000 000001: uint64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = (bits(HI,0,31) << 32) | bits(LO,0,31); temp += umult64(bits(GPR[rs],0,31),bits(GPR[rt],0,31),&LO,&HI); HI = sign_extend(bits(temp,32,63), 32); LO = sign_extend(bits(temp,0,31), 32); /* MFC0 Move from Coprocessor 0 */ 010000 00000 rt(5) rd(5) 00000 000 sel(3): SignalException(Unimplemented); /* MFC1 Move from Coprocessor 1 */ 010001 00000 rt(5) fs(5) 00000 000000: uint64_t data; data = bits(ValueFPR(fs, UNINTERPRETED_WORD),0,31); GPR[rt] = sign_extend(data, 32); /* MFC2 Move from Coprocessor 2 */ 010010 00000 rt(5) Impl(16): SignalException(Unimplemented); /* MFHI Move from HI Register */ 000000 00000 00000 rd(5) 00000 010000: GPR[rd] = HI; /* MFLO Move From LO Register */ 000000 00000 00000 rd(5) 00000 010010: GPR[rd] = LO; /* MOV.fmt Floating Point Move */ 010001 fmt(5) 00000 fs(5) fd(5) 000110: StoreFPR(fd, fmt, ValueFPR(fs, fmt)); /* MOVF/T Move Conditional on Floating Point False/True */ 000000 rs(5) cc(3) 0 tf(1) rd(5) 00000 000001: if (FPConditionCode(cc) == tf) { GPR[rd] = GPR[rs]; } /* MOVF/T.fmt Floating Point Move Conditional on Floating Point False/True */ 010001 fmt(5) cc(3) 0 tf(1) fs(5) fd(5) 010001: SignalException(Unimplemented); /* if (fmt != PS) { if (FPConditionCode(cc) == 1) { StoreFPR(fd, fmt, ValueFPR(fs, fmt)); } } else { int mask=0; if (FPConditionCode(cc+0) == 1) { mask |= 0xF0; } if (FPConditionCode(cc+1) == 1) { mask |= 0x0F; } StoreFPR(fd, PS, ByteMerge(mask, fd, fs)); } */ /* MOVN Move Conditional on Not Zero */ 000000 rs(5) rt(5) rd(5) 00000 001011: if (GPR[rt] != 0) { GPR[rd] = GPR[rs]; } /* MOVN.fmt Floating Point Move Conditional on Not Zero */ 010001 fmt(5) rt(5) fs(5) fd(5) 010011: if (GPR[rt] != 0) { StoreFPR(fd, fmt, ValueFPR(fs, fmt)); } /* MOVZ Move Conditional on Zero */ 000000 rs(5) rt(5) rd(5) 00000 001010: if (GPR[rt] == 0) { GPR[rd] = GPR[rs]; } /* MOVZ.fmt Floating Point Move Conditional on Zero */ 010001 fmt(5) rt(5) fs(5) fd(5) 010010: if (GPR[rt] == 0) { StoreFPR(fd, fmt, ValueFPR(fs, fmt)); } /* MSUB Multiply and Subtract Word to Hi,Lo */ 011100 rs(5) rt(5) 00000 00000 000100: int64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = (bits(HI,0,31)<<32) | bits(LO,0,31); temp -= mult32(bits(GPR[rs],0,31),bits(GPR[rt],0,31)); HI = sign_extend(bits(temp,32,63),32); LO = sign_extend(bits(temp,0,31),32); /* MSUB.fmt Floating Point Multiply Subtract */ 010011 fr(5) ft(5) fs(5) fd(5) 101 fmt(3): float_t vfr,vft,vfs; vfr = ValueFPR(fr, fmt); vfs = ValueFPR(fs, fmt); vft = ValueFPR(ft, fmt); StoreFPR(fd, fmt, float_sub(float_mult(vfs,vft),vfr)); /* MSUBU Multiply and Subtract Word to Hi,Lo */ 011100 rs(5) rt(5) 00000 00000 000101: uint64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = (bits(HI,0,31)<<32) | bits(LO,0,31); temp -= umult32(bits(GPR[rs],0,31),bits(GPR[rt],0,31)); HI = sign_extend(bits(temp,32,63),32); LO = sign_extend(bits(temp,0,31),32); /* MTC0 Move to Coprocessor 0 */ 010000 00100 rt(5) rd(5) 00000 000 sel(3): SignalException(Unimplemented); /* MTC1 Move Word to Floating Point */ 010001 00100 rt(5) fs(5) 00000 000000: StoreFPR(fs, UNINTERPRETED_WORD, bits(GPR[rt],0,31)); /* MTC2 Move Word to Coprocessor 2 */ 010010 00100 rt(5) Impl(16): SignalException(Unimplemented); /* MTHI Move to HI Register */ 000000 rs(5) 00000 00000 00000 010001: HI = GPR[rs]; /* MTLO Move to LO Register */ 000000 rs(5) 00000 00000 00000 010011: LO = GPR[rs]; /* MUL Multiply Word to GPR */ 011100 rs(5) rt(5) rd(5) 00000 000010: int32_t temp; if (NotWordValue(GPR[rt]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = mult32(bits(GPR[rs],0,31), bits(GPR[rt],0,31)); GPR[rd] = sign_extend(temp,32); /* MUL.fmt Floating Point Multiply */ 010001 fmt(5) ft(5) fs(5) fd(5) 000010: StoreFPR(fd, fmt, float_mult(ValueFPR(fs, fmt), ValueFPR(ft, fmt))); /* MULT Multiply Word */ 000000 rs(5) rt(5) 00000 00000 011000: int64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = mult32(bits(GPR[rs],0,31), bits(GPR[rt],0,31)); LO = sign_extend(bits(temp,0,31),32); HI = sign_extend(bits(temp,32,63),32); /* MULTU Multiply Unsigned Word */ 000000 rs(5) rt(5) 00000 00000 011001: int64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = umult32(bits(GPR[rs],0,31), bits(GPR[rt],0,31)); LO = sign_extend(bits(temp,0,31),32); HI = sign_extend(bits(temp,32,63),32); /* NEG.fmt Floating Point Negate */ 010001 fmt(5) 00000 fs(5) fd(5) 000111: StoreFPR(fd, fmt, float_negate(ValueFPR(fs, fmt))); /* NMADD.fmt Floating Point Negative Multiply Add */ 010011 fr(5) ft(5) fs(5) fd(5) 110 fmt(3): float_t vfr,vfs,vft; vfr = ValueFPR(fr, fmt); vfs = ValueFPR(fs, fmt); vft = ValueFPR(ft, fmt); StoreFPR(fd, fmt, float_negate(float_add(vfr,float_mult(vfs,vft)))); /* NMSUB.fmt Floating Point Negative Multiply Subtract */ 010011 fr(5) ft(5) fs(5) fd(5) 111 fmt(3): float_t vfr,vfs,vft; vfr = ValueFPR(fr, fmt); vfs = ValueFPR(fs, fmt); vft = ValueFPR(ft, fmt); StoreFPR(fd, fmt, float_negate(float_sub(float_mult(vfs,vft),vfr))); /* NOP No operation */ 000000 00000 00000 00000 00000 000000: /* Do nothing */ /* NOR Not Or */ 000000 rs(5) rt(5) rd(5) 00000 100111: GPR[rd] = ~(GPR[rs] | GPR[rt]); /* OR Or */ 000000 rs(5) rt(5) rd(5) 00000 100101: GPR[rd] = GPR[rs] | GPR[rt]; /* ORI Or Immediate */ 001101 rs(5) rt(5) immediate(16): GPR[rt] = GPR[rs] | zero_extend(immediate,16); /* PLL.PS Pair Lower Lower */ 010001 10110 ft(5) fs(5) fd(5) 101100: StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),0,31) << 32) | bits(ValueFPR(ft, PS),0,31)); /* PLU.PS Pair Lower Upper */ 010001 10110 ft(5) fs(5) fd(5) 101101: StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),0,31) << 32) | bits(ValueFPR(ft, PS),32,63)); /* PREF Prefetch */ 110011 base(5) hint(5) offset(16): /* Do nothing */ /* PREFI Prefetch Indexed */ 010011 base(5) index(5) hint(5) 00000 001111: /* Do nothing */ /* PUL.PS Pair Upper Lower */ 010001 10110 ft(5) fs(5) fd(5) 101110: StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),32,63) << 32) | bits(ValueFPR(ft, PS),0,31)); /* PUU.PS Pair Upper Upper */ 010001 10110 ft(5) fs(5) fd(5) 101111: StoreFPR(fd, PS, (bits(ValueFPR(fs, PS),32,63) << 32) | bits(ValueFPR(ft, PS),32,63)); /* RECIP.fmt Reciprocal Approximation */ 010001 fmt(5) 00000 fs(5) fd(5) 010101: StoreFPR(fd, fmt, float_recip(ValueFPR(fs, fmt))); /* ROUND.L.fmt Floating point Round */ 010001 fmt(5) 00000 fs(5) fd(5) 001000: StoreFPR(fd, L, ConvertFmt(ValueFPR(fd, fmt), fmt, L)); /* ROUND.W.fmt Floating point Round */ 010001 fmt(5) 00000 fs(5) fd(5) 001100: StoreFPR(fd, W, ConvertFmt(ValueFPR(fd, fmt), fmt, W)); /* RSQRT.fmt Reciprocal Square Root Approximation */ 010001 fmt(5) 00000 fs(5) fd(5) 010110: StoreFPR(fd, fmt, float_recip(float_sqr(ValueFPR(fs, fmt)))); /* SB Store Byte */ 101000 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset,16); StoreMemory(vAddr, BYTE, GPR[rt]); /* SC Store Conditional Word */ 111000 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset,16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } if (LLbit) { StoreMemory(vAddr, BYTE, GPR[rt]); } GPR[rt] = LLbit; /* SCD Store Conditional Doubleword */ 111100 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset,16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } if (LLbit) { StoreMemory(vAddr, DOUBLEWORD, GPR[rt]); } GPR[rt] = LLbit; /* SD Store Doubleword */ 111111 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; vAddr = GPR[base] + sign_extend(offset,16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } doubleword = GPR[rt]; StoreMemory(vAddr, DOUBLEWORD, doubleword); /* SDBBP Software Debug Breakpoint */ 011100 code(20) 111111: if (Debug.DM == 0) { SignalDebugBreakpointException(); } else { SignalDebugModeBreakpointException(); } /* SDC1 Store Doubleword from Floating Point */ 111101 base(5) ft(5) offset(16): uint64_t vAddr,doubleword; vAddr = GPR[base] + sign_extend(offset,16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } doubleword = ValueFPR(ft, UNINTERPRETED_DOUBLEWORD); StoreMemory(vAddr, DOUBLEWORD, doubleword); /* SDC2 Store Doubleword from Coprocessor 2 */ 111110 base(5) rt(5) offset(16): SignalException(Unimplemented); /* SDL Store Doubleword Left */ 101100 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; int byte; vAddr = GPR[base] + sign_extend(offset,16); byte = bits(vAddr,0,2); doubleword = bits(GPR[rt],56-8*byte,63); StoreMemory(vAddr, DOUBLEWORD, doubleword); /* SDR Store Doubleword Right */ 101101 base(5) rt(5) offset(16): uint64_t vAddr,doubleword; int byte; vAddr = GPR[base] + sign_extend(offset,16); byte = bits(vAddr,0,2); doubleword = bits(GPR[rt],8*byte,63) << (8*byte); StoreMemory(vAddr, DOUBLEWORD, doubleword); /* SDXC1 Store Doubleword Indexed from Floating Point */ 010011 base(5) index(5) fs(5) 00000 001001: uint64_t vAddr,doubleword; vAddr = GPR[base] + GPR[index]; if (bits(vAddr,0,2) != 0) { SignalException(AddressError); } doubleword = ValueFPR(fs, UNINTERPRETED_DOUBLEWORD); StoreMemory(vAddr, DOUBLEWORD, doubleword); /* SH Store Halfword */ 101001 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset,16); if (bit(vAddr,0) != 0) { SignalException(AddressError); } StoreMemory(vAddr, HALFWORD, GPR[rt]); /* SLL Shift Word Left Logical */ 000000 00000 rt(5) rd(5) sa(5) 000000: GPR[rd] = sign_extend(GPR[rt] << sa,32); /* SLLV Shift Word Left Logical Variable */ 000000 rs(5) rt(5) rd(5) 00000 000100: GPR[rd] = sign_extend(GPR[rt] << bits(GPR[rs],0,4),32); /* SLT Set on Less Than */ 000000 rs(5) rt(5) rd(5) 00000 101010: if ((int64_t)GPR[rs] < (int64_t)GPR[rt]) { GPR[rd] = 1; } else { GPR[rd] = 0; } /* SLTI Set on Less Than Immediate */ 001010 rs(5) rt(5) immediate(16): if ((int64_t)GPR[rs] < (int64_t)sign_extend(immediate, 16) ) { GPR[rt] = 1; } else { GPR[rt] = 0; } /* SLTIU Set on Less Than Immediate Unsigned */ 001011 rs(5) rt(5) immediate(16): if (GPR[rs] < sign_extend(immediate,16)) { GPR[rt] = 1; } else { GPR[rt] = 0; } /* SLTU Set on Less than Unsigned */ 000000 rs(5) rt(5) rd(5) 00000 101011: if (GPR[rs] < GPR[rt]) { GPR[rd] = 1; } else { GPR[rd] = 0; } /* SQRT.fmt Floating Point Square Root */ 010001 fmt(5) 00000 fs(5) fd(5) 000100: StoreFPR(fd, fmt, float_sqr(ValueFPR(fs, fmt))); /* SRA Shift Word Right Arithmetic */ 000000 00000 rt(5) rd(5) sa(5) 000011: uint64_t temp; if (NotWordValue(GPR[rt])) { UNPREDICTABLE; } GPR[rd] = sign_extend(GPR[rt] >> sa,32-sa); /* SRAV Shift Word Right Arithmetic Variable */ 000000 rs(5) rt(5) rd(5) 00000 000111: int sa; uint64_t temp; if (NotWordValue(GPR[rt])) { UNPREDICTABLE; } sa = bits(GPR[rs],0,4); GPR[rd] = sign_extend(GPR[rt] >> sa,32-sa); /* SRL Shift Word Right Logical */ 000000 00000 rt(5) rd(5) sa(5) 000010: if (NotWordValue(GPR[rt])) { UNPREDICTABLE; } GPR[rd] = zero_extend(GPR[rt] >> sa,32-sa); /* SRLV Shift Word Right Logical Variable */ 000000 rs(5) rt(5) rd(5) 00000 000110: int sa; if (NotWordValue(GPR[rt])) { UNPREDICTABLE; } sa = bits(GPR[rs],0,4); GPR[rd] = zero_extend(GPR[rt] >> sa,32-sa); /* SUB Subtract Word */ 000000 rs(5) rt(5) rd(5) 00000 100010: uint64_t temp; if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } temp = (bit(GPR[rs],31) << 32) | bits(GPR[rs],0,31); temp -= (bit(GPR[rt],31) << 32) | bits(GPR[rt],0,31); if (bit(temp,32) != bit(temp,31)) { SignalException(IntegerOverflow); } else { GPR[rd] = sign_extend(temp,32); } /* SUB.fmt Floating Point Subtract */ 010001 fmt(5) ft(5) fs(5) fd(5) 000001: StoreFPR(fd, fmt, float_sub(ValueFPR(fs, fmt), ValueFPR(ft, fmt))); /* SUBU Subtract Unsigned Word */ 000000 rs(5) rt(5) rd(5) 00000 100011: if (NotWordValue(GPR[rs]) || NotWordValue(GPR[rt])) { UNPREDICTABLE; } GPR[rd] = sign_extend((int32_t)GPR[rs] - (int32_t)GPR[rt], 32); /* SUXC1 Store Doubleword Indexed Unaligned from Floating Point */ 010011 base(5) index(5) fs(5) 00000 001101: uint64_t vAddr, doubleword; vAddr = bits(GPR[base] + GPR[index],3,63) << 3; doubleword = ValueFPR(fs, UNINTERPRETED_DOUBLEWORD); StoreMemory(vAddr, DOUBLEWORD, doubleword); /* SW Store Word */ 101011 base(5) rt(5) offset(16): uint64_t vAddr; vAddr = GPR[base] + sign_extend(offset, 16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } StoreMemory(vAddr, WORD, GPR[rt]); /* SWC1 Store Word from Floating Point */ 111001 base(5) ft(5) offset(16): uint64_t vAddr, doubleword; vAddr = GPR[base] + sign_extend(offset, 16); if (bits(vAddr,0,1) != 0) { SignalException(AddressError); } doubleword = ValueFPR(ft, UNINTERPRETED_WORD); StoreMemory(vAddr, WORD, doubleword); /* SWC2 Store Word from Coprocessor 2 */ 111010 base(5) rt(5) offset(16): SignalException(Unimplemented); /* SWL Store Word Left */ 101010 base(5) rt(5) offset(16): uint64_t vAddr; int byte; vAddr = GPR[base] + sign_extend(offset, 16); byte = WORD - bits(vAddr,0,1); StoreMemory(vAddr, byte, GPR[rt] >> (8*(WORD-byte))); /* SWR Store Word Right */ 101110 base(5) rt(5) offset(16): uint64_t vAddr; int byte; vAddr = GPR[base] + sign_extend(offset, 16); byte = bits(vAddr,0,1) + 1; StoreMemory(vAddr & ~3, byte, GPR[rt] >> (8*(WORD-byte))); /* SWXC1 Store Word Indexed from Floating Point */ 010011 base(5) index(5) fs(5) 00000 001000: uint64_t vAddr, doubleword; vAddr = GPR[base] + GPR[index]; if (bits(vAddr,0,2) != 0) { SignalException(AddressError); } doubleword = ValueFPR(fs, UNINTERPRETED_WORD); StoreMemory(vAddr, WORD, doubleword); /* SYNC Synchonize Shared Memory */ 000000 00000 00000 00000 stype(5) 001111: /* SyncOperation(stype); */ /* SYSCALL System Call */ 000000 code(20) 001100: SignalException(SystemCall); /* TEQ Trap if Equal */ 000000 rs(5) rt(5) code(10) 110100: if (GPR[rs] == GPR[rt]) { SignalException(Trap); } /* TEQI Trap if Equal Immediate */ 000001 rs(5) 01100 immediate(16): if (GPR[rs] == sign_extend(immediate, 16)) { SignalException(Trap); } /* TGE Trap if Greater or Equal */ 000000 rs(5) rt(5) code(10) 110000: if ((int64_t)GPR[rs] >= (int64_t)GPR[rt]) { SignalException(Trap); } /* TGEI Trap if Greater or Equal Immediate */ 000001 rs(5) 01000 immediate(16): if ((int64_t)GPR[rs] >= (int64_t)sign_extend(immediate, 16)) { SignalException(Trap); } /* TGEIU Trap if Greator or Equal Immediate Unsigned */ 000001 rs(5) 01001 immediate(16): if (GPR[rs] >= sign_extend(immediate, 16)) { SignalException(Trap); } /* TGEU Trap if Greater or Equal Unsigned */ 000000 rs(5) rt(5) code(10) 110001: if (GPR[rs] >= GPR[rt]) { SignalException(Trap); } /* TLBP Probe TLB for Matching Entry */ 010000 1 0000 00000 00000 00000 001000: SignalException(Unimplemented); /* TLBR Read Indexed TLB Entry */ 010000 1 0000 00000 00000 00000 000001: SignalException(Unimplemented); /* TLBWI Write Indexed TLB Entry */ 010000 1 0000 00000 00000 00000 000010: SignalException(Unimplemented); /* TLBWR Write Random TLB Entry */ 010000 1 0000 00000 00000 00000 000110: SignalException(Unimplemented); /* TLT Trap if Less Than */ 000000 rs(5) rt(5) code(10) 110010: if ((int64_t)GPR[rs] < (int64_t)GPR[rt]) { SignalException(Trap); } /* TLTI Trap if Less Than Immediate */ 000001 rs(5) 01010 immediate(16): if ((int64_t)GPR[rs] < (int64_t)sign_extend(immediate, 16)) { SignalException(Trap); } /* TLTIO Trap if Less Than Immediate Unsigned */ 000001 rs(5) 01011 immediate(16): if (GPR[rs] < sign_extend(immediate, 16)) { SignalException(Trap); } /* TLTU Trap if Less Than Unsigned */ 000000 rs(5) rt(5) code(10) 110011: if (GPR[rs] < GPR[rt]) { SignalException(Trap); } /* TNE Trap if Not Equal */ 000000 rs(5) rt(5) code(10) 110110: if (GPR[rs] != GPR[rt]) { SignalException(Trap); } /* TNEI Trap if Not Equal Immediate */ 000001 rs(5) 01110 immediate(16): if (GPR[rs] != sign_extend(immediate, 16)) { SignalException(Trap); } /* TRUNC.L.fmt Floating Point Truncate to Long Fixed Point */ 010001 fmt(5) 00000 fs(5) fd(5) 001001: StoreFPR(fd, L, ConvertFmt(ValueFPR(fs, fmt), fmt, L)); /* TRUNC.W.fmt Floating Point truncate to Word Fixed Point */ 010001 fmt(5) 00000 fs(5) fd(5) 001101: StoreFPR(fd, W, ConvertFmt(ValueFPR(fs, fmt), fmt, W)); /* WAIT Enter Standby Mode */ 010000 1 code(19) 100000: WaitForInterrupt(code); /* XOR Exclusive Or */ 000000 rs(5) rt(5) rd(5) 00000 100110: GPR[rd] = GPR[rs] ^ GPR[rt]; /* XORI Exclusive Or Immediate */ 001110 rs(5) rt(5) immediate(16): GPR[rt] = GPR[rs] ^ zero_extend(immediate, 16); /* ADD.fmt Add Float * This is at the end, because otherwise we miss some of the * "pull crud from FPU special registers" instructions. */ 010001 fmt(5) ft(5) fs(5) fd(5) 000000: StoreFPR(fd, fmt, float_add(ValueFPR(fs, fmt),ValueFPR(ft, fmt)));