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 --- |