Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / interpreter_special.def
diff --git a/source/mupen64plus-core/src/r4300/interpreter_special.def b/source/mupen64plus-core/src/r4300/interpreter_special.def
new file mode 100644 (file)
index 0000000..79e217e
--- /dev/null
@@ -0,0 +1,401 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *   Mupen64plus - interpreter_special.def                                 *
+ *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
+ *   Copyright (C) 2002 Hacktarux                                          *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+DECLARE_INSTRUCTION(NOP)
+{
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SLL)
+{
+   rrd32 = (unsigned int)(rrt32) << rsa;
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SRL)
+{
+   rrd32 = (unsigned int)rrt32 >> rsa;
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SRA)
+{
+   rrd32 = (signed int)rrt32 >> rsa;
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SLLV)
+{
+   rrd32 = (unsigned int)(rrt32) << (rrs32&0x1F);
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SRLV)
+{
+   rrd32 = (unsigned int)rrt32 >> (rrs32 & 0x1F);
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SRAV)
+{
+   rrd32 = (signed int)rrt32 >> (rrs32 & 0x1F);
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_JUMP(JR,   irs32, 1, &reg[0],    0, 0)
+DECLARE_JUMP(JALR, irs32, 1, PC->f.r.rd, 0, 0)
+
+DECLARE_INSTRUCTION(SYSCALL)
+{
+   Cause = 8 << 2;
+   exception_general();
+}
+
+DECLARE_INSTRUCTION(SYNC)
+{
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(MFHI)
+{
+   rrd = hi;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(MTHI)
+{
+   hi = rrs;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(MFLO)
+{
+   rrd = lo;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(MTLO)
+{
+   lo = rrs;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSLLV)
+{
+   rrd = rrt << (rrs32&0x3F);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSRLV)
+{
+   rrd = (unsigned long long)rrt >> (rrs32 & 0x3F);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSRAV)
+{
+   rrd = (long long)rrt >> (rrs32 & 0x3F);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(MULT)
+{
+   long long int temp;
+   temp = rrs * rrt;
+   hi = temp >> 32;
+   lo = temp;
+   sign_extended(lo);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(MULTU)
+{
+   unsigned long long int temp;
+   temp = (unsigned int)rrs * (unsigned long long)((unsigned int)rrt);
+   hi = (long long)temp >> 32;
+   lo = temp;
+   sign_extended(lo);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DIV)
+{
+   if (rrt32)
+   {
+     lo = rrs32 / rrt32;
+     hi = rrs32 % rrt32;
+     sign_extended(lo);
+     sign_extended(hi);
+   }
+   else DebugMessage(M64MSG_ERROR, "DIV: divide by 0");
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DIVU)
+{
+   if (rrt32)
+   {
+     lo = (unsigned int)rrs32 / (unsigned int)rrt32;
+     hi = (unsigned int)rrs32 % (unsigned int)rrt32;
+     sign_extended(lo);
+     sign_extended(hi);
+   }
+   else DebugMessage(M64MSG_ERROR, "DIVU: divide by 0");
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DMULT)
+{
+   unsigned long long int op1, op2, op3, op4;
+   unsigned long long int result1, result2, result3, result4;
+   unsigned long long int temp1, temp2, temp3, temp4;
+   int sign = 0;
+   
+   if (rrs < 0)
+     {
+    op2 = -rrs;
+    sign = 1 - sign;
+     }
+   else op2 = rrs;
+   if (rrt < 0)
+     {
+    op4 = -rrt;
+    sign = 1 - sign;
+     }
+   else op4 = rrt;
+   
+   op1 = op2 & 0xFFFFFFFF;
+   op2 = (op2 >> 32) & 0xFFFFFFFF;
+   op3 = op4 & 0xFFFFFFFF;
+   op4 = (op4 >> 32) & 0xFFFFFFFF;
+   
+   temp1 = op1 * op3;
+   temp2 = (temp1 >> 32) + op1 * op4;
+   temp3 = op2 * op3;
+   temp4 = (temp3 >> 32) + op2 * op4;
+   
+   result1 = temp1 & 0xFFFFFFFF;
+   result2 = temp2 + (temp3 & 0xFFFFFFFF);
+   result3 = (result2 >> 32) + temp4;
+   result4 = (result3 >> 32);
+   
+   lo = result1 | (result2 << 32);
+   hi = (result3 & 0xFFFFFFFF) | (result4 << 32);
+   if (sign)
+     {
+    hi = ~hi;
+    if (!lo) hi++;
+    else lo = ~lo + 1;
+     }
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DMULTU)
+{
+   unsigned long long int op1, op2, op3, op4;
+   unsigned long long int result1, result2, result3, result4;
+   unsigned long long int temp1, temp2, temp3, temp4;
+   
+   op1 = rrs & 0xFFFFFFFF;
+   op2 = (rrs >> 32) & 0xFFFFFFFF;
+   op3 = rrt & 0xFFFFFFFF;
+   op4 = (rrt >> 32) & 0xFFFFFFFF;
+   
+   temp1 = op1 * op3;
+   temp2 = (temp1 >> 32) + op1 * op4;
+   temp3 = op2 * op3;
+   temp4 = (temp3 >> 32) + op2 * op4;
+   
+   result1 = temp1 & 0xFFFFFFFF;
+   result2 = temp2 + (temp3 & 0xFFFFFFFF);
+   result3 = (result2 >> 32) + temp4;
+   result4 = (result3 >> 32);
+   
+   lo = result1 | (result2 << 32);
+   hi = (result3 & 0xFFFFFFFF) | (result4 << 32);
+   
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DDIV)
+{
+   if (rrt)
+   {
+     lo = (long long int)rrs / (long long int)rrt;
+     hi = (long long int)rrs % (long long int)rrt;
+   }
+   else DebugMessage(M64MSG_ERROR, "DDIV: divide by 0");
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DDIVU)
+{
+   if (rrt)
+   {
+     lo = (unsigned long long int)rrs / (unsigned long long int)rrt;
+     hi = (unsigned long long int)rrs % (unsigned long long int)rrt;
+   }
+   else DebugMessage(M64MSG_ERROR, "DDIVU: divide by 0");
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(ADD)
+{
+   rrd32 = rrs32 + rrt32;
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(ADDU)
+{
+   rrd32 = rrs32 + rrt32;
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SUB)
+{
+   rrd32 = rrs32 - rrt32;
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SUBU)
+{
+   rrd32 = rrs32 - rrt32;
+   sign_extended(rrd);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(AND)
+{
+   rrd = rrs & rrt;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(OR)
+{
+   rrd = rrs | rrt;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(XOR)
+{
+   rrd = rrs ^ rrt;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(NOR)
+{
+   rrd = ~(rrs | rrt);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SLT)
+{
+   if (rrs < rrt) rrd = 1;
+   else rrd = 0;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(SLTU)
+{
+   if ((unsigned long long)rrs < (unsigned long long)rrt) 
+     rrd = 1;
+   else rrd = 0;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DADD)
+{
+   rrd = rrs + rrt;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DADDU)
+{
+   rrd = rrs + rrt;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSUB)
+{
+   rrd = rrs - rrt;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSUBU)
+{
+   rrd = rrs - rrt;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(TEQ)
+{
+   if (rrs == rrt)
+   {
+     DebugMessage(M64MSG_ERROR, "trap exception in TEQ");
+     stop=1;
+   }
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSLL)
+{
+   rrd = rrt << rsa;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSRL)
+{
+   rrd = (unsigned long long)rrt >> rsa;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSRA)
+{
+   rrd = rrt >> rsa;
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSLL32)
+{
+   rrd = rrt << (32+rsa);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSRL32)
+{
+   rrd = (unsigned long long int)rrt >> (32+rsa);
+   ADD_TO_PC(1);
+}
+
+DECLARE_INSTRUCTION(DSRA32)
+{
+   rrd = (signed long long int)rrt >> (32+rsa);
+   ADD_TO_PC(1);
+}