| 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 |