diff options
| author | Joel Sing <joel@sing.id.au> | 2024-06-18 23:36:43 +1000 |
|---|---|---|
| committer | Joel Sing <joel@sing.id.au> | 2025-03-29 05:54:51 -0700 |
| commit | 535e0daefd5ae1364df148c69fc893a068267605 (patch) | |
| tree | fe1f6dd5d8bf019fe54a06366f2a72bd07609536 /src/cmd/internal/obj | |
| parent | 5fb9e5dc19c48c8de09720bd4cb64eccd933153d (diff) | |
| download | go-535e0daefd5ae1364df148c69fc893a068267605.tar.xz | |
cmd/internal/obj/riscv: add support for vector integer arithmetic instructions
Add support for vector integer arithmetic instructions to the RISC-V
assembler. This includes vector addition, subtraction, integer
extension, add-with-carry, subtract-with-borrow, bitwise logical
operations, comparison, min/max, integer division and multiplication
instructions.
Change-Id: I8c191ef8e31291e13743732903e4f12356133a46
Reviewed-on: https://go-review.googlesource.com/c/go/+/646775
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Meng Zhuo <mengzhuo1203@gmail.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Ryan <markdryan@rivosinc.com>
Diffstat (limited to 'src/cmd/internal/obj')
| -rw-r--r-- | src/cmd/internal/obj/riscv/anames.go | 13 | ||||
| -rw-r--r-- | src/cmd/internal/obj/riscv/cpu.go | 13 | ||||
| -rw-r--r-- | src/cmd/internal/obj/riscv/obj.go | 393 |
3 files changed, 409 insertions, 10 deletions
diff --git a/src/cmd/internal/obj/riscv/anames.go b/src/cmd/internal/obj/riscv/anames.go index 6df5f0a173..a65dfceea9 100644 --- a/src/cmd/internal/obj/riscv/anames.go +++ b/src/cmd/internal/obj/riscv/anames.go @@ -654,5 +654,18 @@ var Anames = []string{ "VL2RV", "VL4RV", "VL8RV", + "VMSGEUVI", + "VMSGEUVV", + "VMSGEVI", + "VMSGEVV", + "VMSGTUVV", + "VMSGTVV", + "VMSLTUVI", + "VMSLTVI", + "VNCVTXXW", + "VNEGV", + "VNOTV", + "VWCVTUXXV", + "VWCVTXXV", "LAST", } diff --git a/src/cmd/internal/obj/riscv/cpu.go b/src/cmd/internal/obj/riscv/cpu.go index 0ecf6dbae2..fa4c2cf372 100644 --- a/src/cmd/internal/obj/riscv/cpu.go +++ b/src/cmd/internal/obj/riscv/cpu.go @@ -1182,6 +1182,19 @@ const ( AVL2RV AVL4RV AVL8RV + AVMSGEUVI + AVMSGEUVV + AVMSGEVI + AVMSGEVV + AVMSGTUVV + AVMSGTVV + AVMSLTUVI + AVMSLTVI + AVNCVTXXW + AVNEGV + AVNOTV + AVWCVTUXXV + AVWCVTXXV // End marker ALAST diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 208550c7be..00b71de7cb 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -1329,6 +1329,43 @@ func validateRFF(ctxt *obj.Link, ins *instruction) { wantNoneReg(ctxt, ins, "rs3", ins.rs3) } +func validateRVIV(ctxt *obj.Link, ins *instruction) { + wantVectorReg(ctxt, ins, "vd", ins.rd) + wantIntReg(ctxt, ins, "rs1", ins.rs1) + wantVectorReg(ctxt, ins, "vs2", ins.rs2) + wantNoneReg(ctxt, ins, "rs3", ins.rs3) +} + +func validateRVV(ctxt *obj.Link, ins *instruction) { + wantVectorReg(ctxt, ins, "vd", ins.rd) + wantNoneReg(ctxt, ins, "rs1", ins.rs1) + wantVectorReg(ctxt, ins, "vs2", ins.rs2) + wantNoneReg(ctxt, ins, "rs3", ins.rs3) +} + +func validateRVVi(ctxt *obj.Link, ins *instruction) { + wantImmI(ctxt, ins, ins.imm, 5) + wantVectorReg(ctxt, ins, "vd", ins.rd) + wantNoneReg(ctxt, ins, "rs1", ins.rs1) + wantVectorReg(ctxt, ins, "vs2", ins.rs2) + wantNoneReg(ctxt, ins, "rs3", ins.rs3) +} + +func validateRVVu(ctxt *obj.Link, ins *instruction) { + wantImmU(ctxt, ins, ins.imm, 5) + wantVectorReg(ctxt, ins, "vd", ins.rd) + wantNoneReg(ctxt, ins, "rs1", ins.rs1) + wantVectorReg(ctxt, ins, "vs2", ins.rs2) + wantNoneReg(ctxt, ins, "rs3", ins.rs3) +} + +func validateRVVV(ctxt *obj.Link, ins *instruction) { + wantVectorReg(ctxt, ins, "vd", ins.rd) + wantVectorReg(ctxt, ins, "vs1", ins.rs1) + wantVectorReg(ctxt, ins, "vs2", ins.rs2) + wantNoneReg(ctxt, ins, "rs3", ins.rs3) +} + func validateIII(ctxt *obj.Link, ins *instruction) { wantImmI(ctxt, ins, ins.imm, 12) wantIntReg(ctxt, ins, "rd", ins.rd) @@ -1346,23 +1383,23 @@ func validateIF(ctxt *obj.Link, ins *instruction) { } func validateIV(ctxt *obj.Link, ins *instruction) { - wantVectorReg(ctxt, ins, "rd", ins.rd) + wantVectorReg(ctxt, ins, "vd", ins.rd) wantIntReg(ctxt, ins, "rs1", ins.rs1) wantNoneReg(ctxt, ins, "rs2", ins.rs2) wantNoneReg(ctxt, ins, "rs3", ins.rs3) } func validateIIIV(ctxt *obj.Link, ins *instruction) { - wantVectorReg(ctxt, ins, "rd", ins.rd) + wantVectorReg(ctxt, ins, "vd", ins.rd) wantIntReg(ctxt, ins, "rs1", ins.rs1) wantIntReg(ctxt, ins, "rs2", ins.rs2) wantNoneReg(ctxt, ins, "rs3", ins.rs3) } func validateIVIV(ctxt *obj.Link, ins *instruction) { - wantVectorReg(ctxt, ins, "rd", ins.rd) + wantVectorReg(ctxt, ins, "vd", ins.rd) wantIntReg(ctxt, ins, "rs1", ins.rs1) - wantVectorReg(ctxt, ins, "rs2", ins.rs2) + wantVectorReg(ctxt, ins, "vs2", ins.rs2) wantNoneReg(ctxt, ins, "rs3", ins.rs3) } @@ -1384,22 +1421,22 @@ func validateSF(ctxt *obj.Link, ins *instruction) { func validateSV(ctxt *obj.Link, ins *instruction) { wantIntReg(ctxt, ins, "rd", ins.rd) - wantVectorReg(ctxt, ins, "rs1", ins.rs1) + wantVectorReg(ctxt, ins, "vs1", ins.rs1) wantNoneReg(ctxt, ins, "rs2", ins.rs2) wantNoneReg(ctxt, ins, "rs3", ins.rs3) } func validateSVII(ctxt *obj.Link, ins *instruction) { - wantVectorReg(ctxt, ins, "rd", ins.rd) + wantVectorReg(ctxt, ins, "vd", ins.rd) wantIntReg(ctxt, ins, "rs1", ins.rs1) wantIntReg(ctxt, ins, "rs2", ins.rs2) wantNoneReg(ctxt, ins, "rs3", ins.rs3) } func validateSVIV(ctxt *obj.Link, ins *instruction) { - wantVectorReg(ctxt, ins, "rd", ins.rd) + wantVectorReg(ctxt, ins, "vd", ins.rd) wantIntReg(ctxt, ins, "rs1", ins.rs1) - wantVectorReg(ctxt, ins, "rs2", ins.rs2) + wantVectorReg(ctxt, ins, "vs2", ins.rs2) wantNoneReg(ctxt, ins, "rs3", ins.rs3) } @@ -1476,11 +1513,15 @@ func encodeR(as obj.As, rs1, rs2, rd, funct3, funct7 uint32) uint32 { if enc == nil { panic("encodeR: could not encode instruction") } + if enc.rs1 != 0 && rs1 != 0 { + panic("encodeR: instruction uses rs1, but rs1 is nonzero") + } if enc.rs2 != 0 && rs2 != 0 { - panic("encodeR: instruction uses rs2, but rs2 was nonzero") + panic("encodeR: instruction uses rs2, but rs2 is nonzero") } funct3 |= enc.funct3 funct7 |= enc.funct7 + rs1 |= enc.rs1 rs2 |= enc.rs2 return funct7<<25 | rs2<<20 | rs1<<15 | funct3<<12 | rd<<7 | enc.opcode } @@ -1533,6 +1574,26 @@ func encodeRFF(ins *instruction) uint32 { return encodeR(ins.as, regF(ins.rs2), 0, regF(ins.rd), ins.funct3, ins.funct7) } +func encodeRVV(ins *instruction) uint32 { + return encodeR(ins.as, 0, regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7) +} + +func encodeRVVi(ins *instruction) uint32 { + return encodeR(ins.as, immI(ins.as, ins.imm, 5), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7) +} + +func encodeRVVu(ins *instruction) uint32 { + return encodeR(ins.as, immU(ins.as, ins.imm, 5), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7) +} + +func encodeRVIV(ins *instruction) uint32 { + return encodeR(ins.as, regI(ins.rs1), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7) +} + +func encodeRVVV(ins *instruction) uint32 { + return encodeR(ins.as, regV(ins.rs1), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7) +} + // encodeI encodes an I-type RISC-V instruction. func encodeI(as obj.As, rs1, rd, imm, funct7 uint32) uint32 { enc := encode(as) @@ -1816,6 +1877,11 @@ var ( rFIEncoding = encoding{encode: encodeRFI, validate: validateRFI, length: 4} rIFEncoding = encoding{encode: encodeRIF, validate: validateRIF, length: 4} rFFEncoding = encoding{encode: encodeRFF, validate: validateRFF, length: 4} + rVVEncoding = encoding{encode: encodeRVV, validate: validateRVV, length: 4} + rVViEncoding = encoding{encode: encodeRVVi, validate: validateRVVi, length: 4} + rVVuEncoding = encoding{encode: encodeRVVu, validate: validateRVVu, length: 4} + rVIVEncoding = encoding{encode: encodeRVIV, validate: validateRVIV, length: 4} + rVVVEncoding = encoding{encode: encodeRVVV, validate: validateRVVV, length: 4} iIIEncoding = encoding{encode: encodeIII, validate: validateIII, length: 4} iFEncoding = encoding{encode: encodeIF, validate: validateIF, length: 4} @@ -2153,7 +2219,7 @@ var instructions = [ALAST & obj.AMask]instructionData{ AVSOXEI32V & obj.AMask: {enc: sVIVEncoding}, AVSOXEI64V & obj.AMask: {enc: sVIVEncoding}, - // 31.7.9. Vector Load/Store Whole Register Instructions + // 31.7.9: Vector Load/Store Whole Register Instructions AVL1RE8V & obj.AMask: {enc: iVEncoding}, AVL1RE16V & obj.AMask: {enc: iVEncoding}, AVL1RE32V & obj.AMask: {enc: iVEncoding}, @@ -2175,6 +2241,177 @@ var instructions = [ALAST & obj.AMask]instructionData{ AVS4RV & obj.AMask: {enc: sVEncoding}, AVS8RV & obj.AMask: {enc: sVEncoding}, + // 31.11.1: Vector Single-Width Integer Add and Subtract + AVADDVV & obj.AMask: {enc: rVVVEncoding}, + AVADDVX & obj.AMask: {enc: rVIVEncoding}, + AVADDVI & obj.AMask: {enc: rVViEncoding}, + AVSUBVV & obj.AMask: {enc: rVVVEncoding}, + AVSUBVX & obj.AMask: {enc: rVIVEncoding}, + AVRSUBVX & obj.AMask: {enc: rVIVEncoding}, + AVRSUBVI & obj.AMask: {enc: rVViEncoding}, + + // 31.11.2: Vector Widening Integer Add/Subtract + AVWADDUVV & obj.AMask: {enc: rVVVEncoding}, + AVWADDUVX & obj.AMask: {enc: rVIVEncoding}, + AVWSUBUVV & obj.AMask: {enc: rVVVEncoding}, + AVWSUBUVX & obj.AMask: {enc: rVIVEncoding}, + AVWADDVV & obj.AMask: {enc: rVVVEncoding}, + AVWADDVX & obj.AMask: {enc: rVIVEncoding}, + AVWSUBVV & obj.AMask: {enc: rVVVEncoding}, + AVWSUBVX & obj.AMask: {enc: rVIVEncoding}, + AVWADDUWV & obj.AMask: {enc: rVVVEncoding}, + AVWADDUWX & obj.AMask: {enc: rVIVEncoding}, + AVWSUBUWV & obj.AMask: {enc: rVVVEncoding}, + AVWSUBUWX & obj.AMask: {enc: rVIVEncoding}, + AVWADDWV & obj.AMask: {enc: rVVVEncoding}, + AVWADDWX & obj.AMask: {enc: rVIVEncoding}, + AVWSUBWV & obj.AMask: {enc: rVVVEncoding}, + AVWSUBWX & obj.AMask: {enc: rVIVEncoding}, + + // 31.11.3: Vector Integer Extension + AVZEXTVF2 & obj.AMask: {enc: rVVEncoding}, + AVSEXTVF2 & obj.AMask: {enc: rVVEncoding}, + AVZEXTVF4 & obj.AMask: {enc: rVVEncoding}, + AVSEXTVF4 & obj.AMask: {enc: rVVEncoding}, + AVZEXTVF8 & obj.AMask: {enc: rVVEncoding}, + AVSEXTVF8 & obj.AMask: {enc: rVVEncoding}, + + // 31.11.4: Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions + AVADCVVM & obj.AMask: {enc: rVVVEncoding}, + AVADCVXM & obj.AMask: {enc: rVIVEncoding}, + AVADCVIM & obj.AMask: {enc: rVViEncoding}, + AVMADCVVM & obj.AMask: {enc: rVVVEncoding}, + AVMADCVXM & obj.AMask: {enc: rVIVEncoding}, + AVMADCVIM & obj.AMask: {enc: rVViEncoding}, + AVMADCVV & obj.AMask: {enc: rVVVEncoding}, + AVMADCVX & obj.AMask: {enc: rVIVEncoding}, + AVMADCVI & obj.AMask: {enc: rVViEncoding}, + AVSBCVVM & obj.AMask: {enc: rVVVEncoding}, + AVSBCVXM & obj.AMask: {enc: rVIVEncoding}, + AVMSBCVVM & obj.AMask: {enc: rVVVEncoding}, + AVMSBCVXM & obj.AMask: {enc: rVIVEncoding}, + AVMSBCVV & obj.AMask: {enc: rVVVEncoding}, + AVMSBCVX & obj.AMask: {enc: rVIVEncoding}, + + // 31.11.5: Vector Bitwise Logical Instructions + AVANDVV & obj.AMask: {enc: rVVVEncoding}, + AVANDVX & obj.AMask: {enc: rVIVEncoding}, + AVANDVI & obj.AMask: {enc: rVViEncoding}, + AVORVV & obj.AMask: {enc: rVVVEncoding}, + AVORVX & obj.AMask: {enc: rVIVEncoding}, + AVORVI & obj.AMask: {enc: rVViEncoding}, + AVXORVV & obj.AMask: {enc: rVVVEncoding}, + AVXORVX & obj.AMask: {enc: rVIVEncoding}, + AVXORVI & obj.AMask: {enc: rVViEncoding}, + + // 31.11.6: Vector Single-Width Shift Instructions + AVSLLVV & obj.AMask: {enc: rVVVEncoding}, + AVSLLVX & obj.AMask: {enc: rVIVEncoding}, + AVSLLVI & obj.AMask: {enc: rVVuEncoding}, + AVSRLVV & obj.AMask: {enc: rVVVEncoding}, + AVSRLVX & obj.AMask: {enc: rVIVEncoding}, + AVSRLVI & obj.AMask: {enc: rVVuEncoding}, + AVSRAVV & obj.AMask: {enc: rVVVEncoding}, + AVSRAVX & obj.AMask: {enc: rVIVEncoding}, + AVSRAVI & obj.AMask: {enc: rVVuEncoding}, + + // 31.11.7: Vector Narrowing Integer Right Shift Instructions + AVNSRLWV & obj.AMask: {enc: rVVVEncoding}, + AVNSRLWX & obj.AMask: {enc: rVIVEncoding}, + AVNSRLWI & obj.AMask: {enc: rVVuEncoding}, + AVNSRAWV & obj.AMask: {enc: rVVVEncoding}, + AVNSRAWX & obj.AMask: {enc: rVIVEncoding}, + AVNSRAWI & obj.AMask: {enc: rVVuEncoding}, + + // 31.11.8: Vector Integer Compare Instructions + AVMSEQVV & obj.AMask: {enc: rVVVEncoding}, + AVMSEQVX & obj.AMask: {enc: rVIVEncoding}, + AVMSEQVI & obj.AMask: {enc: rVViEncoding}, + AVMSNEVV & obj.AMask: {enc: rVVVEncoding}, + AVMSNEVX & obj.AMask: {enc: rVIVEncoding}, + AVMSNEVI & obj.AMask: {enc: rVViEncoding}, + AVMSLTUVV & obj.AMask: {enc: rVVVEncoding}, + AVMSLTUVX & obj.AMask: {enc: rVIVEncoding}, + AVMSLTVV & obj.AMask: {enc: rVVVEncoding}, + AVMSLTVX & obj.AMask: {enc: rVIVEncoding}, + AVMSLEUVV & obj.AMask: {enc: rVVVEncoding}, + AVMSLEUVX & obj.AMask: {enc: rVIVEncoding}, + AVMSLEUVI & obj.AMask: {enc: rVViEncoding}, + AVMSLEVV & obj.AMask: {enc: rVVVEncoding}, + AVMSLEVX & obj.AMask: {enc: rVIVEncoding}, + AVMSLEVI & obj.AMask: {enc: rVViEncoding}, + AVMSGTUVX & obj.AMask: {enc: rVIVEncoding}, + AVMSGTUVI & obj.AMask: {enc: rVViEncoding}, + AVMSGTVX & obj.AMask: {enc: rVIVEncoding}, + AVMSGTVI & obj.AMask: {enc: rVViEncoding}, + + // 31.11.9: Vector Integer Min/Max Instructions + AVMINUVV & obj.AMask: {enc: rVVVEncoding}, + AVMINUVX & obj.AMask: {enc: rVIVEncoding}, + AVMINVV & obj.AMask: {enc: rVVVEncoding}, + AVMINVX & obj.AMask: {enc: rVIVEncoding}, + AVMAXUVV & obj.AMask: {enc: rVVVEncoding}, + AVMAXUVX & obj.AMask: {enc: rVIVEncoding}, + AVMAXVV & obj.AMask: {enc: rVVVEncoding}, + AVMAXVX & obj.AMask: {enc: rVIVEncoding}, + + // 31.11.10: Vector Single-Width Integer Multiply Instructions + AVMULVV & obj.AMask: {enc: rVVVEncoding}, + AVMULVX & obj.AMask: {enc: rVIVEncoding}, + AVMULHVV & obj.AMask: {enc: rVVVEncoding}, + AVMULHVX & obj.AMask: {enc: rVIVEncoding}, + AVMULHUVV & obj.AMask: {enc: rVVVEncoding}, + AVMULHUVX & obj.AMask: {enc: rVIVEncoding}, + AVMULHSUVV & obj.AMask: {enc: rVVVEncoding}, + AVMULHSUVX & obj.AMask: {enc: rVIVEncoding}, + + // 31.11.11: Vector Integer Divide Instructions + AVDIVUVV & obj.AMask: {enc: rVVVEncoding}, + AVDIVUVX & obj.AMask: {enc: rVIVEncoding}, + AVDIVVV & obj.AMask: {enc: rVVVEncoding}, + AVDIVVX & obj.AMask: {enc: rVIVEncoding}, + AVREMUVV & obj.AMask: {enc: rVVVEncoding}, + AVREMUVX & obj.AMask: {enc: rVIVEncoding}, + AVREMVV & obj.AMask: {enc: rVVVEncoding}, + AVREMVX & obj.AMask: {enc: rVIVEncoding}, + + // 31.11.12: Vector Widening Integer Multiply Instructions + AVWMULVV & obj.AMask: {enc: rVVVEncoding}, + AVWMULVX & obj.AMask: {enc: rVIVEncoding}, + AVWMULUVV & obj.AMask: {enc: rVVVEncoding}, + AVWMULUVX & obj.AMask: {enc: rVIVEncoding}, + AVWMULSUVV & obj.AMask: {enc: rVVVEncoding}, + AVWMULSUVX & obj.AMask: {enc: rVIVEncoding}, + + // 31.11.13: Vector Single-Width Integer Multiply-Add Instructions + AVMACCVV & obj.AMask: {enc: rVVVEncoding}, + AVMACCVX & obj.AMask: {enc: rVIVEncoding}, + AVNMSACVV & obj.AMask: {enc: rVVVEncoding}, + AVNMSACVX & obj.AMask: {enc: rVIVEncoding}, + AVMADDVV & obj.AMask: {enc: rVVVEncoding}, + AVMADDVX & obj.AMask: {enc: rVIVEncoding}, + AVNMSUBVV & obj.AMask: {enc: rVVVEncoding}, + AVNMSUBVX & obj.AMask: {enc: rVIVEncoding}, + + // 31.11.14: Vector Widening Integer Multiply-Add Instructions + AVWMACCUVV & obj.AMask: {enc: rVVVEncoding}, + AVWMACCUVX & obj.AMask: {enc: rVIVEncoding}, + AVWMACCVV & obj.AMask: {enc: rVVVEncoding}, + AVWMACCVX & obj.AMask: {enc: rVIVEncoding}, + AVWMACCSUVV & obj.AMask: {enc: rVVVEncoding}, + AVWMACCSUVX & obj.AMask: {enc: rVIVEncoding}, + AVWMACCUSVX & obj.AMask: {enc: rVIVEncoding}, + + // 31.11.15: Vector Integer Merge Instructions + AVMERGEVVM & obj.AMask: {enc: rVVVEncoding}, + AVMERGEVXM & obj.AMask: {enc: rVIVEncoding}, + AVMERGEVIM & obj.AMask: {enc: rVViEncoding}, + + // 31.11.16: Vector Integer Move Instructions + AVMVVV & obj.AMask: {enc: rVVVEncoding}, + AVMVVX & obj.AMask: {enc: rVIVEncoding}, + AVMVVI & obj.AMask: {enc: rVViEncoding}, + // // Privileged ISA // @@ -3146,6 +3383,142 @@ func instructionsForProg(p *obj.Prog) []*instruction { p.Ctxt.Diag("%v: too many operands for instruction", p) } ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), obj.REG_NONE + + case AVADDVV, AVADDVX, AVSUBVV, AVSUBVX, AVRSUBVX, AVWADDUVV, AVWADDUVX, AVWSUBUVV, AVWSUBUVX, + AVWADDVV, AVWADDVX, AVWSUBVV, AVWSUBVX, AVWADDUWV, AVWADDUWX, AVWSUBUWV, AVWSUBUWX, + AVWADDWV, AVWADDWX, AVWSUBWV, AVWSUBWX, AVANDVV, AVANDVX, AVORVV, AVORVX, AVXORVV, AVXORVX, + AVSLLVV, AVSLLVX, AVSRLVV, AVSRLVX, AVSRAVV, AVSRAVX, + AVMSEQVV, AVMSEQVX, AVMSNEVV, AVMSNEVX, AVMSLTUVV, AVMSLTUVX, AVMSLTVV, AVMSLTVX, + AVMSLEUVV, AVMSLEUVX, AVMSLEVV, AVMSLEVX, AVMSGTUVX, AVMSGTVX, + AVMINUVV, AVMINUVX, AVMINVV, AVMINVX, AVMAXUVV, AVMAXUVX, AVMAXVV, AVMAXVX, + AVMULVV, AVMULVX, AVMULHVV, AVMULHVX, AVMULHUVV, AVMULHUVX, AVMULHSUVV, AVMULHSUVX, + AVDIVUVV, AVDIVUVX, AVDIVVV, AVDIVVX, AVREMUVV, AVREMUVX, AVREMVV, AVREMVX, + AVWMULVV, AVWMULVX, AVWMULUVV, AVWMULUVX, AVWMULSUVV, AVWMULSUVX, + AVNSRLWV, AVNSRLWX, AVNSRAWV, AVNSRAWX, + AVMACCVV, AVMACCVX, AVNMSACVV, AVNMSACVX, AVMADDVV, AVMADDVX, AVNMSUBVV, AVNMSUBVX, + AVWMACCUVV, AVWMACCUVX, AVWMACCVV, AVWMACCVX, AVWMACCSUVV, AVWMACCSUVX, AVWMACCUSVX: + // Set mask bit + switch { + case ins.rs3 == obj.REG_NONE: + ins.funct7 |= 1 // unmasked + case ins.rs3 != REG_V0: + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), obj.REG_NONE + + case AVADDVI, AVRSUBVI, AVANDVI, AVORVI, AVXORVI, AVMSEQVI, AVMSNEVI, AVMSLEUVI, AVMSLEVI, AVMSGTUVI, AVMSGTVI, + AVSLLVI, AVSRLVI, AVSRAVI, AVNSRLWI, AVNSRAWI: + // Set mask bit + switch { + case ins.rs3 == obj.REG_NONE: + ins.funct7 |= 1 // unmasked + case ins.rs3 != REG_V0: + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), obj.REG_NONE, uint32(p.Reg), obj.REG_NONE + + case AVZEXTVF2, AVSEXTVF2, AVZEXTVF4, AVSEXTVF4, AVZEXTVF8, AVSEXTVF8: + // Set mask bit + switch { + case ins.rs1 == obj.REG_NONE: + ins.funct7 |= 1 // unmasked + case ins.rs1 != REG_V0: + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + ins.rs1 = obj.REG_NONE + + case AVMVVV, AVMVVX: + if ins.rs1 != obj.REG_NONE { + p.Ctxt.Diag("%v: too many operands for instruction", p) + } + ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), REG_V0 + + case AVMVVI: + if ins.rs1 != obj.REG_NONE { + p.Ctxt.Diag("%v: too many operands for instruction", p) + } + ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), obj.REG_NONE, REG_V0 + + case AVADCVVM, AVADCVXM, AVMADCVVM, AVMADCVXM, AVSBCVVM, AVSBCVXM, AVMSBCVVM, AVMSBCVXM, AVADCVIM, AVMADCVIM, + AVMERGEVVM, AVMERGEVXM, AVMERGEVIM: + if ins.rs3 != REG_V0 { + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg), obj.REG_NONE + + case AVMADCVV, AVMADCVX, AVMSBCVV, AVMSBCVX, AVMADCVI: + ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg) + + case AVNEGV, AVWCVTXXV, AVWCVTUXXV, AVNCVTXXW: + // Set mask bit + switch { + case ins.rs1 == obj.REG_NONE: + ins.funct7 |= 1 // unmasked + case ins.rs1 != REG_V0: + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + switch ins.as { + case AVNEGV: + ins.as = AVRSUBVX + case AVWCVTXXV: + ins.as = AVWADDVX + case AVWCVTUXXV: + ins.as = AVWADDUVX + case AVNCVTXXW: + ins.as = AVNSRLWX + } + ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), REG_X0, uint32(p.From.Reg) + + case AVNOTV: + // Set mask bit + switch { + case ins.rs1 == obj.REG_NONE: + ins.funct7 |= 1 // unmasked + case ins.rs1 != REG_V0: + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + ins.as = AVXORVI + ins.rd, ins.rs1, ins.rs2, ins.imm = uint32(p.To.Reg), obj.REG_NONE, uint32(p.From.Reg), -1 + + case AVMSGTVV, AVMSGTUVV, AVMSGEVV, AVMSGEUVV: + // Set mask bit + switch { + case ins.rs3 == obj.REG_NONE: + ins.funct7 |= 1 // unmasked + case ins.rs3 != REG_V0: + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + switch ins.as { + case AVMSGTVV: + ins.as = AVMSLTVV + case AVMSGTUVV: + ins.as = AVMSLTUVV + case AVMSGEVV: + ins.as = AVMSLEVV + case AVMSGEUVV: + ins.as = AVMSLEUVV + } + ins.rd, ins.rs1, ins.rs2, ins.rs3 = uint32(p.To.Reg), uint32(p.Reg), uint32(p.From.Reg), obj.REG_NONE + + case AVMSLTVI, AVMSLTUVI, AVMSGEVI, AVMSGEUVI: + // Set mask bit + switch { + case ins.rs3 == obj.REG_NONE: + ins.funct7 |= 1 // unmasked + case ins.rs3 != REG_V0: + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + switch ins.as { + case AVMSLTVI: + ins.as = AVMSLEVI + case AVMSLTUVI: + ins.as = AVMSLEUVI + case AVMSGEVI: + ins.as = AVMSGTVI + case AVMSGEUVI: + ins.as = AVMSGTUVI + } + ins.rd, ins.rs1, ins.rs2, ins.rs3, ins.imm = uint32(p.To.Reg), obj.REG_NONE, uint32(p.Reg), obj.REG_NONE, ins.imm-1 } for _, ins := range inss { |
