-
Notifications
You must be signed in to change notification settings - Fork 10.8k
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
[M68k] Add support for bitwise NOT instruction #88049
Conversation
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.
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write If you have received no comments on your PR for a week, you can request a review If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-mc @llvm/pr-subscribers-backend-m68k Author: Peter Lafreniere (n8pjl) ChangesCurrently the bitwise NOT instruction is not recognized. Add support for Using not rather than eori cuts the length of the encoded instruction This change includes tests for both bitwise and arithmetic negation. Full diff: https://github.com/llvm/llvm-project/pull/88049.diff 3 Files Affected:
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
|
Thank you for the patch. Overall looks pretty good, you did a great job on your first LLVM PR! |
Thank you, and yes, I'll write a few tests for MC. I didn't know that those existed. Does LLVM have a preference over if the MC tests go into a second commit, or if I revise the first commit and force push? |
The current policy states that during code review, all changes/fixes to the PR should be put in separate commits (unless there is a substantial change on the main branch that will break the PR and you have to rebase + forced push) so the reviewer can see a clear history of changes. But once the code reviewer is done, you have to squash all the commits before merge. Actually, I think we make "Squash and merge" button the only clickable one on the web UI. |
Good to know, I like that policy. I'm used to email-based patch management, so using PRs takes some getting used to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Please let me know if you're not able to merge the PR (I'm not really sure how they setup permission for new contributors after we migrate to GitHub PR). If you need help to merge, please make sure the email you want to use in the commit is in your account's public email list, otherwise GitHub will assign an ugly "XXX-noreply@github.com" to the commit.
I'm not allowed to merge the PR so it would be great if you could do that for me. |
@n8pjl Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested Please check whether problems have been caused by your change specifically, as How to do this, and the rest of the post-merge process, is covered in detail here. If your change does cause a problem, it may be reverted, or you can revert it yourself. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! |
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.