Skip to content

Commit 89f87c3

Browse files
authored
[RISCV][MC] Add MC layer support for the experimental zabha extension (#80005)
This patch implements the zabha (Byte and Halfword Atomic Memory Operations) v1.0-rc1 extension. See also https://github.com/riscv/riscv-zabha/blob/v1.0-rc1/zabha.adoc.
1 parent dd73666 commit 89f87c3

15 files changed

+407
-0
lines changed

llvm/docs/RISCVUsage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,9 @@ LLVM supports (to various degrees) a number of experimental extensions. All exp
226226

227227
The primary goal of experimental support is to assist in the process of ratification by providing an existence proof of an implementation, and simplifying efforts to validate the value of a proposed extension against large code bases. Experimental extensions are expected to either transition to ratified status, or be eventually removed. The decision on whether to accept an experimental extension is currently done on an entirely case by case basis; if you want to propose one, attending the bi-weekly RISC-V sync-up call is strongly advised.
228228

229+
``experimental-zabha``
230+
LLVM implements assembler support for the `v1.0-rc1 draft specification <https://github.com/riscv/riscv-zabha/tree/v1.0-rc1>`_.
231+
229232
``experimental-zacas``
230233
LLVM implements the `1.0-rc1 draft specification <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc1>`_.
231234

llvm/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ Changes to the RISC-V Backend
9393
-----------------------------
9494

9595
* Support for the Zicond extension is no longer experimental.
96+
* Added assembler/disassembler support for the experimental Zabha (Byte and Halfword Atomic Memory Operations) extension.
9697

9798
Changes to the WebAssembly Backend
9899
----------------------------------

llvm/lib/Support/RISCVISAInfo.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
195195
// clang-format off
196196
static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
197197
{"zaamo", {0, 2}},
198+
{"zabha", {1, 0}},
198199
{"zacas", {1, 0}},
199200
{"zalrsc", {0, 2}},
200201

@@ -1017,6 +1018,7 @@ static const char *ImpliedExtsXSfvfnrclipxfqf[] = {"zve32f"};
10171018
static const char *ImpliedExtsXSfvfwmaccqqq[] = {"zvfbfmin"};
10181019
static const char *ImpliedExtsXSfvqmaccdod[] = {"zve32x"};
10191020
static const char *ImpliedExtsXSfvqmaccqoq[] = {"zve32x"};
1021+
static const char *ImpliedExtsZabha[] = {"a"};
10201022
static const char *ImpliedExtsZacas[] = {"a"};
10211023
static const char *ImpliedExtsZcb[] = {"zca"};
10221024
static const char *ImpliedExtsZcd[] = {"d", "zca"};
@@ -1091,6 +1093,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
10911093
{{"xsfvqmaccdod"}, {ImpliedExtsXSfvqmaccdod}},
10921094
{{"xsfvqmaccqoq"}, {ImpliedExtsXSfvqmaccqoq}},
10931095
{{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
1096+
{{"zabha"}, {ImpliedExtsZabha}},
10941097
{{"zacas"}, {ImpliedExtsZacas}},
10951098
{{"zcb"}, {ImpliedExtsZcb}},
10961099
{{"zcd"}, {ImpliedExtsZcd}},

llvm/lib/Target/RISCV/RISCVFeatures.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ def HasStdExtAOrZaamo
177177
"'A' (Atomic Instructions) or "
178178
"'Zaamo' (Atomic Memory Operations)">;
179179

180+
def FeatureStdExtZabha
181+
: SubtargetFeature<"experimental-zabha", "HasStdExtZabha", "true",
182+
"'Zabha' (Byte and Halfword Atomic Memory Operations)">;
183+
def HasStdExtZabha : Predicate<"Subtarget->hasStdExtZabha()">,
184+
AssemblerPredicate<(all_of FeatureStdExtZabha),
185+
"'Zabha' (Byte and Halfword Atomic Memory Operations)">;
186+
180187
def FeatureStdExtZacas
181188
: SubtargetFeature<"experimental-zacas", "HasStdExtZacas", "true",
182189
"'Zacas' (Atomic Compare-And-Swap Instructions)">;

llvm/lib/Target/RISCV/RISCVInstrInfoZa.td

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
// extensions:
1111
// - Zawrs (v1.0) : Wait-on-Reservation-Set.
1212
// - Zacas (v1.0-rc1) : Atomic Compare-and-Swap.
13+
// - Zabha (v1.0-rc1) : Byte and Halfword Atomic Memory Operations.
1314
//
1415
//===----------------------------------------------------------------------===//
1516

@@ -134,3 +135,53 @@ let Predicates = [HasStdExtZawrs] in {
134135
def WRS_NTO : WRSInst<0b000000001101, "wrs.nto">, Sched<[]>;
135136
def WRS_STO : WRSInst<0b000000011101, "wrs.sto">, Sched<[]>;
136137
} // Predicates = [HasStdExtZawrs]
138+
139+
//===----------------------------------------------------------------------===//
140+
// Zabha (Byte and Halfword Atomic Memory Operations)
141+
//===----------------------------------------------------------------------===//
142+
143+
let Predicates = [HasStdExtZabha] in {
144+
defm AMOSWAP_B : AMO_rr_aq_rl<0b00001, 0b000, "amoswap.b">,
145+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
146+
defm AMOADD_B : AMO_rr_aq_rl<0b00000, 0b000, "amoadd.b">,
147+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
148+
defm AMOXOR_B : AMO_rr_aq_rl<0b00100, 0b000, "amoxor.b">,
149+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
150+
defm AMOAND_B : AMO_rr_aq_rl<0b01100, 0b000, "amoand.b">,
151+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
152+
defm AMOOR_B : AMO_rr_aq_rl<0b01000, 0b000, "amoor.b">,
153+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
154+
defm AMOMIN_B : AMO_rr_aq_rl<0b10000, 0b000, "amomin.b">,
155+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
156+
defm AMOMAX_B : AMO_rr_aq_rl<0b10100, 0b000, "amomax.b">,
157+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
158+
defm AMOMINU_B : AMO_rr_aq_rl<0b11000, 0b000, "amominu.b">,
159+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
160+
defm AMOMAXU_B : AMO_rr_aq_rl<0b11100, 0b000, "amomaxu.b">,
161+
Sched<[WriteAtomicB, ReadAtomicBA, ReadAtomicBD]>;
162+
163+
defm AMOSWAP_H : AMO_rr_aq_rl<0b00001, 0b001, "amoswap.h">,
164+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
165+
defm AMOADD_H : AMO_rr_aq_rl<0b00000, 0b001, "amoadd.h">,
166+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
167+
defm AMOXOR_H : AMO_rr_aq_rl<0b00100, 0b001, "amoxor.h">,
168+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
169+
defm AMOAND_H : AMO_rr_aq_rl<0b01100, 0b001, "amoand.h">,
170+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
171+
defm AMOOR_H : AMO_rr_aq_rl<0b01000, 0b001, "amoor.h">,
172+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
173+
defm AMOMIN_H : AMO_rr_aq_rl<0b10000, 0b001, "amomin.h">,
174+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
175+
defm AMOMAX_H : AMO_rr_aq_rl<0b10100, 0b001, "amomax.h">,
176+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
177+
defm AMOMINU_H : AMO_rr_aq_rl<0b11000, 0b001, "amominu.h">,
178+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
179+
defm AMOMAXU_H : AMO_rr_aq_rl<0b11100, 0b001, "amomaxu.h">,
180+
Sched<[WriteAtomicH, ReadAtomicHA, ReadAtomicHD]>;
181+
}
182+
183+
// If Zacas extension is also implemented, Zabha further provides AMOCAS.[B|H].
184+
let Predicates = [HasStdExtZabha, HasStdExtZacas] in {
185+
defm AMOCAS_B : AMO_cas_aq_rl<0b00101, 0b000, "amocas.b", GPR>;
186+
defm AMOCAS_H : AMO_cas_aq_rl<0b00101, 0b001, "amocas.h", GPR>;
187+
}

llvm/lib/Target/RISCV/RISCVSchedRocket.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ def : ReadAdvance<ReadFClass64, 0>;
239239
//===----------------------------------------------------------------------===//
240240
// Unsupported extensions
241241
defm : UnsupportedSchedV;
242+
defm : UnsupportedSchedZabha;
242243
defm : UnsupportedSchedZba;
243244
defm : UnsupportedSchedZbb;
244245
defm : UnsupportedSchedZbc;

llvm/lib/Target/RISCV/RISCVSchedSiFive7.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,7 @@ foreach mx = SchedMxList in {
12091209

12101210
//===----------------------------------------------------------------------===//
12111211
// Unsupported extensions
1212+
defm : UnsupportedSchedZabha;
12121213
defm : UnsupportedSchedZbc;
12131214
defm : UnsupportedSchedZbkb;
12141215
defm : UnsupportedSchedZbkx;

llvm/lib/Target/RISCV/RISCVSchedSiFiveP400.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ def : ReadAdvance<ReadSingleBitImm, 0>;
345345

346346
//===----------------------------------------------------------------------===//
347347
// Unsupported extensions
348+
defm : UnsupportedSchedZabha;
348349
defm : UnsupportedSchedZbc;
349350
defm : UnsupportedSchedZbkb;
350351
defm : UnsupportedSchedZbkx;

llvm/lib/Target/RISCV/RISCVSchedSyntacoreSCR1.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ def : ReadAdvance<ReadSFBALU, 0>;
199199
//===----------------------------------------------------------------------===//
200200
// Unsupported extensions
201201
defm : UnsupportedSchedV;
202+
defm : UnsupportedSchedZabha;
202203
defm : UnsupportedSchedZba;
203204
defm : UnsupportedSchedZbb;
204205
defm : UnsupportedSchedZbc;

llvm/lib/Target/RISCV/RISCVSchedule.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ def WriteSTB : SchedWrite; // Store byte
3030
def WriteSTH : SchedWrite; // Store half-word
3131
def WriteSTW : SchedWrite; // Store word
3232
def WriteSTD : SchedWrite; // Store double-word
33+
def WriteAtomicB : SchedWrite; //Atomic memory operation byte size
34+
def WriteAtomicH : SchedWrite; //Atomic memory operation halfword size
3335
def WriteAtomicW : SchedWrite; //Atomic memory operation word size
3436
def WriteAtomicD : SchedWrite; //Atomic memory operation double word size
3537
def WriteAtomicLDW : SchedWrite; // Atomic load word
@@ -135,6 +137,10 @@ def ReadIDiv : SchedRead;
135137
def ReadIDiv32 : SchedRead;
136138
def ReadIMul : SchedRead;
137139
def ReadIMul32 : SchedRead;
140+
def ReadAtomicBA : SchedRead;
141+
def ReadAtomicBD : SchedRead;
142+
def ReadAtomicHA : SchedRead;
143+
def ReadAtomicHD : SchedRead;
138144
def ReadAtomicWA : SchedRead;
139145
def ReadAtomicWD : SchedRead;
140146
def ReadAtomicDA : SchedRead;
@@ -271,6 +277,18 @@ def : ReadAdvance<ReadFRoundF16, 0>;
271277
} // Unsupported = true
272278
}
273279

280+
multiclass UnsupportedSchedZabha {
281+
let Unsupported = true in {
282+
def : WriteRes<WriteAtomicB, []>;
283+
def : WriteRes<WriteAtomicH, []>;
284+
285+
def : ReadAdvance<ReadAtomicBA, 0>;
286+
def : ReadAdvance<ReadAtomicBD, 0>;
287+
def : ReadAdvance<ReadAtomicHA, 0>;
288+
def : ReadAdvance<ReadAtomicHD, 0>;
289+
} // Unsupported = true
290+
}
291+
274292
// Include the scheduler resources for other instruction extensions.
275293
include "RISCVScheduleZb.td"
276294
include "RISCVScheduleV.td"

llvm/test/CodeGen/RISCV/attributes.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV32ZACAS %s
9898
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
9999
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV32ZICFILP %s
100+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zabha %s -o - | FileCheck --check-prefix=RV32ZABHA %s
100101

101102
; RUN: llc -mtriple=riscv64 %s -o - | FileCheck %s
102103
; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefixes=CHECK,RV64M %s
@@ -201,6 +202,7 @@
201202
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s
202203
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zalrsc %s -o - | FileCheck --check-prefix=RV64ZALRSC %s
203204
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV64ZICFILP %s
205+
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zabha %s -o - | FileCheck --check-prefix=RV64ZABHA %s
204206

205207
; CHECK: .attribute 4, 16
206208

@@ -300,6 +302,7 @@
300302
; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas1p0"
301303
; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc0p2"
302304
; RV32ZICFILP: .attribute 5, "rv32i2p1_zicfilp0p4"
305+
; RV32ZABHA: .attribute 5, "rv32i2p1_a2p1_zabha1p0"
303306

304307
; RV64M: .attribute 5, "rv64i2p1_m2p0"
305308
; RV64ZMMUL: .attribute 5, "rv64i2p1_zmmul1p0"
@@ -403,6 +406,7 @@
403406
; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0"
404407
; RV64ZALRSC: .attribute 5, "rv64i2p1_zalrsc0p2"
405408
; RV64ZICFILP: .attribute 5, "rv64i2p1_zicfilp0p4"
409+
; RV64ZABHA: .attribute 5, "rv64i2p1_a2p1_zabha1p0"
406410

407411
define i32 @addi(i32 %a) {
408412
%1 = add i32 %a, 1

llvm/test/MC/RISCV/rvzabha-invalid.s

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zabha < %s 2>&1 | FileCheck %s
2+
# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zabha < %s 2>&1 | FileCheck %s
3+
4+
# Final operand must have parentheses
5+
amoswap.b a1, a2, a3 # CHECK: :[[@LINE]]:19: error: expected '(' or optional integer offset
6+
amomin.b a1, a2, 1 # CHECK: :[[@LINE]]:20: error: expected '(' after optional integer offset
7+
amomin.b a1, a2, 1(a3) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
8+
9+
# Only .aq, .rl, and .aqrl suffixes are valid
10+
amoxor.b.rlqa a2, a3, (a4) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
11+
amoor.b.aq.rl a4, a5, (a6) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
12+
amoor.b. a4, a5, (a6) # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
13+
14+
# Non-zero offsets not supported for the third operand (rs1).
15+
amocas.b a1, a3, 1(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0
16+
amocas.h a0, a2, 2(a5) # CHECK: :[[@LINE]]:18: error: optional integer offset must be 0

0 commit comments

Comments
 (0)