| 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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 return; | 209 return; |
| 210 } | 210 } |
| 211 } | 211 } |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| 215 uint32_t TargetMIPS32::getStackAlignment() const { | 215 uint32_t TargetMIPS32::getStackAlignment() const { |
| 216 return MIPS32_STACK_ALIGNMENT_BYTES; | 216 return MIPS32_STACK_ALIGNMENT_BYTES; |
| 217 } | 217 } |
| 218 | 218 |
| 219 uint32_t TargetMIPS32::getCallStackArgumentsSizeBytes(const InstCall *Call) { |
| 220 TargetMIPS32::CallingConv CC; |
| 221 RegNumT DummyReg; |
| 222 size_t OutArgsSizeBytes = 0; |
| 223 for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { |
| 224 Operand *Arg = legalizeUndef(Call->getArg(i)); |
| 225 const Type Ty = Arg->getType(); |
| 226 RegNumT RegNum; |
| 227 if (CC.argInReg(Ty, i, &RegNum)) { |
| 228 continue; |
| 229 } |
| 230 |
| 231 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty); |
| 232 OutArgsSizeBytes += typeWidthInBytesOnStack(Ty); |
| 233 } |
| 234 |
| 235 return applyStackAlignment(OutArgsSizeBytes); |
| 236 } |
| 237 |
| 219 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { | 238 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { |
| 220 constexpr bool NoTailCall = false; | 239 constexpr bool NoTailCall = false; |
| 221 constexpr bool IsTargetHelperCall = true; | 240 constexpr bool IsTargetHelperCall = true; |
| 222 | 241 |
| 223 switch (Instr->getKind()) { | 242 switch (Instr->getKind()) { |
| 224 default: | 243 default: |
| 225 return; | 244 return; |
| 226 case Inst::Arithmetic: { | 245 case Inst::Arithmetic: { |
| 227 Variable *Dest = Instr->getDest(); | 246 Variable *Dest = Instr->getDest(); |
| 228 const Type DestTy = Dest->getType(); | 247 const Type DestTy = Dest->getType(); |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 579 Context.init(Node); | 598 Context.init(Node); |
| 580 while (!Context.atEnd()) { | 599 while (!Context.atEnd()) { |
| 581 PostIncrLoweringContext PostIncrement(Context); | 600 PostIncrLoweringContext PostIncrement(Context); |
| 582 Inst *CurInstr = iteratorToInst(Context.getCur()); | 601 Inst *CurInstr = iteratorToInst(Context.getCur()); |
| 583 if (auto *Call = llvm::dyn_cast<InstCall>(CurInstr)) { | 602 if (auto *Call = llvm::dyn_cast<InstCall>(CurInstr)) { |
| 584 SizeT OutArgsSizeBytes = getCallStackArgumentsSizeBytes(Call); | 603 SizeT OutArgsSizeBytes = getCallStackArgumentsSizeBytes(Call); |
| 585 MaxOutArgsSizeBytes = std::max(MaxOutArgsSizeBytes, OutArgsSizeBytes); | 604 MaxOutArgsSizeBytes = std::max(MaxOutArgsSizeBytes, OutArgsSizeBytes); |
| 586 } | 605 } |
| 587 } | 606 } |
| 588 } | 607 } |
| 608 CurrentAllocaOffset = MaxOutArgsSizeBytes; |
| 589 } | 609 } |
| 590 | 610 |
| 591 void TargetMIPS32::translateO2() { | 611 void TargetMIPS32::translateO2() { |
| 592 TimerMarker T(TimerStack::TT_O2, Func); | 612 TimerMarker T(TimerStack::TT_O2, Func); |
| 593 | 613 |
| 594 // TODO(stichnot): share passes with X86? | 614 // TODO(stichnot): share passes with X86? |
| 595 // https://code.google.com/p/nativeclient/issues/detail?id=4094 | 615 // https://code.google.com/p/nativeclient/issues/detail?id=4094 |
| 596 genTargetHelperCalls(); | 616 genTargetHelperCalls(); |
| 597 | 617 |
| 598 unsetIfNonLeafFunc(); | 618 unsetIfNonLeafFunc(); |
| (...skipping 1090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 } else { | 1709 } else { |
| 1690 Target->_sw(SrcR, Addr); | 1710 Target->_sw(SrcR, Addr); |
| 1691 } | 1711 } |
| 1692 | 1712 |
| 1693 Target->Context.insert<InstFakeDef>(Dest); | 1713 Target->Context.insert<InstFakeDef>(Dest); |
| 1694 Legalized = true; | 1714 Legalized = true; |
| 1695 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { | 1715 } else if (auto *Var = llvm::dyn_cast<Variable>(Src)) { |
| 1696 if (Var->isRematerializable()) { | 1716 if (Var->isRematerializable()) { |
| 1697 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). | 1717 // This is equivalent to an x86 _lea(RematOffset(%esp/%ebp), Variable). |
| 1698 | 1718 |
| 1699 // ExtraOffset is only needed for frame-pointer based frames as we have | 1719 // ExtraOffset is only needed for stack-pointer based frames as we have |
| 1700 // to account for spill storage. | 1720 // to account for spill storage. |
| 1701 const int32_t ExtraOffset = (Var->getRegNum() == Target->getFrameReg()) | 1721 const int32_t ExtraOffset = (Var->getRegNum() == Target->getStackReg()) |
| 1702 ? Target->getFrameFixedAllocaOffset() | 1722 ? Target->getFrameFixedAllocaOffset() |
| 1703 : 0; | 1723 : 0; |
| 1704 | 1724 |
| 1705 const int32_t Offset = Var->getStackOffset() + ExtraOffset; | 1725 const int32_t Offset = Var->getStackOffset() + ExtraOffset; |
| 1706 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); | 1726 Variable *Base = Target->getPhysicalRegister(Var->getRegNum()); |
| 1707 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); | 1727 Variable *T = newBaseRegister(Base, Offset, Dest->getRegNum()); |
| 1708 Target->_mov(Dest, T); | 1728 Target->_mov(Dest, T); |
| 1709 Legalized = true; | 1729 Legalized = true; |
| 1710 } else { | 1730 } else { |
| 1711 if (!Var->hasReg()) { | 1731 if (!Var->hasReg()) { |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1915 FixedAllocaSizeBytes += Value; | 1935 FixedAllocaSizeBytes += Value; |
| 1916 // Constant size alloca. | 1936 // Constant size alloca. |
| 1917 if (!UseFramePointer) { | 1937 if (!UseFramePointer) { |
| 1918 // If we don't need a Frame Pointer, this alloca has a known offset to the | 1938 // If we don't need a Frame Pointer, this alloca has a known offset to the |
| 1919 // stack pointer. We don't need adjust the stack pointer, nor assign any | 1939 // stack pointer. We don't need adjust the stack pointer, nor assign any |
| 1920 // value to Dest, as Dest is rematerializable. | 1940 // value to Dest, as Dest is rematerializable. |
| 1921 assert(Dest->isRematerializable()); | 1941 assert(Dest->isRematerializable()); |
| 1922 Context.insert<InstFakeDef>(Dest); | 1942 Context.insert<InstFakeDef>(Dest); |
| 1923 return; | 1943 return; |
| 1924 } | 1944 } |
| 1945 |
| 1946 if (Alignment > MIPS32_STACK_ALIGNMENT_BYTES) { |
| 1947 CurrentAllocaOffset = |
| 1948 Utils::applyAlignment(CurrentAllocaOffset, Alignment); |
| 1949 } |
| 1950 auto *T = I32Reg(); |
| 1951 _addiu(T, SP, CurrentAllocaOffset); |
| 1952 _mov(Dest, T); |
| 1953 CurrentAllocaOffset += Value; |
| 1954 return; |
| 1955 |
| 1925 } else { | 1956 } else { |
| 1926 // Non-constant sizes need to be adjusted to the next highest multiple of | 1957 // Non-constant sizes need to be adjusted to the next highest multiple of |
| 1927 // the required alignment at runtime. | 1958 // the required alignment at runtime. |
| 1928 VariableAllocaUsed = true; | 1959 VariableAllocaUsed = true; |
| 1929 Variable *AlignAmount; | 1960 Variable *AlignAmount; |
| 1930 auto *TotalSizeR = legalizeToReg(TotalSize, Legal_Reg); | 1961 auto *TotalSizeR = legalizeToReg(TotalSize, Legal_Reg); |
| 1931 auto *T1 = I32Reg(); | 1962 auto *T1 = I32Reg(); |
| 1932 auto *T2 = I32Reg(); | 1963 auto *T2 = I32Reg(); |
| 1933 auto *T3 = I32Reg(); | 1964 auto *T3 = I32Reg(); |
| 1934 auto *T4 = I32Reg(); | 1965 auto *T4 = I32Reg(); |
| 1935 auto *T5 = I32Reg(); | 1966 auto *T5 = I32Reg(); |
| 1936 _addiu(T1, TotalSizeR, MIPS32_STACK_ALIGNMENT_BYTES - 1); | 1967 _addiu(T1, TotalSizeR, MIPS32_STACK_ALIGNMENT_BYTES - 1); |
| 1937 _addiu(T2, getZero(), -MIPS32_STACK_ALIGNMENT_BYTES); | 1968 _addiu(T2, getZero(), -MIPS32_STACK_ALIGNMENT_BYTES); |
| 1938 _and(T3, T1, T2); | 1969 _and(T3, T1, T2); |
| 1939 _subu(T4, SP, T3); | 1970 _subu(T4, SP, T3); |
| 1940 if (Instr->getAlignInBytes()) { | 1971 if (Instr->getAlignInBytes()) { |
| 1941 AlignAmount = | 1972 AlignAmount = |
| 1942 legalizeToReg(Ctx->getConstantInt32(-AlignmentParam), Legal_Reg); | 1973 legalizeToReg(Ctx->getConstantInt32(-AlignmentParam), Legal_Reg); |
| 1943 _and(T5, T4, AlignAmount); | 1974 _and(T5, T4, AlignAmount); |
| 1944 _mov(Dest, T5); | 1975 _mov(Dest, T5); |
| 1945 } else { | 1976 } else { |
| 1946 _mov(Dest, T4); | 1977 _mov(Dest, T4); |
| 1947 } | 1978 } |
| 1948 _mov(SP, Dest); | 1979 _mov(SP, Dest); |
| 1949 return; | 1980 return; |
| 1950 } | 1981 } |
| 1951 | |
| 1952 // Add enough to the returned address to account for the out args area. | |
| 1953 if (MaxOutArgsSizeBytes > 0) { | |
| 1954 Variable *T = makeReg(getPointerType()); | |
| 1955 _addiu(T, SP, MaxOutArgsSizeBytes); | |
| 1956 _mov(Dest, T); | |
| 1957 } else { | |
| 1958 _mov(Dest, SP); | |
| 1959 } | |
| 1960 } | 1982 } |
| 1961 | 1983 |
| 1962 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr, | 1984 void TargetMIPS32::lowerInt64Arithmetic(const InstArithmetic *Instr, |
| 1963 Variable *Dest, Operand *Src0, | 1985 Variable *Dest, Operand *Src0, |
| 1964 Operand *Src1) { | 1986 Operand *Src1) { |
| 1965 InstArithmetic::OpKind Op = Instr->getOp(); | 1987 InstArithmetic::OpKind Op = Instr->getOp(); |
| 1966 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); | 1988 auto *DestLo = llvm::cast<Variable>(loOperand(Dest)); |
| 1967 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 1989 auto *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
| 1968 Variable *Src0LoR = nullptr; | 1990 Variable *Src0LoR = nullptr; |
| 1969 Variable *Src1LoR = nullptr; | 1991 Variable *Src1LoR = nullptr; |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2229 return; | 2251 return; |
| 2230 } | 2252 } |
| 2231 default: | 2253 default: |
| 2232 UnimplementedLoweringError(this, Instr); | 2254 UnimplementedLoweringError(this, Instr); |
| 2233 return; | 2255 return; |
| 2234 } | 2256 } |
| 2235 } | 2257 } |
| 2236 | 2258 |
| 2237 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { | 2259 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { |
| 2238 Variable *Dest = Instr->getDest(); | 2260 Variable *Dest = Instr->getDest(); |
| 2261 |
| 2262 if (Dest->isRematerializable()) { |
| 2263 Context.insert<InstFakeDef>(Dest); |
| 2264 return; |
| 2265 } |
| 2266 |
| 2239 // We need to signal all the UnimplementedLoweringError errors before any | 2267 // We need to signal all the UnimplementedLoweringError errors before any |
| 2240 // legalization into new variables, otherwise Om1 register allocation may fail | 2268 // legalization into new variables, otherwise Om1 register allocation may fail |
| 2241 // when it sees variables that are defined but not used. | 2269 // when it sees variables that are defined but not used. |
| 2242 Type DestTy = Dest->getType(); | 2270 Type DestTy = Dest->getType(); |
| 2243 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); | 2271 Operand *Src0 = legalizeUndef(Instr->getSrc(0)); |
| 2244 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); | 2272 Operand *Src1 = legalizeUndef(Instr->getSrc(1)); |
| 2245 if (DestTy == IceType_i64) { | 2273 if (DestTy == IceType_i64) { |
| 2246 lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1); | 2274 lowerInt64Arithmetic(Instr, Instr->getDest(), Src0, Src1); |
| 2247 return; | 2275 return; |
| 2248 } | 2276 } |
| (...skipping 2751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5000 Str << "\t.set\t" | 5028 Str << "\t.set\t" |
| 5001 << "nomips16\n"; | 5029 << "nomips16\n"; |
| 5002 } | 5030 } |
| 5003 | 5031 |
| 5004 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 5032 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 5005 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 5033 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 5006 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 5034 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 5007 | 5035 |
| 5008 } // end of namespace MIPS32 | 5036 } // end of namespace MIPS32 |
| 5009 } // end of namespace Ice | 5037 } // end of namespace Ice |
| OLD | NEW |