diff options
| author | Damien George <damien.p.george@gmail.com> | 2018-08-04 22:03:49 +1000 |
|---|---|---|
| committer | Damien George <damien.p.george@gmail.com> | 2018-08-04 22:03:49 +1000 |
| commit | 10830059c5d3651abdb2d3532b28a9bb0a9425ee (patch) | |
| tree | db4c54f5f9d54d5833546e345c23f08f1adc1df0 /py/asmx64.h | |
| parent | 4b1e8bdebdf5feb48a51dbf1e584735395069384 (diff) | |
py/emitnative: Fix x86 native zero checks by comparing full word.
On x86 archs (both 32 and 64 bit) a bool return value only sets the 8-bit
al register, and the higher bits of the ax register have an undefined
value. When testing the return value of such cases it is required to just
test al for zero/non-zero. On the other hand, checking for truth or
zero/non-zero on an integer return value requires checking all bits of the
register. These two cases must be distinguished and handled correctly in
generated native code. This patch makes sure of this.
For other supported native archs (ARM, Thumb2, Xtensa) there is no such
distinction and this patch does not change anything for them.
Diffstat (limited to 'py/asmx64.h')
| -rw-r--r-- | py/asmx64.h | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/py/asmx64.h b/py/asmx64.h index 2fbbfa9ff..4d7281d18 100644 --- a/py/asmx64.h +++ b/py/asmx64.h @@ -104,6 +104,7 @@ void asm_x64_sub_r64_r64(asm_x64_t* as, int dest_r64, int src_r64); void asm_x64_mul_r64_r64(asm_x64_t* as, int dest_r64, int src_r64); void asm_x64_cmp_r64_with_r64(asm_x64_t* as, int src_r64_a, int src_r64_b); void asm_x64_test_r8_with_r8(asm_x64_t* as, int src_r64_a, int src_r64_b); +void asm_x64_test_r64_with_r64(asm_x64_t *as, int src_r64_a, int src_r64_b); void asm_x64_setcc_r8(asm_x64_t* as, int jcc_type, int dest_r8); void asm_x64_jmp_label(asm_x64_t* as, mp_uint_t label); void asm_x64_jcc_label(asm_x64_t* as, int jcc_type, mp_uint_t label); @@ -145,14 +146,22 @@ void asm_x64_call_ind(asm_x64_t* as, void* ptr, int temp_r32); #define ASM_EXIT asm_x64_exit #define ASM_JUMP asm_x64_jmp_label -#define ASM_JUMP_IF_REG_ZERO(as, reg, label) \ +#define ASM_JUMP_IF_REG_ZERO(as, reg, label, bool_test) \ do { \ - asm_x64_test_r8_with_r8(as, reg, reg); \ + if (bool_test) { \ + asm_x64_test_r8_with_r8((as), (reg), (reg)); \ + } else { \ + asm_x64_test_r64_with_r64((as), (reg), (reg)); \ + } \ asm_x64_jcc_label(as, ASM_X64_CC_JZ, label); \ } while (0) -#define ASM_JUMP_IF_REG_NONZERO(as, reg, label) \ +#define ASM_JUMP_IF_REG_NONZERO(as, reg, label, bool_test) \ do { \ - asm_x64_test_r8_with_r8(as, reg, reg); \ + if (bool_test) { \ + asm_x64_test_r8_with_r8((as), (reg), (reg)); \ + } else { \ + asm_x64_test_r64_with_r64((as), (reg), (reg)); \ + } \ asm_x64_jcc_label(as, ASM_X64_CC_JNZ, label); \ } while (0) #define ASM_JUMP_IF_REG_EQ(as, reg1, reg2, label) \ |
