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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 static constexpr IValueT kRotateShift = 8; | 83 static constexpr IValueT kRotateShift = 8; |
84 | 84 |
85 // Shift instruction register fields encodings. | 85 // Shift instruction register fields encodings. |
86 static constexpr IValueT kShiftImmShift = 7; | 86 static constexpr IValueT kShiftImmShift = 7; |
87 static constexpr IValueT kShiftImmBits = 5; | 87 static constexpr IValueT kShiftImmBits = 5; |
88 static constexpr IValueT kShiftShift = 5; | 88 static constexpr IValueT kShiftShift = 5; |
89 | 89 |
90 static constexpr IValueT kImmed12Bits = 12; | 90 static constexpr IValueT kImmed12Bits = 12; |
91 static constexpr IValueT kImm12Shift = 0; | 91 static constexpr IValueT kImm12Shift = 0; |
92 | 92 |
| 93 // Rotation instructions (uxtb etc.). |
| 94 static constexpr IValueT kRotationShift = 10; |
| 95 |
93 // Div instruction register field encodings. | 96 // Div instruction register field encodings. |
94 static constexpr IValueT kDivRdShift = 16; | 97 static constexpr IValueT kDivRdShift = 16; |
95 static constexpr IValueT kDivRmShift = 8; | 98 static constexpr IValueT kDivRmShift = 8; |
96 static constexpr IValueT kDivRnShift = 0; | 99 static constexpr IValueT kDivRnShift = 0; |
97 | 100 |
98 // Type of instruction encoding (bits 25-27). See ARM section A5.1 | 101 // Type of instruction encoding (bits 25-27). See ARM section A5.1 |
99 static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000 | 102 static constexpr IValueT kInstTypeDataRegister = 0; // i.e. 000 |
100 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001 | 103 static constexpr IValueT kInstTypeDataImmediate = 1; // i.e. 001 |
101 static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010 | 104 static constexpr IValueT kInstTypeMemImmediate = 2; // i.e. 010 |
102 | 105 |
103 // Offset modifier to current PC for next instruction. The offset is off by 8 | 106 // Offset modifier to current PC for next instruction. The offset is off by 8 |
104 // due to the way the ARM CPUs read PC. | 107 // due to the way the ARM CPUs read PC. |
105 static constexpr IOffsetT kPCReadOffset = 8; | 108 static constexpr IOffsetT kPCReadOffset = 8; |
106 | 109 |
107 // Mask to pull out PC offset from branch (b) instruction. | 110 // Mask to pull out PC offset from branch (b) instruction. |
108 static constexpr int kBranchOffsetBits = 24; | 111 static constexpr int kBranchOffsetBits = 24; |
109 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff; | 112 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff; |
110 | 113 |
111 inline IValueT encodeBool(bool B) { return B ? 1 : 0; } | 114 inline IValueT encodeBool(bool B) { return B ? 1 : 0; } |
112 | 115 |
| 116 inline IValueT encodeRotation(ARM32::AssemblerARM32::RotationValue Value) { |
| 117 return static_cast<IValueT>(Value); |
| 118 } |
| 119 |
113 inline IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) { | 120 inline IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) { |
114 return static_cast<IValueT>(Rn); | 121 return static_cast<IValueT>(Rn); |
115 } | 122 } |
116 | 123 |
117 inline RegARM32::GPRRegister decodeGPRRegister(IValueT R) { | 124 inline RegARM32::GPRRegister decodeGPRRegister(IValueT R) { |
118 return static_cast<RegARM32::GPRRegister>(R); | 125 return static_cast<RegARM32::GPRRegister>(R); |
119 } | 126 } |
120 | 127 |
121 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { | 128 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { |
122 return R != RegARM32::Encoded_Not_GPR; | 129 return R != RegARM32::Encoded_Not_GPR; |
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 !isConditionDefined(Cond)) | 545 !isConditionDefined(Cond)) |
539 return setNeedsTextFixup(); | 546 return setNeedsTextFixup(); |
540 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 547 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
541 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | | 548 IValueT Encoding = Opcode | (encodeCondition(Cond) << kConditionShift) | |
542 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | | 549 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
543 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | | 550 (Rd << kRdShift) | (Rs << kRsShift) | B7 | B4 | |
544 (Rm << kRmShift); | 551 (Rm << kRmShift); |
545 emitInst(Encoding); | 552 emitInst(Encoding); |
546 } | 553 } |
547 | 554 |
| 555 void AssemblerARM32::emitUxt(CondARM32::Cond Cond, IValueT Opcode, IValueT Rd, |
| 556 IValueT Rn, IValueT Rm, RotationValue Rotation) { |
| 557 IValueT Rot = encodeRotation(Rotation); |
| 558 if (!isConditionDefined(Cond) || !Utils::IsUint(2, Rot)) |
| 559 return setNeedsTextFixup(); |
| 560 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 561 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | Opcode | |
| 562 (Rn << kRnShift) | (Rd << kRdShift) | |
| 563 (Rot << kRotationShift) | B6 | B5 | B4 | (Rm << kRmShift); |
| 564 emitInst(Encoding); |
| 565 } |
| 566 |
548 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, | 567 void AssemblerARM32::emitMultiMemOp(CondARM32::Cond Cond, |
549 BlockAddressMode AddressMode, bool IsLoad, | 568 BlockAddressMode AddressMode, bool IsLoad, |
550 IValueT BaseReg, IValueT Registers) { | 569 IValueT BaseReg, IValueT Registers) { |
551 constexpr IValueT NumGPRegisters = 16; | 570 constexpr IValueT NumGPRegisters = 16; |
552 if (!isConditionDefined(Cond) || !isGPRRegisterDefined(BaseReg) || | 571 if (!isConditionDefined(Cond) || !isGPRRegisterDefined(BaseReg) || |
553 Registers >= (1 << NumGPRegisters)) | 572 Registers >= (1 << NumGPRegisters)) |
554 return setNeedsTextFixup(); | 573 return setNeedsTextFixup(); |
555 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 574 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
556 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | | 575 IValueT Encoding = (encodeCondition(Cond) << kConditionShift) | B27 | |
557 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | | 576 AddressMode | (IsLoad ? L : 0) | (BaseReg << kRnShift) | |
(...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 decodeOperand(OpRm, Rm) != DecodedAsRegister) | 1143 decodeOperand(OpRm, Rm) != DecodedAsRegister) |
1125 return setNeedsTextFixup(); | 1144 return setNeedsTextFixup(); |
1126 if (RdHi == RegARM32::Encoded_Reg_pc || RdLo == RegARM32::Encoded_Reg_pc || | 1145 if (RdHi == RegARM32::Encoded_Reg_pc || RdLo == RegARM32::Encoded_Reg_pc || |
1127 Rn == RegARM32::Encoded_Reg_pc || Rm == RegARM32::Encoded_Reg_pc || | 1146 Rn == RegARM32::Encoded_Reg_pc || Rm == RegARM32::Encoded_Reg_pc || |
1128 RdHi == RdLo) | 1147 RdHi == RdLo) |
1129 llvm::report_fatal_error("Umull instruction unpredictable on pc"); | 1148 llvm::report_fatal_error("Umull instruction unpredictable on pc"); |
1130 constexpr bool SetFlags = false; | 1149 constexpr bool SetFlags = false; |
1131 emitMulOp(Cond, B23, RdLo, RdHi, Rn, Rm, SetFlags); | 1150 emitMulOp(Cond, B23, RdLo, RdHi, Rn, Rm, SetFlags); |
1132 } | 1151 } |
1133 | 1152 |
| 1153 void AssemblerARM32::uxt(const Operand *OpRd, const Operand *OpSrc0, |
| 1154 CondARM32::Cond Cond) { |
| 1155 IValueT Rd; |
| 1156 if (decodeOperand(OpRd, Rd) != DecodedAsRegister) |
| 1157 return setNeedsTextFixup(); |
| 1158 // Note: For the moment, we assume no rotation is specified. |
| 1159 RotationValue Rotation = kRotateNone; |
| 1160 constexpr IValueT Rn = RegARM32::Encoded_Reg_pc; |
| 1161 IValueT Rm; |
| 1162 if (decodeOperand(OpSrc0, Rm) != DecodedAsRegister) |
| 1163 return setNeedsTextFixup(); |
| 1164 switch (typeWidthInBytes(OpSrc0->getType())) { |
| 1165 default: |
| 1166 return setNeedsTextFixup(); |
| 1167 case 1: { |
| 1168 // UXTB - ARM section A8.8.274, encoding A1: |
| 1169 // uxtb<c> <Rd>, <Rm>{, <rotate>} |
| 1170 // |
| 1171 // cccc011011101111ddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and |
| 1172 // rr defined (RotationValue) rotate. |
| 1173 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21; |
| 1174 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); |
| 1175 return; |
| 1176 } |
| 1177 case 2: { |
| 1178 // UXTH - ARM section A8.8.276, encoding A1: |
| 1179 // uxth<c> <Rd>< <Rm>{, <rotate>} |
| 1180 // |
| 1181 // cccc01101111nnnnddddrr000111mmmm where cccc=Cond, dddd=Rd, mmmm=Rm, and |
| 1182 // rr defined (RotationValue) rotate. |
| 1183 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; |
| 1184 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); |
| 1185 return; |
| 1186 } |
| 1187 } |
| 1188 } |
| 1189 |
1134 } // end of namespace ARM32 | 1190 } // end of namespace ARM32 |
1135 } // end of namespace Ice | 1191 } // end of namespace Ice |
OLD | NEW |