[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