Skip to content

Commit 4cce107

Browse files
authored
[M68k] Add remaining addressing modes for Atomic operations (#115523)
Had been doing this piece by piece, but makes more sense to do it in a single PR. Adds support for `ARID`, `PCI`, `PCD`, `AL`, and `ARD` addressing modes for atomic operations, along with a variety of tests. The `CodeModel` tests have been rearranged, as some of the new addressing modes are only exercised under some combinations of `CodeModel` and relocation mode
1 parent 6edd867 commit 4cce107

23 files changed

+3262
-11
lines changed

llvm/lib/Target/M68k/Disassembler/M68kDisassembler.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919

2020
#include "llvm/MC/MCAsmInfo.h"
2121
#include "llvm/MC/MCContext.h"
22-
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
2322
#include "llvm/MC/MCDecoderOps.h"
23+
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
2424
#include "llvm/MC/MCInst.h"
2525
#include "llvm/MC/TargetRegistry.h"
2626
#include "llvm/Support/Endian.h"
@@ -83,6 +83,12 @@ static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, uint64_t RegNo,
8383
return DecodeRegisterClass(Inst, RegNo, Address, Decoder);
8484
}
8585

86+
static DecodeStatus DecodeXR32RegisterClass(MCInst &Inst, APInt RegNo,
87+
uint64_t Address,
88+
const void *Decoder) {
89+
return DecodeRegisterClass(Inst, RegNo.getZExtValue(), Address, Decoder);
90+
}
91+
8692
static DecodeStatus DecodeXR16RegisterClass(MCInst &Inst, uint64_t RegNo,
8793
uint64_t Address,
8894
const void *Decoder) {

llvm/lib/Target/M68k/M68kISelDAGToDAG.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,20 @@ bool M68kDAGToDAGISel::SelectARIPD(SDNode *Parent, SDValue N, SDValue &Base) {
708708
return false;
709709
}
710710

711+
[[maybe_unused]] static bool allowARIDWithDisp(SDNode *Parent) {
712+
if (!Parent)
713+
return false;
714+
switch (Parent->getOpcode()) {
715+
case ISD::LOAD:
716+
case ISD::STORE:
717+
case ISD::ATOMIC_LOAD:
718+
case ISD::ATOMIC_STORE:
719+
return true;
720+
default:
721+
return false;
722+
}
723+
}
724+
711725
bool M68kDAGToDAGISel::SelectARID(SDNode *Parent, SDValue N, SDValue &Disp,
712726
SDValue &Base) {
713727
LLVM_DEBUG(dbgs() << "Selecting AddrType::ARID: ");
@@ -740,7 +754,8 @@ bool M68kDAGToDAGISel::SelectARID(SDNode *Parent, SDValue N, SDValue &Disp,
740754
Base = AM.BaseReg;
741755

742756
if (getSymbolicDisplacement(AM, SDLoc(N), Disp)) {
743-
assert(!AM.Disp && "Should not be any displacement");
757+
assert((!AM.Disp || allowARIDWithDisp(Parent)) &&
758+
"Should not be any displacement");
744759
LLVM_DEBUG(dbgs() << "SUCCESS, matched Symbol\n");
745760
return true;
746761
}
@@ -780,6 +795,7 @@ static bool AllowARIIWithZeroDisp(SDNode *Parent) {
780795
case ISD::STORE:
781796
case ISD::ATOMIC_LOAD:
782797
case ISD::ATOMIC_STORE:
798+
case ISD::ATOMIC_CMP_SWAP:
783799
return true;
784800
default:
785801
return false;

llvm/lib/Target/M68k/M68kInstrAtomics.td

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,38 @@ foreach size = [8, 16, 32] in {
1313
def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_ARII:$ptr),
1414
(!cast<MxInst>("MOV"#size#"df") !cast<MxMemOp>("MxARII"#size):$ptr)>;
1515

16+
def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_ARID:$ptr),
17+
(!cast<MxInst>("MOV"#size#"dp") !cast<MxMemOp>("MxARID"#size):$ptr)>;
18+
19+
def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_PCD:$ptr),
20+
(!cast<MxInst>("MOV"#size#"dq") !cast<MxMemOp>("MxPCD"#size):$ptr)>;
21+
22+
def : Pat<(!cast<SDPatternOperator>("atomic_load_"#size) MxCP_PCI:$ptr),
23+
(!cast<MxInst>("MOV"#size#"dk") !cast<MxMemOp>("MxPCI"#size):$ptr)>;
24+
1625
def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_ARI:$ptr),
1726
(!cast<MxInst>("MOV"#size#"jd") !cast<MxMemOp>("MxARI"#size):$ptr,
1827
!cast<MxRegOp>("MxDRD"#size):$val)>;
1928

2029
def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_ARII:$ptr),
2130
(!cast<MxInst>("MOV"#size#"fd") !cast<MxMemOp>("MxARII"#size):$ptr,
2231
!cast<MxRegOp>("MxDRD"#size):$val)>;
32+
33+
def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_ARID:$ptr),
34+
(!cast<MxInst>("MOV"#size#"pd") !cast<MxMemOp>("MxARID"#size):$ptr,
35+
!cast<MxRegOp>("MxDRD"#size):$val)>;
36+
37+
def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_PCD:$ptr),
38+
(!cast<MxInst>("MOV"#size#"qd") !cast<MxMemOp>("MxPCD"#size):$ptr,
39+
!cast<MxRegOp>("MxDRD"#size):$val)>;
40+
41+
def : Pat<(!cast<SDPatternOperator>("atomic_store_"#size) !cast<MxRegOp>("MxDRD"#size):$val, MxCP_PCI:$ptr),
42+
(!cast<MxInst>("MOV"#size#"kd") !cast<MxMemOp>("MxPCI"#size):$ptr,
43+
!cast<MxRegOp>("MxDRD"#size):$val)>;
2344
}
2445

2546
let Predicates = [AtLeastM68020] in {
26-
class MxCASOp<bits<2> size_encoding, MxType type>
47+
class MxCASARIOp<bits<2> size_encoding, MxType type>
2748
: MxInst<(outs type.ROp:$out),
2849
(ins type.ROp:$dc, type.ROp:$du, !cast<MxMemOp>("MxARI"#type.Size):$mem),
2950
"cas."#type.Prefix#" $dc, $du, $mem"> {
@@ -36,17 +57,69 @@ class MxCASOp<bits<2> size_encoding, MxType type>
3657
let mayStore = 1;
3758
}
3859

39-
def CAS8 : MxCASOp<0x1, MxType8d>;
40-
def CAS16 : MxCASOp<0x2, MxType16d>;
41-
def CAS32 : MxCASOp<0x3, MxType32d>;
60+
def CASARI8 : MxCASARIOp<0x1, MxType8d>;
61+
def CASARI16 : MxCASARIOp<0x2, MxType16d>;
62+
def CASARI32 : MxCASARIOp<0x3, MxType32d>;
63+
64+
class MxCASARIDOp<bits<2> size_encoding, MxType type>
65+
: MxInst<(outs type.ROp:$out),
66+
(ins type.ROp:$dc, type.ROp:$du, !cast<MxMemOp>("MxARID"#type.Size):$mem),
67+
"cas."#type.Prefix#" $dc, $du, $mem"> {
68+
let Inst = (ascend
69+
(descend 0b00001, size_encoding, 0b011, MxEncAddrMode_p<"mem">.EA),
70+
(descend 0b0000000, (operand "$du", 3), 0b000, (operand "$dc", 3))
71+
);
72+
let Constraints = "$out = $dc";
73+
let mayLoad = 1;
74+
let mayStore = 1;
75+
}
76+
77+
def CASARID8 : MxCASARIDOp<0x1, MxType8d>;
78+
def CASARID16 : MxCASARIDOp<0x2, MxType16d>;
79+
def CASARID32 : MxCASARIDOp<0x3, MxType32d>;
80+
81+
class MxCASARIIOp<bits<2> size_encoding, MxType type>
82+
: MxInst<(outs type.ROp:$out),
83+
(ins type.ROp:$dc, type.ROp:$du, !cast<MxMemOp>("MxARII"#type.Size):$mem),
84+
"cas."#type.Prefix#" $dc, $du, $mem"> {
85+
let Inst = (ascend
86+
(descend 0b00001, size_encoding, 0b011, MxEncAddrMode_f<"mem">.EA),
87+
(descend 0b0000000, (operand "$du", 3), 0b000, (operand "$dc", 3))
88+
);
89+
let Constraints = "$out = $dc";
90+
let mayLoad = 1;
91+
let mayStore = 1;
92+
}
93+
94+
def CASARII8 : MxCASARIIOp<0x1, MxType8d>;
95+
def CASARII16 : MxCASARIIOp<0x2, MxType16d>;
96+
def CASARII32 : MxCASARIIOp<0x3, MxType32d>;
97+
98+
class MxCASALOp<bits<2> size_encoding, MxType type>
99+
: MxInst<(outs type.ROp:$out),
100+
(ins type.ROp:$dc, type.ROp:$du, !cast<MxMemOp>("MxAL"#type.Size):$mem),
101+
"cas."#type.Prefix#" $dc, $du, $mem"> {
102+
let Inst = (ascend
103+
(descend 0b00001, size_encoding, 0b011, MxEncAddrMode_abs<"mem">.EA),
104+
(descend 0b0000000, (operand "$du", 3), 0b000, (operand "$dc", 3))
105+
);
106+
let Constraints = "$out = $dc";
107+
let mayLoad = 1;
108+
let mayStore = 1;
109+
}
42110

111+
def CASAL8 : MxCASALOp<0x1, MxType8d>;
112+
def CASAL16 : MxCASALOp<0x2, MxType16d>;
113+
def CASAL32 : MxCASALOp<0x3, MxType32d>;
43114

115+
foreach mode = ["ARI", "ARII", "ARID", "AL"] in {
44116
foreach size = [8, 16, 32] in {
45-
def : Pat<(!cast<SDPatternOperator>("atomic_cmp_swap_i"#size) MxCP_ARI:$ptr,
117+
def : Pat<(!cast<SDPatternOperator>("atomic_cmp_swap_i"#size) !cast<ComplexPattern>("MxCP_"#mode):$ptr,
46118
!cast<MxRegOp>("MxDRD"#size):$cmp,
47119
!cast<MxRegOp>("MxDRD"#size):$new),
48-
(!cast<MxInst>("CAS"#size) !cast<MxRegOp>("MxDRD"#size):$cmp,
120+
(!cast<MxInst>("CAS"#mode#size) !cast<MxRegOp>("MxDRD"#size):$cmp,
49121
!cast<MxRegOp>("MxDRD"#size):$new,
50-
!cast<MxMemOp>("MxARI"#size):$ptr)>;
51-
}
122+
!cast<MxMemOp>("Mx"#mode#size):$ptr)>;
123+
} // size
124+
} // addr mode
52125
} // let Predicates = [AtLeastM68020]

llvm/test/CodeGen/M68k/Atomics/load-store.ll

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,3 +604,51 @@ define void @atomic_store_i64_seq_cst(ptr %a, i64 %val) nounwind {
604604
store atomic i64 %val, ptr %a seq_cst, align 8
605605
ret void
606606
}
607+
608+
define void @store_arid(ptr nonnull align 4 %a) {
609+
; NO-ATOMIC-LABEL: store_arid:
610+
; NO-ATOMIC: .cfi_startproc
611+
; NO-ATOMIC-NEXT: ; %bb.0: ; %start
612+
; NO-ATOMIC-NEXT: moveq #1, %d0
613+
; NO-ATOMIC-NEXT: move.l (4,%sp), %a0
614+
; NO-ATOMIC-NEXT: move.l %d0, (32,%a0)
615+
; NO-ATOMIC-NEXT: rts
616+
;
617+
; ATOMIC-LABEL: store_arid:
618+
; ATOMIC: .cfi_startproc
619+
; ATOMIC-NEXT: ; %bb.0: ; %start
620+
; ATOMIC-NEXT: moveq #1, %d0
621+
; ATOMIC-NEXT: move.l (4,%sp), %a0
622+
; ATOMIC-NEXT: move.l %d0, (32,%a0)
623+
; ATOMIC-NEXT: rts
624+
start:
625+
%1 = getelementptr inbounds i32, ptr %a, i32 8
626+
store atomic i32 1, ptr %1 seq_cst, align 4
627+
br label %exit
628+
629+
exit: ; preds = %start
630+
ret void
631+
}
632+
633+
define i32 @load_arid(ptr nonnull align 4 %a) {
634+
; NO-ATOMIC-LABEL: load_arid:
635+
; NO-ATOMIC: .cfi_startproc
636+
; NO-ATOMIC-NEXT: ; %bb.0: ; %start
637+
; NO-ATOMIC-NEXT: move.l (4,%sp), %a0
638+
; NO-ATOMIC-NEXT: move.l (32,%a0), %d0
639+
; NO-ATOMIC-NEXT: rts
640+
;
641+
; ATOMIC-LABEL: load_arid:
642+
; ATOMIC: .cfi_startproc
643+
; ATOMIC-NEXT: ; %bb.0: ; %start
644+
; ATOMIC-NEXT: move.l (4,%sp), %a0
645+
; ATOMIC-NEXT: move.l (32,%a0), %d0
646+
; ATOMIC-NEXT: rts
647+
start:
648+
%1 = getelementptr inbounds i32, ptr %a, i32 8
649+
%2 = load atomic i32, ptr %1 seq_cst, align 4
650+
br label %exit
651+
652+
exit: ; preds = %start
653+
ret i32 %2
654+
}

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

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,3 +588,144 @@ entry:
588588
%old = atomicrmw xchg ptr %ptr, i32 %val monotonic
589589
ret i32 %old
590590
}
591+
592+
define i8 @atomicrmw_sub_i8_arid(ptr align 2 %self) {
593+
; NO-ATOMIC-LABEL: atomicrmw_sub_i8_arid:
594+
; NO-ATOMIC: .cfi_startproc
595+
; NO-ATOMIC-NEXT: ; %bb.0: ; %start
596+
; NO-ATOMIC-NEXT: suba.l #12, %sp
597+
; NO-ATOMIC-NEXT: .cfi_def_cfa_offset -16
598+
; NO-ATOMIC-NEXT: move.l (16,%sp), %a0
599+
; NO-ATOMIC-NEXT: move.l (%a0), %d0
600+
; NO-ATOMIC-NEXT: add.l #4, %d0
601+
; NO-ATOMIC-NEXT: move.l %d0, (%sp)
602+
; NO-ATOMIC-NEXT: move.l #1, (4,%sp)
603+
; NO-ATOMIC-NEXT: jsr __sync_fetch_and_sub_1
604+
; NO-ATOMIC-NEXT: adda.l #12, %sp
605+
; NO-ATOMIC-NEXT: rts
606+
;
607+
; ATOMIC-LABEL: atomicrmw_sub_i8_arid:
608+
; ATOMIC: .cfi_startproc
609+
; ATOMIC-NEXT: ; %bb.0: ; %start
610+
; ATOMIC-NEXT: suba.l #4, %sp
611+
; ATOMIC-NEXT: .cfi_def_cfa_offset -8
612+
; ATOMIC-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
613+
; ATOMIC-NEXT: move.l (8,%sp), %a0
614+
; ATOMIC-NEXT: move.l (%a0), %a0
615+
; ATOMIC-NEXT: move.b (4,%a0), %d1
616+
; ATOMIC-NEXT: move.b %d1, %d0
617+
; ATOMIC-NEXT: .LBB12_1: ; %atomicrmw.start
618+
; ATOMIC-NEXT: ; =>This Inner Loop Header: Depth=1
619+
; ATOMIC-NEXT: move.b %d1, %d2
620+
; ATOMIC-NEXT: add.b #-1, %d2
621+
; ATOMIC-NEXT: cas.b %d0, %d2, (4,%a0)
622+
; ATOMIC-NEXT: move.b %d0, %d2
623+
; ATOMIC-NEXT: sub.b %d1, %d2
624+
; ATOMIC-NEXT: seq %d1
625+
; ATOMIC-NEXT: sub.b #1, %d1
626+
; ATOMIC-NEXT: move.b %d0, %d1
627+
; ATOMIC-NEXT: bne .LBB12_1
628+
; ATOMIC-NEXT: ; %bb.2: ; %atomicrmw.end
629+
; ATOMIC-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
630+
; ATOMIC-NEXT: adda.l #4, %sp
631+
; ATOMIC-NEXT: rts
632+
start:
633+
%self1 = load ptr, ptr %self, align 2
634+
%_18.i.i = getelementptr inbounds i8, ptr %self1, i32 4
635+
%6 = atomicrmw sub ptr %_18.i.i, i8 1 release, align 4
636+
ret i8 %6
637+
}
638+
639+
define i16 @atomicrmw_sub_i16_arid(ptr align 2 %self) {
640+
; NO-ATOMIC-LABEL: atomicrmw_sub_i16_arid:
641+
; NO-ATOMIC: .cfi_startproc
642+
; NO-ATOMIC-NEXT: ; %bb.0: ; %start
643+
; NO-ATOMIC-NEXT: suba.l #12, %sp
644+
; NO-ATOMIC-NEXT: .cfi_def_cfa_offset -16
645+
; NO-ATOMIC-NEXT: move.l (16,%sp), %a0
646+
; NO-ATOMIC-NEXT: move.l (%a0), %d0
647+
; NO-ATOMIC-NEXT: add.l #4, %d0
648+
; NO-ATOMIC-NEXT: move.l %d0, (%sp)
649+
; NO-ATOMIC-NEXT: move.l #1, (4,%sp)
650+
; NO-ATOMIC-NEXT: jsr __sync_fetch_and_sub_2
651+
; NO-ATOMIC-NEXT: adda.l #12, %sp
652+
; NO-ATOMIC-NEXT: rts
653+
;
654+
; ATOMIC-LABEL: atomicrmw_sub_i16_arid:
655+
; ATOMIC: .cfi_startproc
656+
; ATOMIC-NEXT: ; %bb.0: ; %start
657+
; ATOMIC-NEXT: suba.l #4, %sp
658+
; ATOMIC-NEXT: .cfi_def_cfa_offset -8
659+
; ATOMIC-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
660+
; ATOMIC-NEXT: move.l (8,%sp), %a0
661+
; ATOMIC-NEXT: move.l (%a0), %a0
662+
; ATOMIC-NEXT: move.w (4,%a0), %d1
663+
; ATOMIC-NEXT: move.w %d1, %d0
664+
; ATOMIC-NEXT: .LBB13_1: ; %atomicrmw.start
665+
; ATOMIC-NEXT: ; =>This Inner Loop Header: Depth=1
666+
; ATOMIC-NEXT: move.w %d1, %d2
667+
; ATOMIC-NEXT: add.w #-1, %d2
668+
; ATOMIC-NEXT: cas.w %d0, %d2, (4,%a0)
669+
; ATOMIC-NEXT: move.w %d0, %d2
670+
; ATOMIC-NEXT: sub.w %d1, %d2
671+
; ATOMIC-NEXT: seq %d1
672+
; ATOMIC-NEXT: sub.b #1, %d1
673+
; ATOMIC-NEXT: move.w %d0, %d1
674+
; ATOMIC-NEXT: bne .LBB13_1
675+
; ATOMIC-NEXT: ; %bb.2: ; %atomicrmw.end
676+
; ATOMIC-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
677+
; ATOMIC-NEXT: adda.l #4, %sp
678+
; ATOMIC-NEXT: rts
679+
start:
680+
%self1 = load ptr, ptr %self, align 2
681+
%_18.i.i = getelementptr inbounds i8, ptr %self1, i32 4
682+
%6 = atomicrmw sub ptr %_18.i.i, i16 1 release, align 4
683+
ret i16 %6
684+
}
685+
686+
define i32 @atomicrmw_sub_i32_arid(ptr align 2 %self) {
687+
; NO-ATOMIC-LABEL: atomicrmw_sub_i32_arid:
688+
; NO-ATOMIC: .cfi_startproc
689+
; NO-ATOMIC-NEXT: ; %bb.0: ; %start
690+
; NO-ATOMIC-NEXT: suba.l #12, %sp
691+
; NO-ATOMIC-NEXT: .cfi_def_cfa_offset -16
692+
; NO-ATOMIC-NEXT: move.l (16,%sp), %a0
693+
; NO-ATOMIC-NEXT: move.l (%a0), %d0
694+
; NO-ATOMIC-NEXT: add.l #4, %d0
695+
; NO-ATOMIC-NEXT: move.l %d0, (%sp)
696+
; NO-ATOMIC-NEXT: move.l #1, (4,%sp)
697+
; NO-ATOMIC-NEXT: jsr __sync_fetch_and_sub_4
698+
; NO-ATOMIC-NEXT: adda.l #12, %sp
699+
; NO-ATOMIC-NEXT: rts
700+
;
701+
; ATOMIC-LABEL: atomicrmw_sub_i32_arid:
702+
; ATOMIC: .cfi_startproc
703+
; ATOMIC-NEXT: ; %bb.0: ; %start
704+
; ATOMIC-NEXT: suba.l #4, %sp
705+
; ATOMIC-NEXT: .cfi_def_cfa_offset -8
706+
; ATOMIC-NEXT: movem.l %d2, (0,%sp) ; 8-byte Folded Spill
707+
; ATOMIC-NEXT: move.l (8,%sp), %a0
708+
; ATOMIC-NEXT: move.l (%a0), %a0
709+
; ATOMIC-NEXT: move.l (4,%a0), %d1
710+
; ATOMIC-NEXT: move.l %d1, %d0
711+
; ATOMIC-NEXT: .LBB14_1: ; %atomicrmw.start
712+
; ATOMIC-NEXT: ; =>This Inner Loop Header: Depth=1
713+
; ATOMIC-NEXT: move.l %d1, %d2
714+
; ATOMIC-NEXT: add.l #-1, %d2
715+
; ATOMIC-NEXT: cas.l %d0, %d2, (4,%a0)
716+
; ATOMIC-NEXT: move.l %d0, %d2
717+
; ATOMIC-NEXT: sub.l %d1, %d2
718+
; ATOMIC-NEXT: seq %d1
719+
; ATOMIC-NEXT: sub.b #1, %d1
720+
; ATOMIC-NEXT: move.l %d0, %d1
721+
; ATOMIC-NEXT: bne .LBB14_1
722+
; ATOMIC-NEXT: ; %bb.2: ; %atomicrmw.end
723+
; ATOMIC-NEXT: movem.l (0,%sp), %d2 ; 8-byte Folded Reload
724+
; ATOMIC-NEXT: adda.l #4, %sp
725+
; ATOMIC-NEXT: rts
726+
start:
727+
%self1 = load ptr, ptr %self, align 2
728+
%_18.i.i = getelementptr inbounds i8, ptr %self1, i32 4
729+
%6 = atomicrmw sub ptr %_18.i.i, i32 1 release, align 4
730+
ret i32 %6
731+
}

0 commit comments

Comments
 (0)