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.


added segment offsets to memory operand calculations
[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 v3_gprs * gprs,                     
349                              uint8_t reg_code,
350                              struct x86_operand * reg) {
351
352     switch (reg_code) {
353         case 0:
354             reg->operand = (addr_t)&(gprs->rax);
355             break;
356         case 1:
357             reg->operand = (addr_t)&(gprs->rcx);
358             break;
359         case 2:
360             reg->operand = (addr_t)&(gprs->rdx);
361             break;
362         case 3:
363             reg->operand = (addr_t)&(gprs->rbx);
364             break;
365         case 4:
366             if (reg->size == 1) {
367                 reg->operand = (addr_t)&(gprs->rax) + 1;
368             } else {
369                 reg->operand = (addr_t)&(gprs->rsp);
370             }
371             break;
372         case 5:
373             if (reg->size == 1) {
374                 reg->operand = (addr_t)&(gprs->rcx) + 1;
375             } else {
376                 reg->operand = (addr_t)&(gprs->rbp);
377             }
378             break;
379         case 6:
380             if (reg->size == 1) {
381                 reg->operand = (addr_t)&(gprs->rdx) + 1;
382             } else {
383                 reg->operand = (addr_t)&(gprs->rsi);
384             }
385             break;
386         case 7:
387             if (reg->size == 1) {
388                 reg->operand = (addr_t)&(gprs->rbx) + 1;
389             } else {
390                 reg->operand = (addr_t)&(gprs->rdi);
391             }
392             break;
393         default:
394             reg->operand = 0;
395             break;
396     }
397
398     return 0;
399 }
400
401
402 // This converts the displacement into the appropriate masked value
403 /* 
404    QUESTION: Are the register Values signed ?????
405  */
406 #define MASK_DISPLACEMENT(reg, mode) ({                                 \
407             sint64_t val = 0;                                           \
408             if (mode == DISP8) {                                        \
409                 val = (sint8_t)(reg & 0xff);                            \
410             } else if (mode == DISP16) {                                \
411                 val = (sint16_t)(reg & 0xffff);                         \
412             } else if (mode == DISP32) {                                \
413                 val = (sint32_t)(reg & 0xffffffff);                     \
414             } else {                                                    \
415                 PrintError("Error invalid displacement size (%d)\n", mode); \
416                 V3_ASSERT(0);                                           \
417             }                                                           \
418             val;                                                        \
419         })
420
421 static  int decode_rm_operand16(struct guest_info * core,
422                                 uint8_t * modrm_instr, 
423                                 struct x86_instr * instr,
424                                 struct x86_operand * operand, 
425                                 uint8_t * reg_code) { 
426
427     struct v3_gprs * gprs = &(core->vm_regs);
428     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
429     addr_t base_addr = 0;
430     modrm_mode_t mod_mode = 0;
431     uint8_t * instr_cursor = modrm_instr;
432
433     //  PrintDebug("ModRM mod=%d\n", modrm->mod);
434     
435     *reg_code = modrm->reg;
436
437     instr_cursor += 1;
438
439     if (modrm->mod == 3) {
440         //PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
441         operand->type = REG_OPERAND;
442
443         decode_gpr(gprs, modrm->rm, operand);
444
445     } else {
446         struct v3_segment * seg = NULL;
447
448         operand->type = MEM_OPERAND;
449
450         if (modrm->mod == 0) {
451             mod_mode = DISP0;
452         } else if (modrm->mod == 1) {
453             mod_mode = DISP8;
454         } else if (modrm->mod == 2) {
455             mod_mode = DISP16;
456         }
457
458         switch (modrm->rm) {
459             case 0:
460                 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
461                 break;
462             case 1:
463                 base_addr = gprs->rbx + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
464                 break;
465             case 2:
466                 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rsi, mod_mode);
467                 break;
468             case 3:
469                 base_addr = gprs->rbp + MASK_DISPLACEMENT(gprs->rdi, mod_mode);
470                 break;
471             case 4:
472                 base_addr = gprs->rsi;
473                 break;
474             case 5:
475                 base_addr = gprs->rdi;
476                 break;
477             case 6:
478                 if (modrm->mod == 0) {
479                     base_addr = 0;
480                     mod_mode = DISP16;
481                 } else {
482                     base_addr = gprs->rbp;
483                 }
484                 break;
485             case 7:
486                 base_addr = gprs->rbx;
487                 break;
488         }
489
490
491
492         if (mod_mode == DISP8) {
493             base_addr += *(sint8_t *)instr_cursor;
494             instr_cursor += 1;
495         } else if (mod_mode == DISP16) {
496             base_addr += *(sint16_t *)instr_cursor;
497             instr_cursor += 2;
498         }
499     
500         
501         // get appropriate segment
502         if (instr->prefixes.cs_override) {
503             seg = &(core->segments.cs);
504         } else if (instr->prefixes.es_override) {
505             seg = &(core->segments.es);
506         } else if (instr->prefixes.ss_override) {
507             seg = &(core->segments.ss);
508         } else if (instr->prefixes.fs_override) {
509             seg = &(core->segments.fs);
510         } else if (instr->prefixes.gs_override) {
511             seg = &(core->segments.gs);
512         } else {
513             seg = &(core->segments.ds);
514         }
515         
516         operand->operand = get_addr_linear(core, base_addr, seg);
517     }
518
519
520     return (instr_cursor - modrm_instr);
521 }
522
523
524 // returns num_bytes parsed
525 static int decode_rm_operand32(struct guest_info * core, 
526                                uint8_t * modrm_instr,  
527                                struct x86_instr * instr,
528                                struct x86_operand * operand, 
529                                uint8_t * reg_code) {
530
531     struct v3_gprs * gprs = &(core->vm_regs);
532     uint8_t * instr_cursor = modrm_instr;
533     struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
534     addr_t base_addr = 0;
535     modrm_mode_t mod_mode = 0;
536     uint_t has_sib_byte = 0;
537
538
539     *reg_code = modrm->reg;
540
541     instr_cursor += 1;
542
543     if (modrm->mod == 3) {
544         operand->type = REG_OPERAND;
545         //    PrintDebug("first operand = Register (RM=%d)\n",modrm->rm);
546
547         decode_gpr(gprs, modrm->rm, operand);
548
549     } else {
550         struct v3_segment * seg = NULL;
551
552         operand->type = MEM_OPERAND;
553
554         if (modrm->mod == 0) {
555             mod_mode = DISP0;
556         } else if (modrm->mod == 1) {
557             mod_mode = DISP8;
558         } else if (modrm->mod == 2) {
559             mod_mode = DISP32;
560         }
561     
562         switch (modrm->rm) {
563             case 0:
564                 base_addr = gprs->rax;
565                 break;
566             case 1:
567                 base_addr = gprs->rcx;
568                 break;
569             case 2:
570                 base_addr = gprs->rdx;
571                 break;
572             case 3:
573                 base_addr = gprs->rbx;
574                 break;
575             case 4:
576                 has_sib_byte = 1;
577                 break;
578             case 5:
579                 if (modrm->mod == 0) {
580                     base_addr = 0;
581                     mod_mode = DISP32;
582                 } else {
583                     base_addr = gprs->rbp;
584                 }
585                 break;
586             case 6:
587                 base_addr = gprs->rsi;
588                 break;
589             case 7:
590                 base_addr = gprs->rdi;
591                 break;
592         }
593
594         if (has_sib_byte) {
595             instr_cursor += 1;
596             struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
597             int scale = 0x1 << sib->scale;
598
599             instr_cursor += 1;
600
601             switch (sib->index) {
602                 case 0:
603                     base_addr = gprs->rax;
604                     break;
605                 case 1:
606                     base_addr = gprs->rcx;
607                     break;
608                 case 2:
609                     base_addr = gprs->rdx;
610                     break;
611                 case 3:
612                     base_addr = gprs->rbx;
613                     break;
614                 case 4:
615                     base_addr = 0;
616                     break;
617                 case 5:
618                     base_addr = gprs->rbp;
619                     break;
620                 case 6:
621                     base_addr = gprs->rsi;
622                     break;
623                 case 7:
624                     base_addr = gprs->rdi;
625                     break;
626             }
627
628             base_addr *= scale;
629
630
631             switch (sib->base) {
632                 case 0:
633                     base_addr += MASK_DISPLACEMENT(gprs->rax, mod_mode);
634                     break;
635                 case 1:
636                     base_addr += MASK_DISPLACEMENT(gprs->rcx, mod_mode);
637                     break;
638                 case 2:
639                     base_addr += MASK_DISPLACEMENT(gprs->rdx, mod_mode);
640                     break;
641                 case 3:
642                     base_addr += MASK_DISPLACEMENT(gprs->rbx, mod_mode);
643                     break;
644                 case 4:
645                     base_addr += MASK_DISPLACEMENT(gprs->rsp, mod_mode);
646                     break;
647                 case 5:
648                     if (modrm->mod != 0) {
649                         base_addr += MASK_DISPLACEMENT(gprs->rbp, mod_mode);
650                     }
651                     break;
652                 case 6:
653                     base_addr += MASK_DISPLACEMENT(gprs->rsi, mod_mode);
654                     break;
655                 case 7:
656                     base_addr += MASK_DISPLACEMENT(gprs->rdi, mod_mode);
657                     break;
658             }
659
660         } 
661
662
663         if (mod_mode == DISP8) {
664             base_addr += *(sint8_t *)instr_cursor;
665             instr_cursor += 1;
666         } else if (mod_mode == DISP32) {
667             base_addr += *(sint32_t *)instr_cursor;
668             instr_cursor += 4;
669         }
670     
671         // get appropriate segment
672         if (instr->prefixes.cs_override) {
673             seg = &(core->segments.cs);
674         } else if (instr->prefixes.es_override) {
675             seg = &(core->segments.es);
676         } else if (instr->prefixes.ss_override) {
677             seg = &(core->segments.ss);
678         } else if (instr->prefixes.fs_override) {
679             seg = &(core->segments.fs);
680         } else if (instr->prefixes.gs_override) {
681             seg = &(core->segments.gs);
682         } else {
683             seg = &(core->segments.ds);
684         }
685         
686         operand->operand = get_addr_linear(core, base_addr, seg);
687     }
688
689
690     return (instr_cursor - modrm_instr);
691 }
692
693
694
695
696
697 static int decode_rm_operand(struct guest_info * core, 
698                              uint8_t * instr_ptr,        // input
699                              struct x86_instr * instr,
700                              struct x86_operand * operand, 
701                              uint8_t * reg_code) {
702     
703     v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
704
705     if (mode == REAL) {
706         return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
707     } else if ((mode == PROTECTED) || (mode == PROTECTED_PAE)) {
708         return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
709     } else {
710         PrintError("Invalid CPU_MODE (%d)\n", mode);
711         return -1;
712     }
713 }
714                              
715
716
717 static inline op_form_t op_code_to_form_0f(uint8_t * instr, int * length) {
718     *length += 1;
719
720     switch (instr[1]) {
721         case 0x01: {
722             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
723
724             switch (modrm->reg) {
725                 case 4:
726                     return SMSW;
727                 case 6:
728                     return LMSW;
729                 case 7:
730                     return INVLPG;
731                 default:
732                     return INVALID_INSTR;
733             }
734         }
735
736         case 0x06:
737             return CLTS;
738         case 0x20:
739             return MOV_CR2;
740         case 0x21:
741             return MOV_DR2;
742
743         case 0x22:
744             return MOV_2CR;
745         case 0x23:
746             return MOV_2DR;
747
748         case 0x90:
749             return SETO;
750         case 0x91:
751             return SETNO;
752         case 0x92:
753             return SETB;
754         case 0x93:
755             return SETNB;
756         case 0x94:
757             return SETZ;
758         case 0x95:
759             return SETNZ;
760         case 0x96:
761             return SETBE;
762         case 0x97:
763             return SETNBE;
764         case 0x98:
765             return SETS;
766         case 0x99:
767             return SETNS;
768         case 0x9a:
769             return SETP;
770         case 0x9b:
771             return SETNP;
772         case 0x9c:
773             return SETL;
774         case 0x9d:
775             return SETNL;
776         case 0x9e:
777             return SETLE;
778         case 0x9f:
779             return SETNLE;
780
781         case 0xb6:
782             return MOVZX_8;
783         case 0xb7:
784             return MOVZX;
785
786         case 0xbe:
787             return MOVSX_8;
788         case 0xbf:
789             return MOVSX;
790             
791
792         default:
793             return INVALID_INSTR;
794     }
795 }
796
797
798 static op_form_t op_code_to_form(uint8_t * instr, int * length) {
799     *length += 1;
800
801     switch (instr[0]) {
802         case 0x00:
803             return ADD_2MEM_8;
804         case 0x01:
805             return ADD_2MEM;
806         case 0x02:
807             return ADD_MEM2_8;
808         case 0x03:
809             return ADD_MEM2;
810
811         case 0x08:
812             return OR_2MEM_8;
813         case 0x09:
814             return OR_2MEM;
815         case 0x0a:
816             return OR_MEM2_8;
817         case 0x0b:
818             return OR_MEM2;
819
820
821         case 0x0f:
822             return op_code_to_form_0f(instr, length);
823
824         case 0x10:
825             return ADC_2MEM_8;
826         case 0x11:
827             return ADC_2MEM;
828         case 0x12:
829             return ADC_MEM2_8;
830         case 0x13:
831             return ADC_MEM2;
832
833         case 0x20:
834             return AND_2MEM_8; 
835         case 0x21:
836             return AND_2MEM;
837         case 0x22:
838             return AND_MEM2_8;
839         case 0x23:
840             return AND_MEM2;
841
842         case 0x28:
843             return SUB_2MEM_8;
844         case 0x29:
845             return SUB_2MEM;
846         case 0x2a:
847             return SUB_MEM2_8;
848         case 0x2b:
849             return SUB_MEM2;
850
851
852         case 0x30:
853             return XOR_2MEM_8;
854         case 0x31:
855             return XOR_2MEM;
856         case 0x32:
857             return XOR_MEM2_8;
858         case 0x33:
859             return XOR_MEM2;
860
861         case 0x80:{
862             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
863
864             switch (modrm->reg) {
865                 case 0:
866                     return ADD_IMM2_8;
867                 case 1:
868                     return OR_IMM2_8;
869                 case 2:
870                     return ADC_IMM2_8;
871                 case 4:
872                     return AND_IMM2_8;
873                 case 5:
874                     return SUB_IMM2_8;
875                 case 6:
876                     return XOR_IMM2_8;
877                 default:
878                     return INVALID_INSTR;
879             }
880         }
881         case 0x81: {
882             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
883             
884             switch (modrm->reg) {
885                 case 0:
886                     return ADD_IMM2;
887                 case 1:
888                     return OR_IMM2;
889                 case 2:
890                     return ADC_IMM2;
891                 case 4:
892                     return AND_IMM2;
893                 case 5:
894                     return SUB_IMM2;
895                 case 6:
896                     return XOR_IMM2;
897                 default:
898                     return INVALID_INSTR;
899             }
900         }
901         case 0x83: {
902             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
903
904             switch (modrm->reg) {
905                 case 0:
906                     return ADD_IMM2SX_8;
907                 case 1:
908                     return OR_IMM2SX_8;
909                 case 2:
910                     return ADC_IMM2SX_8;
911                 case 4:
912                     return AND_IMM2SX_8;
913                 case 5:
914                     return SUB_IMM2SX_8;
915                 case 6:
916                     return XOR_IMM2SX_8;
917                 default:
918                     return INVALID_INSTR;
919             }
920         }
921
922         case 0x86:
923             return XCHG_8;
924         case 0x87:
925             return XCHG;
926         case 0x88:
927             return MOV_2MEM_8;
928         case 0x89:
929             return MOV_2MEM;
930         case 0x8a:
931             return MOV_MEM2_8;
932         case 0x8b:
933             return MOV_MEM2;
934             
935         case 0x8c:
936             return MOV_SR2;
937         case 0x8e:
938             return MOV_2SR;
939
940
941         case 0x9c:
942             return PUSHF;
943         case 0x9d:
944             return POPF;
945
946         case 0xa0:
947             return MOV_MEM2AL_8;
948         case 0xa1:
949             return MOV_MEM2AX;
950         case 0xa2:
951             return MOV_AL2MEM_8;
952         case 0xa3:
953             return MOV_AX2MEM;
954
955         case 0xa4:
956             return MOVS_8;
957         case 0xa5:
958             return MOVS;
959
960         case 0xaa:
961             return STOS_8;
962         case 0xab:
963             return STOS;
964
965         case 0xc6:
966             return MOV_IMM2_8;
967         case 0xc7:
968             return MOV_IMM2;
969
970         case 0xf4:
971             return HLT;
972
973
974         case 0xf6: {
975             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
976
977             switch (modrm->reg) {
978                 case 2:
979                     return NOT_8;
980                 case 3:
981                     return NEG_8;
982                 default:
983                     return INVALID_INSTR;
984             }
985         }
986         case 0xf7: {
987             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
988
989             switch (modrm->reg) {
990                 case 2:
991                     return NOT;
992                 case 3:
993                     return NEG;
994                 default:
995                     return INVALID_INSTR;
996             }
997         }
998             
999
1000         case 0xfe: {
1001             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1002
1003             switch (modrm->reg) {
1004                 case 0:
1005                     return INC_8;
1006                 case 1:
1007                     return DEC_8;
1008                 default:
1009                     return INVALID_INSTR;
1010             }
1011         }
1012
1013         case 0xff: {
1014             struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1015
1016             switch (modrm->reg) {
1017                 case 0:
1018                     return INC;
1019                 case 1:
1020                     return DEC;
1021                 default:
1022                     return INVALID_INSTR;
1023             }
1024         }
1025
1026         default:
1027             return INVALID_INSTR;
1028     }
1029 }