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