HPCToolkit
amd-xop.c
Go to the documentation of this file.
1 #include "amd-xop.h"
2 
3 typedef unsigned char uc;
4 typedef struct {
5  uc vex : 8;
6  uc opcp : 5;
7  uc B : 1;
8  uc X : 1;
9  uc R : 1;
10  uc pp : 2;
11  uc L : 1;
12  uc vv : 4;
13  uc W : 1;
14  uc opc : 8;
15  uc r_m : 3;
16  uc reg : 3;
17  uc mod : 2;
18 } apm_t;
19 
20 typedef struct {
21  uc vex : 8;
22  uc pp : 2;
23  uc L : 1;
24  uc vv : 4;
25  uc R : 1;
26  uc opc : 8;
27  uc r_m : 3;
28  uc reg : 3;
29  uc mod : 2;
30 } apm_c5_t;
31 
32 static const uc vex_op4_tbl[] = {
33  0x48,
34  0x49,
35  0x5c,
36  0x5d,
37  0x5e,
38  0x5f,
39  0x68,
40  0x69,
41  0x6a,
42  0x6b,
43  0x6c,
44  0x6d,
45  0x6e,
46  0x6f,
47  0x78,
48  0x79,
49  0x7a,
50  0x7b,
51  0x7c,
52  0x7d,
53  0x7e,
54  0x7f,
55 };
56 
57 static const uc xop_op4_tbl[] = {
58  0x85,
59  0x86,
60  0x87,
61  0x8e,
62  0x8f,
63  0x95,
64  0x96,
65  0x97,
66  0x9f,
67  0xa2,
68  0xa3,
69  0xa6,
70  0xb6,
71  0xcc,
72  0xcd,
73  0xce,
74  0xcf,
75  0xec,
76  0xed,
77  0xee,
78  0xef,
79 };
80 
81 #define Table_spec(t) t, sizeof(t)
82 #define Opc_in_tbl(t) opc_in_table(opc, Table_spec(t))
83 
84 static bool
85 default_false(void* seq)
86 {
87  return false;
88 }
89 
90 static inline bool
91 opc_in_table(uc opc, const uc opc_tbl[], const size_t len)
92 {
93  for(size_t i=0; i < len; i++)
94  if (opc == opc_tbl[i]) return true;
95  return false;
96 }
97 
98 static bool
99 xop_op4(void* seq)
100 {
101  apm_t* in = seq;
102  uc opc = in->opc;
103 
104  return Opc_in_tbl(xop_op4_tbl);
105 }
106 
107 static bool
108 vex_op4(void* seq)
109 {
110  apm_t* in = seq;
111  uc opc = in->opc;
112 
113  return Opc_in_tbl(vex_op4_tbl);
114 }
115 
116 static bool
117 vex5_op4(void* seq)
118 {
119  apm_c5_t* in = seq;
120  uc opc = in->opc;
121 
122  return Opc_in_tbl(vex_op4_tbl);
123 }
124 
125 static size_t
126 op4_imm(void* seq)
127 {
128  uc* in = seq;
129 
130  bool has4 = false;
131  if (*in == 0xc4)
132  has4 = vex_op4(seq);
133  if (*in == 0xc5)
134  has4 = vex5_op4(seq);
135  if (*in == 0x8f)
136  has4 = xop_op4(seq);
137 
138  return has4 ? 1 : 0;
139 }
140 
141 static size_t
142 disp_size(void* seq)
143 {
144  uc* escape = seq;
145  size_t rv = 0;
146  uc mod = 0xff;
147  uc r_m = 0xff;
148 
149  if ((*escape == 0xc4) || (*escape == 0x8f)) {
150  apm_t* in = seq;
151  mod = in->mod;
152  r_m = in->r_m;
153  }
154  if (*escape == 0xc5) {
155  apm_c5_t* in = seq;
156  mod = in->mod;
157  r_m = in->r_m;
158  }
159 
160  if ((mod == 0) && (r_m == 5)) rv = 4;
161  else if (mod == 1) rv = 1;
162  else if (mod == 2) rv = 4;
163 
164  return rv;
165 }
166 
167 static size_t
168 sib_byte(void* seq)
169 {
170  uc* escape = seq;
171  uc r_m = 0xff;
172  uc mod = 0xff;
173 
174  if ((*escape == 0xc4) || (*escape == 0x8f)) {
175  apm_t* in = seq;
176  mod = in->mod;
177  r_m = in->r_m;
178  }
179  if (*escape == 0xc5) {
180  apm_c5_t* in = seq;
181  mod = in->mod;
182  r_m = in->r_m;
183  }
184 
185  return (mod != 3) && (r_m == 4) ? 1 : 0;
186 }
187 
188 static size_t
189 escape_len(void* seq)
190 {
191  uc* escape = seq;
192 
193  if ((*escape == 0xc4) || (*escape == 0x8f))
194  return sizeof(apm_t);
195  if (*escape == 0xc5)
196  return sizeof(apm_c5_t);
197 
198  return 1;
199 }
200 
201 static inline size_t
202 ins_len(void* seq)
203 {
204  // length of instruction = size of escape seq + #immediate bytes + # disp bytes + # sib bytes
205  return escape_len(seq) + op4_imm(seq) + disp_size(seq) + sib_byte(seq);
206 }
207 
208 static const uc prefix_tbl[] = {
209  0x66, // op size override
210  0x67, // addr size override
211  0x2e, 0x3e, 0x26, 0x64, 0x65, 0x36, // segment override
212  0xf0, // lock
213  0xf2, 0xf3, // repeat
214 };
215 
216 static bool
217 is_prefix(void* ins)
218 {
219  uc* in = ins;
220  for (int i = 0; i < sizeof(prefix_tbl); i++) {
221  if (*in ==prefix_tbl[i]) return true;
222  }
223  return false;
224 }
225 
226 void
227 adv_amd_decode(amd_decode_t* stat, void* ins)
228 {
229  uc* in = ins;
230  stat->len = 0;
231  // skip standard prefixes
232  for (int i = 0; i < 4; i++) {
233  if (is_prefix(in)) {
234  in++;
235  (stat->len)++;
236  }
237  else break;
238  }
239  stat->success = false;
240  stat->weak = false;
241 
242  if (*in == 0xc4) {
243  stat->success = true;
244  }
245  if (*in == 0x8f) {
246  stat->success = true;
247  stat->weak = true;
248  }
249 
250  stat->len += ins_len(in);
251 }
bool weak
Definition: amd-xop.h:9
static const uc xop_op4_tbl[]
Definition: amd-xop.c:57
static bool xop_op4(void *seq)
Definition: amd-xop.c:99
void adv_amd_decode(amd_decode_t *stat, void *ins)
Definition: amd-xop.c:227
uc R
Definition: amd-xop.c:9
static size_t escape_len(void *seq)
Definition: amd-xop.c:189
uc r_m
Definition: amd-xop.c:27
uc opc
Definition: amd-xop.c:14
static size_t ins_len(void *seq)
Definition: amd-xop.c:202
static size_t sib_byte(void *seq)
Definition: amd-xop.c:168
bool success
Definition: amd-xop.h:8
uc L
Definition: amd-xop.c:23
uc reg
Definition: amd-xop.c:28
static bool is_prefix(void *ins)
Definition: amd-xop.c:217
#define Opc_in_tbl(t)
Definition: amd-xop.c:82
uc mod
Definition: amd-xop.c:29
uc X
Definition: amd-xop.c:8
static const uc prefix_tbl[]
Definition: amd-xop.c:208
uc r_m
Definition: amd-xop.c:15
static size_t op4_imm(void *seq)
Definition: amd-xop.c:126
static bool default_false(void *seq)
Definition: amd-xop.c:85
uc L
Definition: amd-xop.c:11
uc opc
Definition: amd-xop.c:26
uc R
Definition: amd-xop.c:25
uc vex
Definition: amd-xop.c:21
uc pp
Definition: amd-xop.c:22
uc B
Definition: amd-xop.c:7
static bool vex5_op4(void *seq)
Definition: amd-xop.c:117
uc opcp
Definition: amd-xop.c:6
size_t len
Definition: amd-xop.h:10
uc vv
Definition: amd-xop.c:12
uc vv
Definition: amd-xop.c:24
uc vex
Definition: amd-xop.c:5
uc mod
Definition: amd-xop.c:17
uc pp
Definition: amd-xop.c:10
static bool vex_op4(void *seq)
Definition: amd-xop.c:108
unsigned char uc
Definition: amd-xop.c:3
static bool opc_in_table(uc opc, const uc opc_tbl[], const size_t len)
Definition: amd-xop.c:91
uc W
Definition: amd-xop.c:13
static size_t disp_size(void *seq)
Definition: amd-xop.c:142
Definition: amd-xop.c:4
static const uc vex_op4_tbl[]
Definition: amd-xop.c:32
uc reg
Definition: amd-xop.c:16