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