cmd/internal/obj/riscv: reject invalid vadc/vsbc encodings

The RISC-V Instruction Set Manual Volume states that "for vadc and
vsbc, the instruction encoding is reserved if the destination vector
register is v0". The assembler currently allows instructions like

VADCVVM	V1, V2, V0, V0

to be assembled. It's not clear what the behaviour of such
instructions will be on target hardware so it's best to disallow
them.

For reference, binutils (2.44-3.fc42) allows the instruction

vadc.vvm v0, v4, v8, v0

to be assembled and the instruction actually executes on a Banana PI
F3 without crashing. However, clang (20.1.2) refuses to assemble the
instruction, producing the following error.

error: the destination vector register group cannot be V0
        vadc.vvm v0, v4, v8, v0
                 ^
Change-Id: Ia913cbd864ae8dbcf9227f69b963c93a99481cff
Reviewed-on: https://go-review.googlesource.com/c/go/+/669315
Reviewed-by: Carlos Amedee <carlos@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Joel Sing <joel@sing.id.au>
This commit is contained in:
Mark Ryan 2025-05-01 10:43:32 +02:00
parent 5a1f47a7f7
commit d000963d04
3 changed files with 22 additions and 2 deletions

View File

@ -623,17 +623,27 @@ start:
VADCVXM X11, V2, V0, V3 // d7c12540
VADCVIM $15, V2, V0, V3 // d7b12740
VMADCVVM V1, V2, V0, V3 // d7812044
VMADCVVM V1, V2, V0, V0 // 57802044
VMADCVXM X11, V2, V0, V3 // d7c12544
VMADCVXM X11, V2, V0, V0 // 57c02544
VMADCVIM $15, V2, V0, V3 // d7b12744
VMADCVIM $15, V2, V0, V0 // 57b02744
VMADCVV V1, V2, V3 // d7812046
VMADCVV V1, V2, V0 // 57802046
VMADCVX X11, V2, V3 // d7c12546
VMADCVX X11, V2, V0 // 57c02546
VMADCVI $15, V2, V3 // d7b12746
VMADCVI $15, V2, V0 // 57b02746
VSBCVVM V1, V2, V0, V3 // d7812048
VSBCVXM X11, V2, V0, V3 // d7c12548
VMSBCVVM V1, V2, V0, V3 // d781204c
VMSBCVVM V1, V2, V0, V0 // 5780204c
VMSBCVXM X11, V2, V0, V3 // d7c1254c
VMSBCVXM X11, V2, V0, V0 // 57c0254c
VMSBCVV V1, V2, V3 // d781204e
VMSBCVV V1, V2, V0 // 5780204e
VMSBCVX X11, V2, V3 // d7c1254e
VMSBCVX X11, V2, V0 // 57c0254e
// 31.11.5: Vector Bitwise Logical Instructions
VANDVV V1, V2, V3 // d7812026

View File

@ -95,10 +95,13 @@ TEXT errors(SB),$0
VSEXTVF8 V2, V3, V4 // ERROR "invalid vector mask register"
VADCVVM V1, V2, V4, V3 // ERROR "invalid vector mask register"
VADCVVM V1, V2, V3 // ERROR "invalid vector mask register"
VADCVVM V1, V2, V0, V0 // ERROR "invalid destination register V0"
VADCVXM X10, V2, V4, V3 // ERROR "invalid vector mask register"
VADCVXM X10, V2, V3 // ERROR "invalid vector mask register"
VADCVXM X10, V2, V0, V0 // ERROR "invalid destination register V0"
VADCVIM $15, V2, V1, V3 // ERROR "invalid vector mask register"
VADCVIM $15, V2, V3 // ERROR "invalid vector mask register"
VADCVIM $15, V2, V0, V0 // ERROR "invalid destination register V0"
VMADCVVM V1, V2, V4, V3 // ERROR "invalid vector mask register"
VMADCVVM V1, V2, V3 // ERROR "invalid vector mask register"
VMADCVXM X10, V2, V4, V3 // ERROR "invalid vector mask register"
@ -107,8 +110,10 @@ TEXT errors(SB),$0
VMADCVIM $15, V2, V3 // ERROR "invalid vector mask register"
VSBCVVM V1, V2, V4, V3 // ERROR "invalid vector mask register"
VSBCVVM V1, V2, V3 // ERROR "invalid vector mask register"
VSBCVVM V1, V2, V0, V0 // ERROR "invalid destination register V0"
VSBCVXM X10, V2, V4, V3 // ERROR "invalid vector mask register"
VSBCVXM X10, V2, V3 // ERROR "invalid vector mask register"
VSBCVXM X10, V2, V0, V0 // ERROR "invalid destination register V0"
VMSBCVVM V1, V2, V4, V3 // ERROR "invalid vector mask register"
VMSBCVVM V1, V2, V3 // ERROR "invalid vector mask register"
VMSBCVXM X10, V2, V4, V3 // ERROR "invalid vector mask register"

View File

@ -3773,8 +3773,13 @@ func instructionsForProg(p *obj.Prog) []*instruction {
ins.funct7 |= 1 // unmasked
ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), REG_V0
case AVADCVVM, AVADCVXM, AVMADCVVM, AVMADCVXM, AVSBCVVM, AVSBCVXM, AVMSBCVVM, AVMSBCVXM, AVADCVIM, AVMADCVIM,
AVMERGEVVM, AVMERGEVXM, AVMERGEVIM, AVFMERGEVFM:
case AVADCVIM, AVADCVVM, AVADCVXM, AVSBCVVM, AVSBCVXM:
if ins.rd == REG_V0 {
p.Ctxt.Diag("%v: invalid destination register V0", p)
}
fallthrough
case AVMADCVVM, AVMADCVXM, AVMSBCVVM, AVMSBCVXM, AVMADCVIM, AVMERGEVVM, AVMERGEVXM, AVMERGEVIM, AVFMERGEVFM:
if ins.rs3 != REG_V0 {
p.Ctxt.Diag("%v: invalid vector mask register", p)
}