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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 // Mask to pull out PC offset from branch (b) instruction. | 87 // Mask to pull out PC offset from branch (b) instruction. |
88 static constexpr int kBranchOffsetBits = 24; | 88 static constexpr int kBranchOffsetBits = 24; |
89 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff; | 89 static constexpr IOffsetT kBranchOffsetMask = 0x00ffffff; |
90 | 90 |
91 inline IValueT encodeBool(bool B) { return B ? 1 : 0; } | 91 inline IValueT encodeBool(bool B) { return B ? 1 : 0; } |
92 | 92 |
93 inline IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) { | 93 inline IValueT encodeGPRRegister(RegARM32::GPRRegister Rn) { |
94 return static_cast<IValueT>(Rn); | 94 return static_cast<IValueT>(Rn); |
95 } | 95 } |
96 | 96 |
| 97 inline RegARM32::GPRRegister decodeGPRRegister(IValueT R) { |
| 98 return static_cast<RegARM32::GPRRegister>(R); |
| 99 } |
| 100 |
97 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { | 101 inline bool isGPRRegisterDefined(RegARM32::GPRRegister R) { |
98 return R != RegARM32::Encoded_Not_GPR; | 102 return R != RegARM32::Encoded_Not_GPR; |
99 } | 103 } |
100 | 104 |
101 inline bool isGPRRegisterDefined(IValueT R) { | 105 inline bool isGPRRegisterDefined(IValueT R) { |
102 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); | 106 return R != encodeGPRRegister(RegARM32::Encoded_Not_GPR); |
103 } | 107 } |
104 | 108 |
105 inline bool isConditionDefined(CondARM32::Cond Cond) { | 109 inline bool isConditionDefined(CondARM32::Cond Cond) { |
106 return Cond != CondARM32::kNone; | 110 return Cond != CondARM32::kNone; |
(...skipping 24 matching lines...) Expand all Loading... |
131 return (Value >> Shift) & ((1 << Bits) - 1); | 135 return (Value >> Shift) & ((1 << Bits) - 1); |
132 } | 136 } |
133 | 137 |
134 // Extract out a Bit in Value. | 138 // Extract out a Bit in Value. |
135 inline bool isBitSet(IValueT Bit, IValueT Value) { | 139 inline bool isBitSet(IValueT Bit, IValueT Value) { |
136 return (Value & Bit) == Bit; | 140 return (Value & Bit) == Bit; |
137 } | 141 } |
138 | 142 |
139 // Returns the GPR register at given Shift in Value. | 143 // Returns the GPR register at given Shift in Value. |
140 inline RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) { | 144 inline RegARM32::GPRRegister getGPRReg(IValueT Shift, IValueT Value) { |
141 return static_cast<RegARM32::GPRRegister>((Value >> Shift) & 0xF); | 145 return decodeGPRRegister((Value >> Shift) & 0xF); |
142 } | 146 } |
143 | 147 |
144 // The way an operand was decoded in functions decodeOperand and decodeAddress | 148 // The way an operand was decoded in functions decodeOperand and decodeAddress |
145 // below. | 149 // below. |
146 enum DecodedResult { | 150 enum DecodedResult { |
147 // Unable to decode, value left undefined. | 151 // Unable to decode, value left undefined. |
148 CantDecode = 0, | 152 CantDecode = 0, |
149 // Value is register found. | 153 // Value is register found. |
150 DecodedAsRegister, | 154 DecodedAsRegister, |
151 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 | 155 // Value=rrrriiiiiiii where rrrr is the rotation, and iiiiiiii is the imm8 |
152 // value. | 156 // value. |
153 DecodedAsRotatedImm8, | 157 DecodedAsRotatedImm8, |
154 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, | 158 // i.e. 0000000pu0w0nnnn0000iiiiiiiiiiii where nnnn is the base register Rn, |
155 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to | 159 // p=1 if pre-indexed addressing, u=1 if offset positive, w=1 if writeback to |
156 // Rn should be used, and iiiiiiiiiiii is the offset. | 160 // Rn should be used, and iiiiiiiiiiii is the offset. |
157 DecodedAsImmRegOffset | 161 DecodedAsImmRegOffset |
158 }; | 162 }; |
159 | 163 |
160 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5, | 164 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5, |
161 // tt=Shift, and mmmm=Rm. | 165 // tt=Shift, and mmmm=Rm. |
162 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift, | 166 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift, |
163 IValueT imm5) { | 167 IOffsetT imm5) { |
164 (void)kShiftImmBits; | 168 (void)kShiftImmBits; |
165 assert(imm5 < (1 << kShiftImmBits)); | 169 assert(imm5 < (1 << kShiftImmBits)); |
166 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm; | 170 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm; |
167 } | 171 } |
168 | 172 |
169 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) { | 173 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) { |
170 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { | 174 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
171 if (Var->hasReg()) { | 175 if (Var->hasReg()) { |
172 Value = Var->getRegNum(); | 176 Value = Var->getRegNum(); |
173 return DecodedAsRegister; | 177 return DecodedAsRegister; |
(...skipping 27 matching lines...) Expand all Loading... |
201 // Should be a stack variable, with an offset. | 205 // Should be a stack variable, with an offset. |
202 if (Var->hasReg()) | 206 if (Var->hasReg()) |
203 return CantDecode; | 207 return CantDecode; |
204 const IOffsetT Offset = Var->getStackOffset(); | 208 const IOffsetT Offset = Var->getStackOffset(); |
205 if (!Utils::IsAbsoluteUint(12, Offset)) | 209 if (!Utils::IsAbsoluteUint(12, Offset)) |
206 return CantDecode; | 210 return CantDecode; |
207 Value = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, Offset, | 211 Value = decodeImmRegOffset(RegARM32::Encoded_Reg_sp, Offset, |
208 OperandARM32Mem::Offset); | 212 OperandARM32Mem::Offset); |
209 return DecodedAsImmRegOffset; | 213 return DecodedAsImmRegOffset; |
210 } | 214 } |
| 215 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { |
| 216 if (Mem->isRegReg()) |
| 217 // TODO(kschimpf) Add this case. |
| 218 return CantDecode; |
| 219 Variable *Var = Mem->getBase(); |
| 220 if (!Var->hasReg()) |
| 221 return CantDecode; |
| 222 ConstantInteger32 *Offset = Mem->getOffset(); |
| 223 Value = decodeImmRegOffset(decodeGPRRegister(Var->getRegNum()), |
| 224 Offset->getValue(), Mem->getAddrMode()); |
| 225 return DecodedAsImmRegOffset; |
| 226 } |
211 return CantDecode; | 227 return CantDecode; |
212 } | 228 } |
213 | 229 |
214 // Checks that Offset can fit in imm24 constant of branch (b) instruction. | 230 // Checks that Offset can fit in imm24 constant of branch (b) instruction. |
215 bool canEncodeBranchOffset(IOffsetT Offset) { | 231 bool canEncodeBranchOffset(IOffsetT Offset) { |
216 return Utils::IsAligned(Offset, 4) && | 232 return Utils::IsAligned(Offset, 4) && |
217 Utils::IsInt(kBranchOffsetBits, Offset >> 2); | 233 Utils::IsInt(kBranchOffsetBits, Offset >> 2); |
218 } | 234 } |
219 | 235 |
220 } // end of anonymous namespace | 236 } // end of anonymous namespace |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 // Conditions of rule violated. | 667 // Conditions of rule violated. |
652 return setNeedsTextFixup(); | 668 return setNeedsTextFixup(); |
653 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); | 669 emitType01(Cond, kInstTypeDataImmediate, Sub, SetFlags, Rn, Rd, Src1Value); |
654 return; | 670 return; |
655 } | 671 } |
656 } | 672 } |
657 } | 673 } |
658 | 674 |
659 } // end of namespace ARM32 | 675 } // end of namespace ARM32 |
660 } // end of namespace Ice | 676 } // end of namespace Ice |
OLD | NEW |