drc: try even more to not compile code as 64bit
[pcsx_rearmed.git] / libpcsxcore / ix86_64 / ix86_mmx.c
1 // stop compiling if NORECBUILD build (only for Visual Studio)
2 #if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
3
4 #include "ix86-64.h"
5
6 #include <assert.h>
7
8 /********************/
9 /* MMX instructions */
10 /********************/
11
12 // r64 = mm
13
14 /* movq m64 to r64 */
15 void MOVQMtoR( x86MMXRegType to, uptr from )
16 {
17         MEMADDR_OP(0, VAROP2(0x0F, 0x6F), true, to, from, 0);
18 }
19
20 /* movq r64 to m64 */
21 void MOVQRtoM( uptr to, x86MMXRegType from ) 
22 {
23         MEMADDR_OP(0, VAROP2(0x0F, 0x7F), true, from, to, 0);
24 }
25
26 /* pand r64 to r64 */
27 void PANDRtoR( x86MMXRegType to, x86MMXRegType from ) 
28 {
29         RexRB(0, to, from);
30         write16( 0xDB0F );
31         ModRM( 3, to, from ); 
32 }
33
34 void PANDNRtoR( x86MMXRegType to, x86MMXRegType from )
35 {
36         RexRB(0, to, from);
37         write16( 0xDF0F );
38         ModRM( 3, to, from ); 
39 }
40
41 /* por r64 to r64 */
42 void PORRtoR( x86MMXRegType to, x86MMXRegType from ) 
43 {
44         RexRB(0, to, from);
45         write16( 0xEB0F );
46         ModRM( 3, to, from ); 
47 }
48
49 /* pxor r64 to r64 */
50 void PXORRtoR( x86MMXRegType to, x86MMXRegType from ) 
51 {
52         RexRB(0, to, from);
53         write16( 0xEF0F );
54         ModRM( 3, to, from ); 
55 }
56
57 /* psllq r64 to r64 */
58 void PSLLQRtoR( x86MMXRegType to, x86MMXRegType from ) 
59 {
60         RexRB(0, to, from);
61         write16( 0xF30F );
62         ModRM( 3, to, from ); 
63 }
64
65 /* psllq m64 to r64 */
66 void PSLLQMtoR( x86MMXRegType to, uptr from ) 
67 {
68         MEMADDR_OP(0, VAROP2(0x0F, 0xF3), true, to, from, 0);
69 }
70
71 /* psllq imm8 to r64 */
72 void PSLLQItoR( x86MMXRegType to, u8 from ) 
73 {
74         RexB(0, to);
75         write16( 0x730F ); 
76         ModRM( 3, 6, to); 
77         write8( from ); 
78 }
79
80 /* psrlq r64 to r64 */
81 void PSRLQRtoR( x86MMXRegType to, x86MMXRegType from ) 
82 {
83         RexRB(0, to, from);
84         write16( 0xD30F ); 
85         ModRM( 3, to, from ); 
86 }
87
88 /* psrlq m64 to r64 */
89 void PSRLQMtoR( x86MMXRegType to, uptr from ) 
90 {
91         MEMADDR_OP(0, VAROP2(0x0F, 0xD3), true, to, from, 0);
92 }
93
94 /* psrlq imm8 to r64 */
95 void PSRLQItoR( x86MMXRegType to, u8 from ) 
96 {
97         RexB(0, to);
98         write16( 0x730F );
99         ModRM( 3, 2, to); 
100         write8( from ); 
101 }
102
103 /* paddusb r64 to r64 */
104 void PADDUSBRtoR( x86MMXRegType to, x86MMXRegType from ) 
105 {
106         RexRB(0, to, from);
107         write16( 0xDC0F ); 
108         ModRM( 3, to, from ); 
109 }
110
111 /* paddusb m64 to r64 */
112 void PADDUSBMtoR( x86MMXRegType to, uptr from ) 
113 {
114         MEMADDR_OP(0, VAROP2(0x0F, 0xDC), true, to, from, 0);
115 }
116
117 /* paddusw r64 to r64 */
118 void PADDUSWRtoR( x86MMXRegType to, x86MMXRegType from ) 
119 {
120         RexRB(0, to, from);
121         write16( 0xDD0F ); 
122         ModRM( 3, to, from ); 
123 }
124
125 /* paddusw m64 to r64 */
126 void PADDUSWMtoR( x86MMXRegType to, uptr from ) 
127 {
128         MEMADDR_OP(0, VAROP2(0x0F, 0xDD), true, to, from, 0);
129 }
130
131 /* paddb r64 to r64 */
132 void PADDBRtoR( x86MMXRegType to, x86MMXRegType from ) 
133 {
134         RexRB(0, to, from);
135         write16( 0xFC0F ); 
136         ModRM( 3, to, from ); 
137 }
138
139 /* paddb m64 to r64 */
140 void PADDBMtoR( x86MMXRegType to, uptr from ) 
141 {
142         MEMADDR_OP(0, VAROP2(0x0F, 0xFC), true, to, from, 0);
143 }
144
145 /* paddw r64 to r64 */
146 void PADDWRtoR( x86MMXRegType to, x86MMXRegType from ) 
147 {
148         RexRB(0, to, from);
149         write16( 0xFD0F ); 
150         ModRM( 3, to, from ); 
151 }
152
153 /* paddw m64 to r64 */
154 void PADDWMtoR( x86MMXRegType to, uptr from ) 
155 {
156         MEMADDR_OP(0, VAROP2(0x0F, 0xFD), true, to, from, 0);
157 }
158
159 /* paddd r64 to r64 */
160 void PADDDRtoR( x86MMXRegType to, x86MMXRegType from ) 
161 {
162         RexRB(0, to, from);
163         write16( 0xFE0F ); 
164         ModRM( 3, to, from ); 
165 }
166
167 /* paddd m64 to r64 */
168 void PADDDMtoR( x86MMXRegType to, uptr from ) 
169 {
170         MEMADDR_OP(0, VAROP2(0x0F, 0xFE), true, to, from, 0);
171 }
172
173 /* emms */
174 void EMMS( void ) 
175 {
176         write16( 0x770F );
177 }
178
179 void PADDSBRtoR( x86MMXRegType to, x86MMXRegType from ) 
180 {
181         RexRB(0, to, from);
182         write16( 0xEC0F ); 
183         ModRM( 3, to, from ); 
184 }
185
186 void PADDSWRtoR( x86MMXRegType to, x86MMXRegType from ) 
187 {
188         RexRB(0, to, from);
189         write16( 0xED0F );
190         ModRM( 3, to, from ); 
191 }
192
193 // paddq m64 to r64 (sse2 only?)
194 void PADDQMtoR( x86MMXRegType to, uptr from )
195 {
196         MEMADDR_OP(0, VAROP2(0x0F, 0xD4), true, to, from, 0);
197 }
198
199 // paddq r64 to r64 (sse2 only?)
200 void PADDQRtoR( x86MMXRegType to, x86MMXRegType from )
201 {
202         RexRB(0, to, from);
203         write16( 0xD40F ); 
204         ModRM( 3, to, from ); 
205 }
206
207 void PSUBSBRtoR( x86MMXRegType to, x86MMXRegType from ) 
208 {
209         RexRB(0, to, from);
210         write16( 0xE80F ); 
211         ModRM( 3, to, from ); 
212 }
213
214 void PSUBSWRtoR( x86MMXRegType to, x86MMXRegType from ) 
215 {
216         RexRB(0, to, from);
217         write16( 0xE90F );
218         ModRM( 3, to, from ); 
219 }
220
221
222 void PSUBBRtoR( x86MMXRegType to, x86MMXRegType from ) 
223 {
224         RexRB(0, to, from);
225         write16( 0xF80F ); 
226         ModRM( 3, to, from ); 
227 }
228
229 void PSUBWRtoR( x86MMXRegType to, x86MMXRegType from ) 
230 {
231         RexRB(0, to, from);
232         write16( 0xF90F ); 
233         ModRM( 3, to, from ); 
234 }
235
236 void PSUBDRtoR( x86MMXRegType to, x86MMXRegType from ) 
237 {
238         RexRB(0, to, from);
239         write16( 0xFA0F ); 
240         ModRM( 3, to, from ); 
241 }
242
243 void PSUBDMtoR( x86MMXRegType to, uptr from )
244 {
245         MEMADDR_OP(0, VAROP2(0x0F, 0xFA), true, to, from, 0);
246 }
247
248 void PSUBUSBRtoR( x86MMXRegType to, x86MMXRegType from ) 
249 {
250         RexRB(0, to, from);
251         write16( 0xD80F ); 
252         ModRM( 3, to, from ); 
253 }
254
255 void PSUBUSWRtoR( x86MMXRegType to, x86MMXRegType from ) 
256 {
257         RexRB(0, to, from);
258         write16( 0xD90F ); 
259         ModRM( 3, to, from ); 
260 }
261
262 // psubq m64 to r64 (sse2 only?)
263 void PSUBQMtoR( x86MMXRegType to, uptr from )
264 {
265         MEMADDR_OP(0, VAROP2(0x0F, 0xFB), true, to, from, 0);
266 }
267
268 // psubq r64 to r64 (sse2 only?)
269 void PSUBQRtoR( x86MMXRegType to, x86MMXRegType from )
270 {
271         RexRB(0, to, from);
272         write16( 0xFB0F ); 
273         ModRM( 3, to, from ); 
274 }
275
276 // pmuludq m64 to r64 (sse2 only?)
277 void PMULUDQMtoR( x86MMXRegType to, uptr from )
278 {
279         MEMADDR_OP(0, VAROP2(0x0F, 0xF4), true, to, from, 0);
280 }
281
282 // pmuludq r64 to r64 (sse2 only?)
283 void PMULUDQRtoR( x86MMXRegType to, x86MMXRegType from )
284 {
285         RexRB(0, to, from);
286         write16( 0xF40F ); 
287         ModRM( 3, to, from ); 
288 }
289
290 void PCMPEQBRtoR( x86MMXRegType to, x86MMXRegType from )
291 {
292         RexRB(0, to, from);
293         write16( 0x740F ); 
294         ModRM( 3, to, from ); 
295 }
296
297 void PCMPEQWRtoR( x86MMXRegType to, x86MMXRegType from )
298 {
299         RexRB(0, to, from);
300         write16( 0x750F ); 
301         ModRM( 3, to, from ); 
302 }
303
304 void PCMPEQDRtoR( x86MMXRegType to, x86MMXRegType from )
305 {
306         RexRB(0, to, from);
307         write16( 0x760F ); 
308         ModRM( 3, to, from ); 
309 }
310
311 void PCMPEQDMtoR( x86MMXRegType to, uptr from )
312 {
313         MEMADDR_OP(0, VAROP2(0x0F, 0x76), true, to, from, 0);
314 }
315
316 void PCMPGTBRtoR( x86MMXRegType to, x86MMXRegType from )
317 {
318         RexRB(0, to, from);
319         write16( 0x640F ); 
320         ModRM( 3, to, from ); 
321 }
322
323 void PCMPGTWRtoR( x86MMXRegType to, x86MMXRegType from )
324 {
325         RexRB(0, to, from);
326         write16( 0x650F ); 
327         ModRM( 3, to, from ); 
328 }
329
330 void PCMPGTDRtoR( x86MMXRegType to, x86MMXRegType from )
331 {
332         RexRB(0, to, from);
333         write16( 0x660F ); 
334         ModRM( 3, to, from ); 
335 }
336
337 void PCMPGTDMtoR( x86MMXRegType to, uptr from )
338 {
339         MEMADDR_OP(0, VAROP2(0x0F, 0x66), true, to, from, 0);
340 }
341
342 void PSRLWItoR( x86MMXRegType to, u8 from )
343 {
344         RexB(0, to);
345         write16( 0x710F );
346         ModRM( 3, 2 , to ); 
347         write8( from );
348 }
349
350 void PSRLDItoR( x86MMXRegType to, u8 from )
351 {
352         RexB(0, to);
353         write16( 0x720F );
354         ModRM( 3, 2 , to ); 
355         write8( from );
356 }
357
358 void PSRLDRtoR( x86MMXRegType to, x86MMXRegType from )
359 {
360         RexRB(0, to, from);
361         write16( 0xD20F );
362         ModRM( 3, to, from ); 
363 }
364
365 void PSLLWItoR( x86MMXRegType to, u8 from )
366 {
367         RexB(0, to);
368         write16( 0x710F );
369         ModRM( 3, 6 , to ); 
370         write8( from );
371 }
372
373 void PSLLDItoR( x86MMXRegType to, u8 from )
374 {
375         RexB(0, to);
376         write16( 0x720F );
377         ModRM( 3, 6 , to ); 
378         write8( from );
379 }
380
381 void PSLLDRtoR( x86MMXRegType to, x86MMXRegType from )
382 {
383         RexRB(0, to, from);
384         write16( 0xF20F );
385         ModRM( 3, to, from ); 
386 }
387
388 void PSRAWItoR( x86MMXRegType to, u8 from )
389 {
390         RexB(0, to);
391         write16( 0x710F );
392         ModRM( 3, 4 , to ); 
393         write8( from );
394 }
395
396 void PSRADItoR( x86MMXRegType to, u8 from )
397 {
398         RexB(0, to);
399         write16( 0x720F );
400         ModRM( 3, 4 , to ); 
401         write8( from );
402 }
403
404 void PSRADRtoR( x86MMXRegType to, x86MMXRegType from )
405 {
406         RexRB(0, to, from);
407         write16( 0xE20F );
408         ModRM( 3, to, from ); 
409 }
410
411 /* por m64 to r64 */
412 void PORMtoR( x86MMXRegType to, uptr from ) 
413 {
414         MEMADDR_OP(0, VAROP2(0x0F, 0xEB), true, to, from, 0);
415 }
416
417 /* pxor m64 to r64 */
418 void PXORMtoR( x86MMXRegType to, uptr from ) 
419 {
420         MEMADDR_OP(0, VAROP2(0x0F, 0xEF), true, to, from, 0);
421 }
422
423 /* pand m64 to r64 */
424 void PANDMtoR( x86MMXRegType to, uptr from ) 
425 {
426         MEMADDR_OP(0, VAROP2(0x0F, 0xDB), true, to, from, 0);
427 }
428
429 void PANDNMtoR( x86MMXRegType to, uptr from )
430 {
431         MEMADDR_OP(0, VAROP2(0x0F, 0xDF), true, to, from, 0);
432 }
433
434 void PUNPCKHDQRtoR( x86MMXRegType to, x86MMXRegType from )
435 {
436         RexRB(0, to, from);
437         write16( 0x6A0F );
438         ModRM( 3, to, from );
439 }
440
441 void PUNPCKHDQMtoR( x86MMXRegType to, uptr from )
442 {
443         MEMADDR_OP(0, VAROP2(0x0F, 0x6A), true, to, from, 0);
444 }
445
446 void PUNPCKLDQRtoR( x86MMXRegType to, x86MMXRegType from )
447 {
448         RexRB(0, to, from);
449         write16( 0x620F );
450         ModRM( 3, to, from );
451 }
452
453 void PUNPCKLDQMtoR( x86MMXRegType to, uptr from )
454 {
455         MEMADDR_OP(0, VAROP2(0x0F, 0x62), true, to, from, 0);
456 }
457
458 void MOVQ64ItoR( x86MMXRegType reg, u64 i ) 
459 {
460         RexR(0, reg);
461         write16(0x6F0F);
462         ModRM(0, reg, DISP32);
463         write32(2);
464         JMP8( 8 );
465         write64( i );
466 }
467
468 void MOVQRtoR( x86MMXRegType to, x86MMXRegType from )
469 {
470         RexRB(0, to, from);
471         write16( 0x6F0F );
472         ModRM( 3, to, from );
473 }
474
475 void MOVQRmtoROffset( x86MMXRegType to, x86IntRegType from, u32 offset )
476 {
477         RexRB(0, to, from);
478         write16( 0x6F0F );
479
480         if( offset < 128 ) {
481                 ModRM( 1, to, from );
482                 write8(offset);
483         }
484         else {
485                 ModRM( 2, to, from );
486                 write32(offset);
487         }
488 }
489
490 void MOVQRtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
491 {
492         RexRB(0, from, to);
493         write16( 0x7F0F );
494
495         if( offset < 128 ) {
496                 ModRM( 1, from , to );
497                 write8(offset);
498         }
499         else {
500                 ModRM( 2, from, to );
501                 write32(offset);
502         }
503 }
504
505 /* movd m32 to r64 */
506 void MOVDMtoMMX( x86MMXRegType to, uptr from ) 
507 {
508         MEMADDR_OP(0, VAROP2(0x0F, 0x6E), true, to, from, 0);
509 }
510
511 /* movd r64 to m32 */
512 void MOVDMMXtoM( uptr to, x86MMXRegType from ) 
513 {
514         MEMADDR_OP(0, VAROP2(0x0F, 0x7E), true, from, to, 0);
515 }
516
517 void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from )
518 {
519         RexRB(0, to, from);
520         write16( 0x6E0F );
521         ModRM( 3, to, from );
522 }
523
524 void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from )
525 {
526         RexRB(0, to, from);
527         write16( 0x6E0F );
528         ModRM( 0, to, from );
529 }
530
531 void MOVD32RmOffsettoMMX( x86MMXRegType to, x86IntRegType from, u32 offset )
532 {
533         RexRB(0, to, from);
534         write16( 0x6E0F );
535
536         if( offset < 128 ) {
537                 ModRM( 1, to, from );
538                 write8(offset);
539         }
540         else {
541                 ModRM( 2, to, from );
542                 write32(offset);
543         }
544 }
545
546 void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from )
547 {
548         RexRB(0, from, to);
549         write16( 0x7E0F );
550         ModRM( 3, from, to );
551 }
552
553 void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from )
554 {
555         RexRB(0, from, to);
556         write16( 0x7E0F );
557         ModRM( 0, from, to );
558         if( to >= 4 ) {
559                 // no idea why
560                 assert( to == ESP );
561                 write8(0x24);
562         }
563
564 }
565
566 void MOVD32MMXtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
567 {
568         RexRB(0, from, to);
569         write16( 0x7E0F );
570
571         if( offset < 128 ) {
572                 ModRM( 1, from, to );
573                 write8(offset);
574         }
575         else {
576                 ModRM( 2, from, to );
577                 write32(offset);
578         }
579 }
580
581 ///* movd r32 to r64 */
582 //void MOVD32MMXtoMMX( x86MMXRegType to, x86MMXRegType from ) 
583 //{
584 //      write16( 0x6E0F );
585 //      ModRM( 3, to, from );
586 //}
587 //
588 ///* movq r64 to r32 */
589 //void MOVD64MMXtoMMX( x86MMXRegType to, x86MMXRegType from ) 
590 //{
591 //      write16( 0x7E0F );
592 //      ModRM( 3, from, to );
593 //}
594
595 // untested
596 void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
597 {
598         RexRB(0, to, from);
599         write16( 0x630F );
600         ModRM( 3, to, from ); 
601 }
602
603 void PACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
604 {
605         RexRB(0, to, from);
606         write16( 0x6B0F );
607         ModRM( 3, to, from ); 
608 }
609
610 void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from)
611 {
612         RexRB(0, to, from);
613         write16( 0xD70F ); 
614         ModRM( 3, to, from );
615 }
616
617 void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 )
618 {
619         RexRB(0, to, from);
620         write16( 0xc40f );
621         ModRM( 3, to, from );
622         write8( imm8 );
623 }
624
625 void PSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8)
626 {
627         RexRB(0, to, from);
628         write16(0x700f);
629         ModRM( 3, to, from );
630         write8(imm8);
631 }
632
633 void PSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8)
634 {
635         MEMADDR_OP(0, VAROP2(0x0F, 0x70), true, to, from, 1 /* XXX was 0? */);
636         write8(imm8);
637 }
638
639 void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from)
640 {
641         RexRB(0, to, from);
642         write16(0xf70f);
643         ModRM( 3, to, from );
644 }
645
646 #endif