[llvm] [M68k] Add support for bitwise NOT instruction (PR #88049)

Peter Lafreniere via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 8 14:36:09 PDT 2024


https://github.com/n8pjl created https://github.com/llvm/llvm-project/pull/88049

Currently the bitwise NOT instruction is not recognized. Add support for
using NOT on data registers. This is a partial implementation that puts
NOT at the same level of support as NEG currently enjoys.

Using not rather than eori cuts the length of the encoded instruction
in half or in thirds, leading to a reduction of 4-10 cycles per
instruction, on the original 68000.

This change includes tests for both bitwise and arithmetic negation.


>From b9552a6149ce07cc9432681b3efb1f5b6ce809d9 Mon Sep 17 00:00:00 2001
From: Peter Lafreniere <peter at n8pjl.ca>
Date: Mon, 8 Apr 2024 17:24:22 -0400
Subject: [PATCH] [M68k] Add support for bitwise NOT instruction

Currently the bitwise NOT instruction is not recognized. Add support for
using NOT on data registers. This is a partial implementation that puts
NOT at the same level of support as NEG currently enjoys.

Using not rather than eori cuts the length of the encoded instruction
in half or in thirds, leading to a reduction of 4-10 cycles per
instruction, on the original 68000.

This change includes tests for both bitwise and arithmetic negation.
---
 llvm/lib/Target/M68k/M68kInstrArithmetic.td | 20 ++++-
 llvm/test/CodeGen/M68k/Arith/unary.ll       | 86 +++++++++++++++++++++
 llvm/test/CodeGen/M68k/Atomics/rmw.ll       |  2 +-
 3 files changed, 104 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/CodeGen/M68k/Arith/unary.ll

diff --git a/llvm/lib/Target/M68k/M68kInstrArithmetic.td b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
index 3532e56e741705..e2d4e49ddf27b6 100644
--- a/llvm/lib/Target/M68k/M68kInstrArithmetic.td
+++ b/llvm/lib/Target/M68k/M68kInstrArithmetic.td
@@ -15,8 +15,8 @@
 ///    ADD       [~]   ADDA      [~]   ADDI        [~]   ADDQ [ ]   ADDX [~]
 ///    CLR       [ ]   CMP       [~]   CMPA        [~]   CMPI [~]   CMPM [ ]
 ///    CMP2      [ ]   DIVS/DIVU [~]   DIVSL/DIVUL [ ]   EXT  [~]   EXTB [ ]
-///    MULS/MULU [~]   NEG       [~]   NEGX        [~]   SUB  [~]   SUBA [~]
-///    SUBI      [~]   SUBQ      [ ]   SUBX        [~]
+///    MULS/MULU [~]   NEG       [~]   NEGX        [~]   NOT  [~]   SUB  [~]
+///    SUBA      [~]   SUBI      [~]   SUBQ        [ ]   SUBX [~]
 ///
 ///  Map:
 ///
@@ -769,7 +769,7 @@ def : Pat<(mulhu i16:$dst, Mxi16immSExt16:$opd),
 
 
 //===----------------------------------------------------------------------===//
-// NEG/NEGX
+// NEG/NEGX/NOT
 //===----------------------------------------------------------------------===//
 
 /// ------------+------------+------+---------+---------
@@ -809,12 +809,26 @@ class MxNegX_D<MxType TYPE>
 }
 }
 
+class MxNot_D<MxType TYPE>
+    : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
+             "not."#TYPE.Prefix#"\t$dst",
+             [(set TYPE.VT:$dst, (not TYPE.VT:$src))]> {
+  let Inst = (descend 0b01000110,
+    /*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
+    //MODE without last bit
+    0b00,
+    //REGISTER prefixed by D/A bit
+    (operand "$dst", 4)
+  );
+}
+
 } // let Constraints
 } // let Defs = [CCR]
 
 foreach S = [8, 16, 32] in {
   def NEG#S#d  : MxNeg_D<!cast<MxType>("MxType"#S#"d")>;
   def NEGX#S#d : MxNegX_D<!cast<MxType>("MxType"#S#"d")>;
+  def NOT#S#d  : MxNot_D<!cast<MxType>("MxType"#S#"d")>;
 }
 
 def : Pat<(MxSub 0, i8 :$src), (NEG8d  MxDRD8 :$src)>;
diff --git a/llvm/test/CodeGen/M68k/Arith/unary.ll b/llvm/test/CodeGen/M68k/Arith/unary.ll
new file mode 100644
index 00000000000000..a28ac7328d2601
--- /dev/null
+++ b/llvm/test/CodeGen/M68k/Arith/unary.ll
@@ -0,0 +1,86 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --filter-out ";*\.cfi_*"
+; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
+
+define i64 @notll(i64 %x) {
+; CHECK-LABEL: notll:
+; CHECK:  ; %bb.0:
+; CHECK:    move.l (4,%sp), %d0
+; CHECK:    not.l %d0
+; CHECK:    move.l (8,%sp), %d1
+; CHECK:    not.l %d1
+; CHECK:    rts
+  %not = xor i64 %x, -1
+  ret i64 %not
+}
+
+define i32 @notl(i32 %x) {
+; CHECK-LABEL: notl:
+; CHECK:  ; %bb.0:
+; CHECK:    move.l (4,%sp), %d0
+; CHECK:    not.l %d0
+; CHECK:    rts
+  %not = xor i32 %x, -1
+  ret i32 %not
+}
+
+define i16 @nots(i16 %x) {
+; CHECK-LABEL: nots:
+; CHECK:  ; %bb.0:
+; CHECK:    move.w (6,%sp), %d0
+; CHECK:    not.w %d0
+; CHECK:    rts
+  %not = xor i16 %x, -1
+  ret i16 %not
+}
+
+define i8 @notb(i8 %x) {
+; CHECK-LABEL: notb:
+; CHECK:  ; %bb.0:
+; CHECK:    move.b (7,%sp), %d0
+; CHECK:    not.b %d0
+; CHECK:    rts
+  %not = xor i8 %x, -1
+  ret i8 %not
+}
+
+define i64 @negll(i64 %x) {
+; CHECK-LABEL: negll:
+; CHECK:  ; %bb.0:
+; CHECK:    move.l (4,%sp), %d0
+; CHECK:    move.l (8,%sp), %d1
+; CHECK:    neg.l %d1
+; CHECK:    negx.l %d0
+; CHECK:    rts
+  %neg = sub i64 0, %x
+  ret i64 %neg
+}
+
+define i32 @negl(i32 %x) {
+; CHECK-LABEL: negl:
+; CHECK:  ; %bb.0:
+; CHECK:    move.l (4,%sp), %d0
+; CHECK:    neg.l %d0
+; CHECK:    rts
+  %neg = sub i32 0, %x
+  ret i32 %neg
+}
+
+define i16 @negs(i16 %x) {
+; CHECK-LABEL: negs:
+; CHECK:  ; %bb.0:
+; CHECK:    move.w (6,%sp), %d0
+; CHECK:    neg.w %d0
+; CHECK:    rts
+  %neg = sub i16 0, %x
+  ret i16 %neg
+}
+
+define i8 @negb(i8 %x) {
+; CHECK-LABEL: negb:
+; CHECK:  ; %bb.0:
+; CHECK:    move.b (7,%sp), %d0
+; CHECK:    neg.b %d0
+; CHECK:    rts
+  %neg = sub i8 0, %x
+  ret i8 %neg
+}
diff --git a/llvm/test/CodeGen/M68k/Atomics/rmw.ll b/llvm/test/CodeGen/M68k/Atomics/rmw.ll
index b589e7751d80e7..1036a0a8ba3d25 100644
--- a/llvm/test/CodeGen/M68k/Atomics/rmw.ll
+++ b/llvm/test/CodeGen/M68k/Atomics/rmw.ll
@@ -237,7 +237,7 @@ define i16 @atmoicrmw_nand_i16(i16 %val, ptr %ptr) {
 ; ATOMIC-NEXT:    ; =>This Inner Loop Header: Depth=1
 ; ATOMIC-NEXT:    move.w %d2, %d3
 ; ATOMIC-NEXT:    and.w %d0, %d3
-; ATOMIC-NEXT:    eori.w #-1, %d3
+; ATOMIC-NEXT:    not.w %d3
 ; ATOMIC-NEXT:    cas.w %d1, %d3, (%a0)
 ; ATOMIC-NEXT:    move.w %d1, %d3
 ; ATOMIC-NEXT:    sub.w %d2, %d3



More information about the llvm-commits mailing list