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

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: 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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 =
1045 Target->legalizeToReg(Target->Ctx->getConstantInt32(-Offset)); 1056 Target->legalizeToReg(Target->Ctx->getConstantInt32(-Offset),
1057 ScratchRegNum);
1046 Target->_sub(ScratchReg, Base, OffsetVal); 1058 Target->_sub(ScratchReg, Base, OffsetVal);
1047 } else { 1059 } else {
1048 Target->_addiu(ScratchReg, Base, Offset); 1060 Target->_addiu(ScratchReg, Base, Offset);
1049 } 1061 }
1050 1062
1051 return ScratchReg; 1063 return ScratchReg;
1052 } 1064 }
1053 1065
1054 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { 1066 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
1055 Variable *Dest = MovInstr->getDest(); 1067 Variable *Dest = MovInstr->getDest();
1056 assert(Dest != nullptr); 1068 assert(Dest != nullptr);
1057 const Type DestTy = Dest->getType(); 1069 const Type DestTy = Dest->getType();
1058 (void)DestTy;
1059 assert(DestTy != IceType_i64); 1070 assert(DestTy != IceType_i64);
1060 1071
1061 Operand *Src = MovInstr->getSrc(0); 1072 Operand *Src = MovInstr->getSrc(0);
1062 const Type SrcTy = Src->getType(); 1073 const Type SrcTy = Src->getType();
1063 (void)SrcTy; 1074 (void)SrcTy;
1064 assert(SrcTy != IceType_i64); 1075 assert(SrcTy != IceType_i64);
1065 1076
1066 if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) 1077 if (MovInstr->isMultiDest() || MovInstr->isMultiSource())
1067 return; 1078 return;
1068 1079
1069 bool Legalized = false; 1080 bool Legalized = false;
1070 if (Dest->hasReg()) { 1081 if (!Dest->hasReg()) {
1071 if (auto *Var = llvm::dyn_cast<Variable>(Src)) { 1082 auto *SrcR = llvm::cast<Variable>(Src);
1072 if (Var->isRematerializable()) { 1083 assert(SrcR->hasReg());
1073 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). 1084 assert(!SrcR->isRematerializable());
1085 const int32_t Offset = Dest->getStackOffset();
1074 1086
1075 // ExtraOffset is only needed for frame-pointer based frames as we have 1087 // This is a _mov(Mem(), Variable), i.e., a store.
1076 // to account for spill storage. 1088 auto *Base = Target->getPhysicalRegister(
1077 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg()) 1089 Target->getFrameOrStackReg());
1078 ? Target->getFrameFixedAllocaOffset()
1079 : 0;
1080 1090
1081 const int32_t Offset = Var->getStackOffset() + ExtraOffset; 1091 OperandMIPS32Mem *Addr =
1082 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); 1092 OperandMIPS32Mem::create(Target->Func, DestTy, Base,
1083 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); 1093 llvm::cast<ConstantInteger32>(
1084 Target->_mov(Dest, T); 1094 Target->Ctx->getConstantInt32(Offset)));
1095
1096 // FP arguments are passed in GP reg if first argument is
Jim Stichnoth 2016/09/03 13:47:13 "is is in GP" ==> "is in GP" Also, maybe reflow c
jaydeep.patil 2016/09/04 06:24:30 Done.
1097 // is in GP. In this case type of the SrcR is still FP thus
1098 // we need to explicitly generate sw instead of swc1.
1099 const RegNumT RegNum = SrcR->getRegNum();
1100 const bool isSrcGPReg = ((unsigned)RegNum >= RegMIPS32::Reg_A0
1101 && (unsigned)RegNum <= RegMIPS32::Reg_A3)
1102 || ((unsigned)RegNum >= RegMIPS32::Reg_A0A1
1103 && (unsigned)RegNum <= RegMIPS32::Reg_A2A3);
1104 if (SrcTy == IceType_f32 && isSrcGPReg == true) {
1105 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum);
1106 Target->_sw(SrcGPR, Addr);
1107 } else if (SrcTy == IceType_f64 && isSrcGPReg == true) {
1108 Variable *SrcGPRHi, *SrcGPRLo;
1109 if (RegNum == RegMIPS32::Reg_A0A1) {
1110 SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A0);
1111 SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A1);
1112 } else {
1113 SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A2);
1114 SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A3);
1115 }
1116 OperandMIPS32Mem *AddrHi =
1117 OperandMIPS32Mem::create(Target->Func, DestTy, Base,
1118 llvm::cast<ConstantInteger32>(
1119 Target->Ctx->getConstantInt32(Offset+4)));
1120 Target->_sw(SrcGPRLo, Addr);
1121 Target->_sw(SrcGPRHi, AddrHi);
1122 } else {
1123 Target->_sw(SrcR, Addr);
1124 }
1125
1126 Target->Context.insert<InstFakeDef>(Dest);
1127 Legalized = true;
1128 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
1129 if (Var->isRematerializable()) {
1130 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).
1131
1132 // ExtraOffset is only needed for frame-pointer based frames as we have
1133 // to account for spill storage.
1134 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg())
1135 ? Target->getFrameFixedAllocaOffset()
1136 : 0;
1137
1138 const int32_t Offset = Var->getStackOffset() + ExtraOffset;
1139 Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
1140 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum());
1141 Target->_mov(Dest, T);
1142 Legalized = true;
1143 } else {
1144 if (!Var->hasReg()) {
1145 // This is a _mov(Variable, Mem()), i.e., a load.
1146 const int32_t Offset = Var->getStackOffset();
1147 auto *Base = Target->getPhysicalRegister(
1148 Target->getFrameOrStackReg());
1149 OperandMIPS32Mem *Addr;
1150 Addr = OperandMIPS32Mem::create(Target->Func, DestTy,
1151 Base,
1152 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
1153 Target->_lw(Dest, Addr);
1085 Legalized = true; 1154 Legalized = true;
1086 } else if (!Var->hasReg()) {
1087 UnimplementedError(getFlags());
1088 return;
1089 } 1155 }
1090 } 1156 }
1091 } else {
1092 UnimplementedError(getFlags());
1093 return;
1094 } 1157 }
1095 1158
1096 if (Legalized) { 1159 if (Legalized) {
1097 if (MovInstr->isDestRedefined()) { 1160 if (MovInstr->isDestRedefined()) {
1098 Target->_set_dest_redefined(); 1161 Target->_set_dest_redefined();
1099 } 1162 }
1100 MovInstr->setDeleted(); 1163 MovInstr->setDeleted();
1101 } 1164 }
1102 } 1165 }
1103 1166
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1555 } 1618 }
1556 1619
1557 Operand *Src0 = Instr->getSrc(0); 1620 Operand *Src0 = Instr->getSrc(0);
1558 assert(Dest->getType() == Src0->getType()); 1621 assert(Dest->getType() == Src0->getType());
1559 if (Dest->getType() == IceType_i64) { 1622 if (Dest->getType() == IceType_i64) {
1560 Src0 = legalizeUndef(Src0); 1623 Src0 = legalizeUndef(Src0);
1561 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg); 1624 Operand *Src0Lo = legalize(loOperand(Src0), Legal_Reg);
1562 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg); 1625 Operand *Src0Hi = legalize(hiOperand(Src0), Legal_Reg);
1563 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); 1626 auto *DestLo = llvm::cast<Variable>(loOperand(Dest));
1564 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 1627 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest));
1565 // Variable *T_Lo = nullptr, *T_Hi = nullptr;
1566 auto *T_Lo = I32Reg(), *T_Hi = I32Reg(); 1628 auto *T_Lo = I32Reg(), *T_Hi = I32Reg();
1567 _mov(T_Lo, Src0Lo); 1629 _mov(T_Lo, Src0Lo);
1568 _mov(DestLo, T_Lo); 1630 _mov(DestLo, T_Lo);
1569 _mov(T_Hi, Src0Hi); 1631 _mov(T_Hi, Src0Hi);
1570 _mov(DestHi, T_Hi); 1632 _mov(DestHi, T_Hi);
1571 } else { 1633 } else {
1572 Operand *SrcR; 1634 Operand *SrcR;
1573 if (Dest->hasReg()) { 1635 if (Dest->hasReg()) {
1574 // If Dest already has a physical register, then legalize the Src operand 1636 // If Dest already has a physical register, then legalize the Src operand
1575 // into a Variable with the same register assignment. This especially 1637 // 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); 2297 UnimplementedLoweringError(this, Instr);
2236 return; 2298 return;
2237 case Intrinsics::UnknownIntrinsic: 2299 case Intrinsics::UnknownIntrinsic:
2238 Func->setError("Should not be lowering UnknownIntrinsic"); 2300 Func->setError("Should not be lowering UnknownIntrinsic");
2239 return; 2301 return;
2240 } 2302 }
2241 return; 2303 return;
2242 } 2304 }
2243 2305
2244 void TargetMIPS32::lowerLoad(const InstLoad *Instr) { 2306 void TargetMIPS32::lowerLoad(const InstLoad *Instr) {
2245 UnimplementedLoweringError(this, Instr); 2307 // A Load instruction can be treated the same as an Assign instruction, after
2308 // the source operand is transformed into an OperandARM32Mem operand.
2309 Type Ty = Instr->getDest()->getType();
2310 Operand *Src0 = formMemoryOperand(Instr->getSourceAddress(), Ty);
2311 Variable *DestLoad = Instr->getDest();
2312 auto *Assign = InstAssign::create(Func, DestLoad, Src0);
2313 lowerAssign(Assign);
2246 } 2314 }
2247 2315
2248 void TargetMIPS32::doAddressOptLoad() { UnimplementedError(getFlags()); } 2316 void TargetMIPS32::doAddressOptLoad() { UnimplementedError(getFlags()); }
2249 2317
2250 void TargetMIPS32::randomlyInsertNop(float Probability, 2318 void TargetMIPS32::randomlyInsertNop(float Probability,
2251 RandomNumberGenerator &RNG) { 2319 RandomNumberGenerator &RNG) {
2252 RandomNumberGeneratorWrapper RNGW(RNG); 2320 RandomNumberGeneratorWrapper RNGW(RNG);
2253 if (RNGW.getTrueWithProbability(Probability)) { 2321 if (RNGW.getTrueWithProbability(Probability)) {
2254 UnimplementedError(getFlags()); 2322 UnimplementedError(getFlags());
2255 } 2323 }
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 } 2497 }
2430 2498
2431 // Helper for legalize() to emit the right code to lower an operand to a 2499 // Helper for legalize() to emit the right code to lower an operand to a
2432 // register of the appropriate type. 2500 // register of the appropriate type.
2433 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) { 2501 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) {
2434 Type Ty = Src->getType(); 2502 Type Ty = Src->getType();
2435 Variable *Reg = makeReg(Ty, RegNum); 2503 Variable *Reg = makeReg(Ty, RegNum);
2436 if (isVectorType(Ty)) { 2504 if (isVectorType(Ty)) {
2437 UnimplementedError(getFlags()); 2505 UnimplementedError(getFlags());
2438 } else { 2506 } else {
2439 // Mov's Src operand can really only be the flexible second operand type 2507 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Src)) {
2440 // or a register. Users should guarantee that. 2508 _lw(Reg, Mem);
2441 _mov(Reg, Src); 2509 } else {
2510 _mov(Reg, Src);
2511 }
2442 } 2512 }
2443 return Reg; 2513 return Reg;
2444 } 2514 }
2445 2515
2446 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, 2516 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
2447 RegNumT RegNum) { 2517 RegNumT RegNum) {
2448 Type Ty = From->getType(); 2518 Type Ty = From->getType();
2449 // Assert that a physical register is allowed. To date, all calls 2519 // Assert that a physical register is allowed. To date, all calls
2450 // to legalize() allow a physical register. Legal_Flex converts 2520 // to legalize() allow a physical register. Legal_Flex converts
2451 // registers to the right type OperandMIPS32FlexReg as needed. 2521 // registers to the right type OperandMIPS32FlexReg as needed.
2452 assert(Allowed & Legal_Reg); 2522 assert(Allowed & Legal_Reg);
2523
2524 if (RegNum.hasNoValue()) {
2525 if (Variable *Subst = getContext().availabilityGet(From)) {
2526 // At this point we know there is a potential substitution available.
2527 if (!Subst->isRematerializable() && Subst->mustHaveReg() &&
2528 !Subst->hasReg()) {
2529 // At this point we know the substitution will have a register.
2530 if (From->getType() == Subst->getType()) {
2531 // At this point we know the substitution's register is compatible.
2532 return Subst;
2533 }
2534 }
2535 }
2536 }
2537
2453 // Go through the various types of operands: 2538 // Go through the various types of operands:
2454 // OperandMIPS32Mem, Constant, and Variable. 2539 // OperandMIPS32Mem, Constant, and Variable.
2455 // Given the above assertion, if type of operand is not legal 2540 // Given the above assertion, if type of operand is not legal
2456 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy 2541 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy
2457 // to a register. 2542 // to a register.
2543 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(From)) {
2544 // Base must be in a physical register.
2545 Variable *Base = Mem->getBase();
2546 ConstantInteger32 *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset());
2547 Variable *RegBase = nullptr;
2548 assert(Base);
2549
2550 RegBase = llvm::cast<Variable>(
2551 legalize(Base, Legal_Reg | Legal_Rematerializable));
2552
2553 if (Offset != nullptr && Offset->getValue() != 0) {
2554 static constexpr bool ZeroExt = false;
2555 if (!OperandMIPS32Mem::canHoldOffset(Ty, ZeroExt, Offset->getValue())) {
2556 llvm::report_fatal_error("Invalid memory offset.");
2557 }
2558 }
2559
2560 // Create a new operand if there was a change.
2561 if (Base != RegBase) {
2562 Mem = OperandMIPS32Mem::create(Func, Ty, RegBase, Offset,
2563 Mem->getAddrMode());
2564 }
2565
2566 if (Allowed & Legal_Mem) {
2567 From = Mem;
2568 } else {
2569 Variable *Reg = makeReg(Ty, RegNum);
2570 _lw(Reg, Mem);
2571 From = Reg;
2572 }
2573 return From;
2574 }
2575
2458 if (llvm::isa<Constant>(From)) { 2576 if (llvm::isa<Constant>(From)) {
2459 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { 2577 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) {
2460 (void)C; 2578 (void)C;
2461 // TODO(reed kotler): complete this case for proper implementation 2579 // TODO(reed kotler): complete this case for proper implementation
2462 Variable *Reg = makeReg(Ty, RegNum); 2580 Variable *Reg = makeReg(Ty, RegNum);
2463 Context.insert<InstFakeDef>(Reg); 2581 Context.insert<InstFakeDef>(Reg);
2464 return Reg; 2582 return Reg;
2465 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { 2583 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) {
2466 const uint32_t Value = C32->getValue(); 2584 const uint32_t Value = C32->getValue();
2467 // Check if the immediate will fit in a Flexible second operand, 2585 // 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); 2622 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset);
2505 if (Ty == IceType_f32) 2623 if (Ty == IceType_f32)
2506 _lwc1(TReg2, Addr, RO_Lo); 2624 _lwc1(TReg2, Addr, RO_Lo);
2507 else 2625 else
2508 _ldc1(TReg2, Addr, RO_Lo); 2626 _ldc1(TReg2, Addr, RO_Lo);
2509 return copyToReg(TReg2, RegNum); 2627 return copyToReg(TReg2, RegNum);
2510 } 2628 }
2511 } 2629 }
2512 2630
2513 if (auto *Var = llvm::dyn_cast<Variable>(From)) { 2631 if (auto *Var = llvm::dyn_cast<Variable>(From)) {
2632 if (Var->isRematerializable()) {
2633 if (Allowed & Legal_Rematerializable) {
2634 return From;
2635 }
2636
2637 Variable *T = makeReg(Var->getType(), RegNum);
2638 _mov(T, Var);
2639 return T;
2640 }
2514 // Check if the variable is guaranteed a physical register. This 2641 // Check if the variable is guaranteed a physical register. This
2515 // can happen either when the variable is pre-colored or when it is 2642 // can happen either when the variable is pre-colored or when it is
2516 // assigned infinite weight. 2643 // assigned infinite weight.
2517 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); 2644 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg());
2518 // We need a new physical register for the operand if: 2645 // We need a new physical register for the operand if:
2519 // Mem is not allowed and Var isn't guaranteed a physical 2646 // Mem is not allowed and Var isn't guaranteed a physical
2520 // register, or 2647 // register, or
2521 // RegNum is required and Var->getRegNum() doesn't match. 2648 // RegNum is required and Var->getRegNum() doesn't match.
2522 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || 2649 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
2523 (RegNum.hasValue() && RegNum != Var->getRegNum())) { 2650 (RegNum.hasValue() && RegNum != Var->getRegNum())) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 Str << "\t.set\t" 2732 Str << "\t.set\t"
2606 << "nomips16\n"; 2733 << "nomips16\n";
2607 } 2734 }
2608 2735
2609 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; 2736 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM];
2610 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; 2737 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM];
2611 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; 2738 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
2612 2739
2613 } // end of namespace MIPS32 2740 } // end of namespace MIPS32
2614 } // end of namespace Ice 2741 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698