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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2052793003: Calling convention for MIPS32 (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero@master
Patch Set: Created 4 years, 6 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
« src/IceRegistersMIPS32.h ('K') | « src/IceTargetLoweringMIPS32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // 1 //
2 // The Subzero Code Generator 2 // The Subzero Code Generator
3 // 3 //
4 // This file is distributed under the University of Illinois Open Source 4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details. 5 // License. See LICENSE.TXT for details.
6 // 6 //
7 //===----------------------------------------------------------------------===// 7 //===----------------------------------------------------------------------===//
8 /// 8 ///
9 /// \file 9 /// \file
10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 namespace Ice { 57 namespace Ice {
58 namespace MIPS32 { 58 namespace MIPS32 {
59 59
60 using llvm::isInt; 60 using llvm::isInt;
61 61
62 namespace { 62 namespace {
63 63
64 // The maximum number of arguments to pass in GPR registers. 64 // The maximum number of arguments to pass in GPR registers.
65 constexpr uint32_t MIPS32_MAX_GPR_ARG = 4; 65 constexpr uint32_t MIPS32_MAX_GPR_ARG = 4;
66 66
67 std::array<RegNumT, MIPS32_MAX_GPR_ARG> GPRArgInitializer;
68 std::array<RegNumT, MIPS32_MAX_GPR_ARG / 2> I64ArgInitializer;
69
70 constexpr uint32_t MIPS32_MAX_FP_ARG = 2;
71
72 std::array<RegNumT, MIPS32_MAX_FP_ARG> FP32ArgInitializer;
73 std::array<RegNumT, MIPS32_MAX_FP_ARG> FP64ArgInitializer;
74
67 const char *getRegClassName(RegClass C) { 75 const char *getRegClassName(RegClass C) {
68 auto ClassNum = static_cast<RegClassMIPS32>(C); 76 auto ClassNum = static_cast<RegClassMIPS32>(C);
69 assert(ClassNum < RCMIPS32_NUM); 77 assert(ClassNum < RCMIPS32_NUM);
70 switch (ClassNum) { 78 switch (ClassNum) {
71 default: 79 default:
72 assert(C < RC_Target); 80 assert(C < RC_Target);
73 return regClassString(C); 81 return regClassString(C);
74 // Add handling of new register classes below. 82 // Add handling of new register classes below.
75 } 83 }
76 } 84 }
(...skipping 21 matching lines...) Expand all
98 RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM); \ 106 RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM); \
99 for (SizeT RegAlias : alias_init) { \ 107 for (SizeT RegAlias : alias_init) { \
100 assert(!RegisterAliases[RegMIPS32::val][RegAlias] && \ 108 assert(!RegisterAliases[RegMIPS32::val][RegAlias] && \
101 "Duplicate alias for " #val); \ 109 "Duplicate alias for " #val); \
102 RegisterAliases[RegMIPS32::val].set(RegAlias); \ 110 RegisterAliases[RegMIPS32::val].set(RegAlias); \
103 } \ 111 } \
104 RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM); \ 112 RegisterAliases[RegMIPS32::val].resize(RegMIPS32::Reg_NUM); \
105 assert(RegisterAliases[RegMIPS32::val][RegMIPS32::val]); 113 assert(RegisterAliases[RegMIPS32::val][RegMIPS32::val]);
106 REGMIPS32_TABLE; 114 REGMIPS32_TABLE;
107 #undef X 115 #undef X
116
117 // TODO(mohit.bhakkad): Change these inits once we provide argument related
118 // field in register tables
119 for (size_t i = 0; i < MIPS32_MAX_GPR_ARG; i++)
120 GPRArgInitializer[i] = RegNumT::fixme(RegMIPS32::Reg_A0 + i);
121
122 for (size_t i = 0; i < MIPS32_MAX_GPR_ARG / 2; i++)
123 I64ArgInitializer[i] = RegNumT::fixme(RegMIPS32::Reg_A0A1 + i);
124
125 for (size_t i = 0; i < MIPS32_MAX_FP_ARG; i++) {
126 FP32ArgInitializer[i] = RegNumT::fixme(RegMIPS32::Reg_F12 + i * 2);
127 FP64ArgInitializer[i] = RegNumT::fixme(RegMIPS32::Reg_F12F13 + i);
128 }
129
108 TypeToRegisterSet[IceType_void] = InvalidRegisters; 130 TypeToRegisterSet[IceType_void] = InvalidRegisters;
109 TypeToRegisterSet[IceType_i1] = IntegerRegisters; 131 TypeToRegisterSet[IceType_i1] = IntegerRegisters;
110 TypeToRegisterSet[IceType_i8] = IntegerRegisters; 132 TypeToRegisterSet[IceType_i8] = IntegerRegisters;
111 TypeToRegisterSet[IceType_i16] = IntegerRegisters; 133 TypeToRegisterSet[IceType_i16] = IntegerRegisters;
112 TypeToRegisterSet[IceType_i32] = IntegerRegisters; 134 TypeToRegisterSet[IceType_i32] = IntegerRegisters;
113 TypeToRegisterSet[IceType_i64] = IntegerRegisters; 135 TypeToRegisterSet[IceType_i64] = IntegerRegisters;
114 TypeToRegisterSet[IceType_f32] = Float32Registers; 136 TypeToRegisterSet[IceType_f32] = Float32Registers;
115 TypeToRegisterSet[IceType_f64] = Float64Registers; 137 TypeToRegisterSet[IceType_f64] = Float64Registers;
116 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; 138 TypeToRegisterSet[IceType_v4i1] = VectorRegisters;
117 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; 139 TypeToRegisterSet[IceType_v8i1] = VectorRegisters;
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 return; 421 return;
400 } else { 422 } else {
401 int32_t Offset = Var->getStackOffset(); 423 int32_t Offset = Var->getStackOffset();
402 Str << Offset; 424 Str << Offset;
403 Str << "($" << getRegName(getFrameOrStackReg(), FrameSPTy); 425 Str << "($" << getRegName(getFrameOrStackReg(), FrameSPTy);
404 Str << ")"; 426 Str << ")";
405 } 427 }
406 UnimplementedError(getFlags()); 428 UnimplementedError(getFlags());
407 } 429 }
408 430
431 TargetMIPS32::CallingConv::CallingConv()
432 : GPRegsUsed(RegMIPS32::Reg_NUM),
433 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()),
434 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()),
435 VFPRegsUsed(RegMIPS32::Reg_NUM),
436 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()),
437 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()) {}
438
439 bool TargetMIPS32::CallingConv::argInGPR(Type Ty, RegNumT *Reg) {
440 CfgVector<RegNumT> *Source;
441
442 switch (Ty) {
443 default: {
444 assert(isScalarIntegerType(Ty));
445 Source = &GPRArgs;
446 } break;
447 case IceType_i64: {
448 Source = &I64Args;
449 } break;
450 }
451
452 discardUnavailableGPRsAndTheirAliases(Source);
453
454 if (Source->empty()) {
455 GPRegsUsed.set();
456 return false;
457 }
458
459 *Reg = Source->back();
460 // Note that we don't Source->pop_back() here. This is intentional. Notice how
461 // we mark all of Reg's aliases as Used. So, for the next argument,
462 // Source->back() is marked as unavailable, and it is thus implicitly popped
463 // from the stack.
464 GPRegsUsed |= RegisterAliases[*Reg];
465 return true;
466 }
467
468 // GPR are not packed when passing parameters. Thus, a function foo(i32, i64,
469 // i32) will have the first argument in a0, the second in a2-a3, and the third
470 // on the stack. To model this behavior, whenever we pop a register from Regs,
471 // we remove all of its aliases from the pool of available GPRs. This has the
472 // effect of computing the "closure" on the GPR registers.
473 void TargetMIPS32::CallingConv::discardUnavailableGPRsAndTheirAliases(
474 CfgVector<RegNumT> *Regs) {
475 while (!Regs->empty() && GPRegsUsed[Regs->back()]) {
476 GPRegsUsed |= RegisterAliases[Regs->back()];
477 Regs->pop_back();
478 }
479 }
480
481 bool TargetMIPS32::CallingConv::argInVFP(Type Ty, RegNumT *Reg) {
482 CfgVector<RegNumT> *Source;
483
484 switch (Ty) {
485 default: {
486 UnimplementedError(getFlags());
487 return false;
488 } break;
489 case IceType_f32: {
490 Source = &FP32Args;
491 } break;
492 case IceType_f64: {
493 Source = &FP64Args;
494 } break;
495 }
496
497 discardUnavailableVFPRegs(Source);
498
499 if (Source->empty()) {
500 VFPRegsUsed.set();
501 return false;
502 }
503
504 *Reg = Source->back();
505 VFPRegsUsed |= RegisterAliases[*Reg];
506 return true;
507 }
508
509 // Arguments in VFP registers are not packed, so we don't mark the popped
510 // registers' aliases as unavailable.
511 void TargetMIPS32::CallingConv::discardUnavailableVFPRegs(
512 CfgVector<RegNumT> *Regs) {
513 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) {
514 Regs->pop_back();
515 }
516 }
517
409 void TargetMIPS32::lowerArguments() { 518 void TargetMIPS32::lowerArguments() {
410 VarList &Args = Func->getArgs(); 519 VarList &Args = Func->getArgs();
411 // We are only handling integer registers for now. The Mips o32 ABI is 520 // We are only handling integer registers for now. The Mips o32 ABI is
412 // somewhat complex but will be implemented in its totality through follow 521 // somewhat complex but will be implemented in its totality through follow
413 // on patches. 522 // on patches.
414 // 523 //
415 unsigned NumGPRRegsUsed = 0; 524 unsigned NumGPRRegsUsed = 0;
416 // For each register argument, replace Arg in the argument list with the 525 // For each register argument, replace Arg in the argument list with the
417 // home register. Then generate an instruction in the prolog to copy the 526 // home register. Then generate an instruction in the prolog to copy the
418 // home register to the assigned location of Arg. 527 // home register to the assigned location of Arg.
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1714 Str << "\t.set\t" 1823 Str << "\t.set\t"
1715 << "nomips16\n"; 1824 << "nomips16\n";
1716 } 1825 }
1717 1826
1718 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 1827 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
1719 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 1828 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
1720 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 1829 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
1721 1830
1722 } // end of namespace MIPS32 1831 } // end of namespace MIPS32
1723 } // end of namespace Ice 1832 } // end of namespace Ice
OLDNEW
« src/IceRegistersMIPS32.h ('K') | « src/IceTargetLoweringMIPS32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698