Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added stos instruction to the emulator
[palacios.git] / palacios / src / palacios / vmm_xed.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #ifdef __DECODER_TEST__
21 #include "vmm_decoder.h"
22 #include "vmm_xed.h"
23 #include <xed/xed-interface.h>
24 #include "vm_guest.h"
25 #include "test.h"
26
27 #else
28
29 #include <palacios/vmm_decoder.h>
30 #include <palacios/vmm_xed.h>
31 #include <xed/xed-interface.h>
32 #include <palacios/vm_guest.h>
33 #include <palacios/vmm.h>
34 #endif
35
36
37
38 #ifndef DEBUG_XED
39 #undef PrintDebug
40 #define PrintDebug(fmt, args...)
41 #endif
42
43
44
45
46 static uint_t tables_inited = 0;
47
48
49 #define GPR_REGISTER     0
50 #define SEGMENT_REGISTER 1
51 #define CTRL_REGISTER    2
52 #define DEBUG_REGISTER   3
53
54
55
56 /* Disgusting mask hack...
57    I can't think right now, so we'll do it this way...
58 */
59 static const ullong_t mask_1 = 0x00000000000000ffLL;
60 static const ullong_t mask_2 = 0x000000000000ffffLL;
61 static const ullong_t mask_4 = 0x00000000ffffffffLL;
62 static const ullong_t mask_8 = 0xffffffffffffffffLL;
63
64
65 #define MASK(val, length) ({                    \
66       ullong_t mask = 0x0LL;                    \
67       switch (length) {                         \
68       case 1:                                   \
69         mask = mask_1;                          \
70         break;                                  \
71       case 2:                                   \
72         mask = mask_2;                          \
73         break;                                  \
74       case 4:                                   \
75         mask = mask_4;                          \
76         break;                                  \
77       case 8:                                   \
78         mask = mask_8;                          \
79         break;                                  \
80       }                                         \
81       val & mask;})                             \
82
83 struct memory_operand {
84   uint_t segment_size;
85   addr_t segment;
86   uint_t base_size;
87   addr_t base;
88   uint_t index_size;
89   addr_t index;
90   addr_t scale;
91   uint_t displacement_size;
92   ullong_t displacement;
93 };
94
95
96
97
98 static v3_op_type_t get_opcode(xed_iform_enum_t iform);
99
100 static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len);
101 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
102
103 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
104   switch (info->cpu_mode) {
105   case REAL:
106     if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
107       xed_state_init(state,
108                      XED_MACHINE_MODE_LEGACY_16, 
109                      XED_ADDRESS_WIDTH_16b, 
110                      XED_ADDRESS_WIDTH_16b); 
111     }
112    break;
113   case PROTECTED:
114   case PROTECTED_PAE:
115     if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
116       xed_state_init(state,
117                      XED_MACHINE_MODE_LEGACY_32, 
118                      XED_ADDRESS_WIDTH_32b, 
119                      XED_ADDRESS_WIDTH_32b);
120     }
121     break;
122   case LONG_32_COMPAT:
123     if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
124       xed_state_init(state,
125                      XED_MACHINE_MODE_LONG_COMPAT_32, 
126                      XED_ADDRESS_WIDTH_32b, 
127                      XED_ADDRESS_WIDTH_32b);
128     }
129     break;
130   case LONG:
131     if (state->mmode != XED_MACHINE_MODE_LONG_64) {
132       PrintDebug("Setting decoder to long mode\n");
133       //      state->mmode = XED_MACHINE_MODE_LONG_64;
134       //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
135       xed_state_init(state,
136                      XED_MACHINE_MODE_LONG_64, 
137                      XED_ADDRESS_WIDTH_64b, 
138                      XED_ADDRESS_WIDTH_64b);
139     }
140     break;
141   default:
142     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
143     return -1;
144   }
145   return 0;
146 }
147
148 static int is_flags_reg(xed_reg_enum_t xed_reg) {
149   switch (xed_reg) {
150   case XED_REG_FLAGS:
151   case XED_REG_EFLAGS:
152   case XED_REG_RFLAGS:
153     return 1;
154   default:
155     return 0;
156   }
157 }
158
159
160
161 int v3_init_decoder(struct guest_info * info) {
162   // Global library initialization, only do it once
163   if (tables_inited == 0) {
164     xed_tables_init();
165     tables_inited = 1;
166   }
167
168   xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
169   xed_state_zero(decoder_state);
170   xed_state_init(decoder_state,
171                  XED_MACHINE_MODE_LEGACY_32, 
172                  XED_ADDRESS_WIDTH_32b, 
173                  XED_ADDRESS_WIDTH_32b);
174
175   info->decoder_state = decoder_state;
176
177   return 0;
178 }
179
180
181
182 int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
183   xed_decoded_inst_t xed_instr;
184   xed_error_enum_t xed_error;
185   
186
187   if (set_decoder_mode(info, info->decoder_state) == -1) {
188     PrintError("Could not set decoder mode\n");
189     return -1;
190   }
191
192
193   xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
194
195   xed_error = xed_decode(&xed_instr, 
196                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
197                          XED_MAX_INSTRUCTION_BYTES);
198
199   if (xed_error != XED_ERROR_NONE) {
200     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
201     return -1;
202   }
203
204   instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
205
206
207  if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
208    PrintError("Tried to decode memory operation with no memory operands\n");
209    return -1;
210  }
211
212  instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
213
214
215  xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
216  if (cat == XED_CATEGORY_STRINGOP) {
217    instr_info->str_op = 1;
218  } else {
219    instr_info->str_op = 0;
220  }
221
222  xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
223  if (xed_operand_values_has_real_rep(operands)) {
224    instr_info->has_rep = 1;
225  } else {
226    instr_info->has_rep = 0;
227  }
228
229  return 0;
230 }
231
232
233 static int decode_string_op(struct guest_info * info, 
234                             xed_decoded_inst_t * xed_instr,  const xed_inst_t * xi,
235                             struct x86_instr * instr) {
236
237   PrintDebug("String operation\n");
238
239   if (instr->op_type == V3_OP_MOVS) {
240     instr->num_operands = 2;
241
242     if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
243       PrintError("Could not get Destination memory operand\n");
244       return -1;
245     }
246
247     if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
248       PrintError("Could not get Source memory operand\n");
249       return -1;
250     }
251
252     if (instr->prefixes.rep == 1) {
253       addr_t reg_addr = 0;
254       uint_t reg_length = 0;
255
256       xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), &reg_addr, &reg_length);
257       instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
258     } else {
259       instr->str_op_length = 1;
260     }
261
262   } else if (instr->op_type == V3_OP_STOS) {
263     instr->num_operands = 2;
264
265     if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
266       PrintError("Could not get Destination memory operand\n");
267       return -1;
268     }
269
270     // STOS reads from rax
271     xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), 
272                       &(instr->src_operand.operand), 
273                       &(instr->src_operand.size));
274     instr->src_operand.type = REG_OPERAND;
275     
276     if (instr->prefixes.rep == 1) {
277       addr_t reg_addr = 0;
278       uint_t reg_length = 0;
279
280       xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), &reg_addr, &reg_length);
281       instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
282     } else {
283       instr->str_op_length = 1;
284     }
285
286   } else {
287     PrintError("Unhandled String OP\n");
288     return -1;
289   }
290
291   return 0;
292 }
293
294
295
296 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
297   xed_decoded_inst_t xed_instr;
298   xed_error_enum_t xed_error;
299
300
301   v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
302
303   if (set_decoder_mode(info, info->decoder_state) == -1) {
304     PrintError("Could not set decoder mode\n");
305     return -1;
306   }
307
308   xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
309
310   xed_error = xed_decode(&xed_instr, 
311                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
312                          XED_MAX_INSTRUCTION_BYTES);
313
314
315   if (xed_error != XED_ERROR_NONE) {
316     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
317     return -1;
318   }
319
320   const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
321   
322   instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
323
324
325   xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
326
327 #ifdef DEBUG_XED
328   xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
329
330   PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
331 #endif
332
333
334   if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
335     PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
336     return -1;
337   }
338
339
340   // We special case the string operations...
341   if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
342     instr->is_str_op = 1;
343     return decode_string_op(info, &xed_instr, xi, instr); 
344   } else {
345     instr->is_str_op = 0;
346     instr->str_op_length = 0;
347   }
348
349
350   instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
351
352   if (instr->num_operands > 3) {
353     PrintDebug("Special Case Not Handled\n");
354     return -1;
355     // special case
356   } else if (instr->num_operands == 3) {
357     const xed_operand_t * op = xed_inst_operand(xi, 2);
358     xed_operand_enum_t op_enum = xed_operand_name(op);
359
360     if ((!xed_operand_is_register(op_enum)) ||
361         (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
362       // special case
363       PrintError("Special Case not handled\n");
364       return -1;
365     }
366   }
367
368
369
370   //PrintDebug("Number of operands: %d\n", instr->num_operands);
371   //PrintDebug("INSTR length: %d\n", instr->instr_length);
372
373   // set first operand
374   if (instr->num_operands >= 1) {
375     const xed_operand_t * op = xed_inst_operand(xi, 0);
376     xed_operand_enum_t op_enum = xed_operand_name(op);
377
378     struct x86_operand * v3_op = NULL;
379
380     if (xed_operand_written(op)) {
381       v3_op = &(instr->dst_operand);
382     } else {
383       v3_op = &(instr->src_operand);
384     }
385
386
387     if (xed_operand_is_register(op_enum)) {
388       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
389       int v3_reg_type = xed_reg_to_v3_reg(info, 
390                                           xed_reg, 
391                                           &(v3_op->operand), 
392                                           &(v3_op->size));
393
394       if (v3_reg_type == -1) {
395         PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
396         v3_op->type = INVALID_OPERAND;
397         return -1;
398       } else if (v3_reg_type == SEGMENT_REGISTER) {
399         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
400         v3_op->operand = (addr_t)&(seg_reg->selector);
401       }
402
403       v3_op->type = REG_OPERAND;
404     } else {
405
406       switch (op_enum) {
407
408       case XED_OPERAND_MEM0:
409         {
410           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
411             PrintError("Could not get first memory operand\n");
412             return -1;
413           }
414         }
415         break;
416
417       case XED_OPERAND_MEM1:
418       case XED_OPERAND_IMM1:
419         // illegal
420         PrintError("Illegal Operand Order\n");
421         return -1;
422
423
424       case XED_OPERAND_IMM0:
425       case XED_OPERAND_AGEN:
426       case XED_OPERAND_PTR:
427       case XED_OPERAND_RELBR:
428       default:
429         PrintError("Unhandled Operand Type\n");
430         return -1;
431
432
433       }
434     }
435   }
436
437   // set second operand
438   if (instr->num_operands >= 2) {
439     const xed_operand_t * op = xed_inst_operand(xi, 1);
440     //   xed_operand_type_enum_t op_type = xed_operand_type(op);
441     xed_operand_enum_t op_enum = xed_operand_name(op);
442     
443     struct x86_operand * v3_op;
444
445     if (xed_operand_written(op)) {
446       v3_op = &(instr->dst_operand);
447     } else {
448       v3_op = &(instr->src_operand);
449     }
450
451
452     if (xed_operand_is_register(op_enum)) {
453       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
454       int v3_reg_type = xed_reg_to_v3_reg(info, 
455                                           xed_reg, 
456                                           &(v3_op->operand), 
457                                           &(v3_op->size));
458       if (v3_reg_type == -1) {
459         PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
460         v3_op->type = INVALID_OPERAND;
461         return -1;
462       } else if (v3_reg_type == SEGMENT_REGISTER) {
463         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
464         v3_op->operand = (addr_t)&(seg_reg->selector);
465       }
466
467       v3_op->type = REG_OPERAND;
468     
469
470     } else {
471
472       switch (op_enum) {
473
474       case XED_OPERAND_MEM0:
475         {
476           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
477             PrintError("Could not get first memory operand\n");
478             return -1;
479           }
480         }
481         break;
482
483       case XED_OPERAND_IMM0:
484         {
485           instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
486
487           if (instr->src_operand.size > 4) {
488             PrintError("Unhandled 64 bit immediates\n");
489             return -1;
490           }
491           instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
492
493           instr->src_operand.type = IMM_OPERAND;
494
495         }
496         break;
497
498       case XED_OPERAND_MEM1:
499       case XED_OPERAND_IMM1:
500         // illegal
501         PrintError("Illegal Operand Order\n");
502         return -1;
503         
504       case XED_OPERAND_AGEN:
505       case XED_OPERAND_PTR:
506       case XED_OPERAND_RELBR:
507       default:
508         PrintError("Unhandled Operand Type\n");
509         return -1;
510       }
511     }
512
513   }
514
515   // set third operand
516   if (instr->num_operands >= 3) {
517     const xed_operand_t * op = xed_inst_operand(xi, 2);
518     xed_operand_type_enum_t op_type = xed_operand_type(op);
519     xed_operand_enum_t op_enum = xed_operand_name(op);
520
521     if (xed_operand_is_register(op_enum)) {
522       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
523       int v3_reg_type = xed_reg_to_v3_reg(info, 
524                                           xed_reg, 
525                                           &(instr->third_operand.operand), 
526                                           &(instr->third_operand.size));
527
528       if (v3_reg_type == -1) {
529         PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
530         instr->third_operand.type = INVALID_OPERAND;
531         return -1;
532       } else if (v3_reg_type == SEGMENT_REGISTER) {
533         struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
534         instr->third_operand.operand = (addr_t)&(seg_reg->selector);
535       }
536
537
538       instr->third_operand.type = REG_OPERAND;
539
540
541     } else {
542       PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
543       return -1;
544     }
545
546
547   }
548
549
550
551     return 0;
552 }
553
554
555 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
556
557   return -1;
558 }
559
560
561
562
563
564 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
565   struct memory_operand mem_op;
566
567   addr_t seg;
568   addr_t base;
569   addr_t scale;
570   addr_t index;
571   ullong_t displacement;
572   // struct v3_segment * seg_reg;
573
574   PrintDebug("Xen mode = %s\n", xed_machine_mode_enum_t2str(xed_state_get_machine_mode(info->decoder_state)));
575   PrintDebug("Address width: %s\n",
576              xed_address_width_enum_t2str(xed_state_get_address_width(info->decoder_state)));
577   PrintDebug("Stack Address width: %s\n",
578              xed_address_width_enum_t2str(xed_state_get_stack_address_width(info->decoder_state)));
579
580   memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
581
582   xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
583   if (xed_seg != XED_REG_INVALID) {
584     struct v3_segment *tmp_segment;
585     if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
586       PrintError("Unhandled Segment Register\n");
587       return -1;
588     }
589     mem_op.segment = tmp_segment->base;
590   }
591
592   xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
593   if (xed_base != XED_REG_INVALID) {
594     addr_t base_reg;
595     if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
596       PrintError("Unhandled Base register\n");
597       return -1;
598     }
599     mem_op.base = *(addr_t *)base_reg;
600   }
601
602   
603
604   xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
605   if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
606     addr_t index_reg;
607     
608     if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
609       PrintError("Unhandled Index Register\n");
610       return -1;
611     }
612
613     mem_op.index= *(addr_t *)index_reg;
614
615     xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
616     if (xed_scale != 0) {
617       mem_op.scale = xed_scale;
618     }
619   }
620
621
622   xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
623   if (disp_bits) {
624     xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
625
626     mem_op.displacement_size = disp_bits;
627     mem_op.displacement = xed_disp;
628   }
629
630   operand->type = MEM_OPERAND;
631   operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
632   
633   
634
635   PrintDebug("Struct: Seg=%p (size=%d), base=%p, index=%p, scale=%p, displacement=%p (size=%d)\n", 
636              (void *)mem_op.segment, mem_op.segment_size, (void*)mem_op.base, (void *)mem_op.index, 
637              (void *)mem_op.scale, (void *)(addr_t)mem_op.displacement, mem_op.displacement_size);
638
639
640   PrintDebug("operand size: %d\n", operand->size);
641
642   seg = MASK(mem_op.segment, mem_op.segment_size);
643   base = MASK(mem_op.base, mem_op.base_size);
644   index = MASK(mem_op.index, mem_op.index_size);
645   scale = mem_op.scale;
646   // displacement = MASK(mem_op.displacement, mem_op.displacement_size);
647   displacement = mem_op.displacement;
648
649   PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", 
650              (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
651   
652   operand->operand = seg + base + (scale * index) + displacement;
653   return 0;
654 }
655
656
657 static int xed_reg_to_v3_reg(struct guest_info * info, xed_reg_enum_t xed_reg, addr_t * v3_reg, uint_t * reg_len) {
658
659   PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
660
661   switch (xed_reg) {
662   case XED_REG_INVALID:
663     *v3_reg = 0;
664     *reg_len = 0;
665     return -1;
666
667     /* 
668      * GPRs
669      */
670   case XED_REG_RAX: 
671     *v3_reg = (addr_t)&(info->vm_regs.rax);
672     *reg_len = 8;
673     return GPR_REGISTER;
674   case XED_REG_EAX:
675     *v3_reg = (addr_t)&(info->vm_regs.rax);
676     *reg_len = 4;
677     return GPR_REGISTER;
678   case XED_REG_AX:
679     *v3_reg = (addr_t)&(info->vm_regs.rax);
680     *reg_len = 2;
681     return GPR_REGISTER;
682   case XED_REG_AH:
683     *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
684     *reg_len = 1;
685     return GPR_REGISTER;
686   case XED_REG_AL:
687     *v3_reg = (addr_t)&(info->vm_regs.rax);
688     *reg_len = 1;
689     return GPR_REGISTER;
690
691   case XED_REG_RCX: 
692     *v3_reg = (addr_t)&(info->vm_regs.rcx);
693     *reg_len = 8;
694     return GPR_REGISTER;
695   case XED_REG_ECX:
696     *v3_reg = (addr_t)&(info->vm_regs.rcx);
697     *reg_len = 4;
698     return GPR_REGISTER;
699   case XED_REG_CX:
700     *v3_reg = (addr_t)&(info->vm_regs.rcx);
701     *reg_len = 2;
702     return GPR_REGISTER;
703   case XED_REG_CH:
704     *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
705     *reg_len = 1;
706     return GPR_REGISTER;
707   case XED_REG_CL:
708     *v3_reg = (addr_t)&(info->vm_regs.rcx);
709     *reg_len = 1;
710     return GPR_REGISTER;
711
712   case XED_REG_RDX: 
713     *v3_reg = (addr_t)&(info->vm_regs.rdx);
714     *reg_len = 8;
715     return GPR_REGISTER;
716   case XED_REG_EDX:
717     *v3_reg = (addr_t)&(info->vm_regs.rdx);
718     *reg_len = 4;
719     return GPR_REGISTER;
720   case XED_REG_DX:
721     *v3_reg = (addr_t)&(info->vm_regs.rdx);
722     *reg_len = 2;
723     return GPR_REGISTER;
724   case XED_REG_DH:
725     *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
726     *reg_len = 1;
727     return GPR_REGISTER;
728   case XED_REG_DL:
729     *v3_reg = (addr_t)&(info->vm_regs.rdx);
730     *reg_len = 1;
731     return GPR_REGISTER;
732
733   case XED_REG_RBX: 
734     *v3_reg = (addr_t)&(info->vm_regs.rbx);
735     *reg_len = 8;
736     return GPR_REGISTER;
737   case XED_REG_EBX:
738     *v3_reg = (addr_t)&(info->vm_regs.rbx);
739     *reg_len = 4;
740     return GPR_REGISTER;
741   case XED_REG_BX:
742     *v3_reg = (addr_t)&(info->vm_regs.rbx);
743     *reg_len = 2;
744     return GPR_REGISTER;
745   case XED_REG_BH:
746     *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
747     *reg_len = 1;
748     return GPR_REGISTER;
749   case XED_REG_BL:
750     *v3_reg = (addr_t)&(info->vm_regs.rbx);
751     *reg_len = 1;
752     return GPR_REGISTER;
753
754
755   case XED_REG_RSP:
756     *v3_reg = (addr_t)&(info->vm_regs.rsp);
757     *reg_len = 8;
758     return GPR_REGISTER;
759   case XED_REG_ESP:
760     *v3_reg = (addr_t)&(info->vm_regs.rsp);
761     *reg_len = 4;
762     return GPR_REGISTER;
763   case XED_REG_SP:
764     *v3_reg = (addr_t)&(info->vm_regs.rsp);
765     *reg_len = 2;
766     return GPR_REGISTER;
767   case XED_REG_SPL:
768     *v3_reg = (addr_t)&(info->vm_regs.rsp);
769     *reg_len = 1;
770     return GPR_REGISTER;
771
772   case XED_REG_RBP:
773     *v3_reg = (addr_t)&(info->vm_regs.rbp);
774     *reg_len = 8;
775     return GPR_REGISTER;
776   case XED_REG_EBP:
777     *v3_reg = (addr_t)&(info->vm_regs.rbp);
778     *reg_len = 4;
779     return GPR_REGISTER;
780   case XED_REG_BP:
781     *v3_reg = (addr_t)&(info->vm_regs.rbp);
782     *reg_len = 2;
783     return GPR_REGISTER;
784   case XED_REG_BPL:
785     *v3_reg = (addr_t)&(info->vm_regs.rbp);
786     *reg_len = 1;
787     return GPR_REGISTER;
788
789
790
791   case XED_REG_RSI:
792     *v3_reg = (addr_t)&(info->vm_regs.rsi);
793     *reg_len = 8;
794     return GPR_REGISTER;
795   case XED_REG_ESI:
796     *v3_reg = (addr_t)&(info->vm_regs.rsi);
797     *reg_len = 4;
798     return GPR_REGISTER;
799   case XED_REG_SI:
800     *v3_reg = (addr_t)&(info->vm_regs.rsi);
801     *reg_len = 2;
802     return GPR_REGISTER;
803   case XED_REG_SIL:
804     *v3_reg = (addr_t)&(info->vm_regs.rsi);
805     *reg_len = 1;
806     return GPR_REGISTER;
807
808
809   case XED_REG_RDI:
810     *v3_reg = (addr_t)&(info->vm_regs.rdi);
811     *reg_len = 8;
812     return GPR_REGISTER;
813   case XED_REG_EDI:
814     *v3_reg = (addr_t)&(info->vm_regs.rdi);
815     *reg_len = 4;
816     return GPR_REGISTER;
817   case XED_REG_DI:
818     *v3_reg = (addr_t)&(info->vm_regs.rdi);
819     *reg_len = 2;
820     return GPR_REGISTER;
821   case XED_REG_DIL:
822     *v3_reg = (addr_t)&(info->vm_regs.rdi);
823     *reg_len = 1;
824     return GPR_REGISTER;
825
826
827
828
829
830   case XED_REG_R8:
831     *v3_reg = (addr_t)&(info->vm_regs.r8);
832     *reg_len = 8;
833     return GPR_REGISTER;
834   case XED_REG_R8D:
835     *v3_reg = (addr_t)&(info->vm_regs.r8);
836     *reg_len = 4;
837     return GPR_REGISTER;
838   case XED_REG_R8W:
839     *v3_reg = (addr_t)&(info->vm_regs.r8);
840     *reg_len = 2;
841     return GPR_REGISTER;
842   case XED_REG_R8B:
843     *v3_reg = (addr_t)&(info->vm_regs.r8);
844     *reg_len = 1;
845     return GPR_REGISTER;
846
847   case XED_REG_R9:
848     *v3_reg = (addr_t)&(info->vm_regs.r9);
849     *reg_len = 8;
850     return GPR_REGISTER;
851   case XED_REG_R9D:
852     *v3_reg = (addr_t)&(info->vm_regs.r9);
853     *reg_len = 4;
854     return GPR_REGISTER;
855   case XED_REG_R9W:
856     *v3_reg = (addr_t)&(info->vm_regs.r9);
857     *reg_len = 2;
858     return GPR_REGISTER;
859   case XED_REG_R9B:
860     *v3_reg = (addr_t)&(info->vm_regs.r9);
861     *reg_len = 1;
862     return GPR_REGISTER;
863
864   case XED_REG_R10:
865     *v3_reg = (addr_t)&(info->vm_regs.r10);
866     *reg_len = 8;
867     return GPR_REGISTER;
868   case XED_REG_R10D:
869     *v3_reg = (addr_t)&(info->vm_regs.r10);
870     *reg_len = 4;
871     return GPR_REGISTER;
872   case XED_REG_R10W:
873     *v3_reg = (addr_t)&(info->vm_regs.r10);
874     *reg_len = 2;
875     return GPR_REGISTER;
876   case XED_REG_R10B:
877     *v3_reg = (addr_t)&(info->vm_regs.r10);
878     *reg_len = 1;
879     return GPR_REGISTER;
880
881   case XED_REG_R11:
882     *v3_reg = (addr_t)&(info->vm_regs.r11);
883     *reg_len = 8;
884     return GPR_REGISTER;
885   case XED_REG_R11D:
886     *v3_reg = (addr_t)&(info->vm_regs.r11);
887     *reg_len = 4;
888     return GPR_REGISTER;
889   case XED_REG_R11W:
890     *v3_reg = (addr_t)&(info->vm_regs.r11);
891     *reg_len = 2;
892     return GPR_REGISTER;
893   case XED_REG_R11B:
894     *v3_reg = (addr_t)&(info->vm_regs.r11);
895     *reg_len = 1;
896     return GPR_REGISTER;
897
898   case XED_REG_R12:
899     *v3_reg = (addr_t)&(info->vm_regs.r12);
900     *reg_len = 8;
901     return GPR_REGISTER;
902   case XED_REG_R12D:
903     *v3_reg = (addr_t)&(info->vm_regs.r12);
904     *reg_len = 4;
905     return GPR_REGISTER;
906   case XED_REG_R12W:
907     *v3_reg = (addr_t)&(info->vm_regs.r12);
908     *reg_len = 2;
909     return GPR_REGISTER;
910   case XED_REG_R12B:
911     *v3_reg = (addr_t)&(info->vm_regs.r12);
912     *reg_len = 1;
913     return GPR_REGISTER;
914
915   case XED_REG_R13:
916     *v3_reg = (addr_t)&(info->vm_regs.r13);
917     *reg_len = 8;
918     return GPR_REGISTER;
919   case XED_REG_R13D:
920     *v3_reg = (addr_t)&(info->vm_regs.r13);
921     *reg_len = 4;
922     return GPR_REGISTER;
923   case XED_REG_R13W:
924     *v3_reg = (addr_t)&(info->vm_regs.r13);
925     *reg_len = 2;
926     return GPR_REGISTER;
927   case XED_REG_R13B:
928     *v3_reg = (addr_t)&(info->vm_regs.r13);
929     *reg_len = 1;
930     return GPR_REGISTER;
931
932   case XED_REG_R14:
933     *v3_reg = (addr_t)&(info->vm_regs.r14);
934     *reg_len = 8;
935     return GPR_REGISTER;
936   case XED_REG_R14D:
937     *v3_reg = (addr_t)&(info->vm_regs.r14);
938     *reg_len = 4;
939     return GPR_REGISTER;
940   case XED_REG_R14W:
941     *v3_reg = (addr_t)&(info->vm_regs.r14);
942     *reg_len = 2;
943     return GPR_REGISTER;
944   case XED_REG_R14B:
945     *v3_reg = (addr_t)&(info->vm_regs.r14);
946     *reg_len = 1;
947     return GPR_REGISTER;
948
949   case XED_REG_R15:
950     *v3_reg = (addr_t)&(info->vm_regs.r15);
951     *reg_len = 8;
952     return GPR_REGISTER;
953   case XED_REG_R15D:
954     *v3_reg = (addr_t)&(info->vm_regs.r15);
955     *reg_len = 4;
956     return GPR_REGISTER;
957   case XED_REG_R15W:
958     *v3_reg = (addr_t)&(info->vm_regs.r15);
959     *reg_len = 2;
960     return GPR_REGISTER;
961   case XED_REG_R15B:
962     *v3_reg = (addr_t)&(info->vm_regs.r15);
963     *reg_len = 1;
964     return GPR_REGISTER;
965
966
967     /* 
968      *  CTRL REGS
969      */
970   case XED_REG_RIP:
971     *v3_reg = (addr_t)&(info->rip);
972     *reg_len = 8;
973     return CTRL_REGISTER;
974   case XED_REG_EIP:
975     *v3_reg = (addr_t)&(info->rip);
976     *reg_len = 4;
977     return CTRL_REGISTER;  
978   case XED_REG_IP:
979     *v3_reg = (addr_t)&(info->rip);
980     *reg_len = 2;
981     return CTRL_REGISTER;
982
983   case XED_REG_FLAGS:
984     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
985     *reg_len = 2;
986     return CTRL_REGISTER;
987   case XED_REG_EFLAGS:
988     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
989     *reg_len = 4;
990     return CTRL_REGISTER;
991   case XED_REG_RFLAGS:
992     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
993     *reg_len = 8;
994     return CTRL_REGISTER;
995
996   case XED_REG_CR0:
997     *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
998     *reg_len = 4;
999     return CTRL_REGISTER;
1000   case XED_REG_CR2:
1001     *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
1002     *reg_len = 4;
1003     return CTRL_REGISTER;
1004   case XED_REG_CR3:
1005     *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
1006     *reg_len = 4;
1007     return CTRL_REGISTER;
1008   case XED_REG_CR4:
1009     *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
1010    *reg_len = 4;
1011     return CTRL_REGISTER;
1012   case XED_REG_CR8:
1013     *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
1014     *reg_len = 4;
1015     return CTRL_REGISTER;
1016
1017   case XED_REG_CR1:
1018   case XED_REG_CR5:
1019   case XED_REG_CR6:
1020   case XED_REG_CR7:
1021   case XED_REG_CR9:
1022   case XED_REG_CR10:
1023   case XED_REG_CR11:
1024   case XED_REG_CR12:
1025   case XED_REG_CR13:
1026   case XED_REG_CR14:
1027   case XED_REG_CR15:
1028     return -1;
1029
1030
1031
1032
1033     /* 
1034      * SEGMENT REGS
1035      */
1036   case XED_REG_CS:
1037     *v3_reg = (addr_t)&(info->segments.cs);
1038     *reg_len = 8;
1039     return SEGMENT_REGISTER;
1040   case XED_REG_DS:
1041     *v3_reg = (addr_t)&(info->segments.ds);
1042     *reg_len = 8;
1043     return SEGMENT_REGISTER;
1044   case XED_REG_ES:
1045     *v3_reg = (addr_t)&(info->segments.es);
1046     *reg_len = 8;
1047     return SEGMENT_REGISTER;
1048   case XED_REG_SS:
1049     *v3_reg = (addr_t)&(info->segments.ss);
1050     *reg_len = 8;
1051     return SEGMENT_REGISTER;
1052   case XED_REG_FS:
1053     *v3_reg = (addr_t)&(info->segments.fs);
1054     *reg_len = 8;
1055     return SEGMENT_REGISTER;
1056   case XED_REG_GS:
1057     *v3_reg = (addr_t)&(info->segments.gs);
1058     *reg_len = 8;
1059     return SEGMENT_REGISTER;
1060
1061
1062   case XED_REG_GDTR:
1063   case XED_REG_LDTR:
1064   case XED_REG_IDTR:
1065   case XED_REG_TR:
1066     PrintError("Segment selector operand... Don't know how to handle this...\n");
1067     return -1;
1068
1069     /* 
1070      *  DEBUG REGS
1071      */
1072   case XED_REG_DR0:
1073   case XED_REG_DR1:
1074   case XED_REG_DR2:
1075   case XED_REG_DR3:
1076   case XED_REG_DR4:
1077   case XED_REG_DR5:
1078   case XED_REG_DR6:
1079   case XED_REG_DR7:
1080   case XED_REG_DR8:
1081   case XED_REG_DR9:
1082   case XED_REG_DR10:
1083   case XED_REG_DR11:
1084   case XED_REG_DR12:
1085   case XED_REG_DR13:
1086   case XED_REG_DR14:
1087   case XED_REG_DR15:
1088     return -1;
1089
1090
1091
1092
1093
1094
1095   case XED_REG_XMM0:
1096   case XED_REG_XMM1:
1097   case XED_REG_XMM2:
1098   case XED_REG_XMM3:
1099   case XED_REG_XMM4:
1100   case XED_REG_XMM5:
1101   case XED_REG_XMM6:
1102   case XED_REG_XMM7:
1103   case XED_REG_XMM8:
1104   case XED_REG_XMM9:
1105   case XED_REG_XMM10:
1106   case XED_REG_XMM11:
1107   case XED_REG_XMM12:
1108   case XED_REG_XMM13:
1109   case XED_REG_XMM14:
1110   case XED_REG_XMM15:
1111
1112   case XED_REG_MMX0:
1113   case XED_REG_MMX1:
1114   case XED_REG_MMX2:
1115   case XED_REG_MMX3:
1116   case XED_REG_MMX4:
1117   case XED_REG_MMX5:
1118   case XED_REG_MMX6:
1119   case XED_REG_MMX7:
1120
1121   case XED_REG_ST0:
1122   case XED_REG_ST1:
1123   case XED_REG_ST2:
1124   case XED_REG_ST3:
1125   case XED_REG_ST4:
1126   case XED_REG_ST5:
1127   case XED_REG_ST6:
1128   case XED_REG_ST7:
1129
1130   case XED_REG_ONE:
1131   case XED_REG_STACKPUSH:
1132   case XED_REG_STACKPOP:
1133     
1134   case XED_REG_TSC:
1135   case XED_REG_TSCAUX:
1136   case XED_REG_MSRS:
1137
1138   case XED_REG_X87CONTROL:
1139   case XED_REG_X87STATUS:
1140   case XED_REG_X87TOP:
1141   case XED_REG_X87TAG:
1142   case XED_REG_X87PUSH:
1143   case XED_REG_X87POP:
1144   case XED_REG_X87POP2:
1145
1146   case XED_REG_MXCSR:
1147
1148   case XED_REG_TMP0:
1149   case XED_REG_TMP1:
1150   case XED_REG_TMP2:
1151   case XED_REG_TMP3:
1152   case XED_REG_TMP4:
1153   case XED_REG_TMP5:
1154   case XED_REG_TMP6:
1155   case XED_REG_TMP7:
1156   case XED_REG_TMP8:
1157   case XED_REG_TMP9:
1158   case XED_REG_TMP10:
1159   case XED_REG_TMP11:
1160   case XED_REG_TMP12:
1161   case XED_REG_TMP13:
1162   case XED_REG_TMP14:
1163   case XED_REG_TMP15:
1164
1165   case XED_REG_LAST:
1166
1167   case XED_REG_ERROR:
1168     // error??
1169     return -1;
1170
1171   }
1172
1173
1174   return 0;
1175 }
1176
1177
1178
1179 static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
1180
1181   switch (iform) {
1182
1183     /* Control Instructions */
1184
1185   case XED_IFORM_MOV_CR_GPR64_CR:
1186   case XED_IFORM_MOV_CR_GPR32_CR:
1187     return V3_OP_MOVCR2;
1188
1189   case XED_IFORM_MOV_CR_CR_GPR64:
1190   case XED_IFORM_MOV_CR_CR_GPR32:
1191     return V3_OP_MOV2CR;
1192
1193   case XED_IFORM_SMSW_GPRv:
1194     return V3_OP_SMSW;
1195
1196   case XED_IFORM_LMSW_GPR16:
1197     return V3_OP_LMSW;
1198
1199   case XED_IFORM_CLTS:
1200     return V3_OP_CLTS;
1201
1202   case XED_IFORM_INVLPG_MEMb:
1203     return V3_OP_INVLPG;
1204
1205
1206     /* Data Instructions */
1207
1208     // Write
1209   case XED_IFORM_ADC_MEMv_GPRv:
1210   case XED_IFORM_ADC_MEMv_IMM:
1211   case XED_IFORM_ADC_MEMb_GPR8:
1212   case XED_IFORM_ADC_MEMb_IMM:
1213     // Read
1214   case XED_IFORM_ADC_GPRv_MEMv:
1215   case XED_IFORM_ADC_GPR8_MEMb:
1216     return V3_OP_ADC;
1217
1218     // Write
1219   case XED_IFORM_ADD_MEMv_GPRv:
1220   case XED_IFORM_ADD_MEMb_IMM:
1221   case XED_IFORM_ADD_MEMb_GPR8:
1222   case XED_IFORM_ADD_MEMv_IMM:
1223     // Read
1224   case XED_IFORM_ADD_GPRv_MEMv:
1225   case XED_IFORM_ADD_GPR8_MEMb:
1226     return V3_OP_ADD;
1227
1228     // Write
1229   case XED_IFORM_AND_MEMv_IMM:
1230   case XED_IFORM_AND_MEMb_GPR8:
1231   case XED_IFORM_AND_MEMv_GPRv:
1232   case XED_IFORM_AND_MEMb_IMM:
1233     // Read
1234   case XED_IFORM_AND_GPR8_MEMb:
1235   case XED_IFORM_AND_GPRv_MEMv:
1236     return V3_OP_AND;
1237
1238     // Write
1239   case XED_IFORM_SUB_MEMv_IMM:
1240   case XED_IFORM_SUB_MEMb_GPR8:
1241   case XED_IFORM_SUB_MEMb_IMM:
1242   case XED_IFORM_SUB_MEMv_GPRv:
1243     // Read
1244   case XED_IFORM_SUB_GPR8_MEMb:
1245   case XED_IFORM_SUB_GPRv_MEMv:
1246     return V3_OP_SUB;
1247
1248     // Write
1249   case XED_IFORM_MOV_MEMv_GPRv:
1250   case XED_IFORM_MOV_MEMb_GPR8:
1251   case XED_IFORM_MOV_MEMb_AL:
1252   case XED_IFORM_MOV_MEMv_IMM:
1253   case XED_IFORM_MOV_MEMb_IMM:
1254     // Read 
1255   case XED_IFORM_MOV_GPRv_MEMv:
1256   case XED_IFORM_MOV_GPR8_MEMb:
1257   case XED_IFORM_MOV_AL_MEMb:
1258     return V3_OP_MOV;
1259
1260
1261     // Read 
1262   case XED_IFORM_MOVZX_GPRv_MEMb:
1263   case XED_IFORM_MOVZX_GPRv_MEMw:
1264     return V3_OP_MOVZX;
1265
1266     // Read 
1267   case XED_IFORM_MOVSX_GPRv_MEMb:
1268   case XED_IFORM_MOVSX_GPRv_MEMw:
1269     return V3_OP_MOVSX;
1270
1271
1272
1273   case XED_IFORM_DEC_MEMv:
1274   case XED_IFORM_DEC_MEMb:
1275     return V3_OP_DEC;
1276
1277   case XED_IFORM_INC_MEMb:
1278   case XED_IFORM_INC_MEMv:
1279     return V3_OP_INC;
1280
1281     // Write
1282   case XED_IFORM_OR_MEMv_IMM:
1283   case XED_IFORM_OR_MEMb_IMM:
1284   case XED_IFORM_OR_MEMv_GPRv:
1285   case XED_IFORM_OR_MEMb_GPR8:
1286     // Read
1287   case XED_IFORM_OR_GPRv_MEMv:
1288   case XED_IFORM_OR_GPR8_MEMb:
1289     return V3_OP_OR;
1290
1291     // Write
1292   case XED_IFORM_XOR_MEMv_GPRv:
1293   case XED_IFORM_XOR_MEMb_IMM:
1294   case XED_IFORM_XOR_MEMb_GPR8:
1295   case XED_IFORM_XOR_MEMv_IMM:
1296     // Read
1297   case XED_IFORM_XOR_GPRv_MEMv:
1298   case XED_IFORM_XOR_GPR8_MEMb:
1299     return V3_OP_XOR;
1300
1301   case XED_IFORM_NEG_MEMb:
1302   case XED_IFORM_NEG_MEMv:
1303     return V3_OP_NEG;
1304
1305   case XED_IFORM_NOT_MEMv:
1306   case XED_IFORM_NOT_MEMb:
1307     return V3_OP_NOT;
1308
1309   case XED_IFORM_XCHG_MEMv_GPRv:
1310   case XED_IFORM_XCHG_MEMb_GPR8:
1311     return V3_OP_XCHG;
1312
1313   case XED_IFORM_SETB_MEMb:
1314     return V3_OP_SETB;
1315
1316   case XED_IFORM_SETBE_MEMb:
1317     return V3_OP_SETBE;
1318
1319   case XED_IFORM_SETL_MEMb:
1320     return V3_OP_SETL;
1321
1322   case XED_IFORM_SETLE_MEMb:
1323     return V3_OP_SETLE;
1324
1325   case XED_IFORM_SETNB_MEMb:
1326     return V3_OP_SETNB;
1327
1328   case XED_IFORM_SETNBE_MEMb:
1329     return V3_OP_SETNBE;
1330
1331   case XED_IFORM_SETNL_MEMb:
1332     return V3_OP_SETNL;
1333
1334   case XED_IFORM_SETNLE_MEMb:
1335     return V3_OP_SETNLE;
1336
1337   case XED_IFORM_SETNO_MEMb:
1338     return V3_OP_SETNO;
1339     
1340   case XED_IFORM_SETNP_MEMb:
1341     return V3_OP_SETNP;
1342
1343   case XED_IFORM_SETNS_MEMb:
1344     return V3_OP_SETNS;
1345
1346   case XED_IFORM_SETNZ_MEMb:
1347     return V3_OP_SETNZ;
1348
1349   case XED_IFORM_SETO_MEMb:
1350     return V3_OP_SETO;
1351     
1352   case XED_IFORM_SETP_MEMb:
1353     return V3_OP_SETP;
1354
1355   case XED_IFORM_SETS_MEMb:
1356     return V3_OP_SETS;
1357
1358   case XED_IFORM_SETZ_MEMb:
1359     return V3_OP_SETZ;
1360
1361   case XED_IFORM_MOVSB:
1362   case XED_IFORM_MOVSW:
1363   case XED_IFORM_MOVSD:
1364   case XED_IFORM_MOVSQ:
1365     return V3_OP_MOVS;
1366
1367   case XED_IFORM_STOSB:
1368   case XED_IFORM_STOSW:
1369   case XED_IFORM_STOSD:
1370   case XED_IFORM_STOSQ:
1371     return V3_OP_STOS;
1372
1373
1374   default:
1375     return V3_INVALID_OP;
1376   }
1377 }