From: Jim Wilson Date: Mon, 6 Apr 1992 18:11:25 +0000 (-0700) Subject: *** empty log message *** X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=915f619f86bf1f576c909e48cda7699d1addbfbf;p=gcc.git *** empty log message *** From-SVN: r695 --- diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 8ef2cd06e60..0791082f6b8 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -131,6 +131,9 @@ extern int target_flags; /* Width of a word, in units (bytes). */ #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. */ #define WCHAR_TYPE "short unsigned int" diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index c9a7e35e762..6584320f8c3 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -491,8 +491,9 @@ eligible_for_epilogue_delay (trial, slot) if (get_attr_length (trial) != 1) return 0; - /* In the case of a true leaf function, anything can - go into the delay slot. */ + /* In the case of a true leaf function, anything can 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_return_peephole_ok ()) @@ -505,13 +506,10 @@ eligible_for_epilogue_delay (trial, slot) pat = PATTERN (trial); if (GET_CODE (SET_DEST (pat)) != REG || REGNO (SET_DEST (pat)) == 0 - || (leaf_function - && REGNO (SET_DEST (pat)) < 32 - && REGNO (SET_DEST (pat)) >= 16) - || (! leaf_function - && (REGNO (SET_DEST (pat)) >= 32 - || REGNO (SET_DEST (pat)) < 24))) + || REGNO (SET_DEST (pat)) >= 32 + || REGNO (SET_DEST (pat)) < 24) return 0; + src = SET_SRC (pat); if (arith_operand (src, GET_MODE (src))) return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode); @@ -946,9 +944,9 @@ singlemove_string (operands) { 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. */ - if (i & 0x00000FFF) + if ((i & 0x000003FF) != 0) return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; else return "sethi %%hi(%a1),%0"; @@ -1841,48 +1839,63 @@ compute_last_arg_offset () return 4096; } +/* Output code for the function prologue. */ + void output_function_prologue (file, size, leaf_function) FILE *file; int size; + int leaf_function; { if (leaf_function) frame_base_name = "%sp+80"; else 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); fprintf (file, "\t!#PROLOGUE# 0\n"); - if (actual_fsize == 0) /* do nothing. */ ; - else if (actual_fsize < 4096) + if (actual_fsize == 0) + /* do nothing. */ ; + else if (actual_fsize <= 4096) { if (! leaf_function) fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize); else 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 - our callee (and our own register save area). */ - fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n", - -actual_fsize, -actual_fsize); - fprintf (file, "\tsave %%sp,%%g1,%%sp\n"); + /* For frames in the range 4097..8192, we can use just two insns. */ + if (! leaf_function) + { + fprintf (file, "\tsave %%sp,-4096,%%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 { - /* The rest of the support for this case hasn't been implemented, - but FRAME_POINTER_REQUIRED is supposed to prevent it from arising, - by checking the frame size. */ - abort (); - - /* Put pointer to parameters into %g4, and allocate - frame space using result computed into %g1. actual_fsize - used instead of apparent_fsize for reasons stated above. */ - fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n", - -actual_fsize, -actual_fsize); - fprintf (file, "\tadd %%sp,64,%%g4\n\tadd %%sp,%%g1,%%sp\n"); + if (! leaf_function) + { + fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize); + if ((actual_fsize & 0x3ff) != 0) + fprintf (file, "\tor %%g1,%%lo(-%d),%%g1\n", actual_fsize); + fprintf (file, "\tsave %%sp,%%g1,%%sp\n"); + } + else + { + fprintf (file, "\tsethi %%hi(-%d),%%g1\n", actual_fsize); + 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. */ @@ -1922,6 +1935,8 @@ output_function_prologue (file, size, leaf_function) } } +/* Output code for the function epilogue. */ + void output_function_epilogue (file, size, leaf_function) FILE *file; @@ -1982,24 +1997,30 @@ output_function_epilogue (file, size, leaf_function) else 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) - { - fprintf (file, "\t%s\n", ret); - final_scan_insn (XEXP (current_function_epilogue_delay_list, 0), - file, 1, 0, 1); - } - else - fprintf (file, "\t%s\n\tadd %%sp,%d,%%sp\n", ret, actual_fsize); - } - else - { - 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 + if the frame size is zero, thus no adjust for the stack is + needed here. */ + if (actual_fsize != 0) abort (); - 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); + fprintf (file, "\t%s\n", 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; } } @@ -2146,20 +2167,43 @@ output_return (operands) } 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); - 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) - return "jmp %%o7+12\n\tadd %%sp,%0,%%sp"; + return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp"; 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) + 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"; 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"; + else + return "sethi %%hi(%a0),%%g1\n\tretl\n\tadd %%sp,%%g1,%%sp"; } } else diff --git a/gcc/jump.c b/gcc/jump.c index 1a745bb3bcf..410fe64a268 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -116,7 +116,6 @@ int simplejump_p (); extern rtx gen_jump (); -void squeeze_notes (); static void mark_jump_label (); void delete_jump (); static void delete_from_jump_chain (); @@ -1429,8 +1428,8 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan) /* Don't move NOTEs for blocks or loops; shift them outside the ranges, where they'll stay put. */ - squeeze_notes (range1beg, range1end); - squeeze_notes (range2beg, range2end); + range1beg = squeeze_notes (range1beg, range1end); + range2beg = squeeze_notes (range2beg, range2end); /* Get current surrounds of the 2 ranges. */ range1before = PREV_INSN (range1beg); @@ -1824,10 +1823,12 @@ duplicate_loop_exit_test (loop_start) } /* 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 - START nor END is such a note. */ + loop-end notes between START and END out before START. Assume that + 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) rtx 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_VTOP)) { - rtx prev = PREV_INSN (insn); - PREV_INSN (insn) = PREV_INSN (start); - NEXT_INSN (insn) = start; - NEXT_INSN (PREV_INSN (insn)) = insn; - PREV_INSN (NEXT_INSN (insn)) = insn; - NEXT_INSN (prev) = next; - PREV_INSN (next) = prev; + if (insn == start) + start = next; + else + { + rtx prev = PREV_INSN (insn); + PREV_INSN (insn) = PREV_INSN (start); + 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 diff --git a/gcc/loop.c b/gcc/loop.c index d22e97126e5..4f255ef24cd 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -2294,7 +2294,7 @@ find_and_verify_loops (f) /* Include the BARRIER after INSN and copy the 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); /* All those insns are now in TARGET_LOOP_NUM. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 7469539553f..6936302917f 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -617,6 +617,7 @@ extern enum rtx_code unsigned_condition (); extern enum rtx_code signed_condition (); extern rtx plus_constant (), plus_constant_for_output (); extern rtx find_equiv_reg (); +extern rtx squeeze_notes (); extern rtx delete_insn (); extern void delete_jump (); extern rtx get_label_before (); diff --git a/gcc/stmt.c b/gcc/stmt.c index 80f12c6f215..a999cb4f402 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -3752,7 +3752,8 @@ expand_end_case (orig_index) #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); } if (thiscase->exit_label)