Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1676123002: Subzero: Use a proper RegNumT type instead of int32_t/SizeT. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Revert some method name changes Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 InvalidRegisters(RegARM32::Reg_NUM); 299 llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM);
300 for (int i = 0; i < RegARM32::Reg_NUM; ++i) { 300 for (int i = 0; i < RegARM32::Reg_NUM; ++i) {
301 const auto &Entry = RegARM32::RegTable[i]; 301 const auto &Entry = RegARM32::RegTable[i];
302 IntegerRegisters[i] = Entry.IsInt; 302 IntegerRegisters[i] = Entry.IsInt;
303 I64PairRegisters[i] = Entry.IsI64Pair; 303 I64PairRegisters[i] = Entry.IsI64Pair;
304 Float32Registers[i] = Entry.IsFP32; 304 Float32Registers[i] = Entry.IsFP32;
305 Float64Registers[i] = Entry.IsFP64; 305 Float64Registers[i] = Entry.IsFP64;
306 VectorRegisters[i] = Entry.IsVec128; 306 VectorRegisters[i] = Entry.IsVec128;
307 RegisterAliases[i].resize(RegARM32::Reg_NUM); 307 RegisterAliases[i].resize(RegARM32::Reg_NUM);
308 for (int j = 0; j < Entry.NumAliases; ++j) { 308 for (int j = 0; j < Entry.NumAliases; ++j) {
309 assert(i == j || !RegisterAliases[i][Entry.Aliases[j]]); 309 assert(i == j || !RegisterAliases[i][Entry.Aliases[j]]);
310 RegisterAliases[i].set(Entry.Aliases[j]); 310 RegisterAliases[i].set(Entry.Aliases[j]);
311 } 311 }
312 assert(RegisterAliases[i][i]); 312 assert(RegisterAliases[i][i]);
313 if (Entry.CCArg <= 0) { 313 if (Entry.CCArg <= 0) {
314 continue; 314 continue;
315 } 315 }
316 auto RegNum = RegNumT::fromInt(i);
316 if (Entry.IsGPR) { 317 if (Entry.IsGPR) {
317 GPRArgInitializer[Entry.CCArg - 1] = i; 318 GPRArgInitializer[Entry.CCArg - 1] = RegNum;
318 } else if (Entry.IsI64Pair) { 319 } else if (Entry.IsI64Pair) {
319 I64ArgInitializer[Entry.CCArg - 1] = i; 320 I64ArgInitializer[Entry.CCArg - 1] = RegNum;
320 } else if (Entry.IsFP32) { 321 } else if (Entry.IsFP32) {
321 FP32ArgInitializer[Entry.CCArg - 1] = i; 322 FP32ArgInitializer[Entry.CCArg - 1] = RegNum;
322 } else if (Entry.IsFP64) { 323 } else if (Entry.IsFP64) {
323 FP64ArgInitializer[Entry.CCArg - 1] = i; 324 FP64ArgInitializer[Entry.CCArg - 1] = RegNum;
324 } else if (Entry.IsVec128) { 325 } else if (Entry.IsVec128) {
325 Vec128ArgInitializer[Entry.CCArg - 1] = i; 326 Vec128ArgInitializer[Entry.CCArg - 1] = RegNum;
326 } 327 }
327 } 328 }
328 TypeToRegisterSet[IceType_void] = InvalidRegisters; 329 TypeToRegisterSet[IceType_void] = InvalidRegisters;
329 TypeToRegisterSet[IceType_i1] = IntegerRegisters; 330 TypeToRegisterSet[IceType_i1] = IntegerRegisters;
330 TypeToRegisterSet[IceType_i8] = IntegerRegisters; 331 TypeToRegisterSet[IceType_i8] = IntegerRegisters;
331 TypeToRegisterSet[IceType_i16] = IntegerRegisters; 332 TypeToRegisterSet[IceType_i16] = IntegerRegisters;
332 TypeToRegisterSet[IceType_i32] = IntegerRegisters; 333 TypeToRegisterSet[IceType_i32] = IntegerRegisters;
333 TypeToRegisterSet[IceType_i64] = I64PairRegisters; 334 TypeToRegisterSet[IceType_i64] = I64PairRegisters;
334 TypeToRegisterSet[IceType_f32] = Float32Registers; 335 TypeToRegisterSet[IceType_f32] = Float32Registers;
335 TypeToRegisterSet[IceType_f64] = Float64Registers; 336 TypeToRegisterSet[IceType_f64] = Float64Registers;
336 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; 337 TypeToRegisterSet[IceType_v4i1] = VectorRegisters;
337 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; 338 TypeToRegisterSet[IceType_v8i1] = VectorRegisters;
338 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; 339 TypeToRegisterSet[IceType_v16i1] = VectorRegisters;
339 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; 340 TypeToRegisterSet[IceType_v16i8] = VectorRegisters;
340 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; 341 TypeToRegisterSet[IceType_v8i16] = VectorRegisters;
341 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; 342 TypeToRegisterSet[IceType_v4i32] = VectorRegisters;
342 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; 343 TypeToRegisterSet[IceType_v4f32] = VectorRegisters;
343 344
344 for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i) 345 for (size_t i = 0; i < llvm::array_lengthof(TypeToRegisterSet); ++i)
345 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i]; 346 TypeToRegisterSetUnfiltered[i] = TypeToRegisterSet[i];
346 347
347 filterTypeToRegisterSet( 348 filterTypeToRegisterSet(
348 Ctx, RegARM32::Reg_NUM, TypeToRegisterSet, 349 Ctx, RegARM32::Reg_NUM, TypeToRegisterSet,
349 llvm::array_lengthof(TypeToRegisterSet), [](int32_t RegNum) -> IceString { 350 llvm::array_lengthof(TypeToRegisterSet), [](RegNumT RegNum) -> IceString {
350 // This function simply removes ", " from the register name. 351 // This function simply removes ", " from the register name.
351 IceString Name = RegARM32::getRegName(RegNum); 352 IceString Name = RegARM32::getRegName(RegNum);
352 constexpr const char RegSeparator[] = ", "; 353 constexpr const char RegSeparator[] = ", ";
353 constexpr size_t RegSeparatorWidth = 354 constexpr size_t RegSeparatorWidth =
354 llvm::array_lengthof(RegSeparator) - 1; 355 llvm::array_lengthof(RegSeparator) - 1;
355 for (size_t Pos = Name.find(RegSeparator); Pos != std::string::npos; 356 for (size_t Pos = Name.find(RegSeparator); Pos != std::string::npos;
356 Pos = Name.find(RegSeparator)) { 357 Pos = Name.find(RegSeparator)) {
357 Name.replace(Pos, RegSeparatorWidth, ""); 358 Name.replace(Pos, RegSeparatorWidth, "");
358 } 359 }
359 return Name; 360 return Name;
360 }, getRegClassName); 361 }, getRegClassName);
361 } 362 }
362 363
363 namespace { 364 namespace {
364 void copyRegAllocFromInfWeightVariable64On32(const VarList &Vars) { 365 void copyRegAllocFromInfWeightVariable64On32(const VarList &Vars) {
365 for (Variable *Var : Vars) { 366 for (Variable *Var : Vars) {
366 auto *Var64 = llvm::dyn_cast<Variable64On32>(Var); 367 auto *Var64 = llvm::dyn_cast<Variable64On32>(Var);
367 if (!Var64) { 368 if (!Var64) {
368 // This is not the variable we are looking for. 369 // This is not the variable we are looking for.
369 continue; 370 continue;
370 } 371 }
371 assert(Var64->hasReg() || !Var64->mustHaveReg()); 372 assert(Var64->hasReg() || !Var64->mustHaveReg());
372 if (!Var64->hasReg()) { 373 if (!Var64->hasReg()) {
373 continue; 374 continue;
374 } 375 }
375 SizeT FirstReg = RegARM32::getI64PairFirstGPRNum(Var->getRegNum()); 376 auto FirstReg =
377 RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(Var->getRegNum()));
376 // This assumes little endian. 378 // This assumes little endian.
377 Variable *Lo = Var64->getLo(); 379 Variable *Lo = Var64->getLo();
378 Variable *Hi = Var64->getHi(); 380 Variable *Hi = Var64->getHi();
379 assert(Lo->hasReg() == Hi->hasReg()); 381 assert(Lo->hasReg() == Hi->hasReg());
380 if (Lo->hasReg()) { 382 if (Lo->hasReg()) {
381 continue; 383 continue;
382 } 384 }
383 Lo->setRegNum(FirstReg); 385 Lo->setRegNum(FirstReg);
384 Lo->setMustHaveReg(); 386 Lo->setMustHaveReg();
385 Hi->setRegNum(FirstReg + 1); 387 Hi->setRegNum(RegNumT::fixme(FirstReg + 1));
386 Hi->setMustHaveReg(); 388 Hi->setMustHaveReg();
387 } 389 }
388 } 390 }
389 } // end of anonymous namespace 391 } // end of anonymous namespace
390 392
391 uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) { 393 uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) {
392 TargetARM32::CallingConv CC; 394 TargetARM32::CallingConv CC;
393 int32_t DummyReg; 395 RegNumT DummyReg;
394 size_t OutArgsSizeBytes = 0; 396 size_t OutArgsSizeBytes = 0;
395 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { 397 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) {
396 Operand *Arg = legalizeUndef(Call->getArg(i)); 398 Operand *Arg = legalizeUndef(Call->getArg(i));
397 const Type Ty = Arg->getType(); 399 const Type Ty = Arg->getType();
398 if (isScalarIntegerType(Ty)) { 400 if (isScalarIntegerType(Ty)) {
399 if (CC.argInGPR(Ty, &DummyReg)) { 401 if (CC.argInGPR(Ty, &DummyReg)) {
400 continue; 402 continue;
401 } 403 }
402 } else { 404 } else {
403 if (CC.argInVFP(Ty, &DummyReg)) { 405 if (CC.argInVFP(Ty, &DummyReg)) {
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 return ARM32_STACK_ALIGNMENT_BYTES; 897 return ARM32_STACK_ALIGNMENT_BYTES;
896 } 898 }
897 899
898 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { 900 bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) {
899 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) { 901 if (auto *Br = llvm::dyn_cast<InstARM32Br>(I)) {
900 return Br->optimizeBranch(NextNode); 902 return Br->optimizeBranch(NextNode);
901 } 903 }
902 return false; 904 return false;
903 } 905 }
904 906
905 IceString TargetARM32::getRegName(SizeT RegNum, Type Ty) const { 907 IceString TargetARM32::getRegName(RegNumT RegNum, Type Ty) const {
906 assert(RegNum < RegARM32::Reg_NUM);
907 (void)Ty; 908 (void)Ty;
908 return RegARM32::getRegName(RegNum); 909 return RegARM32::getRegName(RegNum);
909 } 910 }
910 911
911 Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) { 912 Variable *TargetARM32::getPhysicalRegister(RegNumT RegNum, Type Ty) {
912 static const Type DefaultType[] = { 913 static const Type DefaultType[] = {
913 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \ 914 #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
914 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \ 915 isGPR, isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
915 (isFP32) \ 916 (isFP32) \
916 ? IceType_f32 \ 917 ? IceType_f32 \
917 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), 918 : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))),
918 REGARM32_TABLE 919 REGARM32_TABLE
919 #undef X 920 #undef X
920 }; 921 };
921 922
922 assert(RegNum < RegARM32::Reg_NUM);
923 if (Ty == IceType_void) { 923 if (Ty == IceType_void) {
924 assert(RegNum < llvm::array_lengthof(DefaultType)); 924 assert(unsigned(RegNum) < llvm::array_lengthof(DefaultType));
925 Ty = DefaultType[RegNum]; 925 Ty = DefaultType[RegNum];
926 } 926 }
927 if (PhysicalRegisters[Ty].empty()) 927 if (PhysicalRegisters[Ty].empty())
928 PhysicalRegisters[Ty].resize(RegARM32::Reg_NUM); 928 PhysicalRegisters[Ty].resize(RegARM32::Reg_NUM);
929 assert(RegNum < PhysicalRegisters[Ty].size()); 929 assert(unsigned(RegNum) < PhysicalRegisters[Ty].size());
930 Variable *Reg = PhysicalRegisters[Ty][RegNum]; 930 Variable *Reg = PhysicalRegisters[Ty][RegNum];
931 if (Reg == nullptr) { 931 if (Reg == nullptr) {
932 Reg = Func->makeVariable(Ty); 932 Reg = Func->makeVariable(Ty);
933 Reg->setRegNum(RegNum); 933 Reg->setRegNum(RegNum);
934 PhysicalRegisters[Ty][RegNum] = Reg; 934 PhysicalRegisters[Ty][RegNum] = Reg;
935 // Specially mark a named physical register as an "argument" so that it is 935 // 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 936 // considered live upon function entry. Otherwise it's possible to get
937 // liveness validation errors for saving callee-save registers. 937 // liveness validation errors for saving callee-save registers.
938 Func->addImplicitArg(Reg); 938 Func->addImplicitArg(Reg);
939 // Don't bother tracking the live range of a named physical register. 939 // Don't bother tracking the live range of a named physical register.
(...skipping 16 matching lines...) Expand all
956 Str << getRegName(Var->getRegNum(), Var->getType()); 956 Str << getRegName(Var->getRegNum(), Var->getType());
957 return; 957 return;
958 } 958 }
959 if (Var->mustHaveReg()) { 959 if (Var->mustHaveReg()) {
960 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) + 960 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName(Func) +
961 ") has no register assigned - function " + 961 ") has no register assigned - function " +
962 Func->getFunctionName()); 962 Func->getFunctionName());
963 } 963 }
964 assert(!Var->isRematerializable()); 964 assert(!Var->isRematerializable());
965 int32_t Offset = Var->getStackOffset(); 965 int32_t Offset = Var->getStackOffset();
966 int32_t BaseRegNum = Var->getBaseRegNum(); 966 auto BaseRegNum = Var->getBaseRegNum();
967 if (BaseRegNum == Variable::NoRegister) { 967 if (BaseRegNum == RegNumT::NoRegister) {
968 BaseRegNum = getFrameOrStackReg(); 968 BaseRegNum = getFrameOrStackReg();
969 } 969 }
970 const Type VarTy = Var->getType(); 970 const Type VarTy = Var->getType();
971 Str << "[" << getRegName(BaseRegNum, VarTy); 971 Str << "[" << getRegName(BaseRegNum, VarTy);
972 if (Offset != 0) { 972 if (Offset != 0) {
973 Str << ", #" << Offset; 973 Str << ", #" << Offset;
974 } 974 }
975 Str << "]"; 975 Str << "]";
976 } 976 }
977 977
978 TargetARM32::CallingConv::CallingConv() 978 TargetARM32::CallingConv::CallingConv()
979 : GPRegsUsed(RegARM32::Reg_NUM), 979 : GPRegsUsed(RegARM32::Reg_NUM),
980 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()), 980 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()),
981 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()), 981 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()),
982 VFPRegsUsed(RegARM32::Reg_NUM), 982 VFPRegsUsed(RegARM32::Reg_NUM),
983 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()), 983 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()),
984 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()), 984 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()),
985 Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {} 985 Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {}
986 986
987 bool TargetARM32::CallingConv::argInGPR(Type Ty, int32_t *Reg) { 987 bool TargetARM32::CallingConv::argInGPR(Type Ty, RegNumT *Reg) {
988 CfgVector<SizeT> *Source; 988 CfgVector<RegNumT> *Source;
989 989
990 switch (Ty) { 990 switch (Ty) {
991 default: { 991 default: {
992 assert(isScalarIntegerType(Ty)); 992 assert(isScalarIntegerType(Ty));
993 Source = &GPRArgs; 993 Source = &GPRArgs;
994 } break; 994 } break;
995 case IceType_i64: { 995 case IceType_i64: {
996 Source = &I64Args; 996 Source = &I64Args;
997 } break; 997 } break;
998 } 998 }
(...skipping 13 matching lines...) Expand all
1012 GPRegsUsed |= RegisterAliases[*Reg]; 1012 GPRegsUsed |= RegisterAliases[*Reg];
1013 return true; 1013 return true;
1014 } 1014 }
1015 1015
1016 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64, 1016 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64,
1017 // i32) will have the first argument in r0, the second in r1-r2, and the third 1017 // i32) will have the first argument in r0, the second in r1-r2, and the third
1018 // on the stack. To model this behavior, whenever we pop a register from Regs, 1018 // on the stack. To model this behavior, whenever we pop a register from Regs,
1019 // we remove all of its aliases from the pool of available GPRs. This has the 1019 // 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. 1020 // effect of computing the "closure" on the GPR registers.
1021 void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases( 1021 void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases(
1022 CfgVector<SizeT> *Regs) { 1022 CfgVector<RegNumT> *Regs) {
1023 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { 1023 while (!Regs->empty() && GPRegsUsed[Regs->back()]) {
1024 GPRegsUsed |= RegisterAliases[Regs->back()]; 1024 GPRegsUsed |= RegisterAliases[Regs->back()];
1025 Regs->pop_back(); 1025 Regs->pop_back();
1026 } 1026 }
1027 } 1027 }
1028 1028
1029 bool TargetARM32::CallingConv::argInVFP(Type Ty, int32_t *Reg) { 1029 bool TargetARM32::CallingConv::argInVFP(Type Ty, RegNumT *Reg) {
1030 CfgVector<SizeT> *Source; 1030 CfgVector<RegNumT> *Source;
1031 1031
1032 switch (Ty) { 1032 switch (Ty) {
1033 default: { 1033 default: {
1034 assert(isVectorType(Ty)); 1034 assert(isVectorType(Ty));
1035 Source = &Vec128Args; 1035 Source = &Vec128Args;
1036 } break; 1036 } break;
1037 case IceType_f32: { 1037 case IceType_f32: {
1038 Source = &FP32Args; 1038 Source = &FP32Args;
1039 } break; 1039 } break;
1040 case IceType_f64: { 1040 case IceType_f64: {
1041 Source = &FP64Args; 1041 Source = &FP64Args;
1042 } break; 1042 } break;
1043 } 1043 }
1044 1044
1045 discardUnavailableVFPRegs(Source); 1045 discardUnavailableVFPRegs(Source);
1046 1046
1047 if (Source->empty()) { 1047 if (Source->empty()) {
1048 VFPRegsUsed.set(); 1048 VFPRegsUsed.set();
1049 return false; 1049 return false;
1050 } 1050 }
1051 1051
1052 *Reg = Source->back(); 1052 *Reg = Source->back();
1053 VFPRegsUsed |= RegisterAliases[*Reg]; 1053 VFPRegsUsed |= RegisterAliases[*Reg];
1054 return true; 1054 return true;
1055 } 1055 }
1056 1056
1057 // Arguments in VFP registers are not packed, so we don't mark the popped 1057 // Arguments in VFP registers are not packed, so we don't mark the popped
1058 // registers' aliases as unavailable. 1058 // registers' aliases as unavailable.
1059 void TargetARM32::CallingConv::discardUnavailableVFPRegs( 1059 void TargetARM32::CallingConv::discardUnavailableVFPRegs(
1060 CfgVector<SizeT> *Regs) { 1060 CfgVector<RegNumT> *Regs) {
1061 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) { 1061 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) {
1062 Regs->pop_back(); 1062 Regs->pop_back();
1063 } 1063 }
1064 } 1064 }
1065 1065
1066 void TargetARM32::lowerArguments() { 1066 void TargetARM32::lowerArguments() {
1067 VarList &Args = Func->getArgs(); 1067 VarList &Args = Func->getArgs();
1068 TargetARM32::CallingConv CC; 1068 TargetARM32::CallingConv CC;
1069 1069
1070 // For each register argument, replace Arg in the argument list with the home 1070 // 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 1071 // register. Then generate an instruction in the prolog to copy the home
1072 // register to the assigned location of Arg. 1072 // register to the assigned location of Arg.
1073 Context.init(Func->getEntryNode()); 1073 Context.init(Func->getEntryNode());
1074 Context.setInsertPoint(Context.getCur()); 1074 Context.setInsertPoint(Context.getCur());
1075 1075
1076 for (SizeT I = 0, E = Args.size(); I < E; ++I) { 1076 for (SizeT I = 0, E = Args.size(); I < E; ++I) {
1077 Variable *Arg = Args[I]; 1077 Variable *Arg = Args[I];
1078 Type Ty = Arg->getType(); 1078 Type Ty = Arg->getType();
1079 int RegNum; 1079 RegNumT RegNum;
1080 if (isScalarIntegerType(Ty)) { 1080 if (isScalarIntegerType(Ty)) {
1081 if (!CC.argInGPR(Ty, &RegNum)) { 1081 if (!CC.argInGPR(Ty, &RegNum)) {
1082 continue; 1082 continue;
1083 } 1083 }
1084 } else { 1084 } else {
1085 if (!CC.argInVFP(Ty, &RegNum)) { 1085 if (!CC.argInVFP(Ty, &RegNum)) {
1086 continue; 1086 continue;
1087 } 1087 }
1088 } 1088 }
1089 1089
1090 Variable *RegisterArg = Func->makeVariable(Ty); 1090 Variable *RegisterArg = Func->makeVariable(Ty);
1091 if (BuildDefs::dump()) { 1091 if (BuildDefs::dump()) {
1092 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); 1092 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
1093 } 1093 }
1094 RegisterArg->setIsArg(); 1094 RegisterArg->setIsArg();
1095 Arg->setIsArg(false); 1095 Arg->setIsArg(false);
1096 Args[I] = RegisterArg; 1096 Args[I] = RegisterArg;
1097 switch (Ty) { 1097 switch (Ty) {
1098 default: { RegisterArg->setRegNum(RegNum); } break; 1098 default: { RegisterArg->setRegNum(RegNum); } break;
1099 case IceType_i64: { 1099 case IceType_i64: {
1100 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg); 1100 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg);
1101 RegisterArg64->initHiLo(Func); 1101 RegisterArg64->initHiLo(Func);
1102 RegisterArg64->getLo()->setRegNum( 1102 RegisterArg64->getLo()->setRegNum(
1103 RegARM32::getI64PairFirstGPRNum(RegNum)); 1103 RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(RegNum)));
1104 RegisterArg64->getHi()->setRegNum( 1104 RegisterArg64->getHi()->setRegNum(
1105 RegARM32::getI64PairSecondGPRNum(RegNum)); 1105 RegNumT::fixme(RegARM32::getI64PairSecondGPRNum(RegNum)));
1106 } break; 1106 } break;
1107 } 1107 }
1108 Context.insert<InstAssign>(Arg, RegisterArg); 1108 Context.insert<InstAssign>(Arg, RegisterArg);
1109 } 1109 }
1110 } 1110 }
1111 1111
1112 // Helper function for addProlog(). 1112 // Helper function for addProlog().
1113 // 1113 //
1114 // This assumes Arg is an argument passed on the stack. This sets the frame 1114 // This assumes Arg is an argument passed on the stack. This sets the frame
1115 // offset for Arg and updates InArgsSizeBytes according to Arg's width. For an 1115 // 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
1280 &PreservedSRegs)}; 1280 &PreservedSRegs)};
1281 for (const auto &RegClass : RegClasses) { 1281 for (const auto &RegClass : RegClasses) {
1282 const uint32_t FirstRegInClass = std::get<0>(RegClass); 1282 const uint32_t FirstRegInClass = std::get<0>(RegClass);
1283 const uint32_t LastRegInClass = std::get<1>(RegClass); 1283 const uint32_t LastRegInClass = std::get<1>(RegClass);
1284 VarList *const PreservedRegsInClass = std::get<2>(RegClass); 1284 VarList *const PreservedRegsInClass = std::get<2>(RegClass);
1285 for (uint32_t Reg = FirstRegInClass; Reg <= LastRegInClass; ++Reg) { 1285 for (uint32_t Reg = FirstRegInClass; Reg <= LastRegInClass; ++Reg) {
1286 if (!ToPreserve[Reg]) { 1286 if (!ToPreserve[Reg]) {
1287 continue; 1287 continue;
1288 } 1288 }
1289 ++NumCallee; 1289 ++NumCallee;
1290 Variable *PhysicalRegister = getPhysicalRegister(Reg); 1290 Variable *PhysicalRegister = getPhysicalRegister(RegNumT::fromInt(Reg));
1291 PreservedRegsSizeBytes += 1291 PreservedRegsSizeBytes +=
1292 typeWidthInBytesOnStack(PhysicalRegister->getType()); 1292 typeWidthInBytesOnStack(PhysicalRegister->getType());
1293 PreservedRegsInClass->push_back(PhysicalRegister); 1293 PreservedRegsInClass->push_back(PhysicalRegister);
1294 } 1294 }
1295 } 1295 }
1296 1296
1297 Ctx->statsUpdateRegistersSaved(NumCallee); 1297 Ctx->statsUpdateRegistersSaved(NumCallee);
1298 if (!PreservedSRegs.empty()) 1298 if (!PreservedSRegs.empty())
1299 _push(PreservedSRegs); 1299 _push(PreservedSRegs);
1300 if (!PreservedGPRs.empty()) 1300 if (!PreservedGPRs.empty())
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 // Arg[0] is closest to the stack/frame pointer. 1355 // Arg[0] is closest to the stack/frame pointer.
1356 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg()); 1356 Variable *FramePtr = getPhysicalRegister(getFrameOrStackReg());
1357 size_t BasicFrameOffset = PreservedRegsSizeBytes; 1357 size_t BasicFrameOffset = PreservedRegsSizeBytes;
1358 if (!UsesFramePointer) 1358 if (!UsesFramePointer)
1359 BasicFrameOffset += SpillAreaSizeBytes; 1359 BasicFrameOffset += SpillAreaSizeBytes;
1360 1360
1361 const VarList &Args = Func->getArgs(); 1361 const VarList &Args = Func->getArgs();
1362 size_t InArgsSizeBytes = 0; 1362 size_t InArgsSizeBytes = 0;
1363 TargetARM32::CallingConv CC; 1363 TargetARM32::CallingConv CC;
1364 for (Variable *Arg : Args) { 1364 for (Variable *Arg : Args) {
1365 int32_t DummyReg; 1365 RegNumT DummyReg;
1366 const Type Ty = Arg->getType(); 1366 const Type Ty = Arg->getType();
1367 1367
1368 // Skip arguments passed in registers. 1368 // Skip arguments passed in registers.
1369 if (isScalarIntegerType(Ty)) { 1369 if (isScalarIntegerType(Ty)) {
1370 if (CC.argInGPR(Ty, &DummyReg)) { 1370 if (CC.argInGPR(Ty, &DummyReg)) {
1371 continue; 1371 continue;
1372 } 1372 }
1373 } else { 1373 } else {
1374 if (CC.argInVFP(Ty, &DummyReg)) { 1374 if (CC.argInVFP(Ty, &DummyReg)) {
1375 continue; 1375 continue;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 1474
1475 RI->setDeleted(); 1475 RI->setDeleted();
1476 } 1476 }
1477 1477
1478 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const { 1478 bool TargetARM32::isLegalMemOffset(Type Ty, int32_t Offset) const {
1479 constexpr bool ZeroExt = false; 1479 constexpr bool ZeroExt = false;
1480 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset); 1480 return OperandARM32Mem::canHoldOffset(Ty, ZeroExt, Offset);
1481 } 1481 }
1482 1482
1483 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister( 1483 Variable *TargetARM32::PostLoweringLegalizer::newBaseRegister(
1484 Variable *Base, int32_t Offset, int32_t ScratchRegNum) { 1484 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) {
1485 // Legalize will likely need a movw/movt combination, but if the top bits are 1485 // 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. 1486 // all 0 from negating the offset and subtracting, we could use that instead.
1487 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; 1487 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0;
1488 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); 1488 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum);
1489 if (ShouldSub) { 1489 if (ShouldSub) {
1490 Operand *OffsetVal = 1490 Operand *OffsetVal =
1491 Target->legalize(Target->Ctx->getConstantInt32(-Offset), 1491 Target->legalize(Target->Ctx->getConstantInt32(-Offset),
1492 Legal_Reg | Legal_Flex, ScratchRegNum); 1492 Legal_Reg | Legal_Flex, ScratchRegNum);
1493 Target->_sub(ScratchReg, Base, OffsetVal); 1493 Target->_sub(ScratchReg, Base, OffsetVal);
1494 } else { 1494 } else {
1495 Operand *OffsetVal = 1495 Operand *OffsetVal =
1496 Target->legalize(Target->Ctx->getConstantInt32(Offset), 1496 Target->legalize(Target->Ctx->getConstantInt32(Offset),
1497 Legal_Reg | Legal_Flex, ScratchRegNum); 1497 Legal_Reg | Legal_Flex, ScratchRegNum);
1498 Target->_add(ScratchReg, Base, OffsetVal); 1498 Target->_add(ScratchReg, Base, OffsetVal);
1499 } 1499 }
1500 1500
1501 if (ScratchRegNum == Target->getReservedTmpReg()) { 1501 if (ScratchRegNum == Target->getReservedTmpReg()) {
1502 const bool BaseIsStackOrFramePtr = 1502 const bool BaseIsStackOrFramePtr =
1503 Base->getRegNum() == static_cast<int32_t>(Target->getFrameOrStackReg()); 1503 Base->getRegNum() == Target->getFrameOrStackReg();
1504 // There is currently no code path that would trigger this assertion, so we 1504 // 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 1505 // 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) 1506 // fatal error (thus the use of assert() and not llvm::report_fatal_error)
1507 // as the program compiled by subzero will still work correctly. 1507 // as the program compiled by subzero will still work correctly.
1508 assert(BaseIsStackOrFramePtr); 1508 assert(BaseIsStackOrFramePtr);
1509 // Side-effect: updates TempBase to reflect the new Temporary. 1509 // Side-effect: updates TempBase to reflect the new Temporary.
1510 if (BaseIsStackOrFramePtr) { 1510 if (BaseIsStackOrFramePtr) {
1511 TempBaseReg = ScratchReg; 1511 TempBaseReg = ScratchReg;
1512 TempBaseOffset = Offset; 1512 TempBaseOffset = Offset;
1513 } else { 1513 } else {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1600 MovInstr->getPredicate()); 1600 MovInstr->getPredicate());
1601 // _str() does not have a Dest, so we add a fake-def(Dest). 1601 // _str() does not have a Dest, so we add a fake-def(Dest).
1602 Target->Context.insert<InstFakeDef>(Dest); 1602 Target->Context.insert<InstFakeDef>(Dest);
1603 Legalized = true; 1603 Legalized = true;
1604 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { 1604 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
1605 if (Var->isRematerializable()) { 1605 if (Var->isRematerializable()) {
1606 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). 1606 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).
1607 1607
1608 // ExtraOffset is only needed for frame-pointer based frames as we have 1608 // ExtraOffset is only needed for frame-pointer based frames as we have
1609 // to account for spill storage. 1609 // to account for spill storage.
1610 const int32_t ExtraOffset = 1610 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg())
1611 (static_cast<SizeT>(Var->getRegNum()) == Target->getFrameReg()) 1611 ? Target->getFrameFixedAllocaOffset()
1612 ? Target->getFrameFixedAllocaOffset() 1612 : 0;
1613 : 0;
1614 1613
1615 const int32_t Offset = Var->getStackOffset() + ExtraOffset; 1614 const int32_t Offset = Var->getStackOffset() + ExtraOffset;
1616 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); 1615 Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
1617 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); 1616 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum());
1618 Target->_mov(Dest, T); 1617 Target->_mov(Dest, T);
1619 Legalized = true; 1618 Legalized = true;
1620 } else { 1619 } else {
1621 if (!Var->hasReg()) { 1620 if (!Var->hasReg()) {
1622 // This is a _mov(Variable, Mem()), i.e., a load. 1621 // This is a _mov(Variable, Mem()), i.e., a load.
1623 const int32_t Offset = Var->getStackOffset(); 1622 const int32_t Offset = Var->getStackOffset();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 bool AllowOffsets) { 1670 bool AllowOffsets) {
1672 assert(!Mem->isRegReg() || !Mem->getIndex()->isRematerializable()); 1671 assert(!Mem->isRegReg() || !Mem->getIndex()->isRematerializable());
1673 assert( 1672 assert(
1674 Mem->isRegReg() || 1673 Mem->isRegReg() ||
1675 Target->isLegalMemOffset(Mem->getType(), Mem->getOffset()->getValue())); 1674 Target->isLegalMemOffset(Mem->getType(), Mem->getOffset()->getValue()));
1676 1675
1677 bool Legalized = false; 1676 bool Legalized = false;
1678 Variable *Base = Mem->getBase(); 1677 Variable *Base = Mem->getBase();
1679 int32_t Offset = Mem->isRegReg() ? 0 : Mem->getOffset()->getValue(); 1678 int32_t Offset = Mem->isRegReg() ? 0 : Mem->getOffset()->getValue();
1680 if (Base->isRematerializable()) { 1679 if (Base->isRematerializable()) {
1681 const int32_t ExtraOffset = 1680 const int32_t ExtraOffset = (Base->getRegNum() == Target->getFrameReg())
1682 (static_cast<SizeT>(Base->getRegNum()) == Target->getFrameReg()) 1681 ? Target->getFrameFixedAllocaOffset()
1683 ? Target->getFrameFixedAllocaOffset() 1682 : 0;
1684 : 0;
1685 Offset += Base->getStackOffset() + ExtraOffset; 1683 Offset += Base->getStackOffset() + ExtraOffset;
1686 Base = Target->getPhysicalRegister(Base->getRegNum()); 1684 Base = Target->getPhysicalRegister(Base->getRegNum());
1687 assert(!Base->isRematerializable()); 1685 assert(!Base->isRematerializable());
1688 Legalized = true; 1686 Legalized = true;
1689 } 1687 }
1690 1688
1691 if (!Legalized && !Target->NeedSandboxing) { 1689 if (!Legalized && !Target->NeedSandboxing) {
1692 return nullptr; 1690 return nullptr;
1693 } 1691 }
1694 1692
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1894 } 1892 }
1895 } 1893 }
1896 llvm::report_fatal_error("Unsupported operand type"); 1894 llvm::report_fatal_error("Unsupported operand type");
1897 return nullptr; 1895 return nullptr;
1898 } 1896 }
1899 1897
1900 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, 1898 llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include,
1901 RegSetMask Exclude) const { 1899 RegSetMask Exclude) const {
1902 llvm::SmallBitVector Registers(RegARM32::Reg_NUM); 1900 llvm::SmallBitVector Registers(RegARM32::Reg_NUM);
1903 1901
1904 for (int32_t i = 0; i < RegARM32::Reg_NUM; ++i) { 1902 for (uint32_t i = 0; i < RegARM32::Reg_NUM; ++i) {
1905 const auto &Entry = RegARM32::RegTable[i]; 1903 const auto &Entry = RegARM32::RegTable[i];
1906 if (Entry.Scratch && (Include & RegSet_CallerSave)) 1904 if (Entry.Scratch && (Include & RegSet_CallerSave))
1907 Registers[i] = true; 1905 Registers[i] = true;
1908 if (Entry.Preserved && (Include & RegSet_CalleeSave)) 1906 if (Entry.Preserved && (Include & RegSet_CalleeSave))
1909 Registers[i] = true; 1907 Registers[i] = true;
1910 if (Entry.StackPtr && (Include & RegSet_StackPointer)) 1908 if (Entry.StackPtr && (Include & RegSet_StackPointer))
1911 Registers[i] = true; 1909 Registers[i] = true;
1912 if (Entry.FramePtr && (Include & RegSet_FramePointer)) 1910 if (Entry.FramePtr && (Include & RegSet_FramePointer))
1913 Registers[i] = true; 1911 Registers[i] = true;
1914 if (Entry.Scratch && (Exclude & RegSet_CallerSave)) 1912 if (Entry.Scratch && (Exclude & RegSet_CallerSave))
(...skipping 1439 matching lines...) Expand 10 before | Expand all | Expand 10 after
3354 if (TargetHelperPreamble != ARM32HelpersPreamble.end()) { 3352 if (TargetHelperPreamble != ARM32HelpersPreamble.end()) {
3355 (this->*TargetHelperPreamble->second)(Instr); 3353 (this->*TargetHelperPreamble->second)(Instr);
3356 } 3354 }
3357 } 3355 }
3358 MaybeLeafFunc = false; 3356 MaybeLeafFunc = false;
3359 NeedsStackAlignment = true; 3357 NeedsStackAlignment = true;
3360 3358
3361 // Assign arguments to registers and stack. Also reserve stack. 3359 // Assign arguments to registers and stack. Also reserve stack.
3362 TargetARM32::CallingConv CC; 3360 TargetARM32::CallingConv CC;
3363 // Pair of Arg Operand -> GPR number assignments. 3361 // Pair of Arg Operand -> GPR number assignments.
3364 llvm::SmallVector<std::pair<Operand *, int32_t>, NumGPRArgs> GPRArgs; 3362 llvm::SmallVector<std::pair<Operand *, RegNumT>, NumGPRArgs> GPRArgs;
3365 llvm::SmallVector<std::pair<Operand *, int32_t>, NumFP32Args> FPArgs; 3363 llvm::SmallVector<std::pair<Operand *, RegNumT>, NumFP32Args> FPArgs;
3366 // Pair of Arg Operand -> stack offset. 3364 // Pair of Arg Operand -> stack offset.
3367 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; 3365 llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs;
3368 size_t ParameterAreaSizeBytes = 0; 3366 size_t ParameterAreaSizeBytes = 0;
3369 3367
3370 // Classify each argument operand according to the location where the 3368 // Classify each argument operand according to the location where the
3371 // argument is passed. 3369 // argument is passed.
3372 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { 3370 for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
3373 Operand *Arg = legalizeUndef(Instr->getArg(i)); 3371 Operand *Arg = legalizeUndef(Instr->getArg(i));
3374 const Type Ty = Arg->getType(); 3372 const Type Ty = Arg->getType();
3375 bool InReg = false; 3373 bool InReg = false;
3376 int32_t Reg; 3374 RegNumT Reg;
3377 if (isScalarIntegerType(Ty)) { 3375 if (isScalarIntegerType(Ty)) {
3378 InReg = CC.argInGPR(Ty, &Reg); 3376 InReg = CC.argInGPR(Ty, &Reg);
3379 } else { 3377 } else {
3380 InReg = CC.argInVFP(Ty, &Reg); 3378 InReg = CC.argInVFP(Ty, &Reg);
3381 } 3379 }
3382 3380
3383 if (!InReg) { 3381 if (!InReg) {
3384 ParameterAreaSizeBytes = 3382 ParameterAreaSizeBytes =
3385 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); 3383 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty);
3386 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); 3384 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes));
3387 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); 3385 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty);
3388 continue; 3386 continue;
3389 } 3387 }
3390 3388
3391 if (Ty == IceType_i64) { 3389 if (Ty == IceType_i64) {
3392 Operand *Lo = loOperand(Arg); 3390 Operand *Lo = loOperand(Arg);
3393 Operand *Hi = hiOperand(Arg); 3391 Operand *Hi = hiOperand(Arg);
3394 GPRArgs.push_back( 3392 GPRArgs.push_back(std::make_pair(
3395 std::make_pair(Lo, RegARM32::getI64PairFirstGPRNum(Reg))); 3393 Lo, RegNumT::fixme(RegARM32::getI64PairFirstGPRNum(Reg))));
3396 GPRArgs.push_back( 3394 GPRArgs.push_back(std::make_pair(
3397 std::make_pair(Hi, RegARM32::getI64PairSecondGPRNum(Reg))); 3395 Hi, RegNumT::fixme(RegARM32::getI64PairSecondGPRNum(Reg))));
3398 } else if (isScalarIntegerType(Ty)) { 3396 } else if (isScalarIntegerType(Ty)) {
3399 GPRArgs.push_back(std::make_pair(Arg, Reg)); 3397 GPRArgs.push_back(std::make_pair(Arg, Reg));
3400 } else { 3398 } else {
3401 FPArgs.push_back(std::make_pair(Arg, Reg)); 3399 FPArgs.push_back(std::make_pair(Arg, Reg));
3402 } 3400 }
3403 } 3401 }
3404 3402
3405 // Adjust the parameter area so that the stack is aligned. It is assumed that 3403 // Adjust the parameter area so that the stack is aligned. It is assumed that
3406 // the stack is already aligned at the start of the calling sequence. 3404 // the stack is already aligned at the start of the calling sequence.
3407 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes); 3405 ParameterAreaSizeBytes = applyStackAlignment(ParameterAreaSizeBytes);
(...skipping 2042 matching lines...) Expand 10 before | Expand all | Expand 10 after
5450 } 5448 }
5451 5449
5452 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) { 5450 void TargetARM32::lowerUnreachable(const InstUnreachable * /*Instr*/) {
5453 _trap(); 5451 _trap();
5454 } 5452 }
5455 5453
5456 void TargetARM32::prelowerPhis() { 5454 void TargetARM32::prelowerPhis() {
5457 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func); 5455 PhiLowering::prelowerPhis32Bit<TargetARM32>(this, Context.getNode(), Func);
5458 } 5456 }
5459 5457
5460 Variable *TargetARM32::makeVectorOfZeros(Type Ty, int32_t RegNum) { 5458 Variable *TargetARM32::makeVectorOfZeros(Type Ty, RegNumT RegNum) {
5461 Variable *Reg = makeReg(Ty, RegNum); 5459 Variable *Reg = makeReg(Ty, RegNum);
5462 Context.insert<InstFakeDef>(Reg); 5460 Context.insert<InstFakeDef>(Reg);
5463 UnimplementedError(Func->getContext()->getFlags()); 5461 UnimplementedError(Func->getContext()->getFlags());
5464 return Reg; 5462 return Reg;
5465 } 5463 }
5466 5464
5467 // Helper for legalize() to emit the right code to lower an operand to a 5465 // Helper for legalize() to emit the right code to lower an operand to a
5468 // register of the appropriate type. 5466 // register of the appropriate type.
5469 Variable *TargetARM32::copyToReg(Operand *Src, int32_t RegNum) { 5467 Variable *TargetARM32::copyToReg(Operand *Src, RegNumT RegNum) {
5470 Type Ty = Src->getType(); 5468 Type Ty = Src->getType();
5471 Variable *Reg = makeReg(Ty, RegNum); 5469 Variable *Reg = makeReg(Ty, RegNum);
5472 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) { 5470 if (auto *Mem = llvm::dyn_cast<OperandARM32Mem>(Src)) {
5473 _ldr(Reg, Mem); 5471 _ldr(Reg, Mem);
5474 } else { 5472 } else {
5475 _mov(Reg, Src); 5473 _mov(Reg, Src);
5476 } 5474 }
5477 return Reg; 5475 return Reg;
5478 } 5476 }
5479 5477
5480 // TODO(jpp): remove unneeded else clauses in legalize. 5478 // TODO(jpp): remove unneeded else clauses in legalize.
5481 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed, 5479 Operand *TargetARM32::legalize(Operand *From, LegalMask Allowed,
5482 int32_t RegNum) { 5480 RegNumT RegNum) {
5483 Type Ty = From->getType(); 5481 Type Ty = From->getType();
5484 // Assert that a physical register is allowed. To date, all calls to 5482 // Assert that a physical register is allowed. To date, all calls to
5485 // legalize() allow a physical register. Legal_Flex converts registers to the 5483 // legalize() allow a physical register. Legal_Flex converts registers to the
5486 // right type OperandARM32FlexReg as needed. 5484 // right type OperandARM32FlexReg as needed.
5487 assert(Allowed & Legal_Reg); 5485 assert(Allowed & Legal_Reg);
5488 5486
5489 // Copied ipsis literis from TargetX86Base<Machine>. 5487 // Copied ipsis literis from TargetX86Base<Machine>.
5490 if (RegNum == Variable::NoRegister) { 5488 if (RegNum == RegNumT::NoRegister) {
5491 if (Variable *Subst = getContext().availabilityGet(From)) { 5489 if (Variable *Subst = getContext().availabilityGet(From)) {
5492 // At this point we know there is a potential substitution available. 5490 // At this point we know there is a potential substitution available.
5493 if (!Subst->isRematerializable() && Subst->mustHaveReg() && 5491 if (!Subst->isRematerializable() && Subst->mustHaveReg() &&
5494 !Subst->hasReg()) { 5492 !Subst->hasReg()) {
5495 // At this point we know the substitution will have a register. 5493 // At this point we know the substitution will have a register.
5496 if (From->getType() == Subst->getType()) { 5494 if (From->getType() == Subst->getType()) {
5497 // At this point we know the substitution's register is compatible. 5495 // At this point we know the substitution's register is compatible.
5498 return Subst; 5496 return Subst;
5499 } 5497 }
5500 } 5498 }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
5664 } 5662 }
5665 // Check if the variable is guaranteed a physical register. This can happen 5663 // 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 5664 // either when the variable is pre-colored or when it is assigned infinite
5667 // weight. 5665 // weight.
5668 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); 5666 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
5669 // We need a new physical register for the operand if: 5667 // We need a new physical register for the operand if:
5670 // Mem is not allowed and Var isn't guaranteed a physical 5668 // Mem is not allowed and Var isn't guaranteed a physical
5671 // register, or 5669 // register, or
5672 // RegNum is required and Var->getRegNum() doesn't match. 5670 // RegNum is required and Var->getRegNum() doesn't match.
5673 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 5671 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
5674 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { 5672 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) {
5675 From = copyToReg(From, RegNum); 5673 From = copyToReg(From, RegNum);
5676 } 5674 }
5677 return From; 5675 return From;
5678 } 5676 }
5679 llvm::report_fatal_error("Unhandled operand kind in legalize()"); 5677 llvm::report_fatal_error("Unhandled operand kind in legalize()");
5680 5678
5681 return From; 5679 return From;
5682 } 5680 }
5683 5681
5684 /// Provide a trivial wrapper to legalize() for this common usage. 5682 /// Provide a trivial wrapper to legalize() for this common usage.
5685 Variable *TargetARM32::legalizeToReg(Operand *From, int32_t RegNum) { 5683 Variable *TargetARM32::legalizeToReg(Operand *From, RegNumT RegNum) {
5686 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); 5684 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum));
5687 } 5685 }
5688 5686
5689 /// Legalize undef values to concrete values. 5687 /// Legalize undef values to concrete values.
5690 Operand *TargetARM32::legalizeUndef(Operand *From, int32_t RegNum) { 5688 Operand *TargetARM32::legalizeUndef(Operand *From, RegNumT RegNum) {
5691 Type Ty = From->getType(); 5689 Type Ty = From->getType();
5692 if (llvm::isa<ConstantUndef>(From)) { 5690 if (llvm::isa<ConstantUndef>(From)) {
5693 // Lower undefs to zero. Another option is to lower undefs to an 5691 // Lower undefs to zero. Another option is to lower undefs to an
5694 // uninitialized register; however, using an uninitialized register results 5692 // uninitialized register; however, using an uninitialized register results
5695 // in less predictable code. 5693 // in less predictable code.
5696 // 5694 //
5697 // If in the future the implementation is changed to lower undef values to 5695 // If in the future the implementation is changed to lower undef values to
5698 // uninitialized registers, a FakeDef will be needed: 5696 // uninitialized registers, a FakeDef will be needed:
5699 // Context.insert(InstFakeDef::create(Func, Reg)); This is in order to 5697 // 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 5698 // ensure that the live range of Reg is not overestimated. If the constant
(...skipping 27 matching lines...) Expand all
5728 Variable64On32 *TargetARM32::makeI64RegPair() { 5726 Variable64On32 *TargetARM32::makeI64RegPair() {
5729 Variable64On32 *Reg = 5727 Variable64On32 *Reg =
5730 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); 5728 llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
5731 Reg->setMustHaveReg(); 5729 Reg->setMustHaveReg();
5732 Reg->initHiLo(Func); 5730 Reg->initHiLo(Func);
5733 Reg->getLo()->setMustNotHaveReg(); 5731 Reg->getLo()->setMustNotHaveReg();
5734 Reg->getHi()->setMustNotHaveReg(); 5732 Reg->getHi()->setMustNotHaveReg();
5735 return Reg; 5733 return Reg;
5736 } 5734 }
5737 5735
5738 Variable *TargetARM32::makeReg(Type Type, int32_t RegNum) { 5736 Variable *TargetARM32::makeReg(Type Type, RegNumT RegNum) {
5739 // There aren't any 64-bit integer registers for ARM32. 5737 // There aren't any 64-bit integer registers for ARM32.
5740 assert(Type != IceType_i64); 5738 assert(Type != IceType_i64);
5741 assert(AllowTemporaryWithNoReg || RegNum != Variable::NoRegister); 5739 assert(AllowTemporaryWithNoReg || RegNum != RegNumT::NoRegister);
5742 Variable *Reg = Func->makeVariable(Type); 5740 Variable *Reg = Func->makeVariable(Type);
5743 if (RegNum == Variable::NoRegister) 5741 if (RegNum == RegNumT::NoRegister)
5744 Reg->setMustHaveReg(); 5742 Reg->setMustHaveReg();
5745 else 5743 else
5746 Reg->setRegNum(RegNum); 5744 Reg->setRegNum(RegNum);
5747 return Reg; 5745 return Reg;
5748 } 5746 }
5749 5747
5750 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align, 5748 void TargetARM32::alignRegisterPow2(Variable *Reg, uint32_t Align,
5751 int32_t TmpRegNum) { 5749 RegNumT TmpRegNum) {
5752 assert(llvm::isPowerOf2_32(Align)); 5750 assert(llvm::isPowerOf2_32(Align));
5753 uint32_t RotateAmt; 5751 uint32_t RotateAmt;
5754 uint32_t Immed_8; 5752 uint32_t Immed_8;
5755 Operand *Mask; 5753 Operand *Mask;
5756 // Use AND or BIC to mask off the bits, depending on which immediate fits (if 5754 // 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 5755 // it fits at all). Assume Align is usually small, in which case BIC works
5758 // better. Thus, this rounds down to the alignment. 5756 // better. Thus, this rounds down to the alignment.
5759 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) { 5757 if (OperandARM32FlexImm::canHoldImm(Align - 1, &RotateAmt, &Immed_8)) {
5760 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex, 5758 Mask = legalize(Ctx->getConstantInt32(Align - 1), Legal_Reg | Legal_Flex,
5761 TmpRegNum); 5759 TmpRegNum);
5762 _bic(Reg, Reg, Mask); 5760 _bic(Reg, Reg, Mask);
5763 } else { 5761 } else {
5764 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex, 5762 Mask = legalize(Ctx->getConstantInt32(-Align), Legal_Reg | Legal_Flex,
5765 TmpRegNum); 5763 TmpRegNum);
5766 _and(Reg, Reg, Mask); 5764 _and(Reg, Reg, Mask);
5767 } 5765 }
5768 } 5766 }
5769 5767
5770 void TargetARM32::postLower() { 5768 void TargetARM32::postLower() {
5771 if (Ctx->getFlags().getOptLevel() == Opt_m1) 5769 if (Ctx->getFlags().getOptLevel() == Opt_m1)
5772 return; 5770 return;
5773 markRedefinitions(); 5771 markRedefinitions();
5774 Context.availabilityUpdate(); 5772 Context.availabilityUpdate();
5775 } 5773 }
5776 5774
5777 void TargetARM32::makeRandomRegisterPermutation( 5775 void TargetARM32::makeRandomRegisterPermutation(
5778 llvm::SmallVectorImpl<int32_t> &Permutation, 5776 llvm::SmallVectorImpl<RegNumT> &Permutation,
5779 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { 5777 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const {
5780 (void)Permutation; 5778 (void)Permutation;
5781 (void)ExcludeRegisters; 5779 (void)ExcludeRegisters;
5782 (void)Salt; 5780 (void)Salt;
5783 UnimplementedError(Func->getContext()->getFlags()); 5781 UnimplementedError(Func->getContext()->getFlags());
5784 } 5782 }
5785 5783
5786 void TargetARM32::emit(const ConstantInteger32 *C) const { 5784 void TargetARM32::emit(const ConstantInteger32 *C) const {
5787 if (!BuildDefs::dump()) 5785 if (!BuildDefs::dump())
5788 return; 5786 return;
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
6523 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; 6521 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
6524 } 6522 }
6525 6523
6526 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM]; 6524 llvm::SmallBitVector TargetARM32::TypeToRegisterSet[RegARM32::RCARM32_NUM];
6527 llvm::SmallBitVector 6525 llvm::SmallBitVector
6528 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM]; 6526 TargetARM32::TypeToRegisterSetUnfiltered[RegARM32::RCARM32_NUM];
6529 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM]; 6527 llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM];
6530 6528
6531 } // end of namespace ARM32 6529 } // end of namespace ARM32
6532 } // end of namespace Ice 6530 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698