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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 } | 226 } |
227 | 227 |
228 namespace { | 228 namespace { |
229 constexpr SizeT NumGPRArgs = | 229 constexpr SizeT NumGPRArgs = |
230 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 230 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
231 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 231 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
232 +(((cc_arg) > 0) ? 1 : 0) | 232 +(((cc_arg) > 0) ? 1 : 0) |
233 REGARM32_GPR_TABLE | 233 REGARM32_GPR_TABLE |
234 #undef X | 234 #undef X |
235 ; | 235 ; |
236 std::array<uint32_t, NumGPRArgs> GPRArgInitializer; | 236 std::array<RegNumT, NumGPRArgs> GPRArgInitializer; |
237 | 237 |
238 constexpr SizeT NumI64Args = | 238 constexpr SizeT NumI64Args = |
239 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 239 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
240 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 240 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
241 +(((cc_arg) > 0) ? 1 : 0) | 241 +(((cc_arg) > 0) ? 1 : 0) |
242 REGARM32_I64PAIR_TABLE | 242 REGARM32_I64PAIR_TABLE |
243 #undef X | 243 #undef X |
244 ; | 244 ; |
245 std::array<uint32_t, NumI64Args> I64ArgInitializer; | 245 std::array<RegNumT, NumI64Args> I64ArgInitializer; |
246 | 246 |
247 constexpr SizeT NumFP32Args = | 247 constexpr SizeT NumFP32Args = |
248 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 248 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
249 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 249 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
250 +(((cc_arg) > 0) ? 1 : 0) | 250 +(((cc_arg) > 0) ? 1 : 0) |
251 REGARM32_FP32_TABLE | 251 REGARM32_FP32_TABLE |
252 #undef X | 252 #undef X |
253 ; | 253 ; |
254 std::array<uint32_t, NumFP32Args> FP32ArgInitializer; | 254 std::array<RegNumT, NumFP32Args> FP32ArgInitializer; |
255 | 255 |
256 constexpr SizeT NumFP64Args = | 256 constexpr SizeT NumFP64Args = |
257 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 257 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
258 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 258 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
259 +(((cc_arg) > 0) ? 1 : 0) | 259 +(((cc_arg) > 0) ? 1 : 0) |
260 REGARM32_FP64_TABLE | 260 REGARM32_FP64_TABLE |
261 #undef X | 261 #undef X |
262 ; | 262 ; |
263 std::array<uint32_t, NumFP64Args> FP64ArgInitializer; | 263 std::array<RegNumT, NumFP64Args> FP64ArgInitializer; |
264 | 264 |
265 constexpr SizeT NumVec128Args = | 265 constexpr SizeT NumVec128Args = |
266 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 266 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
267 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 267 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
268 +(((cc_arg > 0)) ? 1 : 0) | 268 +(((cc_arg > 0)) ? 1 : 0) |
269 REGARM32_VEC128_TABLE | 269 REGARM32_VEC128_TABLE |
270 #undef X | 270 #undef X |
271 ; | 271 ; |
272 std::array<uint32_t, NumVec128Args> Vec128ArgInitializer; | 272 std::array<RegNumT, NumVec128Args> Vec128ArgInitializer; |
273 | 273 |
274 IceString getRegClassName(RegClass C) { | 274 IceString getRegClassName(RegClass C) { |
275 auto ClassNum = static_cast<RegARM32::RegClassARM32>(C); | 275 auto ClassNum = static_cast<RegARM32::RegClassARM32>(C); |
276 assert(ClassNum < RegARM32::RCARM32_NUM); | 276 assert(ClassNum < RegARM32::RCARM32_NUM); |
277 switch (ClassNum) { | 277 switch (ClassNum) { |
278 default: | 278 default: |
279 assert(C < RC_Target); | 279 assert(C < RC_Target); |
280 return regClassString(C); | 280 return regClassString(C); |
281 // Add handling of new register classes below. | 281 // Add handling of new register classes below. |
282 } | 282 } |
283 } | 283 } |
284 | 284 |
285 } // end of anonymous namespace | 285 } // end of anonymous namespace |
286 | 286 |
287 TargetARM32::TargetARM32(Cfg *Func) | 287 TargetARM32::TargetARM32(Cfg *Func) |
288 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl), | 288 : TargetLowering(Func), NeedSandboxing(SandboxingType == ST_NaCl), |
289 CPUFeatures(Func->getContext()->getFlags()) {} | 289 CPUFeatures(Func->getContext()->getFlags()) {} |
290 | 290 |
291 void TargetARM32::staticInit(GlobalContext *Ctx) { | 291 void TargetARM32::staticInit(GlobalContext *Ctx) { |
292 | 292 RegNumT::setLimit(RegARM32::Reg_NUM); |
293 // Limit this size (or do all bitsets need to be the same width)??? | 293 // Limit this size (or do all bitsets need to be the same width)??? |
294 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); | 294 llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); |
295 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); | 295 llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); |
296 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM); | 296 llvm::SmallBitVector Float32Registers(RegARM32::Reg_NUM); |
297 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); | 297 llvm::SmallBitVector Float64Registers(RegARM32::Reg_NUM); |
298 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); | 298 llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); |
299 llvm::SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); | 299 llvm::SmallBitVector QtoSRegisters(RegARM32::Reg_NUM); |
300 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); | 300 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); |
301 const unsigned EncodedReg_q8 = RegARM32::RegTable[RegARM32::Reg_q8].Encoding; | 301 const unsigned EncodedReg_q8 = RegARM32::RegTable[RegARM32::Reg_q8].Encoding; |
302 for (int i = 0; i < RegARM32::Reg_NUM; ++i) { | 302 for (int i = 0; i < RegARM32::Reg_NUM; ++i) { |
303 const auto &Entry = RegARM32::RegTable[i]; | 303 const auto &Entry = RegARM32::RegTable[i]; |
304 IntegerRegisters[i] = Entry.IsInt; | 304 IntegerRegisters[i] = Entry.IsInt; |
305 I64PairRegisters[i] = Entry.IsI64Pair; | 305 I64PairRegisters[i] = Entry.IsI64Pair; |
306 Float32Registers[i] = Entry.IsFP32; | 306 Float32Registers[i] = Entry.IsFP32; |
307 Float64Registers[i] = Entry.IsFP64; | 307 Float64Registers[i] = Entry.IsFP64; |
308 VectorRegisters[i] = Entry.IsVec128; | 308 VectorRegisters[i] = Entry.IsVec128; |
309 RegisterAliases[i].resize(RegARM32::Reg_NUM); | 309 RegisterAliases[i].resize(RegARM32::Reg_NUM); |
310 // TODO(eholk): It would be better to store a QtoS flag in the | 310 // TODO(eholk): It would be better to store a QtoS flag in the |
311 // IceRegistersARM32 table than to compare their encodings here. | 311 // IceRegistersARM32 table than to compare their encodings here. |
312 QtoSRegisters[i] = Entry.IsVec128 && Entry.Encoding < EncodedReg_q8; | 312 QtoSRegisters[i] = Entry.IsVec128 && Entry.Encoding < EncodedReg_q8; |
313 for (int j = 0; j < Entry.NumAliases; ++j) { | 313 for (int j = 0; j < Entry.NumAliases; ++j) { |
314 assert(i == j || !RegisterAliases[i][Entry.Aliases[j]]); | 314 assert(i == j || !RegisterAliases[i][Entry.Aliases[j]]); |
315 RegisterAliases[i].set(Entry.Aliases[j]); | 315 RegisterAliases[i].set(Entry.Aliases[j]); |
316 } | 316 } |
317 assert(RegisterAliases[i][i]); | 317 assert(RegisterAliases[i][i]); |
318 if (Entry.CCArg <= 0) { | 318 if (Entry.CCArg <= 0) { |
319 continue; | 319 continue; |
320 } | 320 } |
| 321 const auto RegNum = RegNumT::fromInt(i); |
321 if (Entry.IsGPR) { | 322 if (Entry.IsGPR) { |
322 GPRArgInitializer[Entry.CCArg - 1] = i; | 323 GPRArgInitializer[Entry.CCArg - 1] = RegNum; |
323 } else if (Entry.IsI64Pair) { | 324 } else if (Entry.IsI64Pair) { |
324 I64ArgInitializer[Entry.CCArg - 1] = i; | 325 I64ArgInitializer[Entry.CCArg - 1] = RegNum; |
325 } else if (Entry.IsFP32) { | 326 } else if (Entry.IsFP32) { |
326 FP32ArgInitializer[Entry.CCArg - 1] = i; | 327 FP32ArgInitializer[Entry.CCArg - 1] = RegNum; |
327 } else if (Entry.IsFP64) { | 328 } else if (Entry.IsFP64) { |
328 FP64ArgInitializer[Entry.CCArg - 1] = i; | 329 FP64ArgInitializer[Entry.CCArg - 1] = RegNum; |
329 } else if (Entry.IsVec128) { | 330 } else if (Entry.IsVec128) { |
330 Vec128ArgInitializer[Entry.CCArg - 1] = i; | 331 Vec128ArgInitializer[Entry.CCArg - 1] = RegNum; |
331 } | 332 } |
332 } | 333 } |
333 TypeToRegisterSet[IceType_void] = InvalidRegisters; | 334 TypeToRegisterSet[IceType_void] = InvalidRegisters; |
334 TypeToRegisterSet[IceType_i1] = IntegerRegisters; | 335 TypeToRegisterSet[IceType_i1] = IntegerRegisters; |
335 TypeToRegisterSet[IceType_i8] = IntegerRegisters; | 336 TypeToRegisterSet[IceType_i8] = IntegerRegisters; |
336 TypeToRegisterSet[IceType_i16] = IntegerRegisters; | 337 TypeToRegisterSet[IceType_i16] = IntegerRegisters; |
337 TypeToRegisterSet[IceType_i32] = IntegerRegisters; | 338 TypeToRegisterSet[IceType_i32] = IntegerRegisters; |
338 TypeToRegisterSet[IceType_i64] = I64PairRegisters; | 339 TypeToRegisterSet[IceType_i64] = I64PairRegisters; |
339 TypeToRegisterSet[IceType_f32] = Float32Registers; | 340 TypeToRegisterSet[IceType_f32] = Float32Registers; |
340 TypeToRegisterSet[IceType_f64] = Float64Registers; | 341 TypeToRegisterSet[IceType_f64] = Float64Registers; |
341 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; | 342 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; |
342 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; | 343 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; |
343 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; | 344 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; |
344 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; | 345 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; |
345 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; | 346 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; |
346 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; | 347 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; |
347 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; | 348 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; |
348 TypeToRegisterSet[RegARM32::RCARM32_QtoS] = QtoSRegisters; | 349 TypeToRegisterSet[RegARM32::RCARM32_QtoS] = QtoSRegisters; |
349 | 350 |
350 for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i) | 351 for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i) |
351 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; | 352 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; |
352 | 353 |
353 filterTypeToRegisterSet( | 354 filterTypeToRegisterSet( |
354 Ctx, RegARM32::Reg_NUM, TypeToRegisterSet, | 355 Ctx, RegARM32::Reg_NUM, TypeToRegisterSet, |
355 llvm::array_lengthof(TypeToRegisterSet), [](int32_t RegNum) -> IceString { | 356 llvm::array_lengthof(TypeToRegisterSet), [](RegNumT RegNum) -> IceString { |
356 // This function simply removes ", " from the register name. | 357 // This function simply removes ", " from the register name. |
357 IceString Name = RegARM32::getRegName(RegNum); | 358 IceString Name = RegARM32::getRegName(RegNum); |
358 constexpr const char RegSeparator[] = ", "; | 359 constexpr const char RegSeparator[] = ", "; |
359 constexpr size_t RegSeparatorWidth = | 360 constexpr size_t RegSeparatorWidth = |
360 llvm::array_lengthof(RegSeparator) - 1; | 361 llvm::array_lengthof(RegSeparator) - 1; |
361 for (size_t Pos = Name.find(RegSeparator); Pos != std::string::npos; | 362 for (size_t Pos = Name.find(RegSeparator); Pos != std::string::npos; |
362 Pos = Name.find(RegSeparator)) { | 363 Pos = Name.find(RegSeparator)) { |
363 Name.replace(Pos, RegSeparatorWidth, ""); | 364 Name.replace(Pos, RegSeparatorWidth, ""); |
364 } | 365 } |
365 return Name; | 366 return Name; |
366 }, getRegClassName); | 367 }, getRegClassName); |
367 } | 368 } |
368 | 369 |
369 namespace { | 370 namespace { |
370 void copyRegAllocFromInfWeightVariable64On32(const VarList &Vars) { | 371 void copyRegAllocFromInfWeightVariable64On32(const VarList &Vars) { |
371 for (Variable *Var : Vars) { | 372 for (Variable *Var : Vars) { |
372 auto *Var64 = llvm::dyn_cast<Variable64On32>(Var); | 373 auto *Var64 = llvm::dyn_cast<Variable64On32>(Var); |
373 if (!Var64) { | 374 if (!Var64) { |
374 // This is not the variable we are looking for. | 375 // This is not the variable we are looking for. |
375 continue; | 376 continue; |
376 } | 377 } |
377 assert(Var64->hasReg() || !Var64->mustHaveReg()); | 378 assert(Var64->hasReg() || !Var64->mustHaveReg()); |
378 if (!Var64->hasReg()) { | 379 if (!Var64->hasReg()) { |
379 continue; | 380 continue; |
380 } | 381 } |
381 SizeT FirstReg = RegARM32::getI64PairFirstGPRNum(Var->getRegNum()); | 382 const auto FirstReg = |
| 383 RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(Var->getRegNum())); |
382 // This assumes little endian. | 384 // This assumes little endian. |
383 Variable *Lo = Var64->getLo(); | 385 Variable *Lo = Var64->getLo(); |
384 Variable *Hi = Var64->getHi(); | 386 Variable *Hi = Var64->getHi(); |
385 assert(Lo->hasReg() == Hi->hasReg()); | 387 assert(Lo->hasReg() == Hi->hasReg()); |
386 if (Lo->hasReg()) { | 388 if (Lo->hasReg()) { |
387 continue; | 389 continue; |
388 } | 390 } |
389 Lo->setRegNum(FirstReg); | 391 Lo->setRegNum(FirstReg); |
390 Lo->setMustHaveReg(); | 392 Lo->setMustHaveReg(); |
391 Hi->setRegNum(FirstReg + 1); | 393 Hi->setRegNum(RegNumT::fixme(FirstReg + 1)); |
392 Hi->setMustHaveReg(); | 394 Hi->setMustHaveReg(); |
393 } | 395 } |
394 } | 396 } |
395 } // end of anonymous namespace | 397 } // end of anonymous namespace |
396 | 398 |
397 uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) { | 399 uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) { |
398 TargetARM32::CallingConv CC; | 400 TargetARM32::CallingConv CC; |
399 int32_t DummyReg; | 401 RegNumT DummyReg; |
400 size_t OutArgsSizeBytes = 0; | 402 size_t OutArgsSizeBytes = 0; |
401 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { | 403 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { |
402 Operand *Arg = legalizeUndef(Call->getArg(i)); | 404 Operand *Arg = legalizeUndef(Call->getArg(i)); |
403 const Type Ty = Arg->getType(); | 405 const Type Ty = Arg->getType(); |
404 if (isScalarIntegerType(Ty)) { | 406 if (isScalarIntegerType(Ty)) { |
405 if (CC.argInGPR(Ty, &DummyReg)) { | 407 if (CC.argInGPR(Ty, &DummyReg)) { |
406 continue; | 408 continue; |
407 } | 409 } |
408 } else { | 410 } else { |
409 if (CC.argInVFP(Ty, &DummyReg)) { | 411 if (CC.argInVFP(Ty, &DummyReg)) { |
(...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
913 return ARM32_STACK_ALIGNMENT_BYTES; | 915 return ARM32_STACK_ALIGNMENT_BYTES; |
914 } | 916 } |
915 | 917 |
916 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { | 918 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { |
917 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { | 919 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { |
918 return Br->optimizeBranch(NextNode); | 920 return Br->optimizeBranch(NextNode); |
919 } | 921 } |
920 return false; | 922 return false; |
921 } | 923 } |
922 | 924 |
923 IceString TargetARM32::getRegName(SizeT RegNum, Type Ty) const { | 925 IceString TargetARM32::getRegName(RegNumT RegNum, Type Ty) const { |
924 assert(RegNum < RegARM32::Reg_NUM); | |
925 (void)Ty; | 926 (void)Ty; |
926 return RegARM32::getRegName(RegNum); | 927 return RegARM32::getRegName(RegNum); |
927 } | 928 } |
928 | 929 |
929 Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) { | 930 Variable *TargetARM32::getPhysicalRegister(RegNumT RegNum, Type Ty) { |
930 static const Type DefaultType[] = { | 931 static const Type DefaultType[] = { |
931 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 932 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
932 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 933 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
933 (isFP32) \ | 934 (isFP32) \ |
934 ? IceType_f32 \ | 935 ? IceType_f32 \ |
935 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), | 936 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), |
936 REGARM32_TABLE | 937 REGARM32_TABLE |
937 #undef X | 938 #undef X |
938 }; | 939 }; |
939 | 940 |
940 assert(RegNum < RegARM32::Reg_NUM); | |
941 if (Ty == IceType_void) { | 941 if (Ty == IceType_void) { |
942 assert(RegNum < llvm::array_lengthof(DefaultType)); | 942 assert(unsigned(RegNum) < llvm::array_lengthof(DefaultType)); |
943 Ty = DefaultType[RegNum]; | 943 Ty = DefaultType[RegNum]; |
944 } | 944 } |
945 if (PhysicalRegisters[Ty].empty()) | 945 if (PhysicalRegisters[Ty].empty()) |
946 PhysicalRegisters[Ty].resize(RegARM32::Reg_NUM); | 946 PhysicalRegisters[Ty].resize(RegARM32::Reg_NUM); |
947 assert(RegNum < PhysicalRegisters[Ty].size()); | 947 assert(unsigned(RegNum) < PhysicalRegisters[Ty].size()); |
948 Variable *Reg = PhysicalRegisters[Ty][RegNum]; | 948 Variable *Reg = PhysicalRegisters[Ty][RegNum]; |
949 if (Reg == nullptr) { | 949 if (Reg == nullptr) { |
950 Reg = Func->makeVariable(Ty); | 950 Reg = Func->makeVariable(Ty); |
951 Reg->setRegNum(RegNum); | 951 Reg->setRegNum(RegNum); |
952 PhysicalRegisters[Ty][RegNum] = Reg; | 952 PhysicalRegisters[Ty][RegNum] = Reg; |
953 // Specially mark a named physical register as an "argument" so that it is | 953 // Specially mark a named physical register as an "argument" so that it is |
954 // considered live upon function entry. Otherwise it's possible to get | 954 // considered live upon function entry. Otherwise it's possible to get |
955 // liveness validation errors for saving callee-save registers. | 955 // liveness validation errors for saving callee-save registers. |
956 Func->addImplicitArg(Reg); | 956 Func->addImplicitArg(Reg); |
957 // Don't bother tracking the live range of a named physical register. | 957 // Don't bother tracking the live range of a named physical register. |
(...skipping 16 matching lines...) Expand all Loading... |
974 Str << getRegName(Var->getRegNum(), Var->getType()); | 974 Str << getRegName(Var->getRegNum(), Var->getType()); |
975 return; | 975 return; |
976 } | 976 } |
977 if (Var->mustHaveReg()) { | 977 if (Var->mustHaveReg()) { |
978 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + | 978 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + |
979 ") has no register assigned - function " + | 979 ") has no register assigned - function " + |
980 Func->getFunctionName()); | 980 Func->getFunctionName()); |
981 } | 981 } |
982 assert(!Var->isRematerializable()); | 982 assert(!Var->isRematerializable()); |
983 int32_t Offset = Var->getStackOffset(); | 983 int32_t Offset = Var->getStackOffset(); |
984 int32_t BaseRegNum = Var->getBaseRegNum(); | 984 auto BaseRegNum = Var->getBaseRegNum(); |
985 if (BaseRegNum == Variable::NoRegister) { | 985 if (BaseRegNum == RegNumT::NoRegister) { |
986 BaseRegNum = getFrameOrStackReg(); | 986 BaseRegNum = getFrameOrStackReg(); |
987 } | 987 } |
988 const Type VarTy = Var->getType(); | 988 const Type VarTy = Var->getType(); |
989 Str << "[" << getRegName(BaseRegNum, VarTy); | 989 Str << "[" << getRegName(BaseRegNum, VarTy); |
990 if (Offset != 0) { | 990 if (Offset != 0) { |
991 Str << ", #" << Offset; | 991 Str << ", #" << Offset; |
992 } | 992 } |
993 Str << "]"; | 993 Str << "]"; |
994 } | 994 } |
995 | 995 |
996 TargetARM32::CallingConv::CallingConv() | 996 TargetARM32::CallingConv::CallingConv() |
997 : GPRegsUsed(RegARM32::Reg_NUM), | 997 : GPRegsUsed(RegARM32::Reg_NUM), |
998 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()), | 998 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()), |
999 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()), | 999 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()), |
1000 VFPRegsUsed(RegARM32::Reg_NUM), | 1000 VFPRegsUsed(RegARM32::Reg_NUM), |
1001 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()), | 1001 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()), |
1002 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()), | 1002 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()), |
1003 Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {} | 1003 Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {} |
1004 | 1004 |
1005 bool TargetARM32::CallingConv::argInGPR(Type Ty, int32_t *Reg) { | 1005 bool TargetARM32::CallingConv::argInGPR(Type Ty, RegNumT *Reg) { |
1006 CfgVector<SizeT> *Source; | 1006 CfgVector<RegNumT> *Source; |
1007 | 1007 |
1008 switch (Ty) { | 1008 switch (Ty) { |
1009 default: { | 1009 default: { |
1010 assert(isScalarIntegerType(Ty)); | 1010 assert(isScalarIntegerType(Ty)); |
1011 Source = &GPRArgs; | 1011 Source = &GPRArgs; |
1012 } break; | 1012 } break; |
1013 case IceType_i64: { | 1013 case IceType_i64: { |
1014 Source = &I64Args; | 1014 Source = &I64Args; |
1015 } break; | 1015 } break; |
1016 } | 1016 } |
(...skipping 13 matching lines...) Expand all Loading... |
1030 GPRegsUsed |= RegisterAliases[*Reg]; | 1030 GPRegsUsed |= RegisterAliases[*Reg]; |
1031 return true; | 1031 return true; |
1032 } | 1032 } |
1033 | 1033 |
1034 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64, | 1034 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64, |
1035 // i32) will have the first argument in r0, the second in r1-r2, and the third | 1035 // i32) will have the first argument in r0, the second in r1-r2, and the third |
1036 // on the stack. To model this behavior, whenever we pop a register from Regs, | 1036 // on the stack. To model this behavior, whenever we pop a register from Regs, |
1037 // we remove all of its aliases from the pool of available GPRs. This has the | 1037 // we remove all of its aliases from the pool of available GPRs. This has the |
1038 // effect of computing the "closure" on the GPR registers. | 1038 // effect of computing the "closure" on the GPR registers. |
1039 void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases( | 1039 void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases( |
1040 CfgVector<SizeT> *Regs) { | 1040 CfgVector<RegNumT> *Regs) { |
1041 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { | 1041 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { |
1042 GPRegsUsed |= RegisterAliases[Regs->back()]; | 1042 GPRegsUsed |= RegisterAliases[Regs->back()]; |
1043 Regs->pop_back(); | 1043 Regs->pop_back(); |
1044 } | 1044 } |
1045 } | 1045 } |
1046 | 1046 |
1047 bool TargetARM32::CallingConv::argInVFP(Type Ty, int32_t *Reg) { | 1047 bool TargetARM32::CallingConv::argInVFP(Type Ty, RegNumT *Reg) { |
1048 CfgVector<SizeT> *Source; | 1048 CfgVector<RegNumT> *Source; |
1049 | 1049 |
1050 switch (Ty) { | 1050 switch (Ty) { |
1051 default: { | 1051 default: { |
1052 assert(isVectorType(Ty)); | 1052 assert(isVectorType(Ty)); |
1053 Source = &Vec128Args; | 1053 Source = &Vec128Args; |
1054 } break; | 1054 } break; |
1055 case IceType_f32: { | 1055 case IceType_f32: { |
1056 Source = &FP32Args; | 1056 Source = &FP32Args; |
1057 } break; | 1057 } break; |
1058 case IceType_f64: { | 1058 case IceType_f64: { |
1059 Source = &FP64Args; | 1059 Source = &FP64Args; |
1060 } break; | 1060 } break; |
1061 } | 1061 } |
1062 | 1062 |
1063 discardUnavailableVFPRegs(Source); | 1063 discardUnavailableVFPRegs(Source); |
1064 | 1064 |
1065 if (Source->empty()) { | 1065 if (Source->empty()) { |
1066 VFPRegsUsed.set(); | 1066 VFPRegsUsed.set(); |
1067 return false; | 1067 return false; |
1068 } | 1068 } |
1069 | 1069 |
1070 *Reg = Source->back(); | 1070 *Reg = Source->back(); |
1071 VFPRegsUsed |= RegisterAliases[*Reg]; | 1071 VFPRegsUsed |= RegisterAliases[*Reg]; |
1072 return true; | 1072 return true; |
1073 } | 1073 } |
1074 | 1074 |
1075 // Arguments in VFP registers are not packed, so we don't mark the popped | 1075 // Arguments in VFP registers are not packed, so we don't mark the popped |
1076 // registers' aliases as unavailable. | 1076 // registers' aliases as unavailable. |
1077 void TargetARM32::CallingConv::discardUnavailableVFPRegs( | 1077 void TargetARM32::CallingConv::discardUnavailableVFPRegs( |
1078 CfgVector<SizeT> *Regs) { | 1078 CfgVector<RegNumT> *Regs) { |
1079 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) { | 1079 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) { |
1080 Regs->pop_back(); | 1080 Regs->pop_back(); |
1081 } | 1081 } |
1082 } | 1082 } |
1083 | 1083 |
1084 void TargetARM32::lowerArguments() { | 1084 void TargetARM32::lowerArguments() { |
1085 VarList &Args = Func->getArgs(); | 1085 VarList &Args = Func->getArgs(); |
1086 TargetARM32::CallingConv CC; | 1086 TargetARM32::CallingConv CC; |
1087 | 1087 |
1088 // For each register argument, replace Arg in the argument list with the home | 1088 // For each register argument, replace Arg in the argument list with the home |
1089 // register. Then generate an instruction in the prolog to copy the home | 1089 // register. Then generate an instruction in the prolog to copy the home |
1090 // register to the assigned location of Arg. | 1090 // register to the assigned location of Arg. |
1091 Context.init(Func->getEntryNode()); | 1091 Context.init(Func->getEntryNode()); |
1092 Context.setInsertPoint(Context.getCur()); | 1092 Context.setInsertPoint(Context.getCur()); |
1093 | 1093 |
1094 for (SizeT I = 0, E = Args.size(); I < E; ++I) { | 1094 for (SizeT I = 0, E = Args.size(); I < E; ++I) { |
1095 Variable *Arg = Args[I]; | 1095 Variable *Arg = Args[I]; |
1096 Type Ty = Arg->getType(); | 1096 Type Ty = Arg->getType(); |
1097 int RegNum; | 1097 RegNumT RegNum; |
1098 if (isScalarIntegerType(Ty)) { | 1098 if (isScalarIntegerType(Ty)) { |
1099 if (!CC.argInGPR(Ty, &RegNum)) { | 1099 if (!CC.argInGPR(Ty, &RegNum)) { |
1100 continue; | 1100 continue; |
1101 } | 1101 } |
1102 } else { | 1102 } else { |
1103 if (!CC.argInVFP(Ty, &RegNum)) { | 1103 if (!CC.argInVFP(Ty, &RegNum)) { |
1104 continue; | 1104 continue; |
1105 } | 1105 } |
1106 } | 1106 } |
1107 | 1107 |
1108 Variable *RegisterArg = Func->makeVariable(Ty); | 1108 Variable *RegisterArg = Func->makeVariable(Ty); |
1109 if (BuildDefs::dump()) { | 1109 if (BuildDefs::dump()) { |
1110 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); | 1110 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); |
1111 } | 1111 } |
1112 RegisterArg->setIsArg(); | 1112 RegisterArg->setIsArg(); |
1113 Arg->setIsArg(false); | 1113 Arg->setIsArg(false); |
1114 Args[I] = RegisterArg; | 1114 Args[I] = RegisterArg; |
1115 switch (Ty) { | 1115 switch (Ty) { |
1116 default: { RegisterArg->setRegNum(RegNum); } break; | 1116 default: { RegisterArg->setRegNum(RegNum); } break; |
1117 case IceType_i64: { | 1117 case IceType_i64: { |
1118 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg); | 1118 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg); |
1119 RegisterArg64->initHiLo(Func); | 1119 RegisterArg64->initHiLo(Func); |
1120 RegisterArg64->getLo()->setRegNum( | 1120 RegisterArg64->getLo()->setRegNum( |
1121 RegARM32::getI64PairFirstGPRNum(RegNum)); | 1121 RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(RegNum))); |
1122 RegisterArg64->getHi()->setRegNum( | 1122 RegisterArg64->getHi()->setRegNum( |
1123 RegARM32::getI64PairSecondGPRNum(RegNum)); | 1123 RegNumT::fixme(RegARM32::getI64PairSecondGPRNum(RegNum))); |
1124 } break; | 1124 } break; |
1125 } | 1125 } |
1126 Context.insert<InstAssign>(Arg, RegisterArg); | 1126 Context.insert<InstAssign>(Arg, RegisterArg); |
1127 } | 1127 } |
1128 } | 1128 } |
1129 | 1129 |
1130 // Helper function for addProlog(). | 1130 // Helper function for addProlog(). |
1131 // | 1131 // |
1132 // This assumes Arg is an argument passed on the stack. This sets the frame | 1132 // This assumes Arg is an argument passed on the stack. This sets the frame |
1133 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an | 1133 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 &PreservedSRegs)}; | 1298 &PreservedSRegs)}; |
1299 for (const auto &RegClass : RegClasses) { | 1299 for (const auto &RegClass : RegClasses) { |
1300 const uint32_t FirstRegInClass = std::get<0>(RegClass); | 1300 const uint32_t FirstRegInClass = std::get<0>(RegClass); |
1301 const uint32_t LastRegInClass = std::get<1>(RegClass); | 1301 const uint32_t LastRegInClass = std::get<1>(RegClass); |
1302 VarList *const PreservedRegsInClass = std::get<2>(RegClass); | 1302 VarList *const PreservedRegsInClass = std::get<2>(RegClass); |
1303 for (uint32_t Reg = FirstRegInClass; Reg <= LastRegInClass; ++Reg) { | 1303 for (uint32_t Reg = FirstRegInClass; Reg <= LastRegInClass; ++Reg) { |
1304 if (!ToPreserve[Reg]) { | 1304 if (!ToPreserve[Reg]) { |
1305 continue; | 1305 continue; |
1306 } | 1306 } |
1307 ++NumCallee; | 1307 ++NumCallee; |
1308 Variable *PhysicalRegister = getPhysicalRegister(Reg); | 1308 Variable *PhysicalRegister = getPhysicalRegister(RegNumT::fromInt(Reg)); |
1309 PreservedRegsSizeBytes += | 1309 PreservedRegsSizeBytes += |
1310 typeWidthInBytesOnStack(PhysicalRegister->getType()); | 1310 typeWidthInBytesOnStack(PhysicalRegister->getType()); |
1311 PreservedRegsInClass->push_back(PhysicalRegister); | 1311 PreservedRegsInClass->push_back(PhysicalRegister); |
1312 } | 1312 } |
1313 } | 1313 } |
1314 | 1314 |
1315 Ctx->statsUpdateRegistersSaved(NumCallee); | 1315 Ctx->statsUpdateRegistersSaved(NumCallee); |
1316 if (!PreservedSRegs.empty()) | 1316 if (!PreservedSRegs.empty()) |
1317 _push(PreservedSRegs); | 1317 _push(PreservedSRegs); |
1318 if (!PreservedGPRs.empty()) | 1318 if (!PreservedGPRs.empty()) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 // Arg[0] is closest to the stack/frame pointer. | 1373 // Arg[0] is closest to the stack/frame pointer. |
1374 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); | 1374 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); |
1375 size_t BasicFrameOffset = PreservedRegsSizeBytes; | 1375 size_t BasicFrameOffset = PreservedRegsSizeBytes; |
1376 if (!UsesFramePointer) | 1376 if (!UsesFramePointer) |
1377 BasicFrameOffset += SpillAreaSizeBytes; | 1377 BasicFrameOffset += SpillAreaSizeBytes; |
1378 | 1378 |
1379 const VarList &Args = Func->getArgs(); | 1379 const VarList &Args = Func->getArgs(); |
1380 size_t InArgsSizeBytes = 0; | 1380 size_t InArgsSizeBytes = 0; |
1381 TargetARM32::CallingConv CC; | 1381 TargetARM32::CallingConv CC; |
1382 for (Variable *Arg : Args) { | 1382 for (Variable *Arg : Args) { |
1383 int32_t DummyReg; | 1383 RegNumT DummyReg; |
1384 const Type Ty = Arg->getType(); | 1384 const Type Ty = Arg->getType(); |
1385 | 1385 |
1386 // Skip arguments passed in registers. | 1386 // Skip arguments passed in registers. |
1387 if (isScalarIntegerType(Ty)) { | 1387 if (isScalarIntegerType(Ty)) { |
1388 if (CC.argInGPR(Ty, &DummyReg)) { | 1388 if (CC.argInGPR(Ty, &DummyReg)) { |
1389 continue; | 1389 continue; |
1390 } | 1390 } |
1391 } else { | 1391 } else { |
1392 if (CC.argInVFP(Ty, &DummyReg)) { | 1392 if (CC.argInVFP(Ty, &DummyReg)) { |
1393 continue; | 1393 continue; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 | 1492 |
1493 RI->setDeleted(); | 1493 RI->setDeleted(); |
1494 } | 1494 } |
1495 | 1495 |
1496 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const { | 1496 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const { |
1497 constexpr bool ZeroExt = false; | 1497 constexpr bool ZeroExt = false; |
1498 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset); | 1498 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset); |
1499 } | 1499 } |
1500 | 1500 |
1501 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister( | 1501 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister( |
1502 Variable *Base, int32_t Offset, int32_t ScratchRegNum) { | 1502 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { |
1503 // Legalize will likely need a movw/movt combination, but if the top bits are | 1503 // Legalize will likely need a movw/movt combination, but if the top bits are |
1504 // all 0 from negating the offset and subtracting, we could use that instead. | 1504 // all 0 from negating the offset and subtracting, we could use that instead. |
1505 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; | 1505 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; |
1506 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); | 1506 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); |
1507 if (ShouldSub) { | 1507 if (ShouldSub) { |
1508 Operand *OffsetVal = | 1508 Operand *OffsetVal = |
1509 Target->legalize(Target->Ctx->getConstantInt32(-Offset), | 1509 Target->legalize(Target->Ctx->getConstantInt32(-Offset), |
1510 Legal_Reg | Legal_Flex, ScratchRegNum); | 1510 Legal_Reg | Legal_Flex, ScratchRegNum); |
1511 Target->_sub(ScratchReg, Base, OffsetVal); | 1511 Target->_sub(ScratchReg, Base, OffsetVal); |
1512 } else { | 1512 } else { |
1513 Operand *OffsetVal = | 1513 Operand *OffsetVal = |
1514 Target->legalize(Target->Ctx->getConstantInt32(Offset), | 1514 Target->legalize(Target->Ctx->getConstantInt32(Offset), |
1515 Legal_Reg | Legal_Flex, ScratchRegNum); | 1515 Legal_Reg | Legal_Flex, ScratchRegNum); |
1516 Target->_add(ScratchReg, Base, OffsetVal); | 1516 Target->_add(ScratchReg, Base, OffsetVal); |
1517 } | 1517 } |
1518 | 1518 |
1519 if (ScratchRegNum == Target->getReservedTmpReg()) { | 1519 if (ScratchRegNum == Target->getReservedTmpReg()) { |
1520 const bool BaseIsStackOrFramePtr = | 1520 const bool BaseIsStackOrFramePtr = |
1521 Base->getRegNum() == static_cast<int32_t>(Target->getFrameOrStackReg()); | 1521 Base->getRegNum() == Target->getFrameOrStackReg(); |
1522 // There is currently no code path that would trigger this assertion, so we | 1522 // There is currently no code path that would trigger this assertion, so we |
1523 // leave this assertion here in case it is ever violated. This is not a | 1523 // leave this assertion here in case it is ever violated. This is not a |
1524 // fatal error (thus the use of assert() and not llvm::report_fatal_error) | 1524 // fatal error (thus the use of assert() and not llvm::report_fatal_error) |
1525 // as the program compiled by subzero will still work correctly. | 1525 // as the program compiled by subzero will still work correctly. |
1526 assert(BaseIsStackOrFramePtr); | 1526 assert(BaseIsStackOrFramePtr); |
1527 // Side-effect: updates TempBase to reflect the new Temporary. | 1527 // Side-effect: updates TempBase to reflect the new Temporary. |
1528 if (BaseIsStackOrFramePtr) { | 1528 if (BaseIsStackOrFramePtr) { |
1529 TempBaseReg = ScratchReg; | 1529 TempBaseReg = ScratchReg; |
1530 TempBaseOffset = Offset; | 1530 TempBaseOffset = Offset; |
1531 } else { | 1531 } else { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1618 MovInstr->getPredicate()); | 1618 MovInstr->getPredicate()); |
1619 // _str() does not have a Dest, so we add a fake-def(Dest). | 1619 // _str() does not have a Dest, so we add a fake-def(Dest). |
1620 Target->Context.insert<InstFakeDef>(Dest); | 1620 Target->Context.insert<InstFakeDef>(Dest); |
1621 Legalized = true; | 1621 Legalized = true; |
1622 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | 1622 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
1623 if (Var->isRematerializable()) { | 1623 if (Var->isRematerializable()) { |
1624 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | 1624 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
1625 | 1625 |
1626 // ExtraOffset is only needed for frame-pointer based frames as we have | 1626 // ExtraOffset is only needed for frame-pointer based frames as we have |
1627 // to account for spill storage. | 1627 // to account for spill storage. |
1628 const int32_t ExtraOffset = | 1628 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg()) |
1629 (static_cast<SizeT>(Var->getRegNum()) == Target->getFrameReg()) | 1629 ? Target->getFrameFixedAllocaOffset() |
1630 ? Target->getFrameFixedAllocaOffset() | 1630 : 0; |
1631 : 0; | |
1632 | 1631 |
1633 const int32_t Offset = Var->getStackOffset() + ExtraOffset; | 1632 const int32_t Offset = Var->getStackOffset() + ExtraOffset; |
1634 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); | 1633 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); |
1635 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); | 1634 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); |
1636 Target->_mov(Dest, T); | 1635 Target->_mov(Dest, T); |
1637 Legalized = true; | 1636 Legalized = true; |
1638 } else { | 1637 } else { |
1639 if (!Var->hasReg()) { | 1638 if (!Var->hasReg()) { |
1640 // This is a _mov(Variable, Mem()), i.e., a load. | 1639 // This is a _mov(Variable, Mem()), i.e., a load. |
1641 const int32_t Offset = Var->getStackOffset(); | 1640 const int32_t Offset = Var->getStackOffset(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1689 bool AllowOffsets) { | 1688 bool AllowOffsets) { |
1690 assert(!Mem->isRegReg() || !Mem->getIndex()->isRematerializable()); | 1689 assert(!Mem->isRegReg() || !Mem->getIndex()->isRematerializable()); |
1691 assert( | 1690 assert( |
1692 Mem->isRegReg() || | 1691 Mem->isRegReg() || |
1693 Target->isLegalMemOffset(Mem->getType(), Mem->getOffset()->getValue())); | 1692 Target->isLegalMemOffset(Mem->getType(), Mem->getOffset()->getValue())); |
1694 | 1693 |
1695 bool Legalized = false; | 1694 bool Legalized = false; |
1696 Variable *Base = Mem->getBase(); | 1695 Variable *Base = Mem->getBase(); |
1697 int32_t Offset = Mem->isRegReg() ? 0 : Mem->getOffset()->getValue(); | 1696 int32_t Offset = Mem->isRegReg() ? 0 : Mem->getOffset()->getValue(); |
1698 if (Base->isRematerializable()) { | 1697 if (Base->isRematerializable()) { |
1699 const int32_t ExtraOffset = | 1698 const int32_t ExtraOffset = (Base->getRegNum() == Target->getFrameReg()) |
1700 (static_cast<SizeT>(Base->getRegNum()) == Target->getFrameReg()) | 1699 ? Target->getFrameFixedAllocaOffset() |
1701 ? Target->getFrameFixedAllocaOffset() | 1700 : 0; |
1702 : 0; | |
1703 Offset += Base->getStackOffset() + ExtraOffset; | 1701 Offset += Base->getStackOffset() + ExtraOffset; |
1704 Base = Target->getPhysicalRegister(Base->getRegNum()); | 1702 Base = Target->getPhysicalRegister(Base->getRegNum()); |
1705 assert(!Base->isRematerializable()); | 1703 assert(!Base->isRematerializable()); |
1706 Legalized = true; | 1704 Legalized = true; |
1707 } | 1705 } |
1708 | 1706 |
1709 if (!Legalized && !Target->NeedSandboxing) { | 1707 if (!Legalized && !Target->NeedSandboxing) { |
1710 return nullptr; | 1708 return nullptr; |
1711 } | 1709 } |
1712 | 1710 |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1912 } | 1910 } |
1913 } | 1911 } |
1914 llvm::report_fatal_error("Unsupported operand type"); | 1912 llvm::report_fatal_error("Unsupported operand type"); |
1915 return nullptr; | 1913 return nullptr; |
1916 } | 1914 } |
1917 | 1915 |
1918 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, | 1916 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, |
1919 RegSetMask Exclude) const { | 1917 RegSetMask Exclude) const { |
1920 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); | 1918 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); |
1921 | 1919 |
1922 for (int32_t i = 0; i < RegARM32::Reg_NUM; ++i) { | 1920 for (uint32_t i = 0; i < RegARM32::Reg_NUM; ++i) { |
1923 const auto &Entry = RegARM32::RegTable[i]; | 1921 const auto &Entry = RegARM32::RegTable[i]; |
1924 if (Entry.Scratch && (Include & RegSet_CallerSave)) | 1922 if (Entry.Scratch && (Include & RegSet_CallerSave)) |
1925 Registers[i] = true; | 1923 Registers[i] = true; |
1926 if (Entry.Preserved && (Include & RegSet_CalleeSave)) | 1924 if (Entry.Preserved && (Include & RegSet_CalleeSave)) |
1927 Registers[i] = true; | 1925 Registers[i] = true; |
1928 if (Entry.StackPtr && (Include & RegSet_StackPointer)) | 1926 if (Entry.StackPtr && (Include & RegSet_StackPointer)) |
1929 Registers[i] = true; | 1927 Registers[i] = true; |
1930 if (Entry.FramePtr && (Include & RegSet_FramePointer)) | 1928 if (Entry.FramePtr && (Include & RegSet_FramePointer)) |
1931 Registers[i] = true; | 1929 Registers[i] = true; |
1932 if (Entry.Scratch && (Exclude & RegSet_CallerSave)) | 1930 if (Entry.Scratch && (Exclude & RegSet_CallerSave)) |
(...skipping 1443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3376 if (TargetHelperPreamble != ARM32HelpersPreamble.end()) { | 3374 if (TargetHelperPreamble != ARM32HelpersPreamble.end()) { |
3377 (this->*TargetHelperPreamble->second)(Instr); | 3375 (this->*TargetHelperPreamble->second)(Instr); |
3378 } | 3376 } |
3379 } | 3377 } |
3380 MaybeLeafFunc = false; | 3378 MaybeLeafFunc = false; |
3381 NeedsStackAlignment = true; | 3379 NeedsStackAlignment = true; |
3382 | 3380 |
3383 // Assign arguments to registers and stack. Also reserve stack. | 3381 // Assign arguments to registers and stack. Also reserve stack. |
3384 TargetARM32::CallingConv CC; | 3382 TargetARM32::CallingConv CC; |
3385 // Pair of Arg Operand -> GPR number assignments. | 3383 // Pair of Arg Operand -> GPR number assignments. |
3386 llvm::SmallVector<std::pair<Operand *, int32_t>, NumGPRArgs> GPRArgs; | 3384 llvm::SmallVector<std::pair<Operand *, RegNumT>, NumGPRArgs> GPRArgs; |
3387 llvm::SmallVector<std::pair<Operand *, int32_t>, NumFP32Args> FPArgs; | 3385 llvm::SmallVector<std::pair<Operand *, RegNumT>, NumFP32Args> FPArgs; |
3388 // Pair of Arg Operand -> stack offset. | 3386 // Pair of Arg Operand -> stack offset. |
3389 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; | 3387 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; |
3390 size_t ParameterAreaSizeBytes = 0; | 3388 size_t ParameterAreaSizeBytes = 0; |
3391 | 3389 |
3392 // Classify each argument operand according to the location where the | 3390 // Classify each argument operand according to the location where the |
3393 // argument is passed. | 3391 // argument is passed. |
3394 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { | 3392 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { |
3395 Operand *Arg = legalizeUndef(Instr->getArg(i)); | 3393 Operand *Arg = legalizeUndef(Instr->getArg(i)); |
3396 const Type Ty = Arg->getType(); | 3394 const Type Ty = Arg->getType(); |
3397 bool InReg = false; | 3395 bool InReg = false; |
3398 int32_t Reg; | 3396 RegNumT Reg; |
3399 if (isScalarIntegerType(Ty)) { | 3397 if (isScalarIntegerType(Ty)) { |
3400 InReg = CC.argInGPR(Ty, &Reg); | 3398 InReg = CC.argInGPR(Ty, &Reg); |
3401 } else { | 3399 } else { |
3402 InReg = CC.argInVFP(Ty, &Reg); | 3400 InReg = CC.argInVFP(Ty, &Reg); |
3403 } | 3401 } |
3404 | 3402 |
3405 if (!InReg) { | 3403 if (!InReg) { |
3406 ParameterAreaSizeBytes = | 3404 ParameterAreaSizeBytes = |
3407 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); | 3405 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); |
3408 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); | 3406 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); |
3409 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); | 3407 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); |
3410 continue; | 3408 continue; |
3411 } | 3409 } |
3412 | 3410 |
3413 if (Ty == IceType_i64) { | 3411 if (Ty == IceType_i64) { |
3414 Operand *Lo = loOperand(Arg); | 3412 Operand *Lo = loOperand(Arg); |
3415 Operand *Hi = hiOperand(Arg); | 3413 Operand *Hi = hiOperand(Arg); |
3416 GPRArgs.push_back( | 3414 GPRArgs.push_back(std::make_pair( |
3417 std::make_pair(Lo, RegARM32::getI64PairFirstGPRNum(Reg))); | 3415 Lo, RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(Reg)))); |
3418 GPRArgs.push_back( | 3416 GPRArgs.push_back(std::make_pair( |
3419 std::make_pair(Hi, RegARM32::getI64PairSecondGPRNum(Reg))); | 3417 Hi, RegNumT::fixme(RegARM32::getI64PairSecondGPRNum(Reg)))); |
3420 } else if (isScalarIntegerType(Ty)) { | 3418 } else if (isScalarIntegerType(Ty)) { |
3421 GPRArgs.push_back(std::make_pair(Arg, Reg)); | 3419 GPRArgs.push_back(std::make_pair(Arg, Reg)); |
3422 } else { | 3420 } else { |
3423 FPArgs.push_back(std::make_pair(Arg, Reg)); | 3421 FPArgs.push_back(std::make_pair(Arg, Reg)); |
3424 } | 3422 } |
3425 } | 3423 } |
3426 | 3424 |
3427 // Adjust the parameter area so that the stack is aligned. It is assumed that | 3425 // Adjust the parameter area so that the stack is aligned. It is assumed that |
3428 // the stack is already aligned at the start of the calling sequence. | 3426 // the stack is already aligned at the start of the calling sequence. |
3429 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes); | 3427 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes); |
(...skipping 2081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5511 } | 5509 } |
5512 | 5510 |
5513 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) { | 5511 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) { |
5514 _trap(); | 5512 _trap(); |
5515 } | 5513 } |
5516 | 5514 |
5517 void TargetARM32::prelowerPhis() { | 5515 void TargetARM32::prelowerPhis() { |
5518 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); | 5516 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); |
5519 } | 5517 } |
5520 | 5518 |
5521 Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) { | 5519 Variable *TargetARM32::makeVectorOfZeros(Type Ty, RegNumT RegNum) { |
5522 Variable *Reg = makeReg(Ty, RegNum); | 5520 Variable *Reg = makeReg(Ty, RegNum); |
5523 Context.insert<InstFakeDef>(Reg); | 5521 Context.insert<InstFakeDef>(Reg); |
5524 assert(isVectorType(Ty)); | 5522 assert(isVectorType(Ty)); |
5525 _veor(Reg, Reg, Reg); | 5523 _veor(Reg, Reg, Reg); |
5526 return Reg; | 5524 return Reg; |
5527 } | 5525 } |
5528 | 5526 |
5529 // Helper for legalize() to emit the right code to lower an operand to a | 5527 // Helper for legalize() to emit the right code to lower an operand to a |
5530 // register of the appropriate type. | 5528 // register of the appropriate type. |
5531 Variable *TargetARM32::copyToReg(Operand *Src, int32_t RegNum) { | 5529 Variable *TargetARM32::copyToReg(Operand *Src, RegNumT RegNum) { |
5532 Type Ty = Src->getType(); | 5530 Type Ty = Src->getType(); |
5533 Variable *Reg = makeReg(Ty, RegNum); | 5531 Variable *Reg = makeReg(Ty, RegNum); |
5534 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) { | 5532 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) { |
5535 _ldr(Reg, Mem); | 5533 _ldr(Reg, Mem); |
5536 } else { | 5534 } else { |
5537 _mov(Reg, Src); | 5535 _mov(Reg, Src); |
5538 } | 5536 } |
5539 return Reg; | 5537 return Reg; |
5540 } | 5538 } |
5541 | 5539 |
5542 // TODO(jpp): remove unneeded else clauses in legalize. | 5540 // TODO(jpp): remove unneeded else clauses in legalize. |
5543 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, | 5541 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, |
5544 int32_t RegNum) { | 5542 RegNumT RegNum) { |
5545 Type Ty = From->getType(); | 5543 Type Ty = From->getType(); |
5546 // Assert that a physical register is allowed. To date, all calls to | 5544 // Assert that a physical register is allowed. To date, all calls to |
5547 // legalize() allow a physical register. Legal_Flex converts registers to the | 5545 // legalize() allow a physical register. Legal_Flex converts registers to the |
5548 // right type OperandARM32FlexReg as needed. | 5546 // right type OperandARM32FlexReg as needed. |
5549 assert(Allowed & Legal_Reg); | 5547 assert(Allowed & Legal_Reg); |
5550 | 5548 |
5551 // Copied ipsis literis from TargetX86Base<Machine>. | 5549 // Copied ipsis literis from TargetX86Base<Machine>. |
5552 if (RegNum == Variable::NoRegister) { | 5550 if (RegNum == RegNumT::NoRegister) { |
5553 if (Variable *Subst = getContext().availabilityGet(From)) { | 5551 if (Variable *Subst = getContext().availabilityGet(From)) { |
5554 // At this point we know there is a potential substitution available. | 5552 // At this point we know there is a potential substitution available. |
5555 if (!Subst->isRematerializable() && Subst->mustHaveReg() && | 5553 if (!Subst->isRematerializable() && Subst->mustHaveReg() && |
5556 !Subst->hasReg()) { | 5554 !Subst->hasReg()) { |
5557 // At this point we know the substitution will have a register. | 5555 // At this point we know the substitution will have a register. |
5558 if (From->getType() == Subst->getType()) { | 5556 if (From->getType() == Subst->getType()) { |
5559 // At this point we know the substitution's register is compatible. | 5557 // At this point we know the substitution's register is compatible. |
5560 return Subst; | 5558 return Subst; |
5561 } | 5559 } |
5562 } | 5560 } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5726 } | 5724 } |
5727 // Check if the variable is guaranteed a physical register. This can happen | 5725 // Check if the variable is guaranteed a physical register. This can happen |
5728 // either when the variable is pre-colored or when it is assigned infinite | 5726 // either when the variable is pre-colored or when it is assigned infinite |
5729 // weight. | 5727 // weight. |
5730 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); | 5728 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
5731 // We need a new physical register for the operand if: | 5729 // We need a new physical register for the operand if: |
5732 // Mem is not allowed and Var isn't guaranteed a physical | 5730 // Mem is not allowed and Var isn't guaranteed a physical |
5733 // register, or | 5731 // register, or |
5734 // RegNum is required and Var->getRegNum() doesn't match. | 5732 // RegNum is required and Var->getRegNum() doesn't match. |
5735 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 5733 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
5736 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 5734 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) { |
5737 From = copyToReg(From, RegNum); | 5735 From = copyToReg(From, RegNum); |
5738 } | 5736 } |
5739 return From; | 5737 return From; |
5740 } | 5738 } |
5741 llvm::report_fatal_error("Unhandled operand kind in legalize()"); | 5739 llvm::report_fatal_error("Unhandled operand kind in legalize()"); |
5742 | 5740 |
5743 return From; | 5741 return From; |
5744 } | 5742 } |
5745 | 5743 |
5746 /// Provide a trivial wrapper to legalize() for this common usage. | 5744 /// Provide a trivial wrapper to legalize() for this common usage. |
5747 Variable *TargetARM32::legalizeToReg(Operand *From, int32_t RegNum) { | 5745 Variable *TargetARM32::legalizeToReg(Operand *From, RegNumT RegNum) { |
5748 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); | 5746 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); |
5749 } | 5747 } |
5750 | 5748 |
5751 /// Legalize undef values to concrete values. | 5749 /// Legalize undef values to concrete values. |
5752 Operand *TargetARM32::legalizeUndef(Operand *From, int32_t RegNum) { | 5750 Operand *TargetARM32::legalizeUndef(Operand *From, RegNumT RegNum) { |
5753 Type Ty = From->getType(); | 5751 Type Ty = From->getType(); |
5754 if (llvm::isa<ConstantUndef>(From)) { | 5752 if (llvm::isa<ConstantUndef>(From)) { |
5755 // Lower undefs to zero. Another option is to lower undefs to an | 5753 // Lower undefs to zero. Another option is to lower undefs to an |
5756 // uninitialized register; however, using an uninitialized register results | 5754 // uninitialized register; however, using an uninitialized register results |
5757 // in less predictable code. | 5755 // in less predictable code. |
5758 // | 5756 // |
5759 // If in the future the implementation is changed to lower undef values to | 5757 // If in the future the implementation is changed to lower undef values to |
5760 // uninitialized registers, a FakeDef will be needed: | 5758 // uninitialized registers, a FakeDef will be needed: |
5761 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to | 5759 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to |
5762 // ensure that the live range of Reg is not overestimated. If the constant | 5760 // ensure that the live range of Reg is not overestimated. If the constant |
(...skipping 27 matching lines...) Expand all Loading... |
5790 Variable64On32 *TargetARM32::makeI64RegPair() { | 5788 Variable64On32 *TargetARM32::makeI64RegPair() { |
5791 Variable64On32 *Reg = | 5789 Variable64On32 *Reg = |
5792 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); | 5790 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); |
5793 Reg->setMustHaveReg(); | 5791 Reg->setMustHaveReg(); |
5794 Reg->initHiLo(Func); | 5792 Reg->initHiLo(Func); |
5795 Reg->getLo()->setMustNotHaveReg(); | 5793 Reg->getLo()->setMustNotHaveReg(); |
5796 Reg->getHi()->setMustNotHaveReg(); | 5794 Reg->getHi()->setMustNotHaveReg(); |
5797 return Reg; | 5795 return Reg; |
5798 } | 5796 } |
5799 | 5797 |
5800 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { | 5798 Variable *TargetARM32::makeReg(Type Type, RegNumT RegNum) { |
5801 // There aren't any 64-bit integer registers for ARM32. | 5799 // There aren't any 64-bit integer registers for ARM32. |
5802 assert(Type != IceType_i64); | 5800 assert(Type != IceType_i64); |
5803 assert(AllowTemporaryWithNoReg || RegNum != Variable::NoRegister); | 5801 assert(AllowTemporaryWithNoReg || RegNum != RegNumT::NoRegister); |
5804 Variable *Reg = Func->makeVariable(Type); | 5802 Variable *Reg = Func->makeVariable(Type); |
5805 if (RegNum == Variable::NoRegister) | 5803 if (RegNum == RegNumT::NoRegister) |
5806 Reg->setMustHaveReg(); | 5804 Reg->setMustHaveReg(); |
5807 else | 5805 else |
5808 Reg->setRegNum(RegNum); | 5806 Reg->setRegNum(RegNum); |
5809 return Reg; | 5807 return Reg; |
5810 } | 5808 } |
5811 | 5809 |
5812 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align, | 5810 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align, |
5813 int32_t TmpRegNum) { | 5811 RegNumT TmpRegNum) { |
5814 assert(llvm::isPowerOf2_32(Align)); | 5812 assert(llvm::isPowerOf2_32(Align)); |
5815 uint32_t RotateAmt; | 5813 uint32_t RotateAmt; |
5816 uint32_t Immed_8; | 5814 uint32_t Immed_8; |
5817 Operand *Mask; | 5815 Operand *Mask; |
5818 // Use AND or BIC to mask off the bits, depending on which immediate fits (if | 5816 // Use AND or BIC to mask off the bits, depending on which immediate fits (if |
5819 // it fits at all). Assume Align is usually small, in which case BIC works | 5817 // it fits at all). Assume Align is usually small, in which case BIC works |
5820 // better. Thus, this rounds down to the alignment. | 5818 // better. Thus, this rounds down to the alignment. |
5821 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) { | 5819 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) { |
5822 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex, | 5820 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex, |
5823 TmpRegNum); | 5821 TmpRegNum); |
5824 _bic(Reg, Reg, Mask); | 5822 _bic(Reg, Reg, Mask); |
5825 } else { | 5823 } else { |
5826 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex, | 5824 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex, |
5827 TmpRegNum); | 5825 TmpRegNum); |
5828 _and(Reg, Reg, Mask); | 5826 _and(Reg, Reg, Mask); |
5829 } | 5827 } |
5830 } | 5828 } |
5831 | 5829 |
5832 void TargetARM32::postLower() { | 5830 void TargetARM32::postLower() { |
5833 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 5831 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
5834 return; | 5832 return; |
5835 markRedefinitions(); | 5833 markRedefinitions(); |
5836 Context.availabilityUpdate(); | 5834 Context.availabilityUpdate(); |
5837 } | 5835 } |
5838 | 5836 |
5839 void TargetARM32::makeRandomRegisterPermutation( | 5837 void TargetARM32::makeRandomRegisterPermutation( |
5840 llvm::SmallVectorImpl<int32_t> &Permutation, | 5838 llvm::SmallVectorImpl<RegNumT> &Permutation, |
5841 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 5839 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
5842 (void)Permutation; | 5840 (void)Permutation; |
5843 (void)ExcludeRegisters; | 5841 (void)ExcludeRegisters; |
5844 (void)Salt; | 5842 (void)Salt; |
5845 UnimplementedError(Func->getContext()->getFlags()); | 5843 UnimplementedError(Func->getContext()->getFlags()); |
5846 } | 5844 } |
5847 | 5845 |
5848 void TargetARM32::emit(const ConstantInteger32 *C) const { | 5846 void TargetARM32::emit(const ConstantInteger32 *C) const { |
5849 if (!BuildDefs::dump()) | 5847 if (!BuildDefs::dump()) |
5850 return; | 5848 return; |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6585 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6583 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
6586 } | 6584 } |
6587 | 6585 |
6588 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; | 6586 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; |
6589 llvm::SmallBitVector | 6587 llvm::SmallBitVector |
6590 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; | 6588 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; |
6591 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6589 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
6592 | 6590 |
6593 } // end of namespace ARM32 | 6591 } // end of namespace ARM32 |
6594 } // end of namespace Ice | 6592 } // end of namespace Ice |
OLD | NEW |