mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd: update golang.org/x/arch for riscv64 disassembler
Update to a newer version of golang.org/x/arch, in order to bring in changes to the riscv64 disassembler, including support for vector and zicond instructions: go get golang.org/x/arch@fea4a9e go mod tidy go mod vendor Change-Id: I19623f76a63cee7d0f83d9f6c2305554ed5d5efb Reviewed-on: https://go-review.googlesource.com/c/go/+/714140 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Alan Donovan <adonovan@google.com> Reviewed-by: Alan Donovan <adonovan@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Joel Sing <joel@sing.id.au>
This commit is contained in:
parent
ca448191c9
commit
39ed968832
10 changed files with 3507 additions and 571 deletions
|
|
@ -4,7 +4,7 @@ go 1.26
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5
|
github.com/google/pprof v0.0.0-20250630185457-6e76a2b096b5
|
||||||
golang.org/x/arch v0.20.1-0.20250808194827-46ba08e3ae58
|
golang.org/x/arch v0.22.1-0.20251016010524-fea4a9ec4938
|
||||||
golang.org/x/build v0.0.0-20250806225920-b7c66c047964
|
golang.org/x/build v0.0.0-20250806225920-b7c66c047964
|
||||||
golang.org/x/mod v0.29.0
|
golang.org/x/mod v0.29.0
|
||||||
golang.org/x/sync v0.17.0
|
golang.org/x/sync v0.17.0
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b h1:ogbOPx8
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
|
github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
|
||||||
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
|
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
|
||||||
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
golang.org/x/arch v0.20.1-0.20250808194827-46ba08e3ae58 h1:uxPa6+/WsUfzikIAPMqpTho10y4qtYpINBurU+6NrHE=
|
golang.org/x/arch v0.22.1-0.20251016010524-fea4a9ec4938 h1:VJ182b/ajNehMFRltVfCh/FR0jAH+QX6hs9zqYod/mU=
|
||||||
golang.org/x/arch v0.20.1-0.20250808194827-46ba08e3ae58/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
golang.org/x/arch v0.22.1-0.20251016010524-fea4a9ec4938/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||||
golang.org/x/build v0.0.0-20250806225920-b7c66c047964 h1:yRs1K51GKq7hsIO+YHJ8LsslrvwFceNPIv0tYjpcBd0=
|
golang.org/x/build v0.0.0-20250806225920-b7c66c047964 h1:yRs1K51GKq7hsIO+YHJ8LsslrvwFceNPIv0tYjpcBd0=
|
||||||
golang.org/x/build v0.0.0-20250806225920-b7c66c047964/go.mod h1:i9Vx7+aOQUpYJRxSO+OpRStVBCVL/9ccI51xblWm5WY=
|
golang.org/x/build v0.0.0-20250806225920-b7c66c047964/go.mod h1:i9Vx7+aOQUpYJRxSO+OpRStVBCVL/9ccI51xblWm5WY=
|
||||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||||
|
|
|
||||||
31
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/arg.go
generated
vendored
31
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/arg.go
generated
vendored
|
|
@ -22,13 +22,23 @@ package riscv64asm
|
||||||
//
|
//
|
||||||
// - arg_fs3: a floating point register rs3 encoded in rs3[31:27] field
|
// - arg_fs3: a floating point register rs3 encoded in rs3[31:27] field
|
||||||
//
|
//
|
||||||
|
// - arg_vd: a vector register vd encoded in vd[11:7] field
|
||||||
|
//
|
||||||
|
// - arg_vm: indicates the presence of the mask register, encoded in vm[25] field
|
||||||
|
//
|
||||||
|
// - arg_vs1: a vector register vs1 encoded in vs1[19:15] field
|
||||||
|
//
|
||||||
|
// - arg_vs2: a vector register vs3 encoded in vs2[20:24] field
|
||||||
|
//
|
||||||
|
// - arg_vs3: a vector register vs3 encoded in vs3[11:7] field
|
||||||
|
//
|
||||||
// - arg_csr: a control status register encoded in csr[31:20] field
|
// - arg_csr: a control status register encoded in csr[31:20] field
|
||||||
//
|
//
|
||||||
// - arg_rs1_mem: source register with offset in load commands
|
// - arg_rs1_mem: source register with offset in load commands
|
||||||
//
|
//
|
||||||
// - arg_rs1_store: source register with offset in store commands
|
// - arg_rs1_store: source register with offset in store commands
|
||||||
//
|
//
|
||||||
// - arg_rs1_amo: source register with offset in atomic commands
|
// - arg_rs1_ptr: source register used as an address with no offset in atomic and vector commands
|
||||||
//
|
//
|
||||||
// - arg_pred: predecessor memory ordering information encoded in pred[27:24] field
|
// - arg_pred: predecessor memory ordering information encoded in pred[27:24] field
|
||||||
// For details, please refer to chapter 2.7 of ISA manual volume 1
|
// For details, please refer to chapter 2.7 of ISA manual volume 1
|
||||||
|
|
@ -46,6 +56,14 @@ package riscv64asm
|
||||||
//
|
//
|
||||||
// - arg_imm20: an U-type immediate encoded in imm20[31:12] field
|
// - arg_imm20: an U-type immediate encoded in imm20[31:12] field
|
||||||
//
|
//
|
||||||
|
// - arg_simm5: a 5 bit signed immediate encoded in imm[19:15] field
|
||||||
|
//
|
||||||
|
// - arg_zimm5: a 5 bit unsigned immediate encoded in imm[19:15] field
|
||||||
|
//
|
||||||
|
// - arg_vtype_zimm10: a 10 bit unsigned immediate encoded in vtypei[29:20] field
|
||||||
|
//
|
||||||
|
// - arg_vtype_zimm11: an 11 bit unsigned immediate encoded in vtypei[30:20] field
|
||||||
|
//
|
||||||
// - arg_jimm20: a J-type immediate encoded in jimm20[31:12] field
|
// - arg_jimm20: a J-type immediate encoded in jimm20[31:12] field
|
||||||
//
|
//
|
||||||
// - arg_shamt5: a shift amount encoded in shamt5[24:20] field
|
// - arg_shamt5: a shift amount encoded in shamt5[24:20] field
|
||||||
|
|
@ -65,9 +83,14 @@ const (
|
||||||
arg_fs1
|
arg_fs1
|
||||||
arg_fs2
|
arg_fs2
|
||||||
arg_fs3
|
arg_fs3
|
||||||
|
arg_vd
|
||||||
|
arg_vm
|
||||||
|
arg_vs1
|
||||||
|
arg_vs2
|
||||||
|
arg_vs3
|
||||||
arg_csr
|
arg_csr
|
||||||
|
|
||||||
arg_rs1_amo
|
arg_rs1_ptr
|
||||||
arg_rs1_mem
|
arg_rs1_mem
|
||||||
arg_rs1_store
|
arg_rs1_store
|
||||||
|
|
||||||
|
|
@ -77,6 +100,10 @@ const (
|
||||||
arg_zimm
|
arg_zimm
|
||||||
arg_imm12
|
arg_imm12
|
||||||
arg_simm12
|
arg_simm12
|
||||||
|
arg_simm5
|
||||||
|
arg_zimm5
|
||||||
|
arg_vtype_zimm10
|
||||||
|
arg_vtype_zimm11
|
||||||
arg_bimm12
|
arg_bimm12
|
||||||
arg_imm20
|
arg_imm20
|
||||||
arg_jimm20
|
arg_jimm20
|
||||||
|
|
|
||||||
60
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/decode.go
generated
vendored
60
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/decode.go
generated
vendored
|
|
@ -63,16 +63,23 @@ Search:
|
||||||
|
|
||||||
// Decode args.
|
// Decode args.
|
||||||
var args Args
|
var args Args
|
||||||
for j, aop := range f.args {
|
k := 0
|
||||||
|
for _, aop := range f.args {
|
||||||
if aop == 0 {
|
if aop == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
arg := decodeArg(aop, x, i)
|
arg := decodeArg(aop, x, i)
|
||||||
if arg == nil && f.op != C_NOP {
|
if arg == nil {
|
||||||
// Cannot decode argument.
|
if aop == arg_vm {
|
||||||
continue Search
|
continue
|
||||||
|
}
|
||||||
|
if f.op != C_NOP {
|
||||||
|
// Cannot decode argument.
|
||||||
|
continue Search
|
||||||
|
}
|
||||||
}
|
}
|
||||||
args[j] = arg
|
args[k] = arg
|
||||||
|
k++
|
||||||
}
|
}
|
||||||
|
|
||||||
if length == 2 {
|
if length == 2 {
|
||||||
|
|
@ -119,8 +126,27 @@ func decodeArg(aop argType, x uint32, index int) Arg {
|
||||||
case arg_fs3:
|
case arg_fs3:
|
||||||
return F0 + Reg((x>>27)&((1<<5)-1))
|
return F0 + Reg((x>>27)&((1<<5)-1))
|
||||||
|
|
||||||
case arg_rs1_amo:
|
case arg_vd:
|
||||||
return AmoReg{X0 + Reg((x>>15)&((1<<5)-1))}
|
return V0 + Reg((x>>7)&((1<<5)-1))
|
||||||
|
|
||||||
|
case arg_vm:
|
||||||
|
if x&(1<<25) == 0 {
|
||||||
|
return V0
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
case arg_vs1:
|
||||||
|
return V0 + Reg((x>>15)&((1<<5)-1))
|
||||||
|
|
||||||
|
case arg_vs2:
|
||||||
|
return V0 + Reg((x>>20)&((1<<5)-1))
|
||||||
|
|
||||||
|
case arg_vs3:
|
||||||
|
return V0 + Reg((x>>7)&((1<<5)-1))
|
||||||
|
|
||||||
|
case arg_rs1_ptr:
|
||||||
|
return RegPtr{X0 + Reg((x>>15)&((1<<5)-1))}
|
||||||
|
|
||||||
case arg_rs1_mem:
|
case arg_rs1_mem:
|
||||||
imm := x >> 20
|
imm := x >> 20
|
||||||
|
|
@ -198,6 +224,26 @@ func decodeArg(aop argType, x uint32, index int) Arg {
|
||||||
}
|
}
|
||||||
return Simm{int32(imm), true, 13}
|
return Simm{int32(imm), true, 13}
|
||||||
|
|
||||||
|
case arg_simm5:
|
||||||
|
imm := x << 12 >> 27
|
||||||
|
// Sign-extend
|
||||||
|
if imm>>uint32(5-1) == 1 {
|
||||||
|
imm |= 0x7ffffff << 5
|
||||||
|
}
|
||||||
|
return Simm{int32(imm), true, 5}
|
||||||
|
|
||||||
|
case arg_zimm5:
|
||||||
|
imm := x << 12 >> 27
|
||||||
|
return Uimm{imm, true}
|
||||||
|
|
||||||
|
case arg_vtype_zimm10:
|
||||||
|
imm := x << 2 >> 22
|
||||||
|
return VType(imm)
|
||||||
|
|
||||||
|
case arg_vtype_zimm11:
|
||||||
|
imm := x << 1 >> 21
|
||||||
|
return VType(imm)
|
||||||
|
|
||||||
case arg_rd_p, arg_rs2_p:
|
case arg_rd_p, arg_rs2_p:
|
||||||
return X8 + Reg((x>>2)&((1<<3)-1))
|
return X8 + Reg((x>>2)&((1<<3)-1))
|
||||||
|
|
||||||
|
|
|
||||||
73
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/gnu.go
generated
vendored
73
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/gnu.go
generated
vendored
|
|
@ -12,15 +12,23 @@ import (
|
||||||
// This form typically matches the syntax defined in the RISC-V Instruction Set Manual. See
|
// This form typically matches the syntax defined in the RISC-V Instruction Set Manual. See
|
||||||
// https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf
|
// https://github.com/riscv/riscv-isa-manual/releases/download/Ratified-IMAFDQC/riscv-spec-20191213.pdf
|
||||||
func GNUSyntax(inst Inst) string {
|
func GNUSyntax(inst Inst) string {
|
||||||
op := strings.ToLower(inst.Op.String())
|
hasVectorArg := false
|
||||||
var args []string
|
var args []string
|
||||||
for _, a := range inst.Args {
|
for _, a := range inst.Args {
|
||||||
if a == nil {
|
if a == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
args = append(args, strings.ToLower(a.String()))
|
args = append(args, strings.ToLower(a.String()))
|
||||||
|
if r, ok := a.(Reg); ok {
|
||||||
|
hasVectorArg = hasVectorArg || (r >= V0 && r <= V31)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if hasVectorArg {
|
||||||
|
return gnuVectorOp(inst, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
op := strings.ToLower(inst.Op.String())
|
||||||
switch inst.Op {
|
switch inst.Op {
|
||||||
case ADDI, ADDIW, ANDI, ORI, SLLI, SLLIW, SRAI, SRAIW, SRLI, SRLIW, XORI:
|
case ADDI, ADDIW, ANDI, ORI, SLLI, SLLIW, SRAI, SRAIW, SRLI, SRLIW, XORI:
|
||||||
if inst.Op == ADDI {
|
if inst.Op == ADDI {
|
||||||
|
|
@ -324,6 +332,12 @@ func GNUSyntax(inst Inst) string {
|
||||||
args[1] = args[2]
|
args[1] = args[2]
|
||||||
args = args[:len(args)-1]
|
args = args[:len(args)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case VSETVLI, VSETIVLI:
|
||||||
|
args[0], args[2] = args[2], strings.ReplaceAll(args[0], " ", "")
|
||||||
|
|
||||||
|
case VSETVL:
|
||||||
|
args[0], args[2] = args[2], args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
if args != nil {
|
if args != nil {
|
||||||
|
|
@ -331,3 +345,60 @@ func GNUSyntax(inst Inst) string {
|
||||||
}
|
}
|
||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func gnuVectorOp(inst Inst, args []string) string {
|
||||||
|
// Instruction is either a vector load, store or an arithmetic
|
||||||
|
// operation. We can use the inst.Enc to figure out which. Whatever
|
||||||
|
// it is, it has at least one argument.
|
||||||
|
|
||||||
|
rawArgs := inst.Args[:]
|
||||||
|
|
||||||
|
var mask string
|
||||||
|
var op string
|
||||||
|
if inst.Enc&(1<<25) == 0 {
|
||||||
|
if implicitMask(inst.Op) {
|
||||||
|
mask = "v0"
|
||||||
|
} else {
|
||||||
|
mask = "v0.t"
|
||||||
|
args = args[1:]
|
||||||
|
rawArgs = rawArgs[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) > 1 {
|
||||||
|
if inst.Enc&0x7f == 0x7 || inst.Enc&0x7f == 0x27 {
|
||||||
|
// It's a load or a store
|
||||||
|
if len(args) >= 2 {
|
||||||
|
args[0], args[len(args)-1] = args[len(args)-1], args[0]
|
||||||
|
}
|
||||||
|
op = pseudoRVVLoad(inst.Op)
|
||||||
|
} else {
|
||||||
|
// It's an arithmetic instruction
|
||||||
|
|
||||||
|
op, args = pseudoRVVArith(inst.Op, rawArgs, args)
|
||||||
|
|
||||||
|
if len(args) == 3 {
|
||||||
|
if imaOrFma(inst.Op) {
|
||||||
|
args[0], args[2] = args[2], args[0]
|
||||||
|
} else {
|
||||||
|
args[0], args[1], args[2] = args[2], args[0], args[1]
|
||||||
|
}
|
||||||
|
} else if len(args) == 2 {
|
||||||
|
args[0], args[1] = args[1], args[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The mask is always the last argument
|
||||||
|
|
||||||
|
if mask != "" {
|
||||||
|
args = append(args, mask)
|
||||||
|
}
|
||||||
|
|
||||||
|
if op == "" {
|
||||||
|
op = inst.Op.String()
|
||||||
|
}
|
||||||
|
op = strings.ToLower(op)
|
||||||
|
|
||||||
|
return op + " " + strings.Join(args, ",")
|
||||||
|
}
|
||||||
|
|
|
||||||
67
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/inst.go
generated
vendored
67
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/inst.go
generated
vendored
|
|
@ -59,7 +59,7 @@ func (i Inst) String() string {
|
||||||
type Reg uint16
|
type Reg uint16
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// General-purpose register
|
// General-purpose registers
|
||||||
X0 Reg = iota
|
X0 Reg = iota
|
||||||
X1
|
X1
|
||||||
X2
|
X2
|
||||||
|
|
@ -93,7 +93,7 @@ const (
|
||||||
X30
|
X30
|
||||||
X31
|
X31
|
||||||
|
|
||||||
//Float point register
|
// Floating point registers
|
||||||
F0
|
F0
|
||||||
F1
|
F1
|
||||||
F2
|
F2
|
||||||
|
|
@ -126,6 +126,40 @@ const (
|
||||||
F29
|
F29
|
||||||
F30
|
F30
|
||||||
F31
|
F31
|
||||||
|
|
||||||
|
// Vector registers
|
||||||
|
V0
|
||||||
|
V1
|
||||||
|
V2
|
||||||
|
V3
|
||||||
|
V4
|
||||||
|
V5
|
||||||
|
V6
|
||||||
|
V7
|
||||||
|
V8
|
||||||
|
V9
|
||||||
|
V10
|
||||||
|
V11
|
||||||
|
V12
|
||||||
|
V13
|
||||||
|
V14
|
||||||
|
V15
|
||||||
|
V16
|
||||||
|
V17
|
||||||
|
V18
|
||||||
|
V19
|
||||||
|
V20
|
||||||
|
V21
|
||||||
|
V22
|
||||||
|
V23
|
||||||
|
V24
|
||||||
|
V25
|
||||||
|
V26
|
||||||
|
V27
|
||||||
|
V28
|
||||||
|
V29
|
||||||
|
V30
|
||||||
|
V31
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r Reg) String() string {
|
func (r Reg) String() string {
|
||||||
|
|
@ -136,6 +170,9 @@ func (r Reg) String() string {
|
||||||
case r >= F0 && r <= F31:
|
case r >= F0 && r <= F31:
|
||||||
return fmt.Sprintf("f%d", r-F0)
|
return fmt.Sprintf("f%d", r-F0)
|
||||||
|
|
||||||
|
case r >= V0 && r <= V31:
|
||||||
|
return fmt.Sprintf("v%d", r-V0)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("Unknown(%d)", r)
|
return fmt.Sprintf("Unknown(%d)", r)
|
||||||
}
|
}
|
||||||
|
|
@ -455,13 +492,13 @@ func (si Simm) String() string {
|
||||||
return fmt.Sprintf("%#x", si.Imm)
|
return fmt.Sprintf("%#x", si.Imm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// An AmoReg is an atomic address register used in AMO instructions
|
// A RegPtr is an address register with no offset
|
||||||
type AmoReg struct {
|
type RegPtr struct {
|
||||||
reg Reg // Avoid promoted String method
|
reg Reg // Avoid promoted String method
|
||||||
}
|
}
|
||||||
|
|
||||||
func (amoReg AmoReg) String() string {
|
func (regPtr RegPtr) String() string {
|
||||||
return fmt.Sprintf("(%s)", amoReg.reg)
|
return fmt.Sprintf("(%s)", regPtr.reg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A RegOffset is a register with offset value
|
// A RegOffset is a register with offset value
|
||||||
|
|
@ -493,3 +530,21 @@ func (memOrder MemOrder) String() string {
|
||||||
}
|
}
|
||||||
return str
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A VType represents the vtype field of VSETIVLI and VSETVLI instructions
|
||||||
|
type VType uint32
|
||||||
|
|
||||||
|
var vlmulName = []string{"M1", "M2", "M4", "M8", "", "MF8", "MF4", "MF2"}
|
||||||
|
var vsewName = []string{"E8", "E16", "E32", "E64", "", "", "", ""}
|
||||||
|
var vtaName = []string{"TU", "TA"}
|
||||||
|
var vmaName = []string{"MU", "MA"}
|
||||||
|
|
||||||
|
func (vtype VType) String() string {
|
||||||
|
|
||||||
|
vlmul := vtype & 0x7
|
||||||
|
vsew := (vtype >> 3) & 0x7
|
||||||
|
vta := (vtype >> 6) & 0x1
|
||||||
|
vma := (vtype >> 7) & 0x1
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s, %s, %s, %s", vsewName[vsew], vlmulName[vlmul], vtaName[vta], vmaName[vma])
|
||||||
|
}
|
||||||
|
|
|
||||||
99
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/plan9x.go
generated
vendored
99
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/plan9x.go
generated
vendored
|
|
@ -26,12 +26,20 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
|
||||||
symname = func(uint64) (string, uint64) { return "", 0 }
|
symname = func(uint64) (string, uint64) { return "", 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasVectorArg := false
|
||||||
var args []string
|
var args []string
|
||||||
for _, a := range inst.Args {
|
for _, a := range inst.Args {
|
||||||
if a == nil {
|
if a == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
args = append(args, plan9Arg(&inst, pc, symname, a))
|
args = append(args, plan9Arg(&inst, pc, symname, a))
|
||||||
|
if r, ok := a.(Reg); ok {
|
||||||
|
hasVectorArg = hasVectorArg || (r >= V0 && r <= V31)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasVectorArg {
|
||||||
|
return plan9VectorOp(inst, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
op := inst.Op.String()
|
op := inst.Op.String()
|
||||||
|
|
@ -180,6 +188,22 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
|
||||||
FNMSUB_D, FNMSUB_H, FNMSUB_Q, FNMSUB_S:
|
FNMSUB_D, FNMSUB_H, FNMSUB_Q, FNMSUB_S:
|
||||||
args[1], args[3] = args[3], args[1]
|
args[1], args[3] = args[3], args[1]
|
||||||
|
|
||||||
|
case FMV_W_X:
|
||||||
|
if inst.Args[1].(Reg) == X0 {
|
||||||
|
args[1] = "$(0.0)"
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case FMV_X_W:
|
||||||
|
op = "MOVF"
|
||||||
|
|
||||||
|
case FMV_D_X:
|
||||||
|
if inst.Args[1].(Reg) == X0 {
|
||||||
|
args[1] = "$(0.0)"
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case FMV_X_D:
|
||||||
|
op = "MOVD"
|
||||||
|
|
||||||
case FSGNJ_S:
|
case FSGNJ_S:
|
||||||
if inst.Args[2] == inst.Args[1] {
|
if inst.Args[2] == inst.Args[1] {
|
||||||
op = "MOVF"
|
op = "MOVF"
|
||||||
|
|
@ -251,13 +275,13 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
|
||||||
|
|
||||||
case FLW, FSW:
|
case FLW, FSW:
|
||||||
op = "MOVF"
|
op = "MOVF"
|
||||||
if inst.Op == FLW {
|
if inst.Op == FSW {
|
||||||
args[0], args[1] = args[1], args[0]
|
args[0], args[1] = args[1], args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
case FLD, FSD:
|
case FLD, FSD:
|
||||||
op = "MOVD"
|
op = "MOVD"
|
||||||
if inst.Op == FLD {
|
if inst.Op == FSD {
|
||||||
args[0], args[1] = args[1], args[0]
|
args[0], args[1] = args[1], args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,6 +341,12 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
|
||||||
} else {
|
} else {
|
||||||
args[0], args[1] = args[1], args[0]
|
args[0], args[1] = args[1], args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case VSETVLI, VSETIVLI:
|
||||||
|
args[0], args[1], args[2] = args[2], args[0], args[1]
|
||||||
|
|
||||||
|
case VSETVL:
|
||||||
|
args[0], args[2] = args[2], args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverse args, placing dest last.
|
// Reverse args, placing dest last.
|
||||||
|
|
@ -354,13 +384,6 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("$%d", int32(imm))
|
return fmt.Sprintf("$%d", int32(imm))
|
||||||
|
|
||||||
case Reg:
|
|
||||||
if a <= 31 {
|
|
||||||
return fmt.Sprintf("X%d", a)
|
|
||||||
} else {
|
|
||||||
return fmt.Sprintf("F%d", a-32)
|
|
||||||
}
|
|
||||||
|
|
||||||
case RegOffset:
|
case RegOffset:
|
||||||
if a.Ofs.Imm == 0 {
|
if a.Ofs.Imm == 0 {
|
||||||
return fmt.Sprintf("(X%d)", a.OfsReg)
|
return fmt.Sprintf("(X%d)", a.OfsReg)
|
||||||
|
|
@ -368,10 +391,66 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
|
||||||
return fmt.Sprintf("%s(X%d)", a.Ofs.String(), a.OfsReg)
|
return fmt.Sprintf("%s(X%d)", a.Ofs.String(), a.OfsReg)
|
||||||
}
|
}
|
||||||
|
|
||||||
case AmoReg:
|
case RegPtr:
|
||||||
return fmt.Sprintf("(X%d)", a.reg)
|
return fmt.Sprintf("(X%d)", a.reg)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return strings.ToUpper(arg.String())
|
return strings.ToUpper(arg.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func plan9VectorOp(inst Inst, args []string) string {
|
||||||
|
// Instruction is either a vector load, store or an arithmetic
|
||||||
|
// operation. We can use the inst.Enc to figure out which. Whatever
|
||||||
|
// it is, it has at least one argument.
|
||||||
|
|
||||||
|
var op string
|
||||||
|
rawArgs := inst.Args[:]
|
||||||
|
|
||||||
|
var mask string
|
||||||
|
if inst.Enc&(1<<25) == 0 {
|
||||||
|
mask = "V0"
|
||||||
|
if !implicitMask(inst.Op) {
|
||||||
|
args = args[1:]
|
||||||
|
rawArgs = rawArgs[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) > 1 {
|
||||||
|
if inst.Enc&0x7f == 0x7 {
|
||||||
|
// It's a load
|
||||||
|
if len(args) == 3 {
|
||||||
|
args[0], args[1] = args[1], args[0]
|
||||||
|
}
|
||||||
|
op = pseudoRVVLoad(inst.Op)
|
||||||
|
} else if inst.Enc&0x7f == 0x27 {
|
||||||
|
// It's a store
|
||||||
|
if len(args) == 3 {
|
||||||
|
args[0], args[1], args[2] = args[2], args[0], args[1]
|
||||||
|
} else if len(args) == 2 {
|
||||||
|
args[0], args[1] = args[1], args[0]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// It's an arithmetic instruction
|
||||||
|
|
||||||
|
op, args = pseudoRVVArith(inst.Op, rawArgs, args)
|
||||||
|
|
||||||
|
if len(args) == 3 && !imaOrFma(inst.Op) {
|
||||||
|
args[0], args[1] = args[1], args[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The mask is always the penultimate argument
|
||||||
|
|
||||||
|
if mask != "" {
|
||||||
|
args = append(args[:len(args)-1], mask, args[len(args)-1])
|
||||||
|
}
|
||||||
|
|
||||||
|
if op == "" {
|
||||||
|
op = inst.Op.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
op = strings.Replace(op, ".", "", -1)
|
||||||
|
return op + " " + strings.Join(args, ", ")
|
||||||
|
}
|
||||||
|
|
|
||||||
3596
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/tables.go
generated
vendored
3596
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
142
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/vector.go
generated
vendored
Normal file
142
src/cmd/vendor/golang.org/x/arch/riscv64/riscv64asm/vector.go
generated
vendored
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package riscv64asm
|
||||||
|
|
||||||
|
// This file contains some utility functions that can be used to decode
|
||||||
|
// vector instructions into both gnu and plan9 assembly.
|
||||||
|
|
||||||
|
func implicitMask(instOp Op) bool {
|
||||||
|
switch instOp {
|
||||||
|
case VADC_VIM, VADC_VVM, VADC_VXM, VFMERGE_VFM, VMADC_VIM, VMADC_VVM,
|
||||||
|
VMADC_VXM, VMERGE_VIM, VMERGE_VVM, VMERGE_VXM, VMSBC_VVM, VMSBC_VXM,
|
||||||
|
VSBC_VVM, VSBC_VXM:
|
||||||
|
return true
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func imaOrFma(instOp Op) bool {
|
||||||
|
switch instOp {
|
||||||
|
case VFMACC_VF, VFMACC_VV, VFMADD_VF, VFMADD_VV, VFMSAC_VF, VFMSAC_VV,
|
||||||
|
VFMSUB_VF, VFMSUB_VV, VFNMACC_VF, VFNMACC_VV, VFNMADD_VF, VFNMADD_VV,
|
||||||
|
VFNMSAC_VF, VFNMSAC_VV, VFNMSUB_VF, VFNMSUB_VV, VFWMACC_VF, VFWMACC_VV,
|
||||||
|
VFWMSAC_VF, VFWMSAC_VV, VFWNMACC_VF, VFWNMACC_VV, VFWNMSAC_VF,
|
||||||
|
VFWNMSAC_VV, VMACC_VV, VMACC_VX, VMADD_VV, VMADD_VX, VNMSAC_VV,
|
||||||
|
VNMSAC_VX, VNMSUB_VV, VNMSUB_VX, VWMACCSU_VV, VWMACCSU_VX, VWMACCUS_VX,
|
||||||
|
VWMACCU_VV, VWMACCU_VX, VWMACC_VV, VWMACC_VX:
|
||||||
|
return true
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func pseudoRVVLoad(instOp Op) string {
|
||||||
|
switch instOp {
|
||||||
|
case VL1RE8_V:
|
||||||
|
return "VL1R.V"
|
||||||
|
|
||||||
|
case VL2RE8_V:
|
||||||
|
return "VL2R.V"
|
||||||
|
|
||||||
|
case VL4RE8_V:
|
||||||
|
return "VL4R.V"
|
||||||
|
|
||||||
|
case VL8RE8_V:
|
||||||
|
return "VL8R.V"
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func pseudoRVVArith(instOp Op, rawArgs []Arg, args []string) (string, []string) {
|
||||||
|
var op string
|
||||||
|
|
||||||
|
switch instOp {
|
||||||
|
case VRSUB_VX:
|
||||||
|
if v, ok := rawArgs[1].(Reg); ok && v == X0 {
|
||||||
|
op = "VNEG.V"
|
||||||
|
args = append(args[:1], args[2:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case VWADD_VX:
|
||||||
|
if v, ok := rawArgs[1].(Reg); ok && v == X0 {
|
||||||
|
op = "VWCVT.X.X.V"
|
||||||
|
args = append(args[:1], args[2:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case VWADDU_VX:
|
||||||
|
if v, ok := rawArgs[1].(Reg); ok && v == X0 {
|
||||||
|
op = "VWCVTU.X.X.V"
|
||||||
|
args = append(args[:1], args[2:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case VXOR_VI:
|
||||||
|
if v, ok := rawArgs[1].(Simm); ok && v.Imm == -1 {
|
||||||
|
op = "VNOT.V"
|
||||||
|
args = append(args[:1], args[2:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case VNSRL_WX:
|
||||||
|
if v, ok := rawArgs[1].(Reg); ok && v == X0 {
|
||||||
|
op = "VNCVT.X.X.W"
|
||||||
|
args = append(args[:1], args[2:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
case VFSGNJN_VV:
|
||||||
|
vs2, ok1 := rawArgs[0].(Reg)
|
||||||
|
vs1, ok2 := rawArgs[1].(Reg)
|
||||||
|
if ok1 && ok2 && vs1 == vs2 {
|
||||||
|
op = "VFNEG.V"
|
||||||
|
args = args[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
case VFSGNJX_VV:
|
||||||
|
vs2, ok1 := rawArgs[0].(Reg)
|
||||||
|
vs1, ok2 := rawArgs[1].(Reg)
|
||||||
|
if ok1 && ok2 && vs1 == vs2 {
|
||||||
|
op = "VFABS.V"
|
||||||
|
args = args[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
case VMAND_MM:
|
||||||
|
vs2, ok1 := rawArgs[0].(Reg)
|
||||||
|
vs1, ok2 := rawArgs[1].(Reg)
|
||||||
|
if ok1 && ok2 && vs1 == vs2 {
|
||||||
|
op = "VMMV.M"
|
||||||
|
args = args[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
case VMXOR_MM:
|
||||||
|
vs2, ok1 := rawArgs[0].(Reg)
|
||||||
|
vs1, ok2 := rawArgs[1].(Reg)
|
||||||
|
vd, ok3 := rawArgs[2].(Reg)
|
||||||
|
if ok1 && ok2 && ok3 && vs1 == vs2 && vd == vs1 {
|
||||||
|
op = "VMCLR.M"
|
||||||
|
args = args[2:]
|
||||||
|
}
|
||||||
|
|
||||||
|
case VMXNOR_MM:
|
||||||
|
vs2, ok1 := rawArgs[0].(Reg)
|
||||||
|
vs1, ok2 := rawArgs[1].(Reg)
|
||||||
|
vd, ok3 := rawArgs[2].(Reg)
|
||||||
|
if ok1 && ok2 && ok3 && vs1 == vs2 && vd == vs1 {
|
||||||
|
op = "VMSET.M"
|
||||||
|
args = args[2:]
|
||||||
|
}
|
||||||
|
|
||||||
|
case VMNAND_MM:
|
||||||
|
vs2, ok1 := rawArgs[0].(Reg)
|
||||||
|
vs1, ok2 := rawArgs[1].(Reg)
|
||||||
|
if ok1 && ok2 && vs1 == vs2 {
|
||||||
|
op = "VMNOT.M"
|
||||||
|
args = args[1:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return op, args
|
||||||
|
}
|
||||||
4
src/cmd/vendor/modules.txt
vendored
4
src/cmd/vendor/modules.txt
vendored
|
|
@ -16,8 +16,8 @@ github.com/google/pprof/third_party/svgpan
|
||||||
# github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b
|
# github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/ianlancetaylor/demangle
|
github.com/ianlancetaylor/demangle
|
||||||
# golang.org/x/arch v0.20.1-0.20250808194827-46ba08e3ae58
|
# golang.org/x/arch v0.22.1-0.20251016010524-fea4a9ec4938
|
||||||
## explicit; go 1.23.0
|
## explicit; go 1.24.0
|
||||||
golang.org/x/arch/arm/armasm
|
golang.org/x/arch/arm/armasm
|
||||||
golang.org/x/arch/arm64/arm64asm
|
golang.org/x/arch/arm64/arm64asm
|
||||||
golang.org/x/arch/loong64/loong64asm
|
golang.org/x/arch/loong64/loong64asm
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue