| 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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 226 if (Offset < 0) { | 226 if (Offset < 0) { |
| 227 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. | 227 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. |
| 228 } else { | 228 } else { |
| 229 Value |= Offset; | 229 Value |= Offset; |
| 230 } | 230 } |
| 231 return Value; | 231 return Value; |
| 232 } | 232 } |
| 233 | 233 |
| 234 // Decodes memory address Opnd, and encodes that information into Value, | 234 // Decodes memory address Opnd, and encodes that information into Value, |
| 235 // based on how ARM represents the address. Returns how the value was encoded. | 235 // based on how ARM represents the address. Returns how the value was encoded. |
| 236 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value) { | 236 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value, |
| 237 const AssemblerARM32::TargetInfo &TInfo) { |
| 237 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { | 238 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { |
| 238 // Should be a stack variable, with an offset. | 239 // Should be a stack variable, with an offset. |
| 239 if (Var->hasReg()) | 240 if (Var->hasReg()) |
| 240 return CantDecode; | 241 return CantDecode; |
| 241 const IOffsetT Offset = Var->getStackOffset(); | 242 IOffsetT Offset = Var->getStackOffset(); |
| 242 if (!Utils::IsAbsoluteUint(12, Offset)) | 243 if (!Utils::IsAbsoluteUint(12, Offset)) |
| 243 return CantDecode; | 244 return CantDecode; |
| 244 RegARM32::GPRRegister BaseReg = RegARM32::Encoded_Reg_sp; | 245 int32_t BaseRegNum = Var->getBaseRegNum(); |
| 245 if (const auto *StackVar = llvm::dyn_cast<StackVariable>(Var)) | 246 if (BaseRegNum == Variable::NoRegister) { |
| 246 BaseReg = decodeGPRRegister(StackVar->getBaseRegNum()); | 247 BaseRegNum = TInfo.FrameOrStackReg; |
| 247 Value = decodeImmRegOffset(BaseReg, Offset, OperandARM32Mem::Offset); | 248 if (!TInfo.HasFramePointer) |
| 249 Offset += TInfo.StackAdjustment; |
| 250 } |
| 251 Value = decodeImmRegOffset(decodeGPRRegister(BaseRegNum), Offset, |
| 252 OperandARM32Mem::Offset); |
| 248 return DecodedAsImmRegOffset; | 253 return DecodedAsImmRegOffset; |
| 249 } | 254 } |
| 250 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { | 255 if (const auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Opnd)) { |
| 251 if (Mem->isRegReg()) | 256 if (Mem->isRegReg()) |
| 252 // TODO(kschimpf) Add this case. | 257 // TODO(kschimpf) Add this case. |
| 253 return CantDecode; | 258 return CantDecode; |
| 254 Variable *Var = Mem->getBase(); | 259 Variable *Var = Mem->getBase(); |
| 255 if (!Var->hasReg()) | 260 if (!Var->hasReg()) |
| 256 return CantDecode; | 261 return CantDecode; |
| 257 ConstantInteger32 *Offset = Mem->getOffset(); | 262 ConstantInteger32 *Offset = Mem->getOffset(); |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 // EOR (Immediate) - ARM section A8.*.46, encoding A1: | 693 // EOR (Immediate) - ARM section A8.*.46, encoding A1: |
| 689 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8 | 694 // eor{s}<c> <Rd>, <Rn>, #RotatedImm8 |
| 690 // | 695 // |
| 691 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, | 696 // cccc0010001snnnnddddiiiiiiiiiiii where cccc=Cond, dddd=Rd, nnnn=Rn, |
| 692 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. | 697 // s=SetFlags and iiiiiiiiiiii=Src1Value defining RotatedImm8. |
| 693 constexpr IValueT Eor = B0; // 0001 | 698 constexpr IValueT Eor = B0; // 0001 |
| 694 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond); | 699 emitType01(Eor, OpRd, OpRn, OpSrc1, SetFlags, Cond); |
| 695 } | 700 } |
| 696 | 701 |
| 697 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, | 702 void AssemblerARM32::ldr(const Operand *OpRt, const Operand *OpAddress, |
| 698 CondARM32::Cond Cond) { | 703 CondARM32::Cond Cond, const TargetInfo &TInfo) { |
| 699 IValueT Rt; | 704 IValueT Rt; |
| 700 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) | 705 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) |
| 701 return setNeedsTextFixup(); | 706 return setNeedsTextFixup(); |
| 702 IValueT Address; | 707 IValueT Address; |
| 703 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) | 708 if (decodeAddress(OpAddress, Address, TInfo) != DecodedAsImmRegOffset) |
| 704 return setNeedsTextFixup(); | 709 return setNeedsTextFixup(); |
| 705 // LDR (immediate) - ARM section A8.8.63, encoding A1: | 710 // LDR (immediate) - ARM section A8.8.63, encoding A1: |
| 706 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 | 711 // ldr<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 |
| 707 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 | 712 // ldr<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 |
| 708 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 | 713 // ldr<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 |
| 709 // | 714 // |
| 710 // LDRB (immediate) - ARM section A8.8.68, encoding A1: | 715 // LDRB (immediate) - ARM section A8.8.68, encoding A1: |
| 711 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 | 716 // ldrb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 |
| 712 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 | 717 // ldrb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 |
| 713 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 | 718 // ldrb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 return setNeedsTextFixup(); | 875 return setNeedsTextFixup(); |
| 871 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || | 876 if (Rd == RegARM32::Encoded_Reg_pc || Rn == RegARM32::Encoded_Reg_pc || |
| 872 Rm == RegARM32::Encoded_Reg_pc) | 877 Rm == RegARM32::Encoded_Reg_pc) |
| 873 llvm::report_fatal_error("Sdiv instruction unpredictable on pc"); | 878 llvm::report_fatal_error("Sdiv instruction unpredictable on pc"); |
| 874 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. | 879 // Assembler registers rd, rn, rm are encoded as rn, rm, rs. |
| 875 constexpr IValueT Opcode = 0; | 880 constexpr IValueT Opcode = 0; |
| 876 emitDivOp(Cond, Opcode, Rd, Rn, Rm); | 881 emitDivOp(Cond, Opcode, Rd, Rn, Rm); |
| 877 } | 882 } |
| 878 | 883 |
| 879 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, | 884 void AssemblerARM32::str(const Operand *OpRt, const Operand *OpAddress, |
| 880 CondARM32::Cond Cond) { | 885 CondARM32::Cond Cond, const TargetInfo &TInfo) { |
| 881 IValueT Rt; | 886 IValueT Rt; |
| 882 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) | 887 if (decodeOperand(OpRt, Rt) != DecodedAsRegister) |
| 883 return setNeedsTextFixup(); | 888 return setNeedsTextFixup(); |
| 884 IValueT Address; | 889 IValueT Address; |
| 885 if (decodeAddress(OpAddress, Address) != DecodedAsImmRegOffset) | 890 if (decodeAddress(OpAddress, Address, TInfo) != DecodedAsImmRegOffset) |
| 886 return setNeedsTextFixup(); | 891 return setNeedsTextFixup(); |
| 887 // STR (immediate) - ARM section A8.8.204, encoding A1: | 892 // STR (immediate) - ARM section A8.8.204, encoding A1: |
| 888 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 | 893 // str<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 |
| 889 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 | 894 // str<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 |
| 890 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 | 895 // str<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 |
| 891 // STRB (immediate) - ARM section A8.8.207, encoding A1: | 896 // STRB (immediate) - ARM section A8.8.207, encoding A1: |
| 892 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 | 897 // strb<c> <Rt>, [<Rn>{, #+/-<imm12>}] ; p=1, w=0 |
| 893 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 | 898 // strb<c> <Rt>, [<Rn>], #+/-<imm12> ; p=1, w=1 |
| 894 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 | 899 // strb<c> <Rt>, [<Rn>, #+/-<imm12>]! ; p=0, w=1 |
| 895 // | 900 // |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1121 if (RdHi == RegARM32::Encoded_Reg_pc || RdLo == RegARM32::Encoded_Reg_pc || | 1126 if (RdHi == RegARM32::Encoded_Reg_pc || RdLo == RegARM32::Encoded_Reg_pc || |
| 1122 Rn == RegARM32::Encoded_Reg_pc || Rm == RegARM32::Encoded_Reg_pc || | 1127 Rn == RegARM32::Encoded_Reg_pc || Rm == RegARM32::Encoded_Reg_pc || |
| 1123 RdHi == RdLo) | 1128 RdHi == RdLo) |
| 1124 llvm::report_fatal_error("Umull instruction unpredictable on pc"); | 1129 llvm::report_fatal_error("Umull instruction unpredictable on pc"); |
| 1125 constexpr bool SetFlags = false; | 1130 constexpr bool SetFlags = false; |
| 1126 emitMulOp(Cond, B23, RdLo, RdHi, Rn, Rm, SetFlags); | 1131 emitMulOp(Cond, B23, RdLo, RdHi, Rn, Rm, SetFlags); |
| 1127 } | 1132 } |
| 1128 | 1133 |
| 1129 } // end of namespace ARM32 | 1134 } // end of namespace ARM32 |
| 1130 } // end of namespace Ice | 1135 } // end of namespace Ice |
| OLD | NEW |