===================================================================
@@ -15091,130 +15091,6 @@
DONE;
})
-;; For -fsplit-stack, check whether we have enough stack space at the
-;; start of a function which allocates 256 bytes or less on the stack.
-;; Branch to the label if we have enough space.
-
-(define_expand "split_stack_check_small"
- [(set (pc)
- (if_then_else
- (ltu (reg SP_REG) (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
- (label_ref
- (match_operand 0 "" ""))
- (pc)))]
- ""
-{
- rtx ssp_offset;
-
-#ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
- ssp_offset = GEN_INT (TARGET_THREAD_SPLIT_STACK_OFFSET);
-#else
- gcc_unreachable ();
-#endif
-
- if (TARGET_64BIT)
- emit_insn (gen_split_stack_compare_small_64 (ssp_offset));
- else
- emit_insn (gen_split_stack_compare_small_32 (ssp_offset));
- ix86_compare_op0 = gen_rtx_REG (CCmode, FLAGS_REG);
- ix86_compare_op1 = GEN_INT (0);
- ix86_expand_branch (GEU, operands[0]);
- JUMP_LABEL (get_last_insn ()) = operands[0];
- DONE;
-})
-
-;; Compare the stack pointer with the -fsplit-stack limit.
-
-(define_insn "split_stack_compare_small_32"
- [(set (reg:CC FLAGS_REG)
- (compare (reg:SI SP_REG)
- (unspec:SI [(match_operand 0 "const_int_operand" "i")]
- UNSPEC_STACK_CHECK)))]
- "!TARGET_64BIT"
- "cmp{l}\t{%%gs:%P0, %%esp|%%esp, %%gs:%P0}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "SI")
- (set_attr "length_immediate" "4")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")])
-
-;; 64-bit version of split_stack_compare_small_32.
-
-(define_insn "split_stack_compare_small_64"
- [(set (reg:CC FLAGS_REG)
- (compare (reg:DI SP_REG)
- (unspec:DI [(match_operand 0 "const_int_operand" "i")]
- UNSPEC_STACK_CHECK)))]
- "TARGET_64BIT"
- "cmp{q}\t{%%fs:%P0, %%rsp|%%rsp, %%fs:%P0}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "DI")
- (set_attr "length_immediate" "4")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")])
-
-;; For -fsplit-stack, check whether we have enough stack space at the
-;; start of a function which allocates more than 256 bytes on the
-;; stack. Branch to the label if we have enough space.
-
-(define_expand "split_stack_check_large"
- [(set (pc)
- (if_then_else
- (ltu (match_operand 0 "" "")
- (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
- (label_ref (match_operand 1 "" ""))
- (pc)))]
- ""
-{
- rtx ssp_offset;
-
-#ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
- ssp_offset = GEN_INT (TARGET_THREAD_SPLIT_STACK_OFFSET);
-#else
- gcc_unreachable ();
-#endif
-
- if (TARGET_64BIT)
- emit_insn (gen_split_stack_compare_large_64 (operands[0], ssp_offset));
- else
- emit_insn (gen_split_stack_compare_large_32 (operands[0], ssp_offset));
- ix86_compare_op0 = gen_rtx_REG (CCmode, FLAGS_REG);
- ix86_compare_op1 = GEN_INT (0);
- ix86_expand_branch (GEU, operands[1]);
- JUMP_LABEL (get_last_insn ()) = operands[1];
- DONE;
-})
-
-;; Compare operand 0 with the -fsplit-stack limit.
-
-(define_insn "split_stack_compare_large_32"
- [(set (reg:CC FLAGS_REG)
- (compare (match_operand:SI 0 "register_operand" "r")
- (unspec:SI [(match_operand 1 "const_int_operand" "i")]
- UNSPEC_STACK_CHECK)))]
- "!TARGET_64BIT"
- "cmp{l}\t{%%gs:%P1, %0|%0, %%gs:%P1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "SI")
- (set_attr "length_immediate" "4")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")])
-
-;; 64-bit version of split_stack_compare_large_32.
-
-(define_insn "split_stack_compare_large_64"
- [(set (reg:CC FLAGS_REG)
- (compare (match_operand:DI 0 "register_operand" "r")
- (unspec:DI [(match_operand 1 "const_int_operand" "i")]
- UNSPEC_STACK_CHECK)))]
- "TARGET_64BIT"
- "cmp{q}\t{%%fs:%P1, %0|%0, %%fs:%P1}"
- [(set_attr "type" "icmp")
- (set_attr "mode" "DI")
- (set_attr "length_immediate" "4")
- (set_attr "memory" "none")
- (set_attr "imm_disp" "false")])
-
;; In order to support the call/return predictor, we use a return
;; instruction which the middle-end doesn't see.
(define_insn "split_stack_return"
===================================================================
@@ -9299,7 +9299,7 @@ ix86_expand_split_stack_prologue (void)
tree decl;
bool is_fastcall;
int regparm, args_size;
- rtx label, jump_insn, allocate_rtx, call_insn, call_fusage;
+ rtx label, limit, current, jump_insn, allocate_rtx, call_insn, call_fusage;
gcc_assert (flag_split_stack && reload_completed);
@@ -9324,8 +9324,13 @@ ix86_expand_split_stack_prologue (void)
the stack boundary in the TCB. The stack boundary always gives
us SPLIT_STACK_AVAILABLE bytes, so if we need less than that we
can compare directly. Otherwise we need to do an addition. */
+
+ limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+ UNSPEC_STACK_CHECK);
+ limit = gen_rtx_CONST (Pmode, limit);
+ limit = gen_rtx_MEM (Pmode, limit);
if (allocate < SPLIT_STACK_AVAILABLE)
- emit_jump_insn (gen_split_stack_check_small (label));
+ current = stack_pointer_rtx;
else
{
rtx offset, scratch_reg;
@@ -9382,9 +9387,14 @@ ix86_expand_split_stack_prologue (void)
emit_insn (gen_addsi3 (scratch_reg, stack_pointer_rtx, offset));
}
- emit_jump_insn (gen_split_stack_check_large (scratch_reg, label));
+ current = scratch_reg;
}
+ ix86_compare_op0 = current;
+ ix86_compare_op1 = limit;
+ ix86_expand_branch (GEU, label);
+ JUMP_LABEL (get_last_insn ()) = label;
+
/* Mark the jump as very likely to be taken. */
jump_insn = get_last_insn ();
gcc_assert (JUMP_P (jump_insn));
@@ -10103,6 +10113,10 @@ ix86_legitimate_address_p (enum machine_
case UNSPEC_DTPOFF:
break;
+ case UNSPEC_STACK_CHECK:
+ gcc_assert (flag_split_stack);
+ break;
+
default:
/* Invalid address unspec. */
return false;
@@ -10994,6 +11008,13 @@ output_pic_addr_const (FILE *file, rtx x
break;
case UNSPEC:
+ if (XINT (x, 1) == UNSPEC_STACK_CHECK)
+ {
+ bool f = output_addr_const_extra (file, x);
+ gcc_assert (f);
+ break;
+ }
+
gcc_assert (XVECLEN (x, 0) == 1);
output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
switch (XINT (x, 1))
@@ -12357,6 +12378,22 @@ output_addr_const_extra (FILE *file, rtx
break;
#endif
+ case UNSPEC_STACK_CHECK:
+ {
+ int offset;
+
+ gcc_assert (flag_split_stack);
+
+#ifdef TARGET_THREAD_SPLIT_STACK_OFFSET
+ offset = TARGET_THREAD_SPLIT_STACK_OFFSET;
+#else
+ gcc_unreachable ();
+#endif
+
+ fprintf (file, "%s:%d", TARGET_64BIT ? "%fs" : "%gs", offset);
+ }
+ break;
+
default:
return false;
}