OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 // | 4 // |
5 // Modified by the Subzero authors. | 5 // Modified by the Subzero authors. |
6 // | 6 // |
7 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// | 7 //===- subzero/src/assembler_ia32.cpp - Assembler for x86-32 -------------===// |
8 // | 8 // |
9 // The Subzero Code Generator | 9 // The Subzero Code Generator |
10 // | 10 // |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 } | 530 } |
531 | 531 |
532 void AssemblerX86::pandn(Type /* Ty */, XmmRegister dst, const Address &src) { | 532 void AssemblerX86::pandn(Type /* Ty */, XmmRegister dst, const Address &src) { |
533 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 533 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
534 EmitUint8(0x66); | 534 EmitUint8(0x66); |
535 EmitUint8(0x0F); | 535 EmitUint8(0x0F); |
536 EmitUint8(0xDF); | 536 EmitUint8(0xDF); |
537 EmitOperand(dst, src); | 537 EmitOperand(dst, src); |
538 } | 538 } |
539 | 539 |
| 540 void AssemblerX86::pmull(Type Ty, XmmRegister dst, XmmRegister src) { |
| 541 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 542 EmitUint8(0x66); |
| 543 EmitUint8(0x0F); |
| 544 if (Ty == IceType_i16) { |
| 545 EmitUint8(0xD5); |
| 546 } else { |
| 547 assert(Ty == IceType_i32); |
| 548 EmitUint8(0x38); |
| 549 EmitUint8(0x40); |
| 550 } |
| 551 EmitXmmRegisterOperand(dst, src); |
| 552 } |
| 553 |
| 554 void AssemblerX86::pmull(Type Ty, XmmRegister dst, const Address &src) { |
| 555 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 556 EmitUint8(0x66); |
| 557 EmitUint8(0x0F); |
| 558 if (Ty == IceType_i16) { |
| 559 EmitUint8(0xD5); |
| 560 } else { |
| 561 assert(Ty == IceType_i32); |
| 562 EmitUint8(0x38); |
| 563 EmitUint8(0x40); |
| 564 } |
| 565 EmitOperand(dst, src); |
| 566 } |
| 567 |
540 void AssemblerX86::pmuludq(Type /* Ty */, XmmRegister dst, XmmRegister src) { | 568 void AssemblerX86::pmuludq(Type /* Ty */, XmmRegister dst, XmmRegister src) { |
541 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 569 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
542 EmitUint8(0x66); | 570 EmitUint8(0x66); |
543 EmitUint8(0x0F); | 571 EmitUint8(0x0F); |
544 EmitUint8(0xF4); | 572 EmitUint8(0xF4); |
545 EmitXmmRegisterOperand(dst, src); | 573 EmitXmmRegisterOperand(dst, src); |
546 } | 574 } |
547 | 575 |
548 void AssemblerX86::pmuludq(Type /* Ty */, XmmRegister dst, const Address &src) { | 576 void AssemblerX86::pmuludq(Type /* Ty */, XmmRegister dst, const Address &src) { |
549 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 577 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 } | 634 } |
607 | 635 |
608 void AssemblerX86::pxor(Type /* Ty */, XmmRegister dst, const Address &src) { | 636 void AssemblerX86::pxor(Type /* Ty */, XmmRegister dst, const Address &src) { |
609 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 637 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
610 EmitUint8(0x66); | 638 EmitUint8(0x66); |
611 EmitUint8(0x0F); | 639 EmitUint8(0x0F); |
612 EmitUint8(0xEF); | 640 EmitUint8(0xEF); |
613 EmitOperand(dst, src); | 641 EmitOperand(dst, src); |
614 } | 642 } |
615 | 643 |
| 644 void AssemblerX86::psll(Type Ty, XmmRegister dst, XmmRegister src) { |
| 645 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 646 EmitUint8(0x66); |
| 647 EmitUint8(0x0F); |
| 648 if (Ty == IceType_i16) { |
| 649 EmitUint8(0xF1); |
| 650 } else { |
| 651 assert(Ty == IceType_i32); |
| 652 EmitUint8(0xF2); |
| 653 } |
| 654 EmitXmmRegisterOperand(dst, src); |
| 655 } |
| 656 |
| 657 void AssemblerX86::psll(Type Ty, XmmRegister dst, const Address &src) { |
| 658 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 659 EmitUint8(0x66); |
| 660 EmitUint8(0x0F); |
| 661 if (Ty == IceType_i16) { |
| 662 EmitUint8(0xF1); |
| 663 } else { |
| 664 assert(Ty == IceType_i32); |
| 665 EmitUint8(0xF2); |
| 666 } |
| 667 EmitOperand(dst, src); |
| 668 } |
| 669 |
| 670 void AssemblerX86::psll(Type Ty, XmmRegister dst, const Immediate &imm) { |
| 671 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 672 assert(imm.is_int8()); |
| 673 EmitUint8(0x66); |
| 674 EmitUint8(0x0F); |
| 675 if (Ty == IceType_i16) { |
| 676 EmitUint8(0x71); |
| 677 } else { |
| 678 assert(Ty == IceType_i32); |
| 679 EmitUint8(0x72); |
| 680 } |
| 681 EmitRegisterOperand(6, dst); |
| 682 EmitUint8(imm.value() & 0xFF); |
| 683 } |
| 684 |
| 685 void AssemblerX86::psra(Type Ty, XmmRegister dst, XmmRegister src) { |
| 686 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 687 EmitUint8(0x66); |
| 688 EmitUint8(0x0F); |
| 689 if (Ty == IceType_i16) { |
| 690 EmitUint8(0xE1); |
| 691 } else { |
| 692 assert(Ty == IceType_i32); |
| 693 EmitUint8(0xE2); |
| 694 } |
| 695 EmitXmmRegisterOperand(dst, src); |
| 696 } |
| 697 |
| 698 void AssemblerX86::psra(Type Ty, XmmRegister dst, const Address &src) { |
| 699 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 700 EmitUint8(0x66); |
| 701 EmitUint8(0x0F); |
| 702 if (Ty == IceType_i16) { |
| 703 EmitUint8(0xE1); |
| 704 } else { |
| 705 assert(Ty == IceType_i32); |
| 706 EmitUint8(0xE2); |
| 707 } |
| 708 EmitOperand(dst, src); |
| 709 } |
| 710 |
| 711 void AssemblerX86::psra(Type Ty, XmmRegister dst, const Immediate &imm) { |
| 712 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
| 713 assert(imm.is_int8()); |
| 714 EmitUint8(0x66); |
| 715 EmitUint8(0x0F); |
| 716 if (Ty == IceType_i16) { |
| 717 EmitUint8(0x71); |
| 718 } else { |
| 719 assert(Ty == IceType_i32); |
| 720 EmitUint8(0x72); |
| 721 } |
| 722 EmitRegisterOperand(4, dst); |
| 723 EmitUint8(imm.value() & 0xFF); |
| 724 } |
| 725 |
616 // {add,sub,mul,div}ps are given a Ty parameter for consistency with | 726 // {add,sub,mul,div}ps are given a Ty parameter for consistency with |
617 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows | 727 // {add,sub,mul,div}ss. In the future, when the PNaCl ABI allows |
618 // addpd, etc., we can use the Ty parameter to decide on adding | 728 // addpd, etc., we can use the Ty parameter to decide on adding |
619 // a 0x66 prefix. | 729 // a 0x66 prefix. |
620 void AssemblerX86::addps(Type /* Ty */, XmmRegister dst, XmmRegister src) { | 730 void AssemblerX86::addps(Type /* Ty */, XmmRegister dst, XmmRegister src) { |
621 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 731 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
622 EmitUint8(0x0F); | 732 EmitUint8(0x0F); |
623 EmitUint8(0x58); | 733 EmitUint8(0x58); |
624 EmitXmmRegisterOperand(dst, src); | 734 EmitXmmRegisterOperand(dst, src); |
625 } | 735 } |
(...skipping 1006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1632 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1742 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1633 EmitUint8(0x48 + reg); | 1743 EmitUint8(0x48 + reg); |
1634 } | 1744 } |
1635 | 1745 |
1636 void AssemblerX86::decl(const Address &address) { | 1746 void AssemblerX86::decl(const Address &address) { |
1637 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1747 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1638 EmitUint8(0xFF); | 1748 EmitUint8(0xFF); |
1639 EmitOperand(1, address); | 1749 EmitOperand(1, address); |
1640 } | 1750 } |
1641 | 1751 |
1642 void AssemblerX86::shll(GPRRegister reg, const Immediate &imm) { | 1752 void AssemblerX86::rol(Type Ty, GPRRegister reg, const Immediate &imm) { |
1643 EmitGenericShift(4, reg, imm); | 1753 EmitGenericShift(0, Ty, reg, imm); |
1644 } | 1754 } |
1645 | 1755 |
1646 void AssemblerX86::shll(GPRRegister operand, GPRRegister shifter) { | 1756 void AssemblerX86::rol(Type Ty, GPRRegister operand, GPRRegister shifter) { |
1647 EmitGenericShift(4, Operand(operand), shifter); | 1757 EmitGenericShift(0, Ty, Operand(operand), shifter); |
1648 } | 1758 } |
1649 | 1759 |
1650 void AssemblerX86::shll(const Address &operand, GPRRegister shifter) { | 1760 void AssemblerX86::rol(Type Ty, const Address &operand, GPRRegister shifter) { |
1651 EmitGenericShift(4, Operand(operand), shifter); | 1761 EmitGenericShift(0, Ty, operand, shifter); |
1652 } | 1762 } |
1653 | 1763 |
1654 void AssemblerX86::shrl(GPRRegister reg, const Immediate &imm) { | 1764 void AssemblerX86::shl(Type Ty, GPRRegister reg, const Immediate &imm) { |
1655 EmitGenericShift(5, reg, imm); | 1765 EmitGenericShift(4, Ty, reg, imm); |
1656 } | 1766 } |
1657 | 1767 |
1658 void AssemblerX86::shrl(GPRRegister operand, GPRRegister shifter) { | 1768 void AssemblerX86::shl(Type Ty, GPRRegister operand, GPRRegister shifter) { |
1659 EmitGenericShift(5, Operand(operand), shifter); | 1769 EmitGenericShift(4, Ty, Operand(operand), shifter); |
1660 } | 1770 } |
1661 | 1771 |
1662 void AssemblerX86::sarl(GPRRegister reg, const Immediate &imm) { | 1772 void AssemblerX86::shl(Type Ty, const Address &operand, GPRRegister shifter) { |
1663 EmitGenericShift(7, reg, imm); | 1773 EmitGenericShift(4, Ty, operand, shifter); |
1664 } | 1774 } |
1665 | 1775 |
1666 void AssemblerX86::sarl(GPRRegister operand, GPRRegister shifter) { | 1776 void AssemblerX86::shr(Type Ty, GPRRegister reg, const Immediate &imm) { |
1667 EmitGenericShift(7, Operand(operand), shifter); | 1777 EmitGenericShift(5, Ty, reg, imm); |
1668 } | 1778 } |
1669 | 1779 |
1670 void AssemblerX86::sarl(const Address &address, GPRRegister shifter) { | 1780 void AssemblerX86::shr(Type Ty, GPRRegister operand, GPRRegister shifter) { |
1671 EmitGenericShift(7, Operand(address), shifter); | 1781 EmitGenericShift(5, Ty, Operand(operand), shifter); |
| 1782 } |
| 1783 |
| 1784 void AssemblerX86::shr(Type Ty, const Address &operand, GPRRegister shifter) { |
| 1785 EmitGenericShift(5, Ty, operand, shifter); |
| 1786 } |
| 1787 |
| 1788 void AssemblerX86::sar(Type Ty, GPRRegister reg, const Immediate &imm) { |
| 1789 EmitGenericShift(7, Ty, reg, imm); |
| 1790 } |
| 1791 |
| 1792 void AssemblerX86::sar(Type Ty, GPRRegister operand, GPRRegister shifter) { |
| 1793 EmitGenericShift(7, Ty, Operand(operand), shifter); |
| 1794 } |
| 1795 |
| 1796 void AssemblerX86::sar(Type Ty, const Address &address, GPRRegister shifter) { |
| 1797 EmitGenericShift(7, Ty, address, shifter); |
1672 } | 1798 } |
1673 | 1799 |
1674 void AssemblerX86::shld(GPRRegister dst, GPRRegister src) { | 1800 void AssemblerX86::shld(GPRRegister dst, GPRRegister src) { |
1675 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 1801 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
1676 EmitUint8(0x0F); | 1802 EmitUint8(0x0F); |
1677 EmitUint8(0xA5); | 1803 EmitUint8(0xA5); |
1678 EmitRegisterOperand(src, dst); | 1804 EmitRegisterOperand(src, dst); |
1679 } | 1805 } |
1680 | 1806 |
1681 void AssemblerX86::shld(GPRRegister dst, GPRRegister src, | 1807 void AssemblerX86::shld(GPRRegister dst, GPRRegister src, |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2122 label->LinkTo(position); | 2248 label->LinkTo(position); |
2123 } | 2249 } |
2124 | 2250 |
2125 void AssemblerX86::EmitNearLabelLink(Label *label) { | 2251 void AssemblerX86::EmitNearLabelLink(Label *label) { |
2126 assert(!label->IsBound()); | 2252 assert(!label->IsBound()); |
2127 intptr_t position = buffer_.Size(); | 2253 intptr_t position = buffer_.Size(); |
2128 EmitUint8(0); | 2254 EmitUint8(0); |
2129 label->NearLinkTo(position); | 2255 label->NearLinkTo(position); |
2130 } | 2256 } |
2131 | 2257 |
2132 void AssemblerX86::EmitGenericShift(int rm, GPRRegister reg, | 2258 void AssemblerX86::EmitGenericShift(int rm, Type Ty, GPRRegister reg, |
2133 const Immediate &imm) { | 2259 const Immediate &imm) { |
2134 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2260 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2135 assert(imm.is_int8()); | 2261 assert(imm.is_int8()); |
| 2262 if (Ty == IceType_i16) |
| 2263 EmitOperandSizeOverride(); |
2136 if (imm.value() == 1) { | 2264 if (imm.value() == 1) { |
2137 EmitUint8(0xD1); | 2265 EmitUint8(isByteSizedArithType(Ty) ? 0xD0 : 0xD1); |
2138 EmitOperand(rm, Operand(reg)); | 2266 EmitOperand(rm, Operand(reg)); |
2139 } else { | 2267 } else { |
2140 EmitUint8(0xC1); | 2268 EmitUint8(isByteSizedArithType(Ty) ? 0xC0 : 0xC1); |
2141 EmitOperand(rm, Operand(reg)); | 2269 EmitOperand(rm, Operand(reg)); |
2142 EmitUint8(imm.value() & 0xFF); | 2270 EmitUint8(imm.value() & 0xFF); |
2143 } | 2271 } |
2144 } | 2272 } |
2145 | 2273 |
2146 void AssemblerX86::EmitGenericShift(int rm, const Operand &operand, | 2274 void AssemblerX86::EmitGenericShift(int rm, Type Ty, const Operand &operand, |
2147 GPRRegister shifter) { | 2275 GPRRegister shifter) { |
2148 AssemblerBuffer::EnsureCapacity ensured(&buffer_); | 2276 AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
2149 assert(shifter == RegX8632::Encoded_Reg_ecx); | 2277 assert(shifter == RegX8632::Encoded_Reg_ecx); |
2150 (void)shifter; | 2278 (void)shifter; |
2151 EmitUint8(0xD3); | 2279 if (Ty == IceType_i16) |
2152 EmitOperand(rm, Operand(operand)); | 2280 EmitOperandSizeOverride(); |
| 2281 EmitUint8(isByteSizedArithType(Ty) ? 0xD2 : 0xD3); |
| 2282 EmitOperand(rm, operand); |
2153 } | 2283 } |
2154 | 2284 |
2155 } // end of namespace x86 | 2285 } // end of namespace x86 |
2156 } // end of namespace Ice | 2286 } // end of namespace Ice |
OLD | NEW |