OSDN Git Service

* arm/vxarm.h: Split out vxWorks support into separate headerfile
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / arm.c
1 /* Output routines for GCC for ARM.
2    Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
4    and Martin Simmons (@harleqn.co.uk).
5    More major hacks by Richard Earnshaw (rearnsha@arm.com).
6
7 This file is part of GNU CC.
8
9 GNU CC is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GNU CC is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GNU CC; see the file COPYING.  If not, write to
21 the Free Software Foundation, 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.  */
23     
24 #include "config.h"
25 #include "system.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "real.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "flags.h"
36 #include "reload.h"
37 #include "tree.h"
38 #include "expr.h"
39 #include "toplev.h"
40 #include "recog.h"
41
42 /* The maximum number of insns skipped which will be conditionalised if
43    possible.  */
44 static int max_insns_skipped = 5;
45
46 extern FILE * asm_out_file;
47 /* Some function declarations.  */
48
49 static HOST_WIDE_INT int_log2 PROTO ((HOST_WIDE_INT));
50 static char * output_multi_immediate PROTO ((rtx *, char *, char *, int,
51                                             HOST_WIDE_INT));
52 static int arm_gen_constant PROTO ((enum rtx_code, enum machine_mode,
53                                     HOST_WIDE_INT, rtx, rtx, int, int));
54 static int arm_naked_function_p PROTO ((tree));
55 static void init_fpa_table PROTO ((void));
56 static enum machine_mode select_dominance_cc_mode PROTO ((rtx, rtx,
57                                                           HOST_WIDE_INT));
58 static HOST_WIDE_INT add_constant PROTO ((rtx, enum machine_mode, int *));
59 static void dump_table PROTO ((rtx));
60 static int fixit PROTO ((rtx, enum machine_mode, int));
61 static rtx find_barrier PROTO ((rtx, int));
62 static int broken_move PROTO ((rtx));
63 static char * fp_const_from_val PROTO ((REAL_VALUE_TYPE *));
64 static int eliminate_lr2ip PROTO ((rtx *));
65 static char * shift_op PROTO ((rtx, HOST_WIDE_INT *));
66 static int pattern_really_clobbers_lr PROTO ((rtx));
67 static int function_really_clobbers_lr PROTO ((rtx));
68 static void emit_multi_reg_push PROTO ((int));
69 static void emit_sfm PROTO ((int, int));
70 static enum arm_cond_code get_arm_condition_code PROTO ((rtx));
71 static int const_ok_for_op RTX_CODE_PROTO ((Hint, Rcode));
72
73 /*  Define the information needed to generate branch insns.  This is
74    stored from the compare operation. */
75 rtx arm_compare_op0, arm_compare_op1;
76
77 /* What type of floating point are we tuning for? */
78 enum floating_point_type arm_fpu;
79
80 /* What type of floating point instructions are available? */
81 enum floating_point_type arm_fpu_arch;
82
83 /* What program mode is the cpu running in? 26-bit mode or 32-bit mode */
84 enum prog_mode_type arm_prgmode;
85
86 /* Set by the -mfp=... option */
87 char * target_fp_name = NULL;
88
89 /* Used to parse -mstructure_size_boundary command line option.  */
90 char * structure_size_string = NULL;
91 int    arm_structure_size_boundary = 32; /* Used to be 8 */
92
93 /* Bit values used to identify processor capabilities.  */
94 #define FL_CO_PROC    0x01            /* Has external co-processor bus */
95 #define FL_FAST_MULT  0x02            /* Fast multiply */
96 #define FL_MODE26     0x04            /* 26-bit mode support */
97 #define FL_MODE32     0x08            /* 32-bit mode support */
98 #define FL_ARCH4      0x10            /* Architecture rel 4 */
99 #define FL_THUMB      0x20            /* Thumb aware */
100 #define FL_LDSCHED    0x40            /* Load scheduling necessary */
101 #define FL_STRONG     0x80            /* StrongARM */
102
103 /* The bits in this mask specify which instructions we are allowed to generate.  */
104 static int insn_flags = 0;
105 /* The bits in this mask specify which instruction scheduling options should
106    be used.  Note - there is an overlap with the FL_FAST_MULT.  For some
107    hardware we want to be able to generate the multiply instructions, but to
108    tune as if they were not present in the architecture.  */
109 static int tune_flags = 0;
110
111 /* The following are used in the arm.md file as equivalents to bits
112    in the above two flag variables.  */
113
114 /* Nonzero if this is an "M" variant of the processor.  */
115 int arm_fast_multiply = 0;
116
117 /* Nonzero if this chip supports the ARM Architecture 4 extensions */
118 int arm_arch4 = 0;
119
120 /* Nonzero if this chip can benefit from load scheduling.  */
121 int arm_ld_sched = 0;
122
123 /* Nonzero if this chip is a StrongARM.  */
124 int arm_is_strong = 0;
125
126 /* Nonzero if this chip is a an ARM6 or an ARM7.  */
127 int arm_is_6_or_7 = 0;
128
129 /* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
130    must report the mode of the memory reference from PRINT_OPERAND to
131    PRINT_OPERAND_ADDRESS.  */
132 enum machine_mode output_memory_reference_mode;
133
134 /* Nonzero if the prologue must setup `fp'.  */
135 int current_function_anonymous_args;
136
137 /* The register number to be used for the PIC offset register.  */
138 int arm_pic_register = 9;
139
140 /* Location counter of .text segment.  */
141 int arm_text_location = 0;
142
143 /* Set to one if we think that lr is only saved because of subroutine calls,
144    but all of these can be `put after' return insns */
145 int lr_save_eliminated;
146
147 /* Set to 1 when a return insn is output, this means that the epilogue
148    is not needed. */
149 static int return_used_this_function;
150
151 /* Set to 1 after arm_reorg has started.  Reset to start at the start of
152    the next function.  */
153 static int after_arm_reorg = 0;
154
155 /* The maximum number of insns to be used when loading a constant.  */
156 static int arm_constant_limit = 3;
157
158 /* For an explanation of these variables, see final_prescan_insn below.  */
159 int arm_ccfsm_state;
160 enum arm_cond_code arm_current_cc;
161 rtx arm_target_insn;
162 int arm_target_label;
163
164 /* The condition codes of the ARM, and the inverse function.  */
165 char * arm_condition_codes[] =
166 {
167   "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
168   "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
169 };
170
171 static enum arm_cond_code get_arm_condition_code ();
172
173 #define streq(string1, string2) (strcmp (string1, string2) == 0)
174 \f
175 /* Initialization code */
176
177 struct processors
178 {
179   char *       name;
180   unsigned int flags;
181 };
182
183 /* Not all of these give usefully different compilation alternatives,
184    but there is no simple way of generalizing them.  */
185 static struct processors all_cores[] =
186 {
187   /* ARM Cores */
188   
189   {"arm2",      FL_CO_PROC | FL_MODE26 },
190   {"arm250",    FL_CO_PROC | FL_MODE26 },
191   {"arm3",      FL_CO_PROC | FL_MODE26 },
192   {"arm6",      FL_CO_PROC | FL_MODE26 | FL_MODE32 },
193   {"arm60",     FL_CO_PROC | FL_MODE26 | FL_MODE32 },
194   {"arm600",    FL_CO_PROC | FL_MODE26 | FL_MODE32 },
195   {"arm610",                 FL_MODE26 | FL_MODE32 },
196   {"arm620",    FL_CO_PROC | FL_MODE26 | FL_MODE32 },
197   {"arm7",      FL_CO_PROC | FL_MODE26 | FL_MODE32 }, 
198   {"arm7m",     FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT }, /* arm7m doesn't exist on its own, */
199   {"arm7d",     FL_CO_PROC | FL_MODE26 | FL_MODE32 },                /* but only with D, (and I),       */
200   {"arm7dm",    FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT }, /* but those don't alter the code, */
201   {"arm7di",    FL_CO_PROC | FL_MODE26 | FL_MODE32 },                /* so arm7m is sometimes used.     */
202   {"arm7dmi",   FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
203   {"arm70",     FL_CO_PROC | FL_MODE26 | FL_MODE32 },
204   {"arm700",    FL_CO_PROC | FL_MODE26 | FL_MODE32 },
205   {"arm700i",   FL_CO_PROC | FL_MODE26 | FL_MODE32 },
206   {"arm710",                 FL_MODE26 | FL_MODE32 },
207   {"arm710c",                FL_MODE26 | FL_MODE32 },
208   {"arm7100",                FL_MODE26 | FL_MODE32 },
209   {"arm7500",                FL_MODE26 | FL_MODE32 },
210   {"arm7500fe", FL_CO_PROC | FL_MODE26 | FL_MODE32 }, /* Doesn't really have an external co-proc, but does have embedded fpu.  */
211   {"arm7tdmi",  FL_CO_PROC |             FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
212   {"arm8",                   FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED },
213   {"arm810",                 FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED },
214   {"arm9",                               FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
215   {"arm9tdmi",                           FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
216   {"strongarm",              FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
217   {"strongarm110",           FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
218   {"strongarm1100",          FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 |            FL_LDSCHED | FL_STRONG },
219   
220   {NULL, 0}
221 };
222
223 static struct processors all_architectures[] =
224 {
225   /* ARM Architectures */
226   
227   {"armv2",     FL_CO_PROC | FL_MODE26 },
228   {"armv2a",    FL_CO_PROC | FL_MODE26 },
229   {"armv3",     FL_CO_PROC | FL_MODE26 | FL_MODE32 },
230   {"armv3m",    FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
231   {"armv4",     FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4  },
232   /* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
233      implementations that support it, so we will leave it out for now.  */
234   {"armv4t",    FL_CO_PROC |             FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
235   {NULL, 0}
236 };
237
238 /* This is a magic stucture.  The 'string' field is magically filled in
239    with a pointer to the value specified by the user on the command line
240    assuming that the user has specified such a value.  */
241
242 struct arm_cpu_select arm_select[] =
243 {
244   /* string       name            processors  */        
245   { NULL,       "-mcpu=",       all_cores  },
246   { NULL,       "-march=",      all_architectures },
247   { NULL,       "-mtune=",      all_cores }
248 };
249
250 /* Return the number of bits set in value' */
251 static unsigned int
252 bit_count (value)
253      signed int value;
254 {
255   unsigned int count = 0;
256   
257   while (value)
258     {
259       value &= ~(value & - value);
260       ++ count;
261     }
262
263   return count;
264 }
265
266 /* Fix up any incompatible options that the user has specified.
267    This has now turned into a maze.  */
268 void
269 arm_override_options ()
270 {
271   unsigned i;
272   
273   /* Set up the flags based on the cpu/architecture selected by the user.  */
274   for (i = sizeof (arm_select) / sizeof (arm_select[0]); i--;)
275     {
276       struct arm_cpu_select * ptr = arm_select + i;
277       
278       if (ptr->string != NULL && ptr->string[0] != '\0')
279         {
280           struct processors * sel;
281
282           for (sel = ptr->processors; sel->name != NULL; sel ++)
283             if (streq (ptr->string, sel->name))
284               {
285                 if (i == 2)
286                   tune_flags = sel->flags;
287                 else
288                   {
289                     /* If we have been given an architecture and a processor
290                        make sure that they are compatible.  We only generate
291                        a warning though, and we prefer the CPU over the
292                        architecture. */
293                     if (insn_flags != 0 && (insn_flags ^ sel->flags))
294                       warning ("switch -mcpu=%s conflicts with -mtune= switch",
295                                ptr->string);
296                     
297                     insn_flags = sel->flags;
298                   }
299                 
300                 break;
301               }
302
303           if (sel->name == NULL)
304             error ("bad value (%s) for %s switch", ptr->string, ptr->name);
305         }
306     }
307   
308   /* If the user did not specify a processor, choose one for them.  */
309   if (insn_flags == 0)
310     {
311       struct processors * sel;
312       unsigned int        sought;
313       static struct cpu_default
314       {
315         int    cpu;
316         char * name;
317       }
318       cpu_defaults[] =
319       {
320         { TARGET_CPU_arm2,      "arm2" },
321         { TARGET_CPU_arm6,      "arm6" },
322         { TARGET_CPU_arm610,    "arm610" },
323         { TARGET_CPU_arm710,    "arm710" },
324         { TARGET_CPU_arm7m,     "arm7m" },
325         { TARGET_CPU_arm7500fe, "arm7500fe" },
326         { TARGET_CPU_arm7tdmi,  "arm7tdmi" },
327         { TARGET_CPU_arm8,      "arm8" },
328         { TARGET_CPU_arm810,    "arm810" },
329         { TARGET_CPU_arm9,      "arm9" },
330         { TARGET_CPU_strongarm, "strongarm" },
331         { TARGET_CPU_generic,   "arm" },
332         { 0, 0 }
333       };
334       struct cpu_default * def;
335           
336       /* Find the default.  */
337       for (def = cpu_defaults; def->name; def ++)
338         if (def->cpu == TARGET_CPU_DEFAULT)
339           break;
340
341       /* Make sure we found the default CPU.  */
342       if (def->name == NULL)
343         abort ();
344       
345       /* Find the default CPU's flags.  */
346       for (sel = all_cores; sel->name != NULL; sel ++)
347         if (streq (def->name, sel->name))
348           break;
349       
350       if (sel->name == NULL)
351         abort ();
352
353       insn_flags = sel->flags;
354       
355       /* Now check to see if the user has specified some command line
356          switch that require certain abilities from the cpu.  */
357       sought = 0;
358       
359       if (TARGET_THUMB_INTERWORK)
360         {
361           sought |= (FL_THUMB | FL_MODE32);
362           
363           /* Force apcs-32 to be used for interworking.  */
364           target_flags |= ARM_FLAG_APCS_32;
365
366           /* There are no ARM processor that supports both APCS-26 and
367              interworking.  Therefore we force FL_MODE26 to be removed
368              from insn_flags here (if it was set), so that the search
369              below will always be able to find a compatible processor.  */
370           insn_flags &= ~ FL_MODE26;
371         }
372       
373       if (! TARGET_APCS_32)
374         sought |= FL_MODE26;
375
376       if (sought != 0 && ((sought & insn_flags) != sought))
377         {
378           /* Try to locate a CPU type that supports all of the abilities
379              of the default CPU, plus the extra abilities requested by
380              the user.  */
381           for (sel = all_cores; sel->name != NULL; sel ++)
382             if ((sel->flags & sought) == (sought | insn_flags))
383               break;
384
385           if (sel->name == NULL)
386             {
387               unsigned int        current_bit_count = 0;
388               struct processors * best_fit = NULL;
389               
390               /* Ideally we would like to issue an error message here
391                  saying that it was not possible to find a CPU compatible
392                  with the default CPU, but which also supports the command
393                  line options specified by the programmer, and so they
394                  ought to use the -mcpu=<name> command line option to
395                  override the default CPU type.
396
397                  Unfortunately this does not work with multilibing.  We
398                  need to be able to support multilibs for -mapcs-26 and for
399                  -mthumb-interwork and there is no CPU that can support both
400                  options.  Instead if we cannot find a cpu that has both the
401                  characteristics of the default cpu and the given command line
402                  options we scan the array again looking for a best match.  */
403               for (sel = all_cores; sel->name != NULL; sel ++)
404                 if ((sel->flags & sought) == sought)
405                   {
406                     unsigned int count;
407
408                     count = bit_count (sel->flags & insn_flags);
409
410                     if (count >= current_bit_count)
411                       {
412                         best_fit = sel;
413                         current_bit_count = count;
414                       }
415                   }
416
417               if (best_fit == NULL)
418                 abort ();
419               else
420                 sel = best_fit;
421             }
422
423           insn_flags = sel->flags;
424         }
425     }
426   
427   /* If tuning has not been specified, tune for whichever processor or
428      architecture has been selected.  */
429   if (tune_flags == 0)
430     tune_flags = insn_flags;
431   
432   /* Make sure that the processor choice does not conflict with any of the
433      other command line choices.  */
434   if (TARGET_APCS_32 && !(insn_flags & FL_MODE32))
435     {
436       /* If APCS-32 was not the default then it must have been set by the
437          user, so issue a warning message.  If the user has specified
438          "-mapcs-32 -mcpu=arm2" then we loose here.  */
439       if ((TARGET_DEFAULT & ARM_FLAG_APCS_32) == 0)
440         warning ("target CPU does not support APCS-32" );
441       target_flags &= ~ ARM_FLAG_APCS_32;
442     }
443   else if (! TARGET_APCS_32 && !(insn_flags & FL_MODE26))
444     {
445       warning ("target CPU does not support APCS-26" );
446       target_flags |= ARM_FLAG_APCS_32;
447     }
448   
449   if (TARGET_THUMB_INTERWORK && !(insn_flags & FL_THUMB))
450     {
451       warning ("target CPU does not support interworking" );
452       target_flags &= ~ARM_FLAG_THUMB;
453     }
454   
455   /* If interworking is enabled then APCS-32 must be selected as well.  */
456   if (TARGET_THUMB_INTERWORK)
457     {
458       if (! TARGET_APCS_32)
459         warning ("interworking forces APCS-32 to be used" );
460       target_flags |= ARM_FLAG_APCS_32;
461     }
462   
463   if (TARGET_APCS_STACK && ! TARGET_APCS)
464     {
465       warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
466       target_flags |= ARM_FLAG_APCS_FRAME;
467     }
468   
469   if (write_symbols != NO_DEBUG && flag_omit_frame_pointer)
470     warning ("-g with -fomit-frame-pointer may not give sensible debugging");
471   
472   if (TARGET_POKE_FUNCTION_NAME)
473     target_flags |= ARM_FLAG_APCS_FRAME;
474   
475   if (TARGET_APCS_REENT && flag_pic)
476     fatal ("-fpic and -mapcs-reent are incompatible");
477   
478   if (TARGET_APCS_REENT)
479     warning ("APCS reentrant code not supported.  Ignored");
480   
481   /* If stack checking is disabled, we can use r10 as the PIC register,
482      which keeps r9 available.  */
483   if (flag_pic && ! TARGET_APCS_STACK)
484     arm_pic_register = 10;
485   
486   /* Well, I'm about to have a go, but pic is NOT going to be compatible
487      with APCS reentrancy, since that requires too much support in the
488      assembler and linker, and the ARMASM assembler seems to lack some
489      required directives.  */
490   if (flag_pic)
491     warning ("Position independent code not supported");
492   
493   if (TARGET_APCS_FLOAT)
494     warning ("Passing floating point arguments in fp regs not yet supported");
495   
496   /* Initialise boolean versions of the flags, for use in the arm.md file.  */
497   arm_fast_multiply = insn_flags & FL_FAST_MULT;
498   arm_arch4         = insn_flags & FL_ARCH4;
499   
500   arm_ld_sched      = tune_flags & FL_LDSCHED;
501   arm_is_strong     = tune_flags & FL_STRONG;
502   arm_is_6_or_7     = ((tune_flags & (FL_MODE26 | FL_MODE32))
503                        && !(tune_flags & FL_ARCH4));
504   
505   /* Default value for floating point code... if no co-processor
506      bus, then schedule for emulated floating point.  Otherwise,
507      assume the user has an FPA.
508      Note: this does not prevent use of floating point instructions,
509      -msoft-float does that.  */
510   arm_fpu = (tune_flags & FL_CO_PROC) ? FP_HARD : FP_SOFT3;
511   
512   if (target_fp_name)
513     {
514       if (streq (target_fp_name, "2"))
515         arm_fpu_arch = FP_SOFT2;
516       else if (streq (target_fp_name, "3"))
517         arm_fpu_arch = FP_SOFT3;
518       else
519         fatal ("Invalid floating point emulation option: -mfpe-%s",
520                target_fp_name);
521     }
522   else
523     arm_fpu_arch = FP_DEFAULT;
524   
525   if (TARGET_FPE && arm_fpu != FP_HARD)
526     arm_fpu = FP_SOFT2;
527   
528   /* For arm2/3 there is no need to do any scheduling if there is only
529      a floating point emulator, or we are doing software floating-point.  */
530   if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD) && (tune_flags & FL_MODE32) == 0)
531     flag_schedule_insns = flag_schedule_insns_after_reload = 0;
532   
533   arm_prog_mode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
534   
535   if (structure_size_string != NULL)
536     {
537       int size = strtol (structure_size_string, NULL, 0);
538       
539       if (size == 8 || size == 32)
540         arm_structure_size_boundary = size;
541       else
542         warning ("Structure size boundary can only be set to 8 or 32");
543     }
544   
545   /* If optimizing for space, don't synthesize constants.
546      For processors with load scheduling, it never costs more than 2 cycles
547      to load a constant, and the load scheduler may well reduce that to 1.  */
548   if (optimize_size || (tune_flags & FL_LDSCHED))
549     arm_constant_limit = 1;
550   
551   /* If optimizing for size, bump the number of instructions that we
552      are prepared to conditionally execute (even on a StrongARM). 
553      Otherwise for the StrongARM, which has early execution of branches,
554      a sequence that is worth skipping is shorter.  */
555   if (optimize_size)
556     max_insns_skipped = 6;
557   else if (arm_is_strong)
558     max_insns_skipped = 3;
559 }
560 \f
561 /* Return 1 if it is possible to return using a single instruction */
562
563 int
564 use_return_insn (iscond)
565      int iscond;
566 {
567   int regno;
568
569   if (!reload_completed
570       || current_function_pretend_args_size
571       || current_function_anonymous_args
572       || ((get_frame_size () + current_function_outgoing_args_size != 0)
573           && !(TARGET_APCS && frame_pointer_needed)))
574     return 0;
575
576   /* Can't be done if interworking with Thumb, and any registers have been
577      stacked.  Similarly, on StrongARM, conditional returns are expensive
578      if they aren't taken and registers have been stacked.  */
579   if (iscond && arm_is_strong && frame_pointer_needed)
580     return 0;
581   if ((iscond && arm_is_strong)
582       || TARGET_THUMB_INTERWORK)
583     for (regno = 0; regno < 16; regno++)
584       if (regs_ever_live[regno] && ! call_used_regs[regno])
585         return 0;
586       
587   /* Can't be done if any of the FPU regs are pushed, since this also
588      requires an insn */
589   for (regno = 16; regno < 24; regno++)
590     if (regs_ever_live[regno] && ! call_used_regs[regno])
591       return 0;
592
593   /* If a function is naked, don't use the "return" insn.  */
594   if (arm_naked_function_p (current_function_decl))
595     return 0;
596
597   return 1;
598 }
599
600 /* Return TRUE if int I is a valid immediate ARM constant.  */
601
602 int
603 const_ok_for_arm (i)
604      HOST_WIDE_INT i;
605 {
606   unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT)0xFF;
607
608   /* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must 
609      be all zero, or all one.  */
610   if ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0
611       && ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) 
612           != ((~(unsigned HOST_WIDE_INT) 0)
613               & ~(unsigned HOST_WIDE_INT) 0xffffffff)))
614     return FALSE;
615   
616   /* Fast return for 0 and powers of 2 */
617   if ((i & (i - 1)) == 0)
618     return TRUE;
619
620   do
621     {
622       if ((i & mask & (unsigned HOST_WIDE_INT) 0xffffffff) == 0)
623         return TRUE;
624       mask =
625           (mask << 2) | ((mask & (unsigned HOST_WIDE_INT) 0xffffffff)
626                          >> (32 - 2)) | ~((unsigned HOST_WIDE_INT) 0xffffffff);
627     } while (mask != ~(unsigned HOST_WIDE_INT) 0xFF);
628
629   return FALSE;
630 }
631
632 /* Return true if I is a valid constant for the operation CODE. */
633 static int
634 const_ok_for_op (i, code)
635      HOST_WIDE_INT i;
636      enum rtx_code code;
637 {
638   if (const_ok_for_arm (i))
639     return 1;
640
641   switch (code)
642     {
643     case PLUS:
644       return const_ok_for_arm (ARM_SIGN_EXTEND (-i));
645
646     case MINUS:         /* Should only occur with (MINUS I reg) => rsb */
647     case XOR:
648     case IOR:
649       return 0;
650
651     case AND:
652       return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
653
654     default:
655       abort ();
656     }
657 }
658
659 /* Emit a sequence of insns to handle a large constant.
660    CODE is the code of the operation required, it can be any of SET, PLUS,
661    IOR, AND, XOR, MINUS;
662    MODE is the mode in which the operation is being performed;
663    VAL is the integer to operate on;
664    SOURCE is the other operand (a register, or a null-pointer for SET);
665    SUBTARGETS means it is safe to create scratch registers if that will
666    either produce a simpler sequence, or we will want to cse the values.
667    Return value is the number of insns emitted.  */
668
669 int
670 arm_split_constant (code, mode, val, target, source, subtargets)
671      enum rtx_code code;
672      enum machine_mode mode;
673      HOST_WIDE_INT val;
674      rtx target;
675      rtx source;
676      int subtargets;
677 {
678   if (subtargets || code == SET
679       || (GET_CODE (target) == REG && GET_CODE (source) == REG
680           && REGNO (target) != REGNO (source)))
681     {
682       /* After arm_reorg has been called, we can't fix up expensive
683          constants by pushing them into memory so we must synthesise
684          them in-line, regardless of the cost.  This is only likely to
685          be more costly on chips that have load delay slots and we are
686          compiling without running the scheduler (so no splitting
687          occurred before the final instruction emission).
688
689          Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
690       */
691       if (! after_arm_reorg
692           && (arm_gen_constant (code, mode, val, target, source, 1, 0)
693               > arm_constant_limit + (code != SET)))
694         {
695           if (code == SET)
696             {
697               /* Currently SET is the only monadic value for CODE, all
698                  the rest are diadic.  */
699               emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (val)));
700               return 1;
701             }
702           else
703             {
704               rtx temp = subtargets ? gen_reg_rtx (mode) : target;
705
706               emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (val)));
707               /* For MINUS, the value is subtracted from, since we never
708                  have subtraction of a constant.  */
709               if (code == MINUS)
710                 emit_insn (gen_rtx_SET (VOIDmode, target,
711                                         gen_rtx (code, mode, temp, source)));
712               else
713                 emit_insn (gen_rtx_SET (VOIDmode, target,
714                                         gen_rtx (code, mode, source, temp)));
715               return 2;
716             }
717         }
718     }
719
720   return arm_gen_constant (code, mode, val, target, source, subtargets, 1);
721 }
722
723 /* As above, but extra parameter GENERATE which, if clear, suppresses
724    RTL generation.  */
725 int
726 arm_gen_constant (code, mode, val, target, source, subtargets, generate)
727      enum rtx_code code;
728      enum machine_mode mode;
729      HOST_WIDE_INT val;
730      rtx target;
731      rtx source;
732      int subtargets;
733      int generate;
734 {
735   int can_invert = 0;
736   int can_negate = 0;
737   int can_negate_initial = 0;
738   int can_shift = 0;
739   int i;
740   int num_bits_set = 0;
741   int set_sign_bit_copies = 0;
742   int clear_sign_bit_copies = 0;
743   int clear_zero_bit_copies = 0;
744   int set_zero_bit_copies = 0;
745   int insns = 0;
746   unsigned HOST_WIDE_INT temp1, temp2;
747   unsigned HOST_WIDE_INT remainder = val & 0xffffffff;
748
749   /* find out which operations are safe for a given CODE.  Also do a quick
750      check for degenerate cases; these can occur when DImode operations
751      are split.  */
752   switch (code)
753     {
754     case SET:
755       can_invert = 1;
756       can_shift = 1;
757       can_negate = 1;
758       break;
759
760     case PLUS:
761       can_negate = 1;
762       can_negate_initial = 1;
763       break;
764
765     case IOR:
766       if (remainder == 0xffffffff)
767         {
768           if (generate)
769             emit_insn (gen_rtx_SET (VOIDmode, target,
770                                     GEN_INT (ARM_SIGN_EXTEND (val))));
771           return 1;
772         }
773       if (remainder == 0)
774         {
775           if (reload_completed && rtx_equal_p (target, source))
776             return 0;
777           if (generate)
778             emit_insn (gen_rtx_SET (VOIDmode, target, source));
779           return 1;
780         }
781       break;
782
783     case AND:
784       if (remainder == 0)
785         {
786           if (generate)
787             emit_insn (gen_rtx_SET (VOIDmode, target, const0_rtx));
788           return 1;
789         }
790       if (remainder == 0xffffffff)
791         {
792           if (reload_completed && rtx_equal_p (target, source))
793             return 0;
794           if (generate)
795             emit_insn (gen_rtx_SET (VOIDmode, target, source));
796           return 1;
797         }
798       can_invert = 1;
799       break;
800
801     case XOR:
802       if (remainder == 0)
803         {
804           if (reload_completed && rtx_equal_p (target, source))
805             return 0;
806           if (generate)
807             emit_insn (gen_rtx_SET (VOIDmode, target, source));
808           return 1;
809         }
810       if (remainder == 0xffffffff)
811         {
812           if (generate)
813             emit_insn (gen_rtx_SET (VOIDmode, target,
814                                     gen_rtx_NOT (mode, source)));
815           return 1;
816         }
817
818       /* We don't know how to handle this yet below.  */
819       abort ();
820
821     case MINUS:
822       /* We treat MINUS as (val - source), since (source - val) is always
823          passed as (source + (-val)).  */
824       if (remainder == 0)
825         {
826           if (generate)
827             emit_insn (gen_rtx_SET (VOIDmode, target,
828                                     gen_rtx_NEG (mode, source)));
829           return 1;
830         }
831       if (const_ok_for_arm (val))
832         {
833           if (generate)
834             emit_insn (gen_rtx_SET (VOIDmode, target, 
835                                     gen_rtx_MINUS (mode, GEN_INT (val),
836                                                    source)));
837           return 1;
838         }
839       can_negate = 1;
840
841       break;
842
843     default:
844       abort ();
845     }
846
847   /* If we can do it in one insn get out quickly */
848   if (const_ok_for_arm (val)
849       || (can_negate_initial && const_ok_for_arm (-val))
850       || (can_invert && const_ok_for_arm (~val)))
851     {
852       if (generate)
853         emit_insn (gen_rtx_SET (VOIDmode, target,
854                                 (source ? gen_rtx (code, mode, source,
855                                                    GEN_INT (val))
856                                  : GEN_INT (val))));
857       return 1;
858     }
859
860
861   /* Calculate a few attributes that may be useful for specific
862      optimizations. */
863
864   for (i = 31; i >= 0; i--)
865     {
866       if ((remainder & (1 << i)) == 0)
867         clear_sign_bit_copies++;
868       else
869         break;
870     }
871
872   for (i = 31; i >= 0; i--)
873     {
874       if ((remainder & (1 << i)) != 0)
875         set_sign_bit_copies++;
876       else
877         break;
878     }
879
880   for (i = 0; i <= 31; i++)
881     {
882       if ((remainder & (1 << i)) == 0)
883         clear_zero_bit_copies++;
884       else
885         break;
886     }
887
888   for (i = 0; i <= 31; i++)
889     {
890       if ((remainder & (1 << i)) != 0)
891         set_zero_bit_copies++;
892       else
893         break;
894     }
895
896   switch (code)
897     {
898     case SET:
899       /* See if we can do this by sign_extending a constant that is known
900          to be negative.  This is a good, way of doing it, since the shift
901          may well merge into a subsequent insn.  */
902       if (set_sign_bit_copies > 1)
903         {
904           if (const_ok_for_arm
905               (temp1 = ARM_SIGN_EXTEND (remainder 
906                                         << (set_sign_bit_copies - 1))))
907             {
908               if (generate)
909                 {
910                   rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
911                   emit_insn (gen_rtx_SET (VOIDmode, new_src, 
912                                           GEN_INT (temp1)));
913                   emit_insn (gen_ashrsi3 (target, new_src, 
914                                           GEN_INT (set_sign_bit_copies - 1)));
915                 }
916               return 2;
917             }
918           /* For an inverted constant, we will need to set the low bits,
919              these will be shifted out of harm's way.  */
920           temp1 |= (1 << (set_sign_bit_copies - 1)) - 1;
921           if (const_ok_for_arm (~temp1))
922             {
923               if (generate)
924                 {
925                   rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
926                   emit_insn (gen_rtx_SET (VOIDmode, new_src,
927                                           GEN_INT (temp1)));
928                   emit_insn (gen_ashrsi3 (target, new_src, 
929                                           GEN_INT (set_sign_bit_copies - 1)));
930                 }
931               return 2;
932             }
933         }
934
935       /* See if we can generate this by setting the bottom (or the top)
936          16 bits, and then shifting these into the other half of the
937          word.  We only look for the simplest cases, to do more would cost
938          too much.  Be careful, however, not to generate this when the
939          alternative would take fewer insns.  */
940       if (val & 0xffff0000)
941         {
942           temp1 = remainder & 0xffff0000;
943           temp2 = remainder & 0x0000ffff;
944
945           /* Overlaps outside this range are best done using other methods. */
946           for (i = 9; i < 24; i++)
947             {
948               if ((((temp2 | (temp2 << i)) & 0xffffffff) == remainder)
949                   && ! const_ok_for_arm (temp2))
950                 {
951                   rtx new_src = (subtargets
952                                  ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
953                                  : target);
954                   insns = arm_gen_constant (code, mode, temp2, new_src,
955                                             source, subtargets, generate);
956                   source = new_src;
957                   if (generate)
958                     emit_insn (gen_rtx_SET
959                                (VOIDmode, target,
960                                 gen_rtx_IOR (mode,
961                                              gen_rtx_ASHIFT (mode, source,
962                                                              GEN_INT (i)),
963                                              source)));
964                   return insns + 1;
965                 }
966             }
967
968           /* Don't duplicate cases already considered. */
969           for (i = 17; i < 24; i++)
970             {
971               if (((temp1 | (temp1 >> i)) == remainder)
972                   && ! const_ok_for_arm (temp1))
973                 {
974                   rtx new_src = (subtargets
975                                  ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
976                                  : target);
977                   insns = arm_gen_constant (code, mode, temp1, new_src,
978                                             source, subtargets, generate);
979                   source = new_src;
980                   if (generate)
981                     emit_insn
982                       (gen_rtx_SET (VOIDmode, target,
983                                     gen_rtx_IOR
984                                     (mode,
985                                      gen_rtx_LSHIFTRT (mode, source,
986                                                        GEN_INT (i)),
987                                      source)));
988                   return insns + 1;
989                 }
990             }
991         }
992       break;
993
994     case IOR:
995     case XOR:
996       /* If we have IOR or XOR, and the constant can be loaded in a
997          single instruction, and we can find a temporary to put it in,
998          then this can be done in two instructions instead of 3-4.  */
999       if (subtargets
1000           /* TARGET can't be NULL if SUBTARGETS is 0 */
1001           || (reload_completed && ! reg_mentioned_p (target, source)))
1002         {
1003           if (const_ok_for_arm (ARM_SIGN_EXTEND (~ val)))
1004             {
1005               if (generate)
1006                 {
1007                   rtx sub = subtargets ? gen_reg_rtx (mode) : target;
1008
1009                   emit_insn (gen_rtx_SET (VOIDmode, sub, GEN_INT (val)));
1010                   emit_insn (gen_rtx_SET (VOIDmode, target, 
1011                                           gen_rtx (code, mode, source, sub)));
1012                 }
1013               return 2;
1014             }
1015         }
1016
1017       if (code == XOR)
1018         break;
1019
1020       if (set_sign_bit_copies > 8
1021           && (val & (-1 << (32 - set_sign_bit_copies))) == val)
1022         {
1023           if (generate)
1024             {
1025               rtx sub = subtargets ? gen_reg_rtx (mode) : target;
1026               rtx shift = GEN_INT (set_sign_bit_copies);
1027
1028               emit_insn (gen_rtx_SET (VOIDmode, sub,
1029                                       gen_rtx_NOT (mode, 
1030                                                    gen_rtx_ASHIFT (mode,
1031                                                                    source, 
1032                                                                    shift))));
1033               emit_insn (gen_rtx_SET (VOIDmode, target,
1034                                       gen_rtx_NOT (mode,
1035                                                    gen_rtx_LSHIFTRT (mode, sub,
1036                                                                      shift))));
1037             }
1038           return 2;
1039         }
1040
1041       if (set_zero_bit_copies > 8
1042           && (remainder & ((1 << set_zero_bit_copies) - 1)) == remainder)
1043         {
1044           if (generate)
1045             {
1046               rtx sub = subtargets ? gen_reg_rtx (mode) : target;
1047               rtx shift = GEN_INT (set_zero_bit_copies);
1048
1049               emit_insn (gen_rtx_SET (VOIDmode, sub,
1050                                       gen_rtx_NOT (mode,
1051                                                    gen_rtx_LSHIFTRT (mode,
1052                                                                      source,
1053                                                                      shift))));
1054               emit_insn (gen_rtx_SET (VOIDmode, target,
1055                                       gen_rtx_NOT (mode,
1056                                                    gen_rtx_ASHIFT (mode, sub,
1057                                                                    shift))));
1058             }
1059           return 2;
1060         }
1061
1062       if (const_ok_for_arm (temp1 = ARM_SIGN_EXTEND (~ val)))
1063         {
1064           if (generate)
1065             {
1066               rtx sub = subtargets ? gen_reg_rtx (mode) : target;
1067               emit_insn (gen_rtx_SET (VOIDmode, sub,
1068                                       gen_rtx_NOT (mode, source)));
1069               source = sub;
1070               if (subtargets)
1071                 sub = gen_reg_rtx (mode);
1072               emit_insn (gen_rtx_SET (VOIDmode, sub,
1073                                       gen_rtx_AND (mode, source, 
1074                                                    GEN_INT (temp1))));
1075               emit_insn (gen_rtx_SET (VOIDmode, target,
1076                                       gen_rtx_NOT (mode, sub)));
1077             }
1078           return 3;
1079         }
1080       break;
1081
1082     case AND:
1083       /* See if two shifts will do 2 or more insn's worth of work.  */
1084       if (clear_sign_bit_copies >= 16 && clear_sign_bit_copies < 24)
1085         {
1086           HOST_WIDE_INT shift_mask = ((0xffffffff 
1087                                        << (32 - clear_sign_bit_copies))
1088                                       & 0xffffffff);
1089
1090           if ((remainder | shift_mask) != 0xffffffff)
1091             {
1092               if (generate)
1093                 {
1094                   rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1095                   insns = arm_gen_constant (AND, mode, remainder | shift_mask,
1096                                             new_src, source, subtargets, 1);
1097                   source = new_src;
1098                 }
1099               else
1100                 {
1101                   rtx targ = subtargets ? NULL_RTX : target;
1102                   insns = arm_gen_constant (AND, mode, remainder | shift_mask,
1103                                             targ, source, subtargets, 0);
1104                 }
1105             }
1106
1107           if (generate)
1108             {
1109               rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1110               rtx shift = GEN_INT (clear_sign_bit_copies);
1111
1112               emit_insn (gen_ashlsi3 (new_src, source, shift));
1113               emit_insn (gen_lshrsi3 (target, new_src, shift));
1114             }
1115
1116           return insns + 2;
1117         }
1118
1119       if (clear_zero_bit_copies >= 16 && clear_zero_bit_copies < 24)
1120         {
1121           HOST_WIDE_INT shift_mask = (1 << clear_zero_bit_copies) - 1;
1122           
1123           if ((remainder | shift_mask) != 0xffffffff)
1124             {
1125               if (generate)
1126                 {
1127                   rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1128
1129                   insns = arm_gen_constant (AND, mode, remainder | shift_mask,
1130                                             new_src, source, subtargets, 1);
1131                   source = new_src;
1132                 }
1133               else
1134                 {
1135                   rtx targ = subtargets ? NULL_RTX : target;
1136
1137                   insns = arm_gen_constant (AND, mode, remainder | shift_mask,
1138                                             targ, source, subtargets, 0);
1139                 }
1140             }
1141
1142           if (generate)
1143             {
1144               rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1145               rtx shift = GEN_INT (clear_zero_bit_copies);
1146
1147               emit_insn (gen_lshrsi3 (new_src, source, shift));
1148               emit_insn (gen_ashlsi3 (target, new_src, shift));
1149             }
1150
1151           return insns + 2;
1152         }
1153
1154       break;
1155
1156     default:
1157       break;
1158     }
1159
1160   for (i = 0; i < 32; i++)
1161     if (remainder & (1 << i))
1162       num_bits_set++;
1163
1164   if (code == AND || (can_invert && num_bits_set > 16))
1165     remainder = (~remainder) & 0xffffffff;
1166   else if (code == PLUS && num_bits_set > 16)
1167     remainder = (-remainder) & 0xffffffff;
1168   else
1169     {
1170       can_invert = 0;
1171       can_negate = 0;
1172     }
1173
1174   /* Now try and find a way of doing the job in either two or three
1175      instructions.
1176      We start by looking for the largest block of zeros that are aligned on
1177      a 2-bit boundary, we then fill up the temps, wrapping around to the
1178      top of the word when we drop off the bottom.
1179      In the worst case this code should produce no more than four insns. */
1180   {
1181     int best_start = 0;
1182     int best_consecutive_zeros = 0;
1183
1184     for (i = 0; i < 32; i += 2)
1185       {
1186         int consecutive_zeros = 0;
1187
1188         if (! (remainder & (3 << i)))
1189           {
1190             while ((i < 32) && ! (remainder & (3 << i)))
1191               {
1192                 consecutive_zeros += 2;
1193                 i += 2;
1194               }
1195             if (consecutive_zeros > best_consecutive_zeros)
1196               {
1197                 best_consecutive_zeros = consecutive_zeros;
1198                 best_start = i - consecutive_zeros;
1199               }
1200             i -= 2;
1201           }
1202       }
1203
1204     /* Now start emitting the insns, starting with the one with the highest
1205        bit set: we do this so that the smallest number will be emitted last;
1206        this is more likely to be combinable with addressing insns. */
1207     i = best_start;
1208     do
1209       {
1210         int end;
1211
1212         if (i <= 0)
1213           i += 32;
1214         if (remainder & (3 << (i - 2)))
1215           {
1216             end = i - 8;
1217             if (end < 0)
1218               end += 32;
1219             temp1 = remainder & ((0x0ff << end)
1220                                  | ((i < end) ? (0xff >> (32 - end)) : 0));
1221             remainder &= ~temp1;
1222
1223             if (generate)
1224               {
1225                 rtx new_src;
1226
1227                 if (code == SET)
1228                   emit_insn (gen_rtx_SET (VOIDmode,
1229                                           new_src = (subtargets
1230                                                      ? gen_reg_rtx (mode)
1231                                                      : target),
1232                                           GEN_INT (can_invert
1233                                                    ? ~temp1 : temp1)));
1234                 else if (code == MINUS)
1235                   emit_insn (gen_rtx_SET (VOIDmode,
1236                                           new_src = (subtargets
1237                                                      ? gen_reg_rtx (mode)
1238                                                      : target),
1239                                           gen_rtx (code, mode, GEN_INT (temp1),
1240                                                    source)));
1241                 else
1242                   emit_insn (gen_rtx_SET (VOIDmode,
1243                                           new_src = (remainder
1244                                                      ? (subtargets
1245                                                         ? gen_reg_rtx (mode)
1246                                                         : target)
1247                                                      : target),
1248                                           gen_rtx (code, mode, source,
1249                                                    GEN_INT (can_invert ? ~temp1
1250                                                             : (can_negate
1251                                                                ? -temp1
1252                                                                : temp1)))));
1253                 source = new_src;
1254               }
1255
1256             if (code == SET)
1257               {
1258                 can_invert = 0;
1259                 code = PLUS;
1260               }
1261             else if (code == MINUS)
1262               code = PLUS;
1263
1264             insns++;
1265             i -= 6;
1266           }
1267         i -= 2;
1268       } while (remainder);
1269   }
1270   return insns;
1271 }
1272
1273 /* Canonicalize a comparison so that we are more likely to recognize it.
1274    This can be done for a few constant compares, where we can make the
1275    immediate value easier to load.  */
1276 enum rtx_code
1277 arm_canonicalize_comparison (code, op1)
1278      enum rtx_code code;
1279      rtx *op1;
1280 {
1281   unsigned HOST_WIDE_INT i = INTVAL (*op1);
1282
1283   switch (code)
1284     {
1285     case EQ:
1286     case NE:
1287       return code;
1288
1289     case GT:
1290     case LE:
1291       if (i != ((((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1))
1292                 - 1)
1293           && (const_ok_for_arm (i+1) || const_ok_for_arm (- (i+1))))
1294         {
1295           *op1 = GEN_INT (i+1);
1296           return code == GT ? GE : LT;
1297         }
1298       break;
1299
1300     case GE:
1301     case LT:
1302       if (i != (((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1))
1303           && (const_ok_for_arm (i-1) || const_ok_for_arm (- (i-1))))
1304         {
1305           *op1 = GEN_INT (i-1);
1306           return code == GE ? GT : LE;
1307         }
1308       break;
1309
1310     case GTU:
1311     case LEU:
1312       if (i != ~((unsigned HOST_WIDE_INT) 0)
1313           && (const_ok_for_arm (i+1) || const_ok_for_arm (- (i+1))))
1314         {
1315           *op1 = GEN_INT (i + 1);
1316           return code == GTU ? GEU : LTU;
1317         }
1318       break;
1319
1320     case GEU:
1321     case LTU:
1322       if (i != 0
1323           && (const_ok_for_arm (i - 1) || const_ok_for_arm (- (i - 1))))
1324         {
1325           *op1 = GEN_INT (i - 1);
1326           return code == GEU ? GTU : LEU;
1327         }
1328       break;
1329
1330     default:
1331       abort ();
1332     }
1333
1334   return code;
1335 }
1336
1337 /* Decide whether a type should be returned in memory (true)
1338    or in a register (false).  This is called by the macro
1339    RETURN_IN_MEMORY.  */
1340 int
1341 arm_return_in_memory (type)
1342      tree type;
1343 {
1344   if (! AGGREGATE_TYPE_P (type))
1345     {
1346       /* All simple types are returned in registers. */
1347       return 0;
1348     }
1349   else if (int_size_in_bytes (type) > 4)
1350     {
1351       /* All structures/unions bigger than one word are returned in memory. */
1352       return 1;
1353     }
1354   else if (TREE_CODE (type) == RECORD_TYPE)
1355     {
1356       tree field;
1357
1358       /* For a struct the APCS says that we must return in a register if
1359          every addressable element has an offset of zero.  For practical
1360          purposes this means that the structure can have at most one non
1361          bit-field element and that this element must be the first one in
1362          the structure.  */
1363
1364       /* Find the first field, ignoring non FIELD_DECL things which will
1365          have been created by C++.  */
1366       for (field = TYPE_FIELDS (type);
1367            field && TREE_CODE (field) != FIELD_DECL;
1368            field = TREE_CHAIN (field))
1369         continue;
1370       
1371       if (field == NULL)
1372         return 0; /* An empty structure.  Allowed by an extension to ANSI C. */
1373
1374       /* Now check the remaining fields, if any. */
1375       for (field = TREE_CHAIN (field);
1376            field;
1377            field = TREE_CHAIN (field))
1378         {
1379           if (TREE_CODE (field) != FIELD_DECL)
1380             continue;
1381           
1382           if (! DECL_BIT_FIELD_TYPE (field))
1383             return 1;
1384         }
1385
1386       return 0;
1387     }
1388   else if (TREE_CODE (type) == UNION_TYPE)
1389     {
1390       tree field;
1391
1392       /* Unions can be returned in registers if every element is
1393          integral, or can be returned in an integer register.  */
1394       for (field = TYPE_FIELDS (type);
1395            field;
1396            field = TREE_CHAIN (field))
1397         {
1398           if (TREE_CODE (field) != FIELD_DECL)
1399             continue;
1400
1401           if (FLOAT_TYPE_P (TREE_TYPE (field)))
1402             return 1;
1403           
1404           if (RETURN_IN_MEMORY (TREE_TYPE (field)))
1405             return 1;
1406         }
1407       
1408       return 0;
1409     }
1410   
1411   /* XXX Not sure what should be done for other aggregates, so put them in
1412      memory. */
1413   return 1;
1414 }
1415
1416 int
1417 legitimate_pic_operand_p (x)
1418      rtx x;
1419 {
1420   if (CONSTANT_P (x) && flag_pic
1421       && (GET_CODE (x) == SYMBOL_REF
1422           || (GET_CODE (x) == CONST
1423               && GET_CODE (XEXP (x, 0)) == PLUS
1424               && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)))
1425     return 0;
1426
1427   return 1;
1428 }
1429
1430 rtx
1431 legitimize_pic_address (orig, mode, reg)
1432      rtx orig;
1433      enum machine_mode mode;
1434      rtx reg;
1435 {
1436   if (GET_CODE (orig) == SYMBOL_REF)
1437     {
1438       rtx pic_ref, address;
1439       rtx insn;
1440       int subregs = 0;
1441
1442       if (reg == 0)
1443         {
1444           if (reload_in_progress || reload_completed)
1445             abort ();
1446           else
1447             reg = gen_reg_rtx (Pmode);
1448
1449           subregs = 1;
1450         }
1451
1452 #ifdef AOF_ASSEMBLER
1453       /* The AOF assembler can generate relocations for these directly, and
1454          understands that the PIC register has to be added into the offset.
1455          */
1456       insn = emit_insn (gen_pic_load_addr_based (reg, orig));
1457 #else
1458       if (subregs)
1459         address = gen_reg_rtx (Pmode);
1460       else
1461         address = reg;
1462
1463       emit_insn (gen_pic_load_addr (address, orig));
1464
1465       pic_ref = gen_rtx_MEM (Pmode,
1466                              gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
1467                                            address));
1468       RTX_UNCHANGING_P (pic_ref) = 1;
1469       insn = emit_move_insn (reg, pic_ref);
1470 #endif
1471       current_function_uses_pic_offset_table = 1;
1472       /* Put a REG_EQUAL note on this insn, so that it can be optimized
1473          by loop.  */
1474       REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig,
1475                                             REG_NOTES (insn));
1476       return reg;
1477     }
1478   else if (GET_CODE (orig) == CONST)
1479     {
1480       rtx base, offset;
1481
1482       if (GET_CODE (XEXP (orig, 0)) == PLUS
1483           && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
1484         return orig;
1485
1486       if (reg == 0)
1487         {
1488           if (reload_in_progress || reload_completed)
1489             abort ();
1490           else
1491             reg = gen_reg_rtx (Pmode);
1492         }
1493
1494       if (GET_CODE (XEXP (orig, 0)) == PLUS)
1495         {
1496           base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
1497           offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
1498                                            base == reg ? 0 : reg);
1499         }
1500       else
1501         abort ();
1502
1503       if (GET_CODE (offset) == CONST_INT)
1504         {
1505           /* The base register doesn't really matter, we only want to
1506              test the index for the appropriate mode.  */
1507           GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
1508
1509           if (! reload_in_progress && ! reload_completed)
1510             offset = force_reg (Pmode, offset);
1511           else
1512             abort ();
1513
1514         win:
1515           if (GET_CODE (offset) == CONST_INT)
1516             return plus_constant_for_output (base, INTVAL (offset));
1517         }
1518
1519       if (GET_MODE_SIZE (mode) > 4
1520           && (GET_MODE_CLASS (mode) == MODE_INT
1521               || TARGET_SOFT_FLOAT))
1522         {
1523           emit_insn (gen_addsi3 (reg, base, offset));
1524           return reg;
1525         }
1526
1527       return gen_rtx_PLUS (Pmode, base, offset);
1528     }
1529   else if (GET_CODE (orig) == LABEL_REF)
1530     current_function_uses_pic_offset_table = 1;
1531
1532   return orig;
1533 }
1534
1535 static rtx pic_rtx;
1536
1537 int
1538 is_pic(x)
1539      rtx x;
1540 {
1541   if (x == pic_rtx)
1542     return 1;
1543   return 0;
1544 }
1545
1546 void
1547 arm_finalize_pic ()
1548 {
1549 #ifndef AOF_ASSEMBLER
1550   rtx l1, pic_tmp, pic_tmp2, seq;
1551   rtx global_offset_table;
1552
1553   if (current_function_uses_pic_offset_table == 0)
1554     return;
1555
1556   if (! flag_pic)
1557     abort ();
1558
1559   start_sequence ();
1560   l1 = gen_label_rtx ();
1561
1562   global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1563   /* On the ARM the PC register contains 'dot + 8' at the time of the
1564      addition.  */
1565   pic_tmp = plus_constant (gen_rtx_LABEL_REF (Pmode, l1), 8);
1566   pic_tmp2 = gen_rtx_CONST (VOIDmode,
1567                             gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
1568
1569   pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
1570   
1571   emit_insn (gen_pic_load_addr (pic_offset_table_rtx, pic_rtx));
1572   emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx, l1));
1573
1574   seq = gen_sequence ();
1575   end_sequence ();
1576   emit_insn_after (seq, get_insns ());
1577
1578   /* Need to emit this whether or not we obey regdecls,
1579      since setjmp/longjmp can cause life info to screw up.  */
1580   emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
1581 #endif /* AOF_ASSEMBLER */
1582 }
1583
1584 #define REG_OR_SUBREG_REG(X)                                            \
1585   (GET_CODE (X) == REG                                                  \
1586    || (GET_CODE (X) == SUBREG && GET_CODE (SUBREG_REG (X)) == REG))
1587
1588 #define REG_OR_SUBREG_RTX(X)                    \
1589    (GET_CODE (X) == REG ? (X) : SUBREG_REG (X))
1590
1591 #define ARM_FRAME_RTX(X)                                \
1592   ((X) == frame_pointer_rtx || (X) == stack_pointer_rtx \
1593    || (X) == arg_pointer_rtx)
1594
1595 int
1596 arm_rtx_costs (x, code)
1597      rtx x;
1598      enum rtx_code code;
1599 {
1600   enum machine_mode mode = GET_MODE (x);
1601   enum rtx_code subcode;
1602   int extra_cost;
1603
1604   switch (code)
1605     {
1606     case MEM:
1607       /* Memory costs quite a lot for the first word, but subsequent words
1608          load at the equivalent of a single insn each.  */
1609       return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
1610               + (CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0));
1611
1612     case DIV:
1613     case MOD:
1614       return 100;
1615
1616     case ROTATE:
1617       if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG)
1618         return 4;
1619       /* Fall through */
1620     case ROTATERT:
1621       if (mode != SImode)
1622         return 8;
1623       /* Fall through */
1624     case ASHIFT: case LSHIFTRT: case ASHIFTRT:
1625       if (mode == DImode)
1626         return (8 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : 8)
1627                 + ((GET_CODE (XEXP (x, 0)) == REG 
1628                     || (GET_CODE (XEXP (x, 0)) == SUBREG
1629                         && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
1630                    ? 0 : 8));
1631       return (1 + ((GET_CODE (XEXP (x, 0)) == REG
1632                     || (GET_CODE (XEXP (x, 0)) == SUBREG
1633                         && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
1634                    ? 0 : 4)
1635               + ((GET_CODE (XEXP (x, 1)) == REG
1636                   || (GET_CODE (XEXP (x, 1)) == SUBREG
1637                       && GET_CODE (SUBREG_REG (XEXP (x, 1))) == REG)
1638                   || (GET_CODE (XEXP (x, 1)) == CONST_INT))
1639                  ? 0 : 4));
1640
1641     case MINUS:
1642       if (mode == DImode)
1643         return (4 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 8)
1644                 + ((REG_OR_SUBREG_REG (XEXP (x, 0))
1645                     || (GET_CODE (XEXP (x, 0)) == CONST_INT
1646                        && const_ok_for_arm (INTVAL (XEXP (x, 0)))))
1647                    ? 0 : 8));
1648
1649       if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1650         return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
1651                       || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
1652                           && const_double_rtx_ok_for_fpu (XEXP (x, 1))))
1653                      ? 0 : 8)
1654                 + ((REG_OR_SUBREG_REG (XEXP (x, 0))
1655                     || (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
1656                         && const_double_rtx_ok_for_fpu (XEXP (x, 0))))
1657                    ? 0 : 8));
1658
1659       if (((GET_CODE (XEXP (x, 0)) == CONST_INT
1660             && const_ok_for_arm (INTVAL (XEXP (x, 0)))
1661             && REG_OR_SUBREG_REG (XEXP (x, 1))))
1662           || (((subcode = GET_CODE (XEXP (x, 1))) == ASHIFT
1663                || subcode == ASHIFTRT || subcode == LSHIFTRT
1664                || subcode == ROTATE || subcode == ROTATERT
1665                || (subcode == MULT
1666                    && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
1667                    && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
1668                         (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
1669               && REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 0))
1670               && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 1))
1671                   || GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
1672               && REG_OR_SUBREG_REG (XEXP (x, 0))))
1673         return 1;
1674       /* Fall through */
1675
1676     case PLUS: 
1677       if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1678         return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
1679                 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
1680                     || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
1681                         && const_double_rtx_ok_for_fpu (XEXP (x, 1))))
1682                    ? 0 : 8));
1683
1684       /* Fall through */
1685     case AND: case XOR: case IOR: 
1686       extra_cost = 0;
1687
1688       /* Normally the frame registers will be spilt into reg+const during
1689          reload, so it is a bad idea to combine them with other instructions,
1690          since then they might not be moved outside of loops.  As a compromise
1691          we allow integration with ops that have a constant as their second
1692          operand.  */
1693       if ((REG_OR_SUBREG_REG (XEXP (x, 0))
1694            && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))
1695            && GET_CODE (XEXP (x, 1)) != CONST_INT)
1696           || (REG_OR_SUBREG_REG (XEXP (x, 0))
1697               && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))))
1698         extra_cost = 4;
1699
1700       if (mode == DImode)
1701         return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
1702                 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
1703                     || (GET_CODE (XEXP (x, 1)) == CONST_INT
1704                         && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
1705                    ? 0 : 8));
1706
1707       if (REG_OR_SUBREG_REG (XEXP (x, 0)))
1708         return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost)
1709                 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
1710                     || (GET_CODE (XEXP (x, 1)) == CONST_INT
1711                         && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
1712                    ? 0 : 4));
1713
1714       else if (REG_OR_SUBREG_REG (XEXP (x, 1)))
1715         return (1 + extra_cost
1716                 + ((((subcode = GET_CODE (XEXP (x, 0))) == ASHIFT
1717                      || subcode == LSHIFTRT || subcode == ASHIFTRT
1718                      || subcode == ROTATE || subcode == ROTATERT
1719                      || (subcode == MULT
1720                          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1721                          && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
1722                               (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
1723                     && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 0)))
1724                     && ((REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 1)))
1725                         || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
1726                    ? 0 : 4));
1727
1728       return 8;
1729
1730     case MULT:
1731       /* There is no point basing this on the tuning, since it is always the
1732          fast variant if it exists at all */
1733       if (arm_fast_multiply && mode == DImode
1734           && (GET_CODE (XEXP (x, 0)) == GET_CODE (XEXP (x, 1)))
1735           && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
1736               || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
1737         return 8;
1738
1739       if (GET_MODE_CLASS (mode) == MODE_FLOAT
1740           || mode == DImode)
1741         return 30;
1742
1743       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1744         {
1745           unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
1746                                       & (unsigned HOST_WIDE_INT) 0xffffffff);
1747           int add_cost = const_ok_for_arm (i) ? 4 : 8;
1748           int j;
1749           /* Tune as appropriate */ 
1750           int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
1751           
1752           for (j = 0; i && j < 32; j += booth_unit_size)
1753             {
1754               i >>= booth_unit_size;
1755               add_cost += 2;
1756             }
1757
1758           return add_cost;
1759         }
1760
1761       return (((tune_flags & FL_FAST_MULT) ? 8 : 30)
1762               + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
1763               + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4));
1764
1765     case TRUNCATE:
1766       if (arm_fast_multiply && mode == SImode
1767           && GET_CODE (XEXP (x, 0)) == LSHIFTRT
1768           && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
1769           && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
1770               == GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)))
1771           && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
1772               || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND))
1773         return 8;
1774       return 99;
1775
1776     case NEG:
1777       if (GET_MODE_CLASS (mode) == MODE_FLOAT)
1778         return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6);
1779       /* Fall through */
1780     case NOT:
1781       if (mode == DImode)
1782         return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
1783
1784       return 1 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
1785
1786     case IF_THEN_ELSE:
1787       if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
1788         return 14;
1789       return 2;
1790
1791     case COMPARE:
1792       return 1;
1793
1794     case ABS:
1795       return 4 + (mode == DImode ? 4 : 0);
1796
1797     case SIGN_EXTEND:
1798       if (GET_MODE (XEXP (x, 0)) == QImode)
1799         return (4 + (mode == DImode ? 4 : 0)
1800                 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
1801       /* Fall through */
1802     case ZERO_EXTEND:
1803       switch (GET_MODE (XEXP (x, 0)))
1804         {
1805         case QImode:
1806           return (1 + (mode == DImode ? 4 : 0)
1807                   + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
1808
1809         case HImode:
1810           return (4 + (mode == DImode ? 4 : 0)
1811                   + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
1812
1813         case SImode:
1814           return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
1815
1816         default:
1817           break;
1818         }
1819       abort ();
1820
1821     default:
1822       return 99;
1823     }
1824 }
1825
1826 int
1827 arm_adjust_cost (insn, link, dep, cost)
1828      rtx insn;
1829      rtx link;
1830      rtx dep;
1831      int cost;
1832 {
1833   rtx i_pat, d_pat;
1834
1835   /* XXX This is not strictly true for the FPA. */
1836   if (REG_NOTE_KIND(link) == REG_DEP_ANTI
1837       || REG_NOTE_KIND(link) == REG_DEP_OUTPUT)
1838     return 0;
1839
1840   if ((i_pat = single_set (insn)) != NULL
1841       && GET_CODE (SET_SRC (i_pat)) == MEM
1842       && (d_pat = single_set (dep)) != NULL
1843       && GET_CODE (SET_DEST (d_pat)) == MEM)
1844     {
1845       /* This is a load after a store, there is no conflict if the load reads
1846          from a cached area.  Assume that loads from the stack, and from the
1847          constant pool are cached, and that others will miss.  This is a 
1848          hack. */
1849       
1850 /*       debug_rtx (insn);
1851       debug_rtx (dep);
1852       debug_rtx (link);
1853       fprintf (stderr, "costs %d\n", cost); */
1854
1855       if (CONSTANT_POOL_ADDRESS_P (XEXP (SET_SRC (i_pat), 0))
1856           || reg_mentioned_p (stack_pointer_rtx, XEXP (SET_SRC (i_pat), 0))
1857           || reg_mentioned_p (frame_pointer_rtx, XEXP (SET_SRC (i_pat), 0))
1858           || reg_mentioned_p (hard_frame_pointer_rtx, 
1859                               XEXP (SET_SRC (i_pat), 0)))
1860         {
1861 /*        fprintf (stderr, "***** Now 1\n"); */
1862           return 1;
1863         }
1864     }
1865
1866   return cost;
1867 }
1868
1869 /* This code has been fixed for cross compilation. */
1870
1871 static int fpa_consts_inited = 0;
1872
1873 char *strings_fpa[8] = {
1874   "0",   "1",   "2",   "3",
1875   "4",   "5",   "0.5", "10"
1876 };
1877
1878 static REAL_VALUE_TYPE values_fpa[8];
1879
1880 static void
1881 init_fpa_table ()
1882 {
1883   int i;
1884   REAL_VALUE_TYPE r;
1885
1886   for (i = 0; i < 8; i++)
1887     {
1888       r = REAL_VALUE_ATOF (strings_fpa[i], DFmode);
1889       values_fpa[i] = r;
1890     }
1891
1892   fpa_consts_inited = 1;
1893 }
1894
1895 /* Return TRUE if rtx X is a valid immediate FPU constant. */
1896
1897 int
1898 const_double_rtx_ok_for_fpu (x)
1899      rtx x;
1900 {
1901   REAL_VALUE_TYPE r;
1902   int i;
1903   
1904   if (!fpa_consts_inited)
1905     init_fpa_table ();
1906   
1907   REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1908   if (REAL_VALUE_MINUS_ZERO (r))
1909     return 0;
1910
1911   for (i = 0; i < 8; i++)
1912     if (REAL_VALUES_EQUAL (r, values_fpa[i]))
1913       return 1;
1914
1915   return 0;
1916 }
1917
1918 /* Return TRUE if rtx X is a valid immediate FPU constant. */
1919
1920 int
1921 neg_const_double_rtx_ok_for_fpu (x)
1922      rtx x;
1923 {
1924   REAL_VALUE_TYPE r;
1925   int i;
1926   
1927   if (!fpa_consts_inited)
1928     init_fpa_table ();
1929   
1930   REAL_VALUE_FROM_CONST_DOUBLE (r, x);
1931   r = REAL_VALUE_NEGATE (r);
1932   if (REAL_VALUE_MINUS_ZERO (r))
1933     return 0;
1934
1935   for (i = 0; i < 8; i++)
1936     if (REAL_VALUES_EQUAL (r, values_fpa[i]))
1937       return 1;
1938
1939   return 0;
1940 }
1941 \f
1942 /* Predicates for `match_operand' and `match_operator'.  */
1943
1944 /* s_register_operand is the same as register_operand, but it doesn't accept
1945    (SUBREG (MEM)...).
1946
1947    This function exists because at the time it was put in it led to better
1948    code.  SUBREG(MEM) always needs a reload in the places where
1949    s_register_operand is used, and this seemed to lead to excessive
1950    reloading.  */
1951
1952 int
1953 s_register_operand (op, mode)
1954      register rtx op;
1955      enum machine_mode mode;
1956 {
1957   if (GET_MODE (op) != mode && mode != VOIDmode)
1958     return 0;
1959
1960   if (GET_CODE (op) == SUBREG)
1961     op = SUBREG_REG (op);
1962
1963   /* We don't consider registers whose class is NO_REGS
1964      to be a register operand.  */
1965   return (GET_CODE (op) == REG
1966           && (REGNO (op) >= FIRST_PSEUDO_REGISTER
1967               || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
1968 }
1969
1970 /* Only accept reg, subreg(reg), const_int.  */
1971
1972 int
1973 reg_or_int_operand (op, mode)
1974      register rtx op;
1975      enum machine_mode mode;
1976 {
1977   if (GET_CODE (op) == CONST_INT)
1978     return 1;
1979
1980   if (GET_MODE (op) != mode && mode != VOIDmode)
1981     return 0;
1982
1983   if (GET_CODE (op) == SUBREG)
1984     op = SUBREG_REG (op);
1985
1986   /* We don't consider registers whose class is NO_REGS
1987      to be a register operand.  */
1988   return (GET_CODE (op) == REG
1989           && (REGNO (op) >= FIRST_PSEUDO_REGISTER
1990               || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
1991 }
1992
1993 /* Return 1 if OP is an item in memory, given that we are in reload.  */
1994
1995 int
1996 reload_memory_operand (op, mode)
1997      rtx op;
1998      enum machine_mode mode ATTRIBUTE_UNUSED;
1999 {
2000   int regno = true_regnum (op);
2001
2002   return (! CONSTANT_P (op)
2003           && (regno == -1
2004               || (GET_CODE (op) == REG
2005                   && REGNO (op) >= FIRST_PSEUDO_REGISTER)));
2006 }
2007
2008 /* Return 1 if OP is a valid memory address, but not valid for a signed byte
2009    memory access (architecture V4) */
2010 int
2011 bad_signed_byte_operand (op, mode)
2012      rtx op;
2013      enum machine_mode mode;
2014 {
2015   if (! memory_operand (op, mode) || GET_CODE (op) != MEM)
2016     return 0;
2017
2018   op = XEXP (op, 0);
2019
2020   /* A sum of anything more complex than reg + reg or reg + const is bad */
2021   if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
2022       && (! s_register_operand (XEXP (op, 0), VOIDmode)
2023           || (! s_register_operand (XEXP (op, 1), VOIDmode)
2024               && GET_CODE (XEXP (op, 1)) != CONST_INT)))
2025     return 1;
2026
2027   /* Big constants are also bad */
2028   if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT
2029       && (INTVAL (XEXP (op, 1)) > 0xff
2030           || -INTVAL (XEXP (op, 1)) > 0xff))
2031     return 1;
2032
2033   /* Everything else is good, or can will automatically be made so. */
2034   return 0;
2035 }
2036
2037 /* Return TRUE for valid operands for the rhs of an ARM instruction.  */
2038
2039 int
2040 arm_rhs_operand (op, mode)
2041      rtx op;
2042      enum machine_mode mode;
2043 {
2044   return (s_register_operand (op, mode)
2045           || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))));
2046 }
2047
2048 /* Return TRUE for valid operands for the rhs of an ARM instruction, or a load.
2049  */
2050
2051 int
2052 arm_rhsm_operand (op, mode)
2053      rtx op;
2054      enum machine_mode mode;
2055 {
2056   return (s_register_operand (op, mode)
2057           || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))
2058           || memory_operand (op, mode));
2059 }
2060
2061 /* Return TRUE for valid operands for the rhs of an ARM instruction, or if a
2062    constant that is valid when negated.  */
2063
2064 int
2065 arm_add_operand (op, mode)
2066      rtx op;
2067      enum machine_mode mode;
2068 {
2069   return (s_register_operand (op, mode)
2070           || (GET_CODE (op) == CONST_INT
2071               && (const_ok_for_arm (INTVAL (op))
2072                   || const_ok_for_arm (-INTVAL (op)))));
2073 }
2074
2075 int
2076 arm_not_operand (op, mode)
2077      rtx op;
2078      enum machine_mode mode;
2079 {
2080   return (s_register_operand (op, mode)
2081           || (GET_CODE (op) == CONST_INT
2082               && (const_ok_for_arm (INTVAL (op))
2083                   || const_ok_for_arm (~INTVAL (op)))));
2084 }
2085
2086 /* Return TRUE if the operand is a memory reference which contains an
2087    offsettable address.  */
2088 int
2089 offsettable_memory_operand (op, mode)
2090      register rtx op;
2091      enum machine_mode mode;
2092 {
2093   if (mode == VOIDmode)
2094     mode = GET_MODE (op);
2095
2096   return (mode == GET_MODE (op)
2097           && GET_CODE (op) == MEM
2098           && offsettable_address_p (reload_completed | reload_in_progress,
2099                                     mode, XEXP (op, 0)));
2100 }
2101
2102 /* Return TRUE if the operand is a memory reference which is, or can be
2103    made word aligned by adjusting the offset.  */
2104 int
2105 alignable_memory_operand (op, mode)
2106      register rtx op;
2107      enum machine_mode mode;
2108 {
2109   rtx reg;
2110
2111   if (mode == VOIDmode)
2112     mode = GET_MODE (op);
2113
2114   if (mode != GET_MODE (op) || GET_CODE (op) != MEM)
2115     return 0;
2116
2117   op = XEXP (op, 0);
2118
2119   return ((GET_CODE (reg = op) == REG
2120            || (GET_CODE (op) == SUBREG
2121                && GET_CODE (reg = SUBREG_REG (op)) == REG)
2122            || (GET_CODE (op) == PLUS
2123                && GET_CODE (XEXP (op, 1)) == CONST_INT
2124                && (GET_CODE (reg = XEXP (op, 0)) == REG
2125                    || (GET_CODE (XEXP (op, 0)) == SUBREG
2126                        && GET_CODE (reg = SUBREG_REG (XEXP (op, 0))) == REG))))
2127           && REGNO_POINTER_ALIGN (REGNO (reg)) >= 4);
2128 }
2129
2130 /* Similar to s_register_operand, but does not allow hard integer 
2131    registers.  */
2132 int
2133 f_register_operand (op, mode)
2134      register rtx op;
2135      enum machine_mode mode;
2136 {
2137   if (GET_MODE (op) != mode && mode != VOIDmode)
2138     return 0;
2139
2140   if (GET_CODE (op) == SUBREG)
2141     op = SUBREG_REG (op);
2142
2143   /* We don't consider registers whose class is NO_REGS
2144      to be a register operand.  */
2145   return (GET_CODE (op) == REG
2146           && (REGNO (op) >= FIRST_PSEUDO_REGISTER
2147               || REGNO_REG_CLASS (REGNO (op)) == FPU_REGS));
2148 }
2149
2150 /* Return TRUE for valid operands for the rhs of an FPU instruction.  */
2151
2152 int
2153 fpu_rhs_operand (op, mode)
2154      rtx op;
2155      enum machine_mode mode;
2156 {
2157   if (s_register_operand (op, mode))
2158     return TRUE;
2159   else if (GET_CODE (op) == CONST_DOUBLE)
2160     return (const_double_rtx_ok_for_fpu (op));
2161
2162   return FALSE;
2163 }
2164
2165 int
2166 fpu_add_operand (op, mode)
2167      rtx op;
2168      enum machine_mode mode;
2169 {
2170   if (s_register_operand (op, mode))
2171     return TRUE;
2172   else if (GET_CODE (op) == CONST_DOUBLE)
2173     return (const_double_rtx_ok_for_fpu (op) 
2174             || neg_const_double_rtx_ok_for_fpu (op));
2175
2176   return FALSE;
2177 }
2178
2179 /* Return nonzero if OP is a constant power of two.  */
2180
2181 int
2182 power_of_two_operand (op, mode)
2183      rtx op;
2184      enum machine_mode mode ATTRIBUTE_UNUSED;
2185 {
2186   if (GET_CODE (op) == CONST_INT)
2187     {
2188       HOST_WIDE_INT value = INTVAL(op);
2189       return value != 0  &&  (value & (value - 1)) == 0;
2190     }
2191   return FALSE;
2192 }
2193
2194 /* Return TRUE for a valid operand of a DImode operation.
2195    Either: REG, CONST_DOUBLE or MEM(DImode_address).
2196    Note that this disallows MEM(REG+REG), but allows
2197    MEM(PRE/POST_INC/DEC(REG)).  */
2198
2199 int
2200 di_operand (op, mode)
2201      rtx op;
2202      enum machine_mode mode;
2203 {
2204   if (s_register_operand (op, mode))
2205     return TRUE;
2206
2207   switch (GET_CODE (op))
2208     {
2209     case CONST_DOUBLE:
2210     case CONST_INT:
2211       return TRUE;
2212
2213     case MEM:
2214       return memory_address_p (DImode, XEXP (op, 0));
2215
2216     default:
2217       return FALSE;
2218     }
2219 }
2220
2221 /* Return TRUE for a valid operand of a DFmode operation when -msoft-float.
2222    Either: REG, CONST_DOUBLE or MEM(DImode_address).
2223    Note that this disallows MEM(REG+REG), but allows
2224    MEM(PRE/POST_INC/DEC(REG)).  */
2225
2226 int
2227 soft_df_operand (op, mode)
2228      rtx op;
2229      enum machine_mode mode;
2230 {
2231   if (s_register_operand (op, mode))
2232     return TRUE;
2233
2234   switch (GET_CODE (op))
2235     {
2236     case CONST_DOUBLE:
2237       return TRUE;
2238
2239     case MEM:
2240       return memory_address_p (DFmode, XEXP (op, 0));
2241
2242     default:
2243       return FALSE;
2244     }
2245 }
2246
2247 /* Return TRUE for valid index operands. */
2248
2249 int
2250 index_operand (op, mode)
2251      rtx op;
2252      enum machine_mode mode;
2253 {
2254   return (s_register_operand(op, mode)
2255           || (immediate_operand (op, mode)
2256               && INTVAL (op) < 4096 && INTVAL (op) > -4096));
2257 }
2258
2259 /* Return TRUE for valid shifts by a constant. This also accepts any
2260    power of two on the (somewhat overly relaxed) assumption that the
2261    shift operator in this case was a mult. */
2262
2263 int
2264 const_shift_operand (op, mode)
2265      rtx op;
2266      enum machine_mode mode;
2267 {
2268   return (power_of_two_operand (op, mode)
2269           || (immediate_operand (op, mode)
2270               && (INTVAL (op) < 32 && INTVAL (op) > 0)));
2271 }
2272
2273 /* Return TRUE for arithmetic operators which can be combined with a multiply
2274    (shift).  */
2275
2276 int
2277 shiftable_operator (x, mode)
2278      rtx x;
2279      enum machine_mode mode;
2280 {
2281   if (GET_MODE (x) != mode)
2282     return FALSE;
2283   else
2284     {
2285       enum rtx_code code = GET_CODE (x);
2286
2287       return (code == PLUS || code == MINUS
2288               || code == IOR || code == XOR || code == AND);
2289     }
2290 }
2291
2292 /* Return TRUE for shift operators. */
2293
2294 int
2295 shift_operator (x, mode)
2296      rtx x;
2297      enum machine_mode mode;
2298 {
2299   if (GET_MODE (x) != mode)
2300     return FALSE;
2301   else
2302     {
2303       enum rtx_code code = GET_CODE (x);
2304
2305       if (code == MULT)
2306         return power_of_two_operand (XEXP (x, 1), mode);
2307
2308       return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT
2309               || code == ROTATERT);
2310     }
2311 }
2312
2313 int equality_operator (x, mode)
2314      rtx x;
2315      enum machine_mode mode ATTRIBUTE_UNUSED;
2316 {
2317   return GET_CODE (x) == EQ || GET_CODE (x) == NE;
2318 }
2319
2320 /* Return TRUE for SMIN SMAX UMIN UMAX operators. */
2321
2322 int
2323 minmax_operator (x, mode)
2324      rtx x;
2325      enum machine_mode mode;
2326 {
2327   enum rtx_code code = GET_CODE (x);
2328
2329   if (GET_MODE (x) != mode)
2330     return FALSE;
2331
2332   return code == SMIN || code == SMAX || code == UMIN || code == UMAX;
2333 }
2334
2335 /* return TRUE if x is EQ or NE */
2336
2337 /* Return TRUE if this is the condition code register, if we aren't given
2338    a mode, accept any class CCmode register */
2339
2340 int
2341 cc_register (x, mode)
2342      rtx x;
2343      enum machine_mode mode;
2344 {
2345   if (mode == VOIDmode)
2346     {
2347       mode = GET_MODE (x);
2348       if (GET_MODE_CLASS (mode) != MODE_CC)
2349         return FALSE;
2350     }
2351
2352   if (mode == GET_MODE (x) && GET_CODE (x) == REG && REGNO (x) == 24)
2353     return TRUE;
2354
2355   return FALSE;
2356 }
2357
2358 /* Return TRUE if this is the condition code register, if we aren't given
2359    a mode, accept any class CCmode register which indicates a dominance
2360    expression.  */
2361
2362 int
2363 dominant_cc_register (x, mode)
2364      rtx x;
2365      enum machine_mode mode;
2366 {
2367   if (mode == VOIDmode)
2368     {
2369       mode = GET_MODE (x);
2370       if (GET_MODE_CLASS (mode) != MODE_CC)
2371         return FALSE;
2372     }
2373
2374   if (mode != CC_DNEmode && mode != CC_DEQmode
2375       && mode != CC_DLEmode && mode != CC_DLTmode
2376       && mode != CC_DGEmode && mode != CC_DGTmode
2377       && mode != CC_DLEUmode && mode != CC_DLTUmode
2378       && mode != CC_DGEUmode && mode != CC_DGTUmode)
2379     return FALSE;
2380
2381   if (mode == GET_MODE (x) && GET_CODE (x) == REG && REGNO (x) == 24)
2382     return TRUE;
2383
2384   return FALSE;
2385 }
2386
2387 /* Return TRUE if X references a SYMBOL_REF.  */
2388 int
2389 symbol_mentioned_p (x)
2390      rtx x;
2391 {
2392   register char *fmt;
2393   register int i;
2394
2395   if (GET_CODE (x) == SYMBOL_REF)
2396     return 1;
2397
2398   fmt = GET_RTX_FORMAT (GET_CODE (x));
2399   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
2400     {
2401       if (fmt[i] == 'E')
2402         {
2403           register int j;
2404
2405           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2406             if (symbol_mentioned_p (XVECEXP (x, i, j)))
2407               return 1;
2408         }
2409       else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i)))
2410         return 1;
2411     }
2412
2413   return 0;
2414 }
2415
2416 /* Return TRUE if X references a LABEL_REF.  */
2417 int
2418 label_mentioned_p (x)
2419      rtx x;
2420 {
2421   register char *fmt;
2422   register int i;
2423
2424   if (GET_CODE (x) == LABEL_REF)
2425     return 1;
2426
2427   fmt = GET_RTX_FORMAT (GET_CODE (x));
2428   for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
2429     {
2430       if (fmt[i] == 'E')
2431         {
2432           register int j;
2433
2434           for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2435             if (label_mentioned_p (XVECEXP (x, i, j)))
2436               return 1;
2437         }
2438       else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i)))
2439         return 1;
2440     }
2441
2442   return 0;
2443 }
2444
2445 enum rtx_code
2446 minmax_code (x)
2447      rtx x;
2448 {
2449   enum rtx_code code = GET_CODE (x);
2450
2451   if (code == SMAX)
2452     return GE;
2453   else if (code == SMIN)
2454     return LE;
2455   else if (code == UMIN)
2456     return LEU;
2457   else if (code == UMAX)
2458     return GEU;
2459
2460   abort ();
2461 }
2462
2463 /* Return 1 if memory locations are adjacent */
2464
2465 int
2466 adjacent_mem_locations (a, b)
2467      rtx a, b;
2468 {
2469   int val0 = 0, val1 = 0;
2470   int reg0, reg1;
2471   
2472   if ((GET_CODE (XEXP (a, 0)) == REG
2473        || (GET_CODE (XEXP (a, 0)) == PLUS
2474            && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
2475       && (GET_CODE (XEXP (b, 0)) == REG
2476           || (GET_CODE (XEXP (b, 0)) == PLUS
2477               && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
2478     {
2479       if (GET_CODE (XEXP (a, 0)) == PLUS)
2480         {
2481           reg0 = REGNO (XEXP (XEXP (a, 0), 0));
2482           val0 = INTVAL (XEXP (XEXP (a, 0), 1));
2483         }
2484       else
2485         reg0 = REGNO (XEXP (a, 0));
2486       if (GET_CODE (XEXP (b, 0)) == PLUS)
2487         {
2488           reg1 = REGNO (XEXP (XEXP (b, 0), 0));
2489           val1 = INTVAL (XEXP (XEXP (b, 0), 1));
2490         }
2491       else
2492         reg1 = REGNO (XEXP (b, 0));
2493       return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
2494     }
2495   return 0;
2496 }
2497
2498 /* Return 1 if OP is a load multiple operation.  It is known to be
2499    parallel and the first section will be tested. */
2500
2501 int
2502 load_multiple_operation (op, mode)
2503      rtx op;
2504      enum machine_mode mode ATTRIBUTE_UNUSED;
2505 {
2506   HOST_WIDE_INT count = XVECLEN (op, 0);
2507   int dest_regno;
2508   rtx src_addr;
2509   HOST_WIDE_INT i = 1, base = 0;
2510   rtx elt;
2511
2512   if (count <= 1
2513       || GET_CODE (XVECEXP (op, 0, 0)) != SET)
2514     return 0;
2515
2516   /* Check to see if this might be a write-back */
2517   if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
2518     {
2519       i++;
2520       base = 1;
2521
2522       /* Now check it more carefully */
2523       if (GET_CODE (SET_DEST (elt)) != REG
2524           || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
2525           || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
2526           || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
2527           || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 2) * 4
2528           || GET_CODE (XVECEXP (op, 0, count - 1)) != CLOBBER
2529           || GET_CODE (XEXP (XVECEXP (op, 0, count - 1), 0)) != REG
2530           || REGNO (XEXP (XVECEXP (op, 0, count - 1), 0))
2531               != REGNO (SET_DEST (elt)))
2532         return 0;
2533
2534       count--;
2535     }
2536
2537   /* Perform a quick check so we don't blow up below.  */
2538   if (count <= i
2539       || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
2540       || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
2541       || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
2542     return 0;
2543
2544   dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
2545   src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
2546
2547   for (; i < count; i++)
2548     {
2549       elt = XVECEXP (op, 0, i);
2550
2551       if (GET_CODE (elt) != SET
2552           || GET_CODE (SET_DEST (elt)) != REG
2553           || GET_MODE (SET_DEST (elt)) != SImode
2554           || REGNO (SET_DEST (elt)) != dest_regno + i - base
2555           || GET_CODE (SET_SRC (elt)) != MEM
2556           || GET_MODE (SET_SRC (elt)) != SImode
2557           || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
2558           || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
2559           || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
2560           || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)
2561         return 0;
2562     }
2563
2564   return 1;
2565 }
2566
2567 /* Return 1 if OP is a store multiple operation.  It is known to be
2568    parallel and the first section will be tested. */
2569
2570 int
2571 store_multiple_operation (op, mode)
2572      rtx op;
2573      enum machine_mode mode ATTRIBUTE_UNUSED;
2574 {
2575   HOST_WIDE_INT count = XVECLEN (op, 0);
2576   int src_regno;
2577   rtx dest_addr;
2578   HOST_WIDE_INT i = 1, base = 0;
2579   rtx elt;
2580
2581   if (count <= 1
2582       || GET_CODE (XVECEXP (op, 0, 0)) != SET)
2583     return 0;
2584
2585   /* Check to see if this might be a write-back */
2586   if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
2587     {
2588       i++;
2589       base = 1;
2590
2591       /* Now check it more carefully */
2592       if (GET_CODE (SET_DEST (elt)) != REG
2593           || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
2594           || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
2595           || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
2596           || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 2) * 4
2597           || GET_CODE (XVECEXP (op, 0, count - 1)) != CLOBBER
2598           || GET_CODE (XEXP (XVECEXP (op, 0, count - 1), 0)) != REG
2599           || REGNO (XEXP (XVECEXP (op, 0, count - 1), 0))
2600               != REGNO (SET_DEST (elt)))
2601         return 0;
2602
2603       count--;
2604     }
2605
2606   /* Perform a quick check so we don't blow up below.  */
2607   if (count <= i
2608       || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
2609       || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
2610       || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
2611     return 0;
2612
2613   src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
2614   dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
2615
2616   for (; i < count; i++)
2617     {
2618       elt = XVECEXP (op, 0, i);
2619
2620       if (GET_CODE (elt) != SET
2621           || GET_CODE (SET_SRC (elt)) != REG
2622           || GET_MODE (SET_SRC (elt)) != SImode
2623           || REGNO (SET_SRC (elt)) != src_regno + i - base
2624           || GET_CODE (SET_DEST (elt)) != MEM
2625           || GET_MODE (SET_DEST (elt)) != SImode
2626           || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
2627           || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
2628           || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
2629           || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)
2630         return 0;
2631     }
2632
2633   return 1;
2634 }
2635
2636 int
2637 load_multiple_sequence (operands, nops, regs, base, load_offset)
2638      rtx *operands;
2639      int nops;
2640      int *regs;
2641      int *base;
2642      HOST_WIDE_INT *load_offset;
2643 {
2644   int unsorted_regs[4];
2645   HOST_WIDE_INT unsorted_offsets[4];
2646   int order[4];
2647   int base_reg = -1;
2648   int i;
2649
2650   /* Can only handle 2, 3, or 4 insns at present, though could be easily
2651      extended if required.  */
2652   if (nops < 2 || nops > 4)
2653     abort ();
2654
2655   /* Loop over the operands and check that the memory references are
2656      suitable (ie immediate offsets from the same base register).  At
2657      the same time, extract the target register, and the memory
2658      offsets.  */
2659   for (i = 0; i < nops; i++)
2660     {
2661       rtx reg;
2662       rtx offset;
2663
2664       /* Convert a subreg of a mem into the mem itself.  */
2665       if (GET_CODE (operands[nops + i]) == SUBREG)
2666         operands[nops + i] = alter_subreg(operands[nops + i]);
2667
2668       if (GET_CODE (operands[nops + i]) != MEM)
2669         abort ();
2670
2671       /* Don't reorder volatile memory references; it doesn't seem worth
2672          looking for the case where the order is ok anyway.  */
2673       if (MEM_VOLATILE_P (operands[nops + i]))
2674         return 0;
2675
2676       offset = const0_rtx;
2677
2678       if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG
2679            || (GET_CODE (reg) == SUBREG
2680                && GET_CODE (reg = SUBREG_REG (reg)) == REG))
2681           || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
2682               && ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))
2683                    == REG)
2684                   || (GET_CODE (reg) == SUBREG
2685                       && GET_CODE (reg = SUBREG_REG (reg)) == REG))
2686               && (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))
2687                   == CONST_INT)))
2688         {
2689           if (i == 0)
2690             {
2691               base_reg = REGNO(reg);
2692               unsorted_regs[0] = (GET_CODE (operands[i]) == REG
2693                                   ? REGNO (operands[i])
2694                                   : REGNO (SUBREG_REG (operands[i])));
2695               order[0] = 0;
2696             }
2697           else 
2698             {
2699               if (base_reg != REGNO (reg))
2700                 /* Not addressed from the same base register.  */
2701                 return 0;
2702
2703               unsorted_regs[i] = (GET_CODE (operands[i]) == REG
2704                                   ? REGNO (operands[i])
2705                                   : REGNO (SUBREG_REG (operands[i])));
2706               if (unsorted_regs[i] < unsorted_regs[order[0]])
2707                 order[0] = i;
2708             }
2709
2710           /* If it isn't an integer register, or if it overwrites the
2711              base register but isn't the last insn in the list, then
2712              we can't do this.  */
2713           if (unsorted_regs[i] < 0 || unsorted_regs[i] > 14
2714               || (i != nops - 1 && unsorted_regs[i] == base_reg))
2715             return 0;
2716
2717           unsorted_offsets[i] = INTVAL (offset);
2718         }
2719       else
2720         /* Not a suitable memory address.  */
2721         return 0;
2722     }
2723
2724   /* All the useful information has now been extracted from the
2725      operands into unsorted_regs and unsorted_offsets; additionally,
2726      order[0] has been set to the lowest numbered register in the
2727      list.  Sort the registers into order, and check that the memory
2728      offsets are ascending and adjacent.  */
2729
2730   for (i = 1; i < nops; i++)
2731     {
2732       int j;
2733
2734       order[i] = order[i - 1];
2735       for (j = 0; j < nops; j++)
2736         if (unsorted_regs[j] > unsorted_regs[order[i - 1]]
2737             && (order[i] == order[i - 1]
2738                 || unsorted_regs[j] < unsorted_regs[order[i]]))
2739           order[i] = j;
2740
2741       /* Have we found a suitable register? if not, one must be used more
2742          than once.  */
2743       if (order[i] == order[i - 1])
2744         return 0;
2745
2746       /* Is the memory address adjacent and ascending? */
2747       if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)
2748         return 0;
2749     }
2750
2751   if (base)
2752     {
2753       *base = base_reg;
2754
2755       for (i = 0; i < nops; i++)
2756         regs[i] = unsorted_regs[order[i]];
2757
2758       *load_offset = unsorted_offsets[order[0]];
2759     }
2760
2761   if (unsorted_offsets[order[0]] == 0)
2762     return 1; /* ldmia */
2763
2764   if (unsorted_offsets[order[0]] == 4)
2765     return 2; /* ldmib */
2766
2767   if (unsorted_offsets[order[nops - 1]] == 0)
2768     return 3; /* ldmda */
2769
2770   if (unsorted_offsets[order[nops - 1]] == -4)
2771     return 4; /* ldmdb */
2772
2773   /* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm if
2774      the offset isn't small enough.  The reason 2 ldrs are faster is because
2775      these ARMs are able to do more than one cache access in a single cycle.
2776      The ARM9 and StrongARM have Harvard caches, whilst the ARM8 has a double 
2777      bandwidth cache.  This means that these cores can do both an instruction 
2778      fetch and a data fetch in a single cycle, so the trick of calculating the 
2779      address into a scratch register (one of the result regs) and then doing a 
2780      load multiple actually becomes slower (and no smaller in code size).  That 
2781      is the transformation
2782  
2783         ldr     rd1, [rbase + offset]
2784         ldr     rd2, [rbase + offset + 4]
2785  
2786      to
2787  
2788         add     rd1, rbase, offset
2789         ldmia   rd1, {rd1, rd2}
2790  
2791      produces worse code -- '3 cycles + any stalls on rd2' instead of '2 cycles 
2792      + any stalls on rd2'.  On ARMs with only one cache access per cycle, the 
2793      first sequence could never complete in less than 6 cycles, whereas the ldm 
2794      sequence would only take 5 and would make better use of sequential accesses
2795      if not hitting the cache.
2796
2797      We cheat here and test 'arm_ld_sched' which we currently know to only be
2798      true for the ARM8, ARM9 and StrongARM.  If this ever changes, then the test
2799      below needs to be reworked.  */
2800   if (nops == 2 && arm_ld_sched)
2801     return 0;
2802
2803   /* Can't do it without setting up the offset, only do this if it takes
2804      no more than one insn.  */
2805   return (const_ok_for_arm (unsorted_offsets[order[0]]) 
2806           || const_ok_for_arm (-unsorted_offsets[order[0]])) ? 5 : 0;
2807 }
2808
2809 char *
2810 emit_ldm_seq (operands, nops)
2811      rtx *operands;
2812      int nops;
2813 {
2814   int regs[4];
2815   int base_reg;
2816   HOST_WIDE_INT offset;
2817   char buf[100];
2818   int i;
2819
2820   switch (load_multiple_sequence (operands, nops, regs, &base_reg, &offset))
2821     {
2822     case 1:
2823       strcpy (buf, "ldm%?ia\t");
2824       break;
2825
2826     case 2:
2827       strcpy (buf, "ldm%?ib\t");
2828       break;
2829
2830     case 3:
2831       strcpy (buf, "ldm%?da\t");
2832       break;
2833
2834     case 4:
2835       strcpy (buf, "ldm%?db\t");
2836       break;
2837
2838     case 5:
2839       if (offset >= 0)
2840         sprintf (buf, "add%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX,
2841                  reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],
2842                  (long) offset);
2843       else
2844         sprintf (buf, "sub%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX,
2845                  reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],
2846                  (long) -offset);
2847       output_asm_insn (buf, operands);
2848       base_reg = regs[0];
2849       strcpy (buf, "ldm%?ia\t");
2850       break;
2851
2852     default:
2853       abort ();
2854     }
2855
2856   sprintf (buf + strlen (buf), "%s%s, {%s%s", REGISTER_PREFIX, 
2857            reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);
2858
2859   for (i = 1; i < nops; i++)
2860     sprintf (buf + strlen (buf), ", %s%s", REGISTER_PREFIX,
2861              reg_names[regs[i]]);
2862
2863   strcat (buf, "}\t%@ phole ldm");
2864
2865   output_asm_insn (buf, operands);
2866   return "";
2867 }
2868
2869 int
2870 store_multiple_sequence (operands, nops, regs, base, load_offset)
2871      rtx *operands;
2872      int nops;
2873      int *regs;
2874      int *base;
2875      HOST_WIDE_INT *load_offset;
2876 {
2877   int unsorted_regs[4];
2878   HOST_WIDE_INT unsorted_offsets[4];
2879   int order[4];
2880   int base_reg = -1;
2881   int i;
2882
2883   /* Can only handle 2, 3, or 4 insns at present, though could be easily
2884      extended if required.  */
2885   if (nops < 2 || nops > 4)
2886     abort ();
2887
2888   /* Loop over the operands and check that the memory references are
2889      suitable (ie immediate offsets from the same base register).  At
2890      the same time, extract the target register, and the memory
2891      offsets.  */
2892   for (i = 0; i < nops; i++)
2893     {
2894       rtx reg;
2895       rtx offset;
2896
2897       /* Convert a subreg of a mem into the mem itself.  */
2898       if (GET_CODE (operands[nops + i]) == SUBREG)
2899         operands[nops + i] = alter_subreg(operands[nops + i]);
2900
2901       if (GET_CODE (operands[nops + i]) != MEM)
2902         abort ();
2903
2904       /* Don't reorder volatile memory references; it doesn't seem worth
2905          looking for the case where the order is ok anyway.  */
2906       if (MEM_VOLATILE_P (operands[nops + i]))
2907         return 0;
2908
2909       offset = const0_rtx;
2910
2911       if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG
2912            || (GET_CODE (reg) == SUBREG
2913                && GET_CODE (reg = SUBREG_REG (reg)) == REG))
2914           || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
2915               && ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))
2916                    == REG)
2917                   || (GET_CODE (reg) == SUBREG
2918                       && GET_CODE (reg = SUBREG_REG (reg)) == REG))
2919               && (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))
2920                   == CONST_INT)))
2921         {
2922           if (i == 0)
2923             {
2924               base_reg = REGNO(reg);
2925               unsorted_regs[0] = (GET_CODE (operands[i]) == REG
2926                                   ? REGNO (operands[i])
2927                                   : REGNO (SUBREG_REG (operands[i])));
2928               order[0] = 0;
2929             }
2930           else 
2931             {
2932               if (base_reg != REGNO (reg))
2933                 /* Not addressed from the same base register.  */
2934                 return 0;
2935
2936               unsorted_regs[i] = (GET_CODE (operands[i]) == REG
2937                                   ? REGNO (operands[i])
2938                                   : REGNO (SUBREG_REG (operands[i])));
2939               if (unsorted_regs[i] < unsorted_regs[order[0]])
2940                 order[0] = i;
2941             }
2942
2943           /* If it isn't an integer register, then we can't do this.  */
2944           if (unsorted_regs[i] < 0 || unsorted_regs[i] > 14)
2945             return 0;
2946
2947           unsorted_offsets[i] = INTVAL (offset);
2948         }
2949       else
2950         /* Not a suitable memory address.  */
2951         return 0;
2952     }
2953
2954   /* All the useful information has now been extracted from the
2955      operands into unsorted_regs and unsorted_offsets; additionally,
2956      order[0] has been set to the lowest numbered register in the
2957      list.  Sort the registers into order, and check that the memory
2958      offsets are ascending and adjacent.  */
2959
2960   for (i = 1; i < nops; i++)
2961     {
2962       int j;
2963
2964       order[i] = order[i - 1];
2965       for (j = 0; j < nops; j++)
2966         if (unsorted_regs[j] > unsorted_regs[order[i - 1]]
2967             && (order[i] == order[i - 1]
2968                 || unsorted_regs[j] < unsorted_regs[order[i]]))
2969           order[i] = j;
2970
2971       /* Have we found a suitable register? if not, one must be used more
2972          than once.  */
2973       if (order[i] == order[i - 1])
2974         return 0;
2975
2976       /* Is the memory address adjacent and ascending? */
2977       if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)
2978         return 0;
2979     }
2980
2981   if (base)
2982     {
2983       *base = base_reg;
2984
2985       for (i = 0; i < nops; i++)
2986         regs[i] = unsorted_regs[order[i]];
2987
2988       *load_offset = unsorted_offsets[order[0]];
2989     }
2990
2991   if (unsorted_offsets[order[0]] == 0)
2992     return 1; /* stmia */
2993
2994   if (unsorted_offsets[order[0]] == 4)
2995     return 2; /* stmib */
2996
2997   if (unsorted_offsets[order[nops - 1]] == 0)
2998     return 3; /* stmda */
2999
3000   if (unsorted_offsets[order[nops - 1]] == -4)
3001     return 4; /* stmdb */
3002
3003   return 0;
3004 }
3005
3006 char *
3007 emit_stm_seq (operands, nops)
3008      rtx *operands;
3009      int nops;
3010 {
3011   int regs[4];
3012   int base_reg;
3013   HOST_WIDE_INT offset;
3014   char buf[100];
3015   int i;
3016
3017   switch (store_multiple_sequence (operands, nops, regs, &base_reg, &offset))
3018     {
3019     case 1:
3020       strcpy (buf, "stm%?ia\t");
3021       break;
3022
3023     case 2:
3024       strcpy (buf, "stm%?ib\t");
3025       break;
3026
3027     case 3:
3028       strcpy (buf, "stm%?da\t");
3029       break;
3030
3031     case 4:
3032       strcpy (buf, "stm%?db\t");
3033       break;
3034
3035     default:
3036       abort ();
3037     }
3038
3039   sprintf (buf + strlen (buf), "%s%s, {%s%s", REGISTER_PREFIX, 
3040            reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);
3041
3042   for (i = 1; i < nops; i++)
3043     sprintf (buf + strlen (buf), ", %s%s", REGISTER_PREFIX,
3044              reg_names[regs[i]]);
3045
3046   strcat (buf, "}\t%@ phole stm");
3047
3048   output_asm_insn (buf, operands);
3049   return "";
3050 }
3051
3052 int
3053 multi_register_push (op, mode)
3054      rtx op;
3055      enum machine_mode mode ATTRIBUTE_UNUSED;
3056 {
3057   if (GET_CODE (op) != PARALLEL
3058       || (GET_CODE (XVECEXP (op, 0, 0)) != SET)
3059       || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
3060       || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != 2))
3061     return 0;
3062
3063   return 1;
3064 }
3065
3066 \f
3067 /* Routines for use with attributes */
3068
3069 /* Return nonzero if ATTR is a valid attribute for DECL.
3070    ATTRIBUTES are any existing attributes and ARGS are the arguments
3071    supplied with ATTR.
3072
3073    Supported attributes:
3074
3075    naked: don't output any prologue or epilogue code, the user is assumed
3076    to do the right thing.  */
3077
3078 int
3079 arm_valid_machine_decl_attribute (decl, attr, args)
3080      tree decl;
3081      tree attr;
3082      tree args;
3083 {
3084   if (args != NULL_TREE)
3085     return 0;
3086
3087   if (is_attribute_p ("naked", attr))
3088     return TREE_CODE (decl) == FUNCTION_DECL;
3089   return 0;
3090 }
3091
3092 /* Return non-zero if FUNC is a naked function.  */
3093
3094 static int
3095 arm_naked_function_p (func)
3096      tree func;
3097 {
3098   tree a;
3099
3100   if (TREE_CODE (func) != FUNCTION_DECL)
3101     abort ();
3102   
3103   a = lookup_attribute ("naked", DECL_MACHINE_ATTRIBUTES (func));
3104   return a != NULL_TREE;
3105 }
3106 \f
3107 /* Routines for use in generating RTL */
3108
3109 rtx
3110 arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
3111                        in_struct_p, scalar_p)
3112      int base_regno;
3113      int count;
3114      rtx from;
3115      int up;
3116      int write_back;
3117      int unchanging_p;
3118      int in_struct_p;
3119      int scalar_p;
3120 {
3121   int i = 0, j;
3122   rtx result;
3123   int sign = up ? 1 : -1;
3124   rtx mem;
3125
3126   result = gen_rtx_PARALLEL (VOIDmode,
3127                              rtvec_alloc (count + (write_back ? 2 : 0)));
3128   if (write_back)
3129     {
3130       XVECEXP (result, 0, 0)
3131         = gen_rtx_SET (GET_MODE (from), from,
3132                        plus_constant (from, count * 4 * sign));
3133       i = 1;
3134       count++;
3135     }
3136
3137   for (j = 0; i < count; i++, j++)
3138     {
3139       mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign));
3140       RTX_UNCHANGING_P (mem) = unchanging_p;
3141       MEM_IN_STRUCT_P (mem) = in_struct_p;
3142       MEM_SCALAR_P (mem) = scalar_p;
3143       XVECEXP (result, 0, i)
3144         = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
3145     }
3146
3147   if (write_back)
3148     XVECEXP (result, 0, i) = gen_rtx_CLOBBER (SImode, from);
3149
3150   return result;
3151 }
3152
3153 rtx
3154 arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
3155                         in_struct_p, scalar_p)
3156      int base_regno;
3157      int count;
3158      rtx to;
3159      int up;
3160      int write_back;
3161      int unchanging_p;
3162      int in_struct_p;
3163      int scalar_p;
3164 {
3165   int i = 0, j;
3166   rtx result;
3167   int sign = up ? 1 : -1;
3168   rtx mem;
3169
3170   result = gen_rtx_PARALLEL (VOIDmode,
3171                              rtvec_alloc (count + (write_back ? 2 : 0)));
3172   if (write_back)
3173     {
3174       XVECEXP (result, 0, 0)
3175         = gen_rtx_SET (GET_MODE (to), to,
3176                        plus_constant (to, count * 4 * sign));
3177       i = 1;
3178       count++;
3179     }
3180
3181   for (j = 0; i < count; i++, j++)
3182     {
3183       mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign));
3184       RTX_UNCHANGING_P (mem) = unchanging_p;
3185       MEM_IN_STRUCT_P (mem) = in_struct_p;
3186       MEM_SCALAR_P (mem) = scalar_p;
3187
3188       XVECEXP (result, 0, i)
3189         = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
3190     }
3191
3192   if (write_back)
3193     XVECEXP (result, 0, i) = gen_rtx_CLOBBER (SImode, to);
3194
3195   return result;
3196 }
3197
3198 int
3199 arm_gen_movstrqi (operands)
3200      rtx *operands;
3201 {
3202   HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
3203   int i;
3204   rtx src, dst;
3205   rtx st_src, st_dst, fin_src, fin_dst;
3206   rtx part_bytes_reg = NULL;
3207   rtx mem;
3208   int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p;
3209   int dst_scalar_p, src_scalar_p;
3210
3211   if (GET_CODE (operands[2]) != CONST_INT
3212       || GET_CODE (operands[3]) != CONST_INT
3213       || INTVAL (operands[2]) > 64
3214       || INTVAL (operands[3]) & 3)
3215     return 0;
3216
3217   st_dst = XEXP (operands[0], 0);
3218   st_src = XEXP (operands[1], 0);
3219
3220   dst_unchanging_p = RTX_UNCHANGING_P (operands[0]);
3221   dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
3222   dst_scalar_p = MEM_SCALAR_P (operands[0]);
3223   src_unchanging_p = RTX_UNCHANGING_P (operands[1]);
3224   src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
3225   src_scalar_p = MEM_SCALAR_P (operands[1]);
3226
3227   fin_dst = dst = copy_to_mode_reg (SImode, st_dst);
3228   fin_src = src = copy_to_mode_reg (SImode, st_src);
3229
3230   in_words_to_go = (INTVAL (operands[2]) + 3) / 4;
3231   out_words_to_go = INTVAL (operands[2]) / 4;
3232   last_bytes = INTVAL (operands[2]) & 3;
3233
3234   if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
3235     part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
3236
3237   for (i = 0; in_words_to_go >= 2; i+=4)
3238     {
3239       if (in_words_to_go > 4)
3240         emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
3241                                           src_unchanging_p,
3242                                           src_in_struct_p,
3243                                           src_scalar_p));
3244       else
3245         emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE, 
3246                                           FALSE, src_unchanging_p,
3247                                           src_in_struct_p, src_scalar_p));
3248
3249       if (out_words_to_go)
3250         {
3251           if (out_words_to_go > 4)
3252             emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
3253                                                dst_unchanging_p,
3254                                                dst_in_struct_p,
3255                                                dst_scalar_p));
3256           else if (out_words_to_go != 1)
3257             emit_insn (arm_gen_store_multiple (0, out_words_to_go,
3258                                                dst, TRUE, 
3259                                                (last_bytes == 0
3260                                                 ? FALSE : TRUE),
3261                                                dst_unchanging_p,
3262                                                dst_in_struct_p,
3263                                                dst_scalar_p));
3264           else
3265             {
3266               mem = gen_rtx_MEM (SImode, dst);
3267               RTX_UNCHANGING_P (mem) = dst_unchanging_p;
3268               MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
3269               MEM_SCALAR_P (mem) = dst_scalar_p;
3270               emit_move_insn (mem, gen_rtx_REG (SImode, 0));
3271               if (last_bytes != 0)
3272                 emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
3273             }
3274         }
3275
3276       in_words_to_go -= in_words_to_go < 4 ? in_words_to_go : 4;
3277       out_words_to_go -= out_words_to_go < 4 ? out_words_to_go : 4;
3278     }
3279
3280   /* OUT_WORDS_TO_GO will be zero here if there are byte stores to do.  */
3281   if (out_words_to_go)
3282   {
3283     rtx sreg;
3284
3285     mem = gen_rtx_MEM (SImode, src);
3286     RTX_UNCHANGING_P (mem) = src_unchanging_p;
3287     MEM_IN_STRUCT_P (mem) = src_in_struct_p;
3288     MEM_SCALAR_P (mem) = src_scalar_p;
3289     emit_move_insn (sreg = gen_reg_rtx (SImode), mem);
3290     emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
3291
3292     mem = gen_rtx_MEM (SImode, dst);
3293     RTX_UNCHANGING_P (mem) = dst_unchanging_p;
3294     MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
3295     MEM_SCALAR_P (mem) = dst_scalar_p;
3296     emit_move_insn (mem, sreg);
3297     emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
3298     in_words_to_go--;
3299
3300     if (in_words_to_go) /* Sanity check */
3301       abort ();
3302   }
3303
3304   if (in_words_to_go)
3305     {
3306       if (in_words_to_go < 0)
3307         abort ();
3308
3309       mem = gen_rtx_MEM (SImode, src);
3310       RTX_UNCHANGING_P (mem) = src_unchanging_p;
3311       MEM_IN_STRUCT_P (mem) = src_in_struct_p;
3312       MEM_SCALAR_P (mem) = src_scalar_p;
3313       part_bytes_reg = copy_to_mode_reg (SImode, mem);
3314     }
3315
3316   if (BYTES_BIG_ENDIAN && last_bytes)
3317     {
3318       rtx tmp = gen_reg_rtx (SImode);
3319
3320       if (part_bytes_reg == NULL)
3321         abort ();
3322
3323       /* The bytes we want are in the top end of the word */
3324       emit_insn (gen_lshrsi3 (tmp, part_bytes_reg,
3325                               GEN_INT (8 * (4 - last_bytes))));
3326       part_bytes_reg = tmp;
3327       
3328       while (last_bytes)
3329         {
3330           mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1));
3331           RTX_UNCHANGING_P (mem) = dst_unchanging_p;
3332           MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
3333           MEM_SCALAR_P (mem) = dst_scalar_p;
3334           emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
3335           if (--last_bytes)
3336             {
3337               tmp = gen_reg_rtx (SImode);
3338               emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (8)));
3339               part_bytes_reg = tmp;
3340             }
3341         }
3342           
3343     }
3344   else
3345     {
3346       while (last_bytes)
3347         {
3348           if (part_bytes_reg == NULL)
3349             abort ();
3350
3351           mem = gen_rtx_MEM (QImode, dst);
3352           RTX_UNCHANGING_P (mem) = dst_unchanging_p;
3353           MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
3354           MEM_SCALAR_P (mem) = dst_scalar_p;
3355           emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
3356           if (--last_bytes)
3357             {
3358               rtx tmp = gen_reg_rtx (SImode);
3359
3360               emit_insn (gen_addsi3 (dst, dst, const1_rtx));
3361               emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (8)));
3362               part_bytes_reg = tmp;
3363             }
3364         }
3365     }
3366
3367   return 1;
3368 }
3369
3370 /* Generate a memory reference for a half word, such that it will be loaded
3371    into the top 16 bits of the word.  We can assume that the address is
3372    known to be alignable and of the form reg, or plus (reg, const).  */
3373 rtx
3374 gen_rotated_half_load (memref)
3375      rtx memref;
3376 {
3377   HOST_WIDE_INT offset = 0;
3378   rtx base = XEXP (memref, 0);
3379
3380   if (GET_CODE (base) == PLUS)
3381     {
3382       offset = INTVAL (XEXP (base, 1));
3383       base = XEXP (base, 0);
3384     }
3385
3386   /* If we aren't allowed to generate unaligned addresses, then fail.  */
3387   if (TARGET_SHORT_BY_BYTES
3388       && ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 0)))
3389     return NULL;
3390
3391   base = gen_rtx_MEM (SImode, plus_constant (base, offset & ~2));
3392
3393   if ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 2))
3394     return base;
3395
3396   return gen_rtx_ROTATE (SImode, base, GEN_INT (16));
3397 }
3398
3399 static enum machine_mode
3400 select_dominance_cc_mode (x, y, cond_or)
3401      rtx x;
3402      rtx y;
3403      HOST_WIDE_INT cond_or;
3404 {
3405   enum rtx_code cond1, cond2;
3406   int swapped = 0;
3407
3408   /* Currently we will probably get the wrong result if the individual
3409      comparisons are not simple.  This also ensures that it is safe to
3410      reverse a comparison if necessary.  */
3411   if ((arm_select_cc_mode (cond1 = GET_CODE (x), XEXP (x, 0), XEXP (x, 1))
3412        != CCmode)
3413       || (arm_select_cc_mode (cond2 = GET_CODE (y), XEXP (y, 0), XEXP (y, 1))
3414           != CCmode))
3415     return CCmode;
3416
3417   if (cond_or)
3418     cond1 = reverse_condition (cond1);
3419
3420   /* If the comparisons are not equal, and one doesn't dominate the other,
3421      then we can't do this.  */
3422   if (cond1 != cond2 
3423       && ! comparison_dominates_p (cond1, cond2)
3424       && (swapped = 1, ! comparison_dominates_p (cond2, cond1)))
3425     return CCmode;
3426
3427   if (swapped)
3428     {
3429       enum rtx_code temp = cond1;
3430       cond1 = cond2;
3431       cond2 = temp;
3432     }
3433
3434   switch (cond1)
3435     {
3436     case EQ:
3437       if (cond2 == EQ || ! cond_or)
3438         return CC_DEQmode;
3439
3440       switch (cond2)
3441         {
3442         case LE: return CC_DLEmode;
3443         case LEU: return CC_DLEUmode;
3444         case GE: return CC_DGEmode;
3445         case GEU: return CC_DGEUmode;
3446         default: break;
3447         }
3448
3449       break;
3450
3451     case LT:
3452       if (cond2 == LT || ! cond_or)
3453         return CC_DLTmode;
3454       if (cond2 == LE)
3455         return CC_DLEmode;
3456       if (cond2 == NE)
3457         return CC_DNEmode;
3458       break;
3459
3460     case GT:
3461       if (cond2 == GT || ! cond_or)
3462         return CC_DGTmode;
3463       if (cond2 == GE)
3464         return CC_DGEmode;
3465       if (cond2 == NE)
3466         return CC_DNEmode;
3467       break;
3468       
3469     case LTU:
3470       if (cond2 == LTU || ! cond_or)
3471         return CC_DLTUmode;
3472       if (cond2 == LEU)
3473         return CC_DLEUmode;
3474       if (cond2 == NE)
3475         return CC_DNEmode;
3476       break;
3477
3478     case GTU:
3479       if (cond2 == GTU || ! cond_or)
3480         return CC_DGTUmode;
3481       if (cond2 == GEU)
3482         return CC_DGEUmode;
3483       if (cond2 == NE)
3484         return CC_DNEmode;
3485       break;
3486
3487     /* The remaining cases only occur when both comparisons are the
3488        same.  */
3489     case NE:
3490       return CC_DNEmode;
3491
3492     case LE:
3493       return CC_DLEmode;
3494
3495     case GE:
3496       return CC_DGEmode;
3497
3498     case LEU:
3499       return CC_DLEUmode;
3500
3501     case GEU:
3502       return CC_DGEUmode;
3503
3504     default:
3505       break;
3506     }
3507
3508   abort ();
3509 }
3510
3511 enum machine_mode
3512 arm_select_cc_mode (op, x, y)
3513      enum rtx_code op;
3514      rtx x;
3515      rtx y;
3516 {
3517   /* All floating point compares return CCFP if it is an equality
3518      comparison, and CCFPE otherwise.  */
3519   if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
3520     return (op == EQ || op == NE) ? CCFPmode : CCFPEmode;
3521   
3522   /* A compare with a shifted operand.  Because of canonicalization, the
3523      comparison will have to be swapped when we emit the assembler.  */
3524   if (GET_MODE (y) == SImode && GET_CODE (y) == REG
3525       && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
3526           || GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ROTATE
3527           || GET_CODE (x) == ROTATERT))
3528     return CC_SWPmode;
3529
3530   /* This is a special case that is used by combine to allow a 
3531      comparison of a shifted byte load to be split into a zero-extend
3532      followed by a comparison of the shifted integer (only valid for
3533      equalities and unsigned inequalities).  */
3534   if (GET_MODE (x) == SImode
3535       && GET_CODE (x) == ASHIFT
3536       && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 24
3537       && GET_CODE (XEXP (x, 0)) == SUBREG
3538       && GET_CODE (SUBREG_REG (XEXP (x, 0))) == MEM
3539       && GET_MODE (SUBREG_REG (XEXP (x, 0))) == QImode
3540       && (op == EQ || op == NE
3541           || op == GEU || op == GTU || op == LTU || op == LEU)
3542       && GET_CODE (y) == CONST_INT)
3543     return CC_Zmode;
3544
3545   /* An operation that sets the condition codes as a side-effect, the
3546      V flag is not set correctly, so we can only use comparisons where
3547      this doesn't matter.  (For LT and GE we can use "mi" and "pl"
3548      instead.  */
3549   if (GET_MODE (x) == SImode
3550       && y == const0_rtx
3551       && (op == EQ || op == NE || op == LT || op == GE)
3552       && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
3553           || GET_CODE (x) == AND || GET_CODE (x) == IOR
3554           || GET_CODE (x) == XOR || GET_CODE (x) == MULT
3555           || GET_CODE (x) == NOT || GET_CODE (x) == NEG
3556           || GET_CODE (x) == LSHIFTRT
3557           || GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
3558           || GET_CODE (x) == ROTATERT || GET_CODE (x) == ZERO_EXTRACT))
3559     return CC_NOOVmode;
3560
3561   /* A construct for a conditional compare, if the false arm contains
3562      0, then both conditions must be true, otherwise either condition
3563      must be true.  Not all conditions are possible, so CCmode is
3564      returned if it can't be done.  */
3565   if (GET_CODE (x) == IF_THEN_ELSE
3566       && (XEXP (x, 2) == const0_rtx
3567           || XEXP (x, 2) == const1_rtx)
3568       && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
3569       && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
3570     return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 
3571                                      INTVAL (XEXP (x, 2)));
3572
3573   if (GET_MODE (x) == QImode && (op == EQ || op == NE))
3574     return CC_Zmode;
3575
3576   if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
3577       && GET_CODE (x) == PLUS
3578       && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
3579     return CC_Cmode;
3580
3581   return CCmode;
3582 }
3583
3584 /* X and Y are two things to compare using CODE.  Emit the compare insn and
3585    return the rtx for register 0 in the proper mode.  FP means this is a
3586    floating point compare: I don't think that it is needed on the arm.  */
3587
3588 rtx
3589 gen_compare_reg (code, x, y)
3590      enum rtx_code code;
3591      rtx x, y;
3592 {
3593   enum machine_mode mode = SELECT_CC_MODE (code, x, y);
3594   rtx cc_reg = gen_rtx_REG (mode, 24);
3595
3596   emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
3597                           gen_rtx_COMPARE (mode, x, y)));
3598
3599   return cc_reg;
3600 }
3601
3602 void
3603 arm_reload_in_hi (operands)
3604      rtx *operands;
3605 {
3606   rtx base = find_replacement (&XEXP (operands[1], 0));
3607
3608   emit_insn (gen_zero_extendqisi2 (operands[2], gen_rtx_MEM (QImode, base)));
3609   /* Handle the case where the address is too complex to be offset by 1.  */
3610   if (GET_CODE (base) == MINUS
3611       || (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
3612     {
3613       rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[0]));
3614
3615       emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
3616       base = base_plus;
3617     }
3618
3619   emit_insn (gen_zero_extendqisi2 (gen_rtx_SUBREG (SImode, operands[0], 0),
3620                                    gen_rtx_MEM (QImode, 
3621                                                 plus_constant (base, 1))));
3622   if (BYTES_BIG_ENDIAN)
3623     emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
3624                         gen_rtx_IOR (SImode, 
3625                                      gen_rtx_ASHIFT
3626                                      (SImode,
3627                                       gen_rtx_SUBREG (SImode, operands[0], 0),
3628                                       GEN_INT (8)),
3629                                      operands[2])));
3630   else
3631     emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
3632                             gen_rtx_IOR (SImode, 
3633                                          gen_rtx_ASHIFT (SImode, operands[2],
3634                                                          GEN_INT (8)),
3635                                          gen_rtx_SUBREG (SImode, operands[0],
3636                                                          0))));
3637 }
3638
3639 void
3640 arm_reload_out_hi (operands)
3641      rtx *operands;
3642 {
3643   rtx base = find_replacement (&XEXP (operands[0], 0));
3644
3645   if (BYTES_BIG_ENDIAN)
3646     {
3647       emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, 1)),
3648                             gen_rtx_SUBREG (QImode, operands[1], 0)));
3649       emit_insn (gen_lshrsi3 (operands[2],
3650                               gen_rtx_SUBREG (SImode, operands[1], 0),
3651                               GEN_INT (8)));
3652       emit_insn (gen_movqi (gen_rtx_MEM (QImode, base),
3653                             gen_rtx_SUBREG (QImode, operands[2], 0)));
3654     }
3655   else
3656     {
3657       emit_insn (gen_movqi (gen_rtx_MEM (QImode, base),
3658                             gen_rtx_SUBREG (QImode, operands[1], 0)));
3659       emit_insn (gen_lshrsi3 (operands[2],
3660                               gen_rtx_SUBREG (SImode, operands[1], 0),
3661                               GEN_INT (8)));
3662       emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, 1)),
3663                             gen_rtx_SUBREG (QImode, operands[2], 0)));
3664     }
3665 }
3666 \f
3667 /* Routines for manipulation of the constant pool.  */
3668 /* This is unashamedly hacked from the version in sh.c, since the problem is
3669    extremely similar.  */
3670
3671 /* Arm instructions cannot load a large constant into a register,
3672    constants have to come from a pc relative load.  The reference of a pc
3673    relative load instruction must be less than 1k infront of the instruction.
3674    This means that we often have to dump a constant inside a function, and
3675    generate code to branch around it.
3676
3677    It is important to minimize this, since the branches will slow things
3678    down and make things bigger.
3679
3680    Worst case code looks like:
3681
3682         ldr     rn, L1
3683         b       L2
3684         align
3685         L1:     .long value
3686         L2:
3687         ..
3688
3689         ldr     rn, L3
3690         b       L4
3691         align
3692         L3:     .long value
3693         L4:
3694         ..
3695
3696    We fix this by performing a scan before scheduling, which notices which
3697    instructions need to have their operands fetched from the constant table
3698    and builds the table.
3699
3700
3701    The algorithm is:
3702
3703    scan, find an instruction which needs a pcrel move.  Look forward, find th
3704    last barrier which is within MAX_COUNT bytes of the requirement.
3705    If there isn't one, make one.  Process all the instructions between
3706    the find and the barrier.
3707
3708    In the above example, we can tell that L3 is within 1k of L1, so
3709    the first move can be shrunk from the 2 insn+constant sequence into
3710    just 1 insn, and the constant moved to L3 to make:
3711
3712         ldr     rn, L1
3713         ..
3714         ldr     rn, L3
3715         b       L4
3716         align
3717         L1:     .long value
3718         L3:     .long value
3719         L4:
3720
3721    Then the second move becomes the target for the shortening process.
3722
3723  */
3724
3725 typedef struct
3726 {
3727   rtx value;                    /* Value in table */
3728   HOST_WIDE_INT next_offset;
3729   enum machine_mode mode;       /* Mode of value */
3730 } pool_node;
3731
3732 /* The maximum number of constants that can fit into one pool, since
3733    the pc relative range is 0...1020 bytes and constants are at least 4
3734    bytes long */
3735
3736 #define MAX_POOL_SIZE (1020/4)
3737 static pool_node pool_vector[MAX_POOL_SIZE];
3738 static int pool_size;
3739 static rtx pool_vector_label;
3740
3741 /* Add a constant to the pool and return its offset within the current
3742    pool.
3743
3744    X is the rtx we want to replace. MODE is its mode.  On return,
3745    ADDRESS_ONLY will be non-zero if we really want the address of such
3746    a constant, not the constant itself.  */
3747 static HOST_WIDE_INT
3748 add_constant (x, mode, address_only)
3749      rtx x;
3750      enum machine_mode mode;
3751      int * address_only;
3752 {
3753   int i;
3754   HOST_WIDE_INT offset;
3755
3756   * address_only = 0;
3757   
3758   if (mode == SImode && GET_CODE (x) == MEM && CONSTANT_P (XEXP (x, 0))
3759       && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))
3760     x = get_pool_constant (XEXP (x, 0));
3761   else if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P(x))
3762     {
3763       *address_only = 1;
3764       mode = get_pool_mode (x);
3765       x = get_pool_constant (x);
3766     }
3767 #ifndef AOF_ASSEMBLER
3768   else if (GET_CODE (x) == UNSPEC && XINT (x, 1) == 3)
3769     x = XVECEXP (x, 0, 0);
3770 #endif
3771
3772 #ifdef AOF_ASSEMBLER
3773   /* PIC Symbol references need to be converted into offsets into the 
3774      based area.  */
3775   if (flag_pic && GET_CODE (x) == SYMBOL_REF)
3776     x = aof_pic_entry (x);
3777 #endif /* AOF_ASSEMBLER */
3778
3779   /* First see if we've already got it */
3780   for (i = 0; i < pool_size; i++)
3781     {
3782       if (GET_CODE (x) == pool_vector[i].value->code
3783           && mode == pool_vector[i].mode)
3784         {
3785           if (GET_CODE (x) == CODE_LABEL)
3786             {
3787               if (XINT (x, 3) != XINT (pool_vector[i].value, 3))
3788                 continue;
3789             }
3790           if (rtx_equal_p (x, pool_vector[i].value))
3791             return pool_vector[i].next_offset - GET_MODE_SIZE (mode);
3792         }
3793     }
3794
3795   /* Need a new one */
3796   pool_vector[pool_size].next_offset = GET_MODE_SIZE (mode);
3797   offset = 0;
3798   if (pool_size == 0)
3799     pool_vector_label = gen_label_rtx ();
3800   else
3801     pool_vector[pool_size].next_offset
3802       += (offset = pool_vector[pool_size - 1].next_offset);
3803
3804   pool_vector[pool_size].value = x;
3805   pool_vector[pool_size].mode = mode;
3806   pool_size++;
3807   return offset;
3808 }
3809
3810 /* Output the literal table */
3811 static void
3812 dump_table (scan)
3813      rtx scan;
3814 {
3815   int i;
3816
3817   scan = emit_label_after (gen_label_rtx (), scan);
3818   scan = emit_insn_after (gen_align_4 (), scan);
3819   scan = emit_label_after (pool_vector_label, scan);
3820
3821   for (i = 0; i < pool_size; i++)
3822     {
3823       pool_node *p = pool_vector + i;
3824
3825       switch (GET_MODE_SIZE (p->mode))
3826         {
3827         case 4:
3828           scan = emit_insn_after (gen_consttable_4 (p->value), scan);
3829           break;
3830
3831         case 8:
3832           scan = emit_insn_after (gen_consttable_8 (p->value), scan);
3833           break;
3834
3835         default:
3836           abort ();
3837           break;
3838         }
3839     }
3840
3841   scan = emit_insn_after (gen_consttable_end (), scan);
3842   scan = emit_barrier_after (scan);
3843   pool_size = 0;
3844 }
3845
3846 /* Non zero if the src operand needs to be fixed up */
3847 static int
3848 fixit (src, mode, destreg)
3849      rtx src;
3850      enum machine_mode mode;
3851      int destreg;
3852 {
3853   if (CONSTANT_P (src))
3854     {
3855       if (GET_CODE (src) == CONST_INT)
3856         return (! const_ok_for_arm (INTVAL (src))
3857                 && ! const_ok_for_arm (~INTVAL (src)));
3858       if (GET_CODE (src) == CONST_DOUBLE)
3859         return (GET_MODE (src) == VOIDmode
3860                 || destreg < 16
3861                 || (! const_double_rtx_ok_for_fpu (src)
3862                     && ! neg_const_double_rtx_ok_for_fpu (src)));
3863       return symbol_mentioned_p (src);
3864     }
3865 #ifndef AOF_ASSEMBLER
3866   else if (GET_CODE (src) == UNSPEC && XINT (src, 1) == 3)
3867     return 1;
3868 #endif
3869   else
3870     return (mode == SImode && GET_CODE (src) == MEM
3871             && GET_CODE (XEXP (src, 0)) == SYMBOL_REF
3872             && CONSTANT_POOL_ADDRESS_P (XEXP (src, 0)));
3873 }
3874
3875 /* Find the last barrier less than MAX_COUNT bytes from FROM, or create one. */
3876 static rtx
3877 find_barrier (from, max_count)
3878      rtx from;
3879      int max_count;
3880 {
3881   int count = 0;
3882   rtx found_barrier = 0;
3883   rtx last = from;
3884
3885   while (from && count < max_count)
3886     {
3887       rtx tmp;
3888       
3889       if (GET_CODE (from) == BARRIER)
3890         found_barrier = from;
3891
3892       /* Count the length of this insn */
3893       if (GET_CODE (from) == INSN
3894           && GET_CODE (PATTERN (from)) == SET
3895           && CONSTANT_P (SET_SRC (PATTERN (from)))
3896           && CONSTANT_POOL_ADDRESS_P (SET_SRC (PATTERN (from))))
3897         count += 8;
3898       /* Handle table jumps as a single entity.  */
3899       else if (GET_CODE (from) == JUMP_INSN
3900                && JUMP_LABEL (from) != 0
3901                && ((tmp = next_real_insn (JUMP_LABEL (from)))
3902                    == next_real_insn (from))
3903                && tmp != NULL
3904                && GET_CODE (tmp) == JUMP_INSN
3905                && (GET_CODE (PATTERN (tmp)) == ADDR_VEC
3906                    || GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC))
3907         {
3908           int elt = GET_CODE (PATTERN (tmp)) == ADDR_DIFF_VEC ? 1 : 0;
3909           count += (get_attr_length (from)
3910                     + GET_MODE_SIZE (SImode) * XVECLEN (PATTERN (tmp), elt));
3911           /* Continue after the dispatch table.  */
3912           last = from;
3913           from = NEXT_INSN (tmp);
3914           continue;
3915         }
3916       else
3917         count += get_attr_length (from);
3918
3919       last = from;
3920       from = NEXT_INSN (from);
3921     }
3922
3923   if (! found_barrier)
3924     {
3925       /* We didn't find a barrier in time to
3926          dump our stuff, so we'll make one.  */
3927       rtx label = gen_label_rtx ();
3928       
3929       if (from)
3930         from = PREV_INSN (last);
3931       else
3932         from = get_last_insn ();
3933       
3934       /* Walk back to be just before any jump.  */
3935       while (GET_CODE (from) == JUMP_INSN
3936              || GET_CODE (from) == NOTE
3937              || GET_CODE (from) == CODE_LABEL)
3938         from = PREV_INSN (from);
3939       
3940       from = emit_jump_insn_after (gen_jump (label), from);
3941       JUMP_LABEL (from) = label;
3942       found_barrier = emit_barrier_after (from);
3943       emit_label_after (label, found_barrier);
3944     }
3945
3946   return found_barrier;
3947 }
3948
3949 /* Non zero if the insn is a move instruction which needs to be fixed. */
3950 static int
3951 broken_move (insn)
3952      rtx insn;
3953 {
3954   if (!INSN_DELETED_P (insn)
3955       && GET_CODE (insn) == INSN
3956       && GET_CODE (PATTERN (insn)) == SET)
3957     {
3958       rtx pat = PATTERN (insn);
3959       rtx src = SET_SRC (pat);
3960       rtx dst = SET_DEST (pat);
3961       int destreg;
3962       enum machine_mode mode = GET_MODE (dst);
3963
3964       if (dst == pc_rtx)
3965         return 0;
3966
3967       if (GET_CODE (dst) == REG)
3968         destreg = REGNO (dst);
3969       else if (GET_CODE (dst) == SUBREG && GET_CODE (SUBREG_REG (dst)) == REG)
3970         destreg = REGNO (SUBREG_REG (dst));
3971       else
3972         return 0;
3973
3974       return fixit (src, mode, destreg);
3975     }
3976   return 0;
3977 }
3978
3979 void
3980 arm_reorg (first)
3981      rtx first;
3982 {
3983   rtx insn;
3984   int count_size;
3985
3986 #if 0
3987   /* The ldr instruction can work with up to a 4k offset, and most constants
3988      will be loaded with one of these instructions; however, the adr 
3989      instruction and the ldf instructions only work with a 1k offset.  This
3990      code needs to be rewritten to use the 4k offset when possible, and to
3991      adjust when a 1k offset is needed.  For now we just use a 1k offset
3992      from the start.  */
3993   count_size = 4000;
3994
3995   /* Floating point operands can't work further than 1024 bytes from the
3996      PC, so to make things simple we restrict all loads for such functions.
3997      */
3998   if (TARGET_HARD_FLOAT)
3999     {
4000       int regno;
4001
4002       for (regno = 16; regno < 24; regno++)
4003         if (regs_ever_live[regno])
4004           {
4005             count_size = 1000;
4006             break;
4007           }
4008     }
4009 #else
4010   count_size = 1000;
4011 #endif /* 0 */
4012
4013   for (insn = first; insn; insn = NEXT_INSN (insn))
4014     {
4015       if (broken_move (insn))
4016         {
4017           /* This is a broken move instruction, scan ahead looking for
4018              a barrier to stick the constant table behind */
4019           rtx scan;
4020           rtx barrier = find_barrier (insn, count_size);
4021
4022           /* Now find all the moves between the points and modify them */
4023           for (scan = insn; scan != barrier; scan = NEXT_INSN (scan))
4024             {
4025               if (broken_move (scan))
4026                 {
4027                   /* This is a broken move instruction, add it to the pool */
4028                   rtx pat = PATTERN (scan);
4029                   rtx src = SET_SRC (pat);
4030                   rtx dst = SET_DEST (pat);
4031                   enum machine_mode mode = GET_MODE (dst);
4032                   HOST_WIDE_INT offset;
4033                   rtx newinsn = scan;
4034                   rtx newsrc;
4035                   rtx addr;
4036                   int scratch;
4037                   int address_only;
4038
4039                   /* If this is an HImode constant load, convert it into
4040                      an SImode constant load.  Since the register is always
4041                      32 bits this is safe.  We have to do this, since the
4042                      load pc-relative instruction only does a 32-bit load. */
4043                   if (mode == HImode)
4044                     {
4045                       mode = SImode;
4046                       if (GET_CODE (dst) != REG)
4047                         abort ();
4048                       PUT_MODE (dst, SImode);
4049                     }
4050
4051                   offset = add_constant (src, mode, &address_only);
4052                   addr = plus_constant (gen_rtx_LABEL_REF (VOIDmode,
4053                                                            pool_vector_label),
4054                                         offset);
4055
4056                   /* If we only want the address of the pool entry, or
4057                      for wide moves to integer regs we need to split
4058                      the address calculation off into a separate insn.
4059                      If necessary, the load can then be done with a
4060                      load-multiple.  This is safe, since we have
4061                      already noted the length of such insns to be 8,
4062                      and we are immediately over-writing the scratch
4063                      we have grabbed with the final result.  */
4064                   if ((address_only || GET_MODE_SIZE (mode) > 4)
4065                       && (scratch = REGNO (dst)) < 16)
4066                     {
4067                       rtx reg;
4068
4069                       if (mode == SImode)
4070                         reg = dst;
4071                       else 
4072                         reg = gen_rtx_REG (SImode, scratch);
4073
4074                       newinsn = emit_insn_after (gen_movaddr (reg, addr),
4075                                                  newinsn);
4076                       addr = reg;
4077                     }
4078
4079                   if (! address_only)
4080                     {
4081                       newsrc = gen_rtx_MEM (mode, addr);
4082
4083                       /* XXX Fixme -- I think the following is bogus.  */
4084                       /* Build a jump insn wrapper around the move instead
4085                          of an ordinary insn, because we want to have room for
4086                          the target label rtx in fld[7], which an ordinary
4087                          insn doesn't have. */
4088                       newinsn
4089                         = emit_jump_insn_after (gen_rtx_SET (VOIDmode, dst,
4090                                                              newsrc),
4091                                                 newinsn);
4092                       JUMP_LABEL (newinsn) = pool_vector_label;
4093
4094                       /* But it's still an ordinary insn */
4095                       PUT_CODE (newinsn, INSN);
4096                     }
4097
4098                   /* Kill old insn */
4099                   delete_insn (scan);
4100                   scan = newinsn;
4101                 }
4102             }
4103           dump_table (barrier);
4104           insn = scan;
4105         }
4106     }
4107
4108   after_arm_reorg = 1;
4109 }
4110
4111 \f
4112 /* Routines to output assembly language.  */
4113
4114 /* If the rtx is the correct value then return the string of the number.
4115    In this way we can ensure that valid double constants are generated even
4116    when cross compiling. */
4117 char *
4118 fp_immediate_constant (x)
4119      rtx x;
4120 {
4121   REAL_VALUE_TYPE r;
4122   int i;
4123   
4124   if (!fpa_consts_inited)
4125     init_fpa_table ();
4126   
4127   REAL_VALUE_FROM_CONST_DOUBLE (r, x);
4128   for (i = 0; i < 8; i++)
4129     if (REAL_VALUES_EQUAL (r, values_fpa[i]))
4130       return strings_fpa[i];
4131
4132   abort ();
4133 }
4134
4135 /* As for fp_immediate_constant, but value is passed directly, not in rtx.  */
4136 static char *
4137 fp_const_from_val (r)
4138      REAL_VALUE_TYPE *r;
4139 {
4140   int i;
4141
4142   if (! fpa_consts_inited)
4143     init_fpa_table ();
4144
4145   for (i = 0; i < 8; i++)
4146     if (REAL_VALUES_EQUAL (*r, values_fpa[i]))
4147       return strings_fpa[i];
4148
4149   abort ();
4150 }
4151
4152 /* Output the operands of a LDM/STM instruction to STREAM.
4153    MASK is the ARM register set mask of which only bits 0-15 are important.
4154    INSTR is the possibly suffixed base register.  HAT unequals zero if a hat
4155    must follow the register list.  */
4156
4157 void
4158 print_multi_reg (stream, instr, mask, hat)
4159      FILE *stream;
4160      char *instr;
4161      int mask, hat;
4162 {
4163   int i;
4164   int not_first = FALSE;
4165
4166   fputc ('\t', stream);
4167   fprintf (stream, instr, REGISTER_PREFIX);
4168   fputs (", {", stream);
4169   for (i = 0; i < 16; i++)
4170     if (mask & (1 << i))
4171       {
4172         if (not_first)
4173           fprintf (stream, ", ");
4174         fprintf (stream, "%s%s", REGISTER_PREFIX, reg_names[i]);
4175         not_first = TRUE;
4176       }
4177
4178   fprintf (stream, "}%s\n", hat ? "^" : "");
4179 }
4180
4181 /* Output a 'call' insn. */
4182
4183 char *
4184 output_call (operands)
4185      rtx *operands;
4186 {
4187   /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
4188
4189   if (REGNO (operands[0]) == 14)
4190     {
4191       operands[0] = gen_rtx_REG (SImode, 12);
4192       output_asm_insn ("mov%?\t%0, %|lr", operands);
4193     }
4194   output_asm_insn ("mov%?\t%|lr, %|pc", operands);
4195   
4196   if (TARGET_THUMB_INTERWORK)
4197     output_asm_insn ("bx%?\t%0", operands);
4198   else
4199     output_asm_insn ("mov%?\t%|pc, %0", operands);
4200   
4201   return "";
4202 }
4203
4204 static int
4205 eliminate_lr2ip (x)
4206      rtx *x;
4207 {
4208   int something_changed = 0;
4209   rtx x0 = *x;
4210   int code = GET_CODE (x0);
4211   register int i, j;
4212   register char *fmt;
4213   
4214   switch (code)
4215     {
4216     case REG:
4217       if (REGNO (x0) == 14)
4218         {
4219           *x = gen_rtx_REG (SImode, 12);
4220           return 1;
4221         }
4222       return 0;
4223     default:
4224       /* Scan through the sub-elements and change any references there */
4225       fmt = GET_RTX_FORMAT (code);
4226       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4227         if (fmt[i] == 'e')
4228           something_changed |= eliminate_lr2ip (&XEXP (x0, i));
4229         else if (fmt[i] == 'E')
4230           for (j = 0; j < XVECLEN (x0, i); j++)
4231             something_changed |= eliminate_lr2ip (&XVECEXP (x0, i, j));
4232       return something_changed;
4233     }
4234 }
4235   
4236 /* Output a 'call' insn that is a reference in memory. */
4237
4238 char *
4239 output_call_mem (operands)
4240      rtx *operands;
4241 {
4242   operands[0] = copy_rtx (operands[0]); /* Be ultra careful */
4243   /* Handle calls using lr by using ip (which may be clobbered in subr anyway).
4244    */
4245   if (eliminate_lr2ip (&operands[0]))
4246     output_asm_insn ("mov%?\t%|ip, %|lr", operands);
4247
4248   if (TARGET_THUMB_INTERWORK)
4249     {
4250       output_asm_insn ("ldr%?\t%|ip, %0", operands);
4251       output_asm_insn ("mov%?\t%|lr, %|pc", operands);
4252       output_asm_insn ("bx%?\t%|ip", operands);
4253     }
4254   else
4255     {
4256       output_asm_insn ("mov%?\t%|lr, %|pc", operands);
4257       output_asm_insn ("ldr%?\t%|pc, %0", operands);
4258     }
4259
4260   return "";
4261 }
4262
4263
4264 /* Output a move from arm registers to an fpu registers.
4265    OPERANDS[0] is an fpu register.
4266    OPERANDS[1] is the first registers of an arm register pair.  */
4267
4268 char *
4269 output_mov_long_double_fpu_from_arm (operands)
4270      rtx *operands;
4271 {
4272   int arm_reg0 = REGNO (operands[1]);
4273   rtx ops[3];
4274
4275   if (arm_reg0 == 12)
4276     abort();
4277
4278   ops[0] = gen_rtx_REG (SImode, arm_reg0);
4279   ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
4280   ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
4281   
4282   output_asm_insn ("stm%?fd\t%|sp!, {%0, %1, %2}", ops);
4283   output_asm_insn ("ldf%?e\t%0, [%|sp], #12", operands);
4284   return "";
4285 }
4286
4287 /* Output a move from an fpu register to arm registers.
4288    OPERANDS[0] is the first registers of an arm register pair.
4289    OPERANDS[1] is an fpu register.  */
4290
4291 char *
4292 output_mov_long_double_arm_from_fpu (operands)
4293      rtx *operands;
4294 {
4295   int arm_reg0 = REGNO (operands[0]);
4296   rtx ops[3];
4297
4298   if (arm_reg0 == 12)
4299     abort();
4300
4301   ops[0] = gen_rtx_REG (SImode, arm_reg0);
4302   ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
4303   ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
4304
4305   output_asm_insn ("stf%?e\t%1, [%|sp, #-12]!", operands);
4306   output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1, %2}", ops);
4307   return "";
4308 }
4309
4310 /* Output a move from arm registers to arm registers of a long double
4311    OPERANDS[0] is the destination.
4312    OPERANDS[1] is the source.  */
4313 char *
4314 output_mov_long_double_arm_from_arm (operands)
4315      rtx *operands;
4316 {
4317   /* We have to be careful here because the two might overlap */
4318   int dest_start = REGNO (operands[0]);
4319   int src_start = REGNO (operands[1]);
4320   rtx ops[2];
4321   int i;
4322
4323   if (dest_start < src_start)
4324     {
4325       for (i = 0; i < 3; i++)
4326         {
4327           ops[0] = gen_rtx_REG (SImode, dest_start + i);
4328           ops[1] = gen_rtx_REG (SImode, src_start + i);
4329           output_asm_insn ("mov%?\t%0, %1", ops);
4330         }
4331     }
4332   else
4333     {
4334       for (i = 2; i >= 0; i--)
4335         {
4336           ops[0] = gen_rtx_REG (SImode, dest_start + i);
4337           ops[1] = gen_rtx_REG (SImode, src_start + i);
4338           output_asm_insn ("mov%?\t%0, %1", ops);
4339         }
4340     }
4341
4342   return "";
4343 }
4344
4345
4346 /* Output a move from arm registers to an fpu registers.
4347    OPERANDS[0] is an fpu register.
4348    OPERANDS[1] is the first registers of an arm register pair.  */
4349
4350 char *
4351 output_mov_double_fpu_from_arm (operands)
4352      rtx *operands;
4353 {
4354   int arm_reg0 = REGNO (operands[1]);
4355   rtx ops[2];
4356
4357   if (arm_reg0 == 12)
4358     abort();
4359   ops[0] = gen_rtx_REG (SImode, arm_reg0);
4360   ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
4361   output_asm_insn ("stm%?fd\t%|sp!, {%0, %1}", ops);
4362   output_asm_insn ("ldf%?d\t%0, [%|sp], #8", operands);
4363   return "";
4364 }
4365
4366 /* Output a move from an fpu register to arm registers.
4367    OPERANDS[0] is the first registers of an arm register pair.
4368    OPERANDS[1] is an fpu register.  */
4369
4370 char *
4371 output_mov_double_arm_from_fpu (operands)
4372      rtx *operands;
4373 {
4374   int arm_reg0 = REGNO (operands[0]);
4375   rtx ops[2];
4376
4377   if (arm_reg0 == 12)
4378     abort();
4379
4380   ops[0] = gen_rtx_REG (SImode, arm_reg0);
4381   ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
4382   output_asm_insn ("stf%?d\t%1, [%|sp, #-8]!", operands);
4383   output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1}", ops);
4384   return "";
4385 }
4386
4387 /* Output a move between double words.
4388    It must be REG<-REG, REG<-CONST_DOUBLE, REG<-CONST_INT, REG<-MEM
4389    or MEM<-REG and all MEMs must be offsettable addresses.  */
4390
4391 char *
4392 output_move_double (operands)
4393      rtx * operands;
4394 {
4395   enum rtx_code code0 = GET_CODE (operands[0]);
4396   enum rtx_code code1 = GET_CODE (operands[1]);
4397   rtx otherops[3];
4398
4399   if (code0 == REG)
4400     {
4401       int reg0 = REGNO (operands[0]);
4402
4403       otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
4404       
4405       if (code1 == REG)
4406         {
4407           int reg1 = REGNO (operands[1]);
4408           if (reg1 == 12)
4409             abort();
4410
4411           /* Ensure the second source is not overwritten */
4412           if (reg1 == reg0 + (WORDS_BIG_ENDIAN ? -1 : 1))
4413             output_asm_insn("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands);
4414           else
4415             output_asm_insn("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
4416         }
4417       else if (code1 == CONST_DOUBLE)
4418         {
4419           if (GET_MODE (operands[1]) == DFmode)
4420             {
4421               long l[2];
4422               union real_extract u;
4423
4424               bcopy ((char *) &CONST_DOUBLE_LOW (operands[1]), (char *) &u,
4425                      sizeof (u));
4426               REAL_VALUE_TO_TARGET_DOUBLE (u.d, l);
4427               otherops[1] = GEN_INT(l[1]);
4428               operands[1] = GEN_INT(l[0]);
4429             }
4430           else if (GET_MODE (operands[1]) != VOIDmode)
4431             abort ();
4432           else if (WORDS_BIG_ENDIAN)
4433             {
4434               
4435               otherops[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4436               operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
4437             }
4438           else
4439             {
4440               
4441               otherops[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
4442               operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4443             }
4444           output_mov_immediate (operands);
4445           output_mov_immediate (otherops);
4446         }
4447       else if (code1 == CONST_INT)
4448         {
4449 #if HOST_BITS_PER_WIDE_INT > 32
4450           /* If HOST_WIDE_INT is more than 32 bits, the intval tells us
4451              what the upper word is.  */
4452           if (WORDS_BIG_ENDIAN)
4453             {
4454               otherops[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
4455               operands[1] = GEN_INT (INTVAL (operands[1]) >> 32);
4456             }
4457           else
4458             {
4459               otherops[1] = GEN_INT (INTVAL (operands[1]) >> 32);
4460               operands[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
4461             }
4462 #else
4463           /* Sign extend the intval into the high-order word */
4464           if (WORDS_BIG_ENDIAN)
4465             {
4466               otherops[1] = operands[1];
4467               operands[1] = (INTVAL (operands[1]) < 0
4468                              ? constm1_rtx : const0_rtx);
4469             }
4470           else
4471             otherops[1] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
4472 #endif
4473           output_mov_immediate (otherops);
4474           output_mov_immediate (operands);
4475         }
4476       else if (code1 == MEM)
4477         {
4478           switch (GET_CODE (XEXP (operands[1], 0)))
4479             {
4480             case REG:
4481               output_asm_insn ("ldm%?ia\t%m1, %M0", operands);
4482               break;
4483
4484             case PRE_INC:
4485               abort (); /* Should never happen now */
4486               break;
4487
4488             case PRE_DEC:
4489               output_asm_insn ("ldm%?db\t%m1!, %M0", operands);
4490               break;
4491
4492             case POST_INC:
4493               output_asm_insn ("ldm%?ia\t%m1!, %M0", operands);
4494               break;
4495
4496             case POST_DEC:
4497               abort (); /* Should never happen now */
4498               break;
4499
4500             case LABEL_REF:
4501             case CONST:
4502               output_asm_insn ("adr%?\t%0, %1", operands);
4503               output_asm_insn ("ldm%?ia\t%0, %M0", operands);
4504               break;
4505
4506             default:
4507               if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1),
4508                                    GET_MODE (XEXP (XEXP (operands[1], 0), 1))))
4509                 {
4510                   otherops[0] = operands[0];
4511                   otherops[1] = XEXP (XEXP (operands[1], 0), 0);
4512                   otherops[2] = XEXP (XEXP (operands[1], 0), 1);
4513                   if (GET_CODE (XEXP (operands[1], 0)) == PLUS)
4514                     {
4515                       if (GET_CODE (otherops[2]) == CONST_INT)
4516                         {
4517                           switch (INTVAL (otherops[2]))
4518                             {
4519                             case -8:
4520                               output_asm_insn ("ldm%?db\t%1, %M0", otherops);
4521                               return "";
4522                             case -4:
4523                               output_asm_insn ("ldm%?da\t%1, %M0", otherops);
4524                               return "";
4525                             case 4:
4526                               output_asm_insn ("ldm%?ib\t%1, %M0", otherops);
4527                               return "";
4528                             }
4529                           if (!(const_ok_for_arm (INTVAL (otherops[2]))))
4530                             output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
4531                           else
4532                             output_asm_insn ("add%?\t%0, %1, %2", otherops);
4533                         }
4534                       else
4535                         output_asm_insn ("add%?\t%0, %1, %2", otherops);
4536                     }
4537                   else
4538                     output_asm_insn ("sub%?\t%0, %1, %2", otherops);
4539                   return "ldm%?ia\t%0, %M0";
4540                 }
4541               else
4542                 {
4543                   otherops[1] = adj_offsettable_operand (operands[1], 4);
4544                   /* Take care of overlapping base/data reg.  */
4545                   if (reg_mentioned_p (operands[0], operands[1]))
4546                     {
4547                       output_asm_insn ("ldr%?\t%0, %1", otherops);
4548                       output_asm_insn ("ldr%?\t%0, %1", operands);
4549                     }
4550                   else
4551                     {
4552                       output_asm_insn ("ldr%?\t%0, %1", operands);
4553                       output_asm_insn ("ldr%?\t%0, %1", otherops);
4554                     }
4555                 }
4556             }
4557         }
4558       else
4559         abort();  /* Constraints should prevent this */
4560     }
4561   else if (code0 == MEM && code1 == REG)
4562     {
4563       if (REGNO (operands[1]) == 12)
4564         abort();
4565
4566       switch (GET_CODE (XEXP (operands[0], 0)))
4567         {
4568         case REG:
4569           output_asm_insn ("stm%?ia\t%m0, %M1", operands);
4570           break;
4571
4572         case PRE_INC:
4573           abort (); /* Should never happen now */
4574           break;
4575
4576         case PRE_DEC:
4577           output_asm_insn ("stm%?db\t%m0!, %M1", operands);
4578           break;
4579
4580         case POST_INC:
4581           output_asm_insn ("stm%?ia\t%m0!, %M1", operands);
4582           break;
4583
4584         case POST_DEC:
4585           abort (); /* Should never happen now */
4586           break;
4587
4588         case PLUS:
4589           if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
4590             {
4591               switch (INTVAL (XEXP (XEXP (operands[0], 0), 1)))
4592                 {
4593                 case -8:
4594                   output_asm_insn ("stm%?db\t%m0, %M1", operands);
4595                   return "";
4596
4597                 case -4:
4598                   output_asm_insn ("stm%?da\t%m0, %M1", operands);
4599                   return "";
4600
4601                 case 4:
4602                   output_asm_insn ("stm%?ib\t%m0, %M1", operands);
4603                   return "";
4604                 }
4605             }
4606           /* Fall through */
4607
4608         default:
4609           otherops[0] = adj_offsettable_operand (operands[0], 4);
4610           otherops[1] = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
4611           output_asm_insn ("str%?\t%1, %0", operands);
4612           output_asm_insn ("str%?\t%1, %0", otherops);
4613         }
4614     }
4615   else
4616     abort();  /* Constraints should prevent this */
4617
4618   return "";
4619 }
4620
4621
4622 /* Output an arbitrary MOV reg, #n.
4623    OPERANDS[0] is a register.  OPERANDS[1] is a const_int.  */
4624
4625 char *
4626 output_mov_immediate (operands)
4627      rtx *operands;
4628 {
4629   HOST_WIDE_INT n = INTVAL (operands[1]);
4630   int n_ones = 0;
4631   int i;
4632
4633   /* Try to use one MOV */
4634   if (const_ok_for_arm (n))
4635     {
4636       output_asm_insn ("mov%?\t%0, %1", operands);
4637       return "";
4638     }
4639
4640   /* Try to use one MVN */
4641   if (const_ok_for_arm (~n))
4642     {
4643       operands[1] = GEN_INT (~n);
4644       output_asm_insn ("mvn%?\t%0, %1", operands);
4645       return "";
4646     }
4647
4648   /* If all else fails, make it out of ORRs or BICs as appropriate. */
4649
4650   for (i=0; i < 32; i++)
4651     if (n & 1 << i)
4652       n_ones++;
4653
4654   if (n_ones > 16)  /* Shorter to use MVN with BIC in this case. */
4655     output_multi_immediate(operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1,
4656                            ~n);
4657   else
4658     output_multi_immediate(operands, "mov%?\t%0, %1", "orr%?\t%0, %0, %1", 1,
4659                            n);
4660
4661   return "";
4662 }
4663
4664
4665 /* Output an ADD r, s, #n where n may be too big for one instruction.  If
4666    adding zero to one register, output nothing.  */
4667
4668 char *
4669 output_add_immediate (operands)
4670      rtx *operands;
4671 {
4672   HOST_WIDE_INT n = INTVAL (operands[2]);
4673
4674   if (n != 0 || REGNO (operands[0]) != REGNO (operands[1]))
4675     {
4676       if (n < 0)
4677         output_multi_immediate (operands,
4678                                 "sub%?\t%0, %1, %2", "sub%?\t%0, %0, %2", 2,
4679                                 -n);
4680       else
4681         output_multi_immediate (operands,
4682                                 "add%?\t%0, %1, %2", "add%?\t%0, %0, %2", 2,
4683                                 n);
4684     }
4685
4686   return "";
4687 }
4688
4689 /* Output a multiple immediate operation.
4690    OPERANDS is the vector of operands referred to in the output patterns.
4691    INSTR1 is the output pattern to use for the first constant.
4692    INSTR2 is the output pattern to use for subsequent constants.
4693    IMMED_OP is the index of the constant slot in OPERANDS.
4694    N is the constant value.  */
4695
4696 static char *
4697 output_multi_immediate (operands, instr1, instr2, immed_op, n)
4698      rtx *operands;
4699      char *instr1, *instr2;
4700      int immed_op;
4701      HOST_WIDE_INT n;
4702 {
4703 #if HOST_BITS_PER_WIDE_INT > 32
4704   n &= 0xffffffff;
4705 #endif
4706
4707   if (n == 0)
4708     {
4709       operands[immed_op] = const0_rtx;
4710       output_asm_insn (instr1, operands); /* Quick and easy output */
4711     }
4712   else
4713     {
4714       int i;
4715       char *instr = instr1;
4716
4717       /* Note that n is never zero here (which would give no output) */
4718       for (i = 0; i < 32; i += 2)
4719         {
4720           if (n & (3 << i))
4721             {
4722               operands[immed_op] = GEN_INT (n & (255 << i));
4723               output_asm_insn (instr, operands);
4724               instr = instr2;
4725               i += 6;
4726             }
4727         }
4728     }
4729   return "";
4730 }
4731
4732
4733 /* Return the appropriate ARM instruction for the operation code.
4734    The returned result should not be overwritten.  OP is the rtx of the
4735    operation.  SHIFT_FIRST_ARG is TRUE if the first argument of the operator
4736    was shifted.  */
4737
4738 char *
4739 arithmetic_instr (op, shift_first_arg)
4740      rtx op;
4741      int shift_first_arg;
4742 {
4743   switch (GET_CODE (op))
4744     {
4745     case PLUS:
4746       return "add";
4747
4748     case MINUS:
4749       return shift_first_arg ? "rsb" : "sub";
4750
4751     case IOR:
4752       return "orr";
4753
4754     case XOR:
4755       return "eor";
4756
4757     case AND:
4758       return "and";
4759
4760     default:
4761       abort ();
4762     }
4763 }
4764
4765
4766 /* Ensure valid constant shifts and return the appropriate shift mnemonic
4767    for the operation code.  The returned result should not be overwritten.
4768    OP is the rtx code of the shift.
4769    On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
4770    shift. */
4771
4772 static char *
4773 shift_op (op, amountp)
4774      rtx op;
4775      HOST_WIDE_INT *amountp;
4776 {
4777   char *mnem;
4778   enum rtx_code code = GET_CODE (op);
4779
4780   if (GET_CODE (XEXP (op, 1)) == REG || GET_CODE (XEXP (op, 1)) == SUBREG)
4781     *amountp = -1;
4782   else if (GET_CODE (XEXP (op, 1)) == CONST_INT)
4783     *amountp = INTVAL (XEXP (op, 1));
4784   else
4785     abort ();
4786
4787   switch (code)
4788     {
4789     case ASHIFT:
4790       mnem = "asl";
4791       break;
4792
4793     case ASHIFTRT:
4794       mnem = "asr";
4795       break;
4796
4797     case LSHIFTRT:
4798       mnem = "lsr";
4799       break;
4800
4801     case ROTATERT:
4802       mnem = "ror";
4803       break;
4804
4805     case MULT:
4806       /* We never have to worry about the amount being other than a
4807          power of 2, since this case can never be reloaded from a reg.  */
4808       if (*amountp != -1)
4809         *amountp = int_log2 (*amountp);
4810       else
4811         abort ();
4812       return "asl";
4813
4814     default:
4815       abort ();
4816     }
4817
4818   if (*amountp != -1)
4819     {
4820       /* This is not 100% correct, but follows from the desire to merge
4821          multiplication by a power of 2 with the recognizer for a
4822          shift.  >=32 is not a valid shift for "asl", so we must try and
4823          output a shift that produces the correct arithmetical result.
4824          Using lsr #32 is identical except for the fact that the carry bit
4825          is not set correctly if we set the flags; but we never use the 
4826          carry bit from such an operation, so we can ignore that.  */
4827       if (code == ROTATERT)
4828         *amountp &= 31;         /* Rotate is just modulo 32 */
4829       else if (*amountp != (*amountp & 31))
4830         {
4831           if (code == ASHIFT)
4832             mnem = "lsr";
4833           *amountp = 32;
4834         }
4835
4836       /* Shifts of 0 are no-ops.  */
4837       if (*amountp == 0)
4838         return NULL;
4839     }     
4840
4841   return mnem;
4842 }
4843
4844
4845 /* Obtain the shift from the POWER of two. */
4846
4847 static HOST_WIDE_INT
4848 int_log2 (power)
4849      HOST_WIDE_INT power;
4850 {
4851   HOST_WIDE_INT shift = 0;
4852
4853   while (((((HOST_WIDE_INT) 1) << shift) & power) == 0)
4854     {
4855       if (shift > 31)
4856         abort ();
4857       shift++;
4858     }
4859
4860   return shift;
4861 }
4862
4863 /* Output a .ascii pseudo-op, keeping track of lengths.  This is because
4864    /bin/as is horribly restrictive.  */
4865
4866 void
4867 output_ascii_pseudo_op (stream, p, len)
4868      FILE *stream;
4869      unsigned char *p;
4870      int len;
4871 {
4872   int i;
4873   int len_so_far = 1000;
4874   int chars_so_far = 0;
4875
4876   for (i = 0; i < len; i++)
4877     {
4878       register int c = p[i];
4879
4880       if (len_so_far > 50)
4881         {
4882           if (chars_so_far)
4883             fputs ("\"\n", stream);
4884           fputs ("\t.ascii\t\"", stream);
4885           len_so_far = 0;
4886           chars_so_far = 0;
4887         }
4888
4889       if (c == '\"' || c == '\\')
4890         {
4891           putc('\\', stream);
4892           len_so_far++;
4893         }
4894
4895       if (c >= ' ' && c < 0177)
4896         {
4897           putc (c, stream);
4898           len_so_far++;
4899         }
4900       else
4901         {
4902           fprintf (stream, "\\%03o", c);
4903           len_so_far +=4;
4904         }
4905
4906       chars_so_far++;
4907     }
4908
4909   fputs ("\"\n", stream);
4910 }
4911 \f
4912
4913 /* Try to determine whether a pattern really clobbers the link register.
4914    This information is useful when peepholing, so that lr need not be pushed
4915    if we combine a call followed by a return.
4916    NOTE: This code does not check for side-effect expressions in a SET_SRC:
4917    such a check should not be needed because these only update an existing
4918    value within a register; the register must still be set elsewhere within
4919    the function. */
4920
4921 static int
4922 pattern_really_clobbers_lr (x)
4923      rtx x;
4924 {
4925   int i;
4926   
4927   switch (GET_CODE (x))
4928     {
4929     case SET:
4930       switch (GET_CODE (SET_DEST (x)))
4931         {
4932         case REG:
4933           return REGNO (SET_DEST (x)) == 14;
4934
4935         case SUBREG:
4936           if (GET_CODE (XEXP (SET_DEST (x), 0)) == REG)
4937             return REGNO (XEXP (SET_DEST (x), 0)) == 14;
4938
4939           if (GET_CODE (XEXP (SET_DEST (x), 0)) == MEM)
4940             return 0;
4941           abort ();
4942
4943         default:
4944           return 0;
4945         }
4946
4947     case PARALLEL:
4948       for (i = 0; i < XVECLEN (x, 0); i++)
4949         if (pattern_really_clobbers_lr (XVECEXP (x, 0, i)))
4950           return 1;
4951       return 0;
4952
4953     case CLOBBER:
4954       switch (GET_CODE (XEXP (x, 0)))
4955         {
4956         case REG:
4957           return REGNO (XEXP (x, 0)) == 14;
4958
4959         case SUBREG:
4960           if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG)
4961             return REGNO (XEXP (XEXP (x, 0), 0)) == 14;
4962           abort ();
4963
4964         default:
4965           return 0;
4966         }
4967
4968     case UNSPEC:
4969       return 1;
4970
4971     default:
4972       return 0;
4973     }
4974 }
4975
4976 static int
4977 function_really_clobbers_lr (first)
4978      rtx first;
4979 {
4980   rtx insn, next;
4981   
4982   for (insn = first; insn; insn = next_nonnote_insn (insn))
4983     {
4984       switch (GET_CODE (insn))
4985         {
4986         case BARRIER:
4987         case NOTE:
4988         case CODE_LABEL:
4989         case JUMP_INSN:         /* Jump insns only change the PC (and conds) */
4990         case INLINE_HEADER:
4991           break;
4992
4993         case INSN:
4994           if (pattern_really_clobbers_lr (PATTERN (insn)))
4995             return 1;
4996           break;
4997
4998         case CALL_INSN:
4999           /* Don't yet know how to handle those calls that are not to a 
5000              SYMBOL_REF */
5001           if (GET_CODE (PATTERN (insn)) != PARALLEL)
5002             abort ();
5003
5004           switch (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)))
5005             {
5006             case CALL:
5007               if (GET_CODE (XEXP (XEXP (XVECEXP (PATTERN (insn), 0, 0), 0), 0))
5008                   != SYMBOL_REF)
5009                 return 1;
5010               break;
5011
5012             case SET:
5013               if (GET_CODE (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn),
5014                                                           0, 0)), 0), 0))
5015                   != SYMBOL_REF)
5016                 return 1;
5017               break;
5018
5019             default:    /* Don't recognize it, be safe */
5020               return 1;
5021             }
5022
5023           /* A call can be made (by peepholing) not to clobber lr iff it is
5024              followed by a return.  There may, however, be a use insn iff
5025              we are returning the result of the call. 
5026              If we run off the end of the insn chain, then that means the
5027              call was at the end of the function.  Unfortunately we don't
5028              have a return insn for the peephole to recognize, so we
5029              must reject this.  (Can this be fixed by adding our own insn?) */
5030           if ((next = next_nonnote_insn (insn)) == NULL)
5031             return 1;
5032
5033           /* No need to worry about lr if the call never returns */
5034           if (GET_CODE (next) == BARRIER)
5035             break;
5036
5037           if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == USE
5038               && (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
5039               && (REGNO (SET_DEST (XVECEXP (PATTERN (insn), 0, 0)))
5040                   == REGNO (XEXP (PATTERN (next), 0))))
5041             if ((next = next_nonnote_insn (next)) == NULL)
5042               return 1;
5043
5044           if (GET_CODE (next) == JUMP_INSN
5045               && GET_CODE (PATTERN (next)) == RETURN)
5046             break;
5047           return 1;
5048
5049         default:
5050           abort ();
5051         }
5052     }
5053
5054   /* We have reached the end of the chain so lr was _not_ clobbered */
5055   return 0;
5056 }
5057
5058 char *
5059 output_return_instruction (operand, really_return, reverse)
5060      rtx operand;
5061      int really_return;
5062      int reverse;
5063 {
5064   char instr[100];
5065   int reg, live_regs = 0;
5066   int volatile_func = (optimize > 0 
5067                        && TREE_THIS_VOLATILE (current_function_decl));
5068
5069   return_used_this_function = 1;
5070
5071   if (volatile_func)
5072     {
5073       rtx ops[2];
5074       /* If this function was declared non-returning, and we have found a tail 
5075          call, then we have to trust that the called function won't return. */
5076       if (! really_return)
5077         return "";
5078
5079       /* Otherwise, trap an attempted return by aborting. */
5080       ops[0] = operand;
5081       ops[1] = gen_rtx_SYMBOL_REF (Pmode, "abort");
5082       assemble_external_libcall (ops[1]);
5083       output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
5084       return "";
5085     }
5086       
5087   if (current_function_calls_alloca && ! really_return)
5088     abort();
5089     
5090   for (reg = 0; reg <= 10; reg++)
5091     if (regs_ever_live[reg] && ! call_used_regs[reg])
5092       live_regs++;
5093
5094   if (live_regs || (regs_ever_live[14] && ! lr_save_eliminated))
5095     live_regs++;
5096
5097   if (frame_pointer_needed)
5098     live_regs += 4;
5099
5100   if (live_regs)
5101     {
5102       if (lr_save_eliminated || ! regs_ever_live[14])
5103         live_regs++;
5104
5105       if (frame_pointer_needed)
5106         strcpy (instr,
5107                 reverse ? "ldm%?%D0ea\t%|fp, {" : "ldm%?%d0ea\t%|fp, {");
5108       else
5109         strcpy (instr, 
5110                 reverse ? "ldm%?%D0fd\t%|sp!, {" : "ldm%?%d0fd\t%|sp!, {");
5111
5112       for (reg = 0; reg <= 10; reg++)
5113         if (regs_ever_live[reg] && ! call_used_regs[reg])
5114           {
5115             strcat (instr, "%|");
5116             strcat (instr, reg_names[reg]);
5117             if (--live_regs)
5118               strcat (instr, ", ");
5119           }
5120
5121       if (frame_pointer_needed)
5122         {
5123           strcat (instr, "%|");
5124           strcat (instr, reg_names[11]);
5125           strcat (instr, ", ");
5126           strcat (instr, "%|");
5127           strcat (instr, reg_names[13]);
5128           strcat (instr, ", ");
5129           strcat (instr, "%|");
5130           strcat (instr, TARGET_THUMB_INTERWORK || (! really_return)
5131                   ? reg_names[14] : reg_names[15] );
5132         }
5133       else
5134         {
5135           strcat (instr, "%|");
5136           if (TARGET_THUMB_INTERWORK && really_return)
5137             strcat (instr, reg_names[12]);
5138           else
5139             strcat (instr, really_return ? reg_names[15] : reg_names[14]);
5140         }
5141       strcat (instr, (TARGET_APCS_32 || !really_return) ? "}" : "}^");
5142       output_asm_insn (instr, &operand);
5143
5144       if (TARGET_THUMB_INTERWORK && really_return)
5145         {
5146           strcpy (instr, "bx%?");
5147           strcat (instr, reverse ? "%D0" : "%d0");
5148           strcat (instr, "\t%|");
5149           strcat (instr, frame_pointer_needed ? "lr" : "ip");
5150
5151           output_asm_insn (instr, & operand);
5152         }
5153     }
5154   else if (really_return)
5155     {
5156       if (TARGET_THUMB_INTERWORK)
5157         sprintf (instr, "bx%%?%%%s0\t%%|lr", reverse ? "D" : "d");
5158       else
5159         sprintf (instr, "mov%%?%%%s0%s\t%%|pc, %%|lr",
5160                  reverse ? "D" : "d", TARGET_APCS_32 ? "" : "s");
5161       
5162       output_asm_insn (instr, & operand);
5163     }
5164
5165   return "";
5166 }
5167
5168 /* Return nonzero if optimizing and the current function is volatile.
5169    Such functions never return, and many memory cycles can be saved
5170    by not storing register values that will never be needed again.
5171    This optimization was added to speed up context switching in a
5172    kernel application. */
5173
5174 int
5175 arm_volatile_func ()
5176 {
5177   return (optimize > 0 && TREE_THIS_VOLATILE (current_function_decl));
5178 }
5179
5180 /* The amount of stack adjustment that happens here, in output_return and in
5181    output_epilogue must be exactly the same as was calculated during reload,
5182    or things will point to the wrong place.  The only time we can safely
5183    ignore this constraint is when a function has no arguments on the stack,
5184    no stack frame requirement and no live registers execpt for `lr'.  If we
5185    can guarantee that by making all function calls into tail calls and that
5186    lr is not clobbered in any other way, then there is no need to push lr
5187    onto the stack. */
5188    
5189 void
5190 output_func_prologue (f, frame_size)
5191      FILE *f;
5192      int frame_size;
5193 {
5194   int reg, live_regs_mask = 0;
5195   int volatile_func = (optimize > 0
5196                        && TREE_THIS_VOLATILE (current_function_decl));
5197
5198   /* Nonzero if we must stuff some register arguments onto the stack as if
5199      they were passed there.  */
5200   int store_arg_regs = 0;
5201
5202   if (arm_ccfsm_state || arm_target_insn)
5203     abort ();                                   /* Sanity check */
5204
5205   if (arm_naked_function_p (current_function_decl))
5206     return;
5207
5208   return_used_this_function = 0;
5209   lr_save_eliminated = 0;
5210   
5211   fprintf (f, "\t%s args = %d, pretend = %d, frame = %d\n",
5212            ASM_COMMENT_START, current_function_args_size,
5213            current_function_pretend_args_size, frame_size);
5214   fprintf (f, "\t%s frame_needed = %d, current_function_anonymous_args = %d\n",
5215            ASM_COMMENT_START, frame_pointer_needed,
5216            current_function_anonymous_args);
5217
5218   if (volatile_func)
5219     fprintf (f, "\t%s Volatile function.\n", ASM_COMMENT_START);
5220
5221   if (current_function_anonymous_args && current_function_pretend_args_size)
5222     store_arg_regs = 1;
5223
5224   for (reg = 0; reg <= 10; reg++)
5225     if (regs_ever_live[reg] && ! call_used_regs[reg])
5226       live_regs_mask |= (1 << reg);
5227
5228   if (frame_pointer_needed)
5229     live_regs_mask |= 0xD800;
5230   else if (regs_ever_live[14])
5231     {
5232       if (! current_function_args_size
5233           && ! function_really_clobbers_lr (get_insns ()))
5234         lr_save_eliminated = 1;
5235       else
5236         live_regs_mask |= 0x4000;
5237     }
5238
5239   if (live_regs_mask)
5240     {
5241       /* if a di mode load/store multiple is used, and the base register
5242          is r3, then r4 can become an ever live register without lr
5243          doing so,  in this case we need to push lr as well, or we
5244          will fail to get a proper return. */
5245
5246       live_regs_mask |= 0x4000;
5247       lr_save_eliminated = 0;
5248
5249     }
5250
5251   if (lr_save_eliminated)
5252     fprintf (f,"\t%s I don't think this function clobbers lr\n",
5253              ASM_COMMENT_START);
5254
5255 #ifdef AOF_ASSEMBLER
5256   if (flag_pic)
5257     fprintf (f, "\tmov\t%sip, %s%s\n", REGISTER_PREFIX, REGISTER_PREFIX,
5258              reg_names[PIC_OFFSET_TABLE_REGNUM]);
5259 #endif
5260 }
5261
5262
5263 void
5264 output_func_epilogue (f, frame_size)
5265      FILE *f;
5266      int frame_size;
5267 {
5268   int reg, live_regs_mask = 0;
5269   /* If we need this then it will always be at least this much */
5270   int floats_offset = 12;
5271   rtx operands[3];
5272   int volatile_func = (optimize > 0
5273                        && TREE_THIS_VOLATILE (current_function_decl));
5274
5275   if (use_return_insn (FALSE) && return_used_this_function)
5276     {
5277       if ((frame_size + current_function_outgoing_args_size) != 0
5278           && !(frame_pointer_needed && TARGET_APCS))
5279         abort ();
5280       goto epilogue_done;
5281     }
5282
5283   /* Naked functions don't have epilogues.  */
5284   if (arm_naked_function_p (current_function_decl))
5285     goto epilogue_done;
5286
5287   /* A volatile function should never return.  Call abort.  */
5288   if (TARGET_ABORT_NORETURN && volatile_func)
5289     {
5290       rtx op = gen_rtx_SYMBOL_REF (Pmode, "abort");
5291       assemble_external_libcall (op);
5292       output_asm_insn ("bl\t%a0", &op);
5293       goto epilogue_done;
5294     }
5295
5296   for (reg = 0; reg <= 10; reg++)
5297     if (regs_ever_live[reg] && ! call_used_regs[reg])
5298       {
5299         live_regs_mask |= (1 << reg);
5300         floats_offset += 4;
5301       }
5302
5303   if (frame_pointer_needed)
5304     {
5305       if (arm_fpu_arch == FP_SOFT2)
5306         {
5307           for (reg = 23; reg > 15; reg--)
5308             if (regs_ever_live[reg] && ! call_used_regs[reg])
5309               {
5310                 floats_offset += 12;
5311                 fprintf (f, "\tldfe\t%s%s, [%sfp, #-%d]\n", REGISTER_PREFIX,
5312                          reg_names[reg], REGISTER_PREFIX, floats_offset);
5313               }
5314         }
5315       else
5316         {
5317           int start_reg = 23;
5318
5319           for (reg = 23; reg > 15; reg--)
5320             {
5321               if (regs_ever_live[reg] && ! call_used_regs[reg])
5322                 {
5323                   floats_offset += 12;
5324                   /* We can't unstack more than four registers at once */
5325                   if (start_reg - reg == 3)
5326                     {
5327                       fprintf (f, "\tlfm\t%s%s, 4, [%sfp, #-%d]\n",
5328                                REGISTER_PREFIX, reg_names[reg],
5329                                REGISTER_PREFIX, floats_offset);
5330                       start_reg = reg - 1;
5331                     }
5332                 }
5333               else
5334                 {
5335                   if (reg != start_reg)
5336                     fprintf (f, "\tlfm\t%s%s, %d, [%sfp, #-%d]\n",
5337                              REGISTER_PREFIX, reg_names[reg + 1],
5338                              start_reg - reg, REGISTER_PREFIX, floats_offset);
5339
5340                   start_reg = reg - 1;
5341                 }
5342             }
5343
5344           /* Just in case the last register checked also needs unstacking.  */
5345           if (reg != start_reg)
5346             fprintf (f, "\tlfm\t%s%s, %d, [%sfp, #-%d]\n",
5347                      REGISTER_PREFIX, reg_names[reg + 1],
5348                      start_reg - reg, REGISTER_PREFIX, floats_offset);
5349         }
5350       
5351       if (TARGET_THUMB_INTERWORK)
5352         {
5353           live_regs_mask |= 0x6800;
5354           print_multi_reg (f, "ldmea\t%sfp", live_regs_mask, FALSE);
5355           fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
5356         }
5357       else
5358         {
5359           live_regs_mask |= 0xA800;
5360           print_multi_reg (f, "ldmea\t%sfp", live_regs_mask,
5361                            TARGET_APCS_32 ? FALSE : TRUE);
5362         }
5363     }
5364   else
5365     {
5366       /* Restore stack pointer if necessary.  */
5367       if (frame_size + current_function_outgoing_args_size != 0)
5368         {
5369           operands[0] = operands[1] = stack_pointer_rtx;
5370           operands[2] = GEN_INT (frame_size
5371                                  + current_function_outgoing_args_size);
5372           output_add_immediate (operands);
5373         }
5374
5375       if (arm_fpu_arch == FP_SOFT2)
5376         {
5377           for (reg = 16; reg < 24; reg++)
5378             if (regs_ever_live[reg] && ! call_used_regs[reg])
5379               fprintf (f, "\tldfe\t%s%s, [%ssp], #12\n", REGISTER_PREFIX,
5380                        reg_names[reg], REGISTER_PREFIX);
5381         }
5382       else
5383         {
5384           int start_reg = 16;
5385
5386           for (reg = 16; reg < 24; reg++)
5387             {
5388               if (regs_ever_live[reg] && ! call_used_regs[reg])
5389                 {
5390                   if (reg - start_reg == 3)
5391                     {
5392                       fprintf (f, "\tlfmfd\t%s%s, 4, [%ssp]!\n",
5393                                REGISTER_PREFIX, reg_names[start_reg],
5394                                REGISTER_PREFIX);
5395                       start_reg = reg + 1;
5396                     }
5397                 }
5398               else
5399                 {
5400                   if (reg != start_reg)
5401                     fprintf (f, "\tlfmfd\t%s%s, %d, [%ssp]!\n",
5402                              REGISTER_PREFIX, reg_names[start_reg],
5403                              reg - start_reg, REGISTER_PREFIX);
5404
5405                   start_reg = reg + 1;
5406                 }
5407             }
5408
5409           /* Just in case the last register checked also needs unstacking.  */
5410           if (reg != start_reg)
5411             fprintf (f, "\tlfmfd\t%s%s, %d, [%ssp]!\n",
5412                      REGISTER_PREFIX, reg_names[start_reg],
5413                      reg - start_reg, REGISTER_PREFIX);
5414         }
5415
5416       if (current_function_pretend_args_size == 0 && regs_ever_live[14])
5417         {
5418           if (TARGET_THUMB_INTERWORK)
5419             {
5420               if (! lr_save_eliminated)
5421                 live_regs_mask |= 0x4000;
5422
5423               if (live_regs_mask != 0)
5424                 print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask, FALSE);
5425
5426               fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
5427             }
5428           else if (lr_save_eliminated)
5429             fprintf (f, (TARGET_APCS_32 ? "\tmov\t%spc, %slr\n"
5430                          : "\tmovs\t%spc, %slr\n"),
5431                      REGISTER_PREFIX, REGISTER_PREFIX, f);
5432           else
5433             print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask | 0x8000,
5434                              TARGET_APCS_32 ? FALSE : TRUE);
5435         }
5436       else
5437         {
5438           if (live_regs_mask || regs_ever_live[14])
5439             {
5440               /* Restore the integer regs, and the return address into lr */
5441               if (! lr_save_eliminated)
5442                 live_regs_mask |= 0x4000;
5443
5444               if (live_regs_mask != 0)
5445                 print_multi_reg (f, "ldmfd\t%ssp!", live_regs_mask, FALSE);
5446             }
5447
5448           if (current_function_pretend_args_size)
5449             {
5450               /* Unwind the pre-pushed regs */
5451               operands[0] = operands[1] = stack_pointer_rtx;
5452               operands[2] = GEN_INT (current_function_pretend_args_size);
5453               output_add_immediate (operands);
5454             }
5455           /* And finally, go home */
5456           if (TARGET_THUMB_INTERWORK)
5457             fprintf (f, "\tbx\t%slr\n", REGISTER_PREFIX);
5458           else if (TARGET_APCS_32)
5459             fprintf (f, "\tmov\t%spc, %slr\n", REGISTER_PREFIX, REGISTER_PREFIX );
5460           else
5461             fprintf (f, "\tmovs\t%spc, %slr\n", REGISTER_PREFIX, REGISTER_PREFIX );
5462         }
5463     }
5464
5465 epilogue_done:
5466
5467   /* Reset the ARM-specific per-function variables.  */
5468   current_function_anonymous_args = 0;
5469   after_arm_reorg = 0;
5470 }
5471
5472 static void
5473 emit_multi_reg_push (mask)
5474      int mask;
5475 {
5476   int num_regs = 0;
5477   int i, j;
5478   rtx par;
5479
5480   for (i = 0; i < 16; i++)
5481     if (mask & (1 << i))
5482       num_regs++;
5483
5484   if (num_regs == 0 || num_regs > 16)
5485     abort ();
5486
5487   par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
5488
5489   for (i = 0; i < 16; i++)
5490     {
5491       if (mask & (1 << i))
5492         {
5493           XVECEXP (par, 0, 0)
5494             = gen_rtx_SET (VOIDmode,
5495                            gen_rtx_MEM (BLKmode,
5496                                         gen_rtx_PRE_DEC (BLKmode,
5497                                                          stack_pointer_rtx)),
5498                            gen_rtx_UNSPEC (BLKmode,
5499                                            gen_rtvec (1,
5500                                                       gen_rtx_REG (SImode, i)),
5501                                            2));
5502           break;
5503         }
5504     }
5505
5506   for (j = 1, i++; j < num_regs; i++)
5507     {
5508       if (mask & (1 << i))
5509         {
5510           XVECEXP (par, 0, j)
5511             = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, i));
5512           j++;
5513         }
5514     }
5515
5516   emit_insn (par);
5517 }
5518
5519 static void
5520 emit_sfm (base_reg, count)
5521      int base_reg;
5522      int count;
5523 {
5524   rtx par;
5525   int i;
5526
5527   par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
5528
5529   XVECEXP (par, 0, 0)
5530     = gen_rtx_SET (VOIDmode, 
5531                    gen_rtx_MEM (BLKmode,
5532                                 gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
5533                    gen_rtx_UNSPEC (BLKmode,
5534                                    gen_rtvec (1, gen_rtx_REG (XFmode, 
5535                                                               base_reg++)),
5536                                    2));
5537   for (i = 1; i < count; i++)
5538     XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode, 
5539                                        gen_rtx_REG (XFmode, base_reg++));
5540
5541   emit_insn (par);
5542 }
5543
5544 void
5545 arm_expand_prologue ()
5546 {
5547   int reg;
5548   rtx amount = GEN_INT (-(get_frame_size ()
5549                           + current_function_outgoing_args_size));
5550   int live_regs_mask = 0;
5551   int store_arg_regs = 0;
5552   int volatile_func = (optimize > 0
5553                        && TREE_THIS_VOLATILE (current_function_decl));
5554
5555   /* Naked functions don't have prologues.  */
5556   if (arm_naked_function_p (current_function_decl))
5557     return;
5558
5559   if (current_function_anonymous_args && current_function_pretend_args_size)
5560     store_arg_regs = 1;
5561
5562   if (! volatile_func)
5563     for (reg = 0; reg <= 10; reg++)
5564       if (regs_ever_live[reg] && ! call_used_regs[reg])
5565         live_regs_mask |= 1 << reg;
5566
5567   if (! volatile_func && regs_ever_live[14])
5568     live_regs_mask |= 0x4000;
5569
5570   if (frame_pointer_needed)
5571     {
5572       live_regs_mask |= 0xD800;
5573       emit_insn (gen_movsi (gen_rtx_REG (SImode, 12),
5574                             stack_pointer_rtx));
5575     }
5576
5577   if (current_function_pretend_args_size)
5578     {
5579       if (store_arg_regs)
5580         emit_multi_reg_push ((0xf0 >> (current_function_pretend_args_size / 4))
5581                              & 0xf);
5582       else
5583         emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 
5584                                GEN_INT (-current_function_pretend_args_size)));
5585     }
5586
5587   if (live_regs_mask)
5588     {
5589       /* If we have to push any regs, then we must push lr as well, or
5590          we won't get a proper return.  */
5591       live_regs_mask |= 0x4000;
5592       emit_multi_reg_push (live_regs_mask);
5593     }
5594       
5595   /* For now the integer regs are still pushed in output_func_epilogue ().  */
5596
5597   if (! volatile_func)
5598     {
5599       if (arm_fpu_arch == FP_SOFT2)
5600         {
5601           for (reg = 23; reg > 15; reg--)
5602             if (regs_ever_live[reg] && ! call_used_regs[reg])
5603               emit_insn (gen_rtx_SET
5604                          (VOIDmode, 
5605                           gen_rtx_MEM (XFmode, 
5606                                        gen_rtx_PRE_DEC (XFmode,
5607                                                         stack_pointer_rtx)),
5608                           gen_rtx_REG (XFmode, reg)));
5609         }
5610       else
5611         {
5612           int start_reg = 23;
5613
5614           for (reg = 23; reg > 15; reg--)
5615             {
5616               if (regs_ever_live[reg] && ! call_used_regs[reg])
5617                 {
5618                   if (start_reg - reg == 3)
5619                     {
5620                       emit_sfm (reg, 4);
5621                       start_reg = reg - 1;
5622                     }
5623                 }
5624               else
5625                 {
5626                   if (start_reg != reg)
5627                     emit_sfm (reg + 1, start_reg - reg);
5628                   start_reg = reg - 1;
5629                 }
5630             }
5631
5632           if (start_reg != reg)
5633             emit_sfm (reg + 1, start_reg - reg);
5634         }
5635     }
5636
5637   if (frame_pointer_needed)
5638     emit_insn (gen_addsi3 (hard_frame_pointer_rtx, gen_rtx_REG (SImode, 12),
5639                            (GEN_INT
5640                             (-(4 + current_function_pretend_args_size)))));
5641
5642   if (amount != const0_rtx)
5643     {
5644       emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, amount));
5645       emit_insn (gen_rtx_CLOBBER (VOIDmode, 
5646                                   gen_rtx_MEM (BLKmode, stack_pointer_rtx)));
5647     }
5648
5649   /* If we are profiling, make sure no instructions are scheduled before
5650      the call to mcount.  Similarly if the user has requested no
5651      scheduling in the prolog.  */
5652   if (profile_flag || profile_block_flag || TARGET_NO_SCHED_PRO)
5653     emit_insn (gen_blockage ());
5654 }
5655   
5656 \f
5657 /* If CODE is 'd', then the X is a condition operand and the instruction
5658    should only be executed if the condition is true.
5659    if CODE is 'D', then the X is a condition operand and the instruction
5660    should only be executed if the condition is false: however, if the mode
5661    of the comparison is CCFPEmode, then always execute the instruction -- we
5662    do this because in these circumstances !GE does not necessarily imply LT;
5663    in these cases the instruction pattern will take care to make sure that
5664    an instruction containing %d will follow, thereby undoing the effects of
5665    doing this instruction unconditionally.
5666    If CODE is 'N' then X is a floating point operand that must be negated
5667    before output.
5668    If CODE is 'B' then output a bitwise inverted value of X (a const int).
5669    If X is a REG and CODE is `M', output a ldm/stm style multi-reg.  */
5670
5671 void
5672 arm_print_operand (stream, x, code)
5673      FILE *stream;
5674      rtx x;
5675      int code;
5676 {
5677   switch (code)
5678     {
5679     case '@':
5680       fputs (ASM_COMMENT_START, stream);
5681       return;
5682
5683     case '|':
5684       fputs (REGISTER_PREFIX, stream);
5685       return;
5686
5687     case '?':
5688       if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
5689         fputs (arm_condition_codes[arm_current_cc], stream);
5690       return;
5691
5692     case 'N':
5693       {
5694         REAL_VALUE_TYPE r;
5695         REAL_VALUE_FROM_CONST_DOUBLE (r, x);
5696         r = REAL_VALUE_NEGATE (r);
5697         fprintf (stream, "%s", fp_const_from_val (&r));
5698       }
5699       return;
5700
5701     case 'B':
5702       if (GET_CODE (x) == CONST_INT)
5703         fprintf (stream,
5704 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
5705                  "%d",
5706 #else
5707                  "%ld",
5708 #endif
5709                  ARM_SIGN_EXTEND (~ INTVAL (x)));
5710       else
5711         {
5712           putc ('~', stream);
5713           output_addr_const (stream, x);
5714         }
5715       return;
5716
5717     case 'i':
5718       fprintf (stream, "%s", arithmetic_instr (x, 1));
5719       return;
5720
5721     case 'I':
5722       fprintf (stream, "%s", arithmetic_instr (x, 0));
5723       return;
5724
5725     case 'S':
5726       {
5727         HOST_WIDE_INT val;
5728         char *shift = shift_op (x, &val);
5729
5730         if (shift)
5731           {
5732             fprintf (stream, ", %s ", shift_op (x, &val));
5733             if (val == -1)
5734               arm_print_operand (stream, XEXP (x, 1), 0);
5735             else
5736               fprintf (stream,
5737 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
5738                        "#%d",
5739 #else
5740                        "#%ld",
5741 #endif
5742                        val);
5743           }
5744       }
5745       return;
5746
5747     case 'Q':
5748       if (REGNO (x) > 15)
5749         abort ();
5750       fputs (REGISTER_PREFIX, stream);
5751       fputs (reg_names[REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0)], stream);
5752       return;
5753
5754     case 'R':
5755       if (REGNO (x) > 15)
5756         abort ();
5757       fputs (REGISTER_PREFIX, stream);
5758       fputs (reg_names[REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1)], stream);
5759       return;
5760
5761     case 'm':
5762       fputs (REGISTER_PREFIX, stream);
5763       if (GET_CODE (XEXP (x, 0)) == REG)
5764         fputs (reg_names[REGNO (XEXP (x, 0))], stream);
5765       else
5766         fputs (reg_names[REGNO (XEXP (XEXP (x, 0), 0))], stream);
5767       return;
5768
5769     case 'M':
5770       fprintf (stream, "{%s%s-%s%s}", REGISTER_PREFIX, reg_names[REGNO (x)],
5771                REGISTER_PREFIX, reg_names[REGNO (x) - 1
5772                                          + ((GET_MODE_SIZE (GET_MODE (x))
5773                                              + GET_MODE_SIZE (SImode) - 1)
5774                                             / GET_MODE_SIZE (SImode))]);
5775       return;
5776
5777     case 'd':
5778       if (x)
5779         fputs (arm_condition_codes[get_arm_condition_code (x)],
5780                stream);
5781       return;
5782
5783     case 'D':
5784       if (x)
5785         fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
5786                                    (get_arm_condition_code (x))],
5787                stream);
5788       return;
5789
5790     default:
5791       if (x == 0)
5792         abort ();
5793
5794       if (GET_CODE (x) == REG)
5795         {
5796           fputs (REGISTER_PREFIX, stream);
5797           fputs (reg_names[REGNO (x)], stream);
5798         }
5799       else if (GET_CODE (x) == MEM)
5800         {
5801           output_memory_reference_mode = GET_MODE (x);
5802           output_address (XEXP (x, 0));
5803         }
5804       else if (GET_CODE (x) == CONST_DOUBLE)
5805         fprintf (stream, "#%s", fp_immediate_constant (x));
5806       else if (GET_CODE (x) == NEG)
5807         abort (); /* This should never happen now. */
5808       else
5809         {
5810           fputc ('#', stream);
5811           output_addr_const (stream, x);
5812         }
5813     }
5814 }
5815
5816 \f
5817 /* A finite state machine takes care of noticing whether or not instructions
5818    can be conditionally executed, and thus decrease execution time and code
5819    size by deleting branch instructions.  The fsm is controlled by
5820    final_prescan_insn, and controls the actions of ASM_OUTPUT_OPCODE.  */
5821
5822 /* The state of the fsm controlling condition codes are:
5823    0: normal, do nothing special
5824    1: make ASM_OUTPUT_OPCODE not output this instruction
5825    2: make ASM_OUTPUT_OPCODE not output this instruction
5826    3: make instructions conditional
5827    4: make instructions conditional
5828
5829    State transitions (state->state by whom under condition):
5830    0 -> 1 final_prescan_insn if the `target' is a label
5831    0 -> 2 final_prescan_insn if the `target' is an unconditional branch
5832    1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
5833    2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
5834    3 -> 0 ASM_OUTPUT_INTERNAL_LABEL if the `target' label is reached
5835           (the target label has CODE_LABEL_NUMBER equal to arm_target_label).
5836    4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
5837           (the target insn is arm_target_insn).
5838
5839    If the jump clobbers the conditions then we use states 2 and 4.
5840
5841    A similar thing can be done with conditional return insns.
5842
5843    XXX In case the `target' is an unconditional branch, this conditionalising
5844    of the instructions always reduces code size, but not always execution
5845    time.  But then, I want to reduce the code size to somewhere near what
5846    /bin/cc produces.  */
5847
5848 /* Returns the index of the ARM condition code string in
5849    `arm_condition_codes'.  COMPARISON should be an rtx like
5850    `(eq (...) (...))'.  */
5851
5852 static enum arm_cond_code
5853 get_arm_condition_code (comparison)
5854      rtx comparison;
5855 {
5856   enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
5857   register int code;
5858   register enum rtx_code comp_code = GET_CODE (comparison);
5859
5860   if (GET_MODE_CLASS (mode) != MODE_CC)
5861     mode = SELECT_CC_MODE (comp_code, XEXP (comparison, 0),
5862                            XEXP (comparison, 1));
5863
5864   switch (mode)
5865     {
5866     case CC_DNEmode: code = ARM_NE; goto dominance;
5867     case CC_DEQmode: code = ARM_EQ; goto dominance;
5868     case CC_DGEmode: code = ARM_GE; goto dominance;
5869     case CC_DGTmode: code = ARM_GT; goto dominance;
5870     case CC_DLEmode: code = ARM_LE; goto dominance;
5871     case CC_DLTmode: code = ARM_LT; goto dominance;
5872     case CC_DGEUmode: code = ARM_CS; goto dominance;
5873     case CC_DGTUmode: code = ARM_HI; goto dominance;
5874     case CC_DLEUmode: code = ARM_LS; goto dominance;
5875     case CC_DLTUmode: code = ARM_CC;
5876
5877     dominance:
5878       if (comp_code != EQ && comp_code != NE)
5879         abort ();
5880
5881       if (comp_code == EQ)
5882         return ARM_INVERSE_CONDITION_CODE (code);
5883       return code;
5884
5885     case CC_NOOVmode:
5886       switch (comp_code)
5887         {
5888         case NE: return ARM_NE;
5889         case EQ: return ARM_EQ;
5890         case GE: return ARM_PL;
5891         case LT: return ARM_MI;
5892         default: abort ();
5893         }
5894
5895     case CC_Zmode:
5896     case CCFPmode:
5897       switch (comp_code)
5898         {
5899         case NE: return ARM_NE;
5900         case EQ: return ARM_EQ;
5901         default: abort ();
5902         }
5903
5904     case CCFPEmode:
5905       switch (comp_code)
5906         {
5907         case GE: return ARM_GE;
5908         case GT: return ARM_GT;
5909         case LE: return ARM_LS;
5910         case LT: return ARM_MI;
5911         default: abort ();
5912         }
5913
5914     case CC_SWPmode:
5915       switch (comp_code)
5916         {
5917         case NE: return ARM_NE;
5918         case EQ: return ARM_EQ;
5919         case GE: return ARM_LE;
5920         case GT: return ARM_LT;
5921         case LE: return ARM_GE;
5922         case LT: return ARM_GT;
5923         case GEU: return ARM_LS;
5924         case GTU: return ARM_CC;
5925         case LEU: return ARM_CS;
5926         case LTU: return ARM_HI;
5927         default: abort ();
5928         }
5929
5930     case CC_Cmode:
5931       switch (comp_code)
5932       {
5933       case LTU: return ARM_CS;
5934       case GEU: return ARM_CC;
5935       default: abort ();
5936       }
5937       
5938     case CCmode:
5939       switch (comp_code)
5940         {
5941         case NE: return ARM_NE;
5942         case EQ: return ARM_EQ;
5943         case GE: return ARM_GE;
5944         case GT: return ARM_GT;
5945         case LE: return ARM_LE;
5946         case LT: return ARM_LT;
5947         case GEU: return ARM_CS;
5948         case GTU: return ARM_HI;
5949         case LEU: return ARM_LS;
5950         case LTU: return ARM_CC;
5951         default: abort ();
5952         }
5953
5954     default: abort ();
5955     }
5956
5957   abort ();
5958 }
5959
5960
5961 void
5962 arm_final_prescan_insn (insn)
5963      rtx insn;
5964 {
5965   /* BODY will hold the body of INSN.  */
5966   register rtx body = PATTERN (insn);
5967
5968   /* This will be 1 if trying to repeat the trick, and things need to be
5969      reversed if it appears to fail.  */
5970   int reverse = 0;
5971
5972   /* JUMP_CLOBBERS will be one implies that the conditions if a branch is
5973      taken are clobbered, even if the rtl suggests otherwise.  It also
5974      means that we have to grub around within the jump expression to find
5975      out what the conditions are when the jump isn't taken.  */
5976   int jump_clobbers = 0;
5977   
5978   /* If we start with a return insn, we only succeed if we find another one. */
5979   int seeking_return = 0;
5980   
5981   /* START_INSN will hold the insn from where we start looking.  This is the
5982      first insn after the following code_label if REVERSE is true.  */
5983   rtx start_insn = insn;
5984
5985   /* If in state 4, check if the target branch is reached, in order to
5986      change back to state 0.  */
5987   if (arm_ccfsm_state == 4)
5988     {
5989       if (insn == arm_target_insn)
5990         {
5991           arm_target_insn = NULL;
5992           arm_ccfsm_state = 0;
5993         }
5994       return;
5995     }
5996
5997   /* If in state 3, it is possible to repeat the trick, if this insn is an
5998      unconditional branch to a label, and immediately following this branch
5999      is the previous target label which is only used once, and the label this
6000      branch jumps to is not too far off.  */
6001   if (arm_ccfsm_state == 3)
6002     {
6003       if (simplejump_p (insn))
6004         {
6005           start_insn = next_nonnote_insn (start_insn);
6006           if (GET_CODE (start_insn) == BARRIER)
6007             {
6008               /* XXX Isn't this always a barrier?  */
6009               start_insn = next_nonnote_insn (start_insn);
6010             }
6011           if (GET_CODE (start_insn) == CODE_LABEL
6012               && CODE_LABEL_NUMBER (start_insn) == arm_target_label
6013               && LABEL_NUSES (start_insn) == 1)
6014             reverse = TRUE;
6015           else
6016             return;
6017         }
6018       else if (GET_CODE (body) == RETURN)
6019         {
6020           start_insn = next_nonnote_insn (start_insn);
6021           if (GET_CODE (start_insn) == BARRIER)
6022             start_insn = next_nonnote_insn (start_insn);
6023           if (GET_CODE (start_insn) == CODE_LABEL
6024               && CODE_LABEL_NUMBER (start_insn) == arm_target_label
6025               && LABEL_NUSES (start_insn) == 1)
6026             {
6027               reverse = TRUE;
6028               seeking_return = 1;
6029             }
6030           else
6031             return;
6032         }
6033       else
6034         return;
6035     }
6036
6037   if (arm_ccfsm_state != 0 && !reverse)
6038     abort ();
6039   if (GET_CODE (insn) != JUMP_INSN)
6040     return;
6041
6042   /* This jump might be paralleled with a clobber of the condition codes 
6043      the jump should always come first */
6044   if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
6045     body = XVECEXP (body, 0, 0);
6046
6047 #if 0  
6048   /* If this is a conditional return then we don't want to know */
6049   if (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
6050       && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
6051       && (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN
6052           || GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN))
6053     return;
6054 #endif
6055
6056   if (reverse
6057       || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
6058           && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
6059     {
6060       int insns_skipped;
6061       int fail = FALSE, succeed = FALSE;
6062       /* Flag which part of the IF_THEN_ELSE is the LABEL_REF.  */
6063       int then_not_else = TRUE;
6064       rtx this_insn = start_insn, label = 0;
6065
6066       if (get_attr_conds (insn) == CONDS_JUMP_CLOB)
6067         {
6068           /* The code below is wrong for these, and I haven't time to
6069              fix it now.  So we just do the safe thing and return.  This
6070              whole function needs re-writing anyway.  */
6071           jump_clobbers = 1;
6072           return;
6073         }
6074       
6075       /* Register the insn jumped to.  */
6076       if (reverse)
6077         {
6078           if (!seeking_return)
6079             label = XEXP (SET_SRC (body), 0);
6080         }
6081       else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
6082         label = XEXP (XEXP (SET_SRC (body), 1), 0);
6083       else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
6084         {
6085           label = XEXP (XEXP (SET_SRC (body), 2), 0);
6086           then_not_else = FALSE;
6087         }
6088       else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
6089         seeking_return = 1;
6090       else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
6091         {
6092           seeking_return = 1;
6093           then_not_else = FALSE;
6094         }
6095       else
6096         abort ();
6097
6098       /* See how many insns this branch skips, and what kind of insns.  If all
6099          insns are okay, and the label or unconditional branch to the same
6100          label is not too far away, succeed.  */
6101       for (insns_skipped = 0;
6102            !fail && !succeed && insns_skipped++ < max_insns_skipped;)
6103         {
6104           rtx scanbody;
6105
6106           this_insn = next_nonnote_insn (this_insn);
6107           if (!this_insn)
6108             break;
6109
6110           switch (GET_CODE (this_insn))
6111             {
6112             case CODE_LABEL:
6113               /* Succeed if it is the target label, otherwise fail since
6114                  control falls in from somewhere else.  */
6115               if (this_insn == label)
6116                 {
6117                   if (jump_clobbers)
6118                     {
6119                       arm_ccfsm_state = 2;
6120                       this_insn = next_nonnote_insn (this_insn);
6121                     }
6122                   else
6123                     arm_ccfsm_state = 1;
6124                   succeed = TRUE;
6125                 }
6126               else
6127                 fail = TRUE;
6128               break;
6129
6130             case BARRIER:
6131               /* Succeed if the following insn is the target label.
6132                  Otherwise fail.  
6133                  If return insns are used then the last insn in a function 
6134                  will be a barrier. */
6135               this_insn = next_nonnote_insn (this_insn);
6136               if (this_insn && this_insn == label)
6137                 {
6138                   if (jump_clobbers)
6139                     {
6140                       arm_ccfsm_state = 2;
6141                       this_insn = next_nonnote_insn (this_insn);
6142                     }
6143                   else
6144                     arm_ccfsm_state = 1;
6145                   succeed = TRUE;
6146                 }
6147               else
6148                 fail = TRUE;
6149               break;
6150
6151             case CALL_INSN:
6152               /* If using 32-bit addresses the cc is not preserved over
6153                  calls */
6154               if (TARGET_APCS_32)
6155                 {
6156                   /* Succeed if the following insn is the target label,
6157                      or if the following two insns are a barrier and
6158                      the target label.  */
6159                   this_insn = next_nonnote_insn (this_insn);
6160                   if (this_insn && GET_CODE (this_insn) == BARRIER)
6161                     this_insn = next_nonnote_insn (this_insn);
6162
6163                   if (this_insn && this_insn == label
6164                       && insns_skipped < max_insns_skipped)
6165                     {
6166                       if (jump_clobbers)
6167                         {
6168                           arm_ccfsm_state = 2;
6169                           this_insn = next_nonnote_insn (this_insn);
6170                         }
6171                       else
6172                         arm_ccfsm_state = 1;
6173                       succeed = TRUE;
6174                     }
6175                   else
6176                     fail = TRUE;
6177                 }
6178               break;
6179
6180             case JUMP_INSN:
6181               /* If this is an unconditional branch to the same label, succeed.
6182                  If it is to another label, do nothing.  If it is conditional,
6183                  fail.  */
6184               /* XXX Probably, the tests for SET and the PC are unnecessary. */
6185
6186               scanbody = PATTERN (this_insn);
6187               if (GET_CODE (scanbody) == SET
6188                   && GET_CODE (SET_DEST (scanbody)) == PC)
6189                 {
6190                   if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
6191                       && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
6192                     {
6193                       arm_ccfsm_state = 2;
6194                       succeed = TRUE;
6195                     }
6196                   else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
6197                     fail = TRUE;
6198                 }
6199               /* Fail if a conditional return is undesirable (eg on a
6200                  StrongARM), but still allow this if optimizing for size.  */
6201               else if (GET_CODE (scanbody) == RETURN
6202                        && ! use_return_insn (TRUE)
6203                        && ! optimize_size)
6204                 fail = TRUE;
6205               else if (GET_CODE (scanbody) == RETURN
6206                        && seeking_return)
6207                 {
6208                   arm_ccfsm_state = 2;
6209                   succeed = TRUE;
6210                 }
6211               else if (GET_CODE (scanbody) == PARALLEL)
6212                 {
6213                   switch (get_attr_conds (this_insn))
6214                     {
6215                     case CONDS_NOCOND:
6216                       break;
6217                     default:
6218                       fail = TRUE;
6219                       break;
6220                     }
6221                 }
6222               break;
6223
6224             case INSN:
6225               /* Instructions using or affecting the condition codes make it
6226                  fail.  */
6227               scanbody = PATTERN (this_insn);
6228               if (! (GET_CODE (scanbody) == SET
6229                      || GET_CODE (scanbody) == PARALLEL)
6230                   || get_attr_conds (this_insn) != CONDS_NOCOND)
6231                 fail = TRUE;
6232               break;
6233
6234             default:
6235               break;
6236             }
6237         }
6238       if (succeed)
6239         {
6240           if ((!seeking_return) && (arm_ccfsm_state == 1 || reverse))
6241             arm_target_label = CODE_LABEL_NUMBER (label);
6242           else if (seeking_return || arm_ccfsm_state == 2)
6243             {
6244               while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
6245                 {
6246                   this_insn = next_nonnote_insn (this_insn);
6247                   if (this_insn && (GET_CODE (this_insn) == BARRIER
6248                                     || GET_CODE (this_insn) == CODE_LABEL))
6249                     abort ();
6250                 }
6251               if (!this_insn)
6252                 {
6253                   /* Oh, dear! we ran off the end.. give up */
6254                   recog (PATTERN (insn), insn, NULL_PTR);
6255                   arm_ccfsm_state = 0;
6256                   arm_target_insn = NULL;
6257                   return;
6258                 }
6259               arm_target_insn = this_insn;
6260             }
6261           else
6262             abort ();
6263           if (jump_clobbers)
6264             {
6265               if (reverse)
6266                 abort ();
6267               arm_current_cc = 
6268                   get_arm_condition_code (XEXP (XEXP (XEXP (SET_SRC (body),
6269                                                             0), 0), 1));
6270               if (GET_CODE (XEXP (XEXP (SET_SRC (body), 0), 0)) == AND)
6271                 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6272               if (GET_CODE (XEXP (SET_SRC (body), 0)) == NE)
6273                 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6274             }
6275           else
6276             {
6277               /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
6278                  what it was.  */
6279               if (!reverse)
6280                 arm_current_cc = get_arm_condition_code (XEXP (SET_SRC (body),
6281                                                                0));
6282             }
6283
6284           if (reverse || then_not_else)
6285             arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6286         }
6287       /* restore recog_operand (getting the attributes of other insns can
6288          destroy this array, but final.c assumes that it remains intact
6289          across this call; since the insn has been recognized already we
6290          call recog direct). */
6291       recog (PATTERN (insn), insn, NULL_PTR);
6292     }
6293 }
6294
6295 #ifdef AOF_ASSEMBLER
6296 /* Special functions only needed when producing AOF syntax assembler. */
6297
6298 rtx aof_pic_label = NULL_RTX;
6299 struct pic_chain
6300 {
6301   struct pic_chain *next;
6302   char *symname;
6303 };
6304
6305 static struct pic_chain *aof_pic_chain = NULL;
6306
6307 rtx
6308 aof_pic_entry (x)
6309      rtx x;
6310 {
6311   struct pic_chain **chainp;
6312   int offset;
6313
6314   if (aof_pic_label == NULL_RTX)
6315     {
6316       /* This needs to persist throughout the compilation.  */
6317       end_temporary_allocation ();
6318       aof_pic_label = gen_rtx_SYMBOL_REF (Pmode, "x$adcons");
6319       resume_temporary_allocation ();
6320     }
6321
6322   for (offset = 0, chainp = &aof_pic_chain; *chainp;
6323        offset += 4, chainp = &(*chainp)->next)
6324     if ((*chainp)->symname == XSTR (x, 0))
6325       return plus_constant (aof_pic_label, offset);
6326
6327   *chainp = (struct pic_chain *) xmalloc (sizeof (struct pic_chain));
6328   (*chainp)->next = NULL;
6329   (*chainp)->symname = XSTR (x, 0);
6330   return plus_constant (aof_pic_label, offset);
6331 }
6332
6333 void
6334 aof_dump_pic_table (f)
6335      FILE *f;
6336 {
6337   struct pic_chain *chain;
6338
6339   if (aof_pic_chain == NULL)
6340     return;
6341
6342   fprintf (f, "\tAREA |%s$$adcons|, BASED %s%s\n",
6343            reg_names[PIC_OFFSET_TABLE_REGNUM], REGISTER_PREFIX,
6344            reg_names[PIC_OFFSET_TABLE_REGNUM]);
6345   fputs ("|x$adcons|\n", f);
6346   
6347   for (chain = aof_pic_chain; chain; chain = chain->next)
6348     {
6349       fputs ("\tDCD\t", f);
6350       assemble_name (f, chain->symname);
6351       fputs ("\n", f);
6352     }
6353 }
6354
6355 int arm_text_section_count = 1;
6356
6357 char *
6358 aof_text_section ()
6359 {
6360   static char buf[100];
6361   sprintf (buf, "\tAREA |C$$code%d|, CODE, READONLY",
6362            arm_text_section_count++);
6363   if (flag_pic)
6364     strcat (buf, ", PIC, REENTRANT");
6365   return buf;
6366 }
6367
6368 static int arm_data_section_count = 1;
6369
6370 char *
6371 aof_data_section ()
6372 {
6373   static char buf[100];
6374   sprintf (buf, "\tAREA |C$$data%d|, DATA", arm_data_section_count++);
6375   return buf;
6376 }
6377
6378 /* The AOF assembler is religiously strict about declarations of
6379    imported and exported symbols, so that it is impossible to declare
6380    a function as imported near the beginning of the file, and then to
6381    export it later on.  It is, however, possible to delay the decision
6382    until all the functions in the file have been compiled.  To get
6383    around this, we maintain a list of the imports and exports, and
6384    delete from it any that are subsequently defined.  At the end of
6385    compilation we spit the remainder of the list out before the END
6386    directive.  */
6387
6388 struct import
6389 {
6390   struct import *next;
6391   char *name;
6392 };
6393
6394 static struct import *imports_list = NULL;
6395
6396 void
6397 aof_add_import (name)
6398      char *name;
6399 {
6400   struct import *new;
6401
6402   for (new = imports_list; new; new = new->next)
6403     if (new->name == name)
6404       return;
6405
6406   new = (struct import *) xmalloc (sizeof (struct import));
6407   new->next = imports_list;
6408   imports_list = new;
6409   new->name = name;
6410 }
6411
6412 void
6413 aof_delete_import (name)
6414      char *name;
6415 {
6416   struct import **old;
6417
6418   for (old = &imports_list; *old; old = & (*old)->next)
6419     {
6420       if ((*old)->name == name)
6421         {
6422           *old = (*old)->next;
6423           return;
6424         }
6425     }
6426 }
6427
6428 int arm_main_function = 0;
6429
6430 void
6431 aof_dump_imports (f)
6432      FILE *f;
6433 {
6434   /* The AOF assembler needs this to cause the startup code to be extracted
6435      from the library.  Brining in __main causes the whole thing to work
6436      automagically.  */
6437   if (arm_main_function)
6438     {
6439       text_section ();
6440       fputs ("\tIMPORT __main\n", f);
6441       fputs ("\tDCD __main\n", f);
6442     }
6443
6444   /* Now dump the remaining imports.  */
6445   while (imports_list)
6446     {
6447       fprintf (f, "\tIMPORT\t");
6448       assemble_name (f, imports_list->name);
6449       fputc ('\n', f);
6450       imports_list = imports_list->next;
6451     }
6452 }
6453 #endif /* AOF_ASSEMBLER */