diff options
author | Mike Pall <mike> | 2016-04-18 11:17:15 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2016-04-18 11:17:15 +0200 |
commit | d13d4209808a050e4fbe7dcb43739983075789d5 (patch) | |
tree | ee971aa2799d26b42b0051cb4290442465f5af5f | |
parent | 0c6fdc1039a3a4450d366fba7af4b29de73f0dc6 (diff) | |
parent | 73680a5fc760cb39760e4bbfce1166ce75de237f (diff) | |
download | luajit-d13d4209808a050e4fbe7dcb43739983075789d5.tar.gz luajit-d13d4209808a050e4fbe7dcb43739983075789d5.tar.bz2 luajit-d13d4209808a050e4fbe7dcb43739983075789d5.zip |
Merge branch 'master' into v2.1
-rw-r--r-- | src/lj_asm_x86.h | 113 |
1 files changed, 104 insertions, 9 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 718cb12e..f515d821 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
@@ -2620,6 +2620,106 @@ static void asm_setup_target(ASMState *as) | |||
2620 | 2620 | ||
2621 | /* -- Trace patching ------------------------------------------------------ */ | 2621 | /* -- Trace patching ------------------------------------------------------ */ |
2622 | 2622 | ||
2623 | static const uint8_t map_op1[256] = { | ||
2624 | 0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x20, | ||
2625 | 0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x51,0x51, | ||
2626 | 0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51, | ||
2627 | 0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51,0x92,0x92,0x92,0x92,0x52,0x45,0x10,0x51, | ||
2628 | #if LJ_64 | ||
2629 | 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, | ||
2630 | #else | ||
2631 | 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51, | ||
2632 | #endif | ||
2633 | 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51, | ||
2634 | 0x51,0x51,0x92,0x92,0x10,0x10,0x12,0x11,0x45,0x86,0x52,0x93,0x51,0x51,0x51,0x51, | ||
2635 | 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, | ||
2636 | 0x93,0x86,0x93,0x93,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92, | ||
2637 | 0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x51,0x47,0x51,0x51,0x51,0x51,0x51, | ||
2638 | #if LJ_64 | ||
2639 | 0x59,0x59,0x59,0x59,0x51,0x51,0x51,0x51,0x52,0x45,0x51,0x51,0x51,0x51,0x51,0x51, | ||
2640 | #else | ||
2641 | 0x55,0x55,0x55,0x55,0x51,0x51,0x51,0x51,0x52,0x45,0x51,0x51,0x51,0x51,0x51,0x51, | ||
2642 | #endif | ||
2643 | 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05, | ||
2644 | 0x93,0x93,0x53,0x51,0x70,0x71,0x93,0x86,0x54,0x51,0x53,0x51,0x51,0x52,0x51,0x51, | ||
2645 | 0x92,0x92,0x92,0x92,0x52,0x52,0x51,0x51,0x92,0x92,0x92,0x92,0x92,0x92,0x92,0x92, | ||
2646 | 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x45,0x45,0x47,0x52,0x51,0x51,0x51,0x51, | ||
2647 | 0x10,0x51,0x10,0x10,0x51,0x51,0x63,0x66,0x51,0x51,0x51,0x51,0x51,0x51,0x92,0x92 | ||
2648 | }; | ||
2649 | |||
2650 | static const uint8_t map_op2[256] = { | ||
2651 | 0x93,0x93,0x93,0x93,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x93,0x52,0x94, | ||
2652 | 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2653 | 0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x53,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2654 | 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x34,0x51,0x35,0x51,0x51,0x51,0x51,0x51, | ||
2655 | 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2656 | 0x53,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2657 | 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2658 | 0x94,0x54,0x54,0x54,0x93,0x93,0x93,0x52,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2659 | 0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46,0x46, | ||
2660 | 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2661 | 0x52,0x52,0x52,0x93,0x94,0x93,0x51,0x51,0x52,0x52,0x52,0x93,0x94,0x93,0x93,0x93, | ||
2662 | 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x94,0x93,0x93,0x93,0x93,0x93, | ||
2663 | 0x93,0x93,0x94,0x93,0x94,0x94,0x94,0x93,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, | ||
2664 | 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2665 | 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93, | ||
2666 | 0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x93,0x52 | ||
2667 | }; | ||
2668 | |||
2669 | static uint32_t asm_x86_inslen(const uint8_t* p) | ||
2670 | { | ||
2671 | uint32_t result = 0; | ||
2672 | uint32_t prefixes = 0; | ||
2673 | uint32_t x = map_op1[*p]; | ||
2674 | for (;;) { | ||
2675 | switch (x >> 4) { | ||
2676 | case 0: return result + x + (prefixes & 4); | ||
2677 | case 1: prefixes |= x; x = map_op1[*++p]; result++; break; | ||
2678 | case 2: x = map_op2[*++p]; break; | ||
2679 | case 3: p++; goto mrm; | ||
2680 | case 4: result -= (prefixes & 2); /* fallthrough */ | ||
2681 | case 5: return result + (x & 15); | ||
2682 | case 6: /* Group 3. */ | ||
2683 | if (p[1] & 0x38) return result + 2; | ||
2684 | if ((prefixes & 2) && (x == 0x66)) return result + 4; | ||
2685 | return result + (x & 15); | ||
2686 | case 7: /* VEX c4/c5. */ | ||
2687 | if (LJ_32 && p[1] < 0xc0) { | ||
2688 | x = 2; | ||
2689 | goto mrm; | ||
2690 | } | ||
2691 | if (x == 0x70) { | ||
2692 | x = *++p & 0x1f; | ||
2693 | result++; | ||
2694 | if (x >= 2) { | ||
2695 | p += 2; | ||
2696 | result += 2; | ||
2697 | goto mrm; | ||
2698 | } | ||
2699 | } | ||
2700 | p++; | ||
2701 | result++; | ||
2702 | x = map_op2[*++p]; | ||
2703 | break; | ||
2704 | case 8: result -= (prefixes & 2); /* fallthrough */ | ||
2705 | case 9: mrm: /* ModR/M and possibly SIB. */ | ||
2706 | result += (x & 15); | ||
2707 | x = *++p; | ||
2708 | switch (x >> 6) { | ||
2709 | case 0: if ((x & 7) == 5) return result + 4; break; | ||
2710 | case 1: result++; break; | ||
2711 | case 2: result += 4; break; | ||
2712 | case 3: return result; | ||
2713 | } | ||
2714 | if ((x & 7) == 4) { | ||
2715 | result++; | ||
2716 | if (x < 0x40 && (p[1] & 7) == 5) result += 4; | ||
2717 | } | ||
2718 | return result; | ||
2719 | } | ||
2720 | } | ||
2721 | } | ||
2722 | |||
2623 | /* Patch exit jumps of existing machine code to a new target. */ | 2723 | /* Patch exit jumps of existing machine code to a new target. */ |
2624 | void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | 2724 | void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) |
2625 | { | 2725 | { |
@@ -2632,18 +2732,13 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | |||
2632 | if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px) | 2732 | if (len > 5 && p[len-5] == XI_JMP && p+len-6 + *(int32_t *)(p+len-4) == px) |
2633 | *(int32_t *)(p+len-4) = jmprel(p+len, target); | 2733 | *(int32_t *)(p+len-4) = jmprel(p+len, target); |
2634 | /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */ | 2734 | /* Do not patch parent exit for a stack check. Skip beyond vmstate update. */ |
2635 | for (; p < pe; p++) | 2735 | for (; p < pe; p += asm_x86_inslen(p)) |
2636 | if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) { | 2736 | if (*(uint32_t *)(p+(LJ_64 ? 3 : 2)) == stateaddr && p[0] == XI_MOVmi) |
2637 | p += LJ_64 ? 11 : 10; | ||
2638 | break; | 2737 | break; |
2639 | } | ||
2640 | lua_assert(p < pe); | 2738 | lua_assert(p < pe); |
2641 | for (; p < pe; p++) { | 2739 | for (; p < pe; p += asm_x86_inslen(p)) |
2642 | if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) { | 2740 | if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) |
2643 | *(int32_t *)(p+2) = jmprel(p+6, target); | 2741 | *(int32_t *)(p+2) = jmprel(p+6, target); |
2644 | p += 5; | ||
2645 | } | ||
2646 | } | ||
2647 | lj_mcode_sync(T->mcode, T->mcode + T->szmcode); | 2742 | lj_mcode_sync(T->mcode, T->mcode + T->szmcode); |
2648 | lj_mcode_patch(J, mcarea, 1); | 2743 | lj_mcode_patch(J, mcarea, 1); |
2649 | } | 2744 | } |