aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/asm
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/asm')
-rw-r--r--src/cmd/asm/internal/arch/arm64.go6
-rw-r--r--src/cmd/asm/internal/arch/riscv64.go35
-rw-r--r--src/cmd/asm/internal/asm/asm.go21
-rw-r--r--src/cmd/asm/internal/asm/parse.go16
-rw-r--r--src/cmd/asm/internal/asm/testdata/riscv64.s24
-rw-r--r--src/cmd/asm/internal/asm/testdata/riscv64error.s4
6 files changed, 95 insertions, 11 deletions
diff --git a/src/cmd/asm/internal/arch/arm64.go b/src/cmd/asm/internal/arch/arm64.go
index e63601de64..87ccb8c040 100644
--- a/src/cmd/asm/internal/arch/arm64.go
+++ b/src/cmd/asm/internal/arch/arm64.go
@@ -59,10 +59,10 @@ func jumpArm64(word string) bool {
var arm64SpecialOperand map[string]arm64.SpecialOperand
-// GetARM64SpecialOperand returns the internal representation of a special operand.
-func GetARM64SpecialOperand(name string) arm64.SpecialOperand {
+// ARM64SpecialOperand returns the internal representation of a special operand.
+func ARM64SpecialOperand(name string) arm64.SpecialOperand {
if arm64SpecialOperand == nil {
- // Generate the mapping automatically when the first time the function is called.
+ // Generate mapping when function is first called.
arm64SpecialOperand = map[string]arm64.SpecialOperand{}
for opd := arm64.SPOP_BEGIN; opd < arm64.SPOP_END; opd++ {
arm64SpecialOperand[opd.String()] = opd
diff --git a/src/cmd/asm/internal/arch/riscv64.go b/src/cmd/asm/internal/arch/riscv64.go
index 27a66c5e63..69e060a865 100644
--- a/src/cmd/asm/internal/arch/riscv64.go
+++ b/src/cmd/asm/internal/arch/riscv64.go
@@ -13,9 +13,8 @@ import (
"cmd/internal/obj/riscv"
)
-// IsRISCV64AMO reports whether the op (as defined by a riscv.A*
-// constant) is one of the AMO instructions that requires special
-// handling.
+// IsRISCV64AMO reports whether op is an AMO instruction that requires
+// special handling.
func IsRISCV64AMO(op obj.As) bool {
switch op {
case riscv.ASCW, riscv.ASCD, riscv.AAMOSWAPW, riscv.AAMOSWAPD, riscv.AAMOADDW, riscv.AAMOADDD,
@@ -26,3 +25,33 @@ func IsRISCV64AMO(op obj.As) bool {
}
return false
}
+
+// IsRISCV64VTypeI reports whether op is a vtype immediate instruction that
+// requires special handling.
+func IsRISCV64VTypeI(op obj.As) bool {
+ return op == riscv.AVSETVLI || op == riscv.AVSETIVLI
+}
+
+var riscv64SpecialOperand map[string]riscv.SpecialOperand
+
+// RISCV64SpecialOperand returns the internal representation of a special operand.
+func RISCV64SpecialOperand(name string) riscv.SpecialOperand {
+ if riscv64SpecialOperand == nil {
+ // Generate mapping when function is first called.
+ riscv64SpecialOperand = map[string]riscv.SpecialOperand{}
+ for opd := riscv.SPOP_BEGIN; opd < riscv.SPOP_END; opd++ {
+ riscv64SpecialOperand[opd.String()] = opd
+ }
+ }
+ if opd, ok := riscv64SpecialOperand[name]; ok {
+ return opd
+ }
+ return riscv.SPOP_END
+}
+
+// RISCV64ValidateVectorType reports whether the given configuration is a
+// valid vector type.
+func RISCV64ValidateVectorType(vsew, vlmul, vtail, vmask int64) error {
+ _, err := riscv.EncodeVectorType(vsew, vlmul, vtail, vmask)
+ return err
+}
diff --git a/src/cmd/asm/internal/asm/asm.go b/src/cmd/asm/internal/asm/asm.go
index 9fc7fa5598..a1f6a73d70 100644
--- a/src/cmd/asm/internal/asm/asm.go
+++ b/src/cmd/asm/internal/asm/asm.go
@@ -915,6 +915,19 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
prog.To = a[5]
break
}
+ if p.arch.Family == sys.RISCV64 && arch.IsRISCV64VTypeI(op) {
+ prog.From = a[0]
+ vsew := p.getSpecial(prog, op, &a[1])
+ vlmul := p.getSpecial(prog, op, &a[2])
+ vtail := p.getSpecial(prog, op, &a[3])
+ vmask := p.getSpecial(prog, op, &a[4])
+ if err := arch.RISCV64ValidateVectorType(vsew, vlmul, vtail, vmask); err != nil {
+ p.errorf("invalid vtype: %v", err)
+ }
+ prog.AddRestSourceArgs([]obj.Addr{a[1], a[2], a[3], a[4]})
+ prog.To = a[5]
+ break
+ }
fallthrough
default:
p.errorf("can't handle %s instruction with %d operands", op, len(a))
@@ -965,3 +978,11 @@ func (p *Parser) getRegister(prog *obj.Prog, op obj.As, addr *obj.Addr) int16 {
}
return addr.Reg
}
+
+// getSpecial checks that addr represents a special operand and returns its value.
+func (p *Parser) getSpecial(prog *obj.Prog, op obj.As, addr *obj.Addr) int64 {
+ if addr.Type != obj.TYPE_SPECIAL || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 {
+ p.errorf("%s: expected special operand; found %s", op, obj.Dconv(prog, addr))
+ }
+ return addr.Offset
+}
diff --git a/src/cmd/asm/internal/asm/parse.go b/src/cmd/asm/internal/asm/parse.go
index 638f4e2fc4..8f8f6dcc34 100644
--- a/src/cmd/asm/internal/asm/parse.go
+++ b/src/cmd/asm/internal/asm/parse.go
@@ -21,6 +21,7 @@ import (
"cmd/asm/internal/lex"
"cmd/internal/obj"
"cmd/internal/obj/arm64"
+ "cmd/internal/obj/riscv"
"cmd/internal/obj/x86"
"cmd/internal/objabi"
"cmd/internal/src"
@@ -398,16 +399,21 @@ func (p *Parser) operand(a *obj.Addr) {
tok := p.next()
name := tok.String()
if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) {
+ // See if this is an architecture specific special operand.
switch p.arch.Family {
case sys.ARM64:
- // arm64 special operands.
- if opd := arch.GetARM64SpecialOperand(name); opd != arm64.SPOP_END {
+ if opd := arch.ARM64SpecialOperand(name); opd != arm64.SPOP_END {
a.Type = obj.TYPE_SPECIAL
a.Offset = int64(opd)
- break
}
- fallthrough
- default:
+ case sys.RISCV64:
+ if opd := arch.RISCV64SpecialOperand(name); opd != riscv.SPOP_END {
+ a.Type = obj.TYPE_SPECIAL
+ a.Offset = int64(opd)
+ }
+ }
+
+ if a.Type != obj.TYPE_SPECIAL {
// We have a symbol. Parse $sym±offset(symkind)
p.symbolReference(a, p.qualifySymbol(name), prefix)
}
diff --git a/src/cmd/asm/internal/asm/testdata/riscv64.s b/src/cmd/asm/internal/asm/testdata/riscv64.s
index 9ab4e066be..cbe99ba348 100644
--- a/src/cmd/asm/internal/asm/testdata/riscv64.s
+++ b/src/cmd/asm/internal/asm/testdata/riscv64.s
@@ -425,6 +425,30 @@ start:
BSETI $1, X10, X11 // 93151528
//
+ // "V" Standard Extension for Vector Operations, Version 1.0
+ //
+
+ // 31.6: Configuration Setting Instructions
+ VSETVLI X10, E8, M1, TU, MU, X12 // 57760500
+ VSETVLI X10, E16, M1, TU, MU, X12 // 57768500
+ VSETVLI X10, E32, M1, TU, MU, X12 // 57760501
+ VSETVLI X10, E64, M1, TU, MU, X12 // 57768501
+ VSETVLI X10, E32, M1, TU, MA, X12 // 57760509
+ VSETVLI X10, E32, M1, TA, MA, X12 // 5776050d
+ VSETVLI X10, E32, M2, TA, MA, X12 // 5776150d
+ VSETVLI X10, E32, M4, TA, MA, X12 // 5776250d
+ VSETVLI X10, E32, M8, TA, MA, X12 // 5776350d
+ VSETVLI X10, E32, MF2, TA, MA, X12 // 5776550d
+ VSETVLI X10, E32, MF4, TA, MA, X12 // 5776650d
+ VSETVLI X10, E32, MF8, TA, MA, X12 // 5776750d
+ VSETVLI X10, E32, M1, TA, MA, X12 // 5776050d
+ VSETVLI $15, E32, M1, TA, MA, X12 // 57f607cd
+ VSETIVLI $0, E32, M1, TA, MA, X12 // 577600cd
+ VSETIVLI $15, E32, M1, TA, MA, X12 // 57f607cd
+ VSETIVLI $31, E32, M1, TA, MA, X12 // 57f60fcd
+ VSETVL X10, X11, X12 // 57f6a580
+
+ //
// Privileged ISA
//
diff --git a/src/cmd/asm/internal/asm/testdata/riscv64error.s b/src/cmd/asm/internal/asm/testdata/riscv64error.s
index 0b0184aaa7..a90f22af9f 100644
--- a/src/cmd/asm/internal/asm/testdata/riscv64error.s
+++ b/src/cmd/asm/internal/asm/testdata/riscv64error.s
@@ -46,4 +46,8 @@ TEXT errors(SB),$0
SRLI $1, X5, F1 // ERROR "expected integer register in rd position but got non-integer register F1"
SRLI $1, F1, X5 // ERROR "expected integer register in rs1 position but got non-integer register F1"
FNES F1, (X5) // ERROR "needs an integer register output"
+ VSETVLI $32, E16, M1, TU, MU, X12 // ERROR "must be in range [0, 31] (5 bits)"
+ VSETVLI $-1, E32, M2, TA, MA, X12 // ERROR "must be in range [0, 31] (5 bits)"
+ VSETIVLI X10, E32, M2, TA, MA, X12 // ERROR "expected immediate value"
+ VSETVL X10, X11 // ERROR "expected integer register in rs1 position"
RET