From a3ed3761ca3501faa64e92e7e38d32fdb146a0ff Mon Sep 17 00:00:00 2001 From: bstarynk Date: Wed, 12 Oct 2011 21:35:19 +0000 Subject: 2011-10-12 Basile Starynkevitch MELT branch merged with trunk rev 179863 using svnmerge. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@179867 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/config/arm/arm-c.c | 38 +++---- gcc/config/arm/arm.c | 242 +++++++++++++++++++---------------------- gcc/config/arm/arm.h | 15 +++ gcc/config/avr/avr-protos.h | 4 +- gcc/config/avr/avr.c | 260 ++++++++++++++++++++++++++++++++++++++------ gcc/config/avr/avr.h | 20 +--- gcc/config/avr/avr.md | 89 ++++++--------- gcc/config/avr/libgcc.S | 28 +++-- gcc/config/cris/cris.c | 30 +++++ gcc/config/cris/cris.h | 16 --- gcc/config/darwin.c | 13 ++- gcc/config/i386/i386.c | 13 ++- gcc/config/i386/i386.md | 6 +- gcc/config/i386/sse.md | 2 +- gcc/config/ia64/ia64.c | 15 +-- gcc/config/pa/pa.c | 21 ++-- gcc/config/rs6000/rs6000.c | 10 +- gcc/config/sparc/sparc.c | 2 +- gcc/config/sparc/sparc.md | 20 ++-- gcc/config/vms/vms.c | 7 +- 20 files changed, 517 insertions(+), 334 deletions(-) (limited to 'gcc/config') diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index f9ad1c9e13e..cd4cefbc330 100644 --- a/gcc/config/arm/arm-c.c +++ b/gcc/config/arm/arm-c.c @@ -1,20 +1,20 @@ -/* Copyright (C) 2007, 2010 Free Software Foundation, Inc. +/* Copyright (C) 2007, 2010, 2011 Free Software Foundation, Inc. -This file is part of GCC. + This file is part of GCC. -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 3, or (at your option) any later -version. + 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 3, or (at your option) any later + version. -GCC is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. -You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING3. If not see -. */ + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ #include "config.h" #include "system.h" @@ -25,21 +25,21 @@ along with GCC; see the file COPYING3. If not see #include "output.h" #include "c-family/c-common.h" - /* Output C specific EABI object attributes. These can not be done in arm.c because they require information from the C frontend. */ -static void arm_output_c_attributes(void) +static void +arm_output_c_attributes (void) { - /* Tag_ABI_PCS_wchar_t. */ - asm_fprintf (asm_out_file, "\t.eabi_attribute 18, %d\n", - (int)(TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT)); + EMIT_EABI_ATTRIBUTE (Tag_ABI_PCS_wchar_t, 18, + (int)(TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT)); } /* Setup so that common code calls arm_output_c_attributes. */ -void arm_lang_object_attributes_init(void) +void +arm_lang_object_attributes_init (void) { arm_lang_output_object_attributes_hook = arm_output_c_attributes; } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 2feac6f45e1..ad733dad1d0 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -1062,12 +1062,12 @@ arm_set_fixed_optab_libfunc (optab optable, enum machine_mode mode, int num_suffix) { char buffer[50]; - + if (num_suffix == 0) sprintf (buffer, "__gnu_%s%s", funcname, modename); else sprintf (buffer, "__gnu_%s%s%d", funcname, modename, num_suffix); - + set_optab_libfunc (optable, mode, buffer); } @@ -1078,13 +1078,13 @@ arm_set_fixed_conv_libfunc (convert_optab optable, enum machine_mode to, { char buffer[50]; const char *maybe_suffix_2 = ""; - + /* Follow the logic for selecting a "2" suffix in fixed-bit.h. */ if (ALL_FIXED_POINT_MODE_P (from) && ALL_FIXED_POINT_MODE_P (to) && UNSIGNED_FIXED_POINT_MODE_P (from) == UNSIGNED_FIXED_POINT_MODE_P (to) && ALL_FRACT_MODE_P (from) == ALL_FRACT_MODE_P (to)) maybe_suffix_2 = "2"; - + sprintf (buffer, "__gnu_%s%s%s%s", funcname, fromname, toname, maybe_suffix_2); @@ -1210,11 +1210,11 @@ arm_init_libfuncs (void) (arm_fp16_format == ARM_FP16_FORMAT_IEEE ? "__gnu_f2h_ieee" : "__gnu_f2h_alternative")); - set_conv_libfunc (sext_optab, SFmode, HFmode, + set_conv_libfunc (sext_optab, SFmode, HFmode, (arm_fp16_format == ARM_FP16_FORMAT_IEEE ? "__gnu_h2f_ieee" : "__gnu_h2f_alternative")); - + /* Arithmetic. */ set_optab_libfunc (add_optab, HFmode, NULL); set_optab_libfunc (sdiv_optab, HFmode, NULL); @@ -1380,14 +1380,14 @@ arm_build_builtin_va_list (void) { tree va_list_name; tree ap_field; - + if (!TARGET_AAPCS_BASED) return std_build_builtin_va_list (); /* AAPCS \S 7.1.4 requires that va_list be a typedef for a type defined as: - struct __va_list + struct __va_list { void *__ap; }; @@ -1411,7 +1411,7 @@ arm_build_builtin_va_list (void) TYPE_STUB_DECL (va_list_type) = va_list_name; /* Create the __ap field. */ ap_field = build_decl (BUILTINS_LOCATION, - FIELD_DECL, + FIELD_DECL, get_identifier ("__ap"), ptr_type_node); DECL_ARTIFICIAL (ap_field) = 1; @@ -1437,7 +1437,7 @@ arm_extract_valist_ptr (tree valist) if (TARGET_AAPCS_BASED) { tree ap_field = TYPE_FIELDS (TREE_TYPE (valist)); - valist = build3 (COMPONENT_REF, TREE_TYPE (ap_field), + valist = build3 (COMPONENT_REF, TREE_TYPE (ap_field), valist, ap_field, NULL_TREE); } @@ -1454,7 +1454,7 @@ arm_expand_builtin_va_start (tree valist, rtx nextarg) /* Implement TARGET_GIMPLIFY_VA_ARG_EXPR. */ static tree -arm_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, +arm_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, gimple_seq *post_p) { valist = arm_extract_valist_ptr (valist); @@ -2312,7 +2312,7 @@ use_return_insn (int iscond, rtx sibling) if (saved_int_regs != 0 && saved_int_regs != (1 << LR_REGNUM)) return 0; - if (flag_pic + if (flag_pic && arm_pic_register != INVALID_REGNUM && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM)) return 0; @@ -2368,7 +2368,7 @@ const_ok_for_arm (HOST_WIDE_INT i) /* Get the number of trailing zeros. */ lowbit = ffs((int) i) - 1; - + /* Only even shifts are allowed in ARM mode so round down to the nearest even number. */ if (TARGET_ARM) @@ -2632,10 +2632,10 @@ optimal_immediate_sequence_1 (enum rtx_code code, unsigned HOST_WIDE_INT val, /* Try and find a way of doing the job in either two or three instructions. - + In ARM mode we can use 8-bit constants, rotated to any 2-bit aligned location. We start at position I. This may be the MSB, or - optimial_immediate_sequence may have positioned it at the largest block + optimial_immediate_sequence may have positioned it at the largest block of zeros that are aligned on a 2-bit boundary. We then fill up the temps, wrapping around to the top of the word when we drop off the bottom. In the worst case this code should produce no more than four insns. @@ -2684,11 +2684,11 @@ optimal_immediate_sequence_1 (enum rtx_code code, unsigned HOST_WIDE_INT val, /* Next, see if we can do a better job with a thumb2 replicated constant. - + We do it this way around to catch the cases like 0x01F001E0 where two 8-bit immediates would work, but a replicated constant would make it worse. - + TODO: 16-bit constants that don't clear all the bits, but still win. TODO: Arithmetic splitting for set/add/sub, rather than bitwise. */ if (TARGET_THUMB2) @@ -2716,7 +2716,7 @@ optimal_immediate_sequence_1 (enum rtx_code code, unsigned HOST_WIDE_INT val, || (matching_bytes == 2 && const_ok_for_op (remainder & ~tmp2, code)))) { - /* At least 3 of the bytes match, and the fourth has at + /* At least 3 of the bytes match, and the fourth has at least as many bits set, or two of the bytes match and it will only require one more insn to finish. */ result = tmp2; @@ -3629,7 +3629,7 @@ arm_libcall_uses_aapcs_base (const_rtx libcall) convert_optab_libfunc (sfloat_optab, SFmode, DImode)); add_libcall (libcall_htab, convert_optab_libfunc (sfloat_optab, DFmode, DImode)); - + add_libcall (libcall_htab, convert_optab_libfunc (ufloat_optab, SFmode, SImode)); add_libcall (libcall_htab, @@ -3949,7 +3949,7 @@ arm_get_pcs_model (const_tree type, const_tree decl) (no argument is ever a candidate for a co-processor register). */ bool base_rules = stdarg_p (type); - + if (user_convention) { if (user_pcs > ARM_PCS_AAPCS_LOCAL) @@ -3984,7 +3984,7 @@ arm_get_pcs_model (const_tree type, const_tree decl) static void aapcs_vfp_cum_init (CUMULATIVE_ARGS *pcum ATTRIBUTE_UNUSED, const_tree fntype ATTRIBUTE_UNUSED, - rtx libcall ATTRIBUTE_UNUSED, + rtx libcall ATTRIBUTE_UNUSED, const_tree fndecl ATTRIBUTE_UNUSED) { /* Record the unallocated VFP registers. */ @@ -4089,7 +4089,7 @@ aapcs_vfp_sub_candidate (const_tree type, enum machine_mode *modep) return count; } - + case RECORD_TYPE: { int count = 0; @@ -4237,7 +4237,7 @@ aapcs_vfp_is_return_candidate (enum arm_pcs pcs_variant, } static bool -aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, enum machine_mode mode, +aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, enum machine_mode mode, const_tree type) { if (!use_vfp_abi (pcum->pcs_variant, false)) @@ -4255,7 +4255,7 @@ aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, enum machine_mode mode, int shift = GET_MODE_SIZE (pcum->aapcs_vfp_rmode) / GET_MODE_SIZE (SFmode); unsigned mask = (1 << (shift * pcum->aapcs_vfp_rcount)) - 1; int regno; - + for (regno = 0; regno < NUM_VFP_ARG_REGS; regno += shift) if (((pcum->aapcs_vfp_regs_free >> regno) & mask) == mask) { @@ -4282,10 +4282,10 @@ aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, enum machine_mode mode, par = gen_rtx_PARALLEL (mode, rtvec_alloc (rcount)); for (i = 0; i < rcount; i++) { - rtx tmp = gen_rtx_REG (rmode, + rtx tmp = gen_rtx_REG (rmode, FIRST_VFP_REGNUM + regno + i * rshift); tmp = gen_rtx_EXPR_LIST - (VOIDmode, tmp, + (VOIDmode, tmp, GEN_INT (i * GET_MODE_SIZE (rmode))); XVECEXP (par, 0, i) = tmp; } @@ -4314,7 +4314,7 @@ aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED, int i; rtx par; int shift; - + aapcs_vfp_is_call_or_return_candidate (pcs_variant, mode, type, &ag_mode, &count); @@ -4333,7 +4333,7 @@ aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED, for (i = 0; i < count; i++) { rtx tmp = gen_rtx_REG (ag_mode, FIRST_VFP_REGNUM + i * shift); - tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, + tmp = gen_rtx_EXPR_LIST (VOIDmode, tmp, GEN_INT (i * GET_MODE_SIZE (ag_mode))); XVECEXP (par, 0, i) = tmp; } @@ -4370,7 +4370,7 @@ aapcs_vfp_advance (CUMULATIVE_ARGS *pcum ATTRIBUTE_UNUSED, and stops after the first match. If that entry then fails to put the argument into a co-processor register, the argument will go on the stack. */ -static struct +static struct { /* Initialize co-processor related state in CUMULATIVE_ARGS structure. */ void (*cum_init) (CUMULATIVE_ARGS *, const_tree, rtx, const_tree); @@ -4406,7 +4406,7 @@ static struct #undef AAPCS_CP static int -aapcs_select_call_coproc (CUMULATIVE_ARGS *pcum, enum machine_mode mode, +aapcs_select_call_coproc (CUMULATIVE_ARGS *pcum, enum machine_mode mode, const_tree type) { int i; @@ -4446,7 +4446,7 @@ aapcs_select_return_coproc (const_tree type, const_tree fntype) int i; for (i = 0; i < ARM_NUM_COPROC_SLOTS; i++) - if (aapcs_cp_arg_layout[i].is_return_candidate (pcs_variant, + if (aapcs_cp_arg_layout[i].is_return_candidate (pcs_variant, TYPE_MODE (type), type)) return i; @@ -4538,7 +4538,7 @@ aapcs_layout_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode, anonymous argument which is on the stack. */ if (!named) return; - + /* Is this a potential co-processor register candidate? */ if (pcum->pcs_variant != ARM_PCS_AAPCS) { @@ -4638,7 +4638,7 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, { if (arm_libcall_uses_aapcs_base (libname)) pcum->pcs_variant = ARM_PCS_AAPCS; - + pcum->aapcs_ncrn = pcum->aapcs_next_ncrn = 0; pcum->aapcs_reg = NULL_RTX; pcum->aapcs_partial = 0; @@ -5685,7 +5685,7 @@ thumb2_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) { bool use_ldrd; enum rtx_code code = GET_CODE (x); - + if (arm_address_register_rtx_p (x, strict_p)) return 1; @@ -5713,7 +5713,7 @@ thumb2_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) offset = INTVAL(addend); if (GET_MODE_SIZE (mode) <= 4) return (offset > -256 && offset < 256); - + return (use_ldrd && offset > -1024 && offset < 1024 && (offset & 3) == 0); } @@ -5869,14 +5869,14 @@ static bool thumb2_index_mul_operand (rtx op) { HOST_WIDE_INT val; - + if (GET_CODE(op) != CONST_INT) return false; val = INTVAL(op); return (val == 1 || val == 2 || val == 4 || val == 8); } - + /* Return nonzero if INDEX is a valid Thumb-2 address index operand. */ static int thumb2_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p) @@ -6224,11 +6224,11 @@ arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc) emit_insn (gen_pic_add_dot_plus_eight (reg, reg, labelno)); else emit_insn (gen_pic_add_dot_plus_four (reg, reg, labelno)); - + *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX, LCT_PURE, /* LCT_CONST? */ Pmode, 1, reg, Pmode); - + insns = get_insns (); end_sequence (); @@ -6246,7 +6246,7 @@ arm_tls_descseq_addr (rtx x, rtx reg) GEN_INT (!TARGET_ARM)), UNSPEC_TLS); rtx reg0 = load_tls_operand (sum, gen_rtx_REG (SImode, 0)); - + emit_insn (gen_tlscall (x, labelno)); if (!reg) reg = gen_reg_rtx (SImode); @@ -6272,7 +6272,7 @@ legitimize_tls_address (rtx x, rtx reg) reg = arm_tls_descseq_addr (x, reg); tp = arm_load_tp (NULL_RTX); - + dest = gen_rtx_PLUS (Pmode, tp, reg); } else @@ -6290,20 +6290,20 @@ legitimize_tls_address (rtx x, rtx reg) reg = arm_tls_descseq_addr (x, reg); tp = arm_load_tp (NULL_RTX); - + dest = gen_rtx_PLUS (Pmode, tp, reg); } else { insns = arm_call_tls_get_addr (x, reg, &ret, TLS_LDM32); - + /* Attach a unique REG_EQUIV, to allow the RTL optimizers to share the LDM result with other LD model accesses. */ eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx), UNSPEC_TLS); dest = gen_reg_rtx (Pmode); emit_libcall_block (insns, dest, ret, eqv); - + /* Load the addend. */ addend = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, x, GEN_INT (TLS_LDO32)), @@ -7428,7 +7428,7 @@ arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed) *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, 0, speed); return true; } - + return false; case UMIN: @@ -8338,9 +8338,9 @@ cortex_a9_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost) { if (GET_CODE (PATTERN (insn)) == SET) { - if (GET_MODE_CLASS + if (GET_MODE_CLASS (GET_MODE (SET_DEST (PATTERN (insn)))) == MODE_FLOAT - || GET_MODE_CLASS + || GET_MODE_CLASS (GET_MODE (SET_SRC (PATTERN (insn)))) == MODE_FLOAT) { enum attr_type attr_type_insn = get_attr_type (insn); @@ -8360,7 +8360,7 @@ cortex_a9_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost) { /* FMACS is a special case where the dependant instruction can be issued 3 cycles before - the normal latency in case of an output + the normal latency in case of an output dependency. */ if ((attr_type_insn == TYPE_FMACS || attr_type_insn == TYPE_FMACD) @@ -8428,8 +8428,8 @@ fa726te_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost) It corrects the value of COST based on the relationship between INSN and DEP through the dependence LINK. It returns the new value. There is a per-core adjust_cost hook to adjust scheduler costs - and the per-core hook can choose to completely override the generic - adjust_cost function. Only put bits of code into arm_adjust_cost that + and the per-core hook can choose to completely override the generic + adjust_cost function. Only put bits of code into arm_adjust_cost that are common across all cores. */ static int arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost) @@ -8473,7 +8473,7 @@ arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost) constant pool are cached, and that others will miss. This is a hack. */ - if ((GET_CODE (src_mem) == SYMBOL_REF + if ((GET_CODE (src_mem) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (src_mem)) || reg_mentioned_p (stack_pointer_rtx, src_mem) || reg_mentioned_p (frame_pointer_rtx, src_mem) @@ -9868,7 +9868,7 @@ arm_cannot_copy_insn_p (rtx insn) word. */ if (recog_memoized (insn) == CODE_FOR_tlscall) return true; - + return for_each_rtx (&PATTERN (insn), arm_note_pic_base, NULL); } @@ -11097,7 +11097,7 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) /* A compare with a shifted operand. Because of canonicalization, the comparison will have to be swapped when we emit the assembler. */ - if (GET_MODE (y) == SImode + if (GET_MODE (y) == SImode && (REG_P (y) || (GET_CODE (y) == SUBREG)) && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT || GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ROTATE @@ -11106,7 +11106,7 @@ arm_select_cc_mode (enum rtx_code op, rtx x, rtx y) /* This operation is performed swapped, but since we only rely on the Z flag we don't need an additional mode. */ - if (GET_MODE (y) == SImode + if (GET_MODE (y) == SImode && (REG_P (y) || (GET_CODE (y) == SUBREG)) && GET_CODE (x) == NEG && (op == EQ || op == NE)) @@ -12456,7 +12456,7 @@ create_fix_barrier (Mfix *fix, HOST_WIDE_INT max_address) still put the pool after the table. */ new_cost = arm_barrier_cost (from); - if (count < max_count + if (count < max_count && (!selected || new_cost <= selected_cost)) { selected = tmp; @@ -12838,7 +12838,7 @@ arm_reorg (void) if (TARGET_THUMB2) thumb2_reorg (); - + minipool_fix_head = minipool_fix_tail = NULL; /* The first insn must always be a note, or the code below won't @@ -13452,7 +13452,7 @@ output_move_double (rtx *operands, bool emit, int *count) if (count) *count = 1; - /* The only case when this might happen is when + /* The only case when this might happen is when you are looking at the length of a DImode instruction that has an invalid constant in it. */ if (code0 == REG && code1 != MEM) @@ -13461,7 +13461,6 @@ output_move_double (rtx *operands, bool emit, int *count) *count = 2; return ""; } - if (code0 == REG) { @@ -13489,7 +13488,6 @@ output_move_double (rtx *operands, bool emit, int *count) gcc_assert (TARGET_LDRD); if (emit) output_asm_insn ("ldr%(d%)\t%0, [%m1, #8]!", operands); - break; case PRE_DEC: @@ -13503,7 +13501,6 @@ output_move_double (rtx *operands, bool emit, int *count) break; case POST_INC: - if (emit) { if (TARGET_LDRD) @@ -13692,7 +13689,7 @@ output_move_double (rtx *operands, bool emit, int *count) } if (GET_CODE (otherops[2]) == CONST_INT) - { + { if (emit) { if (!(const_ok_for_arm (INTVAL (otherops[2])))) @@ -13700,7 +13697,6 @@ output_move_double (rtx *operands, bool emit, int *count) else output_asm_insn ("add%?\t%0, %1, %2", otherops); } - } else { @@ -13716,8 +13712,8 @@ output_move_double (rtx *operands, bool emit, int *count) if (TARGET_LDRD) return "ldr%(d%)\t%0, [%1]"; - - return "ldm%(ia%)\t%1, %M0"; + + return "ldm%(ia%)\t%1, %M0"; } else { @@ -13894,7 +13890,6 @@ output_move_double (rtx *operands, bool emit, int *count) } if (count) *count = 2; - } } @@ -14104,7 +14099,7 @@ output_move_neon (rtx *operands) ops[0] = XEXP (addr, 0); ops[1] = reg; break; - + case POST_MODIFY: /* FIXME: Not currently enabled in neon_vector_mem_operand. */ gcc_unreachable (); @@ -14596,7 +14591,7 @@ arm_compute_save_reg0_reg12_mask (void) } -/* Compute the number of bytes used to store the static chain register on the +/* Compute the number of bytes used to store the static chain register on the stack, above the stack frame. We need to know this accurately to get the alignment of the rest of the stack frame correct. */ @@ -14935,7 +14930,7 @@ output_return_instruction (rtx operand, int really_return, int reverse) then try to pop r3 instead. */ if (stack_adjust) live_regs_mask |= 1 << 3; - + if (TARGET_UNIFIED_ASM) sprintf (instr, "ldmfd%s\t%%|sp, {", conditional); else @@ -15149,7 +15144,7 @@ arm_output_epilogue (rtx sibling) /* If we have already generated the return instruction then it is futile to generate anything else. */ - if (use_return_insn (FALSE, sibling) && + if (use_return_insn (FALSE, sibling) && (cfun->machine->return_used_this_function != 0)) return ""; @@ -15357,7 +15352,7 @@ arm_output_epilogue (rtx sibling) { operands[0] = stack_pointer_rtx; operands[1] = hard_frame_pointer_rtx; - + operands[2] = GEN_INT (offsets->frame - offsets->saved_regs); output_add_immediate (operands); } @@ -15405,7 +15400,7 @@ arm_output_epilogue (rtx sibling) } } } - + if (amount) { operands[1] = operands[0]; @@ -16037,7 +16032,7 @@ arm_get_frame_offsets (void) { int reg = -1; - /* If it is safe to use r3, then do so. This sometimes + /* If it is safe to use r3, then do so. This sometimes generates better code on Thumb-2 by avoiding the need to use 32-bit push/pop instructions. */ if (! any_sibcall_uses_r3 () @@ -16483,7 +16478,7 @@ arm_expand_prologue (void) && TARGET_ARM) { rtx lr = gen_rtx_REG (SImode, LR_REGNUM); - + emit_set_insn (lr, plus_constant (lr, -4)); } @@ -16694,7 +16689,7 @@ arm_print_operand (FILE *stream, rtx x, int code) if (TARGET_UNIFIED_ASM) arm_print_condition (stream); break; - + case '.': /* The current condition code for a condition code setting instruction. Preceded by 's' in unified syntax, otherwise followed by 's'. */ @@ -17221,7 +17216,7 @@ arm_print_operand (FILE *stream, rtx x, int code) of the target. */ align = MEM_ALIGN (x) >> 3; memsize = MEM_SIZE (x); - + /* Only certain alignment specifiers are supported by the hardware. */ if (memsize == 16 && (align % 32) == 0) align_bits = 256; @@ -17231,7 +17226,7 @@ arm_print_operand (FILE *stream, rtx x, int code) align_bits = 64; else align_bits = 0; - + if (align_bits != 0) asm_fprintf (stream, ":%d", align_bits); @@ -17301,7 +17296,7 @@ arm_print_operand (FILE *stream, rtx x, int code) fprintf (stream, "d%d[%d]", regno/2, ((regno % 2) ? 2 : 0)); } return; - + default: if (x == 0) { @@ -17340,7 +17335,7 @@ arm_print_operand (FILE *stream, rtx x, int code) fputs (":lower16:", stream); x = XEXP (x, 0); } - + output_addr_const (stream, x); break; } @@ -17554,8 +17549,8 @@ arm_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor) if (!TARGET_AAPCS_BASED) { - (is_ctor ? - default_named_section_asm_out_constructor + (is_ctor ? + default_named_section_asm_out_constructor : default_named_section_asm_out_destructor) (symbol, priority); return; } @@ -17564,7 +17559,7 @@ arm_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor) if (priority != DEFAULT_INIT_PRIORITY) { char buf[18]; - sprintf (buf, "%s.%.5u", + sprintf (buf, "%s.%.5u", is_ctor ? ".init_array" : ".fini_array", priority); s = get_section (buf, SECTION_WRITE, NULL_TREE); @@ -17638,6 +17633,7 @@ arm_elf_asm_destructor (rtx symbol, int priority) /* Returns the index of the ARM condition code string in `arm_condition_codes', or ARM_NV if the comparison is invalid. COMPARISON should be an rtx like `(eq (...) (...))'. */ + enum arm_cond_code maybe_get_arm_condition_code (rtx comparison) { @@ -18255,7 +18251,7 @@ arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) if (IS_IWMMXT_REGNUM (regno)) return VALID_IWMMXT_REG_MODE (mode); } - + /* We allow almost any value to be stored in the general registers. Restrict doubleword quantities to even register pairs so that we can use ldrd. Do not allow very large Neon structure opaque modes in @@ -19440,7 +19436,7 @@ arm_init_neon_builtins (void) } \ } \ while (0) - + struct builtin_description { const unsigned int mask; @@ -19456,7 +19452,7 @@ static const struct builtin_description bdesc_2arg[] = #define IWMMXT_BUILTIN(code, string, builtin) \ { FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \ ARM_BUILTIN_##builtin, UNKNOWN, 0 }, - + IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB) IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH) IWMMXT_BUILTIN (addv2si3, "waddw", WADDW) @@ -19515,10 +19511,10 @@ static const struct builtin_description bdesc_2arg[] = IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW) IWMMXT_BUILTIN (iwmmxt_wmadds, "wmadds", WMADDS) IWMMXT_BUILTIN (iwmmxt_wmaddu, "wmaddu", WMADDU) - + #define IWMMXT_BUILTIN2(code, builtin) \ { FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, UNKNOWN, 0 }, - + IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS) IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS) IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS) @@ -19552,7 +19548,7 @@ static const struct builtin_description bdesc_2arg[] = IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ) IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ) }; - + static const struct builtin_description bdesc_1arg[] = { IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB) @@ -19574,7 +19570,7 @@ static const struct builtin_description bdesc_1arg[] = IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH) IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW) }; - + /* Set up all the iWMMXt builtins. This is not called if TARGET_IWMMXT is zero. */ @@ -19698,7 +19694,7 @@ arm_init_iwmmxt_builtins (void) = build_function_type_list (long_long_unsigned_type_node, V4HI_type_node,V4HI_type_node, NULL_TREE); - + /* Normal vector binops. */ tree v8qi_ftype_v8qi_v8qi = build_function_type_list (V8QI_type_node, @@ -19714,7 +19710,7 @@ arm_init_iwmmxt_builtins (void) long_long_unsigned_type_node, long_long_unsigned_type_node, NULL_TREE); - + /* Add all builtins that are more or less simple operations on two operands. */ for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++) @@ -20669,7 +20665,7 @@ number_of_first_bit_set (unsigned mask) return ctz_hwi (mask); } -/* Like emit_multi_reg_push, but allowing for a different set of +/* Like emit_multi_reg_push, but allowing for a different set of registers to be described as saved. MASK is the set of registers to be saved; REAL_REGS is the set of registers to be described as saved. If REAL_REGS is 0, only describe the stack adjustment. */ @@ -22291,9 +22287,9 @@ arm_file_start (void) if (arm_fpu_desc->model == ARM_FP_MODEL_VFP) { if (TARGET_HARD_FLOAT) - asm_fprintf (asm_out_file, "\t.eabi_attribute 27, 3\n"); + EMIT_EABI_ATTRIBUTE (Tag_ABI_HardFP_use, 27, 3); if (TARGET_HARD_FLOAT_ABI) - asm_fprintf (asm_out_file, "\t.eabi_attribute 28, 1\n"); + EMIT_EABI_ATTRIBUTE (Tag_ABI_VFP_args, 28, 1); } } asm_fprintf (asm_out_file, "\t.fpu %s\n", fpu_name); @@ -22302,30 +22298,23 @@ arm_file_start (void) are used. However we don't have any easy way of figuring this out. Conservatively record the setting that would have been used. */ - /* Tag_ABI_FP_rounding. */ if (flag_rounding_math) - asm_fprintf (asm_out_file, "\t.eabi_attribute 19, 1\n"); + EMIT_EABI_ATTRIBUTE (Tag_ABI_FP_rounding, 19, 1); + if (!flag_unsafe_math_optimizations) { - /* Tag_ABI_FP_denomal. */ - asm_fprintf (asm_out_file, "\t.eabi_attribute 20, 1\n"); - /* Tag_ABI_FP_exceptions. */ - asm_fprintf (asm_out_file, "\t.eabi_attribute 21, 1\n"); + EMIT_EABI_ATTRIBUTE (Tag_ABI_FP_denormal, 20, 1); + EMIT_EABI_ATTRIBUTE (Tag_ABI_FP_exceptions, 21, 1); } - /* Tag_ABI_FP_user_exceptions. */ if (flag_signaling_nans) - asm_fprintf (asm_out_file, "\t.eabi_attribute 22, 1\n"); - /* Tag_ABI_FP_number_model. */ - asm_fprintf (asm_out_file, "\t.eabi_attribute 23, %d\n", - flag_finite_math_only ? 1 : 3); - - /* Tag_ABI_align8_needed. */ - asm_fprintf (asm_out_file, "\t.eabi_attribute 24, 1\n"); - /* Tag_ABI_align8_preserved. */ - asm_fprintf (asm_out_file, "\t.eabi_attribute 25, 1\n"); - /* Tag_ABI_enum_size. */ - asm_fprintf (asm_out_file, "\t.eabi_attribute 26, %d\n", - flag_short_enums ? 1 : 2); + EMIT_EABI_ATTRIBUTE (Tag_ABI_FP_user_exceptions, 22, 1); + + EMIT_EABI_ATTRIBUTE (Tag_ABI_FP_number_model, 23, + flag_finite_math_only ? 1 : 3); + + EMIT_EABI_ATTRIBUTE (Tag_ABI_align8_needed, 24, 1); + EMIT_EABI_ATTRIBUTE (Tag_ABI_align8_preserved, 25, 1); + EMIT_EABI_ATTRIBUTE (Tag_ABI_enum_size, 26, flag_short_enums ? 1 : 2); /* Tag_ABI_optimization_goals. */ if (optimize_size) @@ -22336,21 +22325,18 @@ arm_file_start (void) val = 1; else val = 6; - asm_fprintf (asm_out_file, "\t.eabi_attribute 30, %d\n", val); + EMIT_EABI_ATTRIBUTE (Tag_ABI_optimization_goals, 30, val); - /* Tag_CPU_unaligned_access. */ - asm_fprintf (asm_out_file, "\t.eabi_attribute 34, %d\n", - unaligned_access); + EMIT_EABI_ATTRIBUTE (Tag_CPU_unaligned_access, 34, unaligned_access); - /* Tag_ABI_FP_16bit_format. */ if (arm_fp16_format) - asm_fprintf (asm_out_file, "\t.eabi_attribute 38, %d\n", - (int)arm_fp16_format); + EMIT_EABI_ATTRIBUTE (Tag_ABI_FP_16bit_format, 38, (int) arm_fp16_format); if (arm_lang_output_object_attributes_hook) arm_lang_output_object_attributes_hook(); } - default_file_start(); + + default_file_start (); } static void @@ -22638,7 +22624,7 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v, { CUMULATIVE_ARGS *pcum = get_cumulative_args (pcum_v); int nregs; - + cfun->machine->uses_anonymous_args = 1; if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL) { @@ -22648,7 +22634,7 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v, } else nregs = pcum->nregs; - + if (nregs < NUM_ARG_REGS) *pretend_size = (NUM_ARG_REGS - nregs) * UNITS_PER_WORD; } @@ -23148,7 +23134,7 @@ arm_preferred_simd_mode (enum machine_mode mode) } /* Implement TARGET_CLASS_LIKELY_SPILLED_P. - + We need to define this for LO_REGS on Thumb-1. Otherwise we can end up using r0-r4 for function arguments, r7 for the stack frame and don't have enough left over to do doubleword arithmetic. For Thumb-2 all the @@ -23716,7 +23702,7 @@ arm_output_shift(rtx * operands, int set_flags) const char *shift; HOST_WIDE_INT val; char c; - + c = flag_chars[set_flags]; if (TARGET_UNIFIED_ASM) { @@ -23747,10 +23733,10 @@ thumb1_output_casesi (rtx *operands) switch (GET_MODE(diff_vec)) { case QImode: - return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned ? + return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned ? "bl\t%___gnu_thumb1_case_uqi" : "bl\t%___gnu_thumb1_case_sqi"); case HImode: - return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned ? + return (ADDR_DIFF_VEC_FLAGS (diff_vec).offset_unsigned ? "bl\t%___gnu_thumb1_case_uhi" : "bl\t%___gnu_thumb1_case_shi"); case SImode: return "bl\t%___gnu_thumb1_case_si"; @@ -23859,7 +23845,7 @@ arm_mangle_type (const_tree type) /* The ARM ABI documents (10th October 2008) say that "__va_list" has to be managled as if it is in the "std" namespace. */ - if (TARGET_AAPCS_BASED + if (TARGET_AAPCS_BASED && lang_hooks.types_compatible_p (CONST_CAST_TREE (type), va_list_type)) { static bool warned; @@ -24385,7 +24371,7 @@ arm_builtin_support_vector_misalignment (enum machine_mode mode, packed access. */ return ((misalignment % align) == 0); } - + return default_builtin_support_vector_misalignment (mode, type, misalignment, is_packed); } diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 993e3a07874..8ce2b3e3e97 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -2235,4 +2235,19 @@ extern int making_const_table; " %{mcpu=generic-*:-march=%*;" \ " :%{mcpu=*:-mcpu=%*} %{march=*:-march=%*}}" +/* This macro is used to emit an EABI tag and its associated value. + We emit the numerical value of the tag in case the assembler does not + support textual tags. (Eg gas prior to 2.20). If requested we include + the tag name in a comment so that anyone reading the assembler output + will know which tag is being set. */ +#define EMIT_EABI_ATTRIBUTE(NAME,NUM,VAL) \ + do \ + { \ + asm_fprintf (asm_out_file, "\t.eabi_attribute %d, %d", NUM, VAL); \ + if (flag_verbose_asm || flag_debug_asm) \ + asm_fprintf (asm_out_file, "\t%s " #NAME, ASM_COMMENT_START); \ + asm_fprintf (asm_out_file, "\n"); \ + } \ + while (0) + #endif /* ! GCC_ARM_H */ diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index a2a5dd0c04e..a799fb2a937 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -82,7 +82,7 @@ extern void avr_output_bld (rtx operands[], int bit_nr); extern void avr_output_addr_vec_elt (FILE *stream, int value); extern const char *avr_out_sbxx_branch (rtx insn, rtx operands[]); extern const char* avr_out_bitop (rtx, rtx*, int*); -extern const char* avr_out_plus (rtx*, int*); +extern const char* avr_out_plus (rtx*, int*, int*); extern const char* avr_out_addto_sp (rtx*, int*); extern bool avr_popcount_each_byte (rtx, int, int); @@ -106,6 +106,8 @@ extern int avr_simplify_comparison_p (enum machine_mode mode, extern RTX_CODE avr_normalize_condition (RTX_CODE condition); extern void out_shift_with_cnt (const char *templ, rtx insn, rtx operands[], int *len, int t_len); +extern reg_class_t avr_mode_code_base_reg_class (enum machine_mode, RTX_CODE, RTX_CODE); +extern bool avr_regno_mode_code_ok_for_base_p (int, enum machine_mode, RTX_CODE, RTX_CODE); extern rtx avr_incoming_return_addr_rtx (void); extern rtx avr_legitimize_reload_address (rtx, enum machine_mode, int, int, int, int, rtx (*)(rtx,int)); #endif /* RTX_CODE */ diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index c28b593a8b8..4a93c0aa8dc 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -351,6 +351,21 @@ avr_option_override (void) { flag_delete_null_pointer_checks = 0; + /* Unwind tables currently require a frame pointer for correctness, + see toplev.c:process_options(). */ + + if ((flag_unwind_tables + || flag_non_call_exceptions + || flag_asynchronous_unwind_tables) + && !ACCUMULATE_OUTGOING_ARGS) + { + flag_omit_frame_pointer = 0; + } + else + { + flag_omit_frame_pointer = (optimize >= 1); + } + avr_current_device = &avr_mcu_types[avr_mcu_index]; avr_current_arch = &avr_arch_types[avr_current_device->arch]; avr_extra_arch_macro = avr_current_device->macro; @@ -1187,43 +1202,68 @@ avr_cannot_modify_jumps_p (void) } +/* Helper function for `avr_legitimate_address_p'. */ + +static inline bool +avr_reg_ok_for_addr_p (rtx reg, addr_space_t as ATTRIBUTE_UNUSED, int strict) +{ + return (REG_P (reg) + && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), + QImode, MEM, UNKNOWN) + || (!strict + && REGNO (reg) >= FIRST_PSEUDO_REGISTER))); +} + + /* Return nonzero if X (an RTX) is a legitimate memory address on the target machine for a memory operand of mode MODE. */ -bool +static bool avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) { reg_class_t r = NO_REGS; - if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x) - : REG_OK_FOR_BASE_NOSTRICT_P (x))) - r = POINTER_REGS; + if (REG_P (x) + && avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC, strict)) + { + r = POINTER_REGS; + } else if (CONSTANT_ADDRESS_P (x)) - r = ALL_REGS; + { + r = ALL_REGS; + } else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) - && GET_CODE (XEXP (x, 1)) == CONST_INT - && INTVAL (XEXP (x, 1)) >= 0) + && CONST_INT_P (XEXP (x, 1)) + && INTVAL (XEXP (x, 1)) >= 0) { - int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode); + rtx reg = XEXP (x, 0); + bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode); + if (fit) - { - if (! strict - || REGNO (XEXP (x,0)) == REG_X - || REGNO (XEXP (x,0)) == REG_Y - || REGNO (XEXP (x,0)) == REG_Z) - r = BASE_POINTER_REGS; - if (XEXP (x,0) == frame_pointer_rtx - || XEXP (x,0) == arg_pointer_rtx) - r = BASE_POINTER_REGS; - } - else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx) - r = POINTER_Y_REGS; + { + if (! strict + || REGNO (reg) == REG_X + || REGNO (reg) == REG_Y + || REGNO (reg) == REG_Z) + { + r = BASE_POINTER_REGS; + } + + if (reg == frame_pointer_rtx + || reg == arg_pointer_rtx) + { + r = BASE_POINTER_REGS; + } + } + else if (frame_pointer_needed && reg == frame_pointer_rtx) + { + r = POINTER_Y_REGS; + } } else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC) && REG_P (XEXP (x, 0)) - && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0)) - : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0)))) + && avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC, strict)) { r = POINTER_REGS; } @@ -1254,7 +1294,7 @@ avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) /* Attempts to replace X with a valid memory address for an operand of mode MODE */ -rtx +static rtx avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode) { bool big_offset_p = false; @@ -1615,9 +1655,37 @@ void notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn) { rtx set; + enum attr_cc cc = get_attr_cc (insn); - switch (get_attr_cc (insn)) + switch (cc) { + default: + break; + + case CC_OUT_PLUS: + { + rtx *op = recog_data.operand; + int len_dummy, icc; + + /* Extract insn's operands. */ + extract_constrain_insn_cached (insn); + + avr_out_plus (op, &len_dummy, &icc); + cc = (enum attr_cc) icc; + + break; + } + } + + switch (cc) + { + default: + /* Special values like CC_OUT_PLUS from above have been + mapped to "standard" CC_* values so we never come here. */ + + gcc_unreachable(); + break; + case CC_NONE: /* Insn does not affect CC at all. */ break; @@ -4658,10 +4726,11 @@ lshrsi3_out (rtx insn, rtx operands[], int *len) addition; otherwise, set *PLEN to the length of the instruction sequence (in words) printed with PLEN == NULL. XOP[3] is an 8-bit scratch register. CODE == PLUS: perform addition by using ADD instructions. - CODE == MINUS: perform addition by using SUB instructions. */ + CODE == MINUS: perform addition by using SUB instructions. + Set *PCC to effect on cc0 according to respective CC_* insn attribute. */ static void -avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code) +avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc) { /* MODE of the operation. */ enum machine_mode mode = GET_MODE (xop[0]); @@ -4685,6 +4754,10 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code) /* Value to add. There are two ways to add VAL: R += VAL and R -= -VAL. */ rtx xval = xop[2]; + /* Addition does not set cc0 in a usable way. */ + + *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER; + if (MINUS == code) xval = gen_int_mode (-UINTVAL (xval), mode); @@ -4707,6 +4780,11 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code) op[0] = reg8; op[1] = GEN_INT (val8); + + /* To get usable cc0 no low-bytes must have been skipped. */ + + if (i && !started) + *pcc = CC_CLOBBER; if (!started && i % 2 == 0 && test_hard_reg_class (ADDW_REGS, reg8)) @@ -4779,6 +4857,11 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code) started = true; } /* for all sub-bytes */ + + /* No output doesn't change cc0. */ + + if (plen && *plen == 0) + *pcc = CC_NONE; } @@ -4788,24 +4871,35 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code) and return "". If PLEN == NULL, print assembler instructions to perform the addition; otherwise, set *PLEN to the length of the instruction sequence (in - words) printed with PLEN == NULL. */ + words) printed with PLEN == NULL. + If PCC != 0 then set *PCC to the the instruction sequence's effect on the + condition code (with respect to XOP[0]). */ const char* -avr_out_plus (rtx *xop, int *plen) +avr_out_plus (rtx *xop, int *plen, int *pcc) { int len_plus, len_minus; + int cc_plus, cc_minus, cc_dummy; + if (!pcc) + pcc = &cc_dummy; + /* Work out if XOP[0] += XOP[2] is better or XOP[0] -= -XOP[2]. */ - avr_out_plus_1 (xop, &len_plus, PLUS); - avr_out_plus_1 (xop, &len_minus, MINUS); + avr_out_plus_1 (xop, &len_plus, PLUS, &cc_plus); + avr_out_plus_1 (xop, &len_minus, MINUS, &cc_minus); + /* Prefer MINUS over PLUS if size is equal because it sets cc0. */ + if (plen) - *plen = (len_minus <= len_plus) ? len_minus : len_plus; + { + *plen = (len_minus <= len_plus) ? len_minus : len_plus; + *pcc = (len_minus <= len_plus) ? cc_minus : cc_plus; + } else if (len_minus <= len_plus) - avr_out_plus_1 (xop, NULL, MINUS); + avr_out_plus_1 (xop, NULL, MINUS, pcc); else - avr_out_plus_1 (xop, NULL, PLUS); + avr_out_plus_1 (xop, NULL, PLUS, pcc); return ""; } @@ -5194,7 +5288,7 @@ adjust_insn_length (rtx insn, int len) case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break; - case ADJUST_LEN_OUT_PLUS: avr_out_plus (op, &len); break; + case ADJUST_LEN_OUT_PLUS: avr_out_plus (op, &len, NULL); break; case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break; @@ -7108,6 +7202,53 @@ test_hard_reg_class (enum reg_class rclass, rtx x) } +/* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction + and thus is suitable to be skipped by CPSE, SBRC, etc. */ + +static bool +avr_2word_insn_p (rtx insn) +{ + if (avr_current_device->errata_skip + || !insn + || 2 != get_attr_length (insn)) + { + return false; + } + + switch (INSN_CODE (insn)) + { + default: + return false; + + case CODE_FOR_movqi_insn: + { + rtx set = single_set (insn); + rtx src = SET_SRC (set); + rtx dest = SET_DEST (set); + + /* Factor out LDS and STS from movqi_insn. */ + + if (MEM_P (dest) + && (REG_P (src) || src == const0_rtx)) + { + return CONSTANT_ADDRESS_P (XEXP (dest, 0)); + } + else if (REG_P (dest) + && MEM_P (src)) + { + return CONSTANT_ADDRESS_P (XEXP (src, 0)); + } + + return false; + } + + case CODE_FOR_call_insn: + case CODE_FOR_call_value_insn: + return true; + } +} + + int jump_over_one_insn_p (rtx insn, rtx dest) { @@ -7116,7 +7257,11 @@ jump_over_one_insn_p (rtx insn, rtx dest) : dest); int jump_addr = INSN_ADDRESSES (INSN_UID (insn)); int dest_addr = INSN_ADDRESSES (uid); - return dest_addr - jump_addr == get_attr_length (insn) + 1; + int jump_offset = dest_addr - jump_addr - get_attr_length (insn); + + return (jump_offset == 1 + || (jump_offset == 2 + && avr_2word_insn_p (next_active_insn (insn)))); } /* Returns 1 if a value of mode MODE can be stored starting with hard @@ -7155,6 +7300,51 @@ avr_hard_regno_mode_ok (int regno, enum machine_mode mode) } +/* Implement `MODE_CODE_BASE_REG_CLASS'. */ + +reg_class_t +avr_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED, + RTX_CODE outer_code ATTRIBUTE_UNUSED, + RTX_CODE index_code ATTRIBUTE_UNUSED) +{ + return reload_completed ? BASE_POINTER_REGS : POINTER_REGS; +} + + +/* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */ + +bool +avr_regno_mode_code_ok_for_base_p (int regno, + enum machine_mode mode ATTRIBUTE_UNUSED, + RTX_CODE outer_code ATTRIBUTE_UNUSED, + RTX_CODE index_code ATTRIBUTE_UNUSED) +{ + if (regno < FIRST_PSEUDO_REGISTER + && (regno == REG_X + || regno == REG_Y + || regno == REG_Z + || regno == ARG_POINTER_REGNUM)) + { + return true; + } + + if (reg_renumber) + { + regno = reg_renumber[regno]; + + if (regno == REG_X + || regno == REG_Y + || regno == REG_Z + || regno == ARG_POINTER_REGNUM) + { + return true; + } + } + + return false; +} + + /* A helper for `output_reload_insisf' and `output_reload_inhi'. */ /* Set 32-bit register OP[0] to compile-time constant OP[1]. CLOBBER_REG is a QI clobber register or NULL_RTX. diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 51bd942cf56..015f12b5fe5 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -308,21 +308,13 @@ enum reg_class { #define REGNO_REG_CLASS(R) avr_regno_reg_class(R) -#define BASE_REG_CLASS (reload_completed ? BASE_POINTER_REGS : POINTER_REGS) +#define MODE_CODE_BASE_REG_CLASS(mode, outer_code, index_code) \ + avr_mode_code_base_reg_class (mode, outer_code, index_code) #define INDEX_REG_CLASS NO_REGS -#define REGNO_OK_FOR_BASE_P(r) (((r) < FIRST_PSEUDO_REGISTER \ - && ((r) == REG_X \ - || (r) == REG_Y \ - || (r) == REG_Z \ - || (r) == ARG_POINTER_REGNUM)) \ - || (reg_renumber \ - && (reg_renumber[r] == REG_X \ - || reg_renumber[r] == REG_Y \ - || reg_renumber[r] == REG_Z \ - || (reg_renumber[r] \ - == ARG_POINTER_REGNUM)))) +#define REGNO_MODE_CODE_OK_FOR_BASE_P(num, mode, outer_code, index_code) \ + avr_regno_mode_code_ok_for_base_p (num, mode, outer_code, index_code) #define REGNO_OK_FOR_INDEX_P(NUM) 0 @@ -381,10 +373,6 @@ typedef struct avr_args { #define MAX_REGS_PER_ADDRESS 1 -#define REG_OK_FOR_BASE_NOSTRICT_P(X) \ - (REGNO (X) >= FIRST_PSEUDO_REGISTER || REG_OK_FOR_BASE_STRICT_P(X)) - -#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) #define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_L,WIN) \ do { \ rtx new_x = avr_legitimize_reload_address (X, MODE, OPNUM, TYPE, \ diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index e17f7f2f263..1052378de65 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -77,7 +77,8 @@ (include "constraints.md") ;; Condition code settings. -(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber" +(define_attr "cc" "none,set_czn,set_zn,set_n,compare,clobber, + out_plus" (const_string "none")) (define_attr "type" "branch,branch1,arith,xcall" @@ -295,7 +296,7 @@ operands[1] = copy_to_mode_reg(QImode, operand1); ") -(define_insn "*movqi" +(define_insn "movqi_insn" [(set (match_operand:QI 0 "nonimmediate_operand" "=r,d,Qm,r,q,r,*r") (match_operand:QI 1 "general_operand" "rL,i,rL,Qm,r,q,i"))] "(register_operand (operands[0],QImode) @@ -786,30 +787,28 @@ (set_attr "cc" "set_n,set_czn,set_czn,set_czn,set_n,set_n")]) (define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=r,!w,!w,d,l,l ,d,r") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0 ,0,0,0 ,0,0") - (match_operand:SI 2 "nonmemory_operand" "r,I ,J ,s,P,N ,n,n"))) - (clobber (match_scratch:QI 3 "=X,X ,X ,X,X,X ,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=r,d ,d,r") + (plus:SI (match_operand:SI 1 "register_operand" "%0,0 ,0,0") + (match_operand:SI 2 "nonmemory_operand" "r,s ,n,n"))) + (clobber (match_scratch:QI 3 "=X,X ,X,&d"))] "" { static const char * const asm_code[] = { "add %A0,%A2\;adc %B0,%B2\;adc %C0,%C2\;adc %D0,%D2", - "adiw %0,%2\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__", - "sbiw %0,%n2\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__", "subi %0,lo8(-(%2))\;sbci %B0,hi8(-(%2))\;sbci %C0,hlo8(-(%2))\;sbci %D0,hhi8(-(%2))", - "sec\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__", - "sec\;sbc %A0,__zero_reg__\;sbc %B0,__zero_reg__\;sbc %C0,__zero_reg__\;sbc %D0,__zero_reg__" + "", + "" }; - if (which_alternative >= (signed) (sizeof (asm_code) / sizeof (*asm_code))) - return avr_out_plus (operands, NULL); + if (*asm_code[which_alternative]) + return asm_code [which_alternative]; - return asm_code [which_alternative]; + return avr_out_plus (operands, NULL, NULL); } - [(set_attr "length" "4,3,3,4,5,5,8,8") - (set_attr "adjust_len" "*,*,*,*,*,*,out_plus,out_plus") - (set_attr "cc" "set_n,set_n,set_czn,set_czn,set_n,set_n,clobber,clobber")]) + [(set_attr "length" "4,4,4,8") + (set_attr "adjust_len" "*,*,out_plus,out_plus") + (set_attr "cc" "set_n,set_czn,out_plus,out_plus")]) (define_insn "*addsi3_zero_extend" [(set (match_operand:SI 0 "register_operand" "=r") @@ -3628,7 +3627,7 @@ "" "") -(define_insn "*call_insn" +(define_insn "call_insn" [(parallel[(call (mem:HI (match_operand:HI 0 "nonmemory_operand" "z,s,z,s")) (match_operand:HI 1 "general_operand" "X,X,X,X")) (use (match_operand:HI 2 "const_int_operand" "L,L,P,P"))])] @@ -3651,7 +3650,7 @@ (const_int 2) (const_int 1))])]) -(define_insn "*call_value_insn" +(define_insn "call_value_insn" [(parallel[(set (match_operand 0 "register_operand" "=r,r,r,r") (call (mem:HI (match_operand:HI 1 "nonmemory_operand" "z,s,z,s")) (match_operand:HI 2 "general_operand" "X,X,X,X"))) @@ -3719,62 +3718,36 @@ (set_attr "cc" "none")]) ;; table jump +;; For entries in jump table see avr_output_addr_vec_elt. -;; Table made from "rjmp" instructions for <=8K devices. +;; Table made from "rjmp .L" instructions for <= 8K devices. (define_insn "*tablejump_rjmp" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] - UNSPEC_INDEX_JMP)) + [(set (pc) + (unspec:HI [(match_operand:HI 0 "register_operand" "!z,*r")] + UNSPEC_INDEX_JMP)) (use (label_ref (match_operand 1 "" ""))) (clobber (match_dup 0))] - "(!AVR_HAVE_JMP_CALL) && (!AVR_HAVE_EIJMP_EICALL)" + "!AVR_HAVE_JMP_CALL" "@ ijmp push %A0\;push %B0\;ret" [(set_attr "length" "1,3") (set_attr "cc" "none,none")]) -;; Not a prologue, but similar idea - move the common piece of code to libgcc. +;; Move the common piece of code to libgcc. +;; Table made from ".word gs(.L)" addresses for > 8K devices. +;; Read jump address from table and perform indirect jump. (define_insn "*tablejump_lib" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] - UNSPEC_INDEX_JMP)) + [(set (pc) + (unspec:HI [(match_operand:HI 0 "register_operand" "z")] + UNSPEC_INDEX_JMP)) (use (label_ref (match_operand 1 "" ""))) (clobber (match_dup 0))] - "AVR_HAVE_JMP_CALL && TARGET_CALL_PROLOGUES" - "%~jmp __tablejump2__" + "AVR_HAVE_JMP_CALL" + "jmp __tablejump2__" [(set_attr "length" "2") (set_attr "cc" "clobber")]) -(define_insn "*tablejump_enh" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] - UNSPEC_INDEX_JMP)) - (use (label_ref (match_operand 1 "" ""))) - (clobber (match_dup 0))] - "AVR_HAVE_JMP_CALL && AVR_HAVE_LPMX" - "lsl r30 - rol r31 - lpm __tmp_reg__,Z+ - lpm r31,Z - mov r30,__tmp_reg__ - %!ijmp" - [(set_attr "length" "6") - (set_attr "cc" "clobber")]) - -(define_insn "*tablejump" - [(set (pc) (unspec:HI [(match_operand:HI 0 "register_operand" "z")] - UNSPEC_INDEX_JMP)) - (use (label_ref (match_operand 1 "" ""))) - (clobber (match_dup 0))] - "AVR_HAVE_JMP_CALL && !AVR_HAVE_EIJMP_EICALL" - "lsl r30 - rol r31 - lpm - inc r30 - push r0 - lpm - push r0 - ret" - [(set_attr "length" "8") - (set_attr "cc" "clobber")]) (define_expand "casesi" [(set (match_dup 6) diff --git a/gcc/config/avr/libgcc.S b/gcc/config/avr/libgcc.S index a4e4b4215b5..8df36072370 100644 --- a/gcc/config/avr/libgcc.S +++ b/gcc/config/avr/libgcc.S @@ -821,27 +821,31 @@ ENDF __tablejump2__ DEFUN __tablejump__ #if defined (__AVR_HAVE_LPMX__) - lpm __tmp_reg__, Z+ - lpm r31, Z - mov r30, __tmp_reg__ - #if defined (__AVR_HAVE_EIJMP_EICALL__) - eijmp -#else + lpm __tmp_reg__, Z+ + push __tmp_reg__ + lpm __tmp_reg__, Z + push __tmp_reg__ + push __zero_reg__ + ret +#else + lpm __tmp_reg__, Z+ + lpm r31, Z + mov r30, __tmp_reg__ ijmp #endif -#else +#else /* !HAVE_LPMX */ lpm - adiw r30, 1 - push r0 + adiw r30, 1 + push r0 lpm - push r0 + push r0 #if defined (__AVR_HAVE_EIJMP_EICALL__) - push __zero_reg__ + push __zero_reg__ #endif ret -#endif +#endif /* !HAVE_LPMX */ ENDF __tablejump__ #endif /* defined (L_tablejump) */ diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c index b74bbd3c482..35ecaa8e2fd 100644 --- a/gcc/config/cris/cris.c +++ b/gcc/config/cris/cris.c @@ -123,6 +123,8 @@ static void cris_asm_output_mi_thunk static void cris_file_start (void); static void cris_init_libfuncs (void); +static reg_class_t cris_preferred_reload_class (rtx, reg_class_t); + static int cris_register_move_cost (enum machine_mode, reg_class_t, reg_class_t); static int cris_memory_move_cost (enum machine_mode, reg_class_t, bool); static bool cris_rtx_costs (rtx, int, int, int, int *, bool); @@ -198,6 +200,9 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION; #undef TARGET_INIT_LIBFUNCS #define TARGET_INIT_LIBFUNCS cris_init_libfuncs +#undef TARGET_PREFERRED_RELOAD_CLASS +#define TARGET_PREFERRED_RELOAD_CLASS cris_preferred_reload_class + #undef TARGET_REGISTER_MOVE_COST #define TARGET_REGISTER_MOVE_COST cris_register_move_cost #undef TARGET_MEMORY_MOVE_COST @@ -1342,6 +1347,31 @@ cris_reload_address_legitimized (rtx x, return false; } + +/* Worker function for TARGET_PREFERRED_RELOAD_CLASS. + + It seems like gcc (2.7.2 and 2.9x of 2000-03-22) may send "NO_REGS" as + the class for a constant (testcase: __Mul in arit.c). To avoid forcing + out a constant into the constant pool, we will trap this case and + return something a bit more sane. FIXME: Check if this is a bug. + Beware that we must not "override" classes that can be specified as + constraint letters, or else asm operands using them will fail when + they need to be reloaded. FIXME: Investigate whether that constitutes + a bug. */ + +static reg_class_t +cris_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, reg_class_t rclass) +{ + if (rclass != ACR_REGS + && rclass != MOF_REGS + && rclass != SRP_REGS + && rclass != CC0_REGS + && rclass != SPECIAL_REGS) + return GENERAL_REGS; + + return rclass; +} + /* Worker function for TARGET_REGISTER_MOVE_COST. */ static int diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index a18b14ef21e..4c28e4530ab 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -583,22 +583,6 @@ enum reg_class /* See REGNO_OK_FOR_BASE_P. */ #define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO) -/* It seems like gcc (2.7.2 and 2.9x of 2000-03-22) may send "NO_REGS" as - the class for a constant (testcase: __Mul in arit.c). To avoid forcing - out a constant into the constant pool, we will trap this case and - return something a bit more sane. FIXME: Check if this is a bug. - Beware that we must not "override" classes that can be specified as - constraint letters, or else asm operands using them will fail when - they need to be reloaded. FIXME: Investigate whether that constitutes - a bug. */ -#define PREFERRED_RELOAD_CLASS(X, CLASS) \ - ((CLASS) != ACR_REGS \ - && (CLASS) != MOF_REGS \ - && (CLASS) != SRP_REGS \ - && (CLASS) != CC0_REGS \ - && (CLASS) != SPECIAL_REGS \ - ? GENERAL_REGS : (CLASS)) - /* We can't move special registers to and from memory in smaller than word_mode. We also can't move between special registers. Luckily, -1, as returned by true_regnum for non-sub/registers, is valid as a diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index bedda1ec65b..d8e5cd974a2 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -2962,7 +2962,7 @@ darwin_override_options (void) static void darwin_patch_builtin (int fncode) { - tree fn = built_in_decls[fncode]; + tree fn = builtin_decl_explicit (fncode); tree sym; char *newname; @@ -2974,7 +2974,7 @@ darwin_patch_builtin (int fncode) set_user_assembler_name (fn, newname); - fn = implicit_built_in_decls[fncode]; + fn = builtin_decl_implicit (fncode); if (fn) set_user_assembler_name (fn, newname); } @@ -3149,9 +3149,10 @@ darwin_rename_builtins (void) use the faster version. */ if (!flag_unsafe_math_optimizations) { - int dcode = (BUILT_IN_COMPLEX_DIV_MIN - + DCmode - MIN_MODE_COMPLEX_FLOAT); - tree fn = built_in_decls[dcode]; + enum built_in_function dcode + = (enum built_in_function)(BUILT_IN_COMPLEX_DIV_MIN + + DCmode - MIN_MODE_COMPLEX_FLOAT); + tree fn = builtin_decl_explicit (dcode); /* Fortran and c call TARGET_INIT_BUILTINS and TARGET_INIT_LIBFUNCS at different times, so we have to put a call into each to ensure that at least one of them is called @@ -3159,7 +3160,7 @@ darwin_rename_builtins (void) new hook to run after build_common_builtin_nodes runs. */ if (fn) set_user_assembler_name (fn, "___ieee_divdc3"); - fn = implicit_built_in_decls[dcode]; + fn = builtin_decl_implicit (dcode); if (fn) set_user_assembler_name (fn, "___ieee_divdc3"); } diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 21ce9b26ce9..625c55e76d9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -8027,7 +8027,7 @@ ix86_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, else { tree copy - = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY], + = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY), 3, dest_addr, src_addr, size_int (cur_size)); gimplify_and_add (copy, pre_p); @@ -28096,7 +28096,6 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, klass = store; memory = 0; break; - break; case UINT64_FTYPE_VOID: case UNSIGNED_FTYPE_VOID: nargs = 0; @@ -29161,7 +29160,7 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in) return NULL_TREE; } - bname = IDENTIFIER_POINTER (DECL_NAME (implicit_built_in_decls[fn])); + bname = IDENTIFIER_POINTER (DECL_NAME (builtin_decl_implicit (fn))); if (fn == BUILT_IN_LOGF) strcpy (name, "vmlsLn4"); @@ -29179,7 +29178,8 @@ ix86_veclibabi_svml (enum built_in_function fn, tree type_out, tree type_in) name[4] &= ~0x20; arity = 0; - for (args = DECL_ARGUMENTS (implicit_built_in_decls[fn]); args; + for (args = DECL_ARGUMENTS (builtin_decl_implicit (fn)); + args; args = TREE_CHAIN (args)) arity++; @@ -29260,11 +29260,12 @@ ix86_veclibabi_acml (enum built_in_function fn, tree type_out, tree type_in) return NULL_TREE; } - bname = IDENTIFIER_POINTER (DECL_NAME (implicit_built_in_decls[fn])); + bname = IDENTIFIER_POINTER (DECL_NAME (builtin_decl_implicit (fn))); sprintf (name + 7, "%s", bname+10); arity = 0; - for (args = DECL_ARGUMENTS (implicit_built_in_decls[fn]); args; + for (args = DECL_ARGUMENTS (builtin_decl_implicit (fn)); + args; args = TREE_CHAIN (args)) arity++; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a11a71b6c2e..b527ad29896 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -11708,9 +11708,13 @@ } }) +;; We need to disable this for TARGET_SEH, as otherwise +;; shrink-wrapped prologue gets enabled too. This might exceed +;; the maximum size of prologue in unwind information. + (define_expand "simple_return" [(simple_return)] - "" + "!TARGET_SEH" { if (crtl->args.pops_args) { diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index f135716c583..9153352d9a8 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -2009,7 +2009,7 @@ "TARGET_FMA" "@ vfnmsub132\t{%2, %3, %0|%0, %3, %2} - vfnmsub231\t{%3, %2, %0|%0, %2, %3} + vfnmsub213\t{%3, %2, %0|%0, %2, %3} vfnmsub231\t{%2, %1, %0|%0, %1, %2}" [(set_attr "type" "ssemuladd") (set_attr "mode" "")]) diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index f4fbf08396d..1f6fe1e4c10 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -10100,15 +10100,12 @@ ia64_init_builtins (void) if (TARGET_HPUX) { - if (built_in_decls [BUILT_IN_FINITE]) - set_user_assembler_name (built_in_decls [BUILT_IN_FINITE], - "_Isfinite"); - if (built_in_decls [BUILT_IN_FINITEF]) - set_user_assembler_name (built_in_decls [BUILT_IN_FINITEF], - "_Isfinitef"); - if (built_in_decls [BUILT_IN_FINITEL]) - set_user_assembler_name (built_in_decls [BUILT_IN_FINITEL], - "_Isfinitef128"); + if ((decl = builtin_decl_explicit (BUILT_IN_FINITE)) != NULL_TREE) + set_user_assembler_name (decl, "_Isfinite"); + if ((decl = builtin_decl_explicit (BUILT_IN_FINITEF)) != NULL_TREE) + set_user_assembler_name (decl, "_Isfinitef"); + if ((decl = builtin_decl_explicit (BUILT_IN_FINITEL)) != NULL_TREE) + set_user_assembler_name (decl, "_Isfinitef128"); } } diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index e3ad4c80d89..66e3fc700b4 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -555,16 +555,21 @@ static void pa_init_builtins (void) { #ifdef DONT_HAVE_FPUTC_UNLOCKED - built_in_decls[(int) BUILT_IN_FPUTC_UNLOCKED] = - built_in_decls[(int) BUILT_IN_PUTC_UNLOCKED]; - implicit_built_in_decls[(int) BUILT_IN_FPUTC_UNLOCKED] - = implicit_built_in_decls[(int) BUILT_IN_PUTC_UNLOCKED]; + { + tree decl = builtin_decl_explicit (BUILT_IN_PUTC_UNLOCKED); + set_builtin_decl (BUILT_IN_FPUTC_UNLOCKED, decl, + builtin_decl_implicit_p (BUILT_IN_PUTC_UNLOCKED)); + } #endif #if TARGET_HPUX_11 - if (built_in_decls [BUILT_IN_FINITE]) - set_user_assembler_name (built_in_decls [BUILT_IN_FINITE], "_Isfinite"); - if (built_in_decls [BUILT_IN_FINITEF]) - set_user_assembler_name (built_in_decls [BUILT_IN_FINITEF], "_Isfinitef"); + { + tree decl; + + if ((decl = builtin_decl_explicit (BUILT_IN_FINITE)) != NULL_TREE) + set_user_assembler_name (decl, "_Isfinite"); + if ((decl = builtin_decl_explicit (BUILT_IN_FINITEF)) != NULL_TREE) + set_user_assembler_name (decl, "_Isfinitef"); + } #endif if (HPUX_LONG_DOUBLE_LIBRARY) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 63c0f0ce201..4fd2192d380 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3739,7 +3739,7 @@ rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in) case BUILT_IN_SQRT: case BUILT_IN_TAN: case BUILT_IN_TANH: - bdecl = implicit_built_in_decls[fn]; + bdecl = builtin_decl_implicit (fn); suffix = "d2"; /* pow -> powd2 */ if (el_mode != DFmode || n != 2) @@ -3776,7 +3776,7 @@ rs6000_builtin_vectorized_libmass (tree fndecl, tree type_out, tree type_in) case BUILT_IN_SQRTF: case BUILT_IN_TANF: case BUILT_IN_TANHF: - bdecl = implicit_built_in_decls[fn]; + bdecl = builtin_decl_implicit (fn); suffix = "4"; /* powf -> powf4 */ if (el_mode != SFmode || n != 4) @@ -9400,7 +9400,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, tree tmp = create_tmp_var (type, "va_arg_tmp"); tree dest_addr = build_fold_addr_expr (tmp); - tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY], + tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY), 3, dest_addr, addr, size_int (rsize * 4)); gimplify_and_add (copy, pre_p); @@ -12213,8 +12213,8 @@ rs6000_init_builtins (void) #if TARGET_XCOFF /* AIX libm provides clog as __clog. */ - if (built_in_decls [BUILT_IN_CLOG]) - set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog"); + if ((tdecl = builtin_decl_explicit ([BUILT_IN_CLOG))) != NULL_TREE) + set_user_assembler_name (tdecl, "__clog"); #endif #ifdef SUBTARGET_INIT_BUILTINS diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 9606f68d9b5..9c7cc56b43e 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -6789,7 +6789,7 @@ sparc_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p, { tree tmp = create_tmp_var (type, "va_arg_tmp"); tree dest_addr = build_fold_addr_expr (tmp); - tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY], + tree copy = build_call_expr (builtin_decl_implicit (BUILT_IN_MEMCPY), 3, dest_addr, addr, size_int (rsize)); TREE_ADDRESSABLE (tmp) = 1; gimplify_and_add (copy, pre_p); diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index a6eba6ca3a6..24993fb1821 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -2614,11 +2614,9 @@ (match_operand:I 3 "arith10_operand" "")))] "TARGET_V9 && !(mode == DImode && TARGET_ARCH32)" { - enum rtx_code code = GET_CODE (operands[1]); rtx cc_reg; - if (GET_MODE (XEXP (operands[1], 0)) == DImode - && ! TARGET_ARCH64) + if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) FAIL; if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) @@ -2629,12 +2627,14 @@ if (XEXP (operands[1], 1) == const0_rtx && GET_CODE (XEXP (operands[1], 0)) == REG && GET_MODE (XEXP (operands[1], 0)) == DImode - && v9_regcmp_p (code)) + && v9_regcmp_p (GET_CODE (operands[1]))) cc_reg = XEXP (operands[1], 0); else cc_reg = gen_compare_reg (operands[1]); - operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] + = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, + const0_rtx); }) (define_expand "movcc" @@ -2644,11 +2644,9 @@ (match_operand:F 3 "register_operand" "")))] "TARGET_V9 && TARGET_FPU" { - enum rtx_code code = GET_CODE (operands[1]); rtx cc_reg; - if (GET_MODE (XEXP (operands[1], 0)) == DImode - && ! TARGET_ARCH64) + if (GET_MODE (XEXP (operands[1], 0)) == DImode && !TARGET_ARCH64) FAIL; if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD) @@ -2659,12 +2657,14 @@ if (XEXP (operands[1], 1) == const0_rtx && GET_CODE (XEXP (operands[1], 0)) == REG && GET_MODE (XEXP (operands[1], 0)) == DImode - && v9_regcmp_p (code)) + && v9_regcmp_p (GET_CODE (operands[1]))) cc_reg = XEXP (operands[1], 0); else cc_reg = gen_compare_reg (operands[1]); - operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx); + operands[1] + = gen_rtx_fmt_ee (GET_CODE (operands[1]), GET_MODE (cc_reg), cc_reg, + const0_rtx); }) ;; Conditional move define_insns diff --git a/gcc/config/vms/vms.c b/gcc/config/vms/vms.c index 62a16619856..44940a3aa3b 100644 --- a/gcc/config/vms/vms.c +++ b/gcc/config/vms/vms.c @@ -99,8 +99,11 @@ vms_patch_builtins (void) unsigned int i; /* Fwrite on VMS is non-standard. */ - implicit_built_in_decls[(int) BUILT_IN_FWRITE] = NULL_TREE; - implicit_built_in_decls[(int) BUILT_IN_FWRITE_UNLOCKED] = NULL_TREE; + if (builtin_decl_implicit_p (BUILT_IN_WRITE)) + set_builtin_decl_implicit_p (BUILT_IN_WRITE, false); + + if (builtin_decl_implicit_p (BUILT_IN_WRITE_UNLOCKED)) + set_builtin_decl_implicit_p (BUILT_IN_WRITE_UNLOCKED, false); /* Define aliases for names. */ for (i = 0; i < NBR_CRTL_NAMES; i++) -- cgit v1.2.1