Skip to content
Snippets Groups Projects
Commit 0d560583 authored by Srinivas Pokala's avatar Srinivas Pokala Committed by Gopher Robot
Browse files

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: default avatarCherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: default avatarVishwanatha 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: default avatarDmitri Shuralyov <dmitshur@google.com>
Reviewed-by: default avatarBill O'Farrell <billotosyr@gmail.com>
parent a96e7362
No related branches found
No related tags found
No related merge requests found
...@@ -4,7 +4,7 @@ go 1.24 ...@@ -4,7 +4,7 @@ go 1.24
require ( require (
github.com/google/pprof v0.0.0-20240722153945-304e4f0156b8 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/build v0.0.0-20240722200705-b9910f320300
golang.org/x/mod v0.20.0 golang.org/x/mod v0.20.0
golang.org/x/sync v0.8.0 golang.org/x/sync v0.8.0
......
...@@ -6,8 +6,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 h1:KwWnWVW ...@@ -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/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 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/arch v0.8.1-0.20240716161256-b863392466ea h1:+dKVGZM+cuxx3fooVKLDxZIPzKR1HYO1Xkd12Je4Z9k= golang.org/x/arch v0.9.1-0.20240807172201-9d90945922a7 h1:4+03DsxQb03qtr7e32FA8tiq18ytCUClXaXxQBDRGbs=
golang.org/x/arch v0.8.1-0.20240716161256-b863392466ea/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= 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 h1:2Cqg4LnvfD2ZpG8+6KbyYUkweWhNS3SgfcN/eeVseJ0=
golang.org/x/build v0.0.0-20240722200705-b9910f320300/go.mod h1:YsGhg4JUVUWLzdqU2wCrtpRrOveOql6w56FLDHq/CJ4= 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= golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
......
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"golang.org/x/arch/arm/armasm" "golang.org/x/arch/arm/armasm"
"golang.org/x/arch/arm64/arm64asm" "golang.org/x/arch/arm64/arm64asm"
"golang.org/x/arch/ppc64/ppc64asm" "golang.org/x/arch/ppc64/ppc64asm"
"golang.org/x/arch/s390x/s390xasm"
"golang.org/x/arch/x86/x86asm" "golang.org/x/arch/x86/x86asm"
) )
...@@ -383,6 +384,23 @@ func disasm_ppc64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.By ...@@ -383,6 +384,23 @@ func disasm_ppc64(code []byte, pc uint64, lookup lookupFunc, byteOrder binary.By
return text, size 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{ var disasms = map[string]disasmFunc{
"386": disasm_386, "386": disasm_386,
"amd64": disasm_amd64, "amd64": disasm_amd64,
...@@ -390,6 +408,7 @@ var disasms = map[string]disasmFunc{ ...@@ -390,6 +408,7 @@ var disasms = map[string]disasmFunc{
"arm64": disasm_arm64, "arm64": disasm_arm64,
"ppc64": disasm_ppc64, "ppc64": disasm_ppc64,
"ppc64le": disasm_ppc64, "ppc64le": disasm_ppc64,
"s390x": disasm_s390x,
} }
var byteOrders = map[string]binary.ByteOrder{ var byteOrders = map[string]binary.ByteOrder{
......
...@@ -104,6 +104,12 @@ var ppcGnuNeed = []string{ ...@@ -104,6 +104,12 @@ var ppcGnuNeed = []string{
"beq", "beq",
} }
var s390xGnuNeed = []string{
"brasl",
"j",
"clije",
}
func mustHaveDisasm(t *testing.T) { func mustHaveDisasm(t *testing.T) {
switch runtime.GOARCH { switch runtime.GOARCH {
case "loong64": case "loong64":
...@@ -112,8 +118,6 @@ func mustHaveDisasm(t *testing.T) { ...@@ -112,8 +118,6 @@ func mustHaveDisasm(t *testing.T) {
t.Skipf("skipping on %s, issue 12559", runtime.GOARCH) t.Skipf("skipping on %s, issue 12559", runtime.GOARCH)
case "riscv64": case "riscv64":
t.Skipf("skipping on %s, issue 36738", runtime.GOARCH) 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, ...@@ -202,6 +206,8 @@ func testDisasm(t *testing.T, srcfname string, printCode bool, printGnuAsm bool,
need = append(need, armGnuNeed...) need = append(need, armGnuNeed...)
case "ppc64", "ppc64le": case "ppc64", "ppc64le":
need = append(need, ppcGnuNeed...) need = append(need, ppcGnuNeed...)
case "s390x":
need = append(need, s390xGnuNeed...)
} }
} }
args = []string{ args = []string{
......
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
// 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
}
// 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
}
// 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
// Instructions with extended mnemonics fall under various categories.
// To handle each of them in one single function, various different
// structure types are defined as below. Corresponding instruction
// structures are created with the help of these base structures.
// Different instruction types are as below:
// Typ1 - Instructions having different base and extended mnemonic strings.
//
// These instructions have single M-field value and single offset.
type typ1ExtndMnics struct {
BaseOpStr string
Value uint8
Offset uint8
ExtnOpStr string
}
// Typ2 - Instructions having couple of extra strings added to the base mnemonic string,
//
// depending on the condition code evaluation.
// These instructions have single M-field value and single offset.
type typ2ExtndMnics struct {
Value uint8
Offset uint8
ExtnOpStr string
}
// Typ3 - Instructions having couple of extra strings added to the base mnemonic string,
//
// depending on the condition code evaluation.
// These instructions have two M-field values and two offsets.
type typ3ExtndMnics struct {
Value1 uint8
Value2 uint8
Offset1 uint8
Offset2 uint8
ExtnOpStr string
}
// Typ4 - Instructions having different base and extended mnemonic strings.
//
// These instructions have two M-field values and two offsets.
type typ4ExtndMnics struct {
BaseOpStr string
Value1 uint8
Value2 uint8
Offset1 uint8
Offset2 uint8
ExtnOpStr string
}
// Typ5 - Instructions having different base and extended mnemonic strings.
//
// These instructions have three M-field values and three offsets.
type typ5ExtndMnics struct {
BaseOpStr string
Value1 uint8
Value2 uint8
Value3 uint8
Offset1 uint8
Offset2 uint8
Offset3 uint8
ExtnOpStr string
}
// "func Handleextndmnemonic" - This is the function where the extended mnemonic logic
// is implemented. This function defines various structures to keep a list of base
// instructions and their extended mnemonic strings. These structure will also have
// M-field values and offset values defined, based on their type.
// HandleExtndMnemonic takes "inst" structure as the input variable.
// Inst structure will have all the details related to an instruction. Based on the
// opcode base string, a switch-case statement is executed. In that, based on the
// M-field value and the offset value of that particular M-field, extended mnemonic
// string is either searched or constructed by adding couple of extra strings to the base
// opcode string from one of the structure defined below.
func HandleExtndMnemonic(inst *Inst) string {
brnchInstrExtndMnics := []typ1ExtndMnics{
//BIC - BRANCH INDIRECT ON CONDITION instruction
typ1ExtndMnics{BaseOpStr: "bic", Value: 1, Offset: 0, ExtnOpStr: "bio"},
typ1ExtndMnics{BaseOpStr: "bic", Value: 2, Offset: 0, ExtnOpStr: "bih"},
typ1ExtndMnics{BaseOpStr: "bic", Value: 4, Offset: 0, ExtnOpStr: "bil"},
typ1ExtndMnics{BaseOpStr: "bic", Value: 7, Offset: 0, ExtnOpStr: "bine"},
typ1ExtndMnics{BaseOpStr: "bic", Value: 8, Offset: 0, ExtnOpStr: "bie"},
typ1ExtndMnics{BaseOpStr: "bic", Value: 11, Offset: 0, ExtnOpStr: "binl"},
typ1ExtndMnics{BaseOpStr: "bic", Value: 13, Offset: 0, ExtnOpStr: "binh"},
typ1ExtndMnics{BaseOpStr: "bic", Value: 14, Offset: 0, ExtnOpStr: "bino"},
typ1ExtndMnics{BaseOpStr: "bic", Value: 15, Offset: 0, ExtnOpStr: "bi"},
//BCR - BRANCH ON CONDITION instruction
typ1ExtndMnics{BaseOpStr: "bcr", Value: 0, Offset: 0, ExtnOpStr: "nopr"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 1, Offset: 0, ExtnOpStr: "bor"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 2, Offset: 0, ExtnOpStr: "bhr"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 4, Offset: 0, ExtnOpStr: "blr"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 7, Offset: 0, ExtnOpStr: "bner"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 8, Offset: 0, ExtnOpStr: "ber"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 11, Offset: 0, ExtnOpStr: "bnlr"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 13, Offset: 0, ExtnOpStr: "bnhr"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 14, Offset: 0, ExtnOpStr: "bnor"},
typ1ExtndMnics{BaseOpStr: "bcr", Value: 15, Offset: 0, ExtnOpStr: "br"},
//BC - BRANCH ON CONDITION instruction
typ1ExtndMnics{BaseOpStr: "bc", Value: 0, Offset: 0, ExtnOpStr: "nopr"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 1, Offset: 0, ExtnOpStr: "bo"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 2, Offset: 0, ExtnOpStr: "bh"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 4, Offset: 0, ExtnOpStr: "bl"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 7, Offset: 0, ExtnOpStr: "bne"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 8, Offset: 0, ExtnOpStr: "be"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 11, Offset: 0, ExtnOpStr: "bnl"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 13, Offset: 0, ExtnOpStr: "bnh"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 14, Offset: 0, ExtnOpStr: "bno"},
typ1ExtndMnics{BaseOpStr: "bc", Value: 15, Offset: 0, ExtnOpStr: "b"},
//BRC - BRANCH RELATIVE ON CONDITION instruction
typ1ExtndMnics{BaseOpStr: "brc", Value: 0, Offset: 0, ExtnOpStr: "jnop"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 1, Offset: 0, ExtnOpStr: "jo"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 2, Offset: 0, ExtnOpStr: "jh"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 4, Offset: 0, ExtnOpStr: "jl"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 7, Offset: 0, ExtnOpStr: "jne"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 8, Offset: 0, ExtnOpStr: "je"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 11, Offset: 0, ExtnOpStr: "jnl"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 13, Offset: 0, ExtnOpStr: "jnh"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 14, Offset: 0, ExtnOpStr: "jno"},
typ1ExtndMnics{BaseOpStr: "brc", Value: 15, Offset: 0, ExtnOpStr: "j"},
//BRCL - BRANCH RELATIVE ON CONDITION LONG instruction
typ1ExtndMnics{BaseOpStr: "brcl", Value: 0, Offset: 0, ExtnOpStr: "jgnop"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 1, Offset: 0, ExtnOpStr: "jgo"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 2, Offset: 0, ExtnOpStr: "jgh"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 4, Offset: 0, ExtnOpStr: "jgl"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 7, Offset: 0, ExtnOpStr: "jgne"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 8, Offset: 0, ExtnOpStr: "jge"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 11, Offset: 0, ExtnOpStr: "jgnl"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 13, Offset: 0, ExtnOpStr: "jgnh"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 14, Offset: 0, ExtnOpStr: "jgno"},
typ1ExtndMnics{BaseOpStr: "brcl", Value: 15, Offset: 0, ExtnOpStr: "jg"},
}
//Compare instructions
cmpInstrExtndMnics := []typ2ExtndMnics{
typ2ExtndMnics{Value: 2, Offset: 2, ExtnOpStr: "h"},
typ2ExtndMnics{Value: 4, Offset: 2, ExtnOpStr: "l"},
typ2ExtndMnics{Value: 6, Offset: 2, ExtnOpStr: "ne"},
typ2ExtndMnics{Value: 8, Offset: 2, ExtnOpStr: "e"},
typ2ExtndMnics{Value: 10, Offset: 2, ExtnOpStr: "nl"},
typ2ExtndMnics{Value: 12, Offset: 2, ExtnOpStr: "nh"},
}
//Load and Store instructions
ldSt_InstrExtndMnics := []typ2ExtndMnics{
typ2ExtndMnics{Value: 1, Offset: 2, ExtnOpStr: "o"},
typ2ExtndMnics{Value: 2, Offset: 2, ExtnOpStr: "h"},
typ2ExtndMnics{Value: 3, Offset: 2, ExtnOpStr: "nle"},
typ2ExtndMnics{Value: 4, Offset: 2, ExtnOpStr: "l"},
typ2ExtndMnics{Value: 5, Offset: 2, ExtnOpStr: "nhe"},
typ2ExtndMnics{Value: 6, Offset: 2, ExtnOpStr: "lh"},
typ2ExtndMnics{Value: 7, Offset: 2, ExtnOpStr: "ne"},
typ2ExtndMnics{Value: 8, Offset: 2, ExtnOpStr: "e"},
typ2ExtndMnics{Value: 9, Offset: 2, ExtnOpStr: "nlh"},
typ2ExtndMnics{Value: 10, Offset: 2, ExtnOpStr: "he"},
typ2ExtndMnics{Value: 11, Offset: 2, ExtnOpStr: "nl"},
typ2ExtndMnics{Value: 12, Offset: 2, ExtnOpStr: "le"},
typ2ExtndMnics{Value: 13, Offset: 2, ExtnOpStr: "nh"},
typ2ExtndMnics{Value: 14, Offset: 2, ExtnOpStr: "no"},
}
vecInstrExtndMnics := []typ2ExtndMnics{
typ2ExtndMnics{Value: 0, Offset: 3, ExtnOpStr: "b"},
typ2ExtndMnics{Value: 1, Offset: 3, ExtnOpStr: "h"},
typ2ExtndMnics{Value: 2, Offset: 3, ExtnOpStr: "f"},
typ2ExtndMnics{Value: 3, Offset: 3, ExtnOpStr: "g"},
typ2ExtndMnics{Value: 4, Offset: 3, ExtnOpStr: "q"},
typ2ExtndMnics{Value: 6, Offset: 3, ExtnOpStr: "lf"},
}
//VCEQ, VCH, VCHL
vec2InstrExtndMnics := []typ3ExtndMnics{
typ3ExtndMnics{Value1: 0, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "b"},
typ3ExtndMnics{Value1: 1, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "h"},
typ3ExtndMnics{Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "f"},
typ3ExtndMnics{Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "g"},
typ3ExtndMnics{Value1: 0, Value2: 1, Offset1: 3, Offset2: 4, ExtnOpStr: "bs"},
typ3ExtndMnics{Value1: 1, Value2: 1, Offset1: 3, Offset2: 4, ExtnOpStr: "hs"},
typ3ExtndMnics{Value1: 2, Value2: 1, Offset1: 3, Offset2: 4, ExtnOpStr: "fs"},
typ3ExtndMnics{Value1: 3, Value2: 1, Offset1: 3, Offset2: 4, ExtnOpStr: "gs"},
}
//VFAE, VFEE, VFENE
vec21InstrExtndMnics := []typ3ExtndMnics{
typ3ExtndMnics{Value1: 0, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "b"},
typ3ExtndMnics{Value1: 1, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "h"},
typ3ExtndMnics{Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "f"},
typ3ExtndMnics{Value1: 0, Value2: 1, Offset1: 3, Offset2: 4, ExtnOpStr: "bs"},
typ3ExtndMnics{Value1: 1, Value2: 1, Offset1: 3, Offset2: 4, ExtnOpStr: "hs"},
typ3ExtndMnics{Value1: 2, Value2: 1, Offset1: 3, Offset2: 4, ExtnOpStr: "fs"},
typ3ExtndMnics{Value1: 0, Value2: 2, Offset1: 3, Offset2: 4, ExtnOpStr: "zb"},
typ3ExtndMnics{Value1: 1, Value2: 2, Offset1: 3, Offset2: 4, ExtnOpStr: "zh"},
typ3ExtndMnics{Value1: 2, Value2: 2, Offset1: 3, Offset2: 4, ExtnOpStr: "zf"},
typ3ExtndMnics{Value1: 0, Value2: 3, Offset1: 3, Offset2: 4, ExtnOpStr: "zbs"},
typ3ExtndMnics{Value1: 1, Value2: 3, Offset1: 3, Offset2: 4, ExtnOpStr: "zhs"},
typ3ExtndMnics{Value1: 2, Value2: 3, Offset1: 3, Offset2: 4, ExtnOpStr: "zfs"},
}
vec3InstrExtndMnics := []typ3ExtndMnics{
typ3ExtndMnics{Value1: 2, Value2: 0, Offset1: 2, Offset2: 3, ExtnOpStr: "sb"},
typ3ExtndMnics{Value1: 3, Value2: 0, Offset1: 2, Offset2: 3, ExtnOpStr: "db"},
typ3ExtndMnics{Value1: 4, Value2: 0, Offset1: 2, Offset2: 3, ExtnOpStr: "xb"},
}
vec4InstrExtndMnics := []typ4ExtndMnics{
// VFA - VECTOR FP ADD
typ4ExtndMnics{BaseOpStr: "vfa", Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfasb"},
typ4ExtndMnics{BaseOpStr: "vfa", Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfadb"},
typ4ExtndMnics{BaseOpStr: "vfa", Value1: 2, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfasb"},
typ4ExtndMnics{BaseOpStr: "vfa", Value1: 3, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfadb"},
typ4ExtndMnics{BaseOpStr: "vfa", Value1: 4, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfaxb"},
// VFD - VECTOR FP DIVIDE
typ4ExtndMnics{BaseOpStr: "vfd", Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfdsb"},
typ4ExtndMnics{BaseOpStr: "vfd", Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfddb"},
typ4ExtndMnics{BaseOpStr: "vfd", Value1: 2, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfdsb"},
typ4ExtndMnics{BaseOpStr: "vfd", Value1: 3, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfddb"},
typ4ExtndMnics{BaseOpStr: "vfd", Value1: 4, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfdxb"},
// VFLL - VECTOR FP LOAD LENGTHENED
typ4ExtndMnics{BaseOpStr: "vfll", Value1: 2, Value2: 0, Offset1: 2, Offset2: 3, ExtnOpStr: "vflfs"},
typ4ExtndMnics{BaseOpStr: "vfll", Value1: 2, Value2: 8, Offset1: 2, Offset2: 3, ExtnOpStr: "wflls"},
typ4ExtndMnics{BaseOpStr: "vfll", Value1: 3, Value2: 8, Offset1: 2, Offset2: 3, ExtnOpStr: "wflld"},
// VFMAX - VECTOR FP MAXIMUM
typ4ExtndMnics{BaseOpStr: "vfmax", Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfmaxsb"},
typ4ExtndMnics{BaseOpStr: "vfmax", Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfmaxdb"},
typ4ExtndMnics{BaseOpStr: "vfmax", Value1: 2, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfmaxsb"},
typ4ExtndMnics{BaseOpStr: "vfmax", Value1: 3, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfmaxdb"},
typ4ExtndMnics{BaseOpStr: "vfmax", Value1: 4, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfmaxxb"},
// VFMIN - VECTOR FP MINIMUM
typ4ExtndMnics{BaseOpStr: "vfmin", Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfminsb"},
typ4ExtndMnics{BaseOpStr: "vfmin", Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfmindb"},
typ4ExtndMnics{BaseOpStr: "vfmin", Value1: 2, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfminsb"},
typ4ExtndMnics{BaseOpStr: "vfmin", Value1: 3, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfmindb"},
typ4ExtndMnics{BaseOpStr: "vfmin", Value1: 4, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfminxb"},
// VFM - VECTOR FP MULTIPLY
typ4ExtndMnics{BaseOpStr: "vfm", Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfmsb"},
typ4ExtndMnics{BaseOpStr: "vfm", Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfmdb"},
typ4ExtndMnics{BaseOpStr: "vfm", Value1: 2, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfmsb"},
typ4ExtndMnics{BaseOpStr: "vfm", Value1: 3, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfmdb"},
typ4ExtndMnics{BaseOpStr: "vfm", Value1: 4, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfmxb"},
// VFSQ - VECTOR FP SQUARE ROOT
typ4ExtndMnics{BaseOpStr: "vfsq", Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfsqsb"},
typ4ExtndMnics{BaseOpStr: "vfsq", Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfsqdb"},
typ4ExtndMnics{BaseOpStr: "vfsq", Value1: 2, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfsqsb"},
typ4ExtndMnics{BaseOpStr: "vfsq", Value1: 3, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfsqdb"},
typ4ExtndMnics{BaseOpStr: "vfsq", Value1: 4, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfsqxb"},
// VFS - VECTOR FP SUBTRACT
typ4ExtndMnics{BaseOpStr: "vfs", Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfssb"},
typ4ExtndMnics{BaseOpStr: "vfs", Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vfsdb"},
typ4ExtndMnics{BaseOpStr: "vfs", Value1: 2, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfssb"},
typ4ExtndMnics{BaseOpStr: "vfs", Value1: 3, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfsdb"},
typ4ExtndMnics{BaseOpStr: "vfs", Value1: 4, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wfsxb"},
// VFTCI - VECTOR FP TEST DATA CLASS IMMEDIATE
typ4ExtndMnics{BaseOpStr: "vftci", Value1: 2, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vftcisb"},
typ4ExtndMnics{BaseOpStr: "vftci", Value1: 3, Value2: 0, Offset1: 3, Offset2: 4, ExtnOpStr: "vftcidb"},
typ4ExtndMnics{BaseOpStr: "vftci", Value1: 2, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wftcisb"},
typ4ExtndMnics{BaseOpStr: "vftci", Value1: 3, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wftcidb"},
typ4ExtndMnics{BaseOpStr: "vftci", Value1: 4, Value2: 8, Offset1: 3, Offset2: 4, ExtnOpStr: "wftcixb"},
}
vec6InstrExtndMnics := []typ5ExtndMnics{
// VFCE - VECTOR FP COMPARE EQUAL
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 2, Value2: 0, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfcesb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 2, Value2: 0, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfcesbs"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 3, Value2: 0, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfcedb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 2, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfcesb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 2, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfcesbs"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 3, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfcedb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 3, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfcedbs"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 4, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfcexb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 4, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfcexbs"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 2, Value2: 4, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkesb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 2, Value2: 4, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkesbs"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 3, Value2: 4, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkedb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 3, Value2: 4, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkedbs"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 2, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkesb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 2, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkesbs"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 3, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkedb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 3, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkedbs"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 4, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkexb"},
typ5ExtndMnics{BaseOpStr: "vfce", Value1: 4, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkexbs"},
// VFCH - VECTOR FP COMPARE HIGH
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 2, Value2: 0, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfchsb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 2, Value2: 0, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfchsbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 3, Value2: 0, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfchdb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 3, Value2: 0, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfchdbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 2, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchsb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 2, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchsbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 3, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchdb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 3, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchdbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 4, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchxb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 4, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchxbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 2, Value2: 4, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkhsb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 2, Value2: 4, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkhsbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 3, Value2: 4, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkhdb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 3, Value2: 4, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkhdbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 2, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhsb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 2, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhsbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 3, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhdb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 3, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhdbs"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 4, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhxb"},
typ5ExtndMnics{BaseOpStr: "vfch", Value1: 4, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhxbs"},
// VFCHE - VECTOR FP COMPARE HIGH OR EQUAL
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 2, Value2: 0, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfchesb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 2, Value2: 0, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfchesbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 3, Value2: 0, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfchedb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 3, Value2: 0, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfchedbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 2, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchesb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 2, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchesbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 3, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchedb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 3, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchedbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 4, Value2: 8, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchexb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 4, Value2: 8, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfchexbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 2, Value2: 4, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkhesb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 2, Value2: 4, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkhesbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 3, Value2: 4, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkhedb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 3, Value2: 4, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "vfkhedbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 2, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhesb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 2, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhesbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 3, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhedb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 3, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhedbs"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 4, Value2: 12, Value3: 0, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhexb"},
typ5ExtndMnics{BaseOpStr: "vfche", Value1: 4, Value2: 12, Value3: 1, Offset1: 3, Offset2: 4, Offset3: 5, ExtnOpStr: "wfkhexbs"},
// VFPSO - VECTOR FP PERFORM SIGN OPERATION
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 2, Value2: 0, Value3: 0, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "vflcsb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 2, Value2: 8, Value3: 0, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflcsb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 2, Value2: 0, Value3: 1, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "vflnsb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 2, Value2: 8, Value3: 1, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflnsb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 2, Value2: 0, Value3: 2, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "vflpsb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 2, Value2: 8, Value3: 2, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflpsb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 3, Value2: 0, Value3: 0, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "vflcdb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 3, Value2: 8, Value3: 0, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflcdb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 3, Value2: 0, Value3: 1, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "vflndb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 3, Value2: 8, Value3: 1, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflndb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 3, Value2: 0, Value3: 2, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "vflpdb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 3, Value2: 8, Value3: 2, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflpdb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 4, Value2: 8, Value3: 0, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflcxb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 4, Value2: 8, Value3: 1, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflnxb"},
typ5ExtndMnics{BaseOpStr: "vfpso", Value1: 4, Value2: 8, Value3: 2, Offset1: 2, Offset2: 3, Offset3: 4, ExtnOpStr: "wflpxb"},
}
vec7InstrExtndMnics := []typ4ExtndMnics{
// VFMA - VECTOR FP MULTIPLY AND ADD
typ4ExtndMnics{BaseOpStr: "vfma", Value1: 0, Value2: 2, Offset1: 4, Offset2: 5, ExtnOpStr: "vfmasb"},
typ4ExtndMnics{BaseOpStr: "vfma", Value1: 0, Value2: 3, Offset1: 4, Offset2: 5, ExtnOpStr: "vfmadb"},
typ4ExtndMnics{BaseOpStr: "vfma", Value1: 8, Value2: 2, Offset1: 4, Offset2: 5, ExtnOpStr: "wfmasb"},
typ4ExtndMnics{BaseOpStr: "vfma", Value1: 8, Value2: 3, Offset1: 4, Offset2: 5, ExtnOpStr: "wfmadb"},
typ4ExtndMnics{BaseOpStr: "vfma", Value1: 8, Value2: 4, Offset1: 4, Offset2: 5, ExtnOpStr: "wfmaxb"},
// VFMS - VECTOR FP MULTIPLY AND SUBTRACT
typ4ExtndMnics{BaseOpStr: "vfms", Value1: 0, Value2: 2, Offset1: 4, Offset2: 5, ExtnOpStr: "vfmssb"},
typ4ExtndMnics{BaseOpStr: "vfms", Value1: 0, Value2: 3, Offset1: 4, Offset2: 5, ExtnOpStr: "vfmsdb"},
typ4ExtndMnics{BaseOpStr: "vfms", Value1: 8, Value2: 2, Offset1: 4, Offset2: 5, ExtnOpStr: "wfmssb"},
typ4ExtndMnics{BaseOpStr: "vfms", Value1: 8, Value2: 3, Offset1: 4, Offset2: 5, ExtnOpStr: "wfmsdb"},
typ4ExtndMnics{BaseOpStr: "vfms", Value1: 8, Value2: 4, Offset1: 4, Offset2: 5, ExtnOpStr: "wfmsxb"},
// VFNMA - VECTOR FP NEGATIVE MULTIPLY AND ADD
typ4ExtndMnics{BaseOpStr: "vfnma", Value1: 0, Value2: 2, Offset1: 4, Offset2: 5, ExtnOpStr: "vfnmasb"},
typ4ExtndMnics{BaseOpStr: "vfnma", Value1: 0, Value2: 3, Offset1: 4, Offset2: 5, ExtnOpStr: "vfnmadb"},
typ4ExtndMnics{BaseOpStr: "vfnma", Value1: 8, Value2: 2, Offset1: 4, Offset2: 5, ExtnOpStr: "wfnmasb"},
typ4ExtndMnics{BaseOpStr: "vfnma", Value1: 8, Value2: 3, Offset1: 4, Offset2: 5, ExtnOpStr: "wfnmadb"},
typ4ExtndMnics{BaseOpStr: "vfnma", Value1: 8, Value2: 4, Offset1: 4, Offset2: 5, ExtnOpStr: "wfnmaxb"},
// VFNMS - VECTOR FP NEGATIVE MULTIPLY AND SUBTRACT
typ4ExtndMnics{BaseOpStr: "vfnms", Value1: 0, Value2: 2, Offset1: 4, Offset2: 5, ExtnOpStr: "vfnmssb"},
typ4ExtndMnics{BaseOpStr: "vfnms", Value1: 0, Value2: 3, Offset1: 4, Offset2: 5, ExtnOpStr: "vfnmsdb"},
typ4ExtndMnics{BaseOpStr: "vfnms", Value1: 8, Value2: 2, Offset1: 4, Offset2: 5, ExtnOpStr: "wfnmssb"},
typ4ExtndMnics{BaseOpStr: "vfnms", Value1: 8, Value2: 3, Offset1: 4, Offset2: 5, ExtnOpStr: "wfnmsdb"},
typ4ExtndMnics{BaseOpStr: "vfnms", Value1: 8, Value2: 4, Offset1: 4, Offset2: 5, ExtnOpStr: "wfnmsxb"},
}
opString := inst.Op.String()
newOpStr := opString
if inst.Enc == 0 {
return ".long 0x0"
} else if inst.Op == 0 {
return "error: unknown instruction"
}
switch opString {
// Case to handle all "branch" instructions with one M-field operand
case "bic", "bcr", "bc", "brc", "brcl":
for i := 0; i < len(brnchInstrExtndMnics); i++ {
if opString == brnchInstrExtndMnics[i].BaseOpStr &&
uint8(inst.Args[brnchInstrExtndMnics[i].Offset].(Mask)) == brnchInstrExtndMnics[i].Value {
newOpStr = brnchInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(brnchInstrExtndMnics[i].Offset))
break
}
}
// Case to handle all "compare" instructions with one M-field operand
case "crb", "cgrb", "crj", "cgrj", "crt", "cgrt", "cib", "cgib", "cij", "cgij", "cit", "cgit", "clrb", "clgrb",
"clrj", "clgrj", "clrt", "clgrt", "clt", "clgt", "clib", "clgib", "clij", "clgij", "clfit", "clgit":
for i := 0; i < len(cmpInstrExtndMnics); i++ {
//For CLT and CLGT instructions, M-value is the second operand.
//Hence, set the offset to "1"
if opString == "clt" || opString == "clgt" {
cmpInstrExtndMnics[i].Offset = 1
}
if uint8(inst.Args[cmpInstrExtndMnics[i].Offset].(Mask)) == cmpInstrExtndMnics[i].Value {
newOpStr = opString + cmpInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(cmpInstrExtndMnics[i].Offset))
break
}
}
// Case to handle all "load" and "store" instructions with one M-field operand
case "lochhi", "lochi", "locghi", "locfhr", "locfh", "locr", "locgr", "loc",
"locg", "selr", "selgr", "selfhr", "stocfh", "stoc", "stocg":
for i := 0; i < len(ldSt_InstrExtndMnics); i++ {
//For LOCFH, LOC, LOCG, SELR, SELGR, SELFHR, STOCFH, STOC, STOCG instructions,
//M-value is the forth operand. Hence, set the offset to "3"
if opString == "locfh" || opString == "loc" || opString == "locg" || opString == "selr" || opString == "selgr" ||
opString == "selfhr" || opString == "stocfh" || opString == "stoc" || opString == "stocg" {
ldSt_InstrExtndMnics[i].Offset = 3
}
if uint8(inst.Args[ldSt_InstrExtndMnics[i].Offset].(Mask)) == ldSt_InstrExtndMnics[i].Value {
newOpStr = opString + ldSt_InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(ldSt_InstrExtndMnics[i].Offset))
break
}
}
// Case to handle all "vector" instructions with one M-field operand
case "vavg", "vavgl", "verllv", "veslv", "vesrav", "vesrlv", "vgfm", "vgm", "vmx", "vmxl", "vmrh", "vmrl", "vmn", "vmnl", "vrep",
"vclz", "vctz", "vec", "vecl", "vlc", "vlp", "vpopct", "vrepi", "verim", "verll", "vesl", "vesra", "vesrl", "vgfma", "vlrep",
"vlgv", "vlvg", "vlbrrep", "vler", "vlbr", "vstbr", "vster", "vpk", "vme", "vmh", "vmle", "vmlh", "vmlo", "vml", "vmo", "vmae",
"vmale", "vmalo", "vmal", "vmah", "vmalh", "vmao", "vmph", "vmplh", "vupl", "vupll", "vscbi", "vs", "vsum", "vsumg", "vsumq",
"va", "vacc":
switch opString {
case "vavg", "vavgl", "verllv", "veslv", "vesrav", "vesrlv", "vgfm", "vgm", "vmx", "vmxl", "vmrh", "vmrl", "vmn", "vmnl", "vrep":
//M-field is 3rd arg for all these instructions. Hence, set the offset to "2"
for i := 0; i < len(vecInstrExtndMnics)-2; i++ { // 0,1,2,3
if uint8(inst.Args[vecInstrExtndMnics[i].Offset].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset))
break
}
}
case "vclz", "vctz", "vec", "vecl", "vlc", "vlp", "vpopct", "vrepi":
for i := 0; i < len(vecInstrExtndMnics)-2; i++ { //0,1,2,3
if uint8(inst.Args[vecInstrExtndMnics[i].Offset-1].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset-1))
break
}
}
case "verim", "verll", "vesl", "vesra", "vesrl", "vgfma", "vlrep":
for i := 0; i < len(vecInstrExtndMnics)-2; i++ { //0,1,2,3
if uint8(inst.Args[vecInstrExtndMnics[i].Offset+1].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset+1))
break
}
}
case "vlgv", "vlvg":
for i := 0; i < len(vecInstrExtndMnics)-2; i++ {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset+1].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset+1))
break
}
}
case "vlbrrep", "vler", "vster":
for i := 1; i < len(vecInstrExtndMnics)-2; i++ {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset+1].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset+1))
break
}
}
case "vpk":
for i := 1; i < len(vecInstrExtndMnics)-2; i++ {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset))
break
}
}
case "vlbr", "vstbr":
for i := 1; i < len(vecInstrExtndMnics)-1; i++ {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset+1].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset+1))
break
}
}
case "vme", "vmh", "vmle", "vmlh", "vmlo", "vmo":
for i := 0; i < len(vecInstrExtndMnics)-3; i++ { //0,1,2
if uint8(inst.Args[vecInstrExtndMnics[i].Offset].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset))
break
}
}
case "vml":
for i := 0; i < len(vecInstrExtndMnics)-3; i++ { //0,1,2
if uint8(inst.Args[vecInstrExtndMnics[i].Offset].(Mask)) == vecInstrExtndMnics[i].Value {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset].(Mask)) == 1 {
newOpStr = opString + string("hw")
} else {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
}
removeArg(inst, int8(vecInstrExtndMnics[i].Offset))
break
}
}
case "vmae", "vmale", "vmalo", "vmal", "vmah", "vmalh", "vmao":
for i := 0; i < len(vecInstrExtndMnics)-3; i++ { //0,1,2
if uint8(inst.Args[vecInstrExtndMnics[i].Offset+1].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset+1))
break
}
}
case "vmph", "vmplh", "vupl", "vupll": //0,1,2
for i := 0; i < len(vecInstrExtndMnics)-3; i++ {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset-1].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset-1))
break
}
}
case "vscbi", "vs", "va", "vacc": // 0,1,2,3,4
for i := 0; i < len(vecInstrExtndMnics)-1; i++ {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset))
break
}
}
case "vsum", "vsumg":
for i := 1; i < len(vecInstrExtndMnics)-4; i++ {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset))
break
}
}
case "vsumq":
for i := 2; i < len(vecInstrExtndMnics)-2; i++ {
if uint8(inst.Args[vecInstrExtndMnics[i].Offset].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset))
break
}
}
}
case "vllez":
for i := 0; i < len(vecInstrExtndMnics); i++ {
if i == 4 {
continue
}
if uint8(inst.Args[vecInstrExtndMnics[i].Offset+1].(Mask)) == vecInstrExtndMnics[i].Value {
newOpStr = opString + vecInstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vecInstrExtndMnics[i].Offset+1))
break
}
}
case "vgbm":
if uint16(inst.Args[1].(Imm)) == uint16(0) {
newOpStr = "vzeo"
removeArg(inst, int8(1))
} else if uint16(inst.Args[1].(Imm)) == uint16(0xFFFF) {
newOpStr = "vone"
removeArg(inst, int8(1))
}
case "vno":
if uint8(inst.Args[1].(VReg)) == uint8(inst.Args[2].(VReg)) { //Bitwise Not instruction(VNOT) if V2 equal to v3
newOpStr = opString + "t"
removeArg(inst, int8(2))
}
case "vmsl":
if uint8(inst.Args[4].(Mask)) == uint8(3) {
newOpStr = opString + "g"
removeArg(inst, int8(4))
}
case "vflr":
if uint8(inst.Args[2].(Mask)) == uint8(3) && ((inst.Args[3].(Mask)>>3)&0x1 == 0x1) {
inst.Args[3] = (inst.Args[3].(Mask) ^ 0x8)
newOpStr = "wflrd"
removeArg(inst, int8(2))
} else if uint8(inst.Args[2].(Mask)) == uint8(4) && ((inst.Args[3].(Mask)>>3)&0x1 == 0x1) {
inst.Args[3] = (inst.Args[3].(Mask) ^ 0x8)
newOpStr = "wflrx"
removeArg(inst, int8(2))
} else if uint8(inst.Args[2].(Mask)) == uint8(3) {
newOpStr = "vflrd"
removeArg(inst, int8(2))
}
case "vllebrz":
if uint8(inst.Args[4].(Mask)) == uint8(1) {
newOpStr = opString + "h"
removeArg(inst, int8(4))
} else if uint8(inst.Args[4].(Mask)) == uint8(2) {
newOpStr = opString + "f"
removeArg(inst, int8(4))
} else if uint8(inst.Args[4].(Mask)) == uint8(3) {
newOpStr = "ldrv"
removeArg(inst, int8(4))
} else if uint8(inst.Args[4].(Mask)) == uint8(6) {
newOpStr = "lerv"
removeArg(inst, int8(4))
}
case "vschp":
if uint8(inst.Args[3].(Mask)) == uint8(2) {
newOpStr = "vschsp"
removeArg(inst, int8(3))
} else if uint8(inst.Args[3].(Mask)) == uint8(3) {
newOpStr = "vschdp"
removeArg(inst, int8(3))
} else if uint8(inst.Args[3].(Mask)) == uint8(4) {
newOpStr = "vschxp"
removeArg(inst, int8(3))
}
case "vsbcbi", "vsbi":
if uint8(inst.Args[4].(Mask)) == uint8(4) {
newOpStr = opString + vecInstrExtndMnics[4].ExtnOpStr
removeArg(inst, int8(4))
}
case "vac", "vaccc":
if uint8(inst.Args[4].(Mask)) == uint8(4) {
newOpStr = opString + vecInstrExtndMnics[3].ExtnOpStr
removeArg(inst, int8(3))
}
case "vceq", "vch", "vchl":
for i := 0; i < len(vec2InstrExtndMnics)-6; i++ {
if uint8(inst.Args[vec2InstrExtndMnics[i].Offset1].(Mask)) == vec2InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec2InstrExtndMnics[i].Offset2].(Mask)) == vec2InstrExtndMnics[i].Value2 {
newOpStr = opString + vec2InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec2InstrExtndMnics[i].Offset1))
removeArg(inst, int8(vec2InstrExtndMnics[i].Offset2-1))
break
}
}
case "vpks", "vpkls":
for i := 1; i < len(vec2InstrExtndMnics)-6; i++ {
if i == 4 {
continue
}
if uint8(inst.Args[vec2InstrExtndMnics[i].Offset1].(Mask)) == vec2InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec2InstrExtndMnics[i].Offset2].(Mask)) == vec2InstrExtndMnics[i].Value2 {
newOpStr = opString + vec2InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec2InstrExtndMnics[i].Offset1))
removeArg(inst, int8(vec2InstrExtndMnics[i].Offset2-1))
break
}
}
case "vfee", "vfene":
var check bool
for i := 0; i < len(vec21InstrExtndMnics); i++ {
if uint8(inst.Args[vec21InstrExtndMnics[i].Offset1].(Mask)) == vec21InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec21InstrExtndMnics[i].Offset2].(Mask)) == vec21InstrExtndMnics[i].Value2 {
newOpStr = opString + vec21InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1))
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset2-1))
check = true
break
}
}
if !check {
if uint8(inst.Args[3].(Mask)) == 0 && (uint8(inst.Args[4].(Mask)) != uint8(0)) {
newOpStr = opString + vec21InstrExtndMnics[0].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[0].Offset1))
} else if uint8(inst.Args[3].(Mask)) == 1 && (uint8(inst.Args[4].(Mask)) != uint8(0)) {
newOpStr = opString + vec21InstrExtndMnics[1].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[1].Offset1))
} else if uint8(inst.Args[3].(Mask)) == 2 && (uint8(inst.Args[4].(Mask)) != uint8(0)) {
newOpStr = opString + vec21InstrExtndMnics[2].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[2].Offset1))
} else if uint8(inst.Args[4].(Mask)) == 0 {
removeArg(inst, int8(vec21InstrExtndMnics[2].Offset2))
}
}
case "vfae", "vstrc":
off := uint8(0)
var check bool
if opString == "vstrc" {
off = uint8(1)
}
for i := 0; i < len(vec21InstrExtndMnics)-9; i++ {
if uint8(inst.Args[vec21InstrExtndMnics[i].Offset1+off].(Mask)) == vec21InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec21InstrExtndMnics[i].Offset2+off].(Mask)) == vec21InstrExtndMnics[i].Value2 {
newOpStr = opString + vec21InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1+off))
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset2+off-1))
check = true
break
}
}
for i := 0; !(check) && (i < len(vec21InstrExtndMnics)-9); i++ {
if uint8(inst.Args[vec21InstrExtndMnics[i].Offset1+off].(Mask)) == vec21InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec21InstrExtndMnics[i].Offset2+off].(Mask)) == vec21InstrExtndMnics[i].Value2 {
newOpStr = opString + vec21InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1+off))
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset2+off-1))
check = true
break
}
}
//for i := 3; !(check) && (i < len(vec21InstrExtndMnics)); i++ {
for i := len(vec21InstrExtndMnics) - 1; !(check) && (i > 2); i-- {
if uint8(inst.Args[vec21InstrExtndMnics[i].Offset1+off].(Mask)) == vec21InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec21InstrExtndMnics[i].Offset2+off].(Mask))&(vec21InstrExtndMnics[i].Value2) == vec21InstrExtndMnics[i].Value2 {
x := uint8(inst.Args[vec21InstrExtndMnics[i].Offset2+off].(Mask)) ^ (vec21InstrExtndMnics[i].Value2)
newOpStr = opString + vec21InstrExtndMnics[i].ExtnOpStr
if x != 0 {
inst.Args[vec21InstrExtndMnics[i].Offset2+off] = Mask(x)
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1+off))
check = true
break
} else {
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1+off))
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset2+off-1))
check = true
break
}
}
}
if !check && inst.Args[4+off].(Mask) == Mask(0) {
removeArg(inst, int8(4+off))
break
}
case "vstrs":
var check bool
for i := 0; i < len(vec21InstrExtndMnics)-3; i++ {
if uint8(inst.Args[vec21InstrExtndMnics[i].Offset1+1].(Mask)) == vec21InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec21InstrExtndMnics[i].Offset2+1].(Mask)) == vec21InstrExtndMnics[i].Value2 {
newOpStr = opString + vec21InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1+1))
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset2))
check = true
break
}
if i == 2 {
i = i + 3
}
}
for i := 0; !(check) && (i < len(vec21InstrExtndMnics)-9); i++ {
if uint8(inst.Args[vec21InstrExtndMnics[i].Offset1+1].(Mask)) == vec21InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec21InstrExtndMnics[i].Offset2+1].(Mask)) != 0 {
newOpStr = opString + vec21InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1+1))
break
}
}
case "vistr":
var check bool
for i := 0; i < len(vec21InstrExtndMnics)-6; i++ {
if uint8(inst.Args[vec21InstrExtndMnics[i].Offset1-1].(Mask)) == vec21InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec21InstrExtndMnics[i].Offset2-1].(Mask)) == vec21InstrExtndMnics[i].Value2 {
newOpStr = opString + vec21InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1-1))
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset2-2))
check = true
break
}
}
for i := 0; !(check) && (i < len(vec21InstrExtndMnics)-9); i++ {
if uint8(inst.Args[vec21InstrExtndMnics[i].Offset1-1].(Mask)) == vec21InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec21InstrExtndMnics[i].Offset2-1].(Mask)) != 0 {
newOpStr = opString + vec21InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec21InstrExtndMnics[i].Offset1-1))
break
}
}
if uint8(inst.Args[3].(Mask)) == 0 {
removeArg(inst, int8(3))
break
}
case "vcfps":
if inst.Args[2].(Mask) == Mask(2) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
inst.Args[3] = Mask((inst.Args[3].(Mask)) ^ (0x8))
newOpStr = "wcefb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(3) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
inst.Args[3] = Mask((inst.Args[3].(Mask)) ^ (0x8))
newOpStr = "wcdgb"
removeArg(inst, int8(2))
break
} else if uint8(inst.Args[2].(Mask)) == uint8(2) {
newOpStr = "vcefb"
removeArg(inst, int8(2))
break
} else if uint8(inst.Args[2].(Mask)) == uint8(3) {
newOpStr = "vcdgb"
removeArg(inst, int8(2))
break
}
case "vcfpl":
if inst.Args[2].(Mask) == Mask(2) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
inst.Args[3] = Mask((inst.Args[3].(Mask)) ^ (0x8))
newOpStr = "wcelfb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(3) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
inst.Args[3] = Mask((inst.Args[3].(Mask)) ^ (0x8))
newOpStr = "wcdlgb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(2) {
newOpStr = "vcelfb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(3) {
newOpStr = "vcdlgb"
removeArg(inst, int8(2))
break
}
case "vcsfp":
if inst.Args[2].(Mask) == Mask(2) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
inst.Args[3] = Mask((inst.Args[3].(Mask)) ^ (0x8))
newOpStr = "wcfeb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(3) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
inst.Args[3] = Mask((inst.Args[3].(Mask)) ^ (0x8))
newOpStr = "wcgdb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(2) {
newOpStr = "vcfeb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(3) {
newOpStr = "vcgdb"
removeArg(inst, int8(2))
break
}
case "vclfp":
if inst.Args[2].(Mask) == Mask(2) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
inst.Args[3] = Mask((inst.Args[3].(Mask)) ^ (0x8))
newOpStr = "wclfeb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(3) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
inst.Args[3] = Mask((inst.Args[3].(Mask)) ^ (0x8))
newOpStr = "wclgdb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(2) {
newOpStr = "vclfeb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(3) {
newOpStr = "vclgdb"
removeArg(inst, int8(2))
break
}
case "vfi":
if inst.Args[2].(Mask) == Mask(2) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
newOpStr = "wfisb"
removeArg(inst, int8(2))
inst.Args[2] = Mask((inst.Args[2].(Mask)) ^ (0x8))
break
} else if inst.Args[2].(Mask) == Mask(3) && ((inst.Args[3].(Mask)>>3)&(0x3) == 1) {
newOpStr = "wfidb"
removeArg(inst, int8(2))
inst.Args[2] = Mask((inst.Args[2].(Mask)) ^ (0x8))
break
} else if inst.Args[2].(Mask) == Mask(4) && ((inst.Args[3].(Mask)>>3)&(0x1) == 1) {
newOpStr = "wfixb"
removeArg(inst, int8(2))
inst.Args[2] = Mask((inst.Args[2].(Mask)) ^ (0x8))
break
} else if inst.Args[2].(Mask) == Mask(2) {
newOpStr = "vfisb"
removeArg(inst, int8(2))
break
} else if inst.Args[2].(Mask) == Mask(3) {
newOpStr = "vfidb"
removeArg(inst, int8(2))
break
}
// Case to handle few vector instructions with 2 M-field operands
case "vfa", "vfd", "vfll", "vfmax", "vfmin", "vfm":
for i := 0; i < len(vec4InstrExtndMnics); i++ {
if opString == vec4InstrExtndMnics[i].BaseOpStr &&
uint8(inst.Args[vec4InstrExtndMnics[i].Offset1].(Mask)) == vec4InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec4InstrExtndMnics[i].Offset2].(Mask)) == vec4InstrExtndMnics[i].Value2 {
newOpStr = vec4InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec4InstrExtndMnics[i].Offset1))
removeArg(inst, int8(vec4InstrExtndMnics[i].Offset2-1))
break
}
}
// Case to handle few special "vector" instructions with 2 M-field operands
case "wfc", "wfk":
for i := 0; i < len(vec3InstrExtndMnics); i++ {
if uint8(inst.Args[vec3InstrExtndMnics[i].Offset1].(Mask)) == vec3InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec3InstrExtndMnics[i].Offset2].(Mask)) == vec3InstrExtndMnics[i].Value2 {
newOpStr = opString + vec3InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec3InstrExtndMnics[i].Offset1))
removeArg(inst, int8(vec3InstrExtndMnics[i].Offset2-1))
break
}
}
// Case to handle few vector instructions with 2 M-field operands
case "vfma", "vfms", "vfnma", "vfnms":
for i := 0; i < len(vec7InstrExtndMnics); i++ {
if opString == vec7InstrExtndMnics[i].BaseOpStr &&
uint8(inst.Args[vec7InstrExtndMnics[i].Offset1].(Mask)) == vec7InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec7InstrExtndMnics[i].Offset2].(Mask)) == vec7InstrExtndMnics[i].Value2 {
newOpStr = vec7InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec7InstrExtndMnics[i].Offset1))
removeArg(inst, int8(vec7InstrExtndMnics[i].Offset2-1))
break
}
}
// List of instructions with 3 M-field operands.
case "vfce", "vfch", "vfche", "vfpso":
for i := 0; i < len(vec6InstrExtndMnics); i++ {
if opString == vec6InstrExtndMnics[i].BaseOpStr &&
uint8(inst.Args[vec6InstrExtndMnics[i].Offset1].(Mask)) == vec6InstrExtndMnics[i].Value1 &&
uint8(inst.Args[vec6InstrExtndMnics[i].Offset2].(Mask)) == vec6InstrExtndMnics[i].Value2 &&
uint8(inst.Args[vec6InstrExtndMnics[i].Offset3].(Mask)) == vec6InstrExtndMnics[i].Value3 {
newOpStr = vec6InstrExtndMnics[i].ExtnOpStr
removeArg(inst, int8(vec6InstrExtndMnics[i].Offset1))
removeArg(inst, int8(vec6InstrExtndMnics[i].Offset2-1))
removeArg(inst, int8(vec6InstrExtndMnics[i].Offset3-2))
break
}
}
default:
return opString
}
return newOpStr
}
// This is the function that is called to print the disassembled instruction
// in the GNU (AT&T) syntax form.
func GNUSyntax(inst Inst, pc uint64) string {
if inst.Enc == 0 {
return ".long 0x0"
} else if inst.Op == 0 {
return "error: unknown instruction"
}
return inst.String(pc)
}
// removeArg removes the arg in inst.Args[index].
func removeArg(inst *Inst, index int8) {
for i := int(index); i < len(inst.Args); i++ {
if i+1 < len(inst.Args) {
inst.Args[i] = inst.Args[i+1]
} else {
inst.Args[i] = nil
}
}
}
// 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)
}
Source diff could not be displayed: it is too large. Options to address this: view the blob.
...@@ -16,11 +16,12 @@ github.com/google/pprof/third_party/svgpan ...@@ -16,11 +16,12 @@ github.com/google/pprof/third_party/svgpan
# github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 # github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465
## explicit; go 1.13 ## explicit; go 1.13
github.com/ianlancetaylor/demangle 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 ## explicit; go 1.18
golang.org/x/arch/arm/armasm golang.org/x/arch/arm/armasm
golang.org/x/arch/arm64/arm64asm golang.org/x/arch/arm64/arm64asm
golang.org/x/arch/ppc64/ppc64asm golang.org/x/arch/ppc64/ppc64asm
golang.org/x/arch/s390x/s390xasm
golang.org/x/arch/x86/x86asm golang.org/x/arch/x86/x86asm
# golang.org/x/build v0.0.0-20240722200705-b9910f320300 # golang.org/x/build v0.0.0-20240722200705-b9910f320300
## explicit; go 1.21 ## explicit; go 1.21
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment