diff options
Diffstat (limited to 'gcc/config/alpha/alpha.c')
-rw-r--r-- | gcc/config/alpha/alpha.c | 167 |
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. */ |