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 | 148ac534fc5592ed7031efde9a577890f078068b (patch) | |
tree | 84b546d904cd5db7916064bce054701430253ae0 /lib | |
parent | c4439c3508aa705add9dc46106270f0b3763b882 (diff) | |
download | external_llvm-148ac534fc5592ed7031efde9a577890f078068b.zip external_llvm-148ac534fc5592ed7031efde9a577890f078068b.tar.gz external_llvm-148ac534fc5592ed7031efde9a577890f078068b.tar.bz2 |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175257 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/AArch64/AArch64InstrInfo.cpp | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/lib/Target/AArch64/AArch64InstrInfo.cpp b/lib/Target/AArch64/AArch64InstrInfo.cpp index 94b3429..9a7504a 100644 --- a/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/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; |