Skip to content

Commit

Permalink
[RISCV][MC] MC layer support for the experimental zalasr extension (l…
Browse files Browse the repository at this point in the history
…lvm#79911)

This PR implements experimental support for the RISC-V Atomic
Load-Acquire and Store-Release Extension (Zalasr). It has been approved
to be pursued as a fast track extension
(https://lists.riscv.org/g/tech-unprivileged/topic/arc_architecture_review/101951698),
but has not yet been approved by ARC or ratified. See
https://github.com/mehnadnerd/riscv-zalasr for draft spec.

---------

Co-authored-by: brs <turtwig@utexas.edu>
Co-authored-by: Philip Reames <preames@rivosinc.com>
  • Loading branch information
3 people authored and Carlos Gálvez committed Feb 1, 2024
1 parent 7cbc43a commit fe5ae8f
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 0 deletions.
9 changes: 9 additions & 0 deletions clang/test/Preprocessor/riscv-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@

// CHECK-NOT: __riscv_zaamo {{.*$}}
// CHECK-NOT: __riscv_zacas {{.*$}}
// CHECK-NOT: __riscv_zalasr {{.*$}}
// CHECK-NOT: __riscv_zalrsc {{.*$}}
// CHECK-NOT: __riscv_zcmop {{.*$}}
// CHECK-NOT: __riscv_zfbfmin {{.*$}}
Expand Down Expand Up @@ -1333,6 +1334,14 @@
// RUN: -o - | FileCheck --check-prefix=CHECK-ZACAS-EXT %s
// CHECK-ZACAS-EXT: __riscv_zacas 1000000{{$}}

// RUN: %clang --target=riscv32 -menable-experimental-extensions \
// RUN: -march=rv32i_zalasr0p1 -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-ZALASR-EXT %s
// RUN: %clang --target=riscv64 -menable-experimental-extensions \
// RUN: -march=rv64i_zalasr0p1 -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-ZALASR-EXT %s
// CHECK-ZALASR-EXT: __riscv_zalasr 1000{{$}}

// RUN: %clang --target=riscv32 -menable-experimental-extensions \
// RUN: -march=rv32i_zalrsc0p2 -E -dM %s \
// RUN: -o - | FileCheck --check-prefix=CHECK-ZALRSC-EXT %s
Expand Down
3 changes: 3 additions & 0 deletions llvm/docs/RISCVUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ The primary goal of experimental support is to assist in the process of ratifica
``experimental-zacas``
LLVM implements the `1.0-rc1 draft specification <https://github.com/riscv/riscv-zacas/releases/tag/v1.0-rc1>`_.

``experimental-zalasr``
LLVM implements the `0.0.5 draft specification <https://github.com/mehnadnerd/riscv-zalasr>`_.

``experimental-zfbfmin``, ``experimental-zvfbfmin``, ``experimental-zvfbfwma``
LLVM implements assembler support for the `1.0.0-rc2 specification <https://github.com/riscv/riscv-bfloat16/releases/tag/v59042fc71c31a9bcb2f1957621c960ed36fac401>`_.

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Support/RISCVISAInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
{"zaamo", {0, 2}},
{"zabha", {1, 0}},
{"zacas", {1, 0}},
{"zalasr", {0, 1}},
{"zalrsc", {0, 2}},

{"zcmop", {0, 2}},
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@ def HasStdExtZacas : Predicate<"Subtarget->hasStdExtZacas()">,
"'Zacas' (Atomic Compare-And-Swap Instructions)">;
def NoStdExtZacas : Predicate<"!Subtarget->hasStdExtZacas()">;

def FeatureStdExtZalasr
: SubtargetFeature<"experimental-zalasr", "HasStdExtZalasr", "true",
"'Zalasr' (Load-Acquire and Store-Release Instructions)">;
def HasStdExtZalasr : Predicate<"Subtarget->hasStdExtZalasr()">,
AssemblerPredicate<(all_of FeatureStdExtZalasr),
"'Zalasr' (Load-Acquire and Store-Release Instructions)">;

def FeatureStdExtZalrsc
: SubtargetFeature<"experimental-zalrsc", "HasStdExtZalrsc", "true",
"'Zalrsc' (Load-Reserved/Store-Conditional)">;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -2146,6 +2146,7 @@ include "RISCVInstrInfoM.td"
// Atomic
include "RISCVInstrInfoA.td"
include "RISCVInstrInfoZa.td"
include "RISCVInstrInfoZalasr.td"

// Scalar FP
include "RISCVInstrInfoF.td"
Expand Down
59 changes: 59 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZalasr.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//===-- RISCVInstrInfoZalasr.td ---------------------------*- 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
//
//===----------------------------------------------------------------------===//
//
// This file describes the RISC-V instructions from the Zalasr (Load-Acquire
// and Store-Release) extension
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Instruction class templates
//===----------------------------------------------------------------------===//

let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in
class LAQ_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
: RVInstRAtomic<0b00110, aq, rl, funct3, OPC_AMO,
(outs GPR:$rd), (ins GPRMemZeroOffset:$rs1),
opcodestr, "$rd, $rs1"> {
let rs2 = 0;
}

let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
class SRL_r<bit aq, bit rl, bits<3> funct3, string opcodestr>
: RVInstRAtomic<0b00111, aq, rl, funct3, OPC_AMO,
(outs ), (ins GPRMemZeroOffset:$rs1, GPR:$rs2),
opcodestr, "$rs2, $rs1"> {
let rd = 0;
}
multiclass LAQ_r_aq_rl<bits<3> funct3, string opcodestr> {
def _AQ : LAQ_r<1, 0, funct3, opcodestr # ".aq">;
def _AQ_RL : LAQ_r<1, 1, funct3, opcodestr # ".aqrl">;
}

multiclass SRL_r_aq_rl<bits<3> funct3, string opcodestr> {
def _RL : SRL_r<0, 1, funct3, opcodestr # ".rl">;
def _AQ_RL : SRL_r<1, 1, funct3, opcodestr # ".aqrl">;
}

//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//

let Predicates = [HasStdExtZalasr] in {
defm LB : LAQ_r_aq_rl<0b000, "lb">;
defm LH : LAQ_r_aq_rl<0b001, "lh">;
defm LW : LAQ_r_aq_rl<0b010, "lw">;
defm SB : SRL_r_aq_rl<0b000, "sb">;
defm SH : SRL_r_aq_rl<0b001, "sh">;
defm SW : SRL_r_aq_rl<0b010, "sw">;
} // Predicates = [HasStdExtZalasr]

let Predicates = [HasStdExtZalasr, IsRV64] in {
defm LD : LAQ_r_aq_rl<0b011, "ld">;
defm SD : SRL_r_aq_rl<0b011, "sd">;
} // Predicates = [HasStdExtZalasr, IsRV64]
4 changes: 4 additions & 0 deletions llvm/test/CodeGen/RISCV/attributes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zvfbfwma %s -o - | FileCheck --check-prefixes=CHECK,RV32ZVFBFWMA %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zaamo %s -o - | FileCheck --check-prefix=RV32ZAAMO %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV32ZACAS %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zalasr %s -o - | FileCheck --check-prefix=RV32ZALASR %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zalrsc %s -o - | FileCheck --check-prefix=RV32ZALRSC %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV32ZICFILP %s
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zabha %s -o - | FileCheck --check-prefix=RV32ZABHA %s
Expand Down Expand Up @@ -200,6 +201,7 @@
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zvfbfwma %s -o - | FileCheck --check-prefixes=CHECK,RV64ZVFBFWMA %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zaamo %s -o - | FileCheck --check-prefix=RV64ZAAMO %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zacas %s -o - | FileCheck --check-prefix=RV64ZACAS %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zalasr %s -o - | FileCheck --check-prefix=RV64ZALASR %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zalrsc %s -o - | FileCheck --check-prefix=RV64ZALRSC %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfilp %s -o - | FileCheck --check-prefix=RV64ZICFILP %s
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zabha %s -o - | FileCheck --check-prefix=RV64ZABHA %s
Expand Down Expand Up @@ -300,6 +302,7 @@
; RV32ZVFBFWMA: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfbfmin1p0_zve32f1p0_zve32x1p0_zvfbfmin1p0_zvfbfwma1p0_zvl32b1p0"
; RV32ZAAMO: .attribute 5, "rv32i2p1_zaamo0p2"
; RV32ZACAS: .attribute 5, "rv32i2p1_a2p1_zacas1p0"
; RV32ZALASR: .attribute 5, "rv32i2p1_zalasr0p1"
; RV32ZALRSC: .attribute 5, "rv32i2p1_zalrsc0p2"
; RV32ZICFILP: .attribute 5, "rv32i2p1_zicfilp0p4"
; RV32ZABHA: .attribute 5, "rv32i2p1_a2p1_zabha1p0"
Expand Down Expand Up @@ -404,6 +407,7 @@
; RV64ZVFBFWMA: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfbfmin1p0_zve32f1p0_zve32x1p0_zvfbfmin1p0_zvfbfwma1p0_zvl32b1p0"
; RV64ZAAMO: .attribute 5, "rv64i2p1_zaamo0p2"
; RV64ZACAS: .attribute 5, "rv64i2p1_a2p1_zacas1p0"
; RV64ZALASR: .attribute 5, "rv64i2p1_zalasr0p1"
; RV64ZALRSC: .attribute 5, "rv64i2p1_zalrsc0p2"
; RV64ZICFILP: .attribute 5, "rv64i2p1_zicfilp0p4"
; RV64ZABHA: .attribute 5, "rv64i2p1_a2p1_zabha1p0"
Expand Down
3 changes: 3 additions & 0 deletions llvm/test/MC/RISCV/attribute-arch.s
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@
.attribute arch, "rv32izacas1p0"
# CHECK: attribute 5, "rv32i2p1_a2p1_zacas1p0"

.attribute arch, "rv32izalasr0p1"
# CHECK: attribute 5, "rv32i2p1_zalasr0p1"

.attribute arch, "rv32i_xcvalu"
# CHECK: attribute 5, "rv32i2p1_xcvalu1p0"

Expand Down
40 changes: 40 additions & 0 deletions llvm/test/MC/RISCV/rv32zalasr-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zalasr < %s 2>&1 | FileCheck -check-prefixes=CHECK %s

# CHECK: error: instruction requires the following: RV64I Base Instruction Set{{$}}
ld.aq a1, (t0)

# CHECK: error: instruction requires the following: RV64I Base Instruction Set{{$}}
ld.aqrl a1, (t0)

# CHECK: error: instruction requires the following: RV64I Base Instruction Set{{$}}
sd.rl a1, (t0)

# CHECK: error: instruction requires the following: RV64I Base Instruction Set{{$}}
sd.aqrl a1, (t0)

# CHECK: error: unrecognized instruction mnemonic
lw. a1, (t0)

# CHECK: error: unrecognized instruction mnemonic
lw.rl t3, 0(t5)

# CHECK: error: unrecognized instruction mnemonic
lh.rlaq t4, (t6)

# CHECK: error: unrecognized instruction mnemonic
sb. a1, (t0)

# CHECK: error: unrecognized instruction mnemonic
sh.aq t3, 0(t5)

# CHECK: error: unrecognized instruction mnemonic
sh.rlaq t4, (t6)

# CHECK: error: optional integer offset must be 0
lw.aq zero, 1(a0)

# CHECK: error: optional integer offset must be 0
sw.rl t1, 2(s0)

# CHECK: error: optional integer offset must be 0
sb.aqrl sp, 3(s2)
78 changes: 78 additions & 0 deletions llvm/test/MC/RISCV/rv32zalasr-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zalasr -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zalasr < %s \
# RUN: | llvm-objdump --mattr=+experimental-zalasr -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zalasr -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zalasr < %s \
# RUN: | llvm-objdump --mattr=+experimental-zalasr -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
#
# RUN: not llvm-mc -triple riscv32 \
# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \
# RUN: | FileCheck --check-prefixes=CHECK-NO-EXT %s
# RUN: not llvm-mc -triple riscv64 \
# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \
# RUN: | FileCheck --check-prefixes=CHECK-NO-EXT %s

# CHECK-ASM-AND-OBJ: lb.aq t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x03,0x05,0x34]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
lb.aq t1, 0(a0)

# CHECK-ASM-AND-OBJ: lh.aq t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x13,0x05,0x34]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
lh.aq t1, 0(a0)

# CHECK-ASM-AND-OBJ: lw.aq t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x23,0x05,0x34]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
lw.aq t1, (a0)

# CHECK-ASM-AND-OBJ: lb.aqrl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x03,0x05,0x36]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
lb.aqrl t1, 0(a0)

# CHECK-ASM-AND-OBJ: lh.aqrl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x13,0x05,0x36]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
lh.aqrl t1, (a0)

# CHECK-ASM-AND-OBJ: lw.aqrl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x23,0x05,0x36]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
lw.aqrl t1, (a0)


# CHECK-ASM-AND-OBJ: sb.rl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x00,0x65,0x3a]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
sb.rl t1, (a0)

# CHECK-ASM-AND-OBJ: sh.rl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x10,0x65,0x3a]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
sh.rl t1, 0(a0)

# CHECK-ASM-AND-OBJ: sw.rl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x20,0x65,0x3a]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
sw.rl t1, (a0)

# CHECK-ASM-AND-OBJ: sb.aqrl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x00,0x65,0x3e]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
sb.aqrl t1, (a0)

# CHECK-ASM-AND-OBJ: sh.aqrl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x10,0x65,0x3e]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
sh.aqrl t1, 0(a0)

# CHECK-ASM-AND-OBJ: sw.aqrl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x20,0x65,0x3e]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
sw.aqrl t1, 0(a0)
28 changes: 28 additions & 0 deletions llvm/test/MC/RISCV/rv64zalasr-invalid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-zalasr < %s 2>&1 | FileCheck -check-prefixes=CHECK %s

# CHECK: error: unrecognized instruction mnemonic
lw. a1, (t0)

# CHECK: error: unrecognized instruction mnemonic
lw.rl t3, 0(t5)

# CHECK: error: unrecognized instruction mnemonic
lh.rlaq t4, (t6)

# CHECK: error: unrecognized instruction mnemonic
sb. a1, (t0)

# CHECK: error: unrecognized instruction mnemonic
sh.aq t3, 0(t5)

# CHECK: error: unrecognized instruction mnemonic
sh.rlaq t4, (t6)

# CHECK: error: optional integer offset must be 0
lw.aq zero, 1(a0)

# CHECK: error: optional integer offset must be 0
sw.rl t1, 2(s0)

# CHECK: error: optional integer offset must be 0
sb.aqrl sp, 3(s2)
31 changes: 31 additions & 0 deletions llvm/test/MC/RISCV/rv64zalasr-valid.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zalasr -riscv-no-aliases -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zalasr < %s \
# RUN: | llvm-objdump --mattr=+experimental-zalasr -M no-aliases -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
#
# RUN: not llvm-mc -triple riscv64 \
# RUN: -riscv-no-aliases -show-encoding < %s 2>&1 \
# RUN: | FileCheck --check-prefixes=CHECK-NO-EXT %s


# CHECK-ASM-AND-OBJ: ld.aq t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x33,0x05,0x34]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
ld.aq t1, (a0)

# CHECK-ASM-AND-OBJ: ld.aqrl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x33,0x05,0x36]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
ld.aqrl t1, 0(a0)


# CHECK-ASM-AND-OBJ: sd.rl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x30,0x65,0x3a]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
sd.rl t1, 0(a0)

# CHECK-ASM-AND-OBJ: sd.aqrl t1, (a0)
# CHECK-ASM: encoding: [0x2f,0x30,0x65,0x3e]
# CHECK-NO-EXT: error: instruction requires the following: 'Zalasr' (Load-Acquire and Store-Release Instructions){{$}}
sd.aqrl t1, (a0)
1 change: 1 addition & 0 deletions llvm/unittests/Support/RISCVISAInfoTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ Experimental extensions
zaamo 0.2
zabha 1.0
zacas 1.0
zalasr 0.1
zalrsc 0.2
zfbfmin 1.0
zcmop 0.2
Expand Down

0 comments on commit fe5ae8f

Please sign in to comment.