OSDN Git Service

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