...

Source file src/pkg/cmd/vendor/golang.org/x/arch/ppc64/ppc64asm/decode.go

     1	// Copyright 2014 The Go Authors.  All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package ppc64asm
     6	
     7	import (
     8		"encoding/binary"
     9		"fmt"
    10		"log"
    11	)
    12	
    13	const debugDecode = false
    14	
    15	// instFormat is a decoding rule for one specific instruction form.
    16	// a uint32 instruction ins matches the rule if ins&Mask == Value
    17	// DontCare bits should be zero, but the machine might not reject
    18	// ones in those bits, they are mainly reserved for future expansion
    19	// of the instruction set.
    20	// The Args are stored in the same order as the instruction manual.
    21	type instFormat struct {
    22		Op       Op
    23		Mask     uint32
    24		Value    uint32
    25		DontCare uint32
    26		Args     [5]*argField
    27	}
    28	
    29	// argField indicate how to decode an argument to an instruction.
    30	// First parse the value from the BitFields, shift it left by Shift
    31	// bits to get the actual numerical value.
    32	type argField struct {
    33		Type  ArgType
    34		Shift uint8
    35		BitFields
    36	}
    37	
    38	// Parse parses the Arg out from the given binary instruction i.
    39	func (a argField) Parse(i uint32) Arg {
    40		switch a.Type {
    41		default:
    42			return nil
    43		case TypeUnknown:
    44			return nil
    45		case TypeReg:
    46			return R0 + Reg(a.BitFields.Parse(i))
    47		case TypeCondRegBit:
    48			return Cond0LT + CondReg(a.BitFields.Parse(i))
    49		case TypeCondRegField:
    50			return CR0 + CondReg(a.BitFields.Parse(i))
    51		case TypeFPReg:
    52			return F0 + Reg(a.BitFields.Parse(i))
    53		case TypeVecReg:
    54			return V0 + Reg(a.BitFields.Parse(i))
    55		case TypeVecSReg:
    56			return VS0 + Reg(a.BitFields.Parse(i))
    57		case TypeSpReg:
    58			return SpReg(a.BitFields.Parse(i))
    59		case TypeImmSigned:
    60			return Imm(a.BitFields.ParseSigned(i) << a.Shift)
    61		case TypeImmUnsigned:
    62			return Imm(a.BitFields.Parse(i) << a.Shift)
    63		case TypePCRel:
    64			return PCRel(a.BitFields.ParseSigned(i) << a.Shift)
    65		case TypeLabel:
    66			return Label(a.BitFields.ParseSigned(i) << a.Shift)
    67		case TypeOffset:
    68			return Offset(a.BitFields.ParseSigned(i) << a.Shift)
    69		}
    70	}
    71	
    72	type ArgType int8
    73	
    74	const (
    75		TypeUnknown      ArgType = iota
    76		TypePCRel                // PC-relative address
    77		TypeLabel                // absolute address
    78		TypeReg                  // integer register
    79		TypeCondRegBit           // conditional register bit (0-31)
    80		TypeCondRegField         // conditional register field (0-7)
    81		TypeFPReg                // floating point register
    82		TypeVecReg               // vector register
    83		TypeVecSReg              // VSX register
    84		TypeSpReg                // special register (depends on Op)
    85		TypeImmSigned            // signed immediate
    86		TypeImmUnsigned          // unsigned immediate/flag/mask, this is the catch-all type
    87		TypeOffset               // signed offset in load/store
    88		TypeLast                 // must be the last one
    89	)
    90	
    91	func (t ArgType) String() string {
    92		switch t {
    93		default:
    94			return fmt.Sprintf("ArgType(%d)", int(t))
    95		case TypeUnknown:
    96			return "Unknown"
    97		case TypeReg:
    98			return "Reg"
    99		case TypeCondRegBit:
   100			return "CondRegBit"
   101		case TypeCondRegField:
   102			return "CondRegField"
   103		case TypeFPReg:
   104			return "FPReg"
   105		case TypeVecReg:
   106			return "VecReg"
   107		case TypeVecSReg:
   108			return "VecSReg"
   109		case TypeSpReg:
   110			return "SpReg"
   111		case TypeImmSigned:
   112			return "ImmSigned"
   113		case TypeImmUnsigned:
   114			return "ImmUnsigned"
   115		case TypePCRel:
   116			return "PCRel"
   117		case TypeLabel:
   118			return "Label"
   119		case TypeOffset:
   120			return "Offset"
   121		}
   122	}
   123	
   124	func (t ArgType) GoString() string {
   125		s := t.String()
   126		if t > 0 && t < TypeLast {
   127			return "Type" + s
   128		}
   129		return s
   130	}
   131	
   132	var (
   133		// Errors
   134		errShort   = fmt.Errorf("truncated instruction")
   135		errUnknown = fmt.Errorf("unknown instruction")
   136	)
   137	
   138	var decoderCover []bool
   139	
   140	// Decode decodes the leading bytes in src as a single instruction using
   141	// byte order ord.
   142	func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) {
   143		if len(src) < 4 {
   144			return inst, errShort
   145		}
   146		if decoderCover == nil {
   147			decoderCover = make([]bool, len(instFormats))
   148		}
   149		inst.Len = 4 // only 4-byte instructions are supported
   150		ui := ord.Uint32(src[:inst.Len])
   151		inst.Enc = ui
   152		for i, iform := range instFormats {
   153			if ui&iform.Mask != iform.Value {
   154				continue
   155			}
   156			if ui&iform.DontCare != 0 {
   157				if debugDecode {
   158					log.Printf("Decode(%#x): unused bit is 1 for Op %s", ui, iform.Op)
   159				}
   160				// to match GNU objdump (libopcodes), we ignore don't care bits
   161			}
   162			for i, argfield := range iform.Args {
   163				if argfield == nil {
   164					break
   165				}
   166				inst.Args[i] = argfield.Parse(ui)
   167			}
   168			inst.Op = iform.Op
   169			if debugDecode {
   170				log.Printf("%#x: search entry %d", ui, i)
   171				continue
   172			}
   173			break
   174		}
   175		if inst.Op == 0 && inst.Enc != 0 {
   176			return inst, errUnknown
   177		}
   178		return inst, nil
   179	}
   180	

View as plain text