Deleted Added
full compact
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 ---