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.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
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.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm_types.h>
22 /* .... Giant fucking switch tables */
138 static int get_addr_width(struct guest_info * info, struct x86_instr * instr) {
140 switch (v3_get_vm_cpu_mode(info)) {
142 return (instr->prefixes.addr_size) ? 4 : 2;
148 if (info->segments.cs.db) {
149 return (instr->prefixes.addr_size) ? 2 : 4;
151 return (instr->prefixes.addr_size) ? 4 : 2;
154 PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
159 static int get_operand_width(struct guest_info * info, struct x86_instr * instr,
260 switch (v3_get_vm_cpu_mode(info)) {
262 return (instr->prefixes.op_size) ? 4 : 2;
264 if (instr->prefixes.rex_op_size) {
267 return (instr->prefixes.op_size) ? 2 : 4;
272 if (info->segments.cs.db) {
274 return (instr->prefixes.op_size) ? 2 : 4;
276 return (instr->prefixes.op_size) ? 4 : 2;
279 PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
283 switch (v3_get_vm_cpu_mode(info)) {
285 PrintError(info->vm_info, info, "Invalid instruction given operating mode (%d)\n", form);
294 PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
300 switch (v3_get_vm_cpu_mode(info)) {
310 PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
319 switch (v3_get_vm_cpu_mode(info)) {
329 PrintError(info->vm_info, info, "Unsupported CPU mode: %d\n", info->cpu_mode);
336 PrintError(info->vm_info, info, "Unsupported instruction form %d\n", form);
346 typedef enum {INVALID_ADDR_TYPE, REG, DISP0, DISP8, DISP16, DISP32} modrm_mode_t;
347 typedef enum {INVALID_REG_SIZE, REG64, REG32, REG16, REG8} reg_size_t;
354 } __attribute__((packed));
361 } __attribute__((packed));
368 static inline int decode_gpr(struct guest_info * core,
370 struct x86_operand * reg) {
372 struct v3_gprs * gprs = &(core->vm_regs);
376 reg->operand = (addr_t)&(gprs->rax);
379 reg->operand = (addr_t)&(gprs->rcx);
382 reg->operand = (addr_t)&(gprs->rdx);
385 reg->operand = (addr_t)&(gprs->rbx);
388 if (reg->size == 1) {
389 reg->operand = (addr_t)&(gprs->rax) + 1;
391 reg->operand = (addr_t)&(gprs->rsp);
395 if (reg->size == 1) {
396 reg->operand = (addr_t)&(gprs->rcx) + 1;
398 reg->operand = (addr_t)&(gprs->rbp);
402 if (reg->size == 1) {
403 reg->operand = (addr_t)&(gprs->rdx) + 1;
405 reg->operand = (addr_t)&(gprs->rsi);
409 if (reg->size == 1) {
410 reg->operand = (addr_t)&(gprs->rbx) + 1;
412 reg->operand = (addr_t)&(gprs->rdi);
416 reg->operand = (addr_t)&(gprs->r8);
419 reg->operand = (addr_t)&(gprs->r9);
422 reg->operand = (addr_t)&(gprs->r10);
425 reg->operand = (addr_t)&(gprs->r11);
428 reg->operand = (addr_t)&(gprs->r12);
431 reg->operand = (addr_t)&(gprs->r13);
434 reg->operand = (addr_t)&(gprs->r14);
437 reg->operand = (addr_t)&(gprs->r15);
440 PrintError(core->vm_info, core, "Invalid Reg Code (%d)\n", reg_code);
451 static inline int decode_cr(struct guest_info * core,
453 struct x86_operand * reg) {
455 struct v3_ctrl_regs * crs = &(core->ctrl_regs);
457 // PrintDebug(core->vm_info, core, "\t Ctrl regs %d\n", reg_code);
461 reg->operand = (addr_t)&(crs->cr0);
464 reg->operand = (addr_t)&(crs->cr2);
467 reg->operand = (addr_t)&(crs->cr3);
470 reg->operand = (addr_t)&(crs->cr4);
474 PrintError(core->vm_info, core, "Invalid Reg Code (%d)\n", reg_code);
481 static struct v3_segment * get_instr_segment(struct guest_info * core, struct x86_instr * instr) {
482 struct v3_segment * seg = &(core->segments.ds);
484 if (instr->prefixes.cs_override) {
485 seg = &(core->segments.cs);
486 } else if (instr->prefixes.es_override) {
487 seg = &(core->segments.es);
488 } else if (instr->prefixes.ss_override) {
489 seg = &(core->segments.ss);
490 } else if (instr->prefixes.fs_override) {
491 seg = &(core->segments.fs);
492 } else if (instr->prefixes.gs_override) {
493 seg = &(core->segments.gs);
501 #define ADDR_MASK(val, length) ({ \
502 ullong_t mask = 0x0LL; \
505 mask = 0x00000000000fffffLL; \
508 mask = 0x00000000ffffffffLL; \
511 mask = 0xffffffffffffffffLL; \
519 static int decode_rm_operand16(struct guest_info * core,
520 uint8_t * modrm_instr,
521 struct x86_instr * instr,
522 struct x86_operand * operand,
523 uint8_t * reg_code) {
525 struct v3_gprs * gprs = &(core->vm_regs);
526 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
527 addr_t base_addr = 0;
528 modrm_mode_t mod_mode = 0;
529 uint8_t * instr_cursor = modrm_instr;
531 // PrintDebug(core->vm_info, core, "ModRM mod=%d\n", modrm->mod);
533 *reg_code = modrm->reg;
537 if (modrm->mod == 3) {
538 //PrintDebug(core->vm_info, core, "first operand = Register (RM=%d)\n",modrm->rm);
539 operand->type = REG_OPERAND;
541 decode_gpr(core, modrm->rm, operand);
544 struct v3_segment * seg = NULL;
546 operand->type = MEM_OPERAND;
548 if (modrm->mod == 0) {
550 } else if (modrm->mod == 1) {
552 } else if (modrm->mod == 2) {
555 PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
556 v3_print_instr(instr);
562 base_addr = gprs->rbx + ADDR_MASK(gprs->rsi, 2);
565 base_addr = gprs->rbx + ADDR_MASK(gprs->rdi, 2);
568 base_addr = gprs->rbp + ADDR_MASK(gprs->rsi, 2);
571 base_addr = gprs->rbp + ADDR_MASK(gprs->rdi, 2);
574 base_addr = ADDR_MASK(gprs->rsi, 2);
577 base_addr = ADDR_MASK(gprs->rdi, 2);
580 if (modrm->mod == 0) {
584 base_addr = ADDR_MASK(gprs->rbp, 2);
588 base_addr = ADDR_MASK(gprs->rbx, 2);
594 if (mod_mode == DISP8) {
595 base_addr += *(sint8_t *)instr_cursor;
597 } else if (mod_mode == DISP16) {
598 base_addr += *(sint16_t *)instr_cursor;
603 // get appropriate segment
604 if (instr->prefixes.cs_override) {
605 seg = &(core->segments.cs);
606 } else if (instr->prefixes.es_override) {
607 seg = &(core->segments.es);
608 } else if (instr->prefixes.ss_override) {
609 seg = &(core->segments.ss);
610 } else if (instr->prefixes.fs_override) {
611 seg = &(core->segments.fs);
612 } else if (instr->prefixes.gs_override) {
613 seg = &(core->segments.gs);
615 seg = &(core->segments.ds);
618 operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg),
619 get_addr_width(core, instr));
623 return (instr_cursor - modrm_instr);
627 // returns num_bytes parsed
628 static int decode_rm_operand32(struct guest_info * core,
629 uint8_t * modrm_instr,
630 struct x86_instr * instr,
631 struct x86_operand * operand,
632 uint8_t * reg_code) {
634 struct v3_gprs * gprs = &(core->vm_regs);
635 uint8_t * instr_cursor = modrm_instr;
636 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
637 addr_t base_addr = 0;
638 modrm_mode_t mod_mode = 0;
639 uint_t has_sib_byte = 0;
642 *reg_code = modrm->reg;
646 if (modrm->mod == 3) {
647 operand->type = REG_OPERAND;
648 // PrintDebug(core->vm_info, core, "first operand = Register (RM=%d)\n",modrm->rm);
650 decode_gpr(core, modrm->rm, operand);
653 struct v3_segment * seg = NULL;
655 operand->type = MEM_OPERAND;
657 if (modrm->mod == 0) {
659 } else if (modrm->mod == 1) {
661 } else if (modrm->mod == 2) {
664 PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
665 v3_print_instr(instr);
671 base_addr = gprs->rax;
674 base_addr = gprs->rcx;
677 base_addr = gprs->rdx;
680 base_addr = gprs->rbx;
686 if (modrm->mod == 0) {
690 base_addr = gprs->rbp;
694 base_addr = gprs->rsi;
697 base_addr = gprs->rdi;
702 struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
703 int scale = 0x1 << sib->scale;
707 switch (sib->index) {
709 base_addr = gprs->rax;
712 base_addr = gprs->rcx;
715 base_addr = gprs->rdx;
718 base_addr = gprs->rbx;
724 base_addr = gprs->rbp;
727 base_addr = gprs->rsi;
730 base_addr = gprs->rdi;
739 base_addr += ADDR_MASK(gprs->rax, 4);
742 base_addr += ADDR_MASK(gprs->rcx, 4);
745 base_addr += ADDR_MASK(gprs->rdx, 4);
748 base_addr += ADDR_MASK(gprs->rbx, 4);
751 base_addr += ADDR_MASK(gprs->rsp, 4);
754 if (modrm->mod != 0) {
755 base_addr += ADDR_MASK(gprs->rbp, 4);
762 base_addr += ADDR_MASK(gprs->rsi, 4);
765 base_addr += ADDR_MASK(gprs->rdi, 4);
772 if (mod_mode == DISP8) {
773 base_addr += *(sint8_t *)instr_cursor;
775 } else if (mod_mode == DISP32) {
776 base_addr += *(sint32_t *)instr_cursor;
780 // get appropriate segment
781 if (instr->prefixes.cs_override) {
782 seg = &(core->segments.cs);
783 } else if (instr->prefixes.es_override) {
784 seg = &(core->segments.es);
785 } else if (instr->prefixes.ss_override) {
786 seg = &(core->segments.ss);
787 } else if (instr->prefixes.fs_override) {
788 seg = &(core->segments.fs);
789 } else if (instr->prefixes.gs_override) {
790 seg = &(core->segments.gs);
792 seg = &(core->segments.ds);
795 operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg),
796 get_addr_width(core, instr));
800 return (instr_cursor - modrm_instr);
804 int decode_rm_operand64(struct guest_info * core, uint8_t * modrm_instr,
805 struct x86_instr * instr, struct x86_operand * operand,
806 uint8_t * reg_code) {
808 struct v3_gprs * gprs = &(core->vm_regs);
809 uint8_t * instr_cursor = modrm_instr;
810 struct modrm_byte * modrm = (struct modrm_byte *)modrm_instr;
811 addr_t base_addr = 0;
812 modrm_mode_t mod_mode = 0;
813 uint_t has_sib_byte = 0;
818 *reg_code = modrm->reg;
819 *reg_code |= (instr->prefixes.rex_reg << 3);
821 if (modrm->mod == 3) {
822 uint8_t rm_val = modrm->rm;
824 rm_val |= (instr->prefixes.rex_rm << 3);
826 operand->type = REG_OPERAND;
827 // PrintDebug(core->vm_info, core, "first operand = Register (RM=%d)\n",modrm->rm);
829 decode_gpr(core, rm_val, operand);
831 struct v3_segment * seg = NULL;
832 uint8_t rm_val = modrm->rm;
834 operand->type = MEM_OPERAND;
837 if (modrm->mod == 0) {
839 } else if (modrm->mod == 1) {
841 } else if (modrm->mod == 2) {
844 PrintError(core->vm_info, core, "Instruction format error: Invalid mod_rm mode (%d)\n", modrm->mod);
845 v3_print_instr(instr);
852 rm_val |= (instr->prefixes.rex_rm << 3);
856 base_addr = gprs->rax;
859 base_addr = gprs->rcx;
862 base_addr = gprs->rdx;
865 base_addr = gprs->rbx;
868 if (modrm->mod == 0) {
872 base_addr = gprs->rbp;
876 base_addr = gprs->rsi;
879 base_addr = gprs->rdi;
882 base_addr = gprs->r8;
885 base_addr = gprs->r9;
888 base_addr = gprs->r10;
891 base_addr = gprs->r11;
894 base_addr = gprs->r12;
897 base_addr = gprs->r13;
900 base_addr = gprs->r14;
903 base_addr = gprs->r15;
911 struct sib_byte * sib = (struct sib_byte *)(instr_cursor);
912 int scale = 0x1 << sib->scale;
913 uint8_t index_val = sib->index;
914 uint8_t base_val = sib->base;
916 index_val |= (instr->prefixes.rex_sib_idx << 3);
917 base_val |= (instr->prefixes.rex_rm << 3);
923 base_addr = gprs->rax;
926 base_addr = gprs->rcx;
929 base_addr = gprs->rdx;
932 base_addr = gprs->rbx;
938 base_addr = gprs->rbp;
941 base_addr = gprs->rsi;
944 base_addr = gprs->rdi;
947 base_addr = gprs->r8;
950 base_addr = gprs->r9;
953 base_addr = gprs->r10;
956 base_addr = gprs->r11;
959 base_addr = gprs->r12;
962 base_addr = gprs->r13;
965 base_addr = gprs->r14;
968 base_addr = gprs->r15;
977 base_addr += gprs->rax;
980 base_addr += gprs->rcx;
983 base_addr += gprs->rdx;
986 base_addr += gprs->rbx;
989 base_addr += gprs->rsp;
992 if (modrm->mod != 0) {
993 base_addr += gprs->rbp;
1000 base_addr += gprs->rsi;
1003 base_addr += gprs->rdi;
1006 base_addr += gprs->r8;
1009 base_addr += gprs->r9;
1012 base_addr += gprs->r10;
1015 base_addr += gprs->r11;
1018 base_addr += gprs->r12;
1021 base_addr += gprs->r13;
1024 base_addr += gprs->r14;
1027 base_addr += gprs->r15;
1034 if (mod_mode == DISP8) {
1035 base_addr += *(sint8_t *)instr_cursor;
1037 } else if (mod_mode == DISP32) {
1038 base_addr += *(sint32_t *)instr_cursor;
1044 //Segments should be ignored
1045 // get appropriate segment
1047 if (instr->prefixes.cs_override) {
1048 seg = &(core->segments.cs);
1049 } else if (instr->prefixes.es_override) {
1050 seg = &(core->segments.es);
1051 } else if (instr->prefixes.ss_override) {
1052 seg = &(core->segments.ss);
1053 } else if (instr->prefixes.fs_override) {
1054 seg = &(core->segments.fs);
1055 } else if (instr->prefixes.gs_override) {
1056 seg = &(core->segments.gs);
1058 seg = &(core->segments.ds);
1062 operand->operand = ADDR_MASK(get_addr_linear(core, base_addr, seg),
1063 get_addr_width(core, instr));
1067 return (instr_cursor - modrm_instr);
1073 static int decode_rm_operand(struct guest_info * core,
1074 uint8_t * instr_ptr, // input
1076 struct x86_instr * instr,
1077 struct x86_operand * operand,
1078 uint8_t * reg_code) {
1080 v3_cpu_mode_t mode = v3_get_vm_cpu_mode(core);
1082 operand->size = get_operand_width(core, instr, form);
1086 return decode_rm_operand16(core, instr_ptr, instr, operand, reg_code);
1088 if (instr->prefixes.rex) {
1089 return decode_rm_operand64(core, instr_ptr, instr, operand, reg_code);
1093 case LONG_32_COMPAT:
1094 return decode_rm_operand32(core, instr_ptr, instr, operand, reg_code);
1096 PrintError(core->vm_info, core, "Invalid CPU_MODE (%d)\n", mode);
1103 static inline op_form_t op_code_to_form_0f(uint8_t * instr, int * length) {
1108 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[2]);
1110 switch (modrm->reg) {
1118 return INVALID_INSTR;
1179 return INVALID_INSTR;
1184 static op_form_t op_code_to_form(uint8_t * instr, int * length) {
1208 return op_code_to_form_0f(instr, length);
1248 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1250 switch (modrm->reg) {
1264 return INVALID_INSTR;
1268 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1270 switch (modrm->reg) {
1284 return INVALID_INSTR;
1288 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1290 switch (modrm->reg) {
1292 return ADD_IMM2SX_8;
1296 return ADC_IMM2SX_8;
1298 return AND_IMM2SX_8;
1300 return SUB_IMM2SX_8;
1302 return XOR_IMM2SX_8;
1304 return INVALID_INSTR;
1333 return MOV_MEM2AL_8;
1337 return MOV_AL2MEM_8;
1363 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1365 switch (modrm->reg) {
1371 return INVALID_INSTR;
1375 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1377 switch (modrm->reg) {
1383 return INVALID_INSTR;
1389 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1391 switch (modrm->reg) {
1397 return INVALID_INSTR;
1402 struct modrm_byte * modrm = (struct modrm_byte *)&(instr[1]);
1404 switch (modrm->reg) {
1410 return INVALID_INSTR;
1415 return INVALID_INSTR;
1421 static char * op_form_to_str(op_form_t form) {
1424 case LMSW: return "LMSW";
1425 case SMSW: return "SMSW";
1426 case CLTS: return "CLTS";
1427 case INVLPG: return "INVLPG";
1428 case MOV_CR2: return "MOV_CR2";
1429 case MOV_2CR: return "MOV_2CR";
1430 case MOV_DR2: return "MOV_DR2";
1431 case MOV_2DR: return "MOV_2DR";
1432 case MOV_SR2: return "MOV_SR2";
1433 case MOV_2SR: return "MOV_2SR";
1434 case MOV_MEM2_8: return "MOV_MEM2_8";
1435 case MOV_MEM2: return "MOV_MEM2";
1436 case MOV_2MEM_8: return "MOV_2MEM_8";
1437 case MOV_2MEM: return "MOV_2MEM";
1438 case MOV_MEM2AL_8: return "MOV_MEM2AL_8";
1439 case MOV_MEM2AX: return "MOV_MEM2AX";
1440 case MOV_AL2MEM_8: return "MOV_AL2MEM_8";
1441 case MOV_AX2MEM: return "MOV_AX2MEM";
1442 case MOV_IMM2_8: return "MOV_IMM2_8";
1443 case MOV_IMM2: return "MOV_IMM2";
1444 case MOVS_8: return "MOVS_8";
1445 case MOVS: return "MOVS";
1446 case MOVSX_8: return "MOVSX_8";
1447 case MOVSX: return "MOVSX";
1448 case MOVZX_8: return "MOVZX_8";
1449 case MOVZX: return "MOVZX";
1450 case HLT: return "HLT";
1451 case PUSHF: return "PUSHF";
1452 case POPF: return "POPF";
1453 case ADC_2MEM_8: return "ADC_2MEM_8";
1454 case ADC_2MEM: return "ADC_2MEM";
1455 case ADC_MEM2_8: return "ADC_MEM2_8";
1456 case ADC_MEM2: return "ADC_MEM2";
1457 case ADC_IMM2_8: return "ADC_IMM2_8";
1458 case ADC_IMM2: return "ADC_IMM2";
1459 case ADC_IMM2SX_8: return "ADC_IMM2SX_8";
1460 case ADD_IMM2_8: return "ADD_IMM2_8";
1461 case ADD_IMM2: return "ADD_IMM2";
1462 case ADD_IMM2SX_8: return "ADD_IMM2SX_8";
1463 case ADD_2MEM_8: return "ADD_2MEM_8";
1464 case ADD_2MEM: return "ADD_2MEM";
1465 case ADD_MEM2_8: return "ADD_MEM2_8";
1466 case ADD_MEM2: return "ADD_MEM2";
1467 case AND_MEM2_8: return "AND_MEM2_8";
1468 case AND_MEM2: return "AND_MEM2";
1469 case AND_2MEM_8: return "AND_2MEM_8";
1470 case AND_2MEM: return "AND_2MEM";
1471 case AND_IMM2_8: return "AND_IMM2_8";
1472 case AND_IMM2: return "AND_IMM2";
1473 case AND_IMM2SX_8: return "AND_IMM2SX_8";
1474 case OR_2MEM_8: return "OR_2MEM_8";
1475 case OR_2MEM: return "OR_2MEM";
1476 case OR_MEM2_8: return "OR_MEM2_8";
1477 case OR_MEM2: return "OR_MEM2";
1478 case OR_IMM2_8: return "OR_IMM2_8";
1479 case OR_IMM2: return "OR_IMM2";
1480 case OR_IMM2SX_8: return "OR_IMM2SX_8";
1481 case SUB_2MEM_8: return "SUB_2MEM_8";
1482 case SUB_2MEM: return "SUB_2MEM";
1483 case SUB_MEM2_8: return "SUB_MEM2_8";
1484 case SUB_MEM2: return "SUB_MEM2";
1485 case SUB_IMM2_8: return "SUB_IMM2_8";
1486 case SUB_IMM2: return "SUB_IMM2";
1487 case SUB_IMM2SX_8: return "SUB_IMM2SX_8";
1488 case XOR_2MEM_8: return "XOR_2MEM_8";
1489 case XOR_2MEM: return "XOR_2MEM";
1490 case XOR_MEM2_8: return "XOR_MEM2_8";
1491 case XOR_MEM2: return "XOR_MEM2";
1492 case XOR_IMM2_8: return "XOR_IMM2_8";
1493 case XOR_IMM2: return "XOR_IMM2";
1494 case XOR_IMM2SX_8: return "XOR_IMM2SX_8";
1495 case INC_8: return "INC_8";
1496 case INC: return "INC";
1497 case DEC_8: return "DEC_8";
1498 case DEC: return "DEC";
1499 case NEG_8: return "NEG_8";
1500 case NEG: return "NEG";
1501 case NOT_8: return "NOT_8";
1502 case NOT: return "NOT";
1503 case XCHG_8: return "XCHG_8";
1504 case XCHG: return "XCHG";
1505 case SETB: return "SETB";
1506 case SETBE: return "SETBE";
1507 case SETL: return "SETL";
1508 case SETLE: return "SETLE";
1509 case SETNB: return "SETNB";
1510 case SETNBE: return "SETNBE";
1511 case SETNL: return "SETNL";
1512 case SETNLE: return "SETNLE";
1513 case SETNO: return "SETNO";
1514 case SETNP: return "SETNP";
1515 case SETNS: return "SETNS";
1516 case SETNZ: return "SETNZ";
1517 case SETP: return "SETP";
1518 case SETS: return "SETS";
1519 case SETZ: return "SETZ";
1520 case SETO: return "SETO";
1521 case STOS_8: return "STOS_8";
1522 case STOS: return "STOS";
1523 case INT: return "INT";
1527 return "INVALID_INSTR";