mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-15 04:30:12 +00:00
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
This commit is contained in:
parent
c4439c3508
commit
148ac534fc
@ -623,18 +623,35 @@ void llvm::emitRegUpdate(MachineBasicBlock &MBB,
|
|||||||
else if (abs(NumBytes) & ~0xffffff) {
|
else if (abs(NumBytes) & ~0xffffff) {
|
||||||
// Generically, we have to materialize the offset into a temporary register
|
// 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
|
// and subtract it. There are a couple of ways this could be done, for now
|
||||||
// we'll go for a literal-pool load.
|
// we'll use a movz/movk or movn/movk sequence.
|
||||||
MachineFunction &MF = *MBB.getParent();
|
uint64_t Bits = static_cast<uint64_t>(abs(NumBytes));
|
||||||
MachineConstantPool *MCP = MF.getConstantPool();
|
BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg)
|
||||||
const Constant *C
|
.addImm(0xffff & Bits).addImm(0)
|
||||||
= ConstantInt::get(Type::getInt64Ty(MF.getFunction()->getContext()),
|
.setMIFlags(MIFlags);
|
||||||
abs(NumBytes));
|
|
||||||
unsigned CPI = MCP->getConstantPoolIndex(C, 8);
|
|
||||||
|
|
||||||
// LDR xTMP, .LITPOOL
|
Bits >>= 16;
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(AArch64::LDRx_lit), ScratchReg)
|
if (Bits & 0xffff) {
|
||||||
.addConstantPoolIndex(CPI)
|
BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg)
|
||||||
.setMIFlag(MIFlags);
|
.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)
|
// ADD DST, SRC, xTMP (, lsl #0)
|
||||||
unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx;
|
unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx;
|
||||||
|
@ -11,17 +11,22 @@ define void @test_bigframe() {
|
|||||||
%var3 = alloca i8, i32 20000000
|
%var3 = alloca i8, i32 20000000
|
||||||
; CHECK: sub sp, sp, #496
|
; CHECK: sub sp, sp, #496
|
||||||
; CHECK: str x30, [sp, #488]
|
; CHECK: str x30, [sp, #488]
|
||||||
; CHECK: ldr [[FRAMEOFFSET:x[0-9]+]], [[FRAMEOFFSET_CPI:.LCPI0_[0-9]+]]
|
; Total adjust is 39999536
|
||||||
; CHECK: sub sp, sp, [[FRAMEOFFSET]]
|
; CHECK: movz [[SUBCONST:x[0-9]+]], #22576
|
||||||
|
; CHECK: movk [[SUBCONST]], #610, lsl #16
|
||||||
|
; CHECK: sub sp, sp, [[SUBCONST]]
|
||||||
|
|
||||||
; CHECK: ldr [[VAR1OFFSET:x[0-9]+]], [[VAR1LOC_CPI:.LCPI0_[0-9]+]]
|
; Total offset is 20000024
|
||||||
|
; CHECK: movz [[VAR1OFFSET:x[0-9]+]], #11544
|
||||||
|
; CHECK: movk [[VAR1OFFSET]], #305, lsl #16
|
||||||
; CHECK: add {{x[0-9]+}}, sp, [[VAR1OFFSET]]
|
; CHECK: add {{x[0-9]+}}, sp, [[VAR1OFFSET]]
|
||||||
store volatile i8* %var1, i8** @addr
|
store volatile i8* %var1, i8** @addr
|
||||||
|
|
||||||
%var1plus2 = getelementptr i8* %var1, i32 2
|
%var1plus2 = getelementptr i8* %var1, i32 2
|
||||||
store volatile i8* %var1plus2, i8** @addr
|
store volatile i8* %var1plus2, i8** @addr
|
||||||
|
|
||||||
; CHECK: ldr [[VAR2OFFSET:x[0-9]+]], [[VAR2LOC_CPI:.LCPI0_[0-9]+]]
|
; CHECK: movz [[VAR2OFFSET:x[0-9]+]], #11528
|
||||||
|
; CHECK: movk [[VAR2OFFSET]], #305, lsl #16
|
||||||
; CHECK: add {{x[0-9]+}}, sp, [[VAR2OFFSET]]
|
; CHECK: add {{x[0-9]+}}, sp, [[VAR2OFFSET]]
|
||||||
store volatile i8* %var2, i8** @addr
|
store volatile i8* %var2, i8** @addr
|
||||||
|
|
||||||
@ -33,18 +38,10 @@ define void @test_bigframe() {
|
|||||||
%var3plus2 = getelementptr i8* %var3, i32 2
|
%var3plus2 = getelementptr i8* %var3, i32 2
|
||||||
store volatile i8* %var3plus2, i8** @addr
|
store volatile i8* %var3plus2, i8** @addr
|
||||||
|
|
||||||
; CHECK: ldr [[FRAMEOFFSET:x[0-9]+]], [[FRAMEOFFSET_CPI]]
|
; CHECK: movz [[ADDCONST:x[0-9]+]], #22576
|
||||||
; CHECK: add sp, sp, [[FRAMEOFFSET]]
|
; CHECK: movk [[ADDCONST]], #610, lsl #16
|
||||||
|
; CHECK: add sp, sp, [[ADDCONST]]
|
||||||
ret void
|
ret void
|
||||||
|
|
||||||
; CHECK: [[FRAMEOFFSET_CPI]]:
|
|
||||||
; CHECK-NEXT: 39999536
|
|
||||||
|
|
||||||
; CHECK: [[VAR1LOC_CPI]]:
|
|
||||||
; CHECK-NEXT: 20000024
|
|
||||||
|
|
||||||
; CHECK: [[VAR2LOC_CPI]]:
|
|
||||||
; CHECK-NEXT: 20000008
|
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test_mediumframe() {
|
define void @test_mediumframe() {
|
||||||
@ -103,10 +100,10 @@ define void @test_tempallocation([8 x i64] %val) nounwind {
|
|||||||
; CHECK-NEXT: stp x19, x20, [sp,
|
; CHECK-NEXT: stp x19, x20, [sp,
|
||||||
|
|
||||||
; Make sure we don't trash an argument register
|
; Make sure we don't trash an argument register
|
||||||
; CHECK-NOT: ldr {{x[0-7]}}, .LCPI1
|
; CHECK-NOT: movz {{x[0-7],}}
|
||||||
; CHECK: sub sp, sp,
|
; CHECK: sub sp, sp,
|
||||||
|
|
||||||
; CHECK-NOT: ldr {{x[0-7]}}, .LCPI1
|
; CHECK-NOT: movz {{x[0-7],}}
|
||||||
|
|
||||||
; CHECK: bl use_addr
|
; CHECK: bl use_addr
|
||||||
call void @use_addr(i8* %var)
|
call void @use_addr(i8* %var)
|
||||||
|
Loading…
Reference in New Issue
Block a user