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 inline bool
85 opc_in_table(uc opc, const uc opc_tbl[], const size_t len)
86 {
87  for(size_t i=0; i < len; i++)
88  if (opc == opc_tbl[i]) return true;
89  return false;
90 }
91 
92 static bool
93 xop_op4(void* seq)
94 {
95  apm_t* in = seq;
96  uc opc = in->opc;
97 
98  return Opc_in_tbl(xop_op4_tbl);
99 }
100 
101 static bool
102 vex_op4(void* seq)
103 {
104  apm_t* in = seq;
105  uc opc = in->opc;
106 
107  return Opc_in_tbl(vex_op4_tbl);
108 }
109 
110 static bool
111 vex5_op4(void* seq)
112 {
113  apm_c5_t* in = seq;
114  uc opc = in->opc;
115 
116  return Opc_in_tbl(vex_op4_tbl);
117 }
118 
119 static size_t
120 op4_imm(void* seq)
121 {
122  uc* in = seq;
123 
124  bool has4 = false;
125  if (*in == 0xc4)
126  has4 = vex_op4(seq);
127  if (*in == 0xc5)
128  has4 = vex5_op4(seq);
129  if (*in == 0x8f)
130  has4 = xop_op4(seq);
131 
132  return has4 ? 1 : 0;
133 }
134 
135 static size_t
136 disp_size(void* seq)
137 {
138  uc* escape = seq;
139  size_t rv = 0;
140  uc mod = 0xff;
141  uc r_m = 0xff;
142 
143  if ((*escape == 0xc4) || (*escape == 0x8f)) {
144  apm_t* in = seq;
145  mod = in->mod;
146  r_m = in->r_m;
147  }
148  if (*escape == 0xc5) {
149  apm_c5_t* in = seq;
150  mod = in->mod;
151  r_m = in->r_m;
152  }
153 
154  if ((mod == 0) && (r_m == 5)) rv = 4;
155  else if (mod == 1) rv = 1;
156  else if (mod == 2) rv = 4;
157 
158  return rv;
159 }
160 
161 static size_t
162 sib_byte(void* seq)
163 {
164  uc* escape = seq;
165  uc r_m = 0xff;
166  uc mod = 0xff;
167 
168  if ((*escape == 0xc4) || (*escape == 0x8f)) {
169  apm_t* in = seq;
170  mod = in->mod;
171  r_m = in->r_m;
172  }
173  if (*escape == 0xc5) {
174  apm_c5_t* in = seq;
175  mod = in->mod;
176  r_m = in->r_m;
177  }
178 
179  return (mod != 3) && (r_m == 4) ? 1 : 0;
180 }
181 
182 static size_t
183 escape_len(void* seq)
184 {
185  uc* escape = seq;
186 
187  if ((*escape == 0xc4) || (*escape == 0x8f))
188  return sizeof(apm_t);
189  if (*escape == 0xc5)
190  return sizeof(apm_c5_t);
191 
192  return 1;
193 }
194 
195 static inline size_t
196 ins_len(void* seq)
197 {
198  // length of instruction = size of escape seq + #immediate bytes + # disp bytes + # sib bytes
199  return escape_len(seq) + op4_imm(seq) + disp_size(seq) + sib_byte(seq);
200 }
201 
202 static const uc prefix_tbl[] = {
203  0x66, // op size override
204  0x67, // addr size override
205  0x2e, 0x3e, 0x26, 0x64, 0x65, 0x36, // segment override
206  0xf0, // lock
207  0xf2, 0xf3, // repeat
208 };
209 
210 static bool
211 is_prefix(void* ins)
212 {
213  uc* in = ins;
214  for (int i = 0; i < sizeof(prefix_tbl); i++) {
215  if (*in ==prefix_tbl[i]) return true;
216  }
217  return false;
218 }
219 
220 void
221 adv_amd_decode(amd_decode_t* stat, void* ins)
222 {
223  uc* in = ins;
224  stat->len = 0;
225  // skip standard prefixes
226  for (int i = 0; i < 4; i++) {
227  if (is_prefix(in)) {
228  in++;
229  (stat->len)++;
230  }
231  else break;
232  }
233  stat->success = false;
234  stat->weak = false;
235 
236  if (*in == 0xc4) {
237  stat->success = true;
238  }
239  if (*in == 0x8f) {
240  stat->success = true;
241  stat->weak = true;
242  }
243 
244  stat->len += ins_len(in);
245 }
bool weak
Definition: amd-xop.h:9
static bool xop_op4(void *seq)
Definition: amd-xop.c:93
static size_t ins_len(void *seq)
Definition: amd-xop.c:196
void adv_amd_decode(amd_decode_t *stat, void *ins)
Definition: amd-xop.c:227
uc r_m
Definition: amd-xop.c:27
uc opc
Definition: amd-xop.c:14
bool success
Definition: amd-xop.h:8
static bool opc_in_table(uc opc, const uc opc_tbl[], const size_t len)
Definition: amd-xop.c:85
static size_t sib_byte(void *seq)
Definition: amd-xop.c:162
static size_t escape_len(void *seq)
Definition: amd-xop.c:183
uc mod
Definition: amd-xop.c:29
static bool vex5_op4(void *seq)
Definition: amd-xop.c:111
uc r_m
Definition: amd-xop.c:15
static size_t disp_size(void *seq)
Definition: amd-xop.c:136
static const uc xop_op4_tbl[]
Definition: amd-xop.c:57
static bool is_prefix(void *ins)
Definition: amd-xop.c:211
uc opc
Definition: amd-xop.c:26
static bool vex_op4(void *seq)
Definition: amd-xop.c:102
#define Opc_in_tbl(t)
Definition: amd-xop.c:82
size_t len
Definition: amd-xop.h:10
uc mod
Definition: amd-xop.c:17
static const uc prefix_tbl[]
Definition: amd-xop.c:202
static const uc vex_op4_tbl[]
Definition: amd-xop.c:32
unsigned char uc
Definition: amd-xop.c:3
static size_t op4_imm(void *seq)
Definition: amd-xop.c:120
Definition: amd-xop.c:4