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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 return ::Ice::ARM32::TargetDataARM32::create(Ctx); | 45 return ::Ice::ARM32::TargetDataARM32::create(Ctx); |
46 } | 46 } |
47 | 47 |
48 std::unique_ptr<::Ice::TargetHeaderLowering> | 48 std::unique_ptr<::Ice::TargetHeaderLowering> |
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::GlobalContext *Ctx) { | 53 void staticInit(::Ice::GlobalContext *Ctx) { |
54 ::Ice::ARM32::TargetARM32::staticInit(Ctx); | 54 ::Ice::ARM32::TargetARM32::staticInit(Ctx); |
55 if (Ctx->getFlags().getUseNonsfi()) { | 55 if (Ice::getFlags().getUseNonsfi()) { |
56 // In nonsfi, we need to reference the _GLOBAL_OFFSET_TABLE_ for accessing | 56 // In nonsfi, we need to reference the _GLOBAL_OFFSET_TABLE_ for accessing |
57 // globals. The GOT is an external symbol (i.e., it is not defined in the | 57 // globals. The GOT is an external symbol (i.e., it is not defined in the |
58 // pexe) so we need to register it as such so that ELF emission won't barf | 58 // pexe) so we need to register it as such so that ELF emission won't barf |
59 // on an "unknown" symbol. The GOT is added to the External symbols list | 59 // on an "unknown" symbol. The GOT is added to the External symbols list |
60 // here because staticInit() is invoked in a single-thread context. | 60 // here because staticInit() is invoked in a single-thread context. |
61 Ctx->getConstantExternSym(Ctx->getGlobalString(::Ice::GlobalOffsetTable)); | 61 Ctx->getConstantExternSym(Ctx->getGlobalString(::Ice::GlobalOffsetTable)); |
62 } | 62 } |
63 } | 63 } |
64 | 64 |
65 bool shouldBePooled(const ::Ice::Constant *C) { | 65 bool shouldBePooled(const ::Ice::Constant *C) { |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 // Add handling of new register classes below. | 293 // Add handling of new register classes below. |
294 case RegARM32::RCARM32_QtoS: | 294 case RegARM32::RCARM32_QtoS: |
295 return "QtoS"; | 295 return "QtoS"; |
296 } | 296 } |
297 } | 297 } |
298 | 298 |
299 } // end of anonymous namespace | 299 } // end of anonymous namespace |
300 | 300 |
301 TargetARM32::TargetARM32(Cfg *Func) | 301 TargetARM32::TargetARM32(Cfg *Func) |
302 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl), | 302 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl), |
303 CPUFeatures(Func->getContext()->getFlags()) {} | 303 CPUFeatures(getFlags()) {} |
304 | 304 |
305 void TargetARM32::staticInit(GlobalContext *Ctx) { | 305 void TargetARM32::staticInit(GlobalContext *Ctx) { |
306 RegNumT::setLimit(RegARM32::Reg_NUM); | 306 RegNumT::setLimit(RegARM32::Reg_NUM); |
307 // Limit this size (or do all bitsets need to be the same width)??? | 307 // Limit this size (or do all bitsets need to be the same width)??? |
308 SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); | 308 SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); |
309 SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); | 309 SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); |
310 SmallBitVector Float32Registers(RegARM32::Reg_NUM); | 310 SmallBitVector Float32Registers(RegARM32::Reg_NUM); |
311 SmallBitVector Float64Registers(RegARM32::Reg_NUM); | 311 SmallBitVector Float64Registers(RegARM32::Reg_NUM); |
312 SmallBitVector VectorRegisters(RegARM32::Reg_NUM); | 312 SmallBitVector VectorRegisters(RegARM32::Reg_NUM); |
313 SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); | 313 SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 createGotPtr(); | 1034 createGotPtr(); |
1035 } | 1035 } |
1036 genTargetHelperCalls(); | 1036 genTargetHelperCalls(); |
1037 findMaxStackOutArgsSize(); | 1037 findMaxStackOutArgsSize(); |
1038 | 1038 |
1039 // Do not merge Alloca instructions, and lay out the stack. | 1039 // Do not merge Alloca instructions, and lay out the stack. |
1040 static constexpr bool SortAndCombineAllocas = true; | 1040 static constexpr bool SortAndCombineAllocas = true; |
1041 Func->processAllocas(SortAndCombineAllocas); | 1041 Func->processAllocas(SortAndCombineAllocas); |
1042 Func->dump("After Alloca processing"); | 1042 Func->dump("After Alloca processing"); |
1043 | 1043 |
1044 if (!Ctx->getFlags().getEnablePhiEdgeSplit()) { | 1044 if (!getFlags().getEnablePhiEdgeSplit()) { |
1045 // Lower Phi instructions. | 1045 // Lower Phi instructions. |
1046 Func->placePhiLoads(); | 1046 Func->placePhiLoads(); |
1047 if (Func->hasError()) | 1047 if (Func->hasError()) |
1048 return; | 1048 return; |
1049 Func->placePhiStores(); | 1049 Func->placePhiStores(); |
1050 if (Func->hasError()) | 1050 if (Func->hasError()) |
1051 return; | 1051 return; |
1052 Func->deletePhis(); | 1052 Func->deletePhis(); |
1053 if (Func->hasError()) | 1053 if (Func->hasError()) |
1054 return; | 1054 return; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 // cleanup, to make the dump cleaner and more useful. | 1102 // cleanup, to make the dump cleaner and more useful. |
1103 Func->dump("After initial ARM32 codegen"); | 1103 Func->dump("After initial ARM32 codegen"); |
1104 Func->getVMetadata()->init(VMK_All); | 1104 Func->getVMetadata()->init(VMK_All); |
1105 regAlloc(RAK_Global); | 1105 regAlloc(RAK_Global); |
1106 if (Func->hasError()) | 1106 if (Func->hasError()) |
1107 return; | 1107 return; |
1108 | 1108 |
1109 copyRegAllocFromInfWeightVariable64On32(Func->getVariables()); | 1109 copyRegAllocFromInfWeightVariable64On32(Func->getVariables()); |
1110 Func->dump("After linear scan regalloc"); | 1110 Func->dump("After linear scan regalloc"); |
1111 | 1111 |
1112 if (Ctx->getFlags().getEnablePhiEdgeSplit()) { | 1112 if (getFlags().getEnablePhiEdgeSplit()) { |
1113 Func->advancedPhiLowering(); | 1113 Func->advancedPhiLowering(); |
1114 Func->dump("After advanced Phi lowering"); | 1114 Func->dump("After advanced Phi lowering"); |
1115 } | 1115 } |
1116 | 1116 |
1117 ForbidTemporaryWithoutReg _(this); | 1117 ForbidTemporaryWithoutReg _(this); |
1118 | 1118 |
1119 // Stack frame mapping. | 1119 // Stack frame mapping. |
1120 Func->genFrame(); | 1120 Func->genFrame(); |
1121 if (Func->hasError()) | 1121 if (Func->hasError()) |
1122 return; | 1122 return; |
1123 Func->dump("After stack frame mapping"); | 1123 Func->dump("After stack frame mapping"); |
1124 | 1124 |
1125 postLowerLegalization(); | 1125 postLowerLegalization(); |
1126 if (Func->hasError()) | 1126 if (Func->hasError()) |
1127 return; | 1127 return; |
1128 Func->dump("After postLowerLegalization"); | 1128 Func->dump("After postLowerLegalization"); |
1129 | 1129 |
1130 Func->contractEmptyNodes(); | 1130 Func->contractEmptyNodes(); |
1131 Func->reorderNodes(); | 1131 Func->reorderNodes(); |
1132 | 1132 |
1133 // Branch optimization. This needs to be done just before code emission. In | 1133 // Branch optimization. This needs to be done just before code emission. In |
1134 // particular, no transformations that insert or reorder CfgNodes should be | 1134 // particular, no transformations that insert or reorder CfgNodes should be |
1135 // done after branch optimization. We go ahead and do it before nop insertion | 1135 // done after branch optimization. We go ahead and do it before nop insertion |
1136 // to reduce the amount of work needed for searching for opportunities. | 1136 // to reduce the amount of work needed for searching for opportunities. |
1137 Func->doBranchOpt(); | 1137 Func->doBranchOpt(); |
1138 Func->dump("After branch optimization"); | 1138 Func->dump("After branch optimization"); |
1139 | 1139 |
1140 // Nop insertion | 1140 // Nop insertion |
1141 if (Ctx->getFlags().getShouldDoNopInsertion()) { | 1141 if (getFlags().getShouldDoNopInsertion()) { |
1142 Func->doNopInsertion(); | 1142 Func->doNopInsertion(); |
1143 } | 1143 } |
1144 } | 1144 } |
1145 | 1145 |
1146 void TargetARM32::translateOm1() { | 1146 void TargetARM32::translateOm1() { |
1147 TimerMarker T(TimerStack::TT_Om1, Func); | 1147 TimerMarker T(TimerStack::TT_Om1, Func); |
1148 | 1148 |
1149 // TODO(stichnot): share passes with other targets? | 1149 // TODO(stichnot): share passes with other targets? |
1150 if (SandboxingType == ST_Nonsfi) { | 1150 if (SandboxingType == ST_Nonsfi) { |
1151 createGotPtr(); | 1151 createGotPtr(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1193 if (Func->hasError()) | 1193 if (Func->hasError()) |
1194 return; | 1194 return; |
1195 Func->dump("After stack frame mapping"); | 1195 Func->dump("After stack frame mapping"); |
1196 | 1196 |
1197 postLowerLegalization(); | 1197 postLowerLegalization(); |
1198 if (Func->hasError()) | 1198 if (Func->hasError()) |
1199 return; | 1199 return; |
1200 Func->dump("After postLowerLegalization"); | 1200 Func->dump("After postLowerLegalization"); |
1201 | 1201 |
1202 // Nop insertion | 1202 // Nop insertion |
1203 if (Ctx->getFlags().getShouldDoNopInsertion()) { | 1203 if (getFlags().getShouldDoNopInsertion()) { |
1204 Func->doNopInsertion(); | 1204 Func->doNopInsertion(); |
1205 } | 1205 } |
1206 } | 1206 } |
1207 | 1207 |
1208 uint32_t TargetARM32::getStackAlignment() const { | 1208 uint32_t TargetARM32::getStackAlignment() const { |
1209 return ARM32_STACK_ALIGNMENT_BYTES; | 1209 return ARM32_STACK_ALIGNMENT_BYTES; |
1210 } | 1210 } |
1211 | 1211 |
1212 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { | 1212 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { |
1213 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { | 1213 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1249 // liveness validation errors for saving callee-save registers. | 1249 // liveness validation errors for saving callee-save registers. |
1250 Func->addImplicitArg(Reg); | 1250 Func->addImplicitArg(Reg); |
1251 // Don't bother tracking the live range of a named physical register. | 1251 // Don't bother tracking the live range of a named physical register. |
1252 Reg->setIgnoreLiveness(); | 1252 Reg->setIgnoreLiveness(); |
1253 } | 1253 } |
1254 return Reg; | 1254 return Reg; |
1255 } | 1255 } |
1256 | 1256 |
1257 void TargetARM32::emitJumpTable(const Cfg *Func, | 1257 void TargetARM32::emitJumpTable(const Cfg *Func, |
1258 const InstJumpTable *JumpTable) const { | 1258 const InstJumpTable *JumpTable) const { |
| 1259 (void)Func; |
1259 (void)JumpTable; | 1260 (void)JumpTable; |
1260 UnimplementedError(Func->getContext()->getFlags()); | 1261 UnimplementedError(getFlags()); |
1261 } | 1262 } |
1262 | 1263 |
1263 void TargetARM32::emitVariable(const Variable *Var) const { | 1264 void TargetARM32::emitVariable(const Variable *Var) const { |
1264 if (!BuildDefs::dump()) | 1265 if (!BuildDefs::dump()) |
1265 return; | 1266 return; |
1266 Ostream &Str = Ctx->getStrEmit(); | 1267 Ostream &Str = Ctx->getStrEmit(); |
1267 if (Var->hasReg()) { | 1268 if (Var->hasReg()) { |
1268 Str << getRegName(Var->getRegNum(), Var->getType()); | 1269 Str << getRegName(Var->getRegNum(), Var->getType()); |
1269 return; | 1270 return; |
1270 } | 1271 } |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1760 Legal_Reg | Legal_Flex, getReservedTmpReg()); | 1761 Legal_Reg | Legal_Flex, getReservedTmpReg()); |
1761 Sandboxer(this).add_sp(AddAmount); | 1762 Sandboxer(this).add_sp(AddAmount); |
1762 } | 1763 } |
1763 } | 1764 } |
1764 | 1765 |
1765 if (!PreservedGPRs.empty()) | 1766 if (!PreservedGPRs.empty()) |
1766 _pop(PreservedGPRs); | 1767 _pop(PreservedGPRs); |
1767 if (!PreservedSRegs.empty()) | 1768 if (!PreservedSRegs.empty()) |
1768 _pop(PreservedSRegs); | 1769 _pop(PreservedSRegs); |
1769 | 1770 |
1770 if (!Ctx->getFlags().getUseSandboxing()) | 1771 if (!getFlags().getUseSandboxing()) |
1771 return; | 1772 return; |
1772 | 1773 |
1773 // Change the original ret instruction into a sandboxed return sequence. | 1774 // Change the original ret instruction into a sandboxed return sequence. |
1774 // | 1775 // |
1775 // bundle_lock | 1776 // bundle_lock |
1776 // bic lr, #0xc000000f | 1777 // bic lr, #0xc000000f |
1777 // bx lr | 1778 // bx lr |
1778 // bundle_unlock | 1779 // bundle_unlock |
1779 // | 1780 // |
1780 // This isn't just aligning to the getBundleAlignLog2Bytes(). It needs to | 1781 // This isn't just aligning to the getBundleAlignLog2Bytes(). It needs to |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2248 // bit-manipulation problems below. | 2249 // bit-manipulation problems below. |
2249 const uint32_t AlignmentParam = std::max(1u, Instr->getAlignInBytes()); | 2250 const uint32_t AlignmentParam = std::max(1u, Instr->getAlignInBytes()); |
2250 | 2251 |
2251 // LLVM enforces power of 2 alignment. | 2252 // LLVM enforces power of 2 alignment. |
2252 assert(llvm::isPowerOf2_32(AlignmentParam)); | 2253 assert(llvm::isPowerOf2_32(AlignmentParam)); |
2253 assert(llvm::isPowerOf2_32(ARM32_STACK_ALIGNMENT_BYTES)); | 2254 assert(llvm::isPowerOf2_32(ARM32_STACK_ALIGNMENT_BYTES)); |
2254 | 2255 |
2255 const uint32_t Alignment = | 2256 const uint32_t Alignment = |
2256 std::max(AlignmentParam, ARM32_STACK_ALIGNMENT_BYTES); | 2257 std::max(AlignmentParam, ARM32_STACK_ALIGNMENT_BYTES); |
2257 const bool OverAligned = Alignment > ARM32_STACK_ALIGNMENT_BYTES; | 2258 const bool OverAligned = Alignment > ARM32_STACK_ALIGNMENT_BYTES; |
2258 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; | 2259 const bool OptM1 = getFlags().getOptLevel() == Opt_m1; |
2259 const bool AllocaWithKnownOffset = Instr->getKnownFrameOffset(); | 2260 const bool AllocaWithKnownOffset = Instr->getKnownFrameOffset(); |
2260 const bool UseFramePointer = | 2261 const bool UseFramePointer = |
2261 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; | 2262 hasFramePointer() || OverAligned || !AllocaWithKnownOffset || OptM1; |
2262 | 2263 |
2263 if (UseFramePointer) | 2264 if (UseFramePointer) |
2264 setHasFramePointer(); | 2265 setHasFramePointer(); |
2265 | 2266 |
2266 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); | 2267 Variable *SP = getPhysicalRegister(RegARM32::Reg_sp); |
2267 if (OverAligned) { | 2268 if (OverAligned) { |
2268 Sandboxer(this).align_sp(Alignment); | 2269 Sandboxer(this).align_sp(Alignment); |
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3349 Variable *Src1R = Srcs.unswappedSrc1R(this); | 3350 Variable *Src1R = Srcs.unswappedSrc1R(this); |
3350 if (isVectorType(DestTy)) { | 3351 if (isVectorType(DestTy)) { |
3351 _vsub(T, Src0R, Src1R); | 3352 _vsub(T, Src0R, Src1R); |
3352 } else { | 3353 } else { |
3353 _sub(T, Src0R, Src1R); | 3354 _sub(T, Src0R, Src1R); |
3354 } | 3355 } |
3355 _mov(Dest, T); | 3356 _mov(Dest, T); |
3356 return; | 3357 return; |
3357 } | 3358 } |
3358 case InstArithmetic::Mul: { | 3359 case InstArithmetic::Mul: { |
3359 const bool OptM1 = Ctx->getFlags().getOptLevel() == Opt_m1; | 3360 const bool OptM1 = getFlags().getOptLevel() == Opt_m1; |
3360 if (!OptM1 && Srcs.hasConstOperand()) { | 3361 if (!OptM1 && Srcs.hasConstOperand()) { |
3361 constexpr std::size_t MaxShifts = 4; | 3362 constexpr std::size_t MaxShifts = 4; |
3362 std::array<StrengthReduction::AggregationElement, MaxShifts> Shifts; | 3363 std::array<StrengthReduction::AggregationElement, MaxShifts> Shifts; |
3363 SizeT NumOperations; | 3364 SizeT NumOperations; |
3364 int32_t Const = Srcs.getConstantValue(); | 3365 int32_t Const = Srcs.getConstantValue(); |
3365 const bool Invert = Const < 0; | 3366 const bool Invert = Const < 0; |
3366 const bool MultiplyByZero = Const == 0; | 3367 const bool MultiplyByZero = Const == 0; |
3367 Operand *_0 = | 3368 Operand *_0 = |
3368 legalize(Ctx->getConstantZero(DestTy), Legal_Reg | Legal_Flex); | 3369 legalize(Ctx->getConstantZero(DestTy), Legal_Reg | Legal_Flex); |
3369 | 3370 |
(...skipping 2758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6128 TmpRegNum); | 6129 TmpRegNum); |
6129 _bic(Reg, Reg, Mask); | 6130 _bic(Reg, Reg, Mask); |
6130 } else { | 6131 } else { |
6131 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex, | 6132 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex, |
6132 TmpRegNum); | 6133 TmpRegNum); |
6133 _and(Reg, Reg, Mask); | 6134 _and(Reg, Reg, Mask); |
6134 } | 6135 } |
6135 } | 6136 } |
6136 | 6137 |
6137 void TargetARM32::postLower() { | 6138 void TargetARM32::postLower() { |
6138 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 6139 if (getFlags().getOptLevel() == Opt_m1) |
6139 return; | 6140 return; |
6140 markRedefinitions(); | 6141 markRedefinitions(); |
6141 Context.availabilityUpdate(); | 6142 Context.availabilityUpdate(); |
6142 } | 6143 } |
6143 | 6144 |
6144 void TargetARM32::makeRandomRegisterPermutation( | 6145 void TargetARM32::makeRandomRegisterPermutation( |
6145 llvm::SmallVectorImpl<RegNumT> &Permutation, | 6146 llvm::SmallVectorImpl<RegNumT> &Permutation, |
6146 const SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 6147 const SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
6147 (void)Permutation; | 6148 (void)Permutation; |
6148 (void)ExcludeRegisters; | 6149 (void)ExcludeRegisters; |
6149 (void)Salt; | 6150 (void)Salt; |
6150 UnimplementedError(Func->getContext()->getFlags()); | 6151 UnimplementedError(getFlags()); |
6151 } | 6152 } |
6152 | 6153 |
6153 void TargetARM32::emit(const ConstantInteger32 *C) const { | 6154 void TargetARM32::emit(const ConstantInteger32 *C) const { |
6154 if (!BuildDefs::dump()) | 6155 if (!BuildDefs::dump()) |
6155 return; | 6156 return; |
6156 Ostream &Str = Ctx->getStrEmit(); | 6157 Ostream &Str = Ctx->getStrEmit(); |
6157 Str << "#" << C->getValue(); | 6158 Str << "#" << C->getValue(); |
6158 } | 6159 } |
6159 | 6160 |
6160 void TargetARM32::emit(const ConstantInteger64 *) const { | 6161 void TargetARM32::emit(const ConstantInteger64 *) const { |
6161 llvm::report_fatal_error("Not expecting to emit 64-bit integers"); | 6162 llvm::report_fatal_error("Not expecting to emit 64-bit integers"); |
6162 } | 6163 } |
6163 | 6164 |
6164 void TargetARM32::emit(const ConstantFloat *C) const { | 6165 void TargetARM32::emit(const ConstantFloat *C) const { |
6165 (void)C; | 6166 (void)C; |
6166 UnimplementedError(Ctx->getFlags()); | 6167 UnimplementedError(getFlags()); |
6167 } | 6168 } |
6168 | 6169 |
6169 void TargetARM32::emit(const ConstantDouble *C) const { | 6170 void TargetARM32::emit(const ConstantDouble *C) const { |
6170 (void)C; | 6171 (void)C; |
6171 UnimplementedError(Ctx->getFlags()); | 6172 UnimplementedError(getFlags()); |
6172 } | 6173 } |
6173 | 6174 |
6174 void TargetARM32::emit(const ConstantUndef *) const { | 6175 void TargetARM32::emit(const ConstantUndef *) const { |
6175 llvm::report_fatal_error("undef value encountered by emitter."); | 6176 llvm::report_fatal_error("undef value encountered by emitter."); |
6176 } | 6177 } |
6177 | 6178 |
6178 void TargetARM32::emit(const ConstantRelocatable *C) const { | 6179 void TargetARM32::emit(const ConstantRelocatable *C) const { |
6179 if (!BuildDefs::dump()) | 6180 if (!BuildDefs::dump()) |
6180 return; | 6181 return; |
6181 Ostream &Str = Ctx->getStrEmit(); | 6182 Ostream &Str = Ctx->getStrEmit(); |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6714 createAutoBundle(); | 6715 createAutoBundle(); |
6715 Target->_sub(SP, SP, SubAmount); | 6716 Target->_sub(SP, SP, SubAmount); |
6716 Target->_bic(SP, SP, memOpBicMask(Target->Func)); | 6717 Target->_bic(SP, SP, memOpBicMask(Target->Func)); |
6717 } | 6718 } |
6718 | 6719 |
6719 TargetDataARM32::TargetDataARM32(GlobalContext *Ctx) | 6720 TargetDataARM32::TargetDataARM32(GlobalContext *Ctx) |
6720 : TargetDataLowering(Ctx) {} | 6721 : TargetDataLowering(Ctx) {} |
6721 | 6722 |
6722 void TargetDataARM32::lowerGlobals(const VariableDeclarationList &Vars, | 6723 void TargetDataARM32::lowerGlobals(const VariableDeclarationList &Vars, |
6723 const std::string &SectionSuffix) { | 6724 const std::string &SectionSuffix) { |
6724 const bool IsPIC = Ctx->getFlags().getUseNonsfi(); | 6725 const bool IsPIC = getFlags().getUseNonsfi(); |
6725 switch (Ctx->getFlags().getOutFileType()) { | 6726 switch (getFlags().getOutFileType()) { |
6726 case FT_Elf: { | 6727 case FT_Elf: { |
6727 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 6728 ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
6728 Writer->writeDataSection(Vars, llvm::ELF::R_ARM_ABS32, SectionSuffix, | 6729 Writer->writeDataSection(Vars, llvm::ELF::R_ARM_ABS32, SectionSuffix, |
6729 IsPIC); | 6730 IsPIC); |
6730 } break; | 6731 } break; |
6731 case FT_Asm: | 6732 case FT_Asm: |
6732 case FT_Iasm: { | 6733 case FT_Iasm: { |
6733 const std::string TranslateOnly = Ctx->getFlags().getTranslateOnly(); | 6734 const std::string TranslateOnly = getFlags().getTranslateOnly(); |
6734 OstreamLocker _(Ctx); | 6735 OstreamLocker _(Ctx); |
6735 for (const VariableDeclaration *Var : Vars) { | 6736 for (const VariableDeclaration *Var : Vars) { |
6736 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | 6737 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { |
6737 emitGlobal(*Var, SectionSuffix); | 6738 emitGlobal(*Var, SectionSuffix); |
6738 } | 6739 } |
6739 } | 6740 } |
6740 } break; | 6741 } break; |
6741 } | 6742 } |
6742 } | 6743 } |
6743 | 6744 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6803 static constexpr size_t MinimumAlignment = 4; | 6804 static constexpr size_t MinimumAlignment = 4; |
6804 SizeT Align = std::max(MinimumAlignment, typeAlignInBytes(Traits::IceType)); | 6805 SizeT Align = std::max(MinimumAlignment, typeAlignInBytes(Traits::IceType)); |
6805 assert((Align % 4) == 0 && "Constants should be aligned"); | 6806 assert((Align % 4) == 0 && "Constants should be aligned"); |
6806 Ostream &Str = Ctx->getStrEmit(); | 6807 Ostream &Str = Ctx->getStrEmit(); |
6807 ConstantList Pool = Ctx->getConstantPool(Traits::IceType); | 6808 ConstantList Pool = Ctx->getConstantPool(Traits::IceType); |
6808 | 6809 |
6809 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",%progbits," << Align | 6810 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",%progbits," << Align |
6810 << "\n" | 6811 << "\n" |
6811 << "\t.align\t" << Align << "\n"; | 6812 << "\t.align\t" << Align << "\n"; |
6812 | 6813 |
6813 if (Ctx->getFlags().getReorderPooledConstants()) { | 6814 if (getFlags().getReorderPooledConstants()) { |
6814 // TODO(jpp): add constant pooling. | 6815 // TODO(jpp): add constant pooling. |
6815 UnimplementedError(Ctx->getFlags()); | 6816 UnimplementedError(getFlags()); |
6816 } | 6817 } |
6817 | 6818 |
6818 for (Constant *C : Pool) { | 6819 for (Constant *C : Pool) { |
6819 if (!C->getShouldBePooled()) { | 6820 if (!C->getShouldBePooled()) { |
6820 continue; | 6821 continue; |
6821 } | 6822 } |
6822 | 6823 |
6823 emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C)); | 6824 emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C)); |
6824 } | 6825 } |
6825 } | 6826 } |
6826 } // end of anonymous namespace | 6827 } // end of anonymous namespace |
6827 | 6828 |
6828 void TargetDataARM32::lowerConstants() { | 6829 void TargetDataARM32::lowerConstants() { |
6829 if (Ctx->getFlags().getDisableTranslation()) | 6830 if (getFlags().getDisableTranslation()) |
6830 return; | 6831 return; |
6831 switch (Ctx->getFlags().getOutFileType()) { | 6832 switch (getFlags().getOutFileType()) { |
6832 case FT_Elf: { | 6833 case FT_Elf: { |
6833 ELFObjectWriter *Writer = Ctx->getObjectWriter(); | 6834 ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
6834 Writer->writeConstantPool<ConstantFloat>(IceType_f32); | 6835 Writer->writeConstantPool<ConstantFloat>(IceType_f32); |
6835 Writer->writeConstantPool<ConstantDouble>(IceType_f64); | 6836 Writer->writeConstantPool<ConstantDouble>(IceType_f64); |
6836 } break; | 6837 } break; |
6837 case FT_Asm: | 6838 case FT_Asm: |
6838 case FT_Iasm: { | 6839 case FT_Iasm: { |
6839 OstreamLocker _(Ctx); | 6840 OstreamLocker _(Ctx); |
6840 emitConstantPool<float>(Ctx); | 6841 emitConstantPool<float>(Ctx); |
6841 emitConstantPool<double>(Ctx); | 6842 emitConstantPool<double>(Ctx); |
6842 break; | 6843 break; |
6843 } | 6844 } |
6844 } | 6845 } |
6845 } | 6846 } |
6846 | 6847 |
6847 void TargetDataARM32::lowerJumpTables() { | 6848 void TargetDataARM32::lowerJumpTables() { |
6848 if (Ctx->getFlags().getDisableTranslation()) | 6849 if (getFlags().getDisableTranslation()) |
6849 return; | 6850 return; |
6850 switch (Ctx->getFlags().getOutFileType()) { | 6851 switch (getFlags().getOutFileType()) { |
6851 case FT_Elf: | 6852 case FT_Elf: |
6852 if (!Ctx->getJumpTables().empty()) { | 6853 if (!Ctx->getJumpTables().empty()) { |
6853 llvm::report_fatal_error("ARM32 does not support jump tables yet."); | 6854 llvm::report_fatal_error("ARM32 does not support jump tables yet."); |
6854 } | 6855 } |
6855 break; | 6856 break; |
6856 case FT_Asm: | 6857 case FT_Asm: |
6857 // Already emitted from Cfg | 6858 // Already emitted from Cfg |
6858 break; | 6859 break; |
6859 case FT_Iasm: { | 6860 case FT_Iasm: { |
6860 // TODO(kschimpf): Fill this in when we get more information. | 6861 // TODO(kschimpf): Fill this in when we get more information. |
6861 break; | 6862 break; |
6862 } | 6863 } |
6863 } | 6864 } |
6864 } | 6865 } |
6865 | 6866 |
6866 TargetHeaderARM32::TargetHeaderARM32(GlobalContext *Ctx) | 6867 TargetHeaderARM32::TargetHeaderARM32(GlobalContext *Ctx) |
6867 : TargetHeaderLowering(Ctx), CPUFeatures(Ctx->getFlags()) {} | 6868 : TargetHeaderLowering(Ctx), CPUFeatures(getFlags()) {} |
6868 | 6869 |
6869 void TargetHeaderARM32::lower() { | 6870 void TargetHeaderARM32::lower() { |
6870 OstreamLocker _(Ctx); | 6871 OstreamLocker _(Ctx); |
6871 Ostream &Str = Ctx->getStrEmit(); | 6872 Ostream &Str = Ctx->getStrEmit(); |
6872 Str << ".syntax unified\n"; | 6873 Str << ".syntax unified\n"; |
6873 // Emit build attributes in format: .eabi_attribute TAG, VALUE. See Sec. 2 of | 6874 // Emit build attributes in format: .eabi_attribute TAG, VALUE. See Sec. 2 of |
6874 // "Addenda to, and Errata in the ABI for the ARM architecture" | 6875 // "Addenda to, and Errata in the ABI for the ARM architecture" |
6875 // http://infocenter.arm.com | 6876 // http://infocenter.arm.com |
6876 // /help/topic/com.arm.doc.ihi0045d/IHI0045D_ABI_addenda.pdf | 6877 // /help/topic/com.arm.doc.ihi0045d/IHI0045D_ABI_addenda.pdf |
6877 // | 6878 // |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6911 // However, for compatibility with current NaCl LLVM, don't claim that. | 6912 // However, for compatibility with current NaCl LLVM, don't claim that. |
6912 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6913 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
6913 } | 6914 } |
6914 | 6915 |
6915 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; | 6916 SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; |
6916 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; | 6917 SmallBitVector TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; |
6917 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6918 SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
6918 | 6919 |
6919 } // end of namespace ARM32 | 6920 } // end of namespace ARM32 |
6920 } // end of namespace Ice | 6921 } // end of namespace Ice |
OLD | NEW |