summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/ia64
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2005-06-03 03:28:44 +0000
committerkan <kan@FreeBSD.org>2005-06-03 03:28:44 +0000
commit2156e40a831a8e0ab68e4bc091c2940bf46ca6df (patch)
treef0dc8ad34f9fcaf27052e24e893a4284b5fee6e9 /contrib/gcc/config/ia64
parent0a20abcc95340c9d2bb59421bac84eca4fb43b0c (diff)
downloadFreeBSD-src-2156e40a831a8e0ab68e4bc091c2940bf46ca6df.zip
FreeBSD-src-2156e40a831a8e0ab68e4bc091c2940bf46ca6df.tar.gz
Gcc 3.4.4 release.
Diffstat (limited to 'contrib/gcc/config/ia64')
-rw-r--r--contrib/gcc/config/ia64/ia64.c98
-rw-r--r--contrib/gcc/config/ia64/t-glibc4
-rw-r--r--contrib/gcc/config/ia64/t-glibc-libunwind4
-rw-r--r--contrib/gcc/config/ia64/t-hpux2
-rw-r--r--contrib/gcc/config/ia64/unwind-ia64.c23
-rw-r--r--contrib/gcc/config/ia64/unwind-ia64.h3
6 files changed, 111 insertions, 23 deletions
diff --git a/contrib/gcc/config/ia64/ia64.c b/contrib/gcc/config/ia64/ia64.c
index 19c5e92..c215b19 100644
--- a/contrib/gcc/config/ia64/ia64.c
+++ b/contrib/gcc/config/ia64/ia64.c
@@ -390,20 +390,55 @@ call_operand (rtx op, enum machine_mode mode)
int
sdata_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
+ HOST_WIDE_INT offset = 0, size = 0;
+
switch (GET_CODE (op))
{
case CONST:
- if (GET_CODE (XEXP (op, 0)) != PLUS
- || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF)
+ op = XEXP (op, 0);
+ if (GET_CODE (op) != PLUS
+ || GET_CODE (XEXP (op, 0)) != SYMBOL_REF
+ || GET_CODE (XEXP (op, 1)) != CONST_INT)
break;
- op = XEXP (XEXP (op, 0), 0);
+ offset = INTVAL (XEXP (op, 1));
+ op = XEXP (op, 0);
/* FALLTHRU */
case SYMBOL_REF:
if (CONSTANT_POOL_ADDRESS_P (op))
- return GET_MODE_SIZE (get_pool_mode (op)) <= ia64_section_threshold;
+ {
+ size = GET_MODE_SIZE (get_pool_mode (op));
+ if (size > ia64_section_threshold)
+ return false;
+ }
else
- return SYMBOL_REF_LOCAL_P (op) && SYMBOL_REF_SMALL_P (op);
+ {
+ tree t;
+
+ if (!SYMBOL_REF_LOCAL_P (op) || !SYMBOL_REF_SMALL_P (op))
+ return false;
+
+ /* Note that in addition to DECLs, we can get various forms
+ of constants here. */
+ t = SYMBOL_REF_DECL (op);
+ if (DECL_P (t))
+ t = DECL_SIZE_UNIT (t);
+ else
+ t = TYPE_SIZE_UNIT (TREE_TYPE (t));
+ if (t && host_integerp (t, 0))
+ {
+ size = tree_low_cst (t, 0);
+ if (size < 0)
+ size = 0;
+ }
+ }
+
+ /* Deny the stupid user trick of addressing outside the object. Such
+ things quickly result in GPREL22 relocation overflows. Of course,
+ they're also highly undefined. From a pure pedant's point of view
+ they deserve a slap on the wrist (such as provided by a relocation
+ overflow), but that just leads to bugzilla noise. */
+ return (offset >= 0 && offset <= size);
default:
break;
@@ -3154,10 +3189,13 @@ ia64_expand_epilogue (int sibcall_p)
preserve those input registers used as arguments to the sibling call.
It is unclear how to compute that number here. */
if (current_frame_info.n_input_regs != 0)
- emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
- GEN_INT (0), GEN_INT (0),
- GEN_INT (current_frame_info.n_input_regs),
- GEN_INT (0)));
+ {
+ rtx n_inputs = GEN_INT (current_frame_info.n_input_regs);
+ insn = emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
+ const0_rtx, const0_rtx,
+ n_inputs, const0_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
}
}
@@ -3283,15 +3321,16 @@ static bool
ia64_assemble_integer (rtx x, unsigned int size, int aligned_p)
{
if (size == POINTER_SIZE / BITS_PER_UNIT
- && aligned_p
&& !(TARGET_NO_PIC || TARGET_AUTO_PIC)
&& GET_CODE (x) == SYMBOL_REF
&& SYMBOL_REF_FUNCTION_P (x))
{
- if (POINTER_SIZE == 32)
- fputs ("\tdata4\t@fptr(", asm_out_file);
- else
- fputs ("\tdata8\t@fptr(", asm_out_file);
+ static const char * const directive[2][2] = {
+ /* 64-bit pointer */ /* 32-bit pointer */
+ { "\tdata8.ua\t@fptr(", "\tdata4.ua\t@fptr("}, /* unaligned */
+ { "\tdata8\t@fptr(", "\tdata4\t@fptr("} /* aligned */
+ };
+ fputs (directive[(aligned_p != 0)][POINTER_SIZE == 32], asm_out_file);
output_addr_const (asm_out_file, x);
fputs (")\n", asm_out_file);
return true;
@@ -3917,6 +3956,12 @@ ia64_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
static bool
ia64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
{
+ /* We can't perform a sibcall if the current function has the syscall_linkage
+ attribute. */
+ if (lookup_attribute ("syscall_linkage",
+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
+ return false;
+
/* We must always return with our current GP. This means we can
only sibcall to functions defined in the current module. */
return decl && (*targetm.binds_local_p) (decl);
@@ -7782,13 +7827,24 @@ process_set (FILE *asm_out_file, rtx pat)
{
dest_regno = REGNO (dest);
- /* If this isn't the final destination for ar.pfs, the alloc
- shouldn't have been marked frame related. */
- if (dest_regno != current_frame_info.reg_save_ar_pfs)
- abort ();
-
- fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
- ia64_dbx_register_number (dest_regno));
+ /* If this is the final destination for ar.pfs, then this must
+ be the alloc in the prologue. */
+ if (dest_regno == current_frame_info.reg_save_ar_pfs)
+ fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
+ ia64_dbx_register_number (dest_regno));
+ else
+ {
+ /* This must be an alloc before a sibcall. We must drop the
+ old frame info. The easiest way to drop the old frame
+ info is to ensure we had a ".restore sp" directive
+ followed by a new prologue. If the procedure doesn't
+ have a memory-stack frame, we'll issue a dummy ".restore
+ sp" now. */
+ if (current_frame_info.total_size == 0 && !frame_pointer_needed)
+ /* if haven't done process_epilogue() yet, do it now */
+ process_epilogue ();
+ fprintf (asm_out_file, "\t.prologue\n");
+ }
return 1;
}
diff --git a/contrib/gcc/config/ia64/t-glibc b/contrib/gcc/config/ia64/t-glibc
index a105662..df4fe9c 100644
--- a/contrib/gcc/config/ia64/t-glibc
+++ b/contrib/gcc/config/ia64/t-glibc
@@ -1 +1,3 @@
-LIB2ADDEH += $(srcdir)/config/ia64/fde-glibc.c
+# Use system libunwind library on IA-64 GLIBC based system.
+LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \
+ $(srcdir)/unwind-compat.c
diff --git a/contrib/gcc/config/ia64/t-glibc-libunwind b/contrib/gcc/config/ia64/t-glibc-libunwind
new file mode 100644
index 0000000..df78f1d
--- /dev/null
+++ b/contrib/gcc/config/ia64/t-glibc-libunwind
@@ -0,0 +1,4 @@
+# Build libunwind for IA-64 GLIBC based system.
+LIBUNWIND = $(srcdir)/config/ia64/fde-glibc.c \
+ $(srcdir)/config/ia64/unwind-ia64.c
+LIBUNWINDDEP = unwind.inc
diff --git a/contrib/gcc/config/ia64/t-hpux b/contrib/gcc/config/ia64/t-hpux
index 597c2ac..d89f174 100644
--- a/contrib/gcc/config/ia64/t-hpux
+++ b/contrib/gcc/config/ia64/t-hpux
@@ -23,6 +23,8 @@ LIBGCC1_TEST =
# We do not want to include the EH stuff that linux uses, we want to use
# the HP-UX libunwind library.
+T_CFLAGS += -DUSE_LIBUNWIND_EXCEPTIONS
+
LIB2ADDEH =
SHLIB_EXT = .so
diff --git a/contrib/gcc/config/ia64/unwind-ia64.c b/contrib/gcc/config/ia64/unwind-ia64.c
index d981d8c..a49652e 100644
--- a/contrib/gcc/config/ia64/unwind-ia64.c
+++ b/contrib/gcc/config/ia64/unwind-ia64.c
@@ -37,6 +37,7 @@
#include "tm.h"
#include "unwind.h"
#include "unwind-ia64.h"
+#include "unwind-compat.h"
#include "ia64intrin.h"
/* This isn't thread safe, but nice for occasional tests. */
@@ -2274,6 +2275,8 @@ uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
"(p6) ldf.fill f22 = [r28] \n\t"
"cmp.ne p7, p0 = r0, r29 \n\t"
";; \n\t"
+ "ld8 r27 = [r20], 8 \n\t"
+ ";; \n\t"
"ld8 r28 = [r20], 8 \n\t"
"(p7) ldf.fill f23 = [r29] \n\t"
"cmp.ne p6, p0 = r0, r22 \n\t"
@@ -2381,4 +2384,24 @@ uw_identify_context (struct _Unwind_Context *context)
}
#include "unwind.inc"
+
+#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
+alias (_Unwind_Backtrace);
+alias (_Unwind_DeleteException);
+alias (_Unwind_FindEnclosingFunction);
+alias (_Unwind_FindTableEntry);
+alias (_Unwind_ForcedUnwind);
+alias (_Unwind_GetBSP);
+alias (_Unwind_GetCFA);
+alias (_Unwind_GetGR);
+alias (_Unwind_GetIP);
+alias (_Unwind_GetLanguageSpecificData);
+alias (_Unwind_GetRegionStart);
+alias (_Unwind_RaiseException);
+alias (_Unwind_Resume);
+alias (_Unwind_Resume_or_Rethrow);
+alias (_Unwind_SetGR);
+alias (_Unwind_SetIP);
+#endif
+
#endif
diff --git a/contrib/gcc/config/ia64/unwind-ia64.h b/contrib/gcc/config/ia64/unwind-ia64.h
index b56b38c..053829f 100644
--- a/contrib/gcc/config/ia64/unwind-ia64.h
+++ b/contrib/gcc/config/ia64/unwind-ia64.h
@@ -28,4 +28,5 @@ struct unw_table_entry
extern struct unw_table_entry *
_Unwind_FindTableEntry (void *pc, unsigned long *segment_base,
- unsigned long *gp);
+ unsigned long *gp)
+ __attribute__ ((__visibility__ ("hidden")));
OpenPOWER on IntegriCloud