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.


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