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.


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