aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/alpha/alpha.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/alpha/alpha.c')
-rw-r--r--gcc/config/alpha/alpha.c110
1 files changed, 65 insertions, 45 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index d6a9f6bc661..e5ee7d8b0e5 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -1,6 +1,6 @@
/* Subroutines used for code generation on the DEC Alpha.
Copyright (C) 1992, 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.
@@ -148,7 +148,7 @@ static rtx alpha_expand_builtin
PARAMS ((tree, rtx, rtx, enum machine_mode, int));
static void alpha_sa_mask
PARAMS ((unsigned long *imaskP, unsigned long *fmaskP));
-static int find_lo_sum
+static int find_lo_sum_using_gp
PARAMS ((rtx *, void *));
static int alpha_does_function_need_gp
PARAMS ((void));
@@ -501,6 +501,9 @@ override_options ()
warning ("trap mode not supported for VAX floats");
alpha_fptm = ALPHA_FPTM_SU;
}
+ if (target_flags_explicit & MASK_LONG_DOUBLE_128)
+ warning ("128-bit long double not supported for VAX floats");
+ target_flags &= ~MASK_LONG_DOUBLE_128;
}
{
@@ -1205,9 +1208,12 @@ tls_symbolic_operand_1 (op, mode, size, unspec)
else
return 0;
- letter = (unspec == UNSPEC_DTPREL ? 'D' : 'T');
-
- return str[1] == letter;
+ if (unspec == UNSPEC_DTPREL)
+ return str[1] == 'D';
+ else if (str[1] == 'I')
+ return size == 64;
+ else
+ return str[1] == 'T';
}
/* Return true if OP is valid for 16-bit DTP relative relocations. */
@@ -1762,7 +1768,7 @@ tls_symbolic_operand_type (symbol)
attribute visibility next time. At least we don't crash... */
if (str[1] == 'G' || str[1] == 'D')
return TLS_MODEL_GLOBAL_DYNAMIC;
- if (str[1] == 'T')
+ if (str[1] == 'I' || str[1] == 'T')
return TLS_MODEL_INITIAL_EXEC;
}
else if (str[0] == '@')
@@ -1776,6 +1782,8 @@ tls_symbolic_operand_type (symbol)
else
return TLS_MODEL_GLOBAL_DYNAMIC;
}
+ if (str[1] == 'I')
+ return TLS_MODEL_INITIAL_EXEC;
if (str[1] == 'T')
{
/* 64-bit local exec is the same as initial exec except without
@@ -1817,6 +1825,10 @@ alpha_in_small_data_p (exp)
if (TREE_CODE (exp) == STRING_CST)
return false;
+ /* Functions are never in the small data area. Duh. */
+ if (TREE_CODE (exp) == FUNCTION_DECL)
+ return false;
+
if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
{
const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
@@ -1901,6 +1913,8 @@ alpha_encode_section_info (decl, first)
encoding = 'D';
break;
case TLS_MODEL_INITIAL_EXEC:
+ encoding = 'I';
+ break;
case TLS_MODEL_LOCAL_EXEC:
encoding = 'T';
break;
@@ -1920,18 +1934,22 @@ alpha_encode_section_info (decl, first)
{
char *newstr;
size_t len;
+ char want_prefix = (is_local ? '@' : '%');
+ char other_prefix = (is_local ? '%' : '@');
- if (symbol_str[0] == (is_local ? '@' : '%'))
+ if (symbol_str[0] == want_prefix)
{
if (symbol_str[1] == encoding)
return;
symbol_str += 2;
}
+ else if (symbol_str[0] == other_prefix)
+ symbol_str += 2;
len = strlen (symbol_str) + 1;
newstr = alloca (len + 2);
- newstr[0] = (is_local ? '@' : '%');
+ newstr[0] = want_prefix;
newstr[1] = encoding;
memcpy (newstr + 2, symbol_str, len);
@@ -2945,12 +2963,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))
{
@@ -3011,7 +3025,7 @@ alpha_expand_mov (mode, operands)
}
/* Otherwise we've nothing left but to drop the thing to memory. */
- operands[1] = force_const_mem (DImode, operands[1]);
+ operands[1] = force_const_mem (mode, operands[1]);
if (reload_in_progress)
{
emit_move_insn (operands[0], XEXP (operands[1], 0));
@@ -3332,10 +3346,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;
@@ -5385,7 +5399,7 @@ alpha_gp_save_rtx ()
{
rtx r = get_hard_reg_initial_val (DImode, 29);
if (GET_CODE (r) != MEM)
- r = gen_mem_addressof (r, NULL_TREE);
+ r = gen_mem_addressof (r, NULL_TREE, /*rescan=*/true);
return r;
}
@@ -6241,12 +6255,15 @@ alpha_va_start (valist, nextarg)
If no integer registers need be stored, then we must subtract 48
in order to account for the integer arg registers which are counted
- in argsize above, but which are not actually stored on the stack. */
+ in argsize above, but which are not actually stored on the stack.
+ Must further be careful here about structures straddling the last
+ integer argument register; that futzes with pretend_args_size,
+ which changes the meaning of AP. */
if (NUM_ARGS <= 6)
offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
else
- offset = -6 * UNITS_PER_WORD;
+ offset = -6 * UNITS_PER_WORD + current_function_pretend_args_size;
if (TARGET_ABI_OPEN_VMS)
{
@@ -6741,14 +6758,16 @@ 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;
+ }
+ }
+
/* 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. */
@@ -6890,11 +6909,18 @@ const struct attribute_spec vms_attribute_table[] =
#endif
static int
-find_lo_sum (px, data)
+find_lo_sum_using_gp (px, data)
rtx *px;
void *data ATTRIBUTE_UNUSED;
{
- return GET_CODE (*px) == LO_SUM;
+ return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
+}
+
+int
+alpha_find_lo_sum_using_gp (insn)
+ rtx insn;
+{
+ return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
}
static int
@@ -6923,15 +6949,9 @@ alpha_does_function_need_gp ()
for (; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn)
&& GET_CODE (PATTERN (insn)) != USE
- && GET_CODE (PATTERN (insn)) != CLOBBER)
- {
- enum attr_type type = get_attr_type (insn);
- if (type == TYPE_LDSYM || type == TYPE_JSR)
- return 1;
- if (TARGET_EXPLICIT_RELOCS
- && for_each_rtx (&PATTERN (insn), find_lo_sum, NULL) > 0)
- return 1;
- }
+ && GET_CODE (PATTERN (insn)) != CLOBBER
+ && get_attr_usegp (insn))
+ return 1;
return 0;
}
@@ -7202,7 +7222,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));
@@ -7211,7 +7231,7 @@ alpha_expand_prologue ()
reg_offset += 8;
}
- for (i = 0; i < 32; i++)
+ for (i = 0; i < 31; i++)
if (fmask & (1L << i))
{
mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset));
@@ -7617,7 +7637,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)
@@ -7631,7 +7651,7 @@ alpha_expand_epilogue ()
reg_offset += 8;
}
- for (i = 0; i < 32; ++i)
+ for (i = 0; i < 31; ++i)
if (fmask & (1L << i))
{
mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));