Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / interpreter_special.def
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - interpreter_special.def                                 *
3  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
4  *   Copyright (C) 2002 Hacktarux                                          *
5  *                                                                         *
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.                                   *
10  *                                                                         *
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.                          *
15  *                                                                         *
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  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 DECLARE_INSTRUCTION(NOP)
23 {
24    ADD_TO_PC(1);
25 }
26
27 DECLARE_INSTRUCTION(SLL)
28 {
29    rrd32 = (unsigned int)(rrt32) << rsa;
30    sign_extended(rrd);
31    ADD_TO_PC(1);
32 }
33
34 DECLARE_INSTRUCTION(SRL)
35 {
36    rrd32 = (unsigned int)rrt32 >> rsa;
37    sign_extended(rrd);
38    ADD_TO_PC(1);
39 }
40
41 DECLARE_INSTRUCTION(SRA)
42 {
43    rrd32 = (signed int)rrt32 >> rsa;
44    sign_extended(rrd);
45    ADD_TO_PC(1);
46 }
47
48 DECLARE_INSTRUCTION(SLLV)
49 {
50    rrd32 = (unsigned int)(rrt32) << (rrs32&0x1F);
51    sign_extended(rrd);
52    ADD_TO_PC(1);
53 }
54
55 DECLARE_INSTRUCTION(SRLV)
56 {
57    rrd32 = (unsigned int)rrt32 >> (rrs32 & 0x1F);
58    sign_extended(rrd);
59    ADD_TO_PC(1);
60 }
61
62 DECLARE_INSTRUCTION(SRAV)
63 {
64    rrd32 = (signed int)rrt32 >> (rrs32 & 0x1F);
65    sign_extended(rrd);
66    ADD_TO_PC(1);
67 }
68
69 DECLARE_JUMP(JR,   irs32, 1, &reg[0],    0, 0)
70 DECLARE_JUMP(JALR, irs32, 1, PC->f.r.rd, 0, 0)
71
72 DECLARE_INSTRUCTION(SYSCALL)
73 {
74    Cause = 8 << 2;
75    exception_general();
76 }
77
78 DECLARE_INSTRUCTION(SYNC)
79 {
80    ADD_TO_PC(1);
81 }
82
83 DECLARE_INSTRUCTION(MFHI)
84 {
85    rrd = hi;
86    ADD_TO_PC(1);
87 }
88
89 DECLARE_INSTRUCTION(MTHI)
90 {
91    hi = rrs;
92    ADD_TO_PC(1);
93 }
94
95 DECLARE_INSTRUCTION(MFLO)
96 {
97    rrd = lo;
98    ADD_TO_PC(1);
99 }
100
101 DECLARE_INSTRUCTION(MTLO)
102 {
103    lo = rrs;
104    ADD_TO_PC(1);
105 }
106
107 DECLARE_INSTRUCTION(DSLLV)
108 {
109    rrd = rrt << (rrs32&0x3F);
110    ADD_TO_PC(1);
111 }
112
113 DECLARE_INSTRUCTION(DSRLV)
114 {
115    rrd = (unsigned long long)rrt >> (rrs32 & 0x3F);
116    ADD_TO_PC(1);
117 }
118
119 DECLARE_INSTRUCTION(DSRAV)
120 {
121    rrd = (long long)rrt >> (rrs32 & 0x3F);
122    ADD_TO_PC(1);
123 }
124
125 DECLARE_INSTRUCTION(MULT)
126 {
127    long long int temp;
128    temp = rrs * rrt;
129    hi = temp >> 32;
130    lo = temp;
131    sign_extended(lo);
132    ADD_TO_PC(1);
133 }
134
135 DECLARE_INSTRUCTION(MULTU)
136 {
137    unsigned long long int temp;
138    temp = (unsigned int)rrs * (unsigned long long)((unsigned int)rrt);
139    hi = (long long)temp >> 32;
140    lo = temp;
141    sign_extended(lo);
142    ADD_TO_PC(1);
143 }
144
145 DECLARE_INSTRUCTION(DIV)
146 {
147    if (rrt32)
148    {
149      lo = rrs32 / rrt32;
150      hi = rrs32 % rrt32;
151      sign_extended(lo);
152      sign_extended(hi);
153    }
154    else DebugMessage(M64MSG_ERROR, "DIV: divide by 0");
155    ADD_TO_PC(1);
156 }
157
158 DECLARE_INSTRUCTION(DIVU)
159 {
160    if (rrt32)
161    {
162      lo = (unsigned int)rrs32 / (unsigned int)rrt32;
163      hi = (unsigned int)rrs32 % (unsigned int)rrt32;
164      sign_extended(lo);
165      sign_extended(hi);
166    }
167    else DebugMessage(M64MSG_ERROR, "DIVU: divide by 0");
168    ADD_TO_PC(1);
169 }
170
171 DECLARE_INSTRUCTION(DMULT)
172 {
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;
176    int sign = 0;
177    
178    if (rrs < 0)
179      {
180     op2 = -rrs;
181     sign = 1 - sign;
182      }
183    else op2 = rrs;
184    if (rrt < 0)
185      {
186     op4 = -rrt;
187     sign = 1 - sign;
188      }
189    else op4 = rrt;
190    
191    op1 = op2 & 0xFFFFFFFF;
192    op2 = (op2 >> 32) & 0xFFFFFFFF;
193    op3 = op4 & 0xFFFFFFFF;
194    op4 = (op4 >> 32) & 0xFFFFFFFF;
195    
196    temp1 = op1 * op3;
197    temp2 = (temp1 >> 32) + op1 * op4;
198    temp3 = op2 * op3;
199    temp4 = (temp3 >> 32) + op2 * op4;
200    
201    result1 = temp1 & 0xFFFFFFFF;
202    result2 = temp2 + (temp3 & 0xFFFFFFFF);
203    result3 = (result2 >> 32) + temp4;
204    result4 = (result3 >> 32);
205    
206    lo = result1 | (result2 << 32);
207    hi = (result3 & 0xFFFFFFFF) | (result4 << 32);
208    if (sign)
209      {
210     hi = ~hi;
211     if (!lo) hi++;
212     else lo = ~lo + 1;
213      }
214    ADD_TO_PC(1);
215 }
216
217 DECLARE_INSTRUCTION(DMULTU)
218 {
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;
222    
223    op1 = rrs & 0xFFFFFFFF;
224    op2 = (rrs >> 32) & 0xFFFFFFFF;
225    op3 = rrt & 0xFFFFFFFF;
226    op4 = (rrt >> 32) & 0xFFFFFFFF;
227    
228    temp1 = op1 * op3;
229    temp2 = (temp1 >> 32) + op1 * op4;
230    temp3 = op2 * op3;
231    temp4 = (temp3 >> 32) + op2 * op4;
232    
233    result1 = temp1 & 0xFFFFFFFF;
234    result2 = temp2 + (temp3 & 0xFFFFFFFF);
235    result3 = (result2 >> 32) + temp4;
236    result4 = (result3 >> 32);
237    
238    lo = result1 | (result2 << 32);
239    hi = (result3 & 0xFFFFFFFF) | (result4 << 32);
240    
241    ADD_TO_PC(1);
242 }
243
244 DECLARE_INSTRUCTION(DDIV)
245 {
246    if (rrt)
247    {
248      lo = (long long int)rrs / (long long int)rrt;
249      hi = (long long int)rrs % (long long int)rrt;
250    }
251    else DebugMessage(M64MSG_ERROR, "DDIV: divide by 0");
252    ADD_TO_PC(1);
253 }
254
255 DECLARE_INSTRUCTION(DDIVU)
256 {
257    if (rrt)
258    {
259      lo = (unsigned long long int)rrs / (unsigned long long int)rrt;
260      hi = (unsigned long long int)rrs % (unsigned long long int)rrt;
261    }
262    else DebugMessage(M64MSG_ERROR, "DDIVU: divide by 0");
263    ADD_TO_PC(1);
264 }
265
266 DECLARE_INSTRUCTION(ADD)
267 {
268    rrd32 = rrs32 + rrt32;
269    sign_extended(rrd);
270    ADD_TO_PC(1);
271 }
272
273 DECLARE_INSTRUCTION(ADDU)
274 {
275    rrd32 = rrs32 + rrt32;
276    sign_extended(rrd);
277    ADD_TO_PC(1);
278 }
279
280 DECLARE_INSTRUCTION(SUB)
281 {
282    rrd32 = rrs32 - rrt32;
283    sign_extended(rrd);
284    ADD_TO_PC(1);
285 }
286
287 DECLARE_INSTRUCTION(SUBU)
288 {
289    rrd32 = rrs32 - rrt32;
290    sign_extended(rrd);
291    ADD_TO_PC(1);
292 }
293
294 DECLARE_INSTRUCTION(AND)
295 {
296    rrd = rrs & rrt;
297    ADD_TO_PC(1);
298 }
299
300 DECLARE_INSTRUCTION(OR)
301 {
302    rrd = rrs | rrt;
303    ADD_TO_PC(1);
304 }
305
306 DECLARE_INSTRUCTION(XOR)
307 {
308    rrd = rrs ^ rrt;
309    ADD_TO_PC(1);
310 }
311
312 DECLARE_INSTRUCTION(NOR)
313 {
314    rrd = ~(rrs | rrt);
315    ADD_TO_PC(1);
316 }
317
318 DECLARE_INSTRUCTION(SLT)
319 {
320    if (rrs < rrt) rrd = 1;
321    else rrd = 0;
322    ADD_TO_PC(1);
323 }
324
325 DECLARE_INSTRUCTION(SLTU)
326 {
327    if ((unsigned long long)rrs < (unsigned long long)rrt) 
328      rrd = 1;
329    else rrd = 0;
330    ADD_TO_PC(1);
331 }
332
333 DECLARE_INSTRUCTION(DADD)
334 {
335    rrd = rrs + rrt;
336    ADD_TO_PC(1);
337 }
338
339 DECLARE_INSTRUCTION(DADDU)
340 {
341    rrd = rrs + rrt;
342    ADD_TO_PC(1);
343 }
344
345 DECLARE_INSTRUCTION(DSUB)
346 {
347    rrd = rrs - rrt;
348    ADD_TO_PC(1);
349 }
350
351 DECLARE_INSTRUCTION(DSUBU)
352 {
353    rrd = rrs - rrt;
354    ADD_TO_PC(1);
355 }
356
357 DECLARE_INSTRUCTION(TEQ)
358 {
359    if (rrs == rrt)
360    {
361      DebugMessage(M64MSG_ERROR, "trap exception in TEQ");
362      stop=1;
363    }
364    ADD_TO_PC(1);
365 }
366
367 DECLARE_INSTRUCTION(DSLL)
368 {
369    rrd = rrt << rsa;
370    ADD_TO_PC(1);
371 }
372
373 DECLARE_INSTRUCTION(DSRL)
374 {
375    rrd = (unsigned long long)rrt >> rsa;
376    ADD_TO_PC(1);
377 }
378
379 DECLARE_INSTRUCTION(DSRA)
380 {
381    rrd = rrt >> rsa;
382    ADD_TO_PC(1);
383 }
384
385 DECLARE_INSTRUCTION(DSLL32)
386 {
387    rrd = rrt << (32+rsa);
388    ADD_TO_PC(1);
389 }
390
391 DECLARE_INSTRUCTION(DSRL32)
392 {
393    rrd = (unsigned long long int)rrt >> (32+rsa);
394    ADD_TO_PC(1);
395 }
396
397 DECLARE_INSTRUCTION(DSRA32)
398 {
399    rrd = (signed long long int)rrt >> (32+rsa);
400    ADD_TO_PC(1);
401 }