Skip to content

Commit 614a578

Browse files
authored
[M68k] Add support for bitwise NOT instruction (#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.
1 parent 4bb5d48 commit 614a578

File tree

5 files changed

+121
-4
lines changed

5 files changed

+121
-4
lines changed

llvm/lib/Target/M68k/M68kInstrArithmetic.td

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
/// ADD [~] ADDA [~] ADDI [~] ADDQ [ ] ADDX [~]
1616
/// CLR [ ] CMP [~] CMPA [~] CMPI [~] CMPM [ ]
1717
/// CMP2 [ ] DIVS/DIVU [~] DIVSL/DIVUL [ ] EXT [~] EXTB [ ]
18-
/// MULS/MULU [~] NEG [~] NEGX [~] SUB [~] SUBA [~]
19-
/// SUBI [~] SUBQ [ ] SUBX [~]
18+
/// MULS/MULU [~] NEG [~] NEGX [~] NOT [~] SUB [~]
19+
/// SUBA [~] SUBI [~] SUBQ [ ] SUBX [~]
2020
///
2121
/// Map:
2222
///
@@ -769,7 +769,7 @@ def : Pat<(mulhu i16:$dst, Mxi16immSExt16:$opd),
769769

770770

771771
//===----------------------------------------------------------------------===//
772-
// NEG/NEGX
772+
// NEG/NEGX/NOT
773773
//===----------------------------------------------------------------------===//
774774

775775
/// ------------+------------+------+---------+---------
@@ -809,12 +809,26 @@ class MxNegX_D<MxType TYPE>
809809
}
810810
}
811811

812+
class MxNot_D<MxType TYPE>
813+
: MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src),
814+
"not."#TYPE.Prefix#"\t$dst",
815+
[(set TYPE.VT:$dst, (not TYPE.VT:$src))]> {
816+
let Inst = (descend 0b01000110,
817+
/*SIZE*/!cast<MxEncSize>("MxEncSize"#TYPE.Size).Value,
818+
//MODE without last bit
819+
0b00,
820+
//REGISTER prefixed by D/A bit
821+
(operand "$dst", 4)
822+
);
823+
}
824+
812825
} // let Constraints
813826
} // let Defs = [CCR]
814827

815828
foreach S = [8, 16, 32] in {
816829
def NEG#S#d : MxNeg_D<!cast<MxType>("MxType"#S#"d")>;
817830
def NEGX#S#d : MxNegX_D<!cast<MxType>("MxType"#S#"d")>;
831+
def NOT#S#d : MxNot_D<!cast<MxType>("MxType"#S#"d")>;
818832
}
819833

820834
def : Pat<(MxSub 0, i8 :$src), (NEG8d MxDRD8 :$src)>;

llvm/test/CodeGen/M68k/Arith/unary.ll

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --filter-out ";*\.cfi_*"
2+
; RUN: llc < %s -mtriple=m68k-linux -verify-machineinstrs | FileCheck %s
3+
4+
define i64 @notll(i64 %x) {
5+
; CHECK-LABEL: notll:
6+
; CHECK: ; %bb.0:
7+
; CHECK: move.l (4,%sp), %d0
8+
; CHECK: not.l %d0
9+
; CHECK: move.l (8,%sp), %d1
10+
; CHECK: not.l %d1
11+
; CHECK: rts
12+
%not = xor i64 %x, -1
13+
ret i64 %not
14+
}
15+
16+
define i32 @notl(i32 %x) {
17+
; CHECK-LABEL: notl:
18+
; CHECK: ; %bb.0:
19+
; CHECK: move.l (4,%sp), %d0
20+
; CHECK: not.l %d0
21+
; CHECK: rts
22+
%not = xor i32 %x, -1
23+
ret i32 %not
24+
}
25+
26+
define i16 @nots(i16 %x) {
27+
; CHECK-LABEL: nots:
28+
; CHECK: ; %bb.0:
29+
; CHECK: move.w (6,%sp), %d0
30+
; CHECK: not.w %d0
31+
; CHECK: rts
32+
%not = xor i16 %x, -1
33+
ret i16 %not
34+
}
35+
36+
define i8 @notb(i8 %x) {
37+
; CHECK-LABEL: notb:
38+
; CHECK: ; %bb.0:
39+
; CHECK: move.b (7,%sp), %d0
40+
; CHECK: not.b %d0
41+
; CHECK: rts
42+
%not = xor i8 %x, -1
43+
ret i8 %not
44+
}
45+
46+
define i64 @negll(i64 %x) {
47+
; CHECK-LABEL: negll:
48+
; CHECK: ; %bb.0:
49+
; CHECK: move.l (4,%sp), %d0
50+
; CHECK: move.l (8,%sp), %d1
51+
; CHECK: neg.l %d1
52+
; CHECK: negx.l %d0
53+
; CHECK: rts
54+
%neg = sub i64 0, %x
55+
ret i64 %neg
56+
}
57+
58+
define i32 @negl(i32 %x) {
59+
; CHECK-LABEL: negl:
60+
; CHECK: ; %bb.0:
61+
; CHECK: move.l (4,%sp), %d0
62+
; CHECK: neg.l %d0
63+
; CHECK: rts
64+
%neg = sub i32 0, %x
65+
ret i32 %neg
66+
}
67+
68+
define i16 @negs(i16 %x) {
69+
; CHECK-LABEL: negs:
70+
; CHECK: ; %bb.0:
71+
; CHECK: move.w (6,%sp), %d0
72+
; CHECK: neg.w %d0
73+
; CHECK: rts
74+
%neg = sub i16 0, %x
75+
ret i16 %neg
76+
}
77+
78+
define i8 @negb(i8 %x) {
79+
; CHECK-LABEL: negb:
80+
; CHECK: ; %bb.0:
81+
; CHECK: move.b (7,%sp), %d0
82+
; CHECK: neg.b %d0
83+
; CHECK: rts
84+
%neg = sub i8 0, %x
85+
ret i8 %neg
86+
}

llvm/test/CodeGen/M68k/Atomics/rmw.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ define i16 @atmoicrmw_nand_i16(i16 %val, ptr %ptr) {
237237
; ATOMIC-NEXT: ; =>This Inner Loop Header: Depth=1
238238
; ATOMIC-NEXT: move.w %d2, %d3
239239
; ATOMIC-NEXT: and.w %d0, %d3
240-
; ATOMIC-NEXT: eori.w #-1, %d3
240+
; ATOMIC-NEXT: not.w %d3
241241
; ATOMIC-NEXT: cas.w %d1, %d3, (%a0)
242242
; ATOMIC-NEXT: move.w %d1, %d3
243243
; ATOMIC-NEXT: sub.w %d2, %d3

llvm/test/MC/Disassembler/M68k/arithmetic.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@
8989
# CHECK: negx.l %a2
9090
0x40 0x8a
9191

92+
# CHECK: not.l %d5
93+
0x46 0x85
94+
95+
# CHECK: not.b %d1
96+
0x46 0x01
97+
9298
# CHECK: or.w (18,%a4,%a0), %d3
9399
0x86 0x74 0x88 0x12
94100

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; RUN: llvm-mc -triple=m68k -show-encoding %s | FileCheck %s
2+
3+
; CHECK: not.b %d0
4+
; CHECK-SAME: encoding: [0x46,0x00]
5+
not.b %d0
6+
; CHECK: not.w %d0
7+
; CHECK-SAME: encoding: [0x46,0x40]
8+
not.w %d0
9+
; CHECK: not.l %d0
10+
; CHECK-SAME: encoding: [0x46,0x80]
11+
not.l %d0

0 commit comments

Comments
 (0)