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.


1aef74aa9b8e421d8638b9847b3544dc685c2de8
[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 struct memory_operand {
84   uint_t segment_size;
85   addr_t segment;
86   uint_t base_size;
87   addr_t base;
88   uint_t index_size;
89   addr_t index;
90   addr_t scale;
91   uint_t displacement_size;
92   ullong_t displacement;
93 };
94
95
96
97
98 static v3_op_type_t get_opcode(xed_iform_enum_t iform);
99
100 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);
101 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
102
103 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
104   switch (info->cpu_mode) {
105   case REAL:
106     if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
107       xed_state_init(state,
108                      XED_MACHINE_MODE_LEGACY_16, 
109                      XED_ADDRESS_WIDTH_16b, 
110                      XED_ADDRESS_WIDTH_16b); 
111     }
112    break;
113   case PROTECTED:
114   case PROTECTED_PAE:
115     if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
116       xed_state_init(state,
117                      XED_MACHINE_MODE_LEGACY_32, 
118                      XED_ADDRESS_WIDTH_32b, 
119                      XED_ADDRESS_WIDTH_32b);
120     }
121     break;
122   case LONG_32_COMPAT:
123     if (state->mmode != XED_MACHINE_MODE_LONG_COMPAT_32) {
124       xed_state_init(state,
125                      XED_MACHINE_MODE_LONG_COMPAT_32, 
126                      XED_ADDRESS_WIDTH_32b, 
127                      XED_ADDRESS_WIDTH_32b);
128     }
129     break;
130   case LONG:
131     if (state->mmode != XED_MACHINE_MODE_LONG_64) {
132       PrintDebug("Setting decoder to long mode\n");
133       //      state->mmode = XED_MACHINE_MODE_LONG_64;
134       //xed_state_set_machine_mode(state, XED_MACHINE_MODE_LONG_64);
135       xed_state_init(state,
136                      XED_MACHINE_MODE_LONG_64, 
137                      XED_ADDRESS_WIDTH_64b, 
138                      XED_ADDRESS_WIDTH_64b);
139     }
140     break;
141   default:
142     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
143     return -1;
144   }
145   return 0;
146 }
147
148 static int is_flags_reg(xed_reg_enum_t xed_reg) {
149   switch (xed_reg) {
150   case XED_REG_FLAGS:
151   case XED_REG_EFLAGS:
152   case XED_REG_RFLAGS:
153     return 1;
154   default:
155     return 0;
156   }
157 }
158
159
160
161 int v3_init_decoder(struct guest_info * info) {
162   // Global library initialization, only do it once
163   if (tables_inited == 0) {
164     xed_tables_init();
165     tables_inited = 1;
166   }
167
168   xed_state_t * decoder_state = (xed_state_t *)V3_Malloc(sizeof(xed_state_t));
169   xed_state_zero(decoder_state);
170   xed_state_init(decoder_state,
171                  XED_MACHINE_MODE_LEGACY_32, 
172                  XED_ADDRESS_WIDTH_32b, 
173                  XED_ADDRESS_WIDTH_32b);
174
175   info->decoder_state = decoder_state;
176
177   return 0;
178 }
179
180
181
182 int v3_basic_mem_decode(struct guest_info * info, addr_t instr_ptr, struct basic_instr_info * instr_info) {
183   xed_decoded_inst_t xed_instr;
184   xed_error_enum_t xed_error;
185   
186
187   if (set_decoder_mode(info, info->decoder_state) == -1) {
188     PrintError("Could not set decoder mode\n");
189     return -1;
190   }
191
192
193   xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
194
195   xed_error = xed_decode(&xed_instr, 
196                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
197                          XED_MAX_INSTRUCTION_BYTES);
198
199   if (xed_error != XED_ERROR_NONE) {
200     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
201     return -1;
202   }
203
204   instr_info->instr_length = xed_decoded_inst_get_length(&xed_instr);
205
206
207  if (xed_decoded_inst_number_of_memory_operands(&xed_instr) == 0) {
208    PrintError("Tried to decode memory operation with no memory operands\n");
209    return -1;
210  }
211
212  instr_info->op_size = xed_decoded_inst_get_memory_operand_length(&xed_instr, 0);
213
214
215  xed_category_enum_t cat = xed_decoded_inst_get_category(&xed_instr);
216  if (cat == XED_CATEGORY_STRINGOP) {
217    instr_info->str_op = 1;
218  } else {
219    instr_info->str_op = 0;
220  }
221
222  xed_operand_values_t * operands = xed_decoded_inst_operands(&xed_instr);
223  if (xed_operand_values_has_real_rep(operands)) {
224    instr_info->has_rep = 1;
225  } else {
226    instr_info->has_rep = 0;
227  }
228
229  return 0;
230 }
231
232
233 static int decode_string_op(struct guest_info * info, 
234                             xed_decoded_inst_t * xed_instr,  const xed_inst_t * xi,
235                             struct x86_instr * instr) {
236
237   PrintDebug("String operation\n");
238
239   if (instr->op_type == V3_OP_MOVS) {
240     instr->num_operands = 2;
241
242     if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
243       PrintError("Could not get Destination memory operand\n");
244       return -1;
245     }
246
247     if (get_memory_operand(info, xed_instr, 1, &(instr->src_operand)) == -1) {
248       PrintError("Could not get Source memory operand\n");
249       return -1;
250     }
251
252     if (instr->prefixes.rep == 1) {
253       addr_t reg_addr = 0;
254       uint_t reg_length = 0;
255
256       xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), &reg_addr, &reg_length);
257       instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
258     } else {
259       instr->str_op_length = 1;
260     }
261
262   } else if (instr->op_type == V3_OP_STOS) {
263     instr->num_operands = 2;
264
265     if (get_memory_operand(info, xed_instr, 0, &(instr->dst_operand)) == -1) {
266       PrintError("Could not get Destination memory operand\n");
267       return -1;
268     }
269
270     // STOS reads from rax
271     xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG0), 
272                       &(instr->src_operand.operand), 
273                       &(instr->src_operand.size));
274     instr->src_operand.type = REG_OPERAND;
275     
276     if (instr->prefixes.rep == 1) {
277       addr_t reg_addr = 0;
278       uint_t reg_length = 0;
279
280       xed_reg_to_v3_reg(info, xed_decoded_inst_get_reg(xed_instr, XED_OPERAND_REG1), &reg_addr, &reg_length);
281       instr->str_op_length = MASK(*(addr_t *)reg_addr, reg_length);
282     } else {
283       instr->str_op_length = 1;
284     }
285
286   } else {
287     PrintError("Unhandled String OP\n");
288     return -1;
289   }
290
291   return 0;
292 }
293
294
295
296 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
297   xed_decoded_inst_t xed_instr;
298   xed_error_enum_t xed_error;
299
300
301   v3_get_prefixes((uchar_t *)instr_ptr, &(instr->prefixes));
302
303   if (set_decoder_mode(info, info->decoder_state) == -1) {
304     PrintError("Could not set decoder mode\n");
305     return -1;
306   }
307
308   xed_decoded_inst_zero_set_mode(&xed_instr, info->decoder_state);
309
310   xed_error = xed_decode(&xed_instr, 
311                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
312                          XED_MAX_INSTRUCTION_BYTES);
313
314
315   if (xed_error != XED_ERROR_NONE) {
316     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
317     return -1;
318   }
319
320   const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
321   
322   instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
323
324
325   xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
326
327 #ifdef DEBUG_XED
328   xed_iclass_enum_t iclass = xed_decoded_inst_get_iclass(&xed_instr);
329
330   PrintDebug("iform=%s, iclass=%s\n", xed_iform_enum_t2str(iform), xed_iclass_enum_t2str(iclass));
331 #endif
332
333
334   if ((instr->op_type = get_opcode(iform)) == V3_INVALID_OP) {
335     PrintError("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
336     return -1;
337   }
338
339
340   // We special case the string operations...
341   if (xed_decoded_inst_get_category(&xed_instr) == XED_CATEGORY_STRINGOP) {
342     instr->is_str_op = 1;
343     return decode_string_op(info, &xed_instr, xi, instr); 
344   } else {
345     instr->is_str_op = 0;
346     instr->str_op_length = 0;
347   }
348
349
350   instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
351
352   if (instr->num_operands > 3) {
353     PrintDebug("Special Case Not Handled\n");
354     return -1;
355     // special case
356   } else if (instr->num_operands == 3) {
357     const xed_operand_t * op = xed_inst_operand(xi, 2);
358     xed_operand_enum_t op_enum = xed_operand_name(op);
359
360     if ((!xed_operand_is_register(op_enum)) ||
361         (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
362       // special case
363       PrintError("Special Case not handled\n");
364       return -1;
365     }
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_MEMb_AL:
1269   case XED_IFORM_MOV_MEMv_IMM:
1270   case XED_IFORM_MOV_MEMb_IMM:
1271     // Read 
1272   case XED_IFORM_MOV_GPRv_MEMv:
1273   case XED_IFORM_MOV_GPR8_MEMb:
1274   case XED_IFORM_MOV_AL_MEMb:
1275     return V3_OP_MOV;
1276
1277
1278     // Read 
1279   case XED_IFORM_MOVZX_GPRv_MEMb:
1280   case XED_IFORM_MOVZX_GPRv_MEMw:
1281     return V3_OP_MOVZX;
1282
1283     // Read 
1284   case XED_IFORM_MOVSX_GPRv_MEMb:
1285   case XED_IFORM_MOVSX_GPRv_MEMw:
1286     return V3_OP_MOVSX;
1287
1288
1289
1290   case XED_IFORM_DEC_MEMv:
1291   case XED_IFORM_DEC_MEMb:
1292     return V3_OP_DEC;
1293
1294   case XED_IFORM_INC_MEMb:
1295   case XED_IFORM_INC_MEMv:
1296     return V3_OP_INC;
1297
1298     // Write
1299   case XED_IFORM_OR_MEMv_IMM:
1300   case XED_IFORM_OR_MEMb_IMM:
1301   case XED_IFORM_OR_MEMv_GPRv:
1302   case XED_IFORM_OR_MEMb_GPR8:
1303     // Read
1304   case XED_IFORM_OR_GPRv_MEMv:
1305   case XED_IFORM_OR_GPR8_MEMb:
1306     return V3_OP_OR;
1307
1308     // Write
1309   case XED_IFORM_XOR_MEMv_GPRv:
1310   case XED_IFORM_XOR_MEMb_IMM:
1311   case XED_IFORM_XOR_MEMb_GPR8:
1312   case XED_IFORM_XOR_MEMv_IMM:
1313     // Read
1314   case XED_IFORM_XOR_GPRv_MEMv:
1315   case XED_IFORM_XOR_GPR8_MEMb:
1316     return V3_OP_XOR;
1317
1318   case XED_IFORM_NEG_MEMb:
1319   case XED_IFORM_NEG_MEMv:
1320     return V3_OP_NEG;
1321
1322   case XED_IFORM_NOT_MEMv:
1323   case XED_IFORM_NOT_MEMb:
1324     return V3_OP_NOT;
1325
1326   case XED_IFORM_XCHG_MEMv_GPRv:
1327   case XED_IFORM_XCHG_MEMb_GPR8:
1328     return V3_OP_XCHG;
1329
1330   case XED_IFORM_SETB_MEMb:
1331     return V3_OP_SETB;
1332
1333   case XED_IFORM_SETBE_MEMb:
1334     return V3_OP_SETBE;
1335
1336   case XED_IFORM_SETL_MEMb:
1337     return V3_OP_SETL;
1338
1339   case XED_IFORM_SETLE_MEMb:
1340     return V3_OP_SETLE;
1341
1342   case XED_IFORM_SETNB_MEMb:
1343     return V3_OP_SETNB;
1344
1345   case XED_IFORM_SETNBE_MEMb:
1346     return V3_OP_SETNBE;
1347
1348   case XED_IFORM_SETNL_MEMb:
1349     return V3_OP_SETNL;
1350
1351   case XED_IFORM_SETNLE_MEMb:
1352     return V3_OP_SETNLE;
1353
1354   case XED_IFORM_SETNO_MEMb:
1355     return V3_OP_SETNO;
1356     
1357   case XED_IFORM_SETNP_MEMb:
1358     return V3_OP_SETNP;
1359
1360   case XED_IFORM_SETNS_MEMb:
1361     return V3_OP_SETNS;
1362
1363   case XED_IFORM_SETNZ_MEMb:
1364     return V3_OP_SETNZ;
1365
1366   case XED_IFORM_SETO_MEMb:
1367     return V3_OP_SETO;
1368     
1369   case XED_IFORM_SETP_MEMb:
1370     return V3_OP_SETP;
1371
1372   case XED_IFORM_SETS_MEMb:
1373     return V3_OP_SETS;
1374
1375   case XED_IFORM_SETZ_MEMb:
1376     return V3_OP_SETZ;
1377
1378   case XED_IFORM_MOVSB:
1379   case XED_IFORM_MOVSW:
1380   case XED_IFORM_MOVSD:
1381   case XED_IFORM_MOVSQ:
1382     return V3_OP_MOVS;
1383
1384   case XED_IFORM_STOSB:
1385   case XED_IFORM_STOSW:
1386   case XED_IFORM_STOSD:
1387   case XED_IFORM_STOSQ:
1388     return V3_OP_STOS;
1389
1390
1391   default:
1392     return V3_INVALID_OP;
1393   }
1394 }