1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - interpreter_special.def *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22 DECLARE_INSTRUCTION(NOP)
27 DECLARE_INSTRUCTION(SLL)
29 rrd32 = (unsigned int)(rrt32) << rsa;
34 DECLARE_INSTRUCTION(SRL)
36 rrd32 = (unsigned int)rrt32 >> rsa;
41 DECLARE_INSTRUCTION(SRA)
43 rrd32 = (signed int)rrt32 >> rsa;
48 DECLARE_INSTRUCTION(SLLV)
50 rrd32 = (unsigned int)(rrt32) << (rrs32&0x1F);
55 DECLARE_INSTRUCTION(SRLV)
57 rrd32 = (unsigned int)rrt32 >> (rrs32 & 0x1F);
62 DECLARE_INSTRUCTION(SRAV)
64 rrd32 = (signed int)rrt32 >> (rrs32 & 0x1F);
69 DECLARE_JUMP(JR, irs32, 1, ®[0], 0, 0)
70 DECLARE_JUMP(JALR, irs32, 1, PC->f.r.rd, 0, 0)
72 DECLARE_INSTRUCTION(SYSCALL)
78 DECLARE_INSTRUCTION(SYNC)
83 DECLARE_INSTRUCTION(MFHI)
89 DECLARE_INSTRUCTION(MTHI)
95 DECLARE_INSTRUCTION(MFLO)
101 DECLARE_INSTRUCTION(MTLO)
107 DECLARE_INSTRUCTION(DSLLV)
109 rrd = rrt << (rrs32&0x3F);
113 DECLARE_INSTRUCTION(DSRLV)
115 rrd = (unsigned long long)rrt >> (rrs32 & 0x3F);
119 DECLARE_INSTRUCTION(DSRAV)
121 rrd = (long long)rrt >> (rrs32 & 0x3F);
125 DECLARE_INSTRUCTION(MULT)
135 DECLARE_INSTRUCTION(MULTU)
137 unsigned long long int temp;
138 temp = (unsigned int)rrs * (unsigned long long)((unsigned int)rrt);
139 hi = (long long)temp >> 32;
145 DECLARE_INSTRUCTION(DIV)
154 else DebugMessage(M64MSG_ERROR, "DIV: divide by 0");
158 DECLARE_INSTRUCTION(DIVU)
162 lo = (unsigned int)rrs32 / (unsigned int)rrt32;
163 hi = (unsigned int)rrs32 % (unsigned int)rrt32;
167 else DebugMessage(M64MSG_ERROR, "DIVU: divide by 0");
171 DECLARE_INSTRUCTION(DMULT)
173 unsigned long long int op1, op2, op3, op4;
174 unsigned long long int result1, result2, result3, result4;
175 unsigned long long int temp1, temp2, temp3, temp4;
191 op1 = op2 & 0xFFFFFFFF;
192 op2 = (op2 >> 32) & 0xFFFFFFFF;
193 op3 = op4 & 0xFFFFFFFF;
194 op4 = (op4 >> 32) & 0xFFFFFFFF;
197 temp2 = (temp1 >> 32) + op1 * op4;
199 temp4 = (temp3 >> 32) + op2 * op4;
201 result1 = temp1 & 0xFFFFFFFF;
202 result2 = temp2 + (temp3 & 0xFFFFFFFF);
203 result3 = (result2 >> 32) + temp4;
204 result4 = (result3 >> 32);
206 lo = result1 | (result2 << 32);
207 hi = (result3 & 0xFFFFFFFF) | (result4 << 32);
217 DECLARE_INSTRUCTION(DMULTU)
219 unsigned long long int op1, op2, op3, op4;
220 unsigned long long int result1, result2, result3, result4;
221 unsigned long long int temp1, temp2, temp3, temp4;
223 op1 = rrs & 0xFFFFFFFF;
224 op2 = (rrs >> 32) & 0xFFFFFFFF;
225 op3 = rrt & 0xFFFFFFFF;
226 op4 = (rrt >> 32) & 0xFFFFFFFF;
229 temp2 = (temp1 >> 32) + op1 * op4;
231 temp4 = (temp3 >> 32) + op2 * op4;
233 result1 = temp1 & 0xFFFFFFFF;
234 result2 = temp2 + (temp3 & 0xFFFFFFFF);
235 result3 = (result2 >> 32) + temp4;
236 result4 = (result3 >> 32);
238 lo = result1 | (result2 << 32);
239 hi = (result3 & 0xFFFFFFFF) | (result4 << 32);
244 DECLARE_INSTRUCTION(DDIV)
248 lo = (long long int)rrs / (long long int)rrt;
249 hi = (long long int)rrs % (long long int)rrt;
251 else DebugMessage(M64MSG_ERROR, "DDIV: divide by 0");
255 DECLARE_INSTRUCTION(DDIVU)
259 lo = (unsigned long long int)rrs / (unsigned long long int)rrt;
260 hi = (unsigned long long int)rrs % (unsigned long long int)rrt;
262 else DebugMessage(M64MSG_ERROR, "DDIVU: divide by 0");
266 DECLARE_INSTRUCTION(ADD)
268 rrd32 = rrs32 + rrt32;
273 DECLARE_INSTRUCTION(ADDU)
275 rrd32 = rrs32 + rrt32;
280 DECLARE_INSTRUCTION(SUB)
282 rrd32 = rrs32 - rrt32;
287 DECLARE_INSTRUCTION(SUBU)
289 rrd32 = rrs32 - rrt32;
294 DECLARE_INSTRUCTION(AND)
300 DECLARE_INSTRUCTION(OR)
306 DECLARE_INSTRUCTION(XOR)
312 DECLARE_INSTRUCTION(NOR)
318 DECLARE_INSTRUCTION(SLT)
320 if (rrs < rrt) rrd = 1;
325 DECLARE_INSTRUCTION(SLTU)
327 if ((unsigned long long)rrs < (unsigned long long)rrt)
333 DECLARE_INSTRUCTION(DADD)
339 DECLARE_INSTRUCTION(DADDU)
345 DECLARE_INSTRUCTION(DSUB)
351 DECLARE_INSTRUCTION(DSUBU)
357 DECLARE_INSTRUCTION(TEQ)
361 DebugMessage(M64MSG_ERROR, "trap exception in TEQ");
367 DECLARE_INSTRUCTION(DSLL)
373 DECLARE_INSTRUCTION(DSRL)
375 rrd = (unsigned long long)rrt >> rsa;
379 DECLARE_INSTRUCTION(DSRA)
385 DECLARE_INSTRUCTION(DSLL32)
387 rrd = rrt << (32+rsa);
391 DECLARE_INSTRUCTION(DSRL32)
393 rrd = (unsigned long long int)rrt >> (32+rsa);
397 DECLARE_INSTRUCTION(DSRA32)
399 rrd = (signed long long int)rrt >> (32+rsa);