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"
42 #include "target-def.h"
44 static int follows_p
PARAMS ((rtx
, rtx
));
45 static void vax_output_function_prologue
PARAMS ((FILE *, HOST_WIDE_INT
));
46 static void vax_file_start
PARAMS ((void));
47 static void vax_output_mi_thunk
PARAMS ((FILE *, tree
, HOST_WIDE_INT
,
48 HOST_WIDE_INT
, tree
));
49 static int vax_address_cost_1
PARAMS ((rtx
));
50 static int vax_address_cost
PARAMS ((rtx
));
51 static int vax_rtx_costs_1
PARAMS ((rtx
, enum rtx_code
, enum rtx_code
));
52 static bool vax_rtx_costs
PARAMS ((rtx
, int, int, int *));
54 /* Initialize the GCC target structure. */
55 #undef TARGET_ASM_ALIGNED_HI_OP
56 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
58 #undef TARGET_ASM_FUNCTION_PROLOGUE
59 #define TARGET_ASM_FUNCTION_PROLOGUE vax_output_function_prologue
61 #undef TARGET_ASM_FILE_START
62 #define TARGET_ASM_FILE_START vax_file_start
63 #undef TARGET_ASM_FILE_START_APP_OFF
64 #define TARGET_ASM_FILE_START_APP_OFF true
66 #undef TARGET_ASM_OUTPUT_MI_THUNK
67 #define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
68 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
69 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
71 #undef TARGET_RTX_COSTS
72 #define TARGET_RTX_COSTS vax_rtx_costs
73 #undef TARGET_ADDRESS_COST
74 #define TARGET_ADDRESS_COST vax_address_cost
76 struct gcc_target targetm
= TARGET_INITIALIZER
;
78 /* Set global variables as needed for the options enabled. */
83 /* We're VAX floating point, not IEEE floating point. */
84 memset (real_format_for_mode
, 0, sizeof real_format_for_mode
);
85 real_format_for_mode
[SFmode
- QFmode
] = &vax_f_format
;
86 real_format_for_mode
[DFmode
- QFmode
]
87 = (TARGET_G_FLOAT
? &vax_g_format
: &vax_d_format
);
90 /* Generate the assembly code for function entry. FILE is a stdio
91 stream to output the code to. SIZE is an int: how many units of
92 temporary storage to allocate.
94 Refer to the array `regs_ever_live' to determine which registers to
95 save; `regs_ever_live[I]' is nonzero if register number I is ever
96 used in the function. This function is responsible for knowing
97 which registers should not be saved even if used. */
100 vax_output_function_prologue (file
, size
)
105 register int mask
= 0;
107 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
108 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
111 fprintf (file
, "\t.word 0x%x\n", mask
);
113 if (dwarf2out_do_frame ())
115 const char *label
= dwarf2out_cfi_label ();
118 for (regno
= FIRST_PSEUDO_REGISTER
-1; regno
>= 0; --regno
)
119 if (regs_ever_live
[regno
] && !call_used_regs
[regno
])
120 dwarf2out_reg_save (label
, regno
, offset
-= 4);
122 dwarf2out_reg_save (label
, PC_REGNUM
, offset
-= 4);
123 dwarf2out_reg_save (label
, FRAME_POINTER_REGNUM
, offset
-= 4);
124 dwarf2out_reg_save (label
, ARG_POINTER_REGNUM
, offset
-= 4);
125 dwarf2out_def_cfa (label
, FRAME_POINTER_REGNUM
, -(offset
- 4));
128 size
-= STARTING_FRAME_OFFSET
;
130 asm_fprintf (file
, "\tmovab %wd(%Rsp),%Rsp\n", -size
);
132 asm_fprintf (file
, "\tsubl2 $%wd,%Rsp\n", size
);
135 /* When debugging with stabs, we want to output an extra dummy label
136 so that gas can distinguish between D_float and G_float prior to
137 processing the .stabs directive identifying type double. */
141 default_file_start ();
143 if (write_symbols
== DBX_DEBUG
)
144 fprintf (asm_out_file
, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR
);
147 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
150 split_quadword_operands (operands
, low
, n
)
152 int n ATTRIBUTE_UNUSED
;
155 /* Split operands. */
157 low
[0] = low
[1] = low
[2] = 0;
158 for (i
= 0; i
< 3; i
++)
161 /* it's already been figured out */;
162 else if (GET_CODE (operands
[i
]) == MEM
163 && (GET_CODE (XEXP (operands
[i
], 0)) == POST_INC
))
165 rtx addr
= XEXP (operands
[i
], 0);
166 operands
[i
] = low
[i
] = gen_rtx_MEM (SImode
, addr
);
167 if (which_alternative
== 0 && i
== 0)
169 addr
= XEXP (operands
[i
], 0);
170 operands
[i
+1] = low
[i
+1] = gen_rtx_MEM (SImode
, addr
);
175 low
[i
] = operand_subword (operands
[i
], 0, 0, DImode
);
176 operands
[i
] = operand_subword (operands
[i
], 1, 0, DImode
);
182 print_operand_address (file
, addr
)
186 register rtx reg1
, breg
, ireg
;
190 switch (GET_CODE (addr
))
194 addr
= XEXP (addr
, 0);
198 fprintf (file
, "(%s)", reg_names
[REGNO (addr
)]);
202 fprintf (file
, "-(%s)", reg_names
[REGNO (XEXP (addr
, 0))]);
206 fprintf (file
, "(%s)+", reg_names
[REGNO (XEXP (addr
, 0))]);
210 /* There can be either two or three things added here. One must be a
211 REG. One can be either a REG or a MULT of a REG and an appropriate
212 constant, and the third can only be a constant or a MEM.
214 We get these two or three things and put the constant or MEM in
215 OFFSET, the MULT or REG in IREG, and the REG in BREG. If we have
216 a register and can't tell yet if it is a base or index register,
219 reg1
= 0; ireg
= 0; breg
= 0; offset
= 0;
221 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0))
222 || GET_CODE (XEXP (addr
, 0)) == MEM
)
224 offset
= XEXP (addr
, 0);
225 addr
= XEXP (addr
, 1);
227 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1))
228 || GET_CODE (XEXP (addr
, 1)) == MEM
)
230 offset
= XEXP (addr
, 1);
231 addr
= XEXP (addr
, 0);
233 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
235 ireg
= XEXP (addr
, 1);
236 addr
= XEXP (addr
, 0);
238 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
240 ireg
= XEXP (addr
, 0);
241 addr
= XEXP (addr
, 1);
243 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
245 reg1
= XEXP (addr
, 1);
246 addr
= XEXP (addr
, 0);
248 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
250 reg1
= XEXP (addr
, 0);
251 addr
= XEXP (addr
, 1);
256 if (GET_CODE (addr
) == REG
)
263 else if (GET_CODE (addr
) == MULT
)
265 else if (GET_CODE (addr
) == PLUS
)
267 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0))
268 || GET_CODE (XEXP (addr
, 0)) == MEM
)
272 if (GET_CODE (offset
) == CONST_INT
)
273 offset
= plus_constant (XEXP (addr
, 0), INTVAL (offset
));
274 else if (GET_CODE (XEXP (addr
, 0)) == CONST_INT
)
275 offset
= plus_constant (offset
, INTVAL (XEXP (addr
, 0)));
279 offset
= XEXP (addr
, 0);
281 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
284 ireg
= reg1
, breg
= XEXP (addr
, 0), reg1
= 0;
286 reg1
= XEXP (addr
, 0);
288 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
292 ireg
= XEXP (addr
, 0);
297 if (CONSTANT_ADDRESS_P (XEXP (addr
, 1))
298 || GET_CODE (XEXP (addr
, 1)) == MEM
)
302 if (GET_CODE (offset
) == CONST_INT
)
303 offset
= plus_constant (XEXP (addr
, 1), INTVAL (offset
));
304 else if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
305 offset
= plus_constant (offset
, INTVAL (XEXP (addr
, 1)));
309 offset
= XEXP (addr
, 1);
311 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
314 ireg
= reg1
, breg
= XEXP (addr
, 1), reg1
= 0;
316 reg1
= XEXP (addr
, 1);
318 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
322 ireg
= XEXP (addr
, 1);
330 /* If REG1 is nonzero, figure out if it is a base or index register. */
333 if (breg
!= 0 || (offset
&& GET_CODE (offset
) == MEM
))
344 output_address (offset
);
347 fprintf (file
, "(%s)", reg_names
[REGNO (breg
)]);
351 if (GET_CODE (ireg
) == MULT
)
352 ireg
= XEXP (ireg
, 0);
353 if (GET_CODE (ireg
) != REG
)
355 fprintf (file
, "[%s]", reg_names
[REGNO (ireg
)]);
360 output_addr_const (file
, addr
);
368 switch (GET_CODE (op
))
400 register enum machine_mode mode
;
401 REAL_VALUE_TYPE r
, s
;
404 if (GET_CODE (c
) != CONST_DOUBLE
)
409 if (c
== const_tiny_rtx
[(int) mode
][0]
410 || c
== const_tiny_rtx
[(int) mode
][1]
411 || c
== const_tiny_rtx
[(int) mode
][2])
414 REAL_VALUE_FROM_CONST_DOUBLE (r
, c
);
416 for (i
= 0; i
< 7; i
++)
419 REAL_VALUE_FROM_INT (s
, x
, 0, mode
);
421 if (REAL_VALUES_EQUAL (r
, s
))
423 if (!exact_real_inverse (mode
, &s
))
425 if (REAL_VALUES_EQUAL (r
, s
))
432 /* Return the cost in cycles of a memory address, relative to register
435 Each of the following adds the indicated number of cycles:
439 1 - indexing and/or offset(register)
444 vax_address_cost_1 (addr
)
447 int reg
= 0, indexed
= 0, indir
= 0, offset
= 0, predec
= 0;
448 rtx plus_op0
= 0, plus_op1
= 0;
450 switch (GET_CODE (addr
))
460 indexed
= 1; /* 2 on VAX 2 */
463 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
465 offset
= (unsigned)(INTVAL(addr
)+128) > 256;
469 offset
= 1; /* 2 on VAX 2 */
471 case LABEL_REF
: /* this is probably a byte offset from the pc */
477 plus_op1
= XEXP (addr
, 0);
479 plus_op0
= XEXP (addr
, 0);
480 addr
= XEXP (addr
, 1);
483 indir
= 2; /* 3 on VAX 2 */
484 addr
= XEXP (addr
, 0);
490 /* Up to 3 things can be added in an address. They are stored in
491 plus_op0, plus_op1, and addr. */
505 /* Indexing and register+offset can both be used (except on a VAX 2)
506 without increasing execution time over either one alone. */
507 if (reg
&& indexed
&& offset
)
508 return reg
+ indir
+ offset
+ predec
;
509 return reg
+ indexed
+ indir
+ offset
+ predec
;
516 return (1 + (GET_CODE (x
) == REG
? 0 : vax_address_cost_1 (x
)));
519 /* Cost of an expression on a VAX. This version has costs tuned for the
520 CVAX chip (found in the VAX 3 series) with comments for variations on
524 vax_rtx_costs_1 (x
, code
, outer_code
)
526 enum rtx_code code
, outer_code
;
528 enum machine_mode mode
= GET_MODE (x
);
530 int i
= 0; /* may be modified in switch */
531 const char *fmt
= GET_RTX_FORMAT (code
); /* may be modified in switch */
535 /* On a VAX, constants from 0..63 are cheap because they can use the
536 1 byte literal constant format. compare to -1 should be made cheap
537 so that decrement-and-branch insns can be formed more easily (if
538 the value -1 is copied to a register some decrement-and-branch
539 patterns will not match). */
543 if (outer_code
== AND
)
544 return ((unsigned HOST_WIDE_INT
) ~INTVAL (x
) <= 077) ? 1 : 2;
545 if ((unsigned HOST_WIDE_INT
) INTVAL (x
) <= 077)
547 if (outer_code
== COMPARE
&& INTVAL (x
) == -1)
549 if (outer_code
== PLUS
&& (unsigned HOST_WIDE_INT
) -INTVAL (x
) <= 077)
559 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
)
560 return vax_float_literal (x
) ? 5 : 8;
562 return (((CONST_DOUBLE_HIGH (x
) == 0
563 && (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
) < 64)
564 || (outer_code
== PLUS
565 && CONST_DOUBLE_HIGH (x
) == -1 \
566 && (unsigned HOST_WIDE_INT
)-CONST_DOUBLE_LOW (x
) < 64))
577 c
= 16; /* 4 on VAX 9000 */
580 c
= 9; /* 4 on VAX 9000, 12 on VAX 2 */
583 c
= 16; /* 6 on VAX 9000, 28 on VAX 2 */
588 c
= 10; /* 3-4 on VAX 9000, 20-28 on VAX 2 */
591 return MAX_COST
; /* Mode is not supported. */
596 return MAX_COST
; /* Mode is not supported. */
601 c
= 30; /* highly variable */
602 else if (mode
== DFmode
)
603 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
606 c
= 11; /* 25 on VAX 2 */
613 return MAX_COST
; /* Mode is not supported. */
617 c
= 6 + (mode
== DFmode
) + (GET_MODE (XEXP (x
, 0)) != SImode
);
621 c
= 7; /* 17 on VAX 2 */
629 c
= 10; /* 6 on VAX 9000 */
633 c
= 6; /* 5 on VAX 2, 4 on VAX 9000 */
634 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
635 fmt
= "e"; /* all constant rotate counts are short */
638 /* Check for small negative integer operand: subl2 can be used with
639 a short positive constant instead. */
640 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
641 if ((unsigned)(INTVAL (XEXP (x
, 1)) + 63) < 127)
644 c
= (mode
== DFmode
) ? 13 : 8; /* 6/8 on VAX 9000, 16/15 on VAX 2 */
650 /* AND is special because the first operand is complemented. */
652 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
654 if ((unsigned)~INTVAL (XEXP (x
, 0)) > 63)
663 else if (mode
== SFmode
)
665 else if (mode
== DImode
)
674 if (mode
== DImode
|| mode
== DFmode
)
675 c
= 5; /* 7 on VAX 2 */
677 c
= 3; /* 4 on VAX 2 */
679 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == POST_INC
)
681 return c
+ vax_address_cost_1 (x
);
687 /* Now look inside the expression. Operands which are not registers or
688 short constants add to the cost.
690 FMT and I may have been adjusted in the switch above for instructions
691 which require special handling */
693 while (*fmt
++ == 'e')
695 register rtx op
= XEXP (x
, i
++);
696 code
= GET_CODE (op
);
698 /* A NOT is likely to be found as the first operand of an AND
699 (in which case the relevant cost is of the operand inside
700 the not) and not likely to be found anywhere else. */
702 op
= XEXP (op
, 0), code
= GET_CODE (op
);
707 if ((unsigned)INTVAL (op
) > 63 && GET_MODE (x
) != QImode
)
708 c
+= 1; /* 2 on VAX 2 */
713 c
+= 1; /* 2 on VAX 2 */
716 if (GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
)
718 /* Registers are faster than floating point constants -- even
719 those constants which can be encoded in a single byte. */
720 if (vax_float_literal (op
))
723 c
+= (GET_MODE (x
) == DFmode
) ? 3 : 2;
727 if (CONST_DOUBLE_HIGH (op
) != 0
728 || (unsigned)CONST_DOUBLE_LOW (op
) > 63)
733 c
+= 1; /* 2 on VAX 2 */
734 if (GET_CODE (XEXP (op
, 0)) != REG
)
735 c
+= vax_address_cost_1 (XEXP (op
, 0));
749 vax_rtx_costs (x
, code
, outer_code
, total
)
751 int code
, outer_code
;
754 *total
= vax_rtx_costs_1 (x
, code
, outer_code
);
758 /* Return 1 if insn A follows B. */
766 for (p
= a
; p
!= b
; p
= NEXT_INSN (p
))
773 /* Returns 1 if we know operand OP was 0 before INSN. */
776 reg_was_0_p (insn
, op
)
781 return ((link
= find_reg_note (insn
, REG_WAS_0
, 0))
782 /* Make sure the insn that stored the 0 is still present
783 and doesn't follow INSN in the insn sequence. */
784 && ! INSN_DELETED_P (XEXP (link
, 0))
785 && GET_CODE (XEXP (link
, 0)) != NOTE
786 && ! follows_p (XEXP (link
, 0), insn
)
787 /* Make sure cross jumping didn't happen here. */
788 && no_labels_between_p (XEXP (link
, 0), insn
)
789 /* Make sure the reg hasn't been clobbered. */
790 && ! reg_set_between_p (op
, XEXP (link
, 0), insn
));
793 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
794 Used for C++ multiple inheritance.
795 .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask
796 addl2 $DELTA, 4(ap) #adjust first argument
797 jmp FUNCTION+2 #jump beyond FUNCTION's entry mask
801 vax_output_mi_thunk (file
, thunk
, delta
, vcall_offset
, function
)
803 tree thunk ATTRIBUTE_UNUSED
;
805 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED
;
808 fprintf (file
, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC
, delta
);
809 asm_fprintf (file
, ",4(%Rap)\n");
810 fprintf (file
, "\tjmp ");
811 assemble_name (file
, XSTR (XEXP (DECL_RTL (function
), 0), 0));
812 fprintf (file
, "+2\n");