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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 | 294 |
295 } // end of anonymous namespace | 295 } // end of anonymous namespace |
296 | 296 |
297 TargetARM32::TargetARM32(Cfg *Func) | 297 TargetARM32::TargetARM32(Cfg *Func) |
298 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl), | 298 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl), |
299 CPUFeatures(Func->getContext()->getFlags()) {} | 299 CPUFeatures(Func->getContext()->getFlags()) {} |
300 | 300 |
301 void TargetARM32::staticInit(GlobalContext *Ctx) { | 301 void TargetARM32::staticInit(GlobalContext *Ctx) { |
302 RegNumT::setLimit(RegARM32::Reg_NUM); | 302 RegNumT::setLimit(RegARM32::Reg_NUM); |
303 // Limit this size (or do all bitsets need to be the same width)??? | 303 // Limit this size (or do all bitsets need to be the same width)??? |
304 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); | 304 SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); |
305 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); | 305 SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); |
306 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM); | 306 SmallBitVector Float32Registers(RegARM32::Reg_NUM); |
307 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); | 307 SmallBitVector Float64Registers(RegARM32::Reg_NUM); |
308 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); | 308 SmallBitVector VectorRegisters(RegARM32::Reg_NUM); |
309 llvm::SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); | 309 SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); |
310 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); | 310 SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); |
311 const unsigned EncodedReg_q8 = RegARM32::RegTable[RegARM32::Reg_q8].Encoding; | 311 const unsigned EncodedReg_q8 = RegARM32::RegTable[RegARM32::Reg_q8].Encoding; |
312 for (int i = 0; i < RegARM32::Reg_NUM; ++i) { | 312 for (int i = 0; i < RegARM32::Reg_NUM; ++i) { |
313 const auto &Entry = RegARM32::RegTable[i]; | 313 const auto &Entry = RegARM32::RegTable[i]; |
314 IntegerRegisters[i] = Entry.IsInt; | 314 IntegerRegisters[i] = Entry.IsInt; |
315 I64PairRegisters[i] = Entry.IsI64Pair; | 315 I64PairRegisters[i] = Entry.IsI64Pair; |
316 Float32Registers[i] = Entry.IsFP32; | 316 Float32Registers[i] = Entry.IsFP32; |
317 Float64Registers[i] = Entry.IsFP64; | 317 Float64Registers[i] = Entry.IsFP64; |
318 VectorRegisters[i] = Entry.IsVec128; | 318 VectorRegisters[i] = Entry.IsVec128; |
319 RegisterAliases[i].resize(RegARM32::Reg_NUM); | 319 RegisterAliases[i].resize(RegARM32::Reg_NUM); |
320 // TODO(eholk): It would be better to store a QtoS flag in the | 320 // TODO(eholk): It would be better to store a QtoS flag in the |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
917 // We makeReg() here instead of getPhysicalRegister() because the latter ends | 917 // We makeReg() here instead of getPhysicalRegister() because the latter ends |
918 // up creating multi-blocks temporaries that liveness fails to validate. | 918 // up creating multi-blocks temporaries that liveness fails to validate. |
919 auto *PC = makeReg(IceType_i32, RegARM32::Reg_pc); | 919 auto *PC = makeReg(IceType_i32, RegARM32::Reg_pc); |
920 | 920 |
921 auto *AddPcReloc = RelocOffset::create(Ctx); | 921 auto *AddPcReloc = RelocOffset::create(Ctx); |
922 AddPcReloc->setSubtract(true); | 922 AddPcReloc->setSubtract(true); |
923 auto *AddPcLabel = InstARM32Label::create(Func, this); | 923 auto *AddPcLabel = InstARM32Label::create(Func, this); |
924 AddPcLabel->setRelocOffset(AddPcReloc); | 924 AddPcLabel->setRelocOffset(AddPcReloc); |
925 | 925 |
926 const IceString EmitText = Name; | 926 const IceString EmitText = Name; |
927 // We need a -8 in the relocation expression to account for the pc's value | |
928 // read by the first instruction emitted in Finish(PC). | |
929 auto *Imm8 = RelocOffset::create(Ctx, -8); | |
930 | 927 |
931 auto *MovwReloc = RelocOffset::create(Ctx); | 928 auto *MovwReloc = RelocOffset::create(Ctx); |
932 auto *MovwLabel = InstARM32Label::create(Func, this); | 929 auto *MovwLabel = InstARM32Label::create(Func, this); |
933 MovwLabel->setRelocOffset(MovwReloc); | 930 MovwLabel->setRelocOffset(MovwReloc); |
934 | 931 |
935 auto *MovtReloc = RelocOffset::create(Ctx); | 932 auto *MovtReloc = RelocOffset::create(Ctx); |
936 auto *MovtLabel = InstARM32Label::create(Func, this); | 933 auto *MovtLabel = InstARM32Label::create(Func, this); |
937 MovtLabel->setRelocOffset(MovtReloc); | 934 MovtLabel->setRelocOffset(MovtReloc); |
938 | 935 |
939 // The EmitString for these constant relocatables have hardcoded offsets | 936 // The EmitString for these constant relocatables have hardcoded offsets |
940 // attached to them. This could be dangerous if, e.g., we ever implemented | 937 // attached to them. This could be dangerous if, e.g., we ever implemented |
941 // instruction scheduling but llvm-mc currently does not support | 938 // instruction scheduling but llvm-mc currently does not support |
942 // | 939 // |
943 // movw reg, #:lower16:(Symbol - Label - Number) | 940 // movw reg, #:lower16:(Symbol - Label - Number) |
944 // movt reg, #:upper16:(Symbol - Label - Number) | 941 // movt reg, #:upper16:(Symbol - Label - Number) |
945 // | 942 // |
946 // relocations. | 943 // relocations. |
947 auto *CRLower = Ctx->getConstantSym({MovwReloc, AddPcReloc, Imm8}, Name, | 944 static constexpr RelocOffsetT PcOffset = -8; |
| 945 auto *CRLower = Ctx->getConstantSym(PcOffset, {MovwReloc, AddPcReloc}, Name, |
948 EmitText + " -16", SuppressMangling); | 946 EmitText + " -16", SuppressMangling); |
949 auto *CRUpper = Ctx->getConstantSym({MovtReloc, AddPcReloc, Imm8}, Name, | 947 auto *CRUpper = Ctx->getConstantSym(PcOffset, {MovtReloc, AddPcReloc}, Name, |
950 EmitText + " -12", SuppressMangling); | 948 EmitText + " -12", SuppressMangling); |
951 | 949 |
952 Context.insert(MovwLabel); | 950 Context.insert(MovwLabel); |
953 _movw(Register, CRLower); | 951 _movw(Register, CRLower); |
954 Context.insert(MovtLabel); | 952 Context.insert(MovtLabel); |
955 _movt(Register, CRUpper); | 953 _movt(Register, CRUpper); |
956 // PC = fake-def to keep liveness consistent. | 954 // PC = fake-def to keep liveness consistent. |
957 Context.insert<InstFakeDef>(PC); | 955 Context.insert<InstFakeDef>(PC); |
958 Context.insert(AddPcLabel); | 956 Context.insert(AddPcLabel); |
959 Finish(PC); | 957 Finish(PC); |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1433 // registers (as a side effect, this gives variables a second chance at | 1431 // registers (as a side effect, this gives variables a second chance at |
1434 // physical register assignment). | 1432 // physical register assignment). |
1435 // | 1433 // |
1436 // A middle ground approach is to leverage sparsity and allocate one block of | 1434 // A middle ground approach is to leverage sparsity and allocate one block of |
1437 // space on the frame for globals (variables with multi-block lifetime), and | 1435 // space on the frame for globals (variables with multi-block lifetime), and |
1438 // one block to share for locals (single-block lifetime). | 1436 // one block to share for locals (single-block lifetime). |
1439 | 1437 |
1440 Context.init(Node); | 1438 Context.init(Node); |
1441 Context.setInsertPoint(Context.getCur()); | 1439 Context.setInsertPoint(Context.getCur()); |
1442 | 1440 |
1443 llvm::SmallBitVector CalleeSaves = | 1441 SmallBitVector CalleeSaves = getRegisterSet(RegSet_CalleeSave, RegSet_None); |
1444 getRegisterSet(RegSet_CalleeSave, RegSet_None); | 1442 RegsUsed = SmallBitVector(CalleeSaves.size()); |
1445 RegsUsed = llvm::SmallBitVector(CalleeSaves.size()); | |
1446 VarList SortedSpilledVariables; | 1443 VarList SortedSpilledVariables; |
1447 size_t GlobalsSize = 0; | 1444 size_t GlobalsSize = 0; |
1448 // If there is a separate locals area, this represents that area. Otherwise | 1445 // If there is a separate locals area, this represents that area. Otherwise |
1449 // it counts any variable not counted by GlobalsSize. | 1446 // it counts any variable not counted by GlobalsSize. |
1450 SpillAreaSizeBytes = 0; | 1447 SpillAreaSizeBytes = 0; |
1451 // If there is a separate locals area, this specifies the alignment for it. | 1448 // If there is a separate locals area, this specifies the alignment for it. |
1452 uint32_t LocalsSlotsAlignmentBytes = 0; | 1449 uint32_t LocalsSlotsAlignmentBytes = 0; |
1453 // The entire spill locations area gets aligned to largest natural alignment | 1450 // The entire spill locations area gets aligned to largest natural alignment |
1454 // of the variables that have a spill slot. | 1451 // of the variables that have a spill slot. |
1455 uint32_t SpillAreaAlignmentBytes = 0; | 1452 uint32_t SpillAreaAlignmentBytes = 0; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1491 } | 1488 } |
1492 if (!MaybeLeafFunc) { | 1489 if (!MaybeLeafFunc) { |
1493 CalleeSaves[RegARM32::Reg_lr] = true; | 1490 CalleeSaves[RegARM32::Reg_lr] = true; |
1494 RegsUsed[RegARM32::Reg_lr] = true; | 1491 RegsUsed[RegARM32::Reg_lr] = true; |
1495 } | 1492 } |
1496 | 1493 |
1497 // Make two passes over the used registers. The first pass records all the | 1494 // Make two passes over the used registers. The first pass records all the |
1498 // used registers -- and their aliases. Then, we figure out which GPRs and | 1495 // used registers -- and their aliases. Then, we figure out which GPRs and |
1499 // VFP S registers should be saved. We don't bother saving D/Q registers | 1496 // VFP S registers should be saved. We don't bother saving D/Q registers |
1500 // because their uses are recorded as S regs uses. | 1497 // because their uses are recorded as S regs uses. |
1501 llvm::SmallBitVector ToPreserve(RegARM32::Reg_NUM); | 1498 SmallBitVector ToPreserve(RegARM32::Reg_NUM); |
1502 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { | 1499 for (SizeT i = 0; i < CalleeSaves.size(); ++i) { |
1503 if (NeedSandboxing && i == RegARM32::Reg_r9) { | 1500 if (NeedSandboxing && i == RegARM32::Reg_r9) { |
1504 // r9 is never updated in sandboxed code. | 1501 // r9 is never updated in sandboxed code. |
1505 continue; | 1502 continue; |
1506 } | 1503 } |
1507 if (CalleeSaves[i] && RegsUsed[i]) { | 1504 if (CalleeSaves[i] && RegsUsed[i]) { |
1508 ToPreserve |= RegisterAliases[i]; | 1505 ToPreserve |= RegisterAliases[i]; |
1509 } | 1506 } |
1510 } | 1507 } |
1511 | 1508 |
(...skipping 624 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2136 } | 2133 } |
2137 Variable *BaseR = legalizeToReg(Base); | 2134 Variable *BaseR = legalizeToReg(Base); |
2138 return OperandARM32Mem::create(Func, SplitType, BaseR, Offset, | 2135 return OperandARM32Mem::create(Func, SplitType, BaseR, Offset, |
2139 Mem->getAddrMode()); | 2136 Mem->getAddrMode()); |
2140 } | 2137 } |
2141 } | 2138 } |
2142 llvm::report_fatal_error("Unsupported operand type"); | 2139 llvm::report_fatal_error("Unsupported operand type"); |
2143 return nullptr; | 2140 return nullptr; |
2144 } | 2141 } |
2145 | 2142 |
2146 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, | 2143 SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, |
2147 RegSetMask Exclude) const { | 2144 RegSetMask Exclude) const { |
2148 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); | 2145 SmallBitVector Registers(RegARM32::Reg_NUM); |
2149 | 2146 |
2150 for (uint32_t i = 0; i < RegARM32::Reg_NUM; ++i) { | 2147 for (uint32_t i = 0; i < RegARM32::Reg_NUM; ++i) { |
2151 const auto &Entry = RegARM32::RegTable[i]; | 2148 const auto &Entry = RegARM32::RegTable[i]; |
2152 if (Entry.Scratch && (Include & RegSet_CallerSave)) | 2149 if (Entry.Scratch && (Include & RegSet_CallerSave)) |
2153 Registers[i] = true; | 2150 Registers[i] = true; |
2154 if (Entry.Preserved && (Include & RegSet_CalleeSave)) | 2151 if (Entry.Preserved && (Include & RegSet_CalleeSave)) |
2155 Registers[i] = true; | 2152 Registers[i] = true; |
2156 if (Entry.StackPtr && (Include & RegSet_StackPointer)) | 2153 if (Entry.StackPtr && (Include & RegSet_StackPointer)) |
2157 Registers[i] = true; | 2154 Registers[i] = true; |
2158 if (Entry.FramePtr && (Include & RegSet_FramePointer)) | 2155 if (Entry.FramePtr && (Include & RegSet_FramePointer)) |
(...skipping 3887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6046 | 6043 |
6047 void TargetARM32::postLower() { | 6044 void TargetARM32::postLower() { |
6048 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 6045 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
6049 return; | 6046 return; |
6050 markRedefinitions(); | 6047 markRedefinitions(); |
6051 Context.availabilityUpdate(); | 6048 Context.availabilityUpdate(); |
6052 } | 6049 } |
6053 | 6050 |
6054 void TargetARM32::makeRandomRegisterPermutation( | 6051 void TargetARM32::makeRandomRegisterPermutation( |
6055 llvm::SmallVectorImpl<RegNumT> &Permutation, | 6052 llvm::SmallVectorImpl<RegNumT> &Permutation, |
6056 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 6053 const SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
6057 (void)Permutation; | 6054 (void)Permutation; |
6058 (void)ExcludeRegisters; | 6055 (void)ExcludeRegisters; |
6059 (void)Salt; | 6056 (void)Salt; |
6060 UnimplementedError(Func->getContext()->getFlags()); | 6057 UnimplementedError(Func->getContext()->getFlags()); |
6061 } | 6058 } |
6062 | 6059 |
6063 void TargetARM32::emit(const ConstantInteger32 *C) const { | 6060 void TargetARM32::emit(const ConstantInteger32 *C) const { |
6064 if (!BuildDefs::dump()) | 6061 if (!BuildDefs::dump()) |
6065 return; | 6062 return; |
6066 Ostream &Str = Ctx->getStrEmit(); | 6063 Ostream &Str = Ctx->getStrEmit(); |
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6793 << ".eabi_attribute 42, 1 @ Tag_MPextension_use\n" | 6790 << ".eabi_attribute 42, 1 @ Tag_MPextension_use\n" |
6794 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; | 6791 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; |
6795 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { | 6792 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { |
6796 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; | 6793 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; |
6797 } | 6794 } |
6798 // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 6795 // Technically R9 is used for TLS with Sandboxing, and we reserve it. |
6799 // However, for compatibility with current NaCl LLVM, don't claim that. | 6796 // However, for compatibility with current NaCl LLVM, don't claim that. |
6800 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6797 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
6801 } | 6798 } |
6802 | 6799 |
6803 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; | 6800 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; |
6804 llvm::SmallBitVector | 6801 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; |
6805 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; | 6802 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
6806 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | |
6807 | 6803 |
6808 } // end of namespace ARM32 | 6804 } // end of namespace ARM32 |
6809 } // end of namespace Ice | 6805 } // end of namespace Ice |
OLD | NEW |