OSDN Git Service

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