Skip to content

Commit 9be48e5

Browse files
committed
add pseudo instrs for 8 and 32 bit src/dst ccr moves and expand them to 16 bit instrs
1 parent c320df4 commit 9be48e5

File tree

5 files changed

+168
-13
lines changed

5 files changed

+168
-13
lines changed

llvm/lib/Target/M68k/M68kExpandPseudo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
190190

191191
case M68k::MOV8cd:
192192
return TII->ExpandCCR(MIB, /*IsToCCR=*/true);
193+
193194
case M68k::MOV8dc:
194195
return TII->ExpandCCR(MIB, /*IsToCCR=*/false);
195196

llvm/lib/Target/M68k/M68kInstrData.td

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ class MxMoveToCCRPseudo<MxOperand MEMOp>
385385

386386
let mayLoad = 1 in
387387
foreach AM = MxMoveSupportedAMs in {
388+
def MOV32c # AM : MxMoveToCCRPseudo<!cast<MxOpBundle>("MxOp32AddrMode_"#AM).Op>;
388389
def MOV16c # AM : MxMoveToCCR<!cast<MxOpBundle>("MxOp16AddrMode_"#AM).Op,
389390
!cast<MxEncMemOp>("MxMoveSrcOpEnc_"#AM)>;
390391
def MOV8c # AM : MxMoveToCCRPseudo<!cast<MxOpBundle>("MxOp8AddrMode_"#AM).Op>;
@@ -419,10 +420,15 @@ class MxMoveFromCCR_M<MxOperand MEMOp, MxEncMemOp DST_ENC>
419420

420421
class MxMoveFromCCRPseudo<MxOperand MEMOp>
421422
: MxPseudo<(outs), (ins MEMOp:$dst, CCRC:$src)>;
423+
class MxMoveFromCCR_RPseudo<MxOperand MEMOp>
424+
: MxPseudo<(outs MEMOp:$dst), (ins CCRC:$src)>;
422425
} // let Uses = [CCR]
423426

424427
let mayStore = 1 in
425428
foreach AM = MxMoveSupportedAMs in {
429+
def MOV32 # AM # c
430+
: MxMoveFromCCR_M<!cast<MxOpBundle>("MxOp32AddrMode_"#AM).Op,
431+
!cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM)>;
426432
def MOV16 # AM # c
427433
: MxMoveFromCCR_M<!cast<MxOpBundle>("MxOp16AddrMode_"#AM).Op,
428434
!cast<MxEncMemOp>("MxMoveDstOpEnc_"#AM)>;
@@ -432,7 +438,7 @@ foreach AM = MxMoveSupportedAMs in {
432438

433439
// Only data register is allowed.
434440
def MOV16dc : MxMoveFromCCR_R;
435-
def MOV8dc : MxMoveFromCCRPseudo<MxOp8AddrMode_d.Op>;
441+
def MOV8dc : MxMoveFromCCR_RPseudo<MxOp8AddrMode_d.Op>;
436442

437443
//===----------------------------------------------------------------------===//
438444
// LEA

llvm/lib/Target/M68k/M68kInstrInfo.cpp

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@
2323
#include "llvm/CodeGen/LivePhysRegs.h"
2424
#include "llvm/CodeGen/LiveVariables.h"
2525
#include "llvm/CodeGen/MachineInstrBuilder.h"
26+
#include "llvm/CodeGen/MachineOperand.h"
2627
#include "llvm/CodeGen/MachineRegisterInfo.h"
28+
#include "llvm/CodeGenTypes/MachineValueType.h"
2729
#include "llvm/MC/TargetRegistry.h"
2830
#include "llvm/Support/ErrorHandling.h"
2931
#include "llvm/Support/Regex.h"
3032

33+
#include <cassert>
3134
#include <functional>
35+
#include <iterator>
3236

3337
using namespace llvm;
3438

@@ -571,6 +575,17 @@ bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB,
571575
}
572576

573577
bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
578+
switch (MIB->getOpcode()) {
579+
case M68k::MOV8cd: {
580+
// Promote used register to the next class
581+
auto &Opd = MIB->getOperand(1);
582+
Opd.setReg(getRegisterInfo().getMatchingSuperReg(
583+
Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));
584+
break;
585+
}
586+
default:
587+
break;
588+
}
574589

575590
// Replace the pseudo instruction with the real one
576591
if (IsToCCR)
@@ -579,11 +594,6 @@ bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
579594
// FIXME M68010 or later is required
580595
MIB->setDesc(get(M68k::MOV16dc));
581596

582-
// Promote used register to the next class
583-
auto &Opd = MIB->getOperand(1);
584-
Opd.setReg(getRegisterInfo().getMatchingSuperReg(
585-
Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));
586-
587597
return true;
588598
}
589599

@@ -757,13 +767,25 @@ void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
757767
bool ToSR = DstReg == M68k::SR;
758768

759769
if (FromCCR) {
760-
assert(M68k::DR8RegClass.contains(DstReg) &&
761-
"Need DR8 register to copy CCR");
762-
Opc = M68k::MOV8dc;
770+
if (M68k::DR8RegClass.contains(DstReg))
771+
Opc = M68k::MOV8dc;
772+
else if (M68k::DR16RegClass.contains(DstReg))
773+
Opc = M68k::MOV16dc;
774+
else {
775+
LLVM_DEBUG(dbgs() << "Cannot copy CCR to " << RI.getName(DstReg) << "("
776+
<< RI.getRegClass(DstReg) << ")\n");
777+
llvm_unreachable("Invalid register for MOVE from CCR");
778+
}
763779
} else if (ToCCR) {
764-
assert(M68k::DR8RegClass.contains(SrcReg) &&
765-
"Need DR8 register to copy CCR");
766-
Opc = M68k::MOV8cd;
780+
if (M68k::DR8RegClass.contains(SrcReg))
781+
Opc = M68k::MOV8cd;
782+
else if (M68k::DR16RegClass.contains(SrcReg))
783+
Opc = M68k::MOV16cd;
784+
else {
785+
LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to CCR"
786+
<< '\n');
787+
llvm_unreachable("Invalid register for MOVE to CCR");
788+
}
767789
} else if (FromSR || ToSR)
768790
llvm_unreachable("Cannot emit SR copy instruction");
769791

llvm/lib/Target/M68k/M68kRegisterInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class M68kRegisterInfo : public M68kGenRegisterInfo {
101101
const TargetRegisterClass *
102102
getCrossCopyRegClass(const TargetRegisterClass *RC) const override {
103103
if (RC == &M68k::CCRCRegClass)
104-
return &M68k::DR32RegClass;
104+
return &M68k::DR16RegClass;
105105
return RC;
106106
}
107107

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc < %s -mtriple=m68k-linux -mcpu=M68020 --verify-machineinstrs | FileCheck %s
3+
4+
define internal void @select_i32(i32 %self, ptr nonnull %value) {
5+
; CHECK-LABEL: select_i32:
6+
; CHECK: .cfi_startproc
7+
; CHECK-NEXT: ; %bb.0: ; %start
8+
; CHECK-NEXT: suba.l #4, %sp
9+
; CHECK-NEXT: .cfi_def_cfa_offset -8
10+
; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
11+
; CHECK-NEXT: cmpi.l #0, (8,%sp)
12+
; CHECK-NEXT: move.w %ccr, %d2
13+
; CHECK-NEXT: sne %d1
14+
; CHECK-NEXT: move.l (12,%sp), %d0
15+
; CHECK-NEXT: move.w %d2, %ccr
16+
; CHECK-NEXT: bne .LBB0_2
17+
; CHECK-NEXT: ; %bb.1: ; %start
18+
; CHECK-NEXT: and.l #255, %d1
19+
; CHECK-NEXT: cmpi.l #0, %d1
20+
; CHECK-NEXT: bne .LBB0_3
21+
; CHECK-NEXT: .LBB0_2: ; %null
22+
; CHECK-NEXT: suba.l %a0, %a0
23+
; CHECK-NEXT: move.l %d0, (%a0)
24+
; CHECK-NEXT: .LBB0_3: ; %exit
25+
; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
26+
; CHECK-NEXT: adda.l #4, %sp
27+
; CHECK-NEXT: rts
28+
start:
29+
%2 = icmp eq i32 %self, 0
30+
%3 = select i1 %2, i32 0, i32 1
31+
switch i32 %3, label %exit [
32+
i32 0, label %nonnull
33+
i32 1, label %null
34+
]
35+
36+
nonnull: ; preds = %start
37+
store ptr %value, ptr null, align 2
38+
br label %exit
39+
40+
null: ; preds = %start
41+
store ptr %value, ptr null, align 2
42+
br label %exit
43+
44+
exit: ; preds = %nonnull, %null
45+
ret void
46+
}
47+
48+
define internal void @select_i16(i16 %self, ptr nonnull %value) {
49+
; CHECK-LABEL: select_i16:
50+
; CHECK: .cfi_startproc
51+
; CHECK-NEXT: ; %bb.0: ; %start
52+
; CHECK-NEXT: suba.l #4, %sp
53+
; CHECK-NEXT: .cfi_def_cfa_offset -8
54+
; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
55+
; CHECK-NEXT: cmpi.w #0, (10,%sp)
56+
; CHECK-NEXT: move.w %ccr, %d2
57+
; CHECK-NEXT: sne %d1
58+
; CHECK-NEXT: move.l (12,%sp), %d0
59+
; CHECK-NEXT: move.w %d2, %ccr
60+
; CHECK-NEXT: bne .LBB1_2
61+
; CHECK-NEXT: ; %bb.1: ; %start
62+
; CHECK-NEXT: and.l #255, %d1
63+
; CHECK-NEXT: cmpi.w #0, %d1
64+
; CHECK-NEXT: bne .LBB1_3
65+
; CHECK-NEXT: .LBB1_2: ; %null
66+
; CHECK-NEXT: suba.l %a0, %a0
67+
; CHECK-NEXT: move.l %d0, (%a0)
68+
; CHECK-NEXT: .LBB1_3: ; %exit
69+
; CHECK-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
70+
; CHECK-NEXT: adda.l #4, %sp
71+
; CHECK-NEXT: rts
72+
start:
73+
%2 = icmp eq i16 %self, 0
74+
%3 = select i1 %2, i16 0, i16 1
75+
switch i16 %3, label %exit [
76+
i16 0, label %nonnull
77+
i16 1, label %null
78+
]
79+
80+
nonnull: ; preds = %start
81+
store ptr %value, ptr null, align 2
82+
br label %exit
83+
84+
null: ; preds = %start
85+
store ptr %value, ptr null, align 2
86+
br label %exit
87+
88+
exit: ; preds = %nonnull, %null
89+
ret void
90+
}
91+
92+
define internal void @select_i8(i8 %self, ptr nonnull %value) {
93+
; CHECK-LABEL: select_i8:
94+
; CHECK: .cfi_startproc
95+
; CHECK-NEXT: ; %bb.0: ; %start
96+
; CHECK-NEXT: move.l (8,%sp), %d0
97+
; CHECK-NEXT: cmpi.b #0, (7,%sp)
98+
; CHECK-NEXT: sne %d1
99+
; CHECK-NEXT: bne .LBB2_2
100+
; CHECK-NEXT: ; %bb.1: ; %start
101+
; CHECK-NEXT: cmpi.b #0, %d1
102+
; CHECK-NEXT: bne .LBB2_3
103+
; CHECK-NEXT: .LBB2_2: ; %null
104+
; CHECK-NEXT: suba.l %a0, %a0
105+
; CHECK-NEXT: move.l %d0, (%a0)
106+
; CHECK-NEXT: .LBB2_3: ; %exit
107+
; CHECK-NEXT: rts
108+
start:
109+
%2 = icmp eq i8 %self, 0
110+
%3 = select i1 %2, i8 0, i8 1
111+
switch i8 %3, label %exit [
112+
i8 0, label %nonnull
113+
i8 1, label %null
114+
]
115+
116+
nonnull: ; preds = %start
117+
store ptr %value, ptr null, align 2
118+
br label %exit
119+
120+
null: ; preds = %start
121+
store ptr %value, ptr null, align 2
122+
br label %exit
123+
124+
exit: ; preds = %nonnull, %null
125+
ret void
126+
}

0 commit comments

Comments
 (0)