OLD | NEW |
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 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1445 | 1445 |
1446 Operand *Src = MovInstr->getSrc(0); | 1446 Operand *Src = MovInstr->getSrc(0); |
1447 const Type SrcTy = Src->getType(); | 1447 const Type SrcTy = Src->getType(); |
1448 (void)SrcTy; | 1448 (void)SrcTy; |
1449 assert(SrcTy != IceType_i64); | 1449 assert(SrcTy != IceType_i64); |
1450 | 1450 |
1451 if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) | 1451 if (MovInstr->isMultiDest() || MovInstr->isMultiSource()) |
1452 return; | 1452 return; |
1453 | 1453 |
1454 bool Legalized = false; | 1454 bool Legalized = false; |
| 1455 auto *SrcR = llvm::cast<Variable>(Src); |
| 1456 if (Dest->hasReg() && SrcR->hasReg()) { |
| 1457 // This might be a GP to/from FP move generated due to argument passing. |
| 1458 // Use mtc1/mfc1 instead of mov.[s/d] if src and dst registers are of |
| 1459 // different types. |
| 1460 const bool IsDstGPR = RegMIPS32::isGPRReg(Dest->getRegNum()); |
| 1461 const bool IsSrcGPR = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
| 1462 const RegNumT SRegNum = SrcR->getRegNum(); |
| 1463 const RegNumT DRegNum = Dest->getRegNum(); |
| 1464 if (IsDstGPR != IsSrcGPR) { |
| 1465 if (IsDstGPR) { |
| 1466 // Dest is GPR and SrcR is FPR. Use mfc1. |
| 1467 if (typeWidthInBytes(Dest->getType()) == 8) { |
| 1468 // Split it into two mfc1 instructions |
| 1469 Variable *SrcGPRHi = Target->makeReg( |
| 1470 IceType_f32, RegMIPS32::get64PairFirstRegNum(SRegNum)); |
| 1471 Variable *SrcGPRLo = Target->makeReg( |
| 1472 IceType_f32, RegMIPS32::get64PairSecondRegNum(SRegNum)); |
| 1473 Variable *DstFPRHi = Target->makeReg( |
| 1474 IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
| 1475 Variable *DstFPRLo = Target->makeReg( |
| 1476 IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); |
| 1477 Target->_mov(DstFPRHi, SrcGPRLo); |
| 1478 Target->_mov(DstFPRLo, SrcGPRHi); |
| 1479 Legalized = true; |
| 1480 } else { |
| 1481 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); |
| 1482 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); |
| 1483 Target->_mov(DstFPR, SrcGPR); |
| 1484 Legalized = true; |
| 1485 } |
| 1486 } else { |
| 1487 // Dest is FPR and SrcR is GPR. Use mtc1. |
| 1488 if (typeWidthInBytes(SrcR->getType()) == 8) { |
| 1489 // Split it into two mtc1 instructions |
| 1490 Variable *SrcGPRHi = Target->makeReg( |
| 1491 IceType_i32, RegMIPS32::get64PairFirstRegNum(SRegNum)); |
| 1492 Variable *SrcGPRLo = Target->makeReg( |
| 1493 IceType_i32, RegMIPS32::get64PairSecondRegNum(SRegNum)); |
| 1494 Variable *DstFPRHi = Target->makeReg( |
| 1495 IceType_f32, RegMIPS32::get64PairFirstRegNum(DRegNum)); |
| 1496 Variable *DstFPRLo = Target->makeReg( |
| 1497 IceType_f32, RegMIPS32::get64PairSecondRegNum(DRegNum)); |
| 1498 Target->_mov(DstFPRHi, SrcGPRLo); |
| 1499 Target->_mov(DstFPRLo, SrcGPRHi); |
| 1500 Legalized = true; |
| 1501 } else { |
| 1502 Variable *SrcGPR = Target->makeReg(IceType_i32, SRegNum); |
| 1503 Variable *DstFPR = Target->makeReg(IceType_f32, DRegNum); |
| 1504 Target->_mov(DstFPR, SrcGPR); |
| 1505 Legalized = true; |
| 1506 } |
| 1507 } |
| 1508 } |
| 1509 if (Legalized) { |
| 1510 if (MovInstr->isDestRedefined()) { |
| 1511 Target->_set_dest_redefined(); |
| 1512 } |
| 1513 MovInstr->setDeleted(); |
| 1514 return; |
| 1515 } |
| 1516 } |
| 1517 |
1455 if (!Dest->hasReg()) { | 1518 if (!Dest->hasReg()) { |
1456 auto *SrcR = llvm::cast<Variable>(Src); | 1519 auto *SrcR = llvm::cast<Variable>(Src); |
1457 assert(SrcR->hasReg()); | 1520 assert(SrcR->hasReg()); |
1458 assert(!SrcR->isRematerializable()); | 1521 assert(!SrcR->isRematerializable()); |
1459 const int32_t Offset = Dest->getStackOffset(); | 1522 const int32_t Offset = Dest->getStackOffset(); |
1460 | 1523 |
1461 // This is a _mov(Mem(), Variable), i.e., a store. | 1524 // This is a _mov(Mem(), Variable), i.e., a store. |
1462 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); | 1525 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg()); |
1463 | 1526 |
1464 OperandMIPS32Mem *Addr = OperandMIPS32Mem::create( | 1527 OperandMIPS32Mem *Addr = OperandMIPS32Mem::create( |
1465 Target->Func, DestTy, Base, | 1528 Target->Func, DestTy, Base, |
1466 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); | 1529 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset))); |
1467 | 1530 |
1468 // FP arguments are passed in GP reg if first argument is in GP. In this | 1531 // FP arguments are passed in GP reg if first argument is in GP. In this |
1469 // case type of the SrcR is still FP thus we need to explicitly generate sw | 1532 // case type of the SrcR is still FP thus we need to explicitly generate sw |
1470 // instead of swc1. | 1533 // instead of swc1. |
1471 const RegNumT RegNum = SrcR->getRegNum(); | 1534 const RegNumT RegNum = SrcR->getRegNum(); |
1472 const bool isSrcGPReg = ((unsigned)RegNum >= RegMIPS32::Reg_A0 && | 1535 const bool IsSrcGPReg = RegMIPS32::isGPRReg(SrcR->getRegNum()); |
1473 (unsigned)RegNum <= RegMIPS32::Reg_A3) || | 1536 if (SrcTy == IceType_f32 && IsSrcGPReg == true) { |
1474 ((unsigned)RegNum >= RegMIPS32::Reg_A0A1 && | |
1475 (unsigned)RegNum <= RegMIPS32::Reg_A2A3); | |
1476 if (SrcTy == IceType_f32 && isSrcGPReg == true) { | |
1477 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); | 1537 Variable *SrcGPR = Target->makeReg(IceType_i32, RegNum); |
1478 Target->_sw(SrcGPR, Addr); | 1538 Target->_sw(SrcGPR, Addr); |
1479 } else if (SrcTy == IceType_f64 && isSrcGPReg == true) { | 1539 } else if (SrcTy == IceType_f64 && IsSrcGPReg == true) { |
1480 Variable *SrcGPRHi, *SrcGPRLo; | 1540 Variable *SrcGPRHi = |
1481 if (RegNum == RegMIPS32::Reg_A0A1) { | 1541 Target->makeReg(IceType_i32, RegMIPS32::get64PairFirstRegNum(RegNum)); |
1482 SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A0); | 1542 Variable *SrcGPRLo = Target->makeReg( |
1483 SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A1); | 1543 IceType_i32, RegMIPS32::get64PairSecondRegNum(RegNum)); |
1484 } else { | |
1485 SrcGPRLo = Target->makeReg(IceType_i32, RegMIPS32::Reg_A2); | |
1486 SrcGPRHi = Target->makeReg(IceType_i32, RegMIPS32::Reg_A3); | |
1487 } | |
1488 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( | 1544 OperandMIPS32Mem *AddrHi = OperandMIPS32Mem::create( |
1489 Target->Func, DestTy, Base, | 1545 Target->Func, DestTy, Base, |
1490 llvm::cast<ConstantInteger32>( | 1546 llvm::cast<ConstantInteger32>( |
1491 Target->Ctx->getConstantInt32(Offset + 4))); | 1547 Target->Ctx->getConstantInt32(Offset + 4))); |
1492 Target->_sw(SrcGPRLo, Addr); | 1548 Target->_sw(SrcGPRLo, Addr); |
1493 Target->_sw(SrcGPRHi, AddrHi); | 1549 Target->_sw(SrcGPRHi, AddrHi); |
1494 } else { | 1550 } else { |
1495 Target->_sw(SrcR, Addr); | 1551 Target->_sw(SrcR, Addr); |
1496 } | 1552 } |
1497 | 1553 |
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2404 } | 2460 } |
2405 case InstCast::Fpext: { | 2461 case InstCast::Fpext: { |
2406 assert(Dest->getType() == IceType_f64); | 2462 assert(Dest->getType() == IceType_f64); |
2407 assert(Src0->getType() == IceType_f32); | 2463 assert(Src0->getType() == IceType_f32); |
2408 auto *DestR = legalizeToReg(Dest); | 2464 auto *DestR = legalizeToReg(Dest); |
2409 auto *Src0R = legalizeToReg(Src0); | 2465 auto *Src0R = legalizeToReg(Src0); |
2410 _cvt_d_s(DestR, Src0R); | 2466 _cvt_d_s(DestR, Src0R); |
2411 _mov(Dest, DestR); | 2467 _mov(Dest, DestR); |
2412 break; | 2468 break; |
2413 } | 2469 } |
2414 case InstCast::Fptosi: // | 2470 case InstCast::Fptosi: { |
2415 UnimplementedLoweringError(this, Instr); | 2471 if (Src0Ty == IceType_f32 && DestTy == IceType_i32) { |
| 2472 Variable *Src0R = legalizeToReg(Src0); |
| 2473 Variable *FTmp = makeReg(IceType_f32); |
| 2474 _trunc_w_s(FTmp, Src0R); |
| 2475 _mov(Dest, FTmp); |
| 2476 } else { |
| 2477 UnimplementedLoweringError(this, Instr); |
| 2478 } |
2416 break; | 2479 break; |
| 2480 } |
2417 case InstCast::Fptoui: | 2481 case InstCast::Fptoui: |
2418 UnimplementedLoweringError(this, Instr); | 2482 UnimplementedLoweringError(this, Instr); |
2419 break; | 2483 break; |
2420 case InstCast::Sitofp: // | 2484 case InstCast::Sitofp: { |
2421 UnimplementedLoweringError(this, Instr); | 2485 if (Src0Ty == IceType_i32 && DestTy == IceType_f32) { |
| 2486 Variable *Src0R = legalizeToReg(Src0); |
| 2487 Variable *FTmp1 = makeReg(IceType_f32); |
| 2488 Variable *FTmp2 = makeReg(IceType_f32); |
| 2489 _mov(FTmp1, Src0R); |
| 2490 _cvt_s_w(FTmp2, FTmp1); |
| 2491 _mov(Dest, FTmp2); |
| 2492 } else { |
| 2493 UnimplementedLoweringError(this, Instr); |
| 2494 } |
2422 break; | 2495 break; |
| 2496 } |
2423 case InstCast::Uitofp: { | 2497 case InstCast::Uitofp: { |
2424 UnimplementedLoweringError(this, Instr); | 2498 UnimplementedLoweringError(this, Instr); |
2425 break; | 2499 break; |
2426 } | 2500 } |
2427 case InstCast::Bitcast: { | 2501 case InstCast::Bitcast: { |
2428 UnimplementedLoweringError(this, Instr); | 2502 UnimplementedLoweringError(this, Instr); |
2429 break; | 2503 break; |
2430 } | 2504 } |
2431 } | 2505 } |
2432 } | 2506 } |
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3545 Str << "\t.set\t" | 3619 Str << "\t.set\t" |
3546 << "nomips16\n"; | 3620 << "nomips16\n"; |
3547 } | 3621 } |
3548 | 3622 |
3549 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 3623 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
3550 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 3624 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
3551 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 3625 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
3552 | 3626 |
3553 } // end of namespace MIPS32 | 3627 } // end of namespace MIPS32 |
3554 } // end of namespace Ice | 3628 } // end of namespace Ice |
OLD | NEW |