OSDN Git Service

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