Core commit. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-core / src / r4300 / x86_64 / assemble.h
CommitLineData
451ab91e 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - assemble.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2007 Richard Goedeken (Richard42) *
5 * Copyright (C) 2002 Hacktarux *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22
23#ifndef __ASSEMBLE_H__
24#define __ASSEMBLE_H__
25
26#include "r4300/recomph.h"
27#include "api/callbacks.h"
28
29#include <stdlib.h>
30
31extern long long int reg[32];
32
33#define RAX 0
34#define RCX 1
35#define RDX 2
36#define RBX 3
37#define RSP 4
38#define RBP 5
39#define RSI 6
40#define RDI 7
41
42#define EAX 0
43#define ECX 1
44#define EDX 2
45#define EBX 3
46#define ESP 4
47#define EBP 5
48#define ESI 6
49#define EDI 7
50
51#define AX 0
52#define CX 1
53#define DX 2
54#define BX 3
55#define SP 4
56#define BP 5
57#define SI 6
58#define DI 7
59
60#define AL 0
61#define CL 1
62#define DL 2
63#define BL 3
64#define AH 4
65#define CH 5
66#define DH 6
67#define BH 7
68
69extern int branch_taken;
70
71void jump_start_rel8(void);
72void jump_end_rel8(void);
73void jump_start_rel32(void);
74void jump_end_rel32(void);
75void add_jump(unsigned int pc_addr, unsigned int mi_addr, unsigned int absolute64);
76
77static inline void put8(unsigned char octet)
78{
79 (*inst_pointer)[code_length] = octet;
80 code_length++;
81 if (code_length == max_code_length)
82 {
83 *inst_pointer = realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
84 max_code_length += 8192;
85 }
86}
87
88static inline void put32(unsigned int dword)
89{
90 if ((code_length + 4) >= max_code_length)
91 {
92 *inst_pointer = realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
93 max_code_length += 8192;
94 }
95 *((unsigned int *) (*inst_pointer + code_length)) = dword;
96 code_length += 4;
97}
98
99static inline void put64(unsigned long long qword)
100{
101 if ((code_length + 8) >= max_code_length)
102 {
103 *inst_pointer = realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
104 max_code_length += 8192;
105 }
106 *((unsigned long long *) (*inst_pointer + code_length)) = qword;
107 code_length += 8;
108}
109
110static inline int rel_r15_offset(void *dest, const char *op_name)
111{
112 /* calculate the destination pointer's offset from the base of the r4300 registers */
113 long long rel_offset = (long long) ((unsigned char *) dest - (unsigned char *) reg);
114
115 if (llabs(rel_offset) > 0x7fffffff)
116 {
117 DebugMessage(M64MSG_ERROR, "Error: destination %p more than 2GB away from r15 base %p in %s()", dest, reg, op_name);
118 asm(" int $3; ");
119 }
120
121 return (int) rel_offset;
122}
123
124static inline void mov_memoffs32_eax(unsigned int *memoffs32)
125{
126 put8(0xA3);
127 put64((unsigned long long) memoffs32);
128}
129
130static inline void mov_rax_memoffs64(unsigned long long *memoffs64)
131{
132 put8(0x48);
133 put8(0xA1);
134 put64((unsigned long long) memoffs64);
135}
136
137static inline void mov_memoffs64_rax(unsigned long long *memoffs64)
138{
139 put8(0x48);
140 put8(0xA3);
141 put64((unsigned long long) memoffs64);
142}
143
144static inline void mov_m8rel_xreg8(unsigned char *m8, int xreg8)
145{
146 int offset = rel_r15_offset(m8, "mov_m8rel_xreg8");
147
148 put8(0x41 | ((xreg8 & 8) >> 1));
149 put8(0x88);
150 put8(0x87 | ((xreg8 & 7) << 3));
151 put32(offset);
152}
153
154static inline void mov_xreg16_m16rel(int xreg16, unsigned short *m16)
155{
156 int offset = rel_r15_offset(m16, "mov_xreg16_m16rel");
157
158 put8(0x66);
159 put8(0x41 | ((xreg16 & 8) >> 1));
160 put8(0x8B);
161 put8(0x87 | ((xreg16 & 7) << 3));
162 put32(offset);
163}
164
165static inline void mov_m16rel_xreg16(unsigned short *m16, int xreg16)
166{
167 int offset = rel_r15_offset(m16, "mov_m16rel_xreg16");
168
169 put8(0x66);
170 put8(0x41 | ((xreg16 & 8) >> 1));
171 put8(0x89);
172 put8(0x87 | ((xreg16 & 7) << 3));
173 put32(offset);
174}
175
176static inline void cmp_xreg32_m32rel(int xreg32, unsigned int *m32)
177{
178 int offset = rel_r15_offset(m32, "cmp_xreg32_m32rel");
179
180 put8(0x41 | ((xreg32 & 8) >> 1));
181 put8(0x3B);
182 put8(0x87 | ((xreg32 & 7) << 3));
183 put32(offset);
184}
185
186static inline void cmp_xreg64_m64rel(int xreg64, unsigned long long *m64)
187{
188 int offset = rel_r15_offset(m64, "cmp_xreg64_m64rel");
189
190 put8(0x49 | ((xreg64 & 8) >> 1));
191 put8(0x3B);
192 put8(0x87 | ((xreg64 & 7) << 3));
193 put32(offset);
194}
195
196static inline void cmp_reg32_reg32(int reg1, int reg2)
197{
198 put8(0x39);
199 put8((reg2 << 3) | reg1 | 0xC0);
200}
201
202static inline void cmp_reg64_reg64(int reg1, int reg2)
203{
204 put8(0x48);
205 put8(0x39);
206 put8((reg2 << 3) | reg1 | 0xC0);
207}
208
209static inline void cmp_reg32_imm8(int reg32, unsigned char imm8)
210{
211 put8(0x83);
212 put8(0xF8 + reg32);
213 put8(imm8);
214}
215
216static inline void cmp_reg64_imm8(int reg64, unsigned char imm8)
217{
218 put8(0x48);
219 put8(0x83);
220 put8(0xF8 + reg64);
221 put8(imm8);
222}
223
224static inline void cmp_reg32_imm32(int reg32, unsigned int imm32)
225{
226 put8(0x81);
227 put8(0xF8 + reg32);
228 put32(imm32);
229}
230
231static inline void cmp_reg64_imm32(int reg64, unsigned int imm32)
232{
233 put8(0x48);
234 put8(0x81);
235 put8(0xF8 + reg64);
236 put32(imm32);
237}
238
239static inline void cmp_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8)
240{
241 put8(0x80);
242 put8(0x3C);
243 put8((reg1 << 3) | reg2);
244 put8(imm8);
245}
246
247static inline void sete_m8rel(unsigned char *m8)
248{
249 int offset = rel_r15_offset(m8, "sete_m8rel");
250
251 put8(0x41);
252 put8(0x0F);
253 put8(0x94);
254 put8(0x87);
255 put32(offset);
256}
257
258static inline void setne_m8rel(unsigned char *m8)
259{
260 int offset = rel_r15_offset(m8, "setne_m8rel");
261
262 put8(0x41);
263 put8(0x0F);
264 put8(0x95);
265 put8(0x87);
266 put32(offset);
267}
268
269static inline void setl_m8rel(unsigned char *m8)
270{
271 int offset = rel_r15_offset(m8, "setl_m8rel");
272
273 put8(0x41);
274 put8(0x0F);
275 put8(0x9C);
276 put8(0x87);
277 put32(offset);
278}
279
280static inline void setle_m8rel(unsigned char *m8)
281{
282 int offset = rel_r15_offset(m8, "setle_m8rel");
283
284 put8(0x41);
285 put8(0x0F);
286 put8(0x9E);
287 put8(0x87);
288 put32(offset);
289}
290
291static inline void setg_m8rel(unsigned char *m8)
292{
293 int offset = rel_r15_offset(m8, "setg_m8rel");
294
295 put8(0x41);
296 put8(0x0F);
297 put8(0x9F);
298 put8(0x87);
299 put32(offset);
300}
301
302static inline void setge_m8rel(unsigned char *m8)
303{
304 int offset = rel_r15_offset(m8, "setge_m8rel");
305
306 put8(0x41);
307 put8(0x0F);
308 put8(0x9D);
309 put8(0x87);
310 put32(offset);
311}
312
313static inline void setl_reg8(unsigned int reg8)
314{
315 put8(0x40); /* we need an REX prefix to use the uniform byte registers */
316 put8(0x0F);
317 put8(0x9C);
318 put8(0xC0 | reg8);
319}
320
321static inline void setb_reg8(unsigned int reg8)
322{
323 put8(0x40); /* we need an REX prefix to use the uniform byte registers */
324 put8(0x0F);
325 put8(0x92);
326 put8(0xC0 | reg8);
327}
328
329static inline void test_m32rel_imm32(unsigned int *m32, unsigned int imm32)
330{
331 int offset = rel_r15_offset(m32, "test_m32rel_imm32");
332
333 put8(0x41);
334 put8(0xF7);
335 put8(0x87);
336 put32(offset);
337 put32(imm32);
338}
339
340static inline void add_m32rel_xreg32(unsigned int *m32, int xreg32)
341{
342 int offset = rel_r15_offset(m32, "add_m32rel_xreg32");
343
344 put8(0x41 | ((xreg32 & 8) >> 1));
345 put8(0x01);
346 put8(0x87 | ((xreg32 & 7) << 3));
347 put32(offset);
348}
349
350static inline void sub_xreg32_m32rel(int xreg32, unsigned int *m32)
351{
352 int offset = rel_r15_offset(m32, "sub_xreg32_m32rel");
353
354 put8(0x41 | ((xreg32 & 8) >> 1));
355 put8(0x2B);
356 put8(0x87 | ((xreg32 & 7) << 3));
357 put32(offset);
358}
359
360static inline void sub_reg32_reg32(int reg1, int reg2)
361{
362 put8(0x29);
363 put8((reg2 << 3) | reg1 | 0xC0);
364}
365
366static inline void sub_reg64_reg64(int reg1, int reg2)
367{
368 put8(0x48);
369 put8(0x29);
370 put8((reg2 << 3) | reg1 | 0xC0);
371}
372
373static inline void sub_reg64_imm32(int reg64, unsigned int imm32)
374{
375 put8(0x48);
376 put8(0x81);
377 put8(0xE8 + reg64);
378 put32(imm32);
379}
380
381static inline void sub_eax_imm32(unsigned int imm32)
382{
383 put8(0x2D);
384 put32(imm32);
385}
386
387static inline void jne_rj(unsigned char saut)
388{
389 put8(0x75);
390 put8(saut);
391}
392
393static inline void je_rj(unsigned char saut)
394{
395 put8(0x74);
396 put8(saut);
397}
398
399static inline void jbe_rj(unsigned char saut)
400{
401 put8(0x76);
402 put8(saut);
403}
404
405static inline void ja_rj(unsigned char saut)
406{
407 put8(0x77);
408 put8(saut);
409}
410
411static inline void jae_rj(unsigned char saut)
412{
413 put8(0x73);
414 put8(saut);
415}
416
417static inline void jp_rj(unsigned char saut)
418{
419 put8(0x7A);
420 put8(saut);
421}
422
423static inline void je_near_rj(unsigned int saut)
424{
425 put8(0x0F);
426 put8(0x84);
427 put32(saut);
428}
429
430static inline void mov_reg32_imm32(int reg32, unsigned int imm32)
431{
432 put8(0xB8+reg32);
433 put32(imm32);
434}
435
436static inline void mov_reg64_imm64(int reg64, unsigned long long imm64)
437{
438 put8(0x48);
439 put8(0xB8+reg64);
440 put64(imm64);
441}
442
443static inline void jmp_imm_short(char saut)
444{
445 put8(0xEB);
446 put8(saut);
447}
448
449static inline void or_m32rel_imm32(unsigned int *m32, unsigned int imm32)
450{
451 int offset = rel_r15_offset(m32, "or_m32rel_imm32");
452
453 put8(0x41);
454 put8(0x81);
455 put8(0x8F);
456 put32(offset);
457 put32(imm32);
458}
459
460static inline void or_reg64_reg64(unsigned int reg1, unsigned int reg2)
461{
462 put8(0x48);
463 put8(0x09);
464 put8(0xC0 | (reg2 << 3) | reg1);
465}
466
467static inline void and_reg64_reg64(unsigned int reg1, unsigned int reg2)
468{
469 put8(0x48);
470 put8(0x21);
471 put8(0xC0 | (reg2 << 3) | reg1);
472}
473
474static inline void and_m32rel_imm32(unsigned int *m32, unsigned int imm32)
475{
476 int offset = rel_r15_offset(m32, "and_m32rel_imm32");
477
478 put8(0x41);
479 put8(0x81);
480 put8(0xA7);
481 put32(offset);
482 put32(imm32);
483}
484
485static inline void xor_reg32_reg32(unsigned int reg1, unsigned int reg2)
486{
487 put8(0x31);
488 put8(0xC0 | (reg2 << 3) | reg1);
489}
490
491static inline void xor_reg64_reg64(unsigned int reg1, unsigned int reg2)
492{
493 put8(0x48);
494 put8(0x31);
495 put8(0xC0 | (reg2 << 3) | reg1);
496}
497
498static inline void add_reg64_imm32(unsigned int reg64, unsigned int imm32)
499{
500 put8(0x48);
501 put8(0x81);
502 put8(0xC0+reg64);
503 put32(imm32);
504}
505
506static inline void add_reg32_imm32(unsigned int reg32, unsigned int imm32)
507{
508 put8(0x81);
509 put8(0xC0+reg32);
510 put32(imm32);
511}
512
513static inline void inc_m32rel(unsigned int *m32)
514{
515 int offset = rel_r15_offset(m32, "inc_m32rel");
516
517 put8(0x41);
518 put8(0xFF);
519 put8(0x87);
520 put32(offset);
521}
522
523static inline void cmp_m32rel_imm32(unsigned int *m32, unsigned int imm32)
524{
525 int offset = rel_r15_offset(m32, "cmp_m32rel_imm32");
526
527 put8(0x41);
528 put8(0x81);
529 put8(0xBF);
530 put32(offset);
531 put32(imm32);
532}
533
534static inline void cmp_eax_imm32(unsigned int imm32)
535{
536 put8(0x3D);
537 put32(imm32);
538}
539
540static inline void mov_m32rel_imm32(unsigned int *m32, unsigned int imm32)
541{
542 int offset = rel_r15_offset(m32, "mov_m32rel_imm32");
543
544 put8(0x41);
545 put8(0xC7);
546 put8(0x87);
547 put32(offset);
548 put32(imm32);
549}
550
551static inline void jmp(unsigned int mi_addr)
552{
553 put8(0xFF);
554 put8(0x25);
555 put32(0);
556 put64(0);
557 add_jump(code_length-8, mi_addr, 1);
558}
559
560static inline void cdq(void)
561{
562 put8(0x99);
563}
564
565static inline void call_reg64(unsigned int reg64)
566{
567 put8(0xFF);
568 put8(0xD0+reg64);
569}
570
571static inline void shr_reg64_imm8(unsigned int reg64, unsigned char imm8)
572{
573 put8(0x48);
574 put8(0xC1);
575 put8(0xE8+reg64);
576 put8(imm8);
577}
578
579static inline void shr_reg32_imm8(unsigned int reg32, unsigned char imm8)
580{
581 put8(0xC1);
582 put8(0xE8+reg32);
583 put8(imm8);
584}
585
586static inline void shr_reg32_cl(unsigned int reg32)
587{
588 put8(0xD3);
589 put8(0xE8+reg32);
590}
591
592static inline void shr_reg64_cl(unsigned int reg64)
593{
594 put8(0x48);
595 put8(0xD3);
596 put8(0xE8+reg64);
597}
598
599static inline void sar_reg32_cl(unsigned int reg32)
600{
601 put8(0xD3);
602 put8(0xF8+reg32);
603}
604
605static inline void sar_reg64_cl(unsigned int reg64)
606{
607 put8(0x48);
608 put8(0xD3);
609 put8(0xF8+reg64);
610}
611
612static inline void shl_reg32_cl(unsigned int reg32)
613{
614 put8(0xD3);
615 put8(0xE0+reg32);
616}
617
618static inline void shl_reg64_cl(unsigned int reg64)
619{
620 put8(0x48);
621 put8(0xD3);
622 put8(0xE0+reg64);
623}
624
625static inline void sar_reg32_imm8(unsigned int reg32, unsigned char imm8)
626{
627 put8(0xC1);
628 put8(0xF8+reg32);
629 put8(imm8);
630}
631
632static inline void sar_reg64_imm8(unsigned int reg64, unsigned char imm8)
633{
634 put8(0x48);
635 put8(0xC1);
636 put8(0xF8+reg64);
637 put8(imm8);
638}
639
640static inline void mul_m32rel(unsigned int *m32)
641{
642 int offset = rel_r15_offset(m32, "mul_m32rel");
643
644 put8(0x41);
645 put8(0xF7);
646 put8(0xA7);
647 put32(offset);
648}
649
650static inline void imul_reg32(unsigned int reg32)
651{
652 put8(0xF7);
653 put8(0xE8+reg32);
654}
655
656static inline void mul_reg64(unsigned int reg64)
657{
658 put8(0x48);
659 put8(0xF7);
660 put8(0xE0+reg64);
661}
662
663static inline void mul_reg32(unsigned int reg32)
664{
665 put8(0xF7);
666 put8(0xE0+reg32);
667}
668
669static inline void idiv_reg32(unsigned int reg32)
670{
671 put8(0xF7);
672 put8(0xF8+reg32);
673}
674
675static inline void div_reg32(unsigned int reg32)
676{
677 put8(0xF7);
678 put8(0xF0+reg32);
679}
680
681static inline void add_reg32_reg32(unsigned int reg1, unsigned int reg2)
682{
683 put8(0x01);
684 put8(0xC0 | (reg2 << 3) | reg1);
685}
686
687static inline void add_reg64_reg64(unsigned int reg1, unsigned int reg2)
688{
689 put8(0x48);
690 put8(0x01);
691 put8(0xC0 | (reg2 << 3) | reg1);
692}
693
694static inline void jmp_reg64(unsigned int reg64)
695{
696 put8(0xFF);
697 put8(0xE0 + reg64);
698}
699
700static inline void mov_reg32_preg64(unsigned int reg1, unsigned int reg2)
701{
702 put8(0x8B);
703 put8((reg1 << 3) | reg2);
704}
705
706static inline void mov_preg64_reg32(int reg1, int reg2)
707{
708 put8(0x89);
709 put8((reg2 << 3) | reg1);
710}
711
712static inline void mov_reg64_preg64(int reg1, int reg2)
713{
714 put8(0x48);
715 put8(0x8B);
716 put8((reg1 << 3) | reg2);
717}
718
719static inline void mov_reg32_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
720{
721 put8(0x8B);
722 put8((reg1 << 3) | 0x84);
723 put8(reg2 | (reg3 << 3));
724 put32(imm32);
725}
726
727static inline void mov_preg64preg64pimm32_reg32(int reg1, int reg2, unsigned int imm32, int reg3)
728{
729 put8(0x89);
730 put8((reg3 << 3) | 0x84);
731 put8(reg1 | (reg2 << 3));
732 put32(imm32);
733}
734
735static inline void mov_reg64_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
736{
737 put8(0x48);
738 put8(0x8B);
739 put8((reg1 << 3) | 0x84);
740 put8(reg2 | (reg3 << 3));
741 put32(imm32);
742}
743
744static inline void mov_reg32_preg64preg64(int reg1, int reg2, int reg3)
745{
746 put8(0x8B);
747 put8((reg1 << 3) | 0x04);
748 put8((reg2 << 3) | reg3);
749}
750
751static inline void mov_reg64_preg64preg64(int reg1, int reg2, int reg3)
752{
753 put8(0x48);
754 put8(0x8B);
755 put8((reg1 << 3) | 0x04);
756 put8(reg2 | (reg3 << 3));
757}
758
759static inline void mov_reg32_preg64pimm32(int reg1, int reg2, unsigned int imm32)
760{
761 put8(0x8B);
762 put8(0x80 | (reg1 << 3) | reg2);
763 put32(imm32);
764}
765
766static inline void mov_reg64_preg64pimm32(int reg1, int reg2, unsigned int imm32)
767{
768 put8(0x48);
769 put8(0x8B);
770 put8(0x80 | (reg1 << 3) | reg2);
771 put32(imm32);
772}
773
774static inline void mov_reg64_preg64pimm8(int reg1, int reg2, unsigned int imm8)
775{
776 put8(0x48);
777 put8(0x8B);
778 put8(0x40 | (reg1 << 3) | reg2);
779 put8(imm8);
780}
781
782static inline void mov_reg64_preg64x8preg64(int reg1, int reg2, int reg3)
783{
784 put8(0x48);
785 put8(0x8B);
786 put8((reg1 << 3) | 4);
787 put8(0xC0 | (reg2 << 3) | reg3);
788}
789
790static inline void mov_preg64preg64_reg8(int reg1, int reg2, int reg8)
791{
792 put8(0x88);
793 put8(0x04 | (reg8 << 3));
794 put8((reg1 << 3) | reg2);
795}
796
797static inline void mov_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8)
798{
799 put8(0xC6);
800 put8(0x04);
801 put8((reg1 << 3) | reg2);
802 put8(imm8);
803}
804
805static inline void mov_preg64preg64_reg16(int reg1, int reg2, int reg16)
806{
807 put8(0x66);
808 put8(0x89);
809 put8(0x04 | (reg16 << 3));
810 put8((reg1 << 3) | reg2);
811}
812
813static inline void mov_preg64preg64_reg32(int reg1, int reg2, int reg32)
814{
815 put8(0x89);
816 put8(0x04 | (reg32 << 3));
817 put8((reg1 << 3) | reg2);
818}
819
820static inline void mov_preg64pimm32_reg32(int reg1, unsigned int imm32, int reg2)
821{
822 put8(0x89);
823 put8(0x80 | reg1 | (reg2 << 3));
824 put32(imm32);
825}
826
827static inline void mov_preg64pimm8_reg64(int reg1, unsigned int imm8, int reg2)
828{
829 put8(0x48);
830 put8(0x89);
831 put8(0x40 | (reg2 << 3) | reg1);
832 put8(imm8);
833}
834
835static inline void add_eax_imm32(unsigned int imm32)
836{
837 put8(0x05);
838 put32(imm32);
839}
840
841static inline void shl_reg32_imm8(unsigned int reg32, unsigned char imm8)
842{
843 put8(0xC1);
844 put8(0xE0 + reg32);
845 put8(imm8);
846}
847
848static inline void shl_reg64_imm8(unsigned int reg64, unsigned char imm8)
849{
850 put8(0x48);
851 put8(0xC1);
852 put8(0xE0 + reg64);
853 put8(imm8);
854}
855
856static inline void mov_reg32_reg32(unsigned int reg1, unsigned int reg2)
857{
858 if (reg1 == reg2) return;
859 put8(0x89);
860 put8(0xC0 | (reg2 << 3) | reg1);
861}
862
863static inline void mov_reg64_reg64(unsigned int reg1, unsigned int reg2)
864{
865 if (reg1 == reg2) return;
866 put8(0x48);
867 put8(0x89);
868 put8(0xC0 | (reg2 << 3) | reg1);
869}
870
871static inline void mov_xreg32_m32rel(unsigned int xreg32, unsigned int *m32)
872{
873 int offset = rel_r15_offset(m32, "mov_xreg32_m32rel");
874
875 put8(0x41 | ((xreg32 & 8) >> 1));
876 put8(0x8B);
877 put8(0x87 | ((xreg32 & 7) << 3));
878 put32(offset);
879}
880
881static inline void mov_m32rel_xreg32(unsigned int *m32, unsigned int xreg32)
882{
883 int offset = rel_r15_offset(m32, "mov_m32rel_xreg32");
884
885 put8(0x41 | ((xreg32 & 8) >> 1));
886 put8(0x89);
887 put8(0x87 | ((xreg32 & 7) << 3));
888 put32(offset);
889}
890
891static inline void mov_xreg64_m64rel(unsigned int xreg64, unsigned long long* m64)
892{
893 int offset = rel_r15_offset(m64, "mov_xreg64_m64rel");
894
895 put8(0x49 | ((xreg64 & 8) >> 1));
896 put8(0x8B);
897 put8(0x87 | ((xreg64 & 7) << 3));
898 put32(offset);
899}
900
901static inline void mov_m64rel_xreg64(unsigned long long *m64, unsigned int xreg64)
902{
903 int offset = rel_r15_offset(m64, "mov_m64rel_xreg64");
904
905 put8(0x49 | ((xreg64 & 8) >> 1));
906 put8(0x89);
907 put8(0x87 | ((xreg64 & 7) << 3));
908 put32(offset);
909}
910
911static inline void mov_xreg8_m8rel(int xreg8, unsigned char *m8)
912{
913 int offset = rel_r15_offset(m8, "mov_xreg8_m8rel");
914
915 put8(0x41 | ((xreg8 & 8) >> 1));
916 put8(0x8A);
917 put8(0x87 | ((xreg8 & 7) << 3));
918 put32(offset);
919}
920
921static inline void and_eax_imm32(unsigned int imm32)
922{
923 put8(0x25);
924 put32(imm32);
925}
926
927static inline void or_reg64_imm32(int reg64, unsigned int imm32)
928{
929 put8(0x48);
930 put8(0x81);
931 put8(0xC8 + reg64);
932 put32(imm32);
933}
934
935static inline void and_reg32_imm32(int reg32, unsigned int imm32)
936{
937 put8(0x81);
938 put8(0xE0 + reg32);
939 put32(imm32);
940}
941
942static inline void and_reg64_imm32(int reg64, unsigned int imm32)
943{
944 put8(0x48);
945 put8(0x81);
946 put8(0xE0 + reg64);
947 put32(imm32);
948}
949
950static inline void and_reg64_imm8(int reg64, unsigned char imm8)
951{
952 put8(0x48);
953 put8(0x83);
954 put8(0xE0 + reg64);
955 put8(imm8);
956}
957
958static inline void xor_reg64_imm32(int reg64, unsigned int imm32)
959{
960 put8(0x48);
961 put8(0x81);
962 put8(0xF0 + reg64);
963 put32(imm32);
964}
965
966static inline void xor_reg8_imm8(int reg8, unsigned char imm8)
967{
968 put8(0x40); /* we need an REX prefix to use the uniform byte registers */
969 put8(0x80);
970 put8(0xF0 + reg8);
971 put8(imm8);
972}
973
974static inline void not_reg64(unsigned int reg64)
975{
976 put8(0x48);
977 put8(0xF7);
978 put8(0xD0 + reg64);
979}
980
981static inline void neg_reg32(unsigned int reg32)
982{
983 put8(0xF7);
984 put8(0xD8 + reg32);
985}
986
987static inline void neg_reg64(unsigned int reg64)
988{
989 put8(0x48);
990 put8(0xF7);
991 put8(0xD8 + reg64);
992}
993
994static inline void movsx_xreg32_m8rel(int xreg32, unsigned char *m8)
995{
996 int offset = rel_r15_offset(m8, "movsx_xreg32_m8rel");
997
998 put8(0x41 | ((xreg32 & 8) >> 1));
999 put8(0x0F);
1000 put8(0xBE);
1001 put8(0x87 | ((xreg32 & 7) << 3));
1002 put32(offset);
1003}
1004
1005static inline void movsx_reg32_8preg64preg64(int reg1, int reg2, int reg3)
1006{
1007 put8(0x0F);
1008 put8(0xBE);
1009 put8((reg1 << 3) | 0x04);
1010 put8((reg2 << 3) | reg3);
1011}
1012
1013static inline void movsx_reg32_16preg64preg64(int reg1, int reg2, int reg3)
1014{
1015 put8(0x0F);
1016 put8(0xBF);
1017 put8((reg1 << 3) | 0x04);
1018 put8((reg2 << 3) | reg3);
1019}
1020
1021static inline void movsx_xreg32_m16rel(int xreg32, unsigned short *m16)
1022{
1023 int offset = rel_r15_offset(m16, "movsx_xreg32_m16rel");
1024
1025 put8(0x41 | ((xreg32 & 8) >> 1));
1026 put8(0x0F);
1027 put8(0xBF);
1028 put8(0x87 | ((xreg32 & 7) << 3));
1029 put32(offset);
1030}
1031
1032static inline void movsxd_reg64_reg32(int reg64, int reg32)
1033{
1034 put8(0x48);
1035 put8(0x63);
1036 put8((reg64 << 3) | reg32 | 0xC0);
1037}
1038
1039static inline void fldcw_m16rel(unsigned short *m16)
1040{
1041 int offset = rel_r15_offset(m16, "fldcw_m16rel");
1042
1043 put8(0x41);
1044 put8(0xD9);
1045 put8(0xAF);
1046 put32(offset);
1047}
1048
1049static inline void fld_preg64_dword(int reg64)
1050{
1051 put8(0xD9);
1052 put8(reg64);
1053}
1054
1055static inline void fdiv_preg64_dword(int reg64)
1056{
1057 put8(0xD8);
1058 put8(0x30 + reg64);
1059}
1060
1061static inline void fstp_preg64_dword(int reg64)
1062{
1063 put8(0xD9);
1064 put8(0x18 + reg64);
1065}
1066
1067static inline void fchs(void)
1068{
1069 put8(0xD9);
1070 put8(0xE0);
1071}
1072
1073static inline void fstp_preg64_qword(int reg64)
1074{
1075 put8(0xDD);
1076 put8(0x18 + reg64);
1077}
1078
1079static inline void fadd_preg64_dword(int reg64)
1080{
1081 put8(0xD8);
1082 put8(reg64);
1083}
1084
1085static inline void fsub_preg64_dword(int reg64)
1086{
1087 put8(0xD8);
1088 put8(0x20 + reg64);
1089}
1090
1091static inline void fmul_preg64_dword(int reg64)
1092{
1093 put8(0xD8);
1094 put8(0x08 + reg64);
1095}
1096
1097static inline void fistp_preg64_dword(int reg64)
1098{
1099 put8(0xDB);
1100 put8(0x18 + reg64);
1101}
1102
1103static inline void fistp_preg64_qword(int reg64)
1104{
1105 put8(0xDF);
1106 put8(0x38 + reg64);
1107}
1108
1109static inline void fld_preg64_qword(int reg64)
1110{
1111 put8(0xDD);
1112 put8(reg64);
1113}
1114
1115static inline void fild_preg64_qword(int reg64)
1116{
1117 put8(0xDF);
1118 put8(0x28+reg64);
1119}
1120
1121static inline void fild_preg64_dword(int reg64)
1122{
1123 put8(0xDB);
1124 put8(reg64);
1125}
1126
1127static inline void fadd_preg64_qword(int reg64)
1128{
1129 put8(0xDC);
1130 put8(reg64);
1131}
1132
1133static inline void fdiv_preg64_qword(int reg64)
1134{
1135 put8(0xDC);
1136 put8(0x30 + reg64);
1137}
1138
1139static inline void fsub_preg64_qword(int reg64)
1140{
1141 put8(0xDC);
1142 put8(0x20 + reg64);
1143}
1144
1145static inline void fmul_preg64_qword(int reg64)
1146{
1147 put8(0xDC);
1148 put8(0x08 + reg64);
1149}
1150
1151static inline void fsqrt(void)
1152{
1153 put8(0xD9);
1154 put8(0xFA);
1155}
1156
1157static inline void fabs_(void)
1158{
1159 put8(0xD9);
1160 put8(0xE1);
1161}
1162
1163static inline void fcomip_fpreg(int fpreg)
1164{
1165 put8(0xDF);
1166 put8(0xF0 + fpreg);
1167}
1168
1169static inline void fucomip_fpreg(int fpreg)
1170{
1171 put8(0xDF);
1172 put8(0xE8 + fpreg);
1173}
1174
1175static inline void ffree_fpreg(int fpreg)
1176{
1177 put8(0xDD);
1178 put8(0xC0 + fpreg);
1179}
1180
1181#endif /* __ASSEMBLE_H__ */
1182