Commit c930d59b by Sagar Thakur Committed by Jim Stichnoth

[Subzero][MIPS32] Implements variable alloca for MIPS32

BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2138383002 . Patch from Sagar Thakur <sagar.thakur@imgtec.com>.
parent ab6a04f6
......@@ -849,7 +849,8 @@ void TargetMIPS32::addProlog(CfgNode *Node) {
// Adds the out args space to the stack, and align SP if necessary.
TotalStackSizeBytes = PreservedRegsSizeBytes + SpillAreaSizeBytes +
FixedAllocaSizeBytes + MaxOutArgsSizeBytes;
FixedAllocaSizeBytes +
(MaxOutArgsSizeBytes * (VariableAllocaUsed ? 0 : 1));
// Generate "addiu sp, sp, -TotalStackSizeBytes"
if (TotalStackSizeBytes) {
......@@ -1125,7 +1126,29 @@ void TargetMIPS32::lowerAlloca(const InstAlloca *Instr) {
return;
}
} else {
UnimplementedLoweringError(this, Instr);
// Non-constant sizes need to be adjusted to the next highest multiple of
// the required alignment at runtime.
VariableAllocaUsed = true;
Variable *AlignAmount;
auto *TotalSizeR = legalizeToReg(TotalSize, Legal_Reg);
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *T5 = I32Reg();
_addiu(T1, TotalSizeR, MIPS32_STACK_ALIGNMENT_BYTES - 1);
_addiu(T2, getZero(), -MIPS32_STACK_ALIGNMENT_BYTES);
_and(T3, T1, T2);
_subu(T4, SP, T3);
if (Instr->getAlignInBytes()) {
AlignAmount =
legalizeToReg(Ctx->getConstantInt32(-AlignmentParam), Legal_Reg);
_and(T5, T4, AlignAmount);
_mov(Dest, T5);
} else {
_mov(Dest, T4);
}
_mov(SP, Dest);
return;
}
......@@ -1647,8 +1670,21 @@ void TargetMIPS32::lowerCall(const InstCall *Instr) {
Context.insert<InstFakeUse>(RegArg);
}
// If variable alloca is used the extra 16 bytes for argument build area
// will be allocated on stack before a call.
if (VariableAllocaUsed)
_addiu(SP, SP, -MaxOutArgsSizeBytes);
Inst *NewCall = InstMIPS32Call::create(Func, ReturnReg, CallTarget);
Context.insert(NewCall);
if (VariableAllocaUsed)
_addiu(SP, SP, MaxOutArgsSizeBytes);
// Insert a fake use of stack pointer to avoid dead code elimination of addiu
// instruction.
Context.insert<InstFakeUse>(SP);
if (ReturnRegHi)
Context.insert(InstFakeDef::create(Func, ReturnRegHi));
// Insert a register-kill pseudo instruction.
......@@ -2276,8 +2312,12 @@ Operand *TargetMIPS32::legalize(Operand *From, LegalMask Allowed,
(void)UpperBits;
uint32_t LowerBits = Value & 0xFFFF;
Variable *TReg = makeReg(Ty, RegNum);
_lui(TReg, Ctx->getConstantInt32(UpperBits));
_ori(Reg, TReg, LowerBits);
if (LowerBits) {
_lui(TReg, Ctx->getConstantInt32(UpperBits));
_ori(Reg, TReg, LowerBits);
} else {
_lui(Reg, Ctx->getConstantInt32(UpperBits));
}
}
return Reg;
} else if (isScalarFloatingType(Ty)) {
......
......@@ -563,6 +563,7 @@ protected:
bool NeedsStackAlignment = false;
bool MaybeLeafFunc = true;
bool PrologEmitsFixedAllocas = false;
bool VariableAllocaUsed = false;
uint32_t MaxOutArgsSizeBytes = 0;
uint32_t TotalStackSizeBytes = 0;
static SmallBitVector TypeToRegisterSet[RCMIPS32_NUM];
......
......@@ -176,6 +176,17 @@ entry:
; ARM32: sub sp, sp, r0
; ARM32: bl {{.*}} R_{{.*}} f2
; MIPS32-LABEL: variable_n_align_16
; MIPS32: addiu [[REG:.*]],{{.*}},7
; MIPS32: li [[REG1:.*]],-8
; MIPS32: and [[REG2:.*]],[[REG]],[[REG1]]
; MIPS32: subu [[REG3:.*]],sp,[[REG2:.*]]
; MIPS32: li [[REG4:.*]],-16
; MIPS32: and {{.*}},[[REG3]],[[REG4]]
; MIPS32: addiu sp,sp,-16
; MIPS32: jal {{.*}} R_{{.*}} f2
; MIPS32: addiu sp,sp,16
define internal void @variable_n_align_32(i32 %n) {
entry:
%array = alloca i8, i32 %n, align 32
......@@ -210,6 +221,17 @@ entry:
; ARM32: mov sp, fp
; ARM32: pop {fp, lr}
; MIPS32-LABEL: variable_n_align_32
; MIPS32: addiu [[REG:.*]],{{.*}},7
; MIPS32: li [[REG1:.*]],-8
; MIPS32: and [[REG2:.*]],[[REG]],[[REG1]]
; MIPS32: subu [[REG3:.*]],sp,[[REG2]]
; MIPS32: li [[REG4:.*]],-32
; MIPS32: and {{.*}},[[REG3]],[[REG4]]
; MIPS32: addiu sp,sp,-16
; MIPS32: jal {{.*}} R_{{.*}} f2
; MIPS32: addiu sp,sp,16
; Test alloca with default (0) alignment.
define internal void @align0(i32 %n) {
entry:
......@@ -228,6 +250,15 @@ entry:
; ARM32: bic r0, r0, #15
; ARM32: sub sp, sp, r0
; MIPS32-LABEL: align0
; MIPS32: addiu [[REG:.*]],{{.*}},7
; MIPS32: li [[REG1:.*]],-8
; MIPS32: and [[REG2:.*]],[[REG]],[[REG1]]
; MIPS32: subu {{.*}},sp,[[REG2]]
; MIPS32: addiu sp,sp,-16
; MIPS32: jal {{.*}} R_{{.*}} f2
; MIPS32: addiu sp,sp,16
; Test a large alignment where a mask might not fit in an immediate
; field of an instruction for some architectures.
define internal void @align1MB(i32 %n) {
......@@ -257,6 +288,17 @@ entry:
; ARM32: and r0, r0, [[REG3]]
; ARM32: sub sp, sp, r0
; MIPS32-LABEL: align1MB
; MIPS32: addiu [[REG:.*]],{{.*}},7
; MIPS32: li [[REG1:.*]],-8
; MIPS32: and [[REG2:.*]],[[REG]],[[REG1]]
; MIPS32: subu [[REG3:.*]],sp,[[REG2]]
; MIPS32: lui [[REG4:.*]],0xfff0
; MIPS32: and {{.*}},[[REG3]],[[REG4]]
; MIPS32: addiu sp,sp,-16
; MIPS32: jal {{.*}} R_{{.*}} f2
; MIPS32: addiu sp,sp,16
; Test a large alignment where a mask might still fit in an immediate
; field of an instruction for some architectures.
define internal void @align512MB(i32 %n) {
......@@ -281,6 +323,17 @@ entry:
; ARM32: and r0, r0, #-536870912 ; 0xe0000000
; ARM32: sub sp, sp, r0
; MIPS32-LABEL: align512MB
; MIPS32: addiu [[REG:.*]],{{.*}},7
; MIPS32: li [[REG2:.*]],-8
; MIPS32: and [[REG3:.*]],[[REG]],[[REG2]]
; MIPS32: subu [[REG4:.*]],sp,[[REG3]]
; MIPS32: lui [[REG5:.*]],0xe000
; MIPS32: and {{.*}},[[REG4]],[[REG5]]
; MIPS32: addiu sp,sp,-16
; MIPS32: jal {{.*}} R_{{.*}} f2
; MIPS32: addiu sp,sp,16
; Test that a simple alloca sequence doesn't trigger a frame pointer.
define internal void @fixed_no_frameptr(i32 %arg) {
entry:
......
......@@ -102,7 +102,6 @@ define internal i32 @ret_8bits_shift_left24() {
; ARM32-NEXT: bx lr
; MIPS32-LABEL: ret_8bits_shift_left24
; MIPS32-NEXT: lui v0,0xff00
; MIPS32-NEXT: ori v0,v0,0x0
; The next few cases wrap around and actually demonstrate the rotation.
......@@ -229,7 +228,6 @@ define internal i32 @ret_16bits_upper() {
; ARM32-NEXT: movt r0, #65535
; MIPS32-LABEL: ret_16bits_upper
; MIPS32-NEXT: lui v0,0xffff
; MIPS32-NEXT: ori v0,v0,0x0
; Some 32-bit immediates can be inverted, and moved in a single instruction.
......
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