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/] [vax/] [vax.c] - Blame information for rev 307

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Subroutines for insn-output.c for VAX.
2
   Copyright (C) 1987, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002,
3
   2004, 2005, 2007
4
   Free Software Foundation, Inc.
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
#include "config.h"
23
#include "system.h"
24
#include "coretypes.h"
25
#include "tm.h"
26
#include "rtl.h"
27
#include "tree.h"
28
#include "regs.h"
29
#include "hard-reg-set.h"
30
#include "real.h"
31
#include "insn-config.h"
32
#include "conditions.h"
33
#include "function.h"
34
#include "output.h"
35
#include "insn-attr.h"
36
#include "recog.h"
37
#include "expr.h"
38
#include "optabs.h"
39
#include "flags.h"
40
#include "debug.h"
41
#include "toplev.h"
42
#include "tm_p.h"
43
#include "target.h"
44
#include "target-def.h"
45
 
46
static void vax_output_function_prologue (FILE *, HOST_WIDE_INT);
47
static void vax_file_start (void);
48
static void vax_init_libfuncs (void);
49
static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
50
                                 HOST_WIDE_INT, tree);
51
static int vax_address_cost_1 (rtx);
52
static int vax_address_cost (rtx);
53
static bool vax_rtx_costs (rtx, int, int, int *);
54
static rtx vax_struct_value_rtx (tree, int);
55
 
56
/* Initialize the GCC target structure.  */
57
#undef TARGET_ASM_ALIGNED_HI_OP
58
#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
59
 
60
#undef TARGET_ASM_FUNCTION_PROLOGUE
61
#define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
62
 
63
#undef TARGET_ASM_FILE_START
64
#define TARGET_ASM_FILE_START vax_file_start
65
#undef TARGET_ASM_FILE_START_APP_OFF
66
#define TARGET_ASM_FILE_START_APP_OFF true
67
 
68
#undef TARGET_INIT_LIBFUNCS
69
#define TARGET_INIT_LIBFUNCS vax_init_libfuncs
70
 
71
#undef TARGET_ASM_OUTPUT_MI_THUNK
72
#define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
73
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
74
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
75
 
76
#undef TARGET_DEFAULT_TARGET_FLAGS
77
#define TARGET_DEFAULT_TARGET_FLAGS TARGET_DEFAULT
78
 
79
#undef TARGET_RTX_COSTS
80
#define TARGET_RTX_COSTS vax_rtx_costs
81
#undef TARGET_ADDRESS_COST
82
#define TARGET_ADDRESS_COST vax_address_cost
83
 
84
#undef TARGET_PROMOTE_PROTOTYPES
85
#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
86
 
87
#undef TARGET_STRUCT_VALUE_RTX
88
#define TARGET_STRUCT_VALUE_RTX vax_struct_value_rtx
89
 
90
struct gcc_target targetm = TARGET_INITIALIZER;
91
 
92
/* Set global variables as needed for the options enabled.  */
93
 
94
void
95
override_options (void)
96
{
97
  /* We're VAX floating point, not IEEE floating point.  */
98
  if (TARGET_G_FLOAT)
99
    REAL_MODE_FORMAT (DFmode) = &vax_g_format;
100
}
101
 
102
/* Generate the assembly code for function entry.  FILE is a stdio
103
   stream to output the code to.  SIZE is an int: how many units of
104
   temporary storage to allocate.
105
 
106
   Refer to the array `regs_ever_live' to determine which registers to
107
   save; `regs_ever_live[I]' is nonzero if register number I is ever
108
   used in the function.  This function is responsible for knowing
109
   which registers should not be saved even if used.  */
110
 
111
static void
112
vax_output_function_prologue (FILE * file, HOST_WIDE_INT size)
113
{
114
  int regno;
115
  int mask = 0;
116
 
117
  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
118
    if (regs_ever_live[regno] && !call_used_regs[regno])
119
      mask |= 1 << regno;
120
 
121
  fprintf (file, "\t.word 0x%x\n", mask);
122
 
123
  if (dwarf2out_do_frame ())
124
    {
125
      const char *label = dwarf2out_cfi_label ();
126
      int offset = 0;
127
 
128
      for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno)
129
        if (regs_ever_live[regno] && !call_used_regs[regno])
130
          dwarf2out_reg_save (label, regno, offset -= 4);
131
 
132
      dwarf2out_reg_save (label, PC_REGNUM, offset -= 4);
133
      dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4);
134
      dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4);
135
      dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4));
136
    }
137
 
138
  size -= STARTING_FRAME_OFFSET;
139
  if (size >= 64)
140
    asm_fprintf (file, "\tmovab %wd(%Rsp),%Rsp\n", -size);
141
  else if (size)
142
    asm_fprintf (file, "\tsubl2 $%wd,%Rsp\n", size);
143
}
144
 
145
/* When debugging with stabs, we want to output an extra dummy label
146
   so that gas can distinguish between D_float and G_float prior to
147
   processing the .stabs directive identifying type double.  */
148
static void
149
vax_file_start (void)
150
{
151
  default_file_start ();
152
 
153
  if (write_symbols == DBX_DEBUG)
154
    fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR);
155
}
156
 
157
/* We can use the BSD C library routines for the libgcc calls that are
158
   still generated, since that's what they boil down to anyways.  When
159
   ELF, avoid the user's namespace.  */
160
 
161
static void
162
vax_init_libfuncs (void)
163
{
164
  set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv");
165
  set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__urem" : "*urem");
166
}
167
 
168
/* This is like nonimmediate_operand with a restriction on the type of MEM.  */
169
 
170
void
171
split_quadword_operands (rtx * operands, rtx * low, int n ATTRIBUTE_UNUSED)
172
{
173
  int i;
174
  /* Split operands.  */
175
 
176
  low[0] = low[1] = low[2] = 0;
177
  for (i = 0; i < 3; i++)
178
    {
179
      if (low[i])
180
        /* it's already been figured out */;
181
      else if (MEM_P (operands[i])
182
               && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
183
        {
184
          rtx addr = XEXP (operands[i], 0);
185
          operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
186
          if (which_alternative == 0 && i == 0)
187
            {
188
              addr = XEXP (operands[i], 0);
189
              operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
190
            }
191
        }
192
      else
193
        {
194
          low[i] = operand_subword (operands[i], 0, 0, DImode);
195
          operands[i] = operand_subword (operands[i], 1, 0, DImode);
196
        }
197
    }
198
}
199
 
200
void
201
print_operand_address (FILE * file, rtx addr)
202
{
203
  rtx reg1, breg, ireg;
204
  rtx offset;
205
 
206
 retry:
207
  switch (GET_CODE (addr))
208
    {
209
    case MEM:
210
      fprintf (file, "*");
211
      addr = XEXP (addr, 0);
212
      goto retry;
213
 
214
    case REG:
215
      fprintf (file, "(%s)", reg_names[REGNO (addr)]);
216
      break;
217
 
218
    case PRE_DEC:
219
      fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
220
      break;
221
 
222
    case POST_INC:
223
      fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
224
      break;
225
 
226
    case PLUS:
227
      /* There can be either two or three things added here.  One must be a
228
         REG.  One can be either a REG or a MULT of a REG and an appropriate
229
         constant, and the third can only be a constant or a MEM.
230
 
231
         We get these two or three things and put the constant or MEM in
232
         OFFSET, the MULT or REG in IREG, and the REG in BREG.  If we have
233
         a register and can't tell yet if it is a base or index register,
234
         put it into REG1.  */
235
 
236
      reg1 = 0; ireg = 0; breg = 0; offset = 0;
237
 
238
      if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
239
          || MEM_P (XEXP (addr, 0)))
240
        {
241
          offset = XEXP (addr, 0);
242
          addr = XEXP (addr, 1);
243
        }
244
      else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
245
               || MEM_P (XEXP (addr, 1)))
246
        {
247
          offset = XEXP (addr, 1);
248
          addr = XEXP (addr, 0);
249
        }
250
      else if (GET_CODE (XEXP (addr, 1)) == MULT)
251
        {
252
          ireg = XEXP (addr, 1);
253
          addr = XEXP (addr, 0);
254
        }
255
      else if (GET_CODE (XEXP (addr, 0)) == MULT)
256
        {
257
          ireg = XEXP (addr, 0);
258
          addr = XEXP (addr, 1);
259
        }
260
      else if (REG_P (XEXP (addr, 1)))
261
        {
262
          reg1 = XEXP (addr, 1);
263
          addr = XEXP (addr, 0);
264
        }
265
      else if (REG_P (XEXP (addr, 0)))
266
        {
267
          reg1 = XEXP (addr, 0);
268
          addr = XEXP (addr, 1);
269
        }
270
      else
271
        gcc_unreachable ();
272
 
273
      if (REG_P (addr))
274
        {
275
          if (reg1)
276
            ireg = addr;
277
          else
278
            reg1 = addr;
279
        }
280
      else if (GET_CODE (addr) == MULT)
281
        ireg = addr;
282
      else
283
        {
284
          gcc_assert (GET_CODE (addr) == PLUS);
285
          if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
286
              || MEM_P (XEXP (addr, 0)))
287
            {
288
              if (offset)
289
                {
290
                  if (CONST_INT_P (offset))
291
                    offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
292
                  else
293
                    {
294
                      gcc_assert (CONST_INT_P (XEXP (addr, 0)));
295
                      offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
296
                    }
297
                }
298
              offset = XEXP (addr, 0);
299
            }
300
          else if (REG_P (XEXP (addr, 0)))
301
            {
302
              if (reg1)
303
                ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
304
              else
305
                reg1 = XEXP (addr, 0);
306
            }
307
          else
308
            {
309
              gcc_assert (GET_CODE (XEXP (addr, 0)) == MULT);
310
              gcc_assert (!ireg);
311
              ireg = XEXP (addr, 0);
312
            }
313
 
314
          if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
315
              || MEM_P (XEXP (addr, 1)))
316
            {
317
              if (offset)
318
                {
319
                  if (CONST_INT_P (offset))
320
                    offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
321
                  else
322
                    {
323
                      gcc_assert (CONST_INT_P (XEXP (addr, 1)));
324
                      offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
325
                    }
326
                }
327
              offset = XEXP (addr, 1);
328
            }
329
          else if (REG_P (XEXP (addr, 1)))
330
            {
331
              if (reg1)
332
                ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
333
              else
334
                reg1 = XEXP (addr, 1);
335
            }
336
          else
337
            {
338
              gcc_assert (GET_CODE (XEXP (addr, 1)) == MULT);
339
              gcc_assert (!ireg);
340
              ireg = XEXP (addr, 1);
341
            }
342
        }
343
 
344
      /* If REG1 is nonzero, figure out if it is a base or index register.  */
345
      if (reg1)
346
        {
347
          if (breg != 0 || (offset && MEM_P (offset)))
348
            {
349
              gcc_assert (!ireg);
350
              ireg = reg1;
351
            }
352
          else
353
            breg = reg1;
354
        }
355
 
356
      if (offset != 0)
357
        output_address (offset);
358
 
359
      if (breg != 0)
360
        fprintf (file, "(%s)", reg_names[REGNO (breg)]);
361
 
362
      if (ireg != 0)
363
        {
364
          if (GET_CODE (ireg) == MULT)
365
            ireg = XEXP (ireg, 0);
366
          gcc_assert (REG_P (ireg));
367
          fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
368
        }
369
      break;
370
 
371
    default:
372
      output_addr_const (file, addr);
373
    }
374
}
375
 
376
const char *
377
rev_cond_name (rtx op)
378
{
379
  switch (GET_CODE (op))
380
    {
381
    case EQ:
382
      return "neq";
383
    case NE:
384
      return "eql";
385
    case LT:
386
      return "geq";
387
    case LE:
388
      return "gtr";
389
    case GT:
390
      return "leq";
391
    case GE:
392
      return "lss";
393
    case LTU:
394
      return "gequ";
395
    case LEU:
396
      return "gtru";
397
    case GTU:
398
      return "lequ";
399
    case GEU:
400
      return "lssu";
401
 
402
    default:
403
      gcc_unreachable ();
404
    }
405
}
406
 
407
int
408
vax_float_literal(rtx c)
409
{
410
  enum machine_mode mode;
411
  REAL_VALUE_TYPE r, s;
412
  int i;
413
 
414
  if (GET_CODE (c) != CONST_DOUBLE)
415
    return 0;
416
 
417
  mode = GET_MODE (c);
418
 
419
  if (c == const_tiny_rtx[(int) mode][0]
420
      || c == const_tiny_rtx[(int) mode][1]
421
      || c == const_tiny_rtx[(int) mode][2])
422
    return 1;
423
 
424
  REAL_VALUE_FROM_CONST_DOUBLE (r, c);
425
 
426
  for (i = 0; i < 7; i++)
427
    {
428
      int x = 1 << i;
429
      bool ok;
430
      REAL_VALUE_FROM_INT (s, x, 0, mode);
431
 
432
      if (REAL_VALUES_EQUAL (r, s))
433
        return 1;
434
      ok = exact_real_inverse (mode, &s);
435
      gcc_assert (ok);
436
      if (REAL_VALUES_EQUAL (r, s))
437
        return 1;
438
    }
439
  return 0;
440
}
441
 
442
 
443
/* Return the cost in cycles of a memory address, relative to register
444
   indirect.
445
 
446
   Each of the following adds the indicated number of cycles:
447
 
448
   1 - symbolic address
449
   1 - pre-decrement
450
   1 - indexing and/or offset(register)
451
   2 - indirect */
452
 
453
 
454
static int
455
vax_address_cost_1 (rtx addr)
456
{
457
  int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
458
  rtx plus_op0 = 0, plus_op1 = 0;
459
 restart:
460
  switch (GET_CODE (addr))
461
    {
462
    case PRE_DEC:
463
      predec = 1;
464
    case REG:
465
    case SUBREG:
466
    case POST_INC:
467
      reg = 1;
468
      break;
469
    case MULT:
470
      indexed = 1;      /* 2 on VAX 2 */
471
      break;
472
    case CONST_INT:
473
      /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
474
      if (offset == 0)
475
        offset = (unsigned HOST_WIDE_INT)(INTVAL(addr)+128) > 256;
476
      break;
477
    case CONST:
478
    case SYMBOL_REF:
479
      offset = 1;       /* 2 on VAX 2 */
480
      break;
481
    case LABEL_REF:     /* this is probably a byte offset from the pc */
482
      if (offset == 0)
483
        offset = 1;
484
      break;
485
    case PLUS:
486
      if (plus_op0)
487
        plus_op1 = XEXP (addr, 0);
488
      else
489
        plus_op0 = XEXP (addr, 0);
490
      addr = XEXP (addr, 1);
491
      goto restart;
492
    case MEM:
493
      indir = 2;        /* 3 on VAX 2 */
494
      addr = XEXP (addr, 0);
495
      goto restart;
496
    default:
497
      break;
498
    }
499
 
500
  /* Up to 3 things can be added in an address.  They are stored in
501
     plus_op0, plus_op1, and addr.  */
502
 
503
  if (plus_op0)
504
    {
505
      addr = plus_op0;
506
      plus_op0 = 0;
507
      goto restart;
508
    }
509
  if (plus_op1)
510
    {
511
      addr = plus_op1;
512
      plus_op1 = 0;
513
      goto restart;
514
    }
515
  /* Indexing and register+offset can both be used (except on a VAX 2)
516
     without increasing execution time over either one alone.  */
517
  if (reg && indexed && offset)
518
    return reg + indir + offset + predec;
519
  return reg + indexed + indir + offset + predec;
520
}
521
 
522
static int
523
vax_address_cost (rtx x)
524
{
525
  return (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x)));
526
}
527
 
528
/* Cost of an expression on a VAX.  This version has costs tuned for the
529
   CVAX chip (found in the VAX 3 series) with comments for variations on
530
   other models.
531
 
532
   FIXME: The costs need review, particularly for TRUNCATE, FLOAT_EXTEND
533
   and FLOAT_TRUNCATE.  We need a -mcpu option to allow provision of
534
   costs on a per cpu basis.  */
535
 
536
static bool
537
vax_rtx_costs (rtx x, int code, int outer_code, int *total)
538
{
539
  enum machine_mode mode = GET_MODE (x);
540
  int i = 0;                                /* may be modified in switch */
541
  const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
542
 
543
  switch (code)
544
    {
545
      /* On a VAX, constants from 0..63 are cheap because they can use the
546
         1 byte literal constant format.  Compare to -1 should be made cheap
547
         so that decrement-and-branch insns can be formed more easily (if
548
         the value -1 is copied to a register some decrement-and-branch
549
         patterns will not match).  */
550
    case CONST_INT:
551
      if (INTVAL (x) == 0)
552
        return true;
553
      if (outer_code == AND)
554
        {
555
          *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2;
556
          return true;
557
        }
558
      if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077
559
          || (outer_code == COMPARE
560
              && INTVAL (x) == -1)
561
          || ((outer_code == PLUS || outer_code == MINUS)
562
              && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077))
563
        {
564
          *total = 1;
565
          return true;
566
        }
567
      /* FALLTHRU */
568
 
569
    case CONST:
570
    case LABEL_REF:
571
    case SYMBOL_REF:
572
      *total = 3;
573
      return true;
574
 
575
    case CONST_DOUBLE:
576
      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
577
        *total = vax_float_literal (x) ? 5 : 8;
578
      else
579
        *total = ((CONST_DOUBLE_HIGH (x) == 0
580
                   && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
581
                  || (outer_code == PLUS
582
                      && CONST_DOUBLE_HIGH (x) == -1
583
                      && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64))
584
                 ? 2 : 5;
585
      return true;
586
 
587
    case POST_INC:
588
      *total = 2;
589
      return true;              /* Implies register operand.  */
590
 
591
    case PRE_DEC:
592
      *total = 3;
593
      return true;              /* Implies register operand.  */
594
 
595
    case MULT:
596
      switch (mode)
597
        {
598
        case DFmode:
599
          *total = 16;          /* 4 on VAX 9000 */
600
          break;
601
        case SFmode:
602
          *total = 9;           /* 4 on VAX 9000, 12 on VAX 2 */
603
          break;
604
        case DImode:
605
          *total = 16;          /* 6 on VAX 9000, 28 on VAX 2 */
606
          break;
607
        case SImode:
608
        case HImode:
609
        case QImode:
610
          *total = 10;          /* 3-4 on VAX 9000, 20-28 on VAX 2 */
611
          break;
612
        default:
613
          *total = MAX_COST;    /* Mode is not supported.  */
614
          return true;
615
        }
616
      break;
617
 
618
    case UDIV:
619
      if (mode != SImode)
620
        {
621
          *total = MAX_COST;    /* Mode is not supported.  */
622
          return true;
623
        }
624
      *total = 17;
625
      break;
626
 
627
    case DIV:
628
      if (mode == DImode)
629
        *total = 30;            /* Highly variable.  */
630
      else if (mode == DFmode)
631
        /* divide takes 28 cycles if the result is not zero, 13 otherwise */
632
        *total = 24;
633
      else
634
        *total = 11;            /* 25 on VAX 2 */
635
      break;
636
 
637
    case MOD:
638
      *total = 23;
639
      break;
640
 
641
    case UMOD:
642
      if (mode != SImode)
643
        {
644
          *total = MAX_COST;    /* Mode is not supported.  */
645
          return true;
646
        }
647
      *total = 29;
648
      break;
649
 
650
    case FLOAT:
651
      *total = (6               /* 4 on VAX 9000 */
652
                + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode));
653
      break;
654
 
655
    case FIX:
656
      *total = 7;               /* 17 on VAX 2 */
657
      break;
658
 
659
    case ASHIFT:
660
    case LSHIFTRT:
661
    case ASHIFTRT:
662
      if (mode == DImode)
663
        *total = 12;
664
      else
665
        *total = 10;            /* 6 on VAX 9000 */
666
      break;
667
 
668
    case ROTATE:
669
    case ROTATERT:
670
      *total = 6;               /* 5 on VAX 2, 4 on VAX 9000 */
671
      if (CONST_INT_P (XEXP (x, 1)))
672
        fmt = "e";              /* all constant rotate counts are short */
673
      break;
674
 
675
    case PLUS:
676
    case MINUS:
677
      *total = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
678
      /* Small integer operands can use subl2 and addl2.  */
679
      if ((CONST_INT_P (XEXP (x, 1)))
680
          && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127)
681
        fmt = "e";
682
      break;
683
 
684
    case IOR:
685
    case XOR:
686
      *total = 3;
687
      break;
688
 
689
    case AND:
690
      /* AND is special because the first operand is complemented.  */
691
      *total = 3;
692
      if (CONST_INT_P (XEXP (x, 0)))
693
        {
694
          if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63)
695
            *total = 4;
696
          fmt = "e";
697
          i = 1;
698
        }
699
      break;
700
 
701
    case NEG:
702
      if (mode == DFmode)
703
        *total = 9;
704
      else if (mode == SFmode)
705
        *total = 6;
706
      else if (mode == DImode)
707
        *total = 4;
708
      else
709
        *total = 2;
710
      break;
711
 
712
    case NOT:
713
      *total = 2;
714
      break;
715
 
716
    case ZERO_EXTRACT:
717
    case SIGN_EXTRACT:
718
      *total = 15;
719
      break;
720
 
721
    case MEM:
722
      if (mode == DImode || mode == DFmode)
723
        *total = 5;             /* 7 on VAX 2 */
724
      else
725
        *total = 3;             /* 4 on VAX 2 */
726
      x = XEXP (x, 0);
727
      if (!REG_P (x) && GET_CODE (x) != POST_INC)
728
        *total += vax_address_cost_1 (x);
729
      return true;
730
 
731
    case FLOAT_EXTEND:
732
    case FLOAT_TRUNCATE:
733
    case TRUNCATE:
734
      *total = 3;               /* FIXME: Costs need to be checked  */
735
      break;
736
 
737
    default:
738
      return false;
739
    }
740
 
741
  /* Now look inside the expression.  Operands which are not registers or
742
     short constants add to the cost.
743
 
744
     FMT and I may have been adjusted in the switch above for instructions
745
     which require special handling.  */
746
 
747
  while (*fmt++ == 'e')
748
    {
749
      rtx op = XEXP (x, i);
750
 
751
      i += 1;
752
      code = GET_CODE (op);
753
 
754
      /* A NOT is likely to be found as the first operand of an AND
755
         (in which case the relevant cost is of the operand inside
756
         the not) and not likely to be found anywhere else.  */
757
      if (code == NOT)
758
        op = XEXP (op, 0), code = GET_CODE (op);
759
 
760
      switch (code)
761
        {
762
        case CONST_INT:
763
          if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63
764
              && GET_MODE (x) != QImode)
765
            *total += 1;        /* 2 on VAX 2 */
766
          break;
767
        case CONST:
768
        case LABEL_REF:
769
        case SYMBOL_REF:
770
          *total += 1;          /* 2 on VAX 2 */
771
          break;
772
        case CONST_DOUBLE:
773
          if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
774
            {
775
              /* Registers are faster than floating point constants -- even
776
                 those constants which can be encoded in a single byte.  */
777
              if (vax_float_literal (op))
778
                *total += 1;
779
              else
780
                *total += (GET_MODE (x) == DFmode) ? 3 : 2;
781
            }
782
          else
783
            {
784
              if (CONST_DOUBLE_HIGH (op) != 0
785
                  || (unsigned)CONST_DOUBLE_LOW (op) > 63)
786
                *total += 2;
787
            }
788
          break;
789
        case MEM:
790
          *total += 1;          /* 2 on VAX 2 */
791
          if (!REG_P (XEXP (op, 0)))
792
            *total += vax_address_cost_1 (XEXP (op, 0));
793
          break;
794
        case REG:
795
        case SUBREG:
796
          break;
797
        default:
798
          *total += 1;
799
          break;
800
        }
801
    }
802
  return true;
803
}
804
 
805
/* Output code to add DELTA to the first argument, and then jump to FUNCTION.
806
   Used for C++ multiple inheritance.
807
        .mask   ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>  #conservative entry mask
808
        addl2   $DELTA, 4(ap)   #adjust first argument
809
        jmp     FUNCTION+2      #jump beyond FUNCTION's entry mask
810
*/
811
 
812
static void
813
vax_output_mi_thunk (FILE * file,
814
                     tree thunk ATTRIBUTE_UNUSED,
815
                     HOST_WIDE_INT delta,
816
                     HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
817
                     tree function)
818
{
819
  fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta);
820
  asm_fprintf (file, ",4(%Rap)\n");
821
  fprintf (file, "\tjmp ");
822
  assemble_name (file,  XSTR (XEXP (DECL_RTL (function), 0), 0));
823
  fprintf (file, "+2\n");
824
}
825
 
826
static rtx
827
vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
828
                      int incoming ATTRIBUTE_UNUSED)
829
{
830
  return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
831
}
832
 
833
/* Worker function for NOTICE_UPDATE_CC.  */
834
 
835
void
836
vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
837
{
838
  if (GET_CODE (exp) == SET)
839
    {
840
      if (GET_CODE (SET_SRC (exp)) == CALL)
841
        CC_STATUS_INIT;
842
      else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT
843
               && GET_CODE (SET_DEST (exp)) != PC)
844
        {
845
          cc_status.flags = 0;
846
          /* The integer operations below don't set carry or
847
             set it in an incompatible way.  That's ok though
848
             as the Z bit is all we need when doing unsigned
849
             comparisons on the result of these insns (since
850
             they're always with 0).  Set CC_NO_OVERFLOW to
851
             generate the correct unsigned branches.  */
852
          switch (GET_CODE (SET_SRC (exp)))
853
            {
854
            case NEG:
855
              if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT)
856
                break;
857
            case AND:
858
            case IOR:
859
            case XOR:
860
            case NOT:
861
            case MEM:
862
            case REG:
863
              cc_status.flags = CC_NO_OVERFLOW;
864
              break;
865
            default:
866
              break;
867
            }
868
          cc_status.value1 = SET_DEST (exp);
869
          cc_status.value2 = SET_SRC (exp);
870
        }
871
    }
872
  else if (GET_CODE (exp) == PARALLEL
873
           && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
874
    {
875
      if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL)
876
        CC_STATUS_INIT;
877
      else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC)
878
        {
879
          cc_status.flags = 0;
880
          cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0));
881
          cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0));
882
        }
883
      else
884
        /* PARALLELs whose first element sets the PC are aob,
885
           sob insns.  They do change the cc's.  */
886
        CC_STATUS_INIT;
887
    }
888
  else
889
    CC_STATUS_INIT;
890
  if (cc_status.value1 && REG_P (cc_status.value1)
891
      && cc_status.value2
892
      && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
893
    cc_status.value2 = 0;
894
  if (cc_status.value1 && MEM_P (cc_status.value1)
895
      && cc_status.value2
896
      && MEM_P (cc_status.value2))
897
    cc_status.value2 = 0;
898
  /* Actual condition, one line up, should be that value2's address
899
     depends on value1, but that is too much of a pain.  */
900
}
901
 
902
/* Output integer move instructions.  */
903
 
904
const char *
905
vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
906
                     enum machine_mode mode)
907
{
908
  switch (mode)
909
    {
910
    case SImode:
911
      if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
912
        {
913
          if (push_operand (operands[0], SImode))
914
            return "pushab %a1";
915
          return "movab %a1,%0";
916
        }
917
      if (operands[1] == const0_rtx)
918
        return "clrl %0";
919
      if (CONST_INT_P (operands[1])
920
          && (unsigned) INTVAL (operands[1]) >= 64)
921
        {
922
          int i = INTVAL (operands[1]);
923
          if ((unsigned)(~i) < 64)
924
            return "mcoml %N1,%0";
925
          if ((unsigned)i < 0x100)
926
            return "movzbl %1,%0";
927
          if (i >= -0x80 && i < 0)
928
            return "cvtbl %1,%0";
929
          if ((unsigned)i < 0x10000)
930
            return "movzwl %1,%0";
931
          if (i >= -0x8000 && i < 0)
932
            return "cvtwl %1,%0";
933
        }
934
      if (push_operand (operands[0], SImode))
935
        return "pushl %1";
936
      return "movl %1,%0";
937
 
938
    case HImode:
939
      if (CONST_INT_P (operands[1]))
940
        {
941
          int i = INTVAL (operands[1]);
942
          if (i == 0)
943
            return "clrw %0";
944
          else if ((unsigned int)i < 64)
945
            return "movw %1,%0";
946
          else if ((unsigned int)~i < 64)
947
            return "mcomw %H1,%0";
948
          else if ((unsigned int)i < 256)
949
            return "movzbw %1,%0";
950
        }
951
      return "movw %1,%0";
952
 
953
    case QImode:
954
      if (CONST_INT_P (operands[1]))
955
        {
956
          int i = INTVAL (operands[1]);
957
          if (i == 0)
958
            return "clrb %0";
959
          else if ((unsigned int)~i < 64)
960
            return "mcomb %B1,%0";
961
        }
962
      return "movb %1,%0";
963
 
964
    default:
965
      gcc_unreachable ();
966
    }
967
}
968
 
969
/* Output integer add instructions.
970
 
971
   The space-time-opcode tradeoffs for addition vary by model of VAX.
972
 
973
   On a VAX 3 "movab (r1)[r2],r3" is faster than "addl3 r1,r2,r3",
974
   but it not faster on other models.
975
 
976
   "movab #(r1),r2" is usually shorter than "addl3 #,r1,r2", and is
977
   faster on a VAX 3, but some VAXen (e.g. VAX 9000) will stall if
978
   a register is used in an address too soon after it is set.
979
   Compromise by using movab only when it is shorter than the add
980
   or the base register in the address is one of sp, ap, and fp,
981
   which are not modified very often.  */
982
 
983
const char *
984
vax_output_int_add (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
985
                    enum machine_mode mode)
986
{
987
  switch (mode)
988
    {
989
    case SImode:
990
      if (rtx_equal_p (operands[0], operands[1]))
991
        {
992
          if (operands[2] == const1_rtx)
993
            return "incl %0";
994
          if (operands[2] == constm1_rtx)
995
            return "decl %0";
996
          if (CONST_INT_P (operands[2])
997
              && (unsigned) (- INTVAL (operands[2])) < 64)
998
            return "subl2 $%n2,%0";
999
          if (CONST_INT_P (operands[2])
1000
              && (unsigned) INTVAL (operands[2]) >= 64
1001
              && REG_P (operands[1])
1002
              && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768)
1003
                   || REGNO (operands[1]) > 11))
1004
            return "movab %c2(%1),%0";
1005
          return "addl2 %2,%0";
1006
        }
1007
 
1008
      if (rtx_equal_p (operands[0], operands[2]))
1009
        return "addl2 %1,%0";
1010
 
1011
      if (CONST_INT_P (operands[2])
1012
          && INTVAL (operands[2]) < 32767
1013
          && INTVAL (operands[2]) > -32768
1014
          && REG_P (operands[1])
1015
          && push_operand (operands[0], SImode))
1016
        return "pushab %c2(%1)";
1017
 
1018
      if (CONST_INT_P (operands[2])
1019
          && (unsigned) (- INTVAL (operands[2])) < 64)
1020
        return "subl3 $%n2,%1,%0";
1021
 
1022
      if (CONST_INT_P (operands[2])
1023
          && (unsigned) INTVAL (operands[2]) >= 64
1024
          && REG_P (operands[1])
1025
          && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768)
1026
               || REGNO (operands[1]) > 11))
1027
        return "movab %c2(%1),%0";
1028
 
1029
      /* Add this if using gcc on a VAX 3xxx:
1030
      if (REG_P (operands[1]) && REG_P (operands[2]))
1031
        return "movab (%1)[%2],%0";
1032
      */
1033
      return "addl3 %1,%2,%0";
1034
 
1035
    case HImode:
1036
      if (rtx_equal_p (operands[0], operands[1]))
1037
        {
1038
          if (operands[2] == const1_rtx)
1039
            return "incw %0";
1040
          if (operands[2] == constm1_rtx)
1041
            return "decw %0";
1042
          if (CONST_INT_P (operands[2])
1043
              && (unsigned) (- INTVAL (operands[2])) < 64)
1044
            return "subw2 $%n2,%0";
1045
          return "addw2 %2,%0";
1046
        }
1047
      if (rtx_equal_p (operands[0], operands[2]))
1048
        return "addw2 %1,%0";
1049
      if (CONST_INT_P (operands[2])
1050
          && (unsigned) (- INTVAL (operands[2])) < 64)
1051
        return "subw3 $%n2,%1,%0";
1052
      return "addw3 %1,%2,%0";
1053
 
1054
    case QImode:
1055
      if (rtx_equal_p (operands[0], operands[1]))
1056
        {
1057
          if (operands[2] == const1_rtx)
1058
            return "incb %0";
1059
          if (operands[2] == constm1_rtx)
1060
            return "decb %0";
1061
          if (CONST_INT_P (operands[2])
1062
              && (unsigned) (- INTVAL (operands[2])) < 64)
1063
            return "subb2 $%n2,%0";
1064
          return "addb2 %2,%0";
1065
        }
1066
      if (rtx_equal_p (operands[0], operands[2]))
1067
        return "addb2 %1,%0";
1068
      if (CONST_INT_P (operands[2])
1069
          && (unsigned) (- INTVAL (operands[2])) < 64)
1070
        return "subb3 $%n2,%1,%0";
1071
      return "addb3 %1,%2,%0";
1072
 
1073
    default:
1074
      gcc_unreachable ();
1075
    }
1076
}
1077
 
1078
/* Output a conditional branch.  */
1079
const char *
1080
vax_output_conditional_branch (enum rtx_code code)
1081
{
1082
  switch (code)
1083
    {
1084
      case EQ:  return "jeql %l0";
1085
      case NE:  return "jneq %l0";
1086
      case GT:  return "jgtr %l0";
1087
      case LT:  return "jlss %l0";
1088
      case GTU: return "jgtru %l0";
1089
      case LTU: return "jlssu %l0";
1090
      case GE:  return "jgeq %l0";
1091
      case LE:  return "jleq %l0";
1092
      case GEU: return "jgequ %l0";
1093
      case LEU: return "jlequ %l0";
1094
      default:
1095
        gcc_unreachable ();
1096
    }
1097
}
1098
 
1099
/* 1 if X is an rtx for a constant that is a valid address.  */
1100
 
1101
int
1102
legitimate_constant_address_p (rtx x)
1103
{
1104
  return (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF
1105
          || CONST_INT_P (x) || GET_CODE (x) == CONST
1106
          || GET_CODE (x) == HIGH);
1107
}
1108
 
1109
/* Nonzero if the constant value X is a legitimate general operand.
1110
   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
1111
 
1112
int
1113
legitimate_constant_p (rtx x ATTRIBUTE_UNUSED)
1114
{
1115
  return 1;
1116
}
1117
 
1118
/* The other macros defined here are used only in legitimate_address_p ().  */
1119
 
1120
/* Nonzero if X is a hard reg that can be used as an index
1121
   or, if not strict, if it is a pseudo reg.  */
1122
#define INDEX_REGISTER_P(X, STRICT) \
1123
(REG_P (X) && (!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X))))
1124
 
1125
/* Nonzero if X is a hard reg that can be used as a base reg
1126
   or, if not strict, if it is a pseudo reg.  */
1127
#define BASE_REGISTER_P(X, STRICT) \
1128
(REG_P (X) && (!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X))))
1129
 
1130
#ifdef NO_EXTERNAL_INDIRECT_ADDRESS
1131
 
1132
/* Re-definition of CONSTANT_ADDRESS_P, which is true only when there
1133
   are no SYMBOL_REFs for external symbols present.  */
1134
 
1135
static int
1136
indirectable_constant_address_p (rtx x)
1137
{
1138
  if (!CONSTANT_ADDRESS_P (x))
1139
    return 0;
1140
  if (GET_CODE (x) == CONST && GET_CODE (XEXP ((x), 0)) == PLUS)
1141
    x = XEXP (XEXP (x, 0), 0);
1142
  if (GET_CODE (x) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (x))
1143
    return 0;
1144
 
1145
  return 1;
1146
}
1147
 
1148
#else /* not NO_EXTERNAL_INDIRECT_ADDRESS */
1149
 
1150
static int
1151
indirectable_constant_address_p (rtx x)
1152
{
1153
  return CONSTANT_ADDRESS_P (x);
1154
}
1155
 
1156
#endif /* not NO_EXTERNAL_INDIRECT_ADDRESS */
1157
 
1158
/* Nonzero if X is an address which can be indirected.  External symbols
1159
   could be in a sharable image library, so we disallow those.  */
1160
 
1161
static int
1162
indirectable_address_p(rtx x, int strict)
1163
{
1164
  if (indirectable_constant_address_p (x))
1165
    return 1;
1166
  if (BASE_REGISTER_P (x, strict))
1167
    return 1;
1168
  if (GET_CODE (x) == PLUS
1169
      && BASE_REGISTER_P (XEXP (x, 0), strict)
1170
      && indirectable_constant_address_p (XEXP (x, 1)))
1171
    return 1;
1172
  return 0;
1173
}
1174
 
1175
/* Return 1 if x is a valid address not using indexing.
1176
   (This much is the easy part.)  */
1177
static int
1178
nonindexed_address_p (rtx x, int strict)
1179
{
1180
  rtx xfoo0;
1181
  if (REG_P (x))
1182
    {
1183
      extern rtx *reg_equiv_mem;
1184
      if (!reload_in_progress
1185
          || reg_equiv_mem[REGNO (x)] == 0
1186
          || indirectable_address_p (reg_equiv_mem[REGNO (x)], strict))
1187
        return 1;
1188
    }
1189
  if (indirectable_constant_address_p (x))
1190
    return 1;
1191
  if (indirectable_address_p (x, strict))
1192
    return 1;
1193
  xfoo0 = XEXP (x, 0);
1194
  if (MEM_P (x) && indirectable_address_p (xfoo0, strict))
1195
    return 1;
1196
  if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
1197
      && BASE_REGISTER_P (xfoo0, strict))
1198
    return 1;
1199
  return 0;
1200
}
1201
 
1202
/* 1 if PROD is either a reg times size of mode MODE and MODE is less
1203
   than or equal 8 bytes, or just a reg if MODE is one byte.  */
1204
 
1205
static int
1206
index_term_p (rtx prod, enum machine_mode mode, int strict)
1207
{
1208
  rtx xfoo0, xfoo1;
1209
 
1210
  if (GET_MODE_SIZE (mode) == 1)
1211
    return BASE_REGISTER_P (prod, strict);
1212
 
1213
  if (GET_CODE (prod) != MULT || GET_MODE_SIZE (mode) > 8)
1214
    return 0;
1215
 
1216
  xfoo0 = XEXP (prod, 0);
1217
  xfoo1 = XEXP (prod, 1);
1218
 
1219
  if (CONST_INT_P (xfoo0)
1220
      && INTVAL (xfoo0) == (int)GET_MODE_SIZE (mode)
1221
      && INDEX_REGISTER_P (xfoo1, strict))
1222
    return 1;
1223
 
1224
  if (CONST_INT_P (xfoo1)
1225
      && INTVAL (xfoo1) == (int)GET_MODE_SIZE (mode)
1226
      && INDEX_REGISTER_P (xfoo0, strict))
1227
    return 1;
1228
 
1229
  return 0;
1230
}
1231
 
1232
/* Return 1 if X is the sum of a register
1233
   and a valid index term for mode MODE.  */
1234
static int
1235
reg_plus_index_p (rtx x, enum machine_mode mode, int strict)
1236
{
1237
  rtx xfoo0, xfoo1;
1238
 
1239
  if (GET_CODE (x) != PLUS)
1240
    return 0;
1241
 
1242
  xfoo0 = XEXP (x, 0);
1243
  xfoo1 = XEXP (x, 1);
1244
 
1245
  if (BASE_REGISTER_P (xfoo0, strict) && index_term_p (xfoo1, mode, strict))
1246
    return 1;
1247
 
1248
  if (BASE_REGISTER_P (xfoo1, strict) && index_term_p (xfoo0, mode, strict))
1249
    return 1;
1250
 
1251
  return 0;
1252
}
1253
 
1254
/* legitimate_address_p returns 1 if it recognizes an RTL expression "x"
1255
   that is a valid memory address for an instruction.
1256
   The MODE argument is the machine mode for the MEM expression
1257
   that wants to use this address.  */
1258
int
1259
legitimate_address_p (enum machine_mode mode, rtx x, int strict)
1260
{
1261
  rtx xfoo0, xfoo1;
1262
 
1263
  if (nonindexed_address_p (x, strict))
1264
    return 1;
1265
 
1266
  if (GET_CODE (x) != PLUS)
1267
    return 0;
1268
 
1269
  /* Handle <address>[index] represented with index-sum outermost */
1270
 
1271
  xfoo0 = XEXP (x, 0);
1272
  xfoo1 = XEXP (x, 1);
1273
 
1274
  if (index_term_p (xfoo0, mode, strict)
1275
      && nonindexed_address_p (xfoo1, strict))
1276
    return 1;
1277
 
1278
  if (index_term_p (xfoo1, mode, strict)
1279
      && nonindexed_address_p (xfoo0, strict))
1280
    return 1;
1281
 
1282
  /* Handle offset(reg)[index] with offset added outermost */
1283
 
1284
  if (indirectable_constant_address_p (xfoo0)
1285
      && (BASE_REGISTER_P (xfoo1, strict)
1286
          || reg_plus_index_p (xfoo1, mode, strict)))
1287
    return 1;
1288
 
1289
  if (indirectable_constant_address_p (xfoo1)
1290
      && (BASE_REGISTER_P (xfoo0, strict)
1291
          || reg_plus_index_p (xfoo0, mode, strict)))
1292
    return 1;
1293
 
1294
  return 0;
1295
}
1296
 
1297
/* Return 1 if x (a legitimate address expression) has an effect that
1298
   depends on the machine mode it is used for.  On the VAX, the predecrement
1299
   and postincrement address depend thus (the amount of decrement or
1300
   increment being the length of the operand) and all indexed address depend
1301
   thus (because the index scale factor is the length of the operand).  */
1302
 
1303
int
1304
vax_mode_dependent_address_p (rtx x)
1305
{
1306
  rtx xfoo0, xfoo1;
1307
 
1308
  if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
1309
    return 1;
1310
  if (GET_CODE (x) != PLUS)
1311
    return 0;
1312
 
1313
  xfoo0 = XEXP (x, 0);
1314
  xfoo1 = XEXP (x, 1);
1315
 
1316
  if (CONSTANT_ADDRESS_P (xfoo0) && REG_P (xfoo1))
1317
    return 0;
1318
  if (CONSTANT_ADDRESS_P (xfoo1) && REG_P (xfoo0))
1319
    return 0;
1320
 
1321
  return 1;
1322
}

powered by: WebSVN 2.1.0

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