diff options
| author | Joel Sing <joel@sing.id.au> | 2025-02-02 23:09:12 +1100 |
|---|---|---|
| committer | Joel Sing <joel@sing.id.au> | 2025-05-02 04:24:40 -0700 |
| commit | 936ecc3e24c5b2e3ea4b0d2ca9eb32c39fdc097e (patch) | |
| tree | 9b2d43c09040e40fb0fea32845925aa6ef899acb /src/cmd/internal/obj | |
| parent | 2e60916f6e153db682fd4ea269c7d0a32e3d1768 (diff) | |
| download | go-936ecc3e24c5b2e3ea4b0d2ca9eb32c39fdc097e.tar.xz | |
cmd/internal/obj/riscv: add support for vector mask instructions
Add support for vector mask instructions to the RISC-V assembler.
These allow manipulation of vector masks and include mask register
logical instructions, population count and find-first bit set
instructions.
Change-Id: I3ab3aa0f918338aee9b37ac5a2b2fdc407875072
Reviewed-on: https://go-review.googlesource.com/c/go/+/646779
Reviewed-by: Carlos Amedee <carlos@golang.org>
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>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Diffstat (limited to 'src/cmd/internal/obj')
| -rw-r--r-- | src/cmd/internal/obj/riscv/anames.go | 8 | ||||
| -rw-r--r-- | src/cmd/internal/obj/riscv/cpu.go | 8 | ||||
| -rw-r--r-- | src/cmd/internal/obj/riscv/obj.go | 70 |
3 files changed, 82 insertions, 4 deletions
diff --git a/src/cmd/internal/obj/riscv/anames.go b/src/cmd/internal/obj/riscv/anames.go index bf1fdb8b88..a689f2de27 100644 --- a/src/cmd/internal/obj/riscv/anames.go +++ b/src/cmd/internal/obj/riscv/anames.go @@ -652,12 +652,16 @@ var Anames = []string{ "SNEZ", "VFABSV", "VFNEGV", - "VMFGEVV", - "VMFGTVV", "VL1RV", "VL2RV", "VL4RV", "VL8RV", + "VMCLRM", + "VMFGEVV", + "VMFGTVV", + "VMMVM", + "VMNOTM", + "VMSETM", "VMSGEUVI", "VMSGEUVV", "VMSGEVI", diff --git a/src/cmd/internal/obj/riscv/cpu.go b/src/cmd/internal/obj/riscv/cpu.go index 3cad4f9d94..d87b6b1efb 100644 --- a/src/cmd/internal/obj/riscv/cpu.go +++ b/src/cmd/internal/obj/riscv/cpu.go @@ -1180,12 +1180,16 @@ const ( ASNEZ AVFABSV AVFNEGV - AVMFGEVV - AVMFGTVV AVL1RV AVL2RV AVL4RV AVL8RV + AVMCLRM + AVMFGEVV + AVMFGTVV + AVMMVM + AVMNOTM + AVMSETM AVMSGEUVI AVMSGEUVV AVMSGEVI diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 83ce7e21df..c911ea01f3 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -1328,6 +1328,13 @@ func validateRVFV(ctxt *obj.Link, ins *instruction) { wantNoneReg(ctxt, ins, "rs3", ins.rs3) } +func validateRVI(ctxt *obj.Link, ins *instruction) { + wantIntReg(ctxt, ins, "rd", ins.rd) + wantNoneReg(ctxt, ins, "rs1", ins.rs1) + wantVectorReg(ctxt, ins, "vs2", ins.rs2) + 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) @@ -1577,6 +1584,10 @@ func encodeRVFV(ins *instruction) uint32 { return encodeR(ins.as, regF(ins.rs1), regV(ins.rs2), regV(ins.rd), ins.funct3, ins.funct7) } +func encodeRVI(ins *instruction) uint32 { + return encodeR(ins.as, 0, regV(ins.rs2), regI(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) } @@ -1881,6 +1892,7 @@ var ( rIFEncoding = encoding{encode: encodeRIF, validate: validateRIF, length: 4} rFFEncoding = encoding{encode: encodeRFF, validate: validateRFF, length: 4} rVFVEncoding = encoding{encode: encodeRVFV, validate: validateRVFV, length: 4} + rVIEncoding = encoding{encode: encodeRVI, validate: validateRVI, length: 4} rVIVEncoding = encoding{encode: encodeRVIV, validate: validateRVIV, length: 4} rVVEncoding = encoding{encode: encodeRVV, validate: validateRVV, length: 4} rVViEncoding = encoding{encode: encodeRVVi, validate: validateRVVi, length: 4} @@ -2609,6 +2621,23 @@ var instructions = [ALAST & obj.AMask]instructionData{ AVFWREDOSUMVS & obj.AMask: {enc: rVVVEncoding}, AVFWREDUSUMVS & obj.AMask: {enc: rVVVEncoding}, + // 31.15: Vector Mask Instructions + AVMANDMM & obj.AMask: {enc: rVVVEncoding}, + AVMNANDMM & obj.AMask: {enc: rVVVEncoding}, + AVMANDNMM & obj.AMask: {enc: rVVVEncoding}, + AVMXORMM & obj.AMask: {enc: rVVVEncoding}, + AVMORMM & obj.AMask: {enc: rVVVEncoding}, + AVMNORMM & obj.AMask: {enc: rVVVEncoding}, + AVMORNMM & obj.AMask: {enc: rVVVEncoding}, + AVMXNORMM & obj.AMask: {enc: rVVVEncoding}, + AVCPOPM & obj.AMask: {enc: rVIEncoding}, + AVFIRSTM & obj.AMask: {enc: rVIEncoding}, + AVMSBFM & obj.AMask: {enc: rVVEncoding}, + AVMSIFM & obj.AMask: {enc: rVVEncoding}, + AVMSOFM & obj.AMask: {enc: rVVEncoding}, + AVIOTAM & obj.AMask: {enc: rVVEncoding}, + AVIDV & obj.AMask: {enc: rVVEncoding}, + // // Privileged ISA // @@ -3765,6 +3794,47 @@ func instructionsForProg(p *obj.Prog) []*instruction { ins.as = AVFSGNJNVV } ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.From.Reg) + + case AVMANDMM, AVMNANDMM, AVMANDNMM, AVMXORMM, AVMORMM, AVMNORMM, AVMORNMM, AVMXNORMM, AVMMVM, AVMNOTM: + ins.rd, ins.rs1, ins.rs2 = uint32(p.To.Reg), uint32(p.From.Reg), uint32(p.Reg) + switch ins.as { + case AVMMVM: + ins.as, ins.rs2 = AVMANDMM, ins.rs1 + case AVMNOTM: + ins.as, ins.rs2 = AVMNANDMM, ins.rs1 + } + + case AVMCLRM, AVMSETM: + ins.rd, ins.rs1, ins.rs2 = uint32(p.From.Reg), uint32(p.From.Reg), uint32(p.From.Reg) + switch ins.as { + case AVMCLRM: + ins.as = AVMXORMM + case AVMSETM: + ins.as = AVMXNORMM + } + + case AVCPOPM, AVFIRSTM, AVMSBFM, AVMSIFM, AVMSOFM, AVIOTAM: + // 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 AVIDV: + // Set mask bit + switch { + case ins.rd == obj.REG_NONE: + ins.funct7 |= 1 // unmasked + case ins.rd != obj.REG_NONE && ins.rs2 != REG_V0: + p.Ctxt.Diag("%v: invalid vector mask register", p) + } + if ins.rd == obj.REG_NONE { + ins.rd = uint32(p.From.Reg) + } + ins.rs1, ins.rs2 = obj.REG_NONE, REG_V0 } for _, ins := range inss { |
