| 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 |