Mercurial > repos > blastem
comparison gen_x86.c @ 682:7ed1dbb48f61
Merge
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 04 Jan 2015 23:35:55 -0800 |
parents | d0943769353b f9431cb3a39c |
children | 74d636e85bf8 |
comparison
equal
deleted
inserted
replaced
681:e26640daf1ae | 682:7ed1dbb48f61 |
---|---|
269 *(out++) = opcode; | 269 *(out++) = opcode; |
270 } else { | 270 } else { |
271 *(out++) = opcode; | 271 *(out++) = opcode; |
272 } | 272 } |
273 if (disp < 128 && disp >= -128) { | 273 if (disp < 128 && disp >= -128) { |
274 *(out++) = MODE_REG_DISPLACE8 | base | (reg << 3); | 274 *(out++) = MODE_REG_DISPLACE8 | base | (reg << 3); |
275 } else { | 275 } else { |
276 *(out++) = MODE_REG_DISPLACE32 | base | (reg << 3); | 276 *(out++) = MODE_REG_DISPLACE32 | base | (reg << 3); |
277 } | 277 } |
278 if (base == RSP) { | 278 if (base == RSP) { |
279 //add SIB byte, with no index and RSP as base | 279 //add SIB byte, with no index and RSP as base |
280 *(out++) = (RSP << 3) | RSP; | 280 *(out++) = (RSP << 3) | RSP; |
281 } | 281 } |
282 *(out++) = disp; | 282 *(out++) = disp; |
283 if (disp >= 128 || disp < -128) { | 283 if (disp >= 128 || disp < -128) { |
284 *(out++) = disp >> 8; | 284 *(out++) = disp >> 8; |
285 *(out++) = disp >> 16; | 285 *(out++) = disp >> 16; |
286 *(out++) = disp >> 24; | 286 *(out++) = disp >> 24; |
287 } | 287 } |
288 code->cur = out; | 288 code->cur = out; |
289 } | 289 } |
290 | 290 |
291 void x86_rrind_sizedir(code_info *code, uint8_t opcode, uint8_t reg, uint8_t base, uint8_t size, uint8_t dir) | 291 void x86_rrind_sizedir(code_info *code, uint8_t opcode, uint8_t reg, uint8_t base, uint8_t size, uint8_t dir) |
328 //add a dummy 8-bit displacement since MODE_REG_INDIRECT with | 328 //add a dummy 8-bit displacement since MODE_REG_INDIRECT with |
329 //an R/M field of RBP selects RIP, relative addressing | 329 //an R/M field of RBP selects RIP, relative addressing |
330 *(out++) = MODE_REG_DISPLACE8 | base | (reg << 3); | 330 *(out++) = MODE_REG_DISPLACE8 | base | (reg << 3); |
331 *(out++) = 0; | 331 *(out++) = 0; |
332 } else { | 332 } else { |
333 *(out++) = MODE_REG_INDIRECT | base | (reg << 3); | 333 *(out++) = MODE_REG_INDIRECT | base | (reg << 3); |
334 if (base == RSP) { | 334 if (base == RSP) { |
335 //add SIB byte, with no index and RSP as base | 335 //add SIB byte, with no index and RSP as base |
336 *(out++) = (RSP << 3) | RSP; | 336 *(out++) = (RSP << 3) | RSP; |
337 } | 337 } |
338 } | 338 } |
339 code->cur = out; | 339 code->cur = out; |
340 } | 340 } |
341 | 341 |
342 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) | 342 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) |
381 *(out++) = opcode | dir; | 381 *(out++) = opcode | dir; |
382 *(out++) = MODE_REG_INDIRECT | RSP | (reg << 3); | 382 *(out++) = MODE_REG_INDIRECT | RSP | (reg << 3); |
383 if (scale == 4) { | 383 if (scale == 4) { |
384 scale = 2; | 384 scale = 2; |
385 } else if(scale == 8) { | 385 } else if(scale == 8) { |
386 scale = 3; | 386 scale = 3; |
387 } else { | 387 } else { |
388 scale--; | 388 scale--; |
389 } | 389 } |
390 *(out++) = scale << 6 | (index << 3) | base; | 390 *(out++) = scale << 6 | (index << 3) | base; |
391 code->cur = out; | 391 code->cur = out; |
448 if (size != SZ_B) { | 448 if (size != SZ_B) { |
449 opcode |= BIT_SIZE; | 449 opcode |= BIT_SIZE; |
450 } | 450 } |
451 *(out++) = opcode; | 451 *(out++) = opcode; |
452 if (disp < 128 && disp >= -128) { | 452 if (disp < 128 && disp >= -128) { |
453 *(out++) = MODE_REG_DISPLACE8 | dst | (opex << 3); | 453 *(out++) = MODE_REG_DISPLACE8 | dst | (opex << 3); |
454 *(out++) = disp; | 454 *(out++) = disp; |
455 } else { | 455 } else { |
456 *(out++) = MODE_REG_DISPLACE32 | dst | (opex << 3); | 456 *(out++) = MODE_REG_DISPLACE32 | dst | (opex << 3); |
457 *(out++) = disp; | 457 *(out++) = disp; |
458 *(out++) = disp >> 8; | 458 *(out++) = disp >> 8; |
459 *(out++) = disp >> 16; | 459 *(out++) = disp >> 16; |
544 if (size != SZ_B) { | 544 if (size != SZ_B) { |
545 opcode |= BIT_SIZE; | 545 opcode |= BIT_SIZE; |
546 } | 546 } |
547 *(out++) = opcode; | 547 *(out++) = opcode; |
548 if (disp < 128 && disp >= -128) { | 548 if (disp < 128 && disp >= -128) { |
549 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); | 549 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); |
550 *(out++) = disp; | 550 *(out++) = disp; |
551 } else { | 551 } else { |
552 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3); | 552 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3); |
553 *(out++) = disp; | 553 *(out++) = disp; |
554 disp >>= 8; | 554 disp >>= 8; |
555 *(out++) = disp; | 555 *(out++) = disp; |
556 disp >>= 8; | 556 disp >>= 8; |
557 *(out++) = disp; | 557 *(out++) = disp; |
558 disp >>= 8; | 558 disp >>= 8; |
559 *(out++) = disp; | 559 *(out++) = disp; |
560 } | 560 } |
561 *(out++) = val; | 561 *(out++) = val; |
562 if (size != SZ_B && !sign_extend) { | 562 if (size != SZ_B && !sign_extend) { |
563 val >>= 8; | 563 val >>= 8; |
564 *(out++) = val; | 564 *(out++) = val; |
624 dst -= (AH-X86_AH); | 624 dst -= (AH-X86_AH); |
625 } | 625 } |
626 | 626 |
627 *(out++) = (val == 1 ? OP_SHIFTROT_1: OP_SHIFTROT_IR) | (size == SZ_B ? 0 : BIT_SIZE); | 627 *(out++) = (val == 1 ? OP_SHIFTROT_1: OP_SHIFTROT_IR) | (size == SZ_B ? 0 : BIT_SIZE); |
628 if (disp < 128 && disp >= -128) { | 628 if (disp < 128 && disp >= -128) { |
629 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); | 629 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); |
630 *(out++) = disp; | 630 *(out++) = disp; |
631 } else { | 631 } else { |
632 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3); | 632 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3); |
633 *(out++) = disp; | 633 *(out++) = disp; |
634 *(out++) = disp >> 8; | 634 *(out++) = disp >> 8; |
635 *(out++) = disp >> 16; | 635 *(out++) = disp >> 16; |
690 dst -= (AH-X86_AH); | 690 dst -= (AH-X86_AH); |
691 } | 691 } |
692 | 692 |
693 *(out++) = OP_SHIFTROT_CL | (size == SZ_B ? 0 : BIT_SIZE); | 693 *(out++) = OP_SHIFTROT_CL | (size == SZ_B ? 0 : BIT_SIZE); |
694 if (disp < 128 && disp >= -128) { | 694 if (disp < 128 && disp >= -128) { |
695 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); | 695 *(out++) = MODE_REG_DISPLACE8 | dst | (op_ex << 3); |
696 *(out++) = disp; | 696 *(out++) = disp; |
697 } else { | 697 } else { |
698 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3); | 698 *(out++) = MODE_REG_DISPLACE32 | dst | (op_ex << 3); |
699 *(out++) = disp; | 699 *(out++) = disp; |
700 *(out++) = disp >> 8; | 700 *(out++) = disp >> 8; |
701 *(out++) = disp >> 16; | 701 *(out++) = disp >> 16; |
702 *(out++) = disp >> 24; | 702 *(out++) = disp >> 24; |
703 } | 703 } |
704 code->cur = out; | 704 code->cur = out; |
705 } | 705 } |
706 | 706 |
707 void rol_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size) | 707 void rol_ir(code_info *code, uint8_t val, uint8_t dst, uint8_t size) |
708 { | 708 { |
1251 if (dst >= AH && dst <= BH) { | 1251 if (dst >= AH && dst <= BH) { |
1252 dst -= (AH-X86_AH); | 1252 dst -= (AH-X86_AH); |
1253 } | 1253 } |
1254 *(out++) = OP_MOV_IEA | (size == SZ_B ? 0 : BIT_SIZE); | 1254 *(out++) = OP_MOV_IEA | (size == SZ_B ? 0 : BIT_SIZE); |
1255 if (disp < 128 && disp >= -128) { | 1255 if (disp < 128 && disp >= -128) { |
1256 *(out++) = MODE_REG_DISPLACE8 | dst; | 1256 *(out++) = MODE_REG_DISPLACE8 | dst; |
1257 *(out++) = disp; | 1257 *(out++) = disp; |
1258 } else { | 1258 } else { |
1259 *(out++) = MODE_REG_DISPLACE32 | dst; | 1259 *(out++) = MODE_REG_DISPLACE32 | dst; |
1260 *(out++) = disp; | 1260 *(out++) = disp; |
1261 *(out++) = disp >> 8; | 1261 *(out++) = disp >> 8; |
1262 *(out++) = disp >> 16; | 1262 *(out++) = disp >> 16; |
1374 } else { | 1374 } else { |
1375 *(out++) = PRE_2BYTE; | 1375 *(out++) = PRE_2BYTE; |
1376 *(out++) = OP2_MOVSX | (src_size == SZ_B ? 0 : BIT_SIZE); | 1376 *(out++) = OP2_MOVSX | (src_size == SZ_B ? 0 : BIT_SIZE); |
1377 } | 1377 } |
1378 if (disp < 128 && disp >= -128) { | 1378 if (disp < 128 && disp >= -128) { |
1379 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3); | 1379 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3); |
1380 *(out++) = disp; | 1380 *(out++) = disp; |
1381 } else { | 1381 } else { |
1382 *(out++) = MODE_REG_DISPLACE32 | src | (dst << 3); | 1382 *(out++) = MODE_REG_DISPLACE32 | src | (dst << 3); |
1383 *(out++) = disp; | 1383 *(out++) = disp; |
1384 *(out++) = disp >> 8; | 1384 *(out++) = disp >> 8; |
1385 *(out++) = disp >> 16; | 1385 *(out++) = disp >> 16; |
1439 out++; | 1439 out++; |
1440 } | 1440 } |
1441 *(out++) = PRE_2BYTE; | 1441 *(out++) = PRE_2BYTE; |
1442 *(out++) = OP2_MOVZX | (src_size == SZ_B ? 0 : BIT_SIZE); | 1442 *(out++) = OP2_MOVZX | (src_size == SZ_B ? 0 : BIT_SIZE); |
1443 if (disp < 128 && disp >= -128) { | 1443 if (disp < 128 && disp >= -128) { |
1444 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3); | 1444 *(out++) = MODE_REG_DISPLACE8 | src | (dst << 3); |
1445 *(out++) = disp; | 1445 *(out++) = disp; |
1446 } else { | 1446 } else { |
1447 *(out++) = MODE_REG_DISPLACE32 | src | (dst << 3); | 1447 *(out++) = MODE_REG_DISPLACE32 | src | (dst << 3); |
1448 *(out++) = disp; | 1448 *(out++) = disp; |
1449 *(out++) = disp >> 8; | 1449 *(out++) = disp >> 8; |
1450 *(out++) = disp >> 16; | 1450 *(out++) = disp >> 16; |
1599 dst -= R8 - X86_R8; | 1599 dst -= R8 - X86_R8; |
1600 } | 1600 } |
1601 *(out++) = PRE_2BYTE; | 1601 *(out++) = PRE_2BYTE; |
1602 *(out++) = OP2_SETCC | cc; | 1602 *(out++) = OP2_SETCC | cc; |
1603 if (disp < 128 && disp >= -128) { | 1603 if (disp < 128 && disp >= -128) { |
1604 *(out++) = MODE_REG_DISPLACE8 | dst; | 1604 *(out++) = MODE_REG_DISPLACE8 | dst; |
1605 *(out++) = disp; | 1605 *(out++) = disp; |
1606 } else { | 1606 } else { |
1607 *(out++) = MODE_REG_DISPLACE32 | dst; | 1607 *(out++) = MODE_REG_DISPLACE32 | dst; |
1608 *(out++) = disp; | 1608 *(out++) = disp; |
1609 *(out++) = disp >> 8; | 1609 *(out++) = disp >> 8; |
1610 *(out++) = disp >> 16; | 1610 *(out++) = disp >> 16; |
1664 out++; | 1664 out++; |
1665 } | 1665 } |
1666 *(out++) = PRE_2BYTE; | 1666 *(out++) = PRE_2BYTE; |
1667 *(out++) = op2; | 1667 *(out++) = op2; |
1668 if (dst_disp < 128 && dst_disp >= -128) { | 1668 if (dst_disp < 128 && dst_disp >= -128) { |
1669 *(out++) = MODE_REG_DISPLACE8 | dst_base | (src << 3); | 1669 *(out++) = MODE_REG_DISPLACE8 | dst_base | (src << 3); |
1670 *(out++) = dst_disp; | 1670 *(out++) = dst_disp; |
1671 } else { | 1671 } else { |
1672 *(out++) = MODE_REG_DISPLACE32 | dst_base | (src << 3); | 1672 *(out++) = MODE_REG_DISPLACE32 | dst_base | (src << 3); |
1673 *(out++) = dst_disp; | 1673 *(out++) = dst_disp; |
1674 *(out++) = dst_disp >> 8; | 1674 *(out++) = dst_disp >> 8; |
1675 *(out++) = dst_disp >> 16; | 1675 *(out++) = dst_disp >> 16; |
1676 *(out++) = dst_disp >> 24; | 1676 *(out++) = dst_disp >> 24; |
1677 } | 1677 } |
1678 code->cur = out; | 1678 code->cur = out; |
1679 } | 1679 } |
1680 | 1680 |
1681 void bit_ir(code_info *code, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size) | 1681 void bit_ir(code_info *code, uint8_t op_ex, uint8_t val, uint8_t dst, uint8_t size) |
1722 out++; | 1722 out++; |
1723 } | 1723 } |
1724 *(out++) = PRE_2BYTE; | 1724 *(out++) = PRE_2BYTE; |
1725 *(out++) = OP2_BTX_I; | 1725 *(out++) = OP2_BTX_I; |
1726 if (dst_disp < 128 && dst_disp >= -128) { | 1726 if (dst_disp < 128 && dst_disp >= -128) { |
1727 *(out++) = MODE_REG_DISPLACE8 | dst_base | (op_ex << 3); | 1727 *(out++) = MODE_REG_DISPLACE8 | dst_base | (op_ex << 3); |
1728 *(out++) = dst_disp; | 1728 *(out++) = dst_disp; |
1729 } else { | 1729 } else { |
1730 *(out++) = MODE_REG_DISPLACE32 | dst_base | (op_ex << 3); | 1730 *(out++) = MODE_REG_DISPLACE32 | dst_base | (op_ex << 3); |
1731 *(out++) = dst_disp; | 1731 *(out++) = dst_disp; |
1732 *(out++) = dst_disp >> 8; | 1732 *(out++) = dst_disp >> 8; |
1733 *(out++) = dst_disp >> 16; | 1733 *(out++) = dst_disp >> 16; |