golang.org/x/arch@v0.17.0/x86/xeddata/example_test.go (about) 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 }