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 // |
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 //===----------------------------------------------------------------------===// | 21 //===----------------------------------------------------------------------===// |
22 | 22 |
23 #include "IceAssemblerARM32.h" | 23 #include "IceAssemblerARM32.h" |
24 | 24 |
25 namespace Ice { | 25 namespace Ice { |
26 | 26 |
| 27 // The following define individual bits. |
| 28 static constexpr uint32_t B0 = 1; |
| 29 static constexpr uint32_t B2 = 1 << 2; |
| 30 static constexpr uint32_t B3 = 1 << 3; |
| 31 static constexpr uint32_t B4 = 1 << 4; |
| 32 static constexpr uint32_t B5 = 1 << 5; |
| 33 static constexpr uint32_t B6 = 1 << 6; |
| 34 static constexpr uint32_t B21 = 1 << 21; |
| 35 static constexpr uint32_t B24 = 1 << 24; |
| 36 |
| 37 // Constants used for the decoding or encoding of the individual fields of |
| 38 // instructions. Based on ARM section A5.1. |
| 39 static constexpr uint32_t kConditionShift = 28; |
| 40 static constexpr uint32_t kOpcodeShift = 21; |
| 41 static constexpr uint32_t kRdShift = 12; |
| 42 static constexpr uint32_t kRmShift = 0; |
| 43 static constexpr uint32_t kRnShift = 16; |
| 44 static constexpr uint32_t kSShift = 20; |
| 45 static constexpr uint32_t kTypeShift = 25; |
| 46 |
| 47 // Immediate instruction fields encoding. |
| 48 static constexpr uint32_t kImmed8Bits = 8; |
| 49 static constexpr uint32_t kImmed8Shift = 0; |
| 50 static constexpr uint32_t kRotateBits = 4; |
| 51 static constexpr uint32_t kRotateShift = 8; |
| 52 |
| 53 // Types of instructions. |
| 54 static constexpr uint32_t kInstTypeImmediate = 1; |
| 55 |
| 56 inline uint32_t encodeBool(bool b) { return b ? 1 : 0; } |
| 57 |
| 58 inline uint32_t encodeGPRRegister(RegARM32::GPRRegister Rn) { |
| 59 return static_cast<uint32_t>(Rn); |
| 60 } |
| 61 |
| 62 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { |
| 63 return R != RegARM32::Encoded_Not_GPR; |
| 64 } |
| 65 |
| 66 inline bool isGPRRegisterDefined(uint32_t R) { |
| 67 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); |
| 68 } |
| 69 |
| 70 inline bool isConditionDefined(CondARM32::Cond Cond) { |
| 71 return Cond != CondARM32::kNone; |
| 72 } |
| 73 |
| 74 inline uint32_t encodeCondition(CondARM32::Cond Cond) { |
| 75 return static_cast<uint32_t>(Cond); |
| 76 } |
| 77 |
| 78 // Converts rotated immediate into imm12. |
| 79 inline uint32_t encodeImm12FromFlexImm(const OperandARM32FlexImm &FlexImm) { |
| 80 uint32_t Immed8 = FlexImm.getImm(); |
| 81 uint32_t Rotate = FlexImm.getRotateAmt(); |
| 82 assert((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))); |
| 83 return (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); |
| 84 } |
| 85 |
27 Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number, | 86 Label *ARM32::AssemblerARM32::getOrCreateLabel(SizeT Number, |
28 LabelVector &Labels) { | 87 LabelVector &Labels) { |
29 Label *L = nullptr; | 88 Label *L = nullptr; |
30 if (Number == Labels.size()) { | 89 if (Number == Labels.size()) { |
31 L = new (this->allocate<Label>()) Label(); | 90 L = new (this->allocate<Label>()) Label(); |
32 Labels.push_back(L); | 91 Labels.push_back(L); |
33 return L; | 92 return L; |
34 } | 93 } |
35 if (Number > Labels.size()) { | 94 if (Number > Labels.size()) { |
36 Labels.resize(Number + 1); | 95 Labels.resize(Number + 1); |
(...skipping 12 matching lines...) Expand all Loading... |
49 while (label->isLinked()) { | 108 while (label->isLinked()) { |
50 intptr_t position = label->getLinkPosition(); | 109 intptr_t position = label->getLinkPosition(); |
51 intptr_t next = Buffer.load<int32_t>(position); | 110 intptr_t next = Buffer.load<int32_t>(position); |
52 Buffer.store<int32_t>(position, bound - (position + 4)); | 111 Buffer.store<int32_t>(position, bound - (position + 4)); |
53 label->setPosition(next); | 112 label->setPosition(next); |
54 } | 113 } |
55 // TODO(kschimpf) Decide if we have near jumps. | 114 // TODO(kschimpf) Decide if we have near jumps. |
56 label->bindTo(bound); | 115 label->bindTo(bound); |
57 } | 116 } |
58 | 117 |
| 118 void ARM32::AssemblerARM32::emitType01(CondARM32::Cond Cond, uint32_t Type, |
| 119 uint32_t Opcode, bool SetCc, uint32_t Rn, |
| 120 uint32_t Rd, uint32_t Imm12) { |
| 121 assert(isGPRRegisterDefined(Rd)); |
| 122 assert(Cond != CondARM32::kNone); |
| 123 uint32_t Encoding = encodeCondition(Cond) << kConditionShift | |
| 124 (Type << kTypeShift) | (Opcode << kOpcodeShift) | |
| 125 (encodeBool(SetCc) << kSShift) | (Rn << kRnShift) | |
| 126 (Rd << kRdShift) | Imm12; |
| 127 emitInst(Encoding); |
| 128 } |
| 129 |
59 void ARM32::AssemblerARM32::bkpt(uint16_t imm16) { | 130 void ARM32::AssemblerARM32::bkpt(uint16_t imm16) { |
60 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 131 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
61 emitInt32(BkptEncoding(imm16)); | 132 uint32_t Encoding = (CondARM32::AL << kConditionShift) | B24 | B21 | |
| 133 ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); |
| 134 emitInst(Encoding); |
62 } | 135 } |
63 | 136 |
64 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister rm, CondARM32::Cond cond) { | 137 void ARM32::AssemblerARM32::bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond) { |
65 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. | 138 // cccc000100101111111111110001mmmm where mmmm=rm and cccc=Cond. |
66 assert(rm != RegARM32::Encoded_Not_GPR); | 139 // (ARM section A8.8.27, encoding A1). |
67 assert(cond != CondARM32::kNone); | 140 assert(isGPRRegisterDefined(Rm)); |
| 141 assert(isConditionDefined(Cond)); |
68 AssemblerBuffer::EnsureCapacity ensured(&Buffer); | 142 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
69 int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | B24 | | 143 uint32_t Encoding = (encodeCondition(Cond) << kConditionShift) | B24 | B21 | |
70 B21 | (0xfff << 8) | B4 | | 144 (0xfff << 8) | B4 | (encodeGPRRegister(Rm) << kRmShift); |
71 (static_cast<int32_t>(rm) << kRmShift); | 145 emitInst(Encoding); |
72 emitInt32(encoding); | 146 } |
| 147 |
| 148 void ARM32::AssemblerARM32::mov(RegARM32::GPRRegister Rd, |
| 149 const OperandARM32FlexImm &FlexImm, |
| 150 CondARM32::Cond Cond) { |
| 151 // cccc0011101s0000ddddiiiiiiiiiiii (ARM section A8.8.102, encoding A1) |
| 152 assert(isConditionDefined(Cond)); |
| 153 AssemblerBuffer::EnsureCapacity ensured(&Buffer); |
| 154 bool SetCc = false; // Note: We don't use movs in this assembler. |
| 155 uint32_t Rn = 0; |
| 156 uint32_t Mov = B3 | B2 | B0; // 1101. |
| 157 emitType01(Cond, kInstTypeImmediate, Mov, SetCc, Rn, encodeGPRRegister(Rd), |
| 158 encodeImm12FromFlexImm(FlexImm)); |
73 } | 159 } |
74 | 160 |
75 } // end of namespace Ice | 161 } // end of namespace Ice |
OLD | NEW |