OSDN Git Service

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