feat(asm): encode the riscv64 vector arithmetic families
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
5de9e985f8
commit
778c297214
3 files changed
+1812
-102
No files matched your search
+564
-81
@@ -3636,88 +3636,571 @@ func encodeRISCVVector(mnem string, ops []*ast.Operand) ([]byte, bool, error) {
|
||||
// (0xcd07f657) from GOARCH=riscv64 go tool asm.
|
||||
ivli := mnem == "VSETIVLI" || isImmOperand(ops[0])
|
||||
return wordLE(riscvVSetEnc(ivli, avl, riscvVType(vsew, vlmul, vta, vma), rd)), true, nil
|
||||
|
||||
case "VADDVV", "VXORVV", "VMSNEVV":
|
||||
// Vector-vector: INSTR vs1, vs2, vd.
|
||||
if len(ops) != 3 {
|
||||
return nil, true, fmt.Errorf("%s expects 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
vs1, vs2, vd := reg(ops[0]), reg(ops[1]), reg(ops[2])
|
||||
if vs1 < 0 || vs2 < 0 || vd < 0 {
|
||||
return nil, true, fmt.Errorf("%s: invalid vector register", mnem)
|
||||
}
|
||||
funct6 := map[string]int{"VADDVV": 0x00, "VXORVV": 0x0B, "VMSNEVV": 0x19}[mnem]
|
||||
return wordLE(riscvVVInstr(funct6, riscvVf3VV, int32(vs1), vs2, vd)), true, nil
|
||||
|
||||
case "VADDVX", "VMSEQVX":
|
||||
// Vector-scalar: INSTR rs1, vs2, vd (the scalar in the rs1 field).
|
||||
if len(ops) != 3 {
|
||||
return nil, true, fmt.Errorf("%s expects 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
rs1, vs2, vd := reg(ops[0]), reg(ops[1]), reg(ops[2])
|
||||
if rs1 < 0 || vs2 < 0 || vd < 0 {
|
||||
return nil, true, fmt.Errorf("%s: invalid register operand", mnem)
|
||||
}
|
||||
funct6 := 0x00
|
||||
if mnem == "VMSEQVX" {
|
||||
funct6 = 0x18
|
||||
}
|
||||
return wordLE(riscvVVInstr(funct6, riscvVf3VX, int32(rs1), vs2, vd)), true, nil
|
||||
|
||||
case "VSLLVI", "VSRLVI":
|
||||
// Vector-immediate shift: INSTR $uimm, vs2, vd.
|
||||
if len(ops) != 3 {
|
||||
return nil, true, fmt.Errorf("%s expects 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
imm := int(immFromOperand(ops[0]))
|
||||
if imm < 0 || imm > 31 {
|
||||
return nil, true, fmt.Errorf("%s: immediate out of range [0, 31]", mnem)
|
||||
}
|
||||
vs2, vd := reg(ops[1]), reg(ops[2])
|
||||
if vs2 < 0 || vd < 0 {
|
||||
return nil, true, fmt.Errorf("%s: invalid vector register", mnem)
|
||||
}
|
||||
funct6 := 0x25 // vsll.vi
|
||||
if mnem == "VSRLVI" {
|
||||
funct6 = 0x28 // vsrl.vi
|
||||
}
|
||||
return wordLE(riscvVVInstr(funct6, riscvVf3VI, int32(imm), vs2, vd)), true, nil
|
||||
|
||||
case "VFIRSTM":
|
||||
// vmfirst.m rd, vs2: the unmasked form carries 0x11 in the rs1 field
|
||||
// and sets the mask bit (funct7 = 0x20 | 1).
|
||||
if len(ops) != 2 {
|
||||
return nil, true, fmt.Errorf("VFIRSTM expects 2 operands, got %d", len(ops))
|
||||
}
|
||||
vs2, rd := reg(ops[0]), reg(ops[1])
|
||||
if vs2 < 0 || rd < 0 {
|
||||
return nil, true, fmt.Errorf("VFIRSTM: invalid register operand")
|
||||
}
|
||||
return wordLE(riscvVUnaryInstr(0x10, riscvVf3MV, 0x11, vs2, rd)), true, nil
|
||||
|
||||
case "VIDV":
|
||||
// vid.v vd (vs2 must be v0; the unmasked form sets the mask bit).
|
||||
if len(ops) != 1 {
|
||||
return nil, true, fmt.Errorf("VIDV expects 1 operand, got %d", len(ops))
|
||||
}
|
||||
vd := reg(ops[0])
|
||||
if vd < 0 {
|
||||
return nil, true, fmt.Errorf("VIDV: invalid vector register")
|
||||
}
|
||||
return wordLE(riscvVUnaryInstr(0x14, riscvVf3MV, 0x11, 0, vd)), true, nil
|
||||
|
||||
case "VMV4RV":
|
||||
// vmv4r.v vd, vs2: whole-register group move.
|
||||
if len(ops) != 2 {
|
||||
return nil, true, fmt.Errorf("VMV4RV expects 2 operands, got %d", len(ops))
|
||||
}
|
||||
vs2, vd := reg(ops[0]), reg(ops[1])
|
||||
if vs2 < 0 || vd < 0 {
|
||||
return nil, true, fmt.Errorf("VMV4RV: invalid vector register")
|
||||
}
|
||||
return wordLE(riscvVUnaryInstr(0x27, 0x3, 0x3, vs2, vd)), true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
// Every remaining OP-V mnemonic the toolchain knows: the arithmetic
|
||||
// table, dispatched by operand class.
|
||||
return encodeRISCVVecOp(mnem, ops)
|
||||
}
|
||||
|
||||
// encodeRISCVVecOp encodes one vector arithmetic instruction through the
|
||||
// extracted table. The entry's class places the operands in the rs1 and vs2
|
||||
// fields, an optional V0 between the sources and the destination clears the
|
||||
// vm bit, and the transform classes rewrite the pseudo forms the toolchain
|
||||
// expands before encoding (the swapped comparisons, VNEGV and friends).
|
||||
func encodeRISCVVecOp(mnem string, ops []*ast.Operand) ([]byte, bool, error) {
|
||||
op, ok := riscvVecOps[mnem]
|
||||
if !ok {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// vecReg reads a register operand; what names the field in the error.
|
||||
vecReg := func(o *ast.Operand, what string) (int, error) {
|
||||
r := regFromOperand(o)
|
||||
if r < 0 {
|
||||
return 0, fmt.Errorf("%s: invalid %s", mnem, what)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
// vecImm reads the immediate the entry's form bounds: signed five bits
|
||||
// [-16, 15], or unsigned [0, 31] for the shifts and slides.
|
||||
vecImm := func(o *ast.Operand) (int32, error) {
|
||||
if !isImmOperand(o) {
|
||||
return 0, fmt.Errorf("%s expects an immediate first operand", mnem)
|
||||
}
|
||||
v := immFromOperand(o)
|
||||
if op.immU {
|
||||
if v < 0 || v > 31 {
|
||||
return 0, fmt.Errorf("%s: immediate %d out of range [0, 31]", mnem, v)
|
||||
}
|
||||
} else if v < -16 || v > 15 {
|
||||
return 0, fmt.Errorf("%s: immediate %d out of range [-16, 15]", mnem, v)
|
||||
}
|
||||
return int32(v), nil
|
||||
}
|
||||
// vecMask reads the optional mask operand: only V0 is lawful.
|
||||
vecMask := func(o *ast.Operand) error {
|
||||
if regFromOperand(o) != 0 {
|
||||
return fmt.Errorf("%s: the vector mask register must be V0", mnem)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// vm carries the funct7 with the vm bit set for the unmasked form: the
|
||||
// toolchain ORs 1 when no V0 follows the sources.
|
||||
vm := func(masked bool) uint32 {
|
||||
if !masked {
|
||||
return op.funct7 | 1
|
||||
}
|
||||
return op.funct7
|
||||
}
|
||||
// word builds the instruction from the entry's fields.
|
||||
word := func(funct7 uint32, rs1Field int32, vs2 int, funct3 uint32, vd int) ([]byte, bool, error) {
|
||||
return wordLE(riscvVecWord(funct7, rs1Field, vs2, funct3, vd)), true, nil
|
||||
}
|
||||
// rename resolves a transform to its target table entry.
|
||||
rename := func(to string) (riscvVecOp, error) {
|
||||
t, ok := riscvVecOps[to]
|
||||
if !ok {
|
||||
return riscvVecOp{}, fmt.Errorf("%s: transform target %q not in the table", mnem, to)
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
switch op.class {
|
||||
case vecVV:
|
||||
// INSTR vs1|$imm, vs2 [, V0], vd.
|
||||
if len(ops) != 3 && len(ops) != 4 {
|
||||
return nil, true, fmt.Errorf("%s expects 3 or 4 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 4
|
||||
if masked {
|
||||
if err := vecMask(ops[2]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
vs2, err := vecReg(ops[1], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
var rs1Field int32
|
||||
if op.imm {
|
||||
if rs1Field, err = vecImm(ops[0]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
} else {
|
||||
var vs1 int
|
||||
if vs1, err = vecReg(ops[0], "vs1"); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
rs1Field = int32(vs1)
|
||||
}
|
||||
return word(vm(masked), rs1Field, vs2, op.funct3, vd)
|
||||
|
||||
case vecMACC:
|
||||
// INSTR vs2, vs1 [, V0], vd: the multiply-accumulate order, the
|
||||
// addend in the rs1 field and the multiplicand in vs2.
|
||||
if len(ops) != 3 && len(ops) != 4 {
|
||||
return nil, true, fmt.Errorf("%s expects 3 or 4 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 4
|
||||
if masked {
|
||||
if err := vecMask(ops[2]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
vs2, err := vecReg(ops[0], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
var rs1Field int32
|
||||
if op.imm {
|
||||
if rs1Field, err = vecImm(ops[1]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
} else {
|
||||
var vs1 int
|
||||
if vs1, err = vecReg(ops[1], "vs1"); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
rs1Field = int32(vs1)
|
||||
}
|
||||
return word(vm(masked), rs1Field, vs2, op.funct3, vd)
|
||||
|
||||
case vecSWAPVV:
|
||||
// VMSGT*/VMSGE*/VMFGT*/VMFGE* swap the two sources and lower to the
|
||||
// VMSLT*/VMSLE*/VMFLT*/VMFLE* entries the table carries.
|
||||
if len(ops) != 3 && len(ops) != 4 {
|
||||
return nil, true, fmt.Errorf("%s expects 3 or 4 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 4
|
||||
if masked {
|
||||
if err := vecMask(ops[2]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
t, err := rename(map[string]string{
|
||||
"VMSGTVV": "VMSLTVV", "VMSGTUVV": "VMSLTUVV",
|
||||
"VMSGEVV": "VMSLEVV", "VMSGEUVV": "VMSLEUVV",
|
||||
"VMFGTVV": "VMFLTVV", "VMFGEVV": "VMFLEVV",
|
||||
}[mnem])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vs2, err := vecReg(ops[0], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vs1, err := vecReg(ops[1], "vs1")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
f7 := t.funct7
|
||||
if !masked {
|
||||
f7 |= 1
|
||||
}
|
||||
return word(f7, int32(vs1), vs2, t.funct3, vd)
|
||||
|
||||
case vecSWAPVI:
|
||||
// VMSLTVI and the VMSGE*VI forms subtract one from the immediate and
|
||||
// lower to the VMSLE*/VMSGT* entries.
|
||||
if len(ops) != 3 && len(ops) != 4 {
|
||||
return nil, true, fmt.Errorf("%s expects 3 or 4 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 4
|
||||
if masked {
|
||||
if err := vecMask(ops[2]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
t, err := rename(map[string]string{
|
||||
"VMSLTVI": "VMSLEVI", "VMSLTUVI": "VMSLEUVI",
|
||||
"VMSGEVI": "VMSGTVI", "VMSGEUVI": "VMSGTUVI",
|
||||
}[mnem])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
imm, err := vecImm(ops[0])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
imm--
|
||||
if imm < -16 || imm > 15 {
|
||||
return nil, true, fmt.Errorf("%s: immediate %d leaves [-16, 15] after the swap", mnem, imm+1)
|
||||
}
|
||||
vs2, err := vecReg(ops[1], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
f7 := t.funct7
|
||||
if !masked {
|
||||
f7 |= 1
|
||||
}
|
||||
return word(f7, imm, vs2, t.funct3, vd)
|
||||
|
||||
case vecUNARY, vecM2I:
|
||||
// INSTR vs2 [, V0], vd: one vector source, the fixed rs1 field; the
|
||||
// m2i members take the destination in the integer file.
|
||||
if len(ops) != 2 && len(ops) != 3 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 or 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 3
|
||||
if masked {
|
||||
if err := vecMask(ops[1]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
vs2, err := vecReg(ops[0], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(vm(masked), int32(op.rs1), vs2, op.funct3, vd)
|
||||
|
||||
case vecNEG:
|
||||
// VNEGV, VWCVTXXV, VWCVTUXXV and VNCVTXXW read as one-operand forms
|
||||
// of VRSUBVX, VWADDVX, VWADDUVX and VNSRLWX with X0 in the rs1 field.
|
||||
if len(ops) != 2 && len(ops) != 3 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 or 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 3
|
||||
if masked {
|
||||
if err := vecMask(ops[1]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
t, err := rename(map[string]string{
|
||||
"VNEGV": "VRSUBVX", "VWCVTXXV": "VWADDVX",
|
||||
"VWCVTUXXV": "VWADDUVX", "VNCVTXXW": "VNSRLWX",
|
||||
}[mnem])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vs2, err := vecReg(ops[0], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
f7 := t.funct7
|
||||
if !masked {
|
||||
f7 |= 1
|
||||
}
|
||||
return word(f7, 0, vs2, t.funct3, vd)
|
||||
|
||||
case vecVNOT:
|
||||
// VNOTV reads as VXORVI with the all-ones immediate.
|
||||
if len(ops) != 2 && len(ops) != 3 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 or 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 3
|
||||
if masked {
|
||||
if err := vecMask(ops[1]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
t, err := rename("VXORVI")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vs2, err := vecReg(ops[0], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
f7 := t.funct7
|
||||
if !masked {
|
||||
f7 |= 1
|
||||
}
|
||||
return word(f7, -1, vs2, t.funct3, vd)
|
||||
|
||||
case vecVFABS:
|
||||
// VFABSV and VFNEGV read as VFSGNJXVV/VFSGNJNVVV with the source in
|
||||
// both the rs1 and vs2 fields.
|
||||
if len(ops) != 2 && len(ops) != 3 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 or 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 3
|
||||
if masked {
|
||||
if err := vecMask(ops[1]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
t, err := rename(map[string]string{
|
||||
"VFABSV": "VFSGNJXVV", "VFNEGV": "VFSGNJNVV",
|
||||
}[mnem])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vs2, err := vecReg(ops[0], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
f7 := t.funct7
|
||||
if !masked {
|
||||
f7 |= 1
|
||||
}
|
||||
return word(f7, int32(vs2), vs2, t.funct3, vd)
|
||||
|
||||
case vecVMVV:
|
||||
// INSTR vs2, vd (vmv.v.v/vmv.v.x): the source in the rs1 field, V0
|
||||
// fixed in vs2, the vm bit from the table.
|
||||
if len(ops) != 2 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
vs2, err := vecReg(ops[0], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(op.funct7, int32(vs2), 0, op.funct3, vd)
|
||||
|
||||
case vecVMVI:
|
||||
// INSTR $imm, vd (vmv.v.i): the immediate in the rs1 field, V0 in
|
||||
// vs2, the vm bit from the table.
|
||||
if len(ops) != 2 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
imm, err := vecImm(ops[0])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(op.funct7, imm, 0, op.funct3, vd)
|
||||
|
||||
case vecVFMVVF:
|
||||
// INSTR fs1, vd (vfmv.v.f): the scalar in the rs1 field, V0 in vs2.
|
||||
if len(ops) != 2 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
fs1, err := vecReg(ops[0], "fs1")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(op.funct7, int32(fs1), 0, op.funct3, vd)
|
||||
|
||||
case vecTWO:
|
||||
// INSTR vs2, vd: two-operand forms with the fixed rs1 field (the
|
||||
// extensions and conversions, the whole-register moves, the scalar
|
||||
// reads).
|
||||
if len(ops) != 2 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
vs2, err := vecReg(ops[0], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(op.funct7, int32(op.rs1), vs2, op.funct3, vd)
|
||||
|
||||
case vecTWOX:
|
||||
// INSTR xs1|fs1, vd: two-operand forms with the fixed vs2 field
|
||||
// (vmv.s.x and vfmv.s.f).
|
||||
if len(ops) != 2 {
|
||||
return nil, true, fmt.Errorf("%s expects 2 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
rs1, err := vecReg(ops[0], "rs1")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(op.funct7, int32(rs1), int(op.rs1), op.funct3, vd)
|
||||
|
||||
case vecADC:
|
||||
// INSTR vs1|$imm, vs2, V0, vd: the carry forms, the mask mandatory,
|
||||
// V0 rejected as the destination.
|
||||
if len(ops) != 4 {
|
||||
return nil, true, fmt.Errorf("%s expects 4 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
if err := vecMask(ops[2]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vs2, err := vecReg(ops[1], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[3], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
if vd == 0 {
|
||||
return nil, true, fmt.Errorf("%s: invalid destination register V0", mnem)
|
||||
}
|
||||
var rs1Field int32
|
||||
if op.imm {
|
||||
if rs1Field, err = vecImm(ops[0]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
} else {
|
||||
var vs1 int
|
||||
if vs1, err = vecReg(ops[0], "vs1"); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
rs1Field = int32(vs1)
|
||||
}
|
||||
return word(op.funct7, rs1Field, vs2, op.funct3, vd)
|
||||
|
||||
case vecMERGE:
|
||||
// INSTR vs1|fs1|$imm, vs2, V0, vd: the merge forms, the mask
|
||||
// mandatory, V0 allowed as the destination.
|
||||
if len(ops) != 4 {
|
||||
return nil, true, fmt.Errorf("%s expects 4 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
if err := vecMask(ops[2]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vs2, err := vecReg(ops[1], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[3], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
var rs1Field int32
|
||||
if op.imm {
|
||||
if rs1Field, err = vecImm(ops[0]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
} else {
|
||||
var vs1 int
|
||||
if vs1, err = vecReg(ops[0], "vs1"); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
rs1Field = int32(vs1)
|
||||
}
|
||||
return word(op.funct7, rs1Field, vs2, op.funct3, vd)
|
||||
|
||||
case vecVMADC:
|
||||
// INSTR vs1|$imm, vs2, vd: the carry-producing forms; the third
|
||||
// operand names the destination and may be V0.
|
||||
if len(ops) != 3 {
|
||||
return nil, true, fmt.Errorf("%s expects 3 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
vs2, err := vecReg(ops[1], "vs2")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vd, err := vecReg(ops[2], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
var rs1Field int32
|
||||
if op.imm {
|
||||
if rs1Field, err = vecImm(ops[0]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
} else {
|
||||
var vs1 int
|
||||
if vs1, err = vecReg(ops[0], "vs1"); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
rs1Field = int32(vs1)
|
||||
}
|
||||
return word(op.funct7, rs1Field, vs2, op.funct3, vd)
|
||||
|
||||
case vecMM:
|
||||
// INSTR vs1, vs2, vd: the mask-mask forms. VMMVM and VMNOTM take
|
||||
// two operands and fold the second source into the first; the vm
|
||||
// bit stays as the table carries it.
|
||||
folded := mnem == "VMMVM" || mnem == "VMNOTM"
|
||||
if (folded && len(ops) != 2) || (!folded && len(ops) != 3) {
|
||||
return nil, true, fmt.Errorf("%s expects %d operands, got %d", mnem, map[bool]int{true: 2, false: 3}[folded], len(ops))
|
||||
}
|
||||
vs1, err := vecReg(ops[0], "vs1")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
vs2 := vs1
|
||||
if !folded {
|
||||
if vs2, err = vecReg(ops[1], "vs2"); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(op.funct7, int32(vs1), vs2, op.funct3, vd)
|
||||
|
||||
case vecVMCLR:
|
||||
// INSTR vd: the whole-mask clears and sets, one register in all
|
||||
// three fields.
|
||||
if len(ops) != 1 {
|
||||
return nil, true, fmt.Errorf("%s expects 1 operand, got %d", mnem, len(ops))
|
||||
}
|
||||
t, err := rename(map[string]string{
|
||||
"VMCLRM": "VMXORMM", "VMSETM": "VMXNORMM",
|
||||
}[mnem])
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
r, err := vecReg(ops[0], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(t.funct7, int32(r), r, t.funct3, r)
|
||||
|
||||
case vecVID:
|
||||
// INSTR [V0,] vd: the element index, the mask before the destination.
|
||||
if len(ops) != 1 && len(ops) != 2 {
|
||||
return nil, true, fmt.Errorf("%s expects 1 or 2 operands, got %d", mnem, len(ops))
|
||||
}
|
||||
masked := len(ops) == 2
|
||||
if masked {
|
||||
if err := vecMask(ops[0]); err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
}
|
||||
vd, err := vecReg(ops[len(ops)-1], "vd")
|
||||
if err != nil {
|
||||
return nil, true, err
|
||||
}
|
||||
return word(vm(masked), int32(op.rs1), 0, op.funct3, vd)
|
||||
}
|
||||
return nil, true, fmt.Errorf("%s: unhandled vector operand class", mnem)
|
||||
}
|
||||
|
||||
// riscvVTypeToken parses a vsetvli configuration token (E8, M8, MF2 and
|
||||
|
||||
+436
-21
@@ -540,11 +540,8 @@ func riscvJType(rd int, offset int32) uint32 {
|
||||
const (
|
||||
riscvOpV = 0x57 // the vector operation opcode (also OPcfg for vset*)
|
||||
// funct3 values: 0 OPIVV, 1 OPFVV, 2 OPMVV, 3 OPIVI, 4 OPIVX,
|
||||
// 5 OPFVF, 6 OPMVX, 7 vsetvli.
|
||||
riscvVf3VV = 0x0 // vector-vector
|
||||
riscvVf3MV = 0x2 // vector mask
|
||||
riscvVf3VI = 0x3 // vector-immediate
|
||||
riscvVf3VX = 0x4 // vector-scalar
|
||||
// 5 OPFVF, 6 OPMVX, 7 vsetvli. The subclass a mnemonic carries lives
|
||||
// in its table entry's funct3.
|
||||
riscvVf3Cfg = 0x7 // vsetvli
|
||||
)
|
||||
|
||||
@@ -578,27 +575,445 @@ func riscvVLSType(op uint32, nf, mop, width int, rs2 int32, rs1, rd int) uint32
|
||||
uint32(rd)<<7 | op
|
||||
}
|
||||
|
||||
// riscvVVInstr encodes an OP-V instruction with the six-bit operation code in
|
||||
// funct7's upper bits, bit 25 as the unmasked flag and the three registers in
|
||||
// the standard positions. vs1 may name an integer register for the *VX forms
|
||||
// (the scalar sits in the rs1 field) or an immediate for the *VI forms.
|
||||
func riscvVVInstr(funct6, funct3 int, vs1 int32, vs2, vd int) uint32 {
|
||||
return uint32(funct6&0x3F)<<26 | 1<<25 | uint32(vs1)<<15 |
|
||||
uint32(funct3)<<12 | uint32(vs2)<<20 | uint32(vd)<<7 | riscvOpV
|
||||
}
|
||||
|
||||
// riscvVUnaryInstr encodes a one-vector-operand OP-V instruction whose fixed
|
||||
// fields live where the second source register would be: rs1Field and vs2 are
|
||||
// written verbatim (the oracle writes fixed non-zero constants there for some
|
||||
// instructions, such as 0x11 in the rs1 field of vmfirst.m and vid.v).
|
||||
func riscvVUnaryInstr(funct6, funct3 int, rs1Field int32, vs2, vd int) uint32 {
|
||||
return uint32(funct6&0x3F)<<26 | 1<<25 | uint32(vs2&0x1F)<<20 |
|
||||
uint32(rs1Field&0x1F)<<15 | uint32(funct3&0x7)<<12 | uint32(vd&0x1F)<<7 | riscvOpV
|
||||
// riscvVecWord composes one OP-V arithmetic word: funct7 carries funct6 << 1
|
||||
// with the vm bit in its LSB, exactly as the table stores it; rs1Field takes
|
||||
// the source register, the scalar or the immediate; vs2 and vd name vector
|
||||
// registers.
|
||||
func riscvVecWord(funct7 uint32, rs1Field int32, vs2 int, funct3 uint32, vd int) uint32 {
|
||||
return funct7<<25 | uint32(vs2&0x1F)<<20 | uint32(rs1Field&0x1F)<<15 |
|
||||
funct3&0x7<<12 | uint32(vd&0x1F)<<7 | riscvOpV
|
||||
}
|
||||
|
||||
// riscvSegNF maps a segment count to the 3-bit nf field (count - 1).
|
||||
func riscvSegNF(n int) int32 { return int32(n - 1) }
|
||||
|
||||
// The table below mirrors the Go toolchain's own instruction table
|
||||
// (cmd/internal/obj/riscv): funct7 carries funct6 << 1 with the fixed
|
||||
// vm bit in its LSB, exactly as the toolchain stores it.
|
||||
|
||||
// riscvVecOpClass names the operand shape a vector arithmetic mnemonic
|
||||
// takes: which operands land in the rs1 and vs2 fields, whether a
|
||||
// V0 mask may sit between them, and whether the class rewrites its
|
||||
// operands or its mnemonic before encoding.
|
||||
type riscvVecOpClass uint8
|
||||
|
||||
const (
|
||||
// vs1, vs2 [, v0], vd: the plain vector-vector form
|
||||
vecVV riscvVecOpClass = iota
|
||||
// vs2, vs1 [, v0], vd: the multiply-accumulate order
|
||||
vecMACC
|
||||
// vs2 [, v0], vd: one vector operand, fixed rs1
|
||||
vecUNARY
|
||||
// vs2 [, v0], xrd: mask bookkeeping into an integer register
|
||||
vecM2I
|
||||
// vs2, vd: vmv.v.v and vmv.v.x spellings
|
||||
vecVMVV
|
||||
// $imm, vd: vmv.v.i
|
||||
vecVMVI
|
||||
// fs1, vd: vfmv.v.f
|
||||
vecVFMVVF
|
||||
// vs2, vd: two-operand forms with a fixed rs1 field
|
||||
vecTWO
|
||||
// xs1|fs1, vd: two-operand forms with a fixed vs2 field
|
||||
vecTWOX
|
||||
// vs1, vs2, v0, vd: the carry forms, mask mandatory
|
||||
vecADC
|
||||
// vs1, vs2, v0, vd: the merge forms, mask mandatory
|
||||
vecMERGE
|
||||
// vs1, vs2, vd: the carry-producing forms
|
||||
vecVMADC
|
||||
// vs2 [, v0], vd with rs1 = x0: VNEGV and friends
|
||||
vecNEG
|
||||
// vs2 [, v0], vd: XOR with -1
|
||||
vecVNOT
|
||||
// vs2, vs1 [, v0], vd: the swapped comparisons
|
||||
vecSWAPVV
|
||||
// $imm, vs2 [, v0], vd: swapped, imm-1
|
||||
vecSWAPVI
|
||||
// vs2 [, v0], vd with rs1 = vs2: VFABSV and VFNEGV
|
||||
vecVFABS
|
||||
// vs1, vs2, vd: the mask-mask forms, no mask operand
|
||||
vecMM
|
||||
// vd: the whole-mask clears and sets
|
||||
vecVMCLR
|
||||
// [v0,] vd: the element index
|
||||
vecVID
|
||||
)
|
||||
|
||||
// riscvVecOp is one vector arithmetic instruction's fixed fields: the
|
||||
// funct3 subclass, the fixed rs1 field (the unary constants), the fixed
|
||||
// funct7 (funct6 << 1 with the fixed vm bit), the operand class and the
|
||||
// immediate form the first operand takes.
|
||||
type riscvVecOp struct {
|
||||
funct3 uint32
|
||||
rs1 uint32
|
||||
funct7 uint32
|
||||
class riscvVecOpClass
|
||||
imm bool // the first operand is an immediate in the rs1 field
|
||||
immU bool // that immediate is unsigned [0, 31] (shifts and slides)
|
||||
}
|
||||
|
||||
// riscvVecOps maps every vector arithmetic mnemonic the toolchain knows
|
||||
// onto its fields. The loads and stores and the configuration setters
|
||||
// have their own paths.
|
||||
var riscvVecOps = map[string]riscvVecOp{
|
||||
"VAADDUVV": {0x2, 0x0, 0x10, 0, false, false},
|
||||
"VAADDUVX": {0x6, 0x0, 0x10, 0, false, false},
|
||||
"VAADDVV": {0x2, 0x0, 0x12, 0, false, false},
|
||||
"VAADDVX": {0x6, 0x0, 0x12, 0, false, false},
|
||||
"VADCVIM": {0x3, 0x0, 0x20, 9, true, false},
|
||||
"VADCVVM": {0x0, 0x0, 0x20, 9, false, false},
|
||||
"VADCVXM": {0x4, 0x0, 0x20, 9, false, false},
|
||||
"VADDVI": {0x3, 0x0, 0x00, 0, true, false},
|
||||
"VADDVV": {0x0, 0x0, 0x00, 0, false, false},
|
||||
"VADDVX": {0x4, 0x0, 0x00, 0, false, false},
|
||||
"VANDNVV": {0x0, 0x0, 0x02, 0, false, false},
|
||||
"VANDNVX": {0x4, 0x0, 0x02, 0, false, false},
|
||||
"VANDVI": {0x3, 0x0, 0x12, 0, true, false},
|
||||
"VANDVV": {0x0, 0x0, 0x12, 0, false, false},
|
||||
"VANDVX": {0x4, 0x0, 0x12, 0, false, false},
|
||||
"VASUBUVV": {0x2, 0x0, 0x14, 0, false, false},
|
||||
"VASUBUVX": {0x6, 0x0, 0x14, 0, false, false},
|
||||
"VASUBVV": {0x2, 0x0, 0x16, 0, false, false},
|
||||
"VASUBVX": {0x6, 0x0, 0x16, 0, false, false},
|
||||
"VBREV8V": {0x2, 0x8, 0x24, 2, false, false},
|
||||
"VBREVV": {0x2, 0xa, 0x24, 2, false, false},
|
||||
"VCLMULHVV": {0x2, 0x0, 0x1a, 0, false, false},
|
||||
"VCLMULHVX": {0x6, 0x0, 0x1a, 0, false, false},
|
||||
"VCLMULVV": {0x2, 0x0, 0x18, 0, false, false},
|
||||
"VCLMULVX": {0x6, 0x0, 0x18, 0, false, false},
|
||||
"VCLZV": {0x2, 0xc, 0x24, 2, false, false},
|
||||
"VCOMPRESSVM": {0x2, 0x0, 0x2f, 17, false, false},
|
||||
"VCPOPM": {0x2, 0x10, 0x20, 3, false, false},
|
||||
"VCPOPV": {0x2, 0xe, 0x24, 2, false, false},
|
||||
"VCTZV": {0x2, 0xd, 0x24, 2, false, false},
|
||||
"VDIVUVV": {0x2, 0x0, 0x40, 0, false, false},
|
||||
"VDIVUVX": {0x6, 0x0, 0x40, 0, false, false},
|
||||
"VDIVVV": {0x2, 0x0, 0x42, 0, false, false},
|
||||
"VDIVVX": {0x6, 0x0, 0x42, 0, false, false},
|
||||
"VFABSV": {0x1, 0x0, 0x14, 16, false, false},
|
||||
"VFADDVF": {0x5, 0x0, 0x00, 0, false, false},
|
||||
"VFADDVV": {0x1, 0x0, 0x00, 0, false, false},
|
||||
"VFCLASSV": {0x1, 0x10, 0x26, 2, false, false},
|
||||
"VFCVTFXUV": {0x1, 0x2, 0x24, 2, false, false},
|
||||
"VFCVTFXV": {0x1, 0x3, 0x24, 2, false, false},
|
||||
"VFCVTRTZXFV": {0x1, 0x7, 0x24, 2, false, false},
|
||||
"VFCVTRTZXUFV": {0x1, 0x6, 0x24, 2, false, false},
|
||||
"VFCVTXFV": {0x1, 0x1, 0x24, 2, false, false},
|
||||
"VFCVTXUFV": {0x1, 0x0, 0x24, 2, false, false},
|
||||
"VFDIVVF": {0x5, 0x0, 0x40, 0, false, false},
|
||||
"VFDIVVV": {0x1, 0x0, 0x40, 0, false, false},
|
||||
"VFIRSTM": {0x2, 0x11, 0x20, 3, false, false},
|
||||
"VFMACCVF": {0x5, 0x0, 0x58, 1, false, false},
|
||||
"VFMACCVV": {0x1, 0x0, 0x58, 1, false, false},
|
||||
"VFMADDVF": {0x5, 0x0, 0x50, 1, false, false},
|
||||
"VFMADDVV": {0x1, 0x0, 0x50, 1, false, false},
|
||||
"VFMAXVF": {0x5, 0x0, 0x0c, 0, false, false},
|
||||
"VFMAXVV": {0x1, 0x0, 0x0c, 0, false, false},
|
||||
"VFMERGEVFM": {0x5, 0x0, 0x2e, 10, false, false},
|
||||
"VFMINVF": {0x5, 0x0, 0x08, 0, false, false},
|
||||
"VFMINVV": {0x1, 0x0, 0x08, 0, false, false},
|
||||
"VFMSACVF": {0x5, 0x0, 0x5c, 1, false, false},
|
||||
"VFMSACVV": {0x1, 0x0, 0x5c, 1, false, false},
|
||||
"VFMSUBVF": {0x5, 0x0, 0x54, 1, false, false},
|
||||
"VFMSUBVV": {0x1, 0x0, 0x54, 1, false, false},
|
||||
"VFMULVF": {0x5, 0x0, 0x48, 0, false, false},
|
||||
"VFMULVV": {0x1, 0x0, 0x48, 0, false, false},
|
||||
"VFMVFS": {0x1, 0x0, 0x21, 7, false, false},
|
||||
"VFMVSF": {0x5, 0x0, 0x21, 8, false, false},
|
||||
"VFMVVF": {0x5, 0x0, 0x2f, 6, false, false},
|
||||
"VFNCVTFFW": {0x1, 0x14, 0x24, 2, false, false},
|
||||
"VFNCVTFXUW": {0x1, 0x12, 0x24, 2, false, false},
|
||||
"VFNCVTFXW": {0x1, 0x13, 0x24, 2, false, false},
|
||||
"VFNCVTRODFFW": {0x1, 0x15, 0x24, 2, false, false},
|
||||
"VFNCVTRTZXFW": {0x1, 0x17, 0x24, 2, false, false},
|
||||
"VFNCVTRTZXUFW": {0x1, 0x16, 0x24, 2, false, false},
|
||||
"VFNCVTXFW": {0x1, 0x11, 0x24, 2, false, false},
|
||||
"VFNCVTXUFW": {0x1, 0x10, 0x24, 2, false, false},
|
||||
"VFNEGV": {0x1, 0x0, 0x12, 16, false, false},
|
||||
"VFNMACCVF": {0x5, 0x0, 0x5a, 1, false, false},
|
||||
"VFNMACCVV": {0x1, 0x0, 0x5a, 1, false, false},
|
||||
"VFNMADDVF": {0x5, 0x0, 0x52, 1, false, false},
|
||||
"VFNMADDVV": {0x1, 0x0, 0x52, 1, false, false},
|
||||
"VFNMSACVF": {0x5, 0x0, 0x5e, 1, false, false},
|
||||
"VFNMSACVV": {0x1, 0x0, 0x5e, 1, false, false},
|
||||
"VFNMSUBVF": {0x5, 0x0, 0x56, 1, false, false},
|
||||
"VFNMSUBVV": {0x1, 0x0, 0x56, 1, false, false},
|
||||
"VFRDIVVF": {0x5, 0x0, 0x42, 0, false, false},
|
||||
"VFREC7V": {0x1, 0x5, 0x26, 2, false, false},
|
||||
"VFREDMAXVS": {0x1, 0x0, 0x0e, 0, false, false},
|
||||
"VFREDMINVS": {0x1, 0x0, 0x0a, 0, false, false},
|
||||
"VFREDOSUMVS": {0x1, 0x0, 0x06, 0, false, false},
|
||||
"VFREDUSUMVS": {0x1, 0x0, 0x02, 0, false, false},
|
||||
"VFRSQRT7V": {0x1, 0x4, 0x26, 2, false, false},
|
||||
"VFRSUBVF": {0x5, 0x0, 0x4e, 0, false, false},
|
||||
"VFSGNJNVF": {0x5, 0x0, 0x12, 0, false, false},
|
||||
"VFSGNJNVV": {0x1, 0x0, 0x12, 0, false, false},
|
||||
"VFSGNJVF": {0x5, 0x0, 0x10, 0, false, false},
|
||||
"VFSGNJVV": {0x1, 0x0, 0x10, 0, false, false},
|
||||
"VFSGNJXVF": {0x5, 0x0, 0x14, 0, false, false},
|
||||
"VFSGNJXVV": {0x1, 0x0, 0x14, 0, false, false},
|
||||
"VFSLIDE1DOWNVF": {0x5, 0x0, 0x1e, 0, false, false},
|
||||
"VFSLIDE1UPVF": {0x5, 0x0, 0x1c, 0, false, false},
|
||||
"VFSQRTV": {0x1, 0x0, 0x26, 2, false, false},
|
||||
"VFSUBVF": {0x5, 0x0, 0x04, 0, false, false},
|
||||
"VFSUBVV": {0x1, 0x0, 0x04, 0, false, false},
|
||||
"VFWADDVF": {0x5, 0x0, 0x60, 0, false, false},
|
||||
"VFWADDVV": {0x1, 0x0, 0x60, 0, false, false},
|
||||
"VFWADDWF": {0x5, 0x0, 0x68, 0, false, false},
|
||||
"VFWADDWV": {0x1, 0x0, 0x68, 0, false, false},
|
||||
"VFWCVTFFV": {0x1, 0xc, 0x24, 2, false, false},
|
||||
"VFWCVTFXUV": {0x1, 0xa, 0x24, 2, false, false},
|
||||
"VFWCVTFXV": {0x1, 0xb, 0x24, 2, false, false},
|
||||
"VFWCVTRTZXFV": {0x1, 0xf, 0x24, 2, false, false},
|
||||
"VFWCVTRTZXUFV": {0x1, 0xe, 0x24, 2, false, false},
|
||||
"VFWCVTXFV": {0x1, 0x9, 0x24, 2, false, false},
|
||||
"VFWCVTXUFV": {0x1, 0x8, 0x24, 2, false, false},
|
||||
"VFWMACCVF": {0x5, 0x0, 0x78, 1, false, false},
|
||||
"VFWMACCVV": {0x1, 0x0, 0x78, 1, false, false},
|
||||
"VFWMSACVF": {0x5, 0x0, 0x7c, 1, false, false},
|
||||
"VFWMSACVV": {0x1, 0x0, 0x7c, 1, false, false},
|
||||
"VFWMULVF": {0x5, 0x0, 0x70, 0, false, false},
|
||||
"VFWMULVV": {0x1, 0x0, 0x70, 0, false, false},
|
||||
"VFWNMACCVF": {0x5, 0x0, 0x7a, 1, false, false},
|
||||
"VFWNMACCVV": {0x1, 0x0, 0x7a, 1, false, false},
|
||||
"VFWNMSACVF": {0x5, 0x0, 0x7e, 1, false, false},
|
||||
"VFWNMSACVV": {0x1, 0x0, 0x7e, 1, false, false},
|
||||
"VFWREDOSUMVS": {0x1, 0x0, 0x66, 0, false, false},
|
||||
"VFWREDUSUMVS": {0x1, 0x0, 0x62, 0, false, false},
|
||||
"VFWSUBVF": {0x5, 0x0, 0x64, 0, false, false},
|
||||
"VFWSUBVV": {0x1, 0x0, 0x64, 0, false, false},
|
||||
"VFWSUBWF": {0x5, 0x0, 0x6c, 0, false, false},
|
||||
"VFWSUBWV": {0x1, 0x0, 0x6c, 0, false, false},
|
||||
"VIDV": {0x2, 0x11, 0x28, 19, false, false},
|
||||
"VIOTAM": {0x2, 0x10, 0x28, 3, false, false},
|
||||
"VMACCVV": {0x2, 0x0, 0x5a, 1, false, false},
|
||||
"VMACCVX": {0x6, 0x0, 0x5a, 1, false, false},
|
||||
"VMADCVI": {0x3, 0x0, 0x23, 11, true, false},
|
||||
"VMADCVIM": {0x3, 0x0, 0x22, 10, true, false},
|
||||
"VMADCVV": {0x0, 0x0, 0x23, 11, false, false},
|
||||
"VMADCVVM": {0x0, 0x0, 0x22, 10, false, false},
|
||||
"VMADCVX": {0x4, 0x0, 0x23, 11, false, false},
|
||||
"VMADCVXM": {0x4, 0x0, 0x22, 10, false, false},
|
||||
"VMADDVV": {0x2, 0x0, 0x52, 1, false, false},
|
||||
"VMADDVX": {0x6, 0x0, 0x52, 1, false, false},
|
||||
"VMANDMM": {0x2, 0x0, 0x33, 17, false, false},
|
||||
"VMANDNMM": {0x2, 0x0, 0x31, 17, false, false},
|
||||
"VMAXUVV": {0x0, 0x0, 0x0c, 0, false, false},
|
||||
"VMAXUVX": {0x4, 0x0, 0x0c, 0, false, false},
|
||||
"VMAXVV": {0x0, 0x0, 0x0e, 0, false, false},
|
||||
"VMAXVX": {0x4, 0x0, 0x0e, 0, false, false},
|
||||
"VMCLRM": {0x2, 0x0, 0x37, 18, false, false},
|
||||
"VMERGEVIM": {0x3, 0x0, 0x2e, 10, true, false},
|
||||
"VMERGEVVM": {0x0, 0x0, 0x2e, 10, false, false},
|
||||
"VMERGEVXM": {0x4, 0x0, 0x2e, 10, false, false},
|
||||
"VMFEQVF": {0x5, 0x0, 0x30, 0, false, false},
|
||||
"VMFEQVV": {0x1, 0x0, 0x30, 0, false, false},
|
||||
"VMFGEVF": {0x5, 0x0, 0x3e, 0, false, false},
|
||||
"VMFGEVV": {0x1, 0x0, 0x32, 14, false, false},
|
||||
"VMFGTVF": {0x5, 0x0, 0x3a, 0, false, false},
|
||||
"VMFGTVV": {0x1, 0x0, 0x36, 14, false, false},
|
||||
"VMFLEVF": {0x5, 0x0, 0x32, 0, false, false},
|
||||
"VMFLEVV": {0x1, 0x0, 0x32, 0, false, false},
|
||||
"VMFLTVF": {0x5, 0x0, 0x36, 0, false, false},
|
||||
"VMFLTVV": {0x1, 0x0, 0x36, 0, false, false},
|
||||
"VMFNEVF": {0x5, 0x0, 0x38, 0, false, false},
|
||||
"VMFNEVV": {0x1, 0x0, 0x38, 0, false, false},
|
||||
"VMINUVV": {0x0, 0x0, 0x08, 0, false, false},
|
||||
"VMINUVX": {0x4, 0x0, 0x08, 0, false, false},
|
||||
"VMINVV": {0x0, 0x0, 0x0a, 0, false, false},
|
||||
"VMINVX": {0x4, 0x0, 0x0a, 0, false, false},
|
||||
"VMMVM": {0x2, 0x0, 0x33, 17, false, false},
|
||||
"VMNANDMM": {0x2, 0x0, 0x3b, 17, false, false},
|
||||
"VMNORMM": {0x2, 0x0, 0x3d, 17, false, false},
|
||||
"VMNOTM": {0x2, 0x0, 0x3b, 17, false, false},
|
||||
"VMORMM": {0x2, 0x0, 0x35, 17, false, false},
|
||||
"VMORNMM": {0x2, 0x0, 0x39, 17, false, false},
|
||||
"VMSBCVV": {0x0, 0x0, 0x27, 11, false, false},
|
||||
"VMSBCVVM": {0x0, 0x0, 0x26, 10, false, false},
|
||||
"VMSBCVX": {0x4, 0x0, 0x27, 11, false, false},
|
||||
"VMSBCVXM": {0x4, 0x0, 0x26, 10, false, false},
|
||||
"VMSBFM": {0x2, 0x1, 0x28, 3, false, false},
|
||||
"VMSEQVI": {0x3, 0x0, 0x30, 0, true, false},
|
||||
"VMSEQVV": {0x0, 0x0, 0x30, 0, false, false},
|
||||
"VMSEQVX": {0x4, 0x0, 0x30, 0, false, false},
|
||||
"VMSETM": {0x2, 0x0, 0x3f, 18, false, false},
|
||||
"VMSGEUVI": {0x3, 0x0, 0x3c, 15, true, false},
|
||||
"VMSGEUVV": {0x0, 0x0, 0x38, 14, false, false},
|
||||
"VMSGEVI": {0x3, 0x0, 0x3e, 15, true, false},
|
||||
"VMSGEVV": {0x0, 0x0, 0x3a, 14, false, false},
|
||||
"VMSGTUVI": {0x3, 0x0, 0x3c, 0, true, false},
|
||||
"VMSGTUVV": {0x0, 0x0, 0x34, 14, false, false},
|
||||
"VMSGTUVX": {0x4, 0x0, 0x3c, 0, false, false},
|
||||
"VMSGTVI": {0x3, 0x0, 0x3e, 0, true, false},
|
||||
"VMSGTVV": {0x0, 0x0, 0x36, 14, false, false},
|
||||
"VMSGTVX": {0x4, 0x0, 0x3e, 0, false, false},
|
||||
"VMSIFM": {0x2, 0x3, 0x28, 3, false, false},
|
||||
"VMSLEUVI": {0x3, 0x0, 0x38, 0, true, false},
|
||||
"VMSLEUVV": {0x0, 0x0, 0x38, 0, false, false},
|
||||
"VMSLEUVX": {0x4, 0x0, 0x38, 0, false, false},
|
||||
"VMSLEVI": {0x3, 0x0, 0x3a, 0, true, false},
|
||||
"VMSLEVV": {0x0, 0x0, 0x3a, 0, false, false},
|
||||
"VMSLEVX": {0x4, 0x0, 0x3a, 0, false, false},
|
||||
"VMSLTUVI": {0x3, 0x0, 0x38, 15, true, false},
|
||||
"VMSLTUVV": {0x0, 0x0, 0x34, 0, false, false},
|
||||
"VMSLTUVX": {0x4, 0x0, 0x34, 0, false, false},
|
||||
"VMSLTVI": {0x3, 0x0, 0x3a, 15, true, false},
|
||||
"VMSLTVV": {0x0, 0x0, 0x36, 0, false, false},
|
||||
"VMSLTVX": {0x4, 0x0, 0x36, 0, false, false},
|
||||
"VMSNEVI": {0x3, 0x0, 0x32, 0, true, false},
|
||||
"VMSNEVV": {0x0, 0x0, 0x32, 0, false, false},
|
||||
"VMSNEVX": {0x4, 0x0, 0x32, 0, false, false},
|
||||
"VMSOFM": {0x2, 0x2, 0x28, 3, false, false},
|
||||
"VMULHSUVV": {0x2, 0x0, 0x4c, 0, false, false},
|
||||
"VMULHSUVX": {0x6, 0x0, 0x4c, 0, false, false},
|
||||
"VMULHUVV": {0x2, 0x0, 0x48, 0, false, false},
|
||||
"VMULHUVX": {0x6, 0x0, 0x48, 0, false, false},
|
||||
"VMULHVV": {0x2, 0x0, 0x4e, 0, false, false},
|
||||
"VMULHVX": {0x6, 0x0, 0x4e, 0, false, false},
|
||||
"VMULVV": {0x2, 0x0, 0x4a, 0, false, false},
|
||||
"VMULVX": {0x6, 0x0, 0x4a, 0, false, false},
|
||||
"VMV1RV": {0x3, 0x0, 0x4f, 7, false, false},
|
||||
"VMV2RV": {0x3, 0x1, 0x4f, 7, false, false},
|
||||
"VMV4RV": {0x3, 0x3, 0x4f, 7, false, false},
|
||||
"VMV8RV": {0x3, 0x7, 0x4f, 7, false, false},
|
||||
"VMVSX": {0x6, 0x0, 0x21, 8, false, false},
|
||||
"VMVVI": {0x3, 0x0, 0x2f, 5, true, false},
|
||||
"VMVVV": {0x0, 0x0, 0x2f, 4, false, false},
|
||||
"VMVVX": {0x4, 0x0, 0x2f, 4, false, false},
|
||||
"VMVXS": {0x2, 0x0, 0x21, 7, false, false},
|
||||
"VMXNORMM": {0x2, 0x0, 0x3f, 17, false, false},
|
||||
"VMXORMM": {0x2, 0x0, 0x37, 17, false, false},
|
||||
"VNCLIPUWI": {0x3, 0x0, 0x5c, 0, true, true},
|
||||
"VNCLIPUWV": {0x0, 0x0, 0x5c, 0, false, false},
|
||||
"VNCLIPUWX": {0x4, 0x0, 0x5c, 0, false, false},
|
||||
"VNCLIPWI": {0x3, 0x0, 0x5e, 0, true, true},
|
||||
"VNCLIPWV": {0x0, 0x0, 0x5e, 0, false, false},
|
||||
"VNCLIPWX": {0x4, 0x0, 0x5e, 0, false, false},
|
||||
"VNCVTXXW": {0x4, 0x0, 0x58, 12, false, false},
|
||||
"VNEGV": {0x4, 0x0, 0x06, 12, false, false},
|
||||
"VNMSACVV": {0x2, 0x0, 0x5e, 1, false, false},
|
||||
"VNMSACVX": {0x6, 0x0, 0x5e, 1, false, false},
|
||||
"VNMSUBVV": {0x2, 0x0, 0x56, 1, false, false},
|
||||
"VNMSUBVX": {0x6, 0x0, 0x56, 1, false, false},
|
||||
"VNOTV": {0x3, 0x0, 0x16, 13, true, false},
|
||||
"VNSRAWI": {0x3, 0x0, 0x5a, 0, true, true},
|
||||
"VNSRAWV": {0x0, 0x0, 0x5a, 0, false, false},
|
||||
"VNSRAWX": {0x4, 0x0, 0x5a, 0, false, false},
|
||||
"VNSRLWI": {0x3, 0x0, 0x58, 0, true, true},
|
||||
"VNSRLWV": {0x0, 0x0, 0x58, 0, false, false},
|
||||
"VNSRLWX": {0x4, 0x0, 0x58, 0, false, false},
|
||||
"VORVI": {0x3, 0x0, 0x14, 0, true, false},
|
||||
"VORVV": {0x0, 0x0, 0x14, 0, false, false},
|
||||
"VORVX": {0x4, 0x0, 0x14, 0, false, false},
|
||||
"VREDANDVS": {0x2, 0x0, 0x02, 0, false, false},
|
||||
"VREDMAXUVS": {0x2, 0x0, 0x0c, 0, false, false},
|
||||
"VREDMAXVS": {0x2, 0x0, 0x0e, 0, false, false},
|
||||
"VREDMINUVS": {0x2, 0x0, 0x08, 0, false, false},
|
||||
"VREDMINVS": {0x2, 0x0, 0x0a, 0, false, false},
|
||||
"VREDORVS": {0x2, 0x0, 0x04, 0, false, false},
|
||||
"VREDSUMVS": {0x2, 0x0, 0x00, 0, false, false},
|
||||
"VREDXORVS": {0x2, 0x0, 0x06, 0, false, false},
|
||||
"VREMUVV": {0x2, 0x0, 0x44, 0, false, false},
|
||||
"VREMUVX": {0x6, 0x0, 0x44, 0, false, false},
|
||||
"VREMVV": {0x2, 0x0, 0x46, 0, false, false},
|
||||
"VREMVX": {0x6, 0x0, 0x46, 0, false, false},
|
||||
"VREV8V": {0x2, 0x9, 0x24, 2, false, false},
|
||||
"VRGATHEREI16VV": {0x0, 0x0, 0x1c, 0, false, false},
|
||||
"VRGATHERVI": {0x3, 0x0, 0x18, 0, true, true},
|
||||
"VRGATHERVV": {0x0, 0x0, 0x18, 0, false, false},
|
||||
"VRGATHERVX": {0x4, 0x0, 0x18, 0, false, false},
|
||||
"VROLVV": {0x0, 0x0, 0x2a, 0, false, false},
|
||||
"VROLVX": {0x4, 0x0, 0x2a, 0, false, false},
|
||||
"VRORVI": {0x3, 0x0, 0x28, 0, true, true},
|
||||
"VRORVV": {0x0, 0x0, 0x28, 0, false, false},
|
||||
"VRORVX": {0x4, 0x0, 0x28, 0, false, false},
|
||||
"VRSUBVI": {0x3, 0x0, 0x06, 0, true, false},
|
||||
"VRSUBVX": {0x4, 0x0, 0x06, 0, false, false},
|
||||
"VSADDUVI": {0x3, 0x0, 0x40, 0, true, false},
|
||||
"VSADDUVV": {0x0, 0x0, 0x40, 0, false, false},
|
||||
"VSADDUVX": {0x4, 0x0, 0x40, 0, false, false},
|
||||
"VSADDVI": {0x3, 0x0, 0x42, 0, true, false},
|
||||
"VSADDVV": {0x0, 0x0, 0x42, 0, false, false},
|
||||
"VSADDVX": {0x4, 0x0, 0x42, 0, false, false},
|
||||
"VSBCVVM": {0x0, 0x0, 0x24, 9, false, false},
|
||||
"VSBCVXM": {0x4, 0x0, 0x24, 9, false, false},
|
||||
"VSEXTVF2": {0x2, 0x7, 0x24, 2, false, false},
|
||||
"VSEXTVF4": {0x2, 0x5, 0x24, 2, false, false},
|
||||
"VSEXTVF8": {0x2, 0x3, 0x24, 2, false, false},
|
||||
"VSLIDE1DOWNVX": {0x6, 0x0, 0x1e, 0, false, false},
|
||||
"VSLIDE1UPVX": {0x6, 0x0, 0x1c, 0, false, false},
|
||||
"VSLIDEDOWNVI": {0x3, 0x0, 0x1e, 0, true, true},
|
||||
"VSLIDEDOWNVX": {0x4, 0x0, 0x1e, 0, false, false},
|
||||
"VSLIDEUPVI": {0x3, 0x0, 0x1c, 0, true, true},
|
||||
"VSLIDEUPVX": {0x4, 0x0, 0x1c, 0, false, false},
|
||||
"VSLLVI": {0x3, 0x0, 0x4a, 0, true, true},
|
||||
"VSLLVV": {0x0, 0x0, 0x4a, 0, false, false},
|
||||
"VSLLVX": {0x4, 0x0, 0x4a, 0, false, false},
|
||||
"VSMULVV": {0x0, 0x0, 0x4e, 0, false, false},
|
||||
"VSMULVX": {0x4, 0x0, 0x4e, 0, false, false},
|
||||
"VSRAVI": {0x3, 0x0, 0x52, 0, true, true},
|
||||
"VSRAVV": {0x0, 0x0, 0x52, 0, false, false},
|
||||
"VSRAVX": {0x4, 0x0, 0x52, 0, false, false},
|
||||
"VSRLVI": {0x3, 0x0, 0x50, 0, true, true},
|
||||
"VSRLVV": {0x0, 0x0, 0x50, 0, false, false},
|
||||
"VSRLVX": {0x4, 0x0, 0x50, 0, false, false},
|
||||
"VSSRAVI": {0x3, 0x0, 0x56, 0, true, true},
|
||||
"VSSRAVV": {0x0, 0x0, 0x56, 0, false, false},
|
||||
"VSSRAVX": {0x4, 0x0, 0x56, 0, false, false},
|
||||
"VSSRLVI": {0x3, 0x0, 0x54, 0, true, true},
|
||||
"VSSRLVV": {0x0, 0x0, 0x54, 0, false, false},
|
||||
"VSSRLVX": {0x4, 0x0, 0x54, 0, false, false},
|
||||
"VSSUBUVV": {0x0, 0x0, 0x44, 0, false, false},
|
||||
"VSSUBUVX": {0x4, 0x0, 0x44, 0, false, false},
|
||||
"VSSUBVV": {0x0, 0x0, 0x46, 0, false, false},
|
||||
"VSSUBVX": {0x4, 0x0, 0x46, 0, false, false},
|
||||
"VSUBVV": {0x0, 0x0, 0x04, 0, false, false},
|
||||
"VSUBVX": {0x4, 0x0, 0x04, 0, false, false},
|
||||
"VWADDUVV": {0x2, 0x0, 0x60, 0, false, false},
|
||||
"VWADDUVX": {0x6, 0x0, 0x60, 0, false, false},
|
||||
"VWADDUWV": {0x2, 0x0, 0x68, 0, false, false},
|
||||
"VWADDUWX": {0x6, 0x0, 0x68, 0, false, false},
|
||||
"VWADDVV": {0x2, 0x0, 0x62, 0, false, false},
|
||||
"VWADDVX": {0x6, 0x0, 0x62, 0, false, false},
|
||||
"VWADDWV": {0x2, 0x0, 0x6a, 0, false, false},
|
||||
"VWADDWX": {0x6, 0x0, 0x6a, 0, false, false},
|
||||
"VWCVTUXXV": {0x6, 0x0, 0x60, 12, false, false},
|
||||
"VWCVTXXV": {0x6, 0x0, 0x62, 12, false, false},
|
||||
"VWMACCSUVV": {0x2, 0x0, 0x7e, 1, false, false},
|
||||
"VWMACCSUVX": {0x6, 0x0, 0x7e, 1, false, false},
|
||||
"VWMACCUSVX": {0x6, 0x0, 0x7c, 1, false, false},
|
||||
"VWMACCUVV": {0x2, 0x0, 0x78, 1, false, false},
|
||||
"VWMACCUVX": {0x6, 0x0, 0x78, 1, false, false},
|
||||
"VWMACCVV": {0x2, 0x0, 0x7a, 1, false, false},
|
||||
"VWMACCVX": {0x6, 0x0, 0x7a, 1, false, false},
|
||||
"VWMULSUVV": {0x2, 0x0, 0x74, 0, false, false},
|
||||
"VWMULSUVX": {0x6, 0x0, 0x74, 0, false, false},
|
||||
"VWMULUVV": {0x2, 0x0, 0x70, 0, false, false},
|
||||
"VWMULUVX": {0x6, 0x0, 0x70, 0, false, false},
|
||||
"VWMULVV": {0x2, 0x0, 0x76, 0, false, false},
|
||||
"VWMULVX": {0x6, 0x0, 0x76, 0, false, false},
|
||||
"VWREDSUMUVS": {0x0, 0x0, 0x60, 0, false, false},
|
||||
"VWREDSUMVS": {0x0, 0x0, 0x62, 0, false, false},
|
||||
"VWSLLVI": {0x3, 0x0, 0x6a, 0, true, true},
|
||||
"VWSLLVV": {0x0, 0x0, 0x6a, 0, false, false},
|
||||
"VWSLLVX": {0x4, 0x0, 0x6a, 0, false, false},
|
||||
"VWSUBUVV": {0x2, 0x0, 0x64, 0, false, false},
|
||||
"VWSUBUVX": {0x6, 0x0, 0x64, 0, false, false},
|
||||
"VWSUBUWV": {0x2, 0x0, 0x6c, 0, false, false},
|
||||
"VWSUBUWX": {0x6, 0x0, 0x6c, 0, false, false},
|
||||
"VWSUBVV": {0x2, 0x0, 0x66, 0, false, false},
|
||||
"VWSUBVX": {0x6, 0x0, 0x66, 0, false, false},
|
||||
"VWSUBWV": {0x2, 0x0, 0x6e, 0, false, false},
|
||||
"VWSUBWX": {0x6, 0x0, 0x6e, 0, false, false},
|
||||
"VXORVI": {0x3, 0x0, 0x16, 0, true, false},
|
||||
"VXORVV": {0x0, 0x0, 0x16, 0, false, false},
|
||||
"VXORVX": {0x4, 0x0, 0x16, 0, false, false},
|
||||
"VZEXTVF2": {0x2, 0x6, 0x24, 2, false, false},
|
||||
"VZEXTVF4": {0x2, 0x4, 0x24, 2, false, false},
|
||||
"VZEXTVF8": {0x2, 0x2, 0x24, 2, false, false},
|
||||
}
|
||||
|
||||
// ---- RVC (compressed) encoding helpers ----
|
||||
|
||||
// isRVCIntReg reports whether a register number can be encoded in the 3-bit
|
||||
|
||||
@@ -0,0 +1,812 @@
|
||||
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package asm
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestRISCVVecArith_Differential proves the vector arithmetic families
|
||||
// against the toolchain: sections 31.11 through 31.16 of the "V"
|
||||
// specification's arithmetic, reductions, mask, slide, gather, compress and
|
||||
// whole-register-move material plus the Zvbb bit-manipulation and Zvbc
|
||||
// carryless-multiplication extensions, in the toolchain's own testdata
|
||||
// wording with every masked and unmasked form, assembled by gasm and by
|
||||
// go tool asm must agree word for word.
|
||||
func TestRISCVVecArith_Differential(t *testing.T) {
|
||||
src := `#include "textflag.h"
|
||||
|
||||
TEXT ·vecarith(SB), NOSPLIT, $0
|
||||
// 31.11.1: Vector Single-Width Integer Add and Subtract
|
||||
VADDVV V1, V2, V3 // d7812002
|
||||
VADDVV V1, V2, V0, V3 // d7812000
|
||||
VADDVX X10, V2, V3 // d7412502
|
||||
VADDVX X10, V2, V0, V3 // d7412500
|
||||
VADDVI $15, V2, V3 // d7b12702
|
||||
VADDVI $15, V2, V0, V3 // d7b12700
|
||||
VADDVI $-16, V2, V3 // d7312802
|
||||
VADDVI $-16, V2, V0, V3 // d7312800
|
||||
VSUBVV V1, V2, V3 // d781200a
|
||||
VSUBVV V1, V2, V0, V3 // d7812008
|
||||
VSUBVX X10, V2, V3 // d741250a
|
||||
VSUBVX X10, V2, V0, V3 // d7412508
|
||||
VRSUBVX X10, V2, V3 // d741250e
|
||||
VRSUBVX X10, V2, V0, V3 // d741250c
|
||||
VRSUBVI $15, V2, V0, V3 // d7b1270c
|
||||
VRSUBVI $-16, V2, V0, V3 // d731280c
|
||||
VNEGV V2, V3 // d741200e
|
||||
VNEGV V2, V0, V3 // d741200c
|
||||
|
||||
// 31.11.2: Vector Widening Integer Add/Subtract
|
||||
VWADDUVV V1, V2, V3 // d7a120c2
|
||||
VWADDUVV V1, V2, V0, V3 // d7a120c0
|
||||
VWADDUVX X10, V2, V3 // d76125c2
|
||||
VWADDUVX X10, V2, V0, V3 // d76125c0
|
||||
VWSUBUVV V1, V2, V3 // d7a120ca
|
||||
VWSUBUVV V1, V2, V0, V3 // d7a120c8
|
||||
VWSUBUVX X10, V2, V3 // d76125ca
|
||||
VWSUBUVX X10, V2, V0, V3 // d76125c8
|
||||
VWADDVV V1, V2, V3 // d7a120c6
|
||||
VWADDVV V1, V2, V0, V3 // d7a120c4
|
||||
VWADDVX X10, V2, V3 // d76125c6
|
||||
VWADDVX X10, V2, V0, V3 // d76125c4
|
||||
VWSUBVV V1, V2, V3 // d7a120ce
|
||||
VWSUBVV V1, V2, V0, V3 // d7a120cc
|
||||
VWSUBVX X10, V2, V3 // d76125ce
|
||||
VWSUBVX X10, V2, V0, V3 // d76125cc
|
||||
VWADDUWV V1, V2, V3 // d7a120d2
|
||||
VWADDUWV V1, V2, V0, V3 // d7a120d0
|
||||
VWADDUWX X10, V2, V3 // d76125d2
|
||||
VWADDUWX X10, V2, V0, V3 // d76125d0
|
||||
VWSUBUWV V1, V2, V3 // d7a120da
|
||||
VWSUBUWV V1, V2, V0, V3 // d7a120d8
|
||||
VWSUBUWX X10, V2, V3 // d76125da
|
||||
VWSUBUWX X10, V2, V0, V3 // d76125d8
|
||||
VWADDWV V1, V2, V3 // d7a120d6
|
||||
VWADDWV V1, V2, V0, V3 // d7a120d4
|
||||
VWADDWX X10, V2, V3 // d76125d6
|
||||
VWADDWX X10, V2, V0, V3 // d76125d4
|
||||
VWSUBWV V1, V2, V3 // d7a120de
|
||||
VWSUBWV V1, V2, V0, V3 // d7a120dc
|
||||
VWSUBWX X10, V2, V3 // d76125de
|
||||
VWSUBWX X10, V2, V0, V3 // d76125dc
|
||||
VWCVTXXV V2, V3 // d76120c6
|
||||
VWCVTXXV V2, V0, V3 // d76120c4
|
||||
VWCVTUXXV V2, V3 // d76120c2
|
||||
VWCVTUXXV V2, V0, V3 // d76120c0
|
||||
|
||||
// 31.11.3: Vector Integer Extension
|
||||
VZEXTVF2 V2, V3 // d721234a
|
||||
VZEXTVF2 V2, V0, V3 // d7212348
|
||||
VSEXTVF2 V2, V3 // d7a1234a
|
||||
VSEXTVF2 V2, V0, V3 // d7a12348
|
||||
VZEXTVF4 V2, V3 // d721224a
|
||||
VZEXTVF4 V2, V0, V3 // d7212248
|
||||
VSEXTVF4 V2, V3 // d7a1224a
|
||||
VSEXTVF4 V2, V0, V3 // d7a12248
|
||||
VZEXTVF8 V2, V3 // d721214a
|
||||
VZEXTVF8 V2, V0, V3 // d7212148
|
||||
VSEXTVF8 V2, V3 // d7a1214a
|
||||
VSEXTVF8 V2, V0, V3 // d7a12148
|
||||
|
||||
// 31.11.4: Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
|
||||
VADCVVM V1, V2, V0, V3 // d7812040
|
||||
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
|
||||
VANDVV V1, V2, V0, V3 // d7812024
|
||||
VANDVX X11, V2, V3 // d7c12526
|
||||
VANDVX X11, V2, V0, V3 // d7c12524
|
||||
VANDVI $15, V2, V3 // d7b12726
|
||||
VANDVI $15, V2, V0, V3 // d7b12724
|
||||
VORVV V1, V2, V3 // d781202a
|
||||
VORVV V1, V2, V0, V3 // d7812028
|
||||
VORVX X11, V2, V3 // d7c1252a
|
||||
VORVX X11, V2, V0, V3 // d7c12528
|
||||
VORVI $15, V2, V3 // d7b1272a
|
||||
VORVI $15, V2, V0, V3 // d7b12728
|
||||
VXORVV V1, V2, V3 // d781202e
|
||||
VXORVV V1, V2, V0, V3 // d781202c
|
||||
VXORVX X11, V2, V3 // d7c1252e
|
||||
VXORVX X11, V2, V0, V3 // d7c1252c
|
||||
VXORVI $15, V2, V3 // d7b1272e
|
||||
VXORVI $15, V2, V0, V3 // d7b1272c
|
||||
VNOTV V2, V3 // d7b12f2e
|
||||
VNOTV V2, V0, V3 // d7b12f2c
|
||||
|
||||
// 31.11.6: Vector Single-Width Shift Instructions
|
||||
VSLLVV V1, V2, V3 // d7812096
|
||||
VSLLVV V1, V2, V0, V3 // d7812094
|
||||
VSLLVX X11, V2, V3 // d7c12596
|
||||
VSLLVX X11, V2, V0, V3 // d7c12594
|
||||
VSLLVI $15, V2, V3 // d7b12796
|
||||
VSLLVI $15, V2, V0, V3 // d7b12794
|
||||
VSRLVV V1, V2, V3 // d78120a2
|
||||
VSRLVV V1, V2, V0, V3 // d78120a0
|
||||
VSRLVX X11, V2, V3 // d7c125a2
|
||||
VSRLVX X11, V2, V0, V3 // d7c125a0
|
||||
VSRLVI $15, V2, V3 // d7b127a2
|
||||
VSRLVI $15, V2, V0, V3 // d7b127a0
|
||||
VSRAVV V1, V2, V3 // d78120a6
|
||||
VSRAVV V1, V2, V0, V3 // d78120a4
|
||||
VSRAVX X11, V2, V3 // d7c125a6
|
||||
VSRAVX X11, V2, V0, V3 // d7c125a4
|
||||
VSRAVI $15, V2, V3 // d7b127a6
|
||||
VSRAVI $15, V2, V0, V3 // d7b127a4
|
||||
|
||||
// 31.11.7: Vector Narrowing Integer Right Shift Instructions
|
||||
VNSRLWV V1, V2, V3 // d78120b2
|
||||
VNSRLWV V1, V2, V0, V3 // d78120b0
|
||||
VNSRLWX X10, V2, V3 // d74125b2
|
||||
VNSRLWX X10, V2, V0, V3 // d74125b0
|
||||
VNSRLWI $31, V2, V3 // d7b12fb2
|
||||
VNSRLWI $31, V2, V0, V3 // d7b12fb0
|
||||
VNSRAWV V1, V2, V3 // d78120b6
|
||||
VNSRAWV V1, V2, V0, V3 // d78120b4
|
||||
VNSRAWX X10, V2, V3 // d74125b6
|
||||
VNSRAWX X10, V2, V0, V3 // d74125b4
|
||||
VNSRAWI $31, V2, V3 // d7b12fb6
|
||||
VNSRAWI $31, V2, V0, V3 // d7b12fb4
|
||||
VNCVTXXW V2, V3 // d74120b2
|
||||
VNCVTXXW V2, V0, V3 // d74120b0
|
||||
|
||||
// 31.11.8: Vector Integer Compare Instructions
|
||||
VMSEQVV V1, V2, V3 // d7812062
|
||||
VMSEQVV V1, V2, V0, V3 // d7812060
|
||||
VMSEQVX X10, V2, V3 // d7412562
|
||||
VMSEQVX X10, V2, V0, V3 // d7412560
|
||||
VMSEQVI $15, V2, V3 // d7b12762
|
||||
VMSEQVI $15, V2, V0, V3 // d7b12760
|
||||
VMSNEVV V1, V2, V3 // d7812066
|
||||
VMSNEVV V1, V2, V0, V3 // d7812064
|
||||
VMSNEVX X10, V2, V3 // d7412566
|
||||
VMSNEVX X10, V2, V0, V3 // d7412564
|
||||
VMSNEVI $15, V2, V3 // d7b12766
|
||||
VMSNEVI $15, V2, V0, V3 // d7b12764
|
||||
VMSLTUVV V1, V2, V3 // d781206a
|
||||
VMSLTUVV V1, V2, V0, V3 // d7812068
|
||||
VMSLTUVX X10, V2, V3 // d741256a
|
||||
VMSLTUVX X10, V2, V0, V3 // d7412568
|
||||
VMSLTVV V1, V2, V3 // d781206e
|
||||
VMSLTVV V1, V2, V0, V3 // d781206c
|
||||
VMSLTVX X10, V2, V3 // d741256e
|
||||
VMSLTVX X10, V2, V0, V3 // d741256c
|
||||
VMSLEUVV V1, V2, V3 // d7812072
|
||||
VMSLEUVV V1, V2, V0, V3 // d7812070
|
||||
VMSLEUVX X10, V2, V3 // d7412572
|
||||
VMSLEUVX X10, V2, V0, V3 // d7412570
|
||||
VMSLEUVI $15, V2, V3 // d7b12772
|
||||
VMSLEUVI $15, V2, V0, V3 // d7b12770
|
||||
VMSLEVV V1, V2, V3 // d7812076
|
||||
VMSLEVV V1, V2, V0, V3 // d7812074
|
||||
VMSLEVX X10, V2, V3 // d7412576
|
||||
VMSLEVX X10, V2, V0, V3 // d7412574
|
||||
VMSLEVI $15, V2, V3 // d7b12776
|
||||
VMSLEVI $15, V2, V0, V3 // d7b12774
|
||||
VMSGTUVX X10, V2, V3 // d741257a
|
||||
VMSGTUVX X10, V2, V0, V3 // d7412578
|
||||
VMSGTUVI $15, V2, V3 // d7b1277a
|
||||
VMSGTUVI $15, V2, V0, V3 // d7b12778
|
||||
VMSGTVX X10, V2, V3 // d741257e
|
||||
VMSGTVX X10, V2, V0, V3 // d741257c
|
||||
VMSGTVI $15, V2, V3 // d7b1277e
|
||||
VMSGTVI $15, V2, V0, V3 // d7b1277c
|
||||
VMSGTVV V1, V2, V3 // d701116e
|
||||
VMSGTVV V1, V2, V0, V3 // d701116c
|
||||
VMSGTUVV V1, V2, V3 // d701116a
|
||||
VMSGTUVV V1, V2, V0, V3 // d7011168
|
||||
VMSGEVV V1, V2, V3 // d7011176
|
||||
VMSGEVV V1, V2, V0, V3 // d7011174
|
||||
VMSGEUVV V1, V2, V3 // d7011172
|
||||
VMSGEUVV V1, V2, V0, V3 // d7011170
|
||||
VMSLTVI $15, V2, V3 // d7312776
|
||||
VMSLTVI $15, V2, V0, V3 // d7312774
|
||||
VMSLTUVI $15, V2, V3 // d7312772
|
||||
VMSLTUVI $15, V2, V0, V3 // d7312770
|
||||
VMSGEVI $15, V2, V3 // d731277e
|
||||
VMSGEVI $15, V2, V0, V3 // d731277c
|
||||
VMSGEUVI $15, V2, V3 // d731277a
|
||||
VMSGEUVI $15, V2, V0, V3 // d7312778
|
||||
|
||||
// 31.11.9: Vector Integer Min/Max Instructions
|
||||
VMINUVV V1, V2, V3 // d7812012
|
||||
VMINUVV V1, V2, V0, V3 // d7812010
|
||||
VMINUVX X10, V2, V3 // d7412512
|
||||
VMINUVX X10, V2, V0, V3 // d7412510
|
||||
VMINVV V1, V2, V3 // d7812016
|
||||
VMINVV V1, V2, V0, V3 // d7812014
|
||||
VMINVX X10, V2, V3 // d7412516
|
||||
VMINVX X10, V2, V0, V3 // d7412514
|
||||
VMAXUVV V1, V2, V3 // d781201a
|
||||
VMAXUVV V1, V2, V0, V3 // d7812018
|
||||
VMAXUVX X10, V2, V3 // d741251a
|
||||
VMAXUVX X10, V2, V0, V3 // d7412518
|
||||
VMAXVV V1, V2, V3 // d781201e
|
||||
VMAXVV V1, V2, V0, V3 // d781201c
|
||||
VMAXVX X10, V2, V3 // d741251e
|
||||
VMAXVX X10, V2, V0, V3 // d741251c
|
||||
|
||||
// 31.11.10: Vector Single-Width Integer Multiply Instructions
|
||||
VMULVV V1, V2, V3 // d7a12096
|
||||
VMULVV V1, V2, V0, V3 // d7a12094
|
||||
VMULVX X10, V2, V3 // d7612596
|
||||
VMULVX X10, V2, V0, V3 // d7612594
|
||||
VMULHVV V1, V2, V3 // d7a1209e
|
||||
VMULHVV V1, V2, V0, V3 // d7a1209c
|
||||
VMULHVX X10, V2, V3 // d761259e
|
||||
VMULHVX X10, V2, V0, V3 // d761259c
|
||||
VMULHUVV V1, V2, V3 // d7a12092
|
||||
VMULHUVV V1, V2, V0, V3 // d7a12090
|
||||
VMULHUVX X10, V2, V3 // d7612592
|
||||
VMULHUVX X10, V2, V0, V3 // d7612590
|
||||
VMULHSUVV V1, V2, V3 // d7a1209a
|
||||
VMULHSUVV V1, V2, V0, V3 // d7a12098
|
||||
VMULHSUVX X10, V2, V3 // d761259a
|
||||
VMULHSUVX X10, V2, V0, V3 // d7612598
|
||||
|
||||
// 31.11.11: Vector Integer Divide Instructions
|
||||
VDIVUVV V1, V2, V3 // d7a12082
|
||||
VDIVUVV V1, V2, V0, V3 // d7a12080
|
||||
VDIVUVX X10, V2, V3 // d7612582
|
||||
VDIVUVX X10, V2, V0, V3 // d7612580
|
||||
VDIVVV V1, V2, V3 // d7a12086
|
||||
VDIVVV V1, V2, V0, V3 // d7a12084
|
||||
VDIVVX X10, V2, V3 // d7612586
|
||||
VDIVVX X10, V2, V0, V3 // d7612584
|
||||
VREMUVV V1, V2, V3 // d7a1208a
|
||||
VREMUVV V1, V2, V0, V3 // d7a12088
|
||||
VREMUVX X10, V2, V3 // d761258a
|
||||
VREMUVX X10, V2, V0, V3 // d7612588
|
||||
VREMVV V1, V2, V3 // d7a1208e
|
||||
VREMVV V1, V2, V0, V3 // d7a1208c
|
||||
VREMVX X10, V2, V3 // d761258e
|
||||
VREMVX X10, V2, V0, V3 // d761258c
|
||||
|
||||
// 31.11.12: Vector Widening Integer Multiply Instructions
|
||||
VWMULVV V1, V2, V3 // d7a120ee
|
||||
VWMULVV V1, V2, V0, V3 // d7a120ec
|
||||
VWMULVX X10, V2, V3 // d76125ee
|
||||
VWMULVX X10, V2, V0, V3 // d76125ec
|
||||
VWMULUVV V1, V2, V3 // d7a120e2
|
||||
VWMULUVV V1, V2, V0, V3 // d7a120e0
|
||||
VWMULUVX X10, V2, V3 // d76125e2
|
||||
VWMULUVX X10, V2, V0, V3 // d76125e0
|
||||
VWMULSUVV V1, V2, V3 // d7a120ea
|
||||
VWMULSUVV V1, V2, V0, V3 // d7a120e8
|
||||
VWMULSUVX X10, V2, V3 // d76125ea
|
||||
VWMULSUVX X10, V2, V0, V3 // d76125e8
|
||||
|
||||
// 31.11.13: Vector Single-Width Integer Multiply-Add Instructions
|
||||
VMACCVV V2, V1, V3 // d7a120b6
|
||||
VMACCVV V2, V1, V0, V3 // d7a120b4
|
||||
VMACCVX V2, X10, V3 // d76125b6
|
||||
VMACCVX V2, X10, V0, V3 // d76125b4
|
||||
VNMSACVV V2, V1, V3 // d7a120be
|
||||
VNMSACVV V2, V1, V0, V3 // d7a120bc
|
||||
VNMSACVX V2, X10, V3 // d76125be
|
||||
VNMSACVX V2, X10, V0, V3 // d76125bc
|
||||
VMADDVV V2, V1, V3 // d7a120a6
|
||||
VMADDVV V2, V1, V0, V3 // d7a120a4
|
||||
VMADDVX V2, X10, V3 // d76125a6
|
||||
VMADDVX V2, X10, V0, V3 // d76125a4
|
||||
VNMSUBVV V2, V1, V3 // d7a120ae
|
||||
VNMSUBVV V2, V1, V0, V3 // d7a120ac
|
||||
VNMSUBVX V2, X10, V3 // d76125ae
|
||||
VNMSUBVX V2, X10, V0, V3 // d76125ac
|
||||
|
||||
// 31.11.14: Vector Widening Integer Multiply-Add Instructions
|
||||
VWMACCUVV V2, V1, V3 // d7a120f2
|
||||
VWMACCUVV V2, V1, V0, V3 // d7a120f0
|
||||
VWMACCUVX V2, X10, V3 // d76125f2
|
||||
VWMACCUVX V2, X10, V0, V3 // d76125f0
|
||||
VWMACCVV V2, V1, V3 // d7a120f6
|
||||
VWMACCVV V2, V1, V0, V3 // d7a120f4
|
||||
VWMACCVX V2, X10, V3 // d76125f6
|
||||
VWMACCVX V2, X10, V0, V3 // d76125f4
|
||||
VWMACCSUVV V2, V1, V3 // d7a120fe
|
||||
VWMACCSUVV V2, V1, V0, V3 // d7a120fc
|
||||
VWMACCSUVX V2, X10, V3 // d76125fe
|
||||
VWMACCSUVX V2, X10, V0, V3 // d76125fc
|
||||
VWMACCUSVX V2, X10, V3 // d76125fa
|
||||
VWMACCUSVX V2, X10, V0, V3 // d76125f8
|
||||
|
||||
// 31.11.15: Vector Integer Merge Instructions
|
||||
VMERGEVVM V1, V2, V0, V3 // d781205c
|
||||
VMERGEVXM X10, V2, V0, V3 // d741255c
|
||||
VMERGEVIM $15, V2, V0, V3 // d7b1275c
|
||||
|
||||
// 31.11.16: Vector Integer Move Instructions
|
||||
VMVVV V2, V3 // d701015e
|
||||
VMVVX X10, V3 // d741055e
|
||||
VMVVI $15, V3 // d7b1075e
|
||||
|
||||
// 31.12.1: Vector Single-Width Saturating Add and Subtract
|
||||
VSADDUVV V1, V2, V3 // d7812082
|
||||
VSADDUVV V1, V2, V0, V3 // d7812080
|
||||
VSADDUVX X10, V2, V3 // d7412582
|
||||
VSADDUVX X10, V2, V0, V3 // d7412580
|
||||
VSADDUVI $15, V2, V3 // d7b12782
|
||||
VSADDUVI $15, V2, V0, V3 // d7b12780
|
||||
VSADDVV V1, V2, V3 // d7812086
|
||||
VSADDVV V1, V2, V0, V3 // d7812084
|
||||
VSADDVX X10, V2, V3 // d7412586
|
||||
VSADDVX X10, V2, V0, V3 // d7412584
|
||||
VSADDVI $15, V2, V3 // d7b12786
|
||||
VSADDVI $15, V2, V0, V3 // d7b12784
|
||||
VSSUBUVV V1, V2, V3 // d781208a
|
||||
VSSUBUVV V1, V2, V0, V3 // d7812088
|
||||
VSSUBUVX X10, V2, V3 // d741258a
|
||||
VSSUBUVX X10, V2, V0, V3 // d7412588
|
||||
VSSUBVV V1, V2, V3 // d781208e
|
||||
VSSUBVV V1, V2, V0, V3 // d781208c
|
||||
VSSUBVX X10, V2, V3 // d741258e
|
||||
VSSUBVX X10, V2, V0, V3 // d741258c
|
||||
|
||||
// 31.12.2: Vector Single-Width Averaging Add and Subtract
|
||||
VAADDUVV V1, V2, V3 // d7a12022
|
||||
VAADDUVV V1, V2, V0, V3 // d7a12020
|
||||
VAADDUVX X10, V2, V3 // d7612522
|
||||
VAADDUVX X10, V2, V0, V3 // d7612520
|
||||
VAADDVV V1, V2, V3 // d7a12026
|
||||
VAADDVV V1, V2, V0, V3 // d7a12024
|
||||
VAADDVX X10, V2, V3 // d7612526
|
||||
VAADDVX X10, V2, V0, V3 // d7612524
|
||||
VASUBUVV V1, V2, V3 // d7a1202a
|
||||
VASUBUVV V1, V2, V0, V3 // d7a12028
|
||||
VASUBUVX X10, V2, V3 // d761252a
|
||||
VASUBUVX X10, V2, V0, V3 // d7612528
|
||||
VASUBVV V1, V2, V3 // d7a1202e
|
||||
VASUBVV V1, V2, V0, V3 // d7a1202c
|
||||
VASUBVX X10, V2, V3 // d761252e
|
||||
VASUBVX X10, V2, V0, V3 // d761252c
|
||||
|
||||
// 31.12.3: Vector Single-Width Fractional Multiply with Rounding and Saturation
|
||||
VSMULVV V1, V2, V3 // d781209e
|
||||
VSMULVV V1, V2, V0, V3 // d781209c
|
||||
VSMULVX X10, V2, V3 // d741259e
|
||||
VSMULVX X10, V2, V0, V3 // d741259c
|
||||
|
||||
// 31.12.4: Vector Single-Width Scaling Shift Instructions
|
||||
VSSRLVV V1, V2, V3 // d78120aa
|
||||
VSSRLVV V1, V2, V0, V3 // d78120a8
|
||||
VSSRLVX X10, V2, V3 // d74125aa
|
||||
VSSRLVX X10, V2, V0, V3 // d74125a8
|
||||
VSSRLVI $15, V2, V3 // d7b127aa
|
||||
VSSRLVI $15, V2, V0, V3 // d7b127a8
|
||||
VSSRAVV V1, V2, V3 // d78120ae
|
||||
VSSRAVV V1, V2, V0, V3 // d78120ac
|
||||
VSSRAVX X10, V2, V3 // d74125ae
|
||||
VSSRAVX X10, V2, V0, V3 // d74125ac
|
||||
VSSRAVI $16, V2, V3 // d73128ae
|
||||
VSSRAVI $16, V2, V0, V3 // d73128ac
|
||||
|
||||
// 31.12.5: Vector Narrowing Fixed-Point Clip Instructions
|
||||
VNCLIPUWV V1, V2, V3 // d78120ba
|
||||
VNCLIPUWV V1, V2, V0, V3 // d78120b8
|
||||
VNCLIPUWX X10, V2, V3 // d74125ba
|
||||
VNCLIPUWX X10, V2, V0, V3 // d74125b8
|
||||
VNCLIPUWI $16, V2, V3 // d73128ba
|
||||
VNCLIPUWI $16, V2, V0, V3 // d73128b8
|
||||
VNCLIPWV V1, V2, V3 // d78120be
|
||||
VNCLIPWV V1, V2, V0, V3 // d78120bc
|
||||
VNCLIPWX X10, V2, V3 // d74125be
|
||||
VNCLIPWX X10, V2, V0, V3 // d74125bc
|
||||
VNCLIPWI $16, V2, V3 // d73128be
|
||||
VNCLIPWI $16, V2, V0, V3 // d73128bc
|
||||
|
||||
// 31.13.2: Vector Single-Width Floating-Point Add/Subtract Instructions
|
||||
VFADDVV V1, V2, V3 // d7912002
|
||||
VFADDVV V1, V2, V0, V3 // d7912000
|
||||
VFADDVF F10, V2, V3 // d7512502
|
||||
VFADDVF F10, V2, V0, V3 // d7512500
|
||||
VFSUBVV V1, V2, V3 // d791200a
|
||||
VFSUBVV V1, V2, V0, V3 // d7912008
|
||||
VFSUBVF F10, V2, V3 // d751250a
|
||||
VFSUBVF F10, V2, V0, V3 // d7512508
|
||||
VFRSUBVF F10, V2, V3 // d751259e
|
||||
VFRSUBVF F10, V2, V0, V3 // d751259c
|
||||
|
||||
// 31.13.3: Vector Widening Floating-Point Add/Subtract Instructions
|
||||
VFWADDVV V1, V2, V3 // d79120c2
|
||||
VFWADDVV V1, V2, V0, V3 // d79120c0
|
||||
VFWADDVF F10, V2, V3 // d75125c2
|
||||
VFWADDVF F10, V2, V0, V3 // d75125c0
|
||||
VFWSUBVV V1, V2, V3 // d79120ca
|
||||
VFWSUBVV V1, V2, V0, V3 // d79120c8
|
||||
VFWSUBVF F10, V2, V3 // d75125ca
|
||||
VFWSUBVF F10, V2, V0, V3 // d75125c8
|
||||
VFWADDWV V1, V2, V3 // d79120d2
|
||||
VFWADDWV V1, V2, V0, V3 // d79120d0
|
||||
VFWADDWF F10, V2, V3 // d75125d2
|
||||
VFWADDWF F10, V2, V0, V3 // d75125d0
|
||||
VFWSUBWV V1, V2, V3 // d79120da
|
||||
VFWSUBWV V1, V2, V0, V3 // d79120d8
|
||||
VFWSUBWF F10, V2, V3 // d75125da
|
||||
VFWSUBWF F10, V2, V0, V3 // d75125d8
|
||||
|
||||
// 31.13.4: Vector Single-Width Floating-Point Multiply/Divide Instructions
|
||||
VFMULVV V1, V2, V3 // d7912092
|
||||
VFMULVV V1, V2, V0, V3 // d7912090
|
||||
VFMULVF F10, V2, V3 // d7512592
|
||||
VFMULVF F10, V2, V0, V3 // d7512590
|
||||
VFDIVVV V1, V2, V3 // d7912082
|
||||
VFDIVVV V1, V2, V0, V3 // d7912080
|
||||
VFDIVVF F10, V2, V3 // d7512582
|
||||
VFDIVVF F10, V2, V0, V3 // d7512580
|
||||
VFRDIVVF F10, V2, V3 // d7512586
|
||||
VFRDIVVF F10, V2, V0, V3 // d7512584
|
||||
|
||||
// 31.13.5: Vector Widening Floating-Point Multiply
|
||||
VFWMULVV V1, V2, V3 // d79120e2
|
||||
VFWMULVV V1, V2, V0, V3 // d79120e0
|
||||
VFWMULVF F10, V2, V3 // d75125e2
|
||||
VFWMULVF F10, V2, V0, V3 // d75125e0
|
||||
|
||||
// 31.13.6: Vector Single-Width Floating-Point Fused Multiply-Add Instructions
|
||||
VFMACCVV V2, V1, V3 // d79120b2
|
||||
VFMACCVV V2, V1, V0, V3 // d79120b0
|
||||
VFMACCVF V2, F10, V3 // d75125b2
|
||||
VFMACCVF V2, F10, V0, V3 // d75125b0
|
||||
VFNMACCVV V2, V1, V3 // d79120b6
|
||||
VFNMACCVV V2, V1, V0, V3 // d79120b4
|
||||
VFNMACCVF V2, F10, V3 // d75125b6
|
||||
VFNMACCVF V2, F10, V0, V3 // d75125b4
|
||||
VFMSACVV V2, V1, V3 // d79120ba
|
||||
VFMSACVV V2, V1, V0, V3 // d79120b8
|
||||
VFMSACVF V2, F10, V3 // d75125ba
|
||||
VFMSACVF V2, F10, V0, V3 // d75125b8
|
||||
VFNMSACVV V2, V1, V3 // d79120be
|
||||
VFNMSACVV V2, V1, V0, V3 // d79120bc
|
||||
VFNMSACVF V2, F10, V3 // d75125be
|
||||
VFNMSACVF V2, F10, V0, V3 // d75125bc
|
||||
VFMADDVV V2, V1, V3 // d79120a2
|
||||
VFMADDVV V2, V1, V0, V3 // d79120a0
|
||||
VFMADDVF V2, F10, V3 // d75125a2
|
||||
VFMADDVF V2, F10, V0, V3 // d75125a0
|
||||
VFNMADDVV V2, V1, V3 // d79120a6
|
||||
VFNMADDVV V2, V1, V0, V3 // d79120a4
|
||||
VFNMADDVF V2, F10, V3 // d75125a6
|
||||
VFNMADDVF V2, F10, V0, V3 // d75125a4
|
||||
VFMSUBVV V2, V1, V3 // d79120aa
|
||||
VFMSUBVV V2, V1, V0, V3 // d79120a8
|
||||
VFMSUBVF V2, F10, V3 // d75125aa
|
||||
VFMSUBVF V2, F10, V0, V3 // d75125a8
|
||||
VFNMSUBVV V2, V1, V3 // d79120ae
|
||||
VFNMSUBVV V2, V1, V0, V3 // d79120ac
|
||||
VFNMSUBVF V2, F10, V3 // d75125ae
|
||||
VFNMSUBVF V2, F10, V0, V3 // d75125ac
|
||||
|
||||
// 31.13.7: Vector Widening Floating-Point Fused Multiply-Add Instructions
|
||||
VFWMACCVV V2, V1, V3 // d79120f2
|
||||
VFWMACCVV V2, V1, V0, V3 // d79120f0
|
||||
VFWMACCVF V2, F10, V3 // d75125f2
|
||||
VFWMACCVF V2, F10, V0, V3 // d75125f0
|
||||
VFWNMACCVV V2, V1, V3 // d79120f6
|
||||
VFWNMACCVV V2, V1, V0, V3 // d79120f4
|
||||
VFWNMACCVF V2, F10, V3 // d75125f6
|
||||
VFWNMACCVF V2, F10, V0, V3 // d75125f4
|
||||
VFWMSACVV V2, V1, V3 // d79120fa
|
||||
VFWMSACVV V2, V1, V0, V3 // d79120f8
|
||||
VFWMSACVF V2, F10, V3 // d75125fa
|
||||
VFWMSACVF V2, F10, V0, V3 // d75125f8
|
||||
VFWNMSACVV V2, V1, V3 // d79120fe
|
||||
VFWNMSACVV V2, V1, V0, V3 // d79120fc
|
||||
VFWNMSACVF V2, F10, V3 // d75125fe
|
||||
VFWNMSACVF V2, F10, V0, V3 // d75125fc
|
||||
|
||||
// 31.13.8: Vector Floating-Point Square-Root Instruction
|
||||
VFSQRTV V2, V3 // d711204e
|
||||
VFSQRTV V2, V0, V3 // d711204c
|
||||
|
||||
// 31.13.9: Vector Floating-Point Reciprocal Square-Root Estimate Instruction
|
||||
VFRSQRT7V V2, V3 // d711224e
|
||||
VFRSQRT7V V2, V0, V3 // d711224c
|
||||
|
||||
// 31.13.10: Vector Floating-Point Reciprocal Estimate Instruction
|
||||
VFREC7V V2, V3 // d791224e
|
||||
VFREC7V V2, V0, V3 // d791224c
|
||||
|
||||
// 31.13.11: Vector Floating-Point MIN/MAX Instructions
|
||||
VFMINVV V1, V2, V3 // d7912012
|
||||
VFMINVV V1, V2, V0, V3 // d7912010
|
||||
VFMINVF F10, V2, V3 // d7512512
|
||||
VFMINVF F10, V2, V0, V3 // d7512510
|
||||
VFMAXVV V1, V2, V3 // d791201a
|
||||
VFMAXVV V1, V2, V0, V3 // d7912018
|
||||
VFMAXVF F10, V2, V3 // d751251a
|
||||
VFMAXVF F10, V2, V0, V3 // d7512518
|
||||
|
||||
// 31.13.12: Vector Floating-Point Sign-Injection Instructions
|
||||
VFSGNJVV V1, V2, V3 // d7912022
|
||||
VFSGNJVV V1, V2, V0, V3 // d7912020
|
||||
VFSGNJVF F10, V2, V3 // d7512522
|
||||
VFSGNJVF F10, V2, V0, V3 // d7512520
|
||||
VFSGNJNVV V1, V2, V3 // d7912026
|
||||
VFSGNJNVV V1, V2, V0, V3 // d7912024
|
||||
VFSGNJNVF F10, V2, V3 // d7512526
|
||||
VFSGNJNVF F10, V2, V0, V3 // d7512524
|
||||
VFSGNJXVV V1, V2, V3 // d791202a
|
||||
VFSGNJXVV V1, V2, V0, V3 // d7912028
|
||||
VFSGNJXVF F10, V2, V3 // d751252a
|
||||
VFSGNJXVF F10, V2, V0, V3 // d7512528
|
||||
VFNEGV V2, V3 // d7112126
|
||||
VFNEGV V2, V0, V3 // d7112124
|
||||
VFABSV V2, V3 // d711212a
|
||||
VFABSV V2, V0, V3 // d7112128
|
||||
|
||||
// 31.13.13: Vector Floating-Point Compare Instructions
|
||||
VMFEQVV V1, V2, V3 // d7912062
|
||||
VMFEQVV V1, V2, V0, V3 // d7912060
|
||||
VMFEQVF F10, V2, V3 // d7512562
|
||||
VMFEQVF F10, V2, V0, V3 // d7512560
|
||||
VMFNEVV V1, V2, V3 // d7912072
|
||||
VMFNEVV V1, V2, V0, V3 // d7912070
|
||||
VMFNEVF F10, V2, V3 // d7512572
|
||||
VMFNEVF F10, V2, V0, V3 // d7512570
|
||||
VMFLTVV V1, V2, V3 // d791206e
|
||||
VMFLTVV V1, V2, V0, V3 // d791206c
|
||||
VMFLTVF F10, V2, V3 // d751256e
|
||||
VMFLTVF F10, V2, V0, V3 // d751256c
|
||||
VMFLEVV V1, V2, V3 // d7912066
|
||||
VMFLEVV V1, V2, V0, V3 // d7912064
|
||||
VMFLEVF F10, V2, V3 // d7512566
|
||||
VMFLEVF F10, V2, V0, V3 // d7512564
|
||||
VMFGTVF F10, V2, V3 // d7512576
|
||||
VMFGTVF F10, V2, V0, V3 // d7512574
|
||||
VMFGEVF F10, V2, V3 // d751257e
|
||||
VMFGEVF F10, V2, V0, V3 // d751257c
|
||||
VMFGTVV V1, V2, V3 // d711116e
|
||||
VMFGTVV V1, V2, V0, V3 // d711116c
|
||||
VMFGEVV V1, V2, V3 // d7111166
|
||||
VMFGEVV V1, V2, V0, V3 // d7111164
|
||||
|
||||
// 31.13.14: Vector Floating-Point Classify Instruction
|
||||
VFCLASSV V2, V3 // d711284e
|
||||
VFCLASSV V2, V0, V3 // d711284c
|
||||
|
||||
// 31.13.15: Vector Floating-Point Merge Instruction
|
||||
VFMERGEVFM F10, V2, V0, V3 // d751255c
|
||||
|
||||
// 31.13.16: Vector Floating-Point Move Instruction
|
||||
VFMVVF F10, V3 // d751055e
|
||||
|
||||
// 31.13.17: Single-Width Floating-Point/Integer Type-Convert Instructions
|
||||
VFCVTXUFV V2, V3 // d711204a
|
||||
VFCVTXUFV V2, V0, V3 // d7112048
|
||||
VFCVTXFV V2, V3 // d791204a
|
||||
VFCVTXFV V2, V0, V3 // d7912048
|
||||
VFCVTRTZXUFV V2, V3 // d711234a
|
||||
VFCVTRTZXUFV V2, V0, V3 // d7112348
|
||||
VFCVTRTZXFV V2, V3 // d791234a
|
||||
VFCVTRTZXFV V2, V0, V3 // d7912348
|
||||
VFCVTFXUV V2, V3 // d711214a
|
||||
VFCVTFXUV V2, V0, V3 // d7112148
|
||||
VFCVTFXV V2, V3 // d791214a
|
||||
VFCVTFXV V2, V0, V3 // d7912148
|
||||
|
||||
// 31.13.18: Widening Floating-Point/Integer Type-Convert Instructions
|
||||
VFWCVTXUFV V2, V3 // d711244a
|
||||
VFWCVTXUFV V2, V0, V3 // d7112448
|
||||
VFWCVTXFV V2, V3 // d791244a
|
||||
VFWCVTXFV V2, V0, V3 // d7912448
|
||||
VFWCVTRTZXUFV V2, V3 // d711274a
|
||||
VFWCVTRTZXUFV V2, V0, V3 // d7112748
|
||||
VFWCVTRTZXFV V2, V3 // d791274a
|
||||
VFWCVTRTZXFV V2, V0, V3 // d7912748
|
||||
VFWCVTFXUV V2, V3 // d711254a
|
||||
VFWCVTFXUV V2, V0, V3 // d7112548
|
||||
VFWCVTFXV V2, V3 // d791254a
|
||||
VFWCVTFXV V2, V0, V3 // d7912548
|
||||
VFWCVTFFV V2, V3 // d711264a
|
||||
VFWCVTFFV V2, V0, V3 // d7112648
|
||||
|
||||
// 31.13.19: Narrowing Floating-Point/Integer Type-Convert Instructions
|
||||
VFNCVTXUFW V2, V3 // d711284a
|
||||
VFNCVTXUFW V2, V0, V3 // d7112848
|
||||
VFNCVTXFW V2, V3 // d791284a
|
||||
VFNCVTXFW V2, V0, V3 // d7912848
|
||||
VFNCVTRTZXUFW V2, V3 // d7112b4a
|
||||
VFNCVTRTZXUFW V2, V0, V3 // d7112b48
|
||||
VFNCVTRTZXFW V2, V3 // d7912b4a
|
||||
VFNCVTRTZXFW V2, V0, V3 // d7912b48
|
||||
VFNCVTFXUW V2, V3 // d711294a
|
||||
VFNCVTFXUW V2, V0, V3 // d7112948
|
||||
VFNCVTFXW V2, V3 // d791294a
|
||||
VFNCVTFXW V2, V0, V3 // d7912948
|
||||
VFNCVTFFW V2, V3 // d7112a4a
|
||||
VFNCVTFFW V2, V0, V3 // d7112a48
|
||||
VFNCVTRODFFW V2, V3 // d7912a4a
|
||||
VFNCVTRODFFW V2, V0, V3 // d7912a48
|
||||
|
||||
// 31.14.1: Vector Single-Width Integer Reduction Instructions
|
||||
VREDSUMVS V1, V2, V3 // d7a12002
|
||||
VREDSUMVS V1, V2, V0, V3 // d7a12000
|
||||
VREDMAXUVS V1, V2, V3 // d7a1201a
|
||||
VREDMAXUVS V1, V2, V0, V3 // d7a12018
|
||||
VREDMAXVS V1, V2, V3 // d7a1201e
|
||||
VREDMAXVS V1, V2, V0, V3 // d7a1201c
|
||||
VREDMINUVS V1, V2, V3 // d7a12012
|
||||
VREDMINUVS V1, V2, V0, V3 // d7a12010
|
||||
VREDMINVS V1, V2, V3 // d7a12016
|
||||
VREDMINVS V1, V2, V0, V3 // d7a12014
|
||||
VREDANDVS V1, V2, V3 // d7a12006
|
||||
VREDANDVS V1, V2, V0, V3 // d7a12004
|
||||
VREDORVS V1, V2, V3 // d7a1200a
|
||||
VREDORVS V1, V2, V0, V3 // d7a12008
|
||||
VREDXORVS V1, V2, V3 // d7a1200e
|
||||
VREDXORVS V1, V2, V0, V3 // d7a1200c
|
||||
|
||||
// 31.14.2: Vector Widening Integer Reduction Instructions
|
||||
VWREDSUMUVS V1, V2, V3 // d78120c2
|
||||
VWREDSUMUVS V1, V2, V0, V3 // d78120c0
|
||||
VWREDSUMVS V1, V2, V3 // d78120c6
|
||||
VWREDSUMVS V1, V2, V0, V3 // d78120c4
|
||||
|
||||
// 31.14.3: Vector Single-Width Floating-Point Reduction Instructions
|
||||
VFREDOSUMVS V1, V2, V3 // d791200e
|
||||
VFREDOSUMVS V1, V2, V0, V3 // d791200c
|
||||
VFREDUSUMVS V1, V2, V3 // d7912006
|
||||
VFREDUSUMVS V1, V2, V0, V3 // d7912004
|
||||
VFREDMAXVS V1, V2, V3 // d791201e
|
||||
VFREDMAXVS V1, V2, V0, V3 // d791201c
|
||||
VFREDMINVS V1, V2, V3 // d7912016
|
||||
VFREDMINVS V1, V2, V0, V3 // d7912014
|
||||
|
||||
// 31.14.4: Vector Widening Floating-Point Reduction Instructions
|
||||
VFWREDOSUMVS V1, V2, V3 // d79120ce
|
||||
VFWREDOSUMVS V1, V2, V0, V3 // d79120cc
|
||||
VFWREDUSUMVS V1, V2, V3 // d79120c6
|
||||
VFWREDUSUMVS V1, V2, V0, V3 // d79120c4
|
||||
|
||||
// 31.15: Vector Mask Instructions
|
||||
VMANDMM V1, V2, V3 // d7a12066
|
||||
VMNANDMM V1, V2, V3 // d7a12076
|
||||
VMANDNMM V1, V2, V3 // d7a12062
|
||||
VMXORMM V1, V2, V3 // d7a1206e
|
||||
VMORMM V1, V2, V3 // d7a1206a
|
||||
VMNORMM V1, V2, V3 // d7a1207a
|
||||
VMORNMM V1, V2, V3 // d7a12072
|
||||
VMXNORMM V1, V2, V3 // d7a1207e
|
||||
VMMVM V2, V3 // d7212166
|
||||
VMCLRM V3 // d7a1316e
|
||||
VMSETM V3 // d7a1317e
|
||||
VMNOTM V2, V3 // d7212176
|
||||
VCPOPM V2, X10 // 57252842
|
||||
VCPOPM V2, V0, X10 // 57252840
|
||||
VFIRSTM V2, X10 // 57a52842
|
||||
VFIRSTM V2, V0, X10 // 57a52840
|
||||
VMSBFM V2, V3 // d7a12052
|
||||
VMSBFM V2, V0, V3 // d7a12050
|
||||
VMSIFM V2, V3 // d7a12152
|
||||
VMSIFM V2, V0, V3 // d7a12150
|
||||
VMSOFM V2, V3 // d7212152
|
||||
VMSOFM V2, V0, V3 // d7212150
|
||||
VIOTAM V2, V3 // d7212852
|
||||
VIOTAM V2, V0, V3 // d7212850
|
||||
VIDV V3 // d7a10852
|
||||
VIDV V0, V3 // d7a10850
|
||||
|
||||
// 31.16.1: Integer Scalar Move Instructions
|
||||
VMVXS V2, X10 // 57252042
|
||||
VMVSX X10, V2 // 57610542
|
||||
|
||||
// 31.16.2: Floating-Point Scalar Move Instructions
|
||||
VFMVFS V2, F10 // 57152042
|
||||
VFMVSF F10, V2 // 57510542
|
||||
|
||||
// 31.16.3: Vector Slide Instructions
|
||||
VSLIDEUPVX X10, V2, V3 // d741253a
|
||||
VSLIDEUPVX X10, V2, V0, V3 // d7412538
|
||||
VSLIDEUPVI $16, V2, V3 // d731283a
|
||||
VSLIDEUPVI $16, V2, V0, V3 // d7312838
|
||||
VSLIDEDOWNVX X10, V2, V3 // d741253e
|
||||
VSLIDEDOWNVX X10, V2, V0, V3 // d741253c
|
||||
VSLIDEDOWNVI $16, V2, V3 // d731283e
|
||||
VSLIDEDOWNVI $16, V2, V0, V3 // d731283c
|
||||
VSLIDE1UPVX X10, V2, V3 // d761253a
|
||||
VSLIDE1UPVX X10, V2, V0, V3 // d7612538
|
||||
VFSLIDE1UPVF F10, V2, V3 // d751253a
|
||||
VFSLIDE1UPVF F10, V2, V0, V3 // d7512538
|
||||
VSLIDE1DOWNVX X10, V2, V3 // d761253e
|
||||
VSLIDE1DOWNVX X10, V2, V0, V3 // d761253c
|
||||
VFSLIDE1DOWNVF F10, V2, V3 // d751253e
|
||||
VFSLIDE1DOWNVF F10, V2, V0, V3 // d751253c
|
||||
|
||||
// 31.16.4: Vector Register Gather Instructions
|
||||
VRGATHERVV V1, V2, V3 // d7812032
|
||||
VRGATHERVV V1, V2, V0, V3 // d7812030
|
||||
VRGATHEREI16VV V1, V2, V3 // d781203a
|
||||
VRGATHEREI16VV V1, V2, V0, V3 // d7812038
|
||||
VRGATHERVX X10, V2, V3 // d7412532
|
||||
VRGATHERVX X10, V2, V0, V3 // d7412530
|
||||
VRGATHERVI $16, V2, V3 // d7312832
|
||||
VRGATHERVI $16, V2, V0, V3 // d7312830
|
||||
|
||||
// 31.16.5: Vector Compress Instruction
|
||||
VCOMPRESSVM V1, V2, V3 // d7a1205e
|
||||
|
||||
// 31.16.6: Whole Vector Register Move
|
||||
VMV1RV V2, V1 // d730209e
|
||||
VMV2RV V12, V10 // 57b5c09e
|
||||
VMV4RV V8, V4 // 57b2819e
|
||||
VMV8RV V8, V0 // 57b0839e
|
||||
|
||||
// 33.2.1: Vector Basic Bit-manipulation (Zvbb)
|
||||
VANDNVV V1, V2, V3 // d7812006
|
||||
VANDNVV V1, V2, V0, V3 // d7812004
|
||||
VANDNVX X10, V2, V3 // d7412506
|
||||
VANDNVX X10, V2, V0, V3 // d7412504
|
||||
VBREVV V2, V3 // d721254a
|
||||
VBREVV V2, V0, V3 // d7212548
|
||||
VBREV8V V2, V3 // d721244a
|
||||
VBREV8V V2, V0, V3 // d7212448
|
||||
VREV8V V2, V3 // d7a1244a
|
||||
VREV8V V2, V0, V3 // d7a12448
|
||||
VCLZV V2, V3 // d721264a
|
||||
VCLZV V2, V0, V3 // d7212648
|
||||
VCTZV V2, V3 // d7a1264a
|
||||
VCTZV V2, V0, V3 // d7a12648
|
||||
VCPOPV V2, V3 // d721274a
|
||||
VCPOPV V2, V0, V3 // d7212748
|
||||
VROLVV V1, V2, V3 // d7812056
|
||||
VROLVV V1, V2, V0, V3 // d7812054
|
||||
VROLVX X10, V2, V3 // d7412556
|
||||
VROLVX X10, V2, V0, V3 // d7412554
|
||||
VRORVV V1, V2, V3 // d7812052
|
||||
VRORVV V1, V2, V0, V3 // d7812050
|
||||
VRORVX X10, V2, V3 // d7412552
|
||||
VRORVX X10, V2, V0, V3 // d7412550
|
||||
VRORVI $16, V2, V3 // d7312852
|
||||
VRORVI $16, V2, V0, V3 // d7312850
|
||||
VWSLLVV V1, V2, V3 // d78120d6
|
||||
VWSLLVV V1, V2, V0, V3 // d78120d4
|
||||
VWSLLVX X10, V2, V3 // d74125d6
|
||||
VWSLLVX X10, V2, V0, V3 // d74125d4
|
||||
VWSLLVI $16, V2, V3 // d73128d6
|
||||
VWSLLVI $16, V2, V0, V3 // d73128d4
|
||||
|
||||
// 33.2.2: Vector Carryless Multiplication (Zvbc)
|
||||
VCLMULVV V1, V2, V3 // d7a12032
|
||||
VCLMULVV V1, V2, V0, V3 // d7a12030
|
||||
VCLMULVX X10, V2, V3 // d7612532
|
||||
VCLMULVX X10, V2, V0, V3 // d7612530
|
||||
VCLMULHVV V1, V2, V3 // d7a12036
|
||||
VCLMULHVV V1, V2, V0, V3 // d7a12034
|
||||
VCLMULHVX X10, V2, V3 // d7612536
|
||||
VCLMULHVX X10, V2, V0, V3 // d7612534
|
||||
RET
|
||||
`
|
||||
dir := t.TempDir()
|
||||
path := filepath.Join(dir, "vecarith_riscv64.s")
|
||||
if err := os.WriteFile(path, []byte(src), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assertRISCVDifferential(t, path, src, "vecarith")
|
||||
}
|
||||
Reference in new issue
Block a user