GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
+ by the Free Software Foundation; either version 3, or (at your
option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT
License for more details.
You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING. If not, write to the
- Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
- MA 02110-1301, USA. */
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
const int dmul; /* cost of DFmode multiplication (and fmadd). */
const int sdiv; /* cost of SFmode division (fdivs). */
const int ddiv; /* cost of DFmode division (fdiv). */
+ const int cache_line_size; /* cache line size in bytes. */
+ const int l1_cache_size; /* size of l1 cache, in kilobytes. */
+ const int l2_cache_size; /* size of l2 cache, in kilobytes. */
+ const int simultaneous_prefetches; /* number of parallel prefetch
+ operations. */
};
const struct processor_costs *rs6000_cost;
COSTS_N_INSNS (1), /* dmul */
COSTS_N_INSNS (1), /* sdiv */
COSTS_N_INSNS (1), /* ddiv */
+ 32,
+ 0,
+ 0,
+ 0,
};
/* Instruction size costs on 64bit processors. */
COSTS_N_INSNS (1), /* dmul */
COSTS_N_INSNS (1), /* sdiv */
COSTS_N_INSNS (1), /* ddiv */
+ 128,
+ 0,
+ 0,
+ 0,
};
/* Instruction costs on RIOS1 processors. */
COSTS_N_INSNS (2), /* dmul */
COSTS_N_INSNS (19), /* sdiv */
COSTS_N_INSNS (19), /* ddiv */
+ 128,
+ 64, /* l1 cache */
+ 512, /* l2 cache */
+ 0, /* streams */
};
/* Instruction costs on RIOS2 processors. */
COSTS_N_INSNS (2), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (17), /* ddiv */
+ 256,
+ 256, /* l1 cache */
+ 1024, /* l2 cache */
+ 0, /* streams */
};
/* Instruction costs on RS64A processors. */
COSTS_N_INSNS (4), /* dmul */
COSTS_N_INSNS (31), /* sdiv */
COSTS_N_INSNS (31), /* ddiv */
+ 128,
+ 128, /* l1 cache */
+ 2048, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on MPCCORE processors. */
COSTS_N_INSNS (5), /* dmul */
COSTS_N_INSNS (10), /* sdiv */
COSTS_N_INSNS (17), /* ddiv */
+ 32,
+ 4, /* l1 cache */
+ 16, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC403 processors. */
COSTS_N_INSNS (11), /* dmul */
COSTS_N_INSNS (11), /* sdiv */
COSTS_N_INSNS (11), /* ddiv */
+ 32,
+ 4, /* l1 cache */
+ 16, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC405 processors. */
COSTS_N_INSNS (11), /* dmul */
COSTS_N_INSNS (11), /* sdiv */
COSTS_N_INSNS (11), /* ddiv */
+ 32,
+ 16, /* l1 cache */
+ 128, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC440 processors. */
COSTS_N_INSNS (5), /* dmul */
COSTS_N_INSNS (19), /* sdiv */
COSTS_N_INSNS (33), /* ddiv */
+ 32,
+ 32, /* l1 cache */
+ 256, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC601 processors. */
COSTS_N_INSNS (5), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (31), /* ddiv */
+ 32,
+ 32, /* l1 cache */
+ 256, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC603 processors. */
COSTS_N_INSNS (4), /* dmul */
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (33), /* ddiv */
+ 32,
+ 8, /* l1 cache */
+ 64, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC604 processors. */
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (32), /* ddiv */
+ 32,
+ 16, /* l1 cache */
+ 512, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC604e processors. */
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (32), /* ddiv */
+ 32,
+ 32, /* l1 cache */
+ 1024, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC620 processors. */
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (18), /* sdiv */
COSTS_N_INSNS (32), /* ddiv */
+ 128,
+ 32, /* l1 cache */
+ 1024, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC630 processors. */
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (21), /* ddiv */
+ 128,
+ 64, /* l1 cache */
+ 1024, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on Cell processor. */
COSTS_N_INSNS (10/2), /* dmul */
COSTS_N_INSNS (74/2), /* sdiv */
COSTS_N_INSNS (74/2), /* ddiv */
+ 128,
+ 32, /* l1 cache */
+ 512, /* l2 cache */
+ 6, /* streams */
};
/* Instruction costs on PPC750 and PPC7400 processors. */
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (31), /* ddiv */
+ 32,
+ 32, /* l1 cache */
+ 512, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC7450 processors. */
COSTS_N_INSNS (5), /* dmul */
COSTS_N_INSNS (21), /* sdiv */
COSTS_N_INSNS (35), /* ddiv */
+ 32,
+ 32, /* l1 cache */
+ 1024, /* l2 cache */
+ 1, /* streams */
};
/* Instruction costs on PPC8540 processors. */
COSTS_N_INSNS (4), /* dmul */
COSTS_N_INSNS (29), /* sdiv */
COSTS_N_INSNS (29), /* ddiv */
+ 32,
+ 32, /* l1 cache */
+ 256, /* l2 cache */
+ 1, /* prefetch streams /*/
};
/* Instruction costs on POWER4 and POWER5 processors. */
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (17), /* sdiv */
COSTS_N_INSNS (17), /* ddiv */
+ 128,
+ 32, /* l1 cache */
+ 1024, /* l2 cache */
+ 8, /* prefetch streams /*/
};
/* Instruction costs on POWER6 processors. */
COSTS_N_INSNS (3), /* dmul */
COSTS_N_INSNS (13), /* sdiv */
COSTS_N_INSNS (16), /* ddiv */
+ 128,
+ 64, /* l1 cache */
+ 2048, /* l2 cache */
+ 16, /* prefetch streams */
};
\f
static bool rs6000_function_ok_for_sibcall (tree, tree);
-static const char *rs6000_invalid_within_doloop (rtx);
+static const char *rs6000_invalid_within_doloop (const_rtx);
static rtx rs6000_generate_compare (enum rtx_code);
-static void rs6000_maybe_dead (rtx);
static void rs6000_emit_stack_tie (void);
static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
static rtx spe_synthesize_frame_save (rtx);
static int constant_pool_expr_1 (rtx, int *, int *);
static bool constant_pool_expr_p (rtx);
static bool legitimate_small_data_p (enum machine_mode, rtx);
-static bool legitimate_indexed_address_p (rtx, int);
static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
static struct machine_function * rs6000_init_machine_status (void);
static bool rs6000_assemble_integer (rtx, unsigned int, int);
static int rs6000_ra_ever_killed (void);
static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
-static bool rs6000_ms_bitfield_layout_p (tree);
+static bool rs6000_ms_bitfield_layout_p (const_tree);
static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
-static const char *rs6000_mangle_fundamental_type (tree);
+static const char *rs6000_mangle_type (const_tree);
extern const struct attribute_spec rs6000_attribute_table[];
static void rs6000_set_default_type_attributes (tree);
+static bool rs6000_reg_live_or_pic_offset_p (int);
static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
tree);
static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
-static bool rs6000_return_in_memory (tree, tree);
+static bool rs6000_return_in_memory (const_tree, const_tree);
static void rs6000_file_start (void);
#if TARGET_ELF
static int rs6000_elf_reloc_rw_mask (void);
static void rs6000_elf_encode_section_info (tree, rtx, int)
ATTRIBUTE_UNUSED;
#endif
-static bool rs6000_use_blocks_for_constant_p (enum machine_mode, rtx);
+static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
#if TARGET_XCOFF
static void rs6000_xcoff_asm_output_anchor (rtx);
static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
static tree rs6000_builtin_conversion (enum tree_code, tree);
static void def_builtin (int, const char *, tree, int);
+static bool rs6000_vector_alignment_reachable (const_tree, bool);
static void rs6000_init_builtins (void);
static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
static void is_altivec_return_reg (rtx, void *);
static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
int easy_vector_constant (rtx, enum machine_mode);
-static bool rs6000_is_opaque_type (tree);
+static bool rs6000_is_opaque_type (const_tree);
static rtx rs6000_dwarf_register_span (rtx);
static void rs6000_init_dwarf_reg_sizes_extra (tree);
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
HOST_WIDE_INT,
rtx[], int *);
static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
- tree, HOST_WIDE_INT,
- rtx[], int *);
-static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, tree, int, bool);
+ const_tree, HOST_WIDE_INT,
+ rtx[], int *);
+static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
static void setup_incoming_varargs (CUMULATIVE_ARGS *,
enum machine_mode, tree,
int *, int);
static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
- tree, bool);
+ const_tree, bool);
static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
-static const char *invalid_arg_for_unprototyped_fn (tree, tree, tree);
+static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
#if TARGET_MACHO
static void macho_branch_islands (void);
static int no_previous_def (tree function_name);
static tree rs6000_build_builtin_va_list (void);
static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
-static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
+static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
static bool rs6000_scalar_mode_supported_p (enum machine_mode);
static bool rs6000_vector_mode_supported_p (enum machine_mode);
static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
#undef TARGET_VECTORIZE_BUILTIN_CONVERSION
#define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
+#undef TARGET_VECTOR_ALIGNMENT_REACHABLE
+#define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
+
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS rs6000_init_builtins
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
-#undef TARGET_MANGLE_FUNDAMENTAL_TYPE
-#define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
+#undef TARGET_MANGLE_TYPE
+#define TARGET_MANGLE_TYPE rs6000_mangle_type
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
/* On rs6000, function arguments are promoted, as are function return
values. */
#undef TARGET_PROMOTE_FUNCTION_ARGS
-#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
+#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
#undef TARGET_PROMOTE_FUNCTION_RETURN
-#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
+#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
#undef TARGET_SPLIT_COMPLEX_ARG
-#define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
+#define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
#undef TARGET_MUST_PASS_IN_STACK
#define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
#undef TARGET_PASS_BY_REFERENCE
default:
gcc_unreachable ();
}
+
+ if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
+ set_param_value ("simultaneous-prefetches",
+ rs6000_cost->simultaneous_prefetches);
+ if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
+ set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
+ if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
+ set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
+ if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
+ set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
}
/* Implement targetm.vectorize.builtin_mask_for_load. */
}
}
+
+/* Return true iff, data reference of TYPE can reach vector alignment (16)
+ after applying N number of iterations. This routine does not determine
+ how may iterations are required to reach desired alignment. */
+
+static bool
+rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
+{
+ if (is_packed)
+ return false;
+
+ if (TARGET_32BIT)
+ {
+ if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
+ return true;
+
+ if (rs6000_alignment_flags == MASK_ALIGN_POWER)
+ return true;
+
+ return false;
+ }
+ else
+ {
+ if (TARGET_MACHO)
+ return false;
+
+ /* Assuming that all other types are naturally aligned. CHECKME! */
+ return true;
+ }
+}
+
/* Handle generic options of the form -mfoo=yes/no.
NAME is the option name.
VALUE is the option value.
putc ('\n', file);
}
+#ifdef HAVE_AS_GNU_ATTRIBUTE
+ if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
+ {
+ fprintf (file, "\t.gnu_attribute 4, %d\n",
+ (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
+ fprintf (file, "\t.gnu_attribute 8, %d\n",
+ (TARGET_ALTIVEC_ABI ? 2
+ : TARGET_SPE_ABI ? 3
+ : 1));
+ }
+#endif
+
if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
{
switch_to_section (toc_section);
return (offset < 0x10000) && (offset + extra < 0x10000);
}
-static bool
+bool
legitimate_indexed_address_p (rtx x, int strict)
{
rtx op0, op1;
first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
emit_move_insn (tmp1,
- gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
+ gen_rtx_REG (Pmode, LR_REGNO));
emit_move_insn (tmp2, mem);
emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
last = emit_move_insn (got, tmp3);
set_unique_reg_note (last, REG_EQUAL, gsym);
- REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
- REG_NOTES (first));
- REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
- REG_NOTES (last));
+ maybe_encapsulate_block (first, last, gsym);
}
}
}
&& (TARGET_POWERPC64 || mode != DImode)
&& legitimate_indexed_address_p (x, reg_ok_strict))
return 1;
+ if (GET_CODE (x) == PRE_MODIFY
+ && mode != TImode
+ && mode != TFmode
+ && mode != TDmode
+ && ((TARGET_HARD_FLOAT && TARGET_FPRS)
+ || TARGET_POWERPC64
+ || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
+ && (TARGET_POWERPC64 || mode != DImode)
+ && !ALTIVEC_VECTOR_MODE (mode)
+ && !SPE_VECTOR_MODE (mode)
+ /* Restrict addressing for DI because of our SUBREG hackery. */
+ && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
+ && TARGET_UPDATE
+ && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
+ && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
+ || legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict))
+ && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
+ return 1;
if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
return 1;
return 0;
case LO_SUM:
return true;
- /* Auto-increment cases are now treated generically in recog.c. */
+ case PRE_INC:
+ case PRE_DEC:
+ case PRE_MODIFY:
+ return TARGET_UPDATE;
default:
break;
if (TARGET_SPE)
{
global_regs[SPEFSCR_REGNO] = 1;
- fixed_regs[FIXED_SCRATCH]
- = call_used_regs[FIXED_SCRATCH]
- = call_really_used_regs[FIXED_SCRATCH] = 1;
+ /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
+ registers in prologues and epilogues. We no longer use r14
+ for FIXED_SCRATCH, but we're keeping r14 out of the allocation
+ pool for link-compatibility with older versions of GCC. Once
+ "old" code has died out, we can return r14 to the allocation
+ pool. */
+ fixed_regs[14]
+ = call_used_regs[14]
+ = call_really_used_regs[14] = 1;
}
if (! TARGET_ALTIVEC)
return dest;
case SImode:
- result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
+ result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
GEN_INT (INTVAL (source)
return;
}
- if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
+ if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
&& !gpc_reg_operand (operands[1], mode))
operands[1] = force_reg (mode, operands[1]);
if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
{
rtx newreg;
- newreg = (no_new_pseudos ? copy_rtx (operands[1])
+ newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
: gen_reg_rtx (mode));
emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
operands[1] = newreg;
&& GET_CODE (operands[1]) != HIGH
&& GET_CODE (operands[1]) != CONST_INT)
{
- rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
+ rtx target = (!can_create_pseudo_p ()
+ ? operands[0]
+ : gen_reg_rtx (mode));
/* If this is a function address on -mcall-aixdesc,
convert it to the address of the descriptor. */
memory always. The cast to unsigned makes -1 > 8. */
static bool
-rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
+rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
{
/* In the darwin64 abi, try to use registers for larger structs
if possible. */
/* Return true if TYPE must be passed on the stack and not in registers. */
static bool
-rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
+rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
{
if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
return must_pass_in_stack_var_size (mode, type);
argument slot. */
enum direction
-function_arg_padding (enum machine_mode mode, tree type)
+function_arg_padding (enum machine_mode mode, const_tree type)
{
#ifndef AGGREGATE_PADDING_FIXED
#define AGGREGATE_PADDING_FIXED 0
/* Recursive workhorse for the following. */
static void
-rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
+rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
HOST_WIDE_INT startbitpos, rtx rvec[],
int *k)
{
calling convention. */
static rtx
-rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, tree type,
+rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
int named, bool retval)
{
rtx rvec[FIRST_PSEUDO_REGISTER];
static bool
rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
- enum machine_mode mode, tree type,
+ enum machine_mode mode, const_tree type,
bool named ATTRIBUTE_UNUSED)
{
if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
CUMULATIVE_ARGS next_cum;
int reg_size = TARGET_32BIT ? 4 : 8;
rtx save_area = NULL_RTX, mem;
- int first_reg_offset, set;
+ int first_reg_offset;
+ alias_set_type set;
/* Skip the last named argument. */
next_cum = *cum;
/* Find the overflow area. */
t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
if (words != 0)
- t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t,
- build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
+ t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
+ size_int (words * UNITS_PER_WORD));
t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
/* Find the register save area. */
t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
if (cfun->machine->varargs_save_offset)
- t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
- build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
+ t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
+ size_int (cfun->machine->varargs_save_offset));
t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
{
regalign = 1;
u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
- size_int (n_reg - 1));
+ build_int_cst (TREE_TYPE (reg), n_reg - 1));
u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
}
/* _Decimal128 is passed in even/odd fpr pairs; the stored
t = sav;
if (sav_ofs)
- t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
+ t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
- u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
- u = build1 (CONVERT_EXPR, integer_type_node, u);
- u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
- t = build2 (PLUS_EXPR, ptr_type_node, t, u);
+ u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
+ build_int_cst (TREE_TYPE (reg), n_reg));
+ u = fold_convert (sizetype, u);
+ u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
+ t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
gimplify_and_add (t, pre_p);
t = ovf;
if (align != 1)
{
- t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
+ t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
+ t = fold_convert (sizetype, t);
t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
- build_int_cst (NULL_TREE, -align));
+ size_int (-align));
+ t = fold_convert (TREE_TYPE (ovf), t);
}
gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
gimplify_and_add (u, pre_p);
- t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
+ t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
gimplify_and_add (t, pre_p);
tree arg0, arg1, arg2;
enum machine_mode mode0, mode1, mode2;
rtx pat, op0, op1, op2;
- struct builtin_description *d;
+ const struct builtin_description *d;
size_t i;
*expandedp = false;
/* Handle DST variants. */
- d = (struct builtin_description *) bdesc_dst;
+ d = bdesc_dst;
for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
if (d->code == fcode)
{
static rtx
altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
{
- struct builtin_description *d;
- struct builtin_description_predicates *dp;
+ const struct builtin_description *d;
+ const struct builtin_description_predicates *dp;
size_t i;
enum insn_code icode;
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
}
/* Expand abs* operations. */
- d = (struct builtin_description *) bdesc_abs;
+ d = bdesc_abs;
for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
if (d->code == fcode)
return altivec_expand_abs_builtin (d->icode, exp, target);
/* Expand the AltiVec predicates. */
- dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
+ dp = bdesc_altivec_preds;
for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
if (dp->code == fcode)
return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
- struct builtin_description *d;
+ const struct builtin_description *d;
size_t i;
rtx ret;
bool success;
return rs6000_expand_binop_builtin (d->icode, exp, target);
/* Handle simple ternary operations. */
- d = (struct builtin_description *) bdesc_3arg;
+ d = bdesc_3arg;
for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
if (d->code == fcode)
return rs6000_expand_ternop_builtin (d->icode, exp, target);
static void
altivec_init_builtins (void)
{
- struct builtin_description *d;
- struct builtin_description_predicates *dp;
+ const struct builtin_description *d;
+ const struct builtin_description_predicates *dp;
size_t i;
tree ftype;
def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
/* Add the DST variants. */
- d = (struct builtin_description *) bdesc_dst;
+ d = bdesc_dst;
for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
/* Initialize the predicates. */
- dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
+ dp = bdesc_altivec_preds;
for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
{
enum machine_mode mode1;
}
/* Initialize the abs* operators. */
- d = (struct builtin_description *) bdesc_abs;
+ d = bdesc_abs;
for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
{
enum machine_mode mode0;
static void
rs6000_common_init_builtins (void)
{
- struct builtin_description *d;
+ const struct builtin_description *d;
size_t i;
tree v4sf_ftype_v4sf_v4sf_v16qi
V8HI_type_node, V8HI_type_node, NULL_TREE);
/* Add the simple ternary operators. */
- d = (struct builtin_description *) bdesc_3arg;
+ d = bdesc_3arg;
for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
{
enum machine_mode mode0, mode1, mode2, mode3;
clear_step = 16;
else if (TARGET_POWERPC64 && align >= 32)
clear_step = 8;
+ else if (TARGET_SPE && align >= 64)
+ clear_step = 8;
else
clear_step = 4;
clear_bytes = 16;
mode = V4SImode;
}
+ else if (bytes >= 8 && TARGET_SPE && align >= 64)
+ {
+ clear_bytes = 8;
+ mode = V2SImode;
+ }
else if (bytes >= 8 && TARGET_POWERPC64
- /* 64-bit loads and stores require word-aligned
- displacements. */
- && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
+ /* 64-bit loads and stores require word-aligned
+ displacements. */
+ && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
{
clear_bytes = 8;
mode = DImode;
mode = V4SImode;
gen_func.mov = gen_movv4si;
}
+ else if (TARGET_SPE && bytes >= 8 && align >= 64)
+ {
+ move_bytes = 8;
+ mode = V2SImode;
+ gen_func.mov = gen_movv2si;
+ }
else if (TARGET_STRING
&& bytes > 24 /* move up to 32 bytes at a time */
&& ! fixed_regs[5]
/* The second flow pass currently (June 1999) can't update
regs_ever_live without disturbing other parts of the compiler, so
update it here to make the prolog/epilogue code happy. */
- if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
- regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
+ if (!can_create_pseudo_p ()
+ && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
+ df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
current_function_uses_pic_offset_table = 1;
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
output_address (plus_constant (XEXP (XEXP (x, 0), 0),
UNITS_PER_WORD));
+ else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0),
+ UNITS_PER_WORD));
else
output_address (XEXP (adjust_address_nv (x, SImode,
UNITS_PER_WORD),
case 'T':
/* Print the symbolic name of a branch target register. */
- if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
- && REGNO (x) != COUNT_REGISTER_REGNUM))
+ if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
+ && REGNO (x) != CTR_REGNO))
output_operand_lossage ("invalid %%T value");
- else if (REGNO (x) == LINK_REGISTER_REGNUM)
+ else if (REGNO (x) == LR_REGNO)
fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
else
fputs ("ctr", file);
/* Print `u' if this has an auto-increment or auto-decrement. */
if (GET_CODE (x) == MEM
&& (GET_CODE (XEXP (x, 0)) == PRE_INC
- || GET_CODE (XEXP (x, 0)) == PRE_DEC))
+ || GET_CODE (XEXP (x, 0)) == PRE_DEC
+ || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
putc ('u', file);
return;
case 'X':
if (GET_CODE (x) == MEM
- && legitimate_indexed_address_p (XEXP (x, 0), 0))
+ && (legitimate_indexed_address_p (XEXP (x, 0), 0)
+ || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
+ && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
putc ('x', file);
return;
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
+ else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
else
output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
if (small_data_operand (x, GET_MODE (x)))
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
+ else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
+ output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
else
output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
if (small_data_operand (x, GET_MODE (x)))
else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
+ else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
+ output_address (XEXP (XEXP (x, 0), 1));
else
output_address (XEXP (x, 0));
}
eq_rtx = rs6000_emit_vector_compare (rev_code, op0, op1,
dest_mode);
- nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
+ nor_code = optab_handler (one_cmpl_optab, (int)dest_mode)->insn_code;
gcc_assert (nor_code != CODE_FOR_nothing);
emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
dest_mode);
- ior_code = ior_optab->handlers[(int)dest_mode].insn_code;
+ ior_code = optab_handler (ior_optab, (int)dest_mode)->insn_code;
gcc_assert (ior_code != CODE_FOR_nothing);
emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
if (dmode != dest_mode)
/* Find lowest numbered live register. */
for (first_reg = 13; first_reg <= 31; first_reg++)
- if (regs_ever_live[first_reg]
+ if (df_regs_ever_live_p (first_reg)
&& (! call_used_regs[first_reg]
|| (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
&& ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
/* Find lowest numbered live register. */
for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
- if (regs_ever_live[first_reg])
+ if (df_regs_ever_live_p (first_reg))
break;
return first_reg;
/* Find lowest numbered live register. */
for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
- if (regs_ever_live[i])
+ if (df_regs_ever_live_p (i))
break;
return i;
/* First, find out if we use _any_ altivec registers. */
for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
- if (regs_ever_live[i])
+ if (df_regs_ever_live_p (i))
mask |= ALTIVEC_REG_BIT (i);
if (mask == 0)
|| rs6000_ra_ever_killed ())
{
info_ptr->lr_save_p = 1;
- regs_ever_live[LINK_REGISTER_REGNUM] = 1;
+ df_set_regs_ever_live (LR_REGNO, true);
}
/* Determine if we need to save the condition code registers. */
- if (regs_ever_live[CR2_REGNO]
- || regs_ever_live[CR3_REGNO]
- || regs_ever_live[CR4_REGNO])
+ if (df_regs_ever_live_p (CR2_REGNO)
+ || df_regs_ever_live_p (CR3_REGNO)
+ || df_regs_ever_live_p (CR4_REGNO))
{
info_ptr->cr_save_p = 1;
if (DEFAULT_ABI == ABI_V4)
}
cfun->machine->ra_need_lr = 1;
- return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
+ return get_hard_reg_initial_val (Pmode, LR_REGNO);
}
/* Say whether a function is a candidate for sibcall handling or not.
}
}
if (DEFAULT_ABI == ABI_DARWIN
- || (*targetm.binds_local_p) (decl))
+ || ((*targetm.binds_local_p) (decl)
+ && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
{
tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
PowerPC uses the COUNT register for branch on table instructions. */
static const char *
-rs6000_invalid_within_doloop (rtx insn)
+rs6000_invalid_within_doloop (const_rtx insn)
{
if (CALL_P (insn))
return "Function call in the loop.";
push_topmost_sequence ();
top = get_insns ();
pop_topmost_sequence ();
- reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
+ reg = gen_rtx_REG (Pmode, LR_REGNO);
for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
{
if (!SIBLING_CALL_P (insn))
return 1;
}
- else if (find_regno_note (insn, REG_INC, LINK_REGISTER_REGNUM))
+ else if (find_regno_note (insn, REG_INC, LR_REGNO))
return 1;
else if (set_of (reg, insn) != NULL_RTX
&& !prologue_epilogue_contains (insn))
return 0;
}
\f
-/* Add a REG_MAYBE_DEAD note to the insn. */
-static void
-rs6000_maybe_dead (rtx insn)
-{
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
- const0_rtx,
- REG_NOTES (insn));
-}
-
/* Emit instructions needed to load the TOC register.
This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
a constant pool; or for SVR4 -fpic. */
void
rs6000_emit_load_toc_table (int fromprolog)
{
- rtx dest, insn;
+ rtx dest;
dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
tmp1 = gen_reg_rtx (Pmode);
tmp2 = gen_reg_rtx (Pmode);
}
- insn = emit_insn (gen_load_toc_v4_PIC_1 (lab));
- if (fromprolog)
- rs6000_maybe_dead (insn);
- insn = emit_move_insn (tmp1,
- gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
- if (fromprolog)
- rs6000_maybe_dead (insn);
- insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
- if (fromprolog)
- rs6000_maybe_dead (insn);
- insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
- if (fromprolog)
- rs6000_maybe_dead (insn);
+ emit_insn (gen_load_toc_v4_PIC_1 (lab));
+ emit_move_insn (tmp1,
+ gen_rtx_REG (Pmode, LR_REGNO));
+ emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
+ emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
}
else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
{
- insn = emit_insn (gen_load_toc_v4_pic_si ());
- if (fromprolog)
- rs6000_maybe_dead (insn);
- insn = emit_move_insn (dest,
- gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
- if (fromprolog)
- rs6000_maybe_dead (insn);
+ emit_insn (gen_load_toc_v4_pic_si ());
+ emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
}
else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
{
ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
- rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (symF)));
- rs6000_maybe_dead (emit_move_insn (dest,
- gen_rtx_REG (Pmode,
- LINK_REGISTER_REGNUM)));
- rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
- symL,
- symF)));
+ emit_insn (gen_load_toc_v4_PIC_1 (symF));
+ emit_move_insn (dest,
+ gen_rtx_REG (Pmode, LR_REGNO));
+ emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
}
else
{
tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
emit_move_insn (dest,
- gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
+ gen_rtx_REG (Pmode, LR_REGNO));
emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
}
- insn = emit_insn (gen_addsi3 (dest, temp0, dest));
- if (fromprolog)
- rs6000_maybe_dead (insn);
+ emit_insn (gen_addsi3 (dest, temp0, dest));
}
else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
{
ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
- insn = emit_insn (gen_elf_high (dest, realsym));
- if (fromprolog)
- rs6000_maybe_dead (insn);
- insn = emit_insn (gen_elf_low (dest, dest, realsym));
- if (fromprolog)
- rs6000_maybe_dead (insn);
+ emit_insn (gen_elf_high (dest, realsym));
+ emit_insn (gen_elf_low (dest, dest, realsym));
}
else
{
gcc_assert (DEFAULT_ABI == ABI_AIX);
if (TARGET_32BIT)
- insn = emit_insn (gen_load_toc_aix_si (dest));
+ emit_insn (gen_load_toc_aix_si (dest));
else
- insn = emit_insn (gen_load_toc_aix_di (dest));
- if (fromprolog)
- rs6000_maybe_dead (insn);
+ emit_insn (gen_load_toc_aix_di (dest));
}
}
emit_move_insn (tmp, operands[0]);
}
else
- emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
+ emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
}
-static GTY(()) int set = -1;
+static GTY(()) alias_set_type set = -1;
-int
+alias_set_type
get_TOC_alias_set (void)
{
if (set == -1)
rtx
create_TOC_reference (rtx symbol)
{
- if (no_new_pseudos)
- regs_ever_live[TOC_REGISTER] = 1;
+ if (!can_create_pseudo_p ())
+ df_set_regs_ever_live (TOC_REGISTER, true);
return gen_rtx_PLUS (Pmode,
gen_rtx_REG (Pmode, TOC_REGISTER),
gen_rtx_CONST (Pmode,
#define TARGET_FIX_AND_CONTINUE 0
#endif
+/* Determine whether the gp REG is really used. */
+
+static bool
+rs6000_reg_live_or_pic_offset_p (int reg)
+{
+ return ((df_regs_ever_live_p (reg)
+ && (!call_used_regs[reg]
+ || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
+ && TARGET_TOC && TARGET_MINIMAL_TOC)))
+ || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
+ && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
+ || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
+}
+
/* Emit function prologue as insns. */
void
if (info->lr_save_p)
{
insn = emit_move_insn (reg0,
- gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
+ gen_rtx_REG (Pmode, LR_REGNO));
RTX_FRAME_RELATED_P (insn) = 1;
}
j = 0;
RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
gen_rtx_REG (SImode,
- LINK_REGISTER_REGNUM));
+ LR_REGNO));
RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
gen_rtx_SYMBOL_REF (Pmode,
"*save_world"));
/* If we use the link register, get it into r0. */
if (!WORLD_SAVE_P (info) && info->lr_save_p)
{
+ rtx addr, reg, mem;
+
insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
- gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
+ gen_rtx_REG (Pmode, LR_REGNO));
RTX_FRAME_RELATED_P (insn) = 1;
+
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (info->lr_save_offset + sp_offset));
+ reg = gen_rtx_REG (Pmode, 0);
+ mem = gen_rtx_MEM (Pmode, addr);
+ /* This should not be of rs6000_sr_alias_set, because of
+ __builtin_return_address. */
+
+ insn = emit_move_insn (mem, reg);
+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ NULL_RTX, NULL_RTX);
}
/* If we need to save CR, put it into r12. */
{
int i;
for (i = 0; i < 64 - info->first_fp_reg_save; i++)
- if ((regs_ever_live[info->first_fp_reg_save+i]
+ if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
&& ! call_used_regs[info->first_fp_reg_save+i]))
emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
info->first_fp_reg_save + i,
RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
gen_rtx_REG (Pmode,
- LINK_REGISTER_REGNUM));
+ LR_REGNO));
sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
alloc_rname = ggc_strdup (rname);
rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
NULL_RTX, NULL_RTX);
}
+ else if (!WORLD_SAVE_P (info)
+ && TARGET_SPE_ABI
+ && info->spe_64bit_regs_used != 0
+ && info->first_gp_reg_save != 32)
+ {
+ int i;
+ rtx spe_save_area_ptr;
+ int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
+ && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
+ && !call_used_regs[STATIC_CHAIN_REGNUM]);
+
+ /* Determine whether we can address all of the registers that need
+ to be saved with an offset from the stack pointer that fits in
+ the small const field for SPE memory instructions. */
+ int spe_regs_addressable_via_sp
+ = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
+ + (32 - info->first_gp_reg_save - 1) * reg_size);
+ int spe_offset;
+
+ if (spe_regs_addressable_via_sp)
+ {
+ spe_save_area_ptr = sp_reg_rtx;
+ spe_offset = info->spe_gp_save_offset + sp_offset;
+ }
+ else
+ {
+ /* Make r11 point to the start of the SPE save area. We need
+ to be careful here if r11 is holding the static chain. If
+ it is, then temporarily save it in r0. We would use r0 as
+ our base register here, but using r0 as a base register in
+ loads and stores means something different from what we
+ would like. */
+ if (using_static_chain_p)
+ {
+ rtx r0 = gen_rtx_REG (Pmode, 0);
+
+ gcc_assert (info->first_gp_reg_save > 11);
+
+ emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
+ }
+
+ spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
+ emit_insn (gen_addsi3 (spe_save_area_ptr, sp_reg_rtx,
+ GEN_INT (info->spe_gp_save_offset + sp_offset)));
+
+ spe_offset = 0;
+ }
+
+ for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+ if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
+ {
+ rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
+ rtx offset, addr, mem;
+
+ /* We're doing all this to ensure that the offset fits into
+ the immediate offset of 'evstdd'. */
+ gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
+
+ offset = GEN_INT (reg_size * i + spe_offset);
+ addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
+ mem = gen_rtx_MEM (V2SImode, addr);
+
+ insn = emit_move_insn (mem, reg);
+
+ rs6000_frame_related (insn, spe_save_area_ptr,
+ info->spe_gp_save_offset
+ + sp_offset + reg_size * i,
+ offset, const0_rtx);
+ }
+
+ /* Move the static chain pointer back. */
+ if (using_static_chain_p && !spe_regs_addressable_via_sp)
+ emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
+ }
else if (!WORLD_SAVE_P (info))
{
int i;
for (i = 0; i < 32 - info->first_gp_reg_save; i++)
- if ((regs_ever_live[info->first_gp_reg_save + i]
- && (!call_used_regs[info->first_gp_reg_save + i]
- || (i + info->first_gp_reg_save
- == RS6000_PIC_OFFSET_TABLE_REGNUM
- && TARGET_TOC && TARGET_MINIMAL_TOC)))
- || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
- && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
- || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
- {
- rtx addr, reg, mem;
- reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
+ if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
+ {
+ rtx addr, reg, mem;
+ reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
- if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
- {
- int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
- rtx b;
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (info->gp_save_offset
+ + sp_offset
+ + reg_size * i));
+ mem = gen_frame_mem (reg_mode, addr);
- if (!SPE_CONST_OFFSET_OK (offset))
- {
- b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
- emit_move_insn (b, GEN_INT (offset));
- }
- else
- b = GEN_INT (offset);
-
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
- mem = gen_frame_mem (V2SImode, addr);
- insn = emit_move_insn (mem, reg);
-
- if (GET_CODE (b) == CONST_INT)
- rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
- NULL_RTX, NULL_RTX);
- else
- rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
- b, GEN_INT (offset));
- }
- else
- {
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
- GEN_INT (info->gp_save_offset
- + sp_offset
- + reg_size * i));
- mem = gen_frame_mem (reg_mode, addr);
-
- insn = emit_move_insn (mem, reg);
- rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
- NULL_RTX, NULL_RTX);
- }
- }
+ insn = emit_move_insn (mem, reg);
+ rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
+ NULL_RTX, NULL_RTX);
+ }
}
/* ??? There's no need to emit actual instructions here, but it's the
}
}
- /* Save lr if we used it. */
- if (!WORLD_SAVE_P (info) && info->lr_save_p)
- {
- rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
- GEN_INT (info->lr_save_offset + sp_offset));
- rtx reg = gen_rtx_REG (Pmode, 0);
- rtx mem = gen_rtx_MEM (Pmode, addr);
- /* This should not be of frame_alias_set, because of
- __builtin_return_address. */
-
- insn = emit_move_insn (mem, reg);
- rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
- NULL_RTX, NULL_RTX);
- }
-
/* Save CR if we use any that must be preserved. */
if (!WORLD_SAVE_P (info) && info->cr_save_p)
{
if (!WORLD_SAVE_P (info) && info->push_p
&& !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
{
- rs6000_emit_allocate_stack (info->total_size, FALSE);
+ if (info->total_size < 32767)
sp_offset = info->total_size;
+ else
+ frame_reg_rtx = frame_ptr_rtx;
+ rs6000_emit_allocate_stack (info->total_size,
+ (frame_reg_rtx != sp_reg_rtx
+ && ((info->altivec_size != 0)
+ || (info->vrsave_mask != 0)
+ )));
+ if (frame_reg_rtx != sp_reg_rtx)
+ rs6000_emit_stack_tie ();
}
/* Set frame pointer, if needed. */
if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
|| (DEFAULT_ABI == ABI_V4
&& (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
- && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
+ && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
{
/* If emit_load_toc_table will use the link register, we need to save
it. We use R12 for this purpose because emit_load_toc_table
&& EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
if (save_LR_around_toc_setup)
{
- rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
+ rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
insn = emit_move_insn (frame_ptr_rtx, lr);
- rs6000_maybe_dead (insn);
RTX_FRAME_RELATED_P (insn) = 1;
rs6000_emit_load_toc_table (TRUE);
insn = emit_move_insn (lr, frame_ptr_rtx);
- rs6000_maybe_dead (insn);
RTX_FRAME_RELATED_P (insn) = 1;
}
else
if (DEFAULT_ABI == ABI_DARWIN
&& flag_pic && current_function_uses_pic_offset_table)
{
- rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
+ rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
rtx src = machopic_function_base_sym ();
/* Save and restore LR locally around this call (in R0). */
if (!info->lr_save_p)
- rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode, 0), lr));
+ emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
- rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (src)));
+ emit_insn (gen_load_macho_picbase (src));
- insn = emit_move_insn (gen_rtx_REG (Pmode,
- RS6000_PIC_OFFSET_TABLE_REGNUM),
- lr);
- rs6000_maybe_dead (insn);
+ emit_move_insn (gen_rtx_REG (Pmode,
+ RS6000_PIC_OFFSET_TABLE_REGNUM),
+ lr);
if (!info->lr_save_p)
- rs6000_maybe_dead (emit_move_insn (lr, gen_rtx_REG (Pmode, 0)));
+ emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
}
#endif
}
RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
gen_rtx_REG (Pmode,
- LINK_REGISTER_REGNUM));
+ LR_REGNO));
RTVEC_ELT (p, j++)
= gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
/* The instruction pattern requires a clobber here;
}
/* Set sp_offset based on the stack push from the prologue. */
- if ((DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return)
- && info->total_size < 32767)
+ if (info->total_size < 32767)
sp_offset = info->total_size;
/* Restore AltiVec registers if needed. */
/* Set LR here to try to overlap restores below. */
if (info->lr_save_p)
- emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
+ emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
gen_rtx_REG (Pmode, 0));
/* Load exception handler data registers, if needed. */
}
emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
}
+ else if (TARGET_SPE_ABI
+ && info->spe_64bit_regs_used != 0
+ && info->first_gp_reg_save != 32)
+ {
+ rtx spe_save_area_ptr;
+ /* Determine whether we can address all of the registers that need
+ to be saved with an offset from the stack pointer that fits in
+ the small const field for SPE memory instructions. */
+ int spe_regs_addressable_via_sp
+ = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
+ + (32 - info->first_gp_reg_save - 1) * reg_size);
+ int spe_offset;
+
+ if (spe_regs_addressable_via_sp)
+ {
+ spe_save_area_ptr = frame_reg_rtx;
+ spe_offset = info->spe_gp_save_offset + sp_offset;
+ }
+ else
+ {
+ /* Make r11 point to the start of the SPE save area. We worried about
+ not clobbering it when we were saving registers in the prologue.
+ There's no need to worry here because the static chain is passed
+ anew to every function. */
+ spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
+
+ emit_insn (gen_addsi3 (spe_save_area_ptr, frame_reg_rtx,
+ GEN_INT (info->spe_gp_save_offset + sp_offset)));
+
+ spe_offset = 0;
+ }
+
+ for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+ if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
+ {
+ rtx offset, addr, mem;
+
+ /* We're doing all this to ensure that the immediate offset
+ fits into the immediate field of 'evldd'. */
+ gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
+
+ offset = GEN_INT (spe_offset + reg_size * i);
+ addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
+ mem = gen_rtx_MEM (V2SImode, addr);
+
+ emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
+ mem);
+ }
+ }
else
for (i = 0; i < 32 - info->first_gp_reg_save; i++)
- if ((regs_ever_live[info->first_gp_reg_save + i]
- && (!call_used_regs[info->first_gp_reg_save + i]
- || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
- && TARGET_TOC && TARGET_MINIMAL_TOC)))
- || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
- && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
- || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
+ if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
{
rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
GEN_INT (info->gp_save_offset
+ reg_size * i));
rtx mem = gen_frame_mem (reg_mode, addr);
- /* Restore 64-bit quantities for SPE. */
- if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
- {
- int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
- rtx b;
-
- if (!SPE_CONST_OFFSET_OK (offset))
- {
- b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
- emit_move_insn (b, GEN_INT (offset));
- }
- else
- b = GEN_INT (offset);
-
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
- mem = gen_frame_mem (V2SImode, addr);
- }
-
emit_move_insn (gen_rtx_REG (reg_mode,
info->first_gp_reg_save + i), mem);
}
/* Restore fpr's if we need to do it without calling a function. */
if (restoring_FPRs_inline)
for (i = 0; i < 64 - info->first_fp_reg_save; i++)
- if ((regs_ever_live[info->first_fp_reg_save+i]
+ if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
&& ! call_used_regs[info->first_fp_reg_save+i]))
{
rtx addr, mem;
if (using_mtcr_multiple)
{
for (i = 0; i < 8; i++)
- if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
+ if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
count++;
gcc_assert (count);
}
ndx = 0;
for (i = 0; i < 8; i++)
- if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
+ if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
{
rtvec r = rtvec_alloc (2);
RTVEC_ELT (r, 0) = r12_rtx;
}
else
for (i = 0; i < 8; i++)
- if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
+ if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
{
emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
CR0_REGNO+i),
/* This blockage is needed so that sched doesn't decide to move
the sp change before the register restores. */
rs6000_emit_stack_tie ();
- emit_move_insn (sp_reg_rtx, frame_reg_rtx);
+ if (TARGET_SPE_ABI
+ && info->spe_64bit_regs_used != 0
+ && info->first_gp_reg_save != 32)
+ emit_insn (gen_addsi3 (sp_reg_rtx, gen_rtx_REG (Pmode, 11),
+ GEN_INT (-(info->spe_gp_save_offset + sp_offset))));
+ else
+ emit_move_insn (sp_reg_rtx, frame_reg_rtx);
}
else if (sp_offset != 0)
emit_insn (TARGET_32BIT
RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
gen_rtx_REG (Pmode,
- LINK_REGISTER_REGNUM));
+ LR_REGNO));
/* If we have to restore more than two FP registers, branch to the
restore function. It will return to our caller. */
rtx insn = get_last_insn ();
while (insn
&& NOTE_P (insn)
- && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL)
+ && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
insn = PREV_INSN (insn);
if (insn
&& (LABEL_P (insn)
|| (NOTE_P (insn)
- && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
+ && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
fputs ("\tnop\n", file);
}
#endif
reload_completed = 1;
epilogue_completed = 1;
- no_new_pseudos = 1;
/* Mark the end of the (empty) prologue. */
emit_note (NOTE_INSN_PROLOGUE_END);
gen_rtx_USE (VOIDmode, const0_rtx),
gen_rtx_USE (VOIDmode,
gen_rtx_REG (SImode,
- LINK_REGISTER_REGNUM)),
+ LR_REGNO)),
gen_rtx_RETURN (VOIDmode))));
SIBLING_CALL_P (insn) = 1;
emit_barrier ();
reload_completed = 0;
epilogue_completed = 0;
- no_new_pseudos = 0;
}
\f
/* A quick summary of the various types of 'constant-pool tables'
else if (DEFAULT_ABI == ABI_DARWIN)
{
const char *mcount_name = RS6000_MCOUNT;
- int caller_addr_regno = LINK_REGISTER_REGNUM;
+ int caller_addr_regno = LR_REGNO;
/* Be conservative and always set this, at least for now. */
current_function_uses_pic_offset_table = 1;
if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
&& is_load_insn (next)
&& is_store_insn (insn)
- && DEP_KIND (dep) == REG_DEP_TRUE)
+ && DEP_TYPE (dep) == REG_DEP_TRUE)
/* Prevent load after store in the same group if it is a true
dependence. */
return true;
for (i = 0; i < issue_rate; i++)
{
- dep_link_t link;
+ sd_iterator_def sd_it;
+ dep_t dep;
rtx insn = group_insns[i];
if (!insn)
continue;
- FOR_EACH_DEP_LINK (link, INSN_FORW_DEPS (insn))
+ FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
{
- dep_t dep = DEP_LINK_DEP (link);
rtx next = DEP_CON (dep);
if (next == next_insn
elements; we must teach the compiler how to mangle them. */
static const char *
-rs6000_mangle_fundamental_type (tree type)
+rs6000_mangle_type (const_tree type)
{
+ type = TYPE_MAIN_VARIANT (type);
+
+ if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
+ && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
+ return NULL;
+
if (type == bool_char_type_node) return "U6__boolc";
if (type == bool_short_type_node) return "U6__bools";
if (type == pixel_type_node) return "u7__pixel";
}
static bool
-rs6000_ms_bitfield_layout_p (tree record_type)
+rs6000_ms_bitfield_layout_p (const_tree record_type)
{
return (TARGET_USE_MS_BITFIELD_LAYOUT &&
!lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
}
bool
-rs6000_elf_in_small_data_p (tree decl)
+rs6000_elf_in_small_data_p (const_tree decl)
{
if (rs6000_sdata == SDATA_NONE)
return false;
/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
static bool
-rs6000_use_blocks_for_constant_p (enum machine_mode mode, rtx x)
+rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
{
return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
}
if (no_previous_def (funname))
{
- int line_number = 0;
rtx label_rtx = gen_label_rtx ();
char *label_buf, temp_buf[256];
ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
CODE_LABEL_NUMBER (label_rtx));
label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
labelname = get_identifier (label_buf);
- for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
- if (insn)
- line_number = NOTE_LINE_NUMBER (insn);
- add_compiler_branch_island (labelname, funname, line_number);
+ add_compiler_branch_island (labelname, funname, insn_line (insn));
}
else
labelname = get_prev_label (funname);
/* Use a different reg for the intermediate value, as
it will be marked UNCHANGING. */
- reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
+ reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
Pmode, reg_temp);
offset =
*total += COSTS_N_INSNS (2);
return false;
+ case CTZ:
case FFS:
*total = COSTS_N_INSNS (4);
return false;
+ case POPCOUNT:
+ *total = COSTS_N_INSNS (6);
+ return false;
+
case NOT:
if (outer_code == AND || outer_code == IOR || outer_code == XOR)
{
/* FALLTHRU */
case AND:
+ case CLZ:
case IOR:
case XOR:
case ZERO_EXTRACT:
fp1, unless -msoft-float. */
rtx
-rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
+rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
{
enum machine_mode mode;
unsigned int regno;
/* Return true if TYPE is a SPE or AltiVec opaque type. */
static bool
-rs6000_is_opaque_type (tree type)
+rs6000_is_opaque_type (const_tree type)
{
return (type == opaque_V2SI_type_node
|| type == opaque_V2SF_type_node
return regno;
if (regno == MQ_REGNO)
return 100;
- if (regno == LINK_REGISTER_REGNUM)
+ if (regno == LR_REGNO)
return 108;
- if (regno == COUNT_REGISTER_REGNUM)
+ if (regno == CTR_REGNO)
return 109;
if (CR_REGNO_P (regno))
return regno - CR0_REGNO + 86;
/* Target hook for invalid_arg_for_unprototyped_fn. */
static const char *
-invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
+invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
{
return (!rs6000_darwin64_abi
&& typelist == 0