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