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

Subversion Repositories openrisc_me

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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