Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- subzero/src/IceAssemblerARM32.h - Assembler for ARM32 ----*- C++ -*-===// | 1 //===- subzero/src/IceAssemblerARM32.h - 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 // |
| 11 // The Subzero Code Generator | 11 // The Subzero Code Generator |
| 12 // | 12 // |
| 13 // This file is distributed under the University of Illinois Open Source | 13 // This file is distributed under the University of Illinois Open Source |
| 14 // License. See LICENSE.TXT for details. | 14 // License. See LICENSE.TXT for details. |
| 15 // | 15 // |
| 16 //===----------------------------------------------------------------------===// | 16 //===----------------------------------------------------------------------===// |
| 17 /// | 17 /// |
| 18 /// \file | 18 /// \file |
| 19 /// This file implements the Assembler class for ARM32. | 19 /// This file implements the Assembler class for ARM32. |
| 20 /// | 20 /// |
| 21 /// Note: All references to ARM "section" documentation refers to the "ARM | |
| 22 /// Architecture Reference Manual, ARMv7-A and ARMv7-R edition". See: | |
| 23 /// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c | |
| 24 /// | |
| 21 //===----------------------------------------------------------------------===// | 25 //===----------------------------------------------------------------------===// |
| 22 | 26 |
| 23 #ifndef SUBZERO_SRC_ICEASSEMBLERARM32_H | 27 #ifndef SUBZERO_SRC_ICEASSEMBLERARM32_H |
| 24 #define SUBZERO_SRC_ICEASSEMBLERARM32_H | 28 #define SUBZERO_SRC_ICEASSEMBLERARM32_H |
| 25 | 29 |
| 26 #include "IceAssembler.h" | 30 #include "IceAssembler.h" |
| 27 #include "IceConditionCodesARM32.h" | 31 #include "IceConditionCodesARM32.h" |
| 28 #include "IceDefs.h" | 32 #include "IceDefs.h" |
| 29 #include "IceFixups.h" | 33 #include "IceFixups.h" |
| 34 #include "IceInstARM32.h" | |
| 30 #include "IceRegistersARM32.h" | 35 #include "IceRegistersARM32.h" |
| 31 #include "IceTargetLowering.h" | 36 #include "IceTargetLowering.h" |
| 32 | 37 |
| 33 namespace Ice { | 38 namespace Ice { |
| 34 namespace ARM32 { | 39 namespace ARM32 { |
| 35 | 40 |
| 36 class AssemblerARM32 : public Assembler { | 41 class AssemblerARM32 : public Assembler { |
| 37 AssemblerARM32(const AssemblerARM32 &) = delete; | 42 AssemblerARM32(const AssemblerARM32 &) = delete; |
| 38 AssemblerARM32 &operator=(const AssemblerARM32 &) = delete; | 43 AssemblerARM32 &operator=(const AssemblerARM32 &) = delete; |
| 39 | 44 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 67 static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0}; | 72 static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0}; |
| 68 return llvm::ArrayRef<uint8_t>(Padding, 4); | 73 return llvm::ArrayRef<uint8_t>(Padding, 4); |
| 69 } | 74 } |
| 70 | 75 |
| 71 void padWithNop(intptr_t Padding) override { | 76 void padWithNop(intptr_t Padding) override { |
| 72 (void)Padding; | 77 (void)Padding; |
| 73 llvm_unreachable("Not yet implemented."); | 78 llvm_unreachable("Not yet implemented."); |
| 74 } | 79 } |
| 75 | 80 |
| 76 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { | 81 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { |
| 77 (void)NodeNumber; | 82 assert(NodeNumber < CfgNodeLabels.size()); |
| 78 llvm_unreachable("Not yet implemented."); | 83 return CfgNodeLabels[NodeNumber]; |
| 79 } | 84 } |
| 80 | 85 |
| 81 void bindCfgNodeLabel(SizeT NodeNumber) override { | 86 void bindCfgNodeLabel(SizeT NodeNumber) override { |
| 82 assert(!getPreliminary()); | 87 assert(!getPreliminary()); |
| 83 Label *L = getOrCreateCfgNodeLabel(NodeNumber); | 88 Label *L = getOrCreateCfgNodeLabel(NodeNumber); |
| 84 this->bind(L); | 89 this->bind(L); |
| 85 } | 90 } |
| 86 | 91 |
| 87 bool fixupIsPCRel(FixupKind Kind) const override { | 92 bool fixupIsPCRel(FixupKind Kind) const override { |
| 88 (void)Kind; | 93 (void)Kind; |
| 89 llvm_unreachable("Not yet implemented."); | 94 llvm_unreachable("Not yet implemented."); |
| 90 } | 95 } |
| 91 void bind(Label *label); | 96 void bind(Label *label); |
| 92 | 97 |
| 93 void bkpt(uint16_t imm16); | 98 void bkpt(uint16_t Imm16); |
| 94 | 99 |
| 95 void bx(RegARM32::GPRRegister rm, CondARM32::Cond cond = CondARM32::AL); | 100 void mov(RegARM32::GPRRegister Rd, const OperandARM32FlexImm &FlexImm, |
| 101 CondARM32::Cond Cond); | |
| 102 | |
| 103 void bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond = CondARM32::AL); | |
| 96 | 104 |
| 97 static bool classof(const Assembler *Asm) { | 105 static bool classof(const Assembler *Asm) { |
| 98 return Asm->getKind() == Asm_ARM32; | 106 return Asm->getKind() == Asm_ARM32; |
| 99 } | 107 } |
| 100 | 108 |
| 101 private: | 109 private: |
| 102 // Instruction encoding bits. | 110 // Instruction encoding bits. |
| 103 | 111 |
| 104 // halfword (or byte) | 112 // halfword (or byte) |
| 105 static constexpr uint32_t H = 1 << 5; | 113 static constexpr uint32_t H = 1 << 5; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 static constexpr uint32_t B20 = 1 << 20; | 153 static constexpr uint32_t B20 = 1 << 20; |
| 146 static constexpr uint32_t B21 = 1 << 21; | 154 static constexpr uint32_t B21 = 1 << 21; |
| 147 static constexpr uint32_t B22 = 1 << 22; | 155 static constexpr uint32_t B22 = 1 << 22; |
| 148 static constexpr uint32_t B23 = 1 << 23; | 156 static constexpr uint32_t B23 = 1 << 23; |
| 149 static constexpr uint32_t B24 = 1 << 24; | 157 static constexpr uint32_t B24 = 1 << 24; |
| 150 static constexpr uint32_t B25 = 1 << 25; | 158 static constexpr uint32_t B25 = 1 << 25; |
| 151 static constexpr uint32_t B26 = 1 << 26; | 159 static constexpr uint32_t B26 = 1 << 26; |
| 152 static constexpr uint32_t B27 = 1 << 27; | 160 static constexpr uint32_t B27 = 1 << 27; |
| 153 | 161 |
| 154 // Constants used for the decoding or encoding of the individual fields of | 162 // Constants used for the decoding or encoding of the individual fields of |
| 155 // instructions. Based on section A5.1 from the "ARM Architecture Reference | 163 // instructions. Based on ARM section A5.1. |
| 156 // Manual, ARMv7-A and ARMv7-R edition". See: | |
| 157 // http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0406c | |
| 158 static constexpr uint32_t kConditionShift = 28; | 164 static constexpr uint32_t kConditionShift = 28; |
| 159 static constexpr uint32_t kConditionBits = 4; | 165 static constexpr uint32_t kConditionBits = 4; |
| 160 static constexpr uint32_t kTypeShift = 25; | 166 static constexpr uint32_t kTypeShift = 25; |
| 161 static constexpr uint32_t kTypeBits = 3; | 167 static constexpr uint32_t kTypeBits = 3; |
| 162 static constexpr uint32_t kLinkShift = 24; | 168 static constexpr uint32_t kLinkShift = 24; |
| 163 static constexpr uint32_t kLinkBits = 1; | 169 static constexpr uint32_t kLinkBits = 1; |
| 164 static constexpr uint32_t kUShift = 23; | 170 static constexpr uint32_t kUShift = 23; |
| 165 static constexpr uint32_t kUBits = 1; | 171 static constexpr uint32_t kUBits = 1; |
| 166 static constexpr uint32_t kOpcodeShift = 21; | 172 static constexpr uint32_t kOpcodeShift = 21; |
| 167 static constexpr uint32_t kOpcodeBits = 4; | 173 static constexpr uint32_t kOpcodeBits = 4; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 static constexpr uint32_t kCRmBits = 4; | 226 static constexpr uint32_t kCRmBits = 4; |
| 221 static constexpr uint32_t kOpc2Shift = 5; | 227 static constexpr uint32_t kOpc2Shift = 5; |
| 222 static constexpr uint32_t kOpc2Bits = 3; | 228 static constexpr uint32_t kOpc2Bits = 3; |
| 223 static constexpr uint32_t kCoprocShift = 8; | 229 static constexpr uint32_t kCoprocShift = 8; |
| 224 static constexpr uint32_t kCoprocBits = 4; | 230 static constexpr uint32_t kCoprocBits = 4; |
| 225 static constexpr uint32_t kCRnShift = 16; | 231 static constexpr uint32_t kCRnShift = 16; |
| 226 static constexpr uint32_t kCRnBits = 4; | 232 static constexpr uint32_t kCRnBits = 4; |
| 227 static constexpr uint32_t kOpc1Shift = 21; | 233 static constexpr uint32_t kOpc1Shift = 21; |
| 228 static constexpr uint32_t kOpc1Bits = 3; | 234 static constexpr uint32_t kOpc1Bits = 3; |
| 229 | 235 |
| 236 // Types of instructions. | |
| 237 static constexpr uint32_t kInstTypeReg = 0; | |
| 238 static constexpr uint32_t kInstTypeImmediate = 1; | |
| 239 | |
| 230 static constexpr uint32_t kBranchOffsetMask = 0x00ffffff; | 240 static constexpr uint32_t kBranchOffsetMask = 0x00ffffff; |
| 231 | 241 |
| 242 // Converts from bool to bit. | |
|
John
2015/10/12 20:45:27
optional: All of these helpers are part of the ass
Karl
2015/10/12 21:24:56
Done.
| |
| 243 static uint32_t encodeBool(bool b) { return b ? 1 : 0; } | |
| 244 | |
| 245 // Converts rotated immediate into imm12. | |
| 246 static uint32_t encodeImm12FromFlexImm(const OperandARM32FlexImm &FlexImm) { | |
| 247 uint32_t Immed8 = FlexImm.getImm(); | |
| 248 uint32_t Rotate = FlexImm.getRotateAmt(); | |
| 249 assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))); | |
| 250 return (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); | |
| 251 } | |
| 252 | |
| 253 static bool isGPRRegisterDefined(uint32_t R) { | |
| 254 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); | |
| 255 } | |
| 256 | |
| 257 static uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) { | |
| 258 return static_cast<uint32_t>(Rn); | |
| 259 } | |
| 260 | |
| 261 static bool isConditionDefined(CondARM32::Cond Cond) { | |
| 262 return Cond != CondARM32::kNone; | |
| 263 } | |
| 264 | |
| 265 static uint32_t encodeCondition(CondARM32::Cond Cond) { | |
| 266 return static_cast<uint32_t>(Cond); | |
| 267 } | |
| 268 | |
| 232 // A vector of pool-allocated x86 labels for CFG nodes. | 269 // A vector of pool-allocated x86 labels for CFG nodes. |
| 233 using LabelVector = std::vector<Label *>; | 270 using LabelVector = std::vector<Label *>; |
| 234 LabelVector CfgNodeLabels; | 271 LabelVector CfgNodeLabels; |
| 235 | 272 |
| 236 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); | 273 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); |
| 237 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) { | 274 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) { |
| 238 return getOrCreateLabel(NodeNumber, CfgNodeLabels); | 275 return getOrCreateLabel(NodeNumber, CfgNodeLabels); |
| 239 } | 276 } |
| 240 | 277 |
| 241 void emitInt32(int32_t Value) { Buffer.emit<int32_t>(Value); } | 278 void emitInt32(uint32_t Value) { Buffer.emit<uint32_t>(Value); } |
| 279 | |
| 280 // Pattern cccctttoooosnnnnddddiiiiiiiiiiii where cccc=Cond, ttt=Type, | |
| 281 // oooo=Opcode, nnnn=Rn, dddd=Rd, iiiiiiiiiiii=imm12 (See ARM section A5.2.3). | |
| 282 void emitType01(CondARM32::Cond Cond, uint32_t Type, uint32_t Opcode, | |
| 283 bool SetCc, uint32_t Rn, uint32_t Rd, uint32_t imm12); | |
| 242 | 284 |
| 243 static int32_t BkptEncoding(uint16_t imm16) { | 285 static int32_t BkptEncoding(uint16_t imm16) { |
| 244 // bkpt requires that the cond field is AL. | 286 // bkpt requires that the cond field is AL. |
| 245 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and i in imm16 | 287 // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and i in imm16 |
| 246 return (CondARM32::AL << kConditionShift) | B24 | B21 | | 288 return (CondARM32::AL << kConditionShift) | B24 | B21 | |
| 247 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); | 289 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); |
| 248 } | 290 } |
| 249 }; | 291 }; |
| 250 | 292 |
| 251 } // end of namespace ARM32 | 293 } // end of namespace ARM32 |
| 252 } // end of namespace Ice | 294 } // end of namespace Ice |
| 253 | 295 |
| 254 #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H | 296 #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H |
| OLD | NEW |