diff options
Diffstat (limited to 'gcc/config/ia64')
-rw-r--r-- | gcc/config/ia64/ia64-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.c | 102 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.h | 35 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.opt | 2 | ||||
-rw-r--r-- | gcc/config/ia64/ia64intrin.h | 93 | ||||
-rw-r--r-- | gcc/config/ia64/vect.md | 37 |
6 files changed, 87 insertions, 184 deletions
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 94fa176f7e7..7b097bf56c4 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -68,7 +68,6 @@ extern void ia64_print_operand (FILE *, rtx, int); extern enum reg_class ia64_preferred_reload_class (rtx, enum reg_class); extern enum reg_class ia64_secondary_reload_class (enum reg_class, enum machine_mode, rtx); -extern void ia64_output_dwarf_dtprel (FILE*, int, rtx); extern void process_for_unwind_directive (FILE *, rtx); extern const char *get_bundle_name (int); #endif /* RTX_CODE */ @@ -114,3 +113,4 @@ extern enum direction ia64_hpux_function_arg_padding (enum machine_mode, tree); #endif /* ARGS_SIZE_RTX */ extern void ia64_hpux_handle_builtin_pragma (struct cpp_reader *); +extern void ia64_output_function_profiler (FILE *, int); diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index c8e0ea398b1..bf9375a4733 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -98,10 +98,6 @@ static const char * const ia64_local_reg_names[80] = static const char * const ia64_output_reg_names[8] = { "out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7" }; -/* Determines whether we use adds, addl, or movl to generate our - TLS immediate offsets. */ -int ia64_tls_size = 22; - /* Which cpu are we scheduling for. */ enum processor_type ia64_tune = PROCESSOR_ITANIUM2; @@ -236,6 +232,8 @@ static void ia64_file_start (void); static void ia64_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); +static void ia64_output_dwarf_dtprel (FILE *, int, rtx) + ATTRIBUTE_UNUSED; static void ia64_rwreloc_select_section (tree, int, unsigned HOST_WIDE_INT) ATTRIBUTE_UNUSED; static void ia64_rwreloc_unique_section (tree, int) @@ -373,6 +371,11 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_SECTION_TYPE_FLAGS #define TARGET_SECTION_TYPE_FLAGS ia64_section_type_flags +#ifdef HAVE_AS_TLS +#undef TARGET_ASM_OUTPUT_DWARF_DTPREL +#define TARGET_ASM_OUTPUT_DWARF_DTPREL ia64_output_dwarf_dtprel +#endif + /* ??? ABI doesn't allow us to define this. */ #if 0 #undef TARGET_PROMOTE_FUNCTION_ARGS @@ -484,7 +487,7 @@ ia64_handle_model_attribute (tree *node, tree name, tree args, } else { - warning (0, "invalid argument of %qs attribute", + warning (OPT_Wattributes, "invalid argument of %qs attribute", IDENTIFIER_POINTER (name)); *no_add_attrs = true; } @@ -516,7 +519,8 @@ ia64_handle_model_attribute (tree *node, tree name, tree args, break; default: - warning (0, "%qs attribute ignored", IDENTIFIER_POINTER (name)); + warning (OPT_Wattributes, "%qs attribute ignored", + IDENTIFIER_POINTER (name)); *no_add_attrs = true; break; } @@ -2011,7 +2015,7 @@ mark_reg_gr_used_mask (rtx reg, void *data ATTRIBUTE_UNUSED) unsigned int regno = REGNO (reg); if (regno < 32) { - unsigned int i, n = HARD_REGNO_NREGS (regno, GET_MODE (reg)); + unsigned int i, n = hard_regno_nregs[regno][GET_MODE (reg)]; for (i = 0; i < n; ++i) current_frame_info.gr_used_mask |= 1 << (regno + i); } @@ -4154,10 +4158,10 @@ ia64_function_value (tree valtype, tree func ATTRIBUTE_UNUSED) } } -/* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL. +/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL. We need to emit DTP-relative relocations. */ -void +static void ia64_output_dwarf_dtprel (FILE *file, int size, rtx x) { gcc_assert (size == 8); @@ -4821,7 +4825,7 @@ fix_range (const char *const_str) /* Implement TARGET_HANDLE_OPTION. */ static bool -ia64_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED) +ia64_handle_option (size_t code, const char *arg, int value) { switch (code) { @@ -4830,15 +4834,9 @@ ia64_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED) return true; case OPT_mtls_size_: - { - char *end; - unsigned long tmp = strtoul (arg, &end, 10); - if (*end || (tmp != 14 && tmp != 22 && tmp != 64)) - error ("bad value %<%s%> for -mtls-size= switch", arg); - else - ia64_tls_size = tmp; - return true; - } + if (value != 14 && value != 22 && value != 64) + error ("bad value %<%s%> for -mtls-size= switch", arg); + return true; case OPT_mtune_: { @@ -4874,7 +4872,7 @@ ia64_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED) } } -/* Handle TARGET_OPTIONS switches. */ +/* Implement OVERRIDE_OPTIONS. */ void ia64_override_options (void) @@ -5170,25 +5168,19 @@ update_set_flags (rtx x, struct reg_flags *pflags) return; case IF_THEN_ELSE: - if (SET_DEST (x) == pc_rtx) - /* X is a conditional branch. */ - return; - else - { - /* X is a conditional move. */ - rtx cond = XEXP (src, 0); - cond = XEXP (cond, 0); - - /* We always split conditional moves into COND_EXEC patterns, so the - only pattern that can reach here is doloop_end_internal. We don't - need to do anything special for this pattern. */ - gcc_assert (GET_CODE (cond) == REG && REGNO (cond) == AR_LC_REGNUM); - return; - } + /* There are three cases here: + (1) The destination is (pc), in which case this is a branch, + nothing here applies. + (2) The destination is ar.lc, in which case this is a + doloop_end_internal, + (3) The destination is an fp register, in which case this is + an fselect instruction. + In all cases, nothing we do in this function applies. */ + return; default: if (COMPARISON_P (src) - && GET_MODE_CLASS (GET_MODE (XEXP (src, 0))) == MODE_FLOAT) + && SCALAR_FLOAT_MODE_P (GET_MODE (XEXP (src, 0)))) /* Set pflags->is_fp to 1 so that we know we're dealing with a floating point comparison when processing the destination of the SET. */ @@ -7422,7 +7414,9 @@ emit_predicate_relation_info (void) && NOTE_LINE_NUMBER (NEXT_INSN (head)) == NOTE_INSN_BASIC_BLOCK) head = NEXT_INSN (head); - for (r = PR_REG (0); r < PR_REG (64); r += 2) + /* Skip p0, which may be thought to be live due to (reg:DI p0) + grabbing the entire block of predicate registers. */ + for (r = PR_REG (2); r < PR_REG (64); r += 2) if (REGNO_REG_SET_P (bb->global_live_at_start, r)) { rtx p = gen_rtx_REG (BImode, r); @@ -8551,4 +8545,38 @@ ia64_vector_mode_supported_p (enum machine_mode mode) } } +void +ia64_output_function_profiler (FILE *file, int labelno) +{ + if (TARGET_GNU_AS) + fputs ("\t.prologue 4, r40\n", file); + else + fputs ("\t.prologue\n\t.save ar.pfs, r40\n", file); + fputs ("\talloc out0 = ar.pfs, 8, 0, 4, 0\n", file); + + if (NO_PROFILE_COUNTERS) + fputs ("\tmov out3 = r0\n\t;;\n", file); + else + { + char buf[20]; + ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); + + if (TARGET_AUTO_PIC) + fputs ("\tmovl out3 = @gprel(", file); + else + fputs ("\taddl out3 = @ltoff(", file); + assemble_name (file, buf); + if (TARGET_AUTO_PIC) + fputs (")\n\t;;\n", file); + else + fputs ("), r1\n\t;;\n", file); + } + + fputs ("\t.save rp, r42\n", file); + fputs ("\tmov out2 = b0\n", file); + fputs ("\t.body\n", file); + fputs ("\tmov out1 = r1\n", file); + fputs ("\tbr.call.sptk.many b0 = _mcount\n\t;;\n", file); +} + #include "gt-ia64.h" diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index bd32069b171..9753a5dc6c2 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -67,7 +67,6 @@ extern unsigned int ia64_section_threshold; #define TARGET_HAVE_TLS true #endif -extern int ia64_tls_size; #define TARGET_TLS14 (ia64_tls_size == 14) #define TARGET_TLS22 (ia64_tls_size == 22) #define TARGET_TLS64 (ia64_tls_size == 64) @@ -506,9 +505,7 @@ while (0) #define LOCAL_REGNO(REGNO) \ (IN_REGNO_P (REGNO) || LOC_REGNO_P (REGNO)) -/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, - return the mode to be used for the comparison. Must be defined if - EXTRA_CC_MODES is defined. */ +/* We define CCImode in ia64-modes.def so we need a selector. */ #define SELECT_CC_MODE(OP,X,Y) CCmode @@ -1268,24 +1265,11 @@ do { \ call the profiling subroutine `mcount'. */ #undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ -do { \ - char buf[20]; \ - ASM_GENERATE_INTERNAL_LABEL (buf, "LP", LABELNO); \ - fputs ("\talloc out0 = ar.pfs, 8, 0, 4, 0\n", FILE); \ - if (TARGET_AUTO_PIC) \ - fputs ("\tmovl out3 = @gprel(", FILE); \ - else \ - fputs ("\taddl out3 = @ltoff(", FILE); \ - assemble_name (FILE, buf); \ - if (TARGET_AUTO_PIC) \ - fputs (");;\n", FILE); \ - else \ - fputs ("), r1;;\n", FILE); \ - fputs ("\tmov out1 = r1\n", FILE); \ - fputs ("\tmov out2 = b0\n", FILE); \ - fputs ("\tbr.call.sptk.many b0 = _mcount;;\n", FILE); \ -} while (0) +#define FUNCTION_PROFILER(FILE, LABELNO) \ + ia64_output_function_profiler(FILE, LABELNO) + +/* Neither hpux nor linux use profile counters. */ +#define NO_PROFILE_COUNTERS 1 /* Trampolines for Nested Functions. */ @@ -1736,13 +1720,6 @@ do { \ { "loc79", LOC_REG (79) }, \ } -/* Emit a dtp-relative reference to a TLS variable. */ - -#ifdef HAVE_AS_TLS -#define ASM_OUTPUT_DWARF_DTPREL(FILE, SIZE, X) \ - ia64_output_dwarf_dtprel (FILE, SIZE, X) -#endif - /* A C compound statement to output to stdio stream STREAM the assembler syntax for an instruction operand X. X is an RTL expression. */ diff --git a/gcc/config/ia64/ia64.opt b/gcc/config/ia64/ia64.opt index f3790ad1012..25a2cc6a91b 100644 --- a/gcc/config/ia64/ia64.opt +++ b/gcc/config/ia64/ia64.opt @@ -89,7 +89,7 @@ Target RejectNegative Joined Specify range of registers to make fixed mtls-size= -Target RejectNegative Joined +Target RejectNegative Joined UInteger Var(ia64_tls_size) Init(22) Specify bit size of immediate TLS offsets mtune= diff --git a/gcc/config/ia64/ia64intrin.h b/gcc/config/ia64/ia64intrin.h index 6054219f48a..fba7296aacb 100644 --- a/gcc/config/ia64/ia64intrin.h +++ b/gcc/config/ia64/ia64intrin.h @@ -1,91 +1,2 @@ -#ifndef _IA64INTRIN_H_INCLUDED -#define _IA64INTRIN_H_INCLUDED - -/* ??? Overloaded builtins havn't been ported to C++ yet. */ -#ifdef __cplusplus - -#define __sync_val_compare_and_swap(PTR, OLD, NEW) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) \ - __sync_val_compare_and_swap_4((int *)(void *)(PTR),(int)(OLD),(int)(NEW)) \ - : (__typeof__(*(PTR))) \ - __sync_val_compare_and_swap_8((long *)(void *)(PTR),(long)(OLD),(long)(NEW))) - -#define __sync_bool_compare_and_swap(PTR, OLD, NEW) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? __sync_bool_compare_and_swap_4((int *)(void *)(PTR),(int)(OLD),(int)(NEW)) \ - : __sync_bool_compare_and_swap_8((long *)(void *)(PTR),(long)(OLD),(long)(NEW))) - -#define __sync_lock_release(PTR) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? __sync_lock_release_4((int *)(void *)(PTR)) \ - : __sync_lock_release_8((long *)(void *)(PTR))) - -#define __sync_lock_test_and_set(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_lock_test_and_set_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_lock_test_and_set_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_fetch_and_add(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_fetch_and_add_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_fetch_and_add_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_fetch_and_sub(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_fetch_and_sub_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_fetch_and_sub_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_fetch_and_and(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_fetch_and_and_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_fetch_and_and_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_fetch_and_or(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_fetch_and_or_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_fetch_and_or_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_fetch_and_xor(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_fetch_and_xor_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_fetch_and_xor_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_fetch_and_nand(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_fetch_and_nand_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_fetch_and_nand_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_add_and_fetch(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_add_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_add_and_fetch_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_sub_and_fetch(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_sub_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_sub_and_fetch_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_and_and_fetch(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_and_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_and_and_fetch_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_or_and_fetch(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_or_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_or_and_fetch_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_xor_and_fetch(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_xor_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_xor_and_fetch_8((long *)(void *)(PTR),(long)(VAL))) - -#define __sync_nand_and_fetch(PTR,VAL) \ - ((sizeof (*(PTR)) == sizeof(int)) \ - ? (__typeof__(*(PTR))) __sync_nand_and_fetch_4((int *)(void *)(PTR),(int)(VAL)) \ - : (__typeof__(*(PTR))) __sync_nand_and_fetch_8((long *)(void *)(PTR),(long)(VAL))) - -#endif /* __cplusplus */ - -#endif /* _IA64INTRIN_H_INCLUDED */ +/* Overloaded builtins have been ported to C++: nothing is needed + in the header anymore. This file intentionally left void. */ diff --git a/gcc/config/ia64/vect.md b/gcc/config/ia64/vect.md index 07e86f9f171..293707d8914 100644 --- a/gcc/config/ia64/vect.md +++ b/gcc/config/ia64/vect.md @@ -1,5 +1,5 @@ ;; IA-64 machine description for vector operations. -;; Copyright (C) 2004 +;; Copyright (C) 2004, 2005 ;; ;; This file is part of GCC. ;; @@ -873,30 +873,8 @@ { rtx x, cmp; - PUT_MODE (operands[3], V2SFmode); - switch (GET_CODE (operands[3])) - { - case EQ: - case NE: - case LT: - case LE: - case UNORDERED: - case ORDERED: - break; - - case GT: - case GE: - x = XEXP (operands[3], 0); - XEXP (operands[3], 0) = XEXP (operands[3], 1); - XEXP (operands[3], 1) = x; - PUT_CODE (operands[3], swap_condition (GET_CODE (operands[3]))); - break; - - default: - gcc_unreachable (); - } - cmp = gen_reg_rtx (V2SFmode); + PUT_MODE (operands[3], V2SFmode); emit_insn (gen_rtx_SET (VOIDmode, cmp, operands[3])); x = gen_rtx_IF_THEN_ELSE (V2SFmode, cmp, operands[1], operands[2]); @@ -906,12 +884,21 @@ (define_insn "*fpcmp" [(set (match_operand:V2SF 0 "fr_register_operand" "=f") + (match_operator:V2SF 3 "comparison_operator" + [(match_operand:V2SF 1 "fr_reg_or_0_operand" "fU") + (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU")]))] + "" + "fpcmp.%D3 %0 = %F1, %F2" + [(set_attr "itanium_class" "fmisc")]) + +(define_insn "*fselect" + [(set (match_operand:V2SF 0 "fr_register_operand" "=f") (if_then_else:V2SF (match_operand:V2SF 1 "fr_register_operand" "f") (match_operand:V2SF 2 "fr_reg_or_0_operand" "fU") (match_operand:V2SF 3 "fr_reg_or_0_operand" "fU")))] "" - "fselect %0 = %2, %3, %1" + "fselect %0 = %F2, %F3, %1" [(set_attr "itanium_class" "fmisc")]) (define_expand "vec_initv2sf" |