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.


fixed emulation bugs
[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
647   // This is a horrendous hack...
648   // XED really screwed the pooch in calculating the displacement
649   if (v3_get_cpu_mode(info) == LONG) {
650     displacement = mem_op.displacement;
651   } else {
652     displacement = MASK(mem_op.displacement, mem_op.displacement_size);
653   }
654
655   PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", 
656              (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);
657   
658   operand->operand = seg + base + (scale * index) + displacement;
659   return 0;
660 }
661
662
663 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) {
664
665   PrintDebug("Xed Register: %s\n", xed_reg_enum_t2str(xed_reg));
666
667   switch (xed_reg) {
668   case XED_REG_INVALID:
669     *v3_reg = 0;
670     *reg_len = 0;
671     return -1;
672
673     /* 
674      * GPRs
675      */
676   case XED_REG_RAX: 
677     *v3_reg = (addr_t)&(info->vm_regs.rax);
678     *reg_len = 8;
679     return GPR_REGISTER;
680   case XED_REG_EAX:
681     *v3_reg = (addr_t)&(info->vm_regs.rax);
682     *reg_len = 4;
683     return GPR_REGISTER;
684   case XED_REG_AX:
685     *v3_reg = (addr_t)&(info->vm_regs.rax);
686     *reg_len = 2;
687     return GPR_REGISTER;
688   case XED_REG_AH:
689     *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
690     *reg_len = 1;
691     return GPR_REGISTER;
692   case XED_REG_AL:
693     *v3_reg = (addr_t)&(info->vm_regs.rax);
694     *reg_len = 1;
695     return GPR_REGISTER;
696
697   case XED_REG_RCX: 
698     *v3_reg = (addr_t)&(info->vm_regs.rcx);
699     *reg_len = 8;
700     return GPR_REGISTER;
701   case XED_REG_ECX:
702     *v3_reg = (addr_t)&(info->vm_regs.rcx);
703     *reg_len = 4;
704     return GPR_REGISTER;
705   case XED_REG_CX:
706     *v3_reg = (addr_t)&(info->vm_regs.rcx);
707     *reg_len = 2;
708     return GPR_REGISTER;
709   case XED_REG_CH:
710     *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
711     *reg_len = 1;
712     return GPR_REGISTER;
713   case XED_REG_CL:
714     *v3_reg = (addr_t)&(info->vm_regs.rcx);
715     *reg_len = 1;
716     return GPR_REGISTER;
717
718   case XED_REG_RDX: 
719     *v3_reg = (addr_t)&(info->vm_regs.rdx);
720     *reg_len = 8;
721     return GPR_REGISTER;
722   case XED_REG_EDX:
723     *v3_reg = (addr_t)&(info->vm_regs.rdx);
724     *reg_len = 4;
725     return GPR_REGISTER;
726   case XED_REG_DX:
727     *v3_reg = (addr_t)&(info->vm_regs.rdx);
728     *reg_len = 2;
729     return GPR_REGISTER;
730   case XED_REG_DH:
731     *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
732     *reg_len = 1;
733     return GPR_REGISTER;
734   case XED_REG_DL:
735     *v3_reg = (addr_t)&(info->vm_regs.rdx);
736     *reg_len = 1;
737     return GPR_REGISTER;
738
739   case XED_REG_RBX: 
740     *v3_reg = (addr_t)&(info->vm_regs.rbx);
741     *reg_len = 8;
742     return GPR_REGISTER;
743   case XED_REG_EBX:
744     *v3_reg = (addr_t)&(info->vm_regs.rbx);
745     *reg_len = 4;
746     return GPR_REGISTER;
747   case XED_REG_BX:
748     *v3_reg = (addr_t)&(info->vm_regs.rbx);
749     *reg_len = 2;
750     return GPR_REGISTER;
751   case XED_REG_BH:
752     *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
753     *reg_len = 1;
754     return GPR_REGISTER;
755   case XED_REG_BL:
756     *v3_reg = (addr_t)&(info->vm_regs.rbx);
757     *reg_len = 1;
758     return GPR_REGISTER;
759
760
761   case XED_REG_RSP:
762     *v3_reg = (addr_t)&(info->vm_regs.rsp);
763     *reg_len = 8;
764     return GPR_REGISTER;
765   case XED_REG_ESP:
766     *v3_reg = (addr_t)&(info->vm_regs.rsp);
767     *reg_len = 4;
768     return GPR_REGISTER;
769   case XED_REG_SP:
770     *v3_reg = (addr_t)&(info->vm_regs.rsp);
771     *reg_len = 2;
772     return GPR_REGISTER;
773   case XED_REG_SPL:
774     *v3_reg = (addr_t)&(info->vm_regs.rsp);
775     *reg_len = 1;
776     return GPR_REGISTER;
777
778   case XED_REG_RBP:
779     *v3_reg = (addr_t)&(info->vm_regs.rbp);
780     *reg_len = 8;
781     return GPR_REGISTER;
782   case XED_REG_EBP:
783     *v3_reg = (addr_t)&(info->vm_regs.rbp);
784     *reg_len = 4;
785     return GPR_REGISTER;
786   case XED_REG_BP:
787     *v3_reg = (addr_t)&(info->vm_regs.rbp);
788     *reg_len = 2;
789     return GPR_REGISTER;
790   case XED_REG_BPL:
791     *v3_reg = (addr_t)&(info->vm_regs.rbp);
792     *reg_len = 1;
793     return GPR_REGISTER;
794
795
796
797   case XED_REG_RSI:
798     *v3_reg = (addr_t)&(info->vm_regs.rsi);
799     *reg_len = 8;
800     return GPR_REGISTER;
801   case XED_REG_ESI:
802     *v3_reg = (addr_t)&(info->vm_regs.rsi);
803     *reg_len = 4;
804     return GPR_REGISTER;
805   case XED_REG_SI:
806     *v3_reg = (addr_t)&(info->vm_regs.rsi);
807     *reg_len = 2;
808     return GPR_REGISTER;
809   case XED_REG_SIL:
810     *v3_reg = (addr_t)&(info->vm_regs.rsi);
811     *reg_len = 1;
812     return GPR_REGISTER;
813
814
815   case XED_REG_RDI:
816     *v3_reg = (addr_t)&(info->vm_regs.rdi);
817     *reg_len = 8;
818     return GPR_REGISTER;
819   case XED_REG_EDI:
820     *v3_reg = (addr_t)&(info->vm_regs.rdi);
821     *reg_len = 4;
822     return GPR_REGISTER;
823   case XED_REG_DI:
824     *v3_reg = (addr_t)&(info->vm_regs.rdi);
825     *reg_len = 2;
826     return GPR_REGISTER;
827   case XED_REG_DIL:
828     *v3_reg = (addr_t)&(info->vm_regs.rdi);
829     *reg_len = 1;
830     return GPR_REGISTER;
831
832
833
834
835
836   case XED_REG_R8:
837     *v3_reg = (addr_t)&(info->vm_regs.r8);
838     *reg_len = 8;
839     return GPR_REGISTER;
840   case XED_REG_R8D:
841     *v3_reg = (addr_t)&(info->vm_regs.r8);
842     *reg_len = 4;
843     return GPR_REGISTER;
844   case XED_REG_R8W:
845     *v3_reg = (addr_t)&(info->vm_regs.r8);
846     *reg_len = 2;
847     return GPR_REGISTER;
848   case XED_REG_R8B:
849     *v3_reg = (addr_t)&(info->vm_regs.r8);
850     *reg_len = 1;
851     return GPR_REGISTER;
852
853   case XED_REG_R9:
854     *v3_reg = (addr_t)&(info->vm_regs.r9);
855     *reg_len = 8;
856     return GPR_REGISTER;
857   case XED_REG_R9D:
858     *v3_reg = (addr_t)&(info->vm_regs.r9);
859     *reg_len = 4;
860     return GPR_REGISTER;
861   case XED_REG_R9W:
862     *v3_reg = (addr_t)&(info->vm_regs.r9);
863     *reg_len = 2;
864     return GPR_REGISTER;
865   case XED_REG_R9B:
866     *v3_reg = (addr_t)&(info->vm_regs.r9);
867     *reg_len = 1;
868     return GPR_REGISTER;
869
870   case XED_REG_R10:
871     *v3_reg = (addr_t)&(info->vm_regs.r10);
872     *reg_len = 8;
873     return GPR_REGISTER;
874   case XED_REG_R10D:
875     *v3_reg = (addr_t)&(info->vm_regs.r10);
876     *reg_len = 4;
877     return GPR_REGISTER;
878   case XED_REG_R10W:
879     *v3_reg = (addr_t)&(info->vm_regs.r10);
880     *reg_len = 2;
881     return GPR_REGISTER;
882   case XED_REG_R10B:
883     *v3_reg = (addr_t)&(info->vm_regs.r10);
884     *reg_len = 1;
885     return GPR_REGISTER;
886
887   case XED_REG_R11:
888     *v3_reg = (addr_t)&(info->vm_regs.r11);
889     *reg_len = 8;
890     return GPR_REGISTER;
891   case XED_REG_R11D:
892     *v3_reg = (addr_t)&(info->vm_regs.r11);
893     *reg_len = 4;
894     return GPR_REGISTER;
895   case XED_REG_R11W:
896     *v3_reg = (addr_t)&(info->vm_regs.r11);
897     *reg_len = 2;
898     return GPR_REGISTER;
899   case XED_REG_R11B:
900     *v3_reg = (addr_t)&(info->vm_regs.r11);
901     *reg_len = 1;
902     return GPR_REGISTER;
903
904   case XED_REG_R12:
905     *v3_reg = (addr_t)&(info->vm_regs.r12);
906     *reg_len = 8;
907     return GPR_REGISTER;
908   case XED_REG_R12D:
909     *v3_reg = (addr_t)&(info->vm_regs.r12);
910     *reg_len = 4;
911     return GPR_REGISTER;
912   case XED_REG_R12W:
913     *v3_reg = (addr_t)&(info->vm_regs.r12);
914     *reg_len = 2;
915     return GPR_REGISTER;
916   case XED_REG_R12B:
917     *v3_reg = (addr_t)&(info->vm_regs.r12);
918     *reg_len = 1;
919     return GPR_REGISTER;
920
921   case XED_REG_R13:
922     *v3_reg = (addr_t)&(info->vm_regs.r13);
923     *reg_len = 8;
924     return GPR_REGISTER;
925   case XED_REG_R13D:
926     *v3_reg = (addr_t)&(info->vm_regs.r13);
927     *reg_len = 4;
928     return GPR_REGISTER;
929   case XED_REG_R13W:
930     *v3_reg = (addr_t)&(info->vm_regs.r13);
931     *reg_len = 2;
932     return GPR_REGISTER;
933   case XED_REG_R13B:
934     *v3_reg = (addr_t)&(info->vm_regs.r13);
935     *reg_len = 1;
936     return GPR_REGISTER;
937
938   case XED_REG_R14:
939     *v3_reg = (addr_t)&(info->vm_regs.r14);
940     *reg_len = 8;
941     return GPR_REGISTER;
942   case XED_REG_R14D:
943     *v3_reg = (addr_t)&(info->vm_regs.r14);
944     *reg_len = 4;
945     return GPR_REGISTER;
946   case XED_REG_R14W:
947     *v3_reg = (addr_t)&(info->vm_regs.r14);
948     *reg_len = 2;
949     return GPR_REGISTER;
950   case XED_REG_R14B:
951     *v3_reg = (addr_t)&(info->vm_regs.r14);
952     *reg_len = 1;
953     return GPR_REGISTER;
954
955   case XED_REG_R15:
956     *v3_reg = (addr_t)&(info->vm_regs.r15);
957     *reg_len = 8;
958     return GPR_REGISTER;
959   case XED_REG_R15D:
960     *v3_reg = (addr_t)&(info->vm_regs.r15);
961     *reg_len = 4;
962     return GPR_REGISTER;
963   case XED_REG_R15W:
964     *v3_reg = (addr_t)&(info->vm_regs.r15);
965     *reg_len = 2;
966     return GPR_REGISTER;
967   case XED_REG_R15B:
968     *v3_reg = (addr_t)&(info->vm_regs.r15);
969     *reg_len = 1;
970     return GPR_REGISTER;
971
972
973     /* 
974      *  CTRL REGS
975      */
976   case XED_REG_RIP:
977     *v3_reg = (addr_t)&(info->rip);
978     *reg_len = 8;
979     return CTRL_REGISTER;
980   case XED_REG_EIP:
981     *v3_reg = (addr_t)&(info->rip);
982     *reg_len = 4;
983     return CTRL_REGISTER;  
984   case XED_REG_IP:
985     *v3_reg = (addr_t)&(info->rip);
986     *reg_len = 2;
987     return CTRL_REGISTER;
988
989   case XED_REG_FLAGS:
990     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
991     *reg_len = 2;
992     return CTRL_REGISTER;
993   case XED_REG_EFLAGS:
994     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
995     *reg_len = 4;
996     return CTRL_REGISTER;
997   case XED_REG_RFLAGS:
998     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
999     *reg_len = 8;
1000     return CTRL_REGISTER;
1001
1002   case XED_REG_CR0:
1003     *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
1004     *reg_len = 4;
1005     return CTRL_REGISTER;
1006   case XED_REG_CR2:
1007     *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
1008     *reg_len = 4;
1009     return CTRL_REGISTER;
1010   case XED_REG_CR3:
1011     *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
1012     *reg_len = 4;
1013     return CTRL_REGISTER;
1014   case XED_REG_CR4:
1015     *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
1016    *reg_len = 4;
1017     return CTRL_REGISTER;
1018   case XED_REG_CR8:
1019     *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
1020     *reg_len = 4;
1021     return CTRL_REGISTER;
1022
1023   case XED_REG_CR1:
1024   case XED_REG_CR5:
1025   case XED_REG_CR6:
1026   case XED_REG_CR7:
1027   case XED_REG_CR9:
1028   case XED_REG_CR10:
1029   case XED_REG_CR11:
1030   case XED_REG_CR12:
1031   case XED_REG_CR13:
1032   case XED_REG_CR14:
1033   case XED_REG_CR15:
1034     return -1;
1035
1036
1037
1038
1039     /* 
1040      * SEGMENT REGS
1041      */
1042   case XED_REG_CS:
1043     *v3_reg = (addr_t)&(info->segments.cs);
1044     *reg_len = 8;
1045     return SEGMENT_REGISTER;
1046   case XED_REG_DS:
1047     *v3_reg = (addr_t)&(info->segments.ds);
1048     *reg_len = 8;
1049     return SEGMENT_REGISTER;
1050   case XED_REG_ES:
1051     *v3_reg = (addr_t)&(info->segments.es);
1052     *reg_len = 8;
1053     return SEGMENT_REGISTER;
1054   case XED_REG_SS:
1055     *v3_reg = (addr_t)&(info->segments.ss);
1056     *reg_len = 8;
1057     return SEGMENT_REGISTER;
1058   case XED_REG_FS:
1059     *v3_reg = (addr_t)&(info->segments.fs);
1060     *reg_len = 8;
1061     return SEGMENT_REGISTER;
1062   case XED_REG_GS:
1063     *v3_reg = (addr_t)&(info->segments.gs);
1064     *reg_len = 8;
1065     return SEGMENT_REGISTER;
1066
1067
1068   case XED_REG_GDTR:
1069   case XED_REG_LDTR:
1070   case XED_REG_IDTR:
1071   case XED_REG_TR:
1072     PrintError("Segment selector operand... Don't know how to handle this...\n");
1073     return -1;
1074
1075     /* 
1076      *  DEBUG REGS
1077      */
1078   case XED_REG_DR0:
1079   case XED_REG_DR1:
1080   case XED_REG_DR2:
1081   case XED_REG_DR3:
1082   case XED_REG_DR4:
1083   case XED_REG_DR5:
1084   case XED_REG_DR6:
1085   case XED_REG_DR7:
1086   case XED_REG_DR8:
1087   case XED_REG_DR9:
1088   case XED_REG_DR10:
1089   case XED_REG_DR11:
1090   case XED_REG_DR12:
1091   case XED_REG_DR13:
1092   case XED_REG_DR14:
1093   case XED_REG_DR15:
1094     return -1;
1095
1096
1097
1098
1099
1100
1101   case XED_REG_XMM0:
1102   case XED_REG_XMM1:
1103   case XED_REG_XMM2:
1104   case XED_REG_XMM3:
1105   case XED_REG_XMM4:
1106   case XED_REG_XMM5:
1107   case XED_REG_XMM6:
1108   case XED_REG_XMM7:
1109   case XED_REG_XMM8:
1110   case XED_REG_XMM9:
1111   case XED_REG_XMM10:
1112   case XED_REG_XMM11:
1113   case XED_REG_XMM12:
1114   case XED_REG_XMM13:
1115   case XED_REG_XMM14:
1116   case XED_REG_XMM15:
1117
1118   case XED_REG_MMX0:
1119   case XED_REG_MMX1:
1120   case XED_REG_MMX2:
1121   case XED_REG_MMX3:
1122   case XED_REG_MMX4:
1123   case XED_REG_MMX5:
1124   case XED_REG_MMX6:
1125   case XED_REG_MMX7:
1126
1127   case XED_REG_ST0:
1128   case XED_REG_ST1:
1129   case XED_REG_ST2:
1130   case XED_REG_ST3:
1131   case XED_REG_ST4:
1132   case XED_REG_ST5:
1133   case XED_REG_ST6:
1134   case XED_REG_ST7:
1135
1136   case XED_REG_ONE:
1137   case XED_REG_STACKPUSH:
1138   case XED_REG_STACKPOP:
1139     
1140   case XED_REG_TSC:
1141   case XED_REG_TSCAUX:
1142   case XED_REG_MSRS:
1143
1144   case XED_REG_X87CONTROL:
1145   case XED_REG_X87STATUS:
1146   case XED_REG_X87TOP:
1147   case XED_REG_X87TAG:
1148   case XED_REG_X87PUSH:
1149   case XED_REG_X87POP:
1150   case XED_REG_X87POP2:
1151
1152   case XED_REG_MXCSR:
1153
1154   case XED_REG_TMP0:
1155   case XED_REG_TMP1:
1156   case XED_REG_TMP2:
1157   case XED_REG_TMP3:
1158   case XED_REG_TMP4:
1159   case XED_REG_TMP5:
1160   case XED_REG_TMP6:
1161   case XED_REG_TMP7:
1162   case XED_REG_TMP8:
1163   case XED_REG_TMP9:
1164   case XED_REG_TMP10:
1165   case XED_REG_TMP11:
1166   case XED_REG_TMP12:
1167   case XED_REG_TMP13:
1168   case XED_REG_TMP14:
1169   case XED_REG_TMP15:
1170
1171   case XED_REG_LAST:
1172
1173   case XED_REG_ERROR:
1174     // error??
1175     return -1;
1176
1177   }
1178
1179
1180   return 0;
1181 }
1182
1183
1184
1185 static v3_op_type_t get_opcode(xed_iform_enum_t iform) {
1186
1187   switch (iform) {
1188
1189     /* Control Instructions */
1190
1191   case XED_IFORM_MOV_CR_GPR64_CR:
1192   case XED_IFORM_MOV_CR_GPR32_CR:
1193     return V3_OP_MOVCR2;
1194
1195   case XED_IFORM_MOV_CR_CR_GPR64:
1196   case XED_IFORM_MOV_CR_CR_GPR32:
1197     return V3_OP_MOV2CR;
1198
1199   case XED_IFORM_SMSW_GPRv:
1200     return V3_OP_SMSW;
1201
1202   case XED_IFORM_LMSW_GPR16:
1203     return V3_OP_LMSW;
1204
1205   case XED_IFORM_CLTS:
1206     return V3_OP_CLTS;
1207
1208   case XED_IFORM_INVLPG_MEMb:
1209     return V3_OP_INVLPG;
1210
1211
1212     /* Data Instructions */
1213
1214     // Write
1215   case XED_IFORM_ADC_MEMv_GPRv:
1216   case XED_IFORM_ADC_MEMv_IMM:
1217   case XED_IFORM_ADC_MEMb_GPR8:
1218   case XED_IFORM_ADC_MEMb_IMM:
1219     // Read
1220   case XED_IFORM_ADC_GPRv_MEMv:
1221   case XED_IFORM_ADC_GPR8_MEMb:
1222     return V3_OP_ADC;
1223
1224     // Write
1225   case XED_IFORM_ADD_MEMv_GPRv:
1226   case XED_IFORM_ADD_MEMb_IMM:
1227   case XED_IFORM_ADD_MEMb_GPR8:
1228   case XED_IFORM_ADD_MEMv_IMM:
1229     // Read
1230   case XED_IFORM_ADD_GPRv_MEMv:
1231   case XED_IFORM_ADD_GPR8_MEMb:
1232     return V3_OP_ADD;
1233
1234     // Write
1235   case XED_IFORM_AND_MEMv_IMM:
1236   case XED_IFORM_AND_MEMb_GPR8:
1237   case XED_IFORM_AND_MEMv_GPRv:
1238   case XED_IFORM_AND_MEMb_IMM:
1239     // Read
1240   case XED_IFORM_AND_GPR8_MEMb:
1241   case XED_IFORM_AND_GPRv_MEMv:
1242     return V3_OP_AND;
1243
1244     // Write
1245   case XED_IFORM_SUB_MEMv_IMM:
1246   case XED_IFORM_SUB_MEMb_GPR8:
1247   case XED_IFORM_SUB_MEMb_IMM:
1248   case XED_IFORM_SUB_MEMv_GPRv:
1249     // Read
1250   case XED_IFORM_SUB_GPR8_MEMb:
1251   case XED_IFORM_SUB_GPRv_MEMv:
1252     return V3_OP_SUB;
1253
1254     // Write
1255   case XED_IFORM_MOV_MEMv_GPRv:
1256   case XED_IFORM_MOV_MEMb_GPR8:
1257   case XED_IFORM_MOV_MEMb_AL:
1258   case XED_IFORM_MOV_MEMv_IMM:
1259   case XED_IFORM_MOV_MEMb_IMM:
1260     // Read 
1261   case XED_IFORM_MOV_GPRv_MEMv:
1262   case XED_IFORM_MOV_GPR8_MEMb:
1263   case XED_IFORM_MOV_AL_MEMb:
1264     return V3_OP_MOV;
1265
1266
1267     // Read 
1268   case XED_IFORM_MOVZX_GPRv_MEMb:
1269   case XED_IFORM_MOVZX_GPRv_MEMw:
1270     return V3_OP_MOVZX;
1271
1272     // Read 
1273   case XED_IFORM_MOVSX_GPRv_MEMb:
1274   case XED_IFORM_MOVSX_GPRv_MEMw:
1275     return V3_OP_MOVSX;
1276
1277
1278
1279   case XED_IFORM_DEC_MEMv:
1280   case XED_IFORM_DEC_MEMb:
1281     return V3_OP_DEC;
1282
1283   case XED_IFORM_INC_MEMb:
1284   case XED_IFORM_INC_MEMv:
1285     return V3_OP_INC;
1286
1287     // Write
1288   case XED_IFORM_OR_MEMv_IMM:
1289   case XED_IFORM_OR_MEMb_IMM:
1290   case XED_IFORM_OR_MEMv_GPRv:
1291   case XED_IFORM_OR_MEMb_GPR8:
1292     // Read
1293   case XED_IFORM_OR_GPRv_MEMv:
1294   case XED_IFORM_OR_GPR8_MEMb:
1295     return V3_OP_OR;
1296
1297     // Write
1298   case XED_IFORM_XOR_MEMv_GPRv:
1299   case XED_IFORM_XOR_MEMb_IMM:
1300   case XED_IFORM_XOR_MEMb_GPR8:
1301   case XED_IFORM_XOR_MEMv_IMM:
1302     // Read
1303   case XED_IFORM_XOR_GPRv_MEMv:
1304   case XED_IFORM_XOR_GPR8_MEMb:
1305     return V3_OP_XOR;
1306
1307   case XED_IFORM_NEG_MEMb:
1308   case XED_IFORM_NEG_MEMv:
1309     return V3_OP_NEG;
1310
1311   case XED_IFORM_NOT_MEMv:
1312   case XED_IFORM_NOT_MEMb:
1313     return V3_OP_NOT;
1314
1315   case XED_IFORM_XCHG_MEMv_GPRv:
1316   case XED_IFORM_XCHG_MEMb_GPR8:
1317     return V3_OP_XCHG;
1318
1319   case XED_IFORM_SETB_MEMb:
1320     return V3_OP_SETB;
1321
1322   case XED_IFORM_SETBE_MEMb:
1323     return V3_OP_SETBE;
1324
1325   case XED_IFORM_SETL_MEMb:
1326     return V3_OP_SETL;
1327
1328   case XED_IFORM_SETLE_MEMb:
1329     return V3_OP_SETLE;
1330
1331   case XED_IFORM_SETNB_MEMb:
1332     return V3_OP_SETNB;
1333
1334   case XED_IFORM_SETNBE_MEMb:
1335     return V3_OP_SETNBE;
1336
1337   case XED_IFORM_SETNL_MEMb:
1338     return V3_OP_SETNL;
1339
1340   case XED_IFORM_SETNLE_MEMb:
1341     return V3_OP_SETNLE;
1342
1343   case XED_IFORM_SETNO_MEMb:
1344     return V3_OP_SETNO;
1345     
1346   case XED_IFORM_SETNP_MEMb:
1347     return V3_OP_SETNP;
1348
1349   case XED_IFORM_SETNS_MEMb:
1350     return V3_OP_SETNS;
1351
1352   case XED_IFORM_SETNZ_MEMb:
1353     return V3_OP_SETNZ;
1354
1355   case XED_IFORM_SETO_MEMb:
1356     return V3_OP_SETO;
1357     
1358   case XED_IFORM_SETP_MEMb:
1359     return V3_OP_SETP;
1360
1361   case XED_IFORM_SETS_MEMb:
1362     return V3_OP_SETS;
1363
1364   case XED_IFORM_SETZ_MEMb:
1365     return V3_OP_SETZ;
1366
1367   case XED_IFORM_MOVSB:
1368   case XED_IFORM_MOVSW:
1369   case XED_IFORM_MOVSD:
1370   case XED_IFORM_MOVSQ:
1371     return V3_OP_MOVS;
1372
1373   case XED_IFORM_STOSB:
1374   case XED_IFORM_STOSW:
1375   case XED_IFORM_STOSD:
1376   case XED_IFORM_STOSQ:
1377     return V3_OP_STOS;
1378
1379
1380   default:
1381     return V3_INVALID_OP;
1382   }
1383 }