Commit ec929173 by Jaydeep Patil Committed by Jim Stichnoth

[SubZero] Legalize load, store for MIPS post lower

This patch legalizes load, store instructions post lowering. R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2411193003 . Patch from Jaydeep Patil <jaydeep.patil@imgtec.com>.
parent b001cc4c
......@@ -1529,7 +1529,17 @@ Variable *TargetMIPS32::PostLoweringLegalizer::newBaseRegister(
Target->Ctx->getConstantInt32(-Offset), ScratchRegNum);
Target->_sub(ScratchReg, Base, OffsetVal);
} else {
Target->_addiu(ScratchReg, Base, Offset);
constexpr bool SignExt = true;
if (!OperandMIPS32Mem::canHoldOffset(Base->getType(), SignExt, Offset)) {
const uint32_t UpperBits = (Offset >> 16) & 0xFFFF;
const uint32_t LowerBits = Offset & 0xFFFF;
Target->_lui(ScratchReg, Target->Ctx->getConstantInt32(UpperBits));
if (LowerBits)
Target->_ori(ScratchReg, ScratchReg, LowerBits);
Target->_addu(ScratchReg, ScratchReg, Base);
} else {
Target->_addiu(ScratchReg, Base, Offset);
}
}
return ScratchReg;
......@@ -1731,6 +1741,35 @@ void TargetMIPS32::PostLoweringLegalizer::legalizeMov(InstMIPS32Mov *MovInstr) {
}
}
OperandMIPS32Mem *
TargetMIPS32::PostLoweringLegalizer::legalizeMemOperand(OperandMIPS32Mem *Mem) {
if (llvm::isa<ConstantRelocatable>(Mem->getOffset())) {
return nullptr;
}
Variable *Base = Mem->getBase();
auto *Ci32 = llvm::cast<ConstantInteger32>(Mem->getOffset());
int32_t Offset = Ci32->getValue();
if (Base->isRematerializable()) {
const int32_t ExtraOffset =
(Base->getRegNum() == Target->getFrameOrStackReg())
? Target->getFrameFixedAllocaOffset()
: 0;
Offset += Base->getStackOffset() + ExtraOffset;
Base = Target->getPhysicalRegister(Base->getRegNum());
}
constexpr bool SignExt = true;
if (!OperandMIPS32Mem::canHoldOffset(Mem->getType(), SignExt, Offset)) {
Base = newBaseRegister(Base, Offset, Target->getReservedTmpReg());
Offset = 0;
}
return OperandMIPS32Mem::create(
Target->Func, Mem->getType(), Base,
llvm::cast<ConstantInteger32>(Target->Ctx->getConstantInt32(Offset)));
}
void TargetMIPS32::postLowerLegalization() {
Func->dump("Before postLowerLegalization");
assert(hasComputedFrame());
......@@ -1740,11 +1779,58 @@ void TargetMIPS32::postLowerLegalization() {
while (!Context.atEnd()) {
PostIncrLoweringContext PostIncrement(Context);
Inst *CurInstr = iteratorToInst(Context.getCur());
// TODO(sagar.thakur): Add remaining cases of legalization.
const SizeT NumSrcs = CurInstr->getSrcSize();
Operand *Src0 = NumSrcs < 1 ? nullptr : CurInstr->getSrc(0);
Operand *Src1 = NumSrcs < 2 ? nullptr : CurInstr->getSrc(1);
auto *Src0V = llvm::dyn_cast_or_null<Variable>(Src0);
auto *Src0M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src0);
auto *Src1M = llvm::dyn_cast_or_null<OperandMIPS32Mem>(Src1);
Variable *Dst = CurInstr->getDest();
if (auto *MovInstr = llvm::dyn_cast<InstMIPS32Mov>(CurInstr)) {
Legalizer.legalizeMov(MovInstr);
continue;
}
if (llvm::isa<InstMIPS32Sw>(CurInstr)) {
if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
_sw(Src0V, LegalMem);
CurInstr->setDeleted();
}
continue;
}
if (llvm::isa<InstMIPS32Swc1>(CurInstr)) {
if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
_swc1(Src0V, LegalMem);
CurInstr->setDeleted();
}
continue;
}
if (llvm::isa<InstMIPS32Sdc1>(CurInstr)) {
if (auto *LegalMem = Legalizer.legalizeMemOperand(Src1M)) {
_sdc1(Src0V, LegalMem);
CurInstr->setDeleted();
}
continue;
}
if (llvm::isa<InstMIPS32Lw>(CurInstr)) {
if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) {
_lw(Dst, LegalMem);
CurInstr->setDeleted();
}
continue;
}
if (llvm::isa<InstMIPS32Lwc1>(CurInstr)) {
if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) {
_lwc1(Dst, LegalMem);
CurInstr->setDeleted();
}
continue;
}
if (llvm::isa<InstMIPS32Ldc1>(CurInstr)) {
if (auto *LegalMem = Legalizer.legalizeMemOperand(Src0M)) {
_ldc1(Dst, LegalMem);
CurInstr->setDeleted();
}
continue;
}
}
}
......
......@@ -90,6 +90,7 @@ public:
RegNumT getFrameOrStackReg() const override {
return UsesFramePointer ? getFrameReg() : getStackReg();
}
RegNumT getReservedTmpReg() const { return RegMIPS32::Reg_AT; }
size_t typeWidthInBytesOnStack(Type Ty) const override {
// Round up to the next multiple of 4 bytes. In particular, i1, i8, and i16
// are rounded up to 4 bytes.
......@@ -726,6 +727,10 @@ protected:
: Target(Target), StackOrFrameReg(Target->getPhysicalRegister(
Target->getFrameOrStackReg())) {}
/// Legalizes Mem. if Mem.Base is a rematerializable variable,
/// Mem.Offset is fixed up.
OperandMIPS32Mem *legalizeMemOperand(OperandMIPS32Mem *Mem);
/// Legalizes Mov if its Source (or Destination) is a spilled Variable, or
/// if its Source is a Rematerializable variable (this form is used in lieu
/// of lea, which is not available in MIPS.)
......
; This file checks support for legalization in MIPS.
; REQUIRES: allow_dump
; RUN: %if --need=target_MIPS32 \
; RUN: --command %p2i --filetype=asm --assemble --disassemble \
; RUN: --target mips32 -i %s --args -O2 \
; RUN: | %if --need=target_MIPS32 \
; RUN: --command FileCheck --check-prefix MIPS32 %s
define internal i32 @legalization(i32 %a, i32 %b, i32 %c, i32 %d,
i32 %e, i32 %f) {
entry:
%a.addr = alloca i8, i32 4, align 4
%b.addr = alloca i8, i32 4, align 4
%c.addr = alloca i8, i32 4, align 4
%d.addr = alloca i8, i32 4, align 4
%e.addr = alloca i8, i32 4, align 4
%f.addr = alloca i8, i32 4, align 4
%r1 = alloca i8, i32 4, align 4
%r2 = alloca i8, i32 4, align 4
%r3 = alloca i8, i32 4, align 4
%a.addr.bc = bitcast i8* %a.addr to i32*
store i32 %a, i32* %a.addr.bc, align 1
%b.addr.bc = bitcast i8* %b.addr to i32*
store i32 %b, i32* %b.addr.bc, align 1
%c.addr.bc = bitcast i8* %c.addr to i32*
store i32 %c, i32* %c.addr.bc, align 1
%d.addr.bc = bitcast i8* %d.addr to i32*
store i32 %d, i32* %d.addr.bc, align 1
%e.addr.bc = bitcast i8* %e.addr to i32*
store i32 %e, i32* %e.addr.bc, align 1
%f.addr.bc = bitcast i8* %f.addr to i32*
store i32 %f, i32* %f.addr.bc, align 1
%a.addr.bc1 = bitcast i8* %a.addr to i32*
%0 = load i32, i32* %a.addr.bc1, align 1
%f.addr.bc2 = bitcast i8* %f.addr to i32*
%1 = load i32, i32* %f.addr.bc2, align 1
%add = add i32 %0, %1
%r1.bc = bitcast i8* %r1 to i32*
store i32 %add, i32* %r1.bc, align 1
%b.addr.bc3 = bitcast i8* %b.addr to i32*
%2 = load i32, i32* %b.addr.bc3, align 1
%e.addr.bc4 = bitcast i8* %e.addr to i32*
%3 = load i32, i32* %e.addr.bc4, align 1
%add1 = add i32 %2, %3
%r2.bc = bitcast i8* %r2 to i32*
store i32 %add1, i32* %r2.bc, align 1
%r1.bc5 = bitcast i8* %r1 to i32*
%4 = load i32, i32* %r1.bc5, align 1
%r2.bc6 = bitcast i8* %r2 to i32*
%5 = load i32, i32* %r2.bc6, align 1
%add2 = add i32 %4, %5
%r3.bc = bitcast i8* %r3 to i32*
store i32 %add2, i32* %r3.bc, align 1
%r3.bc7 = bitcast i8* %r3 to i32*
%6 = load i32, i32* %r3.bc7, align 1
ret i32 %6
}
; MIPS32-LABEL: legalization
; MIPS32: addiu sp,sp,-48
; MIPS32: lw [[ARG_E:.*]],64(sp)
; MIPS32: lw [[ARG_F:.*]],68(sp)
; MIPS32: sw a0,0(sp)
; MIPS32: sw a1,4(sp)
; MIPS32: sw a2,8(sp)
; MIPS32: sw a3,12(sp)
; MIPS32: sw [[ARG_E]],16(sp)
; MIPS32: sw [[ARG_F]],20(sp)
; MIPS32: lw [[TMP_A:.*]],0(sp)
; MIPS32: lw [[TMP_F:.*]],20(sp)
; MIPS32: addu [[ADD1:.*]],[[TMP_A]],[[TMP_F]]
; MIPS32: sw [[ADD1]],24(sp)
; MIPS32: lw [[TMP_B:.*]],4(sp)
; MIPS32: lw [[TMP_E:.*]],16(sp)
; MIPS32: addu [[ADD2:.*]],[[TMP_B]],[[TMP_E]]
; MIPS32: sw [[ADD2]],28(sp)
; MIPS32: lw [[TMP_ADD1:.*]],24(sp)
; MIPS32: lw [[TMP_ADD2:.*]],28(sp)
; MIPS32: addu [[ADD3:.*]],[[TMP_ADD1]],[[TMP_ADD2]]
; MIPS32: sw [[ADD3]],32(sp)
; MIPS32: lw v0,32(sp)
; MIPS32: addiu sp,sp,48
; MIPS32: jr ra
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