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.


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