Commit 298d14e2 by Stefan Maksimovic Committed by Jim Stichnoth

Subzero, MIPS32: Atomic intrinsics fixes

This patch introduces changes to the MIPS32 intrinsic functions to comply with PNaCl smoke tests. Also made a change regarding addressing relative to frame pointer, since it differs in MIPS compared to ARM and x86. R=stichnot@chromium.org Patch from Stefan Maksimovic <makdstefan@gmail.com>. Review-Url: https://codereview.chromium.org/2619363003 .
parent 2bbda7f4
...@@ -939,7 +939,7 @@ void Cfg::sortAndCombineAllocas(CfgVector<InstAlloca *> &Allocas, ...@@ -939,7 +939,7 @@ void Cfg::sortAndCombineAllocas(CfgVector<InstAlloca *> &Allocas,
// Addressing is relative to the frame pointer. Subtract the offset after // Addressing is relative to the frame pointer. Subtract the offset after
// adding the size of the alloca, because it grows downwards from the // adding the size of the alloca, because it grows downwards from the
// frame pointer. // frame pointer.
Offsets.push_back(-(CurrentOffset + Size)); Offsets.push_back(Target->getFramePointerOffset(CurrentOffset, Size));
} else { } else {
// Addressing is relative to the stack pointer or to a user pointer. Add // Addressing is relative to the stack pointer or to a user pointer. Add
// the offset before adding the size of the object, because it grows // the offset before adding the size of the object, because it grows
......
...@@ -253,7 +253,13 @@ public: ...@@ -253,7 +253,13 @@ public:
virtual void reserveFixedAllocaArea(size_t Size, size_t Align) = 0; virtual void reserveFixedAllocaArea(size_t Size, size_t Align) = 0;
virtual int32_t getFrameFixedAllocaOffset() const = 0; virtual int32_t getFrameFixedAllocaOffset() const = 0;
virtual uint32_t maxOutArgsSizeBytes() const { return 0; } virtual uint32_t maxOutArgsSizeBytes() const { return 0; }
// Addressing relative to frame pointer differs in MIPS compared to X86/ARM
// since MIPS decrements its stack pointer prior to saving it in the frame
// pointer register.
virtual uint32_t getFramePointerOffset(uint32_t CurrentOffset,
uint32_t Size) const {
return -(CurrentOffset + Size);
}
/// Return whether a 64-bit Variable should be split into a Variable64On32. /// Return whether a 64-bit Variable should be split into a Variable64On32.
virtual bool shouldSplitToVariable64On32(Type Ty) const = 0; virtual bool shouldSplitToVariable64On32(Type Ty) const = 0;
......
...@@ -4476,8 +4476,8 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4476,8 +4476,8 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
Context.insert<InstFakeUse>(T_Hi); Context.insert<InstFakeUse>(T_Hi);
} else { } else {
auto *T = makeReg(DestTy); auto *T = makeReg(DestTy);
lowerLoad(InstLoad::create(Func, T, auto *Base = legalizeToReg(Instr->getArg(0));
formMemoryOperand(Instr->getArg(0), DestTy))); lowerLoad(InstLoad::create(Func, T, formMemoryOperand(Base, DestTy)));
_sync(); _sync();
_mov(Dest, T); _mov(Dest, T);
// Adding a fake-use of T to ensure the atomic load is not removed if Dest // Adding a fake-use of T to ensure the atomic load is not removed if Dest
...@@ -4524,8 +4524,8 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4524,8 +4524,8 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
} else { } else {
_sync(); _sync();
auto *Val = legalizeToReg(Instr->getArg(0)); auto *Val = legalizeToReg(Instr->getArg(0));
lowerStore(InstStore::create( auto *Base = legalizeToReg(Instr->getArg(1));
Func, Val, formMemoryOperand(Instr->getArg(1), DestTy))); lowerStore(InstStore::create(Func, Val, formMemoryOperand(Base, DestTy)));
_sync(); _sync();
} }
return; return;
...@@ -4552,15 +4552,25 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4552,15 +4552,25 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
InstMIPS32Label *Retry1 = InstMIPS32Label::create(Func, this); InstMIPS32Label *Retry1 = InstMIPS32Label::create(Func, this);
auto *T1 = I32Reg(); auto *T1 = I32Reg();
auto *T2 = I32Reg(); auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
_sync(); _sync();
Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi; Variable *ValHi, *ValLo, *ExpectedLo, *ExpectedHi;
if (llvm::isa<ConstantUndef>(Expected)) { if (llvm::isa<ConstantUndef>(Expected)) {
ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32)); ExpectedLo = legalizeToReg(Ctx->getConstantZero(IceType_i32));
ExpectedHi = legalizeToReg(Ctx->getConstantZero(IceType_i32)); ExpectedHi = legalizeToReg(Ctx->getConstantZero(IceType_i32));
} else { } else if (auto *Expected64 = llvm::dyn_cast<Variable64On32>(Expected)) {
auto *Expected64 = llvm::cast<Variable64On32>(Expected);
ExpectedLo = legalizeToReg(loOperand(Expected64)); ExpectedLo = legalizeToReg(loOperand(Expected64));
ExpectedHi = legalizeToReg(hiOperand(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)) { if (auto *C64 = llvm::dyn_cast<ConstantInteger64>(New)) {
const uint64_t Value = C64->getValue(); const uint64_t Value = C64->getValue();
...@@ -4581,20 +4591,22 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4581,20 +4591,22 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
auto *AddrHi = OperandMIPS32Mem::create( auto *AddrHi = OperandMIPS32Mem::create(
Func, IceType_i32, BaseR, Func, IceType_i32, BaseR,
llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4))); llvm::cast<ConstantInteger32>(Ctx->getConstantInt32(4)));
lowerLoad(InstLoad::create(Func, T3, AddrLo));
lowerLoad(InstLoad::create(Func, T4, AddrHi));
Context.insert(Retry); Context.insert(Retry);
_ll(T1, AddrLo); Sandboxer(this).ll(T1, AddrLo);
_br(NoTarget, NoTarget, T1, ExpectedLo, Exit, CondMIPS32::Cond::NE); _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); _br(NoTarget, NoTarget, ValLo, getZero(), Retry, CondMIPS32::Cond::EQ);
_mov(Dest64->getLo(), T1);
Context.insert(Retry1); Context.insert(Retry1);
_ll(T2, AddrHi); Sandboxer(this).ll(T2, AddrHi);
_br(NoTarget, NoTarget, T2, ExpectedHi, Exit, CondMIPS32::Cond::NE); _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); _br(NoTarget, NoTarget, ValHi, getZero(), Retry1, CondMIPS32::Cond::EQ);
_mov(Dest64->getHi(), T2);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
Context.insert(Exit); Context.insert(Exit);
_mov(Dest64->getLo(), T3);
_mov(Dest64->getHi(), T4);
_sync(); _sync();
} else if (DestTy == IceType_i8 || DestTy == IceType_i16) { } else if (DestTy == IceType_i8 || DestTy == IceType_i16) {
auto *NewR = legalizeToReg(New); auto *NewR = legalizeToReg(New);
...@@ -4626,12 +4638,12 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4626,12 +4638,12 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
_andi(RegAt, NewR, Mask); _andi(RegAt, NewR, Mask);
_sllv(T6, RegAt, T2); _sllv(T6, RegAt, T2);
Context.insert(Retry); Context.insert(Retry);
_ll(T7, formMemoryOperand(T1, DestTy)); Sandboxer(this).ll(T7, formMemoryOperand(T1, DestTy));
_and(T8, T7, T3); _and(T8, T7, T3);
_br(NoTarget, NoTarget, T8, T5, Exit, CondMIPS32::Cond::NE); _br(NoTarget, NoTarget, T8, T5, Exit, CondMIPS32::Cond::NE);
_and(RegAt, T7, T4); _and(RegAt, T7, T4);
_or(T9, RegAt, T6); _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); _br(NoTarget, NoTarget, getZero(), T9, Retry, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
Context.insert(Exit); Context.insert(Exit);
...@@ -4644,14 +4656,14 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4644,14 +4656,14 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
Context.insert<InstFakeUse>(NewR); Context.insert<InstFakeUse>(NewR);
} else { } else {
auto *T1 = I32Reg(); auto *T1 = I32Reg();
_sync();
Context.insert(Retry);
auto *NewR = legalizeToReg(New); auto *NewR = legalizeToReg(New);
auto *ExpectedR = legalizeToReg(Expected); auto *ExpectedR = legalizeToReg(Expected);
auto *ActualAddressR = legalizeToReg(ActualAddress); auto *ActualAddressR = legalizeToReg(ActualAddress);
_sync(); Sandboxer(this).ll(T1, formMemoryOperand(ActualAddressR, DestTy));
Context.insert(Retry);
_ll(T1, formMemoryOperand(ActualAddressR, DestTy));
_br(NoTarget, NoTarget, T1, ExpectedR, Exit, CondMIPS32::Cond::NE); _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); _br(NoTarget, NoTarget, NewR, getZero(), Retry, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
Context.insert(Exit); Context.insert(Exit);
...@@ -4707,9 +4719,10 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4707,9 +4719,10 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
auto *T2 = I32Reg(); auto *T2 = I32Reg();
auto *T3 = I32Reg(); auto *T3 = I32Reg();
Context.insert(Retry); Context.insert(Retry);
_ll(T1, AddrLo); Sandboxer(this).ll(T1, AddrLo);
if (Operation == Intrinsics::AtomicExchange) { if (Operation == Intrinsics::AtomicExchange) {
_mov(RegAt, ValLo); _mov(RegAt, ValLo);
Context.insert<InstFakeUse>(T1);
} else if (Operation == Intrinsics::AtomicAdd) { } else if (Operation == Intrinsics::AtomicAdd) {
createArithInst(Operation, RegAt, T1, ValLo); createArithInst(Operation, RegAt, T1, ValLo);
_sltu(T2, RegAt, T1); _sltu(T2, RegAt, T1);
...@@ -4719,22 +4732,23 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4719,22 +4732,23 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
} else { } else {
createArithInst(Operation, RegAt, T1, ValLo); createArithInst(Operation, RegAt, T1, ValLo);
} }
_sc(RegAt, AddrLo); Sandboxer(this).sc(RegAt, AddrLo);
_br(NoTarget, NoTarget, RegAt, getZero(), Retry, CondMIPS32::Cond::EQ); _br(NoTarget, NoTarget, RegAt, getZero(), Retry, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
_mov(Dest64->getLo(), T1); _mov(Dest64->getLo(), T1);
Context.insert(Retry1); Context.insert(Retry1);
_ll(T3, AddrHi); Sandboxer(this).ll(T3, AddrHi);
if (Operation == Intrinsics::AtomicAdd || if (Operation == Intrinsics::AtomicAdd ||
Operation == Intrinsics::AtomicSub) { Operation == Intrinsics::AtomicSub) {
_addu(RegAt, T2, ValHi); _addu(RegAt, T2, ValHi);
createArithInst(Operation, RegAt, T3, RegAt); createArithInst(Operation, RegAt, T3, RegAt);
} else if (Operation == Intrinsics::AtomicExchange) { } else if (Operation == Intrinsics::AtomicExchange) {
_mov(RegAt, ValHi); _mov(RegAt, ValHi);
Context.insert<InstFakeUse>(T3);
} else { } else {
createArithInst(Operation, RegAt, T3, ValHi); createArithInst(Operation, RegAt, T3, ValHi);
} }
_sc(RegAt, AddrHi); Sandboxer(this).sc(RegAt, AddrHi);
_br(NoTarget, NoTarget, RegAt, getZero(), Retry1, CondMIPS32::Cond::EQ); _br(NoTarget, NoTarget, RegAt, getZero(), Retry1, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
_mov(Dest64->getHi(), T3); _mov(Dest64->getHi(), T3);
...@@ -4765,7 +4779,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4765,7 +4779,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
_nor(T4, getZero(), T3); _nor(T4, getZero(), T3);
_sllv(T5, NewR, T2); _sllv(T5, NewR, T2);
Context.insert(Retry); Context.insert(Retry);
_ll(T6, formMemoryOperand(T1, DestTy)); Sandboxer(this).ll(T6, formMemoryOperand(T1, DestTy));
if (Operation != Intrinsics::AtomicExchange) { if (Operation != Intrinsics::AtomicExchange) {
createArithInst(Operation, RegAt, T6, T5); createArithInst(Operation, RegAt, T6, T5);
_and(RegAt, RegAt, T3); _and(RegAt, RegAt, T3);
...@@ -4776,7 +4790,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4776,7 +4790,7 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
} else { } else {
_or(RegAt, T7, RegAt); _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); _br(NoTarget, NoTarget, RegAt, getZero(), Retry, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
_and(RegAt, T6, T3); _and(RegAt, T6, T3);
...@@ -4794,13 +4808,13 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4794,13 +4808,13 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
auto *ActualAddressR = legalizeToReg(ActualAddress); auto *ActualAddressR = legalizeToReg(ActualAddress);
_sync(); _sync();
Context.insert(Retry); Context.insert(Retry);
_ll(T1, formMemoryOperand(ActualAddressR, DestTy)); Sandboxer(this).ll(T1, formMemoryOperand(ActualAddressR, DestTy));
if (Operation == Intrinsics::AtomicExchange) { if (Operation == Intrinsics::AtomicExchange) {
_mov(T2, NewR); _mov(T2, NewR);
} else { } else {
createArithInst(Operation, T2, T1, NewR); 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); _br(NoTarget, NoTarget, T2, getZero(), Retry, CondMIPS32::Cond::EQ);
Context.insert<InstFakeUse>(getZero()); Context.insert<InstFakeUse>(getZero());
_mov(Dest, T1); _mov(Dest, T1);
...@@ -4831,7 +4845,6 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -4831,7 +4845,6 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
case 1: case 1:
case 2: case 2:
case 4: case 4:
case 8:
Result = LockFree; Result = LockFree;
break; break;
} }
...@@ -5063,12 +5076,15 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { ...@@ -5063,12 +5076,15 @@ void TargetMIPS32::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return; return;
} }
case Intrinsics::NaClReadTP: { case Intrinsics::NaClReadTP: {
if (getFlags().getUseSandboxing()) { if (SandboxingType != ST_NaCl)
UnimplementedLoweringError(this, Instr); llvm::report_fatal_error("nacl-read-tp should have been prelowered.");
} else { else {
InstCall *Call = auto *T8 = makeReg(IceType_i32, RegMIPS32::Reg_T8);
makeHelperCall(RuntimeHelper::H_call_read_tp, Instr->getDest(), 0); Context.insert<InstFakeDef>(T8);
lowerCall(Call); Variable *TP = legalizeToReg(OperandMIPS32Mem::create(
Func, getPointerType(), T8,
llvm::cast<ConstantInteger32>(Ctx->getConstantZero(IceType_i32))));
_mov(Dest, TP);
} }
return; return;
} }
...@@ -6038,7 +6054,8 @@ void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) { ...@@ -6038,7 +6054,8 @@ void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) {
Target->_addiu(SP, SP, StackOffset); Target->_addiu(SP, SP, StackOffset);
return; return;
} }
Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7);
Target->Context.insert<InstFakeDef>(T7);
createAutoBundle(); createAutoBundle();
Target->_addiu(SP, SP, StackOffset); Target->_addiu(SP, SP, StackOffset);
Target->_and(SP, SP, T7); Target->_and(SP, SP, T7);
...@@ -6046,20 +6063,53 @@ void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) { ...@@ -6046,20 +6063,53 @@ void TargetMIPS32::Sandboxer::addiu_sp(uint32_t StackOffset) {
void TargetMIPS32::Sandboxer::lw(Variable *Dest, OperandMIPS32Mem *Mem) { void TargetMIPS32::Sandboxer::lw(Variable *Dest, OperandMIPS32Mem *Mem) {
Variable *Base = Mem->getBase(); 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(); createAutoBundle();
Target->_and(Base, Base, T7); Target->_and(Base, Base, T7);
} }
Target->_lw(Dest, Mem); 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); 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) { void TargetMIPS32::Sandboxer::sw(Variable *Dest, OperandMIPS32Mem *Mem) {
Variable *Base = Mem->getBase(); 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())) {
auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7);
Target->Context.insert<InstFakeDef>(T7);
createAutoBundle(); createAutoBundle();
Target->_and(Base, Base, T7); Target->_and(Base, Base, T7);
} }
...@@ -6069,34 +6119,43 @@ void TargetMIPS32::Sandboxer::sw(Variable *Dest, OperandMIPS32Mem *Mem) { ...@@ -6069,34 +6119,43 @@ void TargetMIPS32::Sandboxer::sw(Variable *Dest, OperandMIPS32Mem *Mem) {
void TargetMIPS32::Sandboxer::lwc1(Variable *Dest, OperandMIPS32Mem *Mem, void TargetMIPS32::Sandboxer::lwc1(Variable *Dest, OperandMIPS32Mem *Mem,
RelocOp Reloc) { RelocOp Reloc) {
Variable *Base = Mem->getBase(); 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())) {
auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7);
Target->Context.insert<InstFakeDef>(T7);
createAutoBundle(); createAutoBundle();
Target->_and(Base, Base, T7); Target->_and(Base, Base, T7);
} }
Target->_lwc1(Dest, Mem, Reloc); 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); Target->_and(Dest, Dest, T7);
}
} }
void TargetMIPS32::Sandboxer::ldc1(Variable *Dest, OperandMIPS32Mem *Mem, void TargetMIPS32::Sandboxer::ldc1(Variable *Dest, OperandMIPS32Mem *Mem,
RelocOp Reloc) { RelocOp Reloc) {
Variable *Base = Mem->getBase(); 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())) {
auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7);
Target->Context.insert<InstFakeDef>(T7);
createAutoBundle(); createAutoBundle();
Target->_and(Base, Base, T7); Target->_and(Base, Base, T7);
} }
Target->_ldc1(Dest, Mem, Reloc); 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); Target->_and(Dest, Dest, T7);
}
} }
void TargetMIPS32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) { void TargetMIPS32::Sandboxer::ret(Variable *RetAddr, Variable *RetValue) {
if (!Target->NeedSandboxing) { if (!Target->NeedSandboxing) {
Target->_ret(RetAddr, RetValue); 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(); createAutoBundle();
Target->_and(RetAddr, RetAddr, T6); Target->_and(RetAddr, RetAddr, T6);
Target->_ret(RetAddr, RetValue); Target->_ret(RetAddr, RetValue);
...@@ -6108,7 +6167,8 @@ void TargetMIPS32::Sandboxer::reset_sp(Variable *Src) { ...@@ -6108,7 +6167,8 @@ void TargetMIPS32::Sandboxer::reset_sp(Variable *Src) {
Target->_mov(SP, Src); Target->_mov(SP, Src);
return; return;
} }
Variable *T7 = Target->getPhysicalRegister(RegMIPS32::Reg_T7); auto *T7 = Target->makeReg(IceType_i32, RegMIPS32::Reg_T7);
Target->Context.insert<InstFakeDef>(T7);
createAutoBundle(); createAutoBundle();
Target->_mov(SP, Src); Target->_mov(SP, Src);
Target->_and(SP, SP, T7); Target->_and(SP, SP, T7);
...@@ -6120,7 +6180,8 @@ InstMIPS32Call *TargetMIPS32::Sandboxer::jal(Variable *ReturnReg, ...@@ -6120,7 +6180,8 @@ InstMIPS32Call *TargetMIPS32::Sandboxer::jal(Variable *ReturnReg,
if (Target->NeedSandboxing) { if (Target->NeedSandboxing) {
createAutoBundle(); createAutoBundle();
if (auto *CallTargetR = llvm::dyn_cast<Variable>(CallTarget)) { 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); Target->_and(CallTargetR, CallTargetR, T6);
} }
} }
......
...@@ -112,6 +112,12 @@ public: ...@@ -112,6 +112,12 @@ public:
uint32_t maxOutArgsSizeBytes() const override { return MaxOutArgsSizeBytes; } uint32_t maxOutArgsSizeBytes() const override { return MaxOutArgsSizeBytes; }
uint32_t getFramePointerOffset(uint32_t CurrentOffset,
uint32_t Size) const override {
(void)Size;
return CurrentOffset + MaxOutArgsSizeBytes;
}
bool shouldSplitToVariable64On32(Type Ty) const override { bool shouldSplitToVariable64On32(Type Ty) const override {
return Ty == IceType_i64; return Ty == IceType_i64;
} }
...@@ -613,6 +619,8 @@ public: ...@@ -613,6 +619,8 @@ public:
void addiu_sp(uint32_t StackOffset); void addiu_sp(uint32_t StackOffset);
void lw(Variable *Dest, OperandMIPS32Mem *Mem); void lw(Variable *Dest, OperandMIPS32Mem *Mem);
void sw(Variable *Dest, OperandMIPS32Mem *Mem); void sw(Variable *Dest, OperandMIPS32Mem *Mem);
void ll(Variable *Dest, OperandMIPS32Mem *Mem);
void sc(Variable *Dest, OperandMIPS32Mem *Mem);
void lwc1(Variable *Dest, OperandMIPS32Mem *Mem, RelocOp Reloc = RO_No); void lwc1(Variable *Dest, OperandMIPS32Mem *Mem, RelocOp Reloc = RO_No);
void ldc1(Variable *Dest, OperandMIPS32Mem *Mem, RelocOp Reloc = RO_No); void ldc1(Variable *Dest, OperandMIPS32Mem *Mem, RelocOp Reloc = RO_No);
void ret(Variable *RetAddr, Variable *RetValue); void ret(Variable *RetAddr, Variable *RetValue);
......
...@@ -156,7 +156,7 @@ next: ...@@ -156,7 +156,7 @@ next:
; MIPS32: addiu v0,sp,0 ; MIPS32: addiu v0,sp,0
; MIPS32: addiu v1,sp,16 ; MIPS32: addiu v1,sp,16
; MIPS32: move a1,a0 ; MIPS32: move a1,a0
; MIPS32: sw a1,16(s8) ; MIPS32: sw a1,32(s8)
; MIPS32: move a1,a0 ; MIPS32: move a1,a0
; MIPS32: sw a1,0(v0) ; MIPS32: sw a1,0(v0)
; MIPS32: sw a0,0(v1) ; MIPS32: sw a0,0(v1)
...@@ -221,9 +221,9 @@ next: ...@@ -221,9 +221,9 @@ next:
; MIPS32: move a1,a0 ; MIPS32: move a1,a0
; MIPS32: sw a1,32(v0) ; MIPS32: sw a1,32(v0)
; MIPS32: move v0,a0 ; MIPS32: move v0,a0
; MIPS32: sw v0,64(s8) ; MIPS32: sw v0,80(s8)
; MIPS32: move v0,a0 ; MIPS32: move v0,a0
; MIPS32: sw v0,48(s8) ; MIPS32: sw v0,96(s8)
; MIPS32: sw a0,0(v1) ; MIPS32: sw a0,0(v1)
; MIPS32: move sp,s8 ; MIPS32: move sp,s8
; MIPS32: lw s8,{{.*}}(sp) ; MIPS32: lw s8,{{.*}}(sp)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment