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 *
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. *
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. *
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
28
#include "../recomph.h"
31
/* Placeholder for RIP-relative offsets is maxmimum 32-bit signed value.
32
* So, if recompiled code is run without running passe2() first, it will
35
#define REL_PLACEHOLDER 0x7fffffff
37
typedef struct _jump_table
41
unsigned int absolute64;
44
static jump_table *jumps_table = NULL;
45
static int jumps_number = 0, max_jumps_number = 0;
47
typedef struct _riprelative_table
49
unsigned int pc_addr; /* index in bytes from start of x86_64 code block to the displacement value to write */
50
unsigned int extra_bytes; /* number of remaining instruction bytes (immediate data) after 4-byte displacement */
51
unsigned char *global_dst; /* 64-bit pointer to the data object */
54
static riprelative_table *riprel_table = NULL;
55
static int riprel_number = 0, max_riprel_number = 0;
57
/* Static Functions */
59
static void add_jump(unsigned int pc_addr, unsigned int mi_addr, unsigned int absolute64)
61
if (jumps_number == max_jumps_number)
63
max_jumps_number += 512;
64
jumps_table = realloc(jumps_table, max_jumps_number*sizeof(jump_table));
66
jumps_table[jumps_number].pc_addr = pc_addr;
67
jumps_table[jumps_number].mi_addr = mi_addr;
68
jumps_table[jumps_number].absolute64 = absolute64;
72
static void add_riprelative(unsigned int pc_addr, unsigned int extra_bytes, void *global_64_ptr)
74
if (riprel_number == max_riprel_number)
76
max_riprel_number += 512;
77
riprel_table = realloc(riprel_table, max_riprel_number * sizeof(riprelative_table));
79
riprel_table[riprel_number].pc_addr = pc_addr;
80
riprel_table[riprel_number].extra_bytes = extra_bytes;
81
riprel_table[riprel_number].global_dst = (unsigned char *) global_64_ptr;
85
/* Global Functions */
87
void init_assembler(void *block_jumps_table, int block_jumps_number, void *block_riprel_table, int block_riprel_number)
89
if (block_jumps_table)
91
jumps_table = block_jumps_table;
92
jumps_number = block_jumps_number;
93
if (jumps_number <= 512)
94
max_jumps_number = 512;
96
max_jumps_number = (jumps_number + 511) & 0xfffffe00;
100
jumps_table = malloc(512*sizeof(jump_table));
102
max_jumps_number = 512;
105
if (block_riprel_table)
107
riprel_table = block_riprel_table;
108
riprel_number = block_riprel_number;
109
if (riprel_number <= 512)
110
max_riprel_number = 512;
112
max_riprel_number = (riprel_number + 511) & 0xfffffe00;
116
riprel_table = malloc(512 * sizeof(riprelative_table));
118
max_riprel_number = 512;
122
void free_assembler(void **block_jumps_table, int *block_jumps_number, void **block_riprel_table, int *block_riprel_number)
124
*block_jumps_table = jumps_table;
125
*block_jumps_number = jumps_number;
126
*block_riprel_table = riprel_table;
127
*block_riprel_number = riprel_number;
130
void passe2(precomp_instr *dest, int start, int end, precomp_block *block)
134
build_wrappers(dest, start, end, block);
136
/* First, fix up all the jumps. This involves a table lookup to find the offset into the block of x86_64 code for
137
* for start of a recompiled r4300i instruction corresponding to the given jump destination address in the N64
138
* address space. Next, the relative offset between this destination and the location of the jump instruction is
139
* computed and stored in memory, so that the jump will branch to the right place in the recompiled code.
141
for (i = 0; i < jumps_number; i++)
143
precomp_instr *jump_instr = dest + ((jumps_table[i].mi_addr - dest[0].addr) / 4);
144
unsigned int jmp_offset_loc = jumps_table[i].pc_addr;
145
unsigned char *addr_dest = NULL;
146
/* calculate the destination address to jump to */
147
if (jump_instr->reg_cache_infos.need_map)
149
addr_dest = jump_instr->reg_cache_infos.jump_wrapper;
153
addr_dest = block->code + jump_instr->local_addr;
155
/* write either a 32-bit IP-relative offset or a 64-bit absolute address */
156
if (jumps_table[i].absolute64)
158
*((unsigned long long *) (block->code + jmp_offset_loc)) = (unsigned long long) addr_dest;
162
long jump_rel_offset = (long) (addr_dest - (block->code + jmp_offset_loc + 4));
163
*((int *) (block->code + jmp_offset_loc)) = (int) jump_rel_offset;
164
if (jump_rel_offset >= 0x7fffffffLL || jump_rel_offset < -0x80000000LL)
166
printf("assembler pass2 error: offset too big for relative jump from %lx to %lx\n",
167
(long) (block->code + jmp_offset_loc + 4), (long) addr_dest);
173
/* Next, fix up all of the RIP-relative memory accesses. This is unique to the x86_64 architecture, because
174
* the 32-bit absolute displacement addressing mode is not available (and there's no 64-bit absolute displacement
177
for (i = 0; i < riprel_number; i++)
179
unsigned char *rel_offset_ptr = block->code + riprel_table[i].pc_addr;
180
long rip_rel_offset = (long) (riprel_table[i].global_dst - (rel_offset_ptr + 4 + riprel_table[i].extra_bytes));
181
if (rip_rel_offset >= 0x7fffffffLL || rip_rel_offset < -0x80000000LL)
183
printf("assembler pass2 error: offset too big between mem target: %lx and code position: %lx\n",
184
(long) riprel_table[i].global_dst, (long) rel_offset_ptr);
187
*((int *) rel_offset_ptr) = (int) rip_rel_offset;
192
static void put8(unsigned char octet)
194
(*inst_pointer)[code_length] = octet;
196
if (code_length == max_code_length)
198
max_code_length += 8192;
199
*inst_pointer = realloc(*inst_pointer, max_code_length);
203
static void put16(unsigned short word)
205
if ((code_length + 2) >= max_code_length)
207
max_code_length += 8192;
208
*inst_pointer = realloc(*inst_pointer, max_code_length);
210
*((unsigned short *) (*inst_pointer + code_length)) = word;
214
static void put32(unsigned int dword)
216
if ((code_length + 4) >= max_code_length)
218
max_code_length += 8192;
219
*inst_pointer = realloc(*inst_pointer, max_code_length);
221
*((unsigned int *) (*inst_pointer + code_length)) = dword;
225
static void put64(unsigned long long qword)
227
if ((code_length + 8) >= max_code_length)
229
max_code_length += 8192;
230
*inst_pointer = realloc(*inst_pointer, max_code_length);
232
*((unsigned long long *) (*inst_pointer + code_length)) = qword;
236
void code_align16(void)
240
if (((long) (*inst_pointer) & 15) != 0)
242
printf("Error: code block pointer is not 16-byte aligned!\n");
246
bytes = code_length & 15;
247
if (bytes != 0) bytes = 16 - bytes;
248
while (bytes > 0) /* this nop-generator was coded from information given in AMD64 optimization manual */
250
if (bytes == 4 || bytes > 9)
251
{ bytes -= 4; put32(0x90666666); }
253
{ bytes -= 1; put8(0x90); }
255
{ bytes -= 2; put16(0x9066); }
257
{ bytes -= 4; put16(0x6666); put8(0x90); }
259
{ bytes -= 5; put32(0x66906666); put8(0x90); }
261
{ bytes -= 6; put32(0x66906666); put16(0x9066); }
263
{ bytes -= 7; put32(0x90666666); put16(0x6666); put8(0x90); }
265
{ bytes -= 8; put32(0x90666666); put32(0x90666666); }
267
{ bytes -= 9; put32(0x66906666); put32(0x66669066); put8(0x90); }
272
static unsigned int g_jump_start8 = 0;
273
static unsigned int g_jump_start32 = 0;
275
void jump_start_rel8(void)
277
g_jump_start8 = code_length;
280
void jump_start_rel32(void)
282
g_jump_start32 = code_length;
285
void jump_end_rel8(void)
287
unsigned int jump_end = code_length;
288
int jump_vec = jump_end - g_jump_start8;
290
if (jump_vec > 127 || jump_vec < -128)
292
printf("Error: 8-bit relative jump too long! From %x to %x\n", g_jump_start8, jump_end);
296
code_length = g_jump_start8 - 1;
298
code_length = jump_end;
301
void jump_end_rel32(void)
303
unsigned int jump_end = code_length;
304
int jump_vec = jump_end - g_jump_start32;
306
code_length = g_jump_start32 - 4;
308
code_length = jump_end;
311
void int_imm8(unsigned char imm8)
317
void mov_eax_memoffs32(unsigned int *memoffs32)
320
put64((unsigned long long) memoffs32);
323
void mov_memoffs32_eax(unsigned int *memoffs32)
326
put64((unsigned long long) memoffs32);
329
void mov_rax_memoffs64(unsigned long long *memoffs64)
333
put64((unsigned long long) memoffs64);
336
void mov_memoffs64_rax(unsigned long long *memoffs64)
340
put64((unsigned long long) memoffs64);
343
void mov_m8abs_reg8(unsigned char *m8, int reg8)
345
if ((long) m8 & 0xFFFFFFFF80000000LL)
347
printf("Error: destination %lx not in lower 2GB for mov_m8abs_reg8()\n", (long) m8);
351
put8((reg8 << 3) | 4);
353
put32((int) (unsigned long) m8);
356
void mov_reg16_m16abs(int reg16, unsigned short *m16)
358
if ((long) m16 & 0xFFFFFFFF80000000LL)
360
printf("Error: destination %lx not in lower 2GB for mov_reg16_m16abs()\n", (long) m16);
365
put8((reg16 << 3) | 4);
367
put32((int) (unsigned long) m16);
370
void mov_m16abs_reg16(unsigned short *m16, int reg16)
372
if ((long) m16 & 0xFFFFFFFF80000000LL)
374
printf("Error: destination %lx not in lower 2GB for mov_m16abs_reg16()\n", (long) m16);
379
put8((reg16 << 3) | 4);
381
put32((int) (unsigned long) m16);
384
void cmp_reg32_m32abs(int reg32, unsigned int *m32)
386
if ((long) m32 & 0xFFFFFFFF80000000LL)
388
printf("Error: destination %lx not in lower 2GB for cmp_reg32_m32abs()\n", (long) m32);
392
put8((reg32 << 3) | 4);
394
put32((int) (unsigned long) m32);
397
void cmp_reg64_m64abs(int reg64, unsigned long long *m64)
399
if ((long) m64 & 0xFFFFFFFF80000000LL)
401
printf("Error: destination %lx not in lower 2GB for cmp_reg64_m64abs()\n", (long) m64);
406
put8((reg64 << 3) | 4);
408
put32((int) (unsigned long) m64);
411
void cmp_reg32_reg32(int reg1, int reg2)
414
put8((reg2 << 3) | reg1 | 0xC0);
417
void cmp_reg64_reg64(int reg1, int reg2)
421
put8((reg2 << 3) | reg1 | 0xC0);
424
void cmp_reg32_imm8(int reg32, unsigned char imm8)
431
void cmp_reg64_imm8(int reg64, unsigned char imm8)
439
void cmp_reg32_imm32(int reg32, unsigned int imm32)
446
void cmp_reg64_imm32(int reg64, unsigned int imm32)
454
void cmp_preg64pimm32_imm8(int reg64, unsigned int imm32, unsigned char imm8)
462
void cmp_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8)
466
put8((reg1 << 3) | reg2);
470
void sete_m8abs(unsigned char *m8)
472
if ((long) m8 & 0xFFFFFFFF80000000LL)
474
printf("Error: destination %lx not in lower 2GB for sete_m8abs()\n", (long) m8);
481
put32((int) (unsigned long) m8);
484
void setne_m8abs(unsigned char *m8)
486
if ((long) m8 & 0xFFFFFFFF80000000LL)
488
printf("Error: destination %lx not in lower 2GB for setne_m8abs()\n", (long) m8);
495
put32((int) (unsigned long) m8);
498
void setl_m8abs(unsigned char *m8)
500
if ((long) m8 & 0xFFFFFFFF80000000LL)
502
printf("Error: destination %lx not in lower 2GB for setl_m8abs()\n", (long) m8);
509
put32((int) (unsigned long) m8);
512
void setle_m8abs(unsigned char *m8)
514
if ((long) m8 & 0xFFFFFFFF80000000LL)
516
printf("Error: destination %lx not in lower 2GB for setle_m8abs()\n", (long) m8);
523
put32((int) (unsigned long) m8);
526
void setg_m8abs(unsigned char *m8)
528
if ((long) m8 & 0xFFFFFFFF80000000LL)
530
printf("Error: destination %lx not in lower 2GB for setg_m8abs()\n", (long) m8);
537
put32((int) (unsigned long) m8);
540
void setge_m8abs(unsigned char *m8)
542
if ((long) m8 & 0xFFFFFFFF80000000LL)
544
printf("Error: destination %lx not in lower 2GB for setge_m8abs()\n", (long) m8);
551
put32((int) (unsigned long) m8);
554
void setl_reg8(unsigned int reg8)
556
put8(0x40); /* we need an REX prefix to use the uniform byte registers */
562
void setb_reg8(unsigned int reg8)
564
put8(0x40); /* we need an REX prefix to use the uniform byte registers */
570
void push_reg64(unsigned int reg64)
575
void pop_reg64(unsigned int reg64)
580
void test_reg32_imm32(int reg32, unsigned int imm32)
587
void test_m32abs_imm32(unsigned int *m32, unsigned int imm32)
589
if ((long) m32 & 0xFFFFFFFF80000000LL)
591
printf("Error: destination %lx not in lower 2GB for test_m32abs_imm32()\n", (long) m32);
597
put32((int) (unsigned long) m32);
601
void cmp_al_imm8(unsigned char imm8)
607
void add_m32abs_reg32(unsigned int *m32, int reg32)
609
if ((long) m32 & 0xFFFFFFFF80000000LL)
611
printf("Error: destination %lx not in lower 2GB for add_m32abs_reg32()\n", (long) m32);
615
put8((reg32 << 3) | 4);
617
put32((int) (unsigned long) m32);
620
void sub_reg32_m32abs(int reg32, unsigned int *m32)
622
if ((long) m32 & 0xFFFFFFFF80000000LL)
624
printf("Error: destination %lx not in lower 2GB for sub_reg32_m32abs()\n", (long) m32);
628
put8((reg32 << 3) | 4);
630
put32((int) (unsigned long) m32);
633
void sub_reg32_reg32(int reg1, int reg2)
636
put8((reg2 << 3) | reg1 | 0xC0);
639
void sub_reg64_reg64(int reg1, int reg2)
643
put8((reg2 << 3) | reg1 | 0xC0);
646
void sbb_reg32_reg32(int reg1, int reg2)
649
put8((reg2 << 3) | reg1 | 0xC0);
652
void sub_reg64_imm32(int reg64, unsigned int imm32)
660
void sub_reg32_imm32(int reg32, unsigned int imm32)
667
void sub_eax_imm32(unsigned int imm32)
673
void jne_rj(unsigned char saut)
679
void je_rj(unsigned char saut)
685
void jb_rj(unsigned char saut)
691
void jbe_rj(unsigned char saut)
697
void ja_rj(unsigned char saut)
703
void jae_rj(unsigned char saut)
709
void jle_rj(unsigned char saut)
715
void jge_rj(unsigned char saut)
721
void jg_rj(unsigned char saut)
727
void jl_rj(unsigned char saut)
733
void jp_rj(unsigned char saut)
739
void je_near(unsigned int mi_addr)
744
add_jump(code_length-4, mi_addr, 0);
747
void je_near_rj(unsigned int saut)
754
void jl_near(unsigned int mi_addr)
759
add_jump(code_length-4, mi_addr, 0);
762
void jl_near_rj(unsigned int saut)
769
void jne_near(unsigned int mi_addr)
774
add_jump(code_length-4, mi_addr, 0);
777
void jne_near_rj(unsigned int saut)
784
void jge_near(unsigned int mi_addr)
789
add_jump(code_length-4, mi_addr, 0);
792
void jge_near_rj(unsigned int saut)
799
void jg_near(unsigned int mi_addr)
804
add_jump(code_length-4, mi_addr, 0);
807
void jle_near(unsigned int mi_addr)
812
add_jump(code_length-4, mi_addr, 0);
815
void jle_near_rj(unsigned int saut)
822
void mov_reg32_imm32(int reg32, unsigned int imm32)
828
void mov_reg64_imm64(int reg64, unsigned long long imm64)
835
void jmp_imm(int saut)
841
void jmp_imm_short(char saut)
847
void or_m32abs_imm32(unsigned int *m32, unsigned int imm32)
849
if ((long) m32 & 0xFFFFFFFF80000000LL)
851
printf("Error: destination %lx not in lower 2GB for or_m32abs_imm32()\n", (long) m32);
857
put32((int) (unsigned long) m32);
861
void or_m32abs_reg32(unsigned int *m32, unsigned int reg32)
863
if ((long) m32 & 0xFFFFFFFF80000000LL)
865
printf("Error: destination %lx not in lower 2GB for or_m32abs_reg32()\n", (long) m32);
869
put8((reg32 << 3) | 4);
871
put32((int) (unsigned long) m32);
874
void or_reg32_m32abs(unsigned int reg32, unsigned int *m32)
876
if ((long) m32 & 0xFFFFFFFF80000000LL)
878
printf("Error: destination %lx not in lower 2GB for or_reg32_m32abs()\n", (long) m32);
882
put8((reg32 << 3) | 4);
884
put32((int) (unsigned long) m32);
887
void or_reg32_reg32(unsigned int reg1, unsigned int reg2)
890
put8(0xC0 | (reg2 << 3) | reg1);
893
void or_reg64_reg64(unsigned int reg1, unsigned int reg2)
897
put8(0xC0 | (reg2 << 3) | reg1);
900
void and_reg32_reg32(unsigned int reg1, unsigned int reg2)
903
put8(0xC0 | (reg2 << 3) | reg1);
906
void and_reg64_reg64(unsigned int reg1, unsigned int reg2)
910
put8(0xC0 | (reg2 << 3) | reg1);
913
void and_m32abs_imm32(unsigned int *m32, unsigned int imm32)
915
if ((long) m32 & 0xFFFFFFFF80000000LL)
917
printf("Error: destination %lx not in lower 2GB for and_m32abs_imm32()\n", (long) m32);
923
put32((int) (unsigned long) m32);
927
void and_reg32_m32abs(unsigned int reg32, unsigned int *m32)
929
if ((long) m32 & 0xFFFFFFFF80000000LL)
931
printf("Error: destination %lx not in lower 2GB for and_reg32_m32abs()\n", (long) m32);
935
put8((reg32 << 3) | 4);
937
put32((int) (unsigned long) m32);
940
void xor_reg32_reg32(unsigned int reg1, unsigned int reg2)
943
put8(0xC0 | (reg2 << 3) | reg1);
946
void xor_reg64_reg64(unsigned int reg1, unsigned int reg2)
950
put8(0xC0 | (reg2 << 3) | reg1);
953
void xor_reg32_m32abs(unsigned int reg32, unsigned int *m32)
955
if ((long) m32 & 0xFFFFFFFF80000000LL)
957
printf("Error: destination %lx not in lower 2GB for xor_reg32_m32abs()\n", (long) m32);
961
put8((reg32 << 3) | 4);
963
put32((int) (unsigned long) m32);
966
void add_m32abs_imm32(unsigned int *m32, unsigned int imm32)
968
if ((long) m32 & 0xFFFFFFFF80000000LL)
970
printf("Error: destination %lx not in lower 2GB for add_m32abs_imm32()\n", (long) m32);
976
put32((int) (unsigned long) m32);
980
void add_m32abs_imm8(unsigned int *m32, unsigned char imm8)
982
if ((long) m32 & 0xFFFFFFFF80000000LL)
984
printf("Error: destination %lx not in lower 2GB for add_m32abs_imm8()\n", (long) m32);
990
put32((int) (unsigned long) m32);
994
void sub_m32abs_imm32(unsigned int *m32, unsigned int imm32)
996
if ((long) m32 & 0xFFFFFFFF80000000LL)
998
printf("Error: destination %lx not in lower 2GB for sub_m32abs_imm32()\n", (long) m32);
1004
put32((int) (unsigned long) m32);
1008
void sub_m64abs_imm32(unsigned long long *m64, unsigned int imm32)
1010
if ((long) m64 & 0xFFFFFFFF80000000LL)
1012
printf("Error: destination %lx not in lower 2GB for sub_m64abs_imm32()\n", (long) m64);
1019
put32((int) (unsigned long) m64);
1023
void add_reg32_imm8(unsigned int reg32, unsigned char imm8)
1030
void add_reg64_imm32(unsigned int reg64, unsigned int imm32)
1038
void add_reg32_imm32(unsigned int reg32, unsigned int imm32)
1045
void inc_m32abs(unsigned int *m32)
1047
if ((long) m32 & 0xFFFFFFFF80000000LL)
1049
printf("Error: destination %lx not in lower 2GB for inc_m32abs()\n", (long) m32);
1055
put32((int) (unsigned long) m32);
1058
void cmp_m32abs_imm32(unsigned int *m32, unsigned int imm32)
1060
if ((long) m32 & 0xFFFFFFFF80000000LL)
1062
printf("Error: destination %lx not in lower 2GB for cmp_m32abs_imm32()\n", (long) m32);
1068
put32((int) (unsigned long) m32);
1072
void cmp_m32abs_imm8(unsigned int *m32, unsigned char imm8)
1074
if ((long) m32 & 0xFFFFFFFF80000000LL)
1076
printf("Error: destination %lx not in lower 2GB for cmp_m32_imm8()\n", (long) m32);
1082
put32((int) (unsigned long) m32);
1086
void cmp_m8abs_imm8(unsigned char *m8, unsigned char imm8)
1088
if ((long) m8 & 0xFFFFFFFF80000000LL)
1090
printf("Error: destination %lx not in lower 2GB for cmp_m8abs_imm8()\n", (long) m8);
1096
put32((int) (unsigned long) m8);
1100
void cmp_eax_imm32(unsigned int imm32)
1106
void mov_m32abs_imm32(unsigned int *m32, unsigned int imm32)
1108
if ((long) m32 & 0xFFFFFFFF80000000LL)
1110
printf("Error: destination %lx not in lower 2GB for mov_m32abs_imm32()\n", (long) m32);
1116
put32((int) (unsigned long) m32);
1120
void jmp(unsigned int mi_addr)
1126
add_jump(code_length-8, mi_addr, 1);
1150
void call_reg64(unsigned int reg64)
1156
void call_m64abs(unsigned long long *m64)
1158
if ((long) m64 & 0xFFFFFFFF80000000LL)
1160
printf("Error: destination %lx not in lower 2GB for call_m64abs()\n", (long) m64);
1166
put32((int) (unsigned long) m64);
1169
void shr_reg64_imm8(unsigned int reg64, unsigned char imm8)
1177
void shr_reg32_imm8(unsigned int reg32, unsigned char imm8)
1184
void shr_reg32_cl(unsigned int reg32)
1190
void shr_reg64_cl(unsigned int reg64)
1197
void sar_reg32_cl(unsigned int reg32)
1203
void sar_reg64_cl(unsigned int reg64)
1210
void shl_reg32_cl(unsigned int reg32)
1216
void shl_reg64_cl(unsigned int reg64)
1223
void shld_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
1227
put8(0xC0 | (reg2 << 3) | reg1);
1230
void shld_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
1234
put8(0xC0 | (reg2 << 3) | reg1);
1238
void shrd_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
1242
put8(0xC0 | (reg2 << 3) | reg1);
1245
void sar_reg32_imm8(unsigned int reg32, unsigned char imm8)
1252
void sar_reg64_imm8(unsigned int reg64, unsigned char imm8)
1260
void shrd_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
1264
put8(0xC0 | (reg2 << 3) | reg1);
1268
void mul_m32abs(unsigned int *m32)
1270
if ((long) m32 & 0xFFFFFFFF80000000LL)
1272
printf("Error: destination %lx not in lower 2GB for mul_m32abs()\n", (long) m32);
1278
put32((int) (unsigned long) m32);
1281
void imul_reg32(unsigned int reg32)
1287
void mul_reg64(unsigned int reg64)
1294
void mul_reg32(unsigned int reg32)
1300
void idiv_reg32(unsigned int reg32)
1306
void div_reg32(unsigned int reg32)
1312
void idiv_m32abs(unsigned int *m32)
1314
if ((long) m32 & 0xFFFFFFFF80000000LL)
1316
printf("Error: destination %lx not in lower 2GB for idiv_m32abs()\n", (long) m32);
1322
put32((int) (unsigned long) m32);
1325
void div_m32abs(unsigned int *m32)
1327
if ((long) m32 & 0xFFFFFFFF80000000LL)
1329
printf("Error: destination %lx not in lower 2GB for div_m32abs()\n", (long) m32);
1335
put32((int) (unsigned long) m32);
1338
void add_reg32_reg32(unsigned int reg1, unsigned int reg2)
1341
put8(0xC0 | (reg2 << 3) | reg1);
1344
void add_reg64_reg64(unsigned int reg1, unsigned int reg2)
1348
put8(0xC0 | (reg2 << 3) | reg1);
1351
void add_reg32_m32abs(unsigned int reg32, unsigned int *m32)
1353
if ((long) m32 & 0xFFFFFFFF80000000LL)
1355
printf("Error: destination %lx not in lower 2GB for add_reg32_m32abs()\n", (long) m32);
1359
put8((reg32 << 3) | 4);
1361
put32((int) (unsigned long) m32);
1364
void add_reg64_m64abs(unsigned int reg64, unsigned long long *m64)
1366
if ((long) m64 & 0xFFFFFFFF80000000LL)
1368
printf("Error: destination %lx not in lower 2GB for add_reg64_m64abs()\n", (long) m64);
1373
put8((reg64 << 3) | 4);
1375
put32((int) (unsigned long) m64);
1378
void adc_reg32_reg32(unsigned int reg1, unsigned int reg2)
1381
put8(0xC0 | (reg2 << 3) | reg1);
1384
void adc_reg32_m32abs(unsigned int reg32, unsigned int *m32)
1386
if ((long) m32 & 0xFFFFFFFF80000000LL)
1388
printf("Error: destination %lx not in lower 2GB for adc_reg32_m32abs()\n", (long) m32);
1392
put8((reg32 << 3) | 4);
1394
put32((int) (unsigned long) m32);
1397
void adc_reg32_imm32(unsigned int reg32, unsigned int imm32)
1404
void jmp_reg64(unsigned int reg64)
1410
void jmp_m64abs(unsigned long long *m64)
1412
if ((long) m64 & 0xFFFFFFFF80000000LL)
1414
printf("Error: destination %lx not in lower 2GB for jmp_m64abs()\n", (long) m64);
1420
put32((int) (unsigned long) m64);
1423
void mov_reg32_preg64(unsigned int reg1, unsigned int reg2)
1426
put8((reg1 << 3) | reg2);
1429
void mov_preg64_reg32(int reg1, int reg2)
1432
put8((reg2 << 3) | reg1);
1435
void mov_preg64_reg64(int reg1, int reg2)
1439
put8((reg2 << 3) | reg1);
1442
void mov_reg64_preg64(int reg1, int reg2)
1446
put8((reg1 << 3) | reg2);
1449
void mov_reg32_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
1452
put8((reg1 << 3) | 0x84);
1453
put8(reg2 | (reg3 << 3));
1457
void mov_preg64preg64pimm32_reg32(int reg1, int reg2, unsigned int imm32, int reg3)
1460
put8((reg3 << 3) | 0x84);
1461
put8(reg1 | (reg2 << 3));
1465
void mov_reg64_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
1469
put8((reg1 << 3) | 0x84);
1470
put8(reg2 | (reg3 << 3));
1474
void mov_reg32_preg64preg64(int reg1, int reg2, int reg3)
1477
put8((reg1 << 3) | 0x04);
1478
put8((reg2 << 3) | reg3);
1481
void mov_reg64_preg64preg64(int reg1, int reg2, int reg3)
1485
put8((reg1 << 3) | 0x04);
1486
put8(reg2 | (reg3 << 3));
1489
void mov_reg32_preg64pimm32(int reg1, int reg2, unsigned int imm32)
1492
put8(0x80 | (reg1 << 3) | reg2);
1496
void mov_reg64_preg64pimm32(int reg1, int reg2, unsigned int imm32)
1500
put8(0x80 | (reg1 << 3) | reg2);
1504
void mov_reg64_preg64pimm8(int reg1, int reg2, unsigned int imm8)
1508
put8(0x40 | (reg1 << 3) | reg2);
1512
void mov_reg32_preg64x4pimm32(int reg1, int reg2, unsigned int imm32)
1515
put8((reg1 << 3) | 4);
1516
put8(0x80 | (reg2 << 3) | 5);
1520
void mov_reg64_preg64x8preg64(int reg1, int reg2, int reg3)
1524
put8((reg1 << 3) | 4);
1525
put8(0xC0 | (reg2 << 3) | reg3);
1528
void mov_preg64preg64_reg8(int reg1, int reg2, int reg8)
1531
put8(0x04 | (reg8 << 3));
1532
put8((reg1 << 3) | reg2);
1535
void mov_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8)
1539
put8((reg1 << 3) | reg2);
1543
void mov_preg64pimm32_imm8(int reg64, unsigned int imm32, unsigned char imm8)
1551
void mov_preg64pimm32_reg16(int reg64, unsigned int imm32, int reg16)
1555
put8(0x80 | reg64 | (reg16 << 3));
1559
void mov_preg64preg64_reg16(int reg1, int reg2, int reg16)
1563
put8(0x04 | (reg16 << 3));
1564
put8((reg1 << 3) | reg2);
1567
void mov_preg64preg64_reg32(int reg1, int reg2, int reg32)
1570
put8(0x04 | (reg32 << 3));
1571
put8((reg1 << 3) | reg2);
1574
void mov_preg64pimm32_reg32(int reg1, unsigned int imm32, int reg2)
1577
put8(0x80 | reg1 | (reg2 << 3));
1581
void mov_preg64pimm8_reg64(int reg1, unsigned int imm8, int reg2)
1585
put8(0x40 | (reg2 << 3) | reg1);
1589
void add_eax_imm32(unsigned int imm32)
1595
void shl_reg32_imm8(unsigned int reg32, unsigned char imm8)
1602
void shl_reg64_imm8(unsigned int reg64, unsigned char imm8)
1610
void mov_reg32_reg32(unsigned int reg1, unsigned int reg2)
1612
if (reg1 == reg2) return;
1614
put8(0xC0 | (reg2 << 3) | reg1);
1617
void mov_reg64_reg64(unsigned int reg1, unsigned int reg2)
1619
if (reg1 == reg2) return;
1622
put8(0xC0 | (reg2 << 3) | reg1);
1625
void mov_reg32_m32abs(unsigned int reg32, unsigned int *m32)
1627
if ((long) m32 & 0xFFFFFFFF80000000LL)
1629
printf("Error: destination %lx not in lower 2GB for mov_reg32_m32abs()\n", (long) m32);
1633
put8((reg32 << 3) | 4);
1635
put32((int) (unsigned long) m32);
1638
void mov_m32abs_reg32(unsigned int *m32, unsigned int reg32)
1640
if ((long) m32 & 0xFFFFFFFF80000000LL)
1642
printf("Error: destination %lx not in lower 2GB for mov_m32abs_reg32()\n", (long) m32);
1646
put8((reg32 << 3) | 4);
1648
put32((int) (unsigned long) m32);
1651
void mov_reg64_m64abs(unsigned int reg64, unsigned long long* m64)
1653
if ((long) m64 & 0xFFFFFFFF80000000LL)
1655
printf("Error: destination %lx not in lower 2GB for mov_reg64_m64abs()\n", (long) m64);
1660
put8((reg64 << 3) | 4);
1662
put32((int) (unsigned long) m64);
1665
void mov_m64abs_reg64(unsigned long long *m64, unsigned int reg64)
1667
if ((long) m64 & 0xFFFFFFFF80000000LL)
1669
printf("Error: destination %lx not in lower 2GB for mov_m64abs_reg64()\n", (long) m64);
1674
put8((reg64 << 3) | 4);
1676
put32((int) (unsigned long) m64);
1679
void mov_reg8_m8abs(int reg8, unsigned char *m8)
1681
if ((long) m8 & 0xFFFFFFFF80000000LL)
1683
printf("Error: destination %lx not in lower 2GB for mov_reg8_m8abs()\n", (long) m8);
1687
put8((reg8 << 3) | 4);
1689
put32((int) (unsigned long) m8);
1692
void and_eax_imm32(unsigned int imm32)
1698
void or_reg32_imm32(int reg32, unsigned int imm32)
1705
void or_reg64_imm32(int reg64, unsigned int imm32)
1713
void and_reg32_imm32(int reg32, unsigned int imm32)
1720
void and_reg64_imm32(int reg64, unsigned int imm32)
1728
void and_reg32_imm8(int reg32, unsigned char imm8)
1735
void and_reg64_imm8(int reg64, unsigned char imm8)
1743
void and_ax_imm16(unsigned short imm16)
1750
void and_al_imm8(unsigned char imm8)
1756
void or_ax_imm16(unsigned short imm16)
1763
void or_eax_imm32(unsigned int imm32)
1769
void xor_ax_imm16(unsigned short imm16)
1776
void xor_al_imm8(unsigned char imm8)
1782
void xor_reg64_imm32(int reg64, unsigned int imm32)
1790
void xor_reg32_imm32(int reg32, unsigned int imm32)
1797
void xor_reg8_imm8(int reg8, unsigned char imm8)
1799
put8(0x40); /* we need an REX prefix to use the uniform byte registers */
1810
void not_reg32(unsigned int reg32)
1816
void not_reg64(unsigned int reg64)
1823
void neg_reg32(unsigned int reg32)
1829
void neg_reg64(unsigned int reg64)
1836
void movsx_reg32_m8abs(int reg32, unsigned char *m8)
1838
if ((long) m8 & 0xFFFFFFFF80000000LL)
1840
printf("Error: destination %lx not in lower 2GB for movsx_reg32_m8abs()\n", (long) m8);
1845
put8((reg32 << 3) | 4);
1847
put32((int) (unsigned long) m8);
1850
void movsx_reg32_8preg64pimm32(int reg1, int reg2, unsigned int imm32)
1854
put8((reg1 << 3) | reg2 | 0x80);
1858
void movsx_reg32_8preg64preg64(int reg1, int reg2, int reg3)
1862
put8((reg1 << 3) | 0x04);
1863
put8((reg2 << 3) | reg3);
1866
void movsx_reg32_16preg64pimm32(int reg1, int reg2, unsigned int imm32)
1870
put8((reg1 << 3) | reg2 | 0x80);
1874
void movsx_reg32_16preg64preg64(int reg1, int reg2, int reg3)
1878
put8((reg1 << 3) | 0x04);
1879
put8((reg2 << 3) | reg3);
1882
void movsx_reg32_reg16(int reg32, int reg16)
1886
put8((reg32 << 3) | reg16 | 0xC0);
1889
void movsx_reg32_m16abs(int reg32, unsigned short *m16)
1891
if ((long) m16 & 0xFFFFFFFF80000000LL)
1893
printf("Error: destination %lx not in lower 2GB for movsx_reg32_m16abs()\n", (long) m16);
1898
put8((reg32 << 3) | 4);
1900
put32((int) (unsigned long) m16);
1903
void movsxd_reg64_reg32(int reg64, int reg32)
1907
put8((reg64 << 3) | reg32 | 0xC0);
1910
void movsxd_reg64_m32abs(int reg64, unsigned int *m32)
1912
if ((long) m32 & 0xFFFFFFFF80000000LL)
1914
printf("Error: destination %lx not in lower 2GB for movsxd_reg64_m32abs()\n", (long) m32);
1919
put8((reg64 << 3) | 0x04);
1921
put32((int) (unsigned long) m32);
1924
void fldcw_m16abs(unsigned short *m16)
1926
if ((long) m16 & 0xFFFFFFFF80000000LL)
1928
printf("Error: destination %lx not in lower 2GB for fldcw_m16abs()\n", (long) m16);
1934
put32((int) (unsigned long) m16);
1937
void fld_preg64_dword(int reg64)
1943
void fdiv_preg64_dword(int reg64)
1949
void fstp_preg64_dword(int reg64)
1961
void fstp_preg64_qword(int reg64)
1967
void fadd_preg64_dword(int reg64)
1973
void fsub_preg64_dword(int reg64)
1979
void fmul_preg64_dword(int reg64)
1985
void fcomp_preg64_dword(int reg64)
1991
void fistp_preg64_dword(int reg64)
1997
void fistp_m32abs(unsigned int *m32)
1999
if ((long) m32 & 0xFFFFFFFF80000000LL)
2001
printf("Error: destination %lx not in lower 2GB for fistp_m32abs()\n", (long) m32);
2007
put32((int) (unsigned long) m32);
2010
void fistp_preg64_qword(int reg64)
2016
void fistp_m64abs(unsigned long long *m64)
2018
if ((long) m64 & 0xFFFFFFFF80000000LL)
2020
printf("Error: destination %lx not in lower 2GB for fistp_m64abs()\n", (long) m64);
2026
put32((int) (unsigned long) m64);
2029
void fld_preg64_qword(int reg64)
2035
void fild_preg64_qword(int reg64)
2041
void fild_preg64_dword(int reg64)
2047
void fadd_preg64_qword(int reg64)
2053
void fdiv_preg64_qword(int reg64)
2059
void fsub_preg64_qword(int reg64)
2065
void fmul_preg64_qword(int reg64)
2083
void fcomip_fpreg(int fpreg)
2089
void fucomip_fpreg(int fpreg)
2095
void ffree_fpreg(int fpreg)