]> gcc.gnu.org Git - gcc.git/blame - gcc/config/arm/arm.c
arm.c (ARM_ADDRESS_COST, [...]): Convert macros to inline functions...
[gcc.git] / gcc / config / arm / arm.c
CommitLineData
b36ba79f 1/* Output routines for GCC for ARM.
6bc82793 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
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 7
4f448245 8 This file is part of GCC.
cce8749e 9
4f448245
NC
10 GCC is free software; you can redistribute it and/or modify it
11 under the terms of the GNU General Public License as published
12 by the Free Software Foundation; either version 2, or (at your
13 option) any later version.
cce8749e 14
4f448245
NC
15 GCC is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 License for more details.
cce8749e 19
4f448245
NC
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING. If not, write to
22 the Free Software Foundation, 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
ff9940b0 24
56636818 25#include "config.h"
43cffd11 26#include "system.h"
4977bab6
ZW
27#include "coretypes.h"
28#include "tm.h"
cce8749e 29#include "rtl.h"
d5b7b3ae 30#include "tree.h"
c7319d87 31#include "obstack.h"
cce8749e
CH
32#include "regs.h"
33#include "hard-reg-set.h"
34#include "real.h"
35#include "insn-config.h"
36#include "conditions.h"
cce8749e
CH
37#include "output.h"
38#include "insn-attr.h"
39#include "flags.h"
af48348a 40#include "reload.h"
49ad7cfa 41#include "function.h"
bee06f3d 42#include "expr.h"
e78d8e51 43#include "optabs.h"
ad076f4e 44#include "toplev.h"
aec3cfba 45#include "recog.h"
92a432f4 46#include "ggc.h"
d5b7b3ae 47#include "except.h"
8b97c5f8 48#include "c-pragma.h"
7b8b8ade 49#include "integrate.h"
c27ba912 50#include "tm_p.h"
672a6f42
NB
51#include "target.h"
52#include "target-def.h"
cce8749e 53
d5b7b3ae
RE
54/* Forward definitions of types. */
55typedef struct minipool_node Mnode;
56typedef struct minipool_fixup Mfix;
57
1d6e90ac
NC
58const struct attribute_spec arm_attribute_table[];
59
d5b7b3ae 60/* Forward function declarations. */
e32bac5b
RE
61static void arm_add_gc_roots (void);
62static int arm_gen_constant (enum rtx_code, enum machine_mode, HOST_WIDE_INT,
63 rtx, rtx, int, int);
64static unsigned bit_count (unsigned long);
65static int arm_address_register_rtx_p (rtx, int);
66static int arm_legitimate_index_p (enum machine_mode, rtx, int);
67static int thumb_base_register_rtx_p (rtx, enum machine_mode, int);
68inline static int thumb_index_register_rtx_p (rtx, int);
69static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
e32bac5b
RE
70static rtx emit_multi_reg_push (int);
71static rtx emit_sfm (int, int);
301d03af 72#ifndef AOF_ASSEMBLER
e32bac5b 73static bool arm_assemble_integer (rtx, unsigned int, int);
301d03af 74#endif
e32bac5b
RE
75static const char *fp_const_from_val (REAL_VALUE_TYPE *);
76static arm_cc get_arm_condition_code (rtx);
77static void init_fpa_table (void);
78static HOST_WIDE_INT int_log2 (HOST_WIDE_INT);
79static rtx is_jump_table (rtx);
80static const char *output_multi_immediate (rtx *, const char *, const char *,
81 int, HOST_WIDE_INT);
82static void print_multi_reg (FILE *, const char *, int, int);
83static const char *shift_op (rtx, HOST_WIDE_INT *);
84static struct machine_function *arm_init_machine_status (void);
85static int number_of_first_bit_set (int);
86static void replace_symbols_in_block (tree, rtx, rtx);
87static void thumb_exit (FILE *, int, rtx);
88static void thumb_pushpop (FILE *, int, int);
e32bac5b
RE
89static rtx is_jump_table (rtx);
90static HOST_WIDE_INT get_jump_table_size (rtx);
91static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
92static Mnode *add_minipool_forward_ref (Mfix *);
93static Mnode *move_minipool_fix_backward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
94static Mnode *add_minipool_backward_ref (Mfix *);
95static void assign_minipool_offsets (Mfix *);
96static void arm_print_value (FILE *, rtx);
97static void dump_minipool (rtx);
98static int arm_barrier_cost (rtx);
99static Mfix *create_fix_barrier (Mfix *, HOST_WIDE_INT);
100static void push_minipool_barrier (rtx, HOST_WIDE_INT);
101static void push_minipool_fix (rtx, HOST_WIDE_INT, rtx *, enum machine_mode,
102 rtx);
103static void arm_reorg (void);
104static bool note_invalid_constants (rtx, HOST_WIDE_INT, int);
105static int current_file_function_operand (rtx);
106static unsigned long arm_compute_save_reg0_reg12_mask (void);
107static unsigned long arm_compute_save_reg_mask (void);
108static unsigned long arm_isr_value (tree);
109static unsigned long arm_compute_func_type (void);
110static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
111static tree arm_handle_isr_attribute (tree *, tree, tree, int, bool *);
112static void arm_output_function_epilogue (FILE *, HOST_WIDE_INT);
113static void arm_output_function_prologue (FILE *, HOST_WIDE_INT);
114static void thumb_output_function_prologue (FILE *, HOST_WIDE_INT);
115static int arm_comp_type_attributes (tree, tree);
116static void arm_set_default_type_attributes (tree);
117static int arm_adjust_cost (rtx, rtx, rtx, int);
118static int arm_use_dfa_pipeline_interface (void);
119static int count_insns_for_constant (HOST_WIDE_INT, int);
120static int arm_get_strip_length (int);
121static bool arm_function_ok_for_sibcall (tree, tree);
122static void arm_internal_label (FILE *, const char *, unsigned long);
123static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
124 tree);
125static int arm_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
126static bool arm_rtx_costs (rtx, int, int, int *);
127static int arm_address_cost (rtx);
128static bool arm_memory_load_p (rtx);
129static bool arm_cirrus_insn_p (rtx);
130static void cirrus_reorg (rtx);
5a9335ef
NC
131static void arm_init_builtins (void);
132static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
133static void arm_init_iwmmxt_builtins (void);
134static rtx safe_vector_operand (rtx, enum machine_mode);
135static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
136static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
137static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
138
ebe413e5 139#ifdef OBJECT_FORMAT_ELF
e32bac5b 140static void arm_elf_asm_named_section (const char *, unsigned int);
ebe413e5 141#endif
fb49053f 142#ifndef ARM_PE
e32bac5b 143static void arm_encode_section_info (tree, rtx, int);
fb49053f 144#endif
5eb99654 145#ifdef AOF_ASSEMBLER
e32bac5b
RE
146static void aof_globalize_label (FILE *, const char *);
147static void aof_dump_imports (FILE *);
148static void aof_dump_pic_table (FILE *);
1bc7c5b6 149static void aof_file_start (void);
e32bac5b 150static void aof_file_end (void);
5eb99654 151#endif
c237e94a 152
672a6f42
NB
153\f
154/* Initialize the GCC target structure. */
155#ifdef TARGET_DLLIMPORT_DECL_ATTRIBUTES
1d6e90ac 156#undef TARGET_MERGE_DECL_ATTRIBUTES
672a6f42
NB
157#define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
158#endif
f3bb6135 159
1d6e90ac 160#undef TARGET_ATTRIBUTE_TABLE
91d231cb 161#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
672a6f42 162
301d03af 163#ifdef AOF_ASSEMBLER
1d6e90ac 164#undef TARGET_ASM_BYTE_OP
301d03af 165#define TARGET_ASM_BYTE_OP "\tDCB\t"
1d6e90ac 166#undef TARGET_ASM_ALIGNED_HI_OP
301d03af 167#define TARGET_ASM_ALIGNED_HI_OP "\tDCW\t"
1d6e90ac 168#undef TARGET_ASM_ALIGNED_SI_OP
301d03af 169#define TARGET_ASM_ALIGNED_SI_OP "\tDCD\t"
5eb99654
KG
170#undef TARGET_ASM_GLOBALIZE_LABEL
171#define TARGET_ASM_GLOBALIZE_LABEL aof_globalize_label
1bc7c5b6
ZW
172#undef TARGET_ASM_FILE_START
173#define TARGET_ASM_FILE_START aof_file_start
a5fe455b
ZW
174#undef TARGET_ASM_FILE_END
175#define TARGET_ASM_FILE_END aof_file_end
301d03af 176#else
1d6e90ac 177#undef TARGET_ASM_ALIGNED_SI_OP
301d03af 178#define TARGET_ASM_ALIGNED_SI_OP NULL
1d6e90ac 179#undef TARGET_ASM_INTEGER
301d03af
RS
180#define TARGET_ASM_INTEGER arm_assemble_integer
181#endif
182
1d6e90ac 183#undef TARGET_ASM_FUNCTION_PROLOGUE
08c148a8
NB
184#define TARGET_ASM_FUNCTION_PROLOGUE arm_output_function_prologue
185
1d6e90ac 186#undef TARGET_ASM_FUNCTION_EPILOGUE
08c148a8
NB
187#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
188
1d6e90ac 189#undef TARGET_COMP_TYPE_ATTRIBUTES
8d8e52be
JM
190#define TARGET_COMP_TYPE_ATTRIBUTES arm_comp_type_attributes
191
1d6e90ac 192#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
8d8e52be
JM
193#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES arm_set_default_type_attributes
194
1d6e90ac 195#undef TARGET_SCHED_ADJUST_COST
c237e94a
ZW
196#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
197
103fc15d
BE
198#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
199#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE arm_use_dfa_pipeline_interface
200
fb49053f
RH
201#undef TARGET_ENCODE_SECTION_INFO
202#ifdef ARM_PE
203#define TARGET_ENCODE_SECTION_INFO arm_pe_encode_section_info
204#else
205#define TARGET_ENCODE_SECTION_INFO arm_encode_section_info
206#endif
207
5a9335ef 208#undef TARGET_STRIP_NAME_ENCODING
772c5265
RH
209#define TARGET_STRIP_NAME_ENCODING arm_strip_name_encoding
210
5a9335ef 211#undef TARGET_ASM_INTERNAL_LABEL
4977bab6
ZW
212#define TARGET_ASM_INTERNAL_LABEL arm_internal_label
213
5a9335ef 214#undef TARGET_FUNCTION_OK_FOR_SIBCALL
4977bab6
ZW
215#define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
216
5a9335ef 217#undef TARGET_ASM_OUTPUT_MI_THUNK
c590b625 218#define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
5a9335ef 219#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3961e8fe 220#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
c590b625 221
5a9335ef 222#undef TARGET_RTX_COSTS
3c50106f 223#define TARGET_RTX_COSTS arm_rtx_costs
5a9335ef 224#undef TARGET_ADDRESS_COST
dcefdf67 225#define TARGET_ADDRESS_COST arm_address_cost
3c50106f 226
5a9335ef 227#undef TARGET_MACHINE_DEPENDENT_REORG
18dbd950
RS
228#define TARGET_MACHINE_DEPENDENT_REORG arm_reorg
229
5a9335ef
NC
230#undef TARGET_INIT_BUILTINS
231#define TARGET_INIT_BUILTINS arm_init_builtins
232#undef TARGET_EXPAND_BUILTIN
233#define TARGET_EXPAND_BUILTIN arm_expand_builtin
234
f6897b10 235struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 236\f
c7319d87
RE
237/* Obstack for minipool constant handling. */
238static struct obstack minipool_obstack;
1d6e90ac 239static char * minipool_startobj;
c7319d87 240
1d6e90ac
NC
241/* The maximum number of insns skipped which
242 will be conditionalised if possible. */
c27ba912
DM
243static int max_insns_skipped = 5;
244
245extern FILE * asm_out_file;
246
6354dc9b 247/* True if we are currently building a constant table. */
13bd191d
PB
248int making_const_table;
249
60d0536b 250/* Define the information needed to generate branch insns. This is
6354dc9b 251 stored from the compare operation. */
ff9940b0 252rtx arm_compare_op0, arm_compare_op1;
ff9940b0 253
6354dc9b 254/* What type of floating point are we tuning for? */
29ad9694 255enum fputype arm_fpu_tune;
bee06f3d 256
6354dc9b 257/* What type of floating point instructions are available? */
29ad9694 258enum fputype arm_fpu_arch;
b111229a 259
6354dc9b 260/* What program mode is the cpu running in? 26-bit mode or 32-bit mode. */
2b835d68
RE
261enum prog_mode_type arm_prgmode;
262
6354dc9b 263/* Set by the -mfp=... option. */
f9cc092a 264const char * target_fp_name = NULL;
2b835d68 265
b355a481 266/* Used to parse -mstructure_size_boundary command line option. */
f9cc092a 267const char * structure_size_string = NULL;
723ae7c1 268int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
b355a481 269
aec3cfba 270/* Bit values used to identify processor capabilities. */
62b10bbc
NC
271#define FL_CO_PROC (1 << 0) /* Has external co-processor bus */
272#define FL_FAST_MULT (1 << 1) /* Fast multiply */
273#define FL_MODE26 (1 << 2) /* 26-bit mode support */
274#define FL_MODE32 (1 << 3) /* 32-bit mode support */
275#define FL_ARCH4 (1 << 4) /* Architecture rel 4 */
276#define FL_ARCH5 (1 << 5) /* Architecture rel 5 */
277#define FL_THUMB (1 << 6) /* Thumb aware */
278#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */
279#define FL_STRONG (1 << 8) /* StrongARM */
6bc82793 280#define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */
d19fb8e3 281#define FL_XSCALE (1 << 10) /* XScale */
9b6b54e2 282#define FL_CIRRUS (1 << 11) /* Cirrus/DSP. */
5a9335ef 283#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */
81f9037c
MM
284#define FL_ARCH6J (1 << 12) /* Architecture rel 6. Adds
285 media instructions. */
286#define FL_VFPV2 (1 << 13) /* Vector Floating Point V2. */
aec3cfba 287
1d6e90ac
NC
288/* The bits in this mask specify which
289 instructions we are allowed to generate. */
0977774b 290static unsigned long insn_flags = 0;
d5b7b3ae 291
aec3cfba
NC
292/* The bits in this mask specify which instruction scheduling options should
293 be used. Note - there is an overlap with the FL_FAST_MULT. For some
294 hardware we want to be able to generate the multiply instructions, but to
295 tune as if they were not present in the architecture. */
0977774b 296static unsigned long tune_flags = 0;
aec3cfba
NC
297
298/* The following are used in the arm.md file as equivalents to bits
299 in the above two flag variables. */
300
2b835d68
RE
301/* Nonzero if this is an "M" variant of the processor. */
302int arm_fast_multiply = 0;
303
6354dc9b 304/* Nonzero if this chip supports the ARM Architecture 4 extensions. */
2b835d68
RE
305int arm_arch4 = 0;
306
6354dc9b 307/* Nonzero if this chip supports the ARM Architecture 5 extensions. */
62b10bbc
NC
308int arm_arch5 = 0;
309
b15bca31
RE
310/* Nonzero if this chip supports the ARM Architecture 5E extensions. */
311int arm_arch5e = 0;
312
aec3cfba 313/* Nonzero if this chip can benefit from load scheduling. */
f5a1b0d2
NC
314int arm_ld_sched = 0;
315
316/* Nonzero if this chip is a StrongARM. */
317int arm_is_strong = 0;
318
5a9335ef
NC
319/* Nonzero if this chip supports Intel Wireless MMX technology. */
320int arm_arch_iwmmxt = 0;
321
d19fb8e3 322/* Nonzero if this chip is an XScale. */
4b3c2e48
PB
323int arm_arch_xscale = 0;
324
325/* Nonzero if tuning for XScale */
326int arm_tune_xscale = 0;
d19fb8e3 327
3569057d 328/* Nonzero if this chip is an ARM6 or an ARM7. */
f5a1b0d2 329int arm_is_6_or_7 = 0;
b111229a 330
9b6b54e2
NC
331/* Nonzero if this chip is a Cirrus/DSP. */
332int arm_is_cirrus = 0;
333
0616531f
RE
334/* Nonzero if generating Thumb instructions. */
335int thumb_code = 0;
336
cce8749e
CH
337/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
338 must report the mode of the memory reference from PRINT_OPERAND to
339 PRINT_OPERAND_ADDRESS. */
f3bb6135 340enum machine_mode output_memory_reference_mode;
cce8749e 341
32de079a 342/* The register number to be used for the PIC offset register. */
ed0e6530 343const char * arm_pic_register_string = NULL;
5b43fed1 344int arm_pic_register = INVALID_REGNUM;
32de079a 345
ff9940b0 346/* Set to 1 when a return insn is output, this means that the epilogue
6354dc9b 347 is not needed. */
d5b7b3ae 348int return_used_this_function;
ff9940b0 349
aec3cfba
NC
350/* Set to 1 after arm_reorg has started. Reset to start at the start of
351 the next function. */
4b632bf1
RE
352static int after_arm_reorg = 0;
353
aec3cfba 354/* The maximum number of insns to be used when loading a constant. */
2b835d68
RE
355static int arm_constant_limit = 3;
356
cce8749e
CH
357/* For an explanation of these variables, see final_prescan_insn below. */
358int arm_ccfsm_state;
84ed5e79 359enum arm_cond_code arm_current_cc;
cce8749e
CH
360rtx arm_target_insn;
361int arm_target_label;
9997d19d
RE
362
363/* The condition codes of the ARM, and the inverse function. */
1d6e90ac 364static const char * const arm_condition_codes[] =
9997d19d
RE
365{
366 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
367 "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
368};
369
f5a1b0d2 370#define streq(string1, string2) (strcmp (string1, string2) == 0)
2b835d68 371\f
6354dc9b 372/* Initialization code. */
2b835d68 373
2b835d68
RE
374struct processors
375{
8b60264b 376 const char *const name;
0977774b 377 const unsigned long flags;
2b835d68
RE
378};
379
380/* Not all of these give usefully different compilation alternatives,
381 but there is no simple way of generalizing them. */
8b60264b 382static const struct processors all_cores[] =
f5a1b0d2
NC
383{
384 /* ARM Cores */
385
386 {"arm2", FL_CO_PROC | FL_MODE26 },
387 {"arm250", FL_CO_PROC | FL_MODE26 },
388 {"arm3", FL_CO_PROC | FL_MODE26 },
389 {"arm6", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
390 {"arm60", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
391 {"arm600", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
392 {"arm610", FL_MODE26 | FL_MODE32 },
393 {"arm620", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
949d79eb
RE
394 {"arm7", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
395 /* arm7m doesn't exist on its own, but only with D, (and I), but
d5b7b3ae 396 those don't alter the code, so arm7m is sometimes used. */
949d79eb
RE
397 {"arm7m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
398 {"arm7d", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
399 {"arm7dm", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
400 {"arm7di", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
f5a1b0d2
NC
401 {"arm7dmi", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
402 {"arm70", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
403 {"arm700", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
404 {"arm700i", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
405 {"arm710", FL_MODE26 | FL_MODE32 },
a120a3bd 406 {"arm720", FL_MODE26 | FL_MODE32 },
f5a1b0d2
NC
407 {"arm710c", FL_MODE26 | FL_MODE32 },
408 {"arm7100", FL_MODE26 | FL_MODE32 },
409 {"arm7500", FL_MODE26 | FL_MODE32 },
3b684012 410 /* Doesn't have an external co-proc, but does have embedded fpa. */
949d79eb 411 {"arm7500fe", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
81f9037c 412 /* V4 Architecture Processors */
f5a1b0d2 413 {"arm7tdmi", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
131b9f3d
RE
414 {"arm710t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
415 {"arm720t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
416 {"arm740t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
f5a1b0d2
NC
417 {"arm8", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
418 {"arm810", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
419 {"arm9", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
6cf32035
NC
420 {"arm920", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
421 {"arm920t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
eab4abeb 422 {"arm940t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
f5a1b0d2 423 {"arm9tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED },
eab4abeb 424 {"arm9e", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED },
9b6b54e2 425 {"ep9312", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS },
f5a1b0d2
NC
426 {"strongarm", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
427 {"strongarm110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
428 {"strongarm1100", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
eab4abeb 429 {"strongarm1110", FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_STRONG },
81f9037c 430 /* V5 Architecture Processors */
eab4abeb
NC
431 {"arm10tdmi", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5 },
432 {"arm1020t", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_ARCH5 },
81f9037c
MM
433 {"arm926ejs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
434 {"arm1026ejs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
eab4abeb 435 {"xscale", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE },
5a9335ef 436 {"iwmmxt", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT },
81f9037c
MM
437 /* V6 Architecture Processors */
438 {"arm1136js", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J },
439 {"arm1136jfs", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J | FL_VFPV2 },
f5a1b0d2
NC
440 {NULL, 0}
441};
442
8b60264b 443static const struct processors all_architectures[] =
2b835d68 444{
f5a1b0d2
NC
445 /* ARM Architectures */
446
62b10bbc
NC
447 { "armv2", FL_CO_PROC | FL_MODE26 },
448 { "armv2a", FL_CO_PROC | FL_MODE26 },
449 { "armv3", FL_CO_PROC | FL_MODE26 | FL_MODE32 },
450 { "armv3m", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT },
949d79eb 451 { "armv4", FL_CO_PROC | FL_MODE26 | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 },
b111229a
RE
452 /* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
453 implementations that support it, so we will leave it out for now. */
62b10bbc
NC
454 { "armv4t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB },
455 { "armv5", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
d19fb8e3
NC
456 { "armv5t", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 },
457 { "armv5te", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E },
81f9037c 458 { "armv6j", FL_CO_PROC | FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_ARCH5 | FL_ARCH5E | FL_ARCH6J },
9b6b54e2 459 { "ep9312", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_LDSCHED | FL_CIRRUS },
5a9335ef 460 {"iwmmxt", FL_MODE32 | FL_FAST_MULT | FL_ARCH4 | FL_THUMB | FL_LDSCHED | FL_STRONG | FL_ARCH5 | FL_ARCH5E | FL_XSCALE | FL_IWMMXT },
62b10bbc 461 { NULL, 0 }
f5a1b0d2
NC
462};
463
9a9f7594 464/* This is a magic structure. The 'string' field is magically filled in
f5a1b0d2
NC
465 with a pointer to the value specified by the user on the command line
466 assuming that the user has specified such a value. */
467
468struct arm_cpu_select arm_select[] =
469{
470 /* string name processors */
471 { NULL, "-mcpu=", all_cores },
472 { NULL, "-march=", all_architectures },
473 { NULL, "-mtune=", all_cores }
2b835d68
RE
474};
475
0977774b
JT
476/* Return the number of bits set in VALUE. */
477static unsigned
e32bac5b 478bit_count (unsigned long value)
aec3cfba 479{
d5b7b3ae 480 unsigned long count = 0;
aec3cfba
NC
481
482 while (value)
483 {
0977774b
JT
484 count++;
485 value &= value - 1; /* Clear the least-significant set bit. */
aec3cfba
NC
486 }
487
488 return count;
489}
490
2b835d68
RE
491/* Fix up any incompatible options that the user has specified.
492 This has now turned into a maze. */
493void
e32bac5b 494arm_override_options (void)
2b835d68 495{
ed4c4348 496 unsigned i;
f5a1b0d2
NC
497
498 /* Set up the flags based on the cpu/architecture selected by the user. */
b6a1cbae 499 for (i = ARRAY_SIZE (arm_select); i--;)
bd9c7e23 500 {
f5a1b0d2
NC
501 struct arm_cpu_select * ptr = arm_select + i;
502
503 if (ptr->string != NULL && ptr->string[0] != '\0')
bd9c7e23 504 {
13bd191d 505 const struct processors * sel;
bd9c7e23 506
5895f793 507 for (sel = ptr->processors; sel->name != NULL; sel++)
f5a1b0d2 508 if (streq (ptr->string, sel->name))
bd9c7e23 509 {
aec3cfba
NC
510 if (i == 2)
511 tune_flags = sel->flags;
512 else
b111229a 513 {
aec3cfba
NC
514 /* If we have been given an architecture and a processor
515 make sure that they are compatible. We only generate
516 a warning though, and we prefer the CPU over the
6354dc9b 517 architecture. */
aec3cfba 518 if (insn_flags != 0 && (insn_flags ^ sel->flags))
6cf32035 519 warning ("switch -mcpu=%s conflicts with -march= switch",
aec3cfba
NC
520 ptr->string);
521
522 insn_flags = sel->flags;
b111229a 523 }
f5a1b0d2 524
bd9c7e23
RE
525 break;
526 }
527
528 if (sel->name == NULL)
529 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
530 }
531 }
aec3cfba 532
f5a1b0d2 533 /* If the user did not specify a processor, choose one for them. */
aec3cfba 534 if (insn_flags == 0)
f5a1b0d2 535 {
8b60264b 536 const struct processors * sel;
aec3cfba 537 unsigned int sought;
8b60264b 538 static const struct cpu_default
aec3cfba 539 {
8b60264b
KG
540 const int cpu;
541 const char *const name;
aec3cfba
NC
542 }
543 cpu_defaults[] =
544 {
545 { TARGET_CPU_arm2, "arm2" },
546 { TARGET_CPU_arm6, "arm6" },
547 { TARGET_CPU_arm610, "arm610" },
2aa0c933 548 { TARGET_CPU_arm710, "arm710" },
aec3cfba
NC
549 { TARGET_CPU_arm7m, "arm7m" },
550 { TARGET_CPU_arm7500fe, "arm7500fe" },
551 { TARGET_CPU_arm7tdmi, "arm7tdmi" },
552 { TARGET_CPU_arm8, "arm8" },
553 { TARGET_CPU_arm810, "arm810" },
554 { TARGET_CPU_arm9, "arm9" },
555 { TARGET_CPU_strongarm, "strongarm" },
d19fb8e3 556 { TARGET_CPU_xscale, "xscale" },
9b6b54e2 557 { TARGET_CPU_ep9312, "ep9312" },
5a9335ef 558 { TARGET_CPU_iwmmxt, "iwmmxt" },
81f9037c
MM
559 { TARGET_CPU_arm926ej_s, "arm926ej-s" },
560 { TARGET_CPU_arm1026ej_s, "arm1026ej-s" },
561 { TARGET_CPU_arm1136j_s, "arm1136j_s" },
562 { TARGET_CPU_arm1136jf_s, "arm1136jf_s" },
aec3cfba
NC
563 { TARGET_CPU_generic, "arm" },
564 { 0, 0 }
565 };
8b60264b 566 const struct cpu_default * def;
aec3cfba
NC
567
568 /* Find the default. */
5895f793 569 for (def = cpu_defaults; def->name; def++)
aec3cfba
NC
570 if (def->cpu == TARGET_CPU_DEFAULT)
571 break;
572
573 /* Make sure we found the default CPU. */
574 if (def->name == NULL)
575 abort ();
576
577 /* Find the default CPU's flags. */
5895f793 578 for (sel = all_cores; sel->name != NULL; sel++)
aec3cfba
NC
579 if (streq (def->name, sel->name))
580 break;
581
582 if (sel->name == NULL)
583 abort ();
584
585 insn_flags = sel->flags;
586
587 /* Now check to see if the user has specified some command line
588 switch that require certain abilities from the cpu. */
589 sought = 0;
f5a1b0d2 590
d5b7b3ae 591 if (TARGET_INTERWORK || TARGET_THUMB)
f5a1b0d2 592 {
aec3cfba
NC
593 sought |= (FL_THUMB | FL_MODE32);
594
595 /* Force apcs-32 to be used for interworking. */
f5a1b0d2 596 target_flags |= ARM_FLAG_APCS_32;
aec3cfba 597
d5b7b3ae 598 /* There are no ARM processors that support both APCS-26 and
aec3cfba
NC
599 interworking. Therefore we force FL_MODE26 to be removed
600 from insn_flags here (if it was set), so that the search
601 below will always be able to find a compatible processor. */
5895f793 602 insn_flags &= ~FL_MODE26;
f5a1b0d2 603 }
5895f793 604 else if (!TARGET_APCS_32)
f5a1b0d2 605 sought |= FL_MODE26;
d5b7b3ae 606
aec3cfba 607 if (sought != 0 && ((sought & insn_flags) != sought))
f5a1b0d2 608 {
aec3cfba
NC
609 /* Try to locate a CPU type that supports all of the abilities
610 of the default CPU, plus the extra abilities requested by
611 the user. */
5895f793 612 for (sel = all_cores; sel->name != NULL; sel++)
aec3cfba 613 if ((sel->flags & sought) == (sought | insn_flags))
f5a1b0d2
NC
614 break;
615
616 if (sel->name == NULL)
aec3cfba 617 {
0977774b 618 unsigned current_bit_count = 0;
8b60264b 619 const struct processors * best_fit = NULL;
aec3cfba
NC
620
621 /* Ideally we would like to issue an error message here
622 saying that it was not possible to find a CPU compatible
623 with the default CPU, but which also supports the command
624 line options specified by the programmer, and so they
625 ought to use the -mcpu=<name> command line option to
626 override the default CPU type.
627
628 Unfortunately this does not work with multilibing. We
629 need to be able to support multilibs for -mapcs-26 and for
630 -mthumb-interwork and there is no CPU that can support both
631 options. Instead if we cannot find a cpu that has both the
632 characteristics of the default cpu and the given command line
633 options we scan the array again looking for a best match. */
5895f793 634 for (sel = all_cores; sel->name != NULL; sel++)
aec3cfba
NC
635 if ((sel->flags & sought) == sought)
636 {
0977774b 637 unsigned count;
aec3cfba
NC
638
639 count = bit_count (sel->flags & insn_flags);
640
641 if (count >= current_bit_count)
642 {
643 best_fit = sel;
644 current_bit_count = count;
645 }
646 }
f5a1b0d2 647
aec3cfba
NC
648 if (best_fit == NULL)
649 abort ();
650 else
651 sel = best_fit;
652 }
653
654 insn_flags = sel->flags;
f5a1b0d2
NC
655 }
656 }
aec3cfba
NC
657
658 /* If tuning has not been specified, tune for whichever processor or
659 architecture has been selected. */
660 if (tune_flags == 0)
661 tune_flags = insn_flags;
e26053d1 662
f5a1b0d2
NC
663 /* Make sure that the processor choice does not conflict with any of the
664 other command line choices. */
aec3cfba 665 if (TARGET_APCS_32 && !(insn_flags & FL_MODE32))
f5a1b0d2 666 {
aec3cfba
NC
667 /* If APCS-32 was not the default then it must have been set by the
668 user, so issue a warning message. If the user has specified
669 "-mapcs-32 -mcpu=arm2" then we loose here. */
670 if ((TARGET_DEFAULT & ARM_FLAG_APCS_32) == 0)
671 warning ("target CPU does not support APCS-32" );
5895f793 672 target_flags &= ~ARM_FLAG_APCS_32;
f5a1b0d2 673 }
5895f793 674 else if (!TARGET_APCS_32 && !(insn_flags & FL_MODE26))
f5a1b0d2
NC
675 {
676 warning ("target CPU does not support APCS-26" );
677 target_flags |= ARM_FLAG_APCS_32;
678 }
679
6cfc7210 680 if (TARGET_INTERWORK && !(insn_flags & FL_THUMB))
f5a1b0d2
NC
681 {
682 warning ("target CPU does not support interworking" );
6cfc7210 683 target_flags &= ~ARM_FLAG_INTERWORK;
f5a1b0d2
NC
684 }
685
d5b7b3ae
RE
686 if (TARGET_THUMB && !(insn_flags & FL_THUMB))
687 {
c725bd79 688 warning ("target CPU does not support THUMB instructions");
d5b7b3ae
RE
689 target_flags &= ~ARM_FLAG_THUMB;
690 }
691
692 if (TARGET_APCS_FRAME && TARGET_THUMB)
693 {
c725bd79 694 /* warning ("ignoring -mapcs-frame because -mthumb was used"); */
d5b7b3ae
RE
695 target_flags &= ~ARM_FLAG_APCS_FRAME;
696 }
d19fb8e3 697
d5b7b3ae
RE
698 /* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done
699 from here where no function is being compiled currently. */
700 if ((target_flags & (THUMB_FLAG_LEAF_BACKTRACE | THUMB_FLAG_BACKTRACE))
701 && TARGET_ARM)
c725bd79 702 warning ("enabling backtrace support is only meaningful when compiling for the Thumb");
d5b7b3ae
RE
703
704 if (TARGET_ARM && TARGET_CALLEE_INTERWORKING)
c725bd79 705 warning ("enabling callee interworking support is only meaningful when compiling for the Thumb");
d5b7b3ae
RE
706
707 if (TARGET_ARM && TARGET_CALLER_INTERWORKING)
c725bd79 708 warning ("enabling caller interworking support is only meaningful when compiling for the Thumb");
d5b7b3ae 709
f5a1b0d2 710 /* If interworking is enabled then APCS-32 must be selected as well. */
6cfc7210 711 if (TARGET_INTERWORK)
f5a1b0d2 712 {
5895f793 713 if (!TARGET_APCS_32)
f5a1b0d2
NC
714 warning ("interworking forces APCS-32 to be used" );
715 target_flags |= ARM_FLAG_APCS_32;
716 }
717
5895f793 718 if (TARGET_APCS_STACK && !TARGET_APCS_FRAME)
f5a1b0d2
NC
719 {
720 warning ("-mapcs-stack-check incompatible with -mno-apcs-frame");
721 target_flags |= ARM_FLAG_APCS_FRAME;
722 }
aec3cfba 723
2b835d68
RE
724 if (TARGET_POKE_FUNCTION_NAME)
725 target_flags |= ARM_FLAG_APCS_FRAME;
aec3cfba 726
2b835d68 727 if (TARGET_APCS_REENT && flag_pic)
400500c4 728 error ("-fpic and -mapcs-reent are incompatible");
aec3cfba 729
2b835d68 730 if (TARGET_APCS_REENT)
f5a1b0d2 731 warning ("APCS reentrant code not supported. Ignored");
aec3cfba 732
d5b7b3ae
RE
733 /* If this target is normally configured to use APCS frames, warn if they
734 are turned off and debugging is turned on. */
735 if (TARGET_ARM
736 && write_symbols != NO_DEBUG
5895f793 737 && !TARGET_APCS_FRAME
d5b7b3ae
RE
738 && (TARGET_DEFAULT & ARM_FLAG_APCS_FRAME))
739 warning ("-g with -mno-apcs-frame may not give sensible debugging");
6cfc7210 740
32de079a
RE
741 /* If stack checking is disabled, we can use r10 as the PIC register,
742 which keeps r9 available. */
5b43fed1
RH
743 if (flag_pic)
744 arm_pic_register = TARGET_APCS_STACK ? 9 : 10;
aec3cfba 745
2b835d68 746 if (TARGET_APCS_FLOAT)
c725bd79 747 warning ("passing floating point arguments in fp regs not yet supported");
f5a1b0d2 748
4912a07c 749 /* Initialize boolean versions of the flags, for use in the arm.md file. */
2ca12935
JL
750 arm_fast_multiply = (insn_flags & FL_FAST_MULT) != 0;
751 arm_arch4 = (insn_flags & FL_ARCH4) != 0;
752 arm_arch5 = (insn_flags & FL_ARCH5) != 0;
b15bca31 753 arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
4b3c2e48 754 arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
6f7ebcbb 755
2ca12935
JL
756 arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
757 arm_is_strong = (tune_flags & FL_STRONG) != 0;
0616531f 758 thumb_code = (TARGET_ARM == 0);
d5b7b3ae
RE
759 arm_is_6_or_7 = (((tune_flags & (FL_MODE26 | FL_MODE32))
760 && !(tune_flags & FL_ARCH4))) != 0;
4b3c2e48 761 arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
9b6b54e2 762 arm_is_cirrus = (tune_flags & FL_CIRRUS) != 0;
5a9335ef
NC
763 arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
764
765 if (TARGET_IWMMXT && (! TARGET_ATPCS))
766 target_flags |= ARM_FLAG_ATPCS;
6f7ebcbb 767
9b6b54e2
NC
768 if (arm_is_cirrus)
769 {
29ad9694 770 arm_fpu_tune = FPUTYPE_MAVERICK;
9b6b54e2
NC
771
772 /* Ignore -mhard-float if -mcpu=ep9312. */
773 if (TARGET_HARD_FLOAT)
774 target_flags ^= ARM_FLAG_SOFT_FLOAT;
775 }
776 else
777 /* Default value for floating point code... if no co-processor
778 bus, then schedule for emulated floating point. Otherwise,
779 assume the user has an FPA.
780 Note: this does not prevent use of floating point instructions,
781 -msoft-float does that. */
29ad9694 782 arm_fpu_tune = (tune_flags & FL_CO_PROC) ? FPUTYPE_FPA : FPUTYPE_FPA_EMU3;
f5a1b0d2 783
b111229a 784 if (target_fp_name)
2b835d68 785 {
f5a1b0d2 786 if (streq (target_fp_name, "2"))
29ad9694 787 arm_fpu_arch = FPUTYPE_FPA_EMU2;
f5a1b0d2 788 else if (streq (target_fp_name, "3"))
29ad9694 789 arm_fpu_arch = FPUTYPE_FPA_EMU3;
2b835d68 790 else
c725bd79 791 error ("invalid floating point emulation option: -mfpe-%s",
b111229a 792 target_fp_name);
2b835d68 793 }
b111229a 794 else
29ad9694 795 arm_fpu_arch = FPUTYPE_DEFAULT;
f5a1b0d2 796
9b6b54e2
NC
797 if (TARGET_FPE)
798 {
29ad9694
RE
799 if (arm_fpu_tune == FPUTYPE_FPA_EMU3)
800 arm_fpu_tune = FPUTYPE_FPA_EMU2;
801 else if (arm_fpu_tune == FPUTYPE_MAVERICK)
802 warning ("-mfpe switch not supported by ep9312 target cpu - ignored.");
803 else if (arm_fpu_tune != FPUTYPE_FPA)
804 arm_fpu_tune = FPUTYPE_FPA_EMU2;
9b6b54e2 805 }
aec3cfba 806
f5a1b0d2
NC
807 /* For arm2/3 there is no need to do any scheduling if there is only
808 a floating point emulator, or we are doing software floating-point. */
29ad9694 809 if ((TARGET_SOFT_FLOAT || arm_fpu_tune != FPUTYPE_FPA)
ed0e6530 810 && (tune_flags & FL_MODE32) == 0)
f5a1b0d2 811 flag_schedule_insns = flag_schedule_insns_after_reload = 0;
aec3cfba 812
cd2b33d0 813 arm_prgmode = TARGET_APCS_32 ? PROG_MODE_PROG32 : PROG_MODE_PROG26;
b355a481
NC
814
815 if (structure_size_string != NULL)
816 {
817 int size = strtol (structure_size_string, NULL, 0);
818
819 if (size == 8 || size == 32)
820 arm_structure_size_boundary = size;
821 else
c725bd79 822 warning ("structure size boundary can only be set to 8 or 32");
b355a481 823 }
ed0e6530
PB
824
825 if (arm_pic_register_string != NULL)
826 {
5b43fed1 827 int pic_register = decode_reg_name (arm_pic_register_string);
e26053d1 828
5895f793 829 if (!flag_pic)
ed0e6530
PB
830 warning ("-mpic-register= is useless without -fpic");
831
ed0e6530 832 /* Prevent the user from choosing an obviously stupid PIC register. */
5b43fed1
RH
833 else if (pic_register < 0 || call_used_regs[pic_register]
834 || pic_register == HARD_FRAME_POINTER_REGNUM
835 || pic_register == STACK_POINTER_REGNUM
836 || pic_register >= PC_REGNUM)
c725bd79 837 error ("unable to use '%s' for PIC register", arm_pic_register_string);
ed0e6530
PB
838 else
839 arm_pic_register = pic_register;
840 }
d5b7b3ae
RE
841
842 if (TARGET_THUMB && flag_schedule_insns)
843 {
844 /* Don't warn since it's on by default in -O2. */
845 flag_schedule_insns = 0;
846 }
847
f5a1b0d2 848 if (optimize_size)
be03ccc9 849 {
577d6328
RE
850 /* There's some dispute as to whether this should be 1 or 2. However,
851 experiments seem to show that in pathological cases a setting of
852 1 degrades less severly than a setting of 2. This could change if
853 other parts of the compiler change their behavior. */
854 arm_constant_limit = 1;
be03ccc9
NP
855
856 /* If optimizing for size, bump the number of instructions that we
857 are prepared to conditionally execute (even on a StrongARM). */
858 max_insns_skipped = 6;
859 }
860 else
861 {
862 /* For processors with load scheduling, it never costs more than
863 2 cycles to load a constant, and the load scheduler may well
864 reduce that to 1. */
865 if (tune_flags & FL_LDSCHED)
866 arm_constant_limit = 1;
867
868 /* On XScale the longer latency of a load makes it more difficult
869 to achieve a good schedule, so it's faster to synthesize
870 constants that can be done in two insns. */
871 if (arm_tune_xscale)
872 arm_constant_limit = 2;
873
874 /* StrongARM has early execution of branches, so a sequence
875 that is worth skipping is shorter. */
876 if (arm_is_strong)
877 max_insns_skipped = 3;
878 }
92a432f4
RE
879
880 /* Register global variables with the garbage collector. */
881 arm_add_gc_roots ();
882}
883
884static void
e32bac5b 885arm_add_gc_roots (void)
92a432f4 886{
c7319d87
RE
887 gcc_obstack_init(&minipool_obstack);
888 minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
2b835d68 889}
cce8749e 890\f
6d3d9133
NC
891/* A table of known ARM exception types.
892 For use with the interrupt function attribute. */
893
894typedef struct
895{
8b60264b
KG
896 const char *const arg;
897 const unsigned long return_value;
6d3d9133
NC
898}
899isr_attribute_arg;
900
8b60264b 901static const isr_attribute_arg isr_attribute_args [] =
6d3d9133
NC
902{
903 { "IRQ", ARM_FT_ISR },
904 { "irq", ARM_FT_ISR },
905 { "FIQ", ARM_FT_FIQ },
906 { "fiq", ARM_FT_FIQ },
907 { "ABORT", ARM_FT_ISR },
908 { "abort", ARM_FT_ISR },
909 { "ABORT", ARM_FT_ISR },
910 { "abort", ARM_FT_ISR },
911 { "UNDEF", ARM_FT_EXCEPTION },
912 { "undef", ARM_FT_EXCEPTION },
913 { "SWI", ARM_FT_EXCEPTION },
914 { "swi", ARM_FT_EXCEPTION },
915 { NULL, ARM_FT_NORMAL }
916};
917
918/* Returns the (interrupt) function type of the current
919 function, or ARM_FT_UNKNOWN if the type cannot be determined. */
920
921static unsigned long
e32bac5b 922arm_isr_value (tree argument)
6d3d9133 923{
8b60264b 924 const isr_attribute_arg * ptr;
1d6e90ac 925 const char * arg;
6d3d9133
NC
926
927 /* No argument - default to IRQ. */
928 if (argument == NULL_TREE)
929 return ARM_FT_ISR;
930
931 /* Get the value of the argument. */
932 if (TREE_VALUE (argument) == NULL_TREE
933 || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
934 return ARM_FT_UNKNOWN;
935
936 arg = TREE_STRING_POINTER (TREE_VALUE (argument));
937
938 /* Check it against the list of known arguments. */
5a9335ef 939 for (ptr = isr_attribute_args; ptr->arg != NULL; ptr++)
1d6e90ac
NC
940 if (streq (arg, ptr->arg))
941 return ptr->return_value;
6d3d9133 942
05713b80 943 /* An unrecognized interrupt type. */
6d3d9133
NC
944 return ARM_FT_UNKNOWN;
945}
946
947/* Computes the type of the current function. */
948
949static unsigned long
e32bac5b 950arm_compute_func_type (void)
6d3d9133
NC
951{
952 unsigned long type = ARM_FT_UNKNOWN;
953 tree a;
954 tree attr;
955
956 if (TREE_CODE (current_function_decl) != FUNCTION_DECL)
957 abort ();
958
959 /* Decide if the current function is volatile. Such functions
960 never return, and many memory cycles can be saved by not storing
961 register values that will never be needed again. This optimization
962 was added to speed up context switching in a kernel application. */
963 if (optimize > 0
964 && current_function_nothrow
965 && TREE_THIS_VOLATILE (current_function_decl))
966 type |= ARM_FT_VOLATILE;
967
968 if (current_function_needs_context)
969 type |= ARM_FT_NESTED;
970
91d231cb 971 attr = DECL_ATTRIBUTES (current_function_decl);
6d3d9133
NC
972
973 a = lookup_attribute ("naked", attr);
974 if (a != NULL_TREE)
975 type |= ARM_FT_NAKED;
976
977 if (cfun->machine->eh_epilogue_sp_ofs != NULL_RTX)
978 type |= ARM_FT_EXCEPTION_HANDLER;
979 else
980 {
981 a = lookup_attribute ("isr", attr);
982 if (a == NULL_TREE)
983 a = lookup_attribute ("interrupt", attr);
984
985 if (a == NULL_TREE)
986 type |= TARGET_INTERWORK ? ARM_FT_INTERWORKED : ARM_FT_NORMAL;
987 else
988 type |= arm_isr_value (TREE_VALUE (a));
989 }
990
991 return type;
992}
993
994/* Returns the type of the current function. */
995
996unsigned long
e32bac5b 997arm_current_func_type (void)
6d3d9133
NC
998{
999 if (ARM_FUNC_TYPE (cfun->machine->func_type) == ARM_FT_UNKNOWN)
1000 cfun->machine->func_type = arm_compute_func_type ();
1001
1002 return cfun->machine->func_type;
1003}
1004\f
a72d4945
RE
1005/* Return 1 if it is possible to return using a single instruction.
1006 If SIBLING is non-null, this is a test for a return before a sibling
1007 call. SIBLING is the call insn, so we can examine its register usage. */
6d3d9133 1008
ff9940b0 1009int
a72d4945 1010use_return_insn (int iscond, rtx sibling)
ff9940b0
RE
1011{
1012 int regno;
9b598fa0 1013 unsigned int func_type;
d5db54a1 1014 unsigned long saved_int_regs;
a72d4945 1015 unsigned HOST_WIDE_INT stack_adjust;
ff9940b0 1016
d5b7b3ae 1017 /* Never use a return instruction before reload has run. */
6d3d9133
NC
1018 if (!reload_completed)
1019 return 0;
efc2515b 1020
9b598fa0
RE
1021 func_type = arm_current_func_type ();
1022
3a7731fd
PB
1023 /* Naked functions and volatile functions need special
1024 consideration. */
1025 if (func_type & (ARM_FT_VOLATILE | ARM_FT_NAKED))
6d3d9133 1026 return 0;
06bea5aa
NC
1027
1028 /* So do interrupt functions that use the frame pointer. */
1029 if (IS_INTERRUPT (func_type) && frame_pointer_needed)
1030 return 0;
a72d4945
RE
1031
1032 stack_adjust = arm_get_frame_size () + current_function_outgoing_args_size;
1033
6d3d9133
NC
1034 /* As do variadic functions. */
1035 if (current_function_pretend_args_size
3cb66fd7 1036 || cfun->machine->uses_anonymous_args
699a4925 1037 /* Or if the function calls __builtin_eh_return () */
6d3d9133 1038 || ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
699a4925
RE
1039 /* Or if the function calls alloca */
1040 || current_function_calls_alloca
a72d4945
RE
1041 /* Or if there is a stack adjustment. However, if the stack pointer
1042 is saved on the stack, we can use a pre-incrementing stack load. */
1043 || !(stack_adjust == 0 || (frame_pointer_needed && stack_adjust == 4)))
ff9940b0
RE
1044 return 0;
1045
d5db54a1
RE
1046 saved_int_regs = arm_compute_save_reg_mask ();
1047
a72d4945
RE
1048 /* Unfortunately, the insn
1049
1050 ldmib sp, {..., sp, ...}
1051
1052 triggers a bug on most SA-110 based devices, such that the stack
1053 pointer won't be correctly restored if the instruction takes a
1054 page fault. We work around this problem by poping r3 along with
1055 the other registers, since that is never slower than executing
1056 another instruction.
1057
1058 We test for !arm_arch5 here, because code for any architecture
1059 less than this could potentially be run on one of the buggy
1060 chips. */
1061 if (stack_adjust == 4 && !arm_arch5)
1062 {
1063 /* Validate that r3 is a call-clobbered register (always true in
1064 the default abi) ... */
1065 if (!call_used_regs[3])
1066 return 0;
1067
1068 /* ... that it isn't being used for a return value (always true
1069 until we implement return-in-regs), or for a tail-call
1070 argument ... */
1071 if (sibling)
1072 {
1073 if (GET_CODE (sibling) != CALL_INSN)
1074 abort ();
1075
1076 if (find_regno_fusage (sibling, USE, 3))
1077 return 0;
1078 }
1079
1080 /* ... and that there are no call-saved registers in r0-r2
1081 (always true in the default ABI). */
1082 if (saved_int_regs & 0x7)
1083 return 0;
1084 }
1085
b111229a 1086 /* Can't be done if interworking with Thumb, and any registers have been
d5db54a1
RE
1087 stacked. */
1088 if (TARGET_INTERWORK && saved_int_regs != 0)
b36ba79f 1089 return 0;
d5db54a1
RE
1090
1091 /* On StrongARM, conditional returns are expensive if they aren't
1092 taken and multiple registers have been stacked. */
1093 if (iscond && arm_is_strong)
6ed30148 1094 {
d5db54a1
RE
1095 /* Conditional return when just the LR is stored is a simple
1096 conditional-load instruction, that's not expensive. */
1097 if (saved_int_regs != 0 && saved_int_regs != (1 << LR_REGNUM))
1098 return 0;
6ed30148
RE
1099
1100 if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
b111229a 1101 return 0;
6ed30148 1102 }
d5db54a1
RE
1103
1104 /* If there are saved registers but the LR isn't saved, then we need
1105 two instructions for the return. */
1106 if (saved_int_regs && !(saved_int_regs & (1 << LR_REGNUM)))
1107 return 0;
1108
3b684012 1109 /* Can't be done if any of the FPA regs are pushed,
6d3d9133 1110 since this also requires an insn. */
d5b7b3ae
RE
1111 if (TARGET_HARD_FLOAT)
1112 for (regno = FIRST_ARM_FP_REGNUM; regno <= LAST_ARM_FP_REGNUM; regno++)
5895f793 1113 if (regs_ever_live[regno] && !call_used_regs[regno])
d5b7b3ae 1114 return 0;
ff9940b0 1115
5a9335ef
NC
1116 if (TARGET_REALLY_IWMMXT)
1117 for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
1118 if (regs_ever_live[regno] && ! call_used_regs [regno])
1119 return 0;
1120
ff9940b0
RE
1121 return 1;
1122}
1123
cce8749e
CH
1124/* Return TRUE if int I is a valid immediate ARM constant. */
1125
1126int
e32bac5b 1127const_ok_for_arm (HOST_WIDE_INT i)
cce8749e 1128{
30cf4896 1129 unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT)0xFF;
cce8749e 1130
56636818
JL
1131 /* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must
1132 be all zero, or all one. */
30cf4896
KG
1133 if ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0
1134 && ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff)
1135 != ((~(unsigned HOST_WIDE_INT) 0)
1136 & ~(unsigned HOST_WIDE_INT) 0xffffffff)))
56636818
JL
1137 return FALSE;
1138
e2c671ba
RE
1139 /* Fast return for 0 and powers of 2 */
1140 if ((i & (i - 1)) == 0)
1141 return TRUE;
1142
cce8749e
CH
1143 do
1144 {
30cf4896 1145 if ((i & mask & (unsigned HOST_WIDE_INT) 0xffffffff) == 0)
f3bb6135 1146 return TRUE;
abaa26e5 1147 mask =
30cf4896
KG
1148 (mask << 2) | ((mask & (unsigned HOST_WIDE_INT) 0xffffffff)
1149 >> (32 - 2)) | ~(unsigned HOST_WIDE_INT) 0xffffffff;
ebe413e5
NC
1150 }
1151 while (mask != ~(unsigned HOST_WIDE_INT) 0xFF);
cce8749e 1152
f3bb6135
RE
1153 return FALSE;
1154}
cce8749e 1155
6354dc9b 1156/* Return true if I is a valid constant for the operation CODE. */
74bbc178 1157static int
e32bac5b 1158const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
e2c671ba
RE
1159{
1160 if (const_ok_for_arm (i))
1161 return 1;
1162
1163 switch (code)
1164 {
1165 case PLUS:
1166 return const_ok_for_arm (ARM_SIGN_EXTEND (-i));
1167
1168 case MINUS: /* Should only occur with (MINUS I reg) => rsb */
1169 case XOR:
1170 case IOR:
1171 return 0;
1172
1173 case AND:
1174 return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
1175
1176 default:
1177 abort ();
1178 }
1179}
1180
1181/* Emit a sequence of insns to handle a large constant.
1182 CODE is the code of the operation required, it can be any of SET, PLUS,
1183 IOR, AND, XOR, MINUS;
1184 MODE is the mode in which the operation is being performed;
1185 VAL is the integer to operate on;
1186 SOURCE is the other operand (a register, or a null-pointer for SET);
1187 SUBTARGETS means it is safe to create scratch registers if that will
2b835d68
RE
1188 either produce a simpler sequence, or we will want to cse the values.
1189 Return value is the number of insns emitted. */
e2c671ba
RE
1190
1191int
e32bac5b
RE
1192arm_split_constant (enum rtx_code code, enum machine_mode mode,
1193 HOST_WIDE_INT val, rtx target, rtx source, int subtargets)
2b835d68
RE
1194{
1195 if (subtargets || code == SET
1196 || (GET_CODE (target) == REG && GET_CODE (source) == REG
1197 && REGNO (target) != REGNO (source)))
1198 {
4b632bf1 1199 /* After arm_reorg has been called, we can't fix up expensive
05713b80 1200 constants by pushing them into memory so we must synthesize
4b632bf1
RE
1201 them in-line, regardless of the cost. This is only likely to
1202 be more costly on chips that have load delay slots and we are
1203 compiling without running the scheduler (so no splitting
aec3cfba
NC
1204 occurred before the final instruction emission).
1205
1206 Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
aec3cfba 1207 */
5895f793 1208 if (!after_arm_reorg
4b632bf1
RE
1209 && (arm_gen_constant (code, mode, val, target, source, 1, 0)
1210 > arm_constant_limit + (code != SET)))
2b835d68
RE
1211 {
1212 if (code == SET)
1213 {
1214 /* Currently SET is the only monadic value for CODE, all
1215 the rest are diadic. */
43cffd11 1216 emit_insn (gen_rtx_SET (VOIDmode, target, GEN_INT (val)));
2b835d68
RE
1217 return 1;
1218 }
1219 else
1220 {
1221 rtx temp = subtargets ? gen_reg_rtx (mode) : target;
1222
43cffd11 1223 emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (val)));
2b835d68
RE
1224 /* For MINUS, the value is subtracted from, since we never
1225 have subtraction of a constant. */
1226 if (code == MINUS)
43cffd11 1227 emit_insn (gen_rtx_SET (VOIDmode, target,
d5b7b3ae 1228 gen_rtx_MINUS (mode, temp, source)));
2b835d68 1229 else
43cffd11
RE
1230 emit_insn (gen_rtx_SET (VOIDmode, target,
1231 gen_rtx (code, mode, source, temp)));
2b835d68
RE
1232 return 2;
1233 }
1234 }
1235 }
1236
1237 return arm_gen_constant (code, mode, val, target, source, subtargets, 1);
1238}
1239
ceebdb09 1240static int
e32bac5b 1241count_insns_for_constant (HOST_WIDE_INT remainder, int i)
ceebdb09
PB
1242{
1243 HOST_WIDE_INT temp1;
1244 int num_insns = 0;
1245 do
1246 {
1247 int end;
1248
1249 if (i <= 0)
1250 i += 32;
1251 if (remainder & (3 << (i - 2)))
1252 {
1253 end = i - 8;
1254 if (end < 0)
1255 end += 32;
1256 temp1 = remainder & ((0x0ff << end)
1257 | ((i < end) ? (0xff >> (32 - end)) : 0));
1258 remainder &= ~temp1;
1259 num_insns++;
1260 i -= 6;
1261 }
1262 i -= 2;
1263 } while (remainder);
1264 return num_insns;
1265}
1266
2b835d68
RE
1267/* As above, but extra parameter GENERATE which, if clear, suppresses
1268 RTL generation. */
1d6e90ac 1269
d5b7b3ae 1270static int
e32bac5b
RE
1271arm_gen_constant (enum rtx_code code, enum machine_mode mode,
1272 HOST_WIDE_INT val, rtx target, rtx source, int subtargets,
1273 int generate)
e2c671ba 1274{
e2c671ba
RE
1275 int can_invert = 0;
1276 int can_negate = 0;
1277 int can_negate_initial = 0;
1278 int can_shift = 0;
1279 int i;
1280 int num_bits_set = 0;
1281 int set_sign_bit_copies = 0;
1282 int clear_sign_bit_copies = 0;
1283 int clear_zero_bit_copies = 0;
1284 int set_zero_bit_copies = 0;
1285 int insns = 0;
e2c671ba 1286 unsigned HOST_WIDE_INT temp1, temp2;
30cf4896 1287 unsigned HOST_WIDE_INT remainder = val & 0xffffffff;
e2c671ba 1288
d5b7b3ae 1289 /* Find out which operations are safe for a given CODE. Also do a quick
e2c671ba
RE
1290 check for degenerate cases; these can occur when DImode operations
1291 are split. */
1292 switch (code)
1293 {
1294 case SET:
1295 can_invert = 1;
1296 can_shift = 1;
1297 can_negate = 1;
1298 break;
1299
1300 case PLUS:
1301 can_negate = 1;
1302 can_negate_initial = 1;
1303 break;
1304
1305 case IOR:
30cf4896 1306 if (remainder == 0xffffffff)
e2c671ba 1307 {
2b835d68 1308 if (generate)
43cffd11
RE
1309 emit_insn (gen_rtx_SET (VOIDmode, target,
1310 GEN_INT (ARM_SIGN_EXTEND (val))));
e2c671ba
RE
1311 return 1;
1312 }
1313 if (remainder == 0)
1314 {
1315 if (reload_completed && rtx_equal_p (target, source))
1316 return 0;
2b835d68 1317 if (generate)
43cffd11 1318 emit_insn (gen_rtx_SET (VOIDmode, target, source));
e2c671ba
RE
1319 return 1;
1320 }
1321 break;
1322
1323 case AND:
1324 if (remainder == 0)
1325 {
2b835d68 1326 if (generate)
43cffd11 1327 emit_insn (gen_rtx_SET (VOIDmode, target, const0_rtx));
e2c671ba
RE
1328 return 1;
1329 }
30cf4896 1330 if (remainder == 0xffffffff)
e2c671ba
RE
1331 {
1332 if (reload_completed && rtx_equal_p (target, source))
1333 return 0;
2b835d68 1334 if (generate)
43cffd11 1335 emit_insn (gen_rtx_SET (VOIDmode, target, source));
e2c671ba
RE
1336 return 1;
1337 }
1338 can_invert = 1;
1339 break;
1340
1341 case XOR:
1342 if (remainder == 0)
1343 {
1344 if (reload_completed && rtx_equal_p (target, source))
1345 return 0;
2b835d68 1346 if (generate)
43cffd11 1347 emit_insn (gen_rtx_SET (VOIDmode, target, source));
e2c671ba
RE
1348 return 1;
1349 }
30cf4896 1350 if (remainder == 0xffffffff)
e2c671ba 1351 {
2b835d68 1352 if (generate)
43cffd11
RE
1353 emit_insn (gen_rtx_SET (VOIDmode, target,
1354 gen_rtx_NOT (mode, source)));
e2c671ba
RE
1355 return 1;
1356 }
1357
1358 /* We don't know how to handle this yet below. */
1359 abort ();
1360
1361 case MINUS:
1362 /* We treat MINUS as (val - source), since (source - val) is always
1363 passed as (source + (-val)). */
1364 if (remainder == 0)
1365 {
2b835d68 1366 if (generate)
43cffd11
RE
1367 emit_insn (gen_rtx_SET (VOIDmode, target,
1368 gen_rtx_NEG (mode, source)));
e2c671ba
RE
1369 return 1;
1370 }
1371 if (const_ok_for_arm (val))
1372 {
2b835d68 1373 if (generate)
43cffd11
RE
1374 emit_insn (gen_rtx_SET (VOIDmode, target,
1375 gen_rtx_MINUS (mode, GEN_INT (val),
1376 source)));
e2c671ba
RE
1377 return 1;
1378 }
1379 can_negate = 1;
1380
1381 break;
1382
1383 default:
1384 abort ();
1385 }
1386
6354dc9b 1387 /* If we can do it in one insn get out quickly. */
e2c671ba
RE
1388 if (const_ok_for_arm (val)
1389 || (can_negate_initial && const_ok_for_arm (-val))
1390 || (can_invert && const_ok_for_arm (~val)))
1391 {
2b835d68 1392 if (generate)
43cffd11
RE
1393 emit_insn (gen_rtx_SET (VOIDmode, target,
1394 (source ? gen_rtx (code, mode, source,
1395 GEN_INT (val))
1396 : GEN_INT (val))));
e2c671ba
RE
1397 return 1;
1398 }
1399
e2c671ba 1400 /* Calculate a few attributes that may be useful for specific
6354dc9b 1401 optimizations. */
e2c671ba
RE
1402 for (i = 31; i >= 0; i--)
1403 {
1404 if ((remainder & (1 << i)) == 0)
1405 clear_sign_bit_copies++;
1406 else
1407 break;
1408 }
1409
1410 for (i = 31; i >= 0; i--)
1411 {
1412 if ((remainder & (1 << i)) != 0)
1413 set_sign_bit_copies++;
1414 else
1415 break;
1416 }
1417
1418 for (i = 0; i <= 31; i++)
1419 {
1420 if ((remainder & (1 << i)) == 0)
1421 clear_zero_bit_copies++;
1422 else
1423 break;
1424 }
1425
1426 for (i = 0; i <= 31; i++)
1427 {
1428 if ((remainder & (1 << i)) != 0)
1429 set_zero_bit_copies++;
1430 else
1431 break;
1432 }
1433
1434 switch (code)
1435 {
1436 case SET:
1437 /* See if we can do this by sign_extending a constant that is known
1438 to be negative. This is a good, way of doing it, since the shift
1439 may well merge into a subsequent insn. */
1440 if (set_sign_bit_copies > 1)
1441 {
1442 if (const_ok_for_arm
1443 (temp1 = ARM_SIGN_EXTEND (remainder
1444 << (set_sign_bit_copies - 1))))
1445 {
2b835d68
RE
1446 if (generate)
1447 {
d499463f 1448 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
43cffd11
RE
1449 emit_insn (gen_rtx_SET (VOIDmode, new_src,
1450 GEN_INT (temp1)));
2b835d68
RE
1451 emit_insn (gen_ashrsi3 (target, new_src,
1452 GEN_INT (set_sign_bit_copies - 1)));
1453 }
e2c671ba
RE
1454 return 2;
1455 }
1456 /* For an inverted constant, we will need to set the low bits,
1457 these will be shifted out of harm's way. */
1458 temp1 |= (1 << (set_sign_bit_copies - 1)) - 1;
1459 if (const_ok_for_arm (~temp1))
1460 {
2b835d68
RE
1461 if (generate)
1462 {
d499463f 1463 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
43cffd11
RE
1464 emit_insn (gen_rtx_SET (VOIDmode, new_src,
1465 GEN_INT (temp1)));
2b835d68
RE
1466 emit_insn (gen_ashrsi3 (target, new_src,
1467 GEN_INT (set_sign_bit_copies - 1)));
1468 }
e2c671ba
RE
1469 return 2;
1470 }
1471 }
1472
1473 /* See if we can generate this by setting the bottom (or the top)
1474 16 bits, and then shifting these into the other half of the
1475 word. We only look for the simplest cases, to do more would cost
1476 too much. Be careful, however, not to generate this when the
1477 alternative would take fewer insns. */
30cf4896 1478 if (val & 0xffff0000)
e2c671ba 1479 {
30cf4896 1480 temp1 = remainder & 0xffff0000;
e2c671ba
RE
1481 temp2 = remainder & 0x0000ffff;
1482
6354dc9b 1483 /* Overlaps outside this range are best done using other methods. */
e2c671ba
RE
1484 for (i = 9; i < 24; i++)
1485 {
30cf4896 1486 if ((((temp2 | (temp2 << i)) & 0xffffffff) == remainder)
5895f793 1487 && !const_ok_for_arm (temp2))
e2c671ba 1488 {
d499463f
RE
1489 rtx new_src = (subtargets
1490 ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
1491 : target);
1492 insns = arm_gen_constant (code, mode, temp2, new_src,
2b835d68 1493 source, subtargets, generate);
e2c671ba 1494 source = new_src;
2b835d68 1495 if (generate)
43cffd11
RE
1496 emit_insn (gen_rtx_SET
1497 (VOIDmode, target,
1498 gen_rtx_IOR (mode,
1499 gen_rtx_ASHIFT (mode, source,
1500 GEN_INT (i)),
1501 source)));
e2c671ba
RE
1502 return insns + 1;
1503 }
1504 }
1505
6354dc9b 1506 /* Don't duplicate cases already considered. */
e2c671ba
RE
1507 for (i = 17; i < 24; i++)
1508 {
1509 if (((temp1 | (temp1 >> i)) == remainder)
5895f793 1510 && !const_ok_for_arm (temp1))
e2c671ba 1511 {
d499463f
RE
1512 rtx new_src = (subtargets
1513 ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
1514 : target);
1515 insns = arm_gen_constant (code, mode, temp1, new_src,
2b835d68 1516 source, subtargets, generate);
e2c671ba 1517 source = new_src;
2b835d68 1518 if (generate)
43cffd11
RE
1519 emit_insn
1520 (gen_rtx_SET (VOIDmode, target,
1521 gen_rtx_IOR
1522 (mode,
1523 gen_rtx_LSHIFTRT (mode, source,
1524 GEN_INT (i)),
1525 source)));
e2c671ba
RE
1526 return insns + 1;
1527 }
1528 }
1529 }
1530 break;
1531
1532 case IOR:
1533 case XOR:
7b64da89
RE
1534 /* If we have IOR or XOR, and the constant can be loaded in a
1535 single instruction, and we can find a temporary to put it in,
e2c671ba
RE
1536 then this can be done in two instructions instead of 3-4. */
1537 if (subtargets
d499463f 1538 /* TARGET can't be NULL if SUBTARGETS is 0 */
5895f793 1539 || (reload_completed && !reg_mentioned_p (target, source)))
e2c671ba 1540 {
5895f793 1541 if (const_ok_for_arm (ARM_SIGN_EXTEND (~val)))
e2c671ba 1542 {
2b835d68
RE
1543 if (generate)
1544 {
1545 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
e2c671ba 1546
43cffd11
RE
1547 emit_insn (gen_rtx_SET (VOIDmode, sub, GEN_INT (val)));
1548 emit_insn (gen_rtx_SET (VOIDmode, target,
1549 gen_rtx (code, mode, source, sub)));
2b835d68 1550 }
e2c671ba
RE
1551 return 2;
1552 }
1553 }
1554
1555 if (code == XOR)
1556 break;
1557
1558 if (set_sign_bit_copies > 8
1559 && (val & (-1 << (32 - set_sign_bit_copies))) == val)
1560 {
2b835d68
RE
1561 if (generate)
1562 {
1563 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
1564 rtx shift = GEN_INT (set_sign_bit_copies);
1565
43cffd11
RE
1566 emit_insn (gen_rtx_SET (VOIDmode, sub,
1567 gen_rtx_NOT (mode,
1568 gen_rtx_ASHIFT (mode,
1569 source,
f5a1b0d2 1570 shift))));
43cffd11
RE
1571 emit_insn (gen_rtx_SET (VOIDmode, target,
1572 gen_rtx_NOT (mode,
1573 gen_rtx_LSHIFTRT (mode, sub,
1574 shift))));
2b835d68 1575 }
e2c671ba
RE
1576 return 2;
1577 }
1578
1579 if (set_zero_bit_copies > 8
1580 && (remainder & ((1 << set_zero_bit_copies) - 1)) == remainder)
1581 {
2b835d68
RE
1582 if (generate)
1583 {
1584 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
1585 rtx shift = GEN_INT (set_zero_bit_copies);
1586
43cffd11
RE
1587 emit_insn (gen_rtx_SET (VOIDmode, sub,
1588 gen_rtx_NOT (mode,
1589 gen_rtx_LSHIFTRT (mode,
1590 source,
f5a1b0d2 1591 shift))));
43cffd11
RE
1592 emit_insn (gen_rtx_SET (VOIDmode, target,
1593 gen_rtx_NOT (mode,
1594 gen_rtx_ASHIFT (mode, sub,
f5a1b0d2 1595 shift))));
2b835d68 1596 }
e2c671ba
RE
1597 return 2;
1598 }
1599
5895f793 1600 if (const_ok_for_arm (temp1 = ARM_SIGN_EXTEND (~val)))
e2c671ba 1601 {
2b835d68
RE
1602 if (generate)
1603 {
1604 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
43cffd11
RE
1605 emit_insn (gen_rtx_SET (VOIDmode, sub,
1606 gen_rtx_NOT (mode, source)));
2b835d68
RE
1607 source = sub;
1608 if (subtargets)
1609 sub = gen_reg_rtx (mode);
43cffd11
RE
1610 emit_insn (gen_rtx_SET (VOIDmode, sub,
1611 gen_rtx_AND (mode, source,
1612 GEN_INT (temp1))));
1613 emit_insn (gen_rtx_SET (VOIDmode, target,
1614 gen_rtx_NOT (mode, sub)));
2b835d68 1615 }
e2c671ba
RE
1616 return 3;
1617 }
1618 break;
1619
1620 case AND:
1621 /* See if two shifts will do 2 or more insn's worth of work. */
1622 if (clear_sign_bit_copies >= 16 && clear_sign_bit_copies < 24)
1623 {
30cf4896 1624 HOST_WIDE_INT shift_mask = ((0xffffffff
e2c671ba 1625 << (32 - clear_sign_bit_copies))
30cf4896 1626 & 0xffffffff);
e2c671ba 1627
30cf4896 1628 if ((remainder | shift_mask) != 0xffffffff)
e2c671ba 1629 {
2b835d68
RE
1630 if (generate)
1631 {
d499463f 1632 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
2b835d68 1633 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
d499463f
RE
1634 new_src, source, subtargets, 1);
1635 source = new_src;
2b835d68
RE
1636 }
1637 else
d499463f
RE
1638 {
1639 rtx targ = subtargets ? NULL_RTX : target;
1640 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
1641 targ, source, subtargets, 0);
1642 }
2b835d68
RE
1643 }
1644
1645 if (generate)
1646 {
d499463f
RE
1647 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1648 rtx shift = GEN_INT (clear_sign_bit_copies);
1649
1650 emit_insn (gen_ashlsi3 (new_src, source, shift));
1651 emit_insn (gen_lshrsi3 (target, new_src, shift));
e2c671ba
RE
1652 }
1653
e2c671ba
RE
1654 return insns + 2;
1655 }
1656
1657 if (clear_zero_bit_copies >= 16 && clear_zero_bit_copies < 24)
1658 {
1659 HOST_WIDE_INT shift_mask = (1 << clear_zero_bit_copies) - 1;
e2c671ba 1660
30cf4896 1661 if ((remainder | shift_mask) != 0xffffffff)
e2c671ba 1662 {
2b835d68
RE
1663 if (generate)
1664 {
d499463f
RE
1665 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1666
2b835d68 1667 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
d499463f
RE
1668 new_src, source, subtargets, 1);
1669 source = new_src;
2b835d68
RE
1670 }
1671 else
d499463f
RE
1672 {
1673 rtx targ = subtargets ? NULL_RTX : target;
1674
1675 insns = arm_gen_constant (AND, mode, remainder | shift_mask,
1676 targ, source, subtargets, 0);
1677 }
2b835d68
RE
1678 }
1679
1680 if (generate)
1681 {
d499463f
RE
1682 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
1683 rtx shift = GEN_INT (clear_zero_bit_copies);
1684
1685 emit_insn (gen_lshrsi3 (new_src, source, shift));
1686 emit_insn (gen_ashlsi3 (target, new_src, shift));
e2c671ba
RE
1687 }
1688
e2c671ba
RE
1689 return insns + 2;
1690 }
1691
1692 break;
1693
1694 default:
1695 break;
1696 }
1697
1698 for (i = 0; i < 32; i++)
1699 if (remainder & (1 << i))
1700 num_bits_set++;
1701
1702 if (code == AND || (can_invert && num_bits_set > 16))
30cf4896 1703 remainder = (~remainder) & 0xffffffff;
e2c671ba 1704 else if (code == PLUS && num_bits_set > 16)
30cf4896 1705 remainder = (-remainder) & 0xffffffff;
e2c671ba
RE
1706 else
1707 {
1708 can_invert = 0;
1709 can_negate = 0;
1710 }
1711
1712 /* Now try and find a way of doing the job in either two or three
1713 instructions.
1714 We start by looking for the largest block of zeros that are aligned on
1715 a 2-bit boundary, we then fill up the temps, wrapping around to the
1716 top of the word when we drop off the bottom.
6354dc9b 1717 In the worst case this code should produce no more than four insns. */
e2c671ba
RE
1718 {
1719 int best_start = 0;
1720 int best_consecutive_zeros = 0;
1721
1722 for (i = 0; i < 32; i += 2)
1723 {
1724 int consecutive_zeros = 0;
1725
5895f793 1726 if (!(remainder & (3 << i)))
e2c671ba 1727 {
5895f793 1728 while ((i < 32) && !(remainder & (3 << i)))
e2c671ba
RE
1729 {
1730 consecutive_zeros += 2;
1731 i += 2;
1732 }
1733 if (consecutive_zeros > best_consecutive_zeros)
1734 {
1735 best_consecutive_zeros = consecutive_zeros;
1736 best_start = i - consecutive_zeros;
1737 }
1738 i -= 2;
1739 }
1740 }
1741
ceebdb09
PB
1742 /* So long as it won't require any more insns to do so, it's
1743 desirable to emit a small constant (in bits 0...9) in the last
1744 insn. This way there is more chance that it can be combined with
1745 a later addressing insn to form a pre-indexed load or store
1746 operation. Consider:
1747
1748 *((volatile int *)0xe0000100) = 1;
1749 *((volatile int *)0xe0000110) = 2;
1750
1751 We want this to wind up as:
1752
1753 mov rA, #0xe0000000
1754 mov rB, #1
1755 str rB, [rA, #0x100]
1756 mov rB, #2
1757 str rB, [rA, #0x110]
1758
1759 rather than having to synthesize both large constants from scratch.
1760
1761 Therefore, we calculate how many insns would be required to emit
1762 the constant starting from `best_start', and also starting from
1763 zero (ie with bit 31 first to be output). If `best_start' doesn't
1764 yield a shorter sequence, we may as well use zero. */
1765 if (best_start != 0
1766 && ((((unsigned HOST_WIDE_INT) 1) << best_start) < remainder)
1767 && (count_insns_for_constant (remainder, 0) <=
1768 count_insns_for_constant (remainder, best_start)))
1769 best_start = 0;
1770
1771 /* Now start emitting the insns. */
e2c671ba
RE
1772 i = best_start;
1773 do
1774 {
1775 int end;
1776
1777 if (i <= 0)
1778 i += 32;
1779 if (remainder & (3 << (i - 2)))
1780 {
1781 end = i - 8;
1782 if (end < 0)
1783 end += 32;
1784 temp1 = remainder & ((0x0ff << end)
1785 | ((i < end) ? (0xff >> (32 - end)) : 0));
1786 remainder &= ~temp1;
1787
d499463f 1788 if (generate)
e2c671ba 1789 {
9503f3d1
RH
1790 rtx new_src, temp1_rtx;
1791
1792 if (code == SET || code == MINUS)
1793 {
1794 new_src = (subtargets ? gen_reg_rtx (mode) : target);
96ae8197 1795 if (can_invert && code != MINUS)
9503f3d1
RH
1796 temp1 = ~temp1;
1797 }
1798 else
1799 {
96ae8197 1800 if (remainder && subtargets)
9503f3d1 1801 new_src = gen_reg_rtx (mode);
96ae8197
NC
1802 else
1803 new_src = target;
9503f3d1
RH
1804 if (can_invert)
1805 temp1 = ~temp1;
1806 else if (can_negate)
1807 temp1 = -temp1;
1808 }
1809
1810 temp1 = trunc_int_for_mode (temp1, mode);
1811 temp1_rtx = GEN_INT (temp1);
d499463f
RE
1812
1813 if (code == SET)
9503f3d1 1814 ;
d499463f 1815 else if (code == MINUS)
9503f3d1 1816 temp1_rtx = gen_rtx_MINUS (mode, temp1_rtx, source);
d499463f 1817 else
9503f3d1
RH
1818 temp1_rtx = gen_rtx_fmt_ee (code, mode, source, temp1_rtx);
1819
1820 emit_insn (gen_rtx_SET (VOIDmode, new_src, temp1_rtx));
d499463f 1821 source = new_src;
e2c671ba
RE
1822 }
1823
d499463f
RE
1824 if (code == SET)
1825 {
1826 can_invert = 0;
1827 code = PLUS;
1828 }
1829 else if (code == MINUS)
1830 code = PLUS;
1831
e2c671ba 1832 insns++;
e2c671ba
RE
1833 i -= 6;
1834 }
1835 i -= 2;
1d6e90ac
NC
1836 }
1837 while (remainder);
e2c671ba 1838 }
1d6e90ac 1839
e2c671ba
RE
1840 return insns;
1841}
1842
bd9c7e23
RE
1843/* Canonicalize a comparison so that we are more likely to recognize it.
1844 This can be done for a few constant compares, where we can make the
1845 immediate value easier to load. */
1d6e90ac 1846
bd9c7e23 1847enum rtx_code
e32bac5b 1848arm_canonicalize_comparison (enum rtx_code code, rtx * op1)
bd9c7e23 1849{
ad076f4e 1850 unsigned HOST_WIDE_INT i = INTVAL (*op1);
bd9c7e23
RE
1851
1852 switch (code)
1853 {
1854 case EQ:
1855 case NE:
1856 return code;
1857
1858 case GT:
1859 case LE:
30cf4896 1860 if (i != ((((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1)) - 1)
5895f793 1861 && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
bd9c7e23 1862 {
5895f793 1863 *op1 = GEN_INT (i + 1);
bd9c7e23
RE
1864 return code == GT ? GE : LT;
1865 }
1866 break;
1867
1868 case GE:
1869 case LT:
30cf4896 1870 if (i != (((unsigned HOST_WIDE_INT) 1) << (HOST_BITS_PER_WIDE_INT - 1))
5895f793 1871 && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
bd9c7e23 1872 {
5895f793 1873 *op1 = GEN_INT (i - 1);
bd9c7e23
RE
1874 return code == GE ? GT : LE;
1875 }
1876 break;
1877
1878 case GTU:
1879 case LEU:
30cf4896 1880 if (i != ~((unsigned HOST_WIDE_INT) 0)
5895f793 1881 && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
bd9c7e23
RE
1882 {
1883 *op1 = GEN_INT (i + 1);
1884 return code == GTU ? GEU : LTU;
1885 }
1886 break;
1887
1888 case GEU:
1889 case LTU:
1890 if (i != 0
5895f793 1891 && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
bd9c7e23
RE
1892 {
1893 *op1 = GEN_INT (i - 1);
1894 return code == GEU ? GTU : LEU;
1895 }
1896 break;
1897
1898 default:
1899 abort ();
1900 }
1901
1902 return code;
1903}
bd9c7e23 1904
f5a1b0d2
NC
1905/* Decide whether a type should be returned in memory (true)
1906 or in a register (false). This is called by the macro
1907 RETURN_IN_MEMORY. */
2b835d68 1908int
e32bac5b 1909arm_return_in_memory (tree type)
2b835d68 1910{
dc0ba55a
JT
1911 HOST_WIDE_INT size;
1912
5895f793 1913 if (!AGGREGATE_TYPE_P (type))
9e291dbe 1914 /* All simple types are returned in registers. */
d7d01975 1915 return 0;
dc0ba55a
JT
1916
1917 size = int_size_in_bytes (type);
1918
1919 if (TARGET_ATPCS)
1920 {
1921 /* ATPCS returns aggregate types in memory only if they are
1922 larger than a word (or are variable size). */
1923 return (size < 0 || size > UNITS_PER_WORD);
1924 }
d5b7b3ae 1925
6bc82793 1926 /* For the arm-wince targets we choose to be compatible with Microsoft's
d5b7b3ae
RE
1927 ARM and Thumb compilers, which always return aggregates in memory. */
1928#ifndef ARM_WINCE
e529bd42
NC
1929 /* All structures/unions bigger than one word are returned in memory.
1930 Also catch the case where int_size_in_bytes returns -1. In this case
6bc82793 1931 the aggregate is either huge or of variable size, and in either case
e529bd42 1932 we will want to return it via memory and not in a register. */
dc0ba55a 1933 if (size < 0 || size > UNITS_PER_WORD)
d7d01975 1934 return 1;
d5b7b3ae 1935
d7d01975 1936 if (TREE_CODE (type) == RECORD_TYPE)
2b835d68
RE
1937 {
1938 tree field;
1939
3a2ea258
RE
1940 /* For a struct the APCS says that we only return in a register
1941 if the type is 'integer like' and every addressable element
1942 has an offset of zero. For practical purposes this means
1943 that the structure can have at most one non bit-field element
1944 and that this element must be the first one in the structure. */
1945
f5a1b0d2
NC
1946 /* Find the first field, ignoring non FIELD_DECL things which will
1947 have been created by C++. */
1948 for (field = TYPE_FIELDS (type);
1949 field && TREE_CODE (field) != FIELD_DECL;
1950 field = TREE_CHAIN (field))
1951 continue;
1952
1953 if (field == NULL)
9e291dbe 1954 return 0; /* An empty structure. Allowed by an extension to ANSI C. */
f5a1b0d2 1955
d5b7b3ae
RE
1956 /* Check that the first field is valid for returning in a register. */
1957
1958 /* ... Floats are not allowed */
9e291dbe 1959 if (FLOAT_TYPE_P (TREE_TYPE (field)))
3a2ea258
RE
1960 return 1;
1961
d5b7b3ae
RE
1962 /* ... Aggregates that are not themselves valid for returning in
1963 a register are not allowed. */
9e291dbe 1964 if (RETURN_IN_MEMORY (TREE_TYPE (field)))
3a2ea258 1965 return 1;
6f7ebcbb 1966
3a2ea258
RE
1967 /* Now check the remaining fields, if any. Only bitfields are allowed,
1968 since they are not addressable. */
f5a1b0d2
NC
1969 for (field = TREE_CHAIN (field);
1970 field;
1971 field = TREE_CHAIN (field))
1972 {
1973 if (TREE_CODE (field) != FIELD_DECL)
1974 continue;
1975
5895f793 1976 if (!DECL_BIT_FIELD_TYPE (field))
f5a1b0d2
NC
1977 return 1;
1978 }
2b835d68
RE
1979
1980 return 0;
1981 }
d7d01975
NC
1982
1983 if (TREE_CODE (type) == UNION_TYPE)
2b835d68
RE
1984 {
1985 tree field;
1986
1987 /* Unions can be returned in registers if every element is
1988 integral, or can be returned in an integer register. */
f5a1b0d2
NC
1989 for (field = TYPE_FIELDS (type);
1990 field;
1991 field = TREE_CHAIN (field))
2b835d68 1992 {
f5a1b0d2
NC
1993 if (TREE_CODE (field) != FIELD_DECL)
1994 continue;
1995
6cc8c0b3
NC
1996 if (FLOAT_TYPE_P (TREE_TYPE (field)))
1997 return 1;
1998
f5a1b0d2 1999 if (RETURN_IN_MEMORY (TREE_TYPE (field)))
2b835d68
RE
2000 return 1;
2001 }
f5a1b0d2 2002
2b835d68
RE
2003 return 0;
2004 }
d5b7b3ae 2005#endif /* not ARM_WINCE */
f5a1b0d2 2006
d5b7b3ae 2007 /* Return all other types in memory. */
2b835d68
RE
2008 return 1;
2009}
2010
3717da94
JT
2011/* Indicate whether or not words of a double are in big-endian order. */
2012
2013int
e32bac5b 2014arm_float_words_big_endian (void)
3717da94 2015{
9b6b54e2
NC
2016 if (TARGET_CIRRUS)
2017 return 0;
3717da94
JT
2018
2019 /* For FPA, float words are always big-endian. For VFP, floats words
2020 follow the memory system mode. */
2021
2022 if (TARGET_HARD_FLOAT)
2023 {
2024 /* FIXME: TARGET_HARD_FLOAT currently implies FPA. */
2025 return 1;
2026 }
2027
2028 if (TARGET_VFP)
2029 return (TARGET_BIG_END ? 1 : 0);
2030
2031 return 1;
2032}
2033
82e9d970
PB
2034/* Initialize a variable CUM of type CUMULATIVE_ARGS
2035 for a call to a function whose data type is FNTYPE.
2036 For a library call, FNTYPE is NULL. */
2037void
e32bac5b
RE
2038arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
2039 rtx libname ATTRIBUTE_UNUSED,
2040 tree fndecl ATTRIBUTE_UNUSED)
82e9d970
PB
2041{
2042 /* On the ARM, the offset starts at 0. */
61f71b34 2043 pcum->nregs = ((fntype && aggregate_value_p (TREE_TYPE (fntype), fntype)) ? 1 : 0);
5a9335ef 2044 pcum->iwmmxt_nregs = 0;
c27ba912 2045
82e9d970
PB
2046 pcum->call_cookie = CALL_NORMAL;
2047
2048 if (TARGET_LONG_CALLS)
2049 pcum->call_cookie = CALL_LONG;
2050
2051 /* Check for long call/short call attributes. The attributes
2052 override any command line option. */
2053 if (fntype)
2054 {
2055 if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (fntype)))
2056 pcum->call_cookie = CALL_SHORT;
2057 else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (fntype)))
2058 pcum->call_cookie = CALL_LONG;
2059 }
5a9335ef
NC
2060
2061 /* Varargs vectors are treated the same as long long.
2062 named_count avoids having to change the way arm handles 'named' */
2063 pcum->named_count = 0;
2064 pcum->nargs = 0;
2065
2066 if (TARGET_REALLY_IWMMXT && fntype)
2067 {
2068 tree fn_arg;
2069
2070 for (fn_arg = TYPE_ARG_TYPES (fntype);
2071 fn_arg;
2072 fn_arg = TREE_CHAIN (fn_arg))
2073 pcum->named_count += 1;
2074
2075 if (! pcum->named_count)
2076 pcum->named_count = INT_MAX;
2077 }
82e9d970
PB
2078}
2079
2080/* Determine where to put an argument to a function.
2081 Value is zero to push the argument on the stack,
2082 or a hard register in which to store the argument.
2083
2084 MODE is the argument's machine mode.
2085 TYPE is the data type of the argument (as a tree).
2086 This is null for libcalls where that information may
2087 not be available.
2088 CUM is a variable of type CUMULATIVE_ARGS which gives info about
2089 the preceding args and about the function being called.
2090 NAMED is nonzero if this argument is a named parameter
2091 (otherwise it is an extra parameter matching an ellipsis). */
1d6e90ac 2092
82e9d970 2093rtx
e32bac5b
RE
2094arm_function_arg (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
2095 tree type ATTRIBUTE_UNUSED, int named)
82e9d970 2096{
5a9335ef
NC
2097 if (TARGET_REALLY_IWMMXT)
2098 {
2099 if (VECTOR_MODE_SUPPORTED_P (mode))
2100 {
2101 /* varargs vectors are treated the same as long long.
2102 named_count avoids having to change the way arm handles 'named' */
2103 if (pcum->named_count <= pcum->nargs + 1)
2104 {
2105 if (pcum->nregs == 1)
2106 pcum->nregs += 1;
2107 if (pcum->nregs <= 2)
2108 return gen_rtx_REG (mode, pcum->nregs);
2109 else
2110 return NULL_RTX;
2111 }
2112 else if (pcum->iwmmxt_nregs <= 9)
2113 return gen_rtx_REG (mode, pcum->iwmmxt_nregs + FIRST_IWMMXT_REGNUM);
2114 else
2115 return NULL_RTX;
2116 }
2117 else if ((mode == DImode || mode == DFmode) && pcum->nregs & 1)
2118 pcum->nregs += 1;
2119 }
2120
82e9d970
PB
2121 if (mode == VOIDmode)
2122 /* Compute operand 2 of the call insn. */
2123 return GEN_INT (pcum->call_cookie);
2124
5895f793 2125 if (!named || pcum->nregs >= NUM_ARG_REGS)
82e9d970
PB
2126 return NULL_RTX;
2127
2128 return gen_rtx_REG (mode, pcum->nregs);
2129}
1741620c
JD
2130
2131/* Variable sized types are passed by reference. This is a GCC
2132 extension to the ARM ABI. */
2133
2134int
e32bac5b
RE
2135arm_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
2136 enum machine_mode mode ATTRIBUTE_UNUSED,
2137 tree type, int named ATTRIBUTE_UNUSED)
1741620c
JD
2138{
2139 return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST;
2140}
2141
2142/* Implement va_arg. */
2143
2144rtx
e32bac5b 2145arm_va_arg (tree valist, tree type)
1741620c
JD
2146{
2147 /* Variable sized types are passed by reference. */
2148 if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
2149 {
2150 rtx addr = std_expand_builtin_va_arg (valist, build_pointer_type (type));
2151 return gen_rtx_MEM (ptr_mode, force_reg (Pmode, addr));
2152 }
2153
5a9335ef
NC
2154 if (FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), NULL) == IWMMXT_ALIGNMENT)
2155 {
2156 tree minus_eight;
2157 tree t;
2158
2159 /* Maintain 64-bit alignment of the valist pointer by
093354e0 2160 constructing: valist = ((valist + (8 - 1)) & -8). */
5a9335ef
NC
2161 minus_eight = build_int_2 (- (IWMMXT_ALIGNMENT / BITS_PER_UNIT), -1);
2162 t = build_int_2 ((IWMMXT_ALIGNMENT / BITS_PER_UNIT) - 1, 0);
2163 t = build (PLUS_EXPR, TREE_TYPE (valist), valist, t);
2164 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, minus_eight);
2165 t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
2166 TREE_SIDE_EFFECTS (t) = 1;
2167 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
2168
f1ba665b 2169 /* This is to stop the combine pass optimizing
5a9335ef
NC
2170 away the alignment adjustment. */
2171 mark_reg_pointer (arg_pointer_rtx, PARM_BOUNDARY);
2172 }
2173
1741620c
JD
2174 return std_expand_builtin_va_arg (valist, type);
2175}
82e9d970 2176\f
c27ba912
DM
2177/* Encode the current state of the #pragma [no_]long_calls. */
2178typedef enum
82e9d970 2179{
c27ba912
DM
2180 OFF, /* No #pramgma [no_]long_calls is in effect. */
2181 LONG, /* #pragma long_calls is in effect. */
2182 SHORT /* #pragma no_long_calls is in effect. */
2183} arm_pragma_enum;
82e9d970 2184
c27ba912 2185static arm_pragma_enum arm_pragma_long_calls = OFF;
82e9d970 2186
8b97c5f8 2187void
e32bac5b 2188arm_pr_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
82e9d970 2189{
8b97c5f8
ZW
2190 arm_pragma_long_calls = LONG;
2191}
2192
2193void
e32bac5b 2194arm_pr_no_long_calls (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
8b97c5f8
ZW
2195{
2196 arm_pragma_long_calls = SHORT;
2197}
2198
2199void
e32bac5b 2200arm_pr_long_calls_off (struct cpp_reader * pfile ATTRIBUTE_UNUSED)
8b97c5f8
ZW
2201{
2202 arm_pragma_long_calls = OFF;
82e9d970
PB
2203}
2204\f
91d231cb
JM
2205/* Table of machine attributes. */
2206const struct attribute_spec arm_attribute_table[] =
82e9d970 2207{
91d231cb 2208 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
82e9d970
PB
2209 /* Function calls made to this symbol must be done indirectly, because
2210 it may lie outside of the 26 bit addressing range of a normal function
2211 call. */
91d231cb 2212 { "long_call", 0, 0, false, true, true, NULL },
82e9d970
PB
2213 /* Whereas these functions are always known to reside within the 26 bit
2214 addressing range. */
91d231cb 2215 { "short_call", 0, 0, false, true, true, NULL },
6d3d9133 2216 /* Interrupt Service Routines have special prologue and epilogue requirements. */
91d231cb
JM
2217 { "isr", 0, 1, false, false, false, arm_handle_isr_attribute },
2218 { "interrupt", 0, 1, false, false, false, arm_handle_isr_attribute },
2219 { "naked", 0, 0, true, false, false, arm_handle_fndecl_attribute },
2220#ifdef ARM_PE
2221 /* ARM/PE has three new attributes:
2222 interfacearm - ?
2223 dllexport - for exporting a function/variable that will live in a dll
2224 dllimport - for importing a function/variable from a dll
2225
2226 Microsoft allows multiple declspecs in one __declspec, separating
2227 them with spaces. We do NOT support this. Instead, use __declspec
2228 multiple times.
2229 */
2230 { "dllimport", 0, 0, true, false, false, NULL },
2231 { "dllexport", 0, 0, true, false, false, NULL },
2232 { "interfacearm", 0, 0, true, false, false, arm_handle_fndecl_attribute },
2233#endif
2234 { NULL, 0, 0, false, false, false, NULL }
2235};
6d3d9133 2236
91d231cb
JM
2237/* Handle an attribute requiring a FUNCTION_DECL;
2238 arguments as in struct attribute_spec.handler. */
2239static tree
e32bac5b
RE
2240arm_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
2241 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
91d231cb
JM
2242{
2243 if (TREE_CODE (*node) != FUNCTION_DECL)
2244 {
2245 warning ("`%s' attribute only applies to functions",
2246 IDENTIFIER_POINTER (name));
2247 *no_add_attrs = true;
2248 }
2249
2250 return NULL_TREE;
2251}
2252
2253/* Handle an "interrupt" or "isr" attribute;
2254 arguments as in struct attribute_spec.handler. */
2255static tree
e32bac5b
RE
2256arm_handle_isr_attribute (tree *node, tree name, tree args, int flags,
2257 bool *no_add_attrs)
91d231cb
JM
2258{
2259 if (DECL_P (*node))
2260 {
2261 if (TREE_CODE (*node) != FUNCTION_DECL)
2262 {
2263 warning ("`%s' attribute only applies to functions",
2264 IDENTIFIER_POINTER (name));
2265 *no_add_attrs = true;
2266 }
2267 /* FIXME: the argument if any is checked for type attributes;
2268 should it be checked for decl ones? */
2269 }
2270 else
2271 {
2272 if (TREE_CODE (*node) == FUNCTION_TYPE
2273 || TREE_CODE (*node) == METHOD_TYPE)
2274 {
2275 if (arm_isr_value (args) == ARM_FT_UNKNOWN)
2276 {
2277 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
2278 *no_add_attrs = true;
2279 }
2280 }
2281 else if (TREE_CODE (*node) == POINTER_TYPE
2282 && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
2283 || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
2284 && arm_isr_value (args) != ARM_FT_UNKNOWN)
2285 {
2286 *node = build_type_copy (*node);
1d6e90ac
NC
2287 TREE_TYPE (*node) = build_type_attribute_variant
2288 (TREE_TYPE (*node),
2289 tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node))));
91d231cb
JM
2290 *no_add_attrs = true;
2291 }
2292 else
2293 {
2294 /* Possibly pass this attribute on from the type to a decl. */
2295 if (flags & ((int) ATTR_FLAG_DECL_NEXT
2296 | (int) ATTR_FLAG_FUNCTION_NEXT
2297 | (int) ATTR_FLAG_ARRAY_NEXT))
2298 {
2299 *no_add_attrs = true;
2300 return tree_cons (name, args, NULL_TREE);
2301 }
2302 else
2303 {
2304 warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
2305 }
2306 }
2307 }
2308
2309 return NULL_TREE;
82e9d970
PB
2310}
2311
2312/* Return 0 if the attributes for two types are incompatible, 1 if they
2313 are compatible, and 2 if they are nearly compatible (which causes a
2314 warning to be generated). */
8d8e52be 2315static int
e32bac5b 2316arm_comp_type_attributes (tree type1, tree type2)
82e9d970 2317{
1cb8d58a 2318 int l1, l2, s1, s2;
bd7fc26f 2319
82e9d970
PB
2320 /* Check for mismatch of non-default calling convention. */
2321 if (TREE_CODE (type1) != FUNCTION_TYPE)
2322 return 1;
2323
2324 /* Check for mismatched call attributes. */
1cb8d58a
NC
2325 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
2326 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
2327 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
2328 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
bd7fc26f
NC
2329
2330 /* Only bother to check if an attribute is defined. */
2331 if (l1 | l2 | s1 | s2)
2332 {
2333 /* If one type has an attribute, the other must have the same attribute. */
1cb8d58a 2334 if ((l1 != l2) || (s1 != s2))
bd7fc26f 2335 return 0;
82e9d970 2336
bd7fc26f
NC
2337 /* Disallow mixed attributes. */
2338 if ((l1 & s2) || (l2 & s1))
2339 return 0;
2340 }
2341
6d3d9133
NC
2342 /* Check for mismatched ISR attribute. */
2343 l1 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type1)) != NULL;
2344 if (! l1)
2345 l1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type1)) != NULL;
2346 l2 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type2)) != NULL;
2347 if (! l2)
2348 l1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type2)) != NULL;
2349 if (l1 != l2)
2350 return 0;
2351
bd7fc26f 2352 return 1;
82e9d970
PB
2353}
2354
c27ba912
DM
2355/* Encode long_call or short_call attribute by prefixing
2356 symbol name in DECL with a special character FLAG. */
2357void
e32bac5b 2358arm_encode_call_attribute (tree decl, int flag)
c27ba912 2359{
3cce094d 2360 const char * str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
6354dc9b 2361 int len = strlen (str);
d19fb8e3 2362 char * newstr;
c27ba912 2363
c27ba912
DM
2364 /* Do not allow weak functions to be treated as short call. */
2365 if (DECL_WEAK (decl) && flag == SHORT_CALL_FLAG_CHAR)
2366 return;
c27ba912 2367
520a57c8
ZW
2368 newstr = alloca (len + 2);
2369 newstr[0] = flag;
2370 strcpy (newstr + 1, str);
c27ba912 2371
6d3d9133 2372 newstr = (char *) ggc_alloc_string (newstr, len + 1);
c27ba912
DM
2373 XSTR (XEXP (DECL_RTL (decl), 0), 0) = newstr;
2374}
2375
2376/* Assigns default attributes to newly defined type. This is used to
2377 set short_call/long_call attributes for function types of
2378 functions defined inside corresponding #pragma scopes. */
8d8e52be 2379static void
e32bac5b 2380arm_set_default_type_attributes (tree type)
c27ba912
DM
2381{
2382 /* Add __attribute__ ((long_call)) to all functions, when
2383 inside #pragma long_calls or __attribute__ ((short_call)),
2384 when inside #pragma no_long_calls. */
2385 if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
2386 {
2387 tree type_attr_list, attr_name;
2388 type_attr_list = TYPE_ATTRIBUTES (type);
2389
2390 if (arm_pragma_long_calls == LONG)
2391 attr_name = get_identifier ("long_call");
2392 else if (arm_pragma_long_calls == SHORT)
2393 attr_name = get_identifier ("short_call");
2394 else
2395 return;
2396
2397 type_attr_list = tree_cons (attr_name, NULL_TREE, type_attr_list);
2398 TYPE_ATTRIBUTES (type) = type_attr_list;
2399 }
2400}
2401\f
2402/* Return 1 if the operand is a SYMBOL_REF for a function known to be
6bc82793 2403 defined within the current compilation unit. If this cannot be
c27ba912
DM
2404 determined, then 0 is returned. */
2405static int
e32bac5b 2406current_file_function_operand (rtx sym_ref)
c27ba912
DM
2407{
2408 /* This is a bit of a fib. A function will have a short call flag
2409 applied to its name if it has the short call attribute, or it has
2410 already been defined within the current compilation unit. */
2411 if (ENCODED_SHORT_CALL_ATTR_P (XSTR (sym_ref, 0)))
2412 return 1;
2413
6d77b53e 2414 /* The current function is always defined within the current compilation
d6a7951f
JM
2415 unit. if it s a weak definition however, then this may not be the real
2416 definition of the function, and so we have to say no. */
c27ba912 2417 if (sym_ref == XEXP (DECL_RTL (current_function_decl), 0)
5895f793 2418 && !DECL_WEAK (current_function_decl))
c27ba912
DM
2419 return 1;
2420
2421 /* We cannot make the determination - default to returning 0. */
2422 return 0;
2423}
2424
825dda42 2425/* Return nonzero if a 32 bit "long_call" should be generated for
c27ba912
DM
2426 this call. We generate a long_call if the function:
2427
2428 a. has an __attribute__((long call))
2429 or b. is within the scope of a #pragma long_calls
2430 or c. the -mlong-calls command line switch has been specified
2431
2432 However we do not generate a long call if the function:
2433
2434 d. has an __attribute__ ((short_call))
2435 or e. is inside the scope of a #pragma no_long_calls
2436 or f. has an __attribute__ ((section))
2437 or g. is defined within the current compilation unit.
2438
2439 This function will be called by C fragments contained in the machine
2440 description file. CALL_REF and CALL_COOKIE correspond to the matched
2441 rtl operands. CALL_SYMBOL is used to distinguish between
2442 two different callers of the function. It is set to 1 in the
2443 "call_symbol" and "call_symbol_value" patterns and to 0 in the "call"
2444 and "call_value" patterns. This is because of the difference in the
2445 SYM_REFs passed by these patterns. */
2446int
e32bac5b 2447arm_is_longcall_p (rtx sym_ref, int call_cookie, int call_symbol)
c27ba912 2448{
5895f793 2449 if (!call_symbol)
c27ba912
DM
2450 {
2451 if (GET_CODE (sym_ref) != MEM)
2452 return 0;
2453
2454 sym_ref = XEXP (sym_ref, 0);
2455 }
2456
2457 if (GET_CODE (sym_ref) != SYMBOL_REF)
2458 return 0;
2459
2460 if (call_cookie & CALL_SHORT)
2461 return 0;
2462
2463 if (TARGET_LONG_CALLS && flag_function_sections)
2464 return 1;
2465
87e27392 2466 if (current_file_function_operand (sym_ref))
c27ba912
DM
2467 return 0;
2468
2469 return (call_cookie & CALL_LONG)
2470 || ENCODED_LONG_CALL_ATTR_P (XSTR (sym_ref, 0))
2471 || TARGET_LONG_CALLS;
2472}
f99fce0c 2473
825dda42 2474/* Return nonzero if it is ok to make a tail-call to DECL. */
4977bab6 2475static bool
e32bac5b 2476arm_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
f99fce0c
RE
2477{
2478 int call_type = TARGET_LONG_CALLS ? CALL_LONG : CALL_NORMAL;
2479
5a9335ef
NC
2480 if (cfun->machine->sibcall_blocked)
2481 return false;
2482
f99fce0c
RE
2483 /* Never tailcall something for which we have no decl, or if we
2484 are in Thumb mode. */
2485 if (decl == NULL || TARGET_THUMB)
4977bab6 2486 return false;
f99fce0c
RE
2487
2488 /* Get the calling method. */
2489 if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
2490 call_type = CALL_SHORT;
2491 else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
2492 call_type = CALL_LONG;
2493
2494 /* Cannot tail-call to long calls, since these are out of range of
2495 a branch instruction. However, if not compiling PIC, we know
2496 we can reach the symbol if it is in this compilation unit. */
5895f793 2497 if (call_type == CALL_LONG && (flag_pic || !TREE_ASM_WRITTEN (decl)))
4977bab6 2498 return false;
f99fce0c
RE
2499
2500 /* If we are interworking and the function is not declared static
2501 then we can't tail-call it unless we know that it exists in this
2502 compilation unit (since it might be a Thumb routine). */
5895f793 2503 if (TARGET_INTERWORK && TREE_PUBLIC (decl) && !TREE_ASM_WRITTEN (decl))
4977bab6 2504 return false;
f99fce0c 2505
6d3d9133
NC
2506 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
2507 if (IS_INTERRUPT (arm_current_func_type ()))
4977bab6 2508 return false;
6d3d9133 2509
f99fce0c 2510 /* Everything else is ok. */
4977bab6 2511 return true;
f99fce0c
RE
2512}
2513
82e9d970 2514\f
6b990f6b
RE
2515/* Addressing mode support functions. */
2516
0b4be7de 2517/* Return nonzero if X is a legitimate immediate operand when compiling
6b990f6b 2518 for PIC. */
32de079a 2519int
e32bac5b 2520legitimate_pic_operand_p (rtx x)
32de079a 2521{
d5b7b3ae
RE
2522 if (CONSTANT_P (x)
2523 && flag_pic
32de079a
RE
2524 && (GET_CODE (x) == SYMBOL_REF
2525 || (GET_CODE (x) == CONST
2526 && GET_CODE (XEXP (x, 0)) == PLUS
2527 && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)))
2528 return 0;
2529
2530 return 1;
2531}
2532
2533rtx
e32bac5b 2534legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
32de079a 2535{
a3c48721
RE
2536 if (GET_CODE (orig) == SYMBOL_REF
2537 || GET_CODE (orig) == LABEL_REF)
32de079a 2538 {
5f37d07c 2539#ifndef AOF_ASSEMBLER
32de079a 2540 rtx pic_ref, address;
5f37d07c 2541#endif
32de079a
RE
2542 rtx insn;
2543 int subregs = 0;
2544
2545 if (reg == 0)
2546 {
893f3d5b 2547 if (no_new_pseudos)
32de079a
RE
2548 abort ();
2549 else
2550 reg = gen_reg_rtx (Pmode);
2551
2552 subregs = 1;
2553 }
2554
2555#ifdef AOF_ASSEMBLER
2556 /* The AOF assembler can generate relocations for these directly, and
6354dc9b 2557 understands that the PIC register has to be added into the offset. */
32de079a
RE
2558 insn = emit_insn (gen_pic_load_addr_based (reg, orig));
2559#else
2560 if (subregs)
2561 address = gen_reg_rtx (Pmode);
2562 else
2563 address = reg;
2564
4bec9f7d
NC
2565 if (TARGET_ARM)
2566 emit_insn (gen_pic_load_addr_arm (address, orig));
2567 else
2568 emit_insn (gen_pic_load_addr_thumb (address, orig));
32de079a 2569
14f583b8
PB
2570 if ((GET_CODE (orig) == LABEL_REF
2571 || (GET_CODE (orig) == SYMBOL_REF &&
94428622 2572 SYMBOL_REF_LOCAL_P (orig)))
14f583b8 2573 && NEED_GOT_RELOC)
a3c48721
RE
2574 pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
2575 else
2576 {
2577 pic_ref = gen_rtx_MEM (Pmode,
2578 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
2579 address));
2580 RTX_UNCHANGING_P (pic_ref) = 1;
2581 }
2582
32de079a
RE
2583 insn = emit_move_insn (reg, pic_ref);
2584#endif
2585 current_function_uses_pic_offset_table = 1;
2586 /* Put a REG_EQUAL note on this insn, so that it can be optimized
2587 by loop. */
43cffd11
RE
2588 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig,
2589 REG_NOTES (insn));
32de079a
RE
2590 return reg;
2591 }
2592 else if (GET_CODE (orig) == CONST)
2593 {
2594 rtx base, offset;
2595
2596 if (GET_CODE (XEXP (orig, 0)) == PLUS
2597 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
2598 return orig;
2599
2600 if (reg == 0)
2601 {
893f3d5b 2602 if (no_new_pseudos)
32de079a
RE
2603 abort ();
2604 else
2605 reg = gen_reg_rtx (Pmode);
2606 }
2607
2608 if (GET_CODE (XEXP (orig, 0)) == PLUS)
2609 {
2610 base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
2611 offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
2612 base == reg ? 0 : reg);
2613 }
2614 else
2615 abort ();
2616
2617 if (GET_CODE (offset) == CONST_INT)
2618 {
2619 /* The base register doesn't really matter, we only want to
2620 test the index for the appropriate mode. */
6b990f6b
RE
2621 if (!arm_legitimate_index_p (mode, offset, 0))
2622 {
2623 if (!no_new_pseudos)
2624 offset = force_reg (Pmode, offset);
2625 else
2626 abort ();
2627 }
32de079a 2628
32de079a 2629 if (GET_CODE (offset) == CONST_INT)
ed8908e7 2630 return plus_constant (base, INTVAL (offset));
32de079a
RE
2631 }
2632
2633 if (GET_MODE_SIZE (mode) > 4
2634 && (GET_MODE_CLASS (mode) == MODE_INT
2635 || TARGET_SOFT_FLOAT))
2636 {
2637 emit_insn (gen_addsi3 (reg, base, offset));
2638 return reg;
2639 }
2640
43cffd11 2641 return gen_rtx_PLUS (Pmode, base, offset);
32de079a 2642 }
32de079a
RE
2643
2644 return orig;
2645}
2646
c1163e75
PB
2647/* Generate code to load the PIC register. PROLOGUE is true if
2648 called from arm_expand_prologue (in which case we want the
2649 generated insns at the start of the function); false if called
2650 by an exception receiver that needs the PIC register reloaded
2651 (in which case the insns are just dumped at the current location). */
32de079a 2652void
e32bac5b 2653arm_finalize_pic (int prologue ATTRIBUTE_UNUSED)
32de079a
RE
2654{
2655#ifndef AOF_ASSEMBLER
c1163e75 2656 rtx l1, pic_tmp, pic_tmp2, seq, pic_rtx;
32de079a
RE
2657 rtx global_offset_table;
2658
ed0e6530 2659 if (current_function_uses_pic_offset_table == 0 || TARGET_SINGLE_PIC_BASE)
32de079a
RE
2660 return;
2661
5895f793 2662 if (!flag_pic)
32de079a
RE
2663 abort ();
2664
2665 start_sequence ();
2666 l1 = gen_label_rtx ();
2667
43cffd11 2668 global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
dfa08768 2669 /* On the ARM the PC register contains 'dot + 8' at the time of the
d5b7b3ae
RE
2670 addition, on the Thumb it is 'dot + 4'. */
2671 pic_tmp = plus_constant (gen_rtx_LABEL_REF (Pmode, l1), TARGET_ARM ? 8 : 4);
84306176
PB
2672 if (GOT_PCREL)
2673 pic_tmp2 = gen_rtx_CONST (VOIDmode,
43cffd11 2674 gen_rtx_PLUS (Pmode, global_offset_table, pc_rtx));
84306176
PB
2675 else
2676 pic_tmp2 = gen_rtx_CONST (VOIDmode, global_offset_table);
43cffd11
RE
2677
2678 pic_rtx = gen_rtx_CONST (Pmode, gen_rtx_MINUS (Pmode, pic_tmp2, pic_tmp));
f5a1b0d2 2679
d5b7b3ae 2680 if (TARGET_ARM)
4bec9f7d
NC
2681 {
2682 emit_insn (gen_pic_load_addr_arm (pic_offset_table_rtx, pic_rtx));
2683 emit_insn (gen_pic_add_dot_plus_eight (pic_offset_table_rtx, l1));
2684 }
d5b7b3ae 2685 else
4bec9f7d
NC
2686 {
2687 emit_insn (gen_pic_load_addr_thumb (pic_offset_table_rtx, pic_rtx));
2688 emit_insn (gen_pic_add_dot_plus_four (pic_offset_table_rtx, l1));
2689 }
32de079a 2690
2f937369 2691 seq = get_insns ();
32de079a 2692 end_sequence ();
c1163e75
PB
2693 if (prologue)
2694 emit_insn_after (seq, get_insns ());
2695 else
2696 emit_insn (seq);
32de079a
RE
2697
2698 /* Need to emit this whether or not we obey regdecls,
2699 since setjmp/longjmp can cause life info to screw up. */
43cffd11 2700 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
32de079a
RE
2701#endif /* AOF_ASSEMBLER */
2702}
2703
6b990f6b
RE
2704/* Return nonzero if X is valid as an ARM state addressing register. */
2705static int
e32bac5b 2706arm_address_register_rtx_p (rtx x, int strict_p)
6b990f6b
RE
2707{
2708 int regno;
2709
2710 if (GET_CODE (x) != REG)
2711 return 0;
2712
2713 regno = REGNO (x);
2714
2715 if (strict_p)
2716 return ARM_REGNO_OK_FOR_BASE_P (regno);
2717
2718 return (regno <= LAST_ARM_REGNUM
2719 || regno >= FIRST_PSEUDO_REGISTER
2720 || regno == FRAME_POINTER_REGNUM
2721 || regno == ARG_POINTER_REGNUM);
2722}
2723
2724/* Return nonzero if X is a valid ARM state address operand. */
2725int
e32bac5b 2726arm_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
6b990f6b
RE
2727{
2728 if (arm_address_register_rtx_p (x, strict_p))
2729 return 1;
2730
2731 else if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
2732 return arm_address_register_rtx_p (XEXP (x, 0), strict_p);
2733
2734 else if ((GET_CODE (x) == POST_MODIFY || GET_CODE (x) == PRE_MODIFY)
2735 && GET_MODE_SIZE (mode) <= 4
2736 && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
2737 && GET_CODE (XEXP (x, 1)) == PLUS
2738 && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
2739 return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), strict_p);
2740
2741 /* After reload constants split into minipools will have addresses
2742 from a LABEL_REF. */
2743 else if (GET_MODE_SIZE (mode) >= 4 && reload_completed
2744 && (GET_CODE (x) == LABEL_REF
2745 || (GET_CODE (x) == CONST
2746 && GET_CODE (XEXP (x, 0)) == PLUS
2747 && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
2748 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
2749 return 1;
2750
2751 else if (mode == TImode)
2752 return 0;
2753
2754 else if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
2755 {
2756 if (GET_CODE (x) == PLUS
2757 && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
2758 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2759 {
2760 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2761
2762 if (val == 4 || val == -4 || val == -8)
2763 return 1;
2764 }
2765 }
2766
2767 else if (GET_CODE (x) == PLUS)
2768 {
2769 rtx xop0 = XEXP (x, 0);
2770 rtx xop1 = XEXP (x, 1);
2771
2772 return ((arm_address_register_rtx_p (xop0, strict_p)
2773 && arm_legitimate_index_p (mode, xop1, strict_p))
2774 || (arm_address_register_rtx_p (xop1, strict_p)
2775 && arm_legitimate_index_p (mode, xop0, strict_p)));
2776 }
2777
2778#if 0
2779 /* Reload currently can't handle MINUS, so disable this for now */
2780 else if (GET_CODE (x) == MINUS)
2781 {
2782 rtx xop0 = XEXP (x, 0);
2783 rtx xop1 = XEXP (x, 1);
2784
2785 return (arm_address_register_rtx_p (xop0, strict_p)
2786 && arm_legitimate_index_p (mode, xop1, strict_p));
2787 }
2788#endif
2789
2790 else if (GET_MODE_CLASS (mode) != MODE_FLOAT
2791 && GET_CODE (x) == SYMBOL_REF
2792 && CONSTANT_POOL_ADDRESS_P (x)
2793 && ! (flag_pic
2794 && symbol_mentioned_p (get_pool_constant (x))))
2795 return 1;
2796
2797 else if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_DEC)
2798 && (GET_MODE_SIZE (mode) <= 4)
2799 && arm_address_register_rtx_p (XEXP (x, 0), strict_p))
2800 return 1;
2801
2802 return 0;
2803}
2804
2805/* Return nonzero if INDEX is valid for an address index operand in
2806 ARM state. */
2807static int
e32bac5b 2808arm_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
6b990f6b
RE
2809{
2810 HOST_WIDE_INT range;
2811 enum rtx_code code = GET_CODE (index);
2812
2813 if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
2814 return (code == CONST_INT && INTVAL (index) < 1024
2815 && INTVAL (index) > -1024
2816 && (INTVAL (index) & 3) == 0);
2817
9b6b54e2
NC
2818 if (TARGET_CIRRUS
2819 && (GET_MODE_CLASS (mode) == MODE_FLOAT || mode == DImode))
2820 return (code == CONST_INT
2821 && INTVAL (index) < 255
2822 && INTVAL (index) > -255);
2823
6b990f6b
RE
2824 if (arm_address_register_rtx_p (index, strict_p)
2825 && GET_MODE_SIZE (mode) <= 4)
2826 return 1;
2827
5a9335ef
NC
2828 if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
2829 return (code == CONST_INT
2830 && INTVAL (index) < 256
2831 && INTVAL (index) > -256);
2832
6b990f6b
RE
2833 /* XXX What about ldrsb? */
2834 if (GET_MODE_SIZE (mode) <= 4 && code == MULT
2835 && (!arm_arch4 || (mode) != HImode))
2836 {
2837 rtx xiop0 = XEXP (index, 0);
2838 rtx xiop1 = XEXP (index, 1);
2839
2840 return ((arm_address_register_rtx_p (xiop0, strict_p)
2841 && power_of_two_operand (xiop1, SImode))
2842 || (arm_address_register_rtx_p (xiop1, strict_p)
2843 && power_of_two_operand (xiop0, SImode)));
2844 }
2845
2846 if (GET_MODE_SIZE (mode) <= 4
2847 && (code == LSHIFTRT || code == ASHIFTRT
2848 || code == ASHIFT || code == ROTATERT)
2849 && (!arm_arch4 || (mode) != HImode))
2850 {
2851 rtx op = XEXP (index, 1);
2852
2853 return (arm_address_register_rtx_p (XEXP (index, 0), strict_p)
2854 && GET_CODE (op) == CONST_INT
2855 && INTVAL (op) > 0
2856 && INTVAL (op) <= 31);
2857 }
2858
2859 /* XXX For ARM v4 we may be doing a sign-extend operation during the
2860 load, but that has a restricted addressing range and we are unable
2861 to tell here whether that is the case. To be safe we restrict all
2862 loads to that range. */
2863 range = ((mode) == HImode || (mode) == QImode)
2864 ? (arm_arch4 ? 256 : 4095) : 4096;
2865
2866 return (code == CONST_INT
2867 && INTVAL (index) < range
2868 && INTVAL (index) > -range);
76a318e9
RE
2869}
2870
2871/* Return nonzero if X is valid as an ARM state addressing register. */
2872static int
e32bac5b 2873thumb_base_register_rtx_p (rtx x, enum machine_mode mode, int strict_p)
76a318e9
RE
2874{
2875 int regno;
2876
2877 if (GET_CODE (x) != REG)
2878 return 0;
2879
2880 regno = REGNO (x);
2881
2882 if (strict_p)
2883 return THUMB_REGNO_MODE_OK_FOR_BASE_P (regno, mode);
2884
2885 return (regno <= LAST_LO_REGNUM
2886 || regno >= FIRST_PSEUDO_REGISTER
2887 || regno == FRAME_POINTER_REGNUM
2888 || (GET_MODE_SIZE (mode) >= 4
2889 && (regno == STACK_POINTER_REGNUM
2890 || x == hard_frame_pointer_rtx
2891 || x == arg_pointer_rtx)));
2892}
2893
2894/* Return nonzero if x is a legitimate index register. This is the case
2895 for any base register that can access a QImode object. */
2896inline static int
e32bac5b 2897thumb_index_register_rtx_p (rtx x, int strict_p)
76a318e9
RE
2898{
2899 return thumb_base_register_rtx_p (x, QImode, strict_p);
2900}
2901
2902/* Return nonzero if x is a legitimate Thumb-state address.
2903
2904 The AP may be eliminated to either the SP or the FP, so we use the
2905 least common denominator, e.g. SImode, and offsets from 0 to 64.
2906
2907 ??? Verify whether the above is the right approach.
2908
2909 ??? Also, the FP may be eliminated to the SP, so perhaps that
2910 needs special handling also.
2911
2912 ??? Look at how the mips16 port solves this problem. It probably uses
2913 better ways to solve some of these problems.
2914
2915 Although it is not incorrect, we don't accept QImode and HImode
2916 addresses based on the frame pointer or arg pointer until the
2917 reload pass starts. This is so that eliminating such addresses
2918 into stack based ones won't produce impossible code. */
2919int
e32bac5b 2920thumb_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
76a318e9
RE
2921{
2922 /* ??? Not clear if this is right. Experiment. */
2923 if (GET_MODE_SIZE (mode) < 4
2924 && !(reload_in_progress || reload_completed)
2925 && (reg_mentioned_p (frame_pointer_rtx, x)
2926 || reg_mentioned_p (arg_pointer_rtx, x)
2927 || reg_mentioned_p (virtual_incoming_args_rtx, x)
2928 || reg_mentioned_p (virtual_outgoing_args_rtx, x)
2929 || reg_mentioned_p (virtual_stack_dynamic_rtx, x)
2930 || reg_mentioned_p (virtual_stack_vars_rtx, x)))
2931 return 0;
2932
2933 /* Accept any base register. SP only in SImode or larger. */
2934 else if (thumb_base_register_rtx_p (x, mode, strict_p))
2935 return 1;
2936
18dbd950 2937 /* This is PC relative data before arm_reorg runs. */
76a318e9
RE
2938 else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
2939 && GET_CODE (x) == SYMBOL_REF
2940 && CONSTANT_POOL_ADDRESS_P (x) && ! flag_pic)
2941 return 1;
2942
18dbd950 2943 /* This is PC relative data after arm_reorg runs. */
76a318e9
RE
2944 else if (GET_MODE_SIZE (mode) >= 4 && reload_completed
2945 && (GET_CODE (x) == LABEL_REF
2946 || (GET_CODE (x) == CONST
2947 && GET_CODE (XEXP (x, 0)) == PLUS
2948 && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
2949 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
2950 return 1;
2951
2952 /* Post-inc indexing only supported for SImode and larger. */
2953 else if (GET_CODE (x) == POST_INC && GET_MODE_SIZE (mode) >= 4
2954 && thumb_index_register_rtx_p (XEXP (x, 0), strict_p))
2955 return 1;
2956
2957 else if (GET_CODE (x) == PLUS)
2958 {
2959 /* REG+REG address can be any two index registers. */
2960 /* We disallow FRAME+REG addressing since we know that FRAME
2961 will be replaced with STACK, and SP relative addressing only
2962 permits SP+OFFSET. */
2963 if (GET_MODE_SIZE (mode) <= 4
2964 && XEXP (x, 0) != frame_pointer_rtx
2965 && XEXP (x, 1) != frame_pointer_rtx
2966 && XEXP (x, 0) != virtual_stack_vars_rtx
2967 && XEXP (x, 1) != virtual_stack_vars_rtx
2968 && thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
2969 && thumb_index_register_rtx_p (XEXP (x, 1), strict_p))
2970 return 1;
2971
2972 /* REG+const has 5-7 bit offset for non-SP registers. */
2973 else if ((thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
2974 || XEXP (x, 0) == arg_pointer_rtx)
2975 && GET_CODE (XEXP (x, 1)) == CONST_INT
2976 && thumb_legitimate_offset_p (mode, INTVAL (XEXP (x, 1))))
2977 return 1;
2978
2979 /* REG+const has 10 bit offset for SP, but only SImode and
2980 larger is supported. */
2981 /* ??? Should probably check for DI/DFmode overflow here
2982 just like GO_IF_LEGITIMATE_OFFSET does. */
2983 else if (GET_CODE (XEXP (x, 0)) == REG
2984 && REGNO (XEXP (x, 0)) == STACK_POINTER_REGNUM
2985 && GET_MODE_SIZE (mode) >= 4
2986 && GET_CODE (XEXP (x, 1)) == CONST_INT
2987 && INTVAL (XEXP (x, 1)) >= 0
2988 && INTVAL (XEXP (x, 1)) + GET_MODE_SIZE (mode) <= 1024
2989 && (INTVAL (XEXP (x, 1)) & 3) == 0)
2990 return 1;
2991
2992 else if (GET_CODE (XEXP (x, 0)) == REG
2993 && REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
2994 && GET_MODE_SIZE (mode) >= 4
2995 && GET_CODE (XEXP (x, 1)) == CONST_INT
2996 && (INTVAL (XEXP (x, 1)) & 3) == 0)
2997 return 1;
2998 }
2999
3000 else if (GET_MODE_CLASS (mode) != MODE_FLOAT
3001 && GET_CODE (x) == SYMBOL_REF
3002 && CONSTANT_POOL_ADDRESS_P (x)
3003 && !(flag_pic
3004 && symbol_mentioned_p (get_pool_constant (x))))
3005 return 1;
3006
3007 return 0;
3008}
3009
3010/* Return nonzero if VAL can be used as an offset in a Thumb-state address
3011 instruction of mode MODE. */
3012int
e32bac5b 3013thumb_legitimate_offset_p (enum machine_mode mode, HOST_WIDE_INT val)
76a318e9
RE
3014{
3015 switch (GET_MODE_SIZE (mode))
3016 {
3017 case 1:
3018 return val >= 0 && val < 32;
3019
3020 case 2:
3021 return val >= 0 && val < 64 && (val & 1) == 0;
3022
3023 default:
3024 return (val >= 0
3025 && (val + GET_MODE_SIZE (mode)) <= 128
3026 && (val & 3) == 0);
3027 }
3028}
3029
ccf4d512
RE
3030/* Try machine-dependent ways of modifying an illegitimate address
3031 to be legitimate. If we find one, return the new, valid address. */
ccf4d512 3032rtx
e32bac5b 3033arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
ccf4d512
RE
3034{
3035 if (GET_CODE (x) == PLUS)
3036 {
3037 rtx xop0 = XEXP (x, 0);
3038 rtx xop1 = XEXP (x, 1);
3039
3040 if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
3041 xop0 = force_reg (SImode, xop0);
3042
3043 if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
3044 xop1 = force_reg (SImode, xop1);
3045
3046 if (ARM_BASE_REGISTER_RTX_P (xop0)
3047 && GET_CODE (xop1) == CONST_INT)
3048 {
3049 HOST_WIDE_INT n, low_n;
3050 rtx base_reg, val;
3051 n = INTVAL (xop1);
3052
3053 if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
3054 {
3055 low_n = n & 0x0f;
3056 n &= ~0x0f;
3057 if (low_n > 4)
3058 {
3059 n += 16;
3060 low_n -= 16;
3061 }
3062 }
3063 else
3064 {
3065 low_n = ((mode) == TImode ? 0
3066 : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));
3067 n -= low_n;
3068 }
3069
3070 base_reg = gen_reg_rtx (SImode);
3071 val = force_operand (gen_rtx_PLUS (SImode, xop0,
3072 GEN_INT (n)), NULL_RTX);
3073 emit_move_insn (base_reg, val);
3074 x = (low_n == 0 ? base_reg
3075 : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n)));
3076 }
3077 else if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
3078 x = gen_rtx_PLUS (SImode, xop0, xop1);
3079 }
3080
3081 /* XXX We don't allow MINUS any more -- see comment in
3082 arm_legitimate_address_p (). */
3083 else if (GET_CODE (x) == MINUS)
3084 {
3085 rtx xop0 = XEXP (x, 0);
3086 rtx xop1 = XEXP (x, 1);
3087
3088 if (CONSTANT_P (xop0))
3089 xop0 = force_reg (SImode, xop0);
3090
3091 if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))
3092 xop1 = force_reg (SImode, xop1);
3093
3094 if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
3095 x = gen_rtx_MINUS (SImode, xop0, xop1);
3096 }
3097
3098 if (flag_pic)
3099 {
3100 /* We need to find and carefully transform any SYMBOL and LABEL
3101 references; so go back to the original address expression. */
3102 rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
3103
3104 if (new_x != orig_x)
3105 x = new_x;
3106 }
3107
3108 return x;
3109}
3110
6b990f6b
RE
3111\f
3112
e2c671ba
RE
3113#define REG_OR_SUBREG_REG(X) \
3114 (GET_CODE (X) == REG \
3115 || (GET_CODE (X) == SUBREG && GET_CODE (SUBREG_REG (X)) == REG))
3116
3117#define REG_OR_SUBREG_RTX(X) \
3118 (GET_CODE (X) == REG ? (X) : SUBREG_REG (X))
3119
d5b7b3ae
RE
3120#ifndef COSTS_N_INSNS
3121#define COSTS_N_INSNS(N) ((N) * 4 - 2)
3122#endif
e32bac5b 3123/* Worker routine for arm_rtx_costs. */
3c50106f 3124static inline int
e32bac5b 3125arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
e2c671ba
RE
3126{
3127 enum machine_mode mode = GET_MODE (x);
3128 enum rtx_code subcode;
3129 int extra_cost;
3130
d5b7b3ae
RE
3131 if (TARGET_THUMB)
3132 {
3133 switch (code)
3134 {
3135 case ASHIFT:
3136 case ASHIFTRT:
3137 case LSHIFTRT:
3138 case ROTATERT:
3139 case PLUS:
3140 case MINUS:
3141 case COMPARE:
3142 case NEG:
3143 case NOT:
3144 return COSTS_N_INSNS (1);
3145
3146 case MULT:
3147 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
3148 {
3149 int cycles = 0;
3150 unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1));
3151
3152 while (i)
3153 {
3154 i >>= 2;
5895f793 3155 cycles++;
d5b7b3ae
RE
3156 }
3157 return COSTS_N_INSNS (2) + cycles;
3158 }
3159 return COSTS_N_INSNS (1) + 16;
3160
3161 case SET:
3162 return (COSTS_N_INSNS (1)
3163 + 4 * ((GET_CODE (SET_SRC (x)) == MEM)
3164 + GET_CODE (SET_DEST (x)) == MEM));
3165
3166 case CONST_INT:
3167 if (outer == SET)
3168 {
3169 if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256)
3170 return 0;
3171 if (thumb_shiftable_const (INTVAL (x)))
3172 return COSTS_N_INSNS (2);
3173 return COSTS_N_INSNS (3);
3174 }
c769a35d 3175 else if ((outer == PLUS || outer == COMPARE)
d5b7b3ae 3176 && INTVAL (x) < 256 && INTVAL (x) > -256)
c769a35d
RE
3177 return 0;
3178 else if (outer == AND
3179 && INTVAL (x) < 256 && INTVAL (x) >= -256)
3180 return COSTS_N_INSNS (1);
d5b7b3ae
RE
3181 else if (outer == ASHIFT || outer == ASHIFTRT
3182 || outer == LSHIFTRT)
3183 return 0;
3184 return COSTS_N_INSNS (2);
3185
3186 case CONST:
3187 case CONST_DOUBLE:
3188 case LABEL_REF:
3189 case SYMBOL_REF:
3190 return COSTS_N_INSNS (3);
3191
3192 case UDIV:
3193 case UMOD:
3194 case DIV:
3195 case MOD:
3196 return 100;
3197
3198 case TRUNCATE:
3199 return 99;
3200
3201 case AND:
3202 case XOR:
3203 case IOR:
3204 /* XXX guess. */
3205 return 8;
3206
3207 case ADDRESSOF:
3208 case MEM:
3209 /* XXX another guess. */
3210 /* Memory costs quite a lot for the first word, but subsequent words
3211 load at the equivalent of a single insn each. */
3212 return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
48f6efae
NC
3213 + ((GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3214 ? 4 : 0));
d5b7b3ae
RE
3215
3216 case IF_THEN_ELSE:
3217 /* XXX a guess. */
3218 if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
3219 return 14;
3220 return 2;
3221
3222 case ZERO_EXTEND:
3223 /* XXX still guessing. */
3224 switch (GET_MODE (XEXP (x, 0)))
3225 {
3226 case QImode:
3227 return (1 + (mode == DImode ? 4 : 0)
3228 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3229
3230 case HImode:
3231 return (4 + (mode == DImode ? 4 : 0)
3232 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3233
3234 case SImode:
3235 return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3236
3237 default:
3238 return 99;
3239 }
3240
3241 default:
3242 return 99;
d5b7b3ae
RE
3243 }
3244 }
3245
e2c671ba
RE
3246 switch (code)
3247 {
3248 case MEM:
3249 /* Memory costs quite a lot for the first word, but subsequent words
3250 load at the equivalent of a single insn each. */
3251 return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
48f6efae
NC
3252 + (GET_CODE (x) == SYMBOL_REF
3253 && CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0));
e2c671ba
RE
3254
3255 case DIV:
3256 case MOD:
b9c53150
RS
3257 case UDIV:
3258 case UMOD:
3259 return optimize_size ? COSTS_N_INSNS (2) : 100;
e2c671ba
RE
3260
3261 case ROTATE:
3262 if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG)
3263 return 4;
3264 /* Fall through */
3265 case ROTATERT:
3266 if (mode != SImode)
3267 return 8;
3268 /* Fall through */
3269 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3270 if (mode == DImode)
3271 return (8 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : 8)
3272 + ((GET_CODE (XEXP (x, 0)) == REG
3273 || (GET_CODE (XEXP (x, 0)) == SUBREG
3274 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
3275 ? 0 : 8));
3276 return (1 + ((GET_CODE (XEXP (x, 0)) == REG
3277 || (GET_CODE (XEXP (x, 0)) == SUBREG
3278 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
3279 ? 0 : 4)
3280 + ((GET_CODE (XEXP (x, 1)) == REG
3281 || (GET_CODE (XEXP (x, 1)) == SUBREG
3282 && GET_CODE (SUBREG_REG (XEXP (x, 1))) == REG)
3283 || (GET_CODE (XEXP (x, 1)) == CONST_INT))
3284 ? 0 : 4));
3285
3286 case MINUS:
3287 if (mode == DImode)
3288 return (4 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 8)
3289 + ((REG_OR_SUBREG_REG (XEXP (x, 0))
3290 || (GET_CODE (XEXP (x, 0)) == CONST_INT
3291 && const_ok_for_arm (INTVAL (XEXP (x, 0)))))
3292 ? 0 : 8));
3293
3294 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
3295 return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
3296 || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
3b684012 3297 && const_double_rtx_ok_for_fpa (XEXP (x, 1))))
e2c671ba
RE
3298 ? 0 : 8)
3299 + ((REG_OR_SUBREG_REG (XEXP (x, 0))
3300 || (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
3b684012 3301 && const_double_rtx_ok_for_fpa (XEXP (x, 0))))
e2c671ba
RE
3302 ? 0 : 8));
3303
3304 if (((GET_CODE (XEXP (x, 0)) == CONST_INT
3305 && const_ok_for_arm (INTVAL (XEXP (x, 0)))
3306 && REG_OR_SUBREG_REG (XEXP (x, 1))))
3307 || (((subcode = GET_CODE (XEXP (x, 1))) == ASHIFT
3308 || subcode == ASHIFTRT || subcode == LSHIFTRT
3309 || subcode == ROTATE || subcode == ROTATERT
3310 || (subcode == MULT
3311 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
3312 && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
3313 (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
3314 && REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 0))
3315 && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 1))
3316 || GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
3317 && REG_OR_SUBREG_REG (XEXP (x, 0))))
3318 return 1;
3319 /* Fall through */
3320
3321 case PLUS:
3322 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
3323 return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
3324 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
3325 || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
3b684012 3326 && const_double_rtx_ok_for_fpa (XEXP (x, 1))))
e2c671ba
RE
3327 ? 0 : 8));
3328
3329 /* Fall through */
3330 case AND: case XOR: case IOR:
3331 extra_cost = 0;
3332
3333 /* Normally the frame registers will be spilt into reg+const during
3334 reload, so it is a bad idea to combine them with other instructions,
3335 since then they might not be moved outside of loops. As a compromise
3336 we allow integration with ops that have a constant as their second
3337 operand. */
3338 if ((REG_OR_SUBREG_REG (XEXP (x, 0))
3339 && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))
3340 && GET_CODE (XEXP (x, 1)) != CONST_INT)
3341 || (REG_OR_SUBREG_REG (XEXP (x, 0))
3342 && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))))
3343 extra_cost = 4;
3344
3345 if (mode == DImode)
3346 return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
3347 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
3348 || (GET_CODE (XEXP (x, 1)) == CONST_INT
74bbc178 3349 && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
e2c671ba
RE
3350 ? 0 : 8));
3351
3352 if (REG_OR_SUBREG_REG (XEXP (x, 0)))
3353 return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost)
3354 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
3355 || (GET_CODE (XEXP (x, 1)) == CONST_INT
74bbc178 3356 && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
e2c671ba
RE
3357 ? 0 : 4));
3358
3359 else if (REG_OR_SUBREG_REG (XEXP (x, 1)))
3360 return (1 + extra_cost
3361 + ((((subcode = GET_CODE (XEXP (x, 0))) == ASHIFT
3362 || subcode == LSHIFTRT || subcode == ASHIFTRT
3363 || subcode == ROTATE || subcode == ROTATERT
3364 || (subcode == MULT
3365 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3366 && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
ad076f4e 3367 (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
e2c671ba
RE
3368 && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 0)))
3369 && ((REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 1)))
ad076f4e 3370 || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
e2c671ba
RE
3371 ? 0 : 4));
3372
3373 return 8;
3374
3375 case MULT:
b111229a 3376 /* There is no point basing this on the tuning, since it is always the
6354dc9b 3377 fast variant if it exists at all. */
2b835d68
RE
3378 if (arm_fast_multiply && mode == DImode
3379 && (GET_CODE (XEXP (x, 0)) == GET_CODE (XEXP (x, 1)))
3380 && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
3381 || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
3382 return 8;
3383
e2c671ba
RE
3384 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3385 || mode == DImode)
3386 return 30;
3387
3388 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
3389 {
2b835d68 3390 unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
30cf4896 3391 & (unsigned HOST_WIDE_INT) 0xffffffff);
e3b66120
JL
3392 int cost, const_ok = const_ok_for_arm (i);
3393 int j, booth_unit_size;
3394
3395 if (arm_tune_xscale)
3396 {
3397 unsigned HOST_WIDE_INT masked_const;
3398
3399 /* The cost will be related to two insns.
3400 First a load of the constant (MOV or LDR), then a multiply. */
3401 cost = 2;
3402 if (! const_ok)
3403 cost += 1; /* LDR is probably more expensive because
3404 of longer result latency. */
3405 masked_const = i & 0xffff8000;
3406 if (masked_const != 0 && masked_const != 0xffff8000)
3407 {
3408 masked_const = i & 0xf8000000;
3409 if (masked_const == 0 || masked_const == 0xf8000000)
3410 cost += 1;
3411 else
3412 cost += 2;
3413 }
3414 return cost;
3415 }
6354dc9b
NC
3416
3417 /* Tune as appropriate. */
e3b66120
JL
3418 cost = const_ok ? 4 : 8;
3419 booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
2b835d68 3420 for (j = 0; i && j < 32; j += booth_unit_size)
e2c671ba 3421 {
2b835d68 3422 i >>= booth_unit_size;
e3b66120 3423 cost += 2;
e2c671ba
RE
3424 }
3425
e3b66120 3426 return cost;
e2c671ba
RE
3427 }
3428
aec3cfba 3429 return (((tune_flags & FL_FAST_MULT) ? 8 : 30)
2b835d68 3430 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
e2c671ba
RE
3431 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4));
3432
56636818
JL
3433 case TRUNCATE:
3434 if (arm_fast_multiply && mode == SImode
3435 && GET_CODE (XEXP (x, 0)) == LSHIFTRT
3436 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
3437 && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
3438 == GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)))
3439 && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
3440 || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND))
3441 return 8;
3442 return 99;
3443
e2c671ba
RE
3444 case NEG:
3445 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
3446 return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6);
3447 /* Fall through */
3448 case NOT:
3449 if (mode == DImode)
3450 return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
3451
3452 return 1 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
3453
3454 case IF_THEN_ELSE:
3455 if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
3456 return 14;
3457 return 2;
3458
3459 case COMPARE:
3460 return 1;
3461
3462 case ABS:
3463 return 4 + (mode == DImode ? 4 : 0);
3464
3465 case SIGN_EXTEND:
3466 if (GET_MODE (XEXP (x, 0)) == QImode)
3467 return (4 + (mode == DImode ? 4 : 0)
3468 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3469 /* Fall through */
3470 case ZERO_EXTEND:
3471 switch (GET_MODE (XEXP (x, 0)))
3472 {
3473 case QImode:
3474 return (1 + (mode == DImode ? 4 : 0)
3475 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3476
3477 case HImode:
3478 return (4 + (mode == DImode ? 4 : 0)
3479 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3480
3481 case SImode:
3482 return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
ad076f4e 3483
5a9335ef
NC
3484 case V8QImode:
3485 case V4HImode:
3486 case V2SImode:
3487 case V4QImode:
3488 case V2HImode:
3489 return 1;
3490
ad076f4e
RE
3491 default:
3492 break;
e2c671ba
RE
3493 }
3494 abort ();
3495
d5b7b3ae
RE
3496 case CONST_INT:
3497 if (const_ok_for_arm (INTVAL (x)))
3498 return outer == SET ? 2 : -1;
3499 else if (outer == AND
5895f793 3500 && const_ok_for_arm (~INTVAL (x)))
d5b7b3ae
RE
3501 return -1;
3502 else if ((outer == COMPARE
3503 || outer == PLUS || outer == MINUS)
5895f793 3504 && const_ok_for_arm (-INTVAL (x)))
d5b7b3ae
RE
3505 return -1;
3506 else
3507 return 5;
3508
3509 case CONST:
3510 case LABEL_REF:
3511 case SYMBOL_REF:
3512 return 6;
3513
3514 case CONST_DOUBLE:
3b684012 3515 if (const_double_rtx_ok_for_fpa (x))
d5b7b3ae
RE
3516 return outer == SET ? 2 : -1;
3517 else if ((outer == COMPARE || outer == PLUS)
3b684012 3518 && neg_const_double_rtx_ok_for_fpa (x))
d5b7b3ae
RE
3519 return -1;
3520 return 7;
3521
e2c671ba
RE
3522 default:
3523 return 99;
3524 }
3525}
32de079a 3526
3c50106f 3527static bool
e32bac5b 3528arm_rtx_costs (rtx x, int code, int outer_code, int *total)
3c50106f
RH
3529{
3530 *total = arm_rtx_costs_1 (x, code, outer_code);
3531 return true;
3532}
3533
dcefdf67
RH
3534/* All address computations that can be done are free, but rtx cost returns
3535 the same for practically all of them. So we weight the different types
3536 of address here in the order (most pref first):
3537 PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
d2b6eb76
ZW
3538static inline int
3539arm_arm_address_cost (rtx x)
3540{
3541 enum rtx_code c = GET_CODE (x);
3542
3543 if (c == PRE_INC || c == PRE_DEC || c == POST_INC || c == POST_DEC)
3544 return 0;
3545 if (c == MEM || c == LABEL_REF || c == SYMBOL_REF)
3546 return 10;
3547
3548 if (c == PLUS || c == MINUS)
3549 {
3550 char cl0 = GET_RTX_CLASS (GET_CODE (XEXP (x, 0)));
3551 char cl1 = GET_RTX_CLASS (GET_CODE (XEXP (x, 1)));
3552
3553 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
3554 return 2;
3555
3556 if (cl0 == '2' || cl0 == 'c' || cl1 == '2' || cl1 == 'c')
3557 return 3;
3558
3559 return 4;
3560 }
3561
3562 return 6;
3563}
3564
3565static inline int
3566arm_thumb_address_cost (rtx x)
3567{
3568 enum rtx_code c = GET_CODE (x);
3569
3570 if (c == REG)
3571 return 1;
3572 if (c == PLUS
3573 && GET_CODE (XEXP (x, 0)) == REG
3574 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3575 return 1;
3576
3577 return 2;
3578}
3579
dcefdf67 3580static int
e32bac5b 3581arm_address_cost (rtx x)
dcefdf67 3582{
d2b6eb76 3583 return TARGET_ARM ? arm_arm_address_cost (x) : arm_thumb_address_cost (x);
dcefdf67
RH
3584}
3585
103fc15d 3586static int
e32bac5b 3587arm_use_dfa_pipeline_interface (void)
103fc15d
BE
3588{
3589 return true;
3590}
3591
c237e94a 3592static int
e32bac5b 3593arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost)
32de079a
RE
3594{
3595 rtx i_pat, d_pat;
3596
d19fb8e3
NC
3597 /* Some true dependencies can have a higher cost depending
3598 on precisely how certain input operands are used. */
4b3c2e48 3599 if (arm_tune_xscale
d19fb8e3 3600 && REG_NOTE_KIND (link) == 0
eda833e3
BE
3601 && recog_memoized (insn) >= 0
3602 && recog_memoized (dep) >= 0)
d19fb8e3
NC
3603 {
3604 int shift_opnum = get_attr_shift (insn);
3605 enum attr_type attr_type = get_attr_type (dep);
3606
3607 /* If nonzero, SHIFT_OPNUM contains the operand number of a shifted
3608 operand for INSN. If we have a shifted input operand and the
3609 instruction we depend on is another ALU instruction, then we may
3610 have to account for an additional stall. */
3611 if (shift_opnum != 0 && attr_type == TYPE_NORMAL)
3612 {
3613 rtx shifted_operand;
3614 int opno;
3615
3616 /* Get the shifted operand. */
3617 extract_insn (insn);
3618 shifted_operand = recog_data.operand[shift_opnum];
3619
3620 /* Iterate over all the operands in DEP. If we write an operand
3621 that overlaps with SHIFTED_OPERAND, then we have increase the
3622 cost of this dependency. */
3623 extract_insn (dep);
3624 preprocess_constraints ();
3625 for (opno = 0; opno < recog_data.n_operands; opno++)
3626 {
3627 /* We can ignore strict inputs. */
3628 if (recog_data.operand_type[opno] == OP_IN)
3629 continue;
3630
3631 if (reg_overlap_mentioned_p (recog_data.operand[opno],
3632 shifted_operand))
3633 return 2;
3634 }
3635 }
3636 }
3637
6354dc9b 3638 /* XXX This is not strictly true for the FPA. */
d5b7b3ae
RE
3639 if (REG_NOTE_KIND (link) == REG_DEP_ANTI
3640 || REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
b36ba79f
RE
3641 return 0;
3642
d5b7b3ae
RE
3643 /* Call insns don't incur a stall, even if they follow a load. */
3644 if (REG_NOTE_KIND (link) == 0
3645 && GET_CODE (insn) == CALL_INSN)
3646 return 1;
3647
32de079a
RE
3648 if ((i_pat = single_set (insn)) != NULL
3649 && GET_CODE (SET_SRC (i_pat)) == MEM
3650 && (d_pat = single_set (dep)) != NULL
3651 && GET_CODE (SET_DEST (d_pat)) == MEM)
3652 {
48f6efae 3653 rtx src_mem = XEXP (SET_SRC (i_pat), 0);
32de079a
RE
3654 /* This is a load after a store, there is no conflict if the load reads
3655 from a cached area. Assume that loads from the stack, and from the
3656 constant pool are cached, and that others will miss. This is a
6354dc9b 3657 hack. */
32de079a 3658
48f6efae
NC
3659 if ((GET_CODE (src_mem) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (src_mem))
3660 || reg_mentioned_p (stack_pointer_rtx, src_mem)
3661 || reg_mentioned_p (frame_pointer_rtx, src_mem)
3662 || reg_mentioned_p (hard_frame_pointer_rtx, src_mem))
949d79eb 3663 return 1;
32de079a
RE
3664 }
3665
3666 return cost;
3667}
3668
ff9940b0
RE
3669static int fpa_consts_inited = 0;
3670
1d6e90ac 3671static const char * const strings_fpa[8] =
62b10bbc 3672{
2b835d68
RE
3673 "0", "1", "2", "3",
3674 "4", "5", "0.5", "10"
3675};
ff9940b0
RE
3676
3677static REAL_VALUE_TYPE values_fpa[8];
3678
3679static void
e32bac5b 3680init_fpa_table (void)
ff9940b0
RE
3681{
3682 int i;
3683 REAL_VALUE_TYPE r;
3684
3685 for (i = 0; i < 8; i++)
3686 {
3687 r = REAL_VALUE_ATOF (strings_fpa[i], DFmode);
3688 values_fpa[i] = r;
3689 }
f3bb6135 3690
ff9940b0
RE
3691 fpa_consts_inited = 1;
3692}
3693
3b684012 3694/* Return TRUE if rtx X is a valid immediate FPA constant. */
cce8749e 3695int
e32bac5b 3696const_double_rtx_ok_for_fpa (rtx x)
cce8749e 3697{
ff9940b0
RE
3698 REAL_VALUE_TYPE r;
3699 int i;
3700
3701 if (!fpa_consts_inited)
3702 init_fpa_table ();
3703
3704 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3705 if (REAL_VALUE_MINUS_ZERO (r))
3706 return 0;
f3bb6135 3707
ff9940b0
RE
3708 for (i = 0; i < 8; i++)
3709 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
3710 return 1;
f3bb6135 3711
ff9940b0 3712 return 0;
f3bb6135 3713}
ff9940b0 3714
3b684012 3715/* Return TRUE if rtx X is a valid immediate FPA constant. */
ff9940b0 3716int
e32bac5b 3717neg_const_double_rtx_ok_for_fpa (rtx x)
ff9940b0
RE
3718{
3719 REAL_VALUE_TYPE r;
3720 int i;
3721
3722 if (!fpa_consts_inited)
3723 init_fpa_table ();
3724
3725 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3726 r = REAL_VALUE_NEGATE (r);
3727 if (REAL_VALUE_MINUS_ZERO (r))
3728 return 0;
f3bb6135 3729
ff9940b0
RE
3730 for (i = 0; i < 8; i++)
3731 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
3732 return 1;
f3bb6135 3733
ff9940b0 3734 return 0;
f3bb6135 3735}
cce8749e
CH
3736\f
3737/* Predicates for `match_operand' and `match_operator'. */
3738
ff9940b0 3739/* s_register_operand is the same as register_operand, but it doesn't accept
56a38cec
DE
3740 (SUBREG (MEM)...).
3741
3742 This function exists because at the time it was put in it led to better
3743 code. SUBREG(MEM) always needs a reload in the places where
3744 s_register_operand is used, and this seemed to lead to excessive
3745 reloading. */
ff9940b0 3746int
e32bac5b 3747s_register_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
3748{
3749 if (GET_MODE (op) != mode && mode != VOIDmode)
3750 return 0;
3751
3752 if (GET_CODE (op) == SUBREG)
f3bb6135 3753 op = SUBREG_REG (op);
ff9940b0
RE
3754
3755 /* We don't consider registers whose class is NO_REGS
3756 to be a register operand. */
d5b7b3ae 3757 /* XXX might have to check for lo regs only for thumb ??? */
ff9940b0
RE
3758 return (GET_CODE (op) == REG
3759 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3760 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
3761}
3762
b0888988
RE
3763/* A hard register operand (even before reload. */
3764int
e32bac5b 3765arm_hard_register_operand (rtx op, enum machine_mode mode)
b0888988
RE
3766{
3767 if (GET_MODE (op) != mode && mode != VOIDmode)
3768 return 0;
3769
3770 return (GET_CODE (op) == REG
3771 && REGNO (op) < FIRST_PSEUDO_REGISTER);
3772}
3773
e2c671ba 3774/* Only accept reg, subreg(reg), const_int. */
e2c671ba 3775int
e32bac5b 3776reg_or_int_operand (rtx op, enum machine_mode mode)
e2c671ba
RE
3777{
3778 if (GET_CODE (op) == CONST_INT)
3779 return 1;
3780
3781 if (GET_MODE (op) != mode && mode != VOIDmode)
3782 return 0;
3783
3784 if (GET_CODE (op) == SUBREG)
3785 op = SUBREG_REG (op);
3786
3787 /* We don't consider registers whose class is NO_REGS
3788 to be a register operand. */
3789 return (GET_CODE (op) == REG
3790 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3791 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
3792}
3793
ff9940b0 3794/* Return 1 if OP is an item in memory, given that we are in reload. */
ff9940b0 3795int
e32bac5b 3796arm_reload_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
ff9940b0
RE
3797{
3798 int regno = true_regnum (op);
3799
5895f793 3800 return (!CONSTANT_P (op)
ff9940b0
RE
3801 && (regno == -1
3802 || (GET_CODE (op) == REG
3803 && REGNO (op) >= FIRST_PSEUDO_REGISTER)));
3804}
3805
4d818c85 3806/* Return 1 if OP is a valid memory address, but not valid for a signed byte
d5b7b3ae 3807 memory access (architecture V4).
f710504c 3808 MODE is QImode if called when computing constraints, or VOIDmode when
d5b7b3ae 3809 emitting patterns. In this latter case we cannot use memory_operand()
6bc82793 3810 because it will fail on badly formed MEMs, which is precisely what we are
d5b7b3ae 3811 trying to catch. */
4d818c85 3812int
e32bac5b 3813bad_signed_byte_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
4d818c85 3814{
d5b7b3ae 3815 if (GET_CODE (op) != MEM)
4d818c85
RE
3816 return 0;
3817
3818 op = XEXP (op, 0);
3819
6354dc9b 3820 /* A sum of anything more complex than reg + reg or reg + const is bad. */
4d818c85 3821 if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
5895f793
RE
3822 && (!s_register_operand (XEXP (op, 0), VOIDmode)
3823 || (!s_register_operand (XEXP (op, 1), VOIDmode)
9c8cc54f 3824 && GET_CODE (XEXP (op, 1)) != CONST_INT)))
4d818c85
RE
3825 return 1;
3826
6354dc9b 3827 /* Big constants are also bad. */
4d818c85
RE
3828 if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT
3829 && (INTVAL (XEXP (op, 1)) > 0xff
3830 || -INTVAL (XEXP (op, 1)) > 0xff))
3831 return 1;
3832
6354dc9b 3833 /* Everything else is good, or can will automatically be made so. */
4d818c85
RE
3834 return 0;
3835}
3836
cce8749e 3837/* Return TRUE for valid operands for the rhs of an ARM instruction. */
cce8749e 3838int
e32bac5b 3839arm_rhs_operand (rtx op, enum machine_mode mode)
cce8749e 3840{
ff9940b0 3841 return (s_register_operand (op, mode)
cce8749e 3842 || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))));
f3bb6135 3843}
cce8749e 3844
1d6e90ac
NC
3845/* Return TRUE for valid operands for the
3846 rhs of an ARM instruction, or a load. */
ff9940b0 3847int
e32bac5b 3848arm_rhsm_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
3849{
3850 return (s_register_operand (op, mode)
3851 || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))
3852 || memory_operand (op, mode));
f3bb6135 3853}
ff9940b0
RE
3854
3855/* Return TRUE for valid operands for the rhs of an ARM instruction, or if a
3856 constant that is valid when negated. */
ff9940b0 3857int
e32bac5b 3858arm_add_operand (rtx op, enum machine_mode mode)
ff9940b0 3859{
d5b7b3ae
RE
3860 if (TARGET_THUMB)
3861 return thumb_cmp_operand (op, mode);
3862
ff9940b0
RE
3863 return (s_register_operand (op, mode)
3864 || (GET_CODE (op) == CONST_INT
3865 && (const_ok_for_arm (INTVAL (op))
3866 || const_ok_for_arm (-INTVAL (op)))));
f3bb6135 3867}
ff9940b0 3868
f9b9980e
RE
3869/* Return TRUE for valid ARM constants (or when valid if negated). */
3870int
91de08c3 3871arm_addimm_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
f9b9980e
RE
3872{
3873 return (GET_CODE (op) == CONST_INT
3874 && (const_ok_for_arm (INTVAL (op))
3875 || const_ok_for_arm (-INTVAL (op))));
3876}
3877
ff9940b0 3878int
e32bac5b 3879arm_not_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
3880{
3881 return (s_register_operand (op, mode)
3882 || (GET_CODE (op) == CONST_INT
3883 && (const_ok_for_arm (INTVAL (op))
3884 || const_ok_for_arm (~INTVAL (op)))));
f3bb6135 3885}
ff9940b0 3886
5165176d
RE
3887/* Return TRUE if the operand is a memory reference which contains an
3888 offsettable address. */
3889int
e32bac5b 3890offsettable_memory_operand (rtx op, enum machine_mode mode)
5165176d
RE
3891{
3892 if (mode == VOIDmode)
3893 mode = GET_MODE (op);
3894
3895 return (mode == GET_MODE (op)
3896 && GET_CODE (op) == MEM
3897 && offsettable_address_p (reload_completed | reload_in_progress,
3898 mode, XEXP (op, 0)));
3899}
3900
3901/* Return TRUE if the operand is a memory reference which is, or can be
3902 made word aligned by adjusting the offset. */
3903int
e32bac5b 3904alignable_memory_operand (rtx op, enum machine_mode mode)
5165176d
RE
3905{
3906 rtx reg;
3907
3908 if (mode == VOIDmode)
3909 mode = GET_MODE (op);
3910
3911 if (mode != GET_MODE (op) || GET_CODE (op) != MEM)
3912 return 0;
3913
3914 op = XEXP (op, 0);
3915
3916 return ((GET_CODE (reg = op) == REG
3917 || (GET_CODE (op) == SUBREG
3918 && GET_CODE (reg = SUBREG_REG (op)) == REG)
3919 || (GET_CODE (op) == PLUS
3920 && GET_CODE (XEXP (op, 1)) == CONST_INT
3921 && (GET_CODE (reg = XEXP (op, 0)) == REG
3922 || (GET_CODE (XEXP (op, 0)) == SUBREG
3923 && GET_CODE (reg = SUBREG_REG (XEXP (op, 0))) == REG))))
bdb429a5 3924 && REGNO_POINTER_ALIGN (REGNO (reg)) >= 32);
5165176d
RE
3925}
3926
b111229a
RE
3927/* Similar to s_register_operand, but does not allow hard integer
3928 registers. */
3929int
e32bac5b 3930f_register_operand (rtx op, enum machine_mode mode)
b111229a
RE
3931{
3932 if (GET_MODE (op) != mode && mode != VOIDmode)
3933 return 0;
3934
3935 if (GET_CODE (op) == SUBREG)
3936 op = SUBREG_REG (op);
3937
3938 /* We don't consider registers whose class is NO_REGS
3939 to be a register operand. */
3940 return (GET_CODE (op) == REG
3941 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3b684012 3942 || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS));
b111229a
RE
3943}
3944
3b684012 3945/* Return TRUE for valid operands for the rhs of an FPA instruction. */
cce8749e 3946int
e32bac5b 3947fpa_rhs_operand (rtx op, enum machine_mode mode)
cce8749e 3948{
ff9940b0 3949 if (s_register_operand (op, mode))
f3bb6135 3950 return TRUE;
9ce71c6f
BS
3951
3952 if (GET_MODE (op) != mode && mode != VOIDmode)
3953 return FALSE;
3954
3955 if (GET_CODE (op) == CONST_DOUBLE)
3b684012 3956 return const_double_rtx_ok_for_fpa (op);
f3bb6135
RE
3957
3958 return FALSE;
3959}
cce8749e 3960
ff9940b0 3961int
e32bac5b 3962fpa_add_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
3963{
3964 if (s_register_operand (op, mode))
f3bb6135 3965 return TRUE;
9ce71c6f
BS
3966
3967 if (GET_MODE (op) != mode && mode != VOIDmode)
3968 return FALSE;
3969
3970 if (GET_CODE (op) == CONST_DOUBLE)
3b684012
RE
3971 return (const_double_rtx_ok_for_fpa (op)
3972 || neg_const_double_rtx_ok_for_fpa (op));
f3bb6135
RE
3973
3974 return FALSE;
ff9940b0
RE
3975}
3976
9b6b54e2 3977/* Return nonzero if OP is a valid Cirrus memory address pattern. */
9b6b54e2 3978int
e32bac5b 3979cirrus_memory_offset (rtx op)
9b6b54e2
NC
3980{
3981 /* Reject eliminable registers. */
3982 if (! (reload_in_progress || reload_completed)
3983 && ( reg_mentioned_p (frame_pointer_rtx, op)
3984 || reg_mentioned_p (arg_pointer_rtx, op)
3985 || reg_mentioned_p (virtual_incoming_args_rtx, op)
3986 || reg_mentioned_p (virtual_outgoing_args_rtx, op)
3987 || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
3988 || reg_mentioned_p (virtual_stack_vars_rtx, op)))
3989 return 0;
3990
3991 if (GET_CODE (op) == MEM)
3992 {
3993 rtx ind;
3994
3995 ind = XEXP (op, 0);
3996
3997 /* Match: (mem (reg)). */
3998 if (GET_CODE (ind) == REG)
3999 return 1;
4000
4001 /* Match:
4002 (mem (plus (reg)
4003 (const))). */
4004 if (GET_CODE (ind) == PLUS
4005 && GET_CODE (XEXP (ind, 0)) == REG
4006 && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
4007 && GET_CODE (XEXP (ind, 1)) == CONST_INT)
4008 return 1;
4009 }
4010
4011 return 0;
4012}
4013
4014/* Return nonzero if OP is a Cirrus or general register. */
9b6b54e2 4015int
e32bac5b 4016cirrus_register_operand (rtx op, enum machine_mode mode)
9b6b54e2
NC
4017{
4018 if (GET_MODE (op) != mode && mode != VOIDmode)
4019 return FALSE;
4020
4021 if (GET_CODE (op) == SUBREG)
4022 op = SUBREG_REG (op);
4023
4024 return (GET_CODE (op) == REG
4025 && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS
4026 || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
4027}
4028
4029/* Return nonzero if OP is a cirrus FP register. */
9b6b54e2 4030int
e32bac5b 4031cirrus_fp_register (rtx op, enum machine_mode mode)
9b6b54e2
NC
4032{
4033 if (GET_MODE (op) != mode && mode != VOIDmode)
4034 return FALSE;
4035
4036 if (GET_CODE (op) == SUBREG)
4037 op = SUBREG_REG (op);
4038
4039 return (GET_CODE (op) == REG
4040 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
4041 || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS));
4042}
4043
4044/* Return nonzero if OP is a 6bit constant (0..63). */
9b6b54e2 4045int
e32bac5b 4046cirrus_shift_const (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
9b6b54e2
NC
4047{
4048 return (GET_CODE (op) == CONST_INT
4049 && INTVAL (op) >= 0
4050 && INTVAL (op) < 64);
4051}
4052
f0375c66
NC
4053/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction.
4054 Use by the Cirrus Maverick code which has to workaround
4055 a hardware bug triggered by such instructions. */
f0375c66 4056static bool
e32bac5b 4057arm_memory_load_p (rtx insn)
9b6b54e2
NC
4058{
4059 rtx body, lhs, rhs;;
4060
f0375c66
NC
4061 if (insn == NULL_RTX || GET_CODE (insn) != INSN)
4062 return false;
9b6b54e2
NC
4063
4064 body = PATTERN (insn);
4065
4066 if (GET_CODE (body) != SET)
f0375c66 4067 return false;
9b6b54e2
NC
4068
4069 lhs = XEXP (body, 0);
4070 rhs = XEXP (body, 1);
4071
f0375c66
NC
4072 lhs = REG_OR_SUBREG_RTX (lhs);
4073
4074 /* If the destination is not a general purpose
4075 register we do not have to worry. */
4076 if (GET_CODE (lhs) != REG
4077 || REGNO_REG_CLASS (REGNO (lhs)) != GENERAL_REGS)
4078 return false;
4079
4080 /* As well as loads from memory we also have to react
4081 to loads of invalid constants which will be turned
4082 into loads from the minipool. */
4083 return (GET_CODE (rhs) == MEM
4084 || GET_CODE (rhs) == SYMBOL_REF
4085 || note_invalid_constants (insn, -1, false));
9b6b54e2
NC
4086}
4087
f0375c66 4088/* Return TRUE if INSN is a Cirrus instruction. */
f0375c66 4089static bool
e32bac5b 4090arm_cirrus_insn_p (rtx insn)
9b6b54e2
NC
4091{
4092 enum attr_cirrus attr;
4093
4094 /* get_attr aborts on USE and CLOBBER. */
4095 if (!insn
4096 || GET_CODE (insn) != INSN
4097 || GET_CODE (PATTERN (insn)) == USE
4098 || GET_CODE (PATTERN (insn)) == CLOBBER)
4099 return 0;
4100
4101 attr = get_attr_cirrus (insn);
4102
f0375c66 4103 return attr != CIRRUS_NOT;
9b6b54e2
NC
4104}
4105
4106/* Cirrus reorg for invalid instruction combinations. */
9b6b54e2 4107static void
e32bac5b 4108cirrus_reorg (rtx first)
9b6b54e2
NC
4109{
4110 enum attr_cirrus attr;
4111 rtx body = PATTERN (first);
4112 rtx t;
4113 int nops;
4114
4115 /* Any branch must be followed by 2 non Cirrus instructions. */
4116 if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN)
4117 {
4118 nops = 0;
4119 t = next_nonnote_insn (first);
4120
f0375c66 4121 if (arm_cirrus_insn_p (t))
9b6b54e2
NC
4122 ++ nops;
4123
f0375c66 4124 if (arm_cirrus_insn_p (next_nonnote_insn (t)))
9b6b54e2
NC
4125 ++ nops;
4126
4127 while (nops --)
4128 emit_insn_after (gen_nop (), first);
4129
4130 return;
4131 }
4132
4133 /* (float (blah)) is in parallel with a clobber. */
4134 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
4135 body = XVECEXP (body, 0, 0);
4136
4137 if (GET_CODE (body) == SET)
4138 {
4139 rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1);
4140
4141 /* cfldrd, cfldr64, cfstrd, cfstr64 must
4142 be followed by a non Cirrus insn. */
4143 if (get_attr_cirrus (first) == CIRRUS_DOUBLE)
4144 {
f0375c66 4145 if (arm_cirrus_insn_p (next_nonnote_insn (first)))
9b6b54e2
NC
4146 emit_insn_after (gen_nop (), first);
4147
4148 return;
4149 }
f0375c66 4150 else if (arm_memory_load_p (first))
9b6b54e2
NC
4151 {
4152 unsigned int arm_regno;
4153
4154 /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr,
4155 ldr/cfmv64hr combination where the Rd field is the same
4156 in both instructions must be split with a non Cirrus
4157 insn. Example:
4158
4159 ldr r0, blah
4160 nop
4161 cfmvsr mvf0, r0. */
4162
4163 /* Get Arm register number for ldr insn. */
4164 if (GET_CODE (lhs) == REG)
4165 arm_regno = REGNO (lhs);
4166 else if (GET_CODE (rhs) == REG)
4167 arm_regno = REGNO (rhs);
4168 else
4169 abort ();
4170
4171 /* Next insn. */
4172 first = next_nonnote_insn (first);
4173
f0375c66 4174 if (! arm_cirrus_insn_p (first))
9b6b54e2
NC
4175 return;
4176
4177 body = PATTERN (first);
4178
4179 /* (float (blah)) is in parallel with a clobber. */
4180 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0))
4181 body = XVECEXP (body, 0, 0);
4182
4183 if (GET_CODE (body) == FLOAT)
4184 body = XEXP (body, 0);
4185
4186 if (get_attr_cirrus (first) == CIRRUS_MOVE
4187 && GET_CODE (XEXP (body, 1)) == REG
4188 && arm_regno == REGNO (XEXP (body, 1)))
4189 emit_insn_after (gen_nop (), first);
4190
4191 return;
4192 }
4193 }
4194
4195 /* get_attr aborts on USE and CLOBBER. */
4196 if (!first
4197 || GET_CODE (first) != INSN
4198 || GET_CODE (PATTERN (first)) == USE
4199 || GET_CODE (PATTERN (first)) == CLOBBER)
4200 return;
4201
4202 attr = get_attr_cirrus (first);
4203
4204 /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...)
4205 must be followed by a non-coprocessor instruction. */
4206 if (attr == CIRRUS_COMPARE)
4207 {
4208 nops = 0;
4209
4210 t = next_nonnote_insn (first);
4211
f0375c66 4212 if (arm_cirrus_insn_p (t))
9b6b54e2
NC
4213 ++ nops;
4214
f0375c66 4215 if (arm_cirrus_insn_p (next_nonnote_insn (t)))
9b6b54e2
NC
4216 ++ nops;
4217
4218 while (nops --)
4219 emit_insn_after (gen_nop (), first);
4220
4221 return;
4222 }
4223}
4224
cce8749e 4225/* Return nonzero if OP is a constant power of two. */
cce8749e 4226int
e32bac5b 4227power_of_two_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
cce8749e
CH
4228{
4229 if (GET_CODE (op) == CONST_INT)
4230 {
d5b7b3ae 4231 HOST_WIDE_INT value = INTVAL (op);
1d6e90ac 4232
f3bb6135 4233 return value != 0 && (value & (value - 1)) == 0;
cce8749e 4234 }
1d6e90ac 4235
f3bb6135
RE
4236 return FALSE;
4237}
cce8749e
CH
4238
4239/* Return TRUE for a valid operand of a DImode operation.
e9c6b69b 4240 Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
ff9940b0
RE
4241 Note that this disallows MEM(REG+REG), but allows
4242 MEM(PRE/POST_INC/DEC(REG)). */
cce8749e 4243int
e32bac5b 4244di_operand (rtx op, enum machine_mode mode)
cce8749e 4245{
ff9940b0 4246 if (s_register_operand (op, mode))
f3bb6135 4247 return TRUE;
cce8749e 4248
9ce71c6f
BS
4249 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
4250 return FALSE;
4251
e9c6b69b
NC
4252 if (GET_CODE (op) == SUBREG)
4253 op = SUBREG_REG (op);
4254
cce8749e
CH
4255 switch (GET_CODE (op))
4256 {
4257 case CONST_DOUBLE:
4258 case CONST_INT:
f3bb6135
RE
4259 return TRUE;
4260
cce8749e 4261 case MEM:
f3bb6135
RE
4262 return memory_address_p (DImode, XEXP (op, 0));
4263
cce8749e 4264 default:
f3bb6135 4265 return FALSE;
cce8749e 4266 }
f3bb6135 4267}
cce8749e 4268
d5b7b3ae
RE
4269/* Like di_operand, but don't accept constants. */
4270int
e32bac5b 4271nonimmediate_di_operand (rtx op, enum machine_mode mode)
d5b7b3ae
RE
4272{
4273 if (s_register_operand (op, mode))
4274 return TRUE;
4275
4276 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
4277 return FALSE;
4278
4279 if (GET_CODE (op) == SUBREG)
4280 op = SUBREG_REG (op);
4281
4282 if (GET_CODE (op) == MEM)
4283 return memory_address_p (DImode, XEXP (op, 0));
4284
4285 return FALSE;
4286}
4287
f3139301 4288/* Return TRUE for a valid operand of a DFmode operation when -msoft-float.
e9c6b69b 4289 Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
f3139301
DE
4290 Note that this disallows MEM(REG+REG), but allows
4291 MEM(PRE/POST_INC/DEC(REG)). */
f3139301 4292int
e32bac5b 4293soft_df_operand (rtx op, enum machine_mode mode)
f3139301
DE
4294{
4295 if (s_register_operand (op, mode))
4b02997f 4296 return TRUE;
f3139301 4297
9ce71c6f
BS
4298 if (mode != VOIDmode && GET_MODE (op) != mode)
4299 return FALSE;
4300
37b80d2e
BS
4301 if (GET_CODE (op) == SUBREG && CONSTANT_P (SUBREG_REG (op)))
4302 return FALSE;
4303
e9c6b69b
NC
4304 if (GET_CODE (op) == SUBREG)
4305 op = SUBREG_REG (op);
9ce71c6f 4306
f3139301
DE
4307 switch (GET_CODE (op))
4308 {
4309 case CONST_DOUBLE:
4310 return TRUE;
4311
4312 case MEM:
4313 return memory_address_p (DFmode, XEXP (op, 0));
4314
4315 default:
4316 return FALSE;
4317 }
4318}
4319
d5b7b3ae
RE
4320/* Like soft_df_operand, but don't accept constants. */
4321int
e32bac5b 4322nonimmediate_soft_df_operand (rtx op, enum machine_mode mode)
d5b7b3ae
RE
4323{
4324 if (s_register_operand (op, mode))
4b02997f 4325 return TRUE;
d5b7b3ae
RE
4326
4327 if (mode != VOIDmode && GET_MODE (op) != mode)
4328 return FALSE;
4329
4330 if (GET_CODE (op) == SUBREG)
4331 op = SUBREG_REG (op);
4332
4333 if (GET_CODE (op) == MEM)
4334 return memory_address_p (DFmode, XEXP (op, 0));
4335 return FALSE;
4336}
cce8749e 4337
d5b7b3ae 4338/* Return TRUE for valid index operands. */
cce8749e 4339int
e32bac5b 4340index_operand (rtx op, enum machine_mode mode)
cce8749e 4341{
d5b7b3ae 4342 return (s_register_operand (op, mode)
ff9940b0 4343 || (immediate_operand (op, mode)
d5b7b3ae
RE
4344 && (GET_CODE (op) != CONST_INT
4345 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))));
f3bb6135 4346}
cce8749e 4347
ff9940b0
RE
4348/* Return TRUE for valid shifts by a constant. This also accepts any
4349 power of two on the (somewhat overly relaxed) assumption that the
6354dc9b 4350 shift operator in this case was a mult. */
ff9940b0 4351int
e32bac5b 4352const_shift_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
4353{
4354 return (power_of_two_operand (op, mode)
4355 || (immediate_operand (op, mode)
d5b7b3ae
RE
4356 && (GET_CODE (op) != CONST_INT
4357 || (INTVAL (op) < 32 && INTVAL (op) > 0))));
f3bb6135 4358}
ff9940b0 4359
cce8749e
CH
4360/* Return TRUE for arithmetic operators which can be combined with a multiply
4361 (shift). */
cce8749e 4362int
e32bac5b 4363shiftable_operator (rtx x, enum machine_mode mode)
cce8749e 4364{
1d6e90ac
NC
4365 enum rtx_code code;
4366
cce8749e
CH
4367 if (GET_MODE (x) != mode)
4368 return FALSE;
cce8749e 4369
1d6e90ac
NC
4370 code = GET_CODE (x);
4371
4372 return (code == PLUS || code == MINUS
4373 || code == IOR || code == XOR || code == AND);
f3bb6135 4374}
cce8749e 4375
6ab589e0 4376/* Return TRUE for binary logical operators. */
6ab589e0 4377int
e32bac5b 4378logical_binary_operator (rtx x, enum machine_mode mode)
6ab589e0 4379{
1d6e90ac
NC
4380 enum rtx_code code;
4381
6ab589e0
JL
4382 if (GET_MODE (x) != mode)
4383 return FALSE;
6ab589e0 4384
1d6e90ac
NC
4385 code = GET_CODE (x);
4386
4387 return (code == IOR || code == XOR || code == AND);
6ab589e0
JL
4388}
4389
6354dc9b 4390/* Return TRUE for shift operators. */
cce8749e 4391int
e32bac5b 4392shift_operator (rtx x,enum machine_mode mode)
cce8749e 4393{
1d6e90ac
NC
4394 enum rtx_code code;
4395
cce8749e
CH
4396 if (GET_MODE (x) != mode)
4397 return FALSE;
cce8749e 4398
1d6e90ac 4399 code = GET_CODE (x);
f3bb6135 4400
1d6e90ac
NC
4401 if (code == MULT)
4402 return power_of_two_operand (XEXP (x, 1), mode);
4403
4404 return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT
4405 || code == ROTATERT);
f3bb6135 4406}
ff9940b0 4407
6354dc9b
NC
4408/* Return TRUE if x is EQ or NE. */
4409int
e32bac5b 4410equality_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
ff9940b0 4411{
f3bb6135 4412 return GET_CODE (x) == EQ || GET_CODE (x) == NE;
ff9940b0
RE
4413}
4414
e45b72c4
RE
4415/* Return TRUE if x is a comparison operator other than LTGT or UNEQ. */
4416int
e32bac5b 4417arm_comparison_operator (rtx x, enum machine_mode mode)
e45b72c4
RE
4418{
4419 return (comparison_operator (x, mode)
4420 && GET_CODE (x) != LTGT
4421 && GET_CODE (x) != UNEQ);
4422}
4423
6354dc9b 4424/* Return TRUE for SMIN SMAX UMIN UMAX operators. */
ff9940b0 4425int
e32bac5b 4426minmax_operator (rtx x, enum machine_mode mode)
ff9940b0
RE
4427{
4428 enum rtx_code code = GET_CODE (x);
4429
4430 if (GET_MODE (x) != mode)
4431 return FALSE;
f3bb6135 4432
ff9940b0 4433 return code == SMIN || code == SMAX || code == UMIN || code == UMAX;
f3bb6135 4434}
ff9940b0 4435
ff9940b0 4436/* Return TRUE if this is the condition code register, if we aren't given
6354dc9b 4437 a mode, accept any class CCmode register. */
ff9940b0 4438int
e32bac5b 4439cc_register (rtx x, enum machine_mode mode)
ff9940b0
RE
4440{
4441 if (mode == VOIDmode)
4442 {
4443 mode = GET_MODE (x);
d5b7b3ae 4444
ff9940b0
RE
4445 if (GET_MODE_CLASS (mode) != MODE_CC)
4446 return FALSE;
4447 }
f3bb6135 4448
d5b7b3ae
RE
4449 if ( GET_MODE (x) == mode
4450 && GET_CODE (x) == REG
4451 && REGNO (x) == CC_REGNUM)
ff9940b0 4452 return TRUE;
f3bb6135 4453
ff9940b0
RE
4454 return FALSE;
4455}
5bbe2d40
RE
4456
4457/* Return TRUE if this is the condition code register, if we aren't given
84ed5e79
RE
4458 a mode, accept any class CCmode register which indicates a dominance
4459 expression. */
5bbe2d40 4460int
e32bac5b 4461dominant_cc_register (rtx x, enum machine_mode mode)
5bbe2d40
RE
4462{
4463 if (mode == VOIDmode)
4464 {
4465 mode = GET_MODE (x);
d5b7b3ae 4466
84ed5e79 4467 if (GET_MODE_CLASS (mode) != MODE_CC)
5bbe2d40
RE
4468 return FALSE;
4469 }
4470
e32bac5b 4471 if (mode != CC_DNEmode && mode != CC_DEQmode
84ed5e79
RE
4472 && mode != CC_DLEmode && mode != CC_DLTmode
4473 && mode != CC_DGEmode && mode != CC_DGTmode
4474 && mode != CC_DLEUmode && mode != CC_DLTUmode
4475 && mode != CC_DGEUmode && mode != CC_DGTUmode)
4476 return FALSE;
4477
d5b7b3ae 4478 return cc_register (x, mode);
5bbe2d40
RE
4479}
4480
2b835d68
RE
4481/* Return TRUE if X references a SYMBOL_REF. */
4482int
e32bac5b 4483symbol_mentioned_p (rtx x)
2b835d68 4484{
1d6e90ac
NC
4485 const char * fmt;
4486 int i;
2b835d68
RE
4487
4488 if (GET_CODE (x) == SYMBOL_REF)
4489 return 1;
4490
4491 fmt = GET_RTX_FORMAT (GET_CODE (x));
d5b7b3ae 4492
2b835d68
RE
4493 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4494 {
4495 if (fmt[i] == 'E')
4496 {
1d6e90ac 4497 int j;
2b835d68
RE
4498
4499 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4500 if (symbol_mentioned_p (XVECEXP (x, i, j)))
4501 return 1;
4502 }
4503 else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i)))
4504 return 1;
4505 }
4506
4507 return 0;
4508}
4509
4510/* Return TRUE if X references a LABEL_REF. */
4511int
e32bac5b 4512label_mentioned_p (rtx x)
2b835d68 4513{
1d6e90ac
NC
4514 const char * fmt;
4515 int i;
2b835d68
RE
4516
4517 if (GET_CODE (x) == LABEL_REF)
4518 return 1;
4519
4520 fmt = GET_RTX_FORMAT (GET_CODE (x));
4521 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4522 {
4523 if (fmt[i] == 'E')
4524 {
1d6e90ac 4525 int j;
2b835d68
RE
4526
4527 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4528 if (label_mentioned_p (XVECEXP (x, i, j)))
4529 return 1;
4530 }
4531 else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i)))
4532 return 1;
4533 }
4534
4535 return 0;
4536}
4537
ff9940b0 4538enum rtx_code
e32bac5b 4539minmax_code (rtx x)
ff9940b0
RE
4540{
4541 enum rtx_code code = GET_CODE (x);
4542
4543 if (code == SMAX)
4544 return GE;
f3bb6135 4545 else if (code == SMIN)
ff9940b0 4546 return LE;
f3bb6135 4547 else if (code == UMIN)
ff9940b0 4548 return LEU;
f3bb6135 4549 else if (code == UMAX)
ff9940b0 4550 return GEU;
f3bb6135 4551
ff9940b0
RE
4552 abort ();
4553}
4554
6354dc9b 4555/* Return 1 if memory locations are adjacent. */
f3bb6135 4556int
e32bac5b 4557adjacent_mem_locations (rtx a, rtx b)
ff9940b0 4558{
ff9940b0
RE
4559 if ((GET_CODE (XEXP (a, 0)) == REG
4560 || (GET_CODE (XEXP (a, 0)) == PLUS
4561 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
4562 && (GET_CODE (XEXP (b, 0)) == REG
4563 || (GET_CODE (XEXP (b, 0)) == PLUS
4564 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
4565 {
1d6e90ac
NC
4566 int val0 = 0, val1 = 0;
4567 int reg0, reg1;
4568
ff9940b0
RE
4569 if (GET_CODE (XEXP (a, 0)) == PLUS)
4570 {
1d6e90ac 4571 reg0 = REGNO (XEXP (XEXP (a, 0), 0));
ff9940b0
RE
4572 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
4573 }
4574 else
4575 reg0 = REGNO (XEXP (a, 0));
1d6e90ac 4576
ff9940b0
RE
4577 if (GET_CODE (XEXP (b, 0)) == PLUS)
4578 {
1d6e90ac 4579 reg1 = REGNO (XEXP (XEXP (b, 0), 0));
ff9940b0
RE
4580 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
4581 }
4582 else
4583 reg1 = REGNO (XEXP (b, 0));
1d6e90ac 4584
e32bac5b
RE
4585 /* Don't accept any offset that will require multiple
4586 instructions to handle, since this would cause the
4587 arith_adjacentmem pattern to output an overlong sequence. */
c75a3ddc
PB
4588 if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1))
4589 return 0;
4590
ff9940b0
RE
4591 return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
4592 }
4593 return 0;
4594}
4595
4596/* Return 1 if OP is a load multiple operation. It is known to be
6354dc9b 4597 parallel and the first section will be tested. */
f3bb6135 4598int
e32bac5b 4599load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
ff9940b0 4600{
f3bb6135 4601 HOST_WIDE_INT count = XVECLEN (op, 0);
ff9940b0
RE
4602 int dest_regno;
4603 rtx src_addr;
f3bb6135 4604 HOST_WIDE_INT i = 1, base = 0;
ff9940b0
RE
4605 rtx elt;
4606
4607 if (count <= 1
4608 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
4609 return 0;
4610
6354dc9b 4611 /* Check to see if this might be a write-back. */
ff9940b0
RE
4612 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
4613 {
4614 i++;
4615 base = 1;
4616
6354dc9b 4617 /* Now check it more carefully. */
ff9940b0
RE
4618 if (GET_CODE (SET_DEST (elt)) != REG
4619 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
4620 || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
4621 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
41e3f998 4622 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
ff9940b0 4623 return 0;
ff9940b0
RE
4624 }
4625
4626 /* Perform a quick check so we don't blow up below. */
4627 if (count <= i
4628 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
4629 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
4630 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
4631 return 0;
4632
4633 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
4634 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
4635
4636 for (; i < count; i++)
4637 {
ed4c4348 4638 elt = XVECEXP (op, 0, i);
ff9940b0
RE
4639
4640 if (GET_CODE (elt) != SET
4641 || GET_CODE (SET_DEST (elt)) != REG
4642 || GET_MODE (SET_DEST (elt)) != SImode
6354dc9b 4643 || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)
ff9940b0
RE
4644 || GET_CODE (SET_SRC (elt)) != MEM
4645 || GET_MODE (SET_SRC (elt)) != SImode
4646 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
5895f793 4647 || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
ff9940b0
RE
4648 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
4649 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)
4650 return 0;
4651 }
4652
4653 return 1;
4654}
4655
4656/* Return 1 if OP is a store multiple operation. It is known to be
6354dc9b 4657 parallel and the first section will be tested. */
f3bb6135 4658int
e32bac5b 4659store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
ff9940b0 4660{
f3bb6135 4661 HOST_WIDE_INT count = XVECLEN (op, 0);
ff9940b0
RE
4662 int src_regno;
4663 rtx dest_addr;
f3bb6135 4664 HOST_WIDE_INT i = 1, base = 0;
ff9940b0
RE
4665 rtx elt;
4666
4667 if (count <= 1
4668 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
4669 return 0;
4670
6354dc9b 4671 /* Check to see if this might be a write-back. */
ff9940b0
RE
4672 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
4673 {
4674 i++;
4675 base = 1;
4676
6354dc9b 4677 /* Now check it more carefully. */
ff9940b0
RE
4678 if (GET_CODE (SET_DEST (elt)) != REG
4679 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
4680 || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
4681 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
41e3f998 4682 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
ff9940b0 4683 return 0;
ff9940b0
RE
4684 }
4685
4686 /* Perform a quick check so we don't blow up below. */
4687 if (count <= i
4688 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
4689 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
4690 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
4691 return 0;
4692
4693 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
4694 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
4695
4696 for (; i < count; i++)
4697 {
4698 elt = XVECEXP (op, 0, i);
4699
4700 if (GET_CODE (elt) != SET
4701 || GET_CODE (SET_SRC (elt)) != REG
4702 || GET_MODE (SET_SRC (elt)) != SImode
6354dc9b 4703 || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)
ff9940b0
RE
4704 || GET_CODE (SET_DEST (elt)) != MEM
4705 || GET_MODE (SET_DEST (elt)) != SImode
4706 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
5895f793 4707 || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
ff9940b0
RE
4708 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
4709 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)
4710 return 0;
4711 }
4712
4713 return 1;
4714}
e2c671ba 4715
84ed5e79 4716int
e32bac5b
RE
4717load_multiple_sequence (rtx *operands, int nops, int *regs, int *base,
4718 HOST_WIDE_INT *load_offset)
84ed5e79
RE
4719{
4720 int unsorted_regs[4];
4721 HOST_WIDE_INT unsorted_offsets[4];
4722 int order[4];
ad076f4e 4723 int base_reg = -1;
84ed5e79
RE
4724 int i;
4725
1d6e90ac
NC
4726 /* Can only handle 2, 3, or 4 insns at present,
4727 though could be easily extended if required. */
84ed5e79
RE
4728 if (nops < 2 || nops > 4)
4729 abort ();
4730
4731 /* Loop over the operands and check that the memory references are
4732 suitable (ie immediate offsets from the same base register). At
4733 the same time, extract the target register, and the memory
4734 offsets. */
4735 for (i = 0; i < nops; i++)
4736 {
4737 rtx reg;
4738 rtx offset;
4739
56636818
JL
4740 /* Convert a subreg of a mem into the mem itself. */
4741 if (GET_CODE (operands[nops + i]) == SUBREG)
4e26a7af 4742 operands[nops + i] = alter_subreg (operands + (nops + i));
56636818 4743
84ed5e79
RE
4744 if (GET_CODE (operands[nops + i]) != MEM)
4745 abort ();
4746
4747 /* Don't reorder volatile memory references; it doesn't seem worth
4748 looking for the case where the order is ok anyway. */
4749 if (MEM_VOLATILE_P (operands[nops + i]))
4750 return 0;
4751
4752 offset = const0_rtx;
4753
4754 if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG
4755 || (GET_CODE (reg) == SUBREG
4756 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4757 || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
4758 && ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))
4759 == REG)
4760 || (GET_CODE (reg) == SUBREG
4761 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4762 && (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))
4763 == CONST_INT)))
4764 {
4765 if (i == 0)
4766 {
d5b7b3ae 4767 base_reg = REGNO (reg);
84ed5e79
RE
4768 unsorted_regs[0] = (GET_CODE (operands[i]) == REG
4769 ? REGNO (operands[i])
4770 : REGNO (SUBREG_REG (operands[i])));
4771 order[0] = 0;
4772 }
4773 else
4774 {
6354dc9b 4775 if (base_reg != (int) REGNO (reg))
84ed5e79
RE
4776 /* Not addressed from the same base register. */
4777 return 0;
4778
4779 unsorted_regs[i] = (GET_CODE (operands[i]) == REG
4780 ? REGNO (operands[i])
4781 : REGNO (SUBREG_REG (operands[i])));
4782 if (unsorted_regs[i] < unsorted_regs[order[0]])
4783 order[0] = i;
4784 }
4785
4786 /* If it isn't an integer register, or if it overwrites the
4787 base register but isn't the last insn in the list, then
4788 we can't do this. */
4789 if (unsorted_regs[i] < 0 || unsorted_regs[i] > 14
4790 || (i != nops - 1 && unsorted_regs[i] == base_reg))
4791 return 0;
4792
4793 unsorted_offsets[i] = INTVAL (offset);
4794 }
4795 else
4796 /* Not a suitable memory address. */
4797 return 0;
4798 }
4799
4800 /* All the useful information has now been extracted from the
4801 operands into unsorted_regs and unsorted_offsets; additionally,
4802 order[0] has been set to the lowest numbered register in the
4803 list. Sort the registers into order, and check that the memory
4804 offsets are ascending and adjacent. */
4805
4806 for (i = 1; i < nops; i++)
4807 {
4808 int j;
4809
4810 order[i] = order[i - 1];
4811 for (j = 0; j < nops; j++)
4812 if (unsorted_regs[j] > unsorted_regs[order[i - 1]]
4813 && (order[i] == order[i - 1]
4814 || unsorted_regs[j] < unsorted_regs[order[i]]))
4815 order[i] = j;
4816
4817 /* Have we found a suitable register? if not, one must be used more
4818 than once. */
4819 if (order[i] == order[i - 1])
4820 return 0;
4821
4822 /* Is the memory address adjacent and ascending? */
4823 if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)
4824 return 0;
4825 }
4826
4827 if (base)
4828 {
4829 *base = base_reg;
4830
4831 for (i = 0; i < nops; i++)
4832 regs[i] = unsorted_regs[order[i]];
4833
4834 *load_offset = unsorted_offsets[order[0]];
4835 }
4836
4837 if (unsorted_offsets[order[0]] == 0)
4838 return 1; /* ldmia */
4839
4840 if (unsorted_offsets[order[0]] == 4)
4841 return 2; /* ldmib */
4842
4843 if (unsorted_offsets[order[nops - 1]] == 0)
4844 return 3; /* ldmda */
4845
4846 if (unsorted_offsets[order[nops - 1]] == -4)
4847 return 4; /* ldmdb */
4848
949d79eb
RE
4849 /* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm
4850 if the offset isn't small enough. The reason 2 ldrs are faster
4851 is because these ARMs are able to do more than one cache access
4852 in a single cycle. The ARM9 and StrongARM have Harvard caches,
4853 whilst the ARM8 has a double bandwidth cache. This means that
4854 these cores can do both an instruction fetch and a data fetch in
4855 a single cycle, so the trick of calculating the address into a
4856 scratch register (one of the result regs) and then doing a load
4857 multiple actually becomes slower (and no smaller in code size).
4858 That is the transformation
6cc8c0b3
NC
4859
4860 ldr rd1, [rbase + offset]
4861 ldr rd2, [rbase + offset + 4]
4862
4863 to
4864
4865 add rd1, rbase, offset
4866 ldmia rd1, {rd1, rd2}
4867
949d79eb
RE
4868 produces worse code -- '3 cycles + any stalls on rd2' instead of
4869 '2 cycles + any stalls on rd2'. On ARMs with only one cache
4870 access per cycle, the first sequence could never complete in less
4871 than 6 cycles, whereas the ldm sequence would only take 5 and
4872 would make better use of sequential accesses if not hitting the
4873 cache.
4874
4875 We cheat here and test 'arm_ld_sched' which we currently know to
4876 only be true for the ARM8, ARM9 and StrongARM. If this ever
4877 changes, then the test below needs to be reworked. */
f5a1b0d2 4878 if (nops == 2 && arm_ld_sched)
b36ba79f
RE
4879 return 0;
4880
84ed5e79
RE
4881 /* Can't do it without setting up the offset, only do this if it takes
4882 no more than one insn. */
4883 return (const_ok_for_arm (unsorted_offsets[order[0]])
4884 || const_ok_for_arm (-unsorted_offsets[order[0]])) ? 5 : 0;
4885}
4886
cd2b33d0 4887const char *
e32bac5b 4888emit_ldm_seq (rtx *operands, int nops)
84ed5e79
RE
4889{
4890 int regs[4];
4891 int base_reg;
4892 HOST_WIDE_INT offset;
4893 char buf[100];
4894 int i;
4895
4896 switch (load_multiple_sequence (operands, nops, regs, &base_reg, &offset))
4897 {
4898 case 1:
4899 strcpy (buf, "ldm%?ia\t");
4900 break;
4901
4902 case 2:
4903 strcpy (buf, "ldm%?ib\t");
4904 break;
4905
4906 case 3:
4907 strcpy (buf, "ldm%?da\t");
4908 break;
4909
4910 case 4:
4911 strcpy (buf, "ldm%?db\t");
4912 break;
4913
4914 case 5:
4915 if (offset >= 0)
4916 sprintf (buf, "add%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX,
4917 reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],
4918 (long) offset);
4919 else
4920 sprintf (buf, "sub%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX,
4921 reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],
4922 (long) -offset);
4923 output_asm_insn (buf, operands);
4924 base_reg = regs[0];
4925 strcpy (buf, "ldm%?ia\t");
4926 break;
4927
4928 default:
4929 abort ();
4930 }
4931
4932 sprintf (buf + strlen (buf), "%s%s, {%s%s", REGISTER_PREFIX,
4933 reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);
4934
4935 for (i = 1; i < nops; i++)
4936 sprintf (buf + strlen (buf), ", %s%s", REGISTER_PREFIX,
4937 reg_names[regs[i]]);
4938
4939 strcat (buf, "}\t%@ phole ldm");
4940
4941 output_asm_insn (buf, operands);
4942 return "";
4943}
4944
4945int
e32bac5b
RE
4946store_multiple_sequence (rtx *operands, int nops, int *regs, int *base,
4947 HOST_WIDE_INT * load_offset)
84ed5e79
RE
4948{
4949 int unsorted_regs[4];
4950 HOST_WIDE_INT unsorted_offsets[4];
4951 int order[4];
ad076f4e 4952 int base_reg = -1;
84ed5e79
RE
4953 int i;
4954
4955 /* Can only handle 2, 3, or 4 insns at present, though could be easily
4956 extended if required. */
4957 if (nops < 2 || nops > 4)
4958 abort ();
4959
4960 /* Loop over the operands and check that the memory references are
4961 suitable (ie immediate offsets from the same base register). At
4962 the same time, extract the target register, and the memory
4963 offsets. */
4964 for (i = 0; i < nops; i++)
4965 {
4966 rtx reg;
4967 rtx offset;
4968
56636818
JL
4969 /* Convert a subreg of a mem into the mem itself. */
4970 if (GET_CODE (operands[nops + i]) == SUBREG)
4e26a7af 4971 operands[nops + i] = alter_subreg (operands + (nops + i));
56636818 4972
84ed5e79
RE
4973 if (GET_CODE (operands[nops + i]) != MEM)
4974 abort ();
4975
4976 /* Don't reorder volatile memory references; it doesn't seem worth
4977 looking for the case where the order is ok anyway. */
4978 if (MEM_VOLATILE_P (operands[nops + i]))
4979 return 0;
4980
4981 offset = const0_rtx;
4982
4983 if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG
4984 || (GET_CODE (reg) == SUBREG
4985 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4986 || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
4987 && ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))
4988 == REG)
4989 || (GET_CODE (reg) == SUBREG
4990 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4991 && (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))
4992 == CONST_INT)))
4993 {
4994 if (i == 0)
4995 {
62b10bbc 4996 base_reg = REGNO (reg);
84ed5e79
RE
4997 unsorted_regs[0] = (GET_CODE (operands[i]) == REG
4998 ? REGNO (operands[i])
4999 : REGNO (SUBREG_REG (operands[i])));
5000 order[0] = 0;
5001 }
5002 else
5003 {
6354dc9b 5004 if (base_reg != (int) REGNO (reg))
84ed5e79
RE
5005 /* Not addressed from the same base register. */
5006 return 0;
5007
5008 unsorted_regs[i] = (GET_CODE (operands[i]) == REG
5009 ? REGNO (operands[i])
5010 : REGNO (SUBREG_REG (operands[i])));
5011 if (unsorted_regs[i] < unsorted_regs[order[0]])
5012 order[0] = i;
5013 }
5014
5015 /* If it isn't an integer register, then we can't do this. */
5016 if (unsorted_regs[i] < 0 || unsorted_regs[i] > 14)
5017 return 0;
5018
5019 unsorted_offsets[i] = INTVAL (offset);
5020 }
5021 else
5022 /* Not a suitable memory address. */
5023 return 0;
5024 }
5025
5026 /* All the useful information has now been extracted from the
5027 operands into unsorted_regs and unsorted_offsets; additionally,
5028 order[0] has been set to the lowest numbered register in the
5029 list. Sort the registers into order, and check that the memory
5030 offsets are ascending and adjacent. */
5031
5032 for (i = 1; i < nops; i++)
5033 {
5034 int j;
5035
5036 order[i] = order[i - 1];
5037 for (j = 0; j < nops; j++)
5038 if (unsorted_regs[j] > unsorted_regs[order[i - 1]]
5039 && (order[i] == order[i - 1]
5040 || unsorted_regs[j] < unsorted_regs[order[i]]))
5041 order[i] = j;
5042
5043 /* Have we found a suitable register? if not, one must be used more
5044 than once. */
5045 if (order[i] == order[i - 1])
5046 return 0;
5047
5048 /* Is the memory address adjacent and ascending? */
5049 if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)
5050 return 0;
5051 }
5052
5053 if (base)
5054 {
5055 *base = base_reg;
5056
5057 for (i = 0; i < nops; i++)
5058 regs[i] = unsorted_regs[order[i]];
5059
5060 *load_offset = unsorted_offsets[order[0]];
5061 }
5062
5063 if (unsorted_offsets[order[0]] == 0)
5064 return 1; /* stmia */
5065
5066 if (unsorted_offsets[order[0]] == 4)
5067 return 2; /* stmib */
5068
5069 if (unsorted_offsets[order[nops - 1]] == 0)
5070 return 3; /* stmda */
5071
5072 if (unsorted_offsets[order[nops - 1]] == -4)
5073 return 4; /* stmdb */
5074
5075 return 0;
5076}
5077
cd2b33d0 5078const char *
e32bac5b 5079emit_stm_seq (rtx *operands, int nops)
84ed5e79
RE
5080{
5081 int regs[4];
5082 int base_reg;
5083 HOST_WIDE_INT offset;
5084 char buf[100];
5085 int i;
5086
5087 switch (store_multiple_sequence (operands, nops, regs, &base_reg, &offset))
5088 {
5089 case 1:
5090 strcpy (buf, "stm%?ia\t");
5091 break;
5092
5093 case 2:
5094 strcpy (buf, "stm%?ib\t");
5095 break;
5096
5097 case 3:
5098 strcpy (buf, "stm%?da\t");
5099 break;
5100
5101 case 4:
5102 strcpy (buf, "stm%?db\t");
5103 break;
5104
5105 default:
5106 abort ();
5107 }
5108
5109 sprintf (buf + strlen (buf), "%s%s, {%s%s", REGISTER_PREFIX,
5110 reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);
5111
5112 for (i = 1; i < nops; i++)
5113 sprintf (buf + strlen (buf), ", %s%s", REGISTER_PREFIX,
5114 reg_names[regs[i]]);
5115
5116 strcat (buf, "}\t%@ phole stm");
5117
5118 output_asm_insn (buf, operands);
5119 return "";
5120}
5121
e2c671ba 5122int
e32bac5b 5123multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
e2c671ba
RE
5124{
5125 if (GET_CODE (op) != PARALLEL
5126 || (GET_CODE (XVECEXP (op, 0, 0)) != SET)
5127 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
b15bca31 5128 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT))
e2c671ba
RE
5129 return 0;
5130
5131 return 1;
5132}
ff9940b0 5133\f
6354dc9b 5134/* Routines for use in generating RTL. */
1d6e90ac 5135
f3bb6135 5136rtx
e32bac5b
RE
5137arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
5138 int write_back, int unchanging_p, int in_struct_p,
5139 int scalar_p)
ff9940b0
RE
5140{
5141 int i = 0, j;
5142 rtx result;
5143 int sign = up ? 1 : -1;
56636818 5144 rtx mem;
ff9940b0 5145
d19fb8e3
NC
5146 /* XScale has load-store double instructions, but they have stricter
5147 alignment requirements than load-store multiple, so we can not
5148 use them.
5149
5150 For XScale ldm requires 2 + NREGS cycles to complete and blocks
5151 the pipeline until completion.
5152
5153 NREGS CYCLES
5154 1 3
5155 2 4
5156 3 5
5157 4 6
5158
5159 An ldr instruction takes 1-3 cycles, but does not block the
5160 pipeline.
5161
5162 NREGS CYCLES
5163 1 1-3
5164 2 2-6
5165 3 3-9
5166 4 4-12
5167
5168 Best case ldr will always win. However, the more ldr instructions
5169 we issue, the less likely we are to be able to schedule them well.
5170 Using ldr instructions also increases code size.
5171
5172 As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
5173 for counts of 3 or 4 regs. */
4b3c2e48 5174 if (arm_tune_xscale && count <= 2 && ! optimize_size)
d19fb8e3
NC
5175 {
5176 rtx seq;
5177
5178 start_sequence ();
5179
5180 for (i = 0; i < count; i++)
5181 {
5182 mem = gen_rtx_MEM (SImode, plus_constant (from, i * 4 * sign));
5183 RTX_UNCHANGING_P (mem) = unchanging_p;
5184 MEM_IN_STRUCT_P (mem) = in_struct_p;
5185 MEM_SCALAR_P (mem) = scalar_p;
5186 emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);
5187 }
5188
5189 if (write_back)
5190 emit_move_insn (from, plus_constant (from, count * 4 * sign));
5191
2f937369 5192 seq = get_insns ();
d19fb8e3
NC
5193 end_sequence ();
5194
5195 return seq;
5196 }
5197
43cffd11 5198 result = gen_rtx_PARALLEL (VOIDmode,
41e3f998 5199 rtvec_alloc (count + (write_back ? 1 : 0)));
ff9940b0 5200 if (write_back)
f3bb6135 5201 {
ff9940b0 5202 XVECEXP (result, 0, 0)
43cffd11
RE
5203 = gen_rtx_SET (GET_MODE (from), from,
5204 plus_constant (from, count * 4 * sign));
ff9940b0
RE
5205 i = 1;
5206 count++;
f3bb6135
RE
5207 }
5208
ff9940b0 5209 for (j = 0; i < count; i++, j++)
f3bb6135 5210 {
43cffd11 5211 mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign));
56636818
JL
5212 RTX_UNCHANGING_P (mem) = unchanging_p;
5213 MEM_IN_STRUCT_P (mem) = in_struct_p;
c6df88cb 5214 MEM_SCALAR_P (mem) = scalar_p;
43cffd11
RE
5215 XVECEXP (result, 0, i)
5216 = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
f3bb6135
RE
5217 }
5218
ff9940b0
RE
5219 return result;
5220}
5221
f3bb6135 5222rtx
e32bac5b
RE
5223arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
5224 int write_back, int unchanging_p, int in_struct_p,
5225 int scalar_p)
ff9940b0
RE
5226{
5227 int i = 0, j;
5228 rtx result;
5229 int sign = up ? 1 : -1;
56636818 5230 rtx mem;
ff9940b0 5231
d19fb8e3
NC
5232 /* See arm_gen_load_multiple for discussion of
5233 the pros/cons of ldm/stm usage for XScale. */
4b3c2e48 5234 if (arm_tune_xscale && count <= 2 && ! optimize_size)
d19fb8e3
NC
5235 {
5236 rtx seq;
5237
5238 start_sequence ();
5239
5240 for (i = 0; i < count; i++)
5241 {
5242 mem = gen_rtx_MEM (SImode, plus_constant (to, i * 4 * sign));
5243 RTX_UNCHANGING_P (mem) = unchanging_p;
5244 MEM_IN_STRUCT_P (mem) = in_struct_p;
5245 MEM_SCALAR_P (mem) = scalar_p;
5246 emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));
5247 }
5248
5249 if (write_back)
5250 emit_move_insn (to, plus_constant (to, count * 4 * sign));
5251
2f937369 5252 seq = get_insns ();
d19fb8e3
NC
5253 end_sequence ();
5254
5255 return seq;
5256 }
5257
43cffd11 5258 result = gen_rtx_PARALLEL (VOIDmode,
41e3f998 5259 rtvec_alloc (count + (write_back ? 1 : 0)));
ff9940b0 5260 if (write_back)
f3bb6135 5261 {
ff9940b0 5262 XVECEXP (result, 0, 0)
43cffd11
RE
5263 = gen_rtx_SET (GET_MODE (to), to,
5264 plus_constant (to, count * 4 * sign));
ff9940b0
RE
5265 i = 1;
5266 count++;
f3bb6135
RE
5267 }
5268
ff9940b0 5269 for (j = 0; i < count; i++, j++)
f3bb6135 5270 {
43cffd11 5271 mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign));
56636818
JL
5272 RTX_UNCHANGING_P (mem) = unchanging_p;
5273 MEM_IN_STRUCT_P (mem) = in_struct_p;
c6df88cb 5274 MEM_SCALAR_P (mem) = scalar_p;
56636818 5275
43cffd11
RE
5276 XVECEXP (result, 0, i)
5277 = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
f3bb6135
RE
5278 }
5279
ff9940b0
RE
5280 return result;
5281}
5282
880e2516 5283int
e32bac5b 5284arm_gen_movstrqi (rtx *operands)
880e2516
RE
5285{
5286 HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
ad076f4e 5287 int i;
880e2516 5288 rtx src, dst;
ad076f4e 5289 rtx st_src, st_dst, fin_src, fin_dst;
880e2516 5290 rtx part_bytes_reg = NULL;
56636818
JL
5291 rtx mem;
5292 int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p;
c6df88cb 5293 int dst_scalar_p, src_scalar_p;
880e2516
RE
5294
5295 if (GET_CODE (operands[2]) != CONST_INT
5296 || GET_CODE (operands[3]) != CONST_INT
5297 || INTVAL (operands[2]) > 64
5298 || INTVAL (operands[3]) & 3)
5299 return 0;
5300
5301 st_dst = XEXP (operands[0], 0);
5302 st_src = XEXP (operands[1], 0);
56636818
JL
5303
5304 dst_unchanging_p = RTX_UNCHANGING_P (operands[0]);
5305 dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
c6df88cb 5306 dst_scalar_p = MEM_SCALAR_P (operands[0]);
56636818
JL
5307 src_unchanging_p = RTX_UNCHANGING_P (operands[1]);
5308 src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
c6df88cb 5309 src_scalar_p = MEM_SCALAR_P (operands[1]);
56636818 5310
880e2516
RE
5311 fin_dst = dst = copy_to_mode_reg (SImode, st_dst);
5312 fin_src = src = copy_to_mode_reg (SImode, st_src);
5313
e9d7b180 5314 in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2]));
880e2516
RE
5315 out_words_to_go = INTVAL (operands[2]) / 4;
5316 last_bytes = INTVAL (operands[2]) & 3;
5317
5318 if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
43cffd11 5319 part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
880e2516
RE
5320
5321 for (i = 0; in_words_to_go >= 2; i+=4)
5322 {
bd9c7e23 5323 if (in_words_to_go > 4)
56636818 5324 emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
c6df88cb
MM
5325 src_unchanging_p,
5326 src_in_struct_p,
5327 src_scalar_p));
bd9c7e23
RE
5328 else
5329 emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE,
56636818 5330 FALSE, src_unchanging_p,
c6df88cb 5331 src_in_struct_p, src_scalar_p));
bd9c7e23 5332
880e2516
RE
5333 if (out_words_to_go)
5334 {
bd9c7e23 5335 if (out_words_to_go > 4)
56636818
JL
5336 emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
5337 dst_unchanging_p,
c6df88cb
MM
5338 dst_in_struct_p,
5339 dst_scalar_p));
bd9c7e23
RE
5340 else if (out_words_to_go != 1)
5341 emit_insn (arm_gen_store_multiple (0, out_words_to_go,
5342 dst, TRUE,
5343 (last_bytes == 0
56636818
JL
5344 ? FALSE : TRUE),
5345 dst_unchanging_p,
c6df88cb
MM
5346 dst_in_struct_p,
5347 dst_scalar_p));
880e2516
RE
5348 else
5349 {
43cffd11 5350 mem = gen_rtx_MEM (SImode, dst);
56636818
JL
5351 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5352 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 5353 MEM_SCALAR_P (mem) = dst_scalar_p;
43cffd11 5354 emit_move_insn (mem, gen_rtx_REG (SImode, 0));
bd9c7e23
RE
5355 if (last_bytes != 0)
5356 emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
880e2516
RE
5357 }
5358 }
5359
5360 in_words_to_go -= in_words_to_go < 4 ? in_words_to_go : 4;
5361 out_words_to_go -= out_words_to_go < 4 ? out_words_to_go : 4;
5362 }
5363
5364 /* OUT_WORDS_TO_GO will be zero here if there are byte stores to do. */
5365 if (out_words_to_go)
62b10bbc
NC
5366 {
5367 rtx sreg;
5368
5369 mem = gen_rtx_MEM (SImode, src);
5370 RTX_UNCHANGING_P (mem) = src_unchanging_p;
5371 MEM_IN_STRUCT_P (mem) = src_in_struct_p;
5372 MEM_SCALAR_P (mem) = src_scalar_p;
5373 emit_move_insn (sreg = gen_reg_rtx (SImode), mem);
5374 emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
5375
5376 mem = gen_rtx_MEM (SImode, dst);
5377 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5378 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
5379 MEM_SCALAR_P (mem) = dst_scalar_p;
5380 emit_move_insn (mem, sreg);
5381 emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
5382 in_words_to_go--;
5383
5384 if (in_words_to_go) /* Sanity check */
5385 abort ();
5386 }
880e2516
RE
5387
5388 if (in_words_to_go)
5389 {
5390 if (in_words_to_go < 0)
5391 abort ();
5392
43cffd11 5393 mem = gen_rtx_MEM (SImode, src);
56636818
JL
5394 RTX_UNCHANGING_P (mem) = src_unchanging_p;
5395 MEM_IN_STRUCT_P (mem) = src_in_struct_p;
c6df88cb 5396 MEM_SCALAR_P (mem) = src_scalar_p;
56636818 5397 part_bytes_reg = copy_to_mode_reg (SImode, mem);
880e2516
RE
5398 }
5399
d5b7b3ae
RE
5400 if (last_bytes && part_bytes_reg == NULL)
5401 abort ();
5402
880e2516
RE
5403 if (BYTES_BIG_ENDIAN && last_bytes)
5404 {
5405 rtx tmp = gen_reg_rtx (SImode);
5406
6354dc9b 5407 /* The bytes we want are in the top end of the word. */
bee06f3d
RE
5408 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg,
5409 GEN_INT (8 * (4 - last_bytes))));
880e2516
RE
5410 part_bytes_reg = tmp;
5411
5412 while (last_bytes)
5413 {
43cffd11 5414 mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1));
56636818
JL
5415 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5416 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 5417 MEM_SCALAR_P (mem) = dst_scalar_p;
5d5603e2
BS
5418 emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
5419
880e2516
RE
5420 if (--last_bytes)
5421 {
5422 tmp = gen_reg_rtx (SImode);
5423 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (8)));
5424 part_bytes_reg = tmp;
5425 }
5426 }
5427
5428 }
5429 else
5430 {
d5b7b3ae 5431 if (last_bytes > 1)
880e2516 5432 {
d5b7b3ae 5433 mem = gen_rtx_MEM (HImode, dst);
56636818
JL
5434 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5435 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 5436 MEM_SCALAR_P (mem) = dst_scalar_p;
5d5603e2 5437 emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
d5b7b3ae
RE
5438 last_bytes -= 2;
5439 if (last_bytes)
880e2516
RE
5440 {
5441 rtx tmp = gen_reg_rtx (SImode);
bd9c7e23 5442
d5b7b3ae
RE
5443 emit_insn (gen_addsi3 (dst, dst, GEN_INT (2)));
5444 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16)));
880e2516
RE
5445 part_bytes_reg = tmp;
5446 }
5447 }
d5b7b3ae
RE
5448
5449 if (last_bytes)
5450 {
5451 mem = gen_rtx_MEM (QImode, dst);
5452 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5453 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
5454 MEM_SCALAR_P (mem) = dst_scalar_p;
5d5603e2 5455 emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
d5b7b3ae 5456 }
880e2516
RE
5457 }
5458
5459 return 1;
5460}
5461
5165176d
RE
5462/* Generate a memory reference for a half word, such that it will be loaded
5463 into the top 16 bits of the word. We can assume that the address is
5464 known to be alignable and of the form reg, or plus (reg, const). */
1d6e90ac 5465
5165176d 5466rtx
e32bac5b 5467arm_gen_rotated_half_load (rtx memref)
5165176d
RE
5468{
5469 HOST_WIDE_INT offset = 0;
5470 rtx base = XEXP (memref, 0);
5471
5472 if (GET_CODE (base) == PLUS)
5473 {
5474 offset = INTVAL (XEXP (base, 1));
5475 base = XEXP (base, 0);
5476 }
5477
956d6950 5478 /* If we aren't allowed to generate unaligned addresses, then fail. */
5f1e6755 5479 if (TARGET_MMU_TRAPS
5165176d
RE
5480 && ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 0)))
5481 return NULL;
5482
43cffd11 5483 base = gen_rtx_MEM (SImode, plus_constant (base, offset & ~2));
5165176d
RE
5484
5485 if ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 2))
5486 return base;
5487
43cffd11 5488 return gen_rtx_ROTATE (SImode, base, GEN_INT (16));
5165176d
RE
5489}
5490
03f1640c
RE
5491/* Select a dominance comparison mode if possible for a test of the general
5492 form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms.
5493 COND_OR == DOM_CC_X_AND_Y => (X && Y)
5494 COND_OR == DOM_CC_NX_OR_Y => ((! X) || Y)
5495 COND_OR == DOM_CC_X_OR_Y => (X || Y)
5496 In all cases OP will be either EQ or NE, but we don't need to know which
5497 here. If we are unable to support a dominance comparison we return
5498 CC mode. This will then fail to match for the RTL expressions that
5499 generate this call. */
03f1640c 5500enum machine_mode
e32bac5b 5501arm_select_dominance_cc_mode (rtx x, rtx y, HOST_WIDE_INT cond_or)
84ed5e79
RE
5502{
5503 enum rtx_code cond1, cond2;
5504 int swapped = 0;
5505
5506 /* Currently we will probably get the wrong result if the individual
5507 comparisons are not simple. This also ensures that it is safe to
956d6950 5508 reverse a comparison if necessary. */
84ed5e79
RE
5509 if ((arm_select_cc_mode (cond1 = GET_CODE (x), XEXP (x, 0), XEXP (x, 1))
5510 != CCmode)
5511 || (arm_select_cc_mode (cond2 = GET_CODE (y), XEXP (y, 0), XEXP (y, 1))
5512 != CCmode))
5513 return CCmode;
5514
1646cf41
RE
5515 /* The if_then_else variant of this tests the second condition if the
5516 first passes, but is true if the first fails. Reverse the first
5517 condition to get a true "inclusive-or" expression. */
03f1640c 5518 if (cond_or == DOM_CC_NX_OR_Y)
84ed5e79
RE
5519 cond1 = reverse_condition (cond1);
5520
5521 /* If the comparisons are not equal, and one doesn't dominate the other,
5522 then we can't do this. */
5523 if (cond1 != cond2
5895f793
RE
5524 && !comparison_dominates_p (cond1, cond2)
5525 && (swapped = 1, !comparison_dominates_p (cond2, cond1)))
84ed5e79
RE
5526 return CCmode;
5527
5528 if (swapped)
5529 {
5530 enum rtx_code temp = cond1;
5531 cond1 = cond2;
5532 cond2 = temp;
5533 }
5534
5535 switch (cond1)
5536 {
5537 case EQ:
03f1640c 5538 if (cond2 == EQ || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5539 return CC_DEQmode;
5540
5541 switch (cond2)
5542 {
5543 case LE: return CC_DLEmode;
5544 case LEU: return CC_DLEUmode;
5545 case GE: return CC_DGEmode;
5546 case GEU: return CC_DGEUmode;
ad076f4e 5547 default: break;
84ed5e79
RE
5548 }
5549
5550 break;
5551
5552 case LT:
03f1640c 5553 if (cond2 == LT || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5554 return CC_DLTmode;
5555 if (cond2 == LE)
5556 return CC_DLEmode;
5557 if (cond2 == NE)
5558 return CC_DNEmode;
5559 break;
5560
5561 case GT:
03f1640c 5562 if (cond2 == GT || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5563 return CC_DGTmode;
5564 if (cond2 == GE)
5565 return CC_DGEmode;
5566 if (cond2 == NE)
5567 return CC_DNEmode;
5568 break;
5569
5570 case LTU:
03f1640c 5571 if (cond2 == LTU || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5572 return CC_DLTUmode;
5573 if (cond2 == LEU)
5574 return CC_DLEUmode;
5575 if (cond2 == NE)
5576 return CC_DNEmode;
5577 break;
5578
5579 case GTU:
03f1640c 5580 if (cond2 == GTU || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5581 return CC_DGTUmode;
5582 if (cond2 == GEU)
5583 return CC_DGEUmode;
5584 if (cond2 == NE)
5585 return CC_DNEmode;
5586 break;
5587
5588 /* The remaining cases only occur when both comparisons are the
5589 same. */
5590 case NE:
5591 return CC_DNEmode;
5592
5593 case LE:
5594 return CC_DLEmode;
5595
5596 case GE:
5597 return CC_DGEmode;
5598
5599 case LEU:
5600 return CC_DLEUmode;
5601
5602 case GEU:
5603 return CC_DGEUmode;
ad076f4e
RE
5604
5605 default:
5606 break;
84ed5e79
RE
5607 }
5608
5609 abort ();
5610}
5611
5612enum machine_mode
e32bac5b 5613arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
84ed5e79
RE
5614{
5615 /* All floating point compares return CCFP if it is an equality
5616 comparison, and CCFPE otherwise. */
5617 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
e45b72c4
RE
5618 {
5619 switch (op)
5620 {
5621 case EQ:
5622 case NE:
5623 case UNORDERED:
5624 case ORDERED:
5625 case UNLT:
5626 case UNLE:
5627 case UNGT:
5628 case UNGE:
5629 case UNEQ:
5630 case LTGT:
5631 return CCFPmode;
5632
5633 case LT:
5634 case LE:
5635 case GT:
5636 case GE:
9b6b54e2
NC
5637 if (TARGET_CIRRUS)
5638 return CCFPmode;
e45b72c4
RE
5639 return CCFPEmode;
5640
5641 default:
5642 abort ();
5643 }
5644 }
84ed5e79
RE
5645
5646 /* A compare with a shifted operand. Because of canonicalization, the
5647 comparison will have to be swapped when we emit the assembler. */
5648 if (GET_MODE (y) == SImode && GET_CODE (y) == REG
5649 && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
5650 || GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ROTATE
5651 || GET_CODE (x) == ROTATERT))
5652 return CC_SWPmode;
5653
956d6950
JL
5654 /* This is a special case that is used by combine to allow a
5655 comparison of a shifted byte load to be split into a zero-extend
84ed5e79 5656 followed by a comparison of the shifted integer (only valid for
956d6950 5657 equalities and unsigned inequalities). */
84ed5e79
RE
5658 if (GET_MODE (x) == SImode
5659 && GET_CODE (x) == ASHIFT
5660 && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 24
5661 && GET_CODE (XEXP (x, 0)) == SUBREG
5662 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == MEM
5663 && GET_MODE (SUBREG_REG (XEXP (x, 0))) == QImode
5664 && (op == EQ || op == NE
5665 || op == GEU || op == GTU || op == LTU || op == LEU)
5666 && GET_CODE (y) == CONST_INT)
5667 return CC_Zmode;
5668
1646cf41
RE
5669 /* A construct for a conditional compare, if the false arm contains
5670 0, then both conditions must be true, otherwise either condition
5671 must be true. Not all conditions are possible, so CCmode is
5672 returned if it can't be done. */
5673 if (GET_CODE (x) == IF_THEN_ELSE
5674 && (XEXP (x, 2) == const0_rtx
5675 || XEXP (x, 2) == const1_rtx)
5676 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
5677 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
03f1640c
RE
5678 return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
5679 INTVAL (XEXP (x, 2)));
1646cf41
RE
5680
5681 /* Alternate canonicalizations of the above. These are somewhat cleaner. */
5682 if (GET_CODE (x) == AND
5683 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
5684 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
03f1640c
RE
5685 return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
5686 DOM_CC_X_AND_Y);
1646cf41
RE
5687
5688 if (GET_CODE (x) == IOR
5689 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
5690 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
03f1640c
RE
5691 return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
5692 DOM_CC_X_OR_Y);
1646cf41 5693
defc0463
RE
5694 /* An operation (on Thumb) where we want to test for a single bit.
5695 This is done by shifting that bit up into the top bit of a
5696 scratch register; we can then branch on the sign bit. */
5697 if (TARGET_THUMB
5698 && GET_MODE (x) == SImode
5699 && (op == EQ || op == NE)
5700 && (GET_CODE (x) == ZERO_EXTRACT))
5701 return CC_Nmode;
5702
84ed5e79
RE
5703 /* An operation that sets the condition codes as a side-effect, the
5704 V flag is not set correctly, so we can only use comparisons where
5705 this doesn't matter. (For LT and GE we can use "mi" and "pl"
defc0463 5706 instead.) */
84ed5e79
RE
5707 if (GET_MODE (x) == SImode
5708 && y == const0_rtx
5709 && (op == EQ || op == NE || op == LT || op == GE)
5710 && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
5711 || GET_CODE (x) == AND || GET_CODE (x) == IOR
5712 || GET_CODE (x) == XOR || GET_CODE (x) == MULT
5713 || GET_CODE (x) == NOT || GET_CODE (x) == NEG
5714 || GET_CODE (x) == LSHIFTRT
5715 || GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
defc0463
RE
5716 || GET_CODE (x) == ROTATERT
5717 || (TARGET_ARM && GET_CODE (x) == ZERO_EXTRACT)))
84ed5e79
RE
5718 return CC_NOOVmode;
5719
84ed5e79
RE
5720 if (GET_MODE (x) == QImode && (op == EQ || op == NE))
5721 return CC_Zmode;
5722
bd9c7e23
RE
5723 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
5724 && GET_CODE (x) == PLUS
5725 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
5726 return CC_Cmode;
5727
84ed5e79
RE
5728 return CCmode;
5729}
5730
ff9940b0
RE
5731/* X and Y are two things to compare using CODE. Emit the compare insn and
5732 return the rtx for register 0 in the proper mode. FP means this is a
5733 floating point compare: I don't think that it is needed on the arm. */
ff9940b0 5734rtx
e32bac5b 5735arm_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
ff9940b0
RE
5736{
5737 enum machine_mode mode = SELECT_CC_MODE (code, x, y);
d5b7b3ae 5738 rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM);
ff9940b0 5739
43cffd11
RE
5740 emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
5741 gen_rtx_COMPARE (mode, x, y)));
ff9940b0
RE
5742
5743 return cc_reg;
5744}
5745
fcd53748
JT
5746/* Generate a sequence of insns that will generate the correct return
5747 address mask depending on the physical architecture that the program
5748 is running on. */
fcd53748 5749rtx
e32bac5b 5750arm_gen_return_addr_mask (void)
fcd53748
JT
5751{
5752 rtx reg = gen_reg_rtx (Pmode);
5753
5754 emit_insn (gen_return_addr_mask (reg));
5755 return reg;
5756}
5757
0a81f500 5758void
e32bac5b 5759arm_reload_in_hi (rtx *operands)
0a81f500 5760{
f9cc092a
RE
5761 rtx ref = operands[1];
5762 rtx base, scratch;
5763 HOST_WIDE_INT offset = 0;
5764
5765 if (GET_CODE (ref) == SUBREG)
5766 {
ddef6bc7 5767 offset = SUBREG_BYTE (ref);
f9cc092a
RE
5768 ref = SUBREG_REG (ref);
5769 }
5770
5771 if (GET_CODE (ref) == REG)
5772 {
5773 /* We have a pseudo which has been spilt onto the stack; there
5774 are two cases here: the first where there is a simple
5775 stack-slot replacement and a second where the stack-slot is
5776 out of range, or is used as a subreg. */
5777 if (reg_equiv_mem[REGNO (ref)])
5778 {
5779 ref = reg_equiv_mem[REGNO (ref)];
5780 base = find_replacement (&XEXP (ref, 0));
5781 }
5782 else
6354dc9b 5783 /* The slot is out of range, or was dressed up in a SUBREG. */
f9cc092a
RE
5784 base = reg_equiv_address[REGNO (ref)];
5785 }
5786 else
5787 base = find_replacement (&XEXP (ref, 0));
0a81f500 5788
e5e809f4
JL
5789 /* Handle the case where the address is too complex to be offset by 1. */
5790 if (GET_CODE (base) == MINUS
5791 || (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
5792 {
f9cc092a 5793 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
e5e809f4 5794
43cffd11 5795 emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
e5e809f4
JL
5796 base = base_plus;
5797 }
f9cc092a
RE
5798 else if (GET_CODE (base) == PLUS)
5799 {
6354dc9b 5800 /* The addend must be CONST_INT, or we would have dealt with it above. */
f9cc092a
RE
5801 HOST_WIDE_INT hi, lo;
5802
5803 offset += INTVAL (XEXP (base, 1));
5804 base = XEXP (base, 0);
5805
6354dc9b 5806 /* Rework the address into a legal sequence of insns. */
f9cc092a
RE
5807 /* Valid range for lo is -4095 -> 4095 */
5808 lo = (offset >= 0
5809 ? (offset & 0xfff)
5810 : -((-offset) & 0xfff));
5811
5812 /* Corner case, if lo is the max offset then we would be out of range
5813 once we have added the additional 1 below, so bump the msb into the
5814 pre-loading insn(s). */
5815 if (lo == 4095)
5816 lo &= 0x7ff;
5817
30cf4896
KG
5818 hi = ((((offset - lo) & (HOST_WIDE_INT) 0xffffffff)
5819 ^ (HOST_WIDE_INT) 0x80000000)
5820 - (HOST_WIDE_INT) 0x80000000);
f9cc092a
RE
5821
5822 if (hi + lo != offset)
5823 abort ();
5824
5825 if (hi != 0)
5826 {
5827 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5828
5829 /* Get the base address; addsi3 knows how to handle constants
6354dc9b 5830 that require more than one insn. */
f9cc092a
RE
5831 emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
5832 base = base_plus;
5833 offset = lo;
5834 }
5835 }
e5e809f4 5836
3a1944a6
RE
5837 /* Operands[2] may overlap operands[0] (though it won't overlap
5838 operands[1]), that's why we asked for a DImode reg -- so we can
5839 use the bit that does not overlap. */
5840 if (REGNO (operands[2]) == REGNO (operands[0]))
5841 scratch = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5842 else
5843 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5844
f9cc092a
RE
5845 emit_insn (gen_zero_extendqisi2 (scratch,
5846 gen_rtx_MEM (QImode,
5847 plus_constant (base,
5848 offset))));
43cffd11
RE
5849 emit_insn (gen_zero_extendqisi2 (gen_rtx_SUBREG (SImode, operands[0], 0),
5850 gen_rtx_MEM (QImode,
f9cc092a
RE
5851 plus_constant (base,
5852 offset + 1))));
5895f793 5853 if (!BYTES_BIG_ENDIAN)
43cffd11
RE
5854 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
5855 gen_rtx_IOR (SImode,
5856 gen_rtx_ASHIFT
5857 (SImode,
5858 gen_rtx_SUBREG (SImode, operands[0], 0),
5859 GEN_INT (8)),
f9cc092a 5860 scratch)));
0a81f500 5861 else
43cffd11
RE
5862 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
5863 gen_rtx_IOR (SImode,
f9cc092a 5864 gen_rtx_ASHIFT (SImode, scratch,
43cffd11
RE
5865 GEN_INT (8)),
5866 gen_rtx_SUBREG (SImode, operands[0],
5867 0))));
0a81f500
RE
5868}
5869
72ac76be 5870/* Handle storing a half-word to memory during reload by synthesizing as two
f9cc092a
RE
5871 byte stores. Take care not to clobber the input values until after we
5872 have moved them somewhere safe. This code assumes that if the DImode
5873 scratch in operands[2] overlaps either the input value or output address
5874 in some way, then that value must die in this insn (we absolutely need
5875 two scratch registers for some corner cases). */
f3bb6135 5876void
e32bac5b 5877arm_reload_out_hi (rtx *operands)
af48348a 5878{
f9cc092a
RE
5879 rtx ref = operands[0];
5880 rtx outval = operands[1];
5881 rtx base, scratch;
5882 HOST_WIDE_INT offset = 0;
5883
5884 if (GET_CODE (ref) == SUBREG)
5885 {
ddef6bc7 5886 offset = SUBREG_BYTE (ref);
f9cc092a
RE
5887 ref = SUBREG_REG (ref);
5888 }
5889
f9cc092a
RE
5890 if (GET_CODE (ref) == REG)
5891 {
5892 /* We have a pseudo which has been spilt onto the stack; there
5893 are two cases here: the first where there is a simple
5894 stack-slot replacement and a second where the stack-slot is
5895 out of range, or is used as a subreg. */
5896 if (reg_equiv_mem[REGNO (ref)])
5897 {
5898 ref = reg_equiv_mem[REGNO (ref)];
5899 base = find_replacement (&XEXP (ref, 0));
5900 }
5901 else
6354dc9b 5902 /* The slot is out of range, or was dressed up in a SUBREG. */
f9cc092a
RE
5903 base = reg_equiv_address[REGNO (ref)];
5904 }
5905 else
5906 base = find_replacement (&XEXP (ref, 0));
5907
5908 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5909
5910 /* Handle the case where the address is too complex to be offset by 1. */
5911 if (GET_CODE (base) == MINUS
5912 || (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
5913 {
5914 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5915
5916 /* Be careful not to destroy OUTVAL. */
5917 if (reg_overlap_mentioned_p (base_plus, outval))
5918 {
5919 /* Updating base_plus might destroy outval, see if we can
5920 swap the scratch and base_plus. */
5895f793 5921 if (!reg_overlap_mentioned_p (scratch, outval))
f9cc092a
RE
5922 {
5923 rtx tmp = scratch;
5924 scratch = base_plus;
5925 base_plus = tmp;
5926 }
5927 else
5928 {
5929 rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
5930
5931 /* Be conservative and copy OUTVAL into the scratch now,
5932 this should only be necessary if outval is a subreg
5933 of something larger than a word. */
5934 /* XXX Might this clobber base? I can't see how it can,
5935 since scratch is known to overlap with OUTVAL, and
5936 must be wider than a word. */
5937 emit_insn (gen_movhi (scratch_hi, outval));
5938 outval = scratch_hi;
5939 }
5940 }
5941
5942 emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
5943 base = base_plus;
5944 }
5945 else if (GET_CODE (base) == PLUS)
5946 {
6354dc9b 5947 /* The addend must be CONST_INT, or we would have dealt with it above. */
f9cc092a
RE
5948 HOST_WIDE_INT hi, lo;
5949
5950 offset += INTVAL (XEXP (base, 1));
5951 base = XEXP (base, 0);
5952
6354dc9b 5953 /* Rework the address into a legal sequence of insns. */
f9cc092a
RE
5954 /* Valid range for lo is -4095 -> 4095 */
5955 lo = (offset >= 0
5956 ? (offset & 0xfff)
5957 : -((-offset) & 0xfff));
5958
5959 /* Corner case, if lo is the max offset then we would be out of range
5960 once we have added the additional 1 below, so bump the msb into the
5961 pre-loading insn(s). */
5962 if (lo == 4095)
5963 lo &= 0x7ff;
5964
30cf4896
KG
5965 hi = ((((offset - lo) & (HOST_WIDE_INT) 0xffffffff)
5966 ^ (HOST_WIDE_INT) 0x80000000)
5967 - (HOST_WIDE_INT) 0x80000000);
f9cc092a
RE
5968
5969 if (hi + lo != offset)
5970 abort ();
5971
5972 if (hi != 0)
5973 {
5974 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5975
5976 /* Be careful not to destroy OUTVAL. */
5977 if (reg_overlap_mentioned_p (base_plus, outval))
5978 {
5979 /* Updating base_plus might destroy outval, see if we
5980 can swap the scratch and base_plus. */
5895f793 5981 if (!reg_overlap_mentioned_p (scratch, outval))
f9cc092a
RE
5982 {
5983 rtx tmp = scratch;
5984 scratch = base_plus;
5985 base_plus = tmp;
5986 }
5987 else
5988 {
5989 rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
5990
5991 /* Be conservative and copy outval into scratch now,
5992 this should only be necessary if outval is a
5993 subreg of something larger than a word. */
5994 /* XXX Might this clobber base? I can't see how it
5995 can, since scratch is known to overlap with
5996 outval. */
5997 emit_insn (gen_movhi (scratch_hi, outval));
5998 outval = scratch_hi;
5999 }
6000 }
6001
6002 /* Get the base address; addsi3 knows how to handle constants
6354dc9b 6003 that require more than one insn. */
f9cc092a
RE
6004 emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
6005 base = base_plus;
6006 offset = lo;
6007 }
6008 }
af48348a 6009
b5cc037f
RE
6010 if (BYTES_BIG_ENDIAN)
6011 {
f9cc092a
RE
6012 emit_insn (gen_movqi (gen_rtx_MEM (QImode,
6013 plus_constant (base, offset + 1)),
5d5603e2 6014 gen_lowpart (QImode, outval)));
f9cc092a
RE
6015 emit_insn (gen_lshrsi3 (scratch,
6016 gen_rtx_SUBREG (SImode, outval, 0),
b5cc037f 6017 GEN_INT (8)));
f9cc092a 6018 emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
5d5603e2 6019 gen_lowpart (QImode, scratch)));
b5cc037f
RE
6020 }
6021 else
6022 {
f9cc092a 6023 emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
5d5603e2 6024 gen_lowpart (QImode, outval)));
f9cc092a
RE
6025 emit_insn (gen_lshrsi3 (scratch,
6026 gen_rtx_SUBREG (SImode, outval, 0),
b5cc037f 6027 GEN_INT (8)));
f9cc092a
RE
6028 emit_insn (gen_movqi (gen_rtx_MEM (QImode,
6029 plus_constant (base, offset + 1)),
5d5603e2 6030 gen_lowpart (QImode, scratch)));
b5cc037f 6031 }
af48348a 6032}
2b835d68 6033\f
d5b7b3ae
RE
6034/* Print a symbolic form of X to the debug file, F. */
6035static void
e32bac5b 6036arm_print_value (FILE *f, rtx x)
d5b7b3ae
RE
6037{
6038 switch (GET_CODE (x))
6039 {
6040 case CONST_INT:
6041 fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
6042 return;
6043
6044 case CONST_DOUBLE:
6045 fprintf (f, "<0x%lx,0x%lx>", (long)XWINT (x, 2), (long)XWINT (x, 3));
6046 return;
6047
5a9335ef
NC
6048 case CONST_VECTOR:
6049 {
6050 int i;
6051
6052 fprintf (f, "<");
6053 for (i = 0; i < CONST_VECTOR_NUNITS (x); i++)
6054 {
6055 fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (CONST_VECTOR_ELT (x, i)));
6056 if (i < (CONST_VECTOR_NUNITS (x) - 1))
6057 fputc (',', f);
6058 }
6059 fprintf (f, ">");
6060 }
6061 return;
6062
d5b7b3ae
RE
6063 case CONST_STRING:
6064 fprintf (f, "\"%s\"", XSTR (x, 0));
6065 return;
6066
6067 case SYMBOL_REF:
6068 fprintf (f, "`%s'", XSTR (x, 0));
6069 return;
6070
6071 case LABEL_REF:
6072 fprintf (f, "L%d", INSN_UID (XEXP (x, 0)));
6073 return;
6074
6075 case CONST:
6076 arm_print_value (f, XEXP (x, 0));
6077 return;
6078
6079 case PLUS:
6080 arm_print_value (f, XEXP (x, 0));
6081 fprintf (f, "+");
6082 arm_print_value (f, XEXP (x, 1));
6083 return;
6084
6085 case PC:
6086 fprintf (f, "pc");
6087 return;
6088
6089 default:
6090 fprintf (f, "????");
6091 return;
6092 }
6093}
6094\f
2b835d68 6095/* Routines for manipulation of the constant pool. */
2b835d68 6096
949d79eb
RE
6097/* Arm instructions cannot load a large constant directly into a
6098 register; they have to come from a pc relative load. The constant
6099 must therefore be placed in the addressable range of the pc
6100 relative load. Depending on the precise pc relative load
6101 instruction the range is somewhere between 256 bytes and 4k. This
6102 means that we often have to dump a constant inside a function, and
2b835d68
RE
6103 generate code to branch around it.
6104
949d79eb
RE
6105 It is important to minimize this, since the branches will slow
6106 things down and make the code larger.
2b835d68 6107
949d79eb
RE
6108 Normally we can hide the table after an existing unconditional
6109 branch so that there is no interruption of the flow, but in the
6110 worst case the code looks like this:
2b835d68
RE
6111
6112 ldr rn, L1
949d79eb 6113 ...
2b835d68
RE
6114 b L2
6115 align
6116 L1: .long value
6117 L2:
949d79eb 6118 ...
2b835d68 6119
2b835d68 6120 ldr rn, L3
949d79eb 6121 ...
2b835d68
RE
6122 b L4
6123 align
2b835d68
RE
6124 L3: .long value
6125 L4:
949d79eb
RE
6126 ...
6127
6128 We fix this by performing a scan after scheduling, which notices
6129 which instructions need to have their operands fetched from the
6130 constant table and builds the table.
6131
6132 The algorithm starts by building a table of all the constants that
6133 need fixing up and all the natural barriers in the function (places
6134 where a constant table can be dropped without breaking the flow).
6135 For each fixup we note how far the pc-relative replacement will be
6136 able to reach and the offset of the instruction into the function.
6137
6138 Having built the table we then group the fixes together to form
6139 tables that are as large as possible (subject to addressing
6140 constraints) and emit each table of constants after the last
6141 barrier that is within range of all the instructions in the group.
6142 If a group does not contain a barrier, then we forcibly create one
6143 by inserting a jump instruction into the flow. Once the table has
6144 been inserted, the insns are then modified to reference the
6145 relevant entry in the pool.
6146
6354dc9b 6147 Possible enhancements to the algorithm (not implemented) are:
949d79eb 6148
d5b7b3ae 6149 1) For some processors and object formats, there may be benefit in
949d79eb
RE
6150 aligning the pools to the start of cache lines; this alignment
6151 would need to be taken into account when calculating addressability
6354dc9b 6152 of a pool. */
2b835d68 6153
d5b7b3ae
RE
6154/* These typedefs are located at the start of this file, so that
6155 they can be used in the prototypes there. This comment is to
6156 remind readers of that fact so that the following structures
6157 can be understood more easily.
6158
6159 typedef struct minipool_node Mnode;
6160 typedef struct minipool_fixup Mfix; */
6161
6162struct minipool_node
6163{
6164 /* Doubly linked chain of entries. */
6165 Mnode * next;
6166 Mnode * prev;
6167 /* The maximum offset into the code that this entry can be placed. While
6168 pushing fixes for forward references, all entries are sorted in order
6169 of increasing max_address. */
6170 HOST_WIDE_INT max_address;
5519a4f9 6171 /* Similarly for an entry inserted for a backwards ref. */
d5b7b3ae
RE
6172 HOST_WIDE_INT min_address;
6173 /* The number of fixes referencing this entry. This can become zero
6174 if we "unpush" an entry. In this case we ignore the entry when we
6175 come to emit the code. */
6176 int refcount;
6177 /* The offset from the start of the minipool. */
6178 HOST_WIDE_INT offset;
6179 /* The value in table. */
6180 rtx value;
6181 /* The mode of value. */
6182 enum machine_mode mode;
5a9335ef
NC
6183 /* The size of the value. With iWMMXt enabled
6184 sizes > 4 also imply an alignment of 8-bytes. */
d5b7b3ae
RE
6185 int fix_size;
6186};
6187
6188struct minipool_fixup
2b835d68 6189{
d5b7b3ae
RE
6190 Mfix * next;
6191 rtx insn;
6192 HOST_WIDE_INT address;
6193 rtx * loc;
6194 enum machine_mode mode;
6195 int fix_size;
6196 rtx value;
6197 Mnode * minipool;
6198 HOST_WIDE_INT forwards;
6199 HOST_WIDE_INT backwards;
6200};
2b835d68 6201
d5b7b3ae
RE
6202/* Fixes less than a word need padding out to a word boundary. */
6203#define MINIPOOL_FIX_SIZE(mode) \
6204 (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4)
2b835d68 6205
d5b7b3ae
RE
6206static Mnode * minipool_vector_head;
6207static Mnode * minipool_vector_tail;
6208static rtx minipool_vector_label;
332072db 6209
d5b7b3ae
RE
6210/* The linked list of all minipool fixes required for this function. */
6211Mfix * minipool_fix_head;
6212Mfix * minipool_fix_tail;
6213/* The fix entry for the current minipool, once it has been placed. */
6214Mfix * minipool_barrier;
6215
6216/* Determines if INSN is the start of a jump table. Returns the end
6217 of the TABLE or NULL_RTX. */
6218static rtx
e32bac5b 6219is_jump_table (rtx insn)
2b835d68 6220{
d5b7b3ae 6221 rtx table;
da6558fd 6222
d5b7b3ae
RE
6223 if (GET_CODE (insn) == JUMP_INSN
6224 && JUMP_LABEL (insn) != NULL
6225 && ((table = next_real_insn (JUMP_LABEL (insn)))
6226 == next_real_insn (insn))
6227 && table != NULL
6228 && GET_CODE (table) == JUMP_INSN
6229 && (GET_CODE (PATTERN (table)) == ADDR_VEC
6230 || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
6231 return table;
6232
6233 return NULL_RTX;
2b835d68
RE
6234}
6235
657d9449
RE
6236#ifndef JUMP_TABLES_IN_TEXT_SECTION
6237#define JUMP_TABLES_IN_TEXT_SECTION 0
6238#endif
6239
d5b7b3ae 6240static HOST_WIDE_INT
e32bac5b 6241get_jump_table_size (rtx insn)
2b835d68 6242{
657d9449
RE
6243 /* ADDR_VECs only take room if read-only data does into the text
6244 section. */
6245 if (JUMP_TABLES_IN_TEXT_SECTION
d48bc59a 6246#if !defined(READONLY_DATA_SECTION) && !defined(READONLY_DATA_SECTION_ASM_OP)
657d9449
RE
6247 || 1
6248#endif
6249 )
6250 {
6251 rtx body = PATTERN (insn);
6252 int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
2b835d68 6253
657d9449
RE
6254 return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
6255 }
6256
6257 return 0;
d5b7b3ae 6258}
2b835d68 6259
d5b7b3ae
RE
6260/* Move a minipool fix MP from its current location to before MAX_MP.
6261 If MAX_MP is NULL, then MP doesn't need moving, but the addressing
093354e0 6262 constraints may need updating. */
d5b7b3ae 6263static Mnode *
e32bac5b
RE
6264move_minipool_fix_forward_ref (Mnode *mp, Mnode *max_mp,
6265 HOST_WIDE_INT max_address)
d5b7b3ae
RE
6266{
6267 /* This should never be true and the code below assumes these are
6268 different. */
6269 if (mp == max_mp)
6270 abort ();
6271
6272 if (max_mp == NULL)
6273 {
6274 if (max_address < mp->max_address)
6275 mp->max_address = max_address;
6276 }
6277 else
2b835d68 6278 {
d5b7b3ae
RE
6279 if (max_address > max_mp->max_address - mp->fix_size)
6280 mp->max_address = max_mp->max_address - mp->fix_size;
6281 else
6282 mp->max_address = max_address;
2b835d68 6283
d5b7b3ae
RE
6284 /* Unlink MP from its current position. Since max_mp is non-null,
6285 mp->prev must be non-null. */
6286 mp->prev->next = mp->next;
6287 if (mp->next != NULL)
6288 mp->next->prev = mp->prev;
6289 else
6290 minipool_vector_tail = mp->prev;
2b835d68 6291
d5b7b3ae
RE
6292 /* Re-insert it before MAX_MP. */
6293 mp->next = max_mp;
6294 mp->prev = max_mp->prev;
6295 max_mp->prev = mp;
6296
6297 if (mp->prev != NULL)
6298 mp->prev->next = mp;
6299 else
6300 minipool_vector_head = mp;
6301 }
2b835d68 6302
d5b7b3ae
RE
6303 /* Save the new entry. */
6304 max_mp = mp;
6305
d6a7951f 6306 /* Scan over the preceding entries and adjust their addresses as
d5b7b3ae
RE
6307 required. */
6308 while (mp->prev != NULL
6309 && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
6310 {
6311 mp->prev->max_address = mp->max_address - mp->prev->fix_size;
6312 mp = mp->prev;
2b835d68
RE
6313 }
6314
d5b7b3ae 6315 return max_mp;
2b835d68
RE
6316}
6317
d5b7b3ae
RE
6318/* Add a constant to the minipool for a forward reference. Returns the
6319 node added or NULL if the constant will not fit in this pool. */
6320static Mnode *
e32bac5b 6321add_minipool_forward_ref (Mfix *fix)
d5b7b3ae
RE
6322{
6323 /* If set, max_mp is the first pool_entry that has a lower
6324 constraint than the one we are trying to add. */
6325 Mnode * max_mp = NULL;
6326 HOST_WIDE_INT max_address = fix->address + fix->forwards;
6327 Mnode * mp;
6328
6329 /* If this fix's address is greater than the address of the first
6330 entry, then we can't put the fix in this pool. We subtract the
6331 size of the current fix to ensure that if the table is fully
6332 packed we still have enough room to insert this value by suffling
6333 the other fixes forwards. */
6334 if (minipool_vector_head &&
6335 fix->address >= minipool_vector_head->max_address - fix->fix_size)
6336 return NULL;
2b835d68 6337
d5b7b3ae
RE
6338 /* Scan the pool to see if a constant with the same value has
6339 already been added. While we are doing this, also note the
6340 location where we must insert the constant if it doesn't already
6341 exist. */
6342 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
6343 {
6344 if (GET_CODE (fix->value) == GET_CODE (mp->value)
6345 && fix->mode == mp->mode
6346 && (GET_CODE (fix->value) != CODE_LABEL
6347 || (CODE_LABEL_NUMBER (fix->value)
6348 == CODE_LABEL_NUMBER (mp->value)))
6349 && rtx_equal_p (fix->value, mp->value))
6350 {
6351 /* More than one fix references this entry. */
6352 mp->refcount++;
6353 return move_minipool_fix_forward_ref (mp, max_mp, max_address);
6354 }
6355
6356 /* Note the insertion point if necessary. */
6357 if (max_mp == NULL
6358 && mp->max_address > max_address)
6359 max_mp = mp;
5a9335ef
NC
6360
6361 /* If we are inserting an 8-bytes aligned quantity and
6362 we have not already found an insertion point, then
6363 make sure that all such 8-byte aligned quantities are
6364 placed at the start of the pool. */
6365 if (TARGET_REALLY_IWMMXT
6366 && max_mp == NULL
6367 && fix->fix_size == 8
6368 && mp->fix_size != 8)
6369 {
6370 max_mp = mp;
6371 max_address = mp->max_address;
6372 }
d5b7b3ae
RE
6373 }
6374
6375 /* The value is not currently in the minipool, so we need to create
6376 a new entry for it. If MAX_MP is NULL, the entry will be put on
6377 the end of the list since the placement is less constrained than
6378 any existing entry. Otherwise, we insert the new fix before
6bc82793 6379 MAX_MP and, if necessary, adjust the constraints on the other
d5b7b3ae
RE
6380 entries. */
6381 mp = xmalloc (sizeof (* mp));
6382 mp->fix_size = fix->fix_size;
6383 mp->mode = fix->mode;
6384 mp->value = fix->value;
6385 mp->refcount = 1;
6386 /* Not yet required for a backwards ref. */
6387 mp->min_address = -65536;
6388
6389 if (max_mp == NULL)
6390 {
6391 mp->max_address = max_address;
6392 mp->next = NULL;
6393 mp->prev = minipool_vector_tail;
6394
6395 if (mp->prev == NULL)
6396 {
6397 minipool_vector_head = mp;
6398 minipool_vector_label = gen_label_rtx ();
7551cbc7 6399 }
2b835d68 6400 else
d5b7b3ae 6401 mp->prev->next = mp;
2b835d68 6402
d5b7b3ae
RE
6403 minipool_vector_tail = mp;
6404 }
6405 else
6406 {
6407 if (max_address > max_mp->max_address - mp->fix_size)
6408 mp->max_address = max_mp->max_address - mp->fix_size;
6409 else
6410 mp->max_address = max_address;
6411
6412 mp->next = max_mp;
6413 mp->prev = max_mp->prev;
6414 max_mp->prev = mp;
6415 if (mp->prev != NULL)
6416 mp->prev->next = mp;
6417 else
6418 minipool_vector_head = mp;
6419 }
6420
6421 /* Save the new entry. */
6422 max_mp = mp;
6423
d6a7951f 6424 /* Scan over the preceding entries and adjust their addresses as
d5b7b3ae
RE
6425 required. */
6426 while (mp->prev != NULL
6427 && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
6428 {
6429 mp->prev->max_address = mp->max_address - mp->prev->fix_size;
6430 mp = mp->prev;
2b835d68
RE
6431 }
6432
d5b7b3ae
RE
6433 return max_mp;
6434}
6435
6436static Mnode *
e32bac5b
RE
6437move_minipool_fix_backward_ref (Mnode *mp, Mnode *min_mp,
6438 HOST_WIDE_INT min_address)
d5b7b3ae
RE
6439{
6440 HOST_WIDE_INT offset;
6441
6442 /* This should never be true, and the code below assumes these are
6443 different. */
6444 if (mp == min_mp)
6445 abort ();
6446
6447 if (min_mp == NULL)
2b835d68 6448 {
d5b7b3ae
RE
6449 if (min_address > mp->min_address)
6450 mp->min_address = min_address;
6451 }
6452 else
6453 {
6454 /* We will adjust this below if it is too loose. */
6455 mp->min_address = min_address;
6456
6457 /* Unlink MP from its current position. Since min_mp is non-null,
6458 mp->next must be non-null. */
6459 mp->next->prev = mp->prev;
6460 if (mp->prev != NULL)
6461 mp->prev->next = mp->next;
6462 else
6463 minipool_vector_head = mp->next;
6464
6465 /* Reinsert it after MIN_MP. */
6466 mp->prev = min_mp;
6467 mp->next = min_mp->next;
6468 min_mp->next = mp;
6469 if (mp->next != NULL)
6470 mp->next->prev = mp;
2b835d68 6471 else
d5b7b3ae
RE
6472 minipool_vector_tail = mp;
6473 }
6474
6475 min_mp = mp;
6476
6477 offset = 0;
6478 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
6479 {
6480 mp->offset = offset;
6481 if (mp->refcount > 0)
6482 offset += mp->fix_size;
6483
6484 if (mp->next && mp->next->min_address < mp->min_address + mp->fix_size)
6485 mp->next->min_address = mp->min_address + mp->fix_size;
6486 }
6487
6488 return min_mp;
6489}
6490
6491/* Add a constant to the minipool for a backward reference. Returns the
6492 node added or NULL if the constant will not fit in this pool.
6493
6494 Note that the code for insertion for a backwards reference can be
6495 somewhat confusing because the calculated offsets for each fix do
6496 not take into account the size of the pool (which is still under
6497 construction. */
6498static Mnode *
e32bac5b 6499add_minipool_backward_ref (Mfix *fix)
d5b7b3ae
RE
6500{
6501 /* If set, min_mp is the last pool_entry that has a lower constraint
6502 than the one we are trying to add. */
e32bac5b 6503 Mnode *min_mp = NULL;
d5b7b3ae
RE
6504 /* This can be negative, since it is only a constraint. */
6505 HOST_WIDE_INT min_address = fix->address - fix->backwards;
e32bac5b 6506 Mnode *mp;
d5b7b3ae
RE
6507
6508 /* If we can't reach the current pool from this insn, or if we can't
6509 insert this entry at the end of the pool without pushing other
6510 fixes out of range, then we don't try. This ensures that we
6511 can't fail later on. */
6512 if (min_address >= minipool_barrier->address
6513 || (minipool_vector_tail->min_address + fix->fix_size
6514 >= minipool_barrier->address))
6515 return NULL;
6516
6517 /* Scan the pool to see if a constant with the same value has
6518 already been added. While we are doing this, also note the
6519 location where we must insert the constant if it doesn't already
6520 exist. */
6521 for (mp = minipool_vector_tail; mp != NULL; mp = mp->prev)
6522 {
6523 if (GET_CODE (fix->value) == GET_CODE (mp->value)
6524 && fix->mode == mp->mode
6525 && (GET_CODE (fix->value) != CODE_LABEL
6526 || (CODE_LABEL_NUMBER (fix->value)
6527 == CODE_LABEL_NUMBER (mp->value)))
6528 && rtx_equal_p (fix->value, mp->value)
6529 /* Check that there is enough slack to move this entry to the
6530 end of the table (this is conservative). */
6531 && (mp->max_address
6532 > (minipool_barrier->address
6533 + minipool_vector_tail->offset
6534 + minipool_vector_tail->fix_size)))
6535 {
6536 mp->refcount++;
6537 return move_minipool_fix_backward_ref (mp, min_mp, min_address);
6538 }
6539
6540 if (min_mp != NULL)
6541 mp->min_address += fix->fix_size;
6542 else
6543 {
6544 /* Note the insertion point if necessary. */
6545 if (mp->min_address < min_address)
5a9335ef
NC
6546 {
6547 /* For now, we do not allow the insertion of 8-byte alignment
6548 requiring nodes anywhere but at the start of the pool. */
6549 if (TARGET_REALLY_IWMMXT && fix->fix_size == 8 && mp->fix_size != 8)
6550 return NULL;
6551 else
6552 min_mp = mp;
6553 }
d5b7b3ae
RE
6554 else if (mp->max_address
6555 < minipool_barrier->address + mp->offset + fix->fix_size)
6556 {
6557 /* Inserting before this entry would push the fix beyond
6558 its maximum address (which can happen if we have
6559 re-located a forwards fix); force the new fix to come
6560 after it. */
6561 min_mp = mp;
6562 min_address = mp->min_address + fix->fix_size;
6563 }
5a9335ef
NC
6564 /* If we are inserting an 8-bytes aligned quantity and
6565 we have not already found an insertion point, then
6566 make sure that all such 8-byte aligned quantities are
6567 placed at the start of the pool. */
6568 else if (TARGET_REALLY_IWMMXT
6569 && min_mp == NULL
6570 && fix->fix_size == 8
6571 && mp->fix_size < 8)
6572 {
6573 min_mp = mp;
6574 min_address = mp->min_address + fix->fix_size;
6575 }
d5b7b3ae
RE
6576 }
6577 }
6578
6579 /* We need to create a new entry. */
6580 mp = xmalloc (sizeof (* mp));
6581 mp->fix_size = fix->fix_size;
6582 mp->mode = fix->mode;
6583 mp->value = fix->value;
6584 mp->refcount = 1;
6585 mp->max_address = minipool_barrier->address + 65536;
6586
6587 mp->min_address = min_address;
6588
6589 if (min_mp == NULL)
6590 {
6591 mp->prev = NULL;
6592 mp->next = minipool_vector_head;
6593
6594 if (mp->next == NULL)
6595 {
6596 minipool_vector_tail = mp;
6597 minipool_vector_label = gen_label_rtx ();
6598 }
6599 else
6600 mp->next->prev = mp;
6601
6602 minipool_vector_head = mp;
6603 }
6604 else
6605 {
6606 mp->next = min_mp->next;
6607 mp->prev = min_mp;
6608 min_mp->next = mp;
da6558fd 6609
d5b7b3ae
RE
6610 if (mp->next != NULL)
6611 mp->next->prev = mp;
6612 else
6613 minipool_vector_tail = mp;
6614 }
6615
6616 /* Save the new entry. */
6617 min_mp = mp;
6618
6619 if (mp->prev)
6620 mp = mp->prev;
6621 else
6622 mp->offset = 0;
6623
6624 /* Scan over the following entries and adjust their offsets. */
6625 while (mp->next != NULL)
6626 {
6627 if (mp->next->min_address < mp->min_address + mp->fix_size)
6628 mp->next->min_address = mp->min_address + mp->fix_size;
6629
6630 if (mp->refcount)
6631 mp->next->offset = mp->offset + mp->fix_size;
6632 else
6633 mp->next->offset = mp->offset;
6634
6635 mp = mp->next;
6636 }
6637
6638 return min_mp;
6639}
6640
6641static void
e32bac5b 6642assign_minipool_offsets (Mfix *barrier)
d5b7b3ae
RE
6643{
6644 HOST_WIDE_INT offset = 0;
e32bac5b 6645 Mnode *mp;
d5b7b3ae
RE
6646
6647 minipool_barrier = barrier;
6648
6649 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
6650 {
6651 mp->offset = offset;
da6558fd 6652
d5b7b3ae
RE
6653 if (mp->refcount > 0)
6654 offset += mp->fix_size;
6655 }
6656}
6657
6658/* Output the literal table */
6659static void
e32bac5b 6660dump_minipool (rtx scan)
d5b7b3ae 6661{
5a9335ef
NC
6662 Mnode * mp;
6663 Mnode * nmp;
6664 int align64 = 0;
6665
6666 if (TARGET_REALLY_IWMMXT)
6667 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
6668 if (mp->refcount > 0 && mp->fix_size == 8)
6669 {
6670 align64 = 1;
6671 break;
6672 }
d5b7b3ae
RE
6673
6674 if (rtl_dump_file)
6675 fprintf (rtl_dump_file,
5a9335ef
NC
6676 ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n",
6677 INSN_UID (scan), (unsigned long) minipool_barrier->address, align64 ? 8 : 4);
d5b7b3ae
RE
6678
6679 scan = emit_label_after (gen_label_rtx (), scan);
5a9335ef 6680 scan = emit_insn_after (align64 ? gen_align_8 () : gen_align_4 (), scan);
d5b7b3ae
RE
6681 scan = emit_label_after (minipool_vector_label, scan);
6682
6683 for (mp = minipool_vector_head; mp != NULL; mp = nmp)
6684 {
6685 if (mp->refcount > 0)
6686 {
6687 if (rtl_dump_file)
6688 {
6689 fprintf (rtl_dump_file,
6690 ";; Offset %u, min %ld, max %ld ",
6691 (unsigned) mp->offset, (unsigned long) mp->min_address,
6692 (unsigned long) mp->max_address);
6693 arm_print_value (rtl_dump_file, mp->value);
6694 fputc ('\n', rtl_dump_file);
6695 }
6696
6697 switch (mp->fix_size)
6698 {
6699#ifdef HAVE_consttable_1
6700 case 1:
6701 scan = emit_insn_after (gen_consttable_1 (mp->value), scan);
6702 break;
6703
6704#endif
6705#ifdef HAVE_consttable_2
6706 case 2:
6707 scan = emit_insn_after (gen_consttable_2 (mp->value), scan);
6708 break;
6709
6710#endif
6711#ifdef HAVE_consttable_4
6712 case 4:
6713 scan = emit_insn_after (gen_consttable_4 (mp->value), scan);
6714 break;
6715
6716#endif
6717#ifdef HAVE_consttable_8
6718 case 8:
6719 scan = emit_insn_after (gen_consttable_8 (mp->value), scan);
6720 break;
6721
6722#endif
6723 default:
6724 abort ();
6725 break;
6726 }
6727 }
6728
6729 nmp = mp->next;
6730 free (mp);
2b835d68
RE
6731 }
6732
d5b7b3ae
RE
6733 minipool_vector_head = minipool_vector_tail = NULL;
6734 scan = emit_insn_after (gen_consttable_end (), scan);
6735 scan = emit_barrier_after (scan);
2b835d68
RE
6736}
6737
d5b7b3ae
RE
6738/* Return the cost of forcibly inserting a barrier after INSN. */
6739static int
e32bac5b 6740arm_barrier_cost (rtx insn)
949d79eb 6741{
d5b7b3ae
RE
6742 /* Basing the location of the pool on the loop depth is preferable,
6743 but at the moment, the basic block information seems to be
6744 corrupt by this stage of the compilation. */
6745 int base_cost = 50;
6746 rtx next = next_nonnote_insn (insn);
6747
6748 if (next != NULL && GET_CODE (next) == CODE_LABEL)
6749 base_cost -= 20;
6750
6751 switch (GET_CODE (insn))
6752 {
6753 case CODE_LABEL:
6754 /* It will always be better to place the table before the label, rather
6755 than after it. */
6756 return 50;
949d79eb 6757
d5b7b3ae
RE
6758 case INSN:
6759 case CALL_INSN:
6760 return base_cost;
6761
6762 case JUMP_INSN:
6763 return base_cost - 10;
6764
6765 default:
6766 return base_cost + 10;
6767 }
6768}
6769
6770/* Find the best place in the insn stream in the range
6771 (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
6772 Create the barrier by inserting a jump and add a new fix entry for
6773 it. */
6774static Mfix *
e32bac5b 6775create_fix_barrier (Mfix *fix, HOST_WIDE_INT max_address)
d5b7b3ae
RE
6776{
6777 HOST_WIDE_INT count = 0;
6778 rtx barrier;
6779 rtx from = fix->insn;
6780 rtx selected = from;
6781 int selected_cost;
6782 HOST_WIDE_INT selected_address;
6783 Mfix * new_fix;
6784 HOST_WIDE_INT max_count = max_address - fix->address;
6785 rtx label = gen_label_rtx ();
6786
6787 selected_cost = arm_barrier_cost (from);
6788 selected_address = fix->address;
6789
6790 while (from && count < max_count)
6791 {
6792 rtx tmp;
6793 int new_cost;
6794
6795 /* This code shouldn't have been called if there was a natural barrier
6796 within range. */
6797 if (GET_CODE (from) == BARRIER)
6798 abort ();
6799
6800 /* Count the length of this insn. */
6801 count += get_attr_length (from);
6802
6803 /* If there is a jump table, add its length. */
6804 tmp = is_jump_table (from);
6805 if (tmp != NULL)
6806 {
6807 count += get_jump_table_size (tmp);
6808
6809 /* Jump tables aren't in a basic block, so base the cost on
6810 the dispatch insn. If we select this location, we will
6811 still put the pool after the table. */
6812 new_cost = arm_barrier_cost (from);
6813
6814 if (count < max_count && new_cost <= selected_cost)
6815 {
6816 selected = tmp;
6817 selected_cost = new_cost;
6818 selected_address = fix->address + count;
6819 }
6820
6821 /* Continue after the dispatch table. */
6822 from = NEXT_INSN (tmp);
6823 continue;
6824 }
6825
6826 new_cost = arm_barrier_cost (from);
6827
6828 if (count < max_count && new_cost <= selected_cost)
6829 {
6830 selected = from;
6831 selected_cost = new_cost;
6832 selected_address = fix->address + count;
6833 }
6834
6835 from = NEXT_INSN (from);
6836 }
6837
6838 /* Create a new JUMP_INSN that branches around a barrier. */
6839 from = emit_jump_insn_after (gen_jump (label), selected);
6840 JUMP_LABEL (from) = label;
6841 barrier = emit_barrier_after (from);
6842 emit_label_after (label, barrier);
6843
6844 /* Create a minipool barrier entry for the new barrier. */
c7319d87 6845 new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* new_fix));
d5b7b3ae
RE
6846 new_fix->insn = barrier;
6847 new_fix->address = selected_address;
6848 new_fix->next = fix->next;
6849 fix->next = new_fix;
6850
6851 return new_fix;
6852}
6853
6854/* Record that there is a natural barrier in the insn stream at
6855 ADDRESS. */
949d79eb 6856static void
e32bac5b 6857push_minipool_barrier (rtx insn, HOST_WIDE_INT address)
2b835d68 6858{
c7319d87 6859 Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
ad076f4e 6860
949d79eb
RE
6861 fix->insn = insn;
6862 fix->address = address;
2b835d68 6863
949d79eb
RE
6864 fix->next = NULL;
6865 if (minipool_fix_head != NULL)
6866 minipool_fix_tail->next = fix;
6867 else
6868 minipool_fix_head = fix;
6869
6870 minipool_fix_tail = fix;
6871}
2b835d68 6872
d5b7b3ae
RE
6873/* Record INSN, which will need fixing up to load a value from the
6874 minipool. ADDRESS is the offset of the insn since the start of the
6875 function; LOC is a pointer to the part of the insn which requires
6876 fixing; VALUE is the constant that must be loaded, which is of type
6877 MODE. */
949d79eb 6878static void
e32bac5b
RE
6879push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx *loc,
6880 enum machine_mode mode, rtx value)
949d79eb 6881{
c7319d87 6882 Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
949d79eb
RE
6883
6884#ifdef AOF_ASSEMBLER
093354e0 6885 /* PIC symbol references need to be converted into offsets into the
949d79eb 6886 based area. */
d5b7b3ae
RE
6887 /* XXX This shouldn't be done here. */
6888 if (flag_pic && GET_CODE (value) == SYMBOL_REF)
949d79eb
RE
6889 value = aof_pic_entry (value);
6890#endif /* AOF_ASSEMBLER */
6891
6892 fix->insn = insn;
6893 fix->address = address;
6894 fix->loc = loc;
6895 fix->mode = mode;
d5b7b3ae 6896 fix->fix_size = MINIPOOL_FIX_SIZE (mode);
949d79eb 6897 fix->value = value;
d5b7b3ae
RE
6898 fix->forwards = get_attr_pool_range (insn);
6899 fix->backwards = get_attr_neg_pool_range (insn);
6900 fix->minipool = NULL;
949d79eb
RE
6901
6902 /* If an insn doesn't have a range defined for it, then it isn't
6903 expecting to be reworked by this code. Better to abort now than
6904 to generate duff assembly code. */
d5b7b3ae 6905 if (fix->forwards == 0 && fix->backwards == 0)
949d79eb
RE
6906 abort ();
6907
5a9335ef
NC
6908 /* With iWMMXt enabled, the pool is aligned to an 8-byte boundary.
6909 So there might be an empty word before the start of the pool.
6910 Hence we reduce the forward range by 4 to allow for this
6911 possibility. */
6912 if (TARGET_REALLY_IWMMXT && fix->fix_size == 8)
6913 fix->forwards -= 4;
6914
d5b7b3ae
RE
6915 if (rtl_dump_file)
6916 {
6917 fprintf (rtl_dump_file,
6918 ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ",
6919 GET_MODE_NAME (mode),
6920 INSN_UID (insn), (unsigned long) address,
6921 -1 * (long)fix->backwards, (long)fix->forwards);
6922 arm_print_value (rtl_dump_file, fix->value);
6923 fprintf (rtl_dump_file, "\n");
6924 }
6925
6354dc9b 6926 /* Add it to the chain of fixes. */
949d79eb 6927 fix->next = NULL;
d5b7b3ae 6928
949d79eb
RE
6929 if (minipool_fix_head != NULL)
6930 minipool_fix_tail->next = fix;
6931 else
6932 minipool_fix_head = fix;
6933
6934 minipool_fix_tail = fix;
6935}
6936
f0375c66
NC
6937/* Scan INSN and note any of its operands that need fixing.
6938 If DO_PUSHES is false we do not actually push any of the fixups
6939 needed. The function returns TRUE is any fixups were needed/pushed.
6940 This is used by arm_memory_load_p() which needs to know about loads
6941 of constants that will be converted into minipool loads. */
f0375c66 6942static bool
e32bac5b 6943note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
949d79eb 6944{
f0375c66 6945 bool result = false;
949d79eb
RE
6946 int opno;
6947
d5b7b3ae 6948 extract_insn (insn);
949d79eb 6949
5895f793 6950 if (!constrain_operands (1))
949d79eb
RE
6951 fatal_insn_not_found (insn);
6952
8c2a5582
RE
6953 if (recog_data.n_alternatives == 0)
6954 return false;
6955
f0375c66 6956 /* Fill in recog_op_alt with information about the constraints of this insn. */
949d79eb
RE
6957 preprocess_constraints ();
6958
1ccbefce 6959 for (opno = 0; opno < recog_data.n_operands; opno++)
949d79eb 6960 {
6354dc9b 6961 /* Things we need to fix can only occur in inputs. */
36ab44c7 6962 if (recog_data.operand_type[opno] != OP_IN)
949d79eb
RE
6963 continue;
6964
6965 /* If this alternative is a memory reference, then any mention
6966 of constants in this alternative is really to fool reload
6967 into allowing us to accept one there. We need to fix them up
6968 now so that we output the right code. */
6969 if (recog_op_alt[opno][which_alternative].memory_ok)
6970 {
1ccbefce 6971 rtx op = recog_data.operand[opno];
949d79eb
RE
6972
6973 if (CONSTANT_P (op))
f0375c66
NC
6974 {
6975 if (do_pushes)
6976 push_minipool_fix (insn, address, recog_data.operand_loc[opno],
6977 recog_data.operand_mode[opno], op);
6978 result = true;
6979 }
d5b7b3ae 6980 else if (GET_CODE (op) == MEM
949d79eb
RE
6981 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
6982 && CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
f0375c66
NC
6983 {
6984 if (do_pushes)
244b1afb
RE
6985 {
6986 rtx cop = avoid_constant_pool_reference (op);
6987
6988 /* Casting the address of something to a mode narrower
6989 than a word can cause avoid_constant_pool_reference()
6990 to return the pool reference itself. That's no good to
6991 us here. Lets just hope that we can use the
6992 constant pool value directly. */
6993 if (op == cop)
c769a35d 6994 cop = get_pool_constant (XEXP (op, 0));
244b1afb
RE
6995
6996 push_minipool_fix (insn, address,
6997 recog_data.operand_loc[opno],
c769a35d 6998 recog_data.operand_mode[opno], cop);
244b1afb 6999 }
f0375c66
NC
7000
7001 result = true;
7002 }
949d79eb 7003 }
2b835d68 7004 }
f0375c66
NC
7005
7006 return result;
2b835d68
RE
7007}
7008
18dbd950
RS
7009/* Gcc puts the pool in the wrong place for ARM, since we can only
7010 load addresses a limited distance around the pc. We do some
7011 special munging to move the constant pool values to the correct
7012 point in the code. */
18dbd950 7013static void
e32bac5b 7014arm_reorg (void)
2b835d68
RE
7015{
7016 rtx insn;
d5b7b3ae
RE
7017 HOST_WIDE_INT address = 0;
7018 Mfix * fix;
ad076f4e 7019
949d79eb 7020 minipool_fix_head = minipool_fix_tail = NULL;
2b835d68 7021
949d79eb
RE
7022 /* The first insn must always be a note, or the code below won't
7023 scan it properly. */
18dbd950
RS
7024 insn = get_insns ();
7025 if (GET_CODE (insn) != NOTE)
949d79eb
RE
7026 abort ();
7027
7028 /* Scan all the insns and record the operands that will need fixing. */
18dbd950 7029 for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn))
2b835d68 7030 {
9b6b54e2 7031 if (TARGET_CIRRUS_FIX_INVALID_INSNS
f0375c66 7032 && (arm_cirrus_insn_p (insn)
9b6b54e2 7033 || GET_CODE (insn) == JUMP_INSN
f0375c66 7034 || arm_memory_load_p (insn)))
9b6b54e2
NC
7035 cirrus_reorg (insn);
7036
949d79eb 7037 if (GET_CODE (insn) == BARRIER)
d5b7b3ae 7038 push_minipool_barrier (insn, address);
f0375c66 7039 else if (INSN_P (insn))
949d79eb
RE
7040 {
7041 rtx table;
7042
f0375c66 7043 note_invalid_constants (insn, address, true);
949d79eb 7044 address += get_attr_length (insn);
d5b7b3ae 7045
949d79eb
RE
7046 /* If the insn is a vector jump, add the size of the table
7047 and skip the table. */
d5b7b3ae 7048 if ((table = is_jump_table (insn)) != NULL)
2b835d68 7049 {
d5b7b3ae 7050 address += get_jump_table_size (table);
949d79eb
RE
7051 insn = table;
7052 }
7053 }
7054 }
332072db 7055
d5b7b3ae
RE
7056 fix = minipool_fix_head;
7057
949d79eb 7058 /* Now scan the fixups and perform the required changes. */
d5b7b3ae 7059 while (fix)
949d79eb 7060 {
d5b7b3ae
RE
7061 Mfix * ftmp;
7062 Mfix * fdel;
7063 Mfix * last_added_fix;
7064 Mfix * last_barrier = NULL;
7065 Mfix * this_fix;
949d79eb
RE
7066
7067 /* Skip any further barriers before the next fix. */
7068 while (fix && GET_CODE (fix->insn) == BARRIER)
7069 fix = fix->next;
7070
d5b7b3ae 7071 /* No more fixes. */
949d79eb
RE
7072 if (fix == NULL)
7073 break;
332072db 7074
d5b7b3ae 7075 last_added_fix = NULL;
2b835d68 7076
d5b7b3ae 7077 for (ftmp = fix; ftmp; ftmp = ftmp->next)
949d79eb 7078 {
949d79eb 7079 if (GET_CODE (ftmp->insn) == BARRIER)
949d79eb 7080 {
d5b7b3ae
RE
7081 if (ftmp->address >= minipool_vector_head->max_address)
7082 break;
2b835d68 7083
d5b7b3ae 7084 last_barrier = ftmp;
2b835d68 7085 }
d5b7b3ae
RE
7086 else if ((ftmp->minipool = add_minipool_forward_ref (ftmp)) == NULL)
7087 break;
7088
7089 last_added_fix = ftmp; /* Keep track of the last fix added. */
2b835d68 7090 }
949d79eb 7091
d5b7b3ae
RE
7092 /* If we found a barrier, drop back to that; any fixes that we
7093 could have reached but come after the barrier will now go in
7094 the next mini-pool. */
949d79eb
RE
7095 if (last_barrier != NULL)
7096 {
d5b7b3ae
RE
7097 /* Reduce the refcount for those fixes that won't go into this
7098 pool after all. */
7099 for (fdel = last_barrier->next;
7100 fdel && fdel != ftmp;
7101 fdel = fdel->next)
7102 {
7103 fdel->minipool->refcount--;
7104 fdel->minipool = NULL;
7105 }
7106
949d79eb
RE
7107 ftmp = last_barrier;
7108 }
7109 else
2bfa88dc 7110 {
d5b7b3ae
RE
7111 /* ftmp is first fix that we can't fit into this pool and
7112 there no natural barriers that we could use. Insert a
7113 new barrier in the code somewhere between the previous
7114 fix and this one, and arrange to jump around it. */
7115 HOST_WIDE_INT max_address;
7116
7117 /* The last item on the list of fixes must be a barrier, so
7118 we can never run off the end of the list of fixes without
7119 last_barrier being set. */
7120 if (ftmp == NULL)
7121 abort ();
7122
7123 max_address = minipool_vector_head->max_address;
2bfa88dc
RE
7124 /* Check that there isn't another fix that is in range that
7125 we couldn't fit into this pool because the pool was
7126 already too large: we need to put the pool before such an
7127 instruction. */
d5b7b3ae
RE
7128 if (ftmp->address < max_address)
7129 max_address = ftmp->address;
7130
7131 last_barrier = create_fix_barrier (last_added_fix, max_address);
7132 }
7133
7134 assign_minipool_offsets (last_barrier);
7135
7136 while (ftmp)
7137 {
7138 if (GET_CODE (ftmp->insn) != BARRIER
7139 && ((ftmp->minipool = add_minipool_backward_ref (ftmp))
7140 == NULL))
7141 break;
2bfa88dc 7142
d5b7b3ae 7143 ftmp = ftmp->next;
2bfa88dc 7144 }
949d79eb
RE
7145
7146 /* Scan over the fixes we have identified for this pool, fixing them
7147 up and adding the constants to the pool itself. */
d5b7b3ae 7148 for (this_fix = fix; this_fix && ftmp != this_fix;
949d79eb
RE
7149 this_fix = this_fix->next)
7150 if (GET_CODE (this_fix->insn) != BARRIER)
7151 {
949d79eb
RE
7152 rtx addr
7153 = plus_constant (gen_rtx_LABEL_REF (VOIDmode,
7154 minipool_vector_label),
d5b7b3ae 7155 this_fix->minipool->offset);
949d79eb
RE
7156 *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr);
7157 }
7158
d5b7b3ae 7159 dump_minipool (last_barrier->insn);
949d79eb 7160 fix = ftmp;
2b835d68 7161 }
4b632bf1 7162
949d79eb
RE
7163 /* From now on we must synthesize any constants that we can't handle
7164 directly. This can happen if the RTL gets split during final
7165 instruction generation. */
4b632bf1 7166 after_arm_reorg = 1;
c7319d87
RE
7167
7168 /* Free the minipool memory. */
7169 obstack_free (&minipool_obstack, minipool_startobj);
2b835d68 7170}
cce8749e
CH
7171\f
7172/* Routines to output assembly language. */
7173
f3bb6135 7174/* If the rtx is the correct value then return the string of the number.
ff9940b0 7175 In this way we can ensure that valid double constants are generated even
6354dc9b 7176 when cross compiling. */
cd2b33d0 7177const char *
e32bac5b 7178fp_immediate_constant (rtx x)
ff9940b0
RE
7179{
7180 REAL_VALUE_TYPE r;
7181 int i;
7182
7183 if (!fpa_consts_inited)
7184 init_fpa_table ();
7185
7186 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
7187 for (i = 0; i < 8; i++)
7188 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
7189 return strings_fpa[i];
f3bb6135 7190
ff9940b0
RE
7191 abort ();
7192}
7193
9997d19d 7194/* As for fp_immediate_constant, but value is passed directly, not in rtx. */
cd2b33d0 7195static const char *
e32bac5b 7196fp_const_from_val (REAL_VALUE_TYPE *r)
9997d19d
RE
7197{
7198 int i;
7199
5895f793 7200 if (!fpa_consts_inited)
9997d19d
RE
7201 init_fpa_table ();
7202
7203 for (i = 0; i < 8; i++)
7204 if (REAL_VALUES_EQUAL (*r, values_fpa[i]))
7205 return strings_fpa[i];
7206
7207 abort ();
7208}
ff9940b0 7209
cce8749e
CH
7210/* Output the operands of a LDM/STM instruction to STREAM.
7211 MASK is the ARM register set mask of which only bits 0-15 are important.
6d3d9133
NC
7212 REG is the base register, either the frame pointer or the stack pointer,
7213 INSTR is the possibly suffixed load or store instruction. */
d5b7b3ae 7214static void
e32bac5b 7215print_multi_reg (FILE *stream, const char *instr, int reg, int mask)
cce8749e
CH
7216{
7217 int i;
7218 int not_first = FALSE;
7219
1d5473cb 7220 fputc ('\t', stream);
dd18ae56 7221 asm_fprintf (stream, instr, reg);
1d5473cb 7222 fputs (", {", stream);
62b10bbc 7223
d5b7b3ae 7224 for (i = 0; i <= LAST_ARM_REGNUM; i++)
cce8749e
CH
7225 if (mask & (1 << i))
7226 {
7227 if (not_first)
7228 fprintf (stream, ", ");
62b10bbc 7229
dd18ae56 7230 asm_fprintf (stream, "%r", i);
cce8749e
CH
7231 not_first = TRUE;
7232 }
f3bb6135 7233
b17fe233
NC
7234 fprintf (stream, "}");
7235
7236 /* Add a ^ character for the 26-bit ABI, but only if we were loading
1ce53769
NC
7237 the PC. Otherwise we would generate an UNPREDICTABLE instruction.
7238 Strictly speaking the instruction would be unpredicatble only if
7239 we were writing back the base register as well, but since we never
7240 want to generate an LDM type 2 instruction (register bank switching)
7241 which is what you get if the PC is not being loaded, we do not need
7242 to check for writeback. */
b17fe233 7243 if (! TARGET_APCS_32
1ce53769 7244 && ((mask & (1 << PC_REGNUM)) != 0))
b17fe233
NC
7245 fprintf (stream, "^");
7246
7247 fprintf (stream, "\n");
f3bb6135 7248}
cce8749e 7249
6354dc9b 7250/* Output a 'call' insn. */
cd2b33d0 7251const char *
e32bac5b 7252output_call (rtx *operands)
cce8749e 7253{
6354dc9b 7254 /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
cce8749e 7255
62b10bbc 7256 if (REGNO (operands[0]) == LR_REGNUM)
cce8749e 7257 {
62b10bbc 7258 operands[0] = gen_rtx_REG (SImode, IP_REGNUM);
1d5473cb 7259 output_asm_insn ("mov%?\t%0, %|lr", operands);
cce8749e 7260 }
62b10bbc 7261
1d5473cb 7262 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
da6558fd 7263
6cfc7210 7264 if (TARGET_INTERWORK)
da6558fd
NC
7265 output_asm_insn ("bx%?\t%0", operands);
7266 else
7267 output_asm_insn ("mov%?\t%|pc, %0", operands);
7268
f3bb6135
RE
7269 return "";
7270}
cce8749e 7271
6354dc9b 7272/* Output a 'call' insn that is a reference in memory. */
cd2b33d0 7273const char *
e32bac5b 7274output_call_mem (rtx *operands)
ff9940b0 7275{
6cfc7210 7276 if (TARGET_INTERWORK)
da6558fd
NC
7277 {
7278 output_asm_insn ("ldr%?\t%|ip, %0", operands);
7279 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
7280 output_asm_insn ("bx%?\t%|ip", operands);
7281 }
6ab5da80
RE
7282 else if (regno_use_in (LR_REGNUM, operands[0]))
7283 {
7284 /* LR is used in the memory address. We load the address in the
7285 first instruction. It's safe to use IP as the target of the
7286 load since the call will kill it anyway. */
7287 output_asm_insn ("ldr%?\t%|ip, %0", operands);
7288 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
7289 output_asm_insn ("mov%?\t%|pc, %|ip", operands);
7290 }
da6558fd
NC
7291 else
7292 {
7293 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
7294 output_asm_insn ("ldr%?\t%|pc, %0", operands);
7295 }
7296
f3bb6135
RE
7297 return "";
7298}
ff9940b0
RE
7299
7300
3b684012
RE
7301/* Output a move from arm registers to an fpa registers.
7302 OPERANDS[0] is an fpa register.
ff9940b0 7303 OPERANDS[1] is the first registers of an arm register pair. */
cd2b33d0 7304const char *
e32bac5b 7305output_mov_long_double_fpa_from_arm (rtx *operands)
ff9940b0
RE
7306{
7307 int arm_reg0 = REGNO (operands[1]);
7308 rtx ops[3];
7309
62b10bbc
NC
7310 if (arm_reg0 == IP_REGNUM)
7311 abort ();
f3bb6135 7312
43cffd11
RE
7313 ops[0] = gen_rtx_REG (SImode, arm_reg0);
7314 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
7315 ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
ff9940b0 7316
1d5473cb
RE
7317 output_asm_insn ("stm%?fd\t%|sp!, {%0, %1, %2}", ops);
7318 output_asm_insn ("ldf%?e\t%0, [%|sp], #12", operands);
62b10bbc 7319
f3bb6135
RE
7320 return "";
7321}
ff9940b0 7322
3b684012 7323/* Output a move from an fpa register to arm registers.
ff9940b0 7324 OPERANDS[0] is the first registers of an arm register pair.
3b684012 7325 OPERANDS[1] is an fpa register. */
cd2b33d0 7326const char *
e32bac5b 7327output_mov_long_double_arm_from_fpa (rtx *operands)
ff9940b0
RE
7328{
7329 int arm_reg0 = REGNO (operands[0]);
7330 rtx ops[3];
7331
62b10bbc
NC
7332 if (arm_reg0 == IP_REGNUM)
7333 abort ();
f3bb6135 7334
43cffd11
RE
7335 ops[0] = gen_rtx_REG (SImode, arm_reg0);
7336 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
7337 ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
ff9940b0 7338
1d5473cb
RE
7339 output_asm_insn ("stf%?e\t%1, [%|sp, #-12]!", operands);
7340 output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1, %2}", ops);
f3bb6135
RE
7341 return "";
7342}
ff9940b0
RE
7343
7344/* Output a move from arm registers to arm registers of a long double
7345 OPERANDS[0] is the destination.
7346 OPERANDS[1] is the source. */
cd2b33d0 7347const char *
e32bac5b 7348output_mov_long_double_arm_from_arm (rtx *operands)
ff9940b0 7349{
6354dc9b 7350 /* We have to be careful here because the two might overlap. */
ff9940b0
RE
7351 int dest_start = REGNO (operands[0]);
7352 int src_start = REGNO (operands[1]);
7353 rtx ops[2];
7354 int i;
7355
7356 if (dest_start < src_start)
7357 {
7358 for (i = 0; i < 3; i++)
7359 {
43cffd11
RE
7360 ops[0] = gen_rtx_REG (SImode, dest_start + i);
7361 ops[1] = gen_rtx_REG (SImode, src_start + i);
9997d19d 7362 output_asm_insn ("mov%?\t%0, %1", ops);
ff9940b0
RE
7363 }
7364 }
7365 else
7366 {
7367 for (i = 2; i >= 0; i--)
7368 {
43cffd11
RE
7369 ops[0] = gen_rtx_REG (SImode, dest_start + i);
7370 ops[1] = gen_rtx_REG (SImode, src_start + i);
9997d19d 7371 output_asm_insn ("mov%?\t%0, %1", ops);
ff9940b0
RE
7372 }
7373 }
f3bb6135 7374
ff9940b0
RE
7375 return "";
7376}
7377
7378
3b684012
RE
7379/* Output a move from arm registers to an fpa registers.
7380 OPERANDS[0] is an fpa register.
cce8749e 7381 OPERANDS[1] is the first registers of an arm register pair. */
cd2b33d0 7382const char *
e32bac5b 7383output_mov_double_fpa_from_arm (rtx *operands)
cce8749e
CH
7384{
7385 int arm_reg0 = REGNO (operands[1]);
7386 rtx ops[2];
7387
62b10bbc
NC
7388 if (arm_reg0 == IP_REGNUM)
7389 abort ();
7390
43cffd11
RE
7391 ops[0] = gen_rtx_REG (SImode, arm_reg0);
7392 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
1d5473cb
RE
7393 output_asm_insn ("stm%?fd\t%|sp!, {%0, %1}", ops);
7394 output_asm_insn ("ldf%?d\t%0, [%|sp], #8", operands);
f3bb6135
RE
7395 return "";
7396}
cce8749e 7397
3b684012 7398/* Output a move from an fpa register to arm registers.
cce8749e 7399 OPERANDS[0] is the first registers of an arm register pair.
3b684012 7400 OPERANDS[1] is an fpa register. */
cd2b33d0 7401const char *
e32bac5b 7402output_mov_double_arm_from_fpa (rtx *operands)
cce8749e
CH
7403{
7404 int arm_reg0 = REGNO (operands[0]);
7405 rtx ops[2];
7406
62b10bbc
NC
7407 if (arm_reg0 == IP_REGNUM)
7408 abort ();
f3bb6135 7409
43cffd11
RE
7410 ops[0] = gen_rtx_REG (SImode, arm_reg0);
7411 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
1d5473cb
RE
7412 output_asm_insn ("stf%?d\t%1, [%|sp, #-8]!", operands);
7413 output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1}", ops);
f3bb6135
RE
7414 return "";
7415}
cce8749e
CH
7416
7417/* Output a move between double words.
7418 It must be REG<-REG, REG<-CONST_DOUBLE, REG<-CONST_INT, REG<-MEM
7419 or MEM<-REG and all MEMs must be offsettable addresses. */
cd2b33d0 7420const char *
e32bac5b 7421output_move_double (rtx *operands)
cce8749e
CH
7422{
7423 enum rtx_code code0 = GET_CODE (operands[0]);
7424 enum rtx_code code1 = GET_CODE (operands[1]);
56636818 7425 rtx otherops[3];
cce8749e
CH
7426
7427 if (code0 == REG)
7428 {
7429 int reg0 = REGNO (operands[0]);
7430
43cffd11 7431 otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
aec3cfba 7432
cce8749e
CH
7433 if (code1 == REG)
7434 {
7435 int reg1 = REGNO (operands[1]);
62b10bbc
NC
7436 if (reg1 == IP_REGNUM)
7437 abort ();
f3bb6135 7438
6354dc9b 7439 /* Ensure the second source is not overwritten. */
c1c2bc04 7440 if (reg1 == reg0 + (WORDS_BIG_ENDIAN ? -1 : 1))
6cfc7210 7441 output_asm_insn ("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands);
cce8749e 7442 else
6cfc7210 7443 output_asm_insn ("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
cce8749e 7444 }
5a9335ef
NC
7445 else if (code1 == CONST_VECTOR)
7446 {
7447 HOST_WIDE_INT hint = 0;
7448
7449 switch (GET_MODE (operands[1]))
7450 {
7451 case V2SImode:
7452 otherops[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 1)));
7453 operands[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)));
7454 break;
7455
7456 case V4HImode:
7457 if (BYTES_BIG_ENDIAN)
7458 {
7459 hint = INTVAL (CONST_VECTOR_ELT (operands[1], 2));
7460 hint <<= 16;
7461 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
7462 }
7463 else
7464 {
7465 hint = INTVAL (CONST_VECTOR_ELT (operands[1], 3));
7466 hint <<= 16;
7467 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
7468 }
7469
7470 otherops[1] = GEN_INT (hint);
7471 hint = 0;
7472
7473 if (BYTES_BIG_ENDIAN)
7474 {
7475 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
7476 hint <<= 16;
7477 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
7478 }
7479 else
7480 {
7481 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
7482 hint <<= 16;
7483 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
7484 }
7485
7486 operands[1] = GEN_INT (hint);
7487 break;
7488
7489 case V8QImode:
7490 if (BYTES_BIG_ENDIAN)
7491 {
7492 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4));
7493 hint <<= 8;
7494 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5));
7495 hint <<= 8;
7496 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6));
7497 hint <<= 8;
7498 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7));
7499 }
7500 else
7501 {
7502 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7));
7503 hint <<= 8;
7504 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6));
7505 hint <<= 8;
7506 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5));
7507 hint <<= 8;
7508 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4));
7509 }
7510
7511 otherops[1] = GEN_INT (hint);
7512 hint = 0;
7513
7514 if (BYTES_BIG_ENDIAN)
7515 {
7516 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
7517 hint <<= 8;
7518 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
7519 hint <<= 8;
7520 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
7521 hint <<= 8;
7522 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
7523 }
7524 else
7525 {
7526 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
7527 hint <<= 8;
7528 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
7529 hint <<= 8;
7530 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
7531 hint <<= 8;
7532 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
7533 }
7534
7535 operands[1] = GEN_INT (hint);
7536 break;
7537
7538 default:
7539 abort ();
7540 }
7541 output_mov_immediate (operands);
7542 output_mov_immediate (otherops);
7543 }
cce8749e
CH
7544 else if (code1 == CONST_DOUBLE)
7545 {
226a5051
RE
7546 if (GET_MODE (operands[1]) == DFmode)
7547 {
b216cd4a 7548 REAL_VALUE_TYPE r;
226a5051 7549 long l[2];
226a5051 7550
b216cd4a
ZW
7551 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
7552 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
d5b7b3ae
RE
7553 otherops[1] = GEN_INT (l[1]);
7554 operands[1] = GEN_INT (l[0]);
226a5051 7555 }
c1c2bc04
RE
7556 else if (GET_MODE (operands[1]) != VOIDmode)
7557 abort ();
7558 else if (WORDS_BIG_ENDIAN)
7559 {
c1c2bc04
RE
7560 otherops[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
7561 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
7562 }
226a5051
RE
7563 else
7564 {
7565 otherops[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
7566 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
7567 }
6cfc7210 7568
c1c2bc04
RE
7569 output_mov_immediate (operands);
7570 output_mov_immediate (otherops);
cce8749e
CH
7571 }
7572 else if (code1 == CONST_INT)
7573 {
56636818
JL
7574#if HOST_BITS_PER_WIDE_INT > 32
7575 /* If HOST_WIDE_INT is more than 32 bits, the intval tells us
7576 what the upper word is. */
7577 if (WORDS_BIG_ENDIAN)
7578 {
7579 otherops[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
7580 operands[1] = GEN_INT (INTVAL (operands[1]) >> 32);
7581 }
7582 else
7583 {
7584 otherops[1] = GEN_INT (INTVAL (operands[1]) >> 32);
7585 operands[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
7586 }
7587#else
6354dc9b 7588 /* Sign extend the intval into the high-order word. */
c1c2bc04
RE
7589 if (WORDS_BIG_ENDIAN)
7590 {
7591 otherops[1] = operands[1];
7592 operands[1] = (INTVAL (operands[1]) < 0
7593 ? constm1_rtx : const0_rtx);
7594 }
ff9940b0 7595 else
c1c2bc04 7596 otherops[1] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
56636818 7597#endif
c1c2bc04
RE
7598 output_mov_immediate (otherops);
7599 output_mov_immediate (operands);
cce8749e
CH
7600 }
7601 else if (code1 == MEM)
7602 {
ff9940b0 7603 switch (GET_CODE (XEXP (operands[1], 0)))
cce8749e 7604 {
ff9940b0 7605 case REG:
9997d19d 7606 output_asm_insn ("ldm%?ia\t%m1, %M0", operands);
ff9940b0 7607 break;
2b835d68 7608
ff9940b0 7609 case PRE_INC:
6354dc9b 7610 abort (); /* Should never happen now. */
ff9940b0 7611 break;
2b835d68 7612
ff9940b0 7613 case PRE_DEC:
2b835d68 7614 output_asm_insn ("ldm%?db\t%m1!, %M0", operands);
ff9940b0 7615 break;
2b835d68 7616
ff9940b0 7617 case POST_INC:
9997d19d 7618 output_asm_insn ("ldm%?ia\t%m1!, %M0", operands);
ff9940b0 7619 break;
2b835d68 7620
ff9940b0 7621 case POST_DEC:
6354dc9b 7622 abort (); /* Should never happen now. */
ff9940b0 7623 break;
2b835d68
RE
7624
7625 case LABEL_REF:
7626 case CONST:
7627 output_asm_insn ("adr%?\t%0, %1", operands);
7628 output_asm_insn ("ldm%?ia\t%0, %M0", operands);
7629 break;
7630
ff9940b0 7631 default:
aec3cfba
NC
7632 if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1),
7633 GET_MODE (XEXP (XEXP (operands[1], 0), 1))))
cce8749e 7634 {
2b835d68
RE
7635 otherops[0] = operands[0];
7636 otherops[1] = XEXP (XEXP (operands[1], 0), 0);
7637 otherops[2] = XEXP (XEXP (operands[1], 0), 1);
1d6e90ac 7638
2b835d68
RE
7639 if (GET_CODE (XEXP (operands[1], 0)) == PLUS)
7640 {
7641 if (GET_CODE (otherops[2]) == CONST_INT)
7642 {
06bea5aa 7643 switch ((int) INTVAL (otherops[2]))
2b835d68
RE
7644 {
7645 case -8:
7646 output_asm_insn ("ldm%?db\t%1, %M0", otherops);
7647 return "";
7648 case -4:
7649 output_asm_insn ("ldm%?da\t%1, %M0", otherops);
7650 return "";
7651 case 4:
7652 output_asm_insn ("ldm%?ib\t%1, %M0", otherops);
7653 return "";
7654 }
1d6e90ac 7655
2b835d68
RE
7656 if (!(const_ok_for_arm (INTVAL (otherops[2]))))
7657 output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
7658 else
7659 output_asm_insn ("add%?\t%0, %1, %2", otherops);
7660 }
7661 else
7662 output_asm_insn ("add%?\t%0, %1, %2", otherops);
7663 }
7664 else
7665 output_asm_insn ("sub%?\t%0, %1, %2", otherops);
6cfc7210 7666
2b835d68
RE
7667 return "ldm%?ia\t%0, %M0";
7668 }
7669 else
7670 {
a4a37b30 7671 otherops[1] = adjust_address (operands[1], SImode, 4);
2b835d68
RE
7672 /* Take care of overlapping base/data reg. */
7673 if (reg_mentioned_p (operands[0], operands[1]))
7674 {
7675 output_asm_insn ("ldr%?\t%0, %1", otherops);
7676 output_asm_insn ("ldr%?\t%0, %1", operands);
7677 }
7678 else
7679 {
7680 output_asm_insn ("ldr%?\t%0, %1", operands);
7681 output_asm_insn ("ldr%?\t%0, %1", otherops);
7682 }
cce8749e
CH
7683 }
7684 }
7685 }
2b835d68 7686 else
6354dc9b 7687 abort (); /* Constraints should prevent this. */
cce8749e
CH
7688 }
7689 else if (code0 == MEM && code1 == REG)
7690 {
62b10bbc
NC
7691 if (REGNO (operands[1]) == IP_REGNUM)
7692 abort ();
2b835d68 7693
ff9940b0
RE
7694 switch (GET_CODE (XEXP (operands[0], 0)))
7695 {
7696 case REG:
9997d19d 7697 output_asm_insn ("stm%?ia\t%m0, %M1", operands);
ff9940b0 7698 break;
2b835d68 7699
ff9940b0 7700 case PRE_INC:
6354dc9b 7701 abort (); /* Should never happen now. */
ff9940b0 7702 break;
2b835d68 7703
ff9940b0 7704 case PRE_DEC:
2b835d68 7705 output_asm_insn ("stm%?db\t%m0!, %M1", operands);
ff9940b0 7706 break;
2b835d68 7707
ff9940b0 7708 case POST_INC:
9997d19d 7709 output_asm_insn ("stm%?ia\t%m0!, %M1", operands);
ff9940b0 7710 break;
2b835d68 7711
ff9940b0 7712 case POST_DEC:
6354dc9b 7713 abort (); /* Should never happen now. */
ff9940b0 7714 break;
2b835d68
RE
7715
7716 case PLUS:
7717 if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
7718 {
06bea5aa 7719 switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
2b835d68
RE
7720 {
7721 case -8:
7722 output_asm_insn ("stm%?db\t%m0, %M1", operands);
7723 return "";
7724
7725 case -4:
7726 output_asm_insn ("stm%?da\t%m0, %M1", operands);
7727 return "";
7728
7729 case 4:
7730 output_asm_insn ("stm%?ib\t%m0, %M1", operands);
7731 return "";
7732 }
7733 }
7734 /* Fall through */
7735
ff9940b0 7736 default:
a4a37b30 7737 otherops[0] = adjust_address (operands[0], SImode, 4);
43cffd11 7738 otherops[1] = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
9997d19d
RE
7739 output_asm_insn ("str%?\t%1, %0", operands);
7740 output_asm_insn ("str%?\t%1, %0", otherops);
cce8749e
CH
7741 }
7742 }
2b835d68 7743 else
1d6e90ac
NC
7744 /* Constraints should prevent this. */
7745 abort ();
cce8749e 7746
9997d19d
RE
7747 return "";
7748}
cce8749e
CH
7749
7750
7751/* Output an arbitrary MOV reg, #n.
7752 OPERANDS[0] is a register. OPERANDS[1] is a const_int. */
cd2b33d0 7753const char *
e32bac5b 7754output_mov_immediate (rtx *operands)
cce8749e 7755{
f3bb6135 7756 HOST_WIDE_INT n = INTVAL (operands[1]);
cce8749e 7757
1d6e90ac 7758 /* Try to use one MOV. */
cce8749e 7759 if (const_ok_for_arm (n))
1d6e90ac 7760 output_asm_insn ("mov%?\t%0, %1", operands);
cce8749e 7761
1d6e90ac
NC
7762 /* Try to use one MVN. */
7763 else if (const_ok_for_arm (~n))
cce8749e 7764 {
f3bb6135 7765 operands[1] = GEN_INT (~n);
9997d19d 7766 output_asm_insn ("mvn%?\t%0, %1", operands);
cce8749e 7767 }
1d6e90ac
NC
7768 else
7769 {
7770 int n_ones = 0;
7771 int i;
cce8749e 7772
1d6e90ac 7773 /* If all else fails, make it out of ORRs or BICs as appropriate. */
5a9335ef 7774 for (i = 0; i < 32; i++)
1d6e90ac 7775 if (n & 1 << i)
5a9335ef 7776 n_ones++;
cce8749e 7777
1d6e90ac
NC
7778 if (n_ones > 16) /* Shorter to use MVN with BIC in this case. */
7779 output_multi_immediate (operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1, ~ n);
7780 else
7781 output_multi_immediate (operands, "mov%?\t%0, %1", "orr%?\t%0, %0, %1", 1, n);
7782 }
f3bb6135
RE
7783
7784 return "";
7785}
cce8749e 7786
1d6e90ac
NC
7787/* Output an ADD r, s, #n where n may be too big for one instruction.
7788 If adding zero to one register, output nothing. */
cd2b33d0 7789const char *
e32bac5b 7790output_add_immediate (rtx *operands)
cce8749e 7791{
f3bb6135 7792 HOST_WIDE_INT n = INTVAL (operands[2]);
cce8749e
CH
7793
7794 if (n != 0 || REGNO (operands[0]) != REGNO (operands[1]))
7795 {
7796 if (n < 0)
7797 output_multi_immediate (operands,
9997d19d
RE
7798 "sub%?\t%0, %1, %2", "sub%?\t%0, %0, %2", 2,
7799 -n);
cce8749e
CH
7800 else
7801 output_multi_immediate (operands,
9997d19d
RE
7802 "add%?\t%0, %1, %2", "add%?\t%0, %0, %2", 2,
7803 n);
cce8749e 7804 }
f3bb6135
RE
7805
7806 return "";
7807}
cce8749e 7808
cce8749e
CH
7809/* Output a multiple immediate operation.
7810 OPERANDS is the vector of operands referred to in the output patterns.
7811 INSTR1 is the output pattern to use for the first constant.
7812 INSTR2 is the output pattern to use for subsequent constants.
7813 IMMED_OP is the index of the constant slot in OPERANDS.
7814 N is the constant value. */
cd2b33d0 7815static const char *
e32bac5b
RE
7816output_multi_immediate (rtx *operands, const char *instr1, const char *instr2,
7817 int immed_op, HOST_WIDE_INT n)
cce8749e 7818{
f3bb6135 7819#if HOST_BITS_PER_WIDE_INT > 32
30cf4896 7820 n &= 0xffffffff;
f3bb6135
RE
7821#endif
7822
cce8749e
CH
7823 if (n == 0)
7824 {
1d6e90ac 7825 /* Quick and easy output. */
cce8749e 7826 operands[immed_op] = const0_rtx;
1d6e90ac 7827 output_asm_insn (instr1, operands);
cce8749e
CH
7828 }
7829 else
7830 {
7831 int i;
cd2b33d0 7832 const char * instr = instr1;
cce8749e 7833
6354dc9b 7834 /* Note that n is never zero here (which would give no output). */
cce8749e
CH
7835 for (i = 0; i < 32; i += 2)
7836 {
7837 if (n & (3 << i))
7838 {
f3bb6135
RE
7839 operands[immed_op] = GEN_INT (n & (255 << i));
7840 output_asm_insn (instr, operands);
cce8749e
CH
7841 instr = instr2;
7842 i += 6;
7843 }
7844 }
7845 }
cd2b33d0 7846
f3bb6135 7847 return "";
9997d19d 7848}
cce8749e 7849
cce8749e
CH
7850/* Return the appropriate ARM instruction for the operation code.
7851 The returned result should not be overwritten. OP is the rtx of the
7852 operation. SHIFT_FIRST_ARG is TRUE if the first argument of the operator
7853 was shifted. */
cd2b33d0 7854const char *
e32bac5b 7855arithmetic_instr (rtx op, int shift_first_arg)
cce8749e 7856{
9997d19d 7857 switch (GET_CODE (op))
cce8749e
CH
7858 {
7859 case PLUS:
f3bb6135
RE
7860 return "add";
7861
cce8749e 7862 case MINUS:
f3bb6135
RE
7863 return shift_first_arg ? "rsb" : "sub";
7864
cce8749e 7865 case IOR:
f3bb6135
RE
7866 return "orr";
7867
cce8749e 7868 case XOR:
f3bb6135
RE
7869 return "eor";
7870
cce8749e 7871 case AND:
f3bb6135
RE
7872 return "and";
7873
cce8749e 7874 default:
f3bb6135 7875 abort ();
cce8749e 7876 }
f3bb6135 7877}
cce8749e 7878
cce8749e
CH
7879/* Ensure valid constant shifts and return the appropriate shift mnemonic
7880 for the operation code. The returned result should not be overwritten.
7881 OP is the rtx code of the shift.
9997d19d 7882 On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
6354dc9b 7883 shift. */
cd2b33d0 7884static const char *
e32bac5b 7885shift_op (rtx op, HOST_WIDE_INT *amountp)
cce8749e 7886{
cd2b33d0 7887 const char * mnem;
e2c671ba 7888 enum rtx_code code = GET_CODE (op);
cce8749e 7889
9997d19d
RE
7890 if (GET_CODE (XEXP (op, 1)) == REG || GET_CODE (XEXP (op, 1)) == SUBREG)
7891 *amountp = -1;
7892 else if (GET_CODE (XEXP (op, 1)) == CONST_INT)
7893 *amountp = INTVAL (XEXP (op, 1));
7894 else
7895 abort ();
7896
e2c671ba 7897 switch (code)
cce8749e
CH
7898 {
7899 case ASHIFT:
7900 mnem = "asl";
7901 break;
f3bb6135 7902
cce8749e
CH
7903 case ASHIFTRT:
7904 mnem = "asr";
cce8749e 7905 break;
f3bb6135 7906
cce8749e
CH
7907 case LSHIFTRT:
7908 mnem = "lsr";
cce8749e 7909 break;
f3bb6135 7910
9997d19d
RE
7911 case ROTATERT:
7912 mnem = "ror";
9997d19d
RE
7913 break;
7914
ff9940b0 7915 case MULT:
e2c671ba
RE
7916 /* We never have to worry about the amount being other than a
7917 power of 2, since this case can never be reloaded from a reg. */
9997d19d
RE
7918 if (*amountp != -1)
7919 *amountp = int_log2 (*amountp);
7920 else
7921 abort ();
f3bb6135
RE
7922 return "asl";
7923
cce8749e 7924 default:
f3bb6135 7925 abort ();
cce8749e
CH
7926 }
7927
e2c671ba
RE
7928 if (*amountp != -1)
7929 {
7930 /* This is not 100% correct, but follows from the desire to merge
7931 multiplication by a power of 2 with the recognizer for a
7932 shift. >=32 is not a valid shift for "asl", so we must try and
7933 output a shift that produces the correct arithmetical result.
ddd5a7c1 7934 Using lsr #32 is identical except for the fact that the carry bit
e2c671ba
RE
7935 is not set correctly if we set the flags; but we never use the
7936 carry bit from such an operation, so we can ignore that. */
7937 if (code == ROTATERT)
1d6e90ac
NC
7938 /* Rotate is just modulo 32. */
7939 *amountp &= 31;
e2c671ba
RE
7940 else if (*amountp != (*amountp & 31))
7941 {
7942 if (code == ASHIFT)
7943 mnem = "lsr";
7944 *amountp = 32;
7945 }
7946
7947 /* Shifts of 0 are no-ops. */
7948 if (*amountp == 0)
7949 return NULL;
7950 }
7951
9997d19d
RE
7952 return mnem;
7953}
cce8749e 7954
6354dc9b 7955/* Obtain the shift from the POWER of two. */
1d6e90ac 7956
18af7313 7957static HOST_WIDE_INT
e32bac5b 7958int_log2 (HOST_WIDE_INT power)
cce8749e 7959{
f3bb6135 7960 HOST_WIDE_INT shift = 0;
cce8749e 7961
30cf4896 7962 while ((((HOST_WIDE_INT) 1 << shift) & power) == 0)
cce8749e
CH
7963 {
7964 if (shift > 31)
f3bb6135 7965 abort ();
e32bac5b 7966 shift++;
cce8749e 7967 }
f3bb6135
RE
7968
7969 return shift;
7970}
cce8749e 7971
cce8749e
CH
7972/* Output a .ascii pseudo-op, keeping track of lengths. This is because
7973 /bin/as is horribly restrictive. */
6cfc7210 7974#define MAX_ASCII_LEN 51
cce8749e
CH
7975
7976void
e32bac5b 7977output_ascii_pseudo_op (FILE *stream, const unsigned char *p, int len)
cce8749e
CH
7978{
7979 int i;
6cfc7210 7980 int len_so_far = 0;
cce8749e 7981
6cfc7210
NC
7982 fputs ("\t.ascii\t\"", stream);
7983
cce8749e
CH
7984 for (i = 0; i < len; i++)
7985 {
1d6e90ac 7986 int c = p[i];
cce8749e 7987
6cfc7210 7988 if (len_so_far >= MAX_ASCII_LEN)
cce8749e 7989 {
6cfc7210 7990 fputs ("\"\n\t.ascii\t\"", stream);
cce8749e 7991 len_so_far = 0;
cce8749e
CH
7992 }
7993
6cfc7210 7994 switch (c)
cce8749e 7995 {
6cfc7210
NC
7996 case TARGET_TAB:
7997 fputs ("\\t", stream);
7998 len_so_far += 2;
7999 break;
8000
8001 case TARGET_FF:
8002 fputs ("\\f", stream);
8003 len_so_far += 2;
8004 break;
8005
8006 case TARGET_BS:
8007 fputs ("\\b", stream);
8008 len_so_far += 2;
8009 break;
8010
8011 case TARGET_CR:
8012 fputs ("\\r", stream);
8013 len_so_far += 2;
8014 break;
8015
8016 case TARGET_NEWLINE:
8017 fputs ("\\n", stream);
8018 c = p [i + 1];
8019 if ((c >= ' ' && c <= '~')
8020 || c == TARGET_TAB)
8021 /* This is a good place for a line break. */
8022 len_so_far = MAX_ASCII_LEN;
8023 else
8024 len_so_far += 2;
8025 break;
8026
8027 case '\"':
8028 case '\\':
8029 putc ('\\', stream);
5895f793 8030 len_so_far++;
6cfc7210 8031 /* drop through. */
f3bb6135 8032
6cfc7210
NC
8033 default:
8034 if (c >= ' ' && c <= '~')
8035 {
8036 putc (c, stream);
5895f793 8037 len_so_far++;
6cfc7210
NC
8038 }
8039 else
8040 {
8041 fprintf (stream, "\\%03o", c);
8042 len_so_far += 4;
8043 }
8044 break;
cce8749e 8045 }
cce8749e 8046 }
f3bb6135 8047
cce8749e 8048 fputs ("\"\n", stream);
f3bb6135 8049}
cce8749e 8050\f
121308d4
NC
8051/* Compute the register sabe mask for registers 0 through 12
8052 inclusive. This code is used by both arm_compute_save_reg_mask
8053 and arm_compute_initial_elimination_offset. */
6d3d9133 8054static unsigned long
e32bac5b 8055arm_compute_save_reg0_reg12_mask (void)
6d3d9133 8056{
121308d4 8057 unsigned long func_type = arm_current_func_type ();
6d3d9133
NC
8058 unsigned int save_reg_mask = 0;
8059 unsigned int reg;
6d3d9133 8060
7b8b8ade 8061 if (IS_INTERRUPT (func_type))
6d3d9133 8062 {
7b8b8ade 8063 unsigned int max_reg;
7b8b8ade
NC
8064 /* Interrupt functions must not corrupt any registers,
8065 even call clobbered ones. If this is a leaf function
8066 we can just examine the registers used by the RTL, but
8067 otherwise we have to assume that whatever function is
8068 called might clobber anything, and so we have to save
8069 all the call-clobbered registers as well. */
8070 if (ARM_FUNC_TYPE (func_type) == ARM_FT_FIQ)
8071 /* FIQ handlers have registers r8 - r12 banked, so
8072 we only need to check r0 - r7, Normal ISRs only
121308d4 8073 bank r14 and r15, so we must check up to r12.
7b8b8ade
NC
8074 r13 is the stack pointer which is always preserved,
8075 so we do not need to consider it here. */
8076 max_reg = 7;
8077 else
8078 max_reg = 12;
8079
8080 for (reg = 0; reg <= max_reg; reg++)
8081 if (regs_ever_live[reg]
8082 || (! current_function_is_leaf && call_used_regs [reg]))
6d3d9133
NC
8083 save_reg_mask |= (1 << reg);
8084 }
8085 else
8086 {
8087 /* In the normal case we only need to save those registers
8088 which are call saved and which are used by this function. */
8089 for (reg = 0; reg <= 10; reg++)
8090 if (regs_ever_live[reg] && ! call_used_regs [reg])
8091 save_reg_mask |= (1 << reg);
8092
8093 /* Handle the frame pointer as a special case. */
8094 if (! TARGET_APCS_FRAME
8095 && ! frame_pointer_needed
8096 && regs_ever_live[HARD_FRAME_POINTER_REGNUM]
8097 && ! call_used_regs[HARD_FRAME_POINTER_REGNUM])
8098 save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM;
8099
8100 /* If we aren't loading the PIC register,
8101 don't stack it even though it may be live. */
8102 if (flag_pic
8103 && ! TARGET_SINGLE_PIC_BASE
8104 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
8105 save_reg_mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
8106 }
8107
121308d4
NC
8108 return save_reg_mask;
8109}
8110
8111/* Compute a bit mask of which registers need to be
8112 saved on the stack for the current function. */
8113
8114static unsigned long
e32bac5b 8115arm_compute_save_reg_mask (void)
121308d4
NC
8116{
8117 unsigned int save_reg_mask = 0;
8118 unsigned long func_type = arm_current_func_type ();
8119
8120 if (IS_NAKED (func_type))
8121 /* This should never really happen. */
8122 return 0;
8123
8124 /* If we are creating a stack frame, then we must save the frame pointer,
8125 IP (which will hold the old stack pointer), LR and the PC. */
8126 if (frame_pointer_needed)
8127 save_reg_mask |=
8128 (1 << ARM_HARD_FRAME_POINTER_REGNUM)
8129 | (1 << IP_REGNUM)
8130 | (1 << LR_REGNUM)
8131 | (1 << PC_REGNUM);
8132
8133 /* Volatile functions do not return, so there
8134 is no need to save any other registers. */
8135 if (IS_VOLATILE (func_type))
8136 return save_reg_mask;
8137
8138 save_reg_mask |= arm_compute_save_reg0_reg12_mask ();
8139
6d3d9133
NC
8140 /* Decide if we need to save the link register.
8141 Interrupt routines have their own banked link register,
8142 so they never need to save it.
1768c26f 8143 Otherwise if we do not use the link register we do not need to save
6d3d9133
NC
8144 it. If we are pushing other registers onto the stack however, we
8145 can save an instruction in the epilogue by pushing the link register
8146 now and then popping it back into the PC. This incurs extra memory
72ac76be 8147 accesses though, so we only do it when optimizing for size, and only
6d3d9133 8148 if we know that we will not need a fancy return sequence. */
3a7731fd 8149 if (regs_ever_live [LR_REGNUM]
6d3d9133
NC
8150 || (save_reg_mask
8151 && optimize_size
3a7731fd 8152 && ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL))
6d3d9133
NC
8153 save_reg_mask |= 1 << LR_REGNUM;
8154
6f7ebcbb
NC
8155 if (cfun->machine->lr_save_eliminated)
8156 save_reg_mask &= ~ (1 << LR_REGNUM);
8157
5a9335ef
NC
8158 if (TARGET_REALLY_IWMMXT
8159 && ((bit_count (save_reg_mask)
8160 + ARM_NUM_INTS (current_function_pretend_args_size)) % 2) != 0)
8161 {
8162 unsigned int reg;
8163
8164 /* The total number of registers that are going to be pushed
8165 onto the stack is odd. We need to ensure that the stack
8166 is 64-bit aligned before we start to save iWMMXt registers,
8167 and also before we start to create locals. (A local variable
8168 might be a double or long long which we will load/store using
8169 an iWMMXt instruction). Therefore we need to push another
8170 ARM register, so that the stack will be 64-bit aligned. We
8171 try to avoid using the arg registers (r0 -r3) as they might be
8172 used to pass values in a tail call. */
8173 for (reg = 4; reg <= 12; reg++)
8174 if ((save_reg_mask & (1 << reg)) == 0)
8175 break;
8176
8177 if (reg <= 12)
8178 save_reg_mask |= (1 << reg);
8179 else
8180 {
8181 cfun->machine->sibcall_blocked = 1;
8182 save_reg_mask |= (1 << 3);
8183 }
8184 }
8185
6d3d9133
NC
8186 return save_reg_mask;
8187}
8188
699a4925 8189/* Generate a function exit sequence. If REALLY_RETURN is false, then do
6d3d9133 8190 everything bar the final return instruction. */
cd2b33d0 8191const char *
e32bac5b 8192output_return_instruction (rtx operand, int really_return, int reverse)
ff9940b0 8193{
6d3d9133 8194 char conditional[10];
ff9940b0 8195 char instr[100];
6d3d9133
NC
8196 int reg;
8197 unsigned long live_regs_mask;
8198 unsigned long func_type;
e26053d1 8199
6d3d9133 8200 func_type = arm_current_func_type ();
e2c671ba 8201
6d3d9133 8202 if (IS_NAKED (func_type))
d5b7b3ae 8203 return "";
6d3d9133
NC
8204
8205 if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
e2c671ba 8206 {
699a4925
RE
8207 /* If this function was declared non-returning, and we have
8208 found a tail call, then we have to trust that the called
8209 function won't return. */
3a5a4282
PB
8210 if (really_return)
8211 {
8212 rtx ops[2];
8213
8214 /* Otherwise, trap an attempted return by aborting. */
8215 ops[0] = operand;
8216 ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)"
8217 : "abort");
8218 assemble_external_libcall (ops[1]);
8219 output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
8220 }
8221
e2c671ba
RE
8222 return "";
8223 }
6d3d9133 8224
5895f793 8225 if (current_function_calls_alloca && !really_return)
62b10bbc 8226 abort ();
ff9940b0 8227
c414f8a9 8228 sprintf (conditional, "%%?%%%c0", reverse ? 'D' : 'd');
d5b7b3ae 8229
6d3d9133 8230 return_used_this_function = 1;
ff9940b0 8231
6d3d9133 8232 live_regs_mask = arm_compute_save_reg_mask ();
ff9940b0 8233
1768c26f 8234 if (live_regs_mask)
6d3d9133 8235 {
1768c26f
PB
8236 const char * return_reg;
8237
8238 /* If we do not have any special requirements for function exit
8239 (eg interworking, or ISR) then we can load the return address
8240 directly into the PC. Otherwise we must load it into LR. */
8241 if (really_return
1768c26f
PB
8242 && ! TARGET_INTERWORK)
8243 return_reg = reg_names[PC_REGNUM];
6d3d9133 8244 else
1768c26f
PB
8245 return_reg = reg_names[LR_REGNUM];
8246
6d3d9133
NC
8247 if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
8248 /* There are two possible reasons for the IP register being saved.
8249 Either a stack frame was created, in which case IP contains the
8250 old stack pointer, or an ISR routine corrupted it. If this in an
8251 ISR routine then just restore IP, otherwise restore IP into SP. */
8252 if (! IS_INTERRUPT (func_type))
8253 {
8254 live_regs_mask &= ~ (1 << IP_REGNUM);
8255 live_regs_mask |= (1 << SP_REGNUM);
8256 }
f3bb6135 8257
3a7731fd
PB
8258 /* On some ARM architectures it is faster to use LDR rather than
8259 LDM to load a single register. On other architectures, the
8260 cost is the same. In 26 bit mode, or for exception handlers,
8261 we have to use LDM to load the PC so that the CPSR is also
8262 restored. */
8263 for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
6d3d9133 8264 {
3a7731fd
PB
8265 if (live_regs_mask == (unsigned int)(1 << reg))
8266 break;
8267 }
8268 if (reg <= LAST_ARM_REGNUM
8269 && (reg != LR_REGNUM
8270 || ! really_return
8271 || (TARGET_APCS_32 && ! IS_INTERRUPT (func_type))))
8272 {
8273 sprintf (instr, "ldr%s\t%%|%s, [%%|sp], #4", conditional,
8274 (reg == LR_REGNUM) ? return_reg : reg_names[reg]);
6d3d9133 8275 }
ff9940b0 8276 else
1d5473cb 8277 {
1768c26f
PB
8278 char *p;
8279 int first = 1;
6d3d9133 8280
699a4925
RE
8281 /* Generate the load multiple instruction to restore the
8282 registers. Note we can get here, even if
8283 frame_pointer_needed is true, but only if sp already
8284 points to the base of the saved core registers. */
8285 if (live_regs_mask & (1 << SP_REGNUM))
a72d4945
RE
8286 {
8287 unsigned HOST_WIDE_INT stack_adjust =
8288 arm_get_frame_size () + current_function_outgoing_args_size;
8289
8290 if (stack_adjust != 0 && stack_adjust != 4)
8291 abort ();
8292
8293 if (stack_adjust && arm_arch5)
8294 sprintf (instr, "ldm%sib\t%%|sp, {", conditional);
8295 else
8296 {
8297 /* If we can't use ldmib (SA110 bug), then try to pop r3
8298 instead. */
8299 if (stack_adjust)
8300 live_regs_mask |= 1 << 3;
8301 sprintf (instr, "ldm%sfd\t%%|sp, {", conditional);
8302 }
8303 }
da6558fd 8304 else
1768c26f
PB
8305 sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
8306
8307 p = instr + strlen (instr);
6d3d9133 8308
1768c26f
PB
8309 for (reg = 0; reg <= SP_REGNUM; reg++)
8310 if (live_regs_mask & (1 << reg))
8311 {
8312 int l = strlen (reg_names[reg]);
8313
8314 if (first)
8315 first = 0;
8316 else
8317 {
8318 memcpy (p, ", ", 2);
8319 p += 2;
8320 }
8321
8322 memcpy (p, "%|", 2);
8323 memcpy (p + 2, reg_names[reg], l);
8324 p += l + 2;
8325 }
8326
8327 if (live_regs_mask & (1 << LR_REGNUM))
8328 {
b17fe233
NC
8329 sprintf (p, "%s%%|%s}", first ? "" : ", ", return_reg);
8330 /* Decide if we need to add the ^ symbol to the end of the
8331 register list. This causes the saved condition codes
8332 register to be copied into the current condition codes
8333 register. We do the copy if we are conforming to the 32-bit
8334 ABI and this is an interrupt function, or if we are
8335 conforming to the 26-bit ABI. There is a special case for
8336 the 26-bit ABI however, which is if we are writing back the
8337 stack pointer but not loading the PC. In this case adding
8338 the ^ symbol would create a type 2 LDM instruction, where
8339 writeback is UNPREDICTABLE. We are safe in leaving the ^
8340 character off in this case however, since the actual return
8341 instruction will be a MOVS which will restore the CPSR. */
8342 if ((TARGET_APCS_32 && IS_INTERRUPT (func_type))
13eedc5a 8343 || (! TARGET_APCS_32 && really_return))
b17fe233 8344 strcat (p, "^");
1768c26f
PB
8345 }
8346 else
8347 strcpy (p, "}");
1d5473cb 8348 }
da6558fd 8349
1768c26f
PB
8350 output_asm_insn (instr, & operand);
8351
3a7731fd
PB
8352 /* See if we need to generate an extra instruction to
8353 perform the actual function return. */
8354 if (really_return
8355 && func_type != ARM_FT_INTERWORKED
8356 && (live_regs_mask & (1 << LR_REGNUM)) != 0)
da6558fd 8357 {
3a7731fd
PB
8358 /* The return has already been handled
8359 by loading the LR into the PC. */
8360 really_return = 0;
da6558fd 8361 }
ff9940b0 8362 }
e26053d1 8363
1768c26f 8364 if (really_return)
ff9940b0 8365 {
6d3d9133
NC
8366 switch ((int) ARM_FUNC_TYPE (func_type))
8367 {
8368 case ARM_FT_ISR:
8369 case ARM_FT_FIQ:
8370 sprintf (instr, "sub%ss\t%%|pc, %%|lr, #4", conditional);
8371 break;
8372
8373 case ARM_FT_INTERWORKED:
8374 sprintf (instr, "bx%s\t%%|lr", conditional);
8375 break;
8376
8377 case ARM_FT_EXCEPTION:
8378 sprintf (instr, "mov%ss\t%%|pc, %%|lr", conditional);
8379 break;
8380
8381 default:
1768c26f
PB
8382 /* ARMv5 implementations always provide BX, so interworking
8383 is the default unless APCS-26 is in use. */
8384 if ((insn_flags & FL_ARCH5) != 0 && TARGET_APCS_32)
8385 sprintf (instr, "bx%s\t%%|lr", conditional);
8386 else
8387 sprintf (instr, "mov%s%s\t%%|pc, %%|lr",
8388 conditional, TARGET_APCS_32 ? "" : "s");
6d3d9133
NC
8389 break;
8390 }
1768c26f
PB
8391
8392 output_asm_insn (instr, & operand);
ff9940b0 8393 }
f3bb6135 8394
ff9940b0
RE
8395 return "";
8396}
8397
ef179a26
NC
8398/* Write the function name into the code section, directly preceding
8399 the function prologue.
8400
8401 Code will be output similar to this:
8402 t0
8403 .ascii "arm_poke_function_name", 0
8404 .align
8405 t1
8406 .word 0xff000000 + (t1 - t0)
8407 arm_poke_function_name
8408 mov ip, sp
8409 stmfd sp!, {fp, ip, lr, pc}
8410 sub fp, ip, #4
8411
8412 When performing a stack backtrace, code can inspect the value
8413 of 'pc' stored at 'fp' + 0. If the trace function then looks
8414 at location pc - 12 and the top 8 bits are set, then we know
8415 that there is a function name embedded immediately preceding this
8416 location and has length ((pc[-3]) & 0xff000000).
8417
8418 We assume that pc is declared as a pointer to an unsigned long.
8419
8420 It is of no benefit to output the function name if we are assembling
8421 a leaf function. These function types will not contain a stack
8422 backtrace structure, therefore it is not possible to determine the
8423 function name. */
ef179a26 8424void
e32bac5b 8425arm_poke_function_name (FILE *stream, const char *name)
ef179a26
NC
8426{
8427 unsigned long alignlength;
8428 unsigned long length;
8429 rtx x;
8430
d5b7b3ae 8431 length = strlen (name) + 1;
0c2ca901 8432 alignlength = ROUND_UP_WORD (length);
ef179a26 8433
949d79eb 8434 ASM_OUTPUT_ASCII (stream, name, length);
ef179a26 8435 ASM_OUTPUT_ALIGN (stream, 2);
30cf4896 8436 x = GEN_INT ((unsigned HOST_WIDE_INT) 0xff000000 + alignlength);
301d03af 8437 assemble_aligned_integer (UNITS_PER_WORD, x);
ef179a26
NC
8438}
8439
6d3d9133
NC
8440/* Place some comments into the assembler stream
8441 describing the current function. */
08c148a8 8442static void
e32bac5b 8443arm_output_function_prologue (FILE *f, HOST_WIDE_INT frame_size)
cce8749e 8444{
6d3d9133 8445 unsigned long func_type;
08c148a8
NB
8446
8447 if (!TARGET_ARM)
8448 {
8449 thumb_output_function_prologue (f, frame_size);
8450 return;
8451 }
6d3d9133
NC
8452
8453 /* Sanity check. */
abaa26e5 8454 if (arm_ccfsm_state || arm_target_insn)
6d3d9133 8455 abort ();
31fdb4d5 8456
6d3d9133
NC
8457 func_type = arm_current_func_type ();
8458
8459 switch ((int) ARM_FUNC_TYPE (func_type))
8460 {
8461 default:
8462 case ARM_FT_NORMAL:
8463 break;
8464 case ARM_FT_INTERWORKED:
8465 asm_fprintf (f, "\t%@ Function supports interworking.\n");
8466 break;
8467 case ARM_FT_EXCEPTION_HANDLER:
8468 asm_fprintf (f, "\t%@ C++ Exception Handler.\n");
8469 break;
8470 case ARM_FT_ISR:
8471 asm_fprintf (f, "\t%@ Interrupt Service Routine.\n");
8472 break;
8473 case ARM_FT_FIQ:
8474 asm_fprintf (f, "\t%@ Fast Interrupt Service Routine.\n");
8475 break;
8476 case ARM_FT_EXCEPTION:
8477 asm_fprintf (f, "\t%@ ARM Exception Handler.\n");
8478 break;
8479 }
ff9940b0 8480
6d3d9133
NC
8481 if (IS_NAKED (func_type))
8482 asm_fprintf (f, "\t%@ Naked Function: prologue and epilogue provided by programmer.\n");
8483
8484 if (IS_VOLATILE (func_type))
8485 asm_fprintf (f, "\t%@ Volatile: function does not return.\n");
8486
8487 if (IS_NESTED (func_type))
8488 asm_fprintf (f, "\t%@ Nested: function declared inside another function.\n");
8489
c53dddc2 8490 asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %wd\n",
dd18ae56
NC
8491 current_function_args_size,
8492 current_function_pretend_args_size, frame_size);
6d3d9133 8493
3cb66fd7 8494 asm_fprintf (f, "\t%@ frame_needed = %d, uses_anonymous_args = %d\n",
dd18ae56 8495 frame_pointer_needed,
3cb66fd7 8496 cfun->machine->uses_anonymous_args);
cce8749e 8497
6f7ebcbb
NC
8498 if (cfun->machine->lr_save_eliminated)
8499 asm_fprintf (f, "\t%@ link register save eliminated.\n");
8500
32de079a
RE
8501#ifdef AOF_ASSEMBLER
8502 if (flag_pic)
dd18ae56 8503 asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, PIC_OFFSET_TABLE_REGNUM);
32de079a 8504#endif
6d3d9133
NC
8505
8506 return_used_this_function = 0;
f3bb6135 8507}
cce8749e 8508
cd2b33d0 8509const char *
a72d4945 8510arm_output_epilogue (rtx sibling)
cce8749e 8511{
949d79eb 8512 int reg;
6f7ebcbb 8513 unsigned long saved_regs_mask;
6d3d9133 8514 unsigned long func_type;
c882c7ac
RE
8515 /* Floats_offset is the offset from the "virtual" frame. In an APCS
8516 frame that is $fp + 4 for a non-variadic function. */
8517 int floats_offset = 0;
cce8749e 8518 rtx operands[3];
0977774b 8519 int frame_size = arm_get_frame_size ();
d5b7b3ae 8520 FILE * f = asm_out_file;
6d3d9133 8521 rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
5a9335ef 8522 unsigned int lrm_count = 0;
a72d4945 8523 int really_return = (sibling == NULL);
cce8749e 8524
6d3d9133
NC
8525 /* If we have already generated the return instruction
8526 then it is futile to generate anything else. */
a72d4945 8527 if (use_return_insn (FALSE, sibling) && return_used_this_function)
949d79eb 8528 return "";
cce8749e 8529
6d3d9133 8530 func_type = arm_current_func_type ();
d5b7b3ae 8531
6d3d9133
NC
8532 if (IS_NAKED (func_type))
8533 /* Naked functions don't have epilogues. */
8534 return "";
0616531f 8535
6d3d9133 8536 if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
e2c671ba 8537 {
86efdc8e 8538 rtx op;
6d3d9133
NC
8539
8540 /* A volatile function should never return. Call abort. */
ed0e6530 8541 op = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)" : "abort");
2b835d68 8542 assemble_external_libcall (op);
e2c671ba 8543 output_asm_insn ("bl\t%a0", &op);
6d3d9133 8544
949d79eb 8545 return "";
e2c671ba
RE
8546 }
8547
6d3d9133
NC
8548 if (ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
8549 && ! really_return)
8550 /* If we are throwing an exception, then we really must
8551 be doing a return, so we can't tail-call. */
8552 abort ();
8553
6f7ebcbb 8554 saved_regs_mask = arm_compute_save_reg_mask ();
5a9335ef
NC
8555
8556 if (TARGET_IWMMXT)
8557 lrm_count = bit_count (saved_regs_mask);
8558
c882c7ac
RE
8559 /* XXX We should adjust floats_offset for any anonymous args, and then
8560 re-adjust vfp_offset below to compensate. */
8561
6d3d9133 8562 /* Compute how far away the floats will be. */
5a9335ef 8563 for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
6f7ebcbb 8564 if (saved_regs_mask & (1 << reg))
6ed30148 8565 floats_offset += 4;
6d3d9133 8566
ff9940b0 8567 if (frame_pointer_needed)
cce8749e 8568 {
c882c7ac
RE
8569 int vfp_offset = 4;
8570
29ad9694 8571 if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
b111229a 8572 {
d5b7b3ae 8573 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
5895f793 8574 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
8575 {
8576 floats_offset += 12;
dd18ae56 8577 asm_fprintf (f, "\tldfe\t%r, [%r, #-%d]\n",
c882c7ac 8578 reg, FP_REGNUM, floats_offset - vfp_offset);
b111229a
RE
8579 }
8580 }
8581 else
8582 {
d5b7b3ae 8583 int start_reg = LAST_ARM_FP_REGNUM;
b111229a 8584
d5b7b3ae 8585 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
b111229a 8586 {
5895f793 8587 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
8588 {
8589 floats_offset += 12;
6cfc7210 8590
6354dc9b 8591 /* We can't unstack more than four registers at once. */
b111229a
RE
8592 if (start_reg - reg == 3)
8593 {
dd18ae56 8594 asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
c882c7ac 8595 reg, FP_REGNUM, floats_offset - vfp_offset);
b111229a
RE
8596 start_reg = reg - 1;
8597 }
8598 }
8599 else
8600 {
8601 if (reg != start_reg)
dd18ae56
NC
8602 asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
8603 reg + 1, start_reg - reg,
c882c7ac 8604 FP_REGNUM, floats_offset - vfp_offset);
b111229a
RE
8605 start_reg = reg - 1;
8606 }
8607 }
8608
8609 /* Just in case the last register checked also needs unstacking. */
8610 if (reg != start_reg)
dd18ae56
NC
8611 asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
8612 reg + 1, start_reg - reg,
c882c7ac 8613 FP_REGNUM, floats_offset - vfp_offset);
b111229a 8614 }
6d3d9133 8615
5a9335ef
NC
8616 if (TARGET_IWMMXT)
8617 {
8618 /* The frame pointer is guaranteed to be non-double-word aligned.
8619 This is because it is set to (old_stack_pointer - 4) and the
8620 old_stack_pointer was double word aligned. Thus the offset to
8621 the iWMMXt registers to be loaded must also be non-double-word
8622 sized, so that the resultant address *is* double-word aligned.
8623 We can ignore floats_offset since that was already included in
8624 the live_regs_mask. */
8625 lrm_count += (lrm_count % 2 ? 2 : 1);
8626
8627 for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
8628 if (regs_ever_live[reg] && !call_used_regs[reg])
8629 {
8630 asm_fprintf (f, "\twldrd\t%r, [%r, #-%d]\n",
8631 reg, FP_REGNUM, lrm_count * 4);
8632 lrm_count += 2;
8633 }
8634 }
8635
6f7ebcbb 8636 /* saved_regs_mask should contain the IP, which at the time of stack
6d3d9133
NC
8637 frame generation actually contains the old stack pointer. So a
8638 quick way to unwind the stack is just pop the IP register directly
8639 into the stack pointer. */
6f7ebcbb 8640 if ((saved_regs_mask & (1 << IP_REGNUM)) == 0)
6d3d9133 8641 abort ();
6f7ebcbb
NC
8642 saved_regs_mask &= ~ (1 << IP_REGNUM);
8643 saved_regs_mask |= (1 << SP_REGNUM);
6d3d9133 8644
6f7ebcbb 8645 /* There are two registers left in saved_regs_mask - LR and PC. We
6d3d9133
NC
8646 only need to restore the LR register (the return address), but to
8647 save time we can load it directly into the PC, unless we need a
8648 special function exit sequence, or we are not really returning. */
8649 if (really_return && ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL)
8650 /* Delete the LR from the register mask, so that the LR on
8651 the stack is loaded into the PC in the register mask. */
6f7ebcbb 8652 saved_regs_mask &= ~ (1 << LR_REGNUM);
b111229a 8653 else
6f7ebcbb 8654 saved_regs_mask &= ~ (1 << PC_REGNUM);
efc2515b
RE
8655
8656 /* We must use SP as the base register, because SP is one of the
8657 registers being restored. If an interrupt or page fault
8658 happens in the ldm instruction, the SP might or might not
8659 have been restored. That would be bad, as then SP will no
8660 longer indicate the safe area of stack, and we can get stack
8661 corruption. Using SP as the base register means that it will
8662 be reset correctly to the original value, should an interrupt
699a4925
RE
8663 occur. If the stack pointer already points at the right
8664 place, then omit the subtraction. */
8665 if (((frame_size + current_function_outgoing_args_size + floats_offset)
8666 != 4 * (1 + (int) bit_count (saved_regs_mask)))
8667 || current_function_calls_alloca)
8668 asm_fprintf (f, "\tsub\t%r, %r, #%d\n", SP_REGNUM, FP_REGNUM,
8669 4 * bit_count (saved_regs_mask));
efc2515b 8670 print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
7b8b8ade
NC
8671
8672 if (IS_INTERRUPT (func_type))
8673 /* Interrupt handlers will have pushed the
8674 IP onto the stack, so restore it now. */
f55d7103 8675 print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, 1 << IP_REGNUM);
cce8749e
CH
8676 }
8677 else
8678 {
d2288d8d 8679 /* Restore stack pointer if necessary. */
56636818 8680 if (frame_size + current_function_outgoing_args_size != 0)
d2288d8d
TG
8681 {
8682 operands[0] = operands[1] = stack_pointer_rtx;
56636818
JL
8683 operands[2] = GEN_INT (frame_size
8684 + current_function_outgoing_args_size);
d2288d8d
TG
8685 output_add_immediate (operands);
8686 }
8687
29ad9694 8688 if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
b111229a 8689 {
d5b7b3ae 8690 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
5895f793 8691 if (regs_ever_live[reg] && !call_used_regs[reg])
dd18ae56
NC
8692 asm_fprintf (f, "\tldfe\t%r, [%r], #12\n",
8693 reg, SP_REGNUM);
b111229a
RE
8694 }
8695 else
8696 {
d5b7b3ae 8697 int start_reg = FIRST_ARM_FP_REGNUM;
b111229a 8698
d5b7b3ae 8699 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
b111229a 8700 {
5895f793 8701 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
8702 {
8703 if (reg - start_reg == 3)
8704 {
dd18ae56
NC
8705 asm_fprintf (f, "\tlfmfd\t%r, 4, [%r]!\n",
8706 start_reg, SP_REGNUM);
b111229a
RE
8707 start_reg = reg + 1;
8708 }
8709 }
8710 else
8711 {
8712 if (reg != start_reg)
dd18ae56
NC
8713 asm_fprintf (f, "\tlfmfd\t%r, %d, [%r]!\n",
8714 start_reg, reg - start_reg,
8715 SP_REGNUM);
6cfc7210 8716
b111229a
RE
8717 start_reg = reg + 1;
8718 }
8719 }
8720
8721 /* Just in case the last register checked also needs unstacking. */
8722 if (reg != start_reg)
dd18ae56
NC
8723 asm_fprintf (f, "\tlfmfd\t%r, %d, [%r]!\n",
8724 start_reg, reg - start_reg, SP_REGNUM);
b111229a
RE
8725 }
8726
5a9335ef
NC
8727 if (TARGET_IWMMXT)
8728 for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
8729 if (regs_ever_live[reg] && !call_used_regs[reg])
8730 asm_fprintf (f, "\twldrd\t%r, [%r, #+8]!\n", reg, SP_REGNUM);
8731
6d3d9133
NC
8732 /* If we can, restore the LR into the PC. */
8733 if (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
8734 && really_return
8735 && current_function_pretend_args_size == 0
6f7ebcbb 8736 && saved_regs_mask & (1 << LR_REGNUM))
cce8749e 8737 {
6f7ebcbb
NC
8738 saved_regs_mask &= ~ (1 << LR_REGNUM);
8739 saved_regs_mask |= (1 << PC_REGNUM);
6d3d9133 8740 }
d5b7b3ae 8741
6d3d9133
NC
8742 /* Load the registers off the stack. If we only have one register
8743 to load use the LDR instruction - it is faster. */
6f7ebcbb 8744 if (saved_regs_mask == (1 << LR_REGNUM))
6d3d9133 8745 {
f4864588 8746 /* The exception handler ignores the LR, so we do
6d3d9133
NC
8747 not really need to load it off the stack. */
8748 if (eh_ofs)
8749 asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
32de079a 8750 else
6d3d9133 8751 asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
cce8749e 8752 }
6f7ebcbb 8753 else if (saved_regs_mask)
f1acdf8b
NC
8754 {
8755 if (saved_regs_mask & (1 << SP_REGNUM))
8756 /* Note - write back to the stack register is not enabled
8757 (ie "ldmfd sp!..."). We know that the stack pointer is
8758 in the list of registers and if we add writeback the
8759 instruction becomes UNPREDICTABLE. */
8760 print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
8761 else
8762 print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
8763 }
6d3d9133
NC
8764
8765 if (current_function_pretend_args_size)
cce8749e 8766 {
6d3d9133
NC
8767 /* Unwind the pre-pushed regs. */
8768 operands[0] = operands[1] = stack_pointer_rtx;
8769 operands[2] = GEN_INT (current_function_pretend_args_size);
8770 output_add_immediate (operands);
8771 }
8772 }
32de079a 8773
f4864588
PB
8774 if (! really_return
8775 || (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
8776 && current_function_pretend_args_size == 0
8777 && saved_regs_mask & (1 << PC_REGNUM)))
6d3d9133 8778 return "";
d5b7b3ae 8779
6d3d9133
NC
8780 /* Generate the return instruction. */
8781 switch ((int) ARM_FUNC_TYPE (func_type))
8782 {
8783 case ARM_FT_EXCEPTION_HANDLER:
8784 /* Even in 26-bit mode we do a mov (rather than a movs)
8785 because we don't have the PSR bits set in the address. */
8786 asm_fprintf (f, "\tmov\t%r, %r\n", PC_REGNUM, EXCEPTION_LR_REGNUM);
8787 break;
0616531f 8788
6d3d9133
NC
8789 case ARM_FT_ISR:
8790 case ARM_FT_FIQ:
8791 asm_fprintf (f, "\tsubs\t%r, %r, #4\n", PC_REGNUM, LR_REGNUM);
8792 break;
8793
8794 case ARM_FT_EXCEPTION:
8795 asm_fprintf (f, "\tmovs\t%r, %r\n", PC_REGNUM, LR_REGNUM);
8796 break;
8797
8798 case ARM_FT_INTERWORKED:
8799 asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
8800 break;
8801
8802 default:
8803 if (frame_pointer_needed)
6bc82793 8804 /* If we used the frame pointer then the return address
6d3d9133
NC
8805 will have been loaded off the stack directly into the
8806 PC, so there is no need to issue a MOV instruction
8807 here. */
8808 ;
8809 else if (current_function_pretend_args_size == 0
6f7ebcbb 8810 && (saved_regs_mask & (1 << LR_REGNUM)))
6d3d9133
NC
8811 /* Similarly we may have been able to load LR into the PC
8812 even if we did not create a stack frame. */
8813 ;
8814 else if (TARGET_APCS_32)
8815 asm_fprintf (f, "\tmov\t%r, %r\n", PC_REGNUM, LR_REGNUM);
8816 else
8817 asm_fprintf (f, "\tmovs\t%r, %r\n", PC_REGNUM, LR_REGNUM);
8818 break;
cce8749e 8819 }
f3bb6135 8820
949d79eb
RE
8821 return "";
8822}
8823
08c148a8 8824static void
e32bac5b
RE
8825arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
8826 HOST_WIDE_INT frame_size)
949d79eb 8827{
d5b7b3ae
RE
8828 if (TARGET_THUMB)
8829 {
8830 /* ??? Probably not safe to set this here, since it assumes that a
8831 function will be emitted as assembly immediately after we generate
8832 RTL for it. This does not happen for inline functions. */
8833 return_used_this_function = 0;
8834 }
8835 else
8836 {
0977774b
JT
8837 /* We need to take into account any stack-frame rounding. */
8838 frame_size = arm_get_frame_size ();
8839
a72d4945 8840 if (use_return_insn (FALSE, NULL)
d5b7b3ae
RE
8841 && return_used_this_function
8842 && (frame_size + current_function_outgoing_args_size) != 0
5895f793 8843 && !frame_pointer_needed)
d5b7b3ae 8844 abort ();
f3bb6135 8845
d5b7b3ae 8846 /* Reset the ARM-specific per-function variables. */
d5b7b3ae
RE
8847 after_arm_reorg = 0;
8848 }
f3bb6135 8849}
e2c671ba 8850
2c849145
JM
8851/* Generate and emit an insn that we will recognize as a push_multi.
8852 Unfortunately, since this insn does not reflect very well the actual
8853 semantics of the operation, we need to annotate the insn for the benefit
8854 of DWARF2 frame unwind information. */
2c849145 8855static rtx
e32bac5b 8856emit_multi_reg_push (int mask)
e2c671ba
RE
8857{
8858 int num_regs = 0;
9b598fa0 8859 int num_dwarf_regs;
e2c671ba
RE
8860 int i, j;
8861 rtx par;
2c849145 8862 rtx dwarf;
87e27392 8863 int dwarf_par_index;
2c849145 8864 rtx tmp, reg;
e2c671ba 8865
d5b7b3ae 8866 for (i = 0; i <= LAST_ARM_REGNUM; i++)
e2c671ba 8867 if (mask & (1 << i))
5895f793 8868 num_regs++;
e2c671ba
RE
8869
8870 if (num_regs == 0 || num_regs > 16)
8871 abort ();
8872
9b598fa0
RE
8873 /* We don't record the PC in the dwarf frame information. */
8874 num_dwarf_regs = num_regs;
8875 if (mask & (1 << PC_REGNUM))
8876 num_dwarf_regs--;
8877
87e27392 8878 /* For the body of the insn we are going to generate an UNSPEC in
05713b80 8879 parallel with several USEs. This allows the insn to be recognized
87e27392
NC
8880 by the push_multi pattern in the arm.md file. The insn looks
8881 something like this:
8882
8883 (parallel [
b15bca31
RE
8884 (set (mem:BLK (pre_dec:BLK (reg:SI sp)))
8885 (unspec:BLK [(reg:SI r4)] UNSPEC_PUSH_MULT))
87e27392
NC
8886 (use (reg:SI 11 fp))
8887 (use (reg:SI 12 ip))
8888 (use (reg:SI 14 lr))
8889 (use (reg:SI 15 pc))
8890 ])
8891
8892 For the frame note however, we try to be more explicit and actually
8893 show each register being stored into the stack frame, plus a (single)
8894 decrement of the stack pointer. We do it this way in order to be
8895 friendly to the stack unwinding code, which only wants to see a single
8896 stack decrement per instruction. The RTL we generate for the note looks
8897 something like this:
8898
8899 (sequence [
8900 (set (reg:SI sp) (plus:SI (reg:SI sp) (const_int -20)))
8901 (set (mem:SI (reg:SI sp)) (reg:SI r4))
8902 (set (mem:SI (plus:SI (reg:SI sp) (const_int 4))) (reg:SI fp))
8903 (set (mem:SI (plus:SI (reg:SI sp) (const_int 8))) (reg:SI ip))
8904 (set (mem:SI (plus:SI (reg:SI sp) (const_int 12))) (reg:SI lr))
87e27392
NC
8905 ])
8906
8907 This sequence is used both by the code to support stack unwinding for
8908 exceptions handlers and the code to generate dwarf2 frame debugging. */
8909
43cffd11 8910 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
9b598fa0 8911 dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_dwarf_regs + 1));
87e27392 8912 dwarf_par_index = 1;
e2c671ba 8913
d5b7b3ae 8914 for (i = 0; i <= LAST_ARM_REGNUM; i++)
e2c671ba
RE
8915 {
8916 if (mask & (1 << i))
8917 {
2c849145
JM
8918 reg = gen_rtx_REG (SImode, i);
8919
e2c671ba 8920 XVECEXP (par, 0, 0)
43cffd11
RE
8921 = gen_rtx_SET (VOIDmode,
8922 gen_rtx_MEM (BLKmode,
8923 gen_rtx_PRE_DEC (BLKmode,
8924 stack_pointer_rtx)),
8925 gen_rtx_UNSPEC (BLKmode,
2c849145 8926 gen_rtvec (1, reg),
9b598fa0 8927 UNSPEC_PUSH_MULT));
2c849145 8928
9b598fa0
RE
8929 if (i != PC_REGNUM)
8930 {
8931 tmp = gen_rtx_SET (VOIDmode,
8932 gen_rtx_MEM (SImode, stack_pointer_rtx),
8933 reg);
8934 RTX_FRAME_RELATED_P (tmp) = 1;
8935 XVECEXP (dwarf, 0, dwarf_par_index) = tmp;
8936 dwarf_par_index++;
8937 }
2c849145 8938
e2c671ba
RE
8939 break;
8940 }
8941 }
8942
8943 for (j = 1, i++; j < num_regs; i++)
8944 {
8945 if (mask & (1 << i))
8946 {
2c849145
JM
8947 reg = gen_rtx_REG (SImode, i);
8948
8949 XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg);
8950
9b598fa0
RE
8951 if (i != PC_REGNUM)
8952 {
8953 tmp = gen_rtx_SET (VOIDmode,
8954 gen_rtx_MEM (SImode,
8955 plus_constant (stack_pointer_rtx,
8956 4 * j)),
8957 reg);
8958 RTX_FRAME_RELATED_P (tmp) = 1;
8959 XVECEXP (dwarf, 0, dwarf_par_index++) = tmp;
8960 }
8961
e2c671ba
RE
8962 j++;
8963 }
8964 }
b111229a 8965
2c849145 8966 par = emit_insn (par);
87e27392
NC
8967
8968 tmp = gen_rtx_SET (SImode,
8969 stack_pointer_rtx,
8970 gen_rtx_PLUS (SImode,
8971 stack_pointer_rtx,
8972 GEN_INT (-4 * num_regs)));
8973 RTX_FRAME_RELATED_P (tmp) = 1;
8974 XVECEXP (dwarf, 0, 0) = tmp;
8975
2c849145
JM
8976 REG_NOTES (par) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
8977 REG_NOTES (par));
8978 return par;
b111229a
RE
8979}
8980
2c849145 8981static rtx
e32bac5b 8982emit_sfm (int base_reg, int count)
b111229a
RE
8983{
8984 rtx par;
2c849145
JM
8985 rtx dwarf;
8986 rtx tmp, reg;
b111229a
RE
8987 int i;
8988
43cffd11 8989 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2c849145 8990 dwarf = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2c849145
JM
8991
8992 reg = gen_rtx_REG (XFmode, base_reg++);
43cffd11
RE
8993
8994 XVECEXP (par, 0, 0)
8995 = gen_rtx_SET (VOIDmode,
8996 gen_rtx_MEM (BLKmode,
8997 gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
8998 gen_rtx_UNSPEC (BLKmode,
2c849145 8999 gen_rtvec (1, reg),
b15bca31 9000 UNSPEC_PUSH_MULT));
2c849145
JM
9001 tmp
9002 = gen_rtx_SET (VOIDmode,
9003 gen_rtx_MEM (XFmode,
9004 gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
9005 reg);
9006 RTX_FRAME_RELATED_P (tmp) = 1;
9007 XVECEXP (dwarf, 0, count - 1) = tmp;
9008
b111229a 9009 for (i = 1; i < count; i++)
2c849145
JM
9010 {
9011 reg = gen_rtx_REG (XFmode, base_reg++);
9012 XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode, reg);
9013
9014 tmp = gen_rtx_SET (VOIDmode,
9015 gen_rtx_MEM (XFmode,
9016 gen_rtx_PRE_DEC (BLKmode,
9017 stack_pointer_rtx)),
9018 reg);
9019 RTX_FRAME_RELATED_P (tmp) = 1;
9020 XVECEXP (dwarf, 0, count - i - 1) = tmp;
9021 }
b111229a 9022
2c849145
JM
9023 par = emit_insn (par);
9024 REG_NOTES (par) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
9025 REG_NOTES (par));
9026 return par;
e2c671ba
RE
9027}
9028
095bb276
NC
9029/* Compute the distance from register FROM to register TO.
9030 These can be the arg pointer (26), the soft frame pointer (25),
9031 the stack pointer (13) or the hard frame pointer (11).
9032 Typical stack layout looks like this:
9033
9034 old stack pointer -> | |
9035 ----
9036 | | \
9037 | | saved arguments for
9038 | | vararg functions
9039 | | /
9040 --
9041 hard FP & arg pointer -> | | \
9042 | | stack
9043 | | frame
9044 | | /
9045 --
9046 | | \
9047 | | call saved
9048 | | registers
9049 soft frame pointer -> | | /
9050 --
9051 | | \
9052 | | local
9053 | | variables
9054 | | /
9055 --
9056 | | \
9057 | | outgoing
9058 | | arguments
9059 current stack pointer -> | | /
9060 --
9061
43aa4e05 9062 For a given function some or all of these stack components
095bb276
NC
9063 may not be needed, giving rise to the possibility of
9064 eliminating some of the registers.
9065
825dda42 9066 The values returned by this function must reflect the behavior
095bb276
NC
9067 of arm_expand_prologue() and arm_compute_save_reg_mask().
9068
9069 The sign of the number returned reflects the direction of stack
9070 growth, so the values are positive for all eliminations except
9071 from the soft frame pointer to the hard frame pointer. */
095bb276 9072unsigned int
e32bac5b 9073arm_compute_initial_elimination_offset (unsigned int from, unsigned int to)
095bb276 9074{
0977774b 9075 unsigned int local_vars = arm_get_frame_size ();
095bb276
NC
9076 unsigned int outgoing_args = current_function_outgoing_args_size;
9077 unsigned int stack_frame;
9078 unsigned int call_saved_registers;
9079 unsigned long func_type;
9080
9081 func_type = arm_current_func_type ();
9082
9083 /* Volatile functions never return, so there is
9084 no need to save call saved registers. */
9085 call_saved_registers = 0;
9086 if (! IS_VOLATILE (func_type))
9087 {
121308d4 9088 unsigned int reg_mask;
095bb276
NC
9089 unsigned int reg;
9090
1d6e90ac 9091 /* Make sure that we compute which registers will be saved
121308d4 9092 on the stack using the same algorithm that is used by
5a9335ef
NC
9093 the prologue creation code. */
9094 reg_mask = arm_compute_save_reg_mask ();
095bb276 9095
121308d4 9096 /* Now count the number of bits set in save_reg_mask.
5a9335ef
NC
9097 If we have already counted the registers in the stack
9098 frame, do not count them again. Non call-saved registers
9099 might be saved in the call-save area of the stack, if
9100 doing so will preserve the stack's alignment. Hence we
9101 must count them here. For each set bit we need 4 bytes
9102 of stack space. */
9103 if (frame_pointer_needed)
9104 reg_mask &= 0x07ff;
9105 call_saved_registers += 4 * bit_count (reg_mask);
ef7112de
NC
9106
9107 /* If the hard floating point registers are going to be
9108 used then they must be saved on the stack as well.
9109 Each register occupies 12 bytes of stack space. */
5a9335ef 9110 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
ef7112de
NC
9111 if (regs_ever_live[reg] && ! call_used_regs[reg])
9112 call_saved_registers += 12;
5a9335ef
NC
9113
9114 if (TARGET_REALLY_IWMMXT)
9115 /* Check for the call-saved iWMMXt registers. */
9116 for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
9117 if (regs_ever_live[reg] && ! call_used_regs [reg])
9118 call_saved_registers += 8;
095bb276
NC
9119 }
9120
9121 /* The stack frame contains 4 registers - the old frame pointer,
9122 the old stack pointer, the return address and PC of the start
9123 of the function. */
9124 stack_frame = frame_pointer_needed ? 16 : 0;
9125
095bb276
NC
9126 /* OK, now we have enough information to compute the distances.
9127 There must be an entry in these switch tables for each pair
9128 of registers in ELIMINABLE_REGS, even if some of the entries
9129 seem to be redundant or useless. */
9130 switch (from)
9131 {
9132 case ARG_POINTER_REGNUM:
9133 switch (to)
9134 {
9135 case THUMB_HARD_FRAME_POINTER_REGNUM:
9136 return 0;
9137
9138 case FRAME_POINTER_REGNUM:
9139 /* This is the reverse of the soft frame pointer
9140 to hard frame pointer elimination below. */
9141 if (call_saved_registers == 0 && stack_frame == 0)
9142 return 0;
9143 return (call_saved_registers + stack_frame - 4);
9144
9145 case ARM_HARD_FRAME_POINTER_REGNUM:
9146 /* If there is no stack frame then the hard
9147 frame pointer and the arg pointer coincide. */
9148 if (stack_frame == 0 && call_saved_registers != 0)
9149 return 0;
9150 /* FIXME: Not sure about this. Maybe we should always return 0 ? */
9151 return (frame_pointer_needed
9152 && current_function_needs_context
3cb66fd7 9153 && ! cfun->machine->uses_anonymous_args) ? 4 : 0;
095bb276
NC
9154
9155 case STACK_POINTER_REGNUM:
9156 /* If nothing has been pushed on the stack at all
9157 then this will return -4. This *is* correct! */
9158 return call_saved_registers + stack_frame + local_vars + outgoing_args - 4;
9159
9160 default:
9161 abort ();
9162 }
9163 break;
9164
9165 case FRAME_POINTER_REGNUM:
9166 switch (to)
9167 {
9168 case THUMB_HARD_FRAME_POINTER_REGNUM:
9169 return 0;
9170
9171 case ARM_HARD_FRAME_POINTER_REGNUM:
9172 /* The hard frame pointer points to the top entry in the
9173 stack frame. The soft frame pointer to the bottom entry
9174 in the stack frame. If there is no stack frame at all,
9175 then they are identical. */
9176 if (call_saved_registers == 0 && stack_frame == 0)
9177 return 0;
9178 return - (call_saved_registers + stack_frame - 4);
9179
9180 case STACK_POINTER_REGNUM:
9181 return local_vars + outgoing_args;
9182
9183 default:
9184 abort ();
9185 }
9186 break;
9187
9188 default:
9189 /* You cannot eliminate from the stack pointer.
9190 In theory you could eliminate from the hard frame
9191 pointer to the stack pointer, but this will never
9192 happen, since if a stack frame is not needed the
9193 hard frame pointer will never be used. */
9194 abort ();
9195 }
9196}
9197
0977774b
JT
9198/* Calculate the size of the stack frame, taking into account any
9199 padding that is required to ensure stack-alignment. */
0977774b 9200HOST_WIDE_INT
e32bac5b 9201arm_get_frame_size (void)
0977774b
JT
9202{
9203 int regno;
9204
0c2ca901 9205 int base_size = ROUND_UP_WORD (get_frame_size ());
0977774b
JT
9206 int entry_size = 0;
9207 unsigned long func_type = arm_current_func_type ();
c231c91e 9208 int leaf;
0977774b
JT
9209
9210 if (! TARGET_ARM)
9211 abort();
9212
9213 if (! TARGET_ATPCS)
9214 return base_size;
9215
c231c91e
RE
9216 /* We need to know if we are a leaf function. Unfortunately, it
9217 is possible to be called after start_sequence has been called,
9218 which causes get_insns to return the insns for the sequence,
9219 not the function, which will cause leaf_function_p to return
9220 the incorrect result.
9221
9222 To work around this, we cache the computed frame size. This
9223 works because we will only be calling RTL expanders that need
9224 to know about leaf functions once reload has completed, and the
9225 frame size cannot be changed after that time, so we can safely
9226 use the cached value. */
9227
9228 if (reload_completed)
9229 return cfun->machine->frame_size;
9230
9231 leaf = leaf_function_p ();
9232
9233 /* A leaf function does not need any stack alignment if it has nothing
9234 on the stack. */
9235 if (leaf && base_size == 0)
9236 {
9237 cfun->machine->frame_size = 0;
9238 return 0;
9239 }
9240
0977774b
JT
9241 /* We know that SP will be word aligned on entry, and we must
9242 preserve that condition at any subroutine call. But those are
9243 the only constraints. */
9244
9245 /* Space for variadic functions. */
9246 if (current_function_pretend_args_size)
9247 entry_size += current_function_pretend_args_size;
9248
9249 /* Space for saved registers. */
9250 entry_size += bit_count (arm_compute_save_reg_mask ()) * 4;
9251
9252 /* Space for saved FPA registers. */
9253 if (! IS_VOLATILE (func_type))
9254 {
9255 for (regno = FIRST_ARM_FP_REGNUM; regno <= LAST_ARM_FP_REGNUM; regno++)
9256 if (regs_ever_live[regno] && ! call_used_regs[regno])
9257 entry_size += 12;
9258 }
9259
5a9335ef
NC
9260 if (TARGET_REALLY_IWMMXT)
9261 {
9262 /* Check for the call-saved iWMMXt registers. */
9263 for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
9264 if (regs_ever_live [regno] && ! call_used_regs [regno])
9265 entry_size += 8;
9266 }
9267
0977774b
JT
9268 if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
9269 base_size += 4;
9270 if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
9271 abort ();
9272
c231c91e
RE
9273 cfun->machine->frame_size = base_size;
9274
0977774b
JT
9275 return base_size;
9276}
9277
6d3d9133 9278/* Generate the prologue instructions for entry into an ARM function. */
e2c671ba 9279void
e32bac5b 9280arm_expand_prologue (void)
e2c671ba
RE
9281{
9282 int reg;
6d3d9133 9283 rtx amount;
2c849145 9284 rtx insn;
68dfd979 9285 rtx ip_rtx;
6d3d9133
NC
9286 unsigned long live_regs_mask;
9287 unsigned long func_type;
68dfd979 9288 int fp_offset = 0;
095bb276
NC
9289 int saved_pretend_args = 0;
9290 unsigned int args_to_push;
d3236b4d 9291
6d3d9133 9292 func_type = arm_current_func_type ();
e2c671ba 9293
31fdb4d5 9294 /* Naked functions don't have prologues. */
6d3d9133 9295 if (IS_NAKED (func_type))
31fdb4d5
DE
9296 return;
9297
095bb276
NC
9298 /* Make a copy of c_f_p_a_s as we may need to modify it locally. */
9299 args_to_push = current_function_pretend_args_size;
9300
6d3d9133
NC
9301 /* Compute which register we will have to save onto the stack. */
9302 live_regs_mask = arm_compute_save_reg_mask ();
e2c671ba 9303
68dfd979 9304 ip_rtx = gen_rtx_REG (SImode, IP_REGNUM);
d3236b4d 9305
e2c671ba
RE
9306 if (frame_pointer_needed)
9307 {
7b8b8ade
NC
9308 if (IS_INTERRUPT (func_type))
9309 {
9310 /* Interrupt functions must not corrupt any registers.
9311 Creating a frame pointer however, corrupts the IP
9312 register, so we must push it first. */
9313 insn = emit_multi_reg_push (1 << IP_REGNUM);
121308d4
NC
9314
9315 /* Do not set RTX_FRAME_RELATED_P on this insn.
9316 The dwarf stack unwinding code only wants to see one
9317 stack decrement per function, and this is not it. If
9318 this instruction is labeled as being part of the frame
9319 creation sequence then dwarf2out_frame_debug_expr will
9320 abort when it encounters the assignment of IP to FP
9321 later on, since the use of SP here establishes SP as
9322 the CFA register and not IP.
9323
9324 Anyway this instruction is not really part of the stack
9325 frame creation although it is part of the prologue. */
7b8b8ade
NC
9326 }
9327 else if (IS_NESTED (func_type))
68dfd979
NC
9328 {
9329 /* The Static chain register is the same as the IP register
9330 used as a scratch register during stack frame creation.
9331 To get around this need to find somewhere to store IP
9332 whilst the frame is being created. We try the following
9333 places in order:
9334
6d3d9133 9335 1. The last argument register.
68dfd979
NC
9336 2. A slot on the stack above the frame. (This only
9337 works if the function is not a varargs function).
095bb276
NC
9338 3. Register r3, after pushing the argument registers
9339 onto the stack.
6d3d9133 9340
34ce3d7b
JM
9341 Note - we only need to tell the dwarf2 backend about the SP
9342 adjustment in the second variant; the static chain register
9343 doesn't need to be unwound, as it doesn't contain a value
9344 inherited from the caller. */
d3236b4d 9345
68dfd979
NC
9346 if (regs_ever_live[3] == 0)
9347 {
9348 insn = gen_rtx_REG (SImode, 3);
9349 insn = gen_rtx_SET (SImode, insn, ip_rtx);
d3236b4d 9350 insn = emit_insn (insn);
68dfd979 9351 }
095bb276 9352 else if (args_to_push == 0)
68dfd979 9353 {
34ce3d7b 9354 rtx dwarf;
68dfd979
NC
9355 insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
9356 insn = gen_rtx_MEM (SImode, insn);
9357 insn = gen_rtx_SET (VOIDmode, insn, ip_rtx);
9358 insn = emit_insn (insn);
34ce3d7b 9359
68dfd979 9360 fp_offset = 4;
34ce3d7b
JM
9361
9362 /* Just tell the dwarf backend that we adjusted SP. */
9363 dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
9364 gen_rtx_PLUS (SImode, stack_pointer_rtx,
9365 GEN_INT (-fp_offset)));
9366 RTX_FRAME_RELATED_P (insn) = 1;
9367 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9368 dwarf, REG_NOTES (insn));
68dfd979
NC
9369 }
9370 else
095bb276
NC
9371 {
9372 /* Store the args on the stack. */
3cb66fd7 9373 if (cfun->machine->uses_anonymous_args)
095bb276
NC
9374 insn = emit_multi_reg_push
9375 ((0xf0 >> (args_to_push / 4)) & 0xf);
9376 else
9377 insn = emit_insn
9378 (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
9379 GEN_INT (- args_to_push)));
9380
9381 RTX_FRAME_RELATED_P (insn) = 1;
9382
9383 saved_pretend_args = 1;
9384 fp_offset = args_to_push;
9385 args_to_push = 0;
9386
9387 /* Now reuse r3 to preserve IP. */
9388 insn = gen_rtx_REG (SImode, 3);
9389 insn = gen_rtx_SET (SImode, insn, ip_rtx);
9390 (void) emit_insn (insn);
9391 }
68dfd979
NC
9392 }
9393
68dfd979
NC
9394 if (fp_offset)
9395 {
9396 insn = gen_rtx_PLUS (SImode, stack_pointer_rtx, GEN_INT (fp_offset));
9397 insn = gen_rtx_SET (SImode, ip_rtx, insn);
9398 }
9399 else
9400 insn = gen_movsi (ip_rtx, stack_pointer_rtx);
9401
6d3d9133 9402 insn = emit_insn (insn);
8e56560e 9403 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba
RE
9404 }
9405
095bb276 9406 if (args_to_push)
e2c671ba 9407 {
6d3d9133 9408 /* Push the argument registers, or reserve space for them. */
3cb66fd7 9409 if (cfun->machine->uses_anonymous_args)
2c849145 9410 insn = emit_multi_reg_push
095bb276 9411 ((0xf0 >> (args_to_push / 4)) & 0xf);
e2c671ba 9412 else
2c849145
JM
9413 insn = emit_insn
9414 (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
095bb276 9415 GEN_INT (- args_to_push)));
2c849145 9416 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba
RE
9417 }
9418
06bea5aa
NC
9419 /* If this is an interrupt service routine, and the link register
9420 is going to be pushed, and we are not creating a stack frame,
9421 (which would involve an extra push of IP and a pop in the epilogue)
9422 subtracting four from LR now will mean that the function return
9423 can be done with a single instruction. */
3a7731fd 9424 if ((func_type == ARM_FT_ISR || func_type == ARM_FT_FIQ)
06bea5aa
NC
9425 && (live_regs_mask & (1 << LR_REGNUM)) != 0
9426 && ! frame_pointer_needed)
9427 emit_insn (gen_rtx_SET (SImode,
9428 gen_rtx_REG (SImode, LR_REGNUM),
9429 gen_rtx_PLUS (SImode,
9430 gen_rtx_REG (SImode, LR_REGNUM),
9431 GEN_INT (-4))));
3a7731fd 9432
e2c671ba
RE
9433 if (live_regs_mask)
9434 {
2c849145
JM
9435 insn = emit_multi_reg_push (live_regs_mask);
9436 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba 9437 }
d5b7b3ae 9438
5a9335ef
NC
9439 if (TARGET_IWMMXT)
9440 for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
9441 if (regs_ever_live[reg] && ! call_used_regs [reg])
9442 {
9443 insn = gen_rtx_PRE_DEC (V2SImode, stack_pointer_rtx);
9444 insn = gen_rtx_MEM (V2SImode, insn);
9445 insn = emit_insn (gen_rtx_SET (VOIDmode, insn,
9446 gen_rtx_REG (V2SImode, reg)));
9447 RTX_FRAME_RELATED_P (insn) = 1;
9448 }
9449
6d3d9133 9450 if (! IS_VOLATILE (func_type))
b111229a 9451 {
29ad9694
RE
9452 /* Save any floating point call-saved registers used by this
9453 function. */
9454 if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
b111229a 9455 {
29ad9694 9456 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
5895f793 9457 if (regs_ever_live[reg] && !call_used_regs[reg])
2c849145
JM
9458 {
9459 insn = gen_rtx_PRE_DEC (XFmode, stack_pointer_rtx);
9460 insn = gen_rtx_MEM (XFmode, insn);
9461 insn = emit_insn (gen_rtx_SET (VOIDmode, insn,
9462 gen_rtx_REG (XFmode, reg)));
9463 RTX_FRAME_RELATED_P (insn) = 1;
9464 }
b111229a
RE
9465 }
9466 else
9467 {
d5b7b3ae 9468 int start_reg = LAST_ARM_FP_REGNUM;
b111229a 9469
29ad9694 9470 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
b111229a 9471 {
5895f793 9472 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
9473 {
9474 if (start_reg - reg == 3)
9475 {
2c849145
JM
9476 insn = emit_sfm (reg, 4);
9477 RTX_FRAME_RELATED_P (insn) = 1;
b111229a
RE
9478 start_reg = reg - 1;
9479 }
9480 }
9481 else
9482 {
9483 if (start_reg != reg)
2c849145
JM
9484 {
9485 insn = emit_sfm (reg + 1, start_reg - reg);
9486 RTX_FRAME_RELATED_P (insn) = 1;
9487 }
b111229a
RE
9488 start_reg = reg - 1;
9489 }
9490 }
9491
9492 if (start_reg != reg)
2c849145
JM
9493 {
9494 insn = emit_sfm (reg + 1, start_reg - reg);
9495 RTX_FRAME_RELATED_P (insn) = 1;
9496 }
b111229a
RE
9497 }
9498 }
e2c671ba
RE
9499
9500 if (frame_pointer_needed)
2c849145 9501 {
6d3d9133 9502 /* Create the new frame pointer. */
095bb276 9503 insn = GEN_INT (-(4 + args_to_push + fp_offset));
68dfd979 9504 insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, ip_rtx, insn));
2c849145 9505 RTX_FRAME_RELATED_P (insn) = 1;
68dfd979 9506
6d3d9133 9507 if (IS_NESTED (func_type))
68dfd979
NC
9508 {
9509 /* Recover the static chain register. */
095bb276
NC
9510 if (regs_ever_live [3] == 0
9511 || saved_pretend_args)
1d6e90ac 9512 insn = gen_rtx_REG (SImode, 3);
68dfd979
NC
9513 else /* if (current_function_pretend_args_size == 0) */
9514 {
29ad9694
RE
9515 insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx,
9516 GEN_INT (4));
68dfd979 9517 insn = gen_rtx_MEM (SImode, insn);
68dfd979 9518 }
1d6e90ac 9519
c14a3a45
NC
9520 emit_insn (gen_rtx_SET (SImode, ip_rtx, insn));
9521 /* Add a USE to stop propagate_one_insn() from barfing. */
6bacc7b0 9522 emit_insn (gen_prologue_use (ip_rtx));
68dfd979 9523 }
2c849145 9524 }
e2c671ba 9525
0977774b 9526 amount = GEN_INT (-(arm_get_frame_size ()
6d3d9133
NC
9527 + current_function_outgoing_args_size));
9528
e2c671ba
RE
9529 if (amount != const0_rtx)
9530 {
745b9093
JM
9531 /* This add can produce multiple insns for a large constant, so we
9532 need to get tricky. */
9533 rtx last = get_last_insn ();
2c849145
JM
9534 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
9535 amount));
745b9093
JM
9536 do
9537 {
9538 last = last ? NEXT_INSN (last) : get_insns ();
9539 RTX_FRAME_RELATED_P (last) = 1;
9540 }
9541 while (last != insn);
e04c2d6c
RE
9542
9543 /* If the frame pointer is needed, emit a special barrier that
9544 will prevent the scheduler from moving stores to the frame
9545 before the stack adjustment. */
9546 if (frame_pointer_needed)
3894f59e
RE
9547 insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
9548 hard_frame_pointer_rtx));
e2c671ba
RE
9549 }
9550
9551 /* If we are profiling, make sure no instructions are scheduled before
f5a1b0d2
NC
9552 the call to mcount. Similarly if the user has requested no
9553 scheduling in the prolog. */
70f4f91c 9554 if (current_function_profile || TARGET_NO_SCHED_PRO)
e2c671ba 9555 emit_insn (gen_blockage ());
6f7ebcbb
NC
9556
9557 /* If the link register is being kept alive, with the return address in it,
9558 then make sure that it does not get reused by the ce2 pass. */
9559 if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
9560 {
6bacc7b0 9561 emit_insn (gen_prologue_use (gen_rtx_REG (SImode, LR_REGNUM)));
6f7ebcbb
NC
9562 cfun->machine->lr_save_eliminated = 1;
9563 }
e2c671ba 9564}
cce8749e 9565\f
9997d19d
RE
9566/* If CODE is 'd', then the X is a condition operand and the instruction
9567 should only be executed if the condition is true.
ddd5a7c1 9568 if CODE is 'D', then the X is a condition operand and the instruction
9997d19d
RE
9569 should only be executed if the condition is false: however, if the mode
9570 of the comparison is CCFPEmode, then always execute the instruction -- we
9571 do this because in these circumstances !GE does not necessarily imply LT;
9572 in these cases the instruction pattern will take care to make sure that
9573 an instruction containing %d will follow, thereby undoing the effects of
ddd5a7c1 9574 doing this instruction unconditionally.
9997d19d
RE
9575 If CODE is 'N' then X is a floating point operand that must be negated
9576 before output.
9577 If CODE is 'B' then output a bitwise inverted value of X (a const int).
9578 If X is a REG and CODE is `M', output a ldm/stm style multi-reg. */
9997d19d 9579void
e32bac5b 9580arm_print_operand (FILE *stream, rtx x, int code)
9997d19d
RE
9581{
9582 switch (code)
9583 {
9584 case '@':
f3139301 9585 fputs (ASM_COMMENT_START, stream);
9997d19d
RE
9586 return;
9587
d5b7b3ae
RE
9588 case '_':
9589 fputs (user_label_prefix, stream);
9590 return;
9591
9997d19d 9592 case '|':
f3139301 9593 fputs (REGISTER_PREFIX, stream);
9997d19d
RE
9594 return;
9595
9596 case '?':
9597 if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
cca0a211
RE
9598 {
9599 if (TARGET_THUMB || current_insn_predicate != NULL)
9600 abort ();
9601
9602 fputs (arm_condition_codes[arm_current_cc], stream);
9603 }
9604 else if (current_insn_predicate)
9605 {
9606 enum arm_cond_code code;
9607
9608 if (TARGET_THUMB)
9609 abort ();
9610
9611 code = get_arm_condition_code (current_insn_predicate);
9612 fputs (arm_condition_codes[code], stream);
9613 }
9997d19d
RE
9614 return;
9615
9616 case 'N':
9617 {
9618 REAL_VALUE_TYPE r;
9619 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
9620 r = REAL_VALUE_NEGATE (r);
9621 fprintf (stream, "%s", fp_const_from_val (&r));
9622 }
9623 return;
9624
9625 case 'B':
9626 if (GET_CODE (x) == CONST_INT)
4bc74ece
NC
9627 {
9628 HOST_WIDE_INT val;
5895f793 9629 val = ARM_SIGN_EXTEND (~INTVAL (x));
36ba9cb8 9630 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
4bc74ece 9631 }
9997d19d
RE
9632 else
9633 {
9634 putc ('~', stream);
9635 output_addr_const (stream, x);
9636 }
9637 return;
9638
9639 case 'i':
9640 fprintf (stream, "%s", arithmetic_instr (x, 1));
9641 return;
9642
9b6b54e2
NC
9643 /* Truncate Cirrus shift counts. */
9644 case 's':
9645 if (GET_CODE (x) == CONST_INT)
9646 {
9647 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x3f);
9648 return;
9649 }
9650 arm_print_operand (stream, x, 0);
9651 return;
9652
9997d19d
RE
9653 case 'I':
9654 fprintf (stream, "%s", arithmetic_instr (x, 0));
9655 return;
9656
9657 case 'S':
9658 {
9659 HOST_WIDE_INT val;
5895f793 9660 const char * shift = shift_op (x, &val);
9997d19d 9661
e2c671ba
RE
9662 if (shift)
9663 {
5895f793 9664 fprintf (stream, ", %s ", shift_op (x, &val));
e2c671ba
RE
9665 if (val == -1)
9666 arm_print_operand (stream, XEXP (x, 1), 0);
9667 else
4a0a75dd 9668 fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, val);
e2c671ba 9669 }
9997d19d
RE
9670 }
9671 return;
9672
d5b7b3ae
RE
9673 /* An explanation of the 'Q', 'R' and 'H' register operands:
9674
9675 In a pair of registers containing a DI or DF value the 'Q'
9676 operand returns the register number of the register containing
093354e0 9677 the least significant part of the value. The 'R' operand returns
d5b7b3ae
RE
9678 the register number of the register containing the most
9679 significant part of the value.
9680
9681 The 'H' operand returns the higher of the two register numbers.
9682 On a run where WORDS_BIG_ENDIAN is true the 'H' operand is the
093354e0 9683 same as the 'Q' operand, since the most significant part of the
d5b7b3ae
RE
9684 value is held in the lower number register. The reverse is true
9685 on systems where WORDS_BIG_ENDIAN is false.
9686
9687 The purpose of these operands is to distinguish between cases
9688 where the endian-ness of the values is important (for example
9689 when they are added together), and cases where the endian-ness
9690 is irrelevant, but the order of register operations is important.
9691 For example when loading a value from memory into a register
9692 pair, the endian-ness does not matter. Provided that the value
9693 from the lower memory address is put into the lower numbered
9694 register, and the value from the higher address is put into the
9695 higher numbered register, the load will work regardless of whether
9696 the value being loaded is big-wordian or little-wordian. The
9697 order of the two register loads can matter however, if the address
9698 of the memory location is actually held in one of the registers
9699 being overwritten by the load. */
c1c2bc04 9700 case 'Q':
d5b7b3ae 9701 if (REGNO (x) > LAST_ARM_REGNUM)
c1c2bc04 9702 abort ();
d5b7b3ae 9703 asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0));
c1c2bc04
RE
9704 return;
9705
9997d19d 9706 case 'R':
d5b7b3ae 9707 if (REGNO (x) > LAST_ARM_REGNUM)
9997d19d 9708 abort ();
d5b7b3ae
RE
9709 asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1));
9710 return;
9711
9712 case 'H':
9713 if (REGNO (x) > LAST_ARM_REGNUM)
9714 abort ();
9715 asm_fprintf (stream, "%r", REGNO (x) + 1);
9997d19d
RE
9716 return;
9717
9718 case 'm':
d5b7b3ae
RE
9719 asm_fprintf (stream, "%r",
9720 GET_CODE (XEXP (x, 0)) == REG
9721 ? REGNO (XEXP (x, 0)) : REGNO (XEXP (XEXP (x, 0), 0)));
9997d19d
RE
9722 return;
9723
9724 case 'M':
dd18ae56 9725 asm_fprintf (stream, "{%r-%r}",
d5b7b3ae 9726 REGNO (x),
e9d7b180 9727 REGNO (x) + ARM_NUM_REGS (GET_MODE (x)) - 1);
9997d19d
RE
9728 return;
9729
9730 case 'd':
64e92a26
RE
9731 /* CONST_TRUE_RTX means always -- that's the default. */
9732 if (x == const_true_rtx)
d5b7b3ae
RE
9733 return;
9734
defc0463
RE
9735 fputs (arm_condition_codes[get_arm_condition_code (x)],
9736 stream);
9997d19d
RE
9737 return;
9738
9739 case 'D':
64e92a26
RE
9740 /* CONST_TRUE_RTX means not always -- ie never. We shouldn't ever
9741 want to do that. */
9742 if (x == const_true_rtx)
9743 abort ();
d5b7b3ae 9744
defc0463
RE
9745 fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
9746 (get_arm_condition_code (x))],
9747 stream);
9997d19d
RE
9748 return;
9749
9b6b54e2
NC
9750 /* Cirrus registers can be accessed in a variety of ways:
9751 single floating point (f)
9752 double floating point (d)
9753 32bit integer (fx)
9754 64bit integer (dx). */
9755 case 'W': /* Cirrus register in F mode. */
9756 case 'X': /* Cirrus register in D mode. */
9757 case 'Y': /* Cirrus register in FX mode. */
9758 case 'Z': /* Cirrus register in DX mode. */
9759 if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
9760 abort ();
9761
9762 fprintf (stream, "mv%s%s",
9763 code == 'W' ? "f"
9764 : code == 'X' ? "d"
9765 : code == 'Y' ? "fx" : "dx", reg_names[REGNO (x)] + 2);
9766
9767 return;
9768
9769 /* Print cirrus register in the mode specified by the register's mode. */
9770 case 'V':
9771 {
9772 int mode = GET_MODE (x);
9773
9774 if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
9775 abort ();
9776
9777 fprintf (stream, "mv%s%s",
9778 mode == DFmode ? "d"
9779 : mode == SImode ? "fx"
9780 : mode == DImode ? "dx"
9781 : "f", reg_names[REGNO (x)] + 2);
9782
9783 return;
9784 }
9785
5a9335ef
NC
9786 case 'U':
9787 if (GET_CODE (x) != REG
9788 || REGNO (x) < FIRST_IWMMXT_GR_REGNUM
9789 || REGNO (x) > LAST_IWMMXT_GR_REGNUM)
9790 /* Bad value for wCG register number. */
9791 abort ();
9792 else
9793 fprintf (stream, "%d", REGNO (x) - FIRST_IWMMXT_GR_REGNUM);
9794 return;
9795
9796 /* Print an iWMMXt control register name. */
9797 case 'w':
9798 if (GET_CODE (x) != CONST_INT
9799 || INTVAL (x) < 0
9800 || INTVAL (x) >= 16)
9801 /* Bad value for wC register number. */
9802 abort ();
9803 else
9804 {
9805 static const char * wc_reg_names [16] =
9806 {
9807 "wCID", "wCon", "wCSSF", "wCASF",
9808 "wC4", "wC5", "wC6", "wC7",
9809 "wCGR0", "wCGR1", "wCGR2", "wCGR3",
9810 "wC12", "wC13", "wC14", "wC15"
9811 };
9812
9813 fprintf (stream, wc_reg_names [INTVAL (x)]);
9814 }
9815 return;
9816
9997d19d
RE
9817 default:
9818 if (x == 0)
9819 abort ();
9820
9821 if (GET_CODE (x) == REG)
d5b7b3ae 9822 asm_fprintf (stream, "%r", REGNO (x));
9997d19d
RE
9823 else if (GET_CODE (x) == MEM)
9824 {
9825 output_memory_reference_mode = GET_MODE (x);
9826 output_address (XEXP (x, 0));
9827 }
9828 else if (GET_CODE (x) == CONST_DOUBLE)
9829 fprintf (stream, "#%s", fp_immediate_constant (x));
9830 else if (GET_CODE (x) == NEG)
6354dc9b 9831 abort (); /* This should never happen now. */
9997d19d
RE
9832 else
9833 {
9834 fputc ('#', stream);
9835 output_addr_const (stream, x);
9836 }
9837 }
9838}
cce8749e 9839\f
301d03af
RS
9840#ifndef AOF_ASSEMBLER
9841/* Target hook for assembling integer objects. The ARM version needs to
9842 handle word-sized values specially. */
301d03af 9843static bool
e32bac5b 9844arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
301d03af
RS
9845{
9846 if (size == UNITS_PER_WORD && aligned_p)
9847 {
9848 fputs ("\t.word\t", asm_out_file);
9849 output_addr_const (asm_out_file, x);
9850
9851 /* Mark symbols as position independent. We only do this in the
9852 .text segment, not in the .data segment. */
9853 if (NEED_GOT_RELOC && flag_pic && making_const_table &&
9854 (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
9855 {
e26053d1 9856 if (GET_CODE (x) == SYMBOL_REF
14f583b8 9857 && (CONSTANT_POOL_ADDRESS_P (x)
94428622 9858 || SYMBOL_REF_LOCAL_P (x)))
301d03af
RS
9859 fputs ("(GOTOFF)", asm_out_file);
9860 else if (GET_CODE (x) == LABEL_REF)
9861 fputs ("(GOTOFF)", asm_out_file);
9862 else
9863 fputs ("(GOT)", asm_out_file);
9864 }
9865 fputc ('\n', asm_out_file);
9866 return true;
9867 }
1d6e90ac 9868
5a9335ef
NC
9869 if (VECTOR_MODE_SUPPORTED_P (GET_MODE (x)))
9870 {
9871 int i, units;
9872
9873 if (GET_CODE (x) != CONST_VECTOR)
9874 abort ();
9875
9876 units = CONST_VECTOR_NUNITS (x);
9877
9878 switch (GET_MODE (x))
9879 {
9880 case V2SImode: size = 4; break;
9881 case V4HImode: size = 2; break;
9882 case V8QImode: size = 1; break;
9883 default:
9884 abort ();
9885 }
9886
9887 for (i = 0; i < units; i++)
9888 {
9889 rtx elt;
9890
9891 elt = CONST_VECTOR_ELT (x, i);
9892 assemble_integer
9893 (elt, size, i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT, 1);
9894 }
9895
9896 return true;
9897 }
9898
301d03af
RS
9899 return default_assemble_integer (x, size, aligned_p);
9900}
9901#endif
9902\f
cce8749e
CH
9903/* A finite state machine takes care of noticing whether or not instructions
9904 can be conditionally executed, and thus decrease execution time and code
9905 size by deleting branch instructions. The fsm is controlled by
9906 final_prescan_insn, and controls the actions of ASM_OUTPUT_OPCODE. */
9907
9908/* The state of the fsm controlling condition codes are:
9909 0: normal, do nothing special
9910 1: make ASM_OUTPUT_OPCODE not output this instruction
9911 2: make ASM_OUTPUT_OPCODE not output this instruction
9912 3: make instructions conditional
9913 4: make instructions conditional
9914
9915 State transitions (state->state by whom under condition):
9916 0 -> 1 final_prescan_insn if the `target' is a label
9917 0 -> 2 final_prescan_insn if the `target' is an unconditional branch
9918 1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
9919 2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
4977bab6 9920 3 -> 0 (*targetm.asm_out.internal_label) if the `target' label is reached
cce8749e
CH
9921 (the target label has CODE_LABEL_NUMBER equal to arm_target_label).
9922 4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
9923 (the target insn is arm_target_insn).
9924
ff9940b0
RE
9925 If the jump clobbers the conditions then we use states 2 and 4.
9926
9927 A similar thing can be done with conditional return insns.
9928
cce8749e
CH
9929 XXX In case the `target' is an unconditional branch, this conditionalising
9930 of the instructions always reduces code size, but not always execution
9931 time. But then, I want to reduce the code size to somewhere near what
9932 /bin/cc produces. */
9933
cce8749e
CH
9934/* Returns the index of the ARM condition code string in
9935 `arm_condition_codes'. COMPARISON should be an rtx like
9936 `(eq (...) (...))'. */
84ed5e79 9937static enum arm_cond_code
e32bac5b 9938get_arm_condition_code (rtx comparison)
cce8749e 9939{
5165176d 9940 enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
1d6e90ac
NC
9941 int code;
9942 enum rtx_code comp_code = GET_CODE (comparison);
5165176d
RE
9943
9944 if (GET_MODE_CLASS (mode) != MODE_CC)
84ed5e79 9945 mode = SELECT_CC_MODE (comp_code, XEXP (comparison, 0),
5165176d
RE
9946 XEXP (comparison, 1));
9947
9948 switch (mode)
cce8749e 9949 {
84ed5e79
RE
9950 case CC_DNEmode: code = ARM_NE; goto dominance;
9951 case CC_DEQmode: code = ARM_EQ; goto dominance;
9952 case CC_DGEmode: code = ARM_GE; goto dominance;
9953 case CC_DGTmode: code = ARM_GT; goto dominance;
9954 case CC_DLEmode: code = ARM_LE; goto dominance;
9955 case CC_DLTmode: code = ARM_LT; goto dominance;
9956 case CC_DGEUmode: code = ARM_CS; goto dominance;
9957 case CC_DGTUmode: code = ARM_HI; goto dominance;
9958 case CC_DLEUmode: code = ARM_LS; goto dominance;
9959 case CC_DLTUmode: code = ARM_CC;
9960
9961 dominance:
9962 if (comp_code != EQ && comp_code != NE)
9963 abort ();
9964
9965 if (comp_code == EQ)
9966 return ARM_INVERSE_CONDITION_CODE (code);
9967 return code;
9968
5165176d 9969 case CC_NOOVmode:
84ed5e79 9970 switch (comp_code)
5165176d 9971 {
84ed5e79
RE
9972 case NE: return ARM_NE;
9973 case EQ: return ARM_EQ;
9974 case GE: return ARM_PL;
9975 case LT: return ARM_MI;
5165176d
RE
9976 default: abort ();
9977 }
9978
9979 case CC_Zmode:
84ed5e79 9980 switch (comp_code)
5165176d 9981 {
84ed5e79
RE
9982 case NE: return ARM_NE;
9983 case EQ: return ARM_EQ;
5165176d
RE
9984 default: abort ();
9985 }
9986
defc0463
RE
9987 case CC_Nmode:
9988 switch (comp_code)
9989 {
9990 case NE: return ARM_MI;
9991 case EQ: return ARM_PL;
9992 default: abort ();
9993 }
9994
5165176d 9995 case CCFPEmode:
e45b72c4
RE
9996 case CCFPmode:
9997 /* These encodings assume that AC=1 in the FPA system control
9998 byte. This allows us to handle all cases except UNEQ and
9999 LTGT. */
84ed5e79
RE
10000 switch (comp_code)
10001 {
10002 case GE: return ARM_GE;
10003 case GT: return ARM_GT;
10004 case LE: return ARM_LS;
10005 case LT: return ARM_MI;
e45b72c4
RE
10006 case NE: return ARM_NE;
10007 case EQ: return ARM_EQ;
10008 case ORDERED: return ARM_VC;
10009 case UNORDERED: return ARM_VS;
10010 case UNLT: return ARM_LT;
10011 case UNLE: return ARM_LE;
10012 case UNGT: return ARM_HI;
10013 case UNGE: return ARM_PL;
10014 /* UNEQ and LTGT do not have a representation. */
10015 case UNEQ: /* Fall through. */
10016 case LTGT: /* Fall through. */
84ed5e79
RE
10017 default: abort ();
10018 }
10019
10020 case CC_SWPmode:
10021 switch (comp_code)
10022 {
10023 case NE: return ARM_NE;
10024 case EQ: return ARM_EQ;
10025 case GE: return ARM_LE;
10026 case GT: return ARM_LT;
10027 case LE: return ARM_GE;
10028 case LT: return ARM_GT;
10029 case GEU: return ARM_LS;
10030 case GTU: return ARM_CC;
10031 case LEU: return ARM_CS;
10032 case LTU: return ARM_HI;
10033 default: abort ();
10034 }
10035
bd9c7e23
RE
10036 case CC_Cmode:
10037 switch (comp_code)
10038 {
10039 case LTU: return ARM_CS;
10040 case GEU: return ARM_CC;
10041 default: abort ();
10042 }
10043
5165176d 10044 case CCmode:
84ed5e79 10045 switch (comp_code)
5165176d 10046 {
84ed5e79
RE
10047 case NE: return ARM_NE;
10048 case EQ: return ARM_EQ;
10049 case GE: return ARM_GE;
10050 case GT: return ARM_GT;
10051 case LE: return ARM_LE;
10052 case LT: return ARM_LT;
10053 case GEU: return ARM_CS;
10054 case GTU: return ARM_HI;
10055 case LEU: return ARM_LS;
10056 case LTU: return ARM_CC;
5165176d
RE
10057 default: abort ();
10058 }
10059
cce8749e
CH
10060 default: abort ();
10061 }
84ed5e79
RE
10062
10063 abort ();
f3bb6135 10064}
cce8749e 10065
cce8749e 10066void
e32bac5b 10067arm_final_prescan_insn (rtx insn)
cce8749e
CH
10068{
10069 /* BODY will hold the body of INSN. */
1d6e90ac 10070 rtx body = PATTERN (insn);
cce8749e
CH
10071
10072 /* This will be 1 if trying to repeat the trick, and things need to be
10073 reversed if it appears to fail. */
10074 int reverse = 0;
10075
ff9940b0
RE
10076 /* JUMP_CLOBBERS will be one implies that the conditions if a branch is
10077 taken are clobbered, even if the rtl suggests otherwise. It also
10078 means that we have to grub around within the jump expression to find
10079 out what the conditions are when the jump isn't taken. */
10080 int jump_clobbers = 0;
10081
6354dc9b 10082 /* If we start with a return insn, we only succeed if we find another one. */
ff9940b0
RE
10083 int seeking_return = 0;
10084
cce8749e
CH
10085 /* START_INSN will hold the insn from where we start looking. This is the
10086 first insn after the following code_label if REVERSE is true. */
10087 rtx start_insn = insn;
10088
10089 /* If in state 4, check if the target branch is reached, in order to
10090 change back to state 0. */
10091 if (arm_ccfsm_state == 4)
10092 {
10093 if (insn == arm_target_insn)
f5a1b0d2
NC
10094 {
10095 arm_target_insn = NULL;
10096 arm_ccfsm_state = 0;
10097 }
cce8749e
CH
10098 return;
10099 }
10100
10101 /* If in state 3, it is possible to repeat the trick, if this insn is an
10102 unconditional branch to a label, and immediately following this branch
10103 is the previous target label which is only used once, and the label this
10104 branch jumps to is not too far off. */
10105 if (arm_ccfsm_state == 3)
10106 {
10107 if (simplejump_p (insn))
10108 {
10109 start_insn = next_nonnote_insn (start_insn);
10110 if (GET_CODE (start_insn) == BARRIER)
10111 {
10112 /* XXX Isn't this always a barrier? */
10113 start_insn = next_nonnote_insn (start_insn);
10114 }
10115 if (GET_CODE (start_insn) == CODE_LABEL
10116 && CODE_LABEL_NUMBER (start_insn) == arm_target_label
10117 && LABEL_NUSES (start_insn) == 1)
10118 reverse = TRUE;
10119 else
10120 return;
10121 }
ff9940b0
RE
10122 else if (GET_CODE (body) == RETURN)
10123 {
10124 start_insn = next_nonnote_insn (start_insn);
10125 if (GET_CODE (start_insn) == BARRIER)
10126 start_insn = next_nonnote_insn (start_insn);
10127 if (GET_CODE (start_insn) == CODE_LABEL
10128 && CODE_LABEL_NUMBER (start_insn) == arm_target_label
10129 && LABEL_NUSES (start_insn) == 1)
10130 {
10131 reverse = TRUE;
10132 seeking_return = 1;
10133 }
10134 else
10135 return;
10136 }
cce8749e
CH
10137 else
10138 return;
10139 }
10140
10141 if (arm_ccfsm_state != 0 && !reverse)
10142 abort ();
10143 if (GET_CODE (insn) != JUMP_INSN)
10144 return;
10145
ddd5a7c1 10146 /* This jump might be paralleled with a clobber of the condition codes
ff9940b0
RE
10147 the jump should always come first */
10148 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
10149 body = XVECEXP (body, 0, 0);
10150
cce8749e
CH
10151 if (reverse
10152 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
10153 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
10154 {
bd9c7e23
RE
10155 int insns_skipped;
10156 int fail = FALSE, succeed = FALSE;
cce8749e
CH
10157 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
10158 int then_not_else = TRUE;
ff9940b0 10159 rtx this_insn = start_insn, label = 0;
cce8749e 10160
e45b72c4
RE
10161 /* If the jump cannot be done with one instruction, we cannot
10162 conditionally execute the instruction in the inverse case. */
ff9940b0 10163 if (get_attr_conds (insn) == CONDS_JUMP_CLOB)
5bbe2d40 10164 {
5bbe2d40
RE
10165 jump_clobbers = 1;
10166 return;
10167 }
ff9940b0 10168
cce8749e
CH
10169 /* Register the insn jumped to. */
10170 if (reverse)
ff9940b0
RE
10171 {
10172 if (!seeking_return)
10173 label = XEXP (SET_SRC (body), 0);
10174 }
cce8749e
CH
10175 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
10176 label = XEXP (XEXP (SET_SRC (body), 1), 0);
10177 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
10178 {
10179 label = XEXP (XEXP (SET_SRC (body), 2), 0);
10180 then_not_else = FALSE;
10181 }
ff9940b0
RE
10182 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
10183 seeking_return = 1;
10184 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
10185 {
10186 seeking_return = 1;
10187 then_not_else = FALSE;
10188 }
cce8749e
CH
10189 else
10190 abort ();
10191
10192 /* See how many insns this branch skips, and what kind of insns. If all
10193 insns are okay, and the label or unconditional branch to the same
10194 label is not too far away, succeed. */
10195 for (insns_skipped = 0;
b36ba79f 10196 !fail && !succeed && insns_skipped++ < max_insns_skipped;)
cce8749e
CH
10197 {
10198 rtx scanbody;
10199
10200 this_insn = next_nonnote_insn (this_insn);
10201 if (!this_insn)
10202 break;
10203
cce8749e
CH
10204 switch (GET_CODE (this_insn))
10205 {
10206 case CODE_LABEL:
10207 /* Succeed if it is the target label, otherwise fail since
10208 control falls in from somewhere else. */
10209 if (this_insn == label)
10210 {
ff9940b0
RE
10211 if (jump_clobbers)
10212 {
10213 arm_ccfsm_state = 2;
10214 this_insn = next_nonnote_insn (this_insn);
10215 }
10216 else
10217 arm_ccfsm_state = 1;
cce8749e
CH
10218 succeed = TRUE;
10219 }
10220 else
10221 fail = TRUE;
10222 break;
10223
ff9940b0 10224 case BARRIER:
cce8749e 10225 /* Succeed if the following insn is the target label.
ff9940b0
RE
10226 Otherwise fail.
10227 If return insns are used then the last insn in a function
6354dc9b 10228 will be a barrier. */
cce8749e 10229 this_insn = next_nonnote_insn (this_insn);
ff9940b0 10230 if (this_insn && this_insn == label)
cce8749e 10231 {
ff9940b0
RE
10232 if (jump_clobbers)
10233 {
10234 arm_ccfsm_state = 2;
10235 this_insn = next_nonnote_insn (this_insn);
10236 }
10237 else
10238 arm_ccfsm_state = 1;
cce8749e
CH
10239 succeed = TRUE;
10240 }
10241 else
10242 fail = TRUE;
10243 break;
10244
ff9940b0 10245 case CALL_INSN:
2b835d68 10246 /* If using 32-bit addresses the cc is not preserved over
914a3b8c 10247 calls. */
2b835d68 10248 if (TARGET_APCS_32)
bd9c7e23
RE
10249 {
10250 /* Succeed if the following insn is the target label,
10251 or if the following two insns are a barrier and
10252 the target label. */
10253 this_insn = next_nonnote_insn (this_insn);
10254 if (this_insn && GET_CODE (this_insn) == BARRIER)
10255 this_insn = next_nonnote_insn (this_insn);
10256
10257 if (this_insn && this_insn == label
b36ba79f 10258 && insns_skipped < max_insns_skipped)
bd9c7e23
RE
10259 {
10260 if (jump_clobbers)
10261 {
10262 arm_ccfsm_state = 2;
10263 this_insn = next_nonnote_insn (this_insn);
10264 }
10265 else
10266 arm_ccfsm_state = 1;
10267 succeed = TRUE;
10268 }
10269 else
10270 fail = TRUE;
10271 }
ff9940b0 10272 break;
2b835d68 10273
cce8749e
CH
10274 case JUMP_INSN:
10275 /* If this is an unconditional branch to the same label, succeed.
10276 If it is to another label, do nothing. If it is conditional,
10277 fail. */
e32bac5b
RE
10278 /* XXX Probably, the tests for SET and the PC are
10279 unnecessary. */
cce8749e 10280
ed4c4348 10281 scanbody = PATTERN (this_insn);
ff9940b0
RE
10282 if (GET_CODE (scanbody) == SET
10283 && GET_CODE (SET_DEST (scanbody)) == PC)
cce8749e
CH
10284 {
10285 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
10286 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
10287 {
10288 arm_ccfsm_state = 2;
10289 succeed = TRUE;
10290 }
10291 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
10292 fail = TRUE;
10293 }
b36ba79f
RE
10294 /* Fail if a conditional return is undesirable (eg on a
10295 StrongARM), but still allow this if optimizing for size. */
10296 else if (GET_CODE (scanbody) == RETURN
a72d4945 10297 && !use_return_insn (TRUE, NULL)
5895f793 10298 && !optimize_size)
b36ba79f 10299 fail = TRUE;
ff9940b0
RE
10300 else if (GET_CODE (scanbody) == RETURN
10301 && seeking_return)
10302 {
10303 arm_ccfsm_state = 2;
10304 succeed = TRUE;
10305 }
10306 else if (GET_CODE (scanbody) == PARALLEL)
10307 {
10308 switch (get_attr_conds (this_insn))
10309 {
10310 case CONDS_NOCOND:
10311 break;
10312 default:
10313 fail = TRUE;
10314 break;
10315 }
10316 }
4e67550b
RE
10317 else
10318 fail = TRUE; /* Unrecognized jump (eg epilogue). */
10319
cce8749e
CH
10320 break;
10321
10322 case INSN:
ff9940b0
RE
10323 /* Instructions using or affecting the condition codes make it
10324 fail. */
ed4c4348 10325 scanbody = PATTERN (this_insn);
5895f793
RE
10326 if (!(GET_CODE (scanbody) == SET
10327 || GET_CODE (scanbody) == PARALLEL)
74641843 10328 || get_attr_conds (this_insn) != CONDS_NOCOND)
cce8749e 10329 fail = TRUE;
9b6b54e2
NC
10330
10331 /* A conditional cirrus instruction must be followed by
10332 a non Cirrus instruction. However, since we
10333 conditionalize instructions in this function and by
10334 the time we get here we can't add instructions
10335 (nops), because shorten_branches() has already been
10336 called, we will disable conditionalizing Cirrus
10337 instructions to be safe. */
10338 if (GET_CODE (scanbody) != USE
10339 && GET_CODE (scanbody) != CLOBBER
f0375c66 10340 && get_attr_cirrus (this_insn) != CIRRUS_NOT)
9b6b54e2 10341 fail = TRUE;
cce8749e
CH
10342 break;
10343
10344 default:
10345 break;
10346 }
10347 }
10348 if (succeed)
10349 {
ff9940b0 10350 if ((!seeking_return) && (arm_ccfsm_state == 1 || reverse))
cce8749e 10351 arm_target_label = CODE_LABEL_NUMBER (label);
ff9940b0
RE
10352 else if (seeking_return || arm_ccfsm_state == 2)
10353 {
10354 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
10355 {
10356 this_insn = next_nonnote_insn (this_insn);
10357 if (this_insn && (GET_CODE (this_insn) == BARRIER
10358 || GET_CODE (this_insn) == CODE_LABEL))
10359 abort ();
10360 }
10361 if (!this_insn)
10362 {
10363 /* Oh, dear! we ran off the end.. give up */
df4ae160 10364 recog (PATTERN (insn), insn, NULL);
ff9940b0 10365 arm_ccfsm_state = 0;
abaa26e5 10366 arm_target_insn = NULL;
ff9940b0
RE
10367 return;
10368 }
10369 arm_target_insn = this_insn;
10370 }
cce8749e
CH
10371 else
10372 abort ();
ff9940b0
RE
10373 if (jump_clobbers)
10374 {
10375 if (reverse)
10376 abort ();
10377 arm_current_cc =
10378 get_arm_condition_code (XEXP (XEXP (XEXP (SET_SRC (body),
10379 0), 0), 1));
10380 if (GET_CODE (XEXP (XEXP (SET_SRC (body), 0), 0)) == AND)
10381 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
10382 if (GET_CODE (XEXP (SET_SRC (body), 0)) == NE)
10383 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
10384 }
10385 else
10386 {
10387 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
10388 what it was. */
10389 if (!reverse)
10390 arm_current_cc = get_arm_condition_code (XEXP (SET_SRC (body),
10391 0));
10392 }
cce8749e 10393
cce8749e
CH
10394 if (reverse || then_not_else)
10395 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
10396 }
d5b7b3ae 10397
1ccbefce 10398 /* Restore recog_data (getting the attributes of other insns can
ff9940b0 10399 destroy this array, but final.c assumes that it remains intact
ddd5a7c1 10400 across this call; since the insn has been recognized already we
b020fd92 10401 call recog direct). */
df4ae160 10402 recog (PATTERN (insn), insn, NULL);
cce8749e 10403 }
f3bb6135 10404}
cce8749e 10405
4b02997f
NC
10406/* Returns true if REGNO is a valid register
10407 for holding a quantity of tyoe MODE. */
4b02997f 10408int
e32bac5b 10409arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
4b02997f
NC
10410{
10411 if (GET_MODE_CLASS (mode) == MODE_CC)
10412 return regno == CC_REGNUM;
10413
10414 if (TARGET_THUMB)
10415 /* For the Thumb we only allow values bigger than SImode in
10416 registers 0 - 6, so that there is always a second low
10417 register available to hold the upper part of the value.
10418 We probably we ought to ensure that the register is the
10419 start of an even numbered register pair. */
e9d7b180 10420 return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
4b02997f 10421
9b6b54e2
NC
10422 if (IS_CIRRUS_REGNUM (regno))
10423 /* We have outlawed SI values in Cirrus registers because they
10424 reside in the lower 32 bits, but SF values reside in the
10425 upper 32 bits. This causes gcc all sorts of grief. We can't
10426 even split the registers into pairs because Cirrus SI values
10427 get sign extended to 64bits-- aldyh. */
10428 return (GET_MODE_CLASS (mode) == MODE_FLOAT) || (mode == DImode);
10429
5a9335ef
NC
10430 if (IS_IWMMXT_GR_REGNUM (regno))
10431 return mode == SImode;
10432
10433 if (IS_IWMMXT_REGNUM (regno))
10434 return VALID_IWMMXT_REG_MODE (mode);
10435
4b02997f 10436 if (regno <= LAST_ARM_REGNUM)
9a9f7594 10437 /* We allow any value to be stored in the general registers. */
3cb66fd7 10438 return 1;
4b02997f
NC
10439
10440 if ( regno == FRAME_POINTER_REGNUM
10441 || regno == ARG_POINTER_REGNUM)
10442 /* We only allow integers in the fake hard registers. */
10443 return GET_MODE_CLASS (mode) == MODE_INT;
10444
3b684012 10445 /* The only registers left are the FPA registers
4b02997f
NC
10446 which we only allow to hold FP values. */
10447 return GET_MODE_CLASS (mode) == MODE_FLOAT
10448 && regno >= FIRST_ARM_FP_REGNUM
10449 && regno <= LAST_ARM_FP_REGNUM;
10450}
10451
d5b7b3ae 10452int
e32bac5b 10453arm_regno_class (int regno)
d5b7b3ae
RE
10454{
10455 if (TARGET_THUMB)
10456 {
10457 if (regno == STACK_POINTER_REGNUM)
10458 return STACK_REG;
10459 if (regno == CC_REGNUM)
10460 return CC_REG;
10461 if (regno < 8)
10462 return LO_REGS;
10463 return HI_REGS;
10464 }
10465
10466 if ( regno <= LAST_ARM_REGNUM
10467 || regno == FRAME_POINTER_REGNUM
10468 || regno == ARG_POINTER_REGNUM)
10469 return GENERAL_REGS;
10470
10471 if (regno == CC_REGNUM)
10472 return NO_REGS;
10473
9b6b54e2
NC
10474 if (IS_CIRRUS_REGNUM (regno))
10475 return CIRRUS_REGS;
10476
5a9335ef
NC
10477 if (IS_IWMMXT_REGNUM (regno))
10478 return IWMMXT_REGS;
10479
e99faaaa
ILT
10480 if (IS_IWMMXT_GR_REGNUM (regno))
10481 return IWMMXT_GR_REGS;
10482
3b684012 10483 return FPA_REGS;
d5b7b3ae
RE
10484}
10485
10486/* Handle a special case when computing the offset
10487 of an argument from the frame pointer. */
10488int
e32bac5b 10489arm_debugger_arg_offset (int value, rtx addr)
d5b7b3ae
RE
10490{
10491 rtx insn;
10492
10493 /* We are only interested if dbxout_parms() failed to compute the offset. */
10494 if (value != 0)
10495 return 0;
10496
10497 /* We can only cope with the case where the address is held in a register. */
10498 if (GET_CODE (addr) != REG)
10499 return 0;
10500
10501 /* If we are using the frame pointer to point at the argument, then
10502 an offset of 0 is correct. */
cd2b33d0 10503 if (REGNO (addr) == (unsigned) HARD_FRAME_POINTER_REGNUM)
d5b7b3ae
RE
10504 return 0;
10505
10506 /* If we are using the stack pointer to point at the
10507 argument, then an offset of 0 is correct. */
5895f793 10508 if ((TARGET_THUMB || !frame_pointer_needed)
d5b7b3ae
RE
10509 && REGNO (addr) == SP_REGNUM)
10510 return 0;
10511
10512 /* Oh dear. The argument is pointed to by a register rather
10513 than being held in a register, or being stored at a known
10514 offset from the frame pointer. Since GDB only understands
10515 those two kinds of argument we must translate the address
10516 held in the register into an offset from the frame pointer.
10517 We do this by searching through the insns for the function
10518 looking to see where this register gets its value. If the
4912a07c 10519 register is initialized from the frame pointer plus an offset
d5b7b3ae
RE
10520 then we are in luck and we can continue, otherwise we give up.
10521
10522 This code is exercised by producing debugging information
10523 for a function with arguments like this:
10524
10525 double func (double a, double b, int c, double d) {return d;}
10526
10527 Without this code the stab for parameter 'd' will be set to
10528 an offset of 0 from the frame pointer, rather than 8. */
10529
10530 /* The if() statement says:
10531
10532 If the insn is a normal instruction
10533 and if the insn is setting the value in a register
10534 and if the register being set is the register holding the address of the argument
10535 and if the address is computing by an addition
10536 that involves adding to a register
10537 which is the frame pointer
10538 a constant integer
10539
10540 then... */
10541
10542 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10543 {
10544 if ( GET_CODE (insn) == INSN
10545 && GET_CODE (PATTERN (insn)) == SET
10546 && REGNO (XEXP (PATTERN (insn), 0)) == REGNO (addr)
10547 && GET_CODE (XEXP (PATTERN (insn), 1)) == PLUS
10548 && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 0)) == REG
cd2b33d0 10549 && REGNO (XEXP (XEXP (PATTERN (insn), 1), 0)) == (unsigned) HARD_FRAME_POINTER_REGNUM
d5b7b3ae
RE
10550 && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 1)) == CONST_INT
10551 )
10552 {
10553 value = INTVAL (XEXP (XEXP (PATTERN (insn), 1), 1));
10554
10555 break;
10556 }
10557 }
10558
10559 if (value == 0)
10560 {
10561 debug_rtx (addr);
c725bd79 10562 warning ("unable to compute real location of stacked parameter");
d5b7b3ae
RE
10563 value = 8; /* XXX magic hack */
10564 }
10565
10566 return value;
10567}
d5b7b3ae 10568\f
5a9335ef
NC
10569#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
10570 do \
10571 { \
10572 if ((MASK) & insn_flags) \
10573 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE); \
10574 } \
10575 while (0)
10576
10577struct builtin_description
10578{
10579 const unsigned int mask;
10580 const enum insn_code icode;
10581 const char * const name;
10582 const enum arm_builtins code;
10583 const enum rtx_code comparison;
10584 const unsigned int flag;
10585};
10586
10587static const struct builtin_description bdesc_2arg[] =
10588{
10589#define IWMMXT_BUILTIN(code, string, builtin) \
10590 { FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \
10591 ARM_BUILTIN_##builtin, 0, 0 },
10592
10593 IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
10594 IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
10595 IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
10596 IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
10597 IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
10598 IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
10599 IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
10600 IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
10601 IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
10602 IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
10603 IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
10604 IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
10605 IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
10606 IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
10607 IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
10608 IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
10609 IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
10610 IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
10611 IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
10612 IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsh", WMULSH)
10613 IWMMXT_BUILTIN (umulv4hi3_highpart, "wmuluh", WMULUH)
10614 IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
10615 IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
10616 IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
10617 IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
10618 IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
10619 IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
10620 IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
10621 IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
10622 IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
10623 IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
10624 IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
10625 IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
10626 IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
10627 IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
10628 IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
10629 IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
10630 IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
10631 IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
10632 IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
10633 IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
10634 IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
10635 IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
10636 IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
10637 IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
10638 IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
10639 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
10640 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
10641 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
10642 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
10643 IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
10644 IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
10645 IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
10646 IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
10647 IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
10648 IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
10649 IWMMXT_BUILTIN (iwmmxt_wmadds, "wmadds", WMADDS)
10650 IWMMXT_BUILTIN (iwmmxt_wmaddu, "wmaddu", WMADDU)
10651
10652#define IWMMXT_BUILTIN2(code, builtin) \
10653 { FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, 0, 0 },
10654
10655 IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
10656 IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
10657 IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
10658 IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
10659 IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
10660 IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
10661 IWMMXT_BUILTIN2 (ashlv4hi3_di, WSLLH)
10662 IWMMXT_BUILTIN2 (ashlv4hi3, WSLLHI)
10663 IWMMXT_BUILTIN2 (ashlv2si3_di, WSLLW)
10664 IWMMXT_BUILTIN2 (ashlv2si3, WSLLWI)
10665 IWMMXT_BUILTIN2 (ashldi3_di, WSLLD)
10666 IWMMXT_BUILTIN2 (ashldi3_iwmmxt, WSLLDI)
10667 IWMMXT_BUILTIN2 (lshrv4hi3_di, WSRLH)
10668 IWMMXT_BUILTIN2 (lshrv4hi3, WSRLHI)
10669 IWMMXT_BUILTIN2 (lshrv2si3_di, WSRLW)
10670 IWMMXT_BUILTIN2 (lshrv2si3, WSRLWI)
10671 IWMMXT_BUILTIN2 (lshrdi3_di, WSRLD)
10672 IWMMXT_BUILTIN2 (lshrdi3, WSRLDI)
10673 IWMMXT_BUILTIN2 (ashrv4hi3_di, WSRAH)
10674 IWMMXT_BUILTIN2 (ashrv4hi3, WSRAHI)
10675 IWMMXT_BUILTIN2 (ashrv2si3_di, WSRAW)
10676 IWMMXT_BUILTIN2 (ashrv2si3, WSRAWI)
10677 IWMMXT_BUILTIN2 (ashrdi3_di, WSRAD)
10678 IWMMXT_BUILTIN2 (ashrdi3, WSRADI)
10679 IWMMXT_BUILTIN2 (rorv4hi3_di, WRORH)
10680 IWMMXT_BUILTIN2 (rorv4hi3, WRORHI)
10681 IWMMXT_BUILTIN2 (rorv2si3_di, WRORW)
10682 IWMMXT_BUILTIN2 (rorv2si3, WRORWI)
10683 IWMMXT_BUILTIN2 (rordi3_di, WRORD)
10684 IWMMXT_BUILTIN2 (rordi3, WRORDI)
10685 IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
10686 IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
10687};
10688
10689static const struct builtin_description bdesc_1arg[] =
10690{
10691 IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
10692 IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
10693 IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
10694 IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
10695 IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
10696 IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
10697 IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
10698 IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
10699 IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
10700 IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
10701 IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
10702 IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
10703 IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
10704 IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
10705 IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
10706 IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
10707 IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
10708 IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
10709};
10710
10711/* Set up all the iWMMXt builtins. This is
10712 not called if TARGET_IWMMXT is zero. */
10713
10714static void
10715arm_init_iwmmxt_builtins (void)
10716{
10717 const struct builtin_description * d;
10718 size_t i;
10719 tree endlink = void_list_node;
10720
10721 tree int_ftype_int
10722 = build_function_type (integer_type_node,
10723 tree_cons (NULL_TREE, integer_type_node, endlink));
10724 tree v8qi_ftype_v8qi_v8qi_int
10725 = build_function_type (V8QI_type_node,
10726 tree_cons (NULL_TREE, V8QI_type_node,
10727 tree_cons (NULL_TREE, V8QI_type_node,
10728 tree_cons (NULL_TREE,
10729 integer_type_node,
10730 endlink))));
10731 tree v4hi_ftype_v4hi_int
10732 = build_function_type (V4HI_type_node,
10733 tree_cons (NULL_TREE, V4HI_type_node,
10734 tree_cons (NULL_TREE, integer_type_node,
10735 endlink)));
10736 tree v2si_ftype_v2si_int
10737 = build_function_type (V2SI_type_node,
10738 tree_cons (NULL_TREE, V2SI_type_node,
10739 tree_cons (NULL_TREE, integer_type_node,
10740 endlink)));
10741 tree v2si_ftype_di_di
10742 = build_function_type (V2SI_type_node,
10743 tree_cons (NULL_TREE, long_long_integer_type_node,
10744 tree_cons (NULL_TREE, long_long_integer_type_node,
10745 endlink)));
10746 tree di_ftype_di_int
10747 = build_function_type (long_long_integer_type_node,
10748 tree_cons (NULL_TREE, long_long_integer_type_node,
10749 tree_cons (NULL_TREE, integer_type_node,
10750 endlink)));
10751 tree di_ftype_di_int_int
10752 = build_function_type (long_long_integer_type_node,
10753 tree_cons (NULL_TREE, long_long_integer_type_node,
10754 tree_cons (NULL_TREE, integer_type_node,
10755 tree_cons (NULL_TREE,
10756 integer_type_node,
10757 endlink))));
10758 tree int_ftype_v8qi
10759 = build_function_type (integer_type_node,
10760 tree_cons (NULL_TREE, V8QI_type_node,
10761 endlink));
10762 tree int_ftype_v4hi
10763 = build_function_type (integer_type_node,
10764 tree_cons (NULL_TREE, V4HI_type_node,
10765 endlink));
10766 tree int_ftype_v2si
10767 = build_function_type (integer_type_node,
10768 tree_cons (NULL_TREE, V2SI_type_node,
10769 endlink));
10770 tree int_ftype_v8qi_int
10771 = build_function_type (integer_type_node,
10772 tree_cons (NULL_TREE, V8QI_type_node,
10773 tree_cons (NULL_TREE, integer_type_node,
10774 endlink)));
10775 tree int_ftype_v4hi_int
10776 = build_function_type (integer_type_node,
10777 tree_cons (NULL_TREE, V4HI_type_node,
10778 tree_cons (NULL_TREE, integer_type_node,
10779 endlink)));
10780 tree int_ftype_v2si_int
10781 = build_function_type (integer_type_node,
10782 tree_cons (NULL_TREE, V2SI_type_node,
10783 tree_cons (NULL_TREE, integer_type_node,
10784 endlink)));
10785 tree v8qi_ftype_v8qi_int_int
10786 = build_function_type (V8QI_type_node,
10787 tree_cons (NULL_TREE, V8QI_type_node,
10788 tree_cons (NULL_TREE, integer_type_node,
10789 tree_cons (NULL_TREE,
10790 integer_type_node,
10791 endlink))));
10792 tree v4hi_ftype_v4hi_int_int
10793 = build_function_type (V4HI_type_node,
10794 tree_cons (NULL_TREE, V4HI_type_node,
10795 tree_cons (NULL_TREE, integer_type_node,
10796 tree_cons (NULL_TREE,
10797 integer_type_node,
10798 endlink))));
10799 tree v2si_ftype_v2si_int_int
10800 = build_function_type (V2SI_type_node,
10801 tree_cons (NULL_TREE, V2SI_type_node,
10802 tree_cons (NULL_TREE, integer_type_node,
10803 tree_cons (NULL_TREE,
10804 integer_type_node,
10805 endlink))));
10806 /* Miscellaneous. */
10807 tree v8qi_ftype_v4hi_v4hi
10808 = build_function_type (V8QI_type_node,
10809 tree_cons (NULL_TREE, V4HI_type_node,
10810 tree_cons (NULL_TREE, V4HI_type_node,
10811 endlink)));
10812 tree v4hi_ftype_v2si_v2si
10813 = build_function_type (V4HI_type_node,
10814 tree_cons (NULL_TREE, V2SI_type_node,
10815 tree_cons (NULL_TREE, V2SI_type_node,
10816 endlink)));
10817 tree v2si_ftype_v4hi_v4hi
10818 = build_function_type (V2SI_type_node,
10819 tree_cons (NULL_TREE, V4HI_type_node,
10820 tree_cons (NULL_TREE, V4HI_type_node,
10821 endlink)));
10822 tree v2si_ftype_v8qi_v8qi
10823 = build_function_type (V2SI_type_node,
10824 tree_cons (NULL_TREE, V8QI_type_node,
10825 tree_cons (NULL_TREE, V8QI_type_node,
10826 endlink)));
10827 tree v4hi_ftype_v4hi_di
10828 = build_function_type (V4HI_type_node,
10829 tree_cons (NULL_TREE, V4HI_type_node,
10830 tree_cons (NULL_TREE,
10831 long_long_integer_type_node,
10832 endlink)));
10833 tree v2si_ftype_v2si_di
10834 = build_function_type (V2SI_type_node,
10835 tree_cons (NULL_TREE, V2SI_type_node,
10836 tree_cons (NULL_TREE,
10837 long_long_integer_type_node,
10838 endlink)));
10839 tree void_ftype_int_int
10840 = build_function_type (void_type_node,
10841 tree_cons (NULL_TREE, integer_type_node,
10842 tree_cons (NULL_TREE, integer_type_node,
10843 endlink)));
10844 tree di_ftype_void
10845 = build_function_type (long_long_unsigned_type_node, endlink);
10846 tree di_ftype_v8qi
10847 = build_function_type (long_long_integer_type_node,
10848 tree_cons (NULL_TREE, V8QI_type_node,
10849 endlink));
10850 tree di_ftype_v4hi
10851 = build_function_type (long_long_integer_type_node,
10852 tree_cons (NULL_TREE, V4HI_type_node,
10853 endlink));
10854 tree di_ftype_v2si
10855 = build_function_type (long_long_integer_type_node,
10856 tree_cons (NULL_TREE, V2SI_type_node,
10857 endlink));
10858 tree v2si_ftype_v4hi
10859 = build_function_type (V2SI_type_node,
10860 tree_cons (NULL_TREE, V4HI_type_node,
10861 endlink));
10862 tree v4hi_ftype_v8qi
10863 = build_function_type (V4HI_type_node,
10864 tree_cons (NULL_TREE, V8QI_type_node,
10865 endlink));
10866
10867 tree di_ftype_di_v4hi_v4hi
10868 = build_function_type (long_long_unsigned_type_node,
10869 tree_cons (NULL_TREE,
10870 long_long_unsigned_type_node,
10871 tree_cons (NULL_TREE, V4HI_type_node,
10872 tree_cons (NULL_TREE,
10873 V4HI_type_node,
10874 endlink))));
10875
10876 tree di_ftype_v4hi_v4hi
10877 = build_function_type (long_long_unsigned_type_node,
10878 tree_cons (NULL_TREE, V4HI_type_node,
10879 tree_cons (NULL_TREE, V4HI_type_node,
10880 endlink)));
10881
10882 /* Normal vector binops. */
10883 tree v8qi_ftype_v8qi_v8qi
10884 = build_function_type (V8QI_type_node,
10885 tree_cons (NULL_TREE, V8QI_type_node,
10886 tree_cons (NULL_TREE, V8QI_type_node,
10887 endlink)));
10888 tree v4hi_ftype_v4hi_v4hi
10889 = build_function_type (V4HI_type_node,
10890 tree_cons (NULL_TREE, V4HI_type_node,
10891 tree_cons (NULL_TREE, V4HI_type_node,
10892 endlink)));
10893 tree v2si_ftype_v2si_v2si
10894 = build_function_type (V2SI_type_node,
10895 tree_cons (NULL_TREE, V2SI_type_node,
10896 tree_cons (NULL_TREE, V2SI_type_node,
10897 endlink)));
10898 tree di_ftype_di_di
10899 = build_function_type (long_long_unsigned_type_node,
10900 tree_cons (NULL_TREE, long_long_unsigned_type_node,
10901 tree_cons (NULL_TREE,
10902 long_long_unsigned_type_node,
10903 endlink)));
10904
10905 /* Add all builtins that are more or less simple operations on two
10906 operands. */
e97a46ce 10907 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5a9335ef
NC
10908 {
10909 /* Use one of the operands; the target can have a different mode for
10910 mask-generating compares. */
10911 enum machine_mode mode;
10912 tree type;
10913
10914 if (d->name == 0)
10915 continue;
10916
10917 mode = insn_data[d->icode].operand[1].mode;
10918
10919 switch (mode)
10920 {
10921 case V8QImode:
10922 type = v8qi_ftype_v8qi_v8qi;
10923 break;
10924 case V4HImode:
10925 type = v4hi_ftype_v4hi_v4hi;
10926 break;
10927 case V2SImode:
10928 type = v2si_ftype_v2si_v2si;
10929 break;
10930 case DImode:
10931 type = di_ftype_di_di;
10932 break;
10933
10934 default:
10935 abort ();
10936 }
10937
10938 def_mbuiltin (d->mask, d->name, type, d->code);
10939 }
10940
10941 /* Add the remaining MMX insns with somewhat more complicated types. */
10942 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wzero", di_ftype_void, ARM_BUILTIN_WZERO);
10943 def_mbuiltin (FL_IWMMXT, "__builtin_arm_setwcx", void_ftype_int_int, ARM_BUILTIN_SETWCX);
10944 def_mbuiltin (FL_IWMMXT, "__builtin_arm_getwcx", int_ftype_int, ARM_BUILTIN_GETWCX);
10945
10946 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSLLH);
10947 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllw", v2si_ftype_v2si_di, ARM_BUILTIN_WSLLW);
10948 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslld", di_ftype_di_di, ARM_BUILTIN_WSLLD);
10949 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSLLHI);
10950 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSLLWI);
10951 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslldi", di_ftype_di_int, ARM_BUILTIN_WSLLDI);
10952
10953 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRLH);
10954 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRLW);
10955 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrld", di_ftype_di_di, ARM_BUILTIN_WSRLD);
10956 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRLHI);
10957 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRLWI);
10958 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrldi", di_ftype_di_int, ARM_BUILTIN_WSRLDI);
10959
10960 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrah", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRAH);
10961 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsraw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRAW);
10962 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrad", di_ftype_di_di, ARM_BUILTIN_WSRAD);
10963 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrahi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRAHI);
10964 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrawi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRAWI);
10965 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsradi", di_ftype_di_int, ARM_BUILTIN_WSRADI);
10966
10967 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WRORH);
10968 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorw", v2si_ftype_v2si_di, ARM_BUILTIN_WRORW);
10969 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrord", di_ftype_di_di, ARM_BUILTIN_WRORD);
10970 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WRORHI);
10971 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorwi", v2si_ftype_v2si_int, ARM_BUILTIN_WRORWI);
10972 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrordi", di_ftype_di_int, ARM_BUILTIN_WRORDI);
10973
10974 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wshufh", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSHUFH);
10975
10976 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadb", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADB);
10977 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadh", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADH);
10978 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadbz", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADBZ);
10979 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadhz", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADHZ);
10980
10981 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsb", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMSB);
10982 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMSH);
10983 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMSW);
10984 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmub", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMUB);
10985 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMUH);
10986 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMUW);
10987 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrb", v8qi_ftype_v8qi_int_int, ARM_BUILTIN_TINSRB);
10988 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrh", v4hi_ftype_v4hi_int_int, ARM_BUILTIN_TINSRH);
10989 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrw", v2si_ftype_v2si_int_int, ARM_BUILTIN_TINSRW);
10990
10991 def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccb", di_ftype_v8qi, ARM_BUILTIN_WACCB);
10992 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wacch", di_ftype_v4hi, ARM_BUILTIN_WACCH);
10993 def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccw", di_ftype_v2si, ARM_BUILTIN_WACCW);
10994
10995 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskb", int_ftype_v8qi, ARM_BUILTIN_TMOVMSKB);
10996 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskh", int_ftype_v4hi, ARM_BUILTIN_TMOVMSKH);
10997 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskw", int_ftype_v2si, ARM_BUILTIN_TMOVMSKW);
10998
10999 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhss", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHSS);
11000 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhus", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHUS);
11001 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwus", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWUS);
11002 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwss", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWSS);
11003 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdus", v2si_ftype_di_di, ARM_BUILTIN_WPACKDUS);
11004 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdss", v2si_ftype_di_di, ARM_BUILTIN_WPACKDSS);
11005
11006 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHUB);
11007 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHUH);
11008 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHUW);
11009 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHSB);
11010 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHSH);
11011 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHSW);
11012 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELUB);
11013 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELUH);
11014 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELUW);
11015 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELSB);
11016 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELSH);
11017 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELSW);
11018
11019 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacs", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACS);
11020 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacsz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACSZ);
11021 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacu", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACU);
11022 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacuz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACUZ);
11023
11024 def_mbuiltin (FL_IWMMXT, "__builtin_arm_walign", v8qi_ftype_v8qi_v8qi_int, ARM_BUILTIN_WALIGN);
11025 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmia", di_ftype_di_int_int, ARM_BUILTIN_TMIA);
11026 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiaph", di_ftype_di_int_int, ARM_BUILTIN_TMIAPH);
11027 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabb", di_ftype_di_int_int, ARM_BUILTIN_TMIABB);
11028 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabt", di_ftype_di_int_int, ARM_BUILTIN_TMIABT);
11029 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatb", di_ftype_di_int_int, ARM_BUILTIN_TMIATB);
11030 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatt", di_ftype_di_int_int, ARM_BUILTIN_TMIATT);
11031}
11032
11033static void
11034arm_init_builtins (void)
11035{
11036 if (TARGET_REALLY_IWMMXT)
11037 arm_init_iwmmxt_builtins ();
11038}
11039
11040/* Errors in the source file can cause expand_expr to return const0_rtx
11041 where we expect a vector. To avoid crashing, use one of the vector
11042 clear instructions. */
11043
11044static rtx
11045safe_vector_operand (rtx x, enum machine_mode mode)
11046{
11047 if (x != const0_rtx)
11048 return x;
11049 x = gen_reg_rtx (mode);
11050
11051 emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
11052 : gen_rtx_SUBREG (DImode, x, 0)));
11053 return x;
11054}
11055
11056/* Subroutine of arm_expand_builtin to take care of binop insns. */
11057
11058static rtx
11059arm_expand_binop_builtin (enum insn_code icode,
11060 tree arglist, rtx target)
11061{
11062 rtx pat;
11063 tree arg0 = TREE_VALUE (arglist);
11064 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11065 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11066 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11067 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11068 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11069 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11070
11071 if (VECTOR_MODE_P (mode0))
11072 op0 = safe_vector_operand (op0, mode0);
11073 if (VECTOR_MODE_P (mode1))
11074 op1 = safe_vector_operand (op1, mode1);
11075
11076 if (! target
11077 || GET_MODE (target) != tmode
11078 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11079 target = gen_reg_rtx (tmode);
11080
11081 /* In case the insn wants input operands in modes different from
11082 the result, abort. */
11083 if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
11084 abort ();
11085
11086 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11087 op0 = copy_to_mode_reg (mode0, op0);
11088 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11089 op1 = copy_to_mode_reg (mode1, op1);
11090
11091 pat = GEN_FCN (icode) (target, op0, op1);
11092 if (! pat)
11093 return 0;
11094 emit_insn (pat);
11095 return target;
11096}
11097
11098/* Subroutine of arm_expand_builtin to take care of unop insns. */
11099
11100static rtx
11101arm_expand_unop_builtin (enum insn_code icode,
11102 tree arglist, rtx target, int do_load)
11103{
11104 rtx pat;
11105 tree arg0 = TREE_VALUE (arglist);
11106 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11107 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11108 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11109
11110 if (! target
11111 || GET_MODE (target) != tmode
11112 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11113 target = gen_reg_rtx (tmode);
11114 if (do_load)
11115 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11116 else
11117 {
11118 if (VECTOR_MODE_P (mode0))
11119 op0 = safe_vector_operand (op0, mode0);
11120
11121 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11122 op0 = copy_to_mode_reg (mode0, op0);
11123 }
11124
11125 pat = GEN_FCN (icode) (target, op0);
11126 if (! pat)
11127 return 0;
11128 emit_insn (pat);
11129 return target;
11130}
11131
11132/* Expand an expression EXP that calls a built-in function,
11133 with result going to TARGET if that's convenient
11134 (and in mode MODE if that's convenient).
11135 SUBTARGET may be used as the target for computing one of EXP's operands.
11136 IGNORE is nonzero if the value is to be ignored. */
11137
11138static rtx
11139arm_expand_builtin (tree exp,
11140 rtx target,
11141 rtx subtarget ATTRIBUTE_UNUSED,
11142 enum machine_mode mode ATTRIBUTE_UNUSED,
11143 int ignore ATTRIBUTE_UNUSED)
11144{
11145 const struct builtin_description * d;
11146 enum insn_code icode;
11147 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
11148 tree arglist = TREE_OPERAND (exp, 1);
11149 tree arg0;
11150 tree arg1;
11151 tree arg2;
11152 rtx op0;
11153 rtx op1;
11154 rtx op2;
11155 rtx pat;
11156 int fcode = DECL_FUNCTION_CODE (fndecl);
11157 size_t i;
11158 enum machine_mode tmode;
11159 enum machine_mode mode0;
11160 enum machine_mode mode1;
11161 enum machine_mode mode2;
11162
11163 switch (fcode)
11164 {
11165 case ARM_BUILTIN_TEXTRMSB:
11166 case ARM_BUILTIN_TEXTRMUB:
11167 case ARM_BUILTIN_TEXTRMSH:
11168 case ARM_BUILTIN_TEXTRMUH:
11169 case ARM_BUILTIN_TEXTRMSW:
11170 case ARM_BUILTIN_TEXTRMUW:
11171 icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
11172 : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
11173 : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
11174 : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
11175 : CODE_FOR_iwmmxt_textrmw);
11176
11177 arg0 = TREE_VALUE (arglist);
11178 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11179 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11180 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11181 tmode = insn_data[icode].operand[0].mode;
11182 mode0 = insn_data[icode].operand[1].mode;
11183 mode1 = insn_data[icode].operand[2].mode;
11184
11185 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11186 op0 = copy_to_mode_reg (mode0, op0);
11187 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11188 {
11189 /* @@@ better error message */
11190 error ("selector must be an immediate");
11191 return gen_reg_rtx (tmode);
11192 }
11193 if (target == 0
11194 || GET_MODE (target) != tmode
11195 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11196 target = gen_reg_rtx (tmode);
11197 pat = GEN_FCN (icode) (target, op0, op1);
11198 if (! pat)
11199 return 0;
11200 emit_insn (pat);
11201 return target;
11202
11203 case ARM_BUILTIN_TINSRB:
11204 case ARM_BUILTIN_TINSRH:
11205 case ARM_BUILTIN_TINSRW:
11206 icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
11207 : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
11208 : CODE_FOR_iwmmxt_tinsrw);
11209 arg0 = TREE_VALUE (arglist);
11210 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11211 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11212 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11213 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11214 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
11215 tmode = insn_data[icode].operand[0].mode;
11216 mode0 = insn_data[icode].operand[1].mode;
11217 mode1 = insn_data[icode].operand[2].mode;
11218 mode2 = insn_data[icode].operand[3].mode;
11219
11220 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11221 op0 = copy_to_mode_reg (mode0, op0);
11222 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11223 op1 = copy_to_mode_reg (mode1, op1);
11224 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11225 {
11226 /* @@@ better error message */
11227 error ("selector must be an immediate");
11228 return const0_rtx;
11229 }
11230 if (target == 0
11231 || GET_MODE (target) != tmode
11232 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11233 target = gen_reg_rtx (tmode);
11234 pat = GEN_FCN (icode) (target, op0, op1, op2);
11235 if (! pat)
11236 return 0;
11237 emit_insn (pat);
11238 return target;
11239
11240 case ARM_BUILTIN_SETWCX:
11241 arg0 = TREE_VALUE (arglist);
11242 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11243 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11244 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11245 emit_insn (gen_iwmmxt_tmcr (op0, op1));
11246 return 0;
11247
11248 case ARM_BUILTIN_GETWCX:
11249 arg0 = TREE_VALUE (arglist);
11250 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11251 target = gen_reg_rtx (SImode);
11252 emit_insn (gen_iwmmxt_tmrc (target, op0));
11253 return target;
11254
11255 case ARM_BUILTIN_WSHUFH:
11256 icode = CODE_FOR_iwmmxt_wshufh;
11257 arg0 = TREE_VALUE (arglist);
11258 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11259 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11260 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11261 tmode = insn_data[icode].operand[0].mode;
11262 mode1 = insn_data[icode].operand[1].mode;
11263 mode2 = insn_data[icode].operand[2].mode;
11264
11265 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
11266 op0 = copy_to_mode_reg (mode1, op0);
11267 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
11268 {
11269 /* @@@ better error message */
11270 error ("mask must be an immediate");
11271 return const0_rtx;
11272 }
11273 if (target == 0
11274 || GET_MODE (target) != tmode
11275 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11276 target = gen_reg_rtx (tmode);
11277 pat = GEN_FCN (icode) (target, op0, op1);
11278 if (! pat)
11279 return 0;
11280 emit_insn (pat);
11281 return target;
11282
11283 case ARM_BUILTIN_WSADB:
11284 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadb, arglist, target);
11285 case ARM_BUILTIN_WSADH:
11286 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadh, arglist, target);
11287 case ARM_BUILTIN_WSADBZ:
11288 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, arglist, target);
11289 case ARM_BUILTIN_WSADHZ:
11290 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, arglist, target);
11291
11292 /* Several three-argument builtins. */
11293 case ARM_BUILTIN_WMACS:
11294 case ARM_BUILTIN_WMACU:
11295 case ARM_BUILTIN_WALIGN:
11296 case ARM_BUILTIN_TMIA:
11297 case ARM_BUILTIN_TMIAPH:
11298 case ARM_BUILTIN_TMIATT:
11299 case ARM_BUILTIN_TMIATB:
11300 case ARM_BUILTIN_TMIABT:
11301 case ARM_BUILTIN_TMIABB:
11302 icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
11303 : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
11304 : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
11305 : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
11306 : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
11307 : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
11308 : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
11309 : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
11310 : CODE_FOR_iwmmxt_walign);
11311 arg0 = TREE_VALUE (arglist);
11312 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11313 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11314 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11315 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11316 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
11317 tmode = insn_data[icode].operand[0].mode;
11318 mode0 = insn_data[icode].operand[1].mode;
11319 mode1 = insn_data[icode].operand[2].mode;
11320 mode2 = insn_data[icode].operand[3].mode;
11321
11322 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11323 op0 = copy_to_mode_reg (mode0, op0);
11324 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11325 op1 = copy_to_mode_reg (mode1, op1);
11326 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11327 op2 = copy_to_mode_reg (mode2, op2);
11328 if (target == 0
11329 || GET_MODE (target) != tmode
11330 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11331 target = gen_reg_rtx (tmode);
11332 pat = GEN_FCN (icode) (target, op0, op1, op2);
11333 if (! pat)
11334 return 0;
11335 emit_insn (pat);
11336 return target;
11337
11338 case ARM_BUILTIN_WZERO:
11339 target = gen_reg_rtx (DImode);
11340 emit_insn (gen_iwmmxt_clrdi (target));
11341 return target;
11342
11343 default:
11344 break;
11345 }
11346
e97a46ce 11347 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5a9335ef
NC
11348 if (d->code == (const enum arm_builtins) fcode)
11349 return arm_expand_binop_builtin (d->icode, arglist, target);
11350
e97a46ce 11351 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5a9335ef
NC
11352 if (d->code == (const enum arm_builtins) fcode)
11353 return arm_expand_unop_builtin (d->icode, arglist, target, 0);
11354
11355 /* @@@ Should really do something sensible here. */
11356 return NULL_RTX;
11357}
11358\f
d5b7b3ae
RE
11359/* Recursively search through all of the blocks in a function
11360 checking to see if any of the variables created in that
11361 function match the RTX called 'orig'. If they do then
11362 replace them with the RTX called 'new'. */
d5b7b3ae 11363static void
e32bac5b 11364replace_symbols_in_block (tree block, rtx orig, rtx new)
d5b7b3ae
RE
11365{
11366 for (; block; block = BLOCK_CHAIN (block))
11367 {
11368 tree sym;
11369
5895f793 11370 if (!TREE_USED (block))
d5b7b3ae
RE
11371 continue;
11372
11373 for (sym = BLOCK_VARS (block); sym; sym = TREE_CHAIN (sym))
11374 {
11375 if ( (DECL_NAME (sym) == 0 && TREE_CODE (sym) != TYPE_DECL)
11376 || DECL_IGNORED_P (sym)
11377 || TREE_CODE (sym) != VAR_DECL
11378 || DECL_EXTERNAL (sym)
5895f793 11379 || !rtx_equal_p (DECL_RTL (sym), orig)
d5b7b3ae
RE
11380 )
11381 continue;
11382
7b8b8ade 11383 SET_DECL_RTL (sym, new);
d5b7b3ae
RE
11384 }
11385
11386 replace_symbols_in_block (BLOCK_SUBBLOCKS (block), orig, new);
11387 }
11388}
11389
1d6e90ac
NC
11390/* Return the number (counting from 0) of
11391 the least significant set bit in MASK. */
11392
e32bac5b
RE
11393inline static int
11394number_of_first_bit_set (int mask)
d5b7b3ae
RE
11395{
11396 int bit;
11397
11398 for (bit = 0;
11399 (mask & (1 << bit)) == 0;
5895f793 11400 ++bit)
d5b7b3ae
RE
11401 continue;
11402
11403 return bit;
11404}
11405
11406/* Generate code to return from a thumb function.
11407 If 'reg_containing_return_addr' is -1, then the return address is
11408 actually on the stack, at the stack pointer. */
11409static void
e32bac5b 11410thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs)
d5b7b3ae
RE
11411{
11412 unsigned regs_available_for_popping;
11413 unsigned regs_to_pop;
11414 int pops_needed;
11415 unsigned available;
11416 unsigned required;
11417 int mode;
11418 int size;
11419 int restore_a4 = FALSE;
11420
11421 /* Compute the registers we need to pop. */
11422 regs_to_pop = 0;
11423 pops_needed = 0;
11424
11425 /* There is an assumption here, that if eh_ofs is not NULL, the
11426 normal return address will have been pushed. */
11427 if (reg_containing_return_addr == -1 || eh_ofs)
11428 {
11429 /* When we are generating a return for __builtin_eh_return,
11430 reg_containing_return_addr must specify the return regno. */
11431 if (eh_ofs && reg_containing_return_addr == -1)
11432 abort ();
11433
11434 regs_to_pop |= 1 << LR_REGNUM;
5895f793 11435 ++pops_needed;
d5b7b3ae
RE
11436 }
11437
11438 if (TARGET_BACKTRACE)
11439 {
11440 /* Restore the (ARM) frame pointer and stack pointer. */
11441 regs_to_pop |= (1 << ARM_HARD_FRAME_POINTER_REGNUM) | (1 << SP_REGNUM);
11442 pops_needed += 2;
11443 }
11444
11445 /* If there is nothing to pop then just emit the BX instruction and
11446 return. */
11447 if (pops_needed == 0)
11448 {
11449 if (eh_ofs)
11450 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
11451
11452 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
11453 return;
11454 }
11455 /* Otherwise if we are not supporting interworking and we have not created
11456 a backtrace structure and the function was not entered in ARM mode then
11457 just pop the return address straight into the PC. */
5895f793
RE
11458 else if (!TARGET_INTERWORK
11459 && !TARGET_BACKTRACE
11460 && !is_called_in_ARM_mode (current_function_decl))
d5b7b3ae
RE
11461 {
11462 if (eh_ofs)
11463 {
11464 asm_fprintf (f, "\tadd\t%r, #4\n", SP_REGNUM);
11465 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
11466 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
11467 }
11468 else
11469 asm_fprintf (f, "\tpop\t{%r}\n", PC_REGNUM);
11470
11471 return;
11472 }
11473
11474 /* Find out how many of the (return) argument registers we can corrupt. */
11475 regs_available_for_popping = 0;
11476
11477 /* If returning via __builtin_eh_return, the bottom three registers
11478 all contain information needed for the return. */
11479 if (eh_ofs)
11480 size = 12;
11481 else
11482 {
11483#ifdef RTX_CODE
11484 /* If we can deduce the registers used from the function's
11485 return value. This is more reliable that examining
11486 regs_ever_live[] because that will be set if the register is
11487 ever used in the function, not just if the register is used
11488 to hold a return value. */
11489
11490 if (current_function_return_rtx != 0)
11491 mode = GET_MODE (current_function_return_rtx);
11492 else
11493#endif
11494 mode = DECL_MODE (DECL_RESULT (current_function_decl));
11495
11496 size = GET_MODE_SIZE (mode);
11497
11498 if (size == 0)
11499 {
11500 /* In a void function we can use any argument register.
11501 In a function that returns a structure on the stack
11502 we can use the second and third argument registers. */
11503 if (mode == VOIDmode)
11504 regs_available_for_popping =
11505 (1 << ARG_REGISTER (1))
11506 | (1 << ARG_REGISTER (2))
11507 | (1 << ARG_REGISTER (3));
11508 else
11509 regs_available_for_popping =
11510 (1 << ARG_REGISTER (2))
11511 | (1 << ARG_REGISTER (3));
11512 }
11513 else if (size <= 4)
11514 regs_available_for_popping =
11515 (1 << ARG_REGISTER (2))
11516 | (1 << ARG_REGISTER (3));
11517 else if (size <= 8)
11518 regs_available_for_popping =
11519 (1 << ARG_REGISTER (3));
11520 }
11521
11522 /* Match registers to be popped with registers into which we pop them. */
11523 for (available = regs_available_for_popping,
11524 required = regs_to_pop;
11525 required != 0 && available != 0;
11526 available &= ~(available & - available),
11527 required &= ~(required & - required))
11528 -- pops_needed;
11529
11530 /* If we have any popping registers left over, remove them. */
11531 if (available > 0)
5895f793 11532 regs_available_for_popping &= ~available;
d5b7b3ae
RE
11533
11534 /* Otherwise if we need another popping register we can use
11535 the fourth argument register. */
11536 else if (pops_needed)
11537 {
11538 /* If we have not found any free argument registers and
11539 reg a4 contains the return address, we must move it. */
11540 if (regs_available_for_popping == 0
11541 && reg_containing_return_addr == LAST_ARG_REGNUM)
11542 {
11543 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM, LAST_ARG_REGNUM);
11544 reg_containing_return_addr = LR_REGNUM;
11545 }
11546 else if (size > 12)
11547 {
11548 /* Register a4 is being used to hold part of the return value,
11549 but we have dire need of a free, low register. */
11550 restore_a4 = TRUE;
11551
11552 asm_fprintf (f, "\tmov\t%r, %r\n",IP_REGNUM, LAST_ARG_REGNUM);
11553 }
11554
11555 if (reg_containing_return_addr != LAST_ARG_REGNUM)
11556 {
11557 /* The fourth argument register is available. */
11558 regs_available_for_popping |= 1 << LAST_ARG_REGNUM;
11559
5895f793 11560 --pops_needed;
d5b7b3ae
RE
11561 }
11562 }
11563
11564 /* Pop as many registers as we can. */
11565 thumb_pushpop (f, regs_available_for_popping, FALSE);
11566
11567 /* Process the registers we popped. */
11568 if (reg_containing_return_addr == -1)
11569 {
11570 /* The return address was popped into the lowest numbered register. */
5895f793 11571 regs_to_pop &= ~(1 << LR_REGNUM);
d5b7b3ae
RE
11572
11573 reg_containing_return_addr =
11574 number_of_first_bit_set (regs_available_for_popping);
11575
11576 /* Remove this register for the mask of available registers, so that
6bc82793 11577 the return address will not be corrupted by further pops. */
5895f793 11578 regs_available_for_popping &= ~(1 << reg_containing_return_addr);
d5b7b3ae
RE
11579 }
11580
11581 /* If we popped other registers then handle them here. */
11582 if (regs_available_for_popping)
11583 {
11584 int frame_pointer;
11585
11586 /* Work out which register currently contains the frame pointer. */
11587 frame_pointer = number_of_first_bit_set (regs_available_for_popping);
11588
11589 /* Move it into the correct place. */
11590 asm_fprintf (f, "\tmov\t%r, %r\n",
11591 ARM_HARD_FRAME_POINTER_REGNUM, frame_pointer);
11592
11593 /* (Temporarily) remove it from the mask of popped registers. */
5895f793
RE
11594 regs_available_for_popping &= ~(1 << frame_pointer);
11595 regs_to_pop &= ~(1 << ARM_HARD_FRAME_POINTER_REGNUM);
d5b7b3ae
RE
11596
11597 if (regs_available_for_popping)
11598 {
11599 int stack_pointer;
11600
11601 /* We popped the stack pointer as well,
11602 find the register that contains it. */
11603 stack_pointer = number_of_first_bit_set (regs_available_for_popping);
11604
11605 /* Move it into the stack register. */
11606 asm_fprintf (f, "\tmov\t%r, %r\n", SP_REGNUM, stack_pointer);
11607
11608 /* At this point we have popped all necessary registers, so
11609 do not worry about restoring regs_available_for_popping
11610 to its correct value:
11611
11612 assert (pops_needed == 0)
11613 assert (regs_available_for_popping == (1 << frame_pointer))
11614 assert (regs_to_pop == (1 << STACK_POINTER)) */
11615 }
11616 else
11617 {
11618 /* Since we have just move the popped value into the frame
11619 pointer, the popping register is available for reuse, and
11620 we know that we still have the stack pointer left to pop. */
11621 regs_available_for_popping |= (1 << frame_pointer);
11622 }
11623 }
11624
11625 /* If we still have registers left on the stack, but we no longer have
11626 any registers into which we can pop them, then we must move the return
11627 address into the link register and make available the register that
11628 contained it. */
11629 if (regs_available_for_popping == 0 && pops_needed > 0)
11630 {
11631 regs_available_for_popping |= 1 << reg_containing_return_addr;
11632
11633 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM,
11634 reg_containing_return_addr);
11635
11636 reg_containing_return_addr = LR_REGNUM;
11637 }
11638
11639 /* If we have registers left on the stack then pop some more.
11640 We know that at most we will want to pop FP and SP. */
11641 if (pops_needed > 0)
11642 {
11643 int popped_into;
11644 int move_to;
11645
11646 thumb_pushpop (f, regs_available_for_popping, FALSE);
11647
11648 /* We have popped either FP or SP.
11649 Move whichever one it is into the correct register. */
11650 popped_into = number_of_first_bit_set (regs_available_for_popping);
11651 move_to = number_of_first_bit_set (regs_to_pop);
11652
11653 asm_fprintf (f, "\tmov\t%r, %r\n", move_to, popped_into);
11654
5895f793 11655 regs_to_pop &= ~(1 << move_to);
d5b7b3ae 11656
5895f793 11657 --pops_needed;
d5b7b3ae
RE
11658 }
11659
11660 /* If we still have not popped everything then we must have only
11661 had one register available to us and we are now popping the SP. */
11662 if (pops_needed > 0)
11663 {
11664 int popped_into;
11665
11666 thumb_pushpop (f, regs_available_for_popping, FALSE);
11667
11668 popped_into = number_of_first_bit_set (regs_available_for_popping);
11669
11670 asm_fprintf (f, "\tmov\t%r, %r\n", SP_REGNUM, popped_into);
11671 /*
11672 assert (regs_to_pop == (1 << STACK_POINTER))
11673 assert (pops_needed == 1)
11674 */
11675 }
11676
11677 /* If necessary restore the a4 register. */
11678 if (restore_a4)
11679 {
11680 if (reg_containing_return_addr != LR_REGNUM)
11681 {
11682 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM, LAST_ARG_REGNUM);
11683 reg_containing_return_addr = LR_REGNUM;
11684 }
11685
11686 asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
11687 }
11688
11689 if (eh_ofs)
11690 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
11691
11692 /* Return to caller. */
11693 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
11694}
11695
11696/* Emit code to push or pop registers to or from the stack. */
11697static void
e32bac5b 11698thumb_pushpop (FILE *f, int mask, int push)
d5b7b3ae
RE
11699{
11700 int regno;
11701 int lo_mask = mask & 0xFF;
11702
5895f793 11703 if (lo_mask == 0 && !push && (mask & (1 << 15)))
d5b7b3ae
RE
11704 {
11705 /* Special case. Do not generate a POP PC statement here, do it in
11706 thumb_exit() */
11707 thumb_exit (f, -1, NULL_RTX);
11708 return;
11709 }
11710
11711 fprintf (f, "\t%s\t{", push ? "push" : "pop");
11712
11713 /* Look at the low registers first. */
5895f793 11714 for (regno = 0; regno <= LAST_LO_REGNUM; regno++, lo_mask >>= 1)
d5b7b3ae
RE
11715 {
11716 if (lo_mask & 1)
11717 {
11718 asm_fprintf (f, "%r", regno);
11719
11720 if ((lo_mask & ~1) != 0)
11721 fprintf (f, ", ");
11722 }
11723 }
11724
11725 if (push && (mask & (1 << LR_REGNUM)))
11726 {
11727 /* Catch pushing the LR. */
11728 if (mask & 0xFF)
11729 fprintf (f, ", ");
11730
11731 asm_fprintf (f, "%r", LR_REGNUM);
11732 }
11733 else if (!push && (mask & (1 << PC_REGNUM)))
11734 {
11735 /* Catch popping the PC. */
11736 if (TARGET_INTERWORK || TARGET_BACKTRACE)
11737 {
11738 /* The PC is never poped directly, instead
11739 it is popped into r3 and then BX is used. */
11740 fprintf (f, "}\n");
11741
11742 thumb_exit (f, -1, NULL_RTX);
11743
11744 return;
11745 }
11746 else
11747 {
11748 if (mask & 0xFF)
11749 fprintf (f, ", ");
11750
11751 asm_fprintf (f, "%r", PC_REGNUM);
11752 }
11753 }
11754
11755 fprintf (f, "}\n");
11756}
11757\f
11758void
e32bac5b 11759thumb_final_prescan_insn (rtx insn)
d5b7b3ae 11760{
d5b7b3ae 11761 if (flag_print_asm_name)
9d98a694
AO
11762 asm_fprintf (asm_out_file, "%@ 0x%04x\n",
11763 INSN_ADDRESSES (INSN_UID (insn)));
d5b7b3ae
RE
11764}
11765
11766int
e32bac5b 11767thumb_shiftable_const (unsigned HOST_WIDE_INT val)
d5b7b3ae
RE
11768{
11769 unsigned HOST_WIDE_INT mask = 0xff;
11770 int i;
11771
11772 if (val == 0) /* XXX */
11773 return 0;
11774
11775 for (i = 0; i < 25; i++)
11776 if ((val & (mask << i)) == val)
11777 return 1;
11778
11779 return 0;
11780}
11781
825dda42 11782/* Returns nonzero if the current function contains,
d5b7b3ae
RE
11783 or might contain a far jump. */
11784int
e32bac5b 11785thumb_far_jump_used_p (int in_prologue)
d5b7b3ae
RE
11786{
11787 rtx insn;
11788
11789 /* This test is only important for leaf functions. */
5895f793 11790 /* assert (!leaf_function_p ()); */
d5b7b3ae
RE
11791
11792 /* If we have already decided that far jumps may be used,
11793 do not bother checking again, and always return true even if
11794 it turns out that they are not being used. Once we have made
11795 the decision that far jumps are present (and that hence the link
11796 register will be pushed onto the stack) we cannot go back on it. */
11797 if (cfun->machine->far_jump_used)
11798 return 1;
11799
11800 /* If this function is not being called from the prologue/epilogue
11801 generation code then it must be being called from the
11802 INITIAL_ELIMINATION_OFFSET macro. */
5895f793 11803 if (!in_prologue)
d5b7b3ae
RE
11804 {
11805 /* In this case we know that we are being asked about the elimination
11806 of the arg pointer register. If that register is not being used,
11807 then there are no arguments on the stack, and we do not have to
11808 worry that a far jump might force the prologue to push the link
11809 register, changing the stack offsets. In this case we can just
11810 return false, since the presence of far jumps in the function will
11811 not affect stack offsets.
11812
11813 If the arg pointer is live (or if it was live, but has now been
11814 eliminated and so set to dead) then we do have to test to see if
11815 the function might contain a far jump. This test can lead to some
11816 false negatives, since before reload is completed, then length of
11817 branch instructions is not known, so gcc defaults to returning their
11818 longest length, which in turn sets the far jump attribute to true.
11819
11820 A false negative will not result in bad code being generated, but it
11821 will result in a needless push and pop of the link register. We
11822 hope that this does not occur too often. */
11823 if (regs_ever_live [ARG_POINTER_REGNUM])
11824 cfun->machine->arg_pointer_live = 1;
5895f793 11825 else if (!cfun->machine->arg_pointer_live)
d5b7b3ae
RE
11826 return 0;
11827 }
11828
11829 /* Check to see if the function contains a branch
11830 insn with the far jump attribute set. */
11831 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
11832 {
11833 if (GET_CODE (insn) == JUMP_INSN
11834 /* Ignore tablejump patterns. */
11835 && GET_CODE (PATTERN (insn)) != ADDR_VEC
11836 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
11837 && get_attr_far_jump (insn) == FAR_JUMP_YES
11838 )
11839 {
9a9f7594 11840 /* Record the fact that we have decided that
d5b7b3ae
RE
11841 the function does use far jumps. */
11842 cfun->machine->far_jump_used = 1;
11843 return 1;
11844 }
11845 }
11846
11847 return 0;
11848}
11849
825dda42 11850/* Return nonzero if FUNC must be entered in ARM mode. */
d5b7b3ae 11851int
e32bac5b 11852is_called_in_ARM_mode (tree func)
d5b7b3ae
RE
11853{
11854 if (TREE_CODE (func) != FUNCTION_DECL)
11855 abort ();
11856
11857 /* Ignore the problem about functions whoes address is taken. */
11858 if (TARGET_CALLEE_INTERWORKING && TREE_PUBLIC (func))
11859 return TRUE;
11860
11861#ifdef ARM_PE
91d231cb 11862 return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
d5b7b3ae
RE
11863#else
11864 return FALSE;
11865#endif
11866}
11867
11868/* The bits which aren't usefully expanded as rtl. */
cd2b33d0 11869const char *
e32bac5b 11870thumb_unexpanded_epilogue (void)
d5b7b3ae
RE
11871{
11872 int regno;
11873 int live_regs_mask = 0;
11874 int high_regs_pushed = 0;
11875 int leaf_function = leaf_function_p ();
11876 int had_to_push_lr;
11877 rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
11878
11879 if (return_used_this_function)
11880 return "";
11881
58e60158
AN
11882 if (IS_NAKED (arm_current_func_type ()))
11883 return "";
11884
d5b7b3ae 11885 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
aeaf4d25 11886 if (THUMB_REG_PUSHED_P (regno))
d5b7b3ae
RE
11887 live_regs_mask |= 1 << regno;
11888
11889 for (regno = 8; regno < 13; regno++)
aeaf4d25
AN
11890 if (THUMB_REG_PUSHED_P (regno))
11891 high_regs_pushed++;
d5b7b3ae
RE
11892
11893 /* The prolog may have pushed some high registers to use as
093354e0 11894 work registers. eg the testsuite file:
d5b7b3ae
RE
11895 gcc/testsuite/gcc/gcc.c-torture/execute/complex-2.c
11896 compiles to produce:
11897 push {r4, r5, r6, r7, lr}
11898 mov r7, r9
11899 mov r6, r8
11900 push {r6, r7}
11901 as part of the prolog. We have to undo that pushing here. */
11902
11903 if (high_regs_pushed)
11904 {
11905 int mask = live_regs_mask;
11906 int next_hi_reg;
11907 int size;
11908 int mode;
11909
11910#ifdef RTX_CODE
11911 /* If we can deduce the registers used from the function's return value.
11912 This is more reliable that examining regs_ever_live[] because that
11913 will be set if the register is ever used in the function, not just if
11914 the register is used to hold a return value. */
11915
11916 if (current_function_return_rtx != 0)
11917 mode = GET_MODE (current_function_return_rtx);
11918 else
11919#endif
11920 mode = DECL_MODE (DECL_RESULT (current_function_decl));
11921
11922 size = GET_MODE_SIZE (mode);
11923
11924 /* Unless we are returning a type of size > 12 register r3 is
11925 available. */
11926 if (size < 13)
11927 mask |= 1 << 3;
11928
11929 if (mask == 0)
11930 /* Oh dear! We have no low registers into which we can pop
11931 high registers! */
400500c4
RK
11932 internal_error
11933 ("no low registers available for popping high registers");
d5b7b3ae
RE
11934
11935 for (next_hi_reg = 8; next_hi_reg < 13; next_hi_reg++)
aeaf4d25 11936 if (THUMB_REG_PUSHED_P (next_hi_reg))
d5b7b3ae
RE
11937 break;
11938
11939 while (high_regs_pushed)
11940 {
11941 /* Find lo register(s) into which the high register(s) can
11942 be popped. */
11943 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
11944 {
11945 if (mask & (1 << regno))
11946 high_regs_pushed--;
11947 if (high_regs_pushed == 0)
11948 break;
11949 }
11950
11951 mask &= (2 << regno) - 1; /* A noop if regno == 8 */
11952
11953 /* Pop the values into the low register(s). */
11954 thumb_pushpop (asm_out_file, mask, 0);
11955
11956 /* Move the value(s) into the high registers. */
11957 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
11958 {
11959 if (mask & (1 << regno))
11960 {
11961 asm_fprintf (asm_out_file, "\tmov\t%r, %r\n", next_hi_reg,
11962 regno);
11963
11964 for (next_hi_reg++; next_hi_reg < 13; next_hi_reg++)
aeaf4d25 11965 if (THUMB_REG_PUSHED_P (next_hi_reg))
d5b7b3ae
RE
11966 break;
11967 }
11968 }
11969 }
11970 }
11971
5895f793 11972 had_to_push_lr = (live_regs_mask || !leaf_function
d5b7b3ae
RE
11973 || thumb_far_jump_used_p (1));
11974
11975 if (TARGET_BACKTRACE
11976 && ((live_regs_mask & 0xFF) == 0)
11977 && regs_ever_live [LAST_ARG_REGNUM] != 0)
11978 {
11979 /* The stack backtrace structure creation code had to
11980 push R7 in order to get a work register, so we pop
11981 it now. */
11982 live_regs_mask |= (1 << LAST_LO_REGNUM);
11983 }
11984
11985 if (current_function_pretend_args_size == 0 || TARGET_BACKTRACE)
11986 {
11987 if (had_to_push_lr
5895f793
RE
11988 && !is_called_in_ARM_mode (current_function_decl)
11989 && !eh_ofs)
d5b7b3ae
RE
11990 live_regs_mask |= 1 << PC_REGNUM;
11991
11992 /* Either no argument registers were pushed or a backtrace
11993 structure was created which includes an adjusted stack
11994 pointer, so just pop everything. */
11995 if (live_regs_mask)
11996 thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
11997
11998 if (eh_ofs)
11999 thumb_exit (asm_out_file, 2, eh_ofs);
12000 /* We have either just popped the return address into the
12001 PC or it is was kept in LR for the entire function or
12002 it is still on the stack because we do not want to
12003 return by doing a pop {pc}. */
12004 else if ((live_regs_mask & (1 << PC_REGNUM)) == 0)
12005 thumb_exit (asm_out_file,
12006 (had_to_push_lr
12007 && is_called_in_ARM_mode (current_function_decl)) ?
12008 -1 : LR_REGNUM, NULL_RTX);
12009 }
12010 else
12011 {
12012 /* Pop everything but the return address. */
5895f793 12013 live_regs_mask &= ~(1 << PC_REGNUM);
d5b7b3ae
RE
12014
12015 if (live_regs_mask)
12016 thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
12017
12018 if (had_to_push_lr)
12019 /* Get the return address into a temporary register. */
12020 thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0);
12021
12022 /* Remove the argument registers that were pushed onto the stack. */
12023 asm_fprintf (asm_out_file, "\tadd\t%r, %r, #%d\n",
12024 SP_REGNUM, SP_REGNUM,
12025 current_function_pretend_args_size);
12026
12027 if (eh_ofs)
12028 thumb_exit (asm_out_file, 2, eh_ofs);
12029 else
12030 thumb_exit (asm_out_file,
12031 had_to_push_lr ? LAST_ARG_REGNUM : LR_REGNUM, NULL_RTX);
12032 }
12033
12034 return "";
12035}
12036
12037/* Functions to save and restore machine-specific function data. */
e2500fed 12038static struct machine_function *
e32bac5b 12039arm_init_machine_status (void)
d5b7b3ae 12040{
e2500fed
GK
12041 struct machine_function *machine;
12042 machine = (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
6d3d9133 12043
e2500fed
GK
12044#if ARM_FT_UNKNOWN != 0
12045 machine->func_type = ARM_FT_UNKNOWN;
6d3d9133 12046#endif
e2500fed 12047 return machine;
f7a80099
NC
12048}
12049
d5b7b3ae
RE
12050/* Return an RTX indicating where the return address to the
12051 calling function can be found. */
12052rtx
e32bac5b 12053arm_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
d5b7b3ae 12054{
d5b7b3ae
RE
12055 if (count != 0)
12056 return NULL_RTX;
12057
9e2f7ec7
DD
12058 if (TARGET_APCS_32)
12059 return get_hard_reg_initial_val (Pmode, LR_REGNUM);
12060 else
d5b7b3ae 12061 {
9e2f7ec7 12062 rtx lr = gen_rtx_AND (Pmode, gen_rtx_REG (Pmode, LR_REGNUM),
d5b7b3ae 12063 GEN_INT (RETURN_ADDR_MASK26));
9e2f7ec7 12064 return get_func_hard_reg_initial_val (cfun, lr);
d5b7b3ae 12065 }
d5b7b3ae
RE
12066}
12067
12068/* Do anything needed before RTL is emitted for each function. */
12069void
e32bac5b 12070arm_init_expanders (void)
d5b7b3ae
RE
12071{
12072 /* Arrange to initialize and mark the machine per-function status. */
12073 init_machine_status = arm_init_machine_status;
d5b7b3ae
RE
12074}
12075
0977774b 12076HOST_WIDE_INT
e32bac5b 12077thumb_get_frame_size (void)
0977774b
JT
12078{
12079 int regno;
12080
0c2ca901 12081 int base_size = ROUND_UP_WORD (get_frame_size ());
0977774b
JT
12082 int count_regs = 0;
12083 int entry_size = 0;
c231c91e 12084 int leaf;
0977774b
JT
12085
12086 if (! TARGET_THUMB)
12087 abort ();
12088
12089 if (! TARGET_ATPCS)
12090 return base_size;
12091
12092 /* We need to know if we are a leaf function. Unfortunately, it
12093 is possible to be called after start_sequence has been called,
12094 which causes get_insns to return the insns for the sequence,
12095 not the function, which will cause leaf_function_p to return
12096 the incorrect result.
12097
12098 To work around this, we cache the computed frame size. This
12099 works because we will only be calling RTL expanders that need
12100 to know about leaf functions once reload has completed, and the
12101 frame size cannot be changed after that time, so we can safely
12102 use the cached value. */
12103
12104 if (reload_completed)
12105 return cfun->machine->frame_size;
12106
c231c91e
RE
12107 leaf = leaf_function_p ();
12108
12109 /* A leaf function does not need any stack alignment if it has nothing
12110 on the stack. */
12111 if (leaf && base_size == 0)
12112 {
12113 cfun->machine->frame_size = 0;
12114 return 0;
12115 }
12116
0977774b
JT
12117 /* We know that SP will be word aligned on entry, and we must
12118 preserve that condition at any subroutine call. But those are
12119 the only constraints. */
12120
12121 /* Space for variadic functions. */
12122 if (current_function_pretend_args_size)
12123 entry_size += current_function_pretend_args_size;
12124
12125 /* Space for pushed lo registers. */
12126 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
12127 if (THUMB_REG_PUSHED_P (regno))
12128 count_regs++;
12129
12130 /* Space for backtrace structure. */
12131 if (TARGET_BACKTRACE)
12132 {
12133 if (count_regs == 0 && regs_ever_live[LAST_ARG_REGNUM] != 0)
12134 entry_size += 20;
12135 else
12136 entry_size += 16;
12137 }
12138
c231c91e 12139 if (count_regs || !leaf || thumb_far_jump_used_p (1))
0977774b
JT
12140 count_regs++; /* LR */
12141
12142 entry_size += count_regs * 4;
12143 count_regs = 0;
12144
12145 /* Space for pushed hi regs. */
12146 for (regno = 8; regno < 13; regno++)
12147 if (THUMB_REG_PUSHED_P (regno))
12148 count_regs++;
12149
12150 entry_size += count_regs * 4;
12151
12152 if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
12153 base_size += 4;
12154 if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
12155 abort ();
12156
12157 cfun->machine->frame_size = base_size;
12158
12159 return base_size;
12160}
12161
d5b7b3ae
RE
12162/* Generate the rest of a function's prologue. */
12163void
e32bac5b 12164thumb_expand_prologue (void)
d5b7b3ae 12165{
0977774b 12166 HOST_WIDE_INT amount = (thumb_get_frame_size ()
d5b7b3ae 12167 + current_function_outgoing_args_size);
6d3d9133
NC
12168 unsigned long func_type;
12169
12170 func_type = arm_current_func_type ();
d5b7b3ae
RE
12171
12172 /* Naked functions don't have prologues. */
6d3d9133 12173 if (IS_NAKED (func_type))
d5b7b3ae
RE
12174 return;
12175
6d3d9133
NC
12176 if (IS_INTERRUPT (func_type))
12177 {
c725bd79 12178 error ("interrupt Service Routines cannot be coded in Thumb mode");
6d3d9133
NC
12179 return;
12180 }
12181
d5b7b3ae
RE
12182 if (frame_pointer_needed)
12183 emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
12184
12185 if (amount)
12186 {
0c2ca901 12187 amount = ROUND_UP_WORD (amount);
d5b7b3ae
RE
12188
12189 if (amount < 512)
12190 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1d6e90ac 12191 GEN_INT (- amount)));
d5b7b3ae
RE
12192 else
12193 {
12194 int regno;
12195 rtx reg;
12196
12197 /* The stack decrement is too big for an immediate value in a single
12198 insn. In theory we could issue multiple subtracts, but after
12199 three of them it becomes more space efficient to place the full
12200 value in the constant pool and load into a register. (Also the
12201 ARM debugger really likes to see only one stack decrement per
12202 function). So instead we look for a scratch register into which
12203 we can load the decrement, and then we subtract this from the
12204 stack pointer. Unfortunately on the thumb the only available
12205 scratch registers are the argument registers, and we cannot use
12206 these as they may hold arguments to the function. Instead we
12207 attempt to locate a call preserved register which is used by this
12208 function. If we can find one, then we know that it will have
12209 been pushed at the start of the prologue and so we can corrupt
12210 it now. */
12211 for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++)
aeaf4d25 12212 if (THUMB_REG_PUSHED_P (regno)
5895f793
RE
12213 && !(frame_pointer_needed
12214 && (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
d5b7b3ae
RE
12215 break;
12216
aeaf4d25 12217 if (regno > LAST_LO_REGNUM) /* Very unlikely. */
d5b7b3ae
RE
12218 {
12219 rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
12220
6bc82793 12221 /* Choose an arbitrary, non-argument low register. */
d5b7b3ae
RE
12222 reg = gen_rtx (REG, SImode, LAST_LO_REGNUM);
12223
12224 /* Save it by copying it into a high, scratch register. */
c14a3a45
NC
12225 emit_insn (gen_movsi (spare, reg));
12226 /* Add a USE to stop propagate_one_insn() from barfing. */
6bacc7b0 12227 emit_insn (gen_prologue_use (spare));
d5b7b3ae
RE
12228
12229 /* Decrement the stack. */
1d6e90ac 12230 emit_insn (gen_movsi (reg, GEN_INT (- amount)));
d5b7b3ae
RE
12231 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
12232 reg));
12233
12234 /* Restore the low register's original value. */
12235 emit_insn (gen_movsi (reg, spare));
12236
12237 /* Emit a USE of the restored scratch register, so that flow
12238 analysis will not consider the restore redundant. The
12239 register won't be used again in this function and isn't
12240 restored by the epilogue. */
6bacc7b0 12241 emit_insn (gen_prologue_use (reg));
d5b7b3ae
RE
12242 }
12243 else
12244 {
12245 reg = gen_rtx (REG, SImode, regno);
12246
1d6e90ac 12247 emit_insn (gen_movsi (reg, GEN_INT (- amount)));
d5b7b3ae
RE
12248 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
12249 reg));
12250 }
12251 }
12252 }
12253
70f4f91c 12254 if (current_function_profile || TARGET_NO_SCHED_PRO)
d5b7b3ae
RE
12255 emit_insn (gen_blockage ());
12256}
12257
12258void
e32bac5b 12259thumb_expand_epilogue (void)
d5b7b3ae 12260{
0977774b 12261 HOST_WIDE_INT amount = (thumb_get_frame_size ()
d5b7b3ae 12262 + current_function_outgoing_args_size);
defc0463
RE
12263 int regno;
12264
6d3d9133
NC
12265 /* Naked functions don't have prologues. */
12266 if (IS_NAKED (arm_current_func_type ()))
d5b7b3ae
RE
12267 return;
12268
12269 if (frame_pointer_needed)
12270 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
12271 else if (amount)
12272 {
0c2ca901 12273 amount = ROUND_UP_WORD (amount);
d5b7b3ae
RE
12274
12275 if (amount < 512)
12276 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
12277 GEN_INT (amount)));
12278 else
12279 {
12280 /* r3 is always free in the epilogue. */
12281 rtx reg = gen_rtx (REG, SImode, LAST_ARG_REGNUM);
12282
12283 emit_insn (gen_movsi (reg, GEN_INT (amount)));
12284 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, reg));
12285 }
12286 }
12287
12288 /* Emit a USE (stack_pointer_rtx), so that
12289 the stack adjustment will not be deleted. */
6bacc7b0 12290 emit_insn (gen_prologue_use (stack_pointer_rtx));
d5b7b3ae 12291
70f4f91c 12292 if (current_function_profile || TARGET_NO_SCHED_PRO)
d5b7b3ae 12293 emit_insn (gen_blockage ());
defc0463
RE
12294
12295 /* Emit a clobber for each insn that will be restored in the epilogue,
12296 so that flow2 will get register lifetimes correct. */
12297 for (regno = 0; regno < 13; regno++)
12298 if (regs_ever_live[regno] && !call_used_regs[regno])
12299 emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, regno)));
12300
12301 if (! regs_ever_live[LR_REGNUM])
12302 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, LR_REGNUM)));
d5b7b3ae
RE
12303}
12304
08c148a8 12305static void
e32bac5b 12306thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
d5b7b3ae
RE
12307{
12308 int live_regs_mask = 0;
12309 int high_regs_pushed = 0;
d5b7b3ae
RE
12310 int regno;
12311
6d3d9133 12312 if (IS_NAKED (arm_current_func_type ()))
d5b7b3ae
RE
12313 return;
12314
12315 if (is_called_in_ARM_mode (current_function_decl))
12316 {
12317 const char * name;
12318
12319 if (GET_CODE (DECL_RTL (current_function_decl)) != MEM)
12320 abort ();
12321 if (GET_CODE (XEXP (DECL_RTL (current_function_decl), 0)) != SYMBOL_REF)
12322 abort ();
12323 name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
12324
12325 /* Generate code sequence to switch us into Thumb mode. */
12326 /* The .code 32 directive has already been emitted by
6d77b53e 12327 ASM_DECLARE_FUNCTION_NAME. */
d5b7b3ae
RE
12328 asm_fprintf (f, "\torr\t%r, %r, #1\n", IP_REGNUM, PC_REGNUM);
12329 asm_fprintf (f, "\tbx\t%r\n", IP_REGNUM);
12330
12331 /* Generate a label, so that the debugger will notice the
12332 change in instruction sets. This label is also used by
12333 the assembler to bypass the ARM code when this function
12334 is called from a Thumb encoded function elsewhere in the
12335 same file. Hence the definition of STUB_NAME here must
12336 agree with the definition in gas/config/tc-arm.c */
12337
12338#define STUB_NAME ".real_start_of"
12339
761c70aa 12340 fprintf (f, "\t.code\t16\n");
d5b7b3ae
RE
12341#ifdef ARM_PE
12342 if (arm_dllexport_name_p (name))
e5951263 12343 name = arm_strip_name_encoding (name);
d5b7b3ae
RE
12344#endif
12345 asm_fprintf (f, "\t.globl %s%U%s\n", STUB_NAME, name);
761c70aa 12346 fprintf (f, "\t.thumb_func\n");
d5b7b3ae
RE
12347 asm_fprintf (f, "%s%U%s:\n", STUB_NAME, name);
12348 }
12349
d5b7b3ae
RE
12350 if (current_function_pretend_args_size)
12351 {
3cb66fd7 12352 if (cfun->machine->uses_anonymous_args)
d5b7b3ae
RE
12353 {
12354 int num_pushes;
12355
761c70aa 12356 fprintf (f, "\tpush\t{");
d5b7b3ae 12357
e9d7b180 12358 num_pushes = ARM_NUM_INTS (current_function_pretend_args_size);
d5b7b3ae
RE
12359
12360 for (regno = LAST_ARG_REGNUM + 1 - num_pushes;
12361 regno <= LAST_ARG_REGNUM;
5895f793 12362 regno++)
d5b7b3ae
RE
12363 asm_fprintf (f, "%r%s", regno,
12364 regno == LAST_ARG_REGNUM ? "" : ", ");
12365
761c70aa 12366 fprintf (f, "}\n");
d5b7b3ae
RE
12367 }
12368 else
12369 asm_fprintf (f, "\tsub\t%r, %r, #%d\n",
12370 SP_REGNUM, SP_REGNUM,
12371 current_function_pretend_args_size);
12372 }
12373
5895f793 12374 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
aeaf4d25 12375 if (THUMB_REG_PUSHED_P (regno))
d5b7b3ae
RE
12376 live_regs_mask |= 1 << regno;
12377
5895f793 12378 if (live_regs_mask || !leaf_function_p () || thumb_far_jump_used_p (1))
d5b7b3ae
RE
12379 live_regs_mask |= 1 << LR_REGNUM;
12380
12381 if (TARGET_BACKTRACE)
12382 {
12383 int offset;
12384 int work_register = 0;
12385 int wr;
12386
12387 /* We have been asked to create a stack backtrace structure.
12388 The code looks like this:
12389
12390 0 .align 2
12391 0 func:
12392 0 sub SP, #16 Reserve space for 4 registers.
12393 2 push {R7} Get a work register.
12394 4 add R7, SP, #20 Get the stack pointer before the push.
12395 6 str R7, [SP, #8] Store the stack pointer (before reserving the space).
12396 8 mov R7, PC Get hold of the start of this code plus 12.
12397 10 str R7, [SP, #16] Store it.
12398 12 mov R7, FP Get hold of the current frame pointer.
12399 14 str R7, [SP, #4] Store it.
12400 16 mov R7, LR Get hold of the current return address.
12401 18 str R7, [SP, #12] Store it.
12402 20 add R7, SP, #16 Point at the start of the backtrace structure.
12403 22 mov FP, R7 Put this value into the frame pointer. */
12404
12405 if ((live_regs_mask & 0xFF) == 0)
12406 {
12407 /* See if the a4 register is free. */
12408
12409 if (regs_ever_live [LAST_ARG_REGNUM] == 0)
12410 work_register = LAST_ARG_REGNUM;
12411 else /* We must push a register of our own */
12412 live_regs_mask |= (1 << LAST_LO_REGNUM);
12413 }
12414
12415 if (work_register == 0)
12416 {
12417 /* Select a register from the list that will be pushed to
12418 use as our work register. */
12419 for (work_register = (LAST_LO_REGNUM + 1); work_register--;)
12420 if ((1 << work_register) & live_regs_mask)
12421 break;
12422 }
12423
12424 asm_fprintf
12425 (f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n",
12426 SP_REGNUM, SP_REGNUM);
12427
12428 if (live_regs_mask)
12429 thumb_pushpop (f, live_regs_mask, 1);
12430
12431 for (offset = 0, wr = 1 << 15; wr != 0; wr >>= 1)
12432 if (wr & live_regs_mask)
12433 offset += 4;
12434
12435 asm_fprintf (f, "\tadd\t%r, %r, #%d\n", work_register, SP_REGNUM,
12436 offset + 16 + current_function_pretend_args_size);
12437
12438 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12439 offset + 4);
12440
12441 /* Make sure that the instruction fetching the PC is in the right place
12442 to calculate "start of backtrace creation code + 12". */
12443 if (live_regs_mask)
12444 {
12445 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, PC_REGNUM);
12446 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12447 offset + 12);
12448 asm_fprintf (f, "\tmov\t%r, %r\n", work_register,
12449 ARM_HARD_FRAME_POINTER_REGNUM);
12450 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12451 offset);
12452 }
12453 else
12454 {
12455 asm_fprintf (f, "\tmov\t%r, %r\n", work_register,
12456 ARM_HARD_FRAME_POINTER_REGNUM);
12457 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12458 offset);
12459 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, PC_REGNUM);
12460 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12461 offset + 12);
12462 }
12463
12464 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, LR_REGNUM);
12465 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12466 offset + 8);
12467 asm_fprintf (f, "\tadd\t%r, %r, #%d\n", work_register, SP_REGNUM,
12468 offset + 12);
12469 asm_fprintf (f, "\tmov\t%r, %r\t\t%@ Backtrace structure created\n",
12470 ARM_HARD_FRAME_POINTER_REGNUM, work_register);
12471 }
12472 else if (live_regs_mask)
12473 thumb_pushpop (f, live_regs_mask, 1);
12474
12475 for (regno = 8; regno < 13; regno++)
e26053d1
NC
12476 if (THUMB_REG_PUSHED_P (regno))
12477 high_regs_pushed++;
d5b7b3ae
RE
12478
12479 if (high_regs_pushed)
12480 {
12481 int pushable_regs = 0;
12482 int mask = live_regs_mask & 0xff;
12483 int next_hi_reg;
12484
12485 for (next_hi_reg = 12; next_hi_reg > LAST_LO_REGNUM; next_hi_reg--)
e26053d1
NC
12486 if (THUMB_REG_PUSHED_P (next_hi_reg))
12487 break;
d5b7b3ae
RE
12488
12489 pushable_regs = mask;
12490
12491 if (pushable_regs == 0)
12492 {
12493 /* Desperation time -- this probably will never happen. */
aeaf4d25 12494 if (THUMB_REG_PUSHED_P (LAST_ARG_REGNUM))
d5b7b3ae
RE
12495 asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, LAST_ARG_REGNUM);
12496 mask = 1 << LAST_ARG_REGNUM;
12497 }
12498
12499 while (high_regs_pushed > 0)
12500 {
12501 for (regno = LAST_LO_REGNUM; regno >= 0; regno--)
12502 {
12503 if (mask & (1 << regno))
12504 {
12505 asm_fprintf (f, "\tmov\t%r, %r\n", regno, next_hi_reg);
12506
5895f793 12507 high_regs_pushed--;
d5b7b3ae
RE
12508
12509 if (high_regs_pushed)
aeaf4d25
AN
12510 {
12511 for (next_hi_reg--; next_hi_reg > LAST_LO_REGNUM;
12512 next_hi_reg--)
12513 if (THUMB_REG_PUSHED_P (next_hi_reg))
d5b7b3ae 12514 break;
aeaf4d25 12515 }
d5b7b3ae
RE
12516 else
12517 {
5895f793 12518 mask &= ~((1 << regno) - 1);
d5b7b3ae
RE
12519 break;
12520 }
12521 }
12522 }
12523
12524 thumb_pushpop (f, mask, 1);
12525 }
12526
12527 if (pushable_regs == 0
aeaf4d25 12528 && (THUMB_REG_PUSHED_P (LAST_ARG_REGNUM)))
d5b7b3ae
RE
12529 asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
12530 }
12531}
12532
12533/* Handle the case of a double word load into a low register from
12534 a computed memory address. The computed address may involve a
12535 register which is overwritten by the load. */
cd2b33d0 12536const char *
e32bac5b 12537thumb_load_double_from_address (rtx *operands)
d5b7b3ae
RE
12538{
12539 rtx addr;
12540 rtx base;
12541 rtx offset;
12542 rtx arg1;
12543 rtx arg2;
12544
12545 if (GET_CODE (operands[0]) != REG)
400500c4 12546 abort ();
d5b7b3ae
RE
12547
12548 if (GET_CODE (operands[1]) != MEM)
400500c4 12549 abort ();
d5b7b3ae
RE
12550
12551 /* Get the memory address. */
12552 addr = XEXP (operands[1], 0);
12553
12554 /* Work out how the memory address is computed. */
12555 switch (GET_CODE (addr))
12556 {
12557 case REG:
12558 operands[2] = gen_rtx (MEM, SImode,
12559 plus_constant (XEXP (operands[1], 0), 4));
12560
12561 if (REGNO (operands[0]) == REGNO (addr))
12562 {
12563 output_asm_insn ("ldr\t%H0, %2", operands);
12564 output_asm_insn ("ldr\t%0, %1", operands);
12565 }
12566 else
12567 {
12568 output_asm_insn ("ldr\t%0, %1", operands);
12569 output_asm_insn ("ldr\t%H0, %2", operands);
12570 }
12571 break;
12572
12573 case CONST:
12574 /* Compute <address> + 4 for the high order load. */
12575 operands[2] = gen_rtx (MEM, SImode,
12576 plus_constant (XEXP (operands[1], 0), 4));
12577
12578 output_asm_insn ("ldr\t%0, %1", operands);
12579 output_asm_insn ("ldr\t%H0, %2", operands);
12580 break;
12581
12582 case PLUS:
12583 arg1 = XEXP (addr, 0);
12584 arg2 = XEXP (addr, 1);
12585
12586 if (CONSTANT_P (arg1))
12587 base = arg2, offset = arg1;
12588 else
12589 base = arg1, offset = arg2;
12590
12591 if (GET_CODE (base) != REG)
400500c4 12592 abort ();
d5b7b3ae
RE
12593
12594 /* Catch the case of <address> = <reg> + <reg> */
12595 if (GET_CODE (offset) == REG)
12596 {
12597 int reg_offset = REGNO (offset);
12598 int reg_base = REGNO (base);
12599 int reg_dest = REGNO (operands[0]);
12600
12601 /* Add the base and offset registers together into the
12602 higher destination register. */
12603 asm_fprintf (asm_out_file, "\tadd\t%r, %r, %r",
12604 reg_dest + 1, reg_base, reg_offset);
12605
12606 /* Load the lower destination register from the address in
12607 the higher destination register. */
12608 asm_fprintf (asm_out_file, "\tldr\t%r, [%r, #0]",
12609 reg_dest, reg_dest + 1);
12610
12611 /* Load the higher destination register from its own address
12612 plus 4. */
12613 asm_fprintf (asm_out_file, "\tldr\t%r, [%r, #4]",
12614 reg_dest + 1, reg_dest + 1);
12615 }
12616 else
12617 {
12618 /* Compute <address> + 4 for the high order load. */
12619 operands[2] = gen_rtx (MEM, SImode,
12620 plus_constant (XEXP (operands[1], 0), 4));
12621
12622 /* If the computed address is held in the low order register
12623 then load the high order register first, otherwise always
12624 load the low order register first. */
12625 if (REGNO (operands[0]) == REGNO (base))
12626 {
12627 output_asm_insn ("ldr\t%H0, %2", operands);
12628 output_asm_insn ("ldr\t%0, %1", operands);
12629 }
12630 else
12631 {
12632 output_asm_insn ("ldr\t%0, %1", operands);
12633 output_asm_insn ("ldr\t%H0, %2", operands);
12634 }
12635 }
12636 break;
12637
12638 case LABEL_REF:
12639 /* With no registers to worry about we can just load the value
12640 directly. */
12641 operands[2] = gen_rtx (MEM, SImode,
12642 plus_constant (XEXP (operands[1], 0), 4));
12643
12644 output_asm_insn ("ldr\t%H0, %2", operands);
12645 output_asm_insn ("ldr\t%0, %1", operands);
12646 break;
12647
12648 default:
400500c4 12649 abort ();
d5b7b3ae
RE
12650 break;
12651 }
12652
12653 return "";
12654}
12655
cd2b33d0 12656const char *
e32bac5b 12657thumb_output_move_mem_multiple (int n, rtx *operands)
d5b7b3ae
RE
12658{
12659 rtx tmp;
12660
12661 switch (n)
12662 {
12663 case 2:
ca356f3a 12664 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 12665 {
ca356f3a
RE
12666 tmp = operands[4];
12667 operands[4] = operands[5];
12668 operands[5] = tmp;
d5b7b3ae 12669 }
ca356f3a
RE
12670 output_asm_insn ("ldmia\t%1!, {%4, %5}", operands);
12671 output_asm_insn ("stmia\t%0!, {%4, %5}", operands);
d5b7b3ae
RE
12672 break;
12673
12674 case 3:
ca356f3a 12675 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 12676 {
ca356f3a
RE
12677 tmp = operands[4];
12678 operands[4] = operands[5];
12679 operands[5] = tmp;
d5b7b3ae 12680 }
ca356f3a 12681 if (REGNO (operands[5]) > REGNO (operands[6]))
d5b7b3ae 12682 {
ca356f3a
RE
12683 tmp = operands[5];
12684 operands[5] = operands[6];
12685 operands[6] = tmp;
d5b7b3ae 12686 }
ca356f3a 12687 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 12688 {
ca356f3a
RE
12689 tmp = operands[4];
12690 operands[4] = operands[5];
12691 operands[5] = tmp;
d5b7b3ae
RE
12692 }
12693
ca356f3a
RE
12694 output_asm_insn ("ldmia\t%1!, {%4, %5, %6}", operands);
12695 output_asm_insn ("stmia\t%0!, {%4, %5, %6}", operands);
d5b7b3ae
RE
12696 break;
12697
12698 default:
12699 abort ();
12700 }
12701
12702 return "";
12703}
12704
1d6e90ac 12705/* Routines for generating rtl. */
d5b7b3ae 12706void
e32bac5b 12707thumb_expand_movstrqi (rtx *operands)
d5b7b3ae
RE
12708{
12709 rtx out = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
12710 rtx in = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
12711 HOST_WIDE_INT len = INTVAL (operands[2]);
12712 HOST_WIDE_INT offset = 0;
12713
12714 while (len >= 12)
12715 {
ca356f3a 12716 emit_insn (gen_movmem12b (out, in, out, in));
d5b7b3ae
RE
12717 len -= 12;
12718 }
12719
12720 if (len >= 8)
12721 {
ca356f3a 12722 emit_insn (gen_movmem8b (out, in, out, in));
d5b7b3ae
RE
12723 len -= 8;
12724 }
12725
12726 if (len >= 4)
12727 {
12728 rtx reg = gen_reg_rtx (SImode);
12729 emit_insn (gen_movsi (reg, gen_rtx (MEM, SImode, in)));
12730 emit_insn (gen_movsi (gen_rtx (MEM, SImode, out), reg));
12731 len -= 4;
12732 offset += 4;
12733 }
12734
12735 if (len >= 2)
12736 {
12737 rtx reg = gen_reg_rtx (HImode);
12738 emit_insn (gen_movhi (reg, gen_rtx (MEM, HImode,
12739 plus_constant (in, offset))));
12740 emit_insn (gen_movhi (gen_rtx (MEM, HImode, plus_constant (out, offset)),
12741 reg));
12742 len -= 2;
12743 offset += 2;
12744 }
12745
12746 if (len)
12747 {
12748 rtx reg = gen_reg_rtx (QImode);
12749 emit_insn (gen_movqi (reg, gen_rtx (MEM, QImode,
12750 plus_constant (in, offset))));
12751 emit_insn (gen_movqi (gen_rtx (MEM, QImode, plus_constant (out, offset)),
12752 reg));
12753 }
12754}
12755
12756int
e32bac5b 12757thumb_cmp_operand (rtx op, enum machine_mode mode)
d5b7b3ae
RE
12758{
12759 return ((GET_CODE (op) == CONST_INT
c769a35d
RE
12760 && INTVAL (op) < 256
12761 && INTVAL (op) >= 0)
defc0463 12762 || s_register_operand (op, mode));
d5b7b3ae
RE
12763}
12764
c769a35d
RE
12765int
12766thumb_cmpneg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
12767{
12768 return (GET_CODE (op) == CONST_INT
12769 && INTVAL (op) < 0
12770 && INTVAL (op) > -256);
12771}
12772
defc0463
RE
12773/* Return TRUE if a result can be stored in OP without clobbering the
12774 condition code register. Prior to reload we only accept a
12775 register. After reload we have to be able to handle memory as
12776 well, since a pseudo may not get a hard reg and reload cannot
12777 handle output-reloads on jump insns.
d5b7b3ae 12778
defc0463
RE
12779 We could possibly handle mem before reload as well, but that might
12780 complicate things with the need to handle increment
12781 side-effects. */
d5b7b3ae 12782
defc0463
RE
12783int
12784thumb_cbrch_target_operand (rtx op, enum machine_mode mode)
12785{
12786 return (s_register_operand (op, mode)
12787 || ((reload_in_progress || reload_completed)
12788 && memory_operand (op, mode)));
d5b7b3ae
RE
12789}
12790
12791/* Handle storing a half-word to memory during reload. */
12792void
e32bac5b 12793thumb_reload_out_hi (rtx *operands)
d5b7b3ae
RE
12794{
12795 emit_insn (gen_thumb_movhi_clobber (operands[0], operands[1], operands[2]));
12796}
12797
e32bac5b 12798/* Handle reading a half-word from memory during reload. */
d5b7b3ae 12799void
e32bac5b 12800thumb_reload_in_hi (rtx *operands ATTRIBUTE_UNUSED)
d5b7b3ae
RE
12801{
12802 abort ();
12803}
12804
c27ba912
DM
12805/* Return the length of a function name prefix
12806 that starts with the character 'c'. */
12807static int
e32bac5b 12808arm_get_strip_length (int c)
c27ba912
DM
12809{
12810 switch (c)
12811 {
12812 ARM_NAME_ENCODING_LENGTHS
12813 default: return 0;
12814 }
12815}
12816
12817/* Return a pointer to a function's name with any
12818 and all prefix encodings stripped from it. */
12819const char *
e32bac5b 12820arm_strip_name_encoding (const char *name)
c27ba912
DM
12821{
12822 int skip;
12823
12824 while ((skip = arm_get_strip_length (* name)))
12825 name += skip;
12826
12827 return name;
12828}
12829
e1944073
KW
12830/* If there is a '*' anywhere in the name's prefix, then
12831 emit the stripped name verbatim, otherwise prepend an
12832 underscore if leading underscores are being used. */
e1944073 12833void
e32bac5b 12834arm_asm_output_labelref (FILE *stream, const char *name)
e1944073
KW
12835{
12836 int skip;
12837 int verbatim = 0;
12838
12839 while ((skip = arm_get_strip_length (* name)))
12840 {
12841 verbatim |= (*name == '*');
12842 name += skip;
12843 }
12844
12845 if (verbatim)
12846 fputs (name, stream);
12847 else
12848 asm_fprintf (stream, "%U%s", name);
12849}
12850
e2500fed
GK
12851rtx aof_pic_label;
12852
2b835d68 12853#ifdef AOF_ASSEMBLER
6354dc9b 12854/* Special functions only needed when producing AOF syntax assembler. */
2b835d68 12855
32de079a
RE
12856struct pic_chain
12857{
62b10bbc 12858 struct pic_chain * next;
5f37d07c 12859 const char * symname;
32de079a
RE
12860};
12861
62b10bbc 12862static struct pic_chain * aof_pic_chain = NULL;
32de079a
RE
12863
12864rtx
e32bac5b 12865aof_pic_entry (rtx x)
32de079a 12866{
62b10bbc 12867 struct pic_chain ** chainp;
32de079a
RE
12868 int offset;
12869
12870 if (aof_pic_label == NULL_RTX)
12871 {
43cffd11 12872 aof_pic_label = gen_rtx_SYMBOL_REF (Pmode, "x$adcons");
32de079a
RE
12873 }
12874
12875 for (offset = 0, chainp = &aof_pic_chain; *chainp;
12876 offset += 4, chainp = &(*chainp)->next)
12877 if ((*chainp)->symname == XSTR (x, 0))
12878 return plus_constant (aof_pic_label, offset);
12879
12880 *chainp = (struct pic_chain *) xmalloc (sizeof (struct pic_chain));
12881 (*chainp)->next = NULL;
12882 (*chainp)->symname = XSTR (x, 0);
12883 return plus_constant (aof_pic_label, offset);
12884}
12885
12886void
e32bac5b 12887aof_dump_pic_table (FILE *f)
32de079a 12888{
62b10bbc 12889 struct pic_chain * chain;
32de079a
RE
12890
12891 if (aof_pic_chain == NULL)
12892 return;
12893
dd18ae56
NC
12894 asm_fprintf (f, "\tAREA |%r$$adcons|, BASED %r\n",
12895 PIC_OFFSET_TABLE_REGNUM,
12896 PIC_OFFSET_TABLE_REGNUM);
32de079a
RE
12897 fputs ("|x$adcons|\n", f);
12898
12899 for (chain = aof_pic_chain; chain; chain = chain->next)
12900 {
12901 fputs ("\tDCD\t", f);
12902 assemble_name (f, chain->symname);
12903 fputs ("\n", f);
12904 }
12905}
12906
2b835d68
RE
12907int arm_text_section_count = 1;
12908
12909char *
e32bac5b 12910aof_text_section (void )
2b835d68
RE
12911{
12912 static char buf[100];
2b835d68
RE
12913 sprintf (buf, "\tAREA |C$$code%d|, CODE, READONLY",
12914 arm_text_section_count++);
12915 if (flag_pic)
12916 strcat (buf, ", PIC, REENTRANT");
12917 return buf;
12918}
12919
12920static int arm_data_section_count = 1;
12921
12922char *
e32bac5b 12923aof_data_section (void)
2b835d68
RE
12924{
12925 static char buf[100];
12926 sprintf (buf, "\tAREA |C$$data%d|, DATA", arm_data_section_count++);
12927 return buf;
12928}
12929
12930/* The AOF assembler is religiously strict about declarations of
12931 imported and exported symbols, so that it is impossible to declare
956d6950 12932 a function as imported near the beginning of the file, and then to
2b835d68
RE
12933 export it later on. It is, however, possible to delay the decision
12934 until all the functions in the file have been compiled. To get
12935 around this, we maintain a list of the imports and exports, and
12936 delete from it any that are subsequently defined. At the end of
12937 compilation we spit the remainder of the list out before the END
12938 directive. */
12939
12940struct import
12941{
62b10bbc 12942 struct import * next;
5f37d07c 12943 const char * name;
2b835d68
RE
12944};
12945
62b10bbc 12946static struct import * imports_list = NULL;
2b835d68
RE
12947
12948void
e32bac5b 12949aof_add_import (const char *name)
2b835d68 12950{
62b10bbc 12951 struct import * new;
2b835d68
RE
12952
12953 for (new = imports_list; new; new = new->next)
12954 if (new->name == name)
12955 return;
12956
12957 new = (struct import *) xmalloc (sizeof (struct import));
12958 new->next = imports_list;
12959 imports_list = new;
12960 new->name = name;
12961}
12962
12963void
e32bac5b 12964aof_delete_import (const char *name)
2b835d68 12965{
62b10bbc 12966 struct import ** old;
2b835d68
RE
12967
12968 for (old = &imports_list; *old; old = & (*old)->next)
12969 {
12970 if ((*old)->name == name)
12971 {
12972 *old = (*old)->next;
12973 return;
12974 }
12975 }
12976}
12977
12978int arm_main_function = 0;
12979
a5fe455b 12980static void
e32bac5b 12981aof_dump_imports (FILE *f)
2b835d68
RE
12982{
12983 /* The AOF assembler needs this to cause the startup code to be extracted
12984 from the library. Brining in __main causes the whole thing to work
12985 automagically. */
12986 if (arm_main_function)
12987 {
12988 text_section ();
12989 fputs ("\tIMPORT __main\n", f);
12990 fputs ("\tDCD __main\n", f);
12991 }
12992
12993 /* Now dump the remaining imports. */
12994 while (imports_list)
12995 {
12996 fprintf (f, "\tIMPORT\t");
12997 assemble_name (f, imports_list->name);
12998 fputc ('\n', f);
12999 imports_list = imports_list->next;
13000 }
13001}
5eb99654
KG
13002
13003static void
e32bac5b 13004aof_globalize_label (FILE *stream, const char *name)
5eb99654
KG
13005{
13006 default_globalize_label (stream, name);
13007 if (! strcmp (name, "main"))
13008 arm_main_function = 1;
13009}
a5fe455b 13010
1bc7c5b6
ZW
13011static void
13012aof_file_start ()
13013{
13014 fputs ("__r0\tRN\t0\n", asm_out_file);
13015 fputs ("__a1\tRN\t0\n", asm_out_file);
13016 fputs ("__a2\tRN\t1\n", asm_out_file);
13017 fputs ("__a3\tRN\t2\n", asm_out_file);
13018 fputs ("__a4\tRN\t3\n", asm_out_file);
13019 fputs ("__v1\tRN\t4\n", asm_out_file);
13020 fputs ("__v2\tRN\t5\n", asm_out_file);
13021 fputs ("__v3\tRN\t6\n", asm_out_file);
13022 fputs ("__v4\tRN\t7\n", asm_out_file);
13023 fputs ("__v5\tRN\t8\n", asm_out_file);
13024 fputs ("__v6\tRN\t9\n", asm_out_file);
13025 fputs ("__sl\tRN\t10\n", asm_out_file);
13026 fputs ("__fp\tRN\t11\n", asm_out_file);
13027 fputs ("__ip\tRN\t12\n", asm_out_file);
13028 fputs ("__sp\tRN\t13\n", asm_out_file);
13029 fputs ("__lr\tRN\t14\n", asm_out_file);
13030 fputs ("__pc\tRN\t15\n", asm_out_file);
13031 fputs ("__f0\tFN\t0\n", asm_out_file);
13032 fputs ("__f1\tFN\t1\n", asm_out_file);
13033 fputs ("__f2\tFN\t2\n", asm_out_file);
13034 fputs ("__f3\tFN\t3\n", asm_out_file);
13035 fputs ("__f4\tFN\t4\n", asm_out_file);
13036 fputs ("__f5\tFN\t5\n", asm_out_file);
13037 fputs ("__f6\tFN\t6\n", asm_out_file);
13038 fputs ("__f7\tFN\t7\n", asm_out_file);
13039 text_section ();
13040}
13041
a5fe455b 13042static void
e32bac5b 13043aof_file_end (void)
a5fe455b
ZW
13044{
13045 if (flag_pic)
13046 aof_dump_pic_table (asm_out_file);
13047 aof_dump_imports (asm_out_file);
13048 fputs ("\tEND\n", asm_out_file);
13049}
2b835d68 13050#endif /* AOF_ASSEMBLER */
7c262518 13051
ebe413e5 13052#ifdef OBJECT_FORMAT_ELF
7c262518
RH
13053/* Switch to an arbitrary section NAME with attributes as specified
13054 by FLAGS. ALIGN specifies any known alignment requirements for
13055 the section; 0 if the default should be used.
13056
13057 Differs from the default elf version only in the prefix character
13058 used before the section type. */
13059
13060static void
e32bac5b 13061arm_elf_asm_named_section (const char *name, unsigned int flags)
7c262518 13062{
6a0a6ac4
AM
13063 char flagchars[10], *f = flagchars;
13064
13065 if (! named_section_first_declaration (name))
13066 {
13067 fprintf (asm_out_file, "\t.section\t%s\n", name);
13068 return;
13069 }
7c262518
RH
13070
13071 if (!(flags & SECTION_DEBUG))
13072 *f++ = 'a';
13073 if (flags & SECTION_WRITE)
13074 *f++ = 'w';
13075 if (flags & SECTION_CODE)
13076 *f++ = 'x';
13077 if (flags & SECTION_SMALL)
13078 *f++ = 's';
201556f0
JJ
13079 if (flags & SECTION_MERGE)
13080 *f++ = 'M';
13081 if (flags & SECTION_STRINGS)
13082 *f++ = 'S';
6a0a6ac4
AM
13083 if (flags & SECTION_TLS)
13084 *f++ = 'T';
7c262518
RH
13085 *f = '\0';
13086
6a0a6ac4 13087 fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
7c262518 13088
6a0a6ac4
AM
13089 if (!(flags & SECTION_NOTYPE))
13090 {
13091 const char *type;
13092
13093 if (flags & SECTION_BSS)
13094 type = "nobits";
13095 else
13096 type = "progbits";
13097
13098 fprintf (asm_out_file, ",%%%s", type);
13099
13100 if (flags & SECTION_ENTSIZE)
13101 fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
13102 }
13103
13104 putc ('\n', asm_out_file);
7c262518 13105}
ebe413e5 13106#endif
fb49053f
RH
13107
13108#ifndef ARM_PE
13109/* Symbols in the text segment can be accessed without indirecting via the
13110 constant pool; it may take an extra binary operation, but this is still
13111 faster than indirecting via memory. Don't do this when not optimizing,
13112 since we won't be calculating al of the offsets necessary to do this
13113 simplification. */
13114
13115static void
e32bac5b 13116arm_encode_section_info (tree decl, rtx rtl, int first)
fb49053f
RH
13117{
13118 /* This doesn't work with AOF syntax, since the string table may be in
13119 a different AREA. */
13120#ifndef AOF_ASSEMBLER
13121 if (optimize > 0 && TREE_CONSTANT (decl)
13122 && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
c6a2438a 13123 SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
fb49053f
RH
13124#endif
13125
13126 /* If we are referencing a function that is weak then encode a long call
13127 flag in the function name, otherwise if the function is static or
13128 or known to be defined in this file then encode a short call flag. */
13129 if (first && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
13130 {
13131 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl))
13132 arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR);
13133 else if (! TREE_PUBLIC (decl))
13134 arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR);
13135 }
13136}
13137#endif /* !ARM_PE */
483ab821 13138
4977bab6 13139static void
e32bac5b 13140arm_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
4977bab6
ZW
13141{
13142 if (arm_ccfsm_state == 3 && (unsigned) arm_target_label == labelno
13143 && !strcmp (prefix, "L"))
13144 {
13145 arm_ccfsm_state = 0;
13146 arm_target_insn = NULL;
13147 }
13148 default_internal_label (stream, prefix, labelno);
13149}
13150
c590b625
RH
13151/* Output code to add DELTA to the first argument, and then jump
13152 to FUNCTION. Used for C++ multiple inheritance. */
c590b625 13153static void
e32bac5b
RE
13154arm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
13155 HOST_WIDE_INT delta,
13156 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
13157 tree function)
483ab821
MM
13158{
13159 int mi_delta = delta;
13160 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
13161 int shift = 0;
61f71b34 13162 int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
483ab821
MM
13163 ? 1 : 0);
13164 if (mi_delta < 0)
13165 mi_delta = - mi_delta;
13166 while (mi_delta != 0)
13167 {
13168 if ((mi_delta & (3 << shift)) == 0)
13169 shift += 2;
13170 else
13171 {
13172 asm_fprintf (file, "\t%s\t%r, %r, #%d\n",
13173 mi_op, this_regno, this_regno,
13174 mi_delta & (0xff << shift));
13175 mi_delta &= ~(0xff << shift);
13176 shift += 8;
13177 }
13178 }
13179 fputs ("\tb\t", file);
13180 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
13181 if (NEED_PLT_RELOC)
13182 fputs ("(PLT)", file);
13183 fputc ('\n', file);
13184}
5a9335ef
NC
13185
13186int
6f5f2481 13187arm_emit_vector_const (FILE *file, rtx x)
5a9335ef
NC
13188{
13189 int i;
13190 const char * pattern;
13191
13192 if (GET_CODE (x) != CONST_VECTOR)
13193 abort ();
13194
13195 switch (GET_MODE (x))
13196 {
13197 case V2SImode: pattern = "%08x"; break;
13198 case V4HImode: pattern = "%04x"; break;
13199 case V8QImode: pattern = "%02x"; break;
13200 default: abort ();
13201 }
13202
13203 fprintf (file, "0x");
13204 for (i = CONST_VECTOR_NUNITS (x); i--;)
13205 {
13206 rtx element;
13207
13208 element = CONST_VECTOR_ELT (x, i);
13209 fprintf (file, pattern, INTVAL (element));
13210 }
13211
13212 return 1;
13213}
13214
13215const char *
6f5f2481 13216arm_output_load_gr (rtx *operands)
5a9335ef
NC
13217{
13218 rtx reg;
13219 rtx offset;
13220 rtx wcgr;
13221 rtx sum;
13222
13223 if (GET_CODE (operands [1]) != MEM
13224 || GET_CODE (sum = XEXP (operands [1], 0)) != PLUS
13225 || GET_CODE (reg = XEXP (sum, 0)) != REG
13226 || GET_CODE (offset = XEXP (sum, 1)) != CONST_INT
13227 || ((INTVAL (offset) < 1024) && (INTVAL (offset) > -1024)))
13228 return "wldrw%?\t%0, %1";
13229
13230 /* Fix up an out-of-range load of a GR register. */
13231 output_asm_insn ("str%?\t%0, [sp, #-4]!\t@ Start of GR load expansion", & reg);
13232 wcgr = operands[0];
13233 operands[0] = reg;
13234 output_asm_insn ("ldr%?\t%0, %1", operands);
13235
13236 operands[0] = wcgr;
13237 operands[1] = reg;
13238 output_asm_insn ("tmcr%?\t%0, %1", operands);
13239 output_asm_insn ("ldr%?\t%0, [sp], #4\t@ End of GR load expansion", & reg);
13240
13241 return "";
13242}
This page took 3.247424 seconds and 5 git commands to generate.