[M68k] Add MC support for link/unlk
Reviewers: myhsu Differential Revision: https://reviews.llvm.org/D125444
This commit is contained in:
parent
cf7c8bd74e
commit
64d326c33c
|
@ -546,9 +546,9 @@ void M68kFrameLowering::emitPrologue(MachineFunction &MF,
|
|||
// Update the frame offset adjustment.
|
||||
MFI.setOffsetAdjustment(-NumBytes);
|
||||
|
||||
// Save FP into the appropriate stack slot.
|
||||
BuildMI(MBB, MBBI, DL, TII.get(M68k::PUSH32r))
|
||||
.addReg(MachineFramePtr, RegState::Kill)
|
||||
BuildMI(MBB, MBBI, DL, TII.get(M68k::LINK16))
|
||||
.addReg(M68k::WA6, RegState::Kill)
|
||||
.addImm(-NumBytes)
|
||||
.setMIFlag(MachineInstr::FrameSetup);
|
||||
|
||||
if (NeedsDwarfCFI) {
|
||||
|
@ -566,11 +566,6 @@ void M68kFrameLowering::emitPrologue(MachineFunction &MF,
|
|||
2 * stackGrowth));
|
||||
}
|
||||
|
||||
// Update FP with the new base value.
|
||||
BuildMI(MBB, MBBI, DL, TII.get(M68k::MOV32aa), FramePtr)
|
||||
.addReg(StackPtr)
|
||||
.setMIFlag(MachineInstr::FrameSetup);
|
||||
|
||||
if (NeedsDwarfCFI) {
|
||||
// Mark effective beginning of when frame pointer becomes valid.
|
||||
// Define the current CFA to use the FP register.
|
||||
|
@ -619,7 +614,8 @@ void M68kFrameLowering::emitPrologue(MachineFunction &MF,
|
|||
NumBytes -= mergeSPUpdates(MBB, MBBI, true);
|
||||
|
||||
// Adjust stack pointer: ESP -= numbytes.
|
||||
emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, /*InEpilogue=*/false);
|
||||
if (!HasFP)
|
||||
emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, /*InEpilogue=*/false);
|
||||
|
||||
unsigned SPOrEstablisher = StackPtr;
|
||||
|
||||
|
@ -702,9 +698,6 @@ void M68kFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||
if (TRI->hasStackRealignment(MF))
|
||||
NumBytes = alignTo(FrameSize, MaxAlign);
|
||||
|
||||
// Pop FP.
|
||||
BuildMI(MBB, MBBI, DL, TII.get(M68k::POP32r), MachineFramePtr)
|
||||
.setMIFlag(MachineInstr::FrameDestroy);
|
||||
} else {
|
||||
NumBytes = StackSize - CSSize;
|
||||
}
|
||||
|
@ -749,10 +742,15 @@ void M68kFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||
LEAAmount);
|
||||
--MBBI;
|
||||
} else {
|
||||
unsigned Opc = (M68k::MOV32rr);
|
||||
BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr).addReg(FramePtr);
|
||||
BuildMI(MBB, MBBI, DL, TII.get(M68k::UNLK))
|
||||
.addReg(MachineFramePtr, RegState::Kill)
|
||||
.setMIFlag(MachineInstr::FrameDestroy);
|
||||
--MBBI;
|
||||
}
|
||||
} else if (hasFP(MF)) {
|
||||
BuildMI(MBB, MBBI, DL, TII.get(M68k::UNLK))
|
||||
.addReg(MachineFramePtr, RegState::Kill)
|
||||
.setMIFlag(MachineInstr::FrameDestroy);
|
||||
} else if (NumBytes) {
|
||||
// Adjust stack pointer back: SP += numbytes.
|
||||
emitSPUpdate(MBB, MBBI, NumBytes, /*InEpilogue=*/true);
|
||||
|
|
|
@ -437,6 +437,35 @@ foreach AM = ["p", "f", "b", "q", "k"] in
|
|||
def LEA32 # AM : MxLEA<!cast<MxOpBundle>("MxOp32AddrMode_"#AM),
|
||||
!cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM)>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// LINK/UNLK
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let Uses = [SP], Defs = [SP] in {
|
||||
let mayStore = 1 in {
|
||||
|
||||
def LINK16 : MxInst<(outs), (ins MxARD16:$src, Mxi16imm:$disp), "link.w\t$src, $disp", []> {
|
||||
let Inst = (ascend
|
||||
(descend 0b0100111001010, (operand "$src", 3)),
|
||||
(operand "$disp", 16)
|
||||
);
|
||||
}
|
||||
|
||||
def LINK32 : MxInst<(outs), (ins MxARD16:$src, Mxi32imm:$disp), "link.l\t$src, $disp", []> {
|
||||
let Inst = (ascend
|
||||
(descend 0b0100100000001, (operand "$src", 3)),
|
||||
(slice "$disp", 31, 16),
|
||||
(slice "$disp", 15, 0)
|
||||
);
|
||||
}
|
||||
|
||||
def UNLK : MxInst<(outs), (ins MxARD32:$src), "unlk\t$src", []> {
|
||||
let Inst = (descend 0b0100111001011, (operand "$src", 3));
|
||||
}
|
||||
|
||||
} // let mayStore = 1
|
||||
} // let Uses = [SP], Defs = [SP]
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Pseudos
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -4,15 +4,13 @@ define i32 @A(i32 %Size) {
|
|||
; CHECK-LABEL: A:
|
||||
; CHECK: .cfi_startproc
|
||||
; CHECK-NEXT: ; %bb.0:
|
||||
; CHECK-NEXT: move.l %a6, -(%sp)
|
||||
; CHECK-NEXT: link.w %a6, #-128
|
||||
; CHECK-NEXT: .cfi_def_cfa_offset -8
|
||||
; CHECK-NEXT: .cfi_offset %a6, -8
|
||||
; CHECK-NEXT: move.l %sp, %a6
|
||||
; CHECK-NEXT: .cfi_def_cfa_register %a6
|
||||
; CHECK-NEXT: move.l %sp, %d0
|
||||
; CHECK-NEXT: and.l #-128, %d0
|
||||
; CHECK-NEXT: move.l %d0, %sp
|
||||
; CHECK-NEXT: suba.l #128, %sp
|
||||
; CHECK-NEXT: move.l %sp, %a4
|
||||
; CHECK-NEXT: movem.l %a4, (116,%a4) ; 8-byte Folded Spill
|
||||
; CHECK-NEXT: move.l (8,%a6), %d1
|
||||
|
@ -23,8 +21,7 @@ define i32 @A(i32 %Size) {
|
|||
; CHECK-NEXT: and.l #-128, %d0
|
||||
; CHECK-NEXT: move.l %d0, %sp
|
||||
; CHECK-NEXT: movem.l (116,%a4), %a4 ; 8-byte Folded Reload
|
||||
; CHECK-NEXT: move.l %a6, %sp
|
||||
; CHECK-NEXT: move.l (%sp)+, %a6
|
||||
; CHECK-NEXT: unlk %a6
|
||||
; CHECK-NEXT: rts
|
||||
%A = alloca i8, i32 %Size, align 128
|
||||
%A_addr = ptrtoint i8* %A to i32
|
||||
|
|
96
llvm/test/CodeGen/M68k/link-unlnk.ll
Normal file
96
llvm/test/CodeGen/M68k/link-unlnk.ll
Normal file
|
@ -0,0 +1,96 @@
|
|||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -frame-pointer=all -mtriple=m68k-linux-gnu %s -verify-machineinstrs -o - \
|
||||
; RUN: | FileCheck --check-prefix=FP %s
|
||||
|
||||
; RUN: llc -frame-pointer=none -mtriple=m68k-linux-gnu %s -verify-machineinstrs -o - \
|
||||
; RUN: | FileCheck --check-prefix=NO-FP %s
|
||||
|
||||
define i32 @fib(i32 %a, i32 %b) {
|
||||
; FP-LABEL: fib:
|
||||
; FP: .cfi_startproc
|
||||
; FP-NEXT: ; %bb.0: ; %entry
|
||||
; FP-NEXT: link.w %a6, #-32
|
||||
; FP-NEXT: .cfi_def_cfa_offset -8
|
||||
; FP-NEXT: .cfi_offset %a6, -8
|
||||
; FP-NEXT: .cfi_def_cfa_register %a6
|
||||
; FP-NEXT: move.l (8,%a6), %d1
|
||||
; FP-NEXT: move.l %d1, (-32,%a6)
|
||||
; FP-NEXT: move.l (12,%a6), %d0
|
||||
; FP-NEXT: add.l %d0, %d1
|
||||
; FP-NEXT: move.l %d0, (0,%a6)
|
||||
; FP-NEXT: add.l %d1, %d0
|
||||
; FP-NEXT: move.l %d1, (32,%a6)
|
||||
; FP-NEXT: add.l %d0, %d1
|
||||
; FP-NEXT: move.l %d0, (64,%a6)
|
||||
; FP-NEXT: move.l %d1, (96,%a6)
|
||||
; FP-NEXT: add.l %d1, %d0
|
||||
; FP-NEXT: move.l %d0, (128,%a6)
|
||||
; FP-NEXT: add.l %d0, %d1
|
||||
; FP-NEXT: move.l %d1, (160,%a6)
|
||||
; FP-NEXT: add.l %d1, %d0
|
||||
; FP-NEXT: move.l %d0, (192,%a6)
|
||||
; FP-NEXT: unlk %a6
|
||||
; FP-NEXT: rts
|
||||
;
|
||||
; NO-FP-LABEL: fib:
|
||||
; NO-FP: .cfi_startproc
|
||||
; NO-FP-NEXT: ; %bb.0: ; %entry
|
||||
; NO-FP-NEXT: suba.l #32, %sp
|
||||
; NO-FP-NEXT: .cfi_def_cfa_offset -36
|
||||
; NO-FP-NEXT: move.l (36,%sp), %d1
|
||||
; NO-FP-NEXT: move.l %d1, (0,%sp)
|
||||
; NO-FP-NEXT: move.l (40,%sp), %d0
|
||||
; NO-FP-NEXT: add.l %d0, %d1
|
||||
; NO-FP-NEXT: move.l %d0, (32,%sp)
|
||||
; NO-FP-NEXT: add.l %d1, %d0
|
||||
; NO-FP-NEXT: move.l %d1, (64,%sp)
|
||||
; NO-FP-NEXT: add.l %d0, %d1
|
||||
; NO-FP-NEXT: move.l %d0, (96,%sp)
|
||||
; NO-FP-NEXT: move.l %d1, (128,%sp)
|
||||
; NO-FP-NEXT: add.l %d1, %d0
|
||||
; NO-FP-NEXT: move.l %d0, (160,%sp)
|
||||
; NO-FP-NEXT: add.l %d0, %d1
|
||||
; NO-FP-NEXT: move.l %d1, (192,%sp)
|
||||
; NO-FP-NEXT: add.l %d1, %d0
|
||||
; NO-FP-NEXT: move.l %d0, (224,%sp)
|
||||
; NO-FP-NEXT: adda.l #32, %sp
|
||||
; NO-FP-NEXT: rts
|
||||
entry:
|
||||
%arr = alloca [8 x i32], align 4
|
||||
%s0 = getelementptr [8 x i32], ptr %arr, i32 0
|
||||
%s1 = getelementptr [8 x i32], ptr %arr, i32 1
|
||||
store i32 %a, i32* %s0
|
||||
store i32 %b, i32* %s1
|
||||
|
||||
%ptr0 = getelementptr [8 x i32], ptr %arr, i32 0
|
||||
%ptr1 = getelementptr [8 x i32], ptr %arr, i32 1
|
||||
%ptr2 = getelementptr [8 x i32], ptr %arr, i32 2
|
||||
%ptr3 = getelementptr [8 x i32], ptr %arr, i32 3
|
||||
%ptr4 = getelementptr [8 x i32], ptr %arr, i32 4
|
||||
%ptr5 = getelementptr [8 x i32], ptr %arr, i32 5
|
||||
%ptr6 = getelementptr [8 x i32], ptr %arr, i32 6
|
||||
%ptr7 = getelementptr [8 x i32], ptr %arr, i32 7
|
||||
|
||||
%res0 = load i32, i32 * %ptr0
|
||||
%res1 = load i32, i32 * %ptr1
|
||||
|
||||
%res2 = add i32 %res0, %res1
|
||||
store i32 %res2, i32 * %ptr2
|
||||
|
||||
%res3 = add i32 %res1, %res2
|
||||
store i32 %res3, i32 * %ptr3
|
||||
|
||||
%res4 = add i32 %res2, %res3
|
||||
store i32 %res4, i32 * %ptr4
|
||||
|
||||
%res5 = add i32 %res3, %res4
|
||||
store i32 %res5, i32 * %ptr5
|
||||
|
||||
%res6 = add i32 %res4, %res5
|
||||
store i32 %res6, i32 * %ptr6
|
||||
|
||||
%res7 = add i32 %res5, %res6
|
||||
store i32 %res7, i32 * %ptr7
|
||||
|
||||
ret i32 %res7
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
# CHECK: move.l %a1, %a0
|
||||
0x20 0x49
|
||||
|
||||
# CHECK: lea (50,%a0), %a1
|
||||
0x43 0xe8 0x00 0x32
|
||||
|
||||
|
@ -52,3 +53,11 @@
|
|||
|
||||
# CHECK: move.l (129,%pc,%d2), %d3
|
||||
0x26 0x3b 0x28 0x81
|
||||
# CHECK: link.w %a3, #31
|
||||
0x4e 0x53 0x00 0x1f
|
||||
|
||||
# CHECK: link.l %a6, #65537
|
||||
0x48 0x0e 0x00 0x01 0x00 0x01
|
||||
|
||||
# CHECK: unlk %a0
|
||||
0x4e 0x58
|
||||
|
|
13
llvm/test/MC/M68k/Data/Classes/MxLink.s
Normal file
13
llvm/test/MC/M68k/Data/Classes/MxLink.s
Normal file
|
@ -0,0 +1,13 @@
|
|||
; RUN: llvm-mc --show-encoding -triple=m68k %s | FileCheck %s
|
||||
|
||||
# CHECK: link.w %a2, #1023
|
||||
# CHECK-SAME: encoding: [0x4e,0x52,0x03,0xff]
|
||||
link.w %a2, #1023
|
||||
|
||||
# CHECK: link.l %a1, #1073741823
|
||||
# CHECK-SAME: encoding: [0x48,0x09,0x3f,0xff,0xff,0xff]
|
||||
link.l %a1, #1073741823
|
||||
|
||||
# CHECK: unlk %a5
|
||||
# CHECK-SAME: encoding: [0x4e,0x5d]
|
||||
unlk %a5
|
Loading…
Reference in New Issue
Block a user