OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

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

Go to most recent revision | 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
 
5949
  base = build_decl (BUILTINS_LOCATION,
5950
                     FIELD_DECL, get_identifier ("__base"),
5951
                     ptr_type_node);
5952
  DECL_FIELD_CONTEXT (base) = record;
5953
  TREE_CHAIN (base) = ofs;
5954
 
5955
  TYPE_FIELDS (record) = base;
5956
  layout_type (record);
5957
 
5958
  va_list_gpr_counter_field = ofs;
5959
  return record;
5960
}
5961
 
5962
#if TARGET_ABI_OSF
5963
/* Helper function for alpha_stdarg_optimize_hook.  Skip over casts
5964
   and constant additions.  */
5965
 
5966
static gimple
5967
va_list_skip_additions (tree lhs)
5968
{
5969
  gimple stmt;
5970
 
5971
  for (;;)
5972
    {
5973
      enum tree_code code;
5974
 
5975
      stmt = SSA_NAME_DEF_STMT (lhs);
5976
 
5977
      if (gimple_code (stmt) == GIMPLE_PHI)
5978
        return stmt;
5979
 
5980
      if (!is_gimple_assign (stmt)
5981
          || gimple_assign_lhs (stmt) != lhs)
5982
        return NULL;
5983
 
5984
      if (TREE_CODE (gimple_assign_rhs1 (stmt)) != SSA_NAME)
5985
        return stmt;
5986
      code = gimple_assign_rhs_code (stmt);
5987
      if (!CONVERT_EXPR_CODE_P (code)
5988
          && ((code != PLUS_EXPR && code != POINTER_PLUS_EXPR)
5989
              || TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST
5990
              || !host_integerp (gimple_assign_rhs2 (stmt), 1)))
5991
        return stmt;
5992
 
5993
      lhs = gimple_assign_rhs1 (stmt);
5994
    }
5995
}
5996
 
5997
/* Check if LHS = RHS statement is
5998
   LHS = *(ap.__base + ap.__offset + cst)
5999
   or
6000
   LHS = *(ap.__base
6001
           + ((ap.__offset + cst <= 47)
6002
              ? ap.__offset + cst - 48 : ap.__offset + cst) + cst2).
6003
   If the former, indicate that GPR registers are needed,
6004
   if the latter, indicate that FPR registers are needed.
6005
 
6006
   Also look for LHS = (*ptr).field, where ptr is one of the forms
6007
   listed above.
6008
 
6009
   On alpha, cfun->va_list_gpr_size is used as size of the needed
6010
   regs and cfun->va_list_fpr_size is a bitmask, bit 0 set if GPR
6011
   registers are needed and bit 1 set if FPR registers are needed.
6012
   Return true if va_list references should not be scanned for the
6013
   current statement.  */
6014
 
6015
static bool
6016
alpha_stdarg_optimize_hook (struct stdarg_info *si, const_gimple stmt)
6017
{
6018
  tree base, offset, rhs;
6019
  int offset_arg = 1;
6020
  gimple base_stmt;
6021
 
6022
  if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
6023
      != GIMPLE_SINGLE_RHS)
6024
    return false;
6025
 
6026
  rhs = gimple_assign_rhs1 (stmt);
6027
  while (handled_component_p (rhs))
6028
    rhs = TREE_OPERAND (rhs, 0);
6029
  if (TREE_CODE (rhs) != INDIRECT_REF
6030
      || TREE_CODE (TREE_OPERAND (rhs, 0)) != SSA_NAME)
6031
    return false;
6032
 
6033
  stmt = va_list_skip_additions (TREE_OPERAND (rhs, 0));
6034
  if (stmt == NULL
6035
      || !is_gimple_assign (stmt)
6036
      || gimple_assign_rhs_code (stmt) != POINTER_PLUS_EXPR)
6037
    return false;
6038
 
6039
  base = gimple_assign_rhs1 (stmt);
6040
  if (TREE_CODE (base) == SSA_NAME)
6041
    {
6042
      base_stmt = va_list_skip_additions (base);
6043
      if (base_stmt
6044
          && is_gimple_assign (base_stmt)
6045
          && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
6046
        base = gimple_assign_rhs1 (base_stmt);
6047
    }
6048
 
6049
  if (TREE_CODE (base) != COMPONENT_REF
6050
      || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
6051
    {
6052
      base = gimple_assign_rhs2 (stmt);
6053
      if (TREE_CODE (base) == SSA_NAME)
6054
        {
6055
          base_stmt = va_list_skip_additions (base);
6056
          if (base_stmt
6057
              && is_gimple_assign (base_stmt)
6058
              && gimple_assign_rhs_code (base_stmt) == COMPONENT_REF)
6059
            base = gimple_assign_rhs1 (base_stmt);
6060
        }
6061
 
6062
      if (TREE_CODE (base) != COMPONENT_REF
6063
          || TREE_OPERAND (base, 1) != TYPE_FIELDS (va_list_type_node))
6064
        return false;
6065
 
6066
      offset_arg = 0;
6067
    }
6068
 
6069
  base = get_base_address (base);
6070
  if (TREE_CODE (base) != VAR_DECL
6071
      || !bitmap_bit_p (si->va_list_vars, DECL_UID (base)))
6072
    return false;
6073
 
6074
  offset = gimple_op (stmt, 1 + offset_arg);
6075
  if (TREE_CODE (offset) == SSA_NAME)
6076
    {
6077
      gimple offset_stmt = va_list_skip_additions (offset);
6078
 
6079
      if (offset_stmt
6080
          && gimple_code (offset_stmt) == GIMPLE_PHI)
6081
        {
6082
          HOST_WIDE_INT sub;
6083
          gimple arg1_stmt, arg2_stmt;
6084
          tree arg1, arg2;
6085
          enum tree_code code1, code2;
6086
 
6087
          if (gimple_phi_num_args (offset_stmt) != 2)
6088
            goto escapes;
6089
 
6090
          arg1_stmt
6091
            = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 0));
6092
          arg2_stmt
6093
            = va_list_skip_additions (gimple_phi_arg_def (offset_stmt, 1));
6094
          if (arg1_stmt == NULL
6095
              || !is_gimple_assign (arg1_stmt)
6096
              || arg2_stmt == NULL
6097
              || !is_gimple_assign (arg2_stmt))
6098
            goto escapes;
6099
 
6100
          code1 = gimple_assign_rhs_code (arg1_stmt);
6101
          code2 = gimple_assign_rhs_code (arg2_stmt);
6102
          if (code1 == COMPONENT_REF
6103
              && (code2 == MINUS_EXPR || code2 == PLUS_EXPR))
6104
            /* Do nothing.  */;
6105
          else if (code2 == COMPONENT_REF
6106
                   && (code1 == MINUS_EXPR || code1 == PLUS_EXPR))
6107
            {
6108
              gimple tem = arg1_stmt;
6109
              code2 = code1;
6110
              arg1_stmt = arg2_stmt;
6111
              arg2_stmt = tem;
6112
            }
6113
          else
6114
            goto escapes;
6115
 
6116
          if (!host_integerp (gimple_assign_rhs2 (arg2_stmt), 0))
6117
            goto escapes;
6118
 
6119
          sub = tree_low_cst (gimple_assign_rhs2 (arg2_stmt), 0);
6120
          if (code2 == MINUS_EXPR)
6121
            sub = -sub;
6122
          if (sub < -48 || sub > -32)
6123
            goto escapes;
6124
 
6125
          arg1 = gimple_assign_rhs1 (arg1_stmt);
6126
          arg2 = gimple_assign_rhs1 (arg2_stmt);
6127
          if (TREE_CODE (arg2) == SSA_NAME)
6128
            {
6129
              arg2_stmt = va_list_skip_additions (arg2);
6130
              if (arg2_stmt == NULL
6131
                  || !is_gimple_assign (arg2_stmt)
6132
                  || gimple_assign_rhs_code (arg2_stmt) != COMPONENT_REF)
6133
                goto escapes;
6134
              arg2 = gimple_assign_rhs1 (arg2_stmt);
6135
            }
6136
          if (arg1 != arg2)
6137
            goto escapes;
6138
 
6139
          if (TREE_CODE (arg1) != COMPONENT_REF
6140
              || TREE_OPERAND (arg1, 1) != va_list_gpr_counter_field
6141
              || get_base_address (arg1) != base)
6142
            goto escapes;
6143
 
6144
          /* Need floating point regs.  */
6145
          cfun->va_list_fpr_size |= 2;
6146
          return false;
6147
        }
6148
      if (offset_stmt
6149
          && is_gimple_assign (offset_stmt)
6150
          && gimple_assign_rhs_code (offset_stmt) == COMPONENT_REF)
6151
        offset = gimple_assign_rhs1 (offset_stmt);
6152
    }
6153
  if (TREE_CODE (offset) != COMPONENT_REF
6154
      || TREE_OPERAND (offset, 1) != va_list_gpr_counter_field
6155
      || get_base_address (offset) != base)
6156
    goto escapes;
6157
  else
6158
    /* Need general regs.  */
6159
    cfun->va_list_fpr_size |= 1;
6160
  return false;
6161
 
6162
escapes:
6163
  si->va_list_escapes = true;
6164
  return false;
6165
}
6166
#endif
6167
 
6168
/* Perform any needed actions needed for a function that is receiving a
6169
   variable number of arguments.  */
6170
 
6171
static void
6172
alpha_setup_incoming_varargs (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
6173
                              tree type, int *pretend_size, int no_rtl)
6174
{
6175
  CUMULATIVE_ARGS cum = *pcum;
6176
 
6177
  /* Skip the current argument.  */
6178
  FUNCTION_ARG_ADVANCE (cum, mode, type, 1);
6179
 
6180
#if TARGET_ABI_UNICOSMK
6181
  /* On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
6182
     arguments on the stack. Unfortunately, it doesn't always store the first
6183
     one (i.e. the one that arrives in $16 or $f16). This is not a problem
6184
     with stdargs as we always have at least one named argument there.  */
6185
  if (cum.num_reg_words < 6)
6186
    {
6187
      if (!no_rtl)
6188
        {
6189
          emit_insn (gen_umk_mismatch_args (GEN_INT (cum.num_reg_words)));
6190
          emit_insn (gen_arg_home_umk ());
6191
        }
6192
      *pretend_size = 0;
6193
    }
6194
#elif TARGET_ABI_OPEN_VMS
6195
  /* For VMS, we allocate space for all 6 arg registers plus a count.
6196
 
6197
     However, if NO registers need to be saved, don't allocate any space.
6198
     This is not only because we won't need the space, but because AP
6199
     includes the current_pretend_args_size and we don't want to mess up
6200
     any ap-relative addresses already made.  */
6201
  if (cum.num_args < 6)
6202
    {
6203
      if (!no_rtl)
6204
        {
6205
          emit_move_insn (gen_rtx_REG (DImode, 1), virtual_incoming_args_rtx);
6206
          emit_insn (gen_arg_home ());
6207
        }
6208
      *pretend_size = 7 * UNITS_PER_WORD;
6209
    }
6210
#else
6211
  /* On OSF/1 and friends, we allocate space for all 12 arg registers, but
6212
     only push those that are remaining.  However, if NO registers need to
6213
     be saved, don't allocate any space.  This is not only because we won't
6214
     need the space, but because AP includes the current_pretend_args_size
6215
     and we don't want to mess up any ap-relative addresses already made.
6216
 
6217
     If we are not to use the floating-point registers, save the integer
6218
     registers where we would put the floating-point registers.  This is
6219
     not the most efficient way to implement varargs with just one register
6220
     class, but it isn't worth doing anything more efficient in this rare
6221
     case.  */
6222
  if (cum >= 6)
6223
    return;
6224
 
6225
  if (!no_rtl)
6226
    {
6227
      int count;
6228
      alias_set_type set = get_varargs_alias_set ();
6229
      rtx tmp;
6230
 
6231
      count = cfun->va_list_gpr_size / UNITS_PER_WORD;
6232
      if (count > 6 - cum)
6233
        count = 6 - cum;
6234
 
6235
      /* Detect whether integer registers or floating-point registers
6236
         are needed by the detected va_arg statements.  See above for
6237
         how these values are computed.  Note that the "escape" value
6238
         is VA_LIST_MAX_FPR_SIZE, which is 255, which has both of
6239
         these bits set.  */
6240
      gcc_assert ((VA_LIST_MAX_FPR_SIZE & 3) == 3);
6241
 
6242
      if (cfun->va_list_fpr_size & 1)
6243
        {
6244
          tmp = gen_rtx_MEM (BLKmode,
6245
                             plus_constant (virtual_incoming_args_rtx,
6246
                                            (cum + 6) * UNITS_PER_WORD));
6247
          MEM_NOTRAP_P (tmp) = 1;
6248
          set_mem_alias_set (tmp, set);
6249
          move_block_from_reg (16 + cum, tmp, count);
6250
        }
6251
 
6252
      if (cfun->va_list_fpr_size & 2)
6253
        {
6254
          tmp = gen_rtx_MEM (BLKmode,
6255
                             plus_constant (virtual_incoming_args_rtx,
6256
                                            cum * UNITS_PER_WORD));
6257
          MEM_NOTRAP_P (tmp) = 1;
6258
          set_mem_alias_set (tmp, set);
6259
          move_block_from_reg (16 + cum + TARGET_FPREGS*32, tmp, count);
6260
        }
6261
     }
6262
  *pretend_size = 12 * UNITS_PER_WORD;
6263
#endif
6264
}
6265
 
6266
static void
6267
alpha_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
6268
{
6269
  HOST_WIDE_INT offset;
6270
  tree t, offset_field, base_field;
6271
 
6272
  if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
6273
    return;
6274
 
6275
  if (TARGET_ABI_UNICOSMK)
6276
    std_expand_builtin_va_start (valist, nextarg);
6277
 
6278
  /* For Unix, TARGET_SETUP_INCOMING_VARARGS moves the starting address base
6279
     up by 48, storing fp arg registers in the first 48 bytes, and the
6280
     integer arg registers in the next 48 bytes.  This is only done,
6281
     however, if any integer registers need to be stored.
6282
 
6283
     If no integer registers need be stored, then we must subtract 48
6284
     in order to account for the integer arg registers which are counted
6285
     in argsize above, but which are not actually stored on the stack.
6286
     Must further be careful here about structures straddling the last
6287
     integer argument register; that futzes with pretend_args_size,
6288
     which changes the meaning of AP.  */
6289
 
6290
  if (NUM_ARGS < 6)
6291
    offset = TARGET_ABI_OPEN_VMS ? UNITS_PER_WORD : 6 * UNITS_PER_WORD;
6292
  else
6293
    offset = -6 * UNITS_PER_WORD + crtl->args.pretend_args_size;
6294
 
6295
  if (TARGET_ABI_OPEN_VMS)
6296
    {
6297
      t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
6298
      t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
6299
                 size_int (offset + NUM_ARGS * UNITS_PER_WORD));
6300
      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
6301
      TREE_SIDE_EFFECTS (t) = 1;
6302
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6303
    }
6304
  else
6305
    {
6306
      base_field = TYPE_FIELDS (TREE_TYPE (valist));
6307
      offset_field = TREE_CHAIN (base_field);
6308
 
6309
      base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
6310
                           valist, base_field, NULL_TREE);
6311
      offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
6312
                             valist, offset_field, NULL_TREE);
6313
 
6314
      t = make_tree (ptr_type_node, virtual_incoming_args_rtx);
6315
      t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t,
6316
                  size_int (offset));
6317
      t = build2 (MODIFY_EXPR, TREE_TYPE (base_field), base_field, t);
6318
      TREE_SIDE_EFFECTS (t) = 1;
6319
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6320
 
6321
      t = build_int_cst (NULL_TREE, NUM_ARGS * UNITS_PER_WORD);
6322
      t = build2 (MODIFY_EXPR, TREE_TYPE (offset_field), offset_field, t);
6323
      TREE_SIDE_EFFECTS (t) = 1;
6324
      expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6325
    }
6326
}
6327
 
6328
static tree
6329
alpha_gimplify_va_arg_1 (tree type, tree base, tree offset,
6330
                         gimple_seq *pre_p)
6331
{
6332
  tree type_size, ptr_type, addend, t, addr;
6333
  gimple_seq internal_post;
6334
 
6335
  /* If the type could not be passed in registers, skip the block
6336
     reserved for the registers.  */
6337
  if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
6338
    {
6339
      t = build_int_cst (TREE_TYPE (offset), 6*8);
6340
      gimplify_assign (offset,
6341
                       build2 (MAX_EXPR, TREE_TYPE (offset), offset, t),
6342
                       pre_p);
6343
    }
6344
 
6345
  addend = offset;
6346
  ptr_type = build_pointer_type_for_mode (type, ptr_mode, true);
6347
 
6348
  if (TREE_CODE (type) == COMPLEX_TYPE)
6349
    {
6350
      tree real_part, imag_part, real_temp;
6351
 
6352
      real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
6353
                                           offset, pre_p);
6354
 
6355
      /* Copy the value into a new temporary, lest the formal temporary
6356
         be reused out from under us.  */
6357
      real_temp = get_initialized_tmp_var (real_part, pre_p, NULL);
6358
 
6359
      imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base,
6360
                                           offset, pre_p);
6361
 
6362
      return build2 (COMPLEX_EXPR, type, real_temp, imag_part);
6363
    }
6364
  else if (TREE_CODE (type) == REAL_TYPE)
6365
    {
6366
      tree fpaddend, cond, fourtyeight;
6367
 
6368
      fourtyeight = build_int_cst (TREE_TYPE (addend), 6*8);
6369
      fpaddend = fold_build2 (MINUS_EXPR, TREE_TYPE (addend),
6370
                              addend, fourtyeight);
6371
      cond = fold_build2 (LT_EXPR, boolean_type_node, addend, fourtyeight);
6372
      addend = fold_build3 (COND_EXPR, TREE_TYPE (addend), cond,
6373
                            fpaddend, addend);
6374
    }
6375
 
6376
  /* Build the final address and force that value into a temporary.  */
6377
  addr = build2 (POINTER_PLUS_EXPR, ptr_type, fold_convert (ptr_type, base),
6378
                 fold_convert (sizetype, addend));
6379
  internal_post = NULL;
6380
  gimplify_expr (&addr, pre_p, &internal_post, is_gimple_val, fb_rvalue);
6381
  gimple_seq_add_seq (pre_p, internal_post);
6382
 
6383
  /* Update the offset field.  */
6384
  type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type));
6385
  if (type_size == NULL || TREE_OVERFLOW (type_size))
6386
    t = size_zero_node;
6387
  else
6388
    {
6389
      t = size_binop (PLUS_EXPR, type_size, size_int (7));
6390
      t = size_binop (TRUNC_DIV_EXPR, t, size_int (8));
6391
      t = size_binop (MULT_EXPR, t, size_int (8));
6392
    }
6393
  t = fold_convert (TREE_TYPE (offset), t);
6394
  gimplify_assign (offset, build2 (PLUS_EXPR, TREE_TYPE (offset), offset, t),
6395
                   pre_p);
6396
 
6397
  return build_va_arg_indirect_ref (addr);
6398
}
6399
 
6400
static tree
6401
alpha_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
6402
                       gimple_seq *post_p)
6403
{
6404
  tree offset_field, base_field, offset, base, t, r;
6405
  bool indirect;
6406
 
6407
  if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK)
6408
    return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
6409
 
6410
  base_field = TYPE_FIELDS (va_list_type_node);
6411
  offset_field = TREE_CHAIN (base_field);
6412
  base_field = build3 (COMPONENT_REF, TREE_TYPE (base_field),
6413
                       valist, base_field, NULL_TREE);
6414
  offset_field = build3 (COMPONENT_REF, TREE_TYPE (offset_field),
6415
                         valist, offset_field, NULL_TREE);
6416
 
6417
  /* Pull the fields of the structure out into temporaries.  Since we never
6418
     modify the base field, we can use a formal temporary.  Sign-extend the
6419
     offset field so that it's the proper width for pointer arithmetic.  */
6420
  base = get_formal_tmp_var (base_field, pre_p);
6421
 
6422
  t = fold_convert (lang_hooks.types.type_for_size (64, 0), offset_field);
6423
  offset = get_initialized_tmp_var (t, pre_p, NULL);
6424
 
6425
  indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
6426
  if (indirect)
6427
    type = build_pointer_type_for_mode (type, ptr_mode, true);
6428
 
6429
  /* Find the value.  Note that this will be a stable indirection, or
6430
     a composite of stable indirections in the case of complex.  */
6431
  r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p);
6432
 
6433
  /* Stuff the offset temporary back into its field.  */
6434
  gimplify_assign (unshare_expr (offset_field),
6435
                   fold_convert (TREE_TYPE (offset_field), offset), pre_p);
6436
 
6437
  if (indirect)
6438
    r = build_va_arg_indirect_ref (r);
6439
 
6440
  return r;
6441
}
6442
 
6443
/* Builtins.  */
6444
 
6445
enum alpha_builtin
6446
{
6447
  ALPHA_BUILTIN_CMPBGE,
6448
  ALPHA_BUILTIN_EXTBL,
6449
  ALPHA_BUILTIN_EXTWL,
6450
  ALPHA_BUILTIN_EXTLL,
6451
  ALPHA_BUILTIN_EXTQL,
6452
  ALPHA_BUILTIN_EXTWH,
6453
  ALPHA_BUILTIN_EXTLH,
6454
  ALPHA_BUILTIN_EXTQH,
6455
  ALPHA_BUILTIN_INSBL,
6456
  ALPHA_BUILTIN_INSWL,
6457
  ALPHA_BUILTIN_INSLL,
6458
  ALPHA_BUILTIN_INSQL,
6459
  ALPHA_BUILTIN_INSWH,
6460
  ALPHA_BUILTIN_INSLH,
6461
  ALPHA_BUILTIN_INSQH,
6462
  ALPHA_BUILTIN_MSKBL,
6463
  ALPHA_BUILTIN_MSKWL,
6464
  ALPHA_BUILTIN_MSKLL,
6465
  ALPHA_BUILTIN_MSKQL,
6466
  ALPHA_BUILTIN_MSKWH,
6467
  ALPHA_BUILTIN_MSKLH,
6468
  ALPHA_BUILTIN_MSKQH,
6469
  ALPHA_BUILTIN_UMULH,
6470
  ALPHA_BUILTIN_ZAP,
6471
  ALPHA_BUILTIN_ZAPNOT,
6472
  ALPHA_BUILTIN_AMASK,
6473
  ALPHA_BUILTIN_IMPLVER,
6474
  ALPHA_BUILTIN_RPCC,
6475
  ALPHA_BUILTIN_THREAD_POINTER,
6476
  ALPHA_BUILTIN_SET_THREAD_POINTER,
6477
  ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
6478
  ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,
6479
 
6480
  /* TARGET_MAX */
6481
  ALPHA_BUILTIN_MINUB8,
6482
  ALPHA_BUILTIN_MINSB8,
6483
  ALPHA_BUILTIN_MINUW4,
6484
  ALPHA_BUILTIN_MINSW4,
6485
  ALPHA_BUILTIN_MAXUB8,
6486
  ALPHA_BUILTIN_MAXSB8,
6487
  ALPHA_BUILTIN_MAXUW4,
6488
  ALPHA_BUILTIN_MAXSW4,
6489
  ALPHA_BUILTIN_PERR,
6490
  ALPHA_BUILTIN_PKLB,
6491
  ALPHA_BUILTIN_PKWB,
6492
  ALPHA_BUILTIN_UNPKBL,
6493
  ALPHA_BUILTIN_UNPKBW,
6494
 
6495
  /* TARGET_CIX */
6496
  ALPHA_BUILTIN_CTTZ,
6497
  ALPHA_BUILTIN_CTLZ,
6498
  ALPHA_BUILTIN_CTPOP,
6499
 
6500
  ALPHA_BUILTIN_max
6501
};
6502
 
6503
static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
6504
  CODE_FOR_builtin_cmpbge,
6505
  CODE_FOR_builtin_extbl,
6506
  CODE_FOR_builtin_extwl,
6507
  CODE_FOR_builtin_extll,
6508
  CODE_FOR_builtin_extql,
6509
  CODE_FOR_builtin_extwh,
6510
  CODE_FOR_builtin_extlh,
6511
  CODE_FOR_builtin_extqh,
6512
  CODE_FOR_builtin_insbl,
6513
  CODE_FOR_builtin_inswl,
6514
  CODE_FOR_builtin_insll,
6515
  CODE_FOR_builtin_insql,
6516
  CODE_FOR_builtin_inswh,
6517
  CODE_FOR_builtin_inslh,
6518
  CODE_FOR_builtin_insqh,
6519
  CODE_FOR_builtin_mskbl,
6520
  CODE_FOR_builtin_mskwl,
6521
  CODE_FOR_builtin_mskll,
6522
  CODE_FOR_builtin_mskql,
6523
  CODE_FOR_builtin_mskwh,
6524
  CODE_FOR_builtin_msklh,
6525
  CODE_FOR_builtin_mskqh,
6526
  CODE_FOR_umuldi3_highpart,
6527
  CODE_FOR_builtin_zap,
6528
  CODE_FOR_builtin_zapnot,
6529
  CODE_FOR_builtin_amask,
6530
  CODE_FOR_builtin_implver,
6531
  CODE_FOR_builtin_rpcc,
6532
  CODE_FOR_load_tp,
6533
  CODE_FOR_set_tp,
6534
  CODE_FOR_builtin_establish_vms_condition_handler,
6535
  CODE_FOR_builtin_revert_vms_condition_handler,
6536
 
6537
  /* TARGET_MAX */
6538
  CODE_FOR_builtin_minub8,
6539
  CODE_FOR_builtin_minsb8,
6540
  CODE_FOR_builtin_minuw4,
6541
  CODE_FOR_builtin_minsw4,
6542
  CODE_FOR_builtin_maxub8,
6543
  CODE_FOR_builtin_maxsb8,
6544
  CODE_FOR_builtin_maxuw4,
6545
  CODE_FOR_builtin_maxsw4,
6546
  CODE_FOR_builtin_perr,
6547
  CODE_FOR_builtin_pklb,
6548
  CODE_FOR_builtin_pkwb,
6549
  CODE_FOR_builtin_unpkbl,
6550
  CODE_FOR_builtin_unpkbw,
6551
 
6552
  /* TARGET_CIX */
6553
  CODE_FOR_ctzdi2,
6554
  CODE_FOR_clzdi2,
6555
  CODE_FOR_popcountdi2
6556
};
6557
 
6558
struct alpha_builtin_def
6559
{
6560
  const char *name;
6561
  enum alpha_builtin code;
6562
  unsigned int target_mask;
6563
  bool is_const;
6564
};
6565
 
6566
static struct alpha_builtin_def const zero_arg_builtins[] = {
6567
  { "__builtin_alpha_implver",  ALPHA_BUILTIN_IMPLVER,  0, true },
6568
  { "__builtin_alpha_rpcc",     ALPHA_BUILTIN_RPCC,     0, false }
6569
};
6570
 
6571
static struct alpha_builtin_def const one_arg_builtins[] = {
6572
  { "__builtin_alpha_amask",    ALPHA_BUILTIN_AMASK,    0, true },
6573
  { "__builtin_alpha_pklb",     ALPHA_BUILTIN_PKLB,     MASK_MAX, true },
6574
  { "__builtin_alpha_pkwb",     ALPHA_BUILTIN_PKWB,     MASK_MAX, true },
6575
  { "__builtin_alpha_unpkbl",   ALPHA_BUILTIN_UNPKBL,   MASK_MAX, true },
6576
  { "__builtin_alpha_unpkbw",   ALPHA_BUILTIN_UNPKBW,   MASK_MAX, true },
6577
  { "__builtin_alpha_cttz",     ALPHA_BUILTIN_CTTZ,     MASK_CIX, true },
6578
  { "__builtin_alpha_ctlz",     ALPHA_BUILTIN_CTLZ,     MASK_CIX, true },
6579
  { "__builtin_alpha_ctpop",    ALPHA_BUILTIN_CTPOP,    MASK_CIX, true }
6580
};
6581
 
6582
static struct alpha_builtin_def const two_arg_builtins[] = {
6583
  { "__builtin_alpha_cmpbge",   ALPHA_BUILTIN_CMPBGE,   0, true },
6584
  { "__builtin_alpha_extbl",    ALPHA_BUILTIN_EXTBL,    0, true },
6585
  { "__builtin_alpha_extwl",    ALPHA_BUILTIN_EXTWL,    0, true },
6586
  { "__builtin_alpha_extll",    ALPHA_BUILTIN_EXTLL,    0, true },
6587
  { "__builtin_alpha_extql",    ALPHA_BUILTIN_EXTQL,    0, true },
6588
  { "__builtin_alpha_extwh",    ALPHA_BUILTIN_EXTWH,    0, true },
6589
  { "__builtin_alpha_extlh",    ALPHA_BUILTIN_EXTLH,    0, true },
6590
  { "__builtin_alpha_extqh",    ALPHA_BUILTIN_EXTQH,    0, true },
6591
  { "__builtin_alpha_insbl",    ALPHA_BUILTIN_INSBL,    0, true },
6592
  { "__builtin_alpha_inswl",    ALPHA_BUILTIN_INSWL,    0, true },
6593
  { "__builtin_alpha_insll",    ALPHA_BUILTIN_INSLL,    0, true },
6594
  { "__builtin_alpha_insql",    ALPHA_BUILTIN_INSQL,    0, true },
6595
  { "__builtin_alpha_inswh",    ALPHA_BUILTIN_INSWH,    0, true },
6596
  { "__builtin_alpha_inslh",    ALPHA_BUILTIN_INSLH,    0, true },
6597
  { "__builtin_alpha_insqh",    ALPHA_BUILTIN_INSQH,    0, true },
6598
  { "__builtin_alpha_mskbl",    ALPHA_BUILTIN_MSKBL,    0, true },
6599
  { "__builtin_alpha_mskwl",    ALPHA_BUILTIN_MSKWL,    0, true },
6600
  { "__builtin_alpha_mskll",    ALPHA_BUILTIN_MSKLL,    0, true },
6601
  { "__builtin_alpha_mskql",    ALPHA_BUILTIN_MSKQL,    0, true },
6602
  { "__builtin_alpha_mskwh",    ALPHA_BUILTIN_MSKWH,    0, true },
6603
  { "__builtin_alpha_msklh",    ALPHA_BUILTIN_MSKLH,    0, true },
6604
  { "__builtin_alpha_mskqh",    ALPHA_BUILTIN_MSKQH,    0, true },
6605
  { "__builtin_alpha_umulh",    ALPHA_BUILTIN_UMULH,    0, true },
6606
  { "__builtin_alpha_zap",      ALPHA_BUILTIN_ZAP,      0, true },
6607
  { "__builtin_alpha_zapnot",   ALPHA_BUILTIN_ZAPNOT,   0, true },
6608
  { "__builtin_alpha_minub8",   ALPHA_BUILTIN_MINUB8,   MASK_MAX, true },
6609
  { "__builtin_alpha_minsb8",   ALPHA_BUILTIN_MINSB8,   MASK_MAX, true },
6610
  { "__builtin_alpha_minuw4",   ALPHA_BUILTIN_MINUW4,   MASK_MAX, true },
6611
  { "__builtin_alpha_minsw4",   ALPHA_BUILTIN_MINSW4,   MASK_MAX, true },
6612
  { "__builtin_alpha_maxub8",   ALPHA_BUILTIN_MAXUB8,   MASK_MAX, true },
6613
  { "__builtin_alpha_maxsb8",   ALPHA_BUILTIN_MAXSB8,   MASK_MAX, true },
6614
  { "__builtin_alpha_maxuw4",   ALPHA_BUILTIN_MAXUW4,   MASK_MAX, true },
6615
  { "__builtin_alpha_maxsw4",   ALPHA_BUILTIN_MAXSW4,   MASK_MAX, true },
6616
  { "__builtin_alpha_perr",     ALPHA_BUILTIN_PERR,     MASK_MAX, true }
6617
};
6618
 
6619
static GTY(()) tree alpha_v8qi_u;
6620
static GTY(()) tree alpha_v8qi_s;
6621
static GTY(()) tree alpha_v4hi_u;
6622
static GTY(()) tree alpha_v4hi_s;
6623
 
6624
/* Helper function of alpha_init_builtins.  Add the COUNT built-in
6625
   functions pointed to by P, with function type FTYPE.  */
6626
 
6627
static void
6628
alpha_add_builtins (const struct alpha_builtin_def *p, size_t count,
6629
                    tree ftype)
6630
{
6631
  tree decl;
6632
  size_t i;
6633
 
6634
  for (i = 0; i < count; ++i, ++p)
6635
    if ((target_flags & p->target_mask) == p->target_mask)
6636
      {
6637
        decl = add_builtin_function (p->name, ftype, p->code, BUILT_IN_MD,
6638
                                     NULL, NULL);
6639
        if (p->is_const)
6640
          TREE_READONLY (decl) = 1;
6641
        TREE_NOTHROW (decl) = 1;
6642
      }
6643
}
6644
 
6645
 
6646
static void
6647
alpha_init_builtins (void)
6648
{
6649
  tree dimode_integer_type_node;
6650
  tree ftype, decl;
6651
 
6652
  dimode_integer_type_node = lang_hooks.types.type_for_mode (DImode, 0);
6653
 
6654
  /* Fwrite on VMS is non-standard.  */
6655
#if TARGET_ABI_OPEN_VMS
6656
  implicit_built_in_decls[(int) BUILT_IN_FWRITE] = NULL_TREE;
6657
  implicit_built_in_decls[(int) BUILT_IN_FWRITE_UNLOCKED] = NULL_TREE;
6658
#endif
6659
 
6660
  ftype = build_function_type (dimode_integer_type_node, void_list_node);
6661
  alpha_add_builtins (zero_arg_builtins, ARRAY_SIZE (zero_arg_builtins),
6662
                      ftype);
6663
 
6664
  ftype = build_function_type_list (dimode_integer_type_node,
6665
                                    dimode_integer_type_node, NULL_TREE);
6666
  alpha_add_builtins (one_arg_builtins, ARRAY_SIZE (one_arg_builtins),
6667
                      ftype);
6668
 
6669
  ftype = build_function_type_list (dimode_integer_type_node,
6670
                                    dimode_integer_type_node,
6671
                                    dimode_integer_type_node, NULL_TREE);
6672
  alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins),
6673
                      ftype);
6674
 
6675
  ftype = build_function_type (ptr_type_node, void_list_node);
6676
  decl = add_builtin_function ("__builtin_thread_pointer", ftype,
6677
                               ALPHA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
6678
                               NULL, NULL);
6679
  TREE_NOTHROW (decl) = 1;
6680
 
6681
  ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
6682
  decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
6683
                               ALPHA_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
6684
                               NULL, NULL);
6685
  TREE_NOTHROW (decl) = 1;
6686
 
6687
  if (TARGET_ABI_OPEN_VMS)
6688
    {
6689
      ftype = build_function_type_list (ptr_type_node, ptr_type_node,
6690
                                        NULL_TREE);
6691
      add_builtin_function ("__builtin_establish_vms_condition_handler", ftype,
6692
                            ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
6693
                            BUILT_IN_MD, NULL, NULL_TREE);
6694
 
6695
      ftype = build_function_type_list (ptr_type_node, void_type_node,
6696
                                        NULL_TREE);
6697
      add_builtin_function ("__builtin_revert_vms_condition_handler", ftype,
6698
                            ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,
6699
                             BUILT_IN_MD, NULL, NULL_TREE);
6700
    }
6701
 
6702
  alpha_v8qi_u = build_vector_type (unsigned_intQI_type_node, 8);
6703
  alpha_v8qi_s = build_vector_type (intQI_type_node, 8);
6704
  alpha_v4hi_u = build_vector_type (unsigned_intHI_type_node, 4);
6705
  alpha_v4hi_s = build_vector_type (intHI_type_node, 4);
6706
}
6707
 
6708
/* Expand an expression EXP that calls a built-in function,
6709
   with result going to TARGET if that's convenient
6710
   (and in mode MODE if that's convenient).
6711
   SUBTARGET may be used as the target for computing one of EXP's operands.
6712
   IGNORE is nonzero if the value is to be ignored.  */
6713
 
6714
static rtx
6715
alpha_expand_builtin (tree exp, rtx target,
6716
                      rtx subtarget ATTRIBUTE_UNUSED,
6717
                      enum machine_mode mode ATTRIBUTE_UNUSED,
6718
                      int ignore ATTRIBUTE_UNUSED)
6719
{
6720
#define MAX_ARGS 2
6721
 
6722
  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6723
  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
6724
  tree arg;
6725
  call_expr_arg_iterator iter;
6726
  enum insn_code icode;
6727
  rtx op[MAX_ARGS], pat;
6728
  int arity;
6729
  bool nonvoid;
6730
 
6731
  if (fcode >= ALPHA_BUILTIN_max)
6732
    internal_error ("bad builtin fcode");
6733
  icode = code_for_builtin[fcode];
6734
  if (icode == 0)
6735
    internal_error ("bad builtin fcode");
6736
 
6737
  nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6738
 
6739
  arity = 0;
6740
  FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
6741
    {
6742
      const struct insn_operand_data *insn_op;
6743
 
6744
      if (arg == error_mark_node)
6745
        return NULL_RTX;
6746
      if (arity > MAX_ARGS)
6747
        return NULL_RTX;
6748
 
6749
      insn_op = &insn_data[icode].operand[arity + nonvoid];
6750
 
6751
      op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
6752
 
6753
      if (!(*insn_op->predicate) (op[arity], insn_op->mode))
6754
        op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
6755
      arity++;
6756
    }
6757
 
6758
  if (nonvoid)
6759
    {
6760
      enum machine_mode tmode = insn_data[icode].operand[0].mode;
6761
      if (!target
6762
          || GET_MODE (target) != tmode
6763
          || !(*insn_data[icode].operand[0].predicate) (target, tmode))
6764
        target = gen_reg_rtx (tmode);
6765
    }
6766
 
6767
  switch (arity)
6768
    {
6769
    case 0:
6770
      pat = GEN_FCN (icode) (target);
6771
      break;
6772
    case 1:
6773
      if (nonvoid)
6774
        pat = GEN_FCN (icode) (target, op[0]);
6775
      else
6776
        pat = GEN_FCN (icode) (op[0]);
6777
      break;
6778
    case 2:
6779
      pat = GEN_FCN (icode) (target, op[0], op[1]);
6780
      break;
6781
    default:
6782
      gcc_unreachable ();
6783
    }
6784
  if (!pat)
6785
    return NULL_RTX;
6786
  emit_insn (pat);
6787
 
6788
  if (nonvoid)
6789
    return target;
6790
  else
6791
    return const0_rtx;
6792
}
6793
 
6794
 
6795
/* Several bits below assume HWI >= 64 bits.  This should be enforced
6796
   by config.gcc.  */
6797
#if HOST_BITS_PER_WIDE_INT < 64
6798
# error "HOST_WIDE_INT too small"
6799
#endif
6800
 
6801
/* Fold the builtin for the CMPBGE instruction.  This is a vector comparison
6802
   with an 8-bit output vector.  OPINT contains the integer operands; bit N
6803
   of OP_CONST is set if OPINT[N] is valid.  */
6804
 
6805
static tree
6806
alpha_fold_builtin_cmpbge (unsigned HOST_WIDE_INT opint[], long op_const)
6807
{
6808
  if (op_const == 3)
6809
    {
6810
      int i, val;
6811
      for (i = 0, val = 0; i < 8; ++i)
6812
        {
6813
          unsigned HOST_WIDE_INT c0 = (opint[0] >> (i * 8)) & 0xff;
6814
          unsigned HOST_WIDE_INT c1 = (opint[1] >> (i * 8)) & 0xff;
6815
          if (c0 >= c1)
6816
            val |= 1 << i;
6817
        }
6818
      return build_int_cst (long_integer_type_node, val);
6819
    }
6820
  else if (op_const == 2 && opint[1] == 0)
6821
    return build_int_cst (long_integer_type_node, 0xff);
6822
  return NULL;
6823
}
6824
 
6825
/* Fold the builtin for the ZAPNOT instruction.  This is essentially a
6826
   specialized form of an AND operation.  Other byte manipulation instructions
6827
   are defined in terms of this instruction, so this is also used as a
6828
   subroutine for other builtins.
6829
 
6830
   OP contains the tree operands; OPINT contains the extracted integer values.
6831
   Bit N of OP_CONST it set if OPINT[N] is valid.  OP may be null if only
6832
   OPINT may be considered.  */
6833
 
6834
static tree
6835
alpha_fold_builtin_zapnot (tree *op, unsigned HOST_WIDE_INT opint[],
6836
                           long op_const)
6837
{
6838
  if (op_const & 2)
6839
    {
6840
      unsigned HOST_WIDE_INT mask = 0;
6841
      int i;
6842
 
6843
      for (i = 0; i < 8; ++i)
6844
        if ((opint[1] >> i) & 1)
6845
          mask |= (unsigned HOST_WIDE_INT)0xff << (i * 8);
6846
 
6847
      if (op_const & 1)
6848
        return build_int_cst (long_integer_type_node, opint[0] & mask);
6849
 
6850
      if (op)
6851
        return fold_build2 (BIT_AND_EXPR, long_integer_type_node, op[0],
6852
                            build_int_cst (long_integer_type_node, mask));
6853
    }
6854
  else if ((op_const & 1) && opint[0] == 0)
6855
    return build_int_cst (long_integer_type_node, 0);
6856
  return NULL;
6857
}
6858
 
6859
/* Fold the builtins for the EXT family of instructions.  */
6860
 
6861
static tree
6862
alpha_fold_builtin_extxx (tree op[], unsigned HOST_WIDE_INT opint[],
6863
                          long op_const, unsigned HOST_WIDE_INT bytemask,
6864
                          bool is_high)
6865
{
6866
  long zap_const = 2;
6867
  tree *zap_op = NULL;
6868
 
6869
  if (op_const & 2)
6870
    {
6871
      unsigned HOST_WIDE_INT loc;
6872
 
6873
      loc = opint[1] & 7;
6874
      if (BYTES_BIG_ENDIAN)
6875
        loc ^= 7;
6876
      loc *= 8;
6877
 
6878
      if (loc != 0)
6879
        {
6880
          if (op_const & 1)
6881
            {
6882
              unsigned HOST_WIDE_INT temp = opint[0];
6883
              if (is_high)
6884
                temp <<= loc;
6885
              else
6886
                temp >>= loc;
6887
              opint[0] = temp;
6888
              zap_const = 3;
6889
            }
6890
        }
6891
      else
6892
        zap_op = op;
6893
    }
6894
 
6895
  opint[1] = bytemask;
6896
  return alpha_fold_builtin_zapnot (zap_op, opint, zap_const);
6897
}
6898
 
6899
/* Fold the builtins for the INS family of instructions.  */
6900
 
6901
static tree
6902
alpha_fold_builtin_insxx (tree op[], unsigned HOST_WIDE_INT opint[],
6903
                          long op_const, unsigned HOST_WIDE_INT bytemask,
6904
                          bool is_high)
6905
{
6906
  if ((op_const & 1) && opint[0] == 0)
6907
    return build_int_cst (long_integer_type_node, 0);
6908
 
6909
  if (op_const & 2)
6910
    {
6911
      unsigned HOST_WIDE_INT temp, loc, byteloc;
6912
      tree *zap_op = NULL;
6913
 
6914
      loc = opint[1] & 7;
6915
      if (BYTES_BIG_ENDIAN)
6916
        loc ^= 7;
6917
      bytemask <<= loc;
6918
 
6919
      temp = opint[0];
6920
      if (is_high)
6921
        {
6922
          byteloc = (64 - (loc * 8)) & 0x3f;
6923
          if (byteloc == 0)
6924
            zap_op = op;
6925
          else
6926
            temp >>= byteloc;
6927
          bytemask >>= 8;
6928
        }
6929
      else
6930
        {
6931
          byteloc = loc * 8;
6932
          if (byteloc == 0)
6933
            zap_op = op;
6934
          else
6935
            temp <<= byteloc;
6936
        }
6937
 
6938
      opint[0] = temp;
6939
      opint[1] = bytemask;
6940
      return alpha_fold_builtin_zapnot (zap_op, opint, op_const);
6941
    }
6942
 
6943
  return NULL;
6944
}
6945
 
6946
static tree
6947
alpha_fold_builtin_mskxx (tree op[], unsigned HOST_WIDE_INT opint[],
6948
                          long op_const, unsigned HOST_WIDE_INT bytemask,
6949
                          bool is_high)
6950
{
6951
  if (op_const & 2)
6952
    {
6953
      unsigned HOST_WIDE_INT loc;
6954
 
6955
      loc = opint[1] & 7;
6956
      if (BYTES_BIG_ENDIAN)
6957
        loc ^= 7;
6958
      bytemask <<= loc;
6959
 
6960
      if (is_high)
6961
        bytemask >>= 8;
6962
 
6963
      opint[1] = bytemask ^ 0xff;
6964
    }
6965
 
6966
  return alpha_fold_builtin_zapnot (op, opint, op_const);
6967
}
6968
 
6969
static tree
6970
alpha_fold_builtin_umulh (unsigned HOST_WIDE_INT opint[], long op_const)
6971
{
6972
  switch (op_const)
6973
    {
6974
    case 3:
6975
      {
6976
        unsigned HOST_WIDE_INT l;
6977
        HOST_WIDE_INT h;
6978
 
6979
        mul_double (opint[0], 0, opint[1], 0, &l, &h);
6980
 
6981
#if HOST_BITS_PER_WIDE_INT > 64
6982
# error fixme
6983
#endif
6984
 
6985
        return build_int_cst (long_integer_type_node, h);
6986
      }
6987
 
6988
    case 1:
6989
      opint[1] = opint[0];
6990
      /* FALLTHRU */
6991
    case 2:
6992
      /* Note that (X*1) >> 64 == 0.  */
6993
      if (opint[1] == 0 || opint[1] == 1)
6994
        return build_int_cst (long_integer_type_node, 0);
6995
      break;
6996
    }
6997
  return NULL;
6998
}
6999
 
7000
static tree
7001
alpha_fold_vector_minmax (enum tree_code code, tree op[], tree vtype)
7002
{
7003
  tree op0 = fold_convert (vtype, op[0]);
7004
  tree op1 = fold_convert (vtype, op[1]);
7005
  tree val = fold_build2 (code, vtype, op0, op1);
7006
  return fold_build1 (VIEW_CONVERT_EXPR, long_integer_type_node, val);
7007
}
7008
 
7009
static tree
7010
alpha_fold_builtin_perr (unsigned HOST_WIDE_INT opint[], long op_const)
7011
{
7012
  unsigned HOST_WIDE_INT temp = 0;
7013
  int i;
7014
 
7015
  if (op_const != 3)
7016
    return NULL;
7017
 
7018
  for (i = 0; i < 8; ++i)
7019
    {
7020
      unsigned HOST_WIDE_INT a = (opint[0] >> (i * 8)) & 0xff;
7021
      unsigned HOST_WIDE_INT b = (opint[1] >> (i * 8)) & 0xff;
7022
      if (a >= b)
7023
        temp += a - b;
7024
      else
7025
        temp += b - a;
7026
    }
7027
 
7028
  return build_int_cst (long_integer_type_node, temp);
7029
}
7030
 
7031
static tree
7032
alpha_fold_builtin_pklb (unsigned HOST_WIDE_INT opint[], long op_const)
7033
{
7034
  unsigned HOST_WIDE_INT temp;
7035
 
7036
  if (op_const == 0)
7037
    return NULL;
7038
 
7039
  temp = opint[0] & 0xff;
7040
  temp |= (opint[0] >> 24) & 0xff00;
7041
 
7042
  return build_int_cst (long_integer_type_node, temp);
7043
}
7044
 
7045
static tree
7046
alpha_fold_builtin_pkwb (unsigned HOST_WIDE_INT opint[], long op_const)
7047
{
7048
  unsigned HOST_WIDE_INT temp;
7049
 
7050
  if (op_const == 0)
7051
    return NULL;
7052
 
7053
  temp = opint[0] & 0xff;
7054
  temp |= (opint[0] >>  8) & 0xff00;
7055
  temp |= (opint[0] >> 16) & 0xff0000;
7056
  temp |= (opint[0] >> 24) & 0xff000000;
7057
 
7058
  return build_int_cst (long_integer_type_node, temp);
7059
}
7060
 
7061
static tree
7062
alpha_fold_builtin_unpkbl (unsigned HOST_WIDE_INT opint[], long op_const)
7063
{
7064
  unsigned HOST_WIDE_INT temp;
7065
 
7066
  if (op_const == 0)
7067
    return NULL;
7068
 
7069
  temp = opint[0] & 0xff;
7070
  temp |= (opint[0] & 0xff00) << 24;
7071
 
7072
  return build_int_cst (long_integer_type_node, temp);
7073
}
7074
 
7075
static tree
7076
alpha_fold_builtin_unpkbw (unsigned HOST_WIDE_INT opint[], long op_const)
7077
{
7078
  unsigned HOST_WIDE_INT temp;
7079
 
7080
  if (op_const == 0)
7081
    return NULL;
7082
 
7083
  temp = opint[0] & 0xff;
7084
  temp |= (opint[0] & 0x0000ff00) << 8;
7085
  temp |= (opint[0] & 0x00ff0000) << 16;
7086
  temp |= (opint[0] & 0xff000000) << 24;
7087
 
7088
  return build_int_cst (long_integer_type_node, temp);
7089
}
7090
 
7091
static tree
7092
alpha_fold_builtin_cttz (unsigned HOST_WIDE_INT opint[], long op_const)
7093
{
7094
  unsigned HOST_WIDE_INT temp;
7095
 
7096
  if (op_const == 0)
7097
    return NULL;
7098
 
7099
  if (opint[0] == 0)
7100
    temp = 64;
7101
  else
7102
    temp = exact_log2 (opint[0] & -opint[0]);
7103
 
7104
  return build_int_cst (long_integer_type_node, temp);
7105
}
7106
 
7107
static tree
7108
alpha_fold_builtin_ctlz (unsigned HOST_WIDE_INT opint[], long op_const)
7109
{
7110
  unsigned HOST_WIDE_INT temp;
7111
 
7112
  if (op_const == 0)
7113
    return NULL;
7114
 
7115
  if (opint[0] == 0)
7116
    temp = 64;
7117
  else
7118
    temp = 64 - floor_log2 (opint[0]) - 1;
7119
 
7120
  return build_int_cst (long_integer_type_node, temp);
7121
}
7122
 
7123
static tree
7124
alpha_fold_builtin_ctpop (unsigned HOST_WIDE_INT opint[], long op_const)
7125
{
7126
  unsigned HOST_WIDE_INT temp, op;
7127
 
7128
  if (op_const == 0)
7129
    return NULL;
7130
 
7131
  op = opint[0];
7132
  temp = 0;
7133
  while (op)
7134
    temp++, op &= op - 1;
7135
 
7136
  return build_int_cst (long_integer_type_node, temp);
7137
}
7138
 
7139
/* Fold one of our builtin functions.  */
7140
 
7141
static tree
7142
alpha_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
7143
{
7144
  tree op[MAX_ARGS], t;
7145
  unsigned HOST_WIDE_INT opint[MAX_ARGS];
7146
  long op_const = 0, arity = 0;
7147
 
7148
  for (t = arglist; t ; t = TREE_CHAIN (t), ++arity)
7149
    {
7150
      tree arg = TREE_VALUE (t);
7151
      if (arg == error_mark_node)
7152
        return NULL;
7153
      if (arity >= MAX_ARGS)
7154
        return NULL;
7155
 
7156
      op[arity] = arg;
7157
      opint[arity] = 0;
7158
      if (TREE_CODE (arg) == INTEGER_CST)
7159
        {
7160
          op_const |= 1L << arity;
7161
          opint[arity] = int_cst_value (arg);
7162
        }
7163
    }
7164
 
7165
  switch (DECL_FUNCTION_CODE (fndecl))
7166
    {
7167
    case ALPHA_BUILTIN_CMPBGE:
7168
      return alpha_fold_builtin_cmpbge (opint, op_const);
7169
 
7170
    case ALPHA_BUILTIN_EXTBL:
7171
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x01, false);
7172
    case ALPHA_BUILTIN_EXTWL:
7173
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, false);
7174
    case ALPHA_BUILTIN_EXTLL:
7175
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, false);
7176
    case ALPHA_BUILTIN_EXTQL:
7177
      return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, false);
7178
    case ALPHA_BUILTIN_EXTWH:
7179
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x03, true);
7180
    case ALPHA_BUILTIN_EXTLH:
7181
      return alpha_fold_builtin_extxx (op, opint, op_const, 0x0f, true);
7182
    case ALPHA_BUILTIN_EXTQH:
7183
      return alpha_fold_builtin_extxx (op, opint, op_const, 0xff, true);
7184
 
7185
    case ALPHA_BUILTIN_INSBL:
7186
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x01, false);
7187
    case ALPHA_BUILTIN_INSWL:
7188
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, false);
7189
    case ALPHA_BUILTIN_INSLL:
7190
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, false);
7191
    case ALPHA_BUILTIN_INSQL:
7192
      return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, false);
7193
    case ALPHA_BUILTIN_INSWH:
7194
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x03, true);
7195
    case ALPHA_BUILTIN_INSLH:
7196
      return alpha_fold_builtin_insxx (op, opint, op_const, 0x0f, true);
7197
    case ALPHA_BUILTIN_INSQH:
7198
      return alpha_fold_builtin_insxx (op, opint, op_const, 0xff, true);
7199
 
7200
    case ALPHA_BUILTIN_MSKBL:
7201
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x01, false);
7202
    case ALPHA_BUILTIN_MSKWL:
7203
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, false);
7204
    case ALPHA_BUILTIN_MSKLL:
7205
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, false);
7206
    case ALPHA_BUILTIN_MSKQL:
7207
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, false);
7208
    case ALPHA_BUILTIN_MSKWH:
7209
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x03, true);
7210
    case ALPHA_BUILTIN_MSKLH:
7211
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0x0f, true);
7212
    case ALPHA_BUILTIN_MSKQH:
7213
      return alpha_fold_builtin_mskxx (op, opint, op_const, 0xff, true);
7214
 
7215
    case ALPHA_BUILTIN_UMULH:
7216
      return alpha_fold_builtin_umulh (opint, op_const);
7217
 
7218
    case ALPHA_BUILTIN_ZAP:
7219
      opint[1] ^= 0xff;
7220
      /* FALLTHRU */
7221
    case ALPHA_BUILTIN_ZAPNOT:
7222
      return alpha_fold_builtin_zapnot (op, opint, op_const);
7223
 
7224
    case ALPHA_BUILTIN_MINUB8:
7225
      return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_u);
7226
    case ALPHA_BUILTIN_MINSB8:
7227
      return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v8qi_s);
7228
    case ALPHA_BUILTIN_MINUW4:
7229
      return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_u);
7230
    case ALPHA_BUILTIN_MINSW4:
7231
      return alpha_fold_vector_minmax (MIN_EXPR, op, alpha_v4hi_s);
7232
    case ALPHA_BUILTIN_MAXUB8:
7233
      return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_u);
7234
    case ALPHA_BUILTIN_MAXSB8:
7235
      return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v8qi_s);
7236
    case ALPHA_BUILTIN_MAXUW4:
7237
      return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_u);
7238
    case ALPHA_BUILTIN_MAXSW4:
7239
      return alpha_fold_vector_minmax (MAX_EXPR, op, alpha_v4hi_s);
7240
 
7241
    case ALPHA_BUILTIN_PERR:
7242
      return alpha_fold_builtin_perr (opint, op_const);
7243
    case ALPHA_BUILTIN_PKLB:
7244
      return alpha_fold_builtin_pklb (opint, op_const);
7245
    case ALPHA_BUILTIN_PKWB:
7246
      return alpha_fold_builtin_pkwb (opint, op_const);
7247
    case ALPHA_BUILTIN_UNPKBL:
7248
      return alpha_fold_builtin_unpkbl (opint, op_const);
7249
    case ALPHA_BUILTIN_UNPKBW:
7250
      return alpha_fold_builtin_unpkbw (opint, op_const);
7251
 
7252
    case ALPHA_BUILTIN_CTTZ:
7253
      return alpha_fold_builtin_cttz (opint, op_const);
7254
    case ALPHA_BUILTIN_CTLZ:
7255
      return alpha_fold_builtin_ctlz (opint, op_const);
7256
    case ALPHA_BUILTIN_CTPOP:
7257
      return alpha_fold_builtin_ctpop (opint, op_const);
7258
 
7259
    case ALPHA_BUILTIN_AMASK:
7260
    case ALPHA_BUILTIN_IMPLVER:
7261
    case ALPHA_BUILTIN_RPCC:
7262
    case ALPHA_BUILTIN_THREAD_POINTER:
7263
    case ALPHA_BUILTIN_SET_THREAD_POINTER:
7264
      /* None of these are foldable at compile-time.  */
7265
    default:
7266
      return NULL;
7267
    }
7268
}
7269
 
7270
/* This page contains routines that are used to determine what the function
7271
   prologue and epilogue code will do and write them out.  */
7272
 
7273
/* Compute the size of the save area in the stack.  */
7274
 
7275
/* These variables are used for communication between the following functions.
7276
   They indicate various things about the current function being compiled
7277
   that are used to tell what kind of prologue, epilogue and procedure
7278
   descriptor to generate.  */
7279
 
7280
/* Nonzero if we need a stack procedure.  */
7281
enum alpha_procedure_types {PT_NULL = 0, PT_REGISTER = 1, PT_STACK = 2};
7282
static enum alpha_procedure_types alpha_procedure_type;
7283
 
7284
/* Register number (either FP or SP) that is used to unwind the frame.  */
7285
static int vms_unwind_regno;
7286
 
7287
/* Register number used to save FP.  We need not have one for RA since
7288
   we don't modify it for register procedures.  This is only defined
7289
   for register frame procedures.  */
7290
static int vms_save_fp_regno;
7291
 
7292
/* Register number used to reference objects off our PV.  */
7293
static int vms_base_regno;
7294
 
7295
/* Compute register masks for saved registers.  */
7296
 
7297
static void
7298
alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP)
7299
{
7300
  unsigned long imask = 0;
7301
  unsigned long fmask = 0;
7302
  unsigned int i;
7303
 
7304
  /* When outputting a thunk, we don't have valid register life info,
7305
     but assemble_start_function wants to output .frame and .mask
7306
     directives.  */
7307
  if (cfun->is_thunk)
7308
    {
7309
      *imaskP = 0;
7310
      *fmaskP = 0;
7311
      return;
7312
    }
7313
 
7314
  if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7315
    imask |= (1UL << HARD_FRAME_POINTER_REGNUM);
7316
 
7317
  /* One for every register we have to save.  */
7318
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7319
    if (! fixed_regs[i] && ! call_used_regs[i]
7320
        && df_regs_ever_live_p (i) && i != REG_RA
7321
        && (!TARGET_ABI_UNICOSMK || i != HARD_FRAME_POINTER_REGNUM))
7322
      {
7323
        if (i < 32)
7324
          imask |= (1UL << i);
7325
        else
7326
          fmask |= (1UL << (i - 32));
7327
      }
7328
 
7329
  /* We need to restore these for the handler.  */
7330
  if (crtl->calls_eh_return)
7331
    {
7332
      for (i = 0; ; ++i)
7333
        {
7334
          unsigned regno = EH_RETURN_DATA_REGNO (i);
7335
          if (regno == INVALID_REGNUM)
7336
            break;
7337
          imask |= 1UL << regno;
7338
        }
7339
    }
7340
 
7341
  /* If any register spilled, then spill the return address also.  */
7342
  /* ??? This is required by the Digital stack unwind specification
7343
     and isn't needed if we're doing Dwarf2 unwinding.  */
7344
  if (imask || fmask || alpha_ra_ever_killed ())
7345
    imask |= (1UL << REG_RA);
7346
 
7347
  *imaskP = imask;
7348
  *fmaskP = fmask;
7349
}
7350
 
7351
int
7352
alpha_sa_size (void)
7353
{
7354
  unsigned long mask[2];
7355
  int sa_size = 0;
7356
  int i, j;
7357
 
7358
  alpha_sa_mask (&mask[0], &mask[1]);
7359
 
7360
  if (TARGET_ABI_UNICOSMK)
7361
    {
7362
      if (mask[0] || mask[1])
7363
        sa_size = 14;
7364
    }
7365
  else
7366
    {
7367
      for (j = 0; j < 2; ++j)
7368
        for (i = 0; i < 32; ++i)
7369
          if ((mask[j] >> i) & 1)
7370
            sa_size++;
7371
    }
7372
 
7373
  if (TARGET_ABI_UNICOSMK)
7374
    {
7375
      /* We might not need to generate a frame if we don't make any calls
7376
         (including calls to __T3E_MISMATCH if this is a vararg function),
7377
         don't have any local variables which require stack slots, don't
7378
         use alloca and have not determined that we need a frame for other
7379
         reasons.  */
7380
 
7381
      alpha_procedure_type
7382
        = (sa_size || get_frame_size() != 0
7383
           || crtl->outgoing_args_size
7384
           || cfun->stdarg || cfun->calls_alloca
7385
           || frame_pointer_needed)
7386
          ? PT_STACK : PT_REGISTER;
7387
 
7388
      /* Always reserve space for saving callee-saved registers if we
7389
         need a frame as required by the calling convention.  */
7390
      if (alpha_procedure_type == PT_STACK)
7391
        sa_size = 14;
7392
    }
7393
  else if (TARGET_ABI_OPEN_VMS)
7394
    {
7395
      /* Start with a stack procedure if we make any calls (REG_RA used), or
7396
         need a frame pointer, with a register procedure if we otherwise need
7397
         at least a slot, and with a null procedure in other cases.  */
7398
      if ((mask[0] >> REG_RA) & 1 || frame_pointer_needed)
7399
        alpha_procedure_type = PT_STACK;
7400
      else if (get_frame_size() != 0)
7401
        alpha_procedure_type = PT_REGISTER;
7402
      else
7403
        alpha_procedure_type = PT_NULL;
7404
 
7405
      /* Don't reserve space for saving FP & RA yet.  Do that later after we've
7406
         made the final decision on stack procedure vs register procedure.  */
7407
      if (alpha_procedure_type == PT_STACK)
7408
        sa_size -= 2;
7409
 
7410
      /* Decide whether to refer to objects off our PV via FP or PV.
7411
         If we need FP for something else or if we receive a nonlocal
7412
         goto (which expects PV to contain the value), we must use PV.
7413
         Otherwise, start by assuming we can use FP.  */
7414
 
7415
      vms_base_regno
7416
        = (frame_pointer_needed
7417
           || cfun->has_nonlocal_label
7418
           || alpha_procedure_type == PT_STACK
7419
           || crtl->outgoing_args_size)
7420
          ? REG_PV : HARD_FRAME_POINTER_REGNUM;
7421
 
7422
      /* If we want to copy PV into FP, we need to find some register
7423
         in which to save FP.  */
7424
 
7425
      vms_save_fp_regno = -1;
7426
      if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
7427
        for (i = 0; i < 32; i++)
7428
          if (! fixed_regs[i] && call_used_regs[i] && ! df_regs_ever_live_p (i))
7429
            vms_save_fp_regno = i;
7430
 
7431
      /* A VMS condition handler requires a stack procedure in our
7432
         implementation. (not required by the calling standard).  */
7433
      if ((vms_save_fp_regno == -1 && alpha_procedure_type == PT_REGISTER)
7434
          || cfun->machine->uses_condition_handler)
7435
        vms_base_regno = REG_PV, alpha_procedure_type = PT_STACK;
7436
      else if (alpha_procedure_type == PT_NULL)
7437
        vms_base_regno = REG_PV;
7438
 
7439
      /* Stack unwinding should be done via FP unless we use it for PV.  */
7440
      vms_unwind_regno = (vms_base_regno == REG_PV
7441
                          ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
7442
 
7443
      /* If this is a stack procedure, allow space for saving FP, RA and
7444
         a condition handler slot if needed.  */
7445
      if (alpha_procedure_type == PT_STACK)
7446
        sa_size += 2 + cfun->machine->uses_condition_handler;
7447
    }
7448
  else
7449
    {
7450
      /* Our size must be even (multiple of 16 bytes).  */
7451
      if (sa_size & 1)
7452
        sa_size++;
7453
    }
7454
 
7455
  return sa_size * 8;
7456
}
7457
 
7458
/* Define the offset between two registers, one to be eliminated,
7459
   and the other its replacement, at the start of a routine.  */
7460
 
7461
HOST_WIDE_INT
7462
alpha_initial_elimination_offset (unsigned int from,
7463
                                  unsigned int to ATTRIBUTE_UNUSED)
7464
{
7465
  HOST_WIDE_INT ret;
7466
 
7467
  ret = alpha_sa_size ();
7468
  ret += ALPHA_ROUND (crtl->outgoing_args_size);
7469
 
7470
  switch (from)
7471
    {
7472
    case FRAME_POINTER_REGNUM:
7473
      break;
7474
 
7475
    case ARG_POINTER_REGNUM:
7476
      ret += (ALPHA_ROUND (get_frame_size ()
7477
                           + crtl->args.pretend_args_size)
7478
              - crtl->args.pretend_args_size);
7479
      break;
7480
 
7481
    default:
7482
      gcc_unreachable ();
7483
    }
7484
 
7485
  return ret;
7486
}
7487
 
7488
#if TARGET_ABI_OPEN_VMS
7489
 
7490
/* Worker function for TARGET_CAN_ELIMINATE.  */
7491
 
7492
static bool
7493
alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
7494
{
7495
  /* We need the alpha_procedure_type to decide. Evaluate it now.  */
7496
  alpha_sa_size ();
7497
 
7498
  switch (alpha_procedure_type)
7499
    {
7500
    case PT_NULL:
7501
      /* NULL procedures have no frame of their own and we only
7502
         know how to resolve from the current stack pointer.  */
7503
      return to == STACK_POINTER_REGNUM;
7504
 
7505
    case PT_REGISTER:
7506
    case PT_STACK:
7507
      /* We always eliminate except to the stack pointer if there is no
7508
         usable frame pointer at hand.  */
7509
      return (to != STACK_POINTER_REGNUM
7510
              || vms_unwind_regno != HARD_FRAME_POINTER_REGNUM);
7511
    }
7512
 
7513
  gcc_unreachable ();
7514
}
7515
 
7516
/* FROM is to be eliminated for TO. Return the offset so that TO+offset
7517
   designates the same location as FROM.  */
7518
 
7519
HOST_WIDE_INT
7520
alpha_vms_initial_elimination_offset (unsigned int from, unsigned int to)
7521
{
7522
  /* The only possible attempts we ever expect are ARG or FRAME_PTR to
7523
     HARD_FRAME or STACK_PTR.  We need the alpha_procedure_type to decide
7524
     on the proper computations and will need the register save area size
7525
     in most cases.  */
7526
 
7527
  HOST_WIDE_INT sa_size = alpha_sa_size ();
7528
 
7529
  /* PT_NULL procedures have no frame of their own and we only allow
7530
     elimination to the stack pointer. This is the argument pointer and we
7531
     resolve the soft frame pointer to that as well.  */
7532
 
7533
  if (alpha_procedure_type == PT_NULL)
7534
    return 0;
7535
 
7536
  /* For a PT_STACK procedure the frame layout looks as follows
7537
 
7538
                      -----> decreasing addresses
7539
 
7540
                   <             size rounded up to 16       |   likewise   >
7541
     --------------#------------------------------+++--------------+++-------#
7542
     incoming args # pretended args | "frame" | regs sa | PV | outgoing args #
7543
     --------------#---------------------------------------------------------#
7544
                                   ^         ^              ^               ^
7545
                              ARG_PTR FRAME_PTR HARD_FRAME_PTR       STACK_PTR
7546
 
7547
 
7548
     PT_REGISTER procedures are similar in that they may have a frame of their
7549
     own. They have no regs-sa/pv/outgoing-args area.
7550
 
7551
     We first compute offset to HARD_FRAME_PTR, then add what we need to get
7552
     to STACK_PTR if need be.  */
7553
 
7554
  {
7555
    HOST_WIDE_INT offset;
7556
    HOST_WIDE_INT pv_save_size = alpha_procedure_type == PT_STACK ? 8 : 0;
7557
 
7558
    switch (from)
7559
      {
7560
      case FRAME_POINTER_REGNUM:
7561
        offset = ALPHA_ROUND (sa_size + pv_save_size);
7562
        break;
7563
      case ARG_POINTER_REGNUM:
7564
        offset = (ALPHA_ROUND (sa_size + pv_save_size
7565
                               + get_frame_size ()
7566
                               + crtl->args.pretend_args_size)
7567
                  - crtl->args.pretend_args_size);
7568
        break;
7569
      default:
7570
        gcc_unreachable ();
7571
      }
7572
 
7573
    if (to == STACK_POINTER_REGNUM)
7574
      offset += ALPHA_ROUND (crtl->outgoing_args_size);
7575
 
7576
    return offset;
7577
  }
7578
}
7579
 
7580
#define COMMON_OBJECT "common_object"
7581
 
7582
static tree
7583
common_object_handler (tree *node, tree name ATTRIBUTE_UNUSED,
7584
                       tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED,
7585
                       bool *no_add_attrs ATTRIBUTE_UNUSED)
7586
{
7587
  tree decl = *node;
7588
  gcc_assert (DECL_P (decl));
7589
 
7590
  DECL_COMMON (decl) = 1;
7591
  return NULL_TREE;
7592
}
7593
 
7594
static const struct attribute_spec vms_attribute_table[] =
7595
{
7596
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
7597
  { COMMON_OBJECT,   0, 1, true,  false, false, common_object_handler },
7598
  { NULL,            0, 0, false, false, false, NULL }
7599
};
7600
 
7601
void
7602
vms_output_aligned_decl_common(FILE *file, tree decl, const char *name,
7603
                               unsigned HOST_WIDE_INT size,
7604
                               unsigned int align)
7605
{
7606
  tree attr = DECL_ATTRIBUTES (decl);
7607
  fprintf (file, "%s", COMMON_ASM_OP);
7608
  assemble_name (file, name);
7609
  fprintf (file, "," HOST_WIDE_INT_PRINT_UNSIGNED, size);
7610
  /* ??? Unlike on OSF/1, the alignment factor is not in log units.  */
7611
  fprintf (file, ",%u", align / BITS_PER_UNIT);
7612
  if (attr)
7613
    {
7614
      attr = lookup_attribute (COMMON_OBJECT, attr);
7615
      if (attr)
7616
        fprintf (file, ",%s",
7617
                 IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (attr))));
7618
    }
7619
  fputc ('\n', file);
7620
}
7621
 
7622
#undef COMMON_OBJECT
7623
 
7624
#endif
7625
 
7626
static int
7627
find_lo_sum_using_gp (rtx *px, void *data ATTRIBUTE_UNUSED)
7628
{
7629
  return GET_CODE (*px) == LO_SUM && XEXP (*px, 0) == pic_offset_table_rtx;
7630
}
7631
 
7632
int
7633
alpha_find_lo_sum_using_gp (rtx insn)
7634
{
7635
  return for_each_rtx (&PATTERN (insn), find_lo_sum_using_gp, NULL) > 0;
7636
}
7637
 
7638
static int
7639
alpha_does_function_need_gp (void)
7640
{
7641
  rtx insn;
7642
 
7643
  /* The GP being variable is an OSF abi thing.  */
7644
  if (! TARGET_ABI_OSF)
7645
    return 0;
7646
 
7647
  /* We need the gp to load the address of __mcount.  */
7648
  if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
7649
    return 1;
7650
 
7651
  /* The code emitted by alpha_output_mi_thunk_osf uses the gp.  */
7652
  if (cfun->is_thunk)
7653
    return 1;
7654
 
7655
  /* The nonlocal receiver pattern assumes that the gp is valid for
7656
     the nested function.  Reasonable because it's almost always set
7657
     correctly already.  For the cases where that's wrong, make sure
7658
     the nested function loads its gp on entry.  */
7659
  if (crtl->has_nonlocal_goto)
7660
    return 1;
7661
 
7662
  /* If we need a GP (we have a LDSYM insn or a CALL_INSN), load it first.
7663
     Even if we are a static function, we still need to do this in case
7664
     our address is taken and passed to something like qsort.  */
7665
 
7666
  push_topmost_sequence ();
7667
  insn = get_insns ();
7668
  pop_topmost_sequence ();
7669
 
7670
  for (; insn; insn = NEXT_INSN (insn))
7671
    if (NONDEBUG_INSN_P (insn)
7672
        && ! JUMP_TABLE_DATA_P (insn)
7673
        && GET_CODE (PATTERN (insn)) != USE
7674
        && GET_CODE (PATTERN (insn)) != CLOBBER
7675
        && get_attr_usegp (insn))
7676
      return 1;
7677
 
7678
  return 0;
7679
}
7680
 
7681
 
7682
/* Helper function to set RTX_FRAME_RELATED_P on instructions, including
7683
   sequences.  */
7684
 
7685
static rtx
7686
set_frame_related_p (void)
7687
{
7688
  rtx seq = get_insns ();
7689
  rtx insn;
7690
 
7691
  end_sequence ();
7692
 
7693
  if (!seq)
7694
    return NULL_RTX;
7695
 
7696
  if (INSN_P (seq))
7697
    {
7698
      insn = seq;
7699
      while (insn != NULL_RTX)
7700
        {
7701
          RTX_FRAME_RELATED_P (insn) = 1;
7702
          insn = NEXT_INSN (insn);
7703
        }
7704
      seq = emit_insn (seq);
7705
    }
7706
  else
7707
    {
7708
      seq = emit_insn (seq);
7709
      RTX_FRAME_RELATED_P (seq) = 1;
7710
    }
7711
  return seq;
7712
}
7713
 
7714
#define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())
7715
 
7716
/* Generates a store with the proper unwind info attached.  VALUE is
7717
   stored at BASE_REG+BASE_OFS.  If FRAME_BIAS is nonzero, then BASE_REG
7718
   contains SP+FRAME_BIAS, and that is the unwind info that should be
7719
   generated.  If FRAME_REG != VALUE, then VALUE is being stored on
7720
   behalf of FRAME_REG, and FRAME_REG should be present in the unwind.  */
7721
 
7722
static void
7723
emit_frame_store_1 (rtx value, rtx base_reg, HOST_WIDE_INT frame_bias,
7724
                    HOST_WIDE_INT base_ofs, rtx frame_reg)
7725
{
7726
  rtx addr, mem, insn;
7727
 
7728
  addr = plus_constant (base_reg, base_ofs);
7729
  mem = gen_rtx_MEM (DImode, addr);
7730
  set_mem_alias_set (mem, alpha_sr_alias_set);
7731
 
7732
  insn = emit_move_insn (mem, value);
7733
  RTX_FRAME_RELATED_P (insn) = 1;
7734
 
7735
  if (frame_bias || value != frame_reg)
7736
    {
7737
      if (frame_bias)
7738
        {
7739
          addr = plus_constant (stack_pointer_rtx, frame_bias + base_ofs);
7740
          mem = gen_rtx_MEM (DImode, addr);
7741
        }
7742
 
7743
      add_reg_note (insn, REG_FRAME_RELATED_EXPR,
7744
                    gen_rtx_SET (VOIDmode, mem, frame_reg));
7745
    }
7746
}
7747
 
7748
static void
7749
emit_frame_store (unsigned int regno, rtx base_reg,
7750
                  HOST_WIDE_INT frame_bias, HOST_WIDE_INT base_ofs)
7751
{
7752
  rtx reg = gen_rtx_REG (DImode, regno);
7753
  emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
7754
}
7755
 
7756
/* Write function prologue.  */
7757
 
7758
/* On vms we have two kinds of functions:
7759
 
7760
   - stack frame (PROC_STACK)
7761
        these are 'normal' functions with local vars and which are
7762
        calling other functions
7763
   - register frame (PROC_REGISTER)
7764
        keeps all data in registers, needs no stack
7765
 
7766
   We must pass this to the assembler so it can generate the
7767
   proper pdsc (procedure descriptor)
7768
   This is done with the '.pdesc' command.
7769
 
7770
   On not-vms, we don't really differentiate between the two, as we can
7771
   simply allocate stack without saving registers.  */
7772
 
7773
void
7774
alpha_expand_prologue (void)
7775
{
7776
  /* Registers to save.  */
7777
  unsigned long imask = 0;
7778
  unsigned long fmask = 0;
7779
  /* Stack space needed for pushing registers clobbered by us.  */
7780
  HOST_WIDE_INT sa_size;
7781
  /* Complete stack size needed.  */
7782
  HOST_WIDE_INT frame_size;
7783
  /* Offset from base reg to register save area.  */
7784
  HOST_WIDE_INT reg_offset;
7785
  rtx sa_reg;
7786
  int i;
7787
 
7788
  sa_size = alpha_sa_size ();
7789
 
7790
  frame_size = get_frame_size ();
7791
  if (TARGET_ABI_OPEN_VMS)
7792
    frame_size = ALPHA_ROUND (sa_size
7793
                              + (alpha_procedure_type == PT_STACK ? 8 : 0)
7794
                              + frame_size
7795
                              + crtl->args.pretend_args_size);
7796
  else if (TARGET_ABI_UNICOSMK)
7797
    /* We have to allocate space for the DSIB if we generate a frame.  */
7798
    frame_size = ALPHA_ROUND (sa_size
7799
                              + (alpha_procedure_type == PT_STACK ? 48 : 0))
7800
                 + ALPHA_ROUND (frame_size
7801
                                + crtl->outgoing_args_size);
7802
  else
7803
    frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
7804
                  + sa_size
7805
                  + ALPHA_ROUND (frame_size
7806
                                 + crtl->args.pretend_args_size));
7807
 
7808
  if (TARGET_ABI_OPEN_VMS)
7809
    reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
7810
  else
7811
    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
7812
 
7813
  alpha_sa_mask (&imask, &fmask);
7814
 
7815
  /* Emit an insn to reload GP, if needed.  */
7816
  if (TARGET_ABI_OSF)
7817
    {
7818
      alpha_function_needs_gp = alpha_does_function_need_gp ();
7819
      if (alpha_function_needs_gp)
7820
        emit_insn (gen_prologue_ldgp ());
7821
    }
7822
 
7823
  /* TARGET_PROFILING_NEEDS_GP actually implies that we need to insert
7824
     the call to mcount ourselves, rather than having the linker do it
7825
     magically in response to -pg.  Since _mcount has special linkage,
7826
     don't represent the call as a call.  */
7827
  if (TARGET_PROFILING_NEEDS_GP && crtl->profile)
7828
    emit_insn (gen_prologue_mcount ());
7829
 
7830
  if (TARGET_ABI_UNICOSMK)
7831
    unicosmk_gen_dsib (&imask);
7832
 
7833
  /* Adjust the stack by the frame size.  If the frame size is > 4096
7834
     bytes, we need to be sure we probe somewhere in the first and last
7835
     4096 bytes (we can probably get away without the latter test) and
7836
     every 8192 bytes in between.  If the frame size is > 32768, we
7837
     do this in a loop.  Otherwise, we generate the explicit probe
7838
     instructions.
7839
 
7840
     Note that we are only allowed to adjust sp once in the prologue.  */
7841
 
7842
  if (frame_size <= 32768)
7843
    {
7844
      if (frame_size > 4096)
7845
        {
7846
          int probed;
7847
 
7848
          for (probed = 4096; probed < frame_size; probed += 8192)
7849
            emit_insn (gen_probe_stack (GEN_INT (TARGET_ABI_UNICOSMK
7850
                                                 ? -probed + 64
7851
                                                 : -probed)));
7852
 
7853
          /* We only have to do this probe if we aren't saving registers.  */
7854
          if (sa_size == 0 && frame_size > probed - 4096)
7855
            emit_insn (gen_probe_stack (GEN_INT (-frame_size)));
7856
        }
7857
 
7858
      if (frame_size != 0)
7859
        FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
7860
                                    GEN_INT (TARGET_ABI_UNICOSMK
7861
                                             ? -frame_size + 64
7862
                                             : -frame_size))));
7863
    }
7864
  else
7865
    {
7866
      /* Here we generate code to set R22 to SP + 4096 and set R23 to the
7867
         number of 8192 byte blocks to probe.  We then probe each block
7868
         in the loop and then set SP to the proper location.  If the
7869
         amount remaining is > 4096, we have to do one more probe if we
7870
         are not saving any registers.  */
7871
 
7872
      HOST_WIDE_INT blocks = (frame_size + 4096) / 8192;
7873
      HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192;
7874
      rtx ptr = gen_rtx_REG (DImode, 22);
7875
      rtx count = gen_rtx_REG (DImode, 23);
7876
      rtx seq;
7877
 
7878
      emit_move_insn (count, GEN_INT (blocks));
7879
      emit_insn (gen_adddi3 (ptr, stack_pointer_rtx,
7880
                             GEN_INT (TARGET_ABI_UNICOSMK ? 4096 - 64 : 4096)));
7881
 
7882
      /* Because of the difficulty in emitting a new basic block this
7883
         late in the compilation, generate the loop as a single insn.  */
7884
      emit_insn (gen_prologue_stack_probe_loop (count, ptr));
7885
 
7886
      if (leftover > 4096 && sa_size == 0)
7887
        {
7888
          rtx last = gen_rtx_MEM (DImode, plus_constant (ptr, -leftover));
7889
          MEM_VOLATILE_P (last) = 1;
7890
          emit_move_insn (last, const0_rtx);
7891
        }
7892
 
7893
      if (TARGET_ABI_WINDOWS_NT)
7894
        {
7895
          /* For NT stack unwind (done by 'reverse execution'), it's
7896
             not OK to take the result of a loop, even though the value
7897
             is already in ptr, so we reload it via a single operation
7898
             and subtract it to sp.
7899
 
7900
             Yes, that's correct -- we have to reload the whole constant
7901
             into a temporary via ldah+lda then subtract from sp.  */
7902
 
7903
          HOST_WIDE_INT lo, hi;
7904
          lo = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
7905
          hi = frame_size - lo;
7906
 
7907
          emit_move_insn (ptr, GEN_INT (hi));
7908
          emit_insn (gen_adddi3 (ptr, ptr, GEN_INT (lo)));
7909
          seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
7910
                                       ptr));
7911
        }
7912
      else
7913
        {
7914
          seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr,
7915
                                       GEN_INT (-leftover)));
7916
        }
7917
 
7918
      /* This alternative is special, because the DWARF code cannot
7919
         possibly intuit through the loop above.  So we invent this
7920
         note it looks at instead.  */
7921
      RTX_FRAME_RELATED_P (seq) = 1;
7922
      add_reg_note (seq, REG_FRAME_RELATED_EXPR,
7923
                    gen_rtx_SET (VOIDmode, stack_pointer_rtx,
7924
                                 gen_rtx_PLUS (Pmode, stack_pointer_rtx,
7925
                                               GEN_INT (TARGET_ABI_UNICOSMK
7926
                                                        ? -frame_size + 64
7927
                                                        : -frame_size))));
7928
    }
7929
 
7930
  if (!TARGET_ABI_UNICOSMK)
7931
    {
7932
      HOST_WIDE_INT sa_bias = 0;
7933
 
7934
      /* Cope with very large offsets to the register save area.  */
7935
      sa_reg = stack_pointer_rtx;
7936
      if (reg_offset + sa_size > 0x8000)
7937
        {
7938
          int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
7939
          rtx sa_bias_rtx;
7940
 
7941
          if (low + sa_size <= 0x8000)
7942
            sa_bias = reg_offset - low, reg_offset = low;
7943
          else
7944
            sa_bias = reg_offset, reg_offset = 0;
7945
 
7946
          sa_reg = gen_rtx_REG (DImode, 24);
7947
          sa_bias_rtx = GEN_INT (sa_bias);
7948
 
7949
          if (add_operand (sa_bias_rtx, DImode))
7950
            emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_bias_rtx));
7951
          else
7952
            {
7953
              emit_move_insn (sa_reg, sa_bias_rtx);
7954
              emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, sa_reg));
7955
            }
7956
        }
7957
 
7958
      /* Save regs in stack order.  Beginning with VMS PV.  */
7959
      if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
7960
        emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
7961
 
7962
      /* Save register RA next.  */
7963
      if (imask & (1UL << REG_RA))
7964
        {
7965
          emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset);
7966
          imask &= ~(1UL << REG_RA);
7967
          reg_offset += 8;
7968
        }
7969
 
7970
      /* Now save any other registers required to be saved.  */
7971
      for (i = 0; i < 31; i++)
7972
        if (imask & (1UL << i))
7973
          {
7974
            emit_frame_store (i, sa_reg, sa_bias, reg_offset);
7975
            reg_offset += 8;
7976
          }
7977
 
7978
      for (i = 0; i < 31; i++)
7979
        if (fmask & (1UL << i))
7980
          {
7981
            emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
7982
            reg_offset += 8;
7983
          }
7984
    }
7985
  else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
7986
    {
7987
      /* The standard frame on the T3E includes space for saving registers.
7988
         We just have to use it. We don't have to save the return address and
7989
         the old frame pointer here - they are saved in the DSIB.  */
7990
 
7991
      reg_offset = -56;
7992
      for (i = 9; i < 15; i++)
7993
        if (imask & (1UL << i))
7994
          {
7995
            emit_frame_store (i, hard_frame_pointer_rtx, 0, reg_offset);
7996
            reg_offset -= 8;
7997
          }
7998
      for (i = 2; i < 10; i++)
7999
        if (fmask & (1UL << i))
8000
          {
8001
            emit_frame_store (i+32, hard_frame_pointer_rtx, 0, reg_offset);
8002
            reg_offset -= 8;
8003
          }
8004
    }
8005
 
8006
  if (TARGET_ABI_OPEN_VMS)
8007
    {
8008
      /* Register frame procedures save the fp.  */
8009
      if (alpha_procedure_type == PT_REGISTER)
8010
        {
8011
          rtx insn = emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
8012
                                     hard_frame_pointer_rtx);
8013
          add_reg_note (insn, REG_CFA_REGISTER, NULL);
8014
          RTX_FRAME_RELATED_P (insn) = 1;
8015
        }
8016
 
8017
      if (alpha_procedure_type != PT_NULL && vms_base_regno != REG_PV)
8018
        emit_insn (gen_force_movdi (gen_rtx_REG (DImode, vms_base_regno),
8019
                                    gen_rtx_REG (DImode, REG_PV)));
8020
 
8021
      if (alpha_procedure_type != PT_NULL
8022
          && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
8023
        FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
8024
 
8025
      /* If we have to allocate space for outgoing args, do it now.  */
8026
      if (crtl->outgoing_args_size != 0)
8027
        {
8028
          rtx seq
8029
            = emit_move_insn (stack_pointer_rtx,
8030
                              plus_constant
8031
                              (hard_frame_pointer_rtx,
8032
                               - (ALPHA_ROUND
8033
                                  (crtl->outgoing_args_size))));
8034
 
8035
          /* Only set FRAME_RELATED_P on the stack adjustment we just emitted
8036
             if ! frame_pointer_needed. Setting the bit will change the CFA
8037
             computation rule to use sp again, which would be wrong if we had
8038
             frame_pointer_needed, as this means sp might move unpredictably
8039
             later on.
8040
 
8041
             Also, note that
8042
               frame_pointer_needed
8043
               => vms_unwind_regno == HARD_FRAME_POINTER_REGNUM
8044
             and
8045
               crtl->outgoing_args_size != 0
8046
               => alpha_procedure_type != PT_NULL,
8047
 
8048
             so when we are not setting the bit here, we are guaranteed to
8049
             have emitted an FRP frame pointer update just before.  */
8050
          RTX_FRAME_RELATED_P (seq) = ! frame_pointer_needed;
8051
        }
8052
    }
8053
  else if (!TARGET_ABI_UNICOSMK)
8054
    {
8055
      /* If we need a frame pointer, set it from the stack pointer.  */
8056
      if (frame_pointer_needed)
8057
        {
8058
          if (TARGET_CAN_FAULT_IN_PROLOGUE)
8059
            FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
8060
          else
8061
            /* This must always be the last instruction in the
8062
               prologue, thus we emit a special move + clobber.  */
8063
              FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
8064
                                           stack_pointer_rtx, sa_reg)));
8065
        }
8066
    }
8067
 
8068
  /* The ABIs for VMS and OSF/1 say that while we can schedule insns into
8069
     the prologue, for exception handling reasons, we cannot do this for
8070
     any insn that might fault.  We could prevent this for mems with a
8071
     (clobber:BLK (scratch)), but this doesn't work for fp insns.  So we
8072
     have to prevent all such scheduling with a blockage.
8073
 
8074
     Linux, on the other hand, never bothered to implement OSF/1's
8075
     exception handling, and so doesn't care about such things.  Anyone
8076
     planning to use dwarf2 frame-unwind info can also omit the blockage.  */
8077
 
8078
  if (! TARGET_CAN_FAULT_IN_PROLOGUE)
8079
    emit_insn (gen_blockage ());
8080
}
8081
 
8082
/* Count the number of .file directives, so that .loc is up to date.  */
8083
int num_source_filenames = 0;
8084
 
8085
/* Output the textual info surrounding the prologue.  */
8086
 
8087
void
8088
alpha_start_function (FILE *file, const char *fnname,
8089
                      tree decl ATTRIBUTE_UNUSED)
8090
{
8091
  unsigned long imask = 0;
8092
  unsigned long fmask = 0;
8093
  /* Stack space needed for pushing registers clobbered by us.  */
8094
  HOST_WIDE_INT sa_size;
8095
  /* Complete stack size needed.  */
8096
  unsigned HOST_WIDE_INT frame_size;
8097
  /* The maximum debuggable frame size (512 Kbytes using Tru64 as).  */
8098
  unsigned HOST_WIDE_INT max_frame_size = TARGET_ABI_OSF && !TARGET_GAS
8099
                                          ? 524288
8100
                                          : 1UL << 31;
8101
  /* Offset from base reg to register save area.  */
8102
  HOST_WIDE_INT reg_offset;
8103
  char *entry_label = (char *) alloca (strlen (fnname) + 6);
8104
  char *tramp_label = (char *) alloca (strlen (fnname) + 6);
8105
  int i;
8106
 
8107
  /* Don't emit an extern directive for functions defined in the same file.  */
8108
  if (TARGET_ABI_UNICOSMK)
8109
    {
8110
      tree name_tree;
8111
      name_tree = get_identifier (fnname);
8112
      TREE_ASM_WRITTEN (name_tree) = 1;
8113
    }
8114
 
8115
#if TARGET_ABI_OPEN_VMS
8116
  if (vms_debug_main
8117
      && strncmp (vms_debug_main, fnname, strlen (vms_debug_main)) == 0)
8118
    {
8119
      targetm.asm_out.globalize_label (asm_out_file, VMS_DEBUG_MAIN_POINTER);
8120
      ASM_OUTPUT_DEF (asm_out_file, VMS_DEBUG_MAIN_POINTER, fnname);
8121
      switch_to_section (text_section);
8122
      vms_debug_main = NULL;
8123
    }
8124
#endif
8125
 
8126
  alpha_fnname = fnname;
8127
  sa_size = alpha_sa_size ();
8128
 
8129
  frame_size = get_frame_size ();
8130
  if (TARGET_ABI_OPEN_VMS)
8131
    frame_size = ALPHA_ROUND (sa_size
8132
                              + (alpha_procedure_type == PT_STACK ? 8 : 0)
8133
                              + frame_size
8134
                              + crtl->args.pretend_args_size);
8135
  else if (TARGET_ABI_UNICOSMK)
8136
    frame_size = ALPHA_ROUND (sa_size
8137
                              + (alpha_procedure_type == PT_STACK ? 48 : 0))
8138
                 + ALPHA_ROUND (frame_size
8139
                              + crtl->outgoing_args_size);
8140
  else
8141
    frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
8142
                  + sa_size
8143
                  + ALPHA_ROUND (frame_size
8144
                                 + crtl->args.pretend_args_size));
8145
 
8146
  if (TARGET_ABI_OPEN_VMS)
8147
    reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
8148
  else
8149
    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
8150
 
8151
  alpha_sa_mask (&imask, &fmask);
8152
 
8153
  /* Ecoff can handle multiple .file directives, so put out file and lineno.
8154
     We have to do that before the .ent directive as we cannot switch
8155
     files within procedures with native ecoff because line numbers are
8156
     linked to procedure descriptors.
8157
     Outputting the lineno helps debugging of one line functions as they
8158
     would otherwise get no line number at all. Please note that we would
8159
     like to put out last_linenum from final.c, but it is not accessible.  */
8160
 
8161
  if (write_symbols == SDB_DEBUG)
8162
    {
8163
#ifdef ASM_OUTPUT_SOURCE_FILENAME
8164
      ASM_OUTPUT_SOURCE_FILENAME (file,
8165
                                  DECL_SOURCE_FILE (current_function_decl));
8166
#endif
8167
#ifdef SDB_OUTPUT_SOURCE_LINE
8168
      if (debug_info_level != DINFO_LEVEL_TERSE)
8169
        SDB_OUTPUT_SOURCE_LINE (file,
8170
                                DECL_SOURCE_LINE (current_function_decl));
8171
#endif
8172
    }
8173
 
8174
  /* Issue function start and label.  */
8175
  if (TARGET_ABI_OPEN_VMS
8176
      || (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive))
8177
    {
8178
      fputs ("\t.ent ", file);
8179
      assemble_name (file, fnname);
8180
      putc ('\n', file);
8181
 
8182
      /* If the function needs GP, we'll write the "..ng" label there.
8183
         Otherwise, do it here.  */
8184
      if (TARGET_ABI_OSF
8185
          && ! alpha_function_needs_gp
8186
          && ! cfun->is_thunk)
8187
        {
8188
          putc ('$', file);
8189
          assemble_name (file, fnname);
8190
          fputs ("..ng:\n", file);
8191
        }
8192
    }
8193
  /* Nested functions on VMS that are potentially called via trampoline
8194
     get a special transfer entry point that loads the called functions
8195
     procedure descriptor and static chain.  */
8196
   if (TARGET_ABI_OPEN_VMS
8197
       && !TREE_PUBLIC (decl)
8198
       && DECL_CONTEXT (decl)
8199
       && !TYPE_P (DECL_CONTEXT (decl)))
8200
     {
8201
        strcpy (tramp_label, fnname);
8202
        strcat (tramp_label, "..tr");
8203
        ASM_OUTPUT_LABEL (file, tramp_label);
8204
        fprintf (file, "\tldq $1,24($27)\n");
8205
        fprintf (file, "\tldq $27,16($27)\n");
8206
     }
8207
 
8208
  strcpy (entry_label, fnname);
8209
  if (TARGET_ABI_OPEN_VMS)
8210
    strcat (entry_label, "..en");
8211
 
8212
  /* For public functions, the label must be globalized by appending an
8213
     additional colon.  */
8214
  if (TARGET_ABI_UNICOSMK && TREE_PUBLIC (decl))
8215
    strcat (entry_label, ":");
8216
 
8217
  ASM_OUTPUT_LABEL (file, entry_label);
8218
  inside_function = TRUE;
8219
 
8220
  if (TARGET_ABI_OPEN_VMS)
8221
    fprintf (file, "\t.base $%d\n", vms_base_regno);
8222
 
8223
  if (!TARGET_ABI_OPEN_VMS && !TARGET_ABI_UNICOSMK && TARGET_IEEE_CONFORMANT
8224
      && !flag_inhibit_size_directive)
8225
    {
8226
      /* Set flags in procedure descriptor to request IEEE-conformant
8227
         math-library routines.  The value we set it to is PDSC_EXC_IEEE
8228
         (/usr/include/pdsc.h).  */
8229
      fputs ("\t.eflag 48\n", file);
8230
    }
8231
 
8232
  /* Set up offsets to alpha virtual arg/local debugging pointer.  */
8233
  alpha_auto_offset = -frame_size + crtl->args.pretend_args_size;
8234
  alpha_arg_offset = -frame_size + 48;
8235
 
8236
  /* Describe our frame.  If the frame size is larger than an integer,
8237
     print it as zero to avoid an assembler error.  We won't be
8238
     properly describing such a frame, but that's the best we can do.  */
8239
  if (TARGET_ABI_UNICOSMK)
8240
    ;
8241
  else if (TARGET_ABI_OPEN_VMS)
8242
    fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
8243
             HOST_WIDE_INT_PRINT_DEC "\n",
8244
             vms_unwind_regno,
8245
             frame_size >= (1UL << 31) ? 0 : frame_size,
8246
             reg_offset);
8247
  else if (!flag_inhibit_size_directive)
8248
    fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
8249
             (frame_pointer_needed
8250
              ? HARD_FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM),
8251
             frame_size >= max_frame_size ? 0 : frame_size,
8252
             crtl->args.pretend_args_size);
8253
 
8254
  /* Describe which registers were spilled.  */
8255
  if (TARGET_ABI_UNICOSMK)
8256
    ;
8257
  else if (TARGET_ABI_OPEN_VMS)
8258
    {
8259
      if (imask)
8260
        /* ??? Does VMS care if mask contains ra?  The old code didn't
8261
           set it, so I don't here.  */
8262
        fprintf (file, "\t.mask 0x%lx,0\n", imask & ~(1UL << REG_RA));
8263
      if (fmask)
8264
        fprintf (file, "\t.fmask 0x%lx,0\n", fmask);
8265
      if (alpha_procedure_type == PT_REGISTER)
8266
        fprintf (file, "\t.fp_save $%d\n", vms_save_fp_regno);
8267
    }
8268
  else if (!flag_inhibit_size_directive)
8269
    {
8270
      if (imask)
8271
        {
8272
          fprintf (file, "\t.mask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", imask,
8273
                   frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
8274
 
8275
          for (i = 0; i < 32; ++i)
8276
            if (imask & (1UL << i))
8277
              reg_offset += 8;
8278
        }
8279
 
8280
      if (fmask)
8281
        fprintf (file, "\t.fmask 0x%lx," HOST_WIDE_INT_PRINT_DEC "\n", fmask,
8282
                 frame_size >= max_frame_size ? 0 : reg_offset - frame_size);
8283
    }
8284
 
8285
#if TARGET_ABI_OPEN_VMS
8286
  /* If a user condition handler has been installed at some point, emit
8287
     the procedure descriptor bits to point the Condition Handling Facility
8288
     at the indirection wrapper, and state the fp offset at which the user
8289
     handler may be found.  */
8290
  if (cfun->machine->uses_condition_handler)
8291
    {
8292
      fprintf (file, "\t.handler __gcc_shell_handler\n");
8293
      fprintf (file, "\t.handler_data %d\n", VMS_COND_HANDLER_FP_OFFSET);
8294
    }
8295
 
8296
  /* Ifdef'ed cause link_section are only available then.  */
8297
  switch_to_section (readonly_data_section);
8298
  fprintf (file, "\t.align 3\n");
8299
  assemble_name (file, fnname); fputs ("..na:\n", file);
8300
  fputs ("\t.ascii \"", file);
8301
  assemble_name (file, fnname);
8302
  fputs ("\\0\"\n", file);
8303
  alpha_need_linkage (fnname, 1);
8304
  switch_to_section (text_section);
8305
#endif
8306
}
8307
 
8308
/* Emit the .prologue note at the scheduled end of the prologue.  */
8309
 
8310
static void
8311
alpha_output_function_end_prologue (FILE *file)
8312
{
8313
  if (TARGET_ABI_UNICOSMK)
8314
    ;
8315
  else if (TARGET_ABI_OPEN_VMS)
8316
    fputs ("\t.prologue\n", file);
8317
  else if (TARGET_ABI_WINDOWS_NT)
8318
    fputs ("\t.prologue 0\n", file);
8319
  else if (!flag_inhibit_size_directive)
8320
    fprintf (file, "\t.prologue %d\n",
8321
             alpha_function_needs_gp || cfun->is_thunk);
8322
}
8323
 
8324
/* Write function epilogue.  */
8325
 
8326
void
8327
alpha_expand_epilogue (void)
8328
{
8329
  /* Registers to save.  */
8330
  unsigned long imask = 0;
8331
  unsigned long fmask = 0;
8332
  /* Stack space needed for pushing registers clobbered by us.  */
8333
  HOST_WIDE_INT sa_size;
8334
  /* Complete stack size needed.  */
8335
  HOST_WIDE_INT frame_size;
8336
  /* Offset from base reg to register save area.  */
8337
  HOST_WIDE_INT reg_offset;
8338
  int fp_is_frame_pointer, fp_offset;
8339
  rtx sa_reg, sa_reg_exp = NULL;
8340
  rtx sp_adj1, sp_adj2, mem, reg, insn;
8341
  rtx eh_ofs;
8342
  rtx cfa_restores = NULL_RTX;
8343
  int i;
8344
 
8345
  sa_size = alpha_sa_size ();
8346
 
8347
  frame_size = get_frame_size ();
8348
  if (TARGET_ABI_OPEN_VMS)
8349
    frame_size = ALPHA_ROUND (sa_size
8350
                              + (alpha_procedure_type == PT_STACK ? 8 : 0)
8351
                              + frame_size
8352
                              + crtl->args.pretend_args_size);
8353
  else if (TARGET_ABI_UNICOSMK)
8354
    frame_size = ALPHA_ROUND (sa_size
8355
                              + (alpha_procedure_type == PT_STACK ? 48 : 0))
8356
                 + ALPHA_ROUND (frame_size
8357
                              + crtl->outgoing_args_size);
8358
  else
8359
    frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
8360
                  + sa_size
8361
                  + ALPHA_ROUND (frame_size
8362
                                 + crtl->args.pretend_args_size));
8363
 
8364
  if (TARGET_ABI_OPEN_VMS)
8365
    {
8366
       if (alpha_procedure_type == PT_STACK)
8367
          reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
8368
       else
8369
          reg_offset = 0;
8370
    }
8371
  else
8372
    reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
8373
 
8374
  alpha_sa_mask (&imask, &fmask);
8375
 
8376
  fp_is_frame_pointer
8377
    = ((TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
8378
       || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed));
8379
  fp_offset = 0;
8380
  sa_reg = stack_pointer_rtx;
8381
 
8382
  if (crtl->calls_eh_return)
8383
    eh_ofs = EH_RETURN_STACKADJ_RTX;
8384
  else
8385
    eh_ofs = NULL_RTX;
8386
 
8387
  if (!TARGET_ABI_UNICOSMK && sa_size)
8388
    {
8389
      /* If we have a frame pointer, restore SP from it.  */
8390
      if ((TARGET_ABI_OPEN_VMS
8391
           && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
8392
          || (!TARGET_ABI_OPEN_VMS && frame_pointer_needed))
8393
        emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
8394
 
8395
      /* Cope with very large offsets to the register save area.  */
8396
      if (reg_offset + sa_size > 0x8000)
8397
        {
8398
          int low = ((reg_offset & 0xffff) ^ 0x8000) - 0x8000;
8399
          HOST_WIDE_INT bias;
8400
 
8401
          if (low + sa_size <= 0x8000)
8402
            bias = reg_offset - low, reg_offset = low;
8403
          else
8404
            bias = reg_offset, reg_offset = 0;
8405
 
8406
          sa_reg = gen_rtx_REG (DImode, 22);
8407
          sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
8408
 
8409
          emit_move_insn (sa_reg, sa_reg_exp);
8410
        }
8411
 
8412
      /* Restore registers in order, excepting a true frame pointer.  */
8413
 
8414
      mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
8415
      if (! eh_ofs)
8416
        set_mem_alias_set (mem, alpha_sr_alias_set);
8417
      reg = gen_rtx_REG (DImode, REG_RA);
8418
      emit_move_insn (reg, mem);
8419
      cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
8420
 
8421
      reg_offset += 8;
8422
      imask &= ~(1UL << REG_RA);
8423
 
8424
      for (i = 0; i < 31; ++i)
8425
        if (imask & (1UL << i))
8426
          {
8427
            if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
8428
              fp_offset = reg_offset;
8429
            else
8430
              {
8431
                mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
8432
                set_mem_alias_set (mem, alpha_sr_alias_set);
8433
                reg = gen_rtx_REG (DImode, i);
8434
                emit_move_insn (reg, mem);
8435
                cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
8436
                                               cfa_restores);
8437
              }
8438
            reg_offset += 8;
8439
          }
8440
 
8441
      for (i = 0; i < 31; ++i)
8442
        if (fmask & (1UL << i))
8443
          {
8444
            mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset));
8445
            set_mem_alias_set (mem, alpha_sr_alias_set);
8446
            reg = gen_rtx_REG (DFmode, i+32);
8447
            emit_move_insn (reg, mem);
8448
            cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
8449
            reg_offset += 8;
8450
          }
8451
    }
8452
  else if (TARGET_ABI_UNICOSMK && alpha_procedure_type == PT_STACK)
8453
    {
8454
      /* Restore callee-saved general-purpose registers.  */
8455
 
8456
      reg_offset = -56;
8457
 
8458
      for (i = 9; i < 15; i++)
8459
        if (imask & (1UL << i))
8460
          {
8461
            mem = gen_rtx_MEM (DImode, plus_constant(hard_frame_pointer_rtx,
8462
                                                     reg_offset));
8463
            set_mem_alias_set (mem, alpha_sr_alias_set);
8464
            reg = gen_rtx_REG (DImode, i);
8465
            emit_move_insn (reg, mem);
8466
            cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
8467
            reg_offset -= 8;
8468
          }
8469
 
8470
      for (i = 2; i < 10; i++)
8471
        if (fmask & (1UL << i))
8472
          {
8473
            mem = gen_rtx_MEM (DFmode, plus_constant(hard_frame_pointer_rtx,
8474
                                                     reg_offset));
8475
            set_mem_alias_set (mem, alpha_sr_alias_set);
8476
            reg = gen_rtx_REG (DFmode, i+32);
8477
            emit_move_insn (reg, mem);
8478
            cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
8479
            reg_offset -= 8;
8480
          }
8481
 
8482
      /* Restore the return address from the DSIB.  */
8483
      mem = gen_rtx_MEM (DImode, plus_constant (hard_frame_pointer_rtx, -8));
8484
      set_mem_alias_set (mem, alpha_sr_alias_set);
8485
      reg = gen_rtx_REG (DImode, REG_RA);
8486
      emit_move_insn (reg, mem);
8487
      cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
8488
    }
8489
 
8490
  if (frame_size || eh_ofs)
8491
    {
8492
      sp_adj1 = stack_pointer_rtx;
8493
 
8494
      if (eh_ofs)
8495
        {
8496
          sp_adj1 = gen_rtx_REG (DImode, 23);
8497
          emit_move_insn (sp_adj1,
8498
                          gen_rtx_PLUS (Pmode, stack_pointer_rtx, eh_ofs));
8499
        }
8500
 
8501
      /* If the stack size is large, begin computation into a temporary
8502
         register so as not to interfere with a potential fp restore,
8503
         which must be consecutive with an SP restore.  */
8504
      if (frame_size < 32768
8505
          && ! (TARGET_ABI_UNICOSMK && cfun->calls_alloca))
8506
        sp_adj2 = GEN_INT (frame_size);
8507
      else if (TARGET_ABI_UNICOSMK)
8508
        {
8509
          sp_adj1 = gen_rtx_REG (DImode, 23);
8510
          emit_move_insn (sp_adj1, hard_frame_pointer_rtx);
8511
          sp_adj2 = const0_rtx;
8512
        }
8513
      else if (frame_size < 0x40007fffL)
8514
        {
8515
          int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000;
8516
 
8517
          sp_adj2 = plus_constant (sp_adj1, frame_size - low);
8518
          if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2))
8519
            sp_adj1 = sa_reg;
8520
          else
8521
            {
8522
              sp_adj1 = gen_rtx_REG (DImode, 23);
8523
              emit_move_insn (sp_adj1, sp_adj2);
8524
            }
8525
          sp_adj2 = GEN_INT (low);
8526
        }
8527
      else
8528
        {
8529
          rtx tmp = gen_rtx_REG (DImode, 23);
8530
          sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3, false);
8531
          if (!sp_adj2)
8532
            {
8533
              /* We can't drop new things to memory this late, afaik,
8534
                 so build it up by pieces.  */
8535
              sp_adj2 = alpha_emit_set_long_const (tmp, frame_size,
8536
                                                   -(frame_size < 0));
8537
              gcc_assert (sp_adj2);
8538
            }
8539
        }
8540
 
8541
      /* From now on, things must be in order.  So emit blockages.  */
8542
 
8543
      /* Restore the frame pointer.  */
8544
      if (TARGET_ABI_UNICOSMK)
8545
        {
8546
          emit_insn (gen_blockage ());
8547
          mem = gen_rtx_MEM (DImode,
8548
                             plus_constant (hard_frame_pointer_rtx, -16));
8549
          set_mem_alias_set (mem, alpha_sr_alias_set);
8550
          emit_move_insn (hard_frame_pointer_rtx, mem);
8551
          cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
8552
                                         hard_frame_pointer_rtx, cfa_restores);
8553
        }
8554
      else if (fp_is_frame_pointer)
8555
        {
8556
          emit_insn (gen_blockage ());
8557
          mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, fp_offset));
8558
          set_mem_alias_set (mem, alpha_sr_alias_set);
8559
          emit_move_insn (hard_frame_pointer_rtx, mem);
8560
          cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
8561
                                         hard_frame_pointer_rtx, cfa_restores);
8562
        }
8563
      else if (TARGET_ABI_OPEN_VMS)
8564
        {
8565
          emit_insn (gen_blockage ());
8566
          emit_move_insn (hard_frame_pointer_rtx,
8567
                          gen_rtx_REG (DImode, vms_save_fp_regno));
8568
          cfa_restores = alloc_reg_note (REG_CFA_RESTORE,
8569
                                         hard_frame_pointer_rtx, cfa_restores);
8570
        }
8571
 
8572
      /* Restore the stack pointer.  */
8573
      emit_insn (gen_blockage ());
8574
      if (sp_adj2 == const0_rtx)
8575
        insn = emit_move_insn (stack_pointer_rtx, sp_adj1);
8576
      else
8577
        insn = emit_move_insn (stack_pointer_rtx,
8578
                               gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
8579
      REG_NOTES (insn) = cfa_restores;
8580
      add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);
8581
      RTX_FRAME_RELATED_P (insn) = 1;
8582
    }
8583
  else
8584
    {
8585
      gcc_assert (cfa_restores == NULL);
8586
 
8587
      if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_REGISTER)
8588
        {
8589
          emit_insn (gen_blockage ());
8590
          insn = emit_move_insn (hard_frame_pointer_rtx,
8591
                                 gen_rtx_REG (DImode, vms_save_fp_regno));
8592
          add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
8593
          RTX_FRAME_RELATED_P (insn) = 1;
8594
        }
8595
      else if (TARGET_ABI_UNICOSMK && alpha_procedure_type != PT_STACK)
8596
        {
8597
          /* Decrement the frame pointer if the function does not have a
8598
             frame.  */
8599
          emit_insn (gen_blockage ());
8600
          emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
8601
                                 hard_frame_pointer_rtx, constm1_rtx));
8602
        }
8603
    }
8604
}
8605
 
8606
/* Output the rest of the textual info surrounding the epilogue.  */
8607
 
8608
void
8609
alpha_end_function (FILE *file, const char *fnname, tree decl ATTRIBUTE_UNUSED)
8610
{
8611
  rtx insn;
8612
 
8613
  /* We output a nop after noreturn calls at the very end of the function to
8614
     ensure that the return address always remains in the caller's code range,
8615
     as not doing so might confuse unwinding engines.  */
8616
  insn = get_last_insn ();
8617
  if (!INSN_P (insn))
8618
    insn = prev_active_insn (insn);
8619
  if (insn && CALL_P (insn))
8620
    output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL);
8621
 
8622
#if TARGET_ABI_OPEN_VMS
8623
  alpha_write_linkage (file, fnname, decl);
8624
#endif
8625
 
8626
  /* End the function.  */
8627
  if (!TARGET_ABI_UNICOSMK && !flag_inhibit_size_directive)
8628
    {
8629
      fputs ("\t.end ", file);
8630
      assemble_name (file, fnname);
8631
      putc ('\n', file);
8632
    }
8633
  inside_function = FALSE;
8634
 
8635
  /* Output jump tables and the static subroutine information block.  */
8636
  if (TARGET_ABI_UNICOSMK)
8637
    {
8638
      unicosmk_output_ssib (file, fnname);
8639
      unicosmk_output_deferred_case_vectors (file);
8640
    }
8641
}
8642
 
8643
#if TARGET_ABI_OPEN_VMS
8644
void avms_asm_output_external (FILE *file, tree decl ATTRIBUTE_UNUSED, const char *name)
8645
{
8646
#ifdef DO_CRTL_NAMES
8647
  DO_CRTL_NAMES;
8648
#endif
8649
}
8650
#endif
8651
 
8652
#if TARGET_ABI_OSF
8653
/* Emit a tail call to FUNCTION after adjusting THIS by DELTA.
8654
 
8655
   In order to avoid the hordes of differences between generated code
8656
   with and without TARGET_EXPLICIT_RELOCS, and to avoid duplicating
8657
   lots of code loading up large constants, generate rtl and emit it
8658
   instead of going straight to text.
8659
 
8660
   Not sure why this idea hasn't been explored before...  */
8661
 
8662
static void
8663
alpha_output_mi_thunk_osf (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
8664
                           HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
8665
                           tree function)
8666
{
8667
  HOST_WIDE_INT hi, lo;
8668
  rtx this_rtx, insn, funexp;
8669
 
8670
  /* We always require a valid GP.  */
8671
  emit_insn (gen_prologue_ldgp ());
8672
  emit_note (NOTE_INSN_PROLOGUE_END);
8673
 
8674
  /* Find the "this" pointer.  If the function returns a structure,
8675
     the structure return pointer is in $16.  */
8676
  if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
8677
    this_rtx = gen_rtx_REG (Pmode, 17);
8678
  else
8679
    this_rtx = gen_rtx_REG (Pmode, 16);
8680
 
8681
  /* Add DELTA.  When possible we use ldah+lda.  Otherwise load the
8682
     entire constant for the add.  */
8683
  lo = ((delta & 0xffff) ^ 0x8000) - 0x8000;
8684
  hi = (((delta - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8685
  if (hi + lo == delta)
8686
    {
8687
      if (hi)
8688
        emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (hi)));
8689
      if (lo)
8690
        emit_insn (gen_adddi3 (this_rtx, this_rtx, GEN_INT (lo)));
8691
    }
8692
  else
8693
    {
8694
      rtx tmp = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 0),
8695
                                           delta, -(delta < 0));
8696
      emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
8697
    }
8698
 
8699
  /* Add a delta stored in the vtable at VCALL_OFFSET.  */
8700
  if (vcall_offset)
8701
    {
8702
      rtx tmp, tmp2;
8703
 
8704
      tmp = gen_rtx_REG (Pmode, 0);
8705
      emit_move_insn (tmp, gen_rtx_MEM (Pmode, this_rtx));
8706
 
8707
      lo = ((vcall_offset & 0xffff) ^ 0x8000) - 0x8000;
8708
      hi = (((vcall_offset - lo) & 0xffffffff) ^ 0x80000000) - 0x80000000;
8709
      if (hi + lo == vcall_offset)
8710
        {
8711
          if (hi)
8712
            emit_insn (gen_adddi3 (tmp, tmp, GEN_INT (hi)));
8713
        }
8714
      else
8715
        {
8716
          tmp2 = alpha_emit_set_long_const (gen_rtx_REG (Pmode, 1),
8717
                                            vcall_offset, -(vcall_offset < 0));
8718
          emit_insn (gen_adddi3 (tmp, tmp, tmp2));
8719
          lo = 0;
8720
        }
8721
      if (lo)
8722
        tmp2 = gen_rtx_PLUS (Pmode, tmp, GEN_INT (lo));
8723
      else
8724
        tmp2 = tmp;
8725
      emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp2));
8726
 
8727
      emit_insn (gen_adddi3 (this_rtx, this_rtx, tmp));
8728
    }
8729
 
8730
  /* Generate a tail call to the target function.  */
8731
  if (! TREE_USED (function))
8732
    {
8733
      assemble_external (function);
8734
      TREE_USED (function) = 1;
8735
    }
8736
  funexp = XEXP (DECL_RTL (function), 0);
8737
  funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
8738
  insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
8739
  SIBLING_CALL_P (insn) = 1;
8740
 
8741
  /* Run just enough of rest_of_compilation to get the insns emitted.
8742
     There's not really enough bulk here to make other passes such as
8743
     instruction scheduling worth while.  Note that use_thunk calls
8744
     assemble_start_function and assemble_end_function.  */
8745
  insn = get_insns ();
8746
  insn_locators_alloc ();
8747
  shorten_branches (insn);
8748
  final_start_function (insn, file, 1);
8749
  final (insn, file, 1);
8750
  final_end_function ();
8751
}
8752
#endif /* TARGET_ABI_OSF */
8753
 
8754
/* Debugging support.  */
8755
 
8756
#include "gstab.h"
8757
 
8758
/* Count the number of sdb related labels are generated (to find block
8759
   start and end boundaries).  */
8760
 
8761
int sdb_label_count = 0;
8762
 
8763
/* Name of the file containing the current function.  */
8764
 
8765
static const char *current_function_file = "";
8766
 
8767
/* Offsets to alpha virtual arg/local debugging pointers.  */
8768
 
8769
long alpha_arg_offset;
8770
long alpha_auto_offset;
8771
 
8772
/* Emit a new filename to a stream.  */
8773
 
8774
void
8775
alpha_output_filename (FILE *stream, const char *name)
8776
{
8777
  static int first_time = TRUE;
8778
 
8779
  if (first_time)
8780
    {
8781
      first_time = FALSE;
8782
      ++num_source_filenames;
8783
      current_function_file = name;
8784
      fprintf (stream, "\t.file\t%d ", num_source_filenames);
8785
      output_quoted_string (stream, name);
8786
      fprintf (stream, "\n");
8787
      if (!TARGET_GAS && write_symbols == DBX_DEBUG)
8788
        fprintf (stream, "\t#@stabs\n");
8789
    }
8790
 
8791
  else if (write_symbols == DBX_DEBUG)
8792
    /* dbxout.c will emit an appropriate .stabs directive.  */
8793
    return;
8794
 
8795
  else if (name != current_function_file
8796
           && strcmp (name, current_function_file) != 0)
8797
    {
8798
      if (inside_function && ! TARGET_GAS)
8799
        fprintf (stream, "\t#.file\t%d ", num_source_filenames);
8800
      else
8801
        {
8802
          ++num_source_filenames;
8803
          current_function_file = name;
8804
          fprintf (stream, "\t.file\t%d ", num_source_filenames);
8805
        }
8806
 
8807
      output_quoted_string (stream, name);
8808
      fprintf (stream, "\n");
8809
    }
8810
}
8811
 
8812
/* Structure to show the current status of registers and memory.  */
8813
 
8814
struct shadow_summary
8815
{
8816
  struct {
8817
    unsigned int i     : 31;    /* Mask of int regs */
8818
    unsigned int fp    : 31;    /* Mask of fp regs */
8819
    unsigned int mem   :  1;    /* mem == imem | fpmem */
8820
  } used, defd;
8821
};
8822
 
8823
/* Summary the effects of expression X on the machine.  Update SUM, a pointer
8824
   to the summary structure.  SET is nonzero if the insn is setting the
8825
   object, otherwise zero.  */
8826
 
8827
static void
8828
summarize_insn (rtx x, struct shadow_summary *sum, int set)
8829
{
8830
  const char *format_ptr;
8831
  int i, j;
8832
 
8833
  if (x == 0)
8834
    return;
8835
 
8836
  switch (GET_CODE (x))
8837
    {
8838
      /* ??? Note that this case would be incorrect if the Alpha had a
8839
         ZERO_EXTRACT in SET_DEST.  */
8840
    case SET:
8841
      summarize_insn (SET_SRC (x), sum, 0);
8842
      summarize_insn (SET_DEST (x), sum, 1);
8843
      break;
8844
 
8845
    case CLOBBER:
8846
      summarize_insn (XEXP (x, 0), sum, 1);
8847
      break;
8848
 
8849
    case USE:
8850
      summarize_insn (XEXP (x, 0), sum, 0);
8851
      break;
8852
 
8853
    case ASM_OPERANDS:
8854
      for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
8855
        summarize_insn (ASM_OPERANDS_INPUT (x, i), sum, 0);
8856
      break;
8857
 
8858
    case PARALLEL:
8859
      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8860
        summarize_insn (XVECEXP (x, 0, i), sum, 0);
8861
      break;
8862
 
8863
    case SUBREG:
8864
      summarize_insn (SUBREG_REG (x), sum, 0);
8865
      break;
8866
 
8867
    case REG:
8868
      {
8869
        int regno = REGNO (x);
8870
        unsigned long mask = ((unsigned long) 1) << (regno % 32);
8871
 
8872
        if (regno == 31 || regno == 63)
8873
          break;
8874
 
8875
        if (set)
8876
          {
8877
            if (regno < 32)
8878
              sum->defd.i |= mask;
8879
            else
8880
              sum->defd.fp |= mask;
8881
          }
8882
        else
8883
          {
8884
            if (regno < 32)
8885
              sum->used.i  |= mask;
8886
            else
8887
              sum->used.fp |= mask;
8888
          }
8889
        }
8890
      break;
8891
 
8892
    case MEM:
8893
      if (set)
8894
        sum->defd.mem = 1;
8895
      else
8896
        sum->used.mem = 1;
8897
 
8898
      /* Find the regs used in memory address computation: */
8899
      summarize_insn (XEXP (x, 0), sum, 0);
8900
      break;
8901
 
8902
    case CONST_INT:   case CONST_DOUBLE:
8903
    case SYMBOL_REF:  case LABEL_REF:     case CONST:
8904
    case SCRATCH:     case ASM_INPUT:
8905
      break;
8906
 
8907
      /* Handle common unary and binary ops for efficiency.  */
8908
    case COMPARE:  case PLUS:    case MINUS:   case MULT:      case DIV:
8909
    case MOD:      case UDIV:    case UMOD:    case AND:       case IOR:
8910
    case XOR:      case ASHIFT:  case ROTATE:  case ASHIFTRT:  case LSHIFTRT:
8911
    case ROTATERT: case SMIN:    case SMAX:    case UMIN:      case UMAX:
8912
    case NE:       case EQ:      case GE:      case GT:        case LE:
8913
    case LT:       case GEU:     case GTU:     case LEU:       case LTU:
8914
      summarize_insn (XEXP (x, 0), sum, 0);
8915
      summarize_insn (XEXP (x, 1), sum, 0);
8916
      break;
8917
 
8918
    case NEG:  case NOT:  case SIGN_EXTEND:  case ZERO_EXTEND:
8919
    case TRUNCATE:  case FLOAT_EXTEND:  case FLOAT_TRUNCATE:  case FLOAT:
8920
    case FIX:  case UNSIGNED_FLOAT:  case UNSIGNED_FIX:  case ABS:
8921
    case SQRT:  case FFS:
8922
      summarize_insn (XEXP (x, 0), sum, 0);
8923
      break;
8924
 
8925
    default:
8926
      format_ptr = GET_RTX_FORMAT (GET_CODE (x));
8927
      for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
8928
        switch (format_ptr[i])
8929
          {
8930
          case 'e':
8931
            summarize_insn (XEXP (x, i), sum, 0);
8932
            break;
8933
 
8934
          case 'E':
8935
            for (j = XVECLEN (x, i) - 1; j >= 0; j--)
8936
              summarize_insn (XVECEXP (x, i, j), sum, 0);
8937
            break;
8938
 
8939
          case 'i':
8940
            break;
8941
 
8942
          default:
8943
            gcc_unreachable ();
8944
          }
8945
    }
8946
}
8947
 
8948
/* Ensure a sufficient number of `trapb' insns are in the code when
8949
   the user requests code with a trap precision of functions or
8950
   instructions.
8951
 
8952
   In naive mode, when the user requests a trap-precision of
8953
   "instruction", a trapb is needed after every instruction that may
8954
   generate a trap.  This ensures that the code is resumption safe but
8955
   it is also slow.
8956
 
8957
   When optimizations are turned on, we delay issuing a trapb as long
8958
   as possible.  In this context, a trap shadow is the sequence of
8959
   instructions that starts with a (potentially) trap generating
8960
   instruction and extends to the next trapb or call_pal instruction
8961
   (but GCC never generates call_pal by itself).  We can delay (and
8962
   therefore sometimes omit) a trapb subject to the following
8963
   conditions:
8964
 
8965
   (a) On entry to the trap shadow, if any Alpha register or memory
8966
   location contains a value that is used as an operand value by some
8967
   instruction in the trap shadow (live on entry), then no instruction
8968
   in the trap shadow may modify the register or memory location.
8969
 
8970
   (b) Within the trap shadow, the computation of the base register
8971
   for a memory load or store instruction may not involve using the
8972
   result of an instruction that might generate an UNPREDICTABLE
8973
   result.
8974
 
8975
   (c) Within the trap shadow, no register may be used more than once
8976
   as a destination register.  (This is to make life easier for the
8977
   trap-handler.)
8978
 
8979
   (d) The trap shadow may not include any branch instructions.  */
8980
 
8981
static void
8982
alpha_handle_trap_shadows (void)
8983
{
8984
  struct shadow_summary shadow;
8985
  int trap_pending, exception_nesting;
8986
  rtx i, n;
8987
 
8988
  trap_pending = 0;
8989
  exception_nesting = 0;
8990
  shadow.used.i = 0;
8991
  shadow.used.fp = 0;
8992
  shadow.used.mem = 0;
8993
  shadow.defd = shadow.used;
8994
 
8995
  for (i = get_insns (); i ; i = NEXT_INSN (i))
8996
    {
8997
      if (NOTE_P (i))
8998
        {
8999
          switch (NOTE_KIND (i))
9000
            {
9001
            case NOTE_INSN_EH_REGION_BEG:
9002
              exception_nesting++;
9003
              if (trap_pending)
9004
                goto close_shadow;
9005
              break;
9006
 
9007
            case NOTE_INSN_EH_REGION_END:
9008
              exception_nesting--;
9009
              if (trap_pending)
9010
                goto close_shadow;
9011
              break;
9012
 
9013
            case NOTE_INSN_EPILOGUE_BEG:
9014
              if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
9015
                goto close_shadow;
9016
              break;
9017
            }
9018
        }
9019
      else if (trap_pending)
9020
        {
9021
          if (alpha_tp == ALPHA_TP_FUNC)
9022
            {
9023
              if (JUMP_P (i)
9024
                  && GET_CODE (PATTERN (i)) == RETURN)
9025
                goto close_shadow;
9026
            }
9027
          else if (alpha_tp == ALPHA_TP_INSN)
9028
            {
9029
              if (optimize > 0)
9030
                {
9031
                  struct shadow_summary sum;
9032
 
9033
                  sum.used.i = 0;
9034
                  sum.used.fp = 0;
9035
                  sum.used.mem = 0;
9036
                  sum.defd = sum.used;
9037
 
9038
                  switch (GET_CODE (i))
9039
                    {
9040
                    case INSN:
9041
                      /* Annoyingly, get_attr_trap will die on these.  */
9042
                      if (GET_CODE (PATTERN (i)) == USE
9043
                          || GET_CODE (PATTERN (i)) == CLOBBER)
9044
                        break;
9045
 
9046
                      summarize_insn (PATTERN (i), &sum, 0);
9047
 
9048
                      if ((sum.defd.i & shadow.defd.i)
9049
                          || (sum.defd.fp & shadow.defd.fp))
9050
                        {
9051
                          /* (c) would be violated */
9052
                          goto close_shadow;
9053
                        }
9054
 
9055
                      /* Combine shadow with summary of current insn: */
9056
                      shadow.used.i   |= sum.used.i;
9057
                      shadow.used.fp  |= sum.used.fp;
9058
                      shadow.used.mem |= sum.used.mem;
9059
                      shadow.defd.i   |= sum.defd.i;
9060
                      shadow.defd.fp  |= sum.defd.fp;
9061
                      shadow.defd.mem |= sum.defd.mem;
9062
 
9063
                      if ((sum.defd.i & shadow.used.i)
9064
                          || (sum.defd.fp & shadow.used.fp)
9065
                          || (sum.defd.mem & shadow.used.mem))
9066
                        {
9067
                          /* (a) would be violated (also takes care of (b))  */
9068
                          gcc_assert (get_attr_trap (i) != TRAP_YES
9069
                                      || (!(sum.defd.i & sum.used.i)
9070
                                          && !(sum.defd.fp & sum.used.fp)));
9071
 
9072
                          goto close_shadow;
9073
                        }
9074
                      break;
9075
 
9076
                    case JUMP_INSN:
9077
                    case CALL_INSN:
9078
                    case CODE_LABEL:
9079
                      goto close_shadow;
9080
 
9081
                    default:
9082
                      gcc_unreachable ();
9083
                    }
9084
                }
9085
              else
9086
                {
9087
                close_shadow:
9088
                  n = emit_insn_before (gen_trapb (), i);
9089
                  PUT_MODE (n, TImode);
9090
                  PUT_MODE (i, TImode);
9091
                  trap_pending = 0;
9092
                  shadow.used.i = 0;
9093
                  shadow.used.fp = 0;
9094
                  shadow.used.mem = 0;
9095
                  shadow.defd = shadow.used;
9096
                }
9097
            }
9098
        }
9099
 
9100
      if ((exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
9101
          && NONJUMP_INSN_P (i)
9102
          && GET_CODE (PATTERN (i)) != USE
9103
          && GET_CODE (PATTERN (i)) != CLOBBER
9104
          && get_attr_trap (i) == TRAP_YES)
9105
        {
9106
          if (optimize && !trap_pending)
9107
            summarize_insn (PATTERN (i), &shadow, 0);
9108
          trap_pending = 1;
9109
        }
9110
    }
9111
}
9112
 
9113
/* Alpha can only issue instruction groups simultaneously if they are
9114
   suitably aligned.  This is very processor-specific.  */
9115
/* There are a number of entries in alphaev4_insn_pipe and alphaev5_insn_pipe
9116
   that are marked "fake".  These instructions do not exist on that target,
9117
   but it is possible to see these insns with deranged combinations of
9118
   command-line options, such as "-mtune=ev4 -mmax".  Instead of aborting,
9119
   choose a result at random.  */
9120
 
9121
enum alphaev4_pipe {
9122
  EV4_STOP = 0,
9123
  EV4_IB0 = 1,
9124
  EV4_IB1 = 2,
9125
  EV4_IBX = 4
9126
};
9127
 
9128
enum alphaev5_pipe {
9129
  EV5_STOP = 0,
9130
  EV5_NONE = 1,
9131
  EV5_E01 = 2,
9132
  EV5_E0 = 4,
9133
  EV5_E1 = 8,
9134
  EV5_FAM = 16,
9135
  EV5_FA = 32,
9136
  EV5_FM = 64
9137
};
9138
 
9139
static enum alphaev4_pipe
9140
alphaev4_insn_pipe (rtx insn)
9141
{
9142
  if (recog_memoized (insn) < 0)
9143
    return EV4_STOP;
9144
  if (get_attr_length (insn) != 4)
9145
    return EV4_STOP;
9146
 
9147
  switch (get_attr_type (insn))
9148
    {
9149
    case TYPE_ILD:
9150
    case TYPE_LDSYM:
9151
    case TYPE_FLD:
9152
    case TYPE_LD_L:
9153
      return EV4_IBX;
9154
 
9155
    case TYPE_IADD:
9156
    case TYPE_ILOG:
9157
    case TYPE_ICMOV:
9158
    case TYPE_ICMP:
9159
    case TYPE_FST:
9160
    case TYPE_SHIFT:
9161
    case TYPE_IMUL:
9162
    case TYPE_FBR:
9163
    case TYPE_MVI:              /* fake */
9164
      return EV4_IB0;
9165
 
9166
    case TYPE_IST:
9167
    case TYPE_MISC:
9168
    case TYPE_IBR:
9169
    case TYPE_JSR:
9170
    case TYPE_CALLPAL:
9171
    case TYPE_FCPYS:
9172
    case TYPE_FCMOV:
9173
    case TYPE_FADD:
9174
    case TYPE_FDIV:
9175
    case TYPE_FMUL:
9176
    case TYPE_ST_C:
9177
    case TYPE_MB:
9178
    case TYPE_FSQRT:            /* fake */
9179
    case TYPE_FTOI:             /* fake */
9180
    case TYPE_ITOF:             /* fake */
9181
      return EV4_IB1;
9182
 
9183
    default:
9184
      gcc_unreachable ();
9185
    }
9186
}
9187
 
9188
static enum alphaev5_pipe
9189
alphaev5_insn_pipe (rtx insn)
9190
{
9191
  if (recog_memoized (insn) < 0)
9192
    return EV5_STOP;
9193
  if (get_attr_length (insn) != 4)
9194
    return EV5_STOP;
9195
 
9196
  switch (get_attr_type (insn))
9197
    {
9198
    case TYPE_ILD:
9199
    case TYPE_FLD:
9200
    case TYPE_LDSYM:
9201
    case TYPE_IADD:
9202
    case TYPE_ILOG:
9203
    case TYPE_ICMOV:
9204
    case TYPE_ICMP:
9205
      return EV5_E01;
9206
 
9207
    case TYPE_IST:
9208
    case TYPE_FST:
9209
    case TYPE_SHIFT:
9210
    case TYPE_IMUL:
9211
    case TYPE_MISC:
9212
    case TYPE_MVI:
9213
    case TYPE_LD_L:
9214
    case TYPE_ST_C:
9215
    case TYPE_MB:
9216
    case TYPE_FTOI:             /* fake */
9217
    case TYPE_ITOF:             /* fake */
9218
      return EV5_E0;
9219
 
9220
    case TYPE_IBR:
9221
    case TYPE_JSR:
9222
    case TYPE_CALLPAL:
9223
      return EV5_E1;
9224
 
9225
    case TYPE_FCPYS:
9226
      return EV5_FAM;
9227
 
9228
    case TYPE_FBR:
9229
    case TYPE_FCMOV:
9230
    case TYPE_FADD:
9231
    case TYPE_FDIV:
9232
    case TYPE_FSQRT:            /* fake */
9233
      return EV5_FA;
9234
 
9235
    case TYPE_FMUL:
9236
      return EV5_FM;
9237
 
9238
    default:
9239
      gcc_unreachable ();
9240
    }
9241
}
9242
 
9243
/* IN_USE is a mask of the slots currently filled within the insn group.
9244
   The mask bits come from alphaev4_pipe above.  If EV4_IBX is set, then
9245
   the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1.
9246
 
9247
   LEN is, of course, the length of the group in bytes.  */
9248
 
9249
static rtx
9250
alphaev4_next_group (rtx insn, int *pin_use, int *plen)
9251
{
9252
  int len, in_use;
9253
 
9254
  len = in_use = 0;
9255
 
9256
  if (! INSN_P (insn)
9257
      || GET_CODE (PATTERN (insn)) == CLOBBER
9258
      || GET_CODE (PATTERN (insn)) == USE)
9259
    goto next_and_done;
9260
 
9261
  while (1)
9262
    {
9263
      enum alphaev4_pipe pipe;
9264
 
9265
      pipe = alphaev4_insn_pipe (insn);
9266
      switch (pipe)
9267
        {
9268
        case EV4_STOP:
9269
          /* Force complex instructions to start new groups.  */
9270
          if (in_use)
9271
            goto done;
9272
 
9273
          /* If this is a completely unrecognized insn, it's an asm.
9274
             We don't know how long it is, so record length as -1 to
9275
             signal a needed realignment.  */
9276
          if (recog_memoized (insn) < 0)
9277
            len = -1;
9278
          else
9279
            len = get_attr_length (insn);
9280
          goto next_and_done;
9281
 
9282
        case EV4_IBX:
9283
          if (in_use & EV4_IB0)
9284
            {
9285
              if (in_use & EV4_IB1)
9286
                goto done;
9287
              in_use |= EV4_IB1;
9288
            }
9289
          else
9290
            in_use |= EV4_IB0 | EV4_IBX;
9291
          break;
9292
 
9293
        case EV4_IB0:
9294
          if (in_use & EV4_IB0)
9295
            {
9296
              if (!(in_use & EV4_IBX) || (in_use & EV4_IB1))
9297
                goto done;
9298
              in_use |= EV4_IB1;
9299
            }
9300
          in_use |= EV4_IB0;
9301
          break;
9302
 
9303
        case EV4_IB1:
9304
          if (in_use & EV4_IB1)
9305
            goto done;
9306
          in_use |= EV4_IB1;
9307
          break;
9308
 
9309
        default:
9310
          gcc_unreachable ();
9311
        }
9312
      len += 4;
9313
 
9314
      /* Haifa doesn't do well scheduling branches.  */
9315
      if (JUMP_P (insn))
9316
        goto next_and_done;
9317
 
9318
    next:
9319
      insn = next_nonnote_insn (insn);
9320
 
9321
      if (!insn || ! INSN_P (insn))
9322
        goto done;
9323
 
9324
      /* Let Haifa tell us where it thinks insn group boundaries are.  */
9325
      if (GET_MODE (insn) == TImode)
9326
        goto done;
9327
 
9328
      if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
9329
        goto next;
9330
    }
9331
 
9332
 next_and_done:
9333
  insn = next_nonnote_insn (insn);
9334
 
9335
 done:
9336
  *plen = len;
9337
  *pin_use = in_use;
9338
  return insn;
9339
}
9340
 
9341
/* IN_USE is a mask of the slots currently filled within the insn group.
9342
   The mask bits come from alphaev5_pipe above.  If EV5_E01 is set, then
9343
   the insn in EV5_E0 can be swapped by the hardware into EV5_E1.
9344
 
9345
   LEN is, of course, the length of the group in bytes.  */
9346
 
9347
static rtx
9348
alphaev5_next_group (rtx insn, int *pin_use, int *plen)
9349
{
9350
  int len, in_use;
9351
 
9352
  len = in_use = 0;
9353
 
9354
  if (! INSN_P (insn)
9355
      || GET_CODE (PATTERN (insn)) == CLOBBER
9356
      || GET_CODE (PATTERN (insn)) == USE)
9357
    goto next_and_done;
9358
 
9359
  while (1)
9360
    {
9361
      enum alphaev5_pipe pipe;
9362
 
9363
      pipe = alphaev5_insn_pipe (insn);
9364
      switch (pipe)
9365
        {
9366
        case EV5_STOP:
9367
          /* Force complex instructions to start new groups.  */
9368
          if (in_use)
9369
            goto done;
9370
 
9371
          /* If this is a completely unrecognized insn, it's an asm.
9372
             We don't know how long it is, so record length as -1 to
9373
             signal a needed realignment.  */
9374
          if (recog_memoized (insn) < 0)
9375
            len = -1;
9376
          else
9377
            len = get_attr_length (insn);
9378
          goto next_and_done;
9379
 
9380
        /* ??? Most of the places below, we would like to assert never
9381
           happen, as it would indicate an error either in Haifa, or
9382
           in the scheduling description.  Unfortunately, Haifa never
9383
           schedules the last instruction of the BB, so we don't have
9384
           an accurate TI bit to go off.  */
9385
        case EV5_E01:
9386
          if (in_use & EV5_E0)
9387
            {
9388
              if (in_use & EV5_E1)
9389
                goto done;
9390
              in_use |= EV5_E1;
9391
            }
9392
          else
9393
            in_use |= EV5_E0 | EV5_E01;
9394
          break;
9395
 
9396
        case EV5_E0:
9397
          if (in_use & EV5_E0)
9398
            {
9399
              if (!(in_use & EV5_E01) || (in_use & EV5_E1))
9400
                goto done;
9401
              in_use |= EV5_E1;
9402
            }
9403
          in_use |= EV5_E0;
9404
          break;
9405
 
9406
        case EV5_E1:
9407
          if (in_use & EV5_E1)
9408
            goto done;
9409
          in_use |= EV5_E1;
9410
          break;
9411
 
9412
        case EV5_FAM:
9413
          if (in_use & EV5_FA)
9414
            {
9415
              if (in_use & EV5_FM)
9416
                goto done;
9417
              in_use |= EV5_FM;
9418
            }
9419
          else
9420
            in_use |= EV5_FA | EV5_FAM;
9421
          break;
9422
 
9423
        case EV5_FA:
9424
          if (in_use & EV5_FA)
9425
            goto done;
9426
          in_use |= EV5_FA;
9427
          break;
9428
 
9429
        case EV5_FM:
9430
          if (in_use & EV5_FM)
9431
            goto done;
9432
          in_use |= EV5_FM;
9433
          break;
9434
 
9435
        case EV5_NONE:
9436
          break;
9437
 
9438
        default:
9439
          gcc_unreachable ();
9440
        }
9441
      len += 4;
9442
 
9443
      /* Haifa doesn't do well scheduling branches.  */
9444
      /* ??? If this is predicted not-taken, slotting continues, except
9445
         that no more IBR, FBR, or JSR insns may be slotted.  */
9446
      if (JUMP_P (insn))
9447
        goto next_and_done;
9448
 
9449
    next:
9450
      insn = next_nonnote_insn (insn);
9451
 
9452
      if (!insn || ! INSN_P (insn))
9453
        goto done;
9454
 
9455
      /* Let Haifa tell us where it thinks insn group boundaries are.  */
9456
      if (GET_MODE (insn) == TImode)
9457
        goto done;
9458
 
9459
      if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE)
9460
        goto next;
9461
    }
9462
 
9463
 next_and_done:
9464
  insn = next_nonnote_insn (insn);
9465
 
9466
 done:
9467
  *plen = len;
9468
  *pin_use = in_use;
9469
  return insn;
9470
}
9471
 
9472
static rtx
9473
alphaev4_next_nop (int *pin_use)
9474
{
9475
  int in_use = *pin_use;
9476
  rtx nop;
9477
 
9478
  if (!(in_use & EV4_IB0))
9479
    {
9480
      in_use |= EV4_IB0;
9481
      nop = gen_nop ();
9482
    }
9483
  else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX)
9484
    {
9485
      in_use |= EV4_IB1;
9486
      nop = gen_nop ();
9487
    }
9488
  else if (TARGET_FP && !(in_use & EV4_IB1))
9489
    {
9490
      in_use |= EV4_IB1;
9491
      nop = gen_fnop ();
9492
    }
9493
  else
9494
    nop = gen_unop ();
9495
 
9496
  *pin_use = in_use;
9497
  return nop;
9498
}
9499
 
9500
static rtx
9501
alphaev5_next_nop (int *pin_use)
9502
{
9503
  int in_use = *pin_use;
9504
  rtx nop;
9505
 
9506
  if (!(in_use & EV5_E1))
9507
    {
9508
      in_use |= EV5_E1;
9509
      nop = gen_nop ();
9510
    }
9511
  else if (TARGET_FP && !(in_use & EV5_FA))
9512
    {
9513
      in_use |= EV5_FA;
9514
      nop = gen_fnop ();
9515
    }
9516
  else if (TARGET_FP && !(in_use & EV5_FM))
9517
    {
9518
      in_use |= EV5_FM;
9519
      nop = gen_fnop ();
9520
    }
9521
  else
9522
    nop = gen_unop ();
9523
 
9524
  *pin_use = in_use;
9525
  return nop;
9526
}
9527
 
9528
/* The instruction group alignment main loop.  */
9529
 
9530
static void
9531
alpha_align_insns (unsigned int max_align,
9532
                   rtx (*next_group) (rtx, int *, int *),
9533
                   rtx (*next_nop) (int *))
9534
{
9535
  /* ALIGN is the known alignment for the insn group.  */
9536
  unsigned int align;
9537
  /* OFS is the offset of the current insn in the insn group.  */
9538
  int ofs;
9539
  int prev_in_use, in_use, len, ldgp;
9540
  rtx i, next;
9541
 
9542
  /* Let shorten branches care for assigning alignments to code labels.  */
9543
  shorten_branches (get_insns ());
9544
 
9545
  if (align_functions < 4)
9546
    align = 4;
9547
  else if ((unsigned int) align_functions < max_align)
9548
    align = align_functions;
9549
  else
9550
    align = max_align;
9551
 
9552
  ofs = prev_in_use = 0;
9553
  i = get_insns ();
9554
  if (NOTE_P (i))
9555
    i = next_nonnote_insn (i);
9556
 
9557
  ldgp = alpha_function_needs_gp ? 8 : 0;
9558
 
9559
  while (i)
9560
    {
9561
      next = (*next_group) (i, &in_use, &len);
9562
 
9563
      /* When we see a label, resync alignment etc.  */
9564
      if (LABEL_P (i))
9565
        {
9566
          unsigned int new_align = 1 << label_to_alignment (i);
9567
 
9568
          if (new_align >= align)
9569
            {
9570
              align = new_align < max_align ? new_align : max_align;
9571
              ofs = 0;
9572
            }
9573
 
9574
          else if (ofs & (new_align-1))
9575
            ofs = (ofs | (new_align-1)) + 1;
9576
          gcc_assert (!len);
9577
        }
9578
 
9579
      /* Handle complex instructions special.  */
9580
      else if (in_use == 0)
9581
        {
9582
          /* Asms will have length < 0.  This is a signal that we have
9583
             lost alignment knowledge.  Assume, however, that the asm
9584
             will not mis-align instructions.  */
9585
          if (len < 0)
9586
            {
9587
              ofs = 0;
9588
              align = 4;
9589
              len = 0;
9590
            }
9591
        }
9592
 
9593
      /* If the known alignment is smaller than the recognized insn group,
9594
         realign the output.  */
9595
      else if ((int) align < len)
9596
        {
9597
          unsigned int new_log_align = len > 8 ? 4 : 3;
9598
          rtx prev, where;
9599
 
9600
          where = prev = prev_nonnote_insn (i);
9601
          if (!where || !LABEL_P (where))
9602
            where = i;
9603
 
9604
          /* Can't realign between a call and its gp reload.  */
9605
          if (! (TARGET_EXPLICIT_RELOCS
9606
                 && prev && CALL_P (prev)))
9607
            {
9608
              emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
9609
              align = 1 << new_log_align;
9610
              ofs = 0;
9611
            }
9612
        }
9613
 
9614
      /* We may not insert padding inside the initial ldgp sequence.  */
9615
      else if (ldgp > 0)
9616
        ldgp -= len;
9617
 
9618
      /* If the group won't fit in the same INT16 as the previous,
9619
         we need to add padding to keep the group together.  Rather
9620
         than simply leaving the insn filling to the assembler, we
9621
         can make use of the knowledge of what sorts of instructions
9622
         were issued in the previous group to make sure that all of
9623
         the added nops are really free.  */
9624
      else if (ofs + len > (int) align)
9625
        {
9626
          int nop_count = (align - ofs) / 4;
9627
          rtx where;
9628
 
9629
          /* Insert nops before labels, branches, and calls to truly merge
9630
             the execution of the nops with the previous instruction group.  */
9631
          where = prev_nonnote_insn (i);
9632
          if (where)
9633
            {
9634
              if (LABEL_P (where))
9635
                {
9636
                  rtx where2 = prev_nonnote_insn (where);
9637
                  if (where2 && JUMP_P (where2))
9638
                    where = where2;
9639
                }
9640
              else if (NONJUMP_INSN_P (where))
9641
                where = i;
9642
            }
9643
          else
9644
            where = i;
9645
 
9646
          do
9647
            emit_insn_before ((*next_nop)(&prev_in_use), where);
9648
          while (--nop_count);
9649
          ofs = 0;
9650
        }
9651
 
9652
      ofs = (ofs + len) & (align - 1);
9653
      prev_in_use = in_use;
9654
      i = next;
9655
    }
9656
}
9657
 
9658
/* Insert an unop between a noreturn function call and GP load.  */
9659
 
9660
static void
9661
alpha_pad_noreturn (void)
9662
{
9663
  rtx insn, next;
9664
 
9665
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9666
    {
9667
      if (!CALL_P (insn)
9668
          || !find_reg_note (insn, REG_NORETURN, NULL_RTX))
9669
        continue;
9670
 
9671
      next = next_active_insn (insn);
9672
 
9673
      if (next)
9674
        {
9675
          rtx pat = PATTERN (next);
9676
 
9677
          if (GET_CODE (pat) == SET
9678
              && GET_CODE (SET_SRC (pat)) == UNSPEC_VOLATILE
9679
              && XINT (SET_SRC (pat), 1) == UNSPECV_LDGP1)
9680
            emit_insn_after (gen_unop (), insn);
9681
        }
9682
    }
9683
}
9684
 
9685
/* Machine dependent reorg pass.  */
9686
 
9687
static void
9688
alpha_reorg (void)
9689
{
9690
  /* Workaround for a linker error that triggers when an
9691
     exception handler immediatelly follows a noreturn function.
9692
 
9693
     The instruction stream from an object file:
9694
 
9695
  54:   00 40 5b 6b     jsr     ra,(t12),58 <__func+0x58>
9696
  58:   00 00 ba 27     ldah    gp,0(ra)
9697
  5c:   00 00 bd 23     lda     gp,0(gp)
9698
  60:   00 00 7d a7     ldq     t12,0(gp)
9699
  64:   00 40 5b 6b     jsr     ra,(t12),68 <__func+0x68>
9700
 
9701
     was converted in the final link pass to:
9702
 
9703
   fdb24:       a0 03 40 d3     bsr     ra,fe9a8 <_called_func+0x8>
9704
   fdb28:       00 00 fe 2f     unop
9705
   fdb2c:       00 00 fe 2f     unop
9706
   fdb30:       30 82 7d a7     ldq     t12,-32208(gp)
9707
   fdb34:       00 40 5b 6b     jsr     ra,(t12),fdb38 <__func+0x68>
9708
 
9709
     GP load instructions were wrongly cleared by the linker relaxation
9710
     pass.  This workaround prevents removal of GP loads by inserting
9711
     an unop instruction between a noreturn function call and
9712
     exception handler prologue.  */
9713
 
9714
  if (current_function_has_exception_handlers ())
9715
    alpha_pad_noreturn ();
9716
 
9717
  if (alpha_tp != ALPHA_TP_PROG || flag_exceptions)
9718
    alpha_handle_trap_shadows ();
9719
 
9720
  /* Due to the number of extra trapb insns, don't bother fixing up
9721
     alignment when trap precision is instruction.  Moreover, we can
9722
     only do our job when sched2 is run.  */
9723
  if (optimize && !optimize_size
9724
      && alpha_tp != ALPHA_TP_INSN
9725
      && flag_schedule_insns_after_reload)
9726
    {
9727
      if (alpha_tune == PROCESSOR_EV4)
9728
        alpha_align_insns (8, alphaev4_next_group, alphaev4_next_nop);
9729
      else if (alpha_tune == PROCESSOR_EV5)
9730
        alpha_align_insns (16, alphaev5_next_group, alphaev5_next_nop);
9731
    }
9732
}
9733
 
9734
#if !TARGET_ABI_UNICOSMK
9735
 
9736
#ifdef HAVE_STAMP_H
9737
#include <stamp.h>
9738
#endif
9739
 
9740
static void
9741
alpha_file_start (void)
9742
{
9743
#ifdef OBJECT_FORMAT_ELF
9744
  /* If emitting dwarf2 debug information, we cannot generate a .file
9745
     directive to start the file, as it will conflict with dwarf2out
9746
     file numbers.  So it's only useful when emitting mdebug output.  */
9747
  targetm.file_start_file_directive = (write_symbols == DBX_DEBUG);
9748
#endif
9749
 
9750
  default_file_start ();
9751
#ifdef MS_STAMP
9752
  fprintf (asm_out_file, "\t.verstamp %d %d\n", MS_STAMP, LS_STAMP);
9753
#endif
9754
 
9755
  fputs ("\t.set noreorder\n", asm_out_file);
9756
  fputs ("\t.set volatile\n", asm_out_file);
9757
  if (!TARGET_ABI_OPEN_VMS)
9758
    fputs ("\t.set noat\n", asm_out_file);
9759
  if (TARGET_EXPLICIT_RELOCS)
9760
    fputs ("\t.set nomacro\n", asm_out_file);
9761
  if (TARGET_SUPPORT_ARCH | TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX)
9762
    {
9763
      const char *arch;
9764
 
9765
      if (alpha_cpu == PROCESSOR_EV6 || TARGET_FIX || TARGET_CIX)
9766
        arch = "ev6";
9767
      else if (TARGET_MAX)
9768
        arch = "pca56";
9769
      else if (TARGET_BWX)
9770
        arch = "ev56";
9771
      else if (alpha_cpu == PROCESSOR_EV5)
9772
        arch = "ev5";
9773
      else
9774
        arch = "ev4";
9775
 
9776
      fprintf (asm_out_file, "\t.arch %s\n", arch);
9777
    }
9778
}
9779
#endif
9780
 
9781
#ifdef OBJECT_FORMAT_ELF
9782
/* Since we don't have a .dynbss section, we should not allow global
9783
   relocations in the .rodata section.  */
9784
 
9785
static int
9786
alpha_elf_reloc_rw_mask (void)
9787
{
9788
  return flag_pic ? 3 : 2;
9789
}
9790
 
9791
/* Return a section for X.  The only special thing we do here is to
9792
   honor small data.  */
9793
 
9794
static section *
9795
alpha_elf_select_rtx_section (enum machine_mode mode, rtx x,
9796
                              unsigned HOST_WIDE_INT align)
9797
{
9798
  if (TARGET_SMALL_DATA && GET_MODE_SIZE (mode) <= g_switch_value)
9799
    /* ??? Consider using mergeable sdata sections.  */
9800
    return sdata_section;
9801
  else
9802
    return default_elf_select_rtx_section (mode, x, align);
9803
}
9804
 
9805
static unsigned int
9806
alpha_elf_section_type_flags (tree decl, const char *name, int reloc)
9807
{
9808
  unsigned int flags = 0;
9809
 
9810
  if (strcmp (name, ".sdata") == 0
9811
      || strncmp (name, ".sdata.", 7) == 0
9812
      || strncmp (name, ".gnu.linkonce.s.", 16) == 0
9813
      || strcmp (name, ".sbss") == 0
9814
      || strncmp (name, ".sbss.", 6) == 0
9815
      || strncmp (name, ".gnu.linkonce.sb.", 17) == 0)
9816
    flags = SECTION_SMALL;
9817
 
9818
  flags |= default_section_type_flags (decl, name, reloc);
9819
  return flags;
9820
}
9821
#endif /* OBJECT_FORMAT_ELF */
9822
 
9823
/* Structure to collect function names for final output in link section.  */
9824
/* Note that items marked with GTY can't be ifdef'ed out.  */
9825
 
9826
enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
9827
enum reloc_kind {KIND_LINKAGE, KIND_CODEADDR};
9828
 
9829
struct GTY(()) alpha_links
9830
{
9831
  int num;
9832
  const char *target;
9833
  rtx linkage;
9834
  enum links_kind lkind;
9835
  enum reloc_kind rkind;
9836
};
9837
 
9838
struct GTY(()) alpha_funcs
9839
{
9840
  int num;
9841
  splay_tree GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9842
    links;
9843
};
9844
 
9845
static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
9846
  splay_tree alpha_links_tree;
9847
static GTY ((param1_is (tree), param2_is (struct alpha_funcs *)))
9848
  splay_tree alpha_funcs_tree;
9849
 
9850
static GTY(()) int alpha_funcs_num;
9851
 
9852
#if TARGET_ABI_OPEN_VMS
9853
 
9854
/* Return the VMS argument type corresponding to MODE.  */
9855
 
9856
enum avms_arg_type
9857
alpha_arg_type (enum machine_mode mode)
9858
{
9859
  switch (mode)
9860
    {
9861
    case SFmode:
9862
      return TARGET_FLOAT_VAX ? FF : FS;
9863
    case DFmode:
9864
      return TARGET_FLOAT_VAX ? FD : FT;
9865
    default:
9866
      return I64;
9867
    }
9868
}
9869
 
9870
/* Return an rtx for an integer representing the VMS Argument Information
9871
   register value.  */
9872
 
9873
rtx
9874
alpha_arg_info_reg_val (CUMULATIVE_ARGS cum)
9875
{
9876
  unsigned HOST_WIDE_INT regval = cum.num_args;
9877
  int i;
9878
 
9879
  for (i = 0; i < 6; i++)
9880
    regval |= ((int) cum.atypes[i]) << (i * 3 + 8);
9881
 
9882
  return GEN_INT (regval);
9883
}
9884
 
9885
/* Register the need for a (fake) .linkage entry for calls to function NAME.
9886
   IS_LOCAL is 1 if this is for a definition, 0 if this is for a real call.
9887
   Return a SYMBOL_REF suited to the call instruction.  */
9888
 
9889
rtx
9890
alpha_need_linkage (const char *name, int is_local)
9891
{
9892
  splay_tree_node node;
9893
  struct alpha_links *al;
9894
  const char *target;
9895
  tree id;
9896
 
9897
  if (name[0] == '*')
9898
    name++;
9899
 
9900
  if (is_local)
9901
    {
9902
      struct alpha_funcs *cfaf;
9903
 
9904
      if (!alpha_funcs_tree)
9905
        alpha_funcs_tree = splay_tree_new_ggc ((splay_tree_compare_fn)
9906
                                               splay_tree_compare_pointers);
9907
 
9908
      cfaf = (struct alpha_funcs *) ggc_alloc (sizeof (struct alpha_funcs));
9909
 
9910
      cfaf->links = 0;
9911
      cfaf->num = ++alpha_funcs_num;
9912
 
9913
      splay_tree_insert (alpha_funcs_tree,
9914
                         (splay_tree_key) current_function_decl,
9915
                         (splay_tree_value) cfaf);
9916
    }
9917
 
9918
  if (alpha_links_tree)
9919
    {
9920
      /* Is this name already defined?  */
9921
 
9922
      node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
9923
      if (node)
9924
        {
9925
          al = (struct alpha_links *) node->value;
9926
          if (is_local)
9927
            {
9928
              /* Defined here but external assumed.  */
9929
              if (al->lkind == KIND_EXTERN)
9930
                al->lkind = KIND_LOCAL;
9931
            }
9932
          else
9933
            {
9934
              /* Used here but unused assumed.  */
9935
              if (al->lkind == KIND_UNUSED)
9936
                al->lkind = KIND_LOCAL;
9937
            }
9938
          return al->linkage;
9939
        }
9940
    }
9941
  else
9942
    alpha_links_tree = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
9943
 
9944
  al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
9945
  name = ggc_strdup (name);
9946
 
9947
  /* Assume external if no definition.  */
9948
  al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
9949
 
9950
  /* Ensure we have an IDENTIFIER so assemble_name can mark it used
9951
     and find the ultimate alias target like assemble_name.  */
9952
  id = get_identifier (name);
9953
  target = NULL;
9954
  while (IDENTIFIER_TRANSPARENT_ALIAS (id))
9955
    {
9956
      id = TREE_CHAIN (id);
9957
      target = IDENTIFIER_POINTER (id);
9958
    }
9959
 
9960
  al->target = target ? target : name;
9961
  al->linkage = gen_rtx_SYMBOL_REF (Pmode, name);
9962
 
9963
  splay_tree_insert (alpha_links_tree, (splay_tree_key) name,
9964
                     (splay_tree_value) al);
9965
 
9966
  return al->linkage;
9967
}
9968
 
9969
/* Return a SYMBOL_REF representing the reference to the .linkage entry
9970
   of function FUNC built for calls made from CFUNDECL.  LFLAG is 1 if
9971
   this is the reference to the linkage pointer value, 0 if this is the
9972
   reference to the function entry value.  RFLAG is 1 if this a reduced
9973
   reference (code address only), 0 if this is a full reference.  */
9974
 
9975
rtx
9976
alpha_use_linkage (rtx func, tree cfundecl, int lflag, int rflag)
9977
{
9978
  splay_tree_node cfunnode;
9979
  struct alpha_funcs *cfaf;
9980
  struct alpha_links *al;
9981
  const char *name = XSTR (func, 0);
9982
 
9983
  cfaf = (struct alpha_funcs *) 0;
9984
  al = (struct alpha_links *) 0;
9985
 
9986
  cfunnode = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) cfundecl);
9987
  cfaf = (struct alpha_funcs *) cfunnode->value;
9988
 
9989
  if (cfaf->links)
9990
    {
9991
      splay_tree_node lnode;
9992
 
9993
      /* Is this name already defined?  */
9994
 
9995
      lnode = splay_tree_lookup (cfaf->links, (splay_tree_key) name);
9996
      if (lnode)
9997
        al = (struct alpha_links *) lnode->value;
9998
    }
9999
  else
10000
    cfaf->links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
10001
 
10002
  if (!al)
10003
    {
10004
      size_t name_len;
10005
      size_t buflen;
10006
      char *linksym;
10007
      splay_tree_node node = 0;
10008
      struct alpha_links *anl;
10009
 
10010
      if (name[0] == '*')
10011
        name++;
10012
 
10013
      name_len = strlen (name);
10014
      linksym = (char *) alloca (name_len + 50);
10015
 
10016
      al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
10017
      al->num = cfaf->num;
10018
 
10019
      node = splay_tree_lookup (alpha_links_tree, (splay_tree_key) name);
10020
      if (node)
10021
        {
10022
          anl = (struct alpha_links *) node->value;
10023
          al->lkind = anl->lkind;
10024
          name = anl->target;
10025
        }
10026
 
10027
      sprintf (linksym, "$%d..%s..lk", cfaf->num, name);
10028
      buflen = strlen (linksym);
10029
 
10030
      al->linkage = gen_rtx_SYMBOL_REF
10031
        (Pmode, ggc_alloc_string (linksym, buflen + 1));
10032
 
10033
      splay_tree_insert (cfaf->links, (splay_tree_key) name,
10034
                         (splay_tree_value) al);
10035
    }
10036
 
10037
  if (rflag)
10038
    al->rkind = KIND_CODEADDR;
10039
  else
10040
    al->rkind = KIND_LINKAGE;
10041
 
10042
  if (lflag)
10043
    return gen_rtx_MEM (Pmode, plus_constant (al->linkage, 8));
10044
  else
10045
    return al->linkage;
10046
}
10047
 
10048
static int
10049
alpha_write_one_linkage (splay_tree_node node, void *data)
10050
{
10051
  const char *const name = (const char *) node->key;
10052
  struct alpha_links *link = (struct alpha_links *) node->value;
10053
  FILE *stream = (FILE *) data;
10054
 
10055
  fprintf (stream, "$%d..%s..lk:\n", link->num, name);
10056
  if (link->rkind == KIND_CODEADDR)
10057
    {
10058
      if (link->lkind == KIND_LOCAL)
10059
        {
10060
          /* Local and used */
10061
          fprintf (stream, "\t.quad %s..en\n", name);
10062
        }
10063
      else
10064
        {
10065
          /* External and used, request code address.  */
10066
          fprintf (stream, "\t.code_address %s\n", name);
10067
        }
10068
    }
10069
  else
10070
    {
10071
      if (link->lkind == KIND_LOCAL)
10072
        {
10073
          /* Local and used, build linkage pair.  */
10074
          fprintf (stream, "\t.quad %s..en\n", name);
10075
          fprintf (stream, "\t.quad %s\n", name);
10076
        }
10077
      else
10078
        {
10079
          /* External and used, request linkage pair.  */
10080
          fprintf (stream, "\t.linkage %s\n", name);
10081
        }
10082
    }
10083
 
10084
  return 0;
10085
}
10086
 
10087
static void
10088
alpha_write_linkage (FILE *stream, const char *funname, tree fundecl)
10089
{
10090
  splay_tree_node node;
10091
  struct alpha_funcs *func;
10092
 
10093
  fprintf (stream, "\t.link\n");
10094
  fprintf (stream, "\t.align 3\n");
10095
  in_section = NULL;
10096
 
10097
  node = splay_tree_lookup (alpha_funcs_tree, (splay_tree_key) fundecl);
10098
  func = (struct alpha_funcs *) node->value;
10099
 
10100
  fputs ("\t.name ", stream);
10101
  assemble_name (stream, funname);
10102
  fputs ("..na\n", stream);
10103
  ASM_OUTPUT_LABEL (stream, funname);
10104
  fprintf (stream, "\t.pdesc ");
10105
  assemble_name (stream, funname);
10106
  fprintf (stream, "..en,%s\n",
10107
           alpha_procedure_type == PT_STACK ? "stack"
10108
           : alpha_procedure_type == PT_REGISTER ? "reg" : "null");
10109
 
10110
  if (func->links)
10111
    {
10112
      splay_tree_foreach (func->links, alpha_write_one_linkage, stream);
10113
      /* splay_tree_delete (func->links); */
10114
    }
10115
}
10116
 
10117
/* Switch to an arbitrary section NAME with attributes as specified
10118
   by FLAGS.  ALIGN specifies any known alignment requirements for
10119
   the section; 0 if the default should be used.  */
10120
 
10121
static void
10122
vms_asm_named_section (const char *name, unsigned int flags,
10123
                       tree decl ATTRIBUTE_UNUSED)
10124
{
10125
  fputc ('\n', asm_out_file);
10126
  fprintf (asm_out_file, ".section\t%s", name);
10127
 
10128
  if (flags & SECTION_DEBUG)
10129
    fprintf (asm_out_file, ",NOWRT");
10130
 
10131
  fputc ('\n', asm_out_file);
10132
}
10133
 
10134
/* Record an element in the table of global constructors.  SYMBOL is
10135
   a SYMBOL_REF of the function to be called; PRIORITY is a number
10136
   between 0 and MAX_INIT_PRIORITY.
10137
 
10138
   Differs from default_ctors_section_asm_out_constructor in that the
10139
   width of the .ctors entry is always 64 bits, rather than the 32 bits
10140
   used by a normal pointer.  */
10141
 
10142
static void
10143
vms_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
10144
{
10145
  switch_to_section (ctors_section);
10146
  assemble_align (BITS_PER_WORD);
10147
  assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
10148
}
10149
 
10150
static void
10151
vms_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED)
10152
{
10153
  switch_to_section (dtors_section);
10154
  assemble_align (BITS_PER_WORD);
10155
  assemble_integer (symbol, UNITS_PER_WORD, BITS_PER_WORD, 1);
10156
}
10157
#else
10158
 
10159
rtx
10160
alpha_need_linkage (const char *name ATTRIBUTE_UNUSED,
10161
                    int is_local ATTRIBUTE_UNUSED)
10162
{
10163
  return NULL_RTX;
10164
}
10165
 
10166
rtx
10167
alpha_use_linkage (rtx func ATTRIBUTE_UNUSED,
10168
                   tree cfundecl ATTRIBUTE_UNUSED,
10169
                   int lflag ATTRIBUTE_UNUSED,
10170
                   int rflag ATTRIBUTE_UNUSED)
10171
{
10172
  return NULL_RTX;
10173
}
10174
 
10175
#endif /* TARGET_ABI_OPEN_VMS */
10176
 
10177
#if TARGET_ABI_UNICOSMK
10178
 
10179
/* This evaluates to true if we do not know how to pass TYPE solely in
10180
   registers.  This is the case for all arguments that do not fit in two
10181
   registers.  */
10182
 
10183
static bool
10184
unicosmk_must_pass_in_stack (enum machine_mode mode, const_tree type)
10185
{
10186
  if (type == NULL)
10187
    return false;
10188
 
10189
  if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
10190
    return true;
10191
  if (TREE_ADDRESSABLE (type))
10192
    return true;
10193
 
10194
  return ALPHA_ARG_SIZE (mode, type, 0) > 2;
10195
}
10196
 
10197
/* Define the offset between two registers, one to be eliminated, and the
10198
   other its replacement, at the start of a routine.  */
10199
 
10200
int
10201
unicosmk_initial_elimination_offset (int from, int to)
10202
{
10203
  int fixed_size;
10204
 
10205
  fixed_size = alpha_sa_size();
10206
  if (fixed_size != 0)
10207
    fixed_size += 48;
10208
 
10209
  if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
10210
    return -fixed_size;
10211
  else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
10212
    return 0;
10213
  else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
10214
    return (ALPHA_ROUND (crtl->outgoing_args_size)
10215
            + ALPHA_ROUND (get_frame_size()));
10216
  else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
10217
    return (ALPHA_ROUND (fixed_size)
10218
            + ALPHA_ROUND (get_frame_size()
10219
                           + crtl->outgoing_args_size));
10220
  else
10221
    gcc_unreachable ();
10222
}
10223
 
10224
/* Output the module name for .ident and .end directives. We have to strip
10225
   directories and add make sure that the module name starts with a letter
10226
   or '$'.  */
10227
 
10228
static void
10229
unicosmk_output_module_name (FILE *file)
10230
{
10231
  const char *name = lbasename (main_input_filename);
10232
  unsigned len = strlen (name);
10233
  char *clean_name = alloca (len + 2);
10234
  char *ptr = clean_name;
10235
 
10236
  /* CAM only accepts module names that start with a letter or '$'. We
10237
     prefix the module name with a '$' if necessary.  */
10238
 
10239
  if (!ISALPHA (*name))
10240
    *ptr++ = '$';
10241
  memcpy (ptr, name, len + 1);
10242
  clean_symbol_name (clean_name);
10243
  fputs (clean_name, file);
10244
}
10245
 
10246
/* Output the definition of a common variable.  */
10247
 
10248
void
10249
unicosmk_output_common (FILE *file, const char *name, int size, int align)
10250
{
10251
  tree name_tree;
10252
  printf ("T3E__: common %s\n", name);
10253
 
10254
  in_section = NULL;
10255
  fputs("\t.endp\n\n\t.psect ", file);
10256
  assemble_name(file, name);
10257
  fprintf(file, ",%d,common\n", floor_log2 (align / BITS_PER_UNIT));
10258
  fprintf(file, "\t.byte\t0:%d\n", size);
10259
 
10260
  /* Mark the symbol as defined in this module.  */
10261
  name_tree = get_identifier (name);
10262
  TREE_ASM_WRITTEN (name_tree) = 1;
10263
}
10264
 
10265
#define SECTION_PUBLIC SECTION_MACH_DEP
10266
#define SECTION_MAIN (SECTION_PUBLIC << 1)
10267
static int current_section_align;
10268
 
10269
/* A get_unnamed_section callback for switching to the text section.  */
10270
 
10271
static void
10272
unicosmk_output_text_section_asm_op (const void *data ATTRIBUTE_UNUSED)
10273
{
10274
  static int count = 0;
10275
  fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@text___%d,code\n", count++);
10276
}
10277
 
10278
/* A get_unnamed_section callback for switching to the data section.  */
10279
 
10280
static void
10281
unicosmk_output_data_section_asm_op (const void *data ATTRIBUTE_UNUSED)
10282
{
10283
  static int count = 1;
10284
  fprintf (asm_out_file, "\t.endp\n\n\t.psect\tgcc@data___%d,data\n", count++);
10285
}
10286
 
10287
/* Implement TARGET_ASM_INIT_SECTIONS.
10288
 
10289
   The Cray assembler is really weird with respect to sections. It has only
10290
   named sections and you can't reopen a section once it has been closed.
10291
   This means that we have to generate unique names whenever we want to
10292
   reenter the text or the data section.  */
10293
 
10294
static void
10295
unicosmk_init_sections (void)
10296
{
10297
  text_section = get_unnamed_section (SECTION_CODE,
10298
                                      unicosmk_output_text_section_asm_op,
10299
                                      NULL);
10300
  data_section = get_unnamed_section (SECTION_WRITE,
10301
                                      unicosmk_output_data_section_asm_op,
10302
                                      NULL);
10303
  readonly_data_section = data_section;
10304
}
10305
 
10306
static unsigned int
10307
unicosmk_section_type_flags (tree decl, const char *name,
10308
                             int reloc ATTRIBUTE_UNUSED)
10309
{
10310
  unsigned int flags = default_section_type_flags (decl, name, reloc);
10311
 
10312
  if (!decl)
10313
    return flags;
10314
 
10315
  if (TREE_CODE (decl) == FUNCTION_DECL)
10316
    {
10317
      current_section_align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT);
10318
      if (align_functions_log > current_section_align)
10319
        current_section_align = align_functions_log;
10320
 
10321
      if (! strcmp (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), "main"))
10322
        flags |= SECTION_MAIN;
10323
    }
10324
  else
10325
    current_section_align = floor_log2 (DECL_ALIGN (decl) / BITS_PER_UNIT);
10326
 
10327
  if (TREE_PUBLIC (decl))
10328
    flags |= SECTION_PUBLIC;
10329
 
10330
  return flags;
10331
}
10332
 
10333
/* Generate a section name for decl and associate it with the
10334
   declaration.  */
10335
 
10336
static void
10337
unicosmk_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
10338
{
10339
  const char *name;
10340
  int len;
10341
 
10342
  gcc_assert (decl);
10343
 
10344
  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
10345
  name = default_strip_name_encoding (name);
10346
  len = strlen (name);
10347
 
10348
  if (TREE_CODE (decl) == FUNCTION_DECL)
10349
    {
10350
      char *string;
10351
 
10352
      /* It is essential that we prefix the section name here because
10353
         otherwise the section names generated for constructors and
10354
         destructors confuse collect2.  */
10355
 
10356
      string = alloca (len + 6);
10357
      sprintf (string, "code@%s", name);
10358
      DECL_SECTION_NAME (decl) = build_string (len + 5, string);
10359
    }
10360
  else if (TREE_PUBLIC (decl))
10361
    DECL_SECTION_NAME (decl) = build_string (len, name);
10362
  else
10363
    {
10364
      char *string;
10365
 
10366
      string = alloca (len + 6);
10367
      sprintf (string, "data@%s", name);
10368
      DECL_SECTION_NAME (decl) = build_string (len + 5, string);
10369
    }
10370
}
10371
 
10372
/* Switch to an arbitrary section NAME with attributes as specified
10373
   by FLAGS.  ALIGN specifies any known alignment requirements for
10374
   the section; 0 if the default should be used.  */
10375
 
10376
static void
10377
unicosmk_asm_named_section (const char *name, unsigned int flags,
10378
                            tree decl ATTRIBUTE_UNUSED)
10379
{
10380
  const char *kind;
10381
 
10382
  /* Close the previous section.  */
10383
 
10384
  fputs ("\t.endp\n\n", asm_out_file);
10385
 
10386
  /* Find out what kind of section we are opening.  */
10387
 
10388
  if (flags & SECTION_MAIN)
10389
    fputs ("\t.start\tmain\n", asm_out_file);
10390
 
10391
  if (flags & SECTION_CODE)
10392
    kind = "code";
10393
  else if (flags & SECTION_PUBLIC)
10394
    kind = "common";
10395
  else
10396
    kind = "data";
10397
 
10398
  if (current_section_align != 0)
10399
    fprintf (asm_out_file, "\t.psect\t%s,%d,%s\n", name,
10400
             current_section_align, kind);
10401
  else
10402
    fprintf (asm_out_file, "\t.psect\t%s,%s\n", name, kind);
10403
}
10404
 
10405
static void
10406
unicosmk_insert_attributes (tree decl, tree *attr_ptr ATTRIBUTE_UNUSED)
10407
{
10408
  if (DECL_P (decl)
10409
      && (TREE_PUBLIC (decl) || TREE_CODE (decl) == FUNCTION_DECL))
10410
    unicosmk_unique_section (decl, 0);
10411
}
10412
 
10413
/* Output an alignment directive. We have to use the macro 'gcc@code@align'
10414
   in code sections because .align fill unused space with zeroes.  */
10415
 
10416
void
10417
unicosmk_output_align (FILE *file, int align)
10418
{
10419
  if (inside_function)
10420
    fprintf (file, "\tgcc@code@align\t%d\n", align);
10421
  else
10422
    fprintf (file, "\t.align\t%d\n", align);
10423
}
10424
 
10425
/* Add a case vector to the current function's list of deferred case
10426
   vectors. Case vectors have to be put into a separate section because CAM
10427
   does not allow data definitions in code sections.  */
10428
 
10429
void
10430
unicosmk_defer_case_vector (rtx lab, rtx vec)
10431
{
10432
  struct machine_function *machine = cfun->machine;
10433
 
10434
  vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec);
10435
  machine->addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec,
10436
                                          machine->addr_list);
10437
}
10438
 
10439
/* Output a case vector.  */
10440
 
10441
static void
10442
unicosmk_output_addr_vec (FILE *file, rtx vec)
10443
{
10444
  rtx lab  = XEXP (vec, 0);
10445
  rtx body = XEXP (vec, 1);
10446
  int vlen = XVECLEN (body, 0);
10447
  int idx;
10448
 
10449
  (*targetm.asm_out.internal_label) (file, "L", CODE_LABEL_NUMBER (lab));
10450
 
10451
  for (idx = 0; idx < vlen; idx++)
10452
    {
10453
      ASM_OUTPUT_ADDR_VEC_ELT
10454
        (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
10455
    }
10456
}
10457
 
10458
/* Output current function's deferred case vectors.  */
10459
 
10460
static void
10461
unicosmk_output_deferred_case_vectors (FILE *file)
10462
{
10463
  struct machine_function *machine = cfun->machine;
10464
  rtx t;
10465
 
10466
  if (machine->addr_list == NULL_RTX)
10467
    return;
10468
 
10469
  switch_to_section (data_section);
10470
  for (t = machine->addr_list; t; t = XEXP (t, 1))
10471
    unicosmk_output_addr_vec (file, XEXP (t, 0));
10472
}
10473
 
10474
/* Generate the name of the SSIB section for the current function.  */
10475
 
10476
#define SSIB_PREFIX "__SSIB_"
10477
#define SSIB_PREFIX_LEN 7
10478
 
10479
static const char *
10480
unicosmk_ssib_name (void)
10481
{
10482
  /* This is ok since CAM won't be able to deal with names longer than that
10483
     anyway.  */
10484
 
10485
  static char name[256];
10486
 
10487
  rtx x;
10488
  const char *fnname;
10489
  int len;
10490
 
10491
  x = DECL_RTL (cfun->decl);
10492
  gcc_assert (MEM_P (x));
10493
  x = XEXP (x, 0);
10494
  gcc_assert (GET_CODE (x) == SYMBOL_REF);
10495
  fnname = XSTR (x, 0);
10496
 
10497
  len = strlen (fnname);
10498
  if (len + SSIB_PREFIX_LEN > 255)
10499
    len = 255 - SSIB_PREFIX_LEN;
10500
 
10501
  strcpy (name, SSIB_PREFIX);
10502
  strncpy (name + SSIB_PREFIX_LEN, fnname, len);
10503
  name[len + SSIB_PREFIX_LEN] = 0;
10504
 
10505
  return name;
10506
}
10507
 
10508
/* Set up the dynamic subprogram information block (DSIB) and update the
10509
   frame pointer register ($15) for subroutines which have a frame. If the
10510
   subroutine doesn't have a frame, simply increment $15.  */
10511
 
10512
static void
10513
unicosmk_gen_dsib (unsigned long *imaskP)
10514
{
10515
  if (alpha_procedure_type == PT_STACK)
10516
    {
10517
      const char *ssib_name;
10518
      rtx mem;
10519
 
10520
      /* Allocate 64 bytes for the DSIB.  */
10521
 
10522
      FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
10523
                                  GEN_INT (-64))));
10524
      emit_insn (gen_blockage ());
10525
 
10526
      /* Save the return address.  */
10527
 
10528
      mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 56));
10529
      set_mem_alias_set (mem, alpha_sr_alias_set);
10530
      FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA)));
10531
      (*imaskP) &= ~(1UL << REG_RA);
10532
 
10533
      /* Save the old frame pointer.  */
10534
 
10535
      mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 48));
10536
      set_mem_alias_set (mem, alpha_sr_alias_set);
10537
      FRP (emit_move_insn (mem, hard_frame_pointer_rtx));
10538
      (*imaskP) &= ~(1UL << HARD_FRAME_POINTER_REGNUM);
10539
 
10540
      emit_insn (gen_blockage ());
10541
 
10542
      /* Store the SSIB pointer.  */
10543
 
10544
      ssib_name = ggc_strdup (unicosmk_ssib_name ());
10545
      mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 32));
10546
      set_mem_alias_set (mem, alpha_sr_alias_set);
10547
 
10548
      FRP (emit_move_insn (gen_rtx_REG (DImode, 5),
10549
                           gen_rtx_SYMBOL_REF (Pmode, ssib_name)));
10550
      FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 5)));
10551
 
10552
      /* Save the CIW index.  */
10553
 
10554
      mem = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx, 24));
10555
      set_mem_alias_set (mem, alpha_sr_alias_set);
10556
      FRP (emit_move_insn (mem, gen_rtx_REG (DImode, 25)));
10557
 
10558
      emit_insn (gen_blockage ());
10559
 
10560
      /* Set the new frame pointer.  */
10561
      FRP (emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
10562
                                  stack_pointer_rtx, GEN_INT (64))));
10563
    }
10564
  else
10565
    {
10566
      /* Increment the frame pointer register to indicate that we do not
10567
         have a frame.  */
10568
      emit_insn (gen_adddi3 (hard_frame_pointer_rtx,
10569
                             hard_frame_pointer_rtx, const1_rtx));
10570
    }
10571
}
10572
 
10573
/* Output the static subroutine information block for the current
10574
   function.  */
10575
 
10576
static void
10577
unicosmk_output_ssib (FILE *file, const char *fnname)
10578
{
10579
  int len;
10580
  int i;
10581
  rtx x;
10582
  rtx ciw;
10583
  struct machine_function *machine = cfun->machine;
10584
 
10585
  in_section = NULL;
10586
  fprintf (file, "\t.endp\n\n\t.psect\t%s%s,data\n", user_label_prefix,
10587
           unicosmk_ssib_name ());
10588
 
10589
  /* Some required stuff and the function name length.  */
10590
 
10591
  len = strlen (fnname);
10592
  fprintf (file, "\t.quad\t^X20008%2.2X28\n", len);
10593
 
10594
  /* Saved registers
10595
     ??? We don't do that yet.  */
10596
 
10597
  fputs ("\t.quad\t0\n", file);
10598
 
10599
  /* Function address.  */
10600
 
10601
  fputs ("\t.quad\t", file);
10602
  assemble_name (file, fnname);
10603
  putc ('\n', file);
10604
 
10605
  fputs ("\t.quad\t0\n", file);
10606
  fputs ("\t.quad\t0\n", file);
10607
 
10608
  /* Function name.
10609
     ??? We do it the same way Cray CC does it but this could be
10610
     simplified.  */
10611
 
10612
  for( i = 0; i < len; i++ )
10613
    fprintf (file, "\t.byte\t%d\n", (int)(fnname[i]));
10614
  if( (len % 8) == 0 )
10615
    fputs ("\t.quad\t0\n", file);
10616
  else
10617
    fprintf (file, "\t.bits\t%d : 0\n", (8 - (len % 8))*8);
10618
 
10619
  /* All call information words used in the function.  */
10620
 
10621
  for (x = machine->first_ciw; x; x = XEXP (x, 1))
10622
    {
10623
      ciw = XEXP (x, 0);
10624
#if HOST_BITS_PER_WIDE_INT == 32
10625
      fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_DOUBLE_HEX "\n",
10626
               CONST_DOUBLE_HIGH (ciw), CONST_DOUBLE_LOW (ciw));
10627
#else
10628
      fprintf (file, "\t.quad\t" HOST_WIDE_INT_PRINT_HEX "\n", INTVAL (ciw));
10629
#endif
10630
    }
10631
}
10632
 
10633
/* Add a call information word (CIW) to the list of the current function's
10634
   CIWs and return its index.
10635
 
10636
   X is a CONST_INT or CONST_DOUBLE representing the CIW.  */
10637
 
10638
rtx
10639
unicosmk_add_call_info_word (rtx x)
10640
{
10641
  rtx node;
10642
  struct machine_function *machine = cfun->machine;
10643
 
10644
  node = gen_rtx_EXPR_LIST (VOIDmode, x, NULL_RTX);
10645
  if (machine->first_ciw == NULL_RTX)
10646
    machine->first_ciw = node;
10647
  else
10648
    XEXP (machine->last_ciw, 1) = node;
10649
 
10650
  machine->last_ciw = node;
10651
  ++machine->ciw_count;
10652
 
10653
  return GEN_INT (machine->ciw_count
10654
                  + strlen (current_function_name ())/8 + 5);
10655
}
10656
 
10657
/* The Cray assembler doesn't accept extern declarations for symbols which
10658
   are defined in the same file. We have to keep track of all global
10659
   symbols which are referenced and/or defined in a source file and output
10660
   extern declarations for those which are referenced but not defined at
10661
   the end of file.  */
10662
 
10663
/* List of identifiers for which an extern declaration might have to be
10664
   emitted.  */
10665
/* FIXME: needs to use GC, so it can be saved and restored for PCH.  */
10666
 
10667
struct unicosmk_extern_list
10668
{
10669
  struct unicosmk_extern_list *next;
10670
  const char *name;
10671
};
10672
 
10673
static struct unicosmk_extern_list *unicosmk_extern_head = 0;
10674
 
10675
/* Output extern declarations which are required for every asm file.  */
10676
 
10677
static void
10678
unicosmk_output_default_externs (FILE *file)
10679
{
10680
  static const char *const externs[] =
10681
    { "__T3E_MISMATCH" };
10682
 
10683
  int i;
10684
  int n;
10685
 
10686
  n = ARRAY_SIZE (externs);
10687
 
10688
  for (i = 0; i < n; i++)
10689
    fprintf (file, "\t.extern\t%s\n", externs[i]);
10690
}
10691
 
10692
/* Output extern declarations for global symbols which are have been
10693
   referenced but not defined.  */
10694
 
10695
static void
10696
unicosmk_output_externs (FILE *file)
10697
{
10698
  struct unicosmk_extern_list *p;
10699
  const char *real_name;
10700
  int len;
10701
  tree name_tree;
10702
 
10703
  len = strlen (user_label_prefix);
10704
  for (p = unicosmk_extern_head; p != 0; p = p->next)
10705
    {
10706
      /* We have to strip the encoding and possibly remove user_label_prefix
10707
         from the identifier in order to handle -fleading-underscore and
10708
         explicit asm names correctly (cf. gcc.dg/asm-names-1.c).  */
10709
      real_name = default_strip_name_encoding (p->name);
10710
      if (len && p->name[0] == '*'
10711
          && !memcmp (real_name, user_label_prefix, len))
10712
        real_name += len;
10713
 
10714
      name_tree = get_identifier (real_name);
10715
      if (! TREE_ASM_WRITTEN (name_tree))
10716
        {
10717
          TREE_ASM_WRITTEN (name_tree) = 1;
10718
          fputs ("\t.extern\t", file);
10719
          assemble_name (file, p->name);
10720
          putc ('\n', file);
10721
        }
10722
    }
10723
}
10724
 
10725
/* Record an extern.  */
10726
 
10727
void
10728
unicosmk_add_extern (const char *name)
10729
{
10730
  struct unicosmk_extern_list *p;
10731
 
10732
  p = (struct unicosmk_extern_list *)
10733
       xmalloc (sizeof (struct unicosmk_extern_list));
10734
  p->next = unicosmk_extern_head;
10735
  p->name = name;
10736
  unicosmk_extern_head = p;
10737
}
10738
 
10739
/* The Cray assembler generates incorrect code if identifiers which
10740
   conflict with register names are used as instruction operands. We have
10741
   to replace such identifiers with DEX expressions.  */
10742
 
10743
/* Structure to collect identifiers which have been replaced by DEX
10744
   expressions.  */
10745
/* FIXME: needs to use GC, so it can be saved and restored for PCH.  */
10746
 
10747
struct unicosmk_dex {
10748
  struct unicosmk_dex *next;
10749
  const char *name;
10750
};
10751
 
10752
/* List of identifiers which have been replaced by DEX expressions. The DEX
10753
   number is determined by the position in the list.  */
10754
 
10755
static struct unicosmk_dex *unicosmk_dex_list = NULL;
10756
 
10757
/* The number of elements in the DEX list.  */
10758
 
10759
static int unicosmk_dex_count = 0;
10760
 
10761
/* Check if NAME must be replaced by a DEX expression.  */
10762
 
10763
static int
10764
unicosmk_special_name (const char *name)
10765
{
10766
  if (name[0] == '*')
10767
    ++name;
10768
 
10769
  if (name[0] == '$')
10770
    ++name;
10771
 
10772
  if (name[0] != 'r' && name[0] != 'f' && name[0] != 'R' && name[0] != 'F')
10773
    return 0;
10774
 
10775
  switch (name[1])
10776
    {
10777
    case '1':  case '2':
10778
      return (name[2] == '\0' || (ISDIGIT (name[2]) && name[3] == '\0'));
10779
 
10780
    case '3':
10781
      return (name[2] == '\0'
10782
               || ((name[2] == '0' || name[2] == '1') && name[3] == '\0'));
10783
 
10784
    default:
10785
      return (ISDIGIT (name[1]) && name[2] == '\0');
10786
    }
10787
}
10788
 
10789
/* Return the DEX number if X must be replaced by a DEX expression and 0
10790
   otherwise.  */
10791
 
10792
static int
10793
unicosmk_need_dex (rtx x)
10794
{
10795
  struct unicosmk_dex *dex;
10796
  const char *name;
10797
  int i;
10798
 
10799
  if (GET_CODE (x) != SYMBOL_REF)
10800
    return 0;
10801
 
10802
  name = XSTR (x,0);
10803
  if (! unicosmk_special_name (name))
10804
    return 0;
10805
 
10806
  i = unicosmk_dex_count;
10807
  for (dex = unicosmk_dex_list; dex; dex = dex->next)
10808
    {
10809
      if (! strcmp (name, dex->name))
10810
        return i;
10811
      --i;
10812
    }
10813
 
10814
  dex = (struct unicosmk_dex *) xmalloc (sizeof (struct unicosmk_dex));
10815
  dex->name = name;
10816
  dex->next = unicosmk_dex_list;
10817
  unicosmk_dex_list = dex;
10818
 
10819
  ++unicosmk_dex_count;
10820
  return unicosmk_dex_count;
10821
}
10822
 
10823
/* Output the DEX definitions for this file.  */
10824
 
10825
static void
10826
unicosmk_output_dex (FILE *file)
10827
{
10828
  struct unicosmk_dex *dex;
10829
  int i;
10830
 
10831
  if (unicosmk_dex_list == NULL)
10832
    return;
10833
 
10834
  fprintf (file, "\t.dexstart\n");
10835
 
10836
  i = unicosmk_dex_count;
10837
  for (dex = unicosmk_dex_list; dex; dex = dex->next)
10838
    {
10839
      fprintf (file, "\tDEX (%d) = ", i);
10840
      assemble_name (file, dex->name);
10841
      putc ('\n', file);
10842
      --i;
10843
    }
10844
 
10845
  fprintf (file, "\t.dexend\n");
10846
}
10847
 
10848
/* Output text that to appear at the beginning of an assembler file.  */
10849
 
10850
static void
10851
unicosmk_file_start (void)
10852
{
10853
  int i;
10854
 
10855
  fputs ("\t.ident\t", asm_out_file);
10856
  unicosmk_output_module_name (asm_out_file);
10857
  fputs ("\n\n", asm_out_file);
10858
 
10859
  /* The Unicos/Mk assembler uses different register names. Instead of trying
10860
     to support them, we simply use micro definitions.  */
10861
 
10862
  /* CAM has different register names: rN for the integer register N and fN
10863
     for the floating-point register N. Instead of trying to use these in
10864
     alpha.md, we define the symbols $N and $fN to refer to the appropriate
10865
     register.  */
10866
 
10867
  for (i = 0; i < 32; ++i)
10868
    fprintf (asm_out_file, "$%d <- r%d\n", i, i);
10869
 
10870
  for (i = 0; i < 32; ++i)
10871
    fprintf (asm_out_file, "$f%d <- f%d\n", i, i);
10872
 
10873
  putc ('\n', asm_out_file);
10874
 
10875
  /* The .align directive fill unused space with zeroes which does not work
10876
     in code sections. We define the macro 'gcc@code@align' which uses nops
10877
     instead. Note that it assumes that code sections always have the
10878
     biggest possible alignment since . refers to the current offset from
10879
     the beginning of the section.  */
10880
 
10881
  fputs ("\t.macro gcc@code@align n\n", asm_out_file);
10882
  fputs ("gcc@n@bytes = 1 << n\n", asm_out_file);
10883
  fputs ("gcc@here = . % gcc@n@bytes\n", asm_out_file);
10884
  fputs ("\t.if ne, gcc@here, 0\n", asm_out_file);
10885
  fputs ("\t.repeat (gcc@n@bytes - gcc@here) / 4\n", asm_out_file);
10886
  fputs ("\tbis r31,r31,r31\n", asm_out_file);
10887
  fputs ("\t.endr\n", asm_out_file);
10888
  fputs ("\t.endif\n", asm_out_file);
10889
  fputs ("\t.endm gcc@code@align\n\n", asm_out_file);
10890
 
10891
  /* Output extern declarations which should always be visible.  */
10892
  unicosmk_output_default_externs (asm_out_file);
10893
 
10894
  /* Open a dummy section. We always need to be inside a section for the
10895
     section-switching code to work correctly.
10896
     ??? This should be a module id or something like that. I still have to
10897
     figure out what the rules for those are.  */
10898
  fputs ("\n\t.psect\t$SG00000,data\n", asm_out_file);
10899
}
10900
 
10901
/* Output text to appear at the end of an assembler file. This includes all
10902
   pending extern declarations and DEX expressions.  */
10903
 
10904
static void
10905
unicosmk_file_end (void)
10906
{
10907
  fputs ("\t.endp\n\n", asm_out_file);
10908
 
10909
  /* Output all pending externs.  */
10910
 
10911
  unicosmk_output_externs (asm_out_file);
10912
 
10913
  /* Output dex definitions used for functions whose names conflict with
10914
     register names.  */
10915
 
10916
  unicosmk_output_dex (asm_out_file);
10917
 
10918
  fputs ("\t.end\t", asm_out_file);
10919
  unicosmk_output_module_name (asm_out_file);
10920
  putc ('\n', asm_out_file);
10921
}
10922
 
10923
#else
10924
 
10925
static void
10926
unicosmk_output_deferred_case_vectors (FILE *file ATTRIBUTE_UNUSED)
10927
{}
10928
 
10929
static void
10930
unicosmk_gen_dsib (unsigned long *imaskP ATTRIBUTE_UNUSED)
10931
{}
10932
 
10933
static void
10934
unicosmk_output_ssib (FILE * file ATTRIBUTE_UNUSED,
10935
                      const char * fnname ATTRIBUTE_UNUSED)
10936
{}
10937
 
10938
rtx
10939
unicosmk_add_call_info_word (rtx x ATTRIBUTE_UNUSED)
10940
{
10941
  return NULL_RTX;
10942
}
10943
 
10944
static int
10945
unicosmk_need_dex (rtx x ATTRIBUTE_UNUSED)
10946
{
10947
  return 0;
10948
}
10949
 
10950
#endif /* TARGET_ABI_UNICOSMK */
10951
 
10952
static void
10953
alpha_init_libfuncs (void)
10954
{
10955
  if (TARGET_ABI_UNICOSMK)
10956
    {
10957
      /* Prevent gcc from generating calls to __divsi3.  */
10958
      set_optab_libfunc (sdiv_optab, SImode, 0);
10959
      set_optab_libfunc (udiv_optab, SImode, 0);
10960
 
10961
      /* Use the functions provided by the system library
10962
         for DImode integer division.  */
10963
      set_optab_libfunc (sdiv_optab, DImode, "$sldiv");
10964
      set_optab_libfunc (udiv_optab, DImode, "$uldiv");
10965
    }
10966
  else if (TARGET_ABI_OPEN_VMS)
10967
    {
10968
      /* Use the VMS runtime library functions for division and
10969
         remainder.  */
10970
      set_optab_libfunc (sdiv_optab, SImode, "OTS$DIV_I");
10971
      set_optab_libfunc (sdiv_optab, DImode, "OTS$DIV_L");
10972
      set_optab_libfunc (udiv_optab, SImode, "OTS$DIV_UI");
10973
      set_optab_libfunc (udiv_optab, DImode, "OTS$DIV_UL");
10974
      set_optab_libfunc (smod_optab, SImode, "OTS$REM_I");
10975
      set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
10976
      set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
10977
      set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
10978
      abort_libfunc = init_one_libfunc ("decc$abort");
10979
      memcmp_libfunc = init_one_libfunc ("decc$memcmp");
10980
#ifdef MEM_LIBFUNCS_INIT
10981
      MEM_LIBFUNCS_INIT;
10982
#endif
10983
    }
10984
}
10985
 
10986
 
10987
/* Initialize the GCC target structure.  */
10988
#if TARGET_ABI_OPEN_VMS
10989
# undef TARGET_ATTRIBUTE_TABLE
10990
# define TARGET_ATTRIBUTE_TABLE vms_attribute_table
10991
# undef TARGET_CAN_ELIMINATE
10992
# define TARGET_CAN_ELIMINATE alpha_vms_can_eliminate
10993
#endif
10994
 
10995
#undef TARGET_IN_SMALL_DATA_P
10996
#define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
10997
 
10998
#if TARGET_ABI_UNICOSMK
10999
# undef TARGET_INSERT_ATTRIBUTES
11000
# define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
11001
# undef TARGET_SECTION_TYPE_FLAGS
11002
# define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
11003
# undef TARGET_ASM_UNIQUE_SECTION
11004
# define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
11005
#undef TARGET_ASM_FUNCTION_RODATA_SECTION
11006
#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
11007
# undef TARGET_ASM_GLOBALIZE_LABEL
11008
# define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
11009
# undef TARGET_MUST_PASS_IN_STACK
11010
# define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
11011
#endif
11012
 
11013
#undef TARGET_ASM_ALIGNED_HI_OP
11014
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
11015
#undef TARGET_ASM_ALIGNED_DI_OP
11016
#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
11017
 
11018
/* Default unaligned ops are provided for ELF systems.  To get unaligned
11019
   data for non-ELF systems, we have to turn off auto alignment.  */
11020
#if !defined (OBJECT_FORMAT_ELF) || TARGET_ABI_OPEN_VMS
11021
#undef TARGET_ASM_UNALIGNED_HI_OP
11022
#define TARGET_ASM_UNALIGNED_HI_OP "\t.align 0\n\t.word\t"
11023
#undef TARGET_ASM_UNALIGNED_SI_OP
11024
#define TARGET_ASM_UNALIGNED_SI_OP "\t.align 0\n\t.long\t"
11025
#undef TARGET_ASM_UNALIGNED_DI_OP
11026
#define TARGET_ASM_UNALIGNED_DI_OP "\t.align 0\n\t.quad\t"
11027
#endif
11028
 
11029
#ifdef OBJECT_FORMAT_ELF
11030
#undef  TARGET_ASM_RELOC_RW_MASK
11031
#define TARGET_ASM_RELOC_RW_MASK  alpha_elf_reloc_rw_mask
11032
#undef  TARGET_ASM_SELECT_RTX_SECTION
11033
#define TARGET_ASM_SELECT_RTX_SECTION  alpha_elf_select_rtx_section
11034
#undef  TARGET_SECTION_TYPE_FLAGS
11035
#define TARGET_SECTION_TYPE_FLAGS  alpha_elf_section_type_flags
11036
#endif
11037
 
11038
#undef TARGET_ASM_FUNCTION_END_PROLOGUE
11039
#define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
11040
 
11041
#undef TARGET_INIT_LIBFUNCS
11042
#define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
11043
 
11044
#undef TARGET_LEGITIMIZE_ADDRESS
11045
#define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address
11046
 
11047
#if TARGET_ABI_UNICOSMK
11048
#undef TARGET_ASM_FILE_START
11049
#define TARGET_ASM_FILE_START unicosmk_file_start
11050
#undef TARGET_ASM_FILE_END
11051
#define TARGET_ASM_FILE_END unicosmk_file_end
11052
#else
11053
#undef TARGET_ASM_FILE_START
11054
#define TARGET_ASM_FILE_START alpha_file_start
11055
#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
11056
#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
11057
#endif
11058
 
11059
#undef TARGET_SCHED_ADJUST_COST
11060
#define TARGET_SCHED_ADJUST_COST alpha_adjust_cost
11061
#undef TARGET_SCHED_ISSUE_RATE
11062
#define TARGET_SCHED_ISSUE_RATE alpha_issue_rate
11063
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
11064
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD \
11065
  alpha_multipass_dfa_lookahead
11066
 
11067
#undef TARGET_HAVE_TLS
11068
#define TARGET_HAVE_TLS HAVE_AS_TLS
11069
 
11070
#undef  TARGET_INIT_BUILTINS
11071
#define TARGET_INIT_BUILTINS alpha_init_builtins
11072
#undef  TARGET_EXPAND_BUILTIN
11073
#define TARGET_EXPAND_BUILTIN alpha_expand_builtin
11074
#undef  TARGET_FOLD_BUILTIN
11075
#define TARGET_FOLD_BUILTIN alpha_fold_builtin
11076
 
11077
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
11078
#define TARGET_FUNCTION_OK_FOR_SIBCALL alpha_function_ok_for_sibcall
11079
#undef TARGET_CANNOT_COPY_INSN_P
11080
#define TARGET_CANNOT_COPY_INSN_P alpha_cannot_copy_insn_p
11081
#undef TARGET_CANNOT_FORCE_CONST_MEM
11082
#define TARGET_CANNOT_FORCE_CONST_MEM alpha_cannot_force_const_mem
11083
 
11084
#if TARGET_ABI_OSF
11085
#undef TARGET_ASM_OUTPUT_MI_THUNK
11086
#define TARGET_ASM_OUTPUT_MI_THUNK alpha_output_mi_thunk_osf
11087
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
11088
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
11089
#undef TARGET_STDARG_OPTIMIZE_HOOK
11090
#define TARGET_STDARG_OPTIMIZE_HOOK alpha_stdarg_optimize_hook
11091
#endif
11092
 
11093
#undef TARGET_RTX_COSTS
11094
#define TARGET_RTX_COSTS alpha_rtx_costs
11095
#undef TARGET_ADDRESS_COST
11096
#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
11097
 
11098
#undef TARGET_MACHINE_DEPENDENT_REORG
11099
#define TARGET_MACHINE_DEPENDENT_REORG alpha_reorg
11100
 
11101
#undef TARGET_PROMOTE_FUNCTION_MODE
11102
#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
11103
#undef TARGET_PROMOTE_PROTOTYPES
11104
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_false
11105
#undef TARGET_RETURN_IN_MEMORY
11106
#define TARGET_RETURN_IN_MEMORY alpha_return_in_memory
11107
#undef TARGET_PASS_BY_REFERENCE
11108
#define TARGET_PASS_BY_REFERENCE alpha_pass_by_reference
11109
#undef TARGET_SETUP_INCOMING_VARARGS
11110
#define TARGET_SETUP_INCOMING_VARARGS alpha_setup_incoming_varargs
11111
#undef TARGET_STRICT_ARGUMENT_NAMING
11112
#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
11113
#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
11114
#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
11115
#undef TARGET_SPLIT_COMPLEX_ARG
11116
#define TARGET_SPLIT_COMPLEX_ARG alpha_split_complex_arg
11117
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
11118
#define TARGET_GIMPLIFY_VA_ARG_EXPR alpha_gimplify_va_arg
11119
#undef TARGET_ARG_PARTIAL_BYTES
11120
#define TARGET_ARG_PARTIAL_BYTES alpha_arg_partial_bytes
11121
#undef TARGET_TRAMPOLINE_INIT
11122
#define TARGET_TRAMPOLINE_INIT alpha_trampoline_init
11123
 
11124
#undef TARGET_SECONDARY_RELOAD
11125
#define TARGET_SECONDARY_RELOAD alpha_secondary_reload
11126
 
11127
#undef TARGET_SCALAR_MODE_SUPPORTED_P
11128
#define TARGET_SCALAR_MODE_SUPPORTED_P alpha_scalar_mode_supported_p
11129
#undef TARGET_VECTOR_MODE_SUPPORTED_P
11130
#define TARGET_VECTOR_MODE_SUPPORTED_P alpha_vector_mode_supported_p
11131
 
11132
#undef TARGET_BUILD_BUILTIN_VA_LIST
11133
#define TARGET_BUILD_BUILTIN_VA_LIST alpha_build_builtin_va_list
11134
 
11135
#undef TARGET_EXPAND_BUILTIN_VA_START
11136
#define TARGET_EXPAND_BUILTIN_VA_START alpha_va_start
11137
 
11138
/* The Alpha architecture does not require sequential consistency.  See
11139
   http://www.cs.umd.edu/~pugh/java/memoryModel/AlphaReordering.html
11140
   for an example of how it can be violated in practice.  */
11141
#undef TARGET_RELAXED_ORDERING
11142
#define TARGET_RELAXED_ORDERING true
11143
 
11144
#undef TARGET_DEFAULT_TARGET_FLAGS
11145
#define TARGET_DEFAULT_TARGET_FLAGS \
11146
  (TARGET_DEFAULT | TARGET_CPU_DEFAULT | TARGET_DEFAULT_EXPLICIT_RELOCS)
11147
#undef TARGET_HANDLE_OPTION
11148
#define TARGET_HANDLE_OPTION alpha_handle_option
11149
 
11150
#ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
11151
#undef TARGET_MANGLE_TYPE
11152
#define TARGET_MANGLE_TYPE alpha_mangle_type
11153
#endif
11154
 
11155
#undef TARGET_LEGITIMATE_ADDRESS_P
11156
#define TARGET_LEGITIMATE_ADDRESS_P alpha_legitimate_address_p
11157
 
11158
struct gcc_target targetm = TARGET_INITIALIZER;
11159
 
11160
 
11161
#include "gt-alpha.h"

powered by: WebSVN 2.1.0

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