| 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 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { | 1014 if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { |
| 1015 return Ctx->getConstantInt32( | 1015 return Ctx->getConstantInt32( |
| 1016 static_cast<uint32_t>(Const->getValue() >> 32)); | 1016 static_cast<uint32_t>(Const->getValue() >> 32)); |
| 1017 } | 1017 } |
| 1018 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) { | 1018 if (auto *Mem = llvm::dyn_cast<OperandMIPS32Mem>(Operand)) { |
| 1019 // Conservatively disallow memory operands with side-effects | 1019 // Conservatively disallow memory operands with side-effects |
| 1020 // in case of duplication. | 1020 // in case of duplication. |
| 1021 assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset); | 1021 assert(Mem->getAddrMode() == OperandMIPS32Mem::Offset); |
| 1022 const Type SplitType = IceType_i32; | 1022 const Type SplitType = IceType_i32; |
| 1023 Variable *Base = Mem->getBase(); | 1023 Variable *Base = Mem->getBase(); |
| 1024 ConstantInteger32 *Offset = Mem->getOffset(); | 1024 auto *Offset = llvm::cast<ConstantInteger32>(Mem->getOffset()); |
| 1025 assert(!Utils::WouldOverflowAdd(Offset->getValue(), 4)); | 1025 assert(!Utils::WouldOverflowAdd(Offset->getValue(), 4)); |
| 1026 int32_t NextOffsetVal = Offset->getValue() + 4; | 1026 int32_t NextOffsetVal = Offset->getValue() + 4; |
| 1027 constexpr bool SignExt = false; | 1027 constexpr bool SignExt = false; |
| 1028 if (!OperandMIPS32Mem::canHoldOffset(SplitType, SignExt, NextOffsetVal)) { | 1028 if (!OperandMIPS32Mem::canHoldOffset(SplitType, SignExt, NextOffsetVal)) { |
| 1029 // We have to make a temp variable and add 4 to either Base or Offset. | 1029 // We have to make a temp variable and add 4 to either Base or Offset. |
| 1030 // If we add 4 to Offset, this will convert a non-RegReg addressing | 1030 // If we add 4 to Offset, this will convert a non-RegReg addressing |
| 1031 // mode into a RegReg addressing mode. Since NaCl sandboxing disallows | 1031 // mode into a RegReg addressing mode. Since NaCl sandboxing disallows |
| 1032 // RegReg addressing modes, prefer adding to base and replacing instead. | 1032 // RegReg addressing modes, prefer adding to base and replacing instead. |
| 1033 // Thus we leave the old offset alone. | 1033 // Thus we leave the old offset alone. |
| 1034 Constant *Four = Ctx->getConstantInt32(4); | 1034 Constant *Four = Ctx->getConstantInt32(4); |
| (...skipping 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2207 Type Ty = From->getType(); | 2207 Type Ty = From->getType(); |
| 2208 // Assert that a physical register is allowed. To date, all calls | 2208 // Assert that a physical register is allowed. To date, all calls |
| 2209 // to legalize() allow a physical register. Legal_Flex converts | 2209 // to legalize() allow a physical register. Legal_Flex converts |
| 2210 // registers to the right type OperandMIPS32FlexReg as needed. | 2210 // registers to the right type OperandMIPS32FlexReg as needed. |
| 2211 assert(Allowed & Legal_Reg); | 2211 assert(Allowed & Legal_Reg); |
| 2212 // Go through the various types of operands: | 2212 // Go through the various types of operands: |
| 2213 // OperandMIPS32Mem, Constant, and Variable. | 2213 // OperandMIPS32Mem, Constant, and Variable. |
| 2214 // Given the above assertion, if type of operand is not legal | 2214 // Given the above assertion, if type of operand is not legal |
| 2215 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy | 2215 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy |
| 2216 // to a register. | 2216 // to a register. |
| 2217 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { | 2217 if (llvm::isa<Constant>(From)) { |
| 2218 (void)C; | 2218 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { |
| 2219 // TODO(reed kotler): complete this case for proper implementation | 2219 (void)C; |
| 2220 Variable *Reg = makeReg(Ty, RegNum); | 2220 // TODO(reed kotler): complete this case for proper implementation |
| 2221 Context.insert<InstFakeDef>(Reg); | 2221 Variable *Reg = makeReg(Ty, RegNum); |
| 2222 return Reg; | 2222 Context.insert<InstFakeDef>(Reg); |
| 2223 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { | 2223 return Reg; |
| 2224 const uint32_t Value = C32->getValue(); | 2224 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { |
| 2225 // Check if the immediate will fit in a Flexible second operand, | 2225 const uint32_t Value = C32->getValue(); |
| 2226 // if a Flexible second operand is allowed. We need to know the exact | 2226 // Check if the immediate will fit in a Flexible second operand, |
| 2227 // value, so that rules out relocatable constants. | 2227 // if a Flexible second operand is allowed. We need to know the exact |
| 2228 // Also try the inverse and use MVN if possible. | 2228 // value, so that rules out relocatable constants. |
| 2229 // Do a movw/movt to a register. | 2229 // Also try the inverse and use MVN if possible. |
| 2230 Variable *Reg; | 2230 // Do a movw/movt to a register. |
| 2231 if (RegNum.hasValue()) | 2231 Variable *Reg; |
| 2232 Reg = getPhysicalRegister(RegNum); | 2232 if (RegNum.hasValue()) |
| 2233 else | 2233 Reg = getPhysicalRegister(RegNum); |
| 2234 Reg = makeReg(Ty, RegNum); | 2234 else |
| 2235 if (isInt<16>(int32_t(Value))) { | 2235 Reg = makeReg(Ty, RegNum); |
| 2236 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); | 2236 if (isInt<16>(int32_t(Value))) { |
| 2237 Context.insert<InstFakeDef>(Zero); | 2237 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); |
| 2238 _addiu(Reg, Zero, Value); | 2238 Context.insert<InstFakeDef>(Zero); |
| 2239 } else { | 2239 _addiu(Reg, Zero, Value); |
| 2240 uint32_t UpperBits = (Value >> 16) & 0xFFFF; | 2240 } else { |
| 2241 (void)UpperBits; | 2241 uint32_t UpperBits = (Value >> 16) & 0xFFFF; |
| 2242 uint32_t LowerBits = Value & 0xFFFF; | 2242 (void)UpperBits; |
| 2243 Variable *TReg = makeReg(Ty, RegNum); | 2243 uint32_t LowerBits = Value & 0xFFFF; |
| 2244 _lui(TReg, UpperBits); | 2244 Variable *TReg = makeReg(Ty, RegNum); |
| 2245 _ori(Reg, TReg, LowerBits); | 2245 _lui(TReg, Ctx->getConstantInt32(UpperBits)); |
| 2246 _ori(Reg, TReg, LowerBits); |
| 2247 } |
| 2248 return Reg; |
| 2249 } else if (isScalarFloatingType(Ty)) { |
| 2250 // Load floats/doubles from literal pool. |
| 2251 auto *CFrom = llvm::cast<Constant>(From); |
| 2252 assert(CFrom->getShouldBePooled()); |
| 2253 Constant *Offset = Ctx->getConstantSym(0, CFrom->getLabelName()); |
| 2254 Variable *TReg1 = makeReg(getPointerType()); |
| 2255 Variable *TReg2 = makeReg(Ty); |
| 2256 Context.insert<InstFakeDef>(TReg2); |
| 2257 _lui(TReg1, Offset, RO_Hi); |
| 2258 OperandMIPS32Mem *Addr = |
| 2259 OperandMIPS32Mem::create(Func, Ty, TReg1, Offset); |
| 2260 if (Ty == IceType_f32) |
| 2261 _lwc1(TReg2, Addr, RO_Lo); |
| 2262 else |
| 2263 _ldc1(TReg2, Addr, RO_Lo); |
| 2264 return copyToReg(TReg2, RegNum); |
| 2246 } | 2265 } |
| 2247 return Reg; | |
| 2248 } | 2266 } |
| 2267 |
| 2249 if (auto *Var = llvm::dyn_cast<Variable>(From)) { | 2268 if (auto *Var = llvm::dyn_cast<Variable>(From)) { |
| 2250 // Check if the variable is guaranteed a physical register. This | 2269 // Check if the variable is guaranteed a physical register. This |
| 2251 // can happen either when the variable is pre-colored or when it is | 2270 // can happen either when the variable is pre-colored or when it is |
| 2252 // assigned infinite weight. | 2271 // assigned infinite weight. |
| 2253 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); | 2272 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
| 2254 // We need a new physical register for the operand if: | 2273 // We need a new physical register for the operand if: |
| 2255 // Mem is not allowed and Var isn't guaranteed a physical | 2274 // Mem is not allowed and Var isn't guaranteed a physical |
| 2256 // register, or | 2275 // register, or |
| 2257 // RegNum is required and Var->getRegNum() doesn't match. | 2276 // RegNum is required and Var->getRegNum() doesn't match. |
| 2258 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 2277 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2341 Str << "\t.set\t" | 2360 Str << "\t.set\t" |
| 2342 << "nomips16\n"; | 2361 << "nomips16\n"; |
| 2343 } | 2362 } |
| 2344 | 2363 |
| 2345 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 2364 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 2346 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 2365 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 2347 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 2366 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 2348 | 2367 |
| 2349 } // end of namespace MIPS32 | 2368 } // end of namespace MIPS32 |
| 2350 } // end of namespace Ice | 2369 } // end of namespace Ice |
| OLD | NEW |