1 /* Subroutines for insn-output.cc for VAX.
2 Copyright (C) 1987-2022 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #define IN_TARGET_CODE 1
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "target.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "stringpool.h"
30 #include "attribs.h"
31 #include "df.h"
32 #include "memmodel.h"
33 #include "tm_p.h"
34 #include "optabs.h"
35 #include "regs.h"
36 #include "emit-rtl.h"
37 #include "calls.h"
38 #include "varasm.h"
39 #include "conditions.h"
40 #include "output.h"
41 #include "expr.h"
42 #include "reload.h"
43 #include "builtins.h"
44
45 /* This file should be included last. */
46 #include "target-def.h"
47
48 static void vax_option_override (void);
49 static void vax_init_builtins (void);
50 static bool vax_legitimate_address_p (machine_mode, rtx, bool);
51 static void vax_file_start (void);
52 static void vax_init_libfuncs (void);
53 static void vax_output_mi_thunk (FILE *, tree, HOST_WIDE_INT,
54 HOST_WIDE_INT, tree);
55 static int vax_address_cost_1 (rtx);
56 static int vax_address_cost (rtx, machine_mode, addr_space_t, bool);
57 static bool vax_rtx_costs (rtx, machine_mode, int, int, int *, bool);
58 static machine_mode vax_cc_modes_compatible (machine_mode, machine_mode);
59 static rtx_insn *vax_md_asm_adjust (vec<rtx> &, vec<rtx> &,
60 vec<machine_mode> &, vec<const char *> &,
61 vec<rtx> &, HARD_REG_SET &, location_t);
62 static rtx vax_function_arg (cumulative_args_t, const function_arg_info &);
63 static void vax_function_arg_advance (cumulative_args_t,
64 const function_arg_info &);
65 static rtx vax_struct_value_rtx (tree, int);
66 static bool vax_lra_p (void);
67 static void vax_asm_trampoline_template (FILE *);
68 static void vax_trampoline_init (rtx, tree, rtx);
69 static poly_int64 vax_return_pops_args (tree, tree, poly_int64);
70 static bool vax_mode_dependent_address_p (const_rtx, addr_space_t);
71 static HOST_WIDE_INT vax_starting_frame_offset (void);
72 static int vax_bitfield_may_trap_p (const_rtx, unsigned);
73
74 /* Initialize the GCC target structure. */
75 #undef TARGET_ASM_ALIGNED_HI_OP
76 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
77
78 #undef TARGET_ASM_FILE_START
79 #define TARGET_ASM_FILE_START vax_file_start
80 #undef TARGET_ASM_FILE_START_APP_OFF
81 #define TARGET_ASM_FILE_START_APP_OFF true
82
83 #undef TARGET_INIT_LIBFUNCS
84 #define TARGET_INIT_LIBFUNCS vax_init_libfuncs
85
86 #undef TARGET_INIT_BUILTINS
87 #define TARGET_INIT_BUILTINS vax_init_builtins
88
89 #undef TARGET_ASM_OUTPUT_MI_THUNK
90 #define TARGET_ASM_OUTPUT_MI_THUNK vax_output_mi_thunk
91 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
92 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
93
94 /* Enable compare elimination pass. */
95 #undef TARGET_FLAGS_REGNUM
96 #define TARGET_FLAGS_REGNUM VAX_PSL_REGNUM
97
98 #undef TARGET_RTX_COSTS
99 #define TARGET_RTX_COSTS vax_rtx_costs
100 #undef TARGET_ADDRESS_COST
101 #define TARGET_ADDRESS_COST vax_address_cost
102
103 /* Return the narrowest CC mode that spans both modes offered. */
104 #undef TARGET_CC_MODES_COMPATIBLE
105 #define TARGET_CC_MODES_COMPATIBLE vax_cc_modes_compatible
106
107 /* Mark PSL as clobbered for compatibility with the CC0 representation. */
108 #undef TARGET_MD_ASM_ADJUST
109 #define TARGET_MD_ASM_ADJUST vax_md_asm_adjust
110
111 #undef TARGET_PROMOTE_PROTOTYPES
112 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
113
114 #undef TARGET_FUNCTION_ARG
115 #define TARGET_FUNCTION_ARG vax_function_arg
116 #undef TARGET_FUNCTION_ARG_ADVANCE
117 #define TARGET_FUNCTION_ARG_ADVANCE vax_function_arg_advance
118
119 #undef TARGET_STRUCT_VALUE_RTX
120 #define TARGET_STRUCT_VALUE_RTX vax_struct_value_rtx
121
122 #undef TARGET_LRA_P
123 #define TARGET_LRA_P vax_lra_p
124
125 #undef TARGET_LEGITIMATE_ADDRESS_P
126 #define TARGET_LEGITIMATE_ADDRESS_P vax_legitimate_address_p
127 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
128 #define TARGET_MODE_DEPENDENT_ADDRESS_P vax_mode_dependent_address_p
129
130 #undef TARGET_FRAME_POINTER_REQUIRED
131 #define TARGET_FRAME_POINTER_REQUIRED hook_bool_void_true
132
133 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
134 #define TARGET_ASM_TRAMPOLINE_TEMPLATE vax_asm_trampoline_template
135 #undef TARGET_TRAMPOLINE_INIT
136 #define TARGET_TRAMPOLINE_INIT vax_trampoline_init
137 #undef TARGET_RETURN_POPS_ARGS
138 #define TARGET_RETURN_POPS_ARGS vax_return_pops_args
139
140 #undef TARGET_OPTION_OVERRIDE
141 #define TARGET_OPTION_OVERRIDE vax_option_override
142
143 #undef TARGET_STARTING_FRAME_OFFSET
144 #define TARGET_STARTING_FRAME_OFFSET vax_starting_frame_offset
145
146 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
147 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
148
149 #undef TARGET_BITFIELD_MAY_TRAP_P
150 #define TARGET_BITFIELD_MAY_TRAP_P vax_bitfield_may_trap_p
151
152 struct gcc_target targetm = TARGET_INITIALIZER;
153
154 /* Set global variables as needed for the options enabled. */
155
156 static void
vax_option_override(void)157 vax_option_override (void)
158 {
159 /* We're VAX floating point, not IEEE floating point. */
160 if (TARGET_G_FLOAT)
161 REAL_MODE_FORMAT (DFmode) = &vax_g_format;
162
163 #ifdef SUBTARGET_OVERRIDE_OPTIONS
164 SUBTARGET_OVERRIDE_OPTIONS;
165 #endif
166 }
167 /* Implement the TARGET_INIT_BUILTINS target hook. */
168
169 static void
vax_init_builtins(void)170 vax_init_builtins (void)
171 {
172 #ifdef SUBTARGET_INIT_BUILTINS
173 SUBTARGET_INIT_BUILTINS;
174 #endif
175 }
176
177
178 static void
vax_add_reg_cfa_offset(rtx insn,int offset,rtx src)179 vax_add_reg_cfa_offset (rtx insn, int offset, rtx src)
180 {
181 rtx x;
182
183 x = plus_constant (Pmode, frame_pointer_rtx, offset);
184 x = gen_rtx_MEM (SImode, x);
185 x = gen_rtx_SET (x, src);
186 add_reg_note (insn, REG_CFA_OFFSET, x);
187 }
188
189 /* Generate the assembly code for function entry. FILE is a stdio
190 stream to output the code to. SIZE is an int: how many units of
191 temporary storage to allocate.
192
193 Refer to the array `regs_ever_live' to determine which registers to
194 save; `regs_ever_live[I]' is nonzero if register number I is ever
195 used in the function. This function is responsible for knowing
196 which registers should not be saved even if used. */
197
198 void
vax_expand_prologue(void)199 vax_expand_prologue (void)
200 {
201 int regno, offset;
202 int mask = 0;
203 HOST_WIDE_INT size;
204 rtx insn;
205
206 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
207 if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
208 mask |= 1 << regno;
209
210 if (crtl->calls_eh_return)
211 {
212 mask |= 0
213 | ( 1 << EH_RETURN_DATA_REGNO(0) )
214 | ( 1 << EH_RETURN_DATA_REGNO(1) )
215 | ( 1 << EH_RETURN_DATA_REGNO(2) )
216 | ( 1 << EH_RETURN_DATA_REGNO(3) )
217 ;
218 }
219
220 insn = emit_insn (gen_procedure_entry_mask (GEN_INT (mask)));
221 RTX_FRAME_RELATED_P (insn) = 1;
222
223 /* The layout of the CALLG/S stack frame is follows:
224
225 <- AP
226 r11
227 r10
228 ... Registers saved as specified by MASK
229 r3
230 r2
231 return-addr
232 old fp
233 old ap
234 old psw
235 condition handler <- CFA, FP, SP
236 (initially zero)
237
238 The rest of the prologue will adjust the SP for the local frame. */
239
240 vax_add_reg_cfa_offset (insn, 8, arg_pointer_rtx);
241 vax_add_reg_cfa_offset (insn, 12, frame_pointer_rtx);
242 vax_add_reg_cfa_offset (insn, 16, pc_rtx);
243
244 offset = 5 * UNITS_PER_WORD; /* PSW, AP &c */
245 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
246 if (mask & (1 << regno))
247 {
248 vax_add_reg_cfa_offset (insn, offset, gen_rtx_REG (SImode, regno));
249 offset += 1 * UNITS_PER_WORD;
250 }
251
252 /* Because add_reg_note pushes the notes, adding this last means that
253 it will be processed first. This is required to allow the other
254 notes to be interpreted properly. */
255 /* The RTX here must match the instantiation of the CFA vreg */
256 add_reg_note (insn, REG_CFA_DEF_CFA,
257 plus_constant (Pmode, frame_pointer_rtx,
258 FRAME_POINTER_CFA_OFFSET(current_function_decl)));
259
260 /* Allocate the local stack frame. */
261 size = get_frame_size ();
262 size -= vax_starting_frame_offset ();
263 emit_insn (gen_addsi3 (stack_pointer_rtx,
264 stack_pointer_rtx, GEN_INT (-size)));
265
266 /* Do not allow instructions referencing local stack memory to be
267 scheduled before the frame is allocated. This is more pedantic
268 than anything else, given that VAX does not currently have a
269 scheduling description. */
270 emit_insn (gen_blockage ());
271 }
272
273 /* When debugging with stabs, we want to output an extra dummy label
274 so that gas can distinguish between D_float and G_float prior to
275 processing the .stabs directive identifying type double. */
276 static void
vax_file_start(void)277 vax_file_start (void)
278 {
279 default_file_start ();
280
281 if (write_symbols == DBX_DEBUG)
282 fprintf (asm_out_file, "___vax_%c_doubles:\n", ASM_DOUBLE_CHAR);
283 }
284
285 /* We can use the BSD C library routines for the libgcc calls that are
286 still generated, since that's what they boil down to anyways. When
287 ELF, avoid the user's namespace. */
288
289 static void
vax_init_libfuncs(void)290 vax_init_libfuncs (void)
291 {
292 if (TARGET_BSD_DIVMOD)
293 {
294 set_optab_libfunc (udiv_optab, SImode, TARGET_ELF ? "*__udiv" : "*udiv");
295 set_optab_libfunc (umod_optab, SImode, TARGET_ELF ? "*__urem" : "*urem");
296 }
297 }
298
299 /* This is like nonimmediate_operand with a restriction on the type of MEM. */
300
301 static void
split_quadword_operands(rtx insn,enum rtx_code code,rtx * operands,rtx * low,int n)302 split_quadword_operands (rtx insn, enum rtx_code code, rtx * operands,
303 rtx * low, int n)
304 {
305 int i;
306
307 for (i = 0; i < n; i++)
308 low[i] = 0;
309
310 for (i = 0; i < n; i++)
311 {
312 if (MEM_P (operands[i])
313 && (GET_CODE (XEXP (operands[i], 0)) == PRE_DEC
314 || GET_CODE (XEXP (operands[i], 0)) == POST_INC))
315 {
316 rtx addr = XEXP (operands[i], 0);
317 operands[i] = low[i] = gen_rtx_MEM (SImode, addr);
318 }
319 else if (optimize_size && MEM_P (operands[i])
320 && REG_P (XEXP (operands[i], 0))
321 && (code != MINUS || operands[1] != const0_rtx)
322 && find_regno_note (insn, REG_DEAD,
323 REGNO (XEXP (operands[i], 0))))
324 {
325 low[i] = gen_rtx_MEM (SImode,
326 gen_rtx_POST_INC (Pmode,
327 XEXP (operands[i], 0)));
328 operands[i] = gen_rtx_MEM (SImode, XEXP (operands[i], 0));
329 }
330 else
331 {
332 low[i] = operand_subword (operands[i], 0, 0, DImode);
333 operands[i] = operand_subword (operands[i], 1, 0, DImode);
334 }
335 }
336 }
337
338 void
print_operand_address(FILE * file,rtx addr)339 print_operand_address (FILE * file, rtx addr)
340 {
341 rtx orig = addr;
342 rtx reg1, breg, ireg;
343 rtx offset;
344
345 retry:
346 switch (GET_CODE (addr))
347 {
348 case MEM:
349 fprintf (file, "*");
350 addr = XEXP (addr, 0);
351 goto retry;
352
353 case REG:
354 fprintf (file, "(%s)", reg_names[REGNO (addr)]);
355 break;
356
357 case PRE_DEC:
358 fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
359 break;
360
361 case POST_INC:
362 fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
363 break;
364
365 case PLUS:
366 /* There can be either two or three things added here. One must be a
367 REG. One can be either a REG or a MULT/ASHIFT of a REG and an
368 appropriate constant, and the third can only be a constant or a MEM.
369
370 We get these two or three things and put the constant or MEM in
371 OFFSET, the MULT/ASHIFT or REG in IREG, and the REG in BREG. If we
372 have a register and can't tell yet if it is a base or index register,
373 put it into REG1. */
374
375 reg1 = 0; ireg = 0; breg = 0; offset = 0;
376
377 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
378 || MEM_P (XEXP (addr, 0)))
379 {
380 offset = XEXP (addr, 0);
381 addr = XEXP (addr, 1);
382 }
383 else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
384 || MEM_P (XEXP (addr, 1)))
385 {
386 offset = XEXP (addr, 1);
387 addr = XEXP (addr, 0);
388 }
389 else if (GET_CODE (XEXP (addr, 1)) == MULT
390 || GET_CODE (XEXP (addr, 1)) == ASHIFT)
391 {
392 ireg = XEXP (addr, 1);
393 addr = XEXP (addr, 0);
394 }
395 else if (GET_CODE (XEXP (addr, 0)) == MULT
396 || GET_CODE (XEXP (addr, 0)) == ASHIFT)
397 {
398 ireg = XEXP (addr, 0);
399 addr = XEXP (addr, 1);
400 }
401 else if (REG_P (XEXP (addr, 1)))
402 {
403 reg1 = XEXP (addr, 1);
404 addr = XEXP (addr, 0);
405 }
406 else if (REG_P (XEXP (addr, 0)))
407 {
408 reg1 = XEXP (addr, 0);
409 addr = XEXP (addr, 1);
410 }
411 else
412 gcc_unreachable ();
413
414 if (REG_P (addr))
415 {
416 if (reg1)
417 ireg = addr;
418 else
419 reg1 = addr;
420 }
421 else if (GET_CODE (addr) == MULT || GET_CODE (addr) == ASHIFT)
422 ireg = addr;
423 else
424 {
425 gcc_assert (GET_CODE (addr) == PLUS);
426 if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
427 || MEM_P (XEXP (addr, 0)))
428 {
429 if (offset)
430 {
431 if (CONST_INT_P (offset))
432 offset = plus_constant (Pmode, XEXP (addr, 0),
433 INTVAL (offset));
434 else
435 {
436 gcc_assert (CONST_INT_P (XEXP (addr, 0)));
437 offset = plus_constant (Pmode, offset,
438 INTVAL (XEXP (addr, 0)));
439 }
440 }
441 offset = XEXP (addr, 0);
442 }
443 else if (REG_P (XEXP (addr, 0)))
444 {
445 if (reg1)
446 ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
447 else
448 reg1 = XEXP (addr, 0);
449 }
450 else
451 {
452 gcc_assert (GET_CODE (XEXP (addr, 0)) == MULT
453 || GET_CODE (XEXP (addr, 0)) == ASHIFT);
454 gcc_assert (!ireg);
455 ireg = XEXP (addr, 0);
456 }
457
458 if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
459 || MEM_P (XEXP (addr, 1)))
460 {
461 if (offset)
462 {
463 if (CONST_INT_P (offset))
464 offset = plus_constant (Pmode, XEXP (addr, 1),
465 INTVAL (offset));
466 else
467 {
468 gcc_assert (CONST_INT_P (XEXP (addr, 1)));
469 offset = plus_constant (Pmode, offset,
470 INTVAL (XEXP (addr, 1)));
471 }
472 }
473 offset = XEXP (addr, 1);
474 }
475 else if (REG_P (XEXP (addr, 1)))
476 {
477 if (reg1)
478 ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
479 else
480 reg1 = XEXP (addr, 1);
481 }
482 else
483 {
484 gcc_assert (GET_CODE (XEXP (addr, 1)) == MULT
485 || GET_CODE (XEXP (addr, 1)) == ASHIFT);
486 gcc_assert (!ireg);
487 ireg = XEXP (addr, 1);
488 }
489 }
490
491 /* If REG1 is nonzero, figure out if it is a base or index register. */
492 if (reg1)
493 {
494 if (breg
495 || (flag_pic && GET_CODE (addr) == SYMBOL_REF)
496 || (offset
497 && (MEM_P (offset)
498 || (flag_pic && symbolic_operand (offset, SImode)))))
499 {
500 gcc_assert (!ireg);
501 ireg = reg1;
502 }
503 else
504 breg = reg1;
505 }
506
507 if (offset != 0)
508 {
509 if (flag_pic && symbolic_operand (offset, SImode))
510 {
511 if (breg && ireg)
512 {
513 debug_rtx (orig);
514 output_operand_lossage ("symbol used with both base and indexed registers");
515 }
516
517 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
518 if (flag_pic > 1 && GET_CODE (offset) == CONST
519 && GET_CODE (XEXP (XEXP (offset, 0), 0)) == SYMBOL_REF
520 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (offset, 0), 0)))
521 {
522 debug_rtx (orig);
523 output_operand_lossage ("symbol with offset used in PIC mode");
524 }
525 #endif
526
527 /* symbol(reg) isn't PIC, but symbol[reg] is. */
528 if (breg)
529 {
530 ireg = breg;
531 breg = 0;
532 }
533
534 }
535
536 output_address (VOIDmode, offset);
537 }
538
539 if (breg != 0)
540 fprintf (file, "(%s)", reg_names[REGNO (breg)]);
541
542 if (ireg != 0)
543 {
544 if (GET_CODE (ireg) == MULT || GET_CODE (ireg) == ASHIFT)
545 ireg = XEXP (ireg, 0);
546 gcc_assert (REG_P (ireg));
547 fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
548 }
549 break;
550
551 default:
552 output_addr_const (file, addr);
553 }
554 }
555
556 void
print_operand(FILE * file,rtx x,int code)557 print_operand (FILE *file, rtx x, int code)
558 {
559 if (code == '#')
560 fputc (ASM_DOUBLE_CHAR, file);
561 else if (code == '|')
562 fputs (REGISTER_PREFIX, file);
563 else if (code == 'k')
564 fputs (cond_name (x), file);
565 else if (code == 'K')
566 fputs (rev_cond_name (x), file);
567 else if (code == 'D' && CONST_INT_P (x) && INTVAL (x) < 0)
568 fprintf (file, "$" NEG_HWI_PRINT_HEX16, INTVAL (x));
569 else if (code == 'P' && CONST_INT_P (x))
570 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + 1);
571 else if (code == 'N' && CONST_INT_P (x))
572 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, ~ INTVAL (x));
573 /* rotl instruction cannot deal with negative arguments. */
574 else if (code == 'R' && CONST_INT_P (x))
575 fprintf (file, "$" HOST_WIDE_INT_PRINT_DEC, 32 - INTVAL (x));
576 else if (code == 'H' && CONST_INT_P (x))
577 fprintf (file, "$%d", (int) (0xffff & ~ INTVAL (x)));
578 else if (code == 'h' && CONST_INT_P (x))
579 fprintf (file, "$%d", (short) - INTVAL (x));
580 else if (code == 'B' && CONST_INT_P (x))
581 fprintf (file, "$%d", (int) (0xff & ~ INTVAL (x)));
582 else if (code == 'b' && CONST_INT_P (x))
583 fprintf (file, "$%d", (int) (0xff & - INTVAL (x)));
584 else if (code == 'M' && CONST_INT_P (x))
585 fprintf (file, "$%d", ((unsigned int)(~0) << (INTVAL (x))));
586 else if (code == 'x' && CONST_INT_P (x))
587 fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
588 else if (REG_P (x))
589 fprintf (file, "%s", reg_names[REGNO (x)]);
590 else if (MEM_P (x))
591 output_address (GET_MODE (x), XEXP (x, 0));
592 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
593 {
594 char dstr[30];
595 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x),
596 sizeof (dstr), 0, 1);
597 fprintf (file, "$0f%s", dstr);
598 }
599 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
600 {
601 char dstr[30];
602 real_to_decimal (dstr, CONST_DOUBLE_REAL_VALUE (x),
603 sizeof (dstr), 0, 1);
604 fprintf (file, "$0%c%s", ASM_DOUBLE_CHAR, dstr);
605 }
606 else
607 {
608 if (flag_pic > 1 && symbolic_operand (x, SImode))
609 {
610 debug_rtx (x);
611 output_operand_lossage ("symbol used as immediate operand");
612 }
613 putc ('$', file);
614 output_addr_const (file, x);
615 }
616 }
617
618 const char *
cond_name(rtx op)619 cond_name (rtx op)
620 {
621 switch (GET_CODE (op))
622 {
623 case NE:
624 return "neq";
625 case EQ:
626 return "eql";
627 case GE:
628 return "geq";
629 case GT:
630 return "gtr";
631 case LE:
632 return "leq";
633 case LT:
634 return "lss";
635 case GEU:
636 return "gequ";
637 case GTU:
638 return "gtru";
639 case LEU:
640 return "lequ";
641 case LTU:
642 return "lssu";
643
644 default:
645 gcc_unreachable ();
646 }
647 }
648
649 const char *
rev_cond_name(rtx op)650 rev_cond_name (rtx op)
651 {
652 switch (GET_CODE (op))
653 {
654 case EQ:
655 return "neq";
656 case NE:
657 return "eql";
658 case LT:
659 return "geq";
660 case LE:
661 return "gtr";
662 case GT:
663 return "leq";
664 case GE:
665 return "lss";
666 case LTU:
667 return "gequ";
668 case LEU:
669 return "gtru";
670 case GTU:
671 return "lequ";
672 case GEU:
673 return "lssu";
674
675 default:
676 gcc_unreachable ();
677 }
678 }
679
680 static bool
vax_float_literal(rtx c)681 vax_float_literal (rtx c)
682 {
683 machine_mode mode;
684 const REAL_VALUE_TYPE *r;
685 REAL_VALUE_TYPE s;
686 int i;
687
688 if (GET_CODE (c) != CONST_DOUBLE)
689 return false;
690
691 mode = GET_MODE (c);
692
693 if (c == const_tiny_rtx[(int) mode][0]
694 || c == const_tiny_rtx[(int) mode][1]
695 || c == const_tiny_rtx[(int) mode][2])
696 return true;
697
698 r = CONST_DOUBLE_REAL_VALUE (c);
699
700 for (i = 0; i < 7; i++)
701 {
702 int x = 1 << i;
703 bool ok;
704 real_from_integer (&s, mode, x, SIGNED);
705
706 if (real_equal (r, &s))
707 return true;
708 ok = exact_real_inverse (mode, &s);
709 gcc_assert (ok);
710 if (real_equal (r, &s))
711 return true;
712 }
713 return false;
714 }
715
716
717 /* Return the cost in cycles of a memory address, relative to register
718 indirect.
719
720 Each of the following adds the indicated number of cycles:
721
722 1 - symbolic address
723 1 - pre-decrement
724 1 - indexing and/or offset(register)
725 2 - indirect */
726
727
728 static int
vax_address_cost_1(rtx addr)729 vax_address_cost_1 (rtx addr)
730 {
731 int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
732 rtx plus_op0 = 0, plus_op1 = 0;
733 restart:
734 switch (GET_CODE (addr))
735 {
736 case PRE_DEC:
737 predec = 1;
738 /* FALLTHRU */
739 case REG:
740 case SUBREG:
741 case POST_INC:
742 reg = 1;
743 break;
744 case MULT:
745 case ASHIFT:
746 indexed = 1; /* 2 on VAX 2 */
747 break;
748 case CONST_INT:
749 /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
750 if (offset == 0)
751 offset = (unsigned HOST_WIDE_INT)(INTVAL(addr)+128) > 256;
752 break;
753 case CONST:
754 case SYMBOL_REF:
755 offset = 1; /* 2 on VAX 2 */
756 break;
757 case LABEL_REF: /* this is probably a byte offset from the pc */
758 if (offset == 0)
759 offset = 1;
760 break;
761 case PLUS:
762 if (plus_op0)
763 plus_op1 = XEXP (addr, 0);
764 else
765 plus_op0 = XEXP (addr, 0);
766 addr = XEXP (addr, 1);
767 goto restart;
768 case MEM:
769 indir = 2; /* 3 on VAX 2 */
770 addr = XEXP (addr, 0);
771 goto restart;
772 default:
773 break;
774 }
775
776 /* Up to 3 things can be added in an address. They are stored in
777 plus_op0, plus_op1, and addr. */
778
779 if (plus_op0)
780 {
781 addr = plus_op0;
782 plus_op0 = 0;
783 goto restart;
784 }
785 if (plus_op1)
786 {
787 addr = plus_op1;
788 plus_op1 = 0;
789 goto restart;
790 }
791 /* Indexing and register+offset can both be used (except on a VAX 2)
792 without increasing execution time over either one alone. */
793 if (reg && indexed && offset)
794 return reg + indir + offset + predec;
795 return reg + indexed + indir + offset + predec;
796 }
797
798 static int
vax_address_cost(rtx x,machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as ATTRIBUTE_UNUSED,bool speed ATTRIBUTE_UNUSED)799 vax_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
800 addr_space_t as ATTRIBUTE_UNUSED,
801 bool speed ATTRIBUTE_UNUSED)
802 {
803 return COSTS_N_INSNS (1 + (REG_P (x) ? 0 : vax_address_cost_1 (x)));
804 }
805
806 /* Cost of an expression on a VAX. This version has costs tuned for the
807 CVAX chip (found in the VAX 3 series) with comments for variations on
808 other models.
809
810 FIXME: The costs need review, particularly for TRUNCATE, FLOAT_EXTEND
811 and FLOAT_TRUNCATE. We need a -mcpu option to allow provision of
812 costs on a per cpu basis. */
813
814 static bool
vax_rtx_costs(rtx x,machine_mode mode,int outer_code,int opno ATTRIBUTE_UNUSED,int * total,bool speed ATTRIBUTE_UNUSED)815 vax_rtx_costs (rtx x, machine_mode mode, int outer_code,
816 int opno ATTRIBUTE_UNUSED,
817 int *total, bool speed ATTRIBUTE_UNUSED)
818 {
819 enum rtx_code code = GET_CODE (x);
820 int i = 0; /* may be modified in switch */
821 const char *fmt = GET_RTX_FORMAT (code); /* may be modified in switch */
822
823 switch (code)
824 {
825 /* On a VAX, constants from 0..63 are cheap because they can use the
826 1 byte literal constant format. Compare to -1 should be made cheap
827 so that decrement-and-branch insns can be formed more easily (if
828 the value -1 is copied to a register some decrement-and-branch
829 patterns will not match). */
830 case CONST_INT:
831 if (INTVAL (x) == 0)
832 {
833 *total = COSTS_N_INSNS (1) / 2;
834 return true;
835 }
836 if (outer_code == AND)
837 {
838 *total = ((unsigned HOST_WIDE_INT) ~INTVAL (x) <= 077
839 ? COSTS_N_INSNS (1) : COSTS_N_INSNS (2));
840 return true;
841 }
842 if ((unsigned HOST_WIDE_INT) INTVAL (x) <= 077
843 || (outer_code == COMPARE
844 && INTVAL (x) == -1)
845 || ((outer_code == PLUS || outer_code == MINUS)
846 && (unsigned HOST_WIDE_INT) -INTVAL (x) <= 077))
847 {
848 *total = COSTS_N_INSNS (1);
849 return true;
850 }
851 /* FALLTHRU */
852
853 case CONST:
854 case LABEL_REF:
855 case SYMBOL_REF:
856 *total = COSTS_N_INSNS (3);
857 return true;
858
859 case CONST_DOUBLE:
860 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
861 *total = vax_float_literal (x) ? COSTS_N_INSNS (5) : COSTS_N_INSNS (8);
862 else
863 *total = ((CONST_DOUBLE_HIGH (x) == 0
864 && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x) < 64)
865 || (outer_code == PLUS
866 && CONST_DOUBLE_HIGH (x) == -1
867 && (unsigned HOST_WIDE_INT)-CONST_DOUBLE_LOW (x) < 64)
868 ? COSTS_N_INSNS (2) : COSTS_N_INSNS (5));
869 return true;
870
871 case POST_INC:
872 *total = COSTS_N_INSNS (2);
873 return true; /* Implies register operand. */
874
875 case PRE_DEC:
876 *total = COSTS_N_INSNS (3);
877 return true; /* Implies register operand. */
878
879 case MULT:
880 switch (mode)
881 {
882 case E_DFmode:
883 *total = COSTS_N_INSNS (16); /* 4 on VAX 9000 */
884 break;
885 case E_SFmode:
886 *total = COSTS_N_INSNS (9); /* 4 on VAX 9000, 12 on VAX 2 */
887 break;
888 case E_DImode:
889 *total = COSTS_N_INSNS (16); /* 6 on VAX 9000, 28 on VAX 2 */
890 break;
891 case E_SImode:
892 case E_HImode:
893 case E_QImode:
894 *total = COSTS_N_INSNS (10); /* 3-4 on VAX 9000, 20-28 on VAX 2 */
895 break;
896 default:
897 *total = MAX_COST; /* Mode is not supported. */
898 return true;
899 }
900 break;
901
902 case UDIV:
903 if (mode != SImode)
904 {
905 *total = MAX_COST; /* Mode is not supported. */
906 return true;
907 }
908 *total = COSTS_N_INSNS (17);
909 break;
910
911 case DIV:
912 if (mode == DImode)
913 *total = COSTS_N_INSNS (30); /* Highly variable. */
914 else if (mode == DFmode)
915 /* divide takes 28 cycles if the result is not zero, 13 otherwise */
916 *total = COSTS_N_INSNS (24);
917 else
918 *total = COSTS_N_INSNS (11); /* 25 on VAX 2 */
919 break;
920
921 case MOD:
922 *total = COSTS_N_INSNS (23);
923 break;
924
925 case UMOD:
926 if (mode != SImode)
927 {
928 *total = MAX_COST; /* Mode is not supported. */
929 return true;
930 }
931 *total = COSTS_N_INSNS (29);
932 break;
933
934 case FLOAT:
935 *total = COSTS_N_INSNS (6 /* 4 on VAX 9000 */
936 + (mode == DFmode)
937 + (GET_MODE (XEXP (x, 0)) != SImode));
938 break;
939
940 case FIX:
941 *total = COSTS_N_INSNS (7); /* 17 on VAX 2 */
942 break;
943
944 case ASHIFT:
945 case LSHIFTRT:
946 case ASHIFTRT:
947 if (mode == DImode)
948 *total = COSTS_N_INSNS (12);
949 else
950 *total = COSTS_N_INSNS (10); /* 6 on VAX 9000 */
951 break;
952
953 case ROTATE:
954 case ROTATERT:
955 *total = COSTS_N_INSNS (6); /* 5 on VAX 2, 4 on VAX 9000 */
956 if (CONST_INT_P (XEXP (x, 1)))
957 fmt = "e"; /* all constant rotate counts are short */
958 break;
959
960 case PLUS:
961 case MINUS:
962 *total = (mode == DFmode /* 6/8 on VAX 9000, 16/15 on VAX 2 */
963 ? COSTS_N_INSNS (13) : COSTS_N_INSNS (8));
964 /* Small integer operands can use subl2 and addl2. */
965 if ((CONST_INT_P (XEXP (x, 1)))
966 && (unsigned HOST_WIDE_INT)(INTVAL (XEXP (x, 1)) + 63) < 127)
967 fmt = "e";
968 break;
969
970 case IOR:
971 case XOR:
972 *total = COSTS_N_INSNS (3);
973 break;
974
975 case AND:
976 /* AND is special because the first operand is complemented. */
977 *total = COSTS_N_INSNS (3);
978 if (CONST_INT_P (XEXP (x, 0)))
979 {
980 if ((unsigned HOST_WIDE_INT)~INTVAL (XEXP (x, 0)) > 63)
981 *total = COSTS_N_INSNS (4);
982 fmt = "e";
983 i = 1;
984 }
985 break;
986
987 case NEG:
988 if (mode == DFmode)
989 *total = COSTS_N_INSNS (9);
990 else if (mode == SFmode)
991 *total = COSTS_N_INSNS (6);
992 else if (mode == DImode)
993 *total = COSTS_N_INSNS (4);
994 else
995 *total = COSTS_N_INSNS (2);
996 break;
997
998 case NOT:
999 *total = COSTS_N_INSNS (2);
1000 break;
1001
1002 case ZERO_EXTRACT:
1003 case SIGN_EXTRACT:
1004 *total = COSTS_N_INSNS (15);
1005 break;
1006
1007 case MEM:
1008 if (mode == DImode || mode == DFmode)
1009 *total = COSTS_N_INSNS (5); /* 7 on VAX 2 */
1010 else
1011 *total = COSTS_N_INSNS (3); /* 4 on VAX 2 */
1012 x = XEXP (x, 0);
1013 if (!REG_P (x) && GET_CODE (x) != POST_INC)
1014 *total += COSTS_N_INSNS (vax_address_cost_1 (x));
1015 return true;
1016
1017 case FLOAT_EXTEND:
1018 case FLOAT_TRUNCATE:
1019 case TRUNCATE:
1020 *total = COSTS_N_INSNS (3); /* FIXME: Costs need to be checked */
1021 break;
1022
1023 default:
1024 return false;
1025 }
1026
1027 /* Now look inside the expression. Operands which are not registers or
1028 short constants add to the cost.
1029
1030 FMT and I may have been adjusted in the switch above for instructions
1031 which require special handling. */
1032
1033 while (*fmt++ == 'e')
1034 {
1035 rtx op = XEXP (x, i);
1036
1037 i += 1;
1038 code = GET_CODE (op);
1039
1040 /* A NOT is likely to be found as the first operand of an AND
1041 (in which case the relevant cost is of the operand inside
1042 the not) and not likely to be found anywhere else. */
1043 if (code == NOT)
1044 op = XEXP (op, 0), code = GET_CODE (op);
1045
1046 switch (code)
1047 {
1048 case CONST_INT:
1049 if ((unsigned HOST_WIDE_INT)INTVAL (op) > 63
1050 && mode != QImode)
1051 *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */
1052 break;
1053 case CONST:
1054 case LABEL_REF:
1055 case SYMBOL_REF:
1056 *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */
1057 break;
1058 case CONST_DOUBLE:
1059 if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
1060 {
1061 /* Registers are faster than floating point constants -- even
1062 those constants which can be encoded in a single byte. */
1063 if (vax_float_literal (op))
1064 *total += COSTS_N_INSNS (1);
1065 else
1066 *total += (GET_MODE (x) == DFmode
1067 ? COSTS_N_INSNS (3) : COSTS_N_INSNS (2));
1068 }
1069 else
1070 {
1071 if (CONST_DOUBLE_HIGH (op) != 0
1072 || (unsigned HOST_WIDE_INT)CONST_DOUBLE_LOW (op) > 63)
1073 *total += COSTS_N_INSNS (2);
1074 }
1075 break;
1076 case MEM:
1077 *total += COSTS_N_INSNS (1); /* 2 on VAX 2 */
1078 if (!REG_P (XEXP (op, 0)))
1079 *total += COSTS_N_INSNS (vax_address_cost_1 (XEXP (op, 0)));
1080 break;
1081 case REG:
1082 case SUBREG:
1083 break;
1084 default:
1085 *total += COSTS_N_INSNS (1);
1086 break;
1087 }
1088 }
1089 return true;
1090 }
1091
1092 /* With ELF we do not support GOT entries for external `symbol+offset'
1093 references, so do not accept external symbol references if an offset
1094 is to be added. Do not accept external symbol references at all if
1095 LOCAL_P is set. This is for cases where making a reference indirect
1096 would make it invalid. Do not accept any kind of symbols if SYMBOL_P
1097 is clear. This is for situations where the a reference is used as an
1098 immediate value for operations other than address loads (MOVA/PUSHA),
1099 as those operations do not support PC-relative immediates. */
1100
1101 bool
vax_acceptable_pic_operand_p(rtx x ATTRIBUTE_UNUSED,bool local_p ATTRIBUTE_UNUSED,bool symbol_p ATTRIBUTE_UNUSED)1102 vax_acceptable_pic_operand_p (rtx x ATTRIBUTE_UNUSED,
1103 bool local_p ATTRIBUTE_UNUSED,
1104 bool symbol_p ATTRIBUTE_UNUSED)
1105 {
1106 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
1107 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
1108 {
1109 x = XEXP (XEXP (x, 0), 0);
1110 local_p = true;
1111 }
1112 switch (GET_CODE (x))
1113 {
1114 case SYMBOL_REF:
1115 return symbol_p && !(local_p && !SYMBOL_REF_LOCAL_P (x));
1116 case LABEL_REF:
1117 return symbol_p && !(local_p && LABEL_REF_NONLOCAL_P (x));
1118 default:
1119 break;
1120 }
1121 #endif
1122 return true;
1123 }
1124
1125 /* Given a comparison code (NE, EQ, etc.) and the operands of a COMPARE,
1126 return the mode to be used for the comparison. As we have the same
1127 interpretation of condition codes across all the instructions we just
1128 return the narrowest mode suitable for the comparison code requested. */
1129
1130 extern machine_mode
vax_select_cc_mode(enum rtx_code op,rtx x ATTRIBUTE_UNUSED,rtx y ATTRIBUTE_UNUSED)1131 vax_select_cc_mode (enum rtx_code op,
1132 rtx x ATTRIBUTE_UNUSED, rtx y ATTRIBUTE_UNUSED)
1133 {
1134 switch (op)
1135 {
1136 default:
1137 gcc_unreachable ();
1138 case NE:
1139 case EQ:
1140 return CCZmode;
1141 case GE:
1142 case LT:
1143 return CCNmode;
1144 case GT:
1145 case LE:
1146 return CCNZmode;
1147 case GEU:
1148 case GTU:
1149 case LEU:
1150 case LTU:
1151 return CCmode;
1152 }
1153 }
1154
1155 /* Return the narrowest CC mode that spans both modes offered. If they
1156 intersect, this will be the wider of the two, and if they do not then
1157 find one that is a superset of both (i.e. CCNZmode for a pair
1158 consisting of CCNmode and CCZmode). A wider CC writer will satisfy
1159 a narrower CC reader, e.g. a comparison operator that uses CCZmode
1160 can use a CCNZmode output of a previous instruction. */
1161
1162 static machine_mode
vax_cc_modes_compatible(machine_mode m1,machine_mode m2)1163 vax_cc_modes_compatible (machine_mode m1, machine_mode m2)
1164 {
1165 switch (m1)
1166 {
1167 default:
1168 gcc_unreachable ();
1169 case E_CCmode:
1170 switch (m2)
1171 {
1172 default:
1173 gcc_unreachable ();
1174 case E_CCmode:
1175 case E_CCNZmode:
1176 case E_CCNmode:
1177 case E_CCZmode:
1178 return m1;
1179 }
1180 case E_CCNZmode:
1181 switch (m2)
1182 {
1183 default:
1184 gcc_unreachable ();
1185 case E_CCmode:
1186 return m2;
1187 case E_CCNmode:
1188 case E_CCNZmode:
1189 case E_CCZmode:
1190 return m1;
1191 }
1192 case E_CCNmode:
1193 case E_CCZmode:
1194 switch (m2)
1195 {
1196 default:
1197 gcc_unreachable ();
1198 case E_CCmode:
1199 case E_CCNZmode:
1200 return m2;
1201 case E_CCNmode:
1202 case E_CCZmode:
1203 return m1 == m2 ? m1 : E_CCNZmode;
1204 }
1205 }
1206 }
1207
1208 /* Mark PSL as clobbered for compatibility with the CC0 representation. */
1209
1210 static rtx_insn *
vax_md_asm_adjust(vec<rtx> & outputs ATTRIBUTE_UNUSED,vec<rtx> & inputs ATTRIBUTE_UNUSED,vec<machine_mode> & input_modes ATTRIBUTE_UNUSED,vec<const char * > & constraints ATTRIBUTE_UNUSED,vec<rtx> & clobbers,HARD_REG_SET & clobbered_regs,location_t)1211 vax_md_asm_adjust (vec<rtx> &outputs ATTRIBUTE_UNUSED,
1212 vec<rtx> &inputs ATTRIBUTE_UNUSED,
1213 vec<machine_mode> &input_modes ATTRIBUTE_UNUSED,
1214 vec<const char *> &constraints ATTRIBUTE_UNUSED,
1215 vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
1216 location_t /*loc*/)
1217 {
1218 clobbers.safe_push (gen_rtx_REG (CCmode, VAX_PSL_REGNUM));
1219 SET_HARD_REG_BIT (clobbered_regs, VAX_PSL_REGNUM);
1220 return NULL;
1221 }
1222
1223 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
1224 Used for C++ multiple inheritance.
1225 .mask ^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11> #conservative entry mask
1226 addl2 $DELTA, 4(ap) #adjust first argument
1227 jmp FUNCTION+2 #jump beyond FUNCTION's entry mask
1228 */
1229
1230 static void
vax_output_mi_thunk(FILE * file,tree thunk ATTRIBUTE_UNUSED,HOST_WIDE_INT delta,HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,tree function)1231 vax_output_mi_thunk (FILE * file,
1232 tree thunk ATTRIBUTE_UNUSED,
1233 HOST_WIDE_INT delta,
1234 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
1235 tree function)
1236 {
1237 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
1238
1239 assemble_start_function (thunk, fnname);
1240 fprintf (file, "\t.word 0x0ffc\n\taddl2 $" HOST_WIDE_INT_PRINT_DEC, delta);
1241 asm_fprintf (file, ",4(%Rap)\n");
1242 fprintf (file, "\tjmp ");
1243 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
1244 fprintf (file, "+2\n");
1245 assemble_end_function (thunk, fnname);
1246 }
1247
1248 static rtx
vax_struct_value_rtx(tree fntype ATTRIBUTE_UNUSED,int incoming ATTRIBUTE_UNUSED)1249 vax_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
1250 int incoming ATTRIBUTE_UNUSED)
1251 {
1252 return gen_rtx_REG (Pmode, VAX_STRUCT_VALUE_REGNUM);
1253 }
1254
1255 /* Return true if we use LRA instead of reload pass. */
1256
1257 static bool
vax_lra_p(void)1258 vax_lra_p (void)
1259 {
1260 return TARGET_LRA;
1261 }
1262
1263 /* Output integer move instructions. */
1264
1265 bool
vax_maybe_split_dimode_move(rtx * operands)1266 vax_maybe_split_dimode_move (rtx *operands)
1267 {
1268 return (TARGET_QMATH
1269 && (!MEM_P (operands[0])
1270 || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
1271 || GET_CODE (XEXP (operands[0], 0)) == POST_INC
1272 || !illegal_addsub_di_memory_operand (operands[0], DImode))
1273 && ((CONST_INT_P (operands[1])
1274 && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64)
1275 || GET_CODE (operands[1]) == CONST_DOUBLE));
1276 }
1277
1278 const char *
vax_output_int_move(rtx insn ATTRIBUTE_UNUSED,rtx * operands,machine_mode mode)1279 vax_output_int_move (rtx insn ATTRIBUTE_UNUSED, rtx *operands,
1280 machine_mode mode)
1281 {
1282 rtx hi[3], lo[3];
1283 const char *pattern_hi, *pattern_lo;
1284 bool push_p;
1285
1286 switch (mode)
1287 {
1288 case E_DImode:
1289 if (operands[1] == const0_rtx)
1290 return "clrq %0";
1291 if (TARGET_QMATH && optimize_size
1292 && (CONST_INT_P (operands[1])
1293 || GET_CODE (operands[1]) == CONST_DOUBLE))
1294 {
1295 unsigned HOST_WIDE_INT hval, lval;
1296 int n;
1297
1298 if (GET_CODE (operands[1]) == CONST_DOUBLE)
1299 {
1300 gcc_assert (HOST_BITS_PER_WIDE_INT != 64);
1301
1302 /* Make sure only the low 32 bits are valid. */
1303 lval = CONST_DOUBLE_LOW (operands[1]) & 0xffffffff;
1304 hval = CONST_DOUBLE_HIGH (operands[1]) & 0xffffffff;
1305 }
1306 else
1307 {
1308 lval = INTVAL (operands[1]);
1309 hval = 0;
1310 }
1311
1312 /* Here we see if we are trying to see if the 64bit value is really
1313 a 6bit shifted some arbitrary amount. If so, we can use ashq to
1314 shift it to the correct value saving 7 bytes (1 addr-mode-byte +
1315 8 bytes - 1 shift byte - 1 short literal byte. */
1316 if (lval != 0
1317 && (n = exact_log2 (lval & (- lval))) != -1
1318 && (lval >> n) < 64)
1319 {
1320 lval >>= n;
1321
1322 /* On 32bit platforms, if the 6bits didn't overflow into the
1323 upper 32bit value that value better be 0. If we have
1324 overflowed, make sure it wasn't too much. */
1325 if (HOST_BITS_PER_WIDE_INT == 32 && hval != 0)
1326 {
1327 if (n <= 26 || hval >= ((unsigned)1 << (n - 26)))
1328 n = 0; /* failure */
1329 else
1330 lval |= hval << (32 - n);
1331 }
1332 /* If n is 0, then ashq is not the best way to emit this. */
1333 if (n > 0)
1334 {
1335 operands[1] = GEN_INT (lval);
1336 operands[2] = GEN_INT (n);
1337 return "ashq %2,%D1,%0";
1338 }
1339 #if HOST_BITS_PER_WIDE_INT == 32
1340 }
1341 /* On 32bit platforms, if the low 32bit value is 0, checkout the
1342 upper 32bit value. */
1343 else if (hval != 0
1344 && (n = exact_log2 (hval & (- hval)) - 1) != -1
1345 && (hval >> n) < 64)
1346 {
1347 operands[1] = GEN_INT (hval >> n);
1348 operands[2] = GEN_INT (n + 32);
1349 return "ashq %2,%D1,%0";
1350 #endif
1351 }
1352 }
1353
1354 if (vax_maybe_split_dimode_move (operands))
1355 {
1356 hi[0] = operands[0];
1357 hi[1] = operands[1];
1358
1359 split_quadword_operands (insn, SET, hi, lo, 2);
1360
1361 pattern_lo = vax_output_int_move (NULL, lo, SImode);
1362 pattern_hi = vax_output_int_move (NULL, hi, SImode);
1363
1364 /* The patterns are just movl/movl or pushl/pushl then a movq will
1365 be shorter (1 opcode byte + 1 addrmode byte + 8 immediate value
1366 bytes .vs. 2 opcode bytes + 2 addrmode bytes + 8 immediate value
1367 value bytes. */
1368 if ((startswith (pattern_lo, "movl")
1369 && startswith (pattern_hi, "movl"))
1370 || (startswith (pattern_lo, "pushl")
1371 && startswith (pattern_hi, "pushl")))
1372 return "movq %1,%0";
1373
1374 if (MEM_P (operands[0])
1375 && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
1376 {
1377 output_asm_insn (pattern_hi, hi);
1378 operands[0] = lo[0];
1379 operands[1] = lo[1];
1380 operands[2] = lo[2];
1381 return pattern_lo;
1382 }
1383 else
1384 {
1385 output_asm_insn (pattern_lo, lo);
1386 operands[0] = hi[0];
1387 operands[1] = hi[1];
1388 operands[2] = hi[2];
1389 return pattern_hi;
1390 }
1391 }
1392 return "movq %1,%0";
1393
1394 case E_SImode:
1395 push_p = push_operand (operands[0], SImode);
1396
1397 if (symbolic_operand (operands[1], SImode))
1398 return push_p ? "pushab %a1" : "movab %a1,%0";
1399
1400 if (operands[1] == const0_rtx)
1401 return push_p ? "pushl %1" : "clrl %0";
1402
1403 if (CONST_INT_P (operands[1])
1404 && (unsigned HOST_WIDE_INT) INTVAL (operands[1]) >= 64)
1405 {
1406 HOST_WIDE_INT i = INTVAL (operands[1]);
1407 int n;
1408 if ((unsigned HOST_WIDE_INT)(~i) < 64)
1409 return "mcoml %N1,%0";
1410 if ((unsigned HOST_WIDE_INT)i < 0x100)
1411 return "movzbl %1,%0";
1412 if (i >= -0x80 && i < 0)
1413 return "cvtbl %1,%0";
1414 if (optimize_size
1415 && (n = exact_log2 (i & (-i))) != -1
1416 && ((unsigned HOST_WIDE_INT)i >> n) < 64)
1417 {
1418 operands[1] = GEN_INT ((unsigned HOST_WIDE_INT)i >> n);
1419 operands[2] = GEN_INT (n);
1420 return "ashl %2,%1,%0";
1421 }
1422 if ((unsigned HOST_WIDE_INT)i < 0x10000)
1423 return "movzwl %1,%0";
1424 if (i >= -0x8000 && i < 0)
1425 return "cvtwl %1,%0";
1426 }
1427 return push_p ? "pushl %1" : "movl %1,%0";
1428
1429 case E_HImode:
1430 if (CONST_INT_P (operands[1]))
1431 {
1432 HOST_WIDE_INT i = INTVAL (operands[1]);
1433 if (i == 0)
1434 return "clrw %0";
1435 else if ((unsigned HOST_WIDE_INT)i < 64)
1436 return "movw %1,%0";
1437 else if ((unsigned HOST_WIDE_INT)~i < 64)
1438 return "mcomw %H1,%0";
1439 else if ((unsigned HOST_WIDE_INT)i < 256)
1440 return "movzbw %1,%0";
1441 else if (i >= -0x80 && i < 0)
1442 return "cvtbw %1,%0";
1443 }
1444 return "movw %1,%0";
1445
1446 case E_QImode:
1447 if (CONST_INT_P (operands[1]))
1448 {
1449 HOST_WIDE_INT i = INTVAL (operands[1]);
1450 if (i == 0)
1451 return "clrb %0";
1452 else if ((unsigned HOST_WIDE_INT)~i < 64)
1453 return "mcomb %B1,%0";
1454 }
1455 return "movb %1,%0";
1456
1457 default:
1458 gcc_unreachable ();
1459 }
1460 }
1461
1462 /* Output integer add instructions.
1463
1464 The space-time-opcode tradeoffs for addition vary by model of VAX.
1465
1466 On a VAX 3 "movab (r1)[r2],r3" is faster than "addl3 r1,r2,r3",
1467 but it not faster on other models.
1468
1469 "movab #(r1),r2" is usually shorter than "addl3 #,r1,r2", and is
1470 faster on a VAX 3, but some VAXen (e.g. VAX 9000) will stall if
1471 a register is used in an address too soon after it is set.
1472 Compromise by using movab only when it is shorter than the add
1473 or the base register in the address is one of sp, ap, and fp,
1474 which are not modified very often. */
1475
1476 const char *
vax_output_int_add(rtx_insn * insn,rtx * operands,machine_mode mode)1477 vax_output_int_add (rtx_insn *insn, rtx *operands, machine_mode mode)
1478 {
1479 switch (mode)
1480 {
1481 case E_DImode:
1482 {
1483 rtx low[3];
1484 const char *pattern;
1485 int carry = 1;
1486 bool sub;
1487
1488 if (TARGET_QMATH && 0)
1489 debug_rtx (insn);
1490
1491 split_quadword_operands (insn, PLUS, operands, low, 3);
1492
1493 if (TARGET_QMATH)
1494 {
1495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
1496 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
1497 gcc_assert (!flag_pic
1498 || !non_pic_external_memory_operand (low[2], SImode));
1499 gcc_assert (!flag_pic
1500 || !non_pic_external_memory_operand (low[0], SImode));
1501 #endif
1502
1503 /* No reason to add a 0 to the low part and thus no carry, so just
1504 emit the appropriate add/sub instruction. */
1505 if (low[2] == const0_rtx)
1506 return vax_output_int_add (NULL, operands, SImode);
1507
1508 /* Are we doing addition or subtraction? */
1509 sub = CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0;
1510
1511 /* We can't use vax_output_int_add since some the patterns don't
1512 modify the carry bit. */
1513 if (sub)
1514 {
1515 if (low[2] == constm1_rtx)
1516 pattern = "decl %0";
1517 else
1518 pattern = "subl2 $%n2,%0";
1519 }
1520 else
1521 {
1522 if (low[2] == const1_rtx)
1523 pattern = "incl %0";
1524 else
1525 pattern = "addl2 %2,%0";
1526 }
1527 output_asm_insn (pattern, low);
1528
1529 /* In 2's complement, -n = ~n + 1. Since we are dealing with
1530 two 32bit parts, we complement each and then add one to
1531 low part. We know that the low part can't overflow since
1532 it's value can never be 0. */
1533 if (sub)
1534 return "sbwc %N2,%0";
1535 return "adwc %2,%0";
1536 }
1537
1538 /* Add low parts. */
1539 if (rtx_equal_p (operands[0], operands[1]))
1540 {
1541 if (low[2] == const0_rtx)
1542 /* Should examine operand, punt if not POST_INC. */
1543 pattern = "tstl %0", carry = 0;
1544 else if (low[2] == const1_rtx)
1545 pattern = "incl %0";
1546 else
1547 pattern = "addl2 %2,%0";
1548 }
1549 else
1550 {
1551 if (low[2] == const0_rtx)
1552 pattern = "movl %1,%0", carry = 0;
1553 else
1554 pattern = "addl3 %2,%1,%0";
1555 }
1556 if (pattern)
1557 output_asm_insn (pattern, low);
1558 if (!carry)
1559 /* If CARRY is 0, we don't have any carry value to worry about. */
1560 return get_insn_template (CODE_FOR_addsi3, insn);
1561 /* %0 = C + %1 + %2 */
1562 if (!rtx_equal_p (operands[0], operands[1]))
1563 output_asm_insn ((operands[1] == const0_rtx
1564 ? "clrl %0"
1565 : "movl %1,%0"), operands);
1566 return "adwc %2,%0";
1567 }
1568
1569 case E_SImode:
1570 if (rtx_equal_p (operands[0], operands[1]))
1571 {
1572 if (operands[2] == const1_rtx)
1573 return "incl %0";
1574 if (operands[2] == constm1_rtx)
1575 return "decl %0";
1576 if (CONST_INT_P (operands[2])
1577 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64)
1578 return "subl2 $%n2,%0";
1579 if (CONST_INT_P (operands[2])
1580 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 64
1581 && REG_P (operands[1])
1582 && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768)
1583 || REGNO (operands[1]) > 11))
1584 return "movab %c2(%1),%0";
1585 if (REG_P (operands[0]) && symbolic_operand (operands[2], SImode))
1586 return "movab %a2[%0],%0";
1587 return "addl2 %2,%0";
1588 }
1589
1590 if (rtx_equal_p (operands[0], operands[2]))
1591 {
1592 if (REG_P (operands[0]) && symbolic_operand (operands[1], SImode))
1593 return "movab %a1[%0],%0";
1594 return "addl2 %1,%0";
1595 }
1596
1597 if (CONST_INT_P (operands[2])
1598 && INTVAL (operands[2]) < 32767
1599 && INTVAL (operands[2]) > -32768
1600 && REG_P (operands[1])
1601 && push_operand (operands[0], SImode))
1602 return "pushab %c2(%1)";
1603
1604 if (CONST_INT_P (operands[2])
1605 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64)
1606 return "subl3 $%n2,%1,%0";
1607
1608 if (CONST_INT_P (operands[2])
1609 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 64
1610 && REG_P (operands[1])
1611 && ((INTVAL (operands[2]) < 32767 && INTVAL (operands[2]) > -32768)
1612 || REGNO (operands[1]) > 11))
1613 return "movab %c2(%1),%0";
1614
1615 /* Add this if using gcc on a VAX 3xxx:
1616 if (REG_P (operands[1]) && REG_P (operands[2]))
1617 return "movab (%1)[%2],%0";
1618 */
1619
1620 if (REG_P (operands[1]) && symbolic_operand (operands[2], SImode))
1621 {
1622 if (push_operand (operands[0], SImode))
1623 return "pushab %a2[%1]";
1624 return "movab %a2[%1],%0";
1625 }
1626
1627 if (REG_P (operands[2]) && symbolic_operand (operands[1], SImode))
1628 {
1629 if (push_operand (operands[0], SImode))
1630 return "pushab %a1[%2]";
1631 return "movab %a1[%2],%0";
1632 }
1633
1634 if (flag_pic && REG_P (operands[0])
1635 && symbolic_operand (operands[2], SImode))
1636 return "movab %a2,%0;addl2 %1,%0";
1637
1638 if (flag_pic
1639 && (symbolic_operand (operands[1], SImode)
1640 || symbolic_operand (operands[2], SImode)))
1641 debug_rtx (insn);
1642
1643 return "addl3 %1,%2,%0";
1644
1645 case E_HImode:
1646 if (rtx_equal_p (operands[0], operands[1]))
1647 {
1648 if (operands[2] == const1_rtx)
1649 return "incw %0";
1650 if (operands[2] == constm1_rtx)
1651 return "decw %0";
1652 if (CONST_INT_P (operands[2])
1653 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64)
1654 return "subw2 $%n2,%0";
1655 return "addw2 %2,%0";
1656 }
1657 if (rtx_equal_p (operands[0], operands[2]))
1658 return "addw2 %1,%0";
1659 if (CONST_INT_P (operands[2])
1660 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64)
1661 return "subw3 $%n2,%1,%0";
1662 return "addw3 %1,%2,%0";
1663
1664 case E_QImode:
1665 if (rtx_equal_p (operands[0], operands[1]))
1666 {
1667 if (operands[2] == const1_rtx)
1668 return "incb %0";
1669 if (operands[2] == constm1_rtx)
1670 return "decb %0";
1671 if (CONST_INT_P (operands[2])
1672 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64)
1673 return "subb2 $%n2,%0";
1674 return "addb2 %2,%0";
1675 }
1676 if (rtx_equal_p (operands[0], operands[2]))
1677 return "addb2 %1,%0";
1678 if (CONST_INT_P (operands[2])
1679 && (unsigned HOST_WIDE_INT) (- INTVAL (operands[2])) < 64)
1680 return "subb3 $%n2,%1,%0";
1681 return "addb3 %1,%2,%0";
1682
1683 default:
1684 gcc_unreachable ();
1685 }
1686 }
1687
1688 const char *
vax_output_int_subtract(rtx_insn * insn,rtx * operands,machine_mode mode)1689 vax_output_int_subtract (rtx_insn *insn, rtx *operands, machine_mode mode)
1690 {
1691 switch (mode)
1692 {
1693 case E_DImode:
1694 {
1695 rtx low[3];
1696 const char *pattern;
1697 int carry = 1;
1698
1699 if (TARGET_QMATH && 0)
1700 debug_rtx (insn);
1701
1702 split_quadword_operands (insn, MINUS, operands, low, 3);
1703
1704 if (TARGET_QMATH)
1705 {
1706 if (operands[1] == const0_rtx && low[1] == const0_rtx)
1707 {
1708 /* Negation is tricky. It's basically complement and increment.
1709 Negate hi, then lo, and subtract the carry back. */
1710
1711 /*
1712 * If the source *or* the destination operands are
1713 * indirect memory references with post-increment
1714 * addressing, an memory reference using the base
1715 * register plus an offset must be constructed to
1716 * address the high word of the source or result.
1717 *
1718 * pre-decrement memory references are rejected by the
1719 * illegal_addsub_di_memory_operand predicate
1720 */
1721
1722 rtx earlyhiw[3];
1723
1724 /* high word - destination */
1725 if (MEM_P (operands[0])
1726 && GET_CODE (XEXP (operands[0], 0)) == POST_INC)
1727 {
1728 const enum machine_mode mode = GET_MODE (operands[0]);
1729 rtx x = XEXP (XEXP (operands[0], 0), 0);
1730 x = plus_constant (Pmode, x, GET_MODE_SIZE (mode));
1731 x = gen_rtx_MEM (mode, x);
1732 earlyhiw[0] = x;
1733 }
1734 else
1735 earlyhiw[0] = operands[0];
1736
1737 earlyhiw[1] = operands[1]; /* easy, this is const0_rtx */
1738
1739 /* high word - source */
1740 if (MEM_P (operands[2])
1741 && GET_CODE (XEXP (operands[2], 0)) == POST_INC)
1742 {
1743 const enum machine_mode mode = GET_MODE (operands[2]);
1744 rtx x = XEXP (XEXP (operands[2], 0), 0);
1745 x = plus_constant (Pmode, x, GET_MODE_SIZE (mode));
1746 x = gen_rtx_MEM (mode, x);
1747 earlyhiw[2] = x;
1748 }
1749 else
1750 earlyhiw[2] = operands[2];
1751
1752 output_asm_insn ("mnegl %2,%0", earlyhiw);
1753 output_asm_insn ("mnegl %2,%0", low);
1754
1755 if (earlyhiw[2] != operands[2])
1756 {
1757 rtx ops[3];
1758 const enum machine_mode mode = GET_MODE (operands[2]);
1759
1760 output_asm_insn ("sbwc $0,%0", operands);
1761 /* update the source operand's base register to
1762 point to the following word */
1763 ops[0] = XEXP (XEXP (operands[2], 0), 0);
1764 ops[1] = const0_rtx;
1765 ops[2] = gen_int_mode (GET_MODE_SIZE (mode), SImode);
1766 output_asm_insn ("addl2 %2,%0", ops);
1767 return "";
1768 }
1769 else
1770 return "sbwc $0,%0";
1771 }
1772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
1773 gcc_assert (rtx_equal_p (low[0], low[1]));
1774 if (low[2] == const1_rtx)
1775 output_asm_insn ("decl %0", low);
1776 else
1777 output_asm_insn ("subl2 %2,%0", low);
1778 return "sbwc %2,%0";
1779 }
1780
1781 /* Subtract low parts. */
1782 if (rtx_equal_p (operands[0], operands[1]))
1783 {
1784 if (low[2] == const0_rtx)
1785 pattern = 0, carry = 0;
1786 else if (low[2] == constm1_rtx)
1787 pattern = "decl %0";
1788 else
1789 pattern = "subl2 %2,%0";
1790 }
1791 else
1792 {
1793 if (low[2] == constm1_rtx)
1794 pattern = "decl %0";
1795 else if (low[2] == const0_rtx)
1796 pattern = get_insn_template (CODE_FOR_movsi, insn), carry = 0;
1797 else
1798 pattern = "subl3 %2,%1,%0";
1799 }
1800 if (pattern)
1801 output_asm_insn (pattern, low);
1802 if (carry)
1803 {
1804 if (!rtx_equal_p (operands[0], operands[1]))
1805 return "movl %1,%0;sbwc %2,%0";
1806 return "sbwc %2,%0";
1807 /* %0 = %2 - %1 - C */
1808 }
1809 return get_insn_template (CODE_FOR_subsi3, insn);
1810 }
1811
1812 default:
1813 gcc_unreachable ();
1814 }
1815 }
1816
1817 /* True if X is an rtx for a constant that is a valid address. */
1818
1819 bool
legitimate_constant_address_p(rtx x)1820 legitimate_constant_address_p (rtx x)
1821 {
1822 if (GET_CODE (x) == LABEL_REF || GET_CODE (x) == SYMBOL_REF
1823 || CONST_INT_P (x) || GET_CODE (x) == HIGH)
1824 return true;
1825 if (GET_CODE (x) != CONST)
1826 return false;
1827 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
1828 if (flag_pic
1829 && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
1830 && !SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0)))
1831 return false;
1832 #endif
1833 return true;
1834 }
1835
1836 /* The other macros defined here are used only in legitimate_address_p (). */
1837
1838 /* Nonzero if X is a hard reg that can be used as an index
1839 or, if not strict, if it is a pseudo reg. */
1840 #define INDEX_REGISTER_P(X, STRICT) \
1841 (REG_P (X) && (!(STRICT) || REGNO_OK_FOR_INDEX_P (REGNO (X))))
1842
1843 /* Nonzero if X is a hard reg that can be used as a base reg
1844 or, if not strict, if it is a pseudo reg. */
1845 #define BASE_REGISTER_P(X, STRICT) \
1846 (REG_P (X) && (!(STRICT) || REGNO_OK_FOR_BASE_P (REGNO (X))))
1847
1848 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
1849
1850 /* Re-definition of CONSTANT_ADDRESS_P, which is true only when there
1851 are no SYMBOL_REFs for external symbols present. */
1852
1853 static bool
indirectable_constant_address_p(rtx x,bool indirect)1854 indirectable_constant_address_p (rtx x, bool indirect)
1855 {
1856 if (GET_CODE (x) == SYMBOL_REF)
1857 return !flag_pic || SYMBOL_REF_LOCAL_P (x) || !indirect;
1858
1859 if (GET_CODE (x) == CONST)
1860 return !flag_pic
1861 || GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
1862 || SYMBOL_REF_LOCAL_P (XEXP (XEXP (x, 0), 0));
1863
1864 return CONSTANT_ADDRESS_P (x);
1865 }
1866
1867 #else /* not NO_EXTERNAL_INDIRECT_ADDRESS */
1868
1869 static bool
indirectable_constant_address_p(rtx x,bool indirect ATTRIBUTE_UNUSED)1870 indirectable_constant_address_p (rtx x, bool indirect ATTRIBUTE_UNUSED)
1871 {
1872 return CONSTANT_ADDRESS_P (x);
1873 }
1874
1875 #endif /* not NO_EXTERNAL_INDIRECT_ADDRESS */
1876
1877 /* True if X is an address which can be indirected. External symbols
1878 could be in a sharable image library, so we disallow those. */
1879
1880 static bool
indirectable_address_p(rtx x,bool strict,bool indirect)1881 indirectable_address_p (rtx x, bool strict, bool indirect)
1882 {
1883 if (indirectable_constant_address_p (x, indirect)
1884 || BASE_REGISTER_P (x, strict))
1885 return true;
1886 if (GET_CODE (x) != PLUS
1887 || !BASE_REGISTER_P (XEXP (x, 0), strict)
1888 || (flag_pic && !CONST_INT_P (XEXP (x, 1))))
1889 return false;
1890 return indirectable_constant_address_p (XEXP (x, 1), indirect);
1891 }
1892
1893 /* Return true if x is a valid address not using indexing.
1894 (This much is the easy part.) */
1895 static bool
nonindexed_address_p(rtx x,bool strict)1896 nonindexed_address_p (rtx x, bool strict)
1897 {
1898 rtx xfoo0;
1899 if (REG_P (x))
1900 {
1901 if (! reload_in_progress
1902 || reg_equiv_mem (REGNO (x)) == 0
1903 || indirectable_address_p (reg_equiv_mem (REGNO (x)), strict, false))
1904 return true;
1905 }
1906 if (indirectable_constant_address_p (x, false))
1907 return true;
1908 if (indirectable_address_p (x, strict, false))
1909 return true;
1910 xfoo0 = XEXP (x, 0);
1911 if (MEM_P (x) && indirectable_address_p (xfoo0, strict, true))
1912 return true;
1913 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
1914 && BASE_REGISTER_P (xfoo0, strict))
1915 return true;
1916 return false;
1917 }
1918
1919 /* True if PROD is either a reg times size of mode MODE and MODE is less
1920 than or equal 8 bytes, or just a reg if MODE is one byte. For a MULT
1921 RTX we accept its operands in either order, however ASHIFT is not
1922 commutative, so in that case reg has to be the left operand. */
1923
1924 static bool
index_term_p(rtx prod,machine_mode mode,bool strict)1925 index_term_p (rtx prod, machine_mode mode, bool strict)
1926 {
1927 rtx xfoo0, xfoo1;
1928
1929 if (GET_MODE_SIZE (mode) == 1)
1930 return BASE_REGISTER_P (prod, strict);
1931
1932 if ((GET_CODE (prod) != MULT && GET_CODE (prod) != ASHIFT)
1933 || GET_MODE_SIZE (mode) > 8)
1934 return false;
1935
1936 xfoo0 = XEXP (prod, 0);
1937 xfoo1 = XEXP (prod, 1);
1938
1939 if (GET_CODE (prod) == MULT
1940 && CONST_INT_P (xfoo0)
1941 && GET_MODE_SIZE (mode) == INTVAL (xfoo0)
1942 && INDEX_REGISTER_P (xfoo1, strict))
1943 return true;
1944
1945 if (GET_CODE (prod) == MULT
1946 && CONST_INT_P (xfoo1)
1947 && GET_MODE_SIZE (mode) == INTVAL (xfoo1)
1948 && INDEX_REGISTER_P (xfoo0, strict))
1949 return true;
1950
1951 if (GET_CODE (prod) == ASHIFT
1952 && CONST_INT_P (xfoo1)
1953 && GET_MODE_SIZE (mode) == (1 << INTVAL (xfoo1))
1954 && INDEX_REGISTER_P (xfoo0, strict))
1955 return true;
1956
1957 return false;
1958 }
1959
1960 /* Return true if X is the sum of a register
1961 and a valid index term for mode MODE. */
1962 static bool
reg_plus_index_p(rtx x,machine_mode mode,bool strict)1963 reg_plus_index_p (rtx x, machine_mode mode, bool strict)
1964 {
1965 rtx xfoo0, xfoo1;
1966
1967 if (GET_CODE (x) != PLUS)
1968 return false;
1969
1970 xfoo0 = XEXP (x, 0);
1971 xfoo1 = XEXP (x, 1);
1972
1973 if (BASE_REGISTER_P (xfoo0, strict) && index_term_p (xfoo1, mode, strict))
1974 return true;
1975
1976 if (BASE_REGISTER_P (xfoo1, strict) && index_term_p (xfoo0, mode, strict))
1977 return true;
1978
1979 return false;
1980 }
1981
1982 /* Return true if xfoo0 and xfoo1 constitute a valid indexed address. */
1983 static bool
indexable_address_p(rtx xfoo0,rtx xfoo1,machine_mode mode,bool strict)1984 indexable_address_p (rtx xfoo0, rtx xfoo1, machine_mode mode, bool strict)
1985 {
1986 if (!CONSTANT_ADDRESS_P (xfoo0))
1987 return false;
1988 if (BASE_REGISTER_P (xfoo1, strict))
1989 return !flag_pic || mode == QImode;
1990 if (flag_pic && symbolic_operand (xfoo0, SImode))
1991 return false;
1992 return reg_plus_index_p (xfoo1, mode, strict);
1993 }
1994
1995 /* legitimate_address_p returns true if it recognizes an RTL expression "x"
1996 that is a valid memory address for an instruction.
1997 The MODE argument is the machine mode for the MEM expression
1998 that wants to use this address. */
1999 bool
vax_legitimate_address_p(machine_mode mode,rtx x,bool strict)2000 vax_legitimate_address_p (machine_mode mode, rtx x, bool strict)
2001 {
2002 rtx xfoo0, xfoo1;
2003
2004 if (nonindexed_address_p (x, strict))
2005 return true;
2006
2007 if (GET_CODE (x) != PLUS)
2008 return false;
2009
2010 /* Handle <address>[index] represented with index-sum outermost */
2011
2012 xfoo0 = XEXP (x, 0);
2013 xfoo1 = XEXP (x, 1);
2014
2015 if (index_term_p (xfoo0, mode, strict)
2016 && nonindexed_address_p (xfoo1, strict))
2017 return true;
2018
2019 if (index_term_p (xfoo1, mode, strict)
2020 && nonindexed_address_p (xfoo0, strict))
2021 return true;
2022
2023 /* Handle offset(reg)[index] with offset added outermost */
2024
2025 if (indexable_address_p (xfoo0, xfoo1, mode, strict)
2026 || indexable_address_p (xfoo1, xfoo0, mode, strict))
2027 return true;
2028
2029 return false;
2030 }
2031
2032 /* Return true if x (a legitimate address expression) has an effect that
2033 depends on the machine mode it is used for. On the VAX, the predecrement
2034 and postincrement address depend thus (the amount of decrement or
2035 increment being the length of the operand) and all indexed address depend
2036 thus (because the index scale factor is the length of the operand). */
2037
2038 static bool
vax_mode_dependent_address_p(const_rtx x,addr_space_t as ATTRIBUTE_UNUSED)2039 vax_mode_dependent_address_p (const_rtx x, addr_space_t as ATTRIBUTE_UNUSED)
2040 {
2041 rtx xfoo0, xfoo1;
2042
2043 /* Auto-increment cases are now dealt with generically in recog.cc. */
2044 if (GET_CODE (x) != PLUS)
2045 return false;
2046
2047 xfoo0 = XEXP (x, 0);
2048 xfoo1 = XEXP (x, 1);
2049
2050 if (CONST_INT_P (xfoo0) && REG_P (xfoo1))
2051 return false;
2052 if (CONST_INT_P (xfoo1) && REG_P (xfoo0))
2053 return false;
2054 if (!flag_pic && CONSTANT_ADDRESS_P (xfoo0) && REG_P (xfoo1))
2055 return false;
2056 if (!flag_pic && CONSTANT_ADDRESS_P (xfoo1) && REG_P (xfoo0))
2057 return false;
2058
2059 return true;
2060 }
2061
2062 static rtx
decompose_address_operand(rtx addr)2063 decompose_address_operand(rtx addr)
2064 {
2065 enum rtx_code code = GET_CODE (addr);
2066
2067 switch (code)
2068 {
2069 case CONST:
2070 return decompose_address_operand (XEXP (addr, 0));
2071 case PLUS:
2072 case MULT:
2073 {
2074 rtx op0, op1;
2075 rtx temp;
2076 /*
2077 * Generate a temporary register, assign the result of
2078 * decomposing op0 to it, then generate an op code opping (PLUS
2079 * or MULT) the result of decomposing op1 to it.
2080 * Return the temporary register.
2081 */
2082 temp = gen_reg_rtx (Pmode);
2083 op0 = decompose_address_operand (XEXP (addr, 0));
2084 op1 = decompose_address_operand (XEXP (addr, 1));
2085
2086 emit_move_insn (temp, op0);
2087
2088 if (code == PLUS)
2089 {
2090 temp = gen_rtx_PLUS (Pmode, temp, op1);
2091 }
2092 else if (code == MULT)
2093 {
2094 temp = gen_rtx_MULT (Pmode, temp, op1);
2095 }
2096
2097 return temp;
2098 }
2099 break;
2100 default:
2101 break;
2102 }
2103 return addr;
2104 }
2105
2106 static rtx
fixup_mathdi_operand(rtx x,machine_mode mode)2107 fixup_mathdi_operand (rtx x, machine_mode mode)
2108 {
2109 if (illegal_addsub_di_memory_operand (x, mode))
2110 {
2111 rtx addr = XEXP (x, 0);
2112 rtx temp = gen_reg_rtx (Pmode);
2113 rtx offset = 0;
2114 #ifdef NO_EXTERNAL_INDIRECT_ADDRESS
2115 if (GET_CODE (addr) == CONST && flag_pic)
2116 {
2117 offset = XEXP (XEXP (addr, 0), 1);
2118 addr = XEXP (XEXP (addr, 0), 0);
2119 }
2120 #endif
2121 emit_move_insn (temp, decompose_address_operand (addr));
2122 if (offset)
2123 temp = gen_rtx_PLUS (Pmode, temp, offset);
2124 x = gen_rtx_MEM (DImode, temp);
2125 }
2126 return x;
2127 }
2128
2129 void
vax_expand_addsub_di_operands(rtx * operands,enum rtx_code code)2130 vax_expand_addsub_di_operands (rtx * operands, enum rtx_code code)
2131 {
2132 int hi_only = operand_subword (operands[2], 0, 0, DImode) == const0_rtx;
2133 rtx temp;
2134
2135 rtx (*gen_old_insn)(rtx, rtx, rtx);
2136 rtx (*gen_si_insn)(rtx, rtx, rtx);
2137 rtx (*gen_insn)(rtx, rtx, rtx);
2138
2139 if (code == PLUS)
2140 {
2141 gen_old_insn = gen_adddi3_old;
2142 gen_si_insn = gen_addsi3;
2143 gen_insn = gen_adcdi3;
2144 }
2145 else if (code == MINUS)
2146 {
2147 gen_old_insn = gen_subdi3_old;
2148 gen_si_insn = gen_subsi3;
2149 gen_insn = gen_sbcdi3;
2150 }
2151 else
2152 gcc_unreachable ();
2153
2154 /* If this is addition (thus operands are commutative) and if there is one
2155 addend that duplicates the desination, we want that addend to be the
2156 first addend. */
2157 if (code == PLUS
2158 && rtx_equal_p (operands[0], operands[2])
2159 && !rtx_equal_p (operands[1], operands[2]))
2160 {
2161 temp = operands[2];
2162 operands[2] = operands[1];
2163 operands[1] = temp;
2164 }
2165
2166 if (!TARGET_QMATH)
2167 {
2168 emit_insn ((*gen_old_insn) (operands[0], operands[1], operands[2]));
2169 }
2170 else if (hi_only)
2171 {
2172 if (!rtx_equal_p (operands[0], operands[1])
2173 && (REG_P (operands[0]) && MEM_P (operands[1])))
2174 {
2175 emit_move_insn (operands[0], operands[1]);
2176 operands[1] = operands[0];
2177 }
2178
2179 operands[0] = fixup_mathdi_operand (operands[0], DImode);
2180 operands[1] = fixup_mathdi_operand (operands[1], DImode);
2181 operands[2] = fixup_mathdi_operand (operands[2], DImode);
2182
2183 if (!rtx_equal_p (operands[0], operands[1]))
2184 emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
2185 operand_subword (operands[1], 0, 0, DImode));
2186
2187 emit_insn ((*gen_si_insn) (operand_subword (operands[0], 1, 0, DImode),
2188 operand_subword (operands[1], 1, 0, DImode),
2189 operand_subword (operands[2], 1, 0, DImode)));
2190 }
2191 else
2192 {
2193 /* If we are adding a value to itself, that's really a multiply by 2,
2194 and that's just a left shift by 1. If subtracting, it's just 0. */
2195 if (rtx_equal_p (operands[1], operands[2]))
2196 {
2197 if (code == PLUS)
2198 emit_insn (gen_ashldi3 (operands[0], operands[1], const1_rtx));
2199 else
2200 emit_move_insn (operands[0], const0_rtx);
2201 return;
2202 }
2203
2204 operands[0] = fixup_mathdi_operand (operands[0], DImode);
2205
2206 /* If an operand is the same as operand[0], use the operand[0] rtx
2207 because fixup will an equivalent rtx but not an equal one. */
2208
2209 if (rtx_equal_p (operands[0], operands[1]))
2210 operands[1] = operands[0];
2211 else
2212 operands[1] = fixup_mathdi_operand (operands[1], DImode);
2213
2214 if (rtx_equal_p (operands[0], operands[2]))
2215 operands[2] = operands[0];
2216 else
2217 operands[2] = fixup_mathdi_operand (operands[2], DImode);
2218
2219 /* If we are adding or subtracting 0, then this is a move. */
2220 if (code == PLUS && operands[1] == const0_rtx)
2221 {
2222 temp = operands[2];
2223 operands[2] = operands[1];
2224 operands[1] = temp;
2225 }
2226 if (operands[2] == const0_rtx)
2227 {
2228 emit_move_insn (operands[0], operands[1]);
2229 return;
2230 }
2231
2232 /* If we are subtracting not from ourselves [d = a - b], and because the
2233 carry ops are two operand only, we would need to do a move prior to
2234 the subtract. And if d == b, we would need a temp otherwise
2235 [d = a, d -= d] and we end up with 0. Instead we rewrite d = a - b
2236 into d = -b, d += a. Since -b can never overflow, even if b == d,
2237 no temp is needed.
2238
2239 If we are doing addition, since the carry ops are two operand, if
2240 we aren't adding to ourselves, move the first addend to the
2241 destination first. */
2242
2243 gcc_assert (operands[1] != const0_rtx || code == MINUS);
2244 if (!rtx_equal_p (operands[0], operands[1]) && operands[1] != const0_rtx)
2245 {
2246 if (code == MINUS && CONSTANT_P (operands[1]))
2247 {
2248 emit_insn (gen_sbcdi3 (operands[0], const0_rtx, operands[2]));
2249 code = PLUS;
2250 gen_insn = gen_adcdi3;
2251 operands[2] = operands[1];
2252 operands[1] = operands[0];
2253 }
2254 else
2255 emit_move_insn (operands[0], operands[1]);
2256 }
2257
2258 /* Subtracting a constant will have been rewritten to an addition of the
2259 negative of that constant before we get here. */
2260 gcc_assert (!CONSTANT_P (operands[2]) || code == PLUS);
2261 emit_insn ((*gen_insn) (operands[0], operands[1], operands[2]));
2262 }
2263 }
2264
2265 /* Output assembler code for a block containing the constant parts
2266 of a trampoline, leaving space for the variable parts. */
2267
2268 /* On the VAX, the trampoline contains an entry mask and two instructions:
2269 .word NN
2270 movl $STATIC,r0 (store the functions static chain)
2271 jmp *$FUNCTION (jump to function code at address FUNCTION) */
2272
2273 static void
vax_asm_trampoline_template(FILE * f ATTRIBUTE_UNUSED)2274 vax_asm_trampoline_template (FILE *f ATTRIBUTE_UNUSED)
2275 {
2276 assemble_aligned_integer (2, const0_rtx);
2277 assemble_aligned_integer (2, GEN_INT (0x8fd0));
2278 assemble_aligned_integer (4, const0_rtx);
2279 assemble_aligned_integer (1, GEN_INT (0x50 + STATIC_CHAIN_REGNUM));
2280 assemble_aligned_integer (2, GEN_INT (0x9f17));
2281 assemble_aligned_integer (4, const0_rtx);
2282 }
2283
2284 /* We copy the register-mask from the function's pure code
2285 to the start of the trampoline. */
2286
2287 static void
vax_trampoline_init(rtx m_tramp,tree fndecl,rtx cxt)2288 vax_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
2289 {
2290 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2291 rtx mem;
2292
2293 emit_block_move (m_tramp, assemble_trampoline_template (),
2294 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
2295
2296 mem = adjust_address (m_tramp, HImode, 0);
2297 emit_move_insn (mem, gen_const_mem (HImode, fnaddr));
2298
2299 mem = adjust_address (m_tramp, SImode, 4);
2300 emit_move_insn (mem, cxt);
2301 mem = adjust_address (m_tramp, SImode, 11);
2302 emit_move_insn (mem, plus_constant (Pmode, fnaddr, 2));
2303 emit_insn (gen_sync_istream ());
2304 }
2305
2306 /* Value is the number of bytes of arguments automatically
2307 popped when returning from a subroutine call.
2308 FUNDECL is the declaration node of the function (as a tree),
2309 FUNTYPE is the data type of the function (as a tree),
2310 or for a library call it is an identifier node for the subroutine name.
2311 SIZE is the number of bytes of arguments passed on the stack.
2312
2313 On the VAX, the RET insn pops a maximum of 255 args for any function. */
2314
2315 static poly_int64
vax_return_pops_args(tree fundecl ATTRIBUTE_UNUSED,tree funtype ATTRIBUTE_UNUSED,poly_int64 size)2316 vax_return_pops_args (tree fundecl ATTRIBUTE_UNUSED,
2317 tree funtype ATTRIBUTE_UNUSED, poly_int64 size)
2318 {
2319 return size > 255 * 4 ? 0 : (HOST_WIDE_INT) size;
2320 }
2321
2322 /* Implement TARGET_FUNCTION_ARG. On the VAX all args are pushed. */
2323
2324 static rtx
vax_function_arg(cumulative_args_t,const function_arg_info &)2325 vax_function_arg (cumulative_args_t, const function_arg_info &)
2326 {
2327 return NULL_RTX;
2328 }
2329
2330 /* Update the data in CUM to advance over argument ARG. */
2331
2332 static void
vax_function_arg_advance(cumulative_args_t cum_v,const function_arg_info & arg)2333 vax_function_arg_advance (cumulative_args_t cum_v,
2334 const function_arg_info &arg)
2335 {
2336 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2337
2338 *cum += (arg.promoted_size_in_bytes () + 3) & ~3;
2339 }
2340
2341 static HOST_WIDE_INT
vax_starting_frame_offset(void)2342 vax_starting_frame_offset (void)
2343 {
2344 /* On ELF targets, reserve the top of the stack for exception handler
2345 stackadj value. */
2346 return TARGET_ELF ? -4 : 0;
2347 }
2348
2349 /* Return 1 if a bitfield instruction (extv/extzv) may trap */
2350 static int
vax_bitfield_may_trap_p(const_rtx x,unsigned flags)2351 vax_bitfield_may_trap_p (const_rtx x, unsigned flags)
2352 {
2353 /* per the VARM
2354 * Bitfield instructions may trap if
2355 * size (arg1) GTRU 32
2356 * size (arg1) NEQ 0, pos (arg 2) GTRU 31 and the field is in a register
2357 * i.e. REG_P(operands[0]) is true
2358 *
2359 * GCC can only determine that a bitfield instruction will not trap
2360 * if the size and position arguments are constants; if they aren't,
2361 * the instruction must be assumed to trap.
2362 */
2363 rtx field = XEXP (x, 0);
2364 rtx size = XEXP (x, 1);
2365 rtx pos = XEXP (x, 2);
2366 int retval = 0;
2367
2368 if (!CONST_INT_P (size) || !CONST_INT_P (pos))
2369 retval = 1;
2370 else if (INTVAL (size) < 0 || INTVAL (size) > GET_MODE_BITSIZE ( SImode ))
2371 retval = 1;
2372 else if (REG_P (field) && INTVAL (size) != 0
2373 && (INTVAL (pos) < 0 || INTVAL (pos) >= GET_MODE_BITSIZE ( SImode )))
2374 retval = 1;
2375 else
2376 retval = 0;
2377 return retval;
2378 }
2379