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:
Joel Sing 2025-10-23 22:34:36 +11:00 committed by Gopher Robot
parent ca448191c9
commit 39ed968832
10 changed files with 3507 additions and 571 deletions

View file

@ -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

View file

@ -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=

View file

@ -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

View file

@ -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))

View file

@ -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, ",")
}

View file

@ -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])
}

View file

@ -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, ", ")
}

File diff suppressed because it is too large Load diff

View 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
}

View file

@ -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