rs6000.c (102780) | rs6000.c (103445) |
---|---|
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 Free Software Foundation, Inc. 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 5 6This file is part of GNU CC. 7 8GNU CC is free software; you can redistribute it and/or modify --- 106 unchanged lines hidden (view full) --- 115int toc_initialized; 116char toc_label_name[10]; 117 118/* Alias set for saves and restores from the rs6000 stack. */ 119static int rs6000_sr_alias_set; 120 121static void rs6000_add_gc_roots PARAMS ((void)); 122static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT)); | 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 Free Software Foundation, Inc. 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 5 6This file is part of GNU CC. 7 8GNU CC is free software; you can redistribute it and/or modify --- 106 unchanged lines hidden (view full) --- 115int toc_initialized; 116char toc_label_name[10]; 117 118/* Alias set for saves and restores from the rs6000 stack. */ 119static int rs6000_sr_alias_set; 120 121static void rs6000_add_gc_roots PARAMS ((void)); 122static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT)); |
123static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx)); | |
124static void validate_condition_mode 125 PARAMS ((enum rtx_code, enum machine_mode)); 126static rtx rs6000_generate_compare PARAMS ((enum rtx_code)); 127static void rs6000_maybe_dead PARAMS ((rtx)); 128static void rs6000_emit_stack_tie PARAMS ((void)); 129static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx)); 130static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int)); 131static unsigned rs6000_hash_constant PARAMS ((rtx)); --- 4772 unchanged lines hidden (view full) --- 4904 else 4905 abort (); 4906 4907 def_builtin (d->mask, d->name, type, d->code); 4908 } 4909} 4910 4911 | 123static void validate_condition_mode 124 PARAMS ((enum rtx_code, enum machine_mode)); 125static rtx rs6000_generate_compare PARAMS ((enum rtx_code)); 126static void rs6000_maybe_dead PARAMS ((rtx)); 127static void rs6000_emit_stack_tie PARAMS ((void)); 128static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx)); 129static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int)); 130static unsigned rs6000_hash_constant PARAMS ((rtx)); --- 4772 unchanged lines hidden (view full) --- 4903 else 4904 abort (); 4905 4906 def_builtin (d->mask, d->name, type, d->code); 4907 } 4908} 4909 4910 |
4912/* Generate a memory reference for expand_block_move, copying volatile, 4913 and other bits from an original memory reference. */ 4914 4915static rtx 4916expand_block_move_mem (mode, addr, orig_mem) 4917 enum machine_mode mode; 4918 rtx addr; 4919 rtx orig_mem; 4920{ 4921 rtx mem = gen_rtx_MEM (mode, addr); 4922 4923 MEM_COPY_ATTRIBUTES (mem, orig_mem); 4924 return mem; 4925} 4926 | |
4927/* Expand a block move operation, and return 1 if successful. Return 0 4928 if we should let the compiler generate normal code. 4929 4930 operands[0] is the destination 4931 operands[1] is the source 4932 operands[2] is the length 4933 operands[3] is the alignment */ 4934 --- 6 unchanged lines hidden (view full) --- 4941 rtx orig_dest = operands[0]; 4942 rtx orig_src = operands[1]; 4943 rtx bytes_rtx = operands[2]; 4944 rtx align_rtx = operands[3]; 4945 int constp = (GET_CODE (bytes_rtx) == CONST_INT); 4946 int align; 4947 int bytes; 4948 int offset; | 4911/* Expand a block move operation, and return 1 if successful. Return 0 4912 if we should let the compiler generate normal code. 4913 4914 operands[0] is the destination 4915 operands[1] is the source 4916 operands[2] is the length 4917 operands[3] is the alignment */ 4918 --- 6 unchanged lines hidden (view full) --- 4925 rtx orig_dest = operands[0]; 4926 rtx orig_src = operands[1]; 4927 rtx bytes_rtx = operands[2]; 4928 rtx align_rtx = operands[3]; 4929 int constp = (GET_CODE (bytes_rtx) == CONST_INT); 4930 int align; 4931 int bytes; 4932 int offset; |
4949 int num_reg; 4950 int i; 4951 rtx src_reg; 4952 rtx dest_reg; 4953 rtx src_addr; 4954 rtx dest_addr; 4955 rtx tmp_reg; 4956 rtx stores[MAX_MOVE_REG]; | |
4957 int move_bytes; 4958 4959 /* If this is not a fixed size move, just call memcpy */ 4960 if (! constp) 4961 return 0; 4962 4963 /* If this is not a fixed size alignment, abort */ 4964 if (GET_CODE (align_rtx) != CONST_INT) --- 5 unchanged lines hidden (view full) --- 4970 if (bytes <= 0) 4971 return 1; 4972 4973 /* store_one_arg depends on expand_block_move to handle at least the size of 4974 reg_parm_stack_space. */ 4975 if (bytes > (TARGET_POWERPC64 ? 64 : 32)) 4976 return 0; 4977 | 4933 int move_bytes; 4934 4935 /* If this is not a fixed size move, just call memcpy */ 4936 if (! constp) 4937 return 0; 4938 4939 /* If this is not a fixed size alignment, abort */ 4940 if (GET_CODE (align_rtx) != CONST_INT) --- 5 unchanged lines hidden (view full) --- 4946 if (bytes <= 0) 4947 return 1; 4948 4949 /* store_one_arg depends on expand_block_move to handle at least the size of 4950 reg_parm_stack_space. */ 4951 if (bytes > (TARGET_POWERPC64 ? 64 : 32)) 4952 return 0; 4953 |
4978 /* Move the address into scratch registers. */ 4979 dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0)); 4980 src_reg = copy_addr_to_reg (XEXP (orig_src, 0)); 4981 | |
4982 if (TARGET_STRING) /* string instructions are available */ 4983 { | 4954 if (TARGET_STRING) /* string instructions are available */ 4955 { |
4984 for ( ; bytes > 0; bytes -= move_bytes) | 4956 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes) |
4985 { | 4957 { |
4958 union { 4959 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx)); 4960 rtx (*mov) PARAMS ((rtx, rtx)); 4961 } gen_func; 4962 enum machine_mode mode = BLKmode; 4963 rtx src, dest; 4964 |
|
4986 if (bytes > 24 /* move up to 32 bytes at a time */ 4987 && ! fixed_regs[5] 4988 && ! fixed_regs[6] 4989 && ! fixed_regs[7] 4990 && ! fixed_regs[8] 4991 && ! fixed_regs[9] 4992 && ! fixed_regs[10] 4993 && ! fixed_regs[11] 4994 && ! fixed_regs[12]) 4995 { 4996 move_bytes = (bytes > 32) ? 32 : bytes; | 4965 if (bytes > 24 /* move up to 32 bytes at a time */ 4966 && ! fixed_regs[5] 4967 && ! fixed_regs[6] 4968 && ! fixed_regs[7] 4969 && ! fixed_regs[8] 4970 && ! fixed_regs[9] 4971 && ! fixed_regs[10] 4972 && ! fixed_regs[11] 4973 && ! fixed_regs[12]) 4974 { 4975 move_bytes = (bytes > 32) ? 32 : bytes; |
4997 emit_insn (gen_movstrsi_8reg (expand_block_move_mem (BLKmode, 4998 dest_reg, 4999 orig_dest), 5000 expand_block_move_mem (BLKmode, 5001 src_reg, 5002 orig_src), 5003 GEN_INT ((move_bytes == 32) 5004 ? 0 : move_bytes), 5005 align_rtx)); | 4976 gen_func.movstrsi = gen_movstrsi_8reg; |
5006 } 5007 else if (bytes > 16 /* move up to 24 bytes at a time */ 5008 && ! fixed_regs[5] 5009 && ! fixed_regs[6] 5010 && ! fixed_regs[7] 5011 && ! fixed_regs[8] 5012 && ! fixed_regs[9] 5013 && ! fixed_regs[10]) 5014 { 5015 move_bytes = (bytes > 24) ? 24 : bytes; | 4977 } 4978 else if (bytes > 16 /* move up to 24 bytes at a time */ 4979 && ! fixed_regs[5] 4980 && ! fixed_regs[6] 4981 && ! fixed_regs[7] 4982 && ! fixed_regs[8] 4983 && ! fixed_regs[9] 4984 && ! fixed_regs[10]) 4985 { 4986 move_bytes = (bytes > 24) ? 24 : bytes; |
5016 emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode, 5017 dest_reg, 5018 orig_dest), 5019 expand_block_move_mem (BLKmode, 5020 src_reg, 5021 orig_src), 5022 GEN_INT (move_bytes), 5023 align_rtx)); | 4987 gen_func.movstrsi = gen_movstrsi_6reg; |
5024 } 5025 else if (bytes > 8 /* move up to 16 bytes at a time */ 5026 && ! fixed_regs[5] 5027 && ! fixed_regs[6] 5028 && ! fixed_regs[7] 5029 && ! fixed_regs[8]) 5030 { 5031 move_bytes = (bytes > 16) ? 16 : bytes; | 4988 } 4989 else if (bytes > 8 /* move up to 16 bytes at a time */ 4990 && ! fixed_regs[5] 4991 && ! fixed_regs[6] 4992 && ! fixed_regs[7] 4993 && ! fixed_regs[8]) 4994 { 4995 move_bytes = (bytes > 16) ? 16 : bytes; |
5032 emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode, 5033 dest_reg, 5034 orig_dest), 5035 expand_block_move_mem (BLKmode, 5036 src_reg, 5037 orig_src), 5038 GEN_INT (move_bytes), 5039 align_rtx)); | 4996 gen_func.movstrsi = gen_movstrsi_4reg; |
5040 } 5041 else if (bytes >= 8 && TARGET_POWERPC64 5042 /* 64-bit loads and stores require word-aligned 5043 displacements. */ 5044 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4))) 5045 { 5046 move_bytes = 8; | 4997 } 4998 else if (bytes >= 8 && TARGET_POWERPC64 4999 /* 64-bit loads and stores require word-aligned 5000 displacements. */ 5001 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4))) 5002 { 5003 move_bytes = 8; |
5047 tmp_reg = gen_reg_rtx (DImode); 5048 emit_move_insn (tmp_reg, 5049 expand_block_move_mem (DImode, 5050 src_reg, orig_src)); 5051 emit_move_insn (expand_block_move_mem (DImode, 5052 dest_reg, orig_dest), 5053 tmp_reg); | 5004 mode = DImode; 5005 gen_func.mov = gen_movdi; |
5054 } 5055 else if (bytes > 4 && !TARGET_POWERPC64) 5056 { /* move up to 8 bytes at a time */ 5057 move_bytes = (bytes > 8) ? 8 : bytes; | 5006 } 5007 else if (bytes > 4 && !TARGET_POWERPC64) 5008 { /* move up to 8 bytes at a time */ 5009 move_bytes = (bytes > 8) ? 8 : bytes; |
5058 emit_insn (gen_movstrsi_2reg (expand_block_move_mem (BLKmode, 5059 dest_reg, 5060 orig_dest), 5061 expand_block_move_mem (BLKmode, 5062 src_reg, 5063 orig_src), 5064 GEN_INT (move_bytes), 5065 align_rtx)); | 5010 gen_func.movstrsi = gen_movstrsi_2reg; |
5066 } 5067 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT)) 5068 { /* move 4 bytes */ 5069 move_bytes = 4; | 5011 } 5012 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT)) 5013 { /* move 4 bytes */ 5014 move_bytes = 4; |
5070 tmp_reg = gen_reg_rtx (SImode); 5071 emit_move_insn (tmp_reg, 5072 expand_block_move_mem (SImode, 5073 src_reg, orig_src)); 5074 emit_move_insn (expand_block_move_mem (SImode, 5075 dest_reg, orig_dest), 5076 tmp_reg); | 5015 mode = SImode; 5016 gen_func.mov = gen_movsi; |
5077 } 5078 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT)) 5079 { /* move 2 bytes */ 5080 move_bytes = 2; | 5017 } 5018 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT)) 5019 { /* move 2 bytes */ 5020 move_bytes = 2; |
5081 tmp_reg = gen_reg_rtx (HImode); 5082 emit_move_insn (tmp_reg, 5083 expand_block_move_mem (HImode, 5084 src_reg, orig_src)); 5085 emit_move_insn (expand_block_move_mem (HImode, 5086 dest_reg, orig_dest), 5087 tmp_reg); | 5021 mode = HImode; 5022 gen_func.mov = gen_movhi; |
5088 } 5089 else if (bytes == 1) /* move 1 byte */ 5090 { 5091 move_bytes = 1; | 5023 } 5024 else if (bytes == 1) /* move 1 byte */ 5025 { 5026 move_bytes = 1; |
5092 tmp_reg = gen_reg_rtx (QImode); 5093 emit_move_insn (tmp_reg, 5094 expand_block_move_mem (QImode, 5095 src_reg, orig_src)); 5096 emit_move_insn (expand_block_move_mem (QImode, 5097 dest_reg, orig_dest), 5098 tmp_reg); | 5027 mode = QImode; 5028 gen_func.mov = gen_movqi; |
5099 } 5100 else 5101 { /* move up to 4 bytes at a time */ 5102 move_bytes = (bytes > 4) ? 4 : bytes; | 5029 } 5030 else 5031 { /* move up to 4 bytes at a time */ 5032 move_bytes = (bytes > 4) ? 4 : bytes; |
5103 emit_insn (gen_movstrsi_1reg (expand_block_move_mem (BLKmode, 5104 dest_reg, 5105 orig_dest), 5106 expand_block_move_mem (BLKmode, 5107 src_reg, 5108 orig_src), 5109 GEN_INT (move_bytes), 5110 align_rtx)); | 5033 gen_func.movstrsi = gen_movstrsi_1reg; |
5111 } 5112 | 5034 } 5035 |
5113 if (bytes > move_bytes) | 5036 src = adjust_address (orig_src, mode, offset); 5037 dest = adjust_address (orig_dest, mode, offset); 5038 5039 if (mode == BLKmode) |
5114 { | 5040 { |
5115 if (! TARGET_POWERPC64) | 5041 /* Move the address into scratch registers. The movstrsi 5042 patterns require zero offset. */ 5043 if (!REG_P (XEXP (src, 0))) |
5116 { | 5044 { |
5117 emit_insn (gen_addsi3 (src_reg, src_reg, 5118 GEN_INT (move_bytes))); 5119 emit_insn (gen_addsi3 (dest_reg, dest_reg, 5120 GEN_INT (move_bytes))); | 5045 rtx src_reg = copy_addr_to_reg (XEXP (src, 0)); 5046 src = replace_equiv_address (src, src_reg); |
5121 } | 5047 } |
5122 else | 5048 set_mem_size (src, GEN_INT (move_bytes)); 5049 5050 if (!REG_P (XEXP (dest, 0))) |
5123 { | 5051 { |
5124 emit_insn (gen_adddi3 (src_reg, src_reg, 5125 GEN_INT (move_bytes))); 5126 emit_insn (gen_adddi3 (dest_reg, dest_reg, 5127 GEN_INT (move_bytes))); | 5052 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0)); 5053 dest = replace_equiv_address (dest, dest_reg); |
5128 } | 5054 } |
5055 set_mem_size (dest, GEN_INT (move_bytes)); 5056 5057 emit_insn ((*gen_func.movstrsi) (dest, src, 5058 GEN_INT (move_bytes & 31), 5059 align_rtx)); |
|
5129 } | 5060 } |
5061 else 5062 { 5063 rtx tmp_reg = gen_reg_rtx (mode); 5064 5065 emit_insn ((*gen_func.mov) (tmp_reg, src)); 5066 emit_insn ((*gen_func.mov) (dest, tmp_reg)); 5067 } |
|
5130 } 5131 } 5132 5133 else /* string instructions not available */ 5134 { | 5068 } 5069 } 5070 5071 else /* string instructions not available */ 5072 { |
5135 num_reg = offset = 0; 5136 for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes)) | 5073 rtx stores[MAX_MOVE_REG]; 5074 int num_reg = 0; 5075 int i; 5076 5077 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes) |
5137 { | 5078 { |
5138 /* Calculate the correct offset for src/dest */ 5139 if (offset == 0) 5140 { 5141 src_addr = src_reg; 5142 dest_addr = dest_reg; 5143 } 5144 else 5145 { 5146 src_addr = plus_constant (src_reg, offset); 5147 dest_addr = plus_constant (dest_reg, offset); 5148 } | 5079 rtx (*gen_mov_func) PARAMS ((rtx, rtx)); 5080 enum machine_mode mode; 5081 rtx src, dest, tmp_reg; |
5149 5150 /* Generate the appropriate load and store, saving the stores 5151 for later. */ 5152 if (bytes >= 8 && TARGET_POWERPC64 5153 /* 64-bit loads and stores require word-aligned 5154 displacements. */ 5155 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4))) 5156 { 5157 move_bytes = 8; | 5082 5083 /* Generate the appropriate load and store, saving the stores 5084 for later. */ 5085 if (bytes >= 8 && TARGET_POWERPC64 5086 /* 64-bit loads and stores require word-aligned 5087 displacements. */ 5088 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4))) 5089 { 5090 move_bytes = 8; |
5158 tmp_reg = gen_reg_rtx (DImode); 5159 emit_insn (gen_movdi (tmp_reg, 5160 expand_block_move_mem (DImode, 5161 src_addr, 5162 orig_src))); 5163 stores[num_reg++] = gen_movdi (expand_block_move_mem (DImode, 5164 dest_addr, 5165 orig_dest), 5166 tmp_reg); | 5091 mode = DImode; 5092 gen_mov_func = gen_movdi; |
5167 } 5168 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT)) 5169 { 5170 move_bytes = 4; | 5093 } 5094 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT)) 5095 { 5096 move_bytes = 4; |
5171 tmp_reg = gen_reg_rtx (SImode); 5172 emit_insn (gen_movsi (tmp_reg, 5173 expand_block_move_mem (SImode, 5174 src_addr, 5175 orig_src))); 5176 stores[num_reg++] = gen_movsi (expand_block_move_mem (SImode, 5177 dest_addr, 5178 orig_dest), 5179 tmp_reg); | 5097 mode = SImode; 5098 gen_mov_func = gen_movsi; |
5180 } 5181 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT)) 5182 { 5183 move_bytes = 2; | 5099 } 5100 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT)) 5101 { 5102 move_bytes = 2; |
5184 tmp_reg = gen_reg_rtx (HImode); 5185 emit_insn (gen_movhi (tmp_reg, 5186 expand_block_move_mem (HImode, 5187 src_addr, 5188 orig_src))); 5189 stores[num_reg++] = gen_movhi (expand_block_move_mem (HImode, 5190 dest_addr, 5191 orig_dest), 5192 tmp_reg); | 5103 mode = HImode; 5104 gen_mov_func = gen_movhi; |
5193 } 5194 else 5195 { 5196 move_bytes = 1; | 5105 } 5106 else 5107 { 5108 move_bytes = 1; |
5197 tmp_reg = gen_reg_rtx (QImode); 5198 emit_insn (gen_movqi (tmp_reg, 5199 expand_block_move_mem (QImode, 5200 src_addr, 5201 orig_src))); 5202 stores[num_reg++] = gen_movqi (expand_block_move_mem (QImode, 5203 dest_addr, 5204 orig_dest), 5205 tmp_reg); | 5109 mode = QImode; 5110 gen_mov_func = gen_movqi; |
5206 } 5207 | 5111 } 5112 |
5113 src = adjust_address (orig_src, mode, offset); 5114 dest = adjust_address (orig_dest, mode, offset); 5115 tmp_reg = gen_reg_rtx (mode); 5116 5117 emit_insn ((*gen_mov_func) (tmp_reg, src)); 5118 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg); 5119 |
|
5208 if (num_reg >= MAX_MOVE_REG) 5209 { 5210 for (i = 0; i < num_reg; i++) 5211 emit_insn (stores[i]); 5212 num_reg = 0; 5213 } 5214 } 5215 --- 2213 unchanged lines hidden (view full) --- 7429 for (first_reg = 13; first_reg <= 31; first_reg++) 7430 if (regs_ever_live[first_reg] 7431 && (! call_used_regs[first_reg] 7432 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM 7433 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1) 7434 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))) 7435 break; 7436 | 5120 if (num_reg >= MAX_MOVE_REG) 5121 { 5122 for (i = 0; i < num_reg; i++) 5123 emit_insn (stores[i]); 5124 num_reg = 0; 5125 } 5126 } 5127 --- 2213 unchanged lines hidden (view full) --- 7341 for (first_reg = 13; first_reg <= 31; first_reg++) 7342 if (regs_ever_live[first_reg] 7343 && (! call_used_regs[first_reg] 7344 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM 7345 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1) 7346 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))) 7347 break; 7348 |
7437 if (current_function_profile) 7438 { 7439 /* AIX must save/restore every register that contains a parameter 7440 before/after the .__mcount call plus an additional register 7441 for the static chain, if needed; use registers from 30 down to 22 7442 to do this. */ 7443 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN) 7444 { 7445 int last_parm_reg, profile_first_reg; 7446 7447 /* Figure out last used parameter register. The proper thing 7448 to do is to walk incoming args of the function. A function 7449 might have live parameter registers even if it has no 7450 incoming args. */ 7451 for (last_parm_reg = 10; 7452 last_parm_reg > 2 && ! regs_ever_live [last_parm_reg]; 7453 last_parm_reg--) 7454 ; 7455 7456 /* Calculate first reg for saving parameter registers 7457 and static chain. 7458 Skip reg 31 which may contain the frame pointer. */ 7459 profile_first_reg = (33 - last_parm_reg 7460 - (current_function_needs_context ? 1 : 0)); | |
7461#if TARGET_MACHO | 7349#if TARGET_MACHO |
7462 /* Need to skip another reg to account for R31 being PICBASE 7463 (when flag_pic is set) or R30 being used as the frame 7464 pointer (when flag_pic is not set). */ 7465 --profile_first_reg; 7466#endif 7467 /* Do not save frame pointer if no parameters needs to be saved. */ 7468 if (profile_first_reg == 31) 7469 profile_first_reg = 32; 7470 7471 if (first_reg > profile_first_reg) 7472 first_reg = profile_first_reg; 7473 } 7474 7475 /* SVR4 may need one register to preserve the static chain. */ 7476 else if (current_function_needs_context) 7477 { 7478 /* Skip reg 31 which may contain the frame pointer. */ 7479 if (first_reg > 30) 7480 first_reg = 30; 7481 } 7482 } 7483 7484#if TARGET_MACHO | |
7485 if (flag_pic && current_function_uses_pic_offset_table && 7486 (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)) 7487 return RS6000_PIC_OFFSET_TABLE_REGNUM; 7488#endif 7489 7490 return first_reg; 7491} 7492 --- 626 unchanged lines hidden (view full) --- 8119 8120void 8121rs6000_emit_load_toc_table (fromprolog) 8122 int fromprolog; 8123{ 8124 rtx dest; 8125 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 8126 | 7350 if (flag_pic && current_function_uses_pic_offset_table && 7351 (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)) 7352 return RS6000_PIC_OFFSET_TABLE_REGNUM; 7353#endif 7354 7355 return first_reg; 7356} 7357 --- 626 unchanged lines hidden (view full) --- 7984 7985void 7986rs6000_emit_load_toc_table (fromprolog) 7987 int fromprolog; 7988{ 7989 rtx dest; 7990 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 7991 |
8127 if (TARGET_ELF && DEFAULT_ABI != ABI_AIX) | 7992 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1) |
8128 { | 7993 { |
8129 if (DEFAULT_ABI == ABI_V4 && flag_pic == 1) | 7994 rtx temp = (fromprolog 7995 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) 7996 : gen_reg_rtx (Pmode)); 7997 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp))); 7998 rs6000_maybe_dead (emit_move_insn (dest, temp)); 7999 } 8000 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2) 8001 { 8002 char buf[30]; 8003 rtx tempLR = (fromprolog 8004 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) 8005 : gen_reg_rtx (Pmode)); 8006 rtx temp0 = (fromprolog 8007 ? gen_rtx_REG (Pmode, 0) 8008 : gen_reg_rtx (Pmode)); 8009 rtx symF; 8010 8011 /* possibly create the toc section */ 8012 if (! toc_initialized) |
8130 { | 8013 { |
8131 rtx temp = (fromprolog 8132 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) 8133 : gen_reg_rtx (Pmode)); 8134 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp))); 8135 rs6000_maybe_dead (emit_move_insn (dest, temp)); | 8014 toc_section (); 8015 function_section (current_function_decl); |
8136 } | 8016 } |
8137 else if (flag_pic == 2) 8138 { 8139 char buf[30]; 8140 rtx tempLR = (fromprolog 8141 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) 8142 : gen_reg_rtx (Pmode)); 8143 rtx temp0 = (fromprolog 8144 ? gen_rtx_REG (Pmode, 0) 8145 : gen_reg_rtx (Pmode)); 8146 rtx symF; | |
8147 | 8017 |
8148 /* possibly create the toc section */ 8149 if (! toc_initialized) 8150 { 8151 toc_section (); 8152 function_section (current_function_decl); 8153 } 8154 8155 if (fromprolog) 8156 { 8157 rtx symL; 8158 8159 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); 8160 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); | 8018 if (fromprolog) 8019 { 8020 rtx symL; |
8161 | 8021 |
8162 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); 8163 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); | 8022 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno); 8023 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); |
8164 | 8024 |
8165 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR, 8166 symF))); 8167 rs6000_maybe_dead (emit_move_insn (dest, tempLR)); 8168 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, 8169 symL, 8170 symF))); 8171 } 8172 else 8173 { 8174 rtx tocsym; 8175 static int reload_toc_labelno = 0; | 8025 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno); 8026 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); |
8176 | 8027 |
8177 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name); | 8028 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR, 8029 symF))); 8030 rs6000_maybe_dead (emit_move_insn (dest, tempLR)); 8031 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, 8032 symL, 8033 symF))); 8034 } 8035 else 8036 { 8037 rtx tocsym; 8038 static int reload_toc_labelno = 0; |
8178 | 8039 |
8179 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++); 8180 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); | 8040 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name); |
8181 | 8041 |
8182 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR, 8183 symF, 8184 tocsym))); 8185 rs6000_maybe_dead (emit_move_insn (dest, tempLR)); 8186 rs6000_maybe_dead (emit_move_insn (temp0, 8187 gen_rtx_MEM (Pmode, dest))); 8188 } 8189 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest))); | 8042 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++); 8043 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 8044 8045 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR, 8046 symF, 8047 tocsym))); 8048 rs6000_maybe_dead (emit_move_insn (dest, tempLR)); 8049 rs6000_maybe_dead (emit_move_insn (temp0, 8050 gen_rtx_MEM (Pmode, dest))); |
8190 } | 8051 } |
8191 else if (flag_pic == 0 && TARGET_MINIMAL_TOC) 8192 { 8193 /* This is for AIX code running in non-PIC ELF. */ 8194 char buf[30]; 8195 rtx realsym; 8196 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 8197 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 8198 8199 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym))); 8200 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym))); 8201 } 8202 else 8203 abort (); | 8052 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest))); |
8204 } | 8053 } |
8205 else | 8054 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC) |
8206 { | 8055 { |
8056 /* This is for AIX code running in non-PIC ELF32. */ 8057 char buf[30]; 8058 rtx realsym; 8059 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 8060 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 8061 8062 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym))); 8063 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym))); 8064 } 8065 else if (DEFAULT_ABI == ABI_AIX) 8066 { |
|
8207 if (TARGET_32BIT) | 8067 if (TARGET_32BIT) |
8208 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest))); | 8068 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest))); |
8209 else | 8069 else |
8210 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest))); | 8070 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest))); |
8211 } | 8071 } |
8072 else 8073 abort (); |
|
8212} 8213 8214int 8215get_TOC_alias_set () 8216{ 8217 static int set = -1; 8218 if (set == -1) 8219 set = new_alias_set (); --- 2013 unchanged lines hidden (view full) --- 10233 10234 For a 32-bit target, CONST_INT values are loaded and shifted 10235 entirely within `low' and can be stored in one TOC entry. */ 10236 10237 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode)) 10238 abort ();/* It would be easy to make this work, but it doesn't now. */ 10239 10240 if (POINTER_SIZE > GET_MODE_BITSIZE (mode)) | 8074} 8075 8076int 8077get_TOC_alias_set () 8078{ 8079 static int set = -1; 8080 if (set == -1) 8081 set = new_alias_set (); --- 2013 unchanged lines hidden (view full) --- 10095 10096 For a 32-bit target, CONST_INT values are loaded and shifted 10097 entirely within `low' and can be stored in one TOC entry. */ 10098 10099 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode)) 10100 abort ();/* It would be easy to make this work, but it doesn't now. */ 10101 10102 if (POINTER_SIZE > GET_MODE_BITSIZE (mode)) |
10241 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode), 10242 POINTER_SIZE, &low, &high, 0); | 10103 { 10104#if HOST_BITS_PER_WIDE_INT == 32 10105 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode), 10106 POINTER_SIZE, &low, &high, 0); 10107#else 10108 low |= high << 32; 10109 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode); 10110 high = (HOST_WIDE_INT) low >> 32; 10111 low &= 0xffffffff; 10112#endif 10113 } |
10243 10244 if (TARGET_64BIT) 10245 { 10246 if (TARGET_MINIMAL_TOC) 10247 fputs (DOUBLE_INT_ASM_OP, file); 10248 else 10249 fprintf (file, "\t.tc ID_%lx_%lx[TC],", 10250 (long) high & 0xffffffff, (long) low & 0xffffffff); --- 201 unchanged lines hidden (view full) --- 10452 else 10453 *p = '\0'; 10454} 10455 10456/* Emit profile function. */ 10457 10458void 10459output_profile_hook (labelno) | 10114 10115 if (TARGET_64BIT) 10116 { 10117 if (TARGET_MINIMAL_TOC) 10118 fputs (DOUBLE_INT_ASM_OP, file); 10119 else 10120 fprintf (file, "\t.tc ID_%lx_%lx[TC],", 10121 (long) high & 0xffffffff, (long) low & 0xffffffff); --- 201 unchanged lines hidden (view full) --- 10323 else 10324 *p = '\0'; 10325} 10326 10327/* Emit profile function. */ 10328 10329void 10330output_profile_hook (labelno) |
10460 int labelno; | 10331 int labelno ATTRIBUTE_UNUSED; |
10461{ 10462 if (DEFAULT_ABI == ABI_AIX) 10463 { | 10332{ 10333 if (DEFAULT_ABI == ABI_AIX) 10334 { |
10335#ifdef NO_PROFILE_COUNTERS 10336 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0); 10337#else |
|
10464 char buf[30]; 10465 const char *label_name; 10466 rtx fun; 10467 10468 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 10469 STRIP_NAME_ENCODING (label_name, ggc_strdup (buf)); 10470 fun = gen_rtx_SYMBOL_REF (Pmode, label_name); 10471 10472 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1, 10473 fun, Pmode); | 10338 char buf[30]; 10339 const char *label_name; 10340 rtx fun; 10341 10342 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 10343 STRIP_NAME_ENCODING (label_name, ggc_strdup (buf)); 10344 fun = gen_rtx_SYMBOL_REF (Pmode, label_name); 10345 10346 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1, 10347 fun, Pmode); |
10348#endif |
|
10474 } 10475 else if (DEFAULT_ABI == ABI_DARWIN) 10476 { 10477 const char *mcount_name = RS6000_MCOUNT; 10478 int caller_addr_regno = LINK_REGISTER_REGNUM; 10479 10480 /* Be conservative and always set this, at least for now. */ 10481 current_function_uses_pic_offset_table = 1; --- 17 unchanged lines hidden (view full) --- 10499/* Write function profiler code. */ 10500 10501void 10502output_function_profiler (file, labelno) 10503 FILE *file; 10504 int labelno; 10505{ 10506 char buf[100]; | 10349 } 10350 else if (DEFAULT_ABI == ABI_DARWIN) 10351 { 10352 const char *mcount_name = RS6000_MCOUNT; 10353 int caller_addr_regno = LINK_REGISTER_REGNUM; 10354 10355 /* Be conservative and always set this, at least for now. */ 10356 current_function_uses_pic_offset_table = 1; --- 17 unchanged lines hidden (view full) --- 10374/* Write function profiler code. */ 10375 10376void 10377output_function_profiler (file, labelno) 10378 FILE *file; 10379 int labelno; 10380{ 10381 char buf[100]; |
10382 int save_lr = 8; |
|
10507 10508 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 10509 switch (DEFAULT_ABI) 10510 { 10511 default: 10512 abort (); 10513 10514 case ABI_V4: | 10383 10384 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); 10385 switch (DEFAULT_ABI) 10386 { 10387 default: 10388 abort (); 10389 10390 case ABI_V4: |
10391 save_lr = 4; 10392 /* Fall through. */ 10393 |
|
10515 case ABI_AIX_NODESC: | 10394 case ABI_AIX_NODESC: |
10395 if (!TARGET_32BIT) 10396 { 10397 warning ("no profiling of 64-bit code for this ABI"); 10398 return; 10399 } |
|
10516 fprintf (file, "\tmflr %s\n", reg_names[0]); 10517 if (flag_pic == 1) 10518 { 10519 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); | 10400 fprintf (file, "\tmflr %s\n", reg_names[0]); 10401 if (flag_pic == 1) 10402 { 10403 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file); |
10520 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", 10521 reg_names[0], reg_names[1]); | 10404 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", 10405 reg_names[0], save_lr, reg_names[1]); |
10522 asm_fprintf (file, "\tmflr %s\n", reg_names[12]); 10523 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]); 10524 assemble_name (file, buf); 10525 asm_fprintf (file, "@got(%s)\n", reg_names[12]); 10526 } 10527 else if (flag_pic > 1) 10528 { | 10406 asm_fprintf (file, "\tmflr %s\n", reg_names[12]); 10407 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]); 10408 assemble_name (file, buf); 10409 asm_fprintf (file, "@got(%s)\n", reg_names[12]); 10410 } 10411 else if (flag_pic > 1) 10412 { |
10529 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", 10530 reg_names[0], reg_names[1]); | 10413 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", 10414 reg_names[0], save_lr, reg_names[1]); |
10531 /* Now, we need to get the address of the label. */ 10532 fputs ("\tbl 1f\n\t.long ", file); 10533 assemble_name (file, buf); 10534 fputs ("-.\n1:", file); 10535 asm_fprintf (file, "\tmflr %s\n", reg_names[11]); 10536 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n", 10537 reg_names[0], reg_names[11]); 10538 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", 10539 reg_names[0], reg_names[0], reg_names[11]); 10540 } 10541 else 10542 { 10543 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]); 10544 assemble_name (file, buf); 10545 fputs ("@ha\n", file); | 10415 /* Now, we need to get the address of the label. */ 10416 fputs ("\tbl 1f\n\t.long ", file); 10417 assemble_name (file, buf); 10418 fputs ("-.\n1:", file); 10419 asm_fprintf (file, "\tmflr %s\n", reg_names[11]); 10420 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n", 10421 reg_names[0], reg_names[11]); 10422 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n", 10423 reg_names[0], reg_names[0], reg_names[11]); 10424 } 10425 else 10426 { 10427 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]); 10428 assemble_name (file, buf); 10429 fputs ("@ha\n", file); |
10546 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n", 10547 reg_names[0], reg_names[1]); | 10430 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", 10431 reg_names[0], save_lr, reg_names[1]); |
10548 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]); 10549 assemble_name (file, buf); 10550 asm_fprintf (file, "@l(%s)\n", reg_names[12]); 10551 } 10552 | 10432 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]); 10433 assemble_name (file, buf); 10434 asm_fprintf (file, "@l(%s)\n", reg_names[12]); 10435 } 10436 |
10553 if (current_function_needs_context) 10554 asm_fprintf (file, "\tmr %s,%s\n", 10555 reg_names[30], reg_names[STATIC_CHAIN_REGNUM]); 10556 fprintf (file, "\tbl %s\n", RS6000_MCOUNT); 10557 if (current_function_needs_context) 10558 asm_fprintf (file, "\tmr %s,%s\n", 10559 reg_names[STATIC_CHAIN_REGNUM], reg_names[30]); | 10437 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC) 10438 { 10439 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n", 10440 reg_names[STATIC_CHAIN_REGNUM], 10441 12, reg_names[1]); 10442 fprintf (file, "\tbl %s\n", RS6000_MCOUNT); 10443 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n", 10444 reg_names[STATIC_CHAIN_REGNUM], 10445 12, reg_names[1]); 10446 } 10447 else 10448 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */ 10449 fprintf (file, "\tbl %s\n", RS6000_MCOUNT); |
10560 break; 10561 10562 case ABI_AIX: 10563 case ABI_DARWIN: 10564 /* Don't do anything, done in output_profile_hook (). */ 10565 break; | 10450 break; 10451 10452 case ABI_AIX: 10453 case ABI_DARWIN: 10454 /* Don't do anything, done in output_profile_hook (). */ 10455 break; |
10566 | |
10567 } 10568} 10569 10570/* Adjust the cost of a scheduling dependency. Return the new cost of 10571 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ 10572 10573static int 10574rs6000_adjust_cost (insn, link, dep_insn, cost) --- 962 unchanged lines hidden --- | 10456 } 10457} 10458 10459/* Adjust the cost of a scheduling dependency. Return the new cost of 10460 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */ 10461 10462static int 10463rs6000_adjust_cost (insn, link, dep_insn, cost) --- 962 unchanged lines hidden --- |