OSDN Git Service

Replace recog_foo with recog_data.foo.
[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_data.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_data.operand[opno];
4274
4275           if (CONSTANT_P (op))
4276             push_minipool_fix (insn, address, recog_data.operand_loc[opno],
4277                                recog_data.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_data.operand_loc[opno],
4281                                recog_data.operand_mode[opno],
4282                                XVECEXP (op, 0, 0));
4283 #endif
4284           else if (recog_data.operand_mode[opno] == SImode
4285                    && GET_CODE (op) == MEM
4286                    && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
4287                    && CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
4288             push_minipool_fix (insn, address, recog_data.operand_loc[opno],
4289                                recog_data.operand_mode[opno],
4290                                get_pool_constant (XEXP (op, 0)));
4291         }
4292     }
4293 }
4294
4295 void
4296 arm_reorg (first)
4297      rtx first;
4298 {
4299   rtx insn;
4300   int address = 0;
4301   struct minipool_fixup *fix;
4302
4303   minipool_fix_head = minipool_fix_tail = NULL;
4304
4305   /* The first insn must always be a note, or the code below won't
4306      scan it properly.  */
4307   if (GET_CODE (first) != NOTE)
4308     abort ();
4309
4310   /* Scan all the insns and record the operands that will need fixing.  */
4311   for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn (insn))
4312     {
4313
4314       if (GET_CODE (insn) == BARRIER)
4315         push_minipool_barrier(insn, address);
4316       else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
4317                || GET_CODE (insn) == JUMP_INSN)
4318         {
4319           rtx table;
4320
4321           note_invalid_constants (insn, address);
4322           address += get_attr_length (insn);
4323           /* If the insn is a vector jump, add the size of the table
4324              and skip the table.  */
4325           if (GET_CODE (insn) == JUMP_INSN
4326               && JUMP_LABEL (insn) != NULL
4327               && ((table = next_real_insn (JUMP_LABEL (insn)))
4328                   == next_real_insn (insn))
4329               && table != NULL
4330               && GET_CODE (table) == JUMP_INSN
4331               && (GET_CODE (PATTERN (table)) == ADDR_VEC
4332                   || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
4333             {
4334               int elt = GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC ? 1 : 0;
4335
4336               address += GET_MODE_SIZE (SImode) * XVECLEN (PATTERN (table), 
4337                                                            elt);
4338               insn = table;
4339             }
4340         }
4341     }
4342
4343   /* Now scan the fixups and perform the required changes.  */
4344   for (fix = minipool_fix_head; fix; fix = fix->next)
4345     {
4346       struct minipool_fixup *ftmp;
4347       struct minipool_fixup *last_barrier = NULL;
4348       int max_range;
4349       rtx barrier;
4350       struct minipool_fixup *this_fix;
4351       int new_minipool_size = 0;
4352
4353       /* Skip any further barriers before the next fix.  */
4354       while (fix && GET_CODE (fix->insn) == BARRIER)
4355         fix = fix->next;
4356
4357       if (fix == NULL)
4358         break;
4359
4360       ftmp = fix;
4361       max_range = fix->address + fix->range;
4362
4363       /* Find all the other fixes that can live in the same pool.  */
4364       while (ftmp->next && ftmp->next->address < max_range
4365              && (GET_CODE (ftmp->next->insn) == BARRIER
4366                  /* Ensure we can reach the constant inside the pool.  */
4367                  || ftmp->next->range > new_minipool_size))
4368         {
4369           ftmp = ftmp->next;
4370           if (GET_CODE (ftmp->insn) == BARRIER)
4371             last_barrier = ftmp;
4372           else
4373             {
4374               /* Does this fix constrain the range we can search?  */
4375               if (ftmp->address + ftmp->range - new_minipool_size < max_range)
4376                 max_range = ftmp->address + ftmp->range - new_minipool_size;
4377
4378               new_minipool_size += GET_MODE_SIZE (ftmp->mode);
4379             }
4380         }
4381
4382       /* If we found a barrier, drop back to that; any fixes that we could
4383          have reached but come after the barrier will now go in the next
4384          mini-pool.  */
4385       if (last_barrier != NULL)
4386         {
4387           barrier = last_barrier->insn;
4388           ftmp = last_barrier;
4389         }
4390       /* ftmp is last fix that we can fit into this pool and we
4391          failed to find a barrier that we could use.  Insert a new
4392          barrier in the code and arrange to jump around it.  */
4393       else
4394         {
4395           /* Check that there isn't another fix that is in range that
4396              we couldn't fit into this pool because the pool was
4397              already too large: we need to put the pool before such an
4398              instruction.  */
4399           if (ftmp->next && ftmp->next->address < max_range)
4400             max_range = ftmp->address;
4401
4402           barrier = find_barrier (ftmp->insn, max_range - ftmp->address);
4403         }
4404
4405       /* Scan over the fixes we have identified for this pool, fixing them
4406          up and adding the constants to the pool itself.  */
4407       for (this_fix = fix; this_fix && ftmp->next != this_fix;
4408            this_fix = this_fix->next)
4409         if (GET_CODE (this_fix->insn) != BARRIER)
4410           {
4411             int offset = add_minipool_constant (this_fix->value,
4412                                                 this_fix->mode);
4413             rtx addr
4414               = plus_constant (gen_rtx_LABEL_REF (VOIDmode, 
4415                                                   minipool_vector_label),
4416                                offset);
4417             *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr);
4418           }
4419
4420       dump_minipool (barrier);
4421       fix = ftmp;
4422     }
4423
4424   /* From now on we must synthesize any constants that we can't handle
4425      directly.  This can happen if the RTL gets split during final
4426      instruction generation.  */
4427   after_arm_reorg = 1;
4428 }
4429
4430 \f
4431 /* Routines to output assembly language.  */
4432
4433 /* If the rtx is the correct value then return the string of the number.
4434    In this way we can ensure that valid double constants are generated even
4435    when cross compiling. */
4436 char *
4437 fp_immediate_constant (x)
4438      rtx x;
4439 {
4440   REAL_VALUE_TYPE r;
4441   int i;
4442   
4443   if (!fpa_consts_inited)
4444     init_fpa_table ();
4445   
4446   REAL_VALUE_FROM_CONST_DOUBLE (r, x);
4447   for (i = 0; i < 8; i++)
4448     if (REAL_VALUES_EQUAL (r, values_fpa[i]))
4449       return strings_fpa[i];
4450
4451   abort ();
4452 }
4453
4454 /* As for fp_immediate_constant, but value is passed directly, not in rtx.  */
4455 static char *
4456 fp_const_from_val (r)
4457      REAL_VALUE_TYPE * r;
4458 {
4459   int i;
4460
4461   if (! fpa_consts_inited)
4462     init_fpa_table ();
4463
4464   for (i = 0; i < 8; i++)
4465     if (REAL_VALUES_EQUAL (*r, values_fpa[i]))
4466       return strings_fpa[i];
4467
4468   abort ();
4469 }
4470
4471 /* Output the operands of a LDM/STM instruction to STREAM.
4472    MASK is the ARM register set mask of which only bits 0-15 are important.
4473    INSTR is the possibly suffixed base register.  HAT unequals zero if a hat
4474    must follow the register list.  */
4475
4476 void
4477 print_multi_reg (stream, instr, reg, mask, hat)
4478      FILE * stream;
4479      char * instr;
4480      int reg;
4481      int mask;
4482      int hat;
4483 {
4484   int i;
4485   int not_first = FALSE;
4486
4487   fputc ('\t', stream);
4488   asm_fprintf (stream, instr, reg);
4489   fputs (", {", stream);
4490   
4491   for (i = 0; i < 16; i++)
4492     if (mask & (1 << i))
4493       {
4494         if (not_first)
4495           fprintf (stream, ", ");
4496         
4497         asm_fprintf (stream, "%r", i);
4498         not_first = TRUE;
4499       }
4500
4501   fprintf (stream, "}%s\n", hat ? "^" : "");
4502 }
4503
4504 /* Output a 'call' insn. */
4505
4506 char *
4507 output_call (operands)
4508      rtx * operands;
4509 {
4510   /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
4511
4512   if (REGNO (operands[0]) == LR_REGNUM)
4513     {
4514       operands[0] = gen_rtx_REG (SImode, IP_REGNUM);
4515       output_asm_insn ("mov%?\t%0, %|lr", operands);
4516     }
4517   
4518   output_asm_insn ("mov%?\t%|lr, %|pc", operands);
4519   
4520   if (TARGET_INTERWORK)
4521     output_asm_insn ("bx%?\t%0", operands);
4522   else
4523     output_asm_insn ("mov%?\t%|pc, %0", operands);
4524   
4525   return "";
4526 }
4527
4528 static int
4529 eliminate_lr2ip (x)
4530      rtx * x;
4531 {
4532   int something_changed = 0;
4533   rtx x0 = * x;
4534   int code = GET_CODE (x0);
4535   register int i, j;
4536   register const char * fmt;
4537   
4538   switch (code)
4539     {
4540     case REG:
4541       if (REGNO (x0) == LR_REGNUM)
4542         {
4543           *x = gen_rtx_REG (SImode, IP_REGNUM);
4544           return 1;
4545         }
4546       return 0;
4547     default:
4548       /* Scan through the sub-elements and change any references there */
4549       fmt = GET_RTX_FORMAT (code);
4550       
4551       for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4552         if (fmt[i] == 'e')
4553           something_changed |= eliminate_lr2ip (&XEXP (x0, i));
4554         else if (fmt[i] == 'E')
4555           for (j = 0; j < XVECLEN (x0, i); j++)
4556             something_changed |= eliminate_lr2ip (&XVECEXP (x0, i, j));
4557       
4558       return something_changed;
4559     }
4560 }
4561   
4562 /* Output a 'call' insn that is a reference in memory. */
4563
4564 char *
4565 output_call_mem (operands)
4566      rtx * operands;
4567 {
4568   operands[0] = copy_rtx (operands[0]); /* Be ultra careful */
4569   /* Handle calls using lr by using ip (which may be clobbered in subr anyway).
4570    */
4571   if (eliminate_lr2ip (&operands[0]))
4572     output_asm_insn ("mov%?\t%|ip, %|lr", operands);
4573
4574   if (TARGET_INTERWORK)
4575     {
4576       output_asm_insn ("ldr%?\t%|ip, %0", operands);
4577       output_asm_insn ("mov%?\t%|lr, %|pc", operands);
4578       output_asm_insn ("bx%?\t%|ip", operands);
4579     }
4580   else
4581     {
4582       output_asm_insn ("mov%?\t%|lr, %|pc", operands);
4583       output_asm_insn ("ldr%?\t%|pc, %0", operands);
4584     }
4585
4586   return "";
4587 }
4588
4589
4590 /* Output a move from arm registers to an fpu registers.
4591    OPERANDS[0] is an fpu register.
4592    OPERANDS[1] is the first registers of an arm register pair.  */
4593
4594 char *
4595 output_mov_long_double_fpu_from_arm (operands)
4596      rtx * operands;
4597 {
4598   int arm_reg0 = REGNO (operands[1]);
4599   rtx ops[3];
4600
4601   if (arm_reg0 == IP_REGNUM)
4602     abort ();
4603
4604   ops[0] = gen_rtx_REG (SImode, arm_reg0);
4605   ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
4606   ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
4607   
4608   output_asm_insn ("stm%?fd\t%|sp!, {%0, %1, %2}", ops);
4609   output_asm_insn ("ldf%?e\t%0, [%|sp], #12", operands);
4610   
4611   return "";
4612 }
4613
4614 /* Output a move from an fpu register to arm registers.
4615    OPERANDS[0] is the first registers of an arm register pair.
4616    OPERANDS[1] is an fpu register.  */
4617
4618 char *
4619 output_mov_long_double_arm_from_fpu (operands)
4620      rtx * operands;
4621 {
4622   int arm_reg0 = REGNO (operands[0]);
4623   rtx ops[3];
4624
4625   if (arm_reg0 == IP_REGNUM)
4626     abort ();
4627
4628   ops[0] = gen_rtx_REG (SImode, arm_reg0);
4629   ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
4630   ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
4631
4632   output_asm_insn ("stf%?e\t%1, [%|sp, #-12]!", operands);
4633   output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1, %2}", ops);
4634   return "";
4635 }
4636
4637 /* Output a move from arm registers to arm registers of a long double
4638    OPERANDS[0] is the destination.
4639    OPERANDS[1] is the source.  */
4640 char *
4641 output_mov_long_double_arm_from_arm (operands)
4642      rtx * operands;
4643 {
4644   /* We have to be careful here because the two might overlap */
4645   int dest_start = REGNO (operands[0]);
4646   int src_start = REGNO (operands[1]);
4647   rtx ops[2];
4648   int i;
4649
4650   if (dest_start < src_start)
4651     {
4652       for (i = 0; i < 3; i++)
4653         {
4654           ops[0] = gen_rtx_REG (SImode, dest_start + i);
4655           ops[1] = gen_rtx_REG (SImode, src_start + i);
4656           output_asm_insn ("mov%?\t%0, %1", ops);
4657         }
4658     }
4659   else
4660     {
4661       for (i = 2; i >= 0; i--)
4662         {
4663           ops[0] = gen_rtx_REG (SImode, dest_start + i);
4664           ops[1] = gen_rtx_REG (SImode, src_start + i);
4665           output_asm_insn ("mov%?\t%0, %1", ops);
4666         }
4667     }
4668
4669   return "";
4670 }
4671
4672
4673 /* Output a move from arm registers to an fpu registers.
4674    OPERANDS[0] is an fpu register.
4675    OPERANDS[1] is the first registers of an arm register pair.  */
4676
4677 char *
4678 output_mov_double_fpu_from_arm (operands)
4679      rtx * operands;
4680 {
4681   int arm_reg0 = REGNO (operands[1]);
4682   rtx ops[2];
4683
4684   if (arm_reg0 == IP_REGNUM)
4685     abort ();
4686   
4687   ops[0] = gen_rtx_REG (SImode, arm_reg0);
4688   ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
4689   output_asm_insn ("stm%?fd\t%|sp!, {%0, %1}", ops);
4690   output_asm_insn ("ldf%?d\t%0, [%|sp], #8", operands);
4691   return "";
4692 }
4693
4694 /* Output a move from an fpu register to arm registers.
4695    OPERANDS[0] is the first registers of an arm register pair.
4696    OPERANDS[1] is an fpu register.  */
4697
4698 char *
4699 output_mov_double_arm_from_fpu (operands)
4700      rtx * operands;
4701 {
4702   int arm_reg0 = REGNO (operands[0]);
4703   rtx ops[2];
4704
4705   if (arm_reg0 == IP_REGNUM)
4706     abort ();
4707
4708   ops[0] = gen_rtx_REG (SImode, arm_reg0);
4709   ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
4710   output_asm_insn ("stf%?d\t%1, [%|sp, #-8]!", operands);
4711   output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1}", ops);
4712   return "";
4713 }
4714
4715 /* Output a move between double words.
4716    It must be REG<-REG, REG<-CONST_DOUBLE, REG<-CONST_INT, REG<-MEM
4717    or MEM<-REG and all MEMs must be offsettable addresses.  */
4718
4719 char *
4720 output_move_double (operands)
4721      rtx * operands;
4722 {
4723   enum rtx_code code0 = GET_CODE (operands[0]);
4724   enum rtx_code code1 = GET_CODE (operands[1]);
4725   rtx otherops[3];
4726
4727   if (code0 == REG)
4728     {
4729       int reg0 = REGNO (operands[0]);
4730
4731       otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
4732       
4733       if (code1 == REG)
4734         {
4735           int reg1 = REGNO (operands[1]);
4736           if (reg1 == IP_REGNUM)
4737             abort ();
4738
4739           /* Ensure the second source is not overwritten */
4740           if (reg1 == reg0 + (WORDS_BIG_ENDIAN ? -1 : 1))
4741             output_asm_insn ("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands);
4742           else
4743             output_asm_insn ("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
4744         }
4745       else if (code1 == CONST_DOUBLE)
4746         {
4747           if (GET_MODE (operands[1]) == DFmode)
4748             {
4749               long l[2];
4750               union real_extract u;
4751
4752               bcopy ((char *) &CONST_DOUBLE_LOW (operands[1]), (char *) &u,
4753                      sizeof (u));
4754               REAL_VALUE_TO_TARGET_DOUBLE (u.d, l);
4755               otherops[1] = GEN_INT(l[1]);
4756               operands[1] = GEN_INT(l[0]);
4757             }
4758           else if (GET_MODE (operands[1]) != VOIDmode)
4759             abort ();
4760           else if (WORDS_BIG_ENDIAN)
4761             {
4762               
4763               otherops[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4764               operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
4765             }
4766           else
4767             {
4768               
4769               otherops[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
4770               operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
4771             }
4772           
4773           output_mov_immediate (operands);
4774           output_mov_immediate (otherops);
4775         }
4776       else if (code1 == CONST_INT)
4777         {
4778 #if HOST_BITS_PER_WIDE_INT > 32
4779           /* If HOST_WIDE_INT is more than 32 bits, the intval tells us
4780              what the upper word is.  */
4781           if (WORDS_BIG_ENDIAN)
4782             {
4783               otherops[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
4784               operands[1] = GEN_INT (INTVAL (operands[1]) >> 32);
4785             }
4786           else
4787             {
4788               otherops[1] = GEN_INT (INTVAL (operands[1]) >> 32);
4789               operands[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
4790             }
4791 #else
4792           /* Sign extend the intval into the high-order word */
4793           if (WORDS_BIG_ENDIAN)
4794             {
4795               otherops[1] = operands[1];
4796               operands[1] = (INTVAL (operands[1]) < 0
4797                              ? constm1_rtx : const0_rtx);
4798             }
4799           else
4800             otherops[1] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
4801 #endif
4802           output_mov_immediate (otherops);
4803           output_mov_immediate (operands);
4804         }
4805       else if (code1 == MEM)
4806         {
4807           switch (GET_CODE (XEXP (operands[1], 0)))
4808             {
4809             case REG:
4810               output_asm_insn ("ldm%?ia\t%m1, %M0", operands);
4811               break;
4812
4813             case PRE_INC:
4814               abort (); /* Should never happen now */
4815               break;
4816
4817             case PRE_DEC:
4818               output_asm_insn ("ldm%?db\t%m1!, %M0", operands);
4819               break;
4820
4821             case POST_INC:
4822               output_asm_insn ("ldm%?ia\t%m1!, %M0", operands);
4823               break;
4824
4825             case POST_DEC:
4826               abort (); /* Should never happen now */
4827               break;
4828
4829             case LABEL_REF:
4830             case CONST:
4831               output_asm_insn ("adr%?\t%0, %1", operands);
4832               output_asm_insn ("ldm%?ia\t%0, %M0", operands);
4833               break;
4834
4835             default:
4836               if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1),
4837                                    GET_MODE (XEXP (XEXP (operands[1], 0), 1))))
4838                 {
4839                   otherops[0] = operands[0];
4840                   otherops[1] = XEXP (XEXP (operands[1], 0), 0);
4841                   otherops[2] = XEXP (XEXP (operands[1], 0), 1);
4842                   if (GET_CODE (XEXP (operands[1], 0)) == PLUS)
4843                     {
4844                       if (GET_CODE (otherops[2]) == CONST_INT)
4845                         {
4846                           switch (INTVAL (otherops[2]))
4847                             {
4848                             case -8:
4849                               output_asm_insn ("ldm%?db\t%1, %M0", otherops);
4850                               return "";
4851                             case -4:
4852                               output_asm_insn ("ldm%?da\t%1, %M0", otherops);
4853                               return "";
4854                             case 4:
4855                               output_asm_insn ("ldm%?ib\t%1, %M0", otherops);
4856                               return "";
4857                             }
4858                           if (!(const_ok_for_arm (INTVAL (otherops[2]))))
4859                             output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
4860                           else
4861                             output_asm_insn ("add%?\t%0, %1, %2", otherops);
4862                         }
4863                       else
4864                         output_asm_insn ("add%?\t%0, %1, %2", otherops);
4865                     }
4866                   else
4867                     output_asm_insn ("sub%?\t%0, %1, %2", otherops);
4868                   
4869                   return "ldm%?ia\t%0, %M0";
4870                 }
4871               else
4872                 {
4873                   otherops[1] = adj_offsettable_operand (operands[1], 4);
4874                   /* Take care of overlapping base/data reg.  */
4875                   if (reg_mentioned_p (operands[0], operands[1]))
4876                     {
4877                       output_asm_insn ("ldr%?\t%0, %1", otherops);
4878                       output_asm_insn ("ldr%?\t%0, %1", operands);
4879                     }
4880                   else
4881                     {
4882                       output_asm_insn ("ldr%?\t%0, %1", operands);
4883                       output_asm_insn ("ldr%?\t%0, %1", otherops);
4884                     }
4885                 }
4886             }
4887         }
4888       else
4889         abort ();  /* Constraints should prevent this */
4890     }
4891   else if (code0 == MEM && code1 == REG)
4892     {
4893       if (REGNO (operands[1]) == IP_REGNUM)
4894         abort ();
4895
4896       switch (GET_CODE (XEXP (operands[0], 0)))
4897         {
4898         case REG:
4899           output_asm_insn ("stm%?ia\t%m0, %M1", operands);
4900           break;
4901
4902         case PRE_INC:
4903           abort (); /* Should never happen now */
4904           break;
4905
4906         case PRE_DEC:
4907           output_asm_insn ("stm%?db\t%m0!, %M1", operands);
4908           break;
4909
4910         case POST_INC:
4911           output_asm_insn ("stm%?ia\t%m0!, %M1", operands);
4912           break;
4913
4914         case POST_DEC:
4915           abort (); /* Should never happen now */
4916           break;
4917
4918         case PLUS:
4919           if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
4920             {
4921               switch (INTVAL (XEXP (XEXP (operands[0], 0), 1)))
4922                 {
4923                 case -8:
4924                   output_asm_insn ("stm%?db\t%m0, %M1", operands);
4925                   return "";
4926
4927                 case -4:
4928                   output_asm_insn ("stm%?da\t%m0, %M1", operands);
4929                   return "";
4930
4931                 case 4:
4932                   output_asm_insn ("stm%?ib\t%m0, %M1", operands);
4933                   return "";
4934                 }
4935             }
4936           /* Fall through */
4937
4938         default:
4939           otherops[0] = adj_offsettable_operand (operands[0], 4);
4940           otherops[1] = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
4941           output_asm_insn ("str%?\t%1, %0", operands);
4942           output_asm_insn ("str%?\t%1, %0", otherops);
4943         }
4944     }
4945   else
4946     abort ();  /* Constraints should prevent this */
4947
4948   return "";
4949 }
4950
4951
4952 /* Output an arbitrary MOV reg, #n.
4953    OPERANDS[0] is a register.  OPERANDS[1] is a const_int.  */
4954
4955 char *
4956 output_mov_immediate (operands)
4957      rtx * operands;
4958 {
4959   HOST_WIDE_INT n = INTVAL (operands[1]);
4960   int n_ones = 0;
4961   int i;
4962
4963   /* Try to use one MOV */
4964   if (const_ok_for_arm (n))
4965     {
4966       output_asm_insn ("mov%?\t%0, %1", operands);
4967       return "";
4968     }
4969
4970   /* Try to use one MVN */
4971   if (const_ok_for_arm (~n))
4972     {
4973       operands[1] = GEN_INT (~n);
4974       output_asm_insn ("mvn%?\t%0, %1", operands);
4975       return "";
4976     }
4977
4978   /* If all else fails, make it out of ORRs or BICs as appropriate. */
4979
4980   for (i=0; i < 32; i++)
4981     if (n & 1 << i)
4982       n_ones++;
4983
4984   if (n_ones > 16)  /* Shorter to use MVN with BIC in this case. */
4985     output_multi_immediate(operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1,
4986                            ~n);
4987   else
4988     output_multi_immediate(operands, "mov%?\t%0, %1", "orr%?\t%0, %0, %1", 1,
4989                            n);
4990
4991   return "";
4992 }
4993
4994
4995 /* Output an ADD r, s, #n where n may be too big for one instruction.  If
4996    adding zero to one register, output nothing.  */
4997
4998 char *
4999 output_add_immediate (operands)
5000      rtx * operands;
5001 {
5002   HOST_WIDE_INT n = INTVAL (operands[2]);
5003
5004   if (n != 0 || REGNO (operands[0]) != REGNO (operands[1]))
5005     {
5006       if (n < 0)
5007         output_multi_immediate (operands,
5008                                 "sub%?\t%0, %1, %2", "sub%?\t%0, %0, %2", 2,
5009                                 -n);
5010       else
5011         output_multi_immediate (operands,
5012                                 "add%?\t%0, %1, %2", "add%?\t%0, %0, %2", 2,
5013                                 n);
5014     }
5015
5016   return "";
5017 }
5018
5019 /* Output a multiple immediate operation.
5020    OPERANDS is the vector of operands referred to in the output patterns.
5021    INSTR1 is the output pattern to use for the first constant.
5022    INSTR2 is the output pattern to use for subsequent constants.
5023    IMMED_OP is the index of the constant slot in OPERANDS.
5024    N is the constant value.  */
5025
5026 static char *
5027 output_multi_immediate (operands, instr1, instr2, immed_op, n)
5028      rtx * operands;
5029      char * instr1, * instr2;
5030      int immed_op;
5031      HOST_WIDE_INT n;
5032 {
5033 #if HOST_BITS_PER_WIDE_INT > 32
5034   n &= 0xffffffff;
5035 #endif
5036
5037   if (n == 0)
5038     {
5039       operands[immed_op] = const0_rtx;
5040       output_asm_insn (instr1, operands); /* Quick and easy output */
5041     }
5042   else
5043     {
5044       int i;
5045       char *instr = instr1;
5046
5047       /* Note that n is never zero here (which would give no output) */
5048       for (i = 0; i < 32; i += 2)
5049         {
5050           if (n & (3 << i))
5051             {
5052               operands[immed_op] = GEN_INT (n & (255 << i));
5053               output_asm_insn (instr, operands);
5054               instr = instr2;
5055               i += 6;
5056             }
5057         }
5058     }
5059   return "";
5060 }
5061
5062
5063 /* Return the appropriate ARM instruction for the operation code.
5064    The returned result should not be overwritten.  OP is the rtx of the
5065    operation.  SHIFT_FIRST_ARG is TRUE if the first argument of the operator
5066    was shifted.  */
5067
5068 char *
5069 arithmetic_instr (op, shift_first_arg)
5070      rtx op;
5071      int shift_first_arg;
5072 {
5073   switch (GET_CODE (op))
5074     {
5075     case PLUS:
5076       return "add";
5077
5078     case MINUS:
5079       return shift_first_arg ? "rsb" : "sub";
5080
5081     case IOR:
5082       return "orr";
5083
5084     case XOR:
5085       return "eor";
5086
5087     case AND:
5088       return "and";
5089
5090     default:
5091       abort ();
5092     }
5093 }
5094
5095
5096 /* Ensure valid constant shifts and return the appropriate shift mnemonic
5097    for the operation code.  The returned result should not be overwritten.
5098    OP is the rtx code of the shift.
5099    On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
5100    shift. */
5101
5102 static char *
5103 shift_op (op, amountp)
5104      rtx op;
5105      HOST_WIDE_INT *amountp;
5106 {
5107   char * mnem;
5108   enum rtx_code code = GET_CODE (op);
5109
5110   if (GET_CODE (XEXP (op, 1)) == REG || GET_CODE (XEXP (op, 1)) == SUBREG)
5111     *amountp = -1;
5112   else if (GET_CODE (XEXP (op, 1)) == CONST_INT)
5113     *amountp = INTVAL (XEXP (op, 1));
5114   else
5115     abort ();
5116
5117   switch (code)
5118     {
5119     case ASHIFT:
5120       mnem = "asl";
5121       break;
5122
5123     case ASHIFTRT:
5124       mnem = "asr";
5125       break;
5126
5127     case LSHIFTRT:
5128       mnem = "lsr";
5129       break;
5130
5131     case ROTATERT:
5132       mnem = "ror";
5133       break;
5134
5135     case MULT:
5136       /* We never have to worry about the amount being other than a
5137          power of 2, since this case can never be reloaded from a reg.  */
5138       if (*amountp != -1)
5139         *amountp = int_log2 (*amountp);
5140       else
5141         abort ();
5142       return "asl";
5143
5144     default:
5145       abort ();
5146     }
5147
5148   if (*amountp != -1)
5149     {
5150       /* This is not 100% correct, but follows from the desire to merge
5151          multiplication by a power of 2 with the recognizer for a
5152          shift.  >=32 is not a valid shift for "asl", so we must try and
5153          output a shift that produces the correct arithmetical result.
5154          Using lsr #32 is identical except for the fact that the carry bit
5155          is not set correctly if we set the flags; but we never use the 
5156          carry bit from such an operation, so we can ignore that.  */
5157       if (code == ROTATERT)
5158         *amountp &= 31;         /* Rotate is just modulo 32 */
5159       else if (*amountp != (*amountp & 31))
5160         {
5161           if (code == ASHIFT)
5162             mnem = "lsr";
5163           *amountp = 32;
5164         }
5165
5166       /* Shifts of 0 are no-ops.  */
5167       if (*amountp == 0)
5168         return NULL;
5169     }     
5170
5171   return mnem;
5172 }
5173
5174
5175 /* Obtain the shift from the POWER of two. */
5176
5177 static HOST_WIDE_INT
5178 int_log2 (power)
5179      HOST_WIDE_INT power;
5180 {
5181   HOST_WIDE_INT shift = 0;
5182
5183   while (((((HOST_WIDE_INT) 1) << shift) & power) == 0)
5184     {
5185       if (shift > 31)
5186         abort ();
5187       shift++;
5188     }
5189
5190   return shift;
5191 }
5192
5193 /* Output a .ascii pseudo-op, keeping track of lengths.  This is because
5194    /bin/as is horribly restrictive.  */
5195 #define MAX_ASCII_LEN 51
5196
5197 void
5198 output_ascii_pseudo_op (stream, p, len)
5199      FILE * stream;
5200      unsigned char * p;
5201      int len;
5202 {
5203   int i;
5204   int len_so_far = 0;
5205
5206   fputs ("\t.ascii\t\"", stream);
5207   
5208   for (i = 0; i < len; i++)
5209     {
5210       register int c = p[i];
5211
5212       if (len_so_far >= MAX_ASCII_LEN)
5213         {
5214           fputs ("\"\n\t.ascii\t\"", stream);
5215           len_so_far = 0;
5216         }
5217
5218       switch (c)
5219         {
5220         case TARGET_TAB:                
5221           fputs ("\\t", stream);
5222           len_so_far += 2;                      
5223           break;
5224           
5225         case TARGET_FF:
5226           fputs ("\\f", stream);
5227           len_so_far += 2;
5228           break;
5229           
5230         case TARGET_BS:
5231           fputs ("\\b", stream);
5232           len_so_far += 2;
5233           break;
5234           
5235         case TARGET_CR:
5236           fputs ("\\r", stream);
5237           len_so_far += 2;
5238           break;
5239           
5240         case TARGET_NEWLINE:
5241           fputs ("\\n", stream);
5242           c = p [i + 1];
5243           if ((c >= ' ' && c <= '~')
5244               || c == TARGET_TAB)
5245             /* This is a good place for a line break.  */
5246             len_so_far = MAX_ASCII_LEN;
5247           else
5248             len_so_far += 2;
5249           break;
5250           
5251         case '\"':
5252         case '\\':
5253           putc ('\\', stream);
5254           len_so_far ++;
5255           /* drop through.  */
5256
5257         default:
5258           if (c >= ' ' && c <= '~')
5259             {
5260               putc (c, stream);
5261               len_so_far ++;
5262             }
5263           else
5264             {
5265               fprintf (stream, "\\%03o", c);
5266               len_so_far += 4;
5267             }
5268           break;
5269         }
5270     }
5271
5272   fputs ("\"\n", stream);
5273 }
5274 \f
5275
5276 /* Try to determine whether a pattern really clobbers the link register.
5277    This information is useful when peepholing, so that lr need not be pushed
5278    if we combine a call followed by a return.
5279    NOTE: This code does not check for side-effect expressions in a SET_SRC:
5280    such a check should not be needed because these only update an existing
5281    value within a register; the register must still be set elsewhere within
5282    the function. */
5283
5284 static int
5285 pattern_really_clobbers_lr (x)
5286      rtx x;
5287 {
5288   int i;
5289   
5290   switch (GET_CODE (x))
5291     {
5292     case SET:
5293       switch (GET_CODE (SET_DEST (x)))
5294         {
5295         case REG:
5296           return REGNO (SET_DEST (x)) == LR_REGNUM;
5297
5298         case SUBREG:
5299           if (GET_CODE (XEXP (SET_DEST (x), 0)) == REG)
5300             return REGNO (XEXP (SET_DEST (x), 0)) == LR_REGNUM;
5301
5302           if (GET_CODE (XEXP (SET_DEST (x), 0)) == MEM)
5303             return 0;
5304           abort ();
5305
5306         default:
5307           return 0;
5308         }
5309
5310     case PARALLEL:
5311       for (i = 0; i < XVECLEN (x, 0); i++)
5312         if (pattern_really_clobbers_lr (XVECEXP (x, 0, i)))
5313           return 1;
5314       return 0;
5315
5316     case CLOBBER:
5317       switch (GET_CODE (XEXP (x, 0)))
5318         {
5319         case REG:
5320           return REGNO (XEXP (x, 0)) == LR_REGNUM;
5321
5322         case SUBREG:
5323           if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG)
5324             return REGNO (XEXP (XEXP (x, 0), 0)) == LR_REGNUM;
5325           abort ();
5326
5327         default:
5328           return 0;
5329         }
5330
5331     case UNSPEC:
5332       return 1;
5333
5334     default:
5335       return 0;
5336     }
5337 }
5338
5339 static int
5340 function_really_clobbers_lr (first)
5341      rtx first;
5342 {
5343   rtx insn, next;
5344   
5345   for (insn = first; insn; insn = next_nonnote_insn (insn))
5346     {
5347       switch (GET_CODE (insn))
5348         {
5349         case BARRIER:
5350         case NOTE:
5351         case CODE_LABEL:
5352         case JUMP_INSN:         /* Jump insns only change the PC (and conds) */
5353           break;
5354
5355         case INSN:
5356           if (pattern_really_clobbers_lr (PATTERN (insn)))
5357             return 1;
5358           break;
5359
5360         case CALL_INSN:
5361           /* Don't yet know how to handle those calls that are not to a 
5362              SYMBOL_REF */
5363           if (GET_CODE (PATTERN (insn)) != PARALLEL)
5364             abort ();
5365
5366           switch (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)))
5367             {
5368             case CALL:
5369               if (GET_CODE (XEXP (XEXP (XVECEXP (PATTERN (insn), 0, 0), 0), 0))
5370                   != SYMBOL_REF)
5371                 return 1;
5372               break;
5373
5374             case SET:
5375               if (GET_CODE (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn),
5376                                                           0, 0)), 0), 0))
5377                   != SYMBOL_REF)
5378                 return 1;
5379               break;
5380
5381             default:    /* Don't recognize it, be safe */
5382               return 1;
5383             }
5384
5385           /* A call can be made (by peepholing) not to clobber lr iff it is
5386              followed by a return.  There may, however, be a use insn iff
5387              we are returning the result of the call. 
5388              If we run off the end of the insn chain, then that means the
5389              call was at the end of the function.  Unfortunately we don't
5390              have a return insn for the peephole to recognize, so we
5391              must reject this.  (Can this be fixed by adding our own insn?) */
5392           if ((next = next_nonnote_insn (insn)) == NULL)
5393             return 1;
5394
5395           /* No need to worry about lr if the call never returns */
5396           if (GET_CODE (next) == BARRIER)
5397             break;
5398
5399           if (GET_CODE (next) == INSN && GET_CODE (PATTERN (next)) == USE
5400               && (GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET)
5401               && (REGNO (SET_DEST (XVECEXP (PATTERN (insn), 0, 0)))
5402                   == REGNO (XEXP (PATTERN (next), 0))))
5403             if ((next = next_nonnote_insn (next)) == NULL)
5404               return 1;
5405
5406           if (GET_CODE (next) == JUMP_INSN
5407               && GET_CODE (PATTERN (next)) == RETURN)
5408             break;
5409           return 1;
5410
5411         default:
5412           abort ();
5413         }
5414     }
5415
5416   /* We have reached the end of the chain so lr was _not_ clobbered */
5417   return 0;
5418 }
5419
5420 char *
5421 output_return_instruction (operand, really_return, reverse)
5422      rtx operand;
5423      int really_return;
5424      int reverse;
5425 {
5426   char instr[100];
5427   int reg, live_regs = 0;
5428   int volatile_func = (optimize > 0 
5429                        && TREE_THIS_VOLATILE (current_function_decl));
5430
5431   return_used_this_function = 1;
5432
5433   if (TARGET_ABORT_NORETURN && volatile_func)
5434     {
5435       rtx ops[2];
5436       /* If this function was declared non-returning, and we have found a tail 
5437          call, then we have to trust that the called function won't return. */
5438       if (! really_return)
5439         return "";
5440
5441       /* Otherwise, trap an attempted return by aborting. */
5442       ops[0] = operand;
5443       ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)" 
5444                                    : "abort");
5445       assemble_external_libcall (ops[1]);
5446       output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
5447       return "";
5448     }
5449       
5450   if (current_function_calls_alloca && ! really_return)
5451     abort ();
5452     
5453   for (reg = 0; reg <= 10; reg++)
5454     if (regs_ever_live[reg] && ! call_used_regs[reg])
5455       live_regs++;
5456
5457   if (flag_pic && ! TARGET_SINGLE_PIC_BASE
5458       && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
5459     live_regs++;
5460
5461   if (live_regs || (regs_ever_live[LR_REGNUM] && ! lr_save_eliminated))
5462     live_regs++;
5463
5464   if (frame_pointer_needed)
5465     live_regs += 4;
5466
5467   if (live_regs)
5468     {
5469       if (lr_save_eliminated || ! regs_ever_live[LR_REGNUM])
5470         live_regs++;
5471
5472       if (frame_pointer_needed)
5473         strcpy (instr,
5474                 reverse ? "ldm%?%D0ea\t%|fp, {" : "ldm%?%d0ea\t%|fp, {");
5475       else
5476         strcpy (instr, 
5477                 reverse ? "ldm%?%D0fd\t%|sp!, {" : "ldm%?%d0fd\t%|sp!, {");
5478
5479       for (reg = 0; reg <= 10; reg++)
5480         if (regs_ever_live[reg]
5481             && (! call_used_regs[reg]
5482                 || (flag_pic && ! TARGET_SINGLE_PIC_BASE
5483                     && reg == PIC_OFFSET_TABLE_REGNUM)))
5484           {
5485             strcat (instr, "%|");
5486             strcat (instr, reg_names[reg]);
5487             if (--live_regs)
5488               strcat (instr, ", ");
5489           }
5490
5491       if (frame_pointer_needed)
5492         {
5493           strcat (instr, "%|");
5494           strcat (instr, reg_names[11]);
5495           strcat (instr, ", ");
5496           strcat (instr, "%|");
5497           strcat (instr, reg_names[13]);
5498           strcat (instr, ", ");
5499           strcat (instr, "%|");
5500           strcat (instr, TARGET_INTERWORK || (! really_return)
5501                   ? reg_names[LR_REGNUM] : reg_names[PC_REGNUM] );
5502         }
5503       else
5504         {
5505           strcat (instr, "%|");
5506           if (TARGET_INTERWORK && really_return)
5507             strcat (instr, reg_names[IP_REGNUM]);
5508           else
5509             strcat (instr, really_return ? reg_names[PC_REGNUM] : reg_names[LR_REGNUM]);
5510         }
5511       strcat (instr, (TARGET_APCS_32 || !really_return) ? "}" : "}^");
5512       output_asm_insn (instr, &operand);
5513
5514       if (TARGET_INTERWORK && really_return)
5515         {
5516           strcpy (instr, "bx%?");
5517           strcat (instr, reverse ? "%D0" : "%d0");
5518           strcat (instr, "\t%|");
5519           strcat (instr, frame_pointer_needed ? "lr" : "ip");
5520
5521           output_asm_insn (instr, & operand);
5522         }
5523     }
5524   else if (really_return)
5525     {
5526       if (TARGET_INTERWORK)
5527         sprintf (instr, "bx%%?%%%s0\t%%|lr", reverse ? "D" : "d");
5528       else
5529         sprintf (instr, "mov%%?%%%s0%s\t%%|pc, %%|lr",
5530                  reverse ? "D" : "d", TARGET_APCS_32 ? "" : "s");
5531       
5532       output_asm_insn (instr, & operand);
5533     }
5534
5535   return "";
5536 }
5537
5538 /* Return nonzero if optimizing and the current function is volatile.
5539    Such functions never return, and many memory cycles can be saved
5540    by not storing register values that will never be needed again.
5541    This optimization was added to speed up context switching in a
5542    kernel application. */
5543
5544 int
5545 arm_volatile_func ()
5546 {
5547   return (optimize > 0 && TREE_THIS_VOLATILE (current_function_decl));
5548 }
5549
5550 /* Write the function name into the code section, directly preceding
5551    the function prologue.
5552
5553    Code will be output similar to this:
5554      t0
5555          .ascii "arm_poke_function_name", 0
5556          .align
5557      t1
5558          .word 0xff000000 + (t1 - t0)
5559      arm_poke_function_name
5560          mov     ip, sp
5561          stmfd   sp!, {fp, ip, lr, pc}
5562          sub     fp, ip, #4
5563
5564    When performing a stack backtrace, code can inspect the value
5565    of 'pc' stored at 'fp' + 0.  If the trace function then looks
5566    at location pc - 12 and the top 8 bits are set, then we know
5567    that there is a function name embedded immediately preceding this
5568    location and has length ((pc[-3]) & 0xff000000).
5569
5570    We assume that pc is declared as a pointer to an unsigned long.
5571
5572    It is of no benefit to output the function name if we are assembling
5573    a leaf function.  These function types will not contain a stack
5574    backtrace structure, therefore it is not possible to determine the
5575    function name.  */
5576
5577 void
5578 arm_poke_function_name (stream, name)
5579    FILE * stream;
5580    char * name;
5581 {
5582   unsigned long alignlength;
5583   unsigned long length;
5584   rtx           x;
5585
5586   length = strlen (name) + 1;
5587   alignlength = (length + 3) & ~3;
5588   
5589   ASM_OUTPUT_ASCII (stream, name, length);
5590   ASM_OUTPUT_ALIGN (stream, 2);
5591   x = GEN_INT (0xff000000UL + alignlength);
5592   ASM_OUTPUT_INT (stream, x);
5593 }
5594
5595 /* The amount of stack adjustment that happens here, in output_return and in
5596    output_epilogue must be exactly the same as was calculated during reload,
5597    or things will point to the wrong place.  The only time we can safely
5598    ignore this constraint is when a function has no arguments on the stack,
5599    no stack frame requirement and no live registers execpt for `lr'.  If we
5600    can guarantee that by making all function calls into tail calls and that
5601    lr is not clobbered in any other way, then there is no need to push lr
5602    onto the stack. */
5603    
5604 void
5605 output_func_prologue (f, frame_size)
5606      FILE * f;
5607      int frame_size;
5608 {
5609   int reg, live_regs_mask = 0;
5610   int volatile_func = (optimize > 0
5611                        && TREE_THIS_VOLATILE (current_function_decl));
5612
5613   /* Nonzero if we must stuff some register arguments onto the stack as if
5614      they were passed there.  */
5615   int store_arg_regs = 0;
5616
5617   if (arm_ccfsm_state || arm_target_insn)
5618     abort ();                                   /* Sanity check */
5619
5620   if (arm_naked_function_p (current_function_decl))
5621     return;
5622
5623   return_used_this_function = 0;
5624   lr_save_eliminated = 0;
5625   
5626   asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %d\n",
5627                current_function_args_size,
5628                current_function_pretend_args_size, frame_size);
5629   asm_fprintf (f, "\t%@ frame_needed = %d, current_function_anonymous_args = %d\n",
5630                frame_pointer_needed,
5631                current_function_anonymous_args);
5632
5633   if (volatile_func)
5634     asm_fprintf (f, "\t%@ Volatile function.\n");
5635
5636   if (current_function_anonymous_args && current_function_pretend_args_size)
5637     store_arg_regs = 1;
5638
5639   for (reg = 0; reg <= 10; reg++)
5640     if (regs_ever_live[reg] && ! call_used_regs[reg])
5641       live_regs_mask |= (1 << reg);
5642
5643   if (flag_pic && ! TARGET_SINGLE_PIC_BASE
5644       && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
5645     live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM);
5646
5647   if (frame_pointer_needed)
5648     live_regs_mask |= 0xD800;
5649   else if (regs_ever_live[LR_REGNUM])
5650     {
5651       if (! current_function_args_size
5652           && ! function_really_clobbers_lr (get_insns ()))
5653         lr_save_eliminated = 1;
5654       else
5655         live_regs_mask |= 1 << LR_REGNUM;
5656     }
5657
5658   if (live_regs_mask)
5659     {
5660       /* if a di mode load/store multiple is used, and the base register
5661          is r3, then r4 can become an ever live register without lr
5662          doing so,  in this case we need to push lr as well, or we
5663          will fail to get a proper return. */
5664
5665       live_regs_mask |= 1 << LR_REGNUM;
5666       lr_save_eliminated = 0;
5667
5668     }
5669
5670   if (lr_save_eliminated)
5671     asm_fprintf (f,"\t%@ I don't think this function clobbers lr\n");
5672
5673 #ifdef AOF_ASSEMBLER
5674   if (flag_pic)
5675     asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, PIC_OFFSET_TABLE_REGNUM);
5676 #endif
5677 }
5678
5679 char *
5680 arm_output_epilogue ()
5681 {
5682   int reg;
5683   int live_regs_mask = 0;
5684   /* If we need this, then it will always be at least this much */
5685   int floats_offset = 12;
5686   rtx operands[3];
5687   int frame_size = get_frame_size ();
5688   FILE *f = asm_out_file;
5689   int volatile_func = (optimize > 0
5690                        && TREE_THIS_VOLATILE (current_function_decl));
5691
5692   if (use_return_insn (FALSE) && return_used_this_function)
5693     return "";
5694
5695   /* Naked functions don't have epilogues.  */
5696   if (arm_naked_function_p (current_function_decl))
5697     return "";
5698
5699   /* A volatile function should never return.  Call abort.  */
5700   if (TARGET_ABORT_NORETURN && volatile_func)
5701     {
5702       rtx op;
5703       op = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)" : "abort");
5704       assemble_external_libcall (op);
5705       output_asm_insn ("bl\t%a0", &op);
5706       return "";
5707     }
5708
5709   for (reg = 0; reg <= 10; reg++)
5710     if (regs_ever_live[reg] && ! call_used_regs[reg])
5711       {
5712         live_regs_mask |= (1 << reg);
5713         floats_offset += 4;
5714       }
5715
5716   /* If we aren't loading the PIC register, don't stack it even though it may
5717      be live.  */
5718   if (flag_pic && ! TARGET_SINGLE_PIC_BASE 
5719       && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
5720     {
5721       live_regs_mask |= (1 << PIC_OFFSET_TABLE_REGNUM);
5722       floats_offset += 4;
5723     }
5724
5725   if (frame_pointer_needed)
5726     {
5727       if (arm_fpu_arch == FP_SOFT2)
5728         {
5729           for (reg = 23; reg > 15; reg--)
5730             if (regs_ever_live[reg] && ! call_used_regs[reg])
5731               {
5732                 floats_offset += 12;
5733                 asm_fprintf (f, "\tldfe\t%r, [%r, #-%d]\n", 
5734                              reg, FP_REGNUM, floats_offset);
5735               }
5736         }
5737       else
5738         {
5739           int start_reg = 23;
5740
5741           for (reg = 23; reg > 15; reg--)
5742             {
5743               if (regs_ever_live[reg] && ! call_used_regs[reg])
5744                 {
5745                   floats_offset += 12;
5746                   
5747                   /* We can't unstack more than four registers at once */
5748                   if (start_reg - reg == 3)
5749                     {
5750                       asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
5751                                    reg, FP_REGNUM, floats_offset);
5752                       start_reg = reg - 1;
5753                     }
5754                 }
5755               else
5756                 {
5757                   if (reg != start_reg)
5758                     asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
5759                                  reg + 1, start_reg - reg,
5760                                  FP_REGNUM, floats_offset);
5761                   start_reg = reg - 1;
5762                 }
5763             }
5764
5765           /* Just in case the last register checked also needs unstacking.  */
5766           if (reg != start_reg)
5767             asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
5768                          reg + 1, start_reg - reg,
5769                          FP_REGNUM, floats_offset);
5770         }
5771       
5772       if (TARGET_INTERWORK)
5773         {
5774           live_regs_mask |= 0x6800;
5775           print_multi_reg (f, "ldmea\t%r", FP_REGNUM, live_regs_mask, FALSE);
5776           asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
5777         }
5778       else
5779         {
5780           live_regs_mask |= 0xA800;
5781           print_multi_reg (f, "ldmea\t%r", FP_REGNUM, live_regs_mask,
5782                            TARGET_APCS_32 ? FALSE : TRUE);
5783         }
5784     }
5785   else
5786     {
5787       /* Restore stack pointer if necessary.  */
5788       if (frame_size + current_function_outgoing_args_size != 0)
5789         {
5790           operands[0] = operands[1] = stack_pointer_rtx;
5791           operands[2] = GEN_INT (frame_size
5792                                  + current_function_outgoing_args_size);
5793           output_add_immediate (operands);
5794         }
5795
5796       if (arm_fpu_arch == FP_SOFT2)
5797         {
5798           for (reg = 16; reg < 24; reg++)
5799             if (regs_ever_live[reg] && ! call_used_regs[reg])
5800               asm_fprintf (f, "\tldfe\t%r, [%r], #12\n",
5801                            reg, SP_REGNUM);
5802         }
5803       else
5804         {
5805           int start_reg = 16;
5806
5807           for (reg = 16; reg < 24; reg++)
5808             {
5809               if (regs_ever_live[reg] && ! call_used_regs[reg])
5810                 {
5811                   if (reg - start_reg == 3)
5812                     {
5813                       asm_fprintf (f, "\tlfmfd\t%r, 4, [%r]!\n",
5814                                    start_reg, SP_REGNUM);
5815                       start_reg = reg + 1;
5816                     }
5817                 }
5818               else
5819                 {
5820                   if (reg != start_reg)
5821                     asm_fprintf (f, "\tlfmfd\t%r, %d, [%r]!\n",
5822                                  start_reg, reg - start_reg,
5823                                  SP_REGNUM);
5824                   
5825                   start_reg = reg + 1;
5826                 }
5827             }
5828
5829           /* Just in case the last register checked also needs unstacking.  */
5830           if (reg != start_reg)
5831             asm_fprintf (f, "\tlfmfd\t%r, %d, [%r]!\n",
5832                          start_reg, reg - start_reg, SP_REGNUM);
5833         }
5834
5835       if (current_function_pretend_args_size == 0 && regs_ever_live[LR_REGNUM])
5836         {
5837           if (TARGET_INTERWORK)
5838             {
5839               if (! lr_save_eliminated)
5840                 live_regs_mask |= 1 << LR_REGNUM;
5841
5842               if (live_regs_mask != 0)
5843                 print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, live_regs_mask, FALSE);
5844               
5845               asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
5846             }
5847           else if (lr_save_eliminated)
5848             asm_fprintf (f, "\tmov%c\t%r, %r\n",
5849                          TARGET_APCS_32 ? ' ' : 's',
5850                          PC_REGNUM, LR_REGNUM);
5851           else
5852             print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, live_regs_mask | 0x8000,
5853                              TARGET_APCS_32 ? FALSE : TRUE);
5854         }
5855       else
5856         {
5857           if (live_regs_mask || regs_ever_live[LR_REGNUM])
5858             {
5859               /* Restore the integer regs, and the return address into lr */
5860               if (! lr_save_eliminated)
5861                 live_regs_mask |= 1 << LR_REGNUM;
5862
5863               if (live_regs_mask != 0)
5864                 print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, live_regs_mask, FALSE);
5865             }
5866
5867           if (current_function_pretend_args_size)
5868             {
5869               /* Unwind the pre-pushed regs */
5870               operands[0] = operands[1] = stack_pointer_rtx;
5871               operands[2] = GEN_INT (current_function_pretend_args_size);
5872               output_add_immediate (operands);
5873             }
5874           /* And finally, go home */
5875           if (TARGET_INTERWORK)
5876             asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
5877           else if (TARGET_APCS_32)
5878             asm_fprintf (f, "\tmov\t%r, %r\n", PC_REGNUM, LR_REGNUM);
5879           else
5880             asm_fprintf (f, "\tmovs\t%r, %r\n", PC_REGNUM, LR_REGNUM);
5881         }
5882     }
5883
5884   return "";
5885 }
5886
5887 void
5888 output_func_epilogue (f, frame_size)
5889      FILE *f ATTRIBUTE_UNUSED;
5890      int frame_size;
5891 {
5892   if (use_return_insn (FALSE) && return_used_this_function
5893       && (frame_size + current_function_outgoing_args_size) != 0
5894       && ! (frame_pointer_needed && TARGET_APCS))
5895         abort ();
5896
5897   /* Reset the ARM-specific per-function variables.  */
5898   current_function_anonymous_args = 0;
5899   after_arm_reorg = 0;
5900 }
5901
5902 static void
5903 emit_multi_reg_push (mask)
5904      int mask;
5905 {
5906   int num_regs = 0;
5907   int i, j;
5908   rtx par;
5909
5910   for (i = 0; i < 16; i++)
5911     if (mask & (1 << i))
5912       num_regs++;
5913
5914   if (num_regs == 0 || num_regs > 16)
5915     abort ();
5916
5917   par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
5918
5919   for (i = 0; i < 16; i++)
5920     {
5921       if (mask & (1 << i))
5922         {
5923           XVECEXP (par, 0, 0)
5924             = gen_rtx_SET (VOIDmode,
5925                            gen_rtx_MEM (BLKmode,
5926                                         gen_rtx_PRE_DEC (BLKmode,
5927                                                          stack_pointer_rtx)),
5928                            gen_rtx_UNSPEC (BLKmode,
5929                                            gen_rtvec (1,
5930                                                       gen_rtx_REG (SImode, i)),
5931                                            2));
5932           break;
5933         }
5934     }
5935
5936   for (j = 1, i++; j < num_regs; i++)
5937     {
5938       if (mask & (1 << i))
5939         {
5940           XVECEXP (par, 0, j)
5941             = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, i));
5942           j++;
5943         }
5944     }
5945
5946   emit_insn (par);
5947 }
5948
5949 static void
5950 emit_sfm (base_reg, count)
5951      int base_reg;
5952      int count;
5953 {
5954   rtx par;
5955   int i;
5956
5957   par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
5958
5959   XVECEXP (par, 0, 0)
5960     = gen_rtx_SET (VOIDmode, 
5961                    gen_rtx_MEM (BLKmode,
5962                                 gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
5963                    gen_rtx_UNSPEC (BLKmode,
5964                                    gen_rtvec (1, gen_rtx_REG (XFmode, 
5965                                                               base_reg++)),
5966                                    2));
5967   for (i = 1; i < count; i++)
5968     XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode, 
5969                                        gen_rtx_REG (XFmode, base_reg++));
5970
5971   emit_insn (par);
5972 }
5973
5974 void
5975 arm_expand_prologue ()
5976 {
5977   int reg;
5978   rtx amount = GEN_INT (-(get_frame_size ()
5979                           + current_function_outgoing_args_size));
5980   int live_regs_mask = 0;
5981   int store_arg_regs = 0;
5982   /* If this function doesn't return, then there is no need to push
5983      the call-saved regs.  */
5984   int volatile_func = (optimize > 0
5985                        && TREE_THIS_VOLATILE (current_function_decl));
5986
5987   /* Naked functions don't have prologues.  */
5988   if (arm_naked_function_p (current_function_decl))
5989     return;
5990
5991   if (current_function_anonymous_args && current_function_pretend_args_size)
5992     store_arg_regs = 1;
5993
5994   if (! volatile_func)
5995     {
5996       for (reg = 0; reg <= 10; reg++)
5997         if (regs_ever_live[reg] && ! call_used_regs[reg])
5998           live_regs_mask |= 1 << reg;
5999
6000       if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
6001         live_regs_mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
6002
6003       if (regs_ever_live[LR_REGNUM])
6004         live_regs_mask |= 1 << LR_REGNUM;
6005     }
6006
6007   if (frame_pointer_needed)
6008     {
6009       live_regs_mask |= 0xD800;
6010       emit_insn (gen_movsi (gen_rtx_REG (SImode, IP_REGNUM),
6011                             stack_pointer_rtx));
6012     }
6013
6014   if (current_function_pretend_args_size)
6015     {
6016       if (store_arg_regs)
6017         emit_multi_reg_push ((0xf0 >> (current_function_pretend_args_size / 4))
6018                              & 0xf);
6019       else
6020         emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, 
6021                                GEN_INT (-current_function_pretend_args_size)));
6022     }
6023
6024   if (live_regs_mask)
6025     {
6026       /* If we have to push any regs, then we must push lr as well, or
6027          we won't get a proper return.  */
6028       live_regs_mask |= 1 << LR_REGNUM;
6029       emit_multi_reg_push (live_regs_mask);
6030     }
6031       
6032   /* For now the integer regs are still pushed in output_func_epilogue ().  */
6033
6034   if (! volatile_func)
6035     {
6036       if (arm_fpu_arch == FP_SOFT2)
6037         {
6038           for (reg = 23; reg > 15; reg--)
6039             if (regs_ever_live[reg] && ! call_used_regs[reg])
6040               emit_insn (gen_rtx_SET
6041                          (VOIDmode, 
6042                           gen_rtx_MEM (XFmode, 
6043                                        gen_rtx_PRE_DEC (XFmode,
6044                                                         stack_pointer_rtx)),
6045                           gen_rtx_REG (XFmode, reg)));
6046         }
6047       else
6048         {
6049           int start_reg = 23;
6050
6051           for (reg = 23; reg > 15; reg--)
6052             {
6053               if (regs_ever_live[reg] && ! call_used_regs[reg])
6054                 {
6055                   if (start_reg - reg == 3)
6056                     {
6057                       emit_sfm (reg, 4);
6058                       start_reg = reg - 1;
6059                     }
6060                 }
6061               else
6062                 {
6063                   if (start_reg != reg)
6064                     emit_sfm (reg + 1, start_reg - reg);
6065                   start_reg = reg - 1;
6066                 }
6067             }
6068
6069           if (start_reg != reg)
6070             emit_sfm (reg + 1, start_reg - reg);
6071         }
6072     }
6073
6074   if (frame_pointer_needed)
6075     emit_insn (gen_addsi3 (hard_frame_pointer_rtx, gen_rtx_REG (SImode, IP_REGNUM),
6076                            (GEN_INT
6077                             (-(4 + current_function_pretend_args_size)))));
6078
6079   if (amount != const0_rtx)
6080     {
6081       emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, amount));
6082       emit_insn (gen_rtx_CLOBBER (VOIDmode, 
6083                                   gen_rtx_MEM (BLKmode, stack_pointer_rtx)));
6084     }
6085
6086   /* If we are profiling, make sure no instructions are scheduled before
6087      the call to mcount.  Similarly if the user has requested no
6088      scheduling in the prolog.  */
6089   if (profile_flag || profile_block_flag || TARGET_NO_SCHED_PRO)
6090     emit_insn (gen_blockage ());
6091 }
6092   
6093 \f
6094 /* If CODE is 'd', then the X is a condition operand and the instruction
6095    should only be executed if the condition is true.
6096    if CODE is 'D', then the X is a condition operand and the instruction
6097    should only be executed if the condition is false: however, if the mode
6098    of the comparison is CCFPEmode, then always execute the instruction -- we
6099    do this because in these circumstances !GE does not necessarily imply LT;
6100    in these cases the instruction pattern will take care to make sure that
6101    an instruction containing %d will follow, thereby undoing the effects of
6102    doing this instruction unconditionally.
6103    If CODE is 'N' then X is a floating point operand that must be negated
6104    before output.
6105    If CODE is 'B' then output a bitwise inverted value of X (a const int).
6106    If X is a REG and CODE is `M', output a ldm/stm style multi-reg.  */
6107
6108 void
6109 arm_print_operand (stream, x, code)
6110      FILE * stream;
6111      rtx x;
6112      int code;
6113 {
6114   switch (code)
6115     {
6116     case '@':
6117       fputs (ASM_COMMENT_START, stream);
6118       return;
6119
6120     case '|':
6121       fputs (REGISTER_PREFIX, stream);
6122       return;
6123
6124     case '?':
6125       if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
6126         fputs (arm_condition_codes[arm_current_cc], stream);
6127       return;
6128
6129     case 'N':
6130       {
6131         REAL_VALUE_TYPE r;
6132         REAL_VALUE_FROM_CONST_DOUBLE (r, x);
6133         r = REAL_VALUE_NEGATE (r);
6134         fprintf (stream, "%s", fp_const_from_val (&r));
6135       }
6136       return;
6137
6138     case 'B':
6139       if (GET_CODE (x) == CONST_INT)
6140         {
6141           HOST_WIDE_INT val;
6142           val = ARM_SIGN_EXTEND (~ INTVAL (x));
6143           fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
6144         }
6145       else
6146         {
6147           putc ('~', stream);
6148           output_addr_const (stream, x);
6149         }
6150       return;
6151
6152     case 'i':
6153       fprintf (stream, "%s", arithmetic_instr (x, 1));
6154       return;
6155
6156     case 'I':
6157       fprintf (stream, "%s", arithmetic_instr (x, 0));
6158       return;
6159
6160     case 'S':
6161       {
6162         HOST_WIDE_INT val;
6163         char * shift = shift_op (x, & val);
6164
6165         if (shift)
6166           {
6167             fprintf (stream, ", %s ", shift_op (x, & val));
6168             if (val == -1)
6169               arm_print_operand (stream, XEXP (x, 1), 0);
6170             else
6171               {
6172                 fputc ('#', stream);
6173                 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
6174               }
6175           }
6176       }
6177       return;
6178
6179     case 'Q':
6180       if (REGNO (x) > 15)
6181         abort ();
6182       fputs (REGISTER_PREFIX, stream);
6183       fputs (reg_names[REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0)], stream);
6184       return;
6185
6186     case 'R':
6187       if (REGNO (x) > 15)
6188         abort ();
6189       fputs (REGISTER_PREFIX, stream);
6190       fputs (reg_names[REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1)], stream);
6191       return;
6192
6193     case 'm':
6194       fputs (REGISTER_PREFIX, stream);
6195       if (GET_CODE (XEXP (x, 0)) == REG)
6196         fputs (reg_names[REGNO (XEXP (x, 0))], stream);
6197       else
6198         fputs (reg_names[REGNO (XEXP (XEXP (x, 0), 0))], stream);
6199       return;
6200
6201     case 'M':
6202       asm_fprintf (stream, "{%r-%r}",
6203                    REGNO (x), REGNO (x) + NUM_REGS (GET_MODE (x)) - 1);
6204       return;
6205
6206     case 'd':
6207       if (x)
6208         fputs (arm_condition_codes[get_arm_condition_code (x)],
6209                stream);
6210       return;
6211
6212     case 'D':
6213       if (x)
6214         fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
6215                                    (get_arm_condition_code (x))],
6216                stream);
6217       return;
6218
6219     default:
6220       if (x == 0)
6221         abort ();
6222
6223       if (GET_CODE (x) == REG)
6224         {
6225           fputs (REGISTER_PREFIX, stream);
6226           fputs (reg_names[REGNO (x)], stream);
6227         }
6228       else if (GET_CODE (x) == MEM)
6229         {
6230           output_memory_reference_mode = GET_MODE (x);
6231           output_address (XEXP (x, 0));
6232         }
6233       else if (GET_CODE (x) == CONST_DOUBLE)
6234         fprintf (stream, "#%s", fp_immediate_constant (x));
6235       else if (GET_CODE (x) == NEG)
6236         abort (); /* This should never happen now. */
6237       else
6238         {
6239           fputc ('#', stream);
6240           output_addr_const (stream, x);
6241         }
6242     }
6243 }
6244 \f
6245 /* A finite state machine takes care of noticing whether or not instructions
6246    can be conditionally executed, and thus decrease execution time and code
6247    size by deleting branch instructions.  The fsm is controlled by
6248    final_prescan_insn, and controls the actions of ASM_OUTPUT_OPCODE.  */
6249
6250 /* The state of the fsm controlling condition codes are:
6251    0: normal, do nothing special
6252    1: make ASM_OUTPUT_OPCODE not output this instruction
6253    2: make ASM_OUTPUT_OPCODE not output this instruction
6254    3: make instructions conditional
6255    4: make instructions conditional
6256
6257    State transitions (state->state by whom under condition):
6258    0 -> 1 final_prescan_insn if the `target' is a label
6259    0 -> 2 final_prescan_insn if the `target' is an unconditional branch
6260    1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
6261    2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
6262    3 -> 0 ASM_OUTPUT_INTERNAL_LABEL if the `target' label is reached
6263           (the target label has CODE_LABEL_NUMBER equal to arm_target_label).
6264    4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
6265           (the target insn is arm_target_insn).
6266
6267    If the jump clobbers the conditions then we use states 2 and 4.
6268
6269    A similar thing can be done with conditional return insns.
6270
6271    XXX In case the `target' is an unconditional branch, this conditionalising
6272    of the instructions always reduces code size, but not always execution
6273    time.  But then, I want to reduce the code size to somewhere near what
6274    /bin/cc produces.  */
6275
6276 /* Returns the index of the ARM condition code string in
6277    `arm_condition_codes'.  COMPARISON should be an rtx like
6278    `(eq (...) (...))'.  */
6279
6280 static enum arm_cond_code
6281 get_arm_condition_code (comparison)
6282      rtx comparison;
6283 {
6284   enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
6285   register int code;
6286   register enum rtx_code comp_code = GET_CODE (comparison);
6287
6288   if (GET_MODE_CLASS (mode) != MODE_CC)
6289     mode = SELECT_CC_MODE (comp_code, XEXP (comparison, 0),
6290                            XEXP (comparison, 1));
6291
6292   switch (mode)
6293     {
6294     case CC_DNEmode: code = ARM_NE; goto dominance;
6295     case CC_DEQmode: code = ARM_EQ; goto dominance;
6296     case CC_DGEmode: code = ARM_GE; goto dominance;
6297     case CC_DGTmode: code = ARM_GT; goto dominance;
6298     case CC_DLEmode: code = ARM_LE; goto dominance;
6299     case CC_DLTmode: code = ARM_LT; goto dominance;
6300     case CC_DGEUmode: code = ARM_CS; goto dominance;
6301     case CC_DGTUmode: code = ARM_HI; goto dominance;
6302     case CC_DLEUmode: code = ARM_LS; goto dominance;
6303     case CC_DLTUmode: code = ARM_CC;
6304
6305     dominance:
6306       if (comp_code != EQ && comp_code != NE)
6307         abort ();
6308
6309       if (comp_code == EQ)
6310         return ARM_INVERSE_CONDITION_CODE (code);
6311       return code;
6312
6313     case CC_NOOVmode:
6314       switch (comp_code)
6315         {
6316         case NE: return ARM_NE;
6317         case EQ: return ARM_EQ;
6318         case GE: return ARM_PL;
6319         case LT: return ARM_MI;
6320         default: abort ();
6321         }
6322
6323     case CC_Zmode:
6324     case CCFPmode:
6325       switch (comp_code)
6326         {
6327         case NE: return ARM_NE;
6328         case EQ: return ARM_EQ;
6329         default: abort ();
6330         }
6331
6332     case CCFPEmode:
6333       switch (comp_code)
6334         {
6335         case GE: return ARM_GE;
6336         case GT: return ARM_GT;
6337         case LE: return ARM_LS;
6338         case LT: return ARM_MI;
6339         default: abort ();
6340         }
6341
6342     case CC_SWPmode:
6343       switch (comp_code)
6344         {
6345         case NE: return ARM_NE;
6346         case EQ: return ARM_EQ;
6347         case GE: return ARM_LE;
6348         case GT: return ARM_LT;
6349         case LE: return ARM_GE;
6350         case LT: return ARM_GT;
6351         case GEU: return ARM_LS;
6352         case GTU: return ARM_CC;
6353         case LEU: return ARM_CS;
6354         case LTU: return ARM_HI;
6355         default: abort ();
6356         }
6357
6358     case CC_Cmode:
6359       switch (comp_code)
6360       {
6361       case LTU: return ARM_CS;
6362       case GEU: return ARM_CC;
6363       default: abort ();
6364       }
6365       
6366     case CCmode:
6367       switch (comp_code)
6368         {
6369         case NE: return ARM_NE;
6370         case EQ: return ARM_EQ;
6371         case GE: return ARM_GE;
6372         case GT: return ARM_GT;
6373         case LE: return ARM_LE;
6374         case LT: return ARM_LT;
6375         case GEU: return ARM_CS;
6376         case GTU: return ARM_HI;
6377         case LEU: return ARM_LS;
6378         case LTU: return ARM_CC;
6379         default: abort ();
6380         }
6381
6382     default: abort ();
6383     }
6384
6385   abort ();
6386 }
6387
6388
6389 void
6390 arm_final_prescan_insn (insn)
6391      rtx insn;
6392 {
6393   /* BODY will hold the body of INSN.  */
6394   register rtx body = PATTERN (insn);
6395
6396   /* This will be 1 if trying to repeat the trick, and things need to be
6397      reversed if it appears to fail.  */
6398   int reverse = 0;
6399
6400   /* JUMP_CLOBBERS will be one implies that the conditions if a branch is
6401      taken are clobbered, even if the rtl suggests otherwise.  It also
6402      means that we have to grub around within the jump expression to find
6403      out what the conditions are when the jump isn't taken.  */
6404   int jump_clobbers = 0;
6405   
6406   /* If we start with a return insn, we only succeed if we find another one. */
6407   int seeking_return = 0;
6408   
6409   /* START_INSN will hold the insn from where we start looking.  This is the
6410      first insn after the following code_label if REVERSE is true.  */
6411   rtx start_insn = insn;
6412
6413   /* If in state 4, check if the target branch is reached, in order to
6414      change back to state 0.  */
6415   if (arm_ccfsm_state == 4)
6416     {
6417       if (insn == arm_target_insn)
6418         {
6419           arm_target_insn = NULL;
6420           arm_ccfsm_state = 0;
6421         }
6422       return;
6423     }
6424
6425   /* If in state 3, it is possible to repeat the trick, if this insn is an
6426      unconditional branch to a label, and immediately following this branch
6427      is the previous target label which is only used once, and the label this
6428      branch jumps to is not too far off.  */
6429   if (arm_ccfsm_state == 3)
6430     {
6431       if (simplejump_p (insn))
6432         {
6433           start_insn = next_nonnote_insn (start_insn);
6434           if (GET_CODE (start_insn) == BARRIER)
6435             {
6436               /* XXX Isn't this always a barrier?  */
6437               start_insn = next_nonnote_insn (start_insn);
6438             }
6439           if (GET_CODE (start_insn) == CODE_LABEL
6440               && CODE_LABEL_NUMBER (start_insn) == arm_target_label
6441               && LABEL_NUSES (start_insn) == 1)
6442             reverse = TRUE;
6443           else
6444             return;
6445         }
6446       else if (GET_CODE (body) == RETURN)
6447         {
6448           start_insn = next_nonnote_insn (start_insn);
6449           if (GET_CODE (start_insn) == BARRIER)
6450             start_insn = next_nonnote_insn (start_insn);
6451           if (GET_CODE (start_insn) == CODE_LABEL
6452               && CODE_LABEL_NUMBER (start_insn) == arm_target_label
6453               && LABEL_NUSES (start_insn) == 1)
6454             {
6455               reverse = TRUE;
6456               seeking_return = 1;
6457             }
6458           else
6459             return;
6460         }
6461       else
6462         return;
6463     }
6464
6465   if (arm_ccfsm_state != 0 && !reverse)
6466     abort ();
6467   if (GET_CODE (insn) != JUMP_INSN)
6468     return;
6469
6470   /* This jump might be paralleled with a clobber of the condition codes 
6471      the jump should always come first */
6472   if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
6473     body = XVECEXP (body, 0, 0);
6474
6475 #if 0  
6476   /* If this is a conditional return then we don't want to know */
6477   if (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
6478       && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
6479       && (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN
6480           || GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN))
6481     return;
6482 #endif
6483
6484   if (reverse
6485       || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
6486           && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
6487     {
6488       int insns_skipped;
6489       int fail = FALSE, succeed = FALSE;
6490       /* Flag which part of the IF_THEN_ELSE is the LABEL_REF.  */
6491       int then_not_else = TRUE;
6492       rtx this_insn = start_insn, label = 0;
6493
6494       if (get_attr_conds (insn) == CONDS_JUMP_CLOB)
6495         {
6496           /* The code below is wrong for these, and I haven't time to
6497              fix it now.  So we just do the safe thing and return.  This
6498              whole function needs re-writing anyway.  */
6499           jump_clobbers = 1;
6500           return;
6501         }
6502       
6503       /* Register the insn jumped to.  */
6504       if (reverse)
6505         {
6506           if (!seeking_return)
6507             label = XEXP (SET_SRC (body), 0);
6508         }
6509       else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
6510         label = XEXP (XEXP (SET_SRC (body), 1), 0);
6511       else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
6512         {
6513           label = XEXP (XEXP (SET_SRC (body), 2), 0);
6514           then_not_else = FALSE;
6515         }
6516       else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
6517         seeking_return = 1;
6518       else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
6519         {
6520           seeking_return = 1;
6521           then_not_else = FALSE;
6522         }
6523       else
6524         abort ();
6525
6526       /* See how many insns this branch skips, and what kind of insns.  If all
6527          insns are okay, and the label or unconditional branch to the same
6528          label is not too far away, succeed.  */
6529       for (insns_skipped = 0;
6530            !fail && !succeed && insns_skipped++ < max_insns_skipped;)
6531         {
6532           rtx scanbody;
6533
6534           this_insn = next_nonnote_insn (this_insn);
6535           if (!this_insn)
6536             break;
6537
6538           switch (GET_CODE (this_insn))
6539             {
6540             case CODE_LABEL:
6541               /* Succeed if it is the target label, otherwise fail since
6542                  control falls in from somewhere else.  */
6543               if (this_insn == label)
6544                 {
6545                   if (jump_clobbers)
6546                     {
6547                       arm_ccfsm_state = 2;
6548                       this_insn = next_nonnote_insn (this_insn);
6549                     }
6550                   else
6551                     arm_ccfsm_state = 1;
6552                   succeed = TRUE;
6553                 }
6554               else
6555                 fail = TRUE;
6556               break;
6557
6558             case BARRIER:
6559               /* Succeed if the following insn is the target label.
6560                  Otherwise fail.  
6561                  If return insns are used then the last insn in a function 
6562                  will be a barrier. */
6563               this_insn = next_nonnote_insn (this_insn);
6564               if (this_insn && this_insn == label)
6565                 {
6566                   if (jump_clobbers)
6567                     {
6568                       arm_ccfsm_state = 2;
6569                       this_insn = next_nonnote_insn (this_insn);
6570                     }
6571                   else
6572                     arm_ccfsm_state = 1;
6573                   succeed = TRUE;
6574                 }
6575               else
6576                 fail = TRUE;
6577               break;
6578
6579             case CALL_INSN:
6580               /* If using 32-bit addresses the cc is not preserved over
6581                  calls */
6582               if (TARGET_APCS_32)
6583                 {
6584                   /* Succeed if the following insn is the target label,
6585                      or if the following two insns are a barrier and
6586                      the target label.  */
6587                   this_insn = next_nonnote_insn (this_insn);
6588                   if (this_insn && GET_CODE (this_insn) == BARRIER)
6589                     this_insn = next_nonnote_insn (this_insn);
6590
6591                   if (this_insn && this_insn == label
6592                       && insns_skipped < max_insns_skipped)
6593                     {
6594                       if (jump_clobbers)
6595                         {
6596                           arm_ccfsm_state = 2;
6597                           this_insn = next_nonnote_insn (this_insn);
6598                         }
6599                       else
6600                         arm_ccfsm_state = 1;
6601                       succeed = TRUE;
6602                     }
6603                   else
6604                     fail = TRUE;
6605                 }
6606               break;
6607
6608             case JUMP_INSN:
6609               /* If this is an unconditional branch to the same label, succeed.
6610                  If it is to another label, do nothing.  If it is conditional,
6611                  fail.  */
6612               /* XXX Probably, the tests for SET and the PC are unnecessary. */
6613
6614               scanbody = PATTERN (this_insn);
6615               if (GET_CODE (scanbody) == SET
6616                   && GET_CODE (SET_DEST (scanbody)) == PC)
6617                 {
6618                   if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
6619                       && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
6620                     {
6621                       arm_ccfsm_state = 2;
6622                       succeed = TRUE;
6623                     }
6624                   else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
6625                     fail = TRUE;
6626                 }
6627               /* Fail if a conditional return is undesirable (eg on a
6628                  StrongARM), but still allow this if optimizing for size.  */
6629               else if (GET_CODE (scanbody) == RETURN
6630                        && ! use_return_insn (TRUE)
6631                        && ! optimize_size)
6632                 fail = TRUE;
6633               else if (GET_CODE (scanbody) == RETURN
6634                        && seeking_return)
6635                 {
6636                   arm_ccfsm_state = 2;
6637                   succeed = TRUE;
6638                 }
6639               else if (GET_CODE (scanbody) == PARALLEL)
6640                 {
6641                   switch (get_attr_conds (this_insn))
6642                     {
6643                     case CONDS_NOCOND:
6644                       break;
6645                     default:
6646                       fail = TRUE;
6647                       break;
6648                     }
6649                 }
6650               break;
6651
6652             case INSN:
6653               /* Instructions using or affecting the condition codes make it
6654                  fail.  */
6655               scanbody = PATTERN (this_insn);
6656               if (! (GET_CODE (scanbody) == SET
6657                      || GET_CODE (scanbody) == PARALLEL)
6658                   || get_attr_conds (this_insn) != CONDS_NOCOND)
6659                 fail = TRUE;
6660               break;
6661
6662             default:
6663               break;
6664             }
6665         }
6666       if (succeed)
6667         {
6668           if ((!seeking_return) && (arm_ccfsm_state == 1 || reverse))
6669             arm_target_label = CODE_LABEL_NUMBER (label);
6670           else if (seeking_return || arm_ccfsm_state == 2)
6671             {
6672               while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
6673                 {
6674                   this_insn = next_nonnote_insn (this_insn);
6675                   if (this_insn && (GET_CODE (this_insn) == BARRIER
6676                                     || GET_CODE (this_insn) == CODE_LABEL))
6677                     abort ();
6678                 }
6679               if (!this_insn)
6680                 {
6681                   /* Oh, dear! we ran off the end.. give up */
6682                   recog (PATTERN (insn), insn, NULL_PTR);
6683                   arm_ccfsm_state = 0;
6684                   arm_target_insn = NULL;
6685                   return;
6686                 }
6687               arm_target_insn = this_insn;
6688             }
6689           else
6690             abort ();
6691           if (jump_clobbers)
6692             {
6693               if (reverse)
6694                 abort ();
6695               arm_current_cc = 
6696                   get_arm_condition_code (XEXP (XEXP (XEXP (SET_SRC (body),
6697                                                             0), 0), 1));
6698               if (GET_CODE (XEXP (XEXP (SET_SRC (body), 0), 0)) == AND)
6699                 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6700               if (GET_CODE (XEXP (SET_SRC (body), 0)) == NE)
6701                 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6702             }
6703           else
6704             {
6705               /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
6706                  what it was.  */
6707               if (!reverse)
6708                 arm_current_cc = get_arm_condition_code (XEXP (SET_SRC (body),
6709                                                                0));
6710             }
6711
6712           if (reverse || then_not_else)
6713             arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
6714         }
6715
6716       /* Restore recog_data (getting the attributes of other insns can
6717          destroy this array, but final.c assumes that it remains intact
6718          across this call; since the insn has been recognized already we
6719          call recog direct). */
6720       recog (PATTERN (insn), insn, NULL_PTR);
6721     }
6722 }
6723
6724 #ifdef AOF_ASSEMBLER
6725 /* Special functions only needed when producing AOF syntax assembler. */
6726
6727 rtx aof_pic_label = NULL_RTX;
6728 struct pic_chain
6729 {
6730   struct pic_chain * next;
6731   char * symname;
6732 };
6733
6734 static struct pic_chain * aof_pic_chain = NULL;
6735
6736 rtx
6737 aof_pic_entry (x)
6738      rtx x;
6739 {
6740   struct pic_chain ** chainp;
6741   int offset;
6742
6743   if (aof_pic_label == NULL_RTX)
6744     {
6745       /* We mark this here and not in arm_add_gc_roots() to avoid
6746          polluting even more code with ifdefs, and because it never
6747          contains anything useful until we assign to it here.  */
6748       ggc_add_rtx_root (&aof_pic_label, 1);
6749       /* This needs to persist throughout the compilation.  */
6750       end_temporary_allocation ();
6751       aof_pic_label = gen_rtx_SYMBOL_REF (Pmode, "x$adcons");
6752       resume_temporary_allocation ();
6753     }
6754
6755   for (offset = 0, chainp = &aof_pic_chain; *chainp;
6756        offset += 4, chainp = &(*chainp)->next)
6757     if ((*chainp)->symname == XSTR (x, 0))
6758       return plus_constant (aof_pic_label, offset);
6759
6760   *chainp = (struct pic_chain *) xmalloc (sizeof (struct pic_chain));
6761   (*chainp)->next = NULL;
6762   (*chainp)->symname = XSTR (x, 0);
6763   return plus_constant (aof_pic_label, offset);
6764 }
6765
6766 void
6767 aof_dump_pic_table (f)
6768      FILE * f;
6769 {
6770   struct pic_chain * chain;
6771
6772   if (aof_pic_chain == NULL)
6773     return;
6774
6775   asm_fprintf (f, "\tAREA |%r$$adcons|, BASED %r\n",
6776                PIC_OFFSET_TABLE_REGNUM,
6777                PIC_OFFSET_TABLE_REGNUM);
6778   fputs ("|x$adcons|\n", f);
6779   
6780   for (chain = aof_pic_chain; chain; chain = chain->next)
6781     {
6782       fputs ("\tDCD\t", f);
6783       assemble_name (f, chain->symname);
6784       fputs ("\n", f);
6785     }
6786 }
6787
6788 int arm_text_section_count = 1;
6789
6790 char *
6791 aof_text_section ()
6792 {
6793   static char buf[100];
6794   sprintf (buf, "\tAREA |C$$code%d|, CODE, READONLY",
6795            arm_text_section_count++);
6796   if (flag_pic)
6797     strcat (buf, ", PIC, REENTRANT");
6798   return buf;
6799 }
6800
6801 static int arm_data_section_count = 1;
6802
6803 char *
6804 aof_data_section ()
6805 {
6806   static char buf[100];
6807   sprintf (buf, "\tAREA |C$$data%d|, DATA", arm_data_section_count++);
6808   return buf;
6809 }
6810
6811 /* The AOF assembler is religiously strict about declarations of
6812    imported and exported symbols, so that it is impossible to declare
6813    a function as imported near the beginning of the file, and then to
6814    export it later on.  It is, however, possible to delay the decision
6815    until all the functions in the file have been compiled.  To get
6816    around this, we maintain a list of the imports and exports, and
6817    delete from it any that are subsequently defined.  At the end of
6818    compilation we spit the remainder of the list out before the END
6819    directive.  */
6820
6821 struct import
6822 {
6823   struct import * next;
6824   char * name;
6825 };
6826
6827 static struct import * imports_list = NULL;
6828
6829 void
6830 aof_add_import (name)
6831      char * name;
6832 {
6833   struct import * new;
6834
6835   for (new = imports_list; new; new = new->next)
6836     if (new->name == name)
6837       return;
6838
6839   new = (struct import *) xmalloc (sizeof (struct import));
6840   new->next = imports_list;
6841   imports_list = new;
6842   new->name = name;
6843 }
6844
6845 void
6846 aof_delete_import (name)
6847      char * name;
6848 {
6849   struct import ** old;
6850
6851   for (old = &imports_list; *old; old = & (*old)->next)
6852     {
6853       if ((*old)->name == name)
6854         {
6855           *old = (*old)->next;
6856           return;
6857         }
6858     }
6859 }
6860
6861 int arm_main_function = 0;
6862
6863 void
6864 aof_dump_imports (f)
6865      FILE * f;
6866 {
6867   /* The AOF assembler needs this to cause the startup code to be extracted
6868      from the library.  Brining in __main causes the whole thing to work
6869      automagically.  */
6870   if (arm_main_function)
6871     {
6872       text_section ();
6873       fputs ("\tIMPORT __main\n", f);
6874       fputs ("\tDCD __main\n", f);
6875     }
6876
6877   /* Now dump the remaining imports.  */
6878   while (imports_list)
6879     {
6880       fprintf (f, "\tIMPORT\t");
6881       assemble_name (f, imports_list->name);
6882       fputc ('\n', f);
6883       imports_list = imports_list->next;
6884     }
6885 }
6886 #endif /* AOF_ASSEMBLER */