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.


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