summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/alpha
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/config/alpha')
-rw-r--r--contrib/gcc/config/alpha/alpha.c68
-rw-r--r--contrib/gcc/config/alpha/alpha.h1
-rw-r--r--contrib/gcc/config/alpha/alpha.md2
-rw-r--r--contrib/gcc/config/alpha/linux.h11
4 files changed, 56 insertions, 26 deletions
diff --git a/contrib/gcc/config/alpha/alpha.c b/contrib/gcc/config/alpha/alpha.c
index 9657e56..42b57e1 100644
--- a/contrib/gcc/config/alpha/alpha.c
+++ b/contrib/gcc/config/alpha/alpha.c
@@ -2949,12 +2949,8 @@ alpha_expand_mov (mode, operands)
compiled at the end of compilation. In the meantime, someone can
re-encode-section-info on some symbol changing it e.g. from global
to local-not-small. If this happens, we'd have emitted a plain
- load rather than a high+losum load and not recognize the insn.
-
- So if rtl inlining is in effect, we delay the global/not-global
- decision until rest_of_compilation by wrapping it in an
- UNSPEC_SYMBOL. */
- if (TARGET_EXPLICIT_RELOCS && flag_inline_functions
+ load rather than a high+losum load and not recognize the insn. */
+ if (TARGET_EXPLICIT_RELOCS
&& rtx_equal_function_value_matters
&& global_symbolic_operand (operands[1], mode))
{
@@ -3336,10 +3332,10 @@ alpha_emit_conditional_branch (code)
if (op1 == const0_rtx)
cmp_code = NIL, branch_code = code;
- /* We want to use cmpcc/bcc when we can, since there is a zero delay
- bypass between logicals and br/cmov on EV5. But we don't want to
- force valid immediate constants into registers needlessly. */
- else if (GET_CODE (op1) == CONST_INT)
+ /* If the constants doesn't fit into an immediate, but can
+ be generated by lda/ldah, we adjust the argument and
+ compare against zero, so we can use beq/bne directly. */
+ else if (GET_CODE (op1) == CONST_INT && (code == EQ || code == NE))
{
HOST_WIDE_INT v = INTVAL (op1), n = -v;
@@ -6748,14 +6744,21 @@ alpha_sa_mask (imaskP, fmaskP)
/* We need to restore these for the handler. */
if (current_function_calls_eh_return)
- for (i = 0; ; ++i)
- {
- unsigned regno = EH_RETURN_DATA_REGNO (i);
- if (regno == INVALID_REGNUM)
- break;
- imask |= 1L << regno;
- }
-
+ {
+ for (i = 0; ; ++i)
+ {
+ unsigned regno = EH_RETURN_DATA_REGNO (i);
+ if (regno == INVALID_REGNUM)
+ break;
+ imask |= 1L << regno;
+ }
+
+ /* Glibc likes to use $31 as an unwind stopper for crt0. To
+ avoid hackery in unwind-dw2.c, we need to actively store a
+ zero in the prologue of _Unwind_RaiseException et al. */
+ imask |= 1UL << 31;
+ }
+
/* If any register spilled, then spill the return address also. */
/* ??? This is required by the Digital stack unwind specification
and isn't needed if we're doing Dwarf2 unwinding. */
@@ -7210,7 +7213,7 @@ alpha_expand_prologue ()
}
/* Now save any other registers required to be saved. */
- for (i = 0; i < 32; i++)
+ for (i = 0; i < 31; i++)
if (imask & (1L << i))
{
mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
@@ -7219,7 +7222,25 @@ alpha_expand_prologue ()
reg_offset += 8;
}
- for (i = 0; i < 32; i++)
+ /* Store a zero if requested for unwinding. */
+ if (imask & (1UL << 31))
+ {
+ rtx insn, t;
+
+ mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
+ set_mem_alias_set (mem, alpha_sr_alias_set);
+ insn = emit_move_insn (mem, const0_rtx);
+
+ RTX_FRAME_RELATED_P (insn) = 1;
+ t = gen_rtx_REG (Pmode, 31);
+ t = gen_rtx_SET (VOIDmode, mem, t);
+ t = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, t, REG_NOTES (insn));
+ REG_NOTES (insn) = t;
+
+ reg_offset += 8;
+ }
+
+ for (i = 0; i < 31; i++)
if (fmask & (1L << i))
{
mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
@@ -7625,7 +7646,7 @@ alpha_expand_epilogue ()
reg_offset += 8;
imask &= ~(1L << REG_RA);
- for (i = 0; i < 32; ++i)
+ for (i = 0; i < 31; ++i)
if (imask & (1L << i))
{
if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
@@ -7639,7 +7660,10 @@ alpha_expand_epilogue ()
reg_offset += 8;
}
- for (i = 0; i < 32; ++i)
+ if (imask & (1UL << 31))
+ reg_offset += 8;
+
+ for (i = 0; i < 31; ++i)
if (fmask & (1L << i))
{
mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
diff --git a/contrib/gcc/config/alpha/alpha.h b/contrib/gcc/config/alpha/alpha.h
index b933ea3..6b52700 100644
--- a/contrib/gcc/config/alpha/alpha.h
+++ b/contrib/gcc/config/alpha/alpha.h
@@ -1276,6 +1276,7 @@ do { \
/* Before the prologue, RA lives in $26. */
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26)
#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (26)
+#define DWARF_ALT_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (64)
/* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 16 : INVALID_REGNUM)
diff --git a/contrib/gcc/config/alpha/alpha.md b/contrib/gcc/config/alpha/alpha.md
index a4c0ae6..f7e9fa4 100644
--- a/contrib/gcc/config/alpha/alpha.md
+++ b/contrib/gcc/config/alpha/alpha.md
@@ -5399,7 +5399,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
UNSPEC_SYMBOL))]
- "TARGET_EXPLICIT_RELOCS && flag_inline_functions"
+ "TARGET_EXPLICIT_RELOCS"
"#"
""
[(set (match_dup 0) (match_dup 1))]
diff --git a/contrib/gcc/config/alpha/linux.h b/contrib/gcc/config/alpha/linux.h
index 0c53344..3a2940c 100644
--- a/contrib/gcc/config/alpha/linux.h
+++ b/contrib/gcc/config/alpha/linux.h
@@ -61,6 +61,9 @@ Boston, MA 02111-1307, USA. */
#define TARGET_HAS_F_SETLKW
+#define LINK_GCC_C_SEQUENCE_SPEC \
+ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
@@ -78,6 +81,8 @@ Boston, MA 02111-1307, USA. */
if (pc_[0] != 0x47fe0410 /* mov $30,$16 */ \
|| pc_[2] != 0x00000083 /* callsys */) \
break; \
+ if ((CONTEXT)->cfa == 0) \
+ break; \
if (pc_[1] == 0x201f0067) /* lda $0,NR_sigreturn */ \
sc_ = (CONTEXT)->cfa; \
else if (pc_[1] == 0x201f015f) /* lda $0,NR_rt_sigreturn */ \
@@ -106,8 +111,8 @@ Boston, MA 02111-1307, USA. */
(FS)->regs.reg[i_+32].loc.offset \
= (long)&sc_->sc_fpregs[i_] - new_cfa_; \
} \
- (FS)->regs.reg[31].how = REG_SAVED_OFFSET; \
- (FS)->regs.reg[31].loc.offset = (long)&sc_->sc_pc - new_cfa_; \
- (FS)->retaddr_column = 31; \
+ (FS)->regs.reg[64].how = REG_SAVED_OFFSET; \
+ (FS)->regs.reg[64].loc.offset = (long)&sc_->sc_pc - new_cfa_; \
+ (FS)->retaddr_column = 64; \
goto SUCCESS; \
} while (0)
OpenPOWER on IntegriCloud