From: Dmitry Stogov Date: Fri, 6 Dec 2019 11:04:58 +0000 (+0300) Subject: Use cheaper code for overflow +/-1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=990b55676147f451ae7a18afbb59099466a944f1;p=php Use cheaper code for overflow +/-1 --- diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index ba7075d261..ac64668e67 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3036,38 +3036,62 @@ static int zend_jit_math_long_long(dasm_State **Dst, } if (may_overflow) { | jo >1 - |.cold_code - |1: + } + + | SET_ZVAL_LVAL res_addr, Ra(result_reg) + if (Z_MODE(op1_addr) != IS_MEM_ZVAL || Z_REG(op1_addr) != Z_REG(res_addr) || Z_OFFSET(op1_addr) != Z_OFFSET(res_addr)) { + if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_LONG) { + | SET_ZVAL_TYPE_INFO res_addr, IS_LONG + } + } + + if (may_overflow) { zend_reg tmp_reg1 = ZREG_XMM0; zend_reg tmp_reg2 = ZREG_XMM1; - | SSE_GET_ZVAL_LVAL tmp_reg1, op1_addr - | SSE_GET_ZVAL_LVAL tmp_reg2, op2_addr - if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) { - | AVX_MATH_REG opcode, tmp_reg1, tmp_reg1, tmp_reg2 - } else { - | SSE_MATH_REG opcode, tmp_reg1, tmp_reg2 - } - | SSE_SET_ZVAL_DVAL res_addr, tmp_reg1 + |.cold_code + |1: + + do { + if ((Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op1_addr)) == 1) || + (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 1)) { + if (opcode == ZEND_ADD) { + |.if X64 + | mov64 rax, 0x43e0000000000000 + | SET_ZVAL_LVAL res_addr, rax + |.else + | SET_ZVAL_LVAL res_addr, 0 + | SET_ZVAL_W2 res_addr, 0x41e00000 + |.endif + break; + } else if (opcode == ZEND_SUB) { + |.if X64 + | mov64 rax, 0xc3e0000000000000 + | SET_ZVAL_LVAL res_addr, rax + |.else + | SET_ZVAL_LVAL res_addr, 0x00200000 + | SET_ZVAL_W2 res_addr, 0xc1e00000 + |.endif + break; + } + } + + | SSE_GET_ZVAL_LVAL tmp_reg1, op1_addr + | SSE_GET_ZVAL_LVAL tmp_reg2, op2_addr + if (zend_jit_x86_flags & ZEND_JIT_CPU_AVX) { + | AVX_MATH_REG opcode, tmp_reg1, tmp_reg1, tmp_reg2 + } else { + | SSE_MATH_REG opcode, tmp_reg1, tmp_reg2 + } + | SSE_SET_ZVAL_DVAL res_addr, tmp_reg1 + } while (0); + if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_DOUBLE) { | SET_ZVAL_TYPE_INFO res_addr, IS_DOUBLE } | jmp >2 |.code - | SET_ZVAL_LVAL res_addr, Ra(result_reg) - if (Z_MODE(op1_addr) != IS_MEM_ZVAL || Z_REG(op1_addr) != Z_REG(res_addr) || Z_OFFSET(op1_addr) != Z_OFFSET(res_addr)) { - if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_LONG) { - | SET_ZVAL_TYPE_INFO res_addr, IS_LONG - } - } |2: - } else if (Z_MODE(res_addr) == IS_MEM_ZVAL) { - | SET_ZVAL_LVAL res_addr, Ra(result_reg) - if (Z_MODE(op1_addr) != IS_MEM_ZVAL || Z_REG(op1_addr) != Z_REG(res_addr) || Z_OFFSET(op1_addr) != Z_OFFSET(res_addr)) { - if ((res_use_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) != MAY_BE_LONG) { - | SET_ZVAL_TYPE_INFO res_addr, IS_LONG - } - } } return 1;