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

Side by Side Diff: src/IceTargetLoweringMIPS32.cpp

Issue 2619943003: [SubZero] Fix code generation issues occurred in Cross-test and PNaCL smoke-tests (Closed)
Patch Set: Addressed review comments Created 3 years, 11 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
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/assembler/mips32/encoding_intrinsics.ll » ('j') | 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 90
91 // Stack alignment 91 // Stack alignment
92 constexpr uint32_t MIPS32_STACK_ALIGNMENT_BYTES = 16; 92 constexpr uint32_t MIPS32_STACK_ALIGNMENT_BYTES = 16;
93 93
94 // Value is in bytes. Return Value adjusted to the next highest multiple of the 94 // Value is in bytes. Return Value adjusted to the next highest multiple of the
95 // stack alignment required for the given type. 95 // stack alignment required for the given type.
96 uint32_t applyStackAlignmentTy(uint32_t Value, Type Ty) { 96 uint32_t applyStackAlignmentTy(uint32_t Value, Type Ty) {
97 size_t typeAlignInBytes = typeWidthInBytes(Ty); 97 size_t typeAlignInBytes = typeWidthInBytes(Ty);
98 // Vectors are stored on stack with the same alignment as that of int type 98 // Vectors are stored on stack with the same alignment as that of int type
99 if (isVectorType(Ty)) 99 if (isVectorType(Ty))
100 typeAlignInBytes = typeWidthInBytes(IceType_i32); 100 typeAlignInBytes = typeWidthInBytes(IceType_i64);
101 return Utils::applyAlignment(Value, typeAlignInBytes); 101 return Utils::applyAlignment(Value, typeAlignInBytes);
102 } 102 }
103 103
104 // Value is in bytes. Return Value adjusted to the next highest multiple of the 104 // Value is in bytes. Return Value adjusted to the next highest multiple of the
105 // stack alignment. 105 // stack alignment.
106 uint32_t applyStackAlignment(uint32_t Value) { 106 uint32_t applyStackAlignment(uint32_t Value) {
107 return Utils::applyAlignment(Value, MIPS32_STACK_ALIGNMENT_BYTES); 107 return Utils::applyAlignment(Value, MIPS32_STACK_ALIGNMENT_BYTES);
108 } 108 }
109 109
110 } // end of anonymous namespace 110 } // end of anonymous namespace
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 PartialOnStack = true; 233 PartialOnStack = true;
234 } 234 }
235 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { 235 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) {
236 Operand *Arg = legalizeUndef(Call->getArg(i)); 236 Operand *Arg = legalizeUndef(Call->getArg(i));
237 const Type Ty = Arg->getType(); 237 const Type Ty = Arg->getType();
238 RegNumT RegNum; 238 RegNumT RegNum;
239 if (CC.argInReg(Ty, i, &RegNum)) { 239 if (CC.argInReg(Ty, i, &RegNum)) {
240 // If PartialOnStack is true and if this is a vector type then last two 240 // If PartialOnStack is true and if this is a vector type then last two
241 // elements are on stack 241 // elements are on stack
242 if (PartialOnStack && isVectorType(Ty)) { 242 if (PartialOnStack && isVectorType(Ty)) {
243 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, IceType_i32); 243 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, IceType_i64);
244 OutArgsSizeBytes += typeWidthInBytesOnStack(IceType_i32) * 2; 244 OutArgsSizeBytes += typeWidthInBytesOnStack(IceType_i32) * 2;
245 } 245 }
246 continue; 246 continue;
247 } 247 }
248 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty); 248 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty);
249 OutArgsSizeBytes += typeWidthInBytesOnStack(Ty); 249 OutArgsSizeBytes += typeWidthInBytesOnStack(Ty);
250 } 250 }
251 // Add size of argument save area 251 // Add size of argument save area
252 constexpr int BytesPerStackArg = 4; 252 constexpr int BytesPerStackArg = 4;
253 OutArgsSizeBytes += MIPS32_MAX_GPR_ARG * BytesPerStackArg; 253 OutArgsSizeBytes += MIPS32_MAX_GPR_ARG * BytesPerStackArg;
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 // Context.insert(InstFakeDef::create(Func, Reg)); 980 // Context.insert(InstFakeDef::create(Func, Reg));
981 // This is in order to ensure that the live range of Reg is not 981 // This is in order to ensure that the live range of Reg is not
982 // overestimated. If the constant being lowered is a 64 bit value, 982 // overestimated. If the constant being lowered is a 64 bit value,
983 // then the result should be split and the lo and hi components will 983 // then the result should be split and the lo and hi components will
984 // need to go in uninitialized registers. 984 // need to go in uninitialized registers.
985 if (isVectorType(Ty)) { 985 if (isVectorType(Ty)) {
986 Variable *Var = makeReg(Ty, RegNum); 986 Variable *Var = makeReg(Ty, RegNum);
987 auto *Reg = llvm::cast<VariableVecOn32>(Var); 987 auto *Reg = llvm::cast<VariableVecOn32>(Var);
988 Reg->initVecElement(Func); 988 Reg->initVecElement(Func);
989 auto *Zero = getZero(); 989 auto *Zero = getZero();
990 Context.insert<InstFakeDef>(Zero);
991 for (Variable *Var : Reg->getContainers()) { 990 for (Variable *Var : Reg->getContainers()) {
992 _mov(Var, Zero); 991 _mov(Var, Zero);
993 } 992 }
994 return Reg; 993 return Reg;
995 } 994 }
996 return Ctx->getConstantZero(Ty); 995 return Ctx->getConstantZero(Ty);
997 } 996 }
998 return From; 997 return From;
999 } 998 }
1000 999
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 1467
1469 // RegClasses is a tuple of 1468 // RegClasses is a tuple of
1470 // 1469 //
1471 // <First Register in Class, Last Register in Class, Vector of Save Registers> 1470 // <First Register in Class, Last Register in Class, Vector of Save Registers>
1472 // 1471 //
1473 // We use this tuple to figure out which register we should save/restore 1472 // We use this tuple to figure out which register we should save/restore
1474 // during 1473 // during
1475 // prolog/epilog. 1474 // prolog/epilog.
1476 using RegClassType = std::tuple<uint32_t, uint32_t, VarList *>; 1475 using RegClassType = std::tuple<uint32_t, uint32_t, VarList *>;
1477 const RegClassType RegClass = RegClassType( 1476 const RegClassType RegClass = RegClassType(
1478 RegMIPS32::Reg_GPR_First, RegMIPS32::Reg_GPR_Last, &PreservedGPRs); 1477 RegMIPS32::Reg_GPR_First, RegMIPS32::Reg_FPR_Last, &PreservedGPRs);
1479 const uint32_t FirstRegInClass = std::get<0>(RegClass); 1478 const uint32_t FirstRegInClass = std::get<0>(RegClass);
1480 const uint32_t LastRegInClass = std::get<1>(RegClass); 1479 const uint32_t LastRegInClass = std::get<1>(RegClass);
1481 VarList *const PreservedRegsInClass = std::get<2>(RegClass); 1480 VarList *const PreservedRegsInClass = std::get<2>(RegClass);
1482 for (uint32_t Reg = LastRegInClass; Reg > FirstRegInClass; Reg--) { 1481 for (uint32_t Reg = LastRegInClass; Reg > FirstRegInClass; Reg--) {
1483 if (!ToPreserve[Reg]) { 1482 if (!ToPreserve[Reg]) {
1484 continue; 1483 continue;
1485 } 1484 }
1486 ++NumCallee; 1485 ++NumCallee;
1487 Variable *PhysicalRegister = getPhysicalRegister(RegNumT::fromInt(Reg)); 1486 Variable *PhysicalRegister = getPhysicalRegister(RegNumT::fromInt(Reg));
1488 PreservedRegsSizeBytes += 1487 PreservedRegsSizeBytes +=
(...skipping 24 matching lines...) Expand all
1513 SpillAreaSizeBytes += MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1); 1512 SpillAreaSizeBytes += MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1);
1514 } else { 1513 } else {
1515 SpillAreaSizeBytes = applyStackAlignment( 1514 SpillAreaSizeBytes = applyStackAlignment(
1516 SpillAreaSizeBytes + 1515 SpillAreaSizeBytes +
1517 (VariableAllocaUsed ? VariableAllocaAlignBytes : MaxOutArgsSizeBytes)); 1516 (VariableAllocaUsed ? VariableAllocaAlignBytes : MaxOutArgsSizeBytes));
1518 } 1517 }
1519 1518
1520 // Combine fixed alloca with SpillAreaSize. 1519 // Combine fixed alloca with SpillAreaSize.
1521 SpillAreaSizeBytes += FixedAllocaSizeBytes; 1520 SpillAreaSizeBytes += FixedAllocaSizeBytes;
1522 1521
1523 TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes; 1522 TotalStackSizeBytes =
1523 applyStackAlignment(PreservedRegsSizeBytes + SpillAreaSizeBytes);
1524 1524
1525 // Generate "addiu sp, sp, -TotalStackSizeBytes" 1525 // Generate "addiu sp, sp, -TotalStackSizeBytes"
1526 if (TotalStackSizeBytes) { 1526 if (TotalStackSizeBytes) {
1527 // Use the scratch register if needed to legalize the immediate. 1527 // Use the scratch register if needed to legalize the immediate.
1528 Sandboxer(this).addiu_sp(-TotalStackSizeBytes); 1528 Sandboxer(this).addiu_sp(-TotalStackSizeBytes);
1529 } 1529 }
1530 1530
1531 Ctx->statsUpdateFrameBytes(TotalStackSizeBytes); 1531 Ctx->statsUpdateFrameBytes(TotalStackSizeBytes);
1532 1532
1533 if (!PreservedGPRs.empty()) { 1533 if (!PreservedGPRs.empty()) {
1534 uint32_t StackOffset = TotalStackSizeBytes; 1534 uint32_t StackOffset = TotalStackSizeBytes;
1535 for (Variable *Var : *PreservedRegsInClass) { 1535 for (Variable *Var : *PreservedRegsInClass) {
1536 Variable *PhysicalRegister = getPhysicalRegister(Var->getRegNum()); 1536 Type RegType;
1537 StackOffset -= typeWidthInBytesOnStack(PhysicalRegister->getType()); 1537 if (RegMIPS32::isFPRReg(Var->getRegNum()))
1538 RegType = IceType_f32;
1539 else
1540 RegType = IceType_i32;
1541 auto *PhysicalRegister = makeReg(RegType, Var->getRegNum());
1542 StackOffset -= typeWidthInBytesOnStack(RegType);
1538 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); 1543 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
1539 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( 1544 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create(
1540 Func, IceType_i32, SP, 1545 Func, RegType, SP,
1541 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); 1546 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset)));
1542 Sandboxer(this).sw(PhysicalRegister, MemoryLocation); 1547 Sandboxer(this).sw(PhysicalRegister, MemoryLocation);
1543 } 1548 }
1544 } 1549 }
1545 1550
1546 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP); 1551 Variable *FP = getPhysicalRegister(RegMIPS32::Reg_FP);
1547 1552
1548 // Generate "mov FP, SP" if needed. 1553 // Generate "mov FP, SP" if needed.
1549 if (UsesFramePointer) { 1554 if (UsesFramePointer) {
1550 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); 1555 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1645 Context.insert<InstFakeUse>(SP); 1650 Context.insert<InstFakeUse>(SP);
1646 Sandboxer(this).reset_sp(FP); 1651 Sandboxer(this).reset_sp(FP);
1647 } 1652 }
1648 1653
1649 VarList::reverse_iterator RIter, END; 1654 VarList::reverse_iterator RIter, END;
1650 1655
1651 if (!PreservedGPRs.empty()) { 1656 if (!PreservedGPRs.empty()) {
1652 uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes; 1657 uint32_t StackOffset = TotalStackSizeBytes - PreservedRegsSizeBytes;
1653 for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend(); 1658 for (RIter = PreservedGPRs.rbegin(), END = PreservedGPRs.rend();
1654 RIter != END; ++RIter) { 1659 RIter != END; ++RIter) {
1655 Variable *PhysicalRegister = getPhysicalRegister((*RIter)->getRegNum()); 1660 Type RegType;
1661 if (RegMIPS32::isFPRReg((*RIter)->getRegNum()))
1662 RegType = IceType_f32;
1663 else
1664 RegType = IceType_i32;
1665 auto *PhysicalRegister = makeReg(RegType, (*RIter)->getRegNum());
1656 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP); 1666 Variable *SP = getPhysicalRegister(RegMIPS32::Reg_SP);
1657 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create( 1667 OperandMIPS32Mem *MemoryLocation = OperandMIPS32Mem::create(
1658 Func, IceType_i32, SP, 1668 Func, RegType, SP,
1659 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset))); 1669 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(StackOffset)));
1660 _lw(PhysicalRegister, MemoryLocation); 1670 _lw(PhysicalRegister, MemoryLocation);
1661 StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType()); 1671 StackOffset += typeWidthInBytesOnStack(PhysicalRegister->getType());
1662 } 1672 }
1663 } 1673 }
1664 1674
1665 if (TotalStackSizeBytes) { 1675 if (TotalStackSizeBytes) {
1666 Sandboxer(this).addiu_sp(TotalStackSizeBytes); 1676 Sandboxer(this).addiu_sp(TotalStackSizeBytes);
1667 } 1677 }
1668 if (!getFlags().getUseSandboxing()) 1678 if (!getFlags().getUseSandboxing())
(...skipping 27 matching lines...) Expand all
1696 Target->_ori(ScratchReg, ScratchReg, LowerBits); 1706 Target->_ori(ScratchReg, ScratchReg, LowerBits);
1697 Target->_addu(ScratchReg, ScratchReg, Base); 1707 Target->_addu(ScratchReg, ScratchReg, Base);
1698 } else { 1708 } else {
1699 Target->_addiu(ScratchReg, Base, Offset); 1709 Target->_addiu(ScratchReg, Base, Offset);
1700 } 1710 }
1701 } 1711 }
1702 1712
1703 return ScratchReg; 1713 return ScratchReg;
1704 } 1714 }
1705 1715
1716 void TargetMIPS32::PostLoweringLegalizer::legalizeMovFp(
1717 InstMIPS32MovFP64ToI64 *MovInstr) {
1718 Variable *Dest = MovInstr->getDest();
1719 Operand *Src = MovInstr->getSrc(0);
1720 const Type SrcTy = Src->getType();
1721
1722 if (Dest != nullptr && SrcTy == IceType_f64) {
1723 int32_t Offset = Dest->getStackOffset();
1724 auto *Base = Target->getPhysicalRegister(Target->getFrameOrStackReg());
1725 OperandMIPS32Mem *TAddr = OperandMIPS32Mem::create(
1726 Target->Func, IceType_f32, Base,
1727 llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
1728 OperandMIPS32Mem *Addr = legalizeMemOperand(TAddr);
1729 auto *SrcV = llvm::cast<Variable>(Src);
1730 Variable *SrcR;
1731 if (MovInstr->getInt64Part() == Int64_Lo) {
1732 SrcR = Target->makeReg(
1733 IceType_f32, RegMIPS32::get64PairFirstRegNum(SrcV->getRegNum()));
1734 } else {
1735 SrcR = Target->makeReg(
1736 IceType_f32, RegMIPS32::get64PairSecondRegNum(SrcV->getRegNum()));
1737 }
1738 Sandboxer(Target).sw(SrcR, Addr);
1739 if (MovInstr->isDestRedefined()) {
1740 Target->_set_dest_redefined();
1741 }
1742 MovInstr->setDeleted();
1743 return;
1744 }
1745
1746 llvm::report_fatal_error("legalizeMovFp: Invalid operands");
1747 }
1748
1706 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) { 1749 void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
1707 Variable *Dest = MovInstr->getDest(); 1750 Variable *Dest = MovInstr->getDest();
1708 assert(Dest != nullptr); 1751 assert(Dest != nullptr);
1709 const Type DestTy = Dest->getType(); 1752 const Type DestTy = Dest->getType();
1710 assert(DestTy != IceType_i64); 1753 assert(DestTy != IceType_i64);
1711 1754
1712 Operand *Src = MovInstr->getSrc(0); 1755 Operand *Src = MovInstr->getSrc(0);
1713 const Type SrcTy = Src->getType(); 1756 const Type SrcTy = Src->getType();
1714 (void)SrcTy; 1757 (void)SrcTy;
1715 assert(SrcTy != IceType_i64); 1758 assert(SrcTy != IceType_i64);
(...skipping 24 matching lines...) Expand all
1740 if (MovInstr->getDestHi() != nullptr && Dest != nullptr) { 1783 if (MovInstr->getDestHi() != nullptr && Dest != nullptr) {
1741 DstFPRHi = Target->makeReg(IceType_i32, 1784 DstFPRHi = Target->makeReg(IceType_i32,
1742 MovInstr->getDestHi()->getRegNum()); 1785 MovInstr->getDestHi()->getRegNum());
1743 DstFPRLo = Target->makeReg(IceType_i32, Dest->getRegNum()); 1786 DstFPRLo = Target->makeReg(IceType_i32, Dest->getRegNum());
1744 } else { 1787 } else {
1745 DstFPRHi = Target->makeReg( 1788 DstFPRHi = Target->makeReg(
1746 IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum)); 1789 IceType_i32, RegMIPS32::get64PairFirstRegNum(DRegNum));
1747 DstFPRLo = Target->makeReg( 1790 DstFPRLo = Target->makeReg(
1748 IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum)); 1791 IceType_i32, RegMIPS32::get64PairSecondRegNum(DRegNum));
1749 } 1792 }
1750 Target->_mov(DstFPRHi, SrcGPRLo); 1793 Target->_mov(DstFPRHi, SrcGPRHi);
1751 Target->_mov(DstFPRLo, SrcGPRHi); 1794 Target->_mov(DstFPRLo, SrcGPRLo);
1752 Legalized = true; 1795 Legalized = true;
1753 } else { 1796 } else {
1754 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum); 1797 Variable *SrcGPR = Target->makeReg(IceType_f32, SRegNum);
1755 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum); 1798 Variable *DstFPR = Target->makeReg(IceType_i32, DRegNum);
1756 Target->_mov(DstFPR, SrcGPR); 1799 Target->_mov(DstFPR, SrcGPR);
1757 Legalized = true; 1800 Legalized = true;
1758 } 1801 }
1759 } else { 1802 } else {
1760 // Dest is FPR and SrcR is GPR. Use mtc1. 1803 // Dest is FPR and SrcR is GPR. Use mtc1.
1761 if (typeWidthInBytes(Dest->getType()) == 8) { 1804 if (typeWidthInBytes(Dest->getType()) == 8) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1853 } 1896 }
1854 1897
1855 Target->Context.insert<InstFakeDef>(Dest); 1898 Target->Context.insert<InstFakeDef>(Dest);
1856 Legalized = true; 1899 Legalized = true;
1857 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { 1900 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) {
1858 if (Var->isRematerializable()) { 1901 if (Var->isRematerializable()) {
1859 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). 1902 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable).
1860 1903
1861 // ExtraOffset is only needed for stack-pointer based frames as we have 1904 // ExtraOffset is only needed for stack-pointer based frames as we have
1862 // to account for spill storage. 1905 // to account for spill storage.
1863 const int32_t ExtraOffset = (Var->getRegNum() == Target->getStackReg()) 1906 const int32_t ExtraOffset =
1864 ? Target->getFrameFixedAllocaOffset() 1907 (Var->getRegNum() == Target->getFrameOrStackReg())
1865 : 0; 1908 ? Target->getFrameFixedAllocaOffset()
1909 : 0;
1866 1910
1867 const int32_t Offset = Var->getStackOffset() + ExtraOffset; 1911 const int32_t Offset = Var->getStackOffset() + ExtraOffset;
1868 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); 1912 Variable *Base = Target->getPhysicalRegister(Var->getRegNum());
1869 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); 1913 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum());
1870 Target->_mov(Dest, T); 1914 Target->_mov(Dest, T);
1871 Legalized = true; 1915 Legalized = true;
1872 } else { 1916 } else {
1873 if (!Var->hasReg()) { 1917 if (!Var->hasReg()) {
1874 // This is a _mov(Variable, Mem()), i.e., a load. 1918 // This is a _mov(Variable, Mem()), i.e., a load.
1875 const int32_t Offset = Var->getStackOffset(); 1919 const int32_t Offset = Var->getStackOffset();
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
2011 Operand *Src0 = NumSrcs < 1 ? nullptr : CurInstr->getSrc(0); 2055 Operand *Src0 = NumSrcs < 1 ? nullptr : CurInstr->getSrc(0);
2012 Operand *Src1 = NumSrcs < 2 ? nullptr : CurInstr->getSrc(1); 2056 Operand *Src1 = NumSrcs < 2 ? nullptr : CurInstr->getSrc(1);
2013 auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0); 2057 auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0);
2014 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0); 2058 auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0);
2015 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1); 2059 auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1);
2016 Variable *Dst = CurInstr->getDest(); 2060 Variable *Dst = CurInstr->getDest();
2017 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) { 2061 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) {
2018 Legalizer.legalizeMov(MovInstr); 2062 Legalizer.legalizeMov(MovInstr);
2019 continue; 2063 continue;
2020 } 2064 }
2065 if (auto *MovInstr = llvm::dyn_cast<InstMIPS32MovFP64ToI64>(CurInstr)) {
2066 Legalizer.legalizeMovFp(MovInstr);
2067 continue;
2068 }
2021 if (llvm::isa<InstMIPS32Sw>(CurInstr)) { 2069 if (llvm::isa<InstMIPS32Sw>(CurInstr)) {
2022 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { 2070 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
2023 Sandboxer(this).sw(Src0V, LegalMem); 2071 Sandboxer(this).sw(Src0V, LegalMem);
2024 CurInstr->setDeleted(); 2072 CurInstr->setDeleted();
2025 } 2073 }
2026 continue; 2074 continue;
2027 } 2075 }
2028 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) { 2076 if (llvm::isa<InstMIPS32Swc1>(CurInstr)) {
2029 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) { 2077 if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
2030 _swc1(Src0V, LegalMem); 2078 _swc1(Src0V, LegalMem);
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after
2601 } 2649 }
2602 2650
2603 Variable *T = makeReg(Dest->getType()); 2651 Variable *T = makeReg(Dest->getType());
2604 Variable *Src0R = legalizeToReg(Src0); 2652 Variable *Src0R = legalizeToReg(Src0);
2605 Variable *Src1R = nullptr; 2653 Variable *Src1R = nullptr;
2606 uint32_t Value = 0; 2654 uint32_t Value = 0;
2607 bool IsSrc1Imm16 = false; 2655 bool IsSrc1Imm16 = false;
2608 2656
2609 switch (Instr->getOp()) { 2657 switch (Instr->getOp()) {
2610 case InstArithmetic::Add: 2658 case InstArithmetic::Add:
2611 case InstArithmetic::And: 2659 case InstArithmetic::Sub: {
2612 case InstArithmetic::Or:
2613 case InstArithmetic::Xor:
2614 case InstArithmetic::Sub:
2615 case InstArithmetic::Shl:
2616 case InstArithmetic::Lshr:
2617 case InstArithmetic::Ashr: {
2618 auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1); 2660 auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1);
2619 if (Const32 != nullptr && isInt<16>(int32_t(Const32->getValue()))) { 2661 if (Const32 != nullptr && isInt<16>(int32_t(Const32->getValue()))) {
2620 IsSrc1Imm16 = true; 2662 IsSrc1Imm16 = true;
2621 Value = Const32->getValue(); 2663 Value = Const32->getValue();
2622 } else { 2664 } else {
2665 Src1R = legalizeToReg(Src1);
2666 }
2667 break;
2668 }
2669 case InstArithmetic::And:
2670 case InstArithmetic::Or:
2671 case InstArithmetic::Xor:
2672 case InstArithmetic::Shl:
2673 case InstArithmetic::Lshr:
2674 case InstArithmetic::Ashr: {
2675 auto *Const32 = llvm::dyn_cast<ConstantInteger32>(Src1);
2676 if (Const32 != nullptr && llvm::isUInt<16>(uint32_t(Const32->getValue()))) {
2677 IsSrc1Imm16 = true;
2678 Value = Const32->getValue();
2679 } else {
2623 Src1R = legalizeToReg(Src1); 2680 Src1R = legalizeToReg(Src1);
2624 } 2681 }
2625 break; 2682 break;
2626 } 2683 }
2627 default: 2684 default:
2628 Src1R = legalizeToReg(Src1); 2685 Src1R = legalizeToReg(Src1);
2629 break; 2686 break;
2630 } 2687 }
2631 constexpr uint32_t DivideByZeroTrapCode = 7; 2688 constexpr uint32_t DivideByZeroTrapCode = 7;
2632 2689
2633 switch (Instr->getOp()) { 2690 switch (Instr->getOp()) {
2634 case InstArithmetic::_num: 2691 case InstArithmetic::_num:
2635 break; 2692 break;
2636 case InstArithmetic::Add: 2693 case InstArithmetic::Add: {
2694 auto *T0R = Src0R;
2695 auto *T1R = Src1R;
2696 if (Dest->getType() != IceType_i32) {
2697 T0R = makeReg(IceType_i32);
2698 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
2699 if (!IsSrc1Imm16) {
2700 T1R = makeReg(IceType_i32);
2701 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
2702 }
2703 }
2637 if (IsSrc1Imm16) { 2704 if (IsSrc1Imm16) {
2638 _addiu(T, Src0R, Value); 2705 _addiu(T, T0R, Value);
2639 } else { 2706 } else {
2640 _addu(T, Src0R, Src1R); 2707 _addu(T, T0R, T1R);
2641 } 2708 }
2642 _mov(Dest, T); 2709 _mov(Dest, T);
2643 return; 2710 return;
2711 }
2644 case InstArithmetic::And: 2712 case InstArithmetic::And:
2645 if (IsSrc1Imm16) { 2713 if (IsSrc1Imm16) {
2646 _andi(T, Src0R, Value); 2714 _andi(T, Src0R, Value);
2647 } else { 2715 } else {
2648 _and(T, Src0R, Src1R); 2716 _and(T, Src0R, Src1R);
2649 } 2717 }
2650 _mov(Dest, T); 2718 _mov(Dest, T);
2651 return; 2719 return;
2652 case InstArithmetic::Or: 2720 case InstArithmetic::Or:
2653 if (IsSrc1Imm16) { 2721 if (IsSrc1Imm16) {
2654 _ori(T, Src0R, Value); 2722 _ori(T, Src0R, Value);
2655 } else { 2723 } else {
2656 _or(T, Src0R, Src1R); 2724 _or(T, Src0R, Src1R);
2657 } 2725 }
2658 _mov(Dest, T); 2726 _mov(Dest, T);
2659 return; 2727 return;
2660 case InstArithmetic::Xor: 2728 case InstArithmetic::Xor:
2661 if (IsSrc1Imm16) { 2729 if (IsSrc1Imm16) {
2662 _xori(T, Src0R, Value); 2730 _xori(T, Src0R, Value);
2663 } else { 2731 } else {
2664 _xor(T, Src0R, Src1R); 2732 _xor(T, Src0R, Src1R);
2665 } 2733 }
2666 _mov(Dest, T); 2734 _mov(Dest, T);
2667 return; 2735 return;
2668 case InstArithmetic::Sub: 2736 case InstArithmetic::Sub: {
2737 auto *T0R = Src0R;
2738 auto *T1R = Src1R;
2739 if (Dest->getType() != IceType_i32) {
2740 T0R = makeReg(IceType_i32);
2741 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
2742 if (!IsSrc1Imm16) {
2743 T1R = makeReg(IceType_i32);
2744 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
2745 }
2746 }
2669 if (IsSrc1Imm16) { 2747 if (IsSrc1Imm16) {
2670 _addiu(T, Src0R, -Value); 2748 _addiu(T, T0R, -Value);
2671 } else { 2749 } else {
2672 _subu(T, Src0R, Src1R); 2750 _subu(T, T0R, T1R);
2673 } 2751 }
2674 _mov(Dest, T); 2752 _mov(Dest, T);
2675 return; 2753 return;
2754 }
2676 case InstArithmetic::Mul: { 2755 case InstArithmetic::Mul: {
2677 _mul(T, Src0R, Src1R); 2756 _mul(T, Src0R, Src1R);
2678 _mov(Dest, T); 2757 _mov(Dest, T);
2679 return; 2758 return;
2680 } 2759 }
2681 case InstArithmetic::Shl: { 2760 case InstArithmetic::Shl: {
2682 if (IsSrc1Imm16) { 2761 if (IsSrc1Imm16) {
2683 _sll(T, Src0R, Value); 2762 _sll(T, Src0R, Value);
2684 } else { 2763 } else {
2685 _sllv(T, Src0R, Src1R); 2764 _sllv(T, Src0R, Src1R);
(...skipping 14 matching lines...) Expand all
2700 } 2779 }
2701 if (IsSrc1Imm16) { 2780 if (IsSrc1Imm16) {
2702 _srl(T, T0R, Value); 2781 _srl(T, T0R, Value);
2703 } else { 2782 } else {
2704 _srlv(T, T0R, T1R); 2783 _srlv(T, T0R, T1R);
2705 } 2784 }
2706 _mov(Dest, T); 2785 _mov(Dest, T);
2707 return; 2786 return;
2708 } 2787 }
2709 case InstArithmetic::Ashr: { 2788 case InstArithmetic::Ashr: {
2789 auto *T0R = Src0R;
2790 auto *T1R = Src1R;
2791 if (Dest->getType() != IceType_i32) {
2792 T0R = makeReg(IceType_i32);
2793 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
2794 if (!IsSrc1Imm16) {
2795 T1R = makeReg(IceType_i32);
2796 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
2797 }
2798 }
2710 if (IsSrc1Imm16) { 2799 if (IsSrc1Imm16) {
2711 _sra(T, Src0R, Value); 2800 _sra(T, T0R, Value);
2712 } else { 2801 } else {
2713 _srav(T, Src0R, Src1R); 2802 _srav(T, T0R, T1R);
2714 } 2803 }
2715 _mov(Dest, T); 2804 _mov(Dest, T);
2716 return; 2805 return;
2717 } 2806 }
2718 case InstArithmetic::Udiv: { 2807 case InstArithmetic::Udiv: {
2719 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); 2808 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
2720 auto *T0R = Src0R; 2809 auto *T0R = Src0R;
2721 auto *T1R = Src1R; 2810 auto *T1R = Src1R;
2722 if (Dest->getType() != IceType_i32) { 2811 if (Dest->getType() != IceType_i32) {
2723 T0R = makeReg(IceType_i32); 2812 T0R = makeReg(IceType_i32);
2724 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); 2813 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
2725 T1R = makeReg(IceType_i32); 2814 T1R = makeReg(IceType_i32);
2726 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); 2815 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R));
2727 } 2816 }
2728 _divu(T_Zero, T0R, T1R); 2817 _divu(T_Zero, T0R, T1R);
2729 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero 2818 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
2730 _mflo(T, T_Zero); 2819 _mflo(T, T_Zero);
2731 _mov(Dest, T); 2820 _mov(Dest, T);
2732 return; 2821 return;
2733 } 2822 }
2734 case InstArithmetic::Sdiv: { 2823 case InstArithmetic::Sdiv: {
2735 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); 2824 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
2736 _div(T_Zero, Src0R, Src1R); 2825 auto *T0R = Src0R;
2737 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero 2826 auto *T1R = Src1R;
2827 if (Dest->getType() != IceType_i32) {
2828 T0R = makeReg(IceType_i32);
2829 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
2830 T1R = makeReg(IceType_i32);
2831 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
2832 }
2833 _div(T_Zero, T0R, T1R);
2834 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
2738 _mflo(T, T_Zero); 2835 _mflo(T, T_Zero);
2739 _mov(Dest, T); 2836 _mov(Dest, T);
2740 return; 2837 return;
2741 } 2838 }
2742 case InstArithmetic::Urem: { 2839 case InstArithmetic::Urem: {
2743 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); 2840 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
2744 auto *T0R = Src0R; 2841 auto *T0R = Src0R;
2745 auto *T1R = Src1R; 2842 auto *T1R = Src1R;
2746 if (Dest->getType() != IceType_i32) { 2843 if (Dest->getType() != IceType_i32) {
2747 T0R = makeReg(IceType_i32); 2844 T0R = makeReg(IceType_i32);
2748 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); 2845 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
2749 T1R = makeReg(IceType_i32); 2846 T1R = makeReg(IceType_i32);
2750 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R)); 2847 lowerCast(InstCast::create(Func, InstCast::Zext, T1R, Src1R));
2751 } 2848 }
2752 _divu(T_Zero, T0R, T1R); 2849 _divu(T_Zero, T0R, T1R);
2753 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero 2850 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
2754 _mfhi(T, T_Zero); 2851 _mfhi(T, T_Zero);
2755 _mov(Dest, T); 2852 _mov(Dest, T);
2756 return; 2853 return;
2757 } 2854 }
2758 case InstArithmetic::Srem: { 2855 case InstArithmetic::Srem: {
2759 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO); 2856 auto *T_Zero = I32Reg(RegMIPS32::Reg_ZERO);
2760 _div(T_Zero, Src0R, Src1R); 2857 auto *T0R = Src0R;
2761 _teq(Src1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero 2858 auto *T1R = Src1R;
2859 if (Dest->getType() != IceType_i32) {
2860 T0R = makeReg(IceType_i32);
2861 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
2862 T1R = makeReg(IceType_i32);
2863 lowerCast(InstCast::create(Func, InstCast::Sext, T1R, Src1R));
2864 }
2865 _div(T_Zero, T0R, T1R);
2866 _teq(T1R, T_Zero, DivideByZeroTrapCode); // Trap if divide-by-zero
2762 _mfhi(T, T_Zero); 2867 _mfhi(T, T_Zero);
2763 _mov(Dest, T); 2868 _mov(Dest, T);
2764 return; 2869 return;
2765 } 2870 }
2766 case InstArithmetic::Fadd: { 2871 case InstArithmetic::Fadd: {
2767 if (DestTy == IceType_f32) { 2872 if (DestTy == IceType_f32) {
2768 _add_s(T, Src0R, Src1R); 2873 _add_s(T, Src0R, Src1R);
2769 _mov(Dest, T); 2874 _mov(Dest, T);
2770 return; 2875 return;
2771 } 2876 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2898 Variable *Src0R = nullptr; 3003 Variable *Src0R = nullptr;
2899 Variable *Src1R = nullptr; 3004 Variable *Src1R = nullptr;
2900 Variable *Src0HiR = nullptr; 3005 Variable *Src0HiR = nullptr;
2901 Variable *Src1HiR = nullptr; 3006 Variable *Src1HiR = nullptr;
2902 if (Src0Ty == IceType_i64) { 3007 if (Src0Ty == IceType_i64) {
2903 Src0R = legalizeToReg(loOperand(Src0)); 3008 Src0R = legalizeToReg(loOperand(Src0));
2904 Src1R = legalizeToReg(loOperand(Src1)); 3009 Src1R = legalizeToReg(loOperand(Src1));
2905 Src0HiR = legalizeToReg(hiOperand(Src0)); 3010 Src0HiR = legalizeToReg(hiOperand(Src0));
2906 Src1HiR = legalizeToReg(hiOperand(Src1)); 3011 Src1HiR = legalizeToReg(hiOperand(Src1));
2907 } else { 3012 } else {
2908 Src0R = legalizeToReg(Src0); 3013 auto *Src0RT = legalizeToReg(Src0);
2909 Src1R = legalizeToReg(Src1); 3014 auto *Src1RT = legalizeToReg(Src1);
3015 // Sign/Zero extend the source operands
3016 if (Src0Ty != IceType_i32) {
3017 InstCast::OpKind CastKind;
3018 switch (CompareInst->getCondition()) {
3019 case InstIcmp::Eq:
3020 case InstIcmp::Ne:
3021 case InstIcmp::Sgt:
3022 case InstIcmp::Sge:
3023 case InstIcmp::Slt:
3024 case InstIcmp::Sle:
3025 CastKind = InstCast::Sext;
3026 break;
3027 default:
3028 CastKind = InstCast::Zext;
3029 break;
3030 }
3031 Src0R = makeReg(IceType_i32);
3032 Src1R = makeReg(IceType_i32);
3033 lowerCast(InstCast::create(Func, CastKind, Src0R, Src0RT));
3034 lowerCast(InstCast::create(Func, CastKind, Src1R, Src1RT));
3035 } else {
3036 Src0R = Src0RT;
3037 Src1R = Src1RT;
3038 }
2910 } 3039 }
2911 auto *DestT = makeReg(IceType_i32); 3040 auto *DestT = makeReg(IceType_i32);
2912 3041
2913 switch (CompareInst->getCondition()) { 3042 switch (CompareInst->getCondition()) {
2914 default: 3043 default:
2915 llvm_unreachable("unexpected condition"); 3044 llvm_unreachable("unexpected condition");
2916 return; 3045 return;
2917 case InstIcmp::Eq: { 3046 case InstIcmp::Eq: {
2918 if (Src0Ty == IceType_i64) { 3047 if (Src0Ty == IceType_i64) {
2919 auto *T1 = I32Reg(); 3048 auto *T1 = I32Reg();
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
3137 Operand *Arg = legalizeUndef(Instr->getArg(i)); 3266 Operand *Arg = legalizeUndef(Instr->getArg(i));
3138 const Type Ty = Arg->getType(); 3267 const Type Ty = Arg->getType();
3139 bool InReg = false; 3268 bool InReg = false;
3140 RegNumT Reg; 3269 RegNumT Reg;
3141 3270
3142 InReg = CC.argInReg(Ty, i, &Reg); 3271 InReg = CC.argInReg(Ty, i, &Reg);
3143 3272
3144 if (!InReg) { 3273 if (!InReg) {
3145 if (isVectorType(Ty)) { 3274 if (isVectorType(Ty)) {
3146 auto *ArgVec = llvm::cast<VariableVecOn32>(Arg); 3275 auto *ArgVec = llvm::cast<VariableVecOn32>(Arg);
3276 ParameterAreaSizeBytes =
3277 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i64);
3147 for (Variable *Elem : ArgVec->getContainers()) { 3278 for (Variable *Elem : ArgVec->getContainers()) {
3148 ParameterAreaSizeBytes =
3149 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32);
3150 StackArgs.push_back(std::make_pair(Elem, ParameterAreaSizeBytes)); 3279 StackArgs.push_back(std::make_pair(Elem, ParameterAreaSizeBytes));
3151 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); 3280 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
3152 } 3281 }
3153 } else { 3282 } else {
3154 ParameterAreaSizeBytes = 3283 ParameterAreaSizeBytes =
3155 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); 3284 applyStackAlignmentTy(ParameterAreaSizeBytes, Ty);
3156 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); 3285 StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes));
3157 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); 3286 ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty);
3158 } 3287 }
3159 ++ArgNum; 3288 ++ArgNum;
(...skipping 12 matching lines...) Expand all
3172 Operand *Elem3 = ArgVec->getContainers()[3]; 3301 Operand *Elem3 = ArgVec->getContainers()[3];
3173 // First argument is passed in $4:$5:$6:$7 3302 // First argument is passed in $4:$5:$6:$7
3174 // Second and rest arguments are passed in $6:$7:stack:stack 3303 // Second and rest arguments are passed in $6:$7:stack:stack
3175 if (ArgNum == 0) { 3304 if (ArgNum == 0) {
3176 GPRArgs.push_back( 3305 GPRArgs.push_back(
3177 std::make_pair(Elem2, RegNumT::fixme((unsigned)Reg + 2))); 3306 std::make_pair(Elem2, RegNumT::fixme((unsigned)Reg + 2)));
3178 GPRArgs.push_back( 3307 GPRArgs.push_back(
3179 std::make_pair(Elem3, RegNumT::fixme((unsigned)Reg + 3))); 3308 std::make_pair(Elem3, RegNumT::fixme((unsigned)Reg + 3)));
3180 } else { 3309 } else {
3181 ParameterAreaSizeBytes = 3310 ParameterAreaSizeBytes =
3182 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32); 3311 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i64);
3183 StackArgs.push_back(std::make_pair(Elem2, ParameterAreaSizeBytes)); 3312 StackArgs.push_back(std::make_pair(Elem2, ParameterAreaSizeBytes));
3184 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); 3313 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
3185 ParameterAreaSizeBytes =
3186 applyStackAlignmentTy(ParameterAreaSizeBytes, IceType_i32);
3187 StackArgs.push_back(std::make_pair(Elem3, ParameterAreaSizeBytes)); 3314 StackArgs.push_back(std::make_pair(Elem3, ParameterAreaSizeBytes));
3188 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32); 3315 ParameterAreaSizeBytes += typeWidthInBytesOnStack(IceType_i32);
3189 } 3316 }
3190 } else if (Ty == IceType_i64) { 3317 } else if (Ty == IceType_i64) {
3191 Operand *Lo = loOperand(Arg); 3318 Operand *Lo = loOperand(Arg);
3192 Operand *Hi = hiOperand(Arg); 3319 Operand *Hi = hiOperand(Arg);
3193 GPRArgs.push_back( 3320 GPRArgs.push_back(
3194 std::make_pair(Lo, RegMIPS32::get64PairFirstRegNum(Reg))); 3321 std::make_pair(Lo, RegMIPS32::get64PairFirstRegNum(Reg)));
3195 GPRArgs.push_back( 3322 GPRArgs.push_back(
3196 std::make_pair(Hi, RegMIPS32::get64PairSecondRegNum(Reg))); 3323 std::make_pair(Hi, RegMIPS32::get64PairSecondRegNum(Reg)));
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
3477 _mov(Dest, T); 3604 _mov(Dest, T);
3478 } 3605 }
3479 } 3606 }
3480 break; 3607 break;
3481 } 3608 }
3482 case InstCast::Trunc: { 3609 case InstCast::Trunc: {
3483 if (Src0Ty == IceType_i64) 3610 if (Src0Ty == IceType_i64)
3484 Src0 = loOperand(Src0); 3611 Src0 = loOperand(Src0);
3485 Variable *Src0R = legalizeToReg(Src0); 3612 Variable *Src0R = legalizeToReg(Src0);
3486 Variable *T = makeReg(DestTy); 3613 Variable *T = makeReg(DestTy);
3487 _mov(T, Src0R); 3614 switch (DestTy) {
3615 case IceType_i1:
3616 _andi(T, Src0R, 0x1);
3617 break;
3618 case IceType_i8:
3619 _andi(T, Src0R, 0xff);
3620 break;
3621 case IceType_i16:
3622 _andi(T, Src0R, 0xffff);
3623 break;
3624 default:
3625 _mov(T, Src0R);
3626 break;
3627 }
3488 _mov(Dest, T); 3628 _mov(Dest, T);
3489 break; 3629 break;
3490 } 3630 }
3491 case InstCast::Fptrunc: { 3631 case InstCast::Fptrunc: {
3492 assert(Dest->getType() == IceType_f32); 3632 assert(Dest->getType() == IceType_f32);
3493 assert(Src0->getType() == IceType_f64); 3633 assert(Src0->getType() == IceType_f64);
3494 auto *DestR = legalizeToReg(Dest); 3634 auto *DestR = legalizeToReg(Dest);
3495 auto *Src0R = legalizeToReg(Src0); 3635 auto *Src0R = legalizeToReg(Src0);
3496 _cvt_s_d(DestR, Src0R); 3636 _cvt_s_d(DestR, Src0R);
3497 _mov(Dest, DestR); 3637 _mov(Dest, DestR);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3533 } 3673 }
3534 case InstCast::Sitofp: 3674 case InstCast::Sitofp:
3535 case InstCast::Uitofp: { 3675 case InstCast::Uitofp: {
3536 if (llvm::isa<Variable64On32>(Dest)) { 3676 if (llvm::isa<Variable64On32>(Dest)) {
3537 llvm::report_fatal_error("i64-to-fp should have been prelowered."); 3677 llvm::report_fatal_error("i64-to-fp should have been prelowered.");
3538 return; 3678 return;
3539 } 3679 }
3540 if (Src0Ty != IceType_i64) { 3680 if (Src0Ty != IceType_i64) {
3541 Variable *Src0R = legalizeToReg(Src0); 3681 Variable *Src0R = legalizeToReg(Src0);
3542 auto *T0R = Src0R; 3682 auto *T0R = Src0R;
3543 if (Src0Ty != IceType_i32 && CastKind == InstCast::Uitofp) { 3683 if (Src0Ty != IceType_i32) {
3544 T0R = makeReg(IceType_i32); 3684 T0R = makeReg(IceType_i32);
3545 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R)); 3685 if (CastKind == InstCast::Uitofp)
3686 lowerCast(InstCast::create(Func, InstCast::Zext, T0R, Src0R));
3687 else
3688 lowerCast(InstCast::create(Func, InstCast::Sext, T0R, Src0R));
3546 } 3689 }
3547 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) { 3690 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f32) {
3548 Variable *FTmp1 = makeReg(IceType_f32); 3691 Variable *FTmp1 = makeReg(IceType_f32);
3549 Variable *FTmp2 = makeReg(IceType_f32); 3692 Variable *FTmp2 = makeReg(IceType_f32);
3550 _mtc1(FTmp1, T0R); 3693 _mtc1(FTmp1, T0R);
3551 _cvt_s_w(FTmp2, FTmp1); 3694 _cvt_s_w(FTmp2, FTmp1);
3552 _mov(Dest, FTmp2); 3695 _mov(Dest, FTmp2);
3553 return; 3696 return;
3554 } 3697 }
3555 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) { 3698 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3597 case IceType_f32: { 3740 case IceType_f32: {
3598 Variable *Src0R = legalizeToReg(Src0); 3741 Variable *Src0R = legalizeToReg(Src0);
3599 _mov(Dest, Src0R); 3742 _mov(Dest, Src0R);
3600 break; 3743 break;
3601 } 3744 }
3602 case IceType_i64: { 3745 case IceType_i64: {
3603 assert(Src0->getType() == IceType_f64); 3746 assert(Src0->getType() == IceType_f64);
3604 Variable *Src0R = legalizeToReg(Src0); 3747 Variable *Src0R = legalizeToReg(Src0);
3605 auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64)); 3748 auto *T = llvm::cast<Variable64On32>(Func->makeVariable(IceType_i64));
3606 T->initHiLo(Func); 3749 T->initHiLo(Func);
3607 T->getHi()->setMustHaveReg(); 3750 T->getHi()->setMustNotHaveReg();
3608 T->getLo()->setMustHaveReg(); 3751 T->getLo()->setMustNotHaveReg();
3609 _mov(T, Src0R); 3752 Context.insert<InstFakeDef>(T->getHi());
3753 Context.insert<InstFakeDef>(T->getLo());
3754 _mov_fp64_to_i64(T->getHi(), Src0R, Int64_Hi);
3755 _mov_fp64_to_i64(T->getLo(), Src0R, Int64_Lo);
3610 lowerAssign(InstAssign::create(Func, Dest, T)); 3756 lowerAssign(InstAssign::create(Func, Dest, T));
3611 break; 3757 break;
3612 } 3758 }
3613 case IceType_f64: { 3759 case IceType_f64: {
3614 assert(Src0->getType() == IceType_i64); 3760 assert(Src0->getType() == IceType_i64);
3615 const uint32_t Mask = 0xFFFFFFFF; 3761 const uint32_t Mask = 0xFFFFFFFF;
3616 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) { 3762 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Src0)) {
3617 Variable *RegHi, *RegLo; 3763 Variable *RegHi, *RegLo;
3618 const uint64_t Value = C64->getValue(); 3764 const uint64_t Value = C64->getValue();
3619 uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask; 3765 uint64_t Upper32Bits = (Value >> INT32_BITS) & Mask;
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
4171 auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest); 4317 auto *VDest = llvm::dyn_cast<VariableVecOn32>(Dest);
4172 VDest->initVecElement(Func); 4318 VDest->initVecElement(Func);
4173 // Temp vector variable 4319 // Temp vector variable
4174 auto *TDest = makeReg(DestTy); 4320 auto *TDest = makeReg(DestTy);
4175 auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest); 4321 auto *TVDest = llvm::dyn_cast<VariableVecOn32>(TDest);
4176 TVDest->initVecElement(Func); 4322 TVDest->initVecElement(Func);
4177 // Destination element 4323 // Destination element
4178 auto *DstE = TVDest->getContainers()[Index / ElemPerCont]; 4324 auto *DstE = TVDest->getContainers()[Index / ElemPerCont];
4179 // Element to insert 4325 // Element to insert
4180 auto *Src1R = legalizeToReg(Instr->getSrc(1)); 4326 auto *Src1R = legalizeToReg(Instr->getSrc(1));
4181 auto *TReg1 = makeReg(Src1R->getType()); 4327 auto *TReg1 = makeReg(IceType_i32);
4182 auto *TReg2 = makeReg(Src1R->getType()); 4328 auto *TReg2 = makeReg(IceType_i32);
4183 auto *TReg3 = makeReg(Src1R->getType()); 4329 auto *TReg3 = makeReg(IceType_i32);
4184 auto *TReg4 = makeReg(Src1R->getType()); 4330 auto *TReg4 = makeReg(IceType_i32);
4185 auto *TReg5 = makeReg(Src1R->getType()); 4331 auto *TReg5 = makeReg(IceType_i32);
4186 auto *TDReg = makeReg(Src1R->getType()); 4332 auto *TDReg = makeReg(IceType_i32);
4187 // Position of the element in the container 4333 // Position of the element in the container
4188 uint32_t PosInCont = Index % ElemPerCont; 4334 uint32_t PosInCont = Index % ElemPerCont;
4189 // Load source vector in a temporary vector 4335 // Load source vector in a temporary vector
4190 for (SizeT i = 0; i < TVDest->ContainersPerVector; ++i) { 4336 for (SizeT i = 0; i < TVDest->ContainersPerVector; ++i) {
4191 auto *DCont = TVDest->getContainers()[i]; 4337 auto *DCont = TVDest->getContainers()[i];
4192 // Do not define DstE as we are going to redefine it 4338 // Do not define DstE as we are going to redefine it
4193 if (DCont == DstE) 4339 if (DCont == DstE)
4194 continue; 4340 continue;
4195 auto *SCont = Src0R->getContainers()[i]; 4341 auto *SCont = Src0R->getContainers()[i];
4196 auto *TReg = makeReg(IceType_i32); 4342 auto *TReg = makeReg(IceType_i32);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4241 case 2: 4387 case 2:
4242 _andi(TReg1, Src1R, 0xff); // Clear bits[31:8] of source 4388 _andi(TReg1, Src1R, 0xff); // Clear bits[31:8] of source
4243 _sll(TReg5, TReg1, 16); // Position in the destination 4389 _sll(TReg5, TReg1, 16); // Position in the destination
4244 _lui(TReg2, Ctx->getConstantInt32(0xff00)); 4390 _lui(TReg2, Ctx->getConstantInt32(0xff00));
4245 _ori(TReg3, TReg2, 0xffff); 4391 _ori(TReg3, TReg2, 0xffff);
4246 _and(TReg4, SrcE, TReg3); // Clear bits[15:8] of element 4392 _and(TReg4, SrcE, TReg3); // Clear bits[15:8] of element
4247 _or(TDReg, TReg5, TReg4); 4393 _or(TDReg, TReg5, TReg4);
4248 _mov(DstE, TDReg); 4394 _mov(DstE, TDReg);
4249 break; 4395 break;
4250 case 3: 4396 case 3:
4251 _srl(TReg1, Src1R, 24); // Position in the destination 4397 _sll(TReg1, Src1R, 24); // Position in the destination
4252 _sll(TReg2, SrcE, 8); 4398 _sll(TReg2, SrcE, 8);
4253 _srl(TReg3, TReg2, 8); // Clear bits[31:24] of element 4399 _srl(TReg3, TReg2, 8); // Clear bits[31:24] of element
4254 _or(TDReg, TReg1, TReg3); 4400 _or(TDReg, TReg1, TReg3);
4255 _mov(DstE, TDReg); 4401 _mov(DstE, TDReg);
4256 break; 4402 break;
4257 default: 4403 default:
4258 llvm::report_fatal_error("InsertElement: Invalid PosInCont"); 4404 llvm::report_fatal_error("InsertElement: Invalid PosInCont");
4259 break; 4405 break;
4260 } 4406 }
4261 } 4407 }
(...skipping 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after
5722 // Use addiu if the immediate is a 16bit value. Otherwise load it 5868 // Use addiu if the immediate is a 16bit value. Otherwise load it
5723 // using a lui-ori instructions. 5869 // using a lui-ori instructions.
5724 Variable *Reg = makeReg(Ty, RegNum); 5870 Variable *Reg = makeReg(Ty, RegNum);
5725 if (isInt<16>(int32_t(Value))) { 5871 if (isInt<16>(int32_t(Value))) {
5726 Variable *Zero = makeReg(Ty, RegMIPS32::Reg_ZERO); 5872 Variable *Zero = makeReg(Ty, RegMIPS32::Reg_ZERO);
5727 Context.insert<InstFakeDef>(Zero); 5873 Context.insert<InstFakeDef>(Zero);
5728 _addiu(Reg, Zero, Value); 5874 _addiu(Reg, Zero, Value);
5729 } else { 5875 } else {
5730 uint32_t UpperBits = (Value >> 16) & 0xFFFF; 5876 uint32_t UpperBits = (Value >> 16) & 0xFFFF;
5731 uint32_t LowerBits = Value & 0xFFFF; 5877 uint32_t LowerBits = Value & 0xFFFF;
5732 Variable *TReg = makeReg(Ty, RegNum);
5733 if (LowerBits) { 5878 if (LowerBits) {
5879 Variable *TReg = makeReg(Ty, RegNum);
5734 _lui(TReg, Ctx->getConstantInt32(UpperBits)); 5880 _lui(TReg, Ctx->getConstantInt32(UpperBits));
5735 _ori(Reg, TReg, LowerBits); 5881 _ori(Reg, TReg, LowerBits);
5736 } else { 5882 } else {
5737 _lui(Reg, Ctx->getConstantInt32(UpperBits)); 5883 _lui(Reg, Ctx->getConstantInt32(UpperBits));
5738 } 5884 }
5739 } 5885 }
5740 return Reg; 5886 return Reg;
5741 } else if (isScalarFloatingType(Ty)) { 5887 } else if (isScalarFloatingType(Ty)) {
5742 auto *CFrom = llvm::cast<Constant>(From); 5888 auto *CFrom = llvm::cast<Constant>(From);
5743 Variable *TReg = makeReg(Ty); 5889 Variable *TReg = makeReg(Ty);
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
5976 if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) { 6122 if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) {
5977 Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6); 6123 Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6);
5978 Target->_and(CallTargetR, CallTargetR, T6); 6124 Target->_and(CallTargetR, CallTargetR, T6);
5979 } 6125 }
5980 } 6126 }
5981 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); 6127 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget);
5982 } 6128 }
5983 6129
5984 } // end of namespace MIPS32 6130 } // end of namespace MIPS32
5985 } // end of namespace Ice 6131 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringMIPS32.h ('k') | tests_lit/assembler/mips32/encoding_intrinsics.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698