Skip to content

[M68k] Add support for MOVEQ instruction #88542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions llvm/lib/Target/M68k/M68kExpandPseudo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ bool M68kExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
default:
return false;

case M68k::MOVI8di:
return TII->ExpandMOVI(MIB, MVT::i8);
case M68k::MOVI16ri:
return TII->ExpandMOVI(MIB, MVT::i16);
case M68k::MOVI32ri:
return TII->ExpandMOVI(MIB, MVT::i32);

case M68k::MOVXd16d8:
return TII->ExpandMOVX_RR(MIB, MVT::i16, MVT::i8);
case M68k::MOVXd32d8:
Expand Down
41 changes: 38 additions & 3 deletions llvm/lib/Target/M68k/M68kInstrData.td
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
///
/// Pseudo:
///
/// MOVSX [x] MOVZX [x] MOVX [x]
/// MOVI [x] MOVSX [x] MOVZX [x] MOVX [x]
///
/// Map:
///
Expand Down Expand Up @@ -165,11 +165,12 @@ foreach AM = MxMoveSupportedAMs in {
} // foreach AM

// R <- I
// No pattern, as all immediate -> register moves are matched to the MOVI pseudo
class MxMove_RI<MxType TYPE, string DST_REG, MxMoveEncoding ENC,
MxImmOpBundle SRC = !cast<MxImmOpBundle>("MxOp"#TYPE.Size#"AddrMode_i"),
MxOpBundle DST = !cast<MxOpBundle>("MxOp"#TYPE.Size#"AddrMode_"#DST_REG)>
: MxMove<TYPE.Prefix, (outs DST.Op:$dst), (ins SRC.Op:$src),
[(set TYPE.VT:$dst, SRC.ImmPat:$src)], ENC>;
[(null_frag)], ENC>;

foreach REG = ["r", "a", "d"] in {
foreach TYPE = !if(!eq(REG, "d"), [MxType8, MxType16, MxType32], [MxType16, MxType32]) in
Expand Down Expand Up @@ -242,6 +243,24 @@ def : Pat<(store MxType32.BPat :$src, MxType32.BPat :$dst),
def : Pat<(store MxType32.BPat :$src, MxType32.JPat :$dst),
(MOV32ji MxType32.JOp :$dst, MxType32.IOp :$src)>;

//===----------------------------------------------------------------------===//
// MOVEQ
//===----------------------------------------------------------------------===//

/// ------------+---------+---+-----------------------
/// F E D C | B A 9 | 8 | 7 6 5 4 3 2 1 0
/// ------------+---------+---+-----------------------
/// 0 1 1 1 | REG | 0 | DATA
/// ------------+---------+---+-----------------------

// No pattern, as all immediate -> register moves are matched to the MOVI pseudo
let Defs = [CCR] in
def MOVQ : MxInst<(outs MxDRD32:$dst), (ins Mxi8imm:$imm),
"moveq\t$imm, $dst",
[(null_frag)]> {
let Inst = (descend 0b0111, (operand "$dst", 3), 0b0, (operand "$imm", 8));
}

//===----------------------------------------------------------------------===//
// MOVEM
//
Expand Down Expand Up @@ -496,7 +515,23 @@ class MxPseudoMove_RR<MxType DST, MxType SRC, list<dag> PAT = []>

class MxPseudoMove_RM<MxType DST, MxOperand SRCOpd, list<dag> PAT = []>
: MxPseudo<(outs DST.ROp:$dst), (ins SRCOpd:$src), PAT>;
}


// These Pseudos handle loading immediates to registers.
// They are expanded post-RA into either move or moveq instructions,
// depending on size, destination register class, and immediate value.
// This is done with pseudoinstructions in order to not constrain RA to
// data registers if moveq matches.
class MxPseudoMove_DI<MxType TYPE>
: MxPseudo<(outs TYPE.ROp:$dst), (ins TYPE.IOp:$src),
[(set TYPE.ROp:$dst, imm:$src)]>;

// i8 imm -> reg can always be converted to moveq,
// but we still emit a pseudo for consistency.
def MOVI8di : MxPseudoMove_DI<MxType8d>;
def MOVI16ri : MxPseudoMove_DI<MxType16r>;
def MOVI32ri : MxPseudoMove_DI<MxType32r>;
} // let Defs = [CCR]

/// This group of Pseudos is analogues to the real x86 extending moves, but
/// since M68k does not have those we need to emulate. These instructions
Expand Down
34 changes: 34 additions & 0 deletions llvm/lib/Target/M68k/M68kInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,40 @@ void M68kInstrInfo::AddZExt(MachineBasicBlock &MBB,
BuildMI(MBB, I, DL, get(And), Reg).addReg(Reg).addImm(Mask);
}

// Convert MOVI to MOVQ if the target is a data register and the immediate
// fits in a sign-extended i8, otherwise emit a plain MOV.
bool M68kInstrInfo::ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const {
Register Reg = MIB->getOperand(0).getReg();
int64_t Imm = MIB->getOperand(1).getImm();
bool IsAddressReg = false;

const auto *DR32 = RI.getRegClass(M68k::DR32RegClassID);
const auto *AR32 = RI.getRegClass(M68k::AR32RegClassID);
const auto *AR16 = RI.getRegClass(M68k::AR16RegClassID);

if (AR16->contains(Reg) || AR32->contains(Reg))
IsAddressReg = true;

LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");

if (MVTSize == MVT::i8 || (!IsAddressReg && Imm >= -128 && Imm <= 127)) {
LLVM_DEBUG(dbgs() << "MOVEQ\n");

// We need to assign to the full register to make IV happy
Register SReg =
MVTSize == MVT::i32 ? Reg : Register(RI.getMatchingMegaReg(Reg, DR32));
assert(SReg && "No viable MEGA register available");

MIB->setDesc(get(M68k::MOVQ));
MIB->getOperand(0).setReg(SReg);
} else {
LLVM_DEBUG(dbgs() << "MOVE\n");
MIB->setDesc(get(MVTSize == MVT::i16 ? M68k::MOV16ri : M68k::MOV32ri));
}

return true;
}

bool M68kInstrInfo::ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst,
MVT MVTSrc) const {
unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/M68k/M68kInstrInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ class M68kInstrInfo : public M68kGenInstrInfo {
void AddZExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
DebugLoc DL, unsigned Reg, MVT From, MVT To) const;

/// Move immediate to register
bool ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const;

/// Move across register classes without extension
bool ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst, MVT MVTSrc) const;

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/M68k/Arith/add-with-overflow.ll
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ define fastcc i1 @test6(i32 %v1, i32 %v2, ptr %X) nounwind {
; CHECK-NEXT: ; %bb.1: ; %normal
; CHECK-NEXT: move.l #0, (%a0)
; CHECK-NEXT: .LBB1_2: ; %carry
; CHECK-NEXT: move.b #0, %d0
; CHECK-NEXT: moveq #0, %d0
; CHECK-NEXT: rts
entry:
%t = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %v1, i32 %v2)
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/M68k/Arith/add.ll
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ define fastcc void @test3(ptr inreg %a) nounwind {
; CHECK-NEXT: suba.l #4, %sp
; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
; CHECK-NEXT: move.l (%a0), %d0
; CHECK-NEXT: move.l #0, %d1
; CHECK-NEXT: moveq #0, %d1
; CHECK-NEXT: move.l #-2147483648, %d2
; CHECK-NEXT: add.l (4,%a0), %d2
; CHECK-NEXT: addx.l %d0, %d1
Expand All @@ -64,7 +64,7 @@ define fastcc void @test4(ptr inreg %a) nounwind {
; CHECK-NEXT: suba.l #4, %sp
; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
; CHECK-NEXT: move.l (%a0), %d0
; CHECK-NEXT: move.l #0, %d1
; CHECK-NEXT: moveq #0, %d1
; CHECK-NEXT: move.l #128, %d2
; CHECK-NEXT: add.l (4,%a0), %d2
; CHECK-NEXT: addx.l %d0, %d1
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/CodeGen/M68k/Arith/bitwise.ll
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ define i64 @lshr64(i64 %a, i64 %b) nounwind {
; CHECK-NEXT: add.l #-32, %d1
; CHECK-NEXT: bmi .LBB18_1
; CHECK-NEXT: ; %bb.2:
; CHECK-NEXT: move.l #0, %d0
; CHECK-NEXT: moveq #0, %d0
; CHECK-NEXT: bra .LBB18_3
; CHECK-NEXT: .LBB18_1:
; CHECK-NEXT: move.l %d2, %d0
Expand Down Expand Up @@ -301,7 +301,7 @@ define i64 @ashr64(i64 %a, i64 %b) nounwind {
; CHECK-NEXT: add.l #-32, %d3
; CHECK-NEXT: bmi .LBB19_5
; CHECK-NEXT: ; %bb.4:
; CHECK-NEXT: move.l #31, %d2
; CHECK-NEXT: moveq #31, %d2
; CHECK-NEXT: .LBB19_5:
; CHECK-NEXT: asr.l %d2, %d0
; CHECK-NEXT: movem.l (0,%sp), %d2-%d3 ; 12-byte Folded Reload
Expand All @@ -322,7 +322,7 @@ define i64 @shl64(i64 %a, i64 %b) nounwind {
; CHECK-NEXT: add.l #-32, %d0
; CHECK-NEXT: bmi .LBB20_1
; CHECK-NEXT: ; %bb.2:
; CHECK-NEXT: move.l #0, %d1
; CHECK-NEXT: moveq #0, %d1
; CHECK-NEXT: bra .LBB20_3
; CHECK-NEXT: .LBB20_1:
; CHECK-NEXT: move.l %d2, %d1
Expand Down
14 changes: 7 additions & 7 deletions llvm/test/CodeGen/M68k/Arith/divide-by-constant.ll
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ define zeroext i8 @test3(i8 zeroext %x, i8 zeroext %c) {
; CHECK-NEXT: move.b (11,%sp), %d0
; CHECK-NEXT: and.l #255, %d0
; CHECK-NEXT: muls #171, %d0
; CHECK-NEXT: move.w #9, %d1
; CHECK-NEXT: moveq #9, %d1
; CHECK-NEXT: lsr.w %d1, %d0
; CHECK-NEXT: and.l #65535, %d0
; CHECK-NEXT: rts
Expand All @@ -58,7 +58,7 @@ define signext i16 @test4(i16 signext %x) nounwind {
; CHECK-NEXT: muls #1986, %d0
; CHECK-NEXT: asr.l #8, %d0
; CHECK-NEXT: asr.l #8, %d0
; CHECK-NEXT: move.w #15, %d1
; CHECK-NEXT: moveq #15, %d1
; CHECK-NEXT: move.w %d0, %d2
; CHECK-NEXT: lsr.w %d1, %d2
; CHECK-NEXT: add.w %d2, %d0
Expand Down Expand Up @@ -94,7 +94,7 @@ define signext i16 @test6(i16 signext %x) nounwind {
; CHECK-NEXT: muls #26215, %d0
; CHECK-NEXT: asr.l #8, %d0
; CHECK-NEXT: asr.l #8, %d0
; CHECK-NEXT: move.w #15, %d1
; CHECK-NEXT: moveq #15, %d1
; CHECK-NEXT: move.w %d0, %d2
; CHECK-NEXT: lsr.w %d1, %d2
; CHECK-NEXT: asr.w #2, %d0
Expand Down Expand Up @@ -128,7 +128,7 @@ define i8 @test8(i8 %x) nounwind {
; CHECK-NEXT: lsr.b #1, %d0
; CHECK-NEXT: and.l #255, %d0
; CHECK-NEXT: muls #211, %d0
; CHECK-NEXT: move.w #13, %d1
; CHECK-NEXT: moveq #13, %d1
; CHECK-NEXT: lsr.w %d1, %d0
; CHECK-NEXT: ; kill: def $bd0 killed $bd0 killed $d0
; CHECK-NEXT: rts
Expand All @@ -143,7 +143,7 @@ define i8 @test9(i8 %x) nounwind {
; CHECK-NEXT: lsr.b #2, %d0
; CHECK-NEXT: and.l #255, %d0
; CHECK-NEXT: muls #71, %d0
; CHECK-NEXT: move.w #11, %d1
; CHECK-NEXT: moveq #11, %d1
; CHECK-NEXT: lsr.w %d1, %d0
; CHECK-NEXT: ; kill: def $bd0 killed $bd0 killed $d0
; CHECK-NEXT: rts
Expand All @@ -156,11 +156,11 @@ define i32 @testsize1(i32 %x) minsize nounwind {
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: suba.l #4, %sp
; CHECK-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
; CHECK-NEXT: move.l #31, %d1
; CHECK-NEXT: moveq #31, %d1
; CHECK-NEXT: move.l (8,%sp), %d0
; CHECK-NEXT: move.l %d0, %d2
; CHECK-NEXT: asr.l %d1, %d2
; CHECK-NEXT: move.l #27, %d1
; CHECK-NEXT: moveq #27, %d1
; CHECK-NEXT: lsr.l %d1, %d2
; CHECK-NEXT: add.l %d2, %d0
; CHECK-NEXT: asr.l #5, %d0
Expand Down
16 changes: 8 additions & 8 deletions llvm/test/CodeGen/M68k/Arith/imul.ll
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ define i64 @mul4_64(i64 %A) {
; 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: move.l #30, %d0
; CHECK-NEXT: moveq #30, %d0
; CHECK-NEXT: move.l (12,%sp), %d1
; CHECK-NEXT: move.l %d1, %d2
; CHECK-NEXT: lsr.l %d0, %d2
Expand All @@ -38,7 +38,7 @@ define i32 @mul4096_32(i32 %A) {
; CHECK-LABEL: mul4096_32:
; CHECK: .cfi_startproc
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: move.l #12, %d1
; CHECK-NEXT: moveq #12, %d1
; CHECK-NEXT: move.l (4,%sp), %d0
; CHECK-NEXT: lsl.l %d1, %d0
; CHECK-NEXT: rts
Expand All @@ -53,11 +53,11 @@ define i64 @mul4096_64(i64 %A) {
; CHECK-NEXT: suba.l #8, %sp
; CHECK-NEXT: .cfi_def_cfa_offset -12
; CHECK-NEXT: movem.l %d2-%d3, (0,%sp) ; 12-byte Folded Spill
; CHECK-NEXT: move.l #20, %d0
; CHECK-NEXT: moveq #20, %d0
; CHECK-NEXT: move.l (16,%sp), %d1
; CHECK-NEXT: move.l %d1, %d2
; CHECK-NEXT: lsr.l %d0, %d2
; CHECK-NEXT: move.l #12, %d3
; CHECK-NEXT: moveq #12, %d3
; CHECK-NEXT: move.l (12,%sp), %d0
; CHECK-NEXT: lsl.l %d3, %d0
; CHECK-NEXT: or.l %d2, %d0
Expand All @@ -73,7 +73,7 @@ define i32 @mulmin4096_32(i32 %A) {
; CHECK-LABEL: mulmin4096_32:
; CHECK: .cfi_startproc
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: move.l #12, %d1
; CHECK-NEXT: moveq #12, %d1
; CHECK-NEXT: move.l (4,%sp), %d0
; CHECK-NEXT: lsl.l %d1, %d0
; CHECK-NEXT: neg.l %d0
Expand All @@ -89,11 +89,11 @@ define i64 @mulmin4096_64(i64 %A) {
; CHECK-NEXT: suba.l #8, %sp
; CHECK-NEXT: .cfi_def_cfa_offset -12
; CHECK-NEXT: movem.l %d2-%d3, (0,%sp) ; 12-byte Folded Spill
; CHECK-NEXT: move.l #20, %d0
; CHECK-NEXT: moveq #20, %d0
; CHECK-NEXT: move.l (16,%sp), %d1
; CHECK-NEXT: move.l %d1, %d2
; CHECK-NEXT: lsr.l %d0, %d2
; CHECK-NEXT: move.l #12, %d3
; CHECK-NEXT: moveq #12, %d3
; CHECK-NEXT: move.l (12,%sp), %d0
; CHECK-NEXT: lsl.l %d3, %d0
; CHECK-NEXT: or.l %d2, %d0
Expand Down Expand Up @@ -258,7 +258,7 @@ define i32 @mul0_32(i32 %A) {
; CHECK-LABEL: mul0_32:
; CHECK: .cfi_startproc
; CHECK-NEXT: ; %bb.0:
; CHECK-NEXT: move.l #0, %d0
; CHECK-NEXT: moveq #0, %d0
; CHECK-NEXT: rts
%mul = mul i32 %A, 0
ret i32 %mul
Expand Down
12 changes: 6 additions & 6 deletions llvm/test/CodeGen/M68k/Arith/smul-with-overflow.ll
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ entry:
define zeroext i8 @smul_i8_no_ovf(i8 signext %a, i8 signext %b) nounwind ssp {
; CHECK-LABEL: smul_i8_no_ovf:
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: move.l #42, %d0
; CHECK-NEXT: moveq #42, %d0
; CHECK-NEXT: rts
entry:
%smul = tail call { i8, i1 } @llvm.smul.with.overflow.i8(i8 %a, i8 %b)
Expand Down Expand Up @@ -70,15 +70,15 @@ define fastcc i1 @test1(i32 %v1, i32 %v2) nounwind {
; CHECK-NEXT: lea (no,%pc), %a0
; CHECK-NEXT: move.l %a0, (%sp)
; CHECK-NEXT: jsr printf@PLT
; CHECK-NEXT: move.b #0, %d0
; CHECK-NEXT: moveq #0, %d0
; CHECK-NEXT: adda.l #12, %sp
; CHECK-NEXT: rts
; CHECK-NEXT: .LBB3_1: ; %normal
; CHECK-NEXT: move.l %d0, (4,%sp)
; CHECK-NEXT: lea (ok,%pc), %a0
; CHECK-NEXT: move.l %a0, (%sp)
; CHECK-NEXT: jsr printf@PLT
; CHECK-NEXT: move.b #1, %d0
; CHECK-NEXT: moveq #1, %d0
; CHECK-NEXT: adda.l #12, %sp
; CHECK-NEXT: rts
entry:
Expand Down Expand Up @@ -108,15 +108,15 @@ define fastcc i1 @test2(i32 %v1, i32 %v2) nounwind {
; CHECK-NEXT: lea (no,%pc), %a0
; CHECK-NEXT: move.l %a0, (%sp)
; CHECK-NEXT: jsr printf@PLT
; CHECK-NEXT: move.b #0, %d0
; CHECK-NEXT: moveq #0, %d0
; CHECK-NEXT: adda.l #12, %sp
; CHECK-NEXT: rts
; CHECK-NEXT: .LBB4_2: ; %normal
; CHECK-NEXT: move.l %d0, (4,%sp)
; CHECK-NEXT: lea (ok,%pc), %a0
; CHECK-NEXT: move.l %a0, (%sp)
; CHECK-NEXT: jsr printf@PLT
; CHECK-NEXT: move.b #1, %d0
; CHECK-NEXT: moveq #1, %d0
; CHECK-NEXT: adda.l #12, %sp
; CHECK-NEXT: rts
entry:
Expand Down Expand Up @@ -155,7 +155,7 @@ define i32 @test4(i32 %a, i32 %b) nounwind readnone {
; CHECK: ; %bb.0: ; %entry
; CHECK-NEXT: move.l (8,%sp), %d0
; CHECK-NEXT: add.l (4,%sp), %d0
; CHECK-NEXT: move.l #4, %d1
; CHECK-NEXT: moveq #4, %d1
; CHECK-NEXT: muls.l %d1, %d0
; CHECK-NEXT: rts
entry:
Expand Down
Loading
Loading