mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 04:35:00 +00:00
Bug fix: align size for dynamic allocas according to stack pointer
alignment restrictions. This is incomplete for one case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4397 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
341a937169
commit
aabb595c4f
@ -833,38 +833,65 @@ CreateCodeForVariableSizeAlloca(const TargetMachine& target,
|
|||||||
Value* numElementsVal,
|
Value* numElementsVal,
|
||||||
vector<MachineInstr*>& getMvec)
|
vector<MachineInstr*>& getMvec)
|
||||||
{
|
{
|
||||||
|
Value* totalSizeVal;
|
||||||
MachineInstr* M;
|
MachineInstr* M;
|
||||||
MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(result);
|
MachineCodeForInstruction& mcfi = MachineCodeForInstruction::get(result);
|
||||||
|
Function *F = result->getParent()->getParent();
|
||||||
|
|
||||||
// Create a Value to hold the (constant) element size
|
// Enforce the alignment constraints on the stack pointer at
|
||||||
Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
|
// compile time if the total size is a known constant.
|
||||||
|
if (isa<Constant>(numElementsVal))
|
||||||
|
{
|
||||||
|
bool isValid;
|
||||||
|
int64_t numElem = GetConstantValueAsSignedInt(numElementsVal, isValid);
|
||||||
|
assert(isValid && "Unexpectedly large array dimension in alloca!");
|
||||||
|
int64_t total = numElem * tsize;
|
||||||
|
if (int extra= total % target.getFrameInfo().getStackFrameSizeAlignment())
|
||||||
|
total += target.getFrameInfo().getStackFrameSizeAlignment() - extra;
|
||||||
|
totalSizeVal = ConstantSInt::get(Type::IntTy, total);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The size is not a constant. Generate code to compute it and
|
||||||
|
// code to pad the size for stack alignment.
|
||||||
|
// Create a Value to hold the (constant) element size
|
||||||
|
Value* tsizeVal = ConstantSInt::get(Type::IntTy, tsize);
|
||||||
|
|
||||||
|
// Create temporary values to hold the result of MUL, SLL, SRL
|
||||||
|
// THIS CASE IS INCOMPLETE AND WILL BE FIXED SHORTLY.
|
||||||
|
TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
|
||||||
|
TmpInstruction* tmpSLL = new TmpInstruction(numElementsVal, tmpProd);
|
||||||
|
TmpInstruction* tmpSRL = new TmpInstruction(numElementsVal, tmpSLL);
|
||||||
|
mcfi.addTemp(tmpProd);
|
||||||
|
mcfi.addTemp(tmpSLL);
|
||||||
|
mcfi.addTemp(tmpSRL);
|
||||||
|
|
||||||
|
// Instruction 1: mul numElements, typeSize -> tmpProd
|
||||||
|
// This will optimize the MUL as far as possible.
|
||||||
|
CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd,getMvec,
|
||||||
|
mcfi, INVALID_MACHINE_OPCODE);
|
||||||
|
|
||||||
|
assert(0 && "Need to insert padding instructions here!");
|
||||||
|
|
||||||
|
totalSizeVal = tmpProd;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the constant offset from SP for dynamically allocated storage
|
// Get the constant offset from SP for dynamically allocated storage
|
||||||
// and create a temporary Value to hold it.
|
// and create a temporary Value to hold it.
|
||||||
assert(result && result->getParent() && "Result value is not part of a fn?");
|
|
||||||
Function *F = result->getParent()->getParent();
|
|
||||||
MachineFunction& mcInfo = MachineFunction::get(F);
|
MachineFunction& mcInfo = MachineFunction::get(F);
|
||||||
bool growUp;
|
bool growUp;
|
||||||
ConstantSInt* dynamicAreaOffset =
|
ConstantSInt* dynamicAreaOffset =
|
||||||
ConstantSInt::get(Type::IntTy,
|
ConstantSInt::get(Type::IntTy,
|
||||||
target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp));
|
target.getFrameInfo().getDynamicAreaOffset(mcInfo,growUp));
|
||||||
assert(! growUp && "Has SPARC v9 stack frame convention changed?");
|
assert(! growUp && "Has SPARC v9 stack frame convention changed?");
|
||||||
|
|
||||||
// Create a temporary value to hold the result of MUL
|
// Instruction 2: sub %sp, totalSizeVal -> %sp
|
||||||
TmpInstruction* tmpProd = new TmpInstruction(numElementsVal, tsizeVal);
|
|
||||||
mcfi.addTemp(tmpProd);
|
|
||||||
|
|
||||||
// Instruction 1: mul numElements, typeSize -> tmpProd
|
|
||||||
CreateMulInstruction(target, F, numElementsVal, tsizeVal, tmpProd, getMvec,
|
|
||||||
mcfi, INVALID_MACHINE_OPCODE);
|
|
||||||
|
|
||||||
// Instruction 2: sub %sp, tmpProd -> %sp
|
|
||||||
M = new MachineInstr(SUB);
|
M = new MachineInstr(SUB);
|
||||||
M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
|
M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
|
||||||
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, tmpProd);
|
M->SetMachineOperandVal(1, MachineOperand::MO_VirtualRegister, totalSizeVal);
|
||||||
M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
|
M->SetMachineOperandReg(2, target.getRegInfo().getStackPointer());
|
||||||
getMvec.push_back(M);
|
getMvec.push_back(M);
|
||||||
|
|
||||||
// Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
|
// Instruction 3: add %sp, frameSizeBelowDynamicArea -> result
|
||||||
M = new MachineInstr(ADD);
|
M = new MachineInstr(ADD);
|
||||||
M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
|
M->SetMachineOperandReg(0, target.getRegInfo().getStackPointer());
|
||||||
@ -1991,11 +2018,12 @@ GetInstructionsByRule(InstructionNode* subtreeRoot,
|
|||||||
bool isVarArgs = funcType->isVarArg();
|
bool isVarArgs = funcType->isVarArg();
|
||||||
bool noPrototype = isVarArgs && funcType->getNumParams() == 0;
|
bool noPrototype = isVarArgs && funcType->getNumParams() == 0;
|
||||||
|
|
||||||
// Use an annotation to pass information about call arguments
|
// Use a descriptor to pass information about call arguments
|
||||||
// to the register allocator.
|
// to the register allocator. This descriptor will be "owned"
|
||||||
|
// and freed automatically when the MachineCodeForInstruction
|
||||||
|
// object for the callInstr goes away.
|
||||||
CallArgsDescriptor* argDesc = new CallArgsDescriptor(callInstr,
|
CallArgsDescriptor* argDesc = new CallArgsDescriptor(callInstr,
|
||||||
retAddrReg, isVarArgs, noPrototype);
|
retAddrReg, isVarArgs, noPrototype);
|
||||||
M->addAnnotation(argDesc);
|
|
||||||
|
|
||||||
assert(callInstr->getOperand(0) == callee
|
assert(callInstr->getOperand(0) == callee
|
||||||
&& "This is assumed in the loop below!");
|
&& "This is assumed in the loop below!");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user