OLD | NEW |
1 //===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===// | 1 //===- subzero/src/IceTargetLoweringMIPS32.cpp - MIPS32 lowering ----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 UnimplementedError(Func->getContext()->getFlags()); | 353 UnimplementedError(Func->getContext()->getFlags()); |
354 return Ctx->getConstantZero(Ty); | 354 return Ctx->getConstantZero(Ty); |
355 } | 355 } |
356 return From; | 356 return From; |
357 } | 357 } |
358 | 358 |
359 Variable *TargetMIPS32::makeReg(Type Type, RegNumT RegNum) { | 359 Variable *TargetMIPS32::makeReg(Type Type, RegNumT RegNum) { |
360 // There aren't any 64-bit integer registers for Mips32. | 360 // There aren't any 64-bit integer registers for Mips32. |
361 assert(Type != IceType_i64); | 361 assert(Type != IceType_i64); |
362 Variable *Reg = Func->makeVariable(Type); | 362 Variable *Reg = Func->makeVariable(Type); |
363 if (RegNum == RegNumT::NoRegister) | 363 if (RegNum.hasValue()) |
| 364 Reg->setRegNum(RegNum); |
| 365 else |
364 Reg->setMustHaveReg(); | 366 Reg->setMustHaveReg(); |
365 else | |
366 Reg->setRegNum(RegNum); | |
367 return Reg; | 367 return Reg; |
368 } | 368 } |
369 | 369 |
370 void TargetMIPS32::emitVariable(const Variable *Var) const { | 370 void TargetMIPS32::emitVariable(const Variable *Var) const { |
371 if (!BuildDefs::dump()) | 371 if (!BuildDefs::dump()) |
372 return; | 372 return; |
373 Ostream &Str = Ctx->getStrEmit(); | 373 Ostream &Str = Ctx->getStrEmit(); |
374 const Type FrameSPTy = IceType_i32; | 374 const Type FrameSPTy = IceType_i32; |
375 if (Var->hasReg()) { | 375 if (Var->hasReg()) { |
376 Str << '$' << getRegName(Var->getRegNum(), Var->getType()); | 376 Str << '$' << getRegName(Var->getRegNum(), Var->getType()); |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1246 Context.insert<InstFakeDef>(Reg); | 1246 Context.insert<InstFakeDef>(Reg); |
1247 return Reg; | 1247 return Reg; |
1248 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { | 1248 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { |
1249 const uint32_t Value = C32->getValue(); | 1249 const uint32_t Value = C32->getValue(); |
1250 // Check if the immediate will fit in a Flexible second operand, | 1250 // Check if the immediate will fit in a Flexible second operand, |
1251 // if a Flexible second operand is allowed. We need to know the exact | 1251 // if a Flexible second operand is allowed. We need to know the exact |
1252 // value, so that rules out relocatable constants. | 1252 // value, so that rules out relocatable constants. |
1253 // Also try the inverse and use MVN if possible. | 1253 // Also try the inverse and use MVN if possible. |
1254 // Do a movw/movt to a register. | 1254 // Do a movw/movt to a register. |
1255 Variable *Reg; | 1255 Variable *Reg; |
1256 if (RegNum == RegNumT::NoRegister) | 1256 if (RegNum.hasValue()) |
| 1257 Reg = getPhysicalRegister(RegNum); |
| 1258 else |
1257 Reg = makeReg(Ty, RegNum); | 1259 Reg = makeReg(Ty, RegNum); |
1258 else | |
1259 Reg = getPhysicalRegister(RegNum); | |
1260 if (isInt<16>(int32_t(Value))) { | 1260 if (isInt<16>(int32_t(Value))) { |
1261 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); | 1261 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); |
1262 Context.insert<InstFakeDef>(Zero); | 1262 Context.insert<InstFakeDef>(Zero); |
1263 _addiu(Reg, Zero, Value); | 1263 _addiu(Reg, Zero, Value); |
1264 } else { | 1264 } else { |
1265 uint32_t UpperBits = (Value >> 16) & 0xFFFF; | 1265 uint32_t UpperBits = (Value >> 16) & 0xFFFF; |
1266 (void)UpperBits; | 1266 (void)UpperBits; |
1267 uint32_t LowerBits = Value & 0xFFFF; | 1267 uint32_t LowerBits = Value & 0xFFFF; |
1268 Variable *TReg = makeReg(Ty, RegNum); | 1268 Variable *TReg = makeReg(Ty, RegNum); |
1269 _lui(TReg, UpperBits); | 1269 _lui(TReg, UpperBits); |
1270 _ori(Reg, TReg, LowerBits); | 1270 _ori(Reg, TReg, LowerBits); |
1271 } | 1271 } |
1272 return Reg; | 1272 return Reg; |
1273 } | 1273 } |
1274 if (auto *Var = llvm::dyn_cast<Variable>(From)) { | 1274 if (auto *Var = llvm::dyn_cast<Variable>(From)) { |
1275 // Check if the variable is guaranteed a physical register. This | 1275 // Check if the variable is guaranteed a physical register. This |
1276 // can happen either when the variable is pre-colored or when it is | 1276 // can happen either when the variable is pre-colored or when it is |
1277 // assigned infinite weight. | 1277 // assigned infinite weight. |
1278 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); | 1278 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
1279 // We need a new physical register for the operand if: | 1279 // We need a new physical register for the operand if: |
1280 // Mem is not allowed and Var isn't guaranteed a physical | 1280 // Mem is not allowed and Var isn't guaranteed a physical |
1281 // register, or | 1281 // register, or |
1282 // RegNum is required and Var->getRegNum() doesn't match. | 1282 // RegNum is required and Var->getRegNum() doesn't match. |
1283 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 1283 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
1284 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) { | 1284 (RegNum.hasValue() && RegNum != Var->getRegNum())) { |
1285 From = copyToReg(From, RegNum); | 1285 From = copyToReg(From, RegNum); |
1286 } | 1286 } |
1287 return From; | 1287 return From; |
1288 } | 1288 } |
1289 return From; | 1289 return From; |
1290 } | 1290 } |
1291 | 1291 |
1292 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) | 1292 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) |
1293 : TargetHeaderLowering(Ctx) {} | 1293 : TargetHeaderLowering(Ctx) {} |
1294 | 1294 |
1295 void TargetHeaderMIPS32::lower() { | 1295 void TargetHeaderMIPS32::lower() { |
1296 OstreamLocker L(Ctx); | 1296 OstreamLocker L(Ctx); |
1297 Ostream &Str = Ctx->getStrEmit(); | 1297 Ostream &Str = Ctx->getStrEmit(); |
1298 Str << "\t.set\t" | 1298 Str << "\t.set\t" |
1299 << "nomicromips\n"; | 1299 << "nomicromips\n"; |
1300 Str << "\t.set\t" | 1300 Str << "\t.set\t" |
1301 << "nomips16\n"; | 1301 << "nomips16\n"; |
1302 } | 1302 } |
1303 | 1303 |
1304 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 1304 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
1305 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 1305 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
1306 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 1306 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
1307 | 1307 |
1308 } // end of namespace MIPS32 | 1308 } // end of namespace MIPS32 |
1309 } // end of namespace Ice | 1309 } // end of namespace Ice |
OLD | NEW |