Deleted Added
full compact
rs6000.c (259268) rs6000.c (259583)
1/* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6
7 This file is part of GCC.
8

--- 14452 unchanged lines hidden (view full) ---

14461 }
14462
14463 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14464 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14465 treg, GEN_INT (-info->total_size));
14466 sp_offset = info->total_size;
14467 }
14468
1/* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6
7 This file is part of GCC.
8

--- 14452 unchanged lines hidden (view full) ---

14461 }
14462
14463 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14464 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14465 treg, GEN_INT (-info->total_size));
14466 sp_offset = info->total_size;
14467 }
14468
14469 /* Save AltiVec registers if needed. */
14470 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14471 {
14472 int i;
14473
14474 /* There should be a non inline version of this, for when we
14475 are saving lots of vector registers. */
14476 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14477 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14478 {
14479 rtx areg, savereg, mem;
14480 int offset;
14481
14482 offset = info->altivec_save_offset + sp_offset
14483 + 16 * (i - info->first_altivec_reg_save);
14484
14485 savereg = gen_rtx_REG (V4SImode, i);
14486
14487 areg = gen_rtx_REG (Pmode, 0);
14488 emit_move_insn (areg, GEN_INT (offset));
14489
14490 /* AltiVec addressing mode is [reg+reg]. */
14491 mem = gen_frame_mem (V4SImode,
14492 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
14493
14494 insn = emit_move_insn (mem, savereg);
14495
14496 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14497 areg, GEN_INT (offset));
14498 }
14499 }
14500
14501 /* VRSAVE is a bit vector representing which AltiVec registers
14502 are used. The OS uses this to determine which vector
14503 registers to save on a context switch. We need to save
14504 VRSAVE on the stack frame, add whatever AltiVec registers we
14505 used in this function, and do the corresponding magic in the
14506 epilogue. */
14507
14508 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14509 && info->vrsave_mask != 0)
14510 {
14511 rtx reg, mem, vrsave;
14512 int offset;
14513
14514 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14515 as frame_reg_rtx and r11 as the static chain pointer for
14516 nested functions. */
14517 reg = gen_rtx_REG (SImode, 0);
14518 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14519 if (TARGET_MACHO)
14520 emit_insn (gen_get_vrsave_internal (reg));
14521 else
14522 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
14523
14524 if (!WORLD_SAVE_P (info))
14525 {
14526 /* Save VRSAVE. */
14527 offset = info->vrsave_save_offset + sp_offset;
14528 mem = gen_frame_mem (SImode,
14529 gen_rtx_PLUS (Pmode, frame_reg_rtx,
14530 GEN_INT (offset)));
14531 insn = emit_move_insn (mem, reg);
14532 }
14533
14534 /* Include the registers in the mask. */
14535 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
14536
14537 insn = emit_insn (generate_set_vrsave (reg, info, 0));
14538 }
14539
14540 /* If we use the link register, get it into r0. */
14541 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14542 {
14543 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14544 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14545 RTX_FRAME_RELATED_P (insn) = 1;
14546 }
14547

--- 221 unchanged lines hidden (view full) ---

14769 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14770 NULL_RTX, NULL_RTX);
14771 }
14772
14773 /* Update stack and set back pointer unless this is V.4,
14774 for which it was done previously. */
14775 if (!WORLD_SAVE_P (info) && info->push_p
14776 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
14469 /* If we use the link register, get it into r0. */
14470 if (!WORLD_SAVE_P (info) && info->lr_save_p)
14471 {
14472 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14473 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14474 RTX_FRAME_RELATED_P (insn) = 1;
14475 }
14476

--- 221 unchanged lines hidden (view full) ---

14698 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14699 NULL_RTX, NULL_RTX);
14700 }
14701
14702 /* Update stack and set back pointer unless this is V.4,
14703 for which it was done previously. */
14704 if (!WORLD_SAVE_P (info) && info->push_p
14705 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
14777 rs6000_emit_allocate_stack (info->total_size, FALSE);
14706 {
14707 if (info->total_size < 32767)
14708 sp_offset = info->total_size;
14709 else
14710 frame_reg_rtx = frame_ptr_rtx;
14711 rs6000_emit_allocate_stack (info->total_size,
14712 (frame_reg_rtx != sp_reg_rtx
14713 && ((info->altivec_size != 0)
14714 || (info->vrsave_mask != 0)
14715 )));
14716 if (frame_reg_rtx != sp_reg_rtx)
14717 rs6000_emit_stack_tie ();
14718 }
14778
14779 /* Set frame pointer, if needed. */
14780 if (frame_pointer_needed)
14781 {
14782 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
14783 sp_reg_rtx);
14784 RTX_FRAME_RELATED_P (insn) = 1;
14785 }
14786
14719
14720 /* Set frame pointer, if needed. */
14721 if (frame_pointer_needed)
14722 {
14723 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
14724 sp_reg_rtx);
14725 RTX_FRAME_RELATED_P (insn) = 1;
14726 }
14727
14728 /* Save AltiVec registers if needed. Save here because the red zone does
14729 not include AltiVec registers. */
14730 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14731 {
14732 int i;
14733
14734 /* There should be a non inline version of this, for when we
14735 are saving lots of vector registers. */
14736 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14737 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14738 {
14739 rtx areg, savereg, mem;
14740 int offset;
14741
14742 offset = info->altivec_save_offset + sp_offset
14743 + 16 * (i - info->first_altivec_reg_save);
14744
14745 savereg = gen_rtx_REG (V4SImode, i);
14746
14747 areg = gen_rtx_REG (Pmode, 0);
14748 emit_move_insn (areg, GEN_INT (offset));
14749
14750 /* AltiVec addressing mode is [reg+reg]. */
14751 mem = gen_frame_mem (V4SImode,
14752 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
14753
14754 insn = emit_move_insn (mem, savereg);
14755
14756 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14757 areg, GEN_INT (offset));
14758 }
14759 }
14760
14761 /* VRSAVE is a bit vector representing which AltiVec registers
14762 are used. The OS uses this to determine which vector
14763 registers to save on a context switch. We need to save
14764 VRSAVE on the stack frame, add whatever AltiVec registers we
14765 used in this function, and do the corresponding magic in the
14766 epilogue. */
14767
14768 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
14769 && info->vrsave_mask != 0)
14770 {
14771 rtx reg, mem, vrsave;
14772 int offset;
14773
14774 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14775 as frame_reg_rtx and r11 as the static chain pointer for
14776 nested functions. */
14777 reg = gen_rtx_REG (SImode, 0);
14778 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
14779 if (TARGET_MACHO)
14780 emit_insn (gen_get_vrsave_internal (reg));
14781 else
14782 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
14783
14784 if (!WORLD_SAVE_P (info))
14785 {
14786 /* Save VRSAVE. */
14787 offset = info->vrsave_save_offset + sp_offset;
14788 mem = gen_frame_mem (SImode,
14789 gen_rtx_PLUS (Pmode, frame_reg_rtx,
14790 GEN_INT (offset)));
14791 insn = emit_move_insn (mem, reg);
14792 }
14793
14794 /* Include the registers in the mask. */
14795 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
14796
14797 insn = emit_insn (generate_set_vrsave (reg, info, 0));
14798 }
14799
14787 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
14788 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
14789 || (DEFAULT_ABI == ABI_V4
14790 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
14791 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
14792 {
14793 /* If emit_load_toc_table will use the link register, we need to save
14794 it. We use R12 for this purpose because emit_load_toc_table

--- 241 unchanged lines hidden (view full) ---

15036 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
15037 RTVEC_ELT (p, j++)
15038 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
15039 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15040
15041 return;
15042 }
15043
14800 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
14801 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
14802 || (DEFAULT_ABI == ABI_V4
14803 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
14804 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
14805 {
14806 /* If emit_load_toc_table will use the link register, we need to save
14807 it. We use R12 for this purpose because emit_load_toc_table

--- 241 unchanged lines hidden (view full) ---

15049 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
15050 RTVEC_ELT (p, j++)
15051 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
15052 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
15053
15054 return;
15055 }
15056
15044 /* If we have a frame pointer, a call to alloca, or a large stack
15045 frame, restore the old stack pointer using the backchain. Otherwise,
15046 we know what size to update it with. */
15047 if (use_backchain_to_restore_sp)
15048 {
15049 /* Under V.4, don't reset the stack pointer until after we're done
15050 loading the saved registers. */
15051 if (DEFAULT_ABI == ABI_V4)
15052 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
15057 /* Set sp_offset based on the stack push from the prologue. */
15058 if (info->total_size < 32767)
15059 sp_offset = info->total_size;
15053
15060
15054 emit_move_insn (frame_reg_rtx,
15055 gen_rtx_MEM (Pmode, sp_reg_rtx));
15056 }
15057 else if (info->push_p)
15058 {
15059 if (DEFAULT_ABI == ABI_V4
15060 || current_function_calls_eh_return)
15061 sp_offset = info->total_size;
15062 else
15063 {
15064 emit_insn (TARGET_32BIT
15065 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15066 GEN_INT (info->total_size))
15067 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15068 GEN_INT (info->total_size)));
15069 }
15070 }
15071
15072 /* Restore AltiVec registers if needed. */
15073 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
15074 {
15075 int i;
15076
15077 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
15078 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
15079 {

--- 23 unchanged lines hidden (view full) ---

15103 GEN_INT (info->vrsave_save_offset + sp_offset));
15104 mem = gen_frame_mem (SImode, addr);
15105 reg = gen_rtx_REG (SImode, 12);
15106 emit_move_insn (reg, mem);
15107
15108 emit_insn (generate_set_vrsave (reg, info, 1));
15109 }
15110
15061 /* Restore AltiVec registers if needed. */
15062 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
15063 {
15064 int i;
15065
15066 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
15067 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
15068 {

--- 23 unchanged lines hidden (view full) ---

15092 GEN_INT (info->vrsave_save_offset + sp_offset));
15093 mem = gen_frame_mem (SImode, addr);
15094 reg = gen_rtx_REG (SImode, 12);
15095 emit_move_insn (reg, mem);
15096
15097 emit_insn (generate_set_vrsave (reg, info, 1));
15098 }
15099
15100 sp_offset = 0;
15101
15102 /* If we have a frame pointer, a call to alloca, or a large stack
15103 frame, restore the old stack pointer using the backchain. Otherwise,
15104 we know what size to update it with. */
15105 if (use_backchain_to_restore_sp)
15106 {
15107 /* Under V.4, don't reset the stack pointer until after we're done
15108 loading the saved registers. */
15109 if (DEFAULT_ABI == ABI_V4)
15110 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
15111
15112 emit_move_insn (frame_reg_rtx,
15113 gen_rtx_MEM (Pmode, sp_reg_rtx));
15114 }
15115 else if (info->push_p)
15116 {
15117 if (DEFAULT_ABI == ABI_V4
15118 || current_function_calls_eh_return)
15119 sp_offset = info->total_size;
15120 else
15121 {
15122 emit_insn (TARGET_32BIT
15123 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15124 GEN_INT (info->total_size))
15125 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15126 GEN_INT (info->total_size)));
15127 }
15128 }
15129
15111 /* Get the old lr if we saved it. */
15112 if (info->lr_save_p)
15113 {
15114 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
15115 info->lr_save_offset + sp_offset);
15116
15117 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
15118 }

--- 4455 unchanged lines hidden ---
15130 /* Get the old lr if we saved it. */
15131 if (info->lr_save_p)
15132 {
15133 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
15134 info->lr_save_offset + sp_offset);
15135
15136 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
15137 }

--- 4455 unchanged lines hidden ---