diff --git a/src/code/amd64.c b/src/code/amd64.c index 63be28eb1c6114138c07f8ec9c51c7be33a0b037..aa25af94e40354ac899a6f5a7929f01c93d15f39 100644 --- a/src/code/amd64.c +++ b/src/code/amd64.c @@ -2757,42 +2757,8 @@ void ins_f_byte_with_arg(unsigned int a, INT32 b) amd64_push_svaluep(P_REG_RCX); return; - case F_CLEAR_4_LOCAL: - { - LABELS(); - ins_debug_instr_prologue(a-F_OFFSET, b, 0); - amd64_load_fp_reg(); - mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), P_REG_RBX); - add_reg_imm(P_REG_RBX, b*sizeof(struct svalue)); - mov_imm_reg(3, P_REG_R8 ); - /* need to use a saving register for the counter. */ - - LABEL_A; - amd64_free_svalue(P_REG_RBX, 0); - mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type)); - mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer)); - add_reg_imm(P_REG_RBX, sizeof(struct svalue ) ); - add_reg_imm(P_REG_R8,-1); - jnz(&label_A); - } - return; - - case F_CLEAR_2_LOCAL: case F_CLEAR_LOCAL: - ins_debug_instr_prologue(a-F_OFFSET, b, 0); - amd64_load_fp_reg(); - mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), P_REG_RBX); - add_reg_imm(P_REG_RBX, b*sizeof(struct svalue)); - amd64_free_svalue(P_REG_RBX, 0); - mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type)); - mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer)); - if( a == F_CLEAR_2_LOCAL ) - { - add_reg_imm( P_REG_RBX, sizeof(struct svalue ) ); - amd64_free_svalue(P_REG_RBX, 0); - mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type)); - mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer)); - } + ins_f_byte_with_2_args( F_CLEAR_N_LOCAL, b, 1 ); return; case F_INC_LOCAL_AND_POP: @@ -3097,6 +3063,30 @@ void ins_f_byte_with_2_args(unsigned int a, INT32 b, INT32 c) ins_f_byte(F_MARK); ins_f_byte_with_2_args(F_EXTERNAL, b, c); return; + + case F_CLEAR_N_LOCAL: + { + LABELS(); + ins_debug_instr_prologue(a-F_OFFSET, b, 0); + amd64_load_fp_reg(); + mov_mem_reg(fp_reg, OFFSETOF(pike_frame, locals), P_REG_RBX); + add_reg_imm(P_REG_RBX, b*sizeof(struct svalue)); + if( c > 1 ) + add_reg_imm_reg(P_REG_RBX, c*sizeof(struct svalue), P_REG_RBP ); + + LABEL_A; + amd64_free_svalue(P_REG_RBX, 0); + mov_imm_mem(PIKE_T_INT, P_REG_RBX, OFFSETOF(svalue, tu.t.type)); + mov_imm_mem(0, P_REG_RBX, OFFSETOF(svalue, u.integer)); + if( c > 1 ) + { + add_reg_imm(P_REG_RBX, sizeof(struct svalue ) ); + cmp_reg_reg( P_REG_RBX, P_REG_RBP ); + jne(&label_A); + } + } + return; + case F_LOCAL_LOCAL_INDEX: { LABELS(); diff --git a/src/interpret_functions.h b/src/interpret_functions.h index 6d9630e9e035099e8b8b10bacf3665f5a56024ad..3540740c7c9a2a3904be1e69d8f816b5ba23b114 100644 --- a/src/interpret_functions.h +++ b/src/interpret_functions.h @@ -549,17 +549,11 @@ OPCODE1(F_ARRAY_LVALUE, "[ lvalues ]", I_UPDATE_SP, { Pike_sp++; }); -OPCODE1(F_CLEAR_2_LOCAL, "clear 2 local", 0, { - free_mixed_svalues(Pike_fp->locals + arg1, 2); - SET_SVAL(Pike_fp->locals[arg1], PIKE_T_INT, NUMBER_NUMBER, integer, 0); - SET_SVAL(Pike_fp->locals[arg1+1], PIKE_T_INT, NUMBER_NUMBER, integer, 0); -}); - -OPCODE1(F_CLEAR_4_LOCAL, "clear 4 local", 0, { +OPCODE2(F_CLEAR_N_LOCAL, "clear n local", 0, { struct svalue *locals = Pike_fp->locals; int e; - free_mixed_svalues(locals + arg1, 4); - for(e = 0; e < 4; e++) + free_mixed_svalues(locals + arg1, arg2); + for(e = 0; e < arg2; e++) { SET_SVAL(locals[arg1+e], PIKE_T_INT, NUMBER_NUMBER, integer, 0); } diff --git a/src/peep.in b/src/peep.in index b306aca1f61b8dc8a7c5f73c12f40a44467bac5b..640719b2659925b346efd494d4edabdf762b3096 100644 --- a/src/peep.in +++ b/src/peep.in @@ -95,21 +95,16 @@ CONST_1 ASSIGN_GLOBAL_AND_POP : ASSIGN_GLOBAL_NUMBER_AND_POP($2a,-1) // Remove clearing of locals from the beginning of functions // But don't remove clearing of arguments! BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) -BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_2_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) -BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_4_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) +BYTE ENTRY START_FUNCTION LABEL(0) CLEAR_N_LOCAL [$1a <= $5a] : BYTE($1a) ENTRY START_FUNCTION LABEL(0) BYTE ENTRY START_FUNCTION CLEAR_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION -BYTE ENTRY START_FUNCTION CLEAR_2_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION -BYTE ENTRY START_FUNCTION CLEAR_4_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION +BYTE ENTRY START_FUNCTION CLEAR_N_LOCAL [$1a <= $4a] : BYTE($1a) ENTRY START_FUNCTION CLEAR_LOCAL CLEAR_LOCAL($1a) : CLEAR_LOCAL($1a) -CLEAR_LOCAL CLEAR_LOCAL($1a+1) : CLEAR_2_LOCAL($1a) -CLEAR_2_LOCAL CLEAR_2_LOCAL($1a+2) : CLEAR_4_LOCAL($1a) +CLEAR_LOCAL CLEAR_LOCAL($1a+1) : CLEAR_N_LOCAL($1a,2) -// Attempt to make the above trigger more often. -CLEAR_LOCAL CLEAR_2_LOCAL($1a+1) : CLEAR_2_LOCAL($1a) CLEAR_LOCAL($2a+1) -CLEAR_LOCAL CLEAR_4_LOCAL($1a+1) : CLEAR_4_LOCAL($1a) CLEAR_LOCAL($2a+3) -CLEAR_2_LOCAL CLEAR_4_LOCAL($1a+2) : CLEAR_4_LOCAL($1a) CLEAR_2_LOCAL($2a+2) +CLEAR_LOCAL CLEAR_N_LOCAL($1a+1) : CLEAR_N_LOCAL($1a,$2b+1) +CLEAR_N_LOCAL CLEAR_LOCAL($1a+$1b) : CLEAR_N_LOCAL($1a,$1b+1) // Attempt to de-interleave clearing of locals. CONST0 CLEAR_LOCAL : CLEAR_LOCAL($2a) CONST0