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.


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