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 4536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4547 auto *New = Instr->getArg(2); | 4547 auto *New = Instr->getArg(2); |
4548 auto *Expected = Instr->getArg(1); | 4548 auto *Expected = Instr->getArg(1); |
4549 auto *ActualAddress = Instr->getArg(0); | 4549 auto *ActualAddress = Instr->getArg(0); |
4550 | 4550 |
4551 if (DestTy == IceType_i64) { | 4551 if (DestTy == IceType_i64) { |
4552 InstMIPS32Label *Retry1 = InstMIPS32Label::create(Func, this); | 4552 InstMIPS32Label *Retry1 = InstMIPS32Label::create(Func, this); |
4553 auto *T1 = I32Reg(); | 4553 auto *T1 = I32Reg(); |
4554 auto *T2 = I32Reg(); | 4554 auto *T2 = I32Reg(); |
4555 auto *T3 = I32Reg(); | 4555 auto *T3 = I32Reg(); |
4556 auto *T4 = I32Reg(); | 4556 auto *T4 = I32Reg(); |
4557 _sync(); | 4557 auto *T5 = I32Reg(); |
| 4558 auto *T6 = I32Reg(); |
4558 Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi; | 4559 Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi; |
4559 if (llvm::isa<ConstantUndef>(Expected)) { | 4560 if (llvm::isa<ConstantUndef>(Expected)) { |
4560 ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32)); | 4561 ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32)); |
4561 ExpectedHi = legalizeToReg(Ctx->getConstantZero(IceType_i32)); | 4562 ExpectedHi = legalizeToReg(Ctx->getConstantZero(IceType_i32)); |
4562 } else if (auto *Expected64 = llvm::dyn_cast<Variable64On32>(Expected)) { | 4563 } else if (auto *Expected64 = llvm::dyn_cast<Variable64On32>(Expected)) { |
4563 ExpectedLo = legalizeToReg(loOperand(Expected64)); | 4564 ExpectedLo = legalizeToReg(loOperand(Expected64)); |
4564 ExpectedHi = legalizeToReg(hiOperand(Expected64)); | 4565 ExpectedHi = legalizeToReg(hiOperand(Expected64)); |
4565 } else if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Expected)) { | 4566 } else if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Expected)) { |
4566 const uint64_t Value = C64->getValue(); | 4567 const uint64_t Value = C64->getValue(); |
4567 uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF; | 4568 uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF; |
(...skipping 18 matching lines...) Expand all Loading... |
4586 auto *Dest64 = llvm::cast<Variable64On32>(Dest); | 4587 auto *Dest64 = llvm::cast<Variable64On32>(Dest); |
4587 auto *BaseR = legalizeToReg(ActualAddress); | 4588 auto *BaseR = legalizeToReg(ActualAddress); |
4588 auto *AddrLo = OperandMIPS32Mem::create( | 4589 auto *AddrLo = OperandMIPS32Mem::create( |
4589 Func, IceType_i32, BaseR, | 4590 Func, IceType_i32, BaseR, |
4590 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0))); | 4591 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(0))); |
4591 auto *AddrHi = OperandMIPS32Mem::create( | 4592 auto *AddrHi = OperandMIPS32Mem::create( |
4592 Func, IceType_i32, BaseR, | 4593 Func, IceType_i32, BaseR, |
4593 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); | 4594 llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); |
4594 lowerLoad(InstLoad::create(Func, T3, AddrLo)); | 4595 lowerLoad(InstLoad::create(Func, T3, AddrLo)); |
4595 lowerLoad(InstLoad::create(Func, T4, AddrHi)); | 4596 lowerLoad(InstLoad::create(Func, T4, AddrHi)); |
| 4597 _sync(); |
4596 Context.insert(Retry); | 4598 Context.insert(Retry); |
4597 Sandboxer(this).ll(T1, AddrLo); | 4599 Sandboxer(this).ll(T1, AddrLo); |
4598 _br(NoTarget, NoTarget, T1, ExpectedLo, Exit, CondMIPS32::Cond::NE); | 4600 _br(NoTarget, NoTarget, T1, ExpectedLo, Exit, CondMIPS32::Cond::NE); |
4599 Sandboxer(this).sc(ValLo, AddrLo); | 4601 _mov(T5, ValLo); |
4600 _br(NoTarget, NoTarget, ValLo, getZero(), Retry, CondMIPS32::Cond::EQ); | 4602 Sandboxer(this).sc(T5, AddrLo); |
| 4603 Context.insert<InstFakeUse>(ValLo); |
| 4604 Context.insert<InstFakeUse>(ExpectedLo); |
| 4605 _br(NoTarget, NoTarget, T5, getZero(), Retry, CondMIPS32::Cond::EQ); |
4601 Context.insert(Retry1); | 4606 Context.insert(Retry1); |
4602 Sandboxer(this).ll(T2, AddrHi); | 4607 Sandboxer(this).ll(T2, AddrHi); |
4603 _br(NoTarget, NoTarget, T2, ExpectedHi, Exit, CondMIPS32::Cond::NE); | 4608 _br(NoTarget, NoTarget, T2, ExpectedHi, Exit, CondMIPS32::Cond::NE); |
4604 Sandboxer(this).sc(ValHi, AddrHi); | 4609 _mov(T6, ValHi); |
4605 _br(NoTarget, NoTarget, ValHi, getZero(), Retry1, CondMIPS32::Cond::EQ); | 4610 Sandboxer(this).sc(T6, AddrHi); |
| 4611 Context.insert<InstFakeUse>(ValHi); |
| 4612 Context.insert<InstFakeUse>(ExpectedHi); |
| 4613 _br(NoTarget, NoTarget, T6, getZero(), Retry1, CondMIPS32::Cond::EQ); |
4606 Context.insert<InstFakeUse>(getZero()); | 4614 Context.insert<InstFakeUse>(getZero()); |
4607 Context.insert(Exit); | 4615 Context.insert(Exit); |
4608 _mov(Dest64->getLo(), T3); | 4616 _mov(Dest64->getLo(), T3); |
4609 _mov(Dest64->getHi(), T4); | 4617 _mov(Dest64->getHi(), T4); |
4610 _sync(); | 4618 _sync(); |
4611 } else if (DestTy == IceType_i8 || DestTy == IceType_i16) { | 4619 } else if (DestTy == IceType_i8 || DestTy == IceType_i16) { |
4612 auto *NewR = legalizeToReg(New); | 4620 auto *NewR = legalizeToReg(New); |
4613 auto *ExpectedR = legalizeToReg(Expected); | 4621 auto *ExpectedR = legalizeToReg(Expected); |
4614 auto *ActualAddressR = legalizeToReg(ActualAddress); | 4622 auto *ActualAddressR = legalizeToReg(ActualAddress); |
4615 const uint32_t ShiftAmount = | 4623 const uint32_t ShiftAmount = |
4616 (INT32_BITS - CHAR_BITS * typeWidthInBytes(DestTy)); | 4624 (INT32_BITS - CHAR_BITS * typeWidthInBytes(DestTy)); |
4617 const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(DestTy))) - 1; | 4625 const uint32_t Mask = (1 << (CHAR_BITS * typeWidthInBytes(DestTy))) - 1; |
4618 auto *RegAt = getPhysicalRegister(RegMIPS32::Reg_AT); | 4626 auto *RegAt = getPhysicalRegister(RegMIPS32::Reg_AT); |
4619 auto *T1 = I32Reg(); | 4627 auto *T1 = I32Reg(); |
4620 auto *T2 = I32Reg(); | 4628 auto *T2 = I32Reg(); |
4621 auto *T3 = I32Reg(); | 4629 auto *T3 = I32Reg(); |
4622 auto *T4 = I32Reg(); | 4630 auto *T4 = I32Reg(); |
4623 auto *T5 = I32Reg(); | 4631 auto *T5 = I32Reg(); |
4624 auto *T6 = I32Reg(); | 4632 auto *T6 = I32Reg(); |
4625 auto *T7 = I32Reg(); | 4633 auto *T7 = I32Reg(); |
4626 auto *T8 = I32Reg(); | 4634 auto *T8 = I32Reg(); |
4627 auto *T9 = I32Reg(); | 4635 auto *T9 = I32Reg(); |
4628 _sync(); | |
4629 _addiu(RegAt, getZero(), -4); | 4636 _addiu(RegAt, getZero(), -4); |
4630 _and(T1, ActualAddressR, RegAt); | 4637 _and(T1, ActualAddressR, RegAt); |
4631 _andi(RegAt, ActualAddressR, 3); | 4638 _andi(RegAt, ActualAddressR, 3); |
4632 _sll(T2, RegAt, 3); | 4639 _sll(T2, RegAt, 3); |
4633 _ori(RegAt, getZero(), Mask); | 4640 _ori(RegAt, getZero(), Mask); |
4634 _sllv(T3, RegAt, T2); | 4641 _sllv(T3, RegAt, T2); |
4635 _nor(T4, getZero(), T3); | 4642 _nor(T4, getZero(), T3); |
4636 _andi(RegAt, ExpectedR, Mask); | 4643 _andi(RegAt, ExpectedR, Mask); |
4637 _sllv(T5, RegAt, T2); | 4644 _sllv(T5, RegAt, T2); |
4638 _andi(RegAt, NewR, Mask); | 4645 _andi(RegAt, NewR, Mask); |
4639 _sllv(T6, RegAt, T2); | 4646 _sllv(T6, RegAt, T2); |
| 4647 _sync(); |
4640 Context.insert(Retry); | 4648 Context.insert(Retry); |
4641 Sandboxer(this).ll(T7, formMemoryOperand(T1, DestTy)); | 4649 Sandboxer(this).ll(T7, formMemoryOperand(T1, DestTy)); |
4642 _and(T8, T7, T3); | 4650 _and(T8, T7, T3); |
4643 _br(NoTarget, NoTarget, T8, T5, Exit, CondMIPS32::Cond::NE); | 4651 _br(NoTarget, NoTarget, T8, T5, Exit, CondMIPS32::Cond::NE); |
4644 _and(RegAt, T7, T4); | 4652 _and(RegAt, T7, T4); |
4645 _or(T9, RegAt, T6); | 4653 _or(T9, RegAt, T6); |
4646 Sandboxer(this).sc(T9, formMemoryOperand(T1, DestTy)); | 4654 Sandboxer(this).sc(T9, formMemoryOperand(T1, DestTy)); |
| 4655 Context.insert<InstFakeUse>(T6); |
4647 _br(NoTarget, NoTarget, getZero(), T9, Retry, CondMIPS32::Cond::EQ); | 4656 _br(NoTarget, NoTarget, getZero(), T9, Retry, CondMIPS32::Cond::EQ); |
4648 Context.insert<InstFakeUse>(getZero()); | 4657 Context.insert<InstFakeUse>(getZero()); |
4649 Context.insert(Exit); | 4658 Context.insert(Exit); |
4650 _srlv(RegAt, T8, T2); | 4659 _srlv(RegAt, T8, T2); |
4651 _sll(RegAt, RegAt, ShiftAmount); | 4660 _sll(RegAt, RegAt, ShiftAmount); |
4652 _sra(RegAt, RegAt, ShiftAmount); | 4661 _sra(RegAt, RegAt, ShiftAmount); |
4653 _mov(Dest, RegAt); | 4662 _mov(Dest, RegAt); |
4654 _sync(); | 4663 _sync(); |
4655 Context.insert<InstFakeUse>(ExpectedR); | 4664 Context.insert<InstFakeUse>(ExpectedR); |
4656 Context.insert<InstFakeUse>(NewR); | 4665 Context.insert<InstFakeUse>(NewR); |
4657 } else { | 4666 } else { |
4658 auto *T1 = I32Reg(); | 4667 auto *T1 = I32Reg(); |
4659 _sync(); | 4668 auto *T2 = I32Reg(); |
4660 Context.insert(Retry); | |
4661 auto *NewR = legalizeToReg(New); | 4669 auto *NewR = legalizeToReg(New); |
4662 auto *ExpectedR = legalizeToReg(Expected); | 4670 auto *ExpectedR = legalizeToReg(Expected); |
4663 auto *ActualAddressR = legalizeToReg(ActualAddress); | 4671 auto *ActualAddressR = legalizeToReg(ActualAddress); |
| 4672 _sync(); |
| 4673 Context.insert(Retry); |
4664 Sandboxer(this).ll(T1, formMemoryOperand(ActualAddressR, DestTy)); | 4674 Sandboxer(this).ll(T1, formMemoryOperand(ActualAddressR, DestTy)); |
4665 _br(NoTarget, NoTarget, T1, ExpectedR, Exit, CondMIPS32::Cond::NE); | 4675 _br(NoTarget, NoTarget, T1, ExpectedR, Exit, CondMIPS32::Cond::NE); |
4666 Sandboxer(this).sc(NewR, formMemoryOperand(ActualAddressR, DestTy)); | 4676 _mov(T2, NewR); |
4667 _br(NoTarget, NoTarget, NewR, getZero(), Retry, CondMIPS32::Cond::EQ); | 4677 Sandboxer(this).sc(T2, formMemoryOperand(ActualAddressR, DestTy)); |
| 4678 _br(NoTarget, NoTarget, T2, getZero(), Retry, CondMIPS32::Cond::EQ); |
4668 Context.insert<InstFakeUse>(getZero()); | 4679 Context.insert<InstFakeUse>(getZero()); |
4669 Context.insert(Exit); | 4680 Context.insert(Exit); |
4670 _mov(Dest, T1); | 4681 _mov(Dest, T1); |
4671 _sync(); | 4682 _sync(); |
4672 Context.insert<InstFakeUse>(ExpectedR); | 4683 Context.insert<InstFakeUse>(ExpectedR); |
4673 Context.insert<InstFakeUse>(NewR); | 4684 Context.insert<InstFakeUse>(NewR); |
4674 } | 4685 } |
4675 return; | 4686 return; |
4676 } | 4687 } |
4677 case Intrinsics::AtomicRMW: { | 4688 case Intrinsics::AtomicRMW: { |
(...skipping 1505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6183 auto *T6 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T6); | 6194 auto *T6 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T6); |
6184 Target->Context.insert<InstFakeDef>(T6); | 6195 Target->Context.insert<InstFakeDef>(T6); |
6185 Target->_and(CallTargetR, CallTargetR, T6); | 6196 Target->_and(CallTargetR, CallTargetR, T6); |
6186 } | 6197 } |
6187 } | 6198 } |
6188 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); | 6199 return Target->Context.insert<InstMIPS32Call>(ReturnReg, CallTarget); |
6189 } | 6200 } |
6190 | 6201 |
6191 } // end of namespace MIPS32 | 6202 } // end of namespace MIPS32 |
6192 } // end of namespace Ice | 6203 } // end of namespace Ice |
OLD | NEW |