- Timestamp:
- Jun 1, 2022 7:38:29 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 151664
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Disassembler/DisasmCore.cpp
r93742 r95167 2479 2479 RT_NOREF_PV(pOp); RT_NOREF_PV(pParam); 2480 2480 2481 PCDISOPCODE pOpCode = &g_InvalidOpcode[0];2482 2483 2481 uint8_t byte = disReadByte(pDis, offInstr++); 2484 2482 pDis->bOpCode = disReadByte(pDis, offInstr++); … … 2494 2492 } 2495 2493 2496 switch(byte & 3) 2497 { 2498 case 0: 2499 pOpCode = g_aVexOpcodesMap[0] + pDis->bOpCode; 2500 break; 2501 // 0x66 prefix 2502 case 1: 2503 pOpCode = g_aVexOpcodesMap_66H[0] + pDis->bOpCode; 2504 2505 break; 2506 2507 // 0xF3 prefix 2508 case 2: 2509 pOpCode = g_aVexOpcodesMap_F3H[0] + pDis->bOpCode; 2510 break; 2511 2512 // 0xF2 prefix 2513 case 3: 2514 pOpCode = g_aVexOpcodesMap_F2H[0] + pDis->bOpCode; 2515 break; 2516 default: 2517 break; 2518 } 2494 PCDISOPMAPDESC const pRange = g_aapVexOpcodesMapRanges[byte & 3][1]; 2495 unsigned const idxOpcode = pDis->bOpCode - pRange->idxFirst; 2496 PCDISOPCODE pOpCode; 2497 if (idxOpcode < pRange->cOpcodes) 2498 pOpCode = &pRange->papOpcodes[idxOpcode]; 2499 else 2500 pOpCode = &g_InvalidOpcode[0]; 2519 2501 2520 2502 return disParseInstruction(offInstr, pOpCode, pDis); … … 2525 2507 { 2526 2508 RT_NOREF_PV(pOp); RT_NOREF_PV(pParam); 2527 2528 PCDISOPCODE pOpCode = NULL;2529 2509 2530 2510 uint8_t byte1 = disReadByte(pDis, offInstr++); … … 2546 2526 pDis->fPrefix |= DISPREFIX_REX; 2547 2527 2548 switch(byte2 & 3) 2549 { 2550 case 0: 2551 if (implOpcode >= 1 && implOpcode <= 3) // Other values are #UD. 2552 { 2553 pOpCode = g_aVexOpcodesMap[implOpcode - 1]; 2554 if (pOpCode != NULL) 2555 { 2556 switch (implOpcode) 2557 { 2558 case 2: 2559 if (pDis->bOpCode >= 0xf0) 2560 pOpCode = &pOpCode[pDis->bOpCode - 0xf0]; 2561 else pOpCode = g_InvalidOpcode; 2562 break; 2563 default: 2564 pOpCode = &pOpCode[pDis->bOpCode]; 2565 } 2566 } 2567 } 2568 break; 2569 // 0x66 prefix 2570 case 1: 2571 if (implOpcode >= 1 && implOpcode <= 3) // Other values are #UD. 2572 { 2573 pOpCode = g_aVexOpcodesMap_66H[implOpcode - 1]; 2574 if (pOpCode != NULL) 2575 pOpCode = &pOpCode[pDis->bOpCode]; 2576 } 2577 break; 2578 2579 // 0xF3 prefix 2580 case 2: 2581 if (implOpcode >= 1 && implOpcode <= 3) // Other values are #UD. 2582 { 2583 pOpCode = g_aVexOpcodesMap_F3H[implOpcode - 1]; 2584 if (pOpCode != NULL) 2585 { 2586 switch (implOpcode) 2587 { 2588 case 2: 2589 if (pDis->bOpCode >= 0xf0) 2590 pOpCode = &pOpCode[pDis->bOpCode - 0xf0]; 2591 else pOpCode = g_InvalidOpcode; 2592 break; 2593 default: 2594 pOpCode = &pOpCode[pDis->bOpCode]; 2595 } 2596 } 2597 2598 } 2599 break; 2600 2601 // 0xF2 prefix 2602 case 3: 2603 if (implOpcode >= 1 && implOpcode <= 3) // Other values are #UD. 2604 { 2605 pOpCode = g_aVexOpcodesMap_F2H[implOpcode - 1]; 2606 if (pOpCode != NULL) 2607 { 2608 switch (implOpcode) 2609 { 2610 case 2: 2611 if (pDis->bOpCode >= 0xf0) 2612 pOpCode = &pOpCode[pDis->bOpCode - 0xf0]; 2613 else pOpCode = g_InvalidOpcode; 2614 break; 2615 case 3: 2616 if (pDis->bOpCode != 0xf0) 2617 pOpCode = g_InvalidOpcode; 2618 break; 2619 default: 2620 pOpCode = &pOpCode[pDis->bOpCode]; 2621 } 2622 } 2623 } 2624 break; 2625 2626 default: 2627 break; 2628 } 2629 2630 if (pOpCode == NULL) 2631 pOpCode = g_InvalidOpcode; 2528 PCDISOPCODE pOpCode; 2529 if (implOpcode < RT_ELEMENTS(g_aapVexOpcodesMapRanges[byte2 & 3])) 2530 { 2531 PCDISOPMAPDESC const pRange = g_aapVexOpcodesMapRanges[byte2 & 3][implOpcode]; 2532 unsigned const idxOpcode = pDis->bOpCode - pRange->idxFirst; 2533 if (idxOpcode < pRange->cOpcodes) 2534 pOpCode = &pRange->papOpcodes[idxOpcode]; 2535 else 2536 pOpCode = &g_InvalidOpcode[0]; 2537 } 2538 else 2539 pOpCode = &g_InvalidOpcode[0]; 2632 2540 2633 2541 return disParseInstruction(offInstr, pOpCode, pDis); -
trunk/src/VBox/Disassembler/DisasmInternal.h
r93115 r95167 85 85 /** @} */ 86 86 87 /** 88 * Opcode map descriptor. 89 * 90 * This is used a number of places to save storage space where there are lots of 91 * invalid instructions and the beginning or end of the map. 92 */ 93 typedef struct DISOPMAPDESC 94 { 95 /** Pointer to the opcodes described by this structure. */ 96 PCDISOPCODE papOpcodes; 97 #if ARCH_BITS <= 32 98 uint16_t 99 #else 100 uint32_t 101 #endif 102 /** The map index corresponding to the first papOpcodes entry. */ 103 idxFirst, 104 /** Number of opcodes in the map. */ 105 cOpcodes; 106 } DISOPMAPDESC; 107 /** Pointer to a const opcode map descriptor. */ 108 typedef DISOPMAPDESC const *PCDISOPMAPDESC; 87 109 88 110 /** @name Opcode maps. … … 125 147 /** VEX opcodes table defined by [VEX.m-mmmm - 1]. 126 148 * 0Fh, 0F38h, 0F3Ah correspondingly, VEX.pp = 00b */ 127 extern PCDISOP CODE const g_aVexOpcodesMap[3];149 extern PCDISOPMAPDESC const g_apVexOpcodesMapRanges_None[3]; 128 150 129 151 /** VEX opcodes table defined by [VEX.m-mmmm - 1]. 130 152 * 0Fh, 0F38h, 0F3Ah correspondingly, VEX.pp = 01b (66h) */ 131 extern PCDISOP CODE const g_aVexOpcodesMap_66H[3];153 extern PCDISOPMAPDESC const g_apVexOpcodesMapRanges_66H[3]; 132 154 133 155 /** 0Fh, 0F38h, 0F3Ah correspondingly, VEX.pp = 10b (F3h) */ 134 extern PCDISOP CODE const g_aVexOpcodesMap_F3H[3];156 extern PCDISOPMAPDESC const g_apVexOpcodesMapRanges_F3H[3]; 135 157 136 158 /** 0Fh, 0F38h, 0F3Ah correspondingly, VEX.pp = 11b (F2h) */ 137 extern PCDISOPCODE const g_aVexOpcodesMap_F2H[3]; 159 extern PCDISOPMAPDESC const g_apVexOpcodesMapRanges_F2H[3]; 160 161 /** Two dimmentional map descriptor array: first index is by VEX.pp (prefix), 162 * second by the VEX.mmmm (map). 163 * The latter has to be bounced checked as we only have the first 4 maps. */ 164 extern PCDISOPMAPDESC const g_aapVexOpcodesMapRanges[4][4]; 138 165 /** @} */ 139 166 -
trunk/src/VBox/Disassembler/DisasmTables.cpp
r93115 r95167 3207 3207 3208 3208 /* Vex codes for two bytes opcodes starting with 0Fh */ 3209 const DISOPCODE g_aMapTwoBytesVex[256] = 3210 { 3211 /* 0 */ 3212 INVALID_OPCODE_BLOCK 3213 3209 const DISOPCODE g_aDisasVexMap1[] = 3210 { 3214 3211 /* 1 */ 3215 3212 OPVEX("vmovups %Vps,%Wps", IDX_ParseModRM, IDX_UseModRM, 0, 0, OP_MOVUPS, OP_PARM_Vps, OP_PARM_Wps, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_HARMLESS), … … 3317 3314 INVALID_OPCODE, 3318 3315 OPVEX("vshufps %Vps,%Hps,%Wps,%Ib", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, IDX_ParseImmByte, OP_SHUFPS, OP_PARM_Vps, OP_PARM_Hps, OP_PARM_Wps, OP_PARM_Ib, DISOPTYPE_HARMLESS), 3319 INVALID_OPCODE, 3320 INVALID_OPCODE, 3321 INVALID_OPCODE, 3322 INVALID_OPCODE, 3323 INVALID_OPCODE, 3324 INVALID_OPCODE, 3325 INVALID_OPCODE, 3326 INVALID_OPCODE, 3327 INVALID_OPCODE, 3328 3329 /* d */ 3330 INVALID_OPCODE_BLOCK 3331 3332 /* e */ 3333 INVALID_OPCODE_BLOCK 3334 3335 /* f */ 3336 INVALID_OPCODE_BLOCK 3337 }; 3316 }; 3317 const DISOPMAPDESC g_DisasVexMap1Range = { &g_aDisasVexMap1[0], 0x10, RT_ELEMENTS(g_aDisasVexMap1) }; 3338 3318 3339 3319 /* Vex codes for two bytes opcodes starting with 0Fh with prefix 66H*/ 3340 const DISOPCODE g_aMapTwoBytesVex_66H[256] = 3341 { 3342 /* 0 */ 3343 INVALID_OPCODE_BLOCK 3344 3320 static const DISOPCODE g_aDisasVexMap1_66[] = 3321 { 3345 3322 /* 1 */ 3346 3323 OPVEX("vmovupd %Vpd,%Wpd", IDX_ParseModRM, IDX_UseModRM, 0, 0, OP_MOVUPD, OP_PARM_Vpd, OP_PARM_Wpd, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_HARMLESS), … … 3523 3500 OPVEX("vpaddw %Vx,%Hx,%Wx", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_PADDW, OP_PARM_Vx, OP_PARM_Hx, OP_PARM_Wx, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3524 3501 OPVEX("vpaddd %Vx,%Hx,%Wx", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_PADDD, OP_PARM_Vx, OP_PARM_Hx, OP_PARM_Wx, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3525 INVALID_OPCODE, 3526 }; 3527 3528 const DISOPCODE g_aMapTwoBytesVex_F2H[256] = 3529 { 3530 /* 0 */ 3531 INVALID_OPCODE_BLOCK 3532 3502 }; 3503 const DISOPMAPDESC g_DisasVexMap1_66Range = { &g_aDisasVexMap1_66[0], 0x10, RT_ELEMENTS(g_aDisasVexMap1_66) }; 3504 3505 static const DISOPCODE g_aDisasVexMap1F2[] = 3506 { 3533 3507 /* 1 */ 3534 3508 OPVEX("vmovsd %Vx,%Hx,%Wsd", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_MOVSD, OP_PARM_Vx, OP_PARM_Hx, OP_PARM_Wsd, OP_PARM_NONE, DISOPTYPE_HARMLESS), … … 3665 3639 /* f */ 3666 3640 OPVEX("vlddqu %Vx,%Mx", IDX_ParseModRM, IDX_UseModRM, 0, 0, OP_LDDQU, OP_PARM_Vx, OP_PARM_Mx, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3667 INVALID_OPCODE, 3668 INVALID_OPCODE, 3669 INVALID_OPCODE, 3670 INVALID_OPCODE, 3671 INVALID_OPCODE, 3672 INVALID_OPCODE, 3673 INVALID_OPCODE, 3674 INVALID_OPCODE, 3675 INVALID_OPCODE, 3676 INVALID_OPCODE, 3677 INVALID_OPCODE, 3678 INVALID_OPCODE, 3679 INVALID_OPCODE, 3680 INVALID_OPCODE, 3681 INVALID_OPCODE, 3682 }; 3641 }; 3642 const DISOPMAPDESC g_DisasVexMap1F2Range = { &g_aDisasVexMap1F2[0], 0x10, RT_ELEMENTS(g_aDisasVexMap1F2) }; 3683 3643 3684 3644 /* Vex codes for two bytes opcodes starting with 0Fh with prefix F3H*/ 3685 const DISOPCODE g_aMapTwoBytesVex_F3H[256] = 3686 { 3687 3688 /* 0 */ 3689 INVALID_OPCODE_BLOCK 3690 3645 static const DISOPCODE g_aDisasVexMap1F3[] = 3646 { 3691 3647 /* 1 */ 3692 3648 OPVEX("vmovss %Vx,%Hx,%Wss", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_MOVSS, OP_PARM_Vx, OP_PARM_Hx, OP_PARM_Wss, OP_PARM_NONE, DISOPTYPE_HARMLESS), … … 3826 3782 INVALID_OPCODE, 3827 3783 OPVEX("vcvtdq2pd %Vx,%Wpd", IDX_ParseModRM, IDX_UseModRM, 0, 0, OP_CVTDQ2PD, OP_PARM_Vx, OP_PARM_Wpd, OP_PARM_NONE, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3828 INVALID_OPCODE, 3829 INVALID_OPCODE, 3830 INVALID_OPCODE, 3831 INVALID_OPCODE, 3832 INVALID_OPCODE, 3833 INVALID_OPCODE, 3834 INVALID_OPCODE, 3835 INVALID_OPCODE, 3836 INVALID_OPCODE, 3837 3838 /* f */ 3839 INVALID_OPCODE_BLOCK 3840 }; 3841 3842 const DISOPCODE g_aMapThreeBytesVex_0F38_F[16] = 3843 { 3844 INVALID_OPCODE, 3845 INVALID_OPCODE, 3784 }; 3785 const DISOPMAPDESC g_DisasVexMap1F3Range = { &g_aDisasVexMap1F3[0], 0x10, RT_ELEMENTS(g_aDisasVexMap1F3) }; 3786 3787 static const DISOPCODE g_aDisasVexMap2[] = 3788 { 3789 /** @todo vsha1nexte at 0xc8 + ? */ 3846 3790 OPVEX("andn %Gy,%By,%Ey", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_ANDN, OP_PARM_Gy, OP_PARM_By, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3847 3791 INVALID_OPCODE, … … 3850 3794 INVALID_OPCODE, 3851 3795 OPVEX("bextr %Gy,%By,%Ey", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_BEXTR, OP_PARM_Gy, OP_PARM_By, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3852 INVALID_OPCODE, 3853 INVALID_OPCODE, 3854 INVALID_OPCODE, 3855 INVALID_OPCODE, 3856 INVALID_OPCODE, 3857 INVALID_OPCODE, 3858 INVALID_OPCODE, 3859 INVALID_OPCODE 3860 }; 3861 3862 const DISOPCODE g_aMapThreeBytesVex_F30F38_F[16] = 3863 { 3864 INVALID_OPCODE, 3865 INVALID_OPCODE, 3866 INVALID_OPCODE, 3867 INVALID_OPCODE, 3796 }; 3797 const DISOPMAPDESC g_DisasVexMap2Range = { &g_aDisasVexMap2[0], 0xf2, RT_ELEMENTS(g_aDisasVexMap2) }; 3798 3799 static const DISOPCODE g_aDisasVexMap2F3[] = 3800 { 3801 /* 0xf3: */ 3802 INVALID_OPCODE, /** @todo vgrp17 */ 3868 3803 INVALID_OPCODE, 3869 3804 OPVEX("pext %Gy,%By,%Ey", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_PEXT, OP_PARM_Gy, OP_PARM_By, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3870 3805 INVALID_OPCODE, 3871 3806 OPVEX("sarx %Gy,%By,%Ey", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_SARX, OP_PARM_Gy, OP_PARM_By, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3872 INVALID_OPCODE, 3873 INVALID_OPCODE, 3874 INVALID_OPCODE, 3875 INVALID_OPCODE, 3876 INVALID_OPCODE, 3877 INVALID_OPCODE, 3878 INVALID_OPCODE, 3879 INVALID_OPCODE 3880 }; 3881 3882 const DISOPCODE g_aMapThreeBytesVex_F20F38_F[16] = 3883 { 3884 INVALID_OPCODE, 3885 INVALID_OPCODE, 3886 INVALID_OPCODE, 3887 INVALID_OPCODE, 3888 INVALID_OPCODE, 3807 }; 3808 const DISOPMAPDESC g_DisasVexMap2F3Range = { &g_aDisasVexMap2F3[0], 0xf3, RT_ELEMENTS(g_aDisasVexMap2F3) }; 3809 3810 static const DISOPCODE g_aDisasVexMap2F2[16] = 3811 { 3889 3812 OPVEX("pdep %Gy,%By,%Ey", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_PDEP, OP_PARM_Gy, OP_PARM_By, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3890 OPVEX("mulx %By,%Gy,%Ey", IDX_ParseVexDest, IDX_ParseModRM,IDX_UseModRM, 0, OP_MULX, OP_PARM_By, OP_PARM_Gy, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS),3813 OPVEX("mulx %By,%Gy,%Ey", IDX_ParseVexDest, IDX_ParseModRM, IDX_UseModRM, 0, OP_MULX, OP_PARM_By, OP_PARM_Gy, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3891 3814 OPVEX("shrx %Gy,%By,%Ey", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_SHRX, OP_PARM_Gy, OP_PARM_By, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS), 3892 INVALID_OPCODE, 3893 INVALID_OPCODE, 3894 INVALID_OPCODE, 3895 INVALID_OPCODE, 3896 INVALID_OPCODE, 3897 INVALID_OPCODE, 3898 INVALID_OPCODE, 3899 INVALID_OPCODE 3900 }; 3901 3902 const DISOPCODE g_aMapThreeBytesVex_660F38[256] = 3903 { 3904 3815 }; 3816 const DISOPMAPDESC g_DisasVexMap2F2Range = { &g_aDisasVexMap2F2[0], 0xf5, RT_ELEMENTS(g_aDisasVexMap2F2) }; 3817 3818 static const DISOPCODE g_aDisasVexMap2_66[] = 3819 { 3905 3820 /* 0 */ 3906 3821 OPVEX("vpshufb %Vx,%Hx,%Wx", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_PSHUFB, OP_PARM_Vx, OP_PARM_Hx, OP_PARM_Wx, OP_PARM_NONE, DISOPTYPE_HARMLESS), … … 4148 4063 INVALID_OPCODE, 4149 4064 OPVEX("shlx %Gy,%By,%Ey", IDX_ParseModRM, IDX_ParseVexDest, IDX_UseModRM, 0, OP_BEXTR, OP_PARM_Gy, OP_PARM_By, OP_PARM_Ey, OP_PARM_NONE, DISOPTYPE_HARMLESS), 4150 INVALID_OPCODE, 4151 INVALID_OPCODE, 4152 INVALID_OPCODE, 4153 INVALID_OPCODE, 4154 INVALID_OPCODE, 4155 INVALID_OPCODE, 4156 INVALID_OPCODE, 4157 INVALID_OPCODE, 4158 }; 4159 4160 const DISOPCODE g_aMapThreeBytesVex_660F3A[256] = 4065 }; 4066 const DISOPMAPDESC g_DisasVexMap2_66Range = { &g_aDisasVexMap2_66[0], 0x00, RT_ELEMENTS(g_aDisasVexMap2_66) }; 4067 4068 const DISOPCODE g_aDisasVexMap3[] = 4069 { 4070 INVALID_OPCODE, /* dummy */ 4071 }; 4072 const DISOPMAPDESC g_DisasVexMap3Range = { &g_aDisasVexMap3[0], 0, RT_ELEMENTS(g_aDisasVexMap3) }; 4073 4074 static const DISOPCODE g_aDisasVexMap3_66[] = 4161 4075 { 4162 4076 /* 0 */ … … 4310 4224 INVALID_OPCODE, 4311 4225 OPVEX("vaeskeygen %Vdq,%Wdq,%Ib", IDX_ParseModRM, IDX_UseModRM, IDX_ParseImmByte, 0, OP_AESKEYGEN, OP_PARM_Vdq, OP_PARM_Wdq, OP_PARM_Ib, OP_PARM_NONE, DISOPTYPE_HARMLESS), 4312 4313 /* e */ 4314 INVALID_OPCODE_BLOCK 4315 4316 /* f */ 4317 INVALID_OPCODE_BLOCK 4318 }; 4319 4320 const DISOPCODE g_aMapThreeBytesVex_F20F3A_F0[1] = 4226 }; 4227 const DISOPMAPDESC g_DisasVexMap3_66Range = { &g_aDisasVexMap3_66[0], 0x00, RT_ELEMENTS(g_aDisasVexMap3_66) }; 4228 4229 const DISOPCODE g_aDisasVexMap3F2[] = 4321 4230 { 4322 4231 OPVEX("rorx %Gy,%Ey,%Ib", IDX_ParseModRM, IDX_UseModRM, IDX_ParseImmByte, 0, OP_RORX, OP_PARM_Gy, OP_PARM_Ey, OP_PARM_Ib, OP_PARM_NONE, DISOPTYPE_HARMLESS), 4323 4232 }; 4324 4325 4326 PCDISOPCODE const g_aVexOpcodesMap[3] = 4327 { 4328 &g_aMapTwoBytesVex[0], // 0fh 2-byte opcodes 4329 &g_aMapThreeBytesVex_0F38_F[0],// 0f38h 3-byte opcodes 4330 NULL, // 0f3ah 3-byte opcodes 4331 }; 4332 4333 PCDISOPCODE const g_aVexOpcodesMap_66H[3] = 4334 { 4335 &g_aMapTwoBytesVex_66H[0], // 0fh 2-byte opcodes 4336 &g_aMapThreeBytesVex_660F38[0],// 0f38h 3-byte opcodes 4337 &g_aMapThreeBytesVex_660F3A[0],// 0f3ah 3-byte opcodes 4338 }; 4339 4340 PCDISOPCODE const g_aVexOpcodesMap_F2H[3] = 4341 { 4342 &g_aMapTwoBytesVex_F2H[0], // 0fh 2-byte opcodes 4343 &g_aMapThreeBytesVex_F20F38_F[0],// 0f38h 3-byte opcodes 4344 &g_aMapThreeBytesVex_F20F3A_F0[0],// 0f3ah 3-byte opcodes 4345 }; 4346 4347 PCDISOPCODE const g_aVexOpcodesMap_F3H[3] = 4348 { 4349 &g_aMapTwoBytesVex_F3H[0], // 0fh 2-byte opcodes 4350 &g_aMapThreeBytesVex_F30F38_F[0],// 0f38h 3-byte opcodes 4351 NULL, // 0f3ah 3-byte opcodes 4352 }; 4233 const DISOPMAPDESC g_DisasVexMap3F2Range = { &g_aDisasVexMap3F2[0], 0xf0, RT_ELEMENTS(g_aDisasVexMap3F2) }; 4234 4235 const DISOPCODE g_aDisasVexMap3F3[] = 4236 { 4237 INVALID_OPCODE, /* dummy */ 4238 }; 4239 const DISOPMAPDESC g_DisasVexMap3F3Range = { &g_aDisasVexMap3F3[0], 0, RT_ELEMENTS(g_aDisasVexMap3F3) }; 4240 4241 4242 /** Invalid range for the g_aapVexOpcodesMapRanges table. */ 4243 const DISOPMAPDESC g_DisasVexMapInvalidRange = { &g_InvalidOpcode[0], 0, 1 }; 4244 4245 4246 PCDISOPMAPDESC const g_aapVexOpcodesMapRanges[4][4] = 4247 { 4248 /* No prefix: */ 4249 { 4250 &g_DisasVexMapInvalidRange, 4251 &g_DisasVexMap1Range, // 0fh 2-byte opcodes 4252 &g_DisasVexMap2Range, // 0f38h 3-byte opcodes 4253 &g_DisasVexMap3Range, // 0f3ah 3-byte opcodes 4254 }, 4255 /* 66h prefix: */ 4256 { 4257 &g_DisasVexMapInvalidRange, 4258 &g_DisasVexMap1_66Range, // 0fh 2-byte opcodes 4259 &g_DisasVexMap2_66Range, // 0f38h 3-byte opcodes 4260 &g_DisasVexMap3_66Range, // 0f3ah 3-byte opcodes 4261 }, 4262 /* f3h prefix: */ 4263 { 4264 &g_DisasVexMapInvalidRange, 4265 &g_DisasVexMap1F3Range, // 0fh 2-byte opcodes 4266 &g_DisasVexMap2F3Range, // 0f38h 3-byte opcodes 4267 &g_DisasVexMap3F3Range, // 0f3ah 3-byte opcodes 4268 }, 4269 /* f2h prefix: */ 4270 { 4271 &g_DisasVexMapInvalidRange, 4272 &g_DisasVexMap1F2Range, // 0fh 2-byte opcodes 4273 &g_DisasVexMap2F2Range, // 0f38h 3-byte opcodes2 4274 &g_DisasVexMap3F2Range, // 0f3ah 3-byte opcodes 4275 } 4276 }; 4277 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
r93115 r95167 221 221 'Ew': ( 'IDX_UseModRM', 'rm', '%Ew', 'Ew', 'RM', ), 222 222 'Ev': ( 'IDX_UseModRM', 'rm', '%Ev', 'Ev', 'RM', ), 223 'Ey': ( 'IDX_UseModRM', 'rm', '%Ey', 'Ey', 'RM', ), 223 224 'Qq': ( 'IDX_UseModRM', 'rm', '%Qq', 'Qq', 'RM', ), 224 225 'Qq_WO': ( 'IDX_UseModRM', 'rm', '%Qq', 'Qq', 'RM', ), … … 270 271 'Gv': ( 'IDX_UseModRM', 'reg', '%Gv', 'Gv', '', ), 271 272 'Gv_RO': ( 'IDX_UseModRM', 'reg', '%Gv', 'Gv', '', ), 273 'Gy': ( 'IDX_UseModRM', 'reg', '%Gy', 'Gy', '', ), 272 274 'Pd': ( 'IDX_UseModRM', 'reg', '%Pd', 'Pd', '', ), 273 275 'PdZx_WO': ( 'IDX_UseModRM', 'reg', '%Pd', 'PdZx', '', ), … … 298 300 299 301 # VEX.vvvv 302 'By': ( 'IDX_UseModRM', 'vvvv', '%By', 'By', 'V', ), 300 303 'HssHi': ( 'IDX_UseModRM', 'vvvv', '%Hx', 'HssHi', 'V', ), 301 304 'HsdHi': ( 'IDX_UseModRM', 'vvvv', '%Hx', 'HsdHi', 'V', ), … … 368 371 'VEX_RVM_REG': ( 'VEX.ModR/M', [ 'reg', 'vvvv', 'rm' ], '11 mr/reg', ), 369 372 'VEX_RVM_MEM': ( 'VEX.ModR/M', [ 'reg', 'vvvv', 'rm' ], '!11 mr/reg', ), 373 'VEX_RMV': ( 'VEX.ModR/M', [ 'reg', 'rm', 'vvvv' ], '', ), 374 'VEX_RMV_REG': ( 'VEX.ModR/M', [ 'reg', 'rm', 'vvvv' ], '11 mr/reg', ), 375 'VEX_RMV_MEM': ( 'VEX.ModR/M', [ 'reg', 'rm', 'vvvv' ], '!11 mr/reg', ), 370 376 'VEX_MVR': ( 'VEX.ModR/M', [ 'rm', 'vvvv', 'reg' ], '', ), 371 377 'VEX_MVR_REG': ( 'VEX.ModR/M', [ 'rm', 'vvvv', 'reg' ], '11 mr/reg', ), … … 595 601 }; 596 602 ## Selectors. 597 ## The first value is the number of table entries required by a603 ## 1. The first value is the number of table entries required by a 598 604 ## decoder or disassembler for this type of selector. 605 ## 2. The second value is how many entries per opcode byte if applicable. 599 606 kdSelectors = { 600 'byte': [ 256, ], ##< next opcode byte selects the instruction (default). 601 '/r': [ 8, ], ##< modrm.reg selects the instruction. 602 'memreg /r':[ 16, ], ##< modrm.reg and (modrm.mod == 3) selects the instruction. 603 'mod /r': [ 32, ], ##< modrm.reg and modrm.mod selects the instruction. 604 '!11 /r': [ 8, ], ##< modrm.reg selects the instruction with modrm.mod != 0y11. 605 '11 /r': [ 8, ], ##< modrm.reg select the instruction with modrm.mod == 0y11. 606 '11': [ 64, ], ##< modrm.reg and modrm.rm select the instruction with modrm.mod == 0y11. 607 'byte': [ 256, 1, ], ##< next opcode byte selects the instruction (default). 608 'byte+pfx': [ 1024, 4, ], ##< next opcode byte selects the instruction together with the 0x66, 0xf2 and 0xf3 prefixes. 609 '/r': [ 8, 1, ], ##< modrm.reg selects the instruction. 610 'memreg /r':[ 16, 1, ], ##< modrm.reg and (modrm.mod == 3) selects the instruction. 611 'mod /r': [ 32, 1, ], ##< modrm.reg and modrm.mod selects the instruction. 612 '!11 /r': [ 8, 1, ], ##< modrm.reg selects the instruction with modrm.mod != 0y11. 613 '11 /r': [ 8, 1, ], ##< modrm.reg select the instruction with modrm.mod == 0y11. 614 '11': [ 64, 1, ], ##< modrm.reg and modrm.rm select the instruction with modrm.mod == 0y11. 607 615 }; 608 616 609 def __init__(self, sName, asLeadOpcodes = None, sSelector = 'byte', sEncoding = 'legacy', sDisParse = None): 617 ## Define the subentry number according to the Instruction::sPrefix 618 ## value for 'byte+pfx' selected tables. 619 kiPrefixOrder = { 620 'none': 0, 621 '0x66': 1, 622 '0xf3': 2, 623 '0xf2': 3, 624 }; 625 626 def __init__(self, sName, sIemName = None, asLeadOpcodes = None, sSelector = 'byte+pfx', 627 sEncoding = 'legacy', sDisParse = None): 610 628 assert sSelector in self.kdSelectors; 611 629 assert sEncoding in self.kdEncodings; … … 618 636 619 637 self.sName = sName; 638 self.sIemName = sIemName; 620 639 self.asLeadOpcodes = asLeadOpcodes; ##< Lead opcode bytes formatted as hex strings like '0x0f'. 621 640 self.sSelector = sSelector; ##< The member selector, see kdSelectors. … … 624 643 self.sDisParse = sDisParse; ##< IDX_ParseXXX. 625 644 645 def copy(self, sNewName, sPrefixFilter = None): 646 """ 647 Copies the table with filtering instruction by sPrefix if not None. 648 """ 649 oCopy = InstructionMap(sNewName, sIemName = self.sIemName, asLeadOpcodes = self.asLeadOpcodes, 650 sSelector = 'byte' if sPrefixFilter is not None and self.sSelector == 'byte+pfx' 651 else self.sSelector, 652 sEncoding = self.sEncoding, sDisParse = self.sDisParse); 653 if sPrefixFilter is None: 654 oCopy.aoInstructions = list(self.aoInstructions); 655 else: 656 oCopy.aoInstructions = [oInstr for oInstr in self.aoInstructions if oInstr.sPrefix == sPrefixFilter]; 657 return oCopy; 658 626 659 def getTableSize(self): 627 660 """ … … 630 663 return self.kdSelectors[self.sSelector][0]; 631 664 665 def getEntriesPerByte(self): 666 """ 667 Number of table entries per opcode bytes. 668 669 This only really makes sense for the 'byte' and 'byte+pfx' selectors, for 670 the others it will just return 1. 671 """ 672 return self.kdSelectors[self.sSelector][1]; 673 632 674 def getInstructionIndex(self, oInstr): 633 675 """ … … 636 678 bOpcode = oInstr.getOpcodeByte(); 637 679 638 # The byte selector issimple. We need a full opcode byte and need just return it.680 # The byte selectors are simple. We need a full opcode byte and need just return it. 639 681 if self.sSelector == 'byte': 640 682 assert oInstr.sOpcode[:2] == '0x' and len(oInstr.sOpcode) == 4, str(oInstr); 641 683 return bOpcode; 684 685 # The byte + prefix selector is similarly simple, though requires a prefix as well as the full opcode. 686 if self.sSelector == 'byte+pfx': 687 assert oInstr.sOpcode[:2] == '0x' and len(oInstr.sOpcode) == 4, str(oInstr); 688 assert self.kiPrefixOrder.get(oInstr.sPrefix, -16384) >= 0; 689 return bOpcode * 4 + self.kiPrefixOrder.get(oInstr.sPrefix, -16384); 642 690 643 691 # The other selectors needs masking and shifting. … … 717 765 return sName; 718 766 767 def getDisasRangeName(self): 768 """ 769 Returns the disassembler table range name for this map. 770 """ 771 return self.getDisasTableName().replace('g_aDisas', 'g_Disas') + 'Range'; 719 772 720 773 def isVexMap(self): … … 1338 1391 ## @name Core attributes. 1339 1392 ## @{ 1393 self.oParent = None # type: Instruction 1340 1394 self.sMnemonic = None; 1341 1395 self.sBrief = None; … … 1398 1452 1399 1453 aasFields.append(['opcode', self.sOpcode]); 1454 if self.sPrefix: 1455 aasFields.append(['prefix', self.sPrefix]); 1400 1456 aasFields.append(['mnemonic', self.sMnemonic]); 1401 1457 for iOperand, oOperand in enumerate(self.aoOperands): … … 1443 1499 return self.toString(True); 1444 1500 1501 def copy(self, oMap = None, sOpcode = None, sSubOpcode = None, sPrefix = None): 1502 """ 1503 Makes a copy of the object for the purpose of putting in a different map 1504 or a different place in the current map. 1505 """ 1506 oCopy = Instruction(self.sSrcFile, self.iLineCreated); 1507 1508 oCopy.oParent = self; 1509 oCopy.sMnemonic = self.sMnemonic; 1510 oCopy.sBrief = self.sBrief; 1511 oCopy.asDescSections = list(self.asDescSections); 1512 oCopy.aoMaps = [oMap,] if oMap else list(self.aoMaps); 1513 oCopy.aoOperands = list(self.aoOperands); ## Deeper copy? 1514 oCopy.sPrefix = sPrefix if sPrefix else self.sPrefix; 1515 oCopy.sOpcode = sOpcode if sOpcode else self.sOpcode; 1516 oCopy.sSubOpcode = sSubOpcode if sSubOpcode else self.sSubOpcode; 1517 oCopy.sEncoding = self.sEncoding; 1518 oCopy.asFlTest = self.asFlTest; 1519 oCopy.asFlModify = self.asFlModify; 1520 oCopy.asFlUndefined = self.asFlUndefined; 1521 oCopy.asFlSet = self.asFlSet; 1522 oCopy.asFlClear = self.asFlClear; 1523 oCopy.dHints = dict(self.dHints); 1524 oCopy.sDisEnum = self.sDisEnum; 1525 oCopy.asCpuIds = list(self.asCpuIds); 1526 oCopy.asReqFeatures = list(self.asReqFeatures); 1527 oCopy.aoTests = list(self.aoTests); ## Deeper copy? 1528 oCopy.sMinCpu = self.sMinCpu; 1529 oCopy.oCpuExpr = self.oCpuExpr; 1530 oCopy.sGroup = self.sGroup; 1531 oCopy.fUnused = self.fUnused; 1532 oCopy.fInvalid = self.fInvalid; 1533 oCopy.sInvalidStyle = self.sInvalidStyle; 1534 oCopy.sXcptType = self.sXcptType; 1535 1536 oCopy.sStats = self.sStats; 1537 oCopy.sFunction = self.sFunction; 1538 oCopy.fStub = self.fStub; 1539 oCopy.fUdStub = self.fUdStub; 1540 1541 oCopy.iLineCompleted = self.iLineCompleted; 1542 oCopy.cOpTags = self.cOpTags; 1543 oCopy.iLineFnIemOpMacro = self.iLineFnIemOpMacro; 1544 oCopy.iLineMnemonicMacro = self.iLineMnemonicMacro; 1545 1546 oCopy.sRawDisOpNo = self.sRawDisOpNo; 1547 oCopy.asRawDisParams = list(self.asRawDisParams); 1548 oCopy.sRawIemOpFlags = self.sRawIemOpFlags; 1549 oCopy.sRawOldOpcodes = self.sRawOldOpcodes; 1550 oCopy.asCopyTests = list(self.asCopyTests); 1551 1552 return oCopy; 1553 1445 1554 def getOpcodeByte(self): 1446 1555 """ … … 1528 1637 1529 1638 ## Instruction maps. 1530 g_dInstructionMaps = { 1531 'one': InstructionMap('one'), 1532 'grp1_80': InstructionMap('grp1_80', asLeadOpcodes = ['0x80',]), 1533 'grp1_81': InstructionMap('grp1_81', asLeadOpcodes = ['0x81',], sSelector = '/r'), 1534 'grp1_82': InstructionMap('grp1_82', asLeadOpcodes = ['0x82',], sSelector = '/r'), 1535 'grp1_83': InstructionMap('grp1_83', asLeadOpcodes = ['0x83',], sSelector = '/r'), 1536 'grp1a': InstructionMap('grp1a', asLeadOpcodes = ['0x8f',], sSelector = '/r'), 1537 'grp2_c0': InstructionMap('grp2_c0', asLeadOpcodes = ['0xc0',], sSelector = '/r'), 1538 'grp2_c1': InstructionMap('grp2_c1', asLeadOpcodes = ['0xc1',], sSelector = '/r'), 1539 'grp2_d0': InstructionMap('grp2_d0', asLeadOpcodes = ['0xd0',], sSelector = '/r'), 1540 'grp2_d1': InstructionMap('grp2_d1', asLeadOpcodes = ['0xd1',], sSelector = '/r'), 1541 'grp2_d2': InstructionMap('grp2_d2', asLeadOpcodes = ['0xd2',], sSelector = '/r'), 1542 'grp2_d3': InstructionMap('grp2_d3', asLeadOpcodes = ['0xd3',], sSelector = '/r'), 1543 'grp3_f6': InstructionMap('grp3_f6', asLeadOpcodes = ['0xf6',], sSelector = '/r'), 1544 'grp3_f7': InstructionMap('grp3_f7', asLeadOpcodes = ['0xf7',], sSelector = '/r'), 1545 'grp4': InstructionMap('grp4', asLeadOpcodes = ['0xfe',], sSelector = '/r'), 1546 'grp5': InstructionMap('grp5', asLeadOpcodes = ['0xff',], sSelector = '/r'), 1547 'grp11_c6_m': InstructionMap('grp11_c6_m',asLeadOpcodes = ['0xc6',], sSelector = '!11 /r'), 1548 'grp11_c6_r': InstructionMap('grp11_c6_r',asLeadOpcodes = ['0xc6',], sSelector = '11'), # xabort 1549 'grp11_c7_m': InstructionMap('grp11_c7_m',asLeadOpcodes = ['0xc7',], sSelector = '!11 /r'), 1550 'grp11_c7_r': InstructionMap('grp11_c7_r',asLeadOpcodes = ['0xc7',], sSelector = '11'), # xbegin 1551 1552 'two0f': InstructionMap('two0f', asLeadOpcodes = ['0x0f',], sDisParse = 'IDX_ParseTwoByteEsc'), 1553 'grp6': InstructionMap('grp6', asLeadOpcodes = ['0x0f', '0x00',], sSelector = '/r'), 1554 'grp7_m': InstructionMap('grp7_m', asLeadOpcodes = ['0x0f', '0x01',], sSelector = '!11 /r'), 1555 'grp7_r': InstructionMap('grp7_r', asLeadOpcodes = ['0x0f', '0x01',], sSelector = '11'), 1556 'grp8': InstructionMap('grp8', asLeadOpcodes = ['0x0f', '0xba',], sSelector = '/r'), 1557 'grp9': InstructionMap('grp9', asLeadOpcodes = ['0x0f', '0xc7',], sSelector = 'mod /r'), 1558 'grp10': InstructionMap('grp10', asLeadOpcodes = ['0x0f', '0xb9',], sSelector = '/r'), # UD1 /w modr/m 1559 'grp12': InstructionMap('grp12', asLeadOpcodes = ['0x0f', '0x71',], sSelector = 'mod /r'), 1560 'grp13': InstructionMap('grp13', asLeadOpcodes = ['0x0f', '0x72',], sSelector = 'mod /r'), 1561 'grp14': InstructionMap('grp14', asLeadOpcodes = ['0x0f', '0x73',], sSelector = 'mod /r'), 1562 'grp15': InstructionMap('grp15', asLeadOpcodes = ['0x0f', '0xae',], sSelector = 'memreg /r'), 1563 'grp16': InstructionMap('grp16', asLeadOpcodes = ['0x0f', '0x18',], sSelector = 'mod /r'), 1564 'grpA17': InstructionMap('grpA17', asLeadOpcodes = ['0x0f', '0x78',], sSelector = '/r'), # AMD: EXTRQ weirdness 1565 'grpP': InstructionMap('grpP', asLeadOpcodes = ['0x0f', '0x0d',], sSelector = '/r'), # AMD: prefetch 1566 1567 'three0f38': InstructionMap('three0f38', asLeadOpcodes = ['0x0f', '0x38',]), 1568 'three0f3a': InstructionMap('three0f3a', asLeadOpcodes = ['0x0f', '0x3a',]), 1569 1570 'vexmap1': InstructionMap('vexmap1', sEncoding = 'vex1'), 1571 'vexgrp12': InstructionMap('vexgrp12', sEncoding = 'vex1', asLeadOpcodes = ['0x71',], sSelector = 'mod /r'), 1572 'vexgrp13': InstructionMap('vexgrp13', sEncoding = 'vex1', asLeadOpcodes = ['0x72',], sSelector = 'mod /r'), 1573 'vexgrp14': InstructionMap('vexgrp14', sEncoding = 'vex1', asLeadOpcodes = ['0x73',], sSelector = 'mod /r'), 1574 'vexgrp15': InstructionMap('vexgrp15', sEncoding = 'vex1', asLeadOpcodes = ['0xae',], sSelector = 'memreg /r'), 1575 'vexgrp17': InstructionMap('vexgrp17', sEncoding = 'vex1', asLeadOpcodes = ['0xf3',], sSelector = '/r'), 1576 1577 'vexmap2': InstructionMap('vexmap2', sEncoding = 'vex2'), 1578 'vexmap3': InstructionMap('vexmap3', sEncoding = 'vex3'), 1579 1580 '3dnow': InstructionMap('3dnow', asLeadOpcodes = ['0x0f', '0x0f',]), 1581 'xopmap8': InstructionMap('xopmap8', sEncoding = 'xop8'), 1582 'xopmap9': InstructionMap('xopmap9', sEncoding = 'xop9'), 1583 'xopgrp1': InstructionMap('xopgrp1', sEncoding = 'xop9', asLeadOpcodes = ['0x01'], sSelector = '/r'), 1584 'xopgrp2': InstructionMap('xopgrp2', sEncoding = 'xop9', asLeadOpcodes = ['0x02'], sSelector = '/r'), 1585 'xopgrp3': InstructionMap('xopgrp3', sEncoding = 'xop9', asLeadOpcodes = ['0x12'], sSelector = '/r'), 1586 'xopmap10': InstructionMap('xopmap10', sEncoding = 'xop10'), 1587 'xopgrp4': InstructionMap('xopgrp4', sEncoding = 'xop10', asLeadOpcodes = ['0x12'], sSelector = '/r'), 1588 }; 1639 g_aoInstructionMaps = [ 1640 InstructionMap('one', 'g_apfnOneByteMap', sSelector = 'byte'), 1641 InstructionMap('grp1_80', asLeadOpcodes = ['0x80',], sSelector = '/r'), 1642 InstructionMap('grp1_81', asLeadOpcodes = ['0x81',], sSelector = '/r'), 1643 InstructionMap('grp1_82', asLeadOpcodes = ['0x82',], sSelector = '/r'), 1644 InstructionMap('grp1_83', asLeadOpcodes = ['0x83',], sSelector = '/r'), 1645 InstructionMap('grp1a', asLeadOpcodes = ['0x8f',], sSelector = '/r'), 1646 InstructionMap('grp2_c0', asLeadOpcodes = ['0xc0',], sSelector = '/r'), 1647 InstructionMap('grp2_c1', asLeadOpcodes = ['0xc1',], sSelector = '/r'), 1648 InstructionMap('grp2_d0', asLeadOpcodes = ['0xd0',], sSelector = '/r'), 1649 InstructionMap('grp2_d1', asLeadOpcodes = ['0xd1',], sSelector = '/r'), 1650 InstructionMap('grp2_d2', asLeadOpcodes = ['0xd2',], sSelector = '/r'), 1651 InstructionMap('grp2_d3', asLeadOpcodes = ['0xd3',], sSelector = '/r'), 1652 ## @todo g_apfnEscF1_E0toFF 1653 InstructionMap('grp3_f6', asLeadOpcodes = ['0xf6',], sSelector = '/r'), 1654 InstructionMap('grp3_f7', asLeadOpcodes = ['0xf7',], sSelector = '/r'), 1655 InstructionMap('grp4', asLeadOpcodes = ['0xfe',], sSelector = '/r'), 1656 InstructionMap('grp5', asLeadOpcodes = ['0xff',], sSelector = '/r'), 1657 InstructionMap('grp11_c6_m', asLeadOpcodes = ['0xc6',], sSelector = '!11 /r'), 1658 InstructionMap('grp11_c6_r', asLeadOpcodes = ['0xc6',], sSelector = '11'), # xabort 1659 InstructionMap('grp11_c7_m', asLeadOpcodes = ['0xc7',], sSelector = '!11 /r'), 1660 InstructionMap('grp11_c7_r', asLeadOpcodes = ['0xc7',], sSelector = '11'), # xbegin 1661 1662 InstructionMap('two0f', 'g_apfnTwoByteMap', asLeadOpcodes = ['0x0f',], sDisParse = 'IDX_ParseTwoByteEsc'), 1663 InstructionMap('grp6', 'g_apfnGroup6', asLeadOpcodes = ['0x0f', '0x00',], sSelector = '/r'), 1664 InstructionMap('grp7_m', 'g_apfnGroup7Mem', asLeadOpcodes = ['0x0f', '0x01',], sSelector = '!11 /r'), 1665 InstructionMap('grp7_r', asLeadOpcodes = ['0x0f', '0x01',], sSelector = '11'), 1666 InstructionMap('grp8', asLeadOpcodes = ['0x0f', '0xba',], sSelector = '/r'), 1667 InstructionMap('grp9', 'g_apfnGroup9RegReg', asLeadOpcodes = ['0x0f', '0xc7',], sSelector = 'mod /r'), 1668 ## @todo What about g_apfnGroup9MemReg? 1669 InstructionMap('grp10', None, asLeadOpcodes = ['0x0f', '0xb9',], sSelector = '/r'), # UD1 /w modr/m 1670 InstructionMap('grp12', 'g_apfnGroup12RegReg', asLeadOpcodes = ['0x0f', '0x71',], sSelector = 'mod /r'), 1671 InstructionMap('grp13', 'g_apfnGroup13RegReg', asLeadOpcodes = ['0x0f', '0x72',], sSelector = 'mod /r'), 1672 InstructionMap('grp14', 'g_apfnGroup14RegReg', asLeadOpcodes = ['0x0f', '0x73',], sSelector = 'mod /r'), 1673 InstructionMap('grp15', 'g_apfnGroup15MemReg', asLeadOpcodes = ['0x0f', '0xae',], sSelector = 'memreg /r'), 1674 ## @todo What about g_apfnGroup15RegReg? 1675 InstructionMap('grp16', asLeadOpcodes = ['0x0f', '0x18',], sSelector = 'mod /r'), 1676 InstructionMap('grpA17', asLeadOpcodes = ['0x0f', '0x78',], sSelector = '/r'), # AMD: EXTRQ weirdness 1677 InstructionMap('grpP', asLeadOpcodes = ['0x0f', '0x0d',], sSelector = '/r'), # AMD: prefetch 1678 1679 InstructionMap('three0f38', 'g_apfnThreeByte0f38', asLeadOpcodes = ['0x0f', '0x38',]), 1680 InstructionMap('three0f3a', 'g_apfnThreeByte0f3a', asLeadOpcodes = ['0x0f', '0x3a',]), 1681 1682 InstructionMap('vexmap1', 'g_apfnVexMap1', sEncoding = 'vex1'), 1683 InstructionMap('vexgrp12', 'g_apfnVexGroup12RegReg', sEncoding = 'vex1', asLeadOpcodes = ['0x71',], sSelector = 'mod /r'), 1684 InstructionMap('vexgrp13', 'g_apfnVexGroup13RegReg', sEncoding = 'vex1', asLeadOpcodes = ['0x72',], sSelector = 'mod /r'), 1685 InstructionMap('vexgrp14', 'g_apfnVexGroup14RegReg', sEncoding = 'vex1', asLeadOpcodes = ['0x73',], sSelector = 'mod /r'), 1686 InstructionMap('vexgrp15', 'g_apfnVexGroup15MemReg', sEncoding = 'vex1', asLeadOpcodes = ['0xae',], sSelector = 'memreg /r'), 1687 InstructionMap('vexgrp17', 'g_apfnVexGroup17_f3', sEncoding = 'vex1', asLeadOpcodes = ['0xf3',], sSelector = '/r'), 1688 1689 InstructionMap('vexmap2', 'g_apfnVexMap2', sEncoding = 'vex2'), 1690 InstructionMap('vexmap3', 'g_apfnVexMap3', sEncoding = 'vex3'), 1691 1692 InstructionMap('3dnow', asLeadOpcodes = ['0x0f', '0x0f',]), 1693 InstructionMap('xopmap8', sEncoding = 'xop8'), 1694 InstructionMap('xopmap9', sEncoding = 'xop9'), 1695 InstructionMap('xopgrp1', sEncoding = 'xop9', asLeadOpcodes = ['0x01'], sSelector = '/r'), 1696 InstructionMap('xopgrp2', sEncoding = 'xop9', asLeadOpcodes = ['0x02'], sSelector = '/r'), 1697 InstructionMap('xopgrp3', sEncoding = 'xop9', asLeadOpcodes = ['0x12'], sSelector = '/r'), 1698 InstructionMap('xopmap10', sEncoding = 'xop10'), 1699 InstructionMap('xopgrp4', sEncoding = 'xop10', asLeadOpcodes = ['0x12'], sSelector = '/r'), 1700 ]; 1701 g_dInstructionMaps = { oMap.sName: oMap for oMap in g_aoInstructionMaps }; 1702 g_dInstructionMapsByIemName = { oMap.sIemName: oMap for oMap in g_aoInstructionMaps }; 1589 1703 1590 1704 … … 1629 1743 self.oReGroupName = re.compile('^og_[a-z0-9]+(|_[a-z0-9]+|_[a-z0-9]+_[a-z0-9]+)$'); 1630 1744 self.oReDisEnum = re.compile('^OP_[A-Z0-9_]+$'); 1745 self.oReFunTable = re.compile('^(IEM_STATIC|static) +const +PFNIEMOP +g_apfn[A-Za-z0-9_]+ *\[ *\d* *\] *= *$'); 1746 self.oReComment = re.compile('//.*?$|/\*.*?\*/'); ## Full comments. 1631 1747 self.fDebug = True; 1632 1748 … … 1726 1842 print('debug: %s' % (sMessage,)); 1727 1843 1844 def stripComments(self, sLine): 1845 """ 1846 Returns sLine with comments stripped. 1847 1848 Complains if traces of incomplete multi-line comments are encountered. 1849 """ 1850 sLine = self.oReComment.sub(" ", sLine); 1851 if sLine.find('/*') >= 0 or sLine.find('*/') >= 0: 1852 self.error('Unexpected multi-line comment will not be handled correctly. Please simplify.'); 1853 return sLine; 1854 1855 def parseFunctionTable(self, sLine): 1856 """ 1857 Parses a PFNIEMOP table, updating/checking the @oppfx value. 1858 1859 Note! Updates iLine as it consumes the whole table. 1860 """ 1861 1862 # 1863 # Extract the table name. 1864 # 1865 sName = re.search(' *([a-zA-Z_0-9]+) *\[', sLine).group(1); 1866 oMap = g_dInstructionMapsByIemName.get(sName); 1867 if not oMap: 1868 self.debug('No map for PFNIEMOP table: %s' % (sName,)); 1869 oMap = self.oDefaultMap; # This is wrong wrong wrong. 1870 1871 # 1872 # All but the g_apfnOneByteMap & g_apfnEscF1_E0toFF tables uses four 1873 # entries per byte: 1874 # no prefix, 066h prefix, f3h prefix, f2h prefix 1875 # Those tables has 256 & 32 entries respectively. 1876 # 1877 cEntriesPerByte = 4; 1878 cValidTableLength = 1024; 1879 asPrefixes = ('none', '0x66', '0xf3', '0xf2'); 1880 1881 oEntriesMatch = re.search('\[ *(256|32) *\]', sLine); 1882 if oEntriesMatch: 1883 cEntriesPerByte = 1; 1884 cValidTableLength = int(oEntriesMatch.group(1)); 1885 asPrefixes = (None,); 1886 1887 # 1888 # The next line should be '{' and nothing else. 1889 # 1890 if self.iLine >= len(self.asLines) or not re.match('^ *{ *$', self.asLines[self.iLine]): 1891 return self.errorOnLine(self.iLine + 1, 'Expected lone "{" on line following PFNIEMOP table %s start' % (sName, )); 1892 self.iLine += 1; 1893 1894 # 1895 # Parse till we find the end of the table. 1896 # 1897 iEntry = 0; 1898 while self.iLine < len(self.asLines): 1899 # Get the next line and strip comments and spaces (assumes no 1900 # multi-line comments). 1901 sLine = self.asLines[self.iLine]; 1902 self.iLine += 1; 1903 sLine = self.stripComments(sLine).strip(); 1904 1905 # Split the line up into entries, expanding IEMOP_X4 usage. 1906 asEntries = sLine.split(','); 1907 for i in range(len(asEntries) - 1, -1, -1): 1908 sEntry = asEntries[i].strip(); 1909 if sEntry.startswith('IEMOP_X4(') and sEntry[-1] == ')': 1910 sEntry = (sEntry[len('IEMOP_X4('):-1]).strip(); 1911 asEntries.insert(i + 1, sEntry); 1912 asEntries.insert(i + 1, sEntry); 1913 asEntries.insert(i + 1, sEntry); 1914 if sEntry: 1915 asEntries[i] = sEntry; 1916 else: 1917 del asEntries[i]; 1918 1919 # Process the entries. 1920 for sEntry in asEntries: 1921 if sEntry in ('};', '}'): 1922 if iEntry != cValidTableLength: 1923 return self.error('Wrong table length for %s: %#x, expected %#x' % (sName, iEntry, cValidTableLength, )); 1924 return True; 1925 if sEntry.startswith('iemOp_Invalid'): 1926 pass; # skip 1927 else: 1928 # Look up matching instruction by function. 1929 sPrefix = asPrefixes[iEntry % cEntriesPerByte]; 1930 sOpcode = '%#04x' % (iEntry // cEntriesPerByte); 1931 aoInstr = g_dAllInstructionsByFunction.get(sEntry); 1932 if aoInstr: 1933 if not isinstance(aoInstr, list): 1934 aoInstr = [aoInstr,]; 1935 oInstr = None; 1936 for oCurInstr in aoInstr: 1937 if oCurInstr.sOpcode == sOpcode and oCurInstr.sPrefix == sPrefix: 1938 pass; 1939 elif oCurInstr.sOpcode == sOpcode and oCurInstr.sPrefix is None: 1940 oCurInstr.sPrefix = sPrefix; 1941 elif oCurInstr.sOpcode is None and oCurInstr.sPrefix is None: 1942 oCurInstr.sOpcode = sOpcode; 1943 oCurInstr.sPrefix = sPrefix; 1944 else: 1945 continue; 1946 oInstr = oCurInstr; 1947 break; 1948 if not oInstr: 1949 oInstr = aoInstr[0].copy(oMap = oMap, sOpcode = sOpcode, sPrefix = sPrefix); 1950 aoInstr.append(oInstr); 1951 g_dAllInstructionsByFunction[sEntry] = aoInstr; 1952 g_aoAllInstructions.append(oInstr); 1953 oMap.aoInstructions.append(oInstr); 1954 else: 1955 self.debug('Function "%s", entry %#04x / byte %#04x in %s, is not associated with an instruction.' 1956 % (sEntry, iEntry, iEntry // cEntriesPerByte, sName,)); 1957 iEntry += 1; 1958 1959 return self.error('Unexpected end of file in PFNIEMOP table'); 1728 1960 1729 1961 def addInstruction(self, iLine = None): … … 1870 2102 1871 2103 self.sComment = ''; 1872 self.aoCurInstrs 2104 self.aoCurInstrs = []; 1873 2105 return True; 1874 2106 … … 2584 2816 self.errorComment(iTagLine, '%s: invalid %s field "%s" in "%s"\nvalid fields: %s' 2585 2817 % ( sTag, sDesc, sField, sItem, 2586 ', '.join([sKey for sKey in TestInOut.kdFields2587 if TestInOut.kdFields[sKey][1] in asValidFieldKinds]),));2818 ', '.join([sKey for sKey, asVal in TestInOut.kdFields.items() 2819 if asVal[1] in asValidFieldKinds]),)); 2588 2820 break; 2589 2821 if oItem is not None: … … 3288 3520 self.doneInstructions(); 3289 3521 3522 # Look for instruction table on the form 'IEM_STATIC const PFNIEMOP g_apfnVexMap3' 3523 # so we can check/add @oppfx info from it. 3524 elif self.iState == self.kiCode and sLine.find('PFNIEMOP') > 0 and self.oReFunTable.match(sLine): 3525 self.parseFunctionTable(sLine); 3526 3290 3527 self.doneInstructions(); 3291 3528 self.debug('%3s stubs out of %3s instructions in %s' … … 3302 3539 # 3303 3540 try: 3304 oFile = open(sSrcFile, "r"); 3541 oFile = open(sSrcFile, "r"); # pylint: disable=consider-using-with 3305 3542 except Exception as oXcpt: 3306 3543 raise Exception("failed to open %s for reading: %s" % (sSrcFile, oXcpt,)); … … 3400 3637 # Generators (may perhaps move later). 3401 3638 # 3639 def __formatDisassemblerTableEntry(oInstr): 3640 """ 3641 """ 3642 sMacro = 'OP'; 3643 cMaxOperands = 3; 3644 if len(oInstr.aoOperands) > 3: 3645 sMacro = 'OPVEX' 3646 cMaxOperands = 4; 3647 assert len(oInstr.aoOperands) <= cMaxOperands; 3648 3649 # 3650 # Format string. 3651 # 3652 sTmp = '%s("%s' % (sMacro, oInstr.sMnemonic,); 3653 for iOperand, oOperand in enumerate(oInstr.aoOperands): 3654 sTmp += ' ' if iOperand == 0 else ','; 3655 if g_kdOpTypes[oOperand.sType][2][0] != '%': ## @todo remove upper() later. 3656 sTmp += g_kdOpTypes[oOperand.sType][2].upper(); ## @todo remove upper() later. 3657 else: 3658 sTmp += g_kdOpTypes[oOperand.sType][2]; 3659 sTmp += '",'; 3660 asColumns = [ sTmp, ]; 3661 3662 # 3663 # Decoders. 3664 # 3665 iStart = len(asColumns); 3666 if oInstr.sEncoding is None: 3667 pass; 3668 elif oInstr.sEncoding == 'ModR/M': 3669 # ASSUME the first operand is using the ModR/M encoding 3670 assert len(oInstr.aoOperands) >= 1 and oInstr.aoOperands[0].usesModRM(); 3671 asColumns.append('IDX_ParseModRM,'); 3672 elif oInstr.sEncoding in [ 'prefix', ]: 3673 for oOperand in oInstr.aoOperands: 3674 asColumns.append('0,'); 3675 elif oInstr.sEncoding in [ 'fixed', 'VEX.fixed' ]: 3676 pass; 3677 elif oInstr.sEncoding == 'VEX.ModR/M': 3678 asColumns.append('IDX_ParseModRM,'); 3679 elif oInstr.sEncoding == 'vex2': 3680 asColumns.append('IDX_ParseVex2b,') 3681 elif oInstr.sEncoding == 'vex3': 3682 asColumns.append('IDX_ParseVex3b,') 3683 elif oInstr.sEncoding in g_dInstructionMaps: 3684 asColumns.append(g_dInstructionMaps[oInstr.sEncoding].sDisParse + ','); 3685 else: 3686 ## @todo 3687 #IDX_ParseTwoByteEsc, 3688 #IDX_ParseGrp1, 3689 #IDX_ParseShiftGrp2, 3690 #IDX_ParseGrp3, 3691 #IDX_ParseGrp4, 3692 #IDX_ParseGrp5, 3693 #IDX_Parse3DNow, 3694 #IDX_ParseGrp6, 3695 #IDX_ParseGrp7, 3696 #IDX_ParseGrp8, 3697 #IDX_ParseGrp9, 3698 #IDX_ParseGrp10, 3699 #IDX_ParseGrp12, 3700 #IDX_ParseGrp13, 3701 #IDX_ParseGrp14, 3702 #IDX_ParseGrp15, 3703 #IDX_ParseGrp16, 3704 #IDX_ParseThreeByteEsc4, 3705 #IDX_ParseThreeByteEsc5, 3706 #IDX_ParseModFence, 3707 #IDX_ParseEscFP, 3708 #IDX_ParseNopPause, 3709 #IDX_ParseInvOpModRM, 3710 assert False, str(oInstr); 3711 3712 # Check for immediates and stuff in the remaining operands. 3713 for oOperand in oInstr.aoOperands[len(asColumns) - iStart:]: 3714 sIdx = g_kdOpTypes[oOperand.sType][0]; 3715 #if sIdx != 'IDX_UseModRM': 3716 asColumns.append(sIdx + ','); 3717 asColumns.extend(['0,'] * (cMaxOperands - (len(asColumns) - iStart))); 3718 3719 # 3720 # Opcode and operands. 3721 # 3722 assert oInstr.sDisEnum, str(oInstr); 3723 asColumns.append(oInstr.sDisEnum + ','); 3724 iStart = len(asColumns) 3725 for oOperand in oInstr.aoOperands: 3726 asColumns.append('OP_PARM_' + g_kdOpTypes[oOperand.sType][3] + ','); 3727 asColumns.extend(['OP_PARM_NONE,'] * (cMaxOperands - (len(asColumns) - iStart))); 3728 3729 # 3730 # Flags. 3731 # 3732 sTmp = ''; 3733 for sHint in sorted(oInstr.dHints.keys()): 3734 sDefine = g_kdHints[sHint]; 3735 if sDefine.startswith('DISOPTYPE_'): 3736 if sTmp: 3737 sTmp += ' | ' + sDefine; 3738 else: 3739 sTmp += sDefine; 3740 if sTmp: 3741 sTmp += '),'; 3742 else: 3743 sTmp += '0),'; 3744 asColumns.append(sTmp); 3745 3746 # 3747 # Format the columns into a line. 3748 # 3749 aoffColumns = [4, 29, 49, 65, 77, 89, 109, 125, 141, 157, 183, 199]; 3750 sLine = ''; 3751 for i, s in enumerate(asColumns): 3752 if len(sLine) < aoffColumns[i]: 3753 sLine += ' ' * (aoffColumns[i] - len(sLine)); 3754 else: 3755 sLine += ' '; 3756 sLine += s; 3757 3758 # OP("psrlw %Vdq,%Wdq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSRLW, OP_PARM_Vdq, OP_PARM_Wdq, OP_PARM_NONE, 3759 # DISOPTYPE_HARMLESS), 3760 # define OP(pszOpcode, idxParse1, idxParse2, idxParse3, opcode, param1, param2, param3, optype) \ 3761 # { pszOpcode, idxParse1, idxParse2, idxParse3, 0, opcode, param1, param2, param3, 0, 0, optype } 3762 return sLine; 3763 3764 def __checkIfShortTable(aoTableOrdered, oMap): 3765 """ 3766 Returns (iInstr, cInstructions, fShortTable) 3767 """ 3768 3769 # Determin how much we can trim off. 3770 cInstructions = len(aoTableOrdered); 3771 while cInstructions > 0 and aoTableOrdered[cInstructions - 1] is None: 3772 cInstructions -= 1; 3773 3774 iInstr = 0; 3775 while iInstr < cInstructions and aoTableOrdered[iInstr] is None: 3776 iInstr += 1; 3777 3778 # If we can save more than 30%, we go for the short table version. 3779 if iInstr + len(aoTableOrdered) - cInstructions >= len(aoTableOrdered) // 30: 3780 return (iInstr, cInstructions, True); 3781 _ = oMap; # Use this for overriding. 3782 3783 # Output the full table. 3784 return (0, len(aoTableOrdered), False); 3785 3402 3786 def generateDisassemblerTables(oDstFile = sys.stdout): 3403 3787 """ … … 3405 3789 """ 3406 3790 3791 # 3792 # The disassembler uses a slightly different table layout to save space, 3793 # since several of the prefix varia 3794 # 3795 aoDisasmMaps = []; 3407 3796 for sName, oMap in sorted(iter(g_dInstructionMaps.items()), 3408 3797 key = lambda aKV: aKV[1].sEncoding + ''.join(aKV[1].asLeadOpcodes)): 3409 assert oMap.sName == sName; 3798 if oMap.sSelector != 'byte+pfx': 3799 aoDisasmMaps.append(oMap); 3800 else: 3801 # Split the map by prefix. 3802 aoDisasmMaps.append(oMap.copy(oMap.sName, 'none')); 3803 aoDisasmMaps.append(oMap.copy(oMap.sName + '_66', '0x66')); 3804 aoDisasmMaps.append(oMap.copy(oMap.sName + '_F3', '0xf3')); 3805 aoDisasmMaps.append(oMap.copy(oMap.sName + '_F2', '0xf2')); 3806 3807 # 3808 # Dump each map. 3809 # 3810 asHeaderLines = []; 3811 print("debug: maps=%s\n" % (', '.join([oMap.sName for oMap in aoDisasmMaps]),)); 3812 for oMap in aoDisasmMaps: 3813 sName = oMap.sName; 3814 3815 if not sName.startswith("vex"): continue; # only looking at the vex maps at the moment. 3816 3817 # 3818 # Get the instructions for the map and see if we can do a short version or not. 3819 # 3820 aoTableOrder = oMap.getInstructionsInTableOrder(); 3821 cEntriesPerByte = oMap.getEntriesPerByte(); 3822 (iInstrStart, iInstrEnd, fShortTable) = __checkIfShortTable(aoTableOrder, oMap); 3823 3824 # 3825 # Output the table start. 3826 # Note! Short tables are static and only accessible via the map range record. 3827 # 3410 3828 asLines = []; 3411 3412 3829 asLines.append('/* Generated from: %-11s Selector: %-7s Encoding: %-7s Lead bytes opcodes: %s */' 3413 3830 % ( oMap.sName, oMap.sSelector, oMap.sEncoding, ' '.join(oMap.asLeadOpcodes), )); 3414 asLines.append('const DISOPCODE %s[] =' % (oMap.getDisasTableName(),)); 3831 if fShortTable: 3832 asLines.append('%sconst DISOPCODE %s[] =' % ('static ' if fShortTable else '', oMap.getDisasTableName(),)); 3833 else: 3834 asHeaderLines.append('extern const DISOPCODE %s[%d];' % (oMap.getDisasTableName(), iInstrEnd - iInstrStart,)); 3835 asLines.append( 'const DISOPCODE %s[%d] =' % (oMap.getDisasTableName(), iInstrEnd - iInstrStart,)); 3415 3836 asLines.append('{'); 3416 3837 3417 aoffColumns = [4, 29, 49, 65, 77, 89, 109, 125, 141, 157, 183, 199]; 3418 3419 aoTableOrder = oMap.getInstructionsInTableOrder(); 3420 for iInstr, oInstr in enumerate(aoTableOrder): 3421 3422 if (iInstr & 0xf) == 0: 3423 if iInstr != 0: 3838 if fShortTable and (iInstrStart & ((0x10 * cEntriesPerByte) - 1)) != 0: 3839 asLines.append(' /* %#04x: */' % (iInstrStart,)); 3840 3841 # 3842 # Output the instructions. 3843 # 3844 iInstr = iInstrStart; 3845 while iInstr < iInstrEnd: 3846 oInstr = aoTableOrder[iInstr]; 3847 if (iInstr & ((0x10 * cEntriesPerByte) - 1)) == 0: 3848 if iInstr != iInstrStart: 3424 3849 asLines.append(''); 3425 asLines.append(' /* %x */' % ( iInstr>> 4,));3850 asLines.append(' /* %x */' % ((iInstr // cEntriesPerByte) >> 4,)); 3426 3851 3427 3852 if oInstr is None: 3428 pass;#asLines.append(' /* %#04x */ None,' % (iInstr)); 3853 # Invalid. Optimize blocks of invalid instructions. 3854 cInvalidInstrs = 1; 3855 while iInstr + cInvalidInstrs < len(aoTableOrder) and aoTableOrder[iInstr + cInvalidInstrs] is None: 3856 cInvalidInstrs += 1; 3857 if (iInstr & (0x10 * cEntriesPerByte - 1)) == 0 and cInvalidInstrs >= 0x10 * cEntriesPerByte: 3858 asLines.append(' INVALID_OPCODE_BLOCK_%u,' % (0x10 * cEntriesPerByte,)); 3859 iInstr += 0x10 * cEntriesPerByte - 1; 3860 elif cEntriesPerByte > 1: 3861 if (iInstr & (cEntriesPerByte - 1)) == 0 and cInvalidInstrs >= cEntriesPerByte: 3862 asLines.append(' INVALID_OPCODE_BLOCK_%u,' % (cEntriesPerByte,)); 3863 iInstr += 3; 3864 else: 3865 asLines.append(' /* %#04x/%d */ INVALID_OPCODE,' 3866 % (iInstr // cEntriesPerByte, iInstr % cEntriesPerByte)); 3867 else: 3868 asLines.append(' /* %#04x */ INVALID_OPCODE,' % (iInstr)); 3429 3869 elif isinstance(oInstr, list): 3430 asLines.append(' /* %#04x */ ComplicatedListStuffNeedingWrapper,' % (iInstr)); 3870 if len(oInstr) != 0: 3871 asLines.append(' /* %#04x */ ComplicatedListStuffNeedingWrapper, /* \n -- %s */' 3872 % (iInstr, '\n -- '.join([str(oItem) for oItem in oInstr]),)); 3873 else: 3874 asLines.append(__formatDisassemblerTableEntry(oInstr)); 3431 3875 else: 3432 sMacro = 'OP'; 3433 cMaxOperands = 3; 3434 if len(oInstr.aoOperands) > 3: 3435 sMacro = 'OPVEX' 3436 cMaxOperands = 4; 3437 assert len(oInstr.aoOperands) <= cMaxOperands; 3438 3439 # 3440 # Format string. 3441 # 3442 sTmp = '%s("%s' % (sMacro, oInstr.sMnemonic,); 3443 for iOperand, oOperand in enumerate(oInstr.aoOperands): 3444 sTmp += ' ' if iOperand == 0 else ','; 3445 if g_kdOpTypes[oOperand.sType][2][0] != '%': ## @todo remove upper() later. 3446 sTmp += g_kdOpTypes[oOperand.sType][2].upper(); ## @todo remove upper() later. 3447 else: 3448 sTmp += g_kdOpTypes[oOperand.sType][2]; 3449 sTmp += '",'; 3450 asColumns = [ sTmp, ]; 3451 3452 # 3453 # Decoders. 3454 # 3455 iStart = len(asColumns); 3456 if oInstr.sEncoding is None: 3457 pass; 3458 elif oInstr.sEncoding == 'ModR/M': 3459 # ASSUME the first operand is using the ModR/M encoding 3460 assert len(oInstr.aoOperands) >= 1 and oInstr.aoOperands[0].usesModRM(); 3461 asColumns.append('IDX_ParseModRM,'); 3462 ## @todo IDX_ParseVexDest 3463 # Is second operand using ModR/M too? 3464 if len(oInstr.aoOperands) > 1 and oInstr.aoOperands[1].usesModRM(): 3465 asColumns.append('IDX_UseModRM,') 3466 elif oInstr.sEncoding in [ 'prefix', ]: 3467 for oOperand in oInstr.aoOperands: 3468 asColumns.append('0,'); 3469 elif oInstr.sEncoding in [ 'fixed' ]: 3470 pass; 3471 elif oInstr.sEncoding == 'vex2': 3472 asColumns.append('IDX_ParseVex2b,') 3473 elif oInstr.sEncoding == 'vex3': 3474 asColumns.append('IDX_ParseVex3b,') 3475 elif oInstr.sEncoding in g_dInstructionMaps: 3476 asColumns.append(g_dInstructionMaps[oInstr.sEncoding].sDisParse + ','); 3477 else: 3478 ## @todo 3479 #IDX_ParseTwoByteEsc, 3480 #IDX_ParseGrp1, 3481 #IDX_ParseShiftGrp2, 3482 #IDX_ParseGrp3, 3483 #IDX_ParseGrp4, 3484 #IDX_ParseGrp5, 3485 #IDX_Parse3DNow, 3486 #IDX_ParseGrp6, 3487 #IDX_ParseGrp7, 3488 #IDX_ParseGrp8, 3489 #IDX_ParseGrp9, 3490 #IDX_ParseGrp10, 3491 #IDX_ParseGrp12, 3492 #IDX_ParseGrp13, 3493 #IDX_ParseGrp14, 3494 #IDX_ParseGrp15, 3495 #IDX_ParseGrp16, 3496 #IDX_ParseThreeByteEsc4, 3497 #IDX_ParseThreeByteEsc5, 3498 #IDX_ParseModFence, 3499 #IDX_ParseEscFP, 3500 #IDX_ParseNopPause, 3501 #IDX_ParseInvOpModRM, 3502 assert False, str(oInstr); 3503 3504 # Check for immediates and stuff in the remaining operands. 3505 for oOperand in oInstr.aoOperands[len(asColumns) - iStart:]: 3506 sIdx = g_kdOpTypes[oOperand.sType][0]; 3507 if sIdx != 'IDX_UseModRM': 3508 asColumns.append(sIdx + ','); 3509 asColumns.extend(['0,'] * (cMaxOperands - (len(asColumns) - iStart))); 3510 3511 # 3512 # Opcode and operands. 3513 # 3514 assert oInstr.sDisEnum, str(oInstr); 3515 asColumns.append(oInstr.sDisEnum + ','); 3516 iStart = len(asColumns) 3517 for oOperand in oInstr.aoOperands: 3518 asColumns.append('OP_PARM_' + g_kdOpTypes[oOperand.sType][3] + ','); 3519 asColumns.extend(['OP_PARM_NONE,'] * (cMaxOperands - (len(asColumns) - iStart))); 3520 3521 # 3522 # Flags. 3523 # 3524 sTmp = ''; 3525 for sHint in sorted(oInstr.dHints.keys()): 3526 sDefine = g_kdHints[sHint]; 3527 if sDefine.startswith('DISOPTYPE_'): 3528 if sTmp: 3529 sTmp += ' | ' + sDefine; 3530 else: 3531 sTmp += sDefine; 3532 if sTmp: 3533 sTmp += '),'; 3534 else: 3535 sTmp += '0),'; 3536 asColumns.append(sTmp); 3537 3538 # 3539 # Format the columns into a line. 3540 # 3541 sLine = ''; 3542 for i, s in enumerate(asColumns): 3543 if len(sLine) < aoffColumns[i]: 3544 sLine += ' ' * (aoffColumns[i] - len(sLine)); 3545 else: 3546 sLine += ' '; 3547 sLine += s; 3548 3549 # OP("psrlw %Vdq,%Wdq", IDX_ParseModRM, IDX_UseModRM, 0, OP_PSRLW, OP_PARM_Vdq, OP_PARM_Wdq, OP_PARM_NONE, 3550 # DISOPTYPE_HARMLESS), 3551 # define OP(pszOpcode, idxParse1, idxParse2, idxParse3, opcode, param1, param2, param3, optype) \ 3552 # { pszOpcode, idxParse1, idxParse2, idxParse3, 0, opcode, param1, param2, param3, 0, 0, optype } 3553 3554 asLines.append(sLine); 3876 asLines.append(__formatDisassemblerTableEntry(oInstr)); 3877 3878 iInstr += 1; 3879 3880 if iInstrStart >= iInstrEnd: 3881 asLines.append(' /* dummy */ INVALID_OPCODE'); 3555 3882 3556 3883 asLines.append('};'); 3557 asLines.append('AssertCompile(RT_ELEMENTS(%s) == %s);' % (oMap.getDisasTableName(), oMap.getTableSize(),)); 3884 asLines.append('AssertCompile(RT_ELEMENTS(%s) == %s);' % (oMap.getDisasTableName(), iInstrEnd - iInstrStart,)); 3885 3886 # 3887 # We always emit a map range record, assuming the linker will eliminate the unnecessary ones. 3888 # 3889 asHeaderLines.append('extern const DISOPMAPDESC %sRange;' % (oMap.getDisasRangeName())); 3890 asLines.append('const DISOPMAPDESC %s = { &%s[0], %#04x, RT_ELEMENTS(%s) };' 3891 % (oMap.getDisasRangeName(), oMap.getDisasTableName(), iInstrStart, oMap.getDisasTableName(),)); 3558 3892 3559 3893 # … … 3562 3896 oDstFile.write('\n'.join(asLines)); 3563 3897 oDstFile.write('\n'); 3564 break; #for now 3898 oDstFile.write('\n'); 3899 #break; #for now 3565 3900 3566 3901 if __name__ == '__main__':
Note:
See TracChangeset
for help on using the changeset viewer.