OSDN Git Service

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