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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 // Add handling of new register classes below. | 70 // Add handling of new register classes below. |
71 } | 71 } |
72 } | 72 } |
73 | 73 |
74 } // end of anonymous namespace | 74 } // end of anonymous namespace |
75 | 75 |
76 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {} | 76 TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {} |
77 | 77 |
78 void TargetMIPS32::staticInit(GlobalContext *Ctx) { | 78 void TargetMIPS32::staticInit(GlobalContext *Ctx) { |
79 (void)Ctx; | 79 (void)Ctx; |
| 80 RegNumT::setLimit(RegMIPS32::Reg_NUM); |
80 llvm::SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM); | 81 llvm::SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM); |
81 llvm::SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM); | 82 llvm::SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM); |
82 llvm::SmallBitVector Float32Registers(RegMIPS32::Reg_NUM); | 83 llvm::SmallBitVector Float32Registers(RegMIPS32::Reg_NUM); |
83 llvm::SmallBitVector Float64Registers(RegMIPS32::Reg_NUM); | 84 llvm::SmallBitVector Float64Registers(RegMIPS32::Reg_NUM); |
84 llvm::SmallBitVector VectorRegisters(RegMIPS32::Reg_NUM); | 85 llvm::SmallBitVector VectorRegisters(RegMIPS32::Reg_NUM); |
85 llvm::SmallBitVector InvalidRegisters(RegMIPS32::Reg_NUM); | 86 llvm::SmallBitVector InvalidRegisters(RegMIPS32::Reg_NUM); |
86 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ | 87 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ |
87 isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 88 isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
88 IntegerRegisters[RegMIPS32::val] = isInt; \ | 89 IntegerRegisters[RegMIPS32::val] = isInt; \ |
89 I64PairRegisters[RegMIPS32::val] = isI64Pair; \ | 90 I64PairRegisters[RegMIPS32::val] = isI64Pair; \ |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 const char *RegNames[RegMIPS32::Reg_NUM] = { | 284 const char *RegNames[RegMIPS32::Reg_NUM] = { |
284 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ | 285 #define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ |
285 isI64Pair, isFP32, isFP64, isVec128, alias_init) \ | 286 isI64Pair, isFP32, isFP64, isVec128, alias_init) \ |
286 name, | 287 name, |
287 REGMIPS32_TABLE | 288 REGMIPS32_TABLE |
288 #undef X | 289 #undef X |
289 }; | 290 }; |
290 | 291 |
291 } // end of anonymous namespace | 292 } // end of anonymous namespace |
292 | 293 |
293 const char *RegMIPS32::getRegName(int32_t RegNum) { | 294 const char *RegMIPS32::getRegName(RegNumT RegNum) { |
294 assert(RegNum < RegMIPS32::Reg_NUM); | 295 RegNum.assertIsValid(); |
295 return RegNames[RegNum]; | 296 return RegNames[RegNum]; |
296 } | 297 } |
297 | 298 |
298 IceString TargetMIPS32::getRegName(SizeT RegNum, Type Ty) const { | 299 IceString TargetMIPS32::getRegName(RegNumT RegNum, Type Ty) const { |
299 (void)Ty; | 300 (void)Ty; |
300 return RegMIPS32::getRegName(RegNum); | 301 return RegMIPS32::getRegName(RegNum); |
301 } | 302 } |
302 | 303 |
303 Variable *TargetMIPS32::getPhysicalRegister(SizeT RegNum, Type Ty) { | 304 Variable *TargetMIPS32::getPhysicalRegister(RegNumT RegNum, Type Ty) { |
304 if (Ty == IceType_void) | 305 if (Ty == IceType_void) |
305 Ty = IceType_i32; | 306 Ty = IceType_i32; |
306 if (PhysicalRegisters[Ty].empty()) | 307 if (PhysicalRegisters[Ty].empty()) |
307 PhysicalRegisters[Ty].resize(RegMIPS32::Reg_NUM); | 308 PhysicalRegisters[Ty].resize(RegMIPS32::Reg_NUM); |
308 assert(RegNum < PhysicalRegisters[Ty].size()); | 309 RegNum.assertIsValid(); |
309 Variable *Reg = PhysicalRegisters[Ty][RegNum]; | 310 Variable *Reg = PhysicalRegisters[Ty][RegNum]; |
310 if (Reg == nullptr) { | 311 if (Reg == nullptr) { |
311 Reg = Func->makeVariable(Ty); | 312 Reg = Func->makeVariable(Ty); |
312 Reg->setRegNum(RegNum); | 313 Reg->setRegNum(RegNum); |
313 PhysicalRegisters[Ty][RegNum] = Reg; | 314 PhysicalRegisters[Ty][RegNum] = Reg; |
314 // Specially mark a named physical register as an "argument" so that it is | 315 // Specially mark a named physical register as an "argument" so that it is |
315 // considered live upon function entry. Otherwise it's possible to get | 316 // considered live upon function entry. Otherwise it's possible to get |
316 // liveness validation errors for saving callee-save registers. | 317 // liveness validation errors for saving callee-save registers. |
317 Func->addImplicitArg(Reg); | 318 Func->addImplicitArg(Reg); |
318 // Don't bother tracking the live range of a named physical register. | 319 // Don't bother tracking the live range of a named physical register. |
319 Reg->setIgnoreLiveness(); | 320 Reg->setIgnoreLiveness(); |
320 } | 321 } |
321 return Reg; | 322 return Reg; |
322 } | 323 } |
323 | 324 |
324 void TargetMIPS32::emitJumpTable(const Cfg *Func, | 325 void TargetMIPS32::emitJumpTable(const Cfg *Func, |
325 const InstJumpTable *JumpTable) const { | 326 const InstJumpTable *JumpTable) const { |
326 (void)JumpTable; | 327 (void)JumpTable; |
327 UnimplementedError(Func->getContext()->getFlags()); | 328 UnimplementedError(Func->getContext()->getFlags()); |
328 } | 329 } |
329 | 330 |
330 /// Provide a trivial wrapper to legalize() for this common usage. | 331 /// Provide a trivial wrapper to legalize() for this common usage. |
331 Variable *TargetMIPS32::legalizeToReg(Operand *From, int32_t RegNum) { | 332 Variable *TargetMIPS32::legalizeToReg(Operand *From, RegNumT RegNum) { |
332 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); | 333 return llvm::cast<Variable>(legalize(From, Legal_Reg, RegNum)); |
333 } | 334 } |
334 | 335 |
335 /// Legalize undef values to concrete values. | 336 /// Legalize undef values to concrete values. |
336 Operand *TargetMIPS32::legalizeUndef(Operand *From, int32_t RegNum) { | 337 Operand *TargetMIPS32::legalizeUndef(Operand *From, RegNumT RegNum) { |
337 (void)RegNum; | 338 (void)RegNum; |
338 Type Ty = From->getType(); | 339 Type Ty = From->getType(); |
339 if (llvm::isa<ConstantUndef>(From)) { | 340 if (llvm::isa<ConstantUndef>(From)) { |
340 // Lower undefs to zero. Another option is to lower undefs to an | 341 // Lower undefs to zero. Another option is to lower undefs to an |
341 // uninitialized register; however, using an uninitialized register | 342 // uninitialized register; however, using an uninitialized register |
342 // results in less predictable code. | 343 // results in less predictable code. |
343 // | 344 // |
344 // If in the future the implementation is changed to lower undef | 345 // If in the future the implementation is changed to lower undef |
345 // values to uninitialized registers, a FakeDef will be needed: | 346 // values to uninitialized registers, a FakeDef will be needed: |
346 // Context.insert(InstFakeDef::create(Func, Reg)); | 347 // Context.insert(InstFakeDef::create(Func, Reg)); |
347 // This is in order to ensure that the live range of Reg is not | 348 // This is in order to ensure that the live range of Reg is not |
348 // overestimated. If the constant being lowered is a 64 bit value, | 349 // overestimated. If the constant being lowered is a 64 bit value, |
349 // then the result should be split and the lo and hi components will | 350 // then the result should be split and the lo and hi components will |
350 // need to go in uninitialized registers. | 351 // need to go in uninitialized registers. |
351 if (isVectorType(Ty)) | 352 if (isVectorType(Ty)) |
352 UnimplementedError(Func->getContext()->getFlags()); | 353 UnimplementedError(Func->getContext()->getFlags()); |
353 return Ctx->getConstantZero(Ty); | 354 return Ctx->getConstantZero(Ty); |
354 } | 355 } |
355 return From; | 356 return From; |
356 } | 357 } |
357 | 358 |
358 Variable *TargetMIPS32::makeReg(Type Type, int32_t RegNum) { | 359 Variable *TargetMIPS32::makeReg(Type Type, RegNumT RegNum) { |
359 // There aren't any 64-bit integer registers for Mips32. | 360 // There aren't any 64-bit integer registers for Mips32. |
360 assert(Type != IceType_i64); | 361 assert(Type != IceType_i64); |
361 Variable *Reg = Func->makeVariable(Type); | 362 Variable *Reg = Func->makeVariable(Type); |
362 if (RegNum == Variable::NoRegister) | 363 if (RegNum == RegNumT::NoRegister) |
363 Reg->setMustHaveReg(); | 364 Reg->setMustHaveReg(); |
364 else | 365 else |
365 Reg->setRegNum(RegNum); | 366 Reg->setRegNum(RegNum); |
366 return Reg; | 367 return Reg; |
367 } | 368 } |
368 | 369 |
369 void TargetMIPS32::emitVariable(const Variable *Var) const { | 370 void TargetMIPS32::emitVariable(const Variable *Var) const { |
370 if (!BuildDefs::dump()) | 371 if (!BuildDefs::dump()) |
371 return; | 372 return; |
372 Ostream &Str = Ctx->getStrEmit(); | 373 Ostream &Str = Ctx->getStrEmit(); |
(...skipping 30 matching lines...) Expand all Loading... |
403 UnimplementedError(Func->getContext()->getFlags()); | 404 UnimplementedError(Func->getContext()->getFlags()); |
404 continue; | 405 continue; |
405 } | 406 } |
406 if (isFloatingType(Ty)) { | 407 if (isFloatingType(Ty)) { |
407 UnimplementedError(Func->getContext()->getFlags()); | 408 UnimplementedError(Func->getContext()->getFlags()); |
408 continue; | 409 continue; |
409 } | 410 } |
410 if (Ty == IceType_i64) { | 411 if (Ty == IceType_i64) { |
411 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) | 412 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) |
412 continue; | 413 continue; |
413 int32_t RegLo = RegMIPS32::Reg_A0 + NumGPRRegsUsed; | 414 auto RegLo = RegNumT::fixme(RegMIPS32::Reg_A0 + NumGPRRegsUsed); |
414 int32_t RegHi = RegLo + 1; | 415 auto RegHi = RegNumT::fixme(RegLo + 1); |
415 ++NumGPRRegsUsed; | 416 ++NumGPRRegsUsed; |
416 // Always start i64 registers at an even register, so this may end | 417 // Always start i64 registers at an even register, so this may end |
417 // up padding away a register. | 418 // up padding away a register. |
418 if (RegLo % 2 != 0) { | 419 if (RegLo % 2 != 0) { |
419 ++RegLo; | 420 RegLo = RegNumT::fixme(RegLo + 1); |
420 ++NumGPRRegsUsed; | 421 ++NumGPRRegsUsed; |
421 } | 422 } |
422 // If this leaves us without room to consume another register, | 423 // If this leaves us without room to consume another register, |
423 // leave any previously speculatively consumed registers as consumed. | 424 // leave any previously speculatively consumed registers as consumed. |
424 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) | 425 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) |
425 continue; | 426 continue; |
426 // RegHi = RegMIPS32::Reg_A0 + NumGPRRegsUsed; | 427 // RegHi = RegNumT::fixme(RegMIPS32::Reg_A0 + NumGPRRegsUsed); |
427 ++NumGPRRegsUsed; | 428 ++NumGPRRegsUsed; |
428 Variable *RegisterArg = Func->makeVariable(Ty); | 429 Variable *RegisterArg = Func->makeVariable(Ty); |
429 auto *RegisterArg64On32 = llvm::cast<Variable64On32>(RegisterArg); | 430 auto *RegisterArg64On32 = llvm::cast<Variable64On32>(RegisterArg); |
430 if (BuildDefs::dump()) | 431 if (BuildDefs::dump()) |
431 RegisterArg64On32->setName(Func, "home_reg:" + Arg->getName(Func)); | 432 RegisterArg64On32->setName(Func, "home_reg:" + Arg->getName(Func)); |
432 RegisterArg64On32->initHiLo(Func); | 433 RegisterArg64On32->initHiLo(Func); |
433 RegisterArg64On32->setIsArg(); | 434 RegisterArg64On32->setIsArg(); |
434 RegisterArg64On32->getLo()->setRegNum(RegLo); | 435 RegisterArg64On32->getLo()->setRegNum(RegLo); |
435 RegisterArg64On32->getHi()->setRegNum(RegHi); | 436 RegisterArg64On32->getHi()->setRegNum(RegHi); |
436 Arg->setIsArg(false); | 437 Arg->setIsArg(false); |
437 Args[I] = RegisterArg64On32; | 438 Args[I] = RegisterArg64On32; |
438 Context.insert<InstAssign>(Arg, RegisterArg); | 439 Context.insert<InstAssign>(Arg, RegisterArg); |
439 continue; | 440 continue; |
440 } else { | 441 } else { |
441 assert(Ty == IceType_i32); | 442 assert(Ty == IceType_i32); |
442 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) | 443 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) |
443 continue; | 444 continue; |
444 int32_t RegNum = RegMIPS32::Reg_A0 + NumGPRRegsUsed; | 445 auto RegNum = RegNumT::fixme(RegMIPS32::Reg_A0 + NumGPRRegsUsed); |
445 ++NumGPRRegsUsed; | 446 ++NumGPRRegsUsed; |
446 Variable *RegisterArg = Func->makeVariable(Ty); | 447 Variable *RegisterArg = Func->makeVariable(Ty); |
447 if (BuildDefs::dump()) { | 448 if (BuildDefs::dump()) { |
448 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); | 449 RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); |
449 } | 450 } |
450 RegisterArg->setRegNum(RegNum); | 451 RegisterArg->setRegNum(RegNum); |
451 RegisterArg->setIsArg(); | 452 RegisterArg->setIsArg(); |
452 Arg->setIsArg(false); | 453 Arg->setIsArg(false); |
453 Args[I] = RegisterArg; | 454 Args[I] = RegisterArg; |
454 Context.insert<InstAssign>(Arg, RegisterArg); | 455 Context.insert<InstAssign>(Arg, RegisterArg); |
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 | 1150 |
1150 void TargetMIPS32::postLower() { | 1151 void TargetMIPS32::postLower() { |
1151 if (Ctx->getFlags().getOptLevel() == Opt_m1) | 1152 if (Ctx->getFlags().getOptLevel() == Opt_m1) |
1152 return; | 1153 return; |
1153 // TODO(rkotler): Find two-address non-SSA instructions where Dest==Src0, | 1154 // TODO(rkotler): Find two-address non-SSA instructions where Dest==Src0, |
1154 // and set the IsDestRedefined flag to keep liveness analysis consistent. | 1155 // and set the IsDestRedefined flag to keep liveness analysis consistent. |
1155 UnimplementedError(Func->getContext()->getFlags()); | 1156 UnimplementedError(Func->getContext()->getFlags()); |
1156 } | 1157 } |
1157 | 1158 |
1158 void TargetMIPS32::makeRandomRegisterPermutation( | 1159 void TargetMIPS32::makeRandomRegisterPermutation( |
1159 llvm::SmallVectorImpl<int32_t> &Permutation, | 1160 llvm::SmallVectorImpl<RegNumT> &Permutation, |
1160 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { | 1161 const llvm::SmallBitVector &ExcludeRegisters, uint64_t Salt) const { |
1161 (void)Permutation; | 1162 (void)Permutation; |
1162 (void)ExcludeRegisters; | 1163 (void)ExcludeRegisters; |
1163 (void)Salt; | 1164 (void)Salt; |
1164 UnimplementedError(Func->getContext()->getFlags()); | 1165 UnimplementedError(Func->getContext()->getFlags()); |
1165 } | 1166 } |
1166 | 1167 |
1167 /* TODO(jvoung): avoid duplicate symbols with multiple targets. | 1168 /* TODO(jvoung): avoid duplicate symbols with multiple targets. |
1168 void ConstantUndef::emitWithoutDollar(GlobalContext *) const { | 1169 void ConstantUndef::emitWithoutDollar(GlobalContext *) const { |
1169 llvm_unreachable("Not expecting to emitWithoutDollar undef"); | 1170 llvm_unreachable("Not expecting to emitWithoutDollar undef"); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 } | 1207 } |
1207 | 1208 |
1208 void TargetDataMIPS32::lowerJumpTables() { | 1209 void TargetDataMIPS32::lowerJumpTables() { |
1209 if (Ctx->getFlags().getDisableTranslation()) | 1210 if (Ctx->getFlags().getDisableTranslation()) |
1210 return; | 1211 return; |
1211 UnimplementedError(Ctx->getFlags()); | 1212 UnimplementedError(Ctx->getFlags()); |
1212 } | 1213 } |
1213 | 1214 |
1214 // Helper for legalize() to emit the right code to lower an operand to a | 1215 // Helper for legalize() to emit the right code to lower an operand to a |
1215 // register of the appropriate type. | 1216 // register of the appropriate type. |
1216 Variable *TargetMIPS32::copyToReg(Operand *Src, int32_t RegNum) { | 1217 Variable *TargetMIPS32::copyToReg(Operand *Src, RegNumT RegNum) { |
1217 Type Ty = Src->getType(); | 1218 Type Ty = Src->getType(); |
1218 Variable *Reg = makeReg(Ty, RegNum); | 1219 Variable *Reg = makeReg(Ty, RegNum); |
1219 if (isVectorType(Ty) || isFloatingType(Ty)) { | 1220 if (isVectorType(Ty) || isFloatingType(Ty)) { |
1220 UnimplementedError(Ctx->getFlags()); | 1221 UnimplementedError(Ctx->getFlags()); |
1221 } else { | 1222 } else { |
1222 // Mov's Src operand can really only be the flexible second operand type | 1223 // Mov's Src operand can really only be the flexible second operand type |
1223 // or a register. Users should guarantee that. | 1224 // or a register. Users should guarantee that. |
1224 _mov(Reg, Src); | 1225 _mov(Reg, Src); |
1225 } | 1226 } |
1226 return Reg; | 1227 return Reg; |
1227 } | 1228 } |
1228 | 1229 |
1229 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, | 1230 Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed, |
1230 int32_t RegNum) { | 1231 RegNumT RegNum) { |
1231 Type Ty = From->getType(); | 1232 Type Ty = From->getType(); |
1232 // Assert that a physical register is allowed. To date, all calls | 1233 // Assert that a physical register is allowed. To date, all calls |
1233 // to legalize() allow a physical register. Legal_Flex converts | 1234 // to legalize() allow a physical register. Legal_Flex converts |
1234 // registers to the right type OperandMIPS32FlexReg as needed. | 1235 // registers to the right type OperandMIPS32FlexReg as needed. |
1235 assert(Allowed & Legal_Reg); | 1236 assert(Allowed & Legal_Reg); |
1236 // Go through the various types of operands: | 1237 // Go through the various types of operands: |
1237 // OperandMIPS32Mem, Constant, and Variable. | 1238 // OperandMIPS32Mem, Constant, and Variable. |
1238 // Given the above assertion, if type of operand is not legal | 1239 // Given the above assertion, if type of operand is not legal |
1239 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy | 1240 // (e.g., OperandMIPS32Mem and !Legal_Mem), we can always copy |
1240 // to a register. | 1241 // to a register. |
1241 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { | 1242 if (auto *C = llvm::dyn_cast<ConstantRelocatable>(From)) { |
1242 (void)C; | 1243 (void)C; |
1243 // TODO(reed kotler): complete this case for proper implementation | 1244 // TODO(reed kotler): complete this case for proper implementation |
1244 Variable *Reg = makeReg(Ty, RegNum); | 1245 Variable *Reg = makeReg(Ty, RegNum); |
1245 Context.insert<InstFakeDef>(Reg); | 1246 Context.insert<InstFakeDef>(Reg); |
1246 return Reg; | 1247 return Reg; |
1247 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { | 1248 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { |
1248 const uint32_t Value = C32->getValue(); | 1249 const uint32_t Value = C32->getValue(); |
1249 // Check if the immediate will fit in a Flexible second operand, | 1250 // Check if the immediate will fit in a Flexible second operand, |
1250 // 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 |
1251 // value, so that rules out relocatable constants. | 1252 // value, so that rules out relocatable constants. |
1252 // Also try the inverse and use MVN if possible. | 1253 // Also try the inverse and use MVN if possible. |
1253 // Do a movw/movt to a register. | 1254 // Do a movw/movt to a register. |
1254 Variable *Reg; | 1255 Variable *Reg; |
1255 if (RegNum == Variable::NoRegister) | 1256 if (RegNum == RegNumT::NoRegister) |
1256 Reg = makeReg(Ty, RegNum); | 1257 Reg = makeReg(Ty, RegNum); |
1257 else | 1258 else |
1258 Reg = getPhysicalRegister(RegNum); | 1259 Reg = getPhysicalRegister(RegNum); |
1259 if (isInt<16>(int32_t(Value))) { | 1260 if (isInt<16>(int32_t(Value))) { |
1260 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); | 1261 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); |
1261 Context.insert<InstFakeDef>(Zero); | 1262 Context.insert<InstFakeDef>(Zero); |
1262 _addiu(Reg, Zero, Value); | 1263 _addiu(Reg, Zero, Value); |
1263 } else { | 1264 } else { |
1264 uint32_t UpperBits = (Value >> 16) & 0xFFFF; | 1265 uint32_t UpperBits = (Value >> 16) & 0xFFFF; |
1265 (void)UpperBits; | 1266 (void)UpperBits; |
1266 uint32_t LowerBits = Value & 0xFFFF; | 1267 uint32_t LowerBits = Value & 0xFFFF; |
1267 Variable *TReg = makeReg(Ty, RegNum); | 1268 Variable *TReg = makeReg(Ty, RegNum); |
1268 _lui(TReg, UpperBits); | 1269 _lui(TReg, UpperBits); |
1269 _ori(Reg, TReg, LowerBits); | 1270 _ori(Reg, TReg, LowerBits); |
1270 } | 1271 } |
1271 return Reg; | 1272 return Reg; |
1272 } | 1273 } |
1273 if (auto *Var = llvm::dyn_cast<Variable>(From)) { | 1274 if (auto *Var = llvm::dyn_cast<Variable>(From)) { |
1274 // Check if the variable is guaranteed a physical register. This | 1275 // Check if the variable is guaranteed a physical register. This |
1275 // 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 |
1276 // assigned infinite weight. | 1277 // assigned infinite weight. |
1277 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); | 1278 bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
1278 // We need a new physical register for the operand if: | 1279 // We need a new physical register for the operand if: |
1279 // Mem is not allowed and Var isn't guaranteed a physical | 1280 // Mem is not allowed and Var isn't guaranteed a physical |
1280 // register, or | 1281 // register, or |
1281 // RegNum is required and Var->getRegNum() doesn't match. | 1282 // RegNum is required and Var->getRegNum() doesn't match. |
1282 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || | 1283 if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
1283 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 1284 (RegNum != RegNumT::NoRegister && RegNum != Var->getRegNum())) { |
1284 From = copyToReg(From, RegNum); | 1285 From = copyToReg(From, RegNum); |
1285 } | 1286 } |
1286 return From; | 1287 return From; |
1287 } | 1288 } |
1288 return From; | 1289 return From; |
1289 } | 1290 } |
1290 | 1291 |
1291 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) | 1292 TargetHeaderMIPS32::TargetHeaderMIPS32(GlobalContext *Ctx) |
1292 : TargetHeaderLowering(Ctx) {} | 1293 : TargetHeaderLowering(Ctx) {} |
1293 | 1294 |
1294 void TargetHeaderMIPS32::lower() { | 1295 void TargetHeaderMIPS32::lower() { |
1295 OstreamLocker L(Ctx); | 1296 OstreamLocker L(Ctx); |
1296 Ostream &Str = Ctx->getStrEmit(); | 1297 Ostream &Str = Ctx->getStrEmit(); |
1297 Str << "\t.set\t" | 1298 Str << "\t.set\t" |
1298 << "nomicromips\n"; | 1299 << "nomicromips\n"; |
1299 Str << "\t.set\t" | 1300 Str << "\t.set\t" |
1300 << "nomips16\n"; | 1301 << "nomips16\n"; |
1301 } | 1302 } |
1302 | 1303 |
1303 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 1304 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
1304 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 1305 llvm::SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
1305 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 1306 llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
1306 | 1307 |
1307 } // end of namespace MIPS32 | 1308 } // end of namespace MIPS32 |
1308 } // end of namespace Ice | 1309 } // end of namespace Ice |
OLD | NEW |