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.


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