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.


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