summaryrefslogtreecommitdiff
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.c167
1 files changed, 112 insertions, 55 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 0c5334004f4..88771b9396d 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -20,8 +20,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#include <stdio.h>
#include "config.h"
+#include <stdio.h>
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -100,16 +100,12 @@ static void add_long_const PROTO((FILE *, HOST_WIDE_INT, int, int, int));
/* Compute the size of the save area in the stack. */
static void alpha_sa_mask PROTO((unsigned long *imaskP,
unsigned long *fmaskP));
-
-/* Strip type information. */
-#define CURRENT_FUNCTION_ARGS_INFO \
-(TARGET_OPEN_VMS ? current_function_args_info & 0xff \
- : current_function_args_info)
-
-/* Some helpful register info. */
-#define REG_PV 27
-#define REG_RA 26
-
+/* Get the number of args of a function in one of two ways. */
+#ifdef OPEN_VMS
+#define NUM_ARGS current_function_args_info.num_args
+#else
+#define NUM_ARGS current_function_args_info
+#endif
/* Parse target option strings. */
@@ -117,21 +113,42 @@ void
override_options ()
{
alpha_cpu
- = TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4;
+ = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6
+ : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4);
if (alpha_cpu_string)
{
if (! strcmp (alpha_cpu_string, "ev4")
|| ! strcmp (alpha_cpu_string, "21064"))
- alpha_cpu = PROCESSOR_EV4;
+ {
+ alpha_cpu = PROCESSOR_EV4;
+ target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
+ }
else if (! strcmp (alpha_cpu_string, "ev5")
|| ! strcmp (alpha_cpu_string, "21164"))
- alpha_cpu = PROCESSOR_EV5;
+ {
+ alpha_cpu = PROCESSOR_EV5;
+ target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX);
+ }
else if (! strcmp (alpha_cpu_string, "ev56")
|| ! strcmp (alpha_cpu_string, "21164a"))
{
alpha_cpu = PROCESSOR_EV5;
- target_flags |= MASK_BYTE_OPS;
+ target_flags |= MASK_BWX;
+ target_flags &= ~ (MASK_CIX | MASK_MAX);
+ }
+ else if (! strcmp (alpha_cpu_string, "pca56")
+ || ! strcmp (alpha_cpu_string, "21164PC"))
+ {
+ alpha_cpu = PROCESSOR_EV5;
+ target_flags |= MASK_BWX | MASK_MAX;
+ target_flags &= ~ MASK_CIX;
+ }
+ else if (! strcmp (alpha_cpu_string, "ev6")
+ || ! strcmp (alpha_cpu_string, "21264"))
+ {
+ alpha_cpu = PROCESSOR_EV6;
+ target_flags |= MASK_BWX | MASK_CIX | MASK_MAX;
}
else
error ("bad value `%s' for -mcpu switch", alpha_cpu_string);
@@ -487,7 +504,7 @@ input_operand (op, mode)
return 1;
/* ... fall through ... */
case MEM:
- return ((TARGET_BYTE_OPS || (mode != HImode && mode != QImode))
+ return ((TARGET_BWX || (mode != HImode && mode != QImode))
&& general_operand (op, mode));
case CONST_DOUBLE:
@@ -1441,12 +1458,12 @@ print_operand (file, x, code)
case ',':
/* Generates single precision instruction suffix. */
- fprintf (file, "%c", (TARGET_FLOAT_VAX?'f':'s'));
+ fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'f' : 's'));
break;
case '-':
/* Generates double precision instruction suffix. */
- fprintf (file, "%c", (TARGET_FLOAT_VAX?'g':'t'));
+ fprintf (file, "%c", (TARGET_FLOAT_VAX ? 'g' : 't'));
break;
case 'r':
@@ -1673,9 +1690,9 @@ alpha_builtin_saveregs (arglist)
/* Compute the current position into the args, taking into account
both registers and memory. Both of these are already included in
- current_function_args_info. */
+ NUM_ARGS. */
- argsize = GEN_INT (CURRENT_FUNCTION_ARGS_INFO * UNITS_PER_WORD);
+ argsize = GEN_INT (NUM_ARGS * UNITS_PER_WORD);
/* For Unix, SETUP_INCOMING_VARARGS moves the starting address base up by 48,
storing fp arg registers in the first 48 bytes, and the integer arg
@@ -1688,10 +1705,10 @@ alpha_builtin_saveregs (arglist)
if (TARGET_OPEN_VMS)
addr = plus_constant (virtual_incoming_args_rtx,
- CURRENT_FUNCTION_ARGS_INFO <= 5 + stdarg
+ NUM_ARGS <= 5 + stdarg
? UNITS_PER_WORD : - 6 * UNITS_PER_WORD);
else
- addr = (CURRENT_FUNCTION_ARGS_INFO <= 5 + stdarg
+ addr = (NUM_ARGS <= 5 + stdarg
? plus_constant (virtual_incoming_args_rtx,
6 * UNITS_PER_WORD)
: plus_constant (virtual_incoming_args_rtx,
@@ -1750,6 +1767,39 @@ alpha_builtin_saveregs (arglist)
}
}
+#if OPEN_VMS
+#define REG_PV 27
+#define REG_RA 26
+#else
+#define REG_RA 26
+#endif
+
+/* Find the current function's return address.
+
+ ??? It would be better to arrange things such that if we would ordinarily
+ have been a leaf function and we didn't spill the hard reg that we
+ wouldn't have to save the register in the prolog. But it's not clear
+ how to get the right information at the right time. */
+
+static rtx alpha_return_addr_rtx;
+
+rtx
+alpha_return_addr ()
+{
+ rtx ret;
+
+ if ((ret = alpha_return_addr_rtx) == NULL)
+ {
+ alpha_return_addr_rtx = ret = gen_reg_rtx (Pmode);
+
+ emit_insn_after (gen_rtx (SET, VOIDmode, ret,
+ gen_rtx (REG, Pmode, REG_RA)),
+ get_insns ());
+ }
+
+ return ret;
+}
+
/* This page contains routines that are used to determine what the function
prologue and epilogue code will do and write them out. */
@@ -2316,6 +2366,18 @@ alpha_does_function_need_gp ()
return 0;
}
+int
+vms_valid_decl_attribute_p (decl, attributes, identifier, args)
+ tree decl;
+ tree attributes;
+ tree identifier;
+ tree args;
+{
+ if (is_attribute_p ("overlaid", identifier))
+ return (args == NULL_TREE);
+ return 0;
+}
+
void
output_prolog (file, size)
FILE *file;
@@ -2646,6 +2708,8 @@ output_epilog (file, size)
/* Show that we know this function if it is called again. */
SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1;
+
+ alpha_return_addr_rtx = 0;
}
#endif /* !OPEN_VMS */
@@ -3124,46 +3188,39 @@ check_float_value (mode, d, overflow)
#if OPEN_VMS
-void *
-function_arg (cum, mode, type, named)
- CUMULATIVE_ARGS *cum;
- enum machine_mode mode;
- tree type;
- int named;
-{
- int arg;
+/* Return the VMS argument type corresponding to MODE. */
- if (mode == VOIDmode) /* final call, return argument information */
+enum avms_arg_type
+alpha_arg_type (mode)
+ enum machine_mode mode;
+{
+ switch (mode)
{
- return GEN_INT (*cum);
+ case SFmode:
+ return TARGET_FLOAT_VAX ? FF : FS;
+ case DFmode:
+ return TARGET_FLOAT_VAX ? FD : FT;
+ default:
+ return I64;
}
+}
- arg = *cum & 0xff;
+/* Return an rtx for an integer representing the VMS Argument Information
+ register value. */
- switch (mode)
- {
- case SFmode:
- *cum |= (((TARGET_FLOAT_VAX)?1:4) << ((arg * 3)+8)); /* 4 = AI$K_AR_FS, IEEE single */
- break;
- case DFmode:
- *cum |= (((TARGET_FLOAT_VAX)?3:5) << ((arg * 3)+8)); /* 5 = AI$K_AR_FT, IEEE double */
- break;
- case TFmode:
- *cum |= (7 << ((arg * 3)+8)); /* 5 = AI$K_AR_FT, IEEE double */
- break;
- default:
- break;
- }
+struct rtx_def *
+alpha_arg_info_reg_val (cum)
+ CUMULATIVE_ARGS cum;
+{
+ unsigned HOST_WIDE_INT regval = cum.num_args;
+ int i;
- return (arg < 6 && ! MUST_PASS_IN_STACK (mode, type)
- ? gen_rtx(REG, mode,
- (*cum & 0xff) + 16 + ((TARGET_FPREGS
- && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
- || GET_MODE_CLASS (mode) == MODE_FLOAT))
- * 32))
- : 0);
-}
+ for (i = 0; i < 6; i++)
+ regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
+ return GEN_INT (regval);
+}
+
/* Structure to collect function names for final output
in link section. */