-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[M68k] Add support for atomic instructions
This adds support for atomic_load, atomic_store, atomic_cmpxchg and atomic_rmw Fixes #48236 Reviewed by: myhsu, efriedma Differential Revision: https://reviews.llvm.org/D136525
- Loading branch information
Showing
11 changed files
with
1,362 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
//===-- M68kInstrAtomics.td - Atomics Instructions ---------*- tablegen -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
foreach size = [8, 16, 32] in { | ||
def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_ARI:$ptr), | ||
(!cast<MxInst>("MOV"#size#"dj") !cast<MxMemOp>("MxARI"#size):$ptr)>; | ||
|
||
def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) MxCP_ARI:$ptr, | ||
!cast<MxRegOp>("MxDRD"#size):$val), | ||
(!cast<MxInst>("MOV"#size#"jd") !cast<MxMemOp>("MxARI"#size):$ptr, | ||
!cast<MxRegOp>("MxDRD"#size):$val)>; | ||
} | ||
|
||
let Predicates = [AtLeastM68020] in { | ||
class MxCASOp<bits<2> size_encoding, MxType type> | ||
: MxInst<(outs type.ROp:$out), | ||
(ins type.ROp:$dc, type.ROp:$du, !cast<MxMemOp>("MxARI"#type.Size):$mem), | ||
"cas."#type.Prefix#" $dc, $du, $mem"> { | ||
let Inst = (ascend | ||
(descend 0b00001, size_encoding, 0b011, MxEncAddrMode_j<"mem">.EA), | ||
(descend 0b0000000, (operand "$du", 3), 0b000, (operand "$dc", 3)) | ||
); | ||
let Constraints = "$out = $dc"; | ||
let mayLoad = 1; | ||
let mayStore = 1; | ||
} | ||
|
||
def CAS8 : MxCASOp<0x1, MxType8d>; | ||
def CAS16 : MxCASOp<0x2, MxType16d>; | ||
def CAS32 : MxCASOp<0x3, MxType32d>; | ||
|
||
|
||
foreach size = [8, 16, 32] in { | ||
def : Pat<(!cast<SDPatternOperator>("atomic_cmp_swap_"#size) MxCP_ARI:$ptr, | ||
!cast<MxRegOp>("MxDRD"#size):$cmp, | ||
!cast<MxRegOp>("MxDRD"#size):$new), | ||
(!cast<MxInst>("CAS"#size) !cast<MxRegOp>("MxDRD"#size):$cmp, | ||
!cast<MxRegOp>("MxDRD"#size):$new, | ||
!cast<MxMemOp>("MxARI"#size):$ptr)>; | ||
} | ||
} // let Predicates = [AtLeastM68020] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | ||
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68000 | FileCheck %s --check-prefix=NO-ATOMIC | ||
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68010 | FileCheck %s --check-prefix=NO-ATOMIC | ||
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68020 | FileCheck %s --check-prefix=ATOMIC | ||
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68030 | FileCheck %s --check-prefix=ATOMIC | ||
; RUN: llc %s -o - -mtriple=m68k -mcpu=M68040 | FileCheck %s --check-prefix=ATOMIC | ||
|
||
define i1 @cmpxchg_i8_monotonic_monotonic(i8 %cmp, i8 %new, ptr %mem) nounwind { | ||
; NO-ATOMIC-LABEL: cmpxchg_i8_monotonic_monotonic: | ||
; NO-ATOMIC: ; %bb.0: | ||
; NO-ATOMIC-NEXT: suba.l #20, %sp | ||
; NO-ATOMIC-NEXT: movem.l %d2, (16,%sp) ; 8-byte Folded Spill | ||
; NO-ATOMIC-NEXT: move.b (31,%sp), %d0 | ||
; NO-ATOMIC-NEXT: and.l #255, %d0 | ||
; NO-ATOMIC-NEXT: move.l %d0, (8,%sp) | ||
; NO-ATOMIC-NEXT: move.b (27,%sp), %d2 | ||
; NO-ATOMIC-NEXT: move.l %d2, %d0 | ||
; NO-ATOMIC-NEXT: and.l #255, %d0 | ||
; NO-ATOMIC-NEXT: move.l %d0, (4,%sp) | ||
; NO-ATOMIC-NEXT: move.l (32,%sp), (%sp) | ||
; NO-ATOMIC-NEXT: jsr __sync_val_compare_and_swap_1@PLT | ||
; NO-ATOMIC-NEXT: sub.b %d2, %d0 | ||
; NO-ATOMIC-NEXT: seq %d0 | ||
; NO-ATOMIC-NEXT: movem.l (16,%sp), %d2 ; 8-byte Folded Reload | ||
; NO-ATOMIC-NEXT: adda.l #20, %sp | ||
; NO-ATOMIC-NEXT: rts | ||
; | ||
; ATOMIC-LABEL: cmpxchg_i8_monotonic_monotonic: | ||
; ATOMIC: ; %bb.0: | ||
; ATOMIC-NEXT: suba.l #4, %sp | ||
; ATOMIC-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill | ||
; ATOMIC-NEXT: move.l (16,%sp), %a0 | ||
; ATOMIC-NEXT: move.b (15,%sp), %d0 | ||
; ATOMIC-NEXT: move.b (11,%sp), %d1 | ||
; ATOMIC-NEXT: move.b %d1, %d2 | ||
; ATOMIC-NEXT: cas.b %d2, %d0, (%a0) | ||
; ATOMIC-NEXT: sub.b %d1, %d2 | ||
; ATOMIC-NEXT: seq %d0 | ||
; ATOMIC-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload | ||
; ATOMIC-NEXT: adda.l #4, %sp | ||
; ATOMIC-NEXT: rts | ||
%res = cmpxchg ptr %mem, i8 %cmp, i8 %new monotonic monotonic | ||
%val = extractvalue {i8, i1} %res, 1 | ||
ret i1 %val | ||
} | ||
|
||
define i16 @cmpxchg_i16_release_monotonic(i16 %cmp, i16 %new, ptr %mem) nounwind { | ||
; NO-ATOMIC-LABEL: cmpxchg_i16_release_monotonic: | ||
; NO-ATOMIC: ; %bb.0: | ||
; NO-ATOMIC-NEXT: suba.l #12, %sp | ||
; NO-ATOMIC-NEXT: move.w (22,%sp), %d0 | ||
; NO-ATOMIC-NEXT: and.l #65535, %d0 | ||
; NO-ATOMIC-NEXT: move.l %d0, (8,%sp) | ||
; NO-ATOMIC-NEXT: move.w (18,%sp), %d0 | ||
; NO-ATOMIC-NEXT: and.l #65535, %d0 | ||
; NO-ATOMIC-NEXT: move.l %d0, (4,%sp) | ||
; NO-ATOMIC-NEXT: move.l (24,%sp), (%sp) | ||
; NO-ATOMIC-NEXT: jsr __sync_val_compare_and_swap_2@PLT | ||
; NO-ATOMIC-NEXT: adda.l #12, %sp | ||
; NO-ATOMIC-NEXT: rts | ||
; | ||
; ATOMIC-LABEL: cmpxchg_i16_release_monotonic: | ||
; ATOMIC: ; %bb.0: | ||
; ATOMIC-NEXT: move.l (12,%sp), %a0 | ||
; ATOMIC-NEXT: move.w (10,%sp), %d1 | ||
; ATOMIC-NEXT: move.w (6,%sp), %d0 | ||
; ATOMIC-NEXT: cas.w %d0, %d1, (%a0) | ||
; ATOMIC-NEXT: rts | ||
%res = cmpxchg ptr %mem, i16 %cmp, i16 %new release monotonic | ||
%val = extractvalue {i16, i1} %res, 0 | ||
ret i16 %val | ||
} | ||
|
||
define i32 @cmpxchg_i32_release_acquire(i32 %cmp, i32 %new, ptr %mem) nounwind { | ||
; NO-ATOMIC-LABEL: cmpxchg_i32_release_acquire: | ||
; NO-ATOMIC: ; %bb.0: | ||
; NO-ATOMIC-NEXT: suba.l #12, %sp | ||
; NO-ATOMIC-NEXT: move.l (20,%sp), (8,%sp) | ||
; NO-ATOMIC-NEXT: move.l (16,%sp), (4,%sp) | ||
; NO-ATOMIC-NEXT: move.l (24,%sp), (%sp) | ||
; NO-ATOMIC-NEXT: jsr __sync_val_compare_and_swap_4@PLT | ||
; NO-ATOMIC-NEXT: adda.l #12, %sp | ||
; NO-ATOMIC-NEXT: rts | ||
; | ||
; ATOMIC-LABEL: cmpxchg_i32_release_acquire: | ||
; ATOMIC: ; %bb.0: | ||
; ATOMIC-NEXT: move.l (12,%sp), %a0 | ||
; ATOMIC-NEXT: move.l (8,%sp), %d1 | ||
; ATOMIC-NEXT: move.l (4,%sp), %d0 | ||
; ATOMIC-NEXT: cas.l %d0, %d1, (%a0) | ||
; ATOMIC-NEXT: rts | ||
%res = cmpxchg ptr %mem, i32 %cmp, i32 %new release acquire | ||
%val = extractvalue {i32, i1} %res, 0 | ||
ret i32 %val | ||
} | ||
|
||
define i64 @cmpxchg_i64_seqcst_seqcst(i64 %cmp, i64 %new, ptr %mem) nounwind { | ||
; NO-ATOMIC-LABEL: cmpxchg_i64_seqcst_seqcst: | ||
; NO-ATOMIC: ; %bb.0: | ||
; NO-ATOMIC-NEXT: suba.l #36, %sp | ||
; NO-ATOMIC-NEXT: move.l (44,%sp), (28,%sp) | ||
; NO-ATOMIC-NEXT: move.l (40,%sp), (24,%sp) | ||
; NO-ATOMIC-NEXT: lea (24,%sp), %a0 | ||
; NO-ATOMIC-NEXT: move.l %a0, (4,%sp) | ||
; NO-ATOMIC-NEXT: move.l #5, (20,%sp) | ||
; NO-ATOMIC-NEXT: move.l #5, (16,%sp) | ||
; NO-ATOMIC-NEXT: move.l (52,%sp), (12,%sp) | ||
; NO-ATOMIC-NEXT: move.l (48,%sp), (8,%sp) | ||
; NO-ATOMIC-NEXT: move.l (56,%sp), (%sp) | ||
; NO-ATOMIC-NEXT: jsr __atomic_compare_exchange_8@PLT | ||
; NO-ATOMIC-NEXT: move.l (28,%sp), %d1 | ||
; NO-ATOMIC-NEXT: move.l (24,%sp), %d0 | ||
; NO-ATOMIC-NEXT: adda.l #36, %sp | ||
; NO-ATOMIC-NEXT: rts | ||
; | ||
; ATOMIC-LABEL: cmpxchg_i64_seqcst_seqcst: | ||
; ATOMIC: ; %bb.0: | ||
; ATOMIC-NEXT: suba.l #36, %sp | ||
; ATOMIC-NEXT: move.l (44,%sp), (28,%sp) | ||
; ATOMIC-NEXT: move.l (40,%sp), (24,%sp) | ||
; ATOMIC-NEXT: lea (24,%sp), %a0 | ||
; ATOMIC-NEXT: move.l %a0, (4,%sp) | ||
; ATOMIC-NEXT: move.l #5, (20,%sp) | ||
; ATOMIC-NEXT: move.l #5, (16,%sp) | ||
; ATOMIC-NEXT: move.l (52,%sp), (12,%sp) | ||
; ATOMIC-NEXT: move.l (48,%sp), (8,%sp) | ||
; ATOMIC-NEXT: move.l (56,%sp), (%sp) | ||
; ATOMIC-NEXT: jsr __atomic_compare_exchange_8@PLT | ||
; ATOMIC-NEXT: move.l (28,%sp), %d1 | ||
; ATOMIC-NEXT: move.l (24,%sp), %d0 | ||
; ATOMIC-NEXT: adda.l #36, %sp | ||
; ATOMIC-NEXT: rts | ||
%res = cmpxchg ptr %mem, i64 %cmp, i64 %new seq_cst seq_cst | ||
%val = extractvalue {i64, i1} %res, 0 | ||
ret i64 %val | ||
} |
Oops, something went wrong.
e086b24
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.
Seeing this, should have __GCC_HAVE_SYNC_COMPARE_AND_SWAP_X defined in clang/lib/Basic/Targets/M68k.cpp in M68kTargetInfo::getTargetDefines().
e086b24
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.
Thanks, I'll look into it.