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 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; | 339 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; |
340 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; | 340 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; |
341 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; | 341 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; |
342 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; | 342 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; |
343 | 343 |
344 for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i) | 344 for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i) |
345 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; | 345 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; |
346 | 346 |
347 filterTypeToRegisterSet( | 347 filterTypeToRegisterSet( |
348 Ctx, RegARM32::Reg_NUM, TypeToRegisterSet, | 348 Ctx, RegARM32::Reg_NUM, TypeToRegisterSet, |
349 llvm::array_lengthof(TypeToRegisterSet), [](int32_t RegNum) -> IceString { | 349 llvm::array_lengthof(TypeToRegisterSet), [](RegNumT RegNum) -> IceString { |
350 // This function simply removes ", " from the register name. | 350 // This function simply removes ", " from the register name. |
351 IceString Name = RegARM32::getRegName(RegNum); | 351 IceString Name = RegARM32::getRegName(RegNum); |
352 constexpr const char RegSeparator[] = ", "; | 352 constexpr const char RegSeparator[] = ", "; |
353 constexpr size_t RegSeparatorWidth = | 353 constexpr size_t RegSeparatorWidth = |
354 llvm::array_lengthof(RegSeparator) - 1; | 354 llvm::array_lengthof(RegSeparator) - 1; |
355 for (size_t Pos = Name.find(RegSeparator); Pos != std::string::npos; | 355 for (size_t Pos = Name.find(RegSeparator); Pos != std::string::npos; |
356 Pos = Name.find(RegSeparator)) { | 356 Pos = Name.find(RegSeparator)) { |
357 Name.replace(Pos, RegSeparatorWidth, ""); | 357 Name.replace(Pos, RegSeparatorWidth, ""); |
358 } | 358 } |
359 return Name; | 359 return Name; |
(...skipping 15 matching lines...) Expand all Loading... | |
375 SizeT FirstReg = RegARM32::getI64PairFirstGPRNum(Var->getRegNum()); | 375 SizeT FirstReg = RegARM32::getI64PairFirstGPRNum(Var->getRegNum()); |
376 // This assumes little endian. | 376 // This assumes little endian. |
377 Variable *Lo = Var64->getLo(); | 377 Variable *Lo = Var64->getLo(); |
378 Variable *Hi = Var64->getHi(); | 378 Variable *Hi = Var64->getHi(); |
379 assert(Lo->hasReg() == Hi->hasReg()); | 379 assert(Lo->hasReg() == Hi->hasReg()); |
380 if (Lo->hasReg()) { | 380 if (Lo->hasReg()) { |
381 continue; | 381 continue; |
382 } | 382 } |
383 Lo->setRegNum(FirstReg); | 383 Lo->setRegNum(FirstReg); |
384 Lo->setMustHaveReg(); | 384 Lo->setMustHaveReg(); |
385 Hi->setRegNum(FirstReg + 1); | 385 Hi->setRegNum(RegNumT::fixme(FirstReg + 1)); |
386 Hi->setMustHaveReg(); | 386 Hi->setMustHaveReg(); |
387 } | 387 } |
388 } | 388 } |
389 } // end of anonymous namespace | 389 } // end of anonymous namespace |
390 | 390 |
391 uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) { | 391 uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) { |
392 TargetARM32::CallingConv CC; | 392 TargetARM32::CallingConv CC; |
393 int32_t DummyReg; | 393 RegNumT DummyReg; |
394 size_t OutArgsSizeBytes = 0; | 394 size_t OutArgsSizeBytes = 0; |
395 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { | 395 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { |
396 Operand *Arg = legalizeUndef(Call->getArg(i)); | 396 Operand *Arg = legalizeUndef(Call->getArg(i)); |
397 const Type Ty = Arg->getType(); | 397 const Type Ty = Arg->getType(); |
398 if (isScalarIntegerType(Ty)) { | 398 if (isScalarIntegerType(Ty)) { |
399 if (CC.argInGPR(Ty, &DummyReg)) { | 399 if (CC.argInGPR(Ty, &DummyReg)) { |
400 continue; | 400 continue; |
401 } | 401 } |
402 } else { | 402 } else { |
403 if (CC.argInVFP(Ty, &DummyReg)) { | 403 if (CC.argInVFP(Ty, &DummyReg)) { |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
895 return ARM32_STACK_ALIGNMENT_BYTES; | 895 return ARM32_STACK_ALIGNMENT_BYTES; |
896 } | 896 } |
897 | 897 |
898 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { | 898 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { |
899 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { | 899 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { |
900 return Br->optimizeBranch(NextNode); | 900 return Br->optimizeBranch(NextNode); |
901 } | 901 } |
902 return false; | 902 return false; |
903 } | 903 } |
904 | 904 |
905 IceString TargetARM32::getRegName(SizeT RegNum, Type Ty) const { | 905 IceString TargetARM32::getRegName(RegNumT RegNum, Type Ty) const { |
906 assert(RegNum < RegARM32::Reg_NUM); | |
907 (void)Ty; | 906 (void)Ty; |
908 return RegARM32::getRegName(RegNum); | 907 return RegARM32::getRegName(RegNum); |
909 } | 908 } |
910 | 909 |
911 Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) { | 910 Variable *TargetARM32::getPhysicalRegister(RegNumT RegNum, Type Ty) { |
912 static const Type DefaultType[] = { | 911 static const Type DefaultType[] = { |
913 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ | 912 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ |
914 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 913 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
915 (isFP32) \ | 914 (isFP32) \ |
916 ? IceType_f32 \ | 915 ? IceType_f32 \ |
917 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), | 916 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), |
918 REGARM32_TABLE | 917 REGARM32_TABLE |
919 #undef X | 918 #undef X |
920 }; | 919 }; |
921 | 920 |
922 assert(RegNum < RegARM32::Reg_NUM); | 921 assert(unsigned(RegNum) < RegARM32::Reg_NUM); |
923 if (Ty == IceType_void) { | 922 if (Ty == IceType_void) { |
924 assert(RegNum < llvm::array_lengthof(DefaultType)); | 923 assert(unsigned(RegNum) < llvm::array_lengthof(DefaultType)); |
925 Ty = DefaultType[RegNum]; | 924 Ty = DefaultType[RegNum]; |
926 } | 925 } |
927 if (PhysicalRegisters[Ty].empty()) | 926 if (PhysicalRegisters[Ty].empty()) |
928 PhysicalRegisters[Ty].resize(RegARM32::Reg_NUM); | 927 PhysicalRegisters[Ty].resize(RegARM32::Reg_NUM); |
929 assert(RegNum < PhysicalRegisters[Ty].size()); | 928 assert(unsigned(RegNum) < PhysicalRegisters[Ty].size()); |
930 Variable *Reg = PhysicalRegisters[Ty][RegNum]; | 929 Variable *Reg = PhysicalRegisters[Ty][RegNum]; |
931 if (Reg == nullptr) { | 930 if (Reg == nullptr) { |
932 Reg = Func->makeVariable(Ty); | 931 Reg = Func->makeVariable(Ty); |
933 Reg->setRegNum(RegNum); | 932 Reg->setRegNum(RegNum); |
934 PhysicalRegisters[Ty][RegNum] = Reg; | 933 PhysicalRegisters[Ty][RegNum] = Reg; |
935 // Specially mark a named physical register as an "argument" so that it is | 934 // Specially mark a named physical register as an "argument" so that it is |
936 // considered live upon function entry. Otherwise it's possible to get | 935 // considered live upon function entry. Otherwise it's possible to get |
937 // liveness validation errors for saving callee-save registers. | 936 // liveness validation errors for saving callee-save registers. |
938 Func->addImplicitArg(Reg); | 937 Func->addImplicitArg(Reg); |
939 // Don't bother tracking the live range of a named physical register. | 938 // Don't bother tracking the live range of a named physical register. |
(...skipping 16 matching lines...) Expand all Loading... | |
956 Str << getRegName(Var->getRegNum(), Var->getType()); | 955 Str << getRegName(Var->getRegNum(), Var->getType()); |
957 return; | 956 return; |
958 } | 957 } |
959 if (Var->mustHaveReg()) { | 958 if (Var->mustHaveReg()) { |
960 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + | 959 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + |
961 ") has no register assigned - function " + | 960 ") has no register assigned - function " + |
962 Func->getFunctionName()); | 961 Func->getFunctionName()); |
963 } | 962 } |
964 assert(!Var->isRematerializable()); | 963 assert(!Var->isRematerializable()); |
965 int32_t Offset = Var->getStackOffset(); | 964 int32_t Offset = Var->getStackOffset(); |
966 int32_t BaseRegNum = Var->getBaseRegNum(); | 965 RegNumT BaseRegNum = Var->getBaseRegNum(); |
967 if (BaseRegNum == Variable::NoRegister) { | 966 if (BaseRegNum == RegNumT::NoRegister) { |
968 BaseRegNum = getFrameOrStackReg(); | 967 BaseRegNum = getFrameOrStackReg(); |
969 } | 968 } |
970 const Type VarTy = Var->getType(); | 969 const Type VarTy = Var->getType(); |
971 Str << "[" << getRegName(BaseRegNum, VarTy); | 970 Str << "[" << getRegName(BaseRegNum, VarTy); |
972 if (Offset != 0) { | 971 if (Offset != 0) { |
973 Str << ", #" << Offset; | 972 Str << ", #" << Offset; |
974 } | 973 } |
975 Str << "]"; | 974 Str << "]"; |
976 } | 975 } |
977 | 976 |
978 TargetARM32::CallingConv::CallingConv() | 977 TargetARM32::CallingConv::CallingConv() |
979 : GPRegsUsed(RegARM32::Reg_NUM), | 978 : GPRegsUsed(RegARM32::Reg_NUM), |
980 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()), | 979 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()), |
981 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()), | 980 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()), |
982 VFPRegsUsed(RegARM32::Reg_NUM), | 981 VFPRegsUsed(RegARM32::Reg_NUM), |
983 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()), | 982 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()), |
984 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()), | 983 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()), |
985 Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {} | 984 Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {} |
986 | 985 |
987 bool TargetARM32::CallingConv::argInGPR(Type Ty, int32_t *Reg) { | 986 bool TargetARM32::CallingConv::argInGPR(Type Ty, RegNumT *Reg) { |
988 CfgVector<SizeT> *Source; | 987 CfgVector<SizeT> *Source; |
989 | 988 |
990 switch (Ty) { | 989 switch (Ty) { |
991 default: { | 990 default: { |
992 assert(isScalarIntegerType(Ty)); | 991 assert(isScalarIntegerType(Ty)); |
993 Source = &GPRArgs; | 992 Source = &GPRArgs; |
994 } break; | 993 } break; |
995 case IceType_i64: { | 994 case IceType_i64: { |
996 Source = &I64Args; | 995 Source = &I64Args; |
997 } break; | 996 } break; |
(...skipping 21 matching lines...) Expand all Loading... | |
1019 // we remove all of its aliases from the pool of available GPRs. This has the | 1018 // we remove all of its aliases from the pool of available GPRs. This has the |
1020 // effect of computing the "closure" on the GPR registers. | 1019 // effect of computing the "closure" on the GPR registers. |
1021 void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases( | 1020 void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases( |
1022 CfgVector<SizeT> *Regs) { | 1021 CfgVector<SizeT> *Regs) { |
1023 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { | 1022 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { |
1024 GPRegsUsed |= RegisterAliases[Regs->back()]; | 1023 GPRegsUsed |= RegisterAliases[Regs->back()]; |
1025 Regs->pop_back(); | 1024 Regs->pop_back(); |
1026 } | 1025 } |
1027 } | 1026 } |
1028 | 1027 |
1029 bool TargetARM32::CallingConv::argInVFP(Type Ty, int32_t *Reg) { | 1028 bool TargetARM32::CallingConv::argInVFP(Type Ty, RegNumT *Reg) { |
1030 CfgVector<SizeT> *Source; | 1029 CfgVector<SizeT> *Source; |
1031 | 1030 |
1032 switch (Ty) { | 1031 switch (Ty) { |
1033 default: { | 1032 default: { |
1034 assert(isVectorType(Ty)); | 1033 assert(isVectorType(Ty)); |
1035 Source = &Vec128Args; | 1034 Source = &Vec128Args; |
1036 } break; | 1035 } break; |
1037 case IceType_f32: { | 1036 case IceType_f32: { |
1038 Source = &FP32Args; | 1037 Source = &FP32Args; |
1039 } break; | 1038 } break; |
(...skipping 29 matching lines...) Expand all Loading... | |
1069 | 1068 |
1070 // For each register argument, replace Arg in the argument list with the home | 1069 // For each register argument, replace Arg in the argument list with the home |
1071 // register. Then generate an instruction in the prolog to copy the home | 1070 // register. Then generate an instruction in the prolog to copy the home |
1072 // register to the assigned location of Arg. | 1071 // register to the assigned location of Arg. |
1073 Context.init(Func->getEntryNode()); | 1072 Context.init(Func->getEntryNode()); |
1074 Context.setInsertPoint(Context.getCur()); | 1073 Context.setInsertPoint(Context.getCur()); |
1075 | 1074 |
1076 for (SizeT I = 0, E = Args.size(); I < E; ++I) { | 1075 for (SizeT I = 0, E = Args.size(); I < E; ++I) { |
1077 Variable *Arg = Args[I]; | 1076 Variable *Arg = Args[I]; |
1078 Type Ty = Arg->getType(); | 1077 Type Ty = Arg->getType(); |
1079 int RegNum; | 1078 RegNumT RegNum; |
1080 if (isScalarIntegerType(Ty)) { | 1079 if (isScalarIntegerType(Ty)) { |
1081 if (!CC.argInGPR(Ty, &RegNum)) { | 1080 if (!CC.argInGPR(Ty, &RegNum)) { |
1082 continue; | 1081 continue; |
1083 } | 1082 } |
1084 } else { | 1083 } else { |
1085 if (!CC.argInVFP(Ty, &RegNum)) { | 1084 if (!CC.argInVFP(Ty, &RegNum)) { |
1086 continue; | 1085 continue; |
1087 } | 1086 } |
1088 } | 1087 } |
1089 | 1088 |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1355 // Arg[0] is closest to the stack/frame pointer. | 1354 // Arg[0] is closest to the stack/frame pointer. |
1356 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); | 1355 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); |
1357 size_t BasicFrameOffset = PreservedRegsSizeBytes; | 1356 size_t BasicFrameOffset = PreservedRegsSizeBytes; |
1358 if (!UsesFramePointer) | 1357 if (!UsesFramePointer) |
1359 BasicFrameOffset += SpillAreaSizeBytes; | 1358 BasicFrameOffset += SpillAreaSizeBytes; |
1360 | 1359 |
1361 const VarList &Args = Func->getArgs(); | 1360 const VarList &Args = Func->getArgs(); |
1362 size_t InArgsSizeBytes = 0; | 1361 size_t InArgsSizeBytes = 0; |
1363 TargetARM32::CallingConv CC; | 1362 TargetARM32::CallingConv CC; |
1364 for (Variable *Arg : Args) { | 1363 for (Variable *Arg : Args) { |
1365 int32_t DummyReg; | 1364 RegNumT DummyReg; |
1366 const Type Ty = Arg->getType(); | 1365 const Type Ty = Arg->getType(); |
1367 | 1366 |
1368 // Skip arguments passed in registers. | 1367 // Skip arguments passed in registers. |
1369 if (isScalarIntegerType(Ty)) { | 1368 if (isScalarIntegerType(Ty)) { |
1370 if (CC.argInGPR(Ty, &DummyReg)) { | 1369 if (CC.argInGPR(Ty, &DummyReg)) { |
1371 continue; | 1370 continue; |
1372 } | 1371 } |
1373 } else { | 1372 } else { |
1374 if (CC.argInVFP(Ty, &DummyReg)) { | 1373 if (CC.argInVFP(Ty, &DummyReg)) { |
1375 continue; | 1374 continue; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1474 | 1473 |
1475 RI->setDeleted(); | 1474 RI->setDeleted(); |
1476 } | 1475 } |
1477 | 1476 |
1478 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const { | 1477 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const { |
1479 constexpr bool ZeroExt = false; | 1478 constexpr bool ZeroExt = false; |
1480 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset); | 1479 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset); |
1481 } | 1480 } |
1482 | 1481 |
1483 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister( | 1482 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister( |
1484 Variable *Base, int32_t Offset, int32_t ScratchRegNum) { | 1483 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { |
1485 // Legalize will likely need a movw/movt combination, but if the top bits are | 1484 // Legalize will likely need a movw/movt combination, but if the top bits are |
1486 // all 0 from negating the offset and subtracting, we could use that instead. | 1485 // all 0 from negating the offset and subtracting, we could use that instead. |
1487 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; | 1486 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; |
1488 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); | 1487 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); |
1489 if (ShouldSub) { | 1488 if (ShouldSub) { |
1490 Operand *OffsetVal = | 1489 Operand *OffsetVal = |
1491 Target->legalize(Target->Ctx->getConstantInt32(-Offset), | 1490 Target->legalize(Target->Ctx->getConstantInt32(-Offset), |
1492 Legal_Reg | Legal_Flex, ScratchRegNum); | 1491 Legal_Reg | Legal_Flex, ScratchRegNum); |
1493 Target->_sub(ScratchReg, Base, OffsetVal); | 1492 Target->_sub(ScratchReg, Base, OffsetVal); |
1494 } else { | 1493 } else { |
1495 Operand *OffsetVal = | 1494 Operand *OffsetVal = |
1496 Target->legalize(Target->Ctx->getConstantInt32(Offset), | 1495 Target->legalize(Target->Ctx->getConstantInt32(Offset), |
1497 Legal_Reg | Legal_Flex, ScratchRegNum); | 1496 Legal_Reg | Legal_Flex, ScratchRegNum); |
1498 Target->_add(ScratchReg, Base, OffsetVal); | 1497 Target->_add(ScratchReg, Base, OffsetVal); |
1499 } | 1498 } |
1500 | 1499 |
1501 if (ScratchRegNum == Target->getReservedTmpReg()) { | 1500 if (ScratchRegNum == Target->getReservedTmpReg()) { |
1502 const bool BaseIsStackOrFramePtr = | 1501 const bool BaseIsStackOrFramePtr = |
1503 Base->getRegNum() == static_cast<int32_t>(Target->getFrameOrStackReg()); | 1502 Base->getRegNum() == Target->getFrameOrStackReg(); |
1504 // There is currently no code path that would trigger this assertion, so we | 1503 // There is currently no code path that would trigger this assertion, so we |
1505 // leave this assertion here in case it is ever violated. This is not a | 1504 // leave this assertion here in case it is ever violated. This is not a |
1506 // fatal error (thus the use of assert() and not llvm::report_fatal_error) | 1505 // fatal error (thus the use of assert() and not llvm::report_fatal_error) |
1507 // as the program compiled by subzero will still work correctly. | 1506 // as the program compiled by subzero will still work correctly. |
1508 assert(BaseIsStackOrFramePtr); | 1507 assert(BaseIsStackOrFramePtr); |
1509 // Side-effect: updates TempBase to reflect the new Temporary. | 1508 // Side-effect: updates TempBase to reflect the new Temporary. |
1510 if (BaseIsStackOrFramePtr) { | 1509 if (BaseIsStackOrFramePtr) { |
1511 TempBaseReg = ScratchReg; | 1510 TempBaseReg = ScratchReg; |
1512 TempBaseOffset = Offset; | 1511 TempBaseOffset = Offset; |
1513 } else { | 1512 } else { |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1600 MovInstr->getPredicate()); | 1599 MovInstr->getPredicate()); |
1601 // _str() does not have a Dest, so we add a fake-def(Dest). | 1600 // _str() does not have a Dest, so we add a fake-def(Dest). |
1602 Target->Context.insert<InstFakeDef>(Dest); | 1601 Target->Context.insert<InstFakeDef>(Dest); |
1603 Legalized = true; | 1602 Legalized = true; |
1604 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | 1603 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
1605 if (Var->isRematerializable()) { | 1604 if (Var->isRematerializable()) { |
1606 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | 1605 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
1607 | 1606 |
1608 // ExtraOffset is only needed for frame-pointer based frames as we have | 1607 // ExtraOffset is only needed for frame-pointer based frames as we have |
1609 // to account for spill storage. | 1608 // to account for spill storage. |
1610 const int32_t ExtraOffset = | 1609 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg()) |
1611 (static_cast<SizeT>(Var->getRegNum()) == Target->getFrameReg()) | 1610 ? Target->getFrameFixedAllocaOffset() |
1612 ? Target->getFrameFixedAllocaOffset() | 1611 : 0; |
1613 : 0; | |
1614 | 1612 |
1615 const int32_t Offset = Var->getStackOffset() + ExtraOffset; | 1613 const int32_t Offset = Var->getStackOffset() + ExtraOffset; |
1616 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); | 1614 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); |
1617 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); | 1615 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); |
1618 Target->_mov(Dest, T); | 1616 Target->_mov(Dest, T); |
1619 Legalized = true; | 1617 Legalized = true; |
1620 } else { | 1618 } else { |
1621 if (!Var->hasReg()) { | 1619 if (!Var->hasReg()) { |
1622 // This is a _mov(Variable, Mem()), i.e., a load. | 1620 // This is a _mov(Variable, Mem()), i.e., a load. |
1623 const int32_t Offset = Var->getStackOffset(); | 1621 const int32_t Offset = Var->getStackOffset(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1671 bool AllowOffsets) { | 1669 bool AllowOffsets) { |
1672 assert(!Mem->isRegReg() || !Mem->getIndex()->isRematerializable()); | 1670 assert(!Mem->isRegReg() || !Mem->getIndex()->isRematerializable()); |
1673 assert( | 1671 assert( |
1674 Mem->isRegReg() || | 1672 Mem->isRegReg() || |
1675 Target->isLegalMemOffset(Mem->getType(), Mem->getOffset()->getValue())); | 1673 Target->isLegalMemOffset(Mem->getType(), Mem->getOffset()->getValue())); |
1676 | 1674 |
1677 bool Legalized = false; | 1675 bool Legalized = false; |
1678 Variable *Base = Mem->getBase(); | 1676 Variable *Base = Mem->getBase(); |
1679 int32_t Offset = Mem->isRegReg() ? 0 : Mem->getOffset()->getValue(); | 1677 int32_t Offset = Mem->isRegReg() ? 0 : Mem->getOffset()->getValue(); |
1680 if (Base->isRematerializable()) { | 1678 if (Base->isRematerializable()) { |
1681 const int32_t ExtraOffset = | 1679 const int32_t ExtraOffset = (Base->getRegNum() == Target->getFrameReg()) |
1682 (static_cast<SizeT>(Base->getRegNum()) == Target->getFrameReg()) | 1680 ? Target->getFrameFixedAllocaOffset() |
1683 ? Target->getFrameFixedAllocaOffset() | 1681 : 0; |
1684 : 0; | |
1685 Offset += Base->getStackOffset() + ExtraOffset; | 1682 Offset += Base->getStackOffset() + ExtraOffset; |
1686 Base = Target->getPhysicalRegister(Base->getRegNum()); | 1683 Base = Target->getPhysicalRegister(Base->getRegNum()); |
1687 assert(!Base->isRematerializable()); | 1684 assert(!Base->isRematerializable()); |
1688 Legalized = true; | 1685 Legalized = true; |
1689 } | 1686 } |
1690 | 1687 |
1691 if (!Legalized && !Target->NeedSandboxing) { | 1688 if (!Legalized && !Target->NeedSandboxing) { |
1692 return nullptr; | 1689 return nullptr; |
1693 } | 1690 } |
1694 | 1691 |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1894 } | 1891 } |
1895 } | 1892 } |
1896 llvm::report_fatal_error("Unsupported operand type"); | 1893 llvm::report_fatal_error("Unsupported operand type"); |
1897 return nullptr; | 1894 return nullptr; |
1898 } | 1895 } |
1899 | 1896 |
1900 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, | 1897 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, |
1901 RegSetMask Exclude) const { | 1898 RegSetMask Exclude) const { |
1902 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); | 1899 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); |
1903 | 1900 |
1904 for (int32_t i = 0; i < RegARM32::Reg_NUM; ++i) { | 1901 for (uint32_t i = 0; i < RegARM32::Reg_NUM; ++i) { |
Eric Holk
2016/02/08 19:37:10
Would something like a Register iterator make sens
Jim Stichnoth
2016/02/09 19:33:39
Good idea for future work. :)
I had thought about
Eric Holk
2016/02/10 01:11:30
Cool :)
| |
1905 const auto &Entry = RegARM32::RegTable[i]; | 1902 const auto &Entry = RegARM32::RegTable[i]; |
1906 if (Entry.Scratch && (Include & RegSet_CallerSave)) | 1903 if (Entry.Scratch && (Include & RegSet_CallerSave)) |
1907 Registers[i] = true; | 1904 Registers[i] = true; |
1908 if (Entry.Preserved && (Include & RegSet_CalleeSave)) | 1905 if (Entry.Preserved && (Include & RegSet_CalleeSave)) |
1909 Registers[i] = true; | 1906 Registers[i] = true; |
1910 if (Entry.StackPtr && (Include & RegSet_StackPointer)) | 1907 if (Entry.StackPtr && (Include & RegSet_StackPointer)) |
1911 Registers[i] = true; | 1908 Registers[i] = true; |
1912 if (Entry.FramePtr && (Include & RegSet_FramePointer)) | 1909 if (Entry.FramePtr && (Include & RegSet_FramePointer)) |
1913 Registers[i] = true; | 1910 Registers[i] = true; |
1914 if (Entry.Scratch && (Exclude & RegSet_CallerSave)) | 1911 if (Entry.Scratch && (Exclude & RegSet_CallerSave)) |
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3354 if (TargetHelperPreamble != ARM32HelpersPreamble.end()) { | 3351 if (TargetHelperPreamble != ARM32HelpersPreamble.end()) { |
3355 (this->*TargetHelperPreamble->second)(Instr); | 3352 (this->*TargetHelperPreamble->second)(Instr); |
3356 } | 3353 } |
3357 } | 3354 } |
3358 MaybeLeafFunc = false; | 3355 MaybeLeafFunc = false; |
3359 NeedsStackAlignment = true; | 3356 NeedsStackAlignment = true; |
3360 | 3357 |
3361 // Assign arguments to registers and stack. Also reserve stack. | 3358 // Assign arguments to registers and stack. Also reserve stack. |
3362 TargetARM32::CallingConv CC; | 3359 TargetARM32::CallingConv CC; |
3363 // Pair of Arg Operand -> GPR number assignments. | 3360 // Pair of Arg Operand -> GPR number assignments. |
3364 llvm::SmallVector<std::pair<Operand *, int32_t>, NumGPRArgs> GPRArgs; | 3361 llvm::SmallVector<std::pair<Operand *, RegNumT>, NumGPRArgs> GPRArgs; |
3365 llvm::SmallVector<std::pair<Operand *, int32_t>, NumFP32Args> FPArgs; | 3362 llvm::SmallVector<std::pair<Operand *, RegNumT>, NumFP32Args> FPArgs; |
3366 // Pair of Arg Operand -> stack offset. | 3363 // Pair of Arg Operand -> stack offset. |
3367 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; | 3364 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; |
3368 size_t ParameterAreaSizeBytes = 0; | 3365 size_t ParameterAreaSizeBytes = 0; |
3369 | 3366 |
3370 // Classify each argument operand according to the location where the | 3367 // Classify each argument operand according to the location where the |
3371 // argument is passed. | 3368 // argument is passed. |
3372 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { | 3369 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { |
3373 Operand *Arg = legalizeUndef(Instr->getArg(i)); | 3370 Operand *Arg = legalizeUndef(Instr->getArg(i)); |
3374 const Type Ty = Arg->getType(); | 3371 const Type Ty = Arg->getType(); |
3375 bool InReg = false; | 3372 bool InReg = false; |
3376 int32_t Reg; | 3373 RegNumT Reg; |
3377 if (isScalarIntegerType(Ty)) { | 3374 if (isScalarIntegerType(Ty)) { |
3378 InReg = CC.argInGPR(Ty, &Reg); | 3375 InReg = CC.argInGPR(Ty, &Reg); |
3379 } else { | 3376 } else { |
3380 InReg = CC.argInVFP(Ty, &Reg); | 3377 InReg = CC.argInVFP(Ty, &Reg); |
3381 } | 3378 } |
3382 | 3379 |
3383 if (!InReg) { | 3380 if (!InReg) { |
3384 ParameterAreaSizeBytes = | 3381 ParameterAreaSizeBytes = |
3385 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); | 3382 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); |
3386 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); | 3383 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); |
(...skipping 2063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5450 } | 5447 } |
5451 | 5448 |
5452 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) { | 5449 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) { |
5453 _trap(); | 5450 _trap(); |
5454 } | 5451 } |
5455 | 5452 |
5456 void TargetARM32::prelowerPhis() { | 5453 void TargetARM32::prelowerPhis() { |
5457 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); | 5454 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); |
5458 } | 5455 } |
5459 | 5456 |
5460 Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) { | 5457 Variable *TargetARM32::makeVectorOfZeros(Type Ty, RegNumT RegNum) { |
5461 Variable *Reg = makeReg(Ty, RegNum); | 5458 Variable *Reg = makeReg(Ty, RegNum); |
5462 Context.insert<InstFakeDef>(Reg); | 5459 Context.insert<InstFakeDef>(Reg); |
5463 UnimplementedError(Func->getContext()->getFlags()); | 5460 UnimplementedError(Func->getContext()->getFlags()); |
5464 return Reg; | 5461 return Reg; |
5465 } | 5462 } |
5466 | 5463 |
5467 // Helper for legalize() to emit the right code to lower an operand to a | 5464 // Helper for legalize() to emit the right code to lower an operand to a |
5468 // register of the appropriate type. | 5465 // register of the appropriate type. |
5469 Variable *TargetARM32::copyToReg(Operand *Src, int32_t RegNum) { | 5466 Variable *TargetARM32::copyToReg(Operand *Src, RegNumT RegNum) { |
5470 Type Ty = Src->getType(); | 5467 Type Ty = Src->getType(); |
5471 Variable *Reg = makeReg(Ty, RegNum); | 5468 Variable *Reg = makeReg(Ty, RegNum); |
5472 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) { | 5469 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) { |
5473 _ldr(Reg, Mem); | 5470 _ldr(Reg, Mem); |
5474 } else { | 5471 } else { |
5475 _mov(Reg, Src); | 5472 _mov(Reg, Src); |
5476 } | 5473 } |
5477 return Reg; | 5474 return Reg; |
5478 } | 5475 } |
5479 | 5476 |
5480 // TODO(jpp): remove unneeded else clauses in legalize. | 5477 // TODO(jpp): remove unneeded else clauses in legalize. |
5481 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, | 5478 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, |
5482 int32_t RegNum) { | 5479 RegNumT RegNum) { |
5483 Type Ty = From->getType(); | 5480 Type Ty = From->getType(); |
5484 // Assert that a physical register is allowed. To date, all calls to | 5481 // Assert that a physical register is allowed. To date, all calls to |
5485 // legalize() allow a physical register. Legal_Flex converts registers to the | 5482 // legalize() allow a physical register. Legal_Flex converts registers to the |
5486 // right type OperandARM32FlexReg as needed. | 5483 // right type OperandARM32FlexReg as needed. |
5487 assert(Allowed & Legal_Reg); | 5484 assert(Allowed & Legal_Reg); |
5488 | 5485 |
5489 // Copied ipsis literis from TargetX86Base<Machine>. | 5486 // Copied ipsis literis from TargetX86Base<Machine>. |
5490 if (RegNum == Variable::NoRegister) { | 5487 if (RegNum == RegNumT::NoRegister) { |
5491 if (Variable *Subst = getContext().availabilityGet(From)) { | 5488 if (Variable *Subst = getContext().availabilityGet(From)) { |
5492 // At this point we know there is a potential substitution available. | 5489 // At this point we know there is a potential substitution available. |
5493 if (!Subst->isRematerializable() && Subst->mustHaveReg() && | 5490 if (!Subst->isRematerializable() && Subst->mustHaveReg() && |
5494 !Subst->hasReg()) { | 5491 !Subst->hasReg()) { |
5495 // At this point we know the substitution will have a register. | 5492 // At this point we know the substitution will have a register. |
5496 if (From->getType() == Subst->getType()) { | 5493 if (From->getType() == Subst->getType()) { |
5497 // At this point we know the substitution's register is compatible. | 5494 // At this point we know the substitution's register is compatible. |
5498 return Subst; | 5495 return Subst; |
5499 } | 5496 } |
5500 } | 5497 } |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5664 } | 5661 } |
5665 // Check if the variable is guaranteed a physical register. This can happen | 5662 // Check if the variable is guaranteed a physical register. This can happen |
5666 // either when the variable is pre-colored or when it is assigned infinite | 5663 // either when the variable is pre-colored or when it is assigned infinite |
5667 // weight. | 5664 // weight. |
5668 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); | 5665 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
5669 // We need a new physical register for the operand if: | 5666 // We need a new physical register for the operand if: |
5670 // Mem is not allowed and Var isn't guaranteed a physical | 5667 // Mem is not allowed and Var isn't guaranteed a physical |
5671 // register, or | 5668 // register, or |
5672 // RegNum is required and Var->getRegNum() doesn't match. | 5669 // RegNum is required and Var->getRegNum() doesn't match. |
5673 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 5670 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
5674 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 5671 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) { |
5675 From = copyToReg(From, RegNum); | 5672 From = copyToReg(From, RegNum); |
5676 } | 5673 } |
5677 return From; | 5674 return From; |
5678 } | 5675 } |
5679 llvm::report_fatal_error("Unhandled operand kind in legalize()"); | 5676 llvm::report_fatal_error("Unhandled operand kind in legalize()"); |
5680 | 5677 |
5681 return From; | 5678 return From; |
5682 } | 5679 } |
5683 | 5680 |
5684 /// Provide a trivial wrapper to legalize() for this common usage. | 5681 /// Provide a trivial wrapper to legalize() for this common usage. |
5685 Variable *TargetARM32::legalizeToReg(Operand *From, int32_t RegNum) { | 5682 Variable *TargetARM32::legalizeToReg(Operand *From, RegNumT RegNum) { |
5686 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); | 5683 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); |
5687 } | 5684 } |
5688 | 5685 |
5689 /// Legalize undef values to concrete values. | 5686 /// Legalize undef values to concrete values. |
5690 Operand *TargetARM32::legalizeUndef(Operand *From, int32_t RegNum) { | 5687 Operand *TargetARM32::legalizeUndef(Operand *From, RegNumT RegNum) { |
5691 Type Ty = From->getType(); | 5688 Type Ty = From->getType(); |
5692 if (llvm::isa<ConstantUndef>(From)) { | 5689 if (llvm::isa<ConstantUndef>(From)) { |
5693 // Lower undefs to zero. Another option is to lower undefs to an | 5690 // Lower undefs to zero. Another option is to lower undefs to an |
5694 // uninitialized register; however, using an uninitialized register results | 5691 // uninitialized register; however, using an uninitialized register results |
5695 // in less predictable code. | 5692 // in less predictable code. |
5696 // | 5693 // |
5697 // If in the future the implementation is changed to lower undef values to | 5694 // If in the future the implementation is changed to lower undef values to |
5698 // uninitialized registers, a FakeDef will be needed: | 5695 // uninitialized registers, a FakeDef will be needed: |
5699 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to | 5696 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to |
5700 // ensure that the live range of Reg is not overestimated. If the constant | 5697 // ensure that the live range of Reg is not overestimated. If the constant |
(...skipping 27 matching lines...) Expand all Loading... | |
5728 Variable64On32 *TargetARM32::makeI64RegPair() { | 5725 Variable64On32 *TargetARM32::makeI64RegPair() { |
5729 Variable64On32 *Reg = | 5726 Variable64On32 *Reg = |
5730 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); | 5727 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); |
5731 Reg->setMustHaveReg(); | 5728 Reg->setMustHaveReg(); |
5732 Reg->initHiLo(Func); | 5729 Reg->initHiLo(Func); |
5733 Reg->getLo()->setMustNotHaveReg(); | 5730 Reg->getLo()->setMustNotHaveReg(); |
5734 Reg->getHi()->setMustNotHaveReg(); | 5731 Reg->getHi()->setMustNotHaveReg(); |
5735 return Reg; | 5732 return Reg; |
5736 } | 5733 } |
5737 | 5734 |
5738 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { | 5735 Variable *TargetARM32::makeReg(Type Type, RegNumT RegNum) { |
5739 // There aren't any 64-bit integer registers for ARM32. | 5736 // There aren't any 64-bit integer registers for ARM32. |
5740 assert(Type != IceType_i64); | 5737 assert(Type != IceType_i64); |
5741 assert(AllowTemporaryWithNoReg || RegNum != Variable::NoRegister); | 5738 assert(AllowTemporaryWithNoReg || RegNum != RegNumT::NoRegister); |
5742 Variable *Reg = Func->makeVariable(Type); | 5739 Variable *Reg = Func->makeVariable(Type); |
5743 if (RegNum == Variable::NoRegister) | 5740 if (RegNum == RegNumT::NoRegister) |
5744 Reg->setMustHaveReg(); | 5741 Reg->setMustHaveReg(); |
5745 else | 5742 else |
5746 Reg->setRegNum(RegNum); | 5743 Reg->setRegNum(RegNum); |
5747 return Reg; | 5744 return Reg; |
5748 } | 5745 } |
5749 | 5746 |
5750 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align, | 5747 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align, |
5751 int32_t TmpRegNum) { | 5748 RegNumT TmpRegNum) { |
5752 assert(llvm::isPowerOf2_32(Align)); | 5749 assert(llvm::isPowerOf2_32(Align)); |
5753 uint32_t RotateAmt; | 5750 uint32_t RotateAmt; |
5754 uint32_t Immed_8; | 5751 uint32_t Immed_8; |
5755 Operand *Mask; | 5752 Operand *Mask; |
5756 // Use AND or BIC to mask off the bits, depending on which immediate fits (if | 5753 // Use AND or BIC to mask off the bits, depending on which immediate fits (if |
5757 // it fits at all). Assume Align is usually small, in which case BIC works | 5754 // it fits at all). Assume Align is usually small, in which case BIC works |
5758 // better. Thus, this rounds down to the alignment. | 5755 // better. Thus, this rounds down to the alignment. |
5759 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) { | 5756 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) { |
5760 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex, | 5757 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex, |
5761 TmpRegNum); | 5758 TmpRegNum); |
5762 _bic(Reg, Reg, Mask); | 5759 _bic(Reg, Reg, Mask); |
5763 } else { | 5760 } else { |
5764 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex, | 5761 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex, |
5765 TmpRegNum); | 5762 TmpRegNum); |
5766 _and(Reg, Reg, Mask); | 5763 _and(Reg, Reg, Mask); |
5767 } | 5764 } |
5768 } | 5765 } |
5769 | 5766 |
5770 void TargetARM32::postLower() { | 5767 void TargetARM32::postLower() { |
5771 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 5768 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
5772 return; | 5769 return; |
5773 markRedefinitions(); | 5770 markRedefinitions(); |
5774 Context.availabilityUpdate(); | 5771 Context.availabilityUpdate(); |
5775 } | 5772 } |
5776 | 5773 |
5777 void TargetARM32::makeRandomRegisterPermutation( | 5774 void TargetARM32::makeRandomRegisterPermutation( |
5778 llvm::SmallVectorImpl<int32_t> &Permutation, | 5775 llvm::SmallVectorImpl<RegNumT> &Permutation, |
5779 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 5776 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
5780 (void)Permutation; | 5777 (void)Permutation; |
5781 (void)ExcludeRegisters; | 5778 (void)ExcludeRegisters; |
5782 (void)Salt; | 5779 (void)Salt; |
5783 UnimplementedError(Func->getContext()->getFlags()); | 5780 UnimplementedError(Func->getContext()->getFlags()); |
5784 } | 5781 } |
5785 | 5782 |
5786 void TargetARM32::emit(const ConstantInteger32 *C) const { | 5783 void TargetARM32::emit(const ConstantInteger32 *C) const { |
5787 if (!BuildDefs::dump()) | 5784 if (!BuildDefs::dump()) |
5788 return; | 5785 return; |
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6523 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 6520 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
6524 } | 6521 } |
6525 | 6522 |
6526 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; | 6523 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; |
6527 llvm::SmallBitVector | 6524 llvm::SmallBitVector |
6528 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; | 6525 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; |
6529 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; | 6526 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; |
6530 | 6527 |
6531 } // end of namespace ARM32 | 6528 } // end of namespace ARM32 |
6532 } // end of namespace Ice | 6529 } // end of namespace Ice |
OLD | NEW |