...

Source file src/golang.org/x/arch/x86/xeddata/example_test.go

Documentation: golang.org/x/arch/x86/xeddata

     1  // Copyright 2018 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 xeddata_test
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"strings"
    11  
    12  	"golang.org/x/arch/x86/xeddata"
    13  )
    14  
    15  // The "testdata/xedpath" directory contains XED metadata files
    16  // that are supposed to be used for Database initialization.
    17  
    18  // Note that XED objects in this file are not real,
    19  // instructions they describe are fictional.
    20  
    21  // This example shows how to print raw XED objects using Reader.
    22  // Objects are called "raw" because some of their fields may
    23  // require additional transformations like macro (states) expansion.
    24  func ExampleReader() {
    25  	const xedPath = "testdata/xedpath"
    26  
    27  	input := strings.NewReader(`
    28  {
    29  ICLASS: VEXADD
    30  EXCEPTIONS: avx-type-zero
    31  CPL: 2000
    32  CATEGORY: AVX-Q
    33  EXTENSION: AVX-Q
    34  ATTRIBUTES: A B C
    35  PATTERN: VV1 0x07 VL128 V66 V0F MOD[mm] MOD!=3 REG[rrr] RM[nnn] MODRM()
    36  OPERANDS: REG0=XMM_R():w:width_dq:fword64 REG1=XMM_N():r:width_dq:fword64 MEM0:r:width_dq:fword64
    37  }
    38  
    39  {
    40  ICLASS: COND_MOV_Z
    41  CPL: 210
    42  CATEGORY: MOV_IF_COND_MET
    43  EXTENSION: BASE
    44  ISA_SET: COND_MOV
    45  FLAGS: READONLY [ zf-tst ]
    46  
    47  PATTERN: 0x0F 0x4F MOD[mm] MOD!=3 REG[rrr] RM[nnn] MODRM()
    48  OPERANDS: REG0=GPRv_R():cw MEM0:r:width_v
    49  PATTERN: 0x0F 0x4F MOD[0b11] MOD=3 REG[rrr] RM[nnn]
    50  OPERANDS: REG0=GPRv_R():cw REG1=GPRv_B():r
    51  }`)
    52  
    53  	objects, err := xeddata.NewReader(input).ReadAll()
    54  	if err != nil {
    55  		log.Fatal(err)
    56  	}
    57  
    58  	for _, o := range objects {
    59  		fmt.Printf("%s (%s):\n", o.Opcode(), o.Extension)
    60  		for _, inst := range o.Insts {
    61  			fmt.Printf("\t[%d] %s\n", inst.Index, inst.Operands)
    62  		}
    63  	}
    64  
    65  	//Output:
    66  	// VEXADD (AVX-Q):
    67  	// 	[0] REG0=XMM_R():w:width_dq:fword64 REG1=XMM_N():r:width_dq:fword64 MEM0:r:width_dq:fword64
    68  	// COND_MOV_Z (BASE):
    69  	// 	[0] REG0=GPRv_R():cw MEM0:r:width_v
    70  	// 	[1] REG0=GPRv_R():cw REG1=GPRv_B():r
    71  }
    72  
    73  // This example shows how to use ExpandStates and its effects.
    74  func ExampleExpandStates() {
    75  	const xedPath = "testdata/xedpath"
    76  
    77  	input := strings.NewReader(`
    78  {
    79  ICLASS: VEXADD
    80  CPL: 3
    81  CATEGORY: ?
    82  EXTENSION: ?
    83  ATTRIBUTES: AT_A AT_B
    84  
    85  PATTERN: _M_VV_TRUE 0x58  _M_VEX_P_66 _M_VLEN_128 _M_MAP_0F MOD[mm] MOD!=3 REG[rrr] RM[nnn] MODRM()
    86  OPERANDS: REG0=XMM_R():w:width_dq:fword64 REG1=XMM_N():r:width_dq:fword64 MEM0:r:width_dq:fword64
    87  
    88  PATTERN: _M_VV_TRUE 0x58  _M_VEX_P_66 _M_VLEN_128 _M_MAP_0F MOD[0b11] MOD=3 REG[rrr] RM[nnn]
    89  OPERANDS: REG0=XMM_R():w:width_dq:fword64 REG1=XMM_N():r:width_dq:fword64 REG2=XMM_B():r:width_dq:fword64
    90  
    91  PATTERN: _M_VV_TRUE 0x58  _M_VEX_P_66 _M_VLEN_256 _M_MAP_0F MOD[mm] MOD!=3 REG[rrr] RM[nnn] MODRM()
    92  OPERANDS: REG0=YMM_R():w:qq:fword64 REG1=YMM_N():r:qq:fword64 MEM0:r:qq:fword64
    93  
    94  PATTERN: _M_VV_TRUE 0x58  _M_VEX_P_66 _M_VLEN_256 _M_MAP_0F MOD[0b11] MOD=3 REG[rrr] RM[nnn]
    95  OPERANDS: REG0=YMM_R():w:qq:fword64 REG1=YMM_N():r:qq:fword64 REG2=YMM_B():r:qq:fword64
    96  }`)
    97  
    98  	objects, err := xeddata.NewReader(input).ReadAll()
    99  	if err != nil {
   100  		log.Fatal(err)
   101  	}
   102  	db, err := xeddata.NewDatabase(xedPath)
   103  	if err != nil {
   104  		log.Fatal(err)
   105  	}
   106  
   107  	for _, o := range objects {
   108  		for _, inst := range o.Insts {
   109  			fmt.Printf("old: %q\n", inst.Pattern)
   110  			fmt.Printf("new: %q\n", xeddata.ExpandStates(db, inst.Pattern))
   111  		}
   112  	}
   113  
   114  	//Output:
   115  	// old: "_M_VV_TRUE 0x58  _M_VEX_P_66 _M_VLEN_128 _M_MAP_0F MOD[mm] MOD!=3 REG[rrr] RM[nnn] MODRM()"
   116  	// new: "VEXVALID=1 0x58 VEX_PREFIX=1 VL=0 MAP=1 MOD[mm] MOD!=3 REG[rrr] RM[nnn] MODRM()"
   117  	// old: "_M_VV_TRUE 0x58  _M_VEX_P_66 _M_VLEN_128 _M_MAP_0F MOD[0b11] MOD=3 REG[rrr] RM[nnn]"
   118  	// new: "VEXVALID=1 0x58 VEX_PREFIX=1 VL=0 MAP=1 MOD[0b11] MOD=3 REG[rrr] RM[nnn]"
   119  	// old: "_M_VV_TRUE 0x58  _M_VEX_P_66 _M_VLEN_256 _M_MAP_0F MOD[mm] MOD!=3 REG[rrr] RM[nnn] MODRM()"
   120  	// new: "VEXVALID=1 0x58 VEX_PREFIX=1 VL=1 MAP=1 MOD[mm] MOD!=3 REG[rrr] RM[nnn] MODRM()"
   121  	// old: "_M_VV_TRUE 0x58  _M_VEX_P_66 _M_VLEN_256 _M_MAP_0F MOD[0b11] MOD=3 REG[rrr] RM[nnn]"
   122  	// new: "VEXVALID=1 0x58 VEX_PREFIX=1 VL=1 MAP=1 MOD[0b11] MOD=3 REG[rrr] RM[nnn]"
   123  }
   124  
   125  // This example shows how to handle Inst "OPERANDS" field.
   126  func ExampleOperand() {
   127  	const xedPath = "testdata/xedpath"
   128  
   129  	input := strings.NewReader(`
   130  {
   131  ICLASS: ADD_N_TIMES # Like IMUL
   132  CPL: 3
   133  CATEGORY: BINARY
   134  EXTENSION: BASE
   135  ISA_SET: I86
   136  FLAGS: MUST [ of-mod sf-u zf-u af-u pf-u cf-mod ]
   137  
   138  PATTERN: 0xAA MOD[mm] MOD!=3 REG[0b101] RM[nnn] MODRM()
   139  OPERANDS: MEM0:r:width_v REG0=AX:rw:SUPP REG1=DX:w:SUPP
   140  }`)
   141  
   142  	objects, err := xeddata.NewReader(input).ReadAll()
   143  	if err != nil {
   144  		log.Fatal(err)
   145  	}
   146  	db, err := xeddata.NewDatabase(xedPath)
   147  	if err != nil {
   148  		log.Fatal(err)
   149  	}
   150  
   151  	inst := objects[0].Insts[0] // Single instruction is enough for this example
   152  	for i, rawOperand := range strings.Fields(inst.Operands) {
   153  		operand, err := xeddata.NewOperand(db, rawOperand)
   154  		if err != nil {
   155  			log.Fatalf("parse operand #%d: %+v", i, err)
   156  		}
   157  
   158  		visibility := "implicit"
   159  		if operand.IsVisible() {
   160  			visibility = "explicit"
   161  		}
   162  		fmt.Printf("(%s) %s:\n", visibility, rawOperand)
   163  
   164  		fmt.Printf("\tname: %q\n", operand.Name)
   165  		if operand.IsVisible() {
   166  			fmt.Printf("\t32/64bit width: %s/%s bytes\n",
   167  				db.WidthSize(operand.Width, xeddata.OpSize32),
   168  				db.WidthSize(operand.Width, xeddata.OpSize64))
   169  		}
   170  	}
   171  
   172  	//Output:
   173  	// (explicit) MEM0:r:width_v:
   174  	// 	name: "MEM0"
   175  	// 	32/64bit width: 4/8 bytes
   176  	// (implicit) REG0=AX:rw:SUPP:
   177  	// 	name: "REG0=AX"
   178  	// (implicit) REG1=DX:w:SUPP:
   179  	// 	name: "REG1=DX"
   180  }
   181  

View as plain text