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.


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