return insn;
}
-/* Generate a create_flat_frame_1 insn. */
-
-static rtx
-gen_create_flat_frame_1 (rtx increment)
-{
- if (TARGET_ARCH64)
- return gen_create_flat_frame_1di (increment);
- else
- return gen_create_flat_frame_1si (increment);
-}
-
-/* Generate a create_flat_frame_2 insn. */
-
-static rtx
-gen_create_flat_frame_2 (rtx increment)
-{
- if (TARGET_ARCH64)
- return gen_create_flat_frame_2di (increment);
- else
- return gen_create_flat_frame_2si (increment);
-}
-
-/* Generate a create_flat_frame_3 insn. */
-
-static rtx
-gen_create_flat_frame_3 (rtx increment)
-{
- if (TARGET_ARCH64)
- return gen_create_flat_frame_3di (increment);
- else
- return gen_create_flat_frame_3si (increment);
-}
-
/* Generate an increment for the stack pointer. */
static rtx
{
HOST_WIDE_INT size;
rtx insn;
- int i;
sparc_leaf_function_p = optimize > 0 && current_function_is_leaf;
if (size == 0)
; /* do nothing. */
- else if (frame_pointer_needed)
+ else
{
- if (size <= 4096)
- {
- if (return_addr_reg_needed_p (sparc_leaf_function_p))
- insn = emit_insn (gen_create_flat_frame_1 (GEN_INT (-size)));
- else
- insn = emit_insn (gen_create_flat_frame_2 (GEN_INT (-size)));
- RTX_FRAME_RELATED_P (insn) = 1;
- for (i=0; i < XVECLEN (PATTERN (insn), 0); i++)
- RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, i)) = 1;
- }
- else
- {
- rtx reg = gen_rtx_REG (Pmode, 1), note;
- emit_move_insn (reg, GEN_INT (-size));
- if (return_addr_reg_needed_p (sparc_leaf_function_p))
- {
- insn = emit_insn (gen_create_flat_frame_1 (reg));
- note
- = gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec
- (3, copy_rtx
- (XVECEXP (PATTERN (insn), 0, 0)),
- gen_stack_pointer_inc
- (GEN_INT (-size)),
- copy_rtx
- (XVECEXP (PATTERN (insn), 0, 2))));
- }
- else
- {
- insn = emit_insn (gen_create_flat_frame_2 (reg));
- note
- = gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec
- (2, copy_rtx
- (XVECEXP (PATTERN (insn), 0, 0)),
- gen_stack_pointer_inc
- (GEN_INT (-size))));
- }
+ rtx size_int_rtx, size_rtx;
+
+ size_rtx = size_int_rtx = GEN_INT (-size);
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
- for (i=0; i < XVECLEN (note, 0); i++)
- RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
- }
- }
- else if (return_addr_reg_needed_p (sparc_leaf_function_p))
- {
if (size <= 4096)
+ insn = emit_insn (gen_stack_pointer_inc (size_int_rtx));
+ else if (size <= 8192 && !frame_pointer_needed)
{
- insn = emit_insn (gen_create_flat_frame_3 (GEN_INT (-size)));
+ insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-4096)));
RTX_FRAME_RELATED_P (insn) = 1;
- for (i=0; i < XVECLEN (PATTERN (insn), 0); i++)
- RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, i)) = 1;
+ insn = emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
}
else
{
- rtx reg = gen_rtx_REG (Pmode, 1), note;
- emit_move_insn (reg, GEN_INT (-size));
- insn = emit_insn (gen_create_flat_frame_3 (reg));
- note
- = gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec
- (2, gen_stack_pointer_inc (GEN_INT (-size)),
- copy_rtx
- (XVECEXP (PATTERN (insn), 0, 1))));
- RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
- for (i=0; i < XVECLEN (note, 0); i++)
- RTX_FRAME_RELATED_P (XVECEXP (note, 0, i)) = 1;
+ size_rtx = gen_rtx_REG (Pmode, 1);
+ emit_move_insn (size_rtx, size_int_rtx);
+ insn = emit_insn (gen_stack_pointer_inc (size_rtx));
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ gen_stack_pointer_inc (size_int_rtx));
}
- }
- else
- {
- if (size <= 4096)
- insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-size)));
- else if (size <= 8192)
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ if (frame_pointer_needed)
{
- insn = emit_insn (gen_stack_pointer_inc (GEN_INT (-4096)));
+ insn = emit_insn (gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
+ gen_rtx_MINUS (Pmode,
+ stack_pointer_rtx,
+ size_rtx)));
RTX_FRAME_RELATED_P (insn) = 1;
- insn = emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
+
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ gen_rtx_SET (VOIDmode, hard_frame_pointer_rtx,
+ plus_constant (stack_pointer_rtx,
+ size)));
+
+ /* Make sure nothing is scheduled until after the frame
+ is established. */
+ emit_insn (gen_blockage ());
}
- else
+
+ if (return_addr_reg_needed_p (sparc_leaf_function_p))
{
- rtx reg = gen_rtx_REG (Pmode, 1);
- emit_move_insn (reg, GEN_INT (-size));
- insn = emit_insn (gen_stack_pointer_inc (reg));
- add_reg_note (insn, REG_FRAME_RELATED_EXPR,
- gen_stack_pointer_inc (GEN_INT (-size)));
- }
+ rtx i7 = gen_rtx_REG (Pmode, INCOMING_RETURN_ADDR_REGNUM);
+ rtx o7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
- RTX_FRAME_RELATED_P (insn) = 1;
- }
+ insn = emit_move_insn (o7, i7);
+ RTX_FRAME_RELATED_P (insn) = 1;
- /* Make sure nothing is scheduled until after the frame is established. */
- emit_insn (gen_blockage ());
+ add_reg_note (insn, REG_CFA_REGISTER,
+ gen_rtx_SET (VOIDmode, o7, i7));
+
+ /* Prevent this instruction from ever being considered dead,
+ even if this function has no epilogue. */
+ emit_insn (gen_rtx_USE (VOIDmode, o7));
+ }
+ }
if (frame_pointer_needed)
{
"save\t%%sp, %0, %%sp"
[(set_attr "type" "savew")])
-;; For the "create flat frame" insns, we need to use special insns
-;; because %fp cannot be clobbered until after the frame is established (so
-;; that it contains the live register window save area) and %i7 changed with
-;; a simple move as it is a fixed register and the move would be eliminated.
-
-(define_insn "create_flat_frame_1<P:mode>"
- [(set (reg:P 30) (reg:P 14))
- (set (reg:P 14) (plus:P (reg:P 14)
- (match_operand:P 0 "arith_operand" "rI")))
- (set (reg:P 31) (reg:P 15))]
- "TARGET_FLAT"
- "add\t%%sp, %0, %%sp\n\tsub\t%%sp, %0, %%fp\n\tmov\t%%o7, %%i7"
- [(set_attr "type" "multi")
- (set_attr "length" "3")])
-
-(define_insn "create_flat_frame_2<P:mode>"
- [(set (reg:P 30) (reg:P 14))
- (set (reg:P 14) (plus:P (reg:P 14)
- (match_operand:P 0 "arith_operand" "rI")))]
- "TARGET_FLAT"
- "add\t%%sp, %0, %%sp\n\tsub\t%%sp, %0, %%fp"
- [(set_attr "type" "multi")
- (set_attr "length" "2")])
-
-(define_insn "create_flat_frame_3<P:mode>"
- [(set (reg:P 14) (plus:P (reg:P 14)
- (match_operand:P 0 "arith_operand" "rI")))
- (set (reg:P 31) (reg:P 15))]
- "TARGET_FLAT"
- "add\t%%sp, %0, %%sp\n\tmov\t%%o7, %%i7"
- [(set_attr "type" "multi")
- (set_attr "length" "2")])
-
(define_expand "epilogue"
[(return)]
""