OSDN Git Service

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