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.
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)
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. */
24 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
35 #include "insn-attr.h"
43 #include "target-def.h"
45 static void vax_output_function_prologue (FILE *, HOST_WIDE_INT);
46 static void vax_file_start (void);
47 static void vax_init_libfuncs (void);
48 static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
50 static int vax_address_cost_1 (rtx);
51 static int vax_address_cost (rtx);
52 static int vax_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
53 static bool vax_rtx_costs (rtx, int, int, int *);
55 /* Initialize the GCC target structure. */
56 #undef TARGET_ASM_ALIGNED_HI_OP
57 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
59 #undef TARGET_ASM_FUNCTION_PROLOGUE
60 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
62 #undef TARGET_ASM_FILE_START
63 #define TARGET_ASM_FILE_START vax_file_start
64 #undef TARGET_ASM_FILE_START_APP_OFF
65 #define TARGET_ASM_FILE_START_APP_OFF true
67 #undef TARGET_INIT_LIBFUNCS
68 #define TARGET_INIT_LIBFUNCS vax_init_libfuncs
70 #undef TARGET_ASM_OUTPUT_MI_THUNK
71 #define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
72 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
73 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
75 #undef TARGET_RTX_COSTS
76 #define TARGET_RTX_COSTS vax_rtx_costs
77 #undef TARGET_ADDRESS_COST
78 #define TARGET_ADDRESS_COST vax_address_cost
80 struct gcc_target targetm = TARGET_INITIALIZER;
82 /* Set global variables as needed for the options enabled. */
85 override_options (void)
87 /* We're VAX floating point, not IEEE floating point. */
88 memset (real_format_for_mode, 0, sizeof real_format_for_mode);
89 real_format_for_mode[SFmode - QFmode] = &vax_f_format;
90 real_format_for_mode[DFmode - QFmode]
91 = (TARGET_G_FLOAT ? &vax_g_format : &vax_d_format);
94 /* Generate the assembly code for function entry. FILE is a stdio
95 stream to output the code to. SIZE is an int: how many units of
96 temporary storage to allocate.
98 Refer to the array `regs_ever_live' to determine which registers to
99 save; `regs_ever_live[I]' is nonzero if register number I is ever
100 used in the function. This function is responsible for knowing
101 which registers should not be saved even if used. */
104 vax_output_function_prologue (FILE * file, HOST_WIDE_INT size)
107 register int mask = 0;
109 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
110 if (regs_ever_live[regno] && !call_used_regs[regno])
113 fprintf (file, "\t.word 0x%x\n", mask);
115 if (dwarf2out_do_frame ())
117 const char *label = dwarf2out_cfi_label ();
120 for (regno = FIRST_PSEUDO_REGISTER-1; regno >= 0; --regno)
121 if (regs_ever_live[regno] && !call_used_regs[regno])
122 dwarf2out_reg_save (label, regno, offset -= 4);
124 dwarf2out_reg_save (label, PC_REGNUM, offset -= 4);
125 dwarf2out_reg_save (label, FRAME_POINTER_REGNUM, offset -= 4);
126 dwarf2out_reg_save (label, ARG_POINTER_REGNUM, offset -= 4);
127 dwarf2out_def_cfa (label, FRAME_POINTER_REGNUM, -(offset - 4));
130 size -= STARTING_FRAME_OFFSET;
132 asm_fprintf (file, "\tmovab %wd(%Rsp),%Rsp\n", -size);
134 asm_fprintf (file, "\tsubl2 $%wd,%Rsp\n", size);
137 /* When debugging with stabs, we want to output an extra dummy label
138 so that gas can distinguish between D_float and G_float prior to
139 processing the .stabs directive identifying type double. */
141 vax_file_start (void)
143 default_file_start ();
145 if (write_symbols == DBX_DEBUG)
146 fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR);
149 /* We can use the BSD C library routines for the libgcc calls that are
150 still generated, since that's what they boil down to anyways. When
151 ELF, avoid the user's namespace. */
154 vax_init_libfuncs (void)
156 set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv");
157 set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__umod" : "*umod");
160 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
163 split_quadword_operands (rtx * operands, rtx * low, int n ATTRIBUTE_UNUSED)
166 /* Split operands. */
168 low[0] = low[1] = low[2] = 0;
169 for (i = 0; i < 3; i++)
172 /* it's already been figured out */;
173 else if (GET_CODE (operands[i]) == MEM
174 && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
176 rtx addr = XEXP (operands[i], 0);
177 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
178 if (which_alternative == 0 && i == 0)
180 addr = XEXP (operands[i], 0);
181 operands[i+1] = low[i+1] = gen_rtx_MEM (SImode, addr);
186 low[i] = operand_subword (operands[i], 0, 0, DImode);
187 operands[i] = operand_subword (operands[i], 1, 0, DImode);
193 print_operand_address (FILE * file, register rtx addr)
195 register rtx reg1, breg, ireg;
199 switch (GET_CODE (addr))
203 addr = XEXP (addr, 0);
207 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
211 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
215 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
219 /* There can be either two or three things added here. One must be a
220 REG. One can be either a REG or a MULT of a REG and an appropriate
221 constant, and the third can only be a constant or a MEM.
223 We get these two or three things and put the constant or MEM in
224 OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have
225 a register and can't tell yet if it is a base or index register,
228 reg1 = 0; ireg = 0; breg = 0; offset = 0;
230 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
231 || GET_CODE (XEXP (addr, 0)) == MEM)
233 offset = XEXP (addr, 0);
234 addr = XEXP (addr, 1);
236 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
237 || GET_CODE (XEXP (addr, 1)) == MEM)
239 offset = XEXP (addr, 1);
240 addr = XEXP (addr, 0);
242 else if (GET_CODE (XEXP (addr, 1)) == MULT)
244 ireg = XEXP (addr, 1);
245 addr = XEXP (addr, 0);
247 else if (GET_CODE (XEXP (addr, 0)) == MULT)
249 ireg = XEXP (addr, 0);
250 addr = XEXP (addr, 1);
252 else if (GET_CODE (XEXP (addr, 1)) == REG)
254 reg1 = XEXP (addr, 1);
255 addr = XEXP (addr, 0);
257 else if (GET_CODE (XEXP (addr, 0)) == REG)
259 reg1 = XEXP (addr, 0);
260 addr = XEXP (addr, 1);
265 if (GET_CODE (addr) == REG)
272 else if (GET_CODE (addr) == MULT)
274 else if (GET_CODE (addr) == PLUS)
276 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
277 || GET_CODE (XEXP (addr, 0)) == MEM)
281 if (GET_CODE (offset) == CONST_INT)
282 offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
283 else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
284 offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
288 offset = XEXP (addr, 0);
290 else if (GET_CODE (XEXP (addr, 0)) == REG)
293 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
295 reg1 = XEXP (addr, 0);
297 else if (GET_CODE (XEXP (addr, 0)) == MULT)
301 ireg = XEXP (addr, 0);
306 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
307 || GET_CODE (XEXP (addr, 1)) == MEM)
311 if (GET_CODE (offset) == CONST_INT)
312 offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
313 else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
314 offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
318 offset = XEXP (addr, 1);
320 else if (GET_CODE (XEXP (addr, 1)) == REG)
323 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
325 reg1 = XEXP (addr, 1);
327 else if (GET_CODE (XEXP (addr, 1)) == MULT)
331 ireg = XEXP (addr, 1);
339 /* If REG1 is nonzero, figure out if it is a base or index register. */
342 if (breg != 0 || (offset && GET_CODE (offset) == MEM))
353 output_address (offset);
356 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
360 if (GET_CODE (ireg) == MULT)
361 ireg = XEXP (ireg, 0);
362 if (GET_CODE (ireg) != REG)
364 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
369 output_addr_const (file, addr);
374 rev_cond_name (rtx op)
376 switch (GET_CODE (op))
405 vax_float_literal(register rtx c)
407 register enum machine_mode mode;
408 REAL_VALUE_TYPE r, s;
411 if (GET_CODE (c) != CONST_DOUBLE)
416 if (c == const_tiny_rtx[(int) mode][0]
417 || c == const_tiny_rtx[(int) mode][1]
418 || c == const_tiny_rtx[(int) mode][2])
421 REAL_VALUE_FROM_CONST_DOUBLE (r, c);
423 for (i = 0; i < 7; i++)
426 REAL_VALUE_FROM_INT (s, x, 0, mode);
428 if (REAL_VALUES_EQUAL (r, s))
430 if (!exact_real_inverse (mode, &s))
432 if (REAL_VALUES_EQUAL (r, s))
439 /* Return the cost in cycles of a memory address, relative to register
442 Each of the following adds the indicated number of cycles:
446 1 - indexing and/or offset(register)
451 vax_address_cost_1 (register rtx addr)
453 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
454 rtx plus_op0 = 0, plus_op1 = 0;
456 switch (GET_CODE (addr))
466 indexed = 1; /* 2 on VAX 2 */
469 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
471 offset = (unsigned)(INTVAL(addr)+128) > 256;
475 offset = 1; /* 2 on VAX 2 */
477 case LABEL_REF: /* this is probably a byte offset from the pc */
483 plus_op1 = XEXP (addr, 0);
485 plus_op0 = XEXP (addr, 0);
486 addr = XEXP (addr, 1);
489 indir = 2; /* 3 on VAX 2 */
490 addr = XEXP (addr, 0);
496 /* Up to 3 things can be added in an address. They are stored in
497 plus_op0, plus_op1, and addr. */
511 /* Indexing and register+offset can both be used (except on a VAX 2)
512 without increasing execution time over either one alone. */
513 if (reg && indexed && offset)
514 return reg + indir + offset + predec;
515 return reg + indexed + indir + offset + predec;
519 vax_address_cost (rtx x)
521 return (1 + (GET_CODE (x) == REG ? 0 : vax_address_cost_1 (x)));
524 /* Cost of an expression on a VAX. This version has costs tuned for the
525 CVAX chip (found in the VAX 3 series) with comments for variations on
529 vax_rtx_costs_1 (register rtx x, enum rtx_code code, enum rtx_code outer_code)
531 enum machine_mode mode = GET_MODE (x);
533 int i = 0; /* may be modified in switch */
534 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
538 /* On a VAX, constants from 0..63 are cheap because they can use the
539 1 byte literal constant format. compare to -1 should be made cheap
540 so that decrement-and-branch insns can be formed more easily (if
541 the value -1 is copied to a register some decrement-and-branch
542 patterns will not match). */
546 if (outer_code == AND)
547 return ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077) ? 1 : 2;
548 if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077)
550 if (outer_code == COMPARE && INTVAL (x) == -1)
552 if (outer_code == PLUS && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077)
562 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
563 return vax_float_literal (x) ? 5 : 8;
565 return (((CONST_DOUBLE_HIGH (x) == 0
566 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
567 || (outer_code == PLUS
568 && CONST_DOUBLE_HIGH (x) == -1 \
569 && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64))
580 c = 16; /* 4 on VAX 9000 */
583 c = 9; /* 4 on VAX 9000, 12 on VAX 2 */
586 c = 16; /* 6 on VAX 9000, 28 on VAX 2 */
591 c = 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
594 return MAX_COST; /* Mode is not supported. */
599 return MAX_COST; /* Mode is not supported. */
604 c = 30; /* highly variable */
605 else if (mode == DFmode)
606 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
609 c = 11; /* 25 on VAX 2 */
616 return MAX_COST; /* Mode is not supported. */
620 c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
624 c = 7; /* 17 on VAX 2 */
632 c = 10; /* 6 on VAX 9000 */
636 c = 6; /* 5 on VAX 2, 4 on VAX 9000 */
637 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
638 fmt = "e"; /* all constant rotate counts are short */
641 /* Check for small negative integer operand: subl2 can be used with
642 a short positive constant instead. */
643 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
644 if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
647 c = (mode == DFmode) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
653 /* AND is special because the first operand is complemented. */
655 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
657 if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
666 else if (mode == SFmode)
668 else if (mode == DImode)
677 if (mode == DImode || mode == DFmode)
678 c = 5; /* 7 on VAX 2 */
680 c = 3; /* 4 on VAX 2 */
682 if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
684 return c + vax_address_cost_1 (x);
690 /* Now look inside the expression. Operands which are not registers or
691 short constants add to the cost.
693 FMT and I may have been adjusted in the switch above for instructions
694 which require special handling */
696 while (*fmt++ == 'e')
698 register rtx op = XEXP (x, i++);
699 code = GET_CODE (op);
701 /* A NOT is likely to be found as the first operand of an AND
702 (in which case the relevant cost is of the operand inside
703 the not) and not likely to be found anywhere else. */
705 op = XEXP (op, 0), code = GET_CODE (op);
710 if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
711 c += 1; /* 2 on VAX 2 */
716 c += 1; /* 2 on VAX 2 */
719 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
721 /* Registers are faster than floating point constants -- even
722 those constants which can be encoded in a single byte. */
723 if (vax_float_literal (op))
726 c += (GET_MODE (x) == DFmode) ? 3 : 2;
730 if (CONST_DOUBLE_HIGH (op) != 0
731 || (unsigned)CONST_DOUBLE_LOW (op) > 63)
736 c += 1; /* 2 on VAX 2 */
737 if (GET_CODE (XEXP (op, 0)) != REG)
738 c += vax_address_cost_1 (XEXP (op, 0));
752 vax_rtx_costs (rtx x, int code, int outer_code, int * total)
754 *total = vax_rtx_costs_1 (x, code, outer_code);
758 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
759 Used for C++ multiple inheritance.
760 .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask
761 addl2 $DELTA, 4(ap) #adjust first argument
762 jmp FUNCTION+2 #jump beyond FUNCTION's entry mask
766 vax_output_mi_thunk (FILE * file,
767 tree thunk ATTRIBUTE_UNUSED,
769 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
772 fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta);
773 asm_fprintf (file, ",4(%Rap)\n");
774 fprintf (file, "\tjmp ");
775 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
776 fprintf (file, "+2\n");