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