Palacios Public Git Repository

To checkout Palacios execute

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


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