~ubuntu-branches/ubuntu/quantal/mupen64plus/quantal

« back to all changes in this revision

Viewing changes to .pc/noexecstack.patch/r4300/x86_64/assemble.c

  • Committer: Bazaar Package Importer
  • Author(s): Sven Eckelmann, Sven Eckelmann, Piotr Ożarowski
  • Date: 2010-05-06 11:34:46 UTC
  • mfrom: (3.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20100506113446-jfcd6uk7waudel82
Tags: 1.5+dfsg1-10
[ Sven Eckelmann ]
* debian/patches:
  - Add rsp_ucode2_reset.patch, Reset status of specific ucode2 hacks after
    starting again
  - Add rsp_hle_bigendian.patch, Fix wrong high level emulation of rsp on big
    endian systems
  - Add rice-crash-vendorstring.patch, Don't crash on long OpenGL vendor
    string (Closes: #580480, LP: #575968)

[ Piotr Ożarowski ]
* DMUA flag set to yes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include <stdlib.h>
 
24
#include <stdio.h>
 
25
 
 
26
#include "assemble.h"
 
27
 
 
28
#include "../recomph.h"
 
29
#include "../r4300.h"
 
30
 
 
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
 
33
 * cause an exception.
 
34
*/
 
35
#define REL_PLACEHOLDER 0x7fffffff
 
36
 
 
37
typedef struct _jump_table
 
38
{
 
39
  unsigned int mi_addr;
 
40
  unsigned int pc_addr;
 
41
  unsigned int absolute64;
 
42
} jump_table;
 
43
 
 
44
static jump_table *jumps_table = NULL;
 
45
static int jumps_number = 0, max_jumps_number = 0;
 
46
 
 
47
typedef struct _riprelative_table
 
48
{
 
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 */
 
52
} riprelative_table;
 
53
 
 
54
static riprelative_table *riprel_table = NULL;
 
55
static int riprel_number = 0, max_riprel_number = 0;
 
56
 
 
57
/* Static Functions */
 
58
 
 
59
static void add_jump(unsigned int pc_addr, unsigned int mi_addr, unsigned int absolute64)
 
60
{
 
61
  if (jumps_number == max_jumps_number)
 
62
  {
 
63
    max_jumps_number += 512;
 
64
    jumps_table = realloc(jumps_table, max_jumps_number*sizeof(jump_table));
 
65
  }
 
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;
 
69
  jumps_number++;
 
70
}
 
71
 
 
72
static void add_riprelative(unsigned int pc_addr, unsigned int extra_bytes, void *global_64_ptr)
 
73
{
 
74
  if (riprel_number == max_riprel_number)
 
75
  {
 
76
    max_riprel_number += 512;
 
77
    riprel_table = realloc(riprel_table, max_riprel_number * sizeof(riprelative_table));
 
78
  }
 
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;
 
82
  riprel_number++;
 
83
}
 
84
 
 
85
/* Global Functions */
 
86
 
 
87
void init_assembler(void *block_jumps_table, int block_jumps_number, void *block_riprel_table, int block_riprel_number)
 
88
{
 
89
  if (block_jumps_table)
 
90
  {
 
91
    jumps_table = block_jumps_table;
 
92
    jumps_number = block_jumps_number;
 
93
    if (jumps_number <= 512)
 
94
      max_jumps_number = 512;
 
95
    else
 
96
      max_jumps_number = (jumps_number + 511) & 0xfffffe00;
 
97
  }
 
98
  else
 
99
  {
 
100
    jumps_table = malloc(512*sizeof(jump_table));
 
101
    jumps_number = 0;
 
102
    max_jumps_number = 512;
 
103
  }
 
104
 
 
105
  if (block_riprel_table)
 
106
  {
 
107
    riprel_table = block_riprel_table;
 
108
    riprel_number = block_riprel_number;
 
109
    if (riprel_number <= 512)
 
110
      max_riprel_number = 512;
 
111
    else
 
112
      max_riprel_number = (riprel_number + 511) & 0xfffffe00;
 
113
  }
 
114
  else
 
115
  {
 
116
    riprel_table = malloc(512 * sizeof(riprelative_table));
 
117
    riprel_number = 0;
 
118
    max_riprel_number = 512;
 
119
  }
 
120
}
 
121
 
 
122
void free_assembler(void **block_jumps_table, int *block_jumps_number, void **block_riprel_table, int *block_riprel_number)
 
123
{
 
124
  *block_jumps_table = jumps_table;
 
125
  *block_jumps_number = jumps_number;
 
126
  *block_riprel_table = riprel_table;
 
127
  *block_riprel_number = riprel_number;
 
128
}
 
129
 
 
130
void passe2(precomp_instr *dest, int start, int end, precomp_block *block)
 
131
{
 
132
  unsigned int i;
 
133
 
 
134
  build_wrappers(dest, start, end, block);
 
135
 
 
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.
 
140
   */
 
141
  for (i = 0; i < jumps_number; i++)
 
142
  {
 
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)
 
148
    {
 
149
      addr_dest = jump_instr->reg_cache_infos.jump_wrapper;
 
150
    }
 
151
    else
 
152
    {
 
153
      addr_dest = block->code + jump_instr->local_addr;
 
154
    }
 
155
    /* write either a 32-bit IP-relative offset or a 64-bit absolute address */
 
156
    if (jumps_table[i].absolute64)
 
157
    {
 
158
      *((unsigned long long *) (block->code + jmp_offset_loc)) = (unsigned long long) addr_dest;
 
159
    }
 
160
    else
 
161
    {
 
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)
 
165
      {
 
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);
 
168
        asm(" int $3; ");
 
169
      }
 
170
    }
 
171
  }
 
172
 
 
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
 
175
   * mode either).
 
176
   */
 
177
  for (i = 0; i < riprel_number; i++)
 
178
  {
 
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)
 
182
    {
 
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);
 
185
      asm(" int $3; ");
 
186
    }
 
187
    *((int *) rel_offset_ptr) = (int) rip_rel_offset;
 
188
  }
 
189
 
 
190
}
 
191
 
 
192
static void put8(unsigned char octet)
 
193
{
 
194
  (*inst_pointer)[code_length] = octet;
 
195
  code_length++;
 
196
  if (code_length == max_code_length)
 
197
  {
 
198
    max_code_length += 8192;
 
199
    *inst_pointer = realloc(*inst_pointer, max_code_length);
 
200
  }
 
201
}
 
202
 
 
203
static void put16(unsigned short word)
 
204
{
 
205
  if ((code_length + 2) >= max_code_length)
 
206
  {
 
207
    max_code_length += 8192;
 
208
    *inst_pointer = realloc(*inst_pointer, max_code_length);
 
209
  }
 
210
  *((unsigned short *) (*inst_pointer + code_length)) = word;
 
211
  code_length += 2;
 
212
}
 
213
 
 
214
static void put32(unsigned int dword)
 
215
{
 
216
  if ((code_length + 4) >= max_code_length)
 
217
  {
 
218
    max_code_length += 8192;
 
219
    *inst_pointer = realloc(*inst_pointer, max_code_length);
 
220
  }
 
221
  *((unsigned int *) (*inst_pointer + code_length)) = dword;
 
222
  code_length += 4;
 
223
}
 
224
 
 
225
static void put64(unsigned long long qword)
 
226
{
 
227
  if ((code_length + 8) >= max_code_length)
 
228
  {
 
229
    max_code_length += 8192;
 
230
    *inst_pointer = realloc(*inst_pointer, max_code_length);
 
231
  }
 
232
  *((unsigned long long *) (*inst_pointer + code_length)) = qword;
 
233
  code_length += 8;
 
234
}
 
235
 
 
236
void code_align16(void)
 
237
{
 
238
  int bytes = 0;
 
239
 
 
240
  if (((long) (*inst_pointer) & 15) != 0)
 
241
  {
 
242
    printf("Error: code block pointer is not 16-byte aligned!\n");
 
243
    asm(" int $3; ");
 
244
  }
 
245
 
 
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 */
 
249
  {
 
250
    if (bytes == 4 || bytes > 9)
 
251
    { bytes -= 4; put32(0x90666666); }
 
252
    else if (bytes == 1)
 
253
    { bytes -= 1; put8(0x90); }
 
254
    else if (bytes == 2)
 
255
    { bytes -= 2; put16(0x9066); }
 
256
    else if (bytes == 3)
 
257
    { bytes -= 4; put16(0x6666); put8(0x90); }
 
258
    else if (bytes == 5)
 
259
    { bytes -= 5; put32(0x66906666); put8(0x90); }
 
260
    else if (bytes == 6)
 
261
    { bytes -= 6; put32(0x66906666); put16(0x9066); }
 
262
    else if (bytes == 7)
 
263
    { bytes -= 7; put32(0x90666666); put16(0x6666); put8(0x90); }
 
264
    else if (bytes == 8)
 
265
    { bytes -= 8; put32(0x90666666); put32(0x90666666); }
 
266
    else if (bytes == 9)
 
267
    { bytes -= 9; put32(0x66906666); put32(0x66669066); put8(0x90); }
 
268
  }
 
269
 
 
270
}
 
271
 
 
272
static unsigned int g_jump_start8 = 0;
 
273
static unsigned int g_jump_start32 = 0;
 
274
 
 
275
void jump_start_rel8(void)
 
276
{
 
277
  g_jump_start8 = code_length;
 
278
}
 
279
 
 
280
void jump_start_rel32(void)
 
281
{
 
282
  g_jump_start32 = code_length;
 
283
}
 
284
 
 
285
void jump_end_rel8(void)
 
286
{
 
287
  unsigned int jump_end = code_length;
 
288
  int jump_vec = jump_end - g_jump_start8;
 
289
 
 
290
  if (jump_vec > 127 || jump_vec < -128)
 
291
  {
 
292
    printf("Error: 8-bit relative jump too long! From %x to %x\n", g_jump_start8, jump_end);
 
293
    asm(" int $3; ");
 
294
  }
 
295
 
 
296
  code_length = g_jump_start8 - 1;
 
297
  put8(jump_vec);
 
298
  code_length = jump_end;
 
299
}
 
300
 
 
301
void jump_end_rel32(void)
 
302
{
 
303
  unsigned int jump_end = code_length;
 
304
  int jump_vec = jump_end - g_jump_start32;
 
305
 
 
306
  code_length = g_jump_start32 - 4;
 
307
  put32(jump_vec);
 
308
  code_length = jump_end;
 
309
}
 
310
 
 
311
void int_imm8(unsigned char imm8)
 
312
{
 
313
   put8(0xCD);
 
314
   put8(imm8);
 
315
}
 
316
 
 
317
void mov_eax_memoffs32(unsigned int *memoffs32)
 
318
{
 
319
   put8(0xA1);
 
320
   put64((unsigned long long) memoffs32);
 
321
}
 
322
 
 
323
void mov_memoffs32_eax(unsigned int *memoffs32)
 
324
{
 
325
   put8(0xA3);
 
326
   put64((unsigned long long) memoffs32);
 
327
}
 
328
 
 
329
void mov_rax_memoffs64(unsigned long long *memoffs64)
 
330
{
 
331
   put8(0x48);
 
332
   put8(0xA1);
 
333
   put64((unsigned long long) memoffs64);
 
334
}
 
335
 
 
336
void mov_memoffs64_rax(unsigned long long *memoffs64)
 
337
{
 
338
   put8(0x48);
 
339
   put8(0xA3);
 
340
   put64((unsigned long long) memoffs64);
 
341
}
 
342
 
 
343
void mov_m8abs_reg8(unsigned char *m8, int reg8)
 
344
{
 
345
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
346
   {
 
347
     printf("Error: destination %lx not in lower 2GB for mov_m8abs_reg8()\n", (long) m8);
 
348
     asm(" int $3; ");
 
349
   }
 
350
   put8(0x88);
 
351
   put8((reg8 << 3) | 4);
 
352
   put8(0x25);
 
353
   put32((int) (unsigned long) m8);
 
354
}
 
355
 
 
356
void mov_reg16_m16abs(int reg16, unsigned short *m16)
 
357
{
 
358
   if ((long) m16 & 0xFFFFFFFF80000000LL)
 
359
   {
 
360
     printf("Error: destination %lx not in lower 2GB for mov_reg16_m16abs()\n", (long) m16);
 
361
     asm(" int $3; ");
 
362
   }
 
363
   put8(0x66);
 
364
   put8(0x8B);
 
365
   put8((reg16 << 3) | 4);
 
366
   put8(0x25);
 
367
   put32((int) (unsigned long) m16);
 
368
}
 
369
 
 
370
void mov_m16abs_reg16(unsigned short *m16, int reg16)
 
371
{
 
372
   if ((long) m16 & 0xFFFFFFFF80000000LL)
 
373
   {
 
374
     printf("Error: destination %lx not in lower 2GB for mov_m16abs_reg16()\n", (long) m16);
 
375
     asm(" int $3; ");
 
376
   }
 
377
   put8(0x66);
 
378
   put8(0x89);
 
379
   put8((reg16 << 3) | 4);
 
380
   put8(0x25);
 
381
   put32((int) (unsigned long) m16);
 
382
}
 
383
 
 
384
void cmp_reg32_m32abs(int reg32, unsigned int *m32)
 
385
{
 
386
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
387
   {
 
388
     printf("Error: destination %lx not in lower 2GB for cmp_reg32_m32abs()\n", (long) m32);
 
389
     asm(" int $3; ");
 
390
   }
 
391
   put8(0x3B);
 
392
   put8((reg32 << 3) | 4);
 
393
   put8(0x25);
 
394
   put32((int) (unsigned long) m32);
 
395
}
 
396
 
 
397
void cmp_reg64_m64abs(int reg64, unsigned long long *m64)
 
398
{
 
399
   if ((long) m64 & 0xFFFFFFFF80000000LL)
 
400
   {
 
401
     printf("Error: destination %lx not in lower 2GB for cmp_reg64_m64abs()\n", (long) m64);
 
402
     asm(" int $3; ");
 
403
   }
 
404
   put8(0x48);
 
405
   put8(0x3B);
 
406
   put8((reg64 << 3) | 4);
 
407
   put8(0x25);
 
408
   put32((int) (unsigned long) m64);
 
409
}
 
410
 
 
411
void cmp_reg32_reg32(int reg1, int reg2)
 
412
{
 
413
   put8(0x39);
 
414
   put8((reg2 << 3) | reg1 | 0xC0);
 
415
}
 
416
 
 
417
void cmp_reg64_reg64(int reg1, int reg2)
 
418
{
 
419
   put8(0x48);
 
420
   put8(0x39);
 
421
   put8((reg2 << 3) | reg1 | 0xC0);
 
422
}
 
423
 
 
424
void cmp_reg32_imm8(int reg32, unsigned char imm8)
 
425
{
 
426
   put8(0x83);
 
427
   put8(0xF8 + reg32);
 
428
   put8(imm8);
 
429
}
 
430
 
 
431
void cmp_reg64_imm8(int reg64, unsigned char imm8)
 
432
{
 
433
   put8(0x48);
 
434
   put8(0x83);
 
435
   put8(0xF8 + reg64);
 
436
   put8(imm8);
 
437
}
 
438
 
 
439
void cmp_reg32_imm32(int reg32, unsigned int imm32)
 
440
{
 
441
   put8(0x81);
 
442
   put8(0xF8 + reg32);
 
443
   put32(imm32);
 
444
}
 
445
 
 
446
void cmp_reg64_imm32(int reg64, unsigned int imm32)
 
447
{
 
448
   put8(0x48);
 
449
   put8(0x81);
 
450
   put8(0xF8 + reg64);
 
451
   put32(imm32);
 
452
}
 
453
 
 
454
void cmp_preg64pimm32_imm8(int reg64, unsigned int imm32, unsigned char imm8)
 
455
{
 
456
   put8(0x80);
 
457
   put8(0xB8 + reg64);
 
458
   put32(imm32);
 
459
   put8(imm8);
 
460
}
 
461
 
 
462
void cmp_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8)
 
463
{
 
464
   put8(0x80);
 
465
   put8(0x3C);
 
466
   put8((reg1 << 3) | reg2);
 
467
   put8(imm8);
 
468
}
 
469
 
 
470
void sete_m8abs(unsigned char *m8)
 
471
{
 
472
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
473
   {
 
474
     printf("Error: destination %lx not in lower 2GB for sete_m8abs()\n", (long) m8);
 
475
     asm(" int $3; ");
 
476
   }
 
477
   put8(0x0F);
 
478
   put8(0x94);
 
479
   put8(0x04);
 
480
   put8(0x25);
 
481
   put32((int) (unsigned long) m8);
 
482
}
 
483
 
 
484
void setne_m8abs(unsigned char *m8)
 
485
{
 
486
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
487
   {
 
488
     printf("Error: destination %lx not in lower 2GB for setne_m8abs()\n", (long) m8);
 
489
     asm(" int $3; ");
 
490
   }
 
491
   put8(0x0F);
 
492
   put8(0x95);
 
493
   put8(0x04);
 
494
   put8(0x25);
 
495
   put32((int) (unsigned long) m8);
 
496
}
 
497
 
 
498
void setl_m8abs(unsigned char *m8)
 
499
{
 
500
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
501
   {
 
502
     printf("Error: destination %lx not in lower 2GB for setl_m8abs()\n", (long) m8);
 
503
     asm(" int $3; ");
 
504
   }
 
505
   put8(0x0F);
 
506
   put8(0x9C);
 
507
   put8(0x04);
 
508
   put8(0x25);
 
509
   put32((int) (unsigned long) m8);
 
510
}
 
511
 
 
512
void setle_m8abs(unsigned char *m8)
 
513
{
 
514
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
515
   {
 
516
     printf("Error: destination %lx not in lower 2GB for setle_m8abs()\n", (long) m8);
 
517
     asm(" int $3; ");
 
518
   }
 
519
   put8(0x0F);
 
520
   put8(0x9E);
 
521
   put8(0x04);
 
522
   put8(0x25);
 
523
   put32((int) (unsigned long) m8);
 
524
}
 
525
 
 
526
void setg_m8abs(unsigned char *m8)
 
527
{
 
528
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
529
   {
 
530
     printf("Error: destination %lx not in lower 2GB for setg_m8abs()\n", (long) m8);
 
531
     asm(" int $3; ");
 
532
   }
 
533
   put8(0x0F);
 
534
   put8(0x9F);
 
535
   put8(0x04);
 
536
   put8(0x25);
 
537
   put32((int) (unsigned long) m8);
 
538
}
 
539
 
 
540
void setge_m8abs(unsigned char *m8)
 
541
{
 
542
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
543
   {
 
544
     printf("Error: destination %lx not in lower 2GB for setge_m8abs()\n", (long) m8);
 
545
     asm(" int $3; ");
 
546
   }
 
547
   put8(0x0F);
 
548
   put8(0x9D);
 
549
   put8(0x04);
 
550
   put8(0x25);
 
551
   put32((int) (unsigned long) m8);
 
552
}
 
553
 
 
554
void setl_reg8(unsigned int reg8)
 
555
{
 
556
   put8(0x40);  /* we need an REX prefix to use the uniform byte registers */
 
557
   put8(0x0F);
 
558
   put8(0x9C);
 
559
   put8(0xC0 | reg8);
 
560
}
 
561
 
 
562
void setb_reg8(unsigned int reg8)
 
563
{
 
564
   put8(0x40);  /* we need an REX prefix to use the uniform byte registers */
 
565
   put8(0x0F);
 
566
   put8(0x92);
 
567
   put8(0xC0 | reg8);
 
568
}
 
569
 
 
570
void push_reg64(unsigned int reg64)
 
571
{
 
572
   put8(0x50 + reg64);
 
573
}
 
574
 
 
575
void pop_reg64(unsigned int reg64)
 
576
{
 
577
   put8(0x58 + reg64);
 
578
}
 
579
 
 
580
void test_reg32_imm32(int reg32, unsigned int imm32)
 
581
{
 
582
   put8(0xF7);
 
583
   put8(0xC0 + reg32);
 
584
   put32(imm32);
 
585
}
 
586
 
 
587
void test_m32abs_imm32(unsigned int *m32, unsigned int imm32)
 
588
{
 
589
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
590
   {
 
591
     printf("Error: destination %lx not in lower 2GB for test_m32abs_imm32()\n", (long) m32);
 
592
     asm(" int $3; ");
 
593
   }
 
594
   put8(0xF7);
 
595
   put8(0x04);
 
596
   put8(0x25);
 
597
   put32((int) (unsigned long) m32);
 
598
   put32(imm32);
 
599
}
 
600
 
 
601
void cmp_al_imm8(unsigned char imm8)
 
602
{
 
603
   put8(0x3C);
 
604
   put8(imm8);
 
605
}
 
606
 
 
607
void add_m32abs_reg32(unsigned int *m32, int reg32)
 
608
{
 
609
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
610
   {
 
611
     printf("Error: destination %lx not in lower 2GB for add_m32abs_reg32()\n", (long) m32);
 
612
     asm(" int $3; ");
 
613
   }
 
614
   put8(0x01);
 
615
   put8((reg32 << 3) | 4);
 
616
   put8(0x25);
 
617
   put32((int) (unsigned long) m32);
 
618
}
 
619
 
 
620
void sub_reg32_m32abs(int reg32, unsigned int *m32)
 
621
{
 
622
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
623
   {
 
624
     printf("Error: destination %lx not in lower 2GB for sub_reg32_m32abs()\n", (long) m32);
 
625
     asm(" int $3; ");
 
626
   }
 
627
   put8(0x2B);
 
628
   put8((reg32 << 3) | 4);
 
629
   put8(0x25);
 
630
   put32((int) (unsigned long) m32);
 
631
}
 
632
 
 
633
void sub_reg32_reg32(int reg1, int reg2)
 
634
{
 
635
   put8(0x29);
 
636
   put8((reg2 << 3) | reg1 | 0xC0);
 
637
}
 
638
 
 
639
void sub_reg64_reg64(int reg1, int reg2)
 
640
{
 
641
   put8(0x48);
 
642
   put8(0x29);
 
643
   put8((reg2 << 3) | reg1 | 0xC0);
 
644
}
 
645
 
 
646
void sbb_reg32_reg32(int reg1, int reg2)
 
647
{
 
648
   put8(0x19);
 
649
   put8((reg2 << 3) | reg1 | 0xC0);
 
650
}
 
651
 
 
652
void sub_reg64_imm32(int reg64, unsigned int imm32)
 
653
{
 
654
   put8(0x48);
 
655
   put8(0x81);
 
656
   put8(0xE8 + reg64);
 
657
   put32(imm32);
 
658
}
 
659
 
 
660
void sub_reg32_imm32(int reg32, unsigned int imm32)
 
661
{
 
662
   put8(0x81);
 
663
   put8(0xE8 + reg32);
 
664
   put32(imm32);
 
665
}
 
666
 
 
667
void sub_eax_imm32(unsigned int imm32)
 
668
{
 
669
   put8(0x2D);
 
670
   put32(imm32);
 
671
}
 
672
 
 
673
void jne_rj(unsigned char saut)
 
674
{
 
675
   put8(0x75);
 
676
   put8(saut);
 
677
}
 
678
 
 
679
void je_rj(unsigned char saut)
 
680
{
 
681
   put8(0x74);
 
682
   put8(saut);
 
683
}
 
684
 
 
685
void jb_rj(unsigned char saut)
 
686
{
 
687
   put8(0x72);
 
688
   put8(saut);
 
689
}
 
690
 
 
691
void jbe_rj(unsigned char saut)
 
692
{
 
693
   put8(0x76);
 
694
   put8(saut);
 
695
}
 
696
 
 
697
void ja_rj(unsigned char saut)
 
698
{
 
699
   put8(0x77);
 
700
   put8(saut);
 
701
}
 
702
 
 
703
void jae_rj(unsigned char saut)
 
704
{
 
705
   put8(0x73);
 
706
   put8(saut);
 
707
}
 
708
 
 
709
void jle_rj(unsigned char saut)
 
710
{
 
711
   put8(0x7E);
 
712
   put8(saut);
 
713
}
 
714
 
 
715
void jge_rj(unsigned char saut)
 
716
{
 
717
   put8(0x7D);
 
718
   put8(saut);
 
719
}
 
720
 
 
721
void jg_rj(unsigned char saut)
 
722
{
 
723
   put8(0x7F);
 
724
   put8(saut);
 
725
}
 
726
 
 
727
void jl_rj(unsigned char saut)
 
728
{
 
729
   put8(0x7C);
 
730
   put8(saut);
 
731
}
 
732
 
 
733
void jp_rj(unsigned char saut)
 
734
{
 
735
   put8(0x7A);
 
736
   put8(saut);
 
737
}
 
738
 
 
739
void je_near(unsigned int mi_addr)
 
740
{
 
741
   put8(0x0F);
 
742
   put8(0x84);
 
743
   put32(0);
 
744
   add_jump(code_length-4, mi_addr, 0);
 
745
}
 
746
 
 
747
void je_near_rj(unsigned int saut)
 
748
{
 
749
   put8(0x0F);
 
750
   put8(0x84);
 
751
   put32(saut);
 
752
}
 
753
 
 
754
void jl_near(unsigned int mi_addr)
 
755
{
 
756
   put8(0x0F);
 
757
   put8(0x8C);
 
758
   put32(0);
 
759
   add_jump(code_length-4, mi_addr, 0);
 
760
}
 
761
 
 
762
void jl_near_rj(unsigned int saut)
 
763
{
 
764
   put8(0x0F);
 
765
   put8(0x8C);
 
766
   put32(saut);
 
767
}
 
768
 
 
769
void jne_near(unsigned int mi_addr)
 
770
{
 
771
   put8(0x0F);
 
772
   put8(0x85);
 
773
   put32(0);
 
774
   add_jump(code_length-4, mi_addr, 0);
 
775
}
 
776
 
 
777
void jne_near_rj(unsigned int saut)
 
778
{
 
779
   put8(0x0F);
 
780
   put8(0x85);
 
781
   put32(saut);
 
782
}
 
783
 
 
784
void jge_near(unsigned int mi_addr)
 
785
{
 
786
   put8(0x0F);
 
787
   put8(0x8D);
 
788
   put32(0);
 
789
   add_jump(code_length-4, mi_addr, 0);
 
790
}
 
791
 
 
792
void jge_near_rj(unsigned int saut)
 
793
{
 
794
   put8(0x0F);
 
795
   put8(0x8D);
 
796
   put32(saut);
 
797
}
 
798
 
 
799
void jg_near(unsigned int mi_addr)
 
800
{
 
801
   put8(0x0F);
 
802
   put8(0x8F);
 
803
   put32(0);
 
804
   add_jump(code_length-4, mi_addr, 0);
 
805
}
 
806
 
 
807
void jle_near(unsigned int mi_addr)
 
808
{
 
809
   put8(0x0F);
 
810
   put8(0x8E);
 
811
   put32(0);
 
812
   add_jump(code_length-4, mi_addr, 0);
 
813
}
 
814
 
 
815
void jle_near_rj(unsigned int saut)
 
816
{
 
817
   put8(0x0F);
 
818
   put8(0x8E);
 
819
   put32(saut);
 
820
}
 
821
 
 
822
void mov_reg32_imm32(int reg32, unsigned int imm32)
 
823
{
 
824
   put8(0xB8+reg32);
 
825
   put32(imm32);
 
826
}
 
827
 
 
828
void mov_reg64_imm64(int reg64, unsigned long long imm64)
 
829
{
 
830
   put8(0x48);
 
831
   put8(0xB8+reg64);
 
832
   put64(imm64);
 
833
}
 
834
 
 
835
void jmp_imm(int saut)
 
836
{
 
837
   put8(0xE9);
 
838
   put32(saut);
 
839
}
 
840
 
 
841
void jmp_imm_short(char saut)
 
842
{
 
843
   put8(0xEB);
 
844
   put8(saut);
 
845
}
 
846
 
 
847
void or_m32abs_imm32(unsigned int *m32, unsigned int imm32)
 
848
{
 
849
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
850
   {
 
851
     printf("Error: destination %lx not in lower 2GB for or_m32abs_imm32()\n", (long) m32);
 
852
     asm(" int $3; ");
 
853
   }
 
854
   put8(0x81);
 
855
   put8(0x0C);
 
856
   put8(0x25);
 
857
   put32((int) (unsigned long) m32);
 
858
   put32(imm32);
 
859
}
 
860
 
 
861
void or_m32abs_reg32(unsigned int *m32, unsigned int reg32)
 
862
{
 
863
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
864
   {
 
865
     printf("Error: destination %lx not in lower 2GB for or_m32abs_reg32()\n", (long) m32);
 
866
     asm(" int $3; ");
 
867
   }
 
868
   put8(0x09);
 
869
   put8((reg32 << 3) | 4);
 
870
   put8(0x25);
 
871
   put32((int) (unsigned long) m32);
 
872
}
 
873
 
 
874
void or_reg32_m32abs(unsigned int reg32, unsigned int *m32)
 
875
{
 
876
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
877
   {
 
878
     printf("Error: destination %lx not in lower 2GB for or_reg32_m32abs()\n", (long) m32);
 
879
     asm(" int $3; ");
 
880
   }
 
881
   put8(0x0B);
 
882
   put8((reg32 << 3) | 4);
 
883
   put8(0x25);
 
884
   put32((int) (unsigned long) m32);
 
885
}
 
886
 
 
887
void or_reg32_reg32(unsigned int reg1, unsigned int reg2)
 
888
{
 
889
   put8(0x09);
 
890
   put8(0xC0 | (reg2 << 3) | reg1);
 
891
}
 
892
 
 
893
void or_reg64_reg64(unsigned int reg1, unsigned int reg2)
 
894
{
 
895
   put8(0x48);
 
896
   put8(0x09);
 
897
   put8(0xC0 | (reg2 << 3) | reg1);
 
898
}
 
899
 
 
900
void and_reg32_reg32(unsigned int reg1, unsigned int reg2)
 
901
{
 
902
   put8(0x21);
 
903
   put8(0xC0 | (reg2 << 3) | reg1);
 
904
}
 
905
 
 
906
void and_reg64_reg64(unsigned int reg1, unsigned int reg2)
 
907
{
 
908
   put8(0x48);
 
909
   put8(0x21);
 
910
   put8(0xC0 | (reg2 << 3) | reg1);
 
911
}
 
912
 
 
913
void and_m32abs_imm32(unsigned int *m32, unsigned int imm32)
 
914
{
 
915
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
916
   {
 
917
     printf("Error: destination %lx not in lower 2GB for and_m32abs_imm32()\n", (long) m32);
 
918
     asm(" int $3; ");
 
919
   }
 
920
   put8(0x81);
 
921
   put8(0x24);
 
922
   put8(0x25);
 
923
   put32((int) (unsigned long) m32);
 
924
   put32(imm32);
 
925
}
 
926
 
 
927
void and_reg32_m32abs(unsigned int reg32, unsigned int *m32)
 
928
{
 
929
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
930
   {
 
931
     printf("Error: destination %lx not in lower 2GB for and_reg32_m32abs()\n", (long) m32);
 
932
     asm(" int $3; ");
 
933
   }
 
934
   put8(0x23);
 
935
   put8((reg32 << 3) | 4);
 
936
   put8(0x25);
 
937
   put32((int) (unsigned long) m32);
 
938
}
 
939
 
 
940
void xor_reg32_reg32(unsigned int reg1, unsigned int reg2)
 
941
{
 
942
   put8(0x31);
 
943
   put8(0xC0 | (reg2 << 3) | reg1);
 
944
}
 
945
 
 
946
void xor_reg64_reg64(unsigned int reg1, unsigned int reg2)
 
947
{
 
948
   put8(0x48);
 
949
   put8(0x31);
 
950
   put8(0xC0 | (reg2 << 3) | reg1);
 
951
}
 
952
 
 
953
void xor_reg32_m32abs(unsigned int reg32, unsigned int *m32)
 
954
{
 
955
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
956
   {
 
957
     printf("Error: destination %lx not in lower 2GB for xor_reg32_m32abs()\n", (long) m32);
 
958
     asm(" int $3; ");
 
959
   }
 
960
   put8(0x33);
 
961
   put8((reg32 << 3) | 4);
 
962
   put8(0x25);
 
963
   put32((int) (unsigned long) m32);
 
964
}
 
965
 
 
966
void add_m32abs_imm32(unsigned int *m32, unsigned int imm32)
 
967
{
 
968
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
969
   {
 
970
     printf("Error: destination %lx not in lower 2GB for add_m32abs_imm32()\n", (long) m32);
 
971
     asm(" int $3; ");
 
972
   }
 
973
   put8(0x81);
 
974
   put8(0x04);
 
975
   put8(0x25);
 
976
   put32((int) (unsigned long) m32);
 
977
   put32(imm32);
 
978
}
 
979
 
 
980
void add_m32abs_imm8(unsigned int *m32, unsigned char imm8)
 
981
{
 
982
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
983
   {
 
984
     printf("Error: destination %lx not in lower 2GB for add_m32abs_imm8()\n", (long) m32);
 
985
     asm(" int $3; ");
 
986
   }
 
987
   put8(0x83);
 
988
   put8(0x04);
 
989
   put8(0x25);
 
990
   put32((int) (unsigned long) m32);
 
991
   put8(imm8);
 
992
}
 
993
 
 
994
void sub_m32abs_imm32(unsigned int *m32, unsigned int imm32)
 
995
{
 
996
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
997
   {
 
998
     printf("Error: destination %lx not in lower 2GB for sub_m32abs_imm32()\n", (long) m32);
 
999
     asm(" int $3; ");
 
1000
   }
 
1001
   put8(0x81);
 
1002
   put8(0x2C);
 
1003
   put8(0x25);
 
1004
   put32((int) (unsigned long) m32);
 
1005
   put32(imm32);
 
1006
}
 
1007
 
 
1008
void sub_m64abs_imm32(unsigned long long *m64, unsigned int imm32)
 
1009
{
 
1010
   if ((long) m64 & 0xFFFFFFFF80000000LL)
 
1011
   {
 
1012
     printf("Error: destination %lx not in lower 2GB for sub_m64abs_imm32()\n", (long) m64);
 
1013
     asm(" int $3; ");
 
1014
   }
 
1015
   put8(0x48);
 
1016
   put8(0x81);
 
1017
   put8(0x2C);
 
1018
   put8(0x25);
 
1019
   put32((int) (unsigned long) m64);
 
1020
   put32(imm32);
 
1021
}
 
1022
 
 
1023
void add_reg32_imm8(unsigned int reg32, unsigned char imm8)
 
1024
{
 
1025
   put8(0x83);
 
1026
   put8(0xC0+reg32);
 
1027
   put8(imm8);
 
1028
}
 
1029
 
 
1030
void add_reg64_imm32(unsigned int reg64, unsigned int imm32)
 
1031
{
 
1032
   put8(0x48);
 
1033
   put8(0x81);
 
1034
   put8(0xC0+reg64);
 
1035
   put32(imm32);
 
1036
}
 
1037
 
 
1038
void add_reg32_imm32(unsigned int reg32, unsigned int imm32)
 
1039
{
 
1040
   put8(0x81);
 
1041
   put8(0xC0+reg32);
 
1042
   put32(imm32);
 
1043
}
 
1044
 
 
1045
void inc_m32abs(unsigned int *m32)
 
1046
{
 
1047
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1048
   {
 
1049
     printf("Error: destination %lx not in lower 2GB for inc_m32abs()\n", (long) m32);
 
1050
     asm(" int $3; ");
 
1051
   }
 
1052
   put8(0xFF);
 
1053
   put8(0x04);
 
1054
   put8(0x25);
 
1055
   put32((int) (unsigned long) m32);
 
1056
}
 
1057
 
 
1058
void cmp_m32abs_imm32(unsigned int *m32, unsigned int imm32)
 
1059
{
 
1060
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1061
   {
 
1062
     printf("Error: destination %lx not in lower 2GB for cmp_m32abs_imm32()\n", (long) m32);
 
1063
     asm(" int $3; ");
 
1064
   }
 
1065
   put8(0x81);
 
1066
   put8(0x3C);
 
1067
   put8(0x25);
 
1068
   put32((int) (unsigned long) m32);
 
1069
   put32(imm32);
 
1070
}
 
1071
 
 
1072
void cmp_m32abs_imm8(unsigned int *m32, unsigned char imm8)
 
1073
{
 
1074
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1075
   {
 
1076
     printf("Error: destination %lx not in lower 2GB for cmp_m32_imm8()\n", (long) m32);
 
1077
     asm(" int $3; ");
 
1078
   }
 
1079
   put8(0x83);
 
1080
   put8(0x3C);
 
1081
   put8(0x25);
 
1082
   put32((int) (unsigned long) m32);
 
1083
   put8(imm8);
 
1084
}
 
1085
 
 
1086
void cmp_m8abs_imm8(unsigned char *m8, unsigned char imm8)
 
1087
{
 
1088
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
1089
   {
 
1090
     printf("Error: destination %lx not in lower 2GB for cmp_m8abs_imm8()\n", (long) m8);
 
1091
     asm(" int $3; ");
 
1092
   }
 
1093
   put8(0x80);
 
1094
   put8(0x3C);
 
1095
   put8(0x25);
 
1096
   put32((int) (unsigned long) m8);
 
1097
   put8(imm8);
 
1098
}
 
1099
 
 
1100
void cmp_eax_imm32(unsigned int imm32)
 
1101
{
 
1102
   put8(0x3D);
 
1103
   put32(imm32);
 
1104
}
 
1105
 
 
1106
void mov_m32abs_imm32(unsigned int *m32, unsigned int imm32)
 
1107
{
 
1108
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1109
   {
 
1110
     printf("Error: destination %lx not in lower 2GB for mov_m32abs_imm32()\n", (long) m32);
 
1111
     asm(" int $3; ");
 
1112
   }
 
1113
   put8(0xC7);
 
1114
   put8(0x04);
 
1115
   put8(0x25);
 
1116
   put32((int) (unsigned long) m32);
 
1117
   put32(imm32);
 
1118
}
 
1119
 
 
1120
void jmp(unsigned int mi_addr)
 
1121
{
 
1122
   put8(0xFF);
 
1123
   put8(0x25);
 
1124
   put32(0);
 
1125
   put64(0);
 
1126
   add_jump(code_length-8, mi_addr, 1);
 
1127
}
 
1128
 
 
1129
void cdq(void)
 
1130
{
 
1131
   put8(0x99);
 
1132
}
 
1133
 
 
1134
void cwde(void)
 
1135
{
 
1136
   put8(0x98);
 
1137
}
 
1138
 
 
1139
void cbw(void)
 
1140
{
 
1141
   put8(0x66);
 
1142
   put8(0x98);
 
1143
}
 
1144
 
 
1145
void ret(void)
 
1146
{
 
1147
   put8(0xC3);
 
1148
}
 
1149
 
 
1150
void call_reg64(unsigned int reg64)
 
1151
{
 
1152
   put8(0xFF);
 
1153
   put8(0xD0+reg64);
 
1154
}
 
1155
 
 
1156
void call_m64abs(unsigned long long *m64)
 
1157
{
 
1158
   if ((long) m64 & 0xFFFFFFFF80000000LL)
 
1159
   {
 
1160
     printf("Error: destination %lx not in lower 2GB for call_m64abs()\n", (long) m64);
 
1161
     asm(" int $3; ");
 
1162
   }
 
1163
   put8(0xFF);
 
1164
   put8(0x14);
 
1165
   put8(0x25);
 
1166
   put32((int) (unsigned long) m64);
 
1167
}
 
1168
 
 
1169
void shr_reg64_imm8(unsigned int reg64, unsigned char imm8)
 
1170
{
 
1171
   put8(0x48);
 
1172
   put8(0xC1);
 
1173
   put8(0xE8+reg64);
 
1174
   put8(imm8);
 
1175
}
 
1176
 
 
1177
void shr_reg32_imm8(unsigned int reg32, unsigned char imm8)
 
1178
{
 
1179
   put8(0xC1);
 
1180
   put8(0xE8+reg32);
 
1181
   put8(imm8);
 
1182
}
 
1183
 
 
1184
void shr_reg32_cl(unsigned int reg32)
 
1185
{
 
1186
   put8(0xD3);
 
1187
   put8(0xE8+reg32);
 
1188
}
 
1189
 
 
1190
void shr_reg64_cl(unsigned int reg64)
 
1191
{
 
1192
   put8(0x48);
 
1193
   put8(0xD3);
 
1194
   put8(0xE8+reg64);
 
1195
}
 
1196
 
 
1197
void sar_reg32_cl(unsigned int reg32)
 
1198
{
 
1199
   put8(0xD3);
 
1200
   put8(0xF8+reg32);
 
1201
}
 
1202
 
 
1203
void sar_reg64_cl(unsigned int reg64)
 
1204
{
 
1205
   put8(0x48);
 
1206
   put8(0xD3);
 
1207
   put8(0xF8+reg64);
 
1208
}
 
1209
 
 
1210
void shl_reg32_cl(unsigned int reg32)
 
1211
{
 
1212
   put8(0xD3);
 
1213
   put8(0xE0+reg32);
 
1214
}
 
1215
 
 
1216
void shl_reg64_cl(unsigned int reg64)
 
1217
{
 
1218
   put8(0x48);
 
1219
   put8(0xD3);
 
1220
   put8(0xE0+reg64);
 
1221
}
 
1222
 
 
1223
void shld_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
 
1224
{
 
1225
   put8(0x0F);
 
1226
   put8(0xA5);
 
1227
   put8(0xC0 | (reg2 << 3) | reg1);
 
1228
}
 
1229
 
 
1230
void shld_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
 
1231
{
 
1232
   put8(0x0F);
 
1233
   put8(0xA4);
 
1234
   put8(0xC0 | (reg2 << 3) | reg1);
 
1235
   put8(imm8);
 
1236
}
 
1237
 
 
1238
void shrd_reg32_reg32_cl(unsigned int reg1, unsigned int reg2)
 
1239
{
 
1240
   put8(0x0F);
 
1241
   put8(0xAD);
 
1242
   put8(0xC0 | (reg2 << 3) | reg1);
 
1243
}
 
1244
 
 
1245
void sar_reg32_imm8(unsigned int reg32, unsigned char imm8)
 
1246
{
 
1247
   put8(0xC1);
 
1248
   put8(0xF8+reg32);
 
1249
   put8(imm8);
 
1250
}
 
1251
 
 
1252
void sar_reg64_imm8(unsigned int reg64, unsigned char imm8)
 
1253
{
 
1254
   put8(0x48);
 
1255
   put8(0xC1);
 
1256
   put8(0xF8+reg64);
 
1257
   put8(imm8);
 
1258
}
 
1259
 
 
1260
void shrd_reg32_reg32_imm8(unsigned int reg1, unsigned int reg2, unsigned char imm8)
 
1261
{
 
1262
   put8(0x0F);
 
1263
   put8(0xAC);
 
1264
   put8(0xC0 | (reg2 << 3) | reg1);
 
1265
   put8(imm8);
 
1266
}
 
1267
 
 
1268
void mul_m32abs(unsigned int *m32)
 
1269
{
 
1270
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1271
   {
 
1272
     printf("Error: destination %lx not in lower 2GB for mul_m32abs()\n", (long) m32);
 
1273
     asm(" int $3; ");
 
1274
   }
 
1275
   put8(0xF7);
 
1276
   put8(0x24);
 
1277
   put8(0x25);
 
1278
   put32((int) (unsigned long) m32);
 
1279
}
 
1280
 
 
1281
void imul_reg32(unsigned int reg32)
 
1282
{
 
1283
   put8(0xF7);
 
1284
   put8(0xE8+reg32);
 
1285
}
 
1286
 
 
1287
void mul_reg64(unsigned int reg64)
 
1288
{
 
1289
   put8(0x48);
 
1290
   put8(0xF7);
 
1291
   put8(0xE0+reg64);
 
1292
}
 
1293
 
 
1294
void mul_reg32(unsigned int reg32)
 
1295
{
 
1296
   put8(0xF7);
 
1297
   put8(0xE0+reg32);
 
1298
}
 
1299
 
 
1300
void idiv_reg32(unsigned int reg32)
 
1301
{
 
1302
   put8(0xF7);
 
1303
   put8(0xF8+reg32);
 
1304
}
 
1305
 
 
1306
void div_reg32(unsigned int reg32)
 
1307
{
 
1308
   put8(0xF7);
 
1309
   put8(0xF0+reg32);
 
1310
}
 
1311
 
 
1312
void idiv_m32abs(unsigned int *m32)
 
1313
{
 
1314
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1315
   {
 
1316
     printf("Error: destination %lx not in lower 2GB for idiv_m32abs()\n", (long) m32);
 
1317
     asm(" int $3; ");
 
1318
   }
 
1319
   put8(0xF7);
 
1320
   put8(0x3C);
 
1321
   put8(0x25);
 
1322
   put32((int) (unsigned long) m32);
 
1323
}
 
1324
 
 
1325
void div_m32abs(unsigned int *m32)
 
1326
{
 
1327
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1328
   {
 
1329
     printf("Error: destination %lx not in lower 2GB for div_m32abs()\n", (long) m32);
 
1330
     asm(" int $3; ");
 
1331
   }
 
1332
   put8(0xF7);
 
1333
   put8(0x34);
 
1334
   put8(0x25);
 
1335
   put32((int) (unsigned long) m32);
 
1336
}
 
1337
 
 
1338
void add_reg32_reg32(unsigned int reg1, unsigned int reg2)
 
1339
{
 
1340
   put8(0x01);
 
1341
   put8(0xC0 | (reg2 << 3) | reg1);
 
1342
}
 
1343
 
 
1344
void add_reg64_reg64(unsigned int reg1, unsigned int reg2)
 
1345
{
 
1346
   put8(0x48);
 
1347
   put8(0x01);
 
1348
   put8(0xC0 | (reg2 << 3) | reg1);
 
1349
}
 
1350
 
 
1351
void add_reg32_m32abs(unsigned int reg32, unsigned int *m32)
 
1352
{
 
1353
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1354
   {
 
1355
     printf("Error: destination %lx not in lower 2GB for add_reg32_m32abs()\n", (long) m32);
 
1356
     asm(" int $3; ");
 
1357
   }
 
1358
   put8(0x03);
 
1359
   put8((reg32 << 3) | 4);
 
1360
   put8(0x25);
 
1361
   put32((int) (unsigned long) m32);
 
1362
}
 
1363
 
 
1364
void add_reg64_m64abs(unsigned int reg64, unsigned long long *m64)
 
1365
{
 
1366
   if ((long) m64 & 0xFFFFFFFF80000000LL)
 
1367
   {
 
1368
     printf("Error: destination %lx not in lower 2GB for add_reg64_m64abs()\n", (long) m64);
 
1369
     asm(" int $3; ");
 
1370
   }
 
1371
   put8(0x48);
 
1372
   put8(0x03);
 
1373
   put8((reg64 << 3) | 4);
 
1374
   put8(0x25);
 
1375
   put32((int) (unsigned long) m64);
 
1376
}
 
1377
 
 
1378
void adc_reg32_reg32(unsigned int reg1, unsigned int reg2)
 
1379
{
 
1380
   put8(0x11);
 
1381
   put8(0xC0 | (reg2 << 3) | reg1);
 
1382
}
 
1383
 
 
1384
void adc_reg32_m32abs(unsigned int reg32, unsigned int *m32)
 
1385
{
 
1386
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1387
   {
 
1388
     printf("Error: destination %lx not in lower 2GB for adc_reg32_m32abs()\n", (long) m32);
 
1389
     asm(" int $3; ");
 
1390
   }
 
1391
   put8(0x13);
 
1392
   put8((reg32 << 3) | 4);
 
1393
   put8(0x25);
 
1394
   put32((int) (unsigned long) m32);
 
1395
}
 
1396
 
 
1397
void adc_reg32_imm32(unsigned int reg32, unsigned int imm32)
 
1398
{
 
1399
   put8(0x81);
 
1400
   put8(0xD0 + reg32);
 
1401
   put32(imm32);
 
1402
}
 
1403
 
 
1404
void jmp_reg64(unsigned int reg64)
 
1405
{
 
1406
   put8(0xFF);
 
1407
   put8(0xE0 + reg64);
 
1408
}
 
1409
 
 
1410
void jmp_m64abs(unsigned long long *m64)
 
1411
{
 
1412
   if ((long) m64 & 0xFFFFFFFF80000000LL)
 
1413
   {
 
1414
     printf("Error: destination %lx not in lower 2GB for jmp_m64abs()\n", (long) m64);
 
1415
     asm(" int $3; ");
 
1416
   }
 
1417
   put8(0xFF);
 
1418
   put8(0x24);
 
1419
   put8(0x25);
 
1420
   put32((int) (unsigned long) m64);
 
1421
}
 
1422
 
 
1423
void mov_reg32_preg64(unsigned int reg1, unsigned int reg2)
 
1424
{
 
1425
   put8(0x8B);
 
1426
   put8((reg1 << 3) | reg2);
 
1427
}
 
1428
 
 
1429
void mov_preg64_reg32(int reg1, int reg2)
 
1430
{
 
1431
   put8(0x89);
 
1432
   put8((reg2 << 3) | reg1);
 
1433
}
 
1434
 
 
1435
void mov_preg64_reg64(int reg1, int reg2)
 
1436
{
 
1437
   put8(0x48);
 
1438
   put8(0x89);
 
1439
   put8((reg2 << 3) | reg1);
 
1440
}
 
1441
 
 
1442
void mov_reg64_preg64(int reg1, int reg2)
 
1443
{
 
1444
   put8(0x48);
 
1445
   put8(0x8B);
 
1446
   put8((reg1 << 3) | reg2);
 
1447
}
 
1448
 
 
1449
void mov_reg32_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
 
1450
{
 
1451
   put8(0x8B);
 
1452
   put8((reg1 << 3) | 0x84);
 
1453
   put8(reg2 | (reg3 << 3));
 
1454
   put32(imm32);
 
1455
}
 
1456
 
 
1457
void mov_preg64preg64pimm32_reg32(int reg1, int reg2, unsigned int imm32, int reg3)
 
1458
{
 
1459
   put8(0x89);
 
1460
   put8((reg3 << 3) | 0x84);
 
1461
   put8(reg1 | (reg2 << 3));
 
1462
   put32(imm32);
 
1463
}
 
1464
 
 
1465
void mov_reg64_preg64preg64pimm32(int reg1, int reg2, int reg3, unsigned int imm32)
 
1466
{
 
1467
   put8(0x48);
 
1468
   put8(0x8B);
 
1469
   put8((reg1 << 3) | 0x84);
 
1470
   put8(reg2 | (reg3 << 3));
 
1471
   put32(imm32);
 
1472
}
 
1473
 
 
1474
void mov_reg32_preg64preg64(int reg1, int reg2, int reg3)
 
1475
{
 
1476
   put8(0x8B);
 
1477
   put8((reg1 << 3) | 0x04);
 
1478
   put8((reg2 << 3) | reg3);
 
1479
}
 
1480
 
 
1481
void mov_reg64_preg64preg64(int reg1, int reg2, int reg3)
 
1482
{
 
1483
   put8(0x48);
 
1484
   put8(0x8B);
 
1485
   put8((reg1 << 3) | 0x04);
 
1486
   put8(reg2 | (reg3 << 3));
 
1487
}
 
1488
 
 
1489
void mov_reg32_preg64pimm32(int reg1, int reg2, unsigned int imm32)
 
1490
{
 
1491
   put8(0x8B);
 
1492
   put8(0x80 | (reg1 << 3) | reg2);
 
1493
   put32(imm32);
 
1494
}
 
1495
 
 
1496
void mov_reg64_preg64pimm32(int reg1, int reg2, unsigned int imm32)
 
1497
{
 
1498
   put8(0x48);
 
1499
   put8(0x8B);
 
1500
   put8(0x80 | (reg1 << 3) | reg2);
 
1501
   put32(imm32);
 
1502
}
 
1503
 
 
1504
void mov_reg64_preg64pimm8(int reg1, int reg2, unsigned int imm8)
 
1505
{
 
1506
   put8(0x48);
 
1507
   put8(0x8B);
 
1508
   put8(0x40 | (reg1 << 3) | reg2);
 
1509
   put8(imm8);
 
1510
}
 
1511
 
 
1512
void mov_reg32_preg64x4pimm32(int reg1, int reg2, unsigned int imm32)
 
1513
{
 
1514
   put8(0x8B);
 
1515
   put8((reg1 << 3) | 4);
 
1516
   put8(0x80 | (reg2 << 3) | 5);
 
1517
   put32(imm32);
 
1518
}
 
1519
 
 
1520
void mov_reg64_preg64x8preg64(int reg1, int reg2, int reg3)
 
1521
{
 
1522
   put8(0x48);
 
1523
   put8(0x8B);
 
1524
   put8((reg1 << 3) | 4);
 
1525
   put8(0xC0 | (reg2 << 3) | reg3);
 
1526
}
 
1527
 
 
1528
void mov_preg64preg64_reg8(int reg1, int reg2, int reg8)
 
1529
{
 
1530
   put8(0x88);
 
1531
   put8(0x04 | (reg8 << 3));
 
1532
   put8((reg1 << 3) | reg2);
 
1533
}
 
1534
 
 
1535
void mov_preg64preg64_imm8(int reg1, int reg2, unsigned char imm8)
 
1536
{
 
1537
   put8(0xC6);
 
1538
   put8(0x04);
 
1539
   put8((reg1 << 3) | reg2);
 
1540
   put8(imm8);
 
1541
}
 
1542
 
 
1543
void mov_preg64pimm32_imm8(int reg64, unsigned int imm32, unsigned char imm8)
 
1544
{
 
1545
   put8(0xC6);
 
1546
   put8(0x80 + reg64);
 
1547
   put32(imm32);
 
1548
   put8(imm8);
 
1549
}
 
1550
 
 
1551
void mov_preg64pimm32_reg16(int reg64, unsigned int imm32, int reg16)
 
1552
{
 
1553
   put8(0x66);
 
1554
   put8(0x89);
 
1555
   put8(0x80 | reg64 | (reg16 << 3));
 
1556
   put32(imm32);
 
1557
}
 
1558
 
 
1559
void mov_preg64preg64_reg16(int reg1, int reg2, int reg16)
 
1560
{
 
1561
   put8(0x66);
 
1562
   put8(0x89);
 
1563
   put8(0x04 | (reg16 << 3));
 
1564
   put8((reg1 << 3) | reg2);
 
1565
}
 
1566
 
 
1567
void mov_preg64preg64_reg32(int reg1, int reg2, int reg32)
 
1568
{
 
1569
   put8(0x89);
 
1570
   put8(0x04 | (reg32 << 3));
 
1571
   put8((reg1 << 3) | reg2);
 
1572
}
 
1573
 
 
1574
void mov_preg64pimm32_reg32(int reg1, unsigned int imm32, int reg2)
 
1575
{
 
1576
   put8(0x89);
 
1577
   put8(0x80 | reg1 | (reg2 << 3));
 
1578
   put32(imm32);
 
1579
}
 
1580
 
 
1581
void mov_preg64pimm8_reg64(int reg1, unsigned int imm8, int reg2)
 
1582
{
 
1583
   put8(0x48);
 
1584
   put8(0x89);
 
1585
   put8(0x40 | (reg2 << 3) | reg1);
 
1586
   put8(imm8);
 
1587
}
 
1588
 
 
1589
void add_eax_imm32(unsigned int imm32)
 
1590
{
 
1591
   put8(0x05);
 
1592
   put32(imm32);
 
1593
}
 
1594
 
 
1595
void shl_reg32_imm8(unsigned int reg32, unsigned char imm8)
 
1596
{
 
1597
   put8(0xC1);
 
1598
   put8(0xE0 + reg32);
 
1599
   put8(imm8);
 
1600
}
 
1601
 
 
1602
void shl_reg64_imm8(unsigned int reg64, unsigned char imm8)
 
1603
{
 
1604
   put8(0x48);
 
1605
   put8(0xC1);
 
1606
   put8(0xE0 + reg64);
 
1607
   put8(imm8);
 
1608
}
 
1609
 
 
1610
void mov_reg32_reg32(unsigned int reg1, unsigned int reg2)
 
1611
{
 
1612
   if (reg1 == reg2) return;
 
1613
   put8(0x89);
 
1614
   put8(0xC0 | (reg2 << 3) | reg1);
 
1615
}
 
1616
 
 
1617
void mov_reg64_reg64(unsigned int reg1, unsigned int reg2)
 
1618
{
 
1619
   if (reg1 == reg2) return;
 
1620
   put8(0x48);
 
1621
   put8(0x89);
 
1622
   put8(0xC0 | (reg2 << 3) | reg1);
 
1623
}
 
1624
 
 
1625
void mov_reg32_m32abs(unsigned int reg32, unsigned int *m32)
 
1626
{
 
1627
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1628
   {
 
1629
     printf("Error: destination %lx not in lower 2GB for mov_reg32_m32abs()\n", (long) m32);
 
1630
     asm(" int $3; ");
 
1631
   }
 
1632
   put8(0x8B);
 
1633
   put8((reg32 << 3) | 4);
 
1634
   put8(0x25);
 
1635
   put32((int) (unsigned long) m32);
 
1636
}
 
1637
 
 
1638
void mov_m32abs_reg32(unsigned int *m32, unsigned int reg32)
 
1639
{
 
1640
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1641
   {
 
1642
     printf("Error: destination %lx not in lower 2GB for mov_m32abs_reg32()\n", (long) m32);
 
1643
     asm(" int $3; ");
 
1644
   }
 
1645
   put8(0x89);
 
1646
   put8((reg32 << 3) | 4);
 
1647
   put8(0x25);
 
1648
   put32((int) (unsigned long) m32);
 
1649
}
 
1650
 
 
1651
void mov_reg64_m64abs(unsigned int reg64, unsigned long long* m64)
 
1652
{
 
1653
   if ((long) m64 & 0xFFFFFFFF80000000LL)
 
1654
   {
 
1655
     printf("Error: destination %lx not in lower 2GB for mov_reg64_m64abs()\n", (long) m64);
 
1656
     asm(" int $3; ");
 
1657
   }
 
1658
   put8(0x48);
 
1659
   put8(0x8B);
 
1660
   put8((reg64 << 3) | 4);
 
1661
   put8(0x25);
 
1662
   put32((int) (unsigned long) m64);
 
1663
}
 
1664
 
 
1665
void mov_m64abs_reg64(unsigned long long *m64, unsigned int reg64)
 
1666
{
 
1667
   if ((long) m64 & 0xFFFFFFFF80000000LL)
 
1668
   {
 
1669
     printf("Error: destination %lx not in lower 2GB for mov_m64abs_reg64()\n", (long) m64);
 
1670
     asm(" int $3; ");
 
1671
   }
 
1672
   put8(0x48);
 
1673
   put8(0x89);
 
1674
   put8((reg64 << 3) | 4);
 
1675
   put8(0x25);
 
1676
   put32((int) (unsigned long) m64);
 
1677
}
 
1678
 
 
1679
void mov_reg8_m8abs(int reg8, unsigned char *m8)
 
1680
{
 
1681
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
1682
   {
 
1683
     printf("Error: destination %lx not in lower 2GB for mov_reg8_m8abs()\n", (long) m8);
 
1684
     asm(" int $3; ");
 
1685
   }
 
1686
   put8(0x8A);
 
1687
   put8((reg8 << 3) | 4);
 
1688
   put8(0x25);
 
1689
   put32((int) (unsigned long) m8);
 
1690
}
 
1691
 
 
1692
void and_eax_imm32(unsigned int imm32)
 
1693
{
 
1694
   put8(0x25);
 
1695
   put32(imm32);
 
1696
}
 
1697
 
 
1698
void or_reg32_imm32(int reg32, unsigned int imm32)
 
1699
{
 
1700
   put8(0x81);
 
1701
   put8(0xC8 + reg32);
 
1702
   put32(imm32);
 
1703
}
 
1704
 
 
1705
void or_reg64_imm32(int reg64, unsigned int imm32)
 
1706
{
 
1707
   put8(0x48);
 
1708
   put8(0x81);
 
1709
   put8(0xC8 + reg64);
 
1710
   put32(imm32);
 
1711
}
 
1712
 
 
1713
void and_reg32_imm32(int reg32, unsigned int imm32)
 
1714
{
 
1715
   put8(0x81);
 
1716
   put8(0xE0 + reg32);
 
1717
   put32(imm32);
 
1718
}
 
1719
 
 
1720
void and_reg64_imm32(int reg64, unsigned int imm32)
 
1721
{
 
1722
   put8(0x48);
 
1723
   put8(0x81);
 
1724
   put8(0xE0 + reg64);
 
1725
   put32(imm32);
 
1726
}
 
1727
 
 
1728
void and_reg32_imm8(int reg32, unsigned char imm8)
 
1729
{
 
1730
   put8(0x83);
 
1731
   put8(0xE0 + reg32);
 
1732
   put8(imm8);
 
1733
}
 
1734
 
 
1735
void and_reg64_imm8(int reg64, unsigned char imm8)
 
1736
{
 
1737
   put8(0x48);
 
1738
   put8(0x83);
 
1739
   put8(0xE0 + reg64);
 
1740
   put8(imm8);
 
1741
}
 
1742
 
 
1743
void and_ax_imm16(unsigned short imm16)
 
1744
{
 
1745
   put8(0x66);
 
1746
   put8(0x25);
 
1747
   put16(imm16);
 
1748
}
 
1749
 
 
1750
void and_al_imm8(unsigned char imm8)
 
1751
{
 
1752
   put8(0x24);
 
1753
   put8(imm8);
 
1754
}
 
1755
 
 
1756
void or_ax_imm16(unsigned short imm16)
 
1757
{
 
1758
   put8(0x66);
 
1759
   put8(0x0D);
 
1760
   put16(imm16);
 
1761
}
 
1762
 
 
1763
void or_eax_imm32(unsigned int imm32)
 
1764
{
 
1765
   put8(0x0D);
 
1766
   put32(imm32);
 
1767
}
 
1768
 
 
1769
void xor_ax_imm16(unsigned short imm16)
 
1770
{
 
1771
   put8(0x66);
 
1772
   put8(0x35);
 
1773
   put16(imm16);
 
1774
}
 
1775
 
 
1776
void xor_al_imm8(unsigned char imm8)
 
1777
{
 
1778
   put8(0x34);
 
1779
   put8(imm8);
 
1780
}
 
1781
 
 
1782
void xor_reg64_imm32(int reg64, unsigned int imm32)
 
1783
{
 
1784
   put8(0x48);
 
1785
   put8(0x81);
 
1786
   put8(0xF0 + reg64);
 
1787
   put32(imm32);
 
1788
}
 
1789
 
 
1790
void xor_reg32_imm32(int reg32, unsigned int imm32)
 
1791
{
 
1792
   put8(0x81);
 
1793
   put8(0xF0 + reg32);
 
1794
   put32(imm32);
 
1795
}
 
1796
 
 
1797
void xor_reg8_imm8(int reg8, unsigned char imm8)
 
1798
{
 
1799
   put8(0x40);  /* we need an REX prefix to use the uniform byte registers */
 
1800
   put8(0x80);
 
1801
   put8(0xF0 + reg8);
 
1802
   put8(imm8);
 
1803
}
 
1804
 
 
1805
void nop(void)
 
1806
{
 
1807
   put8(0x90);
 
1808
}
 
1809
 
 
1810
void not_reg32(unsigned int reg32)
 
1811
{
 
1812
   put8(0xF7);
 
1813
   put8(0xD0 + reg32);
 
1814
}
 
1815
 
 
1816
void not_reg64(unsigned int reg64)
 
1817
{
 
1818
   put8(0x48);
 
1819
   put8(0xF7);
 
1820
   put8(0xD0 + reg64);
 
1821
}
 
1822
 
 
1823
void neg_reg32(unsigned int reg32)
 
1824
{
 
1825
   put8(0xF7);
 
1826
   put8(0xD8 + reg32);
 
1827
}
 
1828
 
 
1829
void neg_reg64(unsigned int reg64)
 
1830
{
 
1831
   put8(0x48);
 
1832
   put8(0xF7);
 
1833
   put8(0xD8 + reg64);
 
1834
}
 
1835
 
 
1836
void movsx_reg32_m8abs(int reg32, unsigned char *m8)
 
1837
{
 
1838
   if ((long) m8 & 0xFFFFFFFF80000000LL)
 
1839
   {
 
1840
     printf("Error: destination %lx not in lower 2GB for movsx_reg32_m8abs()\n", (long) m8);
 
1841
     asm(" int $3; ");
 
1842
   }
 
1843
   put8(0x0F);
 
1844
   put8(0xBE);
 
1845
   put8((reg32 << 3) | 4);
 
1846
   put8(0x25);
 
1847
   put32((int) (unsigned long) m8);
 
1848
}
 
1849
 
 
1850
void movsx_reg32_8preg64pimm32(int reg1, int reg2, unsigned int imm32)
 
1851
{
 
1852
   put8(0x0F);
 
1853
   put8(0xBE);
 
1854
   put8((reg1 << 3) | reg2 | 0x80);
 
1855
   put32(imm32);
 
1856
}
 
1857
 
 
1858
void movsx_reg32_8preg64preg64(int reg1, int reg2, int reg3)
 
1859
{
 
1860
   put8(0x0F);
 
1861
   put8(0xBE);
 
1862
   put8((reg1 << 3) | 0x04);
 
1863
   put8((reg2 << 3) | reg3);
 
1864
}
 
1865
 
 
1866
void movsx_reg32_16preg64pimm32(int reg1, int reg2, unsigned int imm32)
 
1867
{
 
1868
   put8(0x0F);
 
1869
   put8(0xBF);
 
1870
   put8((reg1 << 3) | reg2 | 0x80);
 
1871
   put32(imm32);
 
1872
}
 
1873
 
 
1874
void movsx_reg32_16preg64preg64(int reg1, int reg2, int reg3)
 
1875
{
 
1876
   put8(0x0F);
 
1877
   put8(0xBF);
 
1878
   put8((reg1 << 3) | 0x04);
 
1879
   put8((reg2 << 3) | reg3);
 
1880
}
 
1881
 
 
1882
void movsx_reg32_reg16(int reg32, int reg16)
 
1883
{
 
1884
   put8(0x0F);
 
1885
   put8(0xBF);
 
1886
   put8((reg32 << 3) | reg16 | 0xC0);
 
1887
}
 
1888
 
 
1889
void movsx_reg32_m16abs(int reg32, unsigned short *m16)
 
1890
{
 
1891
   if ((long) m16 & 0xFFFFFFFF80000000LL)
 
1892
   {
 
1893
     printf("Error: destination %lx not in lower 2GB for movsx_reg32_m16abs()\n", (long) m16);
 
1894
     asm(" int $3; ");
 
1895
   }
 
1896
   put8(0x0F);
 
1897
   put8(0xBF);
 
1898
   put8((reg32 << 3) | 4);
 
1899
   put8(0x25);
 
1900
   put32((int) (unsigned long) m16);
 
1901
}
 
1902
 
 
1903
void movsxd_reg64_reg32(int reg64, int reg32)
 
1904
{
 
1905
   put8(0x48);
 
1906
   put8(0x63);
 
1907
   put8((reg64 << 3) | reg32 | 0xC0);
 
1908
}
 
1909
 
 
1910
void movsxd_reg64_m32abs(int reg64, unsigned int *m32)
 
1911
{
 
1912
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
1913
   {
 
1914
     printf("Error: destination %lx not in lower 2GB for movsxd_reg64_m32abs()\n", (long) m32);
 
1915
     asm(" int $3; ");
 
1916
   }
 
1917
   put8(0x48);
 
1918
   put8(0x63);
 
1919
   put8((reg64 << 3) | 0x04);
 
1920
   put8(0x25);
 
1921
   put32((int) (unsigned long) m32);
 
1922
}
 
1923
 
 
1924
void fldcw_m16abs(unsigned short *m16)
 
1925
{
 
1926
   if ((long) m16 & 0xFFFFFFFF80000000LL)
 
1927
   {
 
1928
     printf("Error: destination %lx not in lower 2GB for fldcw_m16abs()\n", (long) m16);
 
1929
     asm(" int $3; ");
 
1930
   }
 
1931
   put8(0xD9);
 
1932
   put8(0x2C);
 
1933
   put8(0x25);
 
1934
   put32((int) (unsigned long) m16);
 
1935
}
 
1936
 
 
1937
void fld_preg64_dword(int reg64)
 
1938
{
 
1939
   put8(0xD9);
 
1940
   put8(reg64);
 
1941
}
 
1942
 
 
1943
void fdiv_preg64_dword(int reg64)
 
1944
{
 
1945
   put8(0xD8);
 
1946
   put8(0x30 + reg64);
 
1947
}
 
1948
 
 
1949
void fstp_preg64_dword(int reg64)
 
1950
{
 
1951
   put8(0xD9);
 
1952
   put8(0x18 + reg64);
 
1953
}
 
1954
 
 
1955
void fchs(void)
 
1956
{
 
1957
   put8(0xD9);
 
1958
   put8(0xE0);
 
1959
}
 
1960
 
 
1961
void fstp_preg64_qword(int reg64)
 
1962
{
 
1963
   put8(0xDD);
 
1964
   put8(0x18 + reg64);
 
1965
}
 
1966
 
 
1967
void fadd_preg64_dword(int reg64)
 
1968
{
 
1969
   put8(0xD8);
 
1970
   put8(reg64);
 
1971
}
 
1972
 
 
1973
void fsub_preg64_dword(int reg64)
 
1974
{
 
1975
   put8(0xD8);
 
1976
   put8(0x20 + reg64);
 
1977
}
 
1978
 
 
1979
void fmul_preg64_dword(int reg64)
 
1980
{
 
1981
   put8(0xD8);
 
1982
   put8(0x08 + reg64);
 
1983
}
 
1984
 
 
1985
void fcomp_preg64_dword(int reg64)
 
1986
{
 
1987
   put8(0xD8);
 
1988
   put8(0x18 + reg64);
 
1989
}
 
1990
 
 
1991
void fistp_preg64_dword(int reg64)
 
1992
{
 
1993
   put8(0xDB);
 
1994
   put8(0x18 + reg64);
 
1995
}
 
1996
 
 
1997
void fistp_m32abs(unsigned int *m32)
 
1998
{
 
1999
   if ((long) m32 & 0xFFFFFFFF80000000LL)
 
2000
   {
 
2001
     printf("Error: destination %lx not in lower 2GB for fistp_m32abs()\n", (long) m32);
 
2002
     asm(" int $3; ");
 
2003
   }
 
2004
   put8(0xDB);
 
2005
   put8(0x1C);
 
2006
   put8(0x25);
 
2007
   put32((int) (unsigned long) m32);
 
2008
}
 
2009
 
 
2010
void fistp_preg64_qword(int reg64)
 
2011
{
 
2012
   put8(0xDF);
 
2013
   put8(0x38 + reg64);
 
2014
}
 
2015
 
 
2016
void fistp_m64abs(unsigned long long *m64)
 
2017
{
 
2018
   if ((long) m64 & 0xFFFFFFFF80000000LL)
 
2019
   {
 
2020
     printf("Error: destination %lx not in lower 2GB for fistp_m64abs()\n", (long) m64);
 
2021
     asm(" int $3; ");
 
2022
   }
 
2023
   put8(0xDF);
 
2024
   put8(0x3C);
 
2025
   put8(0x25);
 
2026
   put32((int) (unsigned long) m64);
 
2027
}
 
2028
 
 
2029
void fld_preg64_qword(int reg64)
 
2030
{
 
2031
   put8(0xDD);
 
2032
   put8(reg64);
 
2033
}
 
2034
 
 
2035
void fild_preg64_qword(int reg64)
 
2036
{
 
2037
   put8(0xDF);
 
2038
   put8(0x28+reg64);
 
2039
}
 
2040
 
 
2041
void fild_preg64_dword(int reg64)
 
2042
{
 
2043
   put8(0xDB);
 
2044
   put8(reg64);
 
2045
}
 
2046
 
 
2047
void fadd_preg64_qword(int reg64)
 
2048
{
 
2049
   put8(0xDC);
 
2050
   put8(reg64);
 
2051
}
 
2052
 
 
2053
void fdiv_preg64_qword(int reg64)
 
2054
{
 
2055
   put8(0xDC);
 
2056
   put8(0x30 + reg64);
 
2057
}
 
2058
 
 
2059
void fsub_preg64_qword(int reg64)
 
2060
{
 
2061
   put8(0xDC);
 
2062
   put8(0x20 + reg64);
 
2063
}
 
2064
 
 
2065
void fmul_preg64_qword(int reg64)
 
2066
{
 
2067
   put8(0xDC);
 
2068
   put8(0x08 + reg64);
 
2069
}
 
2070
 
 
2071
void fsqrt(void)
 
2072
{
 
2073
   put8(0xD9);
 
2074
   put8(0xFA);
 
2075
}
 
2076
 
 
2077
void fabs_(void)
 
2078
{
 
2079
   put8(0xD9);
 
2080
   put8(0xE1);
 
2081
}
 
2082
 
 
2083
void fcomip_fpreg(int fpreg)
 
2084
{
 
2085
   put8(0xDF);
 
2086
   put8(0xF0 + fpreg);
 
2087
}
 
2088
 
 
2089
void fucomip_fpreg(int fpreg)
 
2090
{
 
2091
   put8(0xDF);
 
2092
   put8(0xE8 + fpreg);
 
2093
}
 
2094
 
 
2095
void ffree_fpreg(int fpreg)
 
2096
{
 
2097
   put8(0xDD);
 
2098
   put8(0xC0 + fpreg);
 
2099
}
 
2100