mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 06:32:09 +00:00
- If fp (r7) is used to reference stack objects, use [r, r] address mode.
- If there is a dynamic alloca, in the epilogue, restore the value of sp using r7 - offset. - Other bug fixes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33997 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e14639ac3d
commit
7142f8755a
@ -359,6 +359,19 @@ static unsigned calcNumMI(int Opc, int ExtraOpc, unsigned Bytes,
|
|||||||
return NumMIs;
|
return NumMIs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// emitLoadConstPool - Emits a load from constpool to materialize NumBytes
|
||||||
|
/// immediate.
|
||||||
|
static void emitLoadConstPool(MachineBasicBlock &MBB,
|
||||||
|
MachineBasicBlock::iterator &MBBI,
|
||||||
|
unsigned DestReg, int NumBytes,
|
||||||
|
const TargetInstrInfo &TII) {
|
||||||
|
MachineFunction &MF = *MBB.getParent();
|
||||||
|
MachineConstantPool *ConstantPool = MF.getConstantPool();
|
||||||
|
Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes);
|
||||||
|
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2);
|
||||||
|
BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), DestReg).addConstantPoolIndex(Idx);
|
||||||
|
}
|
||||||
|
|
||||||
/// emitThumbRegPlusConstPool - Emits a series of instructions to materialize
|
/// emitThumbRegPlusConstPool - Emits a series of instructions to materialize
|
||||||
/// a destreg = basereg + immediate in Thumb code. Load the immediate from a
|
/// a destreg = basereg + immediate in Thumb code. Load the immediate from a
|
||||||
/// constpool entry.
|
/// constpool entry.
|
||||||
@ -368,9 +381,8 @@ void emitThumbRegPlusConstPool(MachineBasicBlock &MBB,
|
|||||||
unsigned DestReg, unsigned BaseReg,
|
unsigned DestReg, unsigned BaseReg,
|
||||||
int NumBytes, bool CanChangeCC,
|
int NumBytes, bool CanChangeCC,
|
||||||
const TargetInstrInfo &TII) {
|
const TargetInstrInfo &TII) {
|
||||||
MachineFunction &MF = *MBB.getParent();
|
bool isHigh = !isLowRegister(DestReg) ||
|
||||||
MachineConstantPool *ConstantPool = MF.getConstantPool();
|
(BaseReg != 0 && !isLowRegister(BaseReg));
|
||||||
bool isHigh = !isLowRegister(DestReg) || !isLowRegister(BaseReg);
|
|
||||||
bool isSub = false;
|
bool isSub = false;
|
||||||
// Subtract doesn't have high register version. Load the negative value
|
// Subtract doesn't have high register version. Load the negative value
|
||||||
// if either base or dest register is a high register. Also, if do not
|
// if either base or dest register is a high register. Also, if do not
|
||||||
@ -389,12 +401,9 @@ void emitThumbRegPlusConstPool(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
if (NumBytes <= 255 && NumBytes >= 0)
|
if (NumBytes <= 255 && NumBytes >= 0)
|
||||||
BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
|
BuildMI(MBB, MBBI, TII.get(ARM::tMOVri8), LdReg).addImm(NumBytes);
|
||||||
else {
|
else
|
||||||
// Load the constant.
|
emitLoadConstPool(MBB, MBBI, LdReg, NumBytes, TII);
|
||||||
Constant *C = ConstantInt::get(Type::Int32Ty, NumBytes);
|
|
||||||
unsigned Idx = ConstantPool->getConstantPoolIndex(C, 2);
|
|
||||||
BuildMI(MBB, MBBI, TII.get(ARM::tLDRpci), LdReg).addConstantPoolIndex(Idx);
|
|
||||||
}
|
|
||||||
// Emit add / sub.
|
// Emit add / sub.
|
||||||
int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
|
int Opc = (isSub) ? ARM::tSUBrr : (isHigh ? ARM::tADDhirr : ARM::tADDrr);
|
||||||
const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg);
|
const MachineInstrBuilder MIB = BuildMI(MBB, MBBI, TII.get(Opc), DestReg);
|
||||||
@ -721,8 +730,8 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
|
|||||||
case ARMII::AddrModeTs: {
|
case ARMII::AddrModeTs: {
|
||||||
ImmIdx = i+1;
|
ImmIdx = i+1;
|
||||||
InstrOffs = MI.getOperand(ImmIdx).getImm();
|
InstrOffs = MI.getOperand(ImmIdx).getImm();
|
||||||
NumBits = isSub ? 3 : ((FrameReg == ARM::SP) ? 8 : 5);
|
NumBits = (FrameReg == ARM::SP) ? 8 : 5;
|
||||||
Scale = isSub ? 1 : 4;
|
Scale = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -754,7 +763,7 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
|
|||||||
// If this is a thumb spill / restore, we will be using a constpool load to
|
// If this is a thumb spill / restore, we will be using a constpool load to
|
||||||
// materialize the offset.
|
// materialize the offset.
|
||||||
bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
|
bool isThumSpillRestore = Opcode == ARM::tRestore || Opcode == ARM::tSpill;
|
||||||
if (AddrMode == ARMII::AddrModeTs || !isThumSpillRestore) {
|
if (AddrMode == ARMII::AddrModeTs && !isThumSpillRestore) {
|
||||||
if (AddrMode == ARMII::AddrModeTs) {
|
if (AddrMode == ARMII::AddrModeTs) {
|
||||||
// Thumb tLDRspi, tSTRspi. These will change to instructions that use
|
// Thumb tLDRspi, tSTRspi. These will change to instructions that use
|
||||||
// a different base register.
|
// a different base register.
|
||||||
@ -779,12 +788,21 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
|
|||||||
if (TII.isLoad(Opcode)) {
|
if (TII.isLoad(Opcode)) {
|
||||||
// Use the destination register to materialize sp + offset.
|
// Use the destination register to materialize sp + offset.
|
||||||
unsigned TmpReg = MI.getOperand(0).getReg();
|
unsigned TmpReg = MI.getOperand(0).getReg();
|
||||||
if (Opcode == ARM::tRestore)
|
bool UseRR = false;
|
||||||
|
if (Opcode == ARM::tRestore) {
|
||||||
|
if (FrameReg == ARM::SP)
|
||||||
emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
|
emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
|
||||||
else
|
else {
|
||||||
|
emitLoadConstPool(MBB, II, TmpReg, Offset, TII);
|
||||||
|
UseRR = true;
|
||||||
|
}
|
||||||
|
} else
|
||||||
emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
|
emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
|
||||||
MI.setInstrDescriptor(TII.get(ARM::tLDR));
|
MI.setInstrDescriptor(TII.get(ARM::tLDR));
|
||||||
MI.getOperand(i).ChangeToRegister(TmpReg, false);
|
MI.getOperand(i).ChangeToRegister(TmpReg, false);
|
||||||
|
if (UseRR)
|
||||||
|
MI.addRegOperand(FrameReg, false); // Use [reg, reg] addrmode.
|
||||||
|
else
|
||||||
MI.addRegOperand(0, false); // tLDR has an extra register operand.
|
MI.addRegOperand(0, false); // tLDR has an extra register operand.
|
||||||
} else if (TII.isStore(Opcode)) {
|
} else if (TII.isStore(Opcode)) {
|
||||||
// FIXME! This is horrific!!! We need register scavenging.
|
// FIXME! This is horrific!!! We need register scavenging.
|
||||||
@ -797,19 +815,30 @@ void ARMRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II) const{
|
|||||||
// r2 = r12
|
// r2 = r12
|
||||||
unsigned ValReg = MI.getOperand(0).getReg();
|
unsigned ValReg = MI.getOperand(0).getReg();
|
||||||
unsigned TmpReg = ARM::R3;
|
unsigned TmpReg = ARM::R3;
|
||||||
|
bool UseRR = false;
|
||||||
if (ValReg == ARM::R3) {
|
if (ValReg == ARM::R3) {
|
||||||
BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
|
BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R12).addReg(ARM::R2);
|
||||||
TmpReg = ARM::R2;
|
TmpReg = ARM::R2;
|
||||||
}
|
}
|
||||||
if (Opcode == ARM::tSpill)
|
if (Opcode == ARM::tSpill) {
|
||||||
|
if (FrameReg == ARM::SP)
|
||||||
emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
|
emitThumbRegPlusConstPool(MBB, II, TmpReg, FrameReg,Offset,false,TII);
|
||||||
else
|
else {
|
||||||
|
emitLoadConstPool(MBB, II, TmpReg, Offset, TII);
|
||||||
|
UseRR = true;
|
||||||
|
}
|
||||||
|
} else
|
||||||
emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
|
emitThumbRegPlusImmediate(MBB, II, TmpReg, FrameReg, Offset, TII);
|
||||||
MI.setInstrDescriptor(TII.get(ARM::tSTR));
|
MI.setInstrDescriptor(TII.get(ARM::tSTR));
|
||||||
MI.getOperand(i).ChangeToRegister(TmpReg, false);
|
MI.getOperand(i).ChangeToRegister(TmpReg, false);
|
||||||
|
if (UseRR)
|
||||||
|
MI.addRegOperand(FrameReg, false); // Use [reg, reg] addrmode.
|
||||||
|
else
|
||||||
MI.addRegOperand(0, false); // tSTR has an extra register operand.
|
MI.addRegOperand(0, false); // tSTR has an extra register operand.
|
||||||
if (ValReg == ARM::R3)
|
if (ValReg == ARM::R3) {
|
||||||
BuildMI(MBB, II, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
|
MachineBasicBlock::iterator NII = next(II);
|
||||||
|
BuildMI(MBB, NII, TII.get(ARM::tMOVrr), ARM::R2).addReg(ARM::R12);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
assert(false && "Unexpected opcode!");
|
assert(false && "Unexpected opcode!");
|
||||||
} else {
|
} else {
|
||||||
@ -1152,6 +1181,15 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
AFI->getGPRCalleeSavedArea2Size() +
|
AFI->getGPRCalleeSavedArea2Size() +
|
||||||
AFI->getDPRCalleeSavedAreaSize());
|
AFI->getDPRCalleeSavedAreaSize());
|
||||||
if (isThumb) {
|
if (isThumb) {
|
||||||
|
if (hasFP(MF)) {
|
||||||
|
NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
|
||||||
|
// Reset SP based on frame pointer only if the stack frame extends beyond
|
||||||
|
// frame pointer stack slot or target is ELF and the function has FP.
|
||||||
|
if (NumBytes)
|
||||||
|
emitThumbRegPlusImmediate(MBB, MBBI, ARM::SP, FramePtr, -NumBytes, TII);
|
||||||
|
else
|
||||||
|
BuildMI(MBB, MBBI, TII.get(ARM::tMOVrr), ARM::SP).addReg(FramePtr);
|
||||||
|
} else {
|
||||||
if (MBBI->getOpcode() == ARM::tBX_RET &&
|
if (MBBI->getOpcode() == ARM::tBX_RET &&
|
||||||
&MBB.front() != MBBI &&
|
&MBB.front() != MBBI &&
|
||||||
prior(MBBI)->getOpcode() == ARM::tPOP) {
|
prior(MBBI)->getOpcode() == ARM::tPOP) {
|
||||||
@ -1159,6 +1197,7 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
emitSPUpdate(MBB, PMBBI, NumBytes, isThumb, TII);
|
emitSPUpdate(MBB, PMBBI, NumBytes, isThumb, TII);
|
||||||
} else
|
} else
|
||||||
emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
|
emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Darwin ABI requires FP to point to the stack slot that contains the
|
// Darwin ABI requires FP to point to the stack slot that contains the
|
||||||
// previous FP.
|
// previous FP.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user