| OLD | NEW |
| 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// | 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 } | 403 } |
| 404 | 404 |
| 405 void TargetARM32::emitVariable(const Variable *Var) const { | 405 void TargetARM32::emitVariable(const Variable *Var) const { |
| 406 if (!BuildDefs::dump()) | 406 if (!BuildDefs::dump()) |
| 407 return; | 407 return; |
| 408 Ostream &Str = Ctx->getStrEmit(); | 408 Ostream &Str = Ctx->getStrEmit(); |
| 409 if (Var->hasReg()) { | 409 if (Var->hasReg()) { |
| 410 Str << getRegName(Var->getRegNum(), Var->getType()); | 410 Str << getRegName(Var->getRegNum(), Var->getType()); |
| 411 return; | 411 return; |
| 412 } | 412 } |
| 413 if (Var->getWeight().isInf()) { | 413 if (Var->mustHaveReg()) { |
| 414 llvm::report_fatal_error( | 414 llvm::report_fatal_error( |
| 415 "Infinite-weight Variable has no register assigned"); | 415 "Infinite-weight Variable has no register assigned"); |
| 416 } | 416 } |
| 417 int32_t Offset = Var->getStackOffset(); | 417 int32_t Offset = Var->getStackOffset(); |
| 418 int32_t BaseRegNum = Var->getBaseRegNum(); | 418 int32_t BaseRegNum = Var->getBaseRegNum(); |
| 419 if (BaseRegNum == Variable::NoRegister) { | 419 if (BaseRegNum == Variable::NoRegister) { |
| 420 BaseRegNum = getFrameOrStackReg(); | 420 BaseRegNum = getFrameOrStackReg(); |
| 421 if (!hasFramePointer()) | 421 if (!hasFramePointer()) |
| 422 Offset += getStackAdjustment(); | 422 Offset += getStackAdjustment(); |
| 423 } | 423 } |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 if (ShouldSub) | 900 if (ShouldSub) |
| 901 Offset = -Offset; | 901 Offset = -Offset; |
| 902 Operand *OffsetVal = legalize(Ctx->getConstantInt32(Offset), | 902 Operand *OffsetVal = legalize(Ctx->getConstantInt32(Offset), |
| 903 Legal_Reg | Legal_Flex, getReservedTmpReg()); | 903 Legal_Reg | Legal_Flex, getReservedTmpReg()); |
| 904 Variable *ScratchReg = makeReg(IceType_i32, getReservedTmpReg()); | 904 Variable *ScratchReg = makeReg(IceType_i32, getReservedTmpReg()); |
| 905 if (ShouldSub) | 905 if (ShouldSub) |
| 906 _sub(ScratchReg, OrigBaseReg, OffsetVal); | 906 _sub(ScratchReg, OrigBaseReg, OffsetVal); |
| 907 else | 907 else |
| 908 _add(ScratchReg, OrigBaseReg, OffsetVal); | 908 _add(ScratchReg, OrigBaseReg, OffsetVal); |
| 909 StackVariable *NewVar = Func->makeVariable<StackVariable>(stackSlotType()); | 909 StackVariable *NewVar = Func->makeVariable<StackVariable>(stackSlotType()); |
| 910 NewVar->setWeight(RegWeight::Zero); | 910 NewVar->setMustNotHaveReg(); |
| 911 NewVar->setBaseRegNum(ScratchReg->getRegNum()); | 911 NewVar->setBaseRegNum(ScratchReg->getRegNum()); |
| 912 constexpr int32_t NewOffset = 0; | 912 constexpr int32_t NewOffset = 0; |
| 913 NewVar->setStackOffset(NewOffset); | 913 NewVar->setStackOffset(NewOffset); |
| 914 return NewVar; | 914 return NewVar; |
| 915 } | 915 } |
| 916 | 916 |
| 917 void TargetARM32::legalizeStackSlots() { | 917 void TargetARM32::legalizeStackSlots() { |
| 918 // If a stack variable's frame offset doesn't fit, convert from: | 918 // If a stack variable's frame offset doesn't fit, convert from: |
| 919 // ldr X, OFF[SP] | 919 // ldr X, OFF[SP] |
| 920 // to: | 920 // to: |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 } | 977 } |
| 978 if (!Dest->hasReg()) { | 978 if (!Dest->hasReg()) { |
| 979 int32_t Offset = Dest->getStackOffset(); | 979 int32_t Offset = Dest->getStackOffset(); |
| 980 Offset += StackAdjust; | 980 Offset += StackAdjust; |
| 981 if (!isLegalVariableStackOffset(Offset)) { | 981 if (!isLegalVariableStackOffset(Offset)) { |
| 982 if (NewBaseReg) { | 982 if (NewBaseReg) { |
| 983 int32_t OffsetDiff = Offset - NewBaseOffset; | 983 int32_t OffsetDiff = Offset - NewBaseOffset; |
| 984 if (isLegalVariableStackOffset(OffsetDiff)) { | 984 if (isLegalVariableStackOffset(OffsetDiff)) { |
| 985 StackVariable *NewDest = | 985 StackVariable *NewDest = |
| 986 Func->makeVariable<StackVariable>(stackSlotType()); | 986 Func->makeVariable<StackVariable>(stackSlotType()); |
| 987 NewDest->setWeight(RegWeight::Zero); | 987 NewDest->setMustNotHaveReg(); |
| 988 NewDest->setBaseRegNum(NewBaseReg->getBaseRegNum()); | 988 NewDest->setBaseRegNum(NewBaseReg->getBaseRegNum()); |
| 989 NewDest->setStackOffset(OffsetDiff); | 989 NewDest->setStackOffset(OffsetDiff); |
| 990 Variable *NewDestVar = NewDest; | 990 Variable *NewDestVar = NewDest; |
| 991 _mov(NewDestVar, MovInst->getSrc(0)); | 991 _mov(NewDestVar, MovInst->getSrc(0)); |
| 992 MovInst->setDeleted(); | 992 MovInst->setDeleted(); |
| 993 continue; | 993 continue; |
| 994 } | 994 } |
| 995 } | 995 } |
| 996 StackVariable *LegalDest = legalizeVariableSlot(Dest, OrigBaseReg); | 996 StackVariable *LegalDest = legalizeVariableSlot(Dest, OrigBaseReg); |
| 997 assert(LegalDest != Dest); | 997 assert(LegalDest != Dest); |
| 998 Variable *LegalDestVar = LegalDest; | 998 Variable *LegalDestVar = LegalDest; |
| 999 _mov(LegalDestVar, MovInst->getSrc(0)); | 999 _mov(LegalDestVar, MovInst->getSrc(0)); |
| 1000 MovInst->setDeleted(); | 1000 MovInst->setDeleted(); |
| 1001 NewBaseReg = LegalDest; | 1001 NewBaseReg = LegalDest; |
| 1002 NewBaseOffset = Offset; | 1002 NewBaseOffset = Offset; |
| 1003 continue; | 1003 continue; |
| 1004 } | 1004 } |
| 1005 } | 1005 } |
| 1006 assert(MovInst->getSrcSize() == 1); | 1006 assert(MovInst->getSrcSize() == 1); |
| 1007 Variable *Var = llvm::dyn_cast<Variable>(MovInst->getSrc(0)); | 1007 Variable *Var = llvm::dyn_cast<Variable>(MovInst->getSrc(0)); |
| 1008 if (Var && !Var->hasReg()) { | 1008 if (Var && !Var->hasReg()) { |
| 1009 int32_t Offset = Var->getStackOffset(); | 1009 int32_t Offset = Var->getStackOffset(); |
| 1010 Offset += StackAdjust; | 1010 Offset += StackAdjust; |
| 1011 if (!isLegalVariableStackOffset(Offset)) { | 1011 if (!isLegalVariableStackOffset(Offset)) { |
| 1012 if (NewBaseReg) { | 1012 if (NewBaseReg) { |
| 1013 int32_t OffsetDiff = Offset - NewBaseOffset; | 1013 int32_t OffsetDiff = Offset - NewBaseOffset; |
| 1014 if (isLegalVariableStackOffset(OffsetDiff)) { | 1014 if (isLegalVariableStackOffset(OffsetDiff)) { |
| 1015 StackVariable *NewVar = | 1015 StackVariable *NewVar = |
| 1016 Func->makeVariable<StackVariable>(stackSlotType()); | 1016 Func->makeVariable<StackVariable>(stackSlotType()); |
| 1017 NewVar->setWeight(RegWeight::Zero); | 1017 NewVar->setMustNotHaveReg(); |
| 1018 NewVar->setBaseRegNum(NewBaseReg->getBaseRegNum()); | 1018 NewVar->setBaseRegNum(NewBaseReg->getBaseRegNum()); |
| 1019 NewVar->setStackOffset(OffsetDiff); | 1019 NewVar->setStackOffset(OffsetDiff); |
| 1020 _mov(Dest, NewVar); | 1020 _mov(Dest, NewVar); |
| 1021 MovInst->setDeleted(); | 1021 MovInst->setDeleted(); |
| 1022 continue; | 1022 continue; |
| 1023 } | 1023 } |
| 1024 } | 1024 } |
| 1025 StackVariable *LegalVar = legalizeVariableSlot(Var, OrigBaseReg); | 1025 StackVariable *LegalVar = legalizeVariableSlot(Var, OrigBaseReg); |
| 1026 assert(LegalVar != Var); | 1026 assert(LegalVar != Var); |
| 1027 _mov(Dest, LegalVar); | 1027 _mov(Dest, LegalVar); |
| (...skipping 1799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2827 _movt(BaseReg, Offset); | 2827 _movt(BaseReg, Offset); |
| 2828 From = formMemoryOperand(BaseReg, Ty); | 2828 From = formMemoryOperand(BaseReg, Ty); |
| 2829 return copyToReg(From, RegNum); | 2829 return copyToReg(From, RegNum); |
| 2830 } | 2830 } |
| 2831 } | 2831 } |
| 2832 | 2832 |
| 2833 if (auto Var = llvm::dyn_cast<Variable>(From)) { | 2833 if (auto Var = llvm::dyn_cast<Variable>(From)) { |
| 2834 // Check if the variable is guaranteed a physical register. This | 2834 // Check if the variable is guaranteed a physical register. This |
| 2835 // can happen either when the variable is pre-colored or when it is | 2835 // can happen either when the variable is pre-colored or when it is |
| 2836 // assigned infinite weight. | 2836 // assigned infinite weight. |
| 2837 bool MustHaveRegister = (Var->hasReg() || Var->getWeight().isInf()); | 2837 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
| 2838 // We need a new physical register for the operand if: | 2838 // We need a new physical register for the operand if: |
| 2839 // Mem is not allowed and Var isn't guaranteed a physical | 2839 // Mem is not allowed and Var isn't guaranteed a physical |
| 2840 // register, or | 2840 // register, or |
| 2841 // RegNum is required and Var->getRegNum() doesn't match. | 2841 // RegNum is required and Var->getRegNum() doesn't match. |
| 2842 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 2842 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
| 2843 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 2843 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { |
| 2844 From = copyToReg(From, RegNum); | 2844 From = copyToReg(From, RegNum); |
| 2845 } | 2845 } |
| 2846 return From; | 2846 return From; |
| 2847 } | 2847 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2892 return OperandARM32Mem::create( | 2892 return OperandARM32Mem::create( |
| 2893 Func, Ty, Base, | 2893 Func, Ty, Base, |
| 2894 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))); | 2894 llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))); |
| 2895 } | 2895 } |
| 2896 | 2896 |
| 2897 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { | 2897 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { |
| 2898 // There aren't any 64-bit integer registers for ARM32. | 2898 // There aren't any 64-bit integer registers for ARM32. |
| 2899 assert(Type != IceType_i64); | 2899 assert(Type != IceType_i64); |
| 2900 Variable *Reg = Func->makeVariable(Type); | 2900 Variable *Reg = Func->makeVariable(Type); |
| 2901 if (RegNum == Variable::NoRegister) | 2901 if (RegNum == Variable::NoRegister) |
| 2902 Reg->setWeightInfinite(); | 2902 Reg->setMustHaveReg(); |
| 2903 else | 2903 else |
| 2904 Reg->setRegNum(RegNum); | 2904 Reg->setRegNum(RegNum); |
| 2905 return Reg; | 2905 return Reg; |
| 2906 } | 2906 } |
| 2907 | 2907 |
| 2908 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align) { | 2908 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align) { |
| 2909 assert(llvm::isPowerOf2_32(Align)); | 2909 assert(llvm::isPowerOf2_32(Align)); |
| 2910 uint32_t RotateAmt; | 2910 uint32_t RotateAmt; |
| 2911 uint32_t Immed_8; | 2911 uint32_t Immed_8; |
| 2912 Operand *Mask; | 2912 Operand *Mask; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3039 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; | 3039 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; |
| 3040 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { | 3040 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { |
| 3041 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; | 3041 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; |
| 3042 } | 3042 } |
| 3043 // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 3043 // Technically R9 is used for TLS with Sandboxing, and we reserve it. |
| 3044 // However, for compatibility with current NaCl LLVM, don't claim that. | 3044 // However, for compatibility with current NaCl LLVM, don't claim that. |
| 3045 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 3045 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
| 3046 } | 3046 } |
| 3047 | 3047 |
| 3048 } // end of namespace Ice | 3048 } // end of namespace Ice |
| OLD | NEW |