/* Definitions of target machine for GNU compiler,
for powerpc machines running Linux.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation,
- Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
+ Free Software Foundation, Inc.
Contributed by Michael Meissner (meissner@cygnus.com).
This file is part of GNU CC.
long new_cfa_; \
int i_; \
\
- /* li r0, 0x7777; sc (rt_sigreturn) */ \
- /* li r0, 0x6666; sc (sigreturn) */ \
- if (((*(unsigned int *) (pc_+0) == 0x38007777) \
- || (*(unsigned int *) (pc_+0) == 0x38006666)) \
- && (*(unsigned int *) (pc_+4) == 0x44000002)) \
- sc_ = (CONTEXT)->cfa + SIGNAL_FRAMESIZE; \
+ /* li r0, 0x7777; sc (sigreturn old) */ \
+ /* li r0, 0x0077; sc (sigreturn new) */ \
+ /* li r0, 0x6666; sc (rt_sigreturn old) */ \
+ /* li r0, 0x00AC; sc (rt_sigreturn new) */ \
+ if (*(unsigned int *) (pc_+4) != 0x44000002) \
+ break; \
+ if (*(unsigned int *) (pc_+0) == 0x38007777 \
+ || *(unsigned int *) (pc_+0) == 0x38000077) \
+ { \
+ struct sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ struct sigcontext sigctx; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->sigctx; \
+ } \
+ else if (*(unsigned int *) (pc_+0) == 0x38006666 \
+ || *(unsigned int *) (pc_+0) == 0x380000AC) \
+ { \
+ struct rt_sigframe { \
+ char gap[SIGNAL_FRAMESIZE]; \
+ unsigned long _unused[2]; \
+ struct siginfo *pinfo; \
+ void *puc; \
+ struct siginfo info; \
+ struct ucontext uc; \
+ } *rt_ = (CONTEXT)->cfa; \
+ sc_ = &rt_->uc.uc_mcontext; \
+ } \
else \
break; \
\
\
/* The unwinder expects the IP to point to the following insn, \
whereas the kernel returns the address of the actual \
- faulting insn. */ \
- sc_->regs->nip += 4; \
+ faulting insn. We store NIP+4 in an unused register slot to \
+ get the same result for multiple evaluation of the same signal \
+ frame. */ \
+ sc_->regs->gpr[47] = sc_->regs->nip + 4; \
(FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET; \
(FS)->regs.reg[CR0_REGNO].loc.offset \
- = (long)&(sc_->regs->nip) - new_cfa_; \
+ = (long)&(sc_->regs->gpr[47]) - new_cfa_; \
(FS)->retaddr_column = CR0_REGNO; \
goto SUCCESS; \
} while (0)
/* Subroutines used for code generation on IBM RS/6000.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
This file is part of GNU CC.
#ifdef OBJECT_FORMAT_COFF
static void xcoff_asm_named_section PARAMS ((const char *, unsigned int));
#endif
+static bool rs6000_binds_local_p PARAMS ((tree));
static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
static int rs6000_adjust_priority PARAMS ((rtx, int));
static int rs6000_issue_rate PARAMS ((void));
DECL_SECTION_NAME (decl) = build_string (len, string);
}
-\f
+
+static bool
+rs6000_binds_local_p (exp)
+ tree exp;
+{
+ bool local_p;
+ tree attr;
+
+ /* A non-decl is an entry in the constant pool. */
+ if (!DECL_P (exp))
+ local_p = true;
+ /* Static variables are always local. */
+ else if (! TREE_PUBLIC (exp))
+ local_p = true;
+ /* Otherwise, variables defined outside this object may not be local. */
+ else if (DECL_EXTERNAL (exp))
+ local_p = false;
+ /* Linkonce and weak data are never local. */
+ else if (DECL_ONE_ONLY (exp) || DECL_WEAK (exp))
+ local_p = false;
+ /* If PIC, then assume that any global name can be overridden by
+ * symbols resolved from other modules. */
+ else if (flag_pic || rs6000_flag_pic)
+ local_p = false;
+ /* Uninitialized COMMON variable may be unified with symbols
+ * resolved from other modules. */
+ else if (DECL_COMMON (exp)
+ && (DECL_INITIAL (exp) == NULL
+ || DECL_INITIAL (exp) == error_mark_node))
+ local_p = false;
+ /* Otherwise we're left with initialized (or non-common) global data
+ * which is of necessity defined locally. */
+ else
+ local_p = true;
+
+ return local_p;
+}
+
+
/* If we are referencing a function that is static or is known to be
in this file, make the SYMBOL_REF special. We can use this to indicate
that we can branch to this function without emitting a no-op after the
if (TREE_CODE (decl) == FUNCTION_DECL)
{
rtx sym_ref = XEXP (DECL_RTL (decl), 0);
- if (!TREE_PUBLIC (decl)
- || (!DECL_EXTERNAL (decl)
- && !DECL_ONE_ONLY (decl)
- && !DECL_WEAK (decl)
- && !flag_pic
- && !rs6000_flag_pic))
+ if (rs6000_binds_local_p (decl))
SYMBOL_REF_FLAG (sym_ref) = 1;
if (DEFAULT_ABI == ABI_AIX)
&& DEFAULT_ABI == ABI_V4
&& TREE_CODE (decl) == VAR_DECL)
{
+ rtx sym_ref = XEXP (DECL_RTL (decl), 0);
int size = int_size_in_bytes (TREE_TYPE (decl));
tree section_name = DECL_SECTION_NAME (decl);
const char *name = (char *)0;
int len = 0;
+ if (rs6000_binds_local_p (decl))
+ SYMBOL_REF_FLAG (sym_ref) = 1;
+
if (section_name)
{
if (TREE_CODE (section_name) == STRING_CST)