X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fmupen64plus-core%2Fsrc%2Fr4300%2Finterpreter_special.def;fp=source%2Fmupen64plus-core%2Fsrc%2Fr4300%2Finterpreter_special.def;h=79e217ea0943fb716516b96fbabcd0ac1ca51be6;hb=451ab91e3827a6384981b3300e2a7000d2eaba58;hp=0000000000000000000000000000000000000000;hpb=a2ab25365b5b0dddbee476d695d8a31151407581;p=mupen64plus-pandora.git diff --git a/source/mupen64plus-core/src/r4300/interpreter_special.def b/source/mupen64plus-core/src/r4300/interpreter_special.def new file mode 100644 index 0000000..79e217e --- /dev/null +++ b/source/mupen64plus-core/src/r4300/interpreter_special.def @@ -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, ®[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); +}