aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/SystemZ
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2009-07-16 14:33:52 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2009-07-16 14:33:52 +0000
commit9de2848fac8806e311531fccf112b7936b23de31 (patch)
tree39abaac4a4842ff93c9f8206ce1ca21eb9d0942b /lib/Target/SystemZ
parent74e2dc446c02053bf1e17532707ca56f47453487 (diff)
downloadexternal_llvm-9de2848fac8806e311531fccf112b7936b23de31.zip
external_llvm-9de2848fac8806e311531fccf112b7936b23de31.tar.gz
external_llvm-9de2848fac8806e311531fccf112b7936b23de31.tar.bz2
Handle long-disp stuff more consistently
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76059 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SystemZ')
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.cpp3
-rw-r--r--lib/Target/SystemZ/SystemZInstrInfo.h7
-rw-r--r--lib/Target/SystemZ/SystemZRegisterInfo.cpp28
3 files changed, 31 insertions, 7 deletions
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.cpp b/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 914d333..c54ce53 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -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");
}
}
diff --git a/lib/Target/SystemZ/SystemZInstrInfo.h b/lib/Target/SystemZ/SystemZInstrInfo.h
index 0ef3ca9..ba94ced 100644
--- a/lib/Target/SystemZ/SystemZInstrInfo.h
+++ b/lib/Target/SystemZ/SystemZInstrInfo.h
@@ -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);
+ }
};
}
diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.cpp b/lib/Target/SystemZ/SystemZRegisterInfo.cpp
index c829e43..643d681 100644
--- a/lib/Target/SystemZ/SystemZRegisterInfo.cpp
+++ b/lib/Target/SystemZ/SystemZRegisterInfo.cpp
@@ -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);
}
}