OSDN Git Service

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