]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/vax/vax.c
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / config / vax / vax.c
1 /* Subroutines for insn-output.c for VAX.
2 Copyright (C) 1987, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
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 "flags.h"
39 #include "debug.h"
40 #include "tm_p.h"
41 #include "target.h"
42 #include "target-def.h"
43
44 static int follows_p PARAMS ((rtx, rtx));
45 static void vax_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
46 static void vax_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
47 HOST_WIDE_INT, tree));
48 \f
49 /* Initialize the GCC target structure. */
50 #undef TARGET_ASM_ALIGNED_HI_OP
51 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
52
53 #undef TARGET_ASM_FUNCTION_PROLOGUE
54 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
55
56 #undef TARGET_ASM_OUTPUT_MI_THUNK
57 #define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
58 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
59 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
60
61 struct gcc_target targetm = TARGET_INITIALIZER;
62 \f
63 /* Set global variables as needed for the options enabled. */
64
65 void
66 override_options ()
67 {
68 /* We're VAX floating point, not IEEE floating point. */
69 memset (real_format_for_mode, 0, sizeof real_format_for_mode);
70 real_format_for_mode[SFmode - QFmode] = &vax_f_format;
71 real_format_for_mode[DFmode - QFmode]
72 = (TARGET_G_FLOAT ? &vax_g_format : &vax_d_format);
73 }
74
75 /* Generate the assembly code for function entry. FILE is a stdio
76 stream to output the code to. SIZE is an int: how many units of
77 temporary storage to allocate.
78
79 Refer to the array `regs_ever_live' to determine which registers to
80 save; `regs_ever_live[I]' is nonzero if register number I is ever
81 used in the function. This function is responsible for knowing
82 which registers should not be saved even if used. */
83
84 static void
85 vax_output_function_prologue (file, size)
86 FILE * file;
87 HOST_WIDE_INT size;
88 {
89 register int regno;
90 register int mask = 0;
91
92 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
93 if (regs_ever_live[regno] && !call_used_regs[regno])
94 mask |= 1 << regno;
95
96 fprintf (file, "\t.word 0x%x\n", mask);
97
98 if (dwarf2out_do_frame ())
99 {
100 const char *label = dwarf2out_cfi_label ();
101 int offset = 0;
102
103 for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno)
104 if (regs_ever_live[regno] && !call_used_regs[regno])
105 dwarf2out_reg_save (label, regno, offset -= 4);
106
107 dwarf2out_reg_save (label, PC_REGNUM, offset -= 4);
108 dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4);
109 dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4);
110 dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4));
111 }
112
113 size -= STARTING_FRAME_OFFSET;
114 if (size >= 64)
115 asm_fprintf (file, "\tmovab %d(%Rsp),%Rsp\n", -size);
116 else if (size)
117 asm_fprintf (file, "\tsubl2 $%d,%Rsp\n", size);
118 }
119
120 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
121
122 void
123 split_quadword_operands (operands, low, n)
124 rtx *operands, *low;
125 int n ATTRIBUTE_UNUSED;
126 {
127 int i;
128 /* Split operands. */
129
130 low[0] = low[1] = low[2] = 0;
131 for (i = 0; i < 3; i++)
132 {
133 if (low[i])
134 /* it's already been figured out */;
135 else if (GET_CODE (operands[i]) == MEM
136 && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
137 {
138 rtx addr = XEXP (operands[i], 0);
139 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
140 if (which_alternative == 0 && i == 0)
141 {
142 addr = XEXP (operands[i], 0);
143 operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
144 }
145 }
146 else
147 {
148 low[i] = operand_subword (operands[i], 0, 0, DImode);
149 operands[i] = operand_subword (operands[i], 1, 0, DImode);
150 }
151 }
152 }
153 \f
154 void
155 print_operand_address (file, addr)
156 FILE *file;
157 register rtx addr;
158 {
159 register rtx reg1, breg, ireg;
160 rtx offset;
161
162 retry:
163 switch (GET_CODE (addr))
164 {
165 case MEM:
166 fprintf (file, "*");
167 addr = XEXP (addr, 0);
168 goto retry;
169
170 case REG:
171 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
172 break;
173
174 case PRE_DEC:
175 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
176 break;
177
178 case POST_INC:
179 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
180 break;
181
182 case PLUS:
183 /* There can be either two or three things added here. One must be a
184 REG. One can be either a REG or a MULT of a REG and an appropriate
185 constant, and the third can only be a constant or a MEM.
186
187 We get these two or three things and put the constant or MEM in
188 OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have
189 a register and can't tell yet if it is a base or index register,
190 put it into REG1. */
191
192 reg1 = 0; ireg = 0; breg = 0; offset = 0;
193
194 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
195 || GET_CODE (XEXP (addr, 0)) == MEM)
196 {
197 offset = XEXP (addr, 0);
198 addr = XEXP (addr, 1);
199 }
200 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
201 || GET_CODE (XEXP (addr, 1)) == MEM)
202 {
203 offset = XEXP (addr, 1);
204 addr = XEXP (addr, 0);
205 }
206 else if (GET_CODE (XEXP (addr, 1)) == MULT)
207 {
208 ireg = XEXP (addr, 1);
209 addr = XEXP (addr, 0);
210 }
211 else if (GET_CODE (XEXP (addr, 0)) == MULT)
212 {
213 ireg = XEXP (addr, 0);
214 addr = XEXP (addr, 1);
215 }
216 else if (GET_CODE (XEXP (addr, 1)) == REG)
217 {
218 reg1 = XEXP (addr, 1);
219 addr = XEXP (addr, 0);
220 }
221 else if (GET_CODE (XEXP (addr, 0)) == REG)
222 {
223 reg1 = XEXP (addr, 0);
224 addr = XEXP (addr, 1);
225 }
226 else
227 abort ();
228
229 if (GET_CODE (addr) == REG)
230 {
231 if (reg1)
232 ireg = addr;
233 else
234 reg1 = addr;
235 }
236 else if (GET_CODE (addr) == MULT)
237 ireg = addr;
238 else if (GET_CODE (addr) == PLUS)
239 {
240 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
241 || GET_CODE (XEXP (addr, 0)) == MEM)
242 {
243 if (offset)
244 {
245 if (GET_CODE (offset) == CONST_INT)
246 offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
247 else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
248 offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
249 else
250 abort ();
251 }
252 offset = XEXP (addr, 0);
253 }
254 else if (GET_CODE (XEXP (addr, 0)) == REG)
255 {
256 if (reg1)
257 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
258 else
259 reg1 = XEXP (addr, 0);
260 }
261 else if (GET_CODE (XEXP (addr, 0)) == MULT)
262 {
263 if (ireg)
264 abort ();
265 ireg = XEXP (addr, 0);
266 }
267 else
268 abort ();
269
270 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
271 || GET_CODE (XEXP (addr, 1)) == MEM)
272 {
273 if (offset)
274 {
275 if (GET_CODE (offset) == CONST_INT)
276 offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
277 else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
278 offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
279 else
280 abort ();
281 }
282 offset = XEXP (addr, 1);
283 }
284 else if (GET_CODE (XEXP (addr, 1)) == REG)
285 {
286 if (reg1)
287 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
288 else
289 reg1 = XEXP (addr, 1);
290 }
291 else if (GET_CODE (XEXP (addr, 1)) == MULT)
292 {
293 if (ireg)
294 abort ();
295 ireg = XEXP (addr, 1);
296 }
297 else
298 abort ();
299 }
300 else
301 abort ();
302
303 /* If REG1 is nonzero, figure out if it is a base or index register. */
304 if (reg1)
305 {
306 if (breg != 0 || (offset && GET_CODE (offset) == MEM))
307 {
308 if (ireg)
309 abort ();
310 ireg = reg1;
311 }
312 else
313 breg = reg1;
314 }
315
316 if (offset != 0)
317 output_address (offset);
318
319 if (breg != 0)
320 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
321
322 if (ireg != 0)
323 {
324 if (GET_CODE (ireg) == MULT)
325 ireg = XEXP (ireg, 0);
326 if (GET_CODE (ireg) != REG)
327 abort ();
328 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
329 }
330 break;
331
332 default:
333 output_addr_const (file, addr);
334 }
335 }
336 \f
337 const char *
338 rev_cond_name (op)
339 rtx op;
340 {
341 switch (GET_CODE (op))
342 {
343 case EQ:
344 return "neq";
345 case NE:
346 return "eql";
347 case LT:
348 return "geq";
349 case LE:
350 return "gtr";
351 case GT:
352 return "leq";
353 case GE:
354 return "lss";
355 case LTU:
356 return "gequ";
357 case LEU:
358 return "gtru";
359 case GTU:
360 return "lequ";
361 case GEU:
362 return "lssu";
363
364 default:
365 abort ();
366 }
367 }
368
369 int
370 vax_float_literal(c)
371 register rtx c;
372 {
373 register enum machine_mode mode;
374 REAL_VALUE_TYPE r, s;
375 int i;
376
377 if (GET_CODE (c) != CONST_DOUBLE)
378 return 0;
379
380 mode = GET_MODE (c);
381
382 if (c == const_tiny_rtx[(int) mode][0]
383 || c == const_tiny_rtx[(int) mode][1]
384 || c == const_tiny_rtx[(int) mode][2])
385 return 1;
386
387 REAL_VALUE_FROM_CONST_DOUBLE (r, c);
388
389 for (i = 0; i < 7; i++)
390 {
391 int x = 1 << i;
392 REAL_VALUE_FROM_INT (s, x, 0, mode);
393
394 if (REAL_VALUES_EQUAL (r, s))
395 return 1;
396 if (!exact_real_inverse (mode, &s))
397 abort ();
398 if (REAL_VALUES_EQUAL (r, s))
399 return 1;
400 }
401 return 0;
402 }
403
404
405 /* Return the cost in cycles of a memory address, relative to register
406 indirect.
407
408 Each of the following adds the indicated number of cycles:
409
410 1 - symbolic address
411 1 - pre-decrement
412 1 - indexing and/or offset(register)
413 2 - indirect */
414
415
416 int
417 vax_address_cost (addr)
418 register rtx addr;
419 {
420 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
421 rtx plus_op0 = 0, plus_op1 = 0;
422 restart:
423 switch (GET_CODE (addr))
424 {
425 case PRE_DEC:
426 predec = 1;
427 case REG:
428 case SUBREG:
429 case POST_INC:
430 reg = 1;
431 break;
432 case MULT:
433 indexed = 1; /* 2 on VAX 2 */
434 break;
435 case CONST_INT:
436 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
437 if (offset == 0)
438 offset = (unsigned)(INTVAL(addr)+128) > 256;
439 break;
440 case CONST:
441 case SYMBOL_REF:
442 offset = 1; /* 2 on VAX 2 */
443 break;
444 case LABEL_REF: /* this is probably a byte offset from the pc */
445 if (offset == 0)
446 offset = 1;
447 break;
448 case PLUS:
449 if (plus_op0)
450 plus_op1 = XEXP (addr, 0);
451 else
452 plus_op0 = XEXP (addr, 0);
453 addr = XEXP (addr, 1);
454 goto restart;
455 case MEM:
456 indir = 2; /* 3 on VAX 2 */
457 addr = XEXP (addr, 0);
458 goto restart;
459 default:
460 break;
461 }
462
463 /* Up to 3 things can be added in an address. They are stored in
464 plus_op0, plus_op1, and addr. */
465
466 if (plus_op0)
467 {
468 addr = plus_op0;
469 plus_op0 = 0;
470 goto restart;
471 }
472 if (plus_op1)
473 {
474 addr = plus_op1;
475 plus_op1 = 0;
476 goto restart;
477 }
478 /* Indexing and register+offset can both be used (except on a VAX 2)
479 without increasing execution time over either one alone. */
480 if (reg && indexed && offset)
481 return reg + indir + offset + predec;
482 return reg + indexed + indir + offset + predec;
483 }
484
485
486 /* Cost of an expression on a VAX. This version has costs tuned for the
487 CVAX chip (found in the VAX 3 series) with comments for variations on
488 other models. */
489
490 int
491 vax_rtx_cost (x)
492 register rtx x;
493 {
494 register enum rtx_code code = GET_CODE (x);
495 enum machine_mode mode = GET_MODE (x);
496 register int c;
497 int i = 0; /* may be modified in switch */
498 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
499
500 switch (code)
501 {
502 case POST_INC:
503 return 2;
504 case PRE_DEC:
505 return 3;
506 case MULT:
507 switch (mode)
508 {
509 case DFmode:
510 c = 16; /* 4 on VAX 9000 */
511 break;
512 case SFmode:
513 c = 9; /* 4 on VAX 9000, 12 on VAX 2 */
514 break;
515 case DImode:
516 c = 16; /* 6 on VAX 9000, 28 on VAX 2 */
517 break;
518 case SImode:
519 case HImode:
520 case QImode:
521 c = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
522 break;
523 default:
524 return MAX_COST; /* Mode is not supported. */
525 }
526 break;
527 case UDIV:
528 if (mode != SImode)
529 return MAX_COST; /* Mode is not supported. */
530 c = 17;
531 break;
532 case DIV:
533 if (mode == DImode)
534 c = 30; /* highly variable */
535 else if (mode == DFmode)
536 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
537 c = 24;
538 else
539 c = 11; /* 25 on VAX 2 */
540 break;
541 case MOD:
542 c = 23;
543 break;
544 case UMOD:
545 if (mode != SImode)
546 return MAX_COST; /* Mode is not supported. */
547 c = 29;
548 break;
549 case FLOAT:
550 c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
551 /* 4 on VAX 9000 */
552 break;
553 case FIX:
554 c = 7; /* 17 on VAX 2 */
555 break;
556 case ASHIFT:
557 case LSHIFTRT:
558 case ASHIFTRT:
559 if (mode == DImode)
560 c = 12;
561 else
562 c = 10; /* 6 on VAX 9000 */
563 break;
564 case ROTATE:
565 case ROTATERT:
566 c = 6; /* 5 on VAX 2, 4 on VAX 9000 */
567 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
568 fmt = "e"; /* all constant rotate counts are short */
569 break;
570 case PLUS:
571 /* Check for small negative integer operand: subl2 can be used with
572 a short positive constant instead. */
573 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
574 if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
575 fmt = "e";
576 case MINUS:
577 c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
578 case IOR:
579 case XOR:
580 c = 3;
581 break;
582 case AND:
583 /* AND is special because the first operand is complemented. */
584 c = 3;
585 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
586 {
587 if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
588 c = 4;
589 fmt = "e";
590 i = 1;
591 }
592 break;
593 case NEG:
594 if (mode == DFmode)
595 return 9;
596 else if (mode == SFmode)
597 return 6;
598 else if (mode == DImode)
599 return 4;
600 case NOT:
601 return 2;
602 case ZERO_EXTRACT:
603 case SIGN_EXTRACT:
604 c = 15;
605 break;
606 case MEM:
607 if (mode == DImode || mode == DFmode)
608 c = 5; /* 7 on VAX 2 */
609 else
610 c = 3; /* 4 on VAX 2 */
611 x = XEXP (x, 0);
612 if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
613 return c;
614 return c + vax_address_cost (x);
615 default:
616 c = 3;
617 break;
618 }
619
620
621 /* Now look inside the expression. Operands which are not registers or
622 short constants add to the cost.
623
624 FMT and I may have been adjusted in the switch above for instructions
625 which require special handling */
626
627 while (*fmt++ == 'e')
628 {
629 register rtx op = XEXP (x, i++);
630 code = GET_CODE (op);
631
632 /* A NOT is likely to be found as the first operand of an AND
633 (in which case the relevant cost is of the operand inside
634 the not) and not likely to be found anywhere else. */
635 if (code == NOT)
636 op = XEXP (op, 0), code = GET_CODE (op);
637
638 switch (code)
639 {
640 case CONST_INT:
641 if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
642 c += 1; /* 2 on VAX 2 */
643 break;
644 case CONST:
645 case LABEL_REF:
646 case SYMBOL_REF:
647 c += 1; /* 2 on VAX 2 */
648 break;
649 case CONST_DOUBLE:
650 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
651 {
652 /* Registers are faster than floating point constants -- even
653 those constants which can be encoded in a single byte. */
654 if (vax_float_literal (op))
655 c++;
656 else
657 c += (GET_MODE (x) == DFmode) ? 3 : 2;
658 }
659 else
660 {
661 if (CONST_DOUBLE_HIGH (op) != 0
662 || (unsigned)CONST_DOUBLE_LOW (op) > 63)
663 c += 2;
664 }
665 break;
666 case MEM:
667 c += 1; /* 2 on VAX 2 */
668 if (GET_CODE (XEXP (op, 0)) != REG)
669 c += vax_address_cost (XEXP (op, 0));
670 break;
671 case REG:
672 case SUBREG:
673 break;
674 default:
675 c += 1;
676 break;
677 }
678 }
679 return c;
680 }
681 \f
682 /* Return 1 if insn A follows B. */
683
684 static int
685 follows_p (a, b)
686 rtx a, b;
687 {
688 register rtx p;
689
690 for (p = a; p != b; p = NEXT_INSN (p))
691 if (! p)
692 return 1;
693
694 return 0;
695 }
696
697 /* Returns 1 if we know operand OP was 0 before INSN. */
698
699 int
700 reg_was_0_p (insn, op)
701 rtx insn, op;
702 {
703 rtx link;
704
705 return ((link = find_reg_note (insn, REG_WAS_0, 0))
706 /* Make sure the insn that stored the 0 is still present
707 and doesn't follow INSN in the insn sequence. */
708 && ! INSN_DELETED_P (XEXP (link, 0))
709 && GET_CODE (XEXP (link, 0)) != NOTE
710 && ! follows_p (XEXP (link, 0), insn)
711 /* Make sure cross jumping didn't happen here. */
712 && no_labels_between_p (XEXP (link, 0), insn)
713 /* Make sure the reg hasn't been clobbered. */
714 && ! reg_set_between_p (op, XEXP (link, 0), insn));
715 }
716
717 static void
718 vax_output_mi_thunk (file, thunk, delta, vcall_offset, function)
719 FILE *file;
720 tree thunk ATTRIBUTE_UNUSED;
721 HOST_WIDE_INT delta;
722 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
723 tree function;
724 {
725 fprintf (file, "\t.word 0x0ffc\n");
726 fprintf (file, "\taddl2 $");
727 fprintf (file, HOST_WIDE_INT_PRINT_DEC, delta);
728 asm_fprintf (file, ",4(%Rap)\n");
729 fprintf (file, "\tjmp ");
730 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
731 fprintf (file, "+2\n");
732 }