Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / config / vax / vax.c
blobca5fb6ac6298632216d2c6f545f709a5da36c94f
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.
5 This file is part of GCC.
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.
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.
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. */
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"
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);
57 /* Initialize the GCC target structure. */
58 #undef TARGET_ASM_ALIGNED_HI_OP
59 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
61 #undef TARGET_ASM_FUNCTION_PROLOGUE
62 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
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
69 #undef TARGET_INIT_LIBFUNCS
70 #define TARGET_INIT_LIBFUNCS vax_init_libfuncs
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
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
82 #undef TARGET_PROMOTE_PROTOTYPES
83 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
85 #undef TARGET_STRUCT_VALUE_RTX
86 #define TARGET_STRUCT_VALUE_RTX vax_struct_value_rtx
88 struct gcc_target targetm = TARGET_INITIALIZER;
90 /* Set global variables as needed for the options enabled. */
92 void
93 override_options (void)
95 /* We're VAX floating point, not IEEE floating point. */
96 if (TARGET_G_FLOAT)
97 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
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.
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. */
109 static void
110 vax_output_function_prologue (FILE * file, HOST_WIDE_INT size)
112 register int regno;
113 register int mask = 0;
115 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
116 if (regs_ever_live[regno] && !call_used_regs[regno])
117 mask |= 1 << regno;
119 fprintf (file, "\t.word 0x%x\n", mask);
121 if (dwarf2out_do_frame ())
123 const char *label = dwarf2out_cfi_label ();
124 int offset = 0;
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);
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));
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);
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)
149 default_file_start ();
151 if (write_symbols == DBX_DEBUG)
152 fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR);
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. */
159 static void
160 vax_init_libfuncs (void)
162 set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv");
163 set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__urem" : "*urem");
166 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
168 void
169 split_quadword_operands (rtx * operands, rtx * low, int n ATTRIBUTE_UNUSED)
171 int i;
172 /* Split operands. */
174 low[0] = low[1] = low[2] = 0;
175 for (i = 0; i < 3; i++)
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))
182 rtx addr = XEXP (operands[i], 0);
183 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
184 if (which_alternative == 0 && i == 0)
186 addr = XEXP (operands[i], 0);
187 operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
190 else
192 low[i] = operand_subword (operands[i], 0, 0, DImode);
193 operands[i] = operand_subword (operands[i], 1, 0, DImode);
198 void
199 print_operand_address (FILE * file, register rtx addr)
201 register rtx reg1, breg, ireg;
202 rtx offset;
204 retry:
205 switch (GET_CODE (addr))
207 case MEM:
208 fprintf (file, "*");
209 addr = XEXP (addr, 0);
210 goto retry;
212 case REG:
213 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
214 break;
216 case PRE_DEC:
217 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
218 break;
220 case POST_INC:
221 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
222 break;
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.
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. */
234 reg1 = 0; ireg = 0; breg = 0; offset = 0;
236 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
237 || GET_CODE (XEXP (addr, 0)) == MEM)
239 offset = XEXP (addr, 0);
240 addr = XEXP (addr, 1);
242 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
243 || GET_CODE (XEXP (addr, 1)) == MEM)
245 offset = XEXP (addr, 1);
246 addr = XEXP (addr, 0);
248 else if (GET_CODE (XEXP (addr, 1)) == MULT)
250 ireg = XEXP (addr, 1);
251 addr = XEXP (addr, 0);
253 else if (GET_CODE (XEXP (addr, 0)) == MULT)
255 ireg = XEXP (addr, 0);
256 addr = XEXP (addr, 1);
258 else if (GET_CODE (XEXP (addr, 1)) == REG)
260 reg1 = XEXP (addr, 1);
261 addr = XEXP (addr, 0);
263 else if (GET_CODE (XEXP (addr, 0)) == REG)
265 reg1 = XEXP (addr, 0);
266 addr = XEXP (addr, 1);
268 else
269 abort ();
271 if (GET_CODE (addr) == REG)
273 if (reg1)
274 ireg = addr;
275 else
276 reg1 = addr;
278 else if (GET_CODE (addr) == MULT)
279 ireg = addr;
280 else if (GET_CODE (addr) == PLUS)
282 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
283 || GET_CODE (XEXP (addr, 0)) == MEM)
285 if (offset)
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 ();
294 offset = XEXP (addr, 0);
296 else if (GET_CODE (XEXP (addr, 0)) == REG)
298 if (reg1)
299 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
300 else
301 reg1 = XEXP (addr, 0);
303 else if (GET_CODE (XEXP (addr, 0)) == MULT)
305 if (ireg)
306 abort ();
307 ireg = XEXP (addr, 0);
309 else
310 abort ();
312 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
313 || GET_CODE (XEXP (addr, 1)) == MEM)
315 if (offset)
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 ();
324 offset = XEXP (addr, 1);
326 else if (GET_CODE (XEXP (addr, 1)) == REG)
328 if (reg1)
329 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
330 else
331 reg1 = XEXP (addr, 1);
333 else if (GET_CODE (XEXP (addr, 1)) == MULT)
335 if (ireg)
336 abort ();
337 ireg = XEXP (addr, 1);
339 else
340 abort ();
342 else
343 abort ();
345 /* If REG1 is nonzero, figure out if it is a base or index register. */
346 if (reg1)
348 if (breg != 0 || (offset && GET_CODE (offset) == MEM))
350 if (ireg)
351 abort ();
352 ireg = reg1;
354 else
355 breg = reg1;
358 if (offset != 0)
359 output_address (offset);
361 if (breg != 0)
362 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
364 if (ireg != 0)
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)]);
372 break;
374 default:
375 output_addr_const (file, addr);
379 const char *
380 rev_cond_name (rtx op)
382 switch (GET_CODE (op))
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";
405 default:
406 abort ();
411 vax_float_literal(register rtx c)
413 register enum machine_mode mode;
414 REAL_VALUE_TYPE r, s;
415 int i;
417 if (GET_CODE (c) != CONST_DOUBLE)
418 return 0;
420 mode = GET_MODE (c);
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;
427 REAL_VALUE_FROM_CONST_DOUBLE (r, c);
429 for (i = 0; i < 7; i++)
431 int x = 1 << i;
432 REAL_VALUE_FROM_INT (s, x, 0, mode);
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;
441 return 0;
445 /* Return the cost in cycles of a memory address, relative to register
446 indirect.
448 Each of the following adds the indicated number of cycles:
450 1 - symbolic address
451 1 - pre-decrement
452 1 - indexing and/or offset(register)
453 2 - indirect */
456 static int
457 vax_address_cost_1 (register rtx addr)
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))
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 HOST_WIDE_INT)(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;
502 /* Up to 3 things can be added in an address. They are stored in
503 plus_op0, plus_op1, and addr. */
505 if (plus_op0)
507 addr = plus_op0;
508 plus_op0 = 0;
509 goto restart;
511 if (plus_op1)
513 addr = plus_op1;
514 plus_op1 = 0;
515 goto restart;
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;
524 static int
525 vax_address_cost (rtx x)
527 return (1 + (GET_CODE (x) == REG ? 0 : vax_address_cost_1 (x)));
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. */
534 static int
535 vax_rtx_costs_1 (register rtx x, enum rtx_code code, enum rtx_code outer_code)
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 */
542 switch (code)
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 */
562 case CONST:
563 case LABEL_REF:
564 case SYMBOL_REF:
565 return 3;
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);
578 case POST_INC:
579 return 2;
580 case PRE_DEC:
581 return 3;
582 case MULT:
583 switch (mode)
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. */
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 case MINUS:
648 c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
649 /* Small integer operands can use subl2 and addl2. */
650 if ((GET_CODE (XEXP (x, 1)) == CONST_INT)
651 && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127)
652 fmt = "e";
653 break;
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)
663 if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63)
664 c = 4;
665 fmt = "e";
666 i = 1;
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;
696 /* Now look inside the expression. Operands which are not registers or
697 short constants add to the cost.
699 FMT and I may have been adjusted in the switch above for instructions
700 which require special handling */
702 while (*fmt++ == 'e')
704 register rtx op = XEXP (x, i++);
705 code = GET_CODE (op);
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);
713 switch (code)
715 case CONST_INT:
716 if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63
717 && GET_MODE (x) != QImode)
718 c += 1; /* 2 on VAX 2 */
719 break;
720 case CONST:
721 case LABEL_REF:
722 case SYMBOL_REF:
723 c += 1; /* 2 on VAX 2 */
724 break;
725 case CONST_DOUBLE:
726 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
728 /* Registers are faster than floating point constants -- even
729 those constants which can be encoded in a single byte. */
730 if (vax_float_literal (op))
731 c++;
732 else
733 c += (GET_MODE (x) == DFmode) ? 3 : 2;
735 else
737 if (CONST_DOUBLE_HIGH (op) != 0
738 || (unsigned)CONST_DOUBLE_LOW (op) > 63)
739 c += 2;
741 break;
742 case MEM:
743 c += 1; /* 2 on VAX 2 */
744 if (GET_CODE (XEXP (op, 0)) != REG)
745 c += vax_address_cost_1 (XEXP (op, 0));
746 break;
747 case REG:
748 case SUBREG:
749 break;
750 default:
751 c += 1;
752 break;
755 return c;
758 static bool
759 vax_rtx_costs (rtx x, int code, int outer_code, int * total)
761 *total = vax_rtx_costs_1 (x, code, outer_code);
762 return true;
765 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
766 Used for C++ multiple inheritance.
767 .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask
768 addl2 $DELTA, 4(ap) #adjust first argument
769 jmp FUNCTION+2 #jump beyond FUNCTION's entry mask
772 static void
773 vax_output_mi_thunk (FILE * file,
774 tree thunk ATTRIBUTE_UNUSED,
775 HOST_WIDE_INT delta,
776 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
777 tree function)
779 fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta);
780 asm_fprintf (file, ",4(%Rap)\n");
781 fprintf (file, "\tjmp ");
782 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
783 fprintf (file, "+2\n");
786 static rtx
787 vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
788 int incoming ATTRIBUTE_UNUSED)
790 return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
793 /* Worker function for NOTICE_UPDATE_CC. */
795 void
796 vax_notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
798 if (GET_CODE (exp) == SET)
800 if (GET_CODE (SET_SRC (exp)) == CALL)
801 CC_STATUS_INIT;
802 else if (GET_CODE (SET_DEST (exp)) != ZERO_EXTRACT
803 && GET_CODE (SET_DEST (exp)) != PC)
805 cc_status.flags = 0;
806 /* The integer operations below don't set carry or
807 set it in an incompatible way. That's ok though
808 as the Z bit is all we need when doing unsigned
809 comparisons on the result of these insns (since
810 they're always with 0). Set CC_NO_OVERFLOW to
811 generate the correct unsigned branches. */
812 switch (GET_CODE (SET_SRC (exp)))
814 case NEG:
815 if (GET_MODE_CLASS (GET_MODE (exp)) == MODE_FLOAT)
816 break;
817 case AND:
818 case IOR:
819 case XOR:
820 case NOT:
821 case MEM:
822 case REG:
823 cc_status.flags = CC_NO_OVERFLOW;
824 break;
825 default:
826 break;
828 cc_status.value1 = SET_DEST (exp);
829 cc_status.value2 = SET_SRC (exp);
832 else if (GET_CODE (exp) == PARALLEL
833 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
835 if (GET_CODE (SET_SRC (XVECEXP (exp, 0, 0))) == CALL)
836 CC_STATUS_INIT;
837 else if (GET_CODE (SET_DEST (XVECEXP (exp, 0, 0))) != PC)
839 cc_status.flags = 0;
840 cc_status.value1 = SET_DEST (XVECEXP (exp, 0, 0));
841 cc_status.value2 = SET_SRC (XVECEXP (exp, 0, 0));
843 else
844 /* PARALLELs whose first element sets the PC are aob,
845 sob insns. They do change the cc's. */
846 CC_STATUS_INIT;
848 else
849 CC_STATUS_INIT;
850 if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
851 && cc_status.value2
852 && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
853 cc_status.value2 = 0;
854 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
855 && cc_status.value2
856 && GET_CODE (cc_status.value2) == MEM)
857 cc_status.value2 = 0;
858 /* Actual condition, one line up, should be that value2's address
859 depends on value1, but that is too much of a pain. */