OSDN Git Service

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