Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / interpreter_special.def
CommitLineData
451ab91e 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
22DECLARE_INSTRUCTION(NOP)
23{
24 ADD_TO_PC(1);
25}
26
27DECLARE_INSTRUCTION(SLL)
28{
29 rrd32 = (unsigned int)(rrt32) << rsa;
30 sign_extended(rrd);
31 ADD_TO_PC(1);
32}
33
34DECLARE_INSTRUCTION(SRL)
35{
36 rrd32 = (unsigned int)rrt32 >> rsa;
37 sign_extended(rrd);
38 ADD_TO_PC(1);
39}
40
41DECLARE_INSTRUCTION(SRA)
42{
43 rrd32 = (signed int)rrt32 >> rsa;
44 sign_extended(rrd);
45 ADD_TO_PC(1);
46}
47
48DECLARE_INSTRUCTION(SLLV)
49{
50 rrd32 = (unsigned int)(rrt32) << (rrs32&0x1F);
51 sign_extended(rrd);
52 ADD_TO_PC(1);
53}
54
55DECLARE_INSTRUCTION(SRLV)
56{
57 rrd32 = (unsigned int)rrt32 >> (rrs32 & 0x1F);
58 sign_extended(rrd);
59 ADD_TO_PC(1);
60}
61
62DECLARE_INSTRUCTION(SRAV)
63{
64 rrd32 = (signed int)rrt32 >> (rrs32 & 0x1F);
65 sign_extended(rrd);
66 ADD_TO_PC(1);
67}
68
69DECLARE_JUMP(JR, irs32, 1, &reg[0], 0, 0)
70DECLARE_JUMP(JALR, irs32, 1, PC->f.r.rd, 0, 0)
71
72DECLARE_INSTRUCTION(SYSCALL)
73{
74 Cause = 8 << 2;
75 exception_general();
76}
77
78DECLARE_INSTRUCTION(SYNC)
79{
80 ADD_TO_PC(1);
81}
82
83DECLARE_INSTRUCTION(MFHI)
84{
85 rrd = hi;
86 ADD_TO_PC(1);
87}
88
89DECLARE_INSTRUCTION(MTHI)
90{
91 hi = rrs;
92 ADD_TO_PC(1);
93}
94
95DECLARE_INSTRUCTION(MFLO)
96{
97 rrd = lo;
98 ADD_TO_PC(1);
99}
100
101DECLARE_INSTRUCTION(MTLO)
102{
103 lo = rrs;
104 ADD_TO_PC(1);
105}
106
107DECLARE_INSTRUCTION(DSLLV)
108{
109 rrd = rrt << (rrs32&0x3F);
110 ADD_TO_PC(1);
111}
112
113DECLARE_INSTRUCTION(DSRLV)
114{
115 rrd = (unsigned long long)rrt >> (rrs32 & 0x3F);
116 ADD_TO_PC(1);
117}
118
119DECLARE_INSTRUCTION(DSRAV)
120{
121 rrd = (long long)rrt >> (rrs32 & 0x3F);
122 ADD_TO_PC(1);
123}
124
125DECLARE_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
135DECLARE_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
145DECLARE_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
158DECLARE_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
171DECLARE_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
217DECLARE_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
244DECLARE_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
255DECLARE_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
266DECLARE_INSTRUCTION(ADD)
267{
268 rrd32 = rrs32 + rrt32;
269 sign_extended(rrd);
270 ADD_TO_PC(1);
271}
272
273DECLARE_INSTRUCTION(ADDU)
274{
275 rrd32 = rrs32 + rrt32;
276 sign_extended(rrd);
277 ADD_TO_PC(1);
278}
279
280DECLARE_INSTRUCTION(SUB)
281{
282 rrd32 = rrs32 - rrt32;
283 sign_extended(rrd);
284 ADD_TO_PC(1);
285}
286
287DECLARE_INSTRUCTION(SUBU)
288{
289 rrd32 = rrs32 - rrt32;
290 sign_extended(rrd);
291 ADD_TO_PC(1);
292}
293
294DECLARE_INSTRUCTION(AND)
295{
296 rrd = rrs & rrt;
297 ADD_TO_PC(1);
298}
299
300DECLARE_INSTRUCTION(OR)
301{
302 rrd = rrs | rrt;
303 ADD_TO_PC(1);
304}
305
306DECLARE_INSTRUCTION(XOR)
307{
308 rrd = rrs ^ rrt;
309 ADD_TO_PC(1);
310}
311
312DECLARE_INSTRUCTION(NOR)
313{
314 rrd = ~(rrs | rrt);
315 ADD_TO_PC(1);
316}
317
318DECLARE_INSTRUCTION(SLT)
319{
320 if (rrs < rrt) rrd = 1;
321 else rrd = 0;
322 ADD_TO_PC(1);
323}
324
325DECLARE_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
333DECLARE_INSTRUCTION(DADD)
334{
335 rrd = rrs + rrt;
336 ADD_TO_PC(1);
337}
338
339DECLARE_INSTRUCTION(DADDU)
340{
341 rrd = rrs + rrt;
342 ADD_TO_PC(1);
343}
344
345DECLARE_INSTRUCTION(DSUB)
346{
347 rrd = rrs - rrt;
348 ADD_TO_PC(1);
349}
350
351DECLARE_INSTRUCTION(DSUBU)
352{
353 rrd = rrs - rrt;
354 ADD_TO_PC(1);
355}
356
357DECLARE_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
367DECLARE_INSTRUCTION(DSLL)
368{
369 rrd = rrt << rsa;
370 ADD_TO_PC(1);
371}
372
373DECLARE_INSTRUCTION(DSRL)
374{
375 rrd = (unsigned long long)rrt >> rsa;
376 ADD_TO_PC(1);
377}
378
379DECLARE_INSTRUCTION(DSRA)
380{
381 rrd = rrt >> rsa;
382 ADD_TO_PC(1);
383}
384
385DECLARE_INSTRUCTION(DSLL32)
386{
387 rrd = rrt << (32+rsa);
388 ADD_TO_PC(1);
389}
390
391DECLARE_INSTRUCTION(DSRL32)
392{
393 rrd = (unsigned long long int)rrt >> (32+rsa);
394 ADD_TO_PC(1);
395}
396
397DECLARE_INSTRUCTION(DSRA32)
398{
399 rrd = (signed long long int)rrt >> (32+rsa);
400 ADD_TO_PC(1);
401}