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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2301303003: [SubZero] Implement load and store for MIPS (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addressed review comments Created 4 years, 3 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 // 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 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 regAlloc(RAK_InfOnly); 382 regAlloc(RAK_InfOnly);
383 if (Func->hasError()) 383 if (Func->hasError())
384 return; 384 return;
385 Func->dump("After regalloc of infinite-weight variables"); 385 Func->dump("After regalloc of infinite-weight variables");
386 386
387 Func->genFrame(); 387 Func->genFrame();
388 if (Func->hasError()) 388 if (Func->hasError())
389 return; 389 return;
390 Func->dump("After stack frame mapping"); 390 Func->dump("After stack frame mapping");
391 391
392 postLowerLegalization();
393 if (Func->hasError())
394 return;
395 Func->dump("After postLowerLegalization");
396
392 // Nop insertion 397 // Nop insertion
393 if (getFlags().getShouldDoNopInsertion()) { 398 if (getFlags().getShouldDoNopInsertion()) {
394 Func->doNopInsertion(); 399 Func->doNopInsertion();
395 } 400 }
396 } 401 }
397 402
398 bool TargetMIPS32::doBranchOpt(Inst *Instr, const CfgNode *NextNode) { 403 bool TargetMIPS32::doBranchOpt(Inst *Instr, const CfgNode *NextNode) {
399 if (auto *Br = llvm::dyn_cast<InstMIPS32Br>(Instr)) { 404 if (auto *Br = llvm::dyn_cast<InstMIPS32Br>(Instr)) {
400 return Br->optimizeBranch(NextNode); 405 return Br->optimizeBranch(NextNode);
401 } 406 }
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 else 494 else
490 Reg->setMustHaveReg(); 495 Reg->setMustHaveReg();
491 return Reg; 496 return Reg;
492 } 497 }
493 498
494 OperandMIPS32Mem *TargetMIPS32::formMemoryOperand(Operand *Operand, Type Ty) { 499 OperandMIPS32Mem *TargetMIPS32::formMemoryOperand(Operand *Operand, Type Ty) {
495 // It may be the case that address mode optimization already creates an 500 // It may be the case that address mode optimization already creates an
496 // OperandMIPS32Mem, so in that case it wouldn't need another level of 501 // OperandMIPS32Mem, so in that case it wouldn't need another level of
497 // transformation. 502 // transformation.
498 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) { 503 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) {
499 return Mem; 504 return llvm::cast<OperandMIPS32Mem>(legalize(Mem));
500 } 505 }
501 506
502 // If we didn't do address mode optimization, then we only have a base/offset 507 // If we didn't do address mode optimization, then we only have a base/offset
503 // to work with. MIPS always requires a base register, so just use that to 508 // to work with. MIPS always requires a base register, so just use that to
504 // hold the operand. 509 // hold the operand.
505 auto *Base = llvm::cast<Variable>(legalize(Operand, Legal_Reg)); 510 auto *Base = llvm::cast<Variable>(
511 legalize(Operand, Legal_Reg | Legal_Rematerializable));
506 const int32_t Offset = Base->hasStackOffset() ? Base->getStackOffset() : 0; 512 const int32_t Offset = Base->hasStackOffset() ? Base->getStackOffset() : 0;
507 return OperandMIPS32Mem::create( 513 return OperandMIPS32Mem::create(
508 Func, Ty, Base, 514 Func, Ty, Base,
509 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(Offset))); 515 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(Offset)));
510 } 516 }
511 517
512 void TargetMIPS32::emitVariable(const Variable *Var) const { 518 void TargetMIPS32::emitVariable(const Variable *Var) const {
513 if (!BuildDefs::dump()) 519 if (!BuildDefs::dump())
514 return; 520 return;
515 Ostream &Str = Ctx->getStrEmit(); 521 Ostream &Str = Ctx->getStrEmit();
516 const Type FrameSPTy = IceType_i32; 522 const Type FrameSPTy = IceType_i32;
517 if (Var->hasReg()) { 523 if (Var->hasReg()) {
518 Str << '$' << getRegName(Var->getRegNum(), Var->getType()); 524 Str << '$' << getRegName(Var->getRegNum(), Var->getType());
519 } else { 525 return;
520 int32_t Offset = Var->getStackOffset();
521 Str << Offset;
522 Str << "($" << getRegName(getFrameOrStackReg(), FrameSPTy);
523 Str << ")";
524 } 526 }
527 if (Var->mustHaveReg()) {
528 llvm::report_fatal_error("Infinite-weight Variable (" + Var->getName() +
529 ") has no register assigned - function " +
530 Func->getFunctionName());
531 }
532 const int32_t Offset = Var->getStackOffset();
533 Str << Offset;
534 Str << "($" << getRegName(getFrameOrStackReg(), FrameSPTy);
535 Str << ")";
525 } 536 }
526 537
527 TargetMIPS32::CallingConv::CallingConv() 538 TargetMIPS32::CallingConv::CallingConv()
528 : GPRegsUsed(RegMIPS32::Reg_NUM), 539 : GPRegsUsed(RegMIPS32::Reg_NUM),
529 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()), 540 GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()),
530 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()), 541 I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()),
531 VFPRegsUsed(RegMIPS32::Reg_NUM), 542 VFPRegsUsed(RegMIPS32::Reg_NUM),
532 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()), 543 FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()),
533 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()) {} 544 FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()) {}
534 545
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 return; 1045 return;
1035 } 1046 }
1036 1047
1037 Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister( 1048 Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister(
1038 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) { 1049 Variable *Base, int32_t Offset, RegNumT ScratchRegNum) {
1039 // Legalize will likely need a lui/ori combination, but if the top bits are 1050 // Legalize will likely need a lui/ori combination, but if the top bits are
1040 // all 0 from negating the offset and subtracting, we could use that instead. 1051 // all 0 from negating the offset and subtracting, we could use that instead.
1041 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0; 1052 const bool ShouldSub = Offset != 0 && (-Offset & 0xFFFF0000) == 0;
1042 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum); 1053 Variable *ScratchReg = Target->makeReg(IceType_i32, ScratchRegNum);
1043 if (ShouldSub) { 1054 if (ShouldSub) {
1044 Variable *OffsetVal = 1055 Variable *OffsetVal = Target->legalizeToReg(
1045 Target->legalizeToReg(Target->Ctx->getConstantInt32(-Offset)); 1056 Target->Ctx->getConstantInt32(-Offset), ScratchRegNum);
1046 Target->_sub(ScratchReg, Base, OffsetVal); 1057 Target->_sub(ScratchReg, Base, OffsetVal);
1047 } else { 1058 } else {
1048 Target->_addiu(ScratchReg, Base, Offset); 1059 Target->_addiu(ScratchReg, Base, Offset);
1049 } 1060 }
1050 1061
1051 return ScratchReg; 1062 return ScratchReg;
1052 } 1063 }
1053 1064
1054 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { 1065 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
1055 Variable *Dest = MovInstr->getDest(); 1066 Variable *Dest = MovInstr->getDest();
1056 assert(Dest != nullptr); 1067 assert(Dest != nullptr);
1057 const Type DestTy = Dest->getType(); 1068 const Type DestTy = Dest->getType();
1058 (void)DestTy;
1059 assert(DestTy != IceType_i64); 1069 assert(DestTy != IceType_i64);
1060 1070
1061 Operand *Src = MovInstr->getSrc(0); 1071 Operand *Src = MovInstr->getSrc(0);
1062 const Type SrcTy = Src->getType(); 1072 const Type SrcTy = Src->getType();
1063 (void)SrcTy; 1073 (void)SrcTy;
1064 assert(SrcTy != IceType_i64); 1074 assert(SrcTy != IceType_i64);
1065 1075
1066 if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) 1076 if (MovInstr->isMultiDest() || MovInstr->isMultiSource())
1067 return; 1077 return;
1068 1078
1069 bool Legalized = false; 1079 bool Legalized = false;
1070 if (Dest->hasReg()) { 1080 if (!Dest->hasReg()) {
1071 if (auto *Var = llvm::dyn_cast<Variable>(Src)) { 1081 auto *SrcR = llvm::cast<Variable>(Src);
1072 if (Var->isRematerializable()) { 1082 assert(SrcR->hasReg());
1073 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). 1083 assert(!SrcR->isRematerializable());
1084 const int32_t Offset = Dest->getStackOffset();
1074 1085
1075 // ExtraOffset is only needed for frame-pointer based frames as we have 1086 // This is a _mov(Mem(), Variable), i.e., a store.
1076 // to account for spill storage. 1087 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg());
1077 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg())
1078 ? Target->getFrameFixedAllocaOffset()
1079 : 0;
1080 1088
1081 const int32_t Offset = Var->getStackOffset() + ExtraOffset; 1089 OperandMIPS32Mem *Addr = OperandMIPS32Mem::create(
1082 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); 1090 Target->Func, DestTy, Base,
1083 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); 1091 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
1084 Target->_mov(Dest, T); 1092
1093 // FP arguments are passed in GP reg if first argument is in GP. In this
1094 // case type of the SrcR is still FP thus we need to explicitly generate sw
1095 // instead of swc1.
1096 const RegNumT RegNum = SrcR->getRegNum();
1097 const bool isSrcGPReg = ((unsigned)RegNum >= RegMIPS32::Reg_A0 &&
1098 (unsigned)RegNum <= RegMIPS32::Reg_A3) ||
1099 ((unsigned)RegNum >= RegMIPS32::Reg_A0A1 &&
1100 (unsigned)RegNum <= RegMIPS32::Reg_A2A3);
1101 if (SrcTy == IceType_f32 && isSrcGPReg == true) {
1102 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum);
1103 Target->_sw(SrcGPR, Addr);
1104 } else if (SrcTy == IceType_f64 && isSrcGPReg == true) {
1105 Variable *SrcGPRHi, *SrcGPRLo;
1106 if (RegNum == RegMIPS32::Reg_A0A1) {
1107 SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A0);
1108 SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A1);
1109 } else {
1110 SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A2);
1111 SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A3);
1112 }
1113 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create(
1114 Target->Func, DestTy, Base,
1115 llvm::cast<ConstantInteger32>(
1116 Target->Ctx->getConstantInt32(Offset + 4)));
1117 Target->_sw(SrcGPRLo, Addr);
1118 Target->_sw(SrcGPRHi, AddrHi);
1119 } else {
1120 Target->_sw(SrcR, Addr);
1121 }
1122
1123 Target->Context.insert<InstFakeDef>(Dest);
1124 Legalized = true;
1125 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
1126 if (Var->isRematerializable()) {
1127 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).
1128
1129 // ExtraOffset is only needed for frame-pointer based frames as we have
1130 // to account for spill storage.
1131 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg())
1132 ? Target->getFrameFixedAllocaOffset()
1133 : 0;
1134
1135 const int32_t Offset = Var->getStackOffset() + ExtraOffset;
1136 Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
1137 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum());
1138 Target->_mov(Dest, T);
1139 Legalized = true;
1140 } else {
1141 if (!Var->hasReg()) {
1142 // This is a _mov(Variable, Mem()), i.e., a load.
1143 const int32_t Offset = Var->getStackOffset();
1144 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg());
1145 OperandMIPS32Mem *Addr;
1146 Addr = OperandMIPS32Mem::create(
1147 Target->Func, DestTy, Base,
1148 llvm::cast<ConstantInteger32>(
1149 Target->Ctx->getConstantInt32(Offset)));
1150 Target->_lw(Dest, Addr);
1085 Legalized = true; 1151 Legalized = true;
1086 } else if (!Var->hasReg()) {
1087 UnimplementedError(getFlags());
1088 return;
1089 } 1152 }
1090 } 1153 }
1091 } else {
1092 UnimplementedError(getFlags());
1093 return;
1094 } 1154 }
1095 1155
1096 if (Legalized) { 1156 if (Legalized) {
1097 if (MovInstr->isDestRedefined()) { 1157 if (MovInstr->isDestRedefined()) {
1098 Target->_set_dest_redefined(); 1158 Target->_set_dest_redefined();
1099 } 1159 }
1100 MovInstr->setDeleted(); 1160 MovInstr->setDeleted();
1101 } 1161 }
1102 } 1162 }
1103 1163
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 } 1615 }
1556 1616
1557 Operand *Src0 = Instr->getSrc(0); 1617 Operand *Src0 = Instr->getSrc(0);
1558 assert(Dest->getType() == Src0->getType()); 1618 assert(Dest->getType() == Src0->getType());
1559 if (Dest->getType() == IceType_i64) { 1619 if (Dest->getType() == IceType_i64) {
1560 Src0 = legalizeUndef(Src0); 1620 Src0 = legalizeUndef(Src0);
1561 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); 1621 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg);
1562 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); 1622 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg);
1563 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1623 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
1564 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1624 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1565 // Variable *T_Lo = nullptr, *T_Hi = nullptr;
1566 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); 1625 auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
1567 _mov(T_Lo, Src0Lo); 1626 _mov(T_Lo, Src0Lo);
1568 _mov(DestLo, T_Lo); 1627 _mov(DestLo, T_Lo);
1569 _mov(T_Hi, Src0Hi); 1628 _mov(T_Hi, Src0Hi);
1570 _mov(DestHi, T_Hi); 1629 _mov(DestHi, T_Hi);
1571 } else { 1630 } else {
1572 Operand *SrcR; 1631 Operand *SrcR;
1573 if (Dest->hasReg()) { 1632 if (Dest->hasReg()) {
1574 // If Dest already has a physical register, then legalize the Src operand 1633 // If Dest already has a physical register, then legalize the Src operand
1575 // into a Variable with the same register assignment. This especially 1634 // into a Variable with the same register assignment. This especially
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
2235 UnimplementedLoweringError(this, Instr); 2294 UnimplementedLoweringError(this, Instr);
2236 return; 2295 return;
2237 case Intrinsics::UnknownIntrinsic: 2296 case Intrinsics::UnknownIntrinsic:
2238 Func->setError("Should not be lowering UnknownIntrinsic"); 2297 Func->setError("Should not be lowering UnknownIntrinsic");
2239 return; 2298 return;
2240 } 2299 }
2241 return; 2300 return;
2242 } 2301 }
2243 2302
2244 void TargetMIPS32::lowerLoad(const InstLoad *Instr) { 2303 void TargetMIPS32::lowerLoad(const InstLoad *Instr) {
2245 UnimplementedLoweringError(this, Instr); 2304 // A Load instruction can be treated the same as an Assign instruction, after
2305 // the source operand is transformed into an OperandARM32Mem operand.
2306 Type Ty = Instr->getDest()->getType();
2307 Operand *Src0 = formMemoryOperand(Instr->getSourceAddress(), Ty);
2308 Variable *DestLoad = Instr->getDest();
2309 auto *Assign = InstAssign::create(Func, DestLoad, Src0);
2310 lowerAssign(Assign);
2246 } 2311 }
2247 2312
2248 void TargetMIPS32::doAddressOptLoad() { UnimplementedError(getFlags()); } 2313 void TargetMIPS32::doAddressOptLoad() { UnimplementedError(getFlags()); }
2249 2314
2250 void TargetMIPS32::randomlyInsertNop(float Probability, 2315 void TargetMIPS32::randomlyInsertNop(float Probability,
2251 RandomNumberGenerator &RNG) { 2316 RandomNumberGenerator &RNG) {
2252 RandomNumberGeneratorWrapper RNGW(RNG); 2317 RandomNumberGeneratorWrapper RNGW(RNG);
2253 if (RNGW.getTrueWithProbability(Probability)) { 2318 if (RNGW.getTrueWithProbability(Probability)) {
2254 UnimplementedError(getFlags()); 2319 UnimplementedError(getFlags());
2255 } 2320 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 } 2494 }
2430 2495
2431 // Helper for legalize() to emit the right code to lower an operand to a 2496 // Helper for legalize() to emit the right code to lower an operand to a
2432 // register of the appropriate type. 2497 // register of the appropriate type.
2433 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) { 2498 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) {
2434 Type Ty = Src->getType(); 2499 Type Ty = Src->getType();
2435 Variable *Reg = makeReg(Ty, RegNum); 2500 Variable *Reg = makeReg(Ty, RegNum);
2436 if (isVectorType(Ty)) { 2501 if (isVectorType(Ty)) {
2437 UnimplementedError(getFlags()); 2502 UnimplementedError(getFlags());
2438 } else { 2503 } else {
2439 // Mov's Src operand can really only be the flexible second operand type 2504 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Src)) {
2440 // or a register. Users should guarantee that. 2505 _lw(Reg, Mem);
2441 _mov(Reg, Src); 2506 } else {
2507 _mov(Reg, Src);
2508 }
2442 } 2509 }
2443 return Reg; 2510 return Reg;
2444 } 2511 }
2445 2512
2446 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, 2513 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
2447 RegNumT RegNum) { 2514 RegNumT RegNum) {
2448 Type Ty = From->getType(); 2515 Type Ty = From->getType();
2449 // Assert that a physical register is allowed. To date, all calls 2516 // Assert that a physical register is allowed. To date, all calls
2450 // to legalize() allow a physical register. Legal_Flex converts 2517 // to legalize() allow a physical register. Legal_Flex converts
2451 // registers to the right type OperandMIPS32FlexReg as needed. 2518 // registers to the right type OperandMIPS32FlexReg as needed.
2452 assert(Allowed & Legal_Reg); 2519 assert(Allowed & Legal_Reg);
2520
2521 if (RegNum.hasNoValue()) {
2522 if (Variable *Subst = getContext().availabilityGet(From)) {
2523 // At this point we know there is a potential substitution available.
2524 if (!Subst->isRematerializable() && Subst->mustHaveReg() &&
2525 !Subst->hasReg()) {
2526 // At this point we know the substitution will have a register.
2527 if (From->getType() == Subst->getType()) {
2528 // At this point we know the substitution's register is compatible.
2529 return Subst;
2530 }
2531 }
2532 }
2533 }
2534
2453 // Go through the various types of operands: 2535 // Go through the various types of operands:
2454 // OperandMIPS32Mem, Constant, and Variable. 2536 // OperandMIPS32Mem, Constant, and Variable.
2455 // Given the above assertion, if type of operand is not legal 2537 // Given the above assertion, if type of operand is not legal
2456 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy 2538 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy
2457 // to a register. 2539 // to a register.
2540 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(From)) {
2541 // Base must be in a physical register.
2542 Variable *Base = Mem->getBase();
2543 ConstantInteger32 *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
2544 Variable *RegBase = nullptr;
2545 assert(Base);
2546
2547 RegBase = llvm::cast<Variable>(
2548 legalize(Base, Legal_Reg | Legal_Rematerializable));
2549
2550 if (Offset != nullptr && Offset->getValue() != 0) {
2551 static constexpr bool ZeroExt = false;
2552 if (!OperandMIPS32Mem::canHoldOffset(Ty, ZeroExt, Offset->getValue())) {
2553 llvm::report_fatal_error("Invalid memory offset.");
2554 }
2555 }
2556
2557 // Create a new operand if there was a change.
2558 if (Base != RegBase) {
2559 Mem = OperandMIPS32Mem::create(Func, Ty, RegBase, Offset,
2560 Mem->getAddrMode());
2561 }
2562
2563 if (Allowed & Legal_Mem) {
2564 From = Mem;
2565 } else {
2566 Variable *Reg = makeReg(Ty, RegNum);
2567 _lw(Reg, Mem);
2568 From = Reg;
2569 }
2570 return From;
2571 }
2572
2458 if (llvm::isa<Constant>(From)) { 2573 if (llvm::isa<Constant>(From)) {
2459 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { 2574 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) {
2460 (void)C; 2575 (void)C;
2461 // TODO(reed kotler): complete this case for proper implementation 2576 // TODO(reed kotler): complete this case for proper implementation
2462 Variable *Reg = makeReg(Ty, RegNum); 2577 Variable *Reg = makeReg(Ty, RegNum);
2463 Context.insert<InstFakeDef>(Reg); 2578 Context.insert<InstFakeDef>(Reg);
2464 return Reg; 2579 return Reg;
2465 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { 2580 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
2466 const uint32_t Value = C32->getValue(); 2581 const uint32_t Value = C32->getValue();
2467 // Check if the immediate will fit in a Flexible second operand, 2582 // Check if the immediate will fit in a Flexible second operand,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2504 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset); 2619 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset);
2505 if (Ty == IceType_f32) 2620 if (Ty == IceType_f32)
2506 _lwc1(TReg2, Addr, RO_Lo); 2621 _lwc1(TReg2, Addr, RO_Lo);
2507 else 2622 else
2508 _ldc1(TReg2, Addr, RO_Lo); 2623 _ldc1(TReg2, Addr, RO_Lo);
2509 return copyToReg(TReg2, RegNum); 2624 return copyToReg(TReg2, RegNum);
2510 } 2625 }
2511 } 2626 }
2512 2627
2513 if (auto *Var = llvm::dyn_cast<Variable>(From)) { 2628 if (auto *Var = llvm::dyn_cast<Variable>(From)) {
2629 if (Var->isRematerializable()) {
2630 if (Allowed & Legal_Rematerializable) {
2631 return From;
2632 }
2633
2634 Variable *T = makeReg(Var->getType(), RegNum);
2635 _mov(T, Var);
2636 return T;
2637 }
2514 // Check if the variable is guaranteed a physical register. This 2638 // Check if the variable is guaranteed a physical register. This
2515 // can happen either when the variable is pre-colored or when it is 2639 // can happen either when the variable is pre-colored or when it is
2516 // assigned infinite weight. 2640 // assigned infinite weight.
2517 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); 2641 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
2518 // We need a new physical register for the operand if: 2642 // We need a new physical register for the operand if:
2519 // Mem is not allowed and Var isn't guaranteed a physical 2643 // Mem is not allowed and Var isn't guaranteed a physical
2520 // register, or 2644 // register, or
2521 // RegNum is required and Var->getRegNum() doesn't match. 2645 // RegNum is required and Var->getRegNum() doesn't match.
2522 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 2646 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
2523 (RegNum.hasValue() && RegNum != Var->getRegNum())) { 2647 (RegNum.hasValue() && RegNum != Var->getRegNum())) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 Str << "\t.set\t" 2729 Str << "\t.set\t"
2606 << "nomips16\n"; 2730 << "nomips16\n";
2607 } 2731 }
2608 2732
2609 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 2733 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
2610 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 2734 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
2611 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 2735 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
2612 2736
2613 } // end of namespace MIPS32 2737 } // end of namespace MIPS32
2614 } // end of namespace Ice 2738 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698