1 /* Subroutines for gcc2 for pdp11.
2    Copyright (C) 1994-2022 Free Software Foundation, Inc.
3    Contributed by Michael K. Gschwind (mike@vlsivie.tuwien.ac.at).
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #define IN_TARGET_CODE 1
22 
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "stringpool.h"
31 #include "attribs.h"
32 #include "df.h"
33 #include "memmodel.h"
34 #include "tm_p.h"
35 #include "insn-config.h"
36 #include "insn-attr.h"
37 #include "regs.h"
38 #include "emit-rtl.h"
39 #include "recog.h"
40 #include "conditions.h"
41 #include "output.h"
42 #include "stor-layout.h"
43 #include "varasm.h"
44 #include "calls.h"
45 #include "expr.h"
46 #include "builtins.h"
47 #include "dbxout.h"
48 #include "explow.h"
49 #include "expmed.h"
50 
51 /* This file should be included last.  */
52 #include "target-def.h"
53 
54 /* this is the current value returned by the macro FIRST_PARM_OFFSET
55    defined in tm.h */
56 int current_first_parm_offset;
57 
58 /* Routines to encode/decode pdp11 floats */
59 static void encode_pdp11_f (const struct real_format *fmt,
60                                   long *, const REAL_VALUE_TYPE *);
61 static void decode_pdp11_f (const struct real_format *,
62                                   REAL_VALUE_TYPE *, const long *);
63 static void encode_pdp11_d (const struct real_format *fmt,
64                                   long *, const REAL_VALUE_TYPE *);
65 static void decode_pdp11_d (const struct real_format *,
66                                   REAL_VALUE_TYPE *, const long *);
67 
68 /* These two are taken from the corresponding vax descriptors
69    in real.cc, changing only the encode/decode routine pointers.  */
70 const struct real_format pdp11_f_format =
71   {
72     encode_pdp11_f,
73     decode_pdp11_f,
74     2,
75     24,
76     24,
77     -127,
78     127,
79     15,
80     15,
81     0,
82     false,
83     false,
84     false,
85     false,
86     false,
87     false,
88     false,
89     false,
90     "pdp11_f"
91   };
92 
93 const struct real_format pdp11_d_format =
94   {
95     encode_pdp11_d,
96     decode_pdp11_d,
97     2,
98     56,
99     56,
100     -127,
101     127,
102     15,
103     15,
104     0,
105     false,
106     false,
107     false,
108     false,
109     false,
110     false,
111     false,
112     false,
113     "pdp11_d"
114   };
115 
116 static void
encode_pdp11_f(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)117 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
118                     const REAL_VALUE_TYPE *r)
119 {
120   (*vax_f_format.encode) (fmt, buf, r);
121   buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
122 }
123 
124 static void
decode_pdp11_f(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)125 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
126                     REAL_VALUE_TYPE *r, const long *buf)
127 {
128   long tbuf;
129   tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
130   (*vax_f_format.decode) (fmt, r, &tbuf);
131 }
132 
133 static void
encode_pdp11_d(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)134 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
135                     const REAL_VALUE_TYPE *r)
136 {
137   (*vax_d_format.encode) (fmt, buf, r);
138   buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
139   buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
140 }
141 
142 static void
decode_pdp11_d(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)143 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
144                     REAL_VALUE_TYPE *r, const long *buf)
145 {
146   long tbuf[2];
147   tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
148   tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
149   (*vax_d_format.decode) (fmt, r, tbuf);
150 }
151 
152 static const char *singlemove_string (rtx *);
153 static bool pdp11_assemble_integer (rtx, unsigned int, int);
154 static bool pdp11_rtx_costs (rtx, machine_mode, int, int, int *, bool);
155 static int pdp11_addr_cost (rtx, machine_mode, addr_space_t, bool);
156 static int pdp11_insn_cost (rtx_insn *insn, bool speed);
157 static rtx_insn *pdp11_md_asm_adjust (vec<rtx> &, vec<rtx> &,
158                                               vec<machine_mode> &, vec<const char *> &,
159                                               vec<rtx> &, HARD_REG_SET &, location_t);
160 static bool pdp11_return_in_memory (const_tree, const_tree);
161 static rtx pdp11_function_value (const_tree, const_tree, bool);
162 static rtx pdp11_libcall_value (machine_mode, const_rtx);
163 static bool pdp11_function_value_regno_p (const unsigned int);
164 static void pdp11_trampoline_init (rtx, tree, rtx);
165 static rtx pdp11_function_arg (cumulative_args_t, const function_arg_info &);
166 static void pdp11_function_arg_advance (cumulative_args_t,
167                                                   const function_arg_info &);
168 static void pdp11_conditional_register_usage (void);
169 static bool pdp11_legitimate_constant_p (machine_mode, rtx);
170 
171 static bool pdp11_scalar_mode_supported_p (scalar_mode);
172 
173 /* Initialize the GCC target structure.  */
174 #undef TARGET_ASM_BYTE_OP
175 #define TARGET_ASM_BYTE_OP NULL
176 #undef TARGET_ASM_ALIGNED_HI_OP
177 #define TARGET_ASM_ALIGNED_HI_OP NULL
178 #undef TARGET_ASM_ALIGNED_SI_OP
179 #define TARGET_ASM_ALIGNED_SI_OP NULL
180 #undef TARGET_ASM_INTEGER
181 #define TARGET_ASM_INTEGER pdp11_assemble_integer
182 
183 /* These two apply to Unix and GNU assembler; for DEC, they are
184    overridden during option processing.  */
185 #undef TARGET_ASM_OPEN_PAREN
186 #define TARGET_ASM_OPEN_PAREN "["
187 #undef TARGET_ASM_CLOSE_PAREN
188 #define TARGET_ASM_CLOSE_PAREN "]"
189 
190 #undef TARGET_RTX_COSTS
191 #define TARGET_RTX_COSTS pdp11_rtx_costs
192 
193 #undef  TARGET_ADDRESS_COST
194 #define TARGET_ADDRESS_COST pdp11_addr_cost
195 
196 #undef  TARGET_INSN_COST
197 #define TARGET_INSN_COST pdp11_insn_cost
198 
199 #undef  TARGET_MD_ASM_ADJUST
200 #define TARGET_MD_ASM_ADJUST pdp11_md_asm_adjust
201 
202 #undef TARGET_FUNCTION_ARG
203 #define TARGET_FUNCTION_ARG pdp11_function_arg
204 #undef TARGET_FUNCTION_ARG_ADVANCE
205 #define TARGET_FUNCTION_ARG_ADVANCE pdp11_function_arg_advance
206 
207 #undef TARGET_RETURN_IN_MEMORY
208 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
209 
210 #undef TARGET_FUNCTION_VALUE
211 #define TARGET_FUNCTION_VALUE pdp11_function_value
212 #undef TARGET_LIBCALL_VALUE
213 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
214 #undef TARGET_FUNCTION_VALUE_REGNO_P
215 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
216 
217 #undef TARGET_TRAMPOLINE_INIT
218 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
219 
220 #undef  TARGET_SECONDARY_RELOAD
221 #define TARGET_SECONDARY_RELOAD pdp11_secondary_reload
222 
223 #undef  TARGET_REGISTER_MOVE_COST
224 #define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost
225 
226 #undef  TARGET_PREFERRED_RELOAD_CLASS
227 #define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class
228 
229 #undef  TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
230 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
231 
232 #undef  TARGET_LRA_P
233 #define TARGET_LRA_P pdp11_lra_p
234 
235 #undef  TARGET_LEGITIMATE_ADDRESS_P
236 #define TARGET_LEGITIMATE_ADDRESS_P pdp11_legitimate_address_p
237 
238 #undef  TARGET_CONDITIONAL_REGISTER_USAGE
239 #define TARGET_CONDITIONAL_REGISTER_USAGE pdp11_conditional_register_usage
240 
241 #undef  TARGET_OPTION_OVERRIDE
242 #define TARGET_OPTION_OVERRIDE pdp11_option_override
243 
244 #undef  TARGET_ASM_FILE_START_FILE_DIRECTIVE
245 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
246 
247 #undef  TARGET_ASM_OUTPUT_IDENT
248 #define TARGET_ASM_OUTPUT_IDENT pdp11_output_ident
249 
250 #undef  TARGET_ASM_FUNCTION_SECTION
251 #define TARGET_ASM_FUNCTION_SECTION pdp11_function_section
252 
253 #undef  TARGET_ASM_NAMED_SECTION
254 #define   TARGET_ASM_NAMED_SECTION pdp11_asm_named_section
255 
256 #undef  TARGET_ASM_INIT_SECTIONS
257 #define TARGET_ASM_INIT_SECTIONS pdp11_asm_init_sections
258 
259 #undef  TARGET_ASM_FILE_START
260 #define TARGET_ASM_FILE_START pdp11_file_start
261 
262 #undef  TARGET_ASM_FILE_END
263 #define TARGET_ASM_FILE_END pdp11_file_end
264 
265 #undef  TARGET_PRINT_OPERAND
266 #define TARGET_PRINT_OPERAND pdp11_asm_print_operand
267 
268 #undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
269 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P pdp11_asm_print_operand_punct_valid_p
270 
271 #undef  TARGET_LEGITIMATE_CONSTANT_P
272 #define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p
273 
274 #undef  TARGET_SCALAR_MODE_SUPPORTED_P
275 #define TARGET_SCALAR_MODE_SUPPORTED_P pdp11_scalar_mode_supported_p
276 
277 #undef  TARGET_HARD_REGNO_NREGS
278 #define TARGET_HARD_REGNO_NREGS pdp11_hard_regno_nregs
279 
280 #undef  TARGET_HARD_REGNO_MODE_OK
281 #define TARGET_HARD_REGNO_MODE_OK pdp11_hard_regno_mode_ok
282 
283 #undef  TARGET_MODES_TIEABLE_P
284 #define TARGET_MODES_TIEABLE_P pdp11_modes_tieable_p
285 
286 #undef  TARGET_SECONDARY_MEMORY_NEEDED
287 #define TARGET_SECONDARY_MEMORY_NEEDED pdp11_secondary_memory_needed
288 
289 #undef  TARGET_CAN_CHANGE_MODE_CLASS
290 #define TARGET_CAN_CHANGE_MODE_CLASS pdp11_can_change_mode_class
291 
292 #undef TARGET_INVALID_WITHIN_DOLOOP
293 #define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_insn_null
294 
295 #undef  TARGET_CXX_GUARD_TYPE
296 #define TARGET_CXX_GUARD_TYPE pdp11_guard_type
297 
298 #undef  TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT
299 #define TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT hook_bool_void_false
300 
301 #undef  TARGET_CXX_LIBRARY_RTTI_COMDAT
302 #define TARGET_CXX_LIBRARY_RTTI_COMDAT hook_bool_void_false
303 
304 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
305 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
306 
307 #undef  TARGET_STACK_PROTECT_RUNTIME_ENABLED_P
308 #define TARGET_STACK_PROTECT_RUNTIME_ENABLED_P hook_bool_void_false
309 
310 /* A helper function to determine if REGNO should be saved in the
311    current function's stack frame.  */
312 
313 static inline bool
pdp11_saved_regno(unsigned regno)314 pdp11_saved_regno (unsigned regno)
315 {
316   return !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno);
317 }
318 
319 /* Expand the function prologue.  */
320 
321 /* Frame layout, from high to low memory (stack push order):
322    return address (from jsr instruction)
323    saved CPU registers, lowest number first
324    saved FPU registers, lowest number first, always 64 bit mode
325    *** frame pointer points here ***
326    local variables
327    alloca storage if any.  */
328 void
pdp11_expand_prologue(void)329 pdp11_expand_prologue (void)
330 {
331   HOST_WIDE_INT fsize = get_frame_size ();
332   unsigned regno;
333   rtx x, via_ac = NULL;
334 
335   /* If we are outputting code for main, the switch FPU to the
336      right mode if TARGET_FPU.  */
337   if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
338     {
339       emit_insn (gen_setd ());
340       emit_insn (gen_seti ());
341     }
342 
343   /* Save CPU registers.  */
344   for (regno = R0_REGNUM; regno <= PC_REGNUM; regno++)
345     if (pdp11_saved_regno (regno))
346       {
347           x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
348           x = gen_frame_mem (Pmode, x);
349           emit_move_insn (x, gen_rtx_REG (Pmode, regno));
350       }
351 
352   /* Save FPU registers.  */
353   for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
354     if (pdp11_saved_regno (regno))
355       {
356           x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
357           x = gen_frame_mem (DFmode, x);
358           via_ac = gen_rtx_REG (DFmode, regno);
359           emit_move_insn (x, via_ac);
360       }
361 
362   /* ??? Maybe make ac4, ac5 call used regs?? */
363   for (regno = AC4_REGNUM; regno <= AC5_REGNUM; regno++)
364     if (pdp11_saved_regno (regno))
365       {
366           gcc_assert (via_ac != NULL);
367           emit_move_insn (via_ac, gen_rtx_REG (DFmode, regno));
368 
369           x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
370           x = gen_frame_mem (DFmode, x);
371           emit_move_insn (x, via_ac);
372       }
373 
374   if (frame_pointer_needed)
375     emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
376 
377   /* Make local variable space.  */
378   if (fsize)
379     emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
380                                  GEN_INT (-fsize)));
381 }
382 
383 /* Generate epilogue.  This uses the frame pointer to pop the local
384    variables and any alloca data off the stack.  If there is no alloca
385    and frame pointer elimination hasn't been disabled, there is no
386    frame pointer and the local variables are popped by adjusting the
387    stack pointer instead.  */
388 
389 void
pdp11_expand_epilogue(void)390 pdp11_expand_epilogue (void)
391 {
392   HOST_WIDE_INT fsize = get_frame_size ();
393   unsigned regno;
394   rtx x, reg, via_ac = NULL;
395 
396   /* Deallocate the local variables.  */
397   if (fsize)
398     {
399       if (frame_pointer_needed)
400           {
401             /* We can deallocate the frame with a single move.  */
402             emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
403           }
404       else
405           emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
406                                      GEN_INT (fsize)));
407     }
408 
409   /* Restore the FPU registers.  */
410   if (pdp11_saved_regno (AC4_REGNUM) || pdp11_saved_regno (AC5_REGNUM))
411     {
412       /* Find a temporary with which to restore AC4/5.  */
413       for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
414           if (pdp11_saved_regno (regno))
415             {
416               via_ac = gen_rtx_REG (DFmode, regno);
417               break;
418             }
419     }
420 
421   /* Restore registers via pops.  */
422 
423   for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
424     if (pdp11_saved_regno (regno))
425       {
426           x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
427           x = gen_frame_mem (DFmode, x);
428           reg = gen_rtx_REG (DFmode, regno);
429 
430           if (LOAD_FPU_REG_P (regno))
431             emit_move_insn (reg, x);
432           else
433             {
434               emit_move_insn (via_ac, x);
435               emit_move_insn (reg, via_ac);
436             }
437       }
438 
439   for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
440     if (pdp11_saved_regno (regno))
441       {
442           x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
443           x = gen_frame_mem (Pmode, x);
444           emit_move_insn (gen_rtx_REG (Pmode, regno), x);
445       }
446 
447   emit_jump_insn (gen_rtspc ());
448 }
449 
450 /* Return the best assembler insn template
451    for moving operands[1] into operands[0] as a fullword.  */
452 static const char *
singlemove_string(rtx * operands)453 singlemove_string (rtx *operands)
454 {
455   if (operands[1] != const0_rtx)
456     return "mov\t%1,%0";
457 
458   return "clr\t%0";
459 }
460 
461 
462 /* Expand multi-word operands (SImode or DImode) into the 2 or 4
463    corresponding HImode operands.  The number of operands is given as
464    the third argument, the word count for the mode as the fourth
465    argument, and the required order of parts as the sixth argument.
466    The word count is explicit because sometimes we're asked to compare
467    two constants, both of which have mode VOIDmode, so we can't always
468    rely on the input operand mode to imply the operand size.  */
469 bool
pdp11_expand_operands(rtx * operands,rtx exops[][2],int opcount,int words,pdp11_action * action,pdp11_partorder order)470 pdp11_expand_operands (rtx *operands, rtx exops[][2],
471                            int opcount, int words,
472                            pdp11_action *action, pdp11_partorder order)
473 {
474   int op, w, i, sh;
475   pdp11_partorder useorder;
476   bool sameoff = false;
477   enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype;
478   long sval[2];
479 
480   /* If either piece order is accepted and one is pre-decrement
481      while the other is post-increment, set order to be high order
482      word first.  That will force the pre-decrement to be turned
483      into a pointer adjust, then offset addressing.
484      Otherwise, if either operand uses pre-decrement, that means
485      the order is low order first.
486      Otherwise, if both operands are registers and destination is
487      higher than source and they overlap, do low order word (highest
488      register number) first.  */
489   useorder = either;
490   if (opcount == 2)
491     {
492       if (GET_CODE (operands[0]) == MEM &&
493             GET_CODE (operands[1]) == MEM &&
494             ((GET_CODE (XEXP (operands[0], 0)) == POST_INC &&
495               GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ||
496              (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC &&
497               GET_CODE (XEXP (operands[1], 0)) == POST_INC)))
498               useorder = big;
499       else if ((GET_CODE (operands[0]) == MEM &&
500                     GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ||
501                  (GET_CODE (operands[1]) == MEM &&
502                     GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))
503           useorder = little;
504       else if (REG_P (operands[0]) && REG_P (operands[1]) &&
505                  REGNO (operands[0]) > REGNO (operands[1]) &&
506                  REGNO (operands[0]) < REGNO (operands[1]) + words)
507               useorder = little;
508 
509       /* Check for source == offset from register and dest == push of
510            the same register.  In that case, we have to use the same
511            offset (the one for the low order word) for all words, because
512            the push increases the offset to each source word.
513            In theory there are other cases like this, for example dest == pop,
514            but those don't occur in real life so ignore those.  */
515       if (GET_CODE (operands[0]) ==  MEM
516             && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
517             && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
518             && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
519           sameoff = true;
520     }
521 
522   /* If the caller didn't specify order, use the one we computed,
523      or high word first if we don't care either.  If the caller did
524      specify, verify we don't have a problem with that order.
525      (If it matters to the caller, constraints need to be used to
526      ensure this case doesn't occur).  */
527   if (order == either)
528     order = (useorder == either) ? big : useorder;
529   else
530     gcc_assert (useorder == either || useorder == order);
531 
532 
533   for (op = 0; op < opcount; op++)
534     {
535       /* First classify the operand.  */
536       if (REG_P (operands[op]))
537           optype = REGOP;
538       else if (CONST_INT_P (operands[op])
539                  || GET_CODE (operands[op]) == CONST_DOUBLE)
540           optype = CNSTOP;
541       else if (GET_CODE (XEXP (operands[op], 0)) == POST_INC)
542           optype = POPOP;
543       else if (GET_CODE (XEXP (operands[op], 0)) == PRE_DEC)
544           optype = PUSHOP;
545       else if (!reload_in_progress || offsettable_memref_p (operands[op]))
546           optype = OFFSOP;
547       else if (GET_CODE (operands[op]) == MEM)
548           optype = MEMOP;
549       else
550           optype = RNDOP;
551 
552       /* Check for the cases that the operand constraints are not
553            supposed to allow to happen. Return failure for such cases.  */
554       if (optype == RNDOP)
555           return false;
556 
557       if (action != NULL)
558           action[op] = no_action;
559 
560       /* If the operand uses pre-decrement addressing but we
561            want to get the parts high order first,
562            decrement the former register explicitly
563            and change the operand into ordinary indexing.  */
564       if (optype == PUSHOP && order == big)
565           {
566             gcc_assert (action != NULL);
567             action[op] = dec_before;
568             operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
569                                               XEXP (XEXP (operands[op], 0), 0));
570             optype = OFFSOP;
571           }
572       /* If the operand uses post-increment mode but we want
573            to get the parts low order first, change the operand
574            into ordinary indexing and remember to increment
575            the register explicitly when we're done.  */
576       else if (optype == POPOP && order == little)
577           {
578             gcc_assert (action != NULL);
579             action[op] = inc_after;
580             operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
581                                               XEXP (XEXP (operands[op], 0), 0));
582             optype = OFFSOP;
583           }
584 
585       if (GET_CODE (operands[op]) == CONST_DOUBLE)
586           {
587             gcc_assert (GET_MODE (operands[op]) != VOIDmode);
588             REAL_VALUE_TO_TARGET_DOUBLE
589               (*CONST_DOUBLE_REAL_VALUE (operands[op]), sval);
590           }
591 
592       for (i = 0; i < words; i++)
593           {
594             if (order == big)
595               w = i;
596             else if (sameoff)
597               w = words - 1;
598             else
599               w = words - 1 - i;
600 
601             /* Set the output operand to be word "w" of the input.  */
602             if (optype == REGOP)
603               exops[i][op] = gen_rtx_REG (HImode, REGNO (operands[op]) + w);
604             else if (optype == OFFSOP)
605               exops[i][op] = adjust_address (operands[op], HImode, w * 2);
606             else if (optype == CNSTOP)
607               {
608                 if (GET_CODE (operands[op]) == CONST_DOUBLE)
609                     {
610                       sh = 16 - (w & 1) * 16;
611                       exops[i][op] = gen_rtx_CONST_INT (HImode, (sval[w / 2] >> sh) & 0xffff);
612                     }
613                 else
614                     {
615                       sh = ((words - 1 - w) * 16);
616                       exops[i][op] = gen_rtx_CONST_INT (HImode, trunc_int_for_mode (INTVAL(operands[op]) >> sh, HImode));
617                     }
618               }
619             else
620               exops[i][op] = operands[op];
621           }
622     }
623   return true;
624 }
625 
626 /* Output assembler code to perform a multiple-word move insn
627    with operands OPERANDS.  This moves 2 or 4 words depending
628    on the machine mode of the operands.  */
629 
630 const char *
output_move_multiple(rtx * operands)631 output_move_multiple (rtx *operands)
632 {
633   rtx inops[2];
634   rtx exops[4][2];
635   rtx adjops[2];
636 
637   pdp11_action action[2];
638   int i, words;
639 
640   words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
641   adjops[1] = gen_rtx_CONST_INT (HImode, words * 2);
642 
643   inops[0] = operands[0];
644   inops[1] = operands[1];
645 
646   pdp11_expand_operands (inops, exops, 2, words, action, either);
647 
648   /* Check for explicit decrement before.  */
649   if (action[0] == dec_before)
650     {
651       adjops[0] = XEXP (XEXP (operands[0], 0), 0);
652       output_asm_insn ("sub\t%1,%0", adjops);
653     }
654   if (action[1] == dec_before)
655     {
656       adjops[0] = XEXP (XEXP (operands[1], 0), 0);
657       output_asm_insn ("sub\t%1,%0", adjops);
658     }
659 
660   /* Do the words.  */
661   for (i = 0; i < words; i++)
662     output_asm_insn (singlemove_string (exops[i]), exops[i]);
663 
664   /* Check for increment after.  */
665   if (action[0] == inc_after)
666     {
667       adjops[0] = XEXP (XEXP (operands[0], 0), 0);
668       output_asm_insn ("add\t%1,%0", adjops);
669     }
670   if (action[1] == inc_after)
671     {
672       adjops[0] = XEXP (XEXP (operands[1], 0), 0);
673       output_asm_insn ("add\t%1,%0", adjops);
674     }
675 
676   return "";
677 }
678 
679 /* Build an internal label.  */
680 void
pdp11_gen_int_label(char * label,const char * prefix,int num)681 pdp11_gen_int_label (char *label, const char *prefix, int num)
682 {
683   if (TARGET_DEC_ASM)
684     /* +1 because GCC numbers labels starting at zero.  */
685     sprintf (label, "*%u$", num + 1);
686   else
687     sprintf (label, "*%s_%u", prefix, num);
688 }
689 
690 /* Output an ascii string.  */
691 void
output_ascii(FILE * file,const char * p,int size)692 output_ascii (FILE *file, const char *p, int size)
693 {
694   int i, c;
695   const char *pseudo = "\t.ascii\t";
696   bool delim = false;
697 
698   if (TARGET_DEC_ASM)
699     {
700       if (p[size - 1] == '\0')
701           {
702             pseudo = "\t.asciz\t";
703             size--;
704           }
705       fputs (pseudo, file);
706       for (i = 0; i < size; i++)
707           {
708             c = *p++ & 0xff;
709             if (c < 32 || c == '"' || c > 126)
710               {
711                 if (delim)
712                     putc ('"', file);
713                 fprintf (file, "<%o>", c);
714                 delim = false;
715               }
716             else
717               {
718                 if (!delim)
719                     putc ('"', file);
720                 delim = true;
721                 putc (c, file);
722               }
723           }
724       if (delim)
725           putc ('"', file);
726       putc ('\n', file);
727     }
728   else
729     {
730       fprintf (file, "\t.byte ");
731 
732       for (i = 0; i < size; i++)
733           {
734             fprintf (file, "%#o", *p++ & 0xff);
735             if (i < size - 1)
736               putc (',', file);
737           }
738       putc ('\n', file);
739     }
740 }
741 
742 void
pdp11_asm_output_var(FILE * file,const char * name,int size,int align,bool global)743 pdp11_asm_output_var (FILE *file, const char *name, int size,
744                           int align, bool global)
745 {
746   switch_to_section (data_section);
747   if (align > 8)
748     fprintf (file, "\t.even\n");
749   if (TARGET_DEC_ASM)
750     {
751       assemble_name (file, name);
752       if (global)
753           fputs ("::", file);
754       else
755           fputs (":", file);
756       if (align > 8)
757           fprintf (file, "\t.blkw\t%o\n", (size & 0xffff) / 2);
758       else
759           fprintf (file, "\t.blkb\t%o\n", size & 0xffff);
760     }
761   else
762     {
763       if (global)
764           {
765             fprintf (file, ".globl ");
766             assemble_name (file, name);
767             fprintf (file, "\n");
768           }
769       assemble_name (file, name);
770       fputs (":", file);
771       ASM_OUTPUT_SKIP (file, size);
772     }
773 }
774 
775 /* Special format operators handled here:
776    # -- output the correct immediate operand marker for the assembler
777         dialect.
778    @ -- output the correct indirect marker for the assembler dialect.
779    o -- emit a constant value as a number (not an immediate operand)
780         in octal.  */
781 static void
pdp11_asm_print_operand(FILE * file,rtx x,int code)782 pdp11_asm_print_operand (FILE *file, rtx x, int code)
783 {
784   long sval[2];
785 
786   if (code == '#')
787     {
788       if (TARGET_DEC_ASM)
789           putc ('#', file);
790       else
791           putc ('$', file);
792     }
793   else if (code == '@')
794     {
795       if (TARGET_UNIX_ASM)
796           fprintf (file, "*");
797       else
798           fprintf (file, "@");
799     }
800   else if (GET_CODE (x) == REG)
801     fprintf (file, "%s", reg_names[REGNO (x)]);
802   else if (GET_CODE (x) == MEM)
803     output_address (GET_MODE (x), XEXP (x, 0));
804   else if (GET_CODE (x) == CONST_DOUBLE && FLOAT_MODE_P (GET_MODE (x)))
805     {
806       REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), sval);
807       if (TARGET_DEC_ASM)
808           fprintf (file, "#%lo", (sval[0] >> 16) & 0xffff);
809       else
810           fprintf (file, "$%#lo", (sval[0] >> 16) & 0xffff);
811     }
812   else
813     {
814       if (code != 'o')
815           {
816             if (TARGET_DEC_ASM)
817               putc ('#', file);
818             else
819               putc ('$', file);
820           }
821       output_addr_const_pdp11 (file, x);
822     }
823 }
824 
825 static bool
pdp11_asm_print_operand_punct_valid_p(unsigned char c)826 pdp11_asm_print_operand_punct_valid_p (unsigned char c)
827 {
828   return (c == '#' || c == '@');
829 }
830 
831 void
print_operand_address(FILE * file,rtx addr)832 print_operand_address (FILE *file, rtx addr)
833 {
834   rtx breg;
835   rtx offset;
836   int again = 0;
837 
838  retry:
839 
840   switch (GET_CODE (addr))
841     {
842     case MEM:
843       if (TARGET_UNIX_ASM)
844           fprintf (file, "*");
845       else
846           fprintf (file, "@");
847       addr = XEXP (addr, 0);
848       again = 1;
849       goto retry;
850 
851     case REG:
852       fprintf (file, "(%s)", reg_names[REGNO (addr)]);
853       break;
854 
855     case PRE_MODIFY:
856     case PRE_DEC:
857       fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
858       break;
859 
860     case POST_MODIFY:
861     case POST_INC:
862       fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
863       break;
864 
865     case PLUS:
866       breg = 0;
867       offset = 0;
868       if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
869             || GET_CODE (XEXP (addr, 0)) == MEM)
870           {
871             offset = XEXP (addr, 0);
872             addr = XEXP (addr, 1);
873           }
874       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
875                  || GET_CODE (XEXP (addr, 1)) == MEM)
876           {
877             offset = XEXP (addr, 1);
878             addr = XEXP (addr, 0);
879           }
880       if (GET_CODE (addr) != PLUS)
881           ;
882       else if (GET_CODE (XEXP (addr, 0)) == REG)
883           {
884             breg = XEXP (addr, 0);
885             addr = XEXP (addr, 1);
886           }
887       else if (GET_CODE (XEXP (addr, 1)) == REG)
888           {
889             breg = XEXP (addr, 1);
890             addr = XEXP (addr, 0);
891           }
892       if (GET_CODE (addr) == REG)
893           {
894             gcc_assert (breg == 0);
895             breg = addr;
896             addr = 0;
897           }
898       if (offset != 0)
899           {
900             gcc_assert (addr == 0);
901             addr = offset;
902           }
903       if (addr != 0)
904           output_addr_const_pdp11 (file, addr);
905       if (breg != 0)
906           {
907             gcc_assert (GET_CODE (breg) == REG);
908             fprintf (file, "(%s)", reg_names[REGNO (breg)]);
909           }
910       break;
911 
912     default:
913       if (!again && GET_CODE (addr) == CONST_INT)
914           {
915             /* Absolute (integer number) address.  */
916             if (TARGET_DEC_ASM)
917               fprintf (file, "@#");
918             else if (!TARGET_UNIX_ASM)
919               fprintf (file, "@$");
920           }
921       output_addr_const_pdp11 (file, addr);
922     }
923 }
924 
925 /* Target hook to assemble integer objects.  We need to use the
926    pdp-specific version of output_addr_const.  */
927 
928 static bool
pdp11_assemble_integer(rtx x,unsigned int size,int aligned_p)929 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
930 {
931   if (aligned_p)
932     switch (size)
933       {
934       case 1:
935           fprintf (asm_out_file, "\t.byte\t");
936           output_addr_const_pdp11 (asm_out_file, GEN_INT (INTVAL (x) & 0xff));
937           fputs ("\n", asm_out_file);
938           return true;
939 
940       case 2:
941           fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
942           output_addr_const_pdp11 (asm_out_file, x);
943           fputs ("\n", asm_out_file);
944           return true;
945       }
946   return default_assemble_integer (x, size, aligned_p);
947 }
948 
949 
950 static bool
pdp11_lra_p(void)951 pdp11_lra_p (void)
952 {
953   return TARGET_LRA;
954 }
955 
956 /* Register to register moves are cheap if both are general
957    registers.  */
958 static int
pdp11_register_move_cost(machine_mode mode ATTRIBUTE_UNUSED,reg_class_t c1,reg_class_t c2)959 pdp11_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
960                                 reg_class_t c1, reg_class_t c2)
961 {
962   if (CPU_REG_CLASS (c1) && CPU_REG_CLASS (c2))
963     return 2;
964   else if ((c1 >= LOAD_FPU_REGS && c1 <= FPU_REGS && c2 == LOAD_FPU_REGS) ||
965              (c2 >= LOAD_FPU_REGS && c2 <= FPU_REGS && c1 == LOAD_FPU_REGS))
966     return 2;
967   else
968     return 22;
969 }
970 
971 /* This tries to approximate what pdp11_insn_cost would do, but
972    without visibility into the actual instruction being generated it's
973    inevitably a rough approximation.  */
974 static bool
pdp11_rtx_costs(rtx x,machine_mode mode,int outer_code,int opno ATTRIBUTE_UNUSED,int * total,bool speed)975 pdp11_rtx_costs (rtx x, machine_mode mode, int outer_code,
976                      int opno ATTRIBUTE_UNUSED, int *total, bool speed)
977 {
978   const int code = GET_CODE (x);
979   const int asize = (mode == QImode) ? 2 : GET_MODE_SIZE (mode);
980   rtx src, dest;
981   const char *fmt;
982 
983   switch (code)
984     {
985     case CONST_INT:
986       /* Treat -1, 0, 1 as things that are optimized as clr or dec
987            etc. though that doesn't apply to every case.  */
988       if (INTVAL (x) >= -1 && INTVAL (x) <= 1)
989           {
990             *total = 0;
991             return true;
992           }
993       /* FALL THROUGH.  */
994     case REG:
995     case MEM:
996     case CONST:
997     case LABEL_REF:
998     case SYMBOL_REF:
999     case CONST_DOUBLE:
1000       *total = pdp11_addr_cost (x, mode, ADDR_SPACE_GENERIC, speed);
1001       return true;
1002     }
1003   if (GET_RTX_LENGTH (code) == 0)
1004     {
1005       if (speed)
1006           *total = 0;
1007       else
1008           *total = 2;
1009       return true;
1010     }
1011 
1012   /* Pick up source and dest.  We don't necessarily use the standard
1013      recursion in rtx_costs to figure the cost, because that would
1014      count the destination operand twice for three-operand insns.
1015      Also, this way we can catch special cases like move of zero, or
1016      add one.  */
1017   fmt = GET_RTX_FORMAT (code);
1018   if (fmt[0] != 'e' || (GET_RTX_LENGTH (code) > 1 && fmt[1] != 'e'))
1019     {
1020       if (speed)
1021           *total = 0;
1022       else
1023           *total = 2;
1024       return true;
1025     }
1026   if (GET_RTX_LENGTH (code) > 1)
1027     src = XEXP (x, 1);
1028   dest = XEXP (x, 0);
1029 
1030   /* If optimizing for size, claim everything costs 2 per word, plus
1031      whatever the operands require.  */
1032   if (!speed)
1033     *total = asize;
1034   else
1035     {
1036       if (FLOAT_MODE_P (mode))
1037           {
1038             switch (code)
1039               {
1040               case MULT:
1041               case DIV:
1042               case MOD:
1043                 *total = 20;
1044                 break;
1045 
1046               case COMPARE:
1047                 *total = 4;
1048                 break;
1049 
1050               case PLUS:
1051               case MINUS:
1052                 *total = 6;
1053                 break;
1054 
1055               default:
1056                 *total = 2;
1057                 break;
1058               }
1059           }
1060       else
1061           {
1062             /* Integer operations are scaled for SI and DI modes, though the
1063                scaling is not exactly accurate.  */
1064             switch (code)
1065               {
1066               case MULT:
1067                 *total = 5 * asize * asize;
1068                 break;
1069 
1070               case DIV:
1071                 *total = 10 * asize * asize;
1072                 break;
1073 
1074               case MOD:
1075                 /* Fake value because it's accounted for under DIV, since we
1076                      use a divmod pattern.  */
1077                 total = 0;
1078                 break;
1079 
1080               case ASHIFT:
1081               case ASHIFTRT:
1082               case LSHIFTRT:
1083                 /* This is a bit problematic because the cost depends on the
1084                      shift amount.  Make it <asize> for now, which is for the
1085                      case of a one bit shift.  */
1086                 *total = asize;
1087                 break;
1088 
1089               default:
1090                 *total = asize;
1091                 break;
1092               }
1093           }
1094     }
1095 
1096   /* Now see if we're looking at a SET.  If yes, then look at the
1097      source to see if this is a move or an arithmetic operation, and
1098      continue accordingly to handle the operands.  */
1099   if (code == SET)
1100     {
1101       switch (GET_CODE (src))
1102           {
1103           case REG:
1104           case MEM:
1105           case CONST_INT:
1106           case CONST:
1107           case LABEL_REF:
1108           case SYMBOL_REF:
1109           case CONST_DOUBLE:
1110             /* It's a move.  */
1111             *total += pdp11_addr_cost (dest, mode, ADDR_SPACE_GENERIC, speed);
1112             if (src != const0_rtx)
1113               *total += pdp11_addr_cost (src, mode, ADDR_SPACE_GENERIC, speed);
1114             return true;
1115           default:
1116             /* Not a move.  Get the cost of the source operand and add
1117                that in, but not the destination operand since we're
1118                dealing with read/modify/write operands.  */
1119             *total += rtx_cost (src, mode, (enum rtx_code) outer_code, 1, speed);
1120             return true;
1121           }
1122     }
1123   else if (code == PLUS || code == MINUS)
1124     {
1125       if (GET_CODE (src) == CONST_INT &&
1126             (INTVAL (src) == 1 || INTVAL (src) == -1))
1127           {
1128             *total += rtx_cost (dest, mode, (enum rtx_code) outer_code, 0, speed);
1129             return true;
1130           }
1131     }
1132   return false;
1133 }
1134 
1135 /* Return cost of accessing the supplied operand.  Registers are free.
1136    Anything else starts with a cost of two.  Add to that for memory
1137    references the memory accesses of the addressing mode (if any) plus
1138    the data reference; for other operands just the memory access (if
1139    any) for the mode.  */
1140 static int
pdp11_addr_cost(rtx addr,machine_mode mode,addr_space_t as ATTRIBUTE_UNUSED,bool speed)1141 pdp11_addr_cost (rtx addr, machine_mode mode, addr_space_t as ATTRIBUTE_UNUSED,
1142                      bool speed)
1143 {
1144   int cost = 0;
1145 
1146   if (GET_CODE (addr) != REG)
1147     {
1148       if (!simple_memory_operand (addr, mode))
1149           cost = 2;
1150 
1151       /* If optimizing for speed, account for the memory reference if
1152            any.  */
1153       if (speed && !CONSTANT_P (addr))
1154           cost += (mode == QImode) ? 2 : GET_MODE_SIZE (mode);
1155     }
1156   return cost;
1157 }
1158 
1159 
1160 static int
pdp11_insn_cost(rtx_insn * insn,bool speed)1161 pdp11_insn_cost (rtx_insn *insn, bool speed)
1162 {
1163   int base_cost;
1164   rtx pat, set, dest, src, src2;
1165   machine_mode mode;
1166   enum rtx_code op;
1167 
1168   if (recog_memoized (insn) < 0)
1169     return 0;
1170 
1171   /* If optimizing for size, we want the insn size.  */
1172   if (!speed)
1173     return get_attr_length (insn);
1174   else
1175     {
1176       /* Optimizing for speed.  Get the base cost of the insn, then
1177            adjust for the cost of accessing operands.  Zero means use
1178            the length as the cost even when optimizing for speed.  */
1179       base_cost = get_attr_base_cost (insn);
1180       if (base_cost <= 0)
1181           base_cost = get_attr_length (insn);
1182     }
1183   /* Look for the operands.  Often we have a PARALLEL that's either
1184      the actual operation plus a clobber, or the implicit compare plus
1185      the actual operation.  Find the actual operation.  */
1186   pat = PATTERN (insn);
1187 
1188   if (GET_CODE (pat) == PARALLEL)
1189     {
1190       set = XVECEXP (pat, 0, 0);
1191       if (GET_CODE (set) != SET || GET_CODE (XEXP (set, 1)) == COMPARE)
1192           set = XVECEXP (pat, 0, 1);
1193       if (GET_CODE (set) != SET || GET_CODE (XEXP (set, 1)) == COMPARE)
1194           return 0;
1195     }
1196   else
1197     {
1198       set = pat;
1199       if (GET_CODE (set) != SET)
1200           return 0;
1201     }
1202 
1203   /* Pick up the SET source and destination RTL.  */
1204   dest = XEXP (set, 0);
1205   src = XEXP (set, 1);
1206   mode = GET_MODE (dest);
1207 
1208   /* See if we have a move, or some arithmetic operation.  If a move,
1209      account for source and destination operand costs.  Otherwise,
1210      account for the destination and for the second operand of the
1211      operation -- the first is also destination and we don't want to
1212      double-count it.  */
1213   base_cost += pdp11_addr_cost (dest, mode, ADDR_SPACE_GENERIC, speed);
1214   op = GET_CODE (src);
1215   switch (op)
1216     {
1217     case REG:
1218     case MEM:
1219     case CONST_INT:
1220     case CONST:
1221     case LABEL_REF:
1222     case SYMBOL_REF:
1223     case CONST_DOUBLE:
1224       /* It's a move.  */
1225       if (src != const0_rtx)
1226           base_cost += pdp11_addr_cost (src, mode, ADDR_SPACE_GENERIC, speed);
1227       return base_cost;
1228     default:
1229       break;
1230     }
1231   /* There are some other cases where souce and dest are distinct.  */
1232   if (FLOAT_MODE_P (mode) &&
1233       (op == FLOAT_TRUNCATE || op == FLOAT_EXTEND || op == FIX || op == FLOAT))
1234     {
1235       src2 = XEXP (src, 0);
1236       base_cost += pdp11_addr_cost (src2, mode, ADDR_SPACE_GENERIC, speed);
1237     }
1238   /* Otherwise, pick up the second operand of the arithmetic
1239      operation, if it has two operands.  */
1240   else if (op != SUBREG && op != UNSPEC && GET_RTX_LENGTH (op) > 1)
1241     {
1242       src2 = XEXP (src, 1);
1243       base_cost += pdp11_addr_cost (src2, mode, ADDR_SPACE_GENERIC, speed);
1244     }
1245 
1246   return base_cost;
1247 }
1248 
1249 const char *
output_jump(rtx * operands,int ccnz,int length)1250 output_jump (rtx *operands, int ccnz, int length)
1251 {
1252   rtx tmpop[1];
1253   static char buf[100];
1254   const char *pos, *neg;
1255   enum rtx_code code = GET_CODE (operands[0]);
1256 
1257   if (ccnz)
1258     {
1259       /* These are the branches valid for CCNZmode, i.e., a comparison
1260            with zero where the V bit is not set to zero.  These cases
1261            occur when CC or FCC are set as a side effect of some data
1262            manipulation, such as the ADD instruction.  */
1263       switch (code)
1264           {
1265           case EQ: pos = "beq", neg = "bne"; break;
1266           case NE: pos = "bne", neg = "beq"; break;
1267           case LT: pos = "bmi", neg = "bpl"; break;
1268           case GE: pos = "bpl", neg = "bmi"; break;
1269           default: gcc_unreachable ();
1270           }
1271     }
1272   else
1273     {
1274       switch (code)
1275           {
1276           case EQ: pos = "beq", neg = "bne"; break;
1277           case NE: pos = "bne", neg = "beq"; break;
1278           case GT: pos = "bgt", neg = "ble"; break;
1279           case GTU: pos = "bhi", neg = "blos"; break;
1280           case LT: pos = "blt", neg = "bge"; break;
1281           case LTU: pos = "blo", neg = "bhis"; break;
1282           case GE: pos = "bge", neg = "blt"; break;
1283           case GEU: pos = "bhis", neg = "blo"; break;
1284           case LE: pos = "ble", neg = "bgt"; break;
1285           case LEU: pos = "blos", neg = "bhi"; break;
1286           default: gcc_unreachable ();
1287           }
1288     }
1289   switch (length)
1290     {
1291     case 2:
1292       sprintf (buf, "%s\t%%l1", pos);
1293       return buf;
1294     case 6:
1295       tmpop[0] = gen_label_rtx ();
1296       sprintf (buf, "%s\t%%l0", neg);
1297       output_asm_insn (buf, tmpop);
1298       output_asm_insn ("jmp\t%l1", operands);
1299       output_asm_label (tmpop[0]);
1300       fputs (":\n", asm_out_file);
1301       return "";
1302     default:
1303       gcc_unreachable ();
1304     }
1305 }
1306 
1307 /* Select the CC mode to be used for the side effect compare with
1308    zero, given the compare operation code in op and the compare
1309    operands in x in and y.  */
1310 machine_mode
pdp11_cc_mode(enum rtx_code op ATTRIBUTE_UNUSED,rtx x,rtx y ATTRIBUTE_UNUSED)1311 pdp11_cc_mode (enum rtx_code op ATTRIBUTE_UNUSED, rtx x, rtx y ATTRIBUTE_UNUSED)
1312 {
1313   if (FLOAT_MODE_P (GET_MODE (x)))
1314     {
1315       switch (GET_CODE (x))
1316           {
1317           case ABS:
1318           case NEG:
1319           case REG:
1320           case MEM:
1321             return CCmode;
1322           default:
1323             return CCNZmode;
1324           }
1325     }
1326   else
1327     {
1328       switch (GET_CODE (x))
1329           {
1330           case XOR:
1331           case AND:
1332           case IOR:
1333           case MULT:
1334           case NOT:
1335           case REG:
1336           case MEM:
1337             return CCmode;
1338           default:
1339             return CCNZmode;
1340           }
1341     }
1342 }
1343 
1344 
1345 int
simple_memory_operand(rtx op,machine_mode mode ATTRIBUTE_UNUSED)1346 simple_memory_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1347 {
1348   rtx addr;
1349 
1350   /* Eliminate non-memory operations */
1351   if (GET_CODE (op) != MEM)
1352     return FALSE;
1353 
1354   /* Decode the address now.  */
1355 
1356  indirection:
1357 
1358   addr = XEXP (op, 0);
1359 
1360   switch (GET_CODE (addr))
1361     {
1362     case REG:
1363       /* (R0) - no extra cost */
1364       return 1;
1365 
1366     case PRE_DEC:
1367     case POST_INC:
1368     case PRE_MODIFY:
1369     case POST_MODIFY:
1370       /* -(R0), (R0)+ - cheap! */
1371       return 1;
1372 
1373     case MEM:
1374       /* cheap - is encoded in addressing mode info!
1375 
1376            -- except for @(R0), which has to be @0(R0) !!! */
1377 
1378       if (GET_CODE (XEXP (addr, 0)) == REG)
1379           return 0;
1380 
1381       op=addr;
1382       goto indirection;
1383 
1384     case CONST_INT:
1385     case LABEL_REF:
1386     case CONST:
1387     case SYMBOL_REF:
1388       /* @#address - extra cost */
1389       return 0;
1390 
1391     case PLUS:
1392       /* X(R0) - extra cost */
1393       return 0;
1394 
1395     default:
1396       break;
1397     }
1398 
1399   return FALSE;
1400 }
1401 
1402 /* Similar to simple_memory_operand but doesn't match push/pop.  */
1403 int
no_side_effect_operand(rtx op,machine_mode mode ATTRIBUTE_UNUSED)1404 no_side_effect_operand(rtx op, machine_mode mode ATTRIBUTE_UNUSED)
1405 {
1406   rtx addr;
1407 
1408   /* Eliminate non-memory operations */
1409   if (GET_CODE (op) != MEM)
1410     return FALSE;
1411 
1412   /* Decode the address now.  */
1413 
1414  indirection:
1415 
1416   addr = XEXP (op, 0);
1417 
1418   switch (GET_CODE (addr))
1419     {
1420     case REG:
1421       /* (R0) - no extra cost */
1422       return 1;
1423 
1424     case PRE_DEC:
1425     case POST_INC:
1426     case PRE_MODIFY:
1427     case POST_MODIFY:
1428       return 0;
1429 
1430     case MEM:
1431       /* cheap - is encoded in addressing mode info!
1432 
1433            -- except for @(R0), which has to be @0(R0) !!! */
1434 
1435       if (GET_CODE (XEXP (addr, 0)) == REG)
1436           return 0;
1437 
1438       op=addr;
1439       goto indirection;
1440 
1441     case CONST_INT:
1442     case LABEL_REF:
1443     case CONST:
1444     case SYMBOL_REF:
1445       /* @#address - extra cost */
1446       return 0;
1447 
1448     case PLUS:
1449       /* X(R0) - extra cost */
1450       return 0;
1451 
1452     default:
1453       break;
1454     }
1455 
1456   return FALSE;
1457 }
1458 
1459 /* Return TRUE if op is a push or pop using the register "regno".  */
1460 bool
pushpop_regeq(rtx op,int regno)1461 pushpop_regeq (rtx op, int regno)
1462 {
1463   rtx addr;
1464 
1465   /* False if not memory reference.  */
1466   if (GET_CODE (op) != MEM)
1467     return FALSE;
1468 
1469   /* Get the address of the memory reference.  */
1470   addr = XEXP (op, 0);
1471 
1472   if (GET_CODE (addr) == MEM)
1473     addr = XEXP (addr, 0);
1474 
1475   switch (GET_CODE (addr))
1476     {
1477     case PRE_DEC:
1478     case POST_INC:
1479     case PRE_MODIFY:
1480     case POST_MODIFY:
1481       return REGNO (XEXP (addr, 0)) == (unsigned) regno;
1482     default:
1483       return FALSE;
1484     }
1485 }
1486 
1487 /* This function checks whether a real value can be encoded as
1488    a literal, i.e., addressing mode 27.  In that mode, real values
1489    are one word values, so the remaining 48 bits have to be zero.  */
1490 int
legitimate_const_double_p(rtx address)1491 legitimate_const_double_p (rtx address)
1492 {
1493   long sval[2];
1494 
1495   /* If it's too big for HOST_WIDE_INT, it's definitely to big here.  */
1496   if (GET_MODE (address) == VOIDmode)
1497     return 0;
1498   REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (address), sval);
1499 
1500   if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1501     return 1;
1502   return 0;
1503 }
1504 
1505 /* Implement TARGET_CAN_CHANGE_MODE_CLASS.  */
1506 static bool
pdp11_can_change_mode_class(machine_mode from,machine_mode to,reg_class_t rclass)1507 pdp11_can_change_mode_class (machine_mode from,
1508                                    machine_mode to,
1509                                    reg_class_t rclass)
1510 {
1511   /* Also, FPU registers contain a whole float value and the parts of
1512      it are not separately accessible.
1513 
1514      So we disallow all mode changes involving FPRs.  */
1515   if (FLOAT_MODE_P (from) != FLOAT_MODE_P (to))
1516     return false;
1517 
1518   return !reg_classes_intersect_p (FPU_REGS, rclass);
1519 }
1520 
1521 /* Implement TARGET_CXX_GUARD_TYPE */
1522 static tree
pdp11_guard_type(void)1523 pdp11_guard_type (void)
1524 {
1525   return short_integer_type_node;
1526 }
1527 
1528 /* TARGET_PREFERRED_RELOAD_CLASS
1529 
1530    Given an rtx X being reloaded into a reg required to be
1531    in class CLASS, return the class of reg to actually use.
1532    In general this is just CLASS; but on some machines
1533    in some cases it is preferable to use a more restrictive class.
1534 
1535 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1536 
1537 static reg_class_t
pdp11_preferred_reload_class(rtx x,reg_class_t rclass)1538 pdp11_preferred_reload_class (rtx x, reg_class_t rclass)
1539 {
1540   if (rclass == FPU_REGS)
1541     return LOAD_FPU_REGS;
1542   if (rclass == ALL_REGS)
1543     {
1544       if (FLOAT_MODE_P (GET_MODE (x)))
1545           return LOAD_FPU_REGS;
1546       else
1547           return GENERAL_REGS;
1548     }
1549   return rclass;
1550 }
1551 
1552 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
1553 
1554    Given an rtx X being reloaded into a reg required to be
1555    in class CLASS, return the class of reg to actually use.
1556    In general this is just CLASS; but on some machines
1557    in some cases it is preferable to use a more restrictive class.
1558 
1559 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1560 
1561 static reg_class_t
pdp11_preferred_output_reload_class(rtx x,reg_class_t rclass)1562 pdp11_preferred_output_reload_class (rtx x, reg_class_t rclass)
1563 {
1564   if (rclass == FPU_REGS)
1565     return LOAD_FPU_REGS;
1566   if (rclass == ALL_REGS)
1567     {
1568       if (FLOAT_MODE_P (GET_MODE (x)))
1569           return LOAD_FPU_REGS;
1570       else
1571           return GENERAL_REGS;
1572     }
1573   return rclass;
1574 }
1575 
1576 
1577 /* TARGET_SECONDARY_RELOAD.
1578 
1579    FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an
1580    intermediate register (AC0-AC3: LOAD_FPU_REGS).  Everything else
1581    can be loaded/stored directly.  */
1582 static reg_class_t
pdp11_secondary_reload(bool in_p ATTRIBUTE_UNUSED,rtx x,reg_class_t reload_class,machine_mode reload_mode ATTRIBUTE_UNUSED,secondary_reload_info * sri ATTRIBUTE_UNUSED)1583 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED,
1584                               rtx x,
1585                               reg_class_t reload_class,
1586                               machine_mode reload_mode ATTRIBUTE_UNUSED,
1587                               secondary_reload_info *sri ATTRIBUTE_UNUSED)
1588 {
1589   if (reload_class != NO_LOAD_FPU_REGS || GET_CODE (x) != REG ||
1590       REGNO_REG_CLASS (REGNO (x)) == LOAD_FPU_REGS)
1591     return NO_REGS;
1592 
1593   return LOAD_FPU_REGS;
1594 }
1595 
1596 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
1597 
1598    The answer is yes if we're going between general register and FPU
1599    registers.  The mode doesn't matter in making this check.  */
1600 static bool
pdp11_secondary_memory_needed(machine_mode,reg_class_t c1,reg_class_t c2)1601 pdp11_secondary_memory_needed (machine_mode, reg_class_t c1, reg_class_t c2)
1602 {
1603   int fromfloat = (c1 == LOAD_FPU_REGS || c1 == NO_LOAD_FPU_REGS ||
1604                        c1 == FPU_REGS);
1605   int tofloat = (c2 == LOAD_FPU_REGS || c2 == NO_LOAD_FPU_REGS ||
1606                      c2 == FPU_REGS);
1607 
1608   return (fromfloat != tofloat);
1609 }
1610 
1611 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
1612    that is a valid memory address for an instruction.
1613    The MODE argument is the machine mode for the MEM expression
1614    that wants to use this address.
1615 
1616 */
1617 
1618 static bool
pdp11_legitimate_address_p(machine_mode mode,rtx operand,bool strict)1619 pdp11_legitimate_address_p (machine_mode mode,
1620                                   rtx operand, bool strict)
1621 {
1622     rtx xfoob;
1623 
1624     /* accept @#address */
1625     if (CONSTANT_ADDRESS_P (operand))
1626       return true;
1627 
1628     switch (GET_CODE (operand))
1629       {
1630       case REG:
1631           /* accept (R0) */
1632           return !strict || REGNO_OK_FOR_BASE_P (REGNO (operand));
1633 
1634       case PLUS:
1635           /* accept X(R0) */
1636           return GET_CODE (XEXP (operand, 0)) == REG
1637             && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))))
1638             && CONSTANT_ADDRESS_P (XEXP (operand, 1));
1639 
1640       case PRE_DEC:
1641           /* accept -(R0) */
1642           return GET_CODE (XEXP (operand, 0)) == REG
1643             && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1644 
1645       case POST_INC:
1646           /* accept (R0)+ */
1647           return GET_CODE (XEXP (operand, 0)) == REG
1648             && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1649 
1650       case PRE_MODIFY:
1651           /* accept -(SP) -- which uses PRE_MODIFY for byte mode */
1652           return GET_CODE (XEXP (operand, 0)) == REG
1653             && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1654             && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1655             && GET_CODE (XEXP (xfoob, 0)) == REG
1656             && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1657             && CONST_INT_P (XEXP (xfoob, 1))
1658             && INTVAL (XEXP (xfoob,1)) == -2;
1659 
1660       case POST_MODIFY:
1661           /* accept (SP)+ -- which uses POST_MODIFY for byte mode */
1662           return GET_CODE (XEXP (operand, 0)) == REG
1663             && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1664             && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1665             && GET_CODE (XEXP (xfoob, 0)) == REG
1666             && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1667             && CONST_INT_P (XEXP (xfoob, 1))
1668             && INTVAL (XEXP (xfoob,1)) == 2;
1669 
1670       case MEM:
1671           /* handle another level of indirection ! */
1672           xfoob = XEXP (operand, 0);
1673 
1674           /* (MEM:xx (MEM:xx ())) is not valid for SI, DI and currently
1675              also forbidden for float, because we have to handle this
1676              in output_move_double and/or output_move_quad() - we could
1677              do it, but currently it's not worth it!!!
1678              now that DFmode cannot go into CPU register file,
1679              maybe I should allow float ...
1680              but then I have to handle memory-to-memory moves in movdf ??  */
1681           if (GET_MODE_BITSIZE(mode) > 16)
1682             return false;
1683 
1684           /* accept @address */
1685           if (CONSTANT_ADDRESS_P (xfoob))
1686             return true;
1687 
1688           switch (GET_CODE (xfoob))
1689             {
1690             case REG:
1691               /* accept @(R0) - which is @0(R0) */
1692               return !strict || REGNO_OK_FOR_BASE_P(REGNO (xfoob));
1693 
1694             case PLUS:
1695               /* accept @X(R0) */
1696               return GET_CODE (XEXP (xfoob, 0)) == REG
1697                 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))))
1698                 && CONSTANT_ADDRESS_P (XEXP (xfoob, 1));
1699 
1700             case PRE_DEC:
1701               /* accept @-(R0) */
1702               return GET_CODE (XEXP (xfoob, 0)) == REG
1703                 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1704 
1705             case POST_INC:
1706               /* accept @(R0)+ */
1707               return GET_CODE (XEXP (xfoob, 0)) == REG
1708                 && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1709 
1710             default:
1711               /* anything else is invalid */
1712               return false;
1713             }
1714 
1715       default:
1716           /* anything else is invalid */
1717           return false;
1718       }
1719 }
1720 
1721 /* Return the class number of the smallest class containing
1722    reg number REGNO.  */
1723 enum reg_class
pdp11_regno_reg_class(int regno)1724 pdp11_regno_reg_class (int regno)
1725 {
1726   if (regno == ARG_POINTER_REGNUM)
1727     return NOTSP_REG;
1728   else if (regno == CC_REGNUM || regno == FCC_REGNUM)
1729     return CC_REGS;
1730   else if (regno > AC3_REGNUM)
1731     return NO_LOAD_FPU_REGS;
1732   else if (regno >= AC0_REGNUM)
1733     return LOAD_FPU_REGS;
1734   else if (regno == 6)
1735     return NOTR0_REG;
1736   else if (regno < 6)
1737     return NOTSP_REG;
1738   else
1739     return GENERAL_REGS;
1740 }
1741 
1742 /* Return the regnums of the CC registers.  */
1743 bool
pdp11_fixed_cc_regs(unsigned int * p1,unsigned int * p2)1744 pdp11_fixed_cc_regs (unsigned int *p1, unsigned int *p2)
1745 {
1746   *p1 = CC_REGNUM;
1747   *p2 = FCC_REGNUM;
1748   return true;
1749 }
1750 
1751 static int
pdp11_reg_save_size(void)1752 pdp11_reg_save_size (void)
1753 {
1754   int offset = 0, regno;
1755 
1756   for (regno = 0; regno <= PC_REGNUM; regno++)
1757     if (pdp11_saved_regno (regno))
1758       offset += 2;
1759   for (regno = AC0_REGNUM; regno <= AC5_REGNUM; regno++)
1760     if (pdp11_saved_regno (regno))
1761       offset += 8;
1762 
1763   return offset;
1764 }
1765 
1766 /* Return the offset between two registers, one to be eliminated, and the other
1767    its replacement, at the start of a routine.  */
1768 
1769 int
pdp11_initial_elimination_offset(int from,int to)1770 pdp11_initial_elimination_offset (int from, int to)
1771 {
1772   /* Get the size of the register save area.  */
1773 
1774   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1775     return get_frame_size ();
1776   else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
1777     return pdp11_reg_save_size () + 2;
1778   else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1779     return pdp11_reg_save_size () + 2 + get_frame_size ();
1780   else
1781     gcc_assert (0);
1782 }
1783 
1784 /* A copy of output_addr_const modified for pdp11 expression syntax.
1785    output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1786    use, and for debugging output, which we don't support with this port either.
1787    So this copy should get called whenever needed.
1788 */
1789 void
output_addr_const_pdp11(FILE * file,rtx x)1790 output_addr_const_pdp11 (FILE *file, rtx x)
1791 {
1792   char buf[256];
1793   int i;
1794 
1795  restart:
1796   switch (GET_CODE (x))
1797     {
1798     case PC:
1799       gcc_assert (flag_pic);
1800       putc ('.', file);
1801       break;
1802 
1803     case SYMBOL_REF:
1804       assemble_name (file, XSTR (x, 0));
1805       break;
1806 
1807     case LABEL_REF:
1808       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1809       assemble_name (file, buf);
1810       break;
1811 
1812     case CODE_LABEL:
1813       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1814       assemble_name (file, buf);
1815       break;
1816 
1817     case CONST_INT:
1818       i = INTVAL (x);
1819       if (i < 0)
1820           {
1821             i = -i;
1822             fprintf (file, "-");
1823           }
1824       if (TARGET_DEC_ASM)
1825           fprintf (file, "%o", i & 0xffff);
1826       else
1827           fprintf (file, "%#o", i & 0xffff);
1828       break;
1829 
1830     case CONST:
1831       output_addr_const_pdp11 (file, XEXP (x, 0));
1832       break;
1833 
1834     case PLUS:
1835       /* Some assemblers need integer constants to appear last (e.g. masm).  */
1836       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1837           {
1838             output_addr_const_pdp11 (file, XEXP (x, 1));
1839             if (INTVAL (XEXP (x, 0)) >= 0)
1840               fprintf (file, "+");
1841             output_addr_const_pdp11 (file, XEXP (x, 0));
1842           }
1843       else
1844           {
1845             output_addr_const_pdp11 (file, XEXP (x, 0));
1846             if (INTVAL (XEXP (x, 1)) >= 0)
1847               fprintf (file, "+");
1848             output_addr_const_pdp11 (file, XEXP (x, 1));
1849           }
1850       break;
1851 
1852     case MINUS:
1853       /* Avoid outputting things like x-x or x+5-x,
1854            since some assemblers can't handle that.  */
1855       x = simplify_subtraction (x);
1856       if (GET_CODE (x) != MINUS)
1857           goto restart;
1858 
1859       output_addr_const_pdp11 (file, XEXP (x, 0));
1860       if (GET_CODE (XEXP (x, 1)) != CONST_INT
1861             || INTVAL (XEXP (x, 1)) >= 0)
1862           fprintf (file, "-");
1863       output_addr_const_pdp11 (file, XEXP (x, 1));
1864       break;
1865 
1866     case ZERO_EXTEND:
1867     case SIGN_EXTEND:
1868       output_addr_const_pdp11 (file, XEXP (x, 0));
1869       break;
1870 
1871     default:
1872       output_operand_lossage ("invalid expression as operand");
1873     }
1874 }
1875 
1876 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
1877 
1878 static bool
pdp11_return_in_memory(const_tree type,const_tree fntype ATTRIBUTE_UNUSED)1879 pdp11_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1880 {
1881   /* Integers 32 bits and under, and scalar floats (if FPU), are returned
1882      in registers.  The rest go into memory.  */
1883   return (TYPE_MODE (type) == DImode
1884             || (FLOAT_MODE_P (TYPE_MODE (type)) && ! TARGET_AC0)
1885             || TREE_CODE (type) == VECTOR_TYPE
1886             || COMPLEX_MODE_P (TYPE_MODE (type)));
1887 }
1888 
1889 /* Worker function for TARGET_FUNCTION_VALUE.
1890 
1891    On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! )  */
1892 
1893 static rtx
pdp11_function_value(const_tree valtype,const_tree fntype_or_decl ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)1894 pdp11_function_value (const_tree valtype,
1895                           const_tree fntype_or_decl ATTRIBUTE_UNUSED,
1896                           bool outgoing ATTRIBUTE_UNUSED)
1897 {
1898   return gen_rtx_REG (TYPE_MODE (valtype),
1899                           BASE_RETURN_VALUE_REG(TYPE_MODE(valtype)));
1900 }
1901 
1902 /* Worker function for TARGET_LIBCALL_VALUE.  */
1903 
1904 static rtx
pdp11_libcall_value(machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)1905 pdp11_libcall_value (machine_mode mode,
1906                      const_rtx fun ATTRIBUTE_UNUSED)
1907 {
1908   return  gen_rtx_REG (mode, BASE_RETURN_VALUE_REG(mode));
1909 }
1910 
1911 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1912 
1913    On the pdp, the first "output" reg is the only register thus used.
1914 
1915    maybe ac0 ? - as option someday!  */
1916 
1917 static bool
pdp11_function_value_regno_p(const unsigned int regno)1918 pdp11_function_value_regno_p (const unsigned int regno)
1919 {
1920   return (regno == RETVAL_REGNUM) || (TARGET_AC0 && (regno == AC0_REGNUM));
1921 }
1922 
1923 /* Used for O constraint, matches if shift count is "small".  */
1924 bool
pdp11_small_shift(int n)1925 pdp11_small_shift (int n)
1926 {
1927   return (unsigned) n < 4;
1928 }
1929 
1930 /* Expand a shift insn.  Returns true if the expansion was done,
1931    false if it needs to be handled by the caller.  */
1932 bool
pdp11_expand_shift(rtx * operands,rtx (* shift_sc)(rtx,rtx,rtx),rtx (* shift_base)(rtx,rtx,rtx))1933 pdp11_expand_shift (rtx *operands, rtx (*shift_sc) (rtx, rtx, rtx),
1934                         rtx (*shift_base) (rtx, rtx, rtx))
1935 {
1936   rtx r, test;
1937   rtx_code_label *lb;
1938 
1939   if (CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
1940     emit_insn ((*shift_sc) (operands[0], operands[1], operands[2]));
1941   else if (TARGET_40_PLUS)
1942     return false;
1943   else
1944     {
1945       lb = gen_label_rtx ();
1946       r = gen_reg_rtx (HImode);
1947       emit_move_insn (operands[0], operands[1]);
1948       emit_move_insn (r, operands[2]);
1949       if (!CONST_INT_P (operands[2]))
1950           {
1951             test = gen_rtx_LE (HImode, r, const0_rtx);
1952             emit_jump_insn (gen_cbranchhi4 (test, r, const0_rtx, lb));
1953           }
1954       /* It would be nice to expand the loop here, but that's not
1955            possible because shifts may be generated by the loop unroll
1956            optimizer and it doesn't appreciate flow changes happening
1957            while it's doing things.  */
1958       emit_insn ((*shift_base) (operands[0], operands[1], r));
1959       if (!CONST_INT_P (operands[2]))
1960           {
1961             emit_label (lb);
1962 
1963             /* Allow REG_NOTES to be set on last insn (labels don't have enough
1964                fields, and can't be used for REG_NOTES anyway).  */
1965             emit_use (stack_pointer_rtx);
1966           }
1967     }
1968   return true;
1969 }
1970 
1971 /* Emit the instructions needed to produce a shift by a small constant
1972    amount (unrolled), or a shift made from a loop for the base machine
1973    case.  */
1974 const char *
pdp11_assemble_shift(rtx * operands,machine_mode m,int code)1975 pdp11_assemble_shift (rtx *operands, machine_mode m, int code)
1976 {
1977   int i, n;
1978   rtx inops[2];
1979   rtx exops[2][2];
1980   rtx lb[1];
1981   pdp11_action action[2];
1982   const bool small = CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2]));
1983 
1984   gcc_assert (small || !TARGET_40_PLUS);
1985 
1986   if (m == E_SImode)
1987     {
1988       inops[0] = operands[0];
1989       pdp11_expand_operands (inops, exops, 1, 2, action, either);
1990     }
1991 
1992   if (!small)
1993     {
1994       /* Loop case, generate the top of loop label.  */
1995       lb[0] = gen_label_rtx ();
1996       output_asm_label (lb[0]);
1997       fputs (":\n", asm_out_file);
1998       n = 1;
1999     }
2000   else
2001     n = INTVAL (operands[2]);
2002   if (code == LSHIFTRT)
2003     {
2004       output_asm_insn ("clc", NULL);
2005       switch (m)
2006           {
2007           case E_QImode:
2008             output_asm_insn ("rorb\t%0", operands);
2009             break;
2010           case E_HImode:
2011             output_asm_insn ("ror\t%0", operands);
2012             break;
2013           case E_SImode:
2014             output_asm_insn ("ror\t%0", exops[0]);
2015             output_asm_insn ("ror\t%0", exops[1]);
2016             break;
2017           default:
2018             gcc_unreachable ();
2019           }
2020       n--;
2021     }
2022   for (i = 0; i < n; i++)
2023     {
2024       switch (code)
2025           {
2026           case LSHIFTRT:
2027           case ASHIFTRT:
2028             switch (m)
2029               {
2030               case E_QImode:
2031                 output_asm_insn ("asrb\t%0", operands);
2032                 break;
2033               case E_HImode:
2034                 output_asm_insn ("asr\t%0", operands);
2035                 break;
2036               case E_SImode:
2037                 output_asm_insn ("asr\t%0", exops[0]);
2038                 output_asm_insn ("ror\t%0", exops[1]);
2039                 break;
2040               default:
2041                 gcc_unreachable ();
2042               }
2043             break;
2044           case ASHIFT:
2045             switch (m)
2046               {
2047               case E_QImode:
2048                 output_asm_insn ("aslb\t%0", operands);
2049                 break;
2050               case E_HImode:
2051                 output_asm_insn ("asl\t%0", operands);
2052                 break;
2053               case E_SImode:
2054                 output_asm_insn ("asl\t%0", exops[1]);
2055                 output_asm_insn ("rol\t%0", exops[0]);
2056                 break;
2057               default:
2058                 gcc_unreachable ();
2059               }
2060             break;
2061           }
2062     }
2063   if (!small)
2064     {
2065       /* Loop case, emit the count-down and branch if not done.  */
2066       output_asm_insn ("dec\t%2", operands);
2067       output_asm_insn ("bne\t%l0", lb);
2068     }
2069   return "";
2070 }
2071 
2072 /* Figure out the length of the instructions that will be produced for
2073    the given operands by pdp11_assemble_shift above.  */
2074 int
pdp11_shift_length(rtx * operands,machine_mode m,int code,bool simple_operand_p)2075 pdp11_shift_length (rtx *operands, machine_mode m, int code, bool simple_operand_p)
2076 {
2077   int shift_size;
2078 
2079   /* Shift by 1 is 2 bytes if simple operand, 4 bytes if 2-word addressing mode.  */
2080   shift_size = simple_operand_p ? 2 : 4;
2081 
2082   /* In SImode, two shifts are needed per data item.  */
2083   if (m == E_SImode)
2084     shift_size *= 2;
2085 
2086   /* If shifting by a small constant, the loop is unrolled by the
2087      shift count.  Otherwise, account for the size of the decrement
2088      and branch.  */
2089   if (CONST_INT_P (operands[2]) && pdp11_small_shift (INTVAL (operands[2])))
2090     shift_size *= INTVAL (operands[2]);
2091   else
2092     shift_size += 4;
2093 
2094   /* Logical right shift takes one more instruction (CLC).  */
2095   if (code == LSHIFTRT)
2096     shift_size += 2;
2097 
2098   return shift_size;
2099 }
2100 
2101 /* Return the length of 2 or 4 word integer compares.  */
2102 int
pdp11_cmp_length(rtx * operands,int words)2103 pdp11_cmp_length (rtx *operands, int words)
2104 {
2105   rtx inops[2];
2106   rtx exops[4][2];
2107   int i, len = 0;
2108 
2109   if (!reload_completed)
2110     return 2;
2111 
2112   inops[0] = operands[0];
2113   inops[1] = operands[1];
2114 
2115   pdp11_expand_operands (inops, exops, 2, words, NULL, big);
2116 
2117   for (i = 0; i < words; i++)
2118     {
2119       len += 4;    /* cmp instruction word and branch that follows.  */
2120       if (!REG_P (exops[i][0]) &&
2121             !simple_memory_operand (exops[i][0], HImode))
2122           len += 2;  /* first operand extra word.  */
2123       if (!REG_P (exops[i][1]) &&
2124             !simple_memory_operand (exops[i][1], HImode) &&
2125             !(CONST_INT_P (exops[i][1]) && INTVAL (exops[i][1]) == 0))
2126           len += 2;  /* second operand extra word.  */
2127     }
2128 
2129   /* Deduct one word because there is no branch at the end.  */
2130   return len - 2;
2131 }
2132 
2133 /* Prepend to CLOBBERS hard registers that are automatically clobbered
2134    for an asm We do this for CC_REGNUM and FCC_REGNUM (on FPU target)
2135    to maintain source compatibility with the original cc0-based
2136    compiler.  */
2137 
2138 static rtx_insn *
pdp11_md_asm_adjust(vec<rtx> &,vec<rtx> &,vec<machine_mode> &,vec<const char * > &,vec<rtx> & clobbers,HARD_REG_SET & clobbered_regs,location_t)2139 pdp11_md_asm_adjust (vec<rtx> & /*outputs*/, vec<rtx> & /*inputs*/,
2140                          vec<machine_mode> & /*input_modes*/,
2141                          vec<const char *> & /*constraints*/, vec<rtx> &clobbers,
2142                          HARD_REG_SET &clobbered_regs, location_t /*loc*/)
2143 {
2144   clobbers.safe_push (gen_rtx_REG (CCmode, CC_REGNUM));
2145   SET_HARD_REG_BIT (clobbered_regs, CC_REGNUM);
2146   if (TARGET_FPU)
2147     {
2148       clobbers.safe_push (gen_rtx_REG (CCmode, FCC_REGNUM));
2149       SET_HARD_REG_BIT (clobbered_regs, FCC_REGNUM);
2150     }
2151   return NULL;
2152 }
2153 
2154 /* Worker function for TARGET_TRAMPOLINE_INIT.
2155 
2156    trampoline - how should i do it in separate i+d ?
2157    have some allocate_trampoline magic???
2158 
2159    the following should work for shared I/D:
2160 
2161    MOV    #STATIC, $4         01270Y    0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
2162    JMP    @#FUNCTION          000137  0x0000 <- FUNCTION
2163 */
2164 static void
pdp11_trampoline_init(rtx m_tramp,tree fndecl,rtx chain_value)2165 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
2166 {
2167   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2168   rtx mem;
2169 
2170   gcc_assert (!TARGET_SPLIT);
2171 
2172   mem = adjust_address (m_tramp, HImode, 0);
2173   emit_move_insn (mem, GEN_INT (012700+STATIC_CHAIN_REGNUM));
2174   mem = adjust_address (m_tramp, HImode, 2);
2175   emit_move_insn (mem, chain_value);
2176   mem = adjust_address (m_tramp, HImode, 4);
2177   emit_move_insn (mem, GEN_INT (000137));
2178   emit_move_insn (mem, fnaddr);
2179 }
2180 
2181 /* Worker function for TARGET_FUNCTION_ARG.  */
2182 
2183 static rtx
pdp11_function_arg(cumulative_args_t,const function_arg_info &)2184 pdp11_function_arg (cumulative_args_t, const function_arg_info &)
2185 {
2186   return NULL_RTX;
2187 }
2188 
2189 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
2190 
2191    Update the data in CUM to advance over argument ARG.  */
2192 
2193 static void
pdp11_function_arg_advance(cumulative_args_t cum_v,const function_arg_info & arg)2194 pdp11_function_arg_advance (cumulative_args_t cum_v,
2195                                   const function_arg_info &arg)
2196 {
2197   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2198 
2199   *cum += arg.promoted_size_in_bytes ();
2200 }
2201 
2202 /* Make sure everything's fine if we *don't* have an FPU.
2203    This assumes that putting a register in fixed_regs will keep the
2204    compiler's mitts completely off it.  We don't bother to zero it out
2205    of register classes.  Also fix incompatible register naming with
2206    the UNIX assembler.  */
2207 
2208 static void
pdp11_conditional_register_usage(void)2209 pdp11_conditional_register_usage (void)
2210 {
2211   int i;
2212   HARD_REG_SET x;
2213   if (!TARGET_FPU)
2214     {
2215       x = reg_class_contents[FPU_REGS];
2216       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ )
2217        if (TEST_HARD_REG_BIT (x, i))
2218           fixed_regs[i] = call_used_regs[i] = 1;
2219     }
2220 
2221   if (TARGET_AC0)
2222       call_used_regs[AC0_REGNUM] = 1;
2223   if (TARGET_UNIX_ASM)
2224     {
2225       /* Change names of FPU registers for the UNIX assembler.  */
2226       reg_names[8] = "fr0";
2227       reg_names[9] = "fr1";
2228       reg_names[10] = "fr2";
2229       reg_names[11] = "fr3";
2230       reg_names[12] = "fr4";
2231       reg_names[13] = "fr5";
2232     }
2233 }
2234 
2235 static section *
pdp11_function_section(tree decl ATTRIBUTE_UNUSED,enum node_frequency freq ATTRIBUTE_UNUSED,bool startup ATTRIBUTE_UNUSED,bool exit ATTRIBUTE_UNUSED)2236 pdp11_function_section (tree decl ATTRIBUTE_UNUSED,
2237                               enum node_frequency freq ATTRIBUTE_UNUSED,
2238                               bool startup ATTRIBUTE_UNUSED,
2239                               bool exit ATTRIBUTE_UNUSED)
2240 {
2241   return NULL;
2242 }
2243 
2244 /* Support #ident for DEC assembler, but don't process the
2245    auto-generated ident string that names the compiler (since its
2246    syntax is not correct for DEC .ident).  */
pdp11_output_ident(const char * ident)2247 static void pdp11_output_ident (const char *ident)
2248 {
2249   if (TARGET_DEC_ASM)
2250     {
2251       if (!startswith (ident, "GCC:"))
2252           fprintf (asm_out_file, "\t.ident\t\"%s\"\n", ident);
2253     }
2254 
2255 }
2256 
2257 /* This emits a (user) label, which gets a "_" prefix except for DEC
2258    assembler output.  */
2259 void
pdp11_output_labelref(FILE * file,const char * name)2260 pdp11_output_labelref (FILE *file, const char *name)
2261 {
2262   if (!TARGET_DEC_ASM)
2263     fputs (USER_LABEL_PREFIX, file);
2264   fputs (name, file);
2265 }
2266 
2267 /* This equates name with value.  */
2268 void
pdp11_output_def(FILE * file,const char * label1,const char * label2)2269 pdp11_output_def (FILE *file, const char *label1, const char *label2)
2270 {
2271   if (TARGET_DEC_ASM)
2272     {
2273       assemble_name (file, label1);
2274       putc ('=', file);
2275       assemble_name (file, label2);
2276     }
2277   else
2278     {
2279       fputs ("\t.set\t", file);
2280       assemble_name (file, label1);
2281       putc (',', file);
2282       assemble_name (file, label2);
2283     }
2284   putc ('\n', file);
2285 }
2286 
2287 void
pdp11_output_addr_vec_elt(FILE * file,int value)2288 pdp11_output_addr_vec_elt (FILE *file, int value)
2289 {
2290   char buf[256];
2291 
2292   pdp11_gen_int_label (buf, "L", value);
2293   if (!TARGET_UNIX_ASM)
2294     fprintf (file, "\t.word");
2295   fprintf (file, "\t%s\n", buf + 1);
2296 }
2297 
2298 /* This overrides some target hooks that are initializer elements so
2299    they can't be variables in the #define.  */
2300 static void
pdp11_option_override(void)2301 pdp11_option_override (void)
2302 {
2303   if (TARGET_DEC_ASM)
2304     {
2305       targetm.asm_out.open_paren  = "<";
2306       targetm.asm_out.close_paren = ">";
2307     }
2308 }
2309 
2310 static void
pdp11_asm_named_section(const char * name,unsigned int flags,tree decl ATTRIBUTE_UNUSED)2311 pdp11_asm_named_section (const char *name, unsigned int flags,
2312                                tree decl ATTRIBUTE_UNUSED)
2313 {
2314   const char *rwro = (flags & SECTION_WRITE) ? "rw" : "ro";
2315   const char *insdat = (flags & SECTION_CODE) ? "i" : "d";
2316 
2317   gcc_assert (TARGET_DEC_ASM);
2318   fprintf (asm_out_file, "\t.psect\t%s,con,%s,%s\n", name, insdat, rwro);
2319 }
2320 
2321 static void
pdp11_asm_init_sections(void)2322 pdp11_asm_init_sections (void)
2323 {
2324   if (TARGET_DEC_ASM)
2325     {
2326       bss_section = data_section;
2327     }
2328   else if (TARGET_GNU_ASM)
2329     {
2330       bss_section = get_unnamed_section (SECTION_WRITE | SECTION_BSS,
2331                                                    output_section_asm_op,
2332                                                    ".bss");
2333     }
2334 }
2335 
2336 static void
pdp11_file_start(void)2337 pdp11_file_start (void)
2338 {
2339   default_file_start ();
2340 
2341   if (TARGET_DEC_ASM)
2342     fprintf (asm_out_file, "\t.enabl\tlsb,reg\n\n");
2343 }
2344 
2345 static void
pdp11_file_end(void)2346 pdp11_file_end (void)
2347 {
2348   if (TARGET_DEC_ASM)
2349     fprintf (asm_out_file, "\t.end\n");
2350 }
2351 
2352 /* Implement TARGET_LEGITIMATE_CONSTANT_P.  */
2353 
2354 static bool
pdp11_legitimate_constant_p(machine_mode mode ATTRIBUTE_UNUSED,rtx x)2355 pdp11_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2356 {
2357   return GET_CODE (x) != CONST_DOUBLE || legitimate_const_double_p (x);
2358 }
2359 
2360 /* Implement TARGET_SCALAR_MODE_SUPPORTED_P.  */
2361 
2362 static bool
pdp11_scalar_mode_supported_p(scalar_mode mode)2363 pdp11_scalar_mode_supported_p (scalar_mode mode)
2364 {
2365   /* Support SFmode even with -mfloat64.  */
2366   if (mode == SFmode)
2367     return true;
2368   return default_scalar_mode_supported_p (mode);
2369 }
2370 
2371 /* Implement TARGET_HARD_REGNO_NREGS.  */
2372 
2373 static unsigned int
pdp11_hard_regno_nregs(unsigned int regno,machine_mode mode)2374 pdp11_hard_regno_nregs (unsigned int regno, machine_mode mode)
2375 {
2376   if (regno <= PC_REGNUM)
2377     return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
2378   return 1;
2379 }
2380 
2381 /* Implement TARGET_HARD_REGNO_MODE_OK.  On the pdp, the cpu registers
2382    can hold any mode other than float (because otherwise we may end up
2383    being asked to move from CPU to FPU register, which isn't a valid
2384    operation on the PDP11).  For CPU registers, check alignment.
2385 
2386    FPU accepts SF and DF but actually holds a DF - simplifies life!  */
2387 
2388 static bool
pdp11_hard_regno_mode_ok(unsigned int regno,machine_mode mode)2389 pdp11_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2390 {
2391   if (regno <= PC_REGNUM)
2392     return (GET_MODE_BITSIZE (mode) <= 16
2393               || (GET_MODE_BITSIZE (mode) >= 32
2394                     && !(regno & 1)
2395                     && !FLOAT_MODE_P (mode)));
2396 
2397   return FLOAT_MODE_P (mode);
2398 }
2399 
2400 /* Implement TARGET_MODES_TIEABLE_P.  */
2401 
2402 static bool
pdp11_modes_tieable_p(machine_mode mode1,machine_mode mode2)2403 pdp11_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2404 {
2405   return mode1 == HImode && mode2 == QImode;
2406 }
2407 
2408 /* Implement PUSH_ROUNDING.  On the pdp11, the stack is on an even
2409    boundary.  */
2410 
2411 poly_int64
pdp11_push_rounding(poly_int64 bytes)2412 pdp11_push_rounding (poly_int64 bytes)
2413 {
2414   return (bytes + 1) & ~1;
2415 }
2416 
2417 struct gcc_target targetm = TARGET_INITIALIZER;
2418