/[pcsx2_0.9.7]/trunk/pcsx2/x86/ix86-32/iR5900Arit.cpp
ViewVC logotype

Contents of /trunk/pcsx2/x86/ix86-32/iR5900Arit.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 2 months ago) by william
File size: 15067 byte(s)
re-commit (had local access denied errors when committing)
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
19 #include "Common.h"
20 #include "R5900OpcodeTables.h"
21 #include "iR5900.h"
22
23 using namespace x86Emitter;
24
25 namespace R5900 {
26 namespace Dynarec {
27 namespace OpcodeImpl
28 {
29
30 /*********************************************************
31 * Register arithmetic *
32 * Format: OP rd, rs, rt *
33 *********************************************************/
34
35 // TODO: overflow checks
36
37 #ifndef ARITHMETIC_RECOMPILE
38
39 namespace Interp = R5900::Interpreter::OpcodeImpl;
40
41 REC_FUNC_DEL(ADD, _Rd_);
42 REC_FUNC_DEL(ADDU, _Rd_);
43 REC_FUNC_DEL(DADD, _Rd_);
44 REC_FUNC_DEL(DADDU, _Rd_);
45 REC_FUNC_DEL(SUB, _Rd_);
46 REC_FUNC_DEL(SUBU, _Rd_);
47 REC_FUNC_DEL(DSUB, _Rd_);
48 REC_FUNC_DEL(DSUBU, _Rd_);
49 REC_FUNC_DEL(AND, _Rd_);
50 REC_FUNC_DEL(OR, _Rd_);
51 REC_FUNC_DEL(XOR, _Rd_);
52 REC_FUNC_DEL(NOR, _Rd_);
53 REC_FUNC_DEL(SLT, _Rd_);
54 REC_FUNC_DEL(SLTU, _Rd_);
55
56 #else
57
58 //// ADD
59 void recADD_const()
60 {
61 g_cpuConstRegs[_Rd_].SD[0] = g_cpuConstRegs[_Rs_].SL[0] + g_cpuConstRegs[_Rt_].SL[0];
62 }
63
64 void recADD_constv(int info, int creg, int vreg)
65 {
66 pxAssert( !(info&PROCESS_EE_XMM) );
67
68 s32 cval = g_cpuConstRegs[creg].SL[0];
69
70 xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].SL[0]]);
71 if (cval)
72 xADD(eax, cval);
73 eeSignExtendTo(_Rd_, _Rd_ == vreg && !cval);
74 }
75
76 // s is constant
77 void recADD_consts(int info)
78 {
79 recADD_constv(info, _Rs_, _Rt_);
80 }
81
82 // t is constant
83 void recADD_constt(int info)
84 {
85 recADD_constv(info, _Rt_, _Rs_);
86 }
87
88 // nothing is constant
89 void recADD_(int info)
90 {
91 pxAssert( !(info&PROCESS_EE_XMM) );
92
93 xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rs_].SL[0]]);
94 if (_Rs_ == _Rt_)
95 xADD(eax, eax);
96 else
97 xADD(eax, ptr32[&cpuRegs.GPR.r[_Rt_].SL[0]]);
98 eeSignExtendTo(_Rd_);
99 }
100
101 EERECOMPILE_CODE0(ADD, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
102
103 //// ADDU
104 void recADDU(void)
105 {
106 recADD();
107 }
108
109 //// DADD
110 void recDADD_const(void)
111 {
112 g_cpuConstRegs[_Rd_].SD[0] = g_cpuConstRegs[_Rs_].SD[0] + g_cpuConstRegs[_Rt_].SD[0];
113 }
114
115 void recDADD_constv(int info, int creg, int vreg)
116 {
117 pxAssert( !(info&PROCESS_EE_XMM) );
118
119 GPR_reg64 cval = g_cpuConstRegs[creg];
120
121 if (_Rd_ == vreg) {
122 if (!cval.SD[0])
123 return; // no-op
124 xADD(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], cval.SL[0]);
125 xADC(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], cval.SL[1]);
126 } else {
127 xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].SL[0]]);
128 xMOV(edx, ptr32[&cpuRegs.GPR.r[vreg].SL[1]]);
129 if (cval.SD[0]) {
130 xADD(eax, cval.SL[0]);
131 xADC(edx, cval.SL[1]);
132 }
133 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], eax);
134 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], edx);
135 }
136 }
137
138 void recDADD_consts(int info)
139 {
140 recDADD_constv(info, _Rs_, _Rt_);
141 }
142
143 void recDADD_constt(int info)
144 {
145 recDADD_constv(info, _Rt_, _Rs_);
146 }
147
148 void recDADD_(int info)
149 {
150 pxAssert( !(info&PROCESS_EE_XMM) );
151
152 int rs = _Rs_, rt = _Rt_;
153 if (_Rd_ == _Rt_)
154 rs = _Rt_, rt = _Rs_;
155
156 xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].SL[0]]);
157
158 if (_Rd_ == _Rs_ && _Rs_ == _Rt_) {
159 xSHLD(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], eax, 1);
160 xSHL(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], 1);
161 return;
162 }
163
164 xMOV(edx, ptr32[&cpuRegs.GPR.r[rt].SL[1]]);
165
166 if (_Rd_ == rs) {
167 xADD(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], eax);
168 xADC(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], edx);
169 return;
170 } else if (rs == rt) {
171 xADD(eax, eax);
172 xADC(edx, edx);
173 } else {
174 xADD(eax, ptr32[&cpuRegs.GPR.r[rs].SL[0]]);
175 xADC(edx, ptr32[&cpuRegs.GPR.r[rs].SL[1]]);
176 }
177
178 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], eax);
179 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], edx);
180 }
181
182 EERECOMPILE_CODE0(DADD, XMMINFO_WRITED|XMMINFO_READS|XMMINFO_READT);
183
184 //// DADDU
185 void recDADDU(void)
186 {
187 recDADD();
188 }
189
190 //// SUB
191
192 void recSUB_const()
193 {
194 g_cpuConstRegs[_Rd_].SD[0] = g_cpuConstRegs[_Rs_].SL[0] - g_cpuConstRegs[_Rt_].SL[0];
195 }
196
197 void recSUB_consts(int info)
198 {
199 pxAssert( !(info&PROCESS_EE_XMM) );
200
201 s32 sval = g_cpuConstRegs[_Rs_].SL[0];
202
203 xMOV(eax, sval);
204 xSUB(eax, ptr32[&cpuRegs.GPR.r[_Rt_].SL[0]]);
205 eeSignExtendTo(_Rd_);
206 }
207
208 void recSUB_constt(int info)
209 {
210 pxAssert( !(info&PROCESS_EE_XMM) );
211
212 s32 tval = g_cpuConstRegs[_Rt_].SL[0];
213
214 xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rs_].SL[0]]);
215 if (tval)
216 xSUB(eax, tval);
217 eeSignExtendTo(_Rd_, _Rd_ == _Rs_ && !tval);
218 }
219
220 void recSUB_(int info)
221 {
222 pxAssert( !(info&PROCESS_EE_XMM) );
223
224 if (_Rs_ == _Rt_) {
225 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], 0);
226 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], 0);
227 return;
228 }
229
230 xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rs_].SL[0]]);
231 xSUB(eax, ptr32[&cpuRegs.GPR.r[_Rt_].SL[0]]);
232 eeSignExtendTo(_Rd_);
233 }
234
235 EERECOMPILE_CODE0(SUB, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
236
237 //// SUBU
238 void recSUBU(void)
239 {
240 recSUB();
241 }
242
243 //// DSUB
244 void recDSUB_const()
245 {
246 g_cpuConstRegs[_Rd_].SD[0] = g_cpuConstRegs[_Rs_].SD[0] - g_cpuConstRegs[_Rt_].SD[0];
247 }
248
249 void recDSUB_consts(int info)
250 {
251 pxAssert( !(info&PROCESS_EE_XMM) );
252
253 GPR_reg64 sval = g_cpuConstRegs[_Rs_];
254
255 if (!sval.SD[0] && _Rd_ == _Rt_) {
256 /* To understand this 64-bit negate, consider that a negate in 2's complement
257 * is a NOT then an ADD 1. The upper word should only have the NOT stage unless
258 * the ADD overflows. The ADD only overflows if the lower word is 0.
259 * Incrementing before a NEG is the same as a NOT and the carry flag is set for
260 * a non-zero lower word.
261 */
262 xNEG(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]]);
263 xADC(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], 0);
264 xNEG(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]]);
265 return;
266 } else {
267 xMOV(eax, sval.SL[0]);
268 xMOV(edx, sval.SL[1]);
269 }
270
271 xSUB(eax, ptr32[&cpuRegs.GPR.r[_Rt_].SL[0]]);
272 xSBB(edx, ptr32[&cpuRegs.GPR.r[_Rt_].SL[1]]);
273 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], eax);
274 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], edx);
275 }
276
277 void recDSUB_constt(int info)
278 {
279 pxAssert( !(info&PROCESS_EE_XMM) );
280
281 GPR_reg64 tval = g_cpuConstRegs[_Rt_];
282
283 if (_Rd_ == _Rs_) {
284 xSUB(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], tval.SL[0]);
285 xSBB(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], tval.SL[1]);
286 } else {
287 xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rs_].SL[0]]);
288 xMOV(edx, ptr32[&cpuRegs.GPR.r[_Rs_].SL[1]]);
289 if (tval.SD[0]) {
290 xSUB(eax, tval.SL[0]);
291 xSBB(edx, tval.SL[1]);
292 }
293 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], eax);
294 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], edx);
295 }
296 }
297
298 void recDSUB_(int info)
299 {
300 pxAssert( !(info&PROCESS_EE_XMM) );
301
302 if (_Rs_ == _Rt_) {
303 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], 0);
304 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], 0);
305 } else if (_Rd_ == _Rs_) {
306 xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rt_].SL[0]]);
307 xMOV(edx, ptr32[&cpuRegs.GPR.r[_Rt_].SL[1]]);
308 xSUB(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], eax);
309 xSBB(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], edx);
310 } else {
311 xMOV(eax, ptr32[&cpuRegs.GPR.r[_Rs_].SL[0]]);
312 xMOV(edx, ptr32[&cpuRegs.GPR.r[_Rs_].SL[1]]);
313 xSUB(eax, ptr32[&cpuRegs.GPR.r[_Rt_].SL[0]]);
314 xSBB(edx, ptr32[&cpuRegs.GPR.r[_Rt_].SL[1]]);
315 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[0]], eax);
316 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].SL[1]], edx);
317 }
318 }
319
320 EERECOMPILE_CODE0(DSUB, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
321
322 //// DSUBU
323 void recDSUBU(void)
324 {
325 recDSUB();
326 }
327
328 //// AND
329 void recAND_const()
330 {
331 g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] & g_cpuConstRegs[_Rt_].UD[0];
332 }
333
334 void recAND_constv(int info, int creg, int vreg)
335 {
336 pxAssert( !(info & PROCESS_EE_XMM) );
337
338 GPR_reg64 cval = g_cpuConstRegs[creg];
339
340 for (int i = 0; i < 2; i++) {
341 if (!cval.UL[i]) {
342 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], 0);
343 } else if (_Rd_ == vreg) {
344 if (cval.UL[i] != -1)
345 xAND(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
346 } else {
347 xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].UL[i]]);
348 if (cval.UL[i] != -1)
349 xAND(eax, cval.UL[i]);
350 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
351 }
352 }
353 }
354
355 void recAND_consts(int info)
356 {
357 recAND_constv(info, _Rs_, _Rt_);
358 }
359
360 void recAND_constt(int info)
361 {
362 recAND_constv(info, _Rt_, _Rs_);
363 }
364
365 void recAND_(int info)
366 {
367 pxAssert( !(info & PROCESS_EE_XMM) );
368
369 int rs = _Rs_, rt = _Rt_;
370 if (_Rd_ == _Rt_)
371 rs = _Rt_, rt = _Rs_;
372
373 for (int i = 0; i < 2; i++) {
374 if (_Rd_ == rs) {
375 if (rs == rt)
376 continue;
377 xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
378 xAND(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
379 } else {
380 xMOV(eax, ptr32[&cpuRegs.GPR.r[rs].UL[i]]);
381 if (rs != rt)
382 xAND(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
383 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
384 }
385 }
386 }
387
388 EERECOMPILE_CODE0(AND, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
389
390 //// OR
391 void recOR_const()
392 {
393 g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] | g_cpuConstRegs[_Rt_].UD[0];
394 }
395
396 void recOR_constv(int info, int creg, int vreg)
397 {
398 pxAssert( !(info & PROCESS_EE_XMM) );
399
400 GPR_reg64 cval = g_cpuConstRegs[creg];
401
402 for (int i = 0; i < 2; i++) {
403 if (cval.UL[i] == -1) {
404 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], -1);
405 } else if (_Rd_ == vreg) {
406 if (cval.UL[i])
407 xOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
408 } else {
409 xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].UL[i]]);
410 if (cval.UL[i])
411 xOR(eax, cval.UL[i]);
412 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
413 }
414 }
415 }
416
417 void recOR_consts(int info)
418 {
419 recOR_constv(info, _Rs_, _Rt_);
420 }
421
422 void recOR_constt(int info)
423 {
424 recOR_constv(info, _Rt_, _Rs_);
425 }
426
427 void recOR_(int info)
428 {
429 pxAssert( !(info & PROCESS_EE_XMM) );
430
431 int rs = _Rs_, rt = _Rt_;
432 if (_Rd_ == _Rt_)
433 rs = _Rt_, rt = _Rs_;
434
435 for (int i = 0; i < 2; i++) {
436 if (_Rd_ == rs) {
437 if (rs == rt)
438 continue;
439 xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
440 xOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
441 } else {
442 xMOV(eax, ptr32[&cpuRegs.GPR.r[rs].UL[i]]);
443 if (rs != rt)
444 xOR(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
445 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
446 }
447 }
448 }
449
450 EERECOMPILE_CODE0(OR, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
451
452 //// XOR
453 void recXOR_const()
454 {
455 g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] ^ g_cpuConstRegs[_Rt_].UD[0];
456 }
457
458 void recXOR_constv(int info, int creg, int vreg)
459 {
460 pxAssert( !(info & PROCESS_EE_XMM) );
461
462 GPR_reg64 cval = g_cpuConstRegs[creg];
463
464 for (int i = 0; i < 2; i++) {
465 if (_Rd_ == vreg) {
466 if (cval.UL[i])
467 xXOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
468 } else {
469 xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].UL[i]]);
470 if (cval.UL[i])
471 xXOR(eax, cval.UL[i]);
472 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
473 }
474 }
475 }
476
477 void recXOR_consts(int info)
478 {
479 recXOR_constv(info, _Rs_, _Rt_);
480 }
481
482 void recXOR_constt(int info)
483 {
484 recXOR_constv(info, _Rt_, _Rs_);
485 }
486
487 void recXOR_(int info)
488 {
489 pxAssert( !(info & PROCESS_EE_XMM) );
490
491 int rs = _Rs_, rt = _Rt_;
492 if (_Rd_ == _Rt_)
493 rs = _Rt_, rt = _Rs_;
494
495 for (int i = 0; i < 2; i++) {
496 if (rs == rt) {
497 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], 0);
498 } else if (_Rd_ == rs) {
499 xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
500 xXOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
501 } else {
502 xMOV(eax, ptr32[&cpuRegs.GPR.r[rs].UL[i]]);
503 xXOR(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
504 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
505 }
506 }
507 }
508
509 EERECOMPILE_CODE0(XOR, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
510
511 //// NOR
512 void recNOR_const()
513 {
514 g_cpuConstRegs[_Rd_].UD[0] =~(g_cpuConstRegs[_Rs_].UD[0] | g_cpuConstRegs[_Rt_].UD[0]);
515 }
516
517 void recNOR_constv(int info, int creg, int vreg)
518 {
519 pxAssert( !(info & PROCESS_EE_XMM) );
520
521 GPR_reg64 cval = g_cpuConstRegs[creg];
522
523 for (int i = 0; i < 2; i++) {
524 if (_Rd_ == vreg) {
525 if (cval.UL[i])
526 xOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], cval.UL[i]);
527 xNOT(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]]);
528 } else {
529 xMOV(eax, ptr32[&cpuRegs.GPR.r[vreg].UL[i]]);
530 if (cval.UL[i])
531 xOR(eax, cval.UL[i]);
532 xNOT(eax);
533 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
534 }
535 }
536 }
537
538 void recNOR_consts(int info)
539 {
540 recNOR_constv(info, _Rs_, _Rt_);
541 }
542
543 void recNOR_constt(int info)
544 {
545 recNOR_constv(info, _Rt_, _Rs_);
546 }
547
548 void recNOR_(int info)
549 {
550 pxAssert( !(info & PROCESS_EE_XMM) );
551
552 int rs = _Rs_, rt = _Rt_;
553 if (_Rd_ == _Rt_)
554 rs = _Rt_, rt = _Rs_;
555
556 for (int i = 0; i < 2; i++) {
557 if (_Rd_ == rs) {
558 if (rs == rt) {
559 xNOT(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]]);
560 continue;
561 }
562 xMOV(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
563 xOR(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
564 xNOT(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]]);
565 } else {
566 xMOV(eax, ptr32[&cpuRegs.GPR.r[rs].UL[i]]);
567 if (rs != rt)
568 xOR(eax, ptr32[&cpuRegs.GPR.r[rt].UL[i]]);
569 xNOT(eax);
570 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[i]], eax);
571 }
572 }
573 }
574
575 EERECOMPILE_CODE0(NOR, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
576
577 //// SLT - test with silent hill, lemans
578 void recSLT_const()
579 {
580 g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].SD[0] < g_cpuConstRegs[_Rt_].SD[0];
581 }
582
583 void recSLTs_const(int info, int sign, int st)
584 {
585 pxAssert( !(info & PROCESS_EE_XMM) );
586
587 GPR_reg64 cval = g_cpuConstRegs[st ? _Rt_ : _Rs_];
588
589 xMOV(eax, 1);
590
591 xCMP(ptr32[&cpuRegs.GPR.r[st ? _Rs_ : _Rt_].UL[1]], cval.UL[1]);
592 xForwardJump8 pass1(st ? (sign ? Jcc_Less : Jcc_Below) : (sign ? Jcc_Greater : Jcc_Above));
593 xForwardJump8 fail(st ? (sign ? Jcc_Greater : Jcc_Above) : (sign ? Jcc_Less : Jcc_Below));
594 {
595 xCMP(ptr32[&cpuRegs.GPR.r[st ? _Rs_ : _Rt_].UL[0]], cval.UL[0]);
596 xForwardJump8 pass2(st ? Jcc_Below : Jcc_Above);
597
598 fail.SetTarget();
599 xMOV(eax, 0);
600 pass2.SetTarget();
601 }
602 pass1.SetTarget();
603
604 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
605 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[1]], 0);
606 }
607
608 void recSLTs_(int info, int sign)
609 {
610 pxAssert( !(info & PROCESS_EE_XMM) );
611
612 xMOV(eax, 1);
613
614 xMOV(edx, ptr32[&cpuRegs.GPR.r[_Rs_].UL[1]]);
615 xCMP(edx, ptr32[&cpuRegs.GPR.r[_Rt_].UL[1]]);
616 xForwardJump8 pass1(sign ? Jcc_Less : Jcc_Below);
617 xForwardJump8 fail(sign ? Jcc_Greater : Jcc_Above);
618 {
619 xMOV(edx, ptr32[&cpuRegs.GPR.r[_Rs_].UL[0]]);
620 xCMP(edx, ptr32[&cpuRegs.GPR.r[_Rt_].UL[0]]);
621 xForwardJump8 pass2(Jcc_Below);
622
623 fail.SetTarget();
624 xMOV(eax, 0);
625 pass2.SetTarget();
626 }
627 pass1.SetTarget();
628
629 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[0]], eax);
630 xMOV(ptr32[&cpuRegs.GPR.r[_Rd_].UL[1]], 0);
631 }
632
633 void recSLT_consts(int info)
634 {
635 recSLTs_const(info, 1, 0);
636 }
637
638 void recSLT_constt(int info)
639 {
640 recSLTs_const(info, 1, 1);
641 }
642
643 void recSLT_(int info)
644 {
645 recSLTs_(info, 1);
646 }
647
648 EERECOMPILE_CODE0(SLT, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
649
650 // SLTU - test with silent hill, lemans
651 void recSLTU_const()
652 {
653 g_cpuConstRegs[_Rd_].UD[0] = g_cpuConstRegs[_Rs_].UD[0] < g_cpuConstRegs[_Rt_].UD[0];
654 }
655
656 void recSLTU_consts(int info)
657 {
658 recSLTs_const(info, 0, 0);
659 }
660
661 void recSLTU_constt(int info)
662 {
663 recSLTs_const(info, 0, 1);
664 }
665
666 void recSLTU_(int info)
667 {
668 recSLTs_(info, 0);
669 }
670
671 EERECOMPILE_CODE0(SLTU, XMMINFO_READS|XMMINFO_READT|XMMINFO_WRITED);
672
673 #endif
674
675 } } }

  ViewVC Help
Powered by ViewVC 1.1.22