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.


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