mirror of
https://github.com/golang/go
synced 2024-11-22 03:44:39 -07:00
cmd/objdump: add s390x GNU disasm support
This CL provides vendor support for s390x disassembler gnu syntax. go get golang.org/x/arch@master go mod tidy go mod vendor For #15255 Change-Id: Ia75fa515e7ea7d56913a28147c65650a7ab3062c Reviewed-on: https://go-review.googlesource.com/c/go/+/581015 Reviewed-by: Cherry Mui <cherryyz@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Vishwanatha HD <vishwanatha.hd@ibm.com> Run-TryBot: Cherry Mui <cherryyz@google.com> Auto-Submit: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Bill O'Farrell <billotosyr@gmail.com>
This commit is contained in:
parent
a96e736284
commit
0d5605832c
@ -4,7 +4,7 @@ go 1.24
|
||||
|
||||
require (
|
||||
github.com/google/pprof v0.0.0-20240722153945-304e4f0156b8
|
||||
golang.org/x/arch v0.8.1-0.20240716161256-b863392466ea
|
||||
golang.org/x/arch v0.9.1-0.20240807172201-9d90945922a7
|
||||
golang.org/x/build v0.0.0-20240722200705-b9910f320300
|
||||
golang.org/x/mod v0.20.0
|
||||
golang.org/x/sync v0.8.0
|
||||
|
@ -6,8 +6,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 h1:KwWnWVW
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/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.8.1-0.20240716161256-b863392466ea h1:+dKVGZM+cuxx3fooVKLDxZIPzKR1HYO1Xkd12Je4Z9k=
|
||||
golang.org/x/arch v0.8.1-0.20240716161256-b863392466ea/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/arch v0.9.1-0.20240807172201-9d90945922a7 h1:4+03DsxQb03qtr7e32FA8tiq18ytCUClXaXxQBDRGbs=
|
||||
golang.org/x/arch v0.9.1-0.20240807172201-9d90945922a7/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/build v0.0.0-20240722200705-b9910f320300 h1:2Cqg4LnvfD2ZpG8+6KbyYUkweWhNS3SgfcN/eeVseJ0=
|
||||
golang.org/x/build v0.0.0-20240722200705-b9910f320300/go.mod h1:YsGhg4JUVUWLzdqU2wCrtpRrOveOql6w56FLDHq/CJ4=
|
||||
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"golang.org/x/arch/arm/armasm"
|
||||
"golang.org/x/arch/arm64/arm64asm"
|
||||
"golang.org/x/arch/ppc64/ppc64asm"
|
||||
"golang.org/x/arch/s390x/s390xasm"
|
||||
"golang.org/x/arch/x86/x86asm"
|
||||
)
|
||||
|
||||
@ -383,6 +384,23 @@ func disasm_ppc64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.By
|
||||
return text, size
|
||||
}
|
||||
|
||||
func disasm_s390x(code []byte, pc uint64, lookup lookupFunc, _ binary.ByteOrder, gnuAsm bool) (string, int) {
|
||||
inst, err := s390xasm.Decode(code)
|
||||
var text string
|
||||
size := inst.Len
|
||||
if err != nil || size == 0 || inst.Op == 0 {
|
||||
size = 2
|
||||
text = "?"
|
||||
} else {
|
||||
if gnuAsm {
|
||||
text = fmt.Sprintf("%s", s390xasm.GNUSyntax(inst, pc))
|
||||
} else {
|
||||
text = fmt.Sprintf("%s", "Go/plan9 syntax unsupported..!!")
|
||||
}
|
||||
}
|
||||
return text, size
|
||||
}
|
||||
|
||||
var disasms = map[string]disasmFunc{
|
||||
"386": disasm_386,
|
||||
"amd64": disasm_amd64,
|
||||
@ -390,6 +408,7 @@ var disasms = map[string]disasmFunc{
|
||||
"arm64": disasm_arm64,
|
||||
"ppc64": disasm_ppc64,
|
||||
"ppc64le": disasm_ppc64,
|
||||
"s390x": disasm_s390x,
|
||||
}
|
||||
|
||||
var byteOrders = map[string]binary.ByteOrder{
|
||||
|
@ -104,6 +104,12 @@ var ppcGnuNeed = []string{
|
||||
"beq",
|
||||
}
|
||||
|
||||
var s390xGnuNeed = []string{
|
||||
"brasl",
|
||||
"j",
|
||||
"clije",
|
||||
}
|
||||
|
||||
func mustHaveDisasm(t *testing.T) {
|
||||
switch runtime.GOARCH {
|
||||
case "loong64":
|
||||
@ -112,8 +118,6 @@ func mustHaveDisasm(t *testing.T) {
|
||||
t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
|
||||
case "riscv64":
|
||||
t.Skipf("skipping on %s, issue 36738", runtime.GOARCH)
|
||||
case "s390x":
|
||||
t.Skipf("skipping on %s, issue 15255", runtime.GOARCH)
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,6 +206,8 @@ func testDisasm(t *testing.T, srcfname string, printCode bool, printGnuAsm bool,
|
||||
need = append(need, armGnuNeed...)
|
||||
case "ppc64", "ppc64le":
|
||||
need = append(need, ppcGnuNeed...)
|
||||
case "s390x":
|
||||
need = append(need, s390xGnuNeed...)
|
||||
}
|
||||
}
|
||||
args = []string{
|
||||
|
2
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/Makefile
generated
vendored
Normal file
2
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/Makefile
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
tables.go: ../s390xmap/map.go ../s390x.csv
|
||||
go run ../s390xmap/map.go -fmt=decoder ../s390x.csv >_tables.go && gofmt _tables.go >tables.go && rm _tables.go
|
241
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/decode.go
generated
vendored
Normal file
241
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/decode.go
generated
vendored
Normal file
@ -0,0 +1,241 @@
|
||||
// Copyright 2024 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 s390xasm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// instFormat is a decoding rule for one specific instruction form.
|
||||
// An instruction ins matches the rule if ins&Mask == Value.
|
||||
// DontCare bits are mainly used for finding the same instruction
|
||||
// name differing with the number of argument fields.
|
||||
// The Args are stored in the same order as the instruction manual.
|
||||
type instFormat struct {
|
||||
Op Op
|
||||
Mask uint64
|
||||
Value uint64
|
||||
DontCare uint64
|
||||
Args [8]*argField
|
||||
}
|
||||
|
||||
// argField indicate how to decode an argument to an instruction.
|
||||
// First parse the value from the BitFields, shift it left by Shift
|
||||
// bits to get the actual numerical value.
|
||||
type argField struct {
|
||||
Type ArgType
|
||||
flags uint16
|
||||
BitField
|
||||
}
|
||||
|
||||
// Parse parses the Arg out from the given binary instruction i.
|
||||
func (a argField) Parse(i uint64) Arg {
|
||||
switch a.Type {
|
||||
default:
|
||||
return nil
|
||||
case TypeUnknown:
|
||||
return nil
|
||||
case TypeReg:
|
||||
return R0 + Reg(a.BitField.Parse(i))
|
||||
case TypeFPReg:
|
||||
return F0 + Reg(a.BitField.Parse(i))
|
||||
case TypeCReg:
|
||||
return C0 + Reg(a.BitField.Parse(i))
|
||||
case TypeACReg:
|
||||
return A0 + Reg(a.BitField.Parse(i))
|
||||
case TypeBaseReg:
|
||||
return B0 + Base(a.BitField.Parse(i))
|
||||
case TypeIndexReg:
|
||||
return X0 + Index(a.BitField.Parse(i))
|
||||
case TypeDispUnsigned:
|
||||
return Disp12(a.BitField.Parse(i))
|
||||
case TypeDispSigned20:
|
||||
return Disp20(a.BitField.ParseSigned(i))
|
||||
case TypeVecReg:
|
||||
m := i >> 24 // Handling RXB field(bits 36 to 39)
|
||||
if ((m>>3)&0x1 == 1) && (a.BitField.Offs == 8) {
|
||||
return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
|
||||
} else if ((m>>2)&0x1 == 1) && (a.BitField.Offs == 12) {
|
||||
return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
|
||||
} else if ((m>>1)&0x1 == 1) && (a.BitField.Offs == 16) {
|
||||
return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
|
||||
} else if ((m)&0x1 == 1) && (a.BitField.Offs == 32) {
|
||||
return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
|
||||
} else {
|
||||
return V0 + VReg(a.BitField.Parse(i))
|
||||
}
|
||||
case TypeImmSigned8:
|
||||
return Sign8(a.BitField.ParseSigned(i))
|
||||
case TypeImmSigned16:
|
||||
return Sign16(a.BitField.ParseSigned(i))
|
||||
case TypeImmSigned32:
|
||||
return Sign32(a.BitField.ParseSigned(i))
|
||||
case TypeImmUnsigned:
|
||||
return Imm(a.BitField.Parse(i))
|
||||
case TypeRegImSigned12:
|
||||
return RegIm12(a.BitField.ParseSigned(i))
|
||||
case TypeRegImSigned16:
|
||||
return RegIm16(a.BitField.ParseSigned(i))
|
||||
case TypeRegImSigned24:
|
||||
return RegIm24(a.BitField.ParseSigned(i))
|
||||
case TypeRegImSigned32:
|
||||
return RegIm32(a.BitField.ParseSigned(i))
|
||||
case TypeMask:
|
||||
return Mask(a.BitField.Parse(i))
|
||||
case TypeLen:
|
||||
return Len(a.BitField.Parse(i))
|
||||
}
|
||||
}
|
||||
|
||||
type ArgType int8
|
||||
|
||||
const (
|
||||
TypeUnknown ArgType = iota
|
||||
TypeReg // integer register
|
||||
TypeFPReg // floating point register
|
||||
TypeACReg // access register
|
||||
TypeCReg // control register
|
||||
TypeVecReg // vector register
|
||||
TypeImmUnsigned // unsigned immediate/flag/mask, this is the catch-all type
|
||||
TypeImmSigned8 // Signed 8-bit Immdediate
|
||||
TypeImmSigned16 // Signed 16-bit Immdediate
|
||||
TypeImmSigned32 // Signed 32-bit Immdediate
|
||||
TypeBaseReg // Base Register for accessing memory
|
||||
TypeIndexReg // Index Register
|
||||
TypeDispUnsigned // Displacement 12-bit unsigned for memory address
|
||||
TypeDispSigned20 // Displacement 20-bit signed for memory address
|
||||
TypeRegImSigned12 // RegisterImmediate 12-bit signed data
|
||||
TypeRegImSigned16 // RegisterImmediate 16-bit signed data
|
||||
TypeRegImSigned24 // RegisterImmediate 24-bit signed data
|
||||
TypeRegImSigned32 // RegisterImmediate 32-bit signed data
|
||||
TypeMask // 4-bit Mask
|
||||
TypeLen // Length of Memory Operand
|
||||
TypeLast
|
||||
)
|
||||
|
||||
func (t ArgType) String() string {
|
||||
switch t {
|
||||
default:
|
||||
return fmt.Sprintf("ArgType(%d)", int(t))
|
||||
case TypeUnknown:
|
||||
return "Unknown"
|
||||
case TypeReg:
|
||||
return "Reg"
|
||||
case TypeFPReg:
|
||||
return "FPReg"
|
||||
case TypeACReg:
|
||||
return "ACReg"
|
||||
case TypeCReg:
|
||||
return "CReg"
|
||||
case TypeDispUnsigned:
|
||||
return "DispUnsigned"
|
||||
case TypeDispSigned20:
|
||||
return "DispSigned20"
|
||||
case TypeBaseReg:
|
||||
return "BaseReg"
|
||||
case TypeIndexReg:
|
||||
return "IndexReg"
|
||||
case TypeVecReg:
|
||||
return "VecReg"
|
||||
case TypeImmSigned8:
|
||||
return "ImmSigned8"
|
||||
case TypeImmSigned16:
|
||||
return "ImmSigned16"
|
||||
case TypeImmSigned32:
|
||||
return "ImmSigned32"
|
||||
case TypeImmUnsigned:
|
||||
return "ImmUnsigned"
|
||||
case TypeRegImSigned12:
|
||||
return "RegImSigned12"
|
||||
case TypeRegImSigned16:
|
||||
return "RegImSigned16"
|
||||
case TypeRegImSigned24:
|
||||
return "RegImSigned24"
|
||||
case TypeRegImSigned32:
|
||||
return "RegImSigned32"
|
||||
case TypeMask:
|
||||
return "Mask"
|
||||
case TypeLen:
|
||||
return "Len"
|
||||
}
|
||||
}
|
||||
|
||||
func (t ArgType) GoString() string {
|
||||
s := t.String()
|
||||
if t > 0 && t < TypeLast {
|
||||
return "Type" + s
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
var (
|
||||
// Errors
|
||||
errShort = fmt.Errorf("truncated instruction")
|
||||
errUnknown = fmt.Errorf("unknown instruction")
|
||||
)
|
||||
|
||||
var decoderCover []bool
|
||||
|
||||
// Decode decodes the leading bytes in src as a single instruction using
|
||||
// byte order ord.
|
||||
func Decode(src []byte) (inst Inst, err error) {
|
||||
if len(src) < 2 {
|
||||
return inst, errShort
|
||||
}
|
||||
if decoderCover == nil {
|
||||
decoderCover = make([]bool, len(instFormats))
|
||||
}
|
||||
bit_check := binary.BigEndian.Uint16(src[:2])
|
||||
bit_check = bit_check >> 14
|
||||
l := int(0)
|
||||
if (bit_check & 0x03) == 0 {
|
||||
l = 2
|
||||
} else if bit_check&0x03 == 3 {
|
||||
l = 6
|
||||
} else if (bit_check&0x01 == 1) || (bit_check&0x02 == 2) {
|
||||
l = 4
|
||||
}
|
||||
inst.Len = l
|
||||
ui_extn := uint64(0)
|
||||
switch l {
|
||||
case 2:
|
||||
ui_extn = uint64(binary.BigEndian.Uint16(src[:inst.Len]))
|
||||
inst.Enc = ui_extn
|
||||
ui_extn = ui_extn << 48
|
||||
case 4:
|
||||
ui_extn = uint64(binary.BigEndian.Uint32(src[:inst.Len]))
|
||||
inst.Enc = ui_extn
|
||||
ui_extn = ui_extn << 32
|
||||
case 6:
|
||||
u1 := binary.BigEndian.Uint32(src[:(inst.Len - 2)])
|
||||
u2 := binary.BigEndian.Uint16(src[(inst.Len - 2):inst.Len])
|
||||
ui_extn = uint64(u1)<<16 | uint64(u2)
|
||||
ui_extn = ui_extn << 16
|
||||
inst.Enc = ui_extn
|
||||
default:
|
||||
return inst, errShort
|
||||
}
|
||||
for _, iform := range instFormats {
|
||||
if ui_extn&iform.Mask != iform.Value {
|
||||
continue
|
||||
}
|
||||
if (iform.DontCare & ^(ui_extn)) != iform.DontCare {
|
||||
continue
|
||||
}
|
||||
for j, argfield := range iform.Args {
|
||||
if argfield == nil {
|
||||
break
|
||||
}
|
||||
inst.Args[j] = argfield.Parse(ui_extn)
|
||||
}
|
||||
inst.Op = iform.Op
|
||||
break
|
||||
}
|
||||
if inst.Op == 0 && inst.Enc != 0 {
|
||||
return inst, errUnknown
|
||||
}
|
||||
return inst, nil
|
||||
}
|
98
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/field.go
generated
vendored
Normal file
98
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/field.go
generated
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
// Copyright 2024 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 s390xasm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// A BitField is a bit-field in a 64-bit double word.
|
||||
// Bits are counted from 0 from the MSB to 63 as the LSB.
|
||||
type BitField struct {
|
||||
Offs uint8 // the offset of the left-most bit.
|
||||
Bits uint8 // length in bits.
|
||||
}
|
||||
|
||||
func (b BitField) String() string {
|
||||
if b.Bits > 1 {
|
||||
return fmt.Sprintf("[%d:%d]", b.Offs, int(b.Offs+b.Bits)-1)
|
||||
} else if b.Bits == 1 {
|
||||
return fmt.Sprintf("[%d]", b.Offs)
|
||||
} else {
|
||||
return fmt.Sprintf("[%d, len=0]", b.Offs)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 uint64) uint64 {
|
||||
if b.Bits > 64 || b.Bits == 0 || b.Offs > 63 || b.Offs+b.Bits > 64 {
|
||||
panic(fmt.Sprintf("invalid bitfiled %v", b))
|
||||
}
|
||||
if b.Bits == 20 {
|
||||
return ((((i >> (64 - b.Offs - b.Bits)) & ((1 << 8) - 1)) << 12) | ((i >> (64 - b.Offs - b.Bits + 8)) & 0xFFF))
|
||||
|
||||
} else {
|
||||
return (i >> (64 - 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 uint64) int64 {
|
||||
u := int64(b.Parse(i))
|
||||
return u << (64 - b.Bits) >> (64 - b.Bits)
|
||||
}
|
||||
|
||||
// BitFields is a series of BitFields representing a single number.
|
||||
type BitFields []BitField
|
||||
|
||||
func (bs BitFields) String() string {
|
||||
ss := make([]string, len(bs))
|
||||
for i, bf := range bs {
|
||||
ss[i] = bf.String()
|
||||
}
|
||||
return fmt.Sprintf("<%s>", strings.Join(ss, "|"))
|
||||
}
|
||||
|
||||
func (bs *BitFields) Append(b BitField) {
|
||||
*bs = append(*bs, b)
|
||||
}
|
||||
|
||||
// parse extracts the bitfields from i, concatenate them and return the result
|
||||
// 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 uint64) (u uint64, Bits uint8) {
|
||||
for _, b := range bs {
|
||||
u = (u << b.Bits) | uint64(b.Parse(i))
|
||||
Bits += b.Bits
|
||||
}
|
||||
return u, Bits
|
||||
}
|
||||
|
||||
// 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 uint64) uint64 {
|
||||
u, _ := bs.parse(i)
|
||||
return u
|
||||
}
|
||||
|
||||
// ParseSigned 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 uint64) int64 {
|
||||
u, l := bs.parse(i)
|
||||
return int64(u) << (64 - l) >> (64 - l)
|
||||
}
|
||||
|
||||
// Count the number of bits in the aggregate BitFields
|
||||
func (bs BitFields) NumBits() int {
|
||||
num := 0
|
||||
for _, b := range bs {
|
||||
num += int(b.Bits)
|
||||
}
|
||||
return num
|
||||
}
|
1018
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/gnu.go
generated
vendored
Normal file
1018
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/gnu.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
399
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/inst.go
generated
vendored
Normal file
399
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/inst.go
generated
vendored
Normal file
@ -0,0 +1,399 @@
|
||||
// Copyright 2024 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 s390xasm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Inst struct {
|
||||
Op Op // Opcode mnemonic
|
||||
Enc uint64 // Raw encoding bits (if Len == 8, this is the prefix word)
|
||||
Len int // Length of encoding in bytes.
|
||||
Args Args // Instruction arguments, in Power ISA manual order.
|
||||
}
|
||||
|
||||
func (i Inst) String(pc uint64) string {
|
||||
var buf bytes.Buffer
|
||||
var rxb_check bool
|
||||
m := i.Op.String()
|
||||
if strings.HasPrefix(m, "v") || strings.Contains(m, "wfc") || strings.Contains(m, "wfk") {
|
||||
rxb_check = true
|
||||
}
|
||||
mnemonic := HandleExtndMnemonic(&i)
|
||||
buf.WriteString(fmt.Sprintf("%s", mnemonic))
|
||||
for j, arg := range i.Args {
|
||||
if arg == nil {
|
||||
break
|
||||
}
|
||||
if j == 0 {
|
||||
buf.WriteString(" ")
|
||||
} else {
|
||||
switch arg.(type) {
|
||||
case VReg, Reg:
|
||||
if _, ok := i.Args[j-1].(Disp12); ok {
|
||||
buf.WriteString("")
|
||||
} else if _, ok := i.Args[j-1].(Disp20); ok {
|
||||
buf.WriteString("")
|
||||
} else {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
case Base:
|
||||
if _, ok := i.Args[j-1].(VReg); ok {
|
||||
buf.WriteString(",")
|
||||
} else if _, ok := i.Args[j-1].(Reg); ok {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
case Index, Len:
|
||||
default:
|
||||
buf.WriteString(",")
|
||||
}
|
||||
}
|
||||
buf.WriteString(arg.String(pc))
|
||||
if rxb_check && i.Args[j+2] == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// An Op is an instruction operation.
|
||||
type Op uint16
|
||||
|
||||
func (o Op) String() string {
|
||||
if int(o) >= len(opstr) || opstr[o] == "" {
|
||||
return fmt.Sprintf("Op(%d)", int(o))
|
||||
}
|
||||
return opstr[o]
|
||||
}
|
||||
|
||||
// An Arg is a single instruction argument.
|
||||
// One of these types: Reg, Base, Index, Disp20, Disp12, Len, Mask, Sign8, Sign16, Sign32, RegIm12, RegIm16, RegIm24, RegIm32.
|
||||
type Arg interface {
|
||||
IsArg()
|
||||
String(pc uint64) string
|
||||
}
|
||||
|
||||
// An Args holds the instruction arguments.
|
||||
// If an instruction has fewer than 6 arguments,
|
||||
// the final elements in the array are nil.
|
||||
type Args [8]Arg
|
||||
|
||||
// Base represents an 4-bit Base Register field
|
||||
type Base uint8
|
||||
|
||||
const (
|
||||
B0 Base = iota
|
||||
B1
|
||||
B2
|
||||
B3
|
||||
B4
|
||||
B5
|
||||
B6
|
||||
B7
|
||||
B8
|
||||
B9
|
||||
B10
|
||||
B11
|
||||
B12
|
||||
B13
|
||||
B14
|
||||
B15
|
||||
)
|
||||
|
||||
func (Base) IsArg() {}
|
||||
func (r Base) String(pc uint64) string {
|
||||
switch {
|
||||
case B1 <= r && r <= B15:
|
||||
s := "%"
|
||||
return fmt.Sprintf("%sr%d)", s, int(r-B0))
|
||||
case B0 == r:
|
||||
return fmt.Sprintf("")
|
||||
default:
|
||||
return fmt.Sprintf("Base(%d)", int(r))
|
||||
}
|
||||
}
|
||||
|
||||
// Index represents an 4-bit Index Register field
|
||||
type Index uint8
|
||||
|
||||
const (
|
||||
X0 Index = iota
|
||||
X1
|
||||
X2
|
||||
X3
|
||||
X4
|
||||
X5
|
||||
X6
|
||||
X7
|
||||
X8
|
||||
X9
|
||||
X10
|
||||
X11
|
||||
X12
|
||||
X13
|
||||
X14
|
||||
X15
|
||||
)
|
||||
|
||||
func (Index) IsArg() {}
|
||||
func (r Index) String(pc uint64) string {
|
||||
switch {
|
||||
case X1 <= r && r <= X15:
|
||||
s := "%"
|
||||
return fmt.Sprintf("%sr%d,", s, int(r-X0))
|
||||
case X0 == r:
|
||||
return fmt.Sprintf("")
|
||||
default:
|
||||
return fmt.Sprintf("Base(%d)", int(r))
|
||||
}
|
||||
}
|
||||
|
||||
// Disp20 represents an 20-bit Unsigned Displacement
|
||||
type Disp20 uint32
|
||||
|
||||
func (Disp20) IsArg() {}
|
||||
func (r Disp20) String(pc uint64) string {
|
||||
if (r>>19)&0x01 == 1 {
|
||||
return fmt.Sprintf("%d(", int32(r|0xfff<<20))
|
||||
} else {
|
||||
return fmt.Sprintf("%d(", int32(r))
|
||||
}
|
||||
}
|
||||
|
||||
// Disp12 represents an 12-bit Unsigned Displacement
|
||||
type Disp12 uint16
|
||||
|
||||
func (Disp12) IsArg() {}
|
||||
func (r Disp12) String(pc uint64) string {
|
||||
return fmt.Sprintf("%d(", r)
|
||||
}
|
||||
|
||||
// RegIm12 represents an 12-bit Register immediate number.
|
||||
type RegIm12 uint16
|
||||
|
||||
func (RegIm12) IsArg() {}
|
||||
func (r RegIm12) String(pc uint64) string {
|
||||
if (r>>11)&0x01 == 1 {
|
||||
return fmt.Sprintf("%#x", pc+(2*uint64(int16(r|0xf<<12))))
|
||||
} else {
|
||||
return fmt.Sprintf("%#x", pc+(2*uint64(int16(r))))
|
||||
}
|
||||
}
|
||||
|
||||
// RegIm16 represents an 16-bit Register immediate number.
|
||||
type RegIm16 uint16
|
||||
|
||||
func (RegIm16) IsArg() {}
|
||||
func (r RegIm16) String(pc uint64) string {
|
||||
return fmt.Sprintf("%#x", pc+(2*uint64(int16(r))))
|
||||
}
|
||||
|
||||
// RegIm24 represents an 24-bit Register immediate number.
|
||||
type RegIm24 uint32
|
||||
|
||||
func (RegIm24) IsArg() {}
|
||||
func (r RegIm24) String(pc uint64) string {
|
||||
if (r>>23)&0x01 == 1 {
|
||||
return fmt.Sprintf("%#x", pc+(2*uint64(int32(r|0xff<<24))))
|
||||
} else {
|
||||
return fmt.Sprintf("%#x", pc+(2*uint64(int32(r))))
|
||||
}
|
||||
}
|
||||
|
||||
// RegIm32 represents an 32-bit Register immediate number.
|
||||
type RegIm32 uint32
|
||||
|
||||
func (RegIm32) IsArg() {}
|
||||
func (r RegIm32) String(pc uint64) string {
|
||||
return fmt.Sprintf("%#x", pc+(2*uint64(int32(r))))
|
||||
}
|
||||
|
||||
// A Reg is a single register. The zero value means R0, not the absence of a register.
|
||||
// It also includes special registers.
|
||||
type Reg uint16
|
||||
|
||||
const (
|
||||
R0 Reg = iota
|
||||
R1
|
||||
R2
|
||||
R3
|
||||
R4
|
||||
R5
|
||||
R6
|
||||
R7
|
||||
R8
|
||||
R9
|
||||
R10
|
||||
R11
|
||||
R12
|
||||
R13
|
||||
R14
|
||||
R15
|
||||
F0
|
||||
F1
|
||||
F2
|
||||
F3
|
||||
F4
|
||||
F5
|
||||
F6
|
||||
F7
|
||||
F8
|
||||
F9
|
||||
F10
|
||||
F11
|
||||
F12
|
||||
F13
|
||||
F14
|
||||
F15
|
||||
A0
|
||||
A1
|
||||
A2
|
||||
A3
|
||||
A4
|
||||
A5
|
||||
A6
|
||||
A7
|
||||
A8
|
||||
A9
|
||||
A10
|
||||
A11
|
||||
A12
|
||||
A13
|
||||
A14
|
||||
A15
|
||||
C0
|
||||
C1
|
||||
C2
|
||||
C3
|
||||
C4
|
||||
C5
|
||||
C6
|
||||
C7
|
||||
C8
|
||||
C9
|
||||
C10
|
||||
C11
|
||||
C12
|
||||
C13
|
||||
C14
|
||||
C15
|
||||
)
|
||||
|
||||
func (Reg) IsArg() {}
|
||||
func (r Reg) String(pc uint64) string {
|
||||
s := "%"
|
||||
switch {
|
||||
case R0 <= r && r <= R15:
|
||||
return fmt.Sprintf("%sr%d", s, int(r-R0))
|
||||
case F0 <= r && r <= F15:
|
||||
return fmt.Sprintf("%sf%d", s, int(r-F0))
|
||||
case A0 <= r && r <= A15:
|
||||
return fmt.Sprintf("%sa%d", s, int(r-A0))
|
||||
case C0 <= r && r <= C15:
|
||||
return fmt.Sprintf("%sc%d", s, int(r-C0))
|
||||
default:
|
||||
return fmt.Sprintf("Reg(%d)", int(r))
|
||||
}
|
||||
}
|
||||
|
||||
// VReg is a vector register. The zero value means V0, not the absence of a register.
|
||||
|
||||
type VReg uint8
|
||||
|
||||
const (
|
||||
V0 VReg = iota
|
||||
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 (VReg) IsArg() {}
|
||||
func (r VReg) String(pc uint64) string {
|
||||
s := "%"
|
||||
if V0 <= r && r <= V31 {
|
||||
return fmt.Sprintf("%sv%d", s, int(r-V0))
|
||||
} else {
|
||||
return fmt.Sprintf("VReg(%d)", int(r))
|
||||
}
|
||||
}
|
||||
|
||||
// Imm represents an immediate number.
|
||||
type Imm uint32
|
||||
|
||||
func (Imm) IsArg() {}
|
||||
func (i Imm) String(pc uint64) string {
|
||||
return fmt.Sprintf("%d", uint32(i))
|
||||
}
|
||||
|
||||
// Sign8 represents an 8-bit signed immediate number.
|
||||
type Sign8 int8
|
||||
|
||||
func (Sign8) IsArg() {}
|
||||
func (i Sign8) String(pc uint64) string {
|
||||
return fmt.Sprintf("%d", i)
|
||||
}
|
||||
|
||||
// Sign16 represents an 16-bit signed immediate number.
|
||||
type Sign16 int16
|
||||
|
||||
func (Sign16) IsArg() {}
|
||||
func (i Sign16) String(pc uint64) string {
|
||||
return fmt.Sprintf("%d", i)
|
||||
}
|
||||
|
||||
// Sign32 represents an 32-bit signed immediate number.
|
||||
type Sign32 int32
|
||||
|
||||
func (Sign32) IsArg() {}
|
||||
func (i Sign32) String(pc uint64) string {
|
||||
return fmt.Sprintf("%d", i)
|
||||
}
|
||||
|
||||
// Mask represents an 4-bit mask value
|
||||
type Mask uint8
|
||||
|
||||
func (Mask) IsArg() {}
|
||||
func (i Mask) String(pc uint64) string {
|
||||
return fmt.Sprintf("%d", i)
|
||||
}
|
||||
|
||||
// Len represents an 8-bit type holds 4/8-bit Len argument
|
||||
type Len uint8
|
||||
|
||||
func (Len) IsArg() {}
|
||||
func (i Len) String(pc uint64) string {
|
||||
return fmt.Sprintf("%d,", uint16(i)+1)
|
||||
}
|
5046
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/tables.go
generated
vendored
Normal file
5046
src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/tables.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
src/cmd/vendor/modules.txt
vendored
3
src/cmd/vendor/modules.txt
vendored
@ -16,11 +16,12 @@ github.com/google/pprof/third_party/svgpan
|
||||
# github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465
|
||||
## explicit; go 1.13
|
||||
github.com/ianlancetaylor/demangle
|
||||
# golang.org/x/arch v0.8.1-0.20240716161256-b863392466ea
|
||||
# golang.org/x/arch v0.9.1-0.20240807172201-9d90945922a7
|
||||
## explicit; go 1.18
|
||||
golang.org/x/arch/arm/armasm
|
||||
golang.org/x/arch/arm64/arm64asm
|
||||
golang.org/x/arch/ppc64/ppc64asm
|
||||
golang.org/x/arch/s390x/s390xasm
|
||||
golang.org/x/arch/x86/x86asm
|
||||
# golang.org/x/build v0.0.0-20240722200705-b9910f320300
|
||||
## explicit; go 1.21
|
||||
|
Loading…
Reference in New Issue
Block a user