OSDN Git Service

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