| Index: src/IceTargetLoweringMIPS32.cpp
|
| diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
|
| index 6f9df19cae856b3b26f52224a568e2e4839c6f7c..f0118feab347143a1378cc54408d7eaa8a609697 100644
|
| --- a/src/IceTargetLoweringMIPS32.cpp
|
| +++ b/src/IceTargetLoweringMIPS32.cpp
|
| @@ -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)) {
|
|
|