Source file src/cmd/vendor/golang.org/x/arch/s390x/s390xasm/decode.go

     1  // Copyright 2024 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 s390xasm
     6  
     7  import (
     8  	"encoding/binary"
     9  	"fmt"
    10  )
    11  
    12  // instFormat is a decoding rule for one specific instruction form.
    13  // An instruction ins matches the rule if ins&Mask == Value.
    14  // DontCare bits are mainly used for finding the same instruction
    15  // name differing with the number of argument fields.
    16  // The Args are stored in the same order as the instruction manual.
    17  type instFormat struct {
    18  	Op       Op
    19  	Mask     uint64
    20  	Value    uint64
    21  	DontCare uint64
    22  	Args     [8]*argField
    23  }
    24  
    25  // argField indicate how to decode an argument to an instruction.
    26  // First parse the value from the BitFields, shift it left by Shift
    27  // bits to get the actual numerical value.
    28  type argField struct {
    29  	Type  ArgType
    30  	flags uint16
    31  	BitField
    32  }
    33  
    34  // Parse parses the Arg out from the given binary instruction i.
    35  func (a argField) Parse(i uint64) Arg {
    36  	switch a.Type {
    37  	default:
    38  		return nil
    39  	case TypeUnknown:
    40  		return nil
    41  	case TypeReg:
    42  		return R0 + Reg(a.BitField.Parse(i))
    43  	case TypeFPReg:
    44  		return F0 + Reg(a.BitField.Parse(i))
    45  	case TypeCReg:
    46  		return C0 + Reg(a.BitField.Parse(i))
    47  	case TypeACReg:
    48  		return A0 + Reg(a.BitField.Parse(i))
    49  	case TypeBaseReg:
    50  		return B0 + Base(a.BitField.Parse(i))
    51  	case TypeIndexReg:
    52  		return X0 + Index(a.BitField.Parse(i))
    53  	case TypeDispUnsigned:
    54  		return Disp12(a.BitField.Parse(i))
    55  	case TypeDispSigned20:
    56  		return Disp20(a.BitField.ParseSigned(i))
    57  	case TypeVecReg:
    58  		m := i >> 24 // Handling RXB field(bits 36 to 39)
    59  		if ((m>>3)&0x1 == 1) && (a.BitField.Offs == 8) {
    60  			return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
    61  		} else if ((m>>2)&0x1 == 1) && (a.BitField.Offs == 12) {
    62  			return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
    63  		} else if ((m>>1)&0x1 == 1) && (a.BitField.Offs == 16) {
    64  			return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
    65  		} else if ((m)&0x1 == 1) && (a.BitField.Offs == 32) {
    66  			return V0 + VReg(a.BitField.Parse(i)) + VReg(16)
    67  		} else {
    68  			return V0 + VReg(a.BitField.Parse(i))
    69  		}
    70  	case TypeImmSigned8:
    71  		return Sign8(a.BitField.ParseSigned(i))
    72  	case TypeImmSigned16:
    73  		return Sign16(a.BitField.ParseSigned(i))
    74  	case TypeImmSigned32:
    75  		return Sign32(a.BitField.ParseSigned(i))
    76  	case TypeImmUnsigned:
    77  		return Imm(a.BitField.Parse(i))
    78  	case TypeRegImSigned12:
    79  		return RegIm12(a.BitField.ParseSigned(i))
    80  	case TypeRegImSigned16:
    81  		return RegIm16(a.BitField.ParseSigned(i))
    82  	case TypeRegImSigned24:
    83  		return RegIm24(a.BitField.ParseSigned(i))
    84  	case TypeRegImSigned32:
    85  		return RegIm32(a.BitField.ParseSigned(i))
    86  	case TypeMask:
    87  		return Mask(a.BitField.Parse(i))
    88  	case TypeLen:
    89  		return Len(a.BitField.Parse(i))
    90  	}
    91  }
    92  
    93  type ArgType int8
    94  
    95  const (
    96  	TypeUnknown       ArgType = iota
    97  	TypeReg                   // integer register
    98  	TypeFPReg                 // floating point register
    99  	TypeACReg                 // access register
   100  	TypeCReg                  // control register
   101  	TypeVecReg                // vector register
   102  	TypeImmUnsigned           // unsigned immediate/flag/mask, this is the catch-all type
   103  	TypeImmSigned8            // Signed 8-bit Immdediate
   104  	TypeImmSigned16           // Signed 16-bit Immdediate
   105  	TypeImmSigned32           // Signed 32-bit Immdediate
   106  	TypeBaseReg               // Base Register for accessing memory
   107  	TypeIndexReg              // Index Register
   108  	TypeDispUnsigned          // Displacement 12-bit unsigned for memory address
   109  	TypeDispSigned20          // Displacement 20-bit signed for memory address
   110  	TypeRegImSigned12         // RegisterImmediate 12-bit signed data
   111  	TypeRegImSigned16         // RegisterImmediate 16-bit signed data
   112  	TypeRegImSigned24         // RegisterImmediate 24-bit signed data
   113  	TypeRegImSigned32         // RegisterImmediate 32-bit signed data
   114  	TypeMask                  // 4-bit Mask
   115  	TypeLen                   // Length of Memory Operand
   116  	TypeLast
   117  )
   118  
   119  func (t ArgType) String() string {
   120  	switch t {
   121  	default:
   122  		return fmt.Sprintf("ArgType(%d)", int(t))
   123  	case TypeUnknown:
   124  		return "Unknown"
   125  	case TypeReg:
   126  		return "Reg"
   127  	case TypeFPReg:
   128  		return "FPReg"
   129  	case TypeACReg:
   130  		return "ACReg"
   131  	case TypeCReg:
   132  		return "CReg"
   133  	case TypeDispUnsigned:
   134  		return "DispUnsigned"
   135  	case TypeDispSigned20:
   136  		return "DispSigned20"
   137  	case TypeBaseReg:
   138  		return "BaseReg"
   139  	case TypeIndexReg:
   140  		return "IndexReg"
   141  	case TypeVecReg:
   142  		return "VecReg"
   143  	case TypeImmSigned8:
   144  		return "ImmSigned8"
   145  	case TypeImmSigned16:
   146  		return "ImmSigned16"
   147  	case TypeImmSigned32:
   148  		return "ImmSigned32"
   149  	case TypeImmUnsigned:
   150  		return "ImmUnsigned"
   151  	case TypeRegImSigned12:
   152  		return "RegImSigned12"
   153  	case TypeRegImSigned16:
   154  		return "RegImSigned16"
   155  	case TypeRegImSigned24:
   156  		return "RegImSigned24"
   157  	case TypeRegImSigned32:
   158  		return "RegImSigned32"
   159  	case TypeMask:
   160  		return "Mask"
   161  	case TypeLen:
   162  		return "Len"
   163  	}
   164  }
   165  
   166  func (t ArgType) GoString() string {
   167  	s := t.String()
   168  	if t > 0 && t < TypeLast {
   169  		return "Type" + s
   170  	}
   171  	return s
   172  }
   173  
   174  var (
   175  	// Errors
   176  	errShort   = fmt.Errorf("truncated instruction")
   177  	errUnknown = fmt.Errorf("unknown instruction")
   178  )
   179  
   180  var decoderCover []bool
   181  
   182  // Decode decodes the leading bytes in src as a single instruction using
   183  // byte order ord.
   184  func Decode(src []byte) (inst Inst, err error) {
   185  	if len(src) < 2 {
   186  		return inst, errShort
   187  	}
   188  	if decoderCover == nil {
   189  		decoderCover = make([]bool, len(instFormats))
   190  	}
   191  	bit_check := binary.BigEndian.Uint16(src[:2])
   192  	bit_check = bit_check >> 14
   193  	l := int(0)
   194  	if (bit_check & 0x03) == 0 {
   195  		l = 2
   196  	} else if bit_check&0x03 == 3 {
   197  		l = 6
   198  	} else if (bit_check&0x01 == 1) || (bit_check&0x02 == 2) {
   199  		l = 4
   200  	}
   201  	inst.Len = l
   202  	ui_extn := uint64(0)
   203  	switch l {
   204  	case 2:
   205  		ui_extn = uint64(binary.BigEndian.Uint16(src[:inst.Len]))
   206  		inst.Enc = ui_extn
   207  		ui_extn = ui_extn << 48
   208  	case 4:
   209  		ui_extn = uint64(binary.BigEndian.Uint32(src[:inst.Len]))
   210  		inst.Enc = ui_extn
   211  		ui_extn = ui_extn << 32
   212  	case 6:
   213  		u1 := binary.BigEndian.Uint32(src[:(inst.Len - 2)])
   214  		u2 := binary.BigEndian.Uint16(src[(inst.Len - 2):inst.Len])
   215  		ui_extn = uint64(u1)<<16 | uint64(u2)
   216  		ui_extn = ui_extn << 16
   217  		inst.Enc = ui_extn
   218  	default:
   219  		return inst, errShort
   220  	}
   221  	for _, iform := range instFormats {
   222  		if ui_extn&iform.Mask != iform.Value {
   223  			continue
   224  		}
   225  		if (iform.DontCare & ^(ui_extn)) != iform.DontCare {
   226  			continue
   227  		}
   228  		for j, argfield := range iform.Args {
   229  			if argfield == nil {
   230  				break
   231  			}
   232  			inst.Args[j] = argfield.Parse(ui_extn)
   233  		}
   234  		inst.Op = iform.Op
   235  		break
   236  	}
   237  	if inst.Op == 0 && inst.Enc != 0 {
   238  		return inst, errUnknown
   239  	}
   240  	return inst, nil
   241  }
   242  

View as plain text