mirror of
https://github.com/golang/go.git
synced 2026-06-27 03:11:23 +00:00
cmd: update vendored x/arch
Update vendored x/arch repo to 9c1a596, to bring in the support of AVX instructions in the disassembler. Done by cd GOROOT/src/cmd go get golang.org/x/arch@master go mod tidy go mod vendor Fixes #78065. Change-Id: Ie37b9e1ac57f9c8617d2613de164874ed8cb3a8c Reviewed-on: https://go-review.googlesource.com/c/go/+/781281 TryBot-Bypass: Cherry Mui <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
0db3804845
commit
8621461b26
11 changed files with 16375 additions and 7616 deletions
|
|
@ -4,7 +4,7 @@ go 1.27
|
|||
|
||||
require (
|
||||
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83
|
||||
golang.org/x/arch v0.27.1-0.20260513003155-2ebc08890589
|
||||
golang.org/x/arch v0.27.1-0.20260521044007-9c1a596a2c97
|
||||
golang.org/x/build v0.0.0-20260122183339-3ba88df37c64
|
||||
golang.org/x/mod v0.36.1-0.20260513122029-343ee60345a1
|
||||
golang.org/x/sync v0.20.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/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
|
||||
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/arch v0.27.1-0.20260513003155-2ebc08890589 h1:vhLfA6kUzRvCYV5uFBJbdMndztX1STqGC8GmQJsuldY=
|
||||
golang.org/x/arch v0.27.1-0.20260513003155-2ebc08890589/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8=
|
||||
golang.org/x/arch v0.27.1-0.20260521044007-9c1a596a2c97 h1:OEbDVxixMxnrAI3whhcFkCb0rPrEHwxeSSUMdN0V414=
|
||||
golang.org/x/arch v0.27.1-0.20260521044007-9c1a596a2c97/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8=
|
||||
golang.org/x/build v0.0.0-20260122183339-3ba88df37c64 h1:BNhBATNmH/VtzGolB+ksQPPvn6ZyffiR8TmKenqNo+A=
|
||||
golang.org/x/build v0.0.0-20260122183339-3ba88df37c64/go.mod h1:3QmSbNil8ZWqC94m80Glej1v8b92gYzPIQPTtSa0c+4=
|
||||
golang.org/x/mod v0.36.1-0.20260513122029-343ee60345a1 h1:C0TwvxhsI0bHc1TbK4QEa5PCMrHiST7y/lpX4MVW3KM=
|
||||
|
|
|
|||
653
src/cmd/vendor/golang.org/x/arch/x86/x86asm/avx.go
generated
vendored
Normal file
653
src/cmd/vendor/golang.org/x/arch/x86/x86asm/avx.go
generated
vendored
Normal file
|
|
@ -0,0 +1,653 @@
|
|||
// Copyright 2026 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 x86asm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// This file contains the handling of AVX instructions, based on
|
||||
// tables (avx_tables.go) generated from the XED data.
|
||||
|
||||
//go:generate go run _gen/genavx.go -o avx_tables.go
|
||||
|
||||
// decodeAVX decodes AVX/AVX2/AVX-512 instructions.
|
||||
// It is called from decode1 when a VEX or EVEX prefix is detected.
|
||||
func decodeAVX(src []byte, pos int, vex Prefix, vexIndex int, inst Inst, mode int) (Inst, error) {
|
||||
var vexP, vexL, vexW uint8
|
||||
var mapSelect uint8
|
||||
var vvvv uint8
|
||||
var vexR, vexX, vexB uint8 // Inverted from VEX/EVEX
|
||||
var evex bool
|
||||
var evexR_prime, evexV_prime uint8 // Inverted
|
||||
var evex_aaa, evex_z uint8
|
||||
var evex_b uint8
|
||||
|
||||
vexR = 1
|
||||
vexX = 1
|
||||
vexB = 1 // Default to 1 (inactive inverted)
|
||||
evexR_prime = 1
|
||||
evexV_prime = 1
|
||||
|
||||
if vex == 0xC5 { // 2-byte VEX
|
||||
b1 := uint8(inst.Prefix[vexIndex+1])
|
||||
vexR = (b1 >> 7) & 1
|
||||
vvvv = (b1 >> 3) & 0xF
|
||||
vexL = (b1 >> 2) & 1
|
||||
vexP = b1 & 3
|
||||
mapSelect = 1 // 0F
|
||||
} else if vex == 0xC4 { // 3-byte VEX
|
||||
b1 := uint8(inst.Prefix[vexIndex+1])
|
||||
b2 := uint8(inst.Prefix[vexIndex+2])
|
||||
vexR = (b1 >> 7) & 1
|
||||
vexX = (b1 >> 6) & 1
|
||||
vexB = (b1 >> 5) & 1
|
||||
mapSelect = b1 & 0x1F
|
||||
|
||||
vexW = (b2 >> 7) & 1
|
||||
vvvv = (b2 >> 3) & 0xF
|
||||
vexL = (b2 >> 2) & 1
|
||||
vexP = b2 & 3
|
||||
} else if vex == 0x62 { // EVEX
|
||||
evex = true
|
||||
b1 := uint8(inst.Prefix[vexIndex+1])
|
||||
b2 := uint8(inst.Prefix[vexIndex+2])
|
||||
b3 := uint8(inst.Prefix[vexIndex+3])
|
||||
|
||||
vexR = (b1 >> 7) & 1
|
||||
vexX = (b1 >> 6) & 1
|
||||
vexB = (b1 >> 5) & 1
|
||||
evexR_prime = (b1 >> 4) & 1
|
||||
mapSelect = b1 & 3
|
||||
|
||||
vexW = (b2 >> 7) & 1
|
||||
vvvv = (b2 >> 3) & 0xF
|
||||
vexP = b2 & 3
|
||||
|
||||
evex_z = (b3 >> 7) & 1
|
||||
vexL = (b3 >> 5) & 3
|
||||
evex_b = (b3 >> 4) & 1
|
||||
evexV_prime = (b3 >> 3) & 1
|
||||
evex_aaa = b3 & 7
|
||||
}
|
||||
|
||||
_ = evex_z // TODO: use zeroing mask if needed for output
|
||||
|
||||
opbyte := src[pos]
|
||||
pos++
|
||||
|
||||
var candidates []*avxOptab
|
||||
switch mapSelect {
|
||||
case 1:
|
||||
candidates = avxMap0F[opbyte]
|
||||
case 2:
|
||||
candidates = avxMap0F38[opbyte]
|
||||
case 3:
|
||||
candidates = avxMap0F3A[opbyte]
|
||||
}
|
||||
|
||||
if len(candidates) == 0 {
|
||||
return inst, errors.New("unknown AVX Opcode")
|
||||
}
|
||||
|
||||
var modrm uint8
|
||||
var haveModRM bool
|
||||
if pos < len(src) {
|
||||
modrm = src[pos]
|
||||
haveModRM = true
|
||||
}
|
||||
|
||||
var match *avxOptab
|
||||
|
||||
for i := range candidates {
|
||||
c := candidates[i]
|
||||
if evex != c.evex {
|
||||
continue
|
||||
}
|
||||
c_vexP := c.vexP
|
||||
p_match := false
|
||||
switch c_vexP {
|
||||
case 0:
|
||||
p_match = vexP == 0
|
||||
case 1:
|
||||
p_match = vexP == 1
|
||||
case 2:
|
||||
p_match = vexP == 3
|
||||
case 3:
|
||||
p_match = vexP == 2
|
||||
}
|
||||
if !p_match {
|
||||
continue
|
||||
}
|
||||
|
||||
match_vexL := vexL
|
||||
if evex && evex_b != 0 && haveModRM && (modrm>>6) == 3 {
|
||||
hasZmm := false
|
||||
for j := range candidates {
|
||||
if candidates[j].evex == c.evex && candidates[j].vexP == c.vexP && candidates[j].vexW == c.vexW && candidates[j].vexL == 2 {
|
||||
hasZmm = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasZmm {
|
||||
match_vexL = 2
|
||||
} else {
|
||||
match_vexL = 0
|
||||
}
|
||||
}
|
||||
if c.vexL != match_vexL {
|
||||
continue
|
||||
}
|
||||
if c.vexW != vexW {
|
||||
continue
|
||||
}
|
||||
|
||||
if haveModRM {
|
||||
mod := modrm >> 6
|
||||
reg := (modrm >> 3) & 7
|
||||
if c.opdigit != -1 && reg != uint8(c.opdigit) {
|
||||
continue
|
||||
}
|
||||
if c.ismem == 1 && mod == 3 {
|
||||
continue
|
||||
}
|
||||
if c.ismem == 0 && mod != 3 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
match = c
|
||||
break
|
||||
}
|
||||
|
||||
if match == nil {
|
||||
return Inst{Len: 1}, ErrUnrecognized
|
||||
}
|
||||
|
||||
inst.Op = match.op
|
||||
|
||||
var mod, reg, rm uint8
|
||||
var sib uint8
|
||||
var haveSIB bool
|
||||
var mem Mem
|
||||
var addrMode = mode
|
||||
|
||||
if haveModRM {
|
||||
mod = modrm >> 6
|
||||
reg = (modrm >> 3) & 7
|
||||
rm = modrm & 7
|
||||
pos++
|
||||
|
||||
if mod != 3 && rm == 4 {
|
||||
if pos >= len(src) {
|
||||
return inst, errors.New("truncated")
|
||||
}
|
||||
sib = src[pos]
|
||||
haveSIB = true
|
||||
pos++
|
||||
}
|
||||
|
||||
var disp int64
|
||||
if mod == 0 && (rm == 5 || (haveSIB && (sib&7) == 5)) || mod == 2 {
|
||||
if pos+4 > len(src) {
|
||||
return inst, errors.New("truncated")
|
||||
}
|
||||
disp = int64(int32(binary.LittleEndian.Uint32(src[pos:])))
|
||||
pos += 4
|
||||
} else if mod == 1 {
|
||||
if pos >= len(src) {
|
||||
return inst, errors.New("truncated")
|
||||
}
|
||||
disp = int64(int8(src[pos]))
|
||||
pos++
|
||||
if evex && match.dispScale > 0 {
|
||||
scale := match.dispScale
|
||||
if evex_b != 0 && match.bcstScale > 0 {
|
||||
scale = match.bcstScale
|
||||
}
|
||||
disp *= int64(scale)
|
||||
}
|
||||
}
|
||||
mem.Disp = disp
|
||||
|
||||
if haveSIB {
|
||||
scale := sib >> 6
|
||||
index := (sib >> 3) & 7
|
||||
base := sib & 7
|
||||
|
||||
if vexX == 0 {
|
||||
index |= 8
|
||||
}
|
||||
if vexB == 0 {
|
||||
base |= 8
|
||||
}
|
||||
|
||||
mem.Scale = 1 << uint(scale)
|
||||
if index != 4 {
|
||||
mem.Index = baseRegForBits(addrMode) + Reg(index)
|
||||
}
|
||||
if base&7 != 5 || mod != 0 {
|
||||
mem.Base = baseRegForBits(addrMode) + Reg(base)
|
||||
}
|
||||
} else {
|
||||
if vexB == 0 {
|
||||
rm |= 8
|
||||
}
|
||||
|
||||
if mod != 3 {
|
||||
if !(mod == 0 && rm&7 == 5) {
|
||||
mem.Base = baseRegForBits(addrMode) + Reg(rm)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decode Args
|
||||
for i, argType := range match.args {
|
||||
if argType == argNone {
|
||||
continue
|
||||
}
|
||||
var arg Arg
|
||||
|
||||
switch argType {
|
||||
case argImm8:
|
||||
if pos >= len(src) {
|
||||
return inst, errors.New("truncated")
|
||||
}
|
||||
arg = Imm(src[pos])
|
||||
pos++
|
||||
case argImm8u:
|
||||
if pos >= len(src) {
|
||||
return inst, errors.New("truncated")
|
||||
}
|
||||
arg = Imm(src[pos])
|
||||
pos++
|
||||
case argXmm_SE, argYmm_SE:
|
||||
if pos >= len(src) {
|
||||
return inst, errors.New("truncated")
|
||||
}
|
||||
idx := (src[pos] >> 4) & 0xF
|
||||
if argType == argXmm_SE {
|
||||
arg = X0 + Reg(idx)
|
||||
} else {
|
||||
arg = Y0 + Reg(idx)
|
||||
}
|
||||
pos++
|
||||
case argGPR_R, argGPR32_R, argGPR64_R:
|
||||
idx := reg
|
||||
if vexR == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
base := baseRegForBits(mode)
|
||||
if argType == argGPR32_R {
|
||||
base = EAX
|
||||
} else if argType == argGPR64_R {
|
||||
base = RAX
|
||||
}
|
||||
arg = base + Reg(idx)
|
||||
case argGPR_N, argGPR32_N, argGPR64_N:
|
||||
idx := ^vvvv & 15 // 1s complement
|
||||
base := baseRegForBits(mode)
|
||||
if argType == argGPR32_N {
|
||||
base = EAX
|
||||
} else if argType == argGPR64_N {
|
||||
base = RAX
|
||||
} else if vexW == 1 {
|
||||
base = RAX
|
||||
}
|
||||
arg = base + Reg(idx)
|
||||
case argGPR_B, argGPR32_B, argGPR64_B:
|
||||
idx := rm
|
||||
if vexB == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
base := baseRegForBits(mode)
|
||||
if argType == argGPR32_B {
|
||||
base = EAX
|
||||
} else if argType == argGPR64_B {
|
||||
base = RAX
|
||||
}
|
||||
arg = base + Reg(idx)
|
||||
// VEX/EVEX encoding uses inverted bits for register specifiers (0 means bit is set).
|
||||
case argXmm_R, argXmmEvex_R:
|
||||
idx := reg
|
||||
if vexR == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
if evex && evexR_prime == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
arg = X0 + Reg(idx)
|
||||
case argXmm_B, argXmmEvex_B:
|
||||
idx := rm
|
||||
if vexB == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
if evex && vexX == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
arg = X0 + Reg(idx)
|
||||
case argXmm_N, argXmmEvex_N:
|
||||
idx := 15 - vvvv
|
||||
if evex && evexV_prime == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
arg = X0 + Reg(idx)
|
||||
case argYmm_R, argYmmEvex_R:
|
||||
idx := reg
|
||||
if vexR == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
if evex && evexR_prime == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
arg = Y0 + Reg(idx)
|
||||
case argYmm_B, argYmmEvex_B:
|
||||
idx := rm
|
||||
if vexB == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
if evex && vexX == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
arg = Y0 + Reg(idx)
|
||||
case argYmm_N, argYmmEvex_N:
|
||||
idx := 15 - vvvv
|
||||
if evex && evexV_prime == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
arg = Y0 + Reg(idx)
|
||||
case argZmm_R:
|
||||
vl := vexL
|
||||
if evex && evex_b != 0 && match.ismem == 0 {
|
||||
vl = 2 // RC / SAE implies 512-bit vector length
|
||||
}
|
||||
idx := reg
|
||||
if vexR == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
if evexR_prime == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
if vl == 0 {
|
||||
arg = X0 + Reg(idx)
|
||||
} else if vl == 1 {
|
||||
arg = Y0 + Reg(idx)
|
||||
} else {
|
||||
arg = Z0 + Reg(idx)
|
||||
}
|
||||
case argZmm_B:
|
||||
vl := vexL
|
||||
if evex && evex_b != 0 && match.ismem == 0 {
|
||||
vl = 2
|
||||
}
|
||||
if match.ismem != 0 {
|
||||
arg = mem
|
||||
} else {
|
||||
idx := rm
|
||||
if vexB == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
if vexX == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
if vl == 0 {
|
||||
arg = X0 + Reg(idx)
|
||||
} else if vl == 1 {
|
||||
arg = Y0 + Reg(idx)
|
||||
} else {
|
||||
arg = Z0 + Reg(idx)
|
||||
}
|
||||
}
|
||||
case argZmm_N:
|
||||
vl := vexL
|
||||
if evex && evex_b != 0 && match.ismem == 0 {
|
||||
vl = 2
|
||||
}
|
||||
idx := 15 - vvvv
|
||||
if evexV_prime == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
if vl == 0 {
|
||||
arg = X0 + Reg(idx)
|
||||
} else if vl == 1 {
|
||||
arg = Y0 + Reg(idx)
|
||||
} else {
|
||||
arg = Z0 + Reg(idx)
|
||||
}
|
||||
case argK_R:
|
||||
arg = K0 + Reg(reg&7)
|
||||
case argK_B:
|
||||
arg = K0 + Reg(rm&7)
|
||||
case argK_N:
|
||||
arg = K0 + Reg((15-vvvv)&7)
|
||||
case argKmask:
|
||||
if evex_aaa != 0 {
|
||||
arg = K0 + Reg(evex_aaa)
|
||||
}
|
||||
case argKnot0:
|
||||
if evex_aaa == 0 {
|
||||
return inst, errors.New("k0 mask not allowed")
|
||||
}
|
||||
arg = K0 + Reg(evex_aaa)
|
||||
case argM:
|
||||
arg = mem
|
||||
}
|
||||
|
||||
if arg != nil {
|
||||
inst.Args[i] = arg
|
||||
}
|
||||
}
|
||||
|
||||
n := 0
|
||||
for i := range len(inst.Args) {
|
||||
if inst.Args[i] != nil {
|
||||
if n != i {
|
||||
inst.Args[n] = inst.Args[i]
|
||||
inst.Args[i] = nil
|
||||
}
|
||||
n++
|
||||
}
|
||||
}
|
||||
inst.MemBytes = int(match.memBytes)
|
||||
if inst.MemBytes == 0 && match.ismem != 0 && match.dispScale != 0 {
|
||||
inst.MemBytes = int(match.dispScale)
|
||||
}
|
||||
if evex {
|
||||
inst.Zeroing = evex_z != 0
|
||||
if evex_b != 0 {
|
||||
if match.bcstScale > 0 {
|
||||
inst.Broadcast = true
|
||||
inst.MemBytes = int(match.bcstScale)
|
||||
} else if match.ismem == 0 {
|
||||
inst.SAE = true
|
||||
inst.Rounding = int8(vexL)
|
||||
}
|
||||
}
|
||||
}
|
||||
inst.Len = pos
|
||||
|
||||
if match.vsib && haveSIB {
|
||||
fixVSIB(&inst, vexL, evex, evexV_prime, vexX, sib)
|
||||
}
|
||||
|
||||
return inst, nil
|
||||
}
|
||||
|
||||
// fixVSIB calculates the correct vector register size based on data and index element sizes.
|
||||
func fixVSIB(inst *Inst, vexL uint8, evex bool, evexV_prime uint8, vexX uint8, sib uint8) {
|
||||
var indexElemBits, dataElemBits int
|
||||
switch inst.Op {
|
||||
case VPGATHERDD, VGATHERDPS, VPSCATTERDD, VSCATTERDPS:
|
||||
indexElemBits = 32
|
||||
dataElemBits = 32
|
||||
case VPGATHERDQ, VGATHERDPD, VPSCATTERDQ, VSCATTERDPD:
|
||||
indexElemBits = 32
|
||||
dataElemBits = 64
|
||||
case VPGATHERQD, VGATHERQPS, VPSCATTERQD, VSCATTERQPS:
|
||||
indexElemBits = 64
|
||||
dataElemBits = 32
|
||||
case VPGATHERQQ, VGATHERQPD, VPSCATTERQQ, VSCATTERQPD:
|
||||
indexElemBits = 64
|
||||
dataElemBits = 64
|
||||
case VGATHERPF0DPS, VGATHERPF1DPS, VSCATTERPF0DPS, VSCATTERPF1DPS:
|
||||
indexElemBits = 32
|
||||
dataElemBits = 32
|
||||
case VGATHERPF0DPD, VGATHERPF1DPD, VSCATTERPF0DPD, VSCATTERPF1DPD:
|
||||
indexElemBits = 32
|
||||
dataElemBits = 64
|
||||
case VGATHERPF0QPS, VGATHERPF1QPS, VSCATTERPF0QPS, VSCATTERPF1QPS:
|
||||
indexElemBits = 64
|
||||
dataElemBits = 32
|
||||
case VGATHERPF0QPD, VGATHERPF1QPD, VSCATTERPF0QPD, VSCATTERPF1QPD:
|
||||
indexElemBits = 64
|
||||
dataElemBits = 64
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
maxBits := 128 << vexL
|
||||
|
||||
var destBits, indexVectorBits int
|
||||
if indexElemBits > dataElemBits {
|
||||
indexVectorBits = maxBits
|
||||
numElements := indexVectorBits / indexElemBits
|
||||
destBits = numElements * dataElemBits
|
||||
} else if dataElemBits > indexElemBits {
|
||||
destBits = maxBits
|
||||
numElements := destBits / dataElemBits
|
||||
indexVectorBits = numElements * indexElemBits
|
||||
} else {
|
||||
indexVectorBits = maxBits
|
||||
destBits = maxBits
|
||||
}
|
||||
|
||||
// Override MemBytes to match objdump's output expectation (memory accessed is based on dest size)
|
||||
inst.MemBytes = destBits / 8
|
||||
|
||||
if indexVectorBits < 128 {
|
||||
indexVectorBits = 128
|
||||
}
|
||||
|
||||
var baseReg Reg
|
||||
switch indexVectorBits {
|
||||
case 128:
|
||||
baseReg = X0
|
||||
case 256:
|
||||
baseReg = Y0
|
||||
case 512:
|
||||
baseReg = Z0
|
||||
default:
|
||||
baseReg = X0
|
||||
}
|
||||
|
||||
for i, arg := range inst.Args {
|
||||
if mem, ok := arg.(Mem); ok {
|
||||
idx := (sib >> 3) & 7
|
||||
if vexX == 0 {
|
||||
idx |= 8
|
||||
}
|
||||
if evex && evexV_prime == 0 {
|
||||
idx |= 16
|
||||
}
|
||||
mem.Index = baseReg + Reg(idx)
|
||||
inst.Args[i] = mem
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// argType defines how to decode an argument.
|
||||
// It corresponds to the arg type notation in XED.
|
||||
type argType uint8
|
||||
|
||||
const (
|
||||
argNone argType = iota
|
||||
argImm8
|
||||
argImm8u
|
||||
argImm16
|
||||
argImm32
|
||||
argImm64
|
||||
|
||||
// GPRs
|
||||
argGPR_R // ModRM.reg (default mode size)
|
||||
argGPR_B // ModRM.rm (default mode size)
|
||||
argGPR_N // VEX.vvvv (default mode size)
|
||||
argGPR32_R // ModRM.reg (32-bit forced)
|
||||
argGPR32_B // ModRM.rm (32-bit forced)
|
||||
argGPR32_N // VEX.vvvv (32-bit forced)
|
||||
argGPR64_R // ModRM.reg (64-bit forced)
|
||||
argGPR64_B // ModRM.rm (64-bit forced)
|
||||
argGPR64_N // VEX.vvvv (64-bit forced)
|
||||
|
||||
// XMM
|
||||
argXmm_R
|
||||
argXmm_B
|
||||
argXmm_N
|
||||
argXmmEvex_R
|
||||
argXmmEvex_B
|
||||
argXmmEvex_N
|
||||
argXmm_SE // is4 immediate
|
||||
|
||||
// YMM
|
||||
argYmm_R
|
||||
argYmm_B
|
||||
argYmm_N
|
||||
argYmmEvex_R
|
||||
argYmmEvex_B
|
||||
argYmmEvex_N
|
||||
argYmm_SE
|
||||
|
||||
// ZMM
|
||||
argZmm_R
|
||||
argZmm_B
|
||||
argZmm_N
|
||||
|
||||
// Mask
|
||||
argK_R
|
||||
argK_B
|
||||
argK_N
|
||||
|
||||
argM // Memory operand (ModRM.rm)
|
||||
argKnot0 // Mask register k1-k7
|
||||
argKmask // Mask register k0-k7
|
||||
)
|
||||
|
||||
// hasRC returns true if the instruction supports static rounding control in AVX-512.
|
||||
func hasRC(op Op) bool {
|
||||
switch op {
|
||||
case VADDPD, VADDPS, VADDSD, VADDSS,
|
||||
VSUBPD, VSUBPS, VSUBSD, VSUBSS,
|
||||
VMULPD, VMULPS, VMULSD, VMULSS,
|
||||
VDIVPD, VDIVPS, VDIVSD, VDIVSS,
|
||||
VSQRTPD, VSQRTPS, VSQRTSD, VSQRTSS,
|
||||
VSCALEFPD, VSCALEFPS, VSCALEFSD, VSCALEFSS,
|
||||
VFMADD132PD, VFMADD132PS, VFMADD132SD, VFMADD132SS,
|
||||
VFMADD213PD, VFMADD213PS, VFMADD213SD, VFMADD213SS,
|
||||
VFMADD231PD, VFMADD231PS, VFMADD231SD, VFMADD231SS,
|
||||
VFMSUB132PD, VFMSUB132PS, VFMSUB132SD, VFMSUB132SS,
|
||||
VFMSUB213PD, VFMSUB213PS, VFMSUB213SD, VFMSUB213SS,
|
||||
VFMSUB231PD, VFMSUB231PS, VFMSUB231SD, VFMSUB231SS,
|
||||
VFNMADD132PD, VFNMADD132PS, VFNMADD132SD, VFNMADD132SS,
|
||||
VFNMADD213PD, VFNMADD213PS, VFNMADD213SD, VFNMADD213SS,
|
||||
VFNMADD231PD, VFNMADD231PS, VFNMADD231SD, VFNMADD231SS,
|
||||
VFNMSUB132PD, VFNMSUB132PS, VFNMSUB132SD, VFNMSUB132SS,
|
||||
VFNMSUB213PD, VFNMSUB213PS, VFNMSUB213SD, VFNMSUB213SS,
|
||||
VFNMSUB231PD, VFNMSUB231PS, VFNMSUB231SD, VFNMSUB231SS,
|
||||
VFMADDSUB132PD, VFMADDSUB132PS, VFMADDSUB213PD, VFMADDSUB213PS,
|
||||
VFMADDSUB231PD, VFMADDSUB231PS, VFMSUBADD132PD, VFMSUBADD132PS,
|
||||
VFMSUBADD213PD, VFMSUBADD213PS, VFMSUBADD231PD, VFMSUBADD231PS,
|
||||
VCVTPS2DQ, VCVTPD2DQ, VCVTPS2UDQ, VCVTPD2UDQ,
|
||||
VCVTPS2QQ, VCVTPD2QQ, VCVTPS2UQQ, VCVTPD2UQQ,
|
||||
VCVTUDQ2PS, VCVTUDQ2PD, VCVTQQ2PS, VCVTQQ2PD,
|
||||
VCVTUQQ2PS, VCVTUQQ2PD, VCVTDQ2PS, VCVTDQ2PD,
|
||||
VCVTPS2PD, VCVTPD2PS, VCVTSS2SD, VCVTSD2SS,
|
||||
VCVTUSI2SS, VCVTUSI2SD, VCVTSI2SS, VCVTSI2SD,
|
||||
VCVTSS2USI, VCVTSD2USI, VCVTSS2SI, VCVTSD2SI,
|
||||
VPERMT2PD, VPERMT2PS, VPERMI2PD, VPERMI2PS:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
7382
src/cmd/vendor/golang.org/x/arch/x86/x86asm/avx_tables.go
generated
vendored
Normal file
7382
src/cmd/vendor/golang.org/x/arch/x86/x86asm/avx_tables.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
32
src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode.go
generated
vendored
32
src/cmd/vendor/golang.org/x/arch/x86/x86asm/decode.go
generated
vendored
|
|
@ -405,15 +405,16 @@ ReadPrefixes:
|
|||
}
|
||||
addrSizeIndex = pos
|
||||
|
||||
//Group 5 - Vex encoding
|
||||
// Group 5 - Vex encoding
|
||||
case 0xC5:
|
||||
if pos == 0 && pos+1 < len(src) && (mode == 64 || (mode == 32 && src[pos+1]&0xc0 == 0xc0)) {
|
||||
vex = p
|
||||
vexIndex = pos
|
||||
inst.Prefix[pos] = p
|
||||
inst.Prefix[pos+1] = Prefix(src[pos+1])
|
||||
pos += 1
|
||||
continue
|
||||
pos += 2
|
||||
nprefix = pos
|
||||
break ReadPrefixes
|
||||
} else {
|
||||
nprefix = pos
|
||||
break ReadPrefixes
|
||||
|
|
@ -425,8 +426,25 @@ ReadPrefixes:
|
|||
inst.Prefix[pos] = p
|
||||
inst.Prefix[pos+1] = Prefix(src[pos+1])
|
||||
inst.Prefix[pos+2] = Prefix(src[pos+2])
|
||||
pos += 2
|
||||
continue
|
||||
pos += 3
|
||||
nprefix = pos
|
||||
break ReadPrefixes
|
||||
} else {
|
||||
nprefix = pos
|
||||
break ReadPrefixes
|
||||
}
|
||||
// EVEX encoding
|
||||
case 0x62:
|
||||
if pos == 0 && pos+3 < len(src) && (mode == 64 || (mode == 32 && src[pos+1]&0xc0 == 0xc0)) {
|
||||
vex = p
|
||||
vexIndex = pos
|
||||
inst.Prefix[pos] = p
|
||||
inst.Prefix[pos+1] = Prefix(src[pos+1])
|
||||
inst.Prefix[pos+2] = Prefix(src[pos+2])
|
||||
inst.Prefix[pos+3] = Prefix(src[pos+3])
|
||||
pos += 4
|
||||
nprefix = pos
|
||||
break ReadPrefixes
|
||||
} else {
|
||||
nprefix = pos
|
||||
break ReadPrefixes
|
||||
|
|
@ -462,6 +480,10 @@ ReadPrefixes:
|
|||
// opcode byte into inst.Opcode.
|
||||
opshift = 24
|
||||
|
||||
if vex != 0 {
|
||||
return decodeAVX(src, pos, vex, vexIndex, inst, mode)
|
||||
}
|
||||
|
||||
// Decode loop, executing decoder program.
|
||||
var oldPC, prevPC int
|
||||
Decode:
|
||||
|
|
|
|||
249
src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go
generated
vendored
249
src/cmd/vendor/golang.org/x/arch/x86/x86asm/gnu.go
generated
vendored
|
|
@ -268,7 +268,7 @@ SuffixLoop:
|
|||
}
|
||||
}
|
||||
|
||||
if AL <= a && a <= R15 || ES <= a && a <= GS || X0 <= a && a <= X15 || M0 <= a && a <= M7 {
|
||||
if AL <= a && a <= R15 || ES <= a && a <= GS || X0 <= a && a <= Z31 || M0 <= a && a <= M7 || K0 <= a && a <= K7 {
|
||||
needSuffix = false
|
||||
break SuffixLoop
|
||||
}
|
||||
|
|
@ -279,7 +279,7 @@ SuffixLoop:
|
|||
switch inst.Op {
|
||||
case CMPXCHG8B, FLDCW, FNSTCW, FNSTSW, LDMXCSR, LLDT, LMSW, LTR, PCLMULQDQ,
|
||||
SETA, SETAE, SETB, SETBE, SETE, SETG, SETGE, SETL, SETLE, SETNE, SETNO, SETNP, SETNS, SETO, SETP, SETS,
|
||||
SLDT, SMSW, STMXCSR, STR, VERR, VERW:
|
||||
SLDT, SMSW, STMXCSR, STR, VERR, VERW, VLDMXCSR, VSTMXCSR:
|
||||
// For various reasons, libopcodes emits no suffix for these instructions.
|
||||
|
||||
case CRC32:
|
||||
|
|
@ -354,6 +354,74 @@ SuffixLoop:
|
|||
}
|
||||
}
|
||||
|
||||
isVexOrEvex := false
|
||||
for _, p := range inst.Prefix {
|
||||
if p.IsVEX() || p&0xFF == 0x62 {
|
||||
isVexOrEvex = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isVexOrEvex {
|
||||
hasMem := false
|
||||
for _, a := range inst.Args {
|
||||
if _, ok := a.(Mem); ok {
|
||||
hasMem = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasMem {
|
||||
if inst.Op == VFPCLASSPD || inst.Op == VFPCLASSPS || inst.Op == VCVTTPD2DQ || inst.Op == VCVTTPD2UDQ || inst.Op == VCVTTPD2QQ || inst.Op == VCVTTPD2UQQ || inst.Op == VCVTPD2DQ || inst.Op == VCVTPD2UDQ || inst.Op == VCVTPD2QQ || inst.Op == VCVTPD2UQQ || inst.Op == VCVTPD2PS {
|
||||
vexL := 0
|
||||
isEvex := false
|
||||
for i, p := range inst.Prefix {
|
||||
if p.IsEVEX() && i+3 < len(inst.Prefix) && inst.Prefix[i+3] != 0 {
|
||||
vexL = int((inst.Prefix[i+3]&0xFF)>>5) & 3
|
||||
isEvex = true
|
||||
break
|
||||
} else if p.IsVEX() && i+2 < len(inst.Prefix) {
|
||||
if p&0xFF == 0xC4 {
|
||||
vexL = int((inst.Prefix[i+2]&0xFF)>>2) & 1
|
||||
} else if p&0xFF == 0xC5 {
|
||||
vexL = int((inst.Prefix[i+1]&0xFF)>>2) & 1
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isEvex || inst.Op == VFPCLASSPD || inst.Op == VFPCLASSPS || inst.Op == VCVTPD2DQ {
|
||||
switch vexL {
|
||||
case 0:
|
||||
op += "x"
|
||||
case 1:
|
||||
if inst.Op != VCMPPD && inst.Op != VCMPPS && inst.Op != VCMPPH && inst.Op != VCMPBF16 {
|
||||
op += "y"
|
||||
}
|
||||
case 2:
|
||||
if inst.Op != VCMPPD && inst.Op != VCMPPS && inst.Op != VCMPPH && inst.Op != VCMPBF16 {
|
||||
op += "z"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if inst.Op == VCVTSI2SD || inst.Op == VCVTSI2SS {
|
||||
is64 := false
|
||||
if (inst.Op == VCVTSI2SD || inst.Op == VCVTSI2SS) && inst.MemBytes == 8 {
|
||||
is64 = true
|
||||
} else {
|
||||
for _, a := range inst.Args {
|
||||
if r, ok := a.(Reg); ok && RAX <= r && r <= R15 {
|
||||
is64 = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if is64 {
|
||||
op += "q"
|
||||
} else {
|
||||
op += "l"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust special case opcodes.
|
||||
switch inst.Op {
|
||||
case 0:
|
||||
|
|
@ -374,6 +442,20 @@ SuffixLoop:
|
|||
op = cmppsOps[imm] + op[3:]
|
||||
}
|
||||
|
||||
case VCMPPD, VCMPPS, VCMPSD, VCMPSS, VCMPPH, VCMPSH, VCMPBF16:
|
||||
for i := len(inst.Args) - 1; i >= 0; i-- {
|
||||
if imm, ok := inst.Args[i].(Imm); ok {
|
||||
if 0 <= imm && imm < 8 {
|
||||
inst.Args[i] = nil
|
||||
op = "v" + cmppsOps[imm] + op[4:]
|
||||
}
|
||||
break
|
||||
}
|
||||
if inst.Args[i] != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case PCLMULQDQ:
|
||||
imm, ok := inst.Args[2].(Imm)
|
||||
if ok && imm&^0x11 == 0 {
|
||||
|
|
@ -407,7 +489,64 @@ SuffixLoop:
|
|||
if a == Imm(1) && (inst.Opcode>>24)&^1 == 0xD0 {
|
||||
continue
|
||||
}
|
||||
args = append(args, gnuArg(&inst, pc, symname, a, &usedPrefixes))
|
||||
argStr := gnuArg(&inst, pc, symname, a, &usedPrefixes)
|
||||
if i == 1 {
|
||||
r, ok := a.(Reg)
|
||||
// In GNU syntax, the mask register usually appears as the second argument (index 1).
|
||||
if ok && K1 <= r && r <= K7 {
|
||||
if !strings.HasPrefix(inst.Op.String(), "K") {
|
||||
if len(args) > 0 {
|
||||
args[0] += fmt.Sprintf(" {%s}", argStr)
|
||||
if inst.Zeroing {
|
||||
args[0] += " {z}"
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
} else if ok && r == K0 {
|
||||
if !strings.HasPrefix(inst.Op.String(), "K") {
|
||||
if inst.Zeroing && len(args) > 0 {
|
||||
args[0] += "{z}"
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, ok := a.(Mem); ok && inst.Broadcast && len(args) > 0 {
|
||||
if dstReg, ok := inst.Args[0].(Reg); ok {
|
||||
var vBytes int
|
||||
if X0 <= dstReg && dstReg <= X31 {
|
||||
vBytes = 16
|
||||
} else if Y0 <= dstReg && dstReg <= Y31 {
|
||||
vBytes = 32
|
||||
} else if Z0 <= dstReg && dstReg <= Z31 {
|
||||
vBytes = 64
|
||||
}
|
||||
if vBytes > 0 && inst.MemBytes > 0 {
|
||||
argStr += fmt.Sprintf("{1to%d}", vBytes/inst.MemBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
args = append(args, argStr)
|
||||
}
|
||||
|
||||
if inst.SAE {
|
||||
var sae string
|
||||
if hasRC(inst.Op) {
|
||||
switch inst.Rounding {
|
||||
case 0:
|
||||
sae = "{rn-sae}"
|
||||
case 1:
|
||||
sae = "{rd-sae}"
|
||||
case 2:
|
||||
sae = "{ru-sae}"
|
||||
case 3:
|
||||
sae = "{rz-sae}"
|
||||
}
|
||||
} else {
|
||||
sae = "{sae}"
|
||||
}
|
||||
args = append(args, sae)
|
||||
}
|
||||
|
||||
// The default is to print the arguments in reverse Intel order.
|
||||
|
|
@ -436,7 +575,7 @@ SuffixLoop:
|
|||
}
|
||||
}
|
||||
for _, p := range inst.Prefix {
|
||||
if p == 0 || p.IsVEX() {
|
||||
if p == 0 || p.IsVEX() || p.IsEVEX() {
|
||||
break
|
||||
}
|
||||
if p&PrefixImplicit != 0 {
|
||||
|
|
@ -534,8 +673,6 @@ func gnuArg(inst *Inst, pc uint64, symname SymLookup, x Arg, usedPrefixes *bool)
|
|||
if x == DX {
|
||||
return "(%dx)"
|
||||
}
|
||||
case VMOVDQA, VMOVDQU, VMOVNTDQA, VMOVNTDQ:
|
||||
return strings.Replace(gccRegName[x], "xmm", "ymm", -1)
|
||||
}
|
||||
return gccRegName[x]
|
||||
case Mem:
|
||||
|
|
@ -566,6 +703,10 @@ func gnuArg(inst *Inst, pc uint64, symname SymLookup, x Arg, usedPrefixes *bool)
|
|||
case INSB, INSW, INSD, STOSB, STOSW, STOSD, STOSQ, SCASB, SCASW, SCASD, SCASQ:
|
||||
// These do not accept segment prefixes, at least in the GNU rendering.
|
||||
default:
|
||||
if isVSIB(inst.Op) {
|
||||
haveCS, haveDS, haveES, haveSS = false, false, false, false
|
||||
break
|
||||
}
|
||||
if *usedPrefixes {
|
||||
break
|
||||
}
|
||||
|
|
@ -653,6 +794,14 @@ func gnuArg(inst *Inst, pc uint64, symname SymLookup, x Arg, usedPrefixes *bool)
|
|||
// 16-bit addressing - no scale
|
||||
return fmt.Sprintf("%s%s(%s,%s)", seg, disp, base, index)
|
||||
}
|
||||
if x.Scale == 1 {
|
||||
// Special case to match objdump output for explicit scale 1.
|
||||
// XXX is this the only one?
|
||||
if inst.Op.String() == "VMOVNTDQA" {
|
||||
return fmt.Sprintf("%s%s(%s,%s,1)", seg, disp, base, index)
|
||||
}
|
||||
return fmt.Sprintf("%s%s(%s,%s)", seg, disp, base, index)
|
||||
}
|
||||
return fmt.Sprintf("%s%s(%s,%s,%d)", seg, disp, base, index, x.Scale)
|
||||
case Rel:
|
||||
if pc == 0 {
|
||||
|
|
@ -789,6 +938,94 @@ var gccRegName = [...]string{
|
|||
X13: "%xmm13",
|
||||
X14: "%xmm14",
|
||||
X15: "%xmm15",
|
||||
X16: "%xmm16",
|
||||
X17: "%xmm17",
|
||||
X18: "%xmm18",
|
||||
X19: "%xmm19",
|
||||
X20: "%xmm20",
|
||||
X21: "%xmm21",
|
||||
X22: "%xmm22",
|
||||
X23: "%xmm23",
|
||||
X24: "%xmm24",
|
||||
X25: "%xmm25",
|
||||
X26: "%xmm26",
|
||||
X27: "%xmm27",
|
||||
X28: "%xmm28",
|
||||
X29: "%xmm29",
|
||||
X30: "%xmm30",
|
||||
X31: "%xmm31",
|
||||
Y0: "%ymm0",
|
||||
Y1: "%ymm1",
|
||||
Y2: "%ymm2",
|
||||
Y3: "%ymm3",
|
||||
Y4: "%ymm4",
|
||||
Y5: "%ymm5",
|
||||
Y6: "%ymm6",
|
||||
Y7: "%ymm7",
|
||||
Y8: "%ymm8",
|
||||
Y9: "%ymm9",
|
||||
Y10: "%ymm10",
|
||||
Y11: "%ymm11",
|
||||
Y12: "%ymm12",
|
||||
Y13: "%ymm13",
|
||||
Y14: "%ymm14",
|
||||
Y15: "%ymm15",
|
||||
Y16: "%ymm16",
|
||||
Y17: "%ymm17",
|
||||
Y18: "%ymm18",
|
||||
Y19: "%ymm19",
|
||||
Y20: "%ymm20",
|
||||
Y21: "%ymm21",
|
||||
Y22: "%ymm22",
|
||||
Y23: "%ymm23",
|
||||
Y24: "%ymm24",
|
||||
Y25: "%ymm25",
|
||||
Y26: "%ymm26",
|
||||
Y27: "%ymm27",
|
||||
Y28: "%ymm28",
|
||||
Y29: "%ymm29",
|
||||
Y30: "%ymm30",
|
||||
Y31: "%ymm31",
|
||||
Z0: "%zmm0",
|
||||
Z1: "%zmm1",
|
||||
Z2: "%zmm2",
|
||||
Z3: "%zmm3",
|
||||
Z4: "%zmm4",
|
||||
Z5: "%zmm5",
|
||||
Z6: "%zmm6",
|
||||
Z7: "%zmm7",
|
||||
Z8: "%zmm8",
|
||||
Z9: "%zmm9",
|
||||
Z10: "%zmm10",
|
||||
Z11: "%zmm11",
|
||||
Z12: "%zmm12",
|
||||
Z13: "%zmm13",
|
||||
Z14: "%zmm14",
|
||||
Z15: "%zmm15",
|
||||
Z16: "%zmm16",
|
||||
Z17: "%zmm17",
|
||||
Z18: "%zmm18",
|
||||
Z19: "%zmm19",
|
||||
Z20: "%zmm20",
|
||||
Z21: "%zmm21",
|
||||
Z22: "%zmm22",
|
||||
Z23: "%zmm23",
|
||||
Z24: "%zmm24",
|
||||
Z25: "%zmm25",
|
||||
Z26: "%zmm26",
|
||||
Z27: "%zmm27",
|
||||
Z28: "%zmm28",
|
||||
Z29: "%zmm29",
|
||||
Z30: "%zmm30",
|
||||
Z31: "%zmm31",
|
||||
K0: "%k0",
|
||||
K1: "%k1",
|
||||
K2: "%k2",
|
||||
K3: "%k3",
|
||||
K4: "%k4",
|
||||
K5: "%k5",
|
||||
K6: "%k6",
|
||||
K7: "%k7",
|
||||
CS: "%cs",
|
||||
SS: "%ss",
|
||||
DS: "%ds",
|
||||
|
|
|
|||
197
src/cmd/vendor/golang.org/x/arch/x86/x86asm/inst.go
generated
vendored
197
src/cmd/vendor/golang.org/x/arch/x86/x86asm/inst.go
generated
vendored
|
|
@ -23,6 +23,11 @@ type Inst struct {
|
|||
Len int // length of encoded instruction in bytes
|
||||
PCRel int // length of PC-relative address in instruction encoding
|
||||
PCRelOff int // index of start of PC-relative address in instruction encoding
|
||||
// AVX-512 flags
|
||||
Broadcast bool // EVEX broadcast
|
||||
Zeroing bool // EVEX zeroing
|
||||
SAE bool // Suppress All Exceptions
|
||||
Rounding int8 // Rounding control (0-3), valid only when SAE is true
|
||||
}
|
||||
|
||||
// Prefixes is an array of prefixes associated with a single instruction.
|
||||
|
|
@ -79,6 +84,7 @@ const (
|
|||
PrefixREXB Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
|
||||
PrefixVEX2Bytes Prefix = 0xC5 // Short form of vex prefix
|
||||
PrefixVEX3Bytes Prefix = 0xC4 // Long form of vex prefix
|
||||
PrefixEVEX Prefix = 0x62 // EVEX prefix
|
||||
)
|
||||
|
||||
// IsREX reports whether p is a REX prefix byte.
|
||||
|
|
@ -90,6 +96,10 @@ func (p Prefix) IsVEX() bool {
|
|||
return p&0xFF == PrefixVEX2Bytes || p&0xFF == PrefixVEX3Bytes
|
||||
}
|
||||
|
||||
func (p Prefix) IsEVEX() bool {
|
||||
return p&0xFF == PrefixEVEX
|
||||
}
|
||||
|
||||
func (p Prefix) String() string {
|
||||
p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
|
||||
if s := prefixNames[p]; s != "" {
|
||||
|
|
@ -122,6 +132,9 @@ type Op uint32
|
|||
func (op Op) String() string {
|
||||
i := int(op)
|
||||
if i < 0 || i >= len(opNames) || opNames[i] == "" {
|
||||
if i < len(avxOpNames) && avxOpNames[i] != "" {
|
||||
return avxOpNames[i]
|
||||
}
|
||||
return fmt.Sprintf("Op(%d)", i)
|
||||
}
|
||||
return opNames[i]
|
||||
|
|
@ -130,7 +143,7 @@ func (op Op) String() string {
|
|||
// An Args holds the instruction arguments.
|
||||
// If an instruction has fewer than 4 arguments,
|
||||
// the final elements in the array are nil.
|
||||
type Args [4]Arg
|
||||
type Args [6]Arg
|
||||
|
||||
// An Arg is a single instruction argument,
|
||||
// one of these types: Reg, Mem, Imm, Rel.
|
||||
|
|
@ -268,6 +281,100 @@ const (
|
|||
X13
|
||||
X14
|
||||
X15
|
||||
X16
|
||||
X17
|
||||
X18
|
||||
X19
|
||||
X20
|
||||
X21
|
||||
X22
|
||||
X23
|
||||
X24
|
||||
X25
|
||||
X26
|
||||
X27
|
||||
X28
|
||||
X29
|
||||
X30
|
||||
X31
|
||||
|
||||
// YMM registers.
|
||||
Y0
|
||||
Y1
|
||||
Y2
|
||||
Y3
|
||||
Y4
|
||||
Y5
|
||||
Y6
|
||||
Y7
|
||||
Y8
|
||||
Y9
|
||||
Y10
|
||||
Y11
|
||||
Y12
|
||||
Y13
|
||||
Y14
|
||||
Y15
|
||||
Y16
|
||||
Y17
|
||||
Y18
|
||||
Y19
|
||||
Y20
|
||||
Y21
|
||||
Y22
|
||||
Y23
|
||||
Y24
|
||||
Y25
|
||||
Y26
|
||||
Y27
|
||||
Y28
|
||||
Y29
|
||||
Y30
|
||||
Y31
|
||||
|
||||
// ZMM registers.
|
||||
Z0
|
||||
Z1
|
||||
Z2
|
||||
Z3
|
||||
Z4
|
||||
Z5
|
||||
Z6
|
||||
Z7
|
||||
Z8
|
||||
Z9
|
||||
Z10
|
||||
Z11
|
||||
Z12
|
||||
Z13
|
||||
Z14
|
||||
Z15
|
||||
Z16
|
||||
Z17
|
||||
Z18
|
||||
Z19
|
||||
Z20
|
||||
Z21
|
||||
Z22
|
||||
Z23
|
||||
Z24
|
||||
Z25
|
||||
Z26
|
||||
Z27
|
||||
Z28
|
||||
Z29
|
||||
Z30
|
||||
Z31
|
||||
|
||||
// Mask registers.
|
||||
K0
|
||||
K1
|
||||
K2
|
||||
K3
|
||||
K4
|
||||
K5
|
||||
K6
|
||||
K7
|
||||
|
||||
// Segment registers.
|
||||
ES
|
||||
|
|
@ -595,6 +702,94 @@ var regNames = [...]string{
|
|||
X13: "X13",
|
||||
X14: "X14",
|
||||
X15: "X15",
|
||||
X16: "X16",
|
||||
X17: "X17",
|
||||
X18: "X18",
|
||||
X19: "X19",
|
||||
X20: "X20",
|
||||
X21: "X21",
|
||||
X22: "X22",
|
||||
X23: "X23",
|
||||
X24: "X24",
|
||||
X25: "X25",
|
||||
X26: "X26",
|
||||
X27: "X27",
|
||||
X28: "X28",
|
||||
X29: "X29",
|
||||
X30: "X30",
|
||||
X31: "X31",
|
||||
Y0: "Y0",
|
||||
Y1: "Y1",
|
||||
Y2: "Y2",
|
||||
Y3: "Y3",
|
||||
Y4: "Y4",
|
||||
Y5: "Y5",
|
||||
Y6: "Y6",
|
||||
Y7: "Y7",
|
||||
Y8: "Y8",
|
||||
Y9: "Y9",
|
||||
Y10: "Y10",
|
||||
Y11: "Y11",
|
||||
Y12: "Y12",
|
||||
Y13: "Y13",
|
||||
Y14: "Y14",
|
||||
Y15: "Y15",
|
||||
Y16: "Y16",
|
||||
Y17: "Y17",
|
||||
Y18: "Y18",
|
||||
Y19: "Y19",
|
||||
Y20: "Y20",
|
||||
Y21: "Y21",
|
||||
Y22: "Y22",
|
||||
Y23: "Y23",
|
||||
Y24: "Y24",
|
||||
Y25: "Y25",
|
||||
Y26: "Y26",
|
||||
Y27: "Y27",
|
||||
Y28: "Y28",
|
||||
Y29: "Y29",
|
||||
Y30: "Y30",
|
||||
Y31: "Y31",
|
||||
Z0: "Z0",
|
||||
Z1: "Z1",
|
||||
Z2: "Z2",
|
||||
Z3: "Z3",
|
||||
Z4: "Z4",
|
||||
Z5: "Z5",
|
||||
Z6: "Z6",
|
||||
Z7: "Z7",
|
||||
Z8: "Z8",
|
||||
Z9: "Z9",
|
||||
Z10: "Z10",
|
||||
Z11: "Z11",
|
||||
Z12: "Z12",
|
||||
Z13: "Z13",
|
||||
Z14: "Z14",
|
||||
Z15: "Z15",
|
||||
Z16: "Z16",
|
||||
Z17: "Z17",
|
||||
Z18: "Z18",
|
||||
Z19: "Z19",
|
||||
Z20: "Z20",
|
||||
Z21: "Z21",
|
||||
Z22: "Z22",
|
||||
Z23: "Z23",
|
||||
Z24: "Z24",
|
||||
Z25: "Z25",
|
||||
Z26: "Z26",
|
||||
Z27: "Z27",
|
||||
Z28: "Z28",
|
||||
Z29: "Z29",
|
||||
Z30: "Z30",
|
||||
Z31: "Z31",
|
||||
K0: "K0",
|
||||
K1: "K1",
|
||||
K2: "K2",
|
||||
K3: "K3",
|
||||
K4: "K4",
|
||||
K5: "K5",
|
||||
K6: "K6",
|
||||
K7: "K7",
|
||||
CS: "CS",
|
||||
SS: "SS",
|
||||
DS: "DS",
|
||||
|
|
|
|||
206
src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go
generated
vendored
206
src/cmd/vendor/golang.org/x/arch/x86/x86asm/intel.go
generated
vendored
|
|
@ -99,6 +99,12 @@ func IntelSyntax(inst Inst, pc uint64, symname SymLookup) string {
|
|||
inst.Prefix[i] |= PrefixImplicit
|
||||
inst.Prefix[i+1] |= PrefixImplicit
|
||||
}
|
||||
if p.IsEVEX() {
|
||||
inst.Prefix[i] |= PrefixImplicit
|
||||
inst.Prefix[i+1] |= PrefixImplicit
|
||||
inst.Prefix[i+2] |= PrefixImplicit
|
||||
inst.Prefix[i+3] |= PrefixImplicit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -256,11 +262,55 @@ func IntelSyntax(inst Inst, pc uint64, symname SymLookup) string {
|
|||
}
|
||||
|
||||
var args []string
|
||||
for _, a := range iargs {
|
||||
for i, a := range iargs {
|
||||
if a == nil {
|
||||
break
|
||||
}
|
||||
args = append(args, intelArg(&inst, pc, symname, a))
|
||||
argStr := intelArg(&inst, pc, symname, a)
|
||||
if i == 1 {
|
||||
r, ok := a.(Reg)
|
||||
if ok && K1 <= r && r <= K7 {
|
||||
if !strings.HasPrefix(inst.Op.String(), "K") {
|
||||
isPF := strings.HasPrefix(inst.Op.String(), "VGATHERPF") || strings.HasPrefix(inst.Op.String(), "VSCATTERPF")
|
||||
if isPF {
|
||||
args = append([]string{fmt.Sprintf("{%s}", argStr)}, args...)
|
||||
} else if len(args) > 0 {
|
||||
args[len(args)-1] += fmt.Sprintf(" {%s}", argStr)
|
||||
if inst.Zeroing {
|
||||
args[len(args)-1] += " {z}"
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
} else if ok && r == K0 {
|
||||
if !strings.HasPrefix(inst.Op.String(), "K") {
|
||||
isPF := strings.HasPrefix(inst.Op.String(), "VGATHERPF") || strings.HasPrefix(inst.Op.String(), "VSCATTERPF")
|
||||
if isPF {
|
||||
args = append([]string{fmt.Sprintf("{%s}", argStr)}, args...)
|
||||
} else if inst.Zeroing && len(args) > 0 {
|
||||
args[len(args)-1] += " {z}"
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
if _, ok := a.(Mem); ok && inst.Broadcast && len(args) > 0 {
|
||||
// Find vector size from first argument (destination)
|
||||
if dstReg, ok := iargs[0].(Reg); ok {
|
||||
var vBytes int
|
||||
if X0 <= dstReg && dstReg <= X31 {
|
||||
vBytes = 16
|
||||
} else if Y0 <= dstReg && dstReg <= Y31 {
|
||||
vBytes = 32
|
||||
} else if Z0 <= dstReg && dstReg <= Z31 {
|
||||
vBytes = 64
|
||||
}
|
||||
if vBytes > 0 && inst.MemBytes > 0 {
|
||||
argStr += fmt.Sprintf("{1to%d}", vBytes/inst.MemBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
args = append(args, argStr)
|
||||
}
|
||||
|
||||
var op string
|
||||
|
|
@ -288,6 +338,24 @@ func IntelSyntax(inst Inst, pc uint64, symname SymLookup) string {
|
|||
args[0], args[1] = args[1], args[0]
|
||||
}
|
||||
|
||||
case VCMPPD, VCMPPS, VCMPSD, VCMPSS, VCMPPH, VCMPSH, VCMPBF16:
|
||||
for i := len(inst.Args) - 1; i >= 0; i-- {
|
||||
if imm, ok := inst.Args[i].(Imm); ok {
|
||||
if 0 <= imm && imm < 8 {
|
||||
args = args[:len(args)-1]
|
||||
baseOp := intelOp[inst.Op]
|
||||
if baseOp == "" {
|
||||
baseOp = strings.ToLower(inst.Op.String())
|
||||
}
|
||||
op = "v" + cmppsOps[imm] + baseOp[4:]
|
||||
}
|
||||
break
|
||||
}
|
||||
if inst.Args[i] != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case FCHS, FABS, FTST, FLDPI, FLDL2E, FLDLG2, F2XM1, FXAM, FLD1, FLDL2T, FSQRT, FRNDINT, FCOS, FSIN:
|
||||
if len(args) == 0 {
|
||||
args = append(args, "st0")
|
||||
|
|
@ -326,6 +394,23 @@ func IntelSyntax(inst Inst, pc uint64, symname SymLookup) string {
|
|||
}
|
||||
}
|
||||
|
||||
if inst.SAE {
|
||||
if hasRC(inst.Op) {
|
||||
switch inst.Rounding {
|
||||
case 0:
|
||||
args = append(args, "{rn-sae}")
|
||||
case 1:
|
||||
args = append(args, "{rd-sae}")
|
||||
case 2:
|
||||
args = append(args, "{ru-sae}")
|
||||
case 3:
|
||||
args = append(args, "{rz-sae}")
|
||||
}
|
||||
} else {
|
||||
args = append(args, "{sae}")
|
||||
}
|
||||
}
|
||||
|
||||
if op == "" {
|
||||
op = intelOp[inst.Op]
|
||||
}
|
||||
|
|
@ -375,6 +460,16 @@ func intelArg(inst *Inst, pc uint64, symname SymLookup, arg Arg) string {
|
|||
prefix = "xmmword "
|
||||
case 32:
|
||||
prefix = "ymmword "
|
||||
case 64:
|
||||
prefix = "zmmword "
|
||||
}
|
||||
if isVSIB(inst.Op) {
|
||||
switch inst.Op {
|
||||
case VPGATHERDD, VPSCATTERDD, VPGATHERQD, VPSCATTERQD, VGATHERDPS, VSCATTERDPS, VGATHERQPS, VSCATTERQPS, VGATHERPF0DPS, VGATHERPF1DPS, VSCATTERPF0DPS, VSCATTERPF1DPS, VGATHERPF0QPS, VGATHERPF1QPS, VSCATTERPF0QPS, VSCATTERPF1QPS:
|
||||
prefix = "dword "
|
||||
case VPGATHERDQ, VPSCATTERDQ, VPGATHERQQ, VPSCATTERQQ, VGATHERDPD, VSCATTERDPD, VGATHERQPD, VSCATTERQPD, VGATHERPF0DPD, VGATHERPF1DPD, VSCATTERPF0DPD, VSCATTERPF1DPD, VGATHERPF0QPD, VGATHERPF1QPD, VSCATTERPF0QPD, VSCATTERPF1QPD:
|
||||
prefix = "qword "
|
||||
}
|
||||
}
|
||||
switch inst.Op {
|
||||
case INVLPG:
|
||||
|
|
@ -448,7 +543,17 @@ func intelArg(inst *Inst, pc uint64, symname SymLookup, arg Arg) string {
|
|||
if a.Base != 0 {
|
||||
prefix += "+"
|
||||
}
|
||||
prefix += fmt.Sprintf("%s*%d", intelArg(inst, pc, symname, a.Index), a.Scale)
|
||||
if a.Scale == 1 {
|
||||
if inst.AddrSize == 16 || inst.Op.String() == "VMOVNTDQA" {
|
||||
prefix += fmt.Sprintf("%s*1", intelArg(inst, pc, symname, a.Index))
|
||||
} else if a.Base == 0 && ((X0 <= a.Index && a.Index <= Z31) || (M0 <= a.Index && a.Index <= M7)) {
|
||||
prefix += fmt.Sprintf("1*%s", intelArg(inst, pc, symname, a.Index))
|
||||
} else {
|
||||
prefix += fmt.Sprintf("%s", intelArg(inst, pc, symname, a.Index))
|
||||
}
|
||||
} else {
|
||||
prefix += fmt.Sprintf("%d*%s", a.Scale, intelArg(inst, pc, symname, a.Index))
|
||||
}
|
||||
}
|
||||
if a.Disp != 0 {
|
||||
if prefix[len(prefix)-1] == '[' && (a.Disp >= 0 || int64(int32(a.Disp)) != a.Disp) {
|
||||
|
|
@ -473,12 +578,7 @@ func intelArg(inst *Inst, pc uint64, symname SymLookup, arg Arg) string {
|
|||
}
|
||||
case Reg:
|
||||
if int(a) < len(intelReg) && intelReg[a] != "" {
|
||||
switch inst.Op {
|
||||
case VMOVDQA, VMOVDQU, VMOVNTDQA, VMOVNTDQ:
|
||||
return strings.Replace(intelReg[a], "xmm", "ymm", -1)
|
||||
default:
|
||||
return intelReg[a]
|
||||
}
|
||||
return intelReg[a]
|
||||
}
|
||||
}
|
||||
return strings.ToLower(arg.String())
|
||||
|
|
@ -544,6 +644,94 @@ var intelReg = [...]string{
|
|||
X13: "xmm13",
|
||||
X14: "xmm14",
|
||||
X15: "xmm15",
|
||||
X16: "xmm16",
|
||||
X17: "xmm17",
|
||||
X18: "xmm18",
|
||||
X19: "xmm19",
|
||||
X20: "xmm20",
|
||||
X21: "xmm21",
|
||||
X22: "xmm22",
|
||||
X23: "xmm23",
|
||||
X24: "xmm24",
|
||||
X25: "xmm25",
|
||||
X26: "xmm26",
|
||||
X27: "xmm27",
|
||||
X28: "xmm28",
|
||||
X29: "xmm29",
|
||||
X30: "xmm30",
|
||||
X31: "xmm31",
|
||||
Y0: "ymm0",
|
||||
Y1: "ymm1",
|
||||
Y2: "ymm2",
|
||||
Y3: "ymm3",
|
||||
Y4: "ymm4",
|
||||
Y5: "ymm5",
|
||||
Y6: "ymm6",
|
||||
Y7: "ymm7",
|
||||
Y8: "ymm8",
|
||||
Y9: "ymm9",
|
||||
Y10: "ymm10",
|
||||
Y11: "ymm11",
|
||||
Y12: "ymm12",
|
||||
Y13: "ymm13",
|
||||
Y14: "ymm14",
|
||||
Y15: "ymm15",
|
||||
Y16: "ymm16",
|
||||
Y17: "ymm17",
|
||||
Y18: "ymm18",
|
||||
Y19: "ymm19",
|
||||
Y20: "ymm20",
|
||||
Y21: "ymm21",
|
||||
Y22: "ymm22",
|
||||
Y23: "ymm23",
|
||||
Y24: "ymm24",
|
||||
Y25: "ymm25",
|
||||
Y26: "ymm26",
|
||||
Y27: "ymm27",
|
||||
Y28: "ymm28",
|
||||
Y29: "ymm29",
|
||||
Y30: "ymm30",
|
||||
Y31: "ymm31",
|
||||
Z0: "zmm0",
|
||||
Z1: "zmm1",
|
||||
Z2: "zmm2",
|
||||
Z3: "zmm3",
|
||||
Z4: "zmm4",
|
||||
Z5: "zmm5",
|
||||
Z6: "zmm6",
|
||||
Z7: "zmm7",
|
||||
Z8: "zmm8",
|
||||
Z9: "zmm9",
|
||||
Z10: "zmm10",
|
||||
Z11: "zmm11",
|
||||
Z12: "zmm12",
|
||||
Z13: "zmm13",
|
||||
Z14: "zmm14",
|
||||
Z15: "zmm15",
|
||||
Z16: "zmm16",
|
||||
Z17: "zmm17",
|
||||
Z18: "zmm18",
|
||||
Z19: "zmm19",
|
||||
Z20: "zmm20",
|
||||
Z21: "zmm21",
|
||||
Z22: "zmm22",
|
||||
Z23: "zmm23",
|
||||
Z24: "zmm24",
|
||||
Z25: "zmm25",
|
||||
Z26: "zmm26",
|
||||
Z27: "zmm27",
|
||||
Z28: "zmm28",
|
||||
Z29: "zmm29",
|
||||
Z30: "zmm30",
|
||||
Z31: "zmm31",
|
||||
K0: "k0",
|
||||
K1: "k1",
|
||||
K2: "k2",
|
||||
K3: "k3",
|
||||
K4: "k4",
|
||||
K5: "k5",
|
||||
K6: "k6",
|
||||
K7: "k7",
|
||||
|
||||
// TODO: Maybe the constants are named wrong.
|
||||
SPB: "spl",
|
||||
|
|
|
|||
169
src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go
generated
vendored
169
src/cmd/vendor/golang.org/x/arch/x86/x86asm/plan9x.go
generated
vendored
|
|
@ -34,7 +34,7 @@ func GoSyntax(inst Inst, pc uint64, symname SymLookup) string {
|
|||
var rep string
|
||||
var last Prefix
|
||||
for _, p := range inst.Prefix {
|
||||
if p == 0 || p.IsREX() || p.IsVEX() {
|
||||
if p == 0 || p.IsREX() || p.IsVEX() || p.IsEVEX() {
|
||||
break
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +62,61 @@ func GoSyntax(inst Inst, pc uint64, symname SymLookup) string {
|
|||
}
|
||||
|
||||
op := inst.Op.String()
|
||||
if plan9Suffix[inst.Op] {
|
||||
if inst.Op == VFPCLASSPD || inst.Op == VFPCLASSPS || inst.Op == VCVTTPD2DQ || inst.Op == VCVTTPD2UDQ || inst.Op == VCVTTPD2QQ || inst.Op == VCVTTPD2UQQ || inst.Op == VCVTPD2DQ || inst.Op == VCVTPD2UDQ || inst.Op == VCVTPD2QQ || inst.Op == VCVTPD2UQQ || inst.Op == VCVTPD2PS {
|
||||
vexL := 0
|
||||
isEvex := false
|
||||
for i, p := range inst.Prefix {
|
||||
if p.IsEVEX() && i+3 < len(inst.Prefix) && inst.Prefix[i+3] != 0 {
|
||||
vexL = int((inst.Prefix[i+3]&0xFF)>>5) & 3
|
||||
isEvex = true
|
||||
break
|
||||
} else if p.IsVEX() && i+2 < len(inst.Prefix) {
|
||||
if p&0xFF == 0xC4 {
|
||||
vexL = int((inst.Prefix[i+2]&0xFF)>>2) & 1
|
||||
} else if p&0xFF == 0xC5 {
|
||||
vexL = int((inst.Prefix[i+1]&0xFF)>>2) & 1
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isEvex || inst.Op == VFPCLASSPD || inst.Op == VFPCLASSPS || inst.Op == VCVTPD2DQ {
|
||||
switch vexL {
|
||||
case 0:
|
||||
op += "X"
|
||||
case 1:
|
||||
if inst.Op != VCMPPD && inst.Op != VCMPPS && inst.Op != VCMPPH && inst.Op != VCMPBF16 {
|
||||
op += "Y"
|
||||
}
|
||||
case 2:
|
||||
if inst.Op != VCMPPD && inst.Op != VCMPPS && inst.Op != VCMPPH && inst.Op != VCMPBF16 {
|
||||
op += "Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if inst.Op == VCVTTSD2SI || inst.Op == VCVTTSS2SI || inst.Op == VCVTSD2SI || inst.Op == VCVTSS2SI || inst.Op == VCVTSI2SD || inst.Op == VCVTSI2SS {
|
||||
is64 := false
|
||||
if (inst.Op == VCVTSI2SD || inst.Op == VCVTSI2SS) && inst.MemBytes == 8 {
|
||||
is64 = true
|
||||
} else {
|
||||
for _, a := range inst.Args {
|
||||
if r, ok := a.(Reg); ok && RAX <= r && r <= R15 {
|
||||
is64 = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if inst.Op == VCVTSI2SD || inst.Op == VCVTSI2SS {
|
||||
if is64 {
|
||||
op += "Q"
|
||||
} else {
|
||||
op += "L"
|
||||
}
|
||||
} else {
|
||||
if is64 {
|
||||
op += "Q"
|
||||
}
|
||||
}
|
||||
} else if plan9Suffix[inst.Op] {
|
||||
s := inst.DataSize
|
||||
if inst.MemBytes != 0 {
|
||||
s = inst.MemBytes * 8
|
||||
|
|
@ -83,6 +137,29 @@ func GoSyntax(inst Inst, pc uint64, symname SymLookup) string {
|
|||
}
|
||||
}
|
||||
|
||||
if inst.Broadcast {
|
||||
op += ".BCST"
|
||||
}
|
||||
if inst.SAE {
|
||||
if hasRC(inst.Op) {
|
||||
switch inst.Rounding {
|
||||
case 0:
|
||||
op += ".RN_SAE"
|
||||
case 1:
|
||||
op += ".RD_SAE"
|
||||
case 2:
|
||||
op += ".RU_SAE"
|
||||
case 3:
|
||||
op += ".RZ_SAE"
|
||||
}
|
||||
} else {
|
||||
op += ".SAE"
|
||||
}
|
||||
}
|
||||
if inst.Zeroing {
|
||||
op += ".Z"
|
||||
}
|
||||
|
||||
if inst.Op == CMP {
|
||||
// Use reads-left-to-right ordering for comparisons.
|
||||
// See issue 60920.
|
||||
|
|
@ -349,6 +426,94 @@ var plan9Reg = [...]string{
|
|||
X13: "X13",
|
||||
X14: "X14",
|
||||
X15: "X15",
|
||||
X16: "X16",
|
||||
X17: "X17",
|
||||
X18: "X18",
|
||||
X19: "X19",
|
||||
X20: "X20",
|
||||
X21: "X21",
|
||||
X22: "X22",
|
||||
X23: "X23",
|
||||
X24: "X24",
|
||||
X25: "X25",
|
||||
X26: "X26",
|
||||
X27: "X27",
|
||||
X28: "X28",
|
||||
X29: "X29",
|
||||
X30: "X30",
|
||||
X31: "X31",
|
||||
Y0: "Y0",
|
||||
Y1: "Y1",
|
||||
Y2: "Y2",
|
||||
Y3: "Y3",
|
||||
Y4: "Y4",
|
||||
Y5: "Y5",
|
||||
Y6: "Y6",
|
||||
Y7: "Y7",
|
||||
Y8: "Y8",
|
||||
Y9: "Y9",
|
||||
Y10: "Y10",
|
||||
Y11: "Y11",
|
||||
Y12: "Y12",
|
||||
Y13: "Y13",
|
||||
Y14: "Y14",
|
||||
Y15: "Y15",
|
||||
Y16: "Y16",
|
||||
Y17: "Y17",
|
||||
Y18: "Y18",
|
||||
Y19: "Y19",
|
||||
Y20: "Y20",
|
||||
Y21: "Y21",
|
||||
Y22: "Y22",
|
||||
Y23: "Y23",
|
||||
Y24: "Y24",
|
||||
Y25: "Y25",
|
||||
Y26: "Y26",
|
||||
Y27: "Y27",
|
||||
Y28: "Y28",
|
||||
Y29: "Y29",
|
||||
Y30: "Y30",
|
||||
Y31: "Y31",
|
||||
Z0: "Z0",
|
||||
Z1: "Z1",
|
||||
Z2: "Z2",
|
||||
Z3: "Z3",
|
||||
Z4: "Z4",
|
||||
Z5: "Z5",
|
||||
Z6: "Z6",
|
||||
Z7: "Z7",
|
||||
Z8: "Z8",
|
||||
Z9: "Z9",
|
||||
Z10: "Z10",
|
||||
Z11: "Z11",
|
||||
Z12: "Z12",
|
||||
Z13: "Z13",
|
||||
Z14: "Z14",
|
||||
Z15: "Z15",
|
||||
Z16: "Z16",
|
||||
Z17: "Z17",
|
||||
Z18: "Z18",
|
||||
Z19: "Z19",
|
||||
Z20: "Z20",
|
||||
Z21: "Z21",
|
||||
Z22: "Z22",
|
||||
Z23: "Z23",
|
||||
Z24: "Z24",
|
||||
Z25: "Z25",
|
||||
Z26: "Z26",
|
||||
Z27: "Z27",
|
||||
Z28: "Z28",
|
||||
Z29: "Z29",
|
||||
Z30: "Z30",
|
||||
Z31: "Z31",
|
||||
K0: "K0",
|
||||
K1: "K1",
|
||||
K2: "K2",
|
||||
K3: "K3",
|
||||
K4: "K4",
|
||||
K5: "K5",
|
||||
K6: "K6",
|
||||
K7: "K7",
|
||||
CS: "CS",
|
||||
SS: "SS",
|
||||
DS: "DS",
|
||||
|
|
|
|||
15095
src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go
generated
vendored
15095
src/cmd/vendor/golang.org/x/arch/x86/x86asm/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
2
src/cmd/vendor/modules.txt
vendored
2
src/cmd/vendor/modules.txt
vendored
|
|
@ -16,7 +16,7 @@ github.com/google/pprof/third_party/svgpan
|
|||
# github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b
|
||||
## explicit; go 1.13
|
||||
github.com/ianlancetaylor/demangle
|
||||
# golang.org/x/arch v0.27.1-0.20260513003155-2ebc08890589
|
||||
# golang.org/x/arch v0.27.1-0.20260521044007-9c1a596a2c97
|
||||
## explicit; go 1.25.0
|
||||
golang.org/x/arch/arm/armasm
|
||||
golang.org/x/arch/arm64/arm64asm
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue