Palacios Public Git Repository

To checkout Palacios execute

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


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