aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/alpha
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/alpha')
-rw-r--r--gcc/config/alpha/alpha-protos.h2
-rw-r--r--gcc/config/alpha/alpha.c46
-rw-r--r--gcc/config/alpha/alpha.h5
-rw-r--r--gcc/config/alpha/alpha.md60
-rw-r--r--gcc/config/alpha/freebsd.h6
-rw-r--r--gcc/config/alpha/linux.h2
-rw-r--r--gcc/config/alpha/osf.h34
-rw-r--r--gcc/config/alpha/t-crtfm3
-rw-r--r--gcc/config/alpha/t-osf46
9 files changed, 108 insertions, 56 deletions
diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h
index 71079eff7e8..fe4943bfeb8 100644
--- a/gcc/config/alpha/alpha-protos.h
+++ b/gcc/config/alpha/alpha-protos.h
@@ -142,6 +142,8 @@ extern rtx function_arg PARAMS ((CUMULATIVE_ARGS, enum machine_mode,
extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
extern void alpha_end_function PARAMS ((FILE *, const char *, tree));
+extern int alpha_find_lo_sum_using_gp PARAMS ((rtx));
+
#ifdef REAL_VALUE_TYPE
extern int check_float_value PARAMS ((enum machine_mode,
REAL_VALUE_TYPE *, int));
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index d6a9f6bc661..9657e56bf43 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));
@@ -1920,18 +1920,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);
@@ -3011,7 +3015,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));
@@ -5385,7 +5389,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 +6245,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)
{
@@ -6890,11 +6897,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 +6937,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;
}
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 9e39a40395b..b933ea31625 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -859,8 +859,9 @@ enum reg_class {
/* Return the class of registers that cannot change mode from FROM to TO. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS : NO_REGS)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FLOAT_REGS, CLASS) : 0)
/* Define the cost of moving between registers of various classes. Moving
between FLOAT_REGS and anything else except float regs is expensive.
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index c878366b846..a4c0ae6904d 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -1,6 +1,6 @@
;; Machine description for DEC Alpha for GNU C compiler
;; 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.
@@ -142,6 +142,18 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(define_attr "length" ""
(const_int 4))
+
+;; The USEGP attribute marks instructions that have relocations that use
+;; the GP.
+
+(define_attr "usegp" "no,yes"
+ (cond [(eq_attr "type" "ldsym,jsr")
+ (const_string "yes")
+ (eq_attr "type" "ild,fld,ist,fst")
+ (symbol_ref "alpha_find_lo_sum_using_gp(insn)")
+ ]
+ (const_string "no")))
+
;; Include scheduling descriptions.
@@ -402,7 +414,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
(plus:DI (match_operand:DI 1 "register_operand" "r")
(high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
"TARGET_EXPLICIT_RELOCS"
- "ldah %0,%2(%1)\t\t!gprelhigh")
+ "ldah %0,%2(%1)\t\t!gprelhigh"
+ [(set_attr "usegp" "yes")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -737,17 +750,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
"mulqv %r1,%2,%0"
[(set_attr "type" "imul")])
-(define_insn "umuldi3_highpart"
+(define_expand "umuldi3_highpart"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (truncate:DI
+ (lshiftrt:TI
+ (mult:TI (zero_extend:TI
+ (match_operand:DI 1 "register_operand" ""))
+ (match_operand:DI 2 "reg_or_8bit_operand" ""))
+ (const_int 64))))]
+ ""
+{
+ if (REG_P (operands[2]))
+ operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]);
+})
+
+(define_insn "*umuldi3_highpart_reg"
[(set (match_operand:DI 0 "register_operand" "=r")
(truncate:DI
(lshiftrt:TI
(mult:TI (zero_extend:TI
- (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
+ (match_operand:DI 1 "register_operand" "r"))
(zero_extend:TI
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
+ (match_operand:DI 2 "register_operand" "r")))
(const_int 64))))]
""
- "umulh %r1,%2,%0"
+ "umulh %1,%2,%0"
[(set_attr "type" "imul")
(set_attr "opsize" "udi")])
@@ -2849,7 +2876,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(set (match_operand:DF 0 "register_operand" "=f")
(sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
"TARGET_FP && TARGET_FIX"
- "sqrt%-%/ %1,%0"
+ "sqrt%-%/ %R1,%0"
[(set_attr "type" "fsqrt")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
@@ -5305,7 +5332,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
return "lda %0,%2(%1)\t\t!gprel";
else
return "lda %0,%2(%1)\t\t!gprellow";
-})
+}
+ [(set_attr "usegp" "yes")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -5331,10 +5359,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
[(match_dup 0)]
"operands[0] = split_small_symbolic_operand (operands[0]);")
+;; Accepts any symbolic, not just global, since function calls that
+;; don't go via bsr still use !literal in hopes of linker relaxation.
(define_insn "movdi_er_high_g"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "global_symbolic_operand" "")
+ (match_operand:DI 2 "symbolic_operand" "")
(match_operand 3 "const_int_operand" "")]
UNSPEC_LITERAL))]
"TARGET_EXPLICIT_RELOCS"
@@ -5425,7 +5455,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
UNSPEC_DTPREL))]
"HAVE_AS_TLS"
"ldq %0,%2(%1)\t\t!gotdtprel"
- [(set_attr "type" "ild")])
+ [(set_attr "type" "ild")
+ (set_attr "usegp" "yes")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -5446,7 +5477,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
UNSPEC_TPREL))]
"HAVE_AS_TLS"
"ldq %0,%2(%1)\t\t!gottprel"
- [(set_attr "type" "ild")])
+ [(set_attr "type" "ild")
+ (set_attr "usegp" "yes")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -5477,7 +5509,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
fmov %R1,%0
ldt %0,%1
stt %R1,%0"
- [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
+ [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")
+ (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*")])
;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
;; have been split up by the rules above but we shouldn't reject the
@@ -5524,7 +5557,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi,none"
stt %R1,%0
ftoit %1,%0
itoft %1,%0"
- [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
+ [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")
+ (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*")])
(define_insn "*movdi_fix"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
diff --git a/gcc/config/alpha/freebsd.h b/gcc/config/alpha/freebsd.h
index 0ec96885527..f809c62012e 100644
--- a/gcc/config/alpha/freebsd.h
+++ b/gcc/config/alpha/freebsd.h
@@ -20,11 +20,13 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Provide a CPP_SPEC appropriate for FreeBSD/alpha. Besides the dealing with
+/* Provide a FBSD_TARGET_CPU_CPP_BUILTINS and CPP_SPEC appropriate for
+ FreeBSD/alpha. Besides the dealing with
the GCC option `-posix', and PIC issues as on all FreeBSD platforms, we must
deal with the Alpha's FP issues. */
-#define TARGET_OS_CPP_BUILTINS() \
+#undef FBSD_TARGET_CPU_CPP_BUILTINS
+#define FBSD_TARGET_CPU_CPP_BUILTINS() \
do \
{ \
if (flag_pic) \
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index 28ff3208422..0c533449e8b 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -59,6 +59,8 @@ Boston, MA 02111-1307, USA. */
/* Define this so that all GNU/Linux targets handle the same pragmas. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
+#define TARGET_HAS_F_SETLKW
+
/* Do code reading to identify a signal frame, and set the frame
state data appropriately. See unwind-dw2.c for the structs. */
diff --git a/gcc/config/alpha/osf.h b/gcc/config/alpha/osf.h
index 9fbe2b56a07..2be2a424d35 100644
--- a/gcc/config/alpha/osf.h
+++ b/gcc/config/alpha/osf.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for DEC Alpha on OSF/1.
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
@@ -32,21 +32,23 @@ Boston, MA 02111-1307, USA. */
/* Names to predefine in the preprocessor for this target machine. */
-#define TARGET_OS_CPP_BUILTINS() \
- do { \
- builtin_define_std ("unix"); \
- builtin_define_std ("SYSTYPE_BSD"); \
- builtin_define ("_SYSTYPE_BSD"); \
- builtin_define ("__osf__"); \
- builtin_define ("_LONGLONG"); \
- builtin_define ("__EXTERN_PREFIX"); \
- builtin_assert ("system=unix"); \
- builtin_assert ("system=xpg4"); \
- /* Tru64 UNIX V5 has a 16 byte long \
- double type and requires __X_FLOAT \
- to be defined for <math.h>. */ \
- if (LONG_DOUBLE_TYPE_SIZE == 128) \
- builtin_define ("__X_FLOAT"); \
+#define TARGET_OS_CPP_BUILTINS() \
+ do { \
+ builtin_define_std ("unix"); \
+ builtin_define_std ("SYSTYPE_BSD"); \
+ builtin_define ("_SYSTYPE_BSD"); \
+ builtin_define ("__osf__"); \
+ builtin_define ("__digital__"); \
+ builtin_define ("__arch64__"); \
+ builtin_define ("_LONGLONG"); \
+ builtin_define ("__PRAGMA_EXTERN_PREFIX"); \
+ builtin_assert ("system=unix"); \
+ builtin_assert ("system=xpg4"); \
+ /* Tru64 UNIX V5 has a 16 byte long \
+ double type and requires __X_FLOAT \
+ to be defined for <math.h>. */ \
+ if (LONG_DOUBLE_TYPE_SIZE == 128) \
+ builtin_define ("__X_FLOAT"); \
} while (0)
/* Accept DEC C flags for multithreaded programs. We use _PTHREAD_USE_D4
diff --git a/gcc/config/alpha/t-crtfm b/gcc/config/alpha/t-crtfm
index 7076b517861..5ca8c3f747d 100644
--- a/gcc/config/alpha/t-crtfm
+++ b/gcc/config/alpha/t-crtfm
@@ -1,4 +1,5 @@
EXTRA_PARTS += crtfastmath.o
crtfastmath.o: $(srcdir)/config/alpha/crtfastmath.c $(GCC_PASSES)
- $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -c -o crtfastmath.o $(srcdir)/config/alpha/crtfastmath.c
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -frandom-seed=gcc-crtfastmath -c \
+ -o crtfastmath.o $(srcdir)/config/alpha/crtfastmath.c
diff --git a/gcc/config/alpha/t-osf4 b/gcc/config/alpha/t-osf4
index e9c451b9c04..0525d617662 100644
--- a/gcc/config/alpha/t-osf4
+++ b/gcc/config/alpha/t-osf4
@@ -17,6 +17,6 @@ SHLIB_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
$(LN_S) $(SHLIB_NAME) $(SHLIB_SONAME)
# $(slibdir) double quoted to protect it from expansion while building
# libgcc.mk. We want this delayed until actual install time.
-SHLIB_INSTALL = $(INSTALL_DATA) $(SHLIB_NAME) $$(slibdir)/$(SHLIB_SONAME); \
- rm -f $$(slibdir)/$(SHLIB_NAME); \
- $(LN_S) $(SHLIB_SONAME) $$(slibdir)/$(SHLIB_NAME)
+SHLIB_INSTALL = $(INSTALL_DATA) $(SHLIB_NAME) $$(DESTDIR)$$(slibdir)/$(SHLIB_SONAME); \
+ rm -f $$(DESTDIR)$$(slibdir)/$(SHLIB_NAME); \
+ $(LN_S) $(SHLIB_SONAME) $$(DESTDIR)$$(slibdir)/$(SHLIB_NAME)