From 3b572406c28259bb8dbc1767937bcd965a64b18e Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sun, 18 Jun 2000 11:54:43 -0700 Subject: [PATCH] ia64-protos.h (process_for_unwind_directive): Declare. * config/ia64/ia64-protos.h (process_for_unwind_directive): Declare. (ia64_file_start): Declare. * config/ia64/ia64.h (ADDL_REGNO_P): Don't compare unsigned against 0. (GR_REGNO_P): Likewise. * config/ia64/ia64.c: Many prototypes. (ia64_reg_numbers): Constify. (ia64_input_reg_names, ia64_local_reg_names): Likewise. (ia64_section_threshold): Make unsigned. (ia64_print_operand): Constify. (fix_range): Constify. (ia64_init_builtins): Don't compare signed vs unsigned. (ia64_expand_builtin): Likewise. * config/ia64/ia64.h (EXTRA_CONSTRAINT): New. (CONSTRAINT_OK_FOR_Q): New. * config/ia64/ia64.md (movdi_internal): Use Q for fp<->mem. (movsf_internal, movdf_internal): Likewise. (cmovdi_internal): Rewrite so that constraints and predicates match; simplify splitters. (cmovsi_internal): Likewise. * config/ia64/ia64.h (ASM_SPEC): Add -x for gas. (ASM_FILE_START): New. * config/ia64/ia64.c (ia64_file_start): New. (rtx_needs_barrier): Handle pred.rel.mutex. (emit_predicate_relation_info): New. * config/ia64/ia64.md (pred_rel_mutex): New. * config/ia64/linux.h (ASM_SPEC): Define. * config/ia64/sysv4.h (ASM_FILE_START): Define. * config/ia64/ia64.c (ia64_encode_section_info): Fix thinko filtering global register variables. From-SVN: r34589 --- gcc/ChangeLog | 35 +++++ gcc/config/ia64/ia64-protos.h | 2 + gcc/config/ia64/ia64.c | 278 +++++++++++++++++++++++++--------- gcc/config/ia64/ia64.h | 22 ++- gcc/config/ia64/ia64.md | 185 ++++++++++------------ gcc/config/ia64/linux.h | 1 + gcc/config/ia64/sysv4.h | 6 +- 7 files changed, 340 insertions(+), 189 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 855bd6438c6..efd8221db9f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,38 @@ +2000-06-18 Richard Henderson + + * config/ia64/ia64-protos.h (process_for_unwind_directive): Declare. + (ia64_file_start): Declare. + * config/ia64/ia64.h (ADDL_REGNO_P): Don't compare unsigned against 0. + (GR_REGNO_P): Likewise. + * config/ia64/ia64.c: Many prototypes. + (ia64_reg_numbers): Constify. + (ia64_input_reg_names, ia64_local_reg_names): Likewise. + (ia64_section_threshold): Make unsigned. + (ia64_print_operand): Constify. + (fix_range): Constify. + (ia64_init_builtins): Don't compare signed vs unsigned. + (ia64_expand_builtin): Likewise. + + * config/ia64/ia64.h (EXTRA_CONSTRAINT): New. + (CONSTRAINT_OK_FOR_Q): New. + * config/ia64/ia64.md (movdi_internal): Use Q for fp<->mem. + (movsf_internal, movdf_internal): Likewise. + (cmovdi_internal): Rewrite so that constraints and predicates match; + simplify splitters. + (cmovsi_internal): Likewise. + + * config/ia64/ia64.h (ASM_SPEC): Add -x for gas. + (ASM_FILE_START): New. + * config/ia64/ia64.c (ia64_file_start): New. + (rtx_needs_barrier): Handle pred.rel.mutex. + (emit_predicate_relation_info): New. + * config/ia64/ia64.md (pred_rel_mutex): New. + * config/ia64/linux.h (ASM_SPEC): Define. + * config/ia64/sysv4.h (ASM_FILE_START): Define. + + * config/ia64/ia64.c (ia64_encode_section_info): Fix thinko + filtering global register variables. + 2000-06-18 Kaveh R. Ghazi * c-common.c (add_c_tree_codes): Fix definition for traditional C. diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 7c4c5faadda..dcfe8ccdbb0 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -61,6 +61,7 @@ extern enum reg_class ia64_secondary_reload_class PARAMS((enum reg_class, enum machine_mode, rtx)); extern void ia64_reorg PARAMS((rtx)); +extern void process_for_unwind_directive PARAMS ((FILE *, rtx)); #endif /* RTX_CODE */ #ifdef TREE_CODE @@ -90,6 +91,7 @@ extern void ia64_encode_section_info PARAMS((tree)); #endif /* TREE_CODE */ extern int ia64_epilogue_uses PARAMS((int)); +extern void ia64_file_start PARAMS((FILE *)); extern void ia64_expand_prologue PARAMS((void)); extern void ia64_expand_epilogue PARAMS((void)); extern void ia64_function_prologue PARAMS((FILE *, int)); diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index dca06cd1c3e..66f928b1c97 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -78,7 +78,7 @@ int ia64_local_regs; int ia64_need_regstk; /* Register names for ia64_expand_prologue. */ -char *ia64_reg_numbers[96] = +static const char * const ia64_reg_numbers[96] = { "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", @@ -93,11 +93,11 @@ char *ia64_reg_numbers[96] = "r120","r121","r122","r123","r124","r125","r126","r127"}; /* ??? These strings could be shared with REGISTER_NAMES. */ -char *ia64_input_reg_names[8] = +static const char * const ia64_input_reg_names[8] = { "in0", "in1", "in2", "in3", "in4", "in5", "in6", "in7" }; /* ??? These strings could be shared with REGISTER_NAMES. */ -char *ia64_local_reg_names[80] = +static const char * const ia64_local_reg_names[80] = { "loc0", "loc1", "loc2", "loc3", "loc4", "loc5", "loc6", "loc7", "loc8", "loc9", "loc10","loc11","loc12","loc13","loc14","loc15", "loc16","loc17","loc18","loc19","loc20","loc21","loc22","loc23", @@ -110,7 +110,7 @@ char *ia64_local_reg_names[80] = "loc72","loc73","loc74","loc75","loc76","loc77","loc78","loc79" }; /* ??? These strings could be shared with REGISTER_NAMES. */ -char *ia64_output_reg_names[8] = +static const char * const ia64_output_reg_names[8] = { "out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7" }; /* String used with the -mfixed-range= option. */ @@ -119,8 +119,20 @@ const char *ia64_fixed_range_string; /* Variables which are this size or smaller are put in the sdata/sbss sections. */ -int ia64_section_threshold; - +unsigned int ia64_section_threshold; + +static enum machine_mode hfa_element_mode PARAMS ((tree, int)); +static void fix_range PARAMS ((const char *)); +static void ia64_add_gc_roots PARAMS ((void)); +static void ia64_init_machine_status PARAMS ((struct function *)); +static void ia64_mark_machine_status PARAMS ((struct function *)); +static void emit_insn_group_barriers PARAMS ((rtx)); +static void emit_predicate_relation_info PARAMS ((rtx)); +static int process_set PARAMS ((FILE *, rtx)); +static rtx ia64_expand_compare_and_swap PARAMS ((enum insn_code, tree, + rtx, int)); +static rtx ia64_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx)); + /* Return 1 if OP is a valid operand for the MEM of a CALL insn. */ int @@ -486,6 +498,42 @@ predicate_operator (op, mode) && (code == EQ || code == NE)); } +/* Begin the assembly file. */ + +void +ia64_file_start (f) + FILE *f; +{ + unsigned int rs, re; + int out_state; + + rs = 1; + out_state = 0; + while (1) + { + while (rs < 64 && call_used_regs[PR_REG (rs)]) + rs++; + if (rs >= 64) + break; + for (re = rs + 1; re < 64 && ! call_used_regs[PR_REG (re)]; re++) + continue; + if (out_state == 0) + { + fputs ("\t.pred.safe_across_calls ", f); + out_state = 1; + } + else + fputc (',', f); + if (re == rs + 1) + fprintf (f, "p%u", rs); + else + fprintf (f, "p%u-p%u", rs, re - 1); + rs = re + 1; + } + if (out_state) + fputc ('\n', f); +} + /* Structure to be filled in by ia64_compute_frame_size with register save masks and offsets for the current function. */ @@ -1834,7 +1882,7 @@ ia64_print_operand (file, x, code) case 'U': if (! TARGET_GNU_AS && GET_CODE (x) == CONST_INT) { - char *prefix = "0x"; + const char *prefix = "0x"; if (INTVAL (x) & 0x80000000) { fprintf (file, "0xffffffff"); @@ -2028,11 +2076,11 @@ ia64_asm_output_external (file, decl, name) /* Parse the -mfixed-range= option string. */ static void -fix_range (str) - char *str; +fix_range (const_str) + const char *const_str; { int i, first, last; - char *dash, *comma; + char *str, *dash, *comma; /* str must be of the form REG1'-'REG2{,REG1'-'REG} where REG1 and REG2 are either register names or register numbers. The effect @@ -2040,6 +2088,10 @@ fix_range (str) REG2 as ``fixed'' so they won't be used by the compiler. This is used, e.g., to ensure that kernel mode code doesn't use f32-f127. */ + i = strlen (const_str); + str = (char *) alloca (i + 1); + memcpy (str, const_str, i + 1); + while (1) { dash = strchr (str, '-'); @@ -2188,6 +2240,11 @@ struct reg_flags unsigned int is_branch : 1; /* Is register used as part of a branch? */ }; +static void rws_update PARAMS ((struct reg_write_state *, int, + struct reg_flags, int)); +static int rws_access_reg PARAMS ((int, struct reg_flags, int)); +static int rtx_needs_barrier PARAMS ((rtx, struct reg_flags, int)); + /* Update *RWS for REGNO, which is being written by the current instruction, with predicate PRED, and associated register flags in FLAGS. */ @@ -2637,6 +2694,10 @@ rtx_needs_barrier (x, flags, pred) need_barrier = rws_access_reg (REG_AR_PFS, new_flags, pred); break; + case 5: /* set_bsp */ + need_barrier = 1; + break; + case 6: /* mov pr= */ /* This writes all predicate registers. */ new_flags.is_write = 1; @@ -2647,9 +2708,8 @@ rtx_needs_barrier (x, flags, pred) need_barrier |= rws_access_reg (i, new_flags, pred); break; - case 5: /* set_bsp */ - need_barrier = 1; - break; + case 7: /* pred.rel.mutex */ + return 0; default: abort (); @@ -2809,12 +2869,54 @@ emit_insn_group_barriers (insns) } } +/* Emit pseudo-ops for the assembler to describe predicate relations. + At present this assumes that we only consider predicate pairs to + be mutex, and that the assembler can deduce proper values from + straight-line code. */ + +static void +emit_predicate_relation_info (insns) + rtx insns; +{ + int i; + + /* Make sure the CFG and global_live_at_start are correct. */ + find_basic_blocks (insns, max_reg_num (), NULL); + life_analysis (insns, NULL, 0); + + for (i = n_basic_blocks - 1; i >= 0; --i) + { + basic_block bb = BASIC_BLOCK (i); + int r; + rtx head = bb->head; + + /* We only need such notes at code labels. */ + if (GET_CODE (head) != CODE_LABEL) + continue; + if (GET_CODE (NEXT_INSN (head)) == NOTE + && 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) + if (REGNO_REG_SET_P (bb->global_live_at_start, r)) + { + rtx p1 = gen_rtx_REG (CCmode, r); + rtx p2 = gen_rtx_REG (CCmode, r + 1); + rtx n = emit_insn_after (gen_pred_rel_mutex (p1, p2), head); + if (head == bb->end) + bb->end = n; + head = n; + } + } +} + /* Perform machine dependent operations on the rtl chain INSNS. */ void ia64_reorg (insns) rtx insns; { + emit_predicate_relation_info (insns); emit_insn_group_barriers (insns); } @@ -2916,7 +3018,8 @@ ia64_encode_section_info (decl) /* Careful not to prod global register variables. */ if (TREE_CODE (decl) != VAR_DECL - || GET_CODE (DECL_RTL (decl)) != SYMBOL_REF) + || GET_CODE (DECL_RTL (decl)) != MEM + || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) return; symbol_str = XSTR (XEXP (DECL_RTL (decl), 0), 0); @@ -3250,62 +3353,87 @@ struct builtin_description /* All 32 bit intrinsics that take 2 arguments. */ static struct builtin_description bdesc_2argsi[] = { - { CODE_FOR_fetch_and_add_si, "__sync_fetch_and_add_si", IA64_BUILTIN_FETCH_AND_ADD_SI, 0, 0 }, - { CODE_FOR_fetch_and_sub_si, "__sync_fetch_and_sub_si", IA64_BUILTIN_FETCH_AND_SUB_SI, 0, 0 }, - { CODE_FOR_fetch_and_or_si, "__sync_fetch_and_or_si", IA64_BUILTIN_FETCH_AND_OR_SI, 0, 0 }, - { CODE_FOR_fetch_and_and_si, "__sync_fetch_and_and_si", IA64_BUILTIN_FETCH_AND_AND_SI, 0, 0 }, - { CODE_FOR_fetch_and_xor_si, "__sync_fetch_and_xor_si", IA64_BUILTIN_FETCH_AND_XOR_SI, 0, 0 }, - { CODE_FOR_fetch_and_nand_si, "__sync_fetch_and_nand_si", IA64_BUILTIN_FETCH_AND_NAND_SI, 0, 0 }, - { CODE_FOR_add_and_fetch_si, "__sync_add_and_fetch_si", IA64_BUILTIN_ADD_AND_FETCH_SI, 0, 0 }, - { CODE_FOR_sub_and_fetch_si, "__sync_sub_and_fetch_si", IA64_BUILTIN_SUB_AND_FETCH_SI, 0, 0 }, - { CODE_FOR_or_and_fetch_si, "__sync_or_and_fetch_si", IA64_BUILTIN_OR_AND_FETCH_SI, 0, 0 }, - { CODE_FOR_and_and_fetch_si, "__sync_and_and_fetch_si", IA64_BUILTIN_AND_AND_FETCH_SI, 0, 0 }, - { CODE_FOR_xor_and_fetch_si, "__sync_xor_and_fetch_si", IA64_BUILTIN_XOR_AND_FETCH_SI, 0, 0 }, - { CODE_FOR_nand_and_fetch_si, "__sync_nand_and_fetch_si", IA64_BUILTIN_NAND_AND_FETCH_SI, 0, 0 } + { CODE_FOR_fetch_and_add_si, "__sync_fetch_and_add_si", + IA64_BUILTIN_FETCH_AND_ADD_SI, 0, 0 }, + { CODE_FOR_fetch_and_sub_si, "__sync_fetch_and_sub_si", + IA64_BUILTIN_FETCH_AND_SUB_SI, 0, 0 }, + { CODE_FOR_fetch_and_or_si, "__sync_fetch_and_or_si", + IA64_BUILTIN_FETCH_AND_OR_SI, 0, 0 }, + { CODE_FOR_fetch_and_and_si, "__sync_fetch_and_and_si", + IA64_BUILTIN_FETCH_AND_AND_SI, 0, 0 }, + { CODE_FOR_fetch_and_xor_si, "__sync_fetch_and_xor_si", + IA64_BUILTIN_FETCH_AND_XOR_SI, 0, 0 }, + { CODE_FOR_fetch_and_nand_si, "__sync_fetch_and_nand_si", + IA64_BUILTIN_FETCH_AND_NAND_SI, 0, 0 }, + { CODE_FOR_add_and_fetch_si, "__sync_add_and_fetch_si", + IA64_BUILTIN_ADD_AND_FETCH_SI, 0, 0 }, + { CODE_FOR_sub_and_fetch_si, "__sync_sub_and_fetch_si", + IA64_BUILTIN_SUB_AND_FETCH_SI, 0, 0 }, + { CODE_FOR_or_and_fetch_si, "__sync_or_and_fetch_si", + IA64_BUILTIN_OR_AND_FETCH_SI, 0, 0 }, + { CODE_FOR_and_and_fetch_si, "__sync_and_and_fetch_si", + IA64_BUILTIN_AND_AND_FETCH_SI, 0, 0 }, + { CODE_FOR_xor_and_fetch_si, "__sync_xor_and_fetch_si", + IA64_BUILTIN_XOR_AND_FETCH_SI, 0, 0 }, + { CODE_FOR_nand_and_fetch_si, "__sync_nand_and_fetch_si", + IA64_BUILTIN_NAND_AND_FETCH_SI, 0, 0 } }; /* All 64 bit intrinsics that take 2 arguments. */ static struct builtin_description bdesc_2argdi[] = { - { CODE_FOR_fetch_and_add_di, "__sync_fetch_and_add_di", IA64_BUILTIN_FETCH_AND_ADD_DI, 0, 0 }, - { CODE_FOR_fetch_and_sub_di, "__sync_fetch_and_sub_di", IA64_BUILTIN_FETCH_AND_SUB_DI, 0, 0 }, - { CODE_FOR_fetch_and_or_di, "__sync_fetch_and_or_di", IA64_BUILTIN_FETCH_AND_OR_DI, 0, 0 }, - { CODE_FOR_fetch_and_and_di, "__sync_fetch_and_and_di", IA64_BUILTIN_FETCH_AND_AND_DI, 0, 0 }, - { CODE_FOR_fetch_and_xor_di, "__sync_fetch_and_xor_di", IA64_BUILTIN_FETCH_AND_XOR_DI, 0, 0 }, - { CODE_FOR_fetch_and_nand_di, "__sync_fetch_and_nand_di", IA64_BUILTIN_FETCH_AND_NAND_DI, 0, 0 }, - { CODE_FOR_add_and_fetch_di, "__sync_add_and_fetch_di", IA64_BUILTIN_ADD_AND_FETCH_DI, 0, 0 }, - { CODE_FOR_sub_and_fetch_di, "__sync_sub_and_fetch_di", IA64_BUILTIN_SUB_AND_FETCH_DI, 0, 0 }, - { CODE_FOR_or_and_fetch_di, "__sync_or_and_fetch_di", IA64_BUILTIN_OR_AND_FETCH_DI, 0, 0 }, - { CODE_FOR_and_and_fetch_di, "__sync_and_and_fetch_di", IA64_BUILTIN_AND_AND_FETCH_DI, 0, 0 }, - { CODE_FOR_xor_and_fetch_di, "__sync_xor_and_fetch_di", IA64_BUILTIN_XOR_AND_FETCH_DI, 0, 0 }, - { CODE_FOR_nand_and_fetch_di, "__sync_nand_and_fetch_di", IA64_BUILTIN_NAND_AND_FETCH_DI, 0, 0 } + { CODE_FOR_fetch_and_add_di, "__sync_fetch_and_add_di", + IA64_BUILTIN_FETCH_AND_ADD_DI, 0, 0 }, + { CODE_FOR_fetch_and_sub_di, "__sync_fetch_and_sub_di", + IA64_BUILTIN_FETCH_AND_SUB_DI, 0, 0 }, + { CODE_FOR_fetch_and_or_di, "__sync_fetch_and_or_di", + IA64_BUILTIN_FETCH_AND_OR_DI, 0, 0 }, + { CODE_FOR_fetch_and_and_di, "__sync_fetch_and_and_di", + IA64_BUILTIN_FETCH_AND_AND_DI, 0, 0 }, + { CODE_FOR_fetch_and_xor_di, "__sync_fetch_and_xor_di", + IA64_BUILTIN_FETCH_AND_XOR_DI, 0, 0 }, + { CODE_FOR_fetch_and_nand_di, "__sync_fetch_and_nand_di", + IA64_BUILTIN_FETCH_AND_NAND_DI, 0, 0 }, + { CODE_FOR_add_and_fetch_di, "__sync_add_and_fetch_di", + IA64_BUILTIN_ADD_AND_FETCH_DI, 0, 0 }, + { CODE_FOR_sub_and_fetch_di, "__sync_sub_and_fetch_di", + IA64_BUILTIN_SUB_AND_FETCH_DI, 0, 0 }, + { CODE_FOR_or_and_fetch_di, "__sync_or_and_fetch_di", + IA64_BUILTIN_OR_AND_FETCH_DI, 0, 0 }, + { CODE_FOR_and_and_fetch_di, "__sync_and_and_fetch_di", + IA64_BUILTIN_AND_AND_FETCH_DI, 0, 0 }, + { CODE_FOR_xor_and_fetch_di, "__sync_xor_and_fetch_di", + IA64_BUILTIN_XOR_AND_FETCH_DI, 0, 0 }, + { CODE_FOR_nand_and_fetch_di, "__sync_nand_and_fetch_di", + IA64_BUILTIN_NAND_AND_FETCH_DI, 0, 0 } }; void ia64_init_builtins () { - int i; - struct builtin_description *d; + size_t i; tree psi_type_node = build_pointer_type (integer_type_node); tree pdi_type_node = build_pointer_type (long_integer_type_node); tree endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE); - /* __sync_val_compare_and_swap_si, __sync_bool_compare_and_swap_si */ tree si_ftype_psi_si_si = build_function_type (integer_type_node, tree_cons (NULL_TREE, psi_type_node, tree_cons (NULL_TREE, integer_type_node, - tree_cons (NULL_TREE, integer_type_node, + tree_cons (NULL_TREE, + integer_type_node, endlink)))); /* __sync_val_compare_and_swap_di, __sync_bool_compare_and_swap_di */ tree di_ftype_pdi_di_di = build_function_type (long_integer_type_node, tree_cons (NULL_TREE, pdi_type_node, - tree_cons (NULL_TREE, long_integer_type_node, - tree_cons (NULL_TREE, long_integer_type_node, + tree_cons (NULL_TREE, + long_integer_type_node, + tree_cons (NULL_TREE, + long_integer_type_node, endlink)))); /* __sync_synchronize */ tree void_ftype_void @@ -3321,45 +3449,59 @@ ia64_init_builtins () tree di_ftype_pdi_di = build_function_type (long_integer_type_node, tree_cons (NULL_TREE, pdi_type_node, - tree_cons (NULL_TREE, long_integer_type_node, endlink))); + tree_cons (NULL_TREE, long_integer_type_node, + endlink))); /* __sync_lock_release_si */ tree void_ftype_psi - = build_function_type (void_type_node, tree_cons (NULL_TREE, psi_type_node, endlink)); + = build_function_type (void_type_node, tree_cons (NULL_TREE, psi_type_node, + endlink)); /* __sync_lock_release_di */ tree void_ftype_pdi - = build_function_type (void_type_node, tree_cons (NULL_TREE, pdi_type_node, endlink)); + = build_function_type (void_type_node, tree_cons (NULL_TREE, pdi_type_node, + endlink)); - def_builtin ("__sync_val_compare_and_swap_si", si_ftype_psi_si_si, IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI); + def_builtin ("__sync_val_compare_and_swap_si", si_ftype_psi_si_si, + IA64_BUILTIN_VAL_COMPARE_AND_SWAP_SI); - def_builtin ("__sync_val_compare_and_swap_di", di_ftype_pdi_di_di, IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI); + def_builtin ("__sync_val_compare_and_swap_di", di_ftype_pdi_di_di, + IA64_BUILTIN_VAL_COMPARE_AND_SWAP_DI); - def_builtin ("__sync_bool_compare_and_swap_si", si_ftype_psi_si_si, IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI); + def_builtin ("__sync_bool_compare_and_swap_si", si_ftype_psi_si_si, + IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_SI); - def_builtin ("__sync_bool_compare_and_swap_di", di_ftype_pdi_di_di, IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI); + def_builtin ("__sync_bool_compare_and_swap_di", di_ftype_pdi_di_di, + IA64_BUILTIN_BOOL_COMPARE_AND_SWAP_DI); - def_builtin ("__sync_synchronize", void_ftype_void, IA64_BUILTIN_SYNCHRONIZE); + def_builtin ("__sync_synchronize", void_ftype_void, + IA64_BUILTIN_SYNCHRONIZE); - def_builtin ("__sync_lock_test_and_set_si", si_ftype_psi_si, IA64_BUILTIN_LOCK_TEST_AND_SET_SI); + def_builtin ("__sync_lock_test_and_set_si", si_ftype_psi_si, + IA64_BUILTIN_LOCK_TEST_AND_SET_SI); - def_builtin ("__sync_lock_test_and_set_di", di_ftype_pdi_di, IA64_BUILTIN_LOCK_TEST_AND_SET_DI); + def_builtin ("__sync_lock_test_and_set_di", di_ftype_pdi_di, + IA64_BUILTIN_LOCK_TEST_AND_SET_DI); - def_builtin ("__sync_lock_release_si", void_ftype_psi, IA64_BUILTIN_LOCK_RELEASE_SI); + def_builtin ("__sync_lock_release_si", void_ftype_psi, + IA64_BUILTIN_LOCK_RELEASE_SI); - def_builtin ("__sync_lock_release_di", void_ftype_pdi, IA64_BUILTIN_LOCK_RELEASE_DI); + def_builtin ("__sync_lock_release_di", void_ftype_pdi, + IA64_BUILTIN_LOCK_RELEASE_DI); - def_builtin ("__builtin_ia64_bsp", build_function_type (ptr_type_node, endlink), IA64_BUILTIN_BSP); + def_builtin ("__builtin_ia64_bsp", + build_function_type (ptr_type_node, endlink), + IA64_BUILTIN_BSP); def_builtin ("__builtin_ia64_flushrs", build_function_type (void_type_node, endlink), IA64_BUILTIN_FLUSHRS); /* Add all builtins that are operations on two args. */ - for (i=0, d = bdesc_2argsi; i < sizeof(bdesc_2argsi) / sizeof *d; i++, d++) - def_builtin (d->name, si_ftype_psi_si, d->code); - for (i=0, d = bdesc_2argdi; i < sizeof(bdesc_2argdi) / sizeof *d; i++, d++) - def_builtin (d->name, di_ftype_pdi_di, d->code); + for (i = 0; i < sizeof(bdesc_2argsi) / sizeof *bdesc_2argsi; i++) + def_builtin (bdesc_2argsi[i].name, si_ftype_psi_si, bdesc_2argsi[i].code); + for (i = 0; i < sizeof(bdesc_2argdi) / sizeof *bdesc_2argdi; i++) + def_builtin (bdesc_2argdi[i].name, si_ftype_psi_si, bdesc_2argdi[i].code); } /* Expand fetch_and_op intrinsics. The basic code sequence is: @@ -3679,7 +3821,7 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore) int fcode = DECL_FUNCTION_CODE (fndecl); enum machine_mode tmode, mode0, mode1; enum insn_code icode; - int i; + size_t i; struct builtin_description *d; switch (fcode) @@ -3705,7 +3847,7 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore) tmp_reg = gen_rtx_REG (DImode, GR_REG(0)); target = gen_rtx_MEM (BLKmode, tmp_reg); emit_insn (gen_mf (target)); - return 0; + return const0_rtx; case IA64_BUILTIN_LOCK_TEST_AND_SET_SI: icode = CODE_FOR_lock_test_and_set_si; @@ -3759,7 +3901,7 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore) op0 = gen_rtx_MEM (SImode, copy_to_mode_reg (Pmode, op0)); MEM_VOLATILE_P (op0) = 1; emit_insn (gen_movsi (op0, GEN_INT(0))); - return 0; + return const0_rtx; case IA64_BUILTIN_LOCK_RELEASE_DI: arg0 = TREE_VALUE (arglist); @@ -3767,7 +3909,7 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore) op0 = gen_rtx_MEM (DImode, copy_to_mode_reg (Pmode, op0)); MEM_VOLATILE_P (op0) = 1; emit_insn (gen_movdi (op0, GEN_INT(0))); - return 0; + return const0_rtx; case IA64_BUILTIN_BSP: { @@ -3777,10 +3919,8 @@ ia64_expand_builtin (exp, target, subtarget, mode, ignore) } case IA64_BUILTIN_FLUSHRS: - { - emit_insn (gen_flushrs ()); - return 0; - } + emit_insn (gen_flushrs ()); + return const0_rtx; default: break; diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 0dadc512f56..9dd28957ef3 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -238,10 +238,10 @@ extern const char *ia64_fixed_range_string; #if ((TARGET_CPU_DEFAULT | TARGET_DEFAULT) & MASK_GNU_AS) != 0 /* GNU AS. */ -#define ASM_SPEC "%{mno-gnu-as:-N so}" +#define ASM_SPEC "%{mno-gnu-as:-N so}%{!mno-gnu-as: -x}" #else /* Intel ias. */ -#define ASM_SPEC "%{!mgnu-as:-N so}" +#define ASM_SPEC "%{!mgnu-as:-N so}%{mgnu-as: -x}" #endif /* A C string constant that tells the GNU CC driver program options to pass to @@ -543,8 +543,8 @@ while (0) #define FIRST_PSEUDO_REGISTER 330 /* Ranges for the various kinds of registers. */ -#define ADDL_REGNO_P(REGNO) ((REGNO) >= 0 && (REGNO) <= 3) -#define GR_REGNO_P(REGNO) ((REGNO) >= 0 && (REGNO) <= 127) +#define ADDL_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 3) +#define GR_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 127) #define FR_REGNO_P(REGNO) ((REGNO) >= 128 && (REGNO) <= 255) #define PR_REGNO_P(REGNO) ((REGNO) >= 256 && (REGNO) <= 319) #define BR_REGNO_P(REGNO) ((REGNO) >= 320 && (REGNO) <= 327) @@ -1067,9 +1067,12 @@ enum reg_class /* A C expression that defines the optional machine-dependent constraint letters (`Q', `R', `S', `T', `U') that can be used to segregate specific types of operands, usually memory references, for the target machine. */ -/* ??? This might be useful considering that we have already used all of the - integer constant contraint letters. */ -/* #define EXTRA_CONSTRAINT(VALUE, C) */ + +#define CONSTRAINT_OK_FOR_Q(VALUE) \ + (memory_operand((VALUE), VOIDmode) && ! MEM_VOLATILE_P (VALUE)) + +#define EXTRA_CONSTRAINT(VALUE, C) \ + ((C) == 'Q' ? CONSTRAINT_OK_FOR_Q (VALUE) : 0) /* Basic Stack Layout */ @@ -1460,6 +1463,11 @@ do { \ #define FUNCTION_EPILOGUE(FILE, SIZE) \ ia64_function_epilogue (FILE, SIZE) +/* Output at beginning of assembler file. */ + +#define ASM_FILE_START(FILE) \ + ia64_file_start (FILE) + /* A C compound statement that outputs the assembler code for a thunk function, used to implement C++ virtual function calls with multiple inheritance. */ diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 07adbe3be3b..90ef6a23128 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -80,6 +80,7 @@ ;; 4 pfs_restore ;; 5 set_bsp ;; 6 pr_restore +;; 7 pred.rel.mutex ;; :::::::::::::::::::: ;; :: @@ -288,8 +289,8 @@ }") (define_insn "*movdi_internal" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r, m, r,*f,*f,*f, m, r,*b") - (match_operand:DI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f, m,*f,*b,rO"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r, m,r,*f,*f,*f,Q, r,*b") + (match_operand:DI 1 "move_operand" "rO,J,i,m,rO,*f,rO,*f,Q,*f,*b,rO"))] "! memory_operand (operands[0], DImode) || ! memory_operand (operands[1], DImode)" "@ @@ -301,8 +302,8 @@ getf.sig %0 = %1 setf.sig %0 = %r1 mov %0 = %1 - ldf8%O1 %0 = %1%P1 - stf8%Q0 %0 = %1%P0 + ldf8 %0 = %1%P1 + stf8 %0 = %1%P0 mov %0 = %1 mov %0 = %r1" [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I")]) @@ -392,8 +393,8 @@ }") (define_insn "*movsf_internal" - [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f, m,*r, f,*r,*r, m") - (match_operand:SF 1 "general_operand" "fG,m,fG,fG,*r,*r, m,*r"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f, Q,*r, f,*r,*r, m") + (match_operand:SF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] "! memory_operand (operands[0], SFmode) || ! memory_operand (operands[1], SFmode)" "@ @@ -420,8 +421,8 @@ }") (define_insn "*movdf_internal" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f, m,*r, f,*r,*r, m") - (match_operand:DF 1 "general_operand" "fG,m,fG,fG,*r,*r, m,*r"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f, Q,*r, f,*r,*r, m") + (match_operand:DF 1 "general_operand" "fG,Q,fG,fG,*r,*r, m,*r"))] "! memory_operand (operands[0], DFmode) || ! memory_operand (operands[1], DFmode)" "@ @@ -447,6 +448,7 @@ operands[1] = copy_to_mode_reg (XFmode, operands[1]); }") +;; ??? There's no easy way to mind volatile acquire/release semantics. (define_insn "*movxf_internal" [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f, m") (match_operand:XF 1 "general_operand" "fG,m,fG"))] @@ -2383,71 +2385,47 @@ ;; ??? Add movXXcc patterns? -;; ??? The predicates don't match the constraints. - -;; ??? r/c/m/m and m/c/r/r alternatives make sense, but won't work until the -;; predicates are fixed, because the define_splits won't recognize them. - ;; ;; DImode if_then_else patterns. ;; -(define_insn "*cmovdi_internal" - [(set (match_operand:DI 0 "register_operand" "=r,r,m,r,r,m,r") +(define_insn_and_split "*cmovdi_internal" + [(set (match_operand:DI 0 "nonimmediate_operand" + "=r,m,*f,Q,*b,r,m,*f,Q,*b,r,m,*f,Q,*b") (if_then_else:DI (match_operator:CC 4 "predicate_operator" - [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c") + [(match_operand:CC 1 "register_operand" + "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c") (const_int 0)]) - (match_operand:DI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI") - (match_operand:DI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))] + (match_operand:DI 2 "general_operand" + "0,0,0,0,0,rim*f*b,rO,rOQ,*f,r,rim*f*b,rO,rOQ,*f,r") + (match_operand:DI 3 "general_operand" + "rim*f*b,rO,rOQ,*f,r,0,0,0,0,0,rim*f*b,rO,rOQ,*f,r")))] "" "#" - [(set_attr "type" "A,M,M,A,M,M,unknown")]) - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI - (match_operator:CC 4 "predicate_operator" - [(match_operand:CC 1 "register_operand" "") - (const_int 0)]) - (match_operand:DI 2 "reg_or_22bit_operand" "") - (match_operand:DI 3 "reg_or_22bit_operand" "")))] - "(reload_completed - && (rtx_equal_p (operands[0], operands[2]) - || rtx_equal_p (operands[0], operands[3])))" - [(cond_exec - (match_dup 4) - (set (match_dup 0) (match_dup 2)))] + "reload_completed" + [(const_int 0)] " { - if (rtx_equal_p (operands[0], operands[2])) + rtx tmp; + if (! rtx_equal_p (operands[0], operands[2])) { - operands[2] = operands[3]; - operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, - CCmode, operands[1], const0_rtx); + tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]); + tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp); + emit_insn (tmp); } -}") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI - (match_operator:CC 4 "predicate_operator" - [(match_operand:CC 1 "register_operand" "") - (const_int 0)]) - (match_operand:DI 2 "reg_or_22bit_operand" "") - (match_operand:DI 3 "reg_or_22bit_operand" "")))] - "reload_completed" - [(cond_exec - (match_dup 4) - (set (match_dup 0) (match_dup 2))) - (cond_exec - (match_dup 5) - (set (match_dup 0) (match_dup 3)))] - " -{ - operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, - CCmode, operands[1], const0_rtx); -}") + if (! rtx_equal_p (operands[0], operands[3])) + { + tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, + CCmode, operands[1], const0_rtx); + tmp = gen_rtx_COND_EXEC (VOIDmode, tmp, + gen_rtx_SET (VOIDmode, operands[0], + operands[3])); + emit_insn (tmp); + } + DONE; +}" + [(set_attr "predicable" "no")]) ;; Absolute value pattern. @@ -2461,7 +2439,8 @@ (match_operand:DI 3 "reg_or_22bit_operand" "0,rI")))] "" "#" - [(set_attr "type" "A,unknown")]) + [(set_attr "type" "A,unknown") + (set_attr "predicable" "no")]) (define_split [(set (match_operand:DI 0 "register_operand" "") @@ -2503,62 +2482,41 @@ ;; SImode if_then_else patterns. ;; -(define_insn "*cmovsi_internal" - [(set (match_operand:SI 0 "register_operand" "=r,r,m,r,r,m,r") +(define_insn_and_split "*cmovsi_internal" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,*f,r,m,*f,r,m,*f") (if_then_else:SI (match_operator:CC 4 "predicate_operator" - [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c") + [(match_operand:CC 1 "register_operand" "c,c,c,c,c,c,c,c,c") (const_int 0)]) - (match_operand:SI 2 "reg_or_22bit_operand" "0,0,0,rI,m,r,rI") - (match_operand:SI 3 "reg_or_22bit_operand" "rI,m,r,0,0,0,rI")))] + (match_operand:SI 2 "general_operand" + "0,0,0,rim*f,rO,rO,rim*f,rO,rO") + (match_operand:SI 3 "general_operand" + "rim*f,rO,rO,0,0,0,rim*f,rO,rO")))] "" "#" - [(set_attr "type" "A,M,M,A,M,M,unknown")]) - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (if_then_else:SI - (match_operator:CC 4 "predicate_operator" - [(match_operand:CC 1 "register_operand" "") - (const_int 0)]) - (match_operand:SI 2 "reg_or_22bit_operand" "") - (match_operand:SI 3 "reg_or_22bit_operand" "")))] - "(reload_completed - && (rtx_equal_p (operands[0], operands[2]) - || rtx_equal_p (operands[0], operands[3])))" - [(cond_exec - (match_dup 4) - (set (match_dup 0) (match_dup 2)))] + "reload_completed" + [(const_int 0)] " { - if (rtx_equal_p (operands[0], operands[2])) + rtx tmp; + if (! rtx_equal_p (operands[0], operands[2])) { - operands[2] = operands[3]; - operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, - CCmode, operands[1], const0_rtx); + tmp = gen_rtx_SET (VOIDmode, operands[0], operands[2]); + tmp = gen_rtx_COND_EXEC (VOIDmode, operands[4], tmp); + emit_insn (tmp); } -}") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (if_then_else:SI - (match_operator:CC 4 "predicate_operator" - [(match_operand:CC 1 "register_operand" "") - (const_int 0)]) - (match_operand:SI 2 "reg_or_22bit_operand" "") - (match_operand:SI 3 "reg_or_22bit_operand" "")))] - "reload_completed" - [(cond_exec - (match_dup 4) - (set (match_dup 0) (match_dup 2))) - (cond_exec - (match_dup 5) - (set (match_dup 0) (match_dup 3)))] - " -{ - operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, - CCmode, operands[1], const0_rtx); -}") + if (! rtx_equal_p (operands[0], operands[3])) + { + tmp = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? EQ : NE, + CCmode, operands[1], const0_rtx); + tmp = gen_rtx_COND_EXEC (VOIDmode, tmp, + gen_rtx_SET (VOIDmode, operands[0], + operands[3])); + emit_insn (tmp); + } + DONE; +}" + [(set_attr "predicable" "no")]) (define_insn "*abssi2_internal" [(set (match_operand:SI 0 "register_operand" "=r,r") @@ -2570,7 +2528,8 @@ (match_operand:SI 2 "reg_or_22bit_operand" "0,rI")))] "" "#" - [(set_attr "type" "A,unknown")]) + [(set_attr "type" "A,unknown") + (set_attr "predicable" "no")]) (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -3769,3 +3728,11 @@ (const_int 0)])] "" "(%J0)") + +(define_insn "pred_rel_mutex" + [(unspec_volatile [(match_operand:CC 0 "register_operand" "c") + (match_operand:CC 1 "register_operand" "c")] 7)] + "" + ".pred.rel.mutex %0,%1" + [(set_attr "type" "unknown") + (set_attr "predicable" "no")]) diff --git a/gcc/config/ia64/linux.h b/gcc/config/ia64/linux.h index 5108cfa8211..50e5e6f96a3 100644 --- a/gcc/config/ia64/linux.h +++ b/gcc/config/ia64/linux.h @@ -10,6 +10,7 @@ /* ??? ia64 gas doesn't accept standard svr4 assembler options? */ #undef ASM_SPEC +#define ASM_SPEC "-x" /* Define this for shared library support because it isn't in the main linux.h file. */ diff --git a/gcc/config/ia64/sysv4.h b/gcc/config/ia64/sysv4.h index 9c1c1250a92..906e66b1b03 100644 --- a/gcc/config/ia64/sysv4.h +++ b/gcc/config/ia64/sysv4.h @@ -179,14 +179,12 @@ do { \ /* ??? Unrelated, but dwarf2out.c emits unnecessary newlines after strings, may as well fix at the same time. */ -#if 0 #undef ASM_FILE_START #define ASM_FILE_START(STREAM) \ do { \ - fputs (ASM_APP_OFF, STREAM); \ output_file_directive (STREAM, main_input_filename); \ + ia64_file_start(STREAM); \ } while (0) -#endif /* Case label alignment is handled by ADDR_VEC_ALIGN now. */ @@ -228,7 +226,7 @@ do { \ /* Similarly for constant pool data. */ -extern int ia64_section_threshold; +extern unsigned int ia64_section_threshold; #undef SELECT_RTX_SECTION #define SELECT_RTX_SECTION(MODE, RTX) \ { \ -- 2.30.2