Commit 915f619f by Jim Wilson

*** empty log message ***

From-SVN: r695
parent c468d2d0
...@@ -131,6 +131,9 @@ extern int target_flags; ...@@ -131,6 +131,9 @@ extern int target_flags;
/* Width of a word, in units (bytes). */ /* Width of a word, in units (bytes). */
#define UNITS_PER_WORD 4 #define UNITS_PER_WORD 4
/* Type used for ptrdiff_t, as a string used in a declaration. */
#define PTRDIFF_TYPE "int"
/* Type used for wchar_t, as a string used in a declaration. */ /* Type used for wchar_t, as a string used in a declaration. */
#define WCHAR_TYPE "short unsigned int" #define WCHAR_TYPE "short unsigned int"
......
...@@ -491,8 +491,9 @@ eligible_for_epilogue_delay (trial, slot) ...@@ -491,8 +491,9 @@ eligible_for_epilogue_delay (trial, slot)
if (get_attr_length (trial) != 1) if (get_attr_length (trial) != 1)
return 0; return 0;
/* In the case of a true leaf function, anything can /* In the case of a true leaf function, anything can go into the delay slot.
go into the delay slot. */ A delay slot only exists however if the frame size is zero, otherwise
we will put an insn to adjust the stack after the return. */
if (leaf_function) if (leaf_function)
{ {
if (leaf_return_peephole_ok ()) if (leaf_return_peephole_ok ())
...@@ -505,13 +506,10 @@ eligible_for_epilogue_delay (trial, slot) ...@@ -505,13 +506,10 @@ eligible_for_epilogue_delay (trial, slot)
pat = PATTERN (trial); pat = PATTERN (trial);
if (GET_CODE (SET_DEST (pat)) != REG if (GET_CODE (SET_DEST (pat)) != REG
|| REGNO (SET_DEST (pat)) == 0 || REGNO (SET_DEST (pat)) == 0
|| (leaf_function || REGNO (SET_DEST (pat)) >= 32
&& REGNO (SET_DEST (pat)) < 32 || REGNO (SET_DEST (pat)) < 24)
&& REGNO (SET_DEST (pat)) >= 16)
|| (! leaf_function
&& (REGNO (SET_DEST (pat)) >= 32
|| REGNO (SET_DEST (pat)) < 24)))
return 0; return 0;
src = SET_SRC (pat); src = SET_SRC (pat);
if (arith_operand (src, GET_MODE (src))) if (arith_operand (src, GET_MODE (src)))
return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode); return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode);
...@@ -946,9 +944,9 @@ singlemove_string (operands) ...@@ -946,9 +944,9 @@ singlemove_string (operands)
{ {
int i = INTVAL (operands[1]); int i = INTVAL (operands[1]);
/* If all low order 12 bits are clear, then we only need a single /* If all low order 10 bits are clear, then we only need a single
sethi insn to load the constant. */ sethi insn to load the constant. */
if (i & 0x00000FFF) if ((i & 0x000003FF) != 0)
return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0";
else else
return "sethi %%hi(%a1),%0"; return "sethi %%hi(%a1),%0";
...@@ -1841,48 +1839,63 @@ compute_last_arg_offset () ...@@ -1841,48 +1839,63 @@ compute_last_arg_offset ()
return 4096; return 4096;
} }
/* Output code for the function prologue. */
void void
output_function_prologue (file, size, leaf_function) output_function_prologue (file, size, leaf_function)
FILE *file; FILE *file;
int size; int size;
int leaf_function;
{ {
if (leaf_function) if (leaf_function)
frame_base_name = "%sp+80"; frame_base_name = "%sp+80";
else else
frame_base_name = "%fp"; frame_base_name = "%fp";
/* Need to use actual_fsize, since we are also allocating
space for our callee (and our own register save area). */
actual_fsize = compute_frame_size (size, leaf_function); actual_fsize = compute_frame_size (size, leaf_function);
fprintf (file, "\t!#PROLOGUE# 0\n"); fprintf (file, "\t!#PROLOGUE# 0\n");
if (actual_fsize == 0) /* do nothing. */ ; if (actual_fsize == 0)
else if (actual_fsize < 4096) /* do nothing. */ ;
else if (actual_fsize <= 4096)
{ {
if (! leaf_function) if (! leaf_function)
fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize); fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize);
else else
fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize); fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize);
} }
else if (! leaf_function) else if (actual_fsize <= 8192)
{ {
/* Need to use actual_fsize, since we are also allocating space for /* For frames in the range 4097..8192, we can use just two insns. */
our callee (and our own register save area). */ if (! leaf_function)
fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n", {
-actual_fsize, -actual_fsize); fprintf (file, "\tsave %%sp,-4096,%%sp\n");
fprintf (file, "\tsave %%sp,%%g1,%%sp\n"); fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096);
}
else
{
fprintf (file, "\tadd %%sp,-4096,%%sp\n");
fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096);
}
} }
else else
{ {
/* The rest of the support for this case hasn't been implemented, if (! leaf_function)
but FRAME_POINTER_REQUIRED is supposed to prevent it from arising, {
by checking the frame size. */ fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize);
abort (); if ((actual_fsize & 0x3ff) != 0)
fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize);
/* Put pointer to parameters into %g4, and allocate fprintf (file, "\tsave %%sp,%%g1,%%sp\n");
frame space using result computed into %g1. actual_fsize }
used instead of apparent_fsize for reasons stated above. */ else
fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n", {
-actual_fsize, -actual_fsize); fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize);
fprintf (file, "\tadd %%sp,64,%%g4\n\tadd %%sp,%%g1,%%sp\n"); if ((actual_fsize & 0x3ff) != 0)
fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize);
fprintf (file, "\tadd %%sp,%%g1,%%sp\n");
}
} }
/* If doing anything with PIC, do it now. */ /* If doing anything with PIC, do it now. */
...@@ -1922,6 +1935,8 @@ output_function_prologue (file, size, leaf_function) ...@@ -1922,6 +1935,8 @@ output_function_prologue (file, size, leaf_function)
} }
} }
/* Output code for the function epilogue. */
void void
output_function_epilogue (file, size, leaf_function) output_function_epilogue (file, size, leaf_function)
FILE *file; FILE *file;
...@@ -1982,24 +1997,30 @@ output_function_epilogue (file, size, leaf_function) ...@@ -1982,24 +1997,30 @@ output_function_epilogue (file, size, leaf_function)
else else
fprintf (file, "\t%s\n\trestore\n", ret); fprintf (file, "\t%s\n\trestore\n", ret);
} }
else if (actual_fsize < 4096) /* All of the following cases are for leaf functions. */
else if (current_function_epilogue_delay_list)
{ {
if (current_function_epilogue_delay_list) /* eligible_for_epilogue_delay_slot ensures that if this is a
{ leaf function, then we will only have insn in the delay slot
fprintf (file, "\t%s\n", ret); if the frame size is zero, thus no adjust for the stack is
final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), needed here. */
file, 1, 0, 1); if (actual_fsize != 0)
}
else
fprintf (file, "\t%s\n\tadd %%sp,%d,%%sp\n", ret, actual_fsize);
}
else
{
if (current_function_epilogue_delay_list)
abort (); abort ();
fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", fprintf (file, "\t%s\n", ret);
actual_fsize, actual_fsize, ret); final_scan_insn (XEXP (current_function_epilogue_delay_list, 0),
file, 1, 0, 1);
} }
else if (actual_fsize <= 4096)
fprintf (file, "\t%s\n\tsub %%sp,-%d,%%sp\n", ret, actual_fsize);
else if (actual_fsize <= 8192)
fprintf (file, "\tsub %%sp,-4096,%%sp\n\t%s\n\tsub %%sp,-%d,%%sp\n",
ret, actual_fsize - 4096);
else if ((actual_fsize & 0x3ff) == 0)
fprintf (file, "\tsethi %%hi(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
actual_fsize, ret);
else
fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n",
actual_fsize, actual_fsize, ret);
target_flags |= old_target_epilogue; target_flags |= old_target_epilogue;
} }
} }
...@@ -2146,20 +2167,43 @@ output_return (operands) ...@@ -2146,20 +2167,43 @@ output_return (operands)
} }
else if (leaf_function) else if (leaf_function)
{ {
/* If we didn't allocate a frame pointer for the current function,
the stack pointer might have been adjusted. Output code to
restore it now. */
operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize); operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize);
if (actual_fsize < 4096)
/* Use sub of negated value in first two cases instead of add to
allow actual_fsize == 4096. */
if (actual_fsize <= 4096)
{ {
if (current_function_returns_struct) if (current_function_returns_struct)
return "jmp %%o7+12\n\tadd %%sp,%0,%%sp"; return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp";
else else
return "retl\n\tadd %%sp,%0,%%sp"; return "retl\n\tsub %%sp,-%0,%%sp";
} }
else else if (actual_fsize <= 8192)
{ {
operands[0] = gen_rtx (CONST_INT, VOIDmode, actual_fsize - 4096);
if (current_function_returns_struct) if (current_function_returns_struct)
return "sub %%sp,-4096,%%sp\n\tjmp %%o7+12\n\tsub %%sp,-%0,%%sp";
else
return "sub %%sp,-4096,%%sp\n\tretl\n\tsub %%sp,-%0,%%sp";
}
else if (current_function_returns_struct)
{
if ((actual_fsize & 0x3ff) != 0)
return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
else else
return "sethi %%hi(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp";
}
else
{
if ((actual_fsize & 0x3ff) != 0)
return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
else
return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp";
} }
} }
else else
......
...@@ -116,7 +116,6 @@ int simplejump_p (); ...@@ -116,7 +116,6 @@ int simplejump_p ();
extern rtx gen_jump (); extern rtx gen_jump ();
void squeeze_notes ();
static void mark_jump_label (); static void mark_jump_label ();
void delete_jump (); void delete_jump ();
static void delete_from_jump_chain (); static void delete_from_jump_chain ();
...@@ -1429,8 +1428,8 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) ...@@ -1429,8 +1428,8 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
/* Don't move NOTEs for blocks or loops; shift them /* Don't move NOTEs for blocks or loops; shift them
outside the ranges, where they'll stay put. */ outside the ranges, where they'll stay put. */
squeeze_notes (range1beg, range1end); range1beg = squeeze_notes (range1beg, range1end);
squeeze_notes (range2beg, range2end); range2beg = squeeze_notes (range2beg, range2end);
/* Get current surrounds of the 2 ranges. */ /* Get current surrounds of the 2 ranges. */
range1before = PREV_INSN (range1beg); range1before = PREV_INSN (range1beg);
...@@ -1824,10 +1823,12 @@ duplicate_loop_exit_test (loop_start) ...@@ -1824,10 +1823,12 @@ duplicate_loop_exit_test (loop_start)
} }
/* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, and /* Move all block-beg, block-end, loop-beg, loop-cont, loop-vtop, and
loop-end notes between START and END out before START. Assume neither loop-end notes between START and END out before START. Assume that
START nor END is such a note. */ END is not such a note. START may be such a note. Returns the value
of the new starting insn, which may be different if the original start
was such a note. */
void rtx
squeeze_notes (start, end) squeeze_notes (start, end)
rtx start, end; rtx start, end;
{ {
...@@ -1845,15 +1846,22 @@ squeeze_notes (start, end) ...@@ -1845,15 +1846,22 @@ squeeze_notes (start, end)
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_CONT
|| NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP)) || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_VTOP))
{ {
rtx prev = PREV_INSN (insn); if (insn == start)
PREV_INSN (insn) = PREV_INSN (start); start = next;
NEXT_INSN (insn) = start; else
NEXT_INSN (PREV_INSN (insn)) = insn; {
PREV_INSN (NEXT_INSN (insn)) = insn; rtx prev = PREV_INSN (insn);
NEXT_INSN (prev) = next; PREV_INSN (insn) = PREV_INSN (start);
PREV_INSN (next) = prev; NEXT_INSN (insn) = start;
NEXT_INSN (PREV_INSN (insn)) = insn;
PREV_INSN (NEXT_INSN (insn)) = insn;
NEXT_INSN (prev) = next;
PREV_INSN (next) = prev;
}
} }
} }
return start;
} }
/* Compare the instructions before insn E1 with those before E2 /* Compare the instructions before insn E1 with those before E2
......
...@@ -2294,7 +2294,7 @@ find_and_verify_loops (f) ...@@ -2294,7 +2294,7 @@ find_and_verify_loops (f)
/* Include the BARRIER after INSN and copy the /* Include the BARRIER after INSN and copy the
block after LOC. */ block after LOC. */
squeeze_notes (new_label, NEXT_INSN (insn)); new_label = squeeze_notes (new_label, NEXT_INSN (insn));
reorder_insns (new_label, NEXT_INSN (insn), loc); reorder_insns (new_label, NEXT_INSN (insn), loc);
/* All those insns are now in TARGET_LOOP_NUM. */ /* All those insns are now in TARGET_LOOP_NUM. */
......
...@@ -617,6 +617,7 @@ extern enum rtx_code unsigned_condition (); ...@@ -617,6 +617,7 @@ extern enum rtx_code unsigned_condition ();
extern enum rtx_code signed_condition (); extern enum rtx_code signed_condition ();
extern rtx plus_constant (), plus_constant_for_output (); extern rtx plus_constant (), plus_constant_for_output ();
extern rtx find_equiv_reg (); extern rtx find_equiv_reg ();
extern rtx squeeze_notes ();
extern rtx delete_insn (); extern rtx delete_insn ();
extern void delete_jump (); extern void delete_jump ();
extern rtx get_label_before (); extern rtx get_label_before ();
......
...@@ -3752,7 +3752,8 @@ expand_end_case (orig_index) ...@@ -3752,7 +3752,8 @@ expand_end_case (orig_index)
#endif #endif
} }
reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case = squeeze_notes (NEXT_INSN (before_case), get_last_insn ());
reorder_insns (before_case, get_last_insn (),
thiscase->data.case_stmt.start); thiscase->data.case_stmt.start);
} }
if (thiscase->exit_label) if (thiscase->exit_label)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment