Handle long-disp stuff more consistently

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76059 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anton Korobeynikov 2009-07-16 14:33:52 +00:00
parent 74e2dc446c
commit 9de2848fac
3 changed files with 31 additions and 7 deletions

View File

@ -650,7 +650,8 @@ SystemZInstrInfo::getLongDispOpc(unsigned Opc) const {
case SystemZ::FMOV64mr: return get(SystemZ::FMOV64mry);
case SystemZ::FMOV32rm: return get(SystemZ::FMOV32rmy);
case SystemZ::FMOV64rm: return get(SystemZ::FMOV64rmy);
default: return get(Opc);
default:
assert(0 && "Don't have long disp version of this instruction");
}
}

View File

@ -106,6 +106,13 @@ public:
SystemZCC::CondCodes getCondFromBranchOpc(unsigned Opc) const;
const TargetInstrDesc& getBrCond(SystemZCC::CondCodes CC) const;
const TargetInstrDesc& getLongDispOpc(unsigned Opc) const;
const TargetInstrDesc& getMemoryInstr(unsigned Opc, int64_t Offset = 0) const {
if (Offset < 0 || Offset >= 4096)
return getLongDispOpc(Opc);
else
return get(Opc);
}
};
}

View File

@ -133,8 +133,7 @@ void SystemZRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int Offset = getFrameIndexOffset(MF, FrameIndex) + MI.getOperand(i+1).getImm();
// Check whether displacement is too long to fit into 12 bit zext field.
if (Offset < 0 || Offset >= 4096)
MI.setDesc(TII.getLongDispOpc(MI.getOpcode()));
MI.setDesc(TII.getMemoryInstr(MI.getOpcode(), Offset));
MI.getOperand(i+1).ChangeToImmediate(Offset);
}
@ -179,11 +178,18 @@ SystemZRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
static
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
int64_t NumBytes, const TargetInstrInfo &TII) {
// FIXME: Handle different stack sizes here.
unsigned Opc; uint64_t Chunk;
bool isSub = NumBytes < 0;
uint64_t Offset = isSub ? -NumBytes : NumBytes;
unsigned Opc = SystemZ::ADD64ri16;
uint64_t Chunk = (1LL << 15) - 1;
if (Offset >= (1LL << 15) - 1) {
Opc = SystemZ::ADD64ri32;
Chunk = (1LL << 31) - 1;
} else {
Opc = SystemZ::ADD64ri16;
Chunk = (1LL << 15) - 1;
}
DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
DebugLoc::getUnknownLoc());
@ -293,7 +299,17 @@ void SystemZRegisterInfo::emitEpilogue(MachineFunction &MF,
assert(i < MI.getNumOperands() && "Unexpected restore code!");
}
MI.getOperand(i).ChangeToImmediate(NumBytes + MI.getOperand(i).getImm());
uint64_t Offset = NumBytes + MI.getOperand(i).getImm();
// If Offset does not fit into 20-bit signed displacement field we need to
// emit some additional code...
if (Offset > 524287) {
// Fold the displacement into load instruction as much as possible.
NumBytes = Offset - 524287;
Offset = 524287;
emitSPUpdate(MBB, MBBI, NumBytes, TII);
}
MI.getOperand(i).ChangeToImmediate(Offset);
}
}