OSDN Git Service

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