Skip to content

Commit f1246e9

Browse files
koachanbrad0
authored andcommitted
[SPARC][IAS] Add support for the full set of CAS instructions
This completes the support for the CAS instructions. Besides the base CASA and CASXA forms, on v9 the aliases CAS, CASX, CASL, and CASXL are also available. Reviewed By: barannikov88 Differential Revision: https://reviews.llvm.org/D157234
1 parent af70618 commit f1246e9

File tree

8 files changed

+144
-30
lines changed

8 files changed

+144
-30
lines changed

llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,8 @@ SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
11751175
Parser.getTok().getLoc()));
11761176
Parser.Lex(); // Eat the [
11771177

1178-
if (Mnemonic == "cas" || Mnemonic == "casx" || Mnemonic == "casa") {
1178+
if (Mnemonic == "cas" || Mnemonic == "casl" || Mnemonic == "casa" ||
1179+
Mnemonic == "casx" || Mnemonic == "casxl" || Mnemonic == "casxa") {
11791180
SMLoc S = Parser.getTok().getLoc();
11801181
if (getLexer().getKind() != AsmToken::Percent)
11811182
return MatchOperand_NoMatch;

llvm/lib/Target/Sparc/SparcInstr64Bit.td

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -475,14 +475,34 @@ def SETHIXi : F2_1<0b100,
475475
}
476476

477477
// ATOMICS.
478-
let Predicates = [Is64Bit], Constraints = "$swap = $rd", asi = 0b10000000 in {
479-
def CASXrr: F3_1_asi<3, 0b111110,
478+
let Predicates = [Is64Bit, HasV9], Constraints = "$swap = $rd" in {
479+
let asi = 0b10000000 in
480+
def CASXrr: F3_1_asi<3, 0b111110,
480481
(outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
481482
I64Regs:$swap),
482483
"casx [$rs1], $rs2, $rd",
483484
[(set i64:$rd,
484485
(atomic_cmp_swap_64 i64:$rs1, i64:$rs2, i64:$swap))]>;
485486

487+
let asi = 0b10001000 in
488+
def CASXLrr: F3_1_asi<3, 0b111110,
489+
(outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
490+
I64Regs:$swap),
491+
"casxl [$rs1], $rs2, $rd",
492+
[]>;
493+
494+
def CASXArr: F3_1_asi<3, 0b111110,
495+
(outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
496+
I64Regs:$swap, ASITag:$asi),
497+
"casxa [$rs1] $asi, $rs2, $rd",
498+
[]>;
499+
500+
let Uses = [ASR3] in
501+
def CASXAri: F3_1_cas_asi<3, 0b111110,
502+
(outs I64Regs:$rd), (ins I64Regs:$rs1, I64Regs:$rs2,
503+
I64Regs:$swap),
504+
"casxa [$rs1] %asi, $rs2, $rd",
505+
[]>;
486506
} // Predicates = [Is64Bit], Constraints = ...
487507

488508
let Predicates = [Is64Bit] in {

llvm/lib/Target/Sparc/SparcInstrFormats.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ class F3_1_asi<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
135135
let Inst{4-0} = rs2;
136136
}
137137

138+
// CAS instructions does not use an immediate even when i=1
139+
class F3_1_cas_asi<bits<2> opVal, bits<6> op3val, dag outs, dag ins,
140+
string asmstr, list<dag> pattern, InstrItinClass itin = NoItinerary>
141+
: F3_1_asi<opVal, op3val, outs, ins, asmstr, pattern, itin> {
142+
let asi = 0;
143+
let Inst{13} = 1; // i field = 1
144+
}
145+
138146
class F3_1<bits<2> opVal, bits<6> op3val, dag outs, dag ins, string asmstr,
139147
list<dag> pattern, InstrItinClass itin = IIC_iu_instr>
140148
: F3_1_asi<opVal, op3val, outs, ins, asmstr, pattern, itin> {

llvm/lib/Target/Sparc/SparcInstrInfo.td

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,14 @@ def HasVIS3 : Predicate<"Subtarget->isVIS3()">,
5151
// point instructions.
5252
def HasHardQuad : Predicate<"Subtarget->hasHardQuad()">;
5353

54-
// HasLeonCASA - This is true when the target processor supports the CASA
55-
// instruction
54+
// HasLeonCASA - This is true when the target processor supports the Leon CASA
55+
// instruction.
5656
def HasLeonCASA : Predicate<"Subtarget->hasLeonCasa()">;
5757

58+
// HasCASA - This is true when the target processor supports CASA instruction.
59+
def HasCASA : Predicate<"Subtarget->hasLeonCasa() || Subtarget->isV9()">,
60+
AssemblerPredicate<(any_of LeonCASA, FeatureV9)>;
61+
5862
// HasPWRPSR - This is true when the target processor supports partial
5963
// writes to the PSR register that only affects the ET field.
6064
def HasPWRPSR : Predicate<"Subtarget->hasPWRPSR()">,
@@ -1700,16 +1704,26 @@ let Predicates = [HasV9], rd = 15, rs1 = 0b00000 in
17001704
"sir $simm13", []>;
17011705

17021706
// The CAS instruction, unlike other instructions, only comes in a
1703-
// form which requires an ASI be provided. The ASI value hardcoded
1704-
// here is ASI_PRIMARY, the default unprivileged ASI for SparcV9.
1705-
let Predicates = [HasV9], Constraints = "$swap = $rd", asi = 0b10000000 in
1706-
def CASrr: F3_1_asi<3, 0b111100,
1707+
// form which requires an ASI be provided.
1708+
let Predicates = [HasV9], Constraints = "$swap = $rd" in {
1709+
// The ASI value hardcoded here is ASI_PRIMARY, the default
1710+
// unprivileged ASI for SparcV9.
1711+
let asi = 0b10000000 in
1712+
def CASrr: F3_1_asi<3, 0b111100,
17071713
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
17081714
IntRegs:$swap),
17091715
"cas [$rs1], $rs2, $rd",
17101716
[(set i32:$rd,
17111717
(atomic_cmp_swap_32 iPTR:$rs1, i32:$rs2, i32:$swap))]>;
17121718

1719+
// SparcV9 also specifies a CASL alias, which uses ASI_PRIMARY_LITTLE.
1720+
let asi = 0b10001000 in
1721+
def CASLrr: F3_1_asi<3, 0b111100,
1722+
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
1723+
IntRegs:$swap),
1724+
"casl [$rs1], $rs2, $rd",
1725+
[]>;
1726+
}
17131727

17141728
// CASA is supported as an instruction on some LEON3 and all LEON4 processors.
17151729
// This version can be automatically lowered from C code, selecting ASI 10
@@ -1721,15 +1735,23 @@ let Predicates = [HasLeonCASA], Constraints = "$swap = $rd", asi = 0b00001010 in
17211735
[(set i32:$rd,
17221736
(atomic_cmp_swap_32 iPTR:$rs1, i32:$rs2, i32:$swap))]>;
17231737

1724-
// CASA supported on some LEON3 and all LEON4 processors. Same pattern as
1725-
// CASrr, above, but with a different ASI. This version is supported for
1726-
// inline assembly lowering only.
1727-
let Predicates = [HasLeonCASA], Constraints = "$swap = $rd" in
1738+
// CASA supported on all V9, some LEON3 and all LEON4 processors.
1739+
// Same pattern as CASrr above, but with a different ASI.
1740+
// This version is supported for inline assembly lowering only.
1741+
let Predicates = [HasCASA], Constraints = "$swap = $rd" in
17281742
def CASArr: F3_1_asi<3, 0b111100,
17291743
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
17301744
IntRegs:$swap, ASITag:$asi),
17311745
"casa [$rs1] $asi, $rs2, $rd", []>;
17321746

1747+
// On the other hand, CASA that takes its ASI from a register
1748+
// is only supported on V9 processors.
1749+
let Predicates = [HasV9], Uses = [ASR3], Constraints = "$swap = $rd" in
1750+
def CASAri: F3_1_cas_asi<3, 0b111100,
1751+
(outs IntRegs:$rd), (ins IntRegs:$rs1, IntRegs:$rs2,
1752+
IntRegs:$swap),
1753+
"casa [$rs1] %asi, $rs2, $rd", []>;
1754+
17331755
// TODO: Add DAG sequence to lower these instructions. Currently, only provided
17341756
// as inline assembler-supported instructions.
17351757
let Predicates = [HasUMAC_SMAC], Defs = [Y, ASR18], Uses = [Y, ASR18] in {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# RUN: llvm-mc --disassemble %s -triple=sparcv9-unknown-linux | FileCheck %s
2+
3+
# CHECK: cas [%i0], %l6, %o2
4+
0xd5,0xe6,0x10,0x16
5+
6+
# CHECK: casl [%i0], %l6, %o2
7+
0xd5,0xe6,0x11,0x16
8+
9+
# CHECK: casa [%i0] 255, %l6, %o2
10+
0xd5,0xe6,0x1f,0xf6
11+
12+
# CHECK: casa [%i0] %asi, %l6, %o2
13+
0xd5,0xe6,0x20,0x16
14+
15+
# CHECK: casx [%i0], %l6, %o2
16+
0xd5,0xf6,0x10,0x16
17+
18+
# CHECK: casxl [%i0], %l6, %o2
19+
0xd5,0xf6,0x11,0x16
20+
21+
# CHECK: casxa [%i0] 255, %l6, %o2
22+
0xd5,0xf6,0x1f,0xf6
23+
24+
# CHECK: casxa [%i0] %asi, %l6, %o2
25+
0xd5,0xf6,0x20,0x16
Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,11 @@
1-
! RUN: llvm-mc %s -arch=sparc -mcpu=leon3 -show-encoding | FileCheck %s -check-prefix=CHECK_NO_CASA
2-
! RUN: llvm-mc %s -arch=sparc -mcpu=ut699 -show-encoding | FileCheck %s -check-prefix=CHECK_NO_CASA
1+
! RUN: llvm-mc %s -arch=sparc -mcpu=leon3 -show-encoding | FileCheck %s
2+
! RUN: llvm-mc %s -arch=sparc -mcpu=ut699 -show-encoding | FileCheck %s
33
! RUN: llvm-mc %s -arch=sparc -mcpu=gr712rc -show-encoding | FileCheck %s
44
! RUN: llvm-mc %s -arch=sparc -mcpu=leon4 -show-encoding | FileCheck %s
55
! RUN: llvm-mc %s -arch=sparc -mcpu=gr740 -show-encoding | FileCheck %s
66

7-
8-
! CHECK: casa [%i0] 10, %l6, %o2 ! encoding: [0xd5,0xe6,0x01,0x56]
9-
casa [%i0] 10, %l6, %o2
10-
11-
! CHECK: casa [%i0] 5, %l6, %o2 ! encoding: [0xd5,0xe6,0x00,0xb6]
12-
casa [%i0] 5, %l6, %o2
13-
147
! CHECK: umac %i0, %l6, %o2 ! encoding: [0x95,0xf6,0x00,0x16]
15-
! CHECK_NO_CASA: umac %i0, %l6, %o2 ! encoding: [0x95,0xf6,0x00,0x16]
168
umac %i0, %l6, %o2
179

1810
! CHECK: smac %i0, %l6, %o2 ! encoding: [0x95,0xfe,0x00,0x16]
19-
! CHECK_NO_CASA: smac %i0, %l6, %o2 ! encoding: [0x95,0xfe,0x00,0x16]
2011
smac %i0, %l6, %o2
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
! RUN: not llvm-mc %s -arch=sparc -show-encoding 2>&1 | FileCheck %s --check-prefix=V8
2+
! RUN: not llvm-mc %s -arch=sparc -mattr=+hasleoncasa -show-encoding 2>&1 | FileCheck %s --check-prefix=LEON
3+
! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s --check-prefix=V9
4+
5+
! V8: error: instruction requires a CPU feature not currently enabled
6+
! V9: cas [%i0], %l6, %o2 ! encoding: [0xd5,0xe6,0x10,0x16]
7+
! LEON: error: instruction requires a CPU feature not currently enabled
8+
cas [%i0], %l6, %o2
9+
10+
! V8: error: instruction requires a CPU feature not currently enabled
11+
! V9: casl [%i0], %l6, %o2 ! encoding: [0xd5,0xe6,0x11,0x16]
12+
! LEON: error: instruction requires a CPU feature not currently enabled
13+
casl [%i0], %l6, %o2
14+
15+
! V8: error: instruction requires a CPU feature not currently enabled
16+
! V9: casx [%i0], %l6, %o2 ! encoding: [0xd5,0xf6,0x10,0x16]
17+
! LEON: error: instruction requires a CPU feature not currently enabled
18+
casx [%i0], %l6, %o2
19+
20+
! V8: error: instruction requires a CPU feature not currently enabled
21+
! V9: casxl [%i0], %l6, %o2 ! encoding: [0xd5,0xf6,0x11,0x16]
22+
! LEON: error: instruction requires a CPU feature not currently enabled
23+
casxl [%i0], %l6, %o2
24+
25+
! V8: error: malformed ASI tag, must be a constant integer expression
26+
! V9: casxa [%i0] %asi, %l6, %o2 ! encoding: [0xd5,0xf6,0x20,0x16]
27+
! LEON: error: malformed ASI tag, must be a constant integer expression
28+
casxa [%i0] %asi, %l6, %o2
29+
30+
! V8: error: instruction requires a CPU feature not currently enabled
31+
! V9: casxa [%i0] 128, %l6, %o2 ! encoding: [0xd5,0xf6,0x10,0x16]
32+
! LEON: error: instruction requires a CPU feature not currently enabled
33+
casxa [%i0] 0x80, %l6, %o2
34+
35+
! V8: error: instruction requires a CPU feature not currently enabled
36+
! V9: casxa [%i0] 128, %l6, %o2 ! encoding: [0xd5,0xf6,0x10,0x16]
37+
! LEON: error: instruction requires a CPU feature not currently enabled
38+
casxa [%i0] (0x40+0x40), %l6, %o2
39+
40+
! V8: error: malformed ASI tag, must be a constant integer expression
41+
! V9: casa [%i0] %asi, %l6, %o2 ! encoding: [0xd5,0xe6,0x20,0x16]
42+
! LEON: error: malformed ASI tag, must be a constant integer expression
43+
casa [%i0] %asi, %l6, %o2
44+
45+
! V8: error: instruction requires a CPU feature not currently enabled
46+
! V9: casa [%i0] 128, %l6, %o2 ! encoding: [0xd5,0xe6,0x10,0x16]
47+
! LEON: casa [%i0] 128, %l6, %o2 ! encoding: [0xd5,0xe6,0x10,0x16]
48+
casa [%i0] 0x80, %l6, %o2
49+
50+
! V8: error: instruction requires a CPU feature not currently enabled
51+
! V9: casa [%i0] 128, %l6, %o2 ! encoding: [0xd5,0xe6,0x10,0x16]
52+
! LEON: casa [%i0] 128, %l6, %o2 ! encoding: [0xd5,0xe6,0x10,0x16]
53+
casa [%i0] (0x40+0x40), %l6, %o2

llvm/test/MC/Sparc/sparcv9-atomic-instructions.s

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,3 @@
1717

1818
! CHECK: ldstuba [%i0+2] %asi, %g1 ! encoding: [0xc2,0xee,0x20,0x02]
1919
ldstuba [%i0+2] %asi, %g1
20-
21-
! CHECK: cas [%i0], %l6, %o2 ! encoding: [0xd5,0xe6,0x10,0x16]
22-
cas [%i0], %l6, %o2
23-
24-
! CHECK: casx [%i0], %l6, %o2 ! encoding: [0xd5,0xf6,0x10,0x16]
25-
casx [%i0], %l6, %o2

0 commit comments

Comments
 (0)