Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// | 1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// |
| 2 // | 2 // |
| 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 4 // for details. All rights reserved. Use of this source code is governed by a | 4 // for details. All rights reserved. Use of this source code is governed by a |
| 5 // BSD-style license that can be found in the LICENSE file. | 5 // BSD-style license that can be found in the LICENSE file. |
| 6 // | 6 // |
| 7 // Modified by the Subzero authors. | 7 // Modified by the Subzero authors. |
| 8 // | 8 // |
| 9 //===----------------------------------------------------------------------===// | 9 //===----------------------------------------------------------------------===// |
| 10 // | 10 // |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 828 verifyRegDefined(Rs, "Rs", InstName); | 828 verifyRegDefined(Rs, "Rs", InstName); |
| 829 verifyCondDefined(Cond, InstName); | 829 verifyCondDefined(Cond, InstName); |
| 830 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 830 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 831 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | | 831 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | |
| 832 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) | | 832 (encodeBool(SetFlags) << kSShift) | (Rn << kRnShift) | |
| 833 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | | 833 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | |
| 834 (Rm << kRmShift); | 834 (Rm << kRmShift); |
| 835 emitInst(Encoding); | 835 emitInst(Encoding); |
| 836 } | 836 } |
| 837 | 837 |
| 838 void AssemblerARM32::emitUxt(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, | |
| 839 IValueT Rn, IValueT Rm, RotationValue Rotation, | |
| 840 const char *InstName) { | |
| 841 verifyCondDefined(Cond, InstName); | |
| 842 IValueT Rot = encodeRotation(Rotation); | |
| 843 if (!Utils::IsUint(2, Rot)) | |
| 844 llvm::report_fatal_error(std::string(InstName) + | |
| 845 ": Illegal rotation value"); | |
| 846 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
| 847 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode | | |
| 848 (Rn << kRnShift) | (Rd << kRdShift) | | |
| 849 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift); | |
| 850 emitInst(Encoding); | |
| 851 } | |
| 852 | |
| 853 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, | 838 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, |
| 854 BlockAddressMode AddressMode, bool IsLoad, | 839 BlockAddressMode AddressMode, bool IsLoad, |
| 855 IValueT BaseReg, IValueT Registers, | 840 IValueT BaseReg, IValueT Registers, |
| 856 const char *InstName) { | 841 const char *InstName) { |
| 857 constexpr IValueT NumGPRegisters = 16; | 842 constexpr IValueT NumGPRegisters = 16; |
| 858 verifyCondDefined(Cond, InstName); | 843 verifyCondDefined(Cond, InstName); |
| 859 verifyRegDefined(BaseReg, "base", InstName); | 844 verifyRegDefined(BaseReg, "base", InstName); |
| 860 if (Registers >= (1 << NumGPRegisters)) | 845 if (Registers >= (1 << NumGPRegisters)) |
| 861 llvm::report_fatal_error(std::string(InstName) + | 846 llvm::report_fatal_error(std::string(InstName) + |
| 862 ": Register set too large"); | 847 ": Register set too large"); |
| 863 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 848 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 864 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | | 849 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | |
| 865 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | | 850 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | |
| 866 Registers; | 851 Registers; |
| 867 emitInst(Encoding); | 852 emitInst(Encoding); |
| 868 } | 853 } |
| 869 | 854 |
| 855 void AssemblerARM32::emitSignExtend(CondARM32::Cond Cond, IValueT Opcode, | |
| 856 const Operand *OpRd, const Operand *OpSrc0, | |
| 857 const char *InstName) { | |
| 858 IValueT Rd = encodeRegister(OpRd, "Rd", InstName); | |
| 859 IValueT Rm = encodeRegister(OpSrc0, "Rm", InstName); | |
| 860 // Note: For the moment, we assume no rotation is specified. | |
| 861 RotationValue Rotation = kRotateNone; | |
| 862 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc; | |
| 863 switch (typeWidthInBytes(OpSrc0->getType())) { | |
| 864 default: | |
| 865 llvm::report_fatal_error(std::string(InstName) + | |
| 866 ": Type of Rm not understood"); | |
|
Jim Stichnoth
2015/12/08 05:57:24
Would be nice to have a "break;" here.
Karl
2015/12/08 19:17:43
Done.
| |
| 867 case 1: { | |
| 868 // SXTB/UXTB - Arm sections A8.8.233 and A8.8.274, encoding A1: | |
| 869 // sxtb<c> <Rd>, <Rm>{, <rotate>} | |
| 870 // uxtb<c> <Rd>, <Rm>{, <rotate>} | |
| 871 // | |
| 872 // ccccxxxxxxxx1111ddddrr000111mmmm where cccc=Cond, xxxxxxxx<<20=Opcode, | |
| 873 // dddd=Rd, mmmm=Rm, and rr defined (RotationValue) rotate. | |
| 874 break; | |
| 875 } | |
| 876 case 2: { | |
| 877 // SXTH/UXTH - ARM sections A8.8.235 and A8.8.276, encoding A1: | |
| 878 // uxth<c> <Rd>< <Rm>{, <rotate>} | |
| 879 // | |
| 880 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and | |
| 881 // rr defined (RotationValue) rotate. | |
| 882 Opcode |= B20; | |
| 883 break; | |
| 884 } | |
| 885 } | |
| 886 | |
| 887 verifyCondDefined(Cond, InstName); | |
| 888 IValueT Rot = encodeRotation(Rotation); | |
| 889 if (!Utils::IsUint(2, Rot)) | |
| 890 llvm::report_fatal_error(std::string(InstName) + | |
| 891 ": Illegal rotation value"); | |
| 892 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
| 893 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode | | |
| 894 (Rn << kRnShift) | (Rd << kRdShift) | | |
| 895 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift); | |
| 896 emitInst(Encoding); | |
| 897 } | |
| 898 | |
| 870 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, | 899 void AssemblerARM32::adc(const Operand *OpRd, const Operand *OpRn, |
| 871 const Operand *OpSrc1, bool SetFlags, | 900 const Operand *OpSrc1, bool SetFlags, |
| 872 CondARM32::Cond Cond) { | 901 CondARM32::Cond Cond) { |
| 873 // ADC (register) - ARM section 18.8.2, encoding A1: | 902 // ADC (register) - ARM section 18.8.2, encoding A1: |
| 874 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | 903 // adc{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 875 // | 904 // |
| 876 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 905 // cccc0000101snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 877 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. | 906 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. |
| 878 // | 907 // |
| 879 // ADC (Immediate) - ARM section A8.8.1, encoding A1: | 908 // ADC (Immediate) - ARM section A8.8.1, encoding A1: |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1503 // rsb{s}<c> <Rd>, <Rn>, <Rm>{, <Shift>} | 1532 // rsb{s}<c> <Rd>, <Rn>, <Rm>{, <Shift>} |
| 1504 // | 1533 // |
| 1505 // cccc0000011snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 1534 // cccc0000011snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 1506 // mmmm=Rm, iiiii=shift, tt==ShiftKind, and s=SetFlags. | 1535 // mmmm=Rm, iiiii=shift, tt==ShiftKind, and s=SetFlags. |
| 1507 constexpr const char *RsbName = "rsb"; | 1536 constexpr const char *RsbName = "rsb"; |
| 1508 constexpr IValueT RsbOpcode = B1 | B0; // 0011 | 1537 constexpr IValueT RsbOpcode = B1 | B0; // 0011 |
| 1509 emitType01(Cond, RsbOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, | 1538 emitType01(Cond, RsbOpcode, OpRd, OpRn, OpSrc1, SetFlags, RdIsPcAndSetFlags, |
| 1510 RsbName); | 1539 RsbName); |
| 1511 } | 1540 } |
| 1512 | 1541 |
| 1542 void AssemblerARM32::sxt(const Operand *OpRd, const Operand *OpSrc0, | |
| 1543 CondARM32::Cond Cond) { | |
| 1544 constexpr const char *SxtName = "sxt"; | |
| 1545 constexpr IValueT SxtOpcode = B26 | B25 | B23 | B21; | |
| 1546 emitSignExtend(Cond, SxtOpcode, OpRd, OpSrc0, SxtName); | |
| 1547 } | |
| 1548 | |
| 1513 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, | 1549 void AssemblerARM32::sub(const Operand *OpRd, const Operand *OpRn, |
| 1514 const Operand *OpSrc1, bool SetFlags, | 1550 const Operand *OpSrc1, bool SetFlags, |
| 1515 CondARM32::Cond Cond) { | 1551 CondARM32::Cond Cond) { |
| 1516 // SUB (register) - ARM section A8.8.223, encoding A1: | 1552 // SUB (register) - ARM section A8.8.223, encoding A1: |
| 1517 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} | 1553 // sub{s}<c> <Rd>, <Rn>, <Rm>{, <shift>} |
| 1518 // SUB (SP minus register): See ARM section 8.8.226, encoding A1: | 1554 // SUB (SP minus register): See ARM section 8.8.226, encoding A1: |
| 1519 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>} | 1555 // sub{s}<c> <Rd>, sp, <Rm>{, <Shift>} |
| 1520 // | 1556 // |
| 1521 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, | 1557 // cccc0000010snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 1522 // mmmm=Rm, iiiii=shift, tt=ShiftKind, and s=SetFlags. | 1558 // mmmm=Rm, iiiii=shift, tt=ShiftKind, and s=SetFlags. |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1590 verifyRegNotPc(Rm, "Rm", UmullName); | 1626 verifyRegNotPc(Rm, "Rm", UmullName); |
| 1591 verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName); | 1627 verifyRegsNotEq(RdHi, "RdHi", RdLo, "RdLo", UmullName); |
| 1592 constexpr IValueT UmullOpcode = B23; | 1628 constexpr IValueT UmullOpcode = B23; |
| 1593 constexpr bool SetFlags = false; | 1629 constexpr bool SetFlags = false; |
| 1594 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName); | 1630 emitMulOp(Cond, UmullOpcode, RdLo, RdHi, Rn, Rm, SetFlags, UmullName); |
| 1595 } | 1631 } |
| 1596 | 1632 |
| 1597 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, | 1633 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, |
| 1598 CondARM32::Cond Cond) { | 1634 CondARM32::Cond Cond) { |
| 1599 constexpr const char *UxtName = "uxt"; | 1635 constexpr const char *UxtName = "uxt"; |
| 1600 IValueT Rd = encodeRegister(OpRd, "Rd", UxtName); | 1636 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; |
| 1601 IValueT Rm = encodeRegister(OpSrc0, "Rm", UxtName); | 1637 emitSignExtend(Cond, UxtOpcode, OpRd, OpSrc0, UxtName); |
| 1602 // Note: For the moment, we assume no rotation is specified. | |
| 1603 RotationValue Rotation = kRotateNone; | |
| 1604 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc; | |
| 1605 switch (typeWidthInBytes(OpSrc0->getType())) { | |
| 1606 default: | |
| 1607 llvm::report_fatal_error("Type of Rm not understood: uxt"); | |
| 1608 case 1: { | |
| 1609 // UXTB - ARM section A8.8.274, encoding A1: | |
| 1610 // uxtb<c> <Rd>, <Rm>{, <rotate>} | |
| 1611 // | |
| 1612 // cccc011011101111ddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and | |
| 1613 // rr defined (RotationValue) rotate. | |
| 1614 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21; | |
| 1615 emitUxt(Cond, UxtOpcode, Rd, Rn, Rm, Rotation, UxtName); | |
| 1616 return; | |
| 1617 } | |
| 1618 case 2: { | |
| 1619 // UXTH - ARM section A8.8.276, encoding A1: | |
| 1620 // uxth<c> <Rd>< <Rm>{, <rotate>} | |
| 1621 // | |
| 1622 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and | |
| 1623 // rr defined (RotationValue) rotate. | |
| 1624 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21 | B20; | |
| 1625 emitUxt(Cond, UxtOpcode, Rd, Rn, Rm, Rotation, UxtName); | |
| 1626 return; | |
| 1627 } | |
| 1628 } | |
| 1629 } | 1638 } |
| 1630 | 1639 |
| 1631 } // end of namespace ARM32 | 1640 } // end of namespace ARM32 |
| 1632 } // end of namespace Ice | 1641 } // end of namespace Ice |
| OLD | NEW |