diff options
author | Tim Northover <Tim.Northover@arm.com> | 2013-02-15 09:33:26 +0000 |
---|---|---|
committer | Tim Northover <Tim.Northover@arm.com> | 2013-02-15 09:33:26 +0000 |
commit | 5466e36fb5887ba3f9fa84e75024cedb147469bc (patch) | |
tree | b8e92b968fe369c86e7e664861a29771bb6db473 /llvm/lib/Target | |
parent | d5d7bb5591ec3f48ee45ce27a3dc18d16a9337fe (diff) | |
download | bcm5719-llvm-5466e36fb5887ba3f9fa84e75024cedb147469bc.tar.gz bcm5719-llvm-5466e36fb5887ba3f9fa84e75024cedb147469bc.zip |
AArch64: refactor frame handling to use movz/movk for overlarge offsets.
In the near future litpools will be in a different section, which means that
any access to them is at least two instructions. This makes the case for a
movz/movk pair (if total offset <= 32-bits) even more compelling.
llvm-svn: 175257
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp index 94b342952a8..9a7504afd9f 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -623,18 +623,35 @@ void llvm::emitRegUpdate(MachineBasicBlock &MBB, else if (abs(NumBytes) & ~0xffffff) { // Generically, we have to materialize the offset into a temporary register // and subtract it. There are a couple of ways this could be done, for now - // we'll go for a literal-pool load. - MachineFunction &MF = *MBB.getParent(); - MachineConstantPool *MCP = MF.getConstantPool(); - const Constant *C - = ConstantInt::get(Type::getInt64Ty(MF.getFunction()->getContext()), - abs(NumBytes)); - unsigned CPI = MCP->getConstantPoolIndex(C, 8); - - // LDR xTMP, .LITPOOL - BuildMI(MBB, MBBI, dl, TII.get(AArch64::LDRx_lit), ScratchReg) - .addConstantPoolIndex(CPI) - .setMIFlag(MIFlags); + // we'll use a movz/movk or movn/movk sequence. + uint64_t Bits = static_cast<uint64_t>(abs(NumBytes)); + BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg) + .addImm(0xffff & Bits).addImm(0) + .setMIFlags(MIFlags); + + Bits >>= 16; + if (Bits & 0xffff) { + BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) + .addReg(ScratchReg) + .addImm(0xffff & Bits).addImm(1) + .setMIFlags(MIFlags); + } + + Bits >>= 16; + if (Bits & 0xffff) { + BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) + .addReg(ScratchReg) + .addImm(0xffff & Bits).addImm(2) + .setMIFlags(MIFlags); + } + + Bits >>= 16; + if (Bits & 0xffff) { + BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) + .addReg(ScratchReg) + .addImm(0xffff & Bits).addImm(3) + .setMIFlags(MIFlags); + } // ADD DST, SRC, xTMP (, lsl #0) unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx; |