diff options
-rw-r--r-- | sim/mips/.Sanitize | 1 | ||||
-rw-r--r-- | sim/mips/mips.dc | 7 | ||||
-rw-r--r-- | sim/mips/mips.igen | 9996 |
3 files changed, 10004 insertions, 0 deletions
diff --git a/sim/mips/.Sanitize b/sim/mips/.Sanitize index 21a7ecc..50460e0 100644 --- a/sim/mips/.Sanitize +++ b/sim/mips/.Sanitize @@ -40,6 +40,7 @@ tconfig.in Things-to-lose: mips.igen +mips.dc Do-last: diff --git a/sim/mips/mips.dc b/sim/mips/mips.dc new file mode 100644 index 0000000..c66a33d --- /dev/null +++ b/sim/mips/mips.dc @@ -0,0 +1,7 @@ +# Mips + +# Top level - create a very big switch statement. + + padded-switch,combine : 31 : 26 : : : : 0 : : + + diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen new file mode 100644 index 0000000..7e43a9a --- /dev/null +++ b/sim/mips/mips.igen @@ -0,0 +1,9996 @@ +// <insn> ::= +// <insn-word> { "+" <insn-word> } +// ":" <format-name> +// ":" <filter-flags> +// ":" <options> +// ":" <name> +// <nl> +// { <insn-model> } +// { <insn-mnemonic> } +// <code-block> +// + + +// IGEN config - mips16 +:option:16:insn-bit-size:16 +:option:16:hi-bit-nr:15 +:option:16:insn-specifying-widths:true + +// IGEN config - mipsI.. +:option:32:insn-bit-size:32 +:option:32:hi-bit-nr:31 +:option:32:insn-specifying-widths:true + + + +// Models known by this simulator +:model::mipsI:mipsI: +:model::mipsII:mipsII: +:model::mipsIII:mipsIII: +:model::mipsIV:mipsIV: +:model::mips16:mips16: +// start-sanitize-r5900 +:model::r5900:r5900: +// end-sanitize-r5900 +:model::r3900:r3900: +// start-sanitize-tx19 +:model::tx19:tx19: +// end-sanitize-tx19 + + + +// Pseudo instructions known by IGEN +:internal:::illegal +{ + sim_io_eprintf (SD, "Illegal instruction at address 0x%lx\n", + (unsigned long) cia); + sim_engine_halt (SD, CPU, NULL, cia, sim_signalled, SIGILL); +} + + + + +// +// MIPS Architecture: +// +// CPU Instruction Set (mipsI - mipsIV) +// + + +000000,5.RS,5.RT,5.RD,00000,100000:SPECIAL:32::ADD +"add r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + ALU32_BEGIN (GPR (RS)); + ALU32_ADD (GPR (RT)); + ALU32_END (GPR (RD)); +} + + +001000,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDI +"addi r<RT>, r<RS>, IMMEDIATE" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + ALU32_BEGIN (GPR (RS)); + ALU32_ADD (EXTEND16 (IMMEDIATE)); + ALU32_END (GPR (RT)); +} + + +001001,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ADDIU +"add r<RT>, r<RS>, IMMEDIATE" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + signed32 temp = GPR (RS) + EXTEND16 (IMMEDIATE); + GPR (RT) = EXTEND32 (temp); +} + + +000000,5.RS,5.RT,5.RD,00000,100001:SPECIAL:32::ADDU +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + signed32 temp = GPR (RS) + GPR (RT); + GPR (RD) = EXTEND32 (temp); +} + + +000000,5.RS,5.RT,5.RD,00000,100100:SPECIAL:32::AND +"and r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = GPR (RS) & GPR (RT); +} + + +001100,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ANDI +"and r<RT>, r<RS>, IMMEDIATE" +*mipsI: +*mipsII: +*mipsIII: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RT) = GPR (RS) & IMMEDIATE; +} + + +000100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQ +"beq r<RS>, r<RT>, OFFSET" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) == GPR (RT)) + { + DSPC = (PC + offset); + DELAYSLOT (); + } +} + + +010100,5.RS,5.RT,16.OFFSET:NORMAL:32::BEQL +"beql r<RS>, r<RT>, <OFFSET>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) == GPR (RT)) + { + DSPC = (PC + offset); + DELAYSLOT (); + } + else + NULLIFY(); +} + + +000001,5.RS,00001,16.OFFSET:REGIMM:32::BGEZ +"bgez r<RS>, <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) >= 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } +} + + +000001,5.RS!31,10001,16.OFFSET:REGIMM:32::BGEZAL +"bgezal r<RS>, <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + LR = (CIA + 8); + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) >= 0) + { + DSPC = (PC + offset); + DELAYSLOT(); + } +} + + +000001,5.RS!31,10011,16.OFFSET:REGIMM:32::BGEZALL +"bgezall r<RS>, <OFFSET>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + LR = (CIA + 8); + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) >= 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } + else + NULLIFY (); +} + + +000001,5.RS,00011,16.OFFSET:REGIMM:32::BGEZL +"bgezl r<RS>, <OFFSET>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) >= 0) + { + DSPC = (PC + offset); + DELAYSLOT(); + } + else + NULLIFY (); +} + + +000111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZ +"bgtz r<RS>, <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) > 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } +} + + +010111,5.RS,00000,16.OFFSET:NORMAL:32::BGTZL +"bgtzl r<RS>, <OFFSET>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) > 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } + else + NULLIFY (); +} + + +000110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZ +"blez r<RS>, <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) <= 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } +} + + +010110,5.RS,00000,16.OFFSET:NORMAL:32::BLEZL +"bgezl r<RS>, <OFFSET>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) <= 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } + else + NULLIFY (); +} + + +000001,5.RS,00000,16.OFFSET:REGIMM:32::BLTZ +"bltz r<RS>, <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) < 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } +} + + +000001,5.RS!31,10000,16.OFFSET:REGIMM:32::BLTZAL +"bltzal r<RS>, <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + LR = (CIA + 8); + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) < 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } +} + + +000001,5.RS!31,10010,16.OFFSET:REGIMM:32::BLTZALL +"bltzall r<RS>, <OFFSET>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + LR = (CIA + 8); + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) < 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } + else + NULLIFY (); +} + + +000001,5.RS,00010,16.OFFSET:REGIMM:32::BLTZL +"bltzl r<RS>, <OFFSET>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) < 0) + { + DSPC = (PC + offset); + DELAYSLOT (); + } + else + NULLIFY (); +} + + +000101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNE +"bne r<RS>, r<RT>, <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) != GPR (RT)) + { + DSPC = (PC + offset); + DELAYSLOT (); + } +} + + +010101,5.RS,5.RT,16.OFFSET:NORMAL:32::BNEL +"bnel r<RS>, r<RT>, <OFFSET>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The branch occurs AFTER the next instruction has been + executed */ + if (GPR (RS) != GPR (RT)) + { + DSPC = (PC + offset); + DELAYSLOT (); + } + else + NULLIFY (); +} + + +000000,********************,001101:SPECIAL:32::BREAK +"break" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + SignalException (BreakPoint, instruction_0); +} + + +0100,ZZ!1!3,26.COP_FUN:NORMAL:32::COP0 +"cop<ZZ> <COP_FUN>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + decode_coproc (SD_, ZZ, COP_FUN); +} + + +000000,5.RS,5.RT,5.RD,00000,101100:SPECIAL:64::DADD +"dadd r<RD>, r<RS>, r<RT>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + ALU64_START (GPR (RS)); + ALU64_ADD (GPR (RT)); + ALU64_RESULT (GPR (RT)); +} + + +011000,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDI +"daddi r<RT>, r<RS>, <IMMEDIATE>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + ALU64_START (GPR (RS)); + ALU64_ADD (EXTEND16 (IMMEDIATE)); + ALU64_RESULT (GPR (RT)); +} + + +011001,5.RS,5.RT,16.IMMEDIATE:NORMAL:64::DADDIU +"daddu r<RT>, r<RS>, <IMMEDIATE>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RT) = GPR (RS) + EXTEND16 (immediate); +} + + +000000,5.RS,5.RT,5.RD,00000,101101:SPECIAL:64::DADDU +"daddu r<RD>, r<RS>, r<RT>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = GPR (RS) + GPR (RT); +} + + +000000,5.RS,5.RT,0000000000011110:SPECIAL:64::DDIV +"ddiv r<RS>, r<RT>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + CHECKHILO ("Division"); + { + signed64 n = GPR (RS); + signed64 d = GPR (RT); + if (d == 0) + { + LO = SIGNED64 (0x8000000000000000); + HI = 0; + } + else if (d == -1 && n == SIGNED64 (0x8000000000000000)) + { + LO = SIGNED64 (0x8000000000000000); + HI = 0; + } + else + { + LO = (n / d); + HI = (n % d); + } + } +} + + + +000000,5.RS,5.RT,0000000000,011111:SPECIAL:64::DDIVU +"ddivu r<RS>, r<RT>" +*mipsIII: +*mipsIV: +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + CHECKHILO ("Division"); + { + unsigned64 n = GPR (RS); + unsigned64 d = GPR (RT); + if (d == 0) + { + LO = SIGNED64 (0x8000000000000000); + HI = 0; + } + else + { + LO = (n / d); + HI = (n % d); + } + } +} + + +000000,5.RS,5.RT,0000000000011010:SPECIAL:32::DIV +"div r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + CHECKHILO("Division"); + { + signed32 n = GPR (RS); + signed32 d = GPR (RT); + if (d == 0) + { + LO = EXTEND32 (0x80000000); + HI = EXTEND32 (0); + } + else if (d == -1 && q == 0x80000000) + { + LO = EXTEND32 (0x80000000); + HI = EXTEND32 (0); + } + else + { + LO = EXTEND32 (n / d); + HI = EXTEND32 (n % d); + } + } +} + + +000000,5.RS,5.RT,0000000000011011:SPECIAL:32::DIVU +"divu r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + CHECKHILO ("Division"); + { + unsigned32 n = GPR (RS); + unsigned32 d = GPR (RT); + if (d == 0) + { + LO = EXTEND32 (0x80000000); + HI = EXTEND32 (0); + } + else + { + LO = EXTEND32 (n / d); + HI = EXTEND32 (n % d); + } + } +} + + +000000,5.RS,5.RT,0000000000011100:SPECIAL:64::DMULT +"dmult r<RS>, r<RT>" +*mipsIII: +*mipsIV: +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + CHECKHILO ("Multiplication"); + { + signed64 op1 = GPR (RS); + signed64 op2 = GPR (RT); + unsigned64 lo; + unsigned64 hi; + unsigned64 m00; + unsigned64 m01; + unsigned64 m10; + unsigned64 m11; + unsigned64 mid; + unsigned64 temp; + int sign = 0; + /* make it unsigned */ + if (op1 < 0) + { + op1 = - op1; + ++sign; + } + if (op2 < 0) + { + op2 = - op2; + ++sign; + } + /* multuply out the 4 sub products */ + m00 = (VL4_8 (op1) * VL4_8 (op2)); + m10 = (VH4_8 (op1) * VL4_8 (op2)); + m01 = (VL4_8 (op1) * VH4_8 (op2)); + m11 = (VH4_8 (op1) * VH4_8 (op2)); + /* add the products */ + mid = VH4_8 (m00) + VL4_8 (m10) + VL4_8 (m01); + lo = U8_4 (mid, m00); + hi = m11 + VH4_8 (mid) + VH4_8 (m01) + VH4_8 (m10); + /* save the result */ + if (sign & 1) + { + LO = -lo; + if (lo == 0) + HI = -hi; + else + HI = -hi - 1; + } + else + { + LO = lo; + HI = hi; + } + } +} + + +000000,5.RS,5.RT,0000000000011101:SPECIAL:64::DMULTU +"dmultu r<RS>, r<RT>" +*mipsIII: +*mipsIV: +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + CHECKHILO ("Multiplication"); + { + signed64 op1 = GPR (RS); + signed64 op2 = GPR (RT); + unsigned64 lo; + unsigned64 hi; + unsigned64 m00; + unsigned64 m01; + unsigned64 m10; + unsigned64 m11; + unsigned64 mid; + unsigned64 temp; + /* multuply out the 4 sub products */ + m00 = (VL4_8 (op1) * VL4_8 (op2)); + m10 = (VH4_8 (op1) * VL4_8 (op2)); + m01 = (VL4_8 (op1) * VH4_8 (op2)); + m11 = (VH4_8 (op1) * VH4_8 (op2)); + /* add the products */ + mid = VH4_8 (m00) + VL4_8 (m10) + VL4_8 (m01); + lo = U8_4 (mid, m00); + hi = m11 + VH4_8 (mid) + VH4_8 (m01) + VH4_8 (m10); + /* save the result */ + LO = lo; + HI = hi; + } +} + + +00000000000,5.RT,5.RD,5.SA,111000:SPECIAL:64::DSLL +"dsll r<RD>, r<RT>, <SA>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + s = SA; + GPR (RD) = GPR (RT) << s; +} + + +00000000000,5.RT,5.RD,5.SA,111100:SPECIAL:64::DSLL32 +"dsll32 r<RD>, r<RT>, <SA>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + s = 32 + SA; + GPR (RD) = GPR (RT) << s; +} + + +000000,5.RS,5.RT,5.RD,00000010100:SPECIAL:64::DSLLV +"dsllv r<RD>, r<RT>, r<RS>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + s = MASKED64 (GPR (RS), 5, 0); + GPR (RD) = GPR (RT) << s; +} + + +00000000000,5.RT,5.RD,5.SA,111011:SPECIAL:64::DSRA +"dsra r<RD>, r<RT>, <SA>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + s = SA; + GPR (RD) = ((signed64) GPR (RT)) >> s; +} + + +00000000000,5.RT,5.RD,5.SA,111111:SPECIAL:64::DSRA32 +"dsra32 r<RT>, r<RD>, <SA>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + s = 32 + SA; + GPR (RD) = ((signed64) GPR (RT)) >> s; +} + + +000000,5.RS,5.RT,5.RD,00000010111:SPECIAL:64::DSRAV +"dsra32 r<RT>, r<RD>, r<RS>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = MASKED64 (GPR (RS), 5, 0); + GPR (RD) = ((signed64) GPR (RT)) >> s; +} + + +00000000000,5.RT,5.RD,5.SA,111010:SPECIAL:64::DSRL +"dsrav r<RD>, r<RT>, <SA>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = SA; + GPR (RD) = (unsigned64) GPR (RT) >> s; +} + + +00000000000,5.RT,5.RD,5.SA,111110:SPECIAL:64::DSRL32 +"dsrl32 r<RD>, r<RT>, <SA>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = 32 + SA; + GPR (RD) = (unsigned64) GPR (RT) >> s; +} + + +000000,5.RS,5.RT,5.RD,00000010110:SPECIAL:64::DSRLV +"dsrl32 r<RD>, r<RT>, r<RS>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = MASKED64 (GPR (RS), 5, 0); + GPR (RD) = (unsigned64) GPR (RT) >> s; +} + + +000000,5.RS,5.RT,5.RD,00000101110:SPECIAL:64::DSUB +"dsub r<RD>, r<RS>, r<RT>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + ALU64_BEGIN (GPR (RS)); + ALU64_SUB (GPR (RT)); + ALU64_END (GPR (RD)); +} + + +000000,5.RS,5.RT,5.RD,00000101111:SPECIAL:64::DSUBU +"dsubu r<RD>, r<RS>, r<RT>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = GPR (RS) - GPR (RT); +} + + +000010,26.INSTR_INDEX:NORMAL:32::J +"j <INSTR_INDEX>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The region used is that of the delay slot and NOT the + current instruction */ + address_word region = NIA & MASK (63, 28); + DSPC = region | (INSTR_INDEX << 2); + DELAYSLOT (); + /* FIXME-WAS: ??? Gdb gets confused if the PC is sign-extended, so + we just truncate it to 32 bits here. -- DSPC = VL4_8 (DSPC); */ +} + + +000011,26.INSTR_INDEX:NORMAL:32::JAL +"jal <INSTR_INDEX>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + /* NOTE: The region used is that of the delay slot and NOT the + current instruction */ + address_word region = NIA & MASK (63, 28); + GPR (31) = CIA + 8; + DSPC = region | (INSTR_INDEX << 2); + DELAYSLOT (); + /* FIXME-WAS: ??? Gdb gets confused if the PC is sign-extended, so + we just truncate it to 32 bits here. -- DSPC = VL4_8 (DSPC); */ +} + + +000000,5.RS,00000,5.RD,00000001001:SPECIAL:32::JALR +"jalr r<RS>":RD == 31 +"jalr r<RD>, r<RS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + address_word temp = GPR (RS); + GPR (RD) = CIA + 8; + DSPC = temp; + DELAYSLOT (); + /* FIXME-WAS: ??? Gdb gets confused if the PC is sign-extended, so + we just truncate it to 32 bits here. -- DSPC = VL4_8 (DSPC); */ +} + + +000000,5.RS,000000000000000001000:SPECIAL:32::JR +"jr r<RS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + DSPC = GPR (RS); + DELAYSLOT (); + /* FIXME-WAS: ??? Gdb gets confused if the PC is sign-extended, so + we just truncate it to 32 bits here. -- DSPC = VL4_8 (DSPC); */ +} + + +100000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LB +"lb r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + uword64 vaddr = ((uword64)op1 + offset); + uword64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + uword64 memval = 0; + uword64 memval1 = 0; + uword64 mask = 0x7; + unsigned int shift = 0; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_BYTE,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0x000000FF),8)); + } + } + } +} + + +100100,5.BASE,5.RT,16.OFFSET:NORMAL:32::LBU +"lbu r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 0; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_BYTE,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (((memval >> (8 * byte)) & 0x000000FF)); + } + } + } +} + + +110111,5.BASE,5.RT,16.OFFSET:NORMAL:64::LD +"ld r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 4; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL); + GPR[destreg] = memval; + } + } + } +} + + +1101,ZZ,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDCz +"ldc<ZZ> r<RT>, <OFFSET>(r<BASE>)" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 4; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL); + COP_LD(((instruction >> 26) & 0x3),destreg,memval);; + } + } + } +} + + +011010,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDL +"ldl r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 7; + unsigned int reverse = (ReverseEndian ? mask : 0); + unsigned int bigend = (BigEndianCPU ? mask : 0); + int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); + byte = ((vaddr & mask) ^ bigend); + if (!!ByteSwapMem) + paddr &= ~mask; + LoadMemory(&memval,&memval1,uncached,byte,paddr,vaddr,isDATA,isREAL); + GPR[destreg] = ((memval << ((7 - byte) * 8)) | (GPR[destreg] & (((unsigned64)1 << ((7 - byte) * 8)) - 1))); + } + } + } +} + + +011011,5.BASE,5.RT,16.OFFSET:NORMAL:64::LDR +"ldr r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 7; + unsigned int reverse = (ReverseEndian ? mask : 0); + unsigned int bigend = (BigEndianCPU ? mask : 0); + int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); + byte = ((vaddr & mask) ^ bigend); + if (!ByteSwapMem) + paddr &= ~mask; + LoadMemory(&memval,&memval1,uncached,(7 - byte),paddr,vaddr,isDATA,isREAL); + { + unsigned64 srcmask; + if (byte == 0) + srcmask = 0; + else + srcmask = ((unsigned64)-1 << (8 * (8 - byte))); + GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte))); + } + } + } + } +} + + +100001,5.BASE,5.RT,16.OFFSET:NORMAL:32::LH +"lh r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 1) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 1; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_HALFWORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0x0000FFFF),16)); + } + } + } +} + + +100101,5.BASE,5.RT,16.OFFSET:NORMAL:32::LHU +"lhu r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 1) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 1; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_HALFWORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (((memval >> (8 * byte)) & 0x0000FFFF)); + } + } + } +} + + +110000,5.BASE,5.RT,16.OFFSET:NORMAL:32::LL +"ll r<RT>, <OFFSET>(r<BASE>)" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32)); + LLBIT = 1; + } + } + } +} + + +110100,5.BASE,5.RT,16.OFFSET:NORMAL:64::LLD +"lld r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 4; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL); + GPR[destreg] = memval; + LLBIT = 1; + } + } + } +} + + +001111,00000,5.RT,16.IMMEDIATE:NORMAL:32::LUI +"lui r<RT>, <IMMEDIATE>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg op2 UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + { + GPR[destreg] = (op2 << 16); + } +} + + +100011,5.BASE,5.RT,16.OFFSET:NORMAL:32::LW +"lw r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32)); + } + } + } +} + + +1100,ZZ,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWCz +"lwc<ZZ> r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + COP_LW(((instruction >> 26) & 0x3),destreg,(unsigned int)((memval >> (8 * byte)) & 0xFFFFFFFF)); + } + } + } +} + + +100010,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWL +"lwl r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 3; + unsigned int reverse = (ReverseEndian ? mask : 0); + unsigned int bigend = (BigEndianCPU ? mask : 0); + int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); + byte = ((vaddr & mask) ^ bigend); + if (!!ByteSwapMem) + paddr &= ~mask; + LoadMemory(&memval,&memval1,uncached,byte,paddr,vaddr,isDATA,isREAL); + if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) { + memval >>= 32; + } + GPR[destreg] = ((memval << ((3 - byte) * 8)) | (GPR[destreg] & (((unsigned64)1 << ((3 - byte) * 8)) - 1))); + GPR[destreg] = SIGNEXTEND(GPR[destreg],32); + } + } + } +} + + +100110,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWR +"lwr r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 3; + unsigned int reverse = (ReverseEndian ? mask : 0); + unsigned int bigend = (BigEndianCPU ? mask : 0); + int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); + byte = ((vaddr & mask) ^ bigend); + if (!ByteSwapMem) + paddr &= ~mask; + LoadMemory(&memval,&memval1,uncached,(3 - byte),paddr,vaddr,isDATA,isREAL); + if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) { + memval >>= 32; + } + { + unsigned64 srcmask; + if (byte == 0) + srcmask = 0; + else + srcmask = ((unsigned64)-1 << (8 * (4 - byte))); + GPR[destreg] = ((GPR[destreg] & srcmask) | (memval >> (8 * byte))); + } + GPR[destreg] = SIGNEXTEND(GPR[destreg],32); + } + } + } +} + + +100111,5.BASE,5.RT,16.OFFSET:NORMAL:32::LWU +"lwu r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (((memval >> (8 * byte)) & 0xFFFFFFFF)); + } + } + } +} + + +000000,0000000000,5.RD,00000,010000:SPECIAL:32::MFHI +"mfhi r<RD>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = HI; + HIACCESS = 3; +} + + +000000,0000000000,5.RD,00000,010010:SPECIAL:32::MFLO +"mflo r<RD>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = LO; + LOACCESS = 3; /* 3rd instruction will be safe */ +} + + +000000,5.RS,5.RT,5.RD,00000001011:SPECIAL:32::MOVN +"movn r<RD>, r<RS>, r<RT>" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + if (GPR (RT) != 0) + GPR (RD) = GPR (RS); +} + + +000000,5.RS,5.RT,5.RD,00000001010:SPECIAL:32::MOVZ +"movz r<RD>, r<RS>, r<RT>" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + if (GPR (RT) == 0) + GPR (RD) = GPR (RS); +} + + +000000,5.RS,000000000000000,010001:SPECIAL:32::MTHI +"mthi r<RS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (HIACCESS != 0) + sim_warning ("MT (move-to) over-writing HI register value"); + HI = GPR (RS); + HIACCESS = 3; /* 3rd instruction will be safe */ +} + + +000000,5.RS,000000000000000010011:SPECIAL:32::MTLO +"mtlo r<RS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (LOACCESS != 0) + sim_warning ("MT (move-to) over-writing LO register value"); + LO = GPR (RS); + LOACCESS = 3; /* 3rd instruction will be safe */ +} + + +000000,5.RS,5.RT,5.RD,00000011000:SPECIAL:32::MULT +"mult r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + signed64 prod; + CHECKHILO ("Multiplication"); + prod = (((signed64)(signed32) GPR (RS)) + * ((signed64)(signed32) GPR (RT))); + LO = EXTEND32 (VL4_8 (prod)); + HI = EXTEND32 (VH4_8 (prod)); +} + + +000000,5.RS,5.RT,5.RD,00000011001:SPECIAL:32::MULTU +"multu r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned64 prod; + CHECKHILO ("Multiplication"); + prod = (((unsigned64)(unsigned32) GPR (RS)) + * ((unsigned64)(unsigned32) GPR (RT))); + LO = EXTEND32 (VL4_8 (prod)); + HI = EXTEND32 (VH4_8 (prod)); +} + + +000000,5.RS,5.RT,5.RD,00000,100111:SPECIAL:32::NOR +"nor r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = ~ (GPR (RS) | GPR (RT)); +} + + +000000,5.RS,5.RT,5.RD,00000,100101:SPECIAL:32::OR +"or r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = (GPR (RS) | GPR (RT)); +} + + +001101,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::ORI +"ori r<RD>, r<RS>, <IMMEDIATE>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = (GPR (RS) | IMMEDIATE); +} + + +110011,5.RS,nnnnn,16.OFFSET:NORMAL:32::PREF +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int hint UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + Prefetch(uncached,paddr,vaddr,isDATA,hint); + } + } +} + +101000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SB +"sb r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 0; + unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + byte = ((vaddr & mask) ^ (bigend << shift)); + memval = ((unsigned64) op2 << (8 * byte)); + { + StoreMemory(uncached,AccessLength_BYTE,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +111000,5.BASE,5.RT,16.OFFSET:NORMAL:32::SC +"sc r<RT>, <OFFSET>(r<BASE>)" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); + byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); + memval = ((unsigned64) op2 << (8 * byte)); + if (LLBIT) + { + StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); + } + GPR[(instruction >> 16) & 0x0000001F] = LLBIT; + } + } + } +} + + +111100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SCD +"scd r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + memval = op2; + if (LLBIT) + { + StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL); + } + GPR[(instruction >> 16) & 0x0000001F] = LLBIT; + } + } + } +} + + +111111,5.BASE,5.RT,16.OFFSET:NORMAL:64::SD +"sd r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + memval = op2; + { + StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +1111,ZZ,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDCz +"sdc<ZZ> r<RT>, <OFFSET>(r<BASE>)" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + memval = (unsigned64)COP_SD(((instruction >> 26) & 0x3),destreg); + { + StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +101100,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDL +"sdl r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 7; + unsigned int reverse = (ReverseEndian ? mask : 0); + unsigned int bigend = (BigEndianCPU ? mask : 0); + int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); + byte = ((vaddr & mask) ^ bigend); + if (!!ByteSwapMem) + paddr &= ~mask; + memval = (op2 >> (8 * (7 - byte))); + StoreMemory(uncached,byte,memval,memval1,paddr,vaddr,isREAL); + } + } + } +} + + +101101,5.BASE,5.RT,16.OFFSET:NORMAL:64::SDR +"sdr r<RT>, <OFFSET>(r<BASE>)" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 7; + unsigned int reverse = (ReverseEndian ? mask : 0); + unsigned int bigend = (BigEndianCPU ? mask : 0); + int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); + byte = ((vaddr & mask) ^ bigend); + if (!ByteSwapMem) + paddr &= ~mask; + memval = ((unsigned64) op2 << (byte * 8)); + StoreMemory(uncached,(AccessLength_DOUBLEWORD - byte),memval,memval1,paddr,vaddr,isREAL); + } + } + } +} + + +101001,5.BASE,5.RT,16.OFFSET:NORMAL:32::SH +"sh r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 1) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 1; + unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + byte = ((vaddr & mask) ^ (bigend << shift)); + memval = ((unsigned64) op2 << (8 * byte)); + { + StoreMemory(uncached,AccessLength_HALFWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +00000000000,5.RT,5.RD,5.SA,000000:SPECIAL:32::SLL +"sll r<RD>, r<RT>, <SA>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = SA; + unsigned32 temp = (GPR (RT) << s); + GPR (RD) = EXTEND32 (temp); +} + + +000000,ooooo,5.RT,5.RD,00000000100:SPECIAL:32::SLLV +"sllv r<RD>, r<RT>, r<RS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = MASKED (GPR (RS), 4, 0); + unsigned32 temp = (GPR (RT) << s); + GPR (RD) = EXTEND32 (temp); +} + + +000000,5.RS,5.RT,5.RD,00000101010:SPECIAL:32::SLT +"slt r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) < GPR (RT)) + GPR (RD) = 1; + else + GPR (RD) = 0; +} + + +001010,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTI +"slti r<RD>, r<RS>, <IMMEDIATE>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) < EXTEND16 (IMMEDIATE)) + GPR (RD) = 1; + else + GPR (RD) = 0; +} + + +001011,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::SLTIU +"sltiu r<RD>, r<RS>, <IMMEDIATE>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if ((unsigned_word) GPR (RS) < (unsigned_word) EXTEND16 (IMMEDIATE)) + GPR (RD) = 1; + else + GPR (RD) = 0; +} + +000000,5.RS,5.RT,5.RD,00000101011:SPECIAL:32::SLTU +"sltu r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if ((unsigned_word) GPR (RS) < (unsigned_word) GPR (RT)) + GPR (RD) = 1; + else + GPR (RD) = 0; +} + + +000000,00000,5.RT,5.RD,5.SA,000011:SPECIAL:32::SRA +"sra r<RD>, r<RT>, <SA>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = SA; + signed32 temp = (signed32) GPR (RT) >> s; + GPR (RD) = EXTEND32 (temp); +} + + +000000,5.RS,5.RT,5.RD,00000000111:SPECIAL:32::SRAV +"srav r<RD>, r<RT>, r<RS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = MASKED (GPR (RS), 4, 0); + signed32 temp = (signed32) GPR (RT) >> s; + GPR (RD) = EXTEND32 (temp); +} + + +000000,00000,5.RT,5.RD,5.SA,000010:SPECIAL:32::SRL +"srl r<RD>, r<RT>, <SA>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = SA; + unsigned32 temp = (unsigned32) GPR (RT) >> s; + GPR (RD) = EXTEND32 (temp); +} + + +000000,5.RS,5.RT,5.RD,00000000110:SPECIAL:32::SRLV +"srlv r<RD>, r<RT>, r<RS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + int s = MASKED (GPR (RS), 4, 0); + unsigned32 temp = (unsigned32) GPR (RT) >> s; + GPR (RD) = EXTEND32 (temp); +} + + +000000,5.RS,5.RT,5.RD,00000100010:SPECIAL:32::SUB +"sub r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + ALU32_BEGIN (GPR (RS)); + ALU32_SUB (GPR (RT)); + ALU32_END (GPR (RD)); +} + + +000000,5.RS,5.RT,5.RD,00000100011:SPECIAL:32::SUBU +"subu r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = EXTEND32 (GPR (RS) - GPR (RT)); +} + + +101011,5.BASE,5.RT,16.OFFSET:NORMAL:32::SW +"sw r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); + byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); + memval = ((unsigned64) op2 << (8 * byte)); + { + StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +1110,ZZ,5.RS,5.RT,16.OFFSET:NORMAL:32::SWCz +"swc<ZZ> r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); + byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); + memval = (((unsigned64)COP_SW(((instruction >> 26) & 0x3),destreg)) << (8 * byte)); + { + StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +101010,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWL +"swl r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 3; + unsigned int reverse = (ReverseEndian ? mask : 0); + unsigned int bigend = (BigEndianCPU ? mask : 0); + int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); + byte = ((vaddr & mask) ^ bigend); + if (!!ByteSwapMem) + paddr &= ~mask; + memval = (op2 >> (8 * (3 - byte))); + if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) { + memval <<= 32; + } + StoreMemory(uncached,byte,memval,memval1,paddr,vaddr,isREAL); + } + } + } +} + + +101110,5.BASE,5.RT,16.OFFSET:NORMAL:32::SWR +"swr r<RT>, <OFFSET>(r<BASE>)" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 3; + unsigned int reverse = (ReverseEndian ? mask : 0); + unsigned int bigend = (BigEndianCPU ? mask : 0); + int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ reverse)); + byte = ((vaddr & mask) ^ bigend); + if (!ByteSwapMem) + paddr &= ~mask; + memval = ((unsigned64) op2 << (byte * 8)); + if ((vaddr & (1 << 2)) ^ (BigEndianCPU << 2)) { + memval <<= 32; + } + StoreMemory(uncached,(AccessLength_WORD - byte),memval,memval1,paddr,vaddr,isREAL); + } + } + } +} + + +000000000000000000000,5.STYPE,001111:SPECIAL:32::SYNC +"sync":STYPE == 0 +"sync <STYPE>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + SyncOperation (STYPE); +} + + +000000,20.CODE,001100:SPECIAL:32::SYSCALL +"syscall <CODE>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + SignalException (SystemCall, instruction_0); +} + + +000000,5.RS,5.RT,10.CODE,110100:SPECIAL:32::TEQ +"teq r<RS>, r<RT>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) == GPR (RT)) + SignalException (Trap, instruction_0); +} + + +000001,5.RS,01100,16.IMMEDIATE:REGIMM:32::TEQI +"teqi r<RS>, <IMMEDIATE>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) == EXTEND16 (IMMEDIATE)) + SignalException (Trap, instruction_0); +} + + +000000,5.RS,5.RT,10.CODE,110000:SPECIAL:32::TGE +"tge r<RS>, r<RT>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) >= GPR (RT)) + SignalException (Trap, instruction_0); +} + + +000001,5.RS,01000,16.IMMEDIATE:REGIMM:32::TGEI +"tgei r<RS>, <IMMEDIATE>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) >= EXTEND16 (IMMEDIATE)) + SignalException (Trap, instruction_0); +} + + +000001,5.RS,01001,16.IMMEDIATE:REGIMM:32::TGEIU +"tgeiu r<RS>, <IMMEDIATE>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if ((unsigned_word) GPR (RS) >= (unsigned_word) EXTEND16 (IMMEDIATE)) + SignalException (Trap, instruction_0); +} + + +000000,5.RS,5.RT,10.CODE,110001:SPECIAL:32::TGEU +"tgeu r<RS>, r<RT>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if ((unsigned_word) GPR (RS) >= (unsigned_word) GPR (RT)) + SignalException (Trap, instruction_0); +} + + +000000,5.RS,5.RT,10.CODE,110010:SPECIAL:32::TLT +"tlt r<RS>, r<RT>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) < GPR (RT)) + SignalException (Trap, instruction_0); +} + + +000001,5.RS,01010,16.IMMEDIATE:REGIMM:32::TLTI +"tlti r<RS>, <IMMEDIATE>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) < EXTEND16 (IMMEDIATE)) + SignalException (Trap, instruction_0); +} + + +000001,5.RS,01011,16.IMMEDIATE:REGIMM:32::TLTIU +"tltiu r<RS>, <IMMEDIATE>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if ((unsigned_word) GPR (RS) < (unsigned_word) EXTEND16 (IMMEDIATE)) + SignalException (Trap, instruction_0); +} + + +000000,5.RS,5.RT,10.CODE,110011:SPECIAL:32::TLTU +"tltu r<RS>, r<RT>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if ((unsigned_word) GPR (RS) < (unsigned_word) GPR (RT)) + SignalException (Trap, instruction_0); +} + + +000000,5.RS,5.RT,10.CODE,110110:SPECIAL:32::TNE +"tne r<RS>, r<RT>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) != GPR (RT)) + SignalException (Trap, instruction_0); +} + + +000001,5.RS,01110,16.IMMEDIATE:REGIMM:32::TNEI +"tne r<RS>, <IMMEDIATE>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + if (GPR (RS) != EXTEND16 (IMMEDIATE)) + SignalException (Trap, instruction_0); +} + + +000000,5.RS,5.RT,5.RD,00000100110:SPECIAL:32::XOR +"xor r<RD>, r<RS>, r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = GPR (RS) ^ GPR (RT); +} + + +001110,5.RS,5.RT,16.IMMEDIATE:NORMAL:32::XORI +"xori r<RD>, r<RS>, <IMMEDIATE>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + GPR (RD) = GPR (RS) ^ IMMEDIATE; +} + + +// +// MIPS Architecture: +// +// FPU Instruction Set (COP1 & COP1X) +// + + +010001,10,3.FMT,00000,5.FS,5.FD,000101:COP1:32,f::ABS.fmt +"abs.%s<FMT> f<FD>, f<FS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,AbsoluteValue(ValueFPR(fs,format),format)); + } +} + + +010001,10,3.FMT,kkkkk,5.FS,5.FD,000000:COP1:32,f::ADD +"add.%s<FMT> f<FD>, f<FS>, f<FT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,Add(ValueFPR(fs,format),ValueFPR(ft,format),format)); + } +} + + +// +// FIXME: This does not correctly resolve mipsI-mipsIV differences. +// +// BC1F +// BC1FL +// BC1T +// BC1TL +010001,01000,3.CC,1.N,1.DTF,16.OFFSET:COP1S:32,f::BC1 +"bc1%s<ND,TF> <OFFSET>":CC == 0 +"bc1%s<ND,TF> <CC>, <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)(((instruction >> 0) & 0x0000FFFF) << 2),18); + int boolean UNUSED = ((instruction >> 16) & 0x00000001); + int likely UNUSED = ((instruction >> 17) & 0x00000001); + int condition_code UNUSED = ((instruction >> 18) & 0x00000007); + { + if (condition_code != 0) + SignalException(ReservedInstruction,instruction); + else { + int condition = (PREVCOC1() == boolean); + /* NOTE: The branch occurs AFTER the next instruction has been executed */ + if (condition) { + DSPC = (PC + offset); + DELAYSLOT(); + } + else if (likely) { + NULLIFY(); + } + } + } +} + + +// +// FIXME: This does not correctly differentiate between mips* +// +010001,10,3.FMT,5.FT,5.FS,3.CC,00,11,4.COND:COP1:32::C.cond.fmt +"c.%s<COND>.%s<FMT> f<FS>, f<FT>":CC == 0 +"c.%s<COND>.%s<FMT> <CC>, f<FS>, f<FT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int cmpflags UNUSED = ((instruction >> 0) & 0x0000000F); + int condition_code UNUSED = ((instruction >> 8) & 0x00000007); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + if (condition_code != 0) + { + SignalException(ReservedInstruction,instruction); + } + else + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else { + if (condition_code != 0) + SignalException(ReservedInstruction,instruction); + else + { + int ignore = 0; + int less = 0; + int equal = 0; + int unordered = 1; + unsigned64 ofs = ValueFPR(fs,format); + unsigned64 oft = ValueFPR(ft,format); + if (NaN(ofs,format) || NaN(oft,format)) { + if (FCSR & FP_ENABLE(IO)) { + FCSR |= FP_CAUSE(IO); + SignalException(FPE); + ignore = 1; + } + } else { + less = Less(ofs,oft,format); + equal = Equal(ofs,oft,format); + unordered = 0; + } + if (!ignore) { + int condition = (((cmpflags & (1 << 2)) && less) || ((cmpflags & (1 << 1)) && equal) || ((cmpflags & (1 << 0)) && unordered)); + SETFCC(condition_code,condition); + } + } + } + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,001010:COP1:64::CEIL.L.fmt +"ceil.l.%s<FMT> f<FD>, f<FS>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_long,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_long)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,001110:COP1:32::CEIL.W +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_word,Convert(FP_RM_TOPINF,ValueFPR(fs,format),format,fmt_word)); + } +} + + +// CFC1 +// CTC1 +01000100,x,10,kkkkk,vvvvv,00000000000:COP1S:32::CxC1 +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int to UNUSED = ((instruction >> 23) & 0x00000001); + { + if (to) { + if (fs == 0) { + PENDING_FILL((fs + FCR0IDX),VL4_8(GPR[ft])); + } else if (fs == 31) { + PENDING_FILL((fs + FCR31IDX),VL4_8(GPR[ft])); + } /* else NOP */ + PENDING_FILL(COCIDX,0); /* special case */ + } else { /* control from */ + if (fs == 0) { + PENDING_FILL(ft,SIGNEXTEND(FCR0,32)); + } else if (fs == 31) { + PENDING_FILL(ft,SIGNEXTEND(FCR31,32)); + } /* else NOP */ + } + } +} + + +// +// FIXME: Does not correctly differentiate between mips* +// +010001,10,3.FMT,00000,5.FS,5.FD,100001:COP1:32::CVT.D.fmt +"cvt.d.%s<FMT> f<FD>, f<FS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format == fmt_double) | 0) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_double,Convert(GETRM(),ValueFPR(fs,format),format,fmt_double)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,100101:COP1:64::CVT.L.fmt +"cvt.l.%s<FMT> f<FD>, f<FS>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format == fmt_long) | ((format == fmt_long) || (format == fmt_word))) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_long,Convert(GETRM(),ValueFPR(fs,format),format,fmt_long)); + } +} + + +// +// FIXME: Does not correctly differentiate between mips* +// +010001,10,3.FMT,00000,5.FS,5.FD,100000:COP1:32::CVT.S.fmt +"cvt.s.%s<FMT> f<FD>, f<FS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format == fmt_single) | 0) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_single,Convert(GETRM(),ValueFPR(fs,format),format,fmt_single)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,100100:COP1:32::CVT.W.fmt +"cvt.w.%s<FMT> f<FD>, f<FS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format == fmt_word) | ((format == fmt_long) || (format == fmt_word))) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_word,Convert(GETRM(),ValueFPR(fs,format),format,fmt_word)); + } +} + + +010001,10,3.FMT,5.FT,5.FS,5.FD,000011:COP1:32::DIV.fmt +"div.%s<FMT> f<FD>, f<FS>, f<FT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,Divide(ValueFPR(fs,format),ValueFPR(ft,format),format)); + } +} + + +// DMFC1 +// DMTC1 +01000100,x,01,5.FT,vvvvv,00000000000:COP1S:64::DMxC1 +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int to UNUSED = ((instruction >> 23) & 0x00000001); + { + if (to) { + if (SizeFGR() == 64) { + PENDING_FILL((fs + FGRIDX),GPR[ft]); + } else + if ((fs & 0x1) == 0) + { + PENDING_FILL(((fs + 1) + FGRIDX),VH4_8(GPR[ft])); + PENDING_FILL((fs + FGRIDX),VL4_8(GPR[ft])); + } + } else { + if (SizeFGR() == 64) { + PENDING_FILL(ft,FGR[fs]); + } else + if ((fs & 0x1) == 0) { + PENDING_FILL(ft,(SET64HI(FGR[fs+1]) | FGR[fs])); + } else { + PENDING_FILL(ft,SET64HI(0xDEADC0DE) | 0xBAD0BAD0); + } + } + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,001011:COP1:64::FLOOR.L.fmt +"floor.l.%s<FMT> f<FD>, f<FS>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_long,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_long)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,001111:COP1:32::FLOOR.W.fmt +"floor.w.%s<FMT> f<FD>, f<FS>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_word,Convert(FP_RM_TOMINF,ValueFPR(fs,format),format,fmt_word)); + } +} + + +// LDC1 +110101,5.BASE,5.FT,16.OFFSET:COP1:32::LDC1 + + +010011,5.BASE,5.INDEX,5.0,5.FD,000001:COP1X:64::LDXC1 +"ldxc1 f<FD>, r<INDEX>(r<BASE>)" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + op2); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 4; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL); + COP_LD(1,destreg,memval);; + } + } + } +} + + +// LWC1 +110001,5.BASE,5.FT,16.OFFSET:COP1:32::LWC1 + + +010011,5.BASE,5.INDEX,5.0,5.FD,000000:COP1X:32::LWXC1 +"lwxc1 f<FD>, r<INDEX>(r<BASE>)" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + op2); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + COP_LW(1,destreg,(unsigned int)((memval >> (8 * byte)) & 0xFFFFFFFF)); + } + } + } +} + + + +// +// FIXME: Not correct for mips* +// +010011,5.FR,5.FT,5.FS,5.FD,100,001:COP1X:32::MADD.D +"madd.d f<FD>, f<FR>, f<FS>, f<FT>" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int fr UNUSED = ((instruction >> 21) & 0x0000001F); + { + StoreFPR(destreg,fmt_double,Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double)); + } +} + + +010011,5.FR,5.FT,5.FS,5.FD,100,000:COP1X:32::MADD.S +"madd.s f<FD>, f<FR>, f<FS>, f<FT>" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int fr UNUSED = ((instruction >> 21) & 0x0000001F); + { + StoreFPR(destreg,fmt_single,Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single)); + } +} + + +// MFC1 +010001,00,X,00,5.RT,5.FS,00000000000:COP1S:32::MxC1 +"mXc1 r<RT>, f<FS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int to UNUSED = ((instruction >> 23) & 0x00000001); + { + if (to) { + if (SizeFGR() == 64) { + PENDING_FILL((fs + FGRIDX),(SET64HI(0xDEADC0DE) | VL4_8(GPR[ft]))); + } else { + PENDING_FILL((fs + FGRIDX),VL4_8(GPR[ft])); + } + } else { + PENDING_FILL(ft,SIGNEXTEND(FGR[fs],32)); + } + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,000110:COP1:32::MOV.fmt +"mov.%s<FMT> f<FD>, f<FS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + StoreFPR(destreg,format,ValueFPR(fs,format)); + } +} + + +// MOVF +000000,5.RS,3.CC,0,1.TF,5.RD,00000000001:SPECIAL:32::MOVtf +"mov%s<TF> r<RD>, r<FS>, <CC>" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + int boolean UNUSED = ((instruction >> 16) & 0x00000001); + int condition_code UNUSED = ((instruction >> 18) & 0x00000007); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + if (GETFCC(condition_code) == boolean) + GPR[destreg] = op1; + } +} + + +// MOVF.fmt +010001,10,3.FMT,3.CC,0,1.TF,5.FS,5.FD,010001:COP1:32::MOVtf.fmt +"mov%s<TF>.%s<FMT> +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int boolean UNUSED = ((instruction >> 16) & 0x00000001); + int condition_code UNUSED = ((instruction >> 18) & 0x00000007); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if (GETFCC(condition_code) == boolean) + StoreFPR(destreg,format,ValueFPR(fs,format)); + else + StoreFPR(destreg,format,ValueFPR(destreg,format)); + } +} + + +010001,10,3.FMT,5.RT,5.FS,5.FD,010011:COP1:32::MOVN.fmt +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + StoreFPR(destreg,format,ValueFPR(fs,format)); + } +} + + +// MOVT see MOVtf + + +// MOVT.fmt see MOVtf.fmt + + + +010001,10,3.FMT,5.RT,5.FS,5.FD,010010:COP1:32::MOVZ.fmt +"movz.%s<FMT> f<FD>, f<FS>, r<RT>" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + StoreFPR(destreg,format,ValueFPR(fs,format)); + } +} + + +// MSUB.fmt +010011,5.FR,5.FT,5.FS,5.FD,101,001:COP1X:32::MSUB.D +"msub.d f<FD>, f<FR>, f<FS>, f<FT>" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int fr UNUSED = ((instruction >> 21) & 0x0000001F); + { + StoreFPR(destreg,fmt_double,(Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double)); + } +} + + +// MSUB.fmt +010011,bbbbb,5.FT,5.FS,5.FD,101000:COP1X:32::MSUB.S +"msub.s f<FD>, f<FR>, f<FS>, f<FT>" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int fr UNUSED = ((instruction >> 21) & 0x0000001F); + { + StoreFPR(destreg,fmt_single,(Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single)); + } +} + + +// MTC1 see MxC1 + + +010001,10,3.FMT,5.FT,5.FS,5.FD,000010:COP1:32::MUL.fmt +"mul.%s<FMT> f<FD>, f<FS>, f<FT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,Multiply(ValueFPR(fs,format),ValueFPR(ft,format),format)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,000111:COP1:32::NEG.fmt +"neg.%s<FMT> f<FD>, f<FS>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,Negate(ValueFPR(fs,format),format)); + } +} + + +// NMADD.fmt +010011,5.FR,5.FT,5.FS,5.FD,110001:COP1X:32::NMADD.D +"nmadd.d f<FD>, f<FR>, f<FS>, f<FT>" +*mipsIV: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int fr UNUSED = ((instruction >> 21) & 0x0000001F); + { + StoreFPR(destreg,fmt_double,Negate(Add(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double)); + } +} + + +// NMADD.fmt +010011,5.FR,5.FT,5.FS,5.FD,110000:COP1X:32::NMADD.S +"nmadd.s f<FD>, f<FR>, f<FS>, f<FT>" +*mipsIV: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int fr UNUSED = ((instruction >> 21) & 0x0000001F); + { + StoreFPR(destreg,fmt_single,Negate(Add(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single)); + } +} + + +// NMSUB.fmt +010011,bbbbb,5.FT,5.FS,5.FD,111001:COP1X:32::NMSUB.D +"nmsub.d f<FD>, f<FR>, f<FS>, f<FT>" +*mipsIV: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int fr UNUSED = ((instruction >> 21) & 0x0000001F); + { + StoreFPR(destreg,fmt_double,Negate(Sub(Multiply(ValueFPR(fs,fmt_double),ValueFPR(ft,fmt_double),fmt_double),ValueFPR(fr,fmt_double),fmt_double),fmt_double)); + } +} + + +// NMSUB.fmt +010011,bbbbb,5.FT,5.FS,5.FD,111000:COP1X:32::NMSUB.S +"nmsub.s f<FD>, f<FR>, f<FS>, f<FT>" +*mipsIV: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int fr UNUSED = ((instruction >> 21) & 0x0000001F); + { + StoreFPR(destreg,fmt_single,Negate(Sub(Multiply(ValueFPR(fs,fmt_single),ValueFPR(ft,fmt_single),fmt_single),ValueFPR(fr,fmt_single),fmt_single),fmt_single)); + } +} + + +010011,5.BASE,5.INDEX,5.HINT,00000001111:COP1X:32::PREFX +"prefx <HINT>, r<INDEX>(r<BASE)" +*mipsIV: +{ + unsigned32 instruction = instruction_0; + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + (unsigned64)op2); + unsigned64 paddr; + int uncached; + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + Prefetch(uncached,paddr,vaddr,isDATA,fs); + } +} + +010001,10,3.FMT,00000,5.FS,5.FD,010101:COP1:32::RECIP.fmt +*mipsIV: +"recip.%s<FMT> f<FD>, f<FS>" +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,Recip(ValueFPR(fs,format),format)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,001000:COP1:64::ROUND.L.fmt +"round.l.%S<FMT> f<FD>, f<FS>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_long,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_long)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,001100:COP1:32::ROUND.W.fmt +"round.w.%S<FMT> f<FD>, f<FS>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_word,Convert(FP_RM_NEAREST,ValueFPR(fs,format),format,fmt_word)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,010110:COP1:32::RSQRT.fmt +*mipsIV: +"rsqrt.%s<FMT> f<FD>, f<FS>" +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,Recip(SquareRoot(ValueFPR(fs,format),format))); + } +} + + +// SDC1 + + +010011,5.RS,5.RT,vvvvv,00000001001:COP1X:64::SDXC1 +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + op2); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + memval = (unsigned64)COP_SD(1,fs); + { + StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,000100:COP1:32::SQRT.fmt +"sqrt.%s<FMT> f<FD>, f<FS>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,(SquareRoot(ValueFPR(fs,format),format))); + } +} + + +010001,10,3.FMT,5.FT,5.FS,5.FD,000001:COP1:32::SUB.fmt +"sub.%s<FMT> f<FD>, f<FS>, f<FT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int ft UNUSED = ((instruction >> 16) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,format,Sub(ValueFPR(fs,format),ValueFPR(ft,format),format)); + } +} + + +// SWC1 + + +010011,5.BASE,5.INDEX,5.FS,00000,001000:COP1X:32::SWXC1 +"swxc1 f<FT>, r<OFFSET>(r<BASE>)" +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +{ + unsigned32 instruction = instruction_0; + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + op2); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); + byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); + memval = (((unsigned64)COP_SW(1,fs)) << (8 * byte)); + { + StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,001001:COP1:64::TRUNC.L.fmt +"trunc.l.%s<FMT> f<FD>, f<FS>" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_long,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_long)); + } +} + + +010001,10,3.FMT,00000,5.FS,5.FD,001101:COP1:32::TRUNC.W +"trunc.w.%s<FMT> f<FD>, f<FS>" +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 6) & 0x0000001F); + int fs UNUSED = ((instruction >> 11) & 0x0000001F); + int format UNUSED = ((instruction >> 21) & 0x00000007); + { + if ((format != fmt_single) && (format != fmt_double)) + SignalException(ReservedInstruction,instruction); + else + StoreFPR(destreg,fmt_word,Convert(FP_RM_TOZERO,ValueFPR(fs,format),format,fmt_word)); + } +} + + +// +// MIPS Architecture: +// +// System Control Instruction Set (COP0) +// + + +010000,01000,00000,16.OFFSET:COP0:32::BC0F +"bc0f <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,01000,00010,16.OFFSET:COP0:32::BC0FL +"bc0fl <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,01000,00001,16.OFFSET:COP0:32::BC0T +"bc0t <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + + +010000,01000,00001,16.OFFSET:COP0:32::BC0TL +"bc0tl <OFFSET>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +101111,5.BASE,5.OP,16.OFFSET:NORMAL:32::CACHE +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int hint UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = (op1 + offset); + unsigned64 paddr; + int uncached; + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + CacheOp(hint,vaddr,paddr,instruction); + } +} + + +010000,10000,000000000000000,111001:COP0:32::DI +"di" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,10000,000000000000000,111000:COP0:32::EI +"ei" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,10000,000000000000000,011000:COP0:32::ERET +"eret" +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11000,00000000000:COP0:32::MFBPC +"mfbpc r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11000,00000000000:COP0:32::MFC0 +"mfc0 r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11000,00000000100:COP0:32::MFDAB +"mfdab r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11000,00000000101:COP0:32::MFDABM +"mfdabm r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11000,00000000110:COP0:32::MFDVB +"mfdv r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11000,00000000111:COP0:32::MFDVBM +"mfdvm r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11000,00000000010:COP0:32::MFIAB +"mfiab r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11000,00000000011:COP0:32::MFIABM +"mfiabm r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11001,00000,5.REG,1:COP0:32::MFPC +"mfpc r<RT>, <REG>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00000,5.RT,11001,00000,5.REG,0:COP0:32::MFPS +"mfps r<RT>, <REG>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11000,00000000000:COP0:32::MTBPC +"mtbpc r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,5.RD,00000000000:COP0:32::MTC0 +"mtc0 r<RT>, r<RD>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11000,00000000100:COP0:32::MTDAB +"mtdab r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11000,00000000101:COP0:32::MTDABM +"mtdabm r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11000,00000000110:COP0:32::MTDVB +"mtdvb r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11000,00000000111:COP0:32::MTDVBM +"mtdvbm r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11000,00000000010:COP0:32::MTIAB +"mtiab r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11000,00000000011:COP0:32::MTIABM +"mtiabm r<RT>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11001,00000,5.REG,1:COP0:32::MTPC +"mtpc r<RT>, r<REG>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11001,00000,5.REG,0:COP0:32::MTPCM +"mtpcm r<RT>, r<REG>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,00100,5.RT,11001,00000,5.REG,0:COP0:32::MTPS +"mtps r<RT>, r<REG>" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,10000,000000000000000,001000:COP0:32::TLBP +"tlbp" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,10000,000000000000000,000001:COP0:32::TLBR +"tlbr" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,10000,000000000000000,000010:COP0:32::TLBWI +"tlbwi" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +010000,10000,000000000000000,000110:COP0:32::TLBWR +"tlbwr" +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 + + +// +// MIPS Architecture: +// +// CPU Instruction Set (mips16) +// + +// The instructions in this section are ordered according +// to http://www.sgi.com/MIPS/arch/MIPS16/mips16.pdf. + + +// Load and Store Instructions + + +10000,xxx,ddd,55555:RRI:16::LB +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 0; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_BYTE,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0x000000FF),8)); + } + } + } +} + + +10100,xxx,ddd,55555:RRI:16::LBU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 0; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_BYTE,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (((memval >> (8 * byte)) & 0x000000FF)); + } + } + } +} + + +10001,xxx,ddd,HHHHH:RRI:16::LH +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 1; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 1) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 1; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_HALFWORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0x0000FFFF),16)); + } + } + } +} + + +10101,xxx,ddd,HHHHH:RRI:16::LHU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 1; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 1) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 1; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_HALFWORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (((memval >> (8 * byte)) & 0x0000FFFF)); + } + } + } +} + + +10011,xxx,ddd,WWWWW:RRI:16::LW +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 2; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32)); + } + } + } +} + + +10110,ddd,VVVVVVVV,P:RI:16::LWPC +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + int offset = (instruction >> 0) & 0xff; + t_reg op1 = ((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (unsigned64) 1) & ~ (unsigned64) 0x3; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 2; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32)); + } + } + } +} + + +10010,ddd,VVVVVVVV,s:RI:16::LWSP +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + int offset = (instruction >> 0) & 0xff; + t_reg op1 = 29; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 2; + } + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (SIGNEXTEND(((memval >> (8 * byte)) & 0xFFFFFFFF),32)); + } + } + } +} + + +10111,xxx,ddd,WWWWW:RRI:16::LWU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 2; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 2; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + LoadMemory(&memval,&memval1,uncached,AccessLength_WORD,paddr,vaddr,isDATA,isREAL); + byte = ((vaddr & mask) ^ (bigend << shift)); + GPR[destreg] = (((memval >> (8 * byte)) & 0xFFFFFFFF)); + } + } + } +} + + +00111,xxx,ddd,DDDDD:RRI:16::LD +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 3; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 4; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL); + GPR[destreg] = memval; + } + } + } +} + + +11111100,ddd,5.RD,P:RI64:16::LDPC +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + t_reg op1 = ((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (unsigned64) 1) & ~ (unsigned64) 0x7; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 3; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 4; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL); + GPR[destreg] = memval; + } + } + } +} + + +11111000,ddd,5.RD,s:RI64:16::LDSP +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + t_reg op1 = 29; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 3; + } + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 4; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + LoadMemory(&memval,&memval1,uncached,AccessLength_DOUBLEWORD,paddr,vaddr,isDATA,isREAL); + GPR[destreg] = memval; + } + } + } +} + + +11000,xxx,yyy,55555:RRI:16::SB +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 0; + unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + byte = ((vaddr & mask) ^ (bigend << shift)); + memval = ((unsigned64) op2 << (8 * byte)); + { + StoreMemory(uncached,AccessLength_BYTE,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +11001,xxx,yyy,HHHHH:RRI:16::SH +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 1; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 1) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 1; + unsigned int reverse = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (reverse << shift))); + byte = ((vaddr & mask) ^ (bigend << shift)); + memval = ((unsigned64) op2 << (8 * byte)); + { + StoreMemory(uncached,AccessLength_HALFWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +11011,xxx,yyy,WWWWW:RRI:16::SW +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 2; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); + byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); + memval = ((unsigned64) op2 << (8 * byte)); + { + StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +11010,yyy,VVVVVVVV,s:RI:16::SWSP +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op2 = (instruction >> 8) & 0x7; + int offset = (instruction >> 0) & 0xff; + t_reg op1 = 29; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 2; + } + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); + byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); + memval = ((unsigned64) op2 << (8 * byte)); + { + StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +01100010,VVVVVVVV,Q,s:I8:16::SWRASP +*mips16: +{ + unsigned32 instruction = instruction_0; + int offset = (instruction >> 0) & 0xff; + t_reg op2 = 31; + t_reg op1 = 29; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 2; + } + op2 = GPR[op2]; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 3) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int byte; + paddr = ((paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2))); + byte = ((vaddr & mask) ^ (BigEndianCPU << 2)); + memval = ((unsigned64) op2 << (8 * byte)); + { + StoreMemory(uncached,AccessLength_WORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +01111,xxx,yyy,DDDDD:RRI:16::SD +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 3; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + memval = op2; + { + StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +11111001,yyy,5.RD,s:RI64:16::SDSP +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op2 = (instruction >> 5) & 0x7; + int offset = (instruction >> 0) & 0x1f; + t_reg op1 = 29; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 3; + } + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + memval = op2; + { + StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +11111010,CCCCCCCC,s,Q:I64:16::SDRASP +*mips16: +{ + unsigned32 instruction = instruction_0; + int offset = (instruction >> 0) & 0xff; + t_reg op1 = 29; + t_reg op2 = 31; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + offset <<= 3; + } + op1 = GPR[op1]; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 7) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + memval = op2; + { + StoreMemory(uncached,AccessLength_DOUBLEWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + + +// ALU Immediate Instructions + + +01101,ddd,UUUUUUUU,Z:RI:16::LI +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + int op2 = (instruction >> 0) & 0xff; + t_reg op1 = 0; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + have_extendval = 0; + } + else + { + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if (destreg != 0) + GPR[destreg] = (op1 | op2); + } +} + + +01000,xxx,ddd,04444:RRI_A:16::ADDIU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int op2 = (instruction >> 0) & 0xf; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + op2 |= ((extendval & 0xf) << 11) | (extendval & 0x7f0); + if (op2 >= 0x4000) + op2 -= 0x8000; + have_extendval = 0; + } + else + { + if (op2 >= 0x8) + op2 -= 0x10; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int temp = (unsigned int)(op1 + op2); + signed int tempS UNUSED = (signed int)temp; + GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32); + } +} + + +01001,www,kkkkkkkk:RI:16::ADDIU8 +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg; + int op2 = (instruction >> 0) & 0xff; + if (op1 < 2) + op1 += 16; + destreg = op1; + op1 = GPR[op1]; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + if (op2 >= 0x80) + op2 -= 0x100; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int temp = (unsigned int)(op1 + op2); + signed int tempS UNUSED = (signed int)temp; + GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32); + } +} + + +01100011,KKKKKKKK,S:I8:16::ADJSP +*mips16: +{ + unsigned32 instruction = instruction_0; + int op2 = (instruction >> 0) & 0xff; + t_reg op1 = 29; + int destreg; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + if (op2 >= 0x80) + op2 -= 0x100; + op2 <<= 3; + } + destreg = op1; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int temp = (unsigned int)(op1 + op2); + signed int tempS UNUSED = (signed int)temp; + GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32); + } +} + + +00001,ddd,AAAAAAAA,P:RI:16::ADDIUPC +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + int op2 = (instruction >> 0) & 0xff; + t_reg op1 = ((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (unsigned64) 1) & ~ (unsigned64) 0x3; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + op2 <<= 2; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int temp = (unsigned int)(op1 + op2); + signed int tempS UNUSED = (signed int)temp; + GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32); + } +} + + +00000,ddd,AAAAAAAA,s:RI:16::ADDIUSP +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + int op2 = (instruction >> 0) & 0xff; + t_reg op1 = 29; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + op2 <<= 2; + } + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int temp = (unsigned int)(op1 + op2); + signed int tempS UNUSED = (signed int)temp; + GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32); + } +} + + +01000,xxx,ddd,14444:RRI_A:16::DADDIU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = (instruction >> 5) & 0x7; + int op2 = (instruction >> 0) & 0xf; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + op2 |= ((extendval & 0xf) << 11) | (extendval & 0x7f0); + if (op2 >= 0x4000) + op2 -= 0x8000; + have_extendval = 0; + } + else + { + if (op2 >= 0x8) + op2 -= 0x10; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 temp = (unsigned64)(op1 + op2); + word64 tempS UNUSED = (word64)temp; + GPR[destreg] = (unsigned64)temp; + } +} + + +11111101,www,jjjjj:RI64:16::DADDIU5 +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 5) & 0x7; + int destreg; + int op2 = (instruction >> 0) & 0x1f; + if (op1 < 2) + op1 += 16; + destreg = op1; + op1 = GPR[op1]; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + if (op2 >= 0x10) + op2 -= 0x20; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 temp = (unsigned64)(op1 + op2); + word64 tempS UNUSED = (word64)temp; + GPR[destreg] = (unsigned64)temp; + } +} + + +11111011,KKKKKKKK,S:I64:16::DADJSP +*mips16: +{ + unsigned32 instruction = instruction_0; + int op2 = (instruction >> 0) & 0xff; + t_reg op1 = 29; + int destreg; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + if (op2 >= 0x80) + op2 -= 0x100; + op2 <<= 3; + } + destreg = op1; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 temp = (unsigned64)(op1 + op2); + word64 tempS UNUSED = (word64)temp; + GPR[destreg] = (unsigned64)temp; + } +} + + +11111110,ddd,EEEEE,P:RI64:16::DADDIUPC +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 5) & 0x7; + int op2 = (instruction >> 0) & 0x1f; + t_reg op1 = ((INDELAYSLOT () ? (INJALDELAYSLOT () ? IPC - 4 : IPC - 2) : (have_extendval ? IPC - 2 : IPC)) & ~ (unsigned64) 1) & ~ (unsigned64) 0x3; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + op2 <<= 2; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 temp = (unsigned64)(op1 + op2); + word64 tempS UNUSED = (word64)temp; + GPR[destreg] = (unsigned64)temp; + } +} + + +11111111,ddd,EEEEE,s:RI64:16::DADDIUSP +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 5) & 0x7; + int op2 = (instruction >> 0) & 0x1f; + t_reg op1 = 29; + if (destreg < 2) + destreg += 16; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + op2 <<= 2; + } + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 temp = (unsigned64)(op1 + op2); + word64 tempS UNUSED = (word64)temp; + GPR[destreg] = (unsigned64)temp; + } +} + + +01010,xxx,88888888,T:RI:16::SLTI +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int op2 = (instruction >> 0) & 0xff; + int destreg = 24; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if ((word64)op1 < (word64)op2) + GPR[destreg] = 1; + else + GPR[destreg] = 0; + } +} + + +01011,xxx,88888888,T:RI:16::SLTIU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int op2 = (instruction >> 0) & 0xff; + int destreg = 24; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (op2 >= 0x8000) + op2 -= 0x10000; + have_extendval = 0; + } + else + { + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if ((unsigned64)op1 < (unsigned64)op2) + GPR[destreg] = 1; + else + GPR[destreg] = 0; + } +} + + +11101,xxx,yyy,01010,T:RR:16::CMP +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg = 24; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = (op1 ^ op2); + } +} + + +01110,xxx,UUUUUUUU,T:RI:16::CMPI +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int op2 = (instruction >> 0) & 0xff; + int destreg = 24; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (have_extendval) + { + op2 |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + have_extendval = 0; + } + else + { + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = (op1 ^ op2); + } +} + + +// Two/Three Operand, Register-Type + + +11100,xxx,yyy,ddd,01:RRR:16::ADDU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg = (instruction >> 2) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int temp = (unsigned int)(op1 + op2); + signed int tempS UNUSED = (signed int)temp; + GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32); + } +} + + +11100,xxx,yyy,ddd,11:RRR:16::SUBU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg = (instruction >> 2) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int temp = (unsigned int)(op1 - op2); + signed int tempS UNUSED = (signed int)temp; + GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32); + } +} + + +11100,xxx,yyy,ddd,00:RRR:16::DADDU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg = (instruction >> 2) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 temp = (unsigned64)(op1 + op2); + word64 tempS UNUSED = (word64)temp; + GPR[destreg] = (unsigned64)temp; + } +} + + +11100,xxx,yyy,ddd,10:RRR:16::DSUBU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg = (instruction >> 2) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (destreg < 2) + destreg += 16; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 temp = (unsigned64)(op1 - op2); + word64 tempS UNUSED = (word64)temp; + GPR[destreg] = (unsigned64)temp; + } +} + + +11101,xxx,yyy,00010,T:RR:16::SLT +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg = 24; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if ((word64)op1 < (word64)op2) + GPR[destreg] = 1; + else + GPR[destreg] = 0; + } +} + + +11101,xxx,yyy,00011,T:RR:16::SLTU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg = 24; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if ((unsigned64)op1 < (unsigned64)op2) + GPR[destreg] = 1; + else + GPR[destreg] = 0; + } +} + + +11101,ddd,yyy,01011,Z:RR:16::NEG +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + t_reg op1 = 0; + if (destreg < 2) + destreg += 16; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int temp = (unsigned int)(op1 - op2); + signed int tempS UNUSED = (signed int)temp; + GPR[destreg] = SIGNEXTEND(((unsigned64)temp),32); + } +} + + +11101,www,yyy,01100:RR:16::AND +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + destreg = op1; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = (op1 & op2); + } +} + + +11101,www,yyy,01101:RR:16::OR +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + destreg = op1; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if (destreg != 0) + GPR[destreg] = (op1 | op2); + } +} + + +11101,www,yyy,01110:RR:16::XOR +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + destreg = op1; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = (op1 ^ op2); + } +} + + +11101,ddd,yyy,01111,Z:RR:16::NOT +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + t_reg op1 = 0; + if (destreg < 2) + destreg += 16; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if (destreg != 0) + GPR[destreg] = ~(op1 | op2); + } +} + + +01100111,ddd,XXXXX,z:I8_MOVR32:16::MOVR32 +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 5) & 0x7; + t_reg op1 = (instruction >> 0) & 0x1f; + t_reg op2 = 0; + if (destreg < 2) + destreg += 16; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if (destreg != 0) + GPR[destreg] = (op1 | op2); + } +} + + +01100101,YYYYY,xxx,z:I8_MOV32R:16::MOV32R +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 3) & 0x1f; + t_reg op1 = (instruction >> 0) & 0x7; + t_reg op2 = 0; + destreg = (destreg >> 2) | ((destreg & 3) << 3); + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + if (destreg != 0) + GPR[destreg] = (op1 | op2); + } +} + + +00110,ddd,yyy,sss,00:ISHIFT:16::SLL +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int op1 = (instruction >> 2) & 0x7; + if (destreg < 2) + destreg += 16; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + op1 = (extendval >> 6) & 0x1f; + have_extendval = 0; + } + else + { + if (op1 == 0) + op1 = 8; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = ((unsigned64)op2 << op1); + GPR[destreg] = SIGNEXTEND(GPR[destreg],32); + } +} + + +00110,ddd,yyy,sss,10:ISHIFT:16::SRL +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int op1 = (instruction >> 2) & 0x7; + if (destreg < 2) + destreg += 16; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + op1 = (extendval >> 6) & 0x1f; + have_extendval = 0; + } + else + { + if (op1 == 0) + op1 = 8; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = ((unsigned64)(op2 & 0xFFFFFFFF) >> op1); + GPR[destreg] = SIGNEXTEND(GPR[destreg],32); + } +} + + +00110,ddd,yyy,sss,11:ISHIFT:16::SRA +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int op1 = (instruction >> 2) & 0x7; + if (destreg < 2) + destreg += 16; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + op1 = (extendval >> 6) & 0x1f; + have_extendval = 0; + } + else + { + if (op1 == 0) + op1 = 8; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int highbit = (unsigned int)1 << 31; + GPR[destreg] = ((unsigned64)(op2 & 0xFFFFFFFF) >> op1); + GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((unsigned int)1 << op1) - 1) << (32 - op1)) : 0); + GPR[destreg] = SIGNEXTEND(GPR[destreg],32); + } +} + + +11101,xxx,vvv,00100:RR:16::SLLV +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + destreg = op2; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + op1 &= 0x1F; + GPR[destreg] = ((unsigned64)op2 << op1); + GPR[destreg] = SIGNEXTEND(GPR[destreg],32); + } +} + + +11101,xxx,vvv,00110:RR:16::SRLV +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + destreg = op2; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + op1 &= 0x1F; + GPR[destreg] = ((unsigned64)(op2 & 0xFFFFFFFF) >> op1); + GPR[destreg] = SIGNEXTEND(GPR[destreg],32); + } +} + + +11101,xxx,vvv,00111:RR:16::SRAV +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + destreg = op2; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned int highbit = (unsigned int)1 << 31; + op1 &= 0x1F; + GPR[destreg] = ((unsigned64)(op2 & 0xFFFFFFFF) >> op1); + GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((unsigned int)1 << op1) - 1) << (32 - op1)) : 0); + GPR[destreg] = SIGNEXTEND(GPR[destreg],32); + } +} + + +00110,ddd,yyy,[[[,01:ISHIFT:16::DSLL +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int op1 = (instruction >> 2) & 0x7; + if (destreg < 2) + destreg += 16; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + { + op1 = ((extendval >> 6) & 0x1f) | (extendval & 0x20); + have_extendval = 0; + } + else + { + if (op1 == 0) + op1 = 8; + } + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = ((unsigned64)op2 << op1); + } +} + + +11101,XXX,vvv,01000:RR:16::DSRL +*mips16: +{ + unsigned32 instruction = instruction_0; + int op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg; + if (have_extendval) + { + op1 = ((extendval >> 6) & 0x1f) | (extendval & 0x20); + have_extendval = 0; + } + else + { + if (op1 == 0) + op1 = 8; + } + if (op2 < 2) + op2 += 16; + destreg = op2; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = ((unsigned64)(op2) >> op1); + } +} + + +11101,xxx,vvv,10011:RR:16::DSRA +*mips16: +{ + unsigned32 instruction = instruction_0; + int op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg; + if (have_extendval) + { + op1 = ((extendval >> 6) & 0x1f) | (extendval & 0x20); + have_extendval = 0; + } + else + { + if (op1 == 0) + op1 = 8; + } + if (op2 < 2) + op2 += 16; + destreg = op2; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 highbit = (unsigned64)1 << 63; + GPR[destreg] = ((unsigned64)(op2) >> op1); + GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((unsigned64)1 << op1) - 1) << (64 - op1)) : 0); + } +} + + +11101,xxx,vvv,10100:RR:16::DSLLV +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + destreg = op2; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + op1 &= 0x3F; + GPR[destreg] = ((unsigned64)op2 << op1); + } +} + + +11101,xxx,vvv,10110:RR:16::DSRLV +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + destreg = op2; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + op1 &= 0x3F; + GPR[destreg] = ((unsigned64)(op2) >> op1); + } +} + + +11101,xxx,vvv,10111:RR:16::DSRAV +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + int destreg; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + destreg = op2; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + unsigned64 highbit = (unsigned64)1 << 63; + op1 &= 0x3F; + GPR[destreg] = ((unsigned64)(op2) >> op1); + GPR[destreg] |= (op1 != 0 && (op2 & highbit) ? ((((unsigned64)1 << op1) - 1) << (64 - op1)) : 0); + } +} + + +// Multiply /Divide Instructions + + +11101,xxx,yyy,11000:RR:16::MULT +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + CHECKHILO("Multiplication"); + { + unsigned64 temp = ((word64) op1 * (word64) op2); + LO = SIGNEXTEND((unsigned64)VL4_8(temp),32); + HI = SIGNEXTEND((unsigned64)VH4_8(temp),32); + } + } +} + + +11101,xxx,yyy,11001:RR:16::MULTU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + CHECKHILO("Multiplication"); + { + unsigned64 temp = ((unsigned64)(op1 & 0xffffffff) * (unsigned64)(op2 & 0xffffffff)); + LO = SIGNEXTEND((unsigned64)VL4_8(temp),32); + HI = SIGNEXTEND((unsigned64)VH4_8(temp),32); + } + } +} + + +11101,xxx,yyy,11010:RR:16::DIV +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + CHECKHILO("Division"); + { + int d1 = op1; + int d2 = op2; + if (d2 == 0) + { + LO = SIGNEXTEND(0x80000000,32); + HI = SIGNEXTEND(0,32); + } + else if (d2 == -1 && d1 == 0x80000000) + { + LO = SIGNEXTEND(0x80000000,32); + HI = SIGNEXTEND(0,32); + } + else + { + LO = SIGNEXTEND((d1 / d2),32); + HI = SIGNEXTEND((d1 % d2),32); + } + } + } +} + + +11101,xxx,yyy,11011:RR:16::DIVU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + CHECKHILO("Division"); + { + unsigned int d1 = op1; + unsigned int d2 = op2; + if (d2 == 0) + { + LO = SIGNEXTEND(0x80000000,32); + HI = SIGNEXTEND(0,32); + } + else if (d2 == -1 && d1 == 0x80000000) + { + LO = SIGNEXTEND(0x80000000,32); + HI = SIGNEXTEND(0,32); + } + else + { + LO = SIGNEXTEND((d1 / d2),32); + HI = SIGNEXTEND((d1 % d2),32); + } + } + } +} + + +11101,ddd,00010000:RR:16::MFHI +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + if (destreg < 2) + destreg += 16; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = HI; + HIACCESS = 3; /* 3rd instruction will be safe */ + } +} + + +11101,ddd,00010010:RR:16::MFLO +*mips16: +{ + unsigned32 instruction = instruction_0; + int destreg = (instruction >> 8) & 0x7; + if (destreg < 2) + destreg += 16; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = LO; + LOACCESS = 3; /* 3rd instruction will be safe */ + } +} + + +11101,xxx,yyy,11100:RR:16::DMULT +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + CHECKHILO("Multiplication"); + { + unsigned64 mid; + unsigned64 midhi; + unsigned64 temp; + int sign = 0; + if (op1 < 0) { op1 = - op1; ++sign; } + if (op2 < 0) { op2 = - op2; ++sign; } + LO = ((unsigned64)VL4_8(op1) * VL4_8(op2)); + HI = ((unsigned64)VH4_8(op1) * VH4_8(op2)); + mid = ((unsigned64)VH4_8(op1) * VL4_8(op2)); + midhi = SET64HI(VL4_8(mid)); + temp = (LO + midhi); + if ((temp == midhi) ? (LO != 0) : (temp < midhi)) + HI += 1; + HI += VH4_8(mid); + mid = ((unsigned64)VL4_8(op1) * VH4_8(op2)); + midhi = SET64HI(VL4_8(mid)); + LO = (temp + midhi); + if ((LO == midhi) ? (temp != 0) : (LO < midhi)) + HI += 1; + HI += VH4_8(mid); + if (sign & 1) { LO = - LO; HI = (LO == 0 ? 0 : -1) - HI; } + } + } +} + + +11101,xxx,yyy,11101:RR:16::DMULTU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + CHECKHILO("Multiplication"); + { + unsigned64 mid; + unsigned64 midhi; + unsigned64 temp; + LO = ((unsigned64)VL4_8(op1) * VL4_8(op2)); + HI = ((unsigned64)VH4_8(op1) * VH4_8(op2)); + mid = ((unsigned64)VH4_8(op1) * VL4_8(op2)); + midhi = SET64HI(VL4_8(mid)); + temp = (LO + midhi); + if ((temp == midhi) ? (LO != 0) : (temp < midhi)) + HI += 1; + HI += VH4_8(mid); + mid = ((unsigned64)VL4_8(op1) * VH4_8(op2)); + midhi = SET64HI(VL4_8(mid)); + LO = (temp + midhi); + if ((LO == midhi) ? (temp != 0) : (LO < midhi)) + HI += 1; + HI += VH4_8(mid); + } + } +} + + +11101,xxx,yyy,11110:RR:16::DDIV +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + CHECKHILO("Division"); + { + word64 d1 = op1; + word64 d2 = op2; + if (d2 == 0) + { + LO = SIGNED64 (0x8000000000000000); + HI = 0; + } + else if (d2 == -1 && d1 == SIGNED64 (0x8000000000000000)) + { + LO = SIGNED64 (0x8000000000000000); + HI = 0; + } + else + { + LO = (d1 / d2); + HI = (d1 % d2); + } + } + } +} + + +11101,xxx,yyy,11111:RR:16::DDIVU +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + t_reg op2 = (instruction >> 5) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (op2 < 2) + op2 += 16; + op2 = GPR[op2]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + CHECKHILO("Division"); + { + unsigned64 d1 = op1; + unsigned64 d2 = op2; + if (d2 == 0) + { + LO = SIGNED64 (0x8000000000000000); + HI = 0; + } + else if (d2 == -1 && d1 == SIGNED64 (0x8000000000000000)) + { + LO = SIGNED64 (0x8000000000000000); + HI = 0; + } + else + { + LO = (d1 / d2); + HI = (d1 % d2); + } + } + } +} + + +// Jump and Branch Instructions + + +// JALX +// JAL +00011,aaaaaaaaaaa:I:16::JAL +*mips16: +{ + unsigned32 instruction = instruction_0; + ut_reg op1 = (instruction >> 0) & 0x7ff; + { + unsigned64 paddr; + int uncached; + if (AddressTranslation (PC &~ (unsigned64) 1, isINSTRUCTION, isLOAD, &paddr, &uncached, isTARGET, isREAL)) + { + unsigned64 memval; + unsigned int reverse = (ReverseEndian ? 3 : 0); + unsigned int bigend = (BigEndianCPU ? 3 : 0); + unsigned int byte; + paddr = ((paddr & ~0x7) | ((paddr & 0x7) ^ (reverse << 1))); + LoadMemory (&memval,0,uncached, AccessLength_HALFWORD, paddr, PC, isINSTRUCTION, isREAL); + byte = (((PC &~ (unsigned64) 1) & 0x7) ^ (bigend << 1)); + memval = (memval >> (8 * byte)) & 0xffff; + op1 = (((op1 & 0x1f) << 23) + | ((op1 & 0x3e0) << 13) + | (memval << 2)); + if ((instruction & 0x400) == 0) + op1 |= 1; + PC += 2; + } + } + op1 |= PC & ~ (unsigned64) 0x0fffffff; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + int destreg = 31; + GPR[destreg] = (PC + 2); /* NOTE: The PC is already 2 ahead within the simulator */ + /* NOTE: ??? Gdb gets confused if the PC is sign-extended, + so we just truncate it to 32 bits here. */ + op1 = VL4_8(op1); + /* NOTE: The jump occurs AFTER the next instruction has been executed */ + DSPC = op1; + JALDELAYSLOT(); + } +} + + +11101,xxx,00000000:RR:16::JR +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + /* NOTE: ??? Gdb gets confused if the PC is sign-extended, + so we just truncate it to 32 bits here. */ + op1 = VL4_8(op1); + /* NOTE: The jump occurs AFTER the next instruction has been executed */ + DSPC = op1; + DELAYSLOT(); + } +} + + +1110100000100000,r:RR:16::JRRA +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = 31; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + /* NOTE: ??? Gdb gets confused if the PC is sign-extended, + so we just truncate it to 32 bits here. */ + op1 = VL4_8(op1); + /* NOTE: The jump occurs AFTER the next instruction has been executed */ + DSPC = op1; + DELAYSLOT(); + } +} + + +11101,xxx,01000000,R:RR:16::JALR +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int destreg = 31; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + GPR[destreg] = (PC + 2); /* NOTE: The PC is already 2 ahead within the simulator */ + /* NOTE: ??? Gdb gets confused if the PC is sign-extended, + so we just truncate it to 32 bits here. */ + op1 = VL4_8(op1); + /* NOTE: The jump occurs AFTER the next instruction has been executed */ + DSPC = op1; + DELAYSLOT(); + } +} + + +00100,xxx,pppppppp,z:RI:16::BEQZ +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int offset = (instruction >> 0) & 0xff; + t_reg op2 = 0; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + if (offset >= 0x80) + offset -= 0x100; + } + offset *= 2; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + int condition = (op1 == op2); + if (condition) + PC = PC + offset; + } +} + + +00101,xxx,pppppppp,z:RI:16::BNEZ +*mips16: +{ + unsigned32 instruction = instruction_0; + t_reg op1 = (instruction >> 8) & 0x7; + int offset = (instruction >> 0) & 0xff; + t_reg op2 = 0; + if (op1 < 2) + op1 += 16; + op1 = GPR[op1]; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + if (offset >= 0x80) + offset -= 0x100; + } + offset *= 2; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + int condition = (op1 != op2); + if (condition) + PC = PC + offset; + } +} + + +01100000,pppppppp,t,z:I8:16::BTEQZ +*mips16: +{ + unsigned32 instruction = instruction_0; + int offset = (instruction >> 0) & 0xff; + t_reg op1 = 24; + t_reg op2 = 0; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + if (offset >= 0x80) + offset -= 0x100; + } + offset *= 2; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + int condition = (op1 == op2); + if (condition) + PC = PC + offset; + } +} + + +01100001,pppppppp,t,z:I8:16::BTNEZ +*mips16: +{ + unsigned32 instruction = instruction_0; + int offset = (instruction >> 0) & 0xff; + t_reg op1 = 24; + t_reg op2 = 0; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + if (offset >= 0x80) + offset -= 0x100; + } + offset *= 2; + op1 = GPR[op1]; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + int condition = (op1 != op2); + if (condition) + PC = PC + offset; + } +} + + +00010,qqqqqqqqqqq,z,Z:I:16::B +*mips16: +{ + unsigned32 instruction = instruction_0; + int offset = (instruction >> 0) & 0x7ff; + t_reg op2 = 0; + t_reg op1 = 0; + if (have_extendval) + { + offset |= ((extendval & 0x1f) << 11) | (extendval & 0x7e0); + if (offset >= 0x8000) + offset -= 0x10000; + have_extendval = 0; + } + else + { + if (offset >= 0x400) + offset -= 0x800; + } + offset *= 2; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + int condition = (op1 == op2); + if (condition) + PC = PC + offset; + } +} + + +// Special Instructions + + +// See the front of the mips16 doc +11110,eeeeeeeeeee:I:16::EXTEND +*mips16: +{ + unsigned32 instruction = instruction_0; + int ext = (instruction >> 0) & 0x7ff; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + extendval = ext; + have_extendval = 1; + } +} + + +01100,******,00101:RR:16::BREAK +*mips16: +{ + unsigned32 instruction = instruction_0; + if (have_extendval) + SignalException (ReservedInstruction, instruction); + { + SignalException(BreakPoint,instruction); + } +} + + +// start-sanitize-r5900 + +// FIXME: The instructions below which are typically r5900 specific +// need to be merged back into the above. + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,0000000000011010:MMINORM:32::DIV1 +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + CHECKHILO("Division"); + { + int d1 = op1; + int d2 = op2; + if (d2 == 0) + { + LO1 = SIGNEXTEND(0x80000000,32); + HI1 = SIGNEXTEND(0,32); + } + else if (d2 == -1 && d1 == 0x80000000) + { + LO1 = SIGNEXTEND(0x80000000,32); + HI1 = SIGNEXTEND(0,32); + } + else + { + LO1 = SIGNEXTEND((d1 / d2),32); + HI1 = SIGNEXTEND((d1 % d2),32); + } + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,0000000000011011:MMINORM:32::DIVU1 +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + CHECKHILO("Division"); + { + unsigned int d1 = op1; + unsigned int d2 = op2; + if (d2 == 0) + { + LO1 = SIGNEXTEND(0x80000000,32); + HI1 = SIGNEXTEND(0,32); + } + else if (d2 == -1 && d1 == 0x80000000) + { + LO1 = SIGNEXTEND(0x80000000,32); + HI1 = SIGNEXTEND(0,32); + } + else + { + LO1 = SIGNEXTEND((d1 / d2),32); + HI1 = SIGNEXTEND((d1 % d2),32); + } + } + } +} + +// end-sanitize-r5900 + +000000,5.RS,5.RT,0000000000101001:SPECIAL:64::DMADD16 +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + CHECKHILO("Multiply-Add"); + { + unsigned64 temp = (op1 * op2); + LO = LO + temp; + } + } +} + + +011101,26.INSTR_INDEX:NORMAL:32::JALX +*mipsI: +*mipsII: +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + ut_reg op1 UNUSED = (((instruction >> 0) & 0x03FFFFFF) << 2); + op1 |= (PC & ~0x0FFFFFFF); /* address of instruction in delay slot for the jump */ + { + int destreg = 31; + GPR[destreg] = (PC + 4); /* NOTE: The PC is already 4 ahead within the simulator */ + op1 ^= 1; + /* NOTE: ??? Gdb gets confused if the PC is sign-extended, + so we just truncate it to 32 bits here. */ + op1 = VL4_8(op1); + /* NOTE: The jump occurs AFTER the next instruction has been executed */ + DSPC = op1; + JALDELAYSLOT(); + } +} + +// start-sanitize-r5900 + +011110,5.RS,5.RT,16.OFFSET:NORMAL:128::LQ +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + int destreg UNUSED = ((instruction >> 16) & 0x0000001F); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 15) != 0) + SignalException(AddressLoad); + else + { + if (AddressTranslation(vaddr,isDATA,isLOAD,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + unsigned64 mask = 0x7; + unsigned int shift = 8; + unsigned int reverse UNUSED = (ReverseEndian ? (mask >> shift) : 0); + unsigned int bigend UNUSED = (BigEndianCPU ? (mask >> shift) : 0); + unsigned int byte UNUSED; + LoadMemory(&memval,&memval1,uncached,AccessLength_QUADWORD,paddr,vaddr,isDATA,isREAL); + GPR[destreg] = memval; + GPR1[destreg] = memval1; + } + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000000000:MMINORM:32::MADD +*r5900: +*r3900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + word64 prod = (word64)WORD64(VL4_8(HI),VL4_8(LO)) + ((word64)SIGNEXTEND(op1,32) * (word64)SIGNEXTEND(op2,32)); + LO = SIGNEXTEND(prod,32); + HI = SIGNEXTEND( VH4_8(prod), 32); + if( destreg != 0 ) GPR[destreg] = LO; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000000001:MMINORM:32::MADDU +*r5900: +*r3900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 prod = (unsigned64)WORD64(VL4_8(HI),VL4_8(LO)) + ((unsigned64)VL4_8(op1) * (unsigned64)VL4_8(op2)); + LO = SIGNEXTEND(prod,32); + HI = SIGNEXTEND( VH4_8(prod), 32); + if( destreg != 0 ) GPR[destreg] = LO; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000100000:MMINORM:32::MADD1 +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + word64 prod = (word64)WORD64(VL4_8(HI1),VL4_8(LO1)) + ((word64)SIGNEXTEND(op1,32) * (word64)SIGNEXTEND(op2,32)); + LO1 = SIGNEXTEND(prod,32); + HI1 = SIGNEXTEND( VH4_8(prod), 32); + if( destreg != 0 ) GPR[destreg] = LO1; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000100001:MMINORM:32::MADDU1 +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 prod = (unsigned64)WORD64(VL4_8(HI1),VL4_8(LO1)) + ((unsigned64)VL4_8(op1) * (unsigned64)VL4_8(op2)); + LO1 = SIGNEXTEND(prod,32); + HI1 = SIGNEXTEND( VH4_8(prod), 32); + if( destreg != 0 ) GPR[destreg] = LO1; + } +} + +// end-sanitize-r5900 + +000000,5.RS,5.RT,0000000000101000:SPECIAL:32::MADD16 +*mipsIII: +*mipsIV: +// start-sanitize-r5900 +*r5900: +// end-sanitize-r5900 +*r3900: +// start-sanitize-tx19 +*tx19: +// end-sanitize-tx19 +{ + unsigned32 instruction = instruction_0; + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + CHECKHILO("Multiply-Add"); + { + unsigned64 temp = (op1 * op2); + temp += (SET64HI(VL4_8(HI)) | VL4_8(LO)); + LO = SIGNEXTEND((unsigned64)VL4_8(temp),32); + HI = SIGNEXTEND((unsigned64)VH4_8(temp),32); + } + } +} + +// start-sanitize-r5900 + +0111000000000000,5.RD,00000010000:MMINORM:32::MFHI1 +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + { + GPR[destreg] = HI1; + HI1ACCESS = 3; /* 3rd instruction will be safe */ + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +0111000000000000,5.RD,00000010010:MMINORM:32::MFLO1 +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + { + GPR[destreg] = LO1; + LO1ACCESS = 3; /* 3rd instruction will be safe */ + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +0000000000000000,5.RD,00000101000:SPECIAL:32::MFSA +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + { + GPR[destreg] = SA; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,000000000000000010001:MMINORM:32::MTHI1 +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + if (HI1ACCESS != 0) + sim_warning("MT (move-to) over-writing HI register value"); + HI1 = op1; + HI1ACCESS = 3; /* 3rd instruction will be safe */ + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,000000000000000010011:MMINORM:32::MTLO1 +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + if (LO1ACCESS != 0) + sim_warning("MT (move-to) over-writing LO register value"); + LO1 = op1; + LO1ACCESS = 3; /* 3rd instruction will be safe */ + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +000000,5.RS,000000000000000101001:SPECIAL:32::MTSA +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + SA = op1; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +000001,5.RS,11000,16.IMMEDIATE:REGIMM:32::MTSAB +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg op2 UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + SA = ((op1 & 0xF) ^ (op2 & 0xF)) * 8; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +000001,5.RS,11001,16.IMMEDIATE:REGIMM:32::MTSAH +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg op2 UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + SA = ((op1 & 0x7) ^ (op2 & 0x7)) * 16; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000011000:MMINORM:32::MULT1 +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + CHECKHILO("Multiplication"); + { + unsigned64 temp = ((word64) op1 * (word64) op2); + LO1 = SIGNEXTEND((unsigned64)VL4_8(temp),32); + HI1 = SIGNEXTEND((unsigned64)VH4_8(temp),32); + if ( destreg != 0 ) + GPR[destreg] = LO1; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000011001:MMINORM:32::MULTU1 +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + CHECKHILO("Multiplication"); + { + unsigned64 temp = ((unsigned64)(op1 & 0xffffffff) * (unsigned64)(op2 & 0xffffffff)); + LO1 = SIGNEXTEND((unsigned64)VL4_8(temp),32); + HI1 = SIGNEXTEND((unsigned64)VH4_8(temp),32); + if ( destreg != 0 ) + GPR[destreg] = LO1; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,00101101000:MMI1:32::PABSH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS;i++) + { + if (RT_SH(i) >= 0) + GPR_SH(destreg,i) = RT_SH(i); + else if (RT_SH(i) == -32768) + GPR_SH(destreg,i) = 32767; + else + GPR_SH(destreg,i) = -RT_SH(i); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,00001101000:MMI1:32::PABSW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + { + if (RT_SW(i) >= 0) + GPR_SW(destreg,i) = RT_SW(i); + else if (RT_SW(i) == (int)0x80000000) + GPR_SW(destreg,i) = (int)0x7FFFFFFF; + else + GPR_SW(destreg,i) = -RT_SW(i); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01000001000:MMI0:32::PADDB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < BYTES_IN_MMI_REGS; i++) + { + int s = RS_SB(i); + int t = RT_SB(i); + int r = s + t; + GPR_SB(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00100001000:MMI0:32::PADDH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < HALFWORDS_IN_MMI_REGS; i++) + { + int s = RS_SH(i); + int t = RT_SH(i); + int r = s + t; + GPR_SH(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000001000:MMI0:32::PADDW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < WORDS_IN_MMI_REGS; i++) + { + signed64 s = RS_SW(i); + signed64 t = RT_SW(i); + signed64 r = s + t; + GPR_SW(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11000001000:MMI0:32::PADDSB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < BYTES_IN_MMI_REGS; i++) + { + int s = RS_SB(i); + int t = RT_SB(i); + int r = s + t; + if (r > 127) + GPR_SB(destreg,i) = 127; + else if (r < -128) + GPR_SB(destreg,i) = -128; + else + GPR_SB(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10100001000:MMI0:32::PADDSH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < HALFWORDS_IN_MMI_REGS; i++) + { + int s = RS_SH(i); + int t = RT_SH(i); + int r = s + t; + if (r > 32767) + GPR_SH(destreg,i) = 32767; + else if (r < -32768) + GPR_SH(destreg,i) = -32768; + else + GPR_SH(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10000001000:MMI0:32::PADDSW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < WORDS_IN_MMI_REGS; i++) + { + signed64 s = RS_SW(i); + signed64 t = RT_SW(i); + signed64 r = s + t; + if (r > (int)0x7FFFFFFF) + GPR_SW(destreg,i) = (int)0x7FFFFFFF; + else if (r < (int)0x80000000) + GPR_SW(destreg,i) = (int)0x80000000; + else + GPR_SW(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11000101000:MMI1:32::PADDUB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < BYTES_IN_MMI_REGS; i++) + { + unsigned int s = RS_UB(i); + unsigned int t = RT_UB(i); + unsigned int r = s + t; + if (r > 0xFF) + GPR_UB(destreg,i) = 0xFF; + else + GPR_UB(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10100101000:MMI1:32::PADDUH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < HALFWORDS_IN_MMI_REGS; i++) + { + unsigned int s = RS_UH(i); + unsigned int t = RT_UH(i); + unsigned int r = s + t; + if (r > 0xFFFF) + GPR_UH(destreg,i) = 0xFFFF; + else + GPR_UH(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10000101000:MMI1:32::PADDUW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < WORDS_IN_MMI_REGS; i++) + { + unsigned64 s = RS_UW(i); + unsigned64 t = RT_UW(i); + unsigned64 r = s + t; + if (r > 0xFFFFFFFF) + GPR_UW(destreg,i) = 0xFFFFFFFF; + else + GPR_UW(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00100101000:MMI1:32::PADSBH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS/2;i++) + GPR_SH(destreg,i) = RS_SH(i) - RT_SH(i); + for(;i<HALFWORDS_IN_MMI_REGS;i++) + GPR_SH(destreg,i) = RS_SH(i) + RT_SH(i); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10010001001:MMI2:32::PAND +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + GPR_UW(destreg,i) = (RS_UW(i) & RT_UW(i)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01010101000:MMI1:32::PCEQB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<BYTES_IN_MMI_REGS;i++) + { + if (RS_SB(i) == RT_SB(i)) GPR_SB(destreg,i) = 0xFF; + else GPR_SB(destreg,i) = 0; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00110101000:MMI1:32::PCEQH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS;i++) + { + if (RS_SH(i) == RT_SH(i)) GPR_SH(destreg,i) = 0xFFFF; + else GPR_SH(destreg,i) = 0; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00010101000:MMI1:32::PCEQW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + { + if (RS_SW(i) == RT_SW(i)) GPR_SW(destreg,i) = 0xFFFFFFFF; + else GPR_SW(destreg,i) = 0; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01010001000:MMI0:32::PCGTB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<BYTES_IN_MMI_REGS;i++) + { + if (RS_SB(i) > RT_SB(i)) GPR_SB(destreg,i) = 0xFF; + else GPR_SB(destreg,i) = 0; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00110001000:MMI0:32::PCGTH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS;i++) + { + if (RS_SH(i) > RT_SH(i)) GPR_SH(destreg,i) = 0xFFFF; + else GPR_SH(destreg,i) = 0; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00010001000:MMI0:32::PCGTW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + { + if (RS_SW(i) > RT_SW(i)) GPR_SW(destreg,i) = 0xFFFFFFFF; + else GPR_SW(destreg,i) = 0; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11011101001:MMI3:32::PCPYH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + GPR_UH(destreg,7) = GPR_UH(destreg,6) = GPR_UH(destreg,5) = GPR_UH(destreg,4) = RT_UH(4); + GPR_UH(destreg,3) = GPR_UH(destreg,2) = GPR_UH(destreg,1) = GPR_UH(destreg,0) = RT_UH(0); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01110001001:MMI2:32::PCPYLD +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UD(destreg,0) = RT_UD(0); + GPR_UD(destreg,1) = RS_UD(0); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01110101001:MMI3:32::PCPYUD +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UD(destreg,0) = RS_UD(1); + GPR_UD(destreg,1) = RT_UD(1); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,0000011101001001:MMI2:32::PDIVBW +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + signed32 devisor = RT_SH(0); + if (devisor == -1) + { + LO_SW(0) = -RS_SW(0); + HI_SW(0) = 0; + LO_SW(1) = -RS_SW(1); + HI_SW(1) = 0; + LO_SW(2) = -RS_SW(2); + HI_SW(2) = 0; + LO_SW(3) = -RS_SW(3); + HI_SW(3) = 0; + } + else if (devisor != 0) + { + LO_SW(0) = RS_SW(0) / devisor; + HI_SW(0) = SIGNEXTEND( (RS_SW(0) % devisor), 16 ); + LO_SW(1) = RS_SW(1) / devisor; + HI_SW(1) = SIGNEXTEND( (RS_SW(1) % devisor), 16 ); + LO_SW(2) = RS_SW(2) / devisor; + HI_SW(2) = SIGNEXTEND( (RS_SW(2) % devisor), 16 ); + LO_SW(3) = RS_SW(3) / devisor; + HI_SW(3) = SIGNEXTEND( (RS_SW(3) % devisor), 16 ); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,0000001101101001:MMI3:32::PDIVUW +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + if (RT_UW(0) != 0) + { + LO = (signed32)(RS_UW(0) / RT_UW(0)); + HI = (signed32)(RS_UW(0) % RT_UW(0)); + } + if (RT_UW(2) != 0) + { + LO1 = (signed32)(RS_UW(2) / RT_UW(2)); + HI1 = (signed32)(RS_UW(2) % RT_UW(2)); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,0000001101001001:MMI2:32::PDIVW +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + if (RT_SW(0) == -1) + { + LO = -RS_SW(0); + HI = 0; + } + else if (RT_UW(0) != 0) + { + LO = (signed32)(RS_SW(0) / RT_SW(0)); + HI = (signed32)(RS_SW(0) % RT_SW(0)); + } + if (RT_SW(2) == -1) + { + LO1 = -RS_SW(2); + HI1 = 0; + } + else if (RT_UW(2) != 0) + { + LO1 = (signed32)(RS_SW(2) / RT_SW(2)); + HI1 = (signed32)(RS_SW(2) % RT_SW(2)); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11010101001:MMI3:32::PEXCH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + GPR_UH(destreg,0) = RT_UH(0); + GPR_UH(destreg,1) = RT_UH(2); + GPR_UH(destreg,2) = RT_UH(1); + GPR_UH(destreg,3) = RT_UH(3); + GPR_UH(destreg,4) = RT_UH(4); + GPR_UH(destreg,5) = RT_UH(6); + GPR_UH(destreg,6) = RT_UH(5); + GPR_UH(destreg,7) = RT_UH(7); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11110101001:MMI3:32::PEXCW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + GPR_UW(destreg,0) = RT_UW(0); + GPR_UW(destreg,1) = RT_UW(2); + GPR_UW(destreg,2) = RT_UW(1); + GPR_UW(destreg,3) = RT_UW(3); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11010001001:MMI2:32::PEXOH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + GPR_UH(destreg,0) = RT_UH(2); + GPR_UH(destreg,1) = RT_UH(1); + GPR_UH(destreg,2) = RT_UH(0); + GPR_UH(destreg,3) = RT_UH(3); + GPR_UH(destreg,4) = RT_UH(6); + GPR_UH(destreg,5) = RT_UH(5); + GPR_UH(destreg,6) = RT_UH(4); + GPR_UH(destreg,7) = RT_UH(7); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11110001001:MMI2:32::PEXOW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + GPR_UW(destreg,0) = RT_UW(2); + GPR_UW(destreg,1) = RT_UW(1); + GPR_UW(destreg,2) = RT_UW(0); + GPR_UW(destreg,3) = RT_UW(3); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11110001000:MMI0:32::PEXT5 +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + { + unsigned32 x = RT_UW(i); + GPR_UW(destreg,i) = ((x & (1 << 15)) << (31 - 15)) + | ((x & (31 << 10)) << (19 - 10)) + | ((x & (31 << 5)) << (11 - 5)) + | ((x & (31 << 0)) << (3 - 0)); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11010001000:MMI0:32::PEXTLB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UB(destreg,0) = RT_UB(0); + GPR_UB(destreg,1) = RS_UB(0); + GPR_UB(destreg,2) = RT_UB(1); + GPR_UB(destreg,3) = RS_UB(1); + GPR_UB(destreg,4) = RT_UB(2); + GPR_UB(destreg,5) = RS_UB(2); + GPR_UB(destreg,6) = RT_UB(3); + GPR_UB(destreg,7) = RS_UB(3); + GPR_UB(destreg,8) = RT_UB(4); + GPR_UB(destreg,9) = RS_UB(4); + GPR_UB(destreg,10) = RT_UB(5); + GPR_UB(destreg,11) = RS_UB(5); + GPR_UB(destreg,12) = RT_UB(6); + GPR_UB(destreg,13) = RS_UB(6); + GPR_UB(destreg,14) = RT_UB(7); + GPR_UB(destreg,15) = RS_UB(7); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10110001000:MMI0:32::PEXTLH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UH(destreg,0) = RT_UH(0); + GPR_UH(destreg,1) = RS_UH(0); + GPR_UH(destreg,2) = RT_UH(1); + GPR_UH(destreg,3) = RS_UH(1); + GPR_UH(destreg,4) = RT_UH(2); + GPR_UH(destreg,5) = RS_UH(2); + GPR_UH(destreg,6) = RT_UH(3); + GPR_UH(destreg,7) = RS_UH(3); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10010001000:MMI0:32::PEXTLW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UW(destreg,0) = RT_UW(0); + GPR_UW(destreg,1) = RS_UW(0); + GPR_UW(destreg,2) = RT_UW(1); + GPR_UW(destreg,3) = RS_UW(1); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11010101000:MMI1:32::PEXTUB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UB(destreg,0) = RT_UB(8); + GPR_UB(destreg,1) = RS_UB(8); + GPR_UB(destreg,2) = RT_UB(9); + GPR_UB(destreg,3) = RS_UB(9); + GPR_UB(destreg,4) = RT_UB(10); + GPR_UB(destreg,5) = RS_UB(10); + GPR_UB(destreg,6) = RT_UB(11); + GPR_UB(destreg,7) = RS_UB(11); + GPR_UB(destreg,8) = RT_UB(12); + GPR_UB(destreg,9) = RS_UB(12); + GPR_UB(destreg,10) = RT_UB(13); + GPR_UB(destreg,11) = RS_UB(13); + GPR_UB(destreg,12) = RT_UB(14); + GPR_UB(destreg,13) = RS_UB(14); + GPR_UB(destreg,14) = RT_UB(15); + GPR_UB(destreg,15) = RS_UB(15); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10110101000:MMI1:32::PEXTUH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UH(destreg,0) = RT_UH(4); + GPR_UH(destreg,1) = RS_UH(4); + GPR_UH(destreg,2) = RT_UH(5); + GPR_UH(destreg,3) = RS_UH(5); + GPR_UH(destreg,4) = RT_UH(6); + GPR_UH(destreg,5) = RS_UH(6); + GPR_UH(destreg,6) = RT_UH(7); + GPR_UH(destreg,7) = RS_UH(7); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10010101000:MMI1:32::PEXTUW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UW(destreg,0) = RT_UW(2); + GPR_UW(destreg,1) = RS_UW(2); + GPR_UW(destreg,2) = RT_UW(3); + GPR_UW(destreg,3) = RS_UW(3); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10001001001:MMI2:32::PHMADDH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(1) * RT_SH(1)) + (RS_SH(0) * RT_SH(0)); + GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(3) * RT_SH(3)) + (RS_SH(2) * RT_SH(2)); + GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(5) * RT_SH(5)) + (RS_SH(4) * RT_SH(4)); + GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(7) * RT_SH(7)) + (RS_SH(6) * RT_SH(6)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10101001001:MMI2:32::PHMSUBH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(1) * RT_SH(1)) - (RS_SH(0) * RT_SH(0)); + GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(3) * RT_SH(3)) - (RS_SH(2) * RT_SH(2)); + GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(5) * RT_SH(5)) - (RS_SH(4) * RT_SH(4)); + GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(7) * RT_SH(7)) - (RS_SH(6) * RT_SH(6)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01010001001:MMI2:32::PINTH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UH(destreg,0) = RT_UH(0); + GPR_UH(destreg,1) = RS_UH(4); + GPR_UH(destreg,2) = RT_UH(1); + GPR_UH(destreg,3) = RS_UH(5); + GPR_UH(destreg,4) = RT_UH(2); + GPR_UH(destreg,5) = RS_UH(6); + GPR_UH(destreg,6) = RT_UH(3); + GPR_UH(destreg,7) = RS_UH(7); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01010101001:MMI3:32::PINTOH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UH(destreg,0) = RT_UH(0); + GPR_UH(destreg,1) = RS_UH(0); + GPR_UH(destreg,2) = RT_UH(2); + GPR_UH(destreg,3) = RS_UH(2); + GPR_UH(destreg,4) = RT_UH(4); + GPR_UH(destreg,5) = RS_UH(4); + GPR_UH(destreg,6) = RT_UH(6); + GPR_UH(destreg,7) = RS_UH(6); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,00000,5.RD,00000000100:MMINORM:32::PLZCW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + unsigned long value; + int test; + int count; + int i; + value = RS_UW(0); + count = 0; + test = !!(value & (1 << 31)); + for(i=30; i>=0 && (test == !!(value & (1 << i))); i--) + count++; + GPR_UW(destreg,0) = count; + value = RS_UW(1); + count = 0; + test = !!(value & (1 << 31)); + for(i=30; i>=0 && (test == !!(value & (1 << i))); i--) + count++; + GPR_UW(destreg,1) = count; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10000001001:MMI2:32::PMADDH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_SW(destreg,0) = LO_SW(0) += (RS_SH(0) * RT_SH(0)); + LO_SW(1) += (RS_SH(1) * RT_SH(1)); + GPR_SW(destreg,1) = HI_SW(0) += (RS_SH(2) * RT_SH(2)); + HI_SW(1) += (RS_SH(3) * RT_SH(3)); + GPR_SW(destreg,2) = LO_SW(2) += (RS_SH(4) * RT_SH(4)); + LO_SW(3) += (RS_SH(5) * RT_SH(5)); + GPR_SW(destreg,3) = HI_SW(2) += (RS_SH(6) * RT_SH(6)); + HI_SW(3) += (RS_SH(7) * RT_SH(7)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000101001:MMI3:32::PMADDUW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 sum0 = UNSIGNED64( HI_SW(0), LO_SW(0) ); + unsigned64 sum1 = UNSIGNED64( HI_SW(2), LO_SW(2) ); + unsigned64 prod0 = (unsigned64)RS_UW(0) * (unsigned64)RT_UW(0); + unsigned64 prod1 = (unsigned64)RS_UW(2) * (unsigned64)RT_UW(2); + sum0 += prod0; + sum1 += prod1; + GPR_UD(destreg,0) = sum0; + GPR_UD(destreg,1) = sum1; + LO = SIGNEXTEND( sum0, 32 ); + HI = SIGNEXTEND( VH4_8(sum0), 32 ); + LO1 = SIGNEXTEND( sum1, 32 ); + HI1 = SIGNEXTEND( VH4_8(sum1), 32 ); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00000001001:MMI2:32::PMADDW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + signed64 sum0 = WORD64( HI_SW(0), LO_SW(0) ); + signed64 sum1 = WORD64( HI_SW(2), LO_SW(2) ); + signed64 prod0 = (signed64)RS_SW(0) * (signed64)RT_SW(0); + signed64 prod1 = (signed64)RS_SW(2) * (signed64)RT_SW(2); + sum0 += prod0; + sum1 += prod1; + GPR_SD(destreg,0) = sum0; + GPR_SD(destreg,1) = sum1; + LO = SIGNEXTEND( sum0, 32 ); + HI = SIGNEXTEND( VH4_8(sum0), 32 ); + LO1 = SIGNEXTEND( sum1, 32 ); + HI1 = SIGNEXTEND( VH4_8(sum1), 32 ); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00111001000:MMI0:32::PMAXH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS;i++) + { + if (RS_SH(i) > RT_SH(i)) GPR_SH(destreg,i) = RS_SH(i); + else GPR_SH(destreg,i) = RT_SH(i); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00011001000:MMI0:32::PMAXW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + { + if (RS_SW(i) > RT_SW(i)) GPR_SW(destreg,i) = RS_SW(i); + else GPR_SW(destreg,i) = RT_SW(i); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +0111000000000000,5.RD,01000001001:MMI2:32::PMFHI +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + { + GPR_SD(destreg,0) = HI; + GPR_SD(destreg,1) = HI1; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +0111000000000000,5.RD,01001001001:MMI2:32::PMFLO +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + { + GPR_SD(destreg,0) = LO; + GPR_SD(destreg,1) = LO1; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +0111000000000000,5.RD,5.SA,110000:MMINORM:32::PMFHL +*r5900: +{ + unsigned32 instruction = instruction_0; + int op1 UNUSED = ((instruction >> 6) & 0x0000001F); + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + { + if (op1 == 0) + { + GPR_UW(destreg,0) = LO_UW(0); + GPR_UW(destreg,1) = HI_UW(0); + GPR_UW(destreg,2) = LO_UW(2); + GPR_UW(destreg,3) = HI_UW(2); + } + else if (op1 == 1) + { + GPR_UW(destreg,0) = LO_UW(1); + GPR_UW(destreg,1) = HI_UW(1); + GPR_UW(destreg,2) = LO_UW(3); + GPR_UW(destreg,3) = HI_UW(3); + } + else if (op1 == 2) + { + /* NOTE: This code implements a saturate according to the + figure on page B-115 and not according to the + definition on page B-113 */ + signed64 t = ((unsigned64)HI_UW(0) << 32) | (unsigned64)LO_UW(0); + signed64 u = ((unsigned64)HI_UW(2) << 32) | (unsigned64)LO_UW(2); + if ( t > SIGNED64 (0x000000007FFFFFFF) ) + GPR_SD(destreg,0) = SIGNED64 (0x000000007FFFFFFF); + else if ( t < - SIGNED64 (0x0000000080000000) ) + GPR_SD(destreg,0) = - SIGNED64 (0x0000000080000000); + else + GPR_SD(destreg,0) = t; + if ( u > SIGNED64 (0x000000007FFFFFFF) ) + GPR_SD(destreg,1) = SIGNED64 (0x000000007FFFFFFF); + else if ( u < - SIGNED64 (0x0000000080000000) ) + GPR_SD(destreg,1) = - SIGNED64 (0x0000000080000000); + else + GPR_SD(destreg,1) = u; + } + else if (op1 == 3) + { + GPR_UH(destreg,0) = LO_UH(0); + GPR_UH(destreg,1) = LO_UH(2); + GPR_UH(destreg,2) = HI_UH(0); + GPR_UH(destreg,3) = HI_UH(2); + GPR_UH(destreg,4) = LO_UH(4); + GPR_UH(destreg,5) = LO_UH(6); + GPR_UH(destreg,6) = HI_UH(4); + GPR_UH(destreg,7) = HI_UH(6); + } + else if (op1 == 4) + { + if (LO_SW(0) > 0x7FFF) + GPR_UH(destreg,0) = 0x7FFF; + else if (LO_SW(0) < -0x8000) + GPR_UH(destreg,0) = 0x8000; + else + GPR_UH(destreg,0) = LO_UH(0); + if (LO_SW(1) > 0x7FFF) + GPR_UH(destreg,1) = 0x7FFF; + else if (LO_SW(1) < -0x8000) + GPR_UH(destreg,1) = 0x8000; + else + GPR_UH(destreg,1) = LO_UH(2); + if (HI_SW(0) > 0x7FFF) + GPR_UH(destreg,2) = 0x7FFF; + else if (HI_SW(0) < -0x8000) + GPR_UH(destreg,2) = 0x8000; + else + GPR_UH(destreg,2) = HI_UH(0); + if (HI_SW(1) > 0x7FFF) + GPR_UH(destreg,3) = 0x7FFF; + else if (HI_SW(1) < -0x8000) + GPR_UH(destreg,3) = 0x8000; + else + GPR_UH(destreg,3) = HI_UH(2); + if (LO_SW(2) > 0x7FFF) + GPR_UH(destreg,4) = 0x7FFF; + else if (LO_SW(2) < -0x8000) + GPR_UH(destreg,4) = 0x8000; + else + GPR_UH(destreg,4) = LO_UH(4); + if (LO_SW(3) > 0x7FFF) + GPR_UH(destreg,5) = 0x7FFF; + else if (LO_SW(3) < -0x8000) + GPR_UH(destreg,5) = 0x8000; + else + GPR_UH(destreg,5) = LO_UH(6); + if (HI_SW(2) > 0x7FFF) + GPR_UH(destreg,6) = 0x7FFF; + else if (HI_SW(2) < -0x8000) + GPR_UH(destreg,6) = 0x8000; + else + GPR_UH(destreg,6) = HI_UH(4); + if (HI_SW(3) > 0x7FFF) + GPR_UH(destreg,7) = 0x7FFF; + else if (HI_SW(3) < -0x8000) + GPR_UH(destreg,7) = 0x8000; + else + GPR_UH(destreg,7) = HI_UH(6); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00111101000:MMI1:32::PMINH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS;i++) + { + if (RS_SH(i) < RT_SH(i)) GPR_SH(destreg,i) = RS_SH(i); + else GPR_SH(destreg,i) = RT_SH(i); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00011101000:MMI1:32::PMINW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + { + if (RS_SW(i) < RT_SW(i)) GPR_SW(destreg,i) = RS_SW(i); + else GPR_SW(destreg,i) = RT_SW(i); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10100001001:MMI2:32::PMSUBH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_SW(destreg,0) = LO_SW(0) -= (RS_SH(0) * RT_SH(0)); + LO_SW(1) -= (RS_SH(1) * RT_SH(1)); + GPR_SW(destreg,1) = HI_SW(0) -= (RS_SH(2) * RT_SH(2)); + HI_SW(1) -= (RS_SH(3) * RT_SH(3)); + GPR_SW(destreg,2) = LO_SW(2) -= (RS_SH(4) * RT_SH(4)); + LO_SW(3) -= (RS_SH(5) * RT_SH(5)); + GPR_SW(destreg,3) = HI_SW(2) -= (RS_SH(6) * RT_SH(6)); + HI_SW(3) -= (RS_SH(7) * RT_SH(7)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00100001001:MMI2:32::PMSUBW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + signed64 sum0 = WORD64( HI_SW(0), LO_SW(0) ); + signed64 sum1 = WORD64( HI_SW(2), LO_SW(2) ); + signed64 prod0 = (signed64)RS_SW(0) * (signed64)RT_SW(0); + signed64 prod1 = (signed64)RS_SW(2) * (signed64)RT_SW(2); + sum0 -= prod0; + sum1 -= prod1; + GPR_SD(destreg,0) = sum0; + GPR_SD(destreg,1) = sum1; + LO = SIGNEXTEND( sum0, 32 ); + HI = SIGNEXTEND( VH4_8(sum0), 32 ); + LO1 = SIGNEXTEND( sum1, 32 ); + HI1 = SIGNEXTEND( VH4_8(sum1), 32 ); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,000000000001000101001:MMI3:32::PMTHI +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + HI = RS_SD(0); + HI1 = RS_SD(1); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,000000000001001101001:MMI3:32::PMTLO +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + LO = RS_SD(0); + LO1 = RS_SD(1); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,000000000000000110001:MMINORM:32::PMTHL.LW +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + LO_UW(0) = RS_UW(0); + HI_UW(0) = RS_UW(1); + LO_UW(2) = RS_UW(2); + HI_UW(2) = RS_UW(3); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11100001001:MMI2:32::PMULTH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_SW(destreg,0) = LO_SW(0) = (RS_SH(0) * RT_SH(0)); + LO_SW(1) = (RS_SH(1) * RT_SH(1)); + GPR_SW(destreg,1) = HI_SW(0) = (RS_SH(2) * RT_SH(2)); + HI_SW(1) = (RS_SH(3) * RT_SH(3)); + GPR_SW(destreg,2) = LO_SW(2) = (RS_SH(4) * RT_SH(4)); + LO_SW(3) = (RS_SH(5) * RT_SH(5)); + GPR_SW(destreg,3) = HI_SW(2) = (RS_SH(6) * RT_SH(6)); + HI_SW(3) = (RS_SH(7) * RT_SH(7)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01100101001:MMI3:32::PMULTUW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 sum0 = 0; + unsigned64 sum1 = 0; + unsigned64 prod0 = (unsigned64)RS_UW(0) * (unsigned64)RT_UW(0); + unsigned64 prod1 = (unsigned64)RS_UW(2) * (unsigned64)RT_UW(2); + sum0 = prod0; + sum1 = prod1; + GPR_UD(destreg,0) = sum0; + GPR_UD(destreg,1) = sum1; + LO = SIGNEXTEND( sum0, 32 ); + HI = SIGNEXTEND( VH4_8(sum0), 32 ); + LO1 = SIGNEXTEND( sum1, 32 ); + HI1 = SIGNEXTEND( VH4_8(sum1), 32 ); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01100001001:MMI2:32::PMULTW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + signed64 sum0 = 0; + signed64 sum1 = 0; + signed64 prod0 = (signed64)RS_SW(0) * (signed64)RT_SW(0); + signed64 prod1 = (signed64)RS_SW(2) * (signed64)RT_SW(2); + sum0 = prod0; + sum1 = prod1; + GPR_SD(destreg,0) = sum0; + GPR_SD(destreg,1) = sum1; + LO = SIGNEXTEND( sum0, 32 ); + HI = SIGNEXTEND( VH4_8(sum0), 32 ); + LO1 = SIGNEXTEND( sum1, 32 ); + HI1 = SIGNEXTEND( VH4_8(sum1), 32 ); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10011101001:MMI3:32::PNOR +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + GPR_UW(destreg,i) = ~(RS_UW(i) | RT_UW(i)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10010101001:MMI3:32::POR +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + GPR_UW(destreg,i) = (RS_UW(i) | RT_UW(i)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11111001000:MMI0:32::PPAC5 +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + { + unsigned32 x = RT_UW(i); + GPR_UW(destreg,i) = ((x & (1 << 31)) >> (31 - 15)) + | ((x & (31 << 19)) >> (19 - 10)) + | ((x & (31 << 11)) >> (11 - 5)) + | ((x & (31 << 3)) >> (3 - 0)); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11011001000:MMI0:32::PPACB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UB(destreg,0) = RT_UB(0); + GPR_UB(destreg,1) = RT_UB(2); + GPR_UB(destreg,2) = RT_UB(4); + GPR_UB(destreg,3) = RT_UB(6); + GPR_UB(destreg,4) = RT_UB(8); + GPR_UB(destreg,5) = RT_UB(10); + GPR_UB(destreg,6) = RT_UB(12); + GPR_UB(destreg,7) = RT_UB(14); + GPR_UB(destreg,8) = RS_UB(0); + GPR_UB(destreg,9) = RS_UB(2); + GPR_UB(destreg,10) = RS_UB(4); + GPR_UB(destreg,11) = RS_UB(6); + GPR_UB(destreg,12) = RS_UB(8); + GPR_UB(destreg,13) = RS_UB(10); + GPR_UB(destreg,14) = RS_UB(12); + GPR_UB(destreg,15) = RS_UB(14); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10111001000:MMI0:32::PPACH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UH(destreg,0) = RT_UH(0); + GPR_UH(destreg,1) = RT_UH(2); + GPR_UH(destreg,2) = RT_UH(4); + GPR_UH(destreg,3) = RT_UH(6); + GPR_UH(destreg,4) = RS_UH(0); + GPR_UH(destreg,5) = RS_UH(2); + GPR_UH(destreg,6) = RS_UH(4); + GPR_UH(destreg,7) = RS_UH(6); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10011001000:MMI0:32::PPACW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UW(destreg,0) = RT_UW(0); + GPR_UW(destreg,1) = RT_UW(2); + GPR_UW(destreg,2) = RS_UW(0); + GPR_UW(destreg,3) = RS_UW(2); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11011001001:MMI2:32::PREVH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + GPR_UH(destreg,0) = RT_UH(3); + GPR_UH(destreg,1) = RT_UH(2); + GPR_UH(destreg,2) = RT_UH(1); + GPR_UH(destreg,3) = RT_UH(0); + GPR_UH(destreg,4) = RT_UH(7); + GPR_UH(destreg,5) = RT_UH(6); + GPR_UH(destreg,6) = RT_UH(5); + GPR_UH(destreg,7) = RT_UH(4); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,11111001001:MMI2:32::PROT3W +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + GPR_UW(destreg,0) = RT_UW(0); + GPR_UW(destreg,1) = RT_UW(3); + GPR_UW(destreg,2) = RT_UW(1); + GPR_UW(destreg,3) = RT_UW(2); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,5.SA,110100:MMINORM:32::PSLLH +*r5900: +{ + unsigned32 instruction = instruction_0; + int op1 UNUSED = ((instruction >> 6) & 0x0000001F); + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int shift_by = op1 & (16-1); + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS;i++) + GPR_UH(destreg,i) = (RT_UH(i) << shift_by); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00010001001:MMI2:32::PSLLVW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int s0 = (RS_UB(0) & 0x1F); + int s1 = (RS_UB(8) & 0x1F); + signed32 temp0 = RT_UW(0) << s0; + signed32 temp1 = RT_UW(2) << s1; + GPR_SD(destreg,0) = (signed64)temp0; + GPR_SD(destreg,1) = (signed64)temp1; + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,5.SA,111100:MMINORM:32::PSLLW +*r5900: +{ + unsigned32 instruction = instruction_0; + int op1 UNUSED = ((instruction >> 6) & 0x0000001F); + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int shift_by = op1 & (32-1); + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + GPR_UW(destreg,i) = (RT_UW(i) << shift_by); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,5.SA,110111:MMINORM:32::PSRAH +*r5900: +{ + unsigned32 instruction = instruction_0; + int op1 UNUSED = ((instruction >> 6) & 0x0000001F); + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int shift_by = op1 & (16-1); + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS;i++) + GPR_SH(destreg,i) = SIGNEXTEND( (RT_SH(i) >> shift_by), (16-shift_by) ); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00011101001:MMI3:32::PSRAVW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_SD(destreg,0) = SIGNEXTEND( (RT_SW (0) >> (RS_UB(0) & 0x1F)), 32-(RS_UB(0) & 0x1F) ); + GPR_SD(destreg,1) = SIGNEXTEND( (RT_SW (2) >> (RS_UB(8) & 0x1F)), 32-(RS_UB(8) & 0x1F) ); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,5.SA,111111:MMINORM:32::PSRAW +*r5900: +{ + unsigned32 instruction = instruction_0; + int op1 UNUSED = ((instruction >> 6) & 0x0000001F); + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int shift_by = op1 & (32-1); + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + GPR_SW(destreg,i) = SIGNEXTEND( (RT_SW(i) >> shift_by), (32-shift_by) ); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,5.SA,110110:MMINORM:32::PSRLH +*r5900: +{ + unsigned32 instruction = instruction_0; + int op1 UNUSED = ((instruction >> 6) & 0x0000001F); + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int shift_by = op1 & (16-1); + int i; + for(i=0;i<HALFWORDS_IN_MMI_REGS;i++) + GPR_UH(destreg,i) = (RT_UH(i) >> shift_by); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00011001001:MMI2:32::PSRLVW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + GPR_UD(destreg,0) = SIGNEXTEND ( RT_UW(0) >> (RS_UB(0) & 0x1F), 31); + GPR_UD(destreg,1) = SIGNEXTEND ( RT_UW(2) >> (RS_UB(8) & 0x1F), 31); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +01110000000,5.RT,5.RD,5.SA,111110:MMINORM:32::PSRLW +*r5900: +{ + unsigned32 instruction = instruction_0; + int op1 UNUSED = ((instruction >> 6) & 0x0000001F); + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + { + int shift_by = op1 & (32-1); + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + GPR_UW(destreg,i) = (RT_UW(i) >> shift_by); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,01001001000:MMI0:32::PSUBB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < BYTES_IN_MMI_REGS; i++) + { + int s = RS_SB(i); + int t = RT_SB(i); + int r = s - t; + GPR_SB(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00101001000:MMI0:32::PSUBH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < HALFWORDS_IN_MMI_REGS; i++) + { + int s = RS_SH(i); + int t = RT_SH(i); + int r = s - t; + GPR_SH(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11001001000:MMI0:32::PSUBSB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < BYTES_IN_MMI_REGS; i++) + { + int s = RS_SB(i); + int t = RT_SB(i); + int r = s - t; + if (r > 127) + GPR_SB(destreg,i) = 127; + else if (r < -128) + GPR_SB(destreg,i) = -128; + else + GPR_SB(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10101001000:MMI0:32::PSUBSH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < HALFWORDS_IN_MMI_REGS; i++) + { + int s = RS_SH(i); + int t = RT_SH(i); + int r = s - t; + if (r > 32767) + GPR_SH(destreg,i) = 32767; + else if (r < -32768) + GPR_SH(destreg,i) = -32768; + else + GPR_SH(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10001001000:MMI0:32::PSUBSW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < WORDS_IN_MMI_REGS; i++) + { + signed64 s = RS_SW(i); + signed64 t = RT_SW(i); + signed64 r = s - t; + if (r > (int)0x7FFFFFFF) + GPR_SW(destreg,i) = (int)0x7FFFFFFF; + else if (r < (int)0x80000000) + GPR_SW(destreg,i) = (int)0x80000000; + else + GPR_SW(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11001101000:MMI1:32::PSUBUB +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < BYTES_IN_MMI_REGS; i++) + { + unsigned int s = RS_UB(i); + unsigned int t = RT_UB(i); + unsigned int r = s - t; + if (r > 0xFF) + GPR_UB(destreg,i) = 0; + else + GPR_UB(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10101101000:MMI1:32::PSUBUH +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < HALFWORDS_IN_MMI_REGS; i++) + { + unsigned int s = RS_UH(i); + unsigned int t = RT_UH(i); + unsigned int r = s - t; + if (r > 0xFFFF) + GPR_UH(destreg,i) = 0; + else + GPR_UH(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10001101000:MMI1:32::PSUBUW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < WORDS_IN_MMI_REGS; i++) + { + unsigned64 s = RS_UW(i); + unsigned64 t = RT_UW(i); + unsigned64 r = s - t; + if (r > 0xFFFFFFFF) + GPR_UW(destreg,i) = 0; + else + GPR_UW(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,00001001000:MMI0:32::PSUBW +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for (i=0; i < WORDS_IN_MMI_REGS; i++) + { + signed64 s = RS_SW(i); + signed64 t = RT_SW(i); + signed64 r = s - t; + GPR_SW(destreg,i) = r; + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,10011001001:MMI2:32::PXOR +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int i; + for(i=0;i<WORDS_IN_MMI_REGS;i++) + GPR_UW(destreg,i) = (RS_UW(i) ^ RT_UW(i)); + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011100,5.RS,5.RT,5.RD,11011101000:MMI1:32::QFSRV +*r5900: +{ + unsigned32 instruction = instruction_0; + int destreg UNUSED = ((instruction >> 11) & 0x0000001F); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg rs_reg UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + t_reg rs_reg1 = GPR1[((instruction >> 21) & 0x0000001F)]; + { + int bytes = (SA / 8) % 16; + if (SA % 8) + SignalException(ReservedInstruction,instruction); + else + { + int i; + for(i=0;i<(16-bytes);i++) + GPR_SB(destreg,i) = RT_SB(bytes+i); + for(;i<16;i++) + GPR_SB(destreg,i) = RS_SB(i-(16-bytes)); + } + } +} + +// end-sanitize-r5900 +// start-sanitize-r5900 + +011111,5.RS,5.RT,16.OFFSET:NORMAL:128::SQ +*r5900: +{ + unsigned32 instruction = instruction_0; + t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); + t_reg rt_reg UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; + t_reg rt_reg1 = GPR1[((instruction >> 16) & 0x0000001F)]; + t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; + { + unsigned64 vaddr = ((unsigned64)op1 + offset); + unsigned64 paddr; + int uncached; + if ((vaddr & 15) != 0) + SignalException(AddressStore); + else + { + if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&uncached,isTARGET,isREAL)) + { + unsigned64 memval = 0; + unsigned64 memval1 = 0; + memval = rt_reg; + memval1 = rt_reg1; + { + StoreMemory(uncached,AccessLength_QUADWORD,memval,memval1,paddr,vaddr,isREAL); + } + } + } + } +} + +// end-sanitize-r5900 + +// start-sanitize-cygnus-never + +// What is this instruction? +//111011,5.RS,5.RT,16.OFFSET:NORMAL:32::<INT> +//*mipsI: +//*mipsII: +//*mipsIII: +//*mipsIV: +//// start-sanitize-r5900 +//*r5900: +//// end-sanitize-r5900 +//*r3900: +//// start-sanitize-tx19 +//*tx19: +//// end-sanitize-tx19 +//{ +// unsigned32 instruction = instruction_0; +// t_reg offset UNUSED = SIGNEXTEND((t_reg)((instruction >> 0) & 0x0000FFFF),16); +// t_reg op2 UNUSED = GPR[((instruction >> 16) & 0x0000001F)]; +// t_reg op1 UNUSED = GPR[((instruction >> 21) & 0x0000001F)]; +// { +// if (CoProcPresent(3)) +// SignalException(CoProcessorUnusable); +// else +// SignalException(ReservedInstruction,instruction); +// } +//} + +// end-sanitize-cygnus-never +// start-sanitize-cygnus-never + +// FIXME FIXME FIXME What is this? +//11100,******,00001:RR:16::SDBBP +//*mips16: +//{ +// unsigned32 instruction = instruction_0; +// if (have_extendval) +// SignalException (ReservedInstruction, instruction); +// { +// SignalException(DebugBreakPoint,instruction); +// } +//} + +// end-sanitize-cygnus-never +// start-sanitize-cygnus-never + +// FIXME FIXME FIXME What is this? +000000,********************,001110:SPECIAL:32::SDBBP +//*r3900: +//{ +// unsigned32 instruction = instruction_0; +// { +// SignalException(DebugBreakPoint,instruction); +// } +//} + +// end-sanitize-cygnus-never |