OSDN Git Service

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