diff options
Diffstat (limited to 'gcc/config/ia64/ia64.c')
-rw-r--r-- | gcc/config/ia64/ia64.c | 85 |
1 files changed, 77 insertions, 8 deletions
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index e1e3dff8b59..7df747bf986 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -207,6 +207,11 @@ static int ia64_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); static bool ia64_function_ok_for_sibcall (tree, tree); static bool ia64_return_in_memory (const_tree, const_tree); +static rtx ia64_function_value (const_tree, const_tree, bool); +static rtx ia64_libcall_value (enum machine_mode, const_rtx); +static bool ia64_function_value_regno_p (const unsigned int); +static int ia64_register_move_cost (enum machine_mode, reg_class_t, + reg_class_t); static bool ia64_rtx_costs (rtx, int, int, int *, bool); static int ia64_unspec_may_trap_p (const_rtx, unsigned); static void fix_range (const char *); @@ -451,6 +456,8 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_ASM_GLOBALIZE_DECL_NAME #define TARGET_ASM_GLOBALIZE_DECL_NAME ia64_globalize_decl_name +#undef TARGET_REGISTER_MOVE_COST +#define TARGET_REGISTER_MOVE_COST ia64_register_move_cost #undef TARGET_RTX_COSTS #define TARGET_RTX_COSTS ia64_rtx_costs #undef TARGET_ADDRESS_COST @@ -482,6 +489,13 @@ static const struct attribute_spec ia64_attribute_table[] = #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true #endif +#undef TARGET_FUNCTION_VALUE +#define TARGET_FUNCTION_VALUE ia64_function_value +#undef TARGET_LIBCALL_VALUE +#define TARGET_LIBCALL_VALUE ia64_libcall_value +#undef TARGET_FUNCTION_VALUE_REGNO_P +#define TARGET_FUNCTION_VALUE_REGNO_P ia64_function_value_regno_p + #undef TARGET_STRUCT_VALUE_RTX #define TARGET_STRUCT_VALUE_RTX ia64_struct_value_rtx #undef TARGET_RETURN_IN_MEMORY @@ -496,8 +510,8 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg -#undef TARGET_UNWIND_EMIT -#define TARGET_UNWIND_EMIT process_for_unwind_directive +#undef TARGET_ASM_UNWIND_EMIT +#define TARGET_ASM_UNWIND_EMIT process_for_unwind_directive #undef TARGET_SCALAR_MODE_SUPPORTED_P #define TARGET_SCALAR_MODE_SUPPORTED_P ia64_scalar_mode_supported_p @@ -3413,6 +3427,29 @@ ia64_expand_prologue (void) finish_spill_pointers (); } +/* Output the textual info surrounding the prologue. */ + +void +ia64_start_function (FILE *file, const char *fnname, + tree decl ATTRIBUTE_UNUSED) +{ +#if VMS_DEBUGGING_INFO + if (vms_debug_main + && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0) + { + targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER); + ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname); + dwarf2out_vms_debug_main_pointer (); + vms_debug_main = 0; + } +#endif + + fputs ("\t.proc ", file); + assemble_name (file, fnname); + fputc ('\n', file); + ASM_OUTPUT_LABEL (file, fnname); +} + /* Called after register allocation to add any instructions needed for the epilogue. Using an epilogue insn is favored compared to putting all of the instructions in output_function_prologue(), since it allows the scheduler @@ -4637,13 +4674,20 @@ ia64_return_in_memory (const_tree valtype, const_tree fntype ATTRIBUTE_UNUSED) /* Return rtx for register that holds the function return value. */ -rtx -ia64_function_value (const_tree valtype, const_tree func) +static rtx +ia64_function_value (const_tree valtype, + const_tree fn_decl_or_type, + bool outgoing ATTRIBUTE_UNUSED) { enum machine_mode mode; enum machine_mode hfa_mode; int unsignedp; + const_tree func = fn_decl_or_type; + if (fn_decl_or_type + && !DECL_P (fn_decl_or_type)) + func = NULL; + mode = TYPE_MODE (valtype); hfa_mode = hfa_element_mode (valtype, 0); @@ -4721,6 +4765,28 @@ ia64_function_value (const_tree valtype, const_tree func) } } +/* Worker function for TARGET_LIBCALL_VALUE. */ + +static rtx +ia64_libcall_value (enum machine_mode mode, + const_rtx fun ATTRIBUTE_UNUSED) +{ + return gen_rtx_REG (mode, + (((GET_MODE_CLASS (mode) == MODE_FLOAT + || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT) + && (mode) != TFmode) + ? FR_RET_FIRST : GR_RET_FIRST)); +} + +/* Worker function for FUNCTION_VALUE_REGNO_P. */ + +static bool +ia64_function_value_regno_p (const unsigned int regno) +{ + return ((regno >= GR_RET_FIRST && regno <= GR_RET_LAST) + || (regno >= FR_RET_FIRST && regno <= FR_RET_LAST)); +} + /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL. We need to emit DTP-relative relocations. */ @@ -5140,10 +5206,13 @@ ia64_rtx_costs (rtx x, int code, int outer_code, int *total, /* Calculate the cost of moving data from a register in class FROM to one in class TO, using MODE. */ -int -ia64_register_move_cost (enum machine_mode mode, enum reg_class from, - enum reg_class to) +static int +ia64_register_move_cost (enum machine_mode mode, reg_class_t from_i, + reg_class_t to_i) { + enum reg_class from = (enum reg_class) from_i; + enum reg_class to = (enum reg_class) to_i; + /* ADDL_REGS is the same as GR_REGS for movement purposes. */ if (to == ADDL_REGS) to = GR_REGS; @@ -5540,7 +5609,7 @@ void ia64_init_expanders (void) static struct machine_function * ia64_init_machine_status (void) { - return GGC_CNEW (struct machine_function); + return ggc_alloc_cleared_machine_function (); } static enum attr_itanium_class ia64_safe_itanium_class (rtx); |