From 563c12b029649156a5de1c934a6dd67838ca4845 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 4 Feb 2002 10:16:07 -0800 Subject: [PATCH] combine.c (force_to_mode): Remove STACK_BIAS code. * combine.c (force_to_mode): Remove STACK_BIAS code. (nonzero_bits): Likewise. Replace sp/fp special case with REGNO_POINTER_ALIGN. * config/sparc/sparc.h (FRAME_POINTER_REGNUM): Change to SFP. (HARD_FRAME_POINTER_REGNUM): New. (FIRST_PSEUDO_REGISTER, REG_CLASS_CONTENTS): Update. (FIXED_REGS, CALL_USED_REGS): Update. (REG_ALLOC_ORDER, REGISTER_NAMES): Update. (CONDITIONAL_REGISTER_USAGE): Update for HFP. (HARD_REGNO_NREGS): Update for SFP. (STACK_POINTER_OFFSET): Include bias here ... (FIRST_PARM_OFFSET): ... not here. (STACK_BIAS): Remove. (INIT_EXPANDERS): New. (STARTING_FRAME_OFFSET): Do not include bias. (ELIMINABLE_REGS, CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): New. (REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P): Update for SFP. (REG_OK_FOR_INDEX_P, REG_OK_FOR_BASE_P): Likewise. * config/sparc/aout.h (DBX_REGISTER_NUMBER): Update for HFP. * config/sparc/litecoff.h, config/sparc/sol2.h: Likewise. * config/sparc/sparc.c (mem_min_alignment): Update for HFP. (sparc_nonflat_function_prologue, epilogue_renumber): Likewise. (MUST_SAVE_REGISTER): Likewise. (sparc_flat_function_prologue): Likewise. (sparc_flat_function_epilogue): Likewise. (HARD_FRAME_POINTER_MASK): Rename from FRAME_POINTER_MASK. (sparc_init_modes): SFP is GENERAL_REGS. (sparc_builtin_saveregs): SFP does not have bias applied. From-SVN: r49486 --- gcc/ChangeLog | 32 +++++++++++ gcc/combine.c | 92 +++++++----------------------- gcc/config/sparc/aout.h | 2 +- gcc/config/sparc/litecoff.h | 2 +- gcc/config/sparc/sol2.h | 2 +- gcc/config/sparc/sparc.c | 62 ++++++++++---------- gcc/config/sparc/sparc.h | 110 ++++++++++++++++++++++-------------- 7 files changed, 153 insertions(+), 149 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 919a4081be8..e55ca94e7e8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,35 @@ +2002-02-04 Richard Henderson + + * combine.c (force_to_mode): Remove STACK_BIAS code. + (nonzero_bits): Likewise. Replace sp/fp special case with + REGNO_POINTER_ALIGN. + + * config/sparc/sparc.h (FRAME_POINTER_REGNUM): Change to SFP. + (HARD_FRAME_POINTER_REGNUM): New. + (FIRST_PSEUDO_REGISTER, REG_CLASS_CONTENTS): Update. + (FIXED_REGS, CALL_USED_REGS): Update. + (REG_ALLOC_ORDER, REGISTER_NAMES): Update. + (CONDITIONAL_REGISTER_USAGE): Update for HFP. + (HARD_REGNO_NREGS): Update for SFP. + (STACK_POINTER_OFFSET): Include bias here ... + (FIRST_PARM_OFFSET): ... not here. + (STACK_BIAS): Remove. + (INIT_EXPANDERS): New. + (STARTING_FRAME_OFFSET): Do not include bias. + (ELIMINABLE_REGS, CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): New. + (REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P): Update for SFP. + (REG_OK_FOR_INDEX_P, REG_OK_FOR_BASE_P): Likewise. + * config/sparc/aout.h (DBX_REGISTER_NUMBER): Update for HFP. + * config/sparc/litecoff.h, config/sparc/sol2.h: Likewise. + * config/sparc/sparc.c (mem_min_alignment): Update for HFP. + (sparc_nonflat_function_prologue, epilogue_renumber): Likewise. + (MUST_SAVE_REGISTER): Likewise. + (sparc_flat_function_prologue): Likewise. + (sparc_flat_function_epilogue): Likewise. + (HARD_FRAME_POINTER_MASK): Rename from FRAME_POINTER_MASK. + (sparc_init_modes): SFP is GENERAL_REGS. + (sparc_builtin_saveregs): SFP does not have bias applied. + 2002-02-04 Richard Henderson * config/alpha/alpha.c (current_function_is_thunk): Don't check diff --git a/gcc/combine.c b/gcc/combine.c index 25b4d63d0f0..7662b9b6908 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -6753,33 +6753,12 @@ force_to_mode (x, mode, mask, reg, just_select) smask |= (HOST_WIDE_INT) -1 << width; if (GET_CODE (XEXP (x, 1)) == CONST_INT - && exact_log2 (- smask) >= 0) - { -#ifdef STACK_BIAS - if (STACK_BIAS - && (XEXP (x, 0) == stack_pointer_rtx - || XEXP (x, 0) == frame_pointer_rtx)) - { - int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; - unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode); - - sp_mask &= ~(sp_alignment - 1); - if ((sp_mask & ~smask) == 0 - && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~smask) != 0) - return force_to_mode (plus_constant (XEXP (x, 0), - ((INTVAL (XEXP (x, 1)) - - STACK_BIAS) & smask) - + STACK_BIAS), - mode, smask, reg, next_select); - } -#endif - if ((nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0 - && (INTVAL (XEXP (x, 1)) & ~smask) != 0) - return force_to_mode (plus_constant (XEXP (x, 0), - (INTVAL (XEXP (x, 1)) - & smask)), - mode, smask, reg, next_select); - } + && exact_log2 (- smask) >= 0 + && (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0 + && (INTVAL (XEXP (x, 1)) & ~smask) != 0) + return force_to_mode (plus_constant (XEXP (x, 0), + (INTVAL (XEXP (x, 1)) & smask)), + mode, smask, reg, next_select); } /* ... fall through ... */ @@ -7916,40 +7895,23 @@ nonzero_bits (x, mode) nonzero &= GET_MODE_MASK (ptr_mode); #endif -#ifdef STACK_BOUNDARY - /* If this is the stack pointer, we may know something about its - alignment. If PUSH_ROUNDING is defined, it is possible for the - stack to be momentarily aligned only to that amount, so we pick - the least alignment. */ - - /* We can't check for arg_pointer_rtx here, because it is not - guaranteed to have as much alignment as the stack pointer. - In particular, in the Irix6 n64 ABI, the stack has 128 bit - alignment but the argument pointer has only 64 bit alignment. */ - - if ((x == frame_pointer_rtx - || x == stack_pointer_rtx - || x == hard_frame_pointer_rtx - || (REGNO (x) >= FIRST_VIRTUAL_REGISTER - && REGNO (x) <= LAST_VIRTUAL_REGISTER)) -#ifdef STACK_BIAS - && !STACK_BIAS -#endif - ) + /* Include declared information about alignment of pointers. */ + + if (REG_POINTER (x) && REGNO_POINTER_ALIGN (REGNO (x))) { - int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; + unsigned HOST_WIDE_INT alignment + = REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT; #ifdef PUSH_ROUNDING - if (REGNO (x) == STACK_POINTER_REGNUM && PUSH_ARGS) - sp_alignment = MIN (PUSH_ROUNDING (1), sp_alignment); + /* If PUSH_ROUNDING is defined, it is possible for the + stack to be momentarily aligned only to that amount, + so we pick the least alignment. */ + if (x == stack_pointer_rtx && PUSH_ARGS) + alignment = MIN (PUSH_ROUNDING (1), alignment); #endif - /* We must return here, otherwise we may get a worse result from - one of the choices below. There is nothing useful below as - far as the stack pointer is concerned. */ - return nonzero &= ~(sp_alignment - 1); + nonzero &= ~(alignment - 1); } -#endif /* If X is a register whose nonzero bits value is current, use it. Otherwise, if X is a register whose value we can find, use that @@ -7964,7 +7926,7 @@ nonzero_bits (x, mode) && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, REGNO (x)))) && INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid) - return reg_last_set_nonzero_bits[REGNO (x)]; + return reg_last_set_nonzero_bits[REGNO (x)] & nonzero; tem = get_last_value (x); @@ -7990,7 +7952,7 @@ nonzero_bits (x, mode) | ((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (GET_MODE (x)))); #endif - return nonzero_bits (tem, mode); + return nonzero_bits (tem, mode) & nonzero; } else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)]) { @@ -8128,22 +8090,6 @@ nonzero_bits (x, mode) switch (code) { case PLUS: -#ifdef STACK_BIAS - if (STACK_BIAS - && (XEXP (x, 0) == stack_pointer_rtx - || XEXP (x, 0) == frame_pointer_rtx) - && GET_CODE (XEXP (x, 1)) == CONST_INT) - { - int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; - - nz0 = (GET_MODE_MASK (mode) & ~(sp_alignment - 1)); - nz1 = INTVAL (XEXP (x, 1)) - STACK_BIAS; - width0 = floor_log2 (nz0) + 1; - width1 = floor_log2 (nz1) + 1; - low0 = floor_log2 (nz0 & -nz0); - low1 = floor_log2 (nz1 & -nz1); - } -#endif result_width = MAX (width0, width1) + 1; result_low = MIN (low0, low1); break; diff --git a/gcc/config/sparc/aout.h b/gcc/config/sparc/aout.h index fd84d75244b..3a2273f488b 100644 --- a/gcc/config/sparc/aout.h +++ b/gcc/config/sparc/aout.h @@ -88,7 +88,7 @@ do { \ pointer is really %i7. */ #define DBX_REGISTER_NUMBER(REGNO) \ - (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO) + (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO) /* This is how to output a note to DBX telling it the line number to which the following sequence of instructions corresponds. diff --git a/gcc/config/sparc/litecoff.h b/gcc/config/sparc/litecoff.h index dede792e69b..ad0e1225db4 100644 --- a/gcc/config/sparc/litecoff.h +++ b/gcc/config/sparc/litecoff.h @@ -73,4 +73,4 @@ do { \ pointer is really %i7. */ #define DBX_REGISTER_NUMBER(REGNO) \ - (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO) + (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO) diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h index 46e80c121cb..a387dc24a18 100644 --- a/gcc/config/sparc/sol2.h +++ b/gcc/config/sparc/sol2.h @@ -83,7 +83,7 @@ Boston, MA 02111-1307, USA. */ #undef DBX_REGISTER_NUMBER /* Same as sparc.h */ #define DBX_REGISTER_NUMBER(REGNO) \ - (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO) + (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO) /* We use stabs-in-elf for debugging, because that is what the native toolchain uses. */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index c5b64a7b71d..4017ae7af8d 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -83,10 +83,9 @@ static rtx leaf_label; #ifdef LEAF_REGISTERS -/* Vector to say how input registers are mapped to output - registers. FRAME_POINTER_REGNUM cannot be remapped by - this function to eliminate it. You must use -fomit-frame-pointer - to get that. */ +/* Vector to say how input registers are mapped to output registers. + HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to + eliminate it. You must use -fomit-frame-pointer to get that. */ const char leaf_reg_remap[] = { 0, 1, 2, 3, 4, 5, 6, 7, -1, -1, -1, -1, -1, -1, 14, -1, @@ -2988,8 +2987,7 @@ mem_min_alignment (mem, desired) { int regno = REGNO (base); - if (regno != FRAME_POINTER_REGNUM - && regno != STACK_POINTER_REGNUM) + if (regno != HARD_FRAME_POINTER_REGNUM && regno != STACK_POINTER_REGNUM) { /* Check if the compiler has recorded some information about the alignment of the base REG. If reload has @@ -3206,7 +3204,7 @@ sparc_init_modes () { if (i < 16 && TARGET_V8PLUS) sparc_regno_reg_class[i] = I64_REGS; - else if (i < 32) + else if (i < 32 || i == FRAME_POINTER_REGNUM) sparc_regno_reg_class[i] = GENERAL_REGS; else if (i < 64) sparc_regno_reg_class[i] = FP_REGS; @@ -3554,7 +3552,7 @@ sparc_nonflat_function_prologue (file, size, leaf_function) /* The canonical frame address refers to the top of the frame. */ dwarf2out_def_cfa (label, (leaf_function ? STACK_POINTER_REGNUM - : FRAME_POINTER_REGNUM), + : HARD_FRAME_POINTER_REGNUM), frame_base_offset); if (! leaf_function) @@ -4862,7 +4860,7 @@ sparc_builtin_saveregs () emit_move_insn (gen_rtx_MEM (word_mode, gen_rtx_PLUS (Pmode, frame_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET + GEN_INT (FIRST_PARM_OFFSET (0) + (UNITS_PER_WORD * regno)))), gen_rtx_REG (word_mode, @@ -4870,7 +4868,7 @@ sparc_builtin_saveregs () address = gen_rtx_PLUS (Pmode, frame_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET + GEN_INT (FIRST_PARM_OFFSET (0) + UNITS_PER_WORD * first_reg)); return address; @@ -5483,7 +5481,7 @@ epilogue_renumber (where, test) are in the return delayed slot. */ case PLUS: if (GET_CODE (XEXP (*where, 0)) == REG - && REGNO (XEXP (*where, 0)) == FRAME_POINTER_REGNUM + && REGNO (XEXP (*where, 0)) == HARD_FRAME_POINTER_REGNUM && (GET_CODE (XEXP (*where, 1)) != CONST_INT || INTVAL (XEXP (*where, 1)) < SPARC_STACK_BIAS)) return 1; @@ -5492,7 +5490,7 @@ epilogue_renumber (where, test) case MEM: if (SPARC_STACK_BIAS && GET_CODE (XEXP (*where, 0)) == REG - && REGNO (XEXP (*where, 0)) == FRAME_POINTER_REGNUM) + && REGNO (XEXP (*where, 0)) == HARD_FRAME_POINTER_REGNUM) return 1; break; @@ -6437,12 +6435,12 @@ struct sparc_frame_info zero_frame_info; /* Tell prologue and epilogue if register REGNO should be saved / restored. */ #define RETURN_ADDR_REGNUM 15 -#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM)) +#define HARD_FRAME_POINTER_MASK (1 << (HARD_FRAME_POINTER_REGNUM)) #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM)) #define MUST_SAVE_REGISTER(regno) \ - ((regs_ever_live[regno] && !call_used_regs[regno]) \ - || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) \ + ((regs_ever_live[regno] && !call_used_regs[regno]) \ + || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \ || (regno == RETURN_ADDR_REGNUM && regs_ever_live[RETURN_ADDR_REGNUM])) /* Return the bytes needed to compute the frame pointer from the current @@ -6715,7 +6713,7 @@ sparc_flat_function_prologue (file, size) if (size > 0) { unsigned int reg_offset = current_frame_info.reg_offset; - const char *const fp_str = reg_names[FRAME_POINTER_REGNUM]; + const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM]; static const char *const t1_str = "%g1"; /* Things get a little tricky if local variables take up more than ~4096 @@ -6736,7 +6734,7 @@ sparc_flat_function_prologue (file, size) { fprintf (file, "\tadd\t%s, %d, %s\n", sp_str, (int) -size, sp_str); - if (gmask & FRAME_POINTER_MASK) + if (gmask & HARD_FRAME_POINTER_MASK) { fprintf (file, "\tst\t%s, [%s+%d]\n", fp_str, sp_str, reg_offset); @@ -6751,7 +6749,7 @@ sparc_flat_function_prologue (file, size) fprintf (file, HOST_WIDE_INT_PRINT_DEC, size); fprintf (file, ", %s\n\tsub\t%s, %s, %s\n", t1_str, sp_str, t1_str, sp_str); - if (gmask & FRAME_POINTER_MASK) + if (gmask & HARD_FRAME_POINTER_MASK) { fprintf (file, "\tst\t%s, [%s+%d]\n", fp_str, sp_str, reg_offset); @@ -6763,11 +6761,11 @@ sparc_flat_function_prologue (file, size) if (dwarf2out_do_frame ()) { char *l = dwarf2out_cfi_label (); - if (gmask & FRAME_POINTER_MASK) + if (gmask & HARD_FRAME_POINTER_MASK) { - dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, + dwarf2out_reg_save (l, HARD_FRAME_POINTER_REGNUM, reg_offset - 4 - size); - dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, 0); + dwarf2out_def_cfa (l, HARD_FRAME_POINTER_REGNUM, 0); } else dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, size); @@ -6781,7 +6779,7 @@ sparc_flat_function_prologue (file, size) reg_offset += 4; } sparc_flat_save_restore (file, sp_str, reg_offset, - gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), + gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK), current_frame_info.fmask, "st", "std", -size); } @@ -6798,7 +6796,7 @@ sparc_flat_function_prologue (file, size) { fprintf (file, "\tadd\t%s, %d, %s\n", sp_str, (int) -size1, sp_str); - if (gmask & FRAME_POINTER_MASK) + if (gmask & HARD_FRAME_POINTER_MASK) { fprintf (file, "\tst\t%s, [%s+%d]\n\tsub\t%s, %d, %s\t%s# set up frame pointer\n", fp_str, sp_str, (int) offset, sp_str, (int) -size1, @@ -6812,7 +6810,7 @@ sparc_flat_function_prologue (file, size) fprintf (file, HOST_WIDE_INT_PRINT_DEC, size1); fprintf (file, ", %s\n\tsub\t%s, %s, %s\n", t1_str, sp_str, t1_str, sp_str); - if (gmask & FRAME_POINTER_MASK) + if (gmask & HARD_FRAME_POINTER_MASK) { fprintf (file, "\tst\t%s, [%s+%d]\n\tadd\t%s, %s, %s\t%s# set up frame pointer\n", fp_str, sp_str, (int) offset, sp_str, t1_str, @@ -6823,11 +6821,11 @@ sparc_flat_function_prologue (file, size) if (dwarf2out_do_frame ()) { char *l = dwarf2out_cfi_label (); - if (gmask & FRAME_POINTER_MASK) + if (gmask & HARD_FRAME_POINTER_MASK) { - dwarf2out_reg_save (l, FRAME_POINTER_REGNUM, + dwarf2out_reg_save (l, HARD_FRAME_POINTER_REGNUM, offset - 4 - size1); - dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, 0); + dwarf2out_def_cfa (l, HARD_FRAME_POINTER_REGNUM, 0); } else dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, size1); @@ -6843,7 +6841,7 @@ sparc_flat_function_prologue (file, size) offset += 4; } sparc_flat_save_restore (file, sp_str, offset, - gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), + gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK), current_frame_info.fmask, "st", "std", -size1); fprintf (file, "\tset\t"); @@ -6851,7 +6849,7 @@ sparc_flat_function_prologue (file, size) fprintf (file, ", %s\n\tsub\t%s, %s, %s\n", t1_str, sp_str, t1_str, sp_str); if (dwarf2out_do_frame ()) - if (! (gmask & FRAME_POINTER_MASK)) + if (! (gmask & HARD_FRAME_POINTER_MASK)) dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, size); } } @@ -6900,7 +6898,7 @@ sparc_flat_function_epilogue (file, size) unsigned HOST_WIDE_INT reg_offset = current_frame_info.reg_offset; unsigned HOST_WIDE_INT size1; const char *const sp_str = reg_names[STACK_POINTER_REGNUM]; - const char *const fp_str = reg_names[FRAME_POINTER_REGNUM]; + const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM]; static const char *const t1_str = "%g1"; /* In the reload sequence, we don't need to fill the load delay @@ -6946,7 +6944,7 @@ sparc_flat_function_epilogue (file, size) /* We must restore the frame pointer and return address reg first because they are treated specially by the prologue output code. */ - if (current_frame_info.gmask & FRAME_POINTER_MASK) + if (current_frame_info.gmask & HARD_FRAME_POINTER_MASK) { fprintf (file, "\tld\t[%s+%d], %s\n", sp_str, (int) reg_offset, fp_str); @@ -6961,7 +6959,7 @@ sparc_flat_function_epilogue (file, size) /* Restore any remaining saved registers. */ sparc_flat_save_restore (file, sp_str, reg_offset, - current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), + current_frame_info.gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK), current_frame_info.fmask, "ld", "ldd", 0); diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 608b3938d72..7b793234b1d 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -894,9 +894,10 @@ if (TARGET_ARCH64 \ accessible. We still account for them to simplify register computations (eg: in CLASS_MAX_NREGS). There are also 4 fp condition code registers, so 32+32+32+4 == 100. - Register 100 is used as the integer condition code register. */ + Register 100 is used as the integer condition code register. + Register 101 is used as the soft frame pointer register. */ -#define FIRST_PSEUDO_REGISTER 101 +#define FIRST_PSEUDO_REGISTER 102 #define SPARC_FIRST_FP_REG 32 /* Additional V9 fp regs. */ @@ -962,7 +963,7 @@ if (TARGET_ARCH64 \ 0, 0, 0, 0, 0, 0, 0, 0, \ 0, 0, 0, 0, 0, 0, 0, 0, \ \ - 0, 0, 0, 0, 0} + 0, 0, 0, 0, 0, 1} /* 1 for registers not available across function calls. These must include the FIXED_REGISTERS and also any @@ -987,7 +988,7 @@ if (TARGET_ARCH64 \ 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, \ \ - 1, 1, 1, 1, 1} + 1, 1, 1, 1, 1, 1} /* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that they won't be allocated. */ @@ -1042,7 +1043,7 @@ do \ /* Let the compiler believe the frame pointer is still \ %fp, but output it as %i7. */ \ fixed_regs[31] = 1; \ - reg_names[FRAME_POINTER_REGNUM] = "%i7"; \ + reg_names[HARD_FRAME_POINTER_REGNUM] = "%i7"; \ /* Disable leaf functions */ \ memset (sparc_leaf_regs, 0, FIRST_PSEUDO_REGISTER); \ } \ @@ -1062,9 +1063,9 @@ while (0) #define HARD_REGNO_NREGS(REGNO, MODE) \ (TARGET_ARCH64 \ - ? ((REGNO) < 32 \ - ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \ - : (GET_MODE_SIZE (MODE) + 3) / 4) \ + ? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM \ + ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \ + : (GET_MODE_SIZE (MODE) + 3) / 4) \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) /* Due to the ARCH64 descrepancy above we must override this next @@ -1107,27 +1108,32 @@ extern int sparc_mode_class[]; /* Register to use for pushing function arguments. */ #define STACK_POINTER_REGNUM 14 +/* The stack bias (amount by which the hardware register is offset by). */ +#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0) + /* Actual top-of-stack address is 92/176 greater than the contents of the stack pointer register for !v9/v9. That is: - !v9: 64 bytes for the in and local registers, 4 bytes for structure return address, and 6*4 bytes for the 6 register parameters. - v9: 128 bytes for the in and local registers + 6*8 bytes for the integer parameter regs. */ -#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(0) - -/* The stack bias (amount by which the hardware register is offset by). */ -#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0) - -/* Is stack biased? */ -#define STACK_BIAS SPARC_STACK_BIAS +#define STACK_POINTER_OFFSET (FIRST_PARM_OFFSET(0) + SPARC_STACK_BIAS) /* Base register for access to local variables of the function. */ -#define FRAME_POINTER_REGNUM 30 - -#if 0 -/* Register that is used for the return address for the flat model. */ -#define RETURN_ADDR_REGNUM 15 -#endif +#define HARD_FRAME_POINTER_REGNUM 30 + +/* The soft frame pointer does not have the stack bias applied. */ +#define FRAME_POINTER_REGNUM 101 + +/* Given the stack bias, the stack pointer isn't actually aligned. */ +#define INIT_EXPANDERS \ + do { \ + if (cfun && cfun->emit->regno_pointer_align && SPARC_STACK_BIAS) \ + { \ + REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = BITS_PER_UNIT; \ + REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; \ + } \ + } while (0) /* Value should be nonzero if functions must have frame pointers. Zero means the frame pointer need not be set up (and parms @@ -1138,9 +1144,11 @@ extern int sparc_mode_class[]; Being a non-leaf function does not mean a frame pointer is needed in the flat window model. However, the debugger won't be able to backtrace through us with out it. */ -#define FRAME_POINTER_REQUIRED \ - (TARGET_FLAT ? (current_function_calls_alloca || current_function_varargs \ - || !leaf_function_p ()) \ +#define FRAME_POINTER_REQUIRED \ + (TARGET_FLAT \ + ? (current_function_calls_alloca \ + || current_function_varargs \ + || !leaf_function_p ()) \ : ! (leaf_function_p () && only_leaf_regs_used ())) /* C statement to store the difference between the frame pointer @@ -1275,10 +1283,16 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS, This is an initializer for a vector of HARD_REG_SET of length N_REG_CLASSES. */ -#define REG_CLASS_CONTENTS \ - {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {0xffff, 0, 0, 0}, \ - {-1, 0, 0, 0}, {0, -1, 0, 0}, {0, -1, -1, 0}, \ - {-1, -1, 0, 0}, {-1, -1, -1, 0}, {-1, -1, -1, 0x1f}} +#define REG_CLASS_CONTENTS \ + {{0, 0, 0, 0}, /* NO_REGS */ \ + {0, 0, 0, 0xf}, /* FPCC_REGS */ \ + {0xffff, 0, 0, 0}, /* I64_REGS */ \ + {-1, 0, 0, 0x20}, /* GENERAL_REGS */ \ + {0, -1, 0, 0}, /* FP_REGS */ \ + {0, -1, -1, 0}, /* EXTRA_FP_REGS */ \ + {-1, -1, 0, 0x20}, /* GENERAL_OR_FP_REGS */ \ + {-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \ + {-1, -1, -1, 0x3f}} /* ALL_REGS */ /* The same information, inverted: Return the class number of the smallest class containing @@ -1310,7 +1324,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER]; 88, 89, 90, 91, 92, 93, 94, 95, /* %f56-%f63 */ \ 32, 33, /* %f0,%f1 */ \ 96, 97, 98, 99, 100, /* %fcc0-3, %icc */ \ - 1, 4, 5, 6, 7, 0, 14, 30} + 1, 4, 5, 6, 7, 0, 14, 30, 101} /* This is the order in which to allocate registers for leaf functions. If all registers can fit in the "gi" registers, @@ -1331,7 +1345,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER]; 88, 89, 90, 91, 92, 93, 94, 95, \ 32, 33, \ 96, 97, 98, 99, 100, \ - 0, 14, 30, 31} + 0, 14, 30, 31, 101} #define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc () @@ -1535,7 +1549,7 @@ extern const char leaf_reg_remap[]; of the first local allocated. */ /* This allows space for one TFmode floating point value. */ #define STARTING_FRAME_OFFSET \ - (TARGET_ARCH64 ? (SPARC_STACK_BIAS - 16) \ + (TARGET_ARCH64 ? -16 \ : (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT))) /* If we generate an insn to push BYTES bytes, @@ -1548,13 +1562,11 @@ extern const char leaf_reg_remap[]; even if this function isn't going to use it. v9: This is 128 for the ins and locals. */ #define FIRST_PARM_OFFSET(FNDECL) \ - (TARGET_ARCH64 ? (SPARC_STACK_BIAS + 16 * UNITS_PER_WORD) \ - : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD)) + (TARGET_ARCH64 ? 16 * UNITS_PER_WORD : STRUCT_VALUE_OFFSET + UNITS_PER_WORD) /* Offset from the argument pointer register value to the CFA. This is different from FIRST_PARM_OFFSET because the register window comes between the CFA and the arguments. */ - #define ARG_POINTER_CFA_OFFSET(FNDECL) SPARC_STACK_BIAS /* When a parameter is passed in a register, stack space is still @@ -1568,6 +1580,17 @@ extern const char leaf_reg_remap[]; all 6 slots even for v9. */ #define REG_PARM_STACK_SPACE(DECL) (6 * UNITS_PER_WORD) +/* Definitions for register elimination. */ +/* ??? In TARGET_FLAT mode we needn't have a hard frame pointer. */ + +#define ELIMINABLE_REGS \ + {{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} + +#define CAN_ELIMINATE(FROM, TO) 1 + +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ + ((OFFSET) = SPARC_STACK_BIAS) + /* Keep the stack pointer constant throughout the function. This is both an optimization and a necessity: longjmp doesn't behave itself when the stack pointer moves within @@ -1996,9 +2019,12 @@ do { \ has been allocated, which happens in local-alloc.c. */ #define REGNO_OK_FOR_INDEX_P(REGNO) \ -((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32) -#define REGNO_OK_FOR_BASE_P(REGNO) \ -((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32) +((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32 \ + || (REGNO) == FRAME_POINTER_REGNUM \ + || reg_renumber[REGNO] == FRAME_POINTER_REGNUM) + +#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO) + #define REGNO_OK_FOR_FP_P(REGNO) \ (((unsigned) (REGNO) - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)) \ || ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32))) @@ -2092,11 +2118,13 @@ do { \ /* Nonzero if X is a hard reg that can be used as an index or if it is a pseudo reg. */ #define REG_OK_FOR_INDEX_P(X) \ - (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32)) + (REGNO (X) < 32 \ + || REGNO (X) == FRAME_POINTER_REGNUM \ + || REGNO (X) >= FIRST_PSEUDO_REGISTER) + /* Nonzero if X is a hard reg that can be used as a base reg or if it is a pseudo reg. */ -#define REG_OK_FOR_BASE_P(X) \ - (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32)) +#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_INDEX_P (X) /* 'T', 'U' are for aligned memory loads which aren't needed for arch64. */ @@ -2675,7 +2703,7 @@ do { \ "%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47", \ "%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55", \ "%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63", \ - "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc"} + "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc", "%sfp" } /* Define additional names for use in asm clobbers and asm declarations. */ -- 2.30.2