Index: src/IceTargetLoweringMIPS32.cpp |
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp |
index 36650bdad05066182e43e0509a8c48bd0557769d..612744b40303d93be2e733cba133d0c6381d4e25 100644 |
--- a/src/IceTargetLoweringMIPS32.cpp |
+++ b/src/IceTargetLoweringMIPS32.cpp |
@@ -4330,8 +4330,8 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
Context.insert<InstFakeUse>(T_Hi); |
} else { |
auto *T = makeReg(DestTy); |
- lowerLoad(InstLoad::create(Func, T, |
- formMemoryOperand(Instr->getArg(0), DestTy))); |
+ auto *Base = legalizeToReg(Instr->getArg(0)); |
+ lowerLoad(InstLoad::create(Func, T, formMemoryOperand(Base, DestTy))); |
_sync(); |
_mov(Dest, T); |
// Adding a fake-use of T to ensure the atomic load is not removed if Dest |
@@ -4378,8 +4378,8 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
} else { |
_sync(); |
auto *Val = legalizeToReg(Instr->getArg(0)); |
- lowerStore(InstStore::create( |
- Func, Val, formMemoryOperand(Instr->getArg(1), DestTy))); |
+ auto *Base = legalizeToReg(Instr->getArg(1)); |
+ lowerStore(InstStore::create(Func, Val, formMemoryOperand(Base, DestTy))); |
_sync(); |
} |
return; |
@@ -4406,15 +4406,25 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
InstMIPS32Label *Retry1 = InstMIPS32Label::create(Func, this); |
auto *T1 = I32Reg(); |
auto *T2 = I32Reg(); |
+ auto *T3 = I32Reg(); |
+ auto *T4 = I32Reg(); |
_sync(); |
Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi; |
if (llvm::isa<ConstantUndef>(Expected)) { |
ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32)); |
ExpectedHi = legalizeToReg(Ctx->getConstantZero(IceType_i32)); |
- } else { |
- auto *Expected64 = llvm::cast<Variable64On32>(Expected); |
+ } else if (auto *Expected64 = llvm::dyn_cast<Variable64On32>(Expected)) { |
ExpectedLo = legalizeToReg(loOperand(Expected64)); |
ExpectedHi = legalizeToReg(hiOperand(Expected64)); |
+ } else if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(Expected)) { |
+ const uint64_t Value = C64->getValue(); |
+ uint64_t Upper32Bits = (Value >> INT32_BITS) & 0xFFFFFFFF; |
+ uint64_t Lower32Bits = Value & 0xFFFFFFFF; |
+ ExpectedLo = legalizeToReg(Ctx->getConstantInt32(Lower32Bits)); |
+ ExpectedHi = legalizeToReg(Ctx->getConstantInt32(Upper32Bits)); |
+ } else { |
+ llvm::report_fatal_error( |
+ "AtomicCmpxchg: getArg(1) is nor Constant neither Variable64On32"); |
} |
if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(New)) { |
const uint64_t Value = C64->getValue(); |
@@ -4435,20 +4445,22 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
auto *AddrHi = OperandMIPS32Mem::create( |
Func, IceType_i32, BaseR, |
llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); |
+ lowerLoad(InstLoad::create(Func, T3, AddrLo)); |
+ lowerLoad(InstLoad::create(Func, T4, AddrHi)); |
Context.insert(Retry); |
- _ll(T1, AddrLo); |
+ Sandboxer(this).ll(T1, AddrLo); |
_br(NoTarget, NoTarget, T1, ExpectedLo, Exit, CondMIPS32::Cond::NE); |
- _sc(ValLo, AddrLo); |
+ Sandboxer(this).sc(ValLo, AddrLo); |
_br(NoTarget, NoTarget, ValLo, getZero(), Retry, CondMIPS32::Cond::EQ); |
- _mov(Dest64->getLo(), T1); |
Context.insert(Retry1); |
- _ll(T2, AddrHi); |
+ Sandboxer(this).ll(T2, AddrHi); |
_br(NoTarget, NoTarget, T2, ExpectedHi, Exit, CondMIPS32::Cond::NE); |
- _sc(ValHi, AddrHi); |
+ Sandboxer(this).sc(ValHi, AddrHi); |
_br(NoTarget, NoTarget, ValHi, getZero(), Retry1, CondMIPS32::Cond::EQ); |
- _mov(Dest64->getHi(), T2); |
Context.insert<InstFakeUse>(getZero()); |
Context.insert(Exit); |
+ _mov(Dest64->getLo(), T3); |
+ _mov(Dest64->getHi(), T4); |
_sync(); |
} else if (DestTy == IceType_i8 || DestTy == IceType_i16) { |
auto *NewR = legalizeToReg(New); |
@@ -4480,12 +4492,12 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
_andi(RegAt, NewR, Mask); |
_sllv(T6, RegAt, T2); |
Context.insert(Retry); |
- _ll(T7, formMemoryOperand(T1, DestTy)); |
+ Sandboxer(this).ll(T7, formMemoryOperand(T1, DestTy)); |
_and(T8, T7, T3); |
_br(NoTarget, NoTarget, T8, T5, Exit, CondMIPS32::Cond::NE); |
_and(RegAt, T7, T4); |
_or(T9, RegAt, T6); |
- _sc(T9, formMemoryOperand(T1, DestTy)); |
+ Sandboxer(this).sc(T9, formMemoryOperand(T1, DestTy)); |
_br(NoTarget, NoTarget, getZero(), T9, Retry, CondMIPS32::Cond::EQ); |
Context.insert<InstFakeUse>(getZero()); |
Context.insert(Exit); |
@@ -4498,14 +4510,14 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
Context.insert<InstFakeUse>(NewR); |
} else { |
auto *T1 = I32Reg(); |
+ _sync(); |
+ Context.insert(Retry); |
auto *NewR = legalizeToReg(New); |
auto *ExpectedR = legalizeToReg(Expected); |
auto *ActualAddressR = legalizeToReg(ActualAddress); |
- _sync(); |
- Context.insert(Retry); |
- _ll(T1, formMemoryOperand(ActualAddressR, DestTy)); |
+ Sandboxer(this).ll(T1, formMemoryOperand(ActualAddressR, DestTy)); |
_br(NoTarget, NoTarget, T1, ExpectedR, Exit, CondMIPS32::Cond::NE); |
- _sc(NewR, formMemoryOperand(ActualAddressR, DestTy)); |
+ Sandboxer(this).sc(NewR, formMemoryOperand(ActualAddressR, DestTy)); |
_br(NoTarget, NoTarget, NewR, getZero(), Retry, CondMIPS32::Cond::EQ); |
Context.insert<InstFakeUse>(getZero()); |
Context.insert(Exit); |
@@ -4561,9 +4573,10 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
auto *T2 = I32Reg(); |
auto *T3 = I32Reg(); |
Context.insert(Retry); |
- _ll(T1, AddrLo); |
+ Sandboxer(this).ll(T1, AddrLo); |
if (Operation == Intrinsics::AtomicExchange) { |
_mov(RegAt, ValLo); |
+ Context.insert<InstFakeUse>(T1); |
} else if (Operation == Intrinsics::AtomicAdd) { |
createArithInst(Operation, RegAt, T1, ValLo); |
_sltu(T2, RegAt, T1); |
@@ -4573,22 +4586,23 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
} else { |
createArithInst(Operation, RegAt, T1, ValLo); |
} |
- _sc(RegAt, AddrLo); |
+ Sandboxer(this).sc(RegAt, AddrLo); |
_br(NoTarget, NoTarget, RegAt, getZero(), Retry, CondMIPS32::Cond::EQ); |
Context.insert<InstFakeUse>(getZero()); |
_mov(Dest64->getLo(), T1); |
Context.insert(Retry1); |
- _ll(T3, AddrHi); |
+ Sandboxer(this).ll(T3, AddrHi); |
if (Operation == Intrinsics::AtomicAdd || |
Operation == Intrinsics::AtomicSub) { |
_addu(RegAt, T2, ValHi); |
createArithInst(Operation, RegAt, T3, RegAt); |
} else if (Operation == Intrinsics::AtomicExchange) { |
_mov(RegAt, ValHi); |
+ Context.insert<InstFakeUse>(T3); |
} else { |
createArithInst(Operation, RegAt, T3, ValHi); |
} |
- _sc(RegAt, AddrHi); |
+ Sandboxer(this).sc(RegAt, AddrHi); |
_br(NoTarget, NoTarget, RegAt, getZero(), Retry1, CondMIPS32::Cond::EQ); |
Context.insert<InstFakeUse>(getZero()); |
_mov(Dest64->getHi(), T3); |
@@ -4619,7 +4633,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
_nor(T4, getZero(), T3); |
_sllv(T5, NewR, T2); |
Context.insert(Retry); |
- _ll(T6, formMemoryOperand(T1, DestTy)); |
+ Sandboxer(this).ll(T6, formMemoryOperand(T1, DestTy)); |
if (Operation != Intrinsics::AtomicExchange) { |
createArithInst(Operation, RegAt, T6, T5); |
_and(RegAt, RegAt, T3); |
@@ -4630,7 +4644,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
} else { |
_or(RegAt, T7, RegAt); |
} |
- _sc(RegAt, formMemoryOperand(T1, DestTy)); |
+ Sandboxer(this).sc(RegAt, formMemoryOperand(T1, DestTy)); |
_br(NoTarget, NoTarget, RegAt, getZero(), Retry, CondMIPS32::Cond::EQ); |
Context.insert<InstFakeUse>(getZero()); |
_and(RegAt, T6, T3); |
@@ -4648,13 +4662,13 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
auto *ActualAddressR = legalizeToReg(ActualAddress); |
_sync(); |
Context.insert(Retry); |
- _ll(T1, formMemoryOperand(ActualAddressR, DestTy)); |
+ Sandboxer(this).ll(T1, formMemoryOperand(ActualAddressR, DestTy)); |
if (Operation == Intrinsics::AtomicExchange) { |
_mov(T2, NewR); |
} else { |
createArithInst(Operation, T2, T1, NewR); |
} |
- _sc(T2, formMemoryOperand(ActualAddressR, DestTy)); |
+ Sandboxer(this).sc(T2, formMemoryOperand(ActualAddressR, DestTy)); |
_br(NoTarget, NoTarget, T2, getZero(), Retry, CondMIPS32::Cond::EQ); |
Context.insert<InstFakeUse>(getZero()); |
_mov(Dest, T1); |
@@ -4685,7 +4699,6 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
case 1: |
case 2: |
case 4: |
- case 8: |
Result = LockFree; |
break; |
} |
@@ -4917,12 +4930,15 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
return; |
} |
case Intrinsics::NaClReadTP: { |
- if (getFlags().getUseSandboxing()) { |
- UnimplementedLoweringError(this, Instr); |
- } else { |
- InstCall *Call = |
- makeHelperCall(RuntimeHelper::H_call_read_tp, Instr->getDest(), 0); |
- lowerCall(Call); |
+ if (SandboxingType != ST_NaCl) |
+ llvm::report_fatal_error("nacl-read-tp should have been prelowered."); |
+ else { |
+ auto *T8 = makeReg(IceType_i32, RegMIPS32::Reg_T8); |
+ Context.insert<InstFakeDef>(T8); |
+ Variable *TP = legalizeToReg(OperandMIPS32Mem::create( |
+ Func, getPointerType(), T8, |
+ llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32)))); |
+ _mov(Dest, TP); |
} |
return; |
} |
@@ -5892,7 +5908,8 @@ void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) { |
Target->_addiu(SP, SP, StackOffset); |
return; |
} |
- Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
createAutoBundle(); |
Target->_addiu(SP, SP, StackOffset); |
Target->_and(SP, SP, T7); |
@@ -5900,20 +5917,53 @@ void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) { |
void TargetMIPS32::Sandboxer::lw(Variable *Dest, OperandMIPS32Mem *Mem) { |
Variable *Base = Mem->getBase(); |
- Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
- if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
+ if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum()) && |
+ (RegMIPS32::Reg_T8 != Base->getRegNum())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
createAutoBundle(); |
Target->_and(Base, Base, T7); |
} |
Target->_lw(Dest, Mem); |
- if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) |
+ if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
+ Target->_and(Dest, Dest, T7); |
+ } |
+} |
+ |
+void TargetMIPS32::Sandboxer::ll(Variable *Dest, OperandMIPS32Mem *Mem) { |
+ Variable *Base = Mem->getBase(); |
+ if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
+ createAutoBundle(); |
+ Target->_and(Base, Base, T7); |
+ } |
+ Target->_ll(Dest, Mem); |
+ if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
Target->_and(Dest, Dest, T7); |
+ } |
+} |
+ |
+void TargetMIPS32::Sandboxer::sc(Variable *Dest, OperandMIPS32Mem *Mem) { |
+ Variable *Base = Mem->getBase(); |
+ if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
+ createAutoBundle(); |
+ Target->_and(Base, Base, T7); |
+ } |
+ Target->_sc(Dest, Mem); |
} |
void TargetMIPS32::Sandboxer::sw(Variable *Dest, OperandMIPS32Mem *Mem) { |
Variable *Base = Mem->getBase(); |
- Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
createAutoBundle(); |
Target->_and(Base, Base, T7); |
} |
@@ -5923,34 +5973,43 @@ void TargetMIPS32::Sandboxer::sw(Variable *Dest, OperandMIPS32Mem *Mem) { |
void TargetMIPS32::Sandboxer::lwc1(Variable *Dest, OperandMIPS32Mem *Mem, |
RelocOp Reloc) { |
Variable *Base = Mem->getBase(); |
- Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
createAutoBundle(); |
Target->_and(Base, Base, T7); |
} |
Target->_lwc1(Dest, Mem, Reloc); |
- if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) |
+ if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
Target->_and(Dest, Dest, T7); |
+ } |
} |
void TargetMIPS32::Sandboxer::ldc1(Variable *Dest, OperandMIPS32Mem *Mem, |
RelocOp Reloc) { |
Variable *Base = Mem->getBase(); |
- Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
if (Target->NeedSandboxing && (Target->getStackReg() != Base->getRegNum())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
createAutoBundle(); |
Target->_and(Base, Base, T7); |
} |
Target->_ldc1(Dest, Mem, Reloc); |
- if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) |
+ if (Target->NeedSandboxing && (Dest->getRegNum() == Target->getStackReg())) { |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
Target->_and(Dest, Dest, T7); |
+ } |
} |
void TargetMIPS32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) { |
if (!Target->NeedSandboxing) { |
Target->_ret(RetAddr, RetValue); |
} |
- Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6); |
+ auto *T6 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T6); |
+ Target->Context.insert<InstFakeDef>(T6); |
createAutoBundle(); |
Target->_and(RetAddr, RetAddr, T6); |
Target->_ret(RetAddr, RetValue); |
@@ -5962,7 +6021,8 @@ void TargetMIPS32::Sandboxer::reset_sp(Variable *Src) { |
Target->_mov(SP, Src); |
return; |
} |
- Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); |
+ auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7); |
+ Target->Context.insert<InstFakeDef>(T7); |
createAutoBundle(); |
Target->_mov(SP, Src); |
Target->_and(SP, SP, T7); |
@@ -5974,7 +6034,8 @@ InstMIPS32Call *TargetMIPS32::Sandboxer::jal(Variable *ReturnReg, |
if (Target->NeedSandboxing) { |
createAutoBundle(); |
if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) { |
- Variable *T6 = Target->getPhysicalRegister(RegMIPS32::Reg_T6); |
+ auto *T6 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T6); |
+ Target->Context.insert<InstFakeDef>(T6); |
Target->_and(CallTargetR, CallTargetR, T6); |
} |
} |