[llvm] [M68k] Emit MOV16ds for moves from CCR on 68000 (PR #171703)
Daniel Thornburgh via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 10 13:00:36 PST 2025
https://github.com/mysterymath created https://github.com/llvm/llvm-project/pull/171703
This also marks CCR as a subregister of SR, which allows the value of SR to be tracked with respect to CCR. Finally, removes the 68010 requirement from moves from SR; this is a user mode instruction on 68000.
Fixes #85686
>From 870ad3318e7d2c5f388495daa5d99995c5cd13a1 Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <mysterymath at gmail.com>
Date: Mon, 24 Nov 2025 15:48:50 -0800
Subject: [PATCH] [M68k] Emit MOV16ds for moves from CCR on 68000
This also marks CCR as a subregister of SR, which allows the value of SR
to be tracked with respect to CCR. Finally, removes the 68010
requirement from moves from SR; this is a user mode instruction on
68000.
Fixes #85686
---
llvm/lib/Target/M68k/M68kInstrData.td | 6 +-
llvm/lib/Target/M68k/M68kInstrInfo.cpp | 5 +
llvm/lib/Target/M68k/M68kRegisterInfo.td | 2 +-
.../CodeGen/M68k/Control/non-cmov-switch.ll | 219 ++++++++++++------
4 files changed, 155 insertions(+), 77 deletions(-)
diff --git a/llvm/lib/Target/M68k/M68kInstrData.td b/llvm/lib/Target/M68k/M68kInstrData.td
index 053e545827a1a..9888b4c2b0633 100644
--- a/llvm/lib/Target/M68k/M68kInstrData.td
+++ b/llvm/lib/Target/M68k/M68kInstrData.td
@@ -464,14 +464,12 @@ def MOV16sd : MxMoveToSR<MxOp16AddrMode_d.Op, MxMoveSrcOpEnc_d>;
/// --------------------------------------------------
let Uses = [SR] in {
class MxMoveFromSR_R
- : MxInst<(outs MxDRD16:$dst), (ins SRC:$src), "move.w\t$src, $dst", []>,
- Requires<[ AtLeastM68010 ]> {
+ : MxInst<(outs MxDRD16:$dst), (ins SRC:$src), "move.w\t$src, $dst", []> {
let Inst = (descend 0b0100000011, MxEncAddrMode_d<"dst">.EA);
}
class MxMoveFromSR_M<MxOperand MEMOp, MxEncMemOp DST_ENC>
- : MxInst<(outs), (ins MEMOp:$dst, SRC:$src), "move.w\t$src, $dst", []>,
- Requires<[ AtLeastM68010 ]> {
+ : MxInst<(outs), (ins MEMOp:$dst, SRC:$src), "move.w\t$src, $dst", []> {
let Inst = (ascend
(descend 0b0100000011, DST_ENC.EA),
DST_ENC.Supplement
diff --git a/llvm/lib/Target/M68k/M68kInstrInfo.cpp b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
index b50397c375ba0..c27f5dc5eab1c 100644
--- a/llvm/lib/Target/M68k/M68kInstrInfo.cpp
+++ b/llvm/lib/Target/M68k/M68kInstrInfo.cpp
@@ -690,6 +690,7 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
const DebugLoc &DL, Register DstReg,
Register SrcReg, bool KillSrc,
bool RenamableDest, bool RenamableSrc) const {
+ const auto &Subtarget = MBB.getParent()->getSubtarget<M68kSubtarget>();
unsigned Opc = 0;
// First deal with the normal symmetric copies.
@@ -735,6 +736,10 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
if (FromCCR) {
Opc = M68k::MOV16dc;
+ if (!Subtarget.atLeastM68010()) {
+ Opc = M68k::MOV16ds;
+ SrcReg = M68k::SR;
+ }
if (!M68k::DR8RegClass.contains(DstReg) &&
!M68k::DR16RegClass.contains(DstReg) &&
!M68k::DR32RegClass.contains(DstReg)) {
diff --git a/llvm/lib/Target/M68k/M68kRegisterInfo.td b/llvm/lib/Target/M68k/M68kRegisterInfo.td
index 4942636ffd529..25492c6fc9406 100644
--- a/llvm/lib/Target/M68k/M68kRegisterInfo.td
+++ b/llvm/lib/Target/M68k/M68kRegisterInfo.td
@@ -87,7 +87,7 @@ class MxPseudoReg<string N, list<Register> SUBREGS = [], list<SubRegIndex> SUBID
: MxReg<N, 0, SUBREGS, SUBIDX>;
def CCR : MxPseudoReg<"ccr">;
-def SR : MxPseudoReg<"sr">;
+def SR : MxPseudoReg<"sr", [CCR], [MxSubRegIndex8Lo]>;
def PC : MxPseudoReg<"pc">;
diff --git a/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll b/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
index 9c9033e02f48e..2ce75d380e51e 100644
--- a/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
+++ b/llvm/test/CodeGen/M68k/Control/non-cmov-switch.ll
@@ -1,31 +1,57 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc < %s -mtriple=m68k-linux -mcpu=M68020 --verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -mtriple=m68k-linux -mcpu=M68000 --verify-machineinstrs | FileCheck --check-prefix=M68000 %s
+; RUN: llc < %s -mtriple=m68k-linux -mcpu=M68020 --verify-machineinstrs | FileCheck --check-prefix=M68020 %s
define internal void @select_i32(i32 %self, ptr nonnull %value) {
-; CHECK-LABEL: select_i32:
-; CHECK: .cfi_startproc
-; CHECK-NEXT: ; %bb.0: ; %start
-; CHECK-NEXT: suba.l #4, %sp
-; CHECK-NEXT: .cfi_def_cfa_offset -8
-; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
-; CHECK-NEXT: cmpi.l #0, (8,%sp)
-; CHECK-NEXT: move.w %ccr, %d2
-; CHECK-NEXT: sne %d1
-; CHECK-NEXT: move.l (12,%sp), %d0
-; CHECK-NEXT: move.w %d2, %ccr
-; CHECK-NEXT: bne .LBB0_2
-; CHECK-NEXT: ; %bb.1: ; %start
-; CHECK-NEXT: and.l #255, %d1
-; CHECK-NEXT: and.l #1, %d1
-; CHECK-NEXT: cmpi.l #0, %d1
-; CHECK-NEXT: bne .LBB0_3
-; CHECK-NEXT: .LBB0_2: ; %null
-; CHECK-NEXT: suba.l %a0, %a0
-; CHECK-NEXT: move.l %d0, (%a0)
-; CHECK-NEXT: .LBB0_3: ; %exit
-; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
-; CHECK-NEXT: adda.l #4, %sp
-; CHECK-NEXT: rts
+; M68000-LABEL: select_i32:
+; M68000: .cfi_startproc
+; M68000-NEXT: ; %bb.0: ; %start
+; M68000-NEXT: suba.l #4, %sp
+; M68000-NEXT: .cfi_def_cfa_offset -8
+; M68000-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; M68000-NEXT: cmpi.l #0, (8,%sp)
+; M68000-NEXT: move.w %sr, %d2
+; M68000-NEXT: sne %d1
+; M68000-NEXT: move.l (12,%sp), %d0
+; M68000-NEXT: move.w %d2, %ccr
+; M68000-NEXT: bne .LBB0_2
+; M68000-NEXT: ; %bb.1: ; %start
+; M68000-NEXT: and.l #255, %d1
+; M68000-NEXT: and.l #1, %d1
+; M68000-NEXT: cmpi.l #0, %d1
+; M68000-NEXT: bne .LBB0_3
+; M68000-NEXT: .LBB0_2: ; %null
+; M68000-NEXT: suba.l %a0, %a0
+; M68000-NEXT: move.l %d0, (%a0)
+; M68000-NEXT: .LBB0_3: ; %exit
+; M68000-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; M68000-NEXT: adda.l #4, %sp
+; M68000-NEXT: rts
+;
+; M68020-LABEL: select_i32:
+; M68020: .cfi_startproc
+; M68020-NEXT: ; %bb.0: ; %start
+; M68020-NEXT: suba.l #4, %sp
+; M68020-NEXT: .cfi_def_cfa_offset -8
+; M68020-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; M68020-NEXT: cmpi.l #0, (8,%sp)
+; M68020-NEXT: move.w %ccr, %d2
+; M68020-NEXT: sne %d1
+; M68020-NEXT: move.l (12,%sp), %d0
+; M68020-NEXT: move.w %d2, %ccr
+; M68020-NEXT: bne .LBB0_2
+; M68020-NEXT: ; %bb.1: ; %start
+; M68020-NEXT: and.l #255, %d1
+; M68020-NEXT: and.l #1, %d1
+; M68020-NEXT: cmpi.l #0, %d1
+; M68020-NEXT: bne .LBB0_3
+; M68020-NEXT: .LBB0_2: ; %null
+; M68020-NEXT: suba.l %a0, %a0
+; M68020-NEXT: move.l %d0, (%a0)
+; M68020-NEXT: .LBB0_3: ; %exit
+; M68020-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; M68020-NEXT: adda.l #4, %sp
+; M68020-NEXT: rts
start:
%2 = icmp eq i32 %self, 0
%3 = select i1 %2, i32 0, i32 1
@@ -47,30 +73,55 @@ exit: ; preds = %nonnull, %null
}
define internal void @select_i16(i16 %self, ptr nonnull %value) {
-; CHECK-LABEL: select_i16:
-; CHECK: .cfi_startproc
-; CHECK-NEXT: ; %bb.0: ; %start
-; CHECK-NEXT: suba.l #4, %sp
-; CHECK-NEXT: .cfi_def_cfa_offset -8
-; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
-; CHECK-NEXT: cmpi.w #0, (10,%sp)
-; CHECK-NEXT: move.w %ccr, %d2
-; CHECK-NEXT: sne %d1
-; CHECK-NEXT: move.l (12,%sp), %d0
-; CHECK-NEXT: move.w %d2, %ccr
-; CHECK-NEXT: bne .LBB1_2
-; CHECK-NEXT: ; %bb.1: ; %start
-; CHECK-NEXT: and.l #255, %d1
-; CHECK-NEXT: and.w #1, %d1
-; CHECK-NEXT: cmpi.w #0, %d1
-; CHECK-NEXT: bne .LBB1_3
-; CHECK-NEXT: .LBB1_2: ; %null
-; CHECK-NEXT: suba.l %a0, %a0
-; CHECK-NEXT: move.l %d0, (%a0)
-; CHECK-NEXT: .LBB1_3: ; %exit
-; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
-; CHECK-NEXT: adda.l #4, %sp
-; CHECK-NEXT: rts
+; M68000-LABEL: select_i16:
+; M68000: .cfi_startproc
+; M68000-NEXT: ; %bb.0: ; %start
+; M68000-NEXT: suba.l #4, %sp
+; M68000-NEXT: .cfi_def_cfa_offset -8
+; M68000-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; M68000-NEXT: cmpi.w #0, (10,%sp)
+; M68000-NEXT: move.w %sr, %d2
+; M68000-NEXT: sne %d1
+; M68000-NEXT: move.l (12,%sp), %d0
+; M68000-NEXT: move.w %d2, %ccr
+; M68000-NEXT: bne .LBB1_2
+; M68000-NEXT: ; %bb.1: ; %start
+; M68000-NEXT: and.l #255, %d1
+; M68000-NEXT: and.w #1, %d1
+; M68000-NEXT: cmpi.w #0, %d1
+; M68000-NEXT: bne .LBB1_3
+; M68000-NEXT: .LBB1_2: ; %null
+; M68000-NEXT: suba.l %a0, %a0
+; M68000-NEXT: move.l %d0, (%a0)
+; M68000-NEXT: .LBB1_3: ; %exit
+; M68000-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; M68000-NEXT: adda.l #4, %sp
+; M68000-NEXT: rts
+;
+; M68020-LABEL: select_i16:
+; M68020: .cfi_startproc
+; M68020-NEXT: ; %bb.0: ; %start
+; M68020-NEXT: suba.l #4, %sp
+; M68020-NEXT: .cfi_def_cfa_offset -8
+; M68020-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; M68020-NEXT: cmpi.w #0, (10,%sp)
+; M68020-NEXT: move.w %ccr, %d2
+; M68020-NEXT: sne %d1
+; M68020-NEXT: move.l (12,%sp), %d0
+; M68020-NEXT: move.w %d2, %ccr
+; M68020-NEXT: bne .LBB1_2
+; M68020-NEXT: ; %bb.1: ; %start
+; M68020-NEXT: and.l #255, %d1
+; M68020-NEXT: and.w #1, %d1
+; M68020-NEXT: cmpi.w #0, %d1
+; M68020-NEXT: bne .LBB1_3
+; M68020-NEXT: .LBB1_2: ; %null
+; M68020-NEXT: suba.l %a0, %a0
+; M68020-NEXT: move.l %d0, (%a0)
+; M68020-NEXT: .LBB1_3: ; %exit
+; M68020-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; M68020-NEXT: adda.l #4, %sp
+; M68020-NEXT: rts
start:
%2 = icmp eq i16 %self, 0
%3 = select i1 %2, i16 0, i16 1
@@ -92,29 +143,53 @@ exit: ; preds = %nonnull, %null
}
define internal void @select_i8(i8 %self, ptr nonnull %value) {
-; CHECK-LABEL: select_i8:
-; CHECK: .cfi_startproc
-; CHECK-NEXT: ; %bb.0: ; %start
-; CHECK-NEXT: suba.l #4, %sp
-; CHECK-NEXT: .cfi_def_cfa_offset -8
-; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
-; CHECK-NEXT: cmpi.b #0, (11,%sp)
-; CHECK-NEXT: move.w %ccr, %d2
-; CHECK-NEXT: sne %d1
-; CHECK-NEXT: move.l (12,%sp), %d0
-; CHECK-NEXT: move.w %d2, %ccr
-; CHECK-NEXT: bne .LBB2_2
-; CHECK-NEXT: ; %bb.1: ; %start
-; CHECK-NEXT: and.b #1, %d1
-; CHECK-NEXT: cmpi.b #0, %d1
-; CHECK-NEXT: bne .LBB2_3
-; CHECK-NEXT: .LBB2_2: ; %null
-; CHECK-NEXT: suba.l %a0, %a0
-; CHECK-NEXT: move.l %d0, (%a0)
-; CHECK-NEXT: .LBB2_3: ; %exit
-; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
-; CHECK-NEXT: adda.l #4, %sp
-; CHECK-NEXT: rts
+; M68000-LABEL: select_i8:
+; M68000: .cfi_startproc
+; M68000-NEXT: ; %bb.0: ; %start
+; M68000-NEXT: suba.l #4, %sp
+; M68000-NEXT: .cfi_def_cfa_offset -8
+; M68000-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; M68000-NEXT: cmpi.b #0, (11,%sp)
+; M68000-NEXT: move.w %sr, %d2
+; M68000-NEXT: sne %d1
+; M68000-NEXT: move.l (12,%sp), %d0
+; M68000-NEXT: move.w %d2, %ccr
+; M68000-NEXT: bne .LBB2_2
+; M68000-NEXT: ; %bb.1: ; %start
+; M68000-NEXT: and.b #1, %d1
+; M68000-NEXT: cmpi.b #0, %d1
+; M68000-NEXT: bne .LBB2_3
+; M68000-NEXT: .LBB2_2: ; %null
+; M68000-NEXT: suba.l %a0, %a0
+; M68000-NEXT: move.l %d0, (%a0)
+; M68000-NEXT: .LBB2_3: ; %exit
+; M68000-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; M68000-NEXT: adda.l #4, %sp
+; M68000-NEXT: rts
+;
+; M68020-LABEL: select_i8:
+; M68020: .cfi_startproc
+; M68020-NEXT: ; %bb.0: ; %start
+; M68020-NEXT: suba.l #4, %sp
+; M68020-NEXT: .cfi_def_cfa_offset -8
+; M68020-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
+; M68020-NEXT: cmpi.b #0, (11,%sp)
+; M68020-NEXT: move.w %ccr, %d2
+; M68020-NEXT: sne %d1
+; M68020-NEXT: move.l (12,%sp), %d0
+; M68020-NEXT: move.w %d2, %ccr
+; M68020-NEXT: bne .LBB2_2
+; M68020-NEXT: ; %bb.1: ; %start
+; M68020-NEXT: and.b #1, %d1
+; M68020-NEXT: cmpi.b #0, %d1
+; M68020-NEXT: bne .LBB2_3
+; M68020-NEXT: .LBB2_2: ; %null
+; M68020-NEXT: suba.l %a0, %a0
+; M68020-NEXT: move.l %d0, (%a0)
+; M68020-NEXT: .LBB2_3: ; %exit
+; M68020-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
+; M68020-NEXT: adda.l #4, %sp
+; M68020-NEXT: rts
start:
%2 = icmp eq i8 %self, 0
%3 = select i1 %2, i8 0, i8 1
More information about the llvm-commits
mailing list