| 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 1171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 // assembler. | 1182 // assembler. |
| 1183 constexpr const char *MovName = "mov"; | 1183 constexpr const char *MovName = "mov"; |
| 1184 IValueT Rd = encodeRegister(OpRd, "Rd", MovName); | 1184 IValueT Rd = encodeRegister(OpRd, "Rd", MovName); |
| 1185 constexpr bool SetFlags = false; | 1185 constexpr bool SetFlags = false; |
| 1186 constexpr IValueT Rn = 0; | 1186 constexpr IValueT Rn = 0; |
| 1187 constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101. | 1187 constexpr IValueT MovOpcode = B3 | B2 | B0; // 1101. |
| 1188 emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, | 1188 emitType01(Cond, MovOpcode, Rd, Rn, OpSrc, SetFlags, RdIsPcAndSetFlags, |
| 1189 MovName); | 1189 MovName); |
| 1190 } | 1190 } |
| 1191 | 1191 |
| 1192 void AssemblerARM32::emitMovw(IValueT Opcode, IValueT Rd, IValueT Imm16, | 1192 void AssemblerARM32::emitMovwt(CondARM32::Cond Cond, bool IsMovW, |
| 1193 bool SetFlags, CondARM32::Cond Cond) { | 1193 const Operand *OpRd, const Operand *OpSrc, |
| 1194 constexpr const char *MovwName = "movw"; | 1194 const char *MovName) { |
| 1195 verifyCondDefined(Cond, MovwName); | 1195 IValueT Opcode = B25 | B24 | (IsMovW ? 0 : B22); |
| 1196 IValueT Rd = encodeRegister(OpRd, "Rd", MovName); |
| 1197 IValueT Imm16; |
| 1198 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) { |
| 1199 emitFixup(createMoveFixup(IsMovW, Src)); |
| 1200 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to |
| 1201 // install the correct bits. |
| 1202 Imm16 = 0; |
| 1203 } else if (encodeOperand(OpSrc, Imm16) != EncodedAsConstI32) { |
| 1204 llvm::report_fatal_error(std::string(MovName) + ": Not i32 constant"); |
| 1205 } |
| 1206 verifyCondDefined(Cond, MovName); |
| 1196 if (!Utils::IsAbsoluteUint(16, Imm16)) | 1207 if (!Utils::IsAbsoluteUint(16, Imm16)) |
| 1197 llvm::report_fatal_error(std::string(MovwName) + ": Not I16 constant"); | 1208 llvm::report_fatal_error(std::string(MovName) + ": Constant not i16"); |
| 1198 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 1209 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 1199 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode | | 1210 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | Opcode | |
| 1200 (encodeBool(SetFlags) << kSShift) | | |
| 1201 ((Imm16 >> 12) << 16) | Rd << kRdShift | | 1211 ((Imm16 >> 12) << 16) | Rd << kRdShift | |
| 1202 (Imm16 & 0xfff); | 1212 (Imm16 & 0xfff); |
| 1203 emitInst(Encoding); | 1213 emitInst(Encoding); |
| 1204 } | 1214 } |
| 1205 | 1215 |
| 1206 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc, | 1216 void AssemblerARM32::movw(const Operand *OpRd, const Operand *OpSrc, |
| 1207 CondARM32::Cond Cond) { | 1217 CondARM32::Cond Cond) { |
| 1218 // MOV (immediate) - ARM section A8.8.102, encoding A2: |
| 1219 // movw<c> <Rd>, #<imm16> |
| 1220 // |
| 1221 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and |
| 1222 // iiiiiiiiiiiiiiii=imm16. |
| 1208 constexpr const char *MovwName = "movw"; | 1223 constexpr const char *MovwName = "movw"; |
| 1209 IValueT Rd = encodeRegister(OpRd, "Rd", MovwName); | 1224 constexpr bool IsMovW = true; |
| 1210 if (const auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc)) { | 1225 emitMovwt(Cond, IsMovW, OpRd, OpSrc, MovwName); |
| 1211 // MOVW (immediate) - ARM section A8.8.102, encoding A2: | |
| 1212 // movw<c> <Rd>, #<imm16> | |
| 1213 // | |
| 1214 // cccc00110000iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and | |
| 1215 // iiiiiiiiiiiiiiii=imm16. | |
| 1216 verifyCondDefined(Cond, MovwName); | |
| 1217 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to | |
| 1218 // install the correct bits. | |
| 1219 constexpr bool IsMovW = true; | |
| 1220 emitFixup(createMoveFixup(IsMovW, Src)); | |
| 1221 constexpr IValueT Imm16 = 0; | |
| 1222 constexpr bool SetFlags = false; | |
| 1223 emitMovw(B25 | B24, Rd, Imm16, SetFlags, Cond); | |
| 1224 return; | |
| 1225 } | |
| 1226 IValueT ConstVal; | |
| 1227 if (encodeOperand(OpSrc, ConstVal) != EncodedAsConstI32) | |
| 1228 llvm::report_fatal_error(std::string(MovwName) + ": Constant not i32"); | |
| 1229 | |
| 1230 // TODO(kschimpf): Determine if we want to handle rotated immediate 8 values | |
| 1231 // to handle cases where the constant is greater than 16 bits (encoding A1 | |
| 1232 // below). For now, handle using encoding A2. | |
| 1233 constexpr bool SetFlags = 0; | |
| 1234 emitMovw(B25 | B24, Rd, ConstVal, SetFlags, Cond); | |
| 1235 return; | |
| 1236 | |
| 1237 // MOVW (immediate) - ARM section A8.8.102, encoding A1: | |
| 1238 // movw<c> <Rd>, #<RotatedImm8> | |
| 1239 // | |
| 1240 // cccc0011101s0000ddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, s=SetFlags=0, | |
| 1241 // and iiiiiiiiiiii is a shift-rotated value defining RotatedImm8. | |
| 1242 } | 1226 } |
| 1243 | 1227 |
| 1244 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc, | 1228 void AssemblerARM32::movt(const Operand *OpRd, const Operand *OpSrc, |
| 1245 CondARM32::Cond Cond) { | 1229 CondARM32::Cond Cond) { |
| 1246 // MOVT - ARM section A8.8.102, encoding A2: | 1230 // MOVT - ARM section A8.8.106, encoding A1: |
| 1247 // movt<c> <Rd>, #<imm16> | 1231 // movt<c> <Rd>, #<imm16> |
| 1248 // | 1232 // |
| 1249 // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and | 1233 // cccc00110100iiiiddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, and |
| 1250 // iiiiiiiiiiiiiiii=imm16. | 1234 // iiiiiiiiiiiiiiii=imm16. |
| 1251 constexpr const char *MovtName = "movt"; | 1235 constexpr const char *MovtName = "movt"; |
| 1252 IValueT Rd = encodeRegister(OpRd, "Rd", MovtName); | |
| 1253 auto *Src = llvm::dyn_cast<ConstantRelocatable>(OpSrc); | |
| 1254 if (!Src) | |
| 1255 // TODO(kschimpf) Figure out what else can appear here. | |
| 1256 return setNeedsTextFixup(); | |
| 1257 verifyCondDefined(Cond, MovtName); | |
| 1258 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | |
| 1259 // Use 0 for the lower 16 bits of the relocatable, and add a fixup to | |
| 1260 // install the correct bits. | |
| 1261 constexpr bool IsMovW = false; | 1236 constexpr bool IsMovW = false; |
| 1262 emitFixup(createMoveFixup(IsMovW, Src)); | 1237 emitMovwt(Cond, IsMovW, OpRd, OpSrc, MovtName); |
| 1263 constexpr IValueT Imm16 = 0; | |
| 1264 const IValueT Encoding = encodeCondition(Cond) << kConditionShift | B25 | | |
| 1265 B24 | B22 | ((Imm16 >> 12) << 16) | Rd << kRdShift | | |
| 1266 (Imm16 & 0xfff); | |
| 1267 emitInst(Encoding); | |
| 1268 } | 1238 } |
| 1269 | 1239 |
| 1270 void AssemblerARM32::mvn(const Operand *OpRd, const Operand *OpSrc, | 1240 void AssemblerARM32::mvn(const Operand *OpRd, const Operand *OpSrc, |
| 1271 CondARM32::Cond Cond) { | 1241 CondARM32::Cond Cond) { |
| 1272 // MVN (immediate) - ARM section A8.8.115, encoding A1: | 1242 // MVN (immediate) - ARM section A8.8.115, encoding A1: |
| 1273 // mvn{s}<c> <Rd>, #<const> | 1243 // mvn{s}<c> <Rd>, #<const> |
| 1274 // | 1244 // |
| 1275 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd, | 1245 // cccc0011111s0000ddddiiiiiiiiiiii where cccc=Cond, s=SetFlags=0, dddd=Rd, |
| 1276 // and iiiiiiiiiiii=const | 1246 // and iiiiiiiiiiii=const |
| 1277 // | 1247 // |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1620 // rr defined (RotationValue) rotate. | 1590 // rr defined (RotationValue) rotate. |
| 1621 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21 | B20; | 1591 constexpr IValueT UxtOpcode = B26 | B25 | B23 | B22 | B21 | B20; |
| 1622 emitUxt(Cond, UxtOpcode, Rd, Rn, Rm, Rotation, UxtName); | 1592 emitUxt(Cond, UxtOpcode, Rd, Rn, Rm, Rotation, UxtName); |
| 1623 return; | 1593 return; |
| 1624 } | 1594 } |
| 1625 } | 1595 } |
| 1626 } | 1596 } |
| 1627 | 1597 |
| 1628 } // end of namespace ARM32 | 1598 } // end of namespace ARM32 |
| 1629 } // end of namespace Ice | 1599 } // end of namespace Ice |
| OLD | NEW |