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 #include "osal/preproc.h"
29 
30 #include <stdlib.h>
31 #include <stdint.h>
32 
33 #include <retro_inline.h>
34 
35 
36 #if defined(__x86_64__) || (_M_X64)
37 extern int64_t reg[32];
38 typedef uint64_t native_type;
39 
40 #define RAX 0
41 #define RCX 1
42 #define RDX 2
43 #define RBX 3
44 #define RSP 4
45 #define RBP 5
46 #define RSI 6
47 #define RDI 7
48 #else
49 typedef uint32_t native_type;
50 extern int64_t reg[32];
51 #endif
52 
53 #define EAX 0
54 #define ECX 1
55 #define EDX 2
56 #define EBX 3
57 #define ESP 4
58 #define EBP 5
59 #define ESI 6
60 #define EDI 7
61 
62 #define AX 0
63 #define CX 1
64 #define DX 2
65 #define BX 3
66 #define SP 4
67 #define BP 5
68 #define SI 6
69 #define DI 7
70 
71 #define AL 0
72 #define CL 1
73 #define DL 2
74 #define BL 3
75 #define AH 4
76 #define CH 5
77 #define DH 6
78 #define BH 7
79 
80 extern int branch_taken;
81 
82 extern const uint16_t trunc_mode, round_mode, ceil_mode, floor_mode;
83 
84 void jump_start_rel8(void);
85 void jump_end_rel8(void);
86 void jump_start_rel32(void);
87 void jump_end_rel32(void);
88 void add_jump(unsigned int pc_addr, unsigned int mi_addr, unsigned int absolute64);
89 
put8(unsigned char octet)90 static INLINE void put8(unsigned char octet)
91 {
92    (*inst_pointer)[code_length] = octet;
93    code_length++;
94    if (code_length == max_code_length)
95    {
96       *inst_pointer = (unsigned char*)realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
97       max_code_length += 8192;
98    }
99 }
100 
put32(unsigned int dword)101 static INLINE void put32(unsigned int dword)
102 {
103    if ((code_length + 4) >= max_code_length)
104    {
105       *inst_pointer = (unsigned char*)realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
106       max_code_length += 8192;
107    }
108    *((unsigned int *) (*inst_pointer + code_length)) = dword;
109    code_length += 4;
110 }
111 
put64(uint64_t qword)112 static INLINE void put64(uint64_t qword)
113 {
114    if ((code_length + 8) >= max_code_length)
115    {
116       *inst_pointer = realloc_exec(*inst_pointer, max_code_length, max_code_length+8192);
117       max_code_length += 8192;
118    }
119    *((uint64_t*) (*inst_pointer + code_length)) = qword;
120    code_length += 8;
121 }
122 
123 #ifdef DEBUG
LLABS(int64_t i)124 static INLINE int64_t LLABS(int64_t i)
125 {
126    return (i < 0) ? -i : i;
127 }
128 #endif
129 
rel_r15_offset(void * dest,const char * op_name)130 static INLINE int rel_r15_offset(void *dest, const char *op_name)
131 {
132    /* calculate the destination pointer's offset from the base of the r4300 registers */
133    int64_t rel_offset = (int64_t) ((uint8_t *) dest - (uint8_t *) reg);
134 
135 #ifdef DEBUG
136    if (LLABS(rel_offset) > 0x7fffffff)
137    {
138       DebugMessage(M64MSG_ERROR, "Error: destination %p more than 2GB away from r15 base %p in %s()", dest, reg, op_name);
139 #if 0
140       OSAL_BREAKPOINT_INTERRUPT;
141 #endif
142    }
143 #endif
144 
145    return (int) rel_offset;
146 }
147 
148 #ifdef __x86_64__
fld_preg64_dword(int reg64)149 static INLINE void fld_preg64_dword(int reg64)
150 {
151    put8(0xD9);
152    put8(reg64);
153 }
154 
fdiv_preg64_dword(int reg64)155 static INLINE void fdiv_preg64_dword(int reg64)
156 {
157    put8(0xD8);
158    put8(0x30 + reg64);
159 }
160 
fstp_preg64_dword(int reg64)161 static INLINE void fstp_preg64_dword(int reg64)
162 {
163    put8(0xD9);
164    put8(0x18 + reg64);
165 }
166 
fstp_preg64_qword(int reg64)167 static INLINE void fstp_preg64_qword(int reg64)
168 {
169    put8(0xDD);
170    put8(0x18 + reg64);
171 }
172 
fadd_preg64_dword(int reg64)173 static INLINE void fadd_preg64_dword(int reg64)
174 {
175    put8(0xD8);
176    put8(reg64);
177 }
178 
fsub_preg64_dword(int reg64)179 static INLINE void fsub_preg64_dword(int reg64)
180 {
181    put8(0xD8);
182    put8(0x20 + reg64);
183 }
184 
fmul_preg64_dword(int reg64)185 static INLINE void fmul_preg64_dword(int reg64)
186 {
187    put8(0xD8);
188    put8(0x08 + reg64);
189 }
190 
fistp_preg64_dword(int reg64)191 static INLINE void fistp_preg64_dword(int reg64)
192 {
193    put8(0xDB);
194    put8(0x18 + reg64);
195 }
196 
fistp_preg64_qword(int reg64)197 static INLINE void fistp_preg64_qword(int reg64)
198 {
199    put8(0xDF);
200    put8(0x38 + reg64);
201 }
202 
fld_preg64_qword(int reg64)203 static INLINE void fld_preg64_qword(int reg64)
204 {
205    put8(0xDD);
206    put8(reg64);
207 }
208 
fild_preg64_qword(int reg64)209 static INLINE void fild_preg64_qword(int reg64)
210 {
211    put8(0xDF);
212    put8(0x28+reg64);
213 }
214 
fild_preg64_dword(int reg64)215 static INLINE void fild_preg64_dword(int reg64)
216 {
217    put8(0xDB);
218    put8(reg64);
219 }
220 
fadd_preg64_qword(int reg64)221 static INLINE void fadd_preg64_qword(int reg64)
222 {
223    put8(0xDC);
224    put8(reg64);
225 }
226 
fdiv_preg64_qword(int reg64)227 static INLINE void fdiv_preg64_qword(int reg64)
228 {
229    put8(0xDC);
230    put8(0x30 + reg64);
231 }
232 
fsub_preg64_qword(int reg64)233 static INLINE void fsub_preg64_qword(int reg64)
234 {
235    put8(0xDC);
236    put8(0x20 + reg64);
237 }
238 
fmul_preg64_qword(int reg64)239 static INLINE void fmul_preg64_qword(int reg64)
240 {
241    put8(0xDC);
242    put8(0x08 + reg64);
243 }
cmp_reg64_imm32(int reg64,unsigned int imm32)244 static INLINE void cmp_reg64_imm32(int reg64, unsigned int imm32)
245 {
246    put8(0x48);
247    put8(0x81);
248    put8(0xF8 + reg64);
249    put32(imm32);
250 }
251 
cmp_preg64preg64_imm8(int reg1,int reg2,unsigned char imm8)252 static INLINE void cmp_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8)
253 {
254    put8(0x80);
255    put8(0x3C);
256    put8((reg1 << 3) | reg2);
257    put8(imm8);
258 }
259 
sete_m8rel(unsigned char * m8)260 static INLINE void sete_m8rel(unsigned char *m8)
261 {
262    int offset = rel_r15_offset(m8, "sete_m8rel");
263 
264    put8(0x41);
265    put8(0x0F);
266    put8(0x94);
267    put8(0x87);
268    put32(offset);
269 }
270 
setne_m8rel(unsigned char * m8)271 static INLINE void setne_m8rel(unsigned char *m8)
272 {
273    int offset = rel_r15_offset(m8, "setne_m8rel");
274 
275    put8(0x41);
276    put8(0x0F);
277    put8(0x95);
278    put8(0x87);
279    put32(offset);
280 }
281 
setl_m8rel(unsigned char * m8)282 static INLINE void setl_m8rel(unsigned char *m8)
283 {
284    int offset = rel_r15_offset(m8, "setl_m8rel");
285 
286    put8(0x41);
287    put8(0x0F);
288    put8(0x9C);
289    put8(0x87);
290    put32(offset);
291 }
292 
setle_m8rel(unsigned char * m8)293 static INLINE void setle_m8rel(unsigned char *m8)
294 {
295    int offset = rel_r15_offset(m8, "setle_m8rel");
296 
297    put8(0x41);
298    put8(0x0F);
299    put8(0x9E);
300    put8(0x87);
301    put32(offset);
302 }
303 
setg_m8rel(unsigned char * m8)304 static INLINE void setg_m8rel(unsigned char *m8)
305 {
306    int offset = rel_r15_offset(m8, "setg_m8rel");
307 
308    put8(0x41);
309    put8(0x0F);
310    put8(0x9F);
311    put8(0x87);
312    put32(offset);
313 }
314 
cmp_reg64_reg64(int reg1,int reg2)315 static INLINE void cmp_reg64_reg64(int reg1, int reg2)
316 {
317    put8(0x48);
318    put8(0x39);
319    put8((reg2 << 3) | reg1 | 0xC0);
320 }
321 
cmp_reg64_imm8(int reg64,unsigned char imm8)322 static INLINE void cmp_reg64_imm8(int reg64, unsigned char imm8)
323 {
324    put8(0x48);
325    put8(0x83);
326    put8(0xF8 + reg64);
327    put8(imm8);
328 }
329 
mov_rax_memoffs64(uint64_t * memoffs64)330 static INLINE void mov_rax_memoffs64(uint64_t *memoffs64)
331 {
332    put8(0x48);
333    put8(0xA1);
334    put64((uint64_t) memoffs64);
335 }
336 
mov_memoffs64_rax(uint64_t * memoffs64)337 static INLINE void mov_memoffs64_rax(uint64_t *memoffs64)
338 {
339    put8(0x48);
340    put8(0xA3);
341    put64((uint64_t) memoffs64);
342 }
343 
mov_m8rel_xreg8(unsigned char * m8,int xreg8)344 static INLINE void mov_m8rel_xreg8(unsigned char *m8, int xreg8)
345 {
346    int offset = rel_r15_offset(m8, "mov_m8rel_xreg8");
347 
348    put8(0x41 | ((xreg8 & 8) >> 1));
349    put8(0x88);
350    put8(0x87 | ((xreg8 & 7) << 3));
351    put32(offset);
352 }
353 
mov_xreg16_m16rel(int xreg16,unsigned short * m16)354 static INLINE void mov_xreg16_m16rel(int xreg16, unsigned short *m16)
355 {
356    int offset = rel_r15_offset(m16, "mov_xreg16_m16rel");
357 
358    put8(0x66);
359    put8(0x41 | ((xreg16 & 8) >> 1));
360    put8(0x8B);
361    put8(0x87 | ((xreg16 & 7) << 3));
362    put32(offset);
363 }
364 
mov_m16rel_xreg16(unsigned short * m16,int xreg16)365 static INLINE void mov_m16rel_xreg16(unsigned short *m16, int xreg16)
366 {
367    int offset = rel_r15_offset(m16, "mov_m16rel_xreg16");
368 
369    put8(0x66);
370    put8(0x41 | ((xreg16 & 8) >> 1));
371    put8(0x89);
372    put8(0x87 | ((xreg16 & 7) << 3));
373    put32(offset);
374 }
375 
cmp_xreg32_m32rel(int xreg32,unsigned int * m32)376 static INLINE void cmp_xreg32_m32rel(int xreg32, unsigned int *m32)
377 {
378    int offset = rel_r15_offset(m32, "cmp_xreg32_m32rel");
379 
380    put8(0x41 | ((xreg32 & 8) >> 1));
381    put8(0x3B);
382    put8(0x87 | ((xreg32 & 7) << 3));
383    put32(offset);
384 }
385 
cmp_xreg64_m64rel(int xreg64,uint64_t * m64)386 static INLINE void cmp_xreg64_m64rel(int xreg64, uint64_t *m64)
387 {
388    int offset = rel_r15_offset(m64, "cmp_xreg64_m64rel");
389 
390    put8(0x49 | ((xreg64 & 8) >> 1));
391    put8(0x3B);
392    put8(0x87 | ((xreg64 & 7) << 3));
393    put32(offset);
394 }
395 #else
or_reg32_reg32(unsigned int reg1,unsigned int reg2)396 static INLINE void or_reg32_reg32(unsigned int reg1, unsigned int reg2)
397 {
398    put8(0x09);
399    put8(0xC0 | (reg2 << 3) | reg1);
400 }
401 
fldcw_m16(unsigned short * m16)402 static INLINE void fldcw_m16(unsigned short *m16)
403 {
404    put8(0xD9);
405    put8(0x2D);
406    put32((unsigned int)(m16));
407 }
408 
mov_reg8_m8(int reg8,unsigned char * m8)409 static INLINE void mov_reg8_m8(int reg8, unsigned char *m8)
410 {
411    put8(0x8A);
412    put8((reg8 << 3) | 5);
413    put32((unsigned int)(m8));
414 }
415 
mov_reg32_m32(unsigned int reg32,unsigned int * m32)416 static INLINE void mov_reg32_m32(unsigned int reg32, unsigned int* m32)
417 {
418    put8(0x8B);
419    put8((reg32 << 3) | 5);
420    put32((unsigned int)(m32));
421 }
422 
add_reg32_m32(unsigned int reg32,unsigned int * m32)423 static INLINE void add_reg32_m32(unsigned int reg32, unsigned int *m32)
424 {
425    put8(0x03);
426    put8((reg32 << 3) | 5);
427    put32((unsigned int)(m32));
428 }
429 
movsx_reg32_m16(int reg32,unsigned short * m16)430 static INLINE void movsx_reg32_m16(int reg32, unsigned short *m16)
431 {
432    put8(0x0F);
433    put8(0xBF);
434    put8((reg32 << 3) | 5);
435    put32((unsigned int)(m16));
436 }
437 
movsx_reg32_m8(int reg32,unsigned char * m8)438 static INLINE void movsx_reg32_m8(int reg32, unsigned char *m8)
439 {
440    put8(0x0F);
441    put8(0xBE);
442    put8((reg32 << 3) | 5);
443    put32((unsigned int)(m8));
444 }
445 
mul_m32(unsigned int * m32)446 static INLINE void mul_m32(unsigned int *m32)
447 {
448    put8(0xF7);
449    put8(0x25);
450    put32((unsigned int)(m32));
451 }
452 
mov_m32_imm32(unsigned int * m32,unsigned int imm32)453 static INLINE void mov_m32_imm32(unsigned int *m32, unsigned int imm32)
454 {
455    put8(0xC7);
456    put8(0x05);
457    put32((unsigned int)(m32));
458    put32(imm32);
459 }
460 
cmp_m32_imm32(unsigned int * m32,unsigned int imm32)461 static INLINE void cmp_m32_imm32(unsigned int *m32, unsigned int imm32)
462 {
463    put8(0x81);
464    put8(0x3D);
465    put32((unsigned int)(m32));
466    put32(imm32);
467 }
468 
inc_m32(unsigned int * m32)469 static INLINE void inc_m32(unsigned int *m32)
470 {
471    put8(0xFF);
472    put8(0x05);
473    put32((unsigned int)(m32));
474 }
475 
and_m32_imm32(unsigned int * m32,unsigned int imm32)476 static INLINE void and_m32_imm32(unsigned int *m32, unsigned int imm32)
477 {
478    put8(0x81);
479    put8(0x25);
480    put32((unsigned int)(m32));
481    put32(imm32);
482 }
483 
sub_m32_imm32(unsigned int * m32,unsigned int imm32)484 static INLINE void sub_m32_imm32(unsigned int *m32, unsigned int imm32)
485 {
486    put8(0x81);
487    put8(0x2D);
488    put32((unsigned int)(m32));
489    put32(imm32);
490 }
491 
or_m32_imm32(unsigned int * m32,unsigned int imm32)492 static INLINE void or_m32_imm32(unsigned int *m32, unsigned int imm32)
493 {
494    put8(0x81);
495    put8(0x0D);
496    put32((unsigned int)(m32));
497    put32(imm32);
498 }
499 
mov_m8_reg8(unsigned char * m8,int reg8)500 static INLINE void mov_m8_reg8(unsigned char *m8, int reg8)
501 {
502    put8(0x88);
503    put8((reg8 << 3) | 5);
504    put32((unsigned int)(m8));
505 }
506 
mov_reg16_m16(int reg16,unsigned short * m16)507 static INLINE void mov_reg16_m16(int reg16, unsigned short *m16)
508 {
509    put8(0x66);
510    put8(0x8B);
511    put8((reg16 << 3) | 5);
512    put32((unsigned int)(m16));
513 }
514 
mov_m16_reg16(unsigned short * m16,int reg16)515 static INLINE void mov_m16_reg16(unsigned short *m16, int reg16)
516 {
517    put8(0x66);
518    put8(0x89);
519    put8((reg16 << 3) | 5);
520    put32((unsigned int)(m16));
521 }
522 
cmp_reg32_m32(int reg32,unsigned int * m32)523 static INLINE void cmp_reg32_m32(int reg32, unsigned int *m32)
524 {
525    put8(0x3B);
526    put8((reg32 << 3) | 5);
527    put32((unsigned int)(m32));
528 }
529 
add_m32_reg32(unsigned int * m32,int reg32)530 static INLINE void add_m32_reg32(unsigned int *m32, int reg32)
531 {
532    put8(0x01);
533    put8((reg32 << 3) | 5);
534    put32((unsigned int)(m32));
535 }
536 
sub_reg32_m32(int reg32,unsigned int * m32)537 static INLINE void sub_reg32_m32(int reg32, unsigned int *m32)
538 {
539    put8(0x2B);
540    put8((reg32 << 3) | 5);
541    put32((unsigned int)(m32));
542 }
543 
mov_eax_memoffs32(unsigned int * memoffs32)544 static INLINE void mov_eax_memoffs32(unsigned int *memoffs32)
545 {
546    put8(0xA1);
547    put32((unsigned int)(memoffs32));
548 }
549 
cmp_preg32pimm32_imm8(int reg32,unsigned int imm32,unsigned char imm8)550 static INLINE void cmp_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8)
551 {
552    put8(0x80);
553    put8(0xB8 + reg32);
554    put32(imm32);
555    put8(imm8);
556 }
557 
test_reg32_imm32(int reg32,unsigned int imm32)558 static INLINE void test_reg32_imm32(int reg32, unsigned int imm32)
559 {
560    put8(0xF7);
561    put8(0xC0 + reg32);
562    put32(imm32);
563 }
564 
test_m32_imm32(unsigned int * m32,unsigned int imm32)565 static INLINE void test_m32_imm32(unsigned int *m32, unsigned int imm32)
566 {
567    put8(0xF7);
568    put8(0x05);
569    put32((unsigned int)m32);
570    put32(imm32);
571 }
572 
sbb_reg32_reg32(int reg1,int reg2)573 static INLINE void sbb_reg32_reg32(int reg1, int reg2)
574 {
575    put8(0x19);
576    put8((reg2 << 3) | reg1 | 0xC0);
577 }
578 
sub_reg32_imm32(int reg32,unsigned int imm32)579 static INLINE void sub_reg32_imm32(int reg32, unsigned int imm32)
580 {
581    put8(0x81);
582    put8(0xE8 + reg32);
583    put32(imm32);
584 }
585 
mov_m32_reg32(unsigned int * m32,unsigned int reg32)586 static INLINE void mov_m32_reg32(unsigned int *m32, unsigned int reg32)
587 {
588    put8(0x89);
589    put8((reg32 << 3) | 5);
590    put32((unsigned int)(m32));
591 }
592 
fdiv_preg32_dword(int reg32)593 static INLINE void fdiv_preg32_dword(int reg32)
594 {
595    put8(0xD8);
596    put8(0x30 + reg32);
597 }
598 
fstp_preg32_dword(int reg32)599 static INLINE void fstp_preg32_dword(int reg32)
600 {
601    put8(0xD9);
602    put8(0x18 + reg32);
603 }
604 
fstp_preg32_qword(int reg32)605 static INLINE void fstp_preg32_qword(int reg32)
606 {
607    put8(0xDD);
608    put8(0x18 + reg32);
609 }
610 
fadd_preg32_dword(int reg32)611 static INLINE void fadd_preg32_dword(int reg32)
612 {
613    put8(0xD8);
614    put8(reg32);
615 }
616 
fsub_preg32_dword(int reg32)617 static INLINE void fsub_preg32_dword(int reg32)
618 {
619    put8(0xD8);
620    put8(0x20 + reg32);
621 }
622 
fmul_preg32_dword(int reg32)623 static INLINE void fmul_preg32_dword(int reg32)
624 {
625    put8(0xD8);
626    put8(0x08 + reg32);
627 }
628 
fistp_preg32_dword(int reg32)629 static INLINE void fistp_preg32_dword(int reg32)
630 {
631    put8(0xDB);
632    put8(0x18 + reg32);
633 }
634 
fistp_preg32_qword(int reg32)635 static INLINE void fistp_preg32_qword(int reg32)
636 {
637    put8(0xDF);
638    put8(0x38 + reg32);
639 }
640 
fld_preg32_qword(int reg32)641 static INLINE void fld_preg32_qword(int reg32)
642 {
643    put8(0xDD);
644    put8(reg32);
645 }
646 
fild_preg32_qword(int reg32)647 static INLINE void fild_preg32_qword(int reg32)
648 {
649    put8(0xDF);
650    put8(0x28+reg32);
651 }
652 
fild_preg32_dword(int reg32)653 static INLINE void fild_preg32_dword(int reg32)
654 {
655    put8(0xDB);
656    put8(reg32);
657 }
658 
fadd_preg32_qword(int reg32)659 static INLINE void fadd_preg32_qword(int reg32)
660 {
661    put8(0xDC);
662    put8(reg32);
663 }
664 
fdiv_preg32_qword(int reg32)665 static INLINE void fdiv_preg32_qword(int reg32)
666 {
667    put8(0xDC);
668    put8(0x30 + reg32);
669 }
670 
fsub_preg32_qword(int reg32)671 static INLINE void fsub_preg32_qword(int reg32)
672 {
673    put8(0xDC);
674    put8(0x20 + reg32);
675 }
676 
fmul_preg32_qword(int reg32)677 static INLINE void fmul_preg32_qword(int reg32)
678 {
679    put8(0xDC);
680    put8(0x08 + reg32);
681 }
682 #endif
683 
684 
mov_memoffs32_eax(unsigned int * memoffs32)685 static INLINE void mov_memoffs32_eax(unsigned int *memoffs32)
686 {
687    put8(0xA3);
688 #ifdef __x86_64__
689    put64((uint64_t) memoffs32);
690 #else
691    put32((unsigned int)(memoffs32));
692 #endif
693 }
694 
695 
cmp_reg32_reg32(int reg1,int reg2)696 static INLINE void cmp_reg32_reg32(int reg1, int reg2)
697 {
698    put8(0x39);
699    put8((reg2 << 3) | reg1 | 0xC0);
700 }
701 
cmp_reg32_imm8(int reg32,unsigned char imm8)702 static INLINE void cmp_reg32_imm8(int reg32, unsigned char imm8)
703 {
704    put8(0x83);
705    put8(0xF8 + reg32);
706    put8(imm8);
707 }
708 
709 
cmp_reg32_imm32(int reg32,unsigned int imm32)710 static INLINE void cmp_reg32_imm32(int reg32, unsigned int imm32)
711 {
712    put8(0x81);
713    put8(0xF8 + reg32);
714    put32(imm32);
715 }
716 
717 
setge_m8rel(unsigned char * m8)718 static INLINE void setge_m8rel(unsigned char *m8)
719 {
720    int offset = rel_r15_offset(m8, "setge_m8rel");
721 
722    put8(0x41);
723    put8(0x0F);
724    put8(0x9D);
725    put8(0x87);
726    put32(offset);
727 }
728 
setl_reg8(unsigned int reg8)729 static INLINE void setl_reg8(unsigned int reg8)
730 {
731    put8(0x40);  /* we need an REX prefix to use the uniform byte registers */
732    put8(0x0F);
733    put8(0x9C);
734    put8(0xC0 | reg8);
735 }
736 
setb_reg8(unsigned int reg8)737 static INLINE void setb_reg8(unsigned int reg8)
738 {
739    put8(0x40);  /* we need an REX prefix to use the uniform byte registers */
740    put8(0x0F);
741    put8(0x92);
742    put8(0xC0 | reg8);
743 }
744 
test_m32rel_imm32(unsigned int * m32,unsigned int imm32)745 static INLINE void test_m32rel_imm32(unsigned int *m32, unsigned int imm32)
746 {
747    int offset = rel_r15_offset(m32, "test_m32rel_imm32");
748 
749    put8(0x41);
750    put8(0xF7);
751    put8(0x87);
752    put32(offset);
753    put32(imm32);
754 }
755 
add_m32rel_xreg32(unsigned int * m32,int xreg32)756 static INLINE void add_m32rel_xreg32(unsigned int *m32, int xreg32)
757 {
758    int offset = rel_r15_offset(m32, "add_m32rel_xreg32");
759 
760    put8(0x41 | ((xreg32 & 8) >> 1));
761    put8(0x01);
762    put8(0x87 | ((xreg32 & 7) << 3));
763    put32(offset);
764 }
765 
sub_xreg32_m32rel(int xreg32,unsigned int * m32)766 static INLINE void sub_xreg32_m32rel(int xreg32, unsigned int *m32)
767 {
768    int offset = rel_r15_offset(m32, "sub_xreg32_m32rel");
769 
770    put8(0x41 | ((xreg32 & 8) >> 1));
771    put8(0x2B);
772    put8(0x87 | ((xreg32 & 7) << 3));
773    put32(offset);
774 }
775 
sub_reg32_reg32(int reg1,int reg2)776 static INLINE void sub_reg32_reg32(int reg1, int reg2)
777 {
778    put8(0x29);
779    put8((reg2 << 3) | reg1 | 0xC0);
780 }
781 
sub_reg64_reg64(int reg1,int reg2)782 static INLINE void sub_reg64_reg64(int reg1, int reg2)
783 {
784    put8(0x48);
785    put8(0x29);
786    put8((reg2 << 3) | reg1 | 0xC0);
787 }
788 
sub_reg64_imm32(int reg64,unsigned int imm32)789 static INLINE void sub_reg64_imm32(int reg64, unsigned int imm32)
790 {
791    put8(0x48);
792    put8(0x81);
793    put8(0xE8 + reg64);
794    put32(imm32);
795 }
796 
sub_eax_imm32(unsigned int imm32)797 static INLINE void sub_eax_imm32(unsigned int imm32)
798 {
799    put8(0x2D);
800    put32(imm32);
801 }
802 
jne_rj(unsigned char saut)803 static INLINE void jne_rj(unsigned char saut)
804 {
805    put8(0x75);
806    put8(saut);
807 }
808 
je_rj(unsigned char saut)809 static INLINE void je_rj(unsigned char saut)
810 {
811    put8(0x74);
812    put8(saut);
813 }
814 
jb_rj(unsigned char saut)815 static INLINE void jb_rj(unsigned char saut)
816 {
817    put8(0x72);
818    put8(saut);
819 }
820 
jbe_rj(unsigned char saut)821 static INLINE void jbe_rj(unsigned char saut)
822 {
823    put8(0x76);
824    put8(saut);
825 }
826 
ja_rj(unsigned char saut)827 static INLINE void ja_rj(unsigned char saut)
828 {
829    put8(0x77);
830    put8(saut);
831 }
832 
jae_rj(unsigned char saut)833 static INLINE void jae_rj(unsigned char saut)
834 {
835    put8(0x73);
836    put8(saut);
837 }
838 
jp_rj(unsigned char saut)839 static INLINE void jp_rj(unsigned char saut)
840 {
841    put8(0x7A);
842    put8(saut);
843 }
844 
je_near_rj(unsigned int saut)845 static INLINE void je_near_rj(unsigned int saut)
846 {
847    put8(0x0F);
848    put8(0x84);
849    put32(saut);
850 }
851 
mov_reg32_imm32(int reg32,unsigned int imm32)852 static INLINE void mov_reg32_imm32(int reg32, unsigned int imm32)
853 {
854    put8(0xB8+reg32);
855    put32(imm32);
856 }
857 
mov_reg64_imm64(int reg64,uint64_t imm64)858 static INLINE void mov_reg64_imm64(int reg64, uint64_t imm64)
859 {
860    put8(0x48);
861    put8(0xB8+reg64);
862    put64(imm64);
863 }
864 
jmp_imm_short(char saut)865 static INLINE void jmp_imm_short(char saut)
866 {
867    put8(0xEB);
868    put8(saut);
869 }
870 
871 
or_m32rel_imm32(unsigned int * m32,unsigned int imm32)872 static INLINE void or_m32rel_imm32(unsigned int *m32, unsigned int imm32)
873 {
874    int offset = rel_r15_offset(m32, "or_m32rel_imm32");
875 
876    put8(0x41);
877    put8(0x81);
878    put8(0x8F);
879    put32(offset);
880    put32(imm32);
881 }
882 
or_reg64_reg64(unsigned int reg1,unsigned int reg2)883 static INLINE void or_reg64_reg64(unsigned int reg1, unsigned int reg2)
884 {
885    put8(0x48);
886    put8(0x09);
887    put8(0xC0 | (reg2 << 3) | reg1);
888 }
889 
and_reg64_reg64(unsigned int reg1,unsigned int reg2)890 static INLINE void and_reg64_reg64(unsigned int reg1, unsigned int reg2)
891 {
892    put8(0x48);
893    put8(0x21);
894    put8(0xC0 | (reg2 << 3) | reg1);
895 }
896 
and_m32rel_imm32(unsigned int * m32,unsigned int imm32)897 static INLINE void and_m32rel_imm32(unsigned int *m32, unsigned int imm32)
898 {
899    int offset = rel_r15_offset(m32, "and_m32rel_imm32");
900 
901    put8(0x41);
902    put8(0x81);
903    put8(0xA7);
904    put32(offset);
905    put32(imm32);
906 }
907 
xor_reg32_reg32(unsigned int reg1,unsigned int reg2)908 static INLINE void xor_reg32_reg32(unsigned int reg1, unsigned int reg2)
909 {
910    put8(0x31);
911    put8(0xC0 | (reg2 << 3) | reg1);
912 }
913 
914 
and_reg32_reg32(unsigned int reg1,unsigned int reg2)915 static INLINE void and_reg32_reg32(unsigned int reg1, unsigned int reg2)
916 {
917    put8(0x21);
918    put8(0xC0 | (reg2 << 3) | reg1);
919 }
920 
xor_reg64_reg64(unsigned int reg1,unsigned int reg2)921 static INLINE void xor_reg64_reg64(unsigned int reg1, unsigned int reg2)
922 {
923    put8(0x48);
924    put8(0x31);
925    put8(0xC0 | (reg2 << 3) | reg1);
926 }
927 
add_reg64_imm32(unsigned int reg64,unsigned int imm32)928 static INLINE void add_reg64_imm32(unsigned int reg64, unsigned int imm32)
929 {
930    put8(0x48);
931    put8(0x81);
932    put8(0xC0+reg64);
933    put32(imm32);
934 }
935 
add_reg32_imm32(unsigned int reg32,unsigned int imm32)936 static INLINE void add_reg32_imm32(unsigned int reg32, unsigned int imm32)
937 {
938    put8(0x81);
939    put8(0xC0+reg32);
940    put32(imm32);
941 }
942 
943 
inc_m32rel(unsigned int * m32)944 static INLINE void inc_m32rel(unsigned int *m32)
945 {
946    int offset = rel_r15_offset(m32, "inc_m32rel");
947 
948    put8(0x41);
949    put8(0xFF);
950    put8(0x87);
951    put32(offset);
952 }
953 
cmp_m32rel_imm32(unsigned int * m32,unsigned int imm32)954 static INLINE void cmp_m32rel_imm32(unsigned int *m32, unsigned int imm32)
955 {
956    int offset = rel_r15_offset(m32, "cmp_m32rel_imm32");
957 
958    put8(0x41);
959    put8(0x81);
960    put8(0xBF);
961    put32(offset);
962    put32(imm32);
963 }
964 
965 
cmp_eax_imm32(unsigned int imm32)966 static INLINE void cmp_eax_imm32(unsigned int imm32)
967 {
968    put8(0x3D);
969    put32(imm32);
970 }
971 
mov_m32rel_imm32(unsigned int * m32,unsigned int imm32)972 static INLINE void mov_m32rel_imm32(unsigned int *m32, unsigned int imm32)
973 {
974    int offset = rel_r15_offset(m32, "mov_m32rel_imm32");
975 
976    put8(0x41);
977    put8(0xC7);
978    put8(0x87);
979    put32(offset);
980    put32(imm32);
981 }
982 
shr_reg32_imm8(unsigned int reg32,unsigned char imm8)983 static INLINE void shr_reg32_imm8(unsigned int reg32, unsigned char imm8)
984 {
985    put8(0xC1);
986    put8(0xE8+reg32);
987    put8(imm8);
988 }
989 
call_reg32(unsigned int reg32)990 static INLINE void call_reg32(unsigned int reg32)
991 {
992    put8(0xFF);
993    put8(0xD0+reg32);
994 }
995 
jmp(unsigned int mi_addr)996 static INLINE void jmp(unsigned int mi_addr)
997 {
998 #ifdef __x86_64__
999    put8(0xFF);
1000    put8(0x25);
1001    put32(0);
1002    put64(0);
1003    add_jump(code_length-8, mi_addr, 1);
1004 #else
1005    put8(0xE9);
1006    put32(0);
1007    add_jump(code_length-4, mi_addr, 0);
1008 #endif
1009 }
1010 
cdq(void)1011 static INLINE void cdq(void)
1012 {
1013    put8(0x99);
1014 }
1015 
call_reg64(unsigned int reg64)1016 static INLINE void call_reg64(unsigned int reg64)
1017 {
1018    put8(0xFF);
1019    put8(0xD0+reg64);
1020 }
1021 
shr_reg64_imm8(unsigned int reg64,unsigned char imm8)1022 static INLINE void shr_reg64_imm8(unsigned int reg64, unsigned char imm8)
1023 {
1024    put8(0x48);
1025    put8(0xC1);
1026    put8(0xE8+reg64);
1027    put8(imm8);
1028 }
1029 
shr_reg32_cl(unsigned int reg32)1030 static INLINE void shr_reg32_cl(unsigned int reg32)
1031 {
1032    put8(0xD3);
1033    put8(0xE8+reg32);
1034 }
1035 
shr_reg64_cl(unsigned int reg64)1036 static INLINE void shr_reg64_cl(unsigned int reg64)
1037 {
1038    put8(0x48);
1039    put8(0xD3);
1040    put8(0xE8+reg64);
1041 }
1042 
sar_reg32_cl(unsigned int reg32)1043 static INLINE void sar_reg32_cl(unsigned int reg32)
1044 {
1045    put8(0xD3);
1046    put8(0xF8+reg32);
1047 }
1048 
sar_reg64_cl(unsigned int reg64)1049 static INLINE void sar_reg64_cl(unsigned int reg64)
1050 {
1051    put8(0x48);
1052    put8(0xD3);
1053    put8(0xF8+reg64);
1054 }
1055 
shl_reg32_cl(unsigned int reg32)1056 static INLINE void shl_reg32_cl(unsigned int reg32)
1057 {
1058    put8(0xD3);
1059    put8(0xE0+reg32);
1060 }
1061 
shld_reg32_reg32_cl(unsigned int reg1,unsigned int reg2)1062 static INLINE void shld_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
1063 {
1064    put8(0x0F);
1065    put8(0xA5);
1066    put8(0xC0 | (reg2 << 3) | reg1);
1067 }
1068 
shld_reg32_reg32_imm8(unsigned int reg1,unsigned int reg2,unsigned char imm8)1069 static INLINE void shld_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
1070 {
1071    put8(0x0F);
1072    put8(0xA4);
1073    put8(0xC0 | (reg2 << 3) | reg1);
1074    put8(imm8);
1075 }
1076 
shl_reg64_cl(unsigned int reg64)1077 static INLINE void shl_reg64_cl(unsigned int reg64)
1078 {
1079    put8(0x48);
1080    put8(0xD3);
1081    put8(0xE0+reg64);
1082 }
1083 
sar_reg32_imm8(unsigned int reg32,unsigned char imm8)1084 static INLINE void sar_reg32_imm8(unsigned int reg32, unsigned char imm8)
1085 {
1086    put8(0xC1);
1087    put8(0xF8+reg32);
1088    put8(imm8);
1089 }
1090 
shrd_reg32_reg32_imm8(unsigned int reg1,unsigned int reg2,unsigned char imm8)1091 static INLINE void shrd_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
1092 {
1093    put8(0x0F);
1094    put8(0xAC);
1095    put8(0xC0 | (reg2 << 3) | reg1);
1096    put8(imm8);
1097 }
1098 
sar_reg64_imm8(unsigned int reg64,unsigned char imm8)1099 static INLINE void sar_reg64_imm8(unsigned int reg64, unsigned char imm8)
1100 {
1101    put8(0x48);
1102    put8(0xC1);
1103    put8(0xF8+reg64);
1104    put8(imm8);
1105 }
1106 
1107 
mul_m32rel(unsigned int * m32)1108 static INLINE void mul_m32rel(unsigned int *m32)
1109 {
1110    int offset = rel_r15_offset(m32, "mul_m32rel");
1111 
1112    put8(0x41);
1113    put8(0xF7);
1114    put8(0xA7);
1115    put32(offset);
1116 }
1117 
imul_reg32(unsigned int reg32)1118 static INLINE void imul_reg32(unsigned int reg32)
1119 {
1120    put8(0xF7);
1121    put8(0xE8+reg32);
1122 }
1123 
mul_reg64(unsigned int reg64)1124 static INLINE void mul_reg64(unsigned int reg64)
1125 {
1126    put8(0x48);
1127    put8(0xF7);
1128    put8(0xE0+reg64);
1129 }
1130 
mul_reg32(unsigned int reg32)1131 static INLINE void mul_reg32(unsigned int reg32)
1132 {
1133    put8(0xF7);
1134    put8(0xE0+reg32);
1135 }
1136 
idiv_reg32(unsigned int reg32)1137 static INLINE void idiv_reg32(unsigned int reg32)
1138 {
1139    put8(0xF7);
1140    put8(0xF8+reg32);
1141 }
1142 
div_reg32(unsigned int reg32)1143 static INLINE void div_reg32(unsigned int reg32)
1144 {
1145    put8(0xF7);
1146    put8(0xF0+reg32);
1147 }
1148 
add_reg32_reg32(unsigned int reg1,unsigned int reg2)1149 static INLINE void add_reg32_reg32(unsigned int reg1, unsigned int reg2)
1150 {
1151    put8(0x01);
1152    put8(0xC0 | (reg2 << 3) | reg1);
1153 }
1154 
add_reg64_reg64(unsigned int reg1,unsigned int reg2)1155 static INLINE void add_reg64_reg64(unsigned int reg1, unsigned int reg2)
1156 {
1157    put8(0x48);
1158    put8(0x01);
1159    put8(0xC0 | (reg2 << 3) | reg1);
1160 }
1161 
jmp_reg32(unsigned int reg32)1162 static INLINE void jmp_reg32(unsigned int reg32)
1163 {
1164    put8(0xFF);
1165    put8(0xE0 + reg32);
1166 }
1167 
jmp_reg64(unsigned int reg64)1168 static INLINE void jmp_reg64(unsigned int reg64)
1169 {
1170    put8(0xFF);
1171    put8(0xE0 + reg64);
1172 }
1173 
mov_reg32_preg64(unsigned int reg1,unsigned int reg2)1174 static INLINE void mov_reg32_preg64(unsigned int reg1, unsigned int reg2)
1175 {
1176    put8(0x8B);
1177    put8((reg1 << 3) | reg2);
1178 }
1179 
mov_preg64_reg32(int reg1,int reg2)1180 static INLINE void mov_preg64_reg32(int reg1, int reg2)
1181 {
1182    put8(0x89);
1183    put8((reg2 << 3) | reg1);
1184 }
1185 
mov_reg64_preg64(int reg1,int reg2)1186 static INLINE void mov_reg64_preg64(int reg1, int reg2)
1187 {
1188    put8(0x48);
1189    put8(0x8B);
1190    put8((reg1 << 3) | reg2);
1191 }
1192 
mov_reg32_preg32preg32pimm32(int reg1,int reg2,int reg3,unsigned int imm32)1193 static INLINE void mov_reg32_preg32preg32pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
1194 {
1195    put8(0x8B);
1196    put8((reg1 << 3) | 0x84);
1197    put8(reg2 | (reg3 << 3));
1198    put32(imm32);
1199 }
1200 
mov_preg32pimm32_imm8(int reg32,unsigned int imm32,unsigned char imm8)1201 static INLINE void mov_preg32pimm32_imm8(int reg32, unsigned int imm32, unsigned char imm8)
1202 {
1203    put8(0xC6);
1204    put8(0x80 + reg32);
1205    put32(imm32);
1206    put8(imm8);
1207 }
1208 
mov_preg32_reg32(int reg1,int reg2)1209 static INLINE void mov_preg32_reg32(int reg1, int reg2)
1210 {
1211    put8(0x89);
1212    put8((reg2 << 3) | reg1);
1213 }
1214 
mov_preg32pimm32_reg16(int reg32,unsigned int imm32,int reg16)1215 static INLINE void mov_preg32pimm32_reg16(int reg32, unsigned int imm32, int reg16)
1216 {
1217    put8(0x66);
1218    put8(0x89);
1219    put8(0x80 | reg32 | (reg16 << 3));
1220    put32(imm32);
1221 }
1222 
mov_preg32pimm32_reg32(int reg1,unsigned int imm32,int reg2)1223 static INLINE void mov_preg32pimm32_reg32(int reg1, unsigned int imm32, int reg2)
1224 {
1225    put8(0x89);
1226    put8(0x80 | reg1 | (reg2 << 3));
1227    put32(imm32);
1228 }
1229 
mov_preg32pimm32_reg8(int reg32,unsigned int imm32,int reg8)1230 static INLINE void mov_preg32pimm32_reg8(int reg32, unsigned int imm32, int reg8)
1231 {
1232    put8(0x88);
1233    put8(0x80 | reg32 | (reg8 << 3));
1234    put32(imm32);
1235 }
1236 
mov_reg32_preg32pimm32(int reg1,int reg2,unsigned int imm32)1237 static INLINE void mov_reg32_preg32pimm32(int reg1, int reg2, unsigned int imm32)
1238 {
1239    put8(0x8B);
1240    put8(0x80 | (reg1 << 3) | reg2);
1241    put32(imm32);
1242 }
1243 
mov_reg32_preg32x4pimm32(int reg1,int reg2,unsigned int imm32)1244 static INLINE void mov_reg32_preg32x4pimm32(int reg1, int reg2, unsigned int imm32)
1245 {
1246    put8(0x8B);
1247    put8((reg1 << 3) | 4);
1248    put8(0x80 | (reg2 << 3) | 5);
1249    put32(imm32);
1250 }
1251 
mov_reg32_preg32(unsigned int reg1,unsigned int reg2)1252 static INLINE void mov_reg32_preg32(unsigned int reg1, unsigned int reg2)
1253 {
1254    put8(0x8B);
1255    put8((reg1 << 3) | reg2);
1256 }
1257 
mov_reg32_preg64preg64pimm32(int reg1,int reg2,int reg3,unsigned int imm32)1258 static INLINE void mov_reg32_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
1259 {
1260    put8(0x8B);
1261    put8((reg1 << 3) | 0x84);
1262    put8(reg2 | (reg3 << 3));
1263    put32(imm32);
1264 }
1265 
mov_preg64preg64pimm32_reg32(int reg1,int reg2,unsigned int imm32,int reg3)1266 static INLINE void mov_preg64preg64pimm32_reg32(int reg1, int reg2, unsigned int imm32, int reg3)
1267 {
1268    put8(0x89);
1269    put8((reg3 << 3) | 0x84);
1270    put8(reg1 | (reg2 << 3));
1271    put32(imm32);
1272 }
1273 
mov_reg64_preg64preg64pimm32(int reg1,int reg2,int reg3,unsigned int imm32)1274 static INLINE void mov_reg64_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
1275 {
1276    put8(0x48);
1277    put8(0x8B);
1278    put8((reg1 << 3) | 0x84);
1279    put8(reg2 | (reg3 << 3));
1280    put32(imm32);
1281 }
1282 
mov_reg32_preg64preg64(int reg1,int reg2,int reg3)1283 static INLINE void mov_reg32_preg64preg64(int reg1, int reg2, int reg3)
1284 {
1285    put8(0x8B);
1286    put8((reg1 << 3) | 0x04);
1287    put8((reg2 << 3) | reg3);
1288 }
1289 
mov_reg64_preg64preg64(int reg1,int reg2,int reg3)1290 static INLINE void mov_reg64_preg64preg64(int reg1, int reg2, int reg3)
1291 {
1292    put8(0x48);
1293    put8(0x8B);
1294    put8((reg1 << 3) | 0x04);
1295    put8(reg2 | (reg3 << 3));
1296 }
1297 
mov_reg32_preg64pimm32(int reg1,int reg2,unsigned int imm32)1298 static INLINE void mov_reg32_preg64pimm32(int reg1, int reg2, unsigned int imm32)
1299 {
1300    put8(0x8B);
1301    put8(0x80 | (reg1 << 3) | reg2);
1302    put32(imm32);
1303 }
1304 
mov_reg64_preg64pimm32(int reg1,int reg2,unsigned int imm32)1305 static INLINE void mov_reg64_preg64pimm32(int reg1, int reg2, unsigned int imm32)
1306 {
1307    put8(0x48);
1308    put8(0x8B);
1309    put8(0x80 | (reg1 << 3) | reg2);
1310    put32(imm32);
1311 }
1312 
mov_reg64_preg64pimm8(int reg1,int reg2,unsigned int imm8)1313 static INLINE void mov_reg64_preg64pimm8(int reg1, int reg2, unsigned int imm8)
1314 {
1315    put8(0x48);
1316    put8(0x8B);
1317    put8(0x40 | (reg1 << 3) | reg2);
1318    put8(imm8);
1319 }
1320 
mov_reg64_preg64x8preg64(int reg1,int reg2,int reg3)1321 static INLINE void mov_reg64_preg64x8preg64(int reg1, int reg2, int reg3)
1322 {
1323    put8(0x48);
1324    put8(0x8B);
1325    put8((reg1 << 3) | 4);
1326    put8(0xC0 | (reg2 << 3) | reg3);
1327 }
1328 
mov_preg64preg64_reg8(int reg1,int reg2,int reg8)1329 static INLINE void mov_preg64preg64_reg8(int reg1, int reg2, int reg8)
1330 {
1331    put8(0x88);
1332    put8(0x04 | (reg8 << 3));
1333    put8((reg1 << 3) | reg2);
1334 }
1335 
mov_preg64preg64_imm8(int reg1,int reg2,unsigned char imm8)1336 static INLINE void mov_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8)
1337 {
1338    put8(0xC6);
1339    put8(0x04);
1340    put8((reg1 << 3) | reg2);
1341    put8(imm8);
1342 }
1343 
mov_preg64preg64_reg16(int reg1,int reg2,int reg16)1344 static INLINE void mov_preg64preg64_reg16(int reg1, int reg2, int reg16)
1345 {
1346    put8(0x66);
1347    put8(0x89);
1348    put8(0x04 | (reg16 << 3));
1349    put8((reg1 << 3) | reg2);
1350 }
1351 
mov_preg64preg64_reg32(int reg1,int reg2,int reg32)1352 static INLINE void mov_preg64preg64_reg32(int reg1, int reg2, int reg32)
1353 {
1354    put8(0x89);
1355    put8(0x04 | (reg32 << 3));
1356    put8((reg1 << 3) | reg2);
1357 }
1358 
mov_preg64pimm32_reg32(int reg1,unsigned int imm32,int reg2)1359 static INLINE void mov_preg64pimm32_reg32(int reg1, unsigned int imm32, int reg2)
1360 {
1361    put8(0x89);
1362    put8(0x80 | reg1 | (reg2 << 3));
1363    put32(imm32);
1364 }
1365 
mov_preg64pimm8_reg64(int reg1,unsigned int imm8,int reg2)1366 static INLINE void mov_preg64pimm8_reg64(int reg1, unsigned int imm8, int reg2)
1367 {
1368    put8(0x48);
1369    put8(0x89);
1370    put8(0x40 | (reg2 << 3) | reg1);
1371    put8(imm8);
1372 }
1373 
add_eax_imm32(unsigned int imm32)1374 static INLINE void add_eax_imm32(unsigned int imm32)
1375 {
1376    put8(0x05);
1377    put32(imm32);
1378 }
1379 
shl_reg32_imm8(unsigned int reg32,unsigned char imm8)1380 static INLINE void shl_reg32_imm8(unsigned int reg32, unsigned char imm8)
1381 {
1382    put8(0xC1);
1383    put8(0xE0 + reg32);
1384    put8(imm8);
1385 }
1386 
shl_reg64_imm8(unsigned int reg64,unsigned char imm8)1387 static INLINE void shl_reg64_imm8(unsigned int reg64, unsigned char imm8)
1388 {
1389    put8(0x48);
1390    put8(0xC1);
1391    put8(0xE0 + reg64);
1392    put8(imm8);
1393 }
1394 
1395 
movsx_reg32_8preg32pimm32(int reg1,int reg2,unsigned int imm32)1396 static INLINE void movsx_reg32_8preg32pimm32(int reg1, int reg2, unsigned int imm32)
1397 {
1398    put8(0x0F);
1399    put8(0xBE);
1400    put8((reg1 << 3) | reg2 | 0x80);
1401    put32(imm32);
1402 }
1403 
movsx_reg32_16preg32pimm32(int reg1,int reg2,unsigned int imm32)1404 static INLINE void movsx_reg32_16preg32pimm32(int reg1, int reg2, unsigned int imm32)
1405 {
1406    put8(0x0F);
1407    put8(0xBF);
1408    put8((reg1 << 3) | reg2 | 0x80);
1409    put32(imm32);
1410 }
1411 
1412 
not_reg32(unsigned int reg32)1413 static INLINE void not_reg32(unsigned int reg32)
1414 {
1415    put8(0xF7);
1416    put8(0xD0 + reg32);
1417 }
1418 
mov_reg32_reg32(unsigned int reg1,unsigned int reg2)1419 static INLINE void mov_reg32_reg32(unsigned int reg1, unsigned int reg2)
1420 {
1421    if (reg1 == reg2) return;
1422    put8(0x89);
1423    put8(0xC0 | (reg2 << 3) | reg1);
1424 }
1425 
mov_reg64_reg64(unsigned int reg1,unsigned int reg2)1426 static INLINE void mov_reg64_reg64(unsigned int reg1, unsigned int reg2)
1427 {
1428    if (reg1 == reg2) return;
1429    put8(0x48);
1430    put8(0x89);
1431    put8(0xC0 | (reg2 << 3) | reg1);
1432 }
1433 
mov_xreg32_m32rel(unsigned int xreg32,unsigned int * m32)1434 static INLINE void mov_xreg32_m32rel(unsigned int xreg32, unsigned int *m32)
1435 {
1436    int offset = rel_r15_offset(m32, "mov_xreg32_m32rel");
1437 
1438    put8(0x41 | ((xreg32 & 8) >> 1));
1439    put8(0x8B);
1440    put8(0x87 | ((xreg32 & 7) << 3));
1441    put32(offset);
1442 }
1443 
mov_m32rel_xreg32(unsigned int * m32,unsigned int xreg32)1444 static INLINE void mov_m32rel_xreg32(unsigned int *m32, unsigned int xreg32)
1445 {
1446    int offset = rel_r15_offset(m32, "mov_m32rel_xreg32");
1447 
1448    put8(0x41 | ((xreg32 & 8) >> 1));
1449    put8(0x89);
1450    put8(0x87 | ((xreg32 & 7) << 3));
1451    put32(offset);
1452 }
1453 
mov_xreg64_m64rel(unsigned int xreg64,uint64_t * m64)1454 static INLINE void mov_xreg64_m64rel(unsigned int xreg64, uint64_t* m64)
1455 {
1456    int offset = rel_r15_offset(m64, "mov_xreg64_m64rel");
1457 
1458    put8(0x49 | ((xreg64 & 8) >> 1));
1459    put8(0x8B);
1460    put8(0x87 | ((xreg64 & 7) << 3));
1461    put32(offset);
1462 }
1463 
mov_m64rel_xreg64(uint64_t * m64,unsigned int xreg64)1464 static INLINE void mov_m64rel_xreg64(uint64_t *m64, unsigned int xreg64)
1465 {
1466    int offset = rel_r15_offset(m64, "mov_m64rel_xreg64");
1467 
1468    put8(0x49 | ((xreg64 & 8) >> 1));
1469    put8(0x89);
1470    put8(0x87 | ((xreg64 & 7) << 3));
1471    put32(offset);
1472 }
1473 
mov_xreg8_m8rel(int xreg8,unsigned char * m8)1474 static INLINE void mov_xreg8_m8rel(int xreg8, unsigned char *m8)
1475 {
1476    int offset = rel_r15_offset(m8, "mov_xreg8_m8rel");
1477 
1478    put8(0x41 | ((xreg8 & 8) >> 1));
1479    put8(0x8A);
1480    put8(0x87 | ((xreg8 & 7) << 3));
1481    put32(offset);
1482 }
1483 
1484 
adc_reg32_reg32(unsigned int reg1,unsigned int reg2)1485 static INLINE void adc_reg32_reg32(unsigned int reg1, unsigned int reg2)
1486 {
1487    put8(0x11);
1488    put8(0xC0 | (reg2 << 3) | reg1);
1489 }
1490 
adc_reg32_imm32(unsigned int reg32,unsigned int imm32)1491 static INLINE void adc_reg32_imm32(unsigned int reg32, unsigned int imm32)
1492 {
1493    put8(0x81);
1494    put8(0xD0 + reg32);
1495    put32(imm32);
1496 }
1497 
1498 
and_eax_imm32(unsigned int imm32)1499 static INLINE void and_eax_imm32(unsigned int imm32)
1500 {
1501    put8(0x25);
1502    put32(imm32);
1503 }
1504 
or_reg64_imm32(int reg64,unsigned int imm32)1505 static INLINE void or_reg64_imm32(int reg64, unsigned int imm32)
1506 {
1507    put8(0x48);
1508    put8(0x81);
1509    put8(0xC8 + reg64);
1510    put32(imm32);
1511 }
1512 
1513 
and_reg32_imm32(int reg32,unsigned int imm32)1514 static INLINE void and_reg32_imm32(int reg32, unsigned int imm32)
1515 {
1516    put8(0x81);
1517    put8(0xE0 + reg32);
1518    put32(imm32);
1519 }
1520 
and_reg64_imm32(int reg64,unsigned int imm32)1521 static INLINE void and_reg64_imm32(int reg64, unsigned int imm32)
1522 {
1523    put8(0x48);
1524    put8(0x81);
1525    put8(0xE0 + reg64);
1526    put32(imm32);
1527 }
1528 
and_reg64_imm8(int reg64,unsigned char imm8)1529 static INLINE void and_reg64_imm8(int reg64, unsigned char imm8)
1530 {
1531    put8(0x48);
1532    put8(0x83);
1533    put8(0xE0 + reg64);
1534    put8(imm8);
1535 }
1536 
or_reg32_imm32(int reg32,unsigned int imm32)1537 static INLINE void or_reg32_imm32(int reg32, unsigned int imm32)
1538 {
1539    put8(0x81);
1540    put8(0xC8 + reg32);
1541    put32(imm32);
1542 }
1543 
xor_reg32_imm32(int reg32,unsigned int imm32)1544 static INLINE void xor_reg32_imm32(int reg32, unsigned int imm32)
1545 {
1546    put8(0x81);
1547    put8(0xF0 + reg32);
1548    put32(imm32);
1549 }
1550 
xor_reg8_imm8(int reg8,unsigned char imm8)1551 static INLINE void xor_reg8_imm8(int reg8, unsigned char imm8)
1552 {
1553 #ifdef __x86_64__
1554    put8(0x40);  /* we need an REX prefix to use the uniform byte registers */
1555 #endif
1556    put8(0x80);
1557    put8(0xF0 + reg8);
1558    put8(imm8);
1559 }
1560 
xor_reg64_imm32(int reg64,unsigned int imm32)1561 static INLINE void xor_reg64_imm32(int reg64, unsigned int imm32)
1562 {
1563    put8(0x48);
1564    put8(0x81);
1565    put8(0xF0 + reg64);
1566    put32(imm32);
1567 }
1568 
not_reg64(unsigned int reg64)1569 static INLINE void not_reg64(unsigned int reg64)
1570 {
1571    put8(0x48);
1572    put8(0xF7);
1573    put8(0xD0 + reg64);
1574 }
1575 
neg_reg32(unsigned int reg32)1576 static INLINE void neg_reg32(unsigned int reg32)
1577 {
1578    put8(0xF7);
1579    put8(0xD8 + reg32);
1580 }
1581 
neg_reg64(unsigned int reg64)1582 static INLINE void neg_reg64(unsigned int reg64)
1583 {
1584    put8(0x48);
1585    put8(0xF7);
1586    put8(0xD8 + reg64);
1587 }
1588 
movsx_xreg32_m8rel(int xreg32,unsigned char * m8)1589 static INLINE void movsx_xreg32_m8rel(int xreg32, unsigned char *m8)
1590 {
1591    int offset = rel_r15_offset(m8, "movsx_xreg32_m8rel");
1592 
1593    put8(0x41 | ((xreg32 & 8) >> 1));
1594    put8(0x0F);
1595    put8(0xBE);
1596    put8(0x87 | ((xreg32 & 7) << 3));
1597    put32(offset);
1598 }
1599 
movsx_reg32_8preg64preg64(int reg1,int reg2,int reg3)1600 static INLINE void movsx_reg32_8preg64preg64(int reg1, int reg2, int reg3)
1601 {
1602    put8(0x0F);
1603    put8(0xBE);
1604    put8((reg1 << 3) | 0x04);
1605    put8((reg2 << 3) | reg3);
1606 }
1607 
movsx_reg32_16preg64preg64(int reg1,int reg2,int reg3)1608 static INLINE void movsx_reg32_16preg64preg64(int reg1, int reg2, int reg3)
1609 {
1610    put8(0x0F);
1611    put8(0xBF);
1612    put8((reg1 << 3) | 0x04);
1613    put8((reg2 << 3) | reg3);
1614 }
1615 
movsx_xreg32_m16rel(int xreg32,unsigned short * m16)1616 static INLINE void movsx_xreg32_m16rel(int xreg32, unsigned short *m16)
1617 {
1618    int offset = rel_r15_offset(m16, "movsx_xreg32_m16rel");
1619 
1620    put8(0x41 | ((xreg32 & 8) >> 1));
1621    put8(0x0F);
1622    put8(0xBF);
1623    put8(0x87 | ((xreg32 & 7) << 3));
1624    put32(offset);
1625 }
1626 
movsxd_reg64_reg32(int reg64,int reg32)1627 static INLINE void movsxd_reg64_reg32(int reg64, int reg32)
1628 {
1629    put8(0x48);
1630    put8(0x63);
1631    put8((reg64 << 3) | reg32 | 0xC0);
1632 }
1633 
1634 
fldcw_m16rel(unsigned short * m16)1635 static INLINE void fldcw_m16rel(unsigned short *m16)
1636 {
1637    int offset = rel_r15_offset(m16, "fldcw_m16rel");
1638 
1639    put8(0x41);
1640    put8(0xD9);
1641    put8(0xAF);
1642    put32(offset);
1643 }
1644 
1645 
fchs(void)1646 static INLINE void fchs(void)
1647 {
1648    put8(0xD9);
1649    put8(0xE0);
1650 }
1651 
1652 
fsqrt(void)1653 static INLINE void fsqrt(void)
1654 {
1655    put8(0xD9);
1656    put8(0xFA);
1657 }
1658 
fabs_(void)1659 static INLINE void fabs_(void)
1660 {
1661    put8(0xD9);
1662    put8(0xE1);
1663 }
1664 
fcomip_fpreg(int fpreg)1665 static INLINE void fcomip_fpreg(int fpreg)
1666 {
1667    put8(0xDF);
1668    put8(0xF0 + fpreg);
1669 }
1670 
fucomip_fpreg(int fpreg)1671 static INLINE void fucomip_fpreg(int fpreg)
1672 {
1673    put8(0xDF);
1674    put8(0xE8 + fpreg);
1675 }
1676 
ffree_fpreg(int fpreg)1677 static INLINE void ffree_fpreg(int fpreg)
1678 {
1679    put8(0xDD);
1680    put8(0xC0 + fpreg);
1681 }
1682 
jle_rj(unsigned char saut)1683 static INLINE void jle_rj(unsigned char saut)
1684 {
1685    put8(0x7E);
1686    put8(saut);
1687 }
1688 
jge_rj(unsigned char saut)1689 static INLINE void jge_rj(unsigned char saut)
1690 {
1691    put8(0x7D);
1692    put8(saut);
1693 }
1694 
jg_rj(unsigned char saut)1695 static INLINE void jg_rj(unsigned char saut)
1696 {
1697    put8(0x7F);
1698    put8(saut);
1699 }
1700 
jl_rj(unsigned char saut)1701 static INLINE void jl_rj(unsigned char saut)
1702 {
1703    put8(0x7C);
1704    put8(saut);
1705 }
1706 
fld_preg32_dword(int reg32)1707 static INLINE void fld_preg32_dword(int reg32)
1708 {
1709    put8(0xD9);
1710    put8(reg32);
1711 }
1712 
shrd_reg32_reg32_cl(unsigned int reg1,unsigned int reg2)1713 static INLINE void shrd_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
1714 {
1715    put8(0x0F);
1716    put8(0xAD);
1717    put8(0xC0 | (reg2 << 3) | reg1);
1718 }
1719 
1720 
1721 #endif /* __ASSEMBLE_H__ */
1722 
1723