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