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.


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