aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>2000-06-18 11:54:43 -0700
committerRichard Henderson <rth@gcc.gnu.org>2000-06-18 11:54:43 -0700
commit3b572406c28259bb8dbc1767937bcd965a64b18e (patch)
tree0d265c79e3b4883fed53bfec770ed8a0ab59adf5
parent5538e30f194c64edaae424688e28a2064902fa1a (diff)
downloadgcc-3b572406c28259bb8dbc1767937bcd965a64b18e.zip
gcc-3b572406c28259bb8dbc1767937bcd965a64b18e.tar.gz
gcc-3b572406c28259bb8dbc1767937bcd965a64b18e.tar.bz2
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
-rw-r--r--gcc/ChangeLog35
-rw-r--r--gcc/config/ia64/ia64-protos.h2
-rw-r--r--gcc/config/ia64/ia64.c278
-rw-r--r--gcc/config/ia64/ia64.h22
-rw-r--r--gcc/config/ia64/ia64.md185
-rw-r--r--gcc/config/ia64/linux.h1
-rw-r--r--gcc/config/ia64/sysv4.h6
7 files changed, 340 insertions, 189 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 855bd64..efd8221 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,38 @@
+2000-06-18 Richard Henderson <rth@cygnus.com>
+
+ * 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 <ghazi@caip.rutgers.edu>
* 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 7c4c5fa..dcfe8cc 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 dca06cd..66f928b 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 0dadc51..9dd2895 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 07adbe3..90ef6a23 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 5108cfa..50e5e6f 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 9c1c125..906e66b 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) \
{ \