[llvm] 6a4e72b - [M68k][MC] Add support for 32 bit register-register multiply/divide
Min-Yih Hsu via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 29 21:40:25 PDT 2023
Author: Ian Douglas Scott
Date: 2023-06-29T21:39:41-07:00
New Revision: 6a4e72b232afc86219c04d14b7b66058fd11a7db
URL: https://github.com/llvm/llvm-project/commit/6a4e72b232afc86219c04d14b7b66058fd11a7db
DIFF: https://github.com/llvm/llvm-project/commit/6a4e72b232afc86219c04d14b7b66058fd11a7db.diff
LOG: [M68k][MC] Add support for 32 bit register-register multiply/divide
Previously when targeting 68020+, instruction selection attempted to
emit a 32-bit register-register multiplication, but failed at instruction
selection. With this, it succeeds.
Differential Revision: https://reviews.llvm.org/D152120
Added:
llvm/test/CodeGen/M68k/Arith/mul_div_32.ll
Modified:
llvm/lib/Target/M68k/M68kISelLowering.cpp
llvm/lib/Target/M68k/M68kInstrArithmetic.td
llvm/test/MC/M68k/Arith/Classes/MxDiMu.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp
index 6c877f9dd8edd8..af3af6760ae1cf 100644
--- a/llvm/lib/Target/M68k/M68kISelLowering.cpp
+++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp
@@ -73,16 +73,16 @@ M68kTargetLowering::M68kTargetLowering(const M68kTargetMachine &TM,
setTruncStoreAction(MVT::i32, MVT::i8, Expand);
setTruncStoreAction(MVT::i16, MVT::i8, Expand);
- setOperationAction(ISD::MUL, MVT::i8, Promote);
- setOperationAction(ISD::MUL, MVT::i16, Legal);
+ setOperationAction({ISD::MUL, ISD::SDIV, ISD::UDIV}, MVT::i8, Promote);
+ setOperationAction({ISD::MUL, ISD::SDIV, ISD::UDIV}, MVT::i16, Legal);
if (Subtarget.atLeastM68020())
- setOperationAction(ISD::MUL, MVT::i32, Legal);
+ setOperationAction({ISD::MUL, ISD::SDIV, ISD::UDIV}, MVT::i32, Legal);
else
- setOperationAction(ISD::MUL, MVT::i32, LibCall);
+ setOperationAction({ISD::MUL, ISD::SDIV, ISD::UDIV}, MVT::i32, LibCall);
setOperationAction(ISD::MUL, MVT::i64, LibCall);
for (auto OP :
- {ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM, ISD::UDIVREM, ISD::SDIVREM,
+ {ISD::SREM, ISD::UREM, ISD::UDIVREM, ISD::SDIVREM,
ISD::MULHS, ISD::MULHU, ISD::UMUL_LOHI, ISD::SMUL_LOHI}) {
setOperationAction(OP, MVT::i8, Promote);
setOperationAction(OP, MVT::i16, Legal);
diff --git a/llvm/lib/Target/M68k/M68kInstrArithmetic.td b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
index c5a95b4bed1239..15d2049f62cb73 100644
--- a/llvm/lib/Target/M68k/M68kInstrArithmetic.td
+++ b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
@@ -589,6 +589,22 @@ class MxDiMuOp_DD<string MN, bits<4> CMD, bit SIGNED = false,
);
}
+// $dreg <- $dreg op $dreg
+class MxDiMuOp_DD_Long<string MN, bits<10> CMD, bit SIGNED = false>
+ : MxInst<(outs MxDRD32:$dst), (ins MxDRD32:$src, MxDRD32:$opd), MN#"\t$opd, $dst", []> {
+ let Inst = (ascend
+ (descend CMD,
+ /*MODE*/0b000, /*REGISTER*/(operand "$opd", 3)),
+ (descend 0b0,
+ // REGISTER
+ (operand "$dst", 3),
+ !if(SIGNED, 0b1, 0b0),
+ /*SIZE*/0b0, 0b0000000,
+ // Dr REGISTER
+ 0b000)
+ );
+}
+
// $reg <- $reg op $imm
class MxDiMuOp_DI<string MN, bits<4> CMD, bit SIGNED = false,
MxOperand DST, MxOperand OPD>
@@ -618,6 +634,9 @@ multiclass MxDiMuOp<string MN, bits<4> CMD, bit isComm = 0> {
defm DIV : MxDiMuOp<"div", 0x8>;
+def SDIVd32d32 : MxDiMuOp_DD_Long<"divs.l", 0x131, /*SIGNED*/true>;
+def UDIVd32d32 : MxDiMuOp_DD_Long<"divu.l", 0x131, /*SIGNED*/false>;
+
// This is used to cast immediates to 16-bits for operations which don't
// support smaller immediate sizes.
def as_i16imm : SDNodeXForm<imm, [{
@@ -667,6 +686,12 @@ def : Pat<(urem i16:$dst, i16:$opd),
MxSubRegIndex16Lo)>;
+// RR i32
+def : Pat<(sdiv i32:$dst, i32:$opd), (SDIVd32d32 $dst, $opd)>;
+
+def : Pat<(udiv i32:$dst, i32:$opd), (UDIVd32d32 $dst, $opd)>;
+
+
// RI i8
def : Pat<(sdiv i8:$dst, MximmSExt8:$opd),
(EXTRACT_SUBREG
@@ -712,6 +737,9 @@ def : Pat<(urem i16:$dst, MximmSExt16:$opd),
defm MUL : MxDiMuOp<"mul", 0xC, 1>;
+def SMULd32d32 : MxDiMuOp_DD_Long<"muls.l", 0x130, /*SIGNED*/true>;
+def UMULd32d32 : MxDiMuOp_DD_Long<"mulu.l", 0x130, /*SIGNED*/false>;
+
// RR
def : Pat<(mul i16:$dst, i16:$opd),
(EXTRACT_SUBREG
@@ -728,6 +756,8 @@ def : Pat<(mulhu i16:$dst, i16:$opd),
(LSR32di (LSR32di (UMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8),
MxSubRegIndex16Lo)>;
+def : Pat<(mul i32:$dst, i32:$opd), (SMULd32d32 $dst, $opd)>;
+
// RI
def : Pat<(mul i16:$dst, MximmSExt16:$opd),
diff --git a/llvm/test/CodeGen/M68k/Arith/mul_div_32.ll b/llvm/test/CodeGen/M68k/Arith/mul_div_32.ll
new file mode 100644
index 00000000000000..043a65f5bf2fa3
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/mul_div_32.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc < %s -mtriple=m68k-linux --mcpu M68020 | FileCheck %s
+
+define i32 @mul32(i32 %A, i32 %B) {
+; CHECK-LABEL: mul32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (8,%sp), %d1
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: muls.l %d1, %d0
+; CHECK-NEXT: rts
+ %mul = mul i32 %A, %B
+ ret i32 %mul
+}
+
+define i32 @sdiv_32(i32 %A, i32 %B) {
+; CHECK-LABEL: sdiv_32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (8,%sp), %d1
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: divs.l %d1, %d0
+; CHECK-NEXT: rts
+ %div = sdiv i32 %A, %B
+ ret i32 %div
+}
+
+define i32 @udiv32(i32 %A, i32 %B) {
+; CHECK-LABEL: udiv32:
+; CHECK: .cfi_startproc
+; CHECK-NEXT: ; %bb.0:
+; CHECK-NEXT: move.l (8,%sp), %d1
+; CHECK-NEXT: move.l (4,%sp), %d0
+; CHECK-NEXT: divu.l %d1, %d0
+; CHECK-NEXT: rts
+ %div = udiv i32 %A, %B
+ ret i32 %div
+}
diff --git a/llvm/test/MC/M68k/Arith/Classes/MxDiMu.s b/llvm/test/MC/M68k/Arith/Classes/MxDiMu.s
index 0e2ca264d956cf..964dbfcc11cff2 100644
--- a/llvm/test/MC/M68k/Arith/Classes/MxDiMu.s
+++ b/llvm/test/MC/M68k/Arith/Classes/MxDiMu.s
@@ -12,6 +12,12 @@ divs #0, %d0
; CHECK: divu #-1, %d0
; CHECK-SAME: encoding: [0x80,0xfc,0xff,0xff]
divu #-1, %d0
+; CHECK: divs.l %d1, %d0
+; CHECK-SAME: encoding: [0x4c,0x41,0x08,0x00]
+divs.l %d1, %d0
+; CHECK: divu.l %d1, %d0
+; CHECK-SAME: encoding: [0x4c,0x41,0x00,0x00]
+divu.l %d1, %d0
; CHECK: muls %d1, %d0
; CHECK-SAME: encoding: [0xc1,0xc1]
muls %d1, %d0
@@ -24,3 +30,9 @@ muls #0, %d0
; CHECK: mulu #-1, %d0
; CHECK-SAME: encoding: [0xc0,0xfc,0xff,0xff]
mulu #-1, %d0
+; CHECK: muls.l %d1, %d0
+; CHECK-SAME: encoding: [0x4c,0x01,0x08,0x00]
+muls.l %d1, %d0
+; CHECK: mulu.l %d1, %d0
+; CHECK-SAME: encoding: [0x4c,0x01,0x00,0x00]
+mulu.l %d1, %d0
More information about the llvm-commits
mailing list