Add gops agent
This commit is contained in:
179
vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
generated
vendored
Normal file
179
vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
// Copyright 2014 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 ppc64asm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
const debugDecode = false
|
||||
|
||||
// instFormat is a decoding rule for one specific instruction form.
|
||||
// a uint32 instruction ins matches the rule if ins&Mask == Value
|
||||
// DontCare bits should be zero, but the machine might not reject
|
||||
// ones in those bits, they are mainly reserved for future expansion
|
||||
// of the instruction set.
|
||||
// The Args are stored in the same order as the instruction manual.
|
||||
type instFormat struct {
|
||||
Op Op
|
||||
Mask uint32
|
||||
Value uint32
|
||||
DontCare uint32
|
||||
Args [5]*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
|
||||
Shift uint8
|
||||
BitFields
|
||||
}
|
||||
|
||||
// Parse parses the Arg out from the given binary instruction i.
|
||||
func (a argField) Parse(i uint32) Arg {
|
||||
switch a.Type {
|
||||
default:
|
||||
return nil
|
||||
case TypeUnknown:
|
||||
return nil
|
||||
case TypeReg:
|
||||
return R0 + Reg(a.BitFields.Parse(i))
|
||||
case TypeCondRegBit:
|
||||
return Cond0LT + CondReg(a.BitFields.Parse(i))
|
||||
case TypeCondRegField:
|
||||
return CR0 + CondReg(a.BitFields.Parse(i))
|
||||
case TypeFPReg:
|
||||
return F0 + Reg(a.BitFields.Parse(i))
|
||||
case TypeVecReg:
|
||||
return V0 + Reg(a.BitFields.Parse(i))
|
||||
case TypeVecSReg:
|
||||
return VS0 + Reg(a.BitFields.Parse(i))
|
||||
case TypeSpReg:
|
||||
return SpReg(a.BitFields.Parse(i))
|
||||
case TypeImmSigned:
|
||||
return Imm(a.BitFields.ParseSigned(i) << a.Shift)
|
||||
case TypeImmUnsigned:
|
||||
return Imm(a.BitFields.Parse(i) << a.Shift)
|
||||
case TypePCRel:
|
||||
return PCRel(a.BitFields.ParseSigned(i) << a.Shift)
|
||||
case TypeLabel:
|
||||
return Label(a.BitFields.ParseSigned(i) << a.Shift)
|
||||
case TypeOffset:
|
||||
return Offset(a.BitFields.ParseSigned(i) << a.Shift)
|
||||
}
|
||||
}
|
||||
|
||||
type ArgType int8
|
||||
|
||||
const (
|
||||
TypeUnknown ArgType = iota
|
||||
TypePCRel // PC-relative address
|
||||
TypeLabel // absolute address
|
||||
TypeReg // integer register
|
||||
TypeCondRegBit // conditional register bit (0-31)
|
||||
TypeCondRegField // conditional register field (0-7)
|
||||
TypeFPReg // floating point register
|
||||
TypeVecReg // vector register
|
||||
TypeVecSReg // VSX register
|
||||
TypeSpReg // special register (depends on Op)
|
||||
TypeImmSigned // signed immediate
|
||||
TypeImmUnsigned // unsigned immediate/flag/mask, this is the catch-all type
|
||||
TypeOffset // signed offset in load/store
|
||||
TypeLast // must be the last one
|
||||
)
|
||||
|
||||
func (t ArgType) String() string {
|
||||
switch t {
|
||||
default:
|
||||
return fmt.Sprintf("ArgType(%d)", int(t))
|
||||
case TypeUnknown:
|
||||
return "Unknown"
|
||||
case TypeReg:
|
||||
return "Reg"
|
||||
case TypeCondRegBit:
|
||||
return "CondRegBit"
|
||||
case TypeCondRegField:
|
||||
return "CondRegField"
|
||||
case TypeFPReg:
|
||||
return "FPReg"
|
||||
case TypeVecReg:
|
||||
return "VecReg"
|
||||
case TypeVecSReg:
|
||||
return "VecSReg"
|
||||
case TypeSpReg:
|
||||
return "SpReg"
|
||||
case TypeImmSigned:
|
||||
return "ImmSigned"
|
||||
case TypeImmUnsigned:
|
||||
return "ImmUnsigned"
|
||||
case TypePCRel:
|
||||
return "PCRel"
|
||||
case TypeLabel:
|
||||
return "Label"
|
||||
case TypeOffset:
|
||||
return "Offset"
|
||||
}
|
||||
}
|
||||
|
||||
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, ord binary.ByteOrder) (inst Inst, err error) {
|
||||
if len(src) < 4 {
|
||||
return inst, errShort
|
||||
}
|
||||
if decoderCover == nil {
|
||||
decoderCover = make([]bool, len(instFormats))
|
||||
}
|
||||
inst.Len = 4 // only 4-byte instructions are supported
|
||||
ui := ord.Uint32(src[:inst.Len])
|
||||
inst.Enc = ui
|
||||
for i, iform := range instFormats {
|
||||
if ui&iform.Mask != iform.Value {
|
||||
continue
|
||||
}
|
||||
if ui&iform.DontCare != 0 {
|
||||
if debugDecode {
|
||||
log.Printf("Decode(%#x): unused bit is 1 for Op %s", ui, iform.Op)
|
||||
}
|
||||
// to match GNU objdump (libopcodes), we ignore don't care bits
|
||||
}
|
||||
for i, argfield := range iform.Args {
|
||||
if argfield == nil {
|
||||
break
|
||||
}
|
||||
inst.Args[i] = argfield.Parse(ui)
|
||||
}
|
||||
inst.Op = iform.Op
|
||||
if debugDecode {
|
||||
log.Printf("%#x: search entry %d", ui, i)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
if inst.Op == 0 {
|
||||
return inst, errUnknown
|
||||
}
|
||||
return inst, nil
|
||||
}
|
||||
Reference in New Issue
Block a user