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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 createTargetHeaderLowering(::Ice::GlobalContext *Ctx) { | 49 createTargetHeaderLowering(::Ice::GlobalContext *Ctx) { |
50 return ::Ice::ARM32::TargetHeaderARM32::create(Ctx); | 50 return ::Ice::ARM32::TargetHeaderARM32::create(Ctx); |
51 } | 51 } |
52 | 52 |
53 void staticInit() { ::Ice::ARM32::TargetARM32::staticInit(); } | 53 void staticInit() { ::Ice::ARM32::TargetARM32::staticInit(); } |
54 } // end of namespace ARM32 | 54 } // end of namespace ARM32 |
55 | 55 |
56 namespace Ice { | 56 namespace Ice { |
57 namespace ARM32 { | 57 namespace ARM32 { |
58 | 58 |
59 // Defines the RegARM32::Table table with register information. | |
60 constexpr RegARM32::TableType RegARM32::Table[]; | |
Karl
2016/01/04 21:10:45
Does this generate another copy for use below?
John
2016/01/04 21:45:12
This is the definition for the array declaration.
| |
61 | |
59 namespace { | 62 namespace { |
60 | 63 |
61 // The following table summarizes the logic for lowering the icmp instruction | 64 // The following table summarizes the logic for lowering the icmp instruction |
62 // for i32 and narrower types. Each icmp condition has a clear mapping to an | 65 // for i32 and narrower types. Each icmp condition has a clear mapping to an |
63 // ARM32 conditional move instruction. | 66 // ARM32 conditional move instruction. |
64 | 67 |
65 const struct TableIcmp32_ { | 68 const struct TableIcmp32_ { |
66 CondARM32::Cond Mapping; | 69 CondARM32::Cond Mapping; |
67 } TableIcmp32[] = { | 70 } TableIcmp32[] = { |
68 #define X(val, is_signed, swapped64, C_32, C1_64, C2_64) \ | 71 #define X(val, is_signed, swapped64, C_32, C1_64, C2_64) \ |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 | 235 |
233 void TargetARM32::staticInit() { | 236 void TargetARM32::staticInit() { |
234 // Limit this size (or do all bitsets need to be the same width)??? | 237 // Limit this size (or do all bitsets need to be the same width)??? |
235 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); | 238 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); |
236 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); | 239 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); |
237 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM); | 240 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM); |
238 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); | 241 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); |
239 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); | 242 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); |
240 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); | 243 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); |
241 ScratchRegs.resize(RegARM32::Reg_NUM); | 244 ScratchRegs.resize(RegARM32::Reg_NUM); |
242 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 245 for (int i = 0; i < RegARM32::Reg_NUM; ++i) { |
243 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 246 const auto &Entry = RegARM32::Table[i]; |
244 IntegerRegisters[RegARM32::val] = isInt; \ | 247 IntegerRegisters[i] = Entry.IsInt; |
245 I64PairRegisters[RegARM32::val] = isI64Pair; \ | 248 I64PairRegisters[i] = Entry.IsI64Pair; |
246 Float32Registers[RegARM32::val] = isFP32; \ | 249 Float32Registers[i] = Entry.IsFP32; |
247 Float64Registers[RegARM32::val] = isFP64; \ | 250 Float64Registers[i] = Entry.IsFP64; |
248 VectorRegisters[RegARM32::val] = isVec128; \ | 251 VectorRegisters[i] = Entry.IsVec128; |
249 RegisterAliases[RegARM32::val].resize(RegARM32::Reg_NUM); \ | 252 ScratchRegs[i] = Entry.Scratch; |
250 for (SizeT RegAlias : alias_init) { \ | 253 RegisterAliases[i].resize(RegARM32::Reg_NUM); |
251 assert((!RegisterAliases[RegARM32::val][RegAlias] || \ | 254 for (int j = 0; j < Entry.NumAliases; ++j) { |
252 RegAlias != RegARM32::val) && \ | 255 assert(i == j || !RegisterAliases[i][Entry.Aliases[j]]); |
253 "Duplicate alias for " #val); \ | 256 RegisterAliases[i].set(Entry.Aliases[j]); |
254 RegisterAliases[RegARM32::val].set(RegAlias); \ | 257 } |
255 } \ | 258 assert(RegisterAliases[i][i]); |
256 RegisterAliases[RegARM32::val].set(RegARM32::val); \ | 259 if (Entry.CCArg <= 0) { |
257 ScratchRegs[RegARM32::val] = scratch; \ | 260 continue; |
258 if ((isInt) && (cc_arg) > 0) { \ | 261 } |
259 GPRArgInitializer[(cc_arg)-1] = RegARM32::val; \ | 262 if (Entry.IsGPR) { |
260 } else if ((isI64Pair) && (cc_arg) > 0) { \ | 263 GPRArgInitializer[Entry.CCArg - 1] = i; |
261 I64ArgInitializer[(cc_arg)-1] = RegARM32::val; \ | 264 } else if (Entry.IsI64Pair) { |
262 } else if ((isFP32) && (cc_arg) > 0) { \ | 265 I64ArgInitializer[Entry.CCArg - 1] = i; |
263 FP32ArgInitializer[(cc_arg)-1] = RegARM32::val; \ | 266 } else if (Entry.IsFP32) { |
264 } else if ((isFP64) && (cc_arg) > 0) { \ | 267 FP32ArgInitializer[Entry.CCArg - 1] = i; |
265 FP64ArgInitializer[(cc_arg)-1] = RegARM32::val; \ | 268 } else if (Entry.IsFP64) { |
266 } else if ((isVec128) && (cc_arg) > 0) { \ | 269 FP64ArgInitializer[Entry.CCArg - 1] = i; |
267 Vec128ArgInitializer[(cc_arg)-1] = RegARM32::val; \ | 270 } else if (Entry.IsVec128) { |
271 Vec128ArgInitializer[Entry.CCArg - 1] = i; | |
272 } | |
268 } | 273 } |
269 REGARM32_TABLE; | |
270 #undef X | |
271 TypeToRegisterSet[IceType_void] = InvalidRegisters; | 274 TypeToRegisterSet[IceType_void] = InvalidRegisters; |
272 TypeToRegisterSet[IceType_i1] = IntegerRegisters; | 275 TypeToRegisterSet[IceType_i1] = IntegerRegisters; |
273 TypeToRegisterSet[IceType_i8] = IntegerRegisters; | 276 TypeToRegisterSet[IceType_i8] = IntegerRegisters; |
274 TypeToRegisterSet[IceType_i16] = IntegerRegisters; | 277 TypeToRegisterSet[IceType_i16] = IntegerRegisters; |
275 TypeToRegisterSet[IceType_i32] = IntegerRegisters; | 278 TypeToRegisterSet[IceType_i32] = IntegerRegisters; |
276 TypeToRegisterSet[IceType_i64] = I64PairRegisters; | 279 TypeToRegisterSet[IceType_i64] = I64PairRegisters; |
277 TypeToRegisterSet[IceType_f32] = Float32Registers; | 280 TypeToRegisterSet[IceType_f32] = Float32Registers; |
278 TypeToRegisterSet[IceType_f64] = Float64Registers; | 281 TypeToRegisterSet[IceType_f64] = Float64Registers; |
279 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; | 282 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; |
280 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; | 283 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
820 return ARM32_STACK_ALIGNMENT_BYTES; | 823 return ARM32_STACK_ALIGNMENT_BYTES; |
821 } | 824 } |
822 | 825 |
823 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { | 826 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { |
824 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { | 827 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { |
825 return Br->optimizeBranch(NextNode); | 828 return Br->optimizeBranch(NextNode); |
826 } | 829 } |
827 return false; | 830 return false; |
828 } | 831 } |
829 | 832 |
830 const char *RegARM32::RegNames[] = { | |
831 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | |
832 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | |
833 name, | |
834 REGARM32_TABLE | |
835 #undef X | |
836 }; | |
837 | |
838 IceString TargetARM32::getRegName(SizeT RegNum, Type Ty) const { | 833 IceString TargetARM32::getRegName(SizeT RegNum, Type Ty) const { |
839 assert(RegNum < RegARM32::Reg_NUM); | 834 assert(RegNum < RegARM32::Reg_NUM); |
840 (void)Ty; | 835 (void)Ty; |
841 return RegARM32::RegNames[RegNum]; | 836 return RegARM32::getRegName(RegNum); |
842 } | 837 } |
843 | 838 |
844 Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) { | 839 Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) { |
845 static const Type DefaultType[] = { | 840 static const Type DefaultType[] = { |
846 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 841 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
847 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 842 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
848 (isFP32) \ | 843 (isFP32) \ |
849 ? IceType_f32 \ | 844 ? IceType_f32 \ |
850 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), | 845 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), |
851 REGARM32_TABLE | 846 REGARM32_TABLE |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1827 } | 1822 } |
1828 } | 1823 } |
1829 llvm::report_fatal_error("Unsupported operand type"); | 1824 llvm::report_fatal_error("Unsupported operand type"); |
1830 return nullptr; | 1825 return nullptr; |
1831 } | 1826 } |
1832 | 1827 |
1833 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, | 1828 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, |
1834 RegSetMask Exclude) const { | 1829 RegSetMask Exclude) const { |
1835 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); | 1830 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); |
1836 | 1831 |
1837 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 1832 for (int i = 0; i < RegARM32::Reg_NUM; ++i) { |
1838 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 1833 const auto &Entry = RegARM32::Table[i]; |
1839 if (scratch && (Include & RegSet_CallerSave)) \ | 1834 if (Entry.Scratch && (Include & RegSet_CallerSave)) |
1840 Registers[RegARM32::val] = true; \ | 1835 Registers[i] = true; |
1841 if (preserved && (Include & RegSet_CalleeSave)) \ | 1836 if (Entry.Preserved && (Include & RegSet_CalleeSave)) |
1842 Registers[RegARM32::val] = true; \ | 1837 Registers[i] = true; |
1843 if (stackptr && (Include & RegSet_StackPointer)) \ | 1838 if (Entry.StackPtr && (Include & RegSet_StackPointer)) |
1844 Registers[RegARM32::val] = true; \ | 1839 Registers[i] = true; |
1845 if (frameptr && (Include & RegSet_FramePointer)) \ | 1840 if (Entry.FramePtr && (Include & RegSet_FramePointer)) |
1846 Registers[RegARM32::val] = true; \ | 1841 Registers[i] = true; |
1847 if (scratch && (Exclude & RegSet_CallerSave)) \ | 1842 if (Entry.Scratch && (Exclude & RegSet_CallerSave)) |
1848 Registers[RegARM32::val] = false; \ | 1843 Registers[i] = false; |
1849 if (preserved && (Exclude & RegSet_CalleeSave)) \ | 1844 if (Entry.Preserved && (Exclude & RegSet_CalleeSave)) |
1850 Registers[RegARM32::val] = false; \ | 1845 Registers[i] = false; |
1851 if (stackptr && (Exclude & RegSet_StackPointer)) \ | 1846 if (Entry.StackPtr && (Exclude & RegSet_StackPointer)) |
1852 Registers[RegARM32::val] = false; \ | 1847 Registers[i] = false; |
1853 if (frameptr && (Exclude & RegSet_FramePointer)) \ | 1848 if (Entry.FramePtr && (Exclude & RegSet_FramePointer)) |
1854 Registers[RegARM32::val] = false; | 1849 Registers[i] = false; |
1855 | 1850 } |
1856 REGARM32_TABLE | |
1857 | |
1858 #undef X | |
1859 | 1851 |
1860 return Registers; | 1852 return Registers; |
1861 } | 1853 } |
1862 | 1854 |
1863 void TargetARM32::lowerAlloca(const InstAlloca *Inst) { | 1855 void TargetARM32::lowerAlloca(const InstAlloca *Inst) { |
1864 // Conservatively require the stack to be aligned. Some stack adjustment | 1856 // Conservatively require the stack to be aligned. Some stack adjustment |
1865 // operations implemented below assume that the stack is aligned before the | 1857 // operations implemented below assume that the stack is aligned before the |
1866 // alloca. All the alloca code ensures that the stack alignment is preserved | 1858 // alloca. All the alloca code ensures that the stack alignment is preserved |
1867 // after the alloca. The stack alignment restriction can be relaxed in some | 1859 // after the alloca. The stack alignment restriction can be relaxed in some |
1868 // cases. | 1860 // cases. |
(...skipping 4574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6443 // However, for compatibility with current NaCl LLVM, don't claim that. | 6435 // However, for compatibility with current NaCl LLVM, don't claim that. |
6444 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6436 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
6445 } | 6437 } |
6446 | 6438 |
6447 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM]; | 6439 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM]; |
6448 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6440 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
6449 llvm::SmallBitVector TargetARM32::ScratchRegs; | 6441 llvm::SmallBitVector TargetARM32::ScratchRegs; |
6450 | 6442 |
6451 } // end of namespace ARM32 | 6443 } // end of namespace ARM32 |
6452 } // end of namespace Ice | 6444 } // end of namespace Ice |
OLD | NEW |