OSDN Git Service

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