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