]> gcc.gnu.org Git - gcc.git/blame - gcc/config/arm/arm.c
function.c (assing_parms): Fix typo in last change.
[gcc.git] / gcc / config / arm / arm.c
CommitLineData
b36ba79f 1/* Output routines for GCC for ARM.
b0888988 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
2398fb2a 3 Free Software Foundation, Inc.
cce8749e 4 Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
956d6950 5 and Martin Simmons (@harleqn.co.uk).
b36ba79f 6 More major hacks by Richard Earnshaw (rearnsha@arm.com).
cce8749e
CH
7
8This file is part of GNU CC.
9
10GNU CC is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
15GNU CC is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with GNU CC; see the file COPYING. If not, write to
8fb289e7
RK
22the Free Software Foundation, 59 Temple Place - Suite 330,
23Boston, MA 02111-1307, USA. */
ff9940b0 24
56636818 25#include "config.h"
43cffd11 26#include "system.h"
cce8749e 27#include "rtl.h"
d5b7b3ae 28#include "tree.h"
c7319d87 29#include "obstack.h"
cce8749e
CH
30#include "regs.h"
31#include "hard-reg-set.h"
32#include "real.h"
33#include "insn-config.h"
34#include "conditions.h"
cce8749e
CH
35#include "output.h"
36#include "insn-attr.h"
37#include "flags.h"
af48348a 38#include "reload.h"
49ad7cfa 39#include "function.h"
bee06f3d 40#include "expr.h"
e78d8e51 41#include "optabs.h"
ad076f4e 42#include "toplev.h"
aec3cfba 43#include "recog.h"
92a432f4 44#include "ggc.h"
d5b7b3ae 45#include "except.h"
8b97c5f8 46#include "c-pragma.h"
7b8b8ade 47#include "integrate.h"
c27ba912 48#include "tm_p.h"
672a6f42
NB
49#include "target.h"
50#include "target-def.h"
cce8749e 51
d5b7b3ae
RE
52/* Forward definitions of types. */
53typedef struct minipool_node Mnode;
54typedef struct minipool_fixup Mfix;
55
56/* In order to improve the layout of the prototypes below
57 some short type abbreviations are defined here. */
58#define Hint HOST_WIDE_INT
59#define Mmode enum machine_mode
60#define Ulong unsigned long
6d3d9133 61#define Ccstar const char *
d5b7b3ae
RE
62
63/* Forward function declarations. */
64static void arm_add_gc_roots PARAMS ((void));
65static int arm_gen_constant PARAMS ((enum rtx_code, Mmode, Hint, rtx, rtx, int, int));
d5b7b3ae
RE
66static Ulong bit_count PARAMS ((signed int));
67static int const_ok_for_op PARAMS ((Hint, enum rtx_code));
68static int eliminate_lr2ip PARAMS ((rtx *));
69static rtx emit_multi_reg_push PARAMS ((int));
70static rtx emit_sfm PARAMS ((int, int));
6d3d9133 71static Ccstar fp_const_from_val PARAMS ((REAL_VALUE_TYPE *));
d5b7b3ae
RE
72static arm_cc get_arm_condition_code PARAMS ((rtx));
73static void init_fpa_table PARAMS ((void));
74static Hint int_log2 PARAMS ((Hint));
75static rtx is_jump_table PARAMS ((rtx));
6d3d9133
NC
76static Ccstar output_multi_immediate PARAMS ((rtx *, Ccstar, Ccstar, int, Hint));
77static void print_multi_reg PARAMS ((FILE *, Ccstar, int, int));
d5b7b3ae 78static Mmode select_dominance_cc_mode PARAMS ((rtx, rtx, Hint));
6d3d9133 79static Ccstar shift_op PARAMS ((rtx, Hint *));
d5b7b3ae
RE
80static void arm_init_machine_status PARAMS ((struct function *));
81static void arm_mark_machine_status PARAMS ((struct function *));
f7a80099 82static void arm_free_machine_status PARAMS ((struct function *));
d5b7b3ae
RE
83static int number_of_first_bit_set PARAMS ((int));
84static void replace_symbols_in_block PARAMS ((tree, rtx, rtx));
85static void thumb_exit PARAMS ((FILE *, int, rtx));
86static void thumb_pushpop PARAMS ((FILE *, int, int));
6d3d9133 87static Ccstar thumb_condition_code PARAMS ((rtx, int));
d5b7b3ae
RE
88static rtx is_jump_table PARAMS ((rtx));
89static Hint get_jump_table_size PARAMS ((rtx));
90static Mnode * move_minipool_fix_forward_ref PARAMS ((Mnode *, Mnode *, Hint));
91static Mnode * add_minipool_forward_ref PARAMS ((Mfix *));
92static Mnode * move_minipool_fix_backward_ref PARAMS ((Mnode *, Mnode *, Hint));
93static Mnode * add_minipool_backward_ref PARAMS ((Mfix *));
94static void assign_minipool_offsets PARAMS ((Mfix *));
95static void arm_print_value PARAMS ((FILE *, rtx));
96static void dump_minipool PARAMS ((rtx));
97static int arm_barrier_cost PARAMS ((rtx));
98static Mfix * create_fix_barrier PARAMS ((Mfix *, Hint));
99static void push_minipool_barrier PARAMS ((rtx, Hint));
100static void push_minipool_fix PARAMS ((rtx, Hint, rtx *, Mmode, rtx));
101static void note_invalid_constants PARAMS ((rtx, Hint));
87e27392 102static int current_file_function_operand PARAMS ((rtx));
6d3d9133
NC
103static Ulong arm_compute_save_reg_mask PARAMS ((void));
104static Ulong arm_isr_value PARAMS ((tree));
105static Ulong arm_compute_func_type PARAMS ((void));
91d231cb
JM
106static tree arm_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
107static tree arm_handle_isr_attribute PARAMS ((tree *, tree, tree, int, bool *));
108const struct attribute_spec arm_attribute_table[];
08c148a8
NB
109static void arm_output_function_epilogue PARAMS ((FILE *,
110 HOST_WIDE_INT));
111static void arm_output_function_prologue PARAMS ((FILE *,
112 HOST_WIDE_INT));
113static void thumb_output_function_prologue PARAMS ((FILE *,
114 HOST_WIDE_INT));
8d8e52be
JM
115static int arm_comp_type_attributes PARAMS ((tree, tree));
116static void arm_set_default_type_attributes PARAMS ((tree));
ebe413e5 117#ifdef OBJECT_FORMAT_ELF
7c262518 118static void arm_elf_asm_named_section PARAMS ((const char *,
7c262518 119 unsigned int));
ebe413e5 120#endif
c237e94a
ZW
121static int arm_adjust_cost PARAMS ((rtx, rtx, rtx, int));
122
d5b7b3ae
RE
123#undef Hint
124#undef Mmode
125#undef Ulong
6d3d9133 126#undef Ccstar
672a6f42
NB
127\f
128/* Initialize the GCC target structure. */
129#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
130#undef TARGET_MERGE_DECL_ATTRIBUTES
131#define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
132#endif
f3bb6135 133
91d231cb
JM
134#undef TARGET_ATTRIBUTE_TABLE
135#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
672a6f42 136
08c148a8
NB
137#undef TARGET_ASM_FUNCTION_PROLOGUE
138#define TARGET_ASM_FUNCTION_PROLOGUE arm_output_function_prologue
139
140#undef TARGET_ASM_FUNCTION_EPILOGUE
141#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
142
8d8e52be
JM
143#undef TARGET_COMP_TYPE_ATTRIBUTES
144#define TARGET_COMP_TYPE_ATTRIBUTES arm_comp_type_attributes
145
146#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
147#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES arm_set_default_type_attributes
148
f6155fda
SS
149#undef TARGET_INIT_BUILTINS
150#define TARGET_INIT_BUILTINS arm_init_builtins
151
152#undef TARGET_EXPAND_BUILTIN
153#define TARGET_EXPAND_BUILTIN arm_expand_builtin
154
c237e94a
ZW
155#undef TARGET_SCHED_ADJUST_COST
156#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
157
f6897b10 158struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 159\f
c7319d87
RE
160/* Obstack for minipool constant handling. */
161static struct obstack minipool_obstack;
162static char *minipool_startobj;
163
164#define obstack_chunk_alloc xmalloc
165#define obstack_chunk_free free
166
c27ba912
DM
167/* The maximum number of insns skipped which will be conditionalised if
168 possible. */
169static int max_insns_skipped = 5;
170
171extern FILE * asm_out_file;
172
6354dc9b 173/* True if we are currently building a constant table. */
13bd191d
PB
174int making_const_table;
175
60d0536b 176/* Define the information needed to generate branch insns. This is
6354dc9b 177 stored from the compare operation. */
ff9940b0 178rtx arm_compare_op0, arm_compare_op1;
ff9940b0 179
6354dc9b 180/* What type of floating point are we tuning for? */
bee06f3d
RE
181enum floating_point_type arm_fpu;
182
6354dc9b 183/* What type of floating point instructions are available? */
b111229a
RE
184enum floating_point_type arm_fpu_arch;
185
6354dc9b 186/* What program mode is the cpu running in? 26-bit mode or 32-bit mode. */
2b835d68
RE
187enum prog_mode_type arm_prgmode;
188
6354dc9b 189/* Set by the -mfp=... option. */
f9cc092a 190const char * target_fp_name = NULL;
2b835d68 191
b355a481 192/* Used to parse -mstructure_size_boundary command line option. */
f9cc092a 193const char * structure_size_string = NULL;
723ae7c1 194int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
b355a481 195
aec3cfba 196/* Bit values used to identify processor capabilities. */
62b10bbc
NC
197#define FL_CO_PROC (1 << 0) /* Has external co-processor bus */
198#define FL_FAST_MULT (1 << 1) /* Fast multiply */
199#define FL_MODE26 (1 << 2) /* 26-bit mode support */
200#define FL_MODE32 (1 << 3) /* 32-bit mode support */
201#define FL_ARCH4 (1 << 4) /* Architecture rel 4 */
202#define FL_ARCH5 (1 << 5) /* Architecture rel 5 */
203#define FL_THUMB (1 << 6) /* Thumb aware */
204#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */
205#define FL_STRONG (1 << 8) /* StrongARM */
b15bca31 206#define FL_ARCH5E (1 << 9) /* DSP extenstions to v5 */
d19fb8e3 207#define FL_XSCALE (1 << 10) /* XScale */
aec3cfba 208
d5b7b3ae
RE
209/* The bits in this mask specify which instructions we are
210 allowed to generate. */
aec3cfba 211static int insn_flags = 0;
d5b7b3ae 212
aec3cfba
NC
213/* The bits in this mask specify which instruction scheduling options should
214 be used. Note - there is an overlap with the FL_FAST_MULT. For some
215 hardware we want to be able to generate the multiply instructions, but to
216 tune as if they were not present in the architecture. */
217static int tune_flags = 0;
218
219/* The following are used in the arm.md file as equivalents to bits
220 in the above two flag variables. */
221
2b835d68
RE
222/* Nonzero if this is an "M" variant of the processor. */
223int arm_fast_multiply = 0;
224
6354dc9b 225/* Nonzero if this chip supports the ARM Architecture 4 extensions. */
2b835d68
RE
226int arm_arch4 = 0;
227
6354dc9b 228/* Nonzero if this chip supports the ARM Architecture 5 extensions. */
62b10bbc
NC
229int arm_arch5 = 0;
230
b15bca31
RE
231/* Nonzero if this chip supports the ARM Architecture 5E extensions. */
232int arm_arch5e = 0;
233
aec3cfba 234/* Nonzero if this chip can benefit from load scheduling. */
f5a1b0d2
NC
235int arm_ld_sched = 0;
236
237/* Nonzero if this chip is a StrongARM. */
238int arm_is_strong = 0;
239
d19fb8e3
NC
240/* Nonzero if this chip is an XScale. */
241int arm_is_xscale = 0;
242
3569057d 243/* Nonzero if this chip is an ARM6 or an ARM7. */
f5a1b0d2 244int arm_is_6_or_7 = 0;
b111229a 245
0616531f
RE
246/* Nonzero if generating Thumb instructions. */
247int thumb_code = 0;
248
cce8749e
CH
249/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
250 must report the mode of the memory reference from PRINT_OPERAND to
251 PRINT_OPERAND_ADDRESS. */
f3bb6135 252enum machine_mode output_memory_reference_mode;
cce8749e
CH
253
254/* Nonzero if the prologue must setup `fp'. */
255int current_function_anonymous_args;
256
32de079a 257/* The register number to be used for the PIC offset register. */
ed0e6530 258const char * arm_pic_register_string = NULL;
32de079a
RE
259int arm_pic_register = 9;
260
ff9940b0 261/* Set to 1 when a return insn is output, this means that the epilogue
6354dc9b 262 is not needed. */
d5b7b3ae 263int return_used_this_function;
ff9940b0 264
aec3cfba
NC
265/* Set to 1 after arm_reorg has started. Reset to start at the start of
266 the next function. */
4b632bf1
RE
267static int after_arm_reorg = 0;
268
aec3cfba 269/* The maximum number of insns to be used when loading a constant. */
2b835d68
RE
270static int arm_constant_limit = 3;
271
cce8749e
CH
272/* For an explanation of these variables, see final_prescan_insn below. */
273int arm_ccfsm_state;
84ed5e79 274enum arm_cond_code arm_current_cc;
cce8749e
CH
275rtx arm_target_insn;
276int arm_target_label;
9997d19d
RE
277
278/* The condition codes of the ARM, and the inverse function. */
83182544 279static const char *const arm_condition_codes[] =
9997d19d
RE
280{
281 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
282 "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
283};
284
f5a1b0d2 285#define streq(string1, string2) (strcmp (string1, string2) == 0)
2b835d68 286\f
6354dc9b 287/* Initialization code. */
2b835d68 288
2b835d68
RE
289struct processors
290{
8b60264b
KG
291 const char *const name;
292 const unsigned int flags;
2b835d68
RE
293};
294
295/* Not all of these give usefully different compilation alternatives,
296 but there is no simple way of generalizing them. */
8b60264b 297static const struct processors all_cores[] =
f5a1b0d2
NC
298{
299 /* ARM Cores */
300
301 {"arm2", FL_CO_PROC | FL_MODE26 },
302 {"arm250", FL_CO_PROC | FL_MODE26 },
303 {"arm3", FL_CO_PROC | FL_MODE26 },
304 {"arm6", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
305 {"arm60", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
306 {"arm600", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
307 {"arm610", FL_MODE26 | FL_MODE32 },
308 {"arm620", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
949d79eb
RE
309 {"arm7", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
310 /* arm7m doesn't exist on its own, but only with D, (and I), but
d5b7b3ae 311 those don't alter the code, so arm7m is sometimes used. */
949d79eb
RE
312 {"arm7m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
313 {"arm7d", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
314 {"arm7dm", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
315 {"arm7di", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
f5a1b0d2
NC
316 {"arm7dmi", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
317 {"arm70", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
318 {"arm700", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
319 {"arm700i", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
320 {"arm710", FL_MODE26 | FL_MODE32 },
eab4abeb 321 {"arm710t", FL_MODE26 | FL_MODE32 | FL_THUMB },
a120a3bd 322 {"arm720", FL_MODE26 | FL_MODE32 },
eab4abeb
NC
323 {"arm720t", FL_MODE26 | FL_MODE32 | FL_THUMB },
324 {"arm740t", FL_MODE26 | FL_MODE32 | FL_THUMB },
f5a1b0d2
NC
325 {"arm710c", FL_MODE26 | FL_MODE32 },
326 {"arm7100", FL_MODE26 | FL_MODE32 },
327 {"arm7500", FL_MODE26 | FL_MODE32 },
949d79eb
RE
328 /* Doesn't have an external co-proc, but does have embedded fpu. */
329 {"arm7500fe", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
f5a1b0d2
NC
330 {"arm7tdmi", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
331 {"arm8", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
332 {"arm810", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
333 {"arm9", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
6cf32035
NC
334 {"arm920", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
335 {"arm920t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
eab4abeb 336 {"arm940t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
f5a1b0d2 337 {"arm9tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
eab4abeb 338 {"arm9e", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
f5a1b0d2
NC
339 {"strongarm", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
340 {"strongarm110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
341 {"strongarm1100", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
eab4abeb
NC
342 {"strongarm1110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
343 {"arm10tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5 },
344 {"arm1020t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5 },
345 {"xscale", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE },
f5a1b0d2
NC
346
347 {NULL, 0}
348};
349
8b60264b 350static const struct processors all_architectures[] =
2b835d68 351{
f5a1b0d2
NC
352 /* ARM Architectures */
353
62b10bbc
NC
354 { "armv2", FL_CO_PROC | FL_MODE26 },
355 { "armv2a", FL_CO_PROC | FL_MODE26 },
356 { "armv3", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
357 { "armv3m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
949d79eb 358 { "armv4", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 },
b111229a
RE
359 /* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
360 implementations that support it, so we will leave it out for now. */
62b10bbc
NC
361 { "armv4t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
362 { "armv5", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
d19fb8e3
NC
363 { "armv5t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
364 { "armv5te", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
62b10bbc 365 { NULL, 0 }
f5a1b0d2
NC
366};
367
368/* This is a magic stucture. The 'string' field is magically filled in
369 with a pointer to the value specified by the user on the command line
370 assuming that the user has specified such a value. */
371
372struct arm_cpu_select arm_select[] =
373{
374 /* string name processors */
375 { NULL, "-mcpu=", all_cores },
376 { NULL, "-march=", all_architectures },
377 { NULL, "-mtune=", all_cores }
2b835d68
RE
378};
379
aec3cfba 380/* Return the number of bits set in value' */
d5b7b3ae 381static unsigned long
aec3cfba
NC
382bit_count (value)
383 signed int value;
384{
d5b7b3ae 385 unsigned long count = 0;
aec3cfba
NC
386
387 while (value)
388 {
5895f793
RE
389 value &= ~(value & -value);
390 ++count;
aec3cfba
NC
391 }
392
393 return count;
394}
395
2b835d68
RE
396/* Fix up any incompatible options that the user has specified.
397 This has now turned into a maze. */
398void
399arm_override_options ()
400{
ed4c4348 401 unsigned i;
f5a1b0d2
NC
402
403 /* Set up the flags based on the cpu/architecture selected by the user. */
b6a1cbae 404 for (i = ARRAY_SIZE (arm_select); i--;)
bd9c7e23 405 {
f5a1b0d2
NC
406 struct arm_cpu_select * ptr = arm_select + i;
407
408 if (ptr->string != NULL && ptr->string[0] != '\0')
bd9c7e23 409 {
13bd191d 410 const struct processors * sel;
bd9c7e23 411
5895f793 412 for (sel = ptr->processors; sel->name != NULL; sel++)
f5a1b0d2 413 if (streq (ptr->string, sel->name))
bd9c7e23 414 {
aec3cfba
NC
415 if (i == 2)
416 tune_flags = sel->flags;
417 else
b111229a 418 {
aec3cfba
NC
419 /* If we have been given an architecture and a processor
420 make sure that they are compatible. We only generate
421 a warning though, and we prefer the CPU over the
6354dc9b 422 architecture. */
aec3cfba 423 if (insn_flags != 0 && (insn_flags ^ sel->flags))
6cf32035 424 warning ("switch -mcpu=%s conflicts with -march= switch",
aec3cfba
NC
425 ptr->string);
426
427 insn_flags = sel->flags;
b111229a 428 }
f5a1b0d2 429
bd9c7e23
RE
430 break;
431 }
432
433 if (sel->name == NULL)
434 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
435 }
436 }
aec3cfba 437
f5a1b0d2 438 /* If the user did not specify a processor, choose one for them. */
aec3cfba 439 if (insn_flags == 0)
f5a1b0d2 440 {
8b60264b 441 const struct processors * sel;
aec3cfba 442 unsigned int sought;
8b60264b 443 static const struct cpu_default
aec3cfba 444 {
8b60264b
KG
445 const int cpu;
446 const char *const name;
aec3cfba
NC
447 }
448 cpu_defaults[] =
449 {
450 { TARGET_CPU_arm2, "arm2" },
451 { TARGET_CPU_arm6, "arm6" },
452 { TARGET_CPU_arm610, "arm610" },
2aa0c933 453 { TARGET_CPU_arm710, "arm710" },
aec3cfba
NC
454 { TARGET_CPU_arm7m, "arm7m" },
455 { TARGET_CPU_arm7500fe, "arm7500fe" },
456 { TARGET_CPU_arm7tdmi, "arm7tdmi" },
457 { TARGET_CPU_arm8, "arm8" },
458 { TARGET_CPU_arm810, "arm810" },
459 { TARGET_CPU_arm9, "arm9" },
460 { TARGET_CPU_strongarm, "strongarm" },
d19fb8e3 461 { TARGET_CPU_xscale, "xscale" },
aec3cfba
NC
462 { TARGET_CPU_generic, "arm" },
463 { 0, 0 }
464 };
8b60264b 465 const struct cpu_default * def;
aec3cfba
NC
466
467 /* Find the default. */
5895f793 468 for (def = cpu_defaults; def->name; def++)
aec3cfba
NC
469 if (def->cpu == TARGET_CPU_DEFAULT)
470 break;
471
472 /* Make sure we found the default CPU. */
473 if (def->name == NULL)
474 abort ();
475
476 /* Find the default CPU's flags. */
5895f793 477 for (sel = all_cores; sel->name != NULL; sel++)
aec3cfba
NC
478 if (streq (def->name, sel->name))
479 break;
480
481 if (sel->name == NULL)
482 abort ();
483
484 insn_flags = sel->flags;
485
486 /* Now check to see if the user has specified some command line
487 switch that require certain abilities from the cpu. */
488 sought = 0;
f5a1b0d2 489
d5b7b3ae 490 if (TARGET_INTERWORK || TARGET_THUMB)
f5a1b0d2 491 {
aec3cfba
NC
492 sought |= (FL_THUMB | FL_MODE32);
493
494 /* Force apcs-32 to be used for interworking. */
f5a1b0d2 495 target_flags |= ARM_FLAG_APCS_32;
aec3cfba 496
d5b7b3ae 497 /* There are no ARM processors that support both APCS-26 and
aec3cfba
NC
498 interworking. Therefore we force FL_MODE26 to be removed
499 from insn_flags here (if it was set), so that the search
500 below will always be able to find a compatible processor. */
5895f793 501 insn_flags &= ~FL_MODE26;
f5a1b0d2 502 }
5895f793 503 else if (!TARGET_APCS_32)
f5a1b0d2 504 sought |= FL_MODE26;
d5b7b3ae 505
aec3cfba 506 if (sought != 0 && ((sought & insn_flags) != sought))
f5a1b0d2 507 {
aec3cfba
NC
508 /* Try to locate a CPU type that supports all of the abilities
509 of the default CPU, plus the extra abilities requested by
510 the user. */
5895f793 511 for (sel = all_cores; sel->name != NULL; sel++)
aec3cfba 512 if ((sel->flags & sought) == (sought | insn_flags))
f5a1b0d2
NC
513 break;
514
515 if (sel->name == NULL)
aec3cfba
NC
516 {
517 unsigned int current_bit_count = 0;
8b60264b 518 const struct processors * best_fit = NULL;
aec3cfba
NC
519
520 /* Ideally we would like to issue an error message here
521 saying that it was not possible to find a CPU compatible
522 with the default CPU, but which also supports the command
523 line options specified by the programmer, and so they
524 ought to use the -mcpu=<name> command line option to
525 override the default CPU type.
526
527 Unfortunately this does not work with multilibing. We
528 need to be able to support multilibs for -mapcs-26 and for
529 -mthumb-interwork and there is no CPU that can support both
530 options. Instead if we cannot find a cpu that has both the
531 characteristics of the default cpu and the given command line
532 options we scan the array again looking for a best match. */
5895f793 533 for (sel = all_cores; sel->name != NULL; sel++)
aec3cfba
NC
534 if ((sel->flags & sought) == sought)
535 {
536 unsigned int count;
537
538 count = bit_count (sel->flags & insn_flags);
539
540 if (count >= current_bit_count)
541 {
542 best_fit = sel;
543 current_bit_count = count;
544 }
545 }
f5a1b0d2 546
aec3cfba
NC
547 if (best_fit == NULL)
548 abort ();
549 else
550 sel = best_fit;
551 }
552
553 insn_flags = sel->flags;
f5a1b0d2
NC
554 }
555 }
aec3cfba
NC
556
557 /* If tuning has not been specified, tune for whichever processor or
558 architecture has been selected. */
559 if (tune_flags == 0)
560 tune_flags = insn_flags;
561
f5a1b0d2
NC
562 /* Make sure that the processor choice does not conflict with any of the
563 other command line choices. */
aec3cfba 564 if (TARGET_APCS_32 && !(insn_flags & FL_MODE32))
f5a1b0d2 565 {
aec3cfba
NC
566 /* If APCS-32 was not the default then it must have been set by the
567 user, so issue a warning message. If the user has specified
568 "-mapcs-32 -mcpu=arm2" then we loose here. */
569 if ((TARGET_DEFAULT & ARM_FLAG_APCS_32) == 0)
570 warning ("target CPU does not support APCS-32" );
5895f793 571 target_flags &= ~ARM_FLAG_APCS_32;
f5a1b0d2 572 }
5895f793 573 else if (!TARGET_APCS_32 && !(insn_flags & FL_MODE26))
f5a1b0d2
NC
574 {
575 warning ("target CPU does not support APCS-26" );
576 target_flags |= ARM_FLAG_APCS_32;
577 }
578
6cfc7210 579 if (TARGET_INTERWORK && !(insn_flags & FL_THUMB))
f5a1b0d2
NC
580 {
581 warning ("target CPU does not support interworking" );
6cfc7210 582 target_flags &= ~ARM_FLAG_INTERWORK;
f5a1b0d2
NC
583 }
584
d5b7b3ae
RE
585 if (TARGET_THUMB && !(insn_flags & FL_THUMB))
586 {
c725bd79 587 warning ("target CPU does not support THUMB instructions");
d5b7b3ae
RE
588 target_flags &= ~ARM_FLAG_THUMB;
589 }
590
591 if (TARGET_APCS_FRAME && TARGET_THUMB)
592 {
c725bd79 593 /* warning ("ignoring -mapcs-frame because -mthumb was used"); */
d5b7b3ae
RE
594 target_flags &= ~ARM_FLAG_APCS_FRAME;
595 }
d19fb8e3 596
d5b7b3ae
RE
597 /* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done
598 from here where no function is being compiled currently. */
599 if ((target_flags & (THUMB_FLAG_LEAF_BACKTRACE | THUMB_FLAG_BACKTRACE))
600 && TARGET_ARM)
c725bd79 601 warning ("enabling backtrace support is only meaningful when compiling for the Thumb");
d5b7b3ae
RE
602
603 if (TARGET_ARM && TARGET_CALLEE_INTERWORKING)
c725bd79 604 warning ("enabling callee interworking support is only meaningful when compiling for the Thumb");
d5b7b3ae
RE
605
606 if (TARGET_ARM && TARGET_CALLER_INTERWORKING)
c725bd79 607 warning ("enabling caller interworking support is only meaningful when compiling for the Thumb");
d5b7b3ae 608
f5a1b0d2 609 /* If interworking is enabled then APCS-32 must be selected as well. */
6cfc7210 610 if (TARGET_INTERWORK)
f5a1b0d2 611 {
5895f793 612 if (!TARGET_APCS_32)
f5a1b0d2
NC
613 warning ("interworking forces APCS-32 to be used" );
614 target_flags |= ARM_FLAG_APCS_32;
615 }
616
5895f793 617 if (TARGET_APCS_STACK && !TARGET_APCS_FRAME)
f5a1b0d2
NC
618 {
619 warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
620 target_flags |= ARM_FLAG_APCS_FRAME;
621 }
aec3cfba 622
2b835d68
RE
623 if (TARGET_POKE_FUNCTION_NAME)
624 target_flags |= ARM_FLAG_APCS_FRAME;
aec3cfba 625
2b835d68 626 if (TARGET_APCS_REENT && flag_pic)
400500c4 627 error ("-fpic and -mapcs-reent are incompatible");
aec3cfba 628
2b835d68 629 if (TARGET_APCS_REENT)
f5a1b0d2 630 warning ("APCS reentrant code not supported. Ignored");
aec3cfba 631
d5b7b3ae
RE
632 /* If this target is normally configured to use APCS frames, warn if they
633 are turned off and debugging is turned on. */
634 if (TARGET_ARM
635 && write_symbols != NO_DEBUG
5895f793 636 && !TARGET_APCS_FRAME
d5b7b3ae
RE
637 && (TARGET_DEFAULT & ARM_FLAG_APCS_FRAME))
638 warning ("-g with -mno-apcs-frame may not give sensible debugging");
6cfc7210 639
32de079a
RE
640 /* If stack checking is disabled, we can use r10 as the PIC register,
641 which keeps r9 available. */
5895f793 642 if (flag_pic && !TARGET_APCS_STACK)
32de079a 643 arm_pic_register = 10;
aec3cfba 644
2b835d68 645 if (TARGET_APCS_FLOAT)
c725bd79 646 warning ("passing floating point arguments in fp regs not yet supported");
f5a1b0d2 647
aec3cfba 648 /* Initialise boolean versions of the flags, for use in the arm.md file. */
2ca12935
JL
649 arm_fast_multiply = (insn_flags & FL_FAST_MULT) != 0;
650 arm_arch4 = (insn_flags & FL_ARCH4) != 0;
651 arm_arch5 = (insn_flags & FL_ARCH5) != 0;
b15bca31 652 arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
a67ded0f 653 arm_is_xscale = (insn_flags & FL_XSCALE) != 0;
6f7ebcbb 654
2ca12935
JL
655 arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
656 arm_is_strong = (tune_flags & FL_STRONG) != 0;
0616531f 657 thumb_code = (TARGET_ARM == 0);
d5b7b3ae
RE
658 arm_is_6_or_7 = (((tune_flags & (FL_MODE26 | FL_MODE32))
659 && !(tune_flags & FL_ARCH4))) != 0;
6f7ebcbb 660
bd9c7e23
RE
661 /* Default value for floating point code... if no co-processor
662 bus, then schedule for emulated floating point. Otherwise,
b111229a
RE
663 assume the user has an FPA.
664 Note: this does not prevent use of floating point instructions,
665 -msoft-float does that. */
aec3cfba 666 arm_fpu = (tune_flags & FL_CO_PROC) ? FP_HARD : FP_SOFT3;
f5a1b0d2 667
b111229a 668 if (target_fp_name)
2b835d68 669 {
f5a1b0d2 670 if (streq (target_fp_name, "2"))
b111229a 671 arm_fpu_arch = FP_SOFT2;
f5a1b0d2
NC
672 else if (streq (target_fp_name, "3"))
673 arm_fpu_arch = FP_SOFT3;
2b835d68 674 else
c725bd79 675 error ("invalid floating point emulation option: -mfpe-%s",
b111229a 676 target_fp_name);
2b835d68 677 }
b111229a
RE
678 else
679 arm_fpu_arch = FP_DEFAULT;
f5a1b0d2
NC
680
681 if (TARGET_FPE && arm_fpu != FP_HARD)
682 arm_fpu = FP_SOFT2;
aec3cfba 683
f5a1b0d2
NC
684 /* For arm2/3 there is no need to do any scheduling if there is only
685 a floating point emulator, or we are doing software floating-point. */
ed0e6530
PB
686 if ((TARGET_SOFT_FLOAT || arm_fpu != FP_HARD)
687 && (tune_flags & FL_MODE32) == 0)
f5a1b0d2 688 flag_schedule_insns = flag_schedule_insns_after_reload = 0;
aec3cfba 689
cd2b33d0 690 arm_prgmode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
b355a481
NC
691
692 if (structure_size_string != NULL)
693 {
694 int size = strtol (structure_size_string, NULL, 0);
695
696 if (size == 8 || size == 32)
697 arm_structure_size_boundary = size;
698 else
c725bd79 699 warning ("structure size boundary can only be set to 8 or 32");
b355a481 700 }
ed0e6530
PB
701
702 if (arm_pic_register_string != NULL)
703 {
704 int pic_register;
705
5895f793 706 if (!flag_pic)
ed0e6530
PB
707 warning ("-mpic-register= is useless without -fpic");
708
709 pic_register = decode_reg_name (arm_pic_register_string);
710
711 /* Prevent the user from choosing an obviously stupid PIC register. */
712 if (pic_register < 0 || call_used_regs[pic_register]
713 || pic_register == HARD_FRAME_POINTER_REGNUM
714 || pic_register == STACK_POINTER_REGNUM
715 || pic_register >= PC_REGNUM)
c725bd79 716 error ("unable to use '%s' for PIC register", arm_pic_register_string);
ed0e6530
PB
717 else
718 arm_pic_register = pic_register;
719 }
d5b7b3ae
RE
720
721 if (TARGET_THUMB && flag_schedule_insns)
722 {
723 /* Don't warn since it's on by default in -O2. */
724 flag_schedule_insns = 0;
725 }
726
f5a1b0d2
NC
727 /* If optimizing for space, don't synthesize constants.
728 For processors with load scheduling, it never costs more than 2 cycles
729 to load a constant, and the load scheduler may well reduce that to 1. */
aec3cfba 730 if (optimize_size || (tune_flags & FL_LDSCHED))
f5a1b0d2 731 arm_constant_limit = 1;
aec3cfba 732
d19fb8e3
NC
733 if (arm_is_xscale)
734 arm_constant_limit = 2;
735
f5a1b0d2
NC
736 /* If optimizing for size, bump the number of instructions that we
737 are prepared to conditionally execute (even on a StrongARM).
738 Otherwise for the StrongARM, which has early execution of branches,
739 a sequence that is worth skipping is shorter. */
740 if (optimize_size)
741 max_insns_skipped = 6;
742 else if (arm_is_strong)
743 max_insns_skipped = 3;
92a432f4
RE
744
745 /* Register global variables with the garbage collector. */
746 arm_add_gc_roots ();
747}
748
749static void
750arm_add_gc_roots ()
751{
752 ggc_add_rtx_root (&arm_compare_op0, 1);
753 ggc_add_rtx_root (&arm_compare_op1, 1);
6d3d9133 754 ggc_add_rtx_root (&arm_target_insn, 1); /* Not sure this is really a root. */
c7319d87
RE
755
756 gcc_obstack_init(&minipool_obstack);
757 minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
2b835d68 758}
cce8749e 759\f
6d3d9133
NC
760/* A table of known ARM exception types.
761 For use with the interrupt function attribute. */
762
763typedef struct
764{
8b60264b
KG
765 const char *const arg;
766 const unsigned long return_value;
6d3d9133
NC
767}
768isr_attribute_arg;
769
8b60264b 770static const isr_attribute_arg isr_attribute_args [] =
6d3d9133
NC
771{
772 { "IRQ", ARM_FT_ISR },
773 { "irq", ARM_FT_ISR },
774 { "FIQ", ARM_FT_FIQ },
775 { "fiq", ARM_FT_FIQ },
776 { "ABORT", ARM_FT_ISR },
777 { "abort", ARM_FT_ISR },
778 { "ABORT", ARM_FT_ISR },
779 { "abort", ARM_FT_ISR },
780 { "UNDEF", ARM_FT_EXCEPTION },
781 { "undef", ARM_FT_EXCEPTION },
782 { "SWI", ARM_FT_EXCEPTION },
783 { "swi", ARM_FT_EXCEPTION },
784 { NULL, ARM_FT_NORMAL }
785};
786
787/* Returns the (interrupt) function type of the current
788 function, or ARM_FT_UNKNOWN if the type cannot be determined. */
789
790static unsigned long
791arm_isr_value (argument)
792 tree argument;
793{
8b60264b 794 const isr_attribute_arg * ptr;
6d3d9133
NC
795 const char * arg;
796
797 /* No argument - default to IRQ. */
798 if (argument == NULL_TREE)
799 return ARM_FT_ISR;
800
801 /* Get the value of the argument. */
802 if (TREE_VALUE (argument) == NULL_TREE
803 || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
804 return ARM_FT_UNKNOWN;
805
806 arg = TREE_STRING_POINTER (TREE_VALUE (argument));
807
808 /* Check it against the list of known arguments. */
809 for (ptr = isr_attribute_args; ptr->arg != NULL; ptr ++)
810 if (strcmp (arg, ptr->arg) == 0)
811 return ptr->return_value;
812
813 /* An unrecognised interrupt type. */
814 return ARM_FT_UNKNOWN;
815}
816
817/* Computes the type of the current function. */
818
819static unsigned long
820arm_compute_func_type ()
821{
822 unsigned long type = ARM_FT_UNKNOWN;
823 tree a;
824 tree attr;
825
826 if (TREE_CODE (current_function_decl) != FUNCTION_DECL)
827 abort ();
828
829 /* Decide if the current function is volatile. Such functions
830 never return, and many memory cycles can be saved by not storing
831 register values that will never be needed again. This optimization
832 was added to speed up context switching in a kernel application. */
833 if (optimize > 0
834 && current_function_nothrow
835 && TREE_THIS_VOLATILE (current_function_decl))
836 type |= ARM_FT_VOLATILE;
837
838 if (current_function_needs_context)
839 type |= ARM_FT_NESTED;
840
91d231cb 841 attr = DECL_ATTRIBUTES (current_function_decl);
6d3d9133
NC
842
843 a = lookup_attribute ("naked", attr);
844 if (a != NULL_TREE)
845 type |= ARM_FT_NAKED;
846
847 if (cfun->machine->eh_epilogue_sp_ofs != NULL_RTX)
848 type |= ARM_FT_EXCEPTION_HANDLER;
849 else
850 {
851 a = lookup_attribute ("isr", attr);
852 if (a == NULL_TREE)
853 a = lookup_attribute ("interrupt", attr);
854
855 if (a == NULL_TREE)
856 type |= TARGET_INTERWORK ? ARM_FT_INTERWORKED : ARM_FT_NORMAL;
857 else
858 type |= arm_isr_value (TREE_VALUE (a));
859 }
860
861 return type;
862}
863
864/* Returns the type of the current function. */
865
866unsigned long
867arm_current_func_type ()
868{
869 if (ARM_FUNC_TYPE (cfun->machine->func_type) == ARM_FT_UNKNOWN)
870 cfun->machine->func_type = arm_compute_func_type ();
871
872 return cfun->machine->func_type;
873}
874\f
6354dc9b 875/* Return 1 if it is possible to return using a single instruction. */
6d3d9133 876
ff9940b0 877int
b36ba79f
RE
878use_return_insn (iscond)
879 int iscond;
ff9940b0
RE
880{
881 int regno;
9b598fa0 882 unsigned int func_type;
ff9940b0 883
d5b7b3ae 884 /* Never use a return instruction before reload has run. */
6d3d9133
NC
885 if (!reload_completed)
886 return 0;
887
9b598fa0
RE
888 func_type = arm_current_func_type ();
889
6d3d9133
NC
890 /* Naked functions, volatile functiond and interrupt
891 functions all need special consideration. */
892 if (func_type & (ARM_FT_INTERRUPT | ARM_FT_VOLATILE | ARM_FT_NAKED))
893 return 0;
894
895 /* As do variadic functions. */
896 if (current_function_pretend_args_size
ff9940b0 897 || current_function_anonymous_args
d5b7b3ae 898 /* Of if the function calls __builtin_eh_return () */
6d3d9133 899 || ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
d5b7b3ae 900 /* Or if there is no frame pointer and there is a stack adjustment. */
56636818 901 || ((get_frame_size () + current_function_outgoing_args_size != 0)
5895f793 902 && !frame_pointer_needed))
ff9940b0
RE
903 return 0;
904
b111229a 905 /* Can't be done if interworking with Thumb, and any registers have been
b36ba79f
RE
906 stacked. Similarly, on StrongARM, conditional returns are expensive
907 if they aren't taken and registers have been stacked. */
f5a1b0d2 908 if (iscond && arm_is_strong && frame_pointer_needed)
b36ba79f 909 return 0;
d5b7b3ae 910
f5a1b0d2 911 if ((iscond && arm_is_strong)
6cfc7210 912 || TARGET_INTERWORK)
6ed30148 913 {
d5b7b3ae 914 for (regno = 0; regno <= LAST_ARM_REGNUM; regno++)
5895f793 915 if (regs_ever_live[regno] && !call_used_regs[regno])
6ed30148
RE
916 return 0;
917
918 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
b111229a 919 return 0;
6ed30148 920 }
b111229a 921
6d3d9133
NC
922 /* Can't be done if any of the FPU regs are pushed,
923 since this also requires an insn. */
d5b7b3ae
RE
924 if (TARGET_HARD_FLOAT)
925 for (regno = FIRST_ARM_FP_REGNUM; regno <= LAST_ARM_FP_REGNUM; regno++)
5895f793 926 if (regs_ever_live[regno] && !call_used_regs[regno])
d5b7b3ae 927 return 0;
ff9940b0
RE
928
929 return 1;
930}
931
cce8749e
CH
932/* Return TRUE if int I is a valid immediate ARM constant. */
933
934int
935const_ok_for_arm (i)
ff9940b0 936 HOST_WIDE_INT i;
cce8749e 937{
30cf4896 938 unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT)0xFF;
cce8749e 939
56636818
JL
940 /* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must
941 be all zero, or all one. */
30cf4896
KG
942 if ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0
943 && ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff)
944 != ((~(unsigned HOST_WIDE_INT) 0)
945 & ~(unsigned HOST_WIDE_INT) 0xffffffff)))
56636818
JL
946 return FALSE;
947
e2c671ba
RE
948 /* Fast return for 0 and powers of 2 */
949 if ((i & (i - 1)) == 0)
950 return TRUE;
951
cce8749e
CH
952 do
953 {
30cf4896 954 if ((i & mask & (unsigned HOST_WIDE_INT) 0xffffffff) == 0)
f3bb6135 955 return TRUE;
abaa26e5 956 mask =
30cf4896
KG
957 (mask << 2) | ((mask & (unsigned HOST_WIDE_INT) 0xffffffff)
958 >> (32 - 2)) | ~(unsigned HOST_WIDE_INT) 0xffffffff;
ebe413e5
NC
959 }
960 while (mask != ~(unsigned HOST_WIDE_INT) 0xFF);
cce8749e 961
f3bb6135
RE
962 return FALSE;
963}
cce8749e 964
6354dc9b 965/* Return true if I is a valid constant for the operation CODE. */
74bbc178
NC
966static int
967const_ok_for_op (i, code)
e2c671ba
RE
968 HOST_WIDE_INT i;
969 enum rtx_code code;
e2c671ba
RE
970{
971 if (const_ok_for_arm (i))
972 return 1;
973
974 switch (code)
975 {
976 case PLUS:
977 return const_ok_for_arm (ARM_SIGN_EXTEND (-i));
978
979 case MINUS: /* Should only occur with (MINUS I reg) => rsb */
980 case XOR:
981 case IOR:
982 return 0;
983
984 case AND:
985 return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
986
987 default:
988 abort ();
989 }
990}
991
992/* Emit a sequence of insns to handle a large constant.
993 CODE is the code of the operation required, it can be any of SET, PLUS,
994 IOR, AND, XOR, MINUS;
995 MODE is the mode in which the operation is being performed;
996 VAL is the integer to operate on;
997 SOURCE is the other operand (a register, or a null-pointer for SET);
998 SUBTARGETS means it is safe to create scratch registers if that will
2b835d68
RE
999 either produce a simpler sequence, or we will want to cse the values.
1000 Return value is the number of insns emitted. */
e2c671ba
RE
1001
1002int
1003arm_split_constant (code, mode, val, target, source, subtargets)
1004 enum rtx_code code;
1005 enum machine_mode mode;
1006 HOST_WIDE_INT val;
1007 rtx target;
1008 rtx source;
1009 int subtargets;
2b835d68
RE
1010{
1011 if (subtargets || code == SET
1012 || (GET_CODE (target) == REG && GET_CODE (source) == REG
1013 && REGNO (target) != REGNO (source)))
1014 {
4b632bf1
RE
1015 /* After arm_reorg has been called, we can't fix up expensive
1016 constants by pushing them into memory so we must synthesise
1017 them in-line, regardless of the cost. This is only likely to
1018 be more costly on chips that have load delay slots and we are
1019 compiling without running the scheduler (so no splitting
aec3cfba
NC
1020 occurred before the final instruction emission).
1021
1022 Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
aec3cfba 1023 */
5895f793 1024 if (!after_arm_reorg
4b632bf1
RE
1025 && (arm_gen_constant (code, mode, val, target, source, 1, 0)
1026 > arm_constant_limit + (code != SET)))
2b835d68
RE
1027 {
1028 if (code == SET)
1029 {
1030 /* Currently SET is the only monadic value for CODE, all
1031 the rest are diadic. */
43cffd11 1032 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (val)));
2b835d68
RE
1033 return 1;
1034 }
1035 else
1036 {
1037 rtx temp = subtargets ? gen_reg_rtx (mode) : target;
1038
43cffd11 1039 emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (val)));
2b835d68
RE
1040 /* For MINUS, the value is subtracted from, since we never
1041 have subtraction of a constant. */
1042 if (code == MINUS)
43cffd11 1043 emit_insn (gen_rtx_SET (VOIDmode, target,
d5b7b3ae 1044 gen_rtx_MINUS (mode, temp, source)));
2b835d68 1045 else
43cffd11
RE
1046 emit_insn (gen_rtx_SET (VOIDmode, target,
1047 gen_rtx (code, mode, source, temp)));
2b835d68
RE
1048 return 2;
1049 }
1050 }
1051 }
1052
1053 return arm_gen_constant (code, mode, val, target, source, subtargets, 1);
1054}
1055
ceebdb09
PB
1056static int
1057count_insns_for_constant (HOST_WIDE_INT remainder, int i)
1058{
1059 HOST_WIDE_INT temp1;
1060 int num_insns = 0;
1061 do
1062 {
1063 int end;
1064
1065 if (i <= 0)
1066 i += 32;
1067 if (remainder & (3 << (i - 2)))
1068 {
1069 end = i - 8;
1070 if (end < 0)
1071 end += 32;
1072 temp1 = remainder & ((0x0ff << end)
1073 | ((i < end) ? (0xff >> (32 - end)) : 0));
1074 remainder &= ~temp1;
1075 num_insns++;
1076 i -= 6;
1077 }
1078 i -= 2;
1079 } while (remainder);
1080 return num_insns;
1081}
1082
2b835d68
RE
1083/* As above, but extra parameter GENERATE which, if clear, suppresses
1084 RTL generation. */
d5b7b3ae 1085static int
2b835d68
RE
1086arm_gen_constant (code, mode, val, target, source, subtargets, generate)
1087 enum rtx_code code;
1088 enum machine_mode mode;
1089 HOST_WIDE_INT val;
1090 rtx target;
1091 rtx source;
1092 int subtargets;
1093 int generate;
e2c671ba 1094{
e2c671ba
RE
1095 int can_invert = 0;
1096 int can_negate = 0;
1097 int can_negate_initial = 0;
1098 int can_shift = 0;
1099 int i;
1100 int num_bits_set = 0;
1101 int set_sign_bit_copies = 0;
1102 int clear_sign_bit_copies = 0;
1103 int clear_zero_bit_copies = 0;
1104 int set_zero_bit_copies = 0;
1105 int insns = 0;
e2c671ba 1106 unsigned HOST_WIDE_INT temp1, temp2;
30cf4896 1107 unsigned HOST_WIDE_INT remainder = val & 0xffffffff;
e2c671ba 1108
d5b7b3ae 1109 /* Find out which operations are safe for a given CODE. Also do a quick
e2c671ba
RE
1110 check for degenerate cases; these can occur when DImode operations
1111 are split. */
1112 switch (code)
1113 {
1114 case SET:
1115 can_invert = 1;
1116 can_shift = 1;
1117 can_negate = 1;
1118 break;
1119
1120 case PLUS:
1121 can_negate = 1;
1122 can_negate_initial = 1;
1123 break;
1124
1125 case IOR:
30cf4896 1126 if (remainder == 0xffffffff)
e2c671ba 1127 {
2b835d68 1128 if (generate)
43cffd11
RE
1129 emit_insn (gen_rtx_SET (VOIDmode, target,
1130 GEN_INT (ARM_SIGN_EXTEND (val))));
e2c671ba
RE
1131 return 1;
1132 }
1133 if (remainder == 0)
1134 {
1135 if (reload_completed && rtx_equal_p (target, source))
1136 return 0;
2b835d68 1137 if (generate)
43cffd11 1138 emit_insn (gen_rtx_SET (VOIDmode, target, source));
e2c671ba
RE
1139 return 1;
1140 }
1141 break;
1142
1143 case AND:
1144 if (remainder == 0)
1145 {
2b835d68 1146 if (generate)
43cffd11 1147 emit_insn (gen_rtx_SET (VOIDmode, target, const0_rtx));
e2c671ba
RE
1148 return 1;
1149 }
30cf4896 1150 if (remainder == 0xffffffff)
e2c671ba
RE
1151 {
1152 if (reload_completed && rtx_equal_p (target, source))
1153 return 0;
2b835d68 1154 if (generate)
43cffd11 1155 emit_insn (gen_rtx_SET (VOIDmode, target, source));
e2c671ba
RE
1156 return 1;
1157 }
1158 can_invert = 1;
1159 break;
1160
1161 case XOR:
1162 if (remainder == 0)
1163 {
1164 if (reload_completed && rtx_equal_p (target, source))
1165 return 0;
2b835d68 1166 if (generate)
43cffd11 1167 emit_insn (gen_rtx_SET (VOIDmode, target, source));
e2c671ba
RE
1168 return 1;
1169 }
30cf4896 1170 if (remainder == 0xffffffff)
e2c671ba 1171 {
2b835d68 1172 if (generate)
43cffd11
RE
1173 emit_insn (gen_rtx_SET (VOIDmode, target,
1174 gen_rtx_NOT (mode, source)));
e2c671ba
RE
1175 return 1;
1176 }
1177
1178 /* We don't know how to handle this yet below. */
1179 abort ();
1180
1181 case MINUS:
1182 /* We treat MINUS as (val - source), since (source - val) is always
1183 passed as (source + (-val)). */
1184 if (remainder == 0)
1185 {
2b835d68 1186 if (generate)
43cffd11
RE
1187 emit_insn (gen_rtx_SET (VOIDmode, target,
1188 gen_rtx_NEG (mode, source)));
e2c671ba
RE
1189 return 1;
1190 }
1191 if (const_ok_for_arm (val))
1192 {
2b835d68 1193 if (generate)
43cffd11
RE
1194 emit_insn (gen_rtx_SET (VOIDmode, target,
1195 gen_rtx_MINUS (mode, GEN_INT (val),
1196 source)));
e2c671ba
RE
1197 return 1;
1198 }
1199 can_negate = 1;
1200
1201 break;
1202
1203 default:
1204 abort ();
1205 }
1206
6354dc9b 1207 /* If we can do it in one insn get out quickly. */
e2c671ba
RE
1208 if (const_ok_for_arm (val)
1209 || (can_negate_initial && const_ok_for_arm (-val))
1210 || (can_invert && const_ok_for_arm (~val)))
1211 {
2b835d68 1212 if (generate)
43cffd11
RE
1213 emit_insn (gen_rtx_SET (VOIDmode, target,
1214 (source ? gen_rtx (code, mode, source,
1215 GEN_INT (val))
1216 : GEN_INT (val))));
e2c671ba
RE
1217 return 1;
1218 }
1219
e2c671ba 1220 /* Calculate a few attributes that may be useful for specific
6354dc9b 1221 optimizations. */
e2c671ba
RE
1222 for (i = 31; i >= 0; i--)
1223 {
1224 if ((remainder & (1 << i)) == 0)
1225 clear_sign_bit_copies++;
1226 else
1227 break;
1228 }
1229
1230 for (i = 31; i >= 0; i--)
1231 {
1232 if ((remainder & (1 << i)) != 0)
1233 set_sign_bit_copies++;
1234 else
1235 break;
1236 }
1237
1238 for (i = 0; i <= 31; i++)
1239 {
1240 if ((remainder & (1 << i)) == 0)
1241 clear_zero_bit_copies++;
1242 else
1243 break;
1244 }
1245
1246 for (i = 0; i <= 31; i++)
1247 {
1248 if ((remainder & (1 << i)) != 0)
1249 set_zero_bit_copies++;
1250 else
1251 break;
1252 }
1253
1254 switch (code)
1255 {
1256 case SET:
1257 /* See if we can do this by sign_extending a constant that is known
1258 to be negative. This is a good, way of doing it, since the shift
1259 may well merge into a subsequent insn. */
1260 if (set_sign_bit_copies > 1)
1261 {
1262 if (const_ok_for_arm
1263 (temp1 = ARM_SIGN_EXTEND (remainder
1264 << (set_sign_bit_copies - 1))))
1265 {
2b835d68
RE
1266 if (generate)
1267 {
d499463f 1268 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
43cffd11
RE
1269 emit_insn (gen_rtx_SET (VOIDmode, new_src,
1270 GEN_INT (temp1)));
2b835d68
RE
1271 emit_insn (gen_ashrsi3 (target, new_src,
1272 GEN_INT (set_sign_bit_copies - 1)));
1273 }
e2c671ba
RE
1274 return 2;
1275 }
1276 /* For an inverted constant, we will need to set the low bits,
1277 these will be shifted out of harm's way. */
1278 temp1 |= (1 << (set_sign_bit_copies - 1)) - 1;
1279 if (const_ok_for_arm (~temp1))
1280 {
2b835d68
RE
1281 if (generate)
1282 {
d499463f 1283 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
43cffd11
RE
1284 emit_insn (gen_rtx_SET (VOIDmode, new_src,
1285 GEN_INT (temp1)));
2b835d68
RE
1286 emit_insn (gen_ashrsi3 (target, new_src,
1287 GEN_INT (set_sign_bit_copies - 1)));
1288 }
e2c671ba
RE
1289 return 2;
1290 }
1291 }
1292
1293 /* See if we can generate this by setting the bottom (or the top)
1294 16 bits, and then shifting these into the other half of the
1295 word. We only look for the simplest cases, to do more would cost
1296 too much. Be careful, however, not to generate this when the
1297 alternative would take fewer insns. */
30cf4896 1298 if (val & 0xffff0000)
e2c671ba 1299 {
30cf4896 1300 temp1 = remainder & 0xffff0000;
e2c671ba
RE
1301 temp2 = remainder & 0x0000ffff;
1302
6354dc9b 1303 /* Overlaps outside this range are best done using other methods. */
e2c671ba
RE
1304 for (i = 9; i < 24; i++)
1305 {
30cf4896 1306 if ((((temp2 | (temp2 << i)) & 0xffffffff) == remainder)
5895f793 1307 && !const_ok_for_arm (temp2))
e2c671ba 1308 {
d499463f
RE
1309 rtx new_src = (subtargets
1310 ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
1311 : target);
1312 insns = arm_gen_constant (code, mode, temp2, new_src,
2b835d68 1313 source, subtargets, generate);
e2c671ba 1314 source = new_src;
2b835d68 1315 if (generate)
43cffd11
RE
1316 emit_insn (gen_rtx_SET
1317 (VOIDmode, target,
1318 gen_rtx_IOR (mode,
1319 gen_rtx_ASHIFT (mode, source,
1320 GEN_INT (i)),
1321 source)));
e2c671ba
RE
1322 return insns + 1;
1323 }
1324 }
1325
6354dc9b 1326 /* Don't duplicate cases already considered. */
e2c671ba
RE
1327 for (i = 17; i < 24; i++)
1328 {
1329 if (((temp1 | (temp1 >> i)) == remainder)
5895f793 1330 && !const_ok_for_arm (temp1))
e2c671ba 1331 {
d499463f
RE
1332 rtx new_src = (subtargets
1333 ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
1334 : target);
1335 insns = arm_gen_constant (code, mode, temp1, new_src,
2b835d68 1336 source, subtargets, generate);
e2c671ba 1337 source = new_src;
2b835d68 1338 if (generate)
43cffd11
RE
1339 emit_insn
1340 (gen_rtx_SET (VOIDmode, target,
1341 gen_rtx_IOR
1342 (mode,
1343 gen_rtx_LSHIFTRT (mode, source,
1344 GEN_INT (i)),
1345 source)));
e2c671ba
RE
1346 return insns + 1;
1347 }
1348 }
1349 }
1350 break;
1351
1352 case IOR:
1353 case XOR:
7b64da89
RE
1354 /* If we have IOR or XOR, and the constant can be loaded in a
1355 single instruction, and we can find a temporary to put it in,
e2c671ba
RE
1356 then this can be done in two instructions instead of 3-4. */
1357 if (subtargets
d499463f 1358 /* TARGET can't be NULL if SUBTARGETS is 0 */
5895f793 1359 || (reload_completed && !reg_mentioned_p (target, source)))
e2c671ba 1360 {
5895f793 1361 if (const_ok_for_arm (ARM_SIGN_EXTEND (~val)))
e2c671ba 1362 {
2b835d68
RE
1363 if (generate)
1364 {
1365 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
e2c671ba 1366
43cffd11
RE
1367 emit_insn (gen_rtx_SET (VOIDmode, sub, GEN_INT (val)));
1368 emit_insn (gen_rtx_SET (VOIDmode, target,
1369 gen_rtx (code, mode, source, sub)));
2b835d68 1370 }
e2c671ba
RE
1371 return 2;
1372 }
1373 }
1374
1375 if (code == XOR)
1376 break;
1377
1378 if (set_sign_bit_copies > 8
1379 && (val & (-1 << (32 - set_sign_bit_copies))) == val)
1380 {
2b835d68
RE
1381 if (generate)
1382 {
1383 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
1384 rtx shift = GEN_INT (set_sign_bit_copies);
1385
43cffd11
RE
1386 emit_insn (gen_rtx_SET (VOIDmode, sub,
1387 gen_rtx_NOT (mode,
1388 gen_rtx_ASHIFT (mode,
1389 source,
f5a1b0d2 1390 shift))));
43cffd11
RE
1391 emit_insn (gen_rtx_SET (VOIDmode, target,
1392 gen_rtx_NOT (mode,
1393 gen_rtx_LSHIFTRT (mode, sub,
1394 shift))));
2b835d68 1395 }
e2c671ba
RE
1396 return 2;
1397 }
1398
1399 if (set_zero_bit_copies > 8
1400 && (remainder & ((1 << set_zero_bit_copies) - 1)) == remainder)
1401 {
2b835d68
RE
1402 if (generate)
1403 {
1404 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
1405 rtx shift = GEN_INT (set_zero_bit_copies);
1406
43cffd11
RE
1407 emit_insn (gen_rtx_SET (VOIDmode, sub,
1408 gen_rtx_NOT (mode,
1409 gen_rtx_LSHIFTRT (mode,
1410 source,
f5a1b0d2 1411 shift))));
43cffd11
RE
1412 emit_insn (gen_rtx_SET (VOIDmode, target,
1413 gen_rtx_NOT (mode,
1414 gen_rtx_ASHIFT (mode, sub,
f5a1b0d2 1415 shift))));
2b835d68 1416 }
e2c671ba
RE
1417 return 2;
1418 }
1419
5895f793 1420 if (const_ok_for_arm (temp1 = ARM_SIGN_EXTEND (~val)))
e2c671ba 1421 {
2b835d68
RE
1422 if (generate)
1423 {
1424 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
43cffd11
RE
1425 emit_insn (gen_rtx_SET (VOIDmode, sub,
1426 gen_rtx_NOT (mode, source)));
2b835d68
RE
1427 source = sub;
1428 if (subtargets)
1429 sub = gen_reg_rtx (mode);
43cffd11
RE
1430 emit_insn (gen_rtx_SET (VOIDmode, sub,
1431 gen_rtx_AND (mode, source,
1432 GEN_INT (temp1))));
1433 emit_insn (gen_rtx_SET (VOIDmode, target,
1434 gen_rtx_NOT (mode, sub)));
2b835d68 1435 }
e2c671ba
RE
1436 return 3;
1437 }
1438 break;
1439
1440 case AND:
1441 /* See if two shifts will do 2 or more insn's worth of work. */
1442 if (clear_sign_bit_copies >= 16 && clear_sign_bit_copies < 24)
1443 {
30cf4896 1444 HOST_WIDE_INT shift_mask = ((0xffffffff
e2c671ba 1445 << (32 - clear_sign_bit_copies))
30cf4896 1446 & 0xffffffff);
e2c671ba 1447
30cf4896 1448 if ((remainder | shift_mask) != 0xffffffff)
e2c671ba 1449 {
2b835d68
RE
1450 if (generate)
1451 {
d499463f 1452 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
2b835d68 1453 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
d499463f
RE
1454 new_src, source, subtargets, 1);
1455 source = new_src;
2b835d68
RE
1456 }
1457 else
d499463f
RE
1458 {
1459 rtx targ = subtargets ? NULL_RTX : target;
1460 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
1461 targ, source, subtargets, 0);
1462 }
2b835d68
RE
1463 }
1464
1465 if (generate)
1466 {
d499463f
RE
1467 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1468 rtx shift = GEN_INT (clear_sign_bit_copies);
1469
1470 emit_insn (gen_ashlsi3 (new_src, source, shift));
1471 emit_insn (gen_lshrsi3 (target, new_src, shift));
e2c671ba
RE
1472 }
1473
e2c671ba
RE
1474 return insns + 2;
1475 }
1476
1477 if (clear_zero_bit_copies >= 16 && clear_zero_bit_copies < 24)
1478 {
1479 HOST_WIDE_INT shift_mask = (1 << clear_zero_bit_copies) - 1;
e2c671ba 1480
30cf4896 1481 if ((remainder | shift_mask) != 0xffffffff)
e2c671ba 1482 {
2b835d68
RE
1483 if (generate)
1484 {
d499463f
RE
1485 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1486
2b835d68 1487 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
d499463f
RE
1488 new_src, source, subtargets, 1);
1489 source = new_src;
2b835d68
RE
1490 }
1491 else
d499463f
RE
1492 {
1493 rtx targ = subtargets ? NULL_RTX : target;
1494
1495 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
1496 targ, source, subtargets, 0);
1497 }
2b835d68
RE
1498 }
1499
1500 if (generate)
1501 {
d499463f
RE
1502 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1503 rtx shift = GEN_INT (clear_zero_bit_copies);
1504
1505 emit_insn (gen_lshrsi3 (new_src, source, shift));
1506 emit_insn (gen_ashlsi3 (target, new_src, shift));
e2c671ba
RE
1507 }
1508
e2c671ba
RE
1509 return insns + 2;
1510 }
1511
1512 break;
1513
1514 default:
1515 break;
1516 }
1517
1518 for (i = 0; i < 32; i++)
1519 if (remainder & (1 << i))
1520 num_bits_set++;
1521
1522 if (code == AND || (can_invert && num_bits_set > 16))
30cf4896 1523 remainder = (~remainder) & 0xffffffff;
e2c671ba 1524 else if (code == PLUS && num_bits_set > 16)
30cf4896 1525 remainder = (-remainder) & 0xffffffff;
e2c671ba
RE
1526 else
1527 {
1528 can_invert = 0;
1529 can_negate = 0;
1530 }
1531
1532 /* Now try and find a way of doing the job in either two or three
1533 instructions.
1534 We start by looking for the largest block of zeros that are aligned on
1535 a 2-bit boundary, we then fill up the temps, wrapping around to the
1536 top of the word when we drop off the bottom.
6354dc9b 1537 In the worst case this code should produce no more than four insns. */
e2c671ba
RE
1538 {
1539 int best_start = 0;
1540 int best_consecutive_zeros = 0;
1541
1542 for (i = 0; i < 32; i += 2)
1543 {
1544 int consecutive_zeros = 0;
1545
5895f793 1546 if (!(remainder & (3 << i)))
e2c671ba 1547 {
5895f793 1548 while ((i < 32) && !(remainder & (3 << i)))
e2c671ba
RE
1549 {
1550 consecutive_zeros += 2;
1551 i += 2;
1552 }
1553 if (consecutive_zeros > best_consecutive_zeros)
1554 {
1555 best_consecutive_zeros = consecutive_zeros;
1556 best_start = i - consecutive_zeros;
1557 }
1558 i -= 2;
1559 }
1560 }
1561
ceebdb09
PB
1562 /* So long as it won't require any more insns to do so, it's
1563 desirable to emit a small constant (in bits 0...9) in the last
1564 insn. This way there is more chance that it can be combined with
1565 a later addressing insn to form a pre-indexed load or store
1566 operation. Consider:
1567
1568 *((volatile int *)0xe0000100) = 1;
1569 *((volatile int *)0xe0000110) = 2;
1570
1571 We want this to wind up as:
1572
1573 mov rA, #0xe0000000
1574 mov rB, #1
1575 str rB, [rA, #0x100]
1576 mov rB, #2
1577 str rB, [rA, #0x110]
1578
1579 rather than having to synthesize both large constants from scratch.
1580
1581 Therefore, we calculate how many insns would be required to emit
1582 the constant starting from `best_start', and also starting from
1583 zero (ie with bit 31 first to be output). If `best_start' doesn't
1584 yield a shorter sequence, we may as well use zero. */
1585 if (best_start != 0
1586 && ((((unsigned HOST_WIDE_INT) 1) << best_start) < remainder)
1587 && (count_insns_for_constant (remainder, 0) <=
1588 count_insns_for_constant (remainder, best_start)))
1589 best_start = 0;
1590
1591 /* Now start emitting the insns. */
e2c671ba
RE
1592 i = best_start;
1593 do
1594 {
1595 int end;
1596
1597 if (i <= 0)
1598 i += 32;
1599 if (remainder & (3 << (i - 2)))
1600 {
1601 end = i - 8;
1602 if (end < 0)
1603 end += 32;
1604 temp1 = remainder & ((0x0ff << end)
1605 | ((i < end) ? (0xff >> (32 - end)) : 0));
1606 remainder &= ~temp1;
1607
d499463f 1608 if (generate)
e2c671ba 1609 {
d499463f
RE
1610 rtx new_src;
1611
1612 if (code == SET)
43cffd11
RE
1613 emit_insn (gen_rtx_SET (VOIDmode,
1614 new_src = (subtargets
1615 ? gen_reg_rtx (mode)
1616 : target),
1617 GEN_INT (can_invert
1618 ? ~temp1 : temp1)));
d499463f 1619 else if (code == MINUS)
43cffd11
RE
1620 emit_insn (gen_rtx_SET (VOIDmode,
1621 new_src = (subtargets
1622 ? gen_reg_rtx (mode)
1623 : target),
1624 gen_rtx (code, mode, GEN_INT (temp1),
1625 source)));
d499463f 1626 else
43cffd11
RE
1627 emit_insn (gen_rtx_SET (VOIDmode,
1628 new_src = (remainder
1629 ? (subtargets
1630 ? gen_reg_rtx (mode)
1631 : target)
1632 : target),
1633 gen_rtx (code, mode, source,
1634 GEN_INT (can_invert ? ~temp1
1635 : (can_negate
1636 ? -temp1
1637 : temp1)))));
d499463f 1638 source = new_src;
e2c671ba
RE
1639 }
1640
d499463f
RE
1641 if (code == SET)
1642 {
1643 can_invert = 0;
1644 code = PLUS;
1645 }
1646 else if (code == MINUS)
1647 code = PLUS;
1648
e2c671ba 1649 insns++;
e2c671ba
RE
1650 i -= 6;
1651 }
1652 i -= 2;
1653 } while (remainder);
1654 }
1655 return insns;
1656}
1657
bd9c7e23
RE
1658/* Canonicalize a comparison so that we are more likely to recognize it.
1659 This can be done for a few constant compares, where we can make the
1660 immediate value easier to load. */
1661enum rtx_code
1662arm_canonicalize_comparison (code, op1)
1663 enum rtx_code code;
62b10bbc 1664 rtx * op1;
bd9c7e23 1665{
ad076f4e 1666 unsigned HOST_WIDE_INT i = INTVAL (*op1);
bd9c7e23
RE
1667
1668 switch (code)
1669 {
1670 case EQ:
1671 case NE:
1672 return code;
1673
1674 case GT:
1675 case LE:
30cf4896 1676 if (i != ((((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1)) - 1)
5895f793 1677 && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
bd9c7e23 1678 {
5895f793 1679 *op1 = GEN_INT (i + 1);
bd9c7e23
RE
1680 return code == GT ? GE : LT;
1681 }
1682 break;
1683
1684 case GE:
1685 case LT:
30cf4896 1686 if (i != (((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1))
5895f793 1687 && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
bd9c7e23 1688 {
5895f793 1689 *op1 = GEN_INT (i - 1);
bd9c7e23
RE
1690 return code == GE ? GT : LE;
1691 }
1692 break;
1693
1694 case GTU:
1695 case LEU:
30cf4896 1696 if (i != ~((unsigned HOST_WIDE_INT) 0)
5895f793 1697 && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
bd9c7e23
RE
1698 {
1699 *op1 = GEN_INT (i + 1);
1700 return code == GTU ? GEU : LTU;
1701 }
1702 break;
1703
1704 case GEU:
1705 case LTU:
1706 if (i != 0
5895f793 1707 && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
bd9c7e23
RE
1708 {
1709 *op1 = GEN_INT (i - 1);
1710 return code == GEU ? GTU : LEU;
1711 }
1712 break;
1713
1714 default:
1715 abort ();
1716 }
1717
1718 return code;
1719}
bd9c7e23 1720
f5a1b0d2
NC
1721/* Decide whether a type should be returned in memory (true)
1722 or in a register (false). This is called by the macro
1723 RETURN_IN_MEMORY. */
2b835d68
RE
1724int
1725arm_return_in_memory (type)
1726 tree type;
1727{
5895f793 1728 if (!AGGREGATE_TYPE_P (type))
9e291dbe 1729 /* All simple types are returned in registers. */
d7d01975 1730 return 0;
d5b7b3ae
RE
1731
1732 /* For the arm-wince targets we choose to be compitable with Microsoft's
1733 ARM and Thumb compilers, which always return aggregates in memory. */
1734#ifndef ARM_WINCE
e529bd42
NC
1735 /* All structures/unions bigger than one word are returned in memory.
1736 Also catch the case where int_size_in_bytes returns -1. In this case
1737 the aggregate is either huge or of varaible size, and in either case
1738 we will want to return it via memory and not in a register. */
1739 if (((unsigned int) int_size_in_bytes (type)) > UNITS_PER_WORD)
d7d01975 1740 return 1;
d5b7b3ae 1741
d7d01975 1742 if (TREE_CODE (type) == RECORD_TYPE)
2b835d68
RE
1743 {
1744 tree field;
1745
3a2ea258
RE
1746 /* For a struct the APCS says that we only return in a register
1747 if the type is 'integer like' and every addressable element
1748 has an offset of zero. For practical purposes this means
1749 that the structure can have at most one non bit-field element
1750 and that this element must be the first one in the structure. */
1751
f5a1b0d2
NC
1752 /* Find the first field, ignoring non FIELD_DECL things which will
1753 have been created by C++. */
1754 for (field = TYPE_FIELDS (type);
1755 field && TREE_CODE (field) != FIELD_DECL;
1756 field = TREE_CHAIN (field))
1757 continue;
1758
1759 if (field == NULL)
9e291dbe 1760 return 0; /* An empty structure. Allowed by an extension to ANSI C. */
f5a1b0d2 1761
d5b7b3ae
RE
1762 /* Check that the first field is valid for returning in a register. */
1763
1764 /* ... Floats are not allowed */
9e291dbe 1765 if (FLOAT_TYPE_P (TREE_TYPE (field)))
3a2ea258
RE
1766 return 1;
1767
d5b7b3ae
RE
1768 /* ... Aggregates that are not themselves valid for returning in
1769 a register are not allowed. */
9e291dbe 1770 if (RETURN_IN_MEMORY (TREE_TYPE (field)))
3a2ea258 1771 return 1;
6f7ebcbb 1772
3a2ea258
RE
1773 /* Now check the remaining fields, if any. Only bitfields are allowed,
1774 since they are not addressable. */
f5a1b0d2
NC
1775 for (field = TREE_CHAIN (field);
1776 field;
1777 field = TREE_CHAIN (field))
1778 {
1779 if (TREE_CODE (field) != FIELD_DECL)
1780 continue;
1781
5895f793 1782 if (!DECL_BIT_FIELD_TYPE (field))
f5a1b0d2
NC
1783 return 1;
1784 }
2b835d68
RE
1785
1786 return 0;
1787 }
d7d01975
NC
1788
1789 if (TREE_CODE (type) == UNION_TYPE)
2b835d68
RE
1790 {
1791 tree field;
1792
1793 /* Unions can be returned in registers if every element is
1794 integral, or can be returned in an integer register. */
f5a1b0d2
NC
1795 for (field = TYPE_FIELDS (type);
1796 field;
1797 field = TREE_CHAIN (field))
2b835d68 1798 {
f5a1b0d2
NC
1799 if (TREE_CODE (field) != FIELD_DECL)
1800 continue;
1801
6cc8c0b3
NC
1802 if (FLOAT_TYPE_P (TREE_TYPE (field)))
1803 return 1;
1804
f5a1b0d2 1805 if (RETURN_IN_MEMORY (TREE_TYPE (field)))
2b835d68
RE
1806 return 1;
1807 }
f5a1b0d2 1808
2b835d68
RE
1809 return 0;
1810 }
d5b7b3ae 1811#endif /* not ARM_WINCE */
f5a1b0d2 1812
d5b7b3ae 1813 /* Return all other types in memory. */
2b835d68
RE
1814 return 1;
1815}
1816
82e9d970
PB
1817/* Initialize a variable CUM of type CUMULATIVE_ARGS
1818 for a call to a function whose data type is FNTYPE.
1819 For a library call, FNTYPE is NULL. */
1820void
1821arm_init_cumulative_args (pcum, fntype, libname, indirect)
1822 CUMULATIVE_ARGS * pcum;
1823 tree fntype;
1824 rtx libname ATTRIBUTE_UNUSED;
1825 int indirect ATTRIBUTE_UNUSED;
1826{
1827 /* On the ARM, the offset starts at 0. */
c27ba912
DM
1828 pcum->nregs = ((fntype && aggregate_value_p (TREE_TYPE (fntype))) ? 1 : 0);
1829
82e9d970
PB
1830 pcum->call_cookie = CALL_NORMAL;
1831
1832 if (TARGET_LONG_CALLS)
1833 pcum->call_cookie = CALL_LONG;
1834
1835 /* Check for long call/short call attributes. The attributes
1836 override any command line option. */
1837 if (fntype)
1838 {
1839 if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (fntype)))
1840 pcum->call_cookie = CALL_SHORT;
1841 else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (fntype)))
1842 pcum->call_cookie = CALL_LONG;
1843 }
1844}
1845
1846/* Determine where to put an argument to a function.
1847 Value is zero to push the argument on the stack,
1848 or a hard register in which to store the argument.
1849
1850 MODE is the argument's machine mode.
1851 TYPE is the data type of the argument (as a tree).
1852 This is null for libcalls where that information may
1853 not be available.
1854 CUM is a variable of type CUMULATIVE_ARGS which gives info about
1855 the preceding args and about the function being called.
1856 NAMED is nonzero if this argument is a named parameter
1857 (otherwise it is an extra parameter matching an ellipsis). */
1858rtx
1859arm_function_arg (pcum, mode, type, named)
1860 CUMULATIVE_ARGS * pcum;
1861 enum machine_mode mode;
1862 tree type ATTRIBUTE_UNUSED;
1863 int named;
1864{
1865 if (mode == VOIDmode)
1866 /* Compute operand 2 of the call insn. */
1867 return GEN_INT (pcum->call_cookie);
1868
5895f793 1869 if (!named || pcum->nregs >= NUM_ARG_REGS)
82e9d970
PB
1870 return NULL_RTX;
1871
1872 return gen_rtx_REG (mode, pcum->nregs);
1873}
82e9d970 1874\f
c27ba912
DM
1875/* Encode the current state of the #pragma [no_]long_calls. */
1876typedef enum
82e9d970 1877{
c27ba912
DM
1878 OFF, /* No #pramgma [no_]long_calls is in effect. */
1879 LONG, /* #pragma long_calls is in effect. */
1880 SHORT /* #pragma no_long_calls is in effect. */
1881} arm_pragma_enum;
82e9d970 1882
c27ba912 1883static arm_pragma_enum arm_pragma_long_calls = OFF;
82e9d970 1884
8b97c5f8
ZW
1885void
1886arm_pr_long_calls (pfile)
1887 cpp_reader *pfile ATTRIBUTE_UNUSED;
82e9d970 1888{
8b97c5f8
ZW
1889 arm_pragma_long_calls = LONG;
1890}
1891
1892void
1893arm_pr_no_long_calls (pfile)
1894 cpp_reader *pfile ATTRIBUTE_UNUSED;
1895{
1896 arm_pragma_long_calls = SHORT;
1897}
1898
1899void
1900arm_pr_long_calls_off (pfile)
1901 cpp_reader *pfile ATTRIBUTE_UNUSED;
1902{
1903 arm_pragma_long_calls = OFF;
82e9d970 1904}
8b97c5f8 1905
82e9d970 1906\f
91d231cb
JM
1907/* Table of machine attributes. */
1908const struct attribute_spec arm_attribute_table[] =
82e9d970 1909{
91d231cb 1910 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
82e9d970
PB
1911 /* Function calls made to this symbol must be done indirectly, because
1912 it may lie outside of the 26 bit addressing range of a normal function
1913 call. */
91d231cb 1914 { "long_call", 0, 0, false, true, true, NULL },
82e9d970
PB
1915 /* Whereas these functions are always known to reside within the 26 bit
1916 addressing range. */
91d231cb 1917 { "short_call", 0, 0, false, true, true, NULL },
6d3d9133 1918 /* Interrupt Service Routines have special prologue and epilogue requirements. */
91d231cb
JM
1919 { "isr", 0, 1, false, false, false, arm_handle_isr_attribute },
1920 { "interrupt", 0, 1, false, false, false, arm_handle_isr_attribute },
1921 { "naked", 0, 0, true, false, false, arm_handle_fndecl_attribute },
1922#ifdef ARM_PE
1923 /* ARM/PE has three new attributes:
1924 interfacearm - ?
1925 dllexport - for exporting a function/variable that will live in a dll
1926 dllimport - for importing a function/variable from a dll
1927
1928 Microsoft allows multiple declspecs in one __declspec, separating
1929 them with spaces. We do NOT support this. Instead, use __declspec
1930 multiple times.
1931 */
1932 { "dllimport", 0, 0, true, false, false, NULL },
1933 { "dllexport", 0, 0, true, false, false, NULL },
1934 { "interfacearm", 0, 0, true, false, false, arm_handle_fndecl_attribute },
1935#endif
1936 { NULL, 0, 0, false, false, false, NULL }
1937};
6d3d9133 1938
91d231cb
JM
1939/* Handle an attribute requiring a FUNCTION_DECL;
1940 arguments as in struct attribute_spec.handler. */
1941static tree
1942arm_handle_fndecl_attribute (node, name, args, flags, no_add_attrs)
1943 tree *node;
1944 tree name;
1945 tree args ATTRIBUTE_UNUSED;
1946 int flags ATTRIBUTE_UNUSED;
1947 bool *no_add_attrs;
1948{
1949 if (TREE_CODE (*node) != FUNCTION_DECL)
1950 {
1951 warning ("`%s' attribute only applies to functions",
1952 IDENTIFIER_POINTER (name));
1953 *no_add_attrs = true;
1954 }
1955
1956 return NULL_TREE;
1957}
1958
1959/* Handle an "interrupt" or "isr" attribute;
1960 arguments as in struct attribute_spec.handler. */
1961static tree
1962arm_handle_isr_attribute (node, name, args, flags, no_add_attrs)
1963 tree *node;
1964 tree name;
1965 tree args;
1966 int flags;
1967 bool *no_add_attrs;
1968{
1969 if (DECL_P (*node))
1970 {
1971 if (TREE_CODE (*node) != FUNCTION_DECL)
1972 {
1973 warning ("`%s' attribute only applies to functions",
1974 IDENTIFIER_POINTER (name));
1975 *no_add_attrs = true;
1976 }
1977 /* FIXME: the argument if any is checked for type attributes;
1978 should it be checked for decl ones? */
1979 }
1980 else
1981 {
1982 if (TREE_CODE (*node) == FUNCTION_TYPE
1983 || TREE_CODE (*node) == METHOD_TYPE)
1984 {
1985 if (arm_isr_value (args) == ARM_FT_UNKNOWN)
1986 {
1987 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1988 *no_add_attrs = true;
1989 }
1990 }
1991 else if (TREE_CODE (*node) == POINTER_TYPE
1992 && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
1993 || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
1994 && arm_isr_value (args) != ARM_FT_UNKNOWN)
1995 {
1996 *node = build_type_copy (*node);
1997 TREE_TYPE (*node) = build_type_attribute_variant (TREE_TYPE (*node),
1998 tree_cons (name,
1999 args,
2000 TYPE_ATTRIBUTES (TREE_TYPE (*node))));
2001 *no_add_attrs = true;
2002 }
2003 else
2004 {
2005 /* Possibly pass this attribute on from the type to a decl. */
2006 if (flags & ((int) ATTR_FLAG_DECL_NEXT
2007 | (int) ATTR_FLAG_FUNCTION_NEXT
2008 | (int) ATTR_FLAG_ARRAY_NEXT))
2009 {
2010 *no_add_attrs = true;
2011 return tree_cons (name, args, NULL_TREE);
2012 }
2013 else
2014 {
2015 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
2016 }
2017 }
2018 }
2019
2020 return NULL_TREE;
82e9d970
PB
2021}
2022
2023/* Return 0 if the attributes for two types are incompatible, 1 if they
2024 are compatible, and 2 if they are nearly compatible (which causes a
2025 warning to be generated). */
8d8e52be 2026static int
82e9d970
PB
2027arm_comp_type_attributes (type1, type2)
2028 tree type1;
2029 tree type2;
2030{
1cb8d58a 2031 int l1, l2, s1, s2;
bd7fc26f 2032
82e9d970
PB
2033 /* Check for mismatch of non-default calling convention. */
2034 if (TREE_CODE (type1) != FUNCTION_TYPE)
2035 return 1;
2036
2037 /* Check for mismatched call attributes. */
1cb8d58a
NC
2038 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
2039 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
2040 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
2041 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
bd7fc26f
NC
2042
2043 /* Only bother to check if an attribute is defined. */
2044 if (l1 | l2 | s1 | s2)
2045 {
2046 /* If one type has an attribute, the other must have the same attribute. */
1cb8d58a 2047 if ((l1 != l2) || (s1 != s2))
bd7fc26f 2048 return 0;
82e9d970 2049
bd7fc26f
NC
2050 /* Disallow mixed attributes. */
2051 if ((l1 & s2) || (l2 & s1))
2052 return 0;
2053 }
2054
6d3d9133
NC
2055 /* Check for mismatched ISR attribute. */
2056 l1 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type1)) != NULL;
2057 if (! l1)
2058 l1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type1)) != NULL;
2059 l2 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type2)) != NULL;
2060 if (! l2)
2061 l1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type2)) != NULL;
2062 if (l1 != l2)
2063 return 0;
2064
bd7fc26f 2065 return 1;
82e9d970
PB
2066}
2067
c27ba912
DM
2068/* Encode long_call or short_call attribute by prefixing
2069 symbol name in DECL with a special character FLAG. */
2070void
2071arm_encode_call_attribute (decl, flag)
2072 tree decl;
cd2b33d0 2073 int flag;
c27ba912 2074{
3cce094d 2075 const char * str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
6354dc9b 2076 int len = strlen (str);
d19fb8e3 2077 char * newstr;
c27ba912
DM
2078
2079 if (TREE_CODE (decl) != FUNCTION_DECL)
2080 return;
2081
2082 /* Do not allow weak functions to be treated as short call. */
2083 if (DECL_WEAK (decl) && flag == SHORT_CALL_FLAG_CHAR)
2084 return;
c27ba912 2085
520a57c8
ZW
2086 newstr = alloca (len + 2);
2087 newstr[0] = flag;
2088 strcpy (newstr + 1, str);
c27ba912 2089
6d3d9133 2090 newstr = (char *) ggc_alloc_string (newstr, len + 1);
c27ba912
DM
2091 XSTR (XEXP (DECL_RTL (decl), 0), 0) = newstr;
2092}
2093
2094/* Assigns default attributes to newly defined type. This is used to
2095 set short_call/long_call attributes for function types of
2096 functions defined inside corresponding #pragma scopes. */
8d8e52be 2097static void
c27ba912
DM
2098arm_set_default_type_attributes (type)
2099 tree type;
2100{
2101 /* Add __attribute__ ((long_call)) to all functions, when
2102 inside #pragma long_calls or __attribute__ ((short_call)),
2103 when inside #pragma no_long_calls. */
2104 if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
2105 {
2106 tree type_attr_list, attr_name;
2107 type_attr_list = TYPE_ATTRIBUTES (type);
2108
2109 if (arm_pragma_long_calls == LONG)
2110 attr_name = get_identifier ("long_call");
2111 else if (arm_pragma_long_calls == SHORT)
2112 attr_name = get_identifier ("short_call");
2113 else
2114 return;
2115
2116 type_attr_list = tree_cons (attr_name, NULL_TREE, type_attr_list);
2117 TYPE_ATTRIBUTES (type) = type_attr_list;
2118 }
2119}
2120\f
2121/* Return 1 if the operand is a SYMBOL_REF for a function known to be
2122 defined within the current compilation unit. If this caanot be
2123 determined, then 0 is returned. */
2124static int
2125current_file_function_operand (sym_ref)
2126 rtx sym_ref;
2127{
2128 /* This is a bit of a fib. A function will have a short call flag
2129 applied to its name if it has the short call attribute, or it has
2130 already been defined within the current compilation unit. */
2131 if (ENCODED_SHORT_CALL_ATTR_P (XSTR (sym_ref, 0)))
2132 return 1;
2133
6d77b53e 2134 /* The current function is always defined within the current compilation
c27ba912
DM
2135 unit. if it s a weak defintion however, then this may not be the real
2136 defintion of the function, and so we have to say no. */
2137 if (sym_ref == XEXP (DECL_RTL (current_function_decl), 0)
5895f793 2138 && !DECL_WEAK (current_function_decl))
c27ba912
DM
2139 return 1;
2140
2141 /* We cannot make the determination - default to returning 0. */
2142 return 0;
2143}
2144
2145/* Return non-zero if a 32 bit "long_call" should be generated for
2146 this call. We generate a long_call if the function:
2147
2148 a. has an __attribute__((long call))
2149 or b. is within the scope of a #pragma long_calls
2150 or c. the -mlong-calls command line switch has been specified
2151
2152 However we do not generate a long call if the function:
2153
2154 d. has an __attribute__ ((short_call))
2155 or e. is inside the scope of a #pragma no_long_calls
2156 or f. has an __attribute__ ((section))
2157 or g. is defined within the current compilation unit.
2158
2159 This function will be called by C fragments contained in the machine
2160 description file. CALL_REF and CALL_COOKIE correspond to the matched
2161 rtl operands. CALL_SYMBOL is used to distinguish between
2162 two different callers of the function. It is set to 1 in the
2163 "call_symbol" and "call_symbol_value" patterns and to 0 in the "call"
2164 and "call_value" patterns. This is because of the difference in the
2165 SYM_REFs passed by these patterns. */
2166int
2167arm_is_longcall_p (sym_ref, call_cookie, call_symbol)
2168 rtx sym_ref;
2169 int call_cookie;
2170 int call_symbol;
2171{
5895f793 2172 if (!call_symbol)
c27ba912
DM
2173 {
2174 if (GET_CODE (sym_ref) != MEM)
2175 return 0;
2176
2177 sym_ref = XEXP (sym_ref, 0);
2178 }
2179
2180 if (GET_CODE (sym_ref) != SYMBOL_REF)
2181 return 0;
2182
2183 if (call_cookie & CALL_SHORT)
2184 return 0;
2185
2186 if (TARGET_LONG_CALLS && flag_function_sections)
2187 return 1;
2188
87e27392 2189 if (current_file_function_operand (sym_ref))
c27ba912
DM
2190 return 0;
2191
2192 return (call_cookie & CALL_LONG)
2193 || ENCODED_LONG_CALL_ATTR_P (XSTR (sym_ref, 0))
2194 || TARGET_LONG_CALLS;
2195}
f99fce0c
RE
2196
2197/* Return non-zero if it is ok to make a tail-call to DECL. */
2198int
2199arm_function_ok_for_sibcall (decl)
2200 tree decl;
2201{
2202 int call_type = TARGET_LONG_CALLS ? CALL_LONG : CALL_NORMAL;
2203
2204 /* Never tailcall something for which we have no decl, or if we
2205 are in Thumb mode. */
2206 if (decl == NULL || TARGET_THUMB)
2207 return 0;
2208
2209 /* Get the calling method. */
2210 if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
2211 call_type = CALL_SHORT;
2212 else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
2213 call_type = CALL_LONG;
2214
2215 /* Cannot tail-call to long calls, since these are out of range of
2216 a branch instruction. However, if not compiling PIC, we know
2217 we can reach the symbol if it is in this compilation unit. */
5895f793 2218 if (call_type == CALL_LONG && (flag_pic || !TREE_ASM_WRITTEN (decl)))
f99fce0c
RE
2219 return 0;
2220
2221 /* If we are interworking and the function is not declared static
2222 then we can't tail-call it unless we know that it exists in this
2223 compilation unit (since it might be a Thumb routine). */
5895f793 2224 if (TARGET_INTERWORK && TREE_PUBLIC (decl) && !TREE_ASM_WRITTEN (decl))
f99fce0c
RE
2225 return 0;
2226
6d3d9133
NC
2227 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
2228 if (IS_INTERRUPT (arm_current_func_type ()))
2229 return 0;
2230
f99fce0c
RE
2231 /* Everything else is ok. */
2232 return 1;
2233}
2234
82e9d970 2235\f
32de079a
RE
2236int
2237legitimate_pic_operand_p (x)
2238 rtx x;
2239{
d5b7b3ae
RE
2240 if (CONSTANT_P (x)
2241 && flag_pic
32de079a
RE
2242 && (GET_CODE (x) == SYMBOL_REF
2243 || (GET_CODE (x) == CONST
2244 && GET_CODE (XEXP (x, 0)) == PLUS
2245 && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)))
2246 return 0;
2247
2248 return 1;
2249}
2250
2251rtx
2252legitimize_pic_address (orig, mode, reg)
2253 rtx orig;
2254 enum machine_mode mode;
2255 rtx reg;
2256{
2257 if (GET_CODE (orig) == SYMBOL_REF)
2258 {
5f37d07c 2259#ifndef AOF_ASSEMBLER
32de079a 2260 rtx pic_ref, address;
5f37d07c 2261#endif
32de079a
RE
2262 rtx insn;
2263 int subregs = 0;
2264
2265 if (reg == 0)
2266 {
893f3d5b 2267 if (no_new_pseudos)
32de079a
RE
2268 abort ();
2269 else
2270 reg = gen_reg_rtx (Pmode);
2271
2272 subregs = 1;
2273 }
2274
2275#ifdef AOF_ASSEMBLER
2276 /* The AOF assembler can generate relocations for these directly, and
6354dc9b 2277 understands that the PIC register has to be added into the offset. */
32de079a
RE
2278 insn = emit_insn (gen_pic_load_addr_based (reg, orig));
2279#else
2280 if (subregs)
2281 address = gen_reg_rtx (Pmode);
2282 else
2283 address = reg;
2284
4bec9f7d
NC
2285 if (TARGET_ARM)
2286 emit_insn (gen_pic_load_addr_arm (address, orig));
2287 else
2288 emit_insn (gen_pic_load_addr_thumb (address, orig));
32de079a 2289
43cffd11
RE
2290 pic_ref = gen_rtx_MEM (Pmode,
2291 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
2292 address));
32de079a
RE
2293 RTX_UNCHANGING_P (pic_ref) = 1;
2294 insn = emit_move_insn (reg, pic_ref);
2295#endif
2296 current_function_uses_pic_offset_table = 1;
2297 /* Put a REG_EQUAL note on this insn, so that it can be optimized
2298 by loop. */
43cffd11
RE
2299 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig,
2300 REG_NOTES (insn));
32de079a
RE
2301 return reg;
2302 }
2303 else if (GET_CODE (orig) == CONST)
2304 {
2305 rtx base, offset;
2306
2307 if (GET_CODE (XEXP (orig, 0)) == PLUS
2308 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
2309 return orig;
2310
2311 if (reg == 0)
2312 {
893f3d5b 2313 if (no_new_pseudos)
32de079a
RE
2314 abort ();
2315 else
2316 reg = gen_reg_rtx (Pmode);
2317 }
2318
2319 if (GET_CODE (XEXP (orig, 0)) == PLUS)
2320 {
2321 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
2322 offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
2323 base == reg ? 0 : reg);
2324 }
2325 else
2326 abort ();
2327
2328 if (GET_CODE (offset) == CONST_INT)
2329 {
2330 /* The base register doesn't really matter, we only want to
2331 test the index for the appropriate mode. */
f1008e52 2332 ARM_GO_IF_LEGITIMATE_INDEX (mode, 0, offset, win);
32de079a 2333
5895f793 2334 if (!no_new_pseudos)
32de079a
RE
2335 offset = force_reg (Pmode, offset);
2336 else
2337 abort ();
2338
2339 win:
2340 if (GET_CODE (offset) == CONST_INT)
ed8908e7 2341 return plus_constant (base, INTVAL (offset));
32de079a
RE
2342 }
2343
2344 if (GET_MODE_SIZE (mode) > 4
2345 && (GET_MODE_CLASS (mode) == MODE_INT
2346 || TARGET_SOFT_FLOAT))
2347 {
2348 emit_insn (gen_addsi3 (reg, base, offset));
2349 return reg;
2350 }
2351
43cffd11 2352 return gen_rtx_PLUS (Pmode, base, offset);
32de079a
RE
2353 }
2354 else if (GET_CODE (orig) == LABEL_REF)
82e9d970
PB
2355 {
2356 current_function_uses_pic_offset_table = 1;
2357
2358 if (NEED_GOT_RELOC)
d5b7b3ae
RE
2359 {
2360 rtx pic_ref, address = gen_reg_rtx (Pmode);
4bec9f7d
NC
2361
2362 if (TARGET_ARM)
2363 emit_insn (gen_pic_load_addr_arm (address, orig));
2364 else
2365 emit_insn (gen_pic_load_addr_thumb (address, orig));
d19fb8e3 2366
d5b7b3ae
RE
2367 pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
2368
2369 emit_move_insn (address, pic_ref);
2370 return address;
2371 }
82e9d970 2372 }
32de079a
RE
2373
2374 return orig;
2375}
2376
c1163e75
PB
2377/* Generate code to load the PIC register. PROLOGUE is true if
2378 called from arm_expand_prologue (in which case we want the
2379 generated insns at the start of the function); false if called
2380 by an exception receiver that needs the PIC register reloaded
2381 (in which case the insns are just dumped at the current location). */
eab4abeb 2382
32de079a 2383void
eab4abeb 2384arm_finalize_pic (prologue)
5f37d07c 2385 int prologue ATTRIBUTE_UNUSED;
32de079a
RE
2386{
2387#ifndef AOF_ASSEMBLER
c1163e75 2388 rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx;
32de079a
RE
2389 rtx global_offset_table;
2390
ed0e6530 2391 if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
32de079a
RE
2392 return;
2393
5895f793 2394 if (!flag_pic)
32de079a
RE
2395 abort ();
2396
2397 start_sequence ();
2398 l1 = gen_label_rtx ();
2399
43cffd11 2400 global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
dfa08768 2401 /* On the ARM the PC register contains 'dot + 8' at the time of the
d5b7b3ae
RE
2402 addition, on the Thumb it is 'dot + 4'. */
2403 pic_tmp = plus_constant (gen_rtx_LABEL_REF (Pmode, l1), TARGET_ARM ? 8 : 4);
84306176
PB
2404 if (GOT_PCREL)
2405 pic_tmp2 = gen_rtx_CONST (VOIDmode,
43cffd11 2406 gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
84306176
PB
2407 else
2408 pic_tmp2 = gen_rtx_CONST (VOIDmode, global_offset_table);
43cffd11
RE
2409
2410 pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
f5a1b0d2 2411
d5b7b3ae 2412 if (TARGET_ARM)
4bec9f7d
NC
2413 {
2414 emit_insn (gen_pic_load_addr_arm (pic_offset_table_rtx, pic_rtx));
2415 emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx, l1));
2416 }
d5b7b3ae 2417 else
4bec9f7d
NC
2418 {
2419 emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx));
2420 emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx, l1));
2421 }
32de079a
RE
2422
2423 seq = gen_sequence ();
2424 end_sequence ();
c1163e75
PB
2425 if (prologue)
2426 emit_insn_after (seq, get_insns ());
2427 else
2428 emit_insn (seq);
32de079a
RE
2429
2430 /* Need to emit this whether or not we obey regdecls,
2431 since setjmp/longjmp can cause life info to screw up. */
43cffd11 2432 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
32de079a
RE
2433#endif /* AOF_ASSEMBLER */
2434}
2435
e2c671ba
RE
2436#define REG_OR_SUBREG_REG(X) \
2437 (GET_CODE (X) == REG \
2438 || (GET_CODE (X) == SUBREG && GET_CODE (SUBREG_REG (X)) == REG))
2439
2440#define REG_OR_SUBREG_RTX(X) \
2441 (GET_CODE (X) == REG ? (X) : SUBREG_REG (X))
2442
d5b7b3ae
RE
2443#ifndef COSTS_N_INSNS
2444#define COSTS_N_INSNS(N) ((N) * 4 - 2)
2445#endif
e2c671ba
RE
2446
2447int
d5b7b3ae 2448arm_rtx_costs (x, code, outer)
e2c671ba 2449 rtx x;
74bbc178 2450 enum rtx_code code;
d5b7b3ae 2451 enum rtx_code outer;
e2c671ba
RE
2452{
2453 enum machine_mode mode = GET_MODE (x);
2454 enum rtx_code subcode;
2455 int extra_cost;
2456
d5b7b3ae
RE
2457 if (TARGET_THUMB)
2458 {
2459 switch (code)
2460 {
2461 case ASHIFT:
2462 case ASHIFTRT:
2463 case LSHIFTRT:
2464 case ROTATERT:
2465 case PLUS:
2466 case MINUS:
2467 case COMPARE:
2468 case NEG:
2469 case NOT:
2470 return COSTS_N_INSNS (1);
2471
2472 case MULT:
2473 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2474 {
2475 int cycles = 0;
2476 unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1));
2477
2478 while (i)
2479 {
2480 i >>= 2;
5895f793 2481 cycles++;
d5b7b3ae
RE
2482 }
2483 return COSTS_N_INSNS (2) + cycles;
2484 }
2485 return COSTS_N_INSNS (1) + 16;
2486
2487 case SET:
2488 return (COSTS_N_INSNS (1)
2489 + 4 * ((GET_CODE (SET_SRC (x)) == MEM)
2490 + GET_CODE (SET_DEST (x)) == MEM));
2491
2492 case CONST_INT:
2493 if (outer == SET)
2494 {
2495 if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256)
2496 return 0;
2497 if (thumb_shiftable_const (INTVAL (x)))
2498 return COSTS_N_INSNS (2);
2499 return COSTS_N_INSNS (3);
2500 }
2501 else if (outer == PLUS
2502 && INTVAL (x) < 256 && INTVAL (x) > -256)
2503 return 0;
2504 else if (outer == COMPARE
2505 && (unsigned HOST_WIDE_INT) INTVAL (x) < 256)
2506 return 0;
2507 else if (outer == ASHIFT || outer == ASHIFTRT
2508 || outer == LSHIFTRT)
2509 return 0;
2510 return COSTS_N_INSNS (2);
2511
2512 case CONST:
2513 case CONST_DOUBLE:
2514 case LABEL_REF:
2515 case SYMBOL_REF:
2516 return COSTS_N_INSNS (3);
2517
2518 case UDIV:
2519 case UMOD:
2520 case DIV:
2521 case MOD:
2522 return 100;
2523
2524 case TRUNCATE:
2525 return 99;
2526
2527 case AND:
2528 case XOR:
2529 case IOR:
2530 /* XXX guess. */
2531 return 8;
2532
2533 case ADDRESSOF:
2534 case MEM:
2535 /* XXX another guess. */
2536 /* Memory costs quite a lot for the first word, but subsequent words
2537 load at the equivalent of a single insn each. */
2538 return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
2539 + (CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0));
2540
2541 case IF_THEN_ELSE:
2542 /* XXX a guess. */
2543 if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
2544 return 14;
2545 return 2;
2546
2547 case ZERO_EXTEND:
2548 /* XXX still guessing. */
2549 switch (GET_MODE (XEXP (x, 0)))
2550 {
2551 case QImode:
2552 return (1 + (mode == DImode ? 4 : 0)
2553 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
2554
2555 case HImode:
2556 return (4 + (mode == DImode ? 4 : 0)
2557 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
2558
2559 case SImode:
2560 return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
2561
2562 default:
2563 return 99;
2564 }
2565
2566 default:
2567 return 99;
2568#if 0
2569 case FFS:
2570 case FLOAT:
2571 case FIX:
2572 case UNSIGNED_FIX:
2573 /* XXX guess */
2574 fprintf (stderr, "unexpected code for thumb in rtx_costs: %s\n",
2575 rtx_name[code]);
2576 abort ();
2577#endif
2578 }
2579 }
2580
e2c671ba
RE
2581 switch (code)
2582 {
2583 case MEM:
2584 /* Memory costs quite a lot for the first word, but subsequent words
2585 load at the equivalent of a single insn each. */
2586 return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
2587 + (CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0));
2588
2589 case DIV:
2590 case MOD:
2591 return 100;
2592
2593 case ROTATE:
2594 if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG)
2595 return 4;
2596 /* Fall through */
2597 case ROTATERT:
2598 if (mode != SImode)
2599 return 8;
2600 /* Fall through */
2601 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
2602 if (mode == DImode)
2603 return (8 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : 8)
2604 + ((GET_CODE (XEXP (x, 0)) == REG
2605 || (GET_CODE (XEXP (x, 0)) == SUBREG
2606 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
2607 ? 0 : 8));
2608 return (1 + ((GET_CODE (XEXP (x, 0)) == REG
2609 || (GET_CODE (XEXP (x, 0)) == SUBREG
2610 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
2611 ? 0 : 4)
2612 + ((GET_CODE (XEXP (x, 1)) == REG
2613 || (GET_CODE (XEXP (x, 1)) == SUBREG
2614 && GET_CODE (SUBREG_REG (XEXP (x, 1))) == REG)
2615 || (GET_CODE (XEXP (x, 1)) == CONST_INT))
2616 ? 0 : 4));
2617
2618 case MINUS:
2619 if (mode == DImode)
2620 return (4 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 8)
2621 + ((REG_OR_SUBREG_REG (XEXP (x, 0))
2622 || (GET_CODE (XEXP (x, 0)) == CONST_INT
2623 && const_ok_for_arm (INTVAL (XEXP (x, 0)))))
2624 ? 0 : 8));
2625
2626 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2627 return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
2628 || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
2629 && const_double_rtx_ok_for_fpu (XEXP (x, 1))))
2630 ? 0 : 8)
2631 + ((REG_OR_SUBREG_REG (XEXP (x, 0))
2632 || (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
2633 && const_double_rtx_ok_for_fpu (XEXP (x, 0))))
2634 ? 0 : 8));
2635
2636 if (((GET_CODE (XEXP (x, 0)) == CONST_INT
2637 && const_ok_for_arm (INTVAL (XEXP (x, 0)))
2638 && REG_OR_SUBREG_REG (XEXP (x, 1))))
2639 || (((subcode = GET_CODE (XEXP (x, 1))) == ASHIFT
2640 || subcode == ASHIFTRT || subcode == LSHIFTRT
2641 || subcode == ROTATE || subcode == ROTATERT
2642 || (subcode == MULT
2643 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
2644 && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
2645 (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
2646 && REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 0))
2647 && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 1))
2648 || GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
2649 && REG_OR_SUBREG_REG (XEXP (x, 0))))
2650 return 1;
2651 /* Fall through */
2652
2653 case PLUS:
2654 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2655 return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
2656 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
2657 || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
2658 && const_double_rtx_ok_for_fpu (XEXP (x, 1))))
2659 ? 0 : 8));
2660
2661 /* Fall through */
2662 case AND: case XOR: case IOR:
2663 extra_cost = 0;
2664
2665 /* Normally the frame registers will be spilt into reg+const during
2666 reload, so it is a bad idea to combine them with other instructions,
2667 since then they might not be moved outside of loops. As a compromise
2668 we allow integration with ops that have a constant as their second
2669 operand. */
2670 if ((REG_OR_SUBREG_REG (XEXP (x, 0))
2671 && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))
2672 && GET_CODE (XEXP (x, 1)) != CONST_INT)
2673 || (REG_OR_SUBREG_REG (XEXP (x, 0))
2674 && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))))
2675 extra_cost = 4;
2676
2677 if (mode == DImode)
2678 return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
2679 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
2680 || (GET_CODE (XEXP (x, 1)) == CONST_INT
74bbc178 2681 && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
e2c671ba
RE
2682 ? 0 : 8));
2683
2684 if (REG_OR_SUBREG_REG (XEXP (x, 0)))
2685 return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost)
2686 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
2687 || (GET_CODE (XEXP (x, 1)) == CONST_INT
74bbc178 2688 && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
e2c671ba
RE
2689 ? 0 : 4));
2690
2691 else if (REG_OR_SUBREG_REG (XEXP (x, 1)))
2692 return (1 + extra_cost
2693 + ((((subcode = GET_CODE (XEXP (x, 0))) == ASHIFT
2694 || subcode == LSHIFTRT || subcode == ASHIFTRT
2695 || subcode == ROTATE || subcode == ROTATERT
2696 || (subcode == MULT
2697 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2698 && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
ad076f4e 2699 (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
e2c671ba
RE
2700 && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 0)))
2701 && ((REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 1)))
ad076f4e 2702 || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
e2c671ba
RE
2703 ? 0 : 4));
2704
2705 return 8;
2706
2707 case MULT:
b111229a 2708 /* There is no point basing this on the tuning, since it is always the
6354dc9b 2709 fast variant if it exists at all. */
2b835d68
RE
2710 if (arm_fast_multiply && mode == DImode
2711 && (GET_CODE (XEXP (x, 0)) == GET_CODE (XEXP (x, 1)))
2712 && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
2713 || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
2714 return 8;
2715
e2c671ba
RE
2716 if (GET_MODE_CLASS (mode) == MODE_FLOAT
2717 || mode == DImode)
2718 return 30;
2719
2720 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2721 {
2b835d68 2722 unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
30cf4896 2723 & (unsigned HOST_WIDE_INT) 0xffffffff);
e2c671ba
RE
2724 int add_cost = const_ok_for_arm (i) ? 4 : 8;
2725 int j;
6354dc9b
NC
2726
2727 /* Tune as appropriate. */
aec3cfba 2728 int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
2a5307b1 2729
2b835d68 2730 for (j = 0; i && j < 32; j += booth_unit_size)
e2c671ba 2731 {
2b835d68 2732 i >>= booth_unit_size;
e2c671ba
RE
2733 add_cost += 2;
2734 }
2735
2736 return add_cost;
2737 }
2738
aec3cfba 2739 return (((tune_flags & FL_FAST_MULT) ? 8 : 30)
2b835d68 2740 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
e2c671ba
RE
2741 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4));
2742
56636818
JL
2743 case TRUNCATE:
2744 if (arm_fast_multiply && mode == SImode
2745 && GET_CODE (XEXP (x, 0)) == LSHIFTRT
2746 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
2747 && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
2748 == GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)))
2749 && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
2750 || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND))
2751 return 8;
2752 return 99;
2753
e2c671ba
RE
2754 case NEG:
2755 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2756 return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6);
2757 /* Fall through */
2758 case NOT:
2759 if (mode == DImode)
2760 return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
2761
2762 return 1 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
2763
2764 case IF_THEN_ELSE:
2765 if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
2766 return 14;
2767 return 2;
2768
2769 case COMPARE:
2770 return 1;
2771
2772 case ABS:
2773 return 4 + (mode == DImode ? 4 : 0);
2774
2775 case SIGN_EXTEND:
2776 if (GET_MODE (XEXP (x, 0)) == QImode)
2777 return (4 + (mode == DImode ? 4 : 0)
2778 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
2779 /* Fall through */
2780 case ZERO_EXTEND:
2781 switch (GET_MODE (XEXP (x, 0)))
2782 {
2783 case QImode:
2784 return (1 + (mode == DImode ? 4 : 0)
2785 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
2786
2787 case HImode:
2788 return (4 + (mode == DImode ? 4 : 0)
2789 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
2790
2791 case SImode:
2792 return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
ad076f4e
RE
2793
2794 default:
2795 break;
e2c671ba
RE
2796 }
2797 abort ();
2798
d5b7b3ae
RE
2799 case CONST_INT:
2800 if (const_ok_for_arm (INTVAL (x)))
2801 return outer == SET ? 2 : -1;
2802 else if (outer == AND
5895f793 2803 && const_ok_for_arm (~INTVAL (x)))
d5b7b3ae
RE
2804 return -1;
2805 else if ((outer == COMPARE
2806 || outer == PLUS || outer == MINUS)
5895f793 2807 && const_ok_for_arm (-INTVAL (x)))
d5b7b3ae
RE
2808 return -1;
2809 else
2810 return 5;
2811
2812 case CONST:
2813 case LABEL_REF:
2814 case SYMBOL_REF:
2815 return 6;
2816
2817 case CONST_DOUBLE:
2818 if (const_double_rtx_ok_for_fpu (x))
2819 return outer == SET ? 2 : -1;
2820 else if ((outer == COMPARE || outer == PLUS)
2821 && neg_const_double_rtx_ok_for_fpu (x))
2822 return -1;
2823 return 7;
2824
e2c671ba
RE
2825 default:
2826 return 99;
2827 }
2828}
32de079a 2829
c237e94a 2830static int
32de079a
RE
2831arm_adjust_cost (insn, link, dep, cost)
2832 rtx insn;
2833 rtx link;
2834 rtx dep;
2835 int cost;
2836{
2837 rtx i_pat, d_pat;
2838
d19fb8e3
NC
2839 /* Some true dependencies can have a higher cost depending
2840 on precisely how certain input operands are used. */
2841 if (arm_is_xscale
2842 && REG_NOTE_KIND (link) == 0
2843 && recog_memoized (insn) < 0
2844 && recog_memoized (dep) < 0)
2845 {
2846 int shift_opnum = get_attr_shift (insn);
2847 enum attr_type attr_type = get_attr_type (dep);
2848
2849 /* If nonzero, SHIFT_OPNUM contains the operand number of a shifted
2850 operand for INSN. If we have a shifted input operand and the
2851 instruction we depend on is another ALU instruction, then we may
2852 have to account for an additional stall. */
2853 if (shift_opnum != 0 && attr_type == TYPE_NORMAL)
2854 {
2855 rtx shifted_operand;
2856 int opno;
2857
2858 /* Get the shifted operand. */
2859 extract_insn (insn);
2860 shifted_operand = recog_data.operand[shift_opnum];
2861
2862 /* Iterate over all the operands in DEP. If we write an operand
2863 that overlaps with SHIFTED_OPERAND, then we have increase the
2864 cost of this dependency. */
2865 extract_insn (dep);
2866 preprocess_constraints ();
2867 for (opno = 0; opno < recog_data.n_operands; opno++)
2868 {
2869 /* We can ignore strict inputs. */
2870 if (recog_data.operand_type[opno] == OP_IN)
2871 continue;
2872
2873 if (reg_overlap_mentioned_p (recog_data.operand[opno],
2874 shifted_operand))
2875 return 2;
2876 }
2877 }
2878 }
2879
6354dc9b 2880 /* XXX This is not strictly true for the FPA. */
d5b7b3ae
RE
2881 if (REG_NOTE_KIND (link) == REG_DEP_ANTI
2882 || REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
b36ba79f
RE
2883 return 0;
2884
d5b7b3ae
RE
2885 /* Call insns don't incur a stall, even if they follow a load. */
2886 if (REG_NOTE_KIND (link) == 0
2887 && GET_CODE (insn) == CALL_INSN)
2888 return 1;
2889
32de079a
RE
2890 if ((i_pat = single_set (insn)) != NULL
2891 && GET_CODE (SET_SRC (i_pat)) == MEM
2892 && (d_pat = single_set (dep)) != NULL
2893 && GET_CODE (SET_DEST (d_pat)) == MEM)
2894 {
2895 /* This is a load after a store, there is no conflict if the load reads
2896 from a cached area. Assume that loads from the stack, and from the
2897 constant pool are cached, and that others will miss. This is a
6354dc9b 2898 hack. */
32de079a 2899
32de079a
RE
2900 if (CONSTANT_POOL_ADDRESS_P (XEXP (SET_SRC (i_pat), 0))
2901 || reg_mentioned_p (stack_pointer_rtx, XEXP (SET_SRC (i_pat), 0))
2902 || reg_mentioned_p (frame_pointer_rtx, XEXP (SET_SRC (i_pat), 0))
2903 || reg_mentioned_p (hard_frame_pointer_rtx,
2904 XEXP (SET_SRC (i_pat), 0)))
949d79eb 2905 return 1;
32de079a
RE
2906 }
2907
2908 return cost;
2909}
2910
6354dc9b 2911/* This code has been fixed for cross compilation. */
ff9940b0
RE
2912
2913static int fpa_consts_inited = 0;
2914
27c38fbe 2915static const char *const strings_fpa[8] =
62b10bbc 2916{
2b835d68
RE
2917 "0", "1", "2", "3",
2918 "4", "5", "0.5", "10"
2919};
ff9940b0
RE
2920
2921static REAL_VALUE_TYPE values_fpa[8];
2922
2923static void
2924init_fpa_table ()
2925{
2926 int i;
2927 REAL_VALUE_TYPE r;
2928
2929 for (i = 0; i < 8; i++)
2930 {
2931 r = REAL_VALUE_ATOF (strings_fpa[i], DFmode);
2932 values_fpa[i] = r;
2933 }
f3bb6135 2934
ff9940b0
RE
2935 fpa_consts_inited = 1;
2936}
2937
6354dc9b 2938/* Return TRUE if rtx X is a valid immediate FPU constant. */
cce8749e
CH
2939
2940int
2941const_double_rtx_ok_for_fpu (x)
2942 rtx x;
2943{
ff9940b0
RE
2944 REAL_VALUE_TYPE r;
2945 int i;
2946
2947 if (!fpa_consts_inited)
2948 init_fpa_table ();
2949
2950 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2951 if (REAL_VALUE_MINUS_ZERO (r))
2952 return 0;
f3bb6135 2953
ff9940b0
RE
2954 for (i = 0; i < 8; i++)
2955 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
2956 return 1;
f3bb6135 2957
ff9940b0 2958 return 0;
f3bb6135 2959}
ff9940b0 2960
6354dc9b 2961/* Return TRUE if rtx X is a valid immediate FPU constant. */
ff9940b0
RE
2962
2963int
2964neg_const_double_rtx_ok_for_fpu (x)
2965 rtx x;
2966{
2967 REAL_VALUE_TYPE r;
2968 int i;
2969
2970 if (!fpa_consts_inited)
2971 init_fpa_table ();
2972
2973 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
2974 r = REAL_VALUE_NEGATE (r);
2975 if (REAL_VALUE_MINUS_ZERO (r))
2976 return 0;
f3bb6135 2977
ff9940b0
RE
2978 for (i = 0; i < 8; i++)
2979 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
2980 return 1;
f3bb6135 2981
ff9940b0 2982 return 0;
f3bb6135 2983}
cce8749e
CH
2984\f
2985/* Predicates for `match_operand' and `match_operator'. */
2986
ff9940b0 2987/* s_register_operand is the same as register_operand, but it doesn't accept
56a38cec
DE
2988 (SUBREG (MEM)...).
2989
2990 This function exists because at the time it was put in it led to better
2991 code. SUBREG(MEM) always needs a reload in the places where
2992 s_register_operand is used, and this seemed to lead to excessive
2993 reloading. */
ff9940b0
RE
2994
2995int
2996s_register_operand (op, mode)
2997 register rtx op;
2998 enum machine_mode mode;
2999{
3000 if (GET_MODE (op) != mode && mode != VOIDmode)
3001 return 0;
3002
3003 if (GET_CODE (op) == SUBREG)
f3bb6135 3004 op = SUBREG_REG (op);
ff9940b0
RE
3005
3006 /* We don't consider registers whose class is NO_REGS
3007 to be a register operand. */
d5b7b3ae 3008 /* XXX might have to check for lo regs only for thumb ??? */
ff9940b0
RE
3009 return (GET_CODE (op) == REG
3010 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3011 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
3012}
3013
b0888988
RE
3014/* A hard register operand (even before reload. */
3015int
3016arm_hard_register_operand (op, mode)
3017 register rtx op;
3018 enum machine_mode mode;
3019{
3020 if (GET_MODE (op) != mode && mode != VOIDmode)
3021 return 0;
3022
3023 return (GET_CODE (op) == REG
3024 && REGNO (op) < FIRST_PSEUDO_REGISTER);
3025}
3026
e2c671ba
RE
3027/* Only accept reg, subreg(reg), const_int. */
3028
3029int
3030reg_or_int_operand (op, mode)
3031 register rtx op;
3032 enum machine_mode mode;
3033{
3034 if (GET_CODE (op) == CONST_INT)
3035 return 1;
3036
3037 if (GET_MODE (op) != mode && mode != VOIDmode)
3038 return 0;
3039
3040 if (GET_CODE (op) == SUBREG)
3041 op = SUBREG_REG (op);
3042
3043 /* We don't consider registers whose class is NO_REGS
3044 to be a register operand. */
3045 return (GET_CODE (op) == REG
3046 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3047 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
3048}
3049
ff9940b0
RE
3050/* Return 1 if OP is an item in memory, given that we are in reload. */
3051
3052int
d5b7b3ae 3053arm_reload_memory_operand (op, mode)
ff9940b0 3054 rtx op;
74bbc178 3055 enum machine_mode mode ATTRIBUTE_UNUSED;
ff9940b0
RE
3056{
3057 int regno = true_regnum (op);
3058
5895f793 3059 return (!CONSTANT_P (op)
ff9940b0
RE
3060 && (regno == -1
3061 || (GET_CODE (op) == REG
3062 && REGNO (op) >= FIRST_PSEUDO_REGISTER)));
3063}
3064
4d818c85 3065/* Return 1 if OP is a valid memory address, but not valid for a signed byte
d5b7b3ae 3066 memory access (architecture V4).
f710504c 3067 MODE is QImode if called when computing constraints, or VOIDmode when
d5b7b3ae
RE
3068 emitting patterns. In this latter case we cannot use memory_operand()
3069 because it will fail on badly formed MEMs, which is precisly what we are
3070 trying to catch. */
4d818c85
RE
3071int
3072bad_signed_byte_operand (op, mode)
3073 rtx op;
d5b7b3ae 3074 enum machine_mode mode ATTRIBUTE_UNUSED;
4d818c85 3075{
d5b7b3ae 3076#if 0
5895f793 3077 if ((mode == QImode && !memory_operand (op, mode)) || GET_CODE (op) != MEM)
d5b7b3ae
RE
3078 return 0;
3079#endif
3080 if (GET_CODE (op) != MEM)
4d818c85
RE
3081 return 0;
3082
3083 op = XEXP (op, 0);
3084
6354dc9b 3085 /* A sum of anything more complex than reg + reg or reg + const is bad. */
4d818c85 3086 if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
5895f793
RE
3087 && (!s_register_operand (XEXP (op, 0), VOIDmode)
3088 || (!s_register_operand (XEXP (op, 1), VOIDmode)
9c8cc54f 3089 && GET_CODE (XEXP (op, 1)) != CONST_INT)))
4d818c85
RE
3090 return 1;
3091
6354dc9b 3092 /* Big constants are also bad. */
4d818c85
RE
3093 if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT
3094 && (INTVAL (XEXP (op, 1)) > 0xff
3095 || -INTVAL (XEXP (op, 1)) > 0xff))
3096 return 1;
3097
6354dc9b 3098 /* Everything else is good, or can will automatically be made so. */
4d818c85
RE
3099 return 0;
3100}
3101
cce8749e
CH
3102/* Return TRUE for valid operands for the rhs of an ARM instruction. */
3103
3104int
3105arm_rhs_operand (op, mode)
3106 rtx op;
3107 enum machine_mode mode;
3108{
ff9940b0 3109 return (s_register_operand (op, mode)
cce8749e 3110 || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))));
f3bb6135 3111}
cce8749e 3112
ff9940b0
RE
3113/* Return TRUE for valid operands for the rhs of an ARM instruction, or a load.
3114 */
3115
3116int
3117arm_rhsm_operand (op, mode)
3118 rtx op;
3119 enum machine_mode mode;
3120{
3121 return (s_register_operand (op, mode)
3122 || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))
3123 || memory_operand (op, mode));
f3bb6135 3124}
ff9940b0
RE
3125
3126/* Return TRUE for valid operands for the rhs of an ARM instruction, or if a
3127 constant that is valid when negated. */
3128
3129int
3130arm_add_operand (op, mode)
3131 rtx op;
3132 enum machine_mode mode;
3133{
d5b7b3ae
RE
3134 if (TARGET_THUMB)
3135 return thumb_cmp_operand (op, mode);
3136
ff9940b0
RE
3137 return (s_register_operand (op, mode)
3138 || (GET_CODE (op) == CONST_INT
3139 && (const_ok_for_arm (INTVAL (op))
3140 || const_ok_for_arm (-INTVAL (op)))));
f3bb6135 3141}
ff9940b0
RE
3142
3143int
3144arm_not_operand (op, mode)
3145 rtx op;
3146 enum machine_mode mode;
3147{
3148 return (s_register_operand (op, mode)
3149 || (GET_CODE (op) == CONST_INT
3150 && (const_ok_for_arm (INTVAL (op))
3151 || const_ok_for_arm (~INTVAL (op)))));
f3bb6135 3152}
ff9940b0 3153
5165176d
RE
3154/* Return TRUE if the operand is a memory reference which contains an
3155 offsettable address. */
3156int
3157offsettable_memory_operand (op, mode)
3158 register rtx op;
3159 enum machine_mode mode;
3160{
3161 if (mode == VOIDmode)
3162 mode = GET_MODE (op);
3163
3164 return (mode == GET_MODE (op)
3165 && GET_CODE (op) == MEM
3166 && offsettable_address_p (reload_completed | reload_in_progress,
3167 mode, XEXP (op, 0)));
3168}
3169
3170/* Return TRUE if the operand is a memory reference which is, or can be
3171 made word aligned by adjusting the offset. */
3172int
3173alignable_memory_operand (op, mode)
3174 register rtx op;
3175 enum machine_mode mode;
3176{
3177 rtx reg;
3178
3179 if (mode == VOIDmode)
3180 mode = GET_MODE (op);
3181
3182 if (mode != GET_MODE (op) || GET_CODE (op) != MEM)
3183 return 0;
3184
3185 op = XEXP (op, 0);
3186
3187 return ((GET_CODE (reg = op) == REG
3188 || (GET_CODE (op) == SUBREG
3189 && GET_CODE (reg = SUBREG_REG (op)) == REG)
3190 || (GET_CODE (op) == PLUS
3191 && GET_CODE (XEXP (op, 1)) == CONST_INT
3192 && (GET_CODE (reg = XEXP (op, 0)) == REG
3193 || (GET_CODE (XEXP (op, 0)) == SUBREG
3194 && GET_CODE (reg = SUBREG_REG (XEXP (op, 0))) == REG))))
bdb429a5 3195 && REGNO_POINTER_ALIGN (REGNO (reg)) >= 32);
5165176d
RE
3196}
3197
b111229a
RE
3198/* Similar to s_register_operand, but does not allow hard integer
3199 registers. */
3200int
3201f_register_operand (op, mode)
3202 register rtx op;
3203 enum machine_mode mode;
3204{
3205 if (GET_MODE (op) != mode && mode != VOIDmode)
3206 return 0;
3207
3208 if (GET_CODE (op) == SUBREG)
3209 op = SUBREG_REG (op);
3210
3211 /* We don't consider registers whose class is NO_REGS
3212 to be a register operand. */
3213 return (GET_CODE (op) == REG
3214 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3215 || REGNO_REG_CLASS (REGNO (op)) == FPU_REGS));
3216}
3217
cce8749e
CH
3218/* Return TRUE for valid operands for the rhs of an FPU instruction. */
3219
3220int
3221fpu_rhs_operand (op, mode)
3222 rtx op;
3223 enum machine_mode mode;
3224{
ff9940b0 3225 if (s_register_operand (op, mode))
f3bb6135 3226 return TRUE;
9ce71c6f
BS
3227
3228 if (GET_MODE (op) != mode && mode != VOIDmode)
3229 return FALSE;
3230
3231 if (GET_CODE (op) == CONST_DOUBLE)
3232 return const_double_rtx_ok_for_fpu (op);
f3bb6135
RE
3233
3234 return FALSE;
3235}
cce8749e 3236
ff9940b0
RE
3237int
3238fpu_add_operand (op, mode)
3239 rtx op;
3240 enum machine_mode mode;
3241{
3242 if (s_register_operand (op, mode))
f3bb6135 3243 return TRUE;
9ce71c6f
BS
3244
3245 if (GET_MODE (op) != mode && mode != VOIDmode)
3246 return FALSE;
3247
3248 if (GET_CODE (op) == CONST_DOUBLE)
f3bb6135
RE
3249 return (const_double_rtx_ok_for_fpu (op)
3250 || neg_const_double_rtx_ok_for_fpu (op));
3251
3252 return FALSE;
ff9940b0
RE
3253}
3254
cce8749e
CH
3255/* Return nonzero if OP is a constant power of two. */
3256
3257int
3258power_of_two_operand (op, mode)
3259 rtx op;
74bbc178 3260 enum machine_mode mode ATTRIBUTE_UNUSED;
cce8749e
CH
3261{
3262 if (GET_CODE (op) == CONST_INT)
3263 {
d5b7b3ae 3264 HOST_WIDE_INT value = INTVAL (op);
f3bb6135 3265 return value != 0 && (value & (value - 1)) == 0;
cce8749e 3266 }
f3bb6135
RE
3267 return FALSE;
3268}
cce8749e
CH
3269
3270/* Return TRUE for a valid operand of a DImode operation.
e9c6b69b 3271 Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
ff9940b0
RE
3272 Note that this disallows MEM(REG+REG), but allows
3273 MEM(PRE/POST_INC/DEC(REG)). */
cce8749e
CH
3274
3275int
3276di_operand (op, mode)
3277 rtx op;
3278 enum machine_mode mode;
3279{
ff9940b0 3280 if (s_register_operand (op, mode))
f3bb6135 3281 return TRUE;
cce8749e 3282
9ce71c6f
BS
3283 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
3284 return FALSE;
3285
e9c6b69b
NC
3286 if (GET_CODE (op) == SUBREG)
3287 op = SUBREG_REG (op);
3288
cce8749e
CH
3289 switch (GET_CODE (op))
3290 {
3291 case CONST_DOUBLE:
3292 case CONST_INT:
f3bb6135
RE
3293 return TRUE;
3294
cce8749e 3295 case MEM:
f3bb6135
RE
3296 return memory_address_p (DImode, XEXP (op, 0));
3297
cce8749e 3298 default:
f3bb6135 3299 return FALSE;
cce8749e 3300 }
f3bb6135 3301}
cce8749e 3302
d5b7b3ae
RE
3303/* Like di_operand, but don't accept constants. */
3304int
3305nonimmediate_di_operand (op, mode)
3306 rtx op;
3307 enum machine_mode mode;
3308{
3309 if (s_register_operand (op, mode))
3310 return TRUE;
3311
3312 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
3313 return FALSE;
3314
3315 if (GET_CODE (op) == SUBREG)
3316 op = SUBREG_REG (op);
3317
3318 if (GET_CODE (op) == MEM)
3319 return memory_address_p (DImode, XEXP (op, 0));
3320
3321 return FALSE;
3322}
3323
f3139301 3324/* Return TRUE for a valid operand of a DFmode operation when -msoft-float.
e9c6b69b 3325 Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
f3139301
DE
3326 Note that this disallows MEM(REG+REG), but allows
3327 MEM(PRE/POST_INC/DEC(REG)). */
3328
3329int
3330soft_df_operand (op, mode)
3331 rtx op;
3332 enum machine_mode mode;
3333{
3334 if (s_register_operand (op, mode))
3335 return TRUE;
3336
9ce71c6f
BS
3337 if (mode != VOIDmode && GET_MODE (op) != mode)
3338 return FALSE;
3339
37b80d2e
BS
3340 if (GET_CODE (op) == SUBREG && CONSTANT_P (SUBREG_REG (op)))
3341 return FALSE;
3342
e9c6b69b
NC
3343 if (GET_CODE (op) == SUBREG)
3344 op = SUBREG_REG (op);
9ce71c6f 3345
f3139301
DE
3346 switch (GET_CODE (op))
3347 {
3348 case CONST_DOUBLE:
3349 return TRUE;
3350
3351 case MEM:
3352 return memory_address_p (DFmode, XEXP (op, 0));
3353
3354 default:
3355 return FALSE;
3356 }
3357}
3358
d5b7b3ae
RE
3359/* Like soft_df_operand, but don't accept constants. */
3360int
3361nonimmediate_soft_df_operand (op, mode)
3362 rtx op;
3363 enum machine_mode mode;
3364{
3365 if (s_register_operand (op, mode))
3366 return TRUE;
3367
3368 if (mode != VOIDmode && GET_MODE (op) != mode)
3369 return FALSE;
3370
3371 if (GET_CODE (op) == SUBREG)
3372 op = SUBREG_REG (op);
3373
3374 if (GET_CODE (op) == MEM)
3375 return memory_address_p (DFmode, XEXP (op, 0));
3376 return FALSE;
3377}
cce8749e 3378
d5b7b3ae 3379/* Return TRUE for valid index operands. */
cce8749e
CH
3380int
3381index_operand (op, mode)
3382 rtx op;
3383 enum machine_mode mode;
3384{
d5b7b3ae 3385 return (s_register_operand (op, mode)
ff9940b0 3386 || (immediate_operand (op, mode)
d5b7b3ae
RE
3387 && (GET_CODE (op) != CONST_INT
3388 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))));
f3bb6135 3389}
cce8749e 3390
ff9940b0
RE
3391/* Return TRUE for valid shifts by a constant. This also accepts any
3392 power of two on the (somewhat overly relaxed) assumption that the
6354dc9b 3393 shift operator in this case was a mult. */
ff9940b0
RE
3394
3395int
3396const_shift_operand (op, mode)
3397 rtx op;
3398 enum machine_mode mode;
3399{
3400 return (power_of_two_operand (op, mode)
3401 || (immediate_operand (op, mode)
d5b7b3ae
RE
3402 && (GET_CODE (op) != CONST_INT
3403 || (INTVAL (op) < 32 && INTVAL (op) > 0))));
f3bb6135 3404}
ff9940b0 3405
cce8749e
CH
3406/* Return TRUE for arithmetic operators which can be combined with a multiply
3407 (shift). */
3408
3409int
3410shiftable_operator (x, mode)
3411 rtx x;
3412 enum machine_mode mode;
3413{
3414 if (GET_MODE (x) != mode)
3415 return FALSE;
3416 else
3417 {
3418 enum rtx_code code = GET_CODE (x);
3419
3420 return (code == PLUS || code == MINUS
3421 || code == IOR || code == XOR || code == AND);
3422 }
f3bb6135 3423}
cce8749e 3424
6ab589e0
JL
3425/* Return TRUE for binary logical operators. */
3426
3427int
3428logical_binary_operator (x, mode)
3429 rtx x;
3430 enum machine_mode mode;
3431{
3432 if (GET_MODE (x) != mode)
3433 return FALSE;
3434 else
3435 {
3436 enum rtx_code code = GET_CODE (x);
3437
3438 return (code == IOR || code == XOR || code == AND);
3439 }
3440}
3441
6354dc9b 3442/* Return TRUE for shift operators. */
cce8749e
CH
3443
3444int
3445shift_operator (x, mode)
3446 rtx x;
3447 enum machine_mode mode;
3448{
3449 if (GET_MODE (x) != mode)
3450 return FALSE;
3451 else
3452 {
3453 enum rtx_code code = GET_CODE (x);
3454
ff9940b0 3455 if (code == MULT)
aec3cfba 3456 return power_of_two_operand (XEXP (x, 1), mode);
f3bb6135 3457
e2c671ba
RE
3458 return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT
3459 || code == ROTATERT);
cce8749e 3460 }
f3bb6135 3461}
ff9940b0 3462
6354dc9b
NC
3463/* Return TRUE if x is EQ or NE. */
3464int
3465equality_operator (x, mode)
f3bb6135 3466 rtx x;
74bbc178 3467 enum machine_mode mode ATTRIBUTE_UNUSED;
ff9940b0 3468{
f3bb6135 3469 return GET_CODE (x) == EQ || GET_CODE (x) == NE;
ff9940b0
RE
3470}
3471
e45b72c4
RE
3472/* Return TRUE if x is a comparison operator other than LTGT or UNEQ. */
3473int
3474arm_comparison_operator (x, mode)
3475 rtx x;
3476 enum machine_mode mode;
3477{
3478 return (comparison_operator (x, mode)
3479 && GET_CODE (x) != LTGT
3480 && GET_CODE (x) != UNEQ);
3481}
3482
6354dc9b 3483/* Return TRUE for SMIN SMAX UMIN UMAX operators. */
ff9940b0
RE
3484int
3485minmax_operator (x, mode)
3486 rtx x;
3487 enum machine_mode mode;
3488{
3489 enum rtx_code code = GET_CODE (x);
3490
3491 if (GET_MODE (x) != mode)
3492 return FALSE;
f3bb6135 3493
ff9940b0 3494 return code == SMIN || code == SMAX || code == UMIN || code == UMAX;
f3bb6135 3495}
ff9940b0 3496
ff9940b0 3497/* Return TRUE if this is the condition code register, if we aren't given
6354dc9b 3498 a mode, accept any class CCmode register. */
ff9940b0
RE
3499int
3500cc_register (x, mode)
f3bb6135
RE
3501 rtx x;
3502 enum machine_mode mode;
ff9940b0
RE
3503{
3504 if (mode == VOIDmode)
3505 {
3506 mode = GET_MODE (x);
d5b7b3ae 3507
ff9940b0
RE
3508 if (GET_MODE_CLASS (mode) != MODE_CC)
3509 return FALSE;
3510 }
f3bb6135 3511
d5b7b3ae
RE
3512 if ( GET_MODE (x) == mode
3513 && GET_CODE (x) == REG
3514 && REGNO (x) == CC_REGNUM)
ff9940b0 3515 return TRUE;
f3bb6135 3516
ff9940b0
RE
3517 return FALSE;
3518}
5bbe2d40
RE
3519
3520/* Return TRUE if this is the condition code register, if we aren't given
84ed5e79
RE
3521 a mode, accept any class CCmode register which indicates a dominance
3522 expression. */
5bbe2d40 3523int
84ed5e79 3524dominant_cc_register (x, mode)
5bbe2d40
RE
3525 rtx x;
3526 enum machine_mode mode;
3527{
3528 if (mode == VOIDmode)
3529 {
3530 mode = GET_MODE (x);
d5b7b3ae 3531
84ed5e79 3532 if (GET_MODE_CLASS (mode) != MODE_CC)
5bbe2d40
RE
3533 return FALSE;
3534 }
3535
d5b7b3ae 3536 if ( mode != CC_DNEmode && mode != CC_DEQmode
84ed5e79
RE
3537 && mode != CC_DLEmode && mode != CC_DLTmode
3538 && mode != CC_DGEmode && mode != CC_DGTmode
3539 && mode != CC_DLEUmode && mode != CC_DLTUmode
3540 && mode != CC_DGEUmode && mode != CC_DGTUmode)
3541 return FALSE;
3542
d5b7b3ae 3543 return cc_register (x, mode);
5bbe2d40
RE
3544}
3545
2b835d68
RE
3546/* Return TRUE if X references a SYMBOL_REF. */
3547int
3548symbol_mentioned_p (x)
3549 rtx x;
3550{
6f7d635c 3551 register const char * fmt;
2b835d68
RE
3552 register int i;
3553
3554 if (GET_CODE (x) == SYMBOL_REF)
3555 return 1;
3556
3557 fmt = GET_RTX_FORMAT (GET_CODE (x));
d5b7b3ae 3558
2b835d68
RE
3559 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3560 {
3561 if (fmt[i] == 'E')
3562 {
3563 register int j;
3564
3565 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3566 if (symbol_mentioned_p (XVECEXP (x, i, j)))
3567 return 1;
3568 }
3569 else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i)))
3570 return 1;
3571 }
3572
3573 return 0;
3574}
3575
3576/* Return TRUE if X references a LABEL_REF. */
3577int
3578label_mentioned_p (x)
3579 rtx x;
3580{
6f7d635c 3581 register const char * fmt;
2b835d68
RE
3582 register int i;
3583
3584 if (GET_CODE (x) == LABEL_REF)
3585 return 1;
3586
3587 fmt = GET_RTX_FORMAT (GET_CODE (x));
3588 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3589 {
3590 if (fmt[i] == 'E')
3591 {
3592 register int j;
3593
3594 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3595 if (label_mentioned_p (XVECEXP (x, i, j)))
3596 return 1;
3597 }
3598 else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i)))
3599 return 1;
3600 }
3601
3602 return 0;
3603}
3604
ff9940b0
RE
3605enum rtx_code
3606minmax_code (x)
f3bb6135 3607 rtx x;
ff9940b0
RE
3608{
3609 enum rtx_code code = GET_CODE (x);
3610
3611 if (code == SMAX)
3612 return GE;
f3bb6135 3613 else if (code == SMIN)
ff9940b0 3614 return LE;
f3bb6135 3615 else if (code == UMIN)
ff9940b0 3616 return LEU;
f3bb6135 3617 else if (code == UMAX)
ff9940b0 3618 return GEU;
f3bb6135 3619
ff9940b0
RE
3620 abort ();
3621}
3622
6354dc9b 3623/* Return 1 if memory locations are adjacent. */
f3bb6135 3624int
ff9940b0
RE
3625adjacent_mem_locations (a, b)
3626 rtx a, b;
3627{
3628 int val0 = 0, val1 = 0;
3629 int reg0, reg1;
3630
3631 if ((GET_CODE (XEXP (a, 0)) == REG
3632 || (GET_CODE (XEXP (a, 0)) == PLUS
3633 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
3634 && (GET_CODE (XEXP (b, 0)) == REG
3635 || (GET_CODE (XEXP (b, 0)) == PLUS
3636 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
3637 {
3638 if (GET_CODE (XEXP (a, 0)) == PLUS)
3639 {
3640 reg0 = REGNO (XEXP (XEXP (a, 0), 0));
3641 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
3642 }
3643 else
3644 reg0 = REGNO (XEXP (a, 0));
3645 if (GET_CODE (XEXP (b, 0)) == PLUS)
3646 {
3647 reg1 = REGNO (XEXP (XEXP (b, 0), 0));
3648 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
3649 }
3650 else
3651 reg1 = REGNO (XEXP (b, 0));
3652 return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
3653 }
3654 return 0;
3655}
3656
3657/* Return 1 if OP is a load multiple operation. It is known to be
6354dc9b 3658 parallel and the first section will be tested. */
f3bb6135 3659int
ff9940b0
RE
3660load_multiple_operation (op, mode)
3661 rtx op;
74bbc178 3662 enum machine_mode mode ATTRIBUTE_UNUSED;
ff9940b0 3663{
f3bb6135 3664 HOST_WIDE_INT count = XVECLEN (op, 0);
ff9940b0
RE
3665 int dest_regno;
3666 rtx src_addr;
f3bb6135 3667 HOST_WIDE_INT i = 1, base = 0;
ff9940b0
RE
3668 rtx elt;
3669
3670 if (count <= 1
3671 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
3672 return 0;
3673
6354dc9b 3674 /* Check to see if this might be a write-back. */
ff9940b0
RE
3675 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
3676 {
3677 i++;
3678 base = 1;
3679
6354dc9b 3680 /* Now check it more carefully. */
ff9940b0
RE
3681 if (GET_CODE (SET_DEST (elt)) != REG
3682 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
3683 || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
3684 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
41e3f998 3685 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
ff9940b0 3686 return 0;
ff9940b0
RE
3687 }
3688
3689 /* Perform a quick check so we don't blow up below. */
3690 if (count <= i
3691 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
3692 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
3693 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
3694 return 0;
3695
3696 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
3697 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
3698
3699 for (; i < count; i++)
3700 {
ed4c4348 3701 elt = XVECEXP (op, 0, i);
ff9940b0
RE
3702
3703 if (GET_CODE (elt) != SET
3704 || GET_CODE (SET_DEST (elt)) != REG
3705 || GET_MODE (SET_DEST (elt)) != SImode
6354dc9b 3706 || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)
ff9940b0
RE
3707 || GET_CODE (SET_SRC (elt)) != MEM
3708 || GET_MODE (SET_SRC (elt)) != SImode
3709 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
5895f793 3710 || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
ff9940b0
RE
3711 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
3712 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)
3713 return 0;
3714 }
3715
3716 return 1;
3717}
3718
3719/* Return 1 if OP is a store multiple operation. It is known to be
6354dc9b 3720 parallel and the first section will be tested. */
f3bb6135 3721int
ff9940b0
RE
3722store_multiple_operation (op, mode)
3723 rtx op;
74bbc178 3724 enum machine_mode mode ATTRIBUTE_UNUSED;
ff9940b0 3725{
f3bb6135 3726 HOST_WIDE_INT count = XVECLEN (op, 0);
ff9940b0
RE
3727 int src_regno;
3728 rtx dest_addr;
f3bb6135 3729 HOST_WIDE_INT i = 1, base = 0;
ff9940b0
RE
3730 rtx elt;
3731
3732 if (count <= 1
3733 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
3734 return 0;
3735
6354dc9b 3736 /* Check to see if this might be a write-back. */
ff9940b0
RE
3737 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
3738 {
3739 i++;
3740 base = 1;
3741
6354dc9b 3742 /* Now check it more carefully. */
ff9940b0
RE
3743 if (GET_CODE (SET_DEST (elt)) != REG
3744 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
3745 || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
3746 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
41e3f998 3747 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
ff9940b0 3748 return 0;
ff9940b0
RE
3749 }
3750
3751 /* Perform a quick check so we don't blow up below. */
3752 if (count <= i
3753 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
3754 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
3755 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
3756 return 0;
3757
3758 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
3759 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
3760
3761 for (; i < count; i++)
3762 {
3763 elt = XVECEXP (op, 0, i);
3764
3765 if (GET_CODE (elt) != SET
3766 || GET_CODE (SET_SRC (elt)) != REG
3767 || GET_MODE (SET_SRC (elt)) != SImode
6354dc9b 3768 || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)
ff9940b0
RE
3769 || GET_CODE (SET_DEST (elt)) != MEM
3770 || GET_MODE (SET_DEST (elt)) != SImode
3771 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
5895f793 3772 || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
ff9940b0
RE
3773 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
3774 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)
3775 return 0;
3776 }
3777
3778 return 1;
3779}
e2c671ba 3780
84ed5e79
RE
3781int
3782load_multiple_sequence (operands, nops, regs, base, load_offset)
62b10bbc 3783 rtx * operands;
84ed5e79 3784 int nops;
62b10bbc
NC
3785 int * regs;
3786 int * base;
3787 HOST_WIDE_INT * load_offset;
84ed5e79
RE
3788{
3789 int unsorted_regs[4];
3790 HOST_WIDE_INT unsorted_offsets[4];
3791 int order[4];
ad076f4e 3792 int base_reg = -1;
84ed5e79
RE
3793 int i;
3794
3795 /* Can only handle 2, 3, or 4 insns at present, though could be easily
3796 extended if required. */
3797 if (nops < 2 || nops > 4)
3798 abort ();
3799
3800 /* Loop over the operands and check that the memory references are
3801 suitable (ie immediate offsets from the same base register). At
3802 the same time, extract the target register, and the memory
3803 offsets. */
3804 for (i = 0; i < nops; i++)
3805 {
3806 rtx reg;
3807 rtx offset;
3808
56636818
JL
3809 /* Convert a subreg of a mem into the mem itself. */
3810 if (GET_CODE (operands[nops + i]) == SUBREG)
d5b7b3ae 3811 operands[nops + i] = alter_subreg (operands[nops + i]);
56636818 3812
84ed5e79
RE
3813 if (GET_CODE (operands[nops + i]) != MEM)
3814 abort ();
3815
3816 /* Don't reorder volatile memory references; it doesn't seem worth
3817 looking for the case where the order is ok anyway. */
3818 if (MEM_VOLATILE_P (operands[nops + i]))
3819 return 0;
3820
3821 offset = const0_rtx;
3822
3823 if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG
3824 || (GET_CODE (reg) == SUBREG
3825 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
3826 || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
3827 && ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))
3828 == REG)
3829 || (GET_CODE (reg) == SUBREG
3830 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
3831 && (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))
3832 == CONST_INT)))
3833 {
3834 if (i == 0)
3835 {
d5b7b3ae 3836 base_reg = REGNO (reg);
84ed5e79
RE
3837 unsorted_regs[0] = (GET_CODE (operands[i]) == REG
3838 ? REGNO (operands[i])
3839 : REGNO (SUBREG_REG (operands[i])));
3840 order[0] = 0;
3841 }
3842 else
3843 {
6354dc9b 3844 if (base_reg != (int) REGNO (reg))
84ed5e79
RE
3845 /* Not addressed from the same base register. */
3846 return 0;
3847
3848 unsorted_regs[i] = (GET_CODE (operands[i]) == REG
3849 ? REGNO (operands[i])
3850 : REGNO (SUBREG_REG (operands[i])));
3851 if (unsorted_regs[i] < unsorted_regs[order[0]])
3852 order[0] = i;
3853 }
3854
3855 /* If it isn't an integer register, or if it overwrites the
3856 base register but isn't the last insn in the list, then
3857 we can't do this. */
3858 if (unsorted_regs[i] < 0 || unsorted_regs[i] > 14
3859 || (i != nops - 1 && unsorted_regs[i] == base_reg))
3860 return 0;
3861
3862 unsorted_offsets[i] = INTVAL (offset);
3863 }
3864 else
3865 /* Not a suitable memory address. */
3866 return 0;
3867 }
3868
3869 /* All the useful information has now been extracted from the
3870 operands into unsorted_regs and unsorted_offsets; additionally,
3871 order[0] has been set to the lowest numbered register in the
3872 list. Sort the registers into order, and check that the memory
3873 offsets are ascending and adjacent. */
3874
3875 for (i = 1; i < nops; i++)
3876 {
3877 int j;
3878
3879 order[i] = order[i - 1];
3880 for (j = 0; j < nops; j++)
3881 if (unsorted_regs[j] > unsorted_regs[order[i - 1]]
3882 && (order[i] == order[i - 1]
3883 || unsorted_regs[j] < unsorted_regs[order[i]]))
3884 order[i] = j;
3885
3886 /* Have we found a suitable register? if not, one must be used more
3887 than once. */
3888 if (order[i] == order[i - 1])
3889 return 0;
3890
3891 /* Is the memory address adjacent and ascending? */
3892 if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)
3893 return 0;
3894 }
3895
3896 if (base)
3897 {
3898 *base = base_reg;
3899
3900 for (i = 0; i < nops; i++)
3901 regs[i] = unsorted_regs[order[i]];
3902
3903 *load_offset = unsorted_offsets[order[0]];
3904 }
3905
3906 if (unsorted_offsets[order[0]] == 0)
3907 return 1; /* ldmia */
3908
3909 if (unsorted_offsets[order[0]] == 4)
3910 return 2; /* ldmib */
3911
3912 if (unsorted_offsets[order[nops - 1]] == 0)
3913 return 3; /* ldmda */
3914
3915 if (unsorted_offsets[order[nops - 1]] == -4)
3916 return 4; /* ldmdb */
3917
949d79eb
RE
3918 /* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm
3919 if the offset isn't small enough. The reason 2 ldrs are faster
3920 is because these ARMs are able to do more than one cache access
3921 in a single cycle. The ARM9 and StrongARM have Harvard caches,
3922 whilst the ARM8 has a double bandwidth cache. This means that
3923 these cores can do both an instruction fetch and a data fetch in
3924 a single cycle, so the trick of calculating the address into a
3925 scratch register (one of the result regs) and then doing a load
3926 multiple actually becomes slower (and no smaller in code size).
3927 That is the transformation
6cc8c0b3
NC
3928
3929 ldr rd1, [rbase + offset]
3930 ldr rd2, [rbase + offset + 4]
3931
3932 to
3933
3934 add rd1, rbase, offset
3935 ldmia rd1, {rd1, rd2}
3936
949d79eb
RE
3937 produces worse code -- '3 cycles + any stalls on rd2' instead of
3938 '2 cycles + any stalls on rd2'. On ARMs with only one cache
3939 access per cycle, the first sequence could never complete in less
3940 than 6 cycles, whereas the ldm sequence would only take 5 and
3941 would make better use of sequential accesses if not hitting the
3942 cache.
3943
3944 We cheat here and test 'arm_ld_sched' which we currently know to
3945 only be true for the ARM8, ARM9 and StrongARM. If this ever
3946 changes, then the test below needs to be reworked. */
f5a1b0d2 3947 if (nops == 2 && arm_ld_sched)
b36ba79f
RE
3948 return 0;
3949
84ed5e79
RE
3950 /* Can't do it without setting up the offset, only do this if it takes
3951 no more than one insn. */
3952 return (const_ok_for_arm (unsorted_offsets[order[0]])
3953 || const_ok_for_arm (-unsorted_offsets[order[0]])) ? 5 : 0;
3954}
3955
cd2b33d0 3956const char *
84ed5e79 3957emit_ldm_seq (operands, nops)
62b10bbc 3958 rtx * operands;
84ed5e79
RE
3959 int nops;
3960{
3961 int regs[4];
3962 int base_reg;
3963 HOST_WIDE_INT offset;
3964 char buf[100];
3965 int i;
3966
3967 switch (load_multiple_sequence (operands, nops, regs, &base_reg, &offset))
3968 {
3969 case 1:
3970 strcpy (buf, "ldm%?ia\t");
3971 break;
3972
3973 case 2:
3974 strcpy (buf, "ldm%?ib\t");
3975 break;
3976
3977 case 3:
3978 strcpy (buf, "ldm%?da\t");
3979 break;
3980
3981 case 4:
3982 strcpy (buf, "ldm%?db\t");
3983 break;
3984
3985 case 5:
3986 if (offset >= 0)
3987 sprintf (buf, "add%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX,
3988 reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],
3989 (long) offset);
3990 else
3991 sprintf (buf, "sub%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX,
3992 reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],
3993 (long) -offset);
3994 output_asm_insn (buf, operands);
3995 base_reg = regs[0];
3996 strcpy (buf, "ldm%?ia\t");
3997 break;
3998
3999 default:
4000 abort ();
4001 }
4002
4003 sprintf (buf + strlen (buf), "%s%s, {%s%s", REGISTER_PREFIX,
4004 reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);
4005
4006 for (i = 1; i < nops; i++)
4007 sprintf (buf + strlen (buf), ", %s%s", REGISTER_PREFIX,
4008 reg_names[regs[i]]);
4009
4010 strcat (buf, "}\t%@ phole ldm");
4011
4012 output_asm_insn (buf, operands);
4013 return "";
4014}
4015
4016int
4017store_multiple_sequence (operands, nops, regs, base, load_offset)
62b10bbc 4018 rtx * operands;
84ed5e79 4019 int nops;
62b10bbc
NC
4020 int * regs;
4021 int * base;
4022 HOST_WIDE_INT * load_offset;
84ed5e79
RE
4023{
4024 int unsorted_regs[4];
4025 HOST_WIDE_INT unsorted_offsets[4];
4026 int order[4];
ad076f4e 4027 int base_reg = -1;
84ed5e79
RE
4028 int i;
4029
4030 /* Can only handle 2, 3, or 4 insns at present, though could be easily
4031 extended if required. */
4032 if (nops < 2 || nops > 4)
4033 abort ();
4034
4035 /* Loop over the operands and check that the memory references are
4036 suitable (ie immediate offsets from the same base register). At
4037 the same time, extract the target register, and the memory
4038 offsets. */
4039 for (i = 0; i < nops; i++)
4040 {
4041 rtx reg;
4042 rtx offset;
4043
56636818
JL
4044 /* Convert a subreg of a mem into the mem itself. */
4045 if (GET_CODE (operands[nops + i]) == SUBREG)
d5b7b3ae 4046 operands[nops + i] = alter_subreg (operands[nops + i]);
56636818 4047
84ed5e79
RE
4048 if (GET_CODE (operands[nops + i]) != MEM)
4049 abort ();
4050
4051 /* Don't reorder volatile memory references; it doesn't seem worth
4052 looking for the case where the order is ok anyway. */
4053 if (MEM_VOLATILE_P (operands[nops + i]))
4054 return 0;
4055
4056 offset = const0_rtx;
4057
4058 if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG
4059 || (GET_CODE (reg) == SUBREG
4060 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4061 || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
4062 && ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))
4063 == REG)
4064 || (GET_CODE (reg) == SUBREG
4065 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4066 && (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))
4067 == CONST_INT)))
4068 {
4069 if (i == 0)
4070 {
62b10bbc 4071 base_reg = REGNO (reg);
84ed5e79
RE
4072 unsorted_regs[0] = (GET_CODE (operands[i]) == REG
4073 ? REGNO (operands[i])
4074 : REGNO (SUBREG_REG (operands[i])));
4075 order[0] = 0;
4076 }
4077 else
4078 {
6354dc9b 4079 if (base_reg != (int) REGNO (reg))
84ed5e79
RE
4080 /* Not addressed from the same base register. */
4081 return 0;
4082
4083 unsorted_regs[i] = (GET_CODE (operands[i]) == REG
4084 ? REGNO (operands[i])
4085 : REGNO (SUBREG_REG (operands[i])));
4086 if (unsorted_regs[i] < unsorted_regs[order[0]])
4087 order[0] = i;
4088 }
4089
4090 /* If it isn't an integer register, then we can't do this. */
4091 if (unsorted_regs[i] < 0 || unsorted_regs[i] > 14)
4092 return 0;
4093
4094 unsorted_offsets[i] = INTVAL (offset);
4095 }
4096 else
4097 /* Not a suitable memory address. */
4098 return 0;
4099 }
4100
4101 /* All the useful information has now been extracted from the
4102 operands into unsorted_regs and unsorted_offsets; additionally,
4103 order[0] has been set to the lowest numbered register in the
4104 list. Sort the registers into order, and check that the memory
4105 offsets are ascending and adjacent. */
4106
4107 for (i = 1; i < nops; i++)
4108 {
4109 int j;
4110
4111 order[i] = order[i - 1];
4112 for (j = 0; j < nops; j++)
4113 if (unsorted_regs[j] > unsorted_regs[order[i - 1]]
4114 && (order[i] == order[i - 1]
4115 || unsorted_regs[j] < unsorted_regs[order[i]]))
4116 order[i] = j;
4117
4118 /* Have we found a suitable register? if not, one must be used more
4119 than once. */
4120 if (order[i] == order[i - 1])
4121 return 0;
4122
4123 /* Is the memory address adjacent and ascending? */
4124 if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)
4125 return 0;
4126 }
4127
4128 if (base)
4129 {
4130 *base = base_reg;
4131
4132 for (i = 0; i < nops; i++)
4133 regs[i] = unsorted_regs[order[i]];
4134
4135 *load_offset = unsorted_offsets[order[0]];
4136 }
4137
4138 if (unsorted_offsets[order[0]] == 0)
4139 return 1; /* stmia */
4140
4141 if (unsorted_offsets[order[0]] == 4)
4142 return 2; /* stmib */
4143
4144 if (unsorted_offsets[order[nops - 1]] == 0)
4145 return 3; /* stmda */
4146
4147 if (unsorted_offsets[order[nops - 1]] == -4)
4148 return 4; /* stmdb */
4149
4150 return 0;
4151}
4152
cd2b33d0 4153const char *
84ed5e79 4154emit_stm_seq (operands, nops)
62b10bbc 4155 rtx * operands;
84ed5e79
RE
4156 int nops;
4157{
4158 int regs[4];
4159 int base_reg;
4160 HOST_WIDE_INT offset;
4161 char buf[100];
4162 int i;
4163
4164 switch (store_multiple_sequence (operands, nops, regs, &base_reg, &offset))
4165 {
4166 case 1:
4167 strcpy (buf, "stm%?ia\t");
4168 break;
4169
4170 case 2:
4171 strcpy (buf, "stm%?ib\t");
4172 break;
4173
4174 case 3:
4175 strcpy (buf, "stm%?da\t");
4176 break;
4177
4178 case 4:
4179 strcpy (buf, "stm%?db\t");
4180 break;
4181
4182 default:
4183 abort ();
4184 }
4185
4186 sprintf (buf + strlen (buf), "%s%s, {%s%s", REGISTER_PREFIX,
4187 reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);
4188
4189 for (i = 1; i < nops; i++)
4190 sprintf (buf + strlen (buf), ", %s%s", REGISTER_PREFIX,
4191 reg_names[regs[i]]);
4192
4193 strcat (buf, "}\t%@ phole stm");
4194
4195 output_asm_insn (buf, operands);
4196 return "";
4197}
4198
e2c671ba
RE
4199int
4200multi_register_push (op, mode)
0a81f500 4201 rtx op;
74bbc178 4202 enum machine_mode mode ATTRIBUTE_UNUSED;
e2c671ba
RE
4203{
4204 if (GET_CODE (op) != PARALLEL
4205 || (GET_CODE (XVECEXP (op, 0, 0)) != SET)
4206 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
b15bca31 4207 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT))
e2c671ba
RE
4208 return 0;
4209
4210 return 1;
4211}
ff9940b0 4212\f
6354dc9b 4213/* Routines for use in generating RTL. */
f3bb6135 4214rtx
56636818 4215arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
c6df88cb 4216 in_struct_p, scalar_p)
ff9940b0
RE
4217 int base_regno;
4218 int count;
4219 rtx from;
4220 int up;
4221 int write_back;
56636818
JL
4222 int unchanging_p;
4223 int in_struct_p;
c6df88cb 4224 int scalar_p;
ff9940b0
RE
4225{
4226 int i = 0, j;
4227 rtx result;
4228 int sign = up ? 1 : -1;
56636818 4229 rtx mem;
ff9940b0 4230
d19fb8e3
NC
4231 /* XScale has load-store double instructions, but they have stricter
4232 alignment requirements than load-store multiple, so we can not
4233 use them.
4234
4235 For XScale ldm requires 2 + NREGS cycles to complete and blocks
4236 the pipeline until completion.
4237
4238 NREGS CYCLES
4239 1 3
4240 2 4
4241 3 5
4242 4 6
4243
4244 An ldr instruction takes 1-3 cycles, but does not block the
4245 pipeline.
4246
4247 NREGS CYCLES
4248 1 1-3
4249 2 2-6
4250 3 3-9
4251 4 4-12
4252
4253 Best case ldr will always win. However, the more ldr instructions
4254 we issue, the less likely we are to be able to schedule them well.
4255 Using ldr instructions also increases code size.
4256
4257 As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
4258 for counts of 3 or 4 regs. */
4259 if (arm_is_xscale && count <= 2 && ! optimize_size)
4260 {
4261 rtx seq;
4262
4263 start_sequence ();
4264
4265 for (i = 0; i < count; i++)
4266 {
4267 mem = gen_rtx_MEM (SImode, plus_constant (from, i * 4 * sign));
4268 RTX_UNCHANGING_P (mem) = unchanging_p;
4269 MEM_IN_STRUCT_P (mem) = in_struct_p;
4270 MEM_SCALAR_P (mem) = scalar_p;
4271 emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);
4272 }
4273
4274 if (write_back)
4275 emit_move_insn (from, plus_constant (from, count * 4 * sign));
4276
4277 seq = gen_sequence ();
4278 end_sequence ();
4279
4280 return seq;
4281 }
4282
43cffd11 4283 result = gen_rtx_PARALLEL (VOIDmode,
41e3f998 4284 rtvec_alloc (count + (write_back ? 1 : 0)));
ff9940b0 4285 if (write_back)
f3bb6135 4286 {
ff9940b0 4287 XVECEXP (result, 0, 0)
43cffd11
RE
4288 = gen_rtx_SET (GET_MODE (from), from,
4289 plus_constant (from, count * 4 * sign));
ff9940b0
RE
4290 i = 1;
4291 count++;
f3bb6135
RE
4292 }
4293
ff9940b0 4294 for (j = 0; i < count; i++, j++)
f3bb6135 4295 {
43cffd11 4296 mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign));
56636818
JL
4297 RTX_UNCHANGING_P (mem) = unchanging_p;
4298 MEM_IN_STRUCT_P (mem) = in_struct_p;
c6df88cb 4299 MEM_SCALAR_P (mem) = scalar_p;
43cffd11
RE
4300 XVECEXP (result, 0, i)
4301 = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
f3bb6135
RE
4302 }
4303
ff9940b0
RE
4304 return result;
4305}
4306
f3bb6135 4307rtx
56636818 4308arm_gen_store_multiple (base_regno, count, to, up, write_back, unchanging_p,
c6df88cb 4309 in_struct_p, scalar_p)
ff9940b0
RE
4310 int base_regno;
4311 int count;
4312 rtx to;
4313 int up;
4314 int write_back;
56636818
JL
4315 int unchanging_p;
4316 int in_struct_p;
c6df88cb 4317 int scalar_p;
ff9940b0
RE
4318{
4319 int i = 0, j;
4320 rtx result;
4321 int sign = up ? 1 : -1;
56636818 4322 rtx mem;
ff9940b0 4323
d19fb8e3
NC
4324 /* See arm_gen_load_multiple for discussion of
4325 the pros/cons of ldm/stm usage for XScale. */
4326 if (arm_is_xscale && count <= 2 && ! optimize_size)
4327 {
4328 rtx seq;
4329
4330 start_sequence ();
4331
4332 for (i = 0; i < count; i++)
4333 {
4334 mem = gen_rtx_MEM (SImode, plus_constant (to, i * 4 * sign));
4335 RTX_UNCHANGING_P (mem) = unchanging_p;
4336 MEM_IN_STRUCT_P (mem) = in_struct_p;
4337 MEM_SCALAR_P (mem) = scalar_p;
4338 emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));
4339 }
4340
4341 if (write_back)
4342 emit_move_insn (to, plus_constant (to, count * 4 * sign));
4343
4344 seq = gen_sequence ();
4345 end_sequence ();
4346
4347 return seq;
4348 }
4349
43cffd11 4350 result = gen_rtx_PARALLEL (VOIDmode,
41e3f998 4351 rtvec_alloc (count + (write_back ? 1 : 0)));
ff9940b0 4352 if (write_back)
f3bb6135 4353 {
ff9940b0 4354 XVECEXP (result, 0, 0)
43cffd11
RE
4355 = gen_rtx_SET (GET_MODE (to), to,
4356 plus_constant (to, count * 4 * sign));
ff9940b0
RE
4357 i = 1;
4358 count++;
f3bb6135
RE
4359 }
4360
ff9940b0 4361 for (j = 0; i < count; i++, j++)
f3bb6135 4362 {
43cffd11 4363 mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign));
56636818
JL
4364 RTX_UNCHANGING_P (mem) = unchanging_p;
4365 MEM_IN_STRUCT_P (mem) = in_struct_p;
c6df88cb 4366 MEM_SCALAR_P (mem) = scalar_p;
56636818 4367
43cffd11
RE
4368 XVECEXP (result, 0, i)
4369 = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
f3bb6135
RE
4370 }
4371
ff9940b0
RE
4372 return result;
4373}
4374
880e2516
RE
4375int
4376arm_gen_movstrqi (operands)
62b10bbc 4377 rtx * operands;
880e2516
RE
4378{
4379 HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
ad076f4e 4380 int i;
880e2516 4381 rtx src, dst;
ad076f4e 4382 rtx st_src, st_dst, fin_src, fin_dst;
880e2516 4383 rtx part_bytes_reg = NULL;
56636818
JL
4384 rtx mem;
4385 int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p;
c6df88cb 4386 int dst_scalar_p, src_scalar_p;
880e2516
RE
4387
4388 if (GET_CODE (operands[2]) != CONST_INT
4389 || GET_CODE (operands[3]) != CONST_INT
4390 || INTVAL (operands[2]) > 64
4391 || INTVAL (operands[3]) & 3)
4392 return 0;
4393
4394 st_dst = XEXP (operands[0], 0);
4395 st_src = XEXP (operands[1], 0);
56636818
JL
4396
4397 dst_unchanging_p = RTX_UNCHANGING_P (operands[0]);
4398 dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
c6df88cb 4399 dst_scalar_p = MEM_SCALAR_P (operands[0]);
56636818
JL
4400 src_unchanging_p = RTX_UNCHANGING_P (operands[1]);
4401 src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
c6df88cb 4402 src_scalar_p = MEM_SCALAR_P (operands[1]);
56636818 4403
880e2516
RE
4404 fin_dst = dst = copy_to_mode_reg (SImode, st_dst);
4405 fin_src = src = copy_to_mode_reg (SImode, st_src);
4406
d5b7b3ae 4407 in_words_to_go = NUM_INTS (INTVAL (operands[2]));
880e2516
RE
4408 out_words_to_go = INTVAL (operands[2]) / 4;
4409 last_bytes = INTVAL (operands[2]) & 3;
4410
4411 if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
43cffd11 4412 part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
880e2516
RE
4413
4414 for (i = 0; in_words_to_go >= 2; i+=4)
4415 {
bd9c7e23 4416 if (in_words_to_go > 4)
56636818 4417 emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
c6df88cb
MM
4418 src_unchanging_p,
4419 src_in_struct_p,
4420 src_scalar_p));
bd9c7e23
RE
4421 else
4422 emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE,
56636818 4423 FALSE, src_unchanging_p,
c6df88cb 4424 src_in_struct_p, src_scalar_p));
bd9c7e23 4425
880e2516
RE
4426 if (out_words_to_go)
4427 {
bd9c7e23 4428 if (out_words_to_go > 4)
56636818
JL
4429 emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
4430 dst_unchanging_p,
c6df88cb
MM
4431 dst_in_struct_p,
4432 dst_scalar_p));
bd9c7e23
RE
4433 else if (out_words_to_go != 1)
4434 emit_insn (arm_gen_store_multiple (0, out_words_to_go,
4435 dst, TRUE,
4436 (last_bytes == 0
56636818
JL
4437 ? FALSE : TRUE),
4438 dst_unchanging_p,
c6df88cb
MM
4439 dst_in_struct_p,
4440 dst_scalar_p));
880e2516
RE
4441 else
4442 {
43cffd11 4443 mem = gen_rtx_MEM (SImode, dst);
56636818
JL
4444 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
4445 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 4446 MEM_SCALAR_P (mem) = dst_scalar_p;
43cffd11 4447 emit_move_insn (mem, gen_rtx_REG (SImode, 0));
bd9c7e23
RE
4448 if (last_bytes != 0)
4449 emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
880e2516
RE
4450 }
4451 }
4452
4453 in_words_to_go -= in_words_to_go < 4 ? in_words_to_go : 4;
4454 out_words_to_go -= out_words_to_go < 4 ? out_words_to_go : 4;
4455 }
4456
4457 /* OUT_WORDS_TO_GO will be zero here if there are byte stores to do. */
4458 if (out_words_to_go)
62b10bbc
NC
4459 {
4460 rtx sreg;
4461
4462 mem = gen_rtx_MEM (SImode, src);
4463 RTX_UNCHANGING_P (mem) = src_unchanging_p;
4464 MEM_IN_STRUCT_P (mem) = src_in_struct_p;
4465 MEM_SCALAR_P (mem) = src_scalar_p;
4466 emit_move_insn (sreg = gen_reg_rtx (SImode), mem);
4467 emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
4468
4469 mem = gen_rtx_MEM (SImode, dst);
4470 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
4471 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
4472 MEM_SCALAR_P (mem) = dst_scalar_p;
4473 emit_move_insn (mem, sreg);
4474 emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
4475 in_words_to_go--;
4476
4477 if (in_words_to_go) /* Sanity check */
4478 abort ();
4479 }
880e2516
RE
4480
4481 if (in_words_to_go)
4482 {
4483 if (in_words_to_go < 0)
4484 abort ();
4485
43cffd11 4486 mem = gen_rtx_MEM (SImode, src);
56636818
JL
4487 RTX_UNCHANGING_P (mem) = src_unchanging_p;
4488 MEM_IN_STRUCT_P (mem) = src_in_struct_p;
c6df88cb 4489 MEM_SCALAR_P (mem) = src_scalar_p;
56636818 4490 part_bytes_reg = copy_to_mode_reg (SImode, mem);
880e2516
RE
4491 }
4492
d5b7b3ae
RE
4493 if (last_bytes && part_bytes_reg == NULL)
4494 abort ();
4495
880e2516
RE
4496 if (BYTES_BIG_ENDIAN && last_bytes)
4497 {
4498 rtx tmp = gen_reg_rtx (SImode);
4499
6354dc9b 4500 /* The bytes we want are in the top end of the word. */
bee06f3d
RE
4501 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg,
4502 GEN_INT (8 * (4 - last_bytes))));
880e2516
RE
4503 part_bytes_reg = tmp;
4504
4505 while (last_bytes)
4506 {
43cffd11 4507 mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1));
56636818
JL
4508 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
4509 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 4510 MEM_SCALAR_P (mem) = dst_scalar_p;
43cffd11 4511 emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
62b10bbc 4512
880e2516
RE
4513 if (--last_bytes)
4514 {
4515 tmp = gen_reg_rtx (SImode);
4516 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (8)));
4517 part_bytes_reg = tmp;
4518 }
4519 }
4520
4521 }
4522 else
4523 {
d5b7b3ae 4524 if (last_bytes > 1)
880e2516 4525 {
d5b7b3ae 4526 mem = gen_rtx_MEM (HImode, dst);
56636818
JL
4527 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
4528 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 4529 MEM_SCALAR_P (mem) = dst_scalar_p;
d5b7b3ae
RE
4530 emit_move_insn (mem, gen_rtx_SUBREG (HImode, part_bytes_reg, 0));
4531 last_bytes -= 2;
4532 if (last_bytes)
880e2516
RE
4533 {
4534 rtx tmp = gen_reg_rtx (SImode);
bd9c7e23 4535
d5b7b3ae
RE
4536 emit_insn (gen_addsi3 (dst, dst, GEN_INT (2)));
4537 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16)));
880e2516
RE
4538 part_bytes_reg = tmp;
4539 }
4540 }
d5b7b3ae
RE
4541
4542 if (last_bytes)
4543 {
4544 mem = gen_rtx_MEM (QImode, dst);
4545 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
4546 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
4547 MEM_SCALAR_P (mem) = dst_scalar_p;
4548 emit_move_insn (mem, gen_rtx_SUBREG (QImode, part_bytes_reg, 0));
4549 }
880e2516
RE
4550 }
4551
4552 return 1;
4553}
4554
5165176d
RE
4555/* Generate a memory reference for a half word, such that it will be loaded
4556 into the top 16 bits of the word. We can assume that the address is
4557 known to be alignable and of the form reg, or plus (reg, const). */
4558rtx
d5b7b3ae 4559arm_gen_rotated_half_load (memref)
5165176d
RE
4560 rtx memref;
4561{
4562 HOST_WIDE_INT offset = 0;
4563 rtx base = XEXP (memref, 0);
4564
4565 if (GET_CODE (base) == PLUS)
4566 {
4567 offset = INTVAL (XEXP (base, 1));
4568 base = XEXP (base, 0);
4569 }
4570
956d6950 4571 /* If we aren't allowed to generate unaligned addresses, then fail. */
5f1e6755 4572 if (TARGET_MMU_TRAPS
5165176d
RE
4573 && ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 0)))
4574 return NULL;
4575
43cffd11 4576 base = gen_rtx_MEM (SImode, plus_constant (base, offset & ~2));
5165176d
RE
4577
4578 if ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 2))
4579 return base;
4580
43cffd11 4581 return gen_rtx_ROTATE (SImode, base, GEN_INT (16));
5165176d
RE
4582}
4583
1646cf41
RE
4584/* Select a dominance comparison mode if possible. We support three forms.
4585 COND_OR == 0 => (X && Y)
4586 COND_OR == 1 => ((! X( || Y)
4587 COND_OR == 2 => (X || Y)
4588 If we are unable to support a dominance comparsison we return CC mode.
4589 This will then fail to match for the RTL expressions that generate this
4590 call. */
d19fb8e3 4591
84ed5e79 4592static enum machine_mode
74bbc178 4593select_dominance_cc_mode (x, y, cond_or)
84ed5e79
RE
4594 rtx x;
4595 rtx y;
4596 HOST_WIDE_INT cond_or;
4597{
4598 enum rtx_code cond1, cond2;
4599 int swapped = 0;
4600
4601 /* Currently we will probably get the wrong result if the individual
4602 comparisons are not simple. This also ensures that it is safe to
956d6950 4603 reverse a comparison if necessary. */
84ed5e79
RE
4604 if ((arm_select_cc_mode (cond1 = GET_CODE (x), XEXP (x, 0), XEXP (x, 1))
4605 != CCmode)
4606 || (arm_select_cc_mode (cond2 = GET_CODE (y), XEXP (y, 0), XEXP (y, 1))
4607 != CCmode))
4608 return CCmode;
4609
1646cf41
RE
4610 /* The if_then_else variant of this tests the second condition if the
4611 first passes, but is true if the first fails. Reverse the first
4612 condition to get a true "inclusive-or" expression. */
4613 if (cond_or == 1)
84ed5e79
RE
4614 cond1 = reverse_condition (cond1);
4615
4616 /* If the comparisons are not equal, and one doesn't dominate the other,
4617 then we can't do this. */
4618 if (cond1 != cond2
5895f793
RE
4619 && !comparison_dominates_p (cond1, cond2)
4620 && (swapped = 1, !comparison_dominates_p (cond2, cond1)))
84ed5e79
RE
4621 return CCmode;
4622
4623 if (swapped)
4624 {
4625 enum rtx_code temp = cond1;
4626 cond1 = cond2;
4627 cond2 = temp;
4628 }
4629
4630 switch (cond1)
4631 {
4632 case EQ:
5895f793 4633 if (cond2 == EQ || !cond_or)
84ed5e79
RE
4634 return CC_DEQmode;
4635
4636 switch (cond2)
4637 {
4638 case LE: return CC_DLEmode;
4639 case LEU: return CC_DLEUmode;
4640 case GE: return CC_DGEmode;
4641 case GEU: return CC_DGEUmode;
ad076f4e 4642 default: break;
84ed5e79
RE
4643 }
4644
4645 break;
4646
4647 case LT:
5895f793 4648 if (cond2 == LT || !cond_or)
84ed5e79
RE
4649 return CC_DLTmode;
4650 if (cond2 == LE)
4651 return CC_DLEmode;
4652 if (cond2 == NE)
4653 return CC_DNEmode;
4654 break;
4655
4656 case GT:
5895f793 4657 if (cond2 == GT || !cond_or)
84ed5e79
RE
4658 return CC_DGTmode;
4659 if (cond2 == GE)
4660 return CC_DGEmode;
4661 if (cond2 == NE)
4662 return CC_DNEmode;
4663 break;
4664
4665 case LTU:
5895f793 4666 if (cond2 == LTU || !cond_or)
84ed5e79
RE
4667 return CC_DLTUmode;
4668 if (cond2 == LEU)
4669 return CC_DLEUmode;
4670 if (cond2 == NE)
4671 return CC_DNEmode;
4672 break;
4673
4674 case GTU:
5895f793 4675 if (cond2 == GTU || !cond_or)
84ed5e79
RE
4676 return CC_DGTUmode;
4677 if (cond2 == GEU)
4678 return CC_DGEUmode;
4679 if (cond2 == NE)
4680 return CC_DNEmode;
4681 break;
4682
4683 /* The remaining cases only occur when both comparisons are the
4684 same. */
4685 case NE:
4686 return CC_DNEmode;
4687
4688 case LE:
4689 return CC_DLEmode;
4690
4691 case GE:
4692 return CC_DGEmode;
4693
4694 case LEU:
4695 return CC_DLEUmode;
4696
4697 case GEU:
4698 return CC_DGEUmode;
ad076f4e
RE
4699
4700 default:
4701 break;
84ed5e79
RE
4702 }
4703
4704 abort ();
4705}
4706
4707enum machine_mode
4708arm_select_cc_mode (op, x, y)
4709 enum rtx_code op;
4710 rtx x;
4711 rtx y;
4712{
4713 /* All floating point compares return CCFP if it is an equality
4714 comparison, and CCFPE otherwise. */
4715 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
e45b72c4
RE
4716 {
4717 switch (op)
4718 {
4719 case EQ:
4720 case NE:
4721 case UNORDERED:
4722 case ORDERED:
4723 case UNLT:
4724 case UNLE:
4725 case UNGT:
4726 case UNGE:
4727 case UNEQ:
4728 case LTGT:
4729 return CCFPmode;
4730
4731 case LT:
4732 case LE:
4733 case GT:
4734 case GE:
4735 return CCFPEmode;
4736
4737 default:
4738 abort ();
4739 }
4740 }
84ed5e79
RE
4741
4742 /* A compare with a shifted operand. Because of canonicalization, the
4743 comparison will have to be swapped when we emit the assembler. */
4744 if (GET_MODE (y) == SImode && GET_CODE (y) == REG
4745 && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
4746 || GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ROTATE
4747 || GET_CODE (x) == ROTATERT))
4748 return CC_SWPmode;
4749
956d6950
JL
4750 /* This is a special case that is used by combine to allow a
4751 comparison of a shifted byte load to be split into a zero-extend
84ed5e79 4752 followed by a comparison of the shifted integer (only valid for
956d6950 4753 equalities and unsigned inequalities). */
84ed5e79
RE
4754 if (GET_MODE (x) == SImode
4755 && GET_CODE (x) == ASHIFT
4756 && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 24
4757 && GET_CODE (XEXP (x, 0)) == SUBREG
4758 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == MEM
4759 && GET_MODE (SUBREG_REG (XEXP (x, 0))) == QImode
4760 && (op == EQ || op == NE
4761 || op == GEU || op == GTU || op == LTU || op == LEU)
4762 && GET_CODE (y) == CONST_INT)
4763 return CC_Zmode;
4764
1646cf41
RE
4765 /* A construct for a conditional compare, if the false arm contains
4766 0, then both conditions must be true, otherwise either condition
4767 must be true. Not all conditions are possible, so CCmode is
4768 returned if it can't be done. */
4769 if (GET_CODE (x) == IF_THEN_ELSE
4770 && (XEXP (x, 2) == const0_rtx
4771 || XEXP (x, 2) == const1_rtx)
4772 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
4773 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
4774 return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
4775 INTVAL (XEXP (x, 2)));
4776
4777 /* Alternate canonicalizations of the above. These are somewhat cleaner. */
4778 if (GET_CODE (x) == AND
4779 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
4780 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
4781 return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 0);
4782
4783 if (GET_CODE (x) == IOR
4784 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
4785 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
4786 return select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1), 2);
4787
84ed5e79
RE
4788 /* An operation that sets the condition codes as a side-effect, the
4789 V flag is not set correctly, so we can only use comparisons where
4790 this doesn't matter. (For LT and GE we can use "mi" and "pl"
4791 instead. */
4792 if (GET_MODE (x) == SImode
4793 && y == const0_rtx
4794 && (op == EQ || op == NE || op == LT || op == GE)
4795 && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
4796 || GET_CODE (x) == AND || GET_CODE (x) == IOR
4797 || GET_CODE (x) == XOR || GET_CODE (x) == MULT
4798 || GET_CODE (x) == NOT || GET_CODE (x) == NEG
4799 || GET_CODE (x) == LSHIFTRT
4800 || GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
4801 || GET_CODE (x) == ROTATERT || GET_CODE (x) == ZERO_EXTRACT))
4802 return CC_NOOVmode;
4803
84ed5e79
RE
4804 if (GET_MODE (x) == QImode && (op == EQ || op == NE))
4805 return CC_Zmode;
4806
bd9c7e23
RE
4807 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
4808 && GET_CODE (x) == PLUS
4809 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
4810 return CC_Cmode;
4811
84ed5e79
RE
4812 return CCmode;
4813}
4814
ff9940b0
RE
4815/* X and Y are two things to compare using CODE. Emit the compare insn and
4816 return the rtx for register 0 in the proper mode. FP means this is a
4817 floating point compare: I don't think that it is needed on the arm. */
4818
4819rtx
d5b7b3ae 4820arm_gen_compare_reg (code, x, y)
ff9940b0
RE
4821 enum rtx_code code;
4822 rtx x, y;
4823{
4824 enum machine_mode mode = SELECT_CC_MODE (code, x, y);
d5b7b3ae 4825 rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM);
ff9940b0 4826
43cffd11
RE
4827 emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
4828 gen_rtx_COMPARE (mode, x, y)));
ff9940b0
RE
4829
4830 return cc_reg;
4831}
4832
0a81f500
RE
4833void
4834arm_reload_in_hi (operands)
62b10bbc 4835 rtx * operands;
0a81f500 4836{
f9cc092a
RE
4837 rtx ref = operands[1];
4838 rtx base, scratch;
4839 HOST_WIDE_INT offset = 0;
4840
4841 if (GET_CODE (ref) == SUBREG)
4842 {
ddef6bc7 4843 offset = SUBREG_BYTE (ref);
f9cc092a
RE
4844 ref = SUBREG_REG (ref);
4845 }
4846
4847 if (GET_CODE (ref) == REG)
4848 {
4849 /* We have a pseudo which has been spilt onto the stack; there
4850 are two cases here: the first where there is a simple
4851 stack-slot replacement and a second where the stack-slot is
4852 out of range, or is used as a subreg. */
4853 if (reg_equiv_mem[REGNO (ref)])
4854 {
4855 ref = reg_equiv_mem[REGNO (ref)];
4856 base = find_replacement (&XEXP (ref, 0));
4857 }
4858 else
6354dc9b 4859 /* The slot is out of range, or was dressed up in a SUBREG. */
f9cc092a
RE
4860 base = reg_equiv_address[REGNO (ref)];
4861 }
4862 else
4863 base = find_replacement (&XEXP (ref, 0));
0a81f500 4864
e5e809f4
JL
4865 /* Handle the case where the address is too complex to be offset by 1. */
4866 if (GET_CODE (base) == MINUS
4867 || (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
4868 {
f9cc092a 4869 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
e5e809f4 4870
43cffd11 4871 emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
e5e809f4
JL
4872 base = base_plus;
4873 }
f9cc092a
RE
4874 else if (GET_CODE (base) == PLUS)
4875 {
6354dc9b 4876 /* The addend must be CONST_INT, or we would have dealt with it above. */
f9cc092a
RE
4877 HOST_WIDE_INT hi, lo;
4878
4879 offset += INTVAL (XEXP (base, 1));
4880 base = XEXP (base, 0);
4881
6354dc9b 4882 /* Rework the address into a legal sequence of insns. */
f9cc092a
RE
4883 /* Valid range for lo is -4095 -> 4095 */
4884 lo = (offset >= 0
4885 ? (offset & 0xfff)
4886 : -((-offset) & 0xfff));
4887
4888 /* Corner case, if lo is the max offset then we would be out of range
4889 once we have added the additional 1 below, so bump the msb into the
4890 pre-loading insn(s). */
4891 if (lo == 4095)
4892 lo &= 0x7ff;
4893
30cf4896
KG
4894 hi = ((((offset - lo) & (HOST_WIDE_INT) 0xffffffff)
4895 ^ (HOST_WIDE_INT) 0x80000000)
4896 - (HOST_WIDE_INT) 0x80000000);
f9cc092a
RE
4897
4898 if (hi + lo != offset)
4899 abort ();
4900
4901 if (hi != 0)
4902 {
4903 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
4904
4905 /* Get the base address; addsi3 knows how to handle constants
6354dc9b 4906 that require more than one insn. */
f9cc092a
RE
4907 emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
4908 base = base_plus;
4909 offset = lo;
4910 }
4911 }
e5e809f4 4912
f9cc092a
RE
4913 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
4914 emit_insn (gen_zero_extendqisi2 (scratch,
4915 gen_rtx_MEM (QImode,
4916 plus_constant (base,
4917 offset))));
43cffd11
RE
4918 emit_insn (gen_zero_extendqisi2 (gen_rtx_SUBREG (SImode, operands[0], 0),
4919 gen_rtx_MEM (QImode,
f9cc092a
RE
4920 plus_constant (base,
4921 offset + 1))));
5895f793 4922 if (!BYTES_BIG_ENDIAN)
43cffd11
RE
4923 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
4924 gen_rtx_IOR (SImode,
4925 gen_rtx_ASHIFT
4926 (SImode,
4927 gen_rtx_SUBREG (SImode, operands[0], 0),
4928 GEN_INT (8)),
f9cc092a 4929 scratch)));
0a81f500 4930 else
43cffd11
RE
4931 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
4932 gen_rtx_IOR (SImode,
f9cc092a 4933 gen_rtx_ASHIFT (SImode, scratch,
43cffd11
RE
4934 GEN_INT (8)),
4935 gen_rtx_SUBREG (SImode, operands[0],
4936 0))));
0a81f500
RE
4937}
4938
f9cc092a
RE
4939/* Handle storing a half-word to memory during reload by synthesising as two
4940 byte stores. Take care not to clobber the input values until after we
4941 have moved them somewhere safe. This code assumes that if the DImode
4942 scratch in operands[2] overlaps either the input value or output address
4943 in some way, then that value must die in this insn (we absolutely need
4944 two scratch registers for some corner cases). */
f3bb6135 4945void
af48348a 4946arm_reload_out_hi (operands)
62b10bbc 4947 rtx * operands;
af48348a 4948{
f9cc092a
RE
4949 rtx ref = operands[0];
4950 rtx outval = operands[1];
4951 rtx base, scratch;
4952 HOST_WIDE_INT offset = 0;
4953
4954 if (GET_CODE (ref) == SUBREG)
4955 {
ddef6bc7 4956 offset = SUBREG_BYTE (ref);
f9cc092a
RE
4957 ref = SUBREG_REG (ref);
4958 }
4959
4960
4961 if (GET_CODE (ref) == REG)
4962 {
4963 /* We have a pseudo which has been spilt onto the stack; there
4964 are two cases here: the first where there is a simple
4965 stack-slot replacement and a second where the stack-slot is
4966 out of range, or is used as a subreg. */
4967 if (reg_equiv_mem[REGNO (ref)])
4968 {
4969 ref = reg_equiv_mem[REGNO (ref)];
4970 base = find_replacement (&XEXP (ref, 0));
4971 }
4972 else
6354dc9b 4973 /* The slot is out of range, or was dressed up in a SUBREG. */
f9cc092a
RE
4974 base = reg_equiv_address[REGNO (ref)];
4975 }
4976 else
4977 base = find_replacement (&XEXP (ref, 0));
4978
4979 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
4980
4981 /* Handle the case where the address is too complex to be offset by 1. */
4982 if (GET_CODE (base) == MINUS
4983 || (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
4984 {
4985 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
4986
4987 /* Be careful not to destroy OUTVAL. */
4988 if (reg_overlap_mentioned_p (base_plus, outval))
4989 {
4990 /* Updating base_plus might destroy outval, see if we can
4991 swap the scratch and base_plus. */
5895f793 4992 if (!reg_overlap_mentioned_p (scratch, outval))
f9cc092a
RE
4993 {
4994 rtx tmp = scratch;
4995 scratch = base_plus;
4996 base_plus = tmp;
4997 }
4998 else
4999 {
5000 rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
5001
5002 /* Be conservative and copy OUTVAL into the scratch now,
5003 this should only be necessary if outval is a subreg
5004 of something larger than a word. */
5005 /* XXX Might this clobber base? I can't see how it can,
5006 since scratch is known to overlap with OUTVAL, and
5007 must be wider than a word. */
5008 emit_insn (gen_movhi (scratch_hi, outval));
5009 outval = scratch_hi;
5010 }
5011 }
5012
5013 emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
5014 base = base_plus;
5015 }
5016 else if (GET_CODE (base) == PLUS)
5017 {
6354dc9b 5018 /* The addend must be CONST_INT, or we would have dealt with it above. */
f9cc092a
RE
5019 HOST_WIDE_INT hi, lo;
5020
5021 offset += INTVAL (XEXP (base, 1));
5022 base = XEXP (base, 0);
5023
6354dc9b 5024 /* Rework the address into a legal sequence of insns. */
f9cc092a
RE
5025 /* Valid range for lo is -4095 -> 4095 */
5026 lo = (offset >= 0
5027 ? (offset & 0xfff)
5028 : -((-offset) & 0xfff));
5029
5030 /* Corner case, if lo is the max offset then we would be out of range
5031 once we have added the additional 1 below, so bump the msb into the
5032 pre-loading insn(s). */
5033 if (lo == 4095)
5034 lo &= 0x7ff;
5035
30cf4896
KG
5036 hi = ((((offset - lo) & (HOST_WIDE_INT) 0xffffffff)
5037 ^ (HOST_WIDE_INT) 0x80000000)
5038 - (HOST_WIDE_INT) 0x80000000);
f9cc092a
RE
5039
5040 if (hi + lo != offset)
5041 abort ();
5042
5043 if (hi != 0)
5044 {
5045 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5046
5047 /* Be careful not to destroy OUTVAL. */
5048 if (reg_overlap_mentioned_p (base_plus, outval))
5049 {
5050 /* Updating base_plus might destroy outval, see if we
5051 can swap the scratch and base_plus. */
5895f793 5052 if (!reg_overlap_mentioned_p (scratch, outval))
f9cc092a
RE
5053 {
5054 rtx tmp = scratch;
5055 scratch = base_plus;
5056 base_plus = tmp;
5057 }
5058 else
5059 {
5060 rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
5061
5062 /* Be conservative and copy outval into scratch now,
5063 this should only be necessary if outval is a
5064 subreg of something larger than a word. */
5065 /* XXX Might this clobber base? I can't see how it
5066 can, since scratch is known to overlap with
5067 outval. */
5068 emit_insn (gen_movhi (scratch_hi, outval));
5069 outval = scratch_hi;
5070 }
5071 }
5072
5073 /* Get the base address; addsi3 knows how to handle constants
6354dc9b 5074 that require more than one insn. */
f9cc092a
RE
5075 emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
5076 base = base_plus;
5077 offset = lo;
5078 }
5079 }
af48348a 5080
b5cc037f
RE
5081 if (BYTES_BIG_ENDIAN)
5082 {
f9cc092a
RE
5083 emit_insn (gen_movqi (gen_rtx_MEM (QImode,
5084 plus_constant (base, offset + 1)),
5085 gen_rtx_SUBREG (QImode, outval, 0)));
5086 emit_insn (gen_lshrsi3 (scratch,
5087 gen_rtx_SUBREG (SImode, outval, 0),
b5cc037f 5088 GEN_INT (8)));
f9cc092a
RE
5089 emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
5090 gen_rtx_SUBREG (QImode, scratch, 0)));
b5cc037f
RE
5091 }
5092 else
5093 {
f9cc092a
RE
5094 emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
5095 gen_rtx_SUBREG (QImode, outval, 0)));
5096 emit_insn (gen_lshrsi3 (scratch,
5097 gen_rtx_SUBREG (SImode, outval, 0),
b5cc037f 5098 GEN_INT (8)));
f9cc092a
RE
5099 emit_insn (gen_movqi (gen_rtx_MEM (QImode,
5100 plus_constant (base, offset + 1)),
5101 gen_rtx_SUBREG (QImode, scratch, 0)));
b5cc037f 5102 }
af48348a 5103}
2b835d68 5104\f
d5b7b3ae
RE
5105/* Print a symbolic form of X to the debug file, F. */
5106static void
5107arm_print_value (f, x)
5108 FILE * f;
5109 rtx x;
5110{
5111 switch (GET_CODE (x))
5112 {
5113 case CONST_INT:
5114 fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
5115 return;
5116
5117 case CONST_DOUBLE:
5118 fprintf (f, "<0x%lx,0x%lx>", (long)XWINT (x, 2), (long)XWINT (x, 3));
5119 return;
5120
5121 case CONST_STRING:
5122 fprintf (f, "\"%s\"", XSTR (x, 0));
5123 return;
5124
5125 case SYMBOL_REF:
5126 fprintf (f, "`%s'", XSTR (x, 0));
5127 return;
5128
5129 case LABEL_REF:
5130 fprintf (f, "L%d", INSN_UID (XEXP (x, 0)));
5131 return;
5132
5133 case CONST:
5134 arm_print_value (f, XEXP (x, 0));
5135 return;
5136
5137 case PLUS:
5138 arm_print_value (f, XEXP (x, 0));
5139 fprintf (f, "+");
5140 arm_print_value (f, XEXP (x, 1));
5141 return;
5142
5143 case PC:
5144 fprintf (f, "pc");
5145 return;
5146
5147 default:
5148 fprintf (f, "????");
5149 return;
5150 }
5151}
5152\f
2b835d68 5153/* Routines for manipulation of the constant pool. */
2b835d68 5154
949d79eb
RE
5155/* Arm instructions cannot load a large constant directly into a
5156 register; they have to come from a pc relative load. The constant
5157 must therefore be placed in the addressable range of the pc
5158 relative load. Depending on the precise pc relative load
5159 instruction the range is somewhere between 256 bytes and 4k. This
5160 means that we often have to dump a constant inside a function, and
2b835d68
RE
5161 generate code to branch around it.
5162
949d79eb
RE
5163 It is important to minimize this, since the branches will slow
5164 things down and make the code larger.
2b835d68 5165
949d79eb
RE
5166 Normally we can hide the table after an existing unconditional
5167 branch so that there is no interruption of the flow, but in the
5168 worst case the code looks like this:
2b835d68
RE
5169
5170 ldr rn, L1
949d79eb 5171 ...
2b835d68
RE
5172 b L2
5173 align
5174 L1: .long value
5175 L2:
949d79eb 5176 ...
2b835d68 5177
2b835d68 5178 ldr rn, L3
949d79eb 5179 ...
2b835d68
RE
5180 b L4
5181 align
2b835d68
RE
5182 L3: .long value
5183 L4:
949d79eb
RE
5184 ...
5185
5186 We fix this by performing a scan after scheduling, which notices
5187 which instructions need to have their operands fetched from the
5188 constant table and builds the table.
5189
5190 The algorithm starts by building a table of all the constants that
5191 need fixing up and all the natural barriers in the function (places
5192 where a constant table can be dropped without breaking the flow).
5193 For each fixup we note how far the pc-relative replacement will be
5194 able to reach and the offset of the instruction into the function.
5195
5196 Having built the table we then group the fixes together to form
5197 tables that are as large as possible (subject to addressing
5198 constraints) and emit each table of constants after the last
5199 barrier that is within range of all the instructions in the group.
5200 If a group does not contain a barrier, then we forcibly create one
5201 by inserting a jump instruction into the flow. Once the table has
5202 been inserted, the insns are then modified to reference the
5203 relevant entry in the pool.
5204
6354dc9b 5205 Possible enhancements to the algorithm (not implemented) are:
949d79eb 5206
d5b7b3ae 5207 1) For some processors and object formats, there may be benefit in
949d79eb
RE
5208 aligning the pools to the start of cache lines; this alignment
5209 would need to be taken into account when calculating addressability
6354dc9b 5210 of a pool. */
2b835d68 5211
d5b7b3ae
RE
5212/* These typedefs are located at the start of this file, so that
5213 they can be used in the prototypes there. This comment is to
5214 remind readers of that fact so that the following structures
5215 can be understood more easily.
5216
5217 typedef struct minipool_node Mnode;
5218 typedef struct minipool_fixup Mfix; */
5219
5220struct minipool_node
5221{
5222 /* Doubly linked chain of entries. */
5223 Mnode * next;
5224 Mnode * prev;
5225 /* The maximum offset into the code that this entry can be placed. While
5226 pushing fixes for forward references, all entries are sorted in order
5227 of increasing max_address. */
5228 HOST_WIDE_INT max_address;
5519a4f9 5229 /* Similarly for an entry inserted for a backwards ref. */
d5b7b3ae
RE
5230 HOST_WIDE_INT min_address;
5231 /* The number of fixes referencing this entry. This can become zero
5232 if we "unpush" an entry. In this case we ignore the entry when we
5233 come to emit the code. */
5234 int refcount;
5235 /* The offset from the start of the minipool. */
5236 HOST_WIDE_INT offset;
5237 /* The value in table. */
5238 rtx value;
5239 /* The mode of value. */
5240 enum machine_mode mode;
5241 int fix_size;
5242};
5243
5244struct minipool_fixup
2b835d68 5245{
d5b7b3ae
RE
5246 Mfix * next;
5247 rtx insn;
5248 HOST_WIDE_INT address;
5249 rtx * loc;
5250 enum machine_mode mode;
5251 int fix_size;
5252 rtx value;
5253 Mnode * minipool;
5254 HOST_WIDE_INT forwards;
5255 HOST_WIDE_INT backwards;
5256};
2b835d68 5257
d5b7b3ae
RE
5258/* Fixes less than a word need padding out to a word boundary. */
5259#define MINIPOOL_FIX_SIZE(mode) \
5260 (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4)
2b835d68 5261
d5b7b3ae
RE
5262static Mnode * minipool_vector_head;
5263static Mnode * minipool_vector_tail;
5264static rtx minipool_vector_label;
332072db 5265
d5b7b3ae
RE
5266/* The linked list of all minipool fixes required for this function. */
5267Mfix * minipool_fix_head;
5268Mfix * minipool_fix_tail;
5269/* The fix entry for the current minipool, once it has been placed. */
5270Mfix * minipool_barrier;
5271
5272/* Determines if INSN is the start of a jump table. Returns the end
5273 of the TABLE or NULL_RTX. */
5274static rtx
5275is_jump_table (insn)
5276 rtx insn;
2b835d68 5277{
d5b7b3ae 5278 rtx table;
da6558fd 5279
d5b7b3ae
RE
5280 if (GET_CODE (insn) == JUMP_INSN
5281 && JUMP_LABEL (insn) != NULL
5282 && ((table = next_real_insn (JUMP_LABEL (insn)))
5283 == next_real_insn (insn))
5284 && table != NULL
5285 && GET_CODE (table) == JUMP_INSN
5286 && (GET_CODE (PATTERN (table)) == ADDR_VEC
5287 || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
5288 return table;
5289
5290 return NULL_RTX;
2b835d68
RE
5291}
5292
d5b7b3ae
RE
5293static HOST_WIDE_INT
5294get_jump_table_size (insn)
5295 rtx insn;
2b835d68 5296{
d5b7b3ae
RE
5297 rtx body = PATTERN (insn);
5298 int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
2b835d68 5299
d5b7b3ae
RE
5300 return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
5301}
2b835d68 5302
d5b7b3ae
RE
5303/* Move a minipool fix MP from its current location to before MAX_MP.
5304 If MAX_MP is NULL, then MP doesn't need moving, but the addressing
5305 contrains may need updating. */
5306static Mnode *
5307move_minipool_fix_forward_ref (mp, max_mp, max_address)
5308 Mnode * mp;
5309 Mnode * max_mp;
5310 HOST_WIDE_INT max_address;
5311{
5312 /* This should never be true and the code below assumes these are
5313 different. */
5314 if (mp == max_mp)
5315 abort ();
5316
5317 if (max_mp == NULL)
5318 {
5319 if (max_address < mp->max_address)
5320 mp->max_address = max_address;
5321 }
5322 else
2b835d68 5323 {
d5b7b3ae
RE
5324 if (max_address > max_mp->max_address - mp->fix_size)
5325 mp->max_address = max_mp->max_address - mp->fix_size;
5326 else
5327 mp->max_address = max_address;
2b835d68 5328
d5b7b3ae
RE
5329 /* Unlink MP from its current position. Since max_mp is non-null,
5330 mp->prev must be non-null. */
5331 mp->prev->next = mp->next;
5332 if (mp->next != NULL)
5333 mp->next->prev = mp->prev;
5334 else
5335 minipool_vector_tail = mp->prev;
2b835d68 5336
d5b7b3ae
RE
5337 /* Re-insert it before MAX_MP. */
5338 mp->next = max_mp;
5339 mp->prev = max_mp->prev;
5340 max_mp->prev = mp;
5341
5342 if (mp->prev != NULL)
5343 mp->prev->next = mp;
5344 else
5345 minipool_vector_head = mp;
5346 }
2b835d68 5347
d5b7b3ae
RE
5348 /* Save the new entry. */
5349 max_mp = mp;
5350
5351 /* Scan over the preceeding entries and adjust their addresses as
5352 required. */
5353 while (mp->prev != NULL
5354 && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
5355 {
5356 mp->prev->max_address = mp->max_address - mp->prev->fix_size;
5357 mp = mp->prev;
2b835d68
RE
5358 }
5359
d5b7b3ae 5360 return max_mp;
2b835d68
RE
5361}
5362
d5b7b3ae
RE
5363/* Add a constant to the minipool for a forward reference. Returns the
5364 node added or NULL if the constant will not fit in this pool. */
5365static Mnode *
5366add_minipool_forward_ref (fix)
5367 Mfix * fix;
5368{
5369 /* If set, max_mp is the first pool_entry that has a lower
5370 constraint than the one we are trying to add. */
5371 Mnode * max_mp = NULL;
5372 HOST_WIDE_INT max_address = fix->address + fix->forwards;
5373 Mnode * mp;
5374
5375 /* If this fix's address is greater than the address of the first
5376 entry, then we can't put the fix in this pool. We subtract the
5377 size of the current fix to ensure that if the table is fully
5378 packed we still have enough room to insert this value by suffling
5379 the other fixes forwards. */
5380 if (minipool_vector_head &&
5381 fix->address >= minipool_vector_head->max_address - fix->fix_size)
5382 return NULL;
2b835d68 5383
d5b7b3ae
RE
5384 /* Scan the pool to see if a constant with the same value has
5385 already been added. While we are doing this, also note the
5386 location where we must insert the constant if it doesn't already
5387 exist. */
5388 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5389 {
5390 if (GET_CODE (fix->value) == GET_CODE (mp->value)
5391 && fix->mode == mp->mode
5392 && (GET_CODE (fix->value) != CODE_LABEL
5393 || (CODE_LABEL_NUMBER (fix->value)
5394 == CODE_LABEL_NUMBER (mp->value)))
5395 && rtx_equal_p (fix->value, mp->value))
5396 {
5397 /* More than one fix references this entry. */
5398 mp->refcount++;
5399 return move_minipool_fix_forward_ref (mp, max_mp, max_address);
5400 }
5401
5402 /* Note the insertion point if necessary. */
5403 if (max_mp == NULL
5404 && mp->max_address > max_address)
5405 max_mp = mp;
5406 }
5407
5408 /* The value is not currently in the minipool, so we need to create
5409 a new entry for it. If MAX_MP is NULL, the entry will be put on
5410 the end of the list since the placement is less constrained than
5411 any existing entry. Otherwise, we insert the new fix before
5412 MAX_MP and, if neceesary, adjust the constraints on the other
5413 entries. */
5414 mp = xmalloc (sizeof (* mp));
5415 mp->fix_size = fix->fix_size;
5416 mp->mode = fix->mode;
5417 mp->value = fix->value;
5418 mp->refcount = 1;
5419 /* Not yet required for a backwards ref. */
5420 mp->min_address = -65536;
5421
5422 if (max_mp == NULL)
5423 {
5424 mp->max_address = max_address;
5425 mp->next = NULL;
5426 mp->prev = minipool_vector_tail;
5427
5428 if (mp->prev == NULL)
5429 {
5430 minipool_vector_head = mp;
5431 minipool_vector_label = gen_label_rtx ();
7551cbc7 5432 }
2b835d68 5433 else
d5b7b3ae 5434 mp->prev->next = mp;
2b835d68 5435
d5b7b3ae
RE
5436 minipool_vector_tail = mp;
5437 }
5438 else
5439 {
5440 if (max_address > max_mp->max_address - mp->fix_size)
5441 mp->max_address = max_mp->max_address - mp->fix_size;
5442 else
5443 mp->max_address = max_address;
5444
5445 mp->next = max_mp;
5446 mp->prev = max_mp->prev;
5447 max_mp->prev = mp;
5448 if (mp->prev != NULL)
5449 mp->prev->next = mp;
5450 else
5451 minipool_vector_head = mp;
5452 }
5453
5454 /* Save the new entry. */
5455 max_mp = mp;
5456
5457 /* Scan over the preceeding entries and adjust their addresses as
5458 required. */
5459 while (mp->prev != NULL
5460 && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
5461 {
5462 mp->prev->max_address = mp->max_address - mp->prev->fix_size;
5463 mp = mp->prev;
2b835d68
RE
5464 }
5465
d5b7b3ae
RE
5466 return max_mp;
5467}
5468
5469static Mnode *
5470move_minipool_fix_backward_ref (mp, min_mp, min_address)
5471 Mnode * mp;
5472 Mnode * min_mp;
5473 HOST_WIDE_INT min_address;
5474{
5475 HOST_WIDE_INT offset;
5476
5477 /* This should never be true, and the code below assumes these are
5478 different. */
5479 if (mp == min_mp)
5480 abort ();
5481
5482 if (min_mp == NULL)
2b835d68 5483 {
d5b7b3ae
RE
5484 if (min_address > mp->min_address)
5485 mp->min_address = min_address;
5486 }
5487 else
5488 {
5489 /* We will adjust this below if it is too loose. */
5490 mp->min_address = min_address;
5491
5492 /* Unlink MP from its current position. Since min_mp is non-null,
5493 mp->next must be non-null. */
5494 mp->next->prev = mp->prev;
5495 if (mp->prev != NULL)
5496 mp->prev->next = mp->next;
5497 else
5498 minipool_vector_head = mp->next;
5499
5500 /* Reinsert it after MIN_MP. */
5501 mp->prev = min_mp;
5502 mp->next = min_mp->next;
5503 min_mp->next = mp;
5504 if (mp->next != NULL)
5505 mp->next->prev = mp;
2b835d68 5506 else
d5b7b3ae
RE
5507 minipool_vector_tail = mp;
5508 }
5509
5510 min_mp = mp;
5511
5512 offset = 0;
5513 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5514 {
5515 mp->offset = offset;
5516 if (mp->refcount > 0)
5517 offset += mp->fix_size;
5518
5519 if (mp->next && mp->next->min_address < mp->min_address + mp->fix_size)
5520 mp->next->min_address = mp->min_address + mp->fix_size;
5521 }
5522
5523 return min_mp;
5524}
5525
5526/* Add a constant to the minipool for a backward reference. Returns the
5527 node added or NULL if the constant will not fit in this pool.
5528
5529 Note that the code for insertion for a backwards reference can be
5530 somewhat confusing because the calculated offsets for each fix do
5531 not take into account the size of the pool (which is still under
5532 construction. */
5533static Mnode *
5534add_minipool_backward_ref (fix)
5535 Mfix * fix;
5536{
5537 /* If set, min_mp is the last pool_entry that has a lower constraint
5538 than the one we are trying to add. */
5539 Mnode * min_mp = NULL;
5540 /* This can be negative, since it is only a constraint. */
5541 HOST_WIDE_INT min_address = fix->address - fix->backwards;
5542 Mnode * mp;
5543
5544 /* If we can't reach the current pool from this insn, or if we can't
5545 insert this entry at the end of the pool without pushing other
5546 fixes out of range, then we don't try. This ensures that we
5547 can't fail later on. */
5548 if (min_address >= minipool_barrier->address
5549 || (minipool_vector_tail->min_address + fix->fix_size
5550 >= minipool_barrier->address))
5551 return NULL;
5552
5553 /* Scan the pool to see if a constant with the same value has
5554 already been added. While we are doing this, also note the
5555 location where we must insert the constant if it doesn't already
5556 exist. */
5557 for (mp = minipool_vector_tail; mp != NULL; mp = mp->prev)
5558 {
5559 if (GET_CODE (fix->value) == GET_CODE (mp->value)
5560 && fix->mode == mp->mode
5561 && (GET_CODE (fix->value) != CODE_LABEL
5562 || (CODE_LABEL_NUMBER (fix->value)
5563 == CODE_LABEL_NUMBER (mp->value)))
5564 && rtx_equal_p (fix->value, mp->value)
5565 /* Check that there is enough slack to move this entry to the
5566 end of the table (this is conservative). */
5567 && (mp->max_address
5568 > (minipool_barrier->address
5569 + minipool_vector_tail->offset
5570 + minipool_vector_tail->fix_size)))
5571 {
5572 mp->refcount++;
5573 return move_minipool_fix_backward_ref (mp, min_mp, min_address);
5574 }
5575
5576 if (min_mp != NULL)
5577 mp->min_address += fix->fix_size;
5578 else
5579 {
5580 /* Note the insertion point if necessary. */
5581 if (mp->min_address < min_address)
5582 min_mp = mp;
5583 else if (mp->max_address
5584 < minipool_barrier->address + mp->offset + fix->fix_size)
5585 {
5586 /* Inserting before this entry would push the fix beyond
5587 its maximum address (which can happen if we have
5588 re-located a forwards fix); force the new fix to come
5589 after it. */
5590 min_mp = mp;
5591 min_address = mp->min_address + fix->fix_size;
5592 }
5593 }
5594 }
5595
5596 /* We need to create a new entry. */
5597 mp = xmalloc (sizeof (* mp));
5598 mp->fix_size = fix->fix_size;
5599 mp->mode = fix->mode;
5600 mp->value = fix->value;
5601 mp->refcount = 1;
5602 mp->max_address = minipool_barrier->address + 65536;
5603
5604 mp->min_address = min_address;
5605
5606 if (min_mp == NULL)
5607 {
5608 mp->prev = NULL;
5609 mp->next = minipool_vector_head;
5610
5611 if (mp->next == NULL)
5612 {
5613 minipool_vector_tail = mp;
5614 minipool_vector_label = gen_label_rtx ();
5615 }
5616 else
5617 mp->next->prev = mp;
5618
5619 minipool_vector_head = mp;
5620 }
5621 else
5622 {
5623 mp->next = min_mp->next;
5624 mp->prev = min_mp;
5625 min_mp->next = mp;
da6558fd 5626
d5b7b3ae
RE
5627 if (mp->next != NULL)
5628 mp->next->prev = mp;
5629 else
5630 minipool_vector_tail = mp;
5631 }
5632
5633 /* Save the new entry. */
5634 min_mp = mp;
5635
5636 if (mp->prev)
5637 mp = mp->prev;
5638 else
5639 mp->offset = 0;
5640
5641 /* Scan over the following entries and adjust their offsets. */
5642 while (mp->next != NULL)
5643 {
5644 if (mp->next->min_address < mp->min_address + mp->fix_size)
5645 mp->next->min_address = mp->min_address + mp->fix_size;
5646
5647 if (mp->refcount)
5648 mp->next->offset = mp->offset + mp->fix_size;
5649 else
5650 mp->next->offset = mp->offset;
5651
5652 mp = mp->next;
5653 }
5654
5655 return min_mp;
5656}
5657
5658static void
5659assign_minipool_offsets (barrier)
5660 Mfix * barrier;
5661{
5662 HOST_WIDE_INT offset = 0;
5663 Mnode * mp;
5664
5665 minipool_barrier = barrier;
5666
5667 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5668 {
5669 mp->offset = offset;
da6558fd 5670
d5b7b3ae
RE
5671 if (mp->refcount > 0)
5672 offset += mp->fix_size;
5673 }
5674}
5675
5676/* Output the literal table */
5677static void
5678dump_minipool (scan)
5679 rtx scan;
5680{
5681 Mnode * mp;
5682 Mnode * nmp;
5683
5684 if (rtl_dump_file)
5685 fprintf (rtl_dump_file,
5686 ";; Emitting minipool after insn %u; address %ld\n",
5687 INSN_UID (scan), (unsigned long) minipool_barrier->address);
5688
5689 scan = emit_label_after (gen_label_rtx (), scan);
5690 scan = emit_insn_after (gen_align_4 (), scan);
5691 scan = emit_label_after (minipool_vector_label, scan);
5692
5693 for (mp = minipool_vector_head; mp != NULL; mp = nmp)
5694 {
5695 if (mp->refcount > 0)
5696 {
5697 if (rtl_dump_file)
5698 {
5699 fprintf (rtl_dump_file,
5700 ";; Offset %u, min %ld, max %ld ",
5701 (unsigned) mp->offset, (unsigned long) mp->min_address,
5702 (unsigned long) mp->max_address);
5703 arm_print_value (rtl_dump_file, mp->value);
5704 fputc ('\n', rtl_dump_file);
5705 }
5706
5707 switch (mp->fix_size)
5708 {
5709#ifdef HAVE_consttable_1
5710 case 1:
5711 scan = emit_insn_after (gen_consttable_1 (mp->value), scan);
5712 break;
5713
5714#endif
5715#ifdef HAVE_consttable_2
5716 case 2:
5717 scan = emit_insn_after (gen_consttable_2 (mp->value), scan);
5718 break;
5719
5720#endif
5721#ifdef HAVE_consttable_4
5722 case 4:
5723 scan = emit_insn_after (gen_consttable_4 (mp->value), scan);
5724 break;
5725
5726#endif
5727#ifdef HAVE_consttable_8
5728 case 8:
5729 scan = emit_insn_after (gen_consttable_8 (mp->value), scan);
5730 break;
5731
5732#endif
5733 default:
5734 abort ();
5735 break;
5736 }
5737 }
5738
5739 nmp = mp->next;
5740 free (mp);
2b835d68
RE
5741 }
5742
d5b7b3ae
RE
5743 minipool_vector_head = minipool_vector_tail = NULL;
5744 scan = emit_insn_after (gen_consttable_end (), scan);
5745 scan = emit_barrier_after (scan);
2b835d68
RE
5746}
5747
d5b7b3ae
RE
5748/* Return the cost of forcibly inserting a barrier after INSN. */
5749static int
5750arm_barrier_cost (insn)
5751 rtx insn;
949d79eb 5752{
d5b7b3ae
RE
5753 /* Basing the location of the pool on the loop depth is preferable,
5754 but at the moment, the basic block information seems to be
5755 corrupt by this stage of the compilation. */
5756 int base_cost = 50;
5757 rtx next = next_nonnote_insn (insn);
5758
5759 if (next != NULL && GET_CODE (next) == CODE_LABEL)
5760 base_cost -= 20;
5761
5762 switch (GET_CODE (insn))
5763 {
5764 case CODE_LABEL:
5765 /* It will always be better to place the table before the label, rather
5766 than after it. */
5767 return 50;
949d79eb 5768
d5b7b3ae
RE
5769 case INSN:
5770 case CALL_INSN:
5771 return base_cost;
5772
5773 case JUMP_INSN:
5774 return base_cost - 10;
5775
5776 default:
5777 return base_cost + 10;
5778 }
5779}
5780
5781/* Find the best place in the insn stream in the range
5782 (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
5783 Create the barrier by inserting a jump and add a new fix entry for
5784 it. */
5785static Mfix *
5786create_fix_barrier (fix, max_address)
5787 Mfix * fix;
5788 HOST_WIDE_INT max_address;
5789{
5790 HOST_WIDE_INT count = 0;
5791 rtx barrier;
5792 rtx from = fix->insn;
5793 rtx selected = from;
5794 int selected_cost;
5795 HOST_WIDE_INT selected_address;
5796 Mfix * new_fix;
5797 HOST_WIDE_INT max_count = max_address - fix->address;
5798 rtx label = gen_label_rtx ();
5799
5800 selected_cost = arm_barrier_cost (from);
5801 selected_address = fix->address;
5802
5803 while (from && count < max_count)
5804 {
5805 rtx tmp;
5806 int new_cost;
5807
5808 /* This code shouldn't have been called if there was a natural barrier
5809 within range. */
5810 if (GET_CODE (from) == BARRIER)
5811 abort ();
5812
5813 /* Count the length of this insn. */
5814 count += get_attr_length (from);
5815
5816 /* If there is a jump table, add its length. */
5817 tmp = is_jump_table (from);
5818 if (tmp != NULL)
5819 {
5820 count += get_jump_table_size (tmp);
5821
5822 /* Jump tables aren't in a basic block, so base the cost on
5823 the dispatch insn. If we select this location, we will
5824 still put the pool after the table. */
5825 new_cost = arm_barrier_cost (from);
5826
5827 if (count < max_count && new_cost <= selected_cost)
5828 {
5829 selected = tmp;
5830 selected_cost = new_cost;
5831 selected_address = fix->address + count;
5832 }
5833
5834 /* Continue after the dispatch table. */
5835 from = NEXT_INSN (tmp);
5836 continue;
5837 }
5838
5839 new_cost = arm_barrier_cost (from);
5840
5841 if (count < max_count && new_cost <= selected_cost)
5842 {
5843 selected = from;
5844 selected_cost = new_cost;
5845 selected_address = fix->address + count;
5846 }
5847
5848 from = NEXT_INSN (from);
5849 }
5850
5851 /* Create a new JUMP_INSN that branches around a barrier. */
5852 from = emit_jump_insn_after (gen_jump (label), selected);
5853 JUMP_LABEL (from) = label;
5854 barrier = emit_barrier_after (from);
5855 emit_label_after (label, barrier);
5856
5857 /* Create a minipool barrier entry for the new barrier. */
c7319d87 5858 new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* new_fix));
d5b7b3ae
RE
5859 new_fix->insn = barrier;
5860 new_fix->address = selected_address;
5861 new_fix->next = fix->next;
5862 fix->next = new_fix;
5863
5864 return new_fix;
5865}
5866
5867/* Record that there is a natural barrier in the insn stream at
5868 ADDRESS. */
949d79eb
RE
5869static void
5870push_minipool_barrier (insn, address)
2b835d68 5871 rtx insn;
d5b7b3ae 5872 HOST_WIDE_INT address;
2b835d68 5873{
c7319d87 5874 Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
ad076f4e 5875
949d79eb
RE
5876 fix->insn = insn;
5877 fix->address = address;
2b835d68 5878
949d79eb
RE
5879 fix->next = NULL;
5880 if (minipool_fix_head != NULL)
5881 minipool_fix_tail->next = fix;
5882 else
5883 minipool_fix_head = fix;
5884
5885 minipool_fix_tail = fix;
5886}
2b835d68 5887
d5b7b3ae
RE
5888/* Record INSN, which will need fixing up to load a value from the
5889 minipool. ADDRESS is the offset of the insn since the start of the
5890 function; LOC is a pointer to the part of the insn which requires
5891 fixing; VALUE is the constant that must be loaded, which is of type
5892 MODE. */
949d79eb
RE
5893static void
5894push_minipool_fix (insn, address, loc, mode, value)
5895 rtx insn;
d5b7b3ae
RE
5896 HOST_WIDE_INT address;
5897 rtx * loc;
949d79eb
RE
5898 enum machine_mode mode;
5899 rtx value;
5900{
c7319d87 5901 Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
949d79eb
RE
5902
5903#ifdef AOF_ASSEMBLER
5904 /* PIC symbol refereneces need to be converted into offsets into the
5905 based area. */
d5b7b3ae
RE
5906 /* XXX This shouldn't be done here. */
5907 if (flag_pic && GET_CODE (value) == SYMBOL_REF)
949d79eb
RE
5908 value = aof_pic_entry (value);
5909#endif /* AOF_ASSEMBLER */
5910
5911 fix->insn = insn;
5912 fix->address = address;
5913 fix->loc = loc;
5914 fix->mode = mode;
d5b7b3ae 5915 fix->fix_size = MINIPOOL_FIX_SIZE (mode);
949d79eb 5916 fix->value = value;
d5b7b3ae
RE
5917 fix->forwards = get_attr_pool_range (insn);
5918 fix->backwards = get_attr_neg_pool_range (insn);
5919 fix->minipool = NULL;
949d79eb
RE
5920
5921 /* If an insn doesn't have a range defined for it, then it isn't
5922 expecting to be reworked by this code. Better to abort now than
5923 to generate duff assembly code. */
d5b7b3ae 5924 if (fix->forwards == 0 && fix->backwards == 0)
949d79eb
RE
5925 abort ();
5926
d5b7b3ae
RE
5927 if (rtl_dump_file)
5928 {
5929 fprintf (rtl_dump_file,
5930 ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ",
5931 GET_MODE_NAME (mode),
5932 INSN_UID (insn), (unsigned long) address,
5933 -1 * (long)fix->backwards, (long)fix->forwards);
5934 arm_print_value (rtl_dump_file, fix->value);
5935 fprintf (rtl_dump_file, "\n");
5936 }
5937
6354dc9b 5938 /* Add it to the chain of fixes. */
949d79eb 5939 fix->next = NULL;
d5b7b3ae 5940
949d79eb
RE
5941 if (minipool_fix_head != NULL)
5942 minipool_fix_tail->next = fix;
5943 else
5944 minipool_fix_head = fix;
5945
5946 minipool_fix_tail = fix;
5947}
5948
d5b7b3ae 5949/* Scan INSN and note any of its operands that need fixing. */
949d79eb
RE
5950static void
5951note_invalid_constants (insn, address)
5952 rtx insn;
d5b7b3ae 5953 HOST_WIDE_INT address;
949d79eb
RE
5954{
5955 int opno;
5956
d5b7b3ae 5957 extract_insn (insn);
949d79eb 5958
5895f793 5959 if (!constrain_operands (1))
949d79eb
RE
5960 fatal_insn_not_found (insn);
5961
d5b7b3ae
RE
5962 /* Fill in recog_op_alt with information about the constraints of this
5963 insn. */
949d79eb
RE
5964 preprocess_constraints ();
5965
1ccbefce 5966 for (opno = 0; opno < recog_data.n_operands; opno++)
949d79eb 5967 {
6354dc9b 5968 /* Things we need to fix can only occur in inputs. */
36ab44c7 5969 if (recog_data.operand_type[opno] != OP_IN)
949d79eb
RE
5970 continue;
5971
5972 /* If this alternative is a memory reference, then any mention
5973 of constants in this alternative is really to fool reload
5974 into allowing us to accept one there. We need to fix them up
5975 now so that we output the right code. */
5976 if (recog_op_alt[opno][which_alternative].memory_ok)
5977 {
1ccbefce 5978 rtx op = recog_data.operand[opno];
949d79eb
RE
5979
5980 if (CONSTANT_P (op))
1ccbefce
RH
5981 push_minipool_fix (insn, address, recog_data.operand_loc[opno],
5982 recog_data.operand_mode[opno], op);
d5b7b3ae
RE
5983#if 0
5984 /* RWE: Now we look correctly at the operands for the insn,
5985 this shouldn't be needed any more. */
949d79eb 5986#ifndef AOF_ASSEMBLER
d5b7b3ae 5987 /* XXX Is this still needed? */
b15bca31 5988 else if (GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_PIC_SYM)
1ccbefce
RH
5989 push_minipool_fix (insn, address, recog_data.operand_loc[opno],
5990 recog_data.operand_mode[opno],
5991 XVECEXP (op, 0, 0));
949d79eb 5992#endif
d5b7b3ae
RE
5993#endif
5994 else if (GET_CODE (op) == MEM
949d79eb
RE
5995 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
5996 && CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
1ccbefce
RH
5997 push_minipool_fix (insn, address, recog_data.operand_loc[opno],
5998 recog_data.operand_mode[opno],
949d79eb
RE
5999 get_pool_constant (XEXP (op, 0)));
6000 }
2b835d68 6001 }
2b835d68
RE
6002}
6003
6004void
6005arm_reorg (first)
6006 rtx first;
6007{
6008 rtx insn;
d5b7b3ae
RE
6009 HOST_WIDE_INT address = 0;
6010 Mfix * fix;
ad076f4e 6011
949d79eb 6012 minipool_fix_head = minipool_fix_tail = NULL;
2b835d68 6013
949d79eb
RE
6014 /* The first insn must always be a note, or the code below won't
6015 scan it properly. */
6016 if (GET_CODE (first) != NOTE)
6017 abort ();
6018
6019 /* Scan all the insns and record the operands that will need fixing. */
6020 for (insn = next_nonnote_insn (first); insn; insn = next_nonnote_insn (insn))
2b835d68 6021 {
949d79eb 6022 if (GET_CODE (insn) == BARRIER)
d5b7b3ae 6023 push_minipool_barrier (insn, address);
949d79eb
RE
6024 else if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
6025 || GET_CODE (insn) == JUMP_INSN)
6026 {
6027 rtx table;
6028
6029 note_invalid_constants (insn, address);
6030 address += get_attr_length (insn);
d5b7b3ae 6031
949d79eb
RE
6032 /* If the insn is a vector jump, add the size of the table
6033 and skip the table. */
d5b7b3ae 6034 if ((table = is_jump_table (insn)) != NULL)
2b835d68 6035 {
d5b7b3ae 6036 address += get_jump_table_size (table);
949d79eb
RE
6037 insn = table;
6038 }
6039 }
6040 }
332072db 6041
d5b7b3ae
RE
6042 fix = minipool_fix_head;
6043
949d79eb 6044 /* Now scan the fixups and perform the required changes. */
d5b7b3ae 6045 while (fix)
949d79eb 6046 {
d5b7b3ae
RE
6047 Mfix * ftmp;
6048 Mfix * fdel;
6049 Mfix * last_added_fix;
6050 Mfix * last_barrier = NULL;
6051 Mfix * this_fix;
949d79eb
RE
6052
6053 /* Skip any further barriers before the next fix. */
6054 while (fix && GET_CODE (fix->insn) == BARRIER)
6055 fix = fix->next;
6056
d5b7b3ae 6057 /* No more fixes. */
949d79eb
RE
6058 if (fix == NULL)
6059 break;
332072db 6060
d5b7b3ae 6061 last_added_fix = NULL;
2b835d68 6062
d5b7b3ae 6063 for (ftmp = fix; ftmp; ftmp = ftmp->next)
949d79eb 6064 {
949d79eb 6065 if (GET_CODE (ftmp->insn) == BARRIER)
949d79eb 6066 {
d5b7b3ae
RE
6067 if (ftmp->address >= minipool_vector_head->max_address)
6068 break;
2b835d68 6069
d5b7b3ae 6070 last_barrier = ftmp;
2b835d68 6071 }
d5b7b3ae
RE
6072 else if ((ftmp->minipool = add_minipool_forward_ref (ftmp)) == NULL)
6073 break;
6074
6075 last_added_fix = ftmp; /* Keep track of the last fix added. */
2b835d68 6076 }
949d79eb 6077
d5b7b3ae
RE
6078 /* If we found a barrier, drop back to that; any fixes that we
6079 could have reached but come after the barrier will now go in
6080 the next mini-pool. */
949d79eb
RE
6081 if (last_barrier != NULL)
6082 {
d5b7b3ae
RE
6083 /* Reduce the refcount for those fixes that won't go into this
6084 pool after all. */
6085 for (fdel = last_barrier->next;
6086 fdel && fdel != ftmp;
6087 fdel = fdel->next)
6088 {
6089 fdel->minipool->refcount--;
6090 fdel->minipool = NULL;
6091 }
6092
949d79eb
RE
6093 ftmp = last_barrier;
6094 }
6095 else
2bfa88dc 6096 {
d5b7b3ae
RE
6097 /* ftmp is first fix that we can't fit into this pool and
6098 there no natural barriers that we could use. Insert a
6099 new barrier in the code somewhere between the previous
6100 fix and this one, and arrange to jump around it. */
6101 HOST_WIDE_INT max_address;
6102
6103 /* The last item on the list of fixes must be a barrier, so
6104 we can never run off the end of the list of fixes without
6105 last_barrier being set. */
6106 if (ftmp == NULL)
6107 abort ();
6108
6109 max_address = minipool_vector_head->max_address;
2bfa88dc
RE
6110 /* Check that there isn't another fix that is in range that
6111 we couldn't fit into this pool because the pool was
6112 already too large: we need to put the pool before such an
6113 instruction. */
d5b7b3ae
RE
6114 if (ftmp->address < max_address)
6115 max_address = ftmp->address;
6116
6117 last_barrier = create_fix_barrier (last_added_fix, max_address);
6118 }
6119
6120 assign_minipool_offsets (last_barrier);
6121
6122 while (ftmp)
6123 {
6124 if (GET_CODE (ftmp->insn) != BARRIER
6125 && ((ftmp->minipool = add_minipool_backward_ref (ftmp))
6126 == NULL))
6127 break;
2bfa88dc 6128
d5b7b3ae 6129 ftmp = ftmp->next;
2bfa88dc 6130 }
949d79eb
RE
6131
6132 /* Scan over the fixes we have identified for this pool, fixing them
6133 up and adding the constants to the pool itself. */
d5b7b3ae 6134 for (this_fix = fix; this_fix && ftmp != this_fix;
949d79eb
RE
6135 this_fix = this_fix->next)
6136 if (GET_CODE (this_fix->insn) != BARRIER)
6137 {
949d79eb
RE
6138 rtx addr
6139 = plus_constant (gen_rtx_LABEL_REF (VOIDmode,
6140 minipool_vector_label),
d5b7b3ae 6141 this_fix->minipool->offset);
949d79eb
RE
6142 *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr);
6143 }
6144
d5b7b3ae 6145 dump_minipool (last_barrier->insn);
949d79eb 6146 fix = ftmp;
2b835d68 6147 }
4b632bf1 6148
949d79eb
RE
6149 /* From now on we must synthesize any constants that we can't handle
6150 directly. This can happen if the RTL gets split during final
6151 instruction generation. */
4b632bf1 6152 after_arm_reorg = 1;
c7319d87
RE
6153
6154 /* Free the minipool memory. */
6155 obstack_free (&minipool_obstack, minipool_startobj);
2b835d68 6156}
cce8749e
CH
6157\f
6158/* Routines to output assembly language. */
6159
f3bb6135 6160/* If the rtx is the correct value then return the string of the number.
ff9940b0 6161 In this way we can ensure that valid double constants are generated even
6354dc9b 6162 when cross compiling. */
cd2b33d0 6163const char *
ff9940b0 6164fp_immediate_constant (x)
b5cc037f 6165 rtx x;
ff9940b0
RE
6166{
6167 REAL_VALUE_TYPE r;
6168 int i;
6169
6170 if (!fpa_consts_inited)
6171 init_fpa_table ();
6172
6173 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
6174 for (i = 0; i < 8; i++)
6175 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
6176 return strings_fpa[i];
f3bb6135 6177
ff9940b0
RE
6178 abort ();
6179}
6180
9997d19d 6181/* As for fp_immediate_constant, but value is passed directly, not in rtx. */
cd2b33d0 6182static const char *
9997d19d 6183fp_const_from_val (r)
62b10bbc 6184 REAL_VALUE_TYPE * r;
9997d19d
RE
6185{
6186 int i;
6187
5895f793 6188 if (!fpa_consts_inited)
9997d19d
RE
6189 init_fpa_table ();
6190
6191 for (i = 0; i < 8; i++)
6192 if (REAL_VALUES_EQUAL (*r, values_fpa[i]))
6193 return strings_fpa[i];
6194
6195 abort ();
6196}
ff9940b0 6197
cce8749e
CH
6198/* Output the operands of a LDM/STM instruction to STREAM.
6199 MASK is the ARM register set mask of which only bits 0-15 are important.
6d3d9133
NC
6200 REG is the base register, either the frame pointer or the stack pointer,
6201 INSTR is the possibly suffixed load or store instruction. */
cce8749e 6202
d5b7b3ae 6203static void
6d3d9133 6204print_multi_reg (stream, instr, reg, mask)
62b10bbc 6205 FILE * stream;
cd2b33d0 6206 const char * instr;
dd18ae56
NC
6207 int reg;
6208 int mask;
cce8749e
CH
6209{
6210 int i;
6211 int not_first = FALSE;
6212
1d5473cb 6213 fputc ('\t', stream);
dd18ae56 6214 asm_fprintf (stream, instr, reg);
1d5473cb 6215 fputs (", {", stream);
62b10bbc 6216
d5b7b3ae 6217 for (i = 0; i <= LAST_ARM_REGNUM; i++)
cce8749e
CH
6218 if (mask & (1 << i))
6219 {
6220 if (not_first)
6221 fprintf (stream, ", ");
62b10bbc 6222
dd18ae56 6223 asm_fprintf (stream, "%r", i);
cce8749e
CH
6224 not_first = TRUE;
6225 }
f3bb6135 6226
6d3d9133 6227 fprintf (stream, "}%s\n", TARGET_APCS_32 ? "" : "^");
f3bb6135 6228}
cce8749e 6229
6354dc9b 6230/* Output a 'call' insn. */
cce8749e 6231
cd2b33d0 6232const char *
cce8749e 6233output_call (operands)
62b10bbc 6234 rtx * operands;
cce8749e 6235{
6354dc9b 6236 /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
cce8749e 6237
62b10bbc 6238 if (REGNO (operands[0]) == LR_REGNUM)
cce8749e 6239 {
62b10bbc 6240 operands[0] = gen_rtx_REG (SImode, IP_REGNUM);
1d5473cb 6241 output_asm_insn ("mov%?\t%0, %|lr", operands);
cce8749e 6242 }
62b10bbc 6243
1d5473cb 6244 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
da6558fd 6245
6cfc7210 6246 if (TARGET_INTERWORK)
da6558fd
NC
6247 output_asm_insn ("bx%?\t%0", operands);
6248 else
6249 output_asm_insn ("mov%?\t%|pc, %0", operands);
6250
f3bb6135
RE
6251 return "";
6252}
cce8749e 6253
ff9940b0
RE
6254static int
6255eliminate_lr2ip (x)
62b10bbc 6256 rtx * x;
ff9940b0
RE
6257{
6258 int something_changed = 0;
62b10bbc 6259 rtx x0 = * x;
ff9940b0
RE
6260 int code = GET_CODE (x0);
6261 register int i, j;
6f7d635c 6262 register const char * fmt;
ff9940b0
RE
6263
6264 switch (code)
6265 {
6266 case REG:
62b10bbc 6267 if (REGNO (x0) == LR_REGNUM)
ff9940b0 6268 {
62b10bbc 6269 *x = gen_rtx_REG (SImode, IP_REGNUM);
ff9940b0
RE
6270 return 1;
6271 }
6272 return 0;
6273 default:
6354dc9b 6274 /* Scan through the sub-elements and change any references there. */
ff9940b0 6275 fmt = GET_RTX_FORMAT (code);
62b10bbc 6276
ff9940b0
RE
6277 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
6278 if (fmt[i] == 'e')
6279 something_changed |= eliminate_lr2ip (&XEXP (x0, i));
6280 else if (fmt[i] == 'E')
6281 for (j = 0; j < XVECLEN (x0, i); j++)
6282 something_changed |= eliminate_lr2ip (&XVECEXP (x0, i, j));
62b10bbc 6283
ff9940b0
RE
6284 return something_changed;
6285 }
6286}
6287
6354dc9b 6288/* Output a 'call' insn that is a reference in memory. */
ff9940b0 6289
cd2b33d0 6290const char *
ff9940b0 6291output_call_mem (operands)
62b10bbc 6292 rtx * operands;
ff9940b0 6293{
6354dc9b
NC
6294 operands[0] = copy_rtx (operands[0]); /* Be ultra careful. */
6295 /* Handle calls using lr by using ip (which may be clobbered in subr anyway). */
ff9940b0 6296 if (eliminate_lr2ip (&operands[0]))
1d5473cb 6297 output_asm_insn ("mov%?\t%|ip, %|lr", operands);
f3bb6135 6298
6cfc7210 6299 if (TARGET_INTERWORK)
da6558fd
NC
6300 {
6301 output_asm_insn ("ldr%?\t%|ip, %0", operands);
6302 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
6303 output_asm_insn ("bx%?\t%|ip", operands);
6304 }
6305 else
6306 {
6307 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
6308 output_asm_insn ("ldr%?\t%|pc, %0", operands);
6309 }
6310
f3bb6135
RE
6311 return "";
6312}
ff9940b0
RE
6313
6314
6315/* Output a move from arm registers to an fpu registers.
6316 OPERANDS[0] is an fpu register.
6317 OPERANDS[1] is the first registers of an arm register pair. */
6318
cd2b33d0 6319const char *
ff9940b0 6320output_mov_long_double_fpu_from_arm (operands)
62b10bbc 6321 rtx * operands;
ff9940b0
RE
6322{
6323 int arm_reg0 = REGNO (operands[1]);
6324 rtx ops[3];
6325
62b10bbc
NC
6326 if (arm_reg0 == IP_REGNUM)
6327 abort ();
f3bb6135 6328
43cffd11
RE
6329 ops[0] = gen_rtx_REG (SImode, arm_reg0);
6330 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
6331 ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
ff9940b0 6332
1d5473cb
RE
6333 output_asm_insn ("stm%?fd\t%|sp!, {%0, %1, %2}", ops);
6334 output_asm_insn ("ldf%?e\t%0, [%|sp], #12", operands);
62b10bbc 6335
f3bb6135
RE
6336 return "";
6337}
ff9940b0
RE
6338
6339/* Output a move from an fpu register to arm registers.
6340 OPERANDS[0] is the first registers of an arm register pair.
6341 OPERANDS[1] is an fpu register. */
6342
cd2b33d0 6343const char *
ff9940b0 6344output_mov_long_double_arm_from_fpu (operands)
62b10bbc 6345 rtx * operands;
ff9940b0
RE
6346{
6347 int arm_reg0 = REGNO (operands[0]);
6348 rtx ops[3];
6349
62b10bbc
NC
6350 if (arm_reg0 == IP_REGNUM)
6351 abort ();
f3bb6135 6352
43cffd11
RE
6353 ops[0] = gen_rtx_REG (SImode, arm_reg0);
6354 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
6355 ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
ff9940b0 6356
1d5473cb
RE
6357 output_asm_insn ("stf%?e\t%1, [%|sp, #-12]!", operands);
6358 output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1, %2}", ops);
f3bb6135
RE
6359 return "";
6360}
ff9940b0
RE
6361
6362/* Output a move from arm registers to arm registers of a long double
6363 OPERANDS[0] is the destination.
6364 OPERANDS[1] is the source. */
cd2b33d0 6365const char *
ff9940b0 6366output_mov_long_double_arm_from_arm (operands)
62b10bbc 6367 rtx * operands;
ff9940b0 6368{
6354dc9b 6369 /* We have to be careful here because the two might overlap. */
ff9940b0
RE
6370 int dest_start = REGNO (operands[0]);
6371 int src_start = REGNO (operands[1]);
6372 rtx ops[2];
6373 int i;
6374
6375 if (dest_start < src_start)
6376 {
6377 for (i = 0; i < 3; i++)
6378 {
43cffd11
RE
6379 ops[0] = gen_rtx_REG (SImode, dest_start + i);
6380 ops[1] = gen_rtx_REG (SImode, src_start + i);
9997d19d 6381 output_asm_insn ("mov%?\t%0, %1", ops);
ff9940b0
RE
6382 }
6383 }
6384 else
6385 {
6386 for (i = 2; i >= 0; i--)
6387 {
43cffd11
RE
6388 ops[0] = gen_rtx_REG (SImode, dest_start + i);
6389 ops[1] = gen_rtx_REG (SImode, src_start + i);
9997d19d 6390 output_asm_insn ("mov%?\t%0, %1", ops);
ff9940b0
RE
6391 }
6392 }
f3bb6135 6393
ff9940b0
RE
6394 return "";
6395}
6396
6397
cce8749e
CH
6398/* Output a move from arm registers to an fpu registers.
6399 OPERANDS[0] is an fpu register.
6400 OPERANDS[1] is the first registers of an arm register pair. */
6401
cd2b33d0 6402const char *
cce8749e 6403output_mov_double_fpu_from_arm (operands)
62b10bbc 6404 rtx * operands;
cce8749e
CH
6405{
6406 int arm_reg0 = REGNO (operands[1]);
6407 rtx ops[2];
6408
62b10bbc
NC
6409 if (arm_reg0 == IP_REGNUM)
6410 abort ();
6411
43cffd11
RE
6412 ops[0] = gen_rtx_REG (SImode, arm_reg0);
6413 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
1d5473cb
RE
6414 output_asm_insn ("stm%?fd\t%|sp!, {%0, %1}", ops);
6415 output_asm_insn ("ldf%?d\t%0, [%|sp], #8", operands);
f3bb6135
RE
6416 return "";
6417}
cce8749e
CH
6418
6419/* Output a move from an fpu register to arm registers.
6420 OPERANDS[0] is the first registers of an arm register pair.
6421 OPERANDS[1] is an fpu register. */
6422
cd2b33d0 6423const char *
cce8749e 6424output_mov_double_arm_from_fpu (operands)
62b10bbc 6425 rtx * operands;
cce8749e
CH
6426{
6427 int arm_reg0 = REGNO (operands[0]);
6428 rtx ops[2];
6429
62b10bbc
NC
6430 if (arm_reg0 == IP_REGNUM)
6431 abort ();
f3bb6135 6432
43cffd11
RE
6433 ops[0] = gen_rtx_REG (SImode, arm_reg0);
6434 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
1d5473cb
RE
6435 output_asm_insn ("stf%?d\t%1, [%|sp, #-8]!", operands);
6436 output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1}", ops);
f3bb6135
RE
6437 return "";
6438}
cce8749e
CH
6439
6440/* Output a move between double words.
6441 It must be REG<-REG, REG<-CONST_DOUBLE, REG<-CONST_INT, REG<-MEM
6442 or MEM<-REG and all MEMs must be offsettable addresses. */
6443
cd2b33d0 6444const char *
cce8749e 6445output_move_double (operands)
aec3cfba 6446 rtx * operands;
cce8749e
CH
6447{
6448 enum rtx_code code0 = GET_CODE (operands[0]);
6449 enum rtx_code code1 = GET_CODE (operands[1]);
56636818 6450 rtx otherops[3];
cce8749e
CH
6451
6452 if (code0 == REG)
6453 {
6454 int reg0 = REGNO (operands[0]);
6455
43cffd11 6456 otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
aec3cfba 6457
cce8749e
CH
6458 if (code1 == REG)
6459 {
6460 int reg1 = REGNO (operands[1]);
62b10bbc
NC
6461 if (reg1 == IP_REGNUM)
6462 abort ();
f3bb6135 6463
6354dc9b 6464 /* Ensure the second source is not overwritten. */
c1c2bc04 6465 if (reg1 == reg0 + (WORDS_BIG_ENDIAN ? -1 : 1))
6cfc7210 6466 output_asm_insn ("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands);
cce8749e 6467 else
6cfc7210 6468 output_asm_insn ("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
cce8749e
CH
6469 }
6470 else if (code1 == CONST_DOUBLE)
6471 {
226a5051
RE
6472 if (GET_MODE (operands[1]) == DFmode)
6473 {
6474 long l[2];
6475 union real_extract u;
6476
4e135bdd 6477 memcpy (&u, &CONST_DOUBLE_LOW (operands[1]), sizeof (u));
226a5051 6478 REAL_VALUE_TO_TARGET_DOUBLE (u.d, l);
d5b7b3ae
RE
6479 otherops[1] = GEN_INT (l[1]);
6480 operands[1] = GEN_INT (l[0]);
226a5051 6481 }
c1c2bc04
RE
6482 else if (GET_MODE (operands[1]) != VOIDmode)
6483 abort ();
6484 else if (WORDS_BIG_ENDIAN)
6485 {
6486
6487 otherops[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
6488 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
6489 }
226a5051
RE
6490 else
6491 {
c1c2bc04 6492
226a5051
RE
6493 otherops[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
6494 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
6495 }
6cfc7210 6496
c1c2bc04
RE
6497 output_mov_immediate (operands);
6498 output_mov_immediate (otherops);
cce8749e
CH
6499 }
6500 else if (code1 == CONST_INT)
6501 {
56636818
JL
6502#if HOST_BITS_PER_WIDE_INT > 32
6503 /* If HOST_WIDE_INT is more than 32 bits, the intval tells us
6504 what the upper word is. */
6505 if (WORDS_BIG_ENDIAN)
6506 {
6507 otherops[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
6508 operands[1] = GEN_INT (INTVAL (operands[1]) >> 32);
6509 }
6510 else
6511 {
6512 otherops[1] = GEN_INT (INTVAL (operands[1]) >> 32);
6513 operands[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
6514 }
6515#else
6354dc9b 6516 /* Sign extend the intval into the high-order word. */
c1c2bc04
RE
6517 if (WORDS_BIG_ENDIAN)
6518 {
6519 otherops[1] = operands[1];
6520 operands[1] = (INTVAL (operands[1]) < 0
6521 ? constm1_rtx : const0_rtx);
6522 }
ff9940b0 6523 else
c1c2bc04 6524 otherops[1] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
56636818 6525#endif
c1c2bc04
RE
6526 output_mov_immediate (otherops);
6527 output_mov_immediate (operands);
cce8749e
CH
6528 }
6529 else if (code1 == MEM)
6530 {
ff9940b0 6531 switch (GET_CODE (XEXP (operands[1], 0)))
cce8749e 6532 {
ff9940b0 6533 case REG:
9997d19d 6534 output_asm_insn ("ldm%?ia\t%m1, %M0", operands);
ff9940b0 6535 break;
2b835d68 6536
ff9940b0 6537 case PRE_INC:
6354dc9b 6538 abort (); /* Should never happen now. */
ff9940b0 6539 break;
2b835d68 6540
ff9940b0 6541 case PRE_DEC:
2b835d68 6542 output_asm_insn ("ldm%?db\t%m1!, %M0", operands);
ff9940b0 6543 break;
2b835d68 6544
ff9940b0 6545 case POST_INC:
9997d19d 6546 output_asm_insn ("ldm%?ia\t%m1!, %M0", operands);
ff9940b0 6547 break;
2b835d68 6548
ff9940b0 6549 case POST_DEC:
6354dc9b 6550 abort (); /* Should never happen now. */
ff9940b0 6551 break;
2b835d68
RE
6552
6553 case LABEL_REF:
6554 case CONST:
6555 output_asm_insn ("adr%?\t%0, %1", operands);
6556 output_asm_insn ("ldm%?ia\t%0, %M0", operands);
6557 break;
6558
ff9940b0 6559 default:
aec3cfba
NC
6560 if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1),
6561 GET_MODE (XEXP (XEXP (operands[1], 0), 1))))
cce8749e 6562 {
2b835d68
RE
6563 otherops[0] = operands[0];
6564 otherops[1] = XEXP (XEXP (operands[1], 0), 0);
6565 otherops[2] = XEXP (XEXP (operands[1], 0), 1);
6566 if (GET_CODE (XEXP (operands[1], 0)) == PLUS)
6567 {
6568 if (GET_CODE (otherops[2]) == CONST_INT)
6569 {
6570 switch (INTVAL (otherops[2]))
6571 {
6572 case -8:
6573 output_asm_insn ("ldm%?db\t%1, %M0", otherops);
6574 return "";
6575 case -4:
6576 output_asm_insn ("ldm%?da\t%1, %M0", otherops);
6577 return "";
6578 case 4:
6579 output_asm_insn ("ldm%?ib\t%1, %M0", otherops);
6580 return "";
6581 }
6582 if (!(const_ok_for_arm (INTVAL (otherops[2]))))
6583 output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
6584 else
6585 output_asm_insn ("add%?\t%0, %1, %2", otherops);
6586 }
6587 else
6588 output_asm_insn ("add%?\t%0, %1, %2", otherops);
6589 }
6590 else
6591 output_asm_insn ("sub%?\t%0, %1, %2", otherops);
6cfc7210 6592
2b835d68
RE
6593 return "ldm%?ia\t%0, %M0";
6594 }
6595 else
6596 {
b72f00af 6597 otherops[1] = adjust_address (operands[1], VOIDmode, 4);
2b835d68
RE
6598 /* Take care of overlapping base/data reg. */
6599 if (reg_mentioned_p (operands[0], operands[1]))
6600 {
6601 output_asm_insn ("ldr%?\t%0, %1", otherops);
6602 output_asm_insn ("ldr%?\t%0, %1", operands);
6603 }
6604 else
6605 {
6606 output_asm_insn ("ldr%?\t%0, %1", operands);
6607 output_asm_insn ("ldr%?\t%0, %1", otherops);
6608 }
cce8749e
CH
6609 }
6610 }
6611 }
2b835d68 6612 else
6354dc9b 6613 abort (); /* Constraints should prevent this. */
cce8749e
CH
6614 }
6615 else if (code0 == MEM && code1 == REG)
6616 {
62b10bbc
NC
6617 if (REGNO (operands[1]) == IP_REGNUM)
6618 abort ();
2b835d68 6619
ff9940b0
RE
6620 switch (GET_CODE (XEXP (operands[0], 0)))
6621 {
6622 case REG:
9997d19d 6623 output_asm_insn ("stm%?ia\t%m0, %M1", operands);
ff9940b0 6624 break;
2b835d68 6625
ff9940b0 6626 case PRE_INC:
6354dc9b 6627 abort (); /* Should never happen now. */
ff9940b0 6628 break;
2b835d68 6629
ff9940b0 6630 case PRE_DEC:
2b835d68 6631 output_asm_insn ("stm%?db\t%m0!, %M1", operands);
ff9940b0 6632 break;
2b835d68 6633
ff9940b0 6634 case POST_INC:
9997d19d 6635 output_asm_insn ("stm%?ia\t%m0!, %M1", operands);
ff9940b0 6636 break;
2b835d68 6637
ff9940b0 6638 case POST_DEC:
6354dc9b 6639 abort (); /* Should never happen now. */
ff9940b0 6640 break;
2b835d68
RE
6641
6642 case PLUS:
6643 if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
6644 {
6645 switch (INTVAL (XEXP (XEXP (operands[0], 0), 1)))
6646 {
6647 case -8:
6648 output_asm_insn ("stm%?db\t%m0, %M1", operands);
6649 return "";
6650
6651 case -4:
6652 output_asm_insn ("stm%?da\t%m0, %M1", operands);
6653 return "";
6654
6655 case 4:
6656 output_asm_insn ("stm%?ib\t%m0, %M1", operands);
6657 return "";
6658 }
6659 }
6660 /* Fall through */
6661
ff9940b0 6662 default:
b72f00af 6663 otherops[0] = adjust_address (operands[0], VOIDmode, 4);
43cffd11 6664 otherops[1] = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
9997d19d
RE
6665 output_asm_insn ("str%?\t%1, %0", operands);
6666 output_asm_insn ("str%?\t%1, %0", otherops);
cce8749e
CH
6667 }
6668 }
2b835d68 6669 else
62b10bbc 6670 abort (); /* Constraints should prevent this */
cce8749e 6671
9997d19d
RE
6672 return "";
6673}
cce8749e
CH
6674
6675
6676/* Output an arbitrary MOV reg, #n.
6677 OPERANDS[0] is a register. OPERANDS[1] is a const_int. */
6678
cd2b33d0 6679const char *
cce8749e 6680output_mov_immediate (operands)
62b10bbc 6681 rtx * operands;
cce8749e 6682{
f3bb6135 6683 HOST_WIDE_INT n = INTVAL (operands[1]);
cce8749e
CH
6684 int n_ones = 0;
6685 int i;
6686
6687 /* Try to use one MOV */
cce8749e 6688 if (const_ok_for_arm (n))
f3bb6135 6689 {
9997d19d 6690 output_asm_insn ("mov%?\t%0, %1", operands);
f3bb6135
RE
6691 return "";
6692 }
cce8749e
CH
6693
6694 /* Try to use one MVN */
f3bb6135 6695 if (const_ok_for_arm (~n))
cce8749e 6696 {
f3bb6135 6697 operands[1] = GEN_INT (~n);
9997d19d 6698 output_asm_insn ("mvn%?\t%0, %1", operands);
f3bb6135 6699 return "";
cce8749e
CH
6700 }
6701
6354dc9b 6702 /* If all else fails, make it out of ORRs or BICs as appropriate. */
cce8749e
CH
6703
6704 for (i=0; i < 32; i++)
6705 if (n & 1 << i)
6706 n_ones++;
6707
6354dc9b 6708 if (n_ones > 16) /* Shorter to use MVN with BIC in this case. */
e5951263 6709 output_multi_immediate (operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1, ~n);
cce8749e 6710 else
d5b7b3ae 6711 output_multi_immediate (operands, "mov%?\t%0, %1", "orr%?\t%0, %0, %1", 1, n);
f3bb6135
RE
6712
6713 return "";
6714}
cce8749e
CH
6715
6716
6717/* Output an ADD r, s, #n where n may be too big for one instruction. If
6718 adding zero to one register, output nothing. */
6719
cd2b33d0 6720const char *
cce8749e 6721output_add_immediate (operands)
62b10bbc 6722 rtx * operands;
cce8749e 6723{
f3bb6135 6724 HOST_WIDE_INT n = INTVAL (operands[2]);
cce8749e
CH
6725
6726 if (n != 0 || REGNO (operands[0]) != REGNO (operands[1]))
6727 {
6728 if (n < 0)
6729 output_multi_immediate (operands,
9997d19d
RE
6730 "sub%?\t%0, %1, %2", "sub%?\t%0, %0, %2", 2,
6731 -n);
cce8749e
CH
6732 else
6733 output_multi_immediate (operands,
9997d19d
RE
6734 "add%?\t%0, %1, %2", "add%?\t%0, %0, %2", 2,
6735 n);
cce8749e 6736 }
f3bb6135
RE
6737
6738 return "";
6739}
cce8749e 6740
cce8749e
CH
6741/* Output a multiple immediate operation.
6742 OPERANDS is the vector of operands referred to in the output patterns.
6743 INSTR1 is the output pattern to use for the first constant.
6744 INSTR2 is the output pattern to use for subsequent constants.
6745 IMMED_OP is the index of the constant slot in OPERANDS.
6746 N is the constant value. */
6747
cd2b33d0 6748static const char *
cce8749e 6749output_multi_immediate (operands, instr1, instr2, immed_op, n)
62b10bbc 6750 rtx * operands;
cd2b33d0
NC
6751 const char * instr1;
6752 const char * instr2;
f3bb6135
RE
6753 int immed_op;
6754 HOST_WIDE_INT n;
cce8749e 6755{
f3bb6135 6756#if HOST_BITS_PER_WIDE_INT > 32
30cf4896 6757 n &= 0xffffffff;
f3bb6135
RE
6758#endif
6759
cce8749e
CH
6760 if (n == 0)
6761 {
6762 operands[immed_op] = const0_rtx;
6354dc9b 6763 output_asm_insn (instr1, operands); /* Quick and easy output. */
cce8749e
CH
6764 }
6765 else
6766 {
6767 int i;
cd2b33d0 6768 const char * instr = instr1;
cce8749e 6769
6354dc9b 6770 /* Note that n is never zero here (which would give no output). */
cce8749e
CH
6771 for (i = 0; i < 32; i += 2)
6772 {
6773 if (n & (3 << i))
6774 {
f3bb6135
RE
6775 operands[immed_op] = GEN_INT (n & (255 << i));
6776 output_asm_insn (instr, operands);
cce8749e
CH
6777 instr = instr2;
6778 i += 6;
6779 }
6780 }
6781 }
cd2b33d0 6782
f3bb6135 6783 return "";
9997d19d 6784}
cce8749e
CH
6785
6786
6787/* Return the appropriate ARM instruction for the operation code.
6788 The returned result should not be overwritten. OP is the rtx of the
6789 operation. SHIFT_FIRST_ARG is TRUE if the first argument of the operator
6790 was shifted. */
6791
cd2b33d0 6792const char *
cce8749e
CH
6793arithmetic_instr (op, shift_first_arg)
6794 rtx op;
f3bb6135 6795 int shift_first_arg;
cce8749e 6796{
9997d19d 6797 switch (GET_CODE (op))
cce8749e
CH
6798 {
6799 case PLUS:
f3bb6135
RE
6800 return "add";
6801
cce8749e 6802 case MINUS:
f3bb6135
RE
6803 return shift_first_arg ? "rsb" : "sub";
6804
cce8749e 6805 case IOR:
f3bb6135
RE
6806 return "orr";
6807
cce8749e 6808 case XOR:
f3bb6135
RE
6809 return "eor";
6810
cce8749e 6811 case AND:
f3bb6135
RE
6812 return "and";
6813
cce8749e 6814 default:
f3bb6135 6815 abort ();
cce8749e 6816 }
f3bb6135 6817}
cce8749e
CH
6818
6819
6820/* Ensure valid constant shifts and return the appropriate shift mnemonic
6821 for the operation code. The returned result should not be overwritten.
6822 OP is the rtx code of the shift.
9997d19d 6823 On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
6354dc9b 6824 shift. */
cce8749e 6825
cd2b33d0 6826static const char *
9997d19d
RE
6827shift_op (op, amountp)
6828 rtx op;
6829 HOST_WIDE_INT *amountp;
cce8749e 6830{
cd2b33d0 6831 const char * mnem;
e2c671ba 6832 enum rtx_code code = GET_CODE (op);
cce8749e 6833
9997d19d
RE
6834 if (GET_CODE (XEXP (op, 1)) == REG || GET_CODE (XEXP (op, 1)) == SUBREG)
6835 *amountp = -1;
6836 else if (GET_CODE (XEXP (op, 1)) == CONST_INT)
6837 *amountp = INTVAL (XEXP (op, 1));
6838 else
6839 abort ();
6840
e2c671ba 6841 switch (code)
cce8749e
CH
6842 {
6843 case ASHIFT:
6844 mnem = "asl";
6845 break;
f3bb6135 6846
cce8749e
CH
6847 case ASHIFTRT:
6848 mnem = "asr";
cce8749e 6849 break;
f3bb6135 6850
cce8749e
CH
6851 case LSHIFTRT:
6852 mnem = "lsr";
cce8749e 6853 break;
f3bb6135 6854
9997d19d
RE
6855 case ROTATERT:
6856 mnem = "ror";
9997d19d
RE
6857 break;
6858
ff9940b0 6859 case MULT:
e2c671ba
RE
6860 /* We never have to worry about the amount being other than a
6861 power of 2, since this case can never be reloaded from a reg. */
9997d19d
RE
6862 if (*amountp != -1)
6863 *amountp = int_log2 (*amountp);
6864 else
6865 abort ();
f3bb6135
RE
6866 return "asl";
6867
cce8749e 6868 default:
f3bb6135 6869 abort ();
cce8749e
CH
6870 }
6871
e2c671ba
RE
6872 if (*amountp != -1)
6873 {
6874 /* This is not 100% correct, but follows from the desire to merge
6875 multiplication by a power of 2 with the recognizer for a
6876 shift. >=32 is not a valid shift for "asl", so we must try and
6877 output a shift that produces the correct arithmetical result.
ddd5a7c1 6878 Using lsr #32 is identical except for the fact that the carry bit
e2c671ba
RE
6879 is not set correctly if we set the flags; but we never use the
6880 carry bit from such an operation, so we can ignore that. */
6881 if (code == ROTATERT)
6882 *amountp &= 31; /* Rotate is just modulo 32 */
6883 else if (*amountp != (*amountp & 31))
6884 {
6885 if (code == ASHIFT)
6886 mnem = "lsr";
6887 *amountp = 32;
6888 }
6889
6890 /* Shifts of 0 are no-ops. */
6891 if (*amountp == 0)
6892 return NULL;
6893 }
6894
9997d19d
RE
6895 return mnem;
6896}
cce8749e
CH
6897
6898
6354dc9b 6899/* Obtain the shift from the POWER of two. */
18af7313 6900static HOST_WIDE_INT
cce8749e 6901int_log2 (power)
f3bb6135 6902 HOST_WIDE_INT power;
cce8749e 6903{
f3bb6135 6904 HOST_WIDE_INT shift = 0;
cce8749e 6905
30cf4896 6906 while ((((HOST_WIDE_INT) 1 << shift) & power) == 0)
cce8749e
CH
6907 {
6908 if (shift > 31)
f3bb6135 6909 abort ();
cce8749e
CH
6910 shift++;
6911 }
f3bb6135
RE
6912
6913 return shift;
6914}
cce8749e 6915
cce8749e
CH
6916/* Output a .ascii pseudo-op, keeping track of lengths. This is because
6917 /bin/as is horribly restrictive. */
6cfc7210 6918#define MAX_ASCII_LEN 51
cce8749e
CH
6919
6920void
6921output_ascii_pseudo_op (stream, p, len)
62b10bbc 6922 FILE * stream;
3cce094d 6923 const unsigned char * p;
cce8749e
CH
6924 int len;
6925{
6926 int i;
6cfc7210 6927 int len_so_far = 0;
cce8749e 6928
6cfc7210
NC
6929 fputs ("\t.ascii\t\"", stream);
6930
cce8749e
CH
6931 for (i = 0; i < len; i++)
6932 {
6933 register int c = p[i];
6934
6cfc7210 6935 if (len_so_far >= MAX_ASCII_LEN)
cce8749e 6936 {
6cfc7210 6937 fputs ("\"\n\t.ascii\t\"", stream);
cce8749e 6938 len_so_far = 0;
cce8749e
CH
6939 }
6940
6cfc7210 6941 switch (c)
cce8749e 6942 {
6cfc7210
NC
6943 case TARGET_TAB:
6944 fputs ("\\t", stream);
6945 len_so_far += 2;
6946 break;
6947
6948 case TARGET_FF:
6949 fputs ("\\f", stream);
6950 len_so_far += 2;
6951 break;
6952
6953 case TARGET_BS:
6954 fputs ("\\b", stream);
6955 len_so_far += 2;
6956 break;
6957
6958 case TARGET_CR:
6959 fputs ("\\r", stream);
6960 len_so_far += 2;
6961 break;
6962
6963 case TARGET_NEWLINE:
6964 fputs ("\\n", stream);
6965 c = p [i + 1];
6966 if ((c >= ' ' && c <= '~')
6967 || c == TARGET_TAB)
6968 /* This is a good place for a line break. */
6969 len_so_far = MAX_ASCII_LEN;
6970 else
6971 len_so_far += 2;
6972 break;
6973
6974 case '\"':
6975 case '\\':
6976 putc ('\\', stream);
5895f793 6977 len_so_far++;
6cfc7210 6978 /* drop through. */
f3bb6135 6979
6cfc7210
NC
6980 default:
6981 if (c >= ' ' && c <= '~')
6982 {
6983 putc (c, stream);
5895f793 6984 len_so_far++;
6cfc7210
NC
6985 }
6986 else
6987 {
6988 fprintf (stream, "\\%03o", c);
6989 len_so_far += 4;
6990 }
6991 break;
cce8749e 6992 }
cce8749e 6993 }
f3bb6135 6994
cce8749e 6995 fputs ("\"\n", stream);
f3bb6135 6996}
cce8749e 6997\f
6d3d9133
NC
6998/* Compute a bit mask of which registers need to be
6999 saved on the stack for the current function. */
7000
7001static unsigned long
7002arm_compute_save_reg_mask ()
7003{
7004 unsigned int save_reg_mask = 0;
7005 unsigned int reg;
7006 unsigned long func_type = arm_current_func_type ();
7007
7008 if (IS_NAKED (func_type))
7009 /* This should never really happen. */
7010 return 0;
7011
7012 /* If we are creating a stack frame, then we must save the frame pointer,
7013 IP (which will hold the old stack pointer), LR and the PC. */
7014 if (frame_pointer_needed)
7015 save_reg_mask |=
7016 (1 << ARM_HARD_FRAME_POINTER_REGNUM)
7017 | (1 << IP_REGNUM)
7018 | (1 << LR_REGNUM)
7019 | (1 << PC_REGNUM);
7020
7021 /* Volatile functions do not return, so there
7022 is no need to save any other registers. */
7023 if (IS_VOLATILE (func_type))
7024 return save_reg_mask;
7025
7b8b8ade 7026 if (IS_INTERRUPT (func_type))
6d3d9133 7027 {
7b8b8ade
NC
7028 unsigned int max_reg;
7029
7030 /* Interrupt functions must not corrupt any registers,
7031 even call clobbered ones. If this is a leaf function
7032 we can just examine the registers used by the RTL, but
7033 otherwise we have to assume that whatever function is
7034 called might clobber anything, and so we have to save
7035 all the call-clobbered registers as well. */
7036 if (ARM_FUNC_TYPE (func_type) == ARM_FT_FIQ)
7037 /* FIQ handlers have registers r8 - r12 banked, so
7038 we only need to check r0 - r7, Normal ISRs only
7039 bank r14 and r15, so ew must check up to r12.
7040 r13 is the stack pointer which is always preserved,
7041 so we do not need to consider it here. */
7042 max_reg = 7;
7043 else
7044 max_reg = 12;
7045
7046 for (reg = 0; reg <= max_reg; reg++)
7047 if (regs_ever_live[reg]
7048 || (! current_function_is_leaf && call_used_regs [reg]))
6d3d9133
NC
7049 save_reg_mask |= (1 << reg);
7050 }
7051 else
7052 {
7053 /* In the normal case we only need to save those registers
7054 which are call saved and which are used by this function. */
7055 for (reg = 0; reg <= 10; reg++)
7056 if (regs_ever_live[reg] && ! call_used_regs [reg])
7057 save_reg_mask |= (1 << reg);
7058
7059 /* Handle the frame pointer as a special case. */
7060 if (! TARGET_APCS_FRAME
7061 && ! frame_pointer_needed
7062 && regs_ever_live[HARD_FRAME_POINTER_REGNUM]
7063 && ! call_used_regs[HARD_FRAME_POINTER_REGNUM])
7064 save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM;
7065
7066 /* If we aren't loading the PIC register,
7067 don't stack it even though it may be live. */
7068 if (flag_pic
7069 && ! TARGET_SINGLE_PIC_BASE
7070 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
7071 save_reg_mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
7072 }
7073
7074 /* Decide if we need to save the link register.
7075 Interrupt routines have their own banked link register,
7076 so they never need to save it.
7077 Otheriwse if we do not use the link register we do not need to save
7078 it. If we are pushing other registers onto the stack however, we
7079 can save an instruction in the epilogue by pushing the link register
7080 now and then popping it back into the PC. This incurs extra memory
7081 accesses though, so we only do it when optimising for size, and only
7082 if we know that we will not need a fancy return sequence. */
7083 if (! IS_INTERRUPT (func_type)
7084 && (regs_ever_live [LR_REGNUM]
7085 || (save_reg_mask
7086 && optimize_size
7087 && ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL)))
7088 save_reg_mask |= 1 << LR_REGNUM;
7089
6f7ebcbb
NC
7090 if (cfun->machine->lr_save_eliminated)
7091 save_reg_mask &= ~ (1 << LR_REGNUM);
7092
6d3d9133
NC
7093 return save_reg_mask;
7094}
7095
7096/* Generate a function exit sequence. If REALLY_RETURN is true, then do
7097 everything bar the final return instruction. */
ff9940b0 7098
cd2b33d0 7099const char *
84ed5e79 7100output_return_instruction (operand, really_return, reverse)
f3bb6135
RE
7101 rtx operand;
7102 int really_return;
84ed5e79 7103 int reverse;
ff9940b0 7104{
6d3d9133 7105 char conditional[10];
ff9940b0 7106 char instr[100];
6d3d9133
NC
7107 int reg;
7108 unsigned long live_regs_mask;
7109 unsigned long func_type;
7110
7111 func_type = arm_current_func_type ();
e2c671ba 7112
6d3d9133 7113 if (IS_NAKED (func_type))
d5b7b3ae 7114 return "";
6d3d9133
NC
7115
7116 if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
e2c671ba 7117 {
e2c671ba 7118 /* If this function was declared non-returning, and we have found a tail
3a5a4282
PB
7119 call, then we have to trust that the called function won't return. */
7120 if (really_return)
7121 {
7122 rtx ops[2];
7123
7124 /* Otherwise, trap an attempted return by aborting. */
7125 ops[0] = operand;
7126 ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)"
7127 : "abort");
7128 assemble_external_libcall (ops[1]);
7129 output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
7130 }
7131
e2c671ba
RE
7132 return "";
7133 }
6d3d9133 7134
5895f793 7135 if (current_function_calls_alloca && !really_return)
62b10bbc 7136 abort ();
ff9940b0 7137
6d3d9133
NC
7138 /* Construct the conditional part of the instruction(s) to be emitted. */
7139 sprintf (conditional, "%%?%%%c0", reverse ? 'D' : 'd');
d5b7b3ae 7140
6d3d9133 7141 return_used_this_function = 1;
ff9940b0 7142
6d3d9133 7143 live_regs_mask = arm_compute_save_reg_mask ();
ff9940b0 7144
3a5a4282 7145 /* On some ARM architectures it is faster to use LDR rather than LDM to
6d3d9133
NC
7146 load a single register. On other architectures, the cost is the same.
7147 In 26 bit mode we have to use LDM in order to be able to restore the CPSR. */
7148 if ((live_regs_mask == (1 << LR_REGNUM))
e46ccf7c
PB
7149 && ! TARGET_INTERWORK
7150 && ! IS_INTERRUPT (func_type)
6d3d9133
NC
7151 && (! really_return || TARGET_APCS_32))
7152 {
7153 if (! really_return)
7154 sprintf (instr, "ldr%s\t%%|lr, [%%|sp], #4", conditional);
7155 else
7156 sprintf (instr, "ldr%s\t%%|pc, [%%|sp], #4", conditional);
7157 }
7158 else if (live_regs_mask)
7159 {
7160 if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
7161 /* There are two possible reasons for the IP register being saved.
7162 Either a stack frame was created, in which case IP contains the
7163 old stack pointer, or an ISR routine corrupted it. If this in an
7164 ISR routine then just restore IP, otherwise restore IP into SP. */
7165 if (! IS_INTERRUPT (func_type))
7166 {
7167 live_regs_mask &= ~ (1 << IP_REGNUM);
7168 live_regs_mask |= (1 << SP_REGNUM);
7169 }
f3bb6135 7170
6d3d9133 7171 /* Generate the load multiple instruction to restore the registers. */
ff9940b0 7172 if (frame_pointer_needed)
6d3d9133 7173 sprintf (instr, "ldm%sea\t%%|fp, {", conditional);
ff9940b0 7174 else
6d3d9133 7175 sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
f3bb6135 7176
6d3d9133
NC
7177 for (reg = 0; reg <= SP_REGNUM; reg++)
7178 if (live_regs_mask & (1 << reg))
7179 {
1d5473cb 7180 strcat (instr, "%|");
6d3d9133
NC
7181 strcat (instr, reg_names[reg]);
7182 strcat (instr, ", ");
7183 }
f3bb6135 7184
6d3d9133
NC
7185 if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
7186 {
7187 /* If we are not restoring the LR register then we will
7188 have added one too many commas to the list above.
7189 Replace it with a closing brace. */
7190 instr [strlen (instr) - 2] = '}';
7191 }
ff9940b0 7192 else
1d5473cb
RE
7193 {
7194 strcat (instr, "%|");
6d3d9133
NC
7195
7196 /* At this point there should only be one or two registers left in
7197 live_regs_mask: always LR, and possibly PC if we created a stack
7198 frame. LR contains the return address. If we do not have any
7199 special requirements for function exit (eg interworking, or ISR)
7200 then we can load this value directly into the PC and save an
7201 instruction. */
7202 if (! TARGET_INTERWORK
7203 && ! IS_INTERRUPT (func_type)
7204 && really_return)
7205 strcat (instr, reg_names [PC_REGNUM]);
da6558fd 7206 else
6d3d9133
NC
7207 strcat (instr, reg_names [LR_REGNUM]);
7208
7209 strcat (instr, (TARGET_APCS_32 || !really_return) ? "}" : "}^");
1d5473cb 7210 }
da6558fd 7211
6d3d9133 7212 if (really_return)
da6558fd 7213 {
6d3d9133
NC
7214 /* See if we need to generate an extra instruction to
7215 perform the actual function return. */
7216 switch ((int) ARM_FUNC_TYPE (func_type))
7217 {
7218 case ARM_FT_ISR:
7219 case ARM_FT_FIQ:
7220 output_asm_insn (instr, & operand);
7221
7222 strcpy (instr, "sub");
7223 strcat (instr, conditional);
7224 strcat (instr, "s\t%|pc, %|lr, #4");
7225 break;
7226
7227 case ARM_FT_EXCEPTION:
7228 output_asm_insn (instr, & operand);
7229
7230 strcpy (instr, "mov");
7231 strcat (instr, conditional);
7232 strcat (instr, "s\t%|pc, %|lr");
7233 break;
7234
7235 case ARM_FT_INTERWORKED:
7236 output_asm_insn (instr, & operand);
da6558fd 7237
6d3d9133
NC
7238 strcpy (instr, "bx");
7239 strcat (instr, conditional);
7240 strcat (instr, "\t%|lr");
7241 break;
7242
7243 default:
7244 /* The return has already been handled
7245 by loading the LR into the PC. */
7246 if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
7247 {
7248 output_asm_insn (instr, & operand);
7249
7250 strcpy (instr, "mov");
7251 strcat (instr, conditional);
7252 if (! TARGET_APCS_32)
7253 strcat (instr, "s");
7254 strcat (instr, "\t%|pc, %|lr");
7255 }
7256 break;
7257 }
da6558fd 7258 }
ff9940b0
RE
7259 }
7260 else if (really_return)
7261 {
6d3d9133
NC
7262 switch ((int) ARM_FUNC_TYPE (func_type))
7263 {
7264 case ARM_FT_ISR:
7265 case ARM_FT_FIQ:
7266 sprintf (instr, "sub%ss\t%%|pc, %%|lr, #4", conditional);
7267 break;
7268
7269 case ARM_FT_INTERWORKED:
7270 sprintf (instr, "bx%s\t%%|lr", conditional);
7271 break;
7272
7273 case ARM_FT_EXCEPTION:
7274 sprintf (instr, "mov%ss\t%%|pc, %%|lr", conditional);
7275 break;
7276
7277 default:
7278 sprintf (instr, "mov%s%s\t%%|pc, %%|lr",
7279 conditional, TARGET_APCS_32 ? "" : "s");
7280 break;
7281 }
ff9940b0 7282 }
6d3d9133
NC
7283 else
7284 /* Nothing to load off the stack, and
7285 no return instruction to generate. */
7286 return "";
f3bb6135 7287
6d3d9133
NC
7288 output_asm_insn (instr, & operand);
7289
ff9940b0
RE
7290 return "";
7291}
7292
ef179a26
NC
7293/* Write the function name into the code section, directly preceding
7294 the function prologue.
7295
7296 Code will be output similar to this:
7297 t0
7298 .ascii "arm_poke_function_name", 0
7299 .align
7300 t1
7301 .word 0xff000000 + (t1 - t0)
7302 arm_poke_function_name
7303 mov ip, sp
7304 stmfd sp!, {fp, ip, lr, pc}
7305 sub fp, ip, #4
7306
7307 When performing a stack backtrace, code can inspect the value
7308 of 'pc' stored at 'fp' + 0. If the trace function then looks
7309 at location pc - 12 and the top 8 bits are set, then we know
7310 that there is a function name embedded immediately preceding this
7311 location and has length ((pc[-3]) & 0xff000000).
7312
7313 We assume that pc is declared as a pointer to an unsigned long.
7314
7315 It is of no benefit to output the function name if we are assembling
7316 a leaf function. These function types will not contain a stack
7317 backtrace structure, therefore it is not possible to determine the
7318 function name. */
7319
7320void
7321arm_poke_function_name (stream, name)
7322 FILE * stream;
5f37d07c 7323 const char * name;
ef179a26
NC
7324{
7325 unsigned long alignlength;
7326 unsigned long length;
7327 rtx x;
7328
d5b7b3ae
RE
7329 length = strlen (name) + 1;
7330 alignlength = ROUND_UP (length);
ef179a26 7331
949d79eb 7332 ASM_OUTPUT_ASCII (stream, name, length);
ef179a26 7333 ASM_OUTPUT_ALIGN (stream, 2);
30cf4896 7334 x = GEN_INT ((unsigned HOST_WIDE_INT) 0xff000000 + alignlength);
ef179a26
NC
7335 ASM_OUTPUT_INT (stream, x);
7336}
7337
6d3d9133
NC
7338/* Place some comments into the assembler stream
7339 describing the current function. */
7340
08c148a8
NB
7341static void
7342arm_output_function_prologue (f, frame_size)
6cfc7210 7343 FILE * f;
08c148a8 7344 HOST_WIDE_INT frame_size;
cce8749e 7345{
6d3d9133 7346 unsigned long func_type;
08c148a8
NB
7347
7348 if (!TARGET_ARM)
7349 {
7350 thumb_output_function_prologue (f, frame_size);
7351 return;
7352 }
6d3d9133
NC
7353
7354 /* Sanity check. */
abaa26e5 7355 if (arm_ccfsm_state || arm_target_insn)
6d3d9133 7356 abort ();
31fdb4d5 7357
6d3d9133
NC
7358 func_type = arm_current_func_type ();
7359
7360 switch ((int) ARM_FUNC_TYPE (func_type))
7361 {
7362 default:
7363 case ARM_FT_NORMAL:
7364 break;
7365 case ARM_FT_INTERWORKED:
7366 asm_fprintf (f, "\t%@ Function supports interworking.\n");
7367 break;
7368 case ARM_FT_EXCEPTION_HANDLER:
7369 asm_fprintf (f, "\t%@ C++ Exception Handler.\n");
7370 break;
7371 case ARM_FT_ISR:
7372 asm_fprintf (f, "\t%@ Interrupt Service Routine.\n");
7373 break;
7374 case ARM_FT_FIQ:
7375 asm_fprintf (f, "\t%@ Fast Interrupt Service Routine.\n");
7376 break;
7377 case ARM_FT_EXCEPTION:
7378 asm_fprintf (f, "\t%@ ARM Exception Handler.\n");
7379 break;
7380 }
ff9940b0 7381
6d3d9133
NC
7382 if (IS_NAKED (func_type))
7383 asm_fprintf (f, "\t%@ Naked Function: prologue and epilogue provided by programmer.\n");
7384
7385 if (IS_VOLATILE (func_type))
7386 asm_fprintf (f, "\t%@ Volatile: function does not return.\n");
7387
7388 if (IS_NESTED (func_type))
7389 asm_fprintf (f, "\t%@ Nested: function declared inside another function.\n");
7390
dd18ae56
NC
7391 asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %d\n",
7392 current_function_args_size,
7393 current_function_pretend_args_size, frame_size);
6d3d9133 7394
dd18ae56
NC
7395 asm_fprintf (f, "\t%@ frame_needed = %d, current_function_anonymous_args = %d\n",
7396 frame_pointer_needed,
7397 current_function_anonymous_args);
cce8749e 7398
6f7ebcbb
NC
7399 if (cfun->machine->lr_save_eliminated)
7400 asm_fprintf (f, "\t%@ link register save eliminated.\n");
7401
32de079a
RE
7402#ifdef AOF_ASSEMBLER
7403 if (flag_pic)
dd18ae56 7404 asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, PIC_OFFSET_TABLE_REGNUM);
32de079a 7405#endif
6d3d9133
NC
7406
7407 return_used_this_function = 0;
f3bb6135 7408}
cce8749e 7409
cd2b33d0 7410const char *
0616531f
RE
7411arm_output_epilogue (really_return)
7412 int really_return;
cce8749e 7413{
949d79eb 7414 int reg;
6f7ebcbb 7415 unsigned long saved_regs_mask;
6d3d9133 7416 unsigned long func_type;
6354dc9b 7417 /* If we need this, then it will always be at least this much. */
b111229a 7418 int floats_offset = 12;
cce8749e 7419 rtx operands[3];
949d79eb 7420 int frame_size = get_frame_size ();
d5b7b3ae 7421 FILE * f = asm_out_file;
6d3d9133 7422 rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
cce8749e 7423
6d3d9133
NC
7424 /* If we have already generated the return instruction
7425 then it is futile to generate anything else. */
b36ba79f 7426 if (use_return_insn (FALSE) && return_used_this_function)
949d79eb 7427 return "";
cce8749e 7428
6d3d9133 7429 func_type = arm_current_func_type ();
d5b7b3ae 7430
6d3d9133
NC
7431 if (IS_NAKED (func_type))
7432 /* Naked functions don't have epilogues. */
7433 return "";
0616531f 7434
6d3d9133 7435 if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
e2c671ba 7436 {
86efdc8e 7437 rtx op;
6d3d9133
NC
7438
7439 /* A volatile function should never return. Call abort. */
ed0e6530 7440 op = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)" : "abort");
2b835d68 7441 assemble_external_libcall (op);
e2c671ba 7442 output_asm_insn ("bl\t%a0", &op);
6d3d9133 7443
949d79eb 7444 return "";
e2c671ba
RE
7445 }
7446
6d3d9133
NC
7447 if (ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
7448 && ! really_return)
7449 /* If we are throwing an exception, then we really must
7450 be doing a return, so we can't tail-call. */
7451 abort ();
7452
6f7ebcbb 7453 saved_regs_mask = arm_compute_save_reg_mask ();
6d3d9133
NC
7454
7455 /* Compute how far away the floats will be. */
7456 for (reg = 0; reg <= LAST_ARM_REGNUM; reg ++)
6f7ebcbb 7457 if (saved_regs_mask & (1 << reg))
6ed30148 7458 floats_offset += 4;
6d3d9133 7459
ff9940b0 7460 if (frame_pointer_needed)
cce8749e 7461 {
b111229a
RE
7462 if (arm_fpu_arch == FP_SOFT2)
7463 {
d5b7b3ae 7464 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
5895f793 7465 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
7466 {
7467 floats_offset += 12;
dd18ae56
NC
7468 asm_fprintf (f, "\tldfe\t%r, [%r, #-%d]\n",
7469 reg, FP_REGNUM, floats_offset);
b111229a
RE
7470 }
7471 }
7472 else
7473 {
d5b7b3ae 7474 int start_reg = LAST_ARM_FP_REGNUM;
b111229a 7475
d5b7b3ae 7476 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
b111229a 7477 {
5895f793 7478 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
7479 {
7480 floats_offset += 12;
6cfc7210 7481
6354dc9b 7482 /* We can't unstack more than four registers at once. */
b111229a
RE
7483 if (start_reg - reg == 3)
7484 {
dd18ae56
NC
7485 asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
7486 reg, FP_REGNUM, floats_offset);
b111229a
RE
7487 start_reg = reg - 1;
7488 }
7489 }
7490 else
7491 {
7492 if (reg != start_reg)
dd18ae56
NC
7493 asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
7494 reg + 1, start_reg - reg,
7495 FP_REGNUM, floats_offset);
b111229a
RE
7496 start_reg = reg - 1;
7497 }
7498 }
7499
7500 /* Just in case the last register checked also needs unstacking. */
7501 if (reg != start_reg)
dd18ae56
NC
7502 asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
7503 reg + 1, start_reg - reg,
7504 FP_REGNUM, floats_offset);
b111229a 7505 }
6d3d9133 7506
6f7ebcbb 7507 /* saved_regs_mask should contain the IP, which at the time of stack
6d3d9133
NC
7508 frame generation actually contains the old stack pointer. So a
7509 quick way to unwind the stack is just pop the IP register directly
7510 into the stack pointer. */
6f7ebcbb 7511 if ((saved_regs_mask & (1 << IP_REGNUM)) == 0)
6d3d9133 7512 abort ();
6f7ebcbb
NC
7513 saved_regs_mask &= ~ (1 << IP_REGNUM);
7514 saved_regs_mask |= (1 << SP_REGNUM);
6d3d9133 7515
6f7ebcbb 7516 /* There are two registers left in saved_regs_mask - LR and PC. We
6d3d9133
NC
7517 only need to restore the LR register (the return address), but to
7518 save time we can load it directly into the PC, unless we need a
7519 special function exit sequence, or we are not really returning. */
7520 if (really_return && ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL)
7521 /* Delete the LR from the register mask, so that the LR on
7522 the stack is loaded into the PC in the register mask. */
6f7ebcbb 7523 saved_regs_mask &= ~ (1 << LR_REGNUM);
b111229a 7524 else
6f7ebcbb 7525 saved_regs_mask &= ~ (1 << PC_REGNUM);
6d3d9133 7526
6f7ebcbb 7527 print_multi_reg (f, "ldmea\t%r", FP_REGNUM, saved_regs_mask);
7b8b8ade
NC
7528
7529 if (IS_INTERRUPT (func_type))
7530 /* Interrupt handlers will have pushed the
7531 IP onto the stack, so restore it now. */
7532 print_multi_reg (f, "ldmea\t%r", SP_REGNUM, 1 << IP_REGNUM);
cce8749e
CH
7533 }
7534 else
7535 {
d2288d8d 7536 /* Restore stack pointer if necessary. */
56636818 7537 if (frame_size + current_function_outgoing_args_size != 0)
d2288d8d
TG
7538 {
7539 operands[0] = operands[1] = stack_pointer_rtx;
56636818
JL
7540 operands[2] = GEN_INT (frame_size
7541 + current_function_outgoing_args_size);
d2288d8d
TG
7542 output_add_immediate (operands);
7543 }
7544
b111229a
RE
7545 if (arm_fpu_arch == FP_SOFT2)
7546 {
d5b7b3ae 7547 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
5895f793 7548 if (regs_ever_live[reg] && !call_used_regs[reg])
dd18ae56
NC
7549 asm_fprintf (f, "\tldfe\t%r, [%r], #12\n",
7550 reg, SP_REGNUM);
b111229a
RE
7551 }
7552 else
7553 {
d5b7b3ae 7554 int start_reg = FIRST_ARM_FP_REGNUM;
b111229a 7555
d5b7b3ae 7556 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
b111229a 7557 {
5895f793 7558 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
7559 {
7560 if (reg - start_reg == 3)
7561 {
dd18ae56
NC
7562 asm_fprintf (f, "\tlfmfd\t%r, 4, [%r]!\n",
7563 start_reg, SP_REGNUM);
b111229a
RE
7564 start_reg = reg + 1;
7565 }
7566 }
7567 else
7568 {
7569 if (reg != start_reg)
dd18ae56
NC
7570 asm_fprintf (f, "\tlfmfd\t%r, %d, [%r]!\n",
7571 start_reg, reg - start_reg,
7572 SP_REGNUM);
6cfc7210 7573
b111229a
RE
7574 start_reg = reg + 1;
7575 }
7576 }
7577
7578 /* Just in case the last register checked also needs unstacking. */
7579 if (reg != start_reg)
dd18ae56
NC
7580 asm_fprintf (f, "\tlfmfd\t%r, %d, [%r]!\n",
7581 start_reg, reg - start_reg, SP_REGNUM);
b111229a
RE
7582 }
7583
6d3d9133
NC
7584 /* If we can, restore the LR into the PC. */
7585 if (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
7586 && really_return
7587 && current_function_pretend_args_size == 0
6f7ebcbb 7588 && saved_regs_mask & (1 << LR_REGNUM))
cce8749e 7589 {
6f7ebcbb
NC
7590 saved_regs_mask &= ~ (1 << LR_REGNUM);
7591 saved_regs_mask |= (1 << PC_REGNUM);
6d3d9133 7592 }
d5b7b3ae 7593
6d3d9133
NC
7594 /* Load the registers off the stack. If we only have one register
7595 to load use the LDR instruction - it is faster. */
6f7ebcbb 7596 if (saved_regs_mask == (1 << LR_REGNUM))
6d3d9133
NC
7597 {
7598 /* The excpetion handler ignores the LR, so we do
7599 not really need to load it off the stack. */
7600 if (eh_ofs)
7601 asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
32de079a 7602 else
6d3d9133 7603 asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
cce8749e 7604 }
6f7ebcbb
NC
7605 else if (saved_regs_mask)
7606 print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
6d3d9133
NC
7607
7608 if (current_function_pretend_args_size)
cce8749e 7609 {
6d3d9133
NC
7610 /* Unwind the pre-pushed regs. */
7611 operands[0] = operands[1] = stack_pointer_rtx;
7612 operands[2] = GEN_INT (current_function_pretend_args_size);
7613 output_add_immediate (operands);
7614 }
7615 }
32de079a 7616
9b598fa0 7617#if 0
6d3d9133
NC
7618 if (ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER)
7619 /* Adjust the stack to remove the exception handler stuff. */
7620 asm_fprintf (f, "\tadd\t%r, %r, %r\n", SP_REGNUM, SP_REGNUM,
7621 REGNO (eh_ofs));
9b598fa0 7622#endif
b111229a 7623
6d3d9133
NC
7624 if (! really_return)
7625 return "";
d5b7b3ae 7626
6d3d9133
NC
7627 /* Generate the return instruction. */
7628 switch ((int) ARM_FUNC_TYPE (func_type))
7629 {
7630 case ARM_FT_EXCEPTION_HANDLER:
7631 /* Even in 26-bit mode we do a mov (rather than a movs)
7632 because we don't have the PSR bits set in the address. */
7633 asm_fprintf (f, "\tmov\t%r, %r\n", PC_REGNUM, EXCEPTION_LR_REGNUM);
7634 break;
0616531f 7635
6d3d9133
NC
7636 case ARM_FT_ISR:
7637 case ARM_FT_FIQ:
7638 asm_fprintf (f, "\tsubs\t%r, %r, #4\n", PC_REGNUM, LR_REGNUM);
7639 break;
7640
7641 case ARM_FT_EXCEPTION:
7642 asm_fprintf (f, "\tmovs\t%r, %r\n", PC_REGNUM, LR_REGNUM);
7643 break;
7644
7645 case ARM_FT_INTERWORKED:
7646 asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
7647 break;
7648
7649 default:
7650 if (frame_pointer_needed)
7651 /* If we used the frame pointer then the return adddress
7652 will have been loaded off the stack directly into the
7653 PC, so there is no need to issue a MOV instruction
7654 here. */
7655 ;
7656 else if (current_function_pretend_args_size == 0
6f7ebcbb 7657 && (saved_regs_mask & (1 << LR_REGNUM)))
6d3d9133
NC
7658 /* Similarly we may have been able to load LR into the PC
7659 even if we did not create a stack frame. */
7660 ;
7661 else if (TARGET_APCS_32)
7662 asm_fprintf (f, "\tmov\t%r, %r\n", PC_REGNUM, LR_REGNUM);
7663 else
7664 asm_fprintf (f, "\tmovs\t%r, %r\n", PC_REGNUM, LR_REGNUM);
7665 break;
cce8749e 7666 }
f3bb6135 7667
949d79eb
RE
7668 return "";
7669}
7670
08c148a8
NB
7671static void
7672arm_output_function_epilogue (file, frame_size)
7673 FILE *file ATTRIBUTE_UNUSED;
7674 HOST_WIDE_INT frame_size;
949d79eb 7675{
d5b7b3ae
RE
7676 if (TARGET_THUMB)
7677 {
7678 /* ??? Probably not safe to set this here, since it assumes that a
7679 function will be emitted as assembly immediately after we generate
7680 RTL for it. This does not happen for inline functions. */
7681 return_used_this_function = 0;
7682 }
7683 else
7684 {
7685 if (use_return_insn (FALSE)
7686 && return_used_this_function
7687 && (frame_size + current_function_outgoing_args_size) != 0
5895f793 7688 && !frame_pointer_needed)
d5b7b3ae 7689 abort ();
f3bb6135 7690
d5b7b3ae
RE
7691 /* Reset the ARM-specific per-function variables. */
7692 current_function_anonymous_args = 0;
7693 after_arm_reorg = 0;
7694 }
f3bb6135 7695}
e2c671ba 7696
2c849145
JM
7697/* Generate and emit an insn that we will recognize as a push_multi.
7698 Unfortunately, since this insn does not reflect very well the actual
7699 semantics of the operation, we need to annotate the insn for the benefit
7700 of DWARF2 frame unwind information. */
6d3d9133 7701
2c849145 7702static rtx
e2c671ba
RE
7703emit_multi_reg_push (mask)
7704 int mask;
7705{
7706 int num_regs = 0;
9b598fa0 7707 int num_dwarf_regs;
e2c671ba
RE
7708 int i, j;
7709 rtx par;
2c849145 7710 rtx dwarf;
87e27392 7711 int dwarf_par_index;
2c849145 7712 rtx tmp, reg;
e2c671ba 7713
d5b7b3ae 7714 for (i = 0; i <= LAST_ARM_REGNUM; i++)
e2c671ba 7715 if (mask & (1 << i))
5895f793 7716 num_regs++;
e2c671ba
RE
7717
7718 if (num_regs == 0 || num_regs > 16)
7719 abort ();
7720
9b598fa0
RE
7721 /* We don't record the PC in the dwarf frame information. */
7722 num_dwarf_regs = num_regs;
7723 if (mask & (1 << PC_REGNUM))
7724 num_dwarf_regs--;
7725
87e27392
NC
7726 /* For the body of the insn we are going to generate an UNSPEC in
7727 parallel with several USEs. This allows the insn to be recognised
7728 by the push_multi pattern in the arm.md file. The insn looks
7729 something like this:
7730
7731 (parallel [
b15bca31
RE
7732 (set (mem:BLK (pre_dec:BLK (reg:SI sp)))
7733 (unspec:BLK [(reg:SI r4)] UNSPEC_PUSH_MULT))
87e27392
NC
7734 (use (reg:SI 11 fp))
7735 (use (reg:SI 12 ip))
7736 (use (reg:SI 14 lr))
7737 (use (reg:SI 15 pc))
7738 ])
7739
7740 For the frame note however, we try to be more explicit and actually
7741 show each register being stored into the stack frame, plus a (single)
7742 decrement of the stack pointer. We do it this way in order to be
7743 friendly to the stack unwinding code, which only wants to see a single
7744 stack decrement per instruction. The RTL we generate for the note looks
7745 something like this:
7746
7747 (sequence [
7748 (set (reg:SI sp) (plus:SI (reg:SI sp) (const_int -20)))
7749 (set (mem:SI (reg:SI sp)) (reg:SI r4))
7750 (set (mem:SI (plus:SI (reg:SI sp) (const_int 4))) (reg:SI fp))
7751 (set (mem:SI (plus:SI (reg:SI sp) (const_int 8))) (reg:SI ip))
7752 (set (mem:SI (plus:SI (reg:SI sp) (const_int 12))) (reg:SI lr))
87e27392
NC
7753 ])
7754
7755 This sequence is used both by the code to support stack unwinding for
7756 exceptions handlers and the code to generate dwarf2 frame debugging. */
7757
43cffd11 7758 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
9b598fa0 7759 dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_dwarf_regs + 1));
2c849145 7760 RTX_FRAME_RELATED_P (dwarf) = 1;
87e27392 7761 dwarf_par_index = 1;
e2c671ba 7762
d5b7b3ae 7763 for (i = 0; i <= LAST_ARM_REGNUM; i++)
e2c671ba
RE
7764 {
7765 if (mask & (1 << i))
7766 {
2c849145
JM
7767 reg = gen_rtx_REG (SImode, i);
7768
e2c671ba 7769 XVECEXP (par, 0, 0)
43cffd11
RE
7770 = gen_rtx_SET (VOIDmode,
7771 gen_rtx_MEM (BLKmode,
7772 gen_rtx_PRE_DEC (BLKmode,
7773 stack_pointer_rtx)),
7774 gen_rtx_UNSPEC (BLKmode,
2c849145 7775 gen_rtvec (1, reg),
9b598fa0 7776 UNSPEC_PUSH_MULT));
2c849145 7777
9b598fa0
RE
7778 if (i != PC_REGNUM)
7779 {
7780 tmp = gen_rtx_SET (VOIDmode,
7781 gen_rtx_MEM (SImode, stack_pointer_rtx),
7782 reg);
7783 RTX_FRAME_RELATED_P (tmp) = 1;
7784 XVECEXP (dwarf, 0, dwarf_par_index) = tmp;
7785 dwarf_par_index++;
7786 }
2c849145 7787
e2c671ba
RE
7788 break;
7789 }
7790 }
7791
7792 for (j = 1, i++; j < num_regs; i++)
7793 {
7794 if (mask & (1 << i))
7795 {
2c849145
JM
7796 reg = gen_rtx_REG (SImode, i);
7797
7798 XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg);
7799
9b598fa0
RE
7800 if (i != PC_REGNUM)
7801 {
7802 tmp = gen_rtx_SET (VOIDmode,
7803 gen_rtx_MEM (SImode,
7804 plus_constant (stack_pointer_rtx,
7805 4 * j)),
7806 reg);
7807 RTX_FRAME_RELATED_P (tmp) = 1;
7808 XVECEXP (dwarf, 0, dwarf_par_index++) = tmp;
7809 }
7810
e2c671ba
RE
7811 j++;
7812 }
7813 }
b111229a 7814
2c849145 7815 par = emit_insn (par);
87e27392
NC
7816
7817 tmp = gen_rtx_SET (SImode,
7818 stack_pointer_rtx,
7819 gen_rtx_PLUS (SImode,
7820 stack_pointer_rtx,
7821 GEN_INT (-4 * num_regs)));
7822 RTX_FRAME_RELATED_P (tmp) = 1;
7823 XVECEXP (dwarf, 0, 0) = tmp;
7824
2c849145
JM
7825 REG_NOTES (par) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
7826 REG_NOTES (par));
7827 return par;
b111229a
RE
7828}
7829
2c849145 7830static rtx
b111229a
RE
7831emit_sfm (base_reg, count)
7832 int base_reg;
7833 int count;
7834{
7835 rtx par;
2c849145
JM
7836 rtx dwarf;
7837 rtx tmp, reg;
b111229a
RE
7838 int i;
7839
43cffd11 7840 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2c849145
JM
7841 dwarf = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
7842 RTX_FRAME_RELATED_P (dwarf) = 1;
7843
7844 reg = gen_rtx_REG (XFmode, base_reg++);
43cffd11
RE
7845
7846 XVECEXP (par, 0, 0)
7847 = gen_rtx_SET (VOIDmode,
7848 gen_rtx_MEM (BLKmode,
7849 gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
7850 gen_rtx_UNSPEC (BLKmode,
2c849145 7851 gen_rtvec (1, reg),
b15bca31 7852 UNSPEC_PUSH_MULT));
2c849145
JM
7853 tmp
7854 = gen_rtx_SET (VOIDmode,
7855 gen_rtx_MEM (XFmode,
7856 gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
7857 reg);
7858 RTX_FRAME_RELATED_P (tmp) = 1;
7859 XVECEXP (dwarf, 0, count - 1) = tmp;
7860
b111229a 7861 for (i = 1; i < count; i++)
2c849145
JM
7862 {
7863 reg = gen_rtx_REG (XFmode, base_reg++);
7864 XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode, reg);
7865
7866 tmp = gen_rtx_SET (VOIDmode,
7867 gen_rtx_MEM (XFmode,
7868 gen_rtx_PRE_DEC (BLKmode,
7869 stack_pointer_rtx)),
7870 reg);
7871 RTX_FRAME_RELATED_P (tmp) = 1;
7872 XVECEXP (dwarf, 0, count - i - 1) = tmp;
7873 }
b111229a 7874
2c849145
JM
7875 par = emit_insn (par);
7876 REG_NOTES (par) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
7877 REG_NOTES (par));
7878 return par;
e2c671ba
RE
7879}
7880
095bb276
NC
7881/* Compute the distance from register FROM to register TO.
7882 These can be the arg pointer (26), the soft frame pointer (25),
7883 the stack pointer (13) or the hard frame pointer (11).
7884 Typical stack layout looks like this:
7885
7886 old stack pointer -> | |
7887 ----
7888 | | \
7889 | | saved arguments for
7890 | | vararg functions
7891 | | /
7892 --
7893 hard FP & arg pointer -> | | \
7894 | | stack
7895 | | frame
7896 | | /
7897 --
7898 | | \
7899 | | call saved
7900 | | registers
7901 soft frame pointer -> | | /
7902 --
7903 | | \
7904 | | local
7905 | | variables
7906 | | /
7907 --
7908 | | \
7909 | | outgoing
7910 | | arguments
7911 current stack pointer -> | | /
7912 --
7913
7914 For a given funciton some or all of these stack compomnents
7915 may not be needed, giving rise to the possibility of
7916 eliminating some of the registers.
7917
7918 The values returned by this function must reflect the behaviour
7919 of arm_expand_prologue() and arm_compute_save_reg_mask().
7920
7921 The sign of the number returned reflects the direction of stack
7922 growth, so the values are positive for all eliminations except
7923 from the soft frame pointer to the hard frame pointer. */
7924
7925unsigned int
7926arm_compute_initial_elimination_offset (from, to)
7927 unsigned int from;
7928 unsigned int to;
7929{
7930 unsigned int local_vars = (get_frame_size () + 3) & ~3;
7931 unsigned int outgoing_args = current_function_outgoing_args_size;
7932 unsigned int stack_frame;
7933 unsigned int call_saved_registers;
7934 unsigned long func_type;
7935
7936 func_type = arm_current_func_type ();
7937
7938 /* Volatile functions never return, so there is
7939 no need to save call saved registers. */
7940 call_saved_registers = 0;
7941 if (! IS_VOLATILE (func_type))
7942 {
7943 unsigned int reg;
7944
ef7112de
NC
7945 /* In theory we should check all of the hard registers to
7946 see if they will be saved onto the stack. In practice
7947 registers 11 upwards have special meanings and need to
7948 be check individually. */
095bb276
NC
7949 for (reg = 0; reg <= 10; reg ++)
7950 if (regs_ever_live[reg] && ! call_used_regs[reg])
7951 call_saved_registers += 4;
7952
ef7112de 7953 /* Determine if register 11 will be clobbered. */
095bb276
NC
7954 if (! TARGET_APCS_FRAME
7955 && ! frame_pointer_needed
7956 && regs_ever_live[HARD_FRAME_POINTER_REGNUM]
7957 && ! call_used_regs[HARD_FRAME_POINTER_REGNUM])
7958 call_saved_registers += 4;
7959
ef7112de
NC
7960 /* The PIC register is fixed, so if the function will
7961 corrupt it, it has to be saved onto the stack. */
095bb276
NC
7962 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
7963 call_saved_registers += 4;
7964
7965 if (regs_ever_live[LR_REGNUM]
7966 /* If a stack frame is going to be created, the LR will
7967 be saved as part of that, so we do not need to allow
7968 for it here. */
7969 && ! frame_pointer_needed)
7970 call_saved_registers += 4;
ef7112de
NC
7971
7972 /* If the hard floating point registers are going to be
7973 used then they must be saved on the stack as well.
7974 Each register occupies 12 bytes of stack space. */
7975 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg ++)
7976 if (regs_ever_live[reg] && ! call_used_regs[reg])
7977 call_saved_registers += 12;
095bb276
NC
7978 }
7979
7980 /* The stack frame contains 4 registers - the old frame pointer,
7981 the old stack pointer, the return address and PC of the start
7982 of the function. */
7983 stack_frame = frame_pointer_needed ? 16 : 0;
7984
095bb276
NC
7985 /* OK, now we have enough information to compute the distances.
7986 There must be an entry in these switch tables for each pair
7987 of registers in ELIMINABLE_REGS, even if some of the entries
7988 seem to be redundant or useless. */
7989 switch (from)
7990 {
7991 case ARG_POINTER_REGNUM:
7992 switch (to)
7993 {
7994 case THUMB_HARD_FRAME_POINTER_REGNUM:
7995 return 0;
7996
7997 case FRAME_POINTER_REGNUM:
7998 /* This is the reverse of the soft frame pointer
7999 to hard frame pointer elimination below. */
8000 if (call_saved_registers == 0 && stack_frame == 0)
8001 return 0;
8002 return (call_saved_registers + stack_frame - 4);
8003
8004 case ARM_HARD_FRAME_POINTER_REGNUM:
8005 /* If there is no stack frame then the hard
8006 frame pointer and the arg pointer coincide. */
8007 if (stack_frame == 0 && call_saved_registers != 0)
8008 return 0;
8009 /* FIXME: Not sure about this. Maybe we should always return 0 ? */
8010 return (frame_pointer_needed
8011 && current_function_needs_context
8012 && ! current_function_anonymous_args) ? 4 : 0;
8013
8014 case STACK_POINTER_REGNUM:
8015 /* If nothing has been pushed on the stack at all
8016 then this will return -4. This *is* correct! */
8017 return call_saved_registers + stack_frame + local_vars + outgoing_args - 4;
8018
8019 default:
8020 abort ();
8021 }
8022 break;
8023
8024 case FRAME_POINTER_REGNUM:
8025 switch (to)
8026 {
8027 case THUMB_HARD_FRAME_POINTER_REGNUM:
8028 return 0;
8029
8030 case ARM_HARD_FRAME_POINTER_REGNUM:
8031 /* The hard frame pointer points to the top entry in the
8032 stack frame. The soft frame pointer to the bottom entry
8033 in the stack frame. If there is no stack frame at all,
8034 then they are identical. */
8035 if (call_saved_registers == 0 && stack_frame == 0)
8036 return 0;
8037 return - (call_saved_registers + stack_frame - 4);
8038
8039 case STACK_POINTER_REGNUM:
8040 return local_vars + outgoing_args;
8041
8042 default:
8043 abort ();
8044 }
8045 break;
8046
8047 default:
8048 /* You cannot eliminate from the stack pointer.
8049 In theory you could eliminate from the hard frame
8050 pointer to the stack pointer, but this will never
8051 happen, since if a stack frame is not needed the
8052 hard frame pointer will never be used. */
8053 abort ();
8054 }
8055}
8056
6d3d9133
NC
8057/* Generate the prologue instructions for entry into an ARM function. */
8058
e2c671ba
RE
8059void
8060arm_expand_prologue ()
8061{
8062 int reg;
6d3d9133 8063 rtx amount;
2c849145 8064 rtx insn;
68dfd979 8065 rtx ip_rtx;
6d3d9133
NC
8066 unsigned long live_regs_mask;
8067 unsigned long func_type;
68dfd979 8068 int fp_offset = 0;
095bb276
NC
8069 int saved_pretend_args = 0;
8070 unsigned int args_to_push;
d3236b4d 8071
6d3d9133 8072 func_type = arm_current_func_type ();
e2c671ba 8073
31fdb4d5 8074 /* Naked functions don't have prologues. */
6d3d9133 8075 if (IS_NAKED (func_type))
31fdb4d5
DE
8076 return;
8077
095bb276
NC
8078 /* Make a copy of c_f_p_a_s as we may need to modify it locally. */
8079 args_to_push = current_function_pretend_args_size;
8080
6d3d9133
NC
8081 /* Compute which register we will have to save onto the stack. */
8082 live_regs_mask = arm_compute_save_reg_mask ();
e2c671ba 8083
68dfd979 8084 ip_rtx = gen_rtx_REG (SImode, IP_REGNUM);
d3236b4d 8085
e2c671ba
RE
8086 if (frame_pointer_needed)
8087 {
7b8b8ade
NC
8088 if (IS_INTERRUPT (func_type))
8089 {
8090 /* Interrupt functions must not corrupt any registers.
8091 Creating a frame pointer however, corrupts the IP
8092 register, so we must push it first. */
8093 insn = emit_multi_reg_push (1 << IP_REGNUM);
8094 RTX_FRAME_RELATED_P (insn) = 1;
8095 }
8096 else if (IS_NESTED (func_type))
68dfd979
NC
8097 {
8098 /* The Static chain register is the same as the IP register
8099 used as a scratch register during stack frame creation.
8100 To get around this need to find somewhere to store IP
8101 whilst the frame is being created. We try the following
8102 places in order:
8103
6d3d9133 8104 1. The last argument register.
68dfd979
NC
8105 2. A slot on the stack above the frame. (This only
8106 works if the function is not a varargs function).
095bb276
NC
8107 3. Register r3, after pushing the argument registers
8108 onto the stack.
6d3d9133 8109
34ce3d7b
JM
8110 Note - we only need to tell the dwarf2 backend about the SP
8111 adjustment in the second variant; the static chain register
8112 doesn't need to be unwound, as it doesn't contain a value
8113 inherited from the caller. */
d3236b4d 8114
68dfd979
NC
8115 if (regs_ever_live[3] == 0)
8116 {
8117 insn = gen_rtx_REG (SImode, 3);
8118 insn = gen_rtx_SET (SImode, insn, ip_rtx);
d3236b4d 8119 insn = emit_insn (insn);
68dfd979 8120 }
095bb276 8121 else if (args_to_push == 0)
68dfd979 8122 {
34ce3d7b 8123 rtx dwarf;
68dfd979
NC
8124 insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
8125 insn = gen_rtx_MEM (SImode, insn);
8126 insn = gen_rtx_SET (VOIDmode, insn, ip_rtx);
8127 insn = emit_insn (insn);
34ce3d7b 8128
68dfd979 8129 fp_offset = 4;
34ce3d7b
JM
8130
8131 /* Just tell the dwarf backend that we adjusted SP. */
8132 dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
8133 gen_rtx_PLUS (SImode, stack_pointer_rtx,
8134 GEN_INT (-fp_offset)));
8135 RTX_FRAME_RELATED_P (insn) = 1;
8136 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
8137 dwarf, REG_NOTES (insn));
68dfd979
NC
8138 }
8139 else
095bb276
NC
8140 {
8141 /* Store the args on the stack. */
8142 if (current_function_anonymous_args)
8143 insn = emit_multi_reg_push
8144 ((0xf0 >> (args_to_push / 4)) & 0xf);
8145 else
8146 insn = emit_insn
8147 (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
8148 GEN_INT (- args_to_push)));
8149
8150 RTX_FRAME_RELATED_P (insn) = 1;
8151
8152 saved_pretend_args = 1;
8153 fp_offset = args_to_push;
8154 args_to_push = 0;
8155
8156 /* Now reuse r3 to preserve IP. */
8157 insn = gen_rtx_REG (SImode, 3);
8158 insn = gen_rtx_SET (SImode, insn, ip_rtx);
8159 (void) emit_insn (insn);
8160 }
68dfd979
NC
8161 }
8162
68dfd979
NC
8163 if (fp_offset)
8164 {
8165 insn = gen_rtx_PLUS (SImode, stack_pointer_rtx, GEN_INT (fp_offset));
8166 insn = gen_rtx_SET (SImode, ip_rtx, insn);
8167 }
8168 else
8169 insn = gen_movsi (ip_rtx, stack_pointer_rtx);
8170
6d3d9133 8171 insn = emit_insn (insn);
8e56560e 8172 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba
RE
8173 }
8174
095bb276 8175 if (args_to_push)
e2c671ba 8176 {
6d3d9133
NC
8177 /* Push the argument registers, or reserve space for them. */
8178 if (current_function_anonymous_args)
2c849145 8179 insn = emit_multi_reg_push
095bb276 8180 ((0xf0 >> (args_to_push / 4)) & 0xf);
e2c671ba 8181 else
2c849145
JM
8182 insn = emit_insn
8183 (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
095bb276 8184 GEN_INT (- args_to_push)));
2c849145 8185 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba
RE
8186 }
8187
8188 if (live_regs_mask)
8189 {
2c849145
JM
8190 insn = emit_multi_reg_push (live_regs_mask);
8191 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba 8192 }
d5b7b3ae 8193
6d3d9133 8194 if (! IS_VOLATILE (func_type))
b111229a 8195 {
6d3d9133 8196 /* Save any floating point call-saved registers used by this function. */
b111229a
RE
8197 if (arm_fpu_arch == FP_SOFT2)
8198 {
d5b7b3ae 8199 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg --)
5895f793 8200 if (regs_ever_live[reg] && !call_used_regs[reg])
2c849145
JM
8201 {
8202 insn = gen_rtx_PRE_DEC (XFmode, stack_pointer_rtx);
8203 insn = gen_rtx_MEM (XFmode, insn);
8204 insn = emit_insn (gen_rtx_SET (VOIDmode, insn,
8205 gen_rtx_REG (XFmode, reg)));
8206 RTX_FRAME_RELATED_P (insn) = 1;
8207 }
b111229a
RE
8208 }
8209 else
8210 {
d5b7b3ae 8211 int start_reg = LAST_ARM_FP_REGNUM;
b111229a 8212
d5b7b3ae 8213 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg --)
b111229a 8214 {
5895f793 8215 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
8216 {
8217 if (start_reg - reg == 3)
8218 {
2c849145
JM
8219 insn = emit_sfm (reg, 4);
8220 RTX_FRAME_RELATED_P (insn) = 1;
b111229a
RE
8221 start_reg = reg - 1;
8222 }
8223 }
8224 else
8225 {
8226 if (start_reg != reg)
2c849145
JM
8227 {
8228 insn = emit_sfm (reg + 1, start_reg - reg);
8229 RTX_FRAME_RELATED_P (insn) = 1;
8230 }
b111229a
RE
8231 start_reg = reg - 1;
8232 }
8233 }
8234
8235 if (start_reg != reg)
2c849145
JM
8236 {
8237 insn = emit_sfm (reg + 1, start_reg - reg);
8238 RTX_FRAME_RELATED_P (insn) = 1;
8239 }
b111229a
RE
8240 }
8241 }
e2c671ba
RE
8242
8243 if (frame_pointer_needed)
2c849145 8244 {
6d3d9133 8245 /* Create the new frame pointer. */
095bb276 8246 insn = GEN_INT (-(4 + args_to_push + fp_offset));
68dfd979 8247 insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, ip_rtx, insn));
2c849145 8248 RTX_FRAME_RELATED_P (insn) = 1;
68dfd979 8249
6d3d9133 8250 if (IS_NESTED (func_type))
68dfd979
NC
8251 {
8252 /* Recover the static chain register. */
095bb276
NC
8253 if (regs_ever_live [3] == 0
8254 || saved_pretend_args)
68dfd979
NC
8255 {
8256 insn = gen_rtx_REG (SImode, 3);
8257 insn = gen_rtx_SET (SImode, ip_rtx, insn);
095bb276 8258 (void) emit_insn (insn);
68dfd979
NC
8259 }
8260 else /* if (current_function_pretend_args_size == 0) */
8261 {
8262 insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx, GEN_INT (4));
8263 insn = gen_rtx_MEM (SImode, insn);
8264 insn = gen_rtx_SET (SImode, ip_rtx, insn);
095bb276 8265 (void) emit_insn (insn);
68dfd979
NC
8266 }
8267 }
2c849145 8268 }
e2c671ba 8269
6d3d9133
NC
8270 amount = GEN_INT (-(get_frame_size ()
8271 + current_function_outgoing_args_size));
8272
e2c671ba
RE
8273 if (amount != const0_rtx)
8274 {
745b9093
JM
8275 /* This add can produce multiple insns for a large constant, so we
8276 need to get tricky. */
8277 rtx last = get_last_insn ();
2c849145
JM
8278 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
8279 amount));
745b9093
JM
8280 do
8281 {
8282 last = last ? NEXT_INSN (last) : get_insns ();
8283 RTX_FRAME_RELATED_P (last) = 1;
8284 }
8285 while (last != insn);
e04c2d6c
RE
8286
8287 /* If the frame pointer is needed, emit a special barrier that
8288 will prevent the scheduler from moving stores to the frame
8289 before the stack adjustment. */
8290 if (frame_pointer_needed)
8291 {
8292 rtx unspec = gen_rtx_UNSPEC (SImode,
8293 gen_rtvec (2, stack_pointer_rtx,
b15bca31
RE
8294 hard_frame_pointer_rtx),
8295 UNSPEC_PRLG_STK);
e04c2d6c 8296
6d3d9133 8297 insn = emit_insn (gen_rtx_CLOBBER (VOIDmode,
e04c2d6c
RE
8298 gen_rtx_MEM (BLKmode, unspec)));
8299 }
e2c671ba
RE
8300 }
8301
8302 /* If we are profiling, make sure no instructions are scheduled before
f5a1b0d2
NC
8303 the call to mcount. Similarly if the user has requested no
8304 scheduling in the prolog. */
8456b95a 8305 if (profile_flag || TARGET_NO_SCHED_PRO)
e2c671ba 8306 emit_insn (gen_blockage ());
6f7ebcbb
NC
8307
8308 /* If the link register is being kept alive, with the return address in it,
8309 then make sure that it does not get reused by the ce2 pass. */
8310 if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
8311 {
8312 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, LR_REGNUM)));
8313 cfun->machine->lr_save_eliminated = 1;
8314 }
e2c671ba 8315}
cce8749e 8316\f
9997d19d
RE
8317/* If CODE is 'd', then the X is a condition operand and the instruction
8318 should only be executed if the condition is true.
ddd5a7c1 8319 if CODE is 'D', then the X is a condition operand and the instruction
9997d19d
RE
8320 should only be executed if the condition is false: however, if the mode
8321 of the comparison is CCFPEmode, then always execute the instruction -- we
8322 do this because in these circumstances !GE does not necessarily imply LT;
8323 in these cases the instruction pattern will take care to make sure that
8324 an instruction containing %d will follow, thereby undoing the effects of
ddd5a7c1 8325 doing this instruction unconditionally.
9997d19d
RE
8326 If CODE is 'N' then X is a floating point operand that must be negated
8327 before output.
8328 If CODE is 'B' then output a bitwise inverted value of X (a const int).
8329 If X is a REG and CODE is `M', output a ldm/stm style multi-reg. */
8330
8331void
8332arm_print_operand (stream, x, code)
62b10bbc 8333 FILE * stream;
9997d19d
RE
8334 rtx x;
8335 int code;
8336{
8337 switch (code)
8338 {
8339 case '@':
f3139301 8340 fputs (ASM_COMMENT_START, stream);
9997d19d
RE
8341 return;
8342
d5b7b3ae
RE
8343 case '_':
8344 fputs (user_label_prefix, stream);
8345 return;
8346
9997d19d 8347 case '|':
f3139301 8348 fputs (REGISTER_PREFIX, stream);
9997d19d
RE
8349 return;
8350
8351 case '?':
8352 if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
cca0a211
RE
8353 {
8354 if (TARGET_THUMB || current_insn_predicate != NULL)
8355 abort ();
8356
8357 fputs (arm_condition_codes[arm_current_cc], stream);
8358 }
8359 else if (current_insn_predicate)
8360 {
8361 enum arm_cond_code code;
8362
8363 if (TARGET_THUMB)
8364 abort ();
8365
8366 code = get_arm_condition_code (current_insn_predicate);
8367 fputs (arm_condition_codes[code], stream);
8368 }
9997d19d
RE
8369 return;
8370
8371 case 'N':
8372 {
8373 REAL_VALUE_TYPE r;
8374 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
8375 r = REAL_VALUE_NEGATE (r);
8376 fprintf (stream, "%s", fp_const_from_val (&r));
8377 }
8378 return;
8379
8380 case 'B':
8381 if (GET_CODE (x) == CONST_INT)
4bc74ece
NC
8382 {
8383 HOST_WIDE_INT val;
5895f793 8384 val = ARM_SIGN_EXTEND (~INTVAL (x));
36ba9cb8 8385 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
4bc74ece 8386 }
9997d19d
RE
8387 else
8388 {
8389 putc ('~', stream);
8390 output_addr_const (stream, x);
8391 }
8392 return;
8393
8394 case 'i':
8395 fprintf (stream, "%s", arithmetic_instr (x, 1));
8396 return;
8397
8398 case 'I':
8399 fprintf (stream, "%s", arithmetic_instr (x, 0));
8400 return;
8401
8402 case 'S':
8403 {
8404 HOST_WIDE_INT val;
5895f793 8405 const char * shift = shift_op (x, &val);
9997d19d 8406
e2c671ba
RE
8407 if (shift)
8408 {
5895f793 8409 fprintf (stream, ", %s ", shift_op (x, &val));
e2c671ba
RE
8410 if (val == -1)
8411 arm_print_operand (stream, XEXP (x, 1), 0);
8412 else
4bc74ece
NC
8413 {
8414 fputc ('#', stream);
36ba9cb8 8415 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
4bc74ece 8416 }
e2c671ba 8417 }
9997d19d
RE
8418 }
8419 return;
8420
d5b7b3ae
RE
8421 /* An explanation of the 'Q', 'R' and 'H' register operands:
8422
8423 In a pair of registers containing a DI or DF value the 'Q'
8424 operand returns the register number of the register containing
8425 the least signficant part of the value. The 'R' operand returns
8426 the register number of the register containing the most
8427 significant part of the value.
8428
8429 The 'H' operand returns the higher of the two register numbers.
8430 On a run where WORDS_BIG_ENDIAN is true the 'H' operand is the
8431 same as the 'Q' operand, since the most signficant part of the
8432 value is held in the lower number register. The reverse is true
8433 on systems where WORDS_BIG_ENDIAN is false.
8434
8435 The purpose of these operands is to distinguish between cases
8436 where the endian-ness of the values is important (for example
8437 when they are added together), and cases where the endian-ness
8438 is irrelevant, but the order of register operations is important.
8439 For example when loading a value from memory into a register
8440 pair, the endian-ness does not matter. Provided that the value
8441 from the lower memory address is put into the lower numbered
8442 register, and the value from the higher address is put into the
8443 higher numbered register, the load will work regardless of whether
8444 the value being loaded is big-wordian or little-wordian. The
8445 order of the two register loads can matter however, if the address
8446 of the memory location is actually held in one of the registers
8447 being overwritten by the load. */
c1c2bc04 8448 case 'Q':
d5b7b3ae 8449 if (REGNO (x) > LAST_ARM_REGNUM)
c1c2bc04 8450 abort ();
d5b7b3ae 8451 asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0));
c1c2bc04
RE
8452 return;
8453
9997d19d 8454 case 'R':
d5b7b3ae 8455 if (REGNO (x) > LAST_ARM_REGNUM)
9997d19d 8456 abort ();
d5b7b3ae
RE
8457 asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1));
8458 return;
8459
8460 case 'H':
8461 if (REGNO (x) > LAST_ARM_REGNUM)
8462 abort ();
8463 asm_fprintf (stream, "%r", REGNO (x) + 1);
9997d19d
RE
8464 return;
8465
8466 case 'm':
d5b7b3ae
RE
8467 asm_fprintf (stream, "%r",
8468 GET_CODE (XEXP (x, 0)) == REG
8469 ? REGNO (XEXP (x, 0)) : REGNO (XEXP (XEXP (x, 0), 0)));
9997d19d
RE
8470 return;
8471
8472 case 'M':
dd18ae56 8473 asm_fprintf (stream, "{%r-%r}",
d5b7b3ae
RE
8474 REGNO (x),
8475 REGNO (x) + NUM_REGS (GET_MODE (x)) - 1);
9997d19d
RE
8476 return;
8477
8478 case 'd':
5895f793 8479 if (!x)
d5b7b3ae
RE
8480 return;
8481
8482 if (TARGET_ARM)
9997d19d
RE
8483 fputs (arm_condition_codes[get_arm_condition_code (x)],
8484 stream);
d5b7b3ae
RE
8485 else
8486 fputs (thumb_condition_code (x, 0), stream);
9997d19d
RE
8487 return;
8488
8489 case 'D':
5895f793 8490 if (!x)
d5b7b3ae
RE
8491 return;
8492
8493 if (TARGET_ARM)
8494 fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
8495 (get_arm_condition_code (x))],
9997d19d 8496 stream);
d5b7b3ae
RE
8497 else
8498 fputs (thumb_condition_code (x, 1), stream);
9997d19d
RE
8499 return;
8500
8501 default:
8502 if (x == 0)
8503 abort ();
8504
8505 if (GET_CODE (x) == REG)
d5b7b3ae 8506 asm_fprintf (stream, "%r", REGNO (x));
9997d19d
RE
8507 else if (GET_CODE (x) == MEM)
8508 {
8509 output_memory_reference_mode = GET_MODE (x);
8510 output_address (XEXP (x, 0));
8511 }
8512 else if (GET_CODE (x) == CONST_DOUBLE)
8513 fprintf (stream, "#%s", fp_immediate_constant (x));
8514 else if (GET_CODE (x) == NEG)
6354dc9b 8515 abort (); /* This should never happen now. */
9997d19d
RE
8516 else
8517 {
8518 fputc ('#', stream);
8519 output_addr_const (stream, x);
8520 }
8521 }
8522}
cce8749e
CH
8523\f
8524/* A finite state machine takes care of noticing whether or not instructions
8525 can be conditionally executed, and thus decrease execution time and code
8526 size by deleting branch instructions. The fsm is controlled by
8527 final_prescan_insn, and controls the actions of ASM_OUTPUT_OPCODE. */
8528
8529/* The state of the fsm controlling condition codes are:
8530 0: normal, do nothing special
8531 1: make ASM_OUTPUT_OPCODE not output this instruction
8532 2: make ASM_OUTPUT_OPCODE not output this instruction
8533 3: make instructions conditional
8534 4: make instructions conditional
8535
8536 State transitions (state->state by whom under condition):
8537 0 -> 1 final_prescan_insn if the `target' is a label
8538 0 -> 2 final_prescan_insn if the `target' is an unconditional branch
8539 1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
8540 2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
8541 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL if the `target' label is reached
8542 (the target label has CODE_LABEL_NUMBER equal to arm_target_label).
8543 4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
8544 (the target insn is arm_target_insn).
8545
ff9940b0
RE
8546 If the jump clobbers the conditions then we use states 2 and 4.
8547
8548 A similar thing can be done with conditional return insns.
8549
cce8749e
CH
8550 XXX In case the `target' is an unconditional branch, this conditionalising
8551 of the instructions always reduces code size, but not always execution
8552 time. But then, I want to reduce the code size to somewhere near what
8553 /bin/cc produces. */
8554
cce8749e
CH
8555/* Returns the index of the ARM condition code string in
8556 `arm_condition_codes'. COMPARISON should be an rtx like
8557 `(eq (...) (...))'. */
8558
84ed5e79 8559static enum arm_cond_code
cce8749e
CH
8560get_arm_condition_code (comparison)
8561 rtx comparison;
8562{
5165176d 8563 enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
84ed5e79
RE
8564 register int code;
8565 register enum rtx_code comp_code = GET_CODE (comparison);
5165176d
RE
8566
8567 if (GET_MODE_CLASS (mode) != MODE_CC)
84ed5e79 8568 mode = SELECT_CC_MODE (comp_code, XEXP (comparison, 0),
5165176d
RE
8569 XEXP (comparison, 1));
8570
8571 switch (mode)
cce8749e 8572 {
84ed5e79
RE
8573 case CC_DNEmode: code = ARM_NE; goto dominance;
8574 case CC_DEQmode: code = ARM_EQ; goto dominance;
8575 case CC_DGEmode: code = ARM_GE; goto dominance;
8576 case CC_DGTmode: code = ARM_GT; goto dominance;
8577 case CC_DLEmode: code = ARM_LE; goto dominance;
8578 case CC_DLTmode: code = ARM_LT; goto dominance;
8579 case CC_DGEUmode: code = ARM_CS; goto dominance;
8580 case CC_DGTUmode: code = ARM_HI; goto dominance;
8581 case CC_DLEUmode: code = ARM_LS; goto dominance;
8582 case CC_DLTUmode: code = ARM_CC;
8583
8584 dominance:
8585 if (comp_code != EQ && comp_code != NE)
8586 abort ();
8587
8588 if (comp_code == EQ)
8589 return ARM_INVERSE_CONDITION_CODE (code);
8590 return code;
8591
5165176d 8592 case CC_NOOVmode:
84ed5e79 8593 switch (comp_code)
5165176d 8594 {
84ed5e79
RE
8595 case NE: return ARM_NE;
8596 case EQ: return ARM_EQ;
8597 case GE: return ARM_PL;
8598 case LT: return ARM_MI;
5165176d
RE
8599 default: abort ();
8600 }
8601
8602 case CC_Zmode:
84ed5e79 8603 switch (comp_code)
5165176d 8604 {
84ed5e79
RE
8605 case NE: return ARM_NE;
8606 case EQ: return ARM_EQ;
5165176d
RE
8607 default: abort ();
8608 }
8609
8610 case CCFPEmode:
e45b72c4
RE
8611 case CCFPmode:
8612 /* These encodings assume that AC=1 in the FPA system control
8613 byte. This allows us to handle all cases except UNEQ and
8614 LTGT. */
84ed5e79
RE
8615 switch (comp_code)
8616 {
8617 case GE: return ARM_GE;
8618 case GT: return ARM_GT;
8619 case LE: return ARM_LS;
8620 case LT: return ARM_MI;
e45b72c4
RE
8621 case NE: return ARM_NE;
8622 case EQ: return ARM_EQ;
8623 case ORDERED: return ARM_VC;
8624 case UNORDERED: return ARM_VS;
8625 case UNLT: return ARM_LT;
8626 case UNLE: return ARM_LE;
8627 case UNGT: return ARM_HI;
8628 case UNGE: return ARM_PL;
8629 /* UNEQ and LTGT do not have a representation. */
8630 case UNEQ: /* Fall through. */
8631 case LTGT: /* Fall through. */
84ed5e79
RE
8632 default: abort ();
8633 }
8634
8635 case CC_SWPmode:
8636 switch (comp_code)
8637 {
8638 case NE: return ARM_NE;
8639 case EQ: return ARM_EQ;
8640 case GE: return ARM_LE;
8641 case GT: return ARM_LT;
8642 case LE: return ARM_GE;
8643 case LT: return ARM_GT;
8644 case GEU: return ARM_LS;
8645 case GTU: return ARM_CC;
8646 case LEU: return ARM_CS;
8647 case LTU: return ARM_HI;
8648 default: abort ();
8649 }
8650
bd9c7e23
RE
8651 case CC_Cmode:
8652 switch (comp_code)
8653 {
8654 case LTU: return ARM_CS;
8655 case GEU: return ARM_CC;
8656 default: abort ();
8657 }
8658
5165176d 8659 case CCmode:
84ed5e79 8660 switch (comp_code)
5165176d 8661 {
84ed5e79
RE
8662 case NE: return ARM_NE;
8663 case EQ: return ARM_EQ;
8664 case GE: return ARM_GE;
8665 case GT: return ARM_GT;
8666 case LE: return ARM_LE;
8667 case LT: return ARM_LT;
8668 case GEU: return ARM_CS;
8669 case GTU: return ARM_HI;
8670 case LEU: return ARM_LS;
8671 case LTU: return ARM_CC;
5165176d
RE
8672 default: abort ();
8673 }
8674
cce8749e
CH
8675 default: abort ();
8676 }
84ed5e79
RE
8677
8678 abort ();
f3bb6135 8679}
cce8749e
CH
8680
8681
8682void
74bbc178 8683arm_final_prescan_insn (insn)
cce8749e 8684 rtx insn;
cce8749e
CH
8685{
8686 /* BODY will hold the body of INSN. */
8687 register rtx body = PATTERN (insn);
8688
8689 /* This will be 1 if trying to repeat the trick, and things need to be
8690 reversed if it appears to fail. */
8691 int reverse = 0;
8692
ff9940b0
RE
8693 /* JUMP_CLOBBERS will be one implies that the conditions if a branch is
8694 taken are clobbered, even if the rtl suggests otherwise. It also
8695 means that we have to grub around within the jump expression to find
8696 out what the conditions are when the jump isn't taken. */
8697 int jump_clobbers = 0;
8698
6354dc9b 8699 /* If we start with a return insn, we only succeed if we find another one. */
ff9940b0
RE
8700 int seeking_return = 0;
8701
cce8749e
CH
8702 /* START_INSN will hold the insn from where we start looking. This is the
8703 first insn after the following code_label if REVERSE is true. */
8704 rtx start_insn = insn;
8705
8706 /* If in state 4, check if the target branch is reached, in order to
8707 change back to state 0. */
8708 if (arm_ccfsm_state == 4)
8709 {
8710 if (insn == arm_target_insn)
f5a1b0d2
NC
8711 {
8712 arm_target_insn = NULL;
8713 arm_ccfsm_state = 0;
8714 }
cce8749e
CH
8715 return;
8716 }
8717
8718 /* If in state 3, it is possible to repeat the trick, if this insn is an
8719 unconditional branch to a label, and immediately following this branch
8720 is the previous target label which is only used once, and the label this
8721 branch jumps to is not too far off. */
8722 if (arm_ccfsm_state == 3)
8723 {
8724 if (simplejump_p (insn))
8725 {
8726 start_insn = next_nonnote_insn (start_insn);
8727 if (GET_CODE (start_insn) == BARRIER)
8728 {
8729 /* XXX Isn't this always a barrier? */
8730 start_insn = next_nonnote_insn (start_insn);
8731 }
8732 if (GET_CODE (start_insn) == CODE_LABEL
8733 && CODE_LABEL_NUMBER (start_insn) == arm_target_label
8734 && LABEL_NUSES (start_insn) == 1)
8735 reverse = TRUE;
8736 else
8737 return;
8738 }
ff9940b0
RE
8739 else if (GET_CODE (body) == RETURN)
8740 {
8741 start_insn = next_nonnote_insn (start_insn);
8742 if (GET_CODE (start_insn) == BARRIER)
8743 start_insn = next_nonnote_insn (start_insn);
8744 if (GET_CODE (start_insn) == CODE_LABEL
8745 && CODE_LABEL_NUMBER (start_insn) == arm_target_label
8746 && LABEL_NUSES (start_insn) == 1)
8747 {
8748 reverse = TRUE;
8749 seeking_return = 1;
8750 }
8751 else
8752 return;
8753 }
cce8749e
CH
8754 else
8755 return;
8756 }
8757
8758 if (arm_ccfsm_state != 0 && !reverse)
8759 abort ();
8760 if (GET_CODE (insn) != JUMP_INSN)
8761 return;
8762
ddd5a7c1 8763 /* This jump might be paralleled with a clobber of the condition codes
ff9940b0
RE
8764 the jump should always come first */
8765 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
8766 body = XVECEXP (body, 0, 0);
8767
8768#if 0
8769 /* If this is a conditional return then we don't want to know */
8770 if (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
8771 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE
8772 && (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN
8773 || GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN))
8774 return;
8775#endif
8776
cce8749e
CH
8777 if (reverse
8778 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
8779 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
8780 {
bd9c7e23
RE
8781 int insns_skipped;
8782 int fail = FALSE, succeed = FALSE;
cce8749e
CH
8783 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
8784 int then_not_else = TRUE;
ff9940b0 8785 rtx this_insn = start_insn, label = 0;
cce8749e 8786
e45b72c4
RE
8787 /* If the jump cannot be done with one instruction, we cannot
8788 conditionally execute the instruction in the inverse case. */
ff9940b0 8789 if (get_attr_conds (insn) == CONDS_JUMP_CLOB)
5bbe2d40 8790 {
5bbe2d40
RE
8791 jump_clobbers = 1;
8792 return;
8793 }
ff9940b0 8794
cce8749e
CH
8795 /* Register the insn jumped to. */
8796 if (reverse)
ff9940b0
RE
8797 {
8798 if (!seeking_return)
8799 label = XEXP (SET_SRC (body), 0);
8800 }
cce8749e
CH
8801 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
8802 label = XEXP (XEXP (SET_SRC (body), 1), 0);
8803 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
8804 {
8805 label = XEXP (XEXP (SET_SRC (body), 2), 0);
8806 then_not_else = FALSE;
8807 }
ff9940b0
RE
8808 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
8809 seeking_return = 1;
8810 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
8811 {
8812 seeking_return = 1;
8813 then_not_else = FALSE;
8814 }
cce8749e
CH
8815 else
8816 abort ();
8817
8818 /* See how many insns this branch skips, and what kind of insns. If all
8819 insns are okay, and the label or unconditional branch to the same
8820 label is not too far away, succeed. */
8821 for (insns_skipped = 0;
b36ba79f 8822 !fail && !succeed && insns_skipped++ < max_insns_skipped;)
cce8749e
CH
8823 {
8824 rtx scanbody;
8825
8826 this_insn = next_nonnote_insn (this_insn);
8827 if (!this_insn)
8828 break;
8829
cce8749e
CH
8830 switch (GET_CODE (this_insn))
8831 {
8832 case CODE_LABEL:
8833 /* Succeed if it is the target label, otherwise fail since
8834 control falls in from somewhere else. */
8835 if (this_insn == label)
8836 {
ff9940b0
RE
8837 if (jump_clobbers)
8838 {
8839 arm_ccfsm_state = 2;
8840 this_insn = next_nonnote_insn (this_insn);
8841 }
8842 else
8843 arm_ccfsm_state = 1;
cce8749e
CH
8844 succeed = TRUE;
8845 }
8846 else
8847 fail = TRUE;
8848 break;
8849
ff9940b0 8850 case BARRIER:
cce8749e 8851 /* Succeed if the following insn is the target label.
ff9940b0
RE
8852 Otherwise fail.
8853 If return insns are used then the last insn in a function
6354dc9b 8854 will be a barrier. */
cce8749e 8855 this_insn = next_nonnote_insn (this_insn);
ff9940b0 8856 if (this_insn && this_insn == label)
cce8749e 8857 {
ff9940b0
RE
8858 if (jump_clobbers)
8859 {
8860 arm_ccfsm_state = 2;
8861 this_insn = next_nonnote_insn (this_insn);
8862 }
8863 else
8864 arm_ccfsm_state = 1;
cce8749e
CH
8865 succeed = TRUE;
8866 }
8867 else
8868 fail = TRUE;
8869 break;
8870
ff9940b0 8871 case CALL_INSN:
2b835d68 8872 /* If using 32-bit addresses the cc is not preserved over
914a3b8c 8873 calls. */
2b835d68 8874 if (TARGET_APCS_32)
bd9c7e23
RE
8875 {
8876 /* Succeed if the following insn is the target label,
8877 or if the following two insns are a barrier and
8878 the target label. */
8879 this_insn = next_nonnote_insn (this_insn);
8880 if (this_insn && GET_CODE (this_insn) == BARRIER)
8881 this_insn = next_nonnote_insn (this_insn);
8882
8883 if (this_insn && this_insn == label
b36ba79f 8884 && insns_skipped < max_insns_skipped)
bd9c7e23
RE
8885 {
8886 if (jump_clobbers)
8887 {
8888 arm_ccfsm_state = 2;
8889 this_insn = next_nonnote_insn (this_insn);
8890 }
8891 else
8892 arm_ccfsm_state = 1;
8893 succeed = TRUE;
8894 }
8895 else
8896 fail = TRUE;
8897 }
ff9940b0 8898 break;
2b835d68 8899
cce8749e
CH
8900 case JUMP_INSN:
8901 /* If this is an unconditional branch to the same label, succeed.
8902 If it is to another label, do nothing. If it is conditional,
8903 fail. */
914a3b8c 8904 /* XXX Probably, the tests for SET and the PC are unnecessary. */
cce8749e 8905
ed4c4348 8906 scanbody = PATTERN (this_insn);
ff9940b0
RE
8907 if (GET_CODE (scanbody) == SET
8908 && GET_CODE (SET_DEST (scanbody)) == PC)
cce8749e
CH
8909 {
8910 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
8911 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
8912 {
8913 arm_ccfsm_state = 2;
8914 succeed = TRUE;
8915 }
8916 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
8917 fail = TRUE;
8918 }
b36ba79f
RE
8919 /* Fail if a conditional return is undesirable (eg on a
8920 StrongARM), but still allow this if optimizing for size. */
8921 else if (GET_CODE (scanbody) == RETURN
5895f793
RE
8922 && !use_return_insn (TRUE)
8923 && !optimize_size)
b36ba79f 8924 fail = TRUE;
ff9940b0
RE
8925 else if (GET_CODE (scanbody) == RETURN
8926 && seeking_return)
8927 {
8928 arm_ccfsm_state = 2;
8929 succeed = TRUE;
8930 }
8931 else if (GET_CODE (scanbody) == PARALLEL)
8932 {
8933 switch (get_attr_conds (this_insn))
8934 {
8935 case CONDS_NOCOND:
8936 break;
8937 default:
8938 fail = TRUE;
8939 break;
8940 }
8941 }
4e67550b
RE
8942 else
8943 fail = TRUE; /* Unrecognized jump (eg epilogue). */
8944
cce8749e
CH
8945 break;
8946
8947 case INSN:
ff9940b0
RE
8948 /* Instructions using or affecting the condition codes make it
8949 fail. */
ed4c4348 8950 scanbody = PATTERN (this_insn);
5895f793
RE
8951 if (!(GET_CODE (scanbody) == SET
8952 || GET_CODE (scanbody) == PARALLEL)
74641843 8953 || get_attr_conds (this_insn) != CONDS_NOCOND)
cce8749e
CH
8954 fail = TRUE;
8955 break;
8956
8957 default:
8958 break;
8959 }
8960 }
8961 if (succeed)
8962 {
ff9940b0 8963 if ((!seeking_return) && (arm_ccfsm_state == 1 || reverse))
cce8749e 8964 arm_target_label = CODE_LABEL_NUMBER (label);
ff9940b0
RE
8965 else if (seeking_return || arm_ccfsm_state == 2)
8966 {
8967 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
8968 {
8969 this_insn = next_nonnote_insn (this_insn);
8970 if (this_insn && (GET_CODE (this_insn) == BARRIER
8971 || GET_CODE (this_insn) == CODE_LABEL))
8972 abort ();
8973 }
8974 if (!this_insn)
8975 {
8976 /* Oh, dear! we ran off the end.. give up */
df4ae160 8977 recog (PATTERN (insn), insn, NULL);
ff9940b0 8978 arm_ccfsm_state = 0;
abaa26e5 8979 arm_target_insn = NULL;
ff9940b0
RE
8980 return;
8981 }
8982 arm_target_insn = this_insn;
8983 }
cce8749e
CH
8984 else
8985 abort ();
ff9940b0
RE
8986 if (jump_clobbers)
8987 {
8988 if (reverse)
8989 abort ();
8990 arm_current_cc =
8991 get_arm_condition_code (XEXP (XEXP (XEXP (SET_SRC (body),
8992 0), 0), 1));
8993 if (GET_CODE (XEXP (XEXP (SET_SRC (body), 0), 0)) == AND)
8994 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
8995 if (GET_CODE (XEXP (SET_SRC (body), 0)) == NE)
8996 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
8997 }
8998 else
8999 {
9000 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
9001 what it was. */
9002 if (!reverse)
9003 arm_current_cc = get_arm_condition_code (XEXP (SET_SRC (body),
9004 0));
9005 }
cce8749e 9006
cce8749e
CH
9007 if (reverse || then_not_else)
9008 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
9009 }
d5b7b3ae 9010
1ccbefce 9011 /* Restore recog_data (getting the attributes of other insns can
ff9940b0 9012 destroy this array, but final.c assumes that it remains intact
ddd5a7c1 9013 across this call; since the insn has been recognized already we
b020fd92 9014 call recog direct). */
df4ae160 9015 recog (PATTERN (insn), insn, NULL);
cce8749e 9016 }
f3bb6135 9017}
cce8749e 9018
d5b7b3ae
RE
9019int
9020arm_regno_class (regno)
9021 int regno;
9022{
9023 if (TARGET_THUMB)
9024 {
9025 if (regno == STACK_POINTER_REGNUM)
9026 return STACK_REG;
9027 if (regno == CC_REGNUM)
9028 return CC_REG;
9029 if (regno < 8)
9030 return LO_REGS;
9031 return HI_REGS;
9032 }
9033
9034 if ( regno <= LAST_ARM_REGNUM
9035 || regno == FRAME_POINTER_REGNUM
9036 || regno == ARG_POINTER_REGNUM)
9037 return GENERAL_REGS;
9038
9039 if (regno == CC_REGNUM)
9040 return NO_REGS;
9041
9042 return FPU_REGS;
9043}
9044
9045/* Handle a special case when computing the offset
9046 of an argument from the frame pointer. */
9047int
9048arm_debugger_arg_offset (value, addr)
9049 int value;
9050 rtx addr;
9051{
9052 rtx insn;
9053
9054 /* We are only interested if dbxout_parms() failed to compute the offset. */
9055 if (value != 0)
9056 return 0;
9057
9058 /* We can only cope with the case where the address is held in a register. */
9059 if (GET_CODE (addr) != REG)
9060 return 0;
9061
9062 /* If we are using the frame pointer to point at the argument, then
9063 an offset of 0 is correct. */
cd2b33d0 9064 if (REGNO (addr) == (unsigned) HARD_FRAME_POINTER_REGNUM)
d5b7b3ae
RE
9065 return 0;
9066
9067 /* If we are using the stack pointer to point at the
9068 argument, then an offset of 0 is correct. */
5895f793 9069 if ((TARGET_THUMB || !frame_pointer_needed)
d5b7b3ae
RE
9070 && REGNO (addr) == SP_REGNUM)
9071 return 0;
9072
9073 /* Oh dear. The argument is pointed to by a register rather
9074 than being held in a register, or being stored at a known
9075 offset from the frame pointer. Since GDB only understands
9076 those two kinds of argument we must translate the address
9077 held in the register into an offset from the frame pointer.
9078 We do this by searching through the insns for the function
9079 looking to see where this register gets its value. If the
9080 register is initialised from the frame pointer plus an offset
9081 then we are in luck and we can continue, otherwise we give up.
9082
9083 This code is exercised by producing debugging information
9084 for a function with arguments like this:
9085
9086 double func (double a, double b, int c, double d) {return d;}
9087
9088 Without this code the stab for parameter 'd' will be set to
9089 an offset of 0 from the frame pointer, rather than 8. */
9090
9091 /* The if() statement says:
9092
9093 If the insn is a normal instruction
9094 and if the insn is setting the value in a register
9095 and if the register being set is the register holding the address of the argument
9096 and if the address is computing by an addition
9097 that involves adding to a register
9098 which is the frame pointer
9099 a constant integer
9100
9101 then... */
9102
9103 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9104 {
9105 if ( GET_CODE (insn) == INSN
9106 && GET_CODE (PATTERN (insn)) == SET
9107 && REGNO (XEXP (PATTERN (insn), 0)) == REGNO (addr)
9108 && GET_CODE (XEXP (PATTERN (insn), 1)) == PLUS
9109 && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 0)) == REG
cd2b33d0 9110 && REGNO (XEXP (XEXP (PATTERN (insn), 1), 0)) == (unsigned) HARD_FRAME_POINTER_REGNUM
d5b7b3ae
RE
9111 && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 1)) == CONST_INT
9112 )
9113 {
9114 value = INTVAL (XEXP (XEXP (PATTERN (insn), 1), 1));
9115
9116 break;
9117 }
9118 }
9119
9120 if (value == 0)
9121 {
9122 debug_rtx (addr);
c725bd79 9123 warning ("unable to compute real location of stacked parameter");
d5b7b3ae
RE
9124 value = 8; /* XXX magic hack */
9125 }
9126
9127 return value;
9128}
9129
d19fb8e3 9130#define def_builtin(NAME, TYPE, CODE) \
df4ae160 9131 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL)
d19fb8e3
NC
9132
9133void
9134arm_init_builtins ()
9135{
cbd5937a 9136 tree endlink = void_list_node;
d19fb8e3
NC
9137 tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
9138 tree pchar_type_node = build_pointer_type (char_type_node);
9139
9140 tree int_ftype_int, void_ftype_pchar;
9141
9142 /* void func (void *) */
9143 void_ftype_pchar
9144 = build_function_type (void_type_node,
9145 tree_cons (NULL_TREE, pchar_type_node, endlink));
9146
9147 /* int func (int) */
9148 int_ftype_int
9149 = build_function_type (integer_type_node, int_endlink);
9150
9151 /* Initialize arm V5 builtins. */
9152 if (arm_arch5)
eab4abeb 9153 def_builtin ("__builtin_clz", int_ftype_int, ARM_BUILTIN_CLZ);
b15bca31
RE
9154
9155 /* Initialize arm V5E builtins. */
9156 if (arm_arch5e)
eab4abeb
NC
9157 def_builtin ("__builtin_prefetch", void_ftype_pchar,
9158 ARM_BUILTIN_PREFETCH);
d19fb8e3
NC
9159}
9160
9161/* Expand an expression EXP that calls a built-in function,
9162 with result going to TARGET if that's convenient
9163 (and in mode MODE if that's convenient).
9164 SUBTARGET may be used as the target for computing one of EXP's operands.
9165 IGNORE is nonzero if the value is to be ignored. */
9166
9167rtx
9168arm_expand_builtin (exp, target, subtarget, mode, ignore)
9169 tree exp;
9170 rtx target;
9171 rtx subtarget ATTRIBUTE_UNUSED;
9172 enum machine_mode mode ATTRIBUTE_UNUSED;
9173 int ignore ATTRIBUTE_UNUSED;
9174{
9175 enum insn_code icode;
9176 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
9177 tree arglist = TREE_OPERAND (exp, 1);
9178 tree arg0;
9179 rtx op0, pat;
9180 enum machine_mode tmode, mode0;
9181 int fcode = DECL_FUNCTION_CODE (fndecl);
9182
9183 switch (fcode)
9184 {
9185 default:
9186 break;
9187
9188 case ARM_BUILTIN_CLZ:
9189 icode = CODE_FOR_clz;
9190 arg0 = TREE_VALUE (arglist);
9191 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
9192 tmode = insn_data[icode].operand[0].mode;
9193 mode0 = insn_data[icode].operand[1].mode;
9194
9195 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
9196 op0 = copy_to_mode_reg (mode0, op0);
9197 if (target == 0
9198 || GET_MODE (target) != tmode
9199 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
9200 target = gen_reg_rtx (tmode);
9201 pat = GEN_FCN (icode) (target, op0);
9202 if (! pat)
9203 return 0;
9204 emit_insn (pat);
9205 return target;
9206
9207 case ARM_BUILTIN_PREFETCH:
9208 icode = CODE_FOR_prefetch;
9209 arg0 = TREE_VALUE (arglist);
9210 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
9211
9212 op0 = gen_rtx_MEM (SImode, copy_to_mode_reg (Pmode, op0));
9213
9214 pat = GEN_FCN (icode) (op0);
9215 if (! pat)
9216 return 0;
9217 emit_insn (pat);
9218 return target;
9219 }
9220
9221 /* @@@ Should really do something sensible here. */
9222 return NULL_RTX;
9223}
d5b7b3ae
RE
9224\f
9225/* Recursively search through all of the blocks in a function
9226 checking to see if any of the variables created in that
9227 function match the RTX called 'orig'. If they do then
9228 replace them with the RTX called 'new'. */
9229
9230static void
9231replace_symbols_in_block (block, orig, new)
9232 tree block;
9233 rtx orig;
9234 rtx new;
9235{
9236 for (; block; block = BLOCK_CHAIN (block))
9237 {
9238 tree sym;
9239
5895f793 9240 if (!TREE_USED (block))
d5b7b3ae
RE
9241 continue;
9242
9243 for (sym = BLOCK_VARS (block); sym; sym = TREE_CHAIN (sym))
9244 {
9245 if ( (DECL_NAME (sym) == 0 && TREE_CODE (sym) != TYPE_DECL)
9246 || DECL_IGNORED_P (sym)
9247 || TREE_CODE (sym) != VAR_DECL
9248 || DECL_EXTERNAL (sym)
5895f793 9249 || !rtx_equal_p (DECL_RTL (sym), orig)
d5b7b3ae
RE
9250 )
9251 continue;
9252
7b8b8ade 9253 SET_DECL_RTL (sym, new);
d5b7b3ae
RE
9254 }
9255
9256 replace_symbols_in_block (BLOCK_SUBBLOCKS (block), orig, new);
9257 }
9258}
9259
9260/* Return the number (counting from 0) of the least significant set
9261 bit in MASK. */
9262#ifdef __GNUC__
9263inline
9264#endif
9265static int
9266number_of_first_bit_set (mask)
9267 int mask;
9268{
9269 int bit;
9270
9271 for (bit = 0;
9272 (mask & (1 << bit)) == 0;
5895f793 9273 ++bit)
d5b7b3ae
RE
9274 continue;
9275
9276 return bit;
9277}
9278
9279/* Generate code to return from a thumb function.
9280 If 'reg_containing_return_addr' is -1, then the return address is
9281 actually on the stack, at the stack pointer. */
9282static void
9283thumb_exit (f, reg_containing_return_addr, eh_ofs)
9284 FILE * f;
9285 int reg_containing_return_addr;
9286 rtx eh_ofs;
9287{
9288 unsigned regs_available_for_popping;
9289 unsigned regs_to_pop;
9290 int pops_needed;
9291 unsigned available;
9292 unsigned required;
9293 int mode;
9294 int size;
9295 int restore_a4 = FALSE;
9296
9297 /* Compute the registers we need to pop. */
9298 regs_to_pop = 0;
9299 pops_needed = 0;
9300
9301 /* There is an assumption here, that if eh_ofs is not NULL, the
9302 normal return address will have been pushed. */
9303 if (reg_containing_return_addr == -1 || eh_ofs)
9304 {
9305 /* When we are generating a return for __builtin_eh_return,
9306 reg_containing_return_addr must specify the return regno. */
9307 if (eh_ofs && reg_containing_return_addr == -1)
9308 abort ();
9309
9310 regs_to_pop |= 1 << LR_REGNUM;
5895f793 9311 ++pops_needed;
d5b7b3ae
RE
9312 }
9313
9314 if (TARGET_BACKTRACE)
9315 {
9316 /* Restore the (ARM) frame pointer and stack pointer. */
9317 regs_to_pop |= (1 << ARM_HARD_FRAME_POINTER_REGNUM) | (1 << SP_REGNUM);
9318 pops_needed += 2;
9319 }
9320
9321 /* If there is nothing to pop then just emit the BX instruction and
9322 return. */
9323 if (pops_needed == 0)
9324 {
9325 if (eh_ofs)
9326 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
9327
9328 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
9329 return;
9330 }
9331 /* Otherwise if we are not supporting interworking and we have not created
9332 a backtrace structure and the function was not entered in ARM mode then
9333 just pop the return address straight into the PC. */
5895f793
RE
9334 else if (!TARGET_INTERWORK
9335 && !TARGET_BACKTRACE
9336 && !is_called_in_ARM_mode (current_function_decl))
d5b7b3ae
RE
9337 {
9338 if (eh_ofs)
9339 {
9340 asm_fprintf (f, "\tadd\t%r, #4\n", SP_REGNUM);
9341 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
9342 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
9343 }
9344 else
9345 asm_fprintf (f, "\tpop\t{%r}\n", PC_REGNUM);
9346
9347 return;
9348 }
9349
9350 /* Find out how many of the (return) argument registers we can corrupt. */
9351 regs_available_for_popping = 0;
9352
9353 /* If returning via __builtin_eh_return, the bottom three registers
9354 all contain information needed for the return. */
9355 if (eh_ofs)
9356 size = 12;
9357 else
9358 {
9359#ifdef RTX_CODE
9360 /* If we can deduce the registers used from the function's
9361 return value. This is more reliable that examining
9362 regs_ever_live[] because that will be set if the register is
9363 ever used in the function, not just if the register is used
9364 to hold a return value. */
9365
9366 if (current_function_return_rtx != 0)
9367 mode = GET_MODE (current_function_return_rtx);
9368 else
9369#endif
9370 mode = DECL_MODE (DECL_RESULT (current_function_decl));
9371
9372 size = GET_MODE_SIZE (mode);
9373
9374 if (size == 0)
9375 {
9376 /* In a void function we can use any argument register.
9377 In a function that returns a structure on the stack
9378 we can use the second and third argument registers. */
9379 if (mode == VOIDmode)
9380 regs_available_for_popping =
9381 (1 << ARG_REGISTER (1))
9382 | (1 << ARG_REGISTER (2))
9383 | (1 << ARG_REGISTER (3));
9384 else
9385 regs_available_for_popping =
9386 (1 << ARG_REGISTER (2))
9387 | (1 << ARG_REGISTER (3));
9388 }
9389 else if (size <= 4)
9390 regs_available_for_popping =
9391 (1 << ARG_REGISTER (2))
9392 | (1 << ARG_REGISTER (3));
9393 else if (size <= 8)
9394 regs_available_for_popping =
9395 (1 << ARG_REGISTER (3));
9396 }
9397
9398 /* Match registers to be popped with registers into which we pop them. */
9399 for (available = regs_available_for_popping,
9400 required = regs_to_pop;
9401 required != 0 && available != 0;
9402 available &= ~(available & - available),
9403 required &= ~(required & - required))
9404 -- pops_needed;
9405
9406 /* If we have any popping registers left over, remove them. */
9407 if (available > 0)
5895f793 9408 regs_available_for_popping &= ~available;
d5b7b3ae
RE
9409
9410 /* Otherwise if we need another popping register we can use
9411 the fourth argument register. */
9412 else if (pops_needed)
9413 {
9414 /* If we have not found any free argument registers and
9415 reg a4 contains the return address, we must move it. */
9416 if (regs_available_for_popping == 0
9417 && reg_containing_return_addr == LAST_ARG_REGNUM)
9418 {
9419 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM, LAST_ARG_REGNUM);
9420 reg_containing_return_addr = LR_REGNUM;
9421 }
9422 else if (size > 12)
9423 {
9424 /* Register a4 is being used to hold part of the return value,
9425 but we have dire need of a free, low register. */
9426 restore_a4 = TRUE;
9427
9428 asm_fprintf (f, "\tmov\t%r, %r\n",IP_REGNUM, LAST_ARG_REGNUM);
9429 }
9430
9431 if (reg_containing_return_addr != LAST_ARG_REGNUM)
9432 {
9433 /* The fourth argument register is available. */
9434 regs_available_for_popping |= 1 << LAST_ARG_REGNUM;
9435
5895f793 9436 --pops_needed;
d5b7b3ae
RE
9437 }
9438 }
9439
9440 /* Pop as many registers as we can. */
9441 thumb_pushpop (f, regs_available_for_popping, FALSE);
9442
9443 /* Process the registers we popped. */
9444 if (reg_containing_return_addr == -1)
9445 {
9446 /* The return address was popped into the lowest numbered register. */
5895f793 9447 regs_to_pop &= ~(1 << LR_REGNUM);
d5b7b3ae
RE
9448
9449 reg_containing_return_addr =
9450 number_of_first_bit_set (regs_available_for_popping);
9451
9452 /* Remove this register for the mask of available registers, so that
9453 the return address will not be corrupted by futher pops. */
5895f793 9454 regs_available_for_popping &= ~(1 << reg_containing_return_addr);
d5b7b3ae
RE
9455 }
9456
9457 /* If we popped other registers then handle them here. */
9458 if (regs_available_for_popping)
9459 {
9460 int frame_pointer;
9461
9462 /* Work out which register currently contains the frame pointer. */
9463 frame_pointer = number_of_first_bit_set (regs_available_for_popping);
9464
9465 /* Move it into the correct place. */
9466 asm_fprintf (f, "\tmov\t%r, %r\n",
9467 ARM_HARD_FRAME_POINTER_REGNUM, frame_pointer);
9468
9469 /* (Temporarily) remove it from the mask of popped registers. */
5895f793
RE
9470 regs_available_for_popping &= ~(1 << frame_pointer);
9471 regs_to_pop &= ~(1 << ARM_HARD_FRAME_POINTER_REGNUM);
d5b7b3ae
RE
9472
9473 if (regs_available_for_popping)
9474 {
9475 int stack_pointer;
9476
9477 /* We popped the stack pointer as well,
9478 find the register that contains it. */
9479 stack_pointer = number_of_first_bit_set (regs_available_for_popping);
9480
9481 /* Move it into the stack register. */
9482 asm_fprintf (f, "\tmov\t%r, %r\n", SP_REGNUM, stack_pointer);
9483
9484 /* At this point we have popped all necessary registers, so
9485 do not worry about restoring regs_available_for_popping
9486 to its correct value:
9487
9488 assert (pops_needed == 0)
9489 assert (regs_available_for_popping == (1 << frame_pointer))
9490 assert (regs_to_pop == (1 << STACK_POINTER)) */
9491 }
9492 else
9493 {
9494 /* Since we have just move the popped value into the frame
9495 pointer, the popping register is available for reuse, and
9496 we know that we still have the stack pointer left to pop. */
9497 regs_available_for_popping |= (1 << frame_pointer);
9498 }
9499 }
9500
9501 /* If we still have registers left on the stack, but we no longer have
9502 any registers into which we can pop them, then we must move the return
9503 address into the link register and make available the register that
9504 contained it. */
9505 if (regs_available_for_popping == 0 && pops_needed > 0)
9506 {
9507 regs_available_for_popping |= 1 << reg_containing_return_addr;
9508
9509 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM,
9510 reg_containing_return_addr);
9511
9512 reg_containing_return_addr = LR_REGNUM;
9513 }
9514
9515 /* If we have registers left on the stack then pop some more.
9516 We know that at most we will want to pop FP and SP. */
9517 if (pops_needed > 0)
9518 {
9519 int popped_into;
9520 int move_to;
9521
9522 thumb_pushpop (f, regs_available_for_popping, FALSE);
9523
9524 /* We have popped either FP or SP.
9525 Move whichever one it is into the correct register. */
9526 popped_into = number_of_first_bit_set (regs_available_for_popping);
9527 move_to = number_of_first_bit_set (regs_to_pop);
9528
9529 asm_fprintf (f, "\tmov\t%r, %r\n", move_to, popped_into);
9530
5895f793 9531 regs_to_pop &= ~(1 << move_to);
d5b7b3ae 9532
5895f793 9533 --pops_needed;
d5b7b3ae
RE
9534 }
9535
9536 /* If we still have not popped everything then we must have only
9537 had one register available to us and we are now popping the SP. */
9538 if (pops_needed > 0)
9539 {
9540 int popped_into;
9541
9542 thumb_pushpop (f, regs_available_for_popping, FALSE);
9543
9544 popped_into = number_of_first_bit_set (regs_available_for_popping);
9545
9546 asm_fprintf (f, "\tmov\t%r, %r\n", SP_REGNUM, popped_into);
9547 /*
9548 assert (regs_to_pop == (1 << STACK_POINTER))
9549 assert (pops_needed == 1)
9550 */
9551 }
9552
9553 /* If necessary restore the a4 register. */
9554 if (restore_a4)
9555 {
9556 if (reg_containing_return_addr != LR_REGNUM)
9557 {
9558 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM, LAST_ARG_REGNUM);
9559 reg_containing_return_addr = LR_REGNUM;
9560 }
9561
9562 asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
9563 }
9564
9565 if (eh_ofs)
9566 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
9567
9568 /* Return to caller. */
9569 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
9570}
9571
9572/* Emit code to push or pop registers to or from the stack. */
9573static void
9574thumb_pushpop (f, mask, push)
9575 FILE * f;
9576 int mask;
9577 int push;
9578{
9579 int regno;
9580 int lo_mask = mask & 0xFF;
9581
5895f793 9582 if (lo_mask == 0 && !push && (mask & (1 << 15)))
d5b7b3ae
RE
9583 {
9584 /* Special case. Do not generate a POP PC statement here, do it in
9585 thumb_exit() */
9586 thumb_exit (f, -1, NULL_RTX);
9587 return;
9588 }
9589
9590 fprintf (f, "\t%s\t{", push ? "push" : "pop");
9591
9592 /* Look at the low registers first. */
5895f793 9593 for (regno = 0; regno <= LAST_LO_REGNUM; regno++, lo_mask >>= 1)
d5b7b3ae
RE
9594 {
9595 if (lo_mask & 1)
9596 {
9597 asm_fprintf (f, "%r", regno);
9598
9599 if ((lo_mask & ~1) != 0)
9600 fprintf (f, ", ");
9601 }
9602 }
9603
9604 if (push && (mask & (1 << LR_REGNUM)))
9605 {
9606 /* Catch pushing the LR. */
9607 if (mask & 0xFF)
9608 fprintf (f, ", ");
9609
9610 asm_fprintf (f, "%r", LR_REGNUM);
9611 }
9612 else if (!push && (mask & (1 << PC_REGNUM)))
9613 {
9614 /* Catch popping the PC. */
9615 if (TARGET_INTERWORK || TARGET_BACKTRACE)
9616 {
9617 /* The PC is never poped directly, instead
9618 it is popped into r3 and then BX is used. */
9619 fprintf (f, "}\n");
9620
9621 thumb_exit (f, -1, NULL_RTX);
9622
9623 return;
9624 }
9625 else
9626 {
9627 if (mask & 0xFF)
9628 fprintf (f, ", ");
9629
9630 asm_fprintf (f, "%r", PC_REGNUM);
9631 }
9632 }
9633
9634 fprintf (f, "}\n");
9635}
9636\f
9637void
9638thumb_final_prescan_insn (insn)
9639 rtx insn;
9640{
d5b7b3ae 9641 if (flag_print_asm_name)
9d98a694
AO
9642 asm_fprintf (asm_out_file, "%@ 0x%04x\n",
9643 INSN_ADDRESSES (INSN_UID (insn)));
d5b7b3ae
RE
9644}
9645
9646int
9647thumb_shiftable_const (val)
9648 unsigned HOST_WIDE_INT val;
9649{
9650 unsigned HOST_WIDE_INT mask = 0xff;
9651 int i;
9652
9653 if (val == 0) /* XXX */
9654 return 0;
9655
9656 for (i = 0; i < 25; i++)
9657 if ((val & (mask << i)) == val)
9658 return 1;
9659
9660 return 0;
9661}
9662
9663/* Returns non-zero if the current function contains,
9664 or might contain a far jump. */
9665int
9666thumb_far_jump_used_p (int in_prologue)
9667{
9668 rtx insn;
9669
9670 /* This test is only important for leaf functions. */
5895f793 9671 /* assert (!leaf_function_p ()); */
d5b7b3ae
RE
9672
9673 /* If we have already decided that far jumps may be used,
9674 do not bother checking again, and always return true even if
9675 it turns out that they are not being used. Once we have made
9676 the decision that far jumps are present (and that hence the link
9677 register will be pushed onto the stack) we cannot go back on it. */
9678 if (cfun->machine->far_jump_used)
9679 return 1;
9680
9681 /* If this function is not being called from the prologue/epilogue
9682 generation code then it must be being called from the
9683 INITIAL_ELIMINATION_OFFSET macro. */
5895f793 9684 if (!in_prologue)
d5b7b3ae
RE
9685 {
9686 /* In this case we know that we are being asked about the elimination
9687 of the arg pointer register. If that register is not being used,
9688 then there are no arguments on the stack, and we do not have to
9689 worry that a far jump might force the prologue to push the link
9690 register, changing the stack offsets. In this case we can just
9691 return false, since the presence of far jumps in the function will
9692 not affect stack offsets.
9693
9694 If the arg pointer is live (or if it was live, but has now been
9695 eliminated and so set to dead) then we do have to test to see if
9696 the function might contain a far jump. This test can lead to some
9697 false negatives, since before reload is completed, then length of
9698 branch instructions is not known, so gcc defaults to returning their
9699 longest length, which in turn sets the far jump attribute to true.
9700
9701 A false negative will not result in bad code being generated, but it
9702 will result in a needless push and pop of the link register. We
9703 hope that this does not occur too often. */
9704 if (regs_ever_live [ARG_POINTER_REGNUM])
9705 cfun->machine->arg_pointer_live = 1;
5895f793 9706 else if (!cfun->machine->arg_pointer_live)
d5b7b3ae
RE
9707 return 0;
9708 }
9709
9710 /* Check to see if the function contains a branch
9711 insn with the far jump attribute set. */
9712 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
9713 {
9714 if (GET_CODE (insn) == JUMP_INSN
9715 /* Ignore tablejump patterns. */
9716 && GET_CODE (PATTERN (insn)) != ADDR_VEC
9717 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
9718 && get_attr_far_jump (insn) == FAR_JUMP_YES
9719 )
9720 {
9721 /* Record the fact that we have decied that
9722 the function does use far jumps. */
9723 cfun->machine->far_jump_used = 1;
9724 return 1;
9725 }
9726 }
9727
9728 return 0;
9729}
9730
9731/* Return non-zero if FUNC must be entered in ARM mode. */
9732int
9733is_called_in_ARM_mode (func)
9734 tree func;
9735{
9736 if (TREE_CODE (func) != FUNCTION_DECL)
9737 abort ();
9738
9739 /* Ignore the problem about functions whoes address is taken. */
9740 if (TARGET_CALLEE_INTERWORKING && TREE_PUBLIC (func))
9741 return TRUE;
9742
9743#ifdef ARM_PE
91d231cb 9744 return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
d5b7b3ae
RE
9745#else
9746 return FALSE;
9747#endif
9748}
9749
9750/* The bits which aren't usefully expanded as rtl. */
400500c4 9751
cd2b33d0 9752const char *
d5b7b3ae
RE
9753thumb_unexpanded_epilogue ()
9754{
9755 int regno;
9756 int live_regs_mask = 0;
9757 int high_regs_pushed = 0;
9758 int leaf_function = leaf_function_p ();
9759 int had_to_push_lr;
9760 rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
9761
9762 if (return_used_this_function)
9763 return "";
9764
9765 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
5895f793
RE
9766 if (regs_ever_live[regno] && !call_used_regs[regno]
9767 && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
d5b7b3ae
RE
9768 live_regs_mask |= 1 << regno;
9769
9770 for (regno = 8; regno < 13; regno++)
9771 {
5895f793
RE
9772 if (regs_ever_live[regno] && !call_used_regs[regno]
9773 && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
9774 high_regs_pushed++;
d5b7b3ae
RE
9775 }
9776
9777 /* The prolog may have pushed some high registers to use as
9778 work registers. eg the testuite file:
9779 gcc/testsuite/gcc/gcc.c-torture/execute/complex-2.c
9780 compiles to produce:
9781 push {r4, r5, r6, r7, lr}
9782 mov r7, r9
9783 mov r6, r8
9784 push {r6, r7}
9785 as part of the prolog. We have to undo that pushing here. */
9786
9787 if (high_regs_pushed)
9788 {
9789 int mask = live_regs_mask;
9790 int next_hi_reg;
9791 int size;
9792 int mode;
9793
9794#ifdef RTX_CODE
9795 /* If we can deduce the registers used from the function's return value.
9796 This is more reliable that examining regs_ever_live[] because that
9797 will be set if the register is ever used in the function, not just if
9798 the register is used to hold a return value. */
9799
9800 if (current_function_return_rtx != 0)
9801 mode = GET_MODE (current_function_return_rtx);
9802 else
9803#endif
9804 mode = DECL_MODE (DECL_RESULT (current_function_decl));
9805
9806 size = GET_MODE_SIZE (mode);
9807
9808 /* Unless we are returning a type of size > 12 register r3 is
9809 available. */
9810 if (size < 13)
9811 mask |= 1 << 3;
9812
9813 if (mask == 0)
9814 /* Oh dear! We have no low registers into which we can pop
9815 high registers! */
400500c4
RK
9816 internal_error
9817 ("no low registers available for popping high registers");
d5b7b3ae
RE
9818
9819 for (next_hi_reg = 8; next_hi_reg < 13; next_hi_reg++)
5895f793
RE
9820 if (regs_ever_live[next_hi_reg] && !call_used_regs[next_hi_reg]
9821 && !(TARGET_SINGLE_PIC_BASE && (next_hi_reg == arm_pic_register)))
d5b7b3ae
RE
9822 break;
9823
9824 while (high_regs_pushed)
9825 {
9826 /* Find lo register(s) into which the high register(s) can
9827 be popped. */
9828 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
9829 {
9830 if (mask & (1 << regno))
9831 high_regs_pushed--;
9832 if (high_regs_pushed == 0)
9833 break;
9834 }
9835
9836 mask &= (2 << regno) - 1; /* A noop if regno == 8 */
9837
9838 /* Pop the values into the low register(s). */
9839 thumb_pushpop (asm_out_file, mask, 0);
9840
9841 /* Move the value(s) into the high registers. */
9842 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
9843 {
9844 if (mask & (1 << regno))
9845 {
9846 asm_fprintf (asm_out_file, "\tmov\t%r, %r\n", next_hi_reg,
9847 regno);
9848
9849 for (next_hi_reg++; next_hi_reg < 13; next_hi_reg++)
5895f793
RE
9850 if (regs_ever_live[next_hi_reg]
9851 && !call_used_regs[next_hi_reg]
9852 && !(TARGET_SINGLE_PIC_BASE
9853 && (next_hi_reg == arm_pic_register)))
d5b7b3ae
RE
9854 break;
9855 }
9856 }
9857 }
9858 }
9859
5895f793 9860 had_to_push_lr = (live_regs_mask || !leaf_function
d5b7b3ae
RE
9861 || thumb_far_jump_used_p (1));
9862
9863 if (TARGET_BACKTRACE
9864 && ((live_regs_mask & 0xFF) == 0)
9865 && regs_ever_live [LAST_ARG_REGNUM] != 0)
9866 {
9867 /* The stack backtrace structure creation code had to
9868 push R7 in order to get a work register, so we pop
9869 it now. */
9870 live_regs_mask |= (1 << LAST_LO_REGNUM);
9871 }
9872
9873 if (current_function_pretend_args_size == 0 || TARGET_BACKTRACE)
9874 {
9875 if (had_to_push_lr
5895f793
RE
9876 && !is_called_in_ARM_mode (current_function_decl)
9877 && !eh_ofs)
d5b7b3ae
RE
9878 live_regs_mask |= 1 << PC_REGNUM;
9879
9880 /* Either no argument registers were pushed or a backtrace
9881 structure was created which includes an adjusted stack
9882 pointer, so just pop everything. */
9883 if (live_regs_mask)
9884 thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
9885
9886 if (eh_ofs)
9887 thumb_exit (asm_out_file, 2, eh_ofs);
9888 /* We have either just popped the return address into the
9889 PC or it is was kept in LR for the entire function or
9890 it is still on the stack because we do not want to
9891 return by doing a pop {pc}. */
9892 else if ((live_regs_mask & (1 << PC_REGNUM)) == 0)
9893 thumb_exit (asm_out_file,
9894 (had_to_push_lr
9895 && is_called_in_ARM_mode (current_function_decl)) ?
9896 -1 : LR_REGNUM, NULL_RTX);
9897 }
9898 else
9899 {
9900 /* Pop everything but the return address. */
5895f793 9901 live_regs_mask &= ~(1 << PC_REGNUM);
d5b7b3ae
RE
9902
9903 if (live_regs_mask)
9904 thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
9905
9906 if (had_to_push_lr)
9907 /* Get the return address into a temporary register. */
9908 thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0);
9909
9910 /* Remove the argument registers that were pushed onto the stack. */
9911 asm_fprintf (asm_out_file, "\tadd\t%r, %r, #%d\n",
9912 SP_REGNUM, SP_REGNUM,
9913 current_function_pretend_args_size);
9914
9915 if (eh_ofs)
9916 thumb_exit (asm_out_file, 2, eh_ofs);
9917 else
9918 thumb_exit (asm_out_file,
9919 had_to_push_lr ? LAST_ARG_REGNUM : LR_REGNUM, NULL_RTX);
9920 }
9921
9922 return "";
9923}
9924
9925/* Functions to save and restore machine-specific function data. */
9926
9927static void
9928arm_mark_machine_status (p)
9929 struct function * p;
9930{
6d3d9133 9931 machine_function *machine = p->machine;
d5b7b3ae 9932
f7a80099 9933 if (machine)
9e2f7ec7 9934 ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
d5b7b3ae
RE
9935}
9936
9937static void
9938arm_init_machine_status (p)
9939 struct function * p;
9940{
9941 p->machine =
6d3d9133
NC
9942 (machine_function *) xcalloc (1, sizeof (machine_function));
9943
9944#if ARM_FT_UNKNOWWN != 0
9945 ((machine_function *) p->machine)->func_type = ARM_FT_UNKNOWN;
9946#endif
d5b7b3ae
RE
9947}
9948
f7a80099
NC
9949static void
9950arm_free_machine_status (p)
9951 struct function * p;
9952{
9953 if (p->machine)
9954 {
9955 free (p->machine);
9956 p->machine = NULL;
9957 }
9958}
9959
d5b7b3ae
RE
9960/* Return an RTX indicating where the return address to the
9961 calling function can be found. */
9962rtx
9963arm_return_addr (count, frame)
9964 int count;
9965 rtx frame ATTRIBUTE_UNUSED;
9966{
d5b7b3ae
RE
9967 if (count != 0)
9968 return NULL_RTX;
9969
9e2f7ec7
DD
9970 if (TARGET_APCS_32)
9971 return get_hard_reg_initial_val (Pmode, LR_REGNUM);
9972 else
d5b7b3ae 9973 {
9e2f7ec7 9974 rtx lr = gen_rtx_AND (Pmode, gen_rtx_REG (Pmode, LR_REGNUM),
d5b7b3ae 9975 GEN_INT (RETURN_ADDR_MASK26));
9e2f7ec7 9976 return get_func_hard_reg_initial_val (cfun, lr);
d5b7b3ae 9977 }
d5b7b3ae
RE
9978}
9979
9980/* Do anything needed before RTL is emitted for each function. */
9981void
9982arm_init_expanders ()
9983{
9984 /* Arrange to initialize and mark the machine per-function status. */
9985 init_machine_status = arm_init_machine_status;
9986 mark_machine_status = arm_mark_machine_status;
f7a80099 9987 free_machine_status = arm_free_machine_status;
d5b7b3ae
RE
9988}
9989
9990/* Generate the rest of a function's prologue. */
9991void
9992thumb_expand_prologue ()
9993{
9994 HOST_WIDE_INT amount = (get_frame_size ()
9995 + current_function_outgoing_args_size);
6d3d9133
NC
9996 unsigned long func_type;
9997
9998 func_type = arm_current_func_type ();
d5b7b3ae
RE
9999
10000 /* Naked functions don't have prologues. */
6d3d9133 10001 if (IS_NAKED (func_type))
d5b7b3ae
RE
10002 return;
10003
6d3d9133
NC
10004 if (IS_INTERRUPT (func_type))
10005 {
c725bd79 10006 error ("interrupt Service Routines cannot be coded in Thumb mode");
6d3d9133
NC
10007 return;
10008 }
10009
d5b7b3ae
RE
10010 if (frame_pointer_needed)
10011 emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
10012
10013 if (amount)
10014 {
10015 amount = ROUND_UP (amount);
10016
10017 if (amount < 512)
10018 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
5895f793 10019 GEN_INT (-amount)));
d5b7b3ae
RE
10020 else
10021 {
10022 int regno;
10023 rtx reg;
10024
10025 /* The stack decrement is too big for an immediate value in a single
10026 insn. In theory we could issue multiple subtracts, but after
10027 three of them it becomes more space efficient to place the full
10028 value in the constant pool and load into a register. (Also the
10029 ARM debugger really likes to see only one stack decrement per
10030 function). So instead we look for a scratch register into which
10031 we can load the decrement, and then we subtract this from the
10032 stack pointer. Unfortunately on the thumb the only available
10033 scratch registers are the argument registers, and we cannot use
10034 these as they may hold arguments to the function. Instead we
10035 attempt to locate a call preserved register which is used by this
10036 function. If we can find one, then we know that it will have
10037 been pushed at the start of the prologue and so we can corrupt
10038 it now. */
10039 for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++)
10040 if (regs_ever_live[regno]
5895f793
RE
10041 && !call_used_regs[regno] /* Paranoia */
10042 && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register))
10043 && !(frame_pointer_needed
10044 && (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
d5b7b3ae
RE
10045 break;
10046
10047 if (regno > LAST_LO_REGNUM) /* Very unlikely */
10048 {
10049 rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
10050
10051 /* Choose an arbitary, non-argument low register. */
10052 reg = gen_rtx (REG, SImode, LAST_LO_REGNUM);
10053
10054 /* Save it by copying it into a high, scratch register. */
10055 emit_insn (gen_movsi (spare, reg));
10056
10057 /* Decrement the stack. */
5895f793 10058 emit_insn (gen_movsi (reg, GEN_INT (-amount)));
d5b7b3ae
RE
10059 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
10060 reg));
10061
10062 /* Restore the low register's original value. */
10063 emit_insn (gen_movsi (reg, spare));
10064
10065 /* Emit a USE of the restored scratch register, so that flow
10066 analysis will not consider the restore redundant. The
10067 register won't be used again in this function and isn't
10068 restored by the epilogue. */
10069 emit_insn (gen_rtx_USE (VOIDmode, reg));
10070 }
10071 else
10072 {
10073 reg = gen_rtx (REG, SImode, regno);
10074
5895f793 10075 emit_insn (gen_movsi (reg, GEN_INT (-amount)));
d5b7b3ae
RE
10076 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
10077 reg));
10078 }
10079 }
10080 }
10081
8456b95a 10082 if (profile_flag || TARGET_NO_SCHED_PRO)
d5b7b3ae
RE
10083 emit_insn (gen_blockage ());
10084}
10085
10086void
10087thumb_expand_epilogue ()
10088{
10089 HOST_WIDE_INT amount = (get_frame_size ()
10090 + current_function_outgoing_args_size);
6d3d9133
NC
10091
10092 /* Naked functions don't have prologues. */
10093 if (IS_NAKED (arm_current_func_type ()))
d5b7b3ae
RE
10094 return;
10095
10096 if (frame_pointer_needed)
10097 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
10098 else if (amount)
10099 {
10100 amount = ROUND_UP (amount);
10101
10102 if (amount < 512)
10103 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
10104 GEN_INT (amount)));
10105 else
10106 {
10107 /* r3 is always free in the epilogue. */
10108 rtx reg = gen_rtx (REG, SImode, LAST_ARG_REGNUM);
10109
10110 emit_insn (gen_movsi (reg, GEN_INT (amount)));
10111 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, reg));
10112 }
10113 }
10114
10115 /* Emit a USE (stack_pointer_rtx), so that
10116 the stack adjustment will not be deleted. */
10117 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
10118
8456b95a 10119 if (profile_flag || TARGET_NO_SCHED_PRO)
d5b7b3ae
RE
10120 emit_insn (gen_blockage ());
10121}
10122
08c148a8
NB
10123static void
10124thumb_output_function_prologue (f, size)
d5b7b3ae 10125 FILE * f;
08c148a8 10126 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
d5b7b3ae
RE
10127{
10128 int live_regs_mask = 0;
10129 int high_regs_pushed = 0;
d5b7b3ae
RE
10130 int regno;
10131
6d3d9133 10132 if (IS_NAKED (arm_current_func_type ()))
d5b7b3ae
RE
10133 return;
10134
10135 if (is_called_in_ARM_mode (current_function_decl))
10136 {
10137 const char * name;
10138
10139 if (GET_CODE (DECL_RTL (current_function_decl)) != MEM)
10140 abort ();
10141 if (GET_CODE (XEXP (DECL_RTL (current_function_decl), 0)) != SYMBOL_REF)
10142 abort ();
10143 name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
10144
10145 /* Generate code sequence to switch us into Thumb mode. */
10146 /* The .code 32 directive has already been emitted by
6d77b53e 10147 ASM_DECLARE_FUNCTION_NAME. */
d5b7b3ae
RE
10148 asm_fprintf (f, "\torr\t%r, %r, #1\n", IP_REGNUM, PC_REGNUM);
10149 asm_fprintf (f, "\tbx\t%r\n", IP_REGNUM);
10150
10151 /* Generate a label, so that the debugger will notice the
10152 change in instruction sets. This label is also used by
10153 the assembler to bypass the ARM code when this function
10154 is called from a Thumb encoded function elsewhere in the
10155 same file. Hence the definition of STUB_NAME here must
10156 agree with the definition in gas/config/tc-arm.c */
10157
10158#define STUB_NAME ".real_start_of"
10159
10160 asm_fprintf (f, "\t.code\t16\n");
10161#ifdef ARM_PE
10162 if (arm_dllexport_name_p (name))
e5951263 10163 name = arm_strip_name_encoding (name);
d5b7b3ae
RE
10164#endif
10165 asm_fprintf (f, "\t.globl %s%U%s\n", STUB_NAME, name);
10166 asm_fprintf (f, "\t.thumb_func\n");
10167 asm_fprintf (f, "%s%U%s:\n", STUB_NAME, name);
10168 }
10169
d5b7b3ae
RE
10170 if (current_function_pretend_args_size)
10171 {
6d3d9133 10172 if (current_function_anonymous_args)
d5b7b3ae
RE
10173 {
10174 int num_pushes;
10175
10176 asm_fprintf (f, "\tpush\t{");
10177
10178 num_pushes = NUM_INTS (current_function_pretend_args_size);
10179
10180 for (regno = LAST_ARG_REGNUM + 1 - num_pushes;
10181 regno <= LAST_ARG_REGNUM;
5895f793 10182 regno++)
d5b7b3ae
RE
10183 asm_fprintf (f, "%r%s", regno,
10184 regno == LAST_ARG_REGNUM ? "" : ", ");
10185
10186 asm_fprintf (f, "}\n");
10187 }
10188 else
10189 asm_fprintf (f, "\tsub\t%r, %r, #%d\n",
10190 SP_REGNUM, SP_REGNUM,
10191 current_function_pretend_args_size);
10192 }
10193
5895f793
RE
10194 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
10195 if (regs_ever_live[regno] && !call_used_regs[regno]
10196 && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
d5b7b3ae
RE
10197 live_regs_mask |= 1 << regno;
10198
5895f793 10199 if (live_regs_mask || !leaf_function_p () || thumb_far_jump_used_p (1))
d5b7b3ae
RE
10200 live_regs_mask |= 1 << LR_REGNUM;
10201
10202 if (TARGET_BACKTRACE)
10203 {
10204 int offset;
10205 int work_register = 0;
10206 int wr;
10207
10208 /* We have been asked to create a stack backtrace structure.
10209 The code looks like this:
10210
10211 0 .align 2
10212 0 func:
10213 0 sub SP, #16 Reserve space for 4 registers.
10214 2 push {R7} Get a work register.
10215 4 add R7, SP, #20 Get the stack pointer before the push.
10216 6 str R7, [SP, #8] Store the stack pointer (before reserving the space).
10217 8 mov R7, PC Get hold of the start of this code plus 12.
10218 10 str R7, [SP, #16] Store it.
10219 12 mov R7, FP Get hold of the current frame pointer.
10220 14 str R7, [SP, #4] Store it.
10221 16 mov R7, LR Get hold of the current return address.
10222 18 str R7, [SP, #12] Store it.
10223 20 add R7, SP, #16 Point at the start of the backtrace structure.
10224 22 mov FP, R7 Put this value into the frame pointer. */
10225
10226 if ((live_regs_mask & 0xFF) == 0)
10227 {
10228 /* See if the a4 register is free. */
10229
10230 if (regs_ever_live [LAST_ARG_REGNUM] == 0)
10231 work_register = LAST_ARG_REGNUM;
10232 else /* We must push a register of our own */
10233 live_regs_mask |= (1 << LAST_LO_REGNUM);
10234 }
10235
10236 if (work_register == 0)
10237 {
10238 /* Select a register from the list that will be pushed to
10239 use as our work register. */
10240 for (work_register = (LAST_LO_REGNUM + 1); work_register--;)
10241 if ((1 << work_register) & live_regs_mask)
10242 break;
10243 }
10244
10245 asm_fprintf
10246 (f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n",
10247 SP_REGNUM, SP_REGNUM);
10248
10249 if (live_regs_mask)
10250 thumb_pushpop (f, live_regs_mask, 1);
10251
10252 for (offset = 0, wr = 1 << 15; wr != 0; wr >>= 1)
10253 if (wr & live_regs_mask)
10254 offset += 4;
10255
10256 asm_fprintf (f, "\tadd\t%r, %r, #%d\n", work_register, SP_REGNUM,
10257 offset + 16 + current_function_pretend_args_size);
10258
10259 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
10260 offset + 4);
10261
10262 /* Make sure that the instruction fetching the PC is in the right place
10263 to calculate "start of backtrace creation code + 12". */
10264 if (live_regs_mask)
10265 {
10266 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, PC_REGNUM);
10267 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
10268 offset + 12);
10269 asm_fprintf (f, "\tmov\t%r, %r\n", work_register,
10270 ARM_HARD_FRAME_POINTER_REGNUM);
10271 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
10272 offset);
10273 }
10274 else
10275 {
10276 asm_fprintf (f, "\tmov\t%r, %r\n", work_register,
10277 ARM_HARD_FRAME_POINTER_REGNUM);
10278 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
10279 offset);
10280 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, PC_REGNUM);
10281 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
10282 offset + 12);
10283 }
10284
10285 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, LR_REGNUM);
10286 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
10287 offset + 8);
10288 asm_fprintf (f, "\tadd\t%r, %r, #%d\n", work_register, SP_REGNUM,
10289 offset + 12);
10290 asm_fprintf (f, "\tmov\t%r, %r\t\t%@ Backtrace structure created\n",
10291 ARM_HARD_FRAME_POINTER_REGNUM, work_register);
10292 }
10293 else if (live_regs_mask)
10294 thumb_pushpop (f, live_regs_mask, 1);
10295
10296 for (regno = 8; regno < 13; regno++)
10297 {
5895f793
RE
10298 if (regs_ever_live[regno] && !call_used_regs[regno]
10299 && !(TARGET_SINGLE_PIC_BASE && (regno == arm_pic_register)))
10300 high_regs_pushed++;
d5b7b3ae
RE
10301 }
10302
10303 if (high_regs_pushed)
10304 {
10305 int pushable_regs = 0;
10306 int mask = live_regs_mask & 0xff;
10307 int next_hi_reg;
10308
10309 for (next_hi_reg = 12; next_hi_reg > LAST_LO_REGNUM; next_hi_reg--)
10310 {
5895f793
RE
10311 if (regs_ever_live[next_hi_reg] && !call_used_regs[next_hi_reg]
10312 && !(TARGET_SINGLE_PIC_BASE
10313 && (next_hi_reg == arm_pic_register)))
d5b7b3ae
RE
10314 break;
10315 }
10316
10317 pushable_regs = mask;
10318
10319 if (pushable_regs == 0)
10320 {
10321 /* Desperation time -- this probably will never happen. */
10322 if (regs_ever_live[LAST_ARG_REGNUM]
5895f793 10323 || !call_used_regs[LAST_ARG_REGNUM])
d5b7b3ae
RE
10324 asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, LAST_ARG_REGNUM);
10325 mask = 1 << LAST_ARG_REGNUM;
10326 }
10327
10328 while (high_regs_pushed > 0)
10329 {
10330 for (regno = LAST_LO_REGNUM; regno >= 0; regno--)
10331 {
10332 if (mask & (1 << regno))
10333 {
10334 asm_fprintf (f, "\tmov\t%r, %r\n", regno, next_hi_reg);
10335
5895f793 10336 high_regs_pushed--;
d5b7b3ae
RE
10337
10338 if (high_regs_pushed)
10339 for (next_hi_reg--; next_hi_reg > LAST_LO_REGNUM;
10340 next_hi_reg--)
10341 {
10342 if (regs_ever_live[next_hi_reg]
5895f793
RE
10343 && !call_used_regs[next_hi_reg]
10344 && !(TARGET_SINGLE_PIC_BASE
10345 && (next_hi_reg == arm_pic_register)))
d5b7b3ae
RE
10346 break;
10347 }
10348 else
10349 {
5895f793 10350 mask &= ~((1 << regno) - 1);
d5b7b3ae
RE
10351 break;
10352 }
10353 }
10354 }
10355
10356 thumb_pushpop (f, mask, 1);
10357 }
10358
10359 if (pushable_regs == 0
10360 && (regs_ever_live[LAST_ARG_REGNUM]
5895f793 10361 || !call_used_regs[LAST_ARG_REGNUM]))
d5b7b3ae
RE
10362 asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
10363 }
10364}
10365
10366/* Handle the case of a double word load into a low register from
10367 a computed memory address. The computed address may involve a
10368 register which is overwritten by the load. */
10369
cd2b33d0 10370const char *
d5b7b3ae 10371thumb_load_double_from_address (operands)
400500c4 10372 rtx *operands;
d5b7b3ae
RE
10373{
10374 rtx addr;
10375 rtx base;
10376 rtx offset;
10377 rtx arg1;
10378 rtx arg2;
10379
10380 if (GET_CODE (operands[0]) != REG)
400500c4 10381 abort ();
d5b7b3ae
RE
10382
10383 if (GET_CODE (operands[1]) != MEM)
400500c4 10384 abort ();
d5b7b3ae
RE
10385
10386 /* Get the memory address. */
10387 addr = XEXP (operands[1], 0);
10388
10389 /* Work out how the memory address is computed. */
10390 switch (GET_CODE (addr))
10391 {
10392 case REG:
10393 operands[2] = gen_rtx (MEM, SImode,
10394 plus_constant (XEXP (operands[1], 0), 4));
10395
10396 if (REGNO (operands[0]) == REGNO (addr))
10397 {
10398 output_asm_insn ("ldr\t%H0, %2", operands);
10399 output_asm_insn ("ldr\t%0, %1", operands);
10400 }
10401 else
10402 {
10403 output_asm_insn ("ldr\t%0, %1", operands);
10404 output_asm_insn ("ldr\t%H0, %2", operands);
10405 }
10406 break;
10407
10408 case CONST:
10409 /* Compute <address> + 4 for the high order load. */
10410 operands[2] = gen_rtx (MEM, SImode,
10411 plus_constant (XEXP (operands[1], 0), 4));
10412
10413 output_asm_insn ("ldr\t%0, %1", operands);
10414 output_asm_insn ("ldr\t%H0, %2", operands);
10415 break;
10416
10417 case PLUS:
10418 arg1 = XEXP (addr, 0);
10419 arg2 = XEXP (addr, 1);
10420
10421 if (CONSTANT_P (arg1))
10422 base = arg2, offset = arg1;
10423 else
10424 base = arg1, offset = arg2;
10425
10426 if (GET_CODE (base) != REG)
400500c4 10427 abort ();
d5b7b3ae
RE
10428
10429 /* Catch the case of <address> = <reg> + <reg> */
10430 if (GET_CODE (offset) == REG)
10431 {
10432 int reg_offset = REGNO (offset);
10433 int reg_base = REGNO (base);
10434 int reg_dest = REGNO (operands[0]);
10435
10436 /* Add the base and offset registers together into the
10437 higher destination register. */
10438 asm_fprintf (asm_out_file, "\tadd\t%r, %r, %r",
10439 reg_dest + 1, reg_base, reg_offset);
10440
10441 /* Load the lower destination register from the address in
10442 the higher destination register. */
10443 asm_fprintf (asm_out_file, "\tldr\t%r, [%r, #0]",
10444 reg_dest, reg_dest + 1);
10445
10446 /* Load the higher destination register from its own address
10447 plus 4. */
10448 asm_fprintf (asm_out_file, "\tldr\t%r, [%r, #4]",
10449 reg_dest + 1, reg_dest + 1);
10450 }
10451 else
10452 {
10453 /* Compute <address> + 4 for the high order load. */
10454 operands[2] = gen_rtx (MEM, SImode,
10455 plus_constant (XEXP (operands[1], 0), 4));
10456
10457 /* If the computed address is held in the low order register
10458 then load the high order register first, otherwise always
10459 load the low order register first. */
10460 if (REGNO (operands[0]) == REGNO (base))
10461 {
10462 output_asm_insn ("ldr\t%H0, %2", operands);
10463 output_asm_insn ("ldr\t%0, %1", operands);
10464 }
10465 else
10466 {
10467 output_asm_insn ("ldr\t%0, %1", operands);
10468 output_asm_insn ("ldr\t%H0, %2", operands);
10469 }
10470 }
10471 break;
10472
10473 case LABEL_REF:
10474 /* With no registers to worry about we can just load the value
10475 directly. */
10476 operands[2] = gen_rtx (MEM, SImode,
10477 plus_constant (XEXP (operands[1], 0), 4));
10478
10479 output_asm_insn ("ldr\t%H0, %2", operands);
10480 output_asm_insn ("ldr\t%0, %1", operands);
10481 break;
10482
10483 default:
400500c4 10484 abort ();
d5b7b3ae
RE
10485 break;
10486 }
10487
10488 return "";
10489}
10490
10491
cd2b33d0 10492const char *
d5b7b3ae
RE
10493thumb_output_move_mem_multiple (n, operands)
10494 int n;
10495 rtx * operands;
10496{
10497 rtx tmp;
10498
10499 switch (n)
10500 {
10501 case 2:
ca356f3a 10502 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 10503 {
ca356f3a
RE
10504 tmp = operands[4];
10505 operands[4] = operands[5];
10506 operands[5] = tmp;
d5b7b3ae 10507 }
ca356f3a
RE
10508 output_asm_insn ("ldmia\t%1!, {%4, %5}", operands);
10509 output_asm_insn ("stmia\t%0!, {%4, %5}", operands);
d5b7b3ae
RE
10510 break;
10511
10512 case 3:
ca356f3a 10513 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 10514 {
ca356f3a
RE
10515 tmp = operands[4];
10516 operands[4] = operands[5];
10517 operands[5] = tmp;
d5b7b3ae 10518 }
ca356f3a 10519 if (REGNO (operands[5]) > REGNO (operands[6]))
d5b7b3ae 10520 {
ca356f3a
RE
10521 tmp = operands[5];
10522 operands[5] = operands[6];
10523 operands[6] = tmp;
d5b7b3ae 10524 }
ca356f3a 10525 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 10526 {
ca356f3a
RE
10527 tmp = operands[4];
10528 operands[4] = operands[5];
10529 operands[5] = tmp;
d5b7b3ae
RE
10530 }
10531
ca356f3a
RE
10532 output_asm_insn ("ldmia\t%1!, {%4, %5, %6}", operands);
10533 output_asm_insn ("stmia\t%0!, {%4, %5, %6}", operands);
d5b7b3ae
RE
10534 break;
10535
10536 default:
10537 abort ();
10538 }
10539
10540 return "";
10541}
10542
10543/* Routines for generating rtl */
10544
10545void
10546thumb_expand_movstrqi (operands)
10547 rtx * operands;
10548{
10549 rtx out = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
10550 rtx in = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
10551 HOST_WIDE_INT len = INTVAL (operands[2]);
10552 HOST_WIDE_INT offset = 0;
10553
10554 while (len >= 12)
10555 {
ca356f3a 10556 emit_insn (gen_movmem12b (out, in, out, in));
d5b7b3ae
RE
10557 len -= 12;
10558 }
10559
10560 if (len >= 8)
10561 {
ca356f3a 10562 emit_insn (gen_movmem8b (out, in, out, in));
d5b7b3ae
RE
10563 len -= 8;
10564 }
10565
10566 if (len >= 4)
10567 {
10568 rtx reg = gen_reg_rtx (SImode);
10569 emit_insn (gen_movsi (reg, gen_rtx (MEM, SImode, in)));
10570 emit_insn (gen_movsi (gen_rtx (MEM, SImode, out), reg));
10571 len -= 4;
10572 offset += 4;
10573 }
10574
10575 if (len >= 2)
10576 {
10577 rtx reg = gen_reg_rtx (HImode);
10578 emit_insn (gen_movhi (reg, gen_rtx (MEM, HImode,
10579 plus_constant (in, offset))));
10580 emit_insn (gen_movhi (gen_rtx (MEM, HImode, plus_constant (out, offset)),
10581 reg));
10582 len -= 2;
10583 offset += 2;
10584 }
10585
10586 if (len)
10587 {
10588 rtx reg = gen_reg_rtx (QImode);
10589 emit_insn (gen_movqi (reg, gen_rtx (MEM, QImode,
10590 plus_constant (in, offset))));
10591 emit_insn (gen_movqi (gen_rtx (MEM, QImode, plus_constant (out, offset)),
10592 reg));
10593 }
10594}
10595
10596int
10597thumb_cmp_operand (op, mode)
10598 rtx op;
10599 enum machine_mode mode;
10600{
10601 return ((GET_CODE (op) == CONST_INT
10602 && (unsigned HOST_WIDE_INT) (INTVAL (op)) < 256)
10603 || register_operand (op, mode));
10604}
10605
cd2b33d0 10606static const char *
d5b7b3ae
RE
10607thumb_condition_code (x, invert)
10608 rtx x;
10609 int invert;
10610{
27c38fbe 10611 static const char *const conds[] =
d5b7b3ae
RE
10612 {
10613 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
10614 "hi", "ls", "ge", "lt", "gt", "le"
10615 };
10616 int val;
10617
10618 switch (GET_CODE (x))
10619 {
10620 case EQ: val = 0; break;
10621 case NE: val = 1; break;
10622 case GEU: val = 2; break;
10623 case LTU: val = 3; break;
10624 case GTU: val = 8; break;
10625 case LEU: val = 9; break;
10626 case GE: val = 10; break;
10627 case LT: val = 11; break;
10628 case GT: val = 12; break;
10629 case LE: val = 13; break;
10630 default:
10631 abort ();
10632 }
10633
10634 return conds[val ^ invert];
10635}
10636
10637/* Handle storing a half-word to memory during reload. */
10638void
10639thumb_reload_out_hi (operands)
10640 rtx * operands;
10641{
10642 emit_insn (gen_thumb_movhi_clobber (operands[0], operands[1], operands[2]));
10643}
10644
10645/* Handle storing a half-word to memory during reload. */
10646void
10647thumb_reload_in_hi (operands)
10648 rtx * operands ATTRIBUTE_UNUSED;
10649{
10650 abort ();
10651}
10652
c27ba912
DM
10653/* Return the length of a function name prefix
10654 that starts with the character 'c'. */
10655static int
10656arm_get_strip_length (char c)
10657{
10658 switch (c)
10659 {
10660 ARM_NAME_ENCODING_LENGTHS
10661 default: return 0;
10662 }
10663}
10664
10665/* Return a pointer to a function's name with any
10666 and all prefix encodings stripped from it. */
10667const char *
10668arm_strip_name_encoding (const char * name)
10669{
10670 int skip;
10671
10672 while ((skip = arm_get_strip_length (* name)))
10673 name += skip;
10674
10675 return name;
10676}
10677
2b835d68 10678#ifdef AOF_ASSEMBLER
6354dc9b 10679/* Special functions only needed when producing AOF syntax assembler. */
2b835d68 10680
32de079a
RE
10681rtx aof_pic_label = NULL_RTX;
10682struct pic_chain
10683{
62b10bbc 10684 struct pic_chain * next;
5f37d07c 10685 const char * symname;
32de079a
RE
10686};
10687
62b10bbc 10688static struct pic_chain * aof_pic_chain = NULL;
32de079a
RE
10689
10690rtx
10691aof_pic_entry (x)
10692 rtx x;
10693{
62b10bbc 10694 struct pic_chain ** chainp;
32de079a
RE
10695 int offset;
10696
10697 if (aof_pic_label == NULL_RTX)
10698 {
92a432f4
RE
10699 /* We mark this here and not in arm_add_gc_roots() to avoid
10700 polluting even more code with ifdefs, and because it never
10701 contains anything useful until we assign to it here. */
5895f793 10702 ggc_add_rtx_root (&aof_pic_label, 1);
43cffd11 10703 aof_pic_label = gen_rtx_SYMBOL_REF (Pmode, "x$adcons");
32de079a
RE
10704 }
10705
10706 for (offset = 0, chainp = &aof_pic_chain; *chainp;
10707 offset += 4, chainp = &(*chainp)->next)
10708 if ((*chainp)->symname == XSTR (x, 0))
10709 return plus_constant (aof_pic_label, offset);
10710
10711 *chainp = (struct pic_chain *) xmalloc (sizeof (struct pic_chain));
10712 (*chainp)->next = NULL;
10713 (*chainp)->symname = XSTR (x, 0);
10714 return plus_constant (aof_pic_label, offset);
10715}
10716
10717void
10718aof_dump_pic_table (f)
62b10bbc 10719 FILE * f;
32de079a 10720{
62b10bbc 10721 struct pic_chain * chain;
32de079a
RE
10722
10723 if (aof_pic_chain == NULL)
10724 return;
10725
dd18ae56
NC
10726 asm_fprintf (f, "\tAREA |%r$$adcons|, BASED %r\n",
10727 PIC_OFFSET_TABLE_REGNUM,
10728 PIC_OFFSET_TABLE_REGNUM);
32de079a
RE
10729 fputs ("|x$adcons|\n", f);
10730
10731 for (chain = aof_pic_chain; chain; chain = chain->next)
10732 {
10733 fputs ("\tDCD\t", f);
10734 assemble_name (f, chain->symname);
10735 fputs ("\n", f);
10736 }
10737}
10738
2b835d68
RE
10739int arm_text_section_count = 1;
10740
10741char *
84ed5e79 10742aof_text_section ()
2b835d68
RE
10743{
10744 static char buf[100];
2b835d68
RE
10745 sprintf (buf, "\tAREA |C$$code%d|, CODE, READONLY",
10746 arm_text_section_count++);
10747 if (flag_pic)
10748 strcat (buf, ", PIC, REENTRANT");
10749 return buf;
10750}
10751
10752static int arm_data_section_count = 1;
10753
10754char *
10755aof_data_section ()
10756{
10757 static char buf[100];
10758 sprintf (buf, "\tAREA |C$$data%d|, DATA", arm_data_section_count++);
10759 return buf;
10760}
10761
10762/* The AOF assembler is religiously strict about declarations of
10763 imported and exported symbols, so that it is impossible to declare
956d6950 10764 a function as imported near the beginning of the file, and then to
2b835d68
RE
10765 export it later on. It is, however, possible to delay the decision
10766 until all the functions in the file have been compiled. To get
10767 around this, we maintain a list of the imports and exports, and
10768 delete from it any that are subsequently defined. At the end of
10769 compilation we spit the remainder of the list out before the END
10770 directive. */
10771
10772struct import
10773{
62b10bbc 10774 struct import * next;
5f37d07c 10775 const char * name;
2b835d68
RE
10776};
10777
62b10bbc 10778static struct import * imports_list = NULL;
2b835d68
RE
10779
10780void
10781aof_add_import (name)
5f37d07c 10782 const char * name;
2b835d68 10783{
62b10bbc 10784 struct import * new;
2b835d68
RE
10785
10786 for (new = imports_list; new; new = new->next)
10787 if (new->name == name)
10788 return;
10789
10790 new = (struct import *) xmalloc (sizeof (struct import));
10791 new->next = imports_list;
10792 imports_list = new;
10793 new->name = name;
10794}
10795
10796void
10797aof_delete_import (name)
5f37d07c 10798 const char * name;
2b835d68 10799{
62b10bbc 10800 struct import ** old;
2b835d68
RE
10801
10802 for (old = &imports_list; *old; old = & (*old)->next)
10803 {
10804 if ((*old)->name == name)
10805 {
10806 *old = (*old)->next;
10807 return;
10808 }
10809 }
10810}
10811
10812int arm_main_function = 0;
10813
10814void
10815aof_dump_imports (f)
62b10bbc 10816 FILE * f;
2b835d68
RE
10817{
10818 /* The AOF assembler needs this to cause the startup code to be extracted
10819 from the library. Brining in __main causes the whole thing to work
10820 automagically. */
10821 if (arm_main_function)
10822 {
10823 text_section ();
10824 fputs ("\tIMPORT __main\n", f);
10825 fputs ("\tDCD __main\n", f);
10826 }
10827
10828 /* Now dump the remaining imports. */
10829 while (imports_list)
10830 {
10831 fprintf (f, "\tIMPORT\t");
10832 assemble_name (f, imports_list->name);
10833 fputc ('\n', f);
10834 imports_list = imports_list->next;
10835 }
10836}
10837#endif /* AOF_ASSEMBLER */
7c262518 10838
ebe413e5 10839#ifdef OBJECT_FORMAT_ELF
7c262518
RH
10840/* Switch to an arbitrary section NAME with attributes as specified
10841 by FLAGS. ALIGN specifies any known alignment requirements for
10842 the section; 0 if the default should be used.
10843
10844 Differs from the default elf version only in the prefix character
10845 used before the section type. */
10846
10847static void
715bdd29 10848arm_elf_asm_named_section (name, flags)
7c262518
RH
10849 const char *name;
10850 unsigned int flags;
7c262518
RH
10851{
10852 char flagchars[8], *f = flagchars;
10853 const char *type;
10854
10855 if (!(flags & SECTION_DEBUG))
10856 *f++ = 'a';
10857 if (flags & SECTION_WRITE)
10858 *f++ = 'w';
10859 if (flags & SECTION_CODE)
10860 *f++ = 'x';
10861 if (flags & SECTION_SMALL)
10862 *f++ = 's';
201556f0
JJ
10863 if (flags & SECTION_MERGE)
10864 *f++ = 'M';
10865 if (flags & SECTION_STRINGS)
10866 *f++ = 'S';
7c262518
RH
10867 *f = '\0';
10868
10869 if (flags & SECTION_BSS)
10870 type = "nobits";
10871 else
10872 type = "progbits";
10873
201556f0
JJ
10874 if (flags & SECTION_ENTSIZE)
10875 fprintf (asm_out_file, "\t.section\t%s,\"%s\",%%%s,%d\n",
10876 name, flagchars, type, flags & SECTION_ENTSIZE);
10877 else
10878 fprintf (asm_out_file, "\t.section\t%s,\"%s\",%%%s\n",
10879 name, flagchars, type);
7c262518 10880}
ebe413e5 10881#endif
This page took 2.657004 seconds and 5 git commands to generate.