/[pcsx2_0.9.7]/trunk/pcsx2/MMI.cpp
ViewVC logotype

Contents of /trunk/pcsx2/MMI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (10 years, 2 months ago) by william
File size: 41619 byte(s)
Auto Commited Import of: pcsx2-0.9.7-r3738-debug in ./trunk
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16
17 #include "PrecompiledHeader.h"
18 #include "Common.h"
19
20 namespace R5900 {
21 namespace Interpreter {
22 namespace OpcodeImpl {
23
24 /////////////////////////////////////////////////////////////////
25 // Non-MMI Instructions!
26 //
27 // Several instructions in the MMI opcode class are actually just regular
28 // instructions which have been added to "extend" the R5900's instruction
29 // set. They're here, because if not here they'd be homeless.
30 // - The Pcsx2 team, doing their part to fight homelessness
31
32 void MADD() {
33 s64 temp = (s64)((u64)cpuRegs.LO.UL[0] | ((u64)cpuRegs.HI.UL[0] << 32)) +
34 ((s64)cpuRegs.GPR.r[_Rs_].SL[0] * (s64)cpuRegs.GPR.r[_Rt_].SL[0]);
35
36 cpuRegs.LO.SD[0] = (s32)(temp & 0xffffffff);
37 cpuRegs.HI.SD[0] = (s32)(temp >> 32);
38
39 if (_Rd_) cpuRegs.GPR.r[_Rd_].SD[0] = cpuRegs.LO.SD[0];
40 }
41
42 void MADDU() {
43 u64 tempu = (u64)((u64)cpuRegs.LO.UL[0] | ((u64)cpuRegs.HI.UL[0] << 32)) +
44 ((u64)cpuRegs.GPR.r[_Rs_].UL[0] * (u64)cpuRegs.GPR.r[_Rt_].UL[0]);
45
46 cpuRegs.LO.SD[0] = (s32)(tempu & 0xffffffff);
47 cpuRegs.HI.SD[0] = (s32)(tempu >> 32);
48
49 if (_Rd_) cpuRegs.GPR.r[_Rd_].SD[0] = cpuRegs.LO.SD[0];
50 }
51
52 void MADD1() {
53 s64 temp = (s64)((u64)cpuRegs.LO.UL[2] | ((u64)cpuRegs.HI.UL[2] << 32)) +
54 ((s64)cpuRegs.GPR.r[_Rs_].SL[0] * (s64)cpuRegs.GPR.r[_Rt_].SL[0]);
55
56 cpuRegs.LO.SD[1] = (s32)(temp & 0xffffffff);
57 cpuRegs.HI.SD[1] = (s32)(temp >> 32);
58
59 if (_Rd_) cpuRegs.GPR.r[_Rd_].SD[0] = cpuRegs.LO.SD[1];
60 }
61
62 void MADDU1() {
63 u64 tempu = (u64)((u64)cpuRegs.LO.UL[2] | ((u64)cpuRegs.HI.UL[2] << 32)) +
64 ((u64)cpuRegs.GPR.r[_Rs_].UL[0] * (u64)cpuRegs.GPR.r[_Rt_].UL[0]);
65
66 cpuRegs.LO.SD[1] = (s32)(tempu & 0xffffffff);
67 cpuRegs.HI.SD[1] = (s32)(tempu >> 32);
68
69 if (_Rd_) cpuRegs.GPR.r[_Rd_].SD[0] = cpuRegs.LO.SD[1];
70 }
71
72 void MFHI1() {
73 if (!_Rd_) return;
74 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.HI.UD[1];
75 }
76
77 void MFLO1() {
78 if (!_Rd_) return;
79 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.LO.UD[1];
80 }
81
82 void MTHI1() {
83 cpuRegs.HI.UD[1] = cpuRegs.GPR.r[_Rs_].UD[0];
84 }
85
86 void MTLO1() {
87 cpuRegs.LO.UD[1] = cpuRegs.GPR.r[_Rs_].UD[0];
88 }
89
90 void MULT1() {
91 s64 temp = (s64)cpuRegs.GPR.r[_Rs_].SL[0] * cpuRegs.GPR.r[_Rt_].SL[0];
92
93 // Sign-extend into 64 bits:
94 cpuRegs.LO.SD[1] = (s32)(temp & 0xffffffff);
95 cpuRegs.HI.SD[1] = (s32)(temp >> 32);
96
97 if (_Rd_) cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.LO.UD[1];
98 }
99
100 void MULTU1() {
101 u64 tempu = (u64)cpuRegs.GPR.r[_Rs_].UL[0] * cpuRegs.GPR.r[_Rt_].UL[0];
102
103 // According to docs, sign-extend into 64 bits even though it's an unsigned mult.
104 cpuRegs.LO.SD[1] = (s32)(tempu & 0xffffffff);
105 cpuRegs.HI.SD[1] = (s32)(tempu >> 32);
106
107 if (_Rd_) cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.LO.UD[1];
108 }
109
110 void DIV1() {
111 if (cpuRegs.GPR.r[_Rs_].UL[0] == 0x80000000 && cpuRegs.GPR.r[_Rt_].UL[0] == 0xffffffff)
112 {
113 cpuRegs.LO.SD[1] = (s32)0x80000000;
114 cpuRegs.HI.SD[1] = (s32)0x0;
115 }
116 else if (cpuRegs.GPR.r[_Rt_].SL[0] != 0)
117 {
118 cpuRegs.LO.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0] / cpuRegs.GPR.r[_Rt_].SL[0];
119 cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0] % cpuRegs.GPR.r[_Rt_].SL[0];
120 }
121 else
122 {
123 cpuRegs.LO.SD[1] = (cpuRegs.GPR.r[_Rs_].SL[0] < 0) ? 1 : -1;
124 cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0];
125 }
126 }
127
128 void DIVU1()
129 {
130 if (cpuRegs.GPR.r[_Rt_].UL[0] != 0)
131 {
132 // note: DIVU has no sign extension when assigning back to 64 bits
133 // note 2: reference material strongly disagrees. (air)
134 cpuRegs.LO.SD[1] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] / cpuRegs.GPR.r[_Rt_].UL[0]);
135 cpuRegs.HI.SD[1] = (s32)(cpuRegs.GPR.r[_Rs_].UL[0] % cpuRegs.GPR.r[_Rt_].UL[0]);
136 }
137 else
138 {
139 cpuRegs.LO.SD[1] = -1;
140 cpuRegs.HI.SD[1] = cpuRegs.GPR.r[_Rs_].SL[0];
141 }
142 }
143
144 namespace MMI {
145
146 //*****************MMI OPCODES*********************************
147
148 static __fi void _PLZCW(int n)
149 {
150 // This function counts the number of "like" bits in the source register, starting
151 // with the MSB and working its way down, and returns the result MINUS ONE.
152 // So 0xff00 would return 7, not 8.
153
154 int c = 0;
155 s32 i = cpuRegs.GPR.r[_Rs_].SL[n];
156
157 // Negate the source based on the sign bit. This allows us to use a simple
158 // unified bit test of the MSB for either condition.
159 if( i >= 0 ) i = ~i;
160
161 // shift first, compare, then increment. This excludes the sign bit from our final count.
162 while( i <<= 1, i < 0 ) c++;
163
164 cpuRegs.GPR.r[_Rd_].UL[n] = c;
165 }
166
167 void PLZCW() {
168 if (!_Rd_) return;
169
170 _PLZCW (0);
171 _PLZCW (1);
172 }
173
174 __fi void PMFHL_CLAMP(u16& dst, s32 src)
175 {
176 if (src > 0x7fff) dst = 0x7fff;
177 else if (src < -0x8000) dst = 0x8000;
178 else dst = (u16)src;
179 }
180
181 void PMFHL() {
182 if (!_Rd_) return;
183
184 switch (_Sa_) {
185 case 0x00: // LW
186 cpuRegs.GPR.r[_Rd_].UL[0] = cpuRegs.LO.UL[0];
187 cpuRegs.GPR.r[_Rd_].UL[1] = cpuRegs.HI.UL[0];
188 cpuRegs.GPR.r[_Rd_].UL[2] = cpuRegs.LO.UL[2];
189 cpuRegs.GPR.r[_Rd_].UL[3] = cpuRegs.HI.UL[2];
190 break;
191
192 case 0x01: // UW
193 cpuRegs.GPR.r[_Rd_].UL[0] = cpuRegs.LO.UL[1];
194 cpuRegs.GPR.r[_Rd_].UL[1] = cpuRegs.HI.UL[1];
195 cpuRegs.GPR.r[_Rd_].UL[2] = cpuRegs.LO.UL[3];
196 cpuRegs.GPR.r[_Rd_].UL[3] = cpuRegs.HI.UL[3];
197 break;
198
199 case 0x02: // SLW
200 {
201 s64 TempS64 = ((u64)cpuRegs.HI.UL[0] << 32) | (u64)cpuRegs.LO.UL[0];
202 if (TempS64 >= 0x000000007fffffffLL) {
203 cpuRegs.GPR.r[_Rd_].UD[0] = 0x000000007fffffffLL;
204 } else if (TempS64 <= 0xffffffff80000000LL) {
205 cpuRegs.GPR.r[_Rd_].UD[0] = 0xffffffff80000000LL;
206 } else {
207 cpuRegs.GPR.r[_Rd_].UD[0] = (s64)cpuRegs.LO.SL[0];
208 }
209
210 TempS64 = ((u64)cpuRegs.HI.UL[2] << 32) | (u64)cpuRegs.LO.UL[2];
211 if (TempS64 >= 0x000000007fffffffLL) {
212 cpuRegs.GPR.r[_Rd_].UD[1] = 0x000000007fffffffLL;
213 } else if (TempS64 <= 0xffffffff80000000LL) {
214 cpuRegs.GPR.r[_Rd_].UD[1] = 0xffffffff80000000LL;
215 } else {
216 cpuRegs.GPR.r[_Rd_].UD[1] = (s64)cpuRegs.LO.SL[2];
217 }
218 }
219 break;
220
221 case 0x03: // LH
222 cpuRegs.GPR.r[_Rd_].US[0] = cpuRegs.LO.US[0];
223 cpuRegs.GPR.r[_Rd_].US[1] = cpuRegs.LO.US[2];
224 cpuRegs.GPR.r[_Rd_].US[2] = cpuRegs.HI.US[0];
225 cpuRegs.GPR.r[_Rd_].US[3] = cpuRegs.HI.US[2];
226 cpuRegs.GPR.r[_Rd_].US[4] = cpuRegs.LO.US[4];
227 cpuRegs.GPR.r[_Rd_].US[5] = cpuRegs.LO.US[6];
228 cpuRegs.GPR.r[_Rd_].US[6] = cpuRegs.HI.US[4];
229 cpuRegs.GPR.r[_Rd_].US[7] = cpuRegs.HI.US[6];
230 break;
231
232 case 0x04: // SH
233 PMFHL_CLAMP(cpuRegs.GPR.r[_Rd_].US[0], cpuRegs.LO.UL[0]);
234 PMFHL_CLAMP(cpuRegs.GPR.r[_Rd_].US[1], cpuRegs.LO.UL[1]);
235 PMFHL_CLAMP(cpuRegs.GPR.r[_Rd_].US[2], cpuRegs.HI.UL[0]);
236 PMFHL_CLAMP(cpuRegs.GPR.r[_Rd_].US[3], cpuRegs.HI.UL[1]);
237 PMFHL_CLAMP(cpuRegs.GPR.r[_Rd_].US[4], cpuRegs.LO.UL[2]);
238 PMFHL_CLAMP(cpuRegs.GPR.r[_Rd_].US[5], cpuRegs.LO.UL[3]);
239 PMFHL_CLAMP(cpuRegs.GPR.r[_Rd_].US[6], cpuRegs.HI.UL[2]);
240 PMFHL_CLAMP(cpuRegs.GPR.r[_Rd_].US[7], cpuRegs.HI.UL[3]);
241 break;
242 }
243 }
244
245 void PMTHL() {
246 if (_Sa_ != 0) return;
247
248 cpuRegs.LO.UL[0] = cpuRegs.GPR.r[_Rs_].UL[0];
249 cpuRegs.HI.UL[0] = cpuRegs.GPR.r[_Rs_].UL[1];
250 cpuRegs.LO.UL[2] = cpuRegs.GPR.r[_Rs_].UL[2];
251 cpuRegs.HI.UL[2] = cpuRegs.GPR.r[_Rs_].UL[3];
252 }
253
254 static __fi void _PSLLH(int n)
255 {
256 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rt_].US[n] << ( _Sa_ & 0xf );
257 }
258
259 void PSLLH() {
260 if (!_Rd_) return;
261
262 _PSLLH(0); _PSLLH(1); _PSLLH(2); _PSLLH(3);
263 _PSLLH(4); _PSLLH(5); _PSLLH(6); _PSLLH(7);
264 }
265
266 static __fi void _PSRLH(int n)
267 {
268 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rt_].US[n] >> ( _Sa_ & 0xf );
269 }
270
271 void PSRLH () {
272 if (!_Rd_) return;
273
274 _PSRLH(0); _PSRLH(1); _PSRLH(2); _PSRLH(3);
275 _PSRLH(4); _PSRLH(5); _PSRLH(6); _PSRLH(7);
276 }
277
278 static __fi void _PSRAH(int n)
279 {
280 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rt_].SS[n] >> ( _Sa_ & 0xf );
281 }
282
283 void PSRAH() {
284 if (!_Rd_) return;
285
286 _PSRAH(0); _PSRAH(1); _PSRAH(2); _PSRAH(3);
287 _PSRAH(4); _PSRAH(5); _PSRAH(6); _PSRAH(7);
288 }
289
290 static __fi void _PSLLW(int n)
291 {
292 cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rt_].UL[n] << _Sa_;
293 }
294
295 void PSLLW() {
296 if (!_Rd_) return;
297
298 _PSLLW(0); _PSLLW(1); _PSLLW(2); _PSLLW(3);
299 }
300
301 static __fi void _PSRLW(int n)
302 {
303 cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rt_].UL[n] >> _Sa_;
304 }
305
306 void PSRLW() {
307 if (!_Rd_) return;
308
309 _PSRLW(0); _PSRLW(1); _PSRLW(2); _PSRLW(3);
310 }
311
312 static __fi void _PSRAW(int n)
313 {
314 cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rt_].SL[n] >> _Sa_;
315 }
316
317 void PSRAW() {
318 if (!_Rd_) return;
319
320 _PSRAW(0); _PSRAW(1); _PSRAW(2); _PSRAW(3);
321 }
322
323 //*****************END OF MMI OPCODES**************************
324 //*************************MMI0 OPCODES************************
325
326 static __fi void _PADDW(int n)
327 {
328 cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rs_].UL[n] + cpuRegs.GPR.r[_Rt_].UL[n];
329 }
330
331 void PADDW() {
332 if (!_Rd_) return;
333
334 _PADDW(0); _PADDW(1); _PADDW(2); _PADDW(3);
335 }
336
337 static __fi void _PSUBW(int n)
338 {
339 cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rs_].UL[n] - cpuRegs.GPR.r[_Rt_].UL[n];
340 }
341
342 void PSUBW() {
343 if (!_Rd_) return;
344
345 _PSUBW(0); _PSUBW(1); _PSUBW(2); _PSUBW(3);
346 }
347
348 static __fi void _PCGTW(int n)
349 {
350 if (cpuRegs.GPR.r[_Rs_].SL[n] > cpuRegs.GPR.r[_Rt_].SL[n])
351 cpuRegs.GPR.r[_Rd_].UL[n] = 0xFFFFFFFF;
352 else
353 cpuRegs.GPR.r[_Rd_].UL[n] = 0x00000000;
354 }
355
356 void PCGTW() {
357 if (!_Rd_) return;
358
359 _PCGTW(0); _PCGTW(1); _PCGTW(2); _PCGTW(3);
360 }
361
362 static __fi void _PMAXW(int n)
363 {
364 if (cpuRegs.GPR.r[_Rs_].SL[n] > cpuRegs.GPR.r[_Rt_].SL[n])
365 cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rs_].UL[n];
366 else
367 cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rt_].UL[n];
368 }
369
370 void PMAXW() {
371 if (!_Rd_) return;
372
373 _PMAXW(0); _PMAXW(1); _PMAXW(2); _PMAXW(3);
374 }
375
376 static __fi void _PADDH(int n)
377 {
378 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rs_].US[n] + cpuRegs.GPR.r[_Rt_].US[n];
379 }
380
381 void PADDH() {
382 if (!_Rd_) return;
383
384 _PADDH(0); _PADDH(1); _PADDH(2); _PADDH(3);
385 _PADDH(4); _PADDH(5); _PADDH(6); _PADDH(7);
386 }
387
388 static __fi void _PSUBH(int n)
389 {
390 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rs_].US[n] - cpuRegs.GPR.r[_Rt_].US[n];
391 }
392
393 void PSUBH() {
394 if (!_Rd_) return;
395
396 _PSUBH(0); _PSUBH(1); _PSUBH(2); _PSUBH(3);
397 _PSUBH(4); _PSUBH(5); _PSUBH(6); _PSUBH(7);
398 }
399
400 static __fi void _PCGTH(int n)
401 {
402 if (cpuRegs.GPR.r[_Rs_].SS[n] > cpuRegs.GPR.r[_Rt_].SS[n])
403 cpuRegs.GPR.r[_Rd_].US[n] = 0xFFFF;
404 else
405 cpuRegs.GPR.r[_Rd_].US[n] = 0x0000;
406 }
407
408 void PCGTH() {
409 if (!_Rd_) return;
410
411 _PCGTH(0); _PCGTH(1); _PCGTH(2); _PCGTH(3);
412 _PCGTH(4); _PCGTH(5); _PCGTH(6); _PCGTH(7);
413 }
414
415 static __fi void _PMAXH(int n)
416 {
417 if (cpuRegs.GPR.r[_Rs_].SS[n] > cpuRegs.GPR.r[_Rt_].SS[n])
418 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rs_].US[n];
419 else
420 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rt_].US[n];
421 }
422
423 void PMAXH() {
424 if (!_Rd_) return;
425
426 _PMAXH(0); _PMAXH(1); _PMAXH(2); _PMAXH(3);
427 _PMAXH(4); _PMAXH(5); _PMAXH(6); _PMAXH(7);
428 }
429
430 static __fi void _PADDB(int n)
431 {
432 cpuRegs.GPR.r[_Rd_].SC[n] = cpuRegs.GPR.r[_Rs_].SC[n] + cpuRegs.GPR.r[_Rt_].SC[n];
433 }
434
435 void PADDB() {
436 int i;
437 if (!_Rd_) return;
438
439 for( i=0; i<16; i++ )
440 _PADDB( i );
441 }
442
443 static __fi void _PSUBB(int n)
444 {
445 cpuRegs.GPR.r[_Rd_].SC[n] = cpuRegs.GPR.r[_Rs_].SC[n] - cpuRegs.GPR.r[_Rt_].SC[n];
446 }
447
448 void PSUBB() {
449 int i;
450 if (!_Rd_) return;
451
452 for( i=0; i<16; i++ )
453 _PSUBB( i );
454 }
455
456 static __fi void _PCGTB(int n)
457 {
458 if (cpuRegs.GPR.r[_Rs_].SC[n] > cpuRegs.GPR.r[_Rt_].SC[n])
459 cpuRegs.GPR.r[_Rd_].UC[n] = 0xFF;
460 else
461 cpuRegs.GPR.r[_Rd_].UC[n] = 0x00;
462 }
463
464 void PCGTB() {
465 int i;
466 if (!_Rd_) return;
467
468 for( i=0; i<16; i++ )
469 _PCGTB( i );
470 }
471
472 static __fi void _PADDSW(int n)
473 {
474 s64 sTemp64;
475
476 sTemp64 = (s64)cpuRegs.GPR.r[_Rs_].SL[n] + (s64)cpuRegs.GPR.r[_Rt_].SL[n];
477 if (sTemp64 > 0x7FFFFFFF)
478 cpuRegs.GPR.r[_Rd_].UL[n] = 0x7FFFFFFF;
479 else if ((sTemp64 < (s32)0x80000000) )
480 cpuRegs.GPR.r[_Rd_].UL[n] = 0x80000000LL;
481 else
482 cpuRegs.GPR.r[_Rd_].UL[n] = (s32)sTemp64;
483 }
484
485 void PADDSW() {
486 if (!_Rd_) return;
487
488 _PADDSW(0); _PADDSW(1); _PADDSW(2); _PADDSW(3);
489 }
490
491 static __fi void _PSUBSW(int n)
492 {
493 s64 sTemp64;
494
495 sTemp64 = (s64)cpuRegs.GPR.r[_Rs_].SL[n] - (s64)cpuRegs.GPR.r[_Rt_].SL[n];
496
497 if (sTemp64 >= 0x7FFFFFFF)
498 cpuRegs.GPR.r[_Rd_].UL[n] = 0x7FFFFFFF;
499 else if ((sTemp64 < (s32)0x80000000))
500 cpuRegs.GPR.r[_Rd_].UL[n] = 0x80000000;
501 else
502 cpuRegs.GPR.r[_Rd_].UL[n] = (s32)sTemp64;
503 }
504
505 void PSUBSW() {
506 if (!_Rd_) return;
507
508 _PSUBSW(0);
509 _PSUBSW(1);
510 _PSUBSW(2);
511 _PSUBSW(3);
512 }
513
514 void PEXTLW() {
515 GPR_reg Rs, Rt;
516
517 if (!_Rd_) return;
518
519 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
520 cpuRegs.GPR.r[_Rd_].UL[0] = Rt.UL[0];
521 cpuRegs.GPR.r[_Rd_].UL[1] = Rs.UL[0];
522 cpuRegs.GPR.r[_Rd_].UL[2] = Rt.UL[1];
523 cpuRegs.GPR.r[_Rd_].UL[3] = Rs.UL[1];
524 }
525
526 void PPACW() {
527 GPR_reg Rs, Rt;
528
529 if (!_Rd_) return;
530
531 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
532 cpuRegs.GPR.r[_Rd_].UL[0] = Rt.UL[0];
533 cpuRegs.GPR.r[_Rd_].UL[1] = Rt.UL[2];
534 cpuRegs.GPR.r[_Rd_].UL[2] = Rs.UL[0];
535 cpuRegs.GPR.r[_Rd_].UL[3] = Rs.UL[2];
536 }
537
538 __fi void _PADDSH(int n)
539 {
540 s32 sTemp32;
541 sTemp32 = (s32)cpuRegs.GPR.r[_Rs_].SS[n] + (s32)cpuRegs.GPR.r[_Rt_].SS[n];
542
543 if (sTemp32 > 0x7FFF)
544 cpuRegs.GPR.r[_Rd_].US[n] = 0x7FFF;
545 else if ((sTemp32 < (s32)0xffff8000) )
546 cpuRegs.GPR.r[_Rd_].US[n] = 0x8000;
547 else
548 cpuRegs.GPR.r[_Rd_].US[n] = (s16)sTemp32;
549 }
550
551 void PADDSH() {
552 if (!_Rd_) return;
553
554 _PADDSH(0); _PADDSH(1); _PADDSH(2); _PADDSH(3);
555 _PADDSH(4); _PADDSH(5); _PADDSH(6); _PADDSH(7);
556 }
557
558 __fi void _PSUBSH(int n)
559 {
560 s32 sTemp32;
561 sTemp32 = (s32)cpuRegs.GPR.r[_Rs_].SS[n] - (s32)cpuRegs.GPR.r[_Rt_].SS[n];
562
563 if (sTemp32 >= 0x7FFF)
564 cpuRegs.GPR.r[_Rd_].US[n] = 0x7FFF;
565 else if ((sTemp32 < (s32)0xffff8000) )
566 cpuRegs.GPR.r[_Rd_].US[n] = 0x8000;
567 else
568 cpuRegs.GPR.r[_Rd_].US[n] = (s16)sTemp32;
569 }
570
571 void PSUBSH() {
572 if (!_Rd_) return;
573
574 _PSUBSH(0); _PSUBSH(1); _PSUBSH(2); _PSUBSH(3);
575 _PSUBSH(4); _PSUBSH(5); _PSUBSH(6); _PSUBSH(7);
576 }
577
578 void PEXTLH() {
579 GPR_reg Rs, Rt;
580
581 if (!_Rd_) return;
582
583 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
584 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[0];
585 cpuRegs.GPR.r[_Rd_].US[1] = Rs.US[0];
586 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[1];
587 cpuRegs.GPR.r[_Rd_].US[3] = Rs.US[1];
588 cpuRegs.GPR.r[_Rd_].US[4] = Rt.US[2];
589 cpuRegs.GPR.r[_Rd_].US[5] = Rs.US[2];
590 cpuRegs.GPR.r[_Rd_].US[6] = Rt.US[3];
591 cpuRegs.GPR.r[_Rd_].US[7] = Rs.US[3];
592 }
593
594 void PPACH() {
595 GPR_reg Rs, Rt;
596
597 if (!_Rd_) return;
598
599 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
600 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[0];
601 cpuRegs.GPR.r[_Rd_].US[1] = Rt.US[2];
602 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[4];
603 cpuRegs.GPR.r[_Rd_].US[3] = Rt.US[6];
604 cpuRegs.GPR.r[_Rd_].US[4] = Rs.US[0];
605 cpuRegs.GPR.r[_Rd_].US[5] = Rs.US[2];
606 cpuRegs.GPR.r[_Rd_].US[6] = Rs.US[4];
607 cpuRegs.GPR.r[_Rd_].US[7] = Rs.US[6];
608 }
609
610 __fi void _PADDSB(int n)
611 {
612 s16 sTemp16;
613 sTemp16 = (s16)cpuRegs.GPR.r[_Rs_].SC[n] + (s16)cpuRegs.GPR.r[_Rt_].SC[n];
614
615 if (sTemp16 > 0x7F)
616 cpuRegs.GPR.r[_Rd_].UC[n] = 0x7F;
617 else if (sTemp16 < (s16)0xff80)
618 cpuRegs.GPR.r[_Rd_].UC[n] = 0x80;
619 else
620 cpuRegs.GPR.r[_Rd_].UC[n] = (s8)sTemp16;
621 }
622
623 void PADDSB() {
624 int i;
625 if (!_Rd_) return;
626
627 for( i=0; i<16; i++ )
628 _PADDSB(i);
629 }
630
631 static __fi void _PSUBSB( u8 n )
632 {
633 s16 sTemp16;
634 sTemp16 = (s16)cpuRegs.GPR.r[_Rs_].SC[n] - (s16)cpuRegs.GPR.r[_Rt_].SC[n];
635
636 if (sTemp16 >= 0x7F)
637 cpuRegs.GPR.r[_Rd_].UC[n] = 0x7F;
638 else if (sTemp16 <= (s16)0xff80)
639 cpuRegs.GPR.r[_Rd_].UC[n] = 0x80;
640 else
641 cpuRegs.GPR.r[_Rd_].UC[n] = (s8)sTemp16;
642 }
643
644 void PSUBSB() {
645 int i;
646 if (!_Rd_) return;
647
648 for( i=0; i<16; i++ )
649 _PSUBSB(i);
650 }
651
652 void PEXTLB() {
653 GPR_reg Rs, Rt;
654
655 if (!_Rd_) return;
656
657 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
658 cpuRegs.GPR.r[_Rd_].UC[0] = Rt.UC[0];
659 cpuRegs.GPR.r[_Rd_].UC[1] = Rs.UC[0];
660 cpuRegs.GPR.r[_Rd_].UC[2] = Rt.UC[1];
661 cpuRegs.GPR.r[_Rd_].UC[3] = Rs.UC[1];
662
663 cpuRegs.GPR.r[_Rd_].UC[4] = Rt.UC[2];
664 cpuRegs.GPR.r[_Rd_].UC[5] = Rs.UC[2];
665 cpuRegs.GPR.r[_Rd_].UC[6] = Rt.UC[3];
666 cpuRegs.GPR.r[_Rd_].UC[7] = Rs.UC[3];
667
668 cpuRegs.GPR.r[_Rd_].UC[8] = Rt.UC[4];
669 cpuRegs.GPR.r[_Rd_].UC[9] = Rs.UC[4];
670 cpuRegs.GPR.r[_Rd_].UC[10] = Rt.UC[5];
671 cpuRegs.GPR.r[_Rd_].UC[11] = Rs.UC[5];
672
673 cpuRegs.GPR.r[_Rd_].UC[12] = Rt.UC[6];
674 cpuRegs.GPR.r[_Rd_].UC[13] = Rs.UC[6];
675 cpuRegs.GPR.r[_Rd_].UC[14] = Rt.UC[7];
676 cpuRegs.GPR.r[_Rd_].UC[15] = Rs.UC[7];
677 }
678
679 void PPACB() {
680 GPR_reg Rs, Rt;
681
682 if (!_Rd_) return;
683
684 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
685 cpuRegs.GPR.r[_Rd_].UC[0] = Rt.UC[0];
686 cpuRegs.GPR.r[_Rd_].UC[1] = Rt.UC[2];
687 cpuRegs.GPR.r[_Rd_].UC[2] = Rt.UC[4];
688 cpuRegs.GPR.r[_Rd_].UC[3] = Rt.UC[6];
689
690 cpuRegs.GPR.r[_Rd_].UC[4] = Rt.UC[8];
691 cpuRegs.GPR.r[_Rd_].UC[5] = Rt.UC[10];
692 cpuRegs.GPR.r[_Rd_].UC[6] = Rt.UC[12];
693 cpuRegs.GPR.r[_Rd_].UC[7] = Rt.UC[14];
694
695 cpuRegs.GPR.r[_Rd_].UC[8] = Rs.UC[0];
696 cpuRegs.GPR.r[_Rd_].UC[9] = Rs.UC[2];
697 cpuRegs.GPR.r[_Rd_].UC[10] = Rs.UC[4];
698 cpuRegs.GPR.r[_Rd_].UC[11] = Rs.UC[6];
699
700 cpuRegs.GPR.r[_Rd_].UC[12] = Rs.UC[8];
701 cpuRegs.GPR.r[_Rd_].UC[13] = Rs.UC[10];
702 cpuRegs.GPR.r[_Rd_].UC[14] = Rs.UC[12];
703 cpuRegs.GPR.r[_Rd_].UC[15] = Rs.UC[14];
704 }
705
706 __fi void _PEXT5(int n)
707 {
708 cpuRegs.GPR.r[_Rd_].UL[n] =
709 ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x0000001F) << 3) |
710 ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x000003E0) << 6) |
711 ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x00007C00) << 9) |
712 ((cpuRegs.GPR.r[_Rt_].UL[n] & 0x00008000) << 16);
713 }
714
715 void PEXT5() {
716 if (!_Rd_) return;
717
718 _PEXT5(0); _PEXT5(1); _PEXT5(2); _PEXT5(3);
719 }
720
721 __fi void _PPAC5(int n)
722 {
723 cpuRegs.GPR.r[_Rd_].UL[n] =
724 ((cpuRegs.GPR.r[_Rt_].UL[n] >> 3) & 0x0000001F) |
725 ((cpuRegs.GPR.r[_Rt_].UL[n] >> 6) & 0x000003E0) |
726 ((cpuRegs.GPR.r[_Rt_].UL[n] >> 9) & 0x00007C00) |
727 ((cpuRegs.GPR.r[_Rt_].UL[n] >> 16) & 0x00008000);
728 }
729
730 void PPAC5() {
731 if (!_Rd_) return;
732
733 _PPAC5(0); _PPAC5(1); _PPAC5(2); _PPAC5(3);
734 }
735
736 //***END OF MMI0 OPCODES******************************************
737 //**********MMI1 OPCODES**************************************
738
739 static __fi void _PABSW(int n)
740 {
741 if (cpuRegs.GPR.r[_Rt_].UL[n] == 0x80000000)
742 cpuRegs.GPR.r[_Rd_].UL[n] = 0x7fffffff; //clamp
743 else if (cpuRegs.GPR.r[_Rt_].SL[n] < 0)
744 cpuRegs.GPR.r[_Rd_].UL[n] = - cpuRegs.GPR.r[_Rt_].SL[n];
745 else
746 cpuRegs.GPR.r[_Rd_].UL[n] = cpuRegs.GPR.r[_Rt_].SL[n];
747 }
748
749 void PABSW() {
750 if (!_Rd_) return;
751
752 _PABSW(0); _PABSW(1); _PABSW(2); _PABSW(3);
753 }
754
755 static __fi void _PCEQW(int n)
756 {
757 if (cpuRegs.GPR.r[_Rs_].UL[n] == cpuRegs.GPR.r[_Rt_].UL[n])
758 cpuRegs.GPR.r[_Rd_].UL[n] = 0xFFFFFFFF;
759 else
760 cpuRegs.GPR.r[_Rd_].UL[n] = 0x00000000;
761 }
762
763 void PCEQW() {
764 if (!_Rd_) return;
765
766 _PCEQW(0); _PCEQW(1); _PCEQW(2); _PCEQW(3);
767 }
768
769 static __fi void _PMINW( u8 n )
770 {
771 if (cpuRegs.GPR.r[_Rs_].SL[n] < cpuRegs.GPR.r[_Rt_].SL[n])
772 cpuRegs.GPR.r[_Rd_].SL[n] = cpuRegs.GPR.r[_Rs_].SL[n];
773 else
774 cpuRegs.GPR.r[_Rd_].SL[n] = cpuRegs.GPR.r[_Rt_].SL[n];
775 }
776
777 void PMINW() {
778 if (!_Rd_) return;
779
780 _PMINW(0); _PMINW(1); _PMINW(2); _PMINW(3);
781 }
782
783 void PADSBH() {
784 if (!_Rd_) return;
785
786 _PSUBH(0); _PSUBH(1); _PSUBH(2); _PSUBH(3);
787 _PADDH(4); _PADDH(5); _PADDH(6); _PADDH(7);
788 }
789
790 static __fi void _PABSH(int n)
791 {
792 if (cpuRegs.GPR.r[_Rt_].US[n] == 0x8000)
793 cpuRegs.GPR.r[_Rd_].US[n] = 0x7fff; //clamp
794 else if (cpuRegs.GPR.r[_Rt_].SS[n] < 0)
795 cpuRegs.GPR.r[_Rd_].US[n] = - cpuRegs.GPR.r[_Rt_].SS[n];
796 else
797 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rt_].SS[n];
798 }
799
800 void PABSH() {
801 if (!_Rd_) return;
802
803 _PABSH(0); _PABSH(1); _PABSH(2); _PABSH(3);
804 _PABSH(4); _PABSH(5); _PABSH(6); _PABSH(7);
805 }
806
807 static __fi void _PCEQH( u8 n )
808 {
809 if (cpuRegs.GPR.r[_Rs_].US[n] == cpuRegs.GPR.r[_Rt_].US[n])
810 cpuRegs.GPR.r[_Rd_].US[n] = 0xFFFF;
811 else
812 cpuRegs.GPR.r[_Rd_].US[n] = 0x0000;
813 }
814
815 void PCEQH() {
816 if (!_Rd_) return;
817
818 _PCEQH(0); _PCEQH(1); _PCEQH(2); _PCEQH(3);
819 _PCEQH(4); _PCEQH(5); _PCEQH(6); _PCEQH(7);
820 }
821
822 static __fi void _PMINH( u8 n )
823 {
824 if (cpuRegs.GPR.r[_Rs_].SS[n] < cpuRegs.GPR.r[_Rt_].SS[n])
825 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rs_].US[n];
826 else
827 cpuRegs.GPR.r[_Rd_].US[n] = cpuRegs.GPR.r[_Rt_].US[n];
828 }
829
830 void PMINH() {
831 if (!_Rd_) return;
832
833 _PMINH(0); _PMINH(1); _PMINH(2); _PMINH(3);
834 _PMINH(4); _PMINH(5); _PMINH(6); _PMINH(7);
835 }
836
837 __fi void _PCEQB(int n)
838 {
839 if (cpuRegs.GPR.r[_Rs_].UC[n] == cpuRegs.GPR.r[_Rt_].UC[n])
840 cpuRegs.GPR.r[_Rd_].UC[n] = 0xFF;
841 else
842 cpuRegs.GPR.r[_Rd_].UC[n] = 0x00;
843 }
844
845 void PCEQB() {
846 int i;
847 if (!_Rd_) return;
848
849 for( i=0; i<16; i++ )
850 _PCEQB(i);
851 }
852
853 __fi void _PADDUW(int n)
854 {
855 s64 tmp;
856 tmp = (s64)cpuRegs.GPR.r[_Rs_].UL[n] + (s64)cpuRegs.GPR.r[_Rt_].UL[n];
857
858 if (tmp > 0xffffffff)
859 cpuRegs.GPR.r[_Rd_].UL[n] = 0xffffffff;
860 else
861 cpuRegs.GPR.r[_Rd_].UL[n] = (u32)tmp;
862 }
863
864 void PADDUW () {
865 if (!_Rd_) return;
866
867 _PADDUW(0); _PADDUW(1); _PADDUW(2); _PADDUW(3);
868 }
869
870 __fi void _PSUBUW(int n)
871 {
872 s64 sTemp64;
873 sTemp64 = (s64)cpuRegs.GPR.r[_Rs_].UL[n] - (s64)cpuRegs.GPR.r[_Rt_].UL[n];
874
875 if (sTemp64 <= 0x0)
876 cpuRegs.GPR.r[_Rd_].UL[n] = 0x0;
877 else
878 cpuRegs.GPR.r[_Rd_].UL[n] = (u32)sTemp64;
879 }
880
881 void PSUBUW() {
882 if (!_Rd_) return;
883
884 _PSUBUW(0); _PSUBUW(1); _PSUBUW(2); _PSUBUW(3);
885 }
886
887 void PEXTUW() {
888 GPR_reg Rs, Rt;
889
890 if (!_Rd_) return;
891
892 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
893 cpuRegs.GPR.r[_Rd_].UL[0] = Rt.UL[2];
894 cpuRegs.GPR.r[_Rd_].UL[1] = Rs.UL[2];
895 cpuRegs.GPR.r[_Rd_].UL[2] = Rt.UL[3];
896 cpuRegs.GPR.r[_Rd_].UL[3] = Rs.UL[3];
897 }
898
899 __fi void _PADDUH(int n)
900 {
901 s32 sTemp32;
902 sTemp32 = (s32)cpuRegs.GPR.r[_Rs_].US[n] + (s32)cpuRegs.GPR.r[_Rt_].US[n];
903
904 if (sTemp32 > 0xFFFF)
905 cpuRegs.GPR.r[_Rd_].US[n] = 0xFFFF;
906 else
907 cpuRegs.GPR.r[_Rd_].US[n] = (u16)sTemp32;
908 }
909
910 void PADDUH() {
911 if (!_Rd_) return;
912
913 _PADDUH(0); _PADDUH(1); _PADDUH(2); _PADDUH(3);
914 _PADDUH(4); _PADDUH(5); _PADDUH(6); _PADDUH(7);
915 }
916
917 __fi void _PSUBUH(int n)
918 {
919 s32 sTemp32;
920 sTemp32 = (s32)cpuRegs.GPR.r[_Rs_].US[n] - (s32)cpuRegs.GPR.r[_Rt_].US[n];
921
922 if (sTemp32 <= 0x0)
923 cpuRegs.GPR.r[_Rd_].US[n] = 0x0;
924 else
925 cpuRegs.GPR.r[_Rd_].US[n] = (u16)sTemp32;
926 }
927
928 void PSUBUH() {
929 if (!_Rd_) return;
930
931 _PSUBUH(0); _PSUBUH(1); _PSUBUH(2); _PSUBUH(3);
932 _PSUBUH(4); _PSUBUH(5); _PSUBUH(6); _PSUBUH(7);
933 }
934
935 void PEXTUH() {
936 GPR_reg Rs, Rt;
937
938 if (!_Rd_) return;
939
940 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
941 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[4];
942 cpuRegs.GPR.r[_Rd_].US[1] = Rs.US[4];
943 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[5];
944 cpuRegs.GPR.r[_Rd_].US[3] = Rs.US[5];
945
946 cpuRegs.GPR.r[_Rd_].US[4] = Rt.US[6];
947 cpuRegs.GPR.r[_Rd_].US[5] = Rs.US[6];
948 cpuRegs.GPR.r[_Rd_].US[6] = Rt.US[7];
949 cpuRegs.GPR.r[_Rd_].US[7] = Rs.US[7];
950 }
951
952 __fi void _PADDUB(int n)
953 {
954 u16 Temp16;
955 Temp16 = (u16)cpuRegs.GPR.r[_Rs_].UC[n] + (u16)cpuRegs.GPR.r[_Rt_].UC[n];
956
957 if (Temp16 > 0xFF)
958 cpuRegs.GPR.r[_Rd_].UC[n] = 0xFF;
959 else
960 cpuRegs.GPR.r[_Rd_].UC[n] = (u8)Temp16;
961 }
962
963 void PADDUB() {
964 int i;
965 if (!_Rd_) return;
966
967 for( i=0; i<16; i++ )
968 _PADDUB(i);
969 }
970
971 __fi void _PSUBUB(int n) {
972 s16 sTemp16;
973 sTemp16 = (s16)cpuRegs.GPR.r[_Rs_].UC[n] - (s16)cpuRegs.GPR.r[_Rt_].UC[n];
974
975 if (sTemp16 <= 0x0)
976 cpuRegs.GPR.r[_Rd_].UC[n] = 0x0;
977 else
978 cpuRegs.GPR.r[_Rd_].UC[n] = (u8)sTemp16;
979 }
980
981 void PSUBUB() {
982 int i;
983 if (!_Rd_) return;
984
985 for( i=0; i<16; i++ )
986 _PSUBUB(i);
987 }
988
989 void PEXTUB() {
990 GPR_reg Rs, Rt;
991
992 if (!_Rd_) return;
993
994 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
995 cpuRegs.GPR.r[_Rd_].UC[0] = Rt.UC[8];
996 cpuRegs.GPR.r[_Rd_].UC[1] = Rs.UC[8];
997 cpuRegs.GPR.r[_Rd_].UC[2] = Rt.UC[9];
998 cpuRegs.GPR.r[_Rd_].UC[3] = Rs.UC[9];
999 cpuRegs.GPR.r[_Rd_].UC[4] = Rt.UC[10];
1000 cpuRegs.GPR.r[_Rd_].UC[5] = Rs.UC[10];
1001 cpuRegs.GPR.r[_Rd_].UC[6] = Rt.UC[11];
1002 cpuRegs.GPR.r[_Rd_].UC[7] = Rs.UC[11];
1003 cpuRegs.GPR.r[_Rd_].UC[8] = Rt.UC[12];
1004 cpuRegs.GPR.r[_Rd_].UC[9] = Rs.UC[12];
1005 cpuRegs.GPR.r[_Rd_].UC[10] = Rt.UC[13];
1006 cpuRegs.GPR.r[_Rd_].UC[11] = Rs.UC[13];
1007 cpuRegs.GPR.r[_Rd_].UC[12] = Rt.UC[14];
1008 cpuRegs.GPR.r[_Rd_].UC[13] = Rs.UC[14];
1009 cpuRegs.GPR.r[_Rd_].UC[14] = Rt.UC[15];
1010 cpuRegs.GPR.r[_Rd_].UC[15] = Rs.UC[15];
1011 }
1012
1013 //int saZero = 0;
1014 void QFSRV() { // JayteeMaster: changed a bit to avoid screw up
1015 GPR_reg Rd;
1016 if (!_Rd_) return;
1017
1018 u32 sa_amt = cpuRegs.sa << 3;
1019 if (sa_amt == 0) {
1020 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0];
1021 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1];
1022 //saZero++;
1023 //if( saZero >= 388800 )
1024 //Console.WriteLn( "SA Is Zero, Bitch: %d zeros and counting.", saZero );
1025 } else {
1026 //Console.WriteLn( "SA Properly Valued at: %d (after %d zeros)", sa_amt, saZero );
1027 //saZero = 0;
1028 if (sa_amt < 64) {
1029 /*
1030 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> sa_amt;
1031 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> sa_amt;
1032 cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - sa_amt);
1033 cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - sa_amt);
1034 */
1035 Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[0] >> sa_amt;
1036 Rd.UD[1] = cpuRegs.GPR.r[_Rt_].UD[1] >> sa_amt;
1037 Rd.UD[0]|= cpuRegs.GPR.r[_Rt_].UD[1] << (64 - sa_amt);
1038 Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[0] << (64 - sa_amt);
1039 cpuRegs.GPR.r[_Rd_] = Rd;
1040 } else {
1041 /*
1042 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (sa_amt - 64);
1043 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (sa_amt - 64);
1044 cpuRegs.GPR.r[_Rd_].UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - sa_amt);
1045 cpuRegs.GPR.r[_Rd_].UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - sa_amt);
1046 */
1047 Rd.UD[0] = cpuRegs.GPR.r[_Rt_].UD[1] >> (sa_amt - 64);
1048 Rd.UD[1] = cpuRegs.GPR.r[_Rs_].UD[0] >> (sa_amt - 64);
1049 Rd.UD[0]|= cpuRegs.GPR.r[_Rs_].UD[0] << (128 - sa_amt);
1050 Rd.UD[1]|= cpuRegs.GPR.r[_Rs_].UD[1] << (128 - sa_amt);
1051 cpuRegs.GPR.r[_Rd_] = Rd;
1052 }
1053 }
1054 }
1055
1056 //********END OF MMI1 OPCODES***********************************
1057
1058 //*********MMI2 OPCODES***************************************
1059
1060 static __fi void _PMADDW(int dd, int ss)
1061 {
1062 s64 temp = (s64)((s64)cpuRegs.LO.SL[ss] | ((s64)cpuRegs.HI.SL[ss] << 32)) +
1063 ((s64)cpuRegs.GPR.r[_Rs_].SL[ss] * (s64)cpuRegs.GPR.r[_Rt_].SL[ss]);
1064
1065 cpuRegs.LO.SD[dd] = (s32)(temp & 0xffffffff);
1066 cpuRegs.HI.SD[dd] = (s32)(temp >> 32);
1067
1068 if (_Rd_) cpuRegs.GPR.r[_Rd_].SD[dd] = temp;
1069 }
1070
1071 void PMADDW() {
1072 _PMADDW(0, 0);
1073 _PMADDW(1, 2);
1074 }
1075
1076 void PSLLVW() {
1077 if (!_Rd_) return;
1078
1079 cpuRegs.GPR.r[_Rd_].SD[0] = (s64)(s32)(cpuRegs.GPR.r[_Rt_].UL[0] <<
1080 (cpuRegs.GPR.r[_Rs_].UL[0] & 0x1F));
1081 cpuRegs.GPR.r[_Rd_].SD[1] = (s64)(s32)(cpuRegs.GPR.r[_Rt_].UL[2] <<
1082 (cpuRegs.GPR.r[_Rs_].UL[2] & 0x1F));
1083 }
1084
1085 void PSRLVW() {
1086 if (!_Rd_) return;
1087
1088 cpuRegs.GPR.r[_Rd_].SD[0] = (s64)(s32)(cpuRegs.GPR.r[_Rt_].UL[0] >>
1089 (cpuRegs.GPR.r[_Rs_].UL[0] & 0x1F));
1090 cpuRegs.GPR.r[_Rd_].SD[1] = (s64)(s32)(cpuRegs.GPR.r[_Rt_].UL[2] >>
1091 (cpuRegs.GPR.r[_Rs_].UL[2] & 0x1F));
1092 }
1093
1094 __fi void _PMSUBW(int dd, int ss)
1095 {
1096 s64 temp = (s64)((s64)cpuRegs.LO.SL[ss] | ((s64)cpuRegs.HI.SL[ss] << 32)) -
1097 ((s64)cpuRegs.GPR.r[_Rs_].SL[ss] * (s64)cpuRegs.GPR.r[_Rt_].SL[ss]);
1098
1099 cpuRegs.LO.SD[dd] = (s32)(temp & 0xffffffff);
1100 cpuRegs.HI.SD[dd] = (s32)(temp >> 32);
1101
1102 if (_Rd_) cpuRegs.GPR.r[_Rd_].SD[dd] = temp;
1103 }
1104
1105 void PMSUBW() {
1106 _PMSUBW(0, 0);
1107 _PMSUBW(1, 2);
1108 }
1109
1110 void PMFHI() {
1111 if (!_Rd_) return;
1112
1113 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.HI.UD[0];
1114 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.HI.UD[1];
1115 }
1116
1117 void PMFLO() {
1118 if (!_Rd_) return;
1119
1120 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.LO.UD[0];
1121 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.LO.UD[1];
1122 }
1123
1124 void PINTH() {
1125 GPR_reg Rs, Rt;
1126
1127 if (!_Rd_) return;
1128
1129 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
1130 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[0];
1131 cpuRegs.GPR.r[_Rd_].US[1] = Rs.US[4];
1132 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[1];
1133 cpuRegs.GPR.r[_Rd_].US[3] = Rs.US[5];
1134 cpuRegs.GPR.r[_Rd_].US[4] = Rt.US[2];
1135 cpuRegs.GPR.r[_Rd_].US[5] = Rs.US[6];
1136 cpuRegs.GPR.r[_Rd_].US[6] = Rt.US[3];
1137 cpuRegs.GPR.r[_Rd_].US[7] = Rs.US[7];
1138 }
1139
1140 __fi void _PMULTW(int dd, int ss)
1141 {
1142 s64 temp = (s64)cpuRegs.GPR.r[_Rs_].SL[ss] * (s64)cpuRegs.GPR.r[_Rt_].SL[ss];
1143
1144 cpuRegs.LO.UD[dd] = (s32)(temp & 0xffffffff);
1145 cpuRegs.HI.UD[dd] = (s32)(temp >> 32);
1146
1147 if (_Rd_) cpuRegs.GPR.r[_Rd_].SD[dd] = temp;
1148 }
1149
1150 void PMULTW() {
1151 _PMULTW(0, 0);
1152 _PMULTW(1, 2);
1153 }
1154
1155 __fi void _PDIVW(int dd, int ss)
1156 {
1157 if (cpuRegs.GPR.r[_Rs_].UL[ss] == 0x80000000 && cpuRegs.GPR.r[_Rt_].UL[ss] == 0xffffffff)
1158 {
1159 cpuRegs.LO.SD[dd] = (s32)0x80000000;
1160 cpuRegs.HI.SD[dd] = (s32)0;
1161 }
1162 else if (cpuRegs.GPR.r[_Rt_].SL[ss] != 0)
1163 {
1164 cpuRegs.LO.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss] / cpuRegs.GPR.r[_Rt_].SL[ss];
1165 cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss] % cpuRegs.GPR.r[_Rt_].SL[ss];
1166 }
1167 else
1168 {
1169 cpuRegs.LO.SD[dd] = (cpuRegs.GPR.r[_Rs_].SL[ss] < 0) ? 1 : -1;
1170 cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss];
1171 }
1172 }
1173
1174 void PDIVW() {
1175 _PDIVW(0, 0);
1176 _PDIVW(1, 2);
1177 }
1178
1179 void PCPYLD() {
1180 if (!_Rd_) return;
1181
1182 // note: first _Rs_, since the other way when _Rd_ equals
1183 // _Rs_ or _Rt_ this would screw up
1184 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[0];
1185 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rt_].UD[0];
1186 }
1187
1188 void PMADDH() { // JayteeMaster: changed a bit to avoid screw up
1189 s32 temp;
1190
1191 temp = cpuRegs.LO.UL[0] + (s32)cpuRegs.GPR.r[_Rs_].SS[0] * (s32)cpuRegs.GPR.r[_Rt_].SS[0];
1192 cpuRegs.LO.UL[0] = temp;
1193 /* if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[0] = temp; */
1194
1195 temp = cpuRegs.LO.UL[1] + (s32)cpuRegs.GPR.r[_Rs_].SS[1] * (s32)cpuRegs.GPR.r[_Rt_].SS[1];
1196 cpuRegs.LO.UL[1] = temp;
1197
1198 temp = cpuRegs.HI.UL[0] + (s32)cpuRegs.GPR.r[_Rs_].SS[2] * (s32)cpuRegs.GPR.r[_Rt_].SS[2];
1199 cpuRegs.HI.UL[0] = temp;
1200 /* if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[1] = temp; */
1201
1202 temp = cpuRegs.HI.UL[1] + (s32)cpuRegs.GPR.r[_Rs_].SS[3] * (s32)cpuRegs.GPR.r[_Rt_].SS[3];
1203 cpuRegs.HI.UL[1] = temp;
1204
1205 temp = cpuRegs.LO.UL[2] + (s32)cpuRegs.GPR.r[_Rs_].SS[4] * (s32)cpuRegs.GPR.r[_Rt_].SS[4];
1206 cpuRegs.LO.UL[2] = temp;
1207 /* if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[2] = temp; */
1208
1209 temp = cpuRegs.LO.UL[3] + (s32)cpuRegs.GPR.r[_Rs_].SS[5] * (s32)cpuRegs.GPR.r[_Rt_].SS[5];
1210 cpuRegs.LO.UL[3] = temp;
1211
1212 temp = cpuRegs.HI.UL[2] + (s32)cpuRegs.GPR.r[_Rs_].SS[6] * (s32)cpuRegs.GPR.r[_Rt_].SS[6];
1213 cpuRegs.HI.UL[2] = temp;
1214 /* if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[3] = temp; */
1215
1216 temp = cpuRegs.HI.UL[3] + (s32)cpuRegs.GPR.r[_Rs_].SS[7] * (s32)cpuRegs.GPR.r[_Rt_].SS[7];
1217 cpuRegs.HI.UL[3] = temp;
1218
1219 if (_Rd_) {
1220 cpuRegs.GPR.r[_Rd_].UL[0] = cpuRegs.LO.UL[0];
1221 cpuRegs.GPR.r[_Rd_].UL[1] = cpuRegs.HI.UL[0];
1222 cpuRegs.GPR.r[_Rd_].UL[2] = cpuRegs.LO.UL[2];
1223 cpuRegs.GPR.r[_Rd_].UL[3] = cpuRegs.HI.UL[2];
1224 }
1225
1226 }
1227
1228 // JayteeMaster: changed a bit to avoid screw up
1229 __fi void _PHMADH_LO(int dd, int n)
1230 {
1231 s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
1232 s32 temp = firsttemp + (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
1233
1234 cpuRegs.LO.UL[dd] = temp;
1235 cpuRegs.LO.UL[dd+1] = firsttemp;
1236 }
1237
1238 __fi void _PHMADH_HI(int dd, int n)
1239 {
1240 s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
1241 s32 temp = firsttemp + (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
1242
1243 cpuRegs.HI.UL[dd] = temp;
1244 cpuRegs.HI.UL[dd+1] = firsttemp;
1245 }
1246
1247 void PHMADH() { // JayteeMaster: changed a bit to avoid screw up. Also used 0,2,4,6 instead of 0,1,2,3
1248 _PHMADH_LO(0, 0);
1249 _PHMADH_HI(0, 2);
1250 _PHMADH_LO(2, 4);
1251 _PHMADH_HI(2, 6);
1252 if (_Rd_) {
1253 cpuRegs.GPR.r[_Rd_].UL[0] = cpuRegs.LO.UL[0];
1254 cpuRegs.GPR.r[_Rd_].UL[1] = cpuRegs.HI.UL[0];
1255 cpuRegs.GPR.r[_Rd_].UL[2] = cpuRegs.LO.UL[2];
1256 cpuRegs.GPR.r[_Rd_].UL[3] = cpuRegs.HI.UL[2];
1257 }
1258 }
1259
1260 void PAND() {
1261 if (!_Rd_) return;
1262
1263 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] & cpuRegs.GPR.r[_Rt_].UD[0];
1264 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[1] & cpuRegs.GPR.r[_Rt_].UD[1];
1265 }
1266
1267 void PXOR() {
1268 if (!_Rd_) return;
1269
1270 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] ^ cpuRegs.GPR.r[_Rt_].UD[0];
1271 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[1] ^ cpuRegs.GPR.r[_Rt_].UD[1];
1272 }
1273
1274 void PMSUBH() { // JayteeMaster: changed a bit to avoid screw up
1275 s32 temp;
1276
1277 temp = cpuRegs.LO.UL[0] - (s32)cpuRegs.GPR.r[_Rs_].SS[0] * (s32)cpuRegs.GPR.r[_Rt_].SS[0];
1278 cpuRegs.LO.UL[0] = temp;
1279 /*if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[0] = temp;*/
1280
1281 temp = cpuRegs.LO.UL[1] - (s32)cpuRegs.GPR.r[_Rs_].SS[1] * (s32)cpuRegs.GPR.r[_Rt_].SS[1];
1282 cpuRegs.LO.UL[1] = temp;
1283
1284 temp = cpuRegs.HI.UL[0] - (s32)cpuRegs.GPR.r[_Rs_].SS[2] * (s32)cpuRegs.GPR.r[_Rt_].SS[2];
1285 cpuRegs.HI.UL[0] = temp;
1286 /*if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[1] = temp;*/
1287
1288 temp = cpuRegs.HI.UL[1] - (s32)cpuRegs.GPR.r[_Rs_].SS[3] * (s32)cpuRegs.GPR.r[_Rt_].SS[3];
1289 cpuRegs.HI.UL[1] = temp;
1290
1291 temp = cpuRegs.LO.UL[2] - (s32)cpuRegs.GPR.r[_Rs_].SS[4] * (s32)cpuRegs.GPR.r[_Rt_].SS[4];
1292 cpuRegs.LO.UL[2] = temp;
1293 /*if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[2] = temp;*/
1294
1295 temp = cpuRegs.LO.UL[3] - (s32)cpuRegs.GPR.r[_Rs_].SS[5] * (s32)cpuRegs.GPR.r[_Rt_].SS[5];
1296 cpuRegs.LO.UL[3] = temp;
1297
1298 temp = cpuRegs.HI.UL[2] - (s32)cpuRegs.GPR.r[_Rs_].SS[6] * (s32)cpuRegs.GPR.r[_Rt_].SS[6];
1299 cpuRegs.HI.UL[2] = temp;
1300 /*if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[3] = temp;*/
1301
1302 temp = cpuRegs.HI.UL[3] - (s32)cpuRegs.GPR.r[_Rs_].SS[7] * (s32)cpuRegs.GPR.r[_Rt_].SS[7];
1303 cpuRegs.HI.UL[3] = temp;
1304
1305 if (_Rd_) {
1306 cpuRegs.GPR.r[_Rd_].UL[0] = cpuRegs.LO.UL[0];
1307 cpuRegs.GPR.r[_Rd_].UL[1] = cpuRegs.HI.UL[0];
1308 cpuRegs.GPR.r[_Rd_].UL[2] = cpuRegs.LO.UL[2];
1309 cpuRegs.GPR.r[_Rd_].UL[3] = cpuRegs.HI.UL[2];
1310 }
1311 }
1312
1313 // JayteeMaster: changed a bit to avoid screw up
1314 static __fi void _PHMSBH_LO(int dd, int n, int rdd)
1315 {
1316 s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
1317 s32 temp = firsttemp - (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
1318
1319 cpuRegs.LO.UL[dd] = temp;
1320 cpuRegs.LO.UL[dd+1] = ~firsttemp;
1321 }
1322 static __fi void _PHMSBH_HI(int dd, int n, int rdd)
1323 {
1324 s32 firsttemp = (s32)cpuRegs.GPR.r[_Rs_].SS[n+1] * (s32)cpuRegs.GPR.r[_Rt_].SS[n+1];
1325 s32 temp = firsttemp - (s32)cpuRegs.GPR.r[_Rs_].SS[n] * (s32)cpuRegs.GPR.r[_Rt_].SS[n];
1326
1327 cpuRegs.HI.UL[dd] = temp;
1328 cpuRegs.HI.UL[dd+1] = ~firsttemp;
1329 }
1330
1331 void PHMSBH() { // JayteeMaster: changed a bit to avoid screw up
1332 _PHMSBH_LO(0, 0, 0);
1333 _PHMSBH_HI(0, 2, 1);
1334 _PHMSBH_LO(2, 4, 2);
1335 _PHMSBH_HI(2, 6, 3);
1336 if (_Rd_) {
1337 cpuRegs.GPR.r[_Rd_].UL[0] = cpuRegs.LO.UL[0];
1338 cpuRegs.GPR.r[_Rd_].UL[1] = cpuRegs.HI.UL[0];
1339 cpuRegs.GPR.r[_Rd_].UL[2] = cpuRegs.LO.UL[2];
1340 cpuRegs.GPR.r[_Rd_].UL[3] = cpuRegs.HI.UL[2];
1341 }
1342 }
1343
1344 void PEXEH() {
1345 GPR_reg Rt;
1346
1347 if (!_Rd_) return;
1348
1349 Rt = cpuRegs.GPR.r[_Rt_];
1350 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[2];
1351 cpuRegs.GPR.r[_Rd_].US[1] = Rt.US[1];
1352 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[0];
1353 cpuRegs.GPR.r[_Rd_].US[3] = Rt.US[3];
1354 cpuRegs.GPR.r[_Rd_].US[4] = Rt.US[6];
1355 cpuRegs.GPR.r[_Rd_].US[5] = Rt.US[5];
1356 cpuRegs.GPR.r[_Rd_].US[6] = Rt.US[4];
1357 cpuRegs.GPR.r[_Rd_].US[7] = Rt.US[7];
1358 }
1359
1360 void PREVH () {
1361 GPR_reg Rt;
1362
1363 if (!_Rd_) return;
1364
1365 Rt = cpuRegs.GPR.r[_Rt_];
1366 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[3];
1367 cpuRegs.GPR.r[_Rd_].US[1] = Rt.US[2];
1368 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[1];
1369 cpuRegs.GPR.r[_Rd_].US[3] = Rt.US[0];
1370 cpuRegs.GPR.r[_Rd_].US[4] = Rt.US[7];
1371 cpuRegs.GPR.r[_Rd_].US[5] = Rt.US[6];
1372 cpuRegs.GPR.r[_Rd_].US[6] = Rt.US[5];
1373 cpuRegs.GPR.r[_Rd_].US[7] = Rt.US[4];
1374 }
1375
1376 void PMULTH() { // JayteeMaster: changed a bit to avoid screw up
1377 s32 temp;
1378
1379 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[0] * (s32)cpuRegs.GPR.r[_Rt_].SS[0];
1380 cpuRegs.LO.UL[0] = temp;
1381 /*if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[0] = temp;*/
1382
1383 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[1] * (s32)cpuRegs.GPR.r[_Rt_].SS[1];
1384 cpuRegs.LO.UL[1] = temp;
1385
1386 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[2] * (s32)cpuRegs.GPR.r[_Rt_].SS[2];
1387 cpuRegs.HI.UL[0] = temp;
1388 /*if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[1] = temp;*/
1389
1390 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[3] * (s32)cpuRegs.GPR.r[_Rt_].SS[3];
1391 cpuRegs.HI.UL[1] = temp;
1392
1393 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[4] * (s32)cpuRegs.GPR.r[_Rt_].SS[4];
1394 cpuRegs.LO.UL[2] = temp;
1395 /*if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[2] = temp;*/
1396
1397 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[5] * (s32)cpuRegs.GPR.r[_Rt_].SS[5];
1398 cpuRegs.LO.UL[3] = temp;
1399
1400 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[6] * (s32)cpuRegs.GPR.r[_Rt_].SS[6];
1401 cpuRegs.HI.UL[2] = temp;
1402 /*if (_Rd_) cpuRegs.GPR.r[_Rd_].UL[3] = temp;*/
1403
1404 temp = (s32)cpuRegs.GPR.r[_Rs_].SS[7] * (s32)cpuRegs.GPR.r[_Rt_].SS[7];
1405 cpuRegs.HI.UL[3] = temp;
1406
1407 if (_Rd_) {
1408 cpuRegs.GPR.r[_Rd_].UL[0] = cpuRegs.LO.UL[0];
1409 cpuRegs.GPR.r[_Rd_].UL[1] = cpuRegs.HI.UL[0];
1410 cpuRegs.GPR.r[_Rd_].UL[2] = cpuRegs.LO.UL[2];
1411 cpuRegs.GPR.r[_Rd_].UL[3] = cpuRegs.HI.UL[2];
1412 }
1413 }
1414
1415 __fi void _PDIVBW(int n)
1416 {
1417 if (cpuRegs.GPR.r[_Rs_].UL[n] == 0x80000000 && cpuRegs.GPR.r[_Rt_].US[0] == 0xffff)
1418 {
1419 cpuRegs.LO.SL[n] = (s32)0x80000000;
1420 cpuRegs.HI.SL[n] = (s32)0x0;
1421 }
1422 else if (cpuRegs.GPR.r[_Rt_].US[0] != 0)
1423 {
1424 cpuRegs.LO.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n] / cpuRegs.GPR.r[_Rt_].SS[0];
1425 cpuRegs.HI.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n] % cpuRegs.GPR.r[_Rt_].SS[0];
1426 }
1427 else
1428 {
1429 cpuRegs.LO.SL[n] = (cpuRegs.GPR.r[_Rs_].SL[n] < 0) ? 1 : -1;
1430 cpuRegs.HI.SL[n] = cpuRegs.GPR.r[_Rs_].SL[n];
1431 }
1432 }
1433
1434 void PDIVBW() {
1435 _PDIVBW(0); _PDIVBW(1); _PDIVBW(2); _PDIVBW(3);
1436 }
1437
1438 void PEXEW() {
1439 GPR_reg Rt;
1440
1441 if (!_Rd_) return;
1442
1443 Rt = cpuRegs.GPR.r[_Rt_];
1444 cpuRegs.GPR.r[_Rd_].UL[0] = Rt.UL[2];
1445 cpuRegs.GPR.r[_Rd_].UL[1] = Rt.UL[1];
1446 cpuRegs.GPR.r[_Rd_].UL[2] = Rt.UL[0];
1447 cpuRegs.GPR.r[_Rd_].UL[3] = Rt.UL[3];
1448 }
1449
1450 void PROT3W() {
1451 GPR_reg Rt;
1452
1453 if (!_Rd_) return;
1454
1455 Rt = cpuRegs.GPR.r[_Rt_];
1456 cpuRegs.GPR.r[_Rd_].UL[0] = Rt.UL[1];
1457 cpuRegs.GPR.r[_Rd_].UL[1] = Rt.UL[2];
1458 cpuRegs.GPR.r[_Rd_].UL[2] = Rt.UL[0];
1459 cpuRegs.GPR.r[_Rd_].UL[3] = Rt.UL[3];
1460 }
1461
1462 //*****END OF MMI2 OPCODES***********************************
1463
1464 //*************************MMI3 OPCODES************************
1465
1466 static __fi void _PMADDUW(int dd, int ss)
1467 {
1468 u64 tempu = (u64)((u64)cpuRegs.LO.UL[ss] | ((u64)cpuRegs.HI.UL[ss] << 32)) + \
1469 ((u64)cpuRegs.GPR.r[_Rs_].UL[ss] * (u64)cpuRegs.GPR.r[_Rt_].UL[ss]);
1470
1471 cpuRegs.LO.SD[dd] = (s32)(tempu & 0xffffffff);
1472 cpuRegs.HI.SD[dd] = (s32)(tempu >> 32);
1473
1474 if (_Rd_) cpuRegs.GPR.r[_Rd_].UD[dd] = tempu;
1475 }
1476
1477 void PMADDUW() {
1478 _PMADDUW(0, 0);
1479 _PMADDUW(1, 2);
1480 }
1481
1482 void PSRAVW() {
1483 if (!_Rd_) return;
1484
1485 cpuRegs.GPR.r[_Rd_].SD[0] = (s64)(cpuRegs.GPR.r[_Rt_].SL[0] >>
1486 (cpuRegs.GPR.r[_Rs_].UL[0] & 0x1F));
1487 cpuRegs.GPR.r[_Rd_].SD[1] = (s64)(cpuRegs.GPR.r[_Rt_].SL[2] >>
1488 (cpuRegs.GPR.r[_Rs_].UL[2] & 0x1F));
1489 }
1490
1491 void PMTHI() {
1492 cpuRegs.HI.UD[0] = cpuRegs.GPR.r[_Rs_].UD[0];
1493 cpuRegs.HI.UD[1] = cpuRegs.GPR.r[_Rs_].UD[1];
1494 }
1495
1496 void PMTLO() {
1497 cpuRegs.LO.UD[0] = cpuRegs.GPR.r[_Rs_].UD[0];
1498 cpuRegs.LO.UD[1] = cpuRegs.GPR.r[_Rs_].UD[1];
1499 }
1500
1501 void PINTEH() {
1502 GPR_reg Rs, Rt;
1503
1504 if (!_Rd_) return;
1505
1506 Rs = cpuRegs.GPR.r[_Rs_]; Rt = cpuRegs.GPR.r[_Rt_];
1507 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[0];
1508 cpuRegs.GPR.r[_Rd_].US[1] = Rs.US[0];
1509 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[2];
1510 cpuRegs.GPR.r[_Rd_].US[3] = Rs.US[2];
1511 cpuRegs.GPR.r[_Rd_].US[4] = Rt.US[4];
1512 cpuRegs.GPR.r[_Rd_].US[5] = Rs.US[4];
1513 cpuRegs.GPR.r[_Rd_].US[6] = Rt.US[6];
1514 cpuRegs.GPR.r[_Rd_].US[7] = Rs.US[6];
1515 }
1516
1517 __fi void _PMULTUW(int dd, int ss)
1518 {
1519 u64 tempu = (u64)cpuRegs.GPR.r[_Rs_].UL[ss] * (u64)cpuRegs.GPR.r[_Rt_].UL[ss];
1520
1521 cpuRegs.LO.UD[dd] = (s32)(tempu & 0xffffffff);
1522 cpuRegs.HI.UD[dd] = (s32)(tempu >> 32);
1523
1524 if (_Rd_) cpuRegs.GPR.r[_Rd_].UD[dd] = tempu;
1525 }
1526
1527
1528 void PMULTUW() {
1529 _PMULTUW(0, 0);
1530 _PMULTUW(1, 2);
1531 }
1532
1533 __fi void _PDIVUW(int dd, int ss)
1534 {
1535 if (cpuRegs.GPR.r[_Rt_].UL[ss] != 0) {
1536 cpuRegs.LO.SD[dd] = (s32)(cpuRegs.GPR.r[_Rs_].UL[ss] / cpuRegs.GPR.r[_Rt_].UL[ss]);
1537 cpuRegs.HI.SD[dd] = (s32)(cpuRegs.GPR.r[_Rs_].UL[ss] % cpuRegs.GPR.r[_Rt_].UL[ss]);
1538 }
1539 else
1540 {
1541 cpuRegs.LO.SD[dd] = -1;
1542 cpuRegs.HI.SD[dd] = cpuRegs.GPR.r[_Rs_].SL[ss];
1543 }
1544 }
1545
1546 void PDIVUW() {
1547 _PDIVUW(0, 0);
1548 _PDIVUW(1, 2);
1549 }
1550
1551 void PCPYUD() {
1552 if (!_Rd_) return;
1553
1554 // note: first _Rs_, since the other way when _Rd_ equals
1555 // _Rs_ or _Rt_ this would screw up
1556 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[1];
1557 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rt_].UD[1];
1558 }
1559
1560 void POR() {
1561 if (!_Rd_) return;
1562
1563 cpuRegs.GPR.r[_Rd_].UD[0] = cpuRegs.GPR.r[_Rs_].UD[0] | cpuRegs.GPR.r[_Rt_].UD[0];
1564 cpuRegs.GPR.r[_Rd_].UD[1] = cpuRegs.GPR.r[_Rs_].UD[1] | cpuRegs.GPR.r[_Rt_].UD[1];
1565 }
1566
1567 void PNOR () {
1568 if (!_Rd_) return;
1569
1570 cpuRegs.GPR.r[_Rd_].UD[0] = ~(cpuRegs.GPR.r[_Rs_].UD[0] | cpuRegs.GPR.r[_Rt_].UD[0]);
1571 cpuRegs.GPR.r[_Rd_].UD[1] = ~(cpuRegs.GPR.r[_Rs_].UD[1] | cpuRegs.GPR.r[_Rt_].UD[1]);
1572 }
1573
1574 void PEXCH() {
1575 GPR_reg Rt;
1576
1577 if (!_Rd_) return;
1578
1579 Rt = cpuRegs.GPR.r[_Rt_];
1580 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[0];
1581 cpuRegs.GPR.r[_Rd_].US[1] = Rt.US[2];
1582 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[1];
1583 cpuRegs.GPR.r[_Rd_].US[3] = Rt.US[3];
1584 cpuRegs.GPR.r[_Rd_].US[4] = Rt.US[4];
1585 cpuRegs.GPR.r[_Rd_].US[5] = Rt.US[6];
1586 cpuRegs.GPR.r[_Rd_].US[6] = Rt.US[5];
1587 cpuRegs.GPR.r[_Rd_].US[7] = Rt.US[7];
1588 }
1589
1590 void PCPYH() {
1591 GPR_reg Rt;
1592
1593 if (!_Rd_) return;
1594
1595 Rt = cpuRegs.GPR.r[_Rt_];
1596 cpuRegs.GPR.r[_Rd_].US[0] = Rt.US[0];
1597 cpuRegs.GPR.r[_Rd_].US[1] = Rt.US[0];
1598 cpuRegs.GPR.r[_Rd_].US[2] = Rt.US[0];
1599 cpuRegs.GPR.r[_Rd_].US[3] = Rt.US[0];
1600 cpuRegs.GPR.r[_Rd_].US[4] = Rt.US[4];
1601 cpuRegs.GPR.r[_Rd_].US[5] = Rt.US[4];
1602 cpuRegs.GPR.r[_Rd_].US[6] = Rt.US[4];
1603 cpuRegs.GPR.r[_Rd_].US[7] = Rt.US[4];
1604 }
1605
1606 void PEXCW() {
1607 GPR_reg Rt;
1608
1609 if (!_Rd_) return;
1610
1611 Rt = cpuRegs.GPR.r[_Rt_];
1612 cpuRegs.GPR.r[_Rd_].UL[0] = Rt.UL[0];
1613 cpuRegs.GPR.r[_Rd_].UL[1] = Rt.UL[2];
1614 cpuRegs.GPR.r[_Rd_].UL[2] = Rt.UL[1];
1615 cpuRegs.GPR.r[_Rd_].UL[3] = Rt.UL[3];
1616 }
1617
1618 //**********************END OF MMI3 OPCODES********************
1619
1620 // obs:
1621 // QFSRV not verified
1622
1623 }}} } // end namespace R5900::Interpreter::OpcodeImpl::MMI

  ViewVC Help
Powered by ViewVC 1.1.22