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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
233 continue; | 233 continue; |
234 } | 234 } |
235 | 235 |
236 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty); | 236 OutArgsSizeBytes = applyStackAlignmentTy(OutArgsSizeBytes, Ty); |
237 OutArgsSizeBytes += typeWidthInBytesOnStack(Ty); | 237 OutArgsSizeBytes += typeWidthInBytesOnStack(Ty); |
238 } | 238 } |
239 | 239 |
240 return applyStackAlignment(OutArgsSizeBytes); | 240 return applyStackAlignment(OutArgsSizeBytes); |
241 } | 241 } |
242 | 242 |
243 namespace { | |
244 inline uint64_t getConstantMemoryOrder(Operand *Opnd) { | |
245 if (auto *Integer = llvm::dyn_cast<ConstantInteger32>(Opnd)) | |
246 return Integer->getValue(); | |
247 return Intrinsics::MemoryOrderInvalid; | |
248 } | |
249 } | |
250 | |
243 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { | 251 void TargetMIPS32::genTargetHelperCallFor(Inst *Instr) { |
244 constexpr bool NoTailCall = false; | 252 constexpr bool NoTailCall = false; |
245 constexpr bool IsTargetHelperCall = true; | 253 constexpr bool IsTargetHelperCall = true; |
246 Variable *Dest = Instr->getDest(); | 254 Variable *Dest = Instr->getDest(); |
247 const Type DestTy = Dest ? Dest->getType() : IceType_void; | 255 const Type DestTy = Dest ? Dest->getType() : IceType_void; |
248 | 256 |
249 switch (Instr->getKind()) { | 257 switch (Instr->getKind()) { |
250 default: | 258 default: |
251 return; | 259 return; |
252 case Inst::Select: { | 260 case Inst::Select: { |
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1046 if (ArgNo == 0) { | 1054 if (ArgNo == 0) { |
1047 UseFPRegs = true; | 1055 UseFPRegs = true; |
1048 return argInVFP(Ty, Reg); | 1056 return argInVFP(Ty, Reg); |
1049 } | 1057 } |
1050 if (UseFPRegs && ArgNo == 1) { | 1058 if (UseFPRegs && ArgNo == 1) { |
1051 UseFPRegs = false; | 1059 UseFPRegs = false; |
1052 return argInVFP(Ty, Reg); | 1060 return argInVFP(Ty, Reg); |
1053 } | 1061 } |
1054 return argInGPR(Ty, Reg); | 1062 return argInGPR(Ty, Reg); |
1055 } | 1063 } |
1056 UnimplementedError(getFlags()); | 1064 llvm::report_fatal_error("argInReg: Invalid type."); |
1057 return false; | 1065 return false; |
1058 } | 1066 } |
1059 | 1067 |
1060 bool TargetMIPS32::CallingConv::argInGPR(Type Ty, RegNumT *Reg) { | 1068 bool TargetMIPS32::CallingConv::argInGPR(Type Ty, RegNumT *Reg) { |
1061 CfgVector<RegNumT> *Source; | 1069 CfgVector<RegNumT> *Source; |
1062 | 1070 |
1063 switch (Ty) { | 1071 switch (Ty) { |
1064 default: { | 1072 default: { |
1065 UnimplementedError(getFlags()); | 1073 llvm::report_fatal_error("argInGPR: Invalid type."); |
1066 return false; | 1074 return false; |
1067 } break; | 1075 } break; |
1068 case IceType_v4i1: | 1076 case IceType_v4i1: |
1069 case IceType_v8i1: | 1077 case IceType_v8i1: |
1070 case IceType_v16i1: | 1078 case IceType_v16i1: |
1071 case IceType_v16i8: | 1079 case IceType_v16i8: |
1072 case IceType_v8i16: | 1080 case IceType_v8i16: |
1073 case IceType_v4i32: | 1081 case IceType_v4i32: |
1074 case IceType_v4f32: | 1082 case IceType_v4f32: |
1075 case IceType_i32: | 1083 case IceType_i32: |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1140 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { | 1148 while (!Regs->empty() && GPRegsUsed[Regs->back()]) { |
1141 discardNextGPRAndItsAliases(Regs); | 1149 discardNextGPRAndItsAliases(Regs); |
1142 } | 1150 } |
1143 } | 1151 } |
1144 | 1152 |
1145 bool TargetMIPS32::CallingConv::argInVFP(Type Ty, RegNumT *Reg) { | 1153 bool TargetMIPS32::CallingConv::argInVFP(Type Ty, RegNumT *Reg) { |
1146 CfgVector<RegNumT> *Source; | 1154 CfgVector<RegNumT> *Source; |
1147 | 1155 |
1148 switch (Ty) { | 1156 switch (Ty) { |
1149 default: { | 1157 default: { |
1150 UnimplementedError(getFlags()); | 1158 llvm::report_fatal_error("argInVFP: Invalid type."); |
1151 return false; | 1159 return false; |
1152 } break; | 1160 } break; |
1153 case IceType_f32: { | 1161 case IceType_f32: { |
1154 Source = &FP32Args; | 1162 Source = &FP32Args; |
1155 } break; | 1163 } break; |
1156 case IceType_f64: { | 1164 case IceType_f64: { |
1157 Source = &FP64Args; | 1165 Source = &FP64Args; |
1158 } break; | 1166 } break; |
1159 } | 1167 } |
1160 | 1168 |
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2532 _mov(T1_Hi, T_Hi); | 2540 _mov(T1_Hi, T_Hi); |
2533 _mov(T1_Lo, T_Lo); | 2541 _mov(T1_Lo, T_Lo); |
2534 _andi(T5, Src1LoR, INT32_BITS); | 2542 _andi(T5, Src1LoR, INT32_BITS); |
2535 _movn(T1_Lo, T_Hi, T5); | 2543 _movn(T1_Lo, T_Hi, T5); |
2536 _sra(T6, Src0HiR, INT32_BITS - 1); | 2544 _sra(T6, Src0HiR, INT32_BITS - 1); |
2537 _movn(T1_Hi, T6, T5); | 2545 _movn(T1_Hi, T6, T5); |
2538 _mov(DestHi, T1_Hi); | 2546 _mov(DestHi, T1_Hi); |
2539 _mov(DestLo, T1_Lo); | 2547 _mov(DestLo, T1_Lo); |
2540 return; | 2548 return; |
2541 } | 2549 } |
2542 default: | 2550 case InstArithmetic::Fadd: |
2543 UnimplementedLoweringError(this, Instr); | 2551 case InstArithmetic::Fsub: |
2552 case InstArithmetic::Fmul: | |
2553 case InstArithmetic::Fdiv: | |
2554 case InstArithmetic::Frem: | |
2555 llvm::report_fatal_error("FP instruction with i64 type"); | |
2556 return; | |
2557 case InstArithmetic::Udiv: | |
2558 case InstArithmetic::Sdiv: | |
2559 case InstArithmetic::Urem: | |
2560 case InstArithmetic::Srem: | |
2561 llvm::report_fatal_error("64-bit div and rem should have been prelowered"); | |
2544 return; | 2562 return; |
2545 } | 2563 } |
2546 } | 2564 } |
2547 | 2565 |
2548 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { | 2566 void TargetMIPS32::lowerArithmetic(const InstArithmetic *Instr) { |
2549 Variable *Dest = Instr->getDest(); | 2567 Variable *Dest = Instr->getDest(); |
2550 | 2568 |
2551 if (Dest->isRematerializable()) { | 2569 if (Dest->isRematerializable()) { |
2552 Context.insert<InstFakeDef>(Dest); | 2570 Context.insert<InstFakeDef>(Dest); |
2553 return; | 2571 return; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2777 if (DestTy == IceType_f64) { | 2795 if (DestTy == IceType_f64) { |
2778 _div_d(T, Src0R, Src1R); | 2796 _div_d(T, Src0R, Src1R); |
2779 _mov(Dest, T); | 2797 _mov(Dest, T); |
2780 return; | 2798 return; |
2781 } | 2799 } |
2782 break; | 2800 break; |
2783 case InstArithmetic::Frem: | 2801 case InstArithmetic::Frem: |
2784 llvm::report_fatal_error("frem should have been prelowered."); | 2802 llvm::report_fatal_error("frem should have been prelowered."); |
2785 break; | 2803 break; |
2786 } | 2804 } |
2787 UnimplementedLoweringError(this, Instr); | 2805 llvm::report_fatal_error("Unknown arithmetic operator"); |
2788 } | 2806 } |
2789 | 2807 |
2790 void TargetMIPS32::lowerAssign(const InstAssign *Instr) { | 2808 void TargetMIPS32::lowerAssign(const InstAssign *Instr) { |
2791 Variable *Dest = Instr->getDest(); | 2809 Variable *Dest = Instr->getDest(); |
2792 | 2810 |
2793 if (Dest->isRematerializable()) { | 2811 if (Dest->isRematerializable()) { |
2794 Context.insert<InstFakeDef>(Dest); | 2812 Context.insert<InstFakeDef>(Dest); |
2795 return; | 2813 return; |
2796 } | 2814 } |
2797 | 2815 |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3489 return; | 3507 return; |
3490 } | 3508 } |
3491 if (Src0Ty == IceType_f64 && isScalarIntegerType(DestTy)) { | 3509 if (Src0Ty == IceType_f64 && isScalarIntegerType(DestTy)) { |
3492 Variable *Src0R = legalizeToReg(Src0); | 3510 Variable *Src0R = legalizeToReg(Src0); |
3493 Variable *FTmp = makeReg(IceType_f64); | 3511 Variable *FTmp = makeReg(IceType_f64); |
3494 _trunc_w_d(FTmp, Src0R); | 3512 _trunc_w_d(FTmp, Src0R); |
3495 _mov(Dest, FTmp); | 3513 _mov(Dest, FTmp); |
3496 return; | 3514 return; |
3497 } | 3515 } |
3498 } | 3516 } |
3499 UnimplementedLoweringError(this, Instr); | 3517 llvm::report_fatal_error("Destination is i64 in fp-to-i32"); |
3500 break; | 3518 break; |
3501 } | 3519 } |
3502 case InstCast::Sitofp: | 3520 case InstCast::Sitofp: |
3503 case InstCast::Uitofp: { | 3521 case InstCast::Uitofp: { |
3504 if (llvm::isa<Variable64On32>(Dest)) { | 3522 if (llvm::isa<Variable64On32>(Dest)) { |
3505 llvm::report_fatal_error("i64-to-fp should have been prelowered."); | 3523 llvm::report_fatal_error("i64-to-fp should have been prelowered."); |
3506 return; | 3524 return; |
3507 } | 3525 } |
3508 if (Src0Ty != IceType_i64) { | 3526 if (Src0Ty != IceType_i64) { |
3509 Variable *Src0R = legalizeToReg(Src0); | 3527 Variable *Src0R = legalizeToReg(Src0); |
(...skipping 12 matching lines...) Expand all Loading... | |
3522 } | 3540 } |
3523 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) { | 3541 if (isScalarIntegerType(Src0Ty) && DestTy == IceType_f64) { |
3524 Variable *FTmp1 = makeReg(IceType_f64); | 3542 Variable *FTmp1 = makeReg(IceType_f64); |
3525 Variable *FTmp2 = makeReg(IceType_f64); | 3543 Variable *FTmp2 = makeReg(IceType_f64); |
3526 _mtc1(FTmp1, T0R); | 3544 _mtc1(FTmp1, T0R); |
3527 _cvt_d_w(FTmp2, FTmp1); | 3545 _cvt_d_w(FTmp2, FTmp1); |
3528 _mov(Dest, FTmp2); | 3546 _mov(Dest, FTmp2); |
3529 return; | 3547 return; |
3530 } | 3548 } |
3531 } | 3549 } |
3532 UnimplementedLoweringError(this, Instr); | 3550 llvm::report_fatal_error("Source is i64 in i32-to-fp"); |
3533 break; | 3551 break; |
3534 } | 3552 } |
3535 case InstCast::Bitcast: { | 3553 case InstCast::Bitcast: { |
3536 Operand *Src0 = Instr->getSrc(0); | 3554 Operand *Src0 = Instr->getSrc(0); |
3537 if (DestTy == Src0->getType()) { | 3555 if (DestTy == Src0->getType()) { |
3538 auto *Assign = InstAssign::create(Func, Dest, Src0); | 3556 auto *Assign = InstAssign::create(Func, Dest, Src0); |
3539 lowerAssign(Assign); | 3557 lowerAssign(Assign); |
3540 return; | 3558 return; |
3541 } | 3559 } |
3542 if (isVectorType(DestTy) || isVectorType(Src0->getType())) { | 3560 if (isVectorType(DestTy) || isVectorType(Src0->getType())) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3591 _mov(Dest, RegHi, RegLo); | 3609 _mov(Dest, RegHi, RegLo); |
3592 } else { | 3610 } else { |
3593 auto *Var64On32 = llvm::cast<Variable64On32>(Src0); | 3611 auto *Var64On32 = llvm::cast<Variable64On32>(Src0); |
3594 auto *RegLo = legalizeToReg(loOperand(Var64On32)); | 3612 auto *RegLo = legalizeToReg(loOperand(Var64On32)); |
3595 auto *RegHi = legalizeToReg(hiOperand(Var64On32)); | 3613 auto *RegHi = legalizeToReg(hiOperand(Var64On32)); |
3596 _mov(Dest, RegHi, RegLo); | 3614 _mov(Dest, RegHi, RegLo); |
3597 } | 3615 } |
3598 break; | 3616 break; |
3599 } | 3617 } |
3600 default: | 3618 default: |
3601 UnimplementedLoweringError(this, Instr); | 3619 llvm::report_fatal_error("Unexpected bitcast."); |
3602 } | 3620 } |
3603 break; | 3621 break; |
3604 } | 3622 } |
3605 } | 3623 } |
3606 } | 3624 } |
3607 | 3625 |
3608 void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { | 3626 void TargetMIPS32::lowerExtractElement(const InstExtractElement *Instr) { |
3609 Variable *Dest = Instr->getDest(); | 3627 Variable *Dest = Instr->getDest(); |
3610 const Type DestTy = Dest->getType(); | 3628 const Type DestTy = Dest->getType(); |
3611 Operand *Src1 = Instr->getSrc(1); | 3629 Operand *Src1 = Instr->getSrc(1); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3683 InstFcmp::FCond Cond = Instr->getCondition(); | 3701 InstFcmp::FCond Cond = Instr->getCondition(); |
3684 auto *DestR = makeReg(IceType_i32); | 3702 auto *DestR = makeReg(IceType_i32); |
3685 auto *Src0R = legalizeToReg(Src0); | 3703 auto *Src0R = legalizeToReg(Src0); |
3686 auto *Src1R = legalizeToReg(Src1); | 3704 auto *Src1R = legalizeToReg(Src1); |
3687 const Type Src0Ty = Src0->getType(); | 3705 const Type Src0Ty = Src0->getType(); |
3688 | 3706 |
3689 Operand *FCC0 = OperandMIPS32FCC::create(getFunc(), OperandMIPS32FCC::FCC0); | 3707 Operand *FCC0 = OperandMIPS32FCC::create(getFunc(), OperandMIPS32FCC::FCC0); |
3690 | 3708 |
3691 switch (Cond) { | 3709 switch (Cond) { |
3692 default: { | 3710 default: { |
3693 UnimplementedLoweringError(this, Instr); | 3711 llvm::report_fatal_error("Unhandled fp comparison."); |
3694 return; | 3712 return; |
3695 } | 3713 } |
3696 case InstFcmp::False: { | 3714 case InstFcmp::False: { |
3697 Context.insert<InstFakeUse>(Src0R); | 3715 Context.insert<InstFakeUse>(Src0R); |
3698 Context.insert<InstFakeUse>(Src1R); | 3716 Context.insert<InstFakeUse>(Src1R); |
3699 _addiu(DestR, Zero, 0); | 3717 _addiu(DestR, Zero, 0); |
3700 _mov(Dest, DestR); | 3718 _mov(Dest, DestR); |
3701 break; | 3719 break; |
3702 } | 3720 } |
3703 case InstFcmp::Oeq: { | 3721 case InstFcmp::Oeq: { |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4228 } | 4246 } |
4229 } | 4247 } |
4230 // Write back temporary vector to the destination | 4248 // Write back temporary vector to the destination |
4231 auto *Assign = InstAssign::create(Func, Dest, TDest); | 4249 auto *Assign = InstAssign::create(Func, Dest, TDest); |
4232 lowerAssign(Assign); | 4250 lowerAssign(Assign); |
4233 return; | 4251 return; |
4234 } | 4252 } |
4235 llvm::report_fatal_error("InsertElement requires a constant index"); | 4253 llvm::report_fatal_error("InsertElement requires a constant index"); |
4236 } | 4254 } |
4237 | 4255 |
4256 void TargetMIPS32::createArithInst(uint32_t Operation, Variable *Dest, | |
Jim Stichnoth
2016/11/17 05:35:39
Can you declare Operation as Intrinsics::Intrinsic
sagar.thakur
2016/11/17 10:57:29
Done.
| |
4257 Variable *Src0, Variable *Src1) { | |
4258 switch (Operation) { | |
4259 default: | |
4260 llvm::report_fatal_error("Unknown AtomicRMW operation"); | |
4261 case Intrinsics::AtomicExchange: | |
4262 llvm::report_fatal_error("Can't handle Atomic xchg operation"); | |
4263 case Intrinsics::AtomicAdd: | |
4264 _addu(Dest, Src0, Src1); | |
4265 break; | |
4266 case Intrinsics::AtomicAnd: | |
4267 _and(Dest, Src0, Src1); | |
4268 break; | |
4269 case Intrinsics::AtomicSub: | |
4270 _subu(Dest, Src0, Src1); | |
4271 break; | |
4272 case Intrinsics::AtomicOr: | |
4273 _or(Dest, Src0, Src1); | |
4274 break; | |
4275 case Intrinsics::AtomicXor: | |
4276 _xor(Dest, Src0, Src1); | |
4277 break; | |
4278 } | |
4279 } | |
4280 | |
4238 void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { | 4281 void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
4239 Variable *Dest = Instr->getDest(); | 4282 Variable *Dest = Instr->getDest(); |
4240 Type DestTy = (Dest == nullptr) ? IceType_void : Dest->getType(); | 4283 Type DestTy = (Dest == nullptr) ? IceType_void : Dest->getType(); |
4284 | |
4285 Intrinsics::IntrinsicID ID = Instr->getIntrinsicInfo().ID; | |
4241 switch (Instr->getIntrinsicInfo().ID) { | 4286 switch (Instr->getIntrinsicInfo().ID) { |
Jim Stichnoth
2016/11/17 05:35:39
switch (ID) {
sagar.thakur
2016/11/17 10:57:28
Done.
| |
4287 case Intrinsics::AtomicLoad: { | |
4288 assert(isScalarIntegerType(DestTy)); | |
4289 // We require the memory address to be naturally aligned. Given that is the | |
4290 // case, then normal loads are atomic. | |
4291 if (!Intrinsics::isMemoryOrderValid( | |
4292 ID, getConstantMemoryOrder(Instr->getArg(1)))) { | |
4293 Func->setError("Unexpected memory ordering for AtomicLoad"); | |
4294 return; | |
4295 } | |
4296 if (DestTy == IceType_i64) { | |
4297 auto *Base = legalizeToReg(Instr->getArg(0)); | |
4298 auto *AddrLo = OperandMIPS32Mem::create( | |
4299 Func, IceType_i32, Base, | |
4300 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0))); | |
4301 auto *AddrHi = OperandMIPS32Mem::create( | |
4302 Func, IceType_i32, Base, | |
4303 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); | |
4304 Variable *T_Lo = makeReg(IceType_i32); | |
4305 Variable *T_Hi = makeReg(IceType_i32); | |
4306 auto *Dest64 = llvm::cast<Variable64On32>(Dest); | |
4307 lowerLoad(InstLoad::create(Func, T_Lo, AddrLo, IceType_i32)); | |
4308 lowerLoad(InstLoad::create(Func, T_Hi, AddrHi, IceType_i32)); | |
4309 _sync(); | |
4310 _mov(Dest64->getLo(), T_Lo); | |
4311 _mov(Dest64->getHi(), T_Hi); | |
4312 // Adding a fake-use of T to ensure the atomic load is not removed | |
Jim Stichnoth
2016/11/17 05:35:39
Reflow this and other comments to 80-col
sagar.thakur
2016/11/17 10:57:28
Done.
| |
4313 // if Dest is unused. | |
4314 Context.insert<InstFakeUse>(T_Lo); | |
4315 Context.insert<InstFakeUse>(T_Hi); | |
4316 } else { | |
4317 Variable *T = makeReg(DestTy); | |
4318 lowerLoad(InstLoad::create(Func, T, | |
4319 formMemoryOperand(Instr->getArg(0), DestTy))); | |
4320 _sync(); | |
4321 _mov(Dest, T); | |
4322 // Adding a fake-use of T to ensure the atomic load is not removed | |
4323 // if Dest is unused. | |
4324 Context.insert<InstFakeUse>(T); | |
4325 } | |
4326 return; | |
4327 } | |
4328 case Intrinsics::AtomicStore: { | |
4329 // We require the memory address to be naturally aligned. Given that is the | |
4330 // case, then normal stores are atomic. | |
4331 if (!Intrinsics::isMemoryOrderValid( | |
4332 ID, getConstantMemoryOrder(Instr->getArg(2)))) { | |
4333 Func->setError("Unexpected memory ordering for AtomicLoad"); | |
Jim Stichnoth
2016/11/17 05:35:39
AtomicStore
sagar.thakur
2016/11/17 10:57:28
Done.
| |
4334 return; | |
4335 } | |
4336 auto *Val = Instr->getArg(0); | |
4337 auto Ty = Val->getType(); | |
4338 if (Ty == IceType_i64) { | |
4339 Variable *ValHi, *ValLo; | |
4340 _sync(); | |
4341 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Val)) { | |
4342 const uint64_t Value = C64->getValue(); | |
4343 uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF; | |
4344 uint64_t Lower32Bits = Value & 0XFFFFFFFF; | |
Jim Stichnoth
2016/11/17 05:35:39
lowercase 'x' for consistency
(here and below)
sagar.thakur
2016/11/17 10:57:28
Done.
| |
4345 ValLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits)); | |
4346 ValHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits)); | |
4347 } else { | |
4348 auto *Val64 = llvm::cast<Variable64On32>(Val); | |
4349 ValLo = legalizeToReg(loOperand(Val64)); | |
4350 ValHi = legalizeToReg(hiOperand(Val64)); | |
4351 } | |
4352 | |
4353 auto *Base = legalizeToReg(Instr->getArg(1)); | |
4354 auto *AddrLo = OperandMIPS32Mem::create( | |
4355 Func, IceType_i32, Base, | |
4356 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0))); | |
4357 auto *AddrHi = OperandMIPS32Mem::create( | |
4358 Func, IceType_i32, Base, | |
4359 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); | |
4360 lowerStore(InstStore::create(Func, ValLo, AddrLo, IceType_i32)); | |
4361 lowerStore(InstStore::create(Func, ValHi, AddrHi, IceType_i32)); | |
4362 _sync(); | |
4363 } else { | |
4364 _sync(); | |
4365 Variable *Val = legalizeToReg(Instr->getArg(0)); | |
4366 lowerStore(InstStore::create( | |
4367 Func, Val, formMemoryOperand(Instr->getArg(1), DestTy))); | |
4368 _sync(); | |
4369 } | |
4370 return; | |
4371 } | |
4242 case Intrinsics::AtomicCmpxchg: { | 4372 case Intrinsics::AtomicCmpxchg: { |
4243 UnimplementedLoweringError(this, Instr); | 4373 assert(isScalarIntegerType(DestTy)); |
4374 // We require the memory address to be naturally aligned. Given that is the | |
4375 // case, then normal loads are atomic. | |
4376 if (!Intrinsics::isMemoryOrderValid( | |
4377 ID, getConstantMemoryOrder(Instr->getArg(3)), | |
4378 getConstantMemoryOrder(Instr->getArg(4)))) { | |
4379 Func->setError("Unexpected memory ordering for AtomicCmpxchg"); | |
4380 return; | |
4381 } | |
4382 | |
4383 InstMIPS32Label *Label1 = InstMIPS32Label::create(Func, this); | |
4384 constexpr CfgNode *NoTarget = nullptr; | |
4385 auto *RegAt = getPhysicalRegister(RegMIPS32::Reg_AT); | |
4386 Variable *T1 = I32Reg(); | |
4387 Variable *T2 = I32Reg(); | |
4388 Variable *T3 = I32Reg(); | |
4389 Variable *T4 = I32Reg(); | |
4390 Variable *T5 = I32Reg(); | |
4391 Variable *T6 = I32Reg(); | |
4392 Variable *T7 = I32Reg(); | |
4393 Variable *T8 = I32Reg(); | |
4394 Variable *T9 = I32Reg(); | |
4395 | |
4396 if (DestTy == IceType_i64) { | |
4397 InstMIPS32Label *Retry1 = InstMIPS32Label::create(Func, this); | |
4398 InstMIPS32Label *Retry2 = InstMIPS32Label::create(Func, this); | |
4399 _sync(); | |
4400 Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi; | |
4401 Operand *Expected = Instr->getArg(1); | |
4402 if (llvm::isa<ConstantUndef>(Expected)) { | |
4403 ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32)); | |
4404 ExpectedHi = legalizeToReg(Ctx->getConstantZero(IceType_i32)); | |
4405 } else { | |
4406 auto *Expected64 = llvm::cast<Variable64On32>(Expected); | |
4407 ExpectedLo = legalizeToReg(loOperand(Expected64)); | |
4408 ExpectedHi = legalizeToReg(hiOperand(Expected64)); | |
4409 } | |
4410 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Instr->getArg(2))) { | |
4411 const uint64_t Value = C64->getValue(); | |
4412 uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF; | |
4413 uint64_t Lower32Bits = Value & 0XFFFFFFFF; | |
4414 ValLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits)); | |
4415 ValHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits)); | |
4416 } else { | |
4417 auto *Val = llvm::cast<Variable64On32>(Instr->getArg(2)); | |
4418 ValLo = legalizeToReg(loOperand(Val)); | |
4419 ValHi = legalizeToReg(hiOperand(Val)); | |
4420 } | |
4421 auto *Dest64 = llvm::cast<Variable64On32>(Dest); | |
4422 auto *Base = legalizeToReg(Instr->getArg(0)); | |
4423 auto *AddrLo = OperandMIPS32Mem::create( | |
4424 Func, IceType_i32, Base, | |
4425 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0))); | |
4426 auto *AddrHi = OperandMIPS32Mem::create( | |
4427 Func, IceType_i32, Base, | |
4428 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); | |
4429 | |
4430 Context.insert(Retry1); | |
4431 _ll(T1, AddrLo); | |
4432 _br(NoTarget, NoTarget, T1, ExpectedLo, Label1, CondMIPS32::Cond::NE); | |
4433 _sc(ValLo, AddrLo); | |
4434 _br(NoTarget, NoTarget, ValLo, getZero(), Retry1, CondMIPS32::Cond::EQ); | |
4435 _mov(Dest64->getLo(), T1); | |
4436 Context.insert(Retry2); | |
4437 _ll(T2, AddrHi); | |
4438 _br(NoTarget, NoTarget, T2, ExpectedHi, Label1, CondMIPS32::Cond::NE); | |
4439 _sc(ValHi, AddrHi); | |
4440 _br(NoTarget, NoTarget, ValHi, getZero(), Retry2, CondMIPS32::Cond::EQ); | |
4441 _mov(Dest64->getHi(), T2); | |
4442 _br(NoTarget, Label1); | |
4443 Context.insert<InstFakeUse>(getZero()); | |
4444 | |
4445 Context.insert(Label1); | |
4446 _sync(); | |
4447 return; | |
4448 } | |
4449 | |
4450 auto *New = legalizeToReg(Instr->getArg(2)); | |
4451 auto *Expected = legalizeToReg(Instr->getArg(1)); | |
4452 auto *ActualAddress = legalizeToReg(Instr->getArg(0)); | |
4453 InstMIPS32Label *Label2 = InstMIPS32Label::create(Func, this); | |
4454 | |
4455 const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(DestTy))) - 1; | |
4456 | |
4457 if (DestTy == IceType_i8 || DestTy == IceType_i16) { | |
4458 const uint32_t ShiftAmount = | |
4459 (INT32_BITS - CHAR_BITS * typeWidthInBytes(DestTy)); | |
4460 _sync(); | |
4461 _addiu(RegAt, getZero(), -4); | |
4462 _and(T1, ActualAddress, RegAt); | |
4463 _andi(RegAt, ActualAddress, 3); | |
4464 _sll(T2, RegAt, 3); | |
4465 _ori(RegAt, getZero(), Mask); | |
4466 _sllv(T3, RegAt, T2); | |
4467 _nor(T4, getZero(), T3); | |
4468 _andi(RegAt, Expected, Mask); | |
4469 _sllv(T5, RegAt, T2); | |
4470 _andi(RegAt, New, Mask); | |
4471 _sllv(T6, RegAt, T2); | |
4472 | |
4473 Context.insert(Label1); | |
4474 _ll(T7, formMemoryOperand(T1, DestTy)); | |
4475 _and(T8, T7, T3); | |
4476 _br(NoTarget, NoTarget, T8, T5, Label2, CondMIPS32::Cond::NE); | |
4477 _and(RegAt, T7, T4); | |
4478 _or(T9, RegAt, T6); | |
4479 _sc(T9, formMemoryOperand(T1, DestTy)); | |
4480 _br(NoTarget, NoTarget, getZero(), T9, Label1, CondMIPS32::Cond::EQ); | |
4481 Context.insert<InstFakeUse>(getZero()); | |
4482 Context.insert(Label2); | |
4483 _srlv(RegAt, T8, T2); | |
4484 _sll(RegAt, RegAt, ShiftAmount); | |
4485 _sra(RegAt, RegAt, ShiftAmount); | |
4486 _mov(Dest, RegAt); | |
4487 _sync(); | |
4488 } else { | |
4489 _sync(); | |
4490 Context.insert(Label1); | |
4491 _ll(T1, formMemoryOperand(ActualAddress, DestTy)); | |
4492 _br(NoTarget, NoTarget, T1, Expected, Label2, CondMIPS32::Cond::NE); | |
4493 _sc(New, formMemoryOperand(ActualAddress, DestTy)); | |
4494 _br(NoTarget, NoTarget, New, getZero(), Label1, CondMIPS32::Cond::EQ); | |
4495 Context.insert<InstFakeUse>(getZero()); | |
4496 Context.insert(Label2); | |
4497 _sync(); | |
4498 _mov(Dest, T1); | |
4499 } | |
4500 | |
4501 Context.insert<InstFakeUse>(Expected); | |
4502 Context.insert<InstFakeUse>(New); | |
4503 return; | |
4504 } | |
4505 case Intrinsics::AtomicRMW: { | |
4506 assert(isScalarIntegerType(DestTy)); | |
4507 // We require the memory address to be naturally aligned. Given that is the | |
4508 // case, then normal loads are atomic. | |
4509 if (!Intrinsics::isMemoryOrderValid( | |
4510 ID, getConstantMemoryOrder(Instr->getArg(3)))) { | |
4511 Func->setError("Unexpected memory ordering for AtomicCmpxchg"); | |
Jim Stichnoth
2016/11/17 05:35:39
AtomicRMW
sagar.thakur
2016/11/17 10:57:29
Done.
| |
4512 return; | |
4513 } | |
4514 | |
4515 auto *RegAt = getPhysicalRegister(RegMIPS32::Reg_AT); | |
4516 Variable *T1 = I32Reg(); | |
4517 Variable *T2 = I32Reg(); | |
4518 Variable *T3 = I32Reg(); | |
4519 Variable *T4 = I32Reg(); | |
4520 Variable *T5 = I32Reg(); | |
4521 Variable *T6 = I32Reg(); | |
4522 Variable *T7 = I32Reg(); | |
4523 constexpr CfgNode *NoTarget = nullptr; | |
4524 InstMIPS32Label *Label1 = InstMIPS32Label::create(Func, this); | |
4525 uint32_t Operation = static_cast<uint32_t>( | |
Jim Stichnoth
2016/11/17 05:35:39
Can it be like this:
auto Operation = static_ca
sagar.thakur
2016/11/17 10:57:29
Done.
| |
4526 llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue()); | |
4527 | |
4528 if (DestTy == IceType_i64) { | |
4529 InstMIPS32Label *Label2 = InstMIPS32Label::create(Func, this); | |
4530 _sync(); | |
4531 Variable *ValHi, *ValLo; | |
4532 if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Instr->getArg(2))) { | |
4533 const uint64_t Value = C64->getValue(); | |
4534 uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF; | |
4535 uint64_t Lower32Bits = Value & 0xFFFFFFFF; | |
4536 ValLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits)); | |
4537 ValHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits)); | |
4538 } else { | |
4539 auto *Val = llvm::cast<Variable64On32>(Instr->getArg(2)); | |
4540 ValLo = legalizeToReg(loOperand(Val)); | |
4541 ValHi = legalizeToReg(hiOperand(Val)); | |
4542 } | |
4543 auto *Dest64 = llvm::cast<Variable64On32>(Dest); | |
4544 auto *Base = legalizeToReg(Instr->getArg(1)); | |
4545 auto *AddrLo = OperandMIPS32Mem::create( | |
4546 Func, IceType_i32, Base, | |
4547 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0))); | |
4548 auto *AddrHi = OperandMIPS32Mem::create( | |
4549 Func, IceType_i32, Base, | |
4550 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); | |
4551 | |
4552 Context.insert(Label1); | |
4553 _ll(T1, AddrLo); | |
4554 if (Operation == Intrinsics::AtomicExchange) { | |
4555 _mov(RegAt, ValLo); | |
4556 } else if (Operation == Intrinsics::AtomicAdd) { | |
4557 createArithInst(Operation, RegAt, T1, ValLo); | |
4558 _sltu(T2, RegAt, T1); | |
4559 } else if (Operation == Intrinsics::AtomicSub) { | |
4560 createArithInst(Operation, RegAt, T1, ValLo); | |
4561 _sltu(T2, T1, ValLo); | |
4562 } else { | |
4563 createArithInst(Operation, RegAt, T1, ValLo); | |
4564 } | |
4565 _sc(RegAt, AddrLo); | |
4566 _br(NoTarget, NoTarget, RegAt, getZero(), Label1, CondMIPS32::Cond::EQ); | |
4567 Context.insert<InstFakeUse>(getZero()); | |
4568 _mov(Dest64->getLo(), T1); | |
4569 | |
4570 Context.insert(Label2); | |
4571 _ll(T3, AddrHi); | |
4572 if (Operation == Intrinsics::AtomicAdd || | |
4573 Operation == Intrinsics::AtomicSub) { | |
4574 _addu(RegAt, T2, ValHi); | |
4575 createArithInst(Operation, RegAt, T3, RegAt); | |
4576 } else if (Operation == Intrinsics::AtomicExchange) { | |
4577 _mov(RegAt, ValHi); | |
4578 } else { | |
4579 createArithInst(Operation, RegAt, T3, ValHi); | |
4580 } | |
4581 _sc(RegAt, AddrHi); | |
4582 _br(NoTarget, NoTarget, RegAt, getZero(), Label2, CondMIPS32::Cond::EQ); | |
4583 Context.insert<InstFakeUse>(getZero()); | |
4584 _mov(Dest64->getHi(), T3); | |
4585 Context.insert<InstFakeUse>(ValLo); | |
4586 Context.insert<InstFakeUse>(ValHi); | |
4587 _sync(); | |
4588 return; | |
4589 } | |
4590 | |
4591 auto *New = legalizeToReg(Instr->getArg(2)); | |
4592 auto *ActualAddress = legalizeToReg(Instr->getArg(1)); | |
4593 | |
4594 const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(DestTy))) - 1; | |
4595 | |
4596 if (DestTy == IceType_i8 || DestTy == IceType_i16) { | |
4597 const uint32_t ShiftAmount = | |
4598 INT32_BITS - (CHAR_BITS * typeWidthInBytes(DestTy)); | |
4599 _sync(); | |
4600 _addiu(RegAt, getZero(), -4); | |
4601 _and(T1, ActualAddress, RegAt); | |
4602 _andi(RegAt, ActualAddress, 3); | |
4603 _sll(T2, RegAt, 3); | |
4604 _ori(RegAt, getZero(), Mask); | |
4605 _sllv(T3, RegAt, T2); | |
4606 _nor(T4, getZero(), T3); | |
4607 _sllv(T5, New, T2); | |
4608 Context.insert(Label1); | |
4609 _ll(T6, formMemoryOperand(T1, DestTy)); | |
4610 if (Operation == Intrinsics::AtomicExchange) { | |
4611 _mov(RegAt, T6); | |
4612 } else { | |
4613 createArithInst(Operation, RegAt, T6, T5); | |
4614 _and(RegAt, RegAt, T3); | |
4615 } | |
4616 _and(T7, T6, T4); | |
4617 _or(RegAt, T7, RegAt); | |
4618 _sc(RegAt, formMemoryOperand(T1, DestTy)); | |
4619 _br(NoTarget, NoTarget, RegAt, getZero(), Label1, CondMIPS32::Cond::EQ); | |
4620 Context.insert<InstFakeUse>(getZero()); | |
4621 _and(RegAt, T6, T3); | |
4622 _srlv(RegAt, RegAt, T2); | |
4623 _sll(RegAt, RegAt, ShiftAmount); | |
4624 _sra(RegAt, RegAt, ShiftAmount); | |
4625 _mov(Dest, RegAt); | |
4626 _sync(); | |
4627 } else { | |
4628 _sync(); | |
4629 Context.insert(Label1); | |
4630 _ll(T1, formMemoryOperand(ActualAddress, DestTy)); | |
4631 if (Operation == Intrinsics::AtomicExchange) { | |
4632 _mov(T2, New); | |
4633 } else { | |
4634 createArithInst(Operation, T2, T1, New); | |
4635 } | |
4636 _sc(T2, formMemoryOperand(ActualAddress, DestTy)); | |
4637 _br(NoTarget, NoTarget, T2, getZero(), Label1, CondMIPS32::Cond::EQ); | |
4638 Context.insert<InstFakeUse>(getZero()); | |
4639 _mov(Dest, T1); | |
4640 _sync(); | |
4641 } | |
4642 | |
4643 Context.insert<InstFakeUse>(Dest); | |
4644 Context.insert<InstFakeUse>(New); | |
4244 return; | 4645 return; |
4245 } | 4646 } |
4246 case Intrinsics::AtomicFence: | 4647 case Intrinsics::AtomicFence: |
4247 UnimplementedLoweringError(this, Instr); | |
4248 return; | |
4249 case Intrinsics::AtomicFenceAll: | 4648 case Intrinsics::AtomicFenceAll: |
4250 // NOTE: FenceAll should prevent and load/store from being moved across the | 4649 assert(Dest == nullptr); |
4251 // fence (both atomic and non-atomic). The InstMIPS32Mfence instruction is | 4650 _sync(); |
4252 // currently marked coarsely as "HasSideEffects". | |
4253 UnimplementedLoweringError(this, Instr); | |
4254 return; | 4651 return; |
4255 case Intrinsics::AtomicIsLockFree: { | 4652 case Intrinsics::AtomicIsLockFree: { |
4256 UnimplementedLoweringError(this, Instr); | 4653 Operand *ByteSize = Instr->getArg(0); |
4257 return; | 4654 auto *CI = llvm::dyn_cast<ConstantInteger32>(ByteSize); |
4258 } | 4655 auto *T = I32Reg(); |
4259 case Intrinsics::AtomicLoad: { | 4656 if (CI == nullptr) { |
4260 UnimplementedLoweringError(this, Instr); | 4657 // The PNaCl ABI requires the byte size to be a compile-time constant. |
4261 return; | 4658 Func->setError("AtomicIsLockFree byte size should be compile-time const"); |
4262 } | 4659 return; |
4263 case Intrinsics::AtomicRMW: | 4660 } |
4264 UnimplementedLoweringError(this, Instr); | 4661 static constexpr int32_t NotLockFree = 0; |
4265 return; | 4662 static constexpr int32_t LockFree = 1; |
4266 case Intrinsics::AtomicStore: { | 4663 int32_t Result = NotLockFree; |
4267 UnimplementedLoweringError(this, Instr); | 4664 switch (CI->getValue()) { |
4665 case 1: | |
4666 case 2: | |
4667 case 4: | |
4668 case 8: | |
4669 Result = LockFree; | |
4670 break; | |
4671 } | |
4672 _addiu(T, getZero(), Result); | |
4673 _mov(Dest, T); | |
4268 return; | 4674 return; |
4269 } | 4675 } |
4270 case Intrinsics::Bswap: { | 4676 case Intrinsics::Bswap: { |
4271 auto *Src = Instr->getArg(0); | 4677 auto *Src = Instr->getArg(0); |
4272 const Type SrcTy = Src->getType(); | 4678 const Type SrcTy = Src->getType(); |
4273 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 || | 4679 assert(SrcTy == IceType_i16 || SrcTy == IceType_i32 || |
4274 SrcTy == IceType_i64); | 4680 SrcTy == IceType_i64); |
4275 switch (SrcTy) { | 4681 switch (SrcTy) { |
4276 case IceType_i16: { | 4682 case IceType_i16: { |
4277 auto *T1 = I32Reg(); | 4683 auto *T1 = I32Reg(); |
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4928 break; | 5334 break; |
4929 case IceType_f32: | 5335 case IceType_f32: |
4930 _movn_s(SrcFR, SrcTR, ConditionR); | 5336 _movn_s(SrcFR, SrcTR, ConditionR); |
4931 _mov(Dest, SrcFR); | 5337 _mov(Dest, SrcFR); |
4932 break; | 5338 break; |
4933 case IceType_f64: | 5339 case IceType_f64: |
4934 _movn_d(SrcFR, SrcTR, ConditionR); | 5340 _movn_d(SrcFR, SrcTR, ConditionR); |
4935 _mov(Dest, SrcFR); | 5341 _mov(Dest, SrcFR); |
4936 break; | 5342 break; |
4937 default: | 5343 default: |
4938 UnimplementedLoweringError(this, Instr); | 5344 llvm::report_fatal_error("Select: Invalid type."); |
4939 } | 5345 } |
4940 } | 5346 } |
4941 | 5347 |
4942 void TargetMIPS32::lowerShuffleVector(const InstShuffleVector *Instr) { | 5348 void TargetMIPS32::lowerShuffleVector(const InstShuffleVector *Instr) { |
4943 UnimplementedLoweringError(this, Instr); | 5349 UnimplementedLoweringError(this, Instr); |
4944 } | 5350 } |
4945 | 5351 |
4946 void TargetMIPS32::lowerStore(const InstStore *Instr) { | 5352 void TargetMIPS32::lowerStore(const InstStore *Instr) { |
4947 Operand *Value = Instr->getData(); | 5353 Operand *Value = Instr->getData(); |
4948 Operand *Addr = Instr->getAddr(); | 5354 Operand *Addr = Instr->getAddr(); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5290 Variable *TReg = makeReg(Ty, RegNum); | 5696 Variable *TReg = makeReg(Ty, RegNum); |
5291 _lui(TReg, C, RO_Hi); | 5697 _lui(TReg, C, RO_Hi); |
5292 _addiu(Reg, TReg, C, RO_Lo); | 5698 _addiu(Reg, TReg, C, RO_Lo); |
5293 return Reg; | 5699 return Reg; |
5294 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { | 5700 } else if (auto *C32 = llvm::dyn_cast<ConstantInteger32>(From)) { |
5295 const uint32_t Value = C32->getValue(); | 5701 const uint32_t Value = C32->getValue(); |
5296 // Use addiu if the immediate is a 16bit value. Otherwise load it | 5702 // Use addiu if the immediate is a 16bit value. Otherwise load it |
5297 // using a lui-ori instructions. | 5703 // using a lui-ori instructions. |
5298 Variable *Reg = makeReg(Ty, RegNum); | 5704 Variable *Reg = makeReg(Ty, RegNum); |
5299 if (isInt<16>(int32_t(Value))) { | 5705 if (isInt<16>(int32_t(Value))) { |
5300 Variable *Zero = getPhysicalRegister(RegMIPS32::Reg_ZERO, Ty); | 5706 Variable *Zero = makeReg(Ty, RegMIPS32::Reg_ZERO); |
5301 Context.insert<InstFakeDef>(Zero); | 5707 Context.insert<InstFakeDef>(Zero); |
5302 _addiu(Reg, Zero, Value); | 5708 _addiu(Reg, Zero, Value); |
5303 } else { | 5709 } else { |
5304 uint32_t UpperBits = (Value >> 16) & 0xFFFF; | 5710 uint32_t UpperBits = (Value >> 16) & 0xFFFF; |
5305 uint32_t LowerBits = Value & 0xFFFF; | 5711 uint32_t LowerBits = Value & 0xFFFF; |
5306 Variable *TReg = makeReg(Ty, RegNum); | 5712 Variable *TReg = makeReg(Ty, RegNum); |
5307 if (LowerBits) { | 5713 if (LowerBits) { |
5308 _lui(TReg, Ctx->getConstantInt32(UpperBits)); | 5714 _lui(TReg, Ctx->getConstantInt32(UpperBits)); |
5309 _ori(Reg, TReg, LowerBits); | 5715 _ori(Reg, TReg, LowerBits); |
5310 } else { | 5716 } else { |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5538 | 5944 |
5539 InstMIPS32Call *TargetMIPS32::Sandboxer::jal(Variable *ReturnReg, | 5945 InstMIPS32Call *TargetMIPS32::Sandboxer::jal(Variable *ReturnReg, |
5540 Operand *CallTarget) { | 5946 Operand *CallTarget) { |
5541 if (Target->NeedSandboxing) | 5947 if (Target->NeedSandboxing) |
5542 createAutoBundle(); | 5948 createAutoBundle(); |
5543 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); | 5949 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); |
5544 } | 5950 } |
5545 | 5951 |
5546 } // end of namespace MIPS32 | 5952 } // end of namespace MIPS32 |
5547 } // end of namespace Ice | 5953 } // end of namespace Ice |
OLD | NEW |