riscv-v-spec
riscv-v-spec copied to clipboard
Clarify the relationship between extensions.
Update:
2021/9/6: Add zvamo and zvlsseg.
-
V extension
require
F and D, does it meansimplies
? current ISA spec[1] only useimplies
and didn't appear anyrequire
, so I would like having more explicitly clarification for that word. -
Can
Zvl*b
use withoutV
,zve32*
orzve64*
? -
Are these valid combinations? or it's valid but just meaningless, because it won't effect the minimal VLEN?
-
V
withzvl32b
,zvl64b
-
Zve64
withzvl32b
-
-
Are these valid combinations?
- V with zve32* or zve64*
- Any combination two different zve* extensions .
-
Can
zvamo
andzvlsseg
use withoutV
,zve32*
orzve64*
?
[1] https://github.com/riscv/riscv-isa-manual/blob/draft-20210825-d068b76/src/naming.tex#L148
Few more thing want to clarify:
- Are these valid combinations?
-
V
withzve32*
orzve64*
- Any combination two different
zve*
extensions .
-
Does V extension passed to -march should imply at least Zvl128b? (The V vector extension requires that VLEN ≥ 128.)
Can Zvlb use without V, zve32 or zve64*?
In other words, the question is "Does Zvl*b passed to -march should imply the V extension?"
Yes, I think V should imply Zvl128b.
Changes: 2021/9/8: Update note for ELF attribute.
Hmmm...toolchain still need clarification, but before we got a formal clarification, I written down my understanding and my guess, and we gonna to implement that on toolchain.
-
zvl<x>b
impliedzvl<y>b
ifx
>y
, e.g.zvl256b
impliedzvl128b
,zvl64b
andzvl32b
. -
v
impliedzvl128b
,Zve64*
impliedzvl64b
andZve32*
impliedzvl32b
. -
v
withzvl32b
is valid combination but minimal VLEN still 128 due tov
impliedzvl128b
. -
Zve64
withzvl32b
is valid combination but minimal VLEN still 64 due toZve64
impliedzvl64b
. -
v
with anyzve*
extension is valid combination is valid, but still same asv
, e.g.v
+zve32x
=v
- Different
Zve*
extension can be appear in arch string, but we only take the info from the biggest extension, e.g.-
zve64x
+zve32x
=zve64x
-
zve64d
+zve32f
=zve64d
-
zve64d
+zve64f
=zve64d
-
-
require
means toolchain will report error and abort if the requirement not satisfied, e.g. toolchain will report error forrv32iv
rather than interpret that asrv32ifdv
-
Zvl*b
require eitherv
orzve*
extension, otherwise it's invalid arch, toolchain will report error.
Note for ELF attribute:
-
Tag_RISCV_arch
always emit fully expanded form, e.g.v
will expand tov1p0_zvl128b1p0_zvl64b1p0_zvl32b1p0_zvlsseg1p0_zve64d1p0_zve64f1p0_zve64x1p0_zve32f1p0_zve32x1p0
.
Hmmm...toolchain still need clarification, but before we got a formal clarification, I written down my understanding and my guess, and we gonna to implement that on toolchain.
zvl<x>b
impliedzvl<y>b
ifx
>y
, e.g.zvl256b
impliedzvl128b
,zvl64b
andzvl32b
.
v
impliedzvl128b
,Zve64*
impliedzvl64b
andZve32*
impliedzvl32b
.
v
withzvl32b
is valid combination but minimal VLEN still 128 due tov
impliedzvl128b
.
Zve64
withzvl32b
is valid combination but minimal VLEN still 64 due toZve64
impliedzvl64b
.
v
with anyzve*
extension is valid combination is valid, but still same asv
, e.g.v
+zve32x
=v
Different
Zve*
extension can be appear in arch string, but we only take the info from the biggest extension, e.g.
zve64x
+zve32x
=zve64x
zve64d
+zve32f
=zve64d
zve64d
+zve64f
=zve64d
require
means toolchain will report error and abort if the requirement not satisfied, e.g. toolchain will report error frrv32iv
rather than interpret that asrv32ifdv
Zvl*b
require eitherv
orzve*
extension, otherwise it's invalid arch, toolchain will report error.Addition rule for ELF attribute:
zvl*b
extension must present atTag_RISCV_arch
attribute ifv
orzve*
extension there.- Only emit largest
zvl*b
toTag_RISCV_arch
attribute, e.g.zvl256b
+zvl128b
, then we only emitzvl256
to attribute.- For
v
andzve*
, only emit biggest extension toTag_RISCV_arch
.
My understanding is the same, especially agree with that we only need to take the information from the biggest/largest zve/zvl extensions.
Oh forgot to mention that - the linker should have the same reduced architecture string for zve and zvl. For example, there are two objects, one has zve64x, and another has zve32x. If we link the two objects, then the output architecture string should only have zve64x, since zve32x is covered by it.
If the canonical form of Zfoo32b + Zfoo64b is Zfoo64b only then things don't work, because then you risk a kernel or run-time linker seeing it has Zfoo64b and not thinking that satisfies a Zfoo32b binary because it doesn't also see Zfoo32b, and you'd need to bake in extra logic to teach it about all those special cases.
The canonical (exploded) form for Zfoo32b + Zfoo64b should be Zfoo32b_Zfoo64b. Just as the canonical (exploded) form for F+D is FD. This is longer but things "just work"; having implicit extensions in the machine-processed arch strings just causes headaches. That's for the human-facing strings only.
Updated: Add one more item:
- Can
zvamo
andzvlsseg
use withoutV
,zve32*
orzve64*
?
Also add one more item to toolchain implementation note:
-
zvamo
andzvlsseg
require eitherv
orzve*
extension, otherwise it's invalid arch, toolchain will report error.
Also add one more item to toolchain implementation note:
zvamo
andzvlsseg
require eitherv
orzve*
extension, otherwise it's invalid arch, toolchain will report error.
According to the previous implementation and comments, https://github.com/riscv/riscv-binutils-gdb/pull/219
The zvamo and zvlsseg can be used without v, so I think v shouldn't be required to be specified for them.
The question here is does zvamo require v, or does it imply v. I think it is simpler if it requires v. Likewise with zvlsseg.
Hmmm...toolchain still need clarification, but before we got a formal clarification, I written down my understanding and my guess, and we gonna to implement that on toolchain.
zvl<x>b
impliedzvl<y>b
ifx
>y
, e.g.zvl256b
impliedzvl128b
,zvl64b
andzvl32b
.
v
impliedzvl128b
,Zve64*
impliedzvl64b
andZve32*
impliedzvl32b
.
v
withzvl32b
is valid combination but minimal VLEN still 128 due tov
impliedzvl128b
.
Zve64
withzvl32b
is valid combination but minimal VLEN still 64 due toZve64
impliedzvl64b
.
v
with anyzve*
extension is valid combination is valid, but still same asv
, e.g.v
+zve32x
=v
Different
Zve*
extension can be appear in arch string, but we only take the info from the biggest extension, e.g.
zve64x
+zve32x
=zve64x
zve64d
+zve32f
=zve64d
zve64d
+zve64f
=zve64d
require
means toolchain will report error and abort if the requirement not satisfied, e.g. toolchain will report error frrv32iv
rather than interpret that asrv32ifdv
I don't agree with it. Extension should be able to be specified stand alone. For example, users could specify rv64id without f. Why are we not able to specify v only? That means the only way to specify v is fdv.
Zvl*b
require eitherv
orzve*
extension, otherwise it's invalid arch, toolchain will report error.Addition rule for ELF attribute:
zvl*b
extension must present atTag_RISCV_arch
attribute ifv
orzve*
extension there.- Only emit largest
zvl*b
toTag_RISCV_arch
attribute, e.g.zvl256b
+zvl128b
, then we only emitzvl256
to attribute.- For
v
andzve*
, only emit biggest extension toTag_RISCV_arch
.
I don't agree with it. Extension should be able to be specified stand alone. For example, users could specify rv32id without f. Why are we not able to specify v only? That means the only way to specify v is fdv.
F
and D
extension are both floating point extension, one for single precision and one for double precision, which is highly related.
But for the case of vector operation, it's not obviously relationship between vector and floating point like single precision and double precision.
That behavior will result -march=rv64ifv
equal to -march=rv64ifdv
, rv64ifv
have no d
, that means user didn't want d
extension, but toolchain implied enabled d
because v
, in this case, user should either use zve64f
or explicitly enabled d
, both are possible expected behavior for user, but we never known which one is user's intention, just report error to let user explicitly choose the right way is better IMO.
My intention to prevent require those non-trivial and not obvious knowledge for toolchain user, just like we are trying to release the canonical order hell for the -march option.
@jrtc27
If the canonical form of Zfoo32b + Zfoo64b is Zfoo64b only then things don't work, because then you risk a kernel or run-time linker seeing it has Zfoo64b and not thinking that satisfies a Zfoo32b binary because it doesn't also see Zfoo32b, and you'd need to bake in extra logic to teach it about all those special cases.
The canonical (exploded) form for Zfoo32b + Zfoo64b should be Zfoo32b_Zfoo64b. Just as the canonical (exploded) form for F+D is FD. This is longer but things "just work"; having implicit extensions in the machine-processed arch strings just causes headaches. That's for the human-facing strings only.
My intention was want to reduce the size of Tag_RISCV_arch, but after I write down a arch string with all ratified ext. with crypto, vector and bitmanip, it seems reduce size seems not so useful - it's still long but introduce too many rule need to handle, so I think let keep full expanded version to keep the rule simple.
Full expanded version: "rv64i2p1_m2p0_a2p0_f2p0_d2p0_c2p0_v1p0_zicsr2p0_zifencei2p0_zba1p0_zbb1p0_zbc1p0_zvl128b1p0_zvl64b1p0_zvl32b1p0_zvlsseg1p0_zve64d_zve64f_zve64x_zve32f_zve32x_zbkb1p0_zbkc1p0_zbkx1p0_zknd1p0_zkne1p0_zknh1p0_zksed1p0_zksh1p0_zkr1p0_zkm1p0_zks1p0_zk1p0_zkt1p0"
Reduced version: "rv64i2p1_m2p0_a2p0_f2p0_d2p0_c2p0_v1p0_zicsr2p0_zifencei2p0_zba1p0_zbb1p0_zbc1p0_zvl128b1p0_zvlsseg1p0_zkn1p0_zkn1p0_zks1p0"
@kito-cheng
Can zvamo and zvlsseg use without V, zve32* or zve64*?
I don't see Zvamo mentioned anywhere in the v1.0-rc1 spec. I don't think we need to support it.
I don't know what to say about "standalone Zvlsseg". I can't imagine that is an intended design point.
On a related note, I think the spec should just drop the Zvlsseg ISA string: I see no need to standardize a name for this subset. It certainly made sense when it was optional, but nowadays it is included in all the standard extensions. However, I've suggested this multiple times to the task group and it's never been changed, so I suppose its persistence is intentional.
@kito-cheng
Can zvamo and zvlsseg use without V, zve32* or zve64*?
I don't see Zvamo mentioned anywhere in the v1.0-rc1 spec. I don't think we need to support it.
@nick-knight
I don't know what to say about "standalone Zvlsseg". I can't imagine that is an intended design point.
On a related note, I think the spec should just drop the Zvlsseg ISA string: I see no need to standardize a name for this subset. It certainly made sense when it was optional, but nowadays it is included in all the standard extensions. However, I've suggested this multiple times to the task group and it's never been changed, so I suppose its persistence is intentional.
Oh, thanks for point out that, that actually give me wrong impression is: Zvlsseg is a standalone subset...
Read the spec again, zve* and v both has this sentence, so yes, that should be gone on the toolchain side since all extension are support...
The V extension supports all vector load and store instructions (Section Vector Loads and Stores), except the V extension does not support EEW=64 for index values when XLEN=32.
I don't agree with it. Extension should be able to be specified stand alone. For example, users could specify rv32id without f. Why are we not able to specify v only? That means the only way to specify v is fdv.
F
andD
extension are both floating point extension, one for single precision and one for double precision, which is highly related.But for the case of vector operation, it's not obviously relationship between vector and floating point like single precision and double precision.
That behavior will result
-march=rv64ifv
equal to-march=rv64ifdv
,rv64ifv
have nod
, that means user didn't wantd
extension, but toolchain implied enabledd
becausev
, in this case, user should either usezve64f
or explicitly enabledd
, both are possible expected behavior for user, but we never known which one is user's intention, just report error to let user explicitly choose the right way is better IMO.
The worry is based on the assumption that v implies f and d. What if v does not imply f and d in the tool implementation? Users will specify what users want explicitly and there is no confusion. So,
If users only use integer vector operations, they could specify rv64iv without error messages. If users use single-floating point vector operations, they will specify rv64ifv without error messages. If users use double-floating point vector operations, they will specify rv64idv without error messages.
To enforce users to specify fdv for vector extension, it causes confusion from users' perspective, especially when users only use integer vector operations and see the error messages for rv64iv.
I think arch string is already complex. We have no need to add additional rules on it.
My intention to prevent require those non-trivial and not obvious knowledge for toolchain user, just like we are trying to release the canonical order hell for the -march option.
In 1.0, I think users should use rv64i_zve*x
if they only want to use integer vector operation.
I guess it's why the requirement The V extension requires the scalar processor to implement the F and D extensions, and implements all vector floating-point instructions
and Zve*x
are in the same commit https://github.com/riscv/riscv-v-spec/commit/808a6f83b72d92757ef4c93fcdf076ed99bbecae.
There is already considerable momentum in this regard. Table 27.1 in Vol. 1 defines an "implies" relation on various extensions, for example, Q => D => F => Zicsr. In this case we might add V => D.
I note that toolchains implement a superset of this relation. For example, Clang/LLVM happily assembles this:
void foo(void) { asm ("csrrs x1, 17, x0"); }
with -march=rv32i
, despite csrrs
being part of the Zicsr extension [godbolt link].
EDIT: the toolchain folks have informed us below that this behavior is due to a backwards-incompatible change between i2p0 and i2p1 which is still being addressed.
@nick-knight the fact is LLVM still implement i ext 2.0, which base extension still include zicsr
and zifencei
, you can try -march=rv32i_zcisr
for clang, that result unsupported standard user-level extension 'zcisr'
, split zicsr
and zifencei
from baseline ISA is really annoying backward incompatible change...
For GNU toolchain, @Nelson1225 and me has implement that on upstream for a while, which included in GCC 11, but that not available on https://godbolt.org/ :(
There is already considerable momentum in this regard. Table 27.1 in Vol. 1 defines an "implies" relation on various extensions, for example, Q => D => F => Zicsr. In this case we might add V => D.
Yeah, but I am prefer to make sure this write down to the implies
column, before that I treat require
and implies
are different.
Changes:
2021/9/8: Update note for ELF attribute. Hmmm...toolchain still need clarification, but before we got a formal clarification, I written down my understanding and my guess, and we gonna to implement that on toolchain.
zvl<x>b
impliedzvl<y>b
ifx
>y
, e.g.zvl256b
impliedzvl128b
,zvl64b
andzvl32b
.
v
impliedzvl128b
,Zve64*
impliedzvl64b
andZve32*
impliedzvl32b
.
v
withzvl32b
is valid combination but minimal VLEN still 128 due tov
impliedzvl128b
.
Zve64
withzvl32b
is valid combination but minimal VLEN still 64 due toZve64
impliedzvl64b
.
v
with anyzve*
extension is valid combination is valid, but still same asv
, e.g.v
+zve32x
=v
Different
Zve*
extension can be appear in arch string, but we only take the info from the biggest extension, e.g.
zve64x
+zve32x
=zve64x
zve64d
+zve32f
=zve64d
A question about the rule. Why not emit an error message for the case. You do not know what the users want if they specify both zve* extensions in the arch string. I think the situation is similar to rv64if_zve64d
or rv64id_zve64f
. I agree we should expand it in the ELF attributes, but for human-facing string, should we restrict users to only specify v or one of zve* extensions?
zve64d
+zve64f
=zve64d
require
means toolchain will report error and abort if the requirement not satisfied, e.g. toolchain will report error forrv32iv
rather than interpret that asrv32ifdv
Zvl*b
require eitherv
orzve*
extension, otherwise it's invalid arch, toolchain will report error.Note for ELF attribute:
Tag_RISCV_arch
always emit fully expanded form, e.g.v
will expand tov1p0_zvl128b1p0_zvl64b1p0_zvl32b1p0_zvlsseg1p0_zve64d1p0_zve64f1p0_zve64x1p0_zve32f1p0_zve32x1p0
.
General rule is that extension names imply the things they require, and we take union of all implied features. This simplifies model when string is built up in pieces in different places, with multiple repeated additions of same extension. After vector spec isout, plan to revisit the naming chapter to clear this up.
RISC-V specs use the verb "depend" to describe the relationship between e.g. D and F. The Naming chapter makes it clear that dependence relationships can be used to shorten ISA strings: https://github.com/riscv/riscv-isa-manual/blob/399c9a759eb4540a65c60e2cc236164821ff2346/src/naming.tex#L46
This thread demonstrates that using the alternate verb "require" is causing confusion, so I've fixed the spec to use the standard verb. e8594a7b9f4c22d3c02e2cdf81ad5db8d0bb8c01 and 6fedb869e213da03f36092d661d14911a2f9d2c6
Did anyone try to estimate the number of different combinations that require separate libraries in the embedded toolchain?
In the latest release, the xPack GNU RISC-V Embedded GCC supports roughly 100 libraries and the compressed archive has more than 500 MB.