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.


fc676a960784a896d80fb4c993696a290ee4bc63
[palacios.git] / misc / decoder_test / vmm_xed.c
1 #ifdef __DECODER_TEST__
2 #include "vmm_decoder.h"
3 #include "vmm_xed.h"
4 #include <xed/xed-interface.h>
5 #include "vm_guest.h"
6 #include "test.h"
7 #else
8 #include <palacios/vmm_decoder.h>
9 #include <palacios/vmm_xed.h>
10 #include <xed/xed-interface.h>
11 #include <palacios/vm_guest.h>
12 #include <palacios/vmm.h>
13
14 #endif
15
16 static xed_state_t decoder_state;
17
18 #define GPR_REGISTER     0
19 #define SEGMENT_REGISTER 1
20 #define CTRL_REGISTER    2
21 #define DEBUG_REGISTER   3
22
23
24
25 /* Disgusting mask hack...
26    I can't think right now, so we'll do it this way...
27 */
28 static const ullong_t mask_1 = 0x00000000000000ffLL;
29 static const ullong_t mask_2 = 0x000000000000ffffLL;
30 static const ullong_t mask_4 = 0x00000000ffffffffLL;
31 static const ullong_t mask_8 = 0xffffffffffffffffLL;
32
33
34 #define MASK(val, length) ({                    \
35       ullong_t mask = 0x0LL;                    \
36       switch (length) {                         \
37       case 1:                                   \
38         mask = mask_1;                          \
39       case 2:                                   \
40         mask = mask_2;                          \
41       case 4:                                   \
42         mask = mask_4;                          \
43       case 8:                                   \
44         mask = mask_8;                          \
45       }                                         \
46       val & mask;})                             \
47
48 struct memory_operand {
49   uint_t segment_size;
50   addr_t segment;
51   uint_t base_size;
52   addr_t base;
53   uint_t index_size;
54   addr_t index;
55   addr_t scale;
56   uint_t displacement_size;
57   ullong_t displacement;
58 };
59
60
61
62 // This returns a pointer to a V3_OPCODE_[*] array defined in vmm_decoder.h
63 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode);
64
65 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);
66 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t index, struct x86_operand * operand);
67
68 static int set_decoder_mode(struct guest_info * info, xed_state_t * state) {
69   switch (info->cpu_mode) {
70   case REAL:
71     if (state->mmode != XED_MACHINE_MODE_LEGACY_16) {
72       xed_state_init(state,
73                      XED_MACHINE_MODE_LEGACY_16, 
74                      XED_ADDRESS_WIDTH_16b, 
75                      XED_ADDRESS_WIDTH_16b); 
76     }
77    break;
78   case PROTECTED:
79   case PROTECTED_PAE:
80     if (state->mmode != XED_MACHINE_MODE_LEGACY_32) {
81       xed_state_init(state,
82                      XED_MACHINE_MODE_LEGACY_32, 
83                      XED_ADDRESS_WIDTH_32b, 
84                      XED_ADDRESS_WIDTH_32b);
85     }
86     break;
87   case LONG:
88     if (state->mmode != XED_MACHINE_MODE_LONG_64) {    
89       state->mmode = XED_MACHINE_MODE_LONG_64;
90     }
91     break;
92   default:
93     return -1;
94   }
95   return 0;
96 }
97
98 int is_flags_reg(xed_reg_enum_t xed_reg) {
99   switch (xed_reg) {
100   case XED_REG_FLAGS:
101   case XED_REG_EFLAGS:
102   case XED_REG_RFLAGS:
103     return 1;
104   default:
105     return 0;
106   }
107 }
108
109
110
111 int init_decoder() {
112   xed_tables_init();
113   xed_state_zero(&decoder_state);
114   return 0;
115 }
116
117
118 int v3_decode(struct guest_info * info, addr_t instr_ptr, struct x86_instr * instr) {
119   xed_decoded_inst_t xed_instr;
120   xed_error_enum_t xed_error;
121
122
123
124   if (set_decoder_mode(info, &decoder_state) == -1) {
125     PrintError("Could not set decoder mode\n");
126     return -1;
127   }
128
129
130
131   xed_decoded_inst_zero_set_mode(&xed_instr, &decoder_state);
132
133   xed_error = xed_decode(&xed_instr, 
134                          REINTERPRET_CAST(const xed_uint8_t *, instr_ptr), 
135                          XED_MAX_INSTRUCTION_BYTES);
136
137
138   if (xed_error != XED_ERROR_NONE) {
139     PrintError("Xed error: %s\n", xed_error_enum_t2str(xed_error));
140     return -1;
141   }
142
143   const xed_inst_t * xi = xed_decoded_inst_inst(&xed_instr);
144   
145   instr->instr_length = xed_decoded_inst_get_length(&xed_instr);
146   instr->num_operands = xed_decoded_inst_noperands(&xed_instr);
147
148   xed_iform_enum_t iform = xed_decoded_inst_get_iform_enum(&xed_instr);
149
150
151   PrintDebug("iform=%s\n", xed_iform_enum_t2str(iform));
152
153
154   if (instr->num_operands > 3) {
155     PrintDebug("Special Case Not Handled\n");
156     return -1;
157     // special case
158   } else if (instr->num_operands == 3) {
159     const xed_operand_t * op = xed_inst_operand(xi, 2);
160     xed_operand_enum_t op_enum = xed_operand_name(op);
161
162     if ((!xed_operand_is_register(op_enum)) ||
163         (!is_flags_reg(xed_decoded_inst_get_reg(&xed_instr, op_enum)))) {
164       // special case
165       PrintDebug("Special Case not handled\n");
166       return -1;
167     }
168   }
169
170
171
172
173
174   if (get_opcode(iform, &(instr->opcode)) == -1) {
175     PrintDebug("Could not get opcode. (iform=%s)\n", xed_iform_enum_t2str(iform));
176     return -1;
177   }
178
179
180
181
182   //PrintDebug("Number of operands: %d\n", instr->num_operands);
183   //PrintDebug("INSTR length: %d\n", instr->instr_length);
184
185   // set first operand
186   if (instr->num_operands >= 1) {
187     const xed_operand_t * op = xed_inst_operand(xi, 0);
188     xed_operand_enum_t op_enum = xed_operand_name(op);
189
190     struct x86_operand * v3_op = NULL;
191
192     if (xed_operand_written(op)) {
193       v3_op = &(instr->dst_operand);
194     } else {
195       v3_op = &(instr->src_operand);
196     }
197
198
199     if (xed_operand_is_register(op_enum)) {
200       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
201       int v3_reg_type = xed_reg_to_v3_reg(info, 
202                                           xed_reg, 
203                                           &(v3_op->operand), 
204                                           &(v3_op->size));
205                                           
206       if (v3_reg_type == -1) {
207         PrintError("First operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
208         v3_op->type = INVALID_OPERAND;
209         return -1;
210       } else if (v3_reg_type == SEGMENT_REGISTER) {
211         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
212         v3_op->operand = (addr_t)&(seg_reg->selector);
213       }
214
215       v3_op->type = REG_OPERAND;
216     } else {
217
218       switch (op_enum) {
219
220       case XED_OPERAND_MEM0:
221         {
222           /*
223             struct x86_operand * operand = &(instr->dst_operand);
224             
225             if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
226             operand = &(instr->src_operand);
227             } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
228             operand = &(instr->dst_operand);
229             }
230           */
231           
232           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
233             PrintError("Could not get first memory operand\n");
234             return -1;
235           }
236         }
237         break;
238
239       case XED_OPERAND_MEM1:
240       case XED_OPERAND_IMM1:
241         // illegal
242         PrintError("Illegal Operand Order\n");
243         return -1;
244
245
246       case XED_OPERAND_IMM0:
247       case XED_OPERAND_AGEN:
248       case XED_OPERAND_PTR:
249       case XED_OPERAND_RELBR:
250       default:
251         PrintError("Unhandled Operand Type\n");
252         return -1;
253
254
255       }
256     }
257   }
258
259   // set second operand
260   if (instr->num_operands >= 2) {
261     const xed_operand_t * op = xed_inst_operand(xi, 1);
262     //   xed_operand_type_enum_t op_type = xed_operand_type(op);
263     xed_operand_enum_t op_enum = xed_operand_name(op);
264     
265     struct x86_operand * v3_op;
266
267     if (xed_operand_written(op)) {
268       v3_op = &(instr->dst_operand);
269     } else {
270       v3_op = &(instr->src_operand);
271     }
272
273
274     if (xed_operand_is_register(op_enum)) {
275       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
276       int v3_reg_type = xed_reg_to_v3_reg(info, 
277                                           xed_reg, 
278                                           &(v3_op->operand), 
279                                           &(v3_op->size));
280       if (v3_reg_type == -1) {
281         PrintError("Second operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
282         v3_op->type = INVALID_OPERAND;
283         return -1;
284       } else if (v3_reg_type == SEGMENT_REGISTER) {
285         struct v3_segment * seg_reg = (struct v3_segment *)(v3_op->operand);
286         v3_op->operand = (addr_t)&(seg_reg->selector);
287       }
288
289       v3_op->type = REG_OPERAND;
290     
291
292     } else {
293
294       switch (op_enum) {
295
296       case XED_OPERAND_MEM0:
297         {
298
299           /*
300           if (xed_decoded_inst_mem_read(&xed_instr, 0)) {
301             v3_op = &(instr->src_operand);
302           } else if (xed_decoded_inst_mem_written(&xed_instr, 0)) {
303             v3_op = &(instr->dst_operand);
304           }
305           */
306
307           if (get_memory_operand(info, &xed_instr, 0, v3_op) == -1) {
308             PrintError("Could not get first memory operand\n");
309             return -1;
310           }
311         }
312         break;
313
314       case XED_OPERAND_IMM0:
315         {
316           instr->src_operand.size = xed_decoded_inst_get_immediate_width(&xed_instr);
317
318           if (instr->src_operand.size > 4) {
319             PrintError("Unhandled 64 bit immediates\n");
320             return -1;
321           }
322           instr->src_operand.operand = xed_decoded_inst_get_unsigned_immediate(&xed_instr);
323
324           instr->src_operand.type = IMM_OPERAND;
325
326         }
327         break;
328
329       case XED_OPERAND_MEM1:
330       case XED_OPERAND_IMM1:
331         // illegal
332         PrintError("Illegal Operand Order\n");
333         return -1;
334         
335       case XED_OPERAND_AGEN:
336       case XED_OPERAND_PTR:
337       case XED_OPERAND_RELBR:
338       default:
339         PrintError("Unhandled Operand Type\n");
340         return -1;
341       }
342     }
343
344   }
345
346   // set third operand
347   if (instr->num_operands >= 3) {
348     const xed_operand_t * op = xed_inst_operand(xi, 2);
349     //  xed_operand_type_enum_t op_type = xed_operand_type(op);
350     xed_operand_enum_t op_enum = xed_operand_name(op);
351
352     if (xed_operand_is_register(op_enum)) {
353       xed_reg_enum_t xed_reg =  xed_decoded_inst_get_reg(&xed_instr, op_enum);
354       int v3_reg_type = xed_reg_to_v3_reg(info, 
355                                           xed_reg, 
356                                           &(instr->third_operand.operand), 
357                                           &(instr->third_operand.size));
358
359       if (v3_reg_type == -1) {
360         PrintError("Third operand is an Unhandled Operand: %s\n", xed_reg_enum_t2str(xed_reg));
361         instr->third_operand.type = INVALID_OPERAND;
362         return -1;
363       } else if (v3_reg_type == SEGMENT_REGISTER) {
364         struct v3_segment * seg_reg = (struct v3_segment *)(instr->third_operand.operand);
365         instr->third_operand.operand = (addr_t)&(seg_reg->selector);
366       }
367
368
369       instr->third_operand.type = REG_OPERAND;
370
371
372     } else {
373       //      PrintError("Unhandled third operand type %s\n", xed_operand_type_enum_t2str(op_type));
374       return -1;
375     }
376
377
378   }
379
380
381
382     return 0;
383 }
384
385
386 int v3_encode(struct guest_info * info, struct x86_instr * instr, char * instr_buf) {
387
388   return -1;
389 }
390
391
392
393
394
395 static int get_memory_operand(struct guest_info * info,  xed_decoded_inst_t * xed_instr, uint_t op_index, struct x86_operand * operand) {
396   struct memory_operand mem_op;
397
398   addr_t seg;
399   addr_t base;
400   addr_t scale;
401   addr_t index;
402   ullong_t displacement;
403   // struct v3_segment * seg_reg;
404
405
406
407
408   memset((void*)&mem_op, '\0', sizeof(struct memory_operand));
409
410   xed_reg_enum_t xed_seg = xed_decoded_inst_get_seg_reg(xed_instr, op_index);
411   if (xed_seg != XED_REG_INVALID) {
412     struct v3_segment *tmp_segment;
413     if (xed_reg_to_v3_reg(info, xed_seg, (addr_t *)&tmp_segment, &(mem_op.segment_size)) == -1) {
414       PrintError("Unhandled Segment Register\n");
415       return -1;
416     }
417     mem_op.segment = tmp_segment->base;
418   }
419
420   xed_reg_enum_t xed_base = xed_decoded_inst_get_base_reg(xed_instr, op_index);
421   if (xed_base != XED_REG_INVALID) {
422     addr_t base_reg;
423     if (xed_reg_to_v3_reg(info, xed_base, &base_reg, &(mem_op.base_size)) == -1) {
424       PrintError("Unhandled Base register\n");
425       return -1;
426     }
427     mem_op.base = *(addr_t *)base_reg;
428   }
429
430   
431
432   xed_reg_enum_t xed_idx = xed_decoded_inst_get_index_reg(xed_instr, op_index);
433   if ((op_index == 0) && (xed_idx != XED_REG_INVALID)) {
434     addr_t index_reg;
435     
436     if (xed_reg_to_v3_reg(info, xed_idx, &index_reg, &(mem_op.index_size)) == -1) {
437       PrintError("Unhandled Index Register\n");
438       return -1;
439     }
440
441     mem_op.index= *(addr_t *)index_reg;
442
443     xed_uint_t xed_scale = xed_decoded_inst_get_scale(xed_instr, op_index);
444     if (xed_scale != 0) {
445       mem_op.scale = xed_scale;
446     }
447   }
448
449
450   xed_uint_t disp_bits = xed_decoded_inst_get_memory_displacement_width(xed_instr, op_index);
451   if (disp_bits) {
452     xed_int64_t xed_disp = xed_decoded_inst_get_memory_displacement(xed_instr, op_index);
453
454     mem_op.displacement_size = disp_bits / 8;
455     mem_op.displacement = xed_disp;
456     
457   }
458
459   operand->type = MEM_OPERAND;
460   operand->size = xed_decoded_inst_get_memory_operand_length(xed_instr, op_index);
461   
462   
463
464   PrintDebug("Struct: Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", 
465              mem_op.segment, mem_op.base, mem_op.index, mem_op.scale, mem_op.displacement);
466
467
468   seg = mem_op.segment;
469   base = MASK(mem_op.base, mem_op.base_size);
470   index = MASK(mem_op.index, mem_op.index_size);
471   scale = mem_op.scale;
472   displacement = MASK(mem_op.displacement, mem_op.displacement_size);
473
474   PrintDebug("Seg=%x, base=%x, index=%x, scale=%x, displacement=%x\n", seg, base, index, scale, displacement);
475   
476   operand->operand = seg + base + (scale * index) + displacement;
477   return 0;
478 }
479
480
481 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) {
482
483   switch (xed_reg) {
484   case XED_REG_INVALID:
485     *v3_reg = 0;
486     *reg_len = 0;
487     return -1;
488
489     /* 
490      * GPRs
491      */
492   case XED_REG_RAX: 
493     *v3_reg = (addr_t)&(info->vm_regs.rax);
494     *reg_len = 8;
495     return GPR_REGISTER;
496   case XED_REG_EAX:
497     *v3_reg = (addr_t)&(info->vm_regs.rax);
498     *reg_len = 4;
499     return GPR_REGISTER;
500   case XED_REG_AX:
501     *v3_reg = (addr_t)&(info->vm_regs.rax);
502     *reg_len = 2;
503     return GPR_REGISTER;
504   case XED_REG_AH:
505     *v3_reg = (addr_t)(&(info->vm_regs.rax)) + 1;
506     *reg_len = 1;
507     return GPR_REGISTER;
508   case XED_REG_AL:
509     *v3_reg = (addr_t)&(info->vm_regs.rax);
510     *reg_len = 1;
511     return GPR_REGISTER;
512
513   case XED_REG_RCX: 
514     *v3_reg = (addr_t)&(info->vm_regs.rcx);
515     *reg_len = 8;
516     return GPR_REGISTER;
517   case XED_REG_ECX:
518     *v3_reg = (addr_t)&(info->vm_regs.rcx);
519     *reg_len = 4;
520     return GPR_REGISTER;
521   case XED_REG_CX:
522     *v3_reg = (addr_t)&(info->vm_regs.rcx);
523     *reg_len = 2;
524     return GPR_REGISTER;
525   case XED_REG_CH:
526     *v3_reg = (addr_t)(&(info->vm_regs.rcx)) + 1;
527     *reg_len = 1;
528     return GPR_REGISTER;
529   case XED_REG_CL:
530     *v3_reg = (addr_t)&(info->vm_regs.rcx);
531     *reg_len = 1;
532     return GPR_REGISTER;
533
534   case XED_REG_RDX: 
535     *v3_reg = (addr_t)&(info->vm_regs.rdx);
536     *reg_len = 8;
537     return GPR_REGISTER;
538   case XED_REG_EDX:
539     *v3_reg = (addr_t)&(info->vm_regs.rdx);
540     *reg_len = 4;
541     return GPR_REGISTER;
542   case XED_REG_DX:
543     *v3_reg = (addr_t)&(info->vm_regs.rdx);
544     *reg_len = 2;
545     return GPR_REGISTER;
546   case XED_REG_DH:
547     *v3_reg = (addr_t)(&(info->vm_regs.rdx)) + 1;
548     *reg_len = 1;
549     return GPR_REGISTER;
550   case XED_REG_DL:
551     *v3_reg = (addr_t)&(info->vm_regs.rdx);
552     *reg_len = 1;
553     return GPR_REGISTER;
554
555   case XED_REG_RBX: 
556     *v3_reg = (addr_t)&(info->vm_regs.rbx);
557     *reg_len = 8;
558     return GPR_REGISTER;
559   case XED_REG_EBX:
560     *v3_reg = (addr_t)&(info->vm_regs.rbx);
561     *reg_len = 4;
562     return GPR_REGISTER;
563   case XED_REG_BX:
564     *v3_reg = (addr_t)&(info->vm_regs.rbx);
565     *reg_len = 2;
566     return GPR_REGISTER;
567   case XED_REG_BH:
568     *v3_reg = (addr_t)(&(info->vm_regs.rbx)) + 1;
569     *reg_len = 1;
570     return GPR_REGISTER;
571   case XED_REG_BL:
572     *v3_reg = (addr_t)&(info->vm_regs.rbx);
573     *reg_len = 1;
574     return GPR_REGISTER;
575
576
577   case XED_REG_RSP:
578     *v3_reg = (addr_t)&(info->vm_regs.rsp);
579     *reg_len = 8;
580     return GPR_REGISTER;
581   case XED_REG_ESP:
582     *v3_reg = (addr_t)&(info->vm_regs.rsp);
583     *reg_len = 4;
584     return GPR_REGISTER;
585   case XED_REG_SP:
586     *v3_reg = (addr_t)&(info->vm_regs.rsp);
587     *reg_len = 2;
588     return GPR_REGISTER;
589   case XED_REG_SPL:
590     *v3_reg = (addr_t)&(info->vm_regs.rsp);
591     *reg_len = 1;
592     return GPR_REGISTER;
593
594   case XED_REG_RBP:
595     *v3_reg = (addr_t)&(info->vm_regs.rbp);
596     *reg_len = 8;
597     return GPR_REGISTER;
598   case XED_REG_EBP:
599     *v3_reg = (addr_t)&(info->vm_regs.rbp);
600     *reg_len = 4;
601     return GPR_REGISTER;
602   case XED_REG_BP:
603     *v3_reg = (addr_t)&(info->vm_regs.rbp);
604     *reg_len = 2;
605     return GPR_REGISTER;
606   case XED_REG_BPL:
607     *v3_reg = (addr_t)&(info->vm_regs.rbp);
608     *reg_len = 1;
609     return GPR_REGISTER;
610
611
612
613   case XED_REG_RSI:
614     *v3_reg = (addr_t)&(info->vm_regs.rsi);
615     *reg_len = 8;
616     return GPR_REGISTER;
617   case XED_REG_ESI:
618     *v3_reg = (addr_t)&(info->vm_regs.rsi);
619     *reg_len = 4;
620     return GPR_REGISTER;
621   case XED_REG_SI:
622     *v3_reg = (addr_t)&(info->vm_regs.rsi);
623     *reg_len = 2;
624     return GPR_REGISTER;
625   case XED_REG_SIL:
626     *v3_reg = (addr_t)&(info->vm_regs.rsi);
627     *reg_len = 1;
628     return GPR_REGISTER;
629
630
631   case XED_REG_RDI:
632     *v3_reg = (addr_t)&(info->vm_regs.rdi);
633     *reg_len = 8;
634     return GPR_REGISTER;
635   case XED_REG_EDI:
636     *v3_reg = (addr_t)&(info->vm_regs.rdi);
637     *reg_len = 4;
638     return GPR_REGISTER;
639   case XED_REG_DI:
640     *v3_reg = (addr_t)&(info->vm_regs.rdi);
641     *reg_len = 2;
642     return GPR_REGISTER;
643   case XED_REG_DIL:
644     *v3_reg = (addr_t)&(info->vm_regs.rdi);
645     *reg_len = 1;
646     return GPR_REGISTER;
647
648
649     /* 
650      *  CTRL REGS
651      */
652   case XED_REG_RIP:
653     *v3_reg = (addr_t)&(info->rip);
654     *reg_len = 8;
655     return CTRL_REGISTER;
656   case XED_REG_EIP:
657     *v3_reg = (addr_t)&(info->rip);
658     *reg_len = 4;
659     return CTRL_REGISTER;  
660   case XED_REG_IP:
661     *v3_reg = (addr_t)&(info->rip);
662     *reg_len = 2;
663     return CTRL_REGISTER;
664
665   case XED_REG_FLAGS:
666     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
667     *reg_len = 2;
668     return CTRL_REGISTER;
669   case XED_REG_EFLAGS:
670     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
671     *reg_len = 4;
672     return CTRL_REGISTER;
673   case XED_REG_RFLAGS:
674     *v3_reg = (addr_t)&(info->ctrl_regs.rflags);
675     *reg_len = 8;
676     return CTRL_REGISTER;
677
678   case XED_REG_CR0:
679     *v3_reg = (addr_t)&(info->ctrl_regs.cr0);
680     *reg_len = 4;
681     return CTRL_REGISTER;
682   case XED_REG_CR2:
683     *v3_reg = (addr_t)&(info->ctrl_regs.cr2);
684     *reg_len = 4;
685     return CTRL_REGISTER;
686   case XED_REG_CR3:
687     *v3_reg = (addr_t)&(info->ctrl_regs.cr3);
688     *reg_len = 4;
689     return CTRL_REGISTER;
690   case XED_REG_CR4:
691     *v3_reg = (addr_t)&(info->ctrl_regs.cr4);
692     *reg_len = 4;
693     return CTRL_REGISTER;
694   case XED_REG_CR8:
695     *v3_reg = (addr_t)&(info->ctrl_regs.cr8);
696     *reg_len = 4;
697     return CTRL_REGISTER;
698
699   case XED_REG_CR1:
700   case XED_REG_CR5:
701   case XED_REG_CR6:
702   case XED_REG_CR7:
703   case XED_REG_CR9:
704   case XED_REG_CR10:
705   case XED_REG_CR11:
706   case XED_REG_CR12:
707   case XED_REG_CR13:
708   case XED_REG_CR14:
709   case XED_REG_CR15:
710     return -1;
711
712
713
714
715     /* 
716      * SEGMENT REGS
717      */
718   case XED_REG_CS:
719     *v3_reg = (addr_t)&(info->segments.cs);
720     return SEGMENT_REGISTER;
721   case XED_REG_DS:
722     *v3_reg = (addr_t)&(info->segments.ds);
723     return SEGMENT_REGISTER;
724   case XED_REG_ES:
725     *v3_reg = (addr_t)&(info->segments.es);
726     return SEGMENT_REGISTER;
727   case XED_REG_SS:
728     *v3_reg = (addr_t)&(info->segments.ss);
729     return SEGMENT_REGISTER;
730   case XED_REG_FS:
731     *v3_reg = (addr_t)&(info->segments.fs);
732     return SEGMENT_REGISTER;
733   case XED_REG_GS:
734     *v3_reg = (addr_t)&(info->segments.gs);
735     return SEGMENT_REGISTER;
736
737
738   case XED_REG_GDTR:
739   case XED_REG_LDTR:
740   case XED_REG_IDTR:
741   case XED_REG_TR:
742     PrintError("Segment selector operand... Don't know how to handle this...\n");
743     return -1;
744
745     /* 
746      *  DEBUG REGS
747      */
748   case XED_REG_DR0:
749   case XED_REG_DR1:
750   case XED_REG_DR2:
751   case XED_REG_DR3:
752   case XED_REG_DR4:
753   case XED_REG_DR5:
754   case XED_REG_DR6:
755   case XED_REG_DR7:
756   case XED_REG_DR8:
757   case XED_REG_DR9:
758   case XED_REG_DR10:
759   case XED_REG_DR11:
760   case XED_REG_DR12:
761   case XED_REG_DR13:
762   case XED_REG_DR14:
763   case XED_REG_DR15:
764     return -1;
765
766
767
768
769   case XED_REG_R8:
770   case XED_REG_R8D:
771   case XED_REG_R8W:
772   case XED_REG_R8B:
773
774   case XED_REG_R9:
775   case XED_REG_R9D:
776   case XED_REG_R9W:
777   case XED_REG_R9B:
778
779   case XED_REG_R10:
780   case XED_REG_R10D:
781   case XED_REG_R10W:
782   case XED_REG_R10B:
783
784   case XED_REG_R11:
785   case XED_REG_R11D:
786   case XED_REG_R11W:
787   case XED_REG_R11B:
788
789   case XED_REG_R12:
790   case XED_REG_R12D:
791   case XED_REG_R12W:
792   case XED_REG_R12B:
793
794   case XED_REG_R13:
795   case XED_REG_R13D:
796   case XED_REG_R13W:
797   case XED_REG_R13B:
798
799   case XED_REG_R14:
800   case XED_REG_R14D:
801   case XED_REG_R14W:
802   case XED_REG_R14B:
803
804   case XED_REG_R15:
805   case XED_REG_R15D:
806   case XED_REG_R15W:
807   case XED_REG_R15B:
808
809   case XED_REG_XMM0:
810   case XED_REG_XMM1:
811   case XED_REG_XMM2:
812   case XED_REG_XMM3:
813   case XED_REG_XMM4:
814   case XED_REG_XMM5:
815   case XED_REG_XMM6:
816   case XED_REG_XMM7:
817   case XED_REG_XMM8:
818   case XED_REG_XMM9:
819   case XED_REG_XMM10:
820   case XED_REG_XMM11:
821   case XED_REG_XMM12:
822   case XED_REG_XMM13:
823   case XED_REG_XMM14:
824   case XED_REG_XMM15:
825
826   case XED_REG_MMX0:
827   case XED_REG_MMX1:
828   case XED_REG_MMX2:
829   case XED_REG_MMX3:
830   case XED_REG_MMX4:
831   case XED_REG_MMX5:
832   case XED_REG_MMX6:
833   case XED_REG_MMX7:
834
835   case XED_REG_ST0:
836   case XED_REG_ST1:
837   case XED_REG_ST2:
838   case XED_REG_ST3:
839   case XED_REG_ST4:
840   case XED_REG_ST5:
841   case XED_REG_ST6:
842   case XED_REG_ST7:
843
844   case XED_REG_ONE:
845   case XED_REG_STACKPUSH:
846   case XED_REG_STACKPOP:
847     
848   case XED_REG_TSC:
849   case XED_REG_TSCAUX:
850   case XED_REG_MSRS:
851
852   case XED_REG_X87CONTROL:
853   case XED_REG_X87STATUS:
854   case XED_REG_X87TOP:
855   case XED_REG_X87TAG:
856   case XED_REG_X87PUSH:
857   case XED_REG_X87POP:
858   case XED_REG_X87POP2:
859
860   case XED_REG_MXCSR:
861
862   case XED_REG_TMP0:
863   case XED_REG_TMP1:
864   case XED_REG_TMP2:
865   case XED_REG_TMP3:
866   case XED_REG_TMP4:
867   case XED_REG_TMP5:
868   case XED_REG_TMP6:
869   case XED_REG_TMP7:
870   case XED_REG_TMP8:
871   case XED_REG_TMP9:
872   case XED_REG_TMP10:
873   case XED_REG_TMP11:
874   case XED_REG_TMP12:
875   case XED_REG_TMP13:
876   case XED_REG_TMP14:
877   case XED_REG_TMP15:
878
879   case XED_REG_LAST:
880
881   case XED_REG_ERROR:
882     // error??
883     return -1;
884
885   }
886
887
888   return 0;
889 }
890
891
892
893 static int get_opcode(xed_iform_enum_t iform, addr_t * opcode) {
894
895   switch (iform) {
896   case XED_IFORM_MOV_CR_GPR64_CR:
897   case XED_IFORM_MOV_CR_GPR32_CR:
898     *opcode = (addr_t)&V3_OPCODE_MOVCR2;
899     break;
900
901   case XED_IFORM_MOV_CR_CR_GPR64:
902   case XED_IFORM_MOV_CR_CR_GPR32:
903     *opcode = (addr_t)&V3_OPCODE_MOV2CR;
904     break;
905
906
907   case XED_IFORM_LMSW_GPR16:
908     *opcode = (addr_t)&V3_OPCODE_LMSW;
909     break;
910
911   case XED_IFORM_CLTS:
912     *opcode = (addr_t)&V3_OPCODE_CLTS;
913     break;
914
915   default:
916     *opcode = 0;
917     return -1;
918   }
919
920   return 0;
921 }