OSDN Git Service

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