Home | History | Annotate | Line # | Download | only in alpha
alpha.cc revision 1.1
      1  1.1  mrg /* Subroutines used for code generation on the DEC Alpha.
      2  1.1  mrg    Copyright (C) 1992-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Richard Kenner (kenner (at) vlsi1.ultra.nyu.edu)
      4  1.1  mrg 
      5  1.1  mrg This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg GCC is free software; you can redistribute it and/or modify
      8  1.1  mrg it under the terms of the GNU General Public License as published by
      9  1.1  mrg the Free Software Foundation; either version 3, or (at your option)
     10  1.1  mrg any later version.
     11  1.1  mrg 
     12  1.1  mrg GCC is distributed in the hope that it will be useful,
     13  1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  mrg GNU General Public License for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License
     18  1.1  mrg along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg 
     22  1.1  mrg #define IN_TARGET_CODE 1
     23  1.1  mrg 
     24  1.1  mrg #include "config.h"
     25  1.1  mrg #include "system.h"
     26  1.1  mrg #include "coretypes.h"
     27  1.1  mrg #include "backend.h"
     28  1.1  mrg #include "target.h"
     29  1.1  mrg #include "rtl.h"
     30  1.1  mrg #include "tree.h"
     31  1.1  mrg #include "stringpool.h"
     32  1.1  mrg #include "attribs.h"
     33  1.1  mrg #include "memmodel.h"
     34  1.1  mrg #include "gimple.h"
     35  1.1  mrg #include "df.h"
     36  1.1  mrg #include "predict.h"
     37  1.1  mrg #include "tm_p.h"
     38  1.1  mrg #include "ssa.h"
     39  1.1  mrg #include "expmed.h"
     40  1.1  mrg #include "optabs.h"
     41  1.1  mrg #include "regs.h"
     42  1.1  mrg #include "emit-rtl.h"
     43  1.1  mrg #include "recog.h"
     44  1.1  mrg #include "diagnostic-core.h"
     45  1.1  mrg #include "alias.h"
     46  1.1  mrg #include "fold-const.h"
     47  1.1  mrg #include "stor-layout.h"
     48  1.1  mrg #include "calls.h"
     49  1.1  mrg #include "varasm.h"
     50  1.1  mrg #include "output.h"
     51  1.1  mrg #include "insn-attr.h"
     52  1.1  mrg #include "explow.h"
     53  1.1  mrg #include "expr.h"
     54  1.1  mrg #include "reload.h"
     55  1.1  mrg #include "except.h"
     56  1.1  mrg #include "common/common-target.h"
     57  1.1  mrg #include "debug.h"
     58  1.1  mrg #include "langhooks.h"
     59  1.1  mrg #include "cfgrtl.h"
     60  1.1  mrg #include "tree-pass.h"
     61  1.1  mrg #include "context.h"
     62  1.1  mrg #include "gimple-iterator.h"
     63  1.1  mrg #include "gimplify.h"
     64  1.1  mrg #include "tree-stdarg.h"
     65  1.1  mrg #include "tm-constrs.h"
     66  1.1  mrg #include "libfuncs.h"
     67  1.1  mrg #include "builtins.h"
     68  1.1  mrg #include "rtl-iter.h"
     69  1.1  mrg #include "flags.h"
     70  1.1  mrg #include "opts.h"
     71  1.1  mrg 
     72  1.1  mrg /* This file should be included last.  */
     73  1.1  mrg #include "target-def.h"
     74  1.1  mrg 
     75  1.1  mrg /* Specify which cpu to schedule for.  */
     76  1.1  mrg enum processor_type alpha_tune;
     77  1.1  mrg 
     78  1.1  mrg /* Which cpu we're generating code for.  */
     79  1.1  mrg enum processor_type alpha_cpu;
     80  1.1  mrg 
     81  1.1  mrg static const char * const alpha_cpu_name[] =
     82  1.1  mrg {
     83  1.1  mrg   "ev4", "ev5", "ev6"
     84  1.1  mrg };
     85  1.1  mrg 
     86  1.1  mrg /* Specify how accurate floating-point traps need to be.  */
     87  1.1  mrg 
     88  1.1  mrg enum alpha_trap_precision alpha_tp;
     89  1.1  mrg 
     90  1.1  mrg /* Specify the floating-point rounding mode.  */
     91  1.1  mrg 
     92  1.1  mrg enum alpha_fp_rounding_mode alpha_fprm;
     93  1.1  mrg 
     94  1.1  mrg /* Specify which things cause traps.  */
     95  1.1  mrg 
     96  1.1  mrg enum alpha_fp_trap_mode alpha_fptm;
     97  1.1  mrg 
     98  1.1  mrg /* Nonzero if inside of a function, because the Alpha asm can't
     99  1.1  mrg    handle .files inside of functions.  */
    100  1.1  mrg 
    101  1.1  mrg static int inside_function = FALSE;
    102  1.1  mrg 
    103  1.1  mrg /* The number of cycles of latency we should assume on memory reads.  */
    104  1.1  mrg 
    105  1.1  mrg static int alpha_memory_latency = 3;
    106  1.1  mrg 
    107  1.1  mrg /* Whether the function needs the GP.  */
    108  1.1  mrg 
    109  1.1  mrg static int alpha_function_needs_gp;
    110  1.1  mrg 
    111  1.1  mrg /* The assembler name of the current function.  */
    112  1.1  mrg 
    113  1.1  mrg static const char *alpha_fnname;
    114  1.1  mrg 
    115  1.1  mrg /* The next explicit relocation sequence number.  */
    116  1.1  mrg extern GTY(()) int alpha_next_sequence_number;
    117  1.1  mrg int alpha_next_sequence_number = 1;
    118  1.1  mrg 
    119  1.1  mrg /* The literal and gpdisp sequence numbers for this insn, as printed
    120  1.1  mrg    by %# and %* respectively.  */
    121  1.1  mrg extern GTY(()) int alpha_this_literal_sequence_number;
    122  1.1  mrg extern GTY(()) int alpha_this_gpdisp_sequence_number;
    123  1.1  mrg int alpha_this_literal_sequence_number;
    124  1.1  mrg int alpha_this_gpdisp_sequence_number;
    125  1.1  mrg 
    126  1.1  mrg /* Costs of various operations on the different architectures.  */
    127  1.1  mrg 
    128  1.1  mrg struct alpha_rtx_cost_data
    129  1.1  mrg {
    130  1.1  mrg   unsigned char fp_add;
    131  1.1  mrg   unsigned char fp_mult;
    132  1.1  mrg   unsigned char fp_div_sf;
    133  1.1  mrg   unsigned char fp_div_df;
    134  1.1  mrg   unsigned char int_mult_si;
    135  1.1  mrg   unsigned char int_mult_di;
    136  1.1  mrg   unsigned char int_shift;
    137  1.1  mrg   unsigned char int_cmov;
    138  1.1  mrg   unsigned short int_div;
    139  1.1  mrg };
    140  1.1  mrg 
    141  1.1  mrg static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
    142  1.1  mrg {
    143  1.1  mrg   { /* EV4 */
    144  1.1  mrg     COSTS_N_INSNS (6),		/* fp_add */
    145  1.1  mrg     COSTS_N_INSNS (6),		/* fp_mult */
    146  1.1  mrg     COSTS_N_INSNS (34),		/* fp_div_sf */
    147  1.1  mrg     COSTS_N_INSNS (63),		/* fp_div_df */
    148  1.1  mrg     COSTS_N_INSNS (23),		/* int_mult_si */
    149  1.1  mrg     COSTS_N_INSNS (23),		/* int_mult_di */
    150  1.1  mrg     COSTS_N_INSNS (2),		/* int_shift */
    151  1.1  mrg     COSTS_N_INSNS (2),		/* int_cmov */
    152  1.1  mrg     COSTS_N_INSNS (97),		/* int_div */
    153  1.1  mrg   },
    154  1.1  mrg   { /* EV5 */
    155  1.1  mrg     COSTS_N_INSNS (4),		/* fp_add */
    156  1.1  mrg     COSTS_N_INSNS (4),		/* fp_mult */
    157  1.1  mrg     COSTS_N_INSNS (15),		/* fp_div_sf */
    158  1.1  mrg     COSTS_N_INSNS (22),		/* fp_div_df */
    159  1.1  mrg     COSTS_N_INSNS (8),		/* int_mult_si */
    160  1.1  mrg     COSTS_N_INSNS (12),		/* int_mult_di */
    161  1.1  mrg     COSTS_N_INSNS (1) + 1,	/* int_shift */
    162  1.1  mrg     COSTS_N_INSNS (1),		/* int_cmov */
    163  1.1  mrg     COSTS_N_INSNS (83),		/* int_div */
    164  1.1  mrg   },
    165  1.1  mrg   { /* EV6 */
    166  1.1  mrg     COSTS_N_INSNS (4),		/* fp_add */
    167  1.1  mrg     COSTS_N_INSNS (4),		/* fp_mult */
    168  1.1  mrg     COSTS_N_INSNS (12),		/* fp_div_sf */
    169  1.1  mrg     COSTS_N_INSNS (15),		/* fp_div_df */
    170  1.1  mrg     COSTS_N_INSNS (7),		/* int_mult_si */
    171  1.1  mrg     COSTS_N_INSNS (7),		/* int_mult_di */
    172  1.1  mrg     COSTS_N_INSNS (1),		/* int_shift */
    173  1.1  mrg     COSTS_N_INSNS (2),		/* int_cmov */
    174  1.1  mrg     COSTS_N_INSNS (86),		/* int_div */
    175  1.1  mrg   },
    176  1.1  mrg };
    177  1.1  mrg 
    178  1.1  mrg /* Similar but tuned for code size instead of execution latency.  The
    179  1.1  mrg    extra +N is fractional cost tuning based on latency.  It's used to
    180  1.1  mrg    encourage use of cheaper insns like shift, but only if there's just
    181  1.1  mrg    one of them.  */
    182  1.1  mrg 
    183  1.1  mrg static struct alpha_rtx_cost_data const alpha_rtx_cost_size =
    184  1.1  mrg {
    185  1.1  mrg   COSTS_N_INSNS (1),		/* fp_add */
    186  1.1  mrg   COSTS_N_INSNS (1),		/* fp_mult */
    187  1.1  mrg   COSTS_N_INSNS (1),		/* fp_div_sf */
    188  1.1  mrg   COSTS_N_INSNS (1) + 1,	/* fp_div_df */
    189  1.1  mrg   COSTS_N_INSNS (1) + 1,	/* int_mult_si */
    190  1.1  mrg   COSTS_N_INSNS (1) + 2,	/* int_mult_di */
    191  1.1  mrg   COSTS_N_INSNS (1),		/* int_shift */
    192  1.1  mrg   COSTS_N_INSNS (1),		/* int_cmov */
    193  1.1  mrg   COSTS_N_INSNS (6),		/* int_div */
    194  1.1  mrg };
    195  1.1  mrg 
    196  1.1  mrg /* Get the number of args of a function in one of two ways.  */
    197  1.1  mrg #if TARGET_ABI_OPEN_VMS
    198  1.1  mrg #define NUM_ARGS crtl->args.info.num_args
    199  1.1  mrg #else
    200  1.1  mrg #define NUM_ARGS crtl->args.info
    201  1.1  mrg #endif
    202  1.1  mrg 
    203  1.1  mrg #define REG_PV 27
    204  1.1  mrg #define REG_RA 26
    205  1.1  mrg 
    206  1.1  mrg /* Declarations of static functions.  */
    207  1.1  mrg static struct machine_function *alpha_init_machine_status (void);
    208  1.1  mrg static rtx alpha_emit_xfloating_compare (enum rtx_code *, rtx, rtx);
    209  1.1  mrg static void alpha_handle_trap_shadows (void);
    210  1.1  mrg static void alpha_align_insns (void);
    211  1.1  mrg static void alpha_override_options_after_change (void);
    212  1.1  mrg 
    213  1.1  mrg #if TARGET_ABI_OPEN_VMS
    214  1.1  mrg static void alpha_write_linkage (FILE *, const char *);
    215  1.1  mrg static bool vms_valid_pointer_mode (scalar_int_mode);
    216  1.1  mrg #else
    217  1.1  mrg #define vms_patch_builtins()  gcc_unreachable()
    218  1.1  mrg #endif
    219  1.1  mrg 
    220  1.1  mrg static unsigned int
    222  1.1  mrg rest_of_handle_trap_shadows (void)
    223  1.1  mrg {
    224  1.1  mrg   alpha_handle_trap_shadows ();
    225  1.1  mrg   return 0;
    226  1.1  mrg }
    227  1.1  mrg 
    228  1.1  mrg namespace {
    229  1.1  mrg 
    230  1.1  mrg const pass_data pass_data_handle_trap_shadows =
    231  1.1  mrg {
    232  1.1  mrg   RTL_PASS,
    233  1.1  mrg   "trap_shadows",			/* name */
    234  1.1  mrg   OPTGROUP_NONE,			/* optinfo_flags */
    235  1.1  mrg   TV_NONE,				/* tv_id */
    236  1.1  mrg   0,					/* properties_required */
    237  1.1  mrg   0,					/* properties_provided */
    238  1.1  mrg   0,					/* properties_destroyed */
    239  1.1  mrg   0,					/* todo_flags_start */
    240  1.1  mrg   TODO_df_finish,			/* todo_flags_finish */
    241  1.1  mrg };
    242  1.1  mrg 
    243  1.1  mrg class pass_handle_trap_shadows : public rtl_opt_pass
    244  1.1  mrg {
    245  1.1  mrg public:
    246  1.1  mrg   pass_handle_trap_shadows(gcc::context *ctxt)
    247  1.1  mrg     : rtl_opt_pass(pass_data_handle_trap_shadows, ctxt)
    248  1.1  mrg   {}
    249  1.1  mrg 
    250  1.1  mrg   /* opt_pass methods: */
    251  1.1  mrg   virtual bool gate (function *)
    252  1.1  mrg     {
    253  1.1  mrg       return alpha_tp != ALPHA_TP_PROG || flag_exceptions;
    254  1.1  mrg     }
    255  1.1  mrg 
    256  1.1  mrg   virtual unsigned int execute (function *)
    257  1.1  mrg     {
    258  1.1  mrg       return rest_of_handle_trap_shadows ();
    259  1.1  mrg     }
    260  1.1  mrg 
    261  1.1  mrg }; // class pass_handle_trap_shadows
    262  1.1  mrg 
    263  1.1  mrg } // anon namespace
    264  1.1  mrg 
    265  1.1  mrg rtl_opt_pass *
    266  1.1  mrg make_pass_handle_trap_shadows (gcc::context *ctxt)
    267  1.1  mrg {
    268  1.1  mrg   return new pass_handle_trap_shadows (ctxt);
    269  1.1  mrg }
    270  1.1  mrg 
    271  1.1  mrg static unsigned int
    272  1.1  mrg rest_of_align_insns (void)
    273  1.1  mrg {
    274  1.1  mrg   alpha_align_insns ();
    275  1.1  mrg   return 0;
    276  1.1  mrg }
    277  1.1  mrg 
    278  1.1  mrg namespace {
    279  1.1  mrg 
    280  1.1  mrg const pass_data pass_data_align_insns =
    281  1.1  mrg {
    282  1.1  mrg   RTL_PASS,
    283  1.1  mrg   "align_insns",			/* name */
    284  1.1  mrg   OPTGROUP_NONE,			/* optinfo_flags */
    285  1.1  mrg   TV_NONE,				/* tv_id */
    286  1.1  mrg   0,					/* properties_required */
    287  1.1  mrg   0,					/* properties_provided */
    288  1.1  mrg   0,					/* properties_destroyed */
    289  1.1  mrg   0,					/* todo_flags_start */
    290  1.1  mrg   TODO_df_finish,			/* todo_flags_finish */
    291  1.1  mrg };
    292  1.1  mrg 
    293  1.1  mrg class pass_align_insns : public rtl_opt_pass
    294  1.1  mrg {
    295  1.1  mrg public:
    296  1.1  mrg   pass_align_insns(gcc::context *ctxt)
    297  1.1  mrg     : rtl_opt_pass(pass_data_align_insns, ctxt)
    298  1.1  mrg   {}
    299  1.1  mrg 
    300  1.1  mrg   /* opt_pass methods: */
    301  1.1  mrg   virtual bool gate (function *)
    302  1.1  mrg     {
    303  1.1  mrg       /* Due to the number of extra trapb insns, don't bother fixing up
    304  1.1  mrg 	 alignment when trap precision is instruction.  Moreover, we can
    305  1.1  mrg 	 only do our job when sched2 is run.  */
    306  1.1  mrg       return ((alpha_tune == PROCESSOR_EV4
    307  1.1  mrg 	       || alpha_tune == PROCESSOR_EV5)
    308  1.1  mrg 	      && optimize && !optimize_size
    309  1.1  mrg 	      && alpha_tp != ALPHA_TP_INSN
    310  1.1  mrg 	      && flag_schedule_insns_after_reload);
    311  1.1  mrg     }
    312  1.1  mrg 
    313  1.1  mrg   virtual unsigned int execute (function *)
    314  1.1  mrg     {
    315  1.1  mrg       return rest_of_align_insns ();
    316  1.1  mrg     }
    317  1.1  mrg 
    318  1.1  mrg }; // class pass_align_insns
    319  1.1  mrg 
    320  1.1  mrg } // anon namespace
    321  1.1  mrg 
    322  1.1  mrg rtl_opt_pass *
    323  1.1  mrg make_pass_align_insns (gcc::context *ctxt)
    324  1.1  mrg {
    325  1.1  mrg   return new pass_align_insns (ctxt);
    326  1.1  mrg }
    327  1.1  mrg 
    328  1.1  mrg #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
    329  1.1  mrg /* Implement TARGET_MANGLE_TYPE.  */
    330  1.1  mrg 
    331  1.1  mrg static const char *
    332  1.1  mrg alpha_mangle_type (const_tree type)
    333  1.1  mrg {
    334  1.1  mrg   if (TYPE_MAIN_VARIANT (type) == long_double_type_node
    335  1.1  mrg       && TARGET_LONG_DOUBLE_128)
    336  1.1  mrg     return "g";
    337  1.1  mrg 
    338  1.1  mrg   /* For all other types, use normal C++ mangling.  */
    339  1.1  mrg   return NULL;
    340  1.1  mrg }
    341  1.1  mrg #endif
    342  1.1  mrg 
    343  1.1  mrg /* Parse target option strings.  */
    344  1.1  mrg 
    345  1.1  mrg static void
    346  1.1  mrg alpha_option_override (void)
    347  1.1  mrg {
    348  1.1  mrg   static const struct cpu_table {
    349  1.1  mrg     const char *const name;
    350  1.1  mrg     const enum processor_type processor;
    351  1.1  mrg     const int flags;
    352  1.1  mrg     const unsigned short line_size; /* in bytes */
    353  1.1  mrg     const unsigned short l1_size;   /* in kb.  */
    354  1.1  mrg     const unsigned short l2_size;   /* in kb.  */
    355  1.1  mrg   } cpu_table[] = {
    356  1.1  mrg     /* EV4/LCA45 had 8k L1 caches; EV45 had 16k L1 caches.
    357  1.1  mrg        EV4/EV45 had 128k to 16M 32-byte direct Bcache.  LCA45
    358  1.1  mrg        had 64k to 8M 8-byte direct Bcache.  */
    359  1.1  mrg     { "ev4",	PROCESSOR_EV4, 0, 32, 8, 8*1024 },
    360  1.1  mrg     { "21064",	PROCESSOR_EV4, 0, 32, 8, 8*1024 },
    361  1.1  mrg     { "ev45",	PROCESSOR_EV4, 0, 32, 16, 16*1024 },
    362  1.1  mrg 
    363  1.1  mrg     /* EV5 or EV56 had 8k 32 byte L1, 96k 32 or 64 byte L2,
    364  1.1  mrg        and 1M to 16M 64 byte L3 (not modeled).
    365  1.1  mrg        PCA56 had 16k 64-byte cache; PCA57 had 32k Icache.
    366  1.1  mrg        PCA56 had 8k 64-byte cache; PCA57 had 16k Dcache.  */
    367  1.1  mrg     { "ev5",	PROCESSOR_EV5, 0, 32, 8, 96 },
    368  1.1  mrg     { "21164",	PROCESSOR_EV5, 0, 32, 8, 96 },
    369  1.1  mrg     { "ev56",	PROCESSOR_EV5, MASK_BWX, 32, 8, 96 },
    370  1.1  mrg     { "21164a",	PROCESSOR_EV5, MASK_BWX, 32, 8, 96 },
    371  1.1  mrg     { "pca56",	PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 },
    372  1.1  mrg     { "21164PC",PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 },
    373  1.1  mrg     { "21164pc",PROCESSOR_EV5, MASK_BWX|MASK_MAX, 64, 16, 4*1024 },
    374  1.1  mrg 
    375  1.1  mrg     /* EV6 had 64k 64 byte L1, 1M to 16M Bcache.  */
    376  1.1  mrg     { "ev6",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX, 64, 64, 16*1024 },
    377  1.1  mrg     { "21264",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX, 64, 64, 16*1024 },
    378  1.1  mrg     { "ev67",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX,
    379  1.1  mrg       64, 64, 16*1024 },
    380  1.1  mrg     { "21264a",	PROCESSOR_EV6, MASK_BWX|MASK_MAX|MASK_FIX|MASK_CIX,
    381  1.1  mrg       64, 64, 16*1024 }
    382  1.1  mrg   };
    383  1.1  mrg 
    384  1.1  mrg   int const ct_size = ARRAY_SIZE (cpu_table);
    385  1.1  mrg   int line_size = 0, l1_size = 0, l2_size = 0;
    386  1.1  mrg   int i;
    387  1.1  mrg 
    388  1.1  mrg #ifdef SUBTARGET_OVERRIDE_OPTIONS
    389  1.1  mrg   SUBTARGET_OVERRIDE_OPTIONS;
    390  1.1  mrg #endif
    391  1.1  mrg 
    392  1.1  mrg   /* Default to full IEEE compliance mode for Go language.  */
    393  1.1  mrg   if (strcmp (lang_hooks.name, "GNU Go") == 0
    394  1.1  mrg       && !(target_flags_explicit & MASK_IEEE))
    395  1.1  mrg     target_flags |= MASK_IEEE;
    396  1.1  mrg 
    397  1.1  mrg   alpha_fprm = ALPHA_FPRM_NORM;
    398  1.1  mrg   alpha_tp = ALPHA_TP_PROG;
    399  1.1  mrg   alpha_fptm = ALPHA_FPTM_N;
    400  1.1  mrg 
    401  1.1  mrg   if (TARGET_IEEE)
    402  1.1  mrg     {
    403  1.1  mrg       alpha_tp = ALPHA_TP_INSN;
    404  1.1  mrg       alpha_fptm = ALPHA_FPTM_SU;
    405  1.1  mrg     }
    406  1.1  mrg   if (TARGET_IEEE_WITH_INEXACT)
    407  1.1  mrg     {
    408  1.1  mrg       alpha_tp = ALPHA_TP_INSN;
    409  1.1  mrg       alpha_fptm = ALPHA_FPTM_SUI;
    410  1.1  mrg     }
    411  1.1  mrg 
    412  1.1  mrg   if (alpha_tp_string)
    413  1.1  mrg     {
    414  1.1  mrg       if (! strcmp (alpha_tp_string, "p"))
    415  1.1  mrg 	alpha_tp = ALPHA_TP_PROG;
    416  1.1  mrg       else if (! strcmp (alpha_tp_string, "f"))
    417  1.1  mrg 	alpha_tp = ALPHA_TP_FUNC;
    418  1.1  mrg       else if (! strcmp (alpha_tp_string, "i"))
    419  1.1  mrg 	alpha_tp = ALPHA_TP_INSN;
    420  1.1  mrg       else
    421  1.1  mrg 	error ("bad value %qs for %<-mtrap-precision%> switch",
    422  1.1  mrg 	       alpha_tp_string);
    423  1.1  mrg     }
    424  1.1  mrg 
    425  1.1  mrg   if (alpha_fprm_string)
    426  1.1  mrg     {
    427  1.1  mrg       if (! strcmp (alpha_fprm_string, "n"))
    428  1.1  mrg 	alpha_fprm = ALPHA_FPRM_NORM;
    429  1.1  mrg       else if (! strcmp (alpha_fprm_string, "m"))
    430  1.1  mrg 	alpha_fprm = ALPHA_FPRM_MINF;
    431  1.1  mrg       else if (! strcmp (alpha_fprm_string, "c"))
    432  1.1  mrg 	alpha_fprm = ALPHA_FPRM_CHOP;
    433  1.1  mrg       else if (! strcmp (alpha_fprm_string,"d"))
    434  1.1  mrg 	alpha_fprm = ALPHA_FPRM_DYN;
    435  1.1  mrg       else
    436  1.1  mrg 	error ("bad value %qs for %<-mfp-rounding-mode%> switch",
    437  1.1  mrg 	       alpha_fprm_string);
    438  1.1  mrg     }
    439  1.1  mrg 
    440  1.1  mrg   if (alpha_fptm_string)
    441  1.1  mrg     {
    442  1.1  mrg       if (strcmp (alpha_fptm_string, "n") == 0)
    443  1.1  mrg 	alpha_fptm = ALPHA_FPTM_N;
    444  1.1  mrg       else if (strcmp (alpha_fptm_string, "u") == 0)
    445  1.1  mrg 	alpha_fptm = ALPHA_FPTM_U;
    446  1.1  mrg       else if (strcmp (alpha_fptm_string, "su") == 0)
    447  1.1  mrg 	alpha_fptm = ALPHA_FPTM_SU;
    448  1.1  mrg       else if (strcmp (alpha_fptm_string, "sui") == 0)
    449  1.1  mrg 	alpha_fptm = ALPHA_FPTM_SUI;
    450  1.1  mrg       else
    451  1.1  mrg 	error ("bad value %qs for %<-mfp-trap-mode%> switch",
    452  1.1  mrg 	       alpha_fptm_string);
    453  1.1  mrg     }
    454  1.1  mrg 
    455  1.1  mrg   if (alpha_cpu_string)
    456  1.1  mrg     {
    457  1.1  mrg       for (i = 0; i < ct_size; i++)
    458  1.1  mrg 	if (! strcmp (alpha_cpu_string, cpu_table [i].name))
    459  1.1  mrg 	  {
    460  1.1  mrg 	    alpha_tune = alpha_cpu = cpu_table[i].processor;
    461  1.1  mrg 	    line_size = cpu_table[i].line_size;
    462  1.1  mrg 	    l1_size = cpu_table[i].l1_size;
    463  1.1  mrg 	    l2_size = cpu_table[i].l2_size;
    464  1.1  mrg 	    target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX);
    465  1.1  mrg 	    target_flags |= cpu_table[i].flags;
    466  1.1  mrg 	    break;
    467  1.1  mrg 	  }
    468  1.1  mrg       if (i == ct_size)
    469  1.1  mrg 	error ("bad value %qs for %<-mcpu%> switch", alpha_cpu_string);
    470  1.1  mrg     }
    471  1.1  mrg 
    472  1.1  mrg   if (alpha_tune_string)
    473  1.1  mrg     {
    474  1.1  mrg       for (i = 0; i < ct_size; i++)
    475  1.1  mrg 	if (! strcmp (alpha_tune_string, cpu_table [i].name))
    476  1.1  mrg 	  {
    477  1.1  mrg 	    alpha_tune = cpu_table[i].processor;
    478  1.1  mrg 	    line_size = cpu_table[i].line_size;
    479  1.1  mrg 	    l1_size = cpu_table[i].l1_size;
    480  1.1  mrg 	    l2_size = cpu_table[i].l2_size;
    481  1.1  mrg 	    break;
    482  1.1  mrg 	  }
    483  1.1  mrg       if (i == ct_size)
    484  1.1  mrg 	error ("bad value %qs for %<-mtune%> switch", alpha_tune_string);
    485  1.1  mrg     }
    486  1.1  mrg 
    487  1.1  mrg   if (line_size)
    488  1.1  mrg     SET_OPTION_IF_UNSET (&global_options, &global_options_set,
    489  1.1  mrg 			 param_l1_cache_line_size, line_size);
    490  1.1  mrg   if (l1_size)
    491  1.1  mrg     SET_OPTION_IF_UNSET (&global_options, &global_options_set,
    492  1.1  mrg 			 param_l1_cache_size, l1_size);
    493  1.1  mrg   if (l2_size)
    494  1.1  mrg     SET_OPTION_IF_UNSET (&global_options, &global_options_set,
    495  1.1  mrg 			 param_l2_cache_size, l2_size);
    496  1.1  mrg 
    497  1.1  mrg   /* Do some sanity checks on the above options.  */
    498  1.1  mrg 
    499  1.1  mrg   if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI)
    500  1.1  mrg       && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6)
    501  1.1  mrg     {
    502  1.1  mrg       warning (0, "fp software completion requires %<-mtrap-precision=i%>");
    503  1.1  mrg       alpha_tp = ALPHA_TP_INSN;
    504  1.1  mrg     }
    505  1.1  mrg 
    506  1.1  mrg   if (alpha_cpu == PROCESSOR_EV6)
    507  1.1  mrg     {
    508  1.1  mrg       /* Except for EV6 pass 1 (not released), we always have precise
    509  1.1  mrg 	 arithmetic traps.  Which means we can do software completion
    510  1.1  mrg 	 without minding trap shadows.  */
    511  1.1  mrg       alpha_tp = ALPHA_TP_PROG;
    512  1.1  mrg     }
    513  1.1  mrg 
    514  1.1  mrg   if (TARGET_FLOAT_VAX)
    515  1.1  mrg     {
    516  1.1  mrg       if (alpha_fprm == ALPHA_FPRM_MINF || alpha_fprm == ALPHA_FPRM_DYN)
    517  1.1  mrg 	{
    518  1.1  mrg 	  warning (0, "rounding mode not supported for VAX floats");
    519  1.1  mrg 	  alpha_fprm = ALPHA_FPRM_NORM;
    520  1.1  mrg 	}
    521  1.1  mrg       if (alpha_fptm == ALPHA_FPTM_SUI)
    522  1.1  mrg 	{
    523  1.1  mrg 	  warning (0, "trap mode not supported for VAX floats");
    524  1.1  mrg 	  alpha_fptm = ALPHA_FPTM_SU;
    525  1.1  mrg 	}
    526  1.1  mrg       if (target_flags_explicit & MASK_LONG_DOUBLE_128)
    527  1.1  mrg 	warning (0, "128-bit %<long double%> not supported for VAX floats");
    528  1.1  mrg       target_flags &= ~MASK_LONG_DOUBLE_128;
    529  1.1  mrg     }
    530  1.1  mrg 
    531  1.1  mrg   {
    532  1.1  mrg     char *end;
    533  1.1  mrg     int lat;
    534  1.1  mrg 
    535  1.1  mrg     if (!alpha_mlat_string)
    536  1.1  mrg       alpha_mlat_string = "L1";
    537  1.1  mrg 
    538  1.1  mrg     if (ISDIGIT ((unsigned char)alpha_mlat_string[0])
    539  1.1  mrg 	&& (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0'))
    540  1.1  mrg       ;
    541  1.1  mrg     else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l')
    542  1.1  mrg 	     && ISDIGIT ((unsigned char)alpha_mlat_string[1])
    543  1.1  mrg 	     && alpha_mlat_string[2] == '\0')
    544  1.1  mrg       {
    545  1.1  mrg 	static int const cache_latency[][4] =
    546  1.1  mrg 	{
    547  1.1  mrg 	  { 3, 30, -1 },	/* ev4 -- Bcache is a guess */
    548  1.1  mrg 	  { 2, 12, 38 },	/* ev5 -- Bcache from PC164 LMbench numbers */
    549  1.1  mrg 	  { 3, 12, 30 },	/* ev6 -- Bcache from DS20 LMbench.  */
    550  1.1  mrg 	};
    551  1.1  mrg 
    552  1.1  mrg 	lat = alpha_mlat_string[1] - '0';
    553  1.1  mrg 	if (lat <= 0 || lat > 3 || cache_latency[alpha_tune][lat-1] == -1)
    554  1.1  mrg 	  {
    555  1.1  mrg 	    warning (0, "L%d cache latency unknown for %s",
    556  1.1  mrg 		     lat, alpha_cpu_name[alpha_tune]);
    557  1.1  mrg 	    lat = 3;
    558  1.1  mrg 	  }
    559  1.1  mrg 	else
    560  1.1  mrg 	  lat = cache_latency[alpha_tune][lat-1];
    561  1.1  mrg       }
    562  1.1  mrg     else if (! strcmp (alpha_mlat_string, "main"))
    563  1.1  mrg       {
    564  1.1  mrg 	/* Most current memories have about 370ns latency.  This is
    565  1.1  mrg 	   a reasonable guess for a fast cpu.  */
    566  1.1  mrg 	lat = 150;
    567  1.1  mrg       }
    568  1.1  mrg     else
    569  1.1  mrg       {
    570  1.1  mrg 	warning (0, "bad value %qs for %<-mmemory-latency%>",
    571  1.1  mrg 		 alpha_mlat_string);
    572  1.1  mrg 	lat = 3;
    573  1.1  mrg       }
    574  1.1  mrg 
    575  1.1  mrg     alpha_memory_latency = lat;
    576  1.1  mrg   }
    577  1.1  mrg 
    578  1.1  mrg   /* Default the definition of "small data" to 8 bytes.  */
    579  1.1  mrg   if (!OPTION_SET_P (g_switch_value))
    580  1.1  mrg     g_switch_value = 8;
    581  1.1  mrg 
    582  1.1  mrg   /* Infer TARGET_SMALL_DATA from -fpic/-fPIC.  */
    583  1.1  mrg   if (flag_pic == 1)
    584  1.1  mrg     target_flags |= MASK_SMALL_DATA;
    585  1.1  mrg   else if (flag_pic == 2)
    586  1.1  mrg     target_flags &= ~MASK_SMALL_DATA;
    587  1.1  mrg 
    588  1.1  mrg   alpha_override_options_after_change ();
    589  1.1  mrg 
    590  1.1  mrg   /* Register variables and functions with the garbage collector.  */
    591  1.1  mrg 
    592  1.1  mrg   /* Set up function hooks.  */
    593  1.1  mrg   init_machine_status = alpha_init_machine_status;
    594  1.1  mrg 
    595  1.1  mrg   /* Tell the compiler when we're using VAX floating point.  */
    596  1.1  mrg   if (TARGET_FLOAT_VAX)
    597  1.1  mrg     {
    598  1.1  mrg       REAL_MODE_FORMAT (SFmode) = &vax_f_format;
    599  1.1  mrg       REAL_MODE_FORMAT (DFmode) = &vax_g_format;
    600  1.1  mrg       REAL_MODE_FORMAT (TFmode) = NULL;
    601  1.1  mrg     }
    602  1.1  mrg 
    603  1.1  mrg #ifdef TARGET_DEFAULT_LONG_DOUBLE_128
    604  1.1  mrg   if (!(target_flags_explicit & MASK_LONG_DOUBLE_128))
    605  1.1  mrg     target_flags |= MASK_LONG_DOUBLE_128;
    606  1.1  mrg #endif
    607  1.1  mrg 
    608  1.1  mrg }
    609  1.1  mrg 
    610  1.1  mrg /* Implement targetm.override_options_after_change.  */
    611  1.1  mrg 
    612  1.1  mrg static void
    613  1.1  mrg alpha_override_options_after_change (void)
    614  1.1  mrg {
    615  1.1  mrg   /* Align labels and loops for optimal branching.  */
    616  1.1  mrg   /* ??? Kludge these by not doing anything if we don't optimize.  */
    617  1.1  mrg   if (optimize > 0)
    618  1.1  mrg     {
    619  1.1  mrg       if (flag_align_loops && !str_align_loops)
    620  1.1  mrg 	str_align_loops = "16";
    621  1.1  mrg       if (flag_align_jumps && !str_align_jumps)
    622  1.1  mrg 	str_align_jumps = "16";
    623  1.1  mrg     }
    624  1.1  mrg   if (flag_align_functions && !str_align_functions)
    625  1.1  mrg     str_align_functions = "16";
    626  1.1  mrg }
    627  1.1  mrg 
    628  1.1  mrg /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones.  */
    630  1.1  mrg 
    631  1.1  mrg int
    632  1.1  mrg zap_mask (HOST_WIDE_INT value)
    633  1.1  mrg {
    634  1.1  mrg   int i;
    635  1.1  mrg 
    636  1.1  mrg   for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
    637  1.1  mrg        i++, value >>= 8)
    638  1.1  mrg     if ((value & 0xff) != 0 && (value & 0xff) != 0xff)
    639  1.1  mrg       return 0;
    640  1.1  mrg 
    641  1.1  mrg   return 1;
    642  1.1  mrg }
    643  1.1  mrg 
    644  1.1  mrg /* Return true if OP is valid for a particular TLS relocation.
    645  1.1  mrg    We are already guaranteed that OP is a CONST.  */
    646  1.1  mrg 
    647  1.1  mrg int
    648  1.1  mrg tls_symbolic_operand_1 (rtx op, int size, int unspec)
    649  1.1  mrg {
    650  1.1  mrg   op = XEXP (op, 0);
    651  1.1  mrg 
    652  1.1  mrg   if (GET_CODE (op) != UNSPEC || XINT (op, 1) != unspec)
    653  1.1  mrg     return 0;
    654  1.1  mrg   op = XVECEXP (op, 0, 0);
    655  1.1  mrg 
    656  1.1  mrg   if (GET_CODE (op) != SYMBOL_REF)
    657  1.1  mrg     return 0;
    658  1.1  mrg 
    659  1.1  mrg   switch (SYMBOL_REF_TLS_MODEL (op))
    660  1.1  mrg     {
    661  1.1  mrg     case TLS_MODEL_LOCAL_DYNAMIC:
    662  1.1  mrg       return unspec == UNSPEC_DTPREL && size == alpha_tls_size;
    663  1.1  mrg     case TLS_MODEL_INITIAL_EXEC:
    664  1.1  mrg       return unspec == UNSPEC_TPREL && size == 64;
    665  1.1  mrg     case TLS_MODEL_LOCAL_EXEC:
    666  1.1  mrg       return unspec == UNSPEC_TPREL && size == alpha_tls_size;
    667  1.1  mrg     default:
    668  1.1  mrg       gcc_unreachable ();
    669  1.1  mrg     }
    670  1.1  mrg }
    671  1.1  mrg 
    672  1.1  mrg /* Used by aligned_memory_operand and unaligned_memory_operand to
    673  1.1  mrg    resolve what reload is going to do with OP if it's a register.  */
    674  1.1  mrg 
    675  1.1  mrg rtx
    676  1.1  mrg resolve_reload_operand (rtx op)
    677  1.1  mrg {
    678  1.1  mrg   if (reload_in_progress)
    679  1.1  mrg     {
    680  1.1  mrg       rtx tmp = op;
    681  1.1  mrg       if (SUBREG_P (tmp))
    682  1.1  mrg 	tmp = SUBREG_REG (tmp);
    683  1.1  mrg       if (REG_P (tmp)
    684  1.1  mrg 	  && REGNO (tmp) >= FIRST_PSEUDO_REGISTER)
    685  1.1  mrg 	{
    686  1.1  mrg 	  op = reg_equiv_memory_loc (REGNO (tmp));
    687  1.1  mrg 	  if (op == 0)
    688  1.1  mrg 	    return 0;
    689  1.1  mrg 	}
    690  1.1  mrg     }
    691  1.1  mrg   return op;
    692  1.1  mrg }
    693  1.1  mrg 
    694  1.1  mrg /* The scalar modes supported differs from the default check-what-c-supports
    695  1.1  mrg    version in that sometimes TFmode is available even when long double
    696  1.1  mrg    indicates only DFmode.  */
    697  1.1  mrg 
    698  1.1  mrg static bool
    699  1.1  mrg alpha_scalar_mode_supported_p (scalar_mode mode)
    700  1.1  mrg {
    701  1.1  mrg   switch (mode)
    702  1.1  mrg     {
    703  1.1  mrg     case E_QImode:
    704  1.1  mrg     case E_HImode:
    705  1.1  mrg     case E_SImode:
    706  1.1  mrg     case E_DImode:
    707  1.1  mrg     case E_TImode: /* via optabs.cc */
    708  1.1  mrg       return true;
    709  1.1  mrg 
    710  1.1  mrg     case E_SFmode:
    711  1.1  mrg     case E_DFmode:
    712  1.1  mrg       return true;
    713  1.1  mrg 
    714  1.1  mrg     case E_TFmode:
    715  1.1  mrg       return TARGET_HAS_XFLOATING_LIBS;
    716  1.1  mrg 
    717  1.1  mrg     default:
    718  1.1  mrg       return false;
    719  1.1  mrg     }
    720  1.1  mrg }
    721  1.1  mrg 
    722  1.1  mrg /* Alpha implements a couple of integer vector mode operations when
    723  1.1  mrg    TARGET_MAX is enabled.  We do not check TARGET_MAX here, however,
    724  1.1  mrg    which allows the vectorizer to operate on e.g. move instructions,
    725  1.1  mrg    or when expand_vector_operations can do something useful.  */
    726  1.1  mrg 
    727  1.1  mrg static bool
    728  1.1  mrg alpha_vector_mode_supported_p (machine_mode mode)
    729  1.1  mrg {
    730  1.1  mrg   return mode == V8QImode || mode == V4HImode || mode == V2SImode;
    731  1.1  mrg }
    732  1.1  mrg 
    733  1.1  mrg /* Return the TLS model to use for SYMBOL.  */
    734  1.1  mrg 
    735  1.1  mrg static enum tls_model
    736  1.1  mrg tls_symbolic_operand_type (rtx symbol)
    737  1.1  mrg {
    738  1.1  mrg   enum tls_model model;
    739  1.1  mrg 
    740  1.1  mrg   if (GET_CODE (symbol) != SYMBOL_REF)
    741  1.1  mrg     return TLS_MODEL_NONE;
    742  1.1  mrg   model = SYMBOL_REF_TLS_MODEL (symbol);
    743  1.1  mrg 
    744  1.1  mrg   /* Local-exec with a 64-bit size is the same code as initial-exec.  */
    745  1.1  mrg   if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
    746  1.1  mrg     model = TLS_MODEL_INITIAL_EXEC;
    747  1.1  mrg 
    748  1.1  mrg   return model;
    749  1.1  mrg }
    750  1.1  mrg 
    751  1.1  mrg /* Return true if the function DECL will share the same GP as any
    753  1.1  mrg    function in the current unit of translation.  */
    754  1.1  mrg 
    755  1.1  mrg static bool
    756  1.1  mrg decl_has_samegp (const_tree decl)
    757  1.1  mrg {
    758  1.1  mrg   /* Functions that are not local can be overridden, and thus may
    759  1.1  mrg      not share the same gp.  */
    760  1.1  mrg   if (!(*targetm.binds_local_p) (decl))
    761  1.1  mrg     return false;
    762  1.1  mrg 
    763  1.1  mrg   /* If -msmall-data is in effect, assume that there is only one GP
    764  1.1  mrg      for the module, and so any local symbol has this property.  We
    765  1.1  mrg      need explicit relocations to be able to enforce this for symbols
    766  1.1  mrg      not defined in this unit of translation, however.  */
    767  1.1  mrg   if (TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA)
    768  1.1  mrg     return true;
    769  1.1  mrg 
    770  1.1  mrg   /* Functions that are not external are defined in this UoT.  */
    771  1.1  mrg   /* ??? Irritatingly, static functions not yet emitted are still
    772  1.1  mrg      marked "external".  Apply this to non-static functions only.  */
    773  1.1  mrg   return !TREE_PUBLIC (decl) || !DECL_EXTERNAL (decl);
    774  1.1  mrg }
    775  1.1  mrg 
    776  1.1  mrg /* Return true if EXP should be placed in the small data section.  */
    777  1.1  mrg 
    778  1.1  mrg static bool
    779  1.1  mrg alpha_in_small_data_p (const_tree exp)
    780  1.1  mrg {
    781  1.1  mrg   /* We want to merge strings, so we never consider them small data.  */
    782  1.1  mrg   if (TREE_CODE (exp) == STRING_CST)
    783  1.1  mrg     return false;
    784  1.1  mrg 
    785  1.1  mrg   /* Functions are never in the small data area.  Duh.  */
    786  1.1  mrg   if (TREE_CODE (exp) == FUNCTION_DECL)
    787  1.1  mrg     return false;
    788  1.1  mrg 
    789  1.1  mrg   /* COMMON symbols are never small data.  */
    790  1.1  mrg   if (TREE_CODE (exp) == VAR_DECL && DECL_COMMON (exp))
    791  1.1  mrg     return false;
    792  1.1  mrg 
    793  1.1  mrg   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
    794  1.1  mrg     {
    795  1.1  mrg       const char *section = DECL_SECTION_NAME (exp);
    796  1.1  mrg       if (strcmp (section, ".sdata") == 0
    797  1.1  mrg 	  || strcmp (section, ".sbss") == 0)
    798  1.1  mrg 	return true;
    799  1.1  mrg     }
    800  1.1  mrg   else
    801  1.1  mrg     {
    802  1.1  mrg       HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
    803  1.1  mrg 
    804  1.1  mrg       /* If this is an incomplete type with size 0, then we can't put it
    805  1.1  mrg 	 in sdata because it might be too big when completed.  */
    806  1.1  mrg       if (size > 0 && size <= g_switch_value)
    807  1.1  mrg 	return true;
    808  1.1  mrg     }
    809  1.1  mrg 
    810  1.1  mrg   return false;
    811  1.1  mrg }
    812  1.1  mrg 
    813  1.1  mrg #if TARGET_ABI_OPEN_VMS
    814  1.1  mrg static bool
    815  1.1  mrg vms_valid_pointer_mode (scalar_int_mode mode)
    816  1.1  mrg {
    817  1.1  mrg   return (mode == SImode || mode == DImode);
    818  1.1  mrg }
    819  1.1  mrg 
    820  1.1  mrg static bool
    821  1.1  mrg alpha_linkage_symbol_p (const char *symname)
    822  1.1  mrg {
    823  1.1  mrg   int symlen = strlen (symname);
    824  1.1  mrg 
    825  1.1  mrg   if (symlen > 4)
    826  1.1  mrg     return strcmp (&symname [symlen - 4], "..lk") == 0;
    827  1.1  mrg 
    828  1.1  mrg   return false;
    829  1.1  mrg }
    830  1.1  mrg 
    831  1.1  mrg #define LINKAGE_SYMBOL_REF_P(X) \
    832  1.1  mrg   ((GET_CODE (X) == SYMBOL_REF   \
    833  1.1  mrg     && alpha_linkage_symbol_p (XSTR (X, 0))) \
    834  1.1  mrg    || (GET_CODE (X) == CONST                 \
    835  1.1  mrg        && GET_CODE (XEXP (X, 0)) == PLUS     \
    836  1.1  mrg        && GET_CODE (XEXP (XEXP (X, 0), 0)) == SYMBOL_REF \
    837  1.1  mrg        && alpha_linkage_symbol_p (XSTR (XEXP (XEXP (X, 0), 0), 0))))
    838  1.1  mrg #endif
    839  1.1  mrg 
    840  1.1  mrg /* legitimate_address_p recognizes an RTL expression that is a valid
    841  1.1  mrg    memory address for an instruction.  The MODE argument is the
    842  1.1  mrg    machine mode for the MEM expression that wants to use this address.
    843  1.1  mrg 
    844  1.1  mrg    For Alpha, we have either a constant address or the sum of a
    845  1.1  mrg    register and a constant address, or just a register.  For DImode,
    846  1.1  mrg    any of those forms can be surrounded with an AND that clear the
    847  1.1  mrg    low-order three bits; this is an "unaligned" access.  */
    848  1.1  mrg 
    849  1.1  mrg static bool
    850  1.1  mrg alpha_legitimate_address_p (machine_mode mode, rtx x, bool strict)
    851  1.1  mrg {
    852  1.1  mrg   /* If this is an ldq_u type address, discard the outer AND.  */
    853  1.1  mrg   if (mode == DImode
    854  1.1  mrg       && GET_CODE (x) == AND
    855  1.1  mrg       && CONST_INT_P (XEXP (x, 1))
    856  1.1  mrg       && INTVAL (XEXP (x, 1)) == -8)
    857  1.1  mrg     x = XEXP (x, 0);
    858  1.1  mrg 
    859  1.1  mrg   /* Discard non-paradoxical subregs.  */
    860  1.1  mrg   if (SUBREG_P (x)
    861  1.1  mrg       && (GET_MODE_SIZE (GET_MODE (x))
    862  1.1  mrg 	  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
    863  1.1  mrg     x = SUBREG_REG (x);
    864  1.1  mrg 
    865  1.1  mrg   /* Unadorned general registers are valid.  */
    866  1.1  mrg   if (REG_P (x)
    867  1.1  mrg       && (strict
    868  1.1  mrg 	  ? STRICT_REG_OK_FOR_BASE_P (x)
    869  1.1  mrg 	  : NONSTRICT_REG_OK_FOR_BASE_P (x)))
    870  1.1  mrg     return true;
    871  1.1  mrg 
    872  1.1  mrg   /* Constant addresses (i.e. +/- 32k) are valid.  */
    873  1.1  mrg   if (CONSTANT_ADDRESS_P (x))
    874  1.1  mrg     return true;
    875  1.1  mrg 
    876  1.1  mrg #if TARGET_ABI_OPEN_VMS
    877  1.1  mrg   if (LINKAGE_SYMBOL_REF_P (x))
    878  1.1  mrg     return true;
    879  1.1  mrg #endif
    880  1.1  mrg 
    881  1.1  mrg   /* Register plus a small constant offset is valid.  */
    882  1.1  mrg   if (GET_CODE (x) == PLUS)
    883  1.1  mrg     {
    884  1.1  mrg       rtx ofs = XEXP (x, 1);
    885  1.1  mrg       x = XEXP (x, 0);
    886  1.1  mrg 
    887  1.1  mrg       /* Discard non-paradoxical subregs.  */
    888  1.1  mrg       if (SUBREG_P (x)
    889  1.1  mrg           && (GET_MODE_SIZE (GET_MODE (x))
    890  1.1  mrg 	      < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
    891  1.1  mrg 	x = SUBREG_REG (x);
    892  1.1  mrg 
    893  1.1  mrg       if (REG_P (x))
    894  1.1  mrg 	{
    895  1.1  mrg 	  if (! strict
    896  1.1  mrg 	      && NONSTRICT_REG_OK_FP_BASE_P (x)
    897  1.1  mrg 	      && CONST_INT_P (ofs))
    898  1.1  mrg 	    return true;
    899  1.1  mrg 	  if ((strict
    900  1.1  mrg 	       ? STRICT_REG_OK_FOR_BASE_P (x)
    901  1.1  mrg 	       : NONSTRICT_REG_OK_FOR_BASE_P (x))
    902  1.1  mrg 	      && CONSTANT_ADDRESS_P (ofs))
    903  1.1  mrg 	    return true;
    904  1.1  mrg 	}
    905  1.1  mrg     }
    906  1.1  mrg 
    907  1.1  mrg   /* If we're managing explicit relocations, LO_SUM is valid, as are small
    908  1.1  mrg      data symbols.  Avoid explicit relocations of modes larger than word
    909  1.1  mrg      mode since i.e. $LC0+8($1) can fold around +/- 32k offset.  */
    910  1.1  mrg   else if (TARGET_EXPLICIT_RELOCS
    911  1.1  mrg 	   && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
    912  1.1  mrg     {
    913  1.1  mrg       if (small_symbolic_operand (x, Pmode))
    914  1.1  mrg 	return true;
    915  1.1  mrg 
    916  1.1  mrg       if (GET_CODE (x) == LO_SUM)
    917  1.1  mrg 	{
    918  1.1  mrg 	  rtx ofs = XEXP (x, 1);
    919  1.1  mrg 	  x = XEXP (x, 0);
    920  1.1  mrg 
    921  1.1  mrg 	  /* Discard non-paradoxical subregs.  */
    922  1.1  mrg 	  if (SUBREG_P (x)
    923  1.1  mrg 	      && (GET_MODE_SIZE (GET_MODE (x))
    924  1.1  mrg 		  < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
    925  1.1  mrg 	    x = SUBREG_REG (x);
    926  1.1  mrg 
    927  1.1  mrg 	  /* Must have a valid base register.  */
    928  1.1  mrg 	  if (! (REG_P (x)
    929  1.1  mrg 		 && (strict
    930  1.1  mrg 		     ? STRICT_REG_OK_FOR_BASE_P (x)
    931  1.1  mrg 		     : NONSTRICT_REG_OK_FOR_BASE_P (x))))
    932  1.1  mrg 	    return false;
    933  1.1  mrg 
    934  1.1  mrg 	  /* The symbol must be local.  */
    935  1.1  mrg 	  if (local_symbolic_operand (ofs, Pmode)
    936  1.1  mrg 	      || dtp32_symbolic_operand (ofs, Pmode)
    937  1.1  mrg 	      || tp32_symbolic_operand (ofs, Pmode))
    938  1.1  mrg 	    return true;
    939  1.1  mrg 	}
    940  1.1  mrg     }
    941  1.1  mrg 
    942  1.1  mrg   return false;
    943  1.1  mrg }
    944  1.1  mrg 
    945  1.1  mrg /* Build the SYMBOL_REF for __tls_get_addr.  */
    946  1.1  mrg 
    947  1.1  mrg static GTY(()) rtx tls_get_addr_libfunc;
    948  1.1  mrg 
    949  1.1  mrg static rtx
    950  1.1  mrg get_tls_get_addr (void)
    951  1.1  mrg {
    952  1.1  mrg   if (!tls_get_addr_libfunc)
    953  1.1  mrg     tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
    954  1.1  mrg   return tls_get_addr_libfunc;
    955  1.1  mrg }
    956  1.1  mrg 
    957  1.1  mrg /* Try machine-dependent ways of modifying an illegitimate address
    958  1.1  mrg    to be legitimate.  If we find one, return the new, valid address.  */
    959  1.1  mrg 
    960  1.1  mrg static rtx
    961  1.1  mrg alpha_legitimize_address_1 (rtx x, rtx scratch, machine_mode mode)
    962  1.1  mrg {
    963  1.1  mrg   HOST_WIDE_INT addend;
    964  1.1  mrg 
    965  1.1  mrg   /* If the address is (plus reg const_int) and the CONST_INT is not a
    966  1.1  mrg      valid offset, compute the high part of the constant and add it to
    967  1.1  mrg      the register.  Then our address is (plus temp low-part-const).  */
    968  1.1  mrg   if (GET_CODE (x) == PLUS
    969  1.1  mrg       && REG_P (XEXP (x, 0))
    970  1.1  mrg       && CONST_INT_P (XEXP (x, 1))
    971  1.1  mrg       && ! CONSTANT_ADDRESS_P (XEXP (x, 1)))
    972  1.1  mrg     {
    973  1.1  mrg       addend = INTVAL (XEXP (x, 1));
    974  1.1  mrg       x = XEXP (x, 0);
    975  1.1  mrg       goto split_addend;
    976  1.1  mrg     }
    977  1.1  mrg 
    978  1.1  mrg   /* If the address is (const (plus FOO const_int)), find the low-order
    979  1.1  mrg      part of the CONST_INT.  Then load FOO plus any high-order part of the
    980  1.1  mrg      CONST_INT into a register.  Our address is (plus reg low-part-const).
    981  1.1  mrg      This is done to reduce the number of GOT entries.  */
    982  1.1  mrg   if (can_create_pseudo_p ()
    983  1.1  mrg       && GET_CODE (x) == CONST
    984  1.1  mrg       && GET_CODE (XEXP (x, 0)) == PLUS
    985  1.1  mrg       && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
    986  1.1  mrg     {
    987  1.1  mrg       addend = INTVAL (XEXP (XEXP (x, 0), 1));
    988  1.1  mrg       x = force_reg (Pmode, XEXP (XEXP (x, 0), 0));
    989  1.1  mrg       goto split_addend;
    990  1.1  mrg     }
    991  1.1  mrg 
    992  1.1  mrg   /* If we have a (plus reg const), emit the load as in (2), then add
    993  1.1  mrg      the two registers, and finally generate (plus reg low-part-const) as
    994  1.1  mrg      our address.  */
    995  1.1  mrg   if (can_create_pseudo_p ()
    996  1.1  mrg       && GET_CODE (x) == PLUS
    997  1.1  mrg       && REG_P (XEXP (x, 0))
    998  1.1  mrg       && GET_CODE (XEXP (x, 1)) == CONST
    999  1.1  mrg       && GET_CODE (XEXP (XEXP (x, 1), 0)) == PLUS
   1000  1.1  mrg       && CONST_INT_P (XEXP (XEXP (XEXP (x, 1), 0), 1)))
   1001  1.1  mrg     {
   1002  1.1  mrg       addend = INTVAL (XEXP (XEXP (XEXP (x, 1), 0), 1));
   1003  1.1  mrg       x = expand_simple_binop (Pmode, PLUS, XEXP (x, 0),
   1004  1.1  mrg 			       XEXP (XEXP (XEXP (x, 1), 0), 0),
   1005  1.1  mrg 			       NULL_RTX, 1, OPTAB_LIB_WIDEN);
   1006  1.1  mrg       goto split_addend;
   1007  1.1  mrg     }
   1008  1.1  mrg 
   1009  1.1  mrg   /* If this is a local symbol, split the address into HIGH/LO_SUM parts.
   1010  1.1  mrg      Avoid modes larger than word mode since i.e. $LC0+8($1) can fold
   1011  1.1  mrg      around +/- 32k offset.  */
   1012  1.1  mrg   if (TARGET_EXPLICIT_RELOCS
   1013  1.1  mrg       && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
   1014  1.1  mrg       && symbolic_operand (x, Pmode))
   1015  1.1  mrg     {
   1016  1.1  mrg       rtx r0, r16, eqv, tga, tp, dest, seq;
   1017  1.1  mrg       rtx_insn *insn;
   1018  1.1  mrg 
   1019  1.1  mrg       switch (tls_symbolic_operand_type (x))
   1020  1.1  mrg 	{
   1021  1.1  mrg 	case TLS_MODEL_NONE:
   1022  1.1  mrg 	  break;
   1023  1.1  mrg 
   1024  1.1  mrg 	case TLS_MODEL_GLOBAL_DYNAMIC:
   1025  1.1  mrg 	  {
   1026  1.1  mrg 	    start_sequence ();
   1027  1.1  mrg 
   1028  1.1  mrg 	    r0 = gen_rtx_REG (Pmode, 0);
   1029  1.1  mrg 	    r16 = gen_rtx_REG (Pmode, 16);
   1030  1.1  mrg 	    tga = get_tls_get_addr ();
   1031  1.1  mrg 	    dest = gen_reg_rtx (Pmode);
   1032  1.1  mrg 	    seq = GEN_INT (alpha_next_sequence_number++);
   1033  1.1  mrg 
   1034  1.1  mrg 	    emit_insn (gen_movdi_er_tlsgd (r16, pic_offset_table_rtx, x, seq));
   1035  1.1  mrg 	    rtx val = gen_call_value_osf_tlsgd (r0, tga, seq);
   1036  1.1  mrg 	    insn = emit_call_insn (val);
   1037  1.1  mrg 	    RTL_CONST_CALL_P (insn) = 1;
   1038  1.1  mrg 	    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
   1039  1.1  mrg 
   1040  1.1  mrg 	    insn = get_insns ();
   1041  1.1  mrg 	    end_sequence ();
   1042  1.1  mrg 
   1043  1.1  mrg 	    emit_libcall_block (insn, dest, r0, x);
   1044  1.1  mrg 	    return dest;
   1045  1.1  mrg 	  }
   1046  1.1  mrg 
   1047  1.1  mrg 	case TLS_MODEL_LOCAL_DYNAMIC:
   1048  1.1  mrg 	  {
   1049  1.1  mrg 	    start_sequence ();
   1050  1.1  mrg 
   1051  1.1  mrg 	    r0 = gen_rtx_REG (Pmode, 0);
   1052  1.1  mrg 	    r16 = gen_rtx_REG (Pmode, 16);
   1053  1.1  mrg 	    tga = get_tls_get_addr ();
   1054  1.1  mrg 	    scratch = gen_reg_rtx (Pmode);
   1055  1.1  mrg 	    seq = GEN_INT (alpha_next_sequence_number++);
   1056  1.1  mrg 
   1057  1.1  mrg 	    emit_insn (gen_movdi_er_tlsldm (r16, pic_offset_table_rtx, seq));
   1058  1.1  mrg 	    rtx val = gen_call_value_osf_tlsldm (r0, tga, seq);
   1059  1.1  mrg 	    insn = emit_call_insn (val);
   1060  1.1  mrg 	    RTL_CONST_CALL_P (insn) = 1;
   1061  1.1  mrg 	    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r16);
   1062  1.1  mrg 
   1063  1.1  mrg 	    insn = get_insns ();
   1064  1.1  mrg 	    end_sequence ();
   1065  1.1  mrg 
   1066  1.1  mrg 	    eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
   1067  1.1  mrg 				  UNSPEC_TLSLDM_CALL);
   1068  1.1  mrg 	    emit_libcall_block (insn, scratch, r0, eqv);
   1069  1.1  mrg 
   1070  1.1  mrg 	    eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPREL);
   1071  1.1  mrg 	    eqv = gen_rtx_CONST (Pmode, eqv);
   1072  1.1  mrg 
   1073  1.1  mrg 	    if (alpha_tls_size == 64)
   1074  1.1  mrg 	      {
   1075  1.1  mrg 		dest = gen_reg_rtx (Pmode);
   1076  1.1  mrg 		emit_insn (gen_rtx_SET (dest, eqv));
   1077  1.1  mrg 		emit_insn (gen_adddi3 (dest, dest, scratch));
   1078  1.1  mrg 		return dest;
   1079  1.1  mrg 	      }
   1080  1.1  mrg 	    if (alpha_tls_size == 32)
   1081  1.1  mrg 	      {
   1082  1.1  mrg 		rtx temp = gen_rtx_HIGH (Pmode, eqv);
   1083  1.1  mrg 		temp = gen_rtx_PLUS (Pmode, scratch, temp);
   1084  1.1  mrg 		scratch = gen_reg_rtx (Pmode);
   1085  1.1  mrg 		emit_insn (gen_rtx_SET (scratch, temp));
   1086  1.1  mrg 	      }
   1087  1.1  mrg 	    return gen_rtx_LO_SUM (Pmode, scratch, eqv);
   1088  1.1  mrg 	  }
   1089  1.1  mrg 
   1090  1.1  mrg 	case TLS_MODEL_INITIAL_EXEC:
   1091  1.1  mrg 	  eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
   1092  1.1  mrg 	  eqv = gen_rtx_CONST (Pmode, eqv);
   1093  1.1  mrg 	  tp = gen_reg_rtx (Pmode);
   1094  1.1  mrg 	  scratch = gen_reg_rtx (Pmode);
   1095  1.1  mrg 	  dest = gen_reg_rtx (Pmode);
   1096  1.1  mrg 
   1097  1.1  mrg 	  emit_insn (gen_get_thread_pointerdi (tp));
   1098  1.1  mrg 	  emit_insn (gen_rtx_SET (scratch, eqv));
   1099  1.1  mrg 	  emit_insn (gen_adddi3 (dest, tp, scratch));
   1100  1.1  mrg 	  return dest;
   1101  1.1  mrg 
   1102  1.1  mrg 	case TLS_MODEL_LOCAL_EXEC:
   1103  1.1  mrg 	  eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_TPREL);
   1104  1.1  mrg 	  eqv = gen_rtx_CONST (Pmode, eqv);
   1105  1.1  mrg 	  tp = gen_reg_rtx (Pmode);
   1106  1.1  mrg 
   1107  1.1  mrg 	  emit_insn (gen_get_thread_pointerdi (tp));
   1108  1.1  mrg 	  if (alpha_tls_size == 32)
   1109  1.1  mrg 	    {
   1110  1.1  mrg 	      rtx temp = gen_rtx_HIGH (Pmode, eqv);
   1111  1.1  mrg 	      temp = gen_rtx_PLUS (Pmode, tp, temp);
   1112  1.1  mrg 	      tp = gen_reg_rtx (Pmode);
   1113  1.1  mrg 	      emit_insn (gen_rtx_SET (tp, temp));
   1114  1.1  mrg 	    }
   1115  1.1  mrg 	  return gen_rtx_LO_SUM (Pmode, tp, eqv);
   1116  1.1  mrg 
   1117  1.1  mrg 	default:
   1118  1.1  mrg 	  gcc_unreachable ();
   1119  1.1  mrg 	}
   1120  1.1  mrg 
   1121  1.1  mrg       if (local_symbolic_operand (x, Pmode))
   1122  1.1  mrg 	{
   1123  1.1  mrg 	  if (small_symbolic_operand (x, Pmode))
   1124  1.1  mrg 	    return x;
   1125  1.1  mrg 	  else
   1126  1.1  mrg 	    {
   1127  1.1  mrg 	      if (can_create_pseudo_p ())
   1128  1.1  mrg 	        scratch = gen_reg_rtx (Pmode);
   1129  1.1  mrg 	      emit_insn (gen_rtx_SET (scratch, gen_rtx_HIGH (Pmode, x)));
   1130  1.1  mrg 	      return gen_rtx_LO_SUM (Pmode, scratch, x);
   1131  1.1  mrg 	    }
   1132  1.1  mrg 	}
   1133  1.1  mrg     }
   1134  1.1  mrg 
   1135  1.1  mrg   return NULL;
   1136  1.1  mrg 
   1137  1.1  mrg  split_addend:
   1138  1.1  mrg   {
   1139  1.1  mrg     HOST_WIDE_INT low, high;
   1140  1.1  mrg 
   1141  1.1  mrg     low = ((addend & 0xffff) ^ 0x8000) - 0x8000;
   1142  1.1  mrg     addend -= low;
   1143  1.1  mrg     high = ((addend & 0xffffffff) ^ 0x80000000) - 0x80000000;
   1144  1.1  mrg     addend -= high;
   1145  1.1  mrg 
   1146  1.1  mrg     if (addend)
   1147  1.1  mrg       x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (addend),
   1148  1.1  mrg 			       (!can_create_pseudo_p () ? scratch : NULL_RTX),
   1149  1.1  mrg 			       1, OPTAB_LIB_WIDEN);
   1150  1.1  mrg     if (high)
   1151  1.1  mrg       x = expand_simple_binop (Pmode, PLUS, x, GEN_INT (high),
   1152  1.1  mrg 			       (!can_create_pseudo_p () ? scratch : NULL_RTX),
   1153  1.1  mrg 			       1, OPTAB_LIB_WIDEN);
   1154  1.1  mrg 
   1155  1.1  mrg     return plus_constant (Pmode, x, low);
   1156  1.1  mrg   }
   1157  1.1  mrg }
   1158  1.1  mrg 
   1159  1.1  mrg 
   1160  1.1  mrg /* Try machine-dependent ways of modifying an illegitimate address
   1161  1.1  mrg    to be legitimate.  Return X or the new, valid address.  */
   1162  1.1  mrg 
   1163  1.1  mrg static rtx
   1164  1.1  mrg alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
   1165  1.1  mrg 			  machine_mode mode)
   1166  1.1  mrg {
   1167  1.1  mrg   rtx new_x = alpha_legitimize_address_1 (x, NULL_RTX, mode);
   1168  1.1  mrg   return new_x ? new_x : x;
   1169  1.1  mrg }
   1170  1.1  mrg 
   1171  1.1  mrg /* Return true if ADDR has an effect that depends on the machine mode it
   1172  1.1  mrg    is used for.  On the Alpha this is true only for the unaligned modes.
   1173  1.1  mrg    We can simplify the test since we know that the address must be valid.  */
   1174  1.1  mrg 
   1175  1.1  mrg static bool
   1176  1.1  mrg alpha_mode_dependent_address_p (const_rtx addr,
   1177  1.1  mrg 				addr_space_t as ATTRIBUTE_UNUSED)
   1178  1.1  mrg {
   1179  1.1  mrg   return GET_CODE (addr) == AND;
   1180  1.1  mrg }
   1181  1.1  mrg 
   1182  1.1  mrg /* Primarily this is required for TLS symbols, but given that our move
   1183  1.1  mrg    patterns *ought* to be able to handle any symbol at any time, we
   1184  1.1  mrg    should never be spilling symbolic operands to the constant pool, ever.  */
   1185  1.1  mrg 
   1186  1.1  mrg static bool
   1187  1.1  mrg alpha_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
   1188  1.1  mrg {
   1189  1.1  mrg   enum rtx_code code = GET_CODE (x);
   1190  1.1  mrg   return code == SYMBOL_REF || code == LABEL_REF || code == CONST;
   1191  1.1  mrg }
   1192  1.1  mrg 
   1193  1.1  mrg /* We do not allow indirect calls to be optimized into sibling calls, nor
   1194  1.1  mrg    can we allow a call to a function with a different GP to be optimized
   1195  1.1  mrg    into a sibcall.  */
   1196  1.1  mrg 
   1197  1.1  mrg static bool
   1198  1.1  mrg alpha_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
   1199  1.1  mrg {
   1200  1.1  mrg   /* Can't do indirect tail calls, since we don't know if the target
   1201  1.1  mrg      uses the same GP.  */
   1202  1.1  mrg   if (!decl)
   1203  1.1  mrg     return false;
   1204  1.1  mrg 
   1205  1.1  mrg   /* Otherwise, we can make a tail call if the target function shares
   1206  1.1  mrg      the same GP.  */
   1207  1.1  mrg   return decl_has_samegp (decl);
   1208  1.1  mrg }
   1209  1.1  mrg 
   1210  1.1  mrg bool
   1211  1.1  mrg some_small_symbolic_operand_int (rtx x)
   1212  1.1  mrg {
   1213  1.1  mrg   subrtx_var_iterator::array_type array;
   1214  1.1  mrg   FOR_EACH_SUBRTX_VAR (iter, array, x, ALL)
   1215  1.1  mrg     {
   1216  1.1  mrg       rtx x = *iter;
   1217  1.1  mrg       /* Don't re-split.  */
   1218  1.1  mrg       if (GET_CODE (x) == LO_SUM)
   1219  1.1  mrg 	iter.skip_subrtxes ();
   1220  1.1  mrg       else if (small_symbolic_operand (x, Pmode))
   1221  1.1  mrg 	return true;
   1222  1.1  mrg     }
   1223  1.1  mrg   return false;
   1224  1.1  mrg }
   1225  1.1  mrg 
   1226  1.1  mrg rtx
   1227  1.1  mrg split_small_symbolic_operand (rtx x)
   1228  1.1  mrg {
   1229  1.1  mrg   x = copy_insn (x);
   1230  1.1  mrg   subrtx_ptr_iterator::array_type array;
   1231  1.1  mrg   FOR_EACH_SUBRTX_PTR (iter, array, &x, ALL)
   1232  1.1  mrg     {
   1233  1.1  mrg       rtx *ptr = *iter;
   1234  1.1  mrg       rtx x = *ptr;
   1235  1.1  mrg       /* Don't re-split.  */
   1236  1.1  mrg       if (GET_CODE (x) == LO_SUM)
   1237  1.1  mrg 	iter.skip_subrtxes ();
   1238  1.1  mrg       else if (small_symbolic_operand (x, Pmode))
   1239  1.1  mrg 	{
   1240  1.1  mrg 	  *ptr = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, x);
   1241  1.1  mrg 	  iter.skip_subrtxes ();
   1242  1.1  mrg 	}
   1243  1.1  mrg     }
   1244  1.1  mrg   return x;
   1245  1.1  mrg }
   1246  1.1  mrg 
   1247  1.1  mrg /* Indicate that INSN cannot be duplicated.  This is true for any insn
   1248  1.1  mrg    that we've marked with gpdisp relocs, since those have to stay in
   1249  1.1  mrg    1-1 correspondence with one another.
   1250  1.1  mrg 
   1251  1.1  mrg    Technically we could copy them if we could set up a mapping from one
   1252  1.1  mrg    sequence number to another, across the set of insns to be duplicated.
   1253  1.1  mrg    This seems overly complicated and error-prone since interblock motion
   1254  1.1  mrg    from sched-ebb could move one of the pair of insns to a different block.
   1255  1.1  mrg 
   1256  1.1  mrg    Also cannot allow jsr insns to be duplicated.  If they throw exceptions,
   1257  1.1  mrg    then they'll be in a different block from their ldgp.  Which could lead
   1258  1.1  mrg    the bb reorder code to think that it would be ok to copy just the block
   1259  1.1  mrg    containing the call and branch to the block containing the ldgp.  */
   1260  1.1  mrg 
   1261  1.1  mrg static bool
   1262  1.1  mrg alpha_cannot_copy_insn_p (rtx_insn *insn)
   1263  1.1  mrg {
   1264  1.1  mrg   if (!reload_completed || !TARGET_EXPLICIT_RELOCS)
   1265  1.1  mrg     return false;
   1266  1.1  mrg   if (recog_memoized (insn) >= 0)
   1267  1.1  mrg     return get_attr_cannot_copy (insn);
   1268  1.1  mrg   else
   1269  1.1  mrg     return false;
   1270  1.1  mrg }
   1271  1.1  mrg 
   1272  1.1  mrg 
   1273  1.1  mrg /* Try a machine-dependent way of reloading an illegitimate address
   1274  1.1  mrg    operand.  If we find one, push the reload and return the new rtx.  */
   1275  1.1  mrg 
   1276  1.1  mrg rtx
   1277  1.1  mrg alpha_legitimize_reload_address (rtx x,
   1278  1.1  mrg 				 machine_mode mode ATTRIBUTE_UNUSED,
   1279  1.1  mrg 				 int opnum, int type,
   1280  1.1  mrg 				 int ind_levels ATTRIBUTE_UNUSED)
   1281  1.1  mrg {
   1282  1.1  mrg   /* We must recognize output that we have already generated ourselves.  */
   1283  1.1  mrg   if (GET_CODE (x) == PLUS
   1284  1.1  mrg       && GET_CODE (XEXP (x, 0)) == PLUS
   1285  1.1  mrg       && REG_P (XEXP (XEXP (x, 0), 0))
   1286  1.1  mrg       && CONST_INT_P (XEXP (XEXP (x, 0), 1))
   1287  1.1  mrg       && CONST_INT_P (XEXP (x, 1)))
   1288  1.1  mrg     {
   1289  1.1  mrg       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
   1290  1.1  mrg 		   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
   1291  1.1  mrg 		   opnum, (enum reload_type) type);
   1292  1.1  mrg       return x;
   1293  1.1  mrg     }
   1294  1.1  mrg 
   1295  1.1  mrg   /* We wish to handle large displacements off a base register by
   1296  1.1  mrg      splitting the addend across an ldah and the mem insn.  This
   1297  1.1  mrg      cuts number of extra insns needed from 3 to 1.  */
   1298  1.1  mrg   if (GET_CODE (x) == PLUS
   1299  1.1  mrg       && REG_P (XEXP (x, 0))
   1300  1.1  mrg       && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
   1301  1.1  mrg       && REGNO_OK_FOR_BASE_P (REGNO (XEXP (x, 0)))
   1302  1.1  mrg       && CONST_INT_P (XEXP (x, 1)))
   1303  1.1  mrg     {
   1304  1.1  mrg       HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
   1305  1.1  mrg       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
   1306  1.1  mrg       HOST_WIDE_INT high
   1307  1.1  mrg 	= (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
   1308  1.1  mrg 
   1309  1.1  mrg       /* Check for 32-bit overflow.  */
   1310  1.1  mrg       if (high + low != val)
   1311  1.1  mrg 	return NULL_RTX;
   1312  1.1  mrg 
   1313  1.1  mrg       /* Reload the high part into a base reg; leave the low part
   1314  1.1  mrg 	 in the mem directly.  */
   1315  1.1  mrg       x = gen_rtx_PLUS (GET_MODE (x),
   1316  1.1  mrg 			gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
   1317  1.1  mrg 				      GEN_INT (high)),
   1318  1.1  mrg 			GEN_INT (low));
   1319  1.1  mrg 
   1320  1.1  mrg       push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
   1321  1.1  mrg 		   BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
   1322  1.1  mrg 		   opnum, (enum reload_type) type);
   1323  1.1  mrg       return x;
   1324  1.1  mrg     }
   1325  1.1  mrg 
   1326  1.1  mrg   return NULL_RTX;
   1327  1.1  mrg }
   1328  1.1  mrg 
   1329  1.1  mrg /* Return the cost of moving between registers of various classes.  Moving
   1331  1.1  mrg    between FLOAT_REGS and anything else except float regs is expensive.
   1332  1.1  mrg    In fact, we make it quite expensive because we really don't want to
   1333  1.1  mrg    do these moves unless it is clearly worth it.  Optimizations may
   1334  1.1  mrg    reduce the impact of not being able to allocate a pseudo to a
   1335  1.1  mrg    hard register.  */
   1336  1.1  mrg 
   1337  1.1  mrg static int
   1338  1.1  mrg alpha_register_move_cost (machine_mode /*mode*/,
   1339  1.1  mrg 			  reg_class_t from, reg_class_t to)
   1340  1.1  mrg {
   1341  1.1  mrg   if ((from == FLOAT_REGS) == (to == FLOAT_REGS))
   1342  1.1  mrg     return 2;
   1343  1.1  mrg 
   1344  1.1  mrg   if (TARGET_FIX)
   1345  1.1  mrg     return (from == FLOAT_REGS) ? 6 : 8;
   1346  1.1  mrg 
   1347  1.1  mrg   return 4 + 2 * alpha_memory_latency;
   1348  1.1  mrg }
   1349  1.1  mrg 
   1350  1.1  mrg /* Return the cost of moving data of MODE from a register to
   1351  1.1  mrg    or from memory.  On the Alpha, bump this up a bit.  */
   1352  1.1  mrg 
   1353  1.1  mrg static int
   1354  1.1  mrg alpha_memory_move_cost (machine_mode /*mode*/, reg_class_t /*regclass*/,
   1355  1.1  mrg 			bool /*in*/)
   1356  1.1  mrg {
   1357  1.1  mrg   return 2 * alpha_memory_latency;
   1358  1.1  mrg }
   1359  1.1  mrg 
   1360  1.1  mrg /* Compute a (partial) cost for rtx X.  Return true if the complete
   1361  1.1  mrg    cost has been computed, and false if subexpressions should be
   1362  1.1  mrg    scanned.  In either case, *TOTAL contains the cost result.  */
   1363  1.1  mrg 
   1364  1.1  mrg static bool
   1365  1.1  mrg alpha_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total,
   1366  1.1  mrg 		 bool speed)
   1367  1.1  mrg {
   1368  1.1  mrg   int code = GET_CODE (x);
   1369  1.1  mrg   bool float_mode_p = FLOAT_MODE_P (mode);
   1370  1.1  mrg   const struct alpha_rtx_cost_data *cost_data;
   1371  1.1  mrg 
   1372  1.1  mrg   if (!speed)
   1373  1.1  mrg     cost_data = &alpha_rtx_cost_size;
   1374  1.1  mrg   else
   1375  1.1  mrg     cost_data = &alpha_rtx_cost_data[alpha_tune];
   1376  1.1  mrg 
   1377  1.1  mrg   switch (code)
   1378  1.1  mrg     {
   1379  1.1  mrg     case CONST_INT:
   1380  1.1  mrg       /* If this is an 8-bit constant, return zero since it can be used
   1381  1.1  mrg 	 nearly anywhere with no cost.  If it is a valid operand for an
   1382  1.1  mrg 	 ADD or AND, likewise return 0 if we know it will be used in that
   1383  1.1  mrg 	 context.  Otherwise, return 2 since it might be used there later.
   1384  1.1  mrg 	 All other constants take at least two insns.  */
   1385  1.1  mrg       if (INTVAL (x) >= 0 && INTVAL (x) < 256)
   1386  1.1  mrg 	{
   1387  1.1  mrg 	  *total = 0;
   1388  1.1  mrg 	  return true;
   1389  1.1  mrg 	}
   1390  1.1  mrg       /* FALLTHRU */
   1391  1.1  mrg 
   1392  1.1  mrg     case CONST_DOUBLE:
   1393  1.1  mrg     case CONST_WIDE_INT:
   1394  1.1  mrg       if (x == CONST0_RTX (mode))
   1395  1.1  mrg 	*total = 0;
   1396  1.1  mrg       else if ((outer_code == PLUS && add_operand (x, VOIDmode))
   1397  1.1  mrg 	       || (outer_code == AND && and_operand (x, VOIDmode)))
   1398  1.1  mrg 	*total = 0;
   1399  1.1  mrg       else if (add_operand (x, VOIDmode) || and_operand (x, VOIDmode))
   1400  1.1  mrg 	*total = 2;
   1401  1.1  mrg       else
   1402  1.1  mrg 	*total = COSTS_N_INSNS (2);
   1403  1.1  mrg       return true;
   1404  1.1  mrg 
   1405  1.1  mrg     case CONST:
   1406  1.1  mrg     case SYMBOL_REF:
   1407  1.1  mrg     case LABEL_REF:
   1408  1.1  mrg       if (TARGET_EXPLICIT_RELOCS && small_symbolic_operand (x, VOIDmode))
   1409  1.1  mrg 	*total = COSTS_N_INSNS (outer_code != MEM);
   1410  1.1  mrg       else if (TARGET_EXPLICIT_RELOCS && local_symbolic_operand (x, VOIDmode))
   1411  1.1  mrg 	*total = COSTS_N_INSNS (1 + (outer_code != MEM));
   1412  1.1  mrg       else if (tls_symbolic_operand_type (x))
   1413  1.1  mrg 	/* Estimate of cost for call_pal rduniq.  */
   1414  1.1  mrg 	/* ??? How many insns do we emit here?  More than one...  */
   1415  1.1  mrg 	*total = COSTS_N_INSNS (15);
   1416  1.1  mrg       else
   1417  1.1  mrg 	/* Otherwise we do a load from the GOT.  */
   1418  1.1  mrg 	*total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
   1419  1.1  mrg       return true;
   1420  1.1  mrg 
   1421  1.1  mrg     case HIGH:
   1422  1.1  mrg       /* This is effectively an add_operand.  */
   1423  1.1  mrg       *total = 2;
   1424  1.1  mrg       return true;
   1425  1.1  mrg 
   1426  1.1  mrg     case PLUS:
   1427  1.1  mrg     case MINUS:
   1428  1.1  mrg       if (float_mode_p)
   1429  1.1  mrg 	*total = cost_data->fp_add;
   1430  1.1  mrg       else if (GET_CODE (XEXP (x, 0)) == ASHIFT
   1431  1.1  mrg 	       && const23_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
   1432  1.1  mrg 	{
   1433  1.1  mrg 	  *total = (rtx_cost (XEXP (XEXP (x, 0), 0), mode,
   1434  1.1  mrg 			      (enum rtx_code) outer_code, opno, speed)
   1435  1.1  mrg 		    + rtx_cost (XEXP (x, 1), mode,
   1436  1.1  mrg 				(enum rtx_code) outer_code, opno, speed)
   1437  1.1  mrg 		    + COSTS_N_INSNS (1));
   1438  1.1  mrg 	  return true;
   1439  1.1  mrg 	}
   1440  1.1  mrg       return false;
   1441  1.1  mrg 
   1442  1.1  mrg     case MULT:
   1443  1.1  mrg       if (float_mode_p)
   1444  1.1  mrg 	*total = cost_data->fp_mult;
   1445  1.1  mrg       else if (mode == DImode)
   1446  1.1  mrg 	*total = cost_data->int_mult_di;
   1447  1.1  mrg       else
   1448  1.1  mrg 	*total = cost_data->int_mult_si;
   1449  1.1  mrg       return false;
   1450  1.1  mrg 
   1451  1.1  mrg     case ASHIFT:
   1452  1.1  mrg       if (CONST_INT_P (XEXP (x, 1))
   1453  1.1  mrg 	  && INTVAL (XEXP (x, 1)) <= 3)
   1454  1.1  mrg 	{
   1455  1.1  mrg 	  *total = COSTS_N_INSNS (1);
   1456  1.1  mrg 	  return false;
   1457  1.1  mrg 	}
   1458  1.1  mrg       /* FALLTHRU */
   1459  1.1  mrg 
   1460  1.1  mrg     case ASHIFTRT:
   1461  1.1  mrg     case LSHIFTRT:
   1462  1.1  mrg       *total = cost_data->int_shift;
   1463  1.1  mrg       return false;
   1464  1.1  mrg 
   1465  1.1  mrg     case IF_THEN_ELSE:
   1466  1.1  mrg       if (float_mode_p)
   1467  1.1  mrg         *total = cost_data->fp_add;
   1468  1.1  mrg       else
   1469  1.1  mrg         *total = cost_data->int_cmov;
   1470  1.1  mrg       return false;
   1471  1.1  mrg 
   1472  1.1  mrg     case DIV:
   1473  1.1  mrg     case UDIV:
   1474  1.1  mrg     case MOD:
   1475  1.1  mrg     case UMOD:
   1476  1.1  mrg       if (!float_mode_p)
   1477  1.1  mrg 	*total = cost_data->int_div;
   1478  1.1  mrg       else if (mode == SFmode)
   1479  1.1  mrg         *total = cost_data->fp_div_sf;
   1480  1.1  mrg       else
   1481  1.1  mrg         *total = cost_data->fp_div_df;
   1482  1.1  mrg       return false;
   1483  1.1  mrg 
   1484  1.1  mrg     case MEM:
   1485  1.1  mrg       *total = COSTS_N_INSNS (!speed ? 1 : alpha_memory_latency);
   1486  1.1  mrg       return true;
   1487  1.1  mrg 
   1488  1.1  mrg     case NEG:
   1489  1.1  mrg       if (! float_mode_p)
   1490  1.1  mrg 	{
   1491  1.1  mrg 	  *total = COSTS_N_INSNS (1);
   1492  1.1  mrg 	  return false;
   1493  1.1  mrg 	}
   1494  1.1  mrg       /* FALLTHRU */
   1495  1.1  mrg 
   1496  1.1  mrg     case ABS:
   1497  1.1  mrg       if (! float_mode_p)
   1498  1.1  mrg 	{
   1499  1.1  mrg 	  *total = COSTS_N_INSNS (1) + cost_data->int_cmov;
   1500  1.1  mrg 	  return false;
   1501  1.1  mrg 	}
   1502  1.1  mrg       /* FALLTHRU */
   1503  1.1  mrg 
   1504  1.1  mrg     case FLOAT:
   1505  1.1  mrg     case UNSIGNED_FLOAT:
   1506  1.1  mrg     case FIX:
   1507  1.1  mrg     case UNSIGNED_FIX:
   1508  1.1  mrg     case FLOAT_TRUNCATE:
   1509  1.1  mrg       *total = cost_data->fp_add;
   1510  1.1  mrg       return false;
   1511  1.1  mrg 
   1512  1.1  mrg     case FLOAT_EXTEND:
   1513  1.1  mrg       if (MEM_P (XEXP (x, 0)))
   1514  1.1  mrg 	*total = 0;
   1515  1.1  mrg       else
   1516  1.1  mrg 	*total = cost_data->fp_add;
   1517  1.1  mrg       return false;
   1518  1.1  mrg 
   1519  1.1  mrg     default:
   1520  1.1  mrg       return false;
   1521  1.1  mrg     }
   1522  1.1  mrg }
   1523  1.1  mrg 
   1524  1.1  mrg /* REF is an alignable memory location.  Place an aligned SImode
   1526  1.1  mrg    reference into *PALIGNED_MEM and the number of bits to shift into
   1527  1.1  mrg    *PBITNUM.  SCRATCH is a free register for use in reloading out
   1528  1.1  mrg    of range stack slots.  */
   1529  1.1  mrg 
   1530  1.1  mrg void
   1531  1.1  mrg get_aligned_mem (rtx ref, rtx *paligned_mem, rtx *pbitnum)
   1532  1.1  mrg {
   1533  1.1  mrg   rtx base;
   1534  1.1  mrg   HOST_WIDE_INT disp, offset;
   1535  1.1  mrg 
   1536  1.1  mrg   gcc_assert (MEM_P (ref));
   1537  1.1  mrg 
   1538  1.1  mrg   if (reload_in_progress)
   1539  1.1  mrg     {
   1540  1.1  mrg       base = find_replacement (&XEXP (ref, 0));
   1541  1.1  mrg       gcc_assert (memory_address_p (GET_MODE (ref), base));
   1542  1.1  mrg     }
   1543  1.1  mrg   else
   1544  1.1  mrg     base = XEXP (ref, 0);
   1545  1.1  mrg 
   1546  1.1  mrg   if (GET_CODE (base) == PLUS)
   1547  1.1  mrg     disp = INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
   1548  1.1  mrg   else
   1549  1.1  mrg     disp = 0;
   1550  1.1  mrg 
   1551  1.1  mrg   /* Find the byte offset within an aligned word.  If the memory itself is
   1552  1.1  mrg      claimed to be aligned, believe it.  Otherwise, aligned_memory_operand
   1553  1.1  mrg      will have examined the base register and determined it is aligned, and
   1554  1.1  mrg      thus displacements from it are naturally alignable.  */
   1555  1.1  mrg   if (MEM_ALIGN (ref) >= 32)
   1556  1.1  mrg     offset = 0;
   1557  1.1  mrg   else
   1558  1.1  mrg     offset = disp & 3;
   1559  1.1  mrg 
   1560  1.1  mrg   /* The location should not cross aligned word boundary.  */
   1561  1.1  mrg   gcc_assert (offset + GET_MODE_SIZE (GET_MODE (ref))
   1562  1.1  mrg 	      <= GET_MODE_SIZE (SImode));
   1563  1.1  mrg 
   1564  1.1  mrg   /* Access the entire aligned word.  */
   1565  1.1  mrg   *paligned_mem = widen_memory_access (ref, SImode, -offset);
   1566  1.1  mrg 
   1567  1.1  mrg   /* Convert the byte offset within the word to a bit offset.  */
   1568  1.1  mrg   offset *= BITS_PER_UNIT;
   1569  1.1  mrg   *pbitnum = GEN_INT (offset);
   1570  1.1  mrg }
   1571  1.1  mrg 
   1572  1.1  mrg /* Similar, but just get the address.  Handle the two reload cases.
   1573  1.1  mrg    Add EXTRA_OFFSET to the address we return.  */
   1574  1.1  mrg 
   1575  1.1  mrg rtx
   1576  1.1  mrg get_unaligned_address (rtx ref)
   1577  1.1  mrg {
   1578  1.1  mrg   rtx base;
   1579  1.1  mrg   HOST_WIDE_INT offset = 0;
   1580  1.1  mrg 
   1581  1.1  mrg   gcc_assert (MEM_P (ref));
   1582  1.1  mrg 
   1583  1.1  mrg   if (reload_in_progress)
   1584  1.1  mrg     {
   1585  1.1  mrg       base = find_replacement (&XEXP (ref, 0));
   1586  1.1  mrg       gcc_assert (memory_address_p (GET_MODE (ref), base));
   1587  1.1  mrg     }
   1588  1.1  mrg   else
   1589  1.1  mrg     base = XEXP (ref, 0);
   1590  1.1  mrg 
   1591  1.1  mrg   if (GET_CODE (base) == PLUS)
   1592  1.1  mrg     offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0);
   1593  1.1  mrg 
   1594  1.1  mrg   return plus_constant (Pmode, base, offset);
   1595  1.1  mrg }
   1596  1.1  mrg 
   1597  1.1  mrg /* Compute a value X, such that X & 7 == (ADDR + OFS) & 7.
   1598  1.1  mrg    X is always returned in a register.  */
   1599  1.1  mrg 
   1600  1.1  mrg rtx
   1601  1.1  mrg get_unaligned_offset (rtx addr, HOST_WIDE_INT ofs)
   1602  1.1  mrg {
   1603  1.1  mrg   if (GET_CODE (addr) == PLUS)
   1604  1.1  mrg     {
   1605  1.1  mrg       ofs += INTVAL (XEXP (addr, 1));
   1606  1.1  mrg       addr = XEXP (addr, 0);
   1607  1.1  mrg     }
   1608  1.1  mrg 
   1609  1.1  mrg   return expand_simple_binop (Pmode, PLUS, addr, GEN_INT (ofs & 7),
   1610  1.1  mrg 			      NULL_RTX, 1, OPTAB_LIB_WIDEN);
   1611  1.1  mrg }
   1612  1.1  mrg 
   1613  1.1  mrg /* On the Alpha, all (non-symbolic) constants except zero go into
   1614  1.1  mrg    a floating-point register via memory.  Note that we cannot
   1615  1.1  mrg    return anything that is not a subset of RCLASS, and that some
   1616  1.1  mrg    symbolic constants cannot be dropped to memory.  */
   1617  1.1  mrg 
   1618  1.1  mrg enum reg_class
   1619  1.1  mrg alpha_preferred_reload_class(rtx x, enum reg_class rclass)
   1620  1.1  mrg {
   1621  1.1  mrg   /* Zero is present in any register class.  */
   1622  1.1  mrg   if (x == CONST0_RTX (GET_MODE (x)))
   1623  1.1  mrg     return rclass;
   1624  1.1  mrg 
   1625  1.1  mrg   /* These sorts of constants we can easily drop to memory.  */
   1626  1.1  mrg   if (CONST_SCALAR_INT_P (x)
   1627  1.1  mrg       || CONST_DOUBLE_P (x)
   1628  1.1  mrg       || GET_CODE (x) == CONST_VECTOR)
   1629  1.1  mrg     {
   1630  1.1  mrg       if (rclass == FLOAT_REGS)
   1631  1.1  mrg 	return NO_REGS;
   1632  1.1  mrg       if (rclass == ALL_REGS)
   1633  1.1  mrg 	return GENERAL_REGS;
   1634  1.1  mrg       return rclass;
   1635  1.1  mrg     }
   1636  1.1  mrg 
   1637  1.1  mrg   /* All other kinds of constants should not (and in the case of HIGH
   1638  1.1  mrg      cannot) be dropped to memory -- instead we use a GENERAL_REGS
   1639  1.1  mrg      secondary reload.  */
   1640  1.1  mrg   if (CONSTANT_P (x))
   1641  1.1  mrg     return (rclass == ALL_REGS ? GENERAL_REGS : rclass);
   1642  1.1  mrg 
   1643  1.1  mrg   return rclass;
   1644  1.1  mrg }
   1645  1.1  mrg 
   1646  1.1  mrg /* Inform reload about cases where moving X with a mode MODE to a register in
   1647  1.1  mrg    RCLASS requires an extra scratch or immediate register.  Return the class
   1648  1.1  mrg    needed for the immediate register.  */
   1649  1.1  mrg 
   1650  1.1  mrg static reg_class_t
   1651  1.1  mrg alpha_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
   1652  1.1  mrg 			machine_mode mode, secondary_reload_info *sri)
   1653  1.1  mrg {
   1654  1.1  mrg   enum reg_class rclass = (enum reg_class) rclass_i;
   1655  1.1  mrg 
   1656  1.1  mrg   /* Loading and storing HImode or QImode values to and from memory
   1657  1.1  mrg      usually requires a scratch register.  */
   1658  1.1  mrg   if (!TARGET_BWX && (mode == QImode || mode == HImode || mode == CQImode))
   1659  1.1  mrg     {
   1660  1.1  mrg       if (any_memory_operand (x, mode))
   1661  1.1  mrg 	{
   1662  1.1  mrg 	  if (in_p)
   1663  1.1  mrg 	    {
   1664  1.1  mrg 	      if (!aligned_memory_operand (x, mode))
   1665  1.1  mrg 		sri->icode = direct_optab_handler (reload_in_optab, mode);
   1666  1.1  mrg 	    }
   1667  1.1  mrg 	  else
   1668  1.1  mrg 	    sri->icode = direct_optab_handler (reload_out_optab, mode);
   1669  1.1  mrg 	  return NO_REGS;
   1670  1.1  mrg 	}
   1671  1.1  mrg     }
   1672  1.1  mrg 
   1673  1.1  mrg   /* We also cannot do integral arithmetic into FP regs, as might result
   1674  1.1  mrg      from register elimination into a DImode fp register.  */
   1675  1.1  mrg   if (rclass == FLOAT_REGS)
   1676  1.1  mrg     {
   1677  1.1  mrg       if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
   1678  1.1  mrg 	return GENERAL_REGS;
   1679  1.1  mrg       if (in_p && INTEGRAL_MODE_P (mode)
   1680  1.1  mrg 	  && !MEM_P (x) && !REG_P (x) && !CONST_INT_P (x))
   1681  1.1  mrg 	return GENERAL_REGS;
   1682  1.1  mrg     }
   1683  1.1  mrg 
   1684  1.1  mrg   return NO_REGS;
   1685  1.1  mrg }
   1686  1.1  mrg 
   1687  1.1  mrg /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
   1688  1.1  mrg 
   1689  1.1  mrg    If we are copying between general and FP registers, we need a memory
   1690  1.1  mrg    location unless the FIX extension is available.  */
   1691  1.1  mrg 
   1692  1.1  mrg static bool
   1693  1.1  mrg alpha_secondary_memory_needed (machine_mode, reg_class_t class1,
   1694  1.1  mrg 			       reg_class_t class2)
   1695  1.1  mrg {
   1696  1.1  mrg   return (!TARGET_FIX
   1697  1.1  mrg 	  && ((class1 == FLOAT_REGS && class2 != FLOAT_REGS)
   1698  1.1  mrg 	      || (class2 == FLOAT_REGS && class1 != FLOAT_REGS)));
   1699  1.1  mrg }
   1700  1.1  mrg 
   1701  1.1  mrg /* Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE.  If MODE is
   1702  1.1  mrg    floating-point, use it.  Otherwise, widen to a word like the default.
   1703  1.1  mrg    This is needed because we always store integers in FP registers in
   1704  1.1  mrg    quadword format.  This whole area is very tricky!  */
   1705  1.1  mrg 
   1706  1.1  mrg static machine_mode
   1707  1.1  mrg alpha_secondary_memory_needed_mode (machine_mode mode)
   1708  1.1  mrg {
   1709  1.1  mrg   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
   1710  1.1  mrg     return mode;
   1711  1.1  mrg   if (GET_MODE_SIZE (mode) >= 4)
   1712  1.1  mrg     return mode;
   1713  1.1  mrg   return mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0).require ();
   1714  1.1  mrg }
   1715  1.1  mrg 
   1716  1.1  mrg /* Given SEQ, which is an INSN list, look for any MEMs in either
   1718  1.1  mrg    a SET_DEST or a SET_SRC and copy the in-struct, unchanging, and
   1719  1.1  mrg    volatile flags from REF into each of the MEMs found.  If REF is not
   1720  1.1  mrg    a MEM, don't do anything.  */
   1721  1.1  mrg 
   1722  1.1  mrg void
   1723  1.1  mrg alpha_set_memflags (rtx seq, rtx ref)
   1724  1.1  mrg {
   1725  1.1  mrg   rtx_insn *insn;
   1726  1.1  mrg 
   1727  1.1  mrg   if (!MEM_P (ref))
   1728  1.1  mrg     return;
   1729  1.1  mrg 
   1730  1.1  mrg   /* This is only called from alpha.md, after having had something
   1731  1.1  mrg      generated from one of the insn patterns.  So if everything is
   1732  1.1  mrg      zero, the pattern is already up-to-date.  */
   1733  1.1  mrg   if (!MEM_VOLATILE_P (ref)
   1734  1.1  mrg       && !MEM_NOTRAP_P (ref)
   1735  1.1  mrg       && !MEM_READONLY_P (ref))
   1736  1.1  mrg     return;
   1737  1.1  mrg 
   1738  1.1  mrg   subrtx_var_iterator::array_type array;
   1739  1.1  mrg   for (insn = as_a <rtx_insn *> (seq); insn; insn = NEXT_INSN (insn))
   1740  1.1  mrg     if (INSN_P (insn))
   1741  1.1  mrg       FOR_EACH_SUBRTX_VAR (iter, array, PATTERN (insn), NONCONST)
   1742  1.1  mrg 	{
   1743  1.1  mrg 	  rtx x = *iter;
   1744  1.1  mrg 	  if (MEM_P (x))
   1745  1.1  mrg 	    {
   1746  1.1  mrg 	      MEM_VOLATILE_P (x) = MEM_VOLATILE_P (ref);
   1747  1.1  mrg 	      MEM_NOTRAP_P (x) = MEM_NOTRAP_P (ref);
   1748  1.1  mrg 	      MEM_READONLY_P (x) = MEM_READONLY_P (ref);
   1749  1.1  mrg 	      /* Sadly, we cannot use alias sets because the extra
   1750  1.1  mrg 		 aliasing produced by the AND interferes.  Given that
   1751  1.1  mrg 		 two-byte quantities are the only thing we would be
   1752  1.1  mrg 		 able to differentiate anyway, there does not seem to
   1753  1.1  mrg 		 be any point in convoluting the early out of the
   1754  1.1  mrg 		 alias check.  */
   1755  1.1  mrg 	      iter.skip_subrtxes ();
   1756  1.1  mrg 	    }
   1757  1.1  mrg 	}
   1758  1.1  mrg     else
   1759  1.1  mrg       gcc_unreachable ();
   1760  1.1  mrg }
   1761  1.1  mrg 
   1762  1.1  mrg static rtx alpha_emit_set_const (rtx, machine_mode, HOST_WIDE_INT,
   1764  1.1  mrg 				 int, bool);
   1765  1.1  mrg 
   1766  1.1  mrg /* Internal routine for alpha_emit_set_const to check for N or below insns.
   1767  1.1  mrg    If NO_OUTPUT is true, then we only check to see if N insns are possible,
   1768  1.1  mrg    and return pc_rtx if successful.  */
   1769  1.1  mrg 
   1770  1.1  mrg static rtx
   1771  1.1  mrg alpha_emit_set_const_1 (rtx target, machine_mode mode,
   1772  1.1  mrg 			HOST_WIDE_INT c, int n, bool no_output)
   1773  1.1  mrg {
   1774  1.1  mrg   HOST_WIDE_INT new_const;
   1775  1.1  mrg   int i, bits;
   1776  1.1  mrg   /* Use a pseudo if highly optimizing and still generating RTL.  */
   1777  1.1  mrg   rtx subtarget
   1778  1.1  mrg     = (flag_expensive_optimizations && can_create_pseudo_p () ? 0 : target);
   1779  1.1  mrg   rtx temp, insn;
   1780  1.1  mrg 
   1781  1.1  mrg   /* If this is a sign-extended 32-bit constant, we can do this in at most
   1782  1.1  mrg      three insns, so do it if we have enough insns left.  */
   1783  1.1  mrg 
   1784  1.1  mrg   if (c >> 31 == -1 || c >> 31 == 0)
   1785  1.1  mrg     {
   1786  1.1  mrg       HOST_WIDE_INT low = ((c & 0xffff) ^ 0x8000) - 0x8000;
   1787  1.1  mrg       HOST_WIDE_INT tmp1 = c - low;
   1788  1.1  mrg       HOST_WIDE_INT high = (((tmp1 >> 16) & 0xffff) ^ 0x8000) - 0x8000;
   1789  1.1  mrg       HOST_WIDE_INT extra = 0;
   1790  1.1  mrg 
   1791  1.1  mrg       /* If HIGH will be interpreted as negative but the constant is
   1792  1.1  mrg 	 positive, we must adjust it to do two ldha insns.  */
   1793  1.1  mrg 
   1794  1.1  mrg       if ((high & 0x8000) != 0 && c >= 0)
   1795  1.1  mrg 	{
   1796  1.1  mrg 	  extra = 0x4000;
   1797  1.1  mrg 	  tmp1 -= 0x40000000;
   1798  1.1  mrg 	  high = ((tmp1 >> 16) & 0xffff) - 2 * ((tmp1 >> 16) & 0x8000);
   1799  1.1  mrg 	}
   1800  1.1  mrg 
   1801  1.1  mrg       if (c == low || (low == 0 && extra == 0))
   1802  1.1  mrg 	{
   1803  1.1  mrg 	  /* We used to use copy_to_suggested_reg (GEN_INT (c), target, mode)
   1804  1.1  mrg 	     but that meant that we can't handle INT_MIN on 32-bit machines
   1805  1.1  mrg 	     (like NT/Alpha), because we recurse indefinitely through
   1806  1.1  mrg 	     emit_move_insn to gen_movdi.  So instead, since we know exactly
   1807  1.1  mrg 	     what we want, create it explicitly.  */
   1808  1.1  mrg 
   1809  1.1  mrg 	  if (no_output)
   1810  1.1  mrg 	    return pc_rtx;
   1811  1.1  mrg 	  if (target == NULL)
   1812  1.1  mrg 	    target = gen_reg_rtx (mode);
   1813  1.1  mrg 	  emit_insn (gen_rtx_SET (target, GEN_INT (c)));
   1814  1.1  mrg 	  return target;
   1815  1.1  mrg 	}
   1816  1.1  mrg       else if (n >= 2 + (extra != 0))
   1817  1.1  mrg 	{
   1818  1.1  mrg 	  if (no_output)
   1819  1.1  mrg 	    return pc_rtx;
   1820  1.1  mrg 	  if (!can_create_pseudo_p ())
   1821  1.1  mrg 	    {
   1822  1.1  mrg 	      emit_insn (gen_rtx_SET (target, GEN_INT (high << 16)));
   1823  1.1  mrg 	      temp = target;
   1824  1.1  mrg 	    }
   1825  1.1  mrg 	  else
   1826  1.1  mrg 	    temp = copy_to_suggested_reg (GEN_INT (high << 16),
   1827  1.1  mrg 					  subtarget, mode);
   1828  1.1  mrg 
   1829  1.1  mrg 	  /* As of 2002-02-23, addsi3 is only available when not optimizing.
   1830  1.1  mrg 	     This means that if we go through expand_binop, we'll try to
   1831  1.1  mrg 	     generate extensions, etc, which will require new pseudos, which
   1832  1.1  mrg 	     will fail during some split phases.  The SImode add patterns
   1833  1.1  mrg 	     still exist, but are not named.  So build the insns by hand.  */
   1834  1.1  mrg 
   1835  1.1  mrg 	  if (extra != 0)
   1836  1.1  mrg 	    {
   1837  1.1  mrg 	      if (! subtarget)
   1838  1.1  mrg 		subtarget = gen_reg_rtx (mode);
   1839  1.1  mrg 	      insn = gen_rtx_PLUS (mode, temp, GEN_INT (extra << 16));
   1840  1.1  mrg 	      insn = gen_rtx_SET (subtarget, insn);
   1841  1.1  mrg 	      emit_insn (insn);
   1842  1.1  mrg 	      temp = subtarget;
   1843  1.1  mrg 	    }
   1844  1.1  mrg 
   1845  1.1  mrg 	  if (target == NULL)
   1846  1.1  mrg 	    target = gen_reg_rtx (mode);
   1847  1.1  mrg 	  insn = gen_rtx_PLUS (mode, temp, GEN_INT (low));
   1848  1.1  mrg 	  insn = gen_rtx_SET (target, insn);
   1849  1.1  mrg 	  emit_insn (insn);
   1850  1.1  mrg 	  return target;
   1851  1.1  mrg 	}
   1852  1.1  mrg     }
   1853  1.1  mrg 
   1854  1.1  mrg   /* If we couldn't do it that way, try some other methods.  But if we have
   1855  1.1  mrg      no instructions left, don't bother.  Likewise, if this is SImode and
   1856  1.1  mrg      we can't make pseudos, we can't do anything since the expand_binop
   1857  1.1  mrg      and expand_unop calls will widen and try to make pseudos.  */
   1858  1.1  mrg 
   1859  1.1  mrg   if (n == 1 || (mode == SImode && !can_create_pseudo_p ()))
   1860  1.1  mrg     return 0;
   1861  1.1  mrg 
   1862  1.1  mrg   /* Next, see if we can load a related constant and then shift and possibly
   1863  1.1  mrg      negate it to get the constant we want.  Try this once each increasing
   1864  1.1  mrg      numbers of insns.  */
   1865  1.1  mrg 
   1866  1.1  mrg   for (i = 1; i < n; i++)
   1867  1.1  mrg     {
   1868  1.1  mrg       /* First, see if minus some low bits, we've an easy load of
   1869  1.1  mrg 	 high bits.  */
   1870  1.1  mrg 
   1871  1.1  mrg       new_const = ((c & 0xffff) ^ 0x8000) - 0x8000;
   1872  1.1  mrg       if (new_const != 0)
   1873  1.1  mrg 	{
   1874  1.1  mrg           temp = alpha_emit_set_const (subtarget, mode, c - new_const, i, no_output);
   1875  1.1  mrg 	  if (temp)
   1876  1.1  mrg 	    {
   1877  1.1  mrg 	      if (no_output)
   1878  1.1  mrg 		return temp;
   1879  1.1  mrg 	      return expand_binop (mode, add_optab, temp, GEN_INT (new_const),
   1880  1.1  mrg 				   target, 0, OPTAB_WIDEN);
   1881  1.1  mrg 	    }
   1882  1.1  mrg 	}
   1883  1.1  mrg 
   1884  1.1  mrg       /* Next try complementing.  */
   1885  1.1  mrg       temp = alpha_emit_set_const (subtarget, mode, ~c, i, no_output);
   1886  1.1  mrg       if (temp)
   1887  1.1  mrg 	{
   1888  1.1  mrg 	  if (no_output)
   1889  1.1  mrg 	    return temp;
   1890  1.1  mrg 	  return expand_unop (mode, one_cmpl_optab, temp, target, 0);
   1891  1.1  mrg 	}
   1892  1.1  mrg 
   1893  1.1  mrg       /* Next try to form a constant and do a left shift.  We can do this
   1894  1.1  mrg 	 if some low-order bits are zero; the exact_log2 call below tells
   1895  1.1  mrg 	 us that information.  The bits we are shifting out could be any
   1896  1.1  mrg 	 value, but here we'll just try the 0- and sign-extended forms of
   1897  1.1  mrg 	 the constant.  To try to increase the chance of having the same
   1898  1.1  mrg 	 constant in more than one insn, start at the highest number of
   1899  1.1  mrg 	 bits to shift, but try all possibilities in case a ZAPNOT will
   1900  1.1  mrg 	 be useful.  */
   1901  1.1  mrg 
   1902  1.1  mrg       bits = exact_log2 (c & -c);
   1903  1.1  mrg       if (bits > 0)
   1904  1.1  mrg 	for (; bits > 0; bits--)
   1905  1.1  mrg 	  {
   1906  1.1  mrg 	    new_const = c >> bits;
   1907  1.1  mrg 	    temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
   1908  1.1  mrg 	    if (!temp && c < 0)
   1909  1.1  mrg 	      {
   1910  1.1  mrg 		new_const = (unsigned HOST_WIDE_INT)c >> bits;
   1911  1.1  mrg 		temp = alpha_emit_set_const (subtarget, mode, new_const,
   1912  1.1  mrg 					     i, no_output);
   1913  1.1  mrg 	      }
   1914  1.1  mrg 	    if (temp)
   1915  1.1  mrg 	      {
   1916  1.1  mrg 		if (no_output)
   1917  1.1  mrg 		  return temp;
   1918  1.1  mrg 	        return expand_binop (mode, ashl_optab, temp, GEN_INT (bits),
   1919  1.1  mrg 				     target, 0, OPTAB_WIDEN);
   1920  1.1  mrg 	      }
   1921  1.1  mrg 	  }
   1922  1.1  mrg 
   1923  1.1  mrg       /* Now try high-order zero bits.  Here we try the shifted-in bits as
   1924  1.1  mrg 	 all zero and all ones.  Be careful to avoid shifting outside the
   1925  1.1  mrg 	 mode and to avoid shifting outside the host wide int size.  */
   1926  1.1  mrg 
   1927  1.1  mrg       bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
   1928  1.1  mrg 	      - floor_log2 (c) - 1);
   1929  1.1  mrg       if (bits > 0)
   1930  1.1  mrg 	for (; bits > 0; bits--)
   1931  1.1  mrg 	  {
   1932  1.1  mrg 	    new_const = c << bits;
   1933  1.1  mrg 	    temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
   1934  1.1  mrg 	    if (!temp)
   1935  1.1  mrg 	      {
   1936  1.1  mrg 		new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1);
   1937  1.1  mrg 	        temp = alpha_emit_set_const (subtarget, mode, new_const,
   1938  1.1  mrg 					     i, no_output);
   1939  1.1  mrg 	      }
   1940  1.1  mrg 	    if (temp)
   1941  1.1  mrg 	      {
   1942  1.1  mrg 		if (no_output)
   1943  1.1  mrg 		  return temp;
   1944  1.1  mrg 		return expand_binop (mode, lshr_optab, temp, GEN_INT (bits),
   1945  1.1  mrg 				     target, 1, OPTAB_WIDEN);
   1946  1.1  mrg 	      }
   1947  1.1  mrg 	  }
   1948  1.1  mrg 
   1949  1.1  mrg       /* Now try high-order 1 bits.  We get that with a sign-extension.
   1950  1.1  mrg 	 But one bit isn't enough here.  Be careful to avoid shifting outside
   1951  1.1  mrg 	 the mode and to avoid shifting outside the host wide int size.  */
   1952  1.1  mrg 
   1953  1.1  mrg       bits = (MIN (HOST_BITS_PER_WIDE_INT, GET_MODE_SIZE (mode) * 8)
   1954  1.1  mrg 	      - floor_log2 (~ c) - 2);
   1955  1.1  mrg       if (bits > 0)
   1956  1.1  mrg 	for (; bits > 0; bits--)
   1957  1.1  mrg 	  {
   1958  1.1  mrg 	    new_const = c << bits;
   1959  1.1  mrg 	    temp = alpha_emit_set_const (subtarget, mode, new_const, i, no_output);
   1960  1.1  mrg 	    if (!temp)
   1961  1.1  mrg 	      {
   1962  1.1  mrg 		new_const = (c << bits) | ((HOST_WIDE_INT_1U << bits) - 1);
   1963  1.1  mrg 	        temp = alpha_emit_set_const (subtarget, mode, new_const,
   1964  1.1  mrg 					     i, no_output);
   1965  1.1  mrg 	      }
   1966  1.1  mrg 	    if (temp)
   1967  1.1  mrg 	      {
   1968  1.1  mrg 		if (no_output)
   1969  1.1  mrg 		  return temp;
   1970  1.1  mrg 		return expand_binop (mode, ashr_optab, temp, GEN_INT (bits),
   1971  1.1  mrg 				     target, 0, OPTAB_WIDEN);
   1972  1.1  mrg 	      }
   1973  1.1  mrg 	  }
   1974  1.1  mrg     }
   1975  1.1  mrg 
   1976  1.1  mrg   /* Finally, see if can load a value into the target that is the same as the
   1977  1.1  mrg      constant except that all bytes that are 0 are changed to be 0xff.  If we
   1978  1.1  mrg      can, then we can do a ZAPNOT to obtain the desired constant.  */
   1979  1.1  mrg 
   1980  1.1  mrg   new_const = c;
   1981  1.1  mrg   for (i = 0; i < 64; i += 8)
   1982  1.1  mrg     if ((new_const & ((HOST_WIDE_INT) 0xff << i)) == 0)
   1983  1.1  mrg       new_const |= (HOST_WIDE_INT) 0xff << i;
   1984  1.1  mrg 
   1985  1.1  mrg   /* We are only called for SImode and DImode.  If this is SImode, ensure that
   1986  1.1  mrg      we are sign extended to a full word.  */
   1987  1.1  mrg 
   1988  1.1  mrg   if (mode == SImode)
   1989  1.1  mrg     new_const = ((new_const & 0xffffffff) ^ 0x80000000) - 0x80000000;
   1990  1.1  mrg 
   1991  1.1  mrg   if (new_const != c)
   1992  1.1  mrg     {
   1993  1.1  mrg       temp = alpha_emit_set_const (subtarget, mode, new_const, n - 1, no_output);
   1994  1.1  mrg       if (temp)
   1995  1.1  mrg 	{
   1996  1.1  mrg 	  if (no_output)
   1997  1.1  mrg 	    return temp;
   1998  1.1  mrg 	  return expand_binop (mode, and_optab, temp, GEN_INT (c | ~ new_const),
   1999  1.1  mrg 			       target, 0, OPTAB_WIDEN);
   2000  1.1  mrg 	}
   2001  1.1  mrg     }
   2002  1.1  mrg 
   2003  1.1  mrg   return 0;
   2004  1.1  mrg }
   2005  1.1  mrg 
   2006  1.1  mrg /* Try to output insns to set TARGET equal to the constant C if it can be
   2007  1.1  mrg    done in less than N insns.  Do all computations in MODE.  Returns the place
   2008  1.1  mrg    where the output has been placed if it can be done and the insns have been
   2009  1.1  mrg    emitted.  If it would take more than N insns, zero is returned and no
   2010  1.1  mrg    insns and emitted.  */
   2011  1.1  mrg 
   2012  1.1  mrg static rtx
   2013  1.1  mrg alpha_emit_set_const (rtx target, machine_mode mode,
   2014  1.1  mrg 		      HOST_WIDE_INT c, int n, bool no_output)
   2015  1.1  mrg {
   2016  1.1  mrg   machine_mode orig_mode = mode;
   2017  1.1  mrg   rtx orig_target = target;
   2018  1.1  mrg   rtx result = 0;
   2019  1.1  mrg   int i;
   2020  1.1  mrg 
   2021  1.1  mrg   /* If we can't make any pseudos, TARGET is an SImode hard register, we
   2022  1.1  mrg      can't load this constant in one insn, do this in DImode.  */
   2023  1.1  mrg   if (!can_create_pseudo_p () && mode == SImode
   2024  1.1  mrg       && REG_P (target) && REGNO (target) < FIRST_PSEUDO_REGISTER)
   2025  1.1  mrg     {
   2026  1.1  mrg       result = alpha_emit_set_const_1 (target, mode, c, 1, no_output);
   2027  1.1  mrg       if (result)
   2028  1.1  mrg 	return result;
   2029  1.1  mrg 
   2030  1.1  mrg       target = no_output ? NULL : gen_lowpart (DImode, target);
   2031  1.1  mrg       mode = DImode;
   2032  1.1  mrg     }
   2033  1.1  mrg   else if (mode == V8QImode || mode == V4HImode || mode == V2SImode)
   2034  1.1  mrg     {
   2035  1.1  mrg       target = no_output ? NULL : gen_lowpart (DImode, target);
   2036  1.1  mrg       mode = DImode;
   2037  1.1  mrg     }
   2038  1.1  mrg 
   2039  1.1  mrg   /* Try 1 insn, then 2, then up to N.  */
   2040  1.1  mrg   for (i = 1; i <= n; i++)
   2041  1.1  mrg     {
   2042  1.1  mrg       result = alpha_emit_set_const_1 (target, mode, c, i, no_output);
   2043  1.1  mrg       if (result)
   2044  1.1  mrg 	{
   2045  1.1  mrg 	  rtx_insn *insn;
   2046  1.1  mrg 	  rtx set;
   2047  1.1  mrg 
   2048  1.1  mrg 	  if (no_output)
   2049  1.1  mrg 	    return result;
   2050  1.1  mrg 
   2051  1.1  mrg 	  insn = get_last_insn ();
   2052  1.1  mrg 	  set = single_set (insn);
   2053  1.1  mrg 	  if (! CONSTANT_P (SET_SRC (set)))
   2054  1.1  mrg 	    set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (c));
   2055  1.1  mrg 	  break;
   2056  1.1  mrg 	}
   2057  1.1  mrg     }
   2058  1.1  mrg 
   2059  1.1  mrg   /* Allow for the case where we changed the mode of TARGET.  */
   2060  1.1  mrg   if (result)
   2061  1.1  mrg     {
   2062  1.1  mrg       if (result == target)
   2063  1.1  mrg 	result = orig_target;
   2064  1.1  mrg       else if (mode != orig_mode)
   2065  1.1  mrg 	result = gen_lowpart (orig_mode, result);
   2066  1.1  mrg     }
   2067  1.1  mrg 
   2068  1.1  mrg   return result;
   2069  1.1  mrg }
   2070  1.1  mrg 
   2071  1.1  mrg /* Having failed to find a 3 insn sequence in alpha_emit_set_const,
   2072  1.1  mrg    fall back to a straight forward decomposition.  We do this to avoid
   2073  1.1  mrg    exponential run times encountered when looking for longer sequences
   2074  1.1  mrg    with alpha_emit_set_const.  */
   2075  1.1  mrg 
   2076  1.1  mrg static rtx
   2077  1.1  mrg alpha_emit_set_long_const (rtx target, HOST_WIDE_INT c1)
   2078  1.1  mrg {
   2079  1.1  mrg   HOST_WIDE_INT d1, d2, d3, d4;
   2080  1.1  mrg   machine_mode mode = GET_MODE (target);
   2081  1.1  mrg   rtx orig_target = target;
   2082  1.1  mrg 
   2083  1.1  mrg   /* Decompose the entire word */
   2084  1.1  mrg 
   2085  1.1  mrg   d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
   2086  1.1  mrg   c1 -= d1;
   2087  1.1  mrg   d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
   2088  1.1  mrg   c1 = (c1 - d2) >> 32;
   2089  1.1  mrg   d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000;
   2090  1.1  mrg   c1 -= d3;
   2091  1.1  mrg   d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000;
   2092  1.1  mrg   gcc_assert (c1 == d4);
   2093  1.1  mrg 
   2094  1.1  mrg   if (mode != DImode)
   2095  1.1  mrg     target = gen_lowpart (DImode, target);
   2096  1.1  mrg 
   2097  1.1  mrg   /* Construct the high word */
   2098  1.1  mrg   if (d4)
   2099  1.1  mrg     {
   2100  1.1  mrg       emit_move_insn (target, GEN_INT (d4));
   2101  1.1  mrg       if (d3)
   2102  1.1  mrg 	emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3)));
   2103  1.1  mrg     }
   2104  1.1  mrg   else
   2105  1.1  mrg     emit_move_insn (target, GEN_INT (d3));
   2106  1.1  mrg 
   2107  1.1  mrg   /* Shift it into place */
   2108  1.1  mrg   emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32)));
   2109  1.1  mrg 
   2110  1.1  mrg   /* Add in the low bits.  */
   2111  1.1  mrg   if (d2)
   2112  1.1  mrg     emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2)));
   2113  1.1  mrg   if (d1)
   2114  1.1  mrg     emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1)));
   2115  1.1  mrg 
   2116  1.1  mrg   return orig_target;
   2117  1.1  mrg }
   2118  1.1  mrg 
   2119  1.1  mrg /* Given an integral CONST_INT or CONST_VECTOR, return the low 64 bits.  */
   2120  1.1  mrg 
   2121  1.1  mrg static HOST_WIDE_INT
   2122  1.1  mrg alpha_extract_integer (rtx x)
   2123  1.1  mrg {
   2124  1.1  mrg   if (GET_CODE (x) == CONST_VECTOR)
   2125  1.1  mrg     x = simplify_subreg (DImode, x, GET_MODE (x), 0);
   2126  1.1  mrg 
   2127  1.1  mrg   gcc_assert (CONST_INT_P (x));
   2128  1.1  mrg 
   2129  1.1  mrg   return INTVAL (x);
   2130  1.1  mrg }
   2131  1.1  mrg 
   2132  1.1  mrg /* Implement TARGET_LEGITIMATE_CONSTANT_P.  This is all constants for which
   2133  1.1  mrg    we are willing to load the value into a register via a move pattern.
   2134  1.1  mrg    Normally this is all symbolic constants, integral constants that
   2135  1.1  mrg    take three or fewer instructions, and floating-point zero.  */
   2136  1.1  mrg 
   2137  1.1  mrg bool
   2138  1.1  mrg alpha_legitimate_constant_p (machine_mode mode, rtx x)
   2139  1.1  mrg {
   2140  1.1  mrg   HOST_WIDE_INT i0;
   2141  1.1  mrg 
   2142  1.1  mrg   switch (GET_CODE (x))
   2143  1.1  mrg     {
   2144  1.1  mrg     case LABEL_REF:
   2145  1.1  mrg     case HIGH:
   2146  1.1  mrg       return true;
   2147  1.1  mrg 
   2148  1.1  mrg     case CONST:
   2149  1.1  mrg       if (GET_CODE (XEXP (x, 0)) == PLUS
   2150  1.1  mrg 	  && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
   2151  1.1  mrg 	x = XEXP (XEXP (x, 0), 0);
   2152  1.1  mrg       else
   2153  1.1  mrg 	return true;
   2154  1.1  mrg 
   2155  1.1  mrg       if (GET_CODE (x) != SYMBOL_REF)
   2156  1.1  mrg 	return true;
   2157  1.1  mrg       /* FALLTHRU */
   2158  1.1  mrg 
   2159  1.1  mrg     case SYMBOL_REF:
   2160  1.1  mrg       /* TLS symbols are never valid.  */
   2161  1.1  mrg       return SYMBOL_REF_TLS_MODEL (x) == 0;
   2162  1.1  mrg 
   2163  1.1  mrg     case CONST_WIDE_INT:
   2164  1.1  mrg       if (TARGET_BUILD_CONSTANTS)
   2165  1.1  mrg 	return true;
   2166  1.1  mrg       if (x == CONST0_RTX (mode))
   2167  1.1  mrg 	return true;
   2168  1.1  mrg       mode = DImode;
   2169  1.1  mrg       gcc_assert (CONST_WIDE_INT_NUNITS (x) == 2);
   2170  1.1  mrg       i0 = CONST_WIDE_INT_ELT (x, 1);
   2171  1.1  mrg       if (alpha_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) == NULL)
   2172  1.1  mrg 	return false;
   2173  1.1  mrg       i0 = CONST_WIDE_INT_ELT (x, 0);
   2174  1.1  mrg       goto do_integer;
   2175  1.1  mrg 
   2176  1.1  mrg     case CONST_DOUBLE:
   2177  1.1  mrg       if (x == CONST0_RTX (mode))
   2178  1.1  mrg 	return true;
   2179  1.1  mrg       return false;
   2180  1.1  mrg 
   2181  1.1  mrg     case CONST_VECTOR:
   2182  1.1  mrg       if (x == CONST0_RTX (mode))
   2183  1.1  mrg 	return true;
   2184  1.1  mrg       if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
   2185  1.1  mrg 	return false;
   2186  1.1  mrg       if (GET_MODE_SIZE (mode) != 8)
   2187  1.1  mrg 	return false;
   2188  1.1  mrg       /* FALLTHRU */
   2189  1.1  mrg 
   2190  1.1  mrg     case CONST_INT:
   2191  1.1  mrg       if (TARGET_BUILD_CONSTANTS)
   2192  1.1  mrg 	return true;
   2193  1.1  mrg       i0 = alpha_extract_integer (x);
   2194  1.1  mrg     do_integer:
   2195  1.1  mrg       return alpha_emit_set_const_1 (NULL_RTX, mode, i0, 3, true) != NULL;
   2196  1.1  mrg 
   2197  1.1  mrg     default:
   2198  1.1  mrg       return false;
   2199  1.1  mrg     }
   2200  1.1  mrg }
   2201  1.1  mrg 
   2202  1.1  mrg /* Operand 1 is known to be a constant, and should require more than one
   2203  1.1  mrg    instruction to load.  Emit that multi-part load.  */
   2204  1.1  mrg 
   2205  1.1  mrg bool
   2206  1.1  mrg alpha_split_const_mov (machine_mode mode, rtx *operands)
   2207  1.1  mrg {
   2208  1.1  mrg   HOST_WIDE_INT i0;
   2209  1.1  mrg   rtx temp = NULL_RTX;
   2210  1.1  mrg 
   2211  1.1  mrg   i0 = alpha_extract_integer (operands[1]);
   2212  1.1  mrg 
   2213  1.1  mrg   temp = alpha_emit_set_const (operands[0], mode, i0, 3, false);
   2214  1.1  mrg 
   2215  1.1  mrg   if (!temp && TARGET_BUILD_CONSTANTS)
   2216  1.1  mrg     temp = alpha_emit_set_long_const (operands[0], i0);
   2217  1.1  mrg 
   2218  1.1  mrg   if (temp)
   2219  1.1  mrg     {
   2220  1.1  mrg       if (!rtx_equal_p (operands[0], temp))
   2221  1.1  mrg 	emit_move_insn (operands[0], temp);
   2222  1.1  mrg       return true;
   2223  1.1  mrg     }
   2224  1.1  mrg 
   2225  1.1  mrg   return false;
   2226  1.1  mrg }
   2227  1.1  mrg 
   2228  1.1  mrg /* Expand a move instruction; return true if all work is done.
   2229  1.1  mrg    We don't handle non-bwx subword loads here.  */
   2230  1.1  mrg 
   2231  1.1  mrg bool
   2232  1.1  mrg alpha_expand_mov (machine_mode mode, rtx *operands)
   2233  1.1  mrg {
   2234  1.1  mrg   rtx tmp;
   2235  1.1  mrg 
   2236  1.1  mrg   /* If the output is not a register, the input must be.  */
   2237  1.1  mrg   if (MEM_P (operands[0])
   2238  1.1  mrg       && ! reg_or_0_operand (operands[1], mode))
   2239  1.1  mrg     operands[1] = force_reg (mode, operands[1]);
   2240  1.1  mrg 
   2241  1.1  mrg   /* Allow legitimize_address to perform some simplifications.  */
   2242  1.1  mrg   if (mode == Pmode && symbolic_operand (operands[1], mode))
   2243  1.1  mrg     {
   2244  1.1  mrg       tmp = alpha_legitimize_address_1 (operands[1], operands[0], mode);
   2245  1.1  mrg       if (tmp)
   2246  1.1  mrg 	{
   2247  1.1  mrg 	  if (tmp == operands[0])
   2248  1.1  mrg 	    return true;
   2249  1.1  mrg 	  operands[1] = tmp;
   2250  1.1  mrg 	  return false;
   2251  1.1  mrg 	}
   2252  1.1  mrg     }
   2253  1.1  mrg 
   2254  1.1  mrg   /* Early out for non-constants and valid constants.  */
   2255  1.1  mrg   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], mode))
   2256  1.1  mrg     return false;
   2257  1.1  mrg 
   2258  1.1  mrg   /* Split large integers.  */
   2259  1.1  mrg   if (CONST_INT_P (operands[1])
   2260  1.1  mrg       || GET_CODE (operands[1]) == CONST_VECTOR)
   2261  1.1  mrg     {
   2262  1.1  mrg       if (alpha_split_const_mov (mode, operands))
   2263  1.1  mrg 	return true;
   2264  1.1  mrg     }
   2265  1.1  mrg 
   2266  1.1  mrg   /* Otherwise we've nothing left but to drop the thing to memory.  */
   2267  1.1  mrg   tmp = force_const_mem (mode, operands[1]);
   2268  1.1  mrg 
   2269  1.1  mrg   if (tmp == NULL_RTX)
   2270  1.1  mrg     return false;
   2271  1.1  mrg 
   2272  1.1  mrg   if (reload_in_progress)
   2273  1.1  mrg     {
   2274  1.1  mrg       emit_move_insn (operands[0], XEXP (tmp, 0));
   2275  1.1  mrg       operands[1] = replace_equiv_address (tmp, operands[0]);
   2276  1.1  mrg     }
   2277  1.1  mrg   else
   2278  1.1  mrg     operands[1] = validize_mem (tmp);
   2279  1.1  mrg   return false;
   2280  1.1  mrg }
   2281  1.1  mrg 
   2282  1.1  mrg /* Expand a non-bwx QImode or HImode move instruction;
   2283  1.1  mrg    return true if all work is done.  */
   2284  1.1  mrg 
   2285  1.1  mrg bool
   2286  1.1  mrg alpha_expand_mov_nobwx (machine_mode mode, rtx *operands)
   2287  1.1  mrg {
   2288  1.1  mrg   rtx seq;
   2289  1.1  mrg 
   2290  1.1  mrg   /* If the output is not a register, the input must be.  */
   2291  1.1  mrg   if (MEM_P (operands[0]))
   2292  1.1  mrg     operands[1] = force_reg (mode, operands[1]);
   2293  1.1  mrg 
   2294  1.1  mrg   /* Handle four memory cases, unaligned and aligned for either the input
   2295  1.1  mrg      or the output.  The only case where we can be called during reload is
   2296  1.1  mrg      for aligned loads; all other cases require temporaries.  */
   2297  1.1  mrg 
   2298  1.1  mrg   if (any_memory_operand (operands[1], mode))
   2299  1.1  mrg     {
   2300  1.1  mrg       if (aligned_memory_operand (operands[1], mode))
   2301  1.1  mrg 	{
   2302  1.1  mrg 	  if (reload_in_progress)
   2303  1.1  mrg 	    {
   2304  1.1  mrg 	      seq = gen_reload_in_aligned (mode, operands[0], operands[1]);
   2305  1.1  mrg 	      emit_insn (seq);
   2306  1.1  mrg 	    }
   2307  1.1  mrg 	  else
   2308  1.1  mrg 	    {
   2309  1.1  mrg 	      rtx aligned_mem, bitnum;
   2310  1.1  mrg 	      rtx scratch = gen_reg_rtx (SImode);
   2311  1.1  mrg 	      rtx subtarget;
   2312  1.1  mrg 	      bool copyout;
   2313  1.1  mrg 
   2314  1.1  mrg 	      get_aligned_mem (operands[1], &aligned_mem, &bitnum);
   2315  1.1  mrg 
   2316  1.1  mrg 	      subtarget = operands[0];
   2317  1.1  mrg 	      if (REG_P (subtarget))
   2318  1.1  mrg 		subtarget = gen_lowpart (DImode, subtarget), copyout = false;
   2319  1.1  mrg 	      else
   2320  1.1  mrg 		subtarget = gen_reg_rtx (DImode), copyout = true;
   2321  1.1  mrg 
   2322  1.1  mrg 	      if (mode == QImode)
   2323  1.1  mrg 		seq = gen_aligned_loadqi (subtarget, aligned_mem,
   2324  1.1  mrg 					  bitnum, scratch);
   2325  1.1  mrg 	      else
   2326  1.1  mrg 		seq = gen_aligned_loadhi (subtarget, aligned_mem,
   2327  1.1  mrg 					  bitnum, scratch);
   2328  1.1  mrg 	      emit_insn (seq);
   2329  1.1  mrg 
   2330  1.1  mrg 	      if (copyout)
   2331  1.1  mrg 		emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
   2332  1.1  mrg 	    }
   2333  1.1  mrg 	}
   2334  1.1  mrg       else
   2335  1.1  mrg 	{
   2336  1.1  mrg 	  /* Don't pass these as parameters since that makes the generated
   2337  1.1  mrg 	     code depend on parameter evaluation order which will cause
   2338  1.1  mrg 	     bootstrap failures.  */
   2339  1.1  mrg 
   2340  1.1  mrg 	  rtx temp1, temp2, subtarget, ua;
   2341  1.1  mrg 	  bool copyout;
   2342  1.1  mrg 
   2343  1.1  mrg 	  temp1 = gen_reg_rtx (DImode);
   2344  1.1  mrg 	  temp2 = gen_reg_rtx (DImode);
   2345  1.1  mrg 
   2346  1.1  mrg 	  subtarget = operands[0];
   2347  1.1  mrg 	  if (REG_P (subtarget))
   2348  1.1  mrg 	    subtarget = gen_lowpart (DImode, subtarget), copyout = false;
   2349  1.1  mrg 	  else
   2350  1.1  mrg 	    subtarget = gen_reg_rtx (DImode), copyout = true;
   2351  1.1  mrg 
   2352  1.1  mrg 	  ua = get_unaligned_address (operands[1]);
   2353  1.1  mrg 	  if (mode == QImode)
   2354  1.1  mrg 	    seq = gen_unaligned_loadqi (subtarget, ua, temp1, temp2);
   2355  1.1  mrg 	  else
   2356  1.1  mrg 	    seq = gen_unaligned_loadhi (subtarget, ua, temp1, temp2);
   2357  1.1  mrg 
   2358  1.1  mrg 	  alpha_set_memflags (seq, operands[1]);
   2359  1.1  mrg 	  emit_insn (seq);
   2360  1.1  mrg 
   2361  1.1  mrg 	  if (copyout)
   2362  1.1  mrg 	    emit_move_insn (operands[0], gen_lowpart (mode, subtarget));
   2363  1.1  mrg 	}
   2364  1.1  mrg       return true;
   2365  1.1  mrg     }
   2366  1.1  mrg 
   2367  1.1  mrg   if (any_memory_operand (operands[0], mode))
   2368  1.1  mrg     {
   2369  1.1  mrg       if (aligned_memory_operand (operands[0], mode))
   2370  1.1  mrg 	{
   2371  1.1  mrg 	  rtx aligned_mem, bitnum;
   2372  1.1  mrg 	  rtx temp1 = gen_reg_rtx (SImode);
   2373  1.1  mrg 	  rtx temp2 = gen_reg_rtx (SImode);
   2374  1.1  mrg 
   2375  1.1  mrg 	  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
   2376  1.1  mrg 
   2377  1.1  mrg 	  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
   2378  1.1  mrg 					temp1, temp2));
   2379  1.1  mrg 	}
   2380  1.1  mrg       else
   2381  1.1  mrg 	{
   2382  1.1  mrg 	  rtx temp1 = gen_reg_rtx (DImode);
   2383  1.1  mrg 	  rtx temp2 = gen_reg_rtx (DImode);
   2384  1.1  mrg 	  rtx temp3 = gen_reg_rtx (DImode);
   2385  1.1  mrg 	  rtx ua = get_unaligned_address (operands[0]);
   2386  1.1  mrg 
   2387  1.1  mrg 	  seq = gen_unaligned_store
   2388  1.1  mrg 	    (mode, ua, operands[1], temp1, temp2, temp3);
   2389  1.1  mrg 
   2390  1.1  mrg 	  alpha_set_memflags (seq, operands[0]);
   2391  1.1  mrg 	  emit_insn (seq);
   2392  1.1  mrg 	}
   2393  1.1  mrg       return true;
   2394  1.1  mrg     }
   2395  1.1  mrg 
   2396  1.1  mrg   return false;
   2397  1.1  mrg }
   2398  1.1  mrg 
   2399  1.1  mrg /* Implement the movmisalign patterns.  One of the operands is a memory
   2400  1.1  mrg    that is not naturally aligned.  Emit instructions to load it.  */
   2401  1.1  mrg 
   2402  1.1  mrg void
   2403  1.1  mrg alpha_expand_movmisalign (machine_mode mode, rtx *operands)
   2404  1.1  mrg {
   2405  1.1  mrg   /* Honor misaligned loads, for those we promised to do so.  */
   2406  1.1  mrg   if (MEM_P (operands[1]))
   2407  1.1  mrg     {
   2408  1.1  mrg       rtx tmp;
   2409  1.1  mrg 
   2410  1.1  mrg       if (register_operand (operands[0], mode))
   2411  1.1  mrg 	tmp = operands[0];
   2412  1.1  mrg       else
   2413  1.1  mrg 	tmp = gen_reg_rtx (mode);
   2414  1.1  mrg 
   2415  1.1  mrg       alpha_expand_unaligned_load (tmp, operands[1], 8, 0, 0);
   2416  1.1  mrg       if (tmp != operands[0])
   2417  1.1  mrg 	emit_move_insn (operands[0], tmp);
   2418  1.1  mrg     }
   2419  1.1  mrg   else if (MEM_P (operands[0]))
   2420  1.1  mrg     {
   2421  1.1  mrg       if (!reg_or_0_operand (operands[1], mode))
   2422  1.1  mrg 	operands[1] = force_reg (mode, operands[1]);
   2423  1.1  mrg       alpha_expand_unaligned_store (operands[0], operands[1], 8, 0);
   2424  1.1  mrg     }
   2425  1.1  mrg   else
   2426  1.1  mrg     gcc_unreachable ();
   2427  1.1  mrg }
   2428  1.1  mrg 
   2429  1.1  mrg /* Generate an unsigned DImode to FP conversion.  This is the same code
   2430  1.1  mrg    optabs would emit if we didn't have TFmode patterns.
   2431  1.1  mrg 
   2432  1.1  mrg    For SFmode, this is the only construction I've found that can pass
   2433  1.1  mrg    gcc.c-torture/execute/ieee/rbug.c.  No scenario that uses DFmode
   2434  1.1  mrg    intermediates will work, because you'll get intermediate rounding
   2435  1.1  mrg    that ruins the end result.  Some of this could be fixed by turning
   2436  1.1  mrg    on round-to-positive-infinity, but that requires diddling the fpsr,
   2437  1.1  mrg    which kills performance.  I tried turning this around and converting
   2438  1.1  mrg    to a negative number, so that I could turn on /m, but either I did
   2439  1.1  mrg    it wrong or there's something else cause I wound up with the exact
   2440  1.1  mrg    same single-bit error.  There is a branch-less form of this same code:
   2441  1.1  mrg 
   2442  1.1  mrg 	srl     $16,1,$1
   2443  1.1  mrg 	and     $16,1,$2
   2444  1.1  mrg 	cmplt   $16,0,$3
   2445  1.1  mrg 	or      $1,$2,$2
   2446  1.1  mrg 	cmovge  $16,$16,$2
   2447  1.1  mrg 	itoft	$3,$f10
   2448  1.1  mrg 	itoft	$2,$f11
   2449  1.1  mrg 	cvtqs   $f11,$f11
   2450  1.1  mrg 	adds    $f11,$f11,$f0
   2451  1.1  mrg 	fcmoveq $f10,$f11,$f0
   2452  1.1  mrg 
   2453  1.1  mrg    I'm not using it because it's the same number of instructions as
   2454  1.1  mrg    this branch-full form, and it has more serialized long latency
   2455  1.1  mrg    instructions on the critical path.
   2456  1.1  mrg 
   2457  1.1  mrg    For DFmode, we can avoid rounding errors by breaking up the word
   2458  1.1  mrg    into two pieces, converting them separately, and adding them back:
   2459  1.1  mrg 
   2460  1.1  mrg    LC0: .long 0,0x5f800000
   2461  1.1  mrg 
   2462  1.1  mrg 	itoft	$16,$f11
   2463  1.1  mrg 	lda	$2,LC0
   2464  1.1  mrg 	cmplt	$16,0,$1
   2465  1.1  mrg 	cpyse	$f11,$f31,$f10
   2466  1.1  mrg 	cpyse	$f31,$f11,$f11
   2467  1.1  mrg 	s4addq	$1,$2,$1
   2468  1.1  mrg 	lds	$f12,0($1)
   2469  1.1  mrg 	cvtqt	$f10,$f10
   2470  1.1  mrg 	cvtqt	$f11,$f11
   2471  1.1  mrg 	addt	$f12,$f10,$f0
   2472  1.1  mrg 	addt	$f0,$f11,$f0
   2473  1.1  mrg 
   2474  1.1  mrg    This doesn't seem to be a clear-cut win over the optabs form.
   2475  1.1  mrg    It probably all depends on the distribution of numbers being
   2476  1.1  mrg    converted -- in the optabs form, all but high-bit-set has a
   2477  1.1  mrg    much lower minimum execution time.  */
   2478  1.1  mrg 
   2479  1.1  mrg void
   2480  1.1  mrg alpha_emit_floatuns (rtx operands[2])
   2481  1.1  mrg {
   2482  1.1  mrg   rtx neglab, donelab, i0, i1, f0, in, out;
   2483  1.1  mrg   machine_mode mode;
   2484  1.1  mrg 
   2485  1.1  mrg   out = operands[0];
   2486  1.1  mrg   in = force_reg (DImode, operands[1]);
   2487  1.1  mrg   mode = GET_MODE (out);
   2488  1.1  mrg   neglab = gen_label_rtx ();
   2489  1.1  mrg   donelab = gen_label_rtx ();
   2490  1.1  mrg   i0 = gen_reg_rtx (DImode);
   2491  1.1  mrg   i1 = gen_reg_rtx (DImode);
   2492  1.1  mrg   f0 = gen_reg_rtx (mode);
   2493  1.1  mrg 
   2494  1.1  mrg   emit_cmp_and_jump_insns (in, const0_rtx, LT, const0_rtx, DImode, 0, neglab);
   2495  1.1  mrg 
   2496  1.1  mrg   emit_insn (gen_rtx_SET (out, gen_rtx_FLOAT (mode, in)));
   2497  1.1  mrg   emit_jump_insn (gen_jump (donelab));
   2498  1.1  mrg   emit_barrier ();
   2499  1.1  mrg 
   2500  1.1  mrg   emit_label (neglab);
   2501  1.1  mrg 
   2502  1.1  mrg   emit_insn (gen_lshrdi3 (i0, in, const1_rtx));
   2503  1.1  mrg   emit_insn (gen_anddi3 (i1, in, const1_rtx));
   2504  1.1  mrg   emit_insn (gen_iordi3 (i0, i0, i1));
   2505  1.1  mrg   emit_insn (gen_rtx_SET (f0, gen_rtx_FLOAT (mode, i0)));
   2506  1.1  mrg   emit_insn (gen_rtx_SET (out, gen_rtx_PLUS (mode, f0, f0)));
   2507  1.1  mrg 
   2508  1.1  mrg   emit_label (donelab);
   2509  1.1  mrg }
   2510  1.1  mrg 
   2511  1.1  mrg /* Generate the comparison for a conditional branch.  */
   2512  1.1  mrg 
   2513  1.1  mrg void
   2514  1.1  mrg alpha_emit_conditional_branch (rtx operands[], machine_mode cmp_mode)
   2515  1.1  mrg {
   2516  1.1  mrg   enum rtx_code cmp_code, branch_code;
   2517  1.1  mrg   machine_mode branch_mode = VOIDmode;
   2518  1.1  mrg   enum rtx_code code = GET_CODE (operands[0]);
   2519  1.1  mrg   rtx op0 = operands[1], op1 = operands[2];
   2520  1.1  mrg   rtx tem;
   2521  1.1  mrg 
   2522  1.1  mrg   if (cmp_mode == TFmode)
   2523  1.1  mrg     {
   2524  1.1  mrg       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
   2525  1.1  mrg       op1 = const0_rtx;
   2526  1.1  mrg       cmp_mode = DImode;
   2527  1.1  mrg     }
   2528  1.1  mrg 
   2529  1.1  mrg   /* The general case: fold the comparison code to the types of compares
   2530  1.1  mrg      that we have, choosing the branch as necessary.  */
   2531  1.1  mrg   switch (code)
   2532  1.1  mrg     {
   2533  1.1  mrg     case EQ:  case LE:  case LT:  case LEU:  case LTU:
   2534  1.1  mrg     case UNORDERED:
   2535  1.1  mrg       /* We have these compares.  */
   2536  1.1  mrg       cmp_code = code, branch_code = NE;
   2537  1.1  mrg       break;
   2538  1.1  mrg 
   2539  1.1  mrg     case NE:
   2540  1.1  mrg     case ORDERED:
   2541  1.1  mrg       /* These must be reversed.  */
   2542  1.1  mrg       cmp_code = reverse_condition (code), branch_code = EQ;
   2543  1.1  mrg       break;
   2544  1.1  mrg 
   2545  1.1  mrg     case GE:  case GT: case GEU:  case GTU:
   2546  1.1  mrg       /* For FP, we swap them, for INT, we reverse them.  */
   2547  1.1  mrg       if (cmp_mode == DFmode)
   2548  1.1  mrg 	{
   2549  1.1  mrg 	  cmp_code = swap_condition (code);
   2550  1.1  mrg 	  branch_code = NE;
   2551  1.1  mrg 	  std::swap (op0, op1);
   2552  1.1  mrg 	}
   2553  1.1  mrg       else
   2554  1.1  mrg 	{
   2555  1.1  mrg 	  cmp_code = reverse_condition (code);
   2556  1.1  mrg 	  branch_code = EQ;
   2557  1.1  mrg 	}
   2558  1.1  mrg       break;
   2559  1.1  mrg 
   2560  1.1  mrg     default:
   2561  1.1  mrg       gcc_unreachable ();
   2562  1.1  mrg     }
   2563  1.1  mrg 
   2564  1.1  mrg   if (cmp_mode == DFmode)
   2565  1.1  mrg     {
   2566  1.1  mrg       if (flag_unsafe_math_optimizations && cmp_code != UNORDERED)
   2567  1.1  mrg 	{
   2568  1.1  mrg 	  /* When we are not as concerned about non-finite values, and we
   2569  1.1  mrg 	     are comparing against zero, we can branch directly.  */
   2570  1.1  mrg 	  if (op1 == CONST0_RTX (DFmode))
   2571  1.1  mrg 	    cmp_code = UNKNOWN, branch_code = code;
   2572  1.1  mrg 	  else if (op0 == CONST0_RTX (DFmode))
   2573  1.1  mrg 	    {
   2574  1.1  mrg 	      /* Undo the swap we probably did just above.  */
   2575  1.1  mrg 	      std::swap (op0, op1);
   2576  1.1  mrg 	      branch_code = swap_condition (cmp_code);
   2577  1.1  mrg 	      cmp_code = UNKNOWN;
   2578  1.1  mrg 	    }
   2579  1.1  mrg 	}
   2580  1.1  mrg       else
   2581  1.1  mrg 	{
   2582  1.1  mrg 	  /* ??? We mark the branch mode to be CCmode to prevent the
   2583  1.1  mrg 	     compare and branch from being combined, since the compare
   2584  1.1  mrg 	     insn follows IEEE rules that the branch does not.  */
   2585  1.1  mrg 	  branch_mode = CCmode;
   2586  1.1  mrg 	}
   2587  1.1  mrg     }
   2588  1.1  mrg   else
   2589  1.1  mrg     {
   2590  1.1  mrg       /* The following optimizations are only for signed compares.  */
   2591  1.1  mrg       if (code != LEU && code != LTU && code != GEU && code != GTU)
   2592  1.1  mrg 	{
   2593  1.1  mrg 	  /* Whee.  Compare and branch against 0 directly.  */
   2594  1.1  mrg 	  if (op1 == const0_rtx)
   2595  1.1  mrg 	    cmp_code = UNKNOWN, branch_code = code;
   2596  1.1  mrg 
   2597  1.1  mrg 	  /* If the constants doesn't fit into an immediate, but can
   2598  1.1  mrg  	     be generated by lda/ldah, we adjust the argument and
   2599  1.1  mrg  	     compare against zero, so we can use beq/bne directly.  */
   2600  1.1  mrg 	  /* ??? Don't do this when comparing against symbols, otherwise
   2601  1.1  mrg 	     we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
   2602  1.1  mrg 	     be declared false out of hand (at least for non-weak).  */
   2603  1.1  mrg 	  else if (CONST_INT_P (op1)
   2604  1.1  mrg 		   && (code == EQ || code == NE)
   2605  1.1  mrg 		   && !(symbolic_operand (op0, VOIDmode)
   2606  1.1  mrg 			|| (REG_P (op0) && REG_POINTER (op0))))
   2607  1.1  mrg 	    {
   2608  1.1  mrg 	      rtx n_op1 = GEN_INT (-INTVAL (op1));
   2609  1.1  mrg 
   2610  1.1  mrg 	      if (! satisfies_constraint_I (op1)
   2611  1.1  mrg 		  && (satisfies_constraint_K (n_op1)
   2612  1.1  mrg 		      || satisfies_constraint_L (n_op1)))
   2613  1.1  mrg 		cmp_code = PLUS, branch_code = code, op1 = n_op1;
   2614  1.1  mrg 	    }
   2615  1.1  mrg 	}
   2616  1.1  mrg 
   2617  1.1  mrg       if (!reg_or_0_operand (op0, DImode))
   2618  1.1  mrg 	op0 = force_reg (DImode, op0);
   2619  1.1  mrg       if (cmp_code != PLUS && !reg_or_8bit_operand (op1, DImode))
   2620  1.1  mrg 	op1 = force_reg (DImode, op1);
   2621  1.1  mrg     }
   2622  1.1  mrg 
   2623  1.1  mrg   /* Emit an initial compare instruction, if necessary.  */
   2624  1.1  mrg   tem = op0;
   2625  1.1  mrg   if (cmp_code != UNKNOWN)
   2626  1.1  mrg     {
   2627  1.1  mrg       tem = gen_reg_rtx (cmp_mode);
   2628  1.1  mrg       emit_move_insn (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1));
   2629  1.1  mrg     }
   2630  1.1  mrg 
   2631  1.1  mrg   /* Emit the branch instruction.  */
   2632  1.1  mrg   tem = gen_rtx_SET (pc_rtx,
   2633  1.1  mrg 		     gen_rtx_IF_THEN_ELSE (VOIDmode,
   2634  1.1  mrg 					   gen_rtx_fmt_ee (branch_code,
   2635  1.1  mrg 							   branch_mode, tem,
   2636  1.1  mrg 							   CONST0_RTX (cmp_mode)),
   2637  1.1  mrg 					   gen_rtx_LABEL_REF (VOIDmode,
   2638  1.1  mrg 							      operands[3]),
   2639  1.1  mrg 					   pc_rtx));
   2640  1.1  mrg   emit_jump_insn (tem);
   2641  1.1  mrg }
   2642  1.1  mrg 
   2643  1.1  mrg /* Certain simplifications can be done to make invalid setcc operations
   2644  1.1  mrg    valid.  Return the final comparison, or NULL if we can't work.  */
   2645  1.1  mrg 
   2646  1.1  mrg bool
   2647  1.1  mrg alpha_emit_setcc (rtx operands[], machine_mode cmp_mode)
   2648  1.1  mrg {
   2649  1.1  mrg   enum rtx_code cmp_code;
   2650  1.1  mrg   enum rtx_code code = GET_CODE (operands[1]);
   2651  1.1  mrg   rtx op0 = operands[2], op1 = operands[3];
   2652  1.1  mrg   rtx tmp;
   2653  1.1  mrg 
   2654  1.1  mrg   if (cmp_mode == TFmode)
   2655  1.1  mrg     {
   2656  1.1  mrg       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
   2657  1.1  mrg       op1 = const0_rtx;
   2658  1.1  mrg       cmp_mode = DImode;
   2659  1.1  mrg     }
   2660  1.1  mrg 
   2661  1.1  mrg   if (cmp_mode == DFmode && !TARGET_FIX)
   2662  1.1  mrg     return 0;
   2663  1.1  mrg 
   2664  1.1  mrg   /* The general case: fold the comparison code to the types of compares
   2665  1.1  mrg      that we have, choosing the branch as necessary.  */
   2666  1.1  mrg 
   2667  1.1  mrg   cmp_code = UNKNOWN;
   2668  1.1  mrg   switch (code)
   2669  1.1  mrg     {
   2670  1.1  mrg     case EQ:  case LE:  case LT:  case LEU:  case LTU:
   2671  1.1  mrg     case UNORDERED:
   2672  1.1  mrg       /* We have these compares.  */
   2673  1.1  mrg       if (cmp_mode == DFmode)
   2674  1.1  mrg 	cmp_code = code, code = NE;
   2675  1.1  mrg       break;
   2676  1.1  mrg 
   2677  1.1  mrg     case NE:
   2678  1.1  mrg       if (cmp_mode == DImode && op1 == const0_rtx)
   2679  1.1  mrg 	break;
   2680  1.1  mrg       /* FALLTHRU */
   2681  1.1  mrg 
   2682  1.1  mrg     case ORDERED:
   2683  1.1  mrg       cmp_code = reverse_condition (code);
   2684  1.1  mrg       code = EQ;
   2685  1.1  mrg       break;
   2686  1.1  mrg 
   2687  1.1  mrg     case GE:  case GT: case GEU:  case GTU:
   2688  1.1  mrg       /* These normally need swapping, but for integer zero we have
   2689  1.1  mrg 	 special patterns that recognize swapped operands.  */
   2690  1.1  mrg       if (cmp_mode == DImode && op1 == const0_rtx)
   2691  1.1  mrg 	break;
   2692  1.1  mrg       code = swap_condition (code);
   2693  1.1  mrg       if (cmp_mode == DFmode)
   2694  1.1  mrg 	cmp_code = code, code = NE;
   2695  1.1  mrg       std::swap (op0, op1);
   2696  1.1  mrg       break;
   2697  1.1  mrg 
   2698  1.1  mrg     default:
   2699  1.1  mrg       gcc_unreachable ();
   2700  1.1  mrg     }
   2701  1.1  mrg 
   2702  1.1  mrg   if (cmp_mode == DImode)
   2703  1.1  mrg     {
   2704  1.1  mrg       if (!register_operand (op0, DImode))
   2705  1.1  mrg 	op0 = force_reg (DImode, op0);
   2706  1.1  mrg       if (!reg_or_8bit_operand (op1, DImode))
   2707  1.1  mrg 	op1 = force_reg (DImode, op1);
   2708  1.1  mrg     }
   2709  1.1  mrg 
   2710  1.1  mrg   /* Emit an initial compare instruction, if necessary.  */
   2711  1.1  mrg   if (cmp_code != UNKNOWN)
   2712  1.1  mrg     {
   2713  1.1  mrg       tmp = gen_reg_rtx (cmp_mode);
   2714  1.1  mrg       emit_insn (gen_rtx_SET (tmp, gen_rtx_fmt_ee (cmp_code, cmp_mode,
   2715  1.1  mrg 						   op0, op1)));
   2716  1.1  mrg 
   2717  1.1  mrg       op0 = cmp_mode != DImode ? gen_lowpart (DImode, tmp) : tmp;
   2718  1.1  mrg       op1 = const0_rtx;
   2719  1.1  mrg     }
   2720  1.1  mrg 
   2721  1.1  mrg   /* Emit the setcc instruction.  */
   2722  1.1  mrg   emit_insn (gen_rtx_SET (operands[0], gen_rtx_fmt_ee (code, DImode,
   2723  1.1  mrg 						       op0, op1)));
   2724  1.1  mrg   return true;
   2725  1.1  mrg }
   2726  1.1  mrg 
   2727  1.1  mrg 
   2728  1.1  mrg /* Rewrite a comparison against zero CMP of the form
   2729  1.1  mrg    (CODE (cc0) (const_int 0)) so it can be written validly in
   2730  1.1  mrg    a conditional move (if_then_else CMP ...).
   2731  1.1  mrg    If both of the operands that set cc0 are nonzero we must emit
   2732  1.1  mrg    an insn to perform the compare (it can't be done within
   2733  1.1  mrg    the conditional move).  */
   2734  1.1  mrg 
   2735  1.1  mrg rtx
   2736  1.1  mrg alpha_emit_conditional_move (rtx cmp, machine_mode mode)
   2737  1.1  mrg {
   2738  1.1  mrg   enum rtx_code code = GET_CODE (cmp);
   2739  1.1  mrg   enum rtx_code cmov_code = NE;
   2740  1.1  mrg   rtx op0 = XEXP (cmp, 0);
   2741  1.1  mrg   rtx op1 = XEXP (cmp, 1);
   2742  1.1  mrg   machine_mode cmp_mode
   2743  1.1  mrg     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
   2744  1.1  mrg   machine_mode cmov_mode = VOIDmode;
   2745  1.1  mrg   int local_fast_math = flag_unsafe_math_optimizations;
   2746  1.1  mrg   rtx tem;
   2747  1.1  mrg 
   2748  1.1  mrg   if (cmp_mode == TFmode)
   2749  1.1  mrg     {
   2750  1.1  mrg       op0 = alpha_emit_xfloating_compare (&code, op0, op1);
   2751  1.1  mrg       op1 = const0_rtx;
   2752  1.1  mrg       cmp_mode = DImode;
   2753  1.1  mrg     }
   2754  1.1  mrg 
   2755  1.1  mrg   gcc_assert (cmp_mode == DFmode || cmp_mode == DImode);
   2756  1.1  mrg 
   2757  1.1  mrg   if (FLOAT_MODE_P (cmp_mode) != FLOAT_MODE_P (mode))
   2758  1.1  mrg     {
   2759  1.1  mrg       enum rtx_code cmp_code;
   2760  1.1  mrg 
   2761  1.1  mrg       if (! TARGET_FIX)
   2762  1.1  mrg 	return 0;
   2763  1.1  mrg 
   2764  1.1  mrg       /* If we have fp<->int register move instructions, do a cmov by
   2765  1.1  mrg 	 performing the comparison in fp registers, and move the
   2766  1.1  mrg 	 zero/nonzero value to integer registers, where we can then
   2767  1.1  mrg 	 use a normal cmov, or vice-versa.  */
   2768  1.1  mrg 
   2769  1.1  mrg       switch (code)
   2770  1.1  mrg 	{
   2771  1.1  mrg 	case EQ: case LE: case LT: case LEU: case LTU:
   2772  1.1  mrg 	case UNORDERED:
   2773  1.1  mrg 	  /* We have these compares.  */
   2774  1.1  mrg 	  cmp_code = code, code = NE;
   2775  1.1  mrg 	  break;
   2776  1.1  mrg 
   2777  1.1  mrg 	case NE:
   2778  1.1  mrg 	case ORDERED:
   2779  1.1  mrg 	  /* These must be reversed.  */
   2780  1.1  mrg 	  cmp_code = reverse_condition (code), code = EQ;
   2781  1.1  mrg 	  break;
   2782  1.1  mrg 
   2783  1.1  mrg 	case GE: case GT: case GEU: case GTU:
   2784  1.1  mrg 	  /* These normally need swapping, but for integer zero we have
   2785  1.1  mrg 	     special patterns that recognize swapped operands.  */
   2786  1.1  mrg 	  if (cmp_mode == DImode && op1 == const0_rtx)
   2787  1.1  mrg 	    cmp_code = code, code = NE;
   2788  1.1  mrg 	  else
   2789  1.1  mrg 	    {
   2790  1.1  mrg 	      cmp_code = swap_condition (code);
   2791  1.1  mrg 	      code = NE;
   2792  1.1  mrg 	      std::swap (op0, op1);
   2793  1.1  mrg 	    }
   2794  1.1  mrg 	  break;
   2795  1.1  mrg 
   2796  1.1  mrg 	default:
   2797  1.1  mrg 	  gcc_unreachable ();
   2798  1.1  mrg 	}
   2799  1.1  mrg 
   2800  1.1  mrg       if (cmp_mode == DImode)
   2801  1.1  mrg 	{
   2802  1.1  mrg 	  if (!reg_or_0_operand (op0, DImode))
   2803  1.1  mrg 	    op0 = force_reg (DImode, op0);
   2804  1.1  mrg 	  if (!reg_or_8bit_operand (op1, DImode))
   2805  1.1  mrg 	    op1 = force_reg (DImode, op1);
   2806  1.1  mrg 	}
   2807  1.1  mrg 
   2808  1.1  mrg       tem = gen_reg_rtx (cmp_mode);
   2809  1.1  mrg       emit_insn (gen_rtx_SET (tem, gen_rtx_fmt_ee (cmp_code, cmp_mode,
   2810  1.1  mrg 						   op0, op1)));
   2811  1.1  mrg 
   2812  1.1  mrg       cmp_mode = cmp_mode == DImode ? E_DFmode : E_DImode;
   2813  1.1  mrg       op0 = gen_lowpart (cmp_mode, tem);
   2814  1.1  mrg       op1 = CONST0_RTX (cmp_mode);
   2815  1.1  mrg       cmp = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
   2816  1.1  mrg       local_fast_math = 1;
   2817  1.1  mrg     }
   2818  1.1  mrg 
   2819  1.1  mrg   if (cmp_mode == DImode)
   2820  1.1  mrg     {
   2821  1.1  mrg       if (!reg_or_0_operand (op0, DImode))
   2822  1.1  mrg 	op0 = force_reg (DImode, op0);
   2823  1.1  mrg       if (!reg_or_8bit_operand (op1, DImode))
   2824  1.1  mrg 	op1 = force_reg (DImode, op1);
   2825  1.1  mrg     }
   2826  1.1  mrg 
   2827  1.1  mrg   /* We may be able to use a conditional move directly.
   2828  1.1  mrg      This avoids emitting spurious compares.  */
   2829  1.1  mrg   if (signed_comparison_operator (cmp, VOIDmode)
   2830  1.1  mrg       && (cmp_mode == DImode || local_fast_math)
   2831  1.1  mrg       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
   2832  1.1  mrg     return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
   2833  1.1  mrg 
   2834  1.1  mrg   /* We can't put the comparison inside the conditional move;
   2835  1.1  mrg      emit a compare instruction and put that inside the
   2836  1.1  mrg      conditional move.  Make sure we emit only comparisons we have;
   2837  1.1  mrg      swap or reverse as necessary.  */
   2838  1.1  mrg 
   2839  1.1  mrg   if (!can_create_pseudo_p ())
   2840  1.1  mrg     return NULL_RTX;
   2841  1.1  mrg 
   2842  1.1  mrg   switch (code)
   2843  1.1  mrg     {
   2844  1.1  mrg     case EQ:  case LE:  case LT:  case LEU:  case LTU:
   2845  1.1  mrg     case UNORDERED:
   2846  1.1  mrg       /* We have these compares: */
   2847  1.1  mrg       break;
   2848  1.1  mrg 
   2849  1.1  mrg     case NE:
   2850  1.1  mrg     case ORDERED:
   2851  1.1  mrg       /* These must be reversed.  */
   2852  1.1  mrg       code = reverse_condition (code);
   2853  1.1  mrg       cmov_code = EQ;
   2854  1.1  mrg       break;
   2855  1.1  mrg 
   2856  1.1  mrg     case GE:  case GT:  case GEU:  case GTU:
   2857  1.1  mrg       /* These normally need swapping, but for integer zero we have
   2858  1.1  mrg 	 special patterns that recognize swapped operands.  */
   2859  1.1  mrg       if (cmp_mode == DImode && op1 == const0_rtx)
   2860  1.1  mrg 	break;
   2861  1.1  mrg       code = swap_condition (code);
   2862  1.1  mrg       std::swap (op0, op1);
   2863  1.1  mrg       break;
   2864  1.1  mrg 
   2865  1.1  mrg     default:
   2866  1.1  mrg       gcc_unreachable ();
   2867  1.1  mrg     }
   2868  1.1  mrg 
   2869  1.1  mrg   if (cmp_mode == DImode)
   2870  1.1  mrg     {
   2871  1.1  mrg       if (!reg_or_0_operand (op0, DImode))
   2872  1.1  mrg 	op0 = force_reg (DImode, op0);
   2873  1.1  mrg       if (!reg_or_8bit_operand (op1, DImode))
   2874  1.1  mrg 	op1 = force_reg (DImode, op1);
   2875  1.1  mrg     }
   2876  1.1  mrg 
   2877  1.1  mrg   /* ??? We mark the branch mode to be CCmode to prevent the compare
   2878  1.1  mrg      and cmov from being combined, since the compare insn follows IEEE
   2879  1.1  mrg      rules that the cmov does not.  */
   2880  1.1  mrg   if (cmp_mode == DFmode && !local_fast_math)
   2881  1.1  mrg     cmov_mode = CCmode;
   2882  1.1  mrg 
   2883  1.1  mrg   tem = gen_reg_rtx (cmp_mode);
   2884  1.1  mrg   emit_move_insn (tem, gen_rtx_fmt_ee (code, cmp_mode, op0, op1));
   2885  1.1  mrg   return gen_rtx_fmt_ee (cmov_code, cmov_mode, tem, CONST0_RTX (cmp_mode));
   2886  1.1  mrg }
   2887  1.1  mrg 
   2888  1.1  mrg /* Simplify a conditional move of two constants into a setcc with
   2889  1.1  mrg    arithmetic.  This is done with a splitter since combine would
   2890  1.1  mrg    just undo the work if done during code generation.  It also catches
   2891  1.1  mrg    cases we wouldn't have before cse.  */
   2892  1.1  mrg 
   2893  1.1  mrg int
   2894  1.1  mrg alpha_split_conditional_move (enum rtx_code code, rtx dest, rtx cond,
   2895  1.1  mrg 			      rtx t_rtx, rtx f_rtx)
   2896  1.1  mrg {
   2897  1.1  mrg   HOST_WIDE_INT t, f, diff;
   2898  1.1  mrg   machine_mode mode;
   2899  1.1  mrg   rtx target, subtarget, tmp;
   2900  1.1  mrg 
   2901  1.1  mrg   mode = GET_MODE (dest);
   2902  1.1  mrg   t = INTVAL (t_rtx);
   2903  1.1  mrg   f = INTVAL (f_rtx);
   2904  1.1  mrg   diff = t - f;
   2905  1.1  mrg 
   2906  1.1  mrg   if (((code == NE || code == EQ) && diff < 0)
   2907  1.1  mrg       || (code == GE || code == GT))
   2908  1.1  mrg     {
   2909  1.1  mrg       code = reverse_condition (code);
   2910  1.1  mrg       std::swap (t, f);
   2911  1.1  mrg       diff = -diff;
   2912  1.1  mrg     }
   2913  1.1  mrg 
   2914  1.1  mrg   subtarget = target = dest;
   2915  1.1  mrg   if (mode != DImode)
   2916  1.1  mrg     {
   2917  1.1  mrg       target = gen_lowpart (DImode, dest);
   2918  1.1  mrg       if (can_create_pseudo_p ())
   2919  1.1  mrg         subtarget = gen_reg_rtx (DImode);
   2920  1.1  mrg       else
   2921  1.1  mrg 	subtarget = target;
   2922  1.1  mrg     }
   2923  1.1  mrg   /* Below, we must be careful to use copy_rtx on target and subtarget
   2924  1.1  mrg      in intermediate insns, as they may be a subreg rtx, which may not
   2925  1.1  mrg      be shared.  */
   2926  1.1  mrg 
   2927  1.1  mrg   if (f == 0 && exact_log2 (diff) > 0
   2928  1.1  mrg       /* On EV6, we've got enough shifters to make non-arithmetic shifts
   2929  1.1  mrg 	 viable over a longer latency cmove.  On EV5, the E0 slot is a
   2930  1.1  mrg 	 scarce resource, and on EV4 shift has the same latency as a cmove.  */
   2931  1.1  mrg       && (diff <= 8 || alpha_tune == PROCESSOR_EV6))
   2932  1.1  mrg     {
   2933  1.1  mrg       tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
   2934  1.1  mrg       emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp));
   2935  1.1  mrg 
   2936  1.1  mrg       tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
   2937  1.1  mrg 			    GEN_INT (exact_log2 (t)));
   2938  1.1  mrg       emit_insn (gen_rtx_SET (target, tmp));
   2939  1.1  mrg     }
   2940  1.1  mrg   else if (f == 0 && t == -1)
   2941  1.1  mrg     {
   2942  1.1  mrg       tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
   2943  1.1  mrg       emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp));
   2944  1.1  mrg 
   2945  1.1  mrg       emit_insn (gen_negdi2 (target, copy_rtx (subtarget)));
   2946  1.1  mrg     }
   2947  1.1  mrg   else if (diff == 1 || diff == 4 || diff == 8)
   2948  1.1  mrg     {
   2949  1.1  mrg       rtx add_op;
   2950  1.1  mrg 
   2951  1.1  mrg       tmp = gen_rtx_fmt_ee (code, DImode, cond, const0_rtx);
   2952  1.1  mrg       emit_insn (gen_rtx_SET (copy_rtx (subtarget), tmp));
   2953  1.1  mrg 
   2954  1.1  mrg       if (diff == 1)
   2955  1.1  mrg 	emit_insn (gen_adddi3 (target, copy_rtx (subtarget), GEN_INT (f)));
   2956  1.1  mrg       else
   2957  1.1  mrg 	{
   2958  1.1  mrg 	  add_op = GEN_INT (f);
   2959  1.1  mrg 	  if (sext_add_operand (add_op, mode))
   2960  1.1  mrg 	    {
   2961  1.1  mrg 	      tmp = gen_rtx_ASHIFT (DImode, copy_rtx (subtarget),
   2962  1.1  mrg 				    GEN_INT (exact_log2 (diff)));
   2963  1.1  mrg 	      tmp = gen_rtx_PLUS (DImode, tmp, add_op);
   2964  1.1  mrg 	      emit_insn (gen_rtx_SET (target, tmp));
   2965  1.1  mrg 	    }
   2966  1.1  mrg 	  else
   2967  1.1  mrg 	    return 0;
   2968  1.1  mrg 	}
   2969  1.1  mrg     }
   2970  1.1  mrg   else
   2971  1.1  mrg     return 0;
   2972  1.1  mrg 
   2973  1.1  mrg   return 1;
   2974  1.1  mrg }
   2975  1.1  mrg 
   2976  1.1  mrg /* Look up the function X_floating library function name for the
   2978  1.1  mrg    given operation.  */
   2979  1.1  mrg 
   2980  1.1  mrg struct GTY(()) xfloating_op
   2981  1.1  mrg {
   2982  1.1  mrg   const enum rtx_code code;
   2983  1.1  mrg   const char *const GTY((skip)) osf_func;
   2984  1.1  mrg   const char *const GTY((skip)) vms_func;
   2985  1.1  mrg   rtx libcall;
   2986  1.1  mrg };
   2987  1.1  mrg 
   2988  1.1  mrg static GTY(()) struct xfloating_op xfloating_ops[] =
   2989  1.1  mrg {
   2990  1.1  mrg   { PLUS,		"_OtsAddX", "OTS$ADD_X", 0 },
   2991  1.1  mrg   { MINUS,		"_OtsSubX", "OTS$SUB_X", 0 },
   2992  1.1  mrg   { MULT,		"_OtsMulX", "OTS$MUL_X", 0 },
   2993  1.1  mrg   { DIV,		"_OtsDivX", "OTS$DIV_X", 0 },
   2994  1.1  mrg   { EQ,			"_OtsEqlX", "OTS$EQL_X", 0 },
   2995  1.1  mrg   { NE,			"_OtsNeqX", "OTS$NEQ_X", 0 },
   2996  1.1  mrg   { LT,			"_OtsLssX", "OTS$LSS_X", 0 },
   2997  1.1  mrg   { LE,			"_OtsLeqX", "OTS$LEQ_X", 0 },
   2998  1.1  mrg   { GT,			"_OtsGtrX", "OTS$GTR_X", 0 },
   2999  1.1  mrg   { GE,			"_OtsGeqX", "OTS$GEQ_X", 0 },
   3000  1.1  mrg   { FIX,		"_OtsCvtXQ", "OTS$CVTXQ", 0 },
   3001  1.1  mrg   { FLOAT,		"_OtsCvtQX", "OTS$CVTQX", 0 },
   3002  1.1  mrg   { UNSIGNED_FLOAT,	"_OtsCvtQUX", "OTS$CVTQUX", 0 },
   3003  1.1  mrg   { FLOAT_EXTEND,	"_OtsConvertFloatTX", "OTS$CVT_FLOAT_T_X", 0 },
   3004  1.1  mrg   { FLOAT_TRUNCATE,	"_OtsConvertFloatXT", "OTS$CVT_FLOAT_X_T", 0 }
   3005  1.1  mrg };
   3006  1.1  mrg 
   3007  1.1  mrg static GTY(()) struct xfloating_op vax_cvt_ops[] =
   3008  1.1  mrg {
   3009  1.1  mrg   { FLOAT_EXTEND,	"_OtsConvertFloatGX", "OTS$CVT_FLOAT_G_X", 0 },
   3010  1.1  mrg   { FLOAT_TRUNCATE,	"_OtsConvertFloatXG", "OTS$CVT_FLOAT_X_G", 0 }
   3011  1.1  mrg };
   3012  1.1  mrg 
   3013  1.1  mrg static rtx
   3014  1.1  mrg alpha_lookup_xfloating_lib_func (enum rtx_code code)
   3015  1.1  mrg {
   3016  1.1  mrg   struct xfloating_op *ops = xfloating_ops;
   3017  1.1  mrg   long n = ARRAY_SIZE (xfloating_ops);
   3018  1.1  mrg   long i;
   3019  1.1  mrg 
   3020  1.1  mrg   gcc_assert (TARGET_HAS_XFLOATING_LIBS);
   3021  1.1  mrg 
   3022  1.1  mrg   /* How irritating.  Nothing to key off for the main table.  */
   3023  1.1  mrg   if (TARGET_FLOAT_VAX && (code == FLOAT_EXTEND || code == FLOAT_TRUNCATE))
   3024  1.1  mrg     {
   3025  1.1  mrg       ops = vax_cvt_ops;
   3026  1.1  mrg       n = ARRAY_SIZE (vax_cvt_ops);
   3027  1.1  mrg     }
   3028  1.1  mrg 
   3029  1.1  mrg   for (i = 0; i < n; ++i, ++ops)
   3030  1.1  mrg     if (ops->code == code)
   3031  1.1  mrg       {
   3032  1.1  mrg 	rtx func = ops->libcall;
   3033  1.1  mrg 	if (!func)
   3034  1.1  mrg 	  {
   3035  1.1  mrg 	    func = init_one_libfunc (TARGET_ABI_OPEN_VMS
   3036  1.1  mrg 				     ? ops->vms_func : ops->osf_func);
   3037  1.1  mrg 	    ops->libcall = func;
   3038  1.1  mrg 	  }
   3039  1.1  mrg         return func;
   3040  1.1  mrg       }
   3041  1.1  mrg 
   3042  1.1  mrg   gcc_unreachable ();
   3043  1.1  mrg }
   3044  1.1  mrg 
   3045  1.1  mrg /* Most X_floating operations take the rounding mode as an argument.
   3046  1.1  mrg    Compute that here.  */
   3047  1.1  mrg 
   3048  1.1  mrg static int
   3049  1.1  mrg alpha_compute_xfloating_mode_arg (enum rtx_code code,
   3050  1.1  mrg 				  enum alpha_fp_rounding_mode round)
   3051  1.1  mrg {
   3052  1.1  mrg   int mode;
   3053  1.1  mrg 
   3054  1.1  mrg   switch (round)
   3055  1.1  mrg     {
   3056  1.1  mrg     case ALPHA_FPRM_NORM:
   3057  1.1  mrg       mode = 2;
   3058  1.1  mrg       break;
   3059  1.1  mrg     case ALPHA_FPRM_MINF:
   3060  1.1  mrg       mode = 1;
   3061  1.1  mrg       break;
   3062  1.1  mrg     case ALPHA_FPRM_CHOP:
   3063  1.1  mrg       mode = 0;
   3064  1.1  mrg       break;
   3065  1.1  mrg     case ALPHA_FPRM_DYN:
   3066  1.1  mrg       mode = 4;
   3067  1.1  mrg       break;
   3068  1.1  mrg     default:
   3069  1.1  mrg       gcc_unreachable ();
   3070  1.1  mrg 
   3071  1.1  mrg     /* XXX For reference, round to +inf is mode = 3.  */
   3072  1.1  mrg     }
   3073  1.1  mrg 
   3074  1.1  mrg   if (code == FLOAT_TRUNCATE && alpha_fptm == ALPHA_FPTM_N)
   3075  1.1  mrg     mode |= 0x10000;
   3076  1.1  mrg 
   3077  1.1  mrg   return mode;
   3078  1.1  mrg }
   3079  1.1  mrg 
   3080  1.1  mrg /* Emit an X_floating library function call.
   3081  1.1  mrg 
   3082  1.1  mrg    Note that these functions do not follow normal calling conventions:
   3083  1.1  mrg    TFmode arguments are passed in two integer registers (as opposed to
   3084  1.1  mrg    indirect); TFmode return values appear in R16+R17.
   3085  1.1  mrg 
   3086  1.1  mrg    FUNC is the function to call.
   3087  1.1  mrg    TARGET is where the output belongs.
   3088  1.1  mrg    OPERANDS are the inputs.
   3089  1.1  mrg    NOPERANDS is the count of inputs.
   3090  1.1  mrg    EQUIV is the expression equivalent for the function.
   3091  1.1  mrg */
   3092  1.1  mrg 
   3093  1.1  mrg static void
   3094  1.1  mrg alpha_emit_xfloating_libcall (rtx func, rtx target, rtx operands[],
   3095  1.1  mrg 			      int noperands, rtx equiv)
   3096  1.1  mrg {
   3097  1.1  mrg   rtx usage = NULL_RTX, reg;
   3098  1.1  mrg   int regno = 16, i;
   3099  1.1  mrg 
   3100  1.1  mrg   start_sequence ();
   3101  1.1  mrg 
   3102  1.1  mrg   for (i = 0; i < noperands; ++i)
   3103  1.1  mrg     {
   3104  1.1  mrg       switch (GET_MODE (operands[i]))
   3105  1.1  mrg 	{
   3106  1.1  mrg 	case E_TFmode:
   3107  1.1  mrg 	  reg = gen_rtx_REG (TFmode, regno);
   3108  1.1  mrg 	  regno += 2;
   3109  1.1  mrg 	  break;
   3110  1.1  mrg 
   3111  1.1  mrg 	case E_DFmode:
   3112  1.1  mrg 	  reg = gen_rtx_REG (DFmode, regno + 32);
   3113  1.1  mrg 	  regno += 1;
   3114  1.1  mrg 	  break;
   3115  1.1  mrg 
   3116  1.1  mrg 	case E_VOIDmode:
   3117  1.1  mrg 	  gcc_assert (CONST_INT_P (operands[i]));
   3118  1.1  mrg 	  /* FALLTHRU */
   3119  1.1  mrg 	case E_DImode:
   3120  1.1  mrg 	  reg = gen_rtx_REG (DImode, regno);
   3121  1.1  mrg 	  regno += 1;
   3122  1.1  mrg 	  break;
   3123  1.1  mrg 
   3124  1.1  mrg 	default:
   3125  1.1  mrg 	  gcc_unreachable ();
   3126  1.1  mrg 	}
   3127  1.1  mrg 
   3128  1.1  mrg       emit_move_insn (reg, operands[i]);
   3129  1.1  mrg       use_reg (&usage, reg);
   3130  1.1  mrg     }
   3131  1.1  mrg 
   3132  1.1  mrg   switch (GET_MODE (target))
   3133  1.1  mrg     {
   3134  1.1  mrg     case E_TFmode:
   3135  1.1  mrg       reg = gen_rtx_REG (TFmode, 16);
   3136  1.1  mrg       break;
   3137  1.1  mrg     case E_DFmode:
   3138  1.1  mrg       reg = gen_rtx_REG (DFmode, 32);
   3139  1.1  mrg       break;
   3140  1.1  mrg     case E_DImode:
   3141  1.1  mrg       reg = gen_rtx_REG (DImode, 0);
   3142  1.1  mrg       break;
   3143  1.1  mrg     default:
   3144  1.1  mrg       gcc_unreachable ();
   3145  1.1  mrg     }
   3146  1.1  mrg 
   3147  1.1  mrg   rtx mem = gen_rtx_MEM (QImode, func);
   3148  1.1  mrg   rtx_insn *tmp = emit_call_insn (gen_call_value (reg, mem, const0_rtx,
   3149  1.1  mrg 						  const0_rtx, const0_rtx));
   3150  1.1  mrg   CALL_INSN_FUNCTION_USAGE (tmp) = usage;
   3151  1.1  mrg   RTL_CONST_CALL_P (tmp) = 1;
   3152  1.1  mrg 
   3153  1.1  mrg   tmp = get_insns ();
   3154  1.1  mrg   end_sequence ();
   3155  1.1  mrg 
   3156  1.1  mrg   emit_libcall_block (tmp, target, reg, equiv);
   3157  1.1  mrg }
   3158  1.1  mrg 
   3159  1.1  mrg /* Emit an X_floating library function call for arithmetic (+,-,*,/).  */
   3160  1.1  mrg 
   3161  1.1  mrg void
   3162  1.1  mrg alpha_emit_xfloating_arith (enum rtx_code code, rtx operands[])
   3163  1.1  mrg {
   3164  1.1  mrg   rtx func;
   3165  1.1  mrg   int mode;
   3166  1.1  mrg   rtx out_operands[3];
   3167  1.1  mrg 
   3168  1.1  mrg   func = alpha_lookup_xfloating_lib_func (code);
   3169  1.1  mrg   mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
   3170  1.1  mrg 
   3171  1.1  mrg   out_operands[0] = operands[1];
   3172  1.1  mrg   out_operands[1] = operands[2];
   3173  1.1  mrg   out_operands[2] = GEN_INT (mode);
   3174  1.1  mrg   alpha_emit_xfloating_libcall (func, operands[0], out_operands, 3,
   3175  1.1  mrg 				gen_rtx_fmt_ee (code, TFmode, operands[1],
   3176  1.1  mrg 						operands[2]));
   3177  1.1  mrg }
   3178  1.1  mrg 
   3179  1.1  mrg /* Emit an X_floating library function call for a comparison.  */
   3180  1.1  mrg 
   3181  1.1  mrg static rtx
   3182  1.1  mrg alpha_emit_xfloating_compare (enum rtx_code *pcode, rtx op0, rtx op1)
   3183  1.1  mrg {
   3184  1.1  mrg   enum rtx_code cmp_code, res_code;
   3185  1.1  mrg   rtx func, out, operands[2], note;
   3186  1.1  mrg 
   3187  1.1  mrg   /* X_floating library comparison functions return
   3188  1.1  mrg 	   -1  unordered
   3189  1.1  mrg 	    0  false
   3190  1.1  mrg 	    1  true
   3191  1.1  mrg      Convert the compare against the raw return value.  */
   3192  1.1  mrg 
   3193  1.1  mrg   cmp_code = *pcode;
   3194  1.1  mrg   switch (cmp_code)
   3195  1.1  mrg     {
   3196  1.1  mrg     case UNORDERED:
   3197  1.1  mrg       cmp_code = EQ;
   3198  1.1  mrg       res_code = LT;
   3199  1.1  mrg       break;
   3200  1.1  mrg     case ORDERED:
   3201  1.1  mrg       cmp_code = EQ;
   3202  1.1  mrg       res_code = GE;
   3203  1.1  mrg       break;
   3204  1.1  mrg     case NE:
   3205  1.1  mrg       res_code = NE;
   3206  1.1  mrg       break;
   3207  1.1  mrg     case EQ:
   3208  1.1  mrg     case LT:
   3209  1.1  mrg     case GT:
   3210  1.1  mrg     case LE:
   3211  1.1  mrg     case GE:
   3212  1.1  mrg       res_code = GT;
   3213  1.1  mrg       break;
   3214  1.1  mrg     default:
   3215  1.1  mrg       gcc_unreachable ();
   3216  1.1  mrg     }
   3217  1.1  mrg   *pcode = res_code;
   3218  1.1  mrg 
   3219  1.1  mrg   func = alpha_lookup_xfloating_lib_func (cmp_code);
   3220  1.1  mrg 
   3221  1.1  mrg   operands[0] = op0;
   3222  1.1  mrg   operands[1] = op1;
   3223  1.1  mrg   out = gen_reg_rtx (DImode);
   3224  1.1  mrg 
   3225  1.1  mrg   /* What's actually returned is -1,0,1, not a proper boolean value.  */
   3226  1.1  mrg   note = gen_rtx_fmt_ee (cmp_code, VOIDmode, op0, op1);
   3227  1.1  mrg   note = gen_rtx_UNSPEC (DImode, gen_rtvec (1, note), UNSPEC_XFLT_COMPARE);
   3228  1.1  mrg   alpha_emit_xfloating_libcall (func, out, operands, 2, note);
   3229  1.1  mrg 
   3230  1.1  mrg   return out;
   3231  1.1  mrg }
   3232  1.1  mrg 
   3233  1.1  mrg /* Emit an X_floating library function call for a conversion.  */
   3234  1.1  mrg 
   3235  1.1  mrg void
   3236  1.1  mrg alpha_emit_xfloating_cvt (enum rtx_code orig_code, rtx operands[])
   3237  1.1  mrg {
   3238  1.1  mrg   int noperands = 1, mode;
   3239  1.1  mrg   rtx out_operands[2];
   3240  1.1  mrg   rtx func;
   3241  1.1  mrg   enum rtx_code code = orig_code;
   3242  1.1  mrg 
   3243  1.1  mrg   if (code == UNSIGNED_FIX)
   3244  1.1  mrg     code = FIX;
   3245  1.1  mrg 
   3246  1.1  mrg   func = alpha_lookup_xfloating_lib_func (code);
   3247  1.1  mrg 
   3248  1.1  mrg   out_operands[0] = operands[1];
   3249  1.1  mrg 
   3250  1.1  mrg   switch (code)
   3251  1.1  mrg     {
   3252  1.1  mrg     case FIX:
   3253  1.1  mrg       mode = alpha_compute_xfloating_mode_arg (code, ALPHA_FPRM_CHOP);
   3254  1.1  mrg       out_operands[1] = GEN_INT (mode);
   3255  1.1  mrg       noperands = 2;
   3256  1.1  mrg       break;
   3257  1.1  mrg     case FLOAT_TRUNCATE:
   3258  1.1  mrg       mode = alpha_compute_xfloating_mode_arg (code, alpha_fprm);
   3259  1.1  mrg       out_operands[1] = GEN_INT (mode);
   3260  1.1  mrg       noperands = 2;
   3261  1.1  mrg       break;
   3262  1.1  mrg     default:
   3263  1.1  mrg       break;
   3264  1.1  mrg     }
   3265  1.1  mrg 
   3266  1.1  mrg   alpha_emit_xfloating_libcall (func, operands[0], out_operands, noperands,
   3267  1.1  mrg 				gen_rtx_fmt_e (orig_code,
   3268  1.1  mrg 					       GET_MODE (operands[0]),
   3269  1.1  mrg 					       operands[1]));
   3270  1.1  mrg }
   3271  1.1  mrg 
   3272  1.1  mrg /* Split a TImode or TFmode move from OP[1] to OP[0] into a pair of
   3273  1.1  mrg    DImode moves from OP[2,3] to OP[0,1].  If FIXUP_OVERLAP is true,
   3274  1.1  mrg    guarantee that the sequence
   3275  1.1  mrg      set (OP[0] OP[2])
   3276  1.1  mrg      set (OP[1] OP[3])
   3277  1.1  mrg    is valid.  Naturally, output operand ordering is little-endian.
   3278  1.1  mrg    This is used by *movtf_internal and *movti_internal.  */
   3279  1.1  mrg 
   3280  1.1  mrg void
   3281  1.1  mrg alpha_split_tmode_pair (rtx operands[4], machine_mode mode,
   3282  1.1  mrg 			bool fixup_overlap)
   3283  1.1  mrg {
   3284  1.1  mrg   switch (GET_CODE (operands[1]))
   3285  1.1  mrg     {
   3286  1.1  mrg     case REG:
   3287  1.1  mrg       operands[3] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1);
   3288  1.1  mrg       operands[2] = gen_rtx_REG (DImode, REGNO (operands[1]));
   3289  1.1  mrg       break;
   3290  1.1  mrg 
   3291  1.1  mrg     case MEM:
   3292  1.1  mrg       operands[3] = adjust_address (operands[1], DImode, 8);
   3293  1.1  mrg       operands[2] = adjust_address (operands[1], DImode, 0);
   3294  1.1  mrg       break;
   3295  1.1  mrg 
   3296  1.1  mrg     CASE_CONST_SCALAR_INT:
   3297  1.1  mrg     case CONST_DOUBLE:
   3298  1.1  mrg       gcc_assert (operands[1] == CONST0_RTX (mode));
   3299  1.1  mrg       operands[2] = operands[3] = const0_rtx;
   3300  1.1  mrg       break;
   3301  1.1  mrg 
   3302  1.1  mrg     default:
   3303  1.1  mrg       gcc_unreachable ();
   3304  1.1  mrg     }
   3305  1.1  mrg 
   3306  1.1  mrg   switch (GET_CODE (operands[0]))
   3307  1.1  mrg     {
   3308  1.1  mrg     case REG:
   3309  1.1  mrg       operands[1] = gen_rtx_REG (DImode, REGNO (operands[0]) + 1);
   3310  1.1  mrg       operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
   3311  1.1  mrg       break;
   3312  1.1  mrg 
   3313  1.1  mrg     case MEM:
   3314  1.1  mrg       operands[1] = adjust_address (operands[0], DImode, 8);
   3315  1.1  mrg       operands[0] = adjust_address (operands[0], DImode, 0);
   3316  1.1  mrg       break;
   3317  1.1  mrg 
   3318  1.1  mrg     default:
   3319  1.1  mrg       gcc_unreachable ();
   3320  1.1  mrg     }
   3321  1.1  mrg 
   3322  1.1  mrg   if (fixup_overlap && reg_overlap_mentioned_p (operands[0], operands[3]))
   3323  1.1  mrg     {
   3324  1.1  mrg       std::swap (operands[0], operands[1]);
   3325  1.1  mrg       std::swap (operands[2], operands[3]);
   3326  1.1  mrg     }
   3327  1.1  mrg }
   3328  1.1  mrg 
   3329  1.1  mrg /* Implement negtf2 or abstf2.  Op0 is destination, op1 is source,
   3330  1.1  mrg    op2 is a register containing the sign bit, operation is the
   3331  1.1  mrg    logical operation to be performed.  */
   3332  1.1  mrg 
   3333  1.1  mrg void
   3334  1.1  mrg alpha_split_tfmode_frobsign (rtx operands[3], rtx (*operation) (rtx, rtx, rtx))
   3335  1.1  mrg {
   3336  1.1  mrg   rtx high_bit = operands[2];
   3337  1.1  mrg   rtx scratch;
   3338  1.1  mrg   int move;
   3339  1.1  mrg 
   3340  1.1  mrg   alpha_split_tmode_pair (operands, TFmode, false);
   3341  1.1  mrg 
   3342  1.1  mrg   /* Detect three flavors of operand overlap.  */
   3343  1.1  mrg   move = 1;
   3344  1.1  mrg   if (rtx_equal_p (operands[0], operands[2]))
   3345  1.1  mrg     move = 0;
   3346  1.1  mrg   else if (rtx_equal_p (operands[1], operands[2]))
   3347  1.1  mrg     {
   3348  1.1  mrg       if (rtx_equal_p (operands[0], high_bit))
   3349  1.1  mrg 	move = 2;
   3350  1.1  mrg       else
   3351  1.1  mrg 	move = -1;
   3352  1.1  mrg     }
   3353  1.1  mrg 
   3354  1.1  mrg   if (move < 0)
   3355  1.1  mrg     emit_move_insn (operands[0], operands[2]);
   3356  1.1  mrg 
   3357  1.1  mrg   /* ??? If the destination overlaps both source tf and high_bit, then
   3358  1.1  mrg      assume source tf is dead in its entirety and use the other half
   3359  1.1  mrg      for a scratch register.  Otherwise "scratch" is just the proper
   3360  1.1  mrg      destination register.  */
   3361  1.1  mrg   scratch = operands[move < 2 ? 1 : 3];
   3362  1.1  mrg 
   3363  1.1  mrg   emit_insn ((*operation) (scratch, high_bit, operands[3]));
   3364  1.1  mrg 
   3365  1.1  mrg   if (move > 0)
   3366  1.1  mrg     {
   3367  1.1  mrg       emit_move_insn (operands[0], operands[2]);
   3368  1.1  mrg       if (move > 1)
   3369  1.1  mrg 	emit_move_insn (operands[1], scratch);
   3370  1.1  mrg     }
   3371  1.1  mrg }
   3372  1.1  mrg 
   3373  1.1  mrg /* Use ext[wlq][lh] as the Architecture Handbook describes for extracting
   3375  1.1  mrg    unaligned data:
   3376  1.1  mrg 
   3377  1.1  mrg            unsigned:                       signed:
   3378  1.1  mrg    word:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
   3379  1.1  mrg            ldq_u  r2,X+1(r11)              ldq_u  r2,X+1(r11)
   3380  1.1  mrg            lda    r3,X(r11)                lda    r3,X+2(r11)
   3381  1.1  mrg            extwl  r1,r3,r1                 extql  r1,r3,r1
   3382  1.1  mrg            extwh  r2,r3,r2                 extqh  r2,r3,r2
   3383  1.1  mrg            or     r1.r2.r1                 or     r1,r2,r1
   3384  1.1  mrg                                            sra    r1,48,r1
   3385  1.1  mrg 
   3386  1.1  mrg    long:   ldq_u  r1,X(r11)                ldq_u  r1,X(r11)
   3387  1.1  mrg            ldq_u  r2,X+3(r11)              ldq_u  r2,X+3(r11)
   3388  1.1  mrg            lda    r3,X(r11)                lda    r3,X(r11)
   3389  1.1  mrg            extll  r1,r3,r1                 extll  r1,r3,r1
   3390  1.1  mrg            extlh  r2,r3,r2                 extlh  r2,r3,r2
   3391  1.1  mrg            or     r1.r2.r1                 addl   r1,r2,r1
   3392  1.1  mrg 
   3393  1.1  mrg    quad:   ldq_u  r1,X(r11)
   3394  1.1  mrg            ldq_u  r2,X+7(r11)
   3395  1.1  mrg            lda    r3,X(r11)
   3396  1.1  mrg            extql  r1,r3,r1
   3397  1.1  mrg            extqh  r2,r3,r2
   3398  1.1  mrg            or     r1.r2.r1
   3399  1.1  mrg */
   3400  1.1  mrg 
   3401  1.1  mrg void
   3402  1.1  mrg alpha_expand_unaligned_load (rtx tgt, rtx mem, HOST_WIDE_INT size,
   3403  1.1  mrg 			     HOST_WIDE_INT ofs, int sign)
   3404  1.1  mrg {
   3405  1.1  mrg   rtx meml, memh, addr, extl, exth, tmp, mema;
   3406  1.1  mrg   machine_mode mode;
   3407  1.1  mrg 
   3408  1.1  mrg   if (TARGET_BWX && size == 2)
   3409  1.1  mrg     {
   3410  1.1  mrg       meml = adjust_address (mem, QImode, ofs);
   3411  1.1  mrg       memh = adjust_address (mem, QImode, ofs+1);
   3412  1.1  mrg       extl = gen_reg_rtx (DImode);
   3413  1.1  mrg       exth = gen_reg_rtx (DImode);
   3414  1.1  mrg       emit_insn (gen_zero_extendqidi2 (extl, meml));
   3415  1.1  mrg       emit_insn (gen_zero_extendqidi2 (exth, memh));
   3416  1.1  mrg       exth = expand_simple_binop (DImode, ASHIFT, exth, GEN_INT (8),
   3417  1.1  mrg 				  NULL, 1, OPTAB_LIB_WIDEN);
   3418  1.1  mrg       addr = expand_simple_binop (DImode, IOR, extl, exth,
   3419  1.1  mrg 				  NULL, 1, OPTAB_LIB_WIDEN);
   3420  1.1  mrg 
   3421  1.1  mrg       if (sign && GET_MODE (tgt) != HImode)
   3422  1.1  mrg 	{
   3423  1.1  mrg 	  addr = gen_lowpart (HImode, addr);
   3424  1.1  mrg 	  emit_insn (gen_extend_insn (tgt, addr, GET_MODE (tgt), HImode, 0));
   3425  1.1  mrg 	}
   3426  1.1  mrg       else
   3427  1.1  mrg 	{
   3428  1.1  mrg 	  if (GET_MODE (tgt) != DImode)
   3429  1.1  mrg 	    addr = gen_lowpart (GET_MODE (tgt), addr);
   3430  1.1  mrg 	  emit_move_insn (tgt, addr);
   3431  1.1  mrg 	}
   3432  1.1  mrg       return;
   3433  1.1  mrg     }
   3434  1.1  mrg 
   3435  1.1  mrg   meml = gen_reg_rtx (DImode);
   3436  1.1  mrg   memh = gen_reg_rtx (DImode);
   3437  1.1  mrg   addr = gen_reg_rtx (DImode);
   3438  1.1  mrg   extl = gen_reg_rtx (DImode);
   3439  1.1  mrg   exth = gen_reg_rtx (DImode);
   3440  1.1  mrg 
   3441  1.1  mrg   mema = XEXP (mem, 0);
   3442  1.1  mrg   if (GET_CODE (mema) == LO_SUM)
   3443  1.1  mrg     mema = force_reg (Pmode, mema);
   3444  1.1  mrg 
   3445  1.1  mrg   /* AND addresses cannot be in any alias set, since they may implicitly
   3446  1.1  mrg      alias surrounding code.  Ideally we'd have some alias set that
   3447  1.1  mrg      covered all types except those with alignment 8 or higher.  */
   3448  1.1  mrg 
   3449  1.1  mrg   tmp = change_address (mem, DImode,
   3450  1.1  mrg 			gen_rtx_AND (DImode,
   3451  1.1  mrg 				     plus_constant (DImode, mema, ofs),
   3452  1.1  mrg 				     GEN_INT (-8)));
   3453  1.1  mrg   set_mem_alias_set (tmp, 0);
   3454  1.1  mrg   emit_move_insn (meml, tmp);
   3455  1.1  mrg 
   3456  1.1  mrg   tmp = change_address (mem, DImode,
   3457  1.1  mrg 			gen_rtx_AND (DImode,
   3458  1.1  mrg 				     plus_constant (DImode, mema,
   3459  1.1  mrg 						    ofs + size - 1),
   3460  1.1  mrg 				     GEN_INT (-8)));
   3461  1.1  mrg   set_mem_alias_set (tmp, 0);
   3462  1.1  mrg   emit_move_insn (memh, tmp);
   3463  1.1  mrg 
   3464  1.1  mrg   if (sign && size == 2)
   3465  1.1  mrg     {
   3466  1.1  mrg       emit_move_insn (addr, plus_constant (Pmode, mema, ofs+2));
   3467  1.1  mrg 
   3468  1.1  mrg       emit_insn (gen_extql (extl, meml, addr));
   3469  1.1  mrg       emit_insn (gen_extqh (exth, memh, addr));
   3470  1.1  mrg 
   3471  1.1  mrg       /* We must use tgt here for the target.  Alpha-vms port fails if we use
   3472  1.1  mrg 	 addr for the target, because addr is marked as a pointer and combine
   3473  1.1  mrg 	 knows that pointers are always sign-extended 32-bit values.  */
   3474  1.1  mrg       addr = expand_binop (DImode, ior_optab, extl, exth, tgt, 1, OPTAB_WIDEN);
   3475  1.1  mrg       addr = expand_binop (DImode, ashr_optab, addr, GEN_INT (48),
   3476  1.1  mrg 			   addr, 1, OPTAB_WIDEN);
   3477  1.1  mrg     }
   3478  1.1  mrg   else
   3479  1.1  mrg     {
   3480  1.1  mrg       emit_move_insn (addr, plus_constant (Pmode, mema, ofs));
   3481  1.1  mrg       emit_insn (gen_extxl (extl, meml, GEN_INT (size*8), addr));
   3482  1.1  mrg       switch ((int) size)
   3483  1.1  mrg 	{
   3484  1.1  mrg 	case 2:
   3485  1.1  mrg 	  emit_insn (gen_extwh (exth, memh, addr));
   3486  1.1  mrg 	  mode = HImode;
   3487  1.1  mrg 	  break;
   3488  1.1  mrg 	case 4:
   3489  1.1  mrg 	  emit_insn (gen_extlh (exth, memh, addr));
   3490  1.1  mrg 	  mode = SImode;
   3491  1.1  mrg 	  break;
   3492  1.1  mrg 	case 8:
   3493  1.1  mrg 	  emit_insn (gen_extqh (exth, memh, addr));
   3494  1.1  mrg 	  mode = DImode;
   3495  1.1  mrg 	  break;
   3496  1.1  mrg 	default:
   3497  1.1  mrg 	  gcc_unreachable ();
   3498  1.1  mrg 	}
   3499  1.1  mrg 
   3500  1.1  mrg       addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl),
   3501  1.1  mrg 			   gen_lowpart (mode, exth), gen_lowpart (mode, tgt),
   3502  1.1  mrg 			   sign, OPTAB_WIDEN);
   3503  1.1  mrg     }
   3504  1.1  mrg 
   3505  1.1  mrg   if (addr != tgt)
   3506  1.1  mrg     emit_move_insn (tgt, gen_lowpart (GET_MODE (tgt), addr));
   3507  1.1  mrg }
   3508  1.1  mrg 
   3509  1.1  mrg /* Similarly, use ins and msk instructions to perform unaligned stores.  */
   3510  1.1  mrg 
   3511  1.1  mrg void
   3512  1.1  mrg alpha_expand_unaligned_store (rtx dst, rtx src,
   3513  1.1  mrg 			      HOST_WIDE_INT size, HOST_WIDE_INT ofs)
   3514  1.1  mrg {
   3515  1.1  mrg   rtx dstl, dsth, addr, insl, insh, meml, memh, dsta;
   3516  1.1  mrg 
   3517  1.1  mrg   if (TARGET_BWX && size == 2)
   3518  1.1  mrg     {
   3519  1.1  mrg       if (src != const0_rtx)
   3520  1.1  mrg 	{
   3521  1.1  mrg 	  dstl = gen_lowpart (QImode, src);
   3522  1.1  mrg 	  dsth = expand_simple_binop (DImode, LSHIFTRT, src, GEN_INT (8),
   3523  1.1  mrg 				      NULL, 1, OPTAB_LIB_WIDEN);
   3524  1.1  mrg 	  dsth = gen_lowpart (QImode, dsth);
   3525  1.1  mrg 	}
   3526  1.1  mrg       else
   3527  1.1  mrg 	dstl = dsth = const0_rtx;
   3528  1.1  mrg 
   3529  1.1  mrg       meml = adjust_address (dst, QImode, ofs);
   3530  1.1  mrg       memh = adjust_address (dst, QImode, ofs+1);
   3531  1.1  mrg 
   3532  1.1  mrg       emit_move_insn (meml, dstl);
   3533  1.1  mrg       emit_move_insn (memh, dsth);
   3534  1.1  mrg       return;
   3535  1.1  mrg     }
   3536  1.1  mrg 
   3537  1.1  mrg   dstl = gen_reg_rtx (DImode);
   3538  1.1  mrg   dsth = gen_reg_rtx (DImode);
   3539  1.1  mrg   insl = gen_reg_rtx (DImode);
   3540  1.1  mrg   insh = gen_reg_rtx (DImode);
   3541  1.1  mrg 
   3542  1.1  mrg   dsta = XEXP (dst, 0);
   3543  1.1  mrg   if (GET_CODE (dsta) == LO_SUM)
   3544  1.1  mrg     dsta = force_reg (Pmode, dsta);
   3545  1.1  mrg 
   3546  1.1  mrg   /* AND addresses cannot be in any alias set, since they may implicitly
   3547  1.1  mrg      alias surrounding code.  Ideally we'd have some alias set that
   3548  1.1  mrg      covered all types except those with alignment 8 or higher.  */
   3549  1.1  mrg 
   3550  1.1  mrg   meml = change_address (dst, DImode,
   3551  1.1  mrg 			 gen_rtx_AND (DImode,
   3552  1.1  mrg 				      plus_constant (DImode, dsta, ofs),
   3553  1.1  mrg 				      GEN_INT (-8)));
   3554  1.1  mrg   set_mem_alias_set (meml, 0);
   3555  1.1  mrg 
   3556  1.1  mrg   memh = change_address (dst, DImode,
   3557  1.1  mrg 			 gen_rtx_AND (DImode,
   3558  1.1  mrg 				      plus_constant (DImode, dsta,
   3559  1.1  mrg 						     ofs + size - 1),
   3560  1.1  mrg 				      GEN_INT (-8)));
   3561  1.1  mrg   set_mem_alias_set (memh, 0);
   3562  1.1  mrg 
   3563  1.1  mrg   emit_move_insn (dsth, memh);
   3564  1.1  mrg   emit_move_insn (dstl, meml);
   3565  1.1  mrg 
   3566  1.1  mrg   addr = copy_addr_to_reg (plus_constant (Pmode, dsta, ofs));
   3567  1.1  mrg 
   3568  1.1  mrg   if (src != CONST0_RTX (GET_MODE (src)))
   3569  1.1  mrg     {
   3570  1.1  mrg       emit_insn (gen_insxh (insh, gen_lowpart (DImode, src),
   3571  1.1  mrg 			    GEN_INT (size*8), addr));
   3572  1.1  mrg 
   3573  1.1  mrg       switch ((int) size)
   3574  1.1  mrg 	{
   3575  1.1  mrg 	case 2:
   3576  1.1  mrg 	  emit_insn (gen_inswl (insl, gen_lowpart (HImode, src), addr));
   3577  1.1  mrg 	  break;
   3578  1.1  mrg 	case 4:
   3579  1.1  mrg 	  emit_insn (gen_insll (insl, gen_lowpart (SImode, src), addr));
   3580  1.1  mrg 	  break;
   3581  1.1  mrg 	case 8:
   3582  1.1  mrg 	  emit_insn (gen_insql (insl, gen_lowpart (DImode, src), addr));
   3583  1.1  mrg 	  break;
   3584  1.1  mrg 	default:
   3585  1.1  mrg 	  gcc_unreachable ();
   3586  1.1  mrg 	}
   3587  1.1  mrg     }
   3588  1.1  mrg 
   3589  1.1  mrg   emit_insn (gen_mskxh (dsth, dsth, GEN_INT (size*8), addr));
   3590  1.1  mrg 
   3591  1.1  mrg   switch ((int) size)
   3592  1.1  mrg     {
   3593  1.1  mrg     case 2:
   3594  1.1  mrg       emit_insn (gen_mskwl (dstl, dstl, addr));
   3595  1.1  mrg       break;
   3596  1.1  mrg     case 4:
   3597  1.1  mrg       emit_insn (gen_mskll (dstl, dstl, addr));
   3598  1.1  mrg       break;
   3599  1.1  mrg     case 8:
   3600  1.1  mrg       emit_insn (gen_mskql (dstl, dstl, addr));
   3601  1.1  mrg       break;
   3602  1.1  mrg     default:
   3603  1.1  mrg       gcc_unreachable ();
   3604  1.1  mrg     }
   3605  1.1  mrg 
   3606  1.1  mrg   if (src != CONST0_RTX (GET_MODE (src)))
   3607  1.1  mrg     {
   3608  1.1  mrg       dsth = expand_binop (DImode, ior_optab, insh, dsth, dsth, 0, OPTAB_WIDEN);
   3609  1.1  mrg       dstl = expand_binop (DImode, ior_optab, insl, dstl, dstl, 0, OPTAB_WIDEN);
   3610  1.1  mrg     }
   3611  1.1  mrg 
   3612  1.1  mrg   /* Must store high before low for degenerate case of aligned.  */
   3613  1.1  mrg   emit_move_insn (memh, dsth);
   3614  1.1  mrg   emit_move_insn (meml, dstl);
   3615  1.1  mrg }
   3616  1.1  mrg 
   3617  1.1  mrg /* The block move code tries to maximize speed by separating loads and
   3618  1.1  mrg    stores at the expense of register pressure: we load all of the data
   3619  1.1  mrg    before we store it back out.  There are two secondary effects worth
   3620  1.1  mrg    mentioning, that this speeds copying to/from aligned and unaligned
   3621  1.1  mrg    buffers, and that it makes the code significantly easier to write.  */
   3622  1.1  mrg 
   3623  1.1  mrg #define MAX_MOVE_WORDS	8
   3624  1.1  mrg 
   3625  1.1  mrg /* Load an integral number of consecutive unaligned quadwords.  */
   3626  1.1  mrg 
   3627  1.1  mrg static void
   3628  1.1  mrg alpha_expand_unaligned_load_words (rtx *out_regs, rtx smem,
   3629  1.1  mrg 				   HOST_WIDE_INT words, HOST_WIDE_INT ofs)
   3630  1.1  mrg {
   3631  1.1  mrg   rtx const im8 = GEN_INT (-8);
   3632  1.1  mrg   rtx ext_tmps[MAX_MOVE_WORDS], data_regs[MAX_MOVE_WORDS+1];
   3633  1.1  mrg   rtx sreg, areg, tmp, smema;
   3634  1.1  mrg   HOST_WIDE_INT i;
   3635  1.1  mrg 
   3636  1.1  mrg   smema = XEXP (smem, 0);
   3637  1.1  mrg   if (GET_CODE (smema) == LO_SUM)
   3638  1.1  mrg     smema = force_reg (Pmode, smema);
   3639  1.1  mrg 
   3640  1.1  mrg   /* Generate all the tmp registers we need.  */
   3641  1.1  mrg   for (i = 0; i < words; ++i)
   3642  1.1  mrg     {
   3643  1.1  mrg       data_regs[i] = out_regs[i];
   3644  1.1  mrg       ext_tmps[i] = gen_reg_rtx (DImode);
   3645  1.1  mrg     }
   3646  1.1  mrg   data_regs[words] = gen_reg_rtx (DImode);
   3647  1.1  mrg 
   3648  1.1  mrg   if (ofs != 0)
   3649  1.1  mrg     smem = adjust_address (smem, GET_MODE (smem), ofs);
   3650  1.1  mrg 
   3651  1.1  mrg   /* Load up all of the source data.  */
   3652  1.1  mrg   for (i = 0; i < words; ++i)
   3653  1.1  mrg     {
   3654  1.1  mrg       tmp = change_address (smem, DImode,
   3655  1.1  mrg 			    gen_rtx_AND (DImode,
   3656  1.1  mrg 					 plus_constant (DImode, smema, 8*i),
   3657  1.1  mrg 					 im8));
   3658  1.1  mrg       set_mem_alias_set (tmp, 0);
   3659  1.1  mrg       emit_move_insn (data_regs[i], tmp);
   3660  1.1  mrg     }
   3661  1.1  mrg 
   3662  1.1  mrg   tmp = change_address (smem, DImode,
   3663  1.1  mrg 			gen_rtx_AND (DImode,
   3664  1.1  mrg 				     plus_constant (DImode, smema,
   3665  1.1  mrg 						    8*words - 1),
   3666  1.1  mrg 				     im8));
   3667  1.1  mrg   set_mem_alias_set (tmp, 0);
   3668  1.1  mrg   emit_move_insn (data_regs[words], tmp);
   3669  1.1  mrg 
   3670  1.1  mrg   /* Extract the half-word fragments.  Unfortunately DEC decided to make
   3671  1.1  mrg      extxh with offset zero a noop instead of zeroing the register, so
   3672  1.1  mrg      we must take care of that edge condition ourselves with cmov.  */
   3673  1.1  mrg 
   3674  1.1  mrg   sreg = copy_addr_to_reg (smema);
   3675  1.1  mrg   areg = expand_binop (DImode, and_optab, sreg, GEN_INT (7), NULL,
   3676  1.1  mrg 		       1, OPTAB_WIDEN);
   3677  1.1  mrg   for (i = 0; i < words; ++i)
   3678  1.1  mrg     {
   3679  1.1  mrg       emit_insn (gen_extql (data_regs[i], data_regs[i], sreg));
   3680  1.1  mrg       emit_insn (gen_extqh (ext_tmps[i], data_regs[i+1], sreg));
   3681  1.1  mrg       emit_insn (gen_rtx_SET (ext_tmps[i],
   3682  1.1  mrg 			      gen_rtx_IF_THEN_ELSE (DImode,
   3683  1.1  mrg 						    gen_rtx_EQ (DImode, areg,
   3684  1.1  mrg 								const0_rtx),
   3685  1.1  mrg 						    const0_rtx, ext_tmps[i])));
   3686  1.1  mrg     }
   3687  1.1  mrg 
   3688  1.1  mrg   /* Merge the half-words into whole words.  */
   3689  1.1  mrg   for (i = 0; i < words; ++i)
   3690  1.1  mrg     {
   3691  1.1  mrg       out_regs[i] = expand_binop (DImode, ior_optab, data_regs[i],
   3692  1.1  mrg 				  ext_tmps[i], data_regs[i], 1, OPTAB_WIDEN);
   3693  1.1  mrg     }
   3694  1.1  mrg }
   3695  1.1  mrg 
   3696  1.1  mrg /* Store an integral number of consecutive unaligned quadwords.  DATA_REGS
   3697  1.1  mrg    may be NULL to store zeros.  */
   3698  1.1  mrg 
   3699  1.1  mrg static void
   3700  1.1  mrg alpha_expand_unaligned_store_words (rtx *data_regs, rtx dmem,
   3701  1.1  mrg 				    HOST_WIDE_INT words, HOST_WIDE_INT ofs)
   3702  1.1  mrg {
   3703  1.1  mrg   rtx const im8 = GEN_INT (-8);
   3704  1.1  mrg   rtx ins_tmps[MAX_MOVE_WORDS];
   3705  1.1  mrg   rtx st_tmp_1, st_tmp_2, dreg;
   3706  1.1  mrg   rtx st_addr_1, st_addr_2, dmema;
   3707  1.1  mrg   HOST_WIDE_INT i;
   3708  1.1  mrg 
   3709  1.1  mrg   dmema = XEXP (dmem, 0);
   3710  1.1  mrg   if (GET_CODE (dmema) == LO_SUM)
   3711  1.1  mrg     dmema = force_reg (Pmode, dmema);
   3712  1.1  mrg 
   3713  1.1  mrg   /* Generate all the tmp registers we need.  */
   3714  1.1  mrg   if (data_regs != NULL)
   3715  1.1  mrg     for (i = 0; i < words; ++i)
   3716  1.1  mrg       ins_tmps[i] = gen_reg_rtx(DImode);
   3717  1.1  mrg   st_tmp_1 = gen_reg_rtx(DImode);
   3718  1.1  mrg   st_tmp_2 = gen_reg_rtx(DImode);
   3719  1.1  mrg 
   3720  1.1  mrg   if (ofs != 0)
   3721  1.1  mrg     dmem = adjust_address (dmem, GET_MODE (dmem), ofs);
   3722  1.1  mrg 
   3723  1.1  mrg   st_addr_2 = change_address (dmem, DImode,
   3724  1.1  mrg 			      gen_rtx_AND (DImode,
   3725  1.1  mrg 					   plus_constant (DImode, dmema,
   3726  1.1  mrg 							  words*8 - 1),
   3727  1.1  mrg 					   im8));
   3728  1.1  mrg   set_mem_alias_set (st_addr_2, 0);
   3729  1.1  mrg 
   3730  1.1  mrg   st_addr_1 = change_address (dmem, DImode,
   3731  1.1  mrg 			      gen_rtx_AND (DImode, dmema, im8));
   3732  1.1  mrg   set_mem_alias_set (st_addr_1, 0);
   3733  1.1  mrg 
   3734  1.1  mrg   /* Load up the destination end bits.  */
   3735  1.1  mrg   emit_move_insn (st_tmp_2, st_addr_2);
   3736  1.1  mrg   emit_move_insn (st_tmp_1, st_addr_1);
   3737  1.1  mrg 
   3738  1.1  mrg   /* Shift the input data into place.  */
   3739  1.1  mrg   dreg = copy_addr_to_reg (dmema);
   3740  1.1  mrg   if (data_regs != NULL)
   3741  1.1  mrg     {
   3742  1.1  mrg       for (i = words-1; i >= 0; --i)
   3743  1.1  mrg 	{
   3744  1.1  mrg 	  emit_insn (gen_insqh (ins_tmps[i], data_regs[i], dreg));
   3745  1.1  mrg 	  emit_insn (gen_insql (data_regs[i], data_regs[i], dreg));
   3746  1.1  mrg 	}
   3747  1.1  mrg       for (i = words-1; i > 0; --i)
   3748  1.1  mrg 	{
   3749  1.1  mrg 	  ins_tmps[i-1] = expand_binop (DImode, ior_optab, data_regs[i],
   3750  1.1  mrg 					ins_tmps[i-1], ins_tmps[i-1], 1,
   3751  1.1  mrg 					OPTAB_WIDEN);
   3752  1.1  mrg 	}
   3753  1.1  mrg     }
   3754  1.1  mrg 
   3755  1.1  mrg   /* Split and merge the ends with the destination data.  */
   3756  1.1  mrg   emit_insn (gen_mskqh (st_tmp_2, st_tmp_2, dreg));
   3757  1.1  mrg   emit_insn (gen_mskql (st_tmp_1, st_tmp_1, dreg));
   3758  1.1  mrg 
   3759  1.1  mrg   if (data_regs != NULL)
   3760  1.1  mrg     {
   3761  1.1  mrg       st_tmp_2 = expand_binop (DImode, ior_optab, st_tmp_2, ins_tmps[words-1],
   3762  1.1  mrg 			       st_tmp_2, 1, OPTAB_WIDEN);
   3763  1.1  mrg       st_tmp_1 = expand_binop (DImode, ior_optab, st_tmp_1, data_regs[0],
   3764  1.1  mrg 			       st_tmp_1, 1, OPTAB_WIDEN);
   3765  1.1  mrg     }
   3766  1.1  mrg 
   3767  1.1  mrg   /* Store it all.  */
   3768  1.1  mrg   emit_move_insn (st_addr_2, st_tmp_2);
   3769  1.1  mrg   for (i = words-1; i > 0; --i)
   3770  1.1  mrg     {
   3771  1.1  mrg       rtx tmp = change_address (dmem, DImode,
   3772  1.1  mrg 				gen_rtx_AND (DImode,
   3773  1.1  mrg 					     plus_constant (DImode,
   3774  1.1  mrg 							    dmema, i*8),
   3775  1.1  mrg 					     im8));
   3776  1.1  mrg       set_mem_alias_set (tmp, 0);
   3777  1.1  mrg       emit_move_insn (tmp, data_regs ? ins_tmps[i-1] : const0_rtx);
   3778  1.1  mrg     }
   3779  1.1  mrg   emit_move_insn (st_addr_1, st_tmp_1);
   3780  1.1  mrg }
   3781  1.1  mrg 
   3782  1.1  mrg 
   3783  1.1  mrg /* Expand string/block move operations.
   3784  1.1  mrg 
   3785  1.1  mrg    operands[0] is the pointer to the destination.
   3786  1.1  mrg    operands[1] is the pointer to the source.
   3787  1.1  mrg    operands[2] is the number of bytes to move.
   3788  1.1  mrg    operands[3] is the alignment.  */
   3789  1.1  mrg 
   3790  1.1  mrg int
   3791  1.1  mrg alpha_expand_block_move (rtx operands[])
   3792  1.1  mrg {
   3793  1.1  mrg   rtx bytes_rtx	= operands[2];
   3794  1.1  mrg   rtx align_rtx = operands[3];
   3795  1.1  mrg   HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
   3796  1.1  mrg   HOST_WIDE_INT bytes = orig_bytes;
   3797  1.1  mrg   HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
   3798  1.1  mrg   HOST_WIDE_INT dst_align = src_align;
   3799  1.1  mrg   rtx orig_src = operands[1];
   3800  1.1  mrg   rtx orig_dst = operands[0];
   3801  1.1  mrg   rtx data_regs[2 * MAX_MOVE_WORDS + 16];
   3802  1.1  mrg   rtx tmp;
   3803  1.1  mrg   unsigned int i, words, ofs, nregs = 0;
   3804  1.1  mrg 
   3805  1.1  mrg   if (orig_bytes <= 0)
   3806  1.1  mrg     return 1;
   3807  1.1  mrg   else if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
   3808  1.1  mrg     return 0;
   3809  1.1  mrg 
   3810  1.1  mrg   /* Look for additional alignment information from recorded register info.  */
   3811  1.1  mrg 
   3812  1.1  mrg   tmp = XEXP (orig_src, 0);
   3813  1.1  mrg   if (REG_P (tmp))
   3814  1.1  mrg     src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
   3815  1.1  mrg   else if (GET_CODE (tmp) == PLUS
   3816  1.1  mrg 	   && REG_P (XEXP (tmp, 0))
   3817  1.1  mrg 	   && CONST_INT_P (XEXP (tmp, 1)))
   3818  1.1  mrg     {
   3819  1.1  mrg       unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
   3820  1.1  mrg       unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
   3821  1.1  mrg 
   3822  1.1  mrg       if (a > src_align)
   3823  1.1  mrg 	{
   3824  1.1  mrg           if (a >= 64 && c % 8 == 0)
   3825  1.1  mrg 	    src_align = 64;
   3826  1.1  mrg           else if (a >= 32 && c % 4 == 0)
   3827  1.1  mrg 	    src_align = 32;
   3828  1.1  mrg           else if (a >= 16 && c % 2 == 0)
   3829  1.1  mrg 	    src_align = 16;
   3830  1.1  mrg 	}
   3831  1.1  mrg     }
   3832  1.1  mrg 
   3833  1.1  mrg   tmp = XEXP (orig_dst, 0);
   3834  1.1  mrg   if (REG_P (tmp))
   3835  1.1  mrg     dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
   3836  1.1  mrg   else if (GET_CODE (tmp) == PLUS
   3837  1.1  mrg 	   && REG_P (XEXP (tmp, 0))
   3838  1.1  mrg 	   && CONST_INT_P (XEXP (tmp, 1)))
   3839  1.1  mrg     {
   3840  1.1  mrg       unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
   3841  1.1  mrg       unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
   3842  1.1  mrg 
   3843  1.1  mrg       if (a > dst_align)
   3844  1.1  mrg 	{
   3845  1.1  mrg           if (a >= 64 && c % 8 == 0)
   3846  1.1  mrg 	    dst_align = 64;
   3847  1.1  mrg           else if (a >= 32 && c % 4 == 0)
   3848  1.1  mrg 	    dst_align = 32;
   3849  1.1  mrg           else if (a >= 16 && c % 2 == 0)
   3850  1.1  mrg 	    dst_align = 16;
   3851  1.1  mrg 	}
   3852  1.1  mrg     }
   3853  1.1  mrg 
   3854  1.1  mrg   ofs = 0;
   3855  1.1  mrg   if (src_align >= 64 && bytes >= 8)
   3856  1.1  mrg     {
   3857  1.1  mrg       words = bytes / 8;
   3858  1.1  mrg 
   3859  1.1  mrg       for (i = 0; i < words; ++i)
   3860  1.1  mrg 	data_regs[nregs + i] = gen_reg_rtx (DImode);
   3861  1.1  mrg 
   3862  1.1  mrg       for (i = 0; i < words; ++i)
   3863  1.1  mrg 	emit_move_insn (data_regs[nregs + i],
   3864  1.1  mrg 			adjust_address (orig_src, DImode, ofs + i * 8));
   3865  1.1  mrg 
   3866  1.1  mrg       nregs += words;
   3867  1.1  mrg       bytes -= words * 8;
   3868  1.1  mrg       ofs += words * 8;
   3869  1.1  mrg     }
   3870  1.1  mrg 
   3871  1.1  mrg   if (src_align >= 32 && bytes >= 4)
   3872  1.1  mrg     {
   3873  1.1  mrg       words = bytes / 4;
   3874  1.1  mrg 
   3875  1.1  mrg       for (i = 0; i < words; ++i)
   3876  1.1  mrg 	data_regs[nregs + i] = gen_reg_rtx (SImode);
   3877  1.1  mrg 
   3878  1.1  mrg       for (i = 0; i < words; ++i)
   3879  1.1  mrg 	emit_move_insn (data_regs[nregs + i],
   3880  1.1  mrg 			adjust_address (orig_src, SImode, ofs + i * 4));
   3881  1.1  mrg 
   3882  1.1  mrg       nregs += words;
   3883  1.1  mrg       bytes -= words * 4;
   3884  1.1  mrg       ofs += words * 4;
   3885  1.1  mrg     }
   3886  1.1  mrg 
   3887  1.1  mrg   if (bytes >= 8)
   3888  1.1  mrg     {
   3889  1.1  mrg       words = bytes / 8;
   3890  1.1  mrg 
   3891  1.1  mrg       for (i = 0; i < words+1; ++i)
   3892  1.1  mrg 	data_regs[nregs + i] = gen_reg_rtx (DImode);
   3893  1.1  mrg 
   3894  1.1  mrg       alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
   3895  1.1  mrg 					 words, ofs);
   3896  1.1  mrg 
   3897  1.1  mrg       nregs += words;
   3898  1.1  mrg       bytes -= words * 8;
   3899  1.1  mrg       ofs += words * 8;
   3900  1.1  mrg     }
   3901  1.1  mrg 
   3902  1.1  mrg   if (! TARGET_BWX && bytes >= 4)
   3903  1.1  mrg     {
   3904  1.1  mrg       data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
   3905  1.1  mrg       alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
   3906  1.1  mrg       bytes -= 4;
   3907  1.1  mrg       ofs += 4;
   3908  1.1  mrg     }
   3909  1.1  mrg 
   3910  1.1  mrg   if (bytes >= 2)
   3911  1.1  mrg     {
   3912  1.1  mrg       if (src_align >= 16)
   3913  1.1  mrg 	{
   3914  1.1  mrg 	  do {
   3915  1.1  mrg 	    data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
   3916  1.1  mrg 	    emit_move_insn (tmp, adjust_address (orig_src, HImode, ofs));
   3917  1.1  mrg 	    bytes -= 2;
   3918  1.1  mrg 	    ofs += 2;
   3919  1.1  mrg 	  } while (bytes >= 2);
   3920  1.1  mrg 	}
   3921  1.1  mrg       else if (! TARGET_BWX)
   3922  1.1  mrg 	{
   3923  1.1  mrg 	  data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
   3924  1.1  mrg 	  alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
   3925  1.1  mrg 	  bytes -= 2;
   3926  1.1  mrg 	  ofs += 2;
   3927  1.1  mrg 	}
   3928  1.1  mrg     }
   3929  1.1  mrg 
   3930  1.1  mrg   while (bytes > 0)
   3931  1.1  mrg     {
   3932  1.1  mrg       data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
   3933  1.1  mrg       emit_move_insn (tmp, adjust_address (orig_src, QImode, ofs));
   3934  1.1  mrg       bytes -= 1;
   3935  1.1  mrg       ofs += 1;
   3936  1.1  mrg     }
   3937  1.1  mrg 
   3938  1.1  mrg   gcc_assert (nregs <= ARRAY_SIZE (data_regs));
   3939  1.1  mrg 
   3940  1.1  mrg   /* Now save it back out again.  */
   3941  1.1  mrg 
   3942  1.1  mrg   i = 0, ofs = 0;
   3943  1.1  mrg 
   3944  1.1  mrg   /* Write out the data in whatever chunks reading the source allowed.  */
   3945  1.1  mrg   if (dst_align >= 64)
   3946  1.1  mrg     {
   3947  1.1  mrg       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
   3948  1.1  mrg 	{
   3949  1.1  mrg 	  emit_move_insn (adjust_address (orig_dst, DImode, ofs),
   3950  1.1  mrg 			  data_regs[i]);
   3951  1.1  mrg 	  ofs += 8;
   3952  1.1  mrg 	  i++;
   3953  1.1  mrg 	}
   3954  1.1  mrg     }
   3955  1.1  mrg 
   3956  1.1  mrg   if (dst_align >= 32)
   3957  1.1  mrg     {
   3958  1.1  mrg       /* If the source has remaining DImode regs, write them out in
   3959  1.1  mrg 	 two pieces.  */
   3960  1.1  mrg       while (i < nregs && GET_MODE (data_regs[i]) == DImode)
   3961  1.1  mrg 	{
   3962  1.1  mrg 	  tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32),
   3963  1.1  mrg 			      NULL_RTX, 1, OPTAB_WIDEN);
   3964  1.1  mrg 
   3965  1.1  mrg 	  emit_move_insn (adjust_address (orig_dst, SImode, ofs),
   3966  1.1  mrg 			  gen_lowpart (SImode, data_regs[i]));
   3967  1.1  mrg 	  emit_move_insn (adjust_address (orig_dst, SImode, ofs + 4),
   3968  1.1  mrg 			  gen_lowpart (SImode, tmp));
   3969  1.1  mrg 	  ofs += 8;
   3970  1.1  mrg 	  i++;
   3971  1.1  mrg 	}
   3972  1.1  mrg 
   3973  1.1  mrg       while (i < nregs && GET_MODE (data_regs[i]) == SImode)
   3974  1.1  mrg 	{
   3975  1.1  mrg 	  emit_move_insn (adjust_address (orig_dst, SImode, ofs),
   3976  1.1  mrg 			  data_regs[i]);
   3977  1.1  mrg 	  ofs += 4;
   3978  1.1  mrg 	  i++;
   3979  1.1  mrg 	}
   3980  1.1  mrg     }
   3981  1.1  mrg 
   3982  1.1  mrg   if (i < nregs && GET_MODE (data_regs[i]) == DImode)
   3983  1.1  mrg     {
   3984  1.1  mrg       /* Write out a remaining block of words using unaligned methods.  */
   3985  1.1  mrg 
   3986  1.1  mrg       for (words = 1; i + words < nregs; words++)
   3987  1.1  mrg 	if (GET_MODE (data_regs[i + words]) != DImode)
   3988  1.1  mrg 	  break;
   3989  1.1  mrg 
   3990  1.1  mrg       if (words == 1)
   3991  1.1  mrg 	alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
   3992  1.1  mrg       else
   3993  1.1  mrg         alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
   3994  1.1  mrg 					    words, ofs);
   3995  1.1  mrg 
   3996  1.1  mrg       i += words;
   3997  1.1  mrg       ofs += words * 8;
   3998  1.1  mrg     }
   3999  1.1  mrg 
   4000  1.1  mrg   /* Due to the above, this won't be aligned.  */
   4001  1.1  mrg   /* ??? If we have more than one of these, consider constructing full
   4002  1.1  mrg      words in registers and using alpha_expand_unaligned_store_words.  */
   4003  1.1  mrg   while (i < nregs && GET_MODE (data_regs[i]) == SImode)
   4004  1.1  mrg     {
   4005  1.1  mrg       alpha_expand_unaligned_store (orig_dst, data_regs[i], 4, ofs);
   4006  1.1  mrg       ofs += 4;
   4007  1.1  mrg       i++;
   4008  1.1  mrg     }
   4009  1.1  mrg 
   4010  1.1  mrg   if (dst_align >= 16)
   4011  1.1  mrg     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
   4012  1.1  mrg       {
   4013  1.1  mrg 	emit_move_insn (adjust_address (orig_dst, HImode, ofs), data_regs[i]);
   4014  1.1  mrg 	i++;
   4015  1.1  mrg 	ofs += 2;
   4016  1.1  mrg       }
   4017  1.1  mrg   else
   4018  1.1  mrg     while (i < nregs && GET_MODE (data_regs[i]) == HImode)
   4019  1.1  mrg       {
   4020  1.1  mrg 	alpha_expand_unaligned_store (orig_dst, data_regs[i], 2, ofs);
   4021  1.1  mrg 	i++;
   4022  1.1  mrg 	ofs += 2;
   4023  1.1  mrg       }
   4024  1.1  mrg 
   4025  1.1  mrg   /* The remainder must be byte copies.  */
   4026  1.1  mrg   while (i < nregs)
   4027  1.1  mrg     {
   4028  1.1  mrg       gcc_assert (GET_MODE (data_regs[i]) == QImode);
   4029  1.1  mrg       emit_move_insn (adjust_address (orig_dst, QImode, ofs), data_regs[i]);
   4030  1.1  mrg       i++;
   4031  1.1  mrg       ofs += 1;
   4032  1.1  mrg     }
   4033  1.1  mrg 
   4034  1.1  mrg   return 1;
   4035  1.1  mrg }
   4036  1.1  mrg 
   4037  1.1  mrg int
   4038  1.1  mrg alpha_expand_block_clear (rtx operands[])
   4039  1.1  mrg {
   4040  1.1  mrg   rtx bytes_rtx	= operands[1];
   4041  1.1  mrg   rtx align_rtx = operands[3];
   4042  1.1  mrg   HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
   4043  1.1  mrg   HOST_WIDE_INT bytes = orig_bytes;
   4044  1.1  mrg   HOST_WIDE_INT align = INTVAL (align_rtx) * BITS_PER_UNIT;
   4045  1.1  mrg   HOST_WIDE_INT alignofs = 0;
   4046  1.1  mrg   rtx orig_dst = operands[0];
   4047  1.1  mrg   rtx tmp;
   4048  1.1  mrg   int i, words, ofs = 0;
   4049  1.1  mrg 
   4050  1.1  mrg   if (orig_bytes <= 0)
   4051  1.1  mrg     return 1;
   4052  1.1  mrg   if (orig_bytes > MAX_MOVE_WORDS * UNITS_PER_WORD)
   4053  1.1  mrg     return 0;
   4054  1.1  mrg 
   4055  1.1  mrg   /* Look for stricter alignment.  */
   4056  1.1  mrg   tmp = XEXP (orig_dst, 0);
   4057  1.1  mrg   if (REG_P (tmp))
   4058  1.1  mrg     align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
   4059  1.1  mrg   else if (GET_CODE (tmp) == PLUS
   4060  1.1  mrg 	   && REG_P (XEXP (tmp, 0))
   4061  1.1  mrg 	   && CONST_INT_P (XEXP (tmp, 1)))
   4062  1.1  mrg     {
   4063  1.1  mrg       HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
   4064  1.1  mrg       int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
   4065  1.1  mrg 
   4066  1.1  mrg       if (a > align)
   4067  1.1  mrg 	{
   4068  1.1  mrg           if (a >= 64)
   4069  1.1  mrg 	    align = a, alignofs = 8 - c % 8;
   4070  1.1  mrg           else if (a >= 32)
   4071  1.1  mrg 	    align = a, alignofs = 4 - c % 4;
   4072  1.1  mrg           else if (a >= 16)
   4073  1.1  mrg 	    align = a, alignofs = 2 - c % 2;
   4074  1.1  mrg 	}
   4075  1.1  mrg     }
   4076  1.1  mrg 
   4077  1.1  mrg   /* Handle an unaligned prefix first.  */
   4078  1.1  mrg 
   4079  1.1  mrg   if (alignofs > 0)
   4080  1.1  mrg     {
   4081  1.1  mrg       /* Given that alignofs is bounded by align, the only time BWX could
   4082  1.1  mrg 	 generate three stores is for a 7 byte fill.  Prefer two individual
   4083  1.1  mrg 	 stores over a load/mask/store sequence.  */
   4084  1.1  mrg       if ((!TARGET_BWX || alignofs == 7)
   4085  1.1  mrg 	       && align >= 32
   4086  1.1  mrg 	       && !(alignofs == 4 && bytes >= 4))
   4087  1.1  mrg 	{
   4088  1.1  mrg 	  machine_mode mode = (align >= 64 ? DImode : SImode);
   4089  1.1  mrg 	  int inv_alignofs = (align >= 64 ? 8 : 4) - alignofs;
   4090  1.1  mrg 	  rtx mem, tmp;
   4091  1.1  mrg 	  HOST_WIDE_INT mask;
   4092  1.1  mrg 
   4093  1.1  mrg 	  mem = adjust_address (orig_dst, mode, ofs - inv_alignofs);
   4094  1.1  mrg 	  set_mem_alias_set (mem, 0);
   4095  1.1  mrg 
   4096  1.1  mrg 	  mask = ~(HOST_WIDE_INT_M1U << (inv_alignofs * 8));
   4097  1.1  mrg 	  if (bytes < alignofs)
   4098  1.1  mrg 	    {
   4099  1.1  mrg 	      mask |= HOST_WIDE_INT_M1U << ((inv_alignofs + bytes) * 8);
   4100  1.1  mrg 	      ofs += bytes;
   4101  1.1  mrg 	      bytes = 0;
   4102  1.1  mrg 	    }
   4103  1.1  mrg 	  else
   4104  1.1  mrg 	    {
   4105  1.1  mrg 	      bytes -= alignofs;
   4106  1.1  mrg 	      ofs += alignofs;
   4107  1.1  mrg 	    }
   4108  1.1  mrg 	  alignofs = 0;
   4109  1.1  mrg 
   4110  1.1  mrg 	  tmp = expand_binop (mode, and_optab, mem, GEN_INT (mask),
   4111  1.1  mrg 			      NULL_RTX, 1, OPTAB_WIDEN);
   4112  1.1  mrg 
   4113  1.1  mrg 	  emit_move_insn (mem, tmp);
   4114  1.1  mrg 	}
   4115  1.1  mrg 
   4116  1.1  mrg       if (TARGET_BWX && (alignofs & 1) && bytes >= 1)
   4117  1.1  mrg 	{
   4118  1.1  mrg 	  emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
   4119  1.1  mrg 	  bytes -= 1;
   4120  1.1  mrg 	  ofs += 1;
   4121  1.1  mrg 	  alignofs -= 1;
   4122  1.1  mrg 	}
   4123  1.1  mrg       if (TARGET_BWX && align >= 16 && (alignofs & 3) == 2 && bytes >= 2)
   4124  1.1  mrg 	{
   4125  1.1  mrg 	  emit_move_insn (adjust_address (orig_dst, HImode, ofs), const0_rtx);
   4126  1.1  mrg 	  bytes -= 2;
   4127  1.1  mrg 	  ofs += 2;
   4128  1.1  mrg 	  alignofs -= 2;
   4129  1.1  mrg 	}
   4130  1.1  mrg       if (alignofs == 4 && bytes >= 4)
   4131  1.1  mrg 	{
   4132  1.1  mrg 	  emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
   4133  1.1  mrg 	  bytes -= 4;
   4134  1.1  mrg 	  ofs += 4;
   4135  1.1  mrg 	  alignofs = 0;
   4136  1.1  mrg 	}
   4137  1.1  mrg 
   4138  1.1  mrg       /* If we've not used the extra lead alignment information by now,
   4139  1.1  mrg 	 we won't be able to.  Downgrade align to match what's left over.  */
   4140  1.1  mrg       if (alignofs > 0)
   4141  1.1  mrg 	{
   4142  1.1  mrg 	  alignofs = alignofs & -alignofs;
   4143  1.1  mrg 	  align = MIN (align, alignofs * BITS_PER_UNIT);
   4144  1.1  mrg 	}
   4145  1.1  mrg     }
   4146  1.1  mrg 
   4147  1.1  mrg   /* Handle a block of contiguous long-words.  */
   4148  1.1  mrg 
   4149  1.1  mrg   if (align >= 64 && bytes >= 8)
   4150  1.1  mrg     {
   4151  1.1  mrg       words = bytes / 8;
   4152  1.1  mrg 
   4153  1.1  mrg       for (i = 0; i < words; ++i)
   4154  1.1  mrg 	emit_move_insn (adjust_address (orig_dst, DImode, ofs + i * 8),
   4155  1.1  mrg 			const0_rtx);
   4156  1.1  mrg 
   4157  1.1  mrg       bytes -= words * 8;
   4158  1.1  mrg       ofs += words * 8;
   4159  1.1  mrg     }
   4160  1.1  mrg 
   4161  1.1  mrg   /* If the block is large and appropriately aligned, emit a single
   4162  1.1  mrg      store followed by a sequence of stq_u insns.  */
   4163  1.1  mrg 
   4164  1.1  mrg   if (align >= 32 && bytes > 16)
   4165  1.1  mrg     {
   4166  1.1  mrg       rtx orig_dsta;
   4167  1.1  mrg 
   4168  1.1  mrg       emit_move_insn (adjust_address (orig_dst, SImode, ofs), const0_rtx);
   4169  1.1  mrg       bytes -= 4;
   4170  1.1  mrg       ofs += 4;
   4171  1.1  mrg 
   4172  1.1  mrg       orig_dsta = XEXP (orig_dst, 0);
   4173  1.1  mrg       if (GET_CODE (orig_dsta) == LO_SUM)
   4174  1.1  mrg 	orig_dsta = force_reg (Pmode, orig_dsta);
   4175  1.1  mrg 
   4176  1.1  mrg       words = bytes / 8;
   4177  1.1  mrg       for (i = 0; i < words; ++i)
   4178  1.1  mrg 	{
   4179  1.1  mrg 	  rtx mem
   4180  1.1  mrg 	    = change_address (orig_dst, DImode,
   4181  1.1  mrg 			      gen_rtx_AND (DImode,
   4182  1.1  mrg 					   plus_constant (DImode, orig_dsta,
   4183  1.1  mrg 							  ofs + i*8),
   4184  1.1  mrg 					   GEN_INT (-8)));
   4185  1.1  mrg 	  set_mem_alias_set (mem, 0);
   4186  1.1  mrg 	  emit_move_insn (mem, const0_rtx);
   4187  1.1  mrg 	}
   4188  1.1  mrg 
   4189  1.1  mrg       /* Depending on the alignment, the first stq_u may have overlapped
   4190  1.1  mrg 	 with the initial stl, which means that the last stq_u didn't
   4191  1.1  mrg 	 write as much as it would appear.  Leave those questionable bytes
   4192  1.1  mrg 	 unaccounted for.  */
   4193  1.1  mrg       bytes -= words * 8 - 4;
   4194  1.1  mrg       ofs += words * 8 - 4;
   4195  1.1  mrg     }
   4196  1.1  mrg 
   4197  1.1  mrg   /* Handle a smaller block of aligned words.  */
   4198  1.1  mrg 
   4199  1.1  mrg   if ((align >= 64 && bytes == 4)
   4200  1.1  mrg       || (align == 32 && bytes >= 4))
   4201  1.1  mrg     {
   4202  1.1  mrg       words = bytes / 4;
   4203  1.1  mrg 
   4204  1.1  mrg       for (i = 0; i < words; ++i)
   4205  1.1  mrg 	emit_move_insn (adjust_address (orig_dst, SImode, ofs + i * 4),
   4206  1.1  mrg 			const0_rtx);
   4207  1.1  mrg 
   4208  1.1  mrg       bytes -= words * 4;
   4209  1.1  mrg       ofs += words * 4;
   4210  1.1  mrg     }
   4211  1.1  mrg 
   4212  1.1  mrg   /* An unaligned block uses stq_u stores for as many as possible.  */
   4213  1.1  mrg 
   4214  1.1  mrg   if (bytes >= 8)
   4215  1.1  mrg     {
   4216  1.1  mrg       words = bytes / 8;
   4217  1.1  mrg 
   4218  1.1  mrg       alpha_expand_unaligned_store_words (NULL, orig_dst, words, ofs);
   4219  1.1  mrg 
   4220  1.1  mrg       bytes -= words * 8;
   4221  1.1  mrg       ofs += words * 8;
   4222  1.1  mrg     }
   4223  1.1  mrg 
   4224  1.1  mrg   /* Next clean up any trailing pieces.  */
   4225  1.1  mrg 
   4226  1.1  mrg   /* Count the number of bits in BYTES for which aligned stores could
   4227  1.1  mrg      be emitted.  */
   4228  1.1  mrg   words = 0;
   4229  1.1  mrg   for (i = (TARGET_BWX ? 1 : 4); i * BITS_PER_UNIT <= align ; i <<= 1)
   4230  1.1  mrg     if (bytes & i)
   4231  1.1  mrg       words += 1;
   4232  1.1  mrg 
   4233  1.1  mrg   /* If we have appropriate alignment (and it wouldn't take too many
   4234  1.1  mrg      instructions otherwise), mask out the bytes we need.  */
   4235  1.1  mrg   if (TARGET_BWX ? words > 2 : bytes > 0)
   4236  1.1  mrg     {
   4237  1.1  mrg       if (align >= 64)
   4238  1.1  mrg 	{
   4239  1.1  mrg 	  rtx mem, tmp;
   4240  1.1  mrg 	  HOST_WIDE_INT mask;
   4241  1.1  mrg 
   4242  1.1  mrg 	  mem = adjust_address (orig_dst, DImode, ofs);
   4243  1.1  mrg 	  set_mem_alias_set (mem, 0);
   4244  1.1  mrg 
   4245  1.1  mrg 	  mask = HOST_WIDE_INT_M1U << (bytes * 8);
   4246  1.1  mrg 
   4247  1.1  mrg 	  tmp = expand_binop (DImode, and_optab, mem, GEN_INT (mask),
   4248  1.1  mrg 			      NULL_RTX, 1, OPTAB_WIDEN);
   4249  1.1  mrg 
   4250  1.1  mrg 	  emit_move_insn (mem, tmp);
   4251  1.1  mrg 	  return 1;
   4252  1.1  mrg 	}
   4253  1.1  mrg       else if (align >= 32 && bytes < 4)
   4254  1.1  mrg 	{
   4255  1.1  mrg 	  rtx mem, tmp;
   4256  1.1  mrg 	  HOST_WIDE_INT mask;
   4257  1.1  mrg 
   4258  1.1  mrg 	  mem = adjust_address (orig_dst, SImode, ofs);
   4259  1.1  mrg 	  set_mem_alias_set (mem, 0);
   4260  1.1  mrg 
   4261  1.1  mrg 	  mask = HOST_WIDE_INT_M1U << (bytes * 8);
   4262  1.1  mrg 
   4263  1.1  mrg 	  tmp = expand_binop (SImode, and_optab, mem, GEN_INT (mask),
   4264  1.1  mrg 			      NULL_RTX, 1, OPTAB_WIDEN);
   4265  1.1  mrg 
   4266  1.1  mrg 	  emit_move_insn (mem, tmp);
   4267  1.1  mrg 	  return 1;
   4268  1.1  mrg 	}
   4269  1.1  mrg     }
   4270  1.1  mrg 
   4271  1.1  mrg   if (!TARGET_BWX && bytes >= 4)
   4272  1.1  mrg     {
   4273  1.1  mrg       alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
   4274  1.1  mrg       bytes -= 4;
   4275  1.1  mrg       ofs += 4;
   4276  1.1  mrg     }
   4277  1.1  mrg 
   4278  1.1  mrg   if (bytes >= 2)
   4279  1.1  mrg     {
   4280  1.1  mrg       if (align >= 16)
   4281  1.1  mrg 	{
   4282  1.1  mrg 	  do {
   4283  1.1  mrg 	    emit_move_insn (adjust_address (orig_dst, HImode, ofs),
   4284  1.1  mrg 			    const0_rtx);
   4285  1.1  mrg 	    bytes -= 2;
   4286  1.1  mrg 	    ofs += 2;
   4287  1.1  mrg 	  } while (bytes >= 2);
   4288  1.1  mrg 	}
   4289  1.1  mrg       else if (! TARGET_BWX)
   4290  1.1  mrg 	{
   4291  1.1  mrg 	  alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
   4292  1.1  mrg 	  bytes -= 2;
   4293  1.1  mrg 	  ofs += 2;
   4294  1.1  mrg 	}
   4295  1.1  mrg     }
   4296  1.1  mrg 
   4297  1.1  mrg   while (bytes > 0)
   4298  1.1  mrg     {
   4299  1.1  mrg       emit_move_insn (adjust_address (orig_dst, QImode, ofs), const0_rtx);
   4300  1.1  mrg       bytes -= 1;
   4301  1.1  mrg       ofs += 1;
   4302  1.1  mrg     }
   4303  1.1  mrg 
   4304  1.1  mrg   return 1;
   4305  1.1  mrg }
   4306  1.1  mrg 
   4307  1.1  mrg /* Returns a mask so that zap(x, value) == x & mask.  */
   4308  1.1  mrg 
   4309  1.1  mrg rtx
   4310  1.1  mrg alpha_expand_zap_mask (HOST_WIDE_INT value)
   4311  1.1  mrg {
   4312  1.1  mrg   rtx result;
   4313  1.1  mrg   int i;
   4314  1.1  mrg   HOST_WIDE_INT mask = 0;
   4315  1.1  mrg 
   4316  1.1  mrg   for (i = 7; i >= 0; --i)
   4317  1.1  mrg     {
   4318  1.1  mrg       mask <<= 8;
   4319  1.1  mrg       if (!((value >> i) & 1))
   4320  1.1  mrg 	mask |= 0xff;
   4321  1.1  mrg     }
   4322  1.1  mrg 
   4323  1.1  mrg   result = gen_int_mode (mask, DImode);
   4324  1.1  mrg   return result;
   4325  1.1  mrg }
   4326  1.1  mrg 
   4327  1.1  mrg void
   4328  1.1  mrg alpha_expand_builtin_vector_binop (rtx (*gen) (rtx, rtx, rtx),
   4329  1.1  mrg 				   machine_mode mode,
   4330  1.1  mrg 				   rtx op0, rtx op1, rtx op2)
   4331  1.1  mrg {
   4332  1.1  mrg   op0 = gen_lowpart (mode, op0);
   4333  1.1  mrg 
   4334  1.1  mrg   if (op1 == const0_rtx)
   4335  1.1  mrg     op1 = CONST0_RTX (mode);
   4336  1.1  mrg   else
   4337  1.1  mrg     op1 = gen_lowpart (mode, op1);
   4338  1.1  mrg 
   4339  1.1  mrg   if (op2 == const0_rtx)
   4340  1.1  mrg     op2 = CONST0_RTX (mode);
   4341  1.1  mrg   else
   4342  1.1  mrg     op2 = gen_lowpart (mode, op2);
   4343  1.1  mrg 
   4344  1.1  mrg   emit_insn ((*gen) (op0, op1, op2));
   4345  1.1  mrg }
   4346  1.1  mrg 
   4347  1.1  mrg /* A subroutine of the atomic operation splitters.  Jump to LABEL if
   4348  1.1  mrg    COND is true.  Mark the jump as unlikely to be taken.  */
   4349  1.1  mrg 
   4350  1.1  mrg static void
   4351  1.1  mrg emit_unlikely_jump (rtx cond, rtx label)
   4352  1.1  mrg {
   4353  1.1  mrg   rtx x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
   4354  1.1  mrg   rtx_insn *insn = emit_jump_insn (gen_rtx_SET (pc_rtx, x));
   4355  1.1  mrg   add_reg_br_prob_note (insn, profile_probability::very_unlikely ());
   4356  1.1  mrg }
   4357  1.1  mrg 
   4358  1.1  mrg /* Subroutines of the atomic operation splitters.  Emit barriers
   4359  1.1  mrg    as needed for the memory MODEL.  */
   4360  1.1  mrg 
   4361  1.1  mrg static void
   4362  1.1  mrg alpha_pre_atomic_barrier (enum memmodel model)
   4363  1.1  mrg {
   4364  1.1  mrg   if (need_atomic_barrier_p (model, true))
   4365  1.1  mrg     emit_insn (gen_memory_barrier ());
   4366  1.1  mrg }
   4367  1.1  mrg 
   4368  1.1  mrg static void
   4369  1.1  mrg alpha_post_atomic_barrier (enum memmodel model)
   4370  1.1  mrg {
   4371  1.1  mrg   if (need_atomic_barrier_p (model, false))
   4372  1.1  mrg     emit_insn (gen_memory_barrier ());
   4373  1.1  mrg }
   4374  1.1  mrg 
   4375  1.1  mrg /* A subroutine of the atomic operation splitters.  Emit an insxl
   4376  1.1  mrg    instruction in MODE.  */
   4377  1.1  mrg 
   4378  1.1  mrg static rtx
   4379  1.1  mrg emit_insxl (machine_mode mode, rtx op1, rtx op2)
   4380  1.1  mrg {
   4381  1.1  mrg   rtx ret = gen_reg_rtx (DImode);
   4382  1.1  mrg   rtx (*fn) (rtx, rtx, rtx);
   4383  1.1  mrg 
   4384  1.1  mrg   switch (mode)
   4385  1.1  mrg     {
   4386  1.1  mrg     case E_QImode:
   4387  1.1  mrg       fn = gen_insbl;
   4388  1.1  mrg       break;
   4389  1.1  mrg     case E_HImode:
   4390  1.1  mrg       fn = gen_inswl;
   4391  1.1  mrg       break;
   4392  1.1  mrg     case E_SImode:
   4393  1.1  mrg       fn = gen_insll;
   4394  1.1  mrg       break;
   4395  1.1  mrg     case E_DImode:
   4396  1.1  mrg       fn = gen_insql;
   4397  1.1  mrg       break;
   4398  1.1  mrg     default:
   4399  1.1  mrg       gcc_unreachable ();
   4400  1.1  mrg     }
   4401  1.1  mrg 
   4402  1.1  mrg   op1 = force_reg (mode, op1);
   4403  1.1  mrg   emit_insn (fn (ret, op1, op2));
   4404  1.1  mrg 
   4405  1.1  mrg   return ret;
   4406  1.1  mrg }
   4407  1.1  mrg 
   4408  1.1  mrg /* Expand an atomic fetch-and-operate pattern.  CODE is the binary operation
   4409  1.1  mrg    to perform.  MEM is the memory on which to operate.  VAL is the second
   4410  1.1  mrg    operand of the binary operator.  BEFORE and AFTER are optional locations to
   4411  1.1  mrg    return the value of MEM either before of after the operation.  SCRATCH is
   4412  1.1  mrg    a scratch register.  */
   4413  1.1  mrg 
   4414  1.1  mrg void
   4415  1.1  mrg alpha_split_atomic_op (enum rtx_code code, rtx mem, rtx val, rtx before,
   4416  1.1  mrg 		       rtx after, rtx scratch, enum memmodel model)
   4417  1.1  mrg {
   4418  1.1  mrg   machine_mode mode = GET_MODE (mem);
   4419  1.1  mrg   rtx label, x, cond = gen_rtx_REG (DImode, REGNO (scratch));
   4420  1.1  mrg 
   4421  1.1  mrg   alpha_pre_atomic_barrier (model);
   4422  1.1  mrg 
   4423  1.1  mrg   label = gen_label_rtx ();
   4424  1.1  mrg   emit_label (label);
   4425  1.1  mrg   label = gen_rtx_LABEL_REF (DImode, label);
   4426  1.1  mrg 
   4427  1.1  mrg   if (before == NULL)
   4428  1.1  mrg     before = scratch;
   4429  1.1  mrg   emit_insn (gen_load_locked (mode, before, mem));
   4430  1.1  mrg 
   4431  1.1  mrg   if (code == NOT)
   4432  1.1  mrg     {
   4433  1.1  mrg       x = gen_rtx_AND (mode, before, val);
   4434  1.1  mrg       emit_insn (gen_rtx_SET (val, x));
   4435  1.1  mrg 
   4436  1.1  mrg       x = gen_rtx_NOT (mode, val);
   4437  1.1  mrg     }
   4438  1.1  mrg   else
   4439  1.1  mrg     x = gen_rtx_fmt_ee (code, mode, before, val);
   4440  1.1  mrg   if (after)
   4441  1.1  mrg     emit_insn (gen_rtx_SET (after, copy_rtx (x)));
   4442  1.1  mrg   emit_insn (gen_rtx_SET (scratch, x));
   4443  1.1  mrg 
   4444  1.1  mrg   emit_insn (gen_store_conditional (mode, cond, mem, scratch));
   4445  1.1  mrg 
   4446  1.1  mrg   x = gen_rtx_EQ (DImode, cond, const0_rtx);
   4447  1.1  mrg   emit_unlikely_jump (x, label);
   4448  1.1  mrg 
   4449  1.1  mrg   alpha_post_atomic_barrier (model);
   4450  1.1  mrg }
   4451  1.1  mrg 
   4452  1.1  mrg /* Expand a compare and swap operation.  */
   4453  1.1  mrg 
   4454  1.1  mrg void
   4455  1.1  mrg alpha_split_compare_and_swap (rtx operands[])
   4456  1.1  mrg {
   4457  1.1  mrg   rtx cond, retval, mem, oldval, newval;
   4458  1.1  mrg   bool is_weak;
   4459  1.1  mrg   enum memmodel mod_s, mod_f;
   4460  1.1  mrg   machine_mode mode;
   4461  1.1  mrg   rtx label1, label2, x;
   4462  1.1  mrg 
   4463  1.1  mrg   cond = operands[0];
   4464  1.1  mrg   retval = operands[1];
   4465  1.1  mrg   mem = operands[2];
   4466  1.1  mrg   oldval = operands[3];
   4467  1.1  mrg   newval = operands[4];
   4468  1.1  mrg   is_weak = (operands[5] != const0_rtx);
   4469  1.1  mrg   mod_s = memmodel_from_int (INTVAL (operands[6]));
   4470  1.1  mrg   mod_f = memmodel_from_int (INTVAL (operands[7]));
   4471  1.1  mrg   mode = GET_MODE (mem);
   4472  1.1  mrg 
   4473  1.1  mrg   alpha_pre_atomic_barrier (mod_s);
   4474  1.1  mrg 
   4475  1.1  mrg   label1 = NULL_RTX;
   4476  1.1  mrg   if (!is_weak)
   4477  1.1  mrg     {
   4478  1.1  mrg       label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   4479  1.1  mrg       emit_label (XEXP (label1, 0));
   4480  1.1  mrg     }
   4481  1.1  mrg   label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   4482  1.1  mrg 
   4483  1.1  mrg   emit_insn (gen_load_locked (mode, retval, mem));
   4484  1.1  mrg 
   4485  1.1  mrg   x = gen_lowpart (DImode, retval);
   4486  1.1  mrg   if (oldval == const0_rtx)
   4487  1.1  mrg     {
   4488  1.1  mrg       emit_move_insn (cond, const0_rtx);
   4489  1.1  mrg       x = gen_rtx_NE (DImode, x, const0_rtx);
   4490  1.1  mrg     }
   4491  1.1  mrg   else
   4492  1.1  mrg     {
   4493  1.1  mrg       x = gen_rtx_EQ (DImode, x, oldval);
   4494  1.1  mrg       emit_insn (gen_rtx_SET (cond, x));
   4495  1.1  mrg       x = gen_rtx_EQ (DImode, cond, const0_rtx);
   4496  1.1  mrg     }
   4497  1.1  mrg   emit_unlikely_jump (x, label2);
   4498  1.1  mrg 
   4499  1.1  mrg   emit_move_insn (cond, newval);
   4500  1.1  mrg   emit_insn (gen_store_conditional
   4501  1.1  mrg 	     (mode, cond, mem, gen_lowpart (mode, cond)));
   4502  1.1  mrg 
   4503  1.1  mrg   if (!is_weak)
   4504  1.1  mrg     {
   4505  1.1  mrg       x = gen_rtx_EQ (DImode, cond, const0_rtx);
   4506  1.1  mrg       emit_unlikely_jump (x, label1);
   4507  1.1  mrg     }
   4508  1.1  mrg 
   4509  1.1  mrg   if (!is_mm_relaxed (mod_f))
   4510  1.1  mrg     emit_label (XEXP (label2, 0));
   4511  1.1  mrg 
   4512  1.1  mrg   alpha_post_atomic_barrier (mod_s);
   4513  1.1  mrg 
   4514  1.1  mrg   if (is_mm_relaxed (mod_f))
   4515  1.1  mrg     emit_label (XEXP (label2, 0));
   4516  1.1  mrg }
   4517  1.1  mrg 
   4518  1.1  mrg void
   4519  1.1  mrg alpha_expand_compare_and_swap_12 (rtx operands[])
   4520  1.1  mrg {
   4521  1.1  mrg   rtx cond, dst, mem, oldval, newval, is_weak, mod_s, mod_f;
   4522  1.1  mrg   machine_mode mode;
   4523  1.1  mrg   rtx addr, align, wdst;
   4524  1.1  mrg 
   4525  1.1  mrg   cond = operands[0];
   4526  1.1  mrg   dst = operands[1];
   4527  1.1  mrg   mem = operands[2];
   4528  1.1  mrg   oldval = operands[3];
   4529  1.1  mrg   newval = operands[4];
   4530  1.1  mrg   is_weak = operands[5];
   4531  1.1  mrg   mod_s = operands[6];
   4532  1.1  mrg   mod_f = operands[7];
   4533  1.1  mrg   mode = GET_MODE (mem);
   4534  1.1  mrg 
   4535  1.1  mrg   /* We forced the address into a register via mem_noofs_operand.  */
   4536  1.1  mrg   addr = XEXP (mem, 0);
   4537  1.1  mrg   gcc_assert (register_operand (addr, DImode));
   4538  1.1  mrg 
   4539  1.1  mrg   align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
   4540  1.1  mrg 			       NULL_RTX, 1, OPTAB_DIRECT);
   4541  1.1  mrg 
   4542  1.1  mrg   oldval = convert_modes (DImode, mode, oldval, 1);
   4543  1.1  mrg 
   4544  1.1  mrg   if (newval != const0_rtx)
   4545  1.1  mrg     newval = emit_insxl (mode, newval, addr);
   4546  1.1  mrg 
   4547  1.1  mrg   wdst = gen_reg_rtx (DImode);
   4548  1.1  mrg   emit_insn (gen_atomic_compare_and_swap_1
   4549  1.1  mrg 	     (mode, cond, wdst, mem, oldval, newval, align,
   4550  1.1  mrg 	      is_weak, mod_s, mod_f));
   4551  1.1  mrg 
   4552  1.1  mrg   emit_move_insn (dst, gen_lowpart (mode, wdst));
   4553  1.1  mrg }
   4554  1.1  mrg 
   4555  1.1  mrg void
   4556  1.1  mrg alpha_split_compare_and_swap_12 (rtx operands[])
   4557  1.1  mrg {
   4558  1.1  mrg   rtx cond, dest, orig_mem, oldval, newval, align, scratch;
   4559  1.1  mrg   machine_mode mode;
   4560  1.1  mrg   bool is_weak;
   4561  1.1  mrg   enum memmodel mod_s, mod_f;
   4562  1.1  mrg   rtx label1, label2, mem, addr, width, mask, x;
   4563  1.1  mrg 
   4564  1.1  mrg   cond = operands[0];
   4565  1.1  mrg   dest = operands[1];
   4566  1.1  mrg   orig_mem = operands[2];
   4567  1.1  mrg   oldval = operands[3];
   4568  1.1  mrg   newval = operands[4];
   4569  1.1  mrg   align = operands[5];
   4570  1.1  mrg   is_weak = (operands[6] != const0_rtx);
   4571  1.1  mrg   mod_s = memmodel_from_int (INTVAL (operands[7]));
   4572  1.1  mrg   mod_f = memmodel_from_int (INTVAL (operands[8]));
   4573  1.1  mrg   scratch = operands[9];
   4574  1.1  mrg   mode = GET_MODE (orig_mem);
   4575  1.1  mrg   addr = XEXP (orig_mem, 0);
   4576  1.1  mrg 
   4577  1.1  mrg   mem = gen_rtx_MEM (DImode, align);
   4578  1.1  mrg   MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
   4579  1.1  mrg   if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER)
   4580  1.1  mrg     set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
   4581  1.1  mrg 
   4582  1.1  mrg   alpha_pre_atomic_barrier (mod_s);
   4583  1.1  mrg 
   4584  1.1  mrg   label1 = NULL_RTX;
   4585  1.1  mrg   if (!is_weak)
   4586  1.1  mrg     {
   4587  1.1  mrg       label1 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   4588  1.1  mrg       emit_label (XEXP (label1, 0));
   4589  1.1  mrg     }
   4590  1.1  mrg   label2 = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   4591  1.1  mrg 
   4592  1.1  mrg   emit_insn (gen_load_locked (DImode, scratch, mem));
   4593  1.1  mrg 
   4594  1.1  mrg   width = GEN_INT (GET_MODE_BITSIZE (mode));
   4595  1.1  mrg   mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
   4596  1.1  mrg   emit_insn (gen_extxl (dest, scratch, width, addr));
   4597  1.1  mrg 
   4598  1.1  mrg   if (oldval == const0_rtx)
   4599  1.1  mrg     {
   4600  1.1  mrg       emit_move_insn (cond, const0_rtx);
   4601  1.1  mrg       x = gen_rtx_NE (DImode, dest, const0_rtx);
   4602  1.1  mrg     }
   4603  1.1  mrg   else
   4604  1.1  mrg     {
   4605  1.1  mrg       x = gen_rtx_EQ (DImode, dest, oldval);
   4606  1.1  mrg       emit_insn (gen_rtx_SET (cond, x));
   4607  1.1  mrg       x = gen_rtx_EQ (DImode, cond, const0_rtx);
   4608  1.1  mrg     }
   4609  1.1  mrg   emit_unlikely_jump (x, label2);
   4610  1.1  mrg 
   4611  1.1  mrg   emit_insn (gen_mskxl (cond, scratch, mask, addr));
   4612  1.1  mrg 
   4613  1.1  mrg   if (newval != const0_rtx)
   4614  1.1  mrg     emit_insn (gen_iordi3 (cond, cond, newval));
   4615  1.1  mrg 
   4616  1.1  mrg   emit_insn (gen_store_conditional (DImode, cond, mem, cond));
   4617  1.1  mrg 
   4618  1.1  mrg   if (!is_weak)
   4619  1.1  mrg     {
   4620  1.1  mrg       x = gen_rtx_EQ (DImode, cond, const0_rtx);
   4621  1.1  mrg       emit_unlikely_jump (x, label1);
   4622  1.1  mrg     }
   4623  1.1  mrg 
   4624  1.1  mrg   if (!is_mm_relaxed (mod_f))
   4625  1.1  mrg     emit_label (XEXP (label2, 0));
   4626  1.1  mrg 
   4627  1.1  mrg   alpha_post_atomic_barrier (mod_s);
   4628  1.1  mrg 
   4629  1.1  mrg   if (is_mm_relaxed (mod_f))
   4630  1.1  mrg     emit_label (XEXP (label2, 0));
   4631  1.1  mrg }
   4632  1.1  mrg 
   4633  1.1  mrg /* Expand an atomic exchange operation.  */
   4634  1.1  mrg 
   4635  1.1  mrg void
   4636  1.1  mrg alpha_split_atomic_exchange (rtx operands[])
   4637  1.1  mrg {
   4638  1.1  mrg   rtx retval, mem, val, scratch;
   4639  1.1  mrg   enum memmodel model;
   4640  1.1  mrg   machine_mode mode;
   4641  1.1  mrg   rtx label, x, cond;
   4642  1.1  mrg 
   4643  1.1  mrg   retval = operands[0];
   4644  1.1  mrg   mem = operands[1];
   4645  1.1  mrg   val = operands[2];
   4646  1.1  mrg   model = (enum memmodel) INTVAL (operands[3]);
   4647  1.1  mrg   scratch = operands[4];
   4648  1.1  mrg   mode = GET_MODE (mem);
   4649  1.1  mrg   cond = gen_lowpart (DImode, scratch);
   4650  1.1  mrg 
   4651  1.1  mrg   alpha_pre_atomic_barrier (model);
   4652  1.1  mrg 
   4653  1.1  mrg   label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   4654  1.1  mrg   emit_label (XEXP (label, 0));
   4655  1.1  mrg 
   4656  1.1  mrg   emit_insn (gen_load_locked (mode, retval, mem));
   4657  1.1  mrg   emit_move_insn (scratch, val);
   4658  1.1  mrg   emit_insn (gen_store_conditional (mode, cond, mem, scratch));
   4659  1.1  mrg 
   4660  1.1  mrg   x = gen_rtx_EQ (DImode, cond, const0_rtx);
   4661  1.1  mrg   emit_unlikely_jump (x, label);
   4662  1.1  mrg 
   4663  1.1  mrg   alpha_post_atomic_barrier (model);
   4664  1.1  mrg }
   4665  1.1  mrg 
   4666  1.1  mrg void
   4667  1.1  mrg alpha_expand_atomic_exchange_12 (rtx operands[])
   4668  1.1  mrg {
   4669  1.1  mrg   rtx dst, mem, val, model;
   4670  1.1  mrg   machine_mode mode;
   4671  1.1  mrg   rtx addr, align, wdst;
   4672  1.1  mrg 
   4673  1.1  mrg   dst = operands[0];
   4674  1.1  mrg   mem = operands[1];
   4675  1.1  mrg   val = operands[2];
   4676  1.1  mrg   model = operands[3];
   4677  1.1  mrg   mode = GET_MODE (mem);
   4678  1.1  mrg 
   4679  1.1  mrg   /* We forced the address into a register via mem_noofs_operand.  */
   4680  1.1  mrg   addr = XEXP (mem, 0);
   4681  1.1  mrg   gcc_assert (register_operand (addr, DImode));
   4682  1.1  mrg 
   4683  1.1  mrg   align = expand_simple_binop (Pmode, AND, addr, GEN_INT (-8),
   4684  1.1  mrg 			       NULL_RTX, 1, OPTAB_DIRECT);
   4685  1.1  mrg 
   4686  1.1  mrg   /* Insert val into the correct byte location within the word.  */
   4687  1.1  mrg   if (val != const0_rtx)
   4688  1.1  mrg     val = emit_insxl (mode, val, addr);
   4689  1.1  mrg 
   4690  1.1  mrg   wdst = gen_reg_rtx (DImode);
   4691  1.1  mrg   emit_insn (gen_atomic_exchange_1 (mode, wdst, mem, val, align, model));
   4692  1.1  mrg 
   4693  1.1  mrg   emit_move_insn (dst, gen_lowpart (mode, wdst));
   4694  1.1  mrg }
   4695  1.1  mrg 
   4696  1.1  mrg void
   4697  1.1  mrg alpha_split_atomic_exchange_12 (rtx operands[])
   4698  1.1  mrg {
   4699  1.1  mrg   rtx dest, orig_mem, addr, val, align, scratch;
   4700  1.1  mrg   rtx label, mem, width, mask, x;
   4701  1.1  mrg   machine_mode mode;
   4702  1.1  mrg   enum memmodel model;
   4703  1.1  mrg 
   4704  1.1  mrg   dest = operands[0];
   4705  1.1  mrg   orig_mem = operands[1];
   4706  1.1  mrg   val = operands[2];
   4707  1.1  mrg   align = operands[3];
   4708  1.1  mrg   model = (enum memmodel) INTVAL (operands[4]);
   4709  1.1  mrg   scratch = operands[5];
   4710  1.1  mrg   mode = GET_MODE (orig_mem);
   4711  1.1  mrg   addr = XEXP (orig_mem, 0);
   4712  1.1  mrg 
   4713  1.1  mrg   mem = gen_rtx_MEM (DImode, align);
   4714  1.1  mrg   MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
   4715  1.1  mrg   if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER)
   4716  1.1  mrg     set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
   4717  1.1  mrg 
   4718  1.1  mrg   alpha_pre_atomic_barrier (model);
   4719  1.1  mrg 
   4720  1.1  mrg   label = gen_rtx_LABEL_REF (DImode, gen_label_rtx ());
   4721  1.1  mrg   emit_label (XEXP (label, 0));
   4722  1.1  mrg 
   4723  1.1  mrg   emit_insn (gen_load_locked (DImode, scratch, mem));
   4724  1.1  mrg 
   4725  1.1  mrg   width = GEN_INT (GET_MODE_BITSIZE (mode));
   4726  1.1  mrg   mask = GEN_INT (mode == QImode ? 0xff : 0xffff);
   4727  1.1  mrg   emit_insn (gen_extxl (dest, scratch, width, addr));
   4728  1.1  mrg   emit_insn (gen_mskxl (scratch, scratch, mask, addr));
   4729  1.1  mrg   if (val != const0_rtx)
   4730  1.1  mrg     emit_insn (gen_iordi3 (scratch, scratch, val));
   4731  1.1  mrg 
   4732  1.1  mrg   emit_insn (gen_store_conditional (DImode, scratch, mem, scratch));
   4733  1.1  mrg 
   4734  1.1  mrg   x = gen_rtx_EQ (DImode, scratch, const0_rtx);
   4735  1.1  mrg   emit_unlikely_jump (x, label);
   4736  1.1  mrg 
   4737  1.1  mrg   alpha_post_atomic_barrier (model);
   4738  1.1  mrg }
   4739  1.1  mrg 
   4740  1.1  mrg /* Adjust the cost of a scheduling dependency.  Return the new cost of
   4742  1.1  mrg    a dependency LINK or INSN on DEP_INSN.  COST is the current cost.  */
   4743  1.1  mrg 
   4744  1.1  mrg static int
   4745  1.1  mrg alpha_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
   4746  1.1  mrg 		   unsigned int)
   4747  1.1  mrg {
   4748  1.1  mrg   enum attr_type dep_insn_type;
   4749  1.1  mrg 
   4750  1.1  mrg   /* If the dependence is an anti-dependence, there is no cost.  For an
   4751  1.1  mrg      output dependence, there is sometimes a cost, but it doesn't seem
   4752  1.1  mrg      worth handling those few cases.  */
   4753  1.1  mrg   if (dep_type != 0)
   4754  1.1  mrg     return cost;
   4755  1.1  mrg 
   4756  1.1  mrg   /* If we can't recognize the insns, we can't really do anything.  */
   4757  1.1  mrg   if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
   4758  1.1  mrg     return cost;
   4759  1.1  mrg 
   4760  1.1  mrg   dep_insn_type = get_attr_type (dep_insn);
   4761  1.1  mrg 
   4762  1.1  mrg   /* Bring in the user-defined memory latency.  */
   4763  1.1  mrg   if (dep_insn_type == TYPE_ILD
   4764  1.1  mrg       || dep_insn_type == TYPE_FLD
   4765  1.1  mrg       || dep_insn_type == TYPE_LDSYM)
   4766  1.1  mrg     cost += alpha_memory_latency-1;
   4767  1.1  mrg 
   4768  1.1  mrg   /* Everything else handled in DFA bypasses now.  */
   4769  1.1  mrg 
   4770  1.1  mrg   return cost;
   4771  1.1  mrg }
   4772  1.1  mrg 
   4773  1.1  mrg /* The number of instructions that can be issued per cycle.  */
   4774  1.1  mrg 
   4775  1.1  mrg static int
   4776  1.1  mrg alpha_issue_rate (void)
   4777  1.1  mrg {
   4778  1.1  mrg   return (alpha_tune == PROCESSOR_EV4 ? 2 : 4);
   4779  1.1  mrg }
   4780  1.1  mrg 
   4781  1.1  mrg /* How many alternative schedules to try.  This should be as wide as the
   4782  1.1  mrg    scheduling freedom in the DFA, but no wider.  Making this value too
   4783  1.1  mrg    large results extra work for the scheduler.
   4784  1.1  mrg 
   4785  1.1  mrg    For EV4, loads can be issued to either IB0 or IB1, thus we have 2
   4786  1.1  mrg    alternative schedules.  For EV5, we can choose between E0/E1 and
   4787  1.1  mrg    FA/FM.  For EV6, an arithmetic insn can be issued to U0/U1/L0/L1.  */
   4788  1.1  mrg 
   4789  1.1  mrg static int
   4790  1.1  mrg alpha_multipass_dfa_lookahead (void)
   4791  1.1  mrg {
   4792  1.1  mrg   return (alpha_tune == PROCESSOR_EV6 ? 4 : 2);
   4793  1.1  mrg }
   4794  1.1  mrg 
   4795  1.1  mrg /* Machine-specific function data.  */
   4797  1.1  mrg 
   4798  1.1  mrg struct GTY(()) alpha_links;
   4799  1.1  mrg 
   4800  1.1  mrg struct GTY(()) machine_function
   4801  1.1  mrg {
   4802  1.1  mrg   unsigned HOST_WIDE_INT sa_mask;
   4803  1.1  mrg   HOST_WIDE_INT sa_size;
   4804  1.1  mrg   HOST_WIDE_INT frame_size;
   4805  1.1  mrg 
   4806  1.1  mrg   /* For flag_reorder_blocks_and_partition.  */
   4807  1.1  mrg   rtx gp_save_rtx;
   4808  1.1  mrg 
   4809  1.1  mrg   /* For VMS condition handlers.  */
   4810  1.1  mrg   bool uses_condition_handler;
   4811  1.1  mrg 
   4812  1.1  mrg   /* Linkage entries.  */
   4813  1.1  mrg   hash_map<nofree_string_hash, alpha_links *> *links;
   4814  1.1  mrg };
   4815  1.1  mrg 
   4816  1.1  mrg /* How to allocate a 'struct machine_function'.  */
   4817  1.1  mrg 
   4818  1.1  mrg static struct machine_function *
   4819  1.1  mrg alpha_init_machine_status (void)
   4820  1.1  mrg {
   4821  1.1  mrg   return ggc_cleared_alloc<machine_function> ();
   4822  1.1  mrg }
   4823  1.1  mrg 
   4824  1.1  mrg /* Support for frame based VMS condition handlers.  */
   4825  1.1  mrg 
   4826  1.1  mrg /* A VMS condition handler may be established for a function with a call to
   4827  1.1  mrg    __builtin_establish_vms_condition_handler, and cancelled with a call to
   4828  1.1  mrg    __builtin_revert_vms_condition_handler.
   4829  1.1  mrg 
   4830  1.1  mrg    The VMS Condition Handling Facility knows about the existence of a handler
   4831  1.1  mrg    from the procedure descriptor .handler field.  As the VMS native compilers,
   4832  1.1  mrg    we store the user specified handler's address at a fixed location in the
   4833  1.1  mrg    stack frame and point the procedure descriptor at a common wrapper which
   4834  1.1  mrg    fetches the real handler's address and issues an indirect call.
   4835  1.1  mrg 
   4836  1.1  mrg    The indirection wrapper is "__gcc_shell_handler", provided by libgcc.
   4837  1.1  mrg 
   4838  1.1  mrg    We force the procedure kind to PT_STACK, and the fixed frame location is
   4839  1.1  mrg    fp+8, just before the register save area. We use the handler_data field in
   4840  1.1  mrg    the procedure descriptor to state the fp offset at which the installed
   4841  1.1  mrg    handler address can be found.  */
   4842  1.1  mrg 
   4843  1.1  mrg #define VMS_COND_HANDLER_FP_OFFSET 8
   4844  1.1  mrg 
   4845  1.1  mrg /* Expand code to store the currently installed user VMS condition handler
   4846  1.1  mrg    into TARGET and install HANDLER as the new condition handler.  */
   4847  1.1  mrg 
   4848  1.1  mrg void
   4849  1.1  mrg alpha_expand_builtin_establish_vms_condition_handler (rtx target, rtx handler)
   4850  1.1  mrg {
   4851  1.1  mrg   rtx handler_slot_address = plus_constant (Pmode, hard_frame_pointer_rtx,
   4852  1.1  mrg 					    VMS_COND_HANDLER_FP_OFFSET);
   4853  1.1  mrg 
   4854  1.1  mrg   rtx handler_slot
   4855  1.1  mrg     = gen_rtx_MEM (DImode, handler_slot_address);
   4856  1.1  mrg 
   4857  1.1  mrg   emit_move_insn (target, handler_slot);
   4858  1.1  mrg   emit_move_insn (handler_slot, handler);
   4859  1.1  mrg 
   4860  1.1  mrg   /* Notify the start/prologue/epilogue emitters that the condition handler
   4861  1.1  mrg      slot is needed.  In addition to reserving the slot space, this will force
   4862  1.1  mrg      the procedure kind to PT_STACK so ensure that the hard_frame_pointer_rtx
   4863  1.1  mrg      use above is correct.  */
   4864  1.1  mrg   cfun->machine->uses_condition_handler = true;
   4865  1.1  mrg }
   4866  1.1  mrg 
   4867  1.1  mrg /* Expand code to store the current VMS condition handler into TARGET and
   4868  1.1  mrg    nullify it.  */
   4869  1.1  mrg 
   4870  1.1  mrg void
   4871  1.1  mrg alpha_expand_builtin_revert_vms_condition_handler (rtx target)
   4872  1.1  mrg {
   4873  1.1  mrg   /* We implement this by establishing a null condition handler, with the tiny
   4874  1.1  mrg      side effect of setting uses_condition_handler.  This is a little bit
   4875  1.1  mrg      pessimistic if no actual builtin_establish call is ever issued, which is
   4876  1.1  mrg      not a real problem and expected never to happen anyway.  */
   4877  1.1  mrg 
   4878  1.1  mrg   alpha_expand_builtin_establish_vms_condition_handler (target, const0_rtx);
   4879  1.1  mrg }
   4880  1.1  mrg 
   4881  1.1  mrg /* Functions to save and restore alpha_return_addr_rtx.  */
   4882  1.1  mrg 
   4883  1.1  mrg /* Start the ball rolling with RETURN_ADDR_RTX.  */
   4884  1.1  mrg 
   4885  1.1  mrg rtx
   4886  1.1  mrg alpha_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
   4887  1.1  mrg {
   4888  1.1  mrg   if (count != 0)
   4889  1.1  mrg     return const0_rtx;
   4890  1.1  mrg 
   4891  1.1  mrg   return get_hard_reg_initial_val (Pmode, REG_RA);
   4892  1.1  mrg }
   4893  1.1  mrg 
   4894  1.1  mrg /* Return or create a memory slot containing the gp value for the current
   4895  1.1  mrg    function.  Needed only if TARGET_LD_BUGGY_LDGP.  */
   4896  1.1  mrg 
   4897  1.1  mrg rtx
   4898  1.1  mrg alpha_gp_save_rtx (void)
   4899  1.1  mrg {
   4900  1.1  mrg   rtx_insn *seq;
   4901  1.1  mrg   rtx m = cfun->machine->gp_save_rtx;
   4902  1.1  mrg 
   4903  1.1  mrg   if (m == NULL)
   4904  1.1  mrg     {
   4905  1.1  mrg       start_sequence ();
   4906  1.1  mrg 
   4907  1.1  mrg       m = assign_stack_local (DImode, UNITS_PER_WORD, BITS_PER_WORD);
   4908  1.1  mrg       m = validize_mem (m);
   4909  1.1  mrg       emit_move_insn (m, pic_offset_table_rtx);
   4910  1.1  mrg 
   4911  1.1  mrg       seq = get_insns ();
   4912  1.1  mrg       end_sequence ();
   4913  1.1  mrg 
   4914  1.1  mrg       /* We used to simply emit the sequence after entry_of_function.
   4915  1.1  mrg 	 However this breaks the CFG if the first instruction in the
   4916  1.1  mrg 	 first block is not the NOTE_INSN_BASIC_BLOCK, for example a
   4917  1.1  mrg 	 label.  Emit the sequence properly on the edge.  We are only
   4918  1.1  mrg 	 invoked from dw2_build_landing_pads and finish_eh_generation
   4919  1.1  mrg 	 will call commit_edge_insertions thanks to a kludge.  */
   4920  1.1  mrg       insert_insn_on_edge (seq,
   4921  1.1  mrg 			   single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
   4922  1.1  mrg 
   4923  1.1  mrg       cfun->machine->gp_save_rtx = m;
   4924  1.1  mrg     }
   4925  1.1  mrg 
   4926  1.1  mrg   return m;
   4927  1.1  mrg }
   4928  1.1  mrg 
   4929  1.1  mrg static void
   4930  1.1  mrg alpha_instantiate_decls (void)
   4931  1.1  mrg {
   4932  1.1  mrg   if (cfun->machine->gp_save_rtx != NULL_RTX)
   4933  1.1  mrg     instantiate_decl_rtl (cfun->machine->gp_save_rtx);
   4934  1.1  mrg }
   4935  1.1  mrg 
   4936  1.1  mrg static int
   4937  1.1  mrg alpha_ra_ever_killed (void)
   4938  1.1  mrg {
   4939  1.1  mrg   rtx_insn *top;
   4940  1.1  mrg 
   4941  1.1  mrg   if (!has_hard_reg_initial_val (Pmode, REG_RA))
   4942  1.1  mrg     return (int)df_regs_ever_live_p (REG_RA);
   4943  1.1  mrg 
   4944  1.1  mrg   push_topmost_sequence ();
   4945  1.1  mrg   top = get_insns ();
   4946  1.1  mrg   pop_topmost_sequence ();
   4947  1.1  mrg 
   4948  1.1  mrg   return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL);
   4949  1.1  mrg }
   4950  1.1  mrg 
   4951  1.1  mrg 
   4952  1.1  mrg /* Return the trap mode suffix applicable to the current
   4954  1.1  mrg    instruction, or NULL.  */
   4955  1.1  mrg 
   4956  1.1  mrg static const char *
   4957  1.1  mrg get_trap_mode_suffix (void)
   4958  1.1  mrg {
   4959  1.1  mrg   enum attr_trap_suffix s = get_attr_trap_suffix (current_output_insn);
   4960  1.1  mrg 
   4961  1.1  mrg   switch (s)
   4962  1.1  mrg     {
   4963  1.1  mrg     case TRAP_SUFFIX_NONE:
   4964  1.1  mrg       return NULL;
   4965  1.1  mrg 
   4966  1.1  mrg     case TRAP_SUFFIX_SU:
   4967  1.1  mrg       if (alpha_fptm >= ALPHA_FPTM_SU)
   4968  1.1  mrg 	return "su";
   4969  1.1  mrg       return NULL;
   4970  1.1  mrg 
   4971  1.1  mrg     case TRAP_SUFFIX_SUI:
   4972  1.1  mrg       if (alpha_fptm >= ALPHA_FPTM_SUI)
   4973  1.1  mrg 	return "sui";
   4974  1.1  mrg       return NULL;
   4975  1.1  mrg 
   4976  1.1  mrg     case TRAP_SUFFIX_V_SV:
   4977  1.1  mrg       switch (alpha_fptm)
   4978  1.1  mrg 	{
   4979  1.1  mrg 	case ALPHA_FPTM_N:
   4980  1.1  mrg 	  return NULL;
   4981  1.1  mrg 	case ALPHA_FPTM_U:
   4982  1.1  mrg 	  return "v";
   4983  1.1  mrg 	case ALPHA_FPTM_SU:
   4984  1.1  mrg 	case ALPHA_FPTM_SUI:
   4985  1.1  mrg 	  return "sv";
   4986  1.1  mrg 	default:
   4987  1.1  mrg 	  gcc_unreachable ();
   4988  1.1  mrg 	}
   4989  1.1  mrg 
   4990  1.1  mrg     case TRAP_SUFFIX_V_SV_SVI:
   4991  1.1  mrg       switch (alpha_fptm)
   4992  1.1  mrg 	{
   4993  1.1  mrg 	case ALPHA_FPTM_N:
   4994  1.1  mrg 	  return NULL;
   4995  1.1  mrg 	case ALPHA_FPTM_U:
   4996  1.1  mrg 	  return "v";
   4997  1.1  mrg 	case ALPHA_FPTM_SU:
   4998  1.1  mrg 	  return "sv";
   4999  1.1  mrg 	case ALPHA_FPTM_SUI:
   5000  1.1  mrg 	  return "svi";
   5001  1.1  mrg 	default:
   5002  1.1  mrg 	  gcc_unreachable ();
   5003  1.1  mrg 	}
   5004  1.1  mrg       break;
   5005  1.1  mrg 
   5006  1.1  mrg     case TRAP_SUFFIX_U_SU_SUI:
   5007  1.1  mrg       switch (alpha_fptm)
   5008  1.1  mrg 	{
   5009  1.1  mrg 	case ALPHA_FPTM_N:
   5010  1.1  mrg 	  return NULL;
   5011  1.1  mrg 	case ALPHA_FPTM_U:
   5012  1.1  mrg 	  return "u";
   5013  1.1  mrg 	case ALPHA_FPTM_SU:
   5014  1.1  mrg 	  return "su";
   5015  1.1  mrg 	case ALPHA_FPTM_SUI:
   5016  1.1  mrg 	  return "sui";
   5017  1.1  mrg 	default:
   5018  1.1  mrg 	  gcc_unreachable ();
   5019  1.1  mrg 	}
   5020  1.1  mrg       break;
   5021  1.1  mrg 
   5022  1.1  mrg     default:
   5023  1.1  mrg       gcc_unreachable ();
   5024  1.1  mrg     }
   5025  1.1  mrg   gcc_unreachable ();
   5026  1.1  mrg }
   5027  1.1  mrg 
   5028  1.1  mrg /* Return the rounding mode suffix applicable to the current
   5029  1.1  mrg    instruction, or NULL.  */
   5030  1.1  mrg 
   5031  1.1  mrg static const char *
   5032  1.1  mrg get_round_mode_suffix (void)
   5033  1.1  mrg {
   5034  1.1  mrg   enum attr_round_suffix s = get_attr_round_suffix (current_output_insn);
   5035  1.1  mrg 
   5036  1.1  mrg   switch (s)
   5037  1.1  mrg     {
   5038  1.1  mrg     case ROUND_SUFFIX_NONE:
   5039  1.1  mrg       return NULL;
   5040  1.1  mrg     case ROUND_SUFFIX_NORMAL:
   5041  1.1  mrg       switch (alpha_fprm)
   5042  1.1  mrg 	{
   5043  1.1  mrg 	case ALPHA_FPRM_NORM:
   5044  1.1  mrg 	  return NULL;
   5045  1.1  mrg 	case ALPHA_FPRM_MINF:
   5046  1.1  mrg 	  return "m";
   5047  1.1  mrg 	case ALPHA_FPRM_CHOP:
   5048  1.1  mrg 	  return "c";
   5049  1.1  mrg 	case ALPHA_FPRM_DYN:
   5050  1.1  mrg 	  return "d";
   5051  1.1  mrg 	default:
   5052  1.1  mrg 	  gcc_unreachable ();
   5053  1.1  mrg 	}
   5054  1.1  mrg       break;
   5055  1.1  mrg 
   5056  1.1  mrg     case ROUND_SUFFIX_C:
   5057  1.1  mrg       return "c";
   5058  1.1  mrg 
   5059  1.1  mrg     default:
   5060  1.1  mrg       gcc_unreachable ();
   5061  1.1  mrg     }
   5062  1.1  mrg   gcc_unreachable ();
   5063  1.1  mrg }
   5064  1.1  mrg 
   5065  1.1  mrg /* Implement TARGET_PRINT_OPERAND_PUNCT_VALID_P.  */
   5066  1.1  mrg 
   5067  1.1  mrg static bool
   5068  1.1  mrg alpha_print_operand_punct_valid_p (unsigned char code)
   5069  1.1  mrg {
   5070  1.1  mrg   return (code == '/' || code == ',' || code == '-' || code == '~'
   5071  1.1  mrg 	  || code == '#' || code == '*' || code == '&');
   5072  1.1  mrg }
   5073  1.1  mrg 
   5074  1.1  mrg /* Implement TARGET_PRINT_OPERAND.  The alpha-specific
   5075  1.1  mrg    operand codes are documented below.  */
   5076  1.1  mrg 
   5077  1.1  mrg static void
   5078  1.1  mrg alpha_print_operand (FILE *file, rtx x, int code)
   5079  1.1  mrg {
   5080  1.1  mrg   int i;
   5081  1.1  mrg 
   5082  1.1  mrg   switch (code)
   5083  1.1  mrg     {
   5084  1.1  mrg     case '~':
   5085  1.1  mrg       /* Print the assembler name of the current function.  */
   5086  1.1  mrg       assemble_name (file, alpha_fnname);
   5087  1.1  mrg       break;
   5088  1.1  mrg 
   5089  1.1  mrg     case '&':
   5090  1.1  mrg       if (const char *name = get_some_local_dynamic_name ())
   5091  1.1  mrg 	assemble_name (file, name);
   5092  1.1  mrg       else
   5093  1.1  mrg 	output_operand_lossage ("'%%&' used without any "
   5094  1.1  mrg 				"local dynamic TLS references");
   5095  1.1  mrg       break;
   5096  1.1  mrg 
   5097  1.1  mrg     case '/':
   5098  1.1  mrg       /* Generates the instruction suffix.  The TRAP_SUFFIX and ROUND_SUFFIX
   5099  1.1  mrg 	 attributes are examined to determine what is appropriate.  */
   5100  1.1  mrg       {
   5101  1.1  mrg 	const char *trap = get_trap_mode_suffix ();
   5102  1.1  mrg 	const char *round = get_round_mode_suffix ();
   5103  1.1  mrg 
   5104  1.1  mrg 	if (trap || round)
   5105  1.1  mrg 	  fprintf (file, "/%s%s", (trap ? trap : ""), (round ? round : ""));
   5106  1.1  mrg 	break;
   5107  1.1  mrg       }
   5108  1.1  mrg 
   5109  1.1  mrg     case ',':
   5110  1.1  mrg       /* Generates single precision suffix for floating point
   5111  1.1  mrg 	 instructions (s for IEEE, f for VAX).  */
   5112  1.1  mrg       fputc ((TARGET_FLOAT_VAX ? 'f' : 's'), file);
   5113  1.1  mrg       break;
   5114  1.1  mrg 
   5115  1.1  mrg     case '-':
   5116  1.1  mrg       /* Generates double precision suffix for floating point
   5117  1.1  mrg 	 instructions (t for IEEE, g for VAX).  */
   5118  1.1  mrg       fputc ((TARGET_FLOAT_VAX ? 'g' : 't'), file);
   5119  1.1  mrg       break;
   5120  1.1  mrg 
   5121  1.1  mrg     case '#':
   5122  1.1  mrg       if (alpha_this_literal_sequence_number == 0)
   5123  1.1  mrg 	alpha_this_literal_sequence_number = alpha_next_sequence_number++;
   5124  1.1  mrg       fprintf (file, "%d", alpha_this_literal_sequence_number);
   5125  1.1  mrg       break;
   5126  1.1  mrg 
   5127  1.1  mrg     case '*':
   5128  1.1  mrg       if (alpha_this_gpdisp_sequence_number == 0)
   5129  1.1  mrg 	alpha_this_gpdisp_sequence_number = alpha_next_sequence_number++;
   5130  1.1  mrg       fprintf (file, "%d", alpha_this_gpdisp_sequence_number);
   5131  1.1  mrg       break;
   5132  1.1  mrg 
   5133  1.1  mrg     case 'J':
   5134  1.1  mrg       {
   5135  1.1  mrg 	const char *lituse;
   5136  1.1  mrg 
   5137  1.1  mrg         if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSGD_CALL)
   5138  1.1  mrg 	  {
   5139  1.1  mrg 	    x = XVECEXP (x, 0, 0);
   5140  1.1  mrg 	    lituse = "lituse_tlsgd";
   5141  1.1  mrg 	  }
   5142  1.1  mrg 	else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == UNSPEC_TLSLDM_CALL)
   5143  1.1  mrg 	  {
   5144  1.1  mrg 	    x = XVECEXP (x, 0, 0);
   5145  1.1  mrg 	    lituse = "lituse_tlsldm";
   5146  1.1  mrg 	  }
   5147  1.1  mrg 	else if (CONST_INT_P (x))
   5148  1.1  mrg 	  lituse = "lituse_jsr";
   5149  1.1  mrg 	else
   5150  1.1  mrg 	  {
   5151  1.1  mrg 	    output_operand_lossage ("invalid %%J value");
   5152  1.1  mrg 	    break;
   5153  1.1  mrg 	  }
   5154  1.1  mrg 
   5155  1.1  mrg 	if (x != const0_rtx)
   5156  1.1  mrg 	  fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
   5157  1.1  mrg       }
   5158  1.1  mrg       break;
   5159  1.1  mrg 
   5160  1.1  mrg     case 'j':
   5161  1.1  mrg       {
   5162  1.1  mrg 	const char *lituse;
   5163  1.1  mrg 
   5164  1.1  mrg #ifdef HAVE_AS_JSRDIRECT_RELOCS
   5165  1.1  mrg 	lituse = "lituse_jsrdirect";
   5166  1.1  mrg #else
   5167  1.1  mrg 	lituse = "lituse_jsr";
   5168  1.1  mrg #endif
   5169  1.1  mrg 
   5170  1.1  mrg 	gcc_assert (INTVAL (x) != 0);
   5171  1.1  mrg 	fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
   5172  1.1  mrg       }
   5173  1.1  mrg       break;
   5174  1.1  mrg     case 'r':
   5175  1.1  mrg       /* If this operand is the constant zero, write it as "$31".  */
   5176  1.1  mrg       if (REG_P (x))
   5177  1.1  mrg 	fprintf (file, "%s", reg_names[REGNO (x)]);
   5178  1.1  mrg       else if (x == CONST0_RTX (GET_MODE (x)))
   5179  1.1  mrg 	fprintf (file, "$31");
   5180  1.1  mrg       else
   5181  1.1  mrg 	output_operand_lossage ("invalid %%r value");
   5182  1.1  mrg       break;
   5183  1.1  mrg 
   5184  1.1  mrg     case 'R':
   5185  1.1  mrg       /* Similar, but for floating-point.  */
   5186  1.1  mrg       if (REG_P (x))
   5187  1.1  mrg 	fprintf (file, "%s", reg_names[REGNO (x)]);
   5188  1.1  mrg       else if (x == CONST0_RTX (GET_MODE (x)))
   5189  1.1  mrg 	fprintf (file, "$f31");
   5190  1.1  mrg       else
   5191  1.1  mrg 	output_operand_lossage ("invalid %%R value");
   5192  1.1  mrg       break;
   5193  1.1  mrg 
   5194  1.1  mrg     case 'N':
   5195  1.1  mrg       /* Write the 1's complement of a constant.  */
   5196  1.1  mrg       if (!CONST_INT_P (x))
   5197  1.1  mrg 	output_operand_lossage ("invalid %%N value");
   5198  1.1  mrg 
   5199  1.1  mrg       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
   5200  1.1  mrg       break;
   5201  1.1  mrg 
   5202  1.1  mrg     case 'P':
   5203  1.1  mrg       /* Write 1 << C, for a constant C.  */
   5204  1.1  mrg       if (!CONST_INT_P (x))
   5205  1.1  mrg 	output_operand_lossage ("invalid %%P value");
   5206  1.1  mrg 
   5207  1.1  mrg       fprintf (file, HOST_WIDE_INT_PRINT_DEC, HOST_WIDE_INT_1 << INTVAL (x));
   5208  1.1  mrg       break;
   5209  1.1  mrg 
   5210  1.1  mrg     case 'h':
   5211  1.1  mrg       /* Write the high-order 16 bits of a constant, sign-extended.  */
   5212  1.1  mrg       if (!CONST_INT_P (x))
   5213  1.1  mrg 	output_operand_lossage ("invalid %%h value");
   5214  1.1  mrg 
   5215  1.1  mrg       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) >> 16);
   5216  1.1  mrg       break;
   5217  1.1  mrg 
   5218  1.1  mrg     case 'L':
   5219  1.1  mrg       /* Write the low-order 16 bits of a constant, sign-extended.  */
   5220  1.1  mrg       if (!CONST_INT_P (x))
   5221  1.1  mrg 	output_operand_lossage ("invalid %%L value");
   5222  1.1  mrg 
   5223  1.1  mrg       fprintf (file, HOST_WIDE_INT_PRINT_DEC,
   5224  1.1  mrg 	       (INTVAL (x) & 0xffff) - 2 * (INTVAL (x) & 0x8000));
   5225  1.1  mrg       break;
   5226  1.1  mrg 
   5227  1.1  mrg     case 'm':
   5228  1.1  mrg       /* Write mask for ZAP insn.  */
   5229  1.1  mrg       if (CONST_INT_P (x))
   5230  1.1  mrg 	{
   5231  1.1  mrg 	  HOST_WIDE_INT mask = 0, value = INTVAL (x);
   5232  1.1  mrg 
   5233  1.1  mrg 	  for (i = 0; i < 8; i++, value >>= 8)
   5234  1.1  mrg 	    if (value & 0xff)
   5235  1.1  mrg 	      mask |= (1 << i);
   5236  1.1  mrg 
   5237  1.1  mrg 	  fprintf (file, HOST_WIDE_INT_PRINT_DEC, mask);
   5238  1.1  mrg 	}
   5239  1.1  mrg       else
   5240  1.1  mrg 	output_operand_lossage ("invalid %%m value");
   5241  1.1  mrg       break;
   5242  1.1  mrg 
   5243  1.1  mrg     case 'M':
   5244  1.1  mrg       /* 'b', 'w', 'l', or 'q' as the value of the constant.  */
   5245  1.1  mrg       if (!mode_width_operand (x, VOIDmode))
   5246  1.1  mrg 	output_operand_lossage ("invalid %%M value");
   5247  1.1  mrg 
   5248  1.1  mrg       fprintf (file, "%s",
   5249  1.1  mrg 	       (INTVAL (x) == 8 ? "b"
   5250  1.1  mrg 		: INTVAL (x) == 16 ? "w"
   5251  1.1  mrg 		: INTVAL (x) == 32 ? "l"
   5252  1.1  mrg 		: "q"));
   5253  1.1  mrg       break;
   5254  1.1  mrg 
   5255  1.1  mrg     case 'U':
   5256  1.1  mrg       /* Similar, except do it from the mask.  */
   5257  1.1  mrg       if (CONST_INT_P (x))
   5258  1.1  mrg 	{
   5259  1.1  mrg 	  HOST_WIDE_INT value = INTVAL (x);
   5260  1.1  mrg 
   5261  1.1  mrg 	  if (value == 0xff)
   5262  1.1  mrg 	    {
   5263  1.1  mrg 	      fputc ('b', file);
   5264  1.1  mrg 	      break;
   5265  1.1  mrg 	    }
   5266  1.1  mrg 	  if (value == 0xffff)
   5267  1.1  mrg 	    {
   5268  1.1  mrg 	      fputc ('w', file);
   5269  1.1  mrg 	      break;
   5270  1.1  mrg 	    }
   5271  1.1  mrg 	  if (value == 0xffffffff)
   5272  1.1  mrg 	    {
   5273  1.1  mrg 	      fputc ('l', file);
   5274  1.1  mrg 	      break;
   5275  1.1  mrg 	    }
   5276  1.1  mrg 	  if (value == -1)
   5277  1.1  mrg 	    {
   5278  1.1  mrg 	      fputc ('q', file);
   5279  1.1  mrg 	      break;
   5280  1.1  mrg 	    }
   5281  1.1  mrg 	}
   5282  1.1  mrg 
   5283  1.1  mrg       output_operand_lossage ("invalid %%U value");
   5284  1.1  mrg       break;
   5285  1.1  mrg 
   5286  1.1  mrg     case 's':
   5287  1.1  mrg       /* Write the constant value divided by 8.  */
   5288  1.1  mrg       if (!CONST_INT_P (x)
   5289  1.1  mrg 	  || (unsigned HOST_WIDE_INT) INTVAL (x) >= 64
   5290  1.1  mrg 	  || (INTVAL (x) & 7) != 0)
   5291  1.1  mrg 	output_operand_lossage ("invalid %%s value");
   5292  1.1  mrg 
   5293  1.1  mrg       fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) / 8);
   5294  1.1  mrg       break;
   5295  1.1  mrg 
   5296  1.1  mrg     case 'C': case 'D': case 'c': case 'd':
   5297  1.1  mrg       /* Write out comparison name.  */
   5298  1.1  mrg       {
   5299  1.1  mrg 	enum rtx_code c = GET_CODE (x);
   5300  1.1  mrg 
   5301  1.1  mrg         if (!COMPARISON_P (x))
   5302  1.1  mrg 	  output_operand_lossage ("invalid %%C value");
   5303  1.1  mrg 
   5304  1.1  mrg 	else if (code == 'D')
   5305  1.1  mrg 	  c = reverse_condition (c);
   5306  1.1  mrg 	else if (code == 'c')
   5307  1.1  mrg 	  c = swap_condition (c);
   5308  1.1  mrg 	else if (code == 'd')
   5309  1.1  mrg 	  c = swap_condition (reverse_condition (c));
   5310  1.1  mrg 
   5311  1.1  mrg         if (c == LEU)
   5312  1.1  mrg 	  fprintf (file, "ule");
   5313  1.1  mrg         else if (c == LTU)
   5314  1.1  mrg 	  fprintf (file, "ult");
   5315  1.1  mrg 	else if (c == UNORDERED)
   5316  1.1  mrg 	  fprintf (file, "un");
   5317  1.1  mrg         else
   5318  1.1  mrg 	  fprintf (file, "%s", GET_RTX_NAME (c));
   5319  1.1  mrg       }
   5320  1.1  mrg       break;
   5321  1.1  mrg 
   5322  1.1  mrg     case 'E':
   5323  1.1  mrg       /* Write the divide or modulus operator.  */
   5324  1.1  mrg       switch (GET_CODE (x))
   5325  1.1  mrg 	{
   5326  1.1  mrg 	case DIV:
   5327  1.1  mrg 	  fprintf (file, "div%s", GET_MODE (x) == SImode ? "l" : "q");
   5328  1.1  mrg 	  break;
   5329  1.1  mrg 	case UDIV:
   5330  1.1  mrg 	  fprintf (file, "div%su", GET_MODE (x) == SImode ? "l" : "q");
   5331  1.1  mrg 	  break;
   5332  1.1  mrg 	case MOD:
   5333  1.1  mrg 	  fprintf (file, "rem%s", GET_MODE (x) == SImode ? "l" : "q");
   5334  1.1  mrg 	  break;
   5335  1.1  mrg 	case UMOD:
   5336  1.1  mrg 	  fprintf (file, "rem%su", GET_MODE (x) == SImode ? "l" : "q");
   5337  1.1  mrg 	  break;
   5338  1.1  mrg 	default:
   5339  1.1  mrg 	  output_operand_lossage ("invalid %%E value");
   5340  1.1  mrg 	  break;
   5341  1.1  mrg 	}
   5342  1.1  mrg       break;
   5343  1.1  mrg 
   5344  1.1  mrg     case 'A':
   5345  1.1  mrg       /* Write "_u" for unaligned access.  */
   5346  1.1  mrg       if (MEM_P (x) && GET_CODE (XEXP (x, 0)) == AND)
   5347  1.1  mrg 	fprintf (file, "_u");
   5348  1.1  mrg       break;
   5349  1.1  mrg 
   5350  1.1  mrg     case 0:
   5351  1.1  mrg       if (REG_P (x))
   5352  1.1  mrg 	fprintf (file, "%s", reg_names[REGNO (x)]);
   5353  1.1  mrg       else if (MEM_P (x))
   5354  1.1  mrg 	output_address (GET_MODE (x), XEXP (x, 0));
   5355  1.1  mrg       else if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == UNSPEC)
   5356  1.1  mrg 	{
   5357  1.1  mrg 	  switch (XINT (XEXP (x, 0), 1))
   5358  1.1  mrg 	    {
   5359  1.1  mrg 	    case UNSPEC_DTPREL:
   5360  1.1  mrg 	    case UNSPEC_TPREL:
   5361  1.1  mrg 	      output_addr_const (file, XVECEXP (XEXP (x, 0), 0, 0));
   5362  1.1  mrg 	      break;
   5363  1.1  mrg 	    default:
   5364  1.1  mrg 	      output_operand_lossage ("unknown relocation unspec");
   5365  1.1  mrg 	      break;
   5366  1.1  mrg 	    }
   5367  1.1  mrg 	}
   5368  1.1  mrg       else
   5369  1.1  mrg 	output_addr_const (file, x);
   5370  1.1  mrg       break;
   5371  1.1  mrg 
   5372  1.1  mrg     default:
   5373  1.1  mrg       output_operand_lossage ("invalid %%xn code");
   5374  1.1  mrg     }
   5375  1.1  mrg }
   5376  1.1  mrg 
   5377  1.1  mrg /* Implement TARGET_PRINT_OPERAND_ADDRESS.  */
   5378  1.1  mrg 
   5379  1.1  mrg static void
   5380  1.1  mrg alpha_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
   5381  1.1  mrg {
   5382  1.1  mrg   int basereg = 31;
   5383  1.1  mrg   HOST_WIDE_INT offset = 0;
   5384  1.1  mrg 
   5385  1.1  mrg   if (GET_CODE (addr) == AND)
   5386  1.1  mrg     addr = XEXP (addr, 0);
   5387  1.1  mrg 
   5388  1.1  mrg   if (GET_CODE (addr) == PLUS
   5389  1.1  mrg       && CONST_INT_P (XEXP (addr, 1)))
   5390  1.1  mrg     {
   5391  1.1  mrg       offset = INTVAL (XEXP (addr, 1));
   5392  1.1  mrg       addr = XEXP (addr, 0);
   5393  1.1  mrg     }
   5394  1.1  mrg 
   5395  1.1  mrg   if (GET_CODE (addr) == LO_SUM)
   5396  1.1  mrg     {
   5397  1.1  mrg       const char *reloc16, *reloclo;
   5398  1.1  mrg       rtx op1 = XEXP (addr, 1);
   5399  1.1  mrg 
   5400  1.1  mrg       if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == UNSPEC)
   5401  1.1  mrg 	{
   5402  1.1  mrg 	  op1 = XEXP (op1, 0);
   5403  1.1  mrg 	  switch (XINT (op1, 1))
   5404  1.1  mrg 	    {
   5405  1.1  mrg 	    case UNSPEC_DTPREL:
   5406  1.1  mrg 	      reloc16 = NULL;
   5407  1.1  mrg 	      reloclo = (alpha_tls_size == 16 ? "dtprel" : "dtprello");
   5408  1.1  mrg 	      break;
   5409  1.1  mrg 	    case UNSPEC_TPREL:
   5410  1.1  mrg 	      reloc16 = NULL;
   5411  1.1  mrg 	      reloclo = (alpha_tls_size == 16 ? "tprel" : "tprello");
   5412  1.1  mrg 	      break;
   5413  1.1  mrg 	    default:
   5414  1.1  mrg 	      output_operand_lossage ("unknown relocation unspec");
   5415  1.1  mrg 	      return;
   5416  1.1  mrg 	    }
   5417  1.1  mrg 
   5418  1.1  mrg 	  output_addr_const (file, XVECEXP (op1, 0, 0));
   5419  1.1  mrg 	}
   5420  1.1  mrg       else
   5421  1.1  mrg 	{
   5422  1.1  mrg 	  reloc16 = "gprel";
   5423  1.1  mrg 	  reloclo = "gprellow";
   5424  1.1  mrg 	  output_addr_const (file, op1);
   5425  1.1  mrg 	}
   5426  1.1  mrg 
   5427  1.1  mrg       if (offset)
   5428  1.1  mrg 	fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
   5429  1.1  mrg 
   5430  1.1  mrg       addr = XEXP (addr, 0);
   5431  1.1  mrg       switch (GET_CODE (addr))
   5432  1.1  mrg 	{
   5433  1.1  mrg 	case REG:
   5434  1.1  mrg 	  basereg = REGNO (addr);
   5435  1.1  mrg 	  break;
   5436  1.1  mrg 
   5437  1.1  mrg 	case SUBREG:
   5438  1.1  mrg 	  basereg = subreg_regno (addr);
   5439  1.1  mrg 	  break;
   5440  1.1  mrg 
   5441  1.1  mrg 	default:
   5442  1.1  mrg 	  gcc_unreachable ();
   5443  1.1  mrg 	}
   5444  1.1  mrg 
   5445  1.1  mrg       fprintf (file, "($%d)\t\t!%s", basereg,
   5446  1.1  mrg 	       (basereg == 29 ? reloc16 : reloclo));
   5447  1.1  mrg       return;
   5448  1.1  mrg     }
   5449  1.1  mrg 
   5450  1.1  mrg   switch (GET_CODE (addr))
   5451  1.1  mrg     {
   5452  1.1  mrg     case REG:
   5453  1.1  mrg       basereg = REGNO (addr);
   5454  1.1  mrg       break;
   5455  1.1  mrg 
   5456  1.1  mrg     case SUBREG:
   5457  1.1  mrg       basereg = subreg_regno (addr);
   5458  1.1  mrg       break;
   5459  1.1  mrg 
   5460  1.1  mrg     case CONST_INT:
   5461  1.1  mrg       offset = INTVAL (addr);
   5462  1.1  mrg       break;
   5463  1.1  mrg 
   5464  1.1  mrg     case SYMBOL_REF:
   5465  1.1  mrg       gcc_assert(TARGET_ABI_OPEN_VMS || this_is_asm_operands);
   5466  1.1  mrg       fprintf (file, "%s", XSTR (addr, 0));
   5467  1.1  mrg       return;
   5468  1.1  mrg 
   5469  1.1  mrg     case CONST:
   5470  1.1  mrg       gcc_assert(TARGET_ABI_OPEN_VMS || this_is_asm_operands);
   5471  1.1  mrg       gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS
   5472  1.1  mrg 		  && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF);
   5473  1.1  mrg       fprintf (file, "%s+" HOST_WIDE_INT_PRINT_DEC,
   5474  1.1  mrg 	       XSTR (XEXP (XEXP (addr, 0), 0), 0),
   5475  1.1  mrg 	       INTVAL (XEXP (XEXP (addr, 0), 1)));
   5476  1.1  mrg       return;
   5477  1.1  mrg 
   5478  1.1  mrg     default:
   5479  1.1  mrg       output_operand_lossage ("invalid operand address");
   5480  1.1  mrg       return;
   5481  1.1  mrg     }
   5482  1.1  mrg 
   5483  1.1  mrg   fprintf (file, HOST_WIDE_INT_PRINT_DEC "($%d)", offset, basereg);
   5484  1.1  mrg }
   5485  1.1  mrg 
   5486  1.1  mrg /* Emit RTL insns to initialize the variable parts of a trampoline at
   5488  1.1  mrg    M_TRAMP.  FNDECL is target function's decl.  CHAIN_VALUE is an rtx
   5489  1.1  mrg    for the static chain value for the function.  */
   5490  1.1  mrg 
   5491  1.1  mrg static void
   5492  1.1  mrg alpha_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   5493  1.1  mrg {
   5494  1.1  mrg   rtx fnaddr, mem, word1, word2;
   5495  1.1  mrg 
   5496  1.1  mrg   fnaddr = XEXP (DECL_RTL (fndecl), 0);
   5497  1.1  mrg 
   5498  1.1  mrg #ifdef POINTERS_EXTEND_UNSIGNED
   5499  1.1  mrg   fnaddr = convert_memory_address (Pmode, fnaddr);
   5500  1.1  mrg   chain_value = convert_memory_address (Pmode, chain_value);
   5501  1.1  mrg #endif
   5502  1.1  mrg 
   5503  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   5504  1.1  mrg     {
   5505  1.1  mrg       const char *fnname;
   5506  1.1  mrg       char *trname;
   5507  1.1  mrg 
   5508  1.1  mrg       /* Construct the name of the trampoline entry point.  */
   5509  1.1  mrg       fnname = XSTR (fnaddr, 0);
   5510  1.1  mrg       trname = (char *) alloca (strlen (fnname) + 5);
   5511  1.1  mrg       strcpy (trname, fnname);
   5512  1.1  mrg       strcat (trname, "..tr");
   5513  1.1  mrg       fnname = ggc_alloc_string (trname, strlen (trname) + 1);
   5514  1.1  mrg       word2 = gen_rtx_SYMBOL_REF (Pmode, fnname);
   5515  1.1  mrg 
   5516  1.1  mrg       /* Trampoline (or "bounded") procedure descriptor is constructed from
   5517  1.1  mrg 	 the function's procedure descriptor with certain fields zeroed IAW
   5518  1.1  mrg 	 the VMS calling standard. This is stored in the first quadword.  */
   5519  1.1  mrg       word1 = force_reg (DImode, gen_const_mem (DImode, fnaddr));
   5520  1.1  mrg       word1 = expand_and (DImode, word1,
   5521  1.1  mrg 			  GEN_INT (HOST_WIDE_INT_C (0xffff0fff0000fff0)),
   5522  1.1  mrg 			  NULL);
   5523  1.1  mrg     }
   5524  1.1  mrg   else
   5525  1.1  mrg     {
   5526  1.1  mrg       /* These 4 instructions are:
   5527  1.1  mrg 	    ldq $1,24($27)
   5528  1.1  mrg 	    ldq $27,16($27)
   5529  1.1  mrg 	    jmp $31,($27),0
   5530  1.1  mrg 	    nop
   5531  1.1  mrg 	 We don't bother setting the HINT field of the jump; the nop
   5532  1.1  mrg 	 is merely there for padding.  */
   5533  1.1  mrg       word1 = GEN_INT (HOST_WIDE_INT_C (0xa77b0010a43b0018));
   5534  1.1  mrg       word2 = GEN_INT (HOST_WIDE_INT_C (0x47ff041f6bfb0000));
   5535  1.1  mrg     }
   5536  1.1  mrg 
   5537  1.1  mrg   /* Store the first two words, as computed above.  */
   5538  1.1  mrg   mem = adjust_address (m_tramp, DImode, 0);
   5539  1.1  mrg   emit_move_insn (mem, word1);
   5540  1.1  mrg   mem = adjust_address (m_tramp, DImode, 8);
   5541  1.1  mrg   emit_move_insn (mem, word2);
   5542  1.1  mrg 
   5543  1.1  mrg   /* Store function address and static chain value.  */
   5544  1.1  mrg   mem = adjust_address (m_tramp, Pmode, 16);
   5545  1.1  mrg   emit_move_insn (mem, fnaddr);
   5546  1.1  mrg   mem = adjust_address (m_tramp, Pmode, 24);
   5547  1.1  mrg   emit_move_insn (mem, chain_value);
   5548  1.1  mrg 
   5549  1.1  mrg   if (TARGET_ABI_OSF)
   5550  1.1  mrg     {
   5551  1.1  mrg       emit_insn (gen_imb ());
   5552  1.1  mrg #ifdef HAVE_ENABLE_EXECUTE_STACK
   5553  1.1  mrg       emit_library_call (init_one_libfunc ("__enable_execute_stack"),
   5554  1.1  mrg 			 LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
   5555  1.1  mrg #endif
   5556  1.1  mrg     }
   5557  1.1  mrg }
   5558  1.1  mrg 
   5559  1.1  mrg /* Determine where to put an argument to a function.
   5561  1.1  mrg    Value is zero to push the argument on the stack,
   5562  1.1  mrg    or a hard register in which to store the argument.
   5563  1.1  mrg 
   5564  1.1  mrg    CUM is a variable of type CUMULATIVE_ARGS which gives info about
   5565  1.1  mrg     the preceding args and about the function being called.
   5566  1.1  mrg    ARG is a description of the argument.
   5567  1.1  mrg 
   5568  1.1  mrg    On Alpha the first 6 words of args are normally in registers
   5569  1.1  mrg    and the rest are pushed.  */
   5570  1.1  mrg 
   5571  1.1  mrg static rtx
   5572  1.1  mrg alpha_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
   5573  1.1  mrg {
   5574  1.1  mrg   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   5575  1.1  mrg   int basereg;
   5576  1.1  mrg   int num_args;
   5577  1.1  mrg 
   5578  1.1  mrg   /* Don't get confused and pass small structures in FP registers.  */
   5579  1.1  mrg   if (arg.aggregate_type_p ())
   5580  1.1  mrg     basereg = 16;
   5581  1.1  mrg   else
   5582  1.1  mrg     {
   5583  1.1  mrg       /* With alpha_split_complex_arg, we shouldn't see any raw complex
   5584  1.1  mrg 	 values here.  */
   5585  1.1  mrg       gcc_checking_assert (!COMPLEX_MODE_P (arg.mode));
   5586  1.1  mrg 
   5587  1.1  mrg       /* Set up defaults for FP operands passed in FP registers, and
   5588  1.1  mrg 	 integral operands passed in integer registers.  */
   5589  1.1  mrg       if (TARGET_FPREGS && GET_MODE_CLASS (arg.mode) == MODE_FLOAT)
   5590  1.1  mrg 	basereg = 32 + 16;
   5591  1.1  mrg       else
   5592  1.1  mrg 	basereg = 16;
   5593  1.1  mrg     }
   5594  1.1  mrg 
   5595  1.1  mrg   /* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
   5596  1.1  mrg      the two platforms, so we can't avoid conditional compilation.  */
   5597  1.1  mrg #if TARGET_ABI_OPEN_VMS
   5598  1.1  mrg     {
   5599  1.1  mrg       if (arg.end_marker_p ())
   5600  1.1  mrg 	return alpha_arg_info_reg_val (*cum);
   5601  1.1  mrg 
   5602  1.1  mrg       num_args = cum->num_args;
   5603  1.1  mrg       if (num_args >= 6
   5604  1.1  mrg 	  || targetm.calls.must_pass_in_stack (arg))
   5605  1.1  mrg 	return NULL_RTX;
   5606  1.1  mrg     }
   5607  1.1  mrg #elif TARGET_ABI_OSF
   5608  1.1  mrg     {
   5609  1.1  mrg       if (*cum >= 6)
   5610  1.1  mrg 	return NULL_RTX;
   5611  1.1  mrg       num_args = *cum;
   5612  1.1  mrg 
   5613  1.1  mrg       if (arg.end_marker_p ())
   5614  1.1  mrg 	basereg = 16;
   5615  1.1  mrg       else if (targetm.calls.must_pass_in_stack (arg))
   5616  1.1  mrg 	return NULL_RTX;
   5617  1.1  mrg     }
   5618  1.1  mrg #else
   5619  1.1  mrg #error Unhandled ABI
   5620  1.1  mrg #endif
   5621  1.1  mrg 
   5622  1.1  mrg   return gen_rtx_REG (arg.mode, num_args + basereg);
   5623  1.1  mrg }
   5624  1.1  mrg 
   5625  1.1  mrg /* Update the data in CUM to advance over argument ARG.  */
   5626  1.1  mrg 
   5627  1.1  mrg static void
   5628  1.1  mrg alpha_function_arg_advance (cumulative_args_t cum_v,
   5629  1.1  mrg 			    const function_arg_info &arg)
   5630  1.1  mrg {
   5631  1.1  mrg   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   5632  1.1  mrg   bool onstack = targetm.calls.must_pass_in_stack (arg);
   5633  1.1  mrg   int increment = onstack ? 6 : ALPHA_ARG_SIZE (arg.mode, arg.type);
   5634  1.1  mrg 
   5635  1.1  mrg #if TARGET_ABI_OSF
   5636  1.1  mrg   *cum += increment;
   5637  1.1  mrg #else
   5638  1.1  mrg   if (!onstack && cum->num_args < 6)
   5639  1.1  mrg     cum->atypes[cum->num_args] = alpha_arg_type (arg.mode);
   5640  1.1  mrg   cum->num_args += increment;
   5641  1.1  mrg #endif
   5642  1.1  mrg }
   5643  1.1  mrg 
   5644  1.1  mrg static int
   5645  1.1  mrg alpha_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
   5646  1.1  mrg {
   5647  1.1  mrg   int words = 0;
   5648  1.1  mrg   CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED = get_cumulative_args (cum_v);
   5649  1.1  mrg 
   5650  1.1  mrg #if TARGET_ABI_OPEN_VMS
   5651  1.1  mrg   if (cum->num_args < 6
   5652  1.1  mrg       && 6 < cum->num_args + ALPHA_ARG_SIZE (arg.mode, arg.type))
   5653  1.1  mrg     words = 6 - cum->num_args;
   5654  1.1  mrg #elif TARGET_ABI_OSF
   5655  1.1  mrg   if (*cum < 6 && 6 < *cum + ALPHA_ARG_SIZE (arg.mode, arg.type))
   5656  1.1  mrg     words = 6 - *cum;
   5657  1.1  mrg #else
   5658  1.1  mrg #error Unhandled ABI
   5659  1.1  mrg #endif
   5660  1.1  mrg 
   5661  1.1  mrg   return words * UNITS_PER_WORD;
   5662  1.1  mrg }
   5663  1.1  mrg 
   5664  1.1  mrg 
   5665  1.1  mrg /* Return true if TYPE must be returned in memory, instead of in registers.  */
   5666  1.1  mrg 
   5667  1.1  mrg static bool
   5668  1.1  mrg alpha_return_in_memory (const_tree type, const_tree fndecl ATTRIBUTE_UNUSED)
   5669  1.1  mrg {
   5670  1.1  mrg   machine_mode mode = VOIDmode;
   5671  1.1  mrg   int size;
   5672  1.1  mrg 
   5673  1.1  mrg   if (type)
   5674  1.1  mrg     {
   5675  1.1  mrg       mode = TYPE_MODE (type);
   5676  1.1  mrg 
   5677  1.1  mrg       /* All aggregates are returned in memory, except on OpenVMS where
   5678  1.1  mrg 	 records that fit 64 bits should be returned by immediate value
   5679  1.1  mrg 	 as required by section 3.8.7.1 of the OpenVMS Calling Standard.  */
   5680  1.1  mrg       if (TARGET_ABI_OPEN_VMS
   5681  1.1  mrg 	  && TREE_CODE (type) != ARRAY_TYPE
   5682  1.1  mrg 	  && (unsigned HOST_WIDE_INT) int_size_in_bytes(type) <= 8)
   5683  1.1  mrg 	return false;
   5684  1.1  mrg 
   5685  1.1  mrg       if (AGGREGATE_TYPE_P (type))
   5686  1.1  mrg 	return true;
   5687  1.1  mrg     }
   5688  1.1  mrg 
   5689  1.1  mrg   size = GET_MODE_SIZE (mode);
   5690  1.1  mrg   switch (GET_MODE_CLASS (mode))
   5691  1.1  mrg     {
   5692  1.1  mrg     case MODE_VECTOR_FLOAT:
   5693  1.1  mrg       /* Pass all float vectors in memory, like an aggregate.  */
   5694  1.1  mrg       return true;
   5695  1.1  mrg 
   5696  1.1  mrg     case MODE_COMPLEX_FLOAT:
   5697  1.1  mrg       /* We judge complex floats on the size of their element,
   5698  1.1  mrg 	 not the size of the whole type.  */
   5699  1.1  mrg       size = GET_MODE_UNIT_SIZE (mode);
   5700  1.1  mrg       break;
   5701  1.1  mrg 
   5702  1.1  mrg     case MODE_INT:
   5703  1.1  mrg     case MODE_FLOAT:
   5704  1.1  mrg     case MODE_COMPLEX_INT:
   5705  1.1  mrg     case MODE_VECTOR_INT:
   5706  1.1  mrg       break;
   5707  1.1  mrg 
   5708  1.1  mrg     default:
   5709  1.1  mrg       /* ??? We get called on all sorts of random stuff from
   5710  1.1  mrg 	 aggregate_value_p.  We must return something, but it's not
   5711  1.1  mrg 	 clear what's safe to return.  Pretend it's a struct I
   5712  1.1  mrg 	 guess.  */
   5713  1.1  mrg       return true;
   5714  1.1  mrg     }
   5715  1.1  mrg 
   5716  1.1  mrg   /* Otherwise types must fit in one register.  */
   5717  1.1  mrg   return size > UNITS_PER_WORD;
   5718  1.1  mrg }
   5719  1.1  mrg 
   5720  1.1  mrg /* Return true if ARG should be passed by invisible reference.  */
   5721  1.1  mrg 
   5722  1.1  mrg static bool
   5723  1.1  mrg alpha_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
   5724  1.1  mrg {
   5725  1.1  mrg   /* Pass float and _Complex float variable arguments by reference.
   5726  1.1  mrg      This avoids 64-bit store from a FP register to a pretend args save area
   5727  1.1  mrg      and subsequent 32-bit load from the saved location to a FP register.
   5728  1.1  mrg 
   5729  1.1  mrg      Note that 32-bit loads and stores to/from a FP register on alpha reorder
   5730  1.1  mrg      bits to form a canonical 64-bit value in the FP register.  This fact
   5731  1.1  mrg      invalidates compiler assumption that 32-bit FP value lives in the lower
   5732  1.1  mrg      32-bits of the passed 64-bit FP value, so loading the 32-bit value from
   5733  1.1  mrg      the stored 64-bit location using 32-bit FP load is invalid on alpha.
   5734  1.1  mrg 
   5735  1.1  mrg      This introduces sort of ABI incompatibility, but until _Float32 was
   5736  1.1  mrg      introduced, C-family languages promoted 32-bit float variable arg to
   5737  1.1  mrg      a 64-bit double, and it was not allowed to pass float as a varible
   5738  1.1  mrg      argument.  Passing _Complex float as a variable argument never
   5739  1.1  mrg      worked on alpha.  Thus, we have no backward compatibility issues
   5740  1.1  mrg      to worry about, and passing unpromoted _Float32 and _Complex float
   5741  1.1  mrg      as a variable argument will actually work in the future.  */
   5742  1.1  mrg 
   5743  1.1  mrg   if (arg.mode == SFmode || arg.mode == SCmode)
   5744  1.1  mrg     return !arg.named;
   5745  1.1  mrg 
   5746  1.1  mrg   return arg.mode == TFmode || arg.mode == TCmode;
   5747  1.1  mrg }
   5748  1.1  mrg 
   5749  1.1  mrg /* Define how to find the value returned by a function.  VALTYPE is the
   5750  1.1  mrg    data type of the value (as a tree).  If the precise function being
   5751  1.1  mrg    called is known, FUNC is its FUNCTION_DECL; otherwise, FUNC is 0.
   5752  1.1  mrg    MODE is set instead of VALTYPE for libcalls.
   5753  1.1  mrg 
   5754  1.1  mrg    On Alpha the value is found in $0 for integer functions and
   5755  1.1  mrg    $f0 for floating-point functions.  */
   5756  1.1  mrg 
   5757  1.1  mrg static rtx
   5758  1.1  mrg alpha_function_value_1 (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
   5759  1.1  mrg 			machine_mode mode)
   5760  1.1  mrg {
   5761  1.1  mrg   unsigned int regnum, dummy ATTRIBUTE_UNUSED;
   5762  1.1  mrg   enum mode_class mclass;
   5763  1.1  mrg 
   5764  1.1  mrg   gcc_assert (!valtype || !alpha_return_in_memory (valtype, func));
   5765  1.1  mrg 
   5766  1.1  mrg   if (valtype)
   5767  1.1  mrg     mode = TYPE_MODE (valtype);
   5768  1.1  mrg 
   5769  1.1  mrg   mclass = GET_MODE_CLASS (mode);
   5770  1.1  mrg   switch (mclass)
   5771  1.1  mrg     {
   5772  1.1  mrg     case MODE_INT:
   5773  1.1  mrg       /* Do the same thing as PROMOTE_MODE except for libcalls on VMS,
   5774  1.1  mrg 	 where we have them returning both SImode and DImode.  */
   5775  1.1  mrg       if (!(TARGET_ABI_OPEN_VMS && valtype && AGGREGATE_TYPE_P (valtype)))
   5776  1.1  mrg         PROMOTE_MODE (mode, dummy, valtype);
   5777  1.1  mrg       /* FALLTHRU */
   5778  1.1  mrg 
   5779  1.1  mrg     case MODE_COMPLEX_INT:
   5780  1.1  mrg     case MODE_VECTOR_INT:
   5781  1.1  mrg       regnum = 0;
   5782  1.1  mrg       break;
   5783  1.1  mrg 
   5784  1.1  mrg     case MODE_FLOAT:
   5785  1.1  mrg       regnum = 32;
   5786  1.1  mrg       break;
   5787  1.1  mrg 
   5788  1.1  mrg     case MODE_COMPLEX_FLOAT:
   5789  1.1  mrg       {
   5790  1.1  mrg 	machine_mode cmode = GET_MODE_INNER (mode);
   5791  1.1  mrg 
   5792  1.1  mrg 	return gen_rtx_PARALLEL
   5793  1.1  mrg 	  (VOIDmode,
   5794  1.1  mrg 	   gen_rtvec (2,
   5795  1.1  mrg 		      gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 32),
   5796  1.1  mrg 				         const0_rtx),
   5797  1.1  mrg 		      gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_REG (cmode, 33),
   5798  1.1  mrg 				         GEN_INT (GET_MODE_SIZE (cmode)))));
   5799  1.1  mrg       }
   5800  1.1  mrg 
   5801  1.1  mrg     case MODE_RANDOM:
   5802  1.1  mrg       /* We should only reach here for BLKmode on VMS.  */
   5803  1.1  mrg       gcc_assert (TARGET_ABI_OPEN_VMS && mode == BLKmode);
   5804  1.1  mrg       regnum = 0;
   5805  1.1  mrg       break;
   5806  1.1  mrg 
   5807  1.1  mrg     default:
   5808  1.1  mrg       gcc_unreachable ();
   5809  1.1  mrg     }
   5810  1.1  mrg 
   5811  1.1  mrg   return gen_rtx_REG (mode, regnum);
   5812  1.1  mrg }
   5813  1.1  mrg 
   5814  1.1  mrg /* Implement TARGET_FUNCTION_VALUE.  */
   5815  1.1  mrg 
   5816  1.1  mrg static rtx
   5817  1.1  mrg alpha_function_value (const_tree valtype, const_tree fn_decl_or_type,
   5818  1.1  mrg 		      bool /*outgoing*/)
   5819  1.1  mrg {
   5820  1.1  mrg   return alpha_function_value_1 (valtype, fn_decl_or_type, VOIDmode);
   5821  1.1  mrg }
   5822  1.1  mrg 
   5823  1.1  mrg /* Implement TARGET_LIBCALL_VALUE.  */
   5824  1.1  mrg 
   5825  1.1  mrg static rtx
   5826  1.1  mrg alpha_libcall_value (machine_mode mode, const_rtx /*fun*/)
   5827  1.1  mrg {
   5828  1.1  mrg   return alpha_function_value_1 (NULL_TREE, NULL_TREE, mode);
   5829  1.1  mrg }
   5830  1.1  mrg 
   5831  1.1  mrg /* Implement TARGET_FUNCTION_VALUE_REGNO_P.
   5832  1.1  mrg 
   5833  1.1  mrg    On the Alpha, $0 $1 and $f0 $f1 are the only register thus used.  */
   5834  1.1  mrg 
   5835  1.1  mrg static bool
   5836  1.1  mrg alpha_function_value_regno_p (const unsigned int regno)
   5837  1.1  mrg {
   5838  1.1  mrg   return (regno == 0 || regno == 1 || regno == 32 || regno == 33);
   5839  1.1  mrg }
   5840  1.1  mrg 
   5841  1.1  mrg /* TCmode complex values are passed by invisible reference.  We
   5842  1.1  mrg    should not split these values.  */
   5843  1.1  mrg 
   5844  1.1  mrg static bool
   5845  1.1  mrg alpha_split_complex_arg (const_tree type)
   5846  1.1  mrg {
   5847  1.1  mrg   return TYPE_MODE (type) != TCmode;
   5848  1.1  mrg }
   5849  1.1  mrg 
   5850  1.1  mrg static tree
   5851  1.1  mrg alpha_build_builtin_va_list (void)
   5852  1.1  mrg {
   5853  1.1  mrg   tree base, ofs, space, record, type_decl;
   5854  1.1  mrg 
   5855  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   5856  1.1  mrg     return ptr_type_node;
   5857  1.1  mrg 
   5858  1.1  mrg   record = (*lang_hooks.types.make_type) (RECORD_TYPE);
   5859  1.1  mrg   type_decl = build_decl (BUILTINS_LOCATION,
   5860  1.1  mrg 			  TYPE_DECL, get_identifier ("__va_list_tag"), record);
   5861  1.1  mrg   TYPE_STUB_DECL (record) = type_decl;
   5862  1.1  mrg   TYPE_NAME (record) = type_decl;
   5863  1.1  mrg 
   5864  1.1  mrg   /* C++? SET_IS_AGGR_TYPE (record, 1); */
   5865  1.1  mrg 
   5866  1.1  mrg   /* Dummy field to prevent alignment warnings.  */
   5867  1.1  mrg   space = build_decl (BUILTINS_LOCATION,
   5868  1.1  mrg 		      FIELD_DECL, NULL_TREE, integer_type_node);
   5869  1.1  mrg   DECL_FIELD_CONTEXT (space) = record;
   5870  1.1  mrg   DECL_ARTIFICIAL (space) = 1;
   5871  1.1  mrg   DECL_IGNORED_P (space) = 1;
   5872  1.1  mrg 
   5873  1.1  mrg   ofs = build_decl (BUILTINS_LOCATION,
   5874  1.1  mrg 		    FIELD_DECL, get_identifier ("__offset"),
   5875  1.1  mrg 		    integer_type_node);
   5876  1.1  mrg   DECL_FIELD_CONTEXT (ofs) = record;
   5877  1.1  mrg   DECL_CHAIN (ofs) = space;
   5878  1.1  mrg 
   5879  1.1  mrg   base = build_decl (BUILTINS_LOCATION,
   5880  1.1  mrg 		     FIELD_DECL, get_identifier ("__base"),
   5881  1.1  mrg 		     ptr_type_node);
   5882  1.1  mrg   DECL_FIELD_CONTEXT (base) = record;
   5883  1.1  mrg   DECL_CHAIN (base) = ofs;
   5884  1.1  mrg 
   5885  1.1  mrg   TYPE_FIELDS (record) = base;
   5886  1.1  mrg   layout_type (record);
   5887  1.1  mrg 
   5888  1.1  mrg   va_list_gpr_counter_field = ofs;
   5889  1.1  mrg   return record;
   5890  1.1  mrg }
   5891  1.1  mrg 
   5892  1.1  mrg #if TARGET_ABI_OSF
   5893  1.1  mrg /* Helper function for alpha_stdarg_optimize_hook.  Skip over casts
   5894  1.1  mrg    and constant additions.  */
   5895  1.1  mrg 
   5896  1.1  mrg static gimple *
   5897  1.1  mrg va_list_skip_additions (tree lhs)
   5898  1.1  mrg {
   5899  1.1  mrg   gimple  *stmt;
   5900  1.1  mrg 
   5901  1.1  mrg   for (;;)
   5902  1.1  mrg     {
   5903  1.1  mrg       enum tree_code code;
   5904  1.1  mrg 
   5905  1.1  mrg       stmt = SSA_NAME_DEF_STMT (lhs);
   5906  1.1  mrg 
   5907  1.1  mrg       if (gimple_code (stmt) == GIMPLE_PHI)
   5908  1.1  mrg 	return stmt;
   5909  1.1  mrg 
   5910  1.1  mrg       if (!is_gimple_assign (stmt)
   5911  1.1  mrg 	  || gimple_assign_lhs (stmt) != lhs)
   5912  1.1  mrg 	return NULL;
   5913  1.1  mrg 
   5914  1.1  mrg       if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
   5915  1.1  mrg 	return stmt;
   5916  1.1  mrg       code = gimple_assign_rhs_code (stmt);
   5917  1.1  mrg       if (!CONVERT_EXPR_CODE_P (code)
   5918  1.1  mrg 	  && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
   5919  1.1  mrg 	      || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
   5920  1.1  mrg 	      || !tree_fits_uhwi_p (gimple_assign_rhs2 (stmt))))
   5921  1.1  mrg 	return stmt;
   5922  1.1  mrg 
   5923  1.1  mrg       lhs = gimple_assign_rhs1 (stmt);
   5924  1.1  mrg     }
   5925  1.1  mrg }
   5926  1.1  mrg 
   5927  1.1  mrg /* Check if LHS = RHS statement is
   5928  1.1  mrg    LHS = *(ap.__base + ap.__offset + cst)
   5929  1.1  mrg    or
   5930  1.1  mrg    LHS = *(ap.__base
   5931  1.1  mrg 	   + ((ap.__offset + cst <= 47)
   5932  1.1  mrg 	      ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2).
   5933  1.1  mrg    If the former, indicate that GPR registers are needed,
   5934  1.1  mrg    if the latter, indicate that FPR registers are needed.
   5935  1.1  mrg 
   5936  1.1  mrg    Also look for LHS = (*ptr).field, where ptr is one of the forms
   5937  1.1  mrg    listed above.
   5938  1.1  mrg 
   5939  1.1  mrg    On alpha, cfun->va_list_gpr_size is used as size of the needed
   5940  1.1  mrg    regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR
   5941  1.1  mrg    registers are needed and bit 1 set if FPR registers are needed.
   5942  1.1  mrg    Return true if va_list references should not be scanned for the
   5943  1.1  mrg    current statement.  */
   5944  1.1  mrg 
   5945  1.1  mrg static bool
   5946  1.1  mrg alpha_stdarg_optimize_hook (struct stdarg_info *si, const gimple *stmt)
   5947  1.1  mrg {
   5948  1.1  mrg   tree base, offset, rhs;
   5949  1.1  mrg   int offset_arg = 1;
   5950  1.1  mrg   gimple *base_stmt;
   5951  1.1  mrg 
   5952  1.1  mrg   if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
   5953  1.1  mrg       != GIMPLE_SINGLE_RHS)
   5954  1.1  mrg     return false;
   5955  1.1  mrg 
   5956  1.1  mrg   rhs = gimple_assign_rhs1 (stmt);
   5957  1.1  mrg   while (handled_component_p (rhs))
   5958  1.1  mrg     rhs = TREE_OPERAND (rhs, 0);
   5959  1.1  mrg   if (TREE_CODE (rhs) != MEM_REF
   5960  1.1  mrg       || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
   5961  1.1  mrg     return false;
   5962  1.1  mrg 
   5963  1.1  mrg   stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0));
   5964  1.1  mrg   if (stmt == NULL
   5965  1.1  mrg       || !is_gimple_assign (stmt)
   5966  1.1  mrg       || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
   5967  1.1  mrg     return false;
   5968  1.1  mrg 
   5969  1.1  mrg   base = gimple_assign_rhs1 (stmt);
   5970  1.1  mrg   if (TREE_CODE (base) == SSA_NAME)
   5971  1.1  mrg     {
   5972  1.1  mrg       base_stmt = va_list_skip_additions (base);
   5973  1.1  mrg       if (base_stmt
   5974  1.1  mrg 	  && is_gimple_assign (base_stmt)
   5975  1.1  mrg 	  && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
   5976  1.1  mrg 	base = gimple_assign_rhs1 (base_stmt);
   5977  1.1  mrg     }
   5978  1.1  mrg 
   5979  1.1  mrg   if (TREE_CODE (base) != COMPONENT_REF
   5980  1.1  mrg       || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
   5981  1.1  mrg     {
   5982  1.1  mrg       base = gimple_assign_rhs2 (stmt);
   5983  1.1  mrg       if (TREE_CODE (base) == SSA_NAME)
   5984  1.1  mrg 	{
   5985  1.1  mrg 	  base_stmt = va_list_skip_additions (base);
   5986  1.1  mrg 	  if (base_stmt
   5987  1.1  mrg 	      && is_gimple_assign (base_stmt)
   5988  1.1  mrg 	      && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
   5989  1.1  mrg 	    base = gimple_assign_rhs1 (base_stmt);
   5990  1.1  mrg 	}
   5991  1.1  mrg 
   5992  1.1  mrg       if (TREE_CODE (base) != COMPONENT_REF
   5993  1.1  mrg 	  || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
   5994  1.1  mrg 	return false;
   5995  1.1  mrg 
   5996  1.1  mrg       offset_arg = 0;
   5997  1.1  mrg     }
   5998  1.1  mrg 
   5999  1.1  mrg   base = get_base_address (base);
   6000  1.1  mrg   if (TREE_CODE (base) != VAR_DECL
   6001  1.1  mrg       || !bitmap_bit_p (si->va_list_vars, DECL_UID (base) + num_ssa_names))
   6002  1.1  mrg     return false;
   6003  1.1  mrg 
   6004  1.1  mrg   offset = gimple_op (stmt, 1 + offset_arg);
   6005  1.1  mrg   if (TREE_CODE (offset) == SSA_NAME)
   6006  1.1  mrg     {
   6007  1.1  mrg       gimple *offset_stmt = va_list_skip_additions (offset);
   6008  1.1  mrg 
   6009  1.1  mrg       if (offset_stmt
   6010  1.1  mrg 	  && gimple_code (offset_stmt) == GIMPLE_PHI)
   6011  1.1  mrg 	{
   6012  1.1  mrg 	  HOST_WIDE_INT sub;
   6013  1.1  mrg 	  gimple *arg1_stmt, *arg2_stmt;
   6014  1.1  mrg 	  tree arg1, arg2;
   6015  1.1  mrg 	  enum tree_code code1, code2;
   6016  1.1  mrg 
   6017  1.1  mrg 	  if (gimple_phi_num_args (offset_stmt) != 2)
   6018  1.1  mrg 	    goto escapes;
   6019  1.1  mrg 
   6020  1.1  mrg 	  arg1_stmt
   6021  1.1  mrg 	    = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0));
   6022  1.1  mrg 	  arg2_stmt
   6023  1.1  mrg 	    = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1));
   6024  1.1  mrg 	  if (arg1_stmt == NULL
   6025  1.1  mrg 	      || !is_gimple_assign (arg1_stmt)
   6026  1.1  mrg 	      || arg2_stmt == NULL
   6027  1.1  mrg 	      || !is_gimple_assign (arg2_stmt))
   6028  1.1  mrg 	    goto escapes;
   6029  1.1  mrg 
   6030  1.1  mrg 	  code1 = gimple_assign_rhs_code (arg1_stmt);
   6031  1.1  mrg 	  code2 = gimple_assign_rhs_code (arg2_stmt);
   6032  1.1  mrg 	  if (code1 == COMPONENT_REF
   6033  1.1  mrg 	      && (code2 == MINUS_EXPR || code2 == PLUS_EXPR))
   6034  1.1  mrg 	    /* Do nothing.  */;
   6035  1.1  mrg 	  else if (code2 == COMPONENT_REF
   6036  1.1  mrg 		   && (code1 == MINUS_EXPR || code1 == PLUS_EXPR))
   6037  1.1  mrg 	    {
   6038  1.1  mrg 	      std::swap (arg1_stmt, arg2_stmt);
   6039  1.1  mrg 	      code2 = code1;
   6040  1.1  mrg 	    }
   6041  1.1  mrg 	  else
   6042  1.1  mrg 	    goto escapes;
   6043  1.1  mrg 
   6044  1.1  mrg 	  if (!tree_fits_shwi_p (gimple_assign_rhs2 (arg2_stmt)))
   6045  1.1  mrg 	    goto escapes;
   6046  1.1  mrg 
   6047  1.1  mrg 	  sub = tree_to_shwi (gimple_assign_rhs2 (arg2_stmt));
   6048  1.1  mrg 	  if (code2 == MINUS_EXPR)
   6049  1.1  mrg 	    sub = -sub;
   6050  1.1  mrg 	  if (sub < -48 || sub > -32)
   6051  1.1  mrg 	    goto escapes;
   6052  1.1  mrg 
   6053  1.1  mrg 	  arg1 = gimple_assign_rhs1 (arg1_stmt);
   6054  1.1  mrg 	  arg2 = gimple_assign_rhs1 (arg2_stmt);
   6055  1.1  mrg 	  if (TREE_CODE (arg2) == SSA_NAME)
   6056  1.1  mrg 	    {
   6057  1.1  mrg 	      arg2_stmt = va_list_skip_additions (arg2);
   6058  1.1  mrg 	      if (arg2_stmt == NULL
   6059  1.1  mrg 		  || !is_gimple_assign (arg2_stmt)
   6060  1.1  mrg 		  || gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF)
   6061  1.1  mrg 		goto escapes;
   6062  1.1  mrg 	      arg2 = gimple_assign_rhs1 (arg2_stmt);
   6063  1.1  mrg 	    }
   6064  1.1  mrg 	  if (arg1 != arg2)
   6065  1.1  mrg 	    goto escapes;
   6066  1.1  mrg 
   6067  1.1  mrg 	  if (TREE_CODE (arg1) != COMPONENT_REF
   6068  1.1  mrg 	      || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
   6069  1.1  mrg 	      || get_base_address (arg1) != base)
   6070  1.1  mrg 	    goto escapes;
   6071  1.1  mrg 
   6072  1.1  mrg 	  /* Need floating point regs.  */
   6073  1.1  mrg 	  cfun->va_list_fpr_size |= 2;
   6074  1.1  mrg 	  return false;
   6075  1.1  mrg 	}
   6076  1.1  mrg       if (offset_stmt
   6077  1.1  mrg 	  && is_gimple_assign (offset_stmt)
   6078  1.1  mrg 	  && gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF)
   6079  1.1  mrg 	offset = gimple_assign_rhs1 (offset_stmt);
   6080  1.1  mrg     }
   6081  1.1  mrg   if (TREE_CODE (offset) != COMPONENT_REF
   6082  1.1  mrg       || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
   6083  1.1  mrg       || get_base_address (offset) != base)
   6084  1.1  mrg     goto escapes;
   6085  1.1  mrg   else
   6086  1.1  mrg     /* Need general regs.  */
   6087  1.1  mrg     cfun->va_list_fpr_size |= 1;
   6088  1.1  mrg   return false;
   6089  1.1  mrg 
   6090  1.1  mrg escapes:
   6091  1.1  mrg   si->va_list_escapes = true;
   6092  1.1  mrg   return false;
   6093  1.1  mrg }
   6094  1.1  mrg #endif
   6095  1.1  mrg 
   6096  1.1  mrg /* Perform any needed actions needed for a function that is receiving a
   6097  1.1  mrg    variable number of arguments.  */
   6098  1.1  mrg 
   6099  1.1  mrg static void
   6100  1.1  mrg alpha_setup_incoming_varargs (cumulative_args_t pcum,
   6101  1.1  mrg 			      const function_arg_info &arg,
   6102  1.1  mrg 			      int *pretend_size, int no_rtl)
   6103  1.1  mrg {
   6104  1.1  mrg   CUMULATIVE_ARGS cum = *get_cumulative_args (pcum);
   6105  1.1  mrg 
   6106  1.1  mrg   /* Skip the current argument.  */
   6107  1.1  mrg   targetm.calls.function_arg_advance (pack_cumulative_args (&cum), arg);
   6108  1.1  mrg 
   6109  1.1  mrg #if TARGET_ABI_OPEN_VMS
   6110  1.1  mrg   /* For VMS, we allocate space for all 6 arg registers plus a count.
   6111  1.1  mrg 
   6112  1.1  mrg      However, if NO registers need to be saved, don't allocate any space.
   6113  1.1  mrg      This is not only because we won't need the space, but because AP
   6114  1.1  mrg      includes the current_pretend_args_size and we don't want to mess up
   6115  1.1  mrg      any ap-relative addresses already made.  */
   6116  1.1  mrg   if (cum.num_args < 6)
   6117  1.1  mrg     {
   6118  1.1  mrg       if (!no_rtl)
   6119  1.1  mrg 	{
   6120  1.1  mrg 	  emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
   6121  1.1  mrg 	  emit_insn (gen_arg_home ());
   6122  1.1  mrg 	}
   6123  1.1  mrg       *pretend_size = 7 * UNITS_PER_WORD;
   6124  1.1  mrg     }
   6125  1.1  mrg #else
   6126  1.1  mrg   /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
   6127  1.1  mrg      only push those that are remaining.  However, if NO registers need to
   6128  1.1  mrg      be saved, don't allocate any space.  This is not only because we won't
   6129  1.1  mrg      need the space, but because AP includes the current_pretend_args_size
   6130  1.1  mrg      and we don't want to mess up any ap-relative addresses already made.
   6131  1.1  mrg 
   6132  1.1  mrg      If we are not to use the floating-point registers, save the integer
   6133  1.1  mrg      registers where we would put the floating-point registers.  This is
   6134  1.1  mrg      not the most efficient way to implement varargs with just one register
   6135  1.1  mrg      class, but it isn't worth doing anything more efficient in this rare
   6136  1.1  mrg      case.  */
   6137  1.1  mrg   if (cum >= 6)
   6138  1.1  mrg     return;
   6139  1.1  mrg 
   6140  1.1  mrg   if (!no_rtl)
   6141  1.1  mrg     {
   6142  1.1  mrg       int count;
   6143  1.1  mrg       alias_set_type set = get_varargs_alias_set ();
   6144  1.1  mrg       rtx tmp;
   6145  1.1  mrg 
   6146  1.1  mrg       count = cfun->va_list_gpr_size / UNITS_PER_WORD;
   6147  1.1  mrg       if (count > 6 - cum)
   6148  1.1  mrg 	count = 6 - cum;
   6149  1.1  mrg 
   6150  1.1  mrg       /* Detect whether integer registers or floating-point registers
   6151  1.1  mrg 	 are needed by the detected va_arg statements.  See above for
   6152  1.1  mrg 	 how these values are computed.  Note that the "escape" value
   6153  1.1  mrg 	 is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of
   6154  1.1  mrg 	 these bits set.  */
   6155  1.1  mrg       gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3);
   6156  1.1  mrg 
   6157  1.1  mrg       if (cfun->va_list_fpr_size & 1)
   6158  1.1  mrg 	{
   6159  1.1  mrg 	  tmp = gen_rtx_MEM (BLKmode,
   6160  1.1  mrg 			     plus_constant (Pmode, virtual_incoming_args_rtx,
   6161  1.1  mrg 					    (cum + 6) * UNITS_PER_WORD));
   6162  1.1  mrg 	  MEM_NOTRAP_P (tmp) = 1;
   6163  1.1  mrg 	  set_mem_alias_set (tmp, set);
   6164  1.1  mrg 	  move_block_from_reg (16 + cum, tmp, count);
   6165  1.1  mrg 	}
   6166  1.1  mrg 
   6167  1.1  mrg       if (cfun->va_list_fpr_size & 2)
   6168  1.1  mrg 	{
   6169  1.1  mrg 	  tmp = gen_rtx_MEM (BLKmode,
   6170  1.1  mrg 			     plus_constant (Pmode, virtual_incoming_args_rtx,
   6171  1.1  mrg 					    cum * UNITS_PER_WORD));
   6172  1.1  mrg 	  MEM_NOTRAP_P (tmp) = 1;
   6173  1.1  mrg 	  set_mem_alias_set (tmp, set);
   6174  1.1  mrg 	  move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count);
   6175  1.1  mrg 	}
   6176  1.1  mrg      }
   6177  1.1  mrg   *pretend_size = 12 * UNITS_PER_WORD;
   6178  1.1  mrg #endif
   6179  1.1  mrg }
   6180  1.1  mrg 
   6181  1.1  mrg static void
   6182  1.1  mrg alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
   6183  1.1  mrg {
   6184  1.1  mrg   HOST_WIDE_INT offset;
   6185  1.1  mrg   tree t, offset_field, base_field;
   6186  1.1  mrg 
   6187  1.1  mrg   if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
   6188  1.1  mrg     return;
   6189  1.1  mrg 
   6190  1.1  mrg   /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
   6191  1.1  mrg      up by 48, storing fp arg registers in the first 48 bytes, and the
   6192  1.1  mrg      integer arg registers in the next 48 bytes.  This is only done,
   6193  1.1  mrg      however, if any integer registers need to be stored.
   6194  1.1  mrg 
   6195  1.1  mrg      If no integer registers need be stored, then we must subtract 48
   6196  1.1  mrg      in order to account for the integer arg registers which are counted
   6197  1.1  mrg      in argsize above, but which are not actually stored on the stack.
   6198  1.1  mrg      Must further be careful here about structures straddling the last
   6199  1.1  mrg      integer argument register; that futzes with pretend_args_size,
   6200  1.1  mrg      which changes the meaning of AP.  */
   6201  1.1  mrg 
   6202  1.1  mrg   if (NUM_ARGS < 6)
   6203  1.1  mrg     offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
   6204  1.1  mrg   else
   6205  1.1  mrg     offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size;
   6206  1.1  mrg 
   6207  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   6208  1.1  mrg     {
   6209  1.1  mrg       t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
   6210  1.1  mrg       t = fold_build_pointer_plus_hwi (t, offset + NUM_ARGS * UNITS_PER_WORD);
   6211  1.1  mrg       t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
   6212  1.1  mrg       TREE_SIDE_EFFECTS (t) = 1;
   6213  1.1  mrg       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
   6214  1.1  mrg     }
   6215  1.1  mrg   else
   6216  1.1  mrg     {
   6217  1.1  mrg       base_field = TYPE_FIELDS (TREE_TYPE (valist));
   6218  1.1  mrg       offset_field = DECL_CHAIN (base_field);
   6219  1.1  mrg 
   6220  1.1  mrg       base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
   6221  1.1  mrg 			   valist, base_field, NULL_TREE);
   6222  1.1  mrg       offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
   6223  1.1  mrg 			     valist, offset_field, NULL_TREE);
   6224  1.1  mrg 
   6225  1.1  mrg       t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
   6226  1.1  mrg       t = fold_build_pointer_plus_hwi (t, offset);
   6227  1.1  mrg       t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
   6228  1.1  mrg       TREE_SIDE_EFFECTS (t) = 1;
   6229  1.1  mrg       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
   6230  1.1  mrg 
   6231  1.1  mrg       t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
   6232  1.1  mrg       t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
   6233  1.1  mrg       TREE_SIDE_EFFECTS (t) = 1;
   6234  1.1  mrg       expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
   6235  1.1  mrg     }
   6236  1.1  mrg }
   6237  1.1  mrg 
   6238  1.1  mrg static tree
   6239  1.1  mrg alpha_gimplify_va_arg_1 (tree type, tree base, tree offset,
   6240  1.1  mrg 			 gimple_seq *pre_p)
   6241  1.1  mrg {
   6242  1.1  mrg   tree type_size, ptr_type, addend, t, addr;
   6243  1.1  mrg   gimple_seq internal_post;
   6244  1.1  mrg 
   6245  1.1  mrg   /* If the type could not be passed in registers, skip the block
   6246  1.1  mrg      reserved for the registers.  */
   6247  1.1  mrg   if (must_pass_va_arg_in_stack (type))
   6248  1.1  mrg     {
   6249  1.1  mrg       t = build_int_cst (TREE_TYPE (offset), 6*8);
   6250  1.1  mrg       gimplify_assign (offset,
   6251  1.1  mrg 		       build2 (MAX_EXPR, TREE_TYPE (offset), offset, t),
   6252  1.1  mrg 		       pre_p);
   6253  1.1  mrg     }
   6254  1.1  mrg 
   6255  1.1  mrg   addend = offset;
   6256  1.1  mrg   ptr_type = build_pointer_type_for_mode (type, ptr_mode, true);
   6257  1.1  mrg 
   6258  1.1  mrg   if (TREE_CODE (type) == COMPLEX_TYPE)
   6259  1.1  mrg     {
   6260  1.1  mrg       tree real_part, imag_part, real_temp;
   6261  1.1  mrg 
   6262  1.1  mrg       real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
   6263  1.1  mrg 					   offset, pre_p);
   6264  1.1  mrg 
   6265  1.1  mrg       /* Copy the value into a new temporary, lest the formal temporary
   6266  1.1  mrg 	 be reused out from under us.  */
   6267  1.1  mrg       real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
   6268  1.1  mrg 
   6269  1.1  mrg       imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
   6270  1.1  mrg 					   offset, pre_p);
   6271  1.1  mrg 
   6272  1.1  mrg       return build2 (COMPLEX_EXPR, type, real_temp, imag_part);
   6273  1.1  mrg     }
   6274  1.1  mrg   else if (TREE_CODE (type) == REAL_TYPE)
   6275  1.1  mrg     {
   6276  1.1  mrg       tree fpaddend, cond, fourtyeight;
   6277  1.1  mrg 
   6278  1.1  mrg       fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
   6279  1.1  mrg       fpaddend = fold_build2 (MINUS_EXPR, TREE_TYPE (addend),
   6280  1.1  mrg 			      addend, fourtyeight);
   6281  1.1  mrg       cond = fold_build2 (LT_EXPR, boolean_type_node, addend, fourtyeight);
   6282  1.1  mrg       addend = fold_build3 (COND_EXPR, TREE_TYPE (addend), cond,
   6283  1.1  mrg 			    fpaddend, addend);
   6284  1.1  mrg     }
   6285  1.1  mrg 
   6286  1.1  mrg   /* Build the final address and force that value into a temporary.  */
   6287  1.1  mrg   addr = fold_build_pointer_plus (fold_convert (ptr_type, base), addend);
   6288  1.1  mrg   internal_post = NULL;
   6289  1.1  mrg   gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
   6290  1.1  mrg   gimple_seq_add_seq (pre_p, internal_post);
   6291  1.1  mrg 
   6292  1.1  mrg   /* Update the offset field.  */
   6293  1.1  mrg   type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
   6294  1.1  mrg   if (type_size == NULL || TREE_OVERFLOW (type_size))
   6295  1.1  mrg     t = size_zero_node;
   6296  1.1  mrg   else
   6297  1.1  mrg     {
   6298  1.1  mrg       t = size_binop (PLUS_EXPR, type_size, size_int (7));
   6299  1.1  mrg       t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
   6300  1.1  mrg       t = size_binop (MULT_EXPR, t, size_int (8));
   6301  1.1  mrg     }
   6302  1.1  mrg   t = fold_convert (TREE_TYPE (offset), t);
   6303  1.1  mrg   gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t),
   6304  1.1  mrg       		   pre_p);
   6305  1.1  mrg 
   6306  1.1  mrg   return build_va_arg_indirect_ref (addr);
   6307  1.1  mrg }
   6308  1.1  mrg 
   6309  1.1  mrg static tree
   6310  1.1  mrg alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
   6311  1.1  mrg 		       gimple_seq *post_p)
   6312  1.1  mrg {
   6313  1.1  mrg   tree offset_field, base_field, offset, base, t, r;
   6314  1.1  mrg   bool indirect;
   6315  1.1  mrg 
   6316  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   6317  1.1  mrg     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
   6318  1.1  mrg 
   6319  1.1  mrg   base_field = TYPE_FIELDS (va_list_type_node);
   6320  1.1  mrg   offset_field = DECL_CHAIN (base_field);
   6321  1.1  mrg   base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
   6322  1.1  mrg 		       valist, base_field, NULL_TREE);
   6323  1.1  mrg   offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
   6324  1.1  mrg 			 valist, offset_field, NULL_TREE);
   6325  1.1  mrg 
   6326  1.1  mrg   /* Pull the fields of the structure out into temporaries.  Since we never
   6327  1.1  mrg      modify the base field, we can use a formal temporary.  Sign-extend the
   6328  1.1  mrg      offset field so that it's the proper width for pointer arithmetic.  */
   6329  1.1  mrg   base = get_formal_tmp_var (base_field, pre_p);
   6330  1.1  mrg 
   6331  1.1  mrg   t = fold_convert (build_nonstandard_integer_type (64, 0), offset_field);
   6332  1.1  mrg   offset = get_initialized_tmp_var (t, pre_p, NULL);
   6333  1.1  mrg 
   6334  1.1  mrg   indirect = pass_va_arg_by_reference (type);
   6335  1.1  mrg 
   6336  1.1  mrg   if (indirect)
   6337  1.1  mrg     {
   6338  1.1  mrg       if (TREE_CODE (type) == COMPLEX_TYPE
   6339  1.1  mrg 	  && targetm.calls.split_complex_arg (type))
   6340  1.1  mrg 	{
   6341  1.1  mrg 	  tree real_part, imag_part, real_temp;
   6342  1.1  mrg 
   6343  1.1  mrg 	  tree ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
   6344  1.1  mrg 						       ptr_mode, true);
   6345  1.1  mrg 
   6346  1.1  mrg 	  real_part = alpha_gimplify_va_arg_1 (ptr_type, base,
   6347  1.1  mrg 					       offset, pre_p);
   6348  1.1  mrg 	  real_part = build_va_arg_indirect_ref (real_part);
   6349  1.1  mrg 
   6350  1.1  mrg 	  /* Copy the value into a new temporary, lest the formal temporary
   6351  1.1  mrg 	     be reused out from under us.  */
   6352  1.1  mrg 	  real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
   6353  1.1  mrg 
   6354  1.1  mrg 	  imag_part = alpha_gimplify_va_arg_1 (ptr_type, base,
   6355  1.1  mrg 					       offset, pre_p);
   6356  1.1  mrg 	  imag_part = build_va_arg_indirect_ref (imag_part);
   6357  1.1  mrg 
   6358  1.1  mrg 	  r = build2 (COMPLEX_EXPR, type, real_temp, imag_part);
   6359  1.1  mrg 
   6360  1.1  mrg 	  /* Stuff the offset temporary back into its field.  */
   6361  1.1  mrg 	  gimplify_assign (unshare_expr (offset_field),
   6362  1.1  mrg 			   fold_convert (TREE_TYPE (offset_field), offset),
   6363  1.1  mrg 			   pre_p);
   6364  1.1  mrg 	  return r;
   6365  1.1  mrg 	}
   6366  1.1  mrg       else
   6367  1.1  mrg 	type = build_pointer_type_for_mode (type, ptr_mode, true);
   6368  1.1  mrg     }
   6369  1.1  mrg 
   6370  1.1  mrg   /* Find the value.  Note that this will be a stable indirection, or
   6371  1.1  mrg      a composite of stable indirections in the case of complex.  */
   6372  1.1  mrg   r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
   6373  1.1  mrg 
   6374  1.1  mrg   /* Stuff the offset temporary back into its field.  */
   6375  1.1  mrg   gimplify_assign (unshare_expr (offset_field),
   6376  1.1  mrg 		   fold_convert (TREE_TYPE (offset_field), offset), pre_p);
   6377  1.1  mrg 
   6378  1.1  mrg   if (indirect)
   6379  1.1  mrg     r = build_va_arg_indirect_ref (r);
   6380  1.1  mrg 
   6381  1.1  mrg   return r;
   6382  1.1  mrg }
   6383  1.1  mrg 
   6384  1.1  mrg /* Builtins.  */
   6386  1.1  mrg 
   6387  1.1  mrg enum alpha_builtin
   6388  1.1  mrg {
   6389  1.1  mrg   ALPHA_BUILTIN_CMPBGE,
   6390  1.1  mrg   ALPHA_BUILTIN_EXTBL,
   6391  1.1  mrg   ALPHA_BUILTIN_EXTWL,
   6392  1.1  mrg   ALPHA_BUILTIN_EXTLL,
   6393  1.1  mrg   ALPHA_BUILTIN_EXTQL,
   6394  1.1  mrg   ALPHA_BUILTIN_EXTWH,
   6395  1.1  mrg   ALPHA_BUILTIN_EXTLH,
   6396  1.1  mrg   ALPHA_BUILTIN_EXTQH,
   6397  1.1  mrg   ALPHA_BUILTIN_INSBL,
   6398  1.1  mrg   ALPHA_BUILTIN_INSWL,
   6399  1.1  mrg   ALPHA_BUILTIN_INSLL,
   6400  1.1  mrg   ALPHA_BUILTIN_INSQL,
   6401  1.1  mrg   ALPHA_BUILTIN_INSWH,
   6402  1.1  mrg   ALPHA_BUILTIN_INSLH,
   6403  1.1  mrg   ALPHA_BUILTIN_INSQH,
   6404  1.1  mrg   ALPHA_BUILTIN_MSKBL,
   6405  1.1  mrg   ALPHA_BUILTIN_MSKWL,
   6406  1.1  mrg   ALPHA_BUILTIN_MSKLL,
   6407  1.1  mrg   ALPHA_BUILTIN_MSKQL,
   6408  1.1  mrg   ALPHA_BUILTIN_MSKWH,
   6409  1.1  mrg   ALPHA_BUILTIN_MSKLH,
   6410  1.1  mrg   ALPHA_BUILTIN_MSKQH,
   6411  1.1  mrg   ALPHA_BUILTIN_UMULH,
   6412  1.1  mrg   ALPHA_BUILTIN_ZAP,
   6413  1.1  mrg   ALPHA_BUILTIN_ZAPNOT,
   6414  1.1  mrg   ALPHA_BUILTIN_AMASK,
   6415  1.1  mrg   ALPHA_BUILTIN_IMPLVER,
   6416  1.1  mrg   ALPHA_BUILTIN_RPCC,
   6417  1.1  mrg   ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
   6418  1.1  mrg   ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,
   6419  1.1  mrg 
   6420  1.1  mrg   /* TARGET_MAX */
   6421  1.1  mrg   ALPHA_BUILTIN_MINUB8,
   6422  1.1  mrg   ALPHA_BUILTIN_MINSB8,
   6423  1.1  mrg   ALPHA_BUILTIN_MINUW4,
   6424  1.1  mrg   ALPHA_BUILTIN_MINSW4,
   6425  1.1  mrg   ALPHA_BUILTIN_MAXUB8,
   6426  1.1  mrg   ALPHA_BUILTIN_MAXSB8,
   6427  1.1  mrg   ALPHA_BUILTIN_MAXUW4,
   6428  1.1  mrg   ALPHA_BUILTIN_MAXSW4,
   6429  1.1  mrg   ALPHA_BUILTIN_PERR,
   6430  1.1  mrg   ALPHA_BUILTIN_PKLB,
   6431  1.1  mrg   ALPHA_BUILTIN_PKWB,
   6432  1.1  mrg   ALPHA_BUILTIN_UNPKBL,
   6433  1.1  mrg   ALPHA_BUILTIN_UNPKBW,
   6434  1.1  mrg 
   6435  1.1  mrg   /* TARGET_CIX */
   6436  1.1  mrg   ALPHA_BUILTIN_CTTZ,
   6437  1.1  mrg   ALPHA_BUILTIN_CTLZ,
   6438  1.1  mrg   ALPHA_BUILTIN_CTPOP,
   6439  1.1  mrg 
   6440  1.1  mrg   ALPHA_BUILTIN_max
   6441  1.1  mrg };
   6442  1.1  mrg 
   6443  1.1  mrg static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
   6444  1.1  mrg   CODE_FOR_builtin_cmpbge,
   6445  1.1  mrg   CODE_FOR_extbl,
   6446  1.1  mrg   CODE_FOR_extwl,
   6447  1.1  mrg   CODE_FOR_extll,
   6448  1.1  mrg   CODE_FOR_extql,
   6449  1.1  mrg   CODE_FOR_extwh,
   6450  1.1  mrg   CODE_FOR_extlh,
   6451  1.1  mrg   CODE_FOR_extqh,
   6452  1.1  mrg   CODE_FOR_builtin_insbl,
   6453  1.1  mrg   CODE_FOR_builtin_inswl,
   6454  1.1  mrg   CODE_FOR_builtin_insll,
   6455  1.1  mrg   CODE_FOR_insql,
   6456  1.1  mrg   CODE_FOR_inswh,
   6457  1.1  mrg   CODE_FOR_inslh,
   6458  1.1  mrg   CODE_FOR_insqh,
   6459  1.1  mrg   CODE_FOR_mskbl,
   6460  1.1  mrg   CODE_FOR_mskwl,
   6461  1.1  mrg   CODE_FOR_mskll,
   6462  1.1  mrg   CODE_FOR_mskql,
   6463  1.1  mrg   CODE_FOR_mskwh,
   6464  1.1  mrg   CODE_FOR_msklh,
   6465  1.1  mrg   CODE_FOR_mskqh,
   6466  1.1  mrg   CODE_FOR_umuldi3_highpart,
   6467  1.1  mrg   CODE_FOR_builtin_zap,
   6468  1.1  mrg   CODE_FOR_builtin_zapnot,
   6469  1.1  mrg   CODE_FOR_builtin_amask,
   6470  1.1  mrg   CODE_FOR_builtin_implver,
   6471  1.1  mrg   CODE_FOR_builtin_rpcc,
   6472  1.1  mrg   CODE_FOR_builtin_establish_vms_condition_handler,
   6473  1.1  mrg   CODE_FOR_builtin_revert_vms_condition_handler,
   6474  1.1  mrg 
   6475  1.1  mrg   /* TARGET_MAX */
   6476  1.1  mrg   CODE_FOR_builtin_minub8,
   6477  1.1  mrg   CODE_FOR_builtin_minsb8,
   6478  1.1  mrg   CODE_FOR_builtin_minuw4,
   6479  1.1  mrg   CODE_FOR_builtin_minsw4,
   6480  1.1  mrg   CODE_FOR_builtin_maxub8,
   6481  1.1  mrg   CODE_FOR_builtin_maxsb8,
   6482  1.1  mrg   CODE_FOR_builtin_maxuw4,
   6483  1.1  mrg   CODE_FOR_builtin_maxsw4,
   6484  1.1  mrg   CODE_FOR_builtin_perr,
   6485  1.1  mrg   CODE_FOR_builtin_pklb,
   6486  1.1  mrg   CODE_FOR_builtin_pkwb,
   6487  1.1  mrg   CODE_FOR_builtin_unpkbl,
   6488  1.1  mrg   CODE_FOR_builtin_unpkbw,
   6489  1.1  mrg 
   6490  1.1  mrg   /* TARGET_CIX */
   6491  1.1  mrg   CODE_FOR_ctzdi2,
   6492  1.1  mrg   CODE_FOR_clzdi2,
   6493  1.1  mrg   CODE_FOR_popcountdi2
   6494  1.1  mrg };
   6495  1.1  mrg 
   6496  1.1  mrg struct alpha_builtin_def
   6497  1.1  mrg {
   6498  1.1  mrg   const char *name;
   6499  1.1  mrg   enum alpha_builtin code;
   6500  1.1  mrg   unsigned int target_mask;
   6501  1.1  mrg   bool is_const;
   6502  1.1  mrg };
   6503  1.1  mrg 
   6504  1.1  mrg static struct alpha_builtin_def const zero_arg_builtins[] = {
   6505  1.1  mrg   { "__builtin_alpha_implver",	ALPHA_BUILTIN_IMPLVER,	0, true },
   6506  1.1  mrg   { "__builtin_alpha_rpcc",	ALPHA_BUILTIN_RPCC,	0, false }
   6507  1.1  mrg };
   6508  1.1  mrg 
   6509  1.1  mrg static struct alpha_builtin_def const one_arg_builtins[] = {
   6510  1.1  mrg   { "__builtin_alpha_amask",	ALPHA_BUILTIN_AMASK,	0, true },
   6511  1.1  mrg   { "__builtin_alpha_pklb",	ALPHA_BUILTIN_PKLB,	MASK_MAX, true },
   6512  1.1  mrg   { "__builtin_alpha_pkwb",	ALPHA_BUILTIN_PKWB,	MASK_MAX, true },
   6513  1.1  mrg   { "__builtin_alpha_unpkbl",	ALPHA_BUILTIN_UNPKBL,	MASK_MAX, true },
   6514  1.1  mrg   { "__builtin_alpha_unpkbw",	ALPHA_BUILTIN_UNPKBW,	MASK_MAX, true },
   6515  1.1  mrg   { "__builtin_alpha_cttz",	ALPHA_BUILTIN_CTTZ,	MASK_CIX, true },
   6516  1.1  mrg   { "__builtin_alpha_ctlz",	ALPHA_BUILTIN_CTLZ,	MASK_CIX, true },
   6517  1.1  mrg   { "__builtin_alpha_ctpop",	ALPHA_BUILTIN_CTPOP,	MASK_CIX, true }
   6518  1.1  mrg };
   6519  1.1  mrg 
   6520  1.1  mrg static struct alpha_builtin_def const two_arg_builtins[] = {
   6521  1.1  mrg   { "__builtin_alpha_cmpbge",	ALPHA_BUILTIN_CMPBGE,	0, true },
   6522  1.1  mrg   { "__builtin_alpha_extbl",	ALPHA_BUILTIN_EXTBL,	0, true },
   6523  1.1  mrg   { "__builtin_alpha_extwl",	ALPHA_BUILTIN_EXTWL,	0, true },
   6524  1.1  mrg   { "__builtin_alpha_extll",	ALPHA_BUILTIN_EXTLL,	0, true },
   6525  1.1  mrg   { "__builtin_alpha_extql",	ALPHA_BUILTIN_EXTQL,	0, true },
   6526  1.1  mrg   { "__builtin_alpha_extwh",	ALPHA_BUILTIN_EXTWH,	0, true },
   6527  1.1  mrg   { "__builtin_alpha_extlh",	ALPHA_BUILTIN_EXTLH,	0, true },
   6528  1.1  mrg   { "__builtin_alpha_extqh",	ALPHA_BUILTIN_EXTQH,	0, true },
   6529  1.1  mrg   { "__builtin_alpha_insbl",	ALPHA_BUILTIN_INSBL,	0, true },
   6530  1.1  mrg   { "__builtin_alpha_inswl",	ALPHA_BUILTIN_INSWL,	0, true },
   6531  1.1  mrg   { "__builtin_alpha_insll",	ALPHA_BUILTIN_INSLL,	0, true },
   6532  1.1  mrg   { "__builtin_alpha_insql",	ALPHA_BUILTIN_INSQL,	0, true },
   6533  1.1  mrg   { "__builtin_alpha_inswh",	ALPHA_BUILTIN_INSWH,	0, true },
   6534  1.1  mrg   { "__builtin_alpha_inslh",	ALPHA_BUILTIN_INSLH,	0, true },
   6535  1.1  mrg   { "__builtin_alpha_insqh",	ALPHA_BUILTIN_INSQH,	0, true },
   6536  1.1  mrg   { "__builtin_alpha_mskbl",	ALPHA_BUILTIN_MSKBL,	0, true },
   6537  1.1  mrg   { "__builtin_alpha_mskwl",	ALPHA_BUILTIN_MSKWL,	0, true },
   6538  1.1  mrg   { "__builtin_alpha_mskll",	ALPHA_BUILTIN_MSKLL,	0, true },
   6539  1.1  mrg   { "__builtin_alpha_mskql",	ALPHA_BUILTIN_MSKQL,	0, true },
   6540  1.1  mrg   { "__builtin_alpha_mskwh",	ALPHA_BUILTIN_MSKWH,	0, true },
   6541  1.1  mrg   { "__builtin_alpha_msklh",	ALPHA_BUILTIN_MSKLH,	0, true },
   6542  1.1  mrg   { "__builtin_alpha_mskqh",	ALPHA_BUILTIN_MSKQH,	0, true },
   6543  1.1  mrg   { "__builtin_alpha_umulh",	ALPHA_BUILTIN_UMULH,	0, true },
   6544  1.1  mrg   { "__builtin_alpha_zap",	ALPHA_BUILTIN_ZAP,	0, true },
   6545  1.1  mrg   { "__builtin_alpha_zapnot",	ALPHA_BUILTIN_ZAPNOT,	0, true },
   6546  1.1  mrg   { "__builtin_alpha_minub8",	ALPHA_BUILTIN_MINUB8,	MASK_MAX, true },
   6547  1.1  mrg   { "__builtin_alpha_minsb8",	ALPHA_BUILTIN_MINSB8,	MASK_MAX, true },
   6548  1.1  mrg   { "__builtin_alpha_minuw4",	ALPHA_BUILTIN_MINUW4,	MASK_MAX, true },
   6549  1.1  mrg   { "__builtin_alpha_minsw4",	ALPHA_BUILTIN_MINSW4,	MASK_MAX, true },
   6550  1.1  mrg   { "__builtin_alpha_maxub8",	ALPHA_BUILTIN_MAXUB8,	MASK_MAX, true },
   6551  1.1  mrg   { "__builtin_alpha_maxsb8",	ALPHA_BUILTIN_MAXSB8,	MASK_MAX, true },
   6552  1.1  mrg   { "__builtin_alpha_maxuw4",	ALPHA_BUILTIN_MAXUW4,	MASK_MAX, true },
   6553  1.1  mrg   { "__builtin_alpha_maxsw4",	ALPHA_BUILTIN_MAXSW4,	MASK_MAX, true },
   6554  1.1  mrg   { "__builtin_alpha_perr",	ALPHA_BUILTIN_PERR,	MASK_MAX, true }
   6555  1.1  mrg };
   6556  1.1  mrg 
   6557  1.1  mrg static GTY(()) tree alpha_dimode_u;
   6558  1.1  mrg static GTY(()) tree alpha_v8qi_u;
   6559  1.1  mrg static GTY(()) tree alpha_v8qi_s;
   6560  1.1  mrg static GTY(()) tree alpha_v4hi_u;
   6561  1.1  mrg static GTY(()) tree alpha_v4hi_s;
   6562  1.1  mrg 
   6563  1.1  mrg static GTY(()) tree alpha_builtins[(int) ALPHA_BUILTIN_max];
   6564  1.1  mrg 
   6565  1.1  mrg /* Return the alpha builtin for CODE.  */
   6566  1.1  mrg 
   6567  1.1  mrg static tree
   6568  1.1  mrg alpha_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
   6569  1.1  mrg {
   6570  1.1  mrg   if (code >= ALPHA_BUILTIN_max)
   6571  1.1  mrg     return error_mark_node;
   6572  1.1  mrg   return alpha_builtins[code];
   6573  1.1  mrg }
   6574  1.1  mrg 
   6575  1.1  mrg /* Helper function of alpha_init_builtins.  Add the built-in specified
   6576  1.1  mrg    by NAME, TYPE, CODE, and ECF.  */
   6577  1.1  mrg 
   6578  1.1  mrg static void
   6579  1.1  mrg alpha_builtin_function (const char *name, tree ftype,
   6580  1.1  mrg 			enum alpha_builtin code, unsigned ecf)
   6581  1.1  mrg {
   6582  1.1  mrg   tree decl = add_builtin_function (name, ftype, (int) code,
   6583  1.1  mrg 				    BUILT_IN_MD, NULL, NULL_TREE);
   6584  1.1  mrg 
   6585  1.1  mrg   if (ecf & ECF_CONST)
   6586  1.1  mrg     TREE_READONLY (decl) = 1;
   6587  1.1  mrg   if (ecf & ECF_NOTHROW)
   6588  1.1  mrg     TREE_NOTHROW (decl) = 1;
   6589  1.1  mrg 
   6590  1.1  mrg   alpha_builtins [(int) code] = decl;
   6591  1.1  mrg }
   6592  1.1  mrg 
   6593  1.1  mrg /* Helper function of alpha_init_builtins.  Add the COUNT built-in
   6594  1.1  mrg    functions pointed to by P, with function type FTYPE.  */
   6595  1.1  mrg 
   6596  1.1  mrg static void
   6597  1.1  mrg alpha_add_builtins (const struct alpha_builtin_def *p, size_t count,
   6598  1.1  mrg 		    tree ftype)
   6599  1.1  mrg {
   6600  1.1  mrg   size_t i;
   6601  1.1  mrg 
   6602  1.1  mrg   for (i = 0; i < count; ++i, ++p)
   6603  1.1  mrg     if ((target_flags & p->target_mask) == p->target_mask)
   6604  1.1  mrg       alpha_builtin_function (p->name, ftype, p->code,
   6605  1.1  mrg 			      (p->is_const ? ECF_CONST : 0) | ECF_NOTHROW);
   6606  1.1  mrg }
   6607  1.1  mrg 
   6608  1.1  mrg static void
   6609  1.1  mrg alpha_init_builtins (void)
   6610  1.1  mrg {
   6611  1.1  mrg   tree ftype;
   6612  1.1  mrg 
   6613  1.1  mrg   alpha_dimode_u = lang_hooks.types.type_for_mode (DImode, 1);
   6614  1.1  mrg   alpha_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8);
   6615  1.1  mrg   alpha_v8qi_s = build_vector_type (intQI_type_node, 8);
   6616  1.1  mrg   alpha_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4);
   6617  1.1  mrg   alpha_v4hi_s = build_vector_type (intHI_type_node, 4);
   6618  1.1  mrg 
   6619  1.1  mrg   ftype = build_function_type_list (alpha_dimode_u, NULL_TREE);
   6620  1.1  mrg   alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins), ftype);
   6621  1.1  mrg 
   6622  1.1  mrg   ftype = build_function_type_list (alpha_dimode_u, alpha_dimode_u, NULL_TREE);
   6623  1.1  mrg   alpha_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins), ftype);
   6624  1.1  mrg 
   6625  1.1  mrg   ftype = build_function_type_list (alpha_dimode_u, alpha_dimode_u,
   6626  1.1  mrg 				    alpha_dimode_u, NULL_TREE);
   6627  1.1  mrg   alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins), ftype);
   6628  1.1  mrg 
   6629  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   6630  1.1  mrg     {
   6631  1.1  mrg       ftype = build_function_type_list (ptr_type_node, ptr_type_node,
   6632  1.1  mrg 					NULL_TREE);
   6633  1.1  mrg       alpha_builtin_function ("__builtin_establish_vms_condition_handler",
   6634  1.1  mrg 			      ftype,
   6635  1.1  mrg 			      ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
   6636  1.1  mrg 			      0);
   6637  1.1  mrg 
   6638  1.1  mrg       ftype = build_function_type_list (ptr_type_node, void_type_node,
   6639  1.1  mrg 					NULL_TREE);
   6640  1.1  mrg       alpha_builtin_function ("__builtin_revert_vms_condition_handler", ftype,
   6641  1.1  mrg 			      ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER, 0);
   6642  1.1  mrg 
   6643  1.1  mrg       vms_patch_builtins ();
   6644  1.1  mrg     }
   6645  1.1  mrg }
   6646  1.1  mrg 
   6647  1.1  mrg /* Expand an expression EXP that calls a built-in function,
   6648  1.1  mrg    with result going to TARGET if that's convenient
   6649  1.1  mrg    (and in mode MODE if that's convenient).
   6650  1.1  mrg    SUBTARGET may be used as the target for computing one of EXP's operands.
   6651  1.1  mrg    IGNORE is nonzero if the value is to be ignored.  */
   6652  1.1  mrg 
   6653  1.1  mrg static rtx
   6654  1.1  mrg alpha_expand_builtin (tree exp, rtx target,
   6655  1.1  mrg 		      rtx subtarget ATTRIBUTE_UNUSED,
   6656  1.1  mrg 		      machine_mode mode ATTRIBUTE_UNUSED,
   6657  1.1  mrg 		      int ignore ATTRIBUTE_UNUSED)
   6658  1.1  mrg {
   6659  1.1  mrg #define MAX_ARGS 2
   6660  1.1  mrg 
   6661  1.1  mrg   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
   6662  1.1  mrg   unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
   6663  1.1  mrg   tree arg;
   6664  1.1  mrg   call_expr_arg_iterator iter;
   6665  1.1  mrg   enum insn_code icode;
   6666  1.1  mrg   rtx op[MAX_ARGS], pat;
   6667  1.1  mrg   int arity;
   6668  1.1  mrg   bool nonvoid;
   6669  1.1  mrg 
   6670  1.1  mrg   if (fcode >= ALPHA_BUILTIN_max)
   6671  1.1  mrg     internal_error ("bad builtin fcode");
   6672  1.1  mrg   icode = code_for_builtin[fcode];
   6673  1.1  mrg   if (icode == 0)
   6674  1.1  mrg     internal_error ("bad builtin fcode");
   6675  1.1  mrg 
   6676  1.1  mrg   nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
   6677  1.1  mrg 
   6678  1.1  mrg   arity = 0;
   6679  1.1  mrg   FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
   6680  1.1  mrg     {
   6681  1.1  mrg       const struct insn_operand_data *insn_op;
   6682  1.1  mrg 
   6683  1.1  mrg       if (arg == error_mark_node)
   6684  1.1  mrg 	return NULL_RTX;
   6685  1.1  mrg       if (arity > MAX_ARGS)
   6686  1.1  mrg 	return NULL_RTX;
   6687  1.1  mrg 
   6688  1.1  mrg       insn_op = &insn_data[icode].operand[arity + nonvoid];
   6689  1.1  mrg 
   6690  1.1  mrg       op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
   6691  1.1  mrg 
   6692  1.1  mrg       if (!(*insn_op->predicate) (op[arity], insn_op->mode))
   6693  1.1  mrg 	op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
   6694  1.1  mrg       arity++;
   6695  1.1  mrg     }
   6696  1.1  mrg 
   6697  1.1  mrg   if (nonvoid)
   6698  1.1  mrg     {
   6699  1.1  mrg       machine_mode tmode = insn_data[icode].operand[0].mode;
   6700  1.1  mrg       if (!target
   6701  1.1  mrg 	  || GET_MODE (target) != tmode
   6702  1.1  mrg 	  || !(*insn_data[icode].operand[0].predicate) (target, tmode))
   6703  1.1  mrg 	target = gen_reg_rtx (tmode);
   6704  1.1  mrg     }
   6705  1.1  mrg 
   6706  1.1  mrg   switch (arity)
   6707  1.1  mrg     {
   6708  1.1  mrg     case 0:
   6709  1.1  mrg       pat = GEN_FCN (icode) (target);
   6710  1.1  mrg       break;
   6711  1.1  mrg     case 1:
   6712  1.1  mrg       if (nonvoid)
   6713  1.1  mrg         pat = GEN_FCN (icode) (target, op[0]);
   6714  1.1  mrg       else
   6715  1.1  mrg 	pat = GEN_FCN (icode) (op[0]);
   6716  1.1  mrg       break;
   6717  1.1  mrg     case 2:
   6718  1.1  mrg       pat = GEN_FCN (icode) (target, op[0], op[1]);
   6719  1.1  mrg       break;
   6720  1.1  mrg     default:
   6721  1.1  mrg       gcc_unreachable ();
   6722  1.1  mrg     }
   6723  1.1  mrg   if (!pat)
   6724  1.1  mrg     return NULL_RTX;
   6725  1.1  mrg   emit_insn (pat);
   6726  1.1  mrg 
   6727  1.1  mrg   if (nonvoid)
   6728  1.1  mrg     return target;
   6729  1.1  mrg   else
   6730  1.1  mrg     return const0_rtx;
   6731  1.1  mrg }
   6732  1.1  mrg 
   6733  1.1  mrg /* Fold the builtin for the CMPBGE instruction.  This is a vector comparison
   6734  1.1  mrg    with an 8-bit output vector.  OPINT contains the integer operands; bit N
   6735  1.1  mrg    of OP_CONST is set if OPINT[N] is valid.  */
   6736  1.1  mrg 
   6737  1.1  mrg static tree
   6738  1.1  mrg alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const)
   6739  1.1  mrg {
   6740  1.1  mrg   if (op_const == 3)
   6741  1.1  mrg     {
   6742  1.1  mrg       int i, val;
   6743  1.1  mrg       for (i = 0, val = 0; i < 8; ++i)
   6744  1.1  mrg 	{
   6745  1.1  mrg 	  unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff;
   6746  1.1  mrg 	  unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff;
   6747  1.1  mrg 	  if (c0 >= c1)
   6748  1.1  mrg 	    val |= 1 << i;
   6749  1.1  mrg 	}
   6750  1.1  mrg       return build_int_cst (alpha_dimode_u, val);
   6751  1.1  mrg     }
   6752  1.1  mrg   else if (op_const == 2 && opint[1] == 0)
   6753  1.1  mrg     return build_int_cst (alpha_dimode_u, 0xff);
   6754  1.1  mrg   return NULL;
   6755  1.1  mrg }
   6756  1.1  mrg 
   6757  1.1  mrg /* Fold the builtin for the ZAPNOT instruction.  This is essentially a
   6758  1.1  mrg    specialized form of an AND operation.  Other byte manipulation instructions
   6759  1.1  mrg    are defined in terms of this instruction, so this is also used as a
   6760  1.1  mrg    subroutine for other builtins.
   6761  1.1  mrg 
   6762  1.1  mrg    OP contains the tree operands; OPINT contains the extracted integer values.
   6763  1.1  mrg    Bit N of OP_CONST it set if OPINT[N] is valid.  OP may be null if only
   6764  1.1  mrg    OPINT may be considered.  */
   6765  1.1  mrg 
   6766  1.1  mrg static tree
   6767  1.1  mrg alpha_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[],
   6768  1.1  mrg 			   long op_const)
   6769  1.1  mrg {
   6770  1.1  mrg   if (op_const & 2)
   6771  1.1  mrg     {
   6772  1.1  mrg       unsigned HOST_WIDE_INT mask = 0;
   6773  1.1  mrg       int i;
   6774  1.1  mrg 
   6775  1.1  mrg       for (i = 0; i < 8; ++i)
   6776  1.1  mrg 	if ((opint[1] >> i) & 1)
   6777  1.1  mrg 	  mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8);
   6778  1.1  mrg 
   6779  1.1  mrg       if (op_const & 1)
   6780  1.1  mrg 	return build_int_cst (alpha_dimode_u, opint[0] & mask);
   6781  1.1  mrg 
   6782  1.1  mrg       if (op)
   6783  1.1  mrg 	return fold_build2 (BIT_AND_EXPR, alpha_dimode_u, op[0],
   6784  1.1  mrg 			    build_int_cst (alpha_dimode_u, mask));
   6785  1.1  mrg     }
   6786  1.1  mrg   else if ((op_const & 1) && opint[0] == 0)
   6787  1.1  mrg     return build_int_cst (alpha_dimode_u, 0);
   6788  1.1  mrg   return NULL;
   6789  1.1  mrg }
   6790  1.1  mrg 
   6791  1.1  mrg /* Fold the builtins for the EXT family of instructions.  */
   6792  1.1  mrg 
   6793  1.1  mrg static tree
   6794  1.1  mrg alpha_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[],
   6795  1.1  mrg 			  long op_const, unsigned HOST_WIDE_INT bytemask,
   6796  1.1  mrg 			  bool is_high)
   6797  1.1  mrg {
   6798  1.1  mrg   long zap_const = 2;
   6799  1.1  mrg   tree *zap_op = NULL;
   6800  1.1  mrg 
   6801  1.1  mrg   if (op_const & 2)
   6802  1.1  mrg     {
   6803  1.1  mrg       unsigned HOST_WIDE_INT loc;
   6804  1.1  mrg 
   6805  1.1  mrg       loc = opint[1] & 7;
   6806  1.1  mrg       loc *= BITS_PER_UNIT;
   6807  1.1  mrg 
   6808  1.1  mrg       if (loc != 0)
   6809  1.1  mrg 	{
   6810  1.1  mrg 	  if (op_const & 1)
   6811  1.1  mrg 	    {
   6812  1.1  mrg 	      unsigned HOST_WIDE_INT temp = opint[0];
   6813  1.1  mrg 	      if (is_high)
   6814  1.1  mrg 		temp <<= loc;
   6815  1.1  mrg 	      else
   6816  1.1  mrg 		temp >>= loc;
   6817  1.1  mrg 	      opint[0] = temp;
   6818  1.1  mrg 	      zap_const = 3;
   6819  1.1  mrg 	    }
   6820  1.1  mrg 	}
   6821  1.1  mrg       else
   6822  1.1  mrg 	zap_op = op;
   6823  1.1  mrg     }
   6824  1.1  mrg 
   6825  1.1  mrg   opint[1] = bytemask;
   6826  1.1  mrg   return alpha_fold_builtin_zapnot (zap_op, opint, zap_const);
   6827  1.1  mrg }
   6828  1.1  mrg 
   6829  1.1  mrg /* Fold the builtins for the INS family of instructions.  */
   6830  1.1  mrg 
   6831  1.1  mrg static tree
   6832  1.1  mrg alpha_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[],
   6833  1.1  mrg 			  long op_const, unsigned HOST_WIDE_INT bytemask,
   6834  1.1  mrg 			  bool is_high)
   6835  1.1  mrg {
   6836  1.1  mrg   if ((op_const & 1) && opint[0] == 0)
   6837  1.1  mrg     return build_int_cst (alpha_dimode_u, 0);
   6838  1.1  mrg 
   6839  1.1  mrg   if (op_const & 2)
   6840  1.1  mrg     {
   6841  1.1  mrg       unsigned HOST_WIDE_INT temp, loc, byteloc;
   6842  1.1  mrg       tree *zap_op = NULL;
   6843  1.1  mrg 
   6844  1.1  mrg       loc = opint[1] & 7;
   6845  1.1  mrg       bytemask <<= loc;
   6846  1.1  mrg 
   6847  1.1  mrg       temp = opint[0];
   6848  1.1  mrg       if (is_high)
   6849  1.1  mrg 	{
   6850  1.1  mrg 	  byteloc = (64 - (loc * 8)) & 0x3f;
   6851  1.1  mrg 	  if (byteloc == 0)
   6852  1.1  mrg 	    zap_op = op;
   6853  1.1  mrg 	  else
   6854  1.1  mrg 	    temp >>= byteloc;
   6855  1.1  mrg 	  bytemask >>= 8;
   6856  1.1  mrg 	}
   6857  1.1  mrg       else
   6858  1.1  mrg 	{
   6859  1.1  mrg 	  byteloc = loc * 8;
   6860  1.1  mrg 	  if (byteloc == 0)
   6861  1.1  mrg 	    zap_op = op;
   6862  1.1  mrg 	  else
   6863  1.1  mrg 	    temp <<= byteloc;
   6864  1.1  mrg 	}
   6865  1.1  mrg 
   6866  1.1  mrg       opint[0] = temp;
   6867  1.1  mrg       opint[1] = bytemask;
   6868  1.1  mrg       return alpha_fold_builtin_zapnot (zap_op, opint, op_const);
   6869  1.1  mrg     }
   6870  1.1  mrg 
   6871  1.1  mrg   return NULL;
   6872  1.1  mrg }
   6873  1.1  mrg 
   6874  1.1  mrg static tree
   6875  1.1  mrg alpha_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[],
   6876  1.1  mrg 			  long op_const, unsigned HOST_WIDE_INT bytemask,
   6877  1.1  mrg 			  bool is_high)
   6878  1.1  mrg {
   6879  1.1  mrg   if (op_const & 2)
   6880  1.1  mrg     {
   6881  1.1  mrg       unsigned HOST_WIDE_INT loc;
   6882  1.1  mrg 
   6883  1.1  mrg       loc = opint[1] & 7;
   6884  1.1  mrg       bytemask <<= loc;
   6885  1.1  mrg 
   6886  1.1  mrg       if (is_high)
   6887  1.1  mrg 	bytemask >>= 8;
   6888  1.1  mrg 
   6889  1.1  mrg       opint[1] = bytemask ^ 0xff;
   6890  1.1  mrg     }
   6891  1.1  mrg 
   6892  1.1  mrg   return alpha_fold_builtin_zapnot (op, opint, op_const);
   6893  1.1  mrg }
   6894  1.1  mrg 
   6895  1.1  mrg static tree
   6896  1.1  mrg alpha_fold_vector_minmax (enum tree_code code, tree op[], tree vtype)
   6897  1.1  mrg {
   6898  1.1  mrg   tree op0 = fold_convert (vtype, op[0]);
   6899  1.1  mrg   tree op1 = fold_convert (vtype, op[1]);
   6900  1.1  mrg   tree val = fold_build2 (code, vtype, op0, op1);
   6901  1.1  mrg   return fold_build1 (VIEW_CONVERT_EXPR, alpha_dimode_u, val);
   6902  1.1  mrg }
   6903  1.1  mrg 
   6904  1.1  mrg static tree
   6905  1.1  mrg alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const)
   6906  1.1  mrg {
   6907  1.1  mrg   unsigned HOST_WIDE_INT temp = 0;
   6908  1.1  mrg   int i;
   6909  1.1  mrg 
   6910  1.1  mrg   if (op_const != 3)
   6911  1.1  mrg     return NULL;
   6912  1.1  mrg 
   6913  1.1  mrg   for (i = 0; i < 8; ++i)
   6914  1.1  mrg     {
   6915  1.1  mrg       unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff;
   6916  1.1  mrg       unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff;
   6917  1.1  mrg       if (a >= b)
   6918  1.1  mrg 	temp += a - b;
   6919  1.1  mrg       else
   6920  1.1  mrg 	temp += b - a;
   6921  1.1  mrg     }
   6922  1.1  mrg 
   6923  1.1  mrg   return build_int_cst (alpha_dimode_u, temp);
   6924  1.1  mrg }
   6925  1.1  mrg 
   6926  1.1  mrg static tree
   6927  1.1  mrg alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const)
   6928  1.1  mrg {
   6929  1.1  mrg   unsigned HOST_WIDE_INT temp;
   6930  1.1  mrg 
   6931  1.1  mrg   if (op_const == 0)
   6932  1.1  mrg     return NULL;
   6933  1.1  mrg 
   6934  1.1  mrg   temp = opint[0] & 0xff;
   6935  1.1  mrg   temp |= (opint[0] >> 24) & 0xff00;
   6936  1.1  mrg 
   6937  1.1  mrg   return build_int_cst (alpha_dimode_u, temp);
   6938  1.1  mrg }
   6939  1.1  mrg 
   6940  1.1  mrg static tree
   6941  1.1  mrg alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const)
   6942  1.1  mrg {
   6943  1.1  mrg   unsigned HOST_WIDE_INT temp;
   6944  1.1  mrg 
   6945  1.1  mrg   if (op_const == 0)
   6946  1.1  mrg     return NULL;
   6947  1.1  mrg 
   6948  1.1  mrg   temp = opint[0] & 0xff;
   6949  1.1  mrg   temp |= (opint[0] >>  8) & 0xff00;
   6950  1.1  mrg   temp |= (opint[0] >> 16) & 0xff0000;
   6951  1.1  mrg   temp |= (opint[0] >> 24) & 0xff000000;
   6952  1.1  mrg 
   6953  1.1  mrg   return build_int_cst (alpha_dimode_u, temp);
   6954  1.1  mrg }
   6955  1.1  mrg 
   6956  1.1  mrg static tree
   6957  1.1  mrg alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const)
   6958  1.1  mrg {
   6959  1.1  mrg   unsigned HOST_WIDE_INT temp;
   6960  1.1  mrg 
   6961  1.1  mrg   if (op_const == 0)
   6962  1.1  mrg     return NULL;
   6963  1.1  mrg 
   6964  1.1  mrg   temp = opint[0] & 0xff;
   6965  1.1  mrg   temp |= (opint[0] & 0xff00) << 24;
   6966  1.1  mrg 
   6967  1.1  mrg   return build_int_cst (alpha_dimode_u, temp);
   6968  1.1  mrg }
   6969  1.1  mrg 
   6970  1.1  mrg static tree
   6971  1.1  mrg alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const)
   6972  1.1  mrg {
   6973  1.1  mrg   unsigned HOST_WIDE_INT temp;
   6974  1.1  mrg 
   6975  1.1  mrg   if (op_const == 0)
   6976  1.1  mrg     return NULL;
   6977  1.1  mrg 
   6978  1.1  mrg   temp = opint[0] & 0xff;
   6979  1.1  mrg   temp |= (opint[0] & 0x0000ff00) << 8;
   6980  1.1  mrg   temp |= (opint[0] & 0x00ff0000) << 16;
   6981  1.1  mrg   temp |= (opint[0] & 0xff000000) << 24;
   6982  1.1  mrg 
   6983  1.1  mrg   return build_int_cst (alpha_dimode_u, temp);
   6984  1.1  mrg }
   6985  1.1  mrg 
   6986  1.1  mrg static tree
   6987  1.1  mrg alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const)
   6988  1.1  mrg {
   6989  1.1  mrg   unsigned HOST_WIDE_INT temp;
   6990  1.1  mrg 
   6991  1.1  mrg   if (op_const == 0)
   6992  1.1  mrg     return NULL;
   6993  1.1  mrg 
   6994  1.1  mrg   if (opint[0] == 0)
   6995  1.1  mrg     temp = 64;
   6996  1.1  mrg   else
   6997  1.1  mrg     temp = exact_log2 (opint[0] & -opint[0]);
   6998  1.1  mrg 
   6999  1.1  mrg   return build_int_cst (alpha_dimode_u, temp);
   7000  1.1  mrg }
   7001  1.1  mrg 
   7002  1.1  mrg static tree
   7003  1.1  mrg alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const)
   7004  1.1  mrg {
   7005  1.1  mrg   unsigned HOST_WIDE_INT temp;
   7006  1.1  mrg 
   7007  1.1  mrg   if (op_const == 0)
   7008  1.1  mrg     return NULL;
   7009  1.1  mrg 
   7010  1.1  mrg   if (opint[0] == 0)
   7011  1.1  mrg     temp = 64;
   7012  1.1  mrg   else
   7013  1.1  mrg     temp = 64 - floor_log2 (opint[0]) - 1;
   7014  1.1  mrg 
   7015  1.1  mrg   return build_int_cst (alpha_dimode_u, temp);
   7016  1.1  mrg }
   7017  1.1  mrg 
   7018  1.1  mrg static tree
   7019  1.1  mrg alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const)
   7020  1.1  mrg {
   7021  1.1  mrg   unsigned HOST_WIDE_INT temp, op;
   7022  1.1  mrg 
   7023  1.1  mrg   if (op_const == 0)
   7024  1.1  mrg     return NULL;
   7025  1.1  mrg 
   7026  1.1  mrg   op = opint[0];
   7027  1.1  mrg   temp = 0;
   7028  1.1  mrg   while (op)
   7029  1.1  mrg     temp++, op &= op - 1;
   7030  1.1  mrg 
   7031  1.1  mrg   return build_int_cst (alpha_dimode_u, temp);
   7032  1.1  mrg }
   7033  1.1  mrg 
   7034  1.1  mrg /* Fold one of our builtin functions.  */
   7035  1.1  mrg 
   7036  1.1  mrg static tree
   7037  1.1  mrg alpha_fold_builtin (tree fndecl, int n_args, tree *op,
   7038  1.1  mrg 		    bool ignore ATTRIBUTE_UNUSED)
   7039  1.1  mrg {
   7040  1.1  mrg   unsigned HOST_WIDE_INT opint[MAX_ARGS];
   7041  1.1  mrg   long op_const = 0;
   7042  1.1  mrg   int i;
   7043  1.1  mrg 
   7044  1.1  mrg   if (n_args > MAX_ARGS)
   7045  1.1  mrg     return NULL;
   7046  1.1  mrg 
   7047  1.1  mrg   for (i = 0; i < n_args; i++)
   7048  1.1  mrg     {
   7049  1.1  mrg       tree arg = op[i];
   7050  1.1  mrg       if (arg == error_mark_node)
   7051  1.1  mrg 	return NULL;
   7052  1.1  mrg 
   7053  1.1  mrg       opint[i] = 0;
   7054  1.1  mrg       if (TREE_CODE (arg) == INTEGER_CST)
   7055  1.1  mrg 	{
   7056  1.1  mrg           op_const |= 1L << i;
   7057  1.1  mrg 	  opint[i] = int_cst_value (arg);
   7058  1.1  mrg 	}
   7059  1.1  mrg     }
   7060  1.1  mrg 
   7061  1.1  mrg   switch (DECL_MD_FUNCTION_CODE (fndecl))
   7062  1.1  mrg     {
   7063  1.1  mrg     case ALPHA_BUILTIN_CMPBGE:
   7064  1.1  mrg       return alpha_fold_builtin_cmpbge (opint, op_const);
   7065  1.1  mrg 
   7066  1.1  mrg     case ALPHA_BUILTIN_EXTBL:
   7067  1.1  mrg       return alpha_fold_builtin_extxx (op, opint, op_const, 0x01, false);
   7068  1.1  mrg     case ALPHA_BUILTIN_EXTWL:
   7069  1.1  mrg       return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, false);
   7070  1.1  mrg     case ALPHA_BUILTIN_EXTLL:
   7071  1.1  mrg       return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, false);
   7072  1.1  mrg     case ALPHA_BUILTIN_EXTQL:
   7073  1.1  mrg       return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, false);
   7074  1.1  mrg     case ALPHA_BUILTIN_EXTWH:
   7075  1.1  mrg       return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, true);
   7076  1.1  mrg     case ALPHA_BUILTIN_EXTLH:
   7077  1.1  mrg       return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, true);
   7078  1.1  mrg     case ALPHA_BUILTIN_EXTQH:
   7079  1.1  mrg       return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, true);
   7080  1.1  mrg 
   7081  1.1  mrg     case ALPHA_BUILTIN_INSBL:
   7082  1.1  mrg       return alpha_fold_builtin_insxx (op, opint, op_const, 0x01, false);
   7083  1.1  mrg     case ALPHA_BUILTIN_INSWL:
   7084  1.1  mrg       return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, false);
   7085  1.1  mrg     case ALPHA_BUILTIN_INSLL:
   7086  1.1  mrg       return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, false);
   7087  1.1  mrg     case ALPHA_BUILTIN_INSQL:
   7088  1.1  mrg       return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, false);
   7089  1.1  mrg     case ALPHA_BUILTIN_INSWH:
   7090  1.1  mrg       return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, true);
   7091  1.1  mrg     case ALPHA_BUILTIN_INSLH:
   7092  1.1  mrg       return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, true);
   7093  1.1  mrg     case ALPHA_BUILTIN_INSQH:
   7094  1.1  mrg       return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, true);
   7095  1.1  mrg 
   7096  1.1  mrg     case ALPHA_BUILTIN_MSKBL:
   7097  1.1  mrg       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x01, false);
   7098  1.1  mrg     case ALPHA_BUILTIN_MSKWL:
   7099  1.1  mrg       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, false);
   7100  1.1  mrg     case ALPHA_BUILTIN_MSKLL:
   7101  1.1  mrg       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, false);
   7102  1.1  mrg     case ALPHA_BUILTIN_MSKQL:
   7103  1.1  mrg       return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, false);
   7104  1.1  mrg     case ALPHA_BUILTIN_MSKWH:
   7105  1.1  mrg       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, true);
   7106  1.1  mrg     case ALPHA_BUILTIN_MSKLH:
   7107  1.1  mrg       return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, true);
   7108  1.1  mrg     case ALPHA_BUILTIN_MSKQH:
   7109  1.1  mrg       return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);
   7110  1.1  mrg 
   7111  1.1  mrg     case ALPHA_BUILTIN_ZAP:
   7112  1.1  mrg       opint[1] ^= 0xff;
   7113  1.1  mrg       /* FALLTHRU */
   7114  1.1  mrg     case ALPHA_BUILTIN_ZAPNOT:
   7115  1.1  mrg       return alpha_fold_builtin_zapnot (op, opint, op_const);
   7116  1.1  mrg 
   7117  1.1  mrg     case ALPHA_BUILTIN_MINUB8:
   7118  1.1  mrg       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_u);
   7119  1.1  mrg     case ALPHA_BUILTIN_MINSB8:
   7120  1.1  mrg       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_s);
   7121  1.1  mrg     case ALPHA_BUILTIN_MINUW4:
   7122  1.1  mrg       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_u);
   7123  1.1  mrg     case ALPHA_BUILTIN_MINSW4:
   7124  1.1  mrg       return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_s);
   7125  1.1  mrg     case ALPHA_BUILTIN_MAXUB8:
   7126  1.1  mrg       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_u);
   7127  1.1  mrg     case ALPHA_BUILTIN_MAXSB8:
   7128  1.1  mrg       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_s);
   7129  1.1  mrg     case ALPHA_BUILTIN_MAXUW4:
   7130  1.1  mrg       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_u);
   7131  1.1  mrg     case ALPHA_BUILTIN_MAXSW4:
   7132  1.1  mrg       return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_s);
   7133  1.1  mrg 
   7134  1.1  mrg     case ALPHA_BUILTIN_PERR:
   7135  1.1  mrg       return alpha_fold_builtin_perr (opint, op_const);
   7136  1.1  mrg     case ALPHA_BUILTIN_PKLB:
   7137  1.1  mrg       return alpha_fold_builtin_pklb (opint, op_const);
   7138  1.1  mrg     case ALPHA_BUILTIN_PKWB:
   7139  1.1  mrg       return alpha_fold_builtin_pkwb (opint, op_const);
   7140  1.1  mrg     case ALPHA_BUILTIN_UNPKBL:
   7141  1.1  mrg       return alpha_fold_builtin_unpkbl (opint, op_const);
   7142  1.1  mrg     case ALPHA_BUILTIN_UNPKBW:
   7143  1.1  mrg       return alpha_fold_builtin_unpkbw (opint, op_const);
   7144  1.1  mrg 
   7145  1.1  mrg     case ALPHA_BUILTIN_CTTZ:
   7146  1.1  mrg       return alpha_fold_builtin_cttz (opint, op_const);
   7147  1.1  mrg     case ALPHA_BUILTIN_CTLZ:
   7148  1.1  mrg       return alpha_fold_builtin_ctlz (opint, op_const);
   7149  1.1  mrg     case ALPHA_BUILTIN_CTPOP:
   7150  1.1  mrg       return alpha_fold_builtin_ctpop (opint, op_const);
   7151  1.1  mrg 
   7152  1.1  mrg     case ALPHA_BUILTIN_AMASK:
   7153  1.1  mrg     case ALPHA_BUILTIN_IMPLVER:
   7154  1.1  mrg     case ALPHA_BUILTIN_RPCC:
   7155  1.1  mrg       /* None of these are foldable at compile-time.  */
   7156  1.1  mrg     default:
   7157  1.1  mrg       return NULL;
   7158  1.1  mrg     }
   7159  1.1  mrg }
   7160  1.1  mrg 
   7161  1.1  mrg bool
   7162  1.1  mrg alpha_gimple_fold_builtin (gimple_stmt_iterator *gsi)
   7163  1.1  mrg {
   7164  1.1  mrg   bool changed = false;
   7165  1.1  mrg   gimple *stmt = gsi_stmt (*gsi);
   7166  1.1  mrg   tree call = gimple_call_fn (stmt);
   7167  1.1  mrg   gimple *new_stmt = NULL;
   7168  1.1  mrg 
   7169  1.1  mrg   if (call)
   7170  1.1  mrg     {
   7171  1.1  mrg       tree fndecl = gimple_call_fndecl (stmt);
   7172  1.1  mrg 
   7173  1.1  mrg       if (fndecl)
   7174  1.1  mrg 	{
   7175  1.1  mrg 	  tree arg0, arg1;
   7176  1.1  mrg 
   7177  1.1  mrg 	  switch (DECL_MD_FUNCTION_CODE (fndecl))
   7178  1.1  mrg 	    {
   7179  1.1  mrg 	    case ALPHA_BUILTIN_UMULH:
   7180  1.1  mrg 	      arg0 = gimple_call_arg (stmt, 0);
   7181  1.1  mrg 	      arg1 = gimple_call_arg (stmt, 1);
   7182  1.1  mrg 
   7183  1.1  mrg 	      new_stmt = gimple_build_assign (gimple_call_lhs (stmt),
   7184  1.1  mrg 					      MULT_HIGHPART_EXPR, arg0, arg1);
   7185  1.1  mrg 	      break;
   7186  1.1  mrg 	    default:
   7187  1.1  mrg 	      break;
   7188  1.1  mrg 	    }
   7189  1.1  mrg 	}
   7190  1.1  mrg     }
   7191  1.1  mrg 
   7192  1.1  mrg   if (new_stmt)
   7193  1.1  mrg     {
   7194  1.1  mrg       gsi_replace (gsi, new_stmt, true);
   7195  1.1  mrg       changed = true;
   7196  1.1  mrg     }
   7197  1.1  mrg 
   7198  1.1  mrg   return changed;
   7199  1.1  mrg }
   7200  1.1  mrg 
   7201  1.1  mrg /* This page contains routines that are used to determine what the function
   7203  1.1  mrg    prologue and epilogue code will do and write them out.  */
   7204  1.1  mrg 
   7205  1.1  mrg /* Compute the size of the save area in the stack.  */
   7206  1.1  mrg 
   7207  1.1  mrg /* These variables are used for communication between the following functions.
   7208  1.1  mrg    They indicate various things about the current function being compiled
   7209  1.1  mrg    that are used to tell what kind of prologue, epilogue and procedure
   7210  1.1  mrg    descriptor to generate.  */
   7211  1.1  mrg 
   7212  1.1  mrg /* Nonzero if we need a stack procedure.  */
   7213  1.1  mrg enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
   7214  1.1  mrg static enum alpha_procedure_types alpha_procedure_type;
   7215  1.1  mrg 
   7216  1.1  mrg /* Register number (either FP or SP) that is used to unwind the frame.  */
   7217  1.1  mrg static int vms_unwind_regno;
   7218  1.1  mrg 
   7219  1.1  mrg /* Register number used to save FP.  We need not have one for RA since
   7220  1.1  mrg    we don't modify it for register procedures.  This is only defined
   7221  1.1  mrg    for register frame procedures.  */
   7222  1.1  mrg static int vms_save_fp_regno;
   7223  1.1  mrg 
   7224  1.1  mrg /* Register number used to reference objects off our PV.  */
   7225  1.1  mrg static int vms_base_regno;
   7226  1.1  mrg 
   7227  1.1  mrg /* Compute register masks for saved registers, register save area size,
   7228  1.1  mrg    and total frame size.  */
   7229  1.1  mrg static void
   7230  1.1  mrg alpha_compute_frame_layout (void)
   7231  1.1  mrg {
   7232  1.1  mrg   unsigned HOST_WIDE_INT sa_mask = 0;
   7233  1.1  mrg   HOST_WIDE_INT frame_size;
   7234  1.1  mrg   int sa_size;
   7235  1.1  mrg 
   7236  1.1  mrg   /* When outputting a thunk, we don't have valid register life info,
   7237  1.1  mrg      but assemble_start_function wants to output .frame and .mask
   7238  1.1  mrg      directives.  */
   7239  1.1  mrg   if (!cfun->is_thunk)
   7240  1.1  mrg     {
   7241  1.1  mrg       if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
   7242  1.1  mrg 	sa_mask |= HOST_WIDE_INT_1U << HARD_FRAME_POINTER_REGNUM;
   7243  1.1  mrg 
   7244  1.1  mrg       /* One for every register we have to save.  */
   7245  1.1  mrg       for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   7246  1.1  mrg 	if (! call_used_or_fixed_reg_p (i)
   7247  1.1  mrg 	    && df_regs_ever_live_p (i) && i != REG_RA)
   7248  1.1  mrg 	  sa_mask |= HOST_WIDE_INT_1U << i;
   7249  1.1  mrg 
   7250  1.1  mrg       /* We need to restore these for the handler.  */
   7251  1.1  mrg       if (crtl->calls_eh_return)
   7252  1.1  mrg 	{
   7253  1.1  mrg 	  for (unsigned i = 0; ; ++i)
   7254  1.1  mrg 	    {
   7255  1.1  mrg 	      unsigned regno = EH_RETURN_DATA_REGNO (i);
   7256  1.1  mrg 	      if (regno == INVALID_REGNUM)
   7257  1.1  mrg 		break;
   7258  1.1  mrg 	      sa_mask |= HOST_WIDE_INT_1U << regno;
   7259  1.1  mrg 	    }
   7260  1.1  mrg 	}
   7261  1.1  mrg 
   7262  1.1  mrg       /* If any register spilled, then spill the return address also.  */
   7263  1.1  mrg       /* ??? This is required by the Digital stack unwind specification
   7264  1.1  mrg 	 and isn't needed if we're doing Dwarf2 unwinding.  */
   7265  1.1  mrg       if (sa_mask || alpha_ra_ever_killed ())
   7266  1.1  mrg 	sa_mask |= HOST_WIDE_INT_1U << REG_RA;
   7267  1.1  mrg     }
   7268  1.1  mrg 
   7269  1.1  mrg   sa_size = popcount_hwi(sa_mask);
   7270  1.1  mrg   frame_size = get_frame_size ();
   7271  1.1  mrg 
   7272  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   7273  1.1  mrg     {
   7274  1.1  mrg       /* Start with a stack procedure if we make any calls (REG_RA used), or
   7275  1.1  mrg 	 need a frame pointer, with a register procedure if we otherwise need
   7276  1.1  mrg 	 at least a slot, and with a null procedure in other cases.  */
   7277  1.1  mrg       if ((sa_mask >> REG_RA) & 1 || frame_pointer_needed)
   7278  1.1  mrg 	alpha_procedure_type = PT_STACK;
   7279  1.1  mrg       else if (frame_size != 0)
   7280  1.1  mrg 	alpha_procedure_type = PT_REGISTER;
   7281  1.1  mrg       else
   7282  1.1  mrg 	alpha_procedure_type = PT_NULL;
   7283  1.1  mrg 
   7284  1.1  mrg       /* Don't reserve space for saving FP & RA yet.  Do that later after we've
   7285  1.1  mrg 	 made the final decision on stack procedure vs register procedure.  */
   7286  1.1  mrg       if (alpha_procedure_type == PT_STACK)
   7287  1.1  mrg 	sa_size -= 2;
   7288  1.1  mrg 
   7289  1.1  mrg       /* Decide whether to refer to objects off our PV via FP or PV.
   7290  1.1  mrg 	 If we need FP for something else or if we receive a nonlocal
   7291  1.1  mrg 	 goto (which expects PV to contain the value), we must use PV.
   7292  1.1  mrg 	 Otherwise, start by assuming we can use FP.  */
   7293  1.1  mrg 
   7294  1.1  mrg       vms_base_regno
   7295  1.1  mrg 	= (frame_pointer_needed
   7296  1.1  mrg 	   || cfun->has_nonlocal_label
   7297  1.1  mrg 	   || alpha_procedure_type == PT_STACK
   7298  1.1  mrg 	   || crtl->outgoing_args_size)
   7299  1.1  mrg 	  ? REG_PV : HARD_FRAME_POINTER_REGNUM;
   7300  1.1  mrg 
   7301  1.1  mrg       /* If we want to copy PV into FP, we need to find some register
   7302  1.1  mrg 	 in which to save FP.  */
   7303  1.1  mrg       vms_save_fp_regno = -1;
   7304  1.1  mrg       if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
   7305  1.1  mrg 	for (unsigned i = 0; i < 32; i++)
   7306  1.1  mrg 	  if (! fixed_regs[i] && call_used_or_fixed_reg_p (i)
   7307  1.1  mrg 	      && ! df_regs_ever_live_p (i))
   7308  1.1  mrg 	    {
   7309  1.1  mrg 	      vms_save_fp_regno = i;
   7310  1.1  mrg 	      break;
   7311  1.1  mrg 	    }
   7312  1.1  mrg 
   7313  1.1  mrg       /* A VMS condition handler requires a stack procedure in our
   7314  1.1  mrg 	 implementation. (not required by the calling standard).  */
   7315  1.1  mrg       if ((vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
   7316  1.1  mrg 	  || cfun->machine->uses_condition_handler)
   7317  1.1  mrg 	vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
   7318  1.1  mrg       else if (alpha_procedure_type == PT_NULL)
   7319  1.1  mrg 	vms_base_regno = REG_PV;
   7320  1.1  mrg 
   7321  1.1  mrg       /* Stack unwinding should be done via FP unless we use it for PV.  */
   7322  1.1  mrg       vms_unwind_regno = (vms_base_regno == REG_PV
   7323  1.1  mrg 			  ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
   7324  1.1  mrg 
   7325  1.1  mrg       /* If this is a stack procedure, allow space for saving FP, RA and
   7326  1.1  mrg 	 a condition handler slot if needed.  */
   7327  1.1  mrg       if (alpha_procedure_type == PT_STACK)
   7328  1.1  mrg 	sa_size += 2 + cfun->machine->uses_condition_handler;
   7329  1.1  mrg     }
   7330  1.1  mrg   else
   7331  1.1  mrg     {
   7332  1.1  mrg       /* Our size must be even (multiple of 16 bytes).  */
   7333  1.1  mrg       if (sa_size & 1)
   7334  1.1  mrg 	sa_size++;
   7335  1.1  mrg     }
   7336  1.1  mrg   sa_size *= 8;
   7337  1.1  mrg 
   7338  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   7339  1.1  mrg     frame_size = ALPHA_ROUND (sa_size
   7340  1.1  mrg 			      + (alpha_procedure_type == PT_STACK ? 8 : 0)
   7341  1.1  mrg 			      + frame_size
   7342  1.1  mrg 			      + crtl->args.pretend_args_size);
   7343  1.1  mrg   else
   7344  1.1  mrg     frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
   7345  1.1  mrg 		  + sa_size
   7346  1.1  mrg 		  + ALPHA_ROUND (frame_size + crtl->args.pretend_args_size));
   7347  1.1  mrg 
   7348  1.1  mrg   cfun->machine->sa_mask = sa_mask;
   7349  1.1  mrg   cfun->machine->sa_size = sa_size;
   7350  1.1  mrg   cfun->machine->frame_size = frame_size;
   7351  1.1  mrg }
   7352  1.1  mrg 
   7353  1.1  mrg #undef  TARGET_COMPUTE_FRAME_LAYOUT
   7354  1.1  mrg #define TARGET_COMPUTE_FRAME_LAYOUT  alpha_compute_frame_layout
   7355  1.1  mrg 
   7356  1.1  mrg /* Return 1 if this function can directly return via $26.  */
   7357  1.1  mrg 
   7358  1.1  mrg bool
   7359  1.1  mrg direct_return (void)
   7360  1.1  mrg {
   7361  1.1  mrg   return (TARGET_ABI_OSF
   7362  1.1  mrg 	  && reload_completed
   7363  1.1  mrg 	  && cfun->machine->frame_size == 0);
   7364  1.1  mrg }
   7365  1.1  mrg 
   7366  1.1  mrg /* Define the offset between two registers, one to be eliminated,
   7367  1.1  mrg    and the other its replacement, at the start of a routine.  */
   7368  1.1  mrg 
   7369  1.1  mrg HOST_WIDE_INT
   7370  1.1  mrg alpha_initial_elimination_offset (unsigned int from,
   7371  1.1  mrg 				  unsigned int to ATTRIBUTE_UNUSED)
   7372  1.1  mrg {
   7373  1.1  mrg   HOST_WIDE_INT ret;
   7374  1.1  mrg 
   7375  1.1  mrg   ret = cfun->machine->sa_size;
   7376  1.1  mrg   ret += ALPHA_ROUND (crtl->outgoing_args_size);
   7377  1.1  mrg 
   7378  1.1  mrg   switch (from)
   7379  1.1  mrg     {
   7380  1.1  mrg     case FRAME_POINTER_REGNUM:
   7381  1.1  mrg       break;
   7382  1.1  mrg 
   7383  1.1  mrg     case ARG_POINTER_REGNUM:
   7384  1.1  mrg       ret += (ALPHA_ROUND (get_frame_size ()
   7385  1.1  mrg 			   + crtl->args.pretend_args_size)
   7386  1.1  mrg 	      - crtl->args.pretend_args_size);
   7387  1.1  mrg       break;
   7388  1.1  mrg 
   7389  1.1  mrg     default:
   7390  1.1  mrg       gcc_unreachable ();
   7391  1.1  mrg     }
   7392  1.1  mrg 
   7393  1.1  mrg   return ret;
   7394  1.1  mrg }
   7395  1.1  mrg 
   7396  1.1  mrg #if TARGET_ABI_OPEN_VMS
   7397  1.1  mrg 
   7398  1.1  mrg /* Worker function for TARGET_CAN_ELIMINATE.  */
   7399  1.1  mrg 
   7400  1.1  mrg static bool
   7401  1.1  mrg alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
   7402  1.1  mrg {
   7403  1.1  mrg   switch (alpha_procedure_type)
   7404  1.1  mrg     {
   7405  1.1  mrg     case PT_NULL:
   7406  1.1  mrg       /* NULL procedures have no frame of their own and we only
   7407  1.1  mrg 	 know how to resolve from the current stack pointer.  */
   7408  1.1  mrg       return to == STACK_POINTER_REGNUM;
   7409  1.1  mrg 
   7410  1.1  mrg     case PT_REGISTER:
   7411  1.1  mrg     case PT_STACK:
   7412  1.1  mrg       /* We always eliminate except to the stack pointer if there is no
   7413  1.1  mrg 	 usable frame pointer at hand.  */
   7414  1.1  mrg       return (to != STACK_POINTER_REGNUM
   7415  1.1  mrg 	      || vms_unwind_regno != HARD_FRAME_POINTER_REGNUM);
   7416  1.1  mrg     }
   7417  1.1  mrg 
   7418  1.1  mrg   gcc_unreachable ();
   7419  1.1  mrg }
   7420  1.1  mrg 
   7421  1.1  mrg /* FROM is to be eliminated for TO. Return the offset so that TO+offset
   7422  1.1  mrg    designates the same location as FROM.  */
   7423  1.1  mrg 
   7424  1.1  mrg HOST_WIDE_INT
   7425  1.1  mrg alpha_vms_initial_elimination_offset (unsigned int from, unsigned int to)
   7426  1.1  mrg {
   7427  1.1  mrg   /* The only possible attempts we ever expect are ARG or FRAME_PTR to
   7428  1.1  mrg      HARD_FRAME or STACK_PTR.  We need the alpha_procedure_type to decide
   7429  1.1  mrg      on the proper computations and will need the register save area size
   7430  1.1  mrg      in most cases.  */
   7431  1.1  mrg 
   7432  1.1  mrg   HOST_WIDE_INT sa_size = cfun->machine->sa_size;
   7433  1.1  mrg 
   7434  1.1  mrg   /* PT_NULL procedures have no frame of their own and we only allow
   7435  1.1  mrg      elimination to the stack pointer. This is the argument pointer and we
   7436  1.1  mrg      resolve the soft frame pointer to that as well.  */
   7437  1.1  mrg 
   7438  1.1  mrg   if (alpha_procedure_type == PT_NULL)
   7439  1.1  mrg     return 0;
   7440  1.1  mrg 
   7441  1.1  mrg   /* For a PT_STACK procedure the frame layout looks as follows
   7442  1.1  mrg 
   7443  1.1  mrg                       -----> decreasing addresses
   7444  1.1  mrg 
   7445  1.1  mrg 		   <             size rounded up to 16       |   likewise   >
   7446  1.1  mrg      --------------#------------------------------+++--------------+++-------#
   7447  1.1  mrg      incoming args # pretended args | "frame" | regs sa | PV | outgoing args #
   7448  1.1  mrg      --------------#---------------------------------------------------------#
   7449  1.1  mrg                                    ^         ^              ^               ^
   7450  1.1  mrg 			      ARG_PTR FRAME_PTR HARD_FRAME_PTR       STACK_PTR
   7451  1.1  mrg 
   7452  1.1  mrg 
   7453  1.1  mrg      PT_REGISTER procedures are similar in that they may have a frame of their
   7454  1.1  mrg      own. They have no regs-sa/pv/outgoing-args area.
   7455  1.1  mrg 
   7456  1.1  mrg      We first compute offset to HARD_FRAME_PTR, then add what we need to get
   7457  1.1  mrg      to STACK_PTR if need be.  */
   7458  1.1  mrg 
   7459  1.1  mrg   {
   7460  1.1  mrg     HOST_WIDE_INT offset;
   7461  1.1  mrg     HOST_WIDE_INT pv_save_size = alpha_procedure_type == PT_STACK ? 8 : 0;
   7462  1.1  mrg 
   7463  1.1  mrg     switch (from)
   7464  1.1  mrg       {
   7465  1.1  mrg       case FRAME_POINTER_REGNUM:
   7466  1.1  mrg 	offset = ALPHA_ROUND (sa_size + pv_save_size);
   7467  1.1  mrg 	break;
   7468  1.1  mrg       case ARG_POINTER_REGNUM:
   7469  1.1  mrg 	offset = (ALPHA_ROUND (sa_size + pv_save_size
   7470  1.1  mrg 			       + get_frame_size ()
   7471  1.1  mrg 			       + crtl->args.pretend_args_size)
   7472  1.1  mrg 		  - crtl->args.pretend_args_size);
   7473  1.1  mrg 	break;
   7474  1.1  mrg       default:
   7475  1.1  mrg 	gcc_unreachable ();
   7476  1.1  mrg       }
   7477  1.1  mrg 
   7478  1.1  mrg     if (to == STACK_POINTER_REGNUM)
   7479  1.1  mrg       offset += ALPHA_ROUND (crtl->outgoing_args_size);
   7480  1.1  mrg 
   7481  1.1  mrg     return offset;
   7482  1.1  mrg   }
   7483  1.1  mrg }
   7484  1.1  mrg 
   7485  1.1  mrg #define COMMON_OBJECT "common_object"
   7486  1.1  mrg 
   7487  1.1  mrg static tree
   7488  1.1  mrg common_object_handler (tree *node, tree name ATTRIBUTE_UNUSED,
   7489  1.1  mrg 		       tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED,
   7490  1.1  mrg 		       bool *no_add_attrs ATTRIBUTE_UNUSED)
   7491  1.1  mrg {
   7492  1.1  mrg   tree decl = *node;
   7493  1.1  mrg   gcc_assert (DECL_P (decl));
   7494  1.1  mrg 
   7495  1.1  mrg   DECL_COMMON (decl) = 1;
   7496  1.1  mrg   return NULL_TREE;
   7497  1.1  mrg }
   7498  1.1  mrg 
   7499  1.1  mrg static const struct attribute_spec vms_attribute_table[] =
   7500  1.1  mrg {
   7501  1.1  mrg   /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
   7502  1.1  mrg        affects_type_identity, handler, exclude } */
   7503  1.1  mrg   { COMMON_OBJECT,   0, 1, true,  false, false, false, common_object_handler,
   7504  1.1  mrg     NULL },
   7505  1.1  mrg   { NULL,            0, 0, false, false, false, false, NULL, NULL }
   7506  1.1  mrg };
   7507  1.1  mrg 
   7508  1.1  mrg void
   7509  1.1  mrg vms_output_aligned_decl_common(FILE *file, tree decl, const char *name,
   7510  1.1  mrg 			       unsigned HOST_WIDE_INT size,
   7511  1.1  mrg 			       unsigned int align)
   7512  1.1  mrg {
   7513  1.1  mrg   tree attr = DECL_ATTRIBUTES (decl);
   7514  1.1  mrg   fprintf (file, "%s", COMMON_ASM_OP);
   7515  1.1  mrg   assemble_name (file, name);
   7516  1.1  mrg   fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED, size);
   7517  1.1  mrg   /* ??? Unlike on OSF/1, the alignment factor is not in log units.  */
   7518  1.1  mrg   fprintf (file, ",%u", align / BITS_PER_UNIT);
   7519  1.1  mrg   if (attr)
   7520  1.1  mrg     {
   7521  1.1  mrg       attr = lookup_attribute (COMMON_OBJECT, attr);
   7522  1.1  mrg       if (attr)
   7523  1.1  mrg         fprintf (file, ",%s",
   7524  1.1  mrg 		 IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr))));
   7525  1.1  mrg     }
   7526  1.1  mrg   fputc ('\n', file);
   7527  1.1  mrg }
   7528  1.1  mrg 
   7529  1.1  mrg #undef COMMON_OBJECT
   7530  1.1  mrg 
   7531  1.1  mrg #endif
   7532  1.1  mrg 
   7533  1.1  mrg bool
   7534  1.1  mrg alpha_find_lo_sum_using_gp (rtx insn)
   7535  1.1  mrg {
   7536  1.1  mrg   subrtx_iterator::array_type array;
   7537  1.1  mrg   FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
   7538  1.1  mrg     {
   7539  1.1  mrg       const_rtx x = *iter;
   7540  1.1  mrg       if (GET_CODE (x) == LO_SUM && XEXP (x, 0) == pic_offset_table_rtx)
   7541  1.1  mrg 	return true;
   7542  1.1  mrg     }
   7543  1.1  mrg   return false;
   7544  1.1  mrg }
   7545  1.1  mrg 
   7546  1.1  mrg static int
   7547  1.1  mrg alpha_does_function_need_gp (void)
   7548  1.1  mrg {
   7549  1.1  mrg   rtx_insn *insn;
   7550  1.1  mrg 
   7551  1.1  mrg   /* The GP being variable is an OSF abi thing.  */
   7552  1.1  mrg   if (! TARGET_ABI_OSF)
   7553  1.1  mrg     return 0;
   7554  1.1  mrg 
   7555  1.1  mrg   /* We need the gp to load the address of __mcount.  */
   7556  1.1  mrg   if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
   7557  1.1  mrg     return 1;
   7558  1.1  mrg 
   7559  1.1  mrg   /* The code emitted by alpha_output_mi_thunk_osf uses the gp.  */
   7560  1.1  mrg   if (cfun->is_thunk)
   7561  1.1  mrg     return 1;
   7562  1.1  mrg 
   7563  1.1  mrg   /* The nonlocal receiver pattern assumes that the gp is valid for
   7564  1.1  mrg      the nested function.  Reasonable because it's almost always set
   7565  1.1  mrg      correctly already.  For the cases where that's wrong, make sure
   7566  1.1  mrg      the nested function loads its gp on entry.  */
   7567  1.1  mrg   if (crtl->has_nonlocal_goto)
   7568  1.1  mrg     return 1;
   7569  1.1  mrg 
   7570  1.1  mrg   /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
   7571  1.1  mrg      Even if we are a static function, we still need to do this in case
   7572  1.1  mrg      our address is taken and passed to something like qsort.  */
   7573  1.1  mrg 
   7574  1.1  mrg   push_topmost_sequence ();
   7575  1.1  mrg   insn = get_insns ();
   7576  1.1  mrg   pop_topmost_sequence ();
   7577  1.1  mrg 
   7578  1.1  mrg   for (; insn; insn = NEXT_INSN (insn))
   7579  1.1  mrg     if (NONDEBUG_INSN_P (insn)
   7580  1.1  mrg 	&& GET_CODE (PATTERN (insn)) != USE
   7581  1.1  mrg 	&& GET_CODE (PATTERN (insn)) != CLOBBER
   7582  1.1  mrg 	&& get_attr_usegp (insn))
   7583  1.1  mrg       return 1;
   7584  1.1  mrg 
   7585  1.1  mrg   return 0;
   7586  1.1  mrg }
   7587  1.1  mrg 
   7588  1.1  mrg /* Helper function for alpha_store_data_bypass_p, handle just a single SET
   7589  1.1  mrg    IN_SET.  */
   7590  1.1  mrg 
   7591  1.1  mrg static bool
   7592  1.1  mrg alpha_store_data_bypass_p_1 (rtx_insn *out_insn, rtx in_set)
   7593  1.1  mrg {
   7594  1.1  mrg   if (!MEM_P (SET_DEST (in_set)))
   7595  1.1  mrg     return false;
   7596  1.1  mrg 
   7597  1.1  mrg   rtx out_set = single_set (out_insn);
   7598  1.1  mrg   if (out_set)
   7599  1.1  mrg     return !reg_mentioned_p (SET_DEST (out_set), SET_DEST (in_set));
   7600  1.1  mrg 
   7601  1.1  mrg   rtx out_pat = PATTERN (out_insn);
   7602  1.1  mrg   if (GET_CODE (out_pat) != PARALLEL)
   7603  1.1  mrg     return false;
   7604  1.1  mrg 
   7605  1.1  mrg   for (int i = 0; i < XVECLEN (out_pat, 0); i++)
   7606  1.1  mrg     {
   7607  1.1  mrg       rtx out_exp = XVECEXP (out_pat, 0, i);
   7608  1.1  mrg 
   7609  1.1  mrg       if (GET_CODE (out_exp) == CLOBBER || GET_CODE (out_exp) == USE
   7610  1.1  mrg 	  || GET_CODE (out_exp) == TRAP_IF)
   7611  1.1  mrg 	continue;
   7612  1.1  mrg 
   7613  1.1  mrg       gcc_assert (GET_CODE (out_exp) == SET);
   7614  1.1  mrg 
   7615  1.1  mrg       if (reg_mentioned_p (SET_DEST (out_exp), SET_DEST (in_set)))
   7616  1.1  mrg 	return false;
   7617  1.1  mrg     }
   7618  1.1  mrg 
   7619  1.1  mrg   return true;
   7620  1.1  mrg }
   7621  1.1  mrg 
   7622  1.1  mrg /* True if the dependency between OUT_INSN and IN_INSN is on the store
   7623  1.1  mrg    data not the address operand(s) of the store.  IN_INSN and OUT_INSN
   7624  1.1  mrg    must be either a single_set or a PARALLEL with SETs inside.
   7625  1.1  mrg 
   7626  1.1  mrg    This alpha-specific version of store_data_bypass_p ignores TRAP_IF
   7627  1.1  mrg    that would result in assertion failure (and internal compiler error)
   7628  1.1  mrg    in the generic store_data_bypass_p function.  */
   7629  1.1  mrg 
   7630  1.1  mrg int
   7631  1.1  mrg alpha_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
   7632  1.1  mrg {
   7633  1.1  mrg   rtx in_set = single_set (in_insn);
   7634  1.1  mrg   if (in_set)
   7635  1.1  mrg     return alpha_store_data_bypass_p_1 (out_insn, in_set);
   7636  1.1  mrg 
   7637  1.1  mrg   rtx in_pat = PATTERN (in_insn);
   7638  1.1  mrg   if (GET_CODE (in_pat) != PARALLEL)
   7639  1.1  mrg     return false;
   7640  1.1  mrg 
   7641  1.1  mrg   for (int i = 0; i < XVECLEN (in_pat, 0); i++)
   7642  1.1  mrg     {
   7643  1.1  mrg       rtx in_exp = XVECEXP (in_pat, 0, i);
   7644  1.1  mrg 
   7645  1.1  mrg       if (GET_CODE (in_exp) == CLOBBER || GET_CODE (in_exp) == USE
   7646  1.1  mrg 	  || GET_CODE (in_exp) == TRAP_IF)
   7647  1.1  mrg 	continue;
   7648  1.1  mrg 
   7649  1.1  mrg       gcc_assert (GET_CODE (in_exp) == SET);
   7650  1.1  mrg 
   7651  1.1  mrg       if (!alpha_store_data_bypass_p_1 (out_insn, in_exp))
   7652  1.1  mrg 	return false;
   7653  1.1  mrg     }
   7654  1.1  mrg 
   7655  1.1  mrg   return true;
   7656  1.1  mrg }
   7657  1.1  mrg 
   7658  1.1  mrg /* Helper function to set RTX_FRAME_RELATED_P on instructions, including
   7660  1.1  mrg    sequences.  */
   7661  1.1  mrg 
   7662  1.1  mrg static rtx_insn *
   7663  1.1  mrg set_frame_related_p (void)
   7664  1.1  mrg {
   7665  1.1  mrg   rtx_insn *seq = get_insns ();
   7666  1.1  mrg   rtx_insn *insn;
   7667  1.1  mrg 
   7668  1.1  mrg   end_sequence ();
   7669  1.1  mrg 
   7670  1.1  mrg   if (!seq)
   7671  1.1  mrg     return NULL;
   7672  1.1  mrg 
   7673  1.1  mrg   if (INSN_P (seq))
   7674  1.1  mrg     {
   7675  1.1  mrg       insn = seq;
   7676  1.1  mrg       while (insn != NULL_RTX)
   7677  1.1  mrg 	{
   7678  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
   7679  1.1  mrg 	  insn = NEXT_INSN (insn);
   7680  1.1  mrg 	}
   7681  1.1  mrg       seq = emit_insn (seq);
   7682  1.1  mrg     }
   7683  1.1  mrg   else
   7684  1.1  mrg     {
   7685  1.1  mrg       seq = emit_insn (seq);
   7686  1.1  mrg       RTX_FRAME_RELATED_P (seq) = 1;
   7687  1.1  mrg     }
   7688  1.1  mrg   return seq;
   7689  1.1  mrg }
   7690  1.1  mrg 
   7691  1.1  mrg #define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())
   7692  1.1  mrg 
   7693  1.1  mrg /* Generates a store with the proper unwind info attached.  VALUE is
   7694  1.1  mrg    stored at BASE_REG+BASE_OFS.  If FRAME_BIAS is nonzero, then BASE_REG
   7695  1.1  mrg    contains SP+FRAME_BIAS, and that is the unwind info that should be
   7696  1.1  mrg    generated.  If FRAME_REG != VALUE, then VALUE is being stored on
   7697  1.1  mrg    behalf of FRAME_REG, and FRAME_REG should be present in the unwind.  */
   7698  1.1  mrg 
   7699  1.1  mrg static void
   7700  1.1  mrg emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
   7701  1.1  mrg 		    HOST_WIDE_INT base_ofs, rtx frame_reg)
   7702  1.1  mrg {
   7703  1.1  mrg   rtx addr, mem;
   7704  1.1  mrg   rtx_insn *insn;
   7705  1.1  mrg 
   7706  1.1  mrg   addr = plus_constant (Pmode, base_reg, base_ofs);
   7707  1.1  mrg   mem = gen_frame_mem (DImode, addr);
   7708  1.1  mrg 
   7709  1.1  mrg   insn = emit_move_insn (mem, value);
   7710  1.1  mrg   RTX_FRAME_RELATED_P (insn) = 1;
   7711  1.1  mrg 
   7712  1.1  mrg   if (frame_bias || value != frame_reg)
   7713  1.1  mrg     {
   7714  1.1  mrg       if (frame_bias)
   7715  1.1  mrg 	{
   7716  1.1  mrg 	  addr = plus_constant (Pmode, stack_pointer_rtx,
   7717  1.1  mrg 			        frame_bias + base_ofs);
   7718  1.1  mrg 	  mem = gen_rtx_MEM (DImode, addr);
   7719  1.1  mrg 	}
   7720  1.1  mrg 
   7721  1.1  mrg       add_reg_note (insn, REG_FRAME_RELATED_EXPR,
   7722  1.1  mrg 		    gen_rtx_SET (mem, frame_reg));
   7723  1.1  mrg     }
   7724  1.1  mrg }
   7725  1.1  mrg 
   7726  1.1  mrg static void
   7727  1.1  mrg emit_frame_store (unsigned int regno, rtx base_reg,
   7728  1.1  mrg 		  HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
   7729  1.1  mrg {
   7730  1.1  mrg   rtx reg = gen_rtx_REG (DImode, regno);
   7731  1.1  mrg   emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
   7732  1.1  mrg }
   7733  1.1  mrg 
   7734  1.1  mrg /* Write function prologue.  */
   7735  1.1  mrg 
   7736  1.1  mrg /* On vms we have two kinds of functions:
   7737  1.1  mrg 
   7738  1.1  mrg    - stack frame (PROC_STACK)
   7739  1.1  mrg 	these are 'normal' functions with local vars and which are
   7740  1.1  mrg 	calling other functions
   7741  1.1  mrg    - register frame (PROC_REGISTER)
   7742  1.1  mrg 	keeps all data in registers, needs no stack
   7743  1.1  mrg 
   7744  1.1  mrg    We must pass this to the assembler so it can generate the
   7745  1.1  mrg    proper pdsc (procedure descriptor)
   7746  1.1  mrg    This is done with the '.pdesc' command.
   7747  1.1  mrg 
   7748  1.1  mrg    On not-vms, we don't really differentiate between the two, as we can
   7749  1.1  mrg    simply allocate stack without saving registers.  */
   7750  1.1  mrg 
   7751  1.1  mrg void
   7752  1.1  mrg alpha_expand_prologue (void)
   7753  1.1  mrg {
   7754  1.1  mrg   /* Registers to save.  */
   7755  1.1  mrg   unsigned HOST_WIDE_INT sa_mask = cfun->machine->sa_mask;
   7756  1.1  mrg   /* Stack space needed for pushing registers clobbered by us.  */
   7757  1.1  mrg   HOST_WIDE_INT sa_size = cfun->machine->sa_size;
   7758  1.1  mrg   /* Complete stack size needed.  */
   7759  1.1  mrg   HOST_WIDE_INT frame_size = cfun->machine->frame_size;
   7760  1.1  mrg   /* Probed stack size; it additionally includes the size of
   7761  1.1  mrg      the "reserve region" if any.  */
   7762  1.1  mrg   HOST_WIDE_INT probed_size, sa_bias;
   7763  1.1  mrg   /* Offset from base reg to register save area.  */
   7764  1.1  mrg   HOST_WIDE_INT reg_offset;
   7765  1.1  mrg   rtx sa_reg;
   7766  1.1  mrg 
   7767  1.1  mrg   if (flag_stack_usage_info)
   7768  1.1  mrg     current_function_static_stack_size = frame_size;
   7769  1.1  mrg 
   7770  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   7771  1.1  mrg     reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
   7772  1.1  mrg   else
   7773  1.1  mrg     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
   7774  1.1  mrg 
   7775  1.1  mrg   /* Emit an insn to reload GP, if needed.  */
   7776  1.1  mrg   if (TARGET_ABI_OSF)
   7777  1.1  mrg     {
   7778  1.1  mrg       alpha_function_needs_gp = alpha_does_function_need_gp ();
   7779  1.1  mrg       if (alpha_function_needs_gp)
   7780  1.1  mrg 	emit_insn (gen_prologue_ldgp ());
   7781  1.1  mrg     }
   7782  1.1  mrg 
   7783  1.1  mrg   /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
   7784  1.1  mrg      the call to mcount ourselves, rather than having the linker do it
   7785  1.1  mrg      magically in response to -pg.  Since _mcount has special linkage,
   7786  1.1  mrg      don't represent the call as a call.  */
   7787  1.1  mrg   if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
   7788  1.1  mrg     emit_insn (gen_prologue_mcount ());
   7789  1.1  mrg 
   7790  1.1  mrg   /* Adjust the stack by the frame size.  If the frame size is > 4096
   7791  1.1  mrg      bytes, we need to be sure we probe somewhere in the first and last
   7792  1.1  mrg      4096 bytes (we can probably get away without the latter test) and
   7793  1.1  mrg      every 8192 bytes in between.  If the frame size is > 32768, we
   7794  1.1  mrg      do this in a loop.  Otherwise, we generate the explicit probe
   7795  1.1  mrg      instructions.
   7796  1.1  mrg 
   7797  1.1  mrg      Note that we are only allowed to adjust sp once in the prologue.  */
   7798  1.1  mrg 
   7799  1.1  mrg   probed_size = frame_size;
   7800  1.1  mrg   if (flag_stack_check || flag_stack_clash_protection)
   7801  1.1  mrg     probed_size += get_stack_check_protect ();
   7802  1.1  mrg 
   7803  1.1  mrg   if (probed_size <= 32768)
   7804  1.1  mrg     {
   7805  1.1  mrg       if (probed_size > 4096)
   7806  1.1  mrg 	{
   7807  1.1  mrg 	  int probed;
   7808  1.1  mrg 
   7809  1.1  mrg 	  for (probed = 4096; probed < probed_size; probed += 8192)
   7810  1.1  mrg 	    emit_insn (gen_stack_probe_internal (GEN_INT (-probed)));
   7811  1.1  mrg 
   7812  1.1  mrg 	  /* We only have to do this probe if we aren't saving registers or
   7813  1.1  mrg 	     if we are probing beyond the frame because of -fstack-check.  */
   7814  1.1  mrg 	  if ((sa_size == 0 && probed_size > probed - 4096)
   7815  1.1  mrg 	      || flag_stack_check || flag_stack_clash_protection)
   7816  1.1  mrg 	    emit_insn (gen_stack_probe_internal (GEN_INT (-probed_size)));
   7817  1.1  mrg 	}
   7818  1.1  mrg 
   7819  1.1  mrg       if (frame_size != 0)
   7820  1.1  mrg 	FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
   7821  1.1  mrg 				    GEN_INT (-frame_size))));
   7822  1.1  mrg     }
   7823  1.1  mrg   else
   7824  1.1  mrg     {
   7825  1.1  mrg       /* Here we generate code to set R22 to SP + 4096 and set R23 to the
   7826  1.1  mrg 	 number of 8192 byte blocks to probe.  We then probe each block
   7827  1.1  mrg 	 in the loop and then set SP to the proper location.  If the
   7828  1.1  mrg 	 amount remaining is > 4096, we have to do one more probe if we
   7829  1.1  mrg 	 are not saving any registers or if we are probing beyond the
   7830  1.1  mrg 	 frame because of -fstack-check.  */
   7831  1.1  mrg 
   7832  1.1  mrg       HOST_WIDE_INT blocks = (probed_size + 4096) / 8192;
   7833  1.1  mrg       HOST_WIDE_INT leftover = probed_size + 4096 - blocks * 8192;
   7834  1.1  mrg       rtx ptr = gen_rtx_REG (DImode, 22);
   7835  1.1  mrg       rtx count = gen_rtx_REG (DImode, 23);
   7836  1.1  mrg       rtx seq;
   7837  1.1  mrg 
   7838  1.1  mrg       emit_move_insn (count, GEN_INT (blocks));
   7839  1.1  mrg       emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096)));
   7840  1.1  mrg 
   7841  1.1  mrg       /* Because of the difficulty in emitting a new basic block this
   7842  1.1  mrg 	 late in the compilation, generate the loop as a single insn.  */
   7843  1.1  mrg       emit_insn (gen_prologue_stack_probe_loop (count, ptr));
   7844  1.1  mrg 
   7845  1.1  mrg       if ((leftover > 4096 && sa_size == 0)
   7846  1.1  mrg 	  || flag_stack_check || flag_stack_clash_protection)
   7847  1.1  mrg 	{
   7848  1.1  mrg 	  rtx last = gen_rtx_MEM (DImode,
   7849  1.1  mrg 				  plus_constant (Pmode, ptr, -leftover));
   7850  1.1  mrg 	  MEM_VOLATILE_P (last) = 1;
   7851  1.1  mrg 	  emit_move_insn (last, const0_rtx);
   7852  1.1  mrg 	}
   7853  1.1  mrg 
   7854  1.1  mrg       if (flag_stack_check || flag_stack_clash_protection)
   7855  1.1  mrg 	{
   7856  1.1  mrg 	  /* If -fstack-check is specified we have to load the entire
   7857  1.1  mrg 	     constant into a register and subtract from the sp in one go,
   7858  1.1  mrg 	     because the probed stack size is not equal to the frame size.  */
   7859  1.1  mrg 	  HOST_WIDE_INT lo, hi;
   7860  1.1  mrg 	  lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
   7861  1.1  mrg 	  hi = frame_size - lo;
   7862  1.1  mrg 
   7863  1.1  mrg 	  emit_move_insn (ptr, GEN_INT (hi));
   7864  1.1  mrg 	  emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
   7865  1.1  mrg 	  seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
   7866  1.1  mrg 				       ptr));
   7867  1.1  mrg 	}
   7868  1.1  mrg       else
   7869  1.1  mrg 	{
   7870  1.1  mrg 	  seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
   7871  1.1  mrg 				       GEN_INT (-leftover)));
   7872  1.1  mrg 	}
   7873  1.1  mrg 
   7874  1.1  mrg       /* This alternative is special, because the DWARF code cannot
   7875  1.1  mrg          possibly intuit through the loop above.  So we invent this
   7876  1.1  mrg          note it looks at instead.  */
   7877  1.1  mrg       RTX_FRAME_RELATED_P (seq) = 1;
   7878  1.1  mrg       add_reg_note (seq, REG_FRAME_RELATED_EXPR,
   7879  1.1  mrg 		    gen_rtx_SET (stack_pointer_rtx,
   7880  1.1  mrg 				 plus_constant (Pmode, stack_pointer_rtx,
   7881  1.1  mrg 						-frame_size)));
   7882  1.1  mrg     }
   7883  1.1  mrg 
   7884  1.1  mrg   /* Cope with very large offsets to the register save area.  */
   7885  1.1  mrg   sa_bias = 0;
   7886  1.1  mrg   sa_reg = stack_pointer_rtx;
   7887  1.1  mrg   if (reg_offset + sa_size > 0x8000)
   7888  1.1  mrg     {
   7889  1.1  mrg       int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
   7890  1.1  mrg       rtx sa_bias_rtx;
   7891  1.1  mrg 
   7892  1.1  mrg       if (low + sa_size <= 0x8000)
   7893  1.1  mrg 	sa_bias = reg_offset - low, reg_offset = low;
   7894  1.1  mrg       else
   7895  1.1  mrg 	sa_bias = reg_offset, reg_offset = 0;
   7896  1.1  mrg 
   7897  1.1  mrg       sa_reg = gen_rtx_REG (DImode, 24);
   7898  1.1  mrg       sa_bias_rtx = GEN_INT (sa_bias);
   7899  1.1  mrg 
   7900  1.1  mrg       if (add_operand (sa_bias_rtx, DImode))
   7901  1.1  mrg 	emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
   7902  1.1  mrg       else
   7903  1.1  mrg 	{
   7904  1.1  mrg 	  emit_move_insn (sa_reg, sa_bias_rtx);
   7905  1.1  mrg 	  emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
   7906  1.1  mrg 	}
   7907  1.1  mrg     }
   7908  1.1  mrg 
   7909  1.1  mrg   /* Save regs in stack order.  Beginning with VMS PV.  */
   7910  1.1  mrg   if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
   7911  1.1  mrg     emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
   7912  1.1  mrg 
   7913  1.1  mrg   /* Save register RA next, followed by any other registers
   7914  1.1  mrg      that need to be saved.  */
   7915  1.1  mrg   for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi(sa_mask))
   7916  1.1  mrg     {
   7917  1.1  mrg       emit_frame_store (i, sa_reg, sa_bias, reg_offset);
   7918  1.1  mrg       reg_offset += 8;
   7919  1.1  mrg       sa_mask &= ~(HOST_WIDE_INT_1U << i);
   7920  1.1  mrg     }
   7921  1.1  mrg 
   7922  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   7923  1.1  mrg     {
   7924  1.1  mrg       /* Register frame procedures save the fp.  */
   7925  1.1  mrg       if (alpha_procedure_type == PT_REGISTER)
   7926  1.1  mrg 	{
   7927  1.1  mrg 	  rtx_insn *insn =
   7928  1.1  mrg 	    emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
   7929  1.1  mrg 			    hard_frame_pointer_rtx);
   7930  1.1  mrg 	  add_reg_note (insn, REG_CFA_REGISTER, NULL);
   7931  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
   7932  1.1  mrg 	}
   7933  1.1  mrg 
   7934  1.1  mrg       if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
   7935  1.1  mrg 	emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
   7936  1.1  mrg 				    gen_rtx_REG (DImode, REG_PV)));
   7937  1.1  mrg 
   7938  1.1  mrg       if (alpha_procedure_type != PT_NULL
   7939  1.1  mrg 	  && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
   7940  1.1  mrg 	FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
   7941  1.1  mrg 
   7942  1.1  mrg       /* If we have to allocate space for outgoing args, do it now.  */
   7943  1.1  mrg       if (crtl->outgoing_args_size != 0)
   7944  1.1  mrg 	{
   7945  1.1  mrg 	  rtx_insn *seq
   7946  1.1  mrg 	    = emit_move_insn (stack_pointer_rtx,
   7947  1.1  mrg 			      plus_constant
   7948  1.1  mrg 			      (Pmode, hard_frame_pointer_rtx,
   7949  1.1  mrg 			       - (ALPHA_ROUND
   7950  1.1  mrg 				  (crtl->outgoing_args_size))));
   7951  1.1  mrg 
   7952  1.1  mrg 	  /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
   7953  1.1  mrg 	     if ! frame_pointer_needed. Setting the bit will change the CFA
   7954  1.1  mrg 	     computation rule to use sp again, which would be wrong if we had
   7955  1.1  mrg 	     frame_pointer_needed, as this means sp might move unpredictably
   7956  1.1  mrg 	     later on.
   7957  1.1  mrg 
   7958  1.1  mrg 	     Also, note that
   7959  1.1  mrg 	       frame_pointer_needed
   7960  1.1  mrg 	       => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
   7961  1.1  mrg 	     and
   7962  1.1  mrg 	       crtl->outgoing_args_size != 0
   7963  1.1  mrg 	       => alpha_procedure_type != PT_NULL,
   7964  1.1  mrg 
   7965  1.1  mrg 	     so when we are not setting the bit here, we are guaranteed to
   7966  1.1  mrg 	     have emitted an FRP frame pointer update just before.  */
   7967  1.1  mrg 	  RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
   7968  1.1  mrg 	}
   7969  1.1  mrg     }
   7970  1.1  mrg   else
   7971  1.1  mrg     {
   7972  1.1  mrg       /* If we need a frame pointer, set it from the stack pointer.  */
   7973  1.1  mrg       if (frame_pointer_needed)
   7974  1.1  mrg 	{
   7975  1.1  mrg 	  if (TARGET_CAN_FAULT_IN_PROLOGUE)
   7976  1.1  mrg 	    FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
   7977  1.1  mrg 	  else
   7978  1.1  mrg 	    /* This must always be the last instruction in the
   7979  1.1  mrg 	       prologue, thus we emit a special move + clobber.  */
   7980  1.1  mrg 	      FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
   7981  1.1  mrg 				           stack_pointer_rtx, sa_reg)));
   7982  1.1  mrg 	}
   7983  1.1  mrg     }
   7984  1.1  mrg 
   7985  1.1  mrg   /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
   7986  1.1  mrg      the prologue, for exception handling reasons, we cannot do this for
   7987  1.1  mrg      any insn that might fault.  We could prevent this for mems with a
   7988  1.1  mrg      (clobber:BLK (scratch)), but this doesn't work for fp insns.  So we
   7989  1.1  mrg      have to prevent all such scheduling with a blockage.
   7990  1.1  mrg 
   7991  1.1  mrg      Linux, on the other hand, never bothered to implement OSF/1's
   7992  1.1  mrg      exception handling, and so doesn't care about such things.  Anyone
   7993  1.1  mrg      planning to use dwarf2 frame-unwind info can also omit the blockage.  */
   7994  1.1  mrg 
   7995  1.1  mrg   if (! TARGET_CAN_FAULT_IN_PROLOGUE)
   7996  1.1  mrg     emit_insn (gen_blockage ());
   7997  1.1  mrg }
   7998  1.1  mrg 
   7999  1.1  mrg /* Count the number of .file directives, so that .loc is up to date.  */
   8000  1.1  mrg int num_source_filenames = 0;
   8001  1.1  mrg 
   8002  1.1  mrg /* Output the textual info surrounding the prologue.  */
   8003  1.1  mrg 
   8004  1.1  mrg void
   8005  1.1  mrg alpha_start_function (FILE *file, const char *fnname,
   8006  1.1  mrg 		      tree decl ATTRIBUTE_UNUSED)
   8007  1.1  mrg {
   8008  1.1  mrg   unsigned long imask, fmask;
   8009  1.1  mrg   /* Complete stack size needed.  */
   8010  1.1  mrg   HOST_WIDE_INT frame_size = cfun->machine->frame_size;
   8011  1.1  mrg   /* The maximum debuggable frame size.  */
   8012  1.1  mrg   const HOST_WIDE_INT max_frame_size = HOST_WIDE_INT_1 << 31;
   8013  1.1  mrg   /* Offset from base reg to register save area.  */
   8014  1.1  mrg   HOST_WIDE_INT reg_offset;
   8015  1.1  mrg   char *entry_label = (char *) alloca (strlen (fnname) + 6);
   8016  1.1  mrg   char *tramp_label = (char *) alloca (strlen (fnname) + 6);
   8017  1.1  mrg   int i;
   8018  1.1  mrg 
   8019  1.1  mrg #if TARGET_ABI_OPEN_VMS
   8020  1.1  mrg   vms_start_function (fnname);
   8021  1.1  mrg #endif
   8022  1.1  mrg 
   8023  1.1  mrg   alpha_fnname = fnname;
   8024  1.1  mrg 
   8025  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   8026  1.1  mrg     reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
   8027  1.1  mrg   else
   8028  1.1  mrg     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
   8029  1.1  mrg 
   8030  1.1  mrg   imask = cfun->machine->sa_mask & 0xffffffffu;
   8031  1.1  mrg   fmask = cfun->machine->sa_mask >> 32;
   8032  1.1  mrg 
   8033  1.1  mrg   /* Issue function start and label.  */
   8034  1.1  mrg   if (TARGET_ABI_OPEN_VMS || !flag_inhibit_size_directive)
   8035  1.1  mrg     {
   8036  1.1  mrg       fputs ("\t.ent ", file);
   8037  1.1  mrg       assemble_name (file, fnname);
   8038  1.1  mrg       putc ('\n', file);
   8039  1.1  mrg 
   8040  1.1  mrg       /* If the function needs GP, we'll write the "..ng" label there.
   8041  1.1  mrg 	 Otherwise, do it here.  */
   8042  1.1  mrg       if (TARGET_ABI_OSF
   8043  1.1  mrg           && ! alpha_function_needs_gp
   8044  1.1  mrg 	  && ! cfun->is_thunk)
   8045  1.1  mrg 	{
   8046  1.1  mrg 	  putc ('$', file);
   8047  1.1  mrg 	  assemble_name (file, fnname);
   8048  1.1  mrg 	  fputs ("..ng:\n", file);
   8049  1.1  mrg 	}
   8050  1.1  mrg     }
   8051  1.1  mrg   /* Nested functions on VMS that are potentially called via trampoline
   8052  1.1  mrg      get a special transfer entry point that loads the called functions
   8053  1.1  mrg      procedure descriptor and static chain.  */
   8054  1.1  mrg    if (TARGET_ABI_OPEN_VMS
   8055  1.1  mrg        && !TREE_PUBLIC (decl)
   8056  1.1  mrg        && DECL_CONTEXT (decl)
   8057  1.1  mrg        && !TYPE_P (DECL_CONTEXT (decl))
   8058  1.1  mrg        && TREE_CODE (DECL_CONTEXT (decl)) != TRANSLATION_UNIT_DECL)
   8059  1.1  mrg      {
   8060  1.1  mrg 	strcpy (tramp_label, fnname);
   8061  1.1  mrg 	strcat (tramp_label, "..tr");
   8062  1.1  mrg 	ASM_OUTPUT_LABEL (file, tramp_label);
   8063  1.1  mrg 	fprintf (file, "\tldq $1,24($27)\n");
   8064  1.1  mrg 	fprintf (file, "\tldq $27,16($27)\n");
   8065  1.1  mrg      }
   8066  1.1  mrg 
   8067  1.1  mrg   strcpy (entry_label, fnname);
   8068  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   8069  1.1  mrg     strcat (entry_label, "..en");
   8070  1.1  mrg 
   8071  1.1  mrg   ASM_OUTPUT_LABEL (file, entry_label);
   8072  1.1  mrg   inside_function = TRUE;
   8073  1.1  mrg 
   8074  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   8075  1.1  mrg     fprintf (file, "\t.base $%d\n", vms_base_regno);
   8076  1.1  mrg 
   8077  1.1  mrg   if (TARGET_ABI_OSF
   8078  1.1  mrg       && TARGET_IEEE_CONFORMANT
   8079  1.1  mrg       && !flag_inhibit_size_directive)
   8080  1.1  mrg     {
   8081  1.1  mrg       /* Set flags in procedure descriptor to request IEEE-conformant
   8082  1.1  mrg 	 math-library routines.  The value we set it to is PDSC_EXC_IEEE
   8083  1.1  mrg 	 (/usr/include/pdsc.h).  */
   8084  1.1  mrg       fputs ("\t.eflag 48\n", file);
   8085  1.1  mrg     }
   8086  1.1  mrg 
   8087  1.1  mrg   /* Set up offsets to alpha virtual arg/local debugging pointer.  */
   8088  1.1  mrg   alpha_auto_offset = -frame_size + crtl->args.pretend_args_size;
   8089  1.1  mrg   alpha_arg_offset = -frame_size + 48;
   8090  1.1  mrg 
   8091  1.1  mrg   /* Describe our frame.  If the frame size is larger than an integer,
   8092  1.1  mrg      print it as zero to avoid an assembler error.  We won't be
   8093  1.1  mrg      properly describing such a frame, but that's the best we can do.  */
   8094  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   8095  1.1  mrg     fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
   8096  1.1  mrg 	     HOST_WIDE_INT_PRINT_DEC "\n",
   8097  1.1  mrg 	     vms_unwind_regno,
   8098  1.1  mrg 	     frame_size >= max_frame_size ? 0 : frame_size,
   8099  1.1  mrg 	     reg_offset);
   8100  1.1  mrg   else if (!flag_inhibit_size_directive)
   8101  1.1  mrg     fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
   8102  1.1  mrg 	     (frame_pointer_needed
   8103  1.1  mrg 	      ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
   8104  1.1  mrg 	     frame_size >= max_frame_size ? 0 : frame_size,
   8105  1.1  mrg 	     crtl->args.pretend_args_size);
   8106  1.1  mrg 
   8107  1.1  mrg   /* Describe which registers were spilled.  */
   8108  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   8109  1.1  mrg     {
   8110  1.1  mrg       if (imask)
   8111  1.1  mrg         /* ??? Does VMS care if mask contains ra?  The old code didn't
   8112  1.1  mrg            set it, so I don't here.  */
   8113  1.1  mrg 	fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
   8114  1.1  mrg       if (fmask)
   8115  1.1  mrg 	fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
   8116  1.1  mrg       if (alpha_procedure_type == PT_REGISTER)
   8117  1.1  mrg 	fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
   8118  1.1  mrg     }
   8119  1.1  mrg   else if (!flag_inhibit_size_directive)
   8120  1.1  mrg     {
   8121  1.1  mrg       if (imask)
   8122  1.1  mrg 	{
   8123  1.1  mrg 	  fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
   8124  1.1  mrg 		   frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
   8125  1.1  mrg 
   8126  1.1  mrg 	  for (i = 0; i < 32; ++i)
   8127  1.1  mrg 	    if (imask & (1UL << i))
   8128  1.1  mrg 	      reg_offset += 8;
   8129  1.1  mrg 	}
   8130  1.1  mrg 
   8131  1.1  mrg       if (fmask)
   8132  1.1  mrg 	fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
   8133  1.1  mrg 		 frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
   8134  1.1  mrg     }
   8135  1.1  mrg 
   8136  1.1  mrg #if TARGET_ABI_OPEN_VMS
   8137  1.1  mrg   /* If a user condition handler has been installed at some point, emit
   8138  1.1  mrg      the procedure descriptor bits to point the Condition Handling Facility
   8139  1.1  mrg      at the indirection wrapper, and state the fp offset at which the user
   8140  1.1  mrg      handler may be found.  */
   8141  1.1  mrg   if (cfun->machine->uses_condition_handler)
   8142  1.1  mrg     {
   8143  1.1  mrg       fprintf (file, "\t.handler __gcc_shell_handler\n");
   8144  1.1  mrg       fprintf (file, "\t.handler_data %d\n", VMS_COND_HANDLER_FP_OFFSET);
   8145  1.1  mrg     }
   8146  1.1  mrg 
   8147  1.1  mrg #ifdef TARGET_VMS_CRASH_DEBUG
   8148  1.1  mrg   /* Support of minimal traceback info.  */
   8149  1.1  mrg   switch_to_section (readonly_data_section);
   8150  1.1  mrg   fprintf (file, "\t.align 3\n");
   8151  1.1  mrg   assemble_name (file, fnname); fputs ("..na:\n", file);
   8152  1.1  mrg   fputs ("\t.ascii \"", file);
   8153  1.1  mrg   assemble_name (file, fnname);
   8154  1.1  mrg   fputs ("\\0\"\n", file);
   8155  1.1  mrg   switch_to_section (text_section);
   8156  1.1  mrg #endif
   8157  1.1  mrg #endif /* TARGET_ABI_OPEN_VMS */
   8158  1.1  mrg }
   8159  1.1  mrg 
   8160  1.1  mrg /* Emit the .prologue note at the scheduled end of the prologue.  */
   8161  1.1  mrg 
   8162  1.1  mrg static void
   8163  1.1  mrg alpha_output_function_end_prologue (FILE *file)
   8164  1.1  mrg {
   8165  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   8166  1.1  mrg     fputs ("\t.prologue\n", file);
   8167  1.1  mrg   else if (!flag_inhibit_size_directive)
   8168  1.1  mrg     fprintf (file, "\t.prologue %d\n",
   8169  1.1  mrg 	     alpha_function_needs_gp || cfun->is_thunk);
   8170  1.1  mrg }
   8171  1.1  mrg 
   8172  1.1  mrg /* Write function epilogue.  */
   8173  1.1  mrg 
   8174  1.1  mrg void
   8175  1.1  mrg alpha_expand_epilogue (void)
   8176  1.1  mrg {
   8177  1.1  mrg   /* Registers to save.  */
   8178  1.1  mrg   unsigned HOST_WIDE_INT sa_mask = cfun->machine->sa_mask;
   8179  1.1  mrg   /* Stack space needed for pushing registers clobbered by us.  */
   8180  1.1  mrg   HOST_WIDE_INT sa_size = cfun->machine->sa_size;
   8181  1.1  mrg   /* Complete stack size needed.  */
   8182  1.1  mrg   HOST_WIDE_INT frame_size = cfun->machine->frame_size;
   8183  1.1  mrg   /* Offset from base reg to register save area.  */
   8184  1.1  mrg   HOST_WIDE_INT reg_offset;
   8185  1.1  mrg   int fp_is_frame_pointer, fp_offset;
   8186  1.1  mrg   rtx sa_reg, sa_reg_exp = NULL;
   8187  1.1  mrg   rtx sp_adj1, sp_adj2, mem, reg, insn;
   8188  1.1  mrg   rtx eh_ofs;
   8189  1.1  mrg   rtx cfa_restores = NULL_RTX;
   8190  1.1  mrg 
   8191  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   8192  1.1  mrg     {
   8193  1.1  mrg        if (alpha_procedure_type == PT_STACK)
   8194  1.1  mrg           reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
   8195  1.1  mrg        else
   8196  1.1  mrg           reg_offset = 0;
   8197  1.1  mrg     }
   8198  1.1  mrg   else
   8199  1.1  mrg     reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
   8200  1.1  mrg 
   8201  1.1  mrg   fp_is_frame_pointer
   8202  1.1  mrg     = (TARGET_ABI_OPEN_VMS
   8203  1.1  mrg        ? alpha_procedure_type == PT_STACK
   8204  1.1  mrg        : frame_pointer_needed);
   8205  1.1  mrg   fp_offset = 0;
   8206  1.1  mrg   sa_reg = stack_pointer_rtx;
   8207  1.1  mrg 
   8208  1.1  mrg   if (crtl->calls_eh_return)
   8209  1.1  mrg     eh_ofs = EH_RETURN_STACKADJ_RTX;
   8210  1.1  mrg   else
   8211  1.1  mrg     eh_ofs = NULL_RTX;
   8212  1.1  mrg 
   8213  1.1  mrg   if (sa_size)
   8214  1.1  mrg     {
   8215  1.1  mrg       /* If we have a frame pointer, restore SP from it.  */
   8216  1.1  mrg       if (TARGET_ABI_OPEN_VMS
   8217  1.1  mrg 	  ? vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
   8218  1.1  mrg 	  : frame_pointer_needed)
   8219  1.1  mrg 	emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
   8220  1.1  mrg 
   8221  1.1  mrg       /* Cope with very large offsets to the register save area.  */
   8222  1.1  mrg       if (reg_offset + sa_size > 0x8000)
   8223  1.1  mrg 	{
   8224  1.1  mrg 	  int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
   8225  1.1  mrg 	  HOST_WIDE_INT bias;
   8226  1.1  mrg 
   8227  1.1  mrg 	  if (low + sa_size <= 0x8000)
   8228  1.1  mrg 	    bias = reg_offset - low, reg_offset = low;
   8229  1.1  mrg 	  else
   8230  1.1  mrg 	    bias = reg_offset, reg_offset = 0;
   8231  1.1  mrg 
   8232  1.1  mrg 	  sa_reg = gen_rtx_REG (DImode, 22);
   8233  1.1  mrg 	  sa_reg_exp = plus_constant (Pmode, stack_pointer_rtx, bias);
   8234  1.1  mrg 
   8235  1.1  mrg 	  emit_move_insn (sa_reg, sa_reg_exp);
   8236  1.1  mrg 	}
   8237  1.1  mrg 
   8238  1.1  mrg       /* Restore registers in order, excepting a true frame pointer.  */
   8239  1.1  mrg       for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi(sa_mask))
   8240  1.1  mrg 	{
   8241  1.1  mrg 	  if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
   8242  1.1  mrg 	    fp_offset = reg_offset;
   8243  1.1  mrg 	  else
   8244  1.1  mrg 	    {
   8245  1.1  mrg 	      mem = gen_frame_mem (DImode,
   8246  1.1  mrg 				   plus_constant (Pmode, sa_reg,
   8247  1.1  mrg 						  reg_offset));
   8248  1.1  mrg 	      reg = gen_rtx_REG (DImode, i);
   8249  1.1  mrg 	      emit_move_insn (reg, mem);
   8250  1.1  mrg 	      cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
   8251  1.1  mrg 					     cfa_restores);
   8252  1.1  mrg 	    }
   8253  1.1  mrg 	  reg_offset += 8;
   8254  1.1  mrg 	  sa_mask &= ~(HOST_WIDE_INT_1U << i);
   8255  1.1  mrg 	}
   8256  1.1  mrg     }
   8257  1.1  mrg 
   8258  1.1  mrg   if (frame_size || eh_ofs)
   8259  1.1  mrg     {
   8260  1.1  mrg       sp_adj1 = stack_pointer_rtx;
   8261  1.1  mrg 
   8262  1.1  mrg       if (eh_ofs)
   8263  1.1  mrg 	{
   8264  1.1  mrg 	  sp_adj1 = gen_rtx_REG (DImode, 23);
   8265  1.1  mrg 	  emit_move_insn (sp_adj1,
   8266  1.1  mrg 			  gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
   8267  1.1  mrg 	}
   8268  1.1  mrg 
   8269  1.1  mrg       /* If the stack size is large, begin computation into a temporary
   8270  1.1  mrg 	 register so as not to interfere with a potential fp restore,
   8271  1.1  mrg 	 which must be consecutive with an SP restore.  */
   8272  1.1  mrg       if (frame_size < 32768 && !cfun->calls_alloca)
   8273  1.1  mrg 	sp_adj2 = GEN_INT (frame_size);
   8274  1.1  mrg       else if (frame_size < 0x40007fffL)
   8275  1.1  mrg 	{
   8276  1.1  mrg 	  int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
   8277  1.1  mrg 
   8278  1.1  mrg 	  sp_adj2 = plus_constant (Pmode, sp_adj1, frame_size - low);
   8279  1.1  mrg 	  if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
   8280  1.1  mrg 	    sp_adj1 = sa_reg;
   8281  1.1  mrg 	  else
   8282  1.1  mrg 	    {
   8283  1.1  mrg 	      sp_adj1 = gen_rtx_REG (DImode, 23);
   8284  1.1  mrg 	      emit_move_insn (sp_adj1, sp_adj2);
   8285  1.1  mrg 	    }
   8286  1.1  mrg 	  sp_adj2 = GEN_INT (low);
   8287  1.1  mrg 	}
   8288  1.1  mrg       else
   8289  1.1  mrg 	{
   8290  1.1  mrg 	  rtx tmp = gen_rtx_REG (DImode, 23);
   8291  1.1  mrg 	  sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3, false);
   8292  1.1  mrg 	  if (!sp_adj2)
   8293  1.1  mrg 	    {
   8294  1.1  mrg 	      /* We can't drop new things to memory this late, afaik,
   8295  1.1  mrg 		 so build it up by pieces.  */
   8296  1.1  mrg 	      sp_adj2 = alpha_emit_set_long_const (tmp, frame_size);
   8297  1.1  mrg 	      gcc_assert (sp_adj2);
   8298  1.1  mrg 	    }
   8299  1.1  mrg 	}
   8300  1.1  mrg 
   8301  1.1  mrg       /* From now on, things must be in order.  So emit blockages.  */
   8302  1.1  mrg 
   8303  1.1  mrg       /* Restore the frame pointer.  */
   8304  1.1  mrg       if (fp_is_frame_pointer)
   8305  1.1  mrg 	{
   8306  1.1  mrg 	  emit_insn (gen_blockage ());
   8307  1.1  mrg 	  mem = gen_frame_mem (DImode, plus_constant (Pmode, sa_reg,
   8308  1.1  mrg 						      fp_offset));
   8309  1.1  mrg 	  emit_move_insn (hard_frame_pointer_rtx, mem);
   8310  1.1  mrg 	  cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
   8311  1.1  mrg 					 hard_frame_pointer_rtx, cfa_restores);
   8312  1.1  mrg 	}
   8313  1.1  mrg       else if (TARGET_ABI_OPEN_VMS)
   8314  1.1  mrg 	{
   8315  1.1  mrg 	  emit_insn (gen_blockage ());
   8316  1.1  mrg 	  emit_move_insn (hard_frame_pointer_rtx,
   8317  1.1  mrg 			  gen_rtx_REG (DImode, vms_save_fp_regno));
   8318  1.1  mrg 	  cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
   8319  1.1  mrg 					 hard_frame_pointer_rtx, cfa_restores);
   8320  1.1  mrg 	}
   8321  1.1  mrg 
   8322  1.1  mrg       /* Restore the stack pointer.  */
   8323  1.1  mrg       emit_insn (gen_blockage ());
   8324  1.1  mrg       if (sp_adj2 == const0_rtx)
   8325  1.1  mrg 	insn = emit_move_insn (stack_pointer_rtx, sp_adj1);
   8326  1.1  mrg       else
   8327  1.1  mrg 	insn = emit_move_insn (stack_pointer_rtx,
   8328  1.1  mrg 			       gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
   8329  1.1  mrg       REG_NOTES (insn) = cfa_restores;
   8330  1.1  mrg       add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
   8331  1.1  mrg       RTX_FRAME_RELATED_P (insn) = 1;
   8332  1.1  mrg     }
   8333  1.1  mrg   else
   8334  1.1  mrg     {
   8335  1.1  mrg       gcc_assert (cfa_restores == NULL);
   8336  1.1  mrg 
   8337  1.1  mrg       if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
   8338  1.1  mrg         {
   8339  1.1  mrg           emit_insn (gen_blockage ());
   8340  1.1  mrg           insn = emit_move_insn (hard_frame_pointer_rtx,
   8341  1.1  mrg 				 gen_rtx_REG (DImode, vms_save_fp_regno));
   8342  1.1  mrg 	  add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
   8343  1.1  mrg 	  RTX_FRAME_RELATED_P (insn) = 1;
   8344  1.1  mrg         }
   8345  1.1  mrg     }
   8346  1.1  mrg }
   8347  1.1  mrg 
   8348  1.1  mrg /* Output the rest of the textual info surrounding the epilogue.  */
   8350  1.1  mrg 
   8351  1.1  mrg void
   8352  1.1  mrg alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
   8353  1.1  mrg {
   8354  1.1  mrg   rtx_insn *insn;
   8355  1.1  mrg 
   8356  1.1  mrg   /* We output a nop after noreturn calls at the very end of the function to
   8357  1.1  mrg      ensure that the return address always remains in the caller's code range,
   8358  1.1  mrg      as not doing so might confuse unwinding engines.  */
   8359  1.1  mrg   insn = get_last_insn ();
   8360  1.1  mrg   if (!INSN_P (insn))
   8361  1.1  mrg     insn = prev_active_insn (insn);
   8362  1.1  mrg   if (insn && CALL_P (insn))
   8363  1.1  mrg     output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);
   8364  1.1  mrg 
   8365  1.1  mrg #if TARGET_ABI_OPEN_VMS
   8366  1.1  mrg   /* Write the linkage entries.  */
   8367  1.1  mrg   alpha_write_linkage (file, fnname);
   8368  1.1  mrg #endif
   8369  1.1  mrg 
   8370  1.1  mrg   /* End the function.  */
   8371  1.1  mrg   if (TARGET_ABI_OPEN_VMS
   8372  1.1  mrg       || !flag_inhibit_size_directive)
   8373  1.1  mrg     {
   8374  1.1  mrg       fputs ("\t.end ", file);
   8375  1.1  mrg       assemble_name (file, fnname);
   8376  1.1  mrg       putc ('\n', file);
   8377  1.1  mrg     }
   8378  1.1  mrg   inside_function = FALSE;
   8379  1.1  mrg }
   8380  1.1  mrg 
   8381  1.1  mrg #if TARGET_ABI_OSF
   8382  1.1  mrg /* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
   8383  1.1  mrg 
   8384  1.1  mrg    In order to avoid the hordes of differences between generated code
   8385  1.1  mrg    with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
   8386  1.1  mrg    lots of code loading up large constants, generate rtl and emit it
   8387  1.1  mrg    instead of going straight to text.
   8388  1.1  mrg 
   8389  1.1  mrg    Not sure why this idea hasn't been explored before...  */
   8390  1.1  mrg 
   8391  1.1  mrg static void
   8392  1.1  mrg alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
   8393  1.1  mrg 			   HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
   8394  1.1  mrg 			   tree function)
   8395  1.1  mrg {
   8396  1.1  mrg   const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   8397  1.1  mrg   HOST_WIDE_INT hi, lo;
   8398  1.1  mrg   rtx this_rtx, funexp;
   8399  1.1  mrg   rtx_insn *insn;
   8400  1.1  mrg 
   8401  1.1  mrg   /* We always require a valid GP.  */
   8402  1.1  mrg   emit_insn (gen_prologue_ldgp ());
   8403  1.1  mrg   emit_note (NOTE_INSN_PROLOGUE_END);
   8404  1.1  mrg 
   8405  1.1  mrg   /* Find the "this" pointer.  If the function returns a structure,
   8406  1.1  mrg      the structure return pointer is in $16.  */
   8407  1.1  mrg   if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
   8408  1.1  mrg     this_rtx = gen_rtx_REG (Pmode, 17);
   8409  1.1  mrg   else
   8410  1.1  mrg     this_rtx = gen_rtx_REG (Pmode, 16);
   8411  1.1  mrg 
   8412  1.1  mrg   /* Add DELTA.  When possible we use ldah+lda.  Otherwise load the
   8413  1.1  mrg      entire constant for the add.  */
   8414  1.1  mrg   lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
   8415  1.1  mrg   hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
   8416  1.1  mrg   if (hi + lo == delta)
   8417  1.1  mrg     {
   8418  1.1  mrg       if (hi)
   8419  1.1  mrg 	emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (hi)));
   8420  1.1  mrg       if (lo)
   8421  1.1  mrg 	emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (lo)));
   8422  1.1  mrg     }
   8423  1.1  mrg   else
   8424  1.1  mrg     {
   8425  1.1  mrg       rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0), delta);
   8426  1.1  mrg       emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
   8427  1.1  mrg     }
   8428  1.1  mrg 
   8429  1.1  mrg   /* Add a delta stored in the vtable at VCALL_OFFSET.  */
   8430  1.1  mrg   if (vcall_offset)
   8431  1.1  mrg     {
   8432  1.1  mrg       rtx tmp, tmp2;
   8433  1.1  mrg 
   8434  1.1  mrg       tmp = gen_rtx_REG (Pmode, 0);
   8435  1.1  mrg       emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
   8436  1.1  mrg 
   8437  1.1  mrg       lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
   8438  1.1  mrg       hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
   8439  1.1  mrg       if (hi + lo == vcall_offset)
   8440  1.1  mrg 	{
   8441  1.1  mrg 	  if (hi)
   8442  1.1  mrg 	    emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
   8443  1.1  mrg 	}
   8444  1.1  mrg       else
   8445  1.1  mrg 	{
   8446  1.1  mrg 	  tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
   8447  1.1  mrg 					    vcall_offset);
   8448  1.1  mrg           emit_insn (gen_adddi3 (tmp, tmp, tmp2));
   8449  1.1  mrg 	  lo = 0;
   8450  1.1  mrg 	}
   8451  1.1  mrg       if (lo)
   8452  1.1  mrg 	tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
   8453  1.1  mrg       else
   8454  1.1  mrg 	tmp2 = tmp;
   8455  1.1  mrg       emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
   8456  1.1  mrg 
   8457  1.1  mrg       emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
   8458  1.1  mrg     }
   8459  1.1  mrg 
   8460  1.1  mrg   /* Generate a tail call to the target function.  */
   8461  1.1  mrg   if (! TREE_USED (function))
   8462  1.1  mrg     {
   8463  1.1  mrg       assemble_external (function);
   8464  1.1  mrg       TREE_USED (function) = 1;
   8465  1.1  mrg     }
   8466  1.1  mrg   funexp = XEXP (DECL_RTL (function), 0);
   8467  1.1  mrg   funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
   8468  1.1  mrg   insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
   8469  1.1  mrg   SIBLING_CALL_P (insn) = 1;
   8470  1.1  mrg 
   8471  1.1  mrg   /* Run just enough of rest_of_compilation to get the insns emitted.
   8472  1.1  mrg      There's not really enough bulk here to make other passes such as
   8473  1.1  mrg      instruction scheduling worth while.  */
   8474  1.1  mrg   insn = get_insns ();
   8475  1.1  mrg   shorten_branches (insn);
   8476  1.1  mrg   assemble_start_function (thunk_fndecl, fnname);
   8477  1.1  mrg   final_start_function (insn, file, 1);
   8478  1.1  mrg   final (insn, file, 1);
   8479  1.1  mrg   final_end_function ();
   8480  1.1  mrg   assemble_end_function (thunk_fndecl, fnname);
   8481  1.1  mrg }
   8482  1.1  mrg #endif /* TARGET_ABI_OSF */
   8483  1.1  mrg 
   8484  1.1  mrg /* Debugging support.  */
   8486  1.1  mrg 
   8487  1.1  mrg #include "gstab.h"
   8488  1.1  mrg 
   8489  1.1  mrg /* Name of the file containing the current function.  */
   8490  1.1  mrg 
   8491  1.1  mrg static const char *current_function_file = "";
   8492  1.1  mrg 
   8493  1.1  mrg /* Offsets to alpha virtual arg/local debugging pointers.  */
   8494  1.1  mrg 
   8495  1.1  mrg long alpha_arg_offset;
   8496  1.1  mrg long alpha_auto_offset;
   8497  1.1  mrg 
   8498  1.1  mrg /* Emit a new filename to a stream.  */
   8500  1.1  mrg 
   8501  1.1  mrg void
   8502  1.1  mrg alpha_output_filename (FILE *stream, const char *name)
   8503  1.1  mrg {
   8504  1.1  mrg   static int first_time = TRUE;
   8505  1.1  mrg 
   8506  1.1  mrg   if (first_time)
   8507  1.1  mrg     {
   8508  1.1  mrg       first_time = FALSE;
   8509  1.1  mrg       ++num_source_filenames;
   8510  1.1  mrg       current_function_file = name;
   8511  1.1  mrg       fprintf (stream, "\t.file\t%d ", num_source_filenames);
   8512  1.1  mrg       output_quoted_string (stream, name);
   8513  1.1  mrg       fprintf (stream, "\n");
   8514  1.1  mrg     }
   8515  1.1  mrg 
   8516  1.1  mrg   else if (name != current_function_file
   8517  1.1  mrg 	   && strcmp (name, current_function_file) != 0)
   8518  1.1  mrg     {
   8519  1.1  mrg       ++num_source_filenames;
   8520  1.1  mrg       current_function_file = name;
   8521  1.1  mrg       fprintf (stream, "\t.file\t%d ", num_source_filenames);
   8522  1.1  mrg 
   8523  1.1  mrg       output_quoted_string (stream, name);
   8524  1.1  mrg       fprintf (stream, "\n");
   8525  1.1  mrg     }
   8526  1.1  mrg }
   8527  1.1  mrg 
   8528  1.1  mrg /* Structure to show the current status of registers and memory.  */
   8530  1.1  mrg 
   8531  1.1  mrg struct shadow_summary
   8532  1.1  mrg {
   8533  1.1  mrg   struct {
   8534  1.1  mrg     unsigned int i     : 31;	/* Mask of int regs */
   8535  1.1  mrg     unsigned int fp    : 31;	/* Mask of fp regs */
   8536  1.1  mrg     unsigned int mem   :  1;	/* mem == imem | fpmem */
   8537  1.1  mrg   } used, defd;
   8538  1.1  mrg };
   8539  1.1  mrg 
   8540  1.1  mrg /* Summary the effects of expression X on the machine.  Update SUM, a pointer
   8541  1.1  mrg    to the summary structure.  SET is nonzero if the insn is setting the
   8542  1.1  mrg    object, otherwise zero.  */
   8543  1.1  mrg 
   8544  1.1  mrg static void
   8545  1.1  mrg summarize_insn (rtx x, struct shadow_summary *sum, int set)
   8546  1.1  mrg {
   8547  1.1  mrg   const char *format_ptr;
   8548  1.1  mrg   int i, j;
   8549  1.1  mrg 
   8550  1.1  mrg   if (x == 0)
   8551  1.1  mrg     return;
   8552  1.1  mrg 
   8553  1.1  mrg   switch (GET_CODE (x))
   8554  1.1  mrg     {
   8555  1.1  mrg       /* ??? Note that this case would be incorrect if the Alpha had a
   8556  1.1  mrg 	 ZERO_EXTRACT in SET_DEST.  */
   8557  1.1  mrg     case SET:
   8558  1.1  mrg       summarize_insn (SET_SRC (x), sum, 0);
   8559  1.1  mrg       summarize_insn (SET_DEST (x), sum, 1);
   8560  1.1  mrg       break;
   8561  1.1  mrg 
   8562  1.1  mrg     case CLOBBER:
   8563  1.1  mrg       summarize_insn (XEXP (x, 0), sum, 1);
   8564  1.1  mrg       break;
   8565  1.1  mrg 
   8566  1.1  mrg     case USE:
   8567  1.1  mrg       summarize_insn (XEXP (x, 0), sum, 0);
   8568  1.1  mrg       break;
   8569  1.1  mrg 
   8570  1.1  mrg     case ASM_OPERANDS:
   8571  1.1  mrg       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
   8572  1.1  mrg 	summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
   8573  1.1  mrg       break;
   8574  1.1  mrg 
   8575  1.1  mrg     case PARALLEL:
   8576  1.1  mrg       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
   8577  1.1  mrg 	summarize_insn (XVECEXP (x, 0, i), sum, 0);
   8578  1.1  mrg       break;
   8579  1.1  mrg 
   8580  1.1  mrg     case SUBREG:
   8581  1.1  mrg       summarize_insn (SUBREG_REG (x), sum, 0);
   8582  1.1  mrg       break;
   8583  1.1  mrg 
   8584  1.1  mrg     case REG:
   8585  1.1  mrg       {
   8586  1.1  mrg 	int regno = REGNO (x);
   8587  1.1  mrg 	unsigned long mask = ((unsigned long) 1) << (regno % 32);
   8588  1.1  mrg 
   8589  1.1  mrg 	if (regno == 31 || regno == 63)
   8590  1.1  mrg 	  break;
   8591  1.1  mrg 
   8592  1.1  mrg 	if (set)
   8593  1.1  mrg 	  {
   8594  1.1  mrg 	    if (regno < 32)
   8595  1.1  mrg 	      sum->defd.i |= mask;
   8596  1.1  mrg 	    else
   8597  1.1  mrg 	      sum->defd.fp |= mask;
   8598  1.1  mrg 	  }
   8599  1.1  mrg 	else
   8600  1.1  mrg 	  {
   8601  1.1  mrg 	    if (regno < 32)
   8602  1.1  mrg 	      sum->used.i  |= mask;
   8603  1.1  mrg 	    else
   8604  1.1  mrg 	      sum->used.fp |= mask;
   8605  1.1  mrg 	  }
   8606  1.1  mrg 	}
   8607  1.1  mrg       break;
   8608  1.1  mrg 
   8609  1.1  mrg     case MEM:
   8610  1.1  mrg       if (set)
   8611  1.1  mrg 	sum->defd.mem = 1;
   8612  1.1  mrg       else
   8613  1.1  mrg 	sum->used.mem = 1;
   8614  1.1  mrg 
   8615  1.1  mrg       /* Find the regs used in memory address computation: */
   8616  1.1  mrg       summarize_insn (XEXP (x, 0), sum, 0);
   8617  1.1  mrg       break;
   8618  1.1  mrg 
   8619  1.1  mrg     case CONST_INT:   case CONST_WIDE_INT:  case CONST_DOUBLE:
   8620  1.1  mrg     case SYMBOL_REF:  case LABEL_REF:       case CONST:
   8621  1.1  mrg     case SCRATCH:     case ASM_INPUT:
   8622  1.1  mrg       break;
   8623  1.1  mrg 
   8624  1.1  mrg       /* Handle common unary and binary ops for efficiency.  */
   8625  1.1  mrg     case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
   8626  1.1  mrg     case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
   8627  1.1  mrg     case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
   8628  1.1  mrg     case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
   8629  1.1  mrg     case NE:       case EQ:      case GE:      case GT:        case LE:
   8630  1.1  mrg     case LT:       case GEU:     case GTU:     case LEU:       case LTU:
   8631  1.1  mrg       summarize_insn (XEXP (x, 0), sum, 0);
   8632  1.1  mrg       summarize_insn (XEXP (x, 1), sum, 0);
   8633  1.1  mrg       break;
   8634  1.1  mrg 
   8635  1.1  mrg     case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
   8636  1.1  mrg     case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
   8637  1.1  mrg     case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
   8638  1.1  mrg     case SQRT:  case FFS:
   8639  1.1  mrg       summarize_insn (XEXP (x, 0), sum, 0);
   8640  1.1  mrg       break;
   8641  1.1  mrg 
   8642  1.1  mrg     default:
   8643  1.1  mrg       format_ptr = GET_RTX_FORMAT (GET_CODE (x));
   8644  1.1  mrg       for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
   8645  1.1  mrg 	switch (format_ptr[i])
   8646  1.1  mrg 	  {
   8647  1.1  mrg 	  case 'e':
   8648  1.1  mrg 	    summarize_insn (XEXP (x, i), sum, 0);
   8649  1.1  mrg 	    break;
   8650  1.1  mrg 
   8651  1.1  mrg 	  case 'E':
   8652  1.1  mrg 	    for (j = XVECLEN (x, i) - 1; j >= 0; j--)
   8653  1.1  mrg 	      summarize_insn (XVECEXP (x, i, j), sum, 0);
   8654  1.1  mrg 	    break;
   8655  1.1  mrg 
   8656  1.1  mrg 	  case 'i':
   8657  1.1  mrg 	    break;
   8658  1.1  mrg 
   8659  1.1  mrg 	  default:
   8660  1.1  mrg 	    gcc_unreachable ();
   8661  1.1  mrg 	  }
   8662  1.1  mrg     }
   8663  1.1  mrg }
   8664  1.1  mrg 
   8665  1.1  mrg /* Ensure a sufficient number of `trapb' insns are in the code when
   8666  1.1  mrg    the user requests code with a trap precision of functions or
   8667  1.1  mrg    instructions.
   8668  1.1  mrg 
   8669  1.1  mrg    In naive mode, when the user requests a trap-precision of
   8670  1.1  mrg    "instruction", a trapb is needed after every instruction that may
   8671  1.1  mrg    generate a trap.  This ensures that the code is resumption safe but
   8672  1.1  mrg    it is also slow.
   8673  1.1  mrg 
   8674  1.1  mrg    When optimizations are turned on, we delay issuing a trapb as long
   8675  1.1  mrg    as possible.  In this context, a trap shadow is the sequence of
   8676  1.1  mrg    instructions that starts with a (potentially) trap generating
   8677  1.1  mrg    instruction and extends to the next trapb or call_pal instruction
   8678  1.1  mrg    (but GCC never generates call_pal by itself).  We can delay (and
   8679  1.1  mrg    therefore sometimes omit) a trapb subject to the following
   8680  1.1  mrg    conditions:
   8681  1.1  mrg 
   8682  1.1  mrg    (a) On entry to the trap shadow, if any Alpha register or memory
   8683  1.1  mrg    location contains a value that is used as an operand value by some
   8684  1.1  mrg    instruction in the trap shadow (live on entry), then no instruction
   8685  1.1  mrg    in the trap shadow may modify the register or memory location.
   8686  1.1  mrg 
   8687  1.1  mrg    (b) Within the trap shadow, the computation of the base register
   8688  1.1  mrg    for a memory load or store instruction may not involve using the
   8689  1.1  mrg    result of an instruction that might generate an UNPREDICTABLE
   8690  1.1  mrg    result.
   8691  1.1  mrg 
   8692  1.1  mrg    (c) Within the trap shadow, no register may be used more than once
   8693  1.1  mrg    as a destination register.  (This is to make life easier for the
   8694  1.1  mrg    trap-handler.)
   8695  1.1  mrg 
   8696  1.1  mrg    (d) The trap shadow may not include any branch instructions.  */
   8697  1.1  mrg 
   8698  1.1  mrg static void
   8699  1.1  mrg alpha_handle_trap_shadows (void)
   8700  1.1  mrg {
   8701  1.1  mrg   struct shadow_summary shadow;
   8702  1.1  mrg   int trap_pending, exception_nesting;
   8703  1.1  mrg   rtx_insn *i, *n;
   8704  1.1  mrg 
   8705  1.1  mrg   trap_pending = 0;
   8706  1.1  mrg   exception_nesting = 0;
   8707  1.1  mrg   shadow.used.i = 0;
   8708  1.1  mrg   shadow.used.fp = 0;
   8709  1.1  mrg   shadow.used.mem = 0;
   8710  1.1  mrg   shadow.defd = shadow.used;
   8711  1.1  mrg 
   8712  1.1  mrg   for (i = get_insns (); i ; i = NEXT_INSN (i))
   8713  1.1  mrg     {
   8714  1.1  mrg       if (NOTE_P (i))
   8715  1.1  mrg 	{
   8716  1.1  mrg 	  switch (NOTE_KIND (i))
   8717  1.1  mrg 	    {
   8718  1.1  mrg 	    case NOTE_INSN_EH_REGION_BEG:
   8719  1.1  mrg 	      exception_nesting++;
   8720  1.1  mrg 	      if (trap_pending)
   8721  1.1  mrg 		goto close_shadow;
   8722  1.1  mrg 	      break;
   8723  1.1  mrg 
   8724  1.1  mrg 	    case NOTE_INSN_EH_REGION_END:
   8725  1.1  mrg 	      exception_nesting--;
   8726  1.1  mrg 	      if (trap_pending)
   8727  1.1  mrg 		goto close_shadow;
   8728  1.1  mrg 	      break;
   8729  1.1  mrg 
   8730  1.1  mrg 	    case NOTE_INSN_EPILOGUE_BEG:
   8731  1.1  mrg 	      if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
   8732  1.1  mrg 		goto close_shadow;
   8733  1.1  mrg 	      break;
   8734  1.1  mrg 	    }
   8735  1.1  mrg 	}
   8736  1.1  mrg       else if (trap_pending)
   8737  1.1  mrg 	{
   8738  1.1  mrg 	  if (alpha_tp == ALPHA_TP_FUNC)
   8739  1.1  mrg 	    {
   8740  1.1  mrg 	      if (JUMP_P (i)
   8741  1.1  mrg 		  && GET_CODE (PATTERN (i)) == RETURN)
   8742  1.1  mrg 		goto close_shadow;
   8743  1.1  mrg 	    }
   8744  1.1  mrg 	  else if (alpha_tp == ALPHA_TP_INSN)
   8745  1.1  mrg 	    {
   8746  1.1  mrg 	      if (optimize > 0)
   8747  1.1  mrg 		{
   8748  1.1  mrg 		  struct shadow_summary sum;
   8749  1.1  mrg 
   8750  1.1  mrg 		  sum.used.i = 0;
   8751  1.1  mrg 		  sum.used.fp = 0;
   8752  1.1  mrg 		  sum.used.mem = 0;
   8753  1.1  mrg 		  sum.defd = sum.used;
   8754  1.1  mrg 
   8755  1.1  mrg 		  switch (GET_CODE (i))
   8756  1.1  mrg 		    {
   8757  1.1  mrg 		    case INSN:
   8758  1.1  mrg 		      /* Annoyingly, get_attr_trap will die on these.  */
   8759  1.1  mrg 		      if (GET_CODE (PATTERN (i)) == USE
   8760  1.1  mrg 			  || GET_CODE (PATTERN (i)) == CLOBBER)
   8761  1.1  mrg 			break;
   8762  1.1  mrg 
   8763  1.1  mrg 		      summarize_insn (PATTERN (i), &sum, 0);
   8764  1.1  mrg 
   8765  1.1  mrg 		      if ((sum.defd.i & shadow.defd.i)
   8766  1.1  mrg 			  || (sum.defd.fp & shadow.defd.fp))
   8767  1.1  mrg 			{
   8768  1.1  mrg 			  /* (c) would be violated */
   8769  1.1  mrg 			  goto close_shadow;
   8770  1.1  mrg 			}
   8771  1.1  mrg 
   8772  1.1  mrg 		      /* Combine shadow with summary of current insn: */
   8773  1.1  mrg 		      shadow.used.i   |= sum.used.i;
   8774  1.1  mrg 		      shadow.used.fp  |= sum.used.fp;
   8775  1.1  mrg 		      shadow.used.mem |= sum.used.mem;
   8776  1.1  mrg 		      shadow.defd.i   |= sum.defd.i;
   8777  1.1  mrg 		      shadow.defd.fp  |= sum.defd.fp;
   8778  1.1  mrg 		      shadow.defd.mem |= sum.defd.mem;
   8779  1.1  mrg 
   8780  1.1  mrg 		      if ((sum.defd.i & shadow.used.i)
   8781  1.1  mrg 			  || (sum.defd.fp & shadow.used.fp)
   8782  1.1  mrg 			  || (sum.defd.mem & shadow.used.mem))
   8783  1.1  mrg 			{
   8784  1.1  mrg 			  /* (a) would be violated (also takes care of (b))  */
   8785  1.1  mrg 			  gcc_assert (get_attr_trap (i) != TRAP_YES
   8786  1.1  mrg 				      || (!(sum.defd.i & sum.used.i)
   8787  1.1  mrg 					  && !(sum.defd.fp & sum.used.fp)));
   8788  1.1  mrg 
   8789  1.1  mrg 			  goto close_shadow;
   8790  1.1  mrg 			}
   8791  1.1  mrg 		      break;
   8792  1.1  mrg 
   8793  1.1  mrg 		    case BARRIER:
   8794  1.1  mrg 		      /* __builtin_unreachable can expand to no code at all,
   8795  1.1  mrg 			 leaving (barrier) RTXes in the instruction stream.  */
   8796  1.1  mrg 		      goto close_shadow_notrapb;
   8797  1.1  mrg 
   8798  1.1  mrg 		    case JUMP_INSN:
   8799  1.1  mrg 		    case CALL_INSN:
   8800  1.1  mrg 		    case CODE_LABEL:
   8801  1.1  mrg 		      goto close_shadow;
   8802  1.1  mrg 
   8803  1.1  mrg 		    case DEBUG_INSN:
   8804  1.1  mrg 		      break;
   8805  1.1  mrg 
   8806  1.1  mrg 		    default:
   8807  1.1  mrg 		      gcc_unreachable ();
   8808  1.1  mrg 		    }
   8809  1.1  mrg 		}
   8810  1.1  mrg 	      else
   8811  1.1  mrg 		{
   8812  1.1  mrg 		close_shadow:
   8813  1.1  mrg 		  n = emit_insn_before (gen_trapb (), i);
   8814  1.1  mrg 		  PUT_MODE (n, TImode);
   8815  1.1  mrg 		  PUT_MODE (i, TImode);
   8816  1.1  mrg 		close_shadow_notrapb:
   8817  1.1  mrg 		  trap_pending = 0;
   8818  1.1  mrg 		  shadow.used.i = 0;
   8819  1.1  mrg 		  shadow.used.fp = 0;
   8820  1.1  mrg 		  shadow.used.mem = 0;
   8821  1.1  mrg 		  shadow.defd = shadow.used;
   8822  1.1  mrg 		}
   8823  1.1  mrg 	    }
   8824  1.1  mrg 	}
   8825  1.1  mrg 
   8826  1.1  mrg       if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
   8827  1.1  mrg 	  && NONJUMP_INSN_P (i)
   8828  1.1  mrg 	  && GET_CODE (PATTERN (i)) != USE
   8829  1.1  mrg 	  && GET_CODE (PATTERN (i)) != CLOBBER
   8830  1.1  mrg 	  && get_attr_trap (i) == TRAP_YES)
   8831  1.1  mrg 	{
   8832  1.1  mrg 	  if (optimize && !trap_pending)
   8833  1.1  mrg 	    summarize_insn (PATTERN (i), &shadow, 0);
   8834  1.1  mrg 	  trap_pending = 1;
   8835  1.1  mrg 	}
   8836  1.1  mrg     }
   8837  1.1  mrg }
   8838  1.1  mrg 
   8839  1.1  mrg /* Alpha can only issue instruction groups simultaneously if they are
   8841  1.1  mrg    suitably aligned.  This is very processor-specific.  */
   8842  1.1  mrg /* There are a number of entries in alphaev4_insn_pipe and alphaev5_insn_pipe
   8843  1.1  mrg    that are marked "fake".  These instructions do not exist on that target,
   8844  1.1  mrg    but it is possible to see these insns with deranged combinations of
   8845  1.1  mrg    command-line options, such as "-mtune=ev4 -mmax".  Instead of aborting,
   8846  1.1  mrg    choose a result at random.  */
   8847  1.1  mrg 
   8848  1.1  mrg enum alphaev4_pipe {
   8849  1.1  mrg   EV4_STOP = 0,
   8850  1.1  mrg   EV4_IB0 = 1,
   8851  1.1  mrg   EV4_IB1 = 2,
   8852  1.1  mrg   EV4_IBX = 4
   8853  1.1  mrg };
   8854  1.1  mrg 
   8855  1.1  mrg enum alphaev5_pipe {
   8856  1.1  mrg   EV5_STOP = 0,
   8857  1.1  mrg   EV5_NONE = 1,
   8858  1.1  mrg   EV5_E01 = 2,
   8859  1.1  mrg   EV5_E0 = 4,
   8860  1.1  mrg   EV5_E1 = 8,
   8861  1.1  mrg   EV5_FAM = 16,
   8862  1.1  mrg   EV5_FA = 32,
   8863  1.1  mrg   EV5_FM = 64
   8864  1.1  mrg };
   8865  1.1  mrg 
   8866  1.1  mrg static enum alphaev4_pipe
   8867  1.1  mrg alphaev4_insn_pipe (rtx_insn *insn)
   8868  1.1  mrg {
   8869  1.1  mrg   if (recog_memoized (insn) < 0)
   8870  1.1  mrg     return EV4_STOP;
   8871  1.1  mrg   if (get_attr_length (insn) != 4)
   8872  1.1  mrg     return EV4_STOP;
   8873  1.1  mrg 
   8874  1.1  mrg   switch (get_attr_type (insn))
   8875  1.1  mrg     {
   8876  1.1  mrg     case TYPE_ILD:
   8877  1.1  mrg     case TYPE_LDSYM:
   8878  1.1  mrg     case TYPE_FLD:
   8879  1.1  mrg     case TYPE_LD_L:
   8880  1.1  mrg       return EV4_IBX;
   8881  1.1  mrg 
   8882  1.1  mrg     case TYPE_IADD:
   8883  1.1  mrg     case TYPE_ILOG:
   8884  1.1  mrg     case TYPE_ICMOV:
   8885  1.1  mrg     case TYPE_ICMP:
   8886  1.1  mrg     case TYPE_FST:
   8887  1.1  mrg     case TYPE_SHIFT:
   8888  1.1  mrg     case TYPE_IMUL:
   8889  1.1  mrg     case TYPE_FBR:
   8890  1.1  mrg     case TYPE_MVI:		/* fake */
   8891  1.1  mrg       return EV4_IB0;
   8892  1.1  mrg 
   8893  1.1  mrg     case TYPE_IST:
   8894  1.1  mrg     case TYPE_MISC:
   8895  1.1  mrg     case TYPE_IBR:
   8896  1.1  mrg     case TYPE_JSR:
   8897  1.1  mrg     case TYPE_CALLPAL:
   8898  1.1  mrg     case TYPE_FCPYS:
   8899  1.1  mrg     case TYPE_FCMOV:
   8900  1.1  mrg     case TYPE_FADD:
   8901  1.1  mrg     case TYPE_FDIV:
   8902  1.1  mrg     case TYPE_FMUL:
   8903  1.1  mrg     case TYPE_ST_C:
   8904  1.1  mrg     case TYPE_MB:
   8905  1.1  mrg     case TYPE_FSQRT:		/* fake */
   8906  1.1  mrg     case TYPE_FTOI:		/* fake */
   8907  1.1  mrg     case TYPE_ITOF:		/* fake */
   8908  1.1  mrg       return EV4_IB1;
   8909  1.1  mrg 
   8910  1.1  mrg     default:
   8911  1.1  mrg       gcc_unreachable ();
   8912  1.1  mrg     }
   8913  1.1  mrg }
   8914  1.1  mrg 
   8915  1.1  mrg static enum alphaev5_pipe
   8916  1.1  mrg alphaev5_insn_pipe (rtx_insn *insn)
   8917  1.1  mrg {
   8918  1.1  mrg   if (recog_memoized (insn) < 0)
   8919  1.1  mrg     return EV5_STOP;
   8920  1.1  mrg   if (get_attr_length (insn) != 4)
   8921  1.1  mrg     return EV5_STOP;
   8922  1.1  mrg 
   8923  1.1  mrg   switch (get_attr_type (insn))
   8924  1.1  mrg     {
   8925  1.1  mrg     case TYPE_ILD:
   8926  1.1  mrg     case TYPE_FLD:
   8927  1.1  mrg     case TYPE_LDSYM:
   8928  1.1  mrg     case TYPE_IADD:
   8929  1.1  mrg     case TYPE_ILOG:
   8930  1.1  mrg     case TYPE_ICMOV:
   8931  1.1  mrg     case TYPE_ICMP:
   8932  1.1  mrg       return EV5_E01;
   8933  1.1  mrg 
   8934  1.1  mrg     case TYPE_IST:
   8935  1.1  mrg     case TYPE_FST:
   8936  1.1  mrg     case TYPE_SHIFT:
   8937  1.1  mrg     case TYPE_IMUL:
   8938  1.1  mrg     case TYPE_MISC:
   8939  1.1  mrg     case TYPE_MVI:
   8940  1.1  mrg     case TYPE_LD_L:
   8941  1.1  mrg     case TYPE_ST_C:
   8942  1.1  mrg     case TYPE_MB:
   8943  1.1  mrg     case TYPE_FTOI:		/* fake */
   8944  1.1  mrg     case TYPE_ITOF:		/* fake */
   8945  1.1  mrg       return EV5_E0;
   8946  1.1  mrg 
   8947  1.1  mrg     case TYPE_IBR:
   8948  1.1  mrg     case TYPE_JSR:
   8949  1.1  mrg     case TYPE_CALLPAL:
   8950  1.1  mrg       return EV5_E1;
   8951  1.1  mrg 
   8952  1.1  mrg     case TYPE_FCPYS:
   8953  1.1  mrg       return EV5_FAM;
   8954  1.1  mrg 
   8955  1.1  mrg     case TYPE_FBR:
   8956  1.1  mrg     case TYPE_FCMOV:
   8957  1.1  mrg     case TYPE_FADD:
   8958  1.1  mrg     case TYPE_FDIV:
   8959  1.1  mrg     case TYPE_FSQRT:		/* fake */
   8960  1.1  mrg       return EV5_FA;
   8961  1.1  mrg 
   8962  1.1  mrg     case TYPE_FMUL:
   8963  1.1  mrg       return EV5_FM;
   8964  1.1  mrg 
   8965  1.1  mrg     default:
   8966  1.1  mrg       gcc_unreachable ();
   8967  1.1  mrg     }
   8968  1.1  mrg }
   8969  1.1  mrg 
   8970  1.1  mrg /* IN_USE is a mask of the slots currently filled within the insn group.
   8971  1.1  mrg    The mask bits come from alphaev4_pipe above.  If EV4_IBX is set, then
   8972  1.1  mrg    the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
   8973  1.1  mrg 
   8974  1.1  mrg    LEN is, of course, the length of the group in bytes.  */
   8975  1.1  mrg 
   8976  1.1  mrg static rtx_insn *
   8977  1.1  mrg alphaev4_next_group (rtx_insn *insn, int *pin_use, int *plen)
   8978  1.1  mrg {
   8979  1.1  mrg   int len, in_use;
   8980  1.1  mrg 
   8981  1.1  mrg   len = in_use = 0;
   8982  1.1  mrg 
   8983  1.1  mrg   if (! INSN_P (insn)
   8984  1.1  mrg       || GET_CODE (PATTERN (insn)) == CLOBBER
   8985  1.1  mrg       || GET_CODE (PATTERN (insn)) == USE)
   8986  1.1  mrg     goto next_and_done;
   8987  1.1  mrg 
   8988  1.1  mrg   while (1)
   8989  1.1  mrg     {
   8990  1.1  mrg       enum alphaev4_pipe pipe;
   8991  1.1  mrg 
   8992  1.1  mrg       pipe = alphaev4_insn_pipe (insn);
   8993  1.1  mrg       switch (pipe)
   8994  1.1  mrg 	{
   8995  1.1  mrg 	case EV4_STOP:
   8996  1.1  mrg 	  /* Force complex instructions to start new groups.  */
   8997  1.1  mrg 	  if (in_use)
   8998  1.1  mrg 	    goto done;
   8999  1.1  mrg 
   9000  1.1  mrg 	  /* If this is a completely unrecognized insn, it's an asm.
   9001  1.1  mrg 	     We don't know how long it is, so record length as -1 to
   9002  1.1  mrg 	     signal a needed realignment.  */
   9003  1.1  mrg 	  if (recog_memoized (insn) < 0)
   9004  1.1  mrg 	    len = -1;
   9005  1.1  mrg 	  else
   9006  1.1  mrg 	    len = get_attr_length (insn);
   9007  1.1  mrg 	  goto next_and_done;
   9008  1.1  mrg 
   9009  1.1  mrg 	case EV4_IBX:
   9010  1.1  mrg 	  if (in_use & EV4_IB0)
   9011  1.1  mrg 	    {
   9012  1.1  mrg 	      if (in_use & EV4_IB1)
   9013  1.1  mrg 		goto done;
   9014  1.1  mrg 	      in_use |= EV4_IB1;
   9015  1.1  mrg 	    }
   9016  1.1  mrg 	  else
   9017  1.1  mrg 	    in_use |= EV4_IB0 | EV4_IBX;
   9018  1.1  mrg 	  break;
   9019  1.1  mrg 
   9020  1.1  mrg 	case EV4_IB0:
   9021  1.1  mrg 	  if (in_use & EV4_IB0)
   9022  1.1  mrg 	    {
   9023  1.1  mrg 	      if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
   9024  1.1  mrg 		goto done;
   9025  1.1  mrg 	      in_use |= EV4_IB1;
   9026  1.1  mrg 	    }
   9027  1.1  mrg 	  in_use |= EV4_IB0;
   9028  1.1  mrg 	  break;
   9029  1.1  mrg 
   9030  1.1  mrg 	case EV4_IB1:
   9031  1.1  mrg 	  if (in_use & EV4_IB1)
   9032  1.1  mrg 	    goto done;
   9033  1.1  mrg 	  in_use |= EV4_IB1;
   9034  1.1  mrg 	  break;
   9035  1.1  mrg 
   9036  1.1  mrg 	default:
   9037  1.1  mrg 	  gcc_unreachable ();
   9038  1.1  mrg 	}
   9039  1.1  mrg       len += 4;
   9040  1.1  mrg 
   9041  1.1  mrg       /* Haifa doesn't do well scheduling branches.  */
   9042  1.1  mrg       if (JUMP_P (insn))
   9043  1.1  mrg 	goto next_and_done;
   9044  1.1  mrg 
   9045  1.1  mrg     next:
   9046  1.1  mrg       insn = next_nonnote_insn (insn);
   9047  1.1  mrg 
   9048  1.1  mrg       if (!insn || ! INSN_P (insn))
   9049  1.1  mrg 	goto done;
   9050  1.1  mrg 
   9051  1.1  mrg       /* Let Haifa tell us where it thinks insn group boundaries are.  */
   9052  1.1  mrg       if (GET_MODE (insn) == TImode)
   9053  1.1  mrg 	goto done;
   9054  1.1  mrg 
   9055  1.1  mrg       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
   9056  1.1  mrg 	goto next;
   9057  1.1  mrg     }
   9058  1.1  mrg 
   9059  1.1  mrg  next_and_done:
   9060  1.1  mrg   insn = next_nonnote_insn (insn);
   9061  1.1  mrg 
   9062  1.1  mrg  done:
   9063  1.1  mrg   *plen = len;
   9064  1.1  mrg   *pin_use = in_use;
   9065  1.1  mrg   return insn;
   9066  1.1  mrg }
   9067  1.1  mrg 
   9068  1.1  mrg /* IN_USE is a mask of the slots currently filled within the insn group.
   9069  1.1  mrg    The mask bits come from alphaev5_pipe above.  If EV5_E01 is set, then
   9070  1.1  mrg    the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
   9071  1.1  mrg 
   9072  1.1  mrg    LEN is, of course, the length of the group in bytes.  */
   9073  1.1  mrg 
   9074  1.1  mrg static rtx_insn *
   9075  1.1  mrg alphaev5_next_group (rtx_insn *insn, int *pin_use, int *plen)
   9076  1.1  mrg {
   9077  1.1  mrg   int len, in_use;
   9078  1.1  mrg 
   9079  1.1  mrg   len = in_use = 0;
   9080  1.1  mrg 
   9081  1.1  mrg   if (! INSN_P (insn)
   9082  1.1  mrg       || GET_CODE (PATTERN (insn)) == CLOBBER
   9083  1.1  mrg       || GET_CODE (PATTERN (insn)) == USE)
   9084  1.1  mrg     goto next_and_done;
   9085  1.1  mrg 
   9086  1.1  mrg   while (1)
   9087  1.1  mrg     {
   9088  1.1  mrg       enum alphaev5_pipe pipe;
   9089  1.1  mrg 
   9090  1.1  mrg       pipe = alphaev5_insn_pipe (insn);
   9091  1.1  mrg       switch (pipe)
   9092  1.1  mrg 	{
   9093  1.1  mrg 	case EV5_STOP:
   9094  1.1  mrg 	  /* Force complex instructions to start new groups.  */
   9095  1.1  mrg 	  if (in_use)
   9096  1.1  mrg 	    goto done;
   9097  1.1  mrg 
   9098  1.1  mrg 	  /* If this is a completely unrecognized insn, it's an asm.
   9099  1.1  mrg 	     We don't know how long it is, so record length as -1 to
   9100  1.1  mrg 	     signal a needed realignment.  */
   9101  1.1  mrg 	  if (recog_memoized (insn) < 0)
   9102  1.1  mrg 	    len = -1;
   9103  1.1  mrg 	  else
   9104  1.1  mrg 	    len = get_attr_length (insn);
   9105  1.1  mrg 	  goto next_and_done;
   9106  1.1  mrg 
   9107  1.1  mrg 	/* ??? Most of the places below, we would like to assert never
   9108  1.1  mrg 	   happen, as it would indicate an error either in Haifa, or
   9109  1.1  mrg 	   in the scheduling description.  Unfortunately, Haifa never
   9110  1.1  mrg 	   schedules the last instruction of the BB, so we don't have
   9111  1.1  mrg 	   an accurate TI bit to go off.  */
   9112  1.1  mrg 	case EV5_E01:
   9113  1.1  mrg 	  if (in_use & EV5_E0)
   9114  1.1  mrg 	    {
   9115  1.1  mrg 	      if (in_use & EV5_E1)
   9116  1.1  mrg 		goto done;
   9117  1.1  mrg 	      in_use |= EV5_E1;
   9118  1.1  mrg 	    }
   9119  1.1  mrg 	  else
   9120  1.1  mrg 	    in_use |= EV5_E0 | EV5_E01;
   9121  1.1  mrg 	  break;
   9122  1.1  mrg 
   9123  1.1  mrg 	case EV5_E0:
   9124  1.1  mrg 	  if (in_use & EV5_E0)
   9125  1.1  mrg 	    {
   9126  1.1  mrg 	      if (!(in_use & EV5_E01) || (in_use & EV5_E1))
   9127  1.1  mrg 		goto done;
   9128  1.1  mrg 	      in_use |= EV5_E1;
   9129  1.1  mrg 	    }
   9130  1.1  mrg 	  in_use |= EV5_E0;
   9131  1.1  mrg 	  break;
   9132  1.1  mrg 
   9133  1.1  mrg 	case EV5_E1:
   9134  1.1  mrg 	  if (in_use & EV5_E1)
   9135  1.1  mrg 	    goto done;
   9136  1.1  mrg 	  in_use |= EV5_E1;
   9137  1.1  mrg 	  break;
   9138  1.1  mrg 
   9139  1.1  mrg 	case EV5_FAM:
   9140  1.1  mrg 	  if (in_use & EV5_FA)
   9141  1.1  mrg 	    {
   9142  1.1  mrg 	      if (in_use & EV5_FM)
   9143  1.1  mrg 		goto done;
   9144  1.1  mrg 	      in_use |= EV5_FM;
   9145  1.1  mrg 	    }
   9146  1.1  mrg 	  else
   9147  1.1  mrg 	    in_use |= EV5_FA | EV5_FAM;
   9148  1.1  mrg 	  break;
   9149  1.1  mrg 
   9150  1.1  mrg 	case EV5_FA:
   9151  1.1  mrg 	  if (in_use & EV5_FA)
   9152  1.1  mrg 	    goto done;
   9153  1.1  mrg 	  in_use |= EV5_FA;
   9154  1.1  mrg 	  break;
   9155  1.1  mrg 
   9156  1.1  mrg 	case EV5_FM:
   9157  1.1  mrg 	  if (in_use & EV5_FM)
   9158  1.1  mrg 	    goto done;
   9159  1.1  mrg 	  in_use |= EV5_FM;
   9160  1.1  mrg 	  break;
   9161  1.1  mrg 
   9162  1.1  mrg 	case EV5_NONE:
   9163  1.1  mrg 	  break;
   9164  1.1  mrg 
   9165  1.1  mrg 	default:
   9166  1.1  mrg 	  gcc_unreachable ();
   9167  1.1  mrg 	}
   9168  1.1  mrg       len += 4;
   9169  1.1  mrg 
   9170  1.1  mrg       /* Haifa doesn't do well scheduling branches.  */
   9171  1.1  mrg       /* ??? If this is predicted not-taken, slotting continues, except
   9172  1.1  mrg 	 that no more IBR, FBR, or JSR insns may be slotted.  */
   9173  1.1  mrg       if (JUMP_P (insn))
   9174  1.1  mrg 	goto next_and_done;
   9175  1.1  mrg 
   9176  1.1  mrg     next:
   9177  1.1  mrg       insn = next_nonnote_insn (insn);
   9178  1.1  mrg 
   9179  1.1  mrg       if (!insn || ! INSN_P (insn))
   9180  1.1  mrg 	goto done;
   9181  1.1  mrg 
   9182  1.1  mrg       /* Let Haifa tell us where it thinks insn group boundaries are.  */
   9183  1.1  mrg       if (GET_MODE (insn) == TImode)
   9184  1.1  mrg 	goto done;
   9185  1.1  mrg 
   9186  1.1  mrg       if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
   9187  1.1  mrg 	goto next;
   9188  1.1  mrg     }
   9189  1.1  mrg 
   9190  1.1  mrg  next_and_done:
   9191  1.1  mrg   insn = next_nonnote_insn (insn);
   9192  1.1  mrg 
   9193  1.1  mrg  done:
   9194  1.1  mrg   *plen = len;
   9195  1.1  mrg   *pin_use = in_use;
   9196  1.1  mrg   return insn;
   9197  1.1  mrg }
   9198  1.1  mrg 
   9199  1.1  mrg static rtx
   9200  1.1  mrg alphaev4_next_nop (int *pin_use)
   9201  1.1  mrg {
   9202  1.1  mrg   int in_use = *pin_use;
   9203  1.1  mrg   rtx nop;
   9204  1.1  mrg 
   9205  1.1  mrg   if (!(in_use & EV4_IB0))
   9206  1.1  mrg     {
   9207  1.1  mrg       in_use |= EV4_IB0;
   9208  1.1  mrg       nop = gen_nop ();
   9209  1.1  mrg     }
   9210  1.1  mrg   else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
   9211  1.1  mrg     {
   9212  1.1  mrg       in_use |= EV4_IB1;
   9213  1.1  mrg       nop = gen_nop ();
   9214  1.1  mrg     }
   9215  1.1  mrg   else if (TARGET_FP && !(in_use & EV4_IB1))
   9216  1.1  mrg     {
   9217  1.1  mrg       in_use |= EV4_IB1;
   9218  1.1  mrg       nop = gen_fnop ();
   9219  1.1  mrg     }
   9220  1.1  mrg   else
   9221  1.1  mrg     nop = gen_unop ();
   9222  1.1  mrg 
   9223  1.1  mrg   *pin_use = in_use;
   9224  1.1  mrg   return nop;
   9225  1.1  mrg }
   9226  1.1  mrg 
   9227  1.1  mrg static rtx
   9228  1.1  mrg alphaev5_next_nop (int *pin_use)
   9229  1.1  mrg {
   9230  1.1  mrg   int in_use = *pin_use;
   9231  1.1  mrg   rtx nop;
   9232  1.1  mrg 
   9233  1.1  mrg   if (!(in_use & EV5_E1))
   9234  1.1  mrg     {
   9235  1.1  mrg       in_use |= EV5_E1;
   9236  1.1  mrg       nop = gen_nop ();
   9237  1.1  mrg     }
   9238  1.1  mrg   else if (TARGET_FP && !(in_use & EV5_FA))
   9239  1.1  mrg     {
   9240  1.1  mrg       in_use |= EV5_FA;
   9241  1.1  mrg       nop = gen_fnop ();
   9242  1.1  mrg     }
   9243  1.1  mrg   else if (TARGET_FP && !(in_use & EV5_FM))
   9244  1.1  mrg     {
   9245  1.1  mrg       in_use |= EV5_FM;
   9246  1.1  mrg       nop = gen_fnop ();
   9247  1.1  mrg     }
   9248  1.1  mrg   else
   9249  1.1  mrg     nop = gen_unop ();
   9250  1.1  mrg 
   9251  1.1  mrg   *pin_use = in_use;
   9252  1.1  mrg   return nop;
   9253  1.1  mrg }
   9254  1.1  mrg 
   9255  1.1  mrg /* The instruction group alignment main loop.  */
   9256  1.1  mrg 
   9257  1.1  mrg static void
   9258  1.1  mrg alpha_align_insns_1 (unsigned int max_align,
   9259  1.1  mrg 		     rtx_insn *(*next_group) (rtx_insn *, int *, int *),
   9260  1.1  mrg 		     rtx (*next_nop) (int *))
   9261  1.1  mrg {
   9262  1.1  mrg   /* ALIGN is the known alignment for the insn group.  */
   9263  1.1  mrg   unsigned int align;
   9264  1.1  mrg   /* OFS is the offset of the current insn in the insn group.  */
   9265  1.1  mrg   int ofs;
   9266  1.1  mrg   int prev_in_use, in_use, len, ldgp;
   9267  1.1  mrg   rtx_insn *i, *next;
   9268  1.1  mrg 
   9269  1.1  mrg   /* Let shorten branches care for assigning alignments to code labels.  */
   9270  1.1  mrg   shorten_branches (get_insns ());
   9271  1.1  mrg 
   9272  1.1  mrg   unsigned int option_alignment = align_functions.levels[0].get_value ();
   9273  1.1  mrg   if (option_alignment < 4)
   9274  1.1  mrg     align = 4;
   9275  1.1  mrg   else if ((unsigned int) option_alignment < max_align)
   9276  1.1  mrg     align = option_alignment;
   9277  1.1  mrg   else
   9278  1.1  mrg     align = max_align;
   9279  1.1  mrg 
   9280  1.1  mrg   ofs = prev_in_use = 0;
   9281  1.1  mrg   i = get_insns ();
   9282  1.1  mrg   if (NOTE_P (i))
   9283  1.1  mrg     i = next_nonnote_insn (i);
   9284  1.1  mrg 
   9285  1.1  mrg   ldgp = alpha_function_needs_gp ? 8 : 0;
   9286  1.1  mrg 
   9287  1.1  mrg   while (i)
   9288  1.1  mrg     {
   9289  1.1  mrg       next = (*next_group) (i, &in_use, &len);
   9290  1.1  mrg 
   9291  1.1  mrg       /* When we see a label, resync alignment etc.  */
   9292  1.1  mrg       if (LABEL_P (i))
   9293  1.1  mrg 	{
   9294  1.1  mrg 	  unsigned int new_align
   9295  1.1  mrg 	    = label_to_alignment (i).levels[0].get_value ();
   9296  1.1  mrg 
   9297  1.1  mrg 	  if (new_align >= align)
   9298  1.1  mrg 	    {
   9299  1.1  mrg 	      align = new_align < max_align ? new_align : max_align;
   9300  1.1  mrg 	      ofs = 0;
   9301  1.1  mrg 	    }
   9302  1.1  mrg 
   9303  1.1  mrg 	  else if (ofs & (new_align-1))
   9304  1.1  mrg 	    ofs = (ofs | (new_align-1)) + 1;
   9305  1.1  mrg 	  gcc_assert (!len);
   9306  1.1  mrg 	}
   9307  1.1  mrg 
   9308  1.1  mrg       /* Handle complex instructions special.  */
   9309  1.1  mrg       else if (in_use == 0)
   9310  1.1  mrg 	{
   9311  1.1  mrg 	  /* Asms will have length < 0.  This is a signal that we have
   9312  1.1  mrg 	     lost alignment knowledge.  Assume, however, that the asm
   9313  1.1  mrg 	     will not mis-align instructions.  */
   9314  1.1  mrg 	  if (len < 0)
   9315  1.1  mrg 	    {
   9316  1.1  mrg 	      ofs = 0;
   9317  1.1  mrg 	      align = 4;
   9318  1.1  mrg 	      len = 0;
   9319  1.1  mrg 	    }
   9320  1.1  mrg 	}
   9321  1.1  mrg 
   9322  1.1  mrg       /* If the known alignment is smaller than the recognized insn group,
   9323  1.1  mrg 	 realign the output.  */
   9324  1.1  mrg       else if ((int) align < len)
   9325  1.1  mrg 	{
   9326  1.1  mrg 	  unsigned int new_log_align = len > 8 ? 4 : 3;
   9327  1.1  mrg 	  rtx_insn *prev, *where;
   9328  1.1  mrg 
   9329  1.1  mrg 	  where = prev = prev_nonnote_insn (i);
   9330  1.1  mrg 	  if (!where || !LABEL_P (where))
   9331  1.1  mrg 	    where = i;
   9332  1.1  mrg 
   9333  1.1  mrg 	  /* Can't realign between a call and its gp reload.  */
   9334  1.1  mrg 	  if (! (TARGET_EXPLICIT_RELOCS
   9335  1.1  mrg 		 && prev && CALL_P (prev)))
   9336  1.1  mrg 	    {
   9337  1.1  mrg 	      emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
   9338  1.1  mrg 	      align = 1 << new_log_align;
   9339  1.1  mrg 	      ofs = 0;
   9340  1.1  mrg 	    }
   9341  1.1  mrg 	}
   9342  1.1  mrg 
   9343  1.1  mrg       /* We may not insert padding inside the initial ldgp sequence.  */
   9344  1.1  mrg       else if (ldgp > 0)
   9345  1.1  mrg 	ldgp -= len;
   9346  1.1  mrg 
   9347  1.1  mrg       /* If the group won't fit in the same INT16 as the previous,
   9348  1.1  mrg 	 we need to add padding to keep the group together.  Rather
   9349  1.1  mrg 	 than simply leaving the insn filling to the assembler, we
   9350  1.1  mrg 	 can make use of the knowledge of what sorts of instructions
   9351  1.1  mrg 	 were issued in the previous group to make sure that all of
   9352  1.1  mrg 	 the added nops are really free.  */
   9353  1.1  mrg       else if (ofs + len > (int) align)
   9354  1.1  mrg 	{
   9355  1.1  mrg 	  int nop_count = (align - ofs) / 4;
   9356  1.1  mrg 	  rtx_insn *where;
   9357  1.1  mrg 
   9358  1.1  mrg 	  /* Insert nops before labels, branches, and calls to truly merge
   9359  1.1  mrg 	     the execution of the nops with the previous instruction group.  */
   9360  1.1  mrg 	  where = prev_nonnote_insn (i);
   9361  1.1  mrg 	  if (where)
   9362  1.1  mrg 	    {
   9363  1.1  mrg 	      if (LABEL_P (where))
   9364  1.1  mrg 		{
   9365  1.1  mrg 		  rtx_insn *where2 = prev_nonnote_insn (where);
   9366  1.1  mrg 		  if (where2 && JUMP_P (where2))
   9367  1.1  mrg 		    where = where2;
   9368  1.1  mrg 		}
   9369  1.1  mrg 	      else if (NONJUMP_INSN_P (where))
   9370  1.1  mrg 		where = i;
   9371  1.1  mrg 	    }
   9372  1.1  mrg 	  else
   9373  1.1  mrg 	    where = i;
   9374  1.1  mrg 
   9375  1.1  mrg 	  do
   9376  1.1  mrg 	    emit_insn_before ((*next_nop)(&prev_in_use), where);
   9377  1.1  mrg 	  while (--nop_count);
   9378  1.1  mrg 	  ofs = 0;
   9379  1.1  mrg 	}
   9380  1.1  mrg 
   9381  1.1  mrg       ofs = (ofs + len) & (align - 1);
   9382  1.1  mrg       prev_in_use = in_use;
   9383  1.1  mrg       i = next;
   9384  1.1  mrg     }
   9385  1.1  mrg }
   9386  1.1  mrg 
   9387  1.1  mrg static void
   9388  1.1  mrg alpha_align_insns (void)
   9389  1.1  mrg {
   9390  1.1  mrg   if (alpha_tune == PROCESSOR_EV4)
   9391  1.1  mrg     alpha_align_insns_1 (8, alphaev4_next_group, alphaev4_next_nop);
   9392  1.1  mrg   else if (alpha_tune == PROCESSOR_EV5)
   9393  1.1  mrg     alpha_align_insns_1 (16, alphaev5_next_group, alphaev5_next_nop);
   9394  1.1  mrg   else
   9395  1.1  mrg     gcc_unreachable ();
   9396  1.1  mrg }
   9397  1.1  mrg 
   9398  1.1  mrg /* Insert an unop between sibcall or noreturn function call and GP load.  */
   9399  1.1  mrg 
   9400  1.1  mrg static void
   9401  1.1  mrg alpha_pad_function_end (void)
   9402  1.1  mrg {
   9403  1.1  mrg   rtx_insn *insn, *next;
   9404  1.1  mrg 
   9405  1.1  mrg   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
   9406  1.1  mrg     {
   9407  1.1  mrg       if (!CALL_P (insn)
   9408  1.1  mrg 	  || !(SIBLING_CALL_P (insn)
   9409  1.1  mrg 	       || find_reg_note (insn, REG_NORETURN, NULL_RTX)))
   9410  1.1  mrg         continue;
   9411  1.1  mrg 
   9412  1.1  mrg       next = next_active_insn (insn);
   9413  1.1  mrg       if (next)
   9414  1.1  mrg 	{
   9415  1.1  mrg 	  rtx pat = PATTERN (next);
   9416  1.1  mrg 
   9417  1.1  mrg 	  if (GET_CODE (pat) == SET
   9418  1.1  mrg 	      && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
   9419  1.1  mrg 	      && XINT (SET_SRC (pat), 1) == UNSPECV_LDGP1)
   9420  1.1  mrg 	    emit_insn_after (gen_unop (), insn);
   9421  1.1  mrg 	}
   9422  1.1  mrg     }
   9423  1.1  mrg }
   9424  1.1  mrg 
   9425  1.1  mrg /* Machine dependent reorg pass.  */
   9427  1.1  mrg 
   9428  1.1  mrg static void
   9429  1.1  mrg alpha_reorg (void)
   9430  1.1  mrg {
   9431  1.1  mrg   /* Workaround for a linker error that triggers when an exception
   9432  1.1  mrg      handler immediatelly follows a sibcall or a noreturn function.
   9433  1.1  mrg 
   9434  1.1  mrg In the sibcall case:
   9435  1.1  mrg 
   9436  1.1  mrg      The instruction stream from an object file:
   9437  1.1  mrg 
   9438  1.1  mrg  1d8:   00 00 fb 6b     jmp     (t12)
   9439  1.1  mrg  1dc:   00 00 ba 27     ldah    gp,0(ra)
   9440  1.1  mrg  1e0:   00 00 bd 23     lda     gp,0(gp)
   9441  1.1  mrg  1e4:   00 00 7d a7     ldq     t12,0(gp)
   9442  1.1  mrg  1e8:   00 40 5b 6b     jsr     ra,(t12),1ec <__funcZ+0x1ec>
   9443  1.1  mrg 
   9444  1.1  mrg      was converted in the final link pass to:
   9445  1.1  mrg 
   9446  1.1  mrg    12003aa88:   67 fa ff c3     br      120039428 <...>
   9447  1.1  mrg    12003aa8c:   00 00 fe 2f     unop
   9448  1.1  mrg    12003aa90:   00 00 fe 2f     unop
   9449  1.1  mrg    12003aa94:   48 83 7d a7     ldq     t12,-31928(gp)
   9450  1.1  mrg    12003aa98:   00 40 5b 6b     jsr     ra,(t12),12003aa9c <__func+0x1ec>
   9451  1.1  mrg 
   9452  1.1  mrg And in the noreturn case:
   9453  1.1  mrg 
   9454  1.1  mrg      The instruction stream from an object file:
   9455  1.1  mrg 
   9456  1.1  mrg   54:   00 40 5b 6b     jsr     ra,(t12),58 <__func+0x58>
   9457  1.1  mrg   58:   00 00 ba 27     ldah    gp,0(ra)
   9458  1.1  mrg   5c:   00 00 bd 23     lda     gp,0(gp)
   9459  1.1  mrg   60:   00 00 7d a7     ldq     t12,0(gp)
   9460  1.1  mrg   64:   00 40 5b 6b     jsr     ra,(t12),68 <__func+0x68>
   9461  1.1  mrg 
   9462  1.1  mrg      was converted in the final link pass to:
   9463  1.1  mrg 
   9464  1.1  mrg    fdb24:       a0 03 40 d3     bsr     ra,fe9a8 <_called_func+0x8>
   9465  1.1  mrg    fdb28:       00 00 fe 2f     unop
   9466  1.1  mrg    fdb2c:       00 00 fe 2f     unop
   9467  1.1  mrg    fdb30:       30 82 7d a7     ldq     t12,-32208(gp)
   9468  1.1  mrg    fdb34:       00 40 5b 6b     jsr     ra,(t12),fdb38 <__func+0x68>
   9469  1.1  mrg 
   9470  1.1  mrg      GP load instructions were wrongly cleared by the linker relaxation
   9471  1.1  mrg      pass.  This workaround prevents removal of GP loads by inserting
   9472  1.1  mrg      an unop instruction between a sibcall or noreturn function call and
   9473  1.1  mrg      exception handler prologue.  */
   9474  1.1  mrg 
   9475  1.1  mrg   if (current_function_has_exception_handlers ())
   9476  1.1  mrg     alpha_pad_function_end ();
   9477  1.1  mrg 
   9478  1.1  mrg   /* CALL_PAL that implements trap insn, updates program counter to point
   9479  1.1  mrg      after the insn.  In case trap is the last insn in the function,
   9480  1.1  mrg      emit NOP to guarantee that PC remains inside function boundaries.
   9481  1.1  mrg      This workaround is needed to get reliable backtraces.  */
   9482  1.1  mrg 
   9483  1.1  mrg   rtx_insn *insn = prev_active_insn (get_last_insn ());
   9484  1.1  mrg 
   9485  1.1  mrg   if (insn && NONJUMP_INSN_P (insn))
   9486  1.1  mrg     {
   9487  1.1  mrg       rtx pat = PATTERN (insn);
   9488  1.1  mrg       if (GET_CODE (pat) == PARALLEL)
   9489  1.1  mrg 	{
   9490  1.1  mrg 	  rtx vec = XVECEXP (pat, 0, 0);
   9491  1.1  mrg 	  if (GET_CODE (vec) == TRAP_IF
   9492  1.1  mrg 	      && XEXP (vec, 0) == const1_rtx)
   9493  1.1  mrg 	    emit_insn_after (gen_unop (), insn);
   9494  1.1  mrg 	}
   9495  1.1  mrg     }
   9496  1.1  mrg }
   9497  1.1  mrg 
   9498  1.1  mrg static void
   9500  1.1  mrg alpha_file_start (void)
   9501  1.1  mrg {
   9502  1.1  mrg   default_file_start ();
   9503  1.1  mrg 
   9504  1.1  mrg   fputs ("\t.set noreorder\n", asm_out_file);
   9505  1.1  mrg   fputs ("\t.set volatile\n", asm_out_file);
   9506  1.1  mrg   if (TARGET_ABI_OSF)
   9507  1.1  mrg     fputs ("\t.set noat\n", asm_out_file);
   9508  1.1  mrg   if (TARGET_EXPLICIT_RELOCS)
   9509  1.1  mrg     fputs ("\t.set nomacro\n", asm_out_file);
   9510  1.1  mrg   if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
   9511  1.1  mrg     {
   9512  1.1  mrg       const char *arch;
   9513  1.1  mrg 
   9514  1.1  mrg       if (alpha_cpu == PROCESSOR_EV6 || TARGET_FIX || TARGET_CIX)
   9515  1.1  mrg 	arch = "ev6";
   9516  1.1  mrg       else if (TARGET_MAX)
   9517  1.1  mrg 	arch = "pca56";
   9518  1.1  mrg       else if (TARGET_BWX)
   9519  1.1  mrg 	arch = "ev56";
   9520  1.1  mrg       else if (alpha_cpu == PROCESSOR_EV5)
   9521  1.1  mrg 	arch = "ev5";
   9522  1.1  mrg       else
   9523  1.1  mrg 	arch = "ev4";
   9524  1.1  mrg 
   9525  1.1  mrg       fprintf (asm_out_file, "\t.arch %s\n", arch);
   9526  1.1  mrg     }
   9527  1.1  mrg }
   9528  1.1  mrg 
   9529  1.1  mrg /* Since we don't have a .dynbss section, we should not allow global
   9530  1.1  mrg    relocations in the .rodata section.  */
   9531  1.1  mrg 
   9532  1.1  mrg static int
   9533  1.1  mrg alpha_elf_reloc_rw_mask (void)
   9534  1.1  mrg {
   9535  1.1  mrg   return flag_pic ? 3 : 2;
   9536  1.1  mrg }
   9537  1.1  mrg 
   9538  1.1  mrg /* Return a section for X.  The only special thing we do here is to
   9539  1.1  mrg    honor small data.  */
   9540  1.1  mrg 
   9541  1.1  mrg static section *
   9542  1.1  mrg alpha_elf_select_rtx_section (machine_mode mode, rtx x,
   9543  1.1  mrg 			      unsigned HOST_WIDE_INT align)
   9544  1.1  mrg {
   9545  1.1  mrg   if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
   9546  1.1  mrg     /* ??? Consider using mergeable sdata sections.  */
   9547  1.1  mrg     return sdata_section;
   9548  1.1  mrg   else
   9549  1.1  mrg     return default_elf_select_rtx_section (mode, x, align);
   9550  1.1  mrg }
   9551  1.1  mrg 
   9552  1.1  mrg static unsigned int
   9553  1.1  mrg alpha_elf_section_type_flags (tree decl, const char *name, int reloc)
   9554  1.1  mrg {
   9555  1.1  mrg   unsigned int flags = 0;
   9556  1.1  mrg 
   9557  1.1  mrg   if (strcmp (name, ".sdata") == 0
   9558  1.1  mrg       || startswith (name, ".sdata.")
   9559  1.1  mrg       || startswith (name, ".gnu.linkonce.s.")
   9560  1.1  mrg       || strcmp (name, ".sbss") == 0
   9561  1.1  mrg       || startswith (name, ".sbss.")
   9562  1.1  mrg       || startswith (name, ".gnu.linkonce.sb."))
   9563  1.1  mrg     flags = SECTION_SMALL;
   9564  1.1  mrg 
   9565  1.1  mrg   flags |= default_section_type_flags (decl, name, reloc);
   9566  1.1  mrg   return flags;
   9567  1.1  mrg }
   9568  1.1  mrg 
   9569  1.1  mrg /* Structure to collect function names for final output in link section.  */
   9571  1.1  mrg /* Note that items marked with GTY can't be ifdef'ed out.  */
   9572  1.1  mrg 
   9573  1.1  mrg enum reloc_kind
   9574  1.1  mrg {
   9575  1.1  mrg   KIND_LINKAGE,
   9576  1.1  mrg   KIND_CODEADDR
   9577  1.1  mrg };
   9578  1.1  mrg 
   9579  1.1  mrg struct GTY(()) alpha_links
   9580  1.1  mrg {
   9581  1.1  mrg   rtx func;
   9582  1.1  mrg   rtx linkage;
   9583  1.1  mrg   enum reloc_kind rkind;
   9584  1.1  mrg };
   9585  1.1  mrg 
   9586  1.1  mrg #if TARGET_ABI_OPEN_VMS
   9587  1.1  mrg 
   9588  1.1  mrg /* Return the VMS argument type corresponding to MODE.  */
   9589  1.1  mrg 
   9590  1.1  mrg enum avms_arg_type
   9591  1.1  mrg alpha_arg_type (machine_mode mode)
   9592  1.1  mrg {
   9593  1.1  mrg   switch (mode)
   9594  1.1  mrg     {
   9595  1.1  mrg     case E_SFmode:
   9596  1.1  mrg       return TARGET_FLOAT_VAX ? FF : FS;
   9597  1.1  mrg     case E_DFmode:
   9598  1.1  mrg       return TARGET_FLOAT_VAX ? FD : FT;
   9599  1.1  mrg     default:
   9600  1.1  mrg       return I64;
   9601  1.1  mrg     }
   9602  1.1  mrg }
   9603  1.1  mrg 
   9604  1.1  mrg /* Return an rtx for an integer representing the VMS Argument Information
   9605  1.1  mrg    register value.  */
   9606  1.1  mrg 
   9607  1.1  mrg rtx
   9608  1.1  mrg alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
   9609  1.1  mrg {
   9610  1.1  mrg   unsigned HOST_WIDE_INT regval = cum.num_args;
   9611  1.1  mrg   int i;
   9612  1.1  mrg 
   9613  1.1  mrg   for (i = 0; i < 6; i++)
   9614  1.1  mrg     regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
   9615  1.1  mrg 
   9616  1.1  mrg   return GEN_INT (regval);
   9617  1.1  mrg }
   9618  1.1  mrg 
   9619  1.1  mrg 
   9621  1.1  mrg /* Return a SYMBOL_REF representing the reference to the .linkage entry
   9622  1.1  mrg    of function FUNC built for calls made from CFUNDECL.  LFLAG is 1 if
   9623  1.1  mrg    this is the reference to the linkage pointer value, 0 if this is the
   9624  1.1  mrg    reference to the function entry value.  RFLAG is 1 if this a reduced
   9625  1.1  mrg    reference (code address only), 0 if this is a full reference.  */
   9626  1.1  mrg 
   9627  1.1  mrg rtx
   9628  1.1  mrg alpha_use_linkage (rtx func, bool lflag, bool rflag)
   9629  1.1  mrg {
   9630  1.1  mrg   struct alpha_links *al = NULL;
   9631  1.1  mrg   const char *name = XSTR (func, 0);
   9632  1.1  mrg 
   9633  1.1  mrg   if (cfun->machine->links)
   9634  1.1  mrg     {
   9635  1.1  mrg       /* Is this name already defined?  */
   9636  1.1  mrg       alpha_links **slot = cfun->machine->links->get (name);
   9637  1.1  mrg       if (slot)
   9638  1.1  mrg 	al = *slot;
   9639  1.1  mrg     }
   9640  1.1  mrg   else
   9641  1.1  mrg     cfun->machine->links
   9642  1.1  mrg       = hash_map<nofree_string_hash, alpha_links *>::create_ggc (64);
   9643  1.1  mrg 
   9644  1.1  mrg   if (al == NULL)
   9645  1.1  mrg     {
   9646  1.1  mrg       size_t buf_len;
   9647  1.1  mrg       char *linksym;
   9648  1.1  mrg       tree id;
   9649  1.1  mrg 
   9650  1.1  mrg       if (name[0] == '*')
   9651  1.1  mrg 	name++;
   9652  1.1  mrg 
   9653  1.1  mrg       /* Follow transparent alias, as this is used for CRTL translations.  */
   9654  1.1  mrg       id = maybe_get_identifier (name);
   9655  1.1  mrg       if (id)
   9656  1.1  mrg         {
   9657  1.1  mrg           while (IDENTIFIER_TRANSPARENT_ALIAS (id))
   9658  1.1  mrg             id = TREE_CHAIN (id);
   9659  1.1  mrg           name = IDENTIFIER_POINTER (id);
   9660  1.1  mrg         }
   9661  1.1  mrg 
   9662  1.1  mrg       buf_len = strlen (name) + 8 + 9;
   9663  1.1  mrg       linksym = (char *) alloca (buf_len);
   9664  1.1  mrg       snprintf (linksym, buf_len, "$%d..%s..lk", cfun->funcdef_no, name);
   9665  1.1  mrg 
   9666  1.1  mrg       al = ggc_alloc<alpha_links> ();
   9667  1.1  mrg       al->func = func;
   9668  1.1  mrg       al->linkage = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (linksym));
   9669  1.1  mrg 
   9670  1.1  mrg       cfun->machine->links->put (ggc_strdup (name), al);
   9671  1.1  mrg     }
   9672  1.1  mrg 
   9673  1.1  mrg   al->rkind = rflag ? KIND_CODEADDR : KIND_LINKAGE;
   9674  1.1  mrg 
   9675  1.1  mrg   if (lflag)
   9676  1.1  mrg     return gen_rtx_MEM (Pmode, plus_constant (Pmode, al->linkage, 8));
   9677  1.1  mrg   else
   9678  1.1  mrg     return al->linkage;
   9679  1.1  mrg }
   9680  1.1  mrg 
   9681  1.1  mrg static int
   9682  1.1  mrg alpha_write_one_linkage (const char *name, alpha_links *link, FILE *stream)
   9683  1.1  mrg {
   9684  1.1  mrg   ASM_OUTPUT_INTERNAL_LABEL (stream, XSTR (link->linkage, 0));
   9685  1.1  mrg   if (link->rkind == KIND_CODEADDR)
   9686  1.1  mrg     {
   9687  1.1  mrg       /* External and used, request code address.  */
   9688  1.1  mrg       fprintf (stream, "\t.code_address ");
   9689  1.1  mrg     }
   9690  1.1  mrg   else
   9691  1.1  mrg     {
   9692  1.1  mrg       if (!SYMBOL_REF_EXTERNAL_P (link->func)
   9693  1.1  mrg           && SYMBOL_REF_LOCAL_P (link->func))
   9694  1.1  mrg 	{
   9695  1.1  mrg 	  /* Locally defined, build linkage pair.  */
   9696  1.1  mrg 	  fprintf (stream, "\t.quad %s..en\n", name);
   9697  1.1  mrg 	  fprintf (stream, "\t.quad ");
   9698  1.1  mrg 	}
   9699  1.1  mrg       else
   9700  1.1  mrg 	{
   9701  1.1  mrg 	  /* External, request linkage pair.  */
   9702  1.1  mrg 	  fprintf (stream, "\t.linkage ");
   9703  1.1  mrg 	}
   9704  1.1  mrg     }
   9705  1.1  mrg   assemble_name (stream, name);
   9706  1.1  mrg   fputs ("\n", stream);
   9707  1.1  mrg 
   9708  1.1  mrg   return 0;
   9709  1.1  mrg }
   9710  1.1  mrg 
   9711  1.1  mrg static void
   9712  1.1  mrg alpha_write_linkage (FILE *stream, const char *funname)
   9713  1.1  mrg {
   9714  1.1  mrg   fprintf (stream, "\t.link\n");
   9715  1.1  mrg   fprintf (stream, "\t.align 3\n");
   9716  1.1  mrg   in_section = NULL;
   9717  1.1  mrg 
   9718  1.1  mrg #ifdef TARGET_VMS_CRASH_DEBUG
   9719  1.1  mrg   fputs ("\t.name ", stream);
   9720  1.1  mrg   assemble_name (stream, funname);
   9721  1.1  mrg   fputs ("..na\n", stream);
   9722  1.1  mrg #endif
   9723  1.1  mrg 
   9724  1.1  mrg   ASM_OUTPUT_LABEL (stream, funname);
   9725  1.1  mrg   fprintf (stream, "\t.pdesc ");
   9726  1.1  mrg   assemble_name (stream, funname);
   9727  1.1  mrg   fprintf (stream, "..en,%s\n",
   9728  1.1  mrg 	   alpha_procedure_type == PT_STACK ? "stack"
   9729  1.1  mrg 	   : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
   9730  1.1  mrg 
   9731  1.1  mrg   if (cfun->machine->links)
   9732  1.1  mrg     {
   9733  1.1  mrg       hash_map<nofree_string_hash, alpha_links *>::iterator iter
   9734  1.1  mrg 	= cfun->machine->links->begin ();
   9735  1.1  mrg       for (; iter != cfun->machine->links->end (); ++iter)
   9736  1.1  mrg 	alpha_write_one_linkage ((*iter).first, (*iter).second, stream);
   9737  1.1  mrg     }
   9738  1.1  mrg }
   9739  1.1  mrg 
   9740  1.1  mrg /* Switch to an arbitrary section NAME with attributes as specified
   9741  1.1  mrg    by FLAGS.  ALIGN specifies any known alignment requirements for
   9742  1.1  mrg    the section; 0 if the default should be used.  */
   9743  1.1  mrg 
   9744  1.1  mrg static void
   9745  1.1  mrg vms_asm_named_section (const char *name, unsigned int flags,
   9746  1.1  mrg 		       tree decl ATTRIBUTE_UNUSED)
   9747  1.1  mrg {
   9748  1.1  mrg   fputc ('\n', asm_out_file);
   9749  1.1  mrg   fprintf (asm_out_file, ".section\t%s", name);
   9750  1.1  mrg 
   9751  1.1  mrg   if (flags & SECTION_DEBUG)
   9752  1.1  mrg     fprintf (asm_out_file, ",NOWRT");
   9753  1.1  mrg 
   9754  1.1  mrg   fputc ('\n', asm_out_file);
   9755  1.1  mrg }
   9756  1.1  mrg 
   9757  1.1  mrg /* Record an element in the table of global constructors.  SYMBOL is
   9758  1.1  mrg    a SYMBOL_REF of the function to be called; PRIORITY is a number
   9759  1.1  mrg    between 0 and MAX_INIT_PRIORITY.
   9760  1.1  mrg 
   9761  1.1  mrg    Differs from default_ctors_section_asm_out_constructor in that the
   9762  1.1  mrg    width of the .ctors entry is always 64 bits, rather than the 32 bits
   9763  1.1  mrg    used by a normal pointer.  */
   9764  1.1  mrg 
   9765  1.1  mrg static void
   9766  1.1  mrg vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
   9767  1.1  mrg {
   9768  1.1  mrg   switch_to_section (ctors_section);
   9769  1.1  mrg   assemble_align (BITS_PER_WORD);
   9770  1.1  mrg   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
   9771  1.1  mrg }
   9772  1.1  mrg 
   9773  1.1  mrg static void
   9774  1.1  mrg vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
   9775  1.1  mrg {
   9776  1.1  mrg   switch_to_section (dtors_section);
   9777  1.1  mrg   assemble_align (BITS_PER_WORD);
   9778  1.1  mrg   assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
   9779  1.1  mrg }
   9780  1.1  mrg #else
   9781  1.1  mrg rtx
   9782  1.1  mrg alpha_use_linkage (rtx func ATTRIBUTE_UNUSED,
   9783  1.1  mrg 		   bool lflag ATTRIBUTE_UNUSED,
   9784  1.1  mrg 		   bool rflag ATTRIBUTE_UNUSED)
   9785  1.1  mrg {
   9786  1.1  mrg   return NULL_RTX;
   9787  1.1  mrg }
   9788  1.1  mrg 
   9789  1.1  mrg #endif /* TARGET_ABI_OPEN_VMS */
   9790  1.1  mrg 
   9791  1.1  mrg static void
   9793  1.1  mrg alpha_init_libfuncs (void)
   9794  1.1  mrg {
   9795  1.1  mrg   if (TARGET_ABI_OPEN_VMS)
   9796  1.1  mrg     {
   9797  1.1  mrg       /* Use the VMS runtime library functions for division and
   9798  1.1  mrg 	 remainder.  */
   9799  1.1  mrg       set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
   9800  1.1  mrg       set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
   9801  1.1  mrg       set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
   9802  1.1  mrg       set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
   9803  1.1  mrg       set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
   9804  1.1  mrg       set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
   9805  1.1  mrg       set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
   9806  1.1  mrg       set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
   9807  1.1  mrg #ifdef MEM_LIBFUNCS_INIT
   9808  1.1  mrg       MEM_LIBFUNCS_INIT;
   9809  1.1  mrg #endif
   9810  1.1  mrg     }
   9811  1.1  mrg }
   9812  1.1  mrg 
   9813  1.1  mrg /* On the Alpha, we use this to disable the floating-point registers
   9814  1.1  mrg    when they don't exist.  */
   9815  1.1  mrg 
   9816  1.1  mrg static void
   9817  1.1  mrg alpha_conditional_register_usage (void)
   9818  1.1  mrg {
   9819  1.1  mrg   int i;
   9820  1.1  mrg   if (! TARGET_FPREGS)
   9821  1.1  mrg     for (i = 32; i < 63; i++)
   9822  1.1  mrg       fixed_regs[i] = call_used_regs[i] = 1;
   9823  1.1  mrg }
   9824  1.1  mrg 
   9825  1.1  mrg /* Canonicalize a comparison from one we don't have to one we do have.  */
   9826  1.1  mrg 
   9827  1.1  mrg static void
   9828  1.1  mrg alpha_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
   9829  1.1  mrg 			       bool op0_preserve_value)
   9830  1.1  mrg {
   9831  1.1  mrg   if (!op0_preserve_value
   9832  1.1  mrg       && (*code == GE || *code == GT || *code == GEU || *code == GTU)
   9833  1.1  mrg       && (REG_P (*op1) || *op1 == const0_rtx))
   9834  1.1  mrg     {
   9835  1.1  mrg       std::swap (*op0, *op1);
   9836  1.1  mrg       *code = (int)swap_condition ((enum rtx_code)*code);
   9837  1.1  mrg     }
   9838  1.1  mrg 
   9839  1.1  mrg   if ((*code == LT || *code == LTU)
   9840  1.1  mrg       && CONST_INT_P (*op1) && INTVAL (*op1) == 256)
   9841  1.1  mrg     {
   9842  1.1  mrg       *code = *code == LT ? LE : LEU;
   9843  1.1  mrg       *op1 = GEN_INT (255);
   9844  1.1  mrg     }
   9845  1.1  mrg }
   9846  1.1  mrg 
   9847  1.1  mrg /* Implement TARGET_ATOMIC_ASSIGN_EXPAND_FENV.  */
   9848  1.1  mrg 
   9849  1.1  mrg static void
   9850  1.1  mrg alpha_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   9851  1.1  mrg {
   9852  1.1  mrg   const unsigned HOST_WIDE_INT SWCR_STATUS_MASK = (0x3fUL << 17);
   9853  1.1  mrg 
   9854  1.1  mrg   tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv;
   9855  1.1  mrg   tree new_fenv_var, reload_fenv, restore_fnenv;
   9856  1.1  mrg   tree update_call, atomic_feraiseexcept, hold_fnclex;
   9857  1.1  mrg 
   9858  1.1  mrg   /* Assume OSF/1 compatible interfaces.  */
   9859  1.1  mrg   if (!TARGET_ABI_OSF)
   9860  1.1  mrg     return;
   9861  1.1  mrg 
   9862  1.1  mrg   /* Generate the equivalent of :
   9863  1.1  mrg        unsigned long fenv_var;
   9864  1.1  mrg        fenv_var = __ieee_get_fp_control ();
   9865  1.1  mrg 
   9866  1.1  mrg        unsigned long masked_fenv;
   9867  1.1  mrg        masked_fenv = fenv_var & mask;
   9868  1.1  mrg 
   9869  1.1  mrg        __ieee_set_fp_control (masked_fenv);  */
   9870  1.1  mrg 
   9871  1.1  mrg   fenv_var = create_tmp_var_raw (long_unsigned_type_node);
   9872  1.1  mrg   get_fpscr
   9873  1.1  mrg     = build_fn_decl ("__ieee_get_fp_control",
   9874  1.1  mrg 		     build_function_type_list (long_unsigned_type_node, NULL));
   9875  1.1  mrg   set_fpscr
   9876  1.1  mrg     = build_fn_decl ("__ieee_set_fp_control",
   9877  1.1  mrg 		     build_function_type_list (void_type_node, NULL));
   9878  1.1  mrg   mask = build_int_cst (long_unsigned_type_node, ~SWCR_STATUS_MASK);
   9879  1.1  mrg   ld_fenv = build4 (TARGET_EXPR, long_unsigned_type_node, fenv_var,
   9880  1.1  mrg 		    build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE);
   9881  1.1  mrg   masked_fenv = build2 (BIT_AND_EXPR, long_unsigned_type_node, fenv_var, mask);
   9882  1.1  mrg   hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv);
   9883  1.1  mrg   *hold = build2 (COMPOUND_EXPR, void_type_node,
   9884  1.1  mrg 		  build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
   9885  1.1  mrg 		  hold_fnclex);
   9886  1.1  mrg 
   9887  1.1  mrg   /* Store the value of masked_fenv to clear the exceptions:
   9888  1.1  mrg      __ieee_set_fp_control (masked_fenv);  */
   9889  1.1  mrg 
   9890  1.1  mrg   *clear = build_call_expr (set_fpscr, 1, masked_fenv);
   9891  1.1  mrg 
   9892  1.1  mrg   /* Generate the equivalent of :
   9893  1.1  mrg        unsigned long new_fenv_var;
   9894  1.1  mrg        new_fenv_var = __ieee_get_fp_control ();
   9895  1.1  mrg 
   9896  1.1  mrg        __ieee_set_fp_control (fenv_var);
   9897  1.1  mrg 
   9898  1.1  mrg        __atomic_feraiseexcept (new_fenv_var);  */
   9899  1.1  mrg 
   9900  1.1  mrg   new_fenv_var = create_tmp_var_raw (long_unsigned_type_node);
   9901  1.1  mrg   reload_fenv = build4 (TARGET_EXPR, long_unsigned_type_node, new_fenv_var,
   9902  1.1  mrg 			build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE);
   9903  1.1  mrg   restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var);
   9904  1.1  mrg   atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
   9905  1.1  mrg   update_call
   9906  1.1  mrg     = build_call_expr (atomic_feraiseexcept, 1,
   9907  1.1  mrg 		       fold_convert (integer_type_node, new_fenv_var));
   9908  1.1  mrg   *update = build2 (COMPOUND_EXPR, void_type_node,
   9909  1.1  mrg 		    build2 (COMPOUND_EXPR, void_type_node,
   9910  1.1  mrg 			    reload_fenv, restore_fnenv), update_call);
   9911  1.1  mrg }
   9912  1.1  mrg 
   9913  1.1  mrg /* Implement TARGET_HARD_REGNO_MODE_OK.  On Alpha, the integer registers
   9914  1.1  mrg    can hold any mode.  The floating-point registers can hold 64-bit
   9915  1.1  mrg    integers as well, but not smaller values.  */
   9916  1.1  mrg 
   9917  1.1  mrg static bool
   9918  1.1  mrg alpha_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
   9919  1.1  mrg {
   9920  1.1  mrg   if (IN_RANGE (regno, 32, 62))
   9921  1.1  mrg     return (mode == SFmode
   9922  1.1  mrg 	    || mode == DFmode
   9923  1.1  mrg 	    || mode == DImode
   9924  1.1  mrg 	    || mode == SCmode
   9925  1.1  mrg 	    || mode == DCmode);
   9926  1.1  mrg   return true;
   9927  1.1  mrg }
   9928  1.1  mrg 
   9929  1.1  mrg /* Implement TARGET_MODES_TIEABLE_P.  This asymmetric test is true when
   9930  1.1  mrg    MODE1 could be put in an FP register but MODE2 could not.  */
   9931  1.1  mrg 
   9932  1.1  mrg static bool
   9933  1.1  mrg alpha_modes_tieable_p (machine_mode mode1, machine_mode mode2)
   9934  1.1  mrg {
   9935  1.1  mrg   return (alpha_hard_regno_mode_ok (32, mode1)
   9936  1.1  mrg 	  ? alpha_hard_regno_mode_ok (32, mode2)
   9937  1.1  mrg 	  : true);
   9938  1.1  mrg }
   9939  1.1  mrg 
   9940  1.1  mrg /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
   9941  1.1  mrg 
   9942  1.1  mrg static bool
   9943  1.1  mrg alpha_can_change_mode_class (machine_mode from, machine_mode to,
   9944  1.1  mrg 			     reg_class_t rclass)
   9945  1.1  mrg {
   9946  1.1  mrg   return (GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
   9947  1.1  mrg 	  || !reg_classes_intersect_p (FLOAT_REGS, rclass));
   9948  1.1  mrg }
   9949  1.1  mrg 
   9950  1.1  mrg /* Initialize the GCC target structure.  */
   9952  1.1  mrg #if TARGET_ABI_OPEN_VMS
   9953  1.1  mrg # undef TARGET_ATTRIBUTE_TABLE
   9954  1.1  mrg # define TARGET_ATTRIBUTE_TABLE vms_attribute_table
   9955  1.1  mrg # undef TARGET_CAN_ELIMINATE
   9956  1.1  mrg # define TARGET_CAN_ELIMINATE alpha_vms_can_eliminate
   9957  1.1  mrg #endif
   9958  1.1  mrg 
   9959  1.1  mrg #undef TARGET_IN_SMALL_DATA_P
   9960  1.1  mrg #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
   9961  1.1  mrg 
   9962  1.1  mrg #undef TARGET_ASM_ALIGNED_HI_OP
   9963  1.1  mrg #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
   9964  1.1  mrg #undef TARGET_ASM_ALIGNED_DI_OP
   9965  1.1  mrg #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
   9966  1.1  mrg 
   9967  1.1  mrg /* Default unaligned ops are provided for ELF systems.  To get unaligned
   9968  1.1  mrg    data for non-ELF systems, we have to turn off auto alignment.  */
   9969  1.1  mrg #if TARGET_ABI_OPEN_VMS
   9970  1.1  mrg #undef TARGET_ASM_UNALIGNED_HI_OP
   9971  1.1  mrg #define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
   9972  1.1  mrg #undef TARGET_ASM_UNALIGNED_SI_OP
   9973  1.1  mrg #define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
   9974  1.1  mrg #undef TARGET_ASM_UNALIGNED_DI_OP
   9975  1.1  mrg #define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
   9976  1.1  mrg #endif
   9977  1.1  mrg 
   9978  1.1  mrg #undef  TARGET_ASM_RELOC_RW_MASK
   9979  1.1  mrg #define TARGET_ASM_RELOC_RW_MASK  alpha_elf_reloc_rw_mask
   9980  1.1  mrg #undef	TARGET_ASM_SELECT_RTX_SECTION
   9981  1.1  mrg #define	TARGET_ASM_SELECT_RTX_SECTION  alpha_elf_select_rtx_section
   9982  1.1  mrg #undef  TARGET_SECTION_TYPE_FLAGS
   9983  1.1  mrg #define TARGET_SECTION_TYPE_FLAGS  alpha_elf_section_type_flags
   9984  1.1  mrg 
   9985  1.1  mrg #undef TARGET_ASM_FUNCTION_END_PROLOGUE
   9986  1.1  mrg #define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
   9987  1.1  mrg 
   9988  1.1  mrg #undef TARGET_INIT_LIBFUNCS
   9989  1.1  mrg #define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
   9990  1.1  mrg 
   9991  1.1  mrg #undef TARGET_LEGITIMIZE_ADDRESS
   9992  1.1  mrg #define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address
   9993  1.1  mrg #undef TARGET_MODE_DEPENDENT_ADDRESS_P
   9994  1.1  mrg #define TARGET_MODE_DEPENDENT_ADDRESS_P alpha_mode_dependent_address_p
   9995  1.1  mrg 
   9996  1.1  mrg #undef TARGET_ASM_FILE_START
   9997  1.1  mrg #define TARGET_ASM_FILE_START alpha_file_start
   9998  1.1  mrg 
   9999  1.1  mrg #undef TARGET_SCHED_ADJUST_COST
   10000  1.1  mrg #define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
   10001  1.1  mrg #undef TARGET_SCHED_ISSUE_RATE
   10002  1.1  mrg #define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
   10003  1.1  mrg #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
   10004  1.1  mrg #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
   10005  1.1  mrg   alpha_multipass_dfa_lookahead
   10006  1.1  mrg 
   10007  1.1  mrg #undef TARGET_HAVE_TLS
   10008  1.1  mrg #define TARGET_HAVE_TLS HAVE_AS_TLS
   10009  1.1  mrg 
   10010  1.1  mrg #undef  TARGET_BUILTIN_DECL
   10011  1.1  mrg #define TARGET_BUILTIN_DECL  alpha_builtin_decl
   10012  1.1  mrg #undef  TARGET_INIT_BUILTINS
   10013  1.1  mrg #define TARGET_INIT_BUILTINS alpha_init_builtins
   10014  1.1  mrg #undef  TARGET_EXPAND_BUILTIN
   10015  1.1  mrg #define TARGET_EXPAND_BUILTIN alpha_expand_builtin
   10016  1.1  mrg #undef  TARGET_FOLD_BUILTIN
   10017  1.1  mrg #define TARGET_FOLD_BUILTIN alpha_fold_builtin
   10018  1.1  mrg #undef  TARGET_GIMPLE_FOLD_BUILTIN
   10019  1.1  mrg #define TARGET_GIMPLE_FOLD_BUILTIN alpha_gimple_fold_builtin
   10020  1.1  mrg 
   10021  1.1  mrg #undef TARGET_FUNCTION_OK_FOR_SIBCALL
   10022  1.1  mrg #define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
   10023  1.1  mrg #undef TARGET_CANNOT_COPY_INSN_P
   10024  1.1  mrg #define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
   10025  1.1  mrg #undef TARGET_LEGITIMATE_CONSTANT_P
   10026  1.1  mrg #define TARGET_LEGITIMATE_CONSTANT_P alpha_legitimate_constant_p
   10027  1.1  mrg #undef TARGET_CANNOT_FORCE_CONST_MEM
   10028  1.1  mrg #define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
   10029  1.1  mrg 
   10030  1.1  mrg #if TARGET_ABI_OSF
   10031  1.1  mrg #undef TARGET_ASM_OUTPUT_MI_THUNK
   10032  1.1  mrg #define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
   10033  1.1  mrg #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
   10034  1.1  mrg #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
   10035  1.1  mrg #undef TARGET_STDARG_OPTIMIZE_HOOK
   10036  1.1  mrg #define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
   10037  1.1  mrg #endif
   10038  1.1  mrg 
   10039  1.1  mrg #undef TARGET_PRINT_OPERAND
   10040  1.1  mrg #define TARGET_PRINT_OPERAND alpha_print_operand
   10041  1.1  mrg #undef TARGET_PRINT_OPERAND_ADDRESS
   10042  1.1  mrg #define TARGET_PRINT_OPERAND_ADDRESS alpha_print_operand_address
   10043  1.1  mrg #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
   10044  1.1  mrg #define TARGET_PRINT_OPERAND_PUNCT_VALID_P alpha_print_operand_punct_valid_p
   10045  1.1  mrg 
   10046  1.1  mrg /* Use 16-bits anchor.  */
   10047  1.1  mrg #undef TARGET_MIN_ANCHOR_OFFSET
   10048  1.1  mrg #define TARGET_MIN_ANCHOR_OFFSET -0x7fff - 1
   10049  1.1  mrg #undef TARGET_MAX_ANCHOR_OFFSET
   10050  1.1  mrg #define TARGET_MAX_ANCHOR_OFFSET 0x7fff
   10051  1.1  mrg #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
   10052  1.1  mrg #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
   10053  1.1  mrg 
   10054  1.1  mrg #undef TARGET_REGISTER_MOVE_COST
   10055  1.1  mrg #define TARGET_REGISTER_MOVE_COST alpha_register_move_cost
   10056  1.1  mrg #undef TARGET_MEMORY_MOVE_COST
   10057  1.1  mrg #define TARGET_MEMORY_MOVE_COST alpha_memory_move_cost
   10058  1.1  mrg #undef TARGET_RTX_COSTS
   10059  1.1  mrg #define TARGET_RTX_COSTS alpha_rtx_costs
   10060  1.1  mrg #undef TARGET_ADDRESS_COST
   10061  1.1  mrg #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
   10062  1.1  mrg 
   10063  1.1  mrg #undef TARGET_MACHINE_DEPENDENT_REORG
   10064  1.1  mrg #define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
   10065  1.1  mrg 
   10066  1.1  mrg #undef TARGET_PROMOTE_FUNCTION_MODE
   10067  1.1  mrg #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
   10068  1.1  mrg #undef TARGET_PROMOTE_PROTOTYPES
   10069  1.1  mrg #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
   10070  1.1  mrg 
   10071  1.1  mrg #undef TARGET_FUNCTION_VALUE
   10072  1.1  mrg #define TARGET_FUNCTION_VALUE alpha_function_value
   10073  1.1  mrg #undef TARGET_LIBCALL_VALUE
   10074  1.1  mrg #define TARGET_LIBCALL_VALUE alpha_libcall_value
   10075  1.1  mrg #undef TARGET_FUNCTION_VALUE_REGNO_P
   10076  1.1  mrg #define TARGET_FUNCTION_VALUE_REGNO_P alpha_function_value_regno_p
   10077  1.1  mrg #undef TARGET_RETURN_IN_MEMORY
   10078  1.1  mrg #define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
   10079  1.1  mrg #undef TARGET_PASS_BY_REFERENCE
   10080  1.1  mrg #define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
   10081  1.1  mrg #undef TARGET_SETUP_INCOMING_VARARGS
   10082  1.1  mrg #define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
   10083  1.1  mrg #undef TARGET_STRICT_ARGUMENT_NAMING
   10084  1.1  mrg #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
   10085  1.1  mrg #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
   10086  1.1  mrg #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
   10087  1.1  mrg #undef TARGET_SPLIT_COMPLEX_ARG
   10088  1.1  mrg #define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
   10089  1.1  mrg #undef TARGET_GIMPLIFY_VA_ARG_EXPR
   10090  1.1  mrg #define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
   10091  1.1  mrg #undef TARGET_ARG_PARTIAL_BYTES
   10092  1.1  mrg #define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
   10093  1.1  mrg #undef TARGET_FUNCTION_ARG
   10094  1.1  mrg #define TARGET_FUNCTION_ARG alpha_function_arg
   10095  1.1  mrg #undef TARGET_FUNCTION_ARG_ADVANCE
   10096  1.1  mrg #define TARGET_FUNCTION_ARG_ADVANCE alpha_function_arg_advance
   10097  1.1  mrg #undef TARGET_TRAMPOLINE_INIT
   10098  1.1  mrg #define TARGET_TRAMPOLINE_INIT alpha_trampoline_init
   10099  1.1  mrg 
   10100  1.1  mrg #undef TARGET_INSTANTIATE_DECLS
   10101  1.1  mrg #define TARGET_INSTANTIATE_DECLS alpha_instantiate_decls
   10102  1.1  mrg 
   10103  1.1  mrg #undef TARGET_SECONDARY_RELOAD
   10104  1.1  mrg #define TARGET_SECONDARY_RELOAD alpha_secondary_reload
   10105  1.1  mrg #undef TARGET_SECONDARY_MEMORY_NEEDED
   10106  1.1  mrg #define TARGET_SECONDARY_MEMORY_NEEDED alpha_secondary_memory_needed
   10107  1.1  mrg #undef TARGET_SECONDARY_MEMORY_NEEDED_MODE
   10108  1.1  mrg #define TARGET_SECONDARY_MEMORY_NEEDED_MODE alpha_secondary_memory_needed_mode
   10109  1.1  mrg 
   10110  1.1  mrg #undef TARGET_SCALAR_MODE_SUPPORTED_P
   10111  1.1  mrg #define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
   10112  1.1  mrg #undef TARGET_VECTOR_MODE_SUPPORTED_P
   10113  1.1  mrg #define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
   10114  1.1  mrg 
   10115  1.1  mrg #undef TARGET_BUILD_BUILTIN_VA_LIST
   10116  1.1  mrg #define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
   10117  1.1  mrg 
   10118  1.1  mrg #undef TARGET_EXPAND_BUILTIN_VA_START
   10119  1.1  mrg #define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
   10120  1.1  mrg 
   10121  1.1  mrg #undef TARGET_OPTION_OVERRIDE
   10122  1.1  mrg #define TARGET_OPTION_OVERRIDE alpha_option_override
   10123  1.1  mrg 
   10124  1.1  mrg #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
   10125  1.1  mrg #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE \
   10126  1.1  mrg   alpha_override_options_after_change
   10127  1.1  mrg 
   10128  1.1  mrg #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
   10129  1.1  mrg #undef TARGET_MANGLE_TYPE
   10130  1.1  mrg #define TARGET_MANGLE_TYPE alpha_mangle_type
   10131  1.1  mrg #endif
   10132  1.1  mrg 
   10133           #undef TARGET_LRA_P
   10134           #define TARGET_LRA_P hook_bool_void_false
   10135           
   10136           #undef TARGET_LEGITIMATE_ADDRESS_P
   10137           #define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p
   10138           
   10139           #undef TARGET_CONDITIONAL_REGISTER_USAGE
   10140           #define TARGET_CONDITIONAL_REGISTER_USAGE alpha_conditional_register_usage
   10141           
   10142           #undef TARGET_CANONICALIZE_COMPARISON
   10143           #define TARGET_CANONICALIZE_COMPARISON alpha_canonicalize_comparison
   10144           
   10145           #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
   10146           #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV alpha_atomic_assign_expand_fenv
   10147           
   10148           #undef TARGET_HARD_REGNO_MODE_OK
   10149           #define TARGET_HARD_REGNO_MODE_OK alpha_hard_regno_mode_ok
   10150           
   10151           #undef TARGET_MODES_TIEABLE_P
   10152           #define TARGET_MODES_TIEABLE_P alpha_modes_tieable_p
   10153           
   10154           #undef TARGET_CAN_CHANGE_MODE_CLASS
   10155           #define TARGET_CAN_CHANGE_MODE_CLASS alpha_can_change_mode_class
   10156           
   10157           struct gcc_target targetm = TARGET_INITIALIZER;
   10158           
   10159           
   10160           #include "gt-alpha.h"
   10162