]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/vax/vax.c
* config/alpha/alpha.c, config/arc/arc.c, config/avr/avr.c,
[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, 2004
3 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC 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 GCC 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 GCC; 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 "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 int vax_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
54 static bool vax_rtx_costs (rtx, int, int, int *);
55 static rtx vax_struct_value_rtx (tree, int);
56 \f
57 /* Initialize the GCC target structure. */
58 #undef TARGET_ASM_ALIGNED_HI_OP
59 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
60
61 #undef TARGET_ASM_FUNCTION_PROLOGUE
62 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
63
64 #undef TARGET_ASM_FILE_START
65 #define TARGET_ASM_FILE_START vax_file_start
66 #undef TARGET_ASM_FILE_START_APP_OFF
67 #define TARGET_ASM_FILE_START_APP_OFF true
68
69 #undef TARGET_INIT_LIBFUNCS
70 #define TARGET_INIT_LIBFUNCS vax_init_libfuncs
71
72 #undef TARGET_ASM_OUTPUT_MI_THUNK
73 #define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
74 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
75 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
76
77 #undef TARGET_RTX_COSTS
78 #define TARGET_RTX_COSTS vax_rtx_costs
79 #undef TARGET_ADDRESS_COST
80 #define TARGET_ADDRESS_COST vax_address_cost
81
82 #undef TARGET_PROMOTE_PROTOTYPES
83 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
84
85 #undef TARGET_STRUCT_VALUE_RTX
86 #define TARGET_STRUCT_VALUE_RTX vax_struct_value_rtx
87
88 struct gcc_target targetm = TARGET_INITIALIZER;
89 \f
90 /* Set global variables as needed for the options enabled. */
91
92 void
93 override_options (void)
94 {
95 /* We're VAX floating point, not IEEE floating point. */
96 if (TARGET_G_FLOAT)
97 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
98 }
99
100 /* Generate the assembly code for function entry. FILE is a stdio
101 stream to output the code to. SIZE is an int: how many units of
102 temporary storage to allocate.
103
104 Refer to the array `regs_ever_live' to determine which registers to
105 save; `regs_ever_live[I]' is nonzero if register number I is ever
106 used in the function. This function is responsible for knowing
107 which registers should not be saved even if used. */
108
109 static void
110 vax_output_function_prologue (FILE * file, HOST_WIDE_INT size)
111 {
112 register int regno;
113 register int mask = 0;
114
115 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
116 if (regs_ever_live[regno] && !call_used_regs[regno])
117 mask |= 1 << regno;
118
119 fprintf (file, "\t.word 0x%x\n", mask);
120
121 if (dwarf2out_do_frame ())
122 {
123 const char *label = dwarf2out_cfi_label ();
124 int offset = 0;
125
126 for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno)
127 if (regs_ever_live[regno] && !call_used_regs[regno])
128 dwarf2out_reg_save (label, regno, offset -= 4);
129
130 dwarf2out_reg_save (label, PC_REGNUM, offset -= 4);
131 dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4);
132 dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4);
133 dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4));
134 }
135
136 size -= STARTING_FRAME_OFFSET;
137 if (size >= 64)
138 asm_fprintf (file, "\tmovab %wd(%Rsp),%Rsp\n", -size);
139 else if (size)
140 asm_fprintf (file, "\tsubl2 $%wd,%Rsp\n", size);
141 }
142
143 /* When debugging with stabs, we want to output an extra dummy label
144 so that gas can distinguish between D_float and G_float prior to
145 processing the .stabs directive identifying type double. */
146 static void
147 vax_file_start (void)
148 {
149 default_file_start ();
150
151 if (write_symbols == DBX_DEBUG)
152 fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR);
153 }
154
155 /* We can use the BSD C library routines for the libgcc calls that are
156 still generated, since that's what they boil down to anyways. When
157 ELF, avoid the user's namespace. */
158
159 static void
160 vax_init_libfuncs (void)
161 {
162 set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv");
163 set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__urem" : "*urem");
164 }
165
166 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
167
168 void
169 split_quadword_operands (rtx * operands, rtx * low, int n ATTRIBUTE_UNUSED)
170 {
171 int i;
172 /* Split operands. */
173
174 low[0] = low[1] = low[2] = 0;
175 for (i = 0; i < 3; i++)
176 {
177 if (low[i])
178 /* it's already been figured out */;
179 else if (GET_CODE (operands[i]) == MEM
180 && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
181 {
182 rtx addr = XEXP (operands[i], 0);
183 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
184 if (which_alternative == 0 && i == 0)
185 {
186 addr = XEXP (operands[i], 0);
187 operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
188 }
189 }
190 else
191 {
192 low[i] = operand_subword (operands[i], 0, 0, DImode);
193 operands[i] = operand_subword (operands[i], 1, 0, DImode);
194 }
195 }
196 }
197 \f
198 void
199 print_operand_address (FILE * file, register rtx addr)
200 {
201 register rtx reg1, breg, ireg;
202 rtx offset;
203
204 retry:
205 switch (GET_CODE (addr))
206 {
207 case MEM:
208 fprintf (file, "*");
209 addr = XEXP (addr, 0);
210 goto retry;
211
212 case REG:
213 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
214 break;
215
216 case PRE_DEC:
217 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
218 break;
219
220 case POST_INC:
221 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
222 break;
223
224 case PLUS:
225 /* There can be either two or three things added here. One must be a
226 REG. One can be either a REG or a MULT of a REG and an appropriate
227 constant, and the third can only be a constant or a MEM.
228
229 We get these two or three things and put the constant or MEM in
230 OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have
231 a register and can't tell yet if it is a base or index register,
232 put it into REG1. */
233
234 reg1 = 0; ireg = 0; breg = 0; offset = 0;
235
236 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
237 || GET_CODE (XEXP (addr, 0)) == MEM)
238 {
239 offset = XEXP (addr, 0);
240 addr = XEXP (addr, 1);
241 }
242 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
243 || GET_CODE (XEXP (addr, 1)) == MEM)
244 {
245 offset = XEXP (addr, 1);
246 addr = XEXP (addr, 0);
247 }
248 else if (GET_CODE (XEXP (addr, 1)) == MULT)
249 {
250 ireg = XEXP (addr, 1);
251 addr = XEXP (addr, 0);
252 }
253 else if (GET_CODE (XEXP (addr, 0)) == MULT)
254 {
255 ireg = XEXP (addr, 0);
256 addr = XEXP (addr, 1);
257 }
258 else if (GET_CODE (XEXP (addr, 1)) == REG)
259 {
260 reg1 = XEXP (addr, 1);
261 addr = XEXP (addr, 0);
262 }
263 else if (GET_CODE (XEXP (addr, 0)) == REG)
264 {
265 reg1 = XEXP (addr, 0);
266 addr = XEXP (addr, 1);
267 }
268 else
269 abort ();
270
271 if (GET_CODE (addr) == REG)
272 {
273 if (reg1)
274 ireg = addr;
275 else
276 reg1 = addr;
277 }
278 else if (GET_CODE (addr) == MULT)
279 ireg = addr;
280 else if (GET_CODE (addr) == PLUS)
281 {
282 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
283 || GET_CODE (XEXP (addr, 0)) == MEM)
284 {
285 if (offset)
286 {
287 if (GET_CODE (offset) == CONST_INT)
288 offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
289 else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
290 offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
291 else
292 abort ();
293 }
294 offset = XEXP (addr, 0);
295 }
296 else if (GET_CODE (XEXP (addr, 0)) == REG)
297 {
298 if (reg1)
299 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
300 else
301 reg1 = XEXP (addr, 0);
302 }
303 else if (GET_CODE (XEXP (addr, 0)) == MULT)
304 {
305 if (ireg)
306 abort ();
307 ireg = XEXP (addr, 0);
308 }
309 else
310 abort ();
311
312 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
313 || GET_CODE (XEXP (addr, 1)) == MEM)
314 {
315 if (offset)
316 {
317 if (GET_CODE (offset) == CONST_INT)
318 offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
319 else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
320 offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
321 else
322 abort ();
323 }
324 offset = XEXP (addr, 1);
325 }
326 else if (GET_CODE (XEXP (addr, 1)) == REG)
327 {
328 if (reg1)
329 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
330 else
331 reg1 = XEXP (addr, 1);
332 }
333 else if (GET_CODE (XEXP (addr, 1)) == MULT)
334 {
335 if (ireg)
336 abort ();
337 ireg = XEXP (addr, 1);
338 }
339 else
340 abort ();
341 }
342 else
343 abort ();
344
345 /* If REG1 is nonzero, figure out if it is a base or index register. */
346 if (reg1)
347 {
348 if (breg != 0 || (offset && GET_CODE (offset) == MEM))
349 {
350 if (ireg)
351 abort ();
352 ireg = reg1;
353 }
354 else
355 breg = reg1;
356 }
357
358 if (offset != 0)
359 output_address (offset);
360
361 if (breg != 0)
362 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
363
364 if (ireg != 0)
365 {
366 if (GET_CODE (ireg) == MULT)
367 ireg = XEXP (ireg, 0);
368 if (GET_CODE (ireg) != REG)
369 abort ();
370 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
371 }
372 break;
373
374 default:
375 output_addr_const (file, addr);
376 }
377 }
378 \f
379 const char *
380 rev_cond_name (rtx op)
381 {
382 switch (GET_CODE (op))
383 {
384 case EQ:
385 return "neq";
386 case NE:
387 return "eql";
388 case LT:
389 return "geq";
390 case LE:
391 return "gtr";
392 case GT:
393 return "leq";
394 case GE:
395 return "lss";
396 case LTU:
397 return "gequ";
398 case LEU:
399 return "gtru";
400 case GTU:
401 return "lequ";
402 case GEU:
403 return "lssu";
404
405 default:
406 abort ();
407 }
408 }
409
410 int
411 vax_float_literal(register rtx c)
412 {
413 register enum machine_mode mode;
414 REAL_VALUE_TYPE r, s;
415 int i;
416
417 if (GET_CODE (c) != CONST_DOUBLE)
418 return 0;
419
420 mode = GET_MODE (c);
421
422 if (c == const_tiny_rtx[(int) mode][0]
423 || c == const_tiny_rtx[(int) mode][1]
424 || c == const_tiny_rtx[(int) mode][2])
425 return 1;
426
427 REAL_VALUE_FROM_CONST_DOUBLE (r, c);
428
429 for (i = 0; i < 7; i++)
430 {
431 int x = 1 << i;
432 REAL_VALUE_FROM_INT (s, x, 0, mode);
433
434 if (REAL_VALUES_EQUAL (r, s))
435 return 1;
436 if (!exact_real_inverse (mode, &s))
437 abort ();
438 if (REAL_VALUES_EQUAL (r, s))
439 return 1;
440 }
441 return 0;
442 }
443
444
445 /* Return the cost in cycles of a memory address, relative to register
446 indirect.
447
448 Each of the following adds the indicated number of cycles:
449
450 1 - symbolic address
451 1 - pre-decrement
452 1 - indexing and/or offset(register)
453 2 - indirect */
454
455
456 static int
457 vax_address_cost_1 (register rtx addr)
458 {
459 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
460 rtx plus_op0 = 0, plus_op1 = 0;
461 restart:
462 switch (GET_CODE (addr))
463 {
464 case PRE_DEC:
465 predec = 1;
466 case REG:
467 case SUBREG:
468 case POST_INC:
469 reg = 1;
470 break;
471 case MULT:
472 indexed = 1; /* 2 on VAX 2 */
473 break;
474 case CONST_INT:
475 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
476 if (offset == 0)
477 offset = (unsigned)(INTVAL(addr)+128) > 256;
478 break;
479 case CONST:
480 case SYMBOL_REF:
481 offset = 1; /* 2 on VAX 2 */
482 break;
483 case LABEL_REF: /* this is probably a byte offset from the pc */
484 if (offset == 0)
485 offset = 1;
486 break;
487 case PLUS:
488 if (plus_op0)
489 plus_op1 = XEXP (addr, 0);
490 else
491 plus_op0 = XEXP (addr, 0);
492 addr = XEXP (addr, 1);
493 goto restart;
494 case MEM:
495 indir = 2; /* 3 on VAX 2 */
496 addr = XEXP (addr, 0);
497 goto restart;
498 default:
499 break;
500 }
501
502 /* Up to 3 things can be added in an address. They are stored in
503 plus_op0, plus_op1, and addr. */
504
505 if (plus_op0)
506 {
507 addr = plus_op0;
508 plus_op0 = 0;
509 goto restart;
510 }
511 if (plus_op1)
512 {
513 addr = plus_op1;
514 plus_op1 = 0;
515 goto restart;
516 }
517 /* Indexing and register+offset can both be used (except on a VAX 2)
518 without increasing execution time over either one alone. */
519 if (reg && indexed && offset)
520 return reg + indir + offset + predec;
521 return reg + indexed + indir + offset + predec;
522 }
523
524 static int
525 vax_address_cost (rtx x)
526 {
527 return (1 + (GET_CODE (x) == REG ? 0 : vax_address_cost_1 (x)));
528 }
529
530 /* Cost of an expression on a VAX. This version has costs tuned for the
531 CVAX chip (found in the VAX 3 series) with comments for variations on
532 other models. */
533
534 static int
535 vax_rtx_costs_1 (register rtx x, enum rtx_code code, enum rtx_code outer_code)
536 {
537 enum machine_mode mode = GET_MODE (x);
538 register int c;
539 int i = 0; /* may be modified in switch */
540 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
541
542 switch (code)
543 {
544 /* On a VAX, constants from 0..63 are cheap because they can use the
545 1 byte literal constant format. compare to -1 should be made cheap
546 so that decrement-and-branch insns can be formed more easily (if
547 the value -1 is copied to a register some decrement-and-branch
548 patterns will not match). */
549 case CONST_INT:
550 if (INTVAL (x) == 0)
551 return 0;
552 if (outer_code == AND)
553 return ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2;
554 if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077)
555 return 1;
556 if (outer_code == COMPARE && INTVAL (x) == -1)
557 return 1;
558 if (outer_code == PLUS && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077)
559 return 1;
560 /* FALLTHRU */
561
562 case CONST:
563 case LABEL_REF:
564 case SYMBOL_REF:
565 return 3;
566
567 case CONST_DOUBLE:
568 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
569 return vax_float_literal (x) ? 5 : 8;
570 else
571 return (((CONST_DOUBLE_HIGH (x) == 0
572 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
573 || (outer_code == PLUS
574 && CONST_DOUBLE_HIGH (x) == -1 \
575 && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64))
576 ? 2 : 5);
577
578 case POST_INC:
579 return 2;
580 case PRE_DEC:
581 return 3;
582 case MULT:
583 switch (mode)
584 {
585 case DFmode:
586 c = 16; /* 4 on VAX 9000 */
587 break;
588 case SFmode:
589 c = 9; /* 4 on VAX 9000, 12 on VAX 2 */
590 break;
591 case DImode:
592 c = 16; /* 6 on VAX 9000, 28 on VAX 2 */
593 break;
594 case SImode:
595 case HImode:
596 case QImode:
597 c = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
598 break;
599 default:
600 return MAX_COST; /* Mode is not supported. */
601 }
602 break;
603 case UDIV:
604 if (mode != SImode)
605 return MAX_COST; /* Mode is not supported. */
606 c = 17;
607 break;
608 case DIV:
609 if (mode == DImode)
610 c = 30; /* highly variable */
611 else if (mode == DFmode)
612 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
613 c = 24;
614 else
615 c = 11; /* 25 on VAX 2 */
616 break;
617 case MOD:
618 c = 23;
619 break;
620 case UMOD:
621 if (mode != SImode)
622 return MAX_COST; /* Mode is not supported. */
623 c = 29;
624 break;
625 case FLOAT:
626 c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
627 /* 4 on VAX 9000 */
628 break;
629 case FIX:
630 c = 7; /* 17 on VAX 2 */
631 break;
632 case ASHIFT:
633 case LSHIFTRT:
634 case ASHIFTRT:
635 if (mode == DImode)
636 c = 12;
637 else
638 c = 10; /* 6 on VAX 9000 */
639 break;
640 case ROTATE:
641 case ROTATERT:
642 c = 6; /* 5 on VAX 2, 4 on VAX 9000 */
643 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
644 fmt = "e"; /* all constant rotate counts are short */
645 break;
646 case PLUS:
647 /* Check for small negative integer operand: subl2 can be used with
648 a short positive constant instead. */
649 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
650 if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
651 fmt = "e";
652 case MINUS:
653 c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
654 case IOR:
655 case XOR:
656 c = 3;
657 break;
658 case AND:
659 /* AND is special because the first operand is complemented. */
660 c = 3;
661 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
662 {
663 if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
664 c = 4;
665 fmt = "e";
666 i = 1;
667 }
668 break;
669 case NEG:
670 if (mode == DFmode)
671 return 9;
672 else if (mode == SFmode)
673 return 6;
674 else if (mode == DImode)
675 return 4;
676 case NOT:
677 return 2;
678 case ZERO_EXTRACT:
679 case SIGN_EXTRACT:
680 c = 15;
681 break;
682 case MEM:
683 if (mode == DImode || mode == DFmode)
684 c = 5; /* 7 on VAX 2 */
685 else
686 c = 3; /* 4 on VAX 2 */
687 x = XEXP (x, 0);
688 if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
689 return c;
690 return c + vax_address_cost_1 (x);
691 default:
692 c = 3;
693 break;
694 }
695
696 /* Now look inside the expression. Operands which are not registers or
697 short constants add to the cost.
698
699 FMT and I may have been adjusted in the switch above for instructions
700 which require special handling */
701
702 while (*fmt++ == 'e')
703 {
704 register rtx op = XEXP (x, i++);
705 code = GET_CODE (op);
706
707 /* A NOT is likely to be found as the first operand of an AND
708 (in which case the relevant cost is of the operand inside
709 the not) and not likely to be found anywhere else. */
710 if (code == NOT)
711 op = XEXP (op, 0), code = GET_CODE (op);
712
713 switch (code)
714 {
715 case CONST_INT:
716 if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
717 c += 1; /* 2 on VAX 2 */
718 break;
719 case CONST:
720 case LABEL_REF:
721 case SYMBOL_REF:
722 c += 1; /* 2 on VAX 2 */
723 break;
724 case CONST_DOUBLE:
725 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
726 {
727 /* Registers are faster than floating point constants -- even
728 those constants which can be encoded in a single byte. */
729 if (vax_float_literal (op))
730 c++;
731 else
732 c += (GET_MODE (x) == DFmode) ? 3 : 2;
733 }
734 else
735 {
736 if (CONST_DOUBLE_HIGH (op) != 0
737 || (unsigned)CONST_DOUBLE_LOW (op) > 63)
738 c += 2;
739 }
740 break;
741 case MEM:
742 c += 1; /* 2 on VAX 2 */
743 if (GET_CODE (XEXP (op, 0)) != REG)
744 c += vax_address_cost_1 (XEXP (op, 0));
745 break;
746 case REG:
747 case SUBREG:
748 break;
749 default:
750 c += 1;
751 break;
752 }
753 }
754 return c;
755 }
756
757 static bool
758 vax_rtx_costs (rtx x, int code, int outer_code, int * total)
759 {
760 *total = vax_rtx_costs_1 (x, code, outer_code);
761 return true;
762 }
763 \f
764 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
765 Used for C++ multiple inheritance.
766 .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask
767 addl2 $DELTA, 4(ap) #adjust first argument
768 jmp FUNCTION+2 #jump beyond FUNCTION's entry mask
769 */
770
771 static void
772 vax_output_mi_thunk (FILE * file,
773 tree thunk ATTRIBUTE_UNUSED,
774 HOST_WIDE_INT delta,
775 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
776 tree function)
777 {
778 fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta);
779 asm_fprintf (file, ",4(%Rap)\n");
780 fprintf (file, "\tjmp ");
781 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
782 fprintf (file, "+2\n");
783 }
784 \f
785 static rtx
786 vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
787 int incoming ATTRIBUTE_UNUSED)
788 {
789 return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
790 }