-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[RISCV][MC] MC layer support for the experimental zalasr extension #69685
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -228,6 +228,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 `most recent specification <https://github.com/mehnadnerd/riscv-zalasr>`_. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we nail this down to a version or a date? "most recent" is wrong if that repo changes. |
||
|
||
``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>`_. | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -797,6 +797,13 @@ def FeatureStdExtSvpbmt | |
: SubtargetFeature<"svpbmt", "HasStdExtSvpbmt", "true", | ||
"'Svpbmt' (Page-Based Memory Types)">; | ||
|
||
def FeatureStdExtZalasr | ||
: SubtargetFeature<"experimental-zalasr", "HasStdExtZalasr", "true", | ||
"'Zalasr' (Load-Acquire and Store-Release Instructions)">; | ||
def HasStdExtZalasr : Predicate<"Subtarget->hasStdExtZalasr()">, | ||
AssemblerPredicate<(all_of FeatureStdExtZalasr), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Align |
||
"'Zalasr' (Load-Acquire and Store-Release Instructions)">; | ||
|
||
//===----------------------------------------------------------------------===// | ||
// Vendor extensions | ||
//===----------------------------------------------------------------------===// | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,22 +105,63 @@ defm AMOMAXU_D : AMO_rr_aq_rl<0b11100, 0b011, "amomaxu.d">, | |
// Pseudo-instructions and codegen patterns | ||
//===----------------------------------------------------------------------===// | ||
|
||
// An atomic load operation that does not need either acquire or release | ||
// semantics. | ||
class relaxed_load<PatFrags base> | ||
: PatFrag<(ops node:$ptr), (base node:$ptr)> { | ||
let IsAtomic = 1; | ||
let IsAtomicOrderingMonotonic = 1; | ||
} | ||
|
||
// A atomic load operation that actually needs acquire semantics. | ||
class acquiring_load<PatFrags base> | ||
: PatFrag<(ops node:$ptr), (base node:$ptr)> { | ||
let IsAtomic = 1; | ||
let IsAtomicOrderingAcquire = 1; | ||
} | ||
|
||
// An atomic load operation that needs sequential consistency. | ||
class seq_cst_load<PatFrags base> | ||
: PatFrag<(ops node:$ptr), (base node:$ptr)> { | ||
let IsAtomic = 1; | ||
let IsAtomicOrderingSequentiallyConsistent = 1; | ||
} | ||
|
||
// An atomic store operation that doesn't actually need to be atomic on RISCV. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RISCV -> RISC-V |
||
class relaxed_store<PatFrag base> | ||
: PatFrag<(ops node:$ptr, node:$val), (base node:$val, node:$ptr)> { | ||
let IsAtomic = 1; | ||
let IsAtomicOrderingMonotonic = 1; | ||
} | ||
|
||
// A store operation that actually needs release semantics. | ||
class releasing_store<PatFrag base> | ||
: PatFrag<(ops node:$ptr, node:$val), (base node:$val, node:$ptr)> { | ||
let IsAtomic = 1; | ||
let IsAtomicOrderingRelease = 1; | ||
} | ||
|
||
// A store operation that actually needs sequential consistency. | ||
class seq_cst_store<PatFrag base> | ||
: PatFrag<(ops node:$ptr, node:$val), (base node:$val, node:$ptr)> { | ||
let IsAtomic = 1; | ||
let IsAtomicOrderingSequentiallyConsistent = 1; | ||
} | ||
|
||
// Atomic load/store are available under both +a and +force-atomics. | ||
// Fences will be inserted for atomic load/stores according to the logic in | ||
// RISCVTargetLowering::{emitLeadingFence,emitTrailingFence}. | ||
let Predicates = [HasAtomicLdSt] in { | ||
def : LdPat<atomic_load_8, LB>; | ||
def : LdPat<atomic_load_16, LH>; | ||
def : LdPat<atomic_load_32, LW>; | ||
def : LdPat<relaxed_load<atomic_load_8>, LB>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is an MC patch as the title says, we shouldn't be touching any isel patterns. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was originally an MC patch but I am adding isel support as well. What should I change the title to? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We usually want MC and CodeGen changes as separate PRs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh. I will separate it out then. |
||
def : LdPat<relaxed_load<atomic_load_16>, LH>; | ||
def : LdPat<relaxed_load<atomic_load_32>, LW>; | ||
|
||
def : StPat<atomic_store_8, SB, GPR, XLenVT>; | ||
def : StPat<atomic_store_16, SH, GPR, XLenVT>; | ||
def : StPat<atomic_store_32, SW, GPR, XLenVT>; | ||
def : StPat<relaxed_store<atomic_store_8>, SB, GPR, XLenVT>; | ||
def : StPat<relaxed_store<atomic_store_16>, SH, GPR, XLenVT>; | ||
def : StPat<relaxed_store<atomic_store_32>, SW, GPR, XLenVT>; | ||
} | ||
|
||
let Predicates = [HasAtomicLdSt, IsRV64] in { | ||
def : LdPat<atomic_load_64, LD, i64>; | ||
def : StPat<atomic_store_64, SD, GPR, i64>; | ||
def : LdPat<relaxed_load<atomic_load_64>, LD, i64>; | ||
def : StPat<relaxed_store<atomic_store_64>, SD, GPR, i64>; | ||
} | ||
|
||
/// AMOs | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
//===-- RISCVInstrInfoZalasr.td - RISC-V 'Zalasr' 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// 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_AQ : LAQ_r_aq_rl<0b000, "lb">; | ||
defm LH_AQ : LAQ_r_aq_rl<0b001, "lh">; | ||
defm LW_AQ : LAQ_r_aq_rl<0b010, "lw">; | ||
defm SB_RL : SRL_r_aq_rl<0b000, "sb">; | ||
defm SH_RL : SRL_r_aq_rl<0b001, "sh">; | ||
defm SW_RL : SRL_r_aq_rl<0b010, "sw">; | ||
} // Predicates = [HasStdExtZalasr] | ||
|
||
let Predicates = [HasStdExtZalasr, IsRV64] in { | ||
defm LD_AQ : LAQ_r_aq_rl<0b011, "ld">; | ||
defm SD_RL : SRL_r_aq_rl<0b011, "sd">; | ||
} // Predicates = [HasStdExtZalasr, IsRV64] | ||
|
||
//===----------------------------------------------------------------------===// | ||
// Pseudo-instructions and codegen patterns | ||
//===----------------------------------------------------------------------===// | ||
|
||
class PatLAQ<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't add patterns in MC patch. |
||
: Pat<(vt (OpNode (vt GPRMemZeroOffset:$rs1))), (Inst GPRMemZeroOffset:$rs1)>; | ||
|
||
class PatSRL<SDPatternOperator OpNode, RVInst Inst, ValueType vt = XLenVT> | ||
: Pat<(OpNode (vt GPR:$rs2), (vt GPRMemZeroOffset:$rs1)), (Inst GPR:$rs2, GPRMemZeroOffset:$rs1)>; | ||
|
||
let Predicates = [HasStdExtZalasr] in { | ||
def : PatLAQ<acquiring_load<atomic_load_8>, LB_AQ_AQ>; | ||
def : PatLAQ<seq_cst_load<atomic_load_8>, LB_AQ_AQ>; // these use lb.aq instead of lb.aqrl to match the psABI | ||
|
||
def : PatLAQ<acquiring_load<atomic_load_16>, LH_AQ_AQ>; | ||
def : PatLAQ<seq_cst_load<atomic_load_16>, LH_AQ_AQ>; | ||
|
||
def : PatLAQ<acquiring_load<atomic_load_32>, LW_AQ_AQ>; | ||
def : PatLAQ<seq_cst_load<atomic_load_32>, LW_AQ_AQ>; | ||
|
||
def : PatSRL<releasing_store<atomic_store_8>, SB_RL_RL>; | ||
def : PatSRL<seq_cst_store<atomic_store_8>, SB_RL_RL>; // these use sb.rl instead of sb.aqrl to match the psABI | ||
|
||
def : PatSRL<releasing_store<atomic_store_16>, SH_RL_RL>; | ||
def : PatSRL<seq_cst_store<atomic_store_16>, SH_RL_RL>; | ||
|
||
def : PatSRL<releasing_store<atomic_store_32>, SW_RL_RL>; | ||
def : PatSRL<seq_cst_store<atomic_store_32>, SW_RL_RL>; | ||
} // Predicates HasStdExtZalasr | ||
|
||
let Predicates = [HasStdExtZalasr, IsRV64] in { | ||
def : PatLAQ<acquiring_load<atomic_load_64>, LD_AQ_AQ>; | ||
def : PatLAQ<seq_cst_load<atomic_load_64>, LD_AQ_AQ>; | ||
|
||
def : PatSRL<releasing_store<atomic_store_64>, SD_RL_RL>; | ||
def : PatSRL<seq_cst_store<atomic_store_64>, SD_RL_RL>; | ||
} // Predicates HasStdExtZalasr, IsRV64 |
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) |
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.
Indent line continuations 2 spaces and drop
-x c
. This was recently updated in the reset of the file.