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.


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