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.


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