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.


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