comparison gen_x86.c @ 567:8e395210f50f

Refactor gen_x86 to use an interface more like gen_arm and to remove the need for the caller to decide whether an 8-bit or 32-bit displacement is needed in the rdisp functions. Update m68k_to_x86 to use the new version of the gen_x86 functions and do some minor refactoring there in the process
author Michael Pavone <pavone@retrodev.com>
date Sun, 02 Mar 2014 14:45:36 -0800
parents 96489fb27dbf
children 5ef3fe516da9
comparison
equal deleted inserted replaced
566:624dd5106060 567:8e395210f50f
2 Copyright 2013 Michael Pavone 2 Copyright 2013 Michael Pavone
3 This file is part of BlastEm. 3 This file is part of BlastEm.
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. 4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text.
5 */ 5 */
6 #include "gen_x86.h" 6 #include "gen_x86.h"
7 #include "68kinst.h" 7 #include "mem.h"
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <stdlib.h> 10 #include <stdlib.h>
11 11
12 #define REX_RM_FIELD 0x1 12 #define REX_RM_FIELD 0x1
125 X86_R13, 125 X86_R13,
126 X86_R14, 126 X86_R14,
127 X86_R15 127 X86_R15
128 } x86_regs_enc; 128 } x86_regs_enc;
129 129
130 uint8_t * x86_rr_sizedir(uint8_t * out, uint16_t opcode, uint8_t src, uint8_t dst, uint8_t size) 130 void jmp_nocheck(code_info *code, code_ptr dest)
131 { 131 {
132 code_ptr out = code->cur;
133 ptrdiff_t disp = dest-(out+2);
134 if (disp <= 0x7F && disp >= -0x80) {
135 *(out++) = OP_JMP_BYTE;
136 *(out++) = disp;
137 } else {
138 disp = dest-(out+5);
139 if (disp <= 0x7FFFFFFF && disp >= -2147483648) {
140 *(out++) = OP_JMP;
141 *(out++) = disp;
142 disp >>= 8;
143 *(out++) = disp;
144 disp >>= 8;
145 *(out++) = disp;
146 disp >>= 8;
147 *(out++) = disp;
148 } else {
149 fprintf(stderr, "jmp: %p - %p = %lX\n", dest, out + 6, (long)disp);
150 exit(1);
151 }
152 }
153 code->cur = out;
154 }
155
156 void check_alloc_code(code_info *code, uint32_t inst_size)
157 {
158 if (code->cur + inst_size > code->last) {
159 size_t size = CODE_ALLOC_SIZE;
160 code_ptr next_code = alloc_code(&size);
161 if (!next_code) {
162 fputs("Failed to allocate memory for generated code\n", stderr);
163 exit(1);
164 }
165 if (next_code != code->last + RESERVE_WORDS) {
166 //new chunk is not contiguous with the current one
167 jmp_nocheck(code, next_code);
168 code->cur = next_code;
169 code->last = next_code + size/sizeof(RESERVE_WORDS);
170 }
171 code->last = next_code + size/sizeof(code_word) - RESERVE_WORDS;
172 }
173 }
174
175 void x86_rr_sizedir(code_info *code, uint16_t opcode, uint8_t src, uint8_t dst, uint8_t size)
176 {
177 check_alloc_code(code, 5);
178 code_ptr out = code->cur;
132 uint8_t tmp; 179 uint8_t tmp;
133 if (size == SZ_W) { 180 if (size == SZ_W) {
134 *(out++) = PRE_SIZE; 181 *(out++) = PRE_SIZE;
135 } 182 }
136 if (size == SZ_B && dst >= RSP && dst <= RDI) { 183 if (size == SZ_B && dst >= RSP && dst <= RDI) {
173 *(out++) = opcode; 220 *(out++) = opcode;
174 } else { 221 } else {
175 *(out++) = opcode; 222 *(out++) = opcode;
176 } 223 }
177 *(out++) = MODE_REG_DIRECT | dst | (src << 3); 224 *(out++) = MODE_REG_DIRECT | dst | (src << 3);
178 return out; 225 code->cur = out;
179 } 226 }
180 227
181 uint8_t * x86_rrdisp8_sizedir(uint8_t * out, uint16_t opcode, uint8_t reg, uint8_t base, int8_t disp, uint8_t size, uint8_t dir) 228 void x86_rrdisp_sizedir(code_info *code, uint16_t opcode, uint8_t reg, uint8_t base, int32_t disp, uint8_t size, uint8_t dir)
182 { 229 {
230 check_alloc_code(code, 10);
231 code_ptr out = code->cur;
183 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix 232 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix
184 uint8_t tmp; 233 uint8_t tmp;
185 if (size == SZ_W) { 234 if (size == SZ_W) {
186 *(out++) = PRE_SIZE; 235 *(out++) = PRE_SIZE;
187 } 236 }
216 *(out++) = opcode >> 8; 265 *(out++) = opcode >> 8;
217 *(out++) = opcode; 266 *(out++) = opcode;
218 } else { 267 } else {
219 *(out++) = opcode; 268 *(out++) = opcode;
220 } 269 }
221 *(out++) = MODE_REG_DISPLACE8 | base | (reg << 3); 270 if (disp < 128 && disp >= -128) {
271 *(out++) = MODE_REG_DISPLACE8 | base | (reg << 3);
272 } else {
273 *(out++) = MODE_REG_DISPLACE32 | base | (reg << 3);
274 }
222 if (base == RSP) { 275 if (base == RSP) {
223 //add SIB byte, with no index and RSP as base 276 //add SIB byte, with no index and RSP as base
224 *(out++) = (RSP << 3) | RSP; 277 *(out++) = (RSP << 3) | RSP;
225 } 278 }
226 *(out++) = disp; 279 *(out++) = disp;
227 return out; 280 if (disp >= 128 || disp < -128) {
228 } 281 *(out++) = disp >> 8;
229 282 *(out++) = disp >> 16;
230 uint8_t * x86_rrdisp32_sizedir(uint8_t * out, uint16_t opcode, uint8_t reg, uint8_t base, int32_t disp, uint8_t size, uint8_t dir) 283 *(out++) = disp >> 24;
231 { 284 }
232 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix 285 code->cur = out;
233 uint8_t tmp; 286 }
234 if (size == SZ_W) { 287
235 *(out++) = PRE_SIZE; 288 void x86_rrind_sizedir(code_info *code, uint8_t opcode, uint8_t reg, uint8_t base, uint8_t size, uint8_t dir)
236 } 289 {
237 if (size == SZ_Q || reg >= R8 || base >= R8 || (size == SZ_B && reg >= RSP && reg <= RDI)) { 290 check_alloc_code(code, 5);
238 *out = PRE_REX; 291 code_ptr out = code->cur;
239 if (reg >= AH && reg <= BH) {
240 fprintf(stderr, "attempt to use *H reg in an instruction requiring REX prefix. opcode = %X\n", opcode);
241 exit(1);
242 }
243 if (size == SZ_Q) {
244 *out |= REX_QUAD;
245 }
246 if (reg >= R8) {
247 *out |= REX_REG_FIELD;
248 reg -= (R8 - X86_R8);
249 }
250 if (base >= R8) {
251 *out |= REX_RM_FIELD;
252 base -= (R8 - X86_R8);
253 }
254 out++;
255 }
256 if (size == SZ_B) {
257 if (reg >= AH && reg <= BH) {
258 reg -= (AH-X86_AH);
259 }
260 } else {
261 opcode |= BIT_SIZE;
262 }
263 opcode |= dir;
264 if (opcode >= 0x100) {
265 *(out++) = opcode >> 8;
266 *(out++) = opcode;
267 } else {
268 *(out++) = opcode;
269 }
270 *(out++) = MODE_REG_DISPLACE32 | base | (reg << 3);
271 if (base == RSP) {
272 //add SIB byte, with no index and RSP as base
273 *(out++) = (RSP << 3) | RSP;
274 }
275 *(out++) = disp;
276 *(out++) = disp >> 8;
277 *(out++) = disp >> 16;
278 *(out++) = disp >> 24;
279 return out;
280 }
281
282 uint8_t * x86_rrind_sizedir(uint8_t * out, uint8_t opcode, uint8_t reg, uint8_t base, uint8_t size, uint8_t dir)
283 {
284 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix 292 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix
285 uint8_t tmp; 293 uint8_t tmp;
286 if (size == SZ_W) { 294 if (size == SZ_W) {
287 *(out++) = PRE_SIZE; 295 *(out++) = PRE_SIZE;
288 } 296 }
316 *(out++) = MODE_REG_INDIRECT | base | (reg << 3); 324 *(out++) = MODE_REG_INDIRECT | base | (reg << 3);
317 if (base == RSP) { 325 if (base == RSP) {
318 //add SIB byte, with no index and RSP as base 326 //add SIB byte, with no index and RSP as base
319 *(out++) = (RSP << 3) | RSP; 327 *(out++) = (RSP << 3) | RSP;
320 } 328 }
321 return out; 329 code->cur = out;
322 } 330 }
323 331
324 uint8_t * x86_rrindex_sizedir(uint8_t * out, uint8_t opcode, uint8_t reg, uint8_t base, uint8_t index, uint8_t scale, uint8_t size, uint8_t dir) 332 void x86_rrindex_sizedir(code_info *code, uint8_t opcode, uint8_t reg, uint8_t base, uint8_t index, uint8_t scale, uint8_t size, uint8_t dir)
325 { 333 {
334 check_alloc_code(code, 5);
335 code_ptr out = code->cur;
326 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix 336 //TODO: Deal with the fact that AH, BH, CH and DH can only be in the R/M param when there's a REX prefix
327 uint8_t tmp; 337 uint8_t tmp;
328 if (size == SZ_W) { 338 if (size == SZ_W) {
329 *(out++) = PRE_SIZE; 339 *(out++) = PRE_SIZE;
330 } 340 }
357 } 367 }
358 } else { 368 } else {
359 opcode |= BIT_SIZE; 369 opcode |= BIT_SIZE;
360 } 370 }
361 *(out++) = opcode | dir; 371 *(out++) = opcode | dir;
362 *(out++) = MODE_REG_INDIRECT | base | (RSP << 3); 372 *(out++) = MODE_REG_INDIRECT | RSP | (reg << 3);
363 if (base == RSP) { 373 if (scale == 4) {
364 if (scale == 4) { 374 scale = 2;
365 scale = 3; 375 } else if(scale == 8) {
366 } 376 scale = 3;
367 *(out++) = scale << 6 | (index << 3) | base; 377 } else {
368 } 378 scale--;
369 return out; 379 }
370 } 380 *(out++) = scale << 6 | (index << 3) | base;
371 381 code->cur = out;
372 uint8_t * x86_r_size(uint8_t * out, uint8_t opcode, uint8_t opex, uint8_t dst, uint8_t size) 382 }
373 { 383
384 void x86_r_size(code_info *code, uint8_t opcode, uint8_t opex, uint8_t dst, uint8_t size)
385 {
386 check_alloc_code(code, 4);
387 code_ptr out = code->cur;
374 uint8_t tmp; 388 uint8_t tmp;
375 if (size == SZ_W) { 389 if (size == SZ_W) {
376 *(out++) = PRE_SIZE; 390 *(out++) = PRE_SIZE;
377 } 391 }
378 if (size == SZ_Q || dst >= R8) { 392 if (size == SZ_Q || dst >= R8) {
397 } else { 411 } else {
398 opcode |= BIT_SIZE; 412 opcode |= BIT_SIZE;
399 } 413 }
400 *(out++) = opcode; 414 *(out++) = opcode;
401 *(out++) = MODE_REG_DIRECT | dst | (opex << 3); 415 *(out++) = MODE_REG_DIRECT | dst | (opex << 3);
402 return out; 416 code->cur = out;
403 } 417 }
404 418
405 uint8_t * x86_rdisp8_size(uint8_t * out, uint8_t opcode, uint8_t opex, uint8_t dst, int8_t disp, uint8_t size) 419 void x86_rdisp_size(code_info *code, uint8_t opcode, uint8_t opex, uint8_t dst, int32_t disp, uint8_t size)
406 { 420 {
421 check_alloc_code(code, 7);
422 code_ptr out = code->cur;
407 uint8_t tmp; 423 uint8_t tmp;
408 if (size == SZ_W) { 424 if (size == SZ_W) {
409 *(out++) = PRE_SIZE; 425 *(out++) = PRE_SIZE;
410 } 426 }
411 if (size == SZ_Q || dst >= R8) { 427 if (size == SZ_Q || dst >= R8) {
421 } 437 }
422 if (size != SZ_B) { 438 if (size != SZ_B) {
423 opcode |= BIT_SIZE; 439 opcode |= BIT_SIZE;
424 } 440 }
425 *(out++) = opcode; 441 *(out++) = opcode;
426 *(out++) = MODE_REG_DISPLACE8 | dst | (opex << 3); 442 if (disp < 128 && disp >= -128) {
427 *(out++) = disp; 443 *(out++) = MODE_REG_DISPLACE8 | dst | (opex << 3);
428 return out; 444 *(out++) = disp;
429 } 445 } else {
430 446 *(out++) = MODE_REG_DISPLACE32 | dst | (opex << 3);
431 uint8_t * x86_ir(uint8_t * out, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size) 447 *(out++) = disp;
432 { 448 *(out++) = disp >> 8;
449 *(out++) = disp >> 16;
450 *(out++) = disp >> 24;
451 }
452 code->cur = out;
453 }
454
455 void x86_ir(code_info *code, uint8_t opcode, uint8_t op_ex, uint8_t al_opcode, int32_t val, uint8_t dst, uint8_t size)
456 {
457 check_alloc_code(code, 8);
458 code_ptr out = code->cur;
433 uint8_t sign_extend = 0; 459 uint8_t sign_extend = 0;
434 if (opcode != OP_NOT_NEG && (size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { 460 if (opcode != OP_NOT_NEG && (size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) {
435 sign_extend = 1; 461 sign_extend = 1;
436 opcode |= BIT_DIR; 462 opcode |= BIT_DIR;
437 } 463 }
476 *(out++) = val; 502 *(out++) = val;
477 val >>= 8; 503 val >>= 8;
478 *(out++) = val; 504 *(out++) = val;
479 } 505 }
480 } 506 }
481 return out; 507 code->cur = out;
482 } 508 }
483 509
484 uint8_t * x86_irdisp8(uint8_t * out, uint8_t opcode, uint8_t op_ex, int32_t val, uint8_t dst, int8_t disp, uint8_t size) 510 void x86_irdisp(code_info *code, uint8_t opcode, uint8_t op_ex, int32_t val, uint8_t dst, int32_t disp, uint8_t size)
485 { 511 {
512 check_alloc_code(code, 12);
513 code_ptr out = code->cur;
486 uint8_t sign_extend = 0; 514 uint8_t sign_extend = 0;
487 if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { 515 if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) {
488 sign_extend = 1; 516 sign_extend = 1;
489 opcode |= BIT_DIR; 517 opcode |= BIT_DIR;
490 } 518 }
505 } 533 }
506 if (size != SZ_B) { 534 if (size != SZ_B) {
507 opcode |= BIT_SIZE; 535 opcode |= BIT_SIZE;
508 } 536 }
509 *(out++) = opcode; 537 *(out++) = opcode;
510 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); 538 if (disp < 128 && disp >= -128) {
511 *(out++) = disp; 539 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3);
540 *(out++) = disp;
541 } else {
542 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3);
543 *(out++) = disp;
544 disp >>= 8;
545 *(out++) = disp;
546 disp >>= 8;
547 *(out++) = disp;
548 disp >>= 8;
549 *(out++) = disp;
550 }
512 *(out++) = val; 551 *(out++) = val;
513 if (size != SZ_B && !sign_extend) { 552 if (size != SZ_B && !sign_extend) {
514 val >>= 8; 553 val >>= 8;
515 *(out++) = val; 554 *(out++) = val;
516 if (size != SZ_W) { 555 if (size != SZ_W) {
518 *(out++) = val; 557 *(out++) = val;
519 val >>= 8; 558 val >>= 8;
520 *(out++) = val; 559 *(out++) = val;
521 } 560 }
522 } 561 }
523 return out; 562 code->cur = out;
524 } 563 }
525 564
526 uint8_t * x86_irdisp32(uint8_t * out, uint8_t opcode, uint8_t op_ex, int32_t val, uint8_t dst, int32_t disp, uint8_t size) 565 void x86_shiftrot_ir(code_info *code, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size)
527 { 566 {
528 uint8_t sign_extend = 0; 567 check_alloc_code(code, 5);
529 if ((size == SZ_D || size == SZ_Q) && val <= 0x7F && val >= -0x80) { 568 code_ptr out = code->cur;
530 sign_extend = 1;
531 opcode |= BIT_DIR;
532 }
533 if (size == SZ_W) {
534 *(out++) = PRE_SIZE;
535 }
536
537 if (size == SZ_Q || dst >= R8) {
538 *out = PRE_REX;
539 if (size == SZ_Q) {
540 *out |= REX_QUAD;
541 }
542 if (dst >= R8) {
543 *out |= REX_RM_FIELD;
544 dst -= (R8 - X86_R8);
545 }
546 out++;
547 }
548 if (size != SZ_B) {
549 opcode |= BIT_SIZE;
550 }
551 *(out++) = opcode;
552 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3);
553 *(out++) = disp;
554 disp >>= 8;
555 *(out++) = disp;
556 disp >>= 8;
557 *(out++) = disp;
558 disp >>= 8;
559 *(out++) = disp;
560 *(out++) = val;
561 if (size != SZ_B && !sign_extend) {
562 val >>= 8;
563 *(out++) = val;
564 if (size != SZ_W) {
565 val >>= 8;
566 *(out++) = val;
567 val >>= 8;
568 *(out++) = val;
569 }
570 }
571 return out;
572 }
573
574
575 uint8_t * x86_shiftrot_ir(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size)
576 {
577 if (size == SZ_W) { 569 if (size == SZ_W) {
578 *(out++) = PRE_SIZE; 570 *(out++) = PRE_SIZE;
579 } 571 }
580 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { 572 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) {
581 *out = PRE_REX; 573 *out = PRE_REX;
595 *(out++) = (val == 1 ? OP_SHIFTROT_1: OP_SHIFTROT_IR) | (size == SZ_B ? 0 : BIT_SIZE); 587 *(out++) = (val == 1 ? OP_SHIFTROT_1: OP_SHIFTROT_IR) | (size == SZ_B ? 0 : BIT_SIZE);
596 *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3); 588 *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3);
597 if (val != 1) { 589 if (val != 1) {
598 *(out++) = val; 590 *(out++) = val;
599 } 591 }
600 return out; 592 code->cur = out;
601 } 593 }
602 594
603 uint8_t * x86_shiftrot_irdisp8(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst, int8_t disp, uint8_t size) 595 void x86_shiftrot_irdisp(code_info *code, uint8_t op_ex, uint8_t val, uint8_t dst, int32_t disp, uint8_t size)
604 { 596 {
597 check_alloc_code(code, 9);
598 code_ptr out = code->cur;
605 if (size == SZ_W) { 599 if (size == SZ_W) {
606 *(out++) = PRE_SIZE; 600 *(out++) = PRE_SIZE;
607 } 601 }
608 if (size == SZ_Q || dst >= R8) { 602 if (size == SZ_Q || dst >= R8) {
609 *out = PRE_REX; 603 *out = PRE_REX;
619 if (dst >= AH && dst <= BH) { 613 if (dst >= AH && dst <= BH) {
620 dst -= (AH-X86_AH); 614 dst -= (AH-X86_AH);
621 } 615 }
622 616
623 *(out++) = (val == 1 ? OP_SHIFTROT_1: OP_SHIFTROT_IR) | (size == SZ_B ? 0 : BIT_SIZE); 617 *(out++) = (val == 1 ? OP_SHIFTROT_1: OP_SHIFTROT_IR) | (size == SZ_B ? 0 : BIT_SIZE);
624 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); 618 if (disp < 128 && disp >= -128) {
625 *(out++) = disp; 619 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3);
620 *(out++) = disp;
621 } else {
622 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3);
623 *(out++) = disp;
624 *(out++) = disp >> 8;
625 *(out++) = disp >> 16;
626 *(out++) = disp >> 24;
627 }
626 if (val != 1) { 628 if (val != 1) {
627 *(out++) = val; 629 *(out++) = val;
628 } 630 }
629 return out; 631 code->cur = out;
630 } 632 }
631 633
632 uint8_t * x86_shiftrot_clr(uint8_t * out, uint8_t op_ex, uint8_t dst, uint8_t size) 634 void x86_shiftrot_clr(code_info *code, uint8_t op_ex, uint8_t dst, uint8_t size)
633 { 635 {
636 check_alloc_code(code, 4);
637 code_ptr out = code->cur;
634 if (size == SZ_W) { 638 if (size == SZ_W) {
635 *(out++) = PRE_SIZE; 639 *(out++) = PRE_SIZE;
636 } 640 }
637 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { 641 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) {
638 *out = PRE_REX; 642 *out = PRE_REX;
649 dst -= (AH-X86_AH); 653 dst -= (AH-X86_AH);
650 } 654 }
651 655
652 *(out++) = OP_SHIFTROT_CL | (size == SZ_B ? 0 : BIT_SIZE); 656 *(out++) = OP_SHIFTROT_CL | (size == SZ_B ? 0 : BIT_SIZE);
653 *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3); 657 *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3);
654 return out; 658 code->cur = out;
655 } 659 }
656 660
657 uint8_t * x86_shiftrot_clrdisp8(uint8_t * out, uint8_t op_ex, uint8_t dst, int8_t disp, uint8_t size) 661 void x86_shiftrot_clrdisp(code_info *code, uint8_t op_ex, uint8_t dst, int32_t disp, uint8_t size)
658 { 662 {
663 check_alloc_code(code, 8);
664 code_ptr out = code->cur;
659 if (size == SZ_W) { 665 if (size == SZ_W) {
660 *(out++) = PRE_SIZE; 666 *(out++) = PRE_SIZE;
661 } 667 }
662 if (size == SZ_Q || dst >= R8) { 668 if (size == SZ_Q || dst >= R8) {
663 *out = PRE_REX; 669 *out = PRE_REX;
673 if (dst >= AH && dst <= BH) { 679 if (dst >= AH && dst <= BH) {
674 dst -= (AH-X86_AH); 680 dst -= (AH-X86_AH);
675 } 681 }
676 682
677 *(out++) = OP_SHIFTROT_CL | (size == SZ_B ? 0 : BIT_SIZE); 683 *(out++) = OP_SHIFTROT_CL | (size == SZ_B ? 0 : BIT_SIZE);
678 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); 684 if (disp < 128 && disp >= -128) {
679 *(out++) = disp; 685 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3);
680 return out; 686 *(out++) = disp;
681 } 687 } else {
682 688 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3);
683 uint8_t * rol_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 689 *(out++) = disp;
684 { 690 *(out++) = disp >> 8;
685 return x86_shiftrot_ir(out, OP_EX_ROL, val, dst, size); 691 *(out++) = disp >> 16;
686 } 692 *(out++) = disp >> 24;
687 693 }
688 uint8_t * ror_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 694 code->cur = out;
689 { 695 }
690 return x86_shiftrot_ir(out, OP_EX_ROR, val, dst, size); 696
691 } 697 void rol_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
692 698 {
693 uint8_t * rcl_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 699 x86_shiftrot_ir(code, OP_EX_ROL, val, dst, size);
694 { 700 }
695 return x86_shiftrot_ir(out, OP_EX_RCL, val, dst, size); 701
696 } 702 void ror_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
697 703 {
698 uint8_t * rcr_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 704 x86_shiftrot_ir(code, OP_EX_ROR, val, dst, size);
699 { 705 }
700 return x86_shiftrot_ir(out, OP_EX_RCR, val, dst, size); 706
701 } 707 void rcl_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
702 708 {
703 uint8_t * shl_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 709 x86_shiftrot_ir(code, OP_EX_RCL, val, dst, size);
704 { 710 }
705 return x86_shiftrot_ir(out, OP_EX_SHL, val, dst, size); 711
706 } 712 void rcr_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
707 713 {
708 uint8_t * shr_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 714 x86_shiftrot_ir(code, OP_EX_RCR, val, dst, size);
709 { 715 }
710 return x86_shiftrot_ir(out, OP_EX_SHR, val, dst, size); 716
711 } 717 void shl_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
712 718 {
713 uint8_t * sar_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 719 x86_shiftrot_ir(code, OP_EX_SHL, val, dst, size);
714 { 720 }
715 return x86_shiftrot_ir(out, OP_EX_SAR, val, dst, size); 721
716 } 722 void shr_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
717 723 {
718 uint8_t * rol_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) 724 x86_shiftrot_ir(code, OP_EX_SHR, val, dst, size);
719 { 725 }
720 return x86_shiftrot_irdisp8(out, OP_EX_ROL, val, dst_base, disp, size); 726
721 } 727 void sar_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
722 728 {
723 uint8_t * ror_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) 729 x86_shiftrot_ir(code, OP_EX_SAR, val, dst, size);
724 { 730 }
725 return x86_shiftrot_irdisp8(out, OP_EX_ROR, val, dst_base, disp, size); 731
726 } 732 void rol_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size)
727 733 {
728 uint8_t * rcl_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) 734 x86_shiftrot_irdisp(code, OP_EX_ROL, val, dst_base, disp, size);
729 { 735 }
730 return x86_shiftrot_irdisp8(out, OP_EX_RCL, val, dst_base, disp, size); 736
731 } 737 void ror_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size)
732 738 {
733 uint8_t * rcr_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) 739 x86_shiftrot_irdisp(code, OP_EX_ROR, val, dst_base, disp, size);
734 { 740 }
735 return x86_shiftrot_irdisp8(out, OP_EX_RCR, val, dst_base, disp, size); 741
736 } 742 void rcl_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size)
737 743 {
738 uint8_t * shl_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) 744 x86_shiftrot_irdisp(code, OP_EX_RCL, val, dst_base, disp, size);
739 { 745 }
740 return x86_shiftrot_irdisp8(out, OP_EX_SHL, val, dst_base, disp, size); 746
741 } 747 void rcr_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size)
742 748 {
743 uint8_t * shr_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) 749 x86_shiftrot_irdisp(code, OP_EX_RCR, val, dst_base, disp, size);
744 { 750 }
745 return x86_shiftrot_irdisp8(out, OP_EX_SHR, val, dst_base, disp, size); 751
746 } 752 void shl_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size)
747 753 {
748 uint8_t * sar_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t disp, uint8_t size) 754 x86_shiftrot_irdisp(code, OP_EX_SHL, val, dst_base, disp, size);
749 { 755 }
750 return x86_shiftrot_irdisp8(out, OP_EX_SAR, val, dst_base, disp, size); 756
751 } 757 void shr_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size)
752 758 {
753 uint8_t * rol_clr(uint8_t * out, uint8_t dst, uint8_t size) 759 x86_shiftrot_irdisp(code, OP_EX_SHR, val, dst_base, disp, size);
754 { 760 }
755 return x86_shiftrot_clr(out, OP_EX_ROL, dst, size); 761
756 } 762 void sar_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t disp, uint8_t size)
757 763 {
758 uint8_t * ror_clr(uint8_t * out, uint8_t dst, uint8_t size) 764 x86_shiftrot_irdisp(code, OP_EX_SAR, val, dst_base, disp, size);
759 { 765 }
760 return x86_shiftrot_clr(out, OP_EX_ROR, dst, size); 766
761 } 767 void rol_clr(code_info *code, uint8_t dst, uint8_t size)
762 768 {
763 uint8_t * rcl_clr(uint8_t * out, uint8_t dst, uint8_t size) 769 x86_shiftrot_clr(code, OP_EX_ROL, dst, size);
764 { 770 }
765 return x86_shiftrot_clr(out, OP_EX_RCL, dst, size); 771
766 } 772 void ror_clr(code_info *code, uint8_t dst, uint8_t size)
767 773 {
768 uint8_t * rcr_clr(uint8_t * out, uint8_t dst, uint8_t size) 774 x86_shiftrot_clr(code, OP_EX_ROR, dst, size);
769 { 775 }
770 return x86_shiftrot_clr(out, OP_EX_RCR, dst, size); 776
771 } 777 void rcl_clr(code_info *code, uint8_t dst, uint8_t size)
772 778 {
773 uint8_t * shl_clr(uint8_t * out, uint8_t dst, uint8_t size) 779 x86_shiftrot_clr(code, OP_EX_RCL, dst, size);
774 { 780 }
775 return x86_shiftrot_clr(out, OP_EX_SHL, dst, size); 781
776 } 782 void rcr_clr(code_info *code, uint8_t dst, uint8_t size)
777 783 {
778 uint8_t * shr_clr(uint8_t * out, uint8_t dst, uint8_t size) 784 x86_shiftrot_clr(code, OP_EX_RCR, dst, size);
779 { 785 }
780 return x86_shiftrot_clr(out, OP_EX_SHR, dst, size); 786
781 } 787 void shl_clr(code_info *code, uint8_t dst, uint8_t size)
782 788 {
783 uint8_t * sar_clr(uint8_t * out, uint8_t dst, uint8_t size) 789 x86_shiftrot_clr(code, OP_EX_SHL, dst, size);
784 { 790 }
785 return x86_shiftrot_clr(out, OP_EX_SAR, dst, size); 791
786 } 792 void shr_clr(code_info *code, uint8_t dst, uint8_t size)
787 793 {
788 uint8_t * rol_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 794 x86_shiftrot_clr(code, OP_EX_SHR, dst, size);
789 { 795 }
790 return x86_shiftrot_clrdisp8(out, OP_EX_ROL, dst_base, disp, size); 796
791 } 797 void sar_clr(code_info *code, uint8_t dst, uint8_t size)
792 798 {
793 uint8_t * ror_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 799 x86_shiftrot_clr(code, OP_EX_SAR, dst, size);
794 { 800 }
795 return x86_shiftrot_clrdisp8(out, OP_EX_ROR, dst_base, disp, size); 801
796 } 802 void rol_clrdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
797 803 {
798 uint8_t * rcl_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 804 x86_shiftrot_clrdisp(code, OP_EX_ROL, dst_base, disp, size);
799 { 805 }
800 return x86_shiftrot_clrdisp8(out, OP_EX_RCL, dst_base, disp, size); 806
801 } 807 void ror_clrdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
802 808 {
803 uint8_t * rcr_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 809 x86_shiftrot_clrdisp(code, OP_EX_ROR, dst_base, disp, size);
804 { 810 }
805 return x86_shiftrot_clrdisp8(out, OP_EX_RCR, dst_base, disp, size); 811
806 } 812 void rcl_clrdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
807 813 {
808 uint8_t * shl_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 814 x86_shiftrot_clrdisp(code, OP_EX_RCL, dst_base, disp, size);
809 { 815 }
810 return x86_shiftrot_clrdisp8(out, OP_EX_SHL, dst_base, disp, size); 816
811 } 817 void rcr_clrdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
812 818 {
813 uint8_t * shr_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 819 x86_shiftrot_clrdisp(code, OP_EX_RCR, dst_base, disp, size);
814 { 820 }
815 return x86_shiftrot_clrdisp8(out, OP_EX_SHR, dst_base, disp, size); 821
816 } 822 void shl_clrdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
817 823 {
818 uint8_t * sar_clrdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 824 x86_shiftrot_clrdisp(code, OP_EX_SHL, dst_base, disp, size);
819 { 825 }
820 return x86_shiftrot_clrdisp8(out, OP_EX_SAR, dst_base, disp, size); 826
821 } 827 void shr_clrdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
822 828 {
823 uint8_t * add_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 829 x86_shiftrot_clrdisp(code, OP_EX_SHR, dst_base, disp, size);
824 { 830 }
825 return x86_rr_sizedir(out, OP_ADD, src, dst, size); 831
826 } 832 void sar_clrdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
827 833 {
828 uint8_t * add_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 834 x86_shiftrot_clrdisp(code, OP_EX_SAR, dst_base, disp, size);
829 { 835 }
830 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst, size); 836
831 } 837 void add_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
832 838 {
833 uint8_t * add_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 839 x86_rr_sizedir(code, OP_ADD, src, dst, size);
834 { 840 }
835 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size); 841
836 } 842 void add_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
837 843 {
838 uint8_t * add_irdisp32(uint8_t * out, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size) 844 x86_ir(code, OP_IMMED_ARITH, OP_EX_ADDI, OP_ADD, val, dst, size);
839 { 845 }
840 return x86_irdisp32(out, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size); 846
841 } 847 void add_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
842 848 {
843 uint8_t * add_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 849 x86_irdisp(code, OP_IMMED_ARITH, OP_EX_ADDI, val, dst_base, disp, size);
844 { 850 }
845 return x86_rrdisp8_sizedir(out, OP_ADD, src, dst_base, disp, size, 0); 851
846 } 852 void add_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
847 853 {
848 uint8_t * add_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 854 x86_rrdisp_sizedir(code, OP_ADD, src, dst_base, disp, size, 0);
849 { 855 }
850 return x86_rrdisp8_sizedir(out, OP_ADD, dst, src_base, disp, size, BIT_DIR); 856
851 } 857 void add_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
852 858 {
853 uint8_t * adc_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 859 x86_rrdisp_sizedir(code, OP_ADD, dst, src_base, disp, size, BIT_DIR);
854 { 860 }
855 return x86_rr_sizedir(out, OP_ADC, src, dst, size); 861
856 } 862 void adc_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
857 863 {
858 uint8_t * adc_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 864 x86_rr_sizedir(code, OP_ADC, src, dst, size);
859 { 865 }
860 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ADCI, OP_ADC, val, dst, size); 866
861 } 867 void adc_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
862 868 {
863 uint8_t * adc_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 869 x86_ir(code, OP_IMMED_ARITH, OP_EX_ADCI, OP_ADC, val, dst, size);
864 { 870 }
865 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ADCI, val, dst_base, disp, size); 871
866 } 872 void adc_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
867 873 {
868 uint8_t * adc_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 874 x86_irdisp(code, OP_IMMED_ARITH, OP_EX_ADCI, val, dst_base, disp, size);
869 { 875 }
870 return x86_rrdisp8_sizedir(out, OP_ADC, src, dst_base, disp, size, 0); 876
871 } 877 void adc_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
872 878 {
873 uint8_t * adc_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 879 x86_rrdisp_sizedir(code, OP_ADC, src, dst_base, disp, size, 0);
874 { 880 }
875 return x86_rrdisp8_sizedir(out, OP_ADC, dst, src_base, disp, size, BIT_DIR); 881
876 } 882 void adc_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
877 883 {
878 uint8_t * or_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 884 x86_rrdisp_sizedir(code, OP_ADC, dst, src_base, disp, size, BIT_DIR);
879 { 885 }
880 return x86_rr_sizedir(out, OP_OR, src, dst, size); 886
881 } 887 void or_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
882 uint8_t * or_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 888 {
883 { 889 x86_rr_sizedir(code, OP_OR, src, dst, size);
884 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst, size); 890 }
885 } 891 void or_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
886 892 {
887 uint8_t * or_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 893 x86_ir(code, OP_IMMED_ARITH, OP_EX_ORI, OP_OR, val, dst, size);
888 { 894 }
889 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ORI, val, dst_base, disp, size); 895
890 } 896 void or_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
891 897 {
892 uint8_t * or_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 898 x86_irdisp(code, OP_IMMED_ARITH, OP_EX_ORI, val, dst_base, disp, size);
893 { 899 }
894 return x86_rrdisp8_sizedir(out, OP_OR, src, dst_base, disp, size, 0); 900
895 } 901 void or_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
896 902 {
897 uint8_t * or_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 903 x86_rrdisp_sizedir(code, OP_OR, src, dst_base, disp, size, 0);
898 { 904 }
899 return x86_rrdisp8_sizedir(out, OP_OR, dst, src_base, disp, size, BIT_DIR); 905
900 } 906 void or_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
901 907 {
902 uint8_t * and_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 908 x86_rrdisp_sizedir(code, OP_OR, dst, src_base, disp, size, BIT_DIR);
903 { 909 }
904 return x86_rr_sizedir(out, OP_AND, src, dst, size); 910
905 } 911 void and_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
906 912 {
907 uint8_t * and_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 913 x86_rr_sizedir(code, OP_AND, src, dst, size);
908 { 914 }
909 return x86_ir(out, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst, size); 915
910 } 916 void and_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
911 917 {
912 uint8_t * and_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 918 x86_ir(code, OP_IMMED_ARITH, OP_EX_ANDI, OP_AND, val, dst, size);
913 { 919 }
914 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_ANDI, val, dst_base, disp, size); 920
915 } 921 void and_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
916 922 {
917 uint8_t * and_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 923 x86_irdisp(code, OP_IMMED_ARITH, OP_EX_ANDI, val, dst_base, disp, size);
918 { 924 }
919 return x86_rrdisp8_sizedir(out, OP_AND, src, dst_base, disp, size, 0); 925
920 } 926 void and_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
921 927 {
922 uint8_t * and_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 928 x86_rrdisp_sizedir(code, OP_AND, src, dst_base, disp, size, 0);
923 { 929 }
924 return x86_rrdisp8_sizedir(out, OP_AND, dst, src_base, disp, size, BIT_DIR); 930
925 } 931 void and_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
926 932 {
927 uint8_t * xor_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 933 x86_rrdisp_sizedir(code, OP_AND, dst, src_base, disp, size, BIT_DIR);
928 { 934 }
929 return x86_rr_sizedir(out, OP_XOR, src, dst, size); 935
930 } 936 void xor_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
931 937 {
932 uint8_t * xor_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 938 x86_rr_sizedir(code, OP_XOR, src, dst, size);
933 { 939 }
934 return x86_ir(out, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst, size); 940
935 } 941 void xor_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
936 942 {
937 uint8_t * xor_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 943 x86_ir(code, OP_IMMED_ARITH, OP_EX_XORI, OP_XOR, val, dst, size);
938 { 944 }
939 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_XORI, val, dst_base, disp, size); 945
940 } 946 void xor_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
941 947 {
942 uint8_t * xor_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 948 x86_irdisp(code, OP_IMMED_ARITH, OP_EX_XORI, val, dst_base, disp, size);
943 { 949 }
944 return x86_rrdisp8_sizedir(out, OP_XOR, src, dst_base, disp, size, 0); 950
945 } 951 void xor_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
946 952 {
947 uint8_t * xor_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 953 x86_rrdisp_sizedir(code, OP_XOR, src, dst_base, disp, size, 0);
948 { 954 }
949 return x86_rrdisp8_sizedir(out, OP_XOR, dst, src_base, disp, size, BIT_DIR); 955
950 } 956 void xor_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
951 957 {
952 uint8_t * sub_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 958 x86_rrdisp_sizedir(code, OP_XOR, dst, src_base, disp, size, BIT_DIR);
953 { 959 }
954 return x86_rr_sizedir(out, OP_SUB, src, dst, size); 960
955 } 961 void sub_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
956 962 {
957 uint8_t * sub_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 963 x86_rr_sizedir(code, OP_SUB, src, dst, size);
958 { 964 }
959 return x86_ir(out, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst, size); 965
960 } 966 void sub_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
961 967 {
962 uint8_t * sub_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 968 x86_ir(code, OP_IMMED_ARITH, OP_EX_SUBI, OP_SUB, val, dst, size);
963 { 969 }
964 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_SUBI, val, dst_base, disp, size); 970
965 } 971 void sub_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
966 972 {
967 uint8_t * sub_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 973 x86_irdisp(code, OP_IMMED_ARITH, OP_EX_SUBI, val, dst_base, disp, size);
968 { 974 }
969 return x86_rrdisp8_sizedir(out, OP_SUB, src, dst_base, disp, size, 0); 975
970 } 976 void sub_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
971 977 {
972 uint8_t * sub_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 978 x86_rrdisp_sizedir(code, OP_SUB, src, dst_base, disp, size, 0);
973 { 979 }
974 return x86_rrdisp8_sizedir(out, OP_SUB, dst, src_base, disp, size, BIT_DIR); 980
975 } 981 void sub_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
976 982 {
977 uint8_t * sbb_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 983 x86_rrdisp_sizedir(code, OP_SUB, dst, src_base, disp, size, BIT_DIR);
978 { 984 }
979 return x86_rr_sizedir(out, OP_SBB, src, dst, size); 985
980 } 986 void sbb_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
981 987 {
982 uint8_t * sbb_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 988 x86_rr_sizedir(code, OP_SBB, src, dst, size);
983 { 989 }
984 return x86_ir(out, OP_IMMED_ARITH, OP_EX_SBBI, OP_SBB, val, dst, size); 990
985 } 991 void sbb_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
986 992 {
987 uint8_t * sbb_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 993 x86_ir(code, OP_IMMED_ARITH, OP_EX_SBBI, OP_SBB, val, dst, size);
988 { 994 }
989 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_SBBI, val, dst_base, disp, size); 995
990 } 996 void sbb_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
991 997 {
992 uint8_t * sbb_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 998 x86_irdisp(code, OP_IMMED_ARITH, OP_EX_SBBI, val, dst_base, disp, size);
993 { 999 }
994 return x86_rrdisp8_sizedir(out, OP_SBB, src, dst_base, disp, size, 0); 1000
995 } 1001 void sbb_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
996 1002 {
997 uint8_t * sbb_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 1003 x86_rrdisp_sizedir(code, OP_SBB, src, dst_base, disp, size, 0);
998 { 1004 }
999 return x86_rrdisp8_sizedir(out, OP_SBB, dst, src_base, disp, size, BIT_DIR); 1005
1000 } 1006 void sbb_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
1001 1007 {
1002 uint8_t * cmp_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1008 x86_rrdisp_sizedir(code, OP_SBB, dst, src_base, disp, size, BIT_DIR);
1003 { 1009 }
1004 return x86_rr_sizedir(out, OP_CMP, src, dst, size); 1010
1005 } 1011 void cmp_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1006 1012 {
1007 uint8_t * cmp_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 1013 x86_rr_sizedir(code, OP_CMP, src, dst, size);
1008 { 1014 }
1009 return x86_ir(out, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst, size); 1015
1010 } 1016 void cmp_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
1011 1017 {
1012 uint8_t * cmp_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 1018 x86_ir(code, OP_IMMED_ARITH, OP_EX_CMPI, OP_CMP, val, dst, size);
1013 { 1019 }
1014 return x86_irdisp8(out, OP_IMMED_ARITH, OP_EX_CMPI, val, dst_base, disp, size); 1020
1015 } 1021 void cmp_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
1016 1022 {
1017 uint8_t * cmp_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 1023 x86_irdisp(code, OP_IMMED_ARITH, OP_EX_CMPI, val, dst_base, disp, size);
1018 { 1024 }
1019 return x86_rrdisp8_sizedir(out, OP_CMP, src, dst_base, disp, size, 0); 1025
1020 } 1026 void cmp_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
1021 1027 {
1022 uint8_t * cmp_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 1028 x86_rrdisp_sizedir(code, OP_CMP, src, dst_base, disp, size, 0);
1023 { 1029 }
1024 return x86_rrdisp8_sizedir(out, OP_CMP, dst, src_base, disp, size, BIT_DIR); 1030
1025 } 1031 void cmp_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
1026 1032 {
1027 uint8_t * test_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1033 x86_rrdisp_sizedir(code, OP_CMP, dst, src_base, disp, size, BIT_DIR);
1028 { 1034 }
1029 return x86_rr_sizedir(out, OP_TEST, src, dst, size); 1035
1030 } 1036 void test_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1031 1037 {
1032 uint8_t * test_ir(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 1038 x86_rr_sizedir(code, OP_TEST, src, dst, size);
1033 { 1039 }
1034 return x86_ir(out, OP_NOT_NEG, OP_EX_TEST_I, OP_TEST, val, dst, size); 1040
1035 } 1041 void test_ir(code_info *code, int32_t val, uint8_t dst, uint8_t size)
1036 1042 {
1037 uint8_t * test_irdisp8(uint8_t * out, int32_t val, uint8_t dst_base, int8_t disp, uint8_t size) 1043 x86_ir(code, OP_NOT_NEG, OP_EX_TEST_I, OP_TEST, val, dst, size);
1038 { 1044 }
1039 return x86_irdisp8(out, OP_NOT_NEG, OP_EX_TEST_I, val, dst_base, disp, size); 1045
1040 } 1046 void test_irdisp(code_info *code, int32_t val, uint8_t dst_base, int32_t disp, uint8_t size)
1041 1047 {
1042 uint8_t * test_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 1048 x86_irdisp(code, OP_NOT_NEG, OP_EX_TEST_I, val, dst_base, disp, size);
1043 { 1049 }
1044 return x86_rrdisp8_sizedir(out, OP_TEST, src, dst_base, disp, size, 0); 1050
1045 } 1051 void test_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
1046 1052 {
1047 uint8_t * test_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 1053 x86_rrdisp_sizedir(code, OP_TEST, src, dst_base, disp, size, 0);
1048 { 1054 }
1049 return x86_rrdisp8_sizedir(out, OP_TEST, dst, src_base, disp, size, BIT_DIR); 1055
1050 } 1056 void test_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
1051 1057 {
1052 uint8_t * imul_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1058 x86_rrdisp_sizedir(code, OP_TEST, dst, src_base, disp, size, BIT_DIR);
1053 { 1059 }
1054 return x86_rr_sizedir(out, OP2_IMUL | (PRE_2BYTE << 8), dst, src, size); 1060
1055 } 1061 void imul_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1056 1062 {
1057 uint8_t * imul_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 1063 x86_rr_sizedir(code, OP2_IMUL | (PRE_2BYTE << 8), dst, src, size);
1058 { 1064 }
1059 return x86_rrdisp8_sizedir(out, OP2_IMUL | (PRE_2BYTE << 8), dst, src_base, disp, size, 0); 1065
1060 } 1066 void imul_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
1061 1067 {
1062 uint8_t * not_r(uint8_t * out, uint8_t dst, uint8_t size) 1068 x86_rrdisp_sizedir(code, OP2_IMUL | (PRE_2BYTE << 8), dst, src_base, disp, size, 0);
1063 { 1069 }
1064 return x86_r_size(out, OP_NOT_NEG, OP_EX_NOT, dst, size); 1070
1065 } 1071 void not_r(code_info *code, uint8_t dst, uint8_t size)
1066 1072 {
1067 uint8_t * neg_r(uint8_t * out, uint8_t dst, uint8_t size) 1073 x86_r_size(code, OP_NOT_NEG, OP_EX_NOT, dst, size);
1068 { 1074 }
1069 return x86_r_size(out, OP_NOT_NEG, OP_EX_NEG, dst, size); 1075
1070 } 1076 void neg_r(code_info *code, uint8_t dst, uint8_t size)
1071 1077 {
1072 uint8_t * not_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 1078 x86_r_size(code, OP_NOT_NEG, OP_EX_NEG, dst, size);
1073 { 1079 }
1074 return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_NOT, dst_base, disp, size); 1080
1075 } 1081 void not_rdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
1076 1082 {
1077 uint8_t * neg_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 1083 x86_rdisp_size(code, OP_NOT_NEG, OP_EX_NOT, dst_base, disp, size);
1078 { 1084 }
1079 return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_NEG, dst_base, disp, size); 1085
1080 } 1086 void neg_rdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
1081 1087 {
1082 uint8_t * mul_r(uint8_t * out, uint8_t dst, uint8_t size) 1088 x86_rdisp_size(code, OP_NOT_NEG, OP_EX_NEG, dst_base, disp, size);
1083 { 1089 }
1084 return x86_r_size(out, OP_NOT_NEG, OP_EX_MUL, dst, size); 1090
1085 } 1091 void mul_r(code_info *code, uint8_t dst, uint8_t size)
1086 1092 {
1087 uint8_t * imul_r(uint8_t * out, uint8_t dst, uint8_t size) 1093 x86_r_size(code, OP_NOT_NEG, OP_EX_MUL, dst, size);
1088 { 1094 }
1089 return x86_r_size(out, OP_NOT_NEG, OP_EX_IMUL, dst, size); 1095
1090 } 1096 void imul_r(code_info *code, uint8_t dst, uint8_t size)
1091 1097 {
1092 uint8_t * div_r(uint8_t * out, uint8_t dst, uint8_t size) 1098 x86_r_size(code, OP_NOT_NEG, OP_EX_IMUL, dst, size);
1093 { 1099 }
1094 return x86_r_size(out, OP_NOT_NEG, OP_EX_DIV, dst, size); 1100
1095 } 1101 void div_r(code_info *code, uint8_t dst, uint8_t size)
1096 1102 {
1097 uint8_t * idiv_r(uint8_t * out, uint8_t dst, uint8_t size) 1103 x86_r_size(code, OP_NOT_NEG, OP_EX_DIV, dst, size);
1098 { 1104 }
1099 return x86_r_size(out, OP_NOT_NEG, OP_EX_IDIV, dst, size); 1105
1100 } 1106 void idiv_r(code_info *code, uint8_t dst, uint8_t size)
1101 1107 {
1102 uint8_t * mul_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 1108 x86_r_size(code, OP_NOT_NEG, OP_EX_IDIV, dst, size);
1103 { 1109 }
1104 return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_MUL, dst_base, disp, size); 1110
1105 } 1111 void mul_rdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
1106 1112 {
1107 uint8_t * imul_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 1113 x86_rdisp_size(code, OP_NOT_NEG, OP_EX_MUL, dst_base, disp, size);
1108 { 1114 }
1109 return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_IMUL, dst_base, disp, size); 1115
1110 } 1116 void imul_rdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
1111 1117 {
1112 uint8_t * div_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 1118 x86_rdisp_size(code, OP_NOT_NEG, OP_EX_IMUL, dst_base, disp, size);
1113 { 1119 }
1114 return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_DIV, dst_base, disp, size); 1120
1115 } 1121 void div_rdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
1116 1122 {
1117 uint8_t * idiv_rdisp8(uint8_t * out, uint8_t dst_base, int8_t disp, uint8_t size) 1123 x86_rdisp_size(code, OP_NOT_NEG, OP_EX_DIV, dst_base, disp, size);
1118 { 1124 }
1119 return x86_rdisp8_size(out, OP_NOT_NEG, OP_EX_IDIV, dst_base, disp, size); 1125
1120 } 1126 void idiv_rdisp(code_info *code, uint8_t dst_base, int32_t disp, uint8_t size)
1121 1127 {
1122 uint8_t * mov_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1128 x86_rdisp_size(code, OP_NOT_NEG, OP_EX_IDIV, dst_base, disp, size);
1123 { 1129 }
1124 return x86_rr_sizedir(out, OP_MOV, src, dst, size); 1130
1125 } 1131 void mov_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1126 1132 {
1127 uint8_t * mov_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t disp, uint8_t size) 1133 x86_rr_sizedir(code, OP_MOV, src, dst, size);
1128 { 1134 }
1129 return x86_rrdisp8_sizedir(out, OP_MOV, src, dst_base, disp, size, 0); 1135
1130 } 1136 void mov_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size)
1131 1137 {
1132 uint8_t * mov_rdisp8r(uint8_t * out, uint8_t src_base, int8_t disp, uint8_t dst, uint8_t size) 1138 x86_rrdisp_sizedir(code, OP_MOV, src, dst_base, disp, size, 0);
1133 { 1139 }
1134 return x86_rrdisp8_sizedir(out, OP_MOV, dst, src_base, disp, size, BIT_DIR); 1140
1135 } 1141 void mov_rdispr(code_info *code, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size)
1136 1142 {
1137 uint8_t * mov_rrdisp32(uint8_t * out, uint8_t src, uint8_t dst_base, int32_t disp, uint8_t size) 1143 x86_rrdisp_sizedir(code, OP_MOV, dst, src_base, disp, size, BIT_DIR);
1138 { 1144 }
1139 return x86_rrdisp32_sizedir(out, OP_MOV, src, dst_base, disp, size, 0); 1145
1140 } 1146 void mov_rrind(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1141 1147 {
1142 uint8_t * mov_rdisp32r(uint8_t * out, uint8_t src_base, int32_t disp, uint8_t dst, uint8_t size) 1148 x86_rrind_sizedir(code, OP_MOV, src, dst, size, 0);
1143 { 1149 }
1144 return x86_rrdisp32_sizedir(out, OP_MOV, dst, src_base, disp, size, BIT_DIR); 1150
1145 } 1151 void mov_rindr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1146 1152 {
1147 uint8_t * mov_rrind(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1153 x86_rrind_sizedir(code, OP_MOV, dst, src, size, BIT_DIR);
1148 { 1154 }
1149 return x86_rrind_sizedir(out, OP_MOV, src, dst, size, 0); 1155
1150 } 1156 void mov_rrindex(code_info *code, uint8_t src, uint8_t dst_base, uint8_t dst_index, uint8_t scale, uint8_t size)
1151 1157 {
1152 uint8_t * mov_rindr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1158 x86_rrindex_sizedir(code, OP_MOV, src, dst_base, dst_index, scale, size, 0);
1153 { 1159 }
1154 return x86_rrind_sizedir(out, OP_MOV, dst, src, size, BIT_DIR); 1160
1155 } 1161 void mov_rindexr(code_info *code, uint8_t src_base, uint8_t src_index, uint8_t scale, uint8_t dst, uint8_t size)
1156 1162 {
1157 uint8_t * mov_rrindex(uint8_t * out, uint8_t src, uint8_t dst_base, uint8_t dst_index, uint8_t scale, uint8_t size) 1163 x86_rrindex_sizedir(code, OP_MOV, dst, src_base, src_index, scale, size, BIT_DIR);
1158 { 1164 }
1159 return x86_rrindex_sizedir(out, OP_MOV, src, dst_base, dst_index, scale, size, 0); 1165
1160 } 1166 void mov_ir(code_info *code, int64_t val, uint8_t dst, uint8_t size)
1161 1167 {
1162 uint8_t * mov_rindexr(uint8_t * out, uint8_t src_base, uint8_t src_index, uint8_t scale, uint8_t dst, uint8_t size) 1168 check_alloc_code(code, 14);
1163 { 1169 code_ptr out = code->cur;
1164 return x86_rrindex_sizedir(out, OP_MOV, dst, src_base, src_index, scale, size, BIT_DIR);
1165 }
1166
1167 uint8_t * mov_ir(uint8_t * out, int64_t val, uint8_t dst, uint8_t size)
1168 {
1169 uint8_t sign_extend = 0; 1170 uint8_t sign_extend = 0;
1170 if (size == SZ_Q && val <= 0x7FFFFFFF && val >= -2147483648) { 1171 if (size == SZ_Q && val <= 0x7FFFFFFF && val >= -2147483648) {
1171 sign_extend = 1; 1172 sign_extend = 1;
1172 } 1173 }
1173 if (size == SZ_W) { 1174 if (size == SZ_W) {
1214 val >>= 8; 1215 val >>= 8;
1215 *(out++) = val; 1216 *(out++) = val;
1216 } 1217 }
1217 } 1218 }
1218 } 1219 }
1219 return out; 1220 code->cur = out;
1220 } 1221 }
1221 1222
1222 uint8_t * mov_irdisp8(uint8_t * out, int32_t val, uint8_t dst, int8_t disp, uint8_t size) 1223 void mov_irdisp(code_info *code, int32_t val, uint8_t dst, int32_t disp, uint8_t size)
1223 { 1224 {
1225 check_alloc_code(code, 12);
1226 code_ptr out = code->cur;
1224 if (size == SZ_W) { 1227 if (size == SZ_W) {
1225 *(out++) = PRE_SIZE; 1228 *(out++) = PRE_SIZE;
1226 } 1229 }
1227 if (size == SZ_Q || dst >= R8) { 1230 if (size == SZ_Q || dst >= R8) {
1228 *out = PRE_REX; 1231 *out = PRE_REX;
1237 } 1240 }
1238 if (dst >= AH && dst <= BH) { 1241 if (dst >= AH && dst <= BH) {
1239 dst -= (AH-X86_AH); 1242 dst -= (AH-X86_AH);
1240 } 1243 }
1241 *(out++) = OP_MOV_IEA | (size == SZ_B ? 0 : BIT_SIZE); 1244 *(out++) = OP_MOV_IEA | (size == SZ_B ? 0 : BIT_SIZE);
1242 *(out++) = MODE_REG_DISPLACE8 | dst; 1245 if (disp < 128 && disp >= -128) {
1243 *(out++) = disp; 1246 *(out++) = MODE_REG_DISPLACE8 | dst;
1247 *(out++) = disp;
1248 } else {
1249 *(out++) = MODE_REG_DISPLACE32 | dst;
1250 *(out++) = disp;
1251 *(out++) = disp >> 8;
1252 *(out++) = disp >> 16;
1253 *(out++) = disp >> 24;
1254 }
1244 1255
1245 *(out++) = val; 1256 *(out++) = val;
1246 if (size != SZ_B) { 1257 if (size != SZ_B) {
1247 val >>= 8; 1258 val >>= 8;
1248 *(out++) = val; 1259 *(out++) = val;
1251 *(out++) = val; 1262 *(out++) = val;
1252 val >>= 8; 1263 val >>= 8;
1253 *(out++) = val; 1264 *(out++) = val;
1254 } 1265 }
1255 } 1266 }
1256 return out; 1267 code->cur = out;
1257 } 1268 }
1258 1269
1259 uint8_t * mov_irind(uint8_t * out, int32_t val, uint8_t dst, uint8_t size) 1270 void mov_irind(code_info *code, int32_t val, uint8_t dst, uint8_t size)
1260 { 1271 {
1272 check_alloc_code(code, 8);
1273 code_ptr out = code->cur;
1261 if (size == SZ_W) { 1274 if (size == SZ_W) {
1262 *(out++) = PRE_SIZE; 1275 *(out++) = PRE_SIZE;
1263 } 1276 }
1264 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) { 1277 if (size == SZ_Q || dst >= R8 || (size == SZ_B && dst >= RSP && dst <= RDI)) {
1265 *out = PRE_REX; 1278 *out = PRE_REX;
1287 *(out++) = val; 1300 *(out++) = val;
1288 val >>= 8; 1301 val >>= 8;
1289 *(out++) = val; 1302 *(out++) = val;
1290 } 1303 }
1291 } 1304 }
1292 return out; 1305 code->cur = out;
1293 } 1306 }
1294 1307
1295 uint8_t * movsx_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t src_size, uint8_t size) 1308 void movsx_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t src_size, uint8_t size)
1296 { 1309 {
1310 check_alloc_code(code, 5);
1311 code_ptr out = code->cur;
1297 if (size == SZ_W) { 1312 if (size == SZ_W) {
1298 *(out++) = PRE_SIZE; 1313 *(out++) = PRE_SIZE;
1299 } 1314 }
1300 if (size == SZ_Q || dst >= R8 || src >= R8) { 1315 if (size == SZ_Q || dst >= R8 || src >= R8) {
1301 *out = PRE_REX; 1316 *out = PRE_REX;
1317 } else { 1332 } else {
1318 *(out++) = PRE_2BYTE; 1333 *(out++) = PRE_2BYTE;
1319 *(out++) = OP2_MOVSX | (src_size == SZ_B ? 0 : BIT_SIZE); 1334 *(out++) = OP2_MOVSX | (src_size == SZ_B ? 0 : BIT_SIZE);
1320 } 1335 }
1321 *(out++) = MODE_REG_DIRECT | src | (dst << 3); 1336 *(out++) = MODE_REG_DIRECT | src | (dst << 3);
1322 return out; 1337 code->cur = out;
1323 } 1338 }
1324 1339
1325 uint8_t * movsx_rdisp8r(uint8_t * out, uint8_t src, int8_t disp, uint8_t dst, uint8_t src_size, uint8_t size) 1340 void movsx_rdispr(code_info *code, uint8_t src, int32_t disp, uint8_t dst, uint8_t src_size, uint8_t size)
1326 { 1341 {
1342 check_alloc_code(code, 12);
1343 code_ptr out = code->cur;
1327 if (size == SZ_W) { 1344 if (size == SZ_W) {
1328 *(out++) = PRE_SIZE; 1345 *(out++) = PRE_SIZE;
1329 } 1346 }
1330 if (size == SZ_Q || dst >= R8 || src >= R8) { 1347 if (size == SZ_Q || dst >= R8 || src >= R8) {
1331 *out = PRE_REX; 1348 *out = PRE_REX;
1346 *(out++) = OP_MOVSXD; 1363 *(out++) = OP_MOVSXD;
1347 } else { 1364 } else {
1348 *(out++) = PRE_2BYTE; 1365 *(out++) = PRE_2BYTE;
1349 *(out++) = OP2_MOVSX | (src_size == SZ_B ? 0 : BIT_SIZE); 1366 *(out++) = OP2_MOVSX | (src_size == SZ_B ? 0 : BIT_SIZE);
1350 } 1367 }
1351 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3); 1368 if (disp < 128 && disp >= -128) {
1352 *(out++) = disp; 1369 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3);
1353 return out; 1370 *(out++) = disp;
1354 } 1371 } else {
1355 1372 *(out++) = MODE_REG_DISPLACE32 | src | (dst << 3);
1356 uint8_t * movzx_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t src_size, uint8_t size) 1373 *(out++) = disp;
1357 { 1374 *(out++) = disp >> 8;
1375 *(out++) = disp >> 16;
1376 *(out++) = disp >> 24;
1377 }
1378 code->cur = out;
1379 }
1380
1381 void movzx_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t src_size, uint8_t size)
1382 {
1383 check_alloc_code(code, 5);
1384 code_ptr out = code->cur;
1358 if (size == SZ_W) { 1385 if (size == SZ_W) {
1359 *(out++) = PRE_SIZE; 1386 *(out++) = PRE_SIZE;
1360 } 1387 }
1361 if (size == SZ_Q || dst >= R8 || src >= R8) { 1388 if (size == SZ_Q || dst >= R8 || src >= R8) {
1362 *out = PRE_REX; 1389 *out = PRE_REX;
1374 out++; 1401 out++;
1375 } 1402 }
1376 *(out++) = PRE_2BYTE; 1403 *(out++) = PRE_2BYTE;
1377 *(out++) = OP2_MOVZX | (src_size == SZ_B ? 0 : BIT_SIZE); 1404 *(out++) = OP2_MOVZX | (src_size == SZ_B ? 0 : BIT_SIZE);
1378 *(out++) = MODE_REG_DIRECT | src | (dst << 3); 1405 *(out++) = MODE_REG_DIRECT | src | (dst << 3);
1379 return out; 1406 code->cur = out;
1380 } 1407 }
1381 1408
1382 uint8_t * movzx_rdisp8r(uint8_t * out, uint8_t src, int8_t disp, uint8_t dst, uint8_t src_size, uint8_t size) 1409 void movzx_rdispr(code_info *code, uint8_t src, int32_t disp, uint8_t dst, uint8_t src_size, uint8_t size)
1383 { 1410 {
1411 check_alloc_code(code, 9);
1412 code_ptr out = code->cur;
1384 if (size == SZ_W) { 1413 if (size == SZ_W) {
1385 *(out++) = PRE_SIZE; 1414 *(out++) = PRE_SIZE;
1386 } 1415 }
1387 if (size == SZ_Q || dst >= R8 || src >= R8) { 1416 if (size == SZ_Q || dst >= R8 || src >= R8) {
1388 *out = PRE_REX; 1417 *out = PRE_REX;
1399 } 1428 }
1400 out++; 1429 out++;
1401 } 1430 }
1402 *(out++) = PRE_2BYTE; 1431 *(out++) = PRE_2BYTE;
1403 *(out++) = OP2_MOVZX | (src_size == SZ_B ? 0 : BIT_SIZE); 1432 *(out++) = OP2_MOVZX | (src_size == SZ_B ? 0 : BIT_SIZE);
1404 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3); 1433 if (disp < 128 && disp >= -128) {
1405 *(out++) = disp; 1434 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3);
1406 return out; 1435 *(out++) = disp;
1407 } 1436 } else {
1408 1437 *(out++) = MODE_REG_DISPLACE32 | src | (dst << 3);
1409 uint8_t * xchg_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1438 *(out++) = disp;
1410 { 1439 *(out++) = disp >> 8;
1440 *(out++) = disp >> 16;
1441 *(out++) = disp >> 24;
1442 }
1443 code->cur = out;
1444 }
1445
1446 void xchg_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1447 {
1448 check_alloc_code(code, 4);
1449 code_ptr out = code->cur;
1411 //TODO: Use OP_XCHG_AX when one of the registers is AX, EAX or RAX 1450 //TODO: Use OP_XCHG_AX when one of the registers is AX, EAX or RAX
1412 uint8_t tmp; 1451 uint8_t tmp;
1413 if (size == SZ_W) { 1452 if (size == SZ_W) {
1414 *(out++) = PRE_SIZE; 1453 *(out++) = PRE_SIZE;
1415 } 1454 }
1444 } else { 1483 } else {
1445 opcode |= BIT_SIZE; 1484 opcode |= BIT_SIZE;
1446 } 1485 }
1447 *(out++) = opcode; 1486 *(out++) = opcode;
1448 *(out++) = MODE_REG_DIRECT | dst | (src << 3); 1487 *(out++) = MODE_REG_DIRECT | dst | (src << 3);
1449 return out; 1488 code->cur = out;
1450 } 1489 }
1451 1490
1452 uint8_t * pushf(uint8_t * out) 1491 void pushf(code_info *code)
1453 { 1492 {
1493 check_alloc_code(code, 1);
1494 code_ptr out = code->cur;
1454 *(out++) = OP_PUSHF; 1495 *(out++) = OP_PUSHF;
1455 return out; 1496 code->cur = out;
1456 } 1497 }
1457 1498
1458 uint8_t * popf(uint8_t * out) 1499 void popf(code_info *code)
1459 { 1500 {
1501 check_alloc_code(code, 1);
1502 code_ptr out = code->cur;
1460 *(out++) = OP_POPF; 1503 *(out++) = OP_POPF;
1461 return out; 1504 code->cur = out;
1462 } 1505 }
1463 1506
1464 uint8_t * push_r(uint8_t * out, uint8_t reg) 1507 void push_r(code_info *code, uint8_t reg)
1465 { 1508 {
1509 check_alloc_code(code, 2);
1510 code_ptr out = code->cur;
1466 if (reg >= R8) { 1511 if (reg >= R8) {
1467 *(out++) = PRE_REX | REX_RM_FIELD; 1512 *(out++) = PRE_REX | REX_RM_FIELD;
1468 reg -= R8 - X86_R8; 1513 reg -= R8 - X86_R8;
1469 } 1514 }
1470 *(out++) = OP_PUSH | reg; 1515 *(out++) = OP_PUSH | reg;
1471 return out; 1516 code->cur = out;
1472 } 1517 }
1473 1518
1474 uint8_t * pop_r(uint8_t * out, uint8_t reg) 1519 void pop_r(code_info *code, uint8_t reg)
1475 { 1520 {
1521 check_alloc_code(code, 2);
1522 code_ptr out = code->cur;
1476 if (reg >= R8) { 1523 if (reg >= R8) {
1477 *(out++) = PRE_REX | REX_RM_FIELD; 1524 *(out++) = PRE_REX | REX_RM_FIELD;
1478 reg -= R8 - X86_R8; 1525 reg -= R8 - X86_R8;
1479 } 1526 }
1480 *(out++) = OP_POP | reg; 1527 *(out++) = OP_POP | reg;
1481 return out; 1528 code->cur = out;
1482 } 1529 }
1483 1530
1484 uint8_t * setcc_r(uint8_t * out, uint8_t cc, uint8_t dst) 1531 void setcc_r(code_info *code, uint8_t cc, uint8_t dst)
1485 { 1532 {
1533 check_alloc_code(code, 4);
1534 code_ptr out = code->cur;
1486 if (dst >= R8) { 1535 if (dst >= R8) {
1487 *(out++) = PRE_REX | REX_RM_FIELD; 1536 *(out++) = PRE_REX | REX_RM_FIELD;
1488 dst -= R8 - X86_R8; 1537 dst -= R8 - X86_R8;
1489 } else if (dst >= RSP && dst <= RDI) { 1538 } else if (dst >= RSP && dst <= RDI) {
1490 *(out++) = PRE_REX; 1539 *(out++) = PRE_REX;
1492 dst -= AH - X86_AH; 1541 dst -= AH - X86_AH;
1493 } 1542 }
1494 *(out++) = PRE_2BYTE; 1543 *(out++) = PRE_2BYTE;
1495 *(out++) = OP2_SETCC | cc; 1544 *(out++) = OP2_SETCC | cc;
1496 *(out++) = MODE_REG_DIRECT | dst; 1545 *(out++) = MODE_REG_DIRECT | dst;
1497 return out; 1546 code->cur = out;
1498 } 1547 }
1499 1548
1500 uint8_t * setcc_rind(uint8_t * out, uint8_t cc, uint8_t dst) 1549 void setcc_rind(code_info *code, uint8_t cc, uint8_t dst)
1501 { 1550 {
1551 check_alloc_code(code, 4);
1552 code_ptr out = code->cur;
1502 if (dst >= R8) { 1553 if (dst >= R8) {
1503 *(out++) = PRE_REX | REX_RM_FIELD; 1554 *(out++) = PRE_REX | REX_RM_FIELD;
1504 dst -= R8 - X86_R8; 1555 dst -= R8 - X86_R8;
1505 } 1556 }
1506 *(out++) = PRE_2BYTE; 1557 *(out++) = PRE_2BYTE;
1507 *(out++) = OP2_SETCC | cc; 1558 *(out++) = OP2_SETCC | cc;
1508 *(out++) = MODE_REG_INDIRECT | dst; 1559 *(out++) = MODE_REG_INDIRECT | dst;
1509 return out; 1560 code->cur = out;
1510 } 1561 }
1511 1562
1512 uint8_t * setcc_rdisp8(uint8_t * out, uint8_t cc, uint8_t dst, int8_t disp) 1563 void setcc_rdisp(code_info *code, uint8_t cc, uint8_t dst, int32_t disp)
1513 { 1564 {
1565 check_alloc_code(code, 8);
1566 code_ptr out = code->cur;
1514 if (dst >= R8) { 1567 if (dst >= R8) {
1515 *(out++) = PRE_REX | REX_RM_FIELD; 1568 *(out++) = PRE_REX | REX_RM_FIELD;
1516 dst -= R8 - X86_R8; 1569 dst -= R8 - X86_R8;
1517 } 1570 }
1518 *(out++) = PRE_2BYTE; 1571 *(out++) = PRE_2BYTE;
1519 *(out++) = OP2_SETCC | cc; 1572 *(out++) = OP2_SETCC | cc;
1520 *(out++) = MODE_REG_DISPLACE8 | dst; 1573 if (disp < 128 && disp >= -128) {
1521 *(out++) = disp; 1574 *(out++) = MODE_REG_DISPLACE8 | dst;
1522 return out; 1575 *(out++) = disp;
1523 } 1576 } else {
1524 1577 *(out++) = MODE_REG_DISPLACE32 | dst;
1525 uint8_t * bit_rr(uint8_t * out, uint8_t op2, uint8_t src, uint8_t dst, uint8_t size) 1578 *(out++) = disp;
1526 { 1579 *(out++) = disp >> 8;
1580 *(out++) = disp >> 16;
1581 *(out++) = disp >> 24;
1582 }
1583 code->cur = out;
1584 }
1585
1586 void bit_rr(code_info *code, uint8_t op2, uint8_t src, uint8_t dst, uint8_t size)
1587 {
1588 check_alloc_code(code, 5);
1589 code_ptr out = code->cur;
1527 if (size == SZ_W) { 1590 if (size == SZ_W) {
1528 *(out++) = PRE_SIZE; 1591 *(out++) = PRE_SIZE;
1529 } 1592 }
1530 if (size == SZ_Q || src >= R8 || dst >= R8) { 1593 if (size == SZ_Q || src >= R8 || dst >= R8) {
1531 *out = PRE_REX; 1594 *out = PRE_REX;
1543 out++; 1606 out++;
1544 } 1607 }
1545 *(out++) = PRE_2BYTE; 1608 *(out++) = PRE_2BYTE;
1546 *(out++) = op2; 1609 *(out++) = op2;
1547 *(out++) = MODE_REG_DIRECT | dst | (src << 3); 1610 *(out++) = MODE_REG_DIRECT | dst | (src << 3);
1548 return out; 1611 code->cur = out;
1549 } 1612 }
1550 1613
1551 uint8_t * bit_rrdisp8(uint8_t * out, uint8_t op2, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1614 void bit_rrdisp(code_info *code, uint8_t op2, uint8_t src, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1552 { 1615 {
1616 check_alloc_code(code, 9);
1617 code_ptr out = code->cur;
1553 if (size == SZ_W) { 1618 if (size == SZ_W) {
1554 *(out++) = PRE_SIZE; 1619 *(out++) = PRE_SIZE;
1555 } 1620 }
1556 if (size == SZ_Q || src >= R8 || dst_base >= R8) { 1621 if (size == SZ_Q || src >= R8 || dst_base >= R8) {
1557 *out = PRE_REX; 1622 *out = PRE_REX;
1568 } 1633 }
1569 out++; 1634 out++;
1570 } 1635 }
1571 *(out++) = PRE_2BYTE; 1636 *(out++) = PRE_2BYTE;
1572 *(out++) = op2; 1637 *(out++) = op2;
1573 *(out++) = MODE_REG_DISPLACE8 | dst_base | (src << 3); 1638 if (dst_disp < 128 && dst_disp >= -128) {
1574 *(out++) = dst_disp; 1639 *(out++) = MODE_REG_DISPLACE8 | dst_base | (src << 3);
1575 return out; 1640 *(out++) = dst_disp;
1576 } 1641 } else {
1577 1642 *(out++) = MODE_REG_DISPLACE32 | dst_base | (src << 3);
1578 uint8_t * bit_rrdisp32(uint8_t * out, uint8_t op2, uint8_t src, uint8_t dst_base, int32_t dst_disp, uint8_t size) 1643 *(out++) = dst_disp;
1579 { 1644 *(out++) = dst_disp >> 8;
1580 if (size == SZ_W) { 1645 *(out++) = dst_disp >> 16;
1581 *(out++) = PRE_SIZE; 1646 *(out++) = dst_disp >> 24;
1582 } 1647 }
1583 if (size == SZ_Q || src >= R8 || dst_base >= R8) { 1648 code->cur = out;
1584 *out = PRE_REX; 1649 }
1585 if (size == SZ_Q) { 1650
1586 *out |= REX_QUAD; 1651 void bit_ir(code_info *code, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size)
1587 } 1652 {
1588 if (src >= R8) { 1653 check_alloc_code(code, 6);
1589 *out |= REX_REG_FIELD; 1654 code_ptr out = code->cur;
1590 src -= (R8 - X86_R8);
1591 }
1592 if (dst_base >= R8) {
1593 *out |= REX_RM_FIELD;
1594 dst_base -= (R8 - X86_R8);
1595 }
1596 out++;
1597 }
1598 *(out++) = PRE_2BYTE;
1599 *(out++) = op2;
1600 *(out++) = MODE_REG_DISPLACE32 | dst_base | (src << 3);
1601 *(out++) = dst_disp;
1602 *(out++) = dst_disp >> 8;
1603 *(out++) = dst_disp >> 16;
1604 *(out++) = dst_disp >> 24;
1605 return out;
1606 }
1607
1608 uint8_t * bit_ir(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size)
1609 {
1610 if (size == SZ_W) { 1655 if (size == SZ_W) {
1611 *(out++) = PRE_SIZE; 1656 *(out++) = PRE_SIZE;
1612 } 1657 }
1613 if (size == SZ_Q || dst >= R8) { 1658 if (size == SZ_Q || dst >= R8) {
1614 *out = PRE_REX; 1659 *out = PRE_REX;
1623 } 1668 }
1624 *(out++) = PRE_2BYTE; 1669 *(out++) = PRE_2BYTE;
1625 *(out++) = OP2_BTX_I; 1670 *(out++) = OP2_BTX_I;
1626 *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3); 1671 *(out++) = MODE_REG_DIRECT | dst | (op_ex << 3);
1627 *(out++) = val; 1672 *(out++) = val;
1628 return out; 1673 code->cur = out;
1629 } 1674 }
1630 1675
1631 uint8_t * bit_irdisp8(uint8_t * out, uint8_t op_ex, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1676 void bit_irdisp(code_info *code, uint8_t op_ex, uint8_t val, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1632 { 1677 {
1678 check_alloc_code(code, 10);
1679 code_ptr out = code->cur;
1633 if (size == SZ_W) { 1680 if (size == SZ_W) {
1634 *(out++) = PRE_SIZE; 1681 *(out++) = PRE_SIZE;
1635 } 1682 }
1636 if (size == SZ_Q || dst_base >= R8) { 1683 if (size == SZ_Q || dst_base >= R8) {
1637 *out = PRE_REX; 1684 *out = PRE_REX;
1644 } 1691 }
1645 out++; 1692 out++;
1646 } 1693 }
1647 *(out++) = PRE_2BYTE; 1694 *(out++) = PRE_2BYTE;
1648 *(out++) = OP2_BTX_I; 1695 *(out++) = OP2_BTX_I;
1649 *(out++) = MODE_REG_DISPLACE8 | dst_base | (op_ex << 3); 1696 if (dst_disp < 128 && dst_disp >= -128) {
1650 *(out++) = dst_disp; 1697 *(out++) = MODE_REG_DISPLACE8 | dst_base | (op_ex << 3);
1698 *(out++) = dst_disp;
1699 } else {
1700 *(out++) = MODE_REG_DISPLACE32 | dst_base | (op_ex << 3);
1701 *(out++) = dst_disp;
1702 *(out++) = dst_disp >> 8;
1703 *(out++) = dst_disp >> 16;
1704 *(out++) = dst_disp >> 24;
1705 }
1651 *(out++) = val; 1706 *(out++) = val;
1652 return out; 1707 code->cur = out;
1653 } 1708 }
1654 1709
1655 uint8_t * bt_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1710 void bt_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1656 { 1711 {
1657 return bit_rr(out, OP2_BT, src, dst, size); 1712 return bit_rr(code, OP2_BT, src, dst, size);
1658 } 1713 }
1659 1714
1660 uint8_t * bt_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1715 void bt_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1661 { 1716 {
1662 return bit_rrdisp8(out, OP2_BT, src, dst_base, dst_disp, size); 1717 return bit_rrdisp(code, OP2_BT, src, dst_base, dst_disp, size);
1663 } 1718 }
1664 1719
1665 uint8_t * bt_rrdisp32(uint8_t * out, uint8_t src, uint8_t dst_base, int32_t dst_disp, uint8_t size) 1720 void bt_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
1666 { 1721 {
1667 return bit_rrdisp32(out, OP2_BT, src, dst_base, dst_disp, size); 1722 return bit_ir(code, OP_EX_BT, val, dst, size);
1668 } 1723 }
1669 1724
1670 uint8_t * bt_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 1725 void bt_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1671 { 1726 {
1672 return bit_ir(out, OP_EX_BT, val, dst, size); 1727 return bit_irdisp(code, OP_EX_BT, val, dst_base, dst_disp, size);
1673 } 1728 }
1674 1729
1675 uint8_t * bt_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1730 void bts_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1676 { 1731 {
1677 return bit_irdisp8(out, OP_EX_BT, val, dst_base, dst_disp, size); 1732 return bit_rr(code, OP2_BTS, src, dst, size);
1678 } 1733 }
1679 1734
1680 uint8_t * bts_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1735 void bts_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1681 { 1736 {
1682 return bit_rr(out, OP2_BTS, src, dst, size); 1737 return bit_rrdisp(code, OP2_BTS, src, dst_base, dst_disp, size);
1683 } 1738 }
1684 1739
1685 uint8_t * bts_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1740 void bts_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
1686 { 1741 {
1687 return bit_rrdisp8(out, OP2_BTS, src, dst_base, dst_disp, size); 1742 return bit_ir(code, OP_EX_BTS, val, dst, size);
1688 } 1743 }
1689 1744
1690 uint8_t * bts_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 1745 void bts_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1691 { 1746 {
1692 return bit_ir(out, OP_EX_BTS, val, dst, size); 1747 return bit_irdisp(code, OP_EX_BTS, val, dst_base, dst_disp, size);
1693 } 1748 }
1694 1749
1695 uint8_t * bts_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1750 void btr_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1696 { 1751 {
1697 return bit_irdisp8(out, OP_EX_BTS, val, dst_base, dst_disp, size); 1752 return bit_rr(code, OP2_BTR, src, dst, size);
1698 } 1753 }
1699 1754
1700 uint8_t * btr_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1755 void btr_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1701 { 1756 {
1702 return bit_rr(out, OP2_BTR, src, dst, size); 1757 return bit_rrdisp(code, OP2_BTR, src, dst_base, dst_disp, size);
1703 } 1758 }
1704 1759
1705 uint8_t * btr_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1760 void btr_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
1706 { 1761 {
1707 return bit_rrdisp8(out, OP2_BTR, src, dst_base, dst_disp, size); 1762 return bit_ir(code, OP_EX_BTR, val, dst, size);
1708 } 1763 }
1709 1764
1710 uint8_t * btr_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 1765 void btr_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1711 { 1766 {
1712 return bit_ir(out, OP_EX_BTR, val, dst, size); 1767 return bit_irdisp(code, OP_EX_BTR, val, dst_base, dst_disp, size);
1713 } 1768 }
1714 1769
1715 uint8_t * btr_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1770 void btc_rr(code_info *code, uint8_t src, uint8_t dst, uint8_t size)
1716 { 1771 {
1717 return bit_irdisp8(out, OP_EX_BTR, val, dst_base, dst_disp, size); 1772 return bit_rr(code, OP2_BTC, src, dst, size);
1718 } 1773 }
1719 1774
1720 uint8_t * btc_rr(uint8_t * out, uint8_t src, uint8_t dst, uint8_t size) 1775 void btc_rrdisp(code_info *code, uint8_t src, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1721 { 1776 {
1722 return bit_rr(out, OP2_BTC, src, dst, size); 1777 return bit_rrdisp(code, OP2_BTC, src, dst_base, dst_disp, size);
1723 } 1778 }
1724 1779
1725 uint8_t * btc_rrdisp8(uint8_t * out, uint8_t src, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1780 void btc_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size)
1726 { 1781 {
1727 return bit_rrdisp8(out, OP2_BTC, src, dst_base, dst_disp, size); 1782 return bit_ir(code, OP_EX_BTC, val, dst, size);
1728 } 1783 }
1729 1784
1730 uint8_t * btc_ir(uint8_t * out, uint8_t val, uint8_t dst, uint8_t size) 1785 void btc_irdisp(code_info *code, uint8_t val, uint8_t dst_base, int32_t dst_disp, uint8_t size)
1731 { 1786 {
1732 return bit_ir(out, OP_EX_BTC, val, dst, size); 1787 return bit_irdisp(code, OP_EX_BTC, val, dst_base, dst_disp, size);
1733 } 1788 }
1734 1789
1735 uint8_t * btc_irdisp8(uint8_t * out, uint8_t val, uint8_t dst_base, int8_t dst_disp, uint8_t size) 1790 void jcc(code_info *code, uint8_t cc, code_ptr dest)
1736 { 1791 {
1737 return bit_irdisp8(out, OP_EX_BTC, val, dst_base, dst_disp, size); 1792 check_alloc_code(code, 6);
1738 } 1793 code_ptr out = code->cur;
1739
1740 uint8_t * jcc(uint8_t * out, uint8_t cc, uint8_t * dest)
1741 {
1742 ptrdiff_t disp = dest-(out+2); 1794 ptrdiff_t disp = dest-(out+2);
1743 if (disp <= 0x7F && disp >= -0x80) { 1795 if (disp <= 0x7F && disp >= -0x80) {
1744 *(out++) = OP_JCC | cc; 1796 *(out++) = OP_JCC | cc;
1745 *(out++) = disp; 1797 *(out++) = disp;
1746 } else { 1798 } else {
1754 disp >>= 8; 1806 disp >>= 8;
1755 *(out++) = disp; 1807 *(out++) = disp;
1756 disp >>= 8; 1808 disp >>= 8;
1757 *(out++) = disp; 1809 *(out++) = disp;
1758 } else { 1810 } else {
1759 printf("%p - %p = %lX\n", dest, out + 6, (long)disp); 1811 fprintf(stderr, "jcc: %p - %p = %lX\n", dest, out + 6, (long)disp);
1760 return NULL; 1812 exit(1);
1761 } 1813 }
1762 } 1814 }
1763 return out; 1815 code->cur = out;
1764 } 1816 }
1765 1817
1766 uint8_t * jmp(uint8_t * out, uint8_t * dest) 1818 void jmp(code_info *code, code_ptr dest)
1767 { 1819 {
1820 check_alloc_code(code, 5);
1821 code_ptr out = code->cur;
1768 ptrdiff_t disp = dest-(out+2); 1822 ptrdiff_t disp = dest-(out+2);
1769 if (disp <= 0x7F && disp >= -0x80) { 1823 if (disp <= 0x7F && disp >= -0x80) {
1770 *(out++) = OP_JMP_BYTE; 1824 *(out++) = OP_JMP_BYTE;
1771 *(out++) = disp; 1825 *(out++) = disp;
1772 } else { 1826 } else {
1779 disp >>= 8; 1833 disp >>= 8;
1780 *(out++) = disp; 1834 *(out++) = disp;
1781 disp >>= 8; 1835 disp >>= 8;
1782 *(out++) = disp; 1836 *(out++) = disp;
1783 } else { 1837 } else {
1784 printf("%p - %p = %lX\n", dest, out + 6, (long)disp); 1838 fprintf(stderr, "jmp: %p - %p = %lX\n", dest, out + 6, (long)disp);
1785 return NULL; 1839 exit(1);
1786 } 1840 }
1787 } 1841 }
1788 return out; 1842 code->cur = out;
1789 } 1843 }
1790 1844
1791 uint8_t * jmp_r(uint8_t * out, uint8_t dst) 1845 void jmp_r(code_info *code, uint8_t dst)
1792 { 1846 {
1847 check_alloc_code(code, 3);
1848 code_ptr out = code->cur;
1793 if (dst >= R8) { 1849 if (dst >= R8) {
1794 dst -= R8 - X86_R8; 1850 dst -= R8 - X86_R8;
1795 *(out++) = PRE_REX | REX_RM_FIELD; 1851 *(out++) = PRE_REX | REX_RM_FIELD;
1796 } 1852 }
1797 *(out++) = OP_SINGLE_EA; 1853 *(out++) = OP_SINGLE_EA;
1798 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_JMP_EA << 3); 1854 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_JMP_EA << 3);
1799 return out; 1855 code->cur = out;
1800 } 1856 }
1801 1857
1802 uint8_t * call(uint8_t * out, uint8_t * fun) 1858 void call(code_info *code, code_ptr fun)
1803 { 1859 {
1860 check_alloc_code(code, 5);
1861 code_ptr out = code->cur;
1804 ptrdiff_t disp = fun-(out+5); 1862 ptrdiff_t disp = fun-(out+5);
1805 if (disp <= 0x7FFFFFFF && disp >= -2147483648) { 1863 if (disp <= 0x7FFFFFFF && disp >= -2147483648) {
1806 *(out++) = OP_CALL; 1864 *(out++) = OP_CALL;
1807 *(out++) = disp; 1865 *(out++) = disp;
1808 disp >>= 8; 1866 disp >>= 8;
1811 *(out++) = disp; 1869 *(out++) = disp;
1812 disp >>= 8; 1870 disp >>= 8;
1813 *(out++) = disp; 1871 *(out++) = disp;
1814 } else { 1872 } else {
1815 //TODO: Implement far call??? 1873 //TODO: Implement far call???
1816 printf("%p - %p = %lX\n", fun, out + 5, (long)disp); 1874 fprintf(stderr, "%p - %p = %lX\n", fun, out + 5, (long)disp);
1817 return NULL; 1875 exit(1);
1818 } 1876 }
1819 return out; 1877 code->cur = out;
1820 } 1878 }
1821 1879
1822 uint8_t * call_r(uint8_t * out, uint8_t dst) 1880 void call_r(code_info *code, uint8_t dst)
1823 { 1881 {
1882 check_alloc_code(code, 2);
1883 code_ptr out = code->cur;
1824 *(out++) = OP_SINGLE_EA; 1884 *(out++) = OP_SINGLE_EA;
1825 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_CALL_EA << 3); 1885 *(out++) = MODE_REG_DIRECT | dst | (OP_EX_CALL_EA << 3);
1826 return out; 1886 code->cur = out;
1827 } 1887 }
1828 1888
1829 uint8_t * retn(uint8_t * out) 1889 void retn(code_info *code)
1830 { 1890 {
1891 check_alloc_code(code, 1);
1892 code_ptr out = code->cur;
1831 *(out++) = OP_RETN; 1893 *(out++) = OP_RETN;
1832 return out; 1894 code->cur = out;
1833 } 1895 }
1834 1896
1835 uint8_t * cdq(uint8_t * out) 1897 void cdq(code_info *code)
1836 { 1898 {
1899 check_alloc_code(code, 1);
1900 code_ptr out = code->cur;
1837 *(out++) = OP_CDQ; 1901 *(out++) = OP_CDQ;
1838 return out; 1902 code->cur = out;
1839 } 1903 }
1840 1904
1841 uint8_t * loop(uint8_t * out, uint8_t * dst) 1905 void loop(code_info *code, code_ptr dst)
1842 { 1906 {
1907 check_alloc_code(code, 2);
1908 code_ptr out = code->cur;
1843 ptrdiff_t disp = dst-(out+2); 1909 ptrdiff_t disp = dst-(out+2);
1844 *(out++) = OP_LOOP; 1910 *(out++) = OP_LOOP;
1845 *(out++) = disp; 1911 *(out++) = disp;
1846 return out; 1912 code->cur = out;
1847 } 1913 }
1914