1
0
mirror of https://github.com/golang/go synced 2024-11-23 05:10:09 -07:00

cmd: update x/arch to pull in CL 315572

Because x/arch is now lazy, this removes the checksum for rsc.io/pdf
from the go.sum file: the requirements of rsc.io/pdf are known not to
be relevant to any package imported within the cmd packages.

For #36460
Updates #36905

Change-Id: I3abb6a8029cd0c9099b592ccb01ca5606c93edec
Reviewed-on: https://go-review.googlesource.com/c/go/+/316110
Trust: Bryan C. Mills <bcmills@google.com>
Run-TryBot: Bryan C. Mills <bcmills@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
This commit is contained in:
Bryan C. Mills 2021-05-02 08:52:06 -04:00
parent abb110bf3d
commit 2c9f5a1da8
10 changed files with 5831 additions and 5524 deletions

View File

@ -5,7 +5,7 @@ go 1.17
require (
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 // indirect
golang.org/x/arch v0.0.0-20210308155006-05f8f0431f72
golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect
golang.org/x/mod v0.4.3-0.20210409134425-858fdbee9c24
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect

View File

@ -6,8 +6,8 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/yuin/goldmark v1.3.3/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/arch v0.0.0-20210308155006-05f8f0431f72 h1:CdaLHkic8S6xdhpWgHmtWij2rv2DTGwPuJZjjEDGk2w=
golang.org/x/arch v0.0.0-20210308155006-05f8f0431f72/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e h1:pv3V0NlNSh5Q6AX/StwGLBjcLS7UN4m4Gq+V+uSecqM=
golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
@ -42,4 +42,3 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@ -126,7 +126,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
op = "VMOV"
}
case LDR:
case LDR, LDUR:
var rno uint16
if r, ok := inst.Args[0].(Reg); ok {
rno = uint16(r)
@ -135,12 +135,21 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
}
if rno <= uint16(WZR) {
op = "MOVWU" + suffix
} else if rno >= uint16(B0) && rno <= uint16(B31) {
op = "FMOVB" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(H0) && rno <= uint16(H31) {
op = "FMOVH" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(S0) && rno <= uint16(S31) {
op = "FMOVS" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(D0) && rno <= uint16(D31) {
op = "FMOVD" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(Q0) && rno <= uint16(Q31) {
op = "FMOVQ" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else {
op = "MOVD" + suffix
}
@ -181,12 +190,21 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
}
if rno <= uint16(WZR) {
op = "MOVW" + suffix
} else if rno >= uint16(B0) && rno <= uint16(B31) {
op = "FMOVB" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(H0) && rno <= uint16(H31) {
op = "FMOVH" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(S0) && rno <= uint16(S31) {
op = "FMOVS" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(D0) && rno <= uint16(D31) {
op = "FMOVD" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else if rno >= uint16(Q0) && rno <= uint16(Q31) {
op = "FMOVQ" + suffix
args[0] = fmt.Sprintf("F%d", rno&31)
} else {
op = "MOVD" + suffix
}
@ -251,18 +269,31 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text
op += "W"
}
}
fallthrough
args[0] = fmt.Sprintf("(%s, %s)", args[0], args[1])
args[1] = args[2]
return op + " " + args[1] + ", " + args[0]
case STP, LDP:
args[0] = fmt.Sprintf("(%s, %s)", args[0], args[1])
args[1] = args[2]
if op == "STP" {
op = op + suffix
rno, ok := inst.Args[0].(Reg)
if !ok {
rno = Reg(inst.Args[0].(RegSP))
}
if rno <= WZR {
op = op + "W"
} else if rno >= S0 && rno <= S31 {
op = "F" + op + "S"
} else if rno >= D0 && rno <= D31 {
op = "F" + op + "D"
} else if rno >= Q0 && rno <= Q31 {
op = "F" + op + "Q"
}
op = op + suffix
if inst.Op.String() == "STP" {
return op + " " + args[0] + ", " + args[1]
} else if op == "LDP" {
op = op + suffix
return op + " " + args[1] + ", " + args[0]
} else if op == "LDAXP" || op == "LDXP" || op == "LDAXPW" || op == "LDXPW" {
} else {
return op + " " + args[1] + ", " + args[0]
}
@ -469,6 +500,12 @@ SHA256SU0
SHA256SU1
`)
// floating point instrcutions without "F" prefix.
var fOpsWithoutFPrefix = map[Op]bool{
LDP: true,
STP: true,
}
func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
switch a := arg.(type) {
case Imm:
@ -494,20 +531,17 @@ func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg
regenum := uint16(a)
regno := uint16(a) & 31
if regenum >= uint16(B0) && regenum <= uint16(D31) {
if strings.HasPrefix(inst.Op.String(), "F") || strings.HasSuffix(inst.Op.String(), "CVTF") {
if regenum >= uint16(B0) && regenum <= uint16(Q31) {
if strings.HasPrefix(inst.Op.String(), "F") || strings.HasSuffix(inst.Op.String(), "CVTF") || fOpsWithoutFPrefix[inst.Op] {
// FP registers are the same ones as SIMD registers
// Print Fn for scalar variant to align with assembler (e.g., FCVT, SCVTF, UCVTF, etc.)
return fmt.Sprintf("F%d", regno)
} else {
// Print Vn to align with assembler (e.g., SHA256H)
return fmt.Sprintf("V%d", regno)
}
} else if regenum >= uint16(Q0) && regenum <= uint16(Q31) {
// Print Vn to align with assembler (e.g., SHA256H)
return fmt.Sprintf("V%d", regno)
}
if regno == 31 {
return "ZR"
}

View File

@ -12,18 +12,25 @@ import (
const debugDecode = false
const prefixOpcode = 1
// instFormat is a decoding rule for one specific instruction form.
// a uint32 instruction ins matches the rule if ins&Mask == Value
// an instruction ins matches the rule if ins&Mask == Value
// DontCare bits should be zero, but the machine might not reject
// ones in those bits, they are mainly reserved for future expansion
// of the instruction set.
// The Args are stored in the same order as the instruction manual.
//
// Prefixed instructions are stored as:
// prefix << 32 | suffix,
// Regular instructions are:
// inst << 32
type instFormat struct {
Op Op
Mask uint32
Value uint32
DontCare uint32
Args [5]*argField
Mask uint64
Value uint64
DontCare uint64
Args [6]*argField
}
// argField indicate how to decode an argument to an instruction.
@ -36,7 +43,7 @@ type argField struct {
}
// Parse parses the Arg out from the given binary instruction i.
func (a argField) Parse(i uint32) Arg {
func (a argField) Parse(i [2]uint32) Arg {
switch a.Type {
default:
return nil
@ -54,6 +61,10 @@ func (a argField) Parse(i uint32) Arg {
return V0 + Reg(a.BitFields.Parse(i))
case TypeVecSReg:
return VS0 + Reg(a.BitFields.Parse(i))
case TypeVecSpReg:
return VS0 + Reg(a.BitFields.Parse(i))*2
case TypeMMAReg:
return A0 + Reg(a.BitFields.Parse(i))
case TypeSpReg:
return SpReg(a.BitFields.Parse(i))
case TypeImmSigned:
@ -81,6 +92,8 @@ const (
TypeFPReg // floating point register
TypeVecReg // vector register
TypeVecSReg // VSX register
TypeVecSpReg // VSX register pair (even only encoding)
TypeMMAReg // MMA register
TypeSpReg // special register (depends on Op)
TypeImmSigned // signed immediate
TypeImmUnsigned // unsigned immediate/flag/mask, this is the catch-all type
@ -106,6 +119,10 @@ func (t ArgType) String() string {
return "VecReg"
case TypeVecSReg:
return "VecSReg"
case TypeVecSpReg:
return "VecSpReg"
case TypeMMAReg:
return "MMAReg"
case TypeSpReg:
return "SpReg"
case TypeImmSigned:
@ -146,9 +163,22 @@ func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) {
if decoderCover == nil {
decoderCover = make([]bool, len(instFormats))
}
inst.Len = 4 // only 4-byte instructions are supported
ui := ord.Uint32(src[:inst.Len])
inst.Enc = ui
inst.Len = 4
ui_extn := [2]uint32{ord.Uint32(src[:inst.Len]), 0}
ui := uint64(ui_extn[0]) << 32
inst.Enc = ui_extn[0]
opcode := inst.Enc >> 26
if opcode == prefixOpcode {
// This is a prefixed instruction
inst.Len = 8
if len(src) < 8 {
return inst, errShort
}
// Merge the suffixed word.
ui_extn[1] = ord.Uint32(src[4:inst.Len])
ui |= uint64(ui_extn[1])
inst.SuffixEnc = ui_extn[1]
}
for i, iform := range instFormats {
if ui&iform.Mask != iform.Value {
continue
@ -163,7 +193,7 @@ func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) {
if argfield == nil {
break
}
inst.Args[i] = argfield.Parse(ui)
inst.Args[i] = argfield.Parse(ui_extn)
}
inst.Op = iform.Op
if debugDecode {

View File

@ -14,6 +14,10 @@ import (
type BitField struct {
Offs uint8 // the offset of the left-most bit.
Bits uint8 // length in bits.
// This instruction word holding this field.
// It is always 0 for ISA < 3.1 instructions. It is
// in decoding order. (0 == prefix, 1 == suffix on ISA 3.1)
Word uint8
}
func (b BitField) String() string {
@ -28,16 +32,16 @@ func (b BitField) String() string {
// Parse extracts the bitfield b from i, and return it as an unsigned integer.
// Parse will panic if b is invalid.
func (b BitField) Parse(i uint32) uint32 {
func (b BitField) Parse(i [2]uint32) uint32 {
if b.Bits > 32 || b.Bits == 0 || b.Offs > 31 || b.Offs+b.Bits > 32 {
panic(fmt.Sprintf("invalid bitfiled %v", b))
}
return (i >> (32 - b.Offs - b.Bits)) & ((1 << b.Bits) - 1)
return (i[b.Word] >> (32 - b.Offs - b.Bits)) & ((1 << b.Bits) - 1)
}
// ParseSigned extracts the bitfield b from i, and return it as a signed integer.
// ParseSigned will panic if b is invalid.
func (b BitField) ParseSigned(i uint32) int32 {
func (b BitField) ParseSigned(i [2]uint32) int32 {
u := int32(b.Parse(i))
return u << (32 - b.Bits) >> (32 - b.Bits)
}
@ -61,9 +65,9 @@ func (bs *BitFields) Append(b BitField) {
// as an unsigned integer and the total length of all the bitfields.
// parse will panic if any bitfield in b is invalid, but it doesn't check if
// the sequence of bitfields is reasonable.
func (bs BitFields) parse(i uint32) (u uint32, Bits uint8) {
func (bs BitFields) parse(i [2]uint32) (u uint64, Bits uint8) {
for _, b := range bs {
u = (u << b.Bits) | b.Parse(i)
u = (uint64(u) << b.Bits) | uint64(b.Parse(i))
Bits += b.Bits
}
return u, Bits
@ -71,14 +75,14 @@ func (bs BitFields) parse(i uint32) (u uint32, Bits uint8) {
// Parse extracts the bitfields from i, concatenate them and return the result
// as an unsigned integer. Parse will panic if any bitfield in b is invalid.
func (bs BitFields) Parse(i uint32) uint32 {
func (bs BitFields) Parse(i [2]uint32) uint64 {
u, _ := bs.parse(i)
return u
}
// Parse extracts the bitfields from i, concatenate them and return the result
// as a signed integer. Parse will panic if any bitfield in b is invalid.
func (bs BitFields) ParseSigned(i uint32) int32 {
func (bs BitFields) ParseSigned(i [2]uint32) int64 {
u, l := bs.parse(i)
return int32(u) << (32 - l) >> (32 - l)
return int64(u) << (64 - l) >> (64 - l)
}

View File

@ -34,6 +34,8 @@ func GNUSyntax(inst Inst, pc uint64) string {
startArg := 0
sep := " "
opName := inst.Op.String()
argList := inst.Args[:]
switch opName {
case "bc", "bcl", "bca", "bcla", "bclr", "bclrl", "bcctr", "bcctrl", "bctar", "bctarl":
sfx := inst.Op.String()[2:]
@ -223,23 +225,111 @@ func GNUSyntax(inst Inst, pc uint64) string {
buf.WriteString("spr")
}
case "sync":
switch arg := inst.Args[0].(type) {
case Imm:
switch arg {
case 0:
buf.WriteString("hwsync")
case 1:
buf.WriteString("lwsync")
case 2:
buf.WriteString("ptesync")
}
case "mtfsfi", "mtfsfi.":
buf.WriteString(opName)
l := inst.Args[2].(Imm)
if l == 0 {
// L == 0 is an extended mnemonic for the same.
asm := fmt.Sprintf(" %s,%s",
gnuArg(&inst, 0, inst.Args[0], PC),
gnuArg(&inst, 1, inst.Args[1], PC))
buf.WriteString(asm)
startArg = 3
}
case "paste.":
buf.WriteString(opName)
l := inst.Args[2].(Imm)
if l == 1 {
// L == 1 is an extended mnemonic for the same.
asm := fmt.Sprintf(" %s,%s",
gnuArg(&inst, 0, inst.Args[0], PC),
gnuArg(&inst, 1, inst.Args[1], PC))
buf.WriteString(asm)
startArg = 3
}
case "mtfsf", "mtfsf.":
buf.WriteString(opName)
l := inst.Args[3].(Imm)
if l == 0 {
// L == 0 is an extended mnemonic for the same.
asm := fmt.Sprintf(" %s,%s,%s",
gnuArg(&inst, 0, inst.Args[0], PC),
gnuArg(&inst, 1, inst.Args[1], PC),
gnuArg(&inst, 2, inst.Args[2], PC))
buf.WriteString(asm)
startArg = 4
}
case "sync":
lsc := inst.Args[0].(Imm)<<4 | inst.Args[1].(Imm)
switch lsc {
case 0x00:
buf.WriteString("hwsync")
startArg = 2
case 0x10:
buf.WriteString("lwsync")
startArg = 2
default:
buf.WriteString(opName)
}
case "lbarx", "lharx", "lwarx", "ldarx":
// If EH == 0, omit printing EH.
eh := inst.Args[3].(Imm)
if eh == 0 {
argList = inst.Args[:3]
}
startArg = 2
default:
buf.WriteString(inst.Op.String())
case "paddi":
// There are several extended mnemonics. Notably, "pla" is
// the only valid mnemonic for paddi (R=1), In this case, RA must
// always be 0. Otherwise it is invalid.
r := inst.Args[3].(Imm)
ra := inst.Args[1].(Reg)
str := opName
if ra == R0 {
name := []string{"pli", "pla"}
str = fmt.Sprintf("%s %s,%s",
name[r&1],
gnuArg(&inst, 0, inst.Args[0], PC),
gnuArg(&inst, 2, inst.Args[2], PC))
startArg = 4
} else if r == 0 {
str = fmt.Sprintf("%s %s,%s,%s", opName,
gnuArg(&inst, 0, inst.Args[0], PC),
gnuArg(&inst, 1, inst.Args[1], PC),
gnuArg(&inst, 2, inst.Args[2], PC))
startArg = 4
}
buf.WriteString(str)
default:
// Prefixed load/stores do not print the displacement register when R==1 (they are PCrel).
// This also implies RA should be 0. Likewise, when R==0, printing of R can be omitted.
if strings.HasPrefix(opName, "pl") || strings.HasPrefix(opName, "pst") {
r := inst.Args[3].(Imm)
ra := inst.Args[2].(Reg)
d := inst.Args[1].(Offset)
if r == 1 && ra == R0 {
str := fmt.Sprintf("%s %s,%d", opName, gnuArg(&inst, 0, inst.Args[0], PC), d)
buf.WriteString(str)
startArg = 4
} else if r == 0 {
str := fmt.Sprintf("%s %s,%d(%s)", opName,
gnuArg(&inst, 0, inst.Args[0], PC),
d,
gnuArg(&inst, 2, inst.Args[2], PC))
buf.WriteString(str)
startArg = 4
}
} else {
buf.WriteString(opName)
}
}
for i, arg := range inst.Args[:] {
for i, arg := range argList {
if arg == nil {
break
}

View File

@ -10,10 +10,11 @@ import (
)
type Inst struct {
Op Op // Opcode mnemonic
Enc uint32 // Raw encoding bits
Len int // Length of encoding in bytes.
Args Args // Instruction arguments, in Power ISA manual order.
Op Op // Opcode mnemonic
Enc uint32 // Raw encoding bits (if Len == 8, this is the prefix word)
Len int // Length of encoding in bytes.
SuffixEnc uint32 // Raw encoding bits of second word (if Len == 8)
Args Args // Instruction arguments, in Power ISA manual order.
}
func (i Inst) String() string {
@ -50,9 +51,9 @@ type Arg interface {
}
// An Args holds the instruction arguments.
// If an instruction has fewer than 4 arguments,
// If an instruction has fewer than 6 arguments,
// the final elements in the array are nil.
type Args [5]Arg
type Args [6]Arg
// A Reg is a single register. The zero value means R0, not the absence of a register.
// It also includes special registers.
@ -220,6 +221,14 @@ const (
VS61
VS62
VS63
A0 // MMA registers. These are effectively shadow registers of four adjacent VSR's [An*4,An*4+3]
A1
A2
A3
A4
A5
A6
A7
)
func (Reg) IsArg() {}
@ -233,6 +242,8 @@ func (r Reg) String() string {
return fmt.Sprintf("v%d", int(r-V0))
case VS0 <= r && r <= VS63:
return fmt.Sprintf("vs%d", int(r-VS0))
case A0 <= r && r <= A7:
return fmt.Sprintf("a%d", int(r-A0))
default:
return fmt.Sprintf("Reg(%d)", int(r))
}
@ -328,7 +339,7 @@ func (l Label) String() string {
}
// Imm represents an immediate number.
type Imm int32
type Imm int64
func (Imm) IsArg() {}
func (i Imm) String() string {
@ -336,7 +347,7 @@ func (i Imm) String() string {
}
// Offset represents a memory offset immediate.
type Offset int32
type Offset int64
func (Offset) IsArg() {}
func (o Offset) String() string {

View File

@ -76,6 +76,9 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
}
args = append(args, args[0])
return op + " " + strings.Join(args[1:], ",")
case PASTECC:
// paste. has two input registers, and an L field, unlike other 3 operand instructions.
return op + " " + args[0] + "," + args[1] + "," + args[2]
case SYNC:
if args[0] == "$1" {
return "LWSYNC"
@ -136,7 +139,7 @@ func GoSyntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) strin
case LXVL, LXVLL:
return op + " " + args[1] + "," + args[2] + "," + args[0]
case DCBT, DCBTST, DCBZ, DCBST, DCBI, ICBI:
case DCBT, DCBTST, DCBZ, DCBST, ICBI:
if args[0] == "0" || args[0] == "R0" {
return op + " (" + args[1] + ")"
}

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,8 @@ github.com/google/pprof/third_party/svgpan
# github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639
## explicit
github.com/ianlancetaylor/demangle
# golang.org/x/arch v0.0.0-20210308155006-05f8f0431f72
## explicit; go 1.11
# golang.org/x/arch v0.0.0-20210502124803-cbf565b21d1e
## explicit; go 1.17
golang.org/x/arch/arm/armasm
golang.org/x/arch/arm64/arm64asm
golang.org/x/arch/ppc64/ppc64asm