OSDN Git Service

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