Skip to content

Commit 64d326c

Browse files
committed
[M68k] Add MC support for link/unlk
Reviewers: myhsu Differential Revision: https://reviews.llvm.org/D125444
1 parent cf7c8bd commit 64d326c

File tree

6 files changed

+161
-19
lines changed

6 files changed

+161
-19
lines changed

llvm/lib/Target/M68k/M68kFrameLowering.cpp

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -546,9 +546,9 @@ void M68kFrameLowering::emitPrologue(MachineFunction &MF,
546546
// Update the frame offset adjustment.
547547
MFI.setOffsetAdjustment(-NumBytes);
548548

549-
// Save FP into the appropriate stack slot.
550-
BuildMI(MBB, MBBI, DL, TII.get(M68k::PUSH32r))
551-
.addReg(MachineFramePtr, RegState::Kill)
549+
BuildMI(MBB, MBBI, DL, TII.get(M68k::LINK16))
550+
.addReg(M68k::WA6, RegState::Kill)
551+
.addImm(-NumBytes)
552552
.setMIFlag(MachineInstr::FrameSetup);
553553

554554
if (NeedsDwarfCFI) {
@@ -566,11 +566,6 @@ void M68kFrameLowering::emitPrologue(MachineFunction &MF,
566566
2 * stackGrowth));
567567
}
568568

569-
// Update FP with the new base value.
570-
BuildMI(MBB, MBBI, DL, TII.get(M68k::MOV32aa), FramePtr)
571-
.addReg(StackPtr)
572-
.setMIFlag(MachineInstr::FrameSetup);
573-
574569
if (NeedsDwarfCFI) {
575570
// Mark effective beginning of when frame pointer becomes valid.
576571
// Define the current CFA to use the FP register.
@@ -619,7 +614,8 @@ void M68kFrameLowering::emitPrologue(MachineFunction &MF,
619614
NumBytes -= mergeSPUpdates(MBB, MBBI, true);
620615

621616
// Adjust stack pointer: ESP -= numbytes.
622-
emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, /*InEpilogue=*/false);
617+
if (!HasFP)
618+
emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, /*InEpilogue=*/false);
623619

624620
unsigned SPOrEstablisher = StackPtr;
625621

@@ -702,9 +698,6 @@ void M68kFrameLowering::emitEpilogue(MachineFunction &MF,
702698
if (TRI->hasStackRealignment(MF))
703699
NumBytes = alignTo(FrameSize, MaxAlign);
704700

705-
// Pop FP.
706-
BuildMI(MBB, MBBI, DL, TII.get(M68k::POP32r), MachineFramePtr)
707-
.setMIFlag(MachineInstr::FrameDestroy);
708701
} else {
709702
NumBytes = StackSize - CSSize;
710703
}
@@ -749,10 +742,15 @@ void M68kFrameLowering::emitEpilogue(MachineFunction &MF,
749742
LEAAmount);
750743
--MBBI;
751744
} else {
752-
unsigned Opc = (M68k::MOV32rr);
753-
BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr).addReg(FramePtr);
745+
BuildMI(MBB, MBBI, DL, TII.get(M68k::UNLK))
746+
.addReg(MachineFramePtr, RegState::Kill)
747+
.setMIFlag(MachineInstr::FrameDestroy);
754748
--MBBI;
755749
}
750+
} else if (hasFP(MF)) {
751+
BuildMI(MBB, MBBI, DL, TII.get(M68k::UNLK))
752+
.addReg(MachineFramePtr, RegState::Kill)
753+
.setMIFlag(MachineInstr::FrameDestroy);
756754
} else if (NumBytes) {
757755
// Adjust stack pointer back: SP += numbytes.
758756
emitSPUpdate(MBB, MBBI, NumBytes, /*InEpilogue=*/true);

llvm/lib/Target/M68k/M68kInstrData.td

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,35 @@ foreach AM = ["p", "f", "b", "q", "k"] in
437437
def LEA32 # AM : MxLEA<!cast<MxOpBundle>("MxOp32AddrMode_"#AM),
438438
!cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM)>;
439439

440+
//===----------------------------------------------------------------------===//
441+
// LINK/UNLK
442+
//===----------------------------------------------------------------------===//
443+
444+
let Uses = [SP], Defs = [SP] in {
445+
let mayStore = 1 in {
446+
447+
def LINK16 : MxInst<(outs), (ins MxARD16:$src, Mxi16imm:$disp), "link.w\t$src, $disp", []> {
448+
let Inst = (ascend
449+
(descend 0b0100111001010, (operand "$src", 3)),
450+
(operand "$disp", 16)
451+
);
452+
}
453+
454+
def LINK32 : MxInst<(outs), (ins MxARD16:$src, Mxi32imm:$disp), "link.l\t$src, $disp", []> {
455+
let Inst = (ascend
456+
(descend 0b0100100000001, (operand "$src", 3)),
457+
(slice "$disp", 31, 16),
458+
(slice "$disp", 15, 0)
459+
);
460+
}
461+
462+
def UNLK : MxInst<(outs), (ins MxARD32:$src), "unlk\t$src", []> {
463+
let Inst = (descend 0b0100111001011, (operand "$src", 3));
464+
}
465+
466+
} // let mayStore = 1
467+
} // let Uses = [SP], Defs = [SP]
468+
440469
//===----------------------------------------------------------------------===//
441470
// Pseudos
442471
//===----------------------------------------------------------------------===//

llvm/test/CodeGen/M68k/Alloc/dyn_alloca_aligned.ll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ define i32 @A(i32 %Size) {
44
; CHECK-LABEL: A:
55
; CHECK: .cfi_startproc
66
; CHECK-NEXT: ; %bb.0:
7-
; CHECK-NEXT: move.l %a6, -(%sp)
7+
; CHECK-NEXT: link.w %a6, #-128
88
; CHECK-NEXT: .cfi_def_cfa_offset -8
99
; CHECK-NEXT: .cfi_offset %a6, -8
10-
; CHECK-NEXT: move.l %sp, %a6
1110
; CHECK-NEXT: .cfi_def_cfa_register %a6
1211
; CHECK-NEXT: move.l %sp, %d0
1312
; CHECK-NEXT: and.l #-128, %d0
1413
; CHECK-NEXT: move.l %d0, %sp
15-
; CHECK-NEXT: suba.l #128, %sp
1614
; CHECK-NEXT: move.l %sp, %a4
1715
; CHECK-NEXT: movem.l %a4, (116,%a4) ; 8-byte Folded Spill
1816
; CHECK-NEXT: move.l (8,%a6), %d1
@@ -23,8 +21,7 @@ define i32 @A(i32 %Size) {
2321
; CHECK-NEXT: and.l #-128, %d0
2422
; CHECK-NEXT: move.l %d0, %sp
2523
; CHECK-NEXT: movem.l (116,%a4), %a4 ; 8-byte Folded Reload
26-
; CHECK-NEXT: move.l %a6, %sp
27-
; CHECK-NEXT: move.l (%sp)+, %a6
24+
; CHECK-NEXT: unlk %a6
2825
; CHECK-NEXT: rts
2926
%A = alloca i8, i32 %Size, align 128
3027
%A_addr = ptrtoint i8* %A to i32

llvm/test/CodeGen/M68k/link-unlnk.ll

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -frame-pointer=all -mtriple=m68k-linux-gnu %s -verify-machineinstrs -o - \
3+
; RUN: | FileCheck --check-prefix=FP %s
4+
5+
; RUN: llc -frame-pointer=none -mtriple=m68k-linux-gnu %s -verify-machineinstrs -o - \
6+
; RUN: | FileCheck --check-prefix=NO-FP %s
7+
8+
define i32 @fib(i32 %a, i32 %b) {
9+
; FP-LABEL: fib:
10+
; FP: .cfi_startproc
11+
; FP-NEXT: ; %bb.0: ; %entry
12+
; FP-NEXT: link.w %a6, #-32
13+
; FP-NEXT: .cfi_def_cfa_offset -8
14+
; FP-NEXT: .cfi_offset %a6, -8
15+
; FP-NEXT: .cfi_def_cfa_register %a6
16+
; FP-NEXT: move.l (8,%a6), %d1
17+
; FP-NEXT: move.l %d1, (-32,%a6)
18+
; FP-NEXT: move.l (12,%a6), %d0
19+
; FP-NEXT: add.l %d0, %d1
20+
; FP-NEXT: move.l %d0, (0,%a6)
21+
; FP-NEXT: add.l %d1, %d0
22+
; FP-NEXT: move.l %d1, (32,%a6)
23+
; FP-NEXT: add.l %d0, %d1
24+
; FP-NEXT: move.l %d0, (64,%a6)
25+
; FP-NEXT: move.l %d1, (96,%a6)
26+
; FP-NEXT: add.l %d1, %d0
27+
; FP-NEXT: move.l %d0, (128,%a6)
28+
; FP-NEXT: add.l %d0, %d1
29+
; FP-NEXT: move.l %d1, (160,%a6)
30+
; FP-NEXT: add.l %d1, %d0
31+
; FP-NEXT: move.l %d0, (192,%a6)
32+
; FP-NEXT: unlk %a6
33+
; FP-NEXT: rts
34+
;
35+
; NO-FP-LABEL: fib:
36+
; NO-FP: .cfi_startproc
37+
; NO-FP-NEXT: ; %bb.0: ; %entry
38+
; NO-FP-NEXT: suba.l #32, %sp
39+
; NO-FP-NEXT: .cfi_def_cfa_offset -36
40+
; NO-FP-NEXT: move.l (36,%sp), %d1
41+
; NO-FP-NEXT: move.l %d1, (0,%sp)
42+
; NO-FP-NEXT: move.l (40,%sp), %d0
43+
; NO-FP-NEXT: add.l %d0, %d1
44+
; NO-FP-NEXT: move.l %d0, (32,%sp)
45+
; NO-FP-NEXT: add.l %d1, %d0
46+
; NO-FP-NEXT: move.l %d1, (64,%sp)
47+
; NO-FP-NEXT: add.l %d0, %d1
48+
; NO-FP-NEXT: move.l %d0, (96,%sp)
49+
; NO-FP-NEXT: move.l %d1, (128,%sp)
50+
; NO-FP-NEXT: add.l %d1, %d0
51+
; NO-FP-NEXT: move.l %d0, (160,%sp)
52+
; NO-FP-NEXT: add.l %d0, %d1
53+
; NO-FP-NEXT: move.l %d1, (192,%sp)
54+
; NO-FP-NEXT: add.l %d1, %d0
55+
; NO-FP-NEXT: move.l %d0, (224,%sp)
56+
; NO-FP-NEXT: adda.l #32, %sp
57+
; NO-FP-NEXT: rts
58+
entry:
59+
%arr = alloca [8 x i32], align 4
60+
%s0 = getelementptr [8 x i32], ptr %arr, i32 0
61+
%s1 = getelementptr [8 x i32], ptr %arr, i32 1
62+
store i32 %a, i32* %s0
63+
store i32 %b, i32* %s1
64+
65+
%ptr0 = getelementptr [8 x i32], ptr %arr, i32 0
66+
%ptr1 = getelementptr [8 x i32], ptr %arr, i32 1
67+
%ptr2 = getelementptr [8 x i32], ptr %arr, i32 2
68+
%ptr3 = getelementptr [8 x i32], ptr %arr, i32 3
69+
%ptr4 = getelementptr [8 x i32], ptr %arr, i32 4
70+
%ptr5 = getelementptr [8 x i32], ptr %arr, i32 5
71+
%ptr6 = getelementptr [8 x i32], ptr %arr, i32 6
72+
%ptr7 = getelementptr [8 x i32], ptr %arr, i32 7
73+
74+
%res0 = load i32, i32 * %ptr0
75+
%res1 = load i32, i32 * %ptr1
76+
77+
%res2 = add i32 %res0, %res1
78+
store i32 %res2, i32 * %ptr2
79+
80+
%res3 = add i32 %res1, %res2
81+
store i32 %res3, i32 * %ptr3
82+
83+
%res4 = add i32 %res2, %res3
84+
store i32 %res4, i32 * %ptr4
85+
86+
%res5 = add i32 %res3, %res4
87+
store i32 %res5, i32 * %ptr5
88+
89+
%res6 = add i32 %res4, %res5
90+
store i32 %res6, i32 * %ptr6
91+
92+
%res7 = add i32 %res5, %res6
93+
store i32 %res7, i32 * %ptr7
94+
95+
ret i32 %res7
96+
}

llvm/test/MC/Disassembler/M68k/data.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# CHECK: move.l %a1, %a0
44
0x20 0x49
5+
56
# CHECK: lea (50,%a0), %a1
67
0x43 0xe8 0x00 0x32
78

@@ -52,3 +53,11 @@
5253

5354
# CHECK: move.l (129,%pc,%d2), %d3
5455
0x26 0x3b 0x28 0x81
56+
# CHECK: link.w %a3, #31
57+
0x4e 0x53 0x00 0x1f
58+
59+
# CHECK: link.l %a6, #65537
60+
0x48 0x0e 0x00 0x01 0x00 0x01
61+
62+
# CHECK: unlk %a0
63+
0x4e 0x58
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
; RUN: llvm-mc --show-encoding -triple=m68k %s | FileCheck %s
2+
3+
# CHECK: link.w %a2, #1023
4+
# CHECK-SAME: encoding: [0x4e,0x52,0x03,0xff]
5+
link.w %a2, #1023
6+
7+
# CHECK: link.l %a1, #1073741823
8+
# CHECK-SAME: encoding: [0x48,0x09,0x3f,0xff,0xff,0xff]
9+
link.l %a1, #1073741823
10+
11+
# CHECK: unlk %a5
12+
# CHECK-SAME: encoding: [0x4e,0x5d]
13+
unlk %a5

0 commit comments

Comments
 (0)