OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [alpha/] [alpha.c] - Blame information for rev 378

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.