From: Dmitry Stogov Date: Mon, 21 Mar 2016 10:03:30 +0000 (+0300) Subject: Avoid data bypass delays between integer and floating point execution units on x86... X-Git-Tag: php-7.1.0alpha1~439 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=60b72e434b294ae0c2585734b8d99dd077826900;p=php Avoid data bypass delays between integer and floating point execution units on x86 CPUs. --- diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 22f1a6a3a1..af9daa89b1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8632,6 +8632,17 @@ ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (op1_info == MAY_BE_DOUBLE), ZEND_QM_ASSIGN_DOUBLE, CONST|TMPVARCV, ANY) +{ + USE_OPLINE + zend_free_op free_op1; + zval *value; + + value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); + ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)))), ZEND_QM_ASSIGN_NOREF, CONST|TMPVARCV, ANY) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index b0b8035ba2..a4edfd0f98 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4698,6 +4698,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DEFINED_SPEC_CONST_HANDLER(ZEN ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value; + + value = EX_CONSTANT(opline->op1); + ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -55128,6 +55139,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_T ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value; + + value = EX_VAR(opline->op1.var); + ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -59636,6 +59658,11 @@ void zend_init_opcodes_handlers(void) ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, ZEND_POST_DEC_LONG_OR_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_HANDLER, + ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_HANDLER, ZEND_QM_ASSIGN_NOREF_SPEC_CONST_HANDLER, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER, @@ -59685,7 +59712,7 @@ void zend_init_opcodes_handlers(void) 776 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_RETVAL, 826 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 851 | SPEC_RULE_OP1, - 3840, + 3845, 856, 857 | SPEC_RULE_OP1, 862 | SPEC_RULE_OP1, @@ -59693,9 +59720,9 @@ void zend_init_opcodes_handlers(void) 872 | SPEC_RULE_OP1, 877 | SPEC_RULE_OP1, 882 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 3840, - 3840, - 3840, + 3845, + 3845, + 3845, 907 | SPEC_RULE_OP1, 912 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 937 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -59744,7 +59771,7 @@ void zend_init_opcodes_handlers(void) 1646 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1671 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1696 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 3840, + 3845, 1721, 1722, 1723, @@ -59828,7 +59855,7 @@ void zend_init_opcodes_handlers(void) 2845 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2870 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2895 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 3840 + 3845 }; zend_opcode_handlers = labels; zend_handlers_count = sizeof(labels) / sizeof(void*); @@ -60059,8 +60086,10 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint } break; case ZEND_QM_ASSIGN: - if ((!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { + if ((op1_info == MAY_BE_DOUBLE)) { spec = 3835 | SPEC_RULE_OP1; + } else if ((!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { + spec = 3840 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: