diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a654380521e..06d7826e1c1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2002-07-10 Aldy Hernandez + + * config/rs6000/rs6000.c (emit_frame_save): New. + (rs6000_frame_related): Replace reg2 before reg. + (rs6000_emit_prologue): Use emit_frame_save for saving gprs, fprs, + and eh_return registers. + 2002-07-10 Toon Moene Revert all patches for optimization of Complex .op. Real. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6fcf8909f72..a88b7f05330 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -140,6 +140,8 @@ static rtx rs6000_generate_compare PARAMS ((enum rtx_code)); static void rs6000_maybe_dead PARAMS ((rtx)); static void rs6000_emit_stack_tie PARAMS ((void)); static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx)); +static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode, + unsigned int, int, int)); static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int)); static unsigned rs6000_hash_constant PARAMS ((rtx)); static unsigned toc_hash_function PARAMS ((const void *)); @@ -8452,6 +8454,9 @@ rs6000_frame_related (insn, reg, val, reg2, rreg) real = copy_rtx (PATTERN (insn)); + if (reg2 != NULL_RTX) + real = replace_rtx (real, reg2, rreg); + real = replace_rtx (real, reg, gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM), @@ -8504,9 +8509,6 @@ rs6000_frame_related (insn, reg, val, reg2, rreg) else abort (); - if (reg2 != NULL_RTX) - real = replace_rtx (real, reg2, rreg); - RTX_FRAME_RELATED_P (insn) = 1; REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, real, @@ -8575,6 +8577,53 @@ generate_set_vrsave (reg, info, epiloguep) return insn; } +/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes. + Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */ + +static void +emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size) + rtx frame_reg; + rtx frame_ptr; + enum machine_mode mode; + unsigned int regno; + int offset; + int total_size; +{ + rtx reg, offset_rtx, insn, mem, addr, int_rtx; + rtx replacea, replaceb; + + int_rtx = GEN_INT (offset); + + /* Some cases that need register indexed addressing. */ + if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) + /* Add more cases here. */ + ) + { + /* Whomever calls us must make sure r11 is available in the + flow path of instructions in the prologue. */ + offset_rtx = gen_rtx_REG (Pmode, 11); + emit_move_insn (offset_rtx, int_rtx); + + replacea = offset_rtx; + replaceb = int_rtx; + } + else + { + offset_rtx = int_rtx; + replacea = NULL_RTX; + replaceb = NULL_RTX; + } + + reg = gen_rtx_REG (mode, regno); + addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx); + mem = gen_rtx_MEM (mode, addr); + set_mem_alias_set (mem, rs6000_sr_alias_set); + + insn = emit_move_insn (mem, reg); + + rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb); +} + /* Emit function prologue as insns. */ void @@ -8702,20 +8751,10 @@ rs6000_emit_prologue () for (i = 0; i < 64 - info->first_fp_reg_save; i++) if ((regs_ever_live[info->first_fp_reg_save+i] && ! call_used_regs[info->first_fp_reg_save+i])) - { - rtx addr, reg, mem; - reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i); - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->fp_save_offset - + sp_offset - + 8 * i)); - mem = gen_rtx_MEM (DFmode, addr); - set_mem_alias_set (mem, rs6000_sr_alias_set); - - insn = emit_move_insn (mem, reg); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, - NULL_RTX, NULL_RTX); - } + emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode, + info->first_fp_reg_save + i, + info->fp_save_offset + sp_offset + 8 * i, + info->total_size); } else if (info->first_fp_reg_save != 64) { @@ -8785,20 +8824,10 @@ rs6000_emit_prologue () || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1) || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))) - { - rtx addr, reg, mem; - reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->gp_save_offset - + sp_offset - + reg_size * i)); - mem = gen_rtx_MEM (reg_mode, addr); - set_mem_alias_set (mem, rs6000_sr_alias_set); - - insn = emit_move_insn (mem, reg); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, - NULL_RTX, NULL_RTX); - } + emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, + info->first_gp_reg_save + i, + info->gp_save_offset + sp_offset + reg_size * i, + info->total_size); } /* ??? There's no need to emit actual instructions here, but it's the @@ -8809,22 +8838,14 @@ rs6000_emit_prologue () for (i = 0; ; ++i) { - rtx addr, reg, mem; - regno = EH_RETURN_DATA_REGNO (i); if (regno == INVALID_REGNUM) break; - reg = gen_rtx_REG (reg_mode, regno); - addr = plus_constant (frame_reg_rtx, - info->ehrd_offset + sp_offset - + reg_size * (int) i); - mem = gen_rtx_MEM (reg_mode, addr); - set_mem_alias_set (mem, rs6000_sr_alias_set); - - insn = emit_move_insn (mem, reg); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, - NULL_RTX, NULL_RTX); + emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno, + info->ehrd_offset + sp_offset + + reg_size * (int) i, + info->total_size); } }