Advanced SIMD, the floating-point extensions, SVE, SVE2 and the cryptographic extensions are separate architectural extensions that share one instruction encoding space and one set of registers. [QUOTED] (ARM DDI 0602 for the SVE half; DDI 0487 for the Advanced SIMD half; the FEAT definitions in the Arm Architecture Reference Manual's appendix.)
The register sharing is the load-bearing part and it is what the shared-resource rule means: an implementation that has SVE also has Advanced SIMD, on the same physical registers, and SVE's Z0's bottom 128 bits are Advanced SIMD's V0. One file register, two views, and the second view is wider.
Now the consequence, and it is measurable in one command. If the encoding had to say how wide a vector is, it would need a field, and that field would have to be as wide as the widest vector any implementation might have. SVE's vector length is at most 2048 bits, so a length field would be four bits and every instruction would pay for it. So SVE does not have one, and the space it shares is what makes that affordable.
This is the page where a reader who came from a fixed-width SIMD model has to unlearn something. Advanced SIMD must spend a bit on 128 bits because Advanced SIMD vectors are 128 bits. SVE does not spend a bit, because the width is a property of the implementation and is read at run time from the vector length register rather than from the instruction. [QUOTED]
$ for b in 128 256 512 1024 2048; do
> clang --target=aarch64-linux-gnu -march=armv8.2-a+sve \
> -msve-vector-bits=$b -S -x assembler - -o /dev/null <<EOF
> .text
> add z0.d, p0/m, z0.d, z1.d
> EOF
done
-msve-vector-bits the same instruction assembles to
------------------ ----------------------------------------
128 bits 0x04c00020
256 bits 0x04c00020
512 bits 0x04c00020
1024 bits 0x04c00020
2048 bits 0x04c00020
[MEASURED-ON-BYTES] 5 of 5 are the SAME WORD, from 128 bits to
2048 bits -- a factor of SIXTEEN in vector length and NOT ONE BIT
of difference. That is the whole claim, and it takes one command.
Same instruction, five vector lengths, one word. A factor of sixteen in vector length and not one bit of difference. If you have been reading a manual for a field map, this is the moment to notice that the field you were looking for is not missing from this page's diagram — it is not in the architecture.
[MEASURED] the field the size DOES live in, for SVE:
size = 0 (element 8 bits) 0x04000000 xor 0x00c00020
size = 1 (element 16 bits) 0x04400000 xor 0x00800020
size = 2 (element 32 bits) 0x04800000 xor 0x00400020
size = 3 (element 64 bits) 0x04c00000 xor 0x00000020
TWO bits at bits[23:22] carry all four element sizes and there
is no fourth bit anywhere for the vector LENGTH.
[MEASURED-ON-BYTES] and the operation is a SIX-BIT field, twelve
handlers, one assemble each:
add 0x04c00020 op[21:16] = 000000 class = 00000100
sub 0x04c10020 op[21:16] = 000001 class = 00000100
umax 0x04c90020 op[21:16] = 001001 class = 00000100
smin 0x04ca0020 op[21:16] = 001010 class = 00000100
umin 0x04cb0020 op[21:16] = 001011 class = 00000100
mul 0x04d00020 op[21:16] = 010000 class = 00000100
sdiv 0x04d40020 op[21:16] = 010100 class = 00000100
udiv 0x04d50020 op[21:16] = 010101 class = 00000100
orr 0x04d80020 op[21:16] = 011000 class = 00000100
eor 0x04d90020 op[21:16] = 011001 class = 00000100
and 0x04da0020 op[21:16] = 011010 class = 00000100
bic 0x04db0020 op[21:16] = 011011 class = 00000100
Compare that with concept 1's arithmetic groups. There the width was a suffix and a Q bit; here the width is two bits at bits[23:22] and the operation is six bits at bits[21:16] — the same size field, immediately next to a name table twelve entries long. A decoder with one "size" constant gets concept 1 right and this page right and still has no idea why, because they are different fields that happen to agree.
[MEASURED-ON-BYTES] and the two register files SVE adds, swept:
z0 0x04c00000 xor 0x00000020
z1 0x04c00020 xor 0x00000000
z15 0x04c001e0 xor 0x000001c0
z31 0x04c003e0 xor 0x000003c0
Z0 through Z31 -- five bits, the same width as a scalar
register field and the same width as an Advanced SIMD V
field, and NOTHING else in the word for how wide those
registers are.
[MEASURED] and the restriction the assembler adds that the field
does not: the SVE predicates are FOUR bits wide in the encoding
whilelo p0.d 0x25e11c00 xor 0x00000000
whilelo p1.d 0x25e11c01 xor 0x00000001
whilelo p2.d 0x25e11c02 xor 0x00000002
whilelo p3.d 0x25e11c03 xor 0x00000003
whilelo p4.d 0x25e11c04 xor 0x00000004
add z0.d, p8/m -> invalid restricted predicate register, expected p0..p7
so bits[3:0] address SIXTEEN predicates and the arithmetic
form may use only p0..p7 -- a restriction the ENCODING does not
express and only the assembler enforces.
Thirty-two Z registers in five bits. Sixteen predicates in four bits — and the arithmetic form may use only eight of them. An enforcement the encoding does not express is a rule with no bytes behind it. That last sentence generalises: the assembler is the only enforcement point for a large fraction of what the manual calls "reserved", and a rule enforced only by an assembler is a rule a second assembler is free to get wrong.
And the destination is also the second source. [MEASURED] The assembler refuses add z0.d, p0/m, z1.d, z1.d, so there are only three register fields here — bits[4:0], bits[9:5] and the predicate at bits[12:10] — and the second reader prints the destination twice. A decoder that "fixes" the repeated operand names a register the word does not contain.
It cannot show that a 2048-bit vector actually has 2048 bits, or that Z0's bottom 128 bits are V0, or that any SVE instruction runs. The claim "the length is not in the instruction" is MEASURED; the claim "the length is therefore correct at run time" is QUOTED and needs silicon. That is a one-line argument and it is the whole course in miniature.
It cannot show which extensions an implementation has. The feature registers are readable only at EL1 and there is no EL1 here. The class field is shared whether or not every member of the space is present — which is the definition of a shared space and also the reason the decode is a function of the CPU.
family word binary class field
------------------------ ----------- ------------------------------------ ----------------
Advanced SIMD, 128-bit 0x4ea28420 01001110101000101000010000100000 bits[28:25] = 0111
Advanced SIMD, 64-bit 0x0ea28420 00001110101000101000010000100000 bits[28:25] = 0111
SVE, .d 0x04c00020 00000100110000000000000000100000 bits[28:25] = 0010
SVE, .s 0x04800020 00000100100000000000000000100000 bits[28:25] = 0010
SVE, .h 0x04400020 00000100010000000000000000100000 bits[28:25] = 0010
SVE, .b 0x04000020 00000100000000000000000000100000 bits[28:25] = 0010
FP scalar, .d 0x1e622820 00011110011000100010100000100000 bits[28:25] = 1111
AES (FEAT_AES) REFUSED instruction requires: aes bits[28:25] = ?
SHA-256 (FEAT_SHA2) REFUSED instruction requires: sha2 bits[28:25] = ?
SVE predicate 0x25e11c00 00100101111000010001110000000000 bits[28:25] = 0010
SVE load 0xa5e0a000 10100101111000001010000000000000 bits[28:25] = 0010
SVE store 0xe5e0e000 11100101111000001110000000000000 bits[28:25] = 0010
[MEASURED-ON-BYTES] the class field bits[28:25] is 0b0111 for the
Advanced SIMD data-processing group, the FP groups, AES and SHA-2,
and 0b0010 for the SVE data-processing group -- so four extensions
and two architectures share the space by sharing a class.
So sharing is done by sharing a class: 0b0111 for the Advanced SIMD / FP / AES / SHA-2 families, 0b0010 for the SVE data-processing group. That is the cheap way to do it and it is exactly why a decoder needs to know the CPU.
The other half of a shared space is an assembler that does not have every member of it. And when it says so, it says so by name — and the name is architecture rather than assembler:
aese v0.16b, v1.16b at baseline -> "instruction requires: aes"
ldapr w1, [x0] at 8.1-a -> "instruction requires: rcpc"
ldapr w1, [x0] at 8.3-a -> accepted, 0xdac0dc01
cas w1, w2, [x0] at baseline -> "instruction requires: lse"
fadd h0, h1, h2 at baseline -> "instruction requires: fullfp16"
Five refusals, five feature names, and the whole feature-gating story of the architecture in five lines of diagnostic. Note the middle one: ldapr is refused at armv8.1-a and accepted at armv8.3-a, so FEAT_RCPC is armv8.3-a and not armv8.1-a — a fact you would otherwise have to look up, obtained here by moving one flag.
And note what the refusals are not:
This course got that wrong twice and retracted it twice. casp was reported as unencodable because the three-operand form is a spelling rule, and stlxp x14, x9, x8 was reported as unencodable because the status register is always w. Both were refusals that pointed at an operand that was right — which is the most believable kind of diagnostic there is.
z1.d for z2.d — and watch the same sweep produce five different words. The absence is not a property of the sweep; it is a property of the field.)whilelo p0.d … whilelo p15.d all assemble. add z0.d, p8/m, … does not. (Expect the diagnostic to name a restriction the encoding does not express: "invalid restricted predicate register, expected p0..p7". Four bits address sixteen predicates and the arithmetic form may use eight of them, and the only thing enforcing that is the assembler.)0x4ea28420 (Advanced SIMD) and 0x04c00020 (SVE) and XOR them. (Expect the difference to be exactly the class field plus the size field. Now find the smallest single-bit edit of 0x04c00020 that makes the second reader print something from a different family — that is the boundary, and it is a bit, and a decoder that does not check the class will happily name the wrong family.)Backwards. Thirty-Two Registers is the direct parent: the "same four sizes in four groups" table on that page ends with sve size having no Q bit at all, and this page is the measurement behind that row. The machine course's register concept is where the shared physical file was established for the scalar case; SVE is the same sharing one level up, and the register-counting question ("how many vector registers does this core have?") is unanswerable in the same way for both.
Forwards. The exclusive monitor is where the same class-field idea becomes a correctness problem rather than a decoding one: a 128-bit atomic has to name two consecutive register pairs in a 32-bit instruction, and concept 3 measures what the assembler does with that. Decode the data path is where this page's SVE model is checked by a second reader, and where the mnemonic table above is asserted entry by entry.
Outward, and this is the page's real subject: an encoding that omits a field is making a claim about where the information lives. That is a much rarer design decision than a field position, and it is worth reading the whole collection for the two halves of it. Concept 1 measured a field at bit 23 when the reader expected bit 30. This page measured the absence of a field and the absence turned out to be the design. And in the x86-64 SIMD course the same question has a different answer again, because EVEX encodes a vector length that VEX did not, for exactly the reason SVE omits one — the register file grew and the old prefix stopped being able to say what it meant.
Which is the connection to carry out of the section. Where an encoding puts a field, and where it refuses to, is the clearest statement an architecture makes about what it thinks is constant. Advanced SIMD thinks 128 bits is constant and spends a bit. SVE thinks nothing about a vector is constant and spends zero bits, and reads one register instead. Neither is more modern than the other; one of them is right for its register file.