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.


more decoder work
[palacios.git] / palacios / include / palacios / vmm_instr_decoder.h
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 #include <palacios/vmm_types.h>
21
22
23 /* .... Giant fucking switch tables */
24
25
26 typedef enum {
27     INVALID_INSTR,
28     LMSW,
29     SMSW,
30     CLTS,
31     INVLPG,
32
33     MOV_CR2,
34     MOV_2CR,
35     MOV_DR2,
36     MOV_2DR,
37     MOV_SR2,
38     MOV_2SR,
39
40     MOV_MEM2_8,
41     MOV_MEM2,
42     MOV_2MEM_8,
43     MOV_2MEM,
44     MOV_MEM2AL_8,
45     MOV_MEM2AX,
46     MOV_AL2MEM_8,
47     MOV_AX2MEM,
48     MOV_IMM2_8,
49     MOV_IMM2,
50
51     MOVS_8,
52     MOVS,
53     MOVSX_8,
54     MOVSX,
55     MOVZX_8,
56     MOVZX,
57
58     HLT,
59     PUSHF,
60     POPF,
61
62     ADC_2MEM_8,
63     ADC_2MEM,
64     ADC_MEM2_8,
65     ADC_MEM2,
66     ADC_IMM2_8,
67     ADC_IMM2,
68     ADC_IMM2SX_8,
69     ADD_IMM2_8,
70     ADD_IMM2,
71     ADD_IMM2SX_8,
72     ADD_2MEM_8,
73     ADD_2MEM,
74     ADD_MEM2_8,
75     ADD_MEM2,
76     AND_MEM2_8,
77     AND_MEM2,
78     AND_2MEM_8,
79     AND_2MEM,
80     AND_IMM2_8,
81     AND_IMM2,
82     AND_IMM2SX_8,
83     OR_2MEM_8,
84     OR_2MEM,
85     OR_MEM2_8,
86     OR_MEM2,
87     OR_IMM2_8,
88     OR_IMM2,
89     OR_IMM2SX_8,
90     SUB_2MEM_8,
91     SUB_2MEM,
92     SUB_MEM2_8,
93     SUB_MEM2,
94     SUB_IMM2_8,
95     SUB_IMM2,
96     SUB_IMM2SX_8,
97     XOR_2MEM_8,
98     XOR_2MEM,
99     XOR_MEM2_8,
100     XOR_MEM2,
101     XOR_IMM2_8,
102     XOR_IMM2,
103     XOR_IMM2SX_8,
104
105     INC_8,
106     INC,
107     DEC_8,
108     DEC,
109     NEG_8,
110     NEG, 
111     NOT_8,
112     NOT,
113     XCHG_8,
114     XCHG,
115
116     SETB,
117     SETBE,
118     SETL,
119     SETLE,
120     SETNB,
121     SETNBE,
122     SETNL,
123     SETNLE,
124     SETNO,
125     SETNP,
126     SETNS,
127     SETNZ,
128     SETP,
129     SETS,
130     SETZ,
131     SETO,
132
133     STOS_8,
134     STOS
135 } op_form_t;
136
137
138 static int get_addr_width(struct guest_info * info, struct x86_instr * instr,
139                           op_form_t form) {
140
141     switch (v3_get_vm_cpu_mode(info)) {
142         case REAL:
143             return (instr->prefixes.addr_size) ? 4 : 2;
144         case PROTECTED:
145         case PROTECTED_PAE:
146             return (instr->prefixes.addr_size) ? 2 : 4;
147         case LONG_32_COMPAT:
148         case LONG:
149         default:
150             PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
151             return -1;
152     }
153 }
154
155 static int get_operand_width(struct guest_info * info, struct x86_instr * instr, 
156                              op_form_t form) {
157     switch (form) {
158
159         case CLTS:
160         case HLT:
161             return 0;
162
163         case MOV_MEM2_8:
164         case MOV_2MEM_8:
165         case MOV_MEM2AL_8:
166         case MOV_AL2MEM_8:
167         case MOV_IMM2_8:
168         case MOVS_8:
169         case MOVSX_8:
170         case MOVZX_8:
171         case ADC_2MEM_8:
172         case ADC_MEM2_8:
173         case ADC_IMM2_8:
174         case ADD_IMM2_8:
175         case ADD_2MEM_8:
176         case ADD_MEM2_8:
177         case AND_MEM2_8:
178         case AND_2MEM_8:
179         case AND_IMM2_8:
180         case OR_2MEM_8:
181         case OR_MEM2_8:
182         case OR_IMM2_8:
183         case SUB_2MEM_8:
184         case XOR_2MEM_8:
185         case SUB_MEM2_8:
186         case SUB_IMM2_8:
187         case XOR_MEM2_8:
188         case XOR_IMM2_8:
189         case INC_8:
190         case DEC_8:
191         case NEG_8:
192         case NOT_8:
193         case XCHG_8:
194         case STOS_8:
195         case SETB:
196         case SETBE:
197         case SETL:
198         case SETLE:
199         case SETNB:
200         case SETNBE:
201         case SETNL:
202         case SETNLE:
203         case SETNO:
204         case SETNP:
205         case SETNS:
206         case SETNZ:
207         case SETP:
208         case SETS:
209         case SETZ:
210         case SETO:
211             return 1;
212
213         case LMSW:
214         case SMSW:
215             return 2;
216
217         case MOV_MEM2:
218         case MOV_2MEM:
219         case MOV_MEM2AX:
220         case MOV_AX2MEM:
221         case MOV_IMM2:      
222         case MOVS:
223         case MOVSX:
224         case MOVZX:
225         case ADC_2MEM:
226         case ADC_MEM2:
227         case ADC_IMM2:
228         case ADD_IMM2:
229         case ADD_2MEM:
230         case ADD_MEM2:
231         case AND_MEM2:
232         case AND_2MEM:
233         case AND_IMM2:
234         case OR_2MEM:
235         case OR_MEM2:
236         case OR_IMM2:
237         case SUB_2MEM:
238         case SUB_MEM2:
239         case SUB_IMM2:
240         case XOR_2MEM:
241         case XOR_MEM2:
242         case XOR_IMM2:
243         case INC:
244         case DEC:
245         case NEG: 
246         case NOT:
247         case STOS:
248         case XCHG:
249         case ADC_IMM2SX_8:
250         case AND_IMM2SX_8:
251         case ADD_IMM2SX_8:
252         case OR_IMM2SX_8:
253         case SUB_IMM2SX_8:
254         case XOR_IMM2SX_8:
255             switch (v3_get_vm_cpu_mode(info)) {
256                 case REAL:
257                     return (instr->prefixes.op_size) ? 4 : 2;
258                 case PROTECTED:
259                 case PROTECTED_PAE:
260                     return (instr->prefixes.op_size) ? 2 : 4;
261                 case LONG_32_COMPAT:
262                 case LONG:
263                 default:
264                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
265                     return -1;
266             }
267
268         case INVLPG:
269             switch (v3_get_vm_cpu_mode(info)) {
270                 case REAL:
271                     PrintError("Invalid instruction given operating mode (%d)\n", form);
272                     return 0;
273                 case PROTECTED:
274                 case PROTECTED_PAE:
275                     return 4;
276                 case LONG_32_COMPAT:
277                 case LONG:
278                 default:
279                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
280                     return -1;
281             }
282
283         case PUSHF:
284         case POPF:
285             switch (v3_get_vm_cpu_mode(info)) {
286                 case REAL:
287                     return 2;
288                 case PROTECTED:
289                 case PROTECTED_PAE:
290                     return 4;
291                 case LONG_32_COMPAT:
292                 case LONG:
293                 default:
294                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
295                     return -1;
296             }
297
298         case MOV_DR2:
299         case MOV_2DR:
300         case MOV_CR2:
301         case MOV_2CR:
302             switch (v3_get_vm_cpu_mode(info)) {
303                 case REAL:
304                 case PROTECTED:
305                 case PROTECTED_PAE:
306                     return 4;
307                 case LONG_32_COMPAT:
308                 case LONG:
309                 default:
310                     PrintError("Unsupported CPU mode: %d\n", info->cpu_mode);
311                     return -1;
312             }
313
314         case MOV_SR2:
315         case MOV_2SR:
316         default:
317             PrintError("Unsupported instruction form %d\n", form);
318             return -1;
319         
320     }
321     return 0;
322 }
323
324
325
326 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
327 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
328
329
330 struct modrm_byte {
331     uint_t rm   :   3;
332     uint_t reg  :   3;
333     uint_t mod  :   2;
334 } __attribute__((packed));
335
336
337 struct sib_byte {
338     uint_t base     :   3;
339     uint_t index    :   3;
340     uint_t scale    :   2;
341 } __attribute__((packed));
342
343
344
345
346 struct v3_gprs;
347
348 static inline int decode_gpr(struct guest_info * core,
349                              uint8_t reg_code,
350                              struct x86_operand * reg) {
351
352     struct v3_gprs * gprs = &(core->vm_regs);
353
354     switch (reg_code) {
355         case 0:
356             reg->operand = (addr_t)&(gprs->rax);
357             break;
358         case 1:
359             reg->operand = (addr_t)&(gprs->rcx);
360             break;
361         case 2:
362             reg->operand = (addr_t)&(gprs->rdx);
363             break;
364         case 3:
365             reg->operand = (addr_t)&(gprs->rbx);
366             break;
367         case 4:
368             if (reg->size == 1) {
369                 reg->operand = (addr_t)&(gprs->rax) + 1;
370             } else {
371                 reg->operand = (addr_t)&(gprs->rsp);
372             }
373             break;
374         case 5:
375             if (reg->size == 1) {
376                 reg->operand = (addr_t)&(gprs->rcx) + 1;
377             } else {
378                 reg->operand = (addr_t)&(gprs->rbp);
379             }
380             break;
381         case 6:
382             if (reg->size == 1) {
383                 reg->operand = (addr_t)&(gprs->rdx) + 1;
384             } else {
385                 reg->operand = (addr_t)&(gprs->rsi);
386             }
387             break;
388         case 7:
389             if (reg->size == 1) {
390                 reg->operand = (addr_t)&(gprs->rbx) + 1;
391             } else {
392                 reg->operand = (addr_t)&(gprs->rdi);
393             }
394             break;
395         default:
396             PrintError("Invalid Reg Code (%d)\n", reg_code);
397             reg->operand = 0;
398             return -1;
399     }
400
401     return 0;
402 }
403
404
405
406
407 static inline int decode_cr(struct guest_info * core,                   
408                              uint8_t reg_code,
409                              struct x86_operand * reg) {
410
411     struct v3_ctrl_regs * crs = &(core->ctrl_regs);
412
413     PrintDebug("\t Ctrl regs %d\n", reg_code);
414
415     switch (reg_code) {
416         case 0:
417             reg->operand = (addr_t)&(crs->cr0);
418             break;
419         case 2:
420             reg->operand = (addr_t)&(crs->cr2);
421             break;
422         case 3:
423             reg->operand = (addr_t)&(crs->cr3);
424             break;
425         case 4:
426             reg->operand = (addr_t)&(crs->cr4);
427             break;
428         default:
429             reg->operand = 0;
430             PrintError("Invalid Reg Code (%d)\n", reg_code);
431             return -1;
432     }
433
434     return 0;
435 }
436
437 // This converts the displacement into the appropriate masked value
438 /* 
439    QUESTION: Are the register Values signed ?????
440  */
441 #define MASK_DISPLACEMENT(reg, mode) ({                                 \
442             sint64_t val = 0;                                           \
443             if (mode == DISP8) {                                        \
444                 val = (sint8_t)(reg & 0xff);                            \
445             } else if (mode == DISP16) {                                \
446                 val = (sint16_t)(reg & 0xffff);                         \
447             } else if (mode == DISP32) {                                \
448                 val = (sint32_t)(reg & 0xffffffff);                     \
449             } else {                                                    \
450                 PrintError("Error invalid displacement size (%d)\n", mode); \
451                 /*V3_ASSERT(0);*/                                       \
452             }                                                           \
453             val;                                                        \
454         })
455
456 static  int decode_rm_operand16(struct guest_info * core,
457                                 uint8_t * modrm_instr, 
458                                 struct x86_instr * instr,
459                                 struct x86_operand * operand, 
460                                 uint8_t * reg_code) { 
461
462     struct v3_gprs * gprs = &(core->vm_regs);
463     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
464     addr_t base_addr = 0;
465     modrm_mode_t mod_mode = 0;
466     uint8_t * instr_cursor = modrm_instr;
467
468     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
469     
470     *reg_code = modrm->reg;
471
472     instr_cursor += 1;
473
474     if (modrm->mod == 3) {
475         //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
476         operand->type = REG_OPERAND;
477
478         decode_gpr(core, modrm->rm, operand);
479
480     } else {
481         struct v3_segment * seg = NULL;
482
483         operand->type = MEM_OPERAND;
484
485         if (modrm->mod == 0) {
486             mod_mode = DISP0;
487         } else if (modrm->mod == 1) {
488             mod_mode = DISP8;
489         } else if (modrm->mod == 2) {
490             mod_mode = DISP16;
491         }
492
493         switch (modrm->rm) {
494             case 0:
495                 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
496                 break;
497             case 1:
498                 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
499                 break;
500             case 2:
501                 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
502                 break;
503             case 3:
504                 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
505                 break;
506             case 4:
507                 base_addr = gprs->rsi;
508                 break;
509             case 5:
510                 base_addr = gprs->rdi;
511                 break;
512             case 6:
513                 if (modrm->mod == 0) {
514                     base_addr = 0;
515                     mod_mode = DISP16;
516                 } else {
517                     base_addr = gprs->rbp;
518                 }
519                 break;
520             case 7:
521                 base_addr = gprs->rbx;
522                 break;
523         }
524
525
526
527         if (mod_mode == DISP8) {
528             base_addr += *(sint8_t *)instr_cursor;
529             instr_cursor += 1;
530         } else if (mod_mode == DISP16) {
531             base_addr += *(sint16_t *)instr_cursor;
532             instr_cursor += 2;
533         }
534     
535         
536         // get appropriate segment
537         if (instr->prefixes.cs_override) {
538             seg = &(core->segments.cs);
539         } else if (instr->prefixes.es_override) {
540             seg = &(core->segments.es);
541         } else if (instr->prefixes.ss_override) {
542             seg = &(core->segments.ss);
543         } else if (instr->prefixes.fs_override) {
544             seg = &(core->segments.fs);
545         } else if (instr->prefixes.gs_override) {
546             seg = &(core->segments.gs);
547         } else {
548             seg = &(core->segments.ds);
549         }
550         
551         operand->operand = get_addr_linear(core, base_addr, seg);
552     }
553
554
555     return (instr_cursor - modrm_instr);
556 }
557
558
559 // returns num_bytes parsed
560 static int decode_rm_operand32(struct guest_info * core, 
561                                uint8_t * modrm_instr,  
562                                struct x86_instr * instr,
563                                struct x86_operand * operand, 
564                                uint8_t * reg_code) {
565
566     struct v3_gprs * gprs = &(core->vm_regs);
567     uint8_t * instr_cursor = modrm_instr;
568     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
569     addr_t base_addr = 0;
570     modrm_mode_t mod_mode = 0;
571     uint_t has_sib_byte = 0;
572
573
574     *reg_code = modrm->reg;
575
576     instr_cursor += 1;
577
578     if (modrm->mod == 3) {
579         operand->type = REG_OPERAND;
580         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
581
582         decode_gpr(core, modrm->rm, operand);
583
584     } else {
585         struct v3_segment * seg = NULL;
586
587         operand->type = MEM_OPERAND;
588
589         if (modrm->mod == 0) {
590             mod_mode = DISP0;
591         } else if (modrm->mod == 1) {
592             mod_mode = DISP8;
593         } else if (modrm->mod == 2) {
594             mod_mode = DISP32;
595         }
596     
597         switch (modrm->rm) {
598             case 0:
599                 base_addr = gprs->rax;
600                 break;
601             case 1:
602                 base_addr = gprs->rcx;
603                 break;
604             case 2:
605                 base_addr = gprs->rdx;
606                 break;
607             case 3:
608                 base_addr = gprs->rbx;
609                 break;
610             case 4:
611                 has_sib_byte = 1;
612                 break;
613             case 5:
614                 if (modrm->mod == 0) {
615                     base_addr = 0;
616                     mod_mode = DISP32;
617                 } else {
618                     base_addr = gprs->rbp;
619                 }
620                 break;
621             case 6:
622                 base_addr = gprs->rsi;
623                 break;
624             case 7:
625                 base_addr = gprs->rdi;
626                 break;
627         }
628
629         if (has_sib_byte) {
630             instr_cursor += 1;
631             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
632             int scale = 0x1 << sib->scale;
633
634             instr_cursor += 1;
635
636             switch (sib->index) {
637                 case 0:
638                     base_addr = gprs->rax;
639                     break;
640                 case 1:
641                     base_addr = gprs->rcx;
642                     break;
643                 case 2:
644                     base_addr = gprs->rdx;
645                     break;
646                 case 3:
647                     base_addr = gprs->rbx;
648                     break;
649                 case 4:
650                     base_addr = 0;
651                     break;
652                 case 5:
653                     base_addr = gprs->rbp;
654                     break;
655                 case 6:
656                     base_addr = gprs->rsi;
657                     break;
658                 case 7:
659                     base_addr = gprs->rdi;
660                     break;
661             }
662
663             base_addr *= scale;
664
665
666             switch (sib->base) {
667                 case 0:
668                     base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode);
669                     break;
670                 case 1:
671                     base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode);
672                     break;
673                 case 2:
674                     base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode);
675                     break;
676                 case 3:
677                     base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode);
678                     break;
679                 case 4:
680                     base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode);
681                     break;
682                 case 5:
683                     if (modrm->mod != 0) {
684                         base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode);
685                     }
686                     break;
687                 case 6:
688                     base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode);
689                     break;
690                 case 7:
691                     base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode);
692                     break;
693             }
694
695         } 
696
697
698         if (mod_mode == DISP8) {
699             base_addr += *(sint8_t *)instr_cursor;
700             instr_cursor += 1;
701         } else if (mod_mode == DISP32) {
702             base_addr += *(sint32_t *)instr_cursor;
703             instr_cursor += 4;
704         }
705     
706         // get appropriate segment
707         if (instr->prefixes.cs_override) {
708             seg = &(core->segments.cs);
709         } else if (instr->prefixes.es_override) {
710             seg = &(core->segments.es);
711         } else if (instr->prefixes.ss_override) {
712             seg = &(core->segments.ss);
713         } else if (instr->prefixes.fs_override) {
714             seg = &(core->segments.fs);
715         } else if (instr->prefixes.gs_override) {
716             seg = &(core->segments.gs);
717         } else {
718             seg = &(core->segments.ds);
719         }
720         
721         operand->operand = get_addr_linear(core, base_addr, seg);
722     }
723
724
725     return (instr_cursor - modrm_instr);
726 }
727
728
729
730
731
732 static int decode_rm_operand(struct guest_info * core, 
733                              uint8_t * instr_ptr,        // input
734                              struct x86_instr * instr,
735                              struct x86_operand * operand, 
736                              uint8_t * reg_code) {
737     
738     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
739
740     if (mode == REAL) {
741         return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
742     } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE)) {
743         return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
744     } else {
745         PrintError("Invalid CPU_MODE (%d)\n", mode);
746         return -1;
747     }
748 }
749                              
750
751
752 static inline op_form_t op_code_to_form_0f(uint8_t * instr, int * length) {
753     *length += 1;
754
755     switch (instr[1]) {
756         case 0x01: {
757             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
758
759             switch (modrm->reg) {
760                 case 4:
761                     return SMSW;
762                 case 6:
763                     return LMSW;
764                 case 7:
765                     return INVLPG;
766                 default:
767                     return INVALID_INSTR;
768             }
769         }
770
771         case 0x06:
772             return CLTS;
773         case 0x20:
774             return MOV_CR2;
775         case 0x21:
776             return MOV_DR2;
777
778         case 0x22:
779             return MOV_2CR;
780         case 0x23:
781             return MOV_2DR;
782
783         case 0x90:
784             return SETO;
785         case 0x91:
786             return SETNO;
787         case 0x92:
788             return SETB;
789         case 0x93:
790             return SETNB;
791         case 0x94:
792             return SETZ;
793         case 0x95:
794             return SETNZ;
795         case 0x96:
796             return SETBE;
797         case 0x97:
798             return SETNBE;
799         case 0x98:
800             return SETS;
801         case 0x99:
802             return SETNS;
803         case 0x9a:
804             return SETP;
805         case 0x9b:
806             return SETNP;
807         case 0x9c:
808             return SETL;
809         case 0x9d:
810             return SETNL;
811         case 0x9e:
812             return SETLE;
813         case 0x9f:
814             return SETNLE;
815
816         case 0xb6:
817             return MOVZX_8;
818         case 0xb7:
819             return MOVZX;
820
821         case 0xbe:
822             return MOVSX_8;
823         case 0xbf:
824             return MOVSX;
825             
826
827         default:
828             return INVALID_INSTR;
829     }
830 }
831
832
833 static op_form_t op_code_to_form(uint8_t * instr, int * length) {
834     *length += 1;
835
836     switch (instr[0]) {
837         case 0x00:
838             return ADD_2MEM_8;
839         case 0x01:
840             return ADD_2MEM;
841         case 0x02:
842             return ADD_MEM2_8;
843         case 0x03:
844             return ADD_MEM2;
845
846         case 0x08:
847             return OR_2MEM_8;
848         case 0x09:
849             return OR_2MEM;
850         case 0x0a:
851             return OR_MEM2_8;
852         case 0x0b:
853             return OR_MEM2;
854
855
856         case 0x0f:
857             return op_code_to_form_0f(instr, length);
858
859         case 0x10:
860             return ADC_2MEM_8;
861         case 0x11:
862             return ADC_2MEM;
863         case 0x12:
864             return ADC_MEM2_8;
865         case 0x13:
866             return ADC_MEM2;
867
868         case 0x20:
869             return AND_2MEM_8; 
870         case 0x21:
871             return AND_2MEM;
872         case 0x22:
873             return AND_MEM2_8;
874         case 0x23:
875             return AND_MEM2;
876
877         case 0x28:
878             return SUB_2MEM_8;
879         case 0x29:
880             return SUB_2MEM;
881         case 0x2a:
882             return SUB_MEM2_8;
883         case 0x2b:
884             return SUB_MEM2;
885
886
887         case 0x30:
888             return XOR_2MEM_8;
889         case 0x31:
890             return XOR_2MEM;
891         case 0x32:
892             return XOR_MEM2_8;
893         case 0x33:
894             return XOR_MEM2;
895
896         case 0x80:{
897             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
898
899             switch (modrm->reg) {
900                 case 0:
901                     return ADD_IMM2_8;
902                 case 1:
903                     return OR_IMM2_8;
904                 case 2:
905                     return ADC_IMM2_8;
906                 case 4:
907                     return AND_IMM2_8;
908                 case 5:
909                     return SUB_IMM2_8;
910                 case 6:
911                     return XOR_IMM2_8;
912                 default:
913                     return INVALID_INSTR;
914             }
915         }
916         case 0x81: {
917             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
918             
919             switch (modrm->reg) {
920                 case 0:
921                     return ADD_IMM2;
922                 case 1:
923                     return OR_IMM2;
924                 case 2:
925                     return ADC_IMM2;
926                 case 4:
927                     return AND_IMM2;
928                 case 5:
929                     return SUB_IMM2;
930                 case 6:
931                     return XOR_IMM2;
932                 default:
933                     return INVALID_INSTR;
934             }
935         }
936         case 0x83: {
937             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
938
939             switch (modrm->reg) {
940                 case 0:
941                     return ADD_IMM2SX_8;
942                 case 1:
943                     return OR_IMM2SX_8;
944                 case 2:
945                     return ADC_IMM2SX_8;
946                 case 4:
947                     return AND_IMM2SX_8;
948                 case 5:
949                     return SUB_IMM2SX_8;
950                 case 6:
951                     return XOR_IMM2SX_8;
952                 default:
953                     return INVALID_INSTR;
954             }
955         }
956
957         case 0x86:
958             return XCHG_8;
959         case 0x87:
960             return XCHG;
961         case 0x88:
962             return MOV_2MEM_8;
963         case 0x89:
964             return MOV_2MEM;
965         case 0x8a:
966             return MOV_MEM2_8;
967         case 0x8b:
968             return MOV_MEM2;
969             
970         case 0x8c:
971             return MOV_SR2;
972         case 0x8e:
973             return MOV_2SR;
974
975
976         case 0x9c:
977             return PUSHF;
978         case 0x9d:
979             return POPF;
980
981         case 0xa0:
982             return MOV_MEM2AL_8;
983         case 0xa1:
984             return MOV_MEM2AX;
985         case 0xa2:
986             return MOV_AL2MEM_8;
987         case 0xa3:
988             return MOV_AX2MEM;
989
990         case 0xa4:
991             return MOVS_8;
992         case 0xa5:
993             return MOVS;
994
995         case 0xaa:
996             return STOS_8;
997         case 0xab:
998             return STOS;
999
1000         case 0xc6:
1001             return MOV_IMM2_8;
1002         case 0xc7:
1003             return MOV_IMM2;
1004
1005         case 0xf4:
1006             return HLT;
1007
1008
1009         case 0xf6: {
1010             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1011
1012             switch (modrm->reg) {
1013                 case 2:
1014                     return NOT_8;
1015                 case 3:
1016                     return NEG_8;
1017                 default:
1018                     return INVALID_INSTR;
1019             }
1020         }
1021         case 0xf7: {
1022             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1023
1024             switch (modrm->reg) {
1025                 case 2:
1026                     return NOT;
1027                 case 3:
1028                     return NEG;
1029                 default:
1030                     return INVALID_INSTR;
1031             }
1032         }
1033             
1034
1035         case 0xfe: {
1036             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1037
1038             switch (modrm->reg) {
1039                 case 0:
1040                     return INC_8;
1041                 case 1:
1042                     return DEC_8;
1043                 default:
1044                     return INVALID_INSTR;
1045             }
1046         }
1047
1048         case 0xff: {
1049             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1050
1051             switch (modrm->reg) {
1052                 case 0:
1053                     return INC;
1054                 case 1:
1055                     return DEC;
1056                 default:
1057                     return INVALID_INSTR;
1058             }
1059         }
1060
1061         default:
1062             return INVALID_INSTR;
1063     }
1064 }
1065
1066
1067
1068 static char * op_form_to_str(op_form_t form) {
1069
1070     switch (form) {
1071         case LMSW: return "LMSW";
1072         case SMSW: return "SMSW";
1073         case CLTS: return "CLTS";
1074         case INVLPG: return "INVLPG";
1075         case MOV_CR2: return "MOV_CR2";
1076         case MOV_2CR: return "MOV_2CR";
1077         case MOV_DR2: return "MOV_DR2";
1078         case MOV_2DR: return "MOV_2DR";
1079         case MOV_SR2: return "MOV_SR2";
1080         case MOV_2SR: return "MOV_2SR";
1081         case MOV_MEM2_8: return "MOV_MEM2_8";
1082         case MOV_MEM2: return "MOV_MEM2";
1083         case MOV_2MEM_8: return "MOV_2MEM_8";
1084         case MOV_2MEM: return "MOV_2MEM";
1085         case MOV_MEM2AL_8: return "MOV_MEM2AL_8";
1086         case MOV_MEM2AX: return "MOV_MEM2AX";
1087         case MOV_AL2MEM_8: return "MOV_AL2MEM_8";
1088         case MOV_AX2MEM: return "MOV_AX2MEM";
1089         case MOV_IMM2_8: return "MOV_IMM2_8";
1090         case MOV_IMM2: return "MOV_IMM2";
1091         case MOVS_8: return "MOVS_8";
1092         case MOVS: return "MOVS";
1093         case MOVSX_8: return "MOVSX_8";
1094         case MOVSX: return "MOVSX";
1095         case MOVZX_8: return "MOVZX_8";
1096         case MOVZX: return "MOVZX";
1097         case HLT: return "HLT";
1098         case PUSHF: return "PUSHF";
1099         case POPF: return "POPF";
1100         case ADC_2MEM_8: return "ADC_2MEM_8";
1101         case ADC_2MEM: return "ADC_2MEM";
1102         case ADC_MEM2_8: return "ADC_MEM2_8";
1103         case ADC_MEM2: return "ADC_MEM2";
1104         case ADC_IMM2_8: return "ADC_IMM2_8";
1105         case ADC_IMM2: return "ADC_IMM2";
1106         case ADC_IMM2SX_8: return "ADC_IMM2SX_8";
1107         case ADD_IMM2_8: return "ADD_IMM2_8";
1108         case ADD_IMM2: return "ADD_IMM2";
1109         case ADD_IMM2SX_8: return "ADD_IMM2SX_8";
1110         case ADD_2MEM_8: return "ADD_2MEM_8";
1111         case ADD_2MEM: return "ADD_2MEM";
1112         case ADD_MEM2_8: return "ADD_MEM2_8";
1113         case ADD_MEM2: return "ADD_MEM2";
1114         case AND_MEM2_8: return "AND_MEM2_8";
1115         case AND_MEM2: return "AND_MEM2";
1116         case AND_2MEM_8: return "AND_2MEM_8";
1117         case AND_2MEM: return "AND_2MEM";
1118         case AND_IMM2_8: return "AND_IMM2_8";
1119         case AND_IMM2: return "AND_IMM2";
1120         case AND_IMM2SX_8: return "AND_IMM2SX_8";
1121         case OR_2MEM_8: return "OR_2MEM_8";
1122         case OR_2MEM: return "OR_2MEM";
1123         case OR_MEM2_8: return "OR_MEM2_8";
1124         case OR_MEM2: return "OR_MEM2";
1125         case OR_IMM2_8: return "OR_IMM2_8";
1126         case OR_IMM2: return "OR_IMM2";
1127         case OR_IMM2SX_8: return "OR_IMM2SX_8";
1128         case SUB_2MEM_8: return "SUB_2MEM_8";
1129         case SUB_2MEM: return "SUB_2MEM";
1130         case SUB_MEM2_8: return "SUB_MEM2_8";
1131         case SUB_MEM2: return "SUB_MEM2";
1132         case SUB_IMM2_8: return "SUB_IMM2_8";
1133         case SUB_IMM2: return "SUB_IMM2";
1134         case SUB_IMM2SX_8: return "SUB_IMM2SX_8";
1135         case XOR_2MEM_8: return "XOR_2MEM_8";
1136         case XOR_2MEM: return "XOR_2MEM";
1137         case XOR_MEM2_8: return "XOR_MEM2_8";
1138         case XOR_MEM2: return "XOR_MEM2";
1139         case XOR_IMM2_8: return "XOR_IMM2_8";
1140         case XOR_IMM2: return "XOR_IMM2";
1141         case XOR_IMM2SX_8: return "XOR_IMM2SX_8";
1142         case INC_8: return "INC_8";
1143         case INC: return "INC";
1144         case DEC_8: return "DEC_8";
1145         case DEC: return "DEC";
1146         case NEG_8: return "NEG_8";
1147         case NEG: return "NEG"; 
1148         case NOT_8: return "NOT_8";
1149         case NOT: return "NOT";
1150         case XCHG_8: return "XCHG_8";
1151         case XCHG: return "XCHG";
1152         case SETB: return "SETB";
1153         case SETBE: return "SETBE";
1154         case SETL: return "SETL";
1155         case SETLE: return "SETLE";
1156         case SETNB: return "SETNB";
1157         case SETNBE: return "SETNBE";
1158         case SETNL: return "SETNL";
1159         case SETNLE: return "SETNLE";
1160         case SETNO: return "SETNO";
1161         case SETNP: return "SETNP";
1162         case SETNS: return "SETNS";
1163         case SETNZ: return "SETNZ";
1164         case SETP: return "SETP";
1165         case SETS: return "SETS";
1166         case SETZ: return "SETZ";
1167         case SETO: return "SETO";
1168         case STOS_8: return "STOS_8";
1169         case STOS: return "STOS";
1170
1171         case INVALID_INSTR:
1172         default:
1173             return "INVALID_INSTR";
1174     }
1175 }