1 /* Subroutines for gcc2 for pdp11.
2    Copyright (C) 1994-2014 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 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "insn-config.h"
29 #include "conditions.h"
30 #include "function.h"
31 #include "output.h"
32 #include "insn-attr.h"
33 #include "flags.h"
34 #include "recog.h"
35 #include "tree.h"
36 #include "stor-layout.h"
37 #include "varasm.h"
38 #include "calls.h"
39 #include "expr.h"
40 #include "diagnostic-core.h"
41 #include "tm_p.h"
42 #include "target.h"
43 #include "target-def.h"
44 #include "df.h"
45 #include "opts.h"
46 #include "dbxout.h"
47 
48 /* this is the current value returned by the macro FIRST_PARM_OFFSET
49    defined in tm.h */
50 int current_first_parm_offset;
51 
52 /* Routines to encode/decode pdp11 floats */
53 static void encode_pdp11_f (const struct real_format *fmt,
54 			    long *, const REAL_VALUE_TYPE *);
55 static void decode_pdp11_f (const struct real_format *,
56 			    REAL_VALUE_TYPE *, const long *);
57 static void encode_pdp11_d (const struct real_format *fmt,
58 			    long *, const REAL_VALUE_TYPE *);
59 static void decode_pdp11_d (const struct real_format *,
60 			    REAL_VALUE_TYPE *, const long *);
61 
62 /* These two are taken from the corresponding vax descriptors
63    in real.c, changing only the encode/decode routine pointers.  */
64 const struct real_format pdp11_f_format =
65   {
66     encode_pdp11_f,
67     decode_pdp11_f,
68     2,
69     24,
70     24,
71     -127,
72     127,
73     15,
74     15,
75     false,
76     false,
77     false,
78     false,
79     false,
80     false,
81     false,
82     false
83   };
84 
85 const struct real_format pdp11_d_format =
86   {
87     encode_pdp11_d,
88     decode_pdp11_d,
89     2,
90     56,
91     56,
92     -127,
93     127,
94     15,
95     15,
96     false,
97     false,
98     false,
99     false,
100     false,
101     false,
102     false,
103     false
104   };
105 
106 static void
encode_pdp11_f(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)107 encode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
108 		const REAL_VALUE_TYPE *r)
109 {
110   (*vax_f_format.encode) (fmt, buf, r);
111   buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
112 }
113 
114 static void
decode_pdp11_f(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)115 decode_pdp11_f (const struct real_format *fmt ATTRIBUTE_UNUSED,
116 		REAL_VALUE_TYPE *r, const long *buf)
117 {
118   long tbuf;
119   tbuf = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
120   (*vax_f_format.decode) (fmt, r, &tbuf);
121 }
122 
123 static void
encode_pdp11_d(const struct real_format * fmt ATTRIBUTE_UNUSED,long * buf,const REAL_VALUE_TYPE * r)124 encode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED, long *buf,
125 		const REAL_VALUE_TYPE *r)
126 {
127   (*vax_d_format.encode) (fmt, buf, r);
128   buf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
129   buf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
130 }
131 
132 static void
decode_pdp11_d(const struct real_format * fmt ATTRIBUTE_UNUSED,REAL_VALUE_TYPE * r,const long * buf)133 decode_pdp11_d (const struct real_format *fmt ATTRIBUTE_UNUSED,
134 		REAL_VALUE_TYPE *r, const long *buf)
135 {
136   long tbuf[2];
137   tbuf[0] = ((buf[0] >> 16) & 0xffff) | ((buf[0] & 0xffff) << 16);
138   tbuf[1] = ((buf[1] >> 16) & 0xffff) | ((buf[1] & 0xffff) << 16);
139   (*vax_d_format.decode) (fmt, r, tbuf);
140 }
141 
142 /* This is where the condition code register lives.  */
143 /* rtx cc0_reg_rtx; - no longer needed? */
144 
145 static const char *singlemove_string (rtx *);
146 static bool pdp11_assemble_integer (rtx, unsigned int, int);
147 static bool pdp11_rtx_costs (rtx, int, int, int, int *, bool);
148 static bool pdp11_return_in_memory (const_tree, const_tree);
149 static rtx pdp11_function_value (const_tree, const_tree, bool);
150 static rtx pdp11_libcall_value (enum machine_mode, const_rtx);
151 static bool pdp11_function_value_regno_p (const unsigned int);
152 static void pdp11_trampoline_init (rtx, tree, rtx);
153 static rtx pdp11_function_arg (cumulative_args_t, enum machine_mode,
154 			       const_tree, bool);
155 static void pdp11_function_arg_advance (cumulative_args_t,
156 					enum machine_mode, const_tree, bool);
157 static void pdp11_conditional_register_usage (void);
158 static bool pdp11_legitimate_constant_p (enum machine_mode, rtx);
159 
160 /* Initialize the GCC target structure.  */
161 #undef TARGET_ASM_BYTE_OP
162 #define TARGET_ASM_BYTE_OP NULL
163 #undef TARGET_ASM_ALIGNED_HI_OP
164 #define TARGET_ASM_ALIGNED_HI_OP NULL
165 #undef TARGET_ASM_ALIGNED_SI_OP
166 #define TARGET_ASM_ALIGNED_SI_OP NULL
167 #undef TARGET_ASM_INTEGER
168 #define TARGET_ASM_INTEGER pdp11_assemble_integer
169 
170 #undef TARGET_ASM_OPEN_PAREN
171 #define TARGET_ASM_OPEN_PAREN "["
172 #undef TARGET_ASM_CLOSE_PAREN
173 #define TARGET_ASM_CLOSE_PAREN "]"
174 
175 #undef TARGET_RTX_COSTS
176 #define TARGET_RTX_COSTS pdp11_rtx_costs
177 
178 #undef TARGET_FUNCTION_ARG
179 #define TARGET_FUNCTION_ARG pdp11_function_arg
180 #undef TARGET_FUNCTION_ARG_ADVANCE
181 #define TARGET_FUNCTION_ARG_ADVANCE pdp11_function_arg_advance
182 
183 #undef TARGET_RETURN_IN_MEMORY
184 #define TARGET_RETURN_IN_MEMORY pdp11_return_in_memory
185 
186 #undef TARGET_FUNCTION_VALUE
187 #define TARGET_FUNCTION_VALUE pdp11_function_value
188 #undef TARGET_LIBCALL_VALUE
189 #define TARGET_LIBCALL_VALUE pdp11_libcall_value
190 #undef TARGET_FUNCTION_VALUE_REGNO_P
191 #define TARGET_FUNCTION_VALUE_REGNO_P pdp11_function_value_regno_p
192 
193 #undef TARGET_TRAMPOLINE_INIT
194 #define TARGET_TRAMPOLINE_INIT pdp11_trampoline_init
195 
196 #undef  TARGET_SECONDARY_RELOAD
197 #define TARGET_SECONDARY_RELOAD pdp11_secondary_reload
198 
199 #undef  TARGET_REGISTER_MOVE_COST
200 #define TARGET_REGISTER_MOVE_COST pdp11_register_move_cost
201 
202 #undef  TARGET_PREFERRED_RELOAD_CLASS
203 #define TARGET_PREFERRED_RELOAD_CLASS pdp11_preferred_reload_class
204 
205 #undef  TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
206 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS pdp11_preferred_output_reload_class
207 
208 #undef  TARGET_LEGITIMATE_ADDRESS_P
209 #define TARGET_LEGITIMATE_ADDRESS_P pdp11_legitimate_address_p
210 
211 #undef  TARGET_CONDITIONAL_REGISTER_USAGE
212 #define TARGET_CONDITIONAL_REGISTER_USAGE pdp11_conditional_register_usage
213 
214 #undef  TARGET_ASM_FUNCTION_SECTION
215 #define TARGET_ASM_FUNCTION_SECTION pdp11_function_section
216 
217 #undef  TARGET_PRINT_OPERAND
218 #define TARGET_PRINT_OPERAND pdp11_asm_print_operand
219 
220 #undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
221 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P pdp11_asm_print_operand_punct_valid_p
222 
223 #undef  TARGET_LEGITIMATE_CONSTANT_P
224 #define TARGET_LEGITIMATE_CONSTANT_P pdp11_legitimate_constant_p
225 
226 /* A helper function to determine if REGNO should be saved in the
227    current function's stack frame.  */
228 
229 static inline bool
pdp11_saved_regno(unsigned regno)230 pdp11_saved_regno (unsigned regno)
231 {
232   return !call_used_regs[regno] && df_regs_ever_live_p (regno);
233 }
234 
235 /* Expand the function prologue.  */
236 
237 void
pdp11_expand_prologue(void)238 pdp11_expand_prologue (void)
239 {
240   HOST_WIDE_INT fsize = get_frame_size ();
241   unsigned regno;
242   rtx x, via_ac = NULL;
243 
244   /* If we are outputting code for main, the switch FPU to the
245      right mode if TARGET_FPU.  */
246   if (MAIN_NAME_P (DECL_NAME (current_function_decl)) && TARGET_FPU)
247     {
248       emit_insn (gen_setd ());
249       emit_insn (gen_seti ());
250     }
251 
252   if (frame_pointer_needed)
253     {
254       x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
255       x = gen_frame_mem (Pmode, x);
256       emit_move_insn (x, hard_frame_pointer_rtx);
257 
258       emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
259     }
260 
261   /* Make frame.  */
262   if (fsize)
263     {
264       emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
265 			     GEN_INT (-fsize)));
266 
267       /* Prevent frame references via the frame pointer from being
268 	 scheduled before the frame is allocated.  */
269       if (frame_pointer_needed)
270 	emit_insn (gen_blockage ());
271     }
272 
273   /* Save CPU registers.  */
274   for (regno = R0_REGNUM; regno <= PC_REGNUM; regno++)
275     if (pdp11_saved_regno (regno)
276 	&& (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
277       {
278 	x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
279 	x = gen_frame_mem (Pmode, x);
280 	emit_move_insn (x, gen_rtx_REG (Pmode, regno));
281       }
282 
283   /* Save FPU registers.  */
284   for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
285     if (pdp11_saved_regno (regno))
286       {
287 	x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
288 	x = gen_frame_mem (DFmode, x);
289 	via_ac = gen_rtx_REG (DFmode, regno);
290 	emit_move_insn (x, via_ac);
291       }
292 
293   /* ??? Maybe make ac4, ac5 call used regs?? */
294   for (regno = AC4_REGNUM; regno <= AC5_REGNUM; regno++)
295     if (pdp11_saved_regno (regno))
296       {
297 	gcc_assert (via_ac != NULL);
298 	emit_move_insn (via_ac, gen_rtx_REG (DFmode, regno));
299 
300 	x = gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx);
301 	x = gen_frame_mem (DFmode, x);
302 	emit_move_insn (x, via_ac);
303       }
304 }
305 
306 /* The function epilogue should not depend on the current stack pointer!
307    It should use the frame pointer only.  This is mandatory because
308    of alloca; we also take advantage of it to omit stack adjustments
309    before returning.  */
310 
311 /* Maybe we can make leaf functions faster by switching to the
312    second register file - this way we don't have to save regs!
313    leaf functions are ~ 50% of all functions (dynamically!)
314 
315    set/clear bit 11 (dec. 2048) of status word for switching register files -
316    but how can we do this? the pdp11/45 manual says bit may only
317    be set (p.24), but not cleared!
318 
319    switching to kernel is probably more expensive, so we'll leave it
320    like this and not use the second set of registers...
321 
322    maybe as option if you want to generate code for kernel mode? */
323 
324 void
pdp11_expand_epilogue(void)325 pdp11_expand_epilogue (void)
326 {
327   HOST_WIDE_INT fsize = get_frame_size ();
328   unsigned regno;
329   rtx x, reg, via_ac = NULL;
330 
331   if (pdp11_saved_regno (AC4_REGNUM) || pdp11_saved_regno (AC5_REGNUM))
332     {
333       /* Find a temporary with which to restore AC4/5.  */
334       for (regno = AC0_REGNUM; regno <= AC3_REGNUM; regno++)
335 	if (pdp11_saved_regno (regno))
336 	  {
337 	    via_ac = gen_rtx_REG (DFmode, regno);
338 	    break;
339 	  }
340     }
341 
342   /* If possible, restore registers via pops.  */
343   if (!frame_pointer_needed || crtl->sp_is_unchanging)
344     {
345       /* Restore registers via pops.  */
346 
347       for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
348 	if (pdp11_saved_regno (regno))
349 	  {
350 	    x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
351 	    x = gen_frame_mem (DFmode, x);
352 	    reg = gen_rtx_REG (DFmode, regno);
353 
354 	    if (LOAD_FPU_REG_P (regno))
355 	      emit_move_insn (reg, x);
356 	    else
357 	      {
358 	        emit_move_insn (via_ac, x);
359 		emit_move_insn (reg, via_ac);
360 	      }
361 	  }
362 
363       for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
364 	if (pdp11_saved_regno (regno)
365 	    && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
366 	  {
367 	    x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
368 	    x = gen_frame_mem (Pmode, x);
369 	    emit_move_insn (gen_rtx_REG (Pmode, regno), x);
370 	  }
371     }
372   else
373     {
374       /* Restore registers via moves.  */
375       /* ??? If more than a few registers need to be restored, it's smaller
376 	 to generate a pointer through which we can emit pops.  Consider
377 	 that moves cost 2*NREG words and pops cost NREG+3 words.  This
378 	 means that the crossover is NREG=3.
379 
380 	 Possible registers to use are:
381 	  (1) The first call-saved general register.  This register will
382 		be restored with the last pop.
383 	  (2) R1, if it's not used as a return register.
384 	  (3) FP itself.  This option may result in +4 words, since we
385 		may need two add imm,rn instructions instead of just one.
386 		This also has the downside that we're not representing
387 		the unwind info in any way, so during the epilogue the
388 		debugger may get lost.  */
389 
390       HOST_WIDE_INT ofs = -pdp11_sp_frame_offset ();
391 
392       for (regno = AC5_REGNUM; regno >= AC0_REGNUM; regno--)
393 	if (pdp11_saved_regno (regno))
394 	  {
395 	    x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
396 	    x = gen_frame_mem (DFmode, x);
397 	    reg = gen_rtx_REG (DFmode, regno);
398 
399 	    if (LOAD_FPU_REG_P (regno))
400 	      emit_move_insn (reg, x);
401 	    else
402 	      {
403 	        emit_move_insn (via_ac, x);
404 		emit_move_insn (reg, via_ac);
405 	      }
406 	    ofs += 8;
407 	  }
408 
409       for (regno = PC_REGNUM; regno >= R0_REGNUM + 2; regno--)
410 	if (pdp11_saved_regno (regno)
411 	    && (regno != HARD_FRAME_POINTER_REGNUM || !frame_pointer_needed))
412 	  {
413 	    x = plus_constant (Pmode, hard_frame_pointer_rtx, ofs);
414 	    x = gen_frame_mem (Pmode, x);
415 	    emit_move_insn (gen_rtx_REG (Pmode, regno), x);
416 	    ofs += 2;
417 	  }
418     }
419 
420   /* Deallocate the stack frame.  */
421   if (fsize)
422     {
423       /* Prevent frame references via any pointer from being
424 	 scheduled after the frame is deallocated.  */
425       emit_insn (gen_blockage ());
426 
427       if (frame_pointer_needed)
428 	{
429 	  /* We can deallocate the frame with a single move.  */
430 	  emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
431 	}
432       else
433 	emit_insn (gen_addhi3 (stack_pointer_rtx, stack_pointer_rtx,
434 			       GEN_INT (fsize)));
435     }
436 
437   if (frame_pointer_needed)
438     {
439       x = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
440       x = gen_frame_mem (Pmode, x);
441       emit_move_insn (hard_frame_pointer_rtx, x);
442     }
443 
444   emit_jump_insn (gen_return ());
445 }
446 
447 /* Return the best assembler insn template
448    for moving operands[1] into operands[0] as a fullword.  */
449 static const char *
singlemove_string(rtx * operands)450 singlemove_string (rtx *operands)
451 {
452   if (operands[1] != const0_rtx)
453     return "mov %1,%0";
454 
455   return "clr %0";
456 }
457 
458 
459 /* Expand multi-word operands (SImode or DImode) into the 2 or 4
460    corresponding HImode operands.  The number of operands is given
461    as the third argument, and the required order of the parts as
462    the fourth argument.  */
463 bool
pdp11_expand_operands(rtx * operands,rtx exops[][2],int opcount,pdp11_action * action,pdp11_partorder order)464 pdp11_expand_operands (rtx *operands, rtx exops[][2], int opcount,
465 		       pdp11_action *action, pdp11_partorder order)
466 {
467   int words, op, w, i, sh;
468   pdp11_partorder useorder;
469   bool sameoff = false;
470   enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype;
471   REAL_VALUE_TYPE r;
472   long sval[2];
473 
474   words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
475 
476   /* If either piece order is accepted and one is pre-decrement
477      while the other is post-increment, set order to be high order
478      word first.  That will force the pre-decrement to be turned
479      into a pointer adjust, then offset addressing.
480      Otherwise, if either operand uses pre-decrement, that means
481      the order is low order first.
482      Otherwise, if both operands are registers and destination is
483      higher than source and they overlap, do low order word (highest
484      register number) first.  */
485   useorder = either;
486   if (opcount == 2)
487     {
488       if (!REG_P (operands[0]) && !REG_P (operands[1]) &&
489 	  !(CONSTANT_P (operands[1]) ||
490 	    GET_CODE (operands[1]) == CONST_DOUBLE) &&
491 	  ((GET_CODE (XEXP (operands[0], 0)) == POST_INC &&
492 	    GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) ||
493 	   (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC &&
494 	    GET_CODE (XEXP (operands[1], 0)) == POST_INC)))
495 	    useorder = big;
496       else if ((!REG_P (operands[0]) &&
497 		GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) ||
498 	       (!REG_P (operands[1]) &&
499 		!(CONSTANT_P (operands[1]) ||
500 		  GET_CODE (operands[1]) == CONST_DOUBLE) &&
501 		GET_CODE (XEXP (operands[1], 0)) == PRE_DEC))
502 	useorder = little;
503       else if (REG_P (operands[0]) && REG_P (operands[1]) &&
504 	       REGNO (operands[0]) > REGNO (operands[1]) &&
505 	       REGNO (operands[0]) < REGNO (operands[1]) + words)
506 	    useorder = little;
507 
508       /* Check for source == offset from register and dest == push of
509 	 the same register.  In that case, we have to use the same
510 	 offset (the one for the low order word) for all words, because
511 	 the push increases the offset to each source word.
512 	 In theory there are other cases like this, for example dest == pop,
513 	 but those don't occur in real life so ignore those.  */
514       if (GET_CODE (operands[0]) ==  MEM
515 	  && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC
516 	  && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
517 	  && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
518 	sameoff = true;
519     }
520 
521   /* If the caller didn't specify order, use the one we computed,
522      or high word first if we don't care either.  If the caller did
523      specify, verify we don't have a problem with that order.
524      (If it matters to the caller, constraints need to be used to
525      ensure this case doesn't occur).  */
526   if (order == either)
527     order = (useorder == either) ? big : useorder;
528   else
529     gcc_assert (useorder == either || useorder == order);
530 
531 
532   for (op = 0; op < opcount; op++)
533     {
534       /* First classify the operand.  */
535       if (REG_P (operands[op]))
536 	optype = REGOP;
537       else if (CONSTANT_P (operands[op])
538 	       || GET_CODE (operands[op]) == CONST_DOUBLE)
539 	optype = CNSTOP;
540       else if (GET_CODE (XEXP (operands[op], 0)) == POST_INC)
541 	optype = POPOP;
542       else if (GET_CODE (XEXP (operands[op], 0)) == PRE_DEC)
543 	optype = PUSHOP;
544       else if (!reload_in_progress || offsettable_memref_p (operands[op]))
545 	optype = OFFSOP;
546       else if (GET_CODE (operands[op]) == MEM)
547 	optype = MEMOP;
548       else
549 	optype = RNDOP;
550 
551       /* Check for the cases that the operand constraints are not
552 	 supposed to allow to happen. Return failure for such cases.  */
553       if (optype == RNDOP)
554 	return false;
555 
556       if (action != NULL)
557 	action[op] = no_action;
558 
559       /* If the operand uses pre-decrement addressing but we
560 	 want to get the parts high order first,
561 	 decrement the former register explicitly
562 	 and change the operand into ordinary indexing.  */
563       if (optype == PUSHOP && order == big)
564 	{
565 	  gcc_assert (action != NULL);
566 	  action[op] = dec_before;
567 	  operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
568 				      XEXP (XEXP (operands[op], 0), 0));
569 	  optype = OFFSOP;
570 	}
571       /* If the operand uses post-increment mode but we want
572 	 to get the parts low order first, change the operand
573 	 into ordinary indexing and remember to increment
574 	 the register explicitly when we're done.  */
575       else if (optype == POPOP && order == little)
576 	{
577 	  gcc_assert (action != NULL);
578 	  action[op] = inc_after;
579 	  operands[op] = gen_rtx_MEM (GET_MODE (operands[op]),
580 				      XEXP (XEXP (operands[op], 0), 0));
581 	  optype = OFFSOP;
582 	}
583 
584       if (GET_CODE (operands[op]) == CONST_DOUBLE)
585 	{
586 	  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[op]);
587 	  REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
588 	}
589 
590       for (i = 0; i < words; i++)
591 	{
592 	  if (order == big)
593 	    w = i;
594 	  else if (sameoff)
595 	    w = words - 1;
596 	  else
597 	    w = words - 1 - i;
598 
599 	  /* Set the output operand to be word "w" of the input.  */
600 	  if (optype == REGOP)
601 	    exops[i][op] = gen_rtx_REG (HImode, REGNO (operands[op]) + w);
602 	  else if (optype == OFFSOP)
603 	    exops[i][op] = adjust_address (operands[op], HImode, w * 2);
604 	  else if (optype == CNSTOP)
605 	    {
606 	      if (GET_CODE (operands[op]) == CONST_DOUBLE)
607 		{
608 		  sh = 16 - (w & 1) * 16;
609 		  exops[i][op] = gen_rtx_CONST_INT (HImode, (sval[w / 2] >> sh) & 0xffff);
610 		}
611 	      else
612 		{
613 		  sh = ((words - 1 - w) * 16);
614 		  exops[i][op] = gen_rtx_CONST_INT (HImode, trunc_int_for_mode (INTVAL(operands[op]) >> sh, HImode));
615 		}
616 	    }
617 	  else
618 	    exops[i][op] = operands[op];
619 	}
620     }
621   return true;
622 }
623 
624 /* Output assembler code to perform a multiple-word move insn
625    with operands OPERANDS.  This moves 2 or 4 words depending
626    on the machine mode of the operands.  */
627 
628 const char *
output_move_multiple(rtx * operands)629 output_move_multiple (rtx *operands)
630 {
631   rtx exops[4][2];
632   pdp11_action action[2];
633   int i, words;
634 
635   words = GET_MODE_BITSIZE (GET_MODE (operands[0])) / 16;
636 
637   pdp11_expand_operands (operands, exops, 2, action, either);
638 
639   /* Check for explicit decrement before.  */
640   if (action[0] == dec_before)
641     {
642       operands[0] = XEXP (operands[0], 0);
643       output_asm_insn ("sub $4,%0", operands);
644     }
645   if (action[1] == dec_before)
646     {
647       operands[1] = XEXP (operands[1], 0);
648       output_asm_insn ("sub $4,%1", operands);
649     }
650 
651   /* Do the words.  */
652   for (i = 0; i < words; i++)
653     output_asm_insn (singlemove_string (exops[i]), exops[i]);
654 
655   /* Check for increment after.  */
656   if (action[0] == inc_after)
657     {
658       operands[0] = XEXP (operands[0], 0);
659       output_asm_insn ("add $4,%0", operands);
660     }
661   if (action[1] == inc_after)
662     {
663       operands[1] = XEXP (operands[1], 0);
664       output_asm_insn ("add $4,%1", operands);
665     }
666 
667   return "";
668 }
669 
670 /* Output an ascii string.  */
671 void
output_ascii(FILE * file,const char * p,int size)672 output_ascii (FILE *file, const char *p, int size)
673 {
674   int i;
675 
676   /* This used to output .byte "string", which doesn't work with the UNIX
677      assembler and I think not with DEC ones either.  */
678   fprintf (file, "\t.byte ");
679 
680   for (i = 0; i < size; i++)
681     {
682       register int c = p[i];
683       if (c < 0)
684 	c += 256;
685       fprintf (file, "%#o", c);
686       if (i < size - 1)
687 	putc (',', file);
688     }
689   putc ('\n', file);
690 }
691 
692 
693 void
pdp11_asm_output_var(FILE * file,const char * name,int size,int align,bool global)694 pdp11_asm_output_var (FILE *file, const char *name, int size,
695 		      int align, bool global)
696 {
697   if (align > 8)
698     fprintf (file, "\n\t.even\n");
699   if (global)
700     {
701       fprintf (file, ".globl ");
702       assemble_name (file, name);
703     }
704   fprintf (file, "\n");
705   assemble_name (file, name);
706   fprintf (file, ": .=.+ %#ho\n", (unsigned short)size);
707 }
708 
709 static void
pdp11_asm_print_operand(FILE * file,rtx x,int code)710 pdp11_asm_print_operand (FILE *file, rtx x, int code)
711 {
712   REAL_VALUE_TYPE r;
713   long sval[2];
714 
715   if (code == '#')
716     fprintf (file, "#");
717   else if (code == '@')
718     {
719       if (TARGET_UNIX_ASM)
720 	fprintf (file, "*");
721       else
722 	fprintf (file, "@");
723     }
724   else if (GET_CODE (x) == REG)
725     fprintf (file, "%s", reg_names[REGNO (x)]);
726   else if (GET_CODE (x) == MEM)
727     output_address (XEXP (x, 0));
728   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != SImode)
729     {
730       REAL_VALUE_FROM_CONST_DOUBLE (r, x);
731       REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
732       fprintf (file, "$%#lo", sval[0] >> 16);
733     }
734   else
735     {
736       putc ('$', file);
737       output_addr_const_pdp11 (file, x);
738     }
739 }
740 
741 static bool
pdp11_asm_print_operand_punct_valid_p(unsigned char c)742 pdp11_asm_print_operand_punct_valid_p (unsigned char c)
743 {
744   return (c == '#' || c == '@');
745 }
746 
747 void
print_operand_address(FILE * file,register rtx addr)748 print_operand_address (FILE *file, register rtx addr)
749 {
750   register rtx breg;
751   rtx offset;
752   int again = 0;
753 
754  retry:
755 
756   switch (GET_CODE (addr))
757     {
758     case MEM:
759       if (TARGET_UNIX_ASM)
760 	fprintf (file, "*");
761       else
762 	fprintf (file, "@");
763       addr = XEXP (addr, 0);
764       again = 1;
765       goto retry;
766 
767     case REG:
768       fprintf (file, "(%s)", reg_names[REGNO (addr)]);
769       break;
770 
771     case PRE_MODIFY:
772     case PRE_DEC:
773       fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
774       break;
775 
776     case POST_MODIFY:
777     case POST_INC:
778       fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
779       break;
780 
781     case PLUS:
782       breg = 0;
783       offset = 0;
784       if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
785 	  || GET_CODE (XEXP (addr, 0)) == MEM)
786 	{
787 	  offset = XEXP (addr, 0);
788 	  addr = XEXP (addr, 1);
789 	}
790       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
791 	       || GET_CODE (XEXP (addr, 1)) == MEM)
792 	{
793 	  offset = XEXP (addr, 1);
794 	  addr = XEXP (addr, 0);
795 	}
796       if (GET_CODE (addr) != PLUS)
797 	;
798       else if (GET_CODE (XEXP (addr, 0)) == REG)
799 	{
800 	  breg = XEXP (addr, 0);
801 	  addr = XEXP (addr, 1);
802 	}
803       else if (GET_CODE (XEXP (addr, 1)) == REG)
804 	{
805 	  breg = XEXP (addr, 1);
806 	  addr = XEXP (addr, 0);
807 	}
808       if (GET_CODE (addr) == REG)
809 	{
810 	  gcc_assert (breg == 0);
811 	  breg = addr;
812 	  addr = 0;
813 	}
814       if (offset != 0)
815 	{
816 	  gcc_assert (addr == 0);
817 	  addr = offset;
818 	}
819       if (addr != 0)
820 	output_addr_const_pdp11 (file, addr);
821       if (breg != 0)
822 	{
823 	  gcc_assert (GET_CODE (breg) == REG);
824 	  fprintf (file, "(%s)", reg_names[REGNO (breg)]);
825 	}
826       break;
827 
828     default:
829       if (!again && GET_CODE (addr) == CONST_INT)
830 	{
831 	  /* Absolute (integer number) address.  */
832 	  if (!TARGET_UNIX_ASM)
833 	    fprintf (file, "@$");
834 	}
835       output_addr_const_pdp11 (file, addr);
836     }
837 }
838 
839 /* Target hook to assemble integer objects.  We need to use the
840    pdp-specific version of output_addr_const.  */
841 
842 static bool
pdp11_assemble_integer(rtx x,unsigned int size,int aligned_p)843 pdp11_assemble_integer (rtx x, unsigned int size, int aligned_p)
844 {
845   if (aligned_p)
846     switch (size)
847       {
848       case 1:
849 	fprintf (asm_out_file, "\t.byte\t");
850 	output_addr_const_pdp11 (asm_out_file, GEN_INT (INTVAL (x) & 0xff));
851 ;
852 	fprintf (asm_out_file, " /* char */\n");
853 	return true;
854 
855       case 2:
856 	fprintf (asm_out_file, TARGET_UNIX_ASM ? "\t" : "\t.word\t");
857 	output_addr_const_pdp11 (asm_out_file, x);
858 	fprintf (asm_out_file, " /* short */\n");
859 	return true;
860       }
861   return default_assemble_integer (x, size, aligned_p);
862 }
863 
864 
865 /* register move costs, indexed by regs */
866 
867 static const int move_costs[N_REG_CLASSES][N_REG_CLASSES] =
868 {
869              /* NO  MUL  GEN  LFPU  NLFPU FPU ALL */
870 
871 /* NO */     {  0,   0,   0,    0,    0,    0,   0},
872 /* MUL */    {  0,   2,   2,   22,   22,   22,  22},
873 /* GEN */    {  0,   2,   2,   22,   22,   22,  22},
874 /* LFPU */   {  0,  22,  22,    2,    2,    2,  22},
875 /* NLFPU */  {  0,  22,  22,    2,   10,   10,  22},
876 /* FPU */    {  0,  22,  22,    2,   10,   10,  22},
877 /* ALL */    {  0,  22,  22,   22,   22,   22,  22}
878 }  ;
879 
880 
881 /* -- note that some moves are tremendously expensive,
882    because they require lots of tricks! do we have to
883    charge the costs incurred by secondary reload class
884    -- as we do here with 10 -- or not ? */
885 
886 static int
pdp11_register_move_cost(enum machine_mode mode ATTRIBUTE_UNUSED,reg_class_t c1,reg_class_t c2)887 pdp11_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
888 			  reg_class_t c1, reg_class_t c2)
889 {
890     return move_costs[(int)c1][(int)c2];
891 }
892 
893 static bool
pdp11_rtx_costs(rtx x,int code,int outer_code ATTRIBUTE_UNUSED,int opno ATTRIBUTE_UNUSED,int * total,bool speed ATTRIBUTE_UNUSED)894 pdp11_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
895 		 int opno ATTRIBUTE_UNUSED, int *total,
896 		 bool speed ATTRIBUTE_UNUSED)
897 {
898   switch (code)
899     {
900     case CONST_INT:
901       if (INTVAL (x) == 0 || INTVAL (x) == -1 || INTVAL (x) == 1)
902 	{
903 	  *total = 0;
904 	  return true;
905 	}
906       /* FALLTHRU */
907 
908     case CONST:
909     case LABEL_REF:
910     case SYMBOL_REF:
911       /* Twice as expensive as REG.  */
912       *total = 2;
913       return true;
914 
915     case CONST_DOUBLE:
916       /* Twice (or 4 times) as expensive as 16 bit.  */
917       *total = 4;
918       return true;
919 
920     case MULT:
921       /* ??? There is something wrong in MULT because MULT is not
922          as cheap as total = 2 even if we can shift!  */
923       /* If optimizing for size make mult etc cheap, but not 1, so when
924          in doubt the faster insn is chosen.  */
925       if (optimize_size)
926         *total = COSTS_N_INSNS (2);
927       else
928         *total = COSTS_N_INSNS (11);
929       return false;
930 
931     case DIV:
932       if (optimize_size)
933         *total = COSTS_N_INSNS (2);
934       else
935         *total = COSTS_N_INSNS (25);
936       return false;
937 
938     case MOD:
939       if (optimize_size)
940         *total = COSTS_N_INSNS (2);
941       else
942         *total = COSTS_N_INSNS (26);
943       return false;
944 
945     case ABS:
946       /* Equivalent to length, so same for optimize_size.  */
947       *total = COSTS_N_INSNS (3);
948       return false;
949 
950     case ZERO_EXTEND:
951       /* Only used for qi->hi.  */
952       *total = COSTS_N_INSNS (1);
953       return false;
954 
955     case SIGN_EXTEND:
956       if (GET_MODE (x) == HImode)
957       	*total = COSTS_N_INSNS (1);
958       else if (GET_MODE (x) == SImode)
959 	*total = COSTS_N_INSNS (6);
960       else
961 	*total = COSTS_N_INSNS (2);
962       return false;
963 
964     case ASHIFT:
965     case LSHIFTRT:
966     case ASHIFTRT:
967       if (optimize_size)
968         *total = COSTS_N_INSNS (1);
969       else if (GET_MODE (x) ==  QImode)
970         {
971           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
972    	    *total = COSTS_N_INSNS (8); /* worst case */
973           else
974 	    *total = COSTS_N_INSNS (INTVAL (XEXP (x, 1)));
975         }
976       else if (GET_MODE (x) == HImode)
977         {
978           if (GET_CODE (XEXP (x, 1)) == CONST_INT)
979             {
980 	      if (abs (INTVAL (XEXP (x, 1))) == 1)
981                 *total = COSTS_N_INSNS (1);
982               else
983 	        *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
984             }
985           else
986             *total = COSTS_N_INSNS (10); /* worst case */
987         }
988       else if (GET_MODE (x) == SImode)
989         {
990           if (GET_CODE (XEXP (x, 1)) == CONST_INT)
991 	    *total = COSTS_N_INSNS (2.5 + 0.5 * INTVAL (XEXP (x, 1)));
992           else /* worst case */
993             *total = COSTS_N_INSNS (18);
994         }
995       return false;
996 
997     default:
998       return false;
999     }
1000 }
1001 
1002 const char *
output_jump(enum rtx_code code,int inv,int length)1003 output_jump (enum rtx_code code, int inv, int length)
1004 {
1005     static int x = 0;
1006 
1007     static char buf[1000];
1008     const char *pos, *neg;
1009 
1010     if (cc_prev_status.flags & CC_NO_OVERFLOW)
1011       {
1012 	switch (code)
1013 	  {
1014 	  case GTU: code = GT; break;
1015 	  case LTU: code = LT; break;
1016 	  case GEU: code = GE; break;
1017 	  case LEU: code = LE; break;
1018 	  default: ;
1019 	  }
1020       }
1021     switch (code)
1022       {
1023       case EQ: pos = "beq", neg = "bne"; break;
1024       case NE: pos = "bne", neg = "beq"; break;
1025       case GT: pos = "bgt", neg = "ble"; break;
1026       case GTU: pos = "bhi", neg = "blos"; break;
1027       case LT: pos = "blt", neg = "bge"; break;
1028       case LTU: pos = "blo", neg = "bhis"; break;
1029       case GE: pos = "bge", neg = "blt"; break;
1030       case GEU: pos = "bhis", neg = "blo"; break;
1031       case LE: pos = "ble", neg = "bgt"; break;
1032       case LEU: pos = "blos", neg = "bhi"; break;
1033       default: gcc_unreachable ();
1034       }
1035 
1036 #if 0
1037 /* currently we don't need this, because the tstdf and cmpdf
1038    copy the condition code immediately, and other float operations are not
1039    yet recognized as changing the FCC - if so, then the length-cost of all
1040    jump insns increases by one, because we have to potentially copy the
1041    FCC! */
1042     if (cc_status.flags & CC_IN_FPU)
1043 	output_asm_insn("cfcc", NULL);
1044 #endif
1045 
1046     switch (length)
1047     {
1048       case 2:
1049 
1050 	sprintf(buf, "%s %%l1", inv ? neg : pos);
1051 
1052 	return buf;
1053 
1054       case 6:
1055 
1056 	sprintf(buf, "%s JMP_%d\n\tjmp %%l1\nJMP_%d:", inv ? pos : neg, x, x);
1057 
1058 	x++;
1059 
1060 	return buf;
1061 
1062       default:
1063 
1064 	gcc_unreachable ();
1065     }
1066 
1067 }
1068 
1069 void
notice_update_cc_on_set(rtx exp,rtx insn ATTRIBUTE_UNUSED)1070 notice_update_cc_on_set(rtx exp, rtx insn ATTRIBUTE_UNUSED)
1071 {
1072     if (GET_CODE (SET_DEST (exp)) == CC0)
1073     {
1074       cc_status.flags = 0;
1075       cc_status.value1 = SET_DEST (exp);
1076       cc_status.value2 = SET_SRC (exp);
1077     }
1078     else if (GET_CODE (SET_SRC (exp)) == CALL)
1079     {
1080       CC_STATUS_INIT;
1081     }
1082     else if (SET_DEST(exp) == pc_rtx)
1083     {
1084       /* jump */
1085     }
1086     else if (GET_MODE (SET_DEST(exp)) == HImode
1087 	     || GET_MODE (SET_DEST(exp)) == QImode)
1088     {
1089       cc_status.flags = GET_CODE (SET_SRC(exp)) == MINUS ? 0 : CC_NO_OVERFLOW;
1090       cc_status.value1 = SET_SRC (exp);
1091       cc_status.value2 = SET_DEST (exp);
1092 
1093       if (cc_status.value1 && GET_CODE (cc_status.value1) == REG
1094 	  && cc_status.value2
1095 	  && reg_overlap_mentioned_p (cc_status.value1, cc_status.value2))
1096 	cc_status.value2 = 0;
1097       if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM
1098 	  && cc_status.value2
1099 	  && GET_CODE (cc_status.value2) == MEM)
1100 	cc_status.value2 = 0;
1101     }
1102     else
1103     {
1104       CC_STATUS_INIT;
1105     }
1106 }
1107 
1108 
1109 int
simple_memory_operand(rtx op,enum machine_mode mode ATTRIBUTE_UNUSED)1110 simple_memory_operand(rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1111 {
1112     rtx addr;
1113 
1114     /* Eliminate non-memory operations */
1115     if (GET_CODE (op) != MEM)
1116 	return FALSE;
1117 
1118 #if 0
1119     /* dword operations really put out 2 instructions, so eliminate them.  */
1120     if (GET_MODE_SIZE (GET_MODE (op)) > (HAVE_64BIT_P () ? 8 : 4))
1121 	return FALSE;
1122 #endif
1123 
1124     /* Decode the address now.  */
1125 
1126   indirection:
1127 
1128     addr = XEXP (op, 0);
1129 
1130     switch (GET_CODE (addr))
1131     {
1132       case REG:
1133 	/* (R0) - no extra cost */
1134 	return 1;
1135 
1136       case PRE_DEC:
1137       case POST_INC:
1138 	/* -(R0), (R0)+ - cheap! */
1139 	return 0;
1140 
1141       case MEM:
1142 	/* cheap - is encoded in addressing mode info!
1143 
1144 	   -- except for @(R0), which has to be @0(R0) !!! */
1145 
1146 	if (GET_CODE (XEXP (addr, 0)) == REG)
1147 	    return 0;
1148 
1149 	op=addr;
1150 	goto indirection;
1151 
1152       case CONST_INT:
1153       case LABEL_REF:
1154       case CONST:
1155       case SYMBOL_REF:
1156 	/* @#address - extra cost */
1157 	return 0;
1158 
1159       case PLUS:
1160 	/* X(R0) - extra cost */
1161 	return 0;
1162 
1163       default:
1164 	break;
1165     }
1166 
1167     return FALSE;
1168 }
1169 
1170 
1171 /*
1172  * output a block move:
1173  *
1174  * operands[0]	... to
1175  * operands[1]  ... from
1176  * operands[2]  ... length
1177  * operands[3]  ... alignment
1178  * operands[4]  ... scratch register
1179  */
1180 
1181 
1182 const char *
output_block_move(rtx * operands)1183 output_block_move(rtx *operands)
1184 {
1185     static int count = 0;
1186     char buf[200];
1187     int unroll;
1188     int lastbyte = 0;
1189 
1190     /* Move of zero bytes is a NOP.  */
1191     if (operands[2] == const0_rtx)
1192       return "";
1193 
1194     /* Look for moves by small constant byte counts, those we'll
1195        expand to straight line code.  */
1196     if (CONSTANT_P (operands[2]))
1197     {
1198 	if (INTVAL (operands[2]) < 16
1199 	    && (!optimize_size || INTVAL (operands[2]) < 5)
1200 	    && INTVAL (operands[3]) == 1)
1201 	{
1202 	    register int i;
1203 
1204 	    for (i = 1; i <= INTVAL (operands[2]); i++)
1205 		output_asm_insn("movb (%1)+, (%0)+", operands);
1206 
1207 	    return "";
1208 	}
1209 	else if (INTVAL(operands[2]) < 32
1210 		 && (!optimize_size || INTVAL (operands[2]) < 9)
1211 		 && INTVAL (operands[3]) >= 2)
1212 	{
1213 	    register int i;
1214 
1215 	    for (i = 1; i <= INTVAL (operands[2]) / 2; i++)
1216 		output_asm_insn ("mov (%1)+, (%0)+", operands);
1217 	    if (INTVAL (operands[2]) & 1)
1218 	      output_asm_insn ("movb (%1), (%0)", operands);
1219 
1220 	    return "";
1221 	}
1222     }
1223 
1224     /* Ideally we'd look for moves that are multiples of 4 or 8
1225        bytes and handle those by unrolling the move loop.  That
1226        makes for a lot of code if done at run time, but it's ok
1227        for constant counts.  Also, for variable counts we have
1228        to worry about odd byte count with even aligned pointers.
1229        On 11/40 and up we handle that case; on older machines
1230        we don't and just use byte-wise moves all the time.  */
1231 
1232     if (CONSTANT_P (operands[2]) )
1233     {
1234       if (INTVAL (operands[3]) < 2)
1235 	unroll = 0;
1236       else
1237 	{
1238 	  lastbyte = INTVAL (operands[2]) & 1;
1239 
1240 	  if (optimize_size || INTVAL (operands[2]) & 2)
1241 	    unroll = 1;
1242 	  else if (INTVAL (operands[2]) & 4)
1243 	    unroll = 2;
1244 	  else
1245 	    unroll = 3;
1246 	}
1247 
1248       /* Loop count is byte count scaled by unroll.  */
1249       operands[2] = GEN_INT (INTVAL (operands[2]) >> unroll);
1250       output_asm_insn ("mov %2, %4", operands);
1251     }
1252     else
1253     {
1254 	/* Variable byte count; use the input register
1255 	   as the scratch.  */
1256 	operands[4] = operands[2];
1257 
1258 	/* Decide whether to move by words, and check
1259 	   the byte count for zero.  */
1260 	if (TARGET_40_PLUS && INTVAL (operands[3]) > 1)
1261 	  {
1262 	    unroll = 1;
1263 	    output_asm_insn ("asr %4", operands);
1264 	  }
1265 	else
1266 	  {
1267 	    unroll = 0;
1268 	    output_asm_insn ("tst %4", operands);
1269 	  }
1270 	sprintf (buf, "beq movestrhi%d", count + 1);
1271 	output_asm_insn (buf, NULL);
1272     }
1273 
1274     /* Output the loop label.  */
1275     sprintf (buf, "\nmovestrhi%d:", count);
1276     output_asm_insn (buf, NULL);
1277 
1278     /* Output the appropriate move instructions.  */
1279     switch (unroll)
1280     {
1281       case 0:
1282 	output_asm_insn ("movb (%1)+, (%0)+", operands);
1283 	break;
1284 
1285       case 1:
1286 	output_asm_insn ("mov (%1)+, (%0)+", operands);
1287 	break;
1288 
1289       case 2:
1290 	output_asm_insn ("mov (%1)+, (%0)+", operands);
1291 	output_asm_insn ("mov (%1)+, (%0)+", operands);
1292 	break;
1293 
1294       default:
1295 	output_asm_insn ("mov (%1)+, (%0)+", operands);
1296 	output_asm_insn ("mov (%1)+, (%0)+", operands);
1297 	output_asm_insn ("mov (%1)+, (%0)+", operands);
1298 	output_asm_insn ("mov (%1)+, (%0)+", operands);
1299 	break;
1300     }
1301 
1302     /* Output the decrement and test.  */
1303     if (TARGET_40_PLUS)
1304       {
1305 	sprintf (buf, "sob %%4, movestrhi%d", count);
1306 	output_asm_insn (buf, operands);
1307       }
1308     else
1309       {
1310 	output_asm_insn ("dec %4", operands);
1311 	sprintf (buf, "bgt movestrhi%d", count);
1312 	output_asm_insn (buf, NULL);
1313       }
1314     count ++;
1315 
1316     /* If constant odd byte count, move the last byte.  */
1317     if (lastbyte)
1318       output_asm_insn ("movb (%1), (%0)", operands);
1319     else if (!CONSTANT_P (operands[2]))
1320       {
1321 	/* Output the destination label for the zero byte count check.  */
1322 	sprintf (buf, "\nmovestrhi%d:", count);
1323 	output_asm_insn (buf, NULL);
1324 	count++;
1325 
1326 	/* If we did word moves, check for trailing last byte. */
1327 	if (unroll)
1328 	  {
1329 	    sprintf (buf, "bcc movestrhi%d", count);
1330 	    output_asm_insn (buf, NULL);
1331 	    output_asm_insn ("movb (%1), (%0)", operands);
1332 	    sprintf (buf, "\nmovestrhi%d:", count);
1333 	    output_asm_insn (buf, NULL);
1334 	    count++;
1335 	  }
1336       }
1337 
1338     return "";
1339 }
1340 
1341 /* This function checks whether a real value can be encoded as
1342    a literal, i.e., addressing mode 27.  In that mode, real values
1343    are one word values, so the remaining 48 bits have to be zero.  */
1344 int
legitimate_const_double_p(rtx address)1345 legitimate_const_double_p (rtx address)
1346 {
1347   REAL_VALUE_TYPE r;
1348   long sval[2];
1349   REAL_VALUE_FROM_CONST_DOUBLE (r, address);
1350   REAL_VALUE_TO_TARGET_DOUBLE (r, sval);
1351   if ((sval[0] & 0xffff) == 0 && sval[1] == 0)
1352     return 1;
1353   return 0;
1354 }
1355 
1356 /* Implement CANNOT_CHANGE_MODE_CLASS.  */
1357 bool
pdp11_cannot_change_mode_class(enum machine_mode from,enum machine_mode to,enum reg_class rclass)1358 pdp11_cannot_change_mode_class (enum machine_mode from,
1359 				enum machine_mode to,
1360 				enum reg_class rclass)
1361 {
1362   /* Also, FPU registers contain a whole float value and the parts of
1363      it are not separately accessible.
1364 
1365      So we disallow all mode changes involving FPRs.  */
1366   if (FLOAT_MODE_P (from) != FLOAT_MODE_P (to))
1367     return true;
1368 
1369   return reg_classes_intersect_p (FPU_REGS, rclass);
1370 }
1371 
1372 /* TARGET_PREFERRED_RELOAD_CLASS
1373 
1374    Given an rtx X being reloaded into a reg required to be
1375    in class CLASS, return the class of reg to actually use.
1376    In general this is just CLASS; but on some machines
1377    in some cases it is preferable to use a more restrictive class.
1378 
1379 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1380 
1381 static reg_class_t
pdp11_preferred_reload_class(rtx x,reg_class_t rclass)1382 pdp11_preferred_reload_class (rtx x, reg_class_t rclass)
1383 {
1384   if (rclass == FPU_REGS)
1385     return LOAD_FPU_REGS;
1386   if (rclass == ALL_REGS)
1387     {
1388       if (FLOAT_MODE_P (GET_MODE (x)))
1389 	return LOAD_FPU_REGS;
1390       else
1391 	return GENERAL_REGS;
1392     }
1393   return rclass;
1394 }
1395 
1396 /* TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
1397 
1398    Given an rtx X being reloaded into a reg required to be
1399    in class CLASS, return the class of reg to actually use.
1400    In general this is just CLASS; but on some machines
1401    in some cases it is preferable to use a more restrictive class.
1402 
1403 loading is easier into LOAD_FPU_REGS than FPU_REGS! */
1404 
1405 static reg_class_t
pdp11_preferred_output_reload_class(rtx x,reg_class_t rclass)1406 pdp11_preferred_output_reload_class (rtx x, reg_class_t rclass)
1407 {
1408   if (rclass == FPU_REGS)
1409     return LOAD_FPU_REGS;
1410   if (rclass == ALL_REGS)
1411     {
1412       if (FLOAT_MODE_P (GET_MODE (x)))
1413 	return LOAD_FPU_REGS;
1414       else
1415 	return GENERAL_REGS;
1416     }
1417   return rclass;
1418 }
1419 
1420 
1421 /* TARGET_SECONDARY_RELOAD.
1422 
1423    FPU registers AC4 and AC5 (class NO_LOAD_FPU_REGS) require an
1424    intermediate register (AC0-AC3: LOAD_FPU_REGS).  Everything else
1425    can be loade/stored directly.  */
1426 static reg_class_t
pdp11_secondary_reload(bool in_p ATTRIBUTE_UNUSED,rtx x,reg_class_t reload_class,enum machine_mode reload_mode ATTRIBUTE_UNUSED,secondary_reload_info * sri ATTRIBUTE_UNUSED)1427 pdp11_secondary_reload (bool in_p ATTRIBUTE_UNUSED,
1428 			rtx x,
1429 			reg_class_t reload_class,
1430 			enum machine_mode reload_mode ATTRIBUTE_UNUSED,
1431 			secondary_reload_info *sri ATTRIBUTE_UNUSED)
1432 {
1433   if (reload_class != NO_LOAD_FPU_REGS || GET_CODE (x) != REG ||
1434       REGNO_REG_CLASS (REGNO (x)) == LOAD_FPU_REGS)
1435     return NO_REGS;
1436 
1437   return LOAD_FPU_REGS;
1438 }
1439 
1440 /* Target routine to check if register to register move requires memory.
1441 
1442    The answer is yes if we're going between general register and FPU
1443    registers.  The mode doesn't matter in making this check.
1444 */
1445 bool
pdp11_secondary_memory_needed(reg_class_t c1,reg_class_t c2,enum machine_mode mode ATTRIBUTE_UNUSED)1446 pdp11_secondary_memory_needed (reg_class_t c1, reg_class_t c2,
1447 			       enum machine_mode mode ATTRIBUTE_UNUSED)
1448 {
1449   int fromfloat = (c1 == LOAD_FPU_REGS || c1 == NO_LOAD_FPU_REGS ||
1450 		   c1 == FPU_REGS);
1451   int tofloat = (c2 == LOAD_FPU_REGS || c2 == NO_LOAD_FPU_REGS ||
1452 		 c2 == FPU_REGS);
1453 
1454   return (fromfloat != tofloat);
1455 }
1456 
1457 /* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression
1458    that is a valid memory address for an instruction.
1459    The MODE argument is the machine mode for the MEM expression
1460    that wants to use this address.
1461 
1462 */
1463 
1464 static bool
pdp11_legitimate_address_p(enum machine_mode mode,rtx operand,bool strict)1465 pdp11_legitimate_address_p (enum machine_mode mode,
1466 			    rtx operand, bool strict)
1467 {
1468     rtx xfoob;
1469 
1470     /* accept @#address */
1471     if (CONSTANT_ADDRESS_P (operand))
1472       return true;
1473 
1474     switch (GET_CODE (operand))
1475       {
1476       case REG:
1477 	/* accept (R0) */
1478 	return !strict || REGNO_OK_FOR_BASE_P (REGNO (operand));
1479 
1480       case PLUS:
1481 	/* accept X(R0) */
1482 	return GET_CODE (XEXP (operand, 0)) == REG
1483 	  && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))))
1484 	  && CONSTANT_ADDRESS_P (XEXP (operand, 1));
1485 
1486       case PRE_DEC:
1487 	/* accept -(R0) */
1488 	return GET_CODE (XEXP (operand, 0)) == REG
1489 	  && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1490 
1491       case POST_INC:
1492 	/* accept (R0)+ */
1493 	return GET_CODE (XEXP (operand, 0)) == REG
1494 	  && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (operand, 0))));
1495 
1496       case PRE_MODIFY:
1497 	/* accept -(SP) -- which uses PRE_MODIFY for byte mode */
1498 	return GET_CODE (XEXP (operand, 0)) == REG
1499 	  && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1500 	  && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1501 	  && GET_CODE (XEXP (xfoob, 0)) == REG
1502 	  && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1503 	  && CONSTANT_P (XEXP (xfoob, 1))
1504 	  && INTVAL (XEXP (xfoob,1)) == -2;
1505 
1506       case POST_MODIFY:
1507 	/* accept (SP)+ -- which uses POST_MODIFY for byte mode */
1508 	return GET_CODE (XEXP (operand, 0)) == REG
1509 	  && REGNO (XEXP (operand, 0)) == STACK_POINTER_REGNUM
1510 	  && GET_CODE ((xfoob = XEXP (operand, 1))) == PLUS
1511 	  && GET_CODE (XEXP (xfoob, 0)) == REG
1512 	  && REGNO (XEXP (xfoob, 0)) == STACK_POINTER_REGNUM
1513 	  && CONSTANT_P (XEXP (xfoob, 1))
1514 	  && INTVAL (XEXP (xfoob,1)) == 2;
1515 
1516       case MEM:
1517 	/* handle another level of indirection ! */
1518 	xfoob = XEXP (operand, 0);
1519 
1520 	/* (MEM:xx (MEM:xx ())) is not valid for SI, DI and currently
1521 	   also forbidden for float, because we have to handle this
1522 	   in output_move_double and/or output_move_quad() - we could
1523 	   do it, but currently it's not worth it!!!
1524 	   now that DFmode cannot go into CPU register file,
1525 	   maybe I should allow float ...
1526 	   but then I have to handle memory-to-memory moves in movdf ??  */
1527 	if (GET_MODE_BITSIZE(mode) > 16)
1528 	  return false;
1529 
1530 	/* accept @address */
1531 	if (CONSTANT_ADDRESS_P (xfoob))
1532 	  return true;
1533 
1534 	switch (GET_CODE (xfoob))
1535 	  {
1536 	  case REG:
1537 	    /* accept @(R0) - which is @0(R0) */
1538 	    return !strict || REGNO_OK_FOR_BASE_P(REGNO (xfoob));
1539 
1540 	  case PLUS:
1541 	    /* accept @X(R0) */
1542 	    return GET_CODE (XEXP (xfoob, 0)) == REG
1543 	      && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))))
1544 	      && CONSTANT_ADDRESS_P (XEXP (xfoob, 1));
1545 
1546 	  case PRE_DEC:
1547 	    /* accept @-(R0) */
1548 	    return GET_CODE (XEXP (xfoob, 0)) == REG
1549 	      && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1550 
1551 	  case POST_INC:
1552 	    /* accept @(R0)+ */
1553 	    return GET_CODE (XEXP (xfoob, 0)) == REG
1554 	      && (!strict || REGNO_OK_FOR_BASE_P (REGNO (XEXP (xfoob, 0))));
1555 
1556 	  default:
1557 	    /* anything else is invalid */
1558 	    return false;
1559 	  }
1560 
1561       default:
1562 	/* anything else is invalid */
1563 	return false;
1564       }
1565 }
1566 
1567 /* Return the class number of the smallest class containing
1568    reg number REGNO.  */
1569 enum reg_class
pdp11_regno_reg_class(int regno)1570 pdp11_regno_reg_class (int regno)
1571 {
1572   if (regno == FRAME_POINTER_REGNUM || regno == ARG_POINTER_REGNUM)
1573     return GENERAL_REGS;
1574   else if (regno > AC3_REGNUM)
1575     return NO_LOAD_FPU_REGS;
1576   else if (regno >= AC0_REGNUM)
1577     return LOAD_FPU_REGS;
1578   else if (regno & 1)
1579     return MUL_REGS;
1580   else
1581     return GENERAL_REGS;
1582 }
1583 
1584 
1585 int
pdp11_sp_frame_offset(void)1586 pdp11_sp_frame_offset (void)
1587 {
1588   int offset = 0, regno;
1589   offset = get_frame_size();
1590   for (regno = 0; regno <= PC_REGNUM; regno++)
1591     if (pdp11_saved_regno (regno))
1592       offset += 2;
1593   for (regno = AC0_REGNUM; regno <= AC5_REGNUM; regno++)
1594     if (pdp11_saved_regno (regno))
1595       offset += 8;
1596 
1597   return offset;
1598 }
1599 
1600 /* Return the offset between two registers, one to be eliminated, and the other
1601    its replacement, at the start of a routine.  */
1602 
1603 int
pdp11_initial_elimination_offset(int from,int to)1604 pdp11_initial_elimination_offset (int from, int to)
1605 {
1606   int spoff;
1607 
1608   if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
1609     return 4;
1610   else if (from == FRAME_POINTER_REGNUM
1611 	   && to == HARD_FRAME_POINTER_REGNUM)
1612     return 0;
1613   else
1614     {
1615       gcc_assert (to == STACK_POINTER_REGNUM);
1616 
1617       /* Get the size of the register save area.  */
1618       spoff = pdp11_sp_frame_offset ();
1619       if (from == FRAME_POINTER_REGNUM)
1620 	return spoff;
1621 
1622       gcc_assert (from == ARG_POINTER_REGNUM);
1623 
1624       /* If there is a frame pointer, that is saved too.  */
1625       if (frame_pointer_needed)
1626 	spoff += 2;
1627 
1628       /* Account for the saved PC in the function call.  */
1629       return spoff + 2;
1630     }
1631 }
1632 
1633 /* A copy of output_addr_const modified for pdp11 expression syntax.
1634    output_addr_const also gets called for %cDIGIT and %nDIGIT, which we don't
1635    use, and for debugging output, which we don't support with this port either.
1636    So this copy should get called whenever needed.
1637 */
1638 void
output_addr_const_pdp11(FILE * file,rtx x)1639 output_addr_const_pdp11 (FILE *file, rtx x)
1640 {
1641   char buf[256];
1642   int i;
1643 
1644  restart:
1645   switch (GET_CODE (x))
1646     {
1647     case PC:
1648       gcc_assert (flag_pic);
1649       putc ('.', file);
1650       break;
1651 
1652     case SYMBOL_REF:
1653       assemble_name (file, XSTR (x, 0));
1654       break;
1655 
1656     case LABEL_REF:
1657       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
1658       assemble_name (file, buf);
1659       break;
1660 
1661     case CODE_LABEL:
1662       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
1663       assemble_name (file, buf);
1664       break;
1665 
1666     case CONST_INT:
1667       i = INTVAL (x);
1668       if (i < 0)
1669 	{
1670 	  i = -i;
1671 	  fprintf (file, "-");
1672 	}
1673       fprintf (file, "%#o", i & 0xffff);
1674       break;
1675 
1676     case CONST:
1677       /* This used to output parentheses around the expression,
1678 	 but that does not work on the 386 (either ATT or BSD assembler).  */
1679       output_addr_const_pdp11 (file, XEXP (x, 0));
1680       break;
1681 
1682     case CONST_DOUBLE:
1683       if (GET_MODE (x) == VOIDmode)
1684 	{
1685 	  /* We can use %o if the number is one word and positive.  */
1686 	  gcc_assert (!CONST_DOUBLE_HIGH (x));
1687 	  fprintf (file, "%#ho", (unsigned short) CONST_DOUBLE_LOW (x));
1688 	}
1689       else
1690 	/* We can't handle floating point constants;
1691 	   PRINT_OPERAND must handle them.  */
1692 	output_operand_lossage ("floating constant misused");
1693       break;
1694 
1695     case PLUS:
1696       /* Some assemblers need integer constants to appear last (e.g. masm).  */
1697       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
1698 	{
1699 	  output_addr_const_pdp11 (file, XEXP (x, 1));
1700 	  if (INTVAL (XEXP (x, 0)) >= 0)
1701 	    fprintf (file, "+");
1702 	  output_addr_const_pdp11 (file, XEXP (x, 0));
1703 	}
1704       else
1705 	{
1706 	  output_addr_const_pdp11 (file, XEXP (x, 0));
1707 	  if (INTVAL (XEXP (x, 1)) >= 0)
1708 	    fprintf (file, "+");
1709 	  output_addr_const_pdp11 (file, XEXP (x, 1));
1710 	}
1711       break;
1712 
1713     case MINUS:
1714       /* Avoid outputting things like x-x or x+5-x,
1715 	 since some assemblers can't handle that.  */
1716       x = simplify_subtraction (x);
1717       if (GET_CODE (x) != MINUS)
1718 	goto restart;
1719 
1720       output_addr_const_pdp11 (file, XEXP (x, 0));
1721       if (GET_CODE (XEXP (x, 1)) != CONST_INT
1722 	  || INTVAL (XEXP (x, 1)) >= 0)
1723 	fprintf (file, "-");
1724       output_addr_const_pdp11 (file, XEXP (x, 1));
1725       break;
1726 
1727     case ZERO_EXTEND:
1728     case SIGN_EXTEND:
1729       output_addr_const_pdp11 (file, XEXP (x, 0));
1730       break;
1731 
1732     default:
1733       output_operand_lossage ("invalid expression as operand");
1734     }
1735 }
1736 
1737 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
1738 
1739 static bool
pdp11_return_in_memory(const_tree type,const_tree fntype ATTRIBUTE_UNUSED)1740 pdp11_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1741 {
1742   /* Integers 32 bits and under, and scalar floats (if FPU), are returned
1743      in registers.  The rest go into memory.  */
1744   return (TYPE_MODE (type) == DImode
1745 	  || (FLOAT_MODE_P (TYPE_MODE (type)) && ! TARGET_AC0)
1746 	  || TREE_CODE (type) == VECTOR_TYPE
1747 	  || COMPLEX_MODE_P (TYPE_MODE (type)));
1748 }
1749 
1750 /* Worker function for TARGET_FUNCTION_VALUE.
1751 
1752    On the pdp11 the value is found in R0 (or ac0??? not without FPU!!!! )  */
1753 
1754 static rtx
pdp11_function_value(const_tree valtype,const_tree fntype_or_decl ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)1755 pdp11_function_value (const_tree valtype,
1756  		      const_tree fntype_or_decl ATTRIBUTE_UNUSED,
1757  		      bool outgoing ATTRIBUTE_UNUSED)
1758 {
1759   return gen_rtx_REG (TYPE_MODE (valtype),
1760 		      BASE_RETURN_VALUE_REG(TYPE_MODE(valtype)));
1761 }
1762 
1763 /* Worker function for TARGET_LIBCALL_VALUE.  */
1764 
1765 static rtx
pdp11_libcall_value(enum machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)1766 pdp11_libcall_value (enum machine_mode mode,
1767                      const_rtx fun ATTRIBUTE_UNUSED)
1768 {
1769   return  gen_rtx_REG (mode, BASE_RETURN_VALUE_REG(mode));
1770 }
1771 
1772 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.
1773 
1774    On the pdp, the first "output" reg is the only register thus used.
1775 
1776    maybe ac0 ? - as option someday!  */
1777 
1778 static bool
pdp11_function_value_regno_p(const unsigned int regno)1779 pdp11_function_value_regno_p (const unsigned int regno)
1780 {
1781   return (regno == RETVAL_REGNUM) || (TARGET_AC0 && (regno == AC0_REGNUM));
1782 }
1783 
1784 /* Worker function for TARGET_TRAMPOLINE_INIT.
1785 
1786    trampoline - how should i do it in separate i+d ?
1787    have some allocate_trampoline magic???
1788 
1789    the following should work for shared I/D:
1790 
1791    MOV	#STATIC, $4	01270Y	0x0000 <- STATIC; Y = STATIC_CHAIN_REGNUM
1792    JMP	@#FUNCTION	000137  0x0000 <- FUNCTION
1793 */
1794 
1795 static void
pdp11_trampoline_init(rtx m_tramp,tree fndecl,rtx chain_value)1796 pdp11_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
1797 {
1798   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
1799   rtx mem;
1800 
1801   gcc_assert (!TARGET_SPLIT);
1802 
1803   mem = adjust_address (m_tramp, HImode, 0);
1804   emit_move_insn (mem, GEN_INT (012700+STATIC_CHAIN_REGNUM));
1805   mem = adjust_address (m_tramp, HImode, 2);
1806   emit_move_insn (mem, chain_value);
1807   mem = adjust_address (m_tramp, HImode, 4);
1808   emit_move_insn (mem, GEN_INT (000137));
1809   emit_move_insn (mem, fnaddr);
1810 }
1811 
1812 /* Worker function for TARGET_FUNCTION_ARG.
1813 
1814    Determine where to put an argument to a function.
1815    Value is zero to push the argument on the stack,
1816    or a hard register in which to store the argument.
1817 
1818    MODE is the argument's machine mode.
1819    TYPE is the data type of the argument (as a tree).
1820     This is null for libcalls where that information may
1821     not be available.
1822    CUM is a variable of type CUMULATIVE_ARGS which gives info about
1823     the preceding args and about the function being called.
1824    NAMED is nonzero if this argument is a named parameter
1825     (otherwise it is an extra parameter matching an ellipsis).  */
1826 
1827 static rtx
pdp11_function_arg(cumulative_args_t cum ATTRIBUTE_UNUSED,enum machine_mode mode ATTRIBUTE_UNUSED,const_tree type ATTRIBUTE_UNUSED,bool named ATTRIBUTE_UNUSED)1828 pdp11_function_arg (cumulative_args_t cum ATTRIBUTE_UNUSED,
1829 		    enum machine_mode mode ATTRIBUTE_UNUSED,
1830 		    const_tree type ATTRIBUTE_UNUSED,
1831 		    bool named ATTRIBUTE_UNUSED)
1832 {
1833   return NULL_RTX;
1834 }
1835 
1836 /* Worker function for TARGET_FUNCTION_ARG_ADVANCE.
1837 
1838    Update the data in CUM to advance over an argument of mode MODE and
1839    data type TYPE.  (TYPE is null for libcalls where that information
1840    may not be available.)  */
1841 
1842 static void
pdp11_function_arg_advance(cumulative_args_t cum_v,enum machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)1843 pdp11_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1844 			    const_tree type, bool named ATTRIBUTE_UNUSED)
1845 {
1846   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1847 
1848   *cum += (mode != BLKmode
1849 	   ? GET_MODE_SIZE (mode)
1850 	   : int_size_in_bytes (type));
1851 }
1852 
1853 /* Make sure everything's fine if we *don't* have an FPU.
1854    This assumes that putting a register in fixed_regs will keep the
1855    compiler's mitts completely off it.  We don't bother to zero it out
1856    of register classes.  Also fix incompatible register naming with
1857    the UNIX assembler.  */
1858 
1859 static void
pdp11_conditional_register_usage(void)1860 pdp11_conditional_register_usage (void)
1861 {
1862   int i;
1863   HARD_REG_SET x;
1864   if (!TARGET_FPU)
1865     {
1866       COPY_HARD_REG_SET (x, reg_class_contents[(int)FPU_REGS]);
1867       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ )
1868        if (TEST_HARD_REG_BIT (x, i))
1869 	fixed_regs[i] = call_used_regs[i] = 1;
1870     }
1871 
1872   if (TARGET_AC0)
1873       call_used_regs[AC0_REGNUM] = 1;
1874   if (TARGET_UNIX_ASM)
1875     {
1876       /* Change names of FPU registers for the UNIX assembler.  */
1877       reg_names[8] = "fr0";
1878       reg_names[9] = "fr1";
1879       reg_names[10] = "fr2";
1880       reg_names[11] = "fr3";
1881       reg_names[12] = "fr4";
1882       reg_names[13] = "fr5";
1883     }
1884 }
1885 
1886 static section *
pdp11_function_section(tree decl ATTRIBUTE_UNUSED,enum node_frequency freq ATTRIBUTE_UNUSED,bool startup ATTRIBUTE_UNUSED,bool exit ATTRIBUTE_UNUSED)1887 pdp11_function_section (tree decl ATTRIBUTE_UNUSED,
1888 			enum node_frequency freq ATTRIBUTE_UNUSED,
1889 			bool startup ATTRIBUTE_UNUSED,
1890 			bool exit ATTRIBUTE_UNUSED)
1891 {
1892   return NULL;
1893 }
1894 
1895 /* Implement TARGET_LEGITIMATE_CONSTANT_P.  */
1896 
1897 static bool
pdp11_legitimate_constant_p(enum machine_mode mode ATTRIBUTE_UNUSED,rtx x)1898 pdp11_legitimate_constant_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x)
1899 {
1900   return GET_CODE (x) != CONST_DOUBLE || legitimate_const_double_p (x);
1901 }
1902 
1903 struct gcc_target targetm = TARGET_INITIALIZER;
1904