Mercurial > repos > blastem
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 |