]> gcc.gnu.org Git - gcc.git/blame - gcc/config/arm/arm.c
2003-12-19 Michael Koch <konqueror@gmx.de>
[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
839a4992 852 1 degrades less severely than a setting of 2. This could change if
577d6328
RE
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
839a4992 1054 page fault. We work around this problem by popping r3 along with
a72d4945
RE
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
07e58265 2871/* Return nonzero if X is valid as an Thumb state base register. */
76a318e9 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
07e58265 2886 || regno > LAST_VIRTUAL_REGISTER
76a318e9
RE
2887 || regno == FRAME_POINTER_REGNUM
2888 || (GET_MODE_SIZE (mode) >= 4
2889 && (regno == STACK_POINTER_REGNUM
07e58265 2890 || x >= FIRST_PSEUDO_REGISTER
76a318e9
RE
2891 || x == hard_frame_pointer_rtx
2892 || x == arg_pointer_rtx)));
2893}
2894
2895/* Return nonzero if x is a legitimate index register. This is the case
2896 for any base register that can access a QImode object. */
2897inline static int
e32bac5b 2898thumb_index_register_rtx_p (rtx x, int strict_p)
76a318e9
RE
2899{
2900 return thumb_base_register_rtx_p (x, QImode, strict_p);
2901}
2902
2903/* Return nonzero if x is a legitimate Thumb-state address.
2904
2905 The AP may be eliminated to either the SP or the FP, so we use the
2906 least common denominator, e.g. SImode, and offsets from 0 to 64.
2907
2908 ??? Verify whether the above is the right approach.
2909
2910 ??? Also, the FP may be eliminated to the SP, so perhaps that
2911 needs special handling also.
2912
2913 ??? Look at how the mips16 port solves this problem. It probably uses
2914 better ways to solve some of these problems.
2915
2916 Although it is not incorrect, we don't accept QImode and HImode
2917 addresses based on the frame pointer or arg pointer until the
2918 reload pass starts. This is so that eliminating such addresses
2919 into stack based ones won't produce impossible code. */
2920int
e32bac5b 2921thumb_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
76a318e9
RE
2922{
2923 /* ??? Not clear if this is right. Experiment. */
2924 if (GET_MODE_SIZE (mode) < 4
2925 && !(reload_in_progress || reload_completed)
2926 && (reg_mentioned_p (frame_pointer_rtx, x)
2927 || reg_mentioned_p (arg_pointer_rtx, x)
2928 || reg_mentioned_p (virtual_incoming_args_rtx, x)
2929 || reg_mentioned_p (virtual_outgoing_args_rtx, x)
2930 || reg_mentioned_p (virtual_stack_dynamic_rtx, x)
2931 || reg_mentioned_p (virtual_stack_vars_rtx, x)))
2932 return 0;
2933
2934 /* Accept any base register. SP only in SImode or larger. */
2935 else if (thumb_base_register_rtx_p (x, mode, strict_p))
2936 return 1;
2937
18dbd950 2938 /* This is PC relative data before arm_reorg runs. */
76a318e9
RE
2939 else if (GET_MODE_SIZE (mode) >= 4 && CONSTANT_P (x)
2940 && GET_CODE (x) == SYMBOL_REF
2941 && CONSTANT_POOL_ADDRESS_P (x) && ! flag_pic)
2942 return 1;
2943
18dbd950 2944 /* This is PC relative data after arm_reorg runs. */
76a318e9
RE
2945 else if (GET_MODE_SIZE (mode) >= 4 && reload_completed
2946 && (GET_CODE (x) == LABEL_REF
2947 || (GET_CODE (x) == CONST
2948 && GET_CODE (XEXP (x, 0)) == PLUS
2949 && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
2950 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
2951 return 1;
2952
2953 /* Post-inc indexing only supported for SImode and larger. */
2954 else if (GET_CODE (x) == POST_INC && GET_MODE_SIZE (mode) >= 4
2955 && thumb_index_register_rtx_p (XEXP (x, 0), strict_p))
2956 return 1;
2957
2958 else if (GET_CODE (x) == PLUS)
2959 {
2960 /* REG+REG address can be any two index registers. */
2961 /* We disallow FRAME+REG addressing since we know that FRAME
2962 will be replaced with STACK, and SP relative addressing only
2963 permits SP+OFFSET. */
2964 if (GET_MODE_SIZE (mode) <= 4
2965 && XEXP (x, 0) != frame_pointer_rtx
2966 && XEXP (x, 1) != frame_pointer_rtx
76a318e9
RE
2967 && thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
2968 && thumb_index_register_rtx_p (XEXP (x, 1), strict_p))
2969 return 1;
2970
2971 /* REG+const has 5-7 bit offset for non-SP registers. */
2972 else if ((thumb_index_register_rtx_p (XEXP (x, 0), strict_p)
2973 || XEXP (x, 0) == arg_pointer_rtx)
2974 && GET_CODE (XEXP (x, 1)) == CONST_INT
2975 && thumb_legitimate_offset_p (mode, INTVAL (XEXP (x, 1))))
2976 return 1;
2977
2978 /* REG+const has 10 bit offset for SP, but only SImode and
2979 larger is supported. */
2980 /* ??? Should probably check for DI/DFmode overflow here
2981 just like GO_IF_LEGITIMATE_OFFSET does. */
2982 else if (GET_CODE (XEXP (x, 0)) == REG
2983 && REGNO (XEXP (x, 0)) == STACK_POINTER_REGNUM
2984 && GET_MODE_SIZE (mode) >= 4
2985 && GET_CODE (XEXP (x, 1)) == CONST_INT
2986 && INTVAL (XEXP (x, 1)) >= 0
2987 && INTVAL (XEXP (x, 1)) + GET_MODE_SIZE (mode) <= 1024
2988 && (INTVAL (XEXP (x, 1)) & 3) == 0)
2989 return 1;
2990
2991 else if (GET_CODE (XEXP (x, 0)) == REG
2992 && REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
2993 && GET_MODE_SIZE (mode) >= 4
2994 && GET_CODE (XEXP (x, 1)) == CONST_INT
2995 && (INTVAL (XEXP (x, 1)) & 3) == 0)
2996 return 1;
2997 }
2998
2999 else if (GET_MODE_CLASS (mode) != MODE_FLOAT
3000 && GET_CODE (x) == SYMBOL_REF
3001 && CONSTANT_POOL_ADDRESS_P (x)
3002 && !(flag_pic
3003 && symbol_mentioned_p (get_pool_constant (x))))
3004 return 1;
3005
3006 return 0;
3007}
3008
3009/* Return nonzero if VAL can be used as an offset in a Thumb-state address
3010 instruction of mode MODE. */
3011int
e32bac5b 3012thumb_legitimate_offset_p (enum machine_mode mode, HOST_WIDE_INT val)
76a318e9
RE
3013{
3014 switch (GET_MODE_SIZE (mode))
3015 {
3016 case 1:
3017 return val >= 0 && val < 32;
3018
3019 case 2:
3020 return val >= 0 && val < 64 && (val & 1) == 0;
3021
3022 default:
3023 return (val >= 0
3024 && (val + GET_MODE_SIZE (mode)) <= 128
3025 && (val & 3) == 0);
3026 }
3027}
3028
ccf4d512
RE
3029/* Try machine-dependent ways of modifying an illegitimate address
3030 to be legitimate. If we find one, return the new, valid address. */
ccf4d512 3031rtx
e32bac5b 3032arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
ccf4d512
RE
3033{
3034 if (GET_CODE (x) == PLUS)
3035 {
3036 rtx xop0 = XEXP (x, 0);
3037 rtx xop1 = XEXP (x, 1);
3038
3039 if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
3040 xop0 = force_reg (SImode, xop0);
3041
3042 if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
3043 xop1 = force_reg (SImode, xop1);
3044
3045 if (ARM_BASE_REGISTER_RTX_P (xop0)
3046 && GET_CODE (xop1) == CONST_INT)
3047 {
3048 HOST_WIDE_INT n, low_n;
3049 rtx base_reg, val;
3050 n = INTVAL (xop1);
3051
3052 if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
3053 {
3054 low_n = n & 0x0f;
3055 n &= ~0x0f;
3056 if (low_n > 4)
3057 {
3058 n += 16;
3059 low_n -= 16;
3060 }
3061 }
3062 else
3063 {
3064 low_n = ((mode) == TImode ? 0
3065 : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));
3066 n -= low_n;
3067 }
3068
3069 base_reg = gen_reg_rtx (SImode);
3070 val = force_operand (gen_rtx_PLUS (SImode, xop0,
3071 GEN_INT (n)), NULL_RTX);
3072 emit_move_insn (base_reg, val);
3073 x = (low_n == 0 ? base_reg
3074 : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n)));
3075 }
3076 else if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
3077 x = gen_rtx_PLUS (SImode, xop0, xop1);
3078 }
3079
3080 /* XXX We don't allow MINUS any more -- see comment in
3081 arm_legitimate_address_p (). */
3082 else if (GET_CODE (x) == MINUS)
3083 {
3084 rtx xop0 = XEXP (x, 0);
3085 rtx xop1 = XEXP (x, 1);
3086
3087 if (CONSTANT_P (xop0))
3088 xop0 = force_reg (SImode, xop0);
3089
3090 if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))
3091 xop1 = force_reg (SImode, xop1);
3092
3093 if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
3094 x = gen_rtx_MINUS (SImode, xop0, xop1);
3095 }
3096
3097 if (flag_pic)
3098 {
3099 /* We need to find and carefully transform any SYMBOL and LABEL
3100 references; so go back to the original address expression. */
3101 rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
3102
3103 if (new_x != orig_x)
3104 x = new_x;
3105 }
3106
3107 return x;
3108}
3109
6b990f6b
RE
3110\f
3111
e2c671ba
RE
3112#define REG_OR_SUBREG_REG(X) \
3113 (GET_CODE (X) == REG \
3114 || (GET_CODE (X) == SUBREG && GET_CODE (SUBREG_REG (X)) == REG))
3115
3116#define REG_OR_SUBREG_RTX(X) \
3117 (GET_CODE (X) == REG ? (X) : SUBREG_REG (X))
3118
d5b7b3ae
RE
3119#ifndef COSTS_N_INSNS
3120#define COSTS_N_INSNS(N) ((N) * 4 - 2)
3121#endif
e32bac5b 3122/* Worker routine for arm_rtx_costs. */
3c50106f 3123static inline int
e32bac5b 3124arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
e2c671ba
RE
3125{
3126 enum machine_mode mode = GET_MODE (x);
3127 enum rtx_code subcode;
3128 int extra_cost;
3129
d5b7b3ae
RE
3130 if (TARGET_THUMB)
3131 {
3132 switch (code)
3133 {
3134 case ASHIFT:
3135 case ASHIFTRT:
3136 case LSHIFTRT:
3137 case ROTATERT:
3138 case PLUS:
3139 case MINUS:
3140 case COMPARE:
3141 case NEG:
3142 case NOT:
3143 return COSTS_N_INSNS (1);
3144
3145 case MULT:
3146 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
3147 {
3148 int cycles = 0;
3149 unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1));
3150
3151 while (i)
3152 {
3153 i >>= 2;
5895f793 3154 cycles++;
d5b7b3ae
RE
3155 }
3156 return COSTS_N_INSNS (2) + cycles;
3157 }
3158 return COSTS_N_INSNS (1) + 16;
3159
3160 case SET:
3161 return (COSTS_N_INSNS (1)
3162 + 4 * ((GET_CODE (SET_SRC (x)) == MEM)
3163 + GET_CODE (SET_DEST (x)) == MEM));
3164
3165 case CONST_INT:
3166 if (outer == SET)
3167 {
3168 if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256)
3169 return 0;
3170 if (thumb_shiftable_const (INTVAL (x)))
3171 return COSTS_N_INSNS (2);
3172 return COSTS_N_INSNS (3);
3173 }
c769a35d 3174 else if ((outer == PLUS || outer == COMPARE)
d5b7b3ae 3175 && INTVAL (x) < 256 && INTVAL (x) > -256)
c769a35d
RE
3176 return 0;
3177 else if (outer == AND
3178 && INTVAL (x) < 256 && INTVAL (x) >= -256)
3179 return COSTS_N_INSNS (1);
d5b7b3ae
RE
3180 else if (outer == ASHIFT || outer == ASHIFTRT
3181 || outer == LSHIFTRT)
3182 return 0;
3183 return COSTS_N_INSNS (2);
3184
3185 case CONST:
3186 case CONST_DOUBLE:
3187 case LABEL_REF:
3188 case SYMBOL_REF:
3189 return COSTS_N_INSNS (3);
3190
3191 case UDIV:
3192 case UMOD:
3193 case DIV:
3194 case MOD:
3195 return 100;
3196
3197 case TRUNCATE:
3198 return 99;
3199
3200 case AND:
3201 case XOR:
3202 case IOR:
3203 /* XXX guess. */
3204 return 8;
3205
3206 case ADDRESSOF:
3207 case MEM:
3208 /* XXX another guess. */
3209 /* Memory costs quite a lot for the first word, but subsequent words
3210 load at the equivalent of a single insn each. */
3211 return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
48f6efae
NC
3212 + ((GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
3213 ? 4 : 0));
d5b7b3ae
RE
3214
3215 case IF_THEN_ELSE:
3216 /* XXX a guess. */
3217 if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
3218 return 14;
3219 return 2;
3220
3221 case ZERO_EXTEND:
3222 /* XXX still guessing. */
3223 switch (GET_MODE (XEXP (x, 0)))
3224 {
3225 case QImode:
3226 return (1 + (mode == DImode ? 4 : 0)
3227 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3228
3229 case HImode:
3230 return (4 + (mode == DImode ? 4 : 0)
3231 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3232
3233 case SImode:
3234 return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3235
3236 default:
3237 return 99;
3238 }
3239
3240 default:
3241 return 99;
d5b7b3ae
RE
3242 }
3243 }
3244
e2c671ba
RE
3245 switch (code)
3246 {
3247 case MEM:
3248 /* Memory costs quite a lot for the first word, but subsequent words
3249 load at the equivalent of a single insn each. */
3250 return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
48f6efae
NC
3251 + (GET_CODE (x) == SYMBOL_REF
3252 && CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0));
e2c671ba
RE
3253
3254 case DIV:
3255 case MOD:
b9c53150
RS
3256 case UDIV:
3257 case UMOD:
3258 return optimize_size ? COSTS_N_INSNS (2) : 100;
e2c671ba
RE
3259
3260 case ROTATE:
3261 if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG)
3262 return 4;
3263 /* Fall through */
3264 case ROTATERT:
3265 if (mode != SImode)
3266 return 8;
3267 /* Fall through */
3268 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3269 if (mode == DImode)
3270 return (8 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : 8)
3271 + ((GET_CODE (XEXP (x, 0)) == REG
3272 || (GET_CODE (XEXP (x, 0)) == SUBREG
3273 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
3274 ? 0 : 8));
3275 return (1 + ((GET_CODE (XEXP (x, 0)) == REG
3276 || (GET_CODE (XEXP (x, 0)) == SUBREG
3277 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
3278 ? 0 : 4)
3279 + ((GET_CODE (XEXP (x, 1)) == REG
3280 || (GET_CODE (XEXP (x, 1)) == SUBREG
3281 && GET_CODE (SUBREG_REG (XEXP (x, 1))) == REG)
3282 || (GET_CODE (XEXP (x, 1)) == CONST_INT))
3283 ? 0 : 4));
3284
3285 case MINUS:
3286 if (mode == DImode)
3287 return (4 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 8)
3288 + ((REG_OR_SUBREG_REG (XEXP (x, 0))
3289 || (GET_CODE (XEXP (x, 0)) == CONST_INT
3290 && const_ok_for_arm (INTVAL (XEXP (x, 0)))))
3291 ? 0 : 8));
3292
3293 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
3294 return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
3295 || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
3b684012 3296 && const_double_rtx_ok_for_fpa (XEXP (x, 1))))
e2c671ba
RE
3297 ? 0 : 8)
3298 + ((REG_OR_SUBREG_REG (XEXP (x, 0))
3299 || (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
3b684012 3300 && const_double_rtx_ok_for_fpa (XEXP (x, 0))))
e2c671ba
RE
3301 ? 0 : 8));
3302
3303 if (((GET_CODE (XEXP (x, 0)) == CONST_INT
3304 && const_ok_for_arm (INTVAL (XEXP (x, 0)))
3305 && REG_OR_SUBREG_REG (XEXP (x, 1))))
3306 || (((subcode = GET_CODE (XEXP (x, 1))) == ASHIFT
3307 || subcode == ASHIFTRT || subcode == LSHIFTRT
3308 || subcode == ROTATE || subcode == ROTATERT
3309 || (subcode == MULT
3310 && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
3311 && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
3312 (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
3313 && REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 0))
3314 && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 1))
3315 || GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
3316 && REG_OR_SUBREG_REG (XEXP (x, 0))))
3317 return 1;
3318 /* Fall through */
3319
3320 case PLUS:
3321 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
3322 return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
3323 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
3324 || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
3b684012 3325 && const_double_rtx_ok_for_fpa (XEXP (x, 1))))
e2c671ba
RE
3326 ? 0 : 8));
3327
3328 /* Fall through */
3329 case AND: case XOR: case IOR:
3330 extra_cost = 0;
3331
3332 /* Normally the frame registers will be spilt into reg+const during
3333 reload, so it is a bad idea to combine them with other instructions,
3334 since then they might not be moved outside of loops. As a compromise
3335 we allow integration with ops that have a constant as their second
3336 operand. */
3337 if ((REG_OR_SUBREG_REG (XEXP (x, 0))
3338 && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))
3339 && GET_CODE (XEXP (x, 1)) != CONST_INT)
3340 || (REG_OR_SUBREG_REG (XEXP (x, 0))
3341 && ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))))
3342 extra_cost = 4;
3343
3344 if (mode == DImode)
3345 return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
3346 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
3347 || (GET_CODE (XEXP (x, 1)) == CONST_INT
74bbc178 3348 && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
e2c671ba
RE
3349 ? 0 : 8));
3350
3351 if (REG_OR_SUBREG_REG (XEXP (x, 0)))
3352 return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost)
3353 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
3354 || (GET_CODE (XEXP (x, 1)) == CONST_INT
74bbc178 3355 && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
e2c671ba
RE
3356 ? 0 : 4));
3357
3358 else if (REG_OR_SUBREG_REG (XEXP (x, 1)))
3359 return (1 + extra_cost
3360 + ((((subcode = GET_CODE (XEXP (x, 0))) == ASHIFT
3361 || subcode == LSHIFTRT || subcode == ASHIFTRT
3362 || subcode == ROTATE || subcode == ROTATERT
3363 || (subcode == MULT
3364 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3365 && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
ad076f4e 3366 (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
e2c671ba
RE
3367 && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 0)))
3368 && ((REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 1)))
ad076f4e 3369 || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
e2c671ba
RE
3370 ? 0 : 4));
3371
3372 return 8;
3373
3374 case MULT:
b111229a 3375 /* There is no point basing this on the tuning, since it is always the
6354dc9b 3376 fast variant if it exists at all. */
2b835d68
RE
3377 if (arm_fast_multiply && mode == DImode
3378 && (GET_CODE (XEXP (x, 0)) == GET_CODE (XEXP (x, 1)))
3379 && (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
3380 || GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
3381 return 8;
3382
e2c671ba
RE
3383 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3384 || mode == DImode)
3385 return 30;
3386
3387 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
3388 {
2b835d68 3389 unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
30cf4896 3390 & (unsigned HOST_WIDE_INT) 0xffffffff);
e3b66120
JL
3391 int cost, const_ok = const_ok_for_arm (i);
3392 int j, booth_unit_size;
3393
3394 if (arm_tune_xscale)
3395 {
3396 unsigned HOST_WIDE_INT masked_const;
3397
3398 /* The cost will be related to two insns.
3399 First a load of the constant (MOV or LDR), then a multiply. */
3400 cost = 2;
3401 if (! const_ok)
3402 cost += 1; /* LDR is probably more expensive because
3403 of longer result latency. */
3404 masked_const = i & 0xffff8000;
3405 if (masked_const != 0 && masked_const != 0xffff8000)
3406 {
3407 masked_const = i & 0xf8000000;
3408 if (masked_const == 0 || masked_const == 0xf8000000)
3409 cost += 1;
3410 else
3411 cost += 2;
3412 }
3413 return cost;
3414 }
6354dc9b
NC
3415
3416 /* Tune as appropriate. */
e3b66120
JL
3417 cost = const_ok ? 4 : 8;
3418 booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
2b835d68 3419 for (j = 0; i && j < 32; j += booth_unit_size)
e2c671ba 3420 {
2b835d68 3421 i >>= booth_unit_size;
e3b66120 3422 cost += 2;
e2c671ba
RE
3423 }
3424
e3b66120 3425 return cost;
e2c671ba
RE
3426 }
3427
aec3cfba 3428 return (((tune_flags & FL_FAST_MULT) ? 8 : 30)
2b835d68 3429 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
e2c671ba
RE
3430 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4));
3431
56636818
JL
3432 case TRUNCATE:
3433 if (arm_fast_multiply && mode == SImode
3434 && GET_CODE (XEXP (x, 0)) == LSHIFTRT
3435 && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
3436 && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
3437 == GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)))
3438 && (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
3439 || GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND))
3440 return 8;
3441 return 99;
3442
e2c671ba
RE
3443 case NEG:
3444 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
3445 return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6);
3446 /* Fall through */
3447 case NOT:
3448 if (mode == DImode)
3449 return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
3450
3451 return 1 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
3452
3453 case IF_THEN_ELSE:
3454 if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
3455 return 14;
3456 return 2;
3457
3458 case COMPARE:
3459 return 1;
3460
3461 case ABS:
3462 return 4 + (mode == DImode ? 4 : 0);
3463
3464 case SIGN_EXTEND:
3465 if (GET_MODE (XEXP (x, 0)) == QImode)
3466 return (4 + (mode == DImode ? 4 : 0)
3467 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3468 /* Fall through */
3469 case ZERO_EXTEND:
3470 switch (GET_MODE (XEXP (x, 0)))
3471 {
3472 case QImode:
3473 return (1 + (mode == DImode ? 4 : 0)
3474 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3475
3476 case HImode:
3477 return (4 + (mode == DImode ? 4 : 0)
3478 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
3479
3480 case SImode:
3481 return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
ad076f4e 3482
5a9335ef
NC
3483 case V8QImode:
3484 case V4HImode:
3485 case V2SImode:
3486 case V4QImode:
3487 case V2HImode:
3488 return 1;
3489
ad076f4e
RE
3490 default:
3491 break;
e2c671ba
RE
3492 }
3493 abort ();
3494
d5b7b3ae
RE
3495 case CONST_INT:
3496 if (const_ok_for_arm (INTVAL (x)))
3497 return outer == SET ? 2 : -1;
3498 else if (outer == AND
5895f793 3499 && const_ok_for_arm (~INTVAL (x)))
d5b7b3ae
RE
3500 return -1;
3501 else if ((outer == COMPARE
3502 || outer == PLUS || outer == MINUS)
5895f793 3503 && const_ok_for_arm (-INTVAL (x)))
d5b7b3ae
RE
3504 return -1;
3505 else
3506 return 5;
3507
3508 case CONST:
3509 case LABEL_REF:
3510 case SYMBOL_REF:
3511 return 6;
3512
3513 case CONST_DOUBLE:
3b684012 3514 if (const_double_rtx_ok_for_fpa (x))
d5b7b3ae
RE
3515 return outer == SET ? 2 : -1;
3516 else if ((outer == COMPARE || outer == PLUS)
3b684012 3517 && neg_const_double_rtx_ok_for_fpa (x))
d5b7b3ae
RE
3518 return -1;
3519 return 7;
3520
e2c671ba
RE
3521 default:
3522 return 99;
3523 }
3524}
32de079a 3525
3c50106f 3526static bool
e32bac5b 3527arm_rtx_costs (rtx x, int code, int outer_code, int *total)
3c50106f
RH
3528{
3529 *total = arm_rtx_costs_1 (x, code, outer_code);
3530 return true;
3531}
3532
dcefdf67
RH
3533/* All address computations that can be done are free, but rtx cost returns
3534 the same for practically all of them. So we weight the different types
3535 of address here in the order (most pref first):
3536 PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */
d2b6eb76
ZW
3537static inline int
3538arm_arm_address_cost (rtx x)
3539{
3540 enum rtx_code c = GET_CODE (x);
3541
3542 if (c == PRE_INC || c == PRE_DEC || c == POST_INC || c == POST_DEC)
3543 return 0;
3544 if (c == MEM || c == LABEL_REF || c == SYMBOL_REF)
3545 return 10;
3546
3547 if (c == PLUS || c == MINUS)
3548 {
3549 char cl0 = GET_RTX_CLASS (GET_CODE (XEXP (x, 0)));
3550 char cl1 = GET_RTX_CLASS (GET_CODE (XEXP (x, 1)));
3551
3552 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
3553 return 2;
3554
3555 if (cl0 == '2' || cl0 == 'c' || cl1 == '2' || cl1 == 'c')
3556 return 3;
3557
3558 return 4;
3559 }
3560
3561 return 6;
3562}
3563
3564static inline int
3565arm_thumb_address_cost (rtx x)
3566{
3567 enum rtx_code c = GET_CODE (x);
3568
3569 if (c == REG)
3570 return 1;
3571 if (c == PLUS
3572 && GET_CODE (XEXP (x, 0)) == REG
3573 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3574 return 1;
3575
3576 return 2;
3577}
3578
dcefdf67 3579static int
e32bac5b 3580arm_address_cost (rtx x)
dcefdf67 3581{
d2b6eb76 3582 return TARGET_ARM ? arm_arm_address_cost (x) : arm_thumb_address_cost (x);
dcefdf67
RH
3583}
3584
103fc15d 3585static int
e32bac5b 3586arm_use_dfa_pipeline_interface (void)
103fc15d
BE
3587{
3588 return true;
3589}
3590
c237e94a 3591static int
e32bac5b 3592arm_adjust_cost (rtx insn, rtx link, rtx dep, int cost)
32de079a
RE
3593{
3594 rtx i_pat, d_pat;
3595
d19fb8e3
NC
3596 /* Some true dependencies can have a higher cost depending
3597 on precisely how certain input operands are used. */
4b3c2e48 3598 if (arm_tune_xscale
d19fb8e3 3599 && REG_NOTE_KIND (link) == 0
eda833e3
BE
3600 && recog_memoized (insn) >= 0
3601 && recog_memoized (dep) >= 0)
d19fb8e3
NC
3602 {
3603 int shift_opnum = get_attr_shift (insn);
3604 enum attr_type attr_type = get_attr_type (dep);
3605
3606 /* If nonzero, SHIFT_OPNUM contains the operand number of a shifted
3607 operand for INSN. If we have a shifted input operand and the
3608 instruction we depend on is another ALU instruction, then we may
3609 have to account for an additional stall. */
3610 if (shift_opnum != 0 && attr_type == TYPE_NORMAL)
3611 {
3612 rtx shifted_operand;
3613 int opno;
3614
3615 /* Get the shifted operand. */
3616 extract_insn (insn);
3617 shifted_operand = recog_data.operand[shift_opnum];
3618
3619 /* Iterate over all the operands in DEP. If we write an operand
3620 that overlaps with SHIFTED_OPERAND, then we have increase the
3621 cost of this dependency. */
3622 extract_insn (dep);
3623 preprocess_constraints ();
3624 for (opno = 0; opno < recog_data.n_operands; opno++)
3625 {
3626 /* We can ignore strict inputs. */
3627 if (recog_data.operand_type[opno] == OP_IN)
3628 continue;
3629
3630 if (reg_overlap_mentioned_p (recog_data.operand[opno],
3631 shifted_operand))
3632 return 2;
3633 }
3634 }
3635 }
3636
6354dc9b 3637 /* XXX This is not strictly true for the FPA. */
d5b7b3ae
RE
3638 if (REG_NOTE_KIND (link) == REG_DEP_ANTI
3639 || REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
b36ba79f
RE
3640 return 0;
3641
d5b7b3ae
RE
3642 /* Call insns don't incur a stall, even if they follow a load. */
3643 if (REG_NOTE_KIND (link) == 0
3644 && GET_CODE (insn) == CALL_INSN)
3645 return 1;
3646
32de079a
RE
3647 if ((i_pat = single_set (insn)) != NULL
3648 && GET_CODE (SET_SRC (i_pat)) == MEM
3649 && (d_pat = single_set (dep)) != NULL
3650 && GET_CODE (SET_DEST (d_pat)) == MEM)
3651 {
48f6efae 3652 rtx src_mem = XEXP (SET_SRC (i_pat), 0);
32de079a
RE
3653 /* This is a load after a store, there is no conflict if the load reads
3654 from a cached area. Assume that loads from the stack, and from the
3655 constant pool are cached, and that others will miss. This is a
6354dc9b 3656 hack. */
32de079a 3657
48f6efae
NC
3658 if ((GET_CODE (src_mem) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (src_mem))
3659 || reg_mentioned_p (stack_pointer_rtx, src_mem)
3660 || reg_mentioned_p (frame_pointer_rtx, src_mem)
3661 || reg_mentioned_p (hard_frame_pointer_rtx, src_mem))
949d79eb 3662 return 1;
32de079a
RE
3663 }
3664
3665 return cost;
3666}
3667
ff9940b0
RE
3668static int fpa_consts_inited = 0;
3669
1d6e90ac 3670static const char * const strings_fpa[8] =
62b10bbc 3671{
2b835d68
RE
3672 "0", "1", "2", "3",
3673 "4", "5", "0.5", "10"
3674};
ff9940b0
RE
3675
3676static REAL_VALUE_TYPE values_fpa[8];
3677
3678static void
e32bac5b 3679init_fpa_table (void)
ff9940b0
RE
3680{
3681 int i;
3682 REAL_VALUE_TYPE r;
3683
3684 for (i = 0; i < 8; i++)
3685 {
3686 r = REAL_VALUE_ATOF (strings_fpa[i], DFmode);
3687 values_fpa[i] = r;
3688 }
f3bb6135 3689
ff9940b0
RE
3690 fpa_consts_inited = 1;
3691}
3692
3b684012 3693/* Return TRUE if rtx X is a valid immediate FPA constant. */
cce8749e 3694int
e32bac5b 3695const_double_rtx_ok_for_fpa (rtx x)
cce8749e 3696{
ff9940b0
RE
3697 REAL_VALUE_TYPE r;
3698 int i;
3699
3700 if (!fpa_consts_inited)
3701 init_fpa_table ();
3702
3703 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3704 if (REAL_VALUE_MINUS_ZERO (r))
3705 return 0;
f3bb6135 3706
ff9940b0
RE
3707 for (i = 0; i < 8; i++)
3708 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
3709 return 1;
f3bb6135 3710
ff9940b0 3711 return 0;
f3bb6135 3712}
ff9940b0 3713
3b684012 3714/* Return TRUE if rtx X is a valid immediate FPA constant. */
ff9940b0 3715int
e32bac5b 3716neg_const_double_rtx_ok_for_fpa (rtx x)
ff9940b0
RE
3717{
3718 REAL_VALUE_TYPE r;
3719 int i;
3720
3721 if (!fpa_consts_inited)
3722 init_fpa_table ();
3723
3724 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
3725 r = REAL_VALUE_NEGATE (r);
3726 if (REAL_VALUE_MINUS_ZERO (r))
3727 return 0;
f3bb6135 3728
ff9940b0
RE
3729 for (i = 0; i < 8; i++)
3730 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
3731 return 1;
f3bb6135 3732
ff9940b0 3733 return 0;
f3bb6135 3734}
cce8749e
CH
3735\f
3736/* Predicates for `match_operand' and `match_operator'. */
3737
ff9940b0 3738/* s_register_operand is the same as register_operand, but it doesn't accept
56a38cec
DE
3739 (SUBREG (MEM)...).
3740
3741 This function exists because at the time it was put in it led to better
3742 code. SUBREG(MEM) always needs a reload in the places where
3743 s_register_operand is used, and this seemed to lead to excessive
3744 reloading. */
ff9940b0 3745int
e32bac5b 3746s_register_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
3747{
3748 if (GET_MODE (op) != mode && mode != VOIDmode)
3749 return 0;
3750
3751 if (GET_CODE (op) == SUBREG)
f3bb6135 3752 op = SUBREG_REG (op);
ff9940b0
RE
3753
3754 /* We don't consider registers whose class is NO_REGS
3755 to be a register operand. */
d5b7b3ae 3756 /* XXX might have to check for lo regs only for thumb ??? */
ff9940b0
RE
3757 return (GET_CODE (op) == REG
3758 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3759 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
3760}
3761
b0888988
RE
3762/* A hard register operand (even before reload. */
3763int
e32bac5b 3764arm_hard_register_operand (rtx op, enum machine_mode mode)
b0888988
RE
3765{
3766 if (GET_MODE (op) != mode && mode != VOIDmode)
3767 return 0;
3768
3769 return (GET_CODE (op) == REG
3770 && REGNO (op) < FIRST_PSEUDO_REGISTER);
3771}
3772
e2c671ba 3773/* Only accept reg, subreg(reg), const_int. */
e2c671ba 3774int
e32bac5b 3775reg_or_int_operand (rtx op, enum machine_mode mode)
e2c671ba
RE
3776{
3777 if (GET_CODE (op) == CONST_INT)
3778 return 1;
3779
3780 if (GET_MODE (op) != mode && mode != VOIDmode)
3781 return 0;
3782
3783 if (GET_CODE (op) == SUBREG)
3784 op = SUBREG_REG (op);
3785
3786 /* We don't consider registers whose class is NO_REGS
3787 to be a register operand. */
3788 return (GET_CODE (op) == REG
3789 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3790 || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
3791}
3792
ff9940b0 3793/* Return 1 if OP is an item in memory, given that we are in reload. */
ff9940b0 3794int
e32bac5b 3795arm_reload_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
ff9940b0
RE
3796{
3797 int regno = true_regnum (op);
3798
5895f793 3799 return (!CONSTANT_P (op)
ff9940b0
RE
3800 && (regno == -1
3801 || (GET_CODE (op) == REG
3802 && REGNO (op) >= FIRST_PSEUDO_REGISTER)));
3803}
3804
4d818c85 3805/* Return 1 if OP is a valid memory address, but not valid for a signed byte
d5b7b3ae 3806 memory access (architecture V4).
f710504c 3807 MODE is QImode if called when computing constraints, or VOIDmode when
d5b7b3ae 3808 emitting patterns. In this latter case we cannot use memory_operand()
6bc82793 3809 because it will fail on badly formed MEMs, which is precisely what we are
d5b7b3ae 3810 trying to catch. */
4d818c85 3811int
e32bac5b 3812bad_signed_byte_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
4d818c85 3813{
d5b7b3ae 3814 if (GET_CODE (op) != MEM)
4d818c85
RE
3815 return 0;
3816
3817 op = XEXP (op, 0);
3818
6354dc9b 3819 /* A sum of anything more complex than reg + reg or reg + const is bad. */
4d818c85 3820 if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
5895f793
RE
3821 && (!s_register_operand (XEXP (op, 0), VOIDmode)
3822 || (!s_register_operand (XEXP (op, 1), VOIDmode)
9c8cc54f 3823 && GET_CODE (XEXP (op, 1)) != CONST_INT)))
4d818c85
RE
3824 return 1;
3825
6354dc9b 3826 /* Big constants are also bad. */
4d818c85
RE
3827 if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT
3828 && (INTVAL (XEXP (op, 1)) > 0xff
3829 || -INTVAL (XEXP (op, 1)) > 0xff))
3830 return 1;
3831
6354dc9b 3832 /* Everything else is good, or can will automatically be made so. */
4d818c85
RE
3833 return 0;
3834}
3835
cce8749e 3836/* Return TRUE for valid operands for the rhs of an ARM instruction. */
cce8749e 3837int
e32bac5b 3838arm_rhs_operand (rtx op, enum machine_mode mode)
cce8749e 3839{
ff9940b0 3840 return (s_register_operand (op, mode)
cce8749e 3841 || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op))));
f3bb6135 3842}
cce8749e 3843
1d6e90ac
NC
3844/* Return TRUE for valid operands for the
3845 rhs of an ARM instruction, or a load. */
ff9940b0 3846int
e32bac5b 3847arm_rhsm_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
3848{
3849 return (s_register_operand (op, mode)
3850 || (GET_CODE (op) == CONST_INT && const_ok_for_arm (INTVAL (op)))
3851 || memory_operand (op, mode));
f3bb6135 3852}
ff9940b0
RE
3853
3854/* Return TRUE for valid operands for the rhs of an ARM instruction, or if a
3855 constant that is valid when negated. */
ff9940b0 3856int
e32bac5b 3857arm_add_operand (rtx op, enum machine_mode mode)
ff9940b0 3858{
d5b7b3ae
RE
3859 if (TARGET_THUMB)
3860 return thumb_cmp_operand (op, mode);
3861
ff9940b0
RE
3862 return (s_register_operand (op, mode)
3863 || (GET_CODE (op) == CONST_INT
3864 && (const_ok_for_arm (INTVAL (op))
3865 || const_ok_for_arm (-INTVAL (op)))));
f3bb6135 3866}
ff9940b0 3867
f9b9980e
RE
3868/* Return TRUE for valid ARM constants (or when valid if negated). */
3869int
91de08c3 3870arm_addimm_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
f9b9980e
RE
3871{
3872 return (GET_CODE (op) == CONST_INT
3873 && (const_ok_for_arm (INTVAL (op))
3874 || const_ok_for_arm (-INTVAL (op))));
3875}
3876
ff9940b0 3877int
e32bac5b 3878arm_not_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
3879{
3880 return (s_register_operand (op, mode)
3881 || (GET_CODE (op) == CONST_INT
3882 && (const_ok_for_arm (INTVAL (op))
3883 || const_ok_for_arm (~INTVAL (op)))));
f3bb6135 3884}
ff9940b0 3885
5165176d
RE
3886/* Return TRUE if the operand is a memory reference which contains an
3887 offsettable address. */
3888int
e32bac5b 3889offsettable_memory_operand (rtx op, enum machine_mode mode)
5165176d
RE
3890{
3891 if (mode == VOIDmode)
3892 mode = GET_MODE (op);
3893
3894 return (mode == GET_MODE (op)
3895 && GET_CODE (op) == MEM
3896 && offsettable_address_p (reload_completed | reload_in_progress,
3897 mode, XEXP (op, 0)));
3898}
3899
3900/* Return TRUE if the operand is a memory reference which is, or can be
3901 made word aligned by adjusting the offset. */
3902int
e32bac5b 3903alignable_memory_operand (rtx op, enum machine_mode mode)
5165176d
RE
3904{
3905 rtx reg;
3906
3907 if (mode == VOIDmode)
3908 mode = GET_MODE (op);
3909
3910 if (mode != GET_MODE (op) || GET_CODE (op) != MEM)
3911 return 0;
3912
3913 op = XEXP (op, 0);
3914
3915 return ((GET_CODE (reg = op) == REG
3916 || (GET_CODE (op) == SUBREG
3917 && GET_CODE (reg = SUBREG_REG (op)) == REG)
3918 || (GET_CODE (op) == PLUS
3919 && GET_CODE (XEXP (op, 1)) == CONST_INT
3920 && (GET_CODE (reg = XEXP (op, 0)) == REG
3921 || (GET_CODE (XEXP (op, 0)) == SUBREG
3922 && GET_CODE (reg = SUBREG_REG (XEXP (op, 0))) == REG))))
bdb429a5 3923 && REGNO_POINTER_ALIGN (REGNO (reg)) >= 32);
5165176d
RE
3924}
3925
b111229a
RE
3926/* Similar to s_register_operand, but does not allow hard integer
3927 registers. */
3928int
e32bac5b 3929f_register_operand (rtx op, enum machine_mode mode)
b111229a
RE
3930{
3931 if (GET_MODE (op) != mode && mode != VOIDmode)
3932 return 0;
3933
3934 if (GET_CODE (op) == SUBREG)
3935 op = SUBREG_REG (op);
3936
3937 /* We don't consider registers whose class is NO_REGS
3938 to be a register operand. */
3939 return (GET_CODE (op) == REG
3940 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
3b684012 3941 || REGNO_REG_CLASS (REGNO (op)) == FPA_REGS));
b111229a
RE
3942}
3943
3b684012 3944/* Return TRUE for valid operands for the rhs of an FPA instruction. */
cce8749e 3945int
e32bac5b 3946fpa_rhs_operand (rtx op, enum machine_mode mode)
cce8749e 3947{
ff9940b0 3948 if (s_register_operand (op, mode))
f3bb6135 3949 return TRUE;
9ce71c6f
BS
3950
3951 if (GET_MODE (op) != mode && mode != VOIDmode)
3952 return FALSE;
3953
3954 if (GET_CODE (op) == CONST_DOUBLE)
3b684012 3955 return const_double_rtx_ok_for_fpa (op);
f3bb6135
RE
3956
3957 return FALSE;
3958}
cce8749e 3959
ff9940b0 3960int
e32bac5b 3961fpa_add_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
3962{
3963 if (s_register_operand (op, mode))
f3bb6135 3964 return TRUE;
9ce71c6f
BS
3965
3966 if (GET_MODE (op) != mode && mode != VOIDmode)
3967 return FALSE;
3968
3969 if (GET_CODE (op) == CONST_DOUBLE)
3b684012
RE
3970 return (const_double_rtx_ok_for_fpa (op)
3971 || neg_const_double_rtx_ok_for_fpa (op));
f3bb6135
RE
3972
3973 return FALSE;
ff9940b0
RE
3974}
3975
9b6b54e2 3976/* Return nonzero if OP is a valid Cirrus memory address pattern. */
9b6b54e2 3977int
e32bac5b 3978cirrus_memory_offset (rtx op)
9b6b54e2
NC
3979{
3980 /* Reject eliminable registers. */
3981 if (! (reload_in_progress || reload_completed)
3982 && ( reg_mentioned_p (frame_pointer_rtx, op)
3983 || reg_mentioned_p (arg_pointer_rtx, op)
3984 || reg_mentioned_p (virtual_incoming_args_rtx, op)
3985 || reg_mentioned_p (virtual_outgoing_args_rtx, op)
3986 || reg_mentioned_p (virtual_stack_dynamic_rtx, op)
3987 || reg_mentioned_p (virtual_stack_vars_rtx, op)))
3988 return 0;
3989
3990 if (GET_CODE (op) == MEM)
3991 {
3992 rtx ind;
3993
3994 ind = XEXP (op, 0);
3995
3996 /* Match: (mem (reg)). */
3997 if (GET_CODE (ind) == REG)
3998 return 1;
3999
4000 /* Match:
4001 (mem (plus (reg)
4002 (const))). */
4003 if (GET_CODE (ind) == PLUS
4004 && GET_CODE (XEXP (ind, 0)) == REG
4005 && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
4006 && GET_CODE (XEXP (ind, 1)) == CONST_INT)
4007 return 1;
4008 }
4009
4010 return 0;
4011}
4012
4013/* Return nonzero if OP is a Cirrus or general register. */
9b6b54e2 4014int
e32bac5b 4015cirrus_register_operand (rtx op, enum machine_mode mode)
9b6b54e2
NC
4016{
4017 if (GET_MODE (op) != mode && mode != VOIDmode)
4018 return FALSE;
4019
4020 if (GET_CODE (op) == SUBREG)
4021 op = SUBREG_REG (op);
4022
4023 return (GET_CODE (op) == REG
4024 && (REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS
4025 || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS));
4026}
4027
4028/* Return nonzero if OP is a cirrus FP register. */
9b6b54e2 4029int
e32bac5b 4030cirrus_fp_register (rtx op, enum machine_mode mode)
9b6b54e2
NC
4031{
4032 if (GET_MODE (op) != mode && mode != VOIDmode)
4033 return FALSE;
4034
4035 if (GET_CODE (op) == SUBREG)
4036 op = SUBREG_REG (op);
4037
4038 return (GET_CODE (op) == REG
4039 && (REGNO (op) >= FIRST_PSEUDO_REGISTER
4040 || REGNO_REG_CLASS (REGNO (op)) == CIRRUS_REGS));
4041}
4042
4043/* Return nonzero if OP is a 6bit constant (0..63). */
9b6b54e2 4044int
e32bac5b 4045cirrus_shift_const (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
9b6b54e2
NC
4046{
4047 return (GET_CODE (op) == CONST_INT
4048 && INTVAL (op) >= 0
4049 && INTVAL (op) < 64);
4050}
4051
f0375c66
NC
4052/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction.
4053 Use by the Cirrus Maverick code which has to workaround
4054 a hardware bug triggered by such instructions. */
f0375c66 4055static bool
e32bac5b 4056arm_memory_load_p (rtx insn)
9b6b54e2
NC
4057{
4058 rtx body, lhs, rhs;;
4059
f0375c66
NC
4060 if (insn == NULL_RTX || GET_CODE (insn) != INSN)
4061 return false;
9b6b54e2
NC
4062
4063 body = PATTERN (insn);
4064
4065 if (GET_CODE (body) != SET)
f0375c66 4066 return false;
9b6b54e2
NC
4067
4068 lhs = XEXP (body, 0);
4069 rhs = XEXP (body, 1);
4070
f0375c66
NC
4071 lhs = REG_OR_SUBREG_RTX (lhs);
4072
4073 /* If the destination is not a general purpose
4074 register we do not have to worry. */
4075 if (GET_CODE (lhs) != REG
4076 || REGNO_REG_CLASS (REGNO (lhs)) != GENERAL_REGS)
4077 return false;
4078
4079 /* As well as loads from memory we also have to react
4080 to loads of invalid constants which will be turned
4081 into loads from the minipool. */
4082 return (GET_CODE (rhs) == MEM
4083 || GET_CODE (rhs) == SYMBOL_REF
4084 || note_invalid_constants (insn, -1, false));
9b6b54e2
NC
4085}
4086
f0375c66 4087/* Return TRUE if INSN is a Cirrus instruction. */
f0375c66 4088static bool
e32bac5b 4089arm_cirrus_insn_p (rtx insn)
9b6b54e2
NC
4090{
4091 enum attr_cirrus attr;
4092
4093 /* get_attr aborts on USE and CLOBBER. */
4094 if (!insn
4095 || GET_CODE (insn) != INSN
4096 || GET_CODE (PATTERN (insn)) == USE
4097 || GET_CODE (PATTERN (insn)) == CLOBBER)
4098 return 0;
4099
4100 attr = get_attr_cirrus (insn);
4101
f0375c66 4102 return attr != CIRRUS_NOT;
9b6b54e2
NC
4103}
4104
4105/* Cirrus reorg for invalid instruction combinations. */
9b6b54e2 4106static void
e32bac5b 4107cirrus_reorg (rtx first)
9b6b54e2
NC
4108{
4109 enum attr_cirrus attr;
4110 rtx body = PATTERN (first);
4111 rtx t;
4112 int nops;
4113
4114 /* Any branch must be followed by 2 non Cirrus instructions. */
4115 if (GET_CODE (first) == JUMP_INSN && GET_CODE (body) != RETURN)
4116 {
4117 nops = 0;
4118 t = next_nonnote_insn (first);
4119
f0375c66 4120 if (arm_cirrus_insn_p (t))
9b6b54e2
NC
4121 ++ nops;
4122
f0375c66 4123 if (arm_cirrus_insn_p (next_nonnote_insn (t)))
9b6b54e2
NC
4124 ++ nops;
4125
4126 while (nops --)
4127 emit_insn_after (gen_nop (), first);
4128
4129 return;
4130 }
4131
4132 /* (float (blah)) is in parallel with a clobber. */
4133 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
4134 body = XVECEXP (body, 0, 0);
4135
4136 if (GET_CODE (body) == SET)
4137 {
4138 rtx lhs = XEXP (body, 0), rhs = XEXP (body, 1);
4139
4140 /* cfldrd, cfldr64, cfstrd, cfstr64 must
4141 be followed by a non Cirrus insn. */
4142 if (get_attr_cirrus (first) == CIRRUS_DOUBLE)
4143 {
f0375c66 4144 if (arm_cirrus_insn_p (next_nonnote_insn (first)))
9b6b54e2
NC
4145 emit_insn_after (gen_nop (), first);
4146
4147 return;
4148 }
f0375c66 4149 else if (arm_memory_load_p (first))
9b6b54e2
NC
4150 {
4151 unsigned int arm_regno;
4152
4153 /* Any ldr/cfmvdlr, ldr/cfmvdhr, ldr/cfmvsr, ldr/cfmv64lr,
4154 ldr/cfmv64hr combination where the Rd field is the same
4155 in both instructions must be split with a non Cirrus
4156 insn. Example:
4157
4158 ldr r0, blah
4159 nop
4160 cfmvsr mvf0, r0. */
4161
4162 /* Get Arm register number for ldr insn. */
4163 if (GET_CODE (lhs) == REG)
4164 arm_regno = REGNO (lhs);
4165 else if (GET_CODE (rhs) == REG)
4166 arm_regno = REGNO (rhs);
4167 else
4168 abort ();
4169
4170 /* Next insn. */
4171 first = next_nonnote_insn (first);
4172
f0375c66 4173 if (! arm_cirrus_insn_p (first))
9b6b54e2
NC
4174 return;
4175
4176 body = PATTERN (first);
4177
4178 /* (float (blah)) is in parallel with a clobber. */
4179 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0))
4180 body = XVECEXP (body, 0, 0);
4181
4182 if (GET_CODE (body) == FLOAT)
4183 body = XEXP (body, 0);
4184
4185 if (get_attr_cirrus (first) == CIRRUS_MOVE
4186 && GET_CODE (XEXP (body, 1)) == REG
4187 && arm_regno == REGNO (XEXP (body, 1)))
4188 emit_insn_after (gen_nop (), first);
4189
4190 return;
4191 }
4192 }
4193
4194 /* get_attr aborts on USE and CLOBBER. */
4195 if (!first
4196 || GET_CODE (first) != INSN
4197 || GET_CODE (PATTERN (first)) == USE
4198 || GET_CODE (PATTERN (first)) == CLOBBER)
4199 return;
4200
4201 attr = get_attr_cirrus (first);
4202
4203 /* Any coprocessor compare instruction (cfcmps, cfcmpd, ...)
4204 must be followed by a non-coprocessor instruction. */
4205 if (attr == CIRRUS_COMPARE)
4206 {
4207 nops = 0;
4208
4209 t = next_nonnote_insn (first);
4210
f0375c66 4211 if (arm_cirrus_insn_p (t))
9b6b54e2
NC
4212 ++ nops;
4213
f0375c66 4214 if (arm_cirrus_insn_p (next_nonnote_insn (t)))
9b6b54e2
NC
4215 ++ nops;
4216
4217 while (nops --)
4218 emit_insn_after (gen_nop (), first);
4219
4220 return;
4221 }
4222}
4223
cce8749e 4224/* Return nonzero if OP is a constant power of two. */
cce8749e 4225int
e32bac5b 4226power_of_two_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
cce8749e
CH
4227{
4228 if (GET_CODE (op) == CONST_INT)
4229 {
d5b7b3ae 4230 HOST_WIDE_INT value = INTVAL (op);
1d6e90ac 4231
f3bb6135 4232 return value != 0 && (value & (value - 1)) == 0;
cce8749e 4233 }
1d6e90ac 4234
f3bb6135
RE
4235 return FALSE;
4236}
cce8749e
CH
4237
4238/* Return TRUE for a valid operand of a DImode operation.
e9c6b69b 4239 Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
ff9940b0
RE
4240 Note that this disallows MEM(REG+REG), but allows
4241 MEM(PRE/POST_INC/DEC(REG)). */
cce8749e 4242int
e32bac5b 4243di_operand (rtx op, enum machine_mode mode)
cce8749e 4244{
ff9940b0 4245 if (s_register_operand (op, mode))
f3bb6135 4246 return TRUE;
cce8749e 4247
9ce71c6f
BS
4248 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
4249 return FALSE;
4250
e9c6b69b
NC
4251 if (GET_CODE (op) == SUBREG)
4252 op = SUBREG_REG (op);
4253
cce8749e
CH
4254 switch (GET_CODE (op))
4255 {
4256 case CONST_DOUBLE:
4257 case CONST_INT:
f3bb6135
RE
4258 return TRUE;
4259
cce8749e 4260 case MEM:
f3bb6135
RE
4261 return memory_address_p (DImode, XEXP (op, 0));
4262
cce8749e 4263 default:
f3bb6135 4264 return FALSE;
cce8749e 4265 }
f3bb6135 4266}
cce8749e 4267
d5b7b3ae
RE
4268/* Like di_operand, but don't accept constants. */
4269int
e32bac5b 4270nonimmediate_di_operand (rtx op, enum machine_mode mode)
d5b7b3ae
RE
4271{
4272 if (s_register_operand (op, mode))
4273 return TRUE;
4274
4275 if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
4276 return FALSE;
4277
4278 if (GET_CODE (op) == SUBREG)
4279 op = SUBREG_REG (op);
4280
4281 if (GET_CODE (op) == MEM)
4282 return memory_address_p (DImode, XEXP (op, 0));
4283
4284 return FALSE;
4285}
4286
f3139301 4287/* Return TRUE for a valid operand of a DFmode operation when -msoft-float.
e9c6b69b 4288 Either: REG, SUBREG, CONST_DOUBLE or MEM(DImode_address).
f3139301
DE
4289 Note that this disallows MEM(REG+REG), but allows
4290 MEM(PRE/POST_INC/DEC(REG)). */
f3139301 4291int
e32bac5b 4292soft_df_operand (rtx op, enum machine_mode mode)
f3139301
DE
4293{
4294 if (s_register_operand (op, mode))
4b02997f 4295 return TRUE;
f3139301 4296
9ce71c6f
BS
4297 if (mode != VOIDmode && GET_MODE (op) != mode)
4298 return FALSE;
4299
37b80d2e
BS
4300 if (GET_CODE (op) == SUBREG && CONSTANT_P (SUBREG_REG (op)))
4301 return FALSE;
4302
e9c6b69b
NC
4303 if (GET_CODE (op) == SUBREG)
4304 op = SUBREG_REG (op);
9ce71c6f 4305
f3139301
DE
4306 switch (GET_CODE (op))
4307 {
4308 case CONST_DOUBLE:
4309 return TRUE;
4310
4311 case MEM:
4312 return memory_address_p (DFmode, XEXP (op, 0));
4313
4314 default:
4315 return FALSE;
4316 }
4317}
4318
d5b7b3ae
RE
4319/* Like soft_df_operand, but don't accept constants. */
4320int
e32bac5b 4321nonimmediate_soft_df_operand (rtx op, enum machine_mode mode)
d5b7b3ae
RE
4322{
4323 if (s_register_operand (op, mode))
4b02997f 4324 return TRUE;
d5b7b3ae
RE
4325
4326 if (mode != VOIDmode && GET_MODE (op) != mode)
4327 return FALSE;
4328
4329 if (GET_CODE (op) == SUBREG)
4330 op = SUBREG_REG (op);
4331
4332 if (GET_CODE (op) == MEM)
4333 return memory_address_p (DFmode, XEXP (op, 0));
4334 return FALSE;
4335}
cce8749e 4336
d5b7b3ae 4337/* Return TRUE for valid index operands. */
cce8749e 4338int
e32bac5b 4339index_operand (rtx op, enum machine_mode mode)
cce8749e 4340{
d5b7b3ae 4341 return (s_register_operand (op, mode)
ff9940b0 4342 || (immediate_operand (op, mode)
d5b7b3ae
RE
4343 && (GET_CODE (op) != CONST_INT
4344 || (INTVAL (op) < 4096 && INTVAL (op) > -4096))));
f3bb6135 4345}
cce8749e 4346
ff9940b0
RE
4347/* Return TRUE for valid shifts by a constant. This also accepts any
4348 power of two on the (somewhat overly relaxed) assumption that the
6354dc9b 4349 shift operator in this case was a mult. */
ff9940b0 4350int
e32bac5b 4351const_shift_operand (rtx op, enum machine_mode mode)
ff9940b0
RE
4352{
4353 return (power_of_two_operand (op, mode)
4354 || (immediate_operand (op, mode)
d5b7b3ae
RE
4355 && (GET_CODE (op) != CONST_INT
4356 || (INTVAL (op) < 32 && INTVAL (op) > 0))));
f3bb6135 4357}
ff9940b0 4358
cce8749e
CH
4359/* Return TRUE for arithmetic operators which can be combined with a multiply
4360 (shift). */
cce8749e 4361int
e32bac5b 4362shiftable_operator (rtx x, enum machine_mode mode)
cce8749e 4363{
1d6e90ac
NC
4364 enum rtx_code code;
4365
cce8749e
CH
4366 if (GET_MODE (x) != mode)
4367 return FALSE;
cce8749e 4368
1d6e90ac
NC
4369 code = GET_CODE (x);
4370
4371 return (code == PLUS || code == MINUS
4372 || code == IOR || code == XOR || code == AND);
f3bb6135 4373}
cce8749e 4374
6ab589e0 4375/* Return TRUE for binary logical operators. */
6ab589e0 4376int
e32bac5b 4377logical_binary_operator (rtx x, enum machine_mode mode)
6ab589e0 4378{
1d6e90ac
NC
4379 enum rtx_code code;
4380
6ab589e0
JL
4381 if (GET_MODE (x) != mode)
4382 return FALSE;
6ab589e0 4383
1d6e90ac
NC
4384 code = GET_CODE (x);
4385
4386 return (code == IOR || code == XOR || code == AND);
6ab589e0
JL
4387}
4388
6354dc9b 4389/* Return TRUE for shift operators. */
cce8749e 4390int
e32bac5b 4391shift_operator (rtx x,enum machine_mode mode)
cce8749e 4392{
1d6e90ac
NC
4393 enum rtx_code code;
4394
cce8749e
CH
4395 if (GET_MODE (x) != mode)
4396 return FALSE;
cce8749e 4397
1d6e90ac 4398 code = GET_CODE (x);
f3bb6135 4399
1d6e90ac
NC
4400 if (code == MULT)
4401 return power_of_two_operand (XEXP (x, 1), mode);
4402
4403 return (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT
4404 || code == ROTATERT);
f3bb6135 4405}
ff9940b0 4406
6354dc9b
NC
4407/* Return TRUE if x is EQ or NE. */
4408int
e32bac5b 4409equality_operator (rtx x, enum machine_mode mode ATTRIBUTE_UNUSED)
ff9940b0 4410{
f3bb6135 4411 return GET_CODE (x) == EQ || GET_CODE (x) == NE;
ff9940b0
RE
4412}
4413
e45b72c4
RE
4414/* Return TRUE if x is a comparison operator other than LTGT or UNEQ. */
4415int
e32bac5b 4416arm_comparison_operator (rtx x, enum machine_mode mode)
e45b72c4
RE
4417{
4418 return (comparison_operator (x, mode)
4419 && GET_CODE (x) != LTGT
4420 && GET_CODE (x) != UNEQ);
4421}
4422
6354dc9b 4423/* Return TRUE for SMIN SMAX UMIN UMAX operators. */
ff9940b0 4424int
e32bac5b 4425minmax_operator (rtx x, enum machine_mode mode)
ff9940b0
RE
4426{
4427 enum rtx_code code = GET_CODE (x);
4428
4429 if (GET_MODE (x) != mode)
4430 return FALSE;
f3bb6135 4431
ff9940b0 4432 return code == SMIN || code == SMAX || code == UMIN || code == UMAX;
f3bb6135 4433}
ff9940b0 4434
ff9940b0 4435/* Return TRUE if this is the condition code register, if we aren't given
6354dc9b 4436 a mode, accept any class CCmode register. */
ff9940b0 4437int
e32bac5b 4438cc_register (rtx x, enum machine_mode mode)
ff9940b0
RE
4439{
4440 if (mode == VOIDmode)
4441 {
4442 mode = GET_MODE (x);
d5b7b3ae 4443
ff9940b0
RE
4444 if (GET_MODE_CLASS (mode) != MODE_CC)
4445 return FALSE;
4446 }
f3bb6135 4447
d5b7b3ae
RE
4448 if ( GET_MODE (x) == mode
4449 && GET_CODE (x) == REG
4450 && REGNO (x) == CC_REGNUM)
ff9940b0 4451 return TRUE;
f3bb6135 4452
ff9940b0
RE
4453 return FALSE;
4454}
5bbe2d40
RE
4455
4456/* Return TRUE if this is the condition code register, if we aren't given
84ed5e79
RE
4457 a mode, accept any class CCmode register which indicates a dominance
4458 expression. */
5bbe2d40 4459int
e32bac5b 4460dominant_cc_register (rtx x, enum machine_mode mode)
5bbe2d40
RE
4461{
4462 if (mode == VOIDmode)
4463 {
4464 mode = GET_MODE (x);
d5b7b3ae 4465
84ed5e79 4466 if (GET_MODE_CLASS (mode) != MODE_CC)
5bbe2d40
RE
4467 return FALSE;
4468 }
4469
e32bac5b 4470 if (mode != CC_DNEmode && mode != CC_DEQmode
84ed5e79
RE
4471 && mode != CC_DLEmode && mode != CC_DLTmode
4472 && mode != CC_DGEmode && mode != CC_DGTmode
4473 && mode != CC_DLEUmode && mode != CC_DLTUmode
4474 && mode != CC_DGEUmode && mode != CC_DGTUmode)
4475 return FALSE;
4476
d5b7b3ae 4477 return cc_register (x, mode);
5bbe2d40
RE
4478}
4479
2b835d68
RE
4480/* Return TRUE if X references a SYMBOL_REF. */
4481int
e32bac5b 4482symbol_mentioned_p (rtx x)
2b835d68 4483{
1d6e90ac
NC
4484 const char * fmt;
4485 int i;
2b835d68
RE
4486
4487 if (GET_CODE (x) == SYMBOL_REF)
4488 return 1;
4489
4490 fmt = GET_RTX_FORMAT (GET_CODE (x));
d5b7b3ae 4491
2b835d68
RE
4492 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4493 {
4494 if (fmt[i] == 'E')
4495 {
1d6e90ac 4496 int j;
2b835d68
RE
4497
4498 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4499 if (symbol_mentioned_p (XVECEXP (x, i, j)))
4500 return 1;
4501 }
4502 else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i)))
4503 return 1;
4504 }
4505
4506 return 0;
4507}
4508
4509/* Return TRUE if X references a LABEL_REF. */
4510int
e32bac5b 4511label_mentioned_p (rtx x)
2b835d68 4512{
1d6e90ac
NC
4513 const char * fmt;
4514 int i;
2b835d68
RE
4515
4516 if (GET_CODE (x) == LABEL_REF)
4517 return 1;
4518
4519 fmt = GET_RTX_FORMAT (GET_CODE (x));
4520 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
4521 {
4522 if (fmt[i] == 'E')
4523 {
1d6e90ac 4524 int j;
2b835d68
RE
4525
4526 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
4527 if (label_mentioned_p (XVECEXP (x, i, j)))
4528 return 1;
4529 }
4530 else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i)))
4531 return 1;
4532 }
4533
4534 return 0;
4535}
4536
ff9940b0 4537enum rtx_code
e32bac5b 4538minmax_code (rtx x)
ff9940b0
RE
4539{
4540 enum rtx_code code = GET_CODE (x);
4541
4542 if (code == SMAX)
4543 return GE;
f3bb6135 4544 else if (code == SMIN)
ff9940b0 4545 return LE;
f3bb6135 4546 else if (code == UMIN)
ff9940b0 4547 return LEU;
f3bb6135 4548 else if (code == UMAX)
ff9940b0 4549 return GEU;
f3bb6135 4550
ff9940b0
RE
4551 abort ();
4552}
4553
6354dc9b 4554/* Return 1 if memory locations are adjacent. */
f3bb6135 4555int
e32bac5b 4556adjacent_mem_locations (rtx a, rtx b)
ff9940b0 4557{
ff9940b0
RE
4558 if ((GET_CODE (XEXP (a, 0)) == REG
4559 || (GET_CODE (XEXP (a, 0)) == PLUS
4560 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
4561 && (GET_CODE (XEXP (b, 0)) == REG
4562 || (GET_CODE (XEXP (b, 0)) == PLUS
4563 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
4564 {
1d6e90ac
NC
4565 int val0 = 0, val1 = 0;
4566 int reg0, reg1;
4567
ff9940b0
RE
4568 if (GET_CODE (XEXP (a, 0)) == PLUS)
4569 {
1d6e90ac 4570 reg0 = REGNO (XEXP (XEXP (a, 0), 0));
ff9940b0
RE
4571 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
4572 }
4573 else
4574 reg0 = REGNO (XEXP (a, 0));
1d6e90ac 4575
ff9940b0
RE
4576 if (GET_CODE (XEXP (b, 0)) == PLUS)
4577 {
1d6e90ac 4578 reg1 = REGNO (XEXP (XEXP (b, 0), 0));
ff9940b0
RE
4579 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
4580 }
4581 else
4582 reg1 = REGNO (XEXP (b, 0));
1d6e90ac 4583
e32bac5b
RE
4584 /* Don't accept any offset that will require multiple
4585 instructions to handle, since this would cause the
4586 arith_adjacentmem pattern to output an overlong sequence. */
c75a3ddc
PB
4587 if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1))
4588 return 0;
4589
ff9940b0
RE
4590 return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
4591 }
4592 return 0;
4593}
4594
4595/* Return 1 if OP is a load multiple operation. It is known to be
6354dc9b 4596 parallel and the first section will be tested. */
f3bb6135 4597int
e32bac5b 4598load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
ff9940b0 4599{
f3bb6135 4600 HOST_WIDE_INT count = XVECLEN (op, 0);
ff9940b0
RE
4601 int dest_regno;
4602 rtx src_addr;
f3bb6135 4603 HOST_WIDE_INT i = 1, base = 0;
ff9940b0
RE
4604 rtx elt;
4605
4606 if (count <= 1
4607 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
4608 return 0;
4609
6354dc9b 4610 /* Check to see if this might be a write-back. */
ff9940b0
RE
4611 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
4612 {
4613 i++;
4614 base = 1;
4615
6354dc9b 4616 /* Now check it more carefully. */
ff9940b0
RE
4617 if (GET_CODE (SET_DEST (elt)) != REG
4618 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
4619 || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
4620 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
41e3f998 4621 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
ff9940b0 4622 return 0;
ff9940b0
RE
4623 }
4624
4625 /* Perform a quick check so we don't blow up below. */
4626 if (count <= i
4627 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
4628 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
4629 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
4630 return 0;
4631
4632 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
4633 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
4634
4635 for (; i < count; i++)
4636 {
ed4c4348 4637 elt = XVECEXP (op, 0, i);
ff9940b0
RE
4638
4639 if (GET_CODE (elt) != SET
4640 || GET_CODE (SET_DEST (elt)) != REG
4641 || GET_MODE (SET_DEST (elt)) != SImode
6354dc9b 4642 || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)
ff9940b0
RE
4643 || GET_CODE (SET_SRC (elt)) != MEM
4644 || GET_MODE (SET_SRC (elt)) != SImode
4645 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
5895f793 4646 || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
ff9940b0
RE
4647 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
4648 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != (i - base) * 4)
4649 return 0;
4650 }
4651
4652 return 1;
4653}
4654
4655/* Return 1 if OP is a store multiple operation. It is known to be
6354dc9b 4656 parallel and the first section will be tested. */
f3bb6135 4657int
e32bac5b 4658store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
ff9940b0 4659{
f3bb6135 4660 HOST_WIDE_INT count = XVECLEN (op, 0);
ff9940b0
RE
4661 int src_regno;
4662 rtx dest_addr;
f3bb6135 4663 HOST_WIDE_INT i = 1, base = 0;
ff9940b0
RE
4664 rtx elt;
4665
4666 if (count <= 1
4667 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
4668 return 0;
4669
6354dc9b 4670 /* Check to see if this might be a write-back. */
ff9940b0
RE
4671 if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
4672 {
4673 i++;
4674 base = 1;
4675
6354dc9b 4676 /* Now check it more carefully. */
ff9940b0
RE
4677 if (GET_CODE (SET_DEST (elt)) != REG
4678 || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
4679 || REGNO (XEXP (SET_SRC (elt), 0)) != REGNO (SET_DEST (elt))
4680 || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
41e3f998 4681 || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
ff9940b0 4682 return 0;
ff9940b0
RE
4683 }
4684
4685 /* Perform a quick check so we don't blow up below. */
4686 if (count <= i
4687 || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
4688 || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
4689 || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
4690 return 0;
4691
4692 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
4693 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
4694
4695 for (; i < count; i++)
4696 {
4697 elt = XVECEXP (op, 0, i);
4698
4699 if (GET_CODE (elt) != SET
4700 || GET_CODE (SET_SRC (elt)) != REG
4701 || GET_MODE (SET_SRC (elt)) != SImode
6354dc9b 4702 || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)
ff9940b0
RE
4703 || GET_CODE (SET_DEST (elt)) != MEM
4704 || GET_MODE (SET_DEST (elt)) != SImode
4705 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
5895f793 4706 || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
ff9940b0
RE
4707 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
4708 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != (i - base) * 4)
4709 return 0;
4710 }
4711
4712 return 1;
4713}
e2c671ba 4714
84ed5e79 4715int
e32bac5b
RE
4716load_multiple_sequence (rtx *operands, int nops, int *regs, int *base,
4717 HOST_WIDE_INT *load_offset)
84ed5e79
RE
4718{
4719 int unsorted_regs[4];
4720 HOST_WIDE_INT unsorted_offsets[4];
4721 int order[4];
ad076f4e 4722 int base_reg = -1;
84ed5e79
RE
4723 int i;
4724
1d6e90ac
NC
4725 /* Can only handle 2, 3, or 4 insns at present,
4726 though could be easily extended if required. */
84ed5e79
RE
4727 if (nops < 2 || nops > 4)
4728 abort ();
4729
4730 /* Loop over the operands and check that the memory references are
4731 suitable (ie immediate offsets from the same base register). At
4732 the same time, extract the target register, and the memory
4733 offsets. */
4734 for (i = 0; i < nops; i++)
4735 {
4736 rtx reg;
4737 rtx offset;
4738
56636818
JL
4739 /* Convert a subreg of a mem into the mem itself. */
4740 if (GET_CODE (operands[nops + i]) == SUBREG)
4e26a7af 4741 operands[nops + i] = alter_subreg (operands + (nops + i));
56636818 4742
84ed5e79
RE
4743 if (GET_CODE (operands[nops + i]) != MEM)
4744 abort ();
4745
4746 /* Don't reorder volatile memory references; it doesn't seem worth
4747 looking for the case where the order is ok anyway. */
4748 if (MEM_VOLATILE_P (operands[nops + i]))
4749 return 0;
4750
4751 offset = const0_rtx;
4752
4753 if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG
4754 || (GET_CODE (reg) == SUBREG
4755 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4756 || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
4757 && ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))
4758 == REG)
4759 || (GET_CODE (reg) == SUBREG
4760 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4761 && (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))
4762 == CONST_INT)))
4763 {
4764 if (i == 0)
4765 {
d5b7b3ae 4766 base_reg = REGNO (reg);
84ed5e79
RE
4767 unsorted_regs[0] = (GET_CODE (operands[i]) == REG
4768 ? REGNO (operands[i])
4769 : REGNO (SUBREG_REG (operands[i])));
4770 order[0] = 0;
4771 }
4772 else
4773 {
6354dc9b 4774 if (base_reg != (int) REGNO (reg))
84ed5e79
RE
4775 /* Not addressed from the same base register. */
4776 return 0;
4777
4778 unsorted_regs[i] = (GET_CODE (operands[i]) == REG
4779 ? REGNO (operands[i])
4780 : REGNO (SUBREG_REG (operands[i])));
4781 if (unsorted_regs[i] < unsorted_regs[order[0]])
4782 order[0] = i;
4783 }
4784
4785 /* If it isn't an integer register, or if it overwrites the
4786 base register but isn't the last insn in the list, then
4787 we can't do this. */
4788 if (unsorted_regs[i] < 0 || unsorted_regs[i] > 14
4789 || (i != nops - 1 && unsorted_regs[i] == base_reg))
4790 return 0;
4791
4792 unsorted_offsets[i] = INTVAL (offset);
4793 }
4794 else
4795 /* Not a suitable memory address. */
4796 return 0;
4797 }
4798
4799 /* All the useful information has now been extracted from the
4800 operands into unsorted_regs and unsorted_offsets; additionally,
4801 order[0] has been set to the lowest numbered register in the
4802 list. Sort the registers into order, and check that the memory
4803 offsets are ascending and adjacent. */
4804
4805 for (i = 1; i < nops; i++)
4806 {
4807 int j;
4808
4809 order[i] = order[i - 1];
4810 for (j = 0; j < nops; j++)
4811 if (unsorted_regs[j] > unsorted_regs[order[i - 1]]
4812 && (order[i] == order[i - 1]
4813 || unsorted_regs[j] < unsorted_regs[order[i]]))
4814 order[i] = j;
4815
4816 /* Have we found a suitable register? if not, one must be used more
4817 than once. */
4818 if (order[i] == order[i - 1])
4819 return 0;
4820
4821 /* Is the memory address adjacent and ascending? */
4822 if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)
4823 return 0;
4824 }
4825
4826 if (base)
4827 {
4828 *base = base_reg;
4829
4830 for (i = 0; i < nops; i++)
4831 regs[i] = unsorted_regs[order[i]];
4832
4833 *load_offset = unsorted_offsets[order[0]];
4834 }
4835
4836 if (unsorted_offsets[order[0]] == 0)
4837 return 1; /* ldmia */
4838
4839 if (unsorted_offsets[order[0]] == 4)
4840 return 2; /* ldmib */
4841
4842 if (unsorted_offsets[order[nops - 1]] == 0)
4843 return 3; /* ldmda */
4844
4845 if (unsorted_offsets[order[nops - 1]] == -4)
4846 return 4; /* ldmdb */
4847
949d79eb
RE
4848 /* For ARM8,9 & StrongARM, 2 ldr instructions are faster than an ldm
4849 if the offset isn't small enough. The reason 2 ldrs are faster
4850 is because these ARMs are able to do more than one cache access
4851 in a single cycle. The ARM9 and StrongARM have Harvard caches,
4852 whilst the ARM8 has a double bandwidth cache. This means that
4853 these cores can do both an instruction fetch and a data fetch in
4854 a single cycle, so the trick of calculating the address into a
4855 scratch register (one of the result regs) and then doing a load
4856 multiple actually becomes slower (and no smaller in code size).
4857 That is the transformation
6cc8c0b3
NC
4858
4859 ldr rd1, [rbase + offset]
4860 ldr rd2, [rbase + offset + 4]
4861
4862 to
4863
4864 add rd1, rbase, offset
4865 ldmia rd1, {rd1, rd2}
4866
949d79eb
RE
4867 produces worse code -- '3 cycles + any stalls on rd2' instead of
4868 '2 cycles + any stalls on rd2'. On ARMs with only one cache
4869 access per cycle, the first sequence could never complete in less
4870 than 6 cycles, whereas the ldm sequence would only take 5 and
4871 would make better use of sequential accesses if not hitting the
4872 cache.
4873
4874 We cheat here and test 'arm_ld_sched' which we currently know to
4875 only be true for the ARM8, ARM9 and StrongARM. If this ever
4876 changes, then the test below needs to be reworked. */
f5a1b0d2 4877 if (nops == 2 && arm_ld_sched)
b36ba79f
RE
4878 return 0;
4879
84ed5e79
RE
4880 /* Can't do it without setting up the offset, only do this if it takes
4881 no more than one insn. */
4882 return (const_ok_for_arm (unsorted_offsets[order[0]])
4883 || const_ok_for_arm (-unsorted_offsets[order[0]])) ? 5 : 0;
4884}
4885
cd2b33d0 4886const char *
e32bac5b 4887emit_ldm_seq (rtx *operands, int nops)
84ed5e79
RE
4888{
4889 int regs[4];
4890 int base_reg;
4891 HOST_WIDE_INT offset;
4892 char buf[100];
4893 int i;
4894
4895 switch (load_multiple_sequence (operands, nops, regs, &base_reg, &offset))
4896 {
4897 case 1:
4898 strcpy (buf, "ldm%?ia\t");
4899 break;
4900
4901 case 2:
4902 strcpy (buf, "ldm%?ib\t");
4903 break;
4904
4905 case 3:
4906 strcpy (buf, "ldm%?da\t");
4907 break;
4908
4909 case 4:
4910 strcpy (buf, "ldm%?db\t");
4911 break;
4912
4913 case 5:
4914 if (offset >= 0)
4915 sprintf (buf, "add%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX,
4916 reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],
4917 (long) offset);
4918 else
4919 sprintf (buf, "sub%%?\t%s%s, %s%s, #%ld", REGISTER_PREFIX,
4920 reg_names[regs[0]], REGISTER_PREFIX, reg_names[base_reg],
4921 (long) -offset);
4922 output_asm_insn (buf, operands);
4923 base_reg = regs[0];
4924 strcpy (buf, "ldm%?ia\t");
4925 break;
4926
4927 default:
4928 abort ();
4929 }
4930
4931 sprintf (buf + strlen (buf), "%s%s, {%s%s", REGISTER_PREFIX,
4932 reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);
4933
4934 for (i = 1; i < nops; i++)
4935 sprintf (buf + strlen (buf), ", %s%s", REGISTER_PREFIX,
4936 reg_names[regs[i]]);
4937
4938 strcat (buf, "}\t%@ phole ldm");
4939
4940 output_asm_insn (buf, operands);
4941 return "";
4942}
4943
4944int
e32bac5b
RE
4945store_multiple_sequence (rtx *operands, int nops, int *regs, int *base,
4946 HOST_WIDE_INT * load_offset)
84ed5e79
RE
4947{
4948 int unsorted_regs[4];
4949 HOST_WIDE_INT unsorted_offsets[4];
4950 int order[4];
ad076f4e 4951 int base_reg = -1;
84ed5e79
RE
4952 int i;
4953
4954 /* Can only handle 2, 3, or 4 insns at present, though could be easily
4955 extended if required. */
4956 if (nops < 2 || nops > 4)
4957 abort ();
4958
4959 /* Loop over the operands and check that the memory references are
4960 suitable (ie immediate offsets from the same base register). At
4961 the same time, extract the target register, and the memory
4962 offsets. */
4963 for (i = 0; i < nops; i++)
4964 {
4965 rtx reg;
4966 rtx offset;
4967
56636818
JL
4968 /* Convert a subreg of a mem into the mem itself. */
4969 if (GET_CODE (operands[nops + i]) == SUBREG)
4e26a7af 4970 operands[nops + i] = alter_subreg (operands + (nops + i));
56636818 4971
84ed5e79
RE
4972 if (GET_CODE (operands[nops + i]) != MEM)
4973 abort ();
4974
4975 /* Don't reorder volatile memory references; it doesn't seem worth
4976 looking for the case where the order is ok anyway. */
4977 if (MEM_VOLATILE_P (operands[nops + i]))
4978 return 0;
4979
4980 offset = const0_rtx;
4981
4982 if ((GET_CODE (reg = XEXP (operands[nops + i], 0)) == REG
4983 || (GET_CODE (reg) == SUBREG
4984 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4985 || (GET_CODE (XEXP (operands[nops + i], 0)) == PLUS
4986 && ((GET_CODE (reg = XEXP (XEXP (operands[nops + i], 0), 0))
4987 == REG)
4988 || (GET_CODE (reg) == SUBREG
4989 && GET_CODE (reg = SUBREG_REG (reg)) == REG))
4990 && (GET_CODE (offset = XEXP (XEXP (operands[nops + i], 0), 1))
4991 == CONST_INT)))
4992 {
4993 if (i == 0)
4994 {
62b10bbc 4995 base_reg = REGNO (reg);
84ed5e79
RE
4996 unsorted_regs[0] = (GET_CODE (operands[i]) == REG
4997 ? REGNO (operands[i])
4998 : REGNO (SUBREG_REG (operands[i])));
4999 order[0] = 0;
5000 }
5001 else
5002 {
6354dc9b 5003 if (base_reg != (int) REGNO (reg))
84ed5e79
RE
5004 /* Not addressed from the same base register. */
5005 return 0;
5006
5007 unsorted_regs[i] = (GET_CODE (operands[i]) == REG
5008 ? REGNO (operands[i])
5009 : REGNO (SUBREG_REG (operands[i])));
5010 if (unsorted_regs[i] < unsorted_regs[order[0]])
5011 order[0] = i;
5012 }
5013
5014 /* If it isn't an integer register, then we can't do this. */
5015 if (unsorted_regs[i] < 0 || unsorted_regs[i] > 14)
5016 return 0;
5017
5018 unsorted_offsets[i] = INTVAL (offset);
5019 }
5020 else
5021 /* Not a suitable memory address. */
5022 return 0;
5023 }
5024
5025 /* All the useful information has now been extracted from the
5026 operands into unsorted_regs and unsorted_offsets; additionally,
5027 order[0] has been set to the lowest numbered register in the
5028 list. Sort the registers into order, and check that the memory
5029 offsets are ascending and adjacent. */
5030
5031 for (i = 1; i < nops; i++)
5032 {
5033 int j;
5034
5035 order[i] = order[i - 1];
5036 for (j = 0; j < nops; j++)
5037 if (unsorted_regs[j] > unsorted_regs[order[i - 1]]
5038 && (order[i] == order[i - 1]
5039 || unsorted_regs[j] < unsorted_regs[order[i]]))
5040 order[i] = j;
5041
5042 /* Have we found a suitable register? if not, one must be used more
5043 than once. */
5044 if (order[i] == order[i - 1])
5045 return 0;
5046
5047 /* Is the memory address adjacent and ascending? */
5048 if (unsorted_offsets[order[i]] != unsorted_offsets[order[i - 1]] + 4)
5049 return 0;
5050 }
5051
5052 if (base)
5053 {
5054 *base = base_reg;
5055
5056 for (i = 0; i < nops; i++)
5057 regs[i] = unsorted_regs[order[i]];
5058
5059 *load_offset = unsorted_offsets[order[0]];
5060 }
5061
5062 if (unsorted_offsets[order[0]] == 0)
5063 return 1; /* stmia */
5064
5065 if (unsorted_offsets[order[0]] == 4)
5066 return 2; /* stmib */
5067
5068 if (unsorted_offsets[order[nops - 1]] == 0)
5069 return 3; /* stmda */
5070
5071 if (unsorted_offsets[order[nops - 1]] == -4)
5072 return 4; /* stmdb */
5073
5074 return 0;
5075}
5076
cd2b33d0 5077const char *
e32bac5b 5078emit_stm_seq (rtx *operands, int nops)
84ed5e79
RE
5079{
5080 int regs[4];
5081 int base_reg;
5082 HOST_WIDE_INT offset;
5083 char buf[100];
5084 int i;
5085
5086 switch (store_multiple_sequence (operands, nops, regs, &base_reg, &offset))
5087 {
5088 case 1:
5089 strcpy (buf, "stm%?ia\t");
5090 break;
5091
5092 case 2:
5093 strcpy (buf, "stm%?ib\t");
5094 break;
5095
5096 case 3:
5097 strcpy (buf, "stm%?da\t");
5098 break;
5099
5100 case 4:
5101 strcpy (buf, "stm%?db\t");
5102 break;
5103
5104 default:
5105 abort ();
5106 }
5107
5108 sprintf (buf + strlen (buf), "%s%s, {%s%s", REGISTER_PREFIX,
5109 reg_names[base_reg], REGISTER_PREFIX, reg_names[regs[0]]);
5110
5111 for (i = 1; i < nops; i++)
5112 sprintf (buf + strlen (buf), ", %s%s", REGISTER_PREFIX,
5113 reg_names[regs[i]]);
5114
5115 strcat (buf, "}\t%@ phole stm");
5116
5117 output_asm_insn (buf, operands);
5118 return "";
5119}
5120
e2c671ba 5121int
e32bac5b 5122multi_register_push (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
e2c671ba
RE
5123{
5124 if (GET_CODE (op) != PARALLEL
5125 || (GET_CODE (XVECEXP (op, 0, 0)) != SET)
5126 || (GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC)
b15bca31 5127 || (XINT (SET_SRC (XVECEXP (op, 0, 0)), 1) != UNSPEC_PUSH_MULT))
e2c671ba
RE
5128 return 0;
5129
5130 return 1;
5131}
ff9940b0 5132\f
6354dc9b 5133/* Routines for use in generating RTL. */
1d6e90ac 5134
f3bb6135 5135rtx
e32bac5b
RE
5136arm_gen_load_multiple (int base_regno, int count, rtx from, int up,
5137 int write_back, int unchanging_p, int in_struct_p,
5138 int scalar_p)
ff9940b0
RE
5139{
5140 int i = 0, j;
5141 rtx result;
5142 int sign = up ? 1 : -1;
56636818 5143 rtx mem;
ff9940b0 5144
d19fb8e3
NC
5145 /* XScale has load-store double instructions, but they have stricter
5146 alignment requirements than load-store multiple, so we can not
5147 use them.
5148
5149 For XScale ldm requires 2 + NREGS cycles to complete and blocks
5150 the pipeline until completion.
5151
5152 NREGS CYCLES
5153 1 3
5154 2 4
5155 3 5
5156 4 6
5157
5158 An ldr instruction takes 1-3 cycles, but does not block the
5159 pipeline.
5160
5161 NREGS CYCLES
5162 1 1-3
5163 2 2-6
5164 3 3-9
5165 4 4-12
5166
5167 Best case ldr will always win. However, the more ldr instructions
5168 we issue, the less likely we are to be able to schedule them well.
5169 Using ldr instructions also increases code size.
5170
5171 As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
5172 for counts of 3 or 4 regs. */
4b3c2e48 5173 if (arm_tune_xscale && count <= 2 && ! optimize_size)
d19fb8e3
NC
5174 {
5175 rtx seq;
5176
5177 start_sequence ();
5178
5179 for (i = 0; i < count; i++)
5180 {
5181 mem = gen_rtx_MEM (SImode, plus_constant (from, i * 4 * sign));
5182 RTX_UNCHANGING_P (mem) = unchanging_p;
5183 MEM_IN_STRUCT_P (mem) = in_struct_p;
5184 MEM_SCALAR_P (mem) = scalar_p;
5185 emit_move_insn (gen_rtx_REG (SImode, base_regno + i), mem);
5186 }
5187
5188 if (write_back)
5189 emit_move_insn (from, plus_constant (from, count * 4 * sign));
5190
2f937369 5191 seq = get_insns ();
d19fb8e3
NC
5192 end_sequence ();
5193
5194 return seq;
5195 }
5196
43cffd11 5197 result = gen_rtx_PARALLEL (VOIDmode,
41e3f998 5198 rtvec_alloc (count + (write_back ? 1 : 0)));
ff9940b0 5199 if (write_back)
f3bb6135 5200 {
ff9940b0 5201 XVECEXP (result, 0, 0)
43cffd11
RE
5202 = gen_rtx_SET (GET_MODE (from), from,
5203 plus_constant (from, count * 4 * sign));
ff9940b0
RE
5204 i = 1;
5205 count++;
f3bb6135
RE
5206 }
5207
ff9940b0 5208 for (j = 0; i < count; i++, j++)
f3bb6135 5209 {
43cffd11 5210 mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4 * sign));
56636818
JL
5211 RTX_UNCHANGING_P (mem) = unchanging_p;
5212 MEM_IN_STRUCT_P (mem) = in_struct_p;
c6df88cb 5213 MEM_SCALAR_P (mem) = scalar_p;
43cffd11
RE
5214 XVECEXP (result, 0, i)
5215 = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, base_regno + j), mem);
f3bb6135
RE
5216 }
5217
ff9940b0
RE
5218 return result;
5219}
5220
f3bb6135 5221rtx
e32bac5b
RE
5222arm_gen_store_multiple (int base_regno, int count, rtx to, int up,
5223 int write_back, int unchanging_p, int in_struct_p,
5224 int scalar_p)
ff9940b0
RE
5225{
5226 int i = 0, j;
5227 rtx result;
5228 int sign = up ? 1 : -1;
56636818 5229 rtx mem;
ff9940b0 5230
d19fb8e3
NC
5231 /* See arm_gen_load_multiple for discussion of
5232 the pros/cons of ldm/stm usage for XScale. */
4b3c2e48 5233 if (arm_tune_xscale && count <= 2 && ! optimize_size)
d19fb8e3
NC
5234 {
5235 rtx seq;
5236
5237 start_sequence ();
5238
5239 for (i = 0; i < count; i++)
5240 {
5241 mem = gen_rtx_MEM (SImode, plus_constant (to, i * 4 * sign));
5242 RTX_UNCHANGING_P (mem) = unchanging_p;
5243 MEM_IN_STRUCT_P (mem) = in_struct_p;
5244 MEM_SCALAR_P (mem) = scalar_p;
5245 emit_move_insn (mem, gen_rtx_REG (SImode, base_regno + i));
5246 }
5247
5248 if (write_back)
5249 emit_move_insn (to, plus_constant (to, count * 4 * sign));
5250
2f937369 5251 seq = get_insns ();
d19fb8e3
NC
5252 end_sequence ();
5253
5254 return seq;
5255 }
5256
43cffd11 5257 result = gen_rtx_PARALLEL (VOIDmode,
41e3f998 5258 rtvec_alloc (count + (write_back ? 1 : 0)));
ff9940b0 5259 if (write_back)
f3bb6135 5260 {
ff9940b0 5261 XVECEXP (result, 0, 0)
43cffd11
RE
5262 = gen_rtx_SET (GET_MODE (to), to,
5263 plus_constant (to, count * 4 * sign));
ff9940b0
RE
5264 i = 1;
5265 count++;
f3bb6135
RE
5266 }
5267
ff9940b0 5268 for (j = 0; i < count; i++, j++)
f3bb6135 5269 {
43cffd11 5270 mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4 * sign));
56636818
JL
5271 RTX_UNCHANGING_P (mem) = unchanging_p;
5272 MEM_IN_STRUCT_P (mem) = in_struct_p;
c6df88cb 5273 MEM_SCALAR_P (mem) = scalar_p;
56636818 5274
43cffd11
RE
5275 XVECEXP (result, 0, i)
5276 = gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (SImode, base_regno + j));
f3bb6135
RE
5277 }
5278
ff9940b0
RE
5279 return result;
5280}
5281
880e2516 5282int
e32bac5b 5283arm_gen_movstrqi (rtx *operands)
880e2516
RE
5284{
5285 HOST_WIDE_INT in_words_to_go, out_words_to_go, last_bytes;
ad076f4e 5286 int i;
880e2516 5287 rtx src, dst;
ad076f4e 5288 rtx st_src, st_dst, fin_src, fin_dst;
880e2516 5289 rtx part_bytes_reg = NULL;
56636818
JL
5290 rtx mem;
5291 int dst_unchanging_p, dst_in_struct_p, src_unchanging_p, src_in_struct_p;
c6df88cb 5292 int dst_scalar_p, src_scalar_p;
880e2516
RE
5293
5294 if (GET_CODE (operands[2]) != CONST_INT
5295 || GET_CODE (operands[3]) != CONST_INT
5296 || INTVAL (operands[2]) > 64
5297 || INTVAL (operands[3]) & 3)
5298 return 0;
5299
5300 st_dst = XEXP (operands[0], 0);
5301 st_src = XEXP (operands[1], 0);
56636818
JL
5302
5303 dst_unchanging_p = RTX_UNCHANGING_P (operands[0]);
5304 dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
c6df88cb 5305 dst_scalar_p = MEM_SCALAR_P (operands[0]);
56636818
JL
5306 src_unchanging_p = RTX_UNCHANGING_P (operands[1]);
5307 src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
c6df88cb 5308 src_scalar_p = MEM_SCALAR_P (operands[1]);
56636818 5309
880e2516
RE
5310 fin_dst = dst = copy_to_mode_reg (SImode, st_dst);
5311 fin_src = src = copy_to_mode_reg (SImode, st_src);
5312
e9d7b180 5313 in_words_to_go = ARM_NUM_INTS (INTVAL (operands[2]));
880e2516
RE
5314 out_words_to_go = INTVAL (operands[2]) / 4;
5315 last_bytes = INTVAL (operands[2]) & 3;
5316
5317 if (out_words_to_go != in_words_to_go && ((in_words_to_go - 1) & 3) != 0)
43cffd11 5318 part_bytes_reg = gen_rtx_REG (SImode, (in_words_to_go - 1) & 3);
880e2516
RE
5319
5320 for (i = 0; in_words_to_go >= 2; i+=4)
5321 {
bd9c7e23 5322 if (in_words_to_go > 4)
56636818 5323 emit_insn (arm_gen_load_multiple (0, 4, src, TRUE, TRUE,
c6df88cb
MM
5324 src_unchanging_p,
5325 src_in_struct_p,
5326 src_scalar_p));
bd9c7e23
RE
5327 else
5328 emit_insn (arm_gen_load_multiple (0, in_words_to_go, src, TRUE,
56636818 5329 FALSE, src_unchanging_p,
c6df88cb 5330 src_in_struct_p, src_scalar_p));
bd9c7e23 5331
880e2516
RE
5332 if (out_words_to_go)
5333 {
bd9c7e23 5334 if (out_words_to_go > 4)
56636818
JL
5335 emit_insn (arm_gen_store_multiple (0, 4, dst, TRUE, TRUE,
5336 dst_unchanging_p,
c6df88cb
MM
5337 dst_in_struct_p,
5338 dst_scalar_p));
bd9c7e23
RE
5339 else if (out_words_to_go != 1)
5340 emit_insn (arm_gen_store_multiple (0, out_words_to_go,
5341 dst, TRUE,
5342 (last_bytes == 0
56636818
JL
5343 ? FALSE : TRUE),
5344 dst_unchanging_p,
c6df88cb
MM
5345 dst_in_struct_p,
5346 dst_scalar_p));
880e2516
RE
5347 else
5348 {
43cffd11 5349 mem = gen_rtx_MEM (SImode, dst);
56636818
JL
5350 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5351 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 5352 MEM_SCALAR_P (mem) = dst_scalar_p;
43cffd11 5353 emit_move_insn (mem, gen_rtx_REG (SImode, 0));
bd9c7e23
RE
5354 if (last_bytes != 0)
5355 emit_insn (gen_addsi3 (dst, dst, GEN_INT (4)));
880e2516
RE
5356 }
5357 }
5358
5359 in_words_to_go -= in_words_to_go < 4 ? in_words_to_go : 4;
5360 out_words_to_go -= out_words_to_go < 4 ? out_words_to_go : 4;
5361 }
5362
5363 /* OUT_WORDS_TO_GO will be zero here if there are byte stores to do. */
5364 if (out_words_to_go)
62b10bbc
NC
5365 {
5366 rtx sreg;
5367
5368 mem = gen_rtx_MEM (SImode, src);
5369 RTX_UNCHANGING_P (mem) = src_unchanging_p;
5370 MEM_IN_STRUCT_P (mem) = src_in_struct_p;
5371 MEM_SCALAR_P (mem) = src_scalar_p;
5372 emit_move_insn (sreg = gen_reg_rtx (SImode), mem);
5373 emit_move_insn (fin_src = gen_reg_rtx (SImode), plus_constant (src, 4));
5374
5375 mem = gen_rtx_MEM (SImode, dst);
5376 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5377 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
5378 MEM_SCALAR_P (mem) = dst_scalar_p;
5379 emit_move_insn (mem, sreg);
5380 emit_move_insn (fin_dst = gen_reg_rtx (SImode), plus_constant (dst, 4));
5381 in_words_to_go--;
5382
5383 if (in_words_to_go) /* Sanity check */
5384 abort ();
5385 }
880e2516
RE
5386
5387 if (in_words_to_go)
5388 {
5389 if (in_words_to_go < 0)
5390 abort ();
5391
43cffd11 5392 mem = gen_rtx_MEM (SImode, src);
56636818
JL
5393 RTX_UNCHANGING_P (mem) = src_unchanging_p;
5394 MEM_IN_STRUCT_P (mem) = src_in_struct_p;
c6df88cb 5395 MEM_SCALAR_P (mem) = src_scalar_p;
56636818 5396 part_bytes_reg = copy_to_mode_reg (SImode, mem);
880e2516
RE
5397 }
5398
d5b7b3ae
RE
5399 if (last_bytes && part_bytes_reg == NULL)
5400 abort ();
5401
880e2516
RE
5402 if (BYTES_BIG_ENDIAN && last_bytes)
5403 {
5404 rtx tmp = gen_reg_rtx (SImode);
5405
6354dc9b 5406 /* The bytes we want are in the top end of the word. */
bee06f3d
RE
5407 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg,
5408 GEN_INT (8 * (4 - last_bytes))));
880e2516
RE
5409 part_bytes_reg = tmp;
5410
5411 while (last_bytes)
5412 {
43cffd11 5413 mem = gen_rtx_MEM (QImode, plus_constant (dst, last_bytes - 1));
56636818
JL
5414 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5415 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 5416 MEM_SCALAR_P (mem) = dst_scalar_p;
5d5603e2
BS
5417 emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
5418
880e2516
RE
5419 if (--last_bytes)
5420 {
5421 tmp = gen_reg_rtx (SImode);
5422 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (8)));
5423 part_bytes_reg = tmp;
5424 }
5425 }
5426
5427 }
5428 else
5429 {
d5b7b3ae 5430 if (last_bytes > 1)
880e2516 5431 {
d5b7b3ae 5432 mem = gen_rtx_MEM (HImode, dst);
56636818
JL
5433 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5434 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
c6df88cb 5435 MEM_SCALAR_P (mem) = dst_scalar_p;
5d5603e2 5436 emit_move_insn (mem, gen_lowpart (HImode, part_bytes_reg));
d5b7b3ae
RE
5437 last_bytes -= 2;
5438 if (last_bytes)
880e2516
RE
5439 {
5440 rtx tmp = gen_reg_rtx (SImode);
bd9c7e23 5441
d5b7b3ae
RE
5442 emit_insn (gen_addsi3 (dst, dst, GEN_INT (2)));
5443 emit_insn (gen_lshrsi3 (tmp, part_bytes_reg, GEN_INT (16)));
880e2516
RE
5444 part_bytes_reg = tmp;
5445 }
5446 }
d5b7b3ae
RE
5447
5448 if (last_bytes)
5449 {
5450 mem = gen_rtx_MEM (QImode, dst);
5451 RTX_UNCHANGING_P (mem) = dst_unchanging_p;
5452 MEM_IN_STRUCT_P (mem) = dst_in_struct_p;
5453 MEM_SCALAR_P (mem) = dst_scalar_p;
5d5603e2 5454 emit_move_insn (mem, gen_lowpart (QImode, part_bytes_reg));
d5b7b3ae 5455 }
880e2516
RE
5456 }
5457
5458 return 1;
5459}
5460
5165176d
RE
5461/* Generate a memory reference for a half word, such that it will be loaded
5462 into the top 16 bits of the word. We can assume that the address is
5463 known to be alignable and of the form reg, or plus (reg, const). */
1d6e90ac 5464
5165176d 5465rtx
e32bac5b 5466arm_gen_rotated_half_load (rtx memref)
5165176d
RE
5467{
5468 HOST_WIDE_INT offset = 0;
5469 rtx base = XEXP (memref, 0);
5470
5471 if (GET_CODE (base) == PLUS)
5472 {
5473 offset = INTVAL (XEXP (base, 1));
5474 base = XEXP (base, 0);
5475 }
5476
956d6950 5477 /* If we aren't allowed to generate unaligned addresses, then fail. */
5f1e6755 5478 if (TARGET_MMU_TRAPS
5165176d
RE
5479 && ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 0)))
5480 return NULL;
5481
43cffd11 5482 base = gen_rtx_MEM (SImode, plus_constant (base, offset & ~2));
5165176d
RE
5483
5484 if ((BYTES_BIG_ENDIAN ? 1 : 0) ^ ((offset & 2) == 2))
5485 return base;
5486
43cffd11 5487 return gen_rtx_ROTATE (SImode, base, GEN_INT (16));
5165176d
RE
5488}
5489
03f1640c
RE
5490/* Select a dominance comparison mode if possible for a test of the general
5491 form (OP (COND_OR (X) (Y)) (const_int 0)). We support three forms.
5492 COND_OR == DOM_CC_X_AND_Y => (X && Y)
5493 COND_OR == DOM_CC_NX_OR_Y => ((! X) || Y)
5494 COND_OR == DOM_CC_X_OR_Y => (X || Y)
5495 In all cases OP will be either EQ or NE, but we don't need to know which
5496 here. If we are unable to support a dominance comparison we return
5497 CC mode. This will then fail to match for the RTL expressions that
5498 generate this call. */
03f1640c 5499enum machine_mode
e32bac5b 5500arm_select_dominance_cc_mode (rtx x, rtx y, HOST_WIDE_INT cond_or)
84ed5e79
RE
5501{
5502 enum rtx_code cond1, cond2;
5503 int swapped = 0;
5504
5505 /* Currently we will probably get the wrong result if the individual
5506 comparisons are not simple. This also ensures that it is safe to
956d6950 5507 reverse a comparison if necessary. */
84ed5e79
RE
5508 if ((arm_select_cc_mode (cond1 = GET_CODE (x), XEXP (x, 0), XEXP (x, 1))
5509 != CCmode)
5510 || (arm_select_cc_mode (cond2 = GET_CODE (y), XEXP (y, 0), XEXP (y, 1))
5511 != CCmode))
5512 return CCmode;
5513
1646cf41
RE
5514 /* The if_then_else variant of this tests the second condition if the
5515 first passes, but is true if the first fails. Reverse the first
5516 condition to get a true "inclusive-or" expression. */
03f1640c 5517 if (cond_or == DOM_CC_NX_OR_Y)
84ed5e79
RE
5518 cond1 = reverse_condition (cond1);
5519
5520 /* If the comparisons are not equal, and one doesn't dominate the other,
5521 then we can't do this. */
5522 if (cond1 != cond2
5895f793
RE
5523 && !comparison_dominates_p (cond1, cond2)
5524 && (swapped = 1, !comparison_dominates_p (cond2, cond1)))
84ed5e79
RE
5525 return CCmode;
5526
5527 if (swapped)
5528 {
5529 enum rtx_code temp = cond1;
5530 cond1 = cond2;
5531 cond2 = temp;
5532 }
5533
5534 switch (cond1)
5535 {
5536 case EQ:
03f1640c 5537 if (cond2 == EQ || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5538 return CC_DEQmode;
5539
5540 switch (cond2)
5541 {
5542 case LE: return CC_DLEmode;
5543 case LEU: return CC_DLEUmode;
5544 case GE: return CC_DGEmode;
5545 case GEU: return CC_DGEUmode;
ad076f4e 5546 default: break;
84ed5e79
RE
5547 }
5548
5549 break;
5550
5551 case LT:
03f1640c 5552 if (cond2 == LT || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5553 return CC_DLTmode;
5554 if (cond2 == LE)
5555 return CC_DLEmode;
5556 if (cond2 == NE)
5557 return CC_DNEmode;
5558 break;
5559
5560 case GT:
03f1640c 5561 if (cond2 == GT || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5562 return CC_DGTmode;
5563 if (cond2 == GE)
5564 return CC_DGEmode;
5565 if (cond2 == NE)
5566 return CC_DNEmode;
5567 break;
5568
5569 case LTU:
03f1640c 5570 if (cond2 == LTU || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5571 return CC_DLTUmode;
5572 if (cond2 == LEU)
5573 return CC_DLEUmode;
5574 if (cond2 == NE)
5575 return CC_DNEmode;
5576 break;
5577
5578 case GTU:
03f1640c 5579 if (cond2 == GTU || cond_or == DOM_CC_X_AND_Y)
84ed5e79
RE
5580 return CC_DGTUmode;
5581 if (cond2 == GEU)
5582 return CC_DGEUmode;
5583 if (cond2 == NE)
5584 return CC_DNEmode;
5585 break;
5586
5587 /* The remaining cases only occur when both comparisons are the
5588 same. */
5589 case NE:
5590 return CC_DNEmode;
5591
5592 case LE:
5593 return CC_DLEmode;
5594
5595 case GE:
5596 return CC_DGEmode;
5597
5598 case LEU:
5599 return CC_DLEUmode;
5600
5601 case GEU:
5602 return CC_DGEUmode;
ad076f4e
RE
5603
5604 default:
5605 break;
84ed5e79
RE
5606 }
5607
5608 abort ();
5609}
5610
5611enum machine_mode
e32bac5b 5612arm_select_cc_mode (enum rtx_code op, rtx x, rtx y)
84ed5e79
RE
5613{
5614 /* All floating point compares return CCFP if it is an equality
5615 comparison, and CCFPE otherwise. */
5616 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
e45b72c4
RE
5617 {
5618 switch (op)
5619 {
5620 case EQ:
5621 case NE:
5622 case UNORDERED:
5623 case ORDERED:
5624 case UNLT:
5625 case UNLE:
5626 case UNGT:
5627 case UNGE:
5628 case UNEQ:
5629 case LTGT:
5630 return CCFPmode;
5631
5632 case LT:
5633 case LE:
5634 case GT:
5635 case GE:
9b6b54e2
NC
5636 if (TARGET_CIRRUS)
5637 return CCFPmode;
e45b72c4
RE
5638 return CCFPEmode;
5639
5640 default:
5641 abort ();
5642 }
5643 }
84ed5e79
RE
5644
5645 /* A compare with a shifted operand. Because of canonicalization, the
5646 comparison will have to be swapped when we emit the assembler. */
5647 if (GET_MODE (y) == SImode && GET_CODE (y) == REG
5648 && (GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
5649 || GET_CODE (x) == LSHIFTRT || GET_CODE (x) == ROTATE
5650 || GET_CODE (x) == ROTATERT))
5651 return CC_SWPmode;
5652
956d6950
JL
5653 /* This is a special case that is used by combine to allow a
5654 comparison of a shifted byte load to be split into a zero-extend
84ed5e79 5655 followed by a comparison of the shifted integer (only valid for
956d6950 5656 equalities and unsigned inequalities). */
84ed5e79
RE
5657 if (GET_MODE (x) == SImode
5658 && GET_CODE (x) == ASHIFT
5659 && GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 24
5660 && GET_CODE (XEXP (x, 0)) == SUBREG
5661 && GET_CODE (SUBREG_REG (XEXP (x, 0))) == MEM
5662 && GET_MODE (SUBREG_REG (XEXP (x, 0))) == QImode
5663 && (op == EQ || op == NE
5664 || op == GEU || op == GTU || op == LTU || op == LEU)
5665 && GET_CODE (y) == CONST_INT)
5666 return CC_Zmode;
5667
1646cf41
RE
5668 /* A construct for a conditional compare, if the false arm contains
5669 0, then both conditions must be true, otherwise either condition
5670 must be true. Not all conditions are possible, so CCmode is
5671 returned if it can't be done. */
5672 if (GET_CODE (x) == IF_THEN_ELSE
5673 && (XEXP (x, 2) == const0_rtx
5674 || XEXP (x, 2) == const1_rtx)
5675 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
5676 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
03f1640c
RE
5677 return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
5678 INTVAL (XEXP (x, 2)));
1646cf41
RE
5679
5680 /* Alternate canonicalizations of the above. These are somewhat cleaner. */
5681 if (GET_CODE (x) == AND
5682 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
5683 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
03f1640c
RE
5684 return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
5685 DOM_CC_X_AND_Y);
1646cf41
RE
5686
5687 if (GET_CODE (x) == IOR
5688 && GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == '<'
5689 && GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == '<')
03f1640c
RE
5690 return arm_select_dominance_cc_mode (XEXP (x, 0), XEXP (x, 1),
5691 DOM_CC_X_OR_Y);
1646cf41 5692
defc0463
RE
5693 /* An operation (on Thumb) where we want to test for a single bit.
5694 This is done by shifting that bit up into the top bit of a
5695 scratch register; we can then branch on the sign bit. */
5696 if (TARGET_THUMB
5697 && GET_MODE (x) == SImode
5698 && (op == EQ || op == NE)
5699 && (GET_CODE (x) == ZERO_EXTRACT))
5700 return CC_Nmode;
5701
84ed5e79
RE
5702 /* An operation that sets the condition codes as a side-effect, the
5703 V flag is not set correctly, so we can only use comparisons where
5704 this doesn't matter. (For LT and GE we can use "mi" and "pl"
defc0463 5705 instead.) */
84ed5e79
RE
5706 if (GET_MODE (x) == SImode
5707 && y == const0_rtx
5708 && (op == EQ || op == NE || op == LT || op == GE)
5709 && (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
5710 || GET_CODE (x) == AND || GET_CODE (x) == IOR
5711 || GET_CODE (x) == XOR || GET_CODE (x) == MULT
5712 || GET_CODE (x) == NOT || GET_CODE (x) == NEG
5713 || GET_CODE (x) == LSHIFTRT
5714 || GET_CODE (x) == ASHIFT || GET_CODE (x) == ASHIFTRT
defc0463
RE
5715 || GET_CODE (x) == ROTATERT
5716 || (TARGET_ARM && GET_CODE (x) == ZERO_EXTRACT)))
84ed5e79
RE
5717 return CC_NOOVmode;
5718
84ed5e79
RE
5719 if (GET_MODE (x) == QImode && (op == EQ || op == NE))
5720 return CC_Zmode;
5721
bd9c7e23
RE
5722 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
5723 && GET_CODE (x) == PLUS
5724 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
5725 return CC_Cmode;
5726
84ed5e79
RE
5727 return CCmode;
5728}
5729
ff9940b0
RE
5730/* X and Y are two things to compare using CODE. Emit the compare insn and
5731 return the rtx for register 0 in the proper mode. FP means this is a
5732 floating point compare: I don't think that it is needed on the arm. */
ff9940b0 5733rtx
e32bac5b 5734arm_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
ff9940b0
RE
5735{
5736 enum machine_mode mode = SELECT_CC_MODE (code, x, y);
d5b7b3ae 5737 rtx cc_reg = gen_rtx_REG (mode, CC_REGNUM);
ff9940b0 5738
43cffd11
RE
5739 emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
5740 gen_rtx_COMPARE (mode, x, y)));
ff9940b0
RE
5741
5742 return cc_reg;
5743}
5744
fcd53748
JT
5745/* Generate a sequence of insns that will generate the correct return
5746 address mask depending on the physical architecture that the program
5747 is running on. */
fcd53748 5748rtx
e32bac5b 5749arm_gen_return_addr_mask (void)
fcd53748
JT
5750{
5751 rtx reg = gen_reg_rtx (Pmode);
5752
5753 emit_insn (gen_return_addr_mask (reg));
5754 return reg;
5755}
5756
0a81f500 5757void
e32bac5b 5758arm_reload_in_hi (rtx *operands)
0a81f500 5759{
f9cc092a
RE
5760 rtx ref = operands[1];
5761 rtx base, scratch;
5762 HOST_WIDE_INT offset = 0;
5763
5764 if (GET_CODE (ref) == SUBREG)
5765 {
ddef6bc7 5766 offset = SUBREG_BYTE (ref);
f9cc092a
RE
5767 ref = SUBREG_REG (ref);
5768 }
5769
5770 if (GET_CODE (ref) == REG)
5771 {
5772 /* We have a pseudo which has been spilt onto the stack; there
5773 are two cases here: the first where there is a simple
5774 stack-slot replacement and a second where the stack-slot is
5775 out of range, or is used as a subreg. */
5776 if (reg_equiv_mem[REGNO (ref)])
5777 {
5778 ref = reg_equiv_mem[REGNO (ref)];
5779 base = find_replacement (&XEXP (ref, 0));
5780 }
5781 else
6354dc9b 5782 /* The slot is out of range, or was dressed up in a SUBREG. */
f9cc092a
RE
5783 base = reg_equiv_address[REGNO (ref)];
5784 }
5785 else
5786 base = find_replacement (&XEXP (ref, 0));
0a81f500 5787
e5e809f4
JL
5788 /* Handle the case where the address is too complex to be offset by 1. */
5789 if (GET_CODE (base) == MINUS
5790 || (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
5791 {
f9cc092a 5792 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
e5e809f4 5793
43cffd11 5794 emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
e5e809f4
JL
5795 base = base_plus;
5796 }
f9cc092a
RE
5797 else if (GET_CODE (base) == PLUS)
5798 {
6354dc9b 5799 /* The addend must be CONST_INT, or we would have dealt with it above. */
f9cc092a
RE
5800 HOST_WIDE_INT hi, lo;
5801
5802 offset += INTVAL (XEXP (base, 1));
5803 base = XEXP (base, 0);
5804
6354dc9b 5805 /* Rework the address into a legal sequence of insns. */
f9cc092a
RE
5806 /* Valid range for lo is -4095 -> 4095 */
5807 lo = (offset >= 0
5808 ? (offset & 0xfff)
5809 : -((-offset) & 0xfff));
5810
5811 /* Corner case, if lo is the max offset then we would be out of range
5812 once we have added the additional 1 below, so bump the msb into the
5813 pre-loading insn(s). */
5814 if (lo == 4095)
5815 lo &= 0x7ff;
5816
30cf4896
KG
5817 hi = ((((offset - lo) & (HOST_WIDE_INT) 0xffffffff)
5818 ^ (HOST_WIDE_INT) 0x80000000)
5819 - (HOST_WIDE_INT) 0x80000000);
f9cc092a
RE
5820
5821 if (hi + lo != offset)
5822 abort ();
5823
5824 if (hi != 0)
5825 {
5826 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5827
5828 /* Get the base address; addsi3 knows how to handle constants
6354dc9b 5829 that require more than one insn. */
f9cc092a
RE
5830 emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
5831 base = base_plus;
5832 offset = lo;
5833 }
5834 }
e5e809f4 5835
3a1944a6
RE
5836 /* Operands[2] may overlap operands[0] (though it won't overlap
5837 operands[1]), that's why we asked for a DImode reg -- so we can
5838 use the bit that does not overlap. */
5839 if (REGNO (operands[2]) == REGNO (operands[0]))
5840 scratch = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5841 else
5842 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5843
f9cc092a
RE
5844 emit_insn (gen_zero_extendqisi2 (scratch,
5845 gen_rtx_MEM (QImode,
5846 plus_constant (base,
5847 offset))));
43cffd11
RE
5848 emit_insn (gen_zero_extendqisi2 (gen_rtx_SUBREG (SImode, operands[0], 0),
5849 gen_rtx_MEM (QImode,
f9cc092a
RE
5850 plus_constant (base,
5851 offset + 1))));
5895f793 5852 if (!BYTES_BIG_ENDIAN)
43cffd11
RE
5853 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
5854 gen_rtx_IOR (SImode,
5855 gen_rtx_ASHIFT
5856 (SImode,
5857 gen_rtx_SUBREG (SImode, operands[0], 0),
5858 GEN_INT (8)),
f9cc092a 5859 scratch)));
0a81f500 5860 else
43cffd11
RE
5861 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_SUBREG (SImode, operands[0], 0),
5862 gen_rtx_IOR (SImode,
f9cc092a 5863 gen_rtx_ASHIFT (SImode, scratch,
43cffd11
RE
5864 GEN_INT (8)),
5865 gen_rtx_SUBREG (SImode, operands[0],
5866 0))));
0a81f500
RE
5867}
5868
72ac76be 5869/* Handle storing a half-word to memory during reload by synthesizing as two
f9cc092a
RE
5870 byte stores. Take care not to clobber the input values until after we
5871 have moved them somewhere safe. This code assumes that if the DImode
5872 scratch in operands[2] overlaps either the input value or output address
5873 in some way, then that value must die in this insn (we absolutely need
5874 two scratch registers for some corner cases). */
f3bb6135 5875void
e32bac5b 5876arm_reload_out_hi (rtx *operands)
af48348a 5877{
f9cc092a
RE
5878 rtx ref = operands[0];
5879 rtx outval = operands[1];
5880 rtx base, scratch;
5881 HOST_WIDE_INT offset = 0;
5882
5883 if (GET_CODE (ref) == SUBREG)
5884 {
ddef6bc7 5885 offset = SUBREG_BYTE (ref);
f9cc092a
RE
5886 ref = SUBREG_REG (ref);
5887 }
5888
f9cc092a
RE
5889 if (GET_CODE (ref) == REG)
5890 {
5891 /* We have a pseudo which has been spilt onto the stack; there
5892 are two cases here: the first where there is a simple
5893 stack-slot replacement and a second where the stack-slot is
5894 out of range, or is used as a subreg. */
5895 if (reg_equiv_mem[REGNO (ref)])
5896 {
5897 ref = reg_equiv_mem[REGNO (ref)];
5898 base = find_replacement (&XEXP (ref, 0));
5899 }
5900 else
6354dc9b 5901 /* The slot is out of range, or was dressed up in a SUBREG. */
f9cc092a
RE
5902 base = reg_equiv_address[REGNO (ref)];
5903 }
5904 else
5905 base = find_replacement (&XEXP (ref, 0));
5906
5907 scratch = gen_rtx_REG (SImode, REGNO (operands[2]));
5908
5909 /* Handle the case where the address is too complex to be offset by 1. */
5910 if (GET_CODE (base) == MINUS
5911 || (GET_CODE (base) == PLUS && GET_CODE (XEXP (base, 1)) != CONST_INT))
5912 {
5913 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5914
5915 /* Be careful not to destroy OUTVAL. */
5916 if (reg_overlap_mentioned_p (base_plus, outval))
5917 {
5918 /* Updating base_plus might destroy outval, see if we can
5919 swap the scratch and base_plus. */
5895f793 5920 if (!reg_overlap_mentioned_p (scratch, outval))
f9cc092a
RE
5921 {
5922 rtx tmp = scratch;
5923 scratch = base_plus;
5924 base_plus = tmp;
5925 }
5926 else
5927 {
5928 rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
5929
5930 /* Be conservative and copy OUTVAL into the scratch now,
5931 this should only be necessary if outval is a subreg
5932 of something larger than a word. */
5933 /* XXX Might this clobber base? I can't see how it can,
5934 since scratch is known to overlap with OUTVAL, and
5935 must be wider than a word. */
5936 emit_insn (gen_movhi (scratch_hi, outval));
5937 outval = scratch_hi;
5938 }
5939 }
5940
5941 emit_insn (gen_rtx_SET (VOIDmode, base_plus, base));
5942 base = base_plus;
5943 }
5944 else if (GET_CODE (base) == PLUS)
5945 {
6354dc9b 5946 /* The addend must be CONST_INT, or we would have dealt with it above. */
f9cc092a
RE
5947 HOST_WIDE_INT hi, lo;
5948
5949 offset += INTVAL (XEXP (base, 1));
5950 base = XEXP (base, 0);
5951
6354dc9b 5952 /* Rework the address into a legal sequence of insns. */
f9cc092a
RE
5953 /* Valid range for lo is -4095 -> 4095 */
5954 lo = (offset >= 0
5955 ? (offset & 0xfff)
5956 : -((-offset) & 0xfff));
5957
5958 /* Corner case, if lo is the max offset then we would be out of range
5959 once we have added the additional 1 below, so bump the msb into the
5960 pre-loading insn(s). */
5961 if (lo == 4095)
5962 lo &= 0x7ff;
5963
30cf4896
KG
5964 hi = ((((offset - lo) & (HOST_WIDE_INT) 0xffffffff)
5965 ^ (HOST_WIDE_INT) 0x80000000)
5966 - (HOST_WIDE_INT) 0x80000000);
f9cc092a
RE
5967
5968 if (hi + lo != offset)
5969 abort ();
5970
5971 if (hi != 0)
5972 {
5973 rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
5974
5975 /* Be careful not to destroy OUTVAL. */
5976 if (reg_overlap_mentioned_p (base_plus, outval))
5977 {
5978 /* Updating base_plus might destroy outval, see if we
5979 can swap the scratch and base_plus. */
5895f793 5980 if (!reg_overlap_mentioned_p (scratch, outval))
f9cc092a
RE
5981 {
5982 rtx tmp = scratch;
5983 scratch = base_plus;
5984 base_plus = tmp;
5985 }
5986 else
5987 {
5988 rtx scratch_hi = gen_rtx_REG (HImode, REGNO (operands[2]));
5989
5990 /* Be conservative and copy outval into scratch now,
5991 this should only be necessary if outval is a
5992 subreg of something larger than a word. */
5993 /* XXX Might this clobber base? I can't see how it
5994 can, since scratch is known to overlap with
5995 outval. */
5996 emit_insn (gen_movhi (scratch_hi, outval));
5997 outval = scratch_hi;
5998 }
5999 }
6000
6001 /* Get the base address; addsi3 knows how to handle constants
6354dc9b 6002 that require more than one insn. */
f9cc092a
RE
6003 emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
6004 base = base_plus;
6005 offset = lo;
6006 }
6007 }
af48348a 6008
b5cc037f
RE
6009 if (BYTES_BIG_ENDIAN)
6010 {
f9cc092a
RE
6011 emit_insn (gen_movqi (gen_rtx_MEM (QImode,
6012 plus_constant (base, offset + 1)),
5d5603e2 6013 gen_lowpart (QImode, outval)));
f9cc092a
RE
6014 emit_insn (gen_lshrsi3 (scratch,
6015 gen_rtx_SUBREG (SImode, outval, 0),
b5cc037f 6016 GEN_INT (8)));
f9cc092a 6017 emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
5d5603e2 6018 gen_lowpart (QImode, scratch)));
b5cc037f
RE
6019 }
6020 else
6021 {
f9cc092a 6022 emit_insn (gen_movqi (gen_rtx_MEM (QImode, plus_constant (base, offset)),
5d5603e2 6023 gen_lowpart (QImode, outval)));
f9cc092a
RE
6024 emit_insn (gen_lshrsi3 (scratch,
6025 gen_rtx_SUBREG (SImode, outval, 0),
b5cc037f 6026 GEN_INT (8)));
f9cc092a
RE
6027 emit_insn (gen_movqi (gen_rtx_MEM (QImode,
6028 plus_constant (base, offset + 1)),
5d5603e2 6029 gen_lowpart (QImode, scratch)));
b5cc037f 6030 }
af48348a 6031}
2b835d68 6032\f
d5b7b3ae
RE
6033/* Print a symbolic form of X to the debug file, F. */
6034static void
e32bac5b 6035arm_print_value (FILE *f, rtx x)
d5b7b3ae
RE
6036{
6037 switch (GET_CODE (x))
6038 {
6039 case CONST_INT:
6040 fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
6041 return;
6042
6043 case CONST_DOUBLE:
6044 fprintf (f, "<0x%lx,0x%lx>", (long)XWINT (x, 2), (long)XWINT (x, 3));
6045 return;
6046
5a9335ef
NC
6047 case CONST_VECTOR:
6048 {
6049 int i;
6050
6051 fprintf (f, "<");
6052 for (i = 0; i < CONST_VECTOR_NUNITS (x); i++)
6053 {
6054 fprintf (f, HOST_WIDE_INT_PRINT_HEX, INTVAL (CONST_VECTOR_ELT (x, i)));
6055 if (i < (CONST_VECTOR_NUNITS (x) - 1))
6056 fputc (',', f);
6057 }
6058 fprintf (f, ">");
6059 }
6060 return;
6061
d5b7b3ae
RE
6062 case CONST_STRING:
6063 fprintf (f, "\"%s\"", XSTR (x, 0));
6064 return;
6065
6066 case SYMBOL_REF:
6067 fprintf (f, "`%s'", XSTR (x, 0));
6068 return;
6069
6070 case LABEL_REF:
6071 fprintf (f, "L%d", INSN_UID (XEXP (x, 0)));
6072 return;
6073
6074 case CONST:
6075 arm_print_value (f, XEXP (x, 0));
6076 return;
6077
6078 case PLUS:
6079 arm_print_value (f, XEXP (x, 0));
6080 fprintf (f, "+");
6081 arm_print_value (f, XEXP (x, 1));
6082 return;
6083
6084 case PC:
6085 fprintf (f, "pc");
6086 return;
6087
6088 default:
6089 fprintf (f, "????");
6090 return;
6091 }
6092}
6093\f
2b835d68 6094/* Routines for manipulation of the constant pool. */
2b835d68 6095
949d79eb
RE
6096/* Arm instructions cannot load a large constant directly into a
6097 register; they have to come from a pc relative load. The constant
6098 must therefore be placed in the addressable range of the pc
6099 relative load. Depending on the precise pc relative load
6100 instruction the range is somewhere between 256 bytes and 4k. This
6101 means that we often have to dump a constant inside a function, and
2b835d68
RE
6102 generate code to branch around it.
6103
949d79eb
RE
6104 It is important to minimize this, since the branches will slow
6105 things down and make the code larger.
2b835d68 6106
949d79eb
RE
6107 Normally we can hide the table after an existing unconditional
6108 branch so that there is no interruption of the flow, but in the
6109 worst case the code looks like this:
2b835d68
RE
6110
6111 ldr rn, L1
949d79eb 6112 ...
2b835d68
RE
6113 b L2
6114 align
6115 L1: .long value
6116 L2:
949d79eb 6117 ...
2b835d68 6118
2b835d68 6119 ldr rn, L3
949d79eb 6120 ...
2b835d68
RE
6121 b L4
6122 align
2b835d68
RE
6123 L3: .long value
6124 L4:
949d79eb
RE
6125 ...
6126
6127 We fix this by performing a scan after scheduling, which notices
6128 which instructions need to have their operands fetched from the
6129 constant table and builds the table.
6130
6131 The algorithm starts by building a table of all the constants that
6132 need fixing up and all the natural barriers in the function (places
6133 where a constant table can be dropped without breaking the flow).
6134 For each fixup we note how far the pc-relative replacement will be
6135 able to reach and the offset of the instruction into the function.
6136
6137 Having built the table we then group the fixes together to form
6138 tables that are as large as possible (subject to addressing
6139 constraints) and emit each table of constants after the last
6140 barrier that is within range of all the instructions in the group.
6141 If a group does not contain a barrier, then we forcibly create one
6142 by inserting a jump instruction into the flow. Once the table has
6143 been inserted, the insns are then modified to reference the
6144 relevant entry in the pool.
6145
6354dc9b 6146 Possible enhancements to the algorithm (not implemented) are:
949d79eb 6147
d5b7b3ae 6148 1) For some processors and object formats, there may be benefit in
949d79eb
RE
6149 aligning the pools to the start of cache lines; this alignment
6150 would need to be taken into account when calculating addressability
6354dc9b 6151 of a pool. */
2b835d68 6152
d5b7b3ae
RE
6153/* These typedefs are located at the start of this file, so that
6154 they can be used in the prototypes there. This comment is to
6155 remind readers of that fact so that the following structures
6156 can be understood more easily.
6157
6158 typedef struct minipool_node Mnode;
6159 typedef struct minipool_fixup Mfix; */
6160
6161struct minipool_node
6162{
6163 /* Doubly linked chain of entries. */
6164 Mnode * next;
6165 Mnode * prev;
6166 /* The maximum offset into the code that this entry can be placed. While
6167 pushing fixes for forward references, all entries are sorted in order
6168 of increasing max_address. */
6169 HOST_WIDE_INT max_address;
5519a4f9 6170 /* Similarly for an entry inserted for a backwards ref. */
d5b7b3ae
RE
6171 HOST_WIDE_INT min_address;
6172 /* The number of fixes referencing this entry. This can become zero
6173 if we "unpush" an entry. In this case we ignore the entry when we
6174 come to emit the code. */
6175 int refcount;
6176 /* The offset from the start of the minipool. */
6177 HOST_WIDE_INT offset;
6178 /* The value in table. */
6179 rtx value;
6180 /* The mode of value. */
6181 enum machine_mode mode;
5a9335ef
NC
6182 /* The size of the value. With iWMMXt enabled
6183 sizes > 4 also imply an alignment of 8-bytes. */
d5b7b3ae
RE
6184 int fix_size;
6185};
6186
6187struct minipool_fixup
2b835d68 6188{
d5b7b3ae
RE
6189 Mfix * next;
6190 rtx insn;
6191 HOST_WIDE_INT address;
6192 rtx * loc;
6193 enum machine_mode mode;
6194 int fix_size;
6195 rtx value;
6196 Mnode * minipool;
6197 HOST_WIDE_INT forwards;
6198 HOST_WIDE_INT backwards;
6199};
2b835d68 6200
d5b7b3ae
RE
6201/* Fixes less than a word need padding out to a word boundary. */
6202#define MINIPOOL_FIX_SIZE(mode) \
6203 (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4)
2b835d68 6204
d5b7b3ae
RE
6205static Mnode * minipool_vector_head;
6206static Mnode * minipool_vector_tail;
6207static rtx minipool_vector_label;
332072db 6208
d5b7b3ae
RE
6209/* The linked list of all minipool fixes required for this function. */
6210Mfix * minipool_fix_head;
6211Mfix * minipool_fix_tail;
6212/* The fix entry for the current minipool, once it has been placed. */
6213Mfix * minipool_barrier;
6214
6215/* Determines if INSN is the start of a jump table. Returns the end
6216 of the TABLE or NULL_RTX. */
6217static rtx
e32bac5b 6218is_jump_table (rtx insn)
2b835d68 6219{
d5b7b3ae 6220 rtx table;
da6558fd 6221
d5b7b3ae
RE
6222 if (GET_CODE (insn) == JUMP_INSN
6223 && JUMP_LABEL (insn) != NULL
6224 && ((table = next_real_insn (JUMP_LABEL (insn)))
6225 == next_real_insn (insn))
6226 && table != NULL
6227 && GET_CODE (table) == JUMP_INSN
6228 && (GET_CODE (PATTERN (table)) == ADDR_VEC
6229 || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
6230 return table;
6231
6232 return NULL_RTX;
2b835d68
RE
6233}
6234
657d9449
RE
6235#ifndef JUMP_TABLES_IN_TEXT_SECTION
6236#define JUMP_TABLES_IN_TEXT_SECTION 0
6237#endif
6238
d5b7b3ae 6239static HOST_WIDE_INT
e32bac5b 6240get_jump_table_size (rtx insn)
2b835d68 6241{
657d9449
RE
6242 /* ADDR_VECs only take room if read-only data does into the text
6243 section. */
6244 if (JUMP_TABLES_IN_TEXT_SECTION
d48bc59a 6245#if !defined(READONLY_DATA_SECTION) && !defined(READONLY_DATA_SECTION_ASM_OP)
657d9449
RE
6246 || 1
6247#endif
6248 )
6249 {
6250 rtx body = PATTERN (insn);
6251 int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
2b835d68 6252
657d9449
RE
6253 return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
6254 }
6255
6256 return 0;
d5b7b3ae 6257}
2b835d68 6258
d5b7b3ae
RE
6259/* Move a minipool fix MP from its current location to before MAX_MP.
6260 If MAX_MP is NULL, then MP doesn't need moving, but the addressing
093354e0 6261 constraints may need updating. */
d5b7b3ae 6262static Mnode *
e32bac5b
RE
6263move_minipool_fix_forward_ref (Mnode *mp, Mnode *max_mp,
6264 HOST_WIDE_INT max_address)
d5b7b3ae
RE
6265{
6266 /* This should never be true and the code below assumes these are
6267 different. */
6268 if (mp == max_mp)
6269 abort ();
6270
6271 if (max_mp == NULL)
6272 {
6273 if (max_address < mp->max_address)
6274 mp->max_address = max_address;
6275 }
6276 else
2b835d68 6277 {
d5b7b3ae
RE
6278 if (max_address > max_mp->max_address - mp->fix_size)
6279 mp->max_address = max_mp->max_address - mp->fix_size;
6280 else
6281 mp->max_address = max_address;
2b835d68 6282
d5b7b3ae
RE
6283 /* Unlink MP from its current position. Since max_mp is non-null,
6284 mp->prev must be non-null. */
6285 mp->prev->next = mp->next;
6286 if (mp->next != NULL)
6287 mp->next->prev = mp->prev;
6288 else
6289 minipool_vector_tail = mp->prev;
2b835d68 6290
d5b7b3ae
RE
6291 /* Re-insert it before MAX_MP. */
6292 mp->next = max_mp;
6293 mp->prev = max_mp->prev;
6294 max_mp->prev = mp;
6295
6296 if (mp->prev != NULL)
6297 mp->prev->next = mp;
6298 else
6299 minipool_vector_head = mp;
6300 }
2b835d68 6301
d5b7b3ae
RE
6302 /* Save the new entry. */
6303 max_mp = mp;
6304
d6a7951f 6305 /* Scan over the preceding entries and adjust their addresses as
d5b7b3ae
RE
6306 required. */
6307 while (mp->prev != NULL
6308 && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
6309 {
6310 mp->prev->max_address = mp->max_address - mp->prev->fix_size;
6311 mp = mp->prev;
2b835d68
RE
6312 }
6313
d5b7b3ae 6314 return max_mp;
2b835d68
RE
6315}
6316
d5b7b3ae
RE
6317/* Add a constant to the minipool for a forward reference. Returns the
6318 node added or NULL if the constant will not fit in this pool. */
6319static Mnode *
e32bac5b 6320add_minipool_forward_ref (Mfix *fix)
d5b7b3ae
RE
6321{
6322 /* If set, max_mp is the first pool_entry that has a lower
6323 constraint than the one we are trying to add. */
6324 Mnode * max_mp = NULL;
6325 HOST_WIDE_INT max_address = fix->address + fix->forwards;
6326 Mnode * mp;
6327
6328 /* If this fix's address is greater than the address of the first
6329 entry, then we can't put the fix in this pool. We subtract the
6330 size of the current fix to ensure that if the table is fully
6331 packed we still have enough room to insert this value by suffling
6332 the other fixes forwards. */
6333 if (minipool_vector_head &&
6334 fix->address >= minipool_vector_head->max_address - fix->fix_size)
6335 return NULL;
2b835d68 6336
d5b7b3ae
RE
6337 /* Scan the pool to see if a constant with the same value has
6338 already been added. While we are doing this, also note the
6339 location where we must insert the constant if it doesn't already
6340 exist. */
6341 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
6342 {
6343 if (GET_CODE (fix->value) == GET_CODE (mp->value)
6344 && fix->mode == mp->mode
6345 && (GET_CODE (fix->value) != CODE_LABEL
6346 || (CODE_LABEL_NUMBER (fix->value)
6347 == CODE_LABEL_NUMBER (mp->value)))
6348 && rtx_equal_p (fix->value, mp->value))
6349 {
6350 /* More than one fix references this entry. */
6351 mp->refcount++;
6352 return move_minipool_fix_forward_ref (mp, max_mp, max_address);
6353 }
6354
6355 /* Note the insertion point if necessary. */
6356 if (max_mp == NULL
6357 && mp->max_address > max_address)
6358 max_mp = mp;
5a9335ef
NC
6359
6360 /* If we are inserting an 8-bytes aligned quantity and
6361 we have not already found an insertion point, then
6362 make sure that all such 8-byte aligned quantities are
6363 placed at the start of the pool. */
6364 if (TARGET_REALLY_IWMMXT
6365 && max_mp == NULL
6366 && fix->fix_size == 8
6367 && mp->fix_size != 8)
6368 {
6369 max_mp = mp;
6370 max_address = mp->max_address;
6371 }
d5b7b3ae
RE
6372 }
6373
6374 /* The value is not currently in the minipool, so we need to create
6375 a new entry for it. If MAX_MP is NULL, the entry will be put on
6376 the end of the list since the placement is less constrained than
6377 any existing entry. Otherwise, we insert the new fix before
6bc82793 6378 MAX_MP and, if necessary, adjust the constraints on the other
d5b7b3ae
RE
6379 entries. */
6380 mp = xmalloc (sizeof (* mp));
6381 mp->fix_size = fix->fix_size;
6382 mp->mode = fix->mode;
6383 mp->value = fix->value;
6384 mp->refcount = 1;
6385 /* Not yet required for a backwards ref. */
6386 mp->min_address = -65536;
6387
6388 if (max_mp == NULL)
6389 {
6390 mp->max_address = max_address;
6391 mp->next = NULL;
6392 mp->prev = minipool_vector_tail;
6393
6394 if (mp->prev == NULL)
6395 {
6396 minipool_vector_head = mp;
6397 minipool_vector_label = gen_label_rtx ();
7551cbc7 6398 }
2b835d68 6399 else
d5b7b3ae 6400 mp->prev->next = mp;
2b835d68 6401
d5b7b3ae
RE
6402 minipool_vector_tail = mp;
6403 }
6404 else
6405 {
6406 if (max_address > max_mp->max_address - mp->fix_size)
6407 mp->max_address = max_mp->max_address - mp->fix_size;
6408 else
6409 mp->max_address = max_address;
6410
6411 mp->next = max_mp;
6412 mp->prev = max_mp->prev;
6413 max_mp->prev = mp;
6414 if (mp->prev != NULL)
6415 mp->prev->next = mp;
6416 else
6417 minipool_vector_head = mp;
6418 }
6419
6420 /* Save the new entry. */
6421 max_mp = mp;
6422
d6a7951f 6423 /* Scan over the preceding entries and adjust their addresses as
d5b7b3ae
RE
6424 required. */
6425 while (mp->prev != NULL
6426 && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
6427 {
6428 mp->prev->max_address = mp->max_address - mp->prev->fix_size;
6429 mp = mp->prev;
2b835d68
RE
6430 }
6431
d5b7b3ae
RE
6432 return max_mp;
6433}
6434
6435static Mnode *
e32bac5b
RE
6436move_minipool_fix_backward_ref (Mnode *mp, Mnode *min_mp,
6437 HOST_WIDE_INT min_address)
d5b7b3ae
RE
6438{
6439 HOST_WIDE_INT offset;
6440
6441 /* This should never be true, and the code below assumes these are
6442 different. */
6443 if (mp == min_mp)
6444 abort ();
6445
6446 if (min_mp == NULL)
2b835d68 6447 {
d5b7b3ae
RE
6448 if (min_address > mp->min_address)
6449 mp->min_address = min_address;
6450 }
6451 else
6452 {
6453 /* We will adjust this below if it is too loose. */
6454 mp->min_address = min_address;
6455
6456 /* Unlink MP from its current position. Since min_mp is non-null,
6457 mp->next must be non-null. */
6458 mp->next->prev = mp->prev;
6459 if (mp->prev != NULL)
6460 mp->prev->next = mp->next;
6461 else
6462 minipool_vector_head = mp->next;
6463
6464 /* Reinsert it after MIN_MP. */
6465 mp->prev = min_mp;
6466 mp->next = min_mp->next;
6467 min_mp->next = mp;
6468 if (mp->next != NULL)
6469 mp->next->prev = mp;
2b835d68 6470 else
d5b7b3ae
RE
6471 minipool_vector_tail = mp;
6472 }
6473
6474 min_mp = mp;
6475
6476 offset = 0;
6477 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
6478 {
6479 mp->offset = offset;
6480 if (mp->refcount > 0)
6481 offset += mp->fix_size;
6482
6483 if (mp->next && mp->next->min_address < mp->min_address + mp->fix_size)
6484 mp->next->min_address = mp->min_address + mp->fix_size;
6485 }
6486
6487 return min_mp;
6488}
6489
6490/* Add a constant to the minipool for a backward reference. Returns the
6491 node added or NULL if the constant will not fit in this pool.
6492
6493 Note that the code for insertion for a backwards reference can be
6494 somewhat confusing because the calculated offsets for each fix do
6495 not take into account the size of the pool (which is still under
6496 construction. */
6497static Mnode *
e32bac5b 6498add_minipool_backward_ref (Mfix *fix)
d5b7b3ae
RE
6499{
6500 /* If set, min_mp is the last pool_entry that has a lower constraint
6501 than the one we are trying to add. */
e32bac5b 6502 Mnode *min_mp = NULL;
d5b7b3ae
RE
6503 /* This can be negative, since it is only a constraint. */
6504 HOST_WIDE_INT min_address = fix->address - fix->backwards;
e32bac5b 6505 Mnode *mp;
d5b7b3ae
RE
6506
6507 /* If we can't reach the current pool from this insn, or if we can't
6508 insert this entry at the end of the pool without pushing other
6509 fixes out of range, then we don't try. This ensures that we
6510 can't fail later on. */
6511 if (min_address >= minipool_barrier->address
6512 || (minipool_vector_tail->min_address + fix->fix_size
6513 >= minipool_barrier->address))
6514 return NULL;
6515
6516 /* Scan the pool to see if a constant with the same value has
6517 already been added. While we are doing this, also note the
6518 location where we must insert the constant if it doesn't already
6519 exist. */
6520 for (mp = minipool_vector_tail; mp != NULL; mp = mp->prev)
6521 {
6522 if (GET_CODE (fix->value) == GET_CODE (mp->value)
6523 && fix->mode == mp->mode
6524 && (GET_CODE (fix->value) != CODE_LABEL
6525 || (CODE_LABEL_NUMBER (fix->value)
6526 == CODE_LABEL_NUMBER (mp->value)))
6527 && rtx_equal_p (fix->value, mp->value)
6528 /* Check that there is enough slack to move this entry to the
6529 end of the table (this is conservative). */
6530 && (mp->max_address
6531 > (minipool_barrier->address
6532 + minipool_vector_tail->offset
6533 + minipool_vector_tail->fix_size)))
6534 {
6535 mp->refcount++;
6536 return move_minipool_fix_backward_ref (mp, min_mp, min_address);
6537 }
6538
6539 if (min_mp != NULL)
6540 mp->min_address += fix->fix_size;
6541 else
6542 {
6543 /* Note the insertion point if necessary. */
6544 if (mp->min_address < min_address)
5a9335ef
NC
6545 {
6546 /* For now, we do not allow the insertion of 8-byte alignment
6547 requiring nodes anywhere but at the start of the pool. */
6548 if (TARGET_REALLY_IWMMXT && fix->fix_size == 8 && mp->fix_size != 8)
6549 return NULL;
6550 else
6551 min_mp = mp;
6552 }
d5b7b3ae
RE
6553 else if (mp->max_address
6554 < minipool_barrier->address + mp->offset + fix->fix_size)
6555 {
6556 /* Inserting before this entry would push the fix beyond
6557 its maximum address (which can happen if we have
6558 re-located a forwards fix); force the new fix to come
6559 after it. */
6560 min_mp = mp;
6561 min_address = mp->min_address + fix->fix_size;
6562 }
5a9335ef
NC
6563 /* If we are inserting an 8-bytes aligned quantity and
6564 we have not already found an insertion point, then
6565 make sure that all such 8-byte aligned quantities are
6566 placed at the start of the pool. */
6567 else if (TARGET_REALLY_IWMMXT
6568 && min_mp == NULL
6569 && fix->fix_size == 8
6570 && mp->fix_size < 8)
6571 {
6572 min_mp = mp;
6573 min_address = mp->min_address + fix->fix_size;
6574 }
d5b7b3ae
RE
6575 }
6576 }
6577
6578 /* We need to create a new entry. */
6579 mp = xmalloc (sizeof (* mp));
6580 mp->fix_size = fix->fix_size;
6581 mp->mode = fix->mode;
6582 mp->value = fix->value;
6583 mp->refcount = 1;
6584 mp->max_address = minipool_barrier->address + 65536;
6585
6586 mp->min_address = min_address;
6587
6588 if (min_mp == NULL)
6589 {
6590 mp->prev = NULL;
6591 mp->next = minipool_vector_head;
6592
6593 if (mp->next == NULL)
6594 {
6595 minipool_vector_tail = mp;
6596 minipool_vector_label = gen_label_rtx ();
6597 }
6598 else
6599 mp->next->prev = mp;
6600
6601 minipool_vector_head = mp;
6602 }
6603 else
6604 {
6605 mp->next = min_mp->next;
6606 mp->prev = min_mp;
6607 min_mp->next = mp;
da6558fd 6608
d5b7b3ae
RE
6609 if (mp->next != NULL)
6610 mp->next->prev = mp;
6611 else
6612 minipool_vector_tail = mp;
6613 }
6614
6615 /* Save the new entry. */
6616 min_mp = mp;
6617
6618 if (mp->prev)
6619 mp = mp->prev;
6620 else
6621 mp->offset = 0;
6622
6623 /* Scan over the following entries and adjust their offsets. */
6624 while (mp->next != NULL)
6625 {
6626 if (mp->next->min_address < mp->min_address + mp->fix_size)
6627 mp->next->min_address = mp->min_address + mp->fix_size;
6628
6629 if (mp->refcount)
6630 mp->next->offset = mp->offset + mp->fix_size;
6631 else
6632 mp->next->offset = mp->offset;
6633
6634 mp = mp->next;
6635 }
6636
6637 return min_mp;
6638}
6639
6640static void
e32bac5b 6641assign_minipool_offsets (Mfix *barrier)
d5b7b3ae
RE
6642{
6643 HOST_WIDE_INT offset = 0;
e32bac5b 6644 Mnode *mp;
d5b7b3ae
RE
6645
6646 minipool_barrier = barrier;
6647
6648 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
6649 {
6650 mp->offset = offset;
da6558fd 6651
d5b7b3ae
RE
6652 if (mp->refcount > 0)
6653 offset += mp->fix_size;
6654 }
6655}
6656
6657/* Output the literal table */
6658static void
e32bac5b 6659dump_minipool (rtx scan)
d5b7b3ae 6660{
5a9335ef
NC
6661 Mnode * mp;
6662 Mnode * nmp;
6663 int align64 = 0;
6664
6665 if (TARGET_REALLY_IWMMXT)
6666 for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
6667 if (mp->refcount > 0 && mp->fix_size == 8)
6668 {
6669 align64 = 1;
6670 break;
6671 }
d5b7b3ae
RE
6672
6673 if (rtl_dump_file)
6674 fprintf (rtl_dump_file,
5a9335ef
NC
6675 ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n",
6676 INSN_UID (scan), (unsigned long) minipool_barrier->address, align64 ? 8 : 4);
d5b7b3ae
RE
6677
6678 scan = emit_label_after (gen_label_rtx (), scan);
5a9335ef 6679 scan = emit_insn_after (align64 ? gen_align_8 () : gen_align_4 (), scan);
d5b7b3ae
RE
6680 scan = emit_label_after (minipool_vector_label, scan);
6681
6682 for (mp = minipool_vector_head; mp != NULL; mp = nmp)
6683 {
6684 if (mp->refcount > 0)
6685 {
6686 if (rtl_dump_file)
6687 {
6688 fprintf (rtl_dump_file,
6689 ";; Offset %u, min %ld, max %ld ",
6690 (unsigned) mp->offset, (unsigned long) mp->min_address,
6691 (unsigned long) mp->max_address);
6692 arm_print_value (rtl_dump_file, mp->value);
6693 fputc ('\n', rtl_dump_file);
6694 }
6695
6696 switch (mp->fix_size)
6697 {
6698#ifdef HAVE_consttable_1
6699 case 1:
6700 scan = emit_insn_after (gen_consttable_1 (mp->value), scan);
6701 break;
6702
6703#endif
6704#ifdef HAVE_consttable_2
6705 case 2:
6706 scan = emit_insn_after (gen_consttable_2 (mp->value), scan);
6707 break;
6708
6709#endif
6710#ifdef HAVE_consttable_4
6711 case 4:
6712 scan = emit_insn_after (gen_consttable_4 (mp->value), scan);
6713 break;
6714
6715#endif
6716#ifdef HAVE_consttable_8
6717 case 8:
6718 scan = emit_insn_after (gen_consttable_8 (mp->value), scan);
6719 break;
6720
6721#endif
6722 default:
6723 abort ();
6724 break;
6725 }
6726 }
6727
6728 nmp = mp->next;
6729 free (mp);
2b835d68
RE
6730 }
6731
d5b7b3ae
RE
6732 minipool_vector_head = minipool_vector_tail = NULL;
6733 scan = emit_insn_after (gen_consttable_end (), scan);
6734 scan = emit_barrier_after (scan);
2b835d68
RE
6735}
6736
d5b7b3ae
RE
6737/* Return the cost of forcibly inserting a barrier after INSN. */
6738static int
e32bac5b 6739arm_barrier_cost (rtx insn)
949d79eb 6740{
d5b7b3ae
RE
6741 /* Basing the location of the pool on the loop depth is preferable,
6742 but at the moment, the basic block information seems to be
6743 corrupt by this stage of the compilation. */
6744 int base_cost = 50;
6745 rtx next = next_nonnote_insn (insn);
6746
6747 if (next != NULL && GET_CODE (next) == CODE_LABEL)
6748 base_cost -= 20;
6749
6750 switch (GET_CODE (insn))
6751 {
6752 case CODE_LABEL:
6753 /* It will always be better to place the table before the label, rather
6754 than after it. */
6755 return 50;
949d79eb 6756
d5b7b3ae
RE
6757 case INSN:
6758 case CALL_INSN:
6759 return base_cost;
6760
6761 case JUMP_INSN:
6762 return base_cost - 10;
6763
6764 default:
6765 return base_cost + 10;
6766 }
6767}
6768
6769/* Find the best place in the insn stream in the range
6770 (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
6771 Create the barrier by inserting a jump and add a new fix entry for
6772 it. */
6773static Mfix *
e32bac5b 6774create_fix_barrier (Mfix *fix, HOST_WIDE_INT max_address)
d5b7b3ae
RE
6775{
6776 HOST_WIDE_INT count = 0;
6777 rtx barrier;
6778 rtx from = fix->insn;
6779 rtx selected = from;
6780 int selected_cost;
6781 HOST_WIDE_INT selected_address;
6782 Mfix * new_fix;
6783 HOST_WIDE_INT max_count = max_address - fix->address;
6784 rtx label = gen_label_rtx ();
6785
6786 selected_cost = arm_barrier_cost (from);
6787 selected_address = fix->address;
6788
6789 while (from && count < max_count)
6790 {
6791 rtx tmp;
6792 int new_cost;
6793
6794 /* This code shouldn't have been called if there was a natural barrier
6795 within range. */
6796 if (GET_CODE (from) == BARRIER)
6797 abort ();
6798
6799 /* Count the length of this insn. */
6800 count += get_attr_length (from);
6801
6802 /* If there is a jump table, add its length. */
6803 tmp = is_jump_table (from);
6804 if (tmp != NULL)
6805 {
6806 count += get_jump_table_size (tmp);
6807
6808 /* Jump tables aren't in a basic block, so base the cost on
6809 the dispatch insn. If we select this location, we will
6810 still put the pool after the table. */
6811 new_cost = arm_barrier_cost (from);
6812
6813 if (count < max_count && new_cost <= selected_cost)
6814 {
6815 selected = tmp;
6816 selected_cost = new_cost;
6817 selected_address = fix->address + count;
6818 }
6819
6820 /* Continue after the dispatch table. */
6821 from = NEXT_INSN (tmp);
6822 continue;
6823 }
6824
6825 new_cost = arm_barrier_cost (from);
6826
6827 if (count < max_count && new_cost <= selected_cost)
6828 {
6829 selected = from;
6830 selected_cost = new_cost;
6831 selected_address = fix->address + count;
6832 }
6833
6834 from = NEXT_INSN (from);
6835 }
6836
6837 /* Create a new JUMP_INSN that branches around a barrier. */
6838 from = emit_jump_insn_after (gen_jump (label), selected);
6839 JUMP_LABEL (from) = label;
6840 barrier = emit_barrier_after (from);
6841 emit_label_after (label, barrier);
6842
6843 /* Create a minipool barrier entry for the new barrier. */
c7319d87 6844 new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* new_fix));
d5b7b3ae
RE
6845 new_fix->insn = barrier;
6846 new_fix->address = selected_address;
6847 new_fix->next = fix->next;
6848 fix->next = new_fix;
6849
6850 return new_fix;
6851}
6852
6853/* Record that there is a natural barrier in the insn stream at
6854 ADDRESS. */
949d79eb 6855static void
e32bac5b 6856push_minipool_barrier (rtx insn, HOST_WIDE_INT address)
2b835d68 6857{
c7319d87 6858 Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
ad076f4e 6859
949d79eb
RE
6860 fix->insn = insn;
6861 fix->address = address;
2b835d68 6862
949d79eb
RE
6863 fix->next = NULL;
6864 if (minipool_fix_head != NULL)
6865 minipool_fix_tail->next = fix;
6866 else
6867 minipool_fix_head = fix;
6868
6869 minipool_fix_tail = fix;
6870}
2b835d68 6871
d5b7b3ae
RE
6872/* Record INSN, which will need fixing up to load a value from the
6873 minipool. ADDRESS is the offset of the insn since the start of the
6874 function; LOC is a pointer to the part of the insn which requires
6875 fixing; VALUE is the constant that must be loaded, which is of type
6876 MODE. */
949d79eb 6877static void
e32bac5b
RE
6878push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx *loc,
6879 enum machine_mode mode, rtx value)
949d79eb 6880{
c7319d87 6881 Mfix * fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (* fix));
949d79eb
RE
6882
6883#ifdef AOF_ASSEMBLER
093354e0 6884 /* PIC symbol references need to be converted into offsets into the
949d79eb 6885 based area. */
d5b7b3ae
RE
6886 /* XXX This shouldn't be done here. */
6887 if (flag_pic && GET_CODE (value) == SYMBOL_REF)
949d79eb
RE
6888 value = aof_pic_entry (value);
6889#endif /* AOF_ASSEMBLER */
6890
6891 fix->insn = insn;
6892 fix->address = address;
6893 fix->loc = loc;
6894 fix->mode = mode;
d5b7b3ae 6895 fix->fix_size = MINIPOOL_FIX_SIZE (mode);
949d79eb 6896 fix->value = value;
d5b7b3ae
RE
6897 fix->forwards = get_attr_pool_range (insn);
6898 fix->backwards = get_attr_neg_pool_range (insn);
6899 fix->minipool = NULL;
949d79eb
RE
6900
6901 /* If an insn doesn't have a range defined for it, then it isn't
6902 expecting to be reworked by this code. Better to abort now than
6903 to generate duff assembly code. */
d5b7b3ae 6904 if (fix->forwards == 0 && fix->backwards == 0)
949d79eb
RE
6905 abort ();
6906
5a9335ef
NC
6907 /* With iWMMXt enabled, the pool is aligned to an 8-byte boundary.
6908 So there might be an empty word before the start of the pool.
6909 Hence we reduce the forward range by 4 to allow for this
6910 possibility. */
6911 if (TARGET_REALLY_IWMMXT && fix->fix_size == 8)
6912 fix->forwards -= 4;
6913
d5b7b3ae
RE
6914 if (rtl_dump_file)
6915 {
6916 fprintf (rtl_dump_file,
6917 ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ",
6918 GET_MODE_NAME (mode),
6919 INSN_UID (insn), (unsigned long) address,
6920 -1 * (long)fix->backwards, (long)fix->forwards);
6921 arm_print_value (rtl_dump_file, fix->value);
6922 fprintf (rtl_dump_file, "\n");
6923 }
6924
6354dc9b 6925 /* Add it to the chain of fixes. */
949d79eb 6926 fix->next = NULL;
d5b7b3ae 6927
949d79eb
RE
6928 if (minipool_fix_head != NULL)
6929 minipool_fix_tail->next = fix;
6930 else
6931 minipool_fix_head = fix;
6932
6933 minipool_fix_tail = fix;
6934}
6935
f0375c66
NC
6936/* Scan INSN and note any of its operands that need fixing.
6937 If DO_PUSHES is false we do not actually push any of the fixups
6938 needed. The function returns TRUE is any fixups were needed/pushed.
6939 This is used by arm_memory_load_p() which needs to know about loads
6940 of constants that will be converted into minipool loads. */
f0375c66 6941static bool
e32bac5b 6942note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
949d79eb 6943{
f0375c66 6944 bool result = false;
949d79eb
RE
6945 int opno;
6946
d5b7b3ae 6947 extract_insn (insn);
949d79eb 6948
5895f793 6949 if (!constrain_operands (1))
949d79eb
RE
6950 fatal_insn_not_found (insn);
6951
8c2a5582
RE
6952 if (recog_data.n_alternatives == 0)
6953 return false;
6954
f0375c66 6955 /* Fill in recog_op_alt with information about the constraints of this insn. */
949d79eb
RE
6956 preprocess_constraints ();
6957
1ccbefce 6958 for (opno = 0; opno < recog_data.n_operands; opno++)
949d79eb 6959 {
6354dc9b 6960 /* Things we need to fix can only occur in inputs. */
36ab44c7 6961 if (recog_data.operand_type[opno] != OP_IN)
949d79eb
RE
6962 continue;
6963
6964 /* If this alternative is a memory reference, then any mention
6965 of constants in this alternative is really to fool reload
6966 into allowing us to accept one there. We need to fix them up
6967 now so that we output the right code. */
6968 if (recog_op_alt[opno][which_alternative].memory_ok)
6969 {
1ccbefce 6970 rtx op = recog_data.operand[opno];
949d79eb
RE
6971
6972 if (CONSTANT_P (op))
f0375c66
NC
6973 {
6974 if (do_pushes)
6975 push_minipool_fix (insn, address, recog_data.operand_loc[opno],
6976 recog_data.operand_mode[opno], op);
6977 result = true;
6978 }
d5b7b3ae 6979 else if (GET_CODE (op) == MEM
949d79eb
RE
6980 && GET_CODE (XEXP (op, 0)) == SYMBOL_REF
6981 && CONSTANT_POOL_ADDRESS_P (XEXP (op, 0)))
f0375c66
NC
6982 {
6983 if (do_pushes)
244b1afb
RE
6984 {
6985 rtx cop = avoid_constant_pool_reference (op);
6986
6987 /* Casting the address of something to a mode narrower
6988 than a word can cause avoid_constant_pool_reference()
6989 to return the pool reference itself. That's no good to
6990 us here. Lets just hope that we can use the
6991 constant pool value directly. */
6992 if (op == cop)
c769a35d 6993 cop = get_pool_constant (XEXP (op, 0));
244b1afb
RE
6994
6995 push_minipool_fix (insn, address,
6996 recog_data.operand_loc[opno],
c769a35d 6997 recog_data.operand_mode[opno], cop);
244b1afb 6998 }
f0375c66
NC
6999
7000 result = true;
7001 }
949d79eb 7002 }
2b835d68 7003 }
f0375c66
NC
7004
7005 return result;
2b835d68
RE
7006}
7007
18dbd950
RS
7008/* Gcc puts the pool in the wrong place for ARM, since we can only
7009 load addresses a limited distance around the pc. We do some
7010 special munging to move the constant pool values to the correct
7011 point in the code. */
18dbd950 7012static void
e32bac5b 7013arm_reorg (void)
2b835d68
RE
7014{
7015 rtx insn;
d5b7b3ae
RE
7016 HOST_WIDE_INT address = 0;
7017 Mfix * fix;
ad076f4e 7018
949d79eb 7019 minipool_fix_head = minipool_fix_tail = NULL;
2b835d68 7020
949d79eb
RE
7021 /* The first insn must always be a note, or the code below won't
7022 scan it properly. */
18dbd950
RS
7023 insn = get_insns ();
7024 if (GET_CODE (insn) != NOTE)
949d79eb
RE
7025 abort ();
7026
7027 /* Scan all the insns and record the operands that will need fixing. */
18dbd950 7028 for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn))
2b835d68 7029 {
9b6b54e2 7030 if (TARGET_CIRRUS_FIX_INVALID_INSNS
f0375c66 7031 && (arm_cirrus_insn_p (insn)
9b6b54e2 7032 || GET_CODE (insn) == JUMP_INSN
f0375c66 7033 || arm_memory_load_p (insn)))
9b6b54e2
NC
7034 cirrus_reorg (insn);
7035
949d79eb 7036 if (GET_CODE (insn) == BARRIER)
d5b7b3ae 7037 push_minipool_barrier (insn, address);
f0375c66 7038 else if (INSN_P (insn))
949d79eb
RE
7039 {
7040 rtx table;
7041
f0375c66 7042 note_invalid_constants (insn, address, true);
949d79eb 7043 address += get_attr_length (insn);
d5b7b3ae 7044
949d79eb
RE
7045 /* If the insn is a vector jump, add the size of the table
7046 and skip the table. */
d5b7b3ae 7047 if ((table = is_jump_table (insn)) != NULL)
2b835d68 7048 {
d5b7b3ae 7049 address += get_jump_table_size (table);
949d79eb
RE
7050 insn = table;
7051 }
7052 }
7053 }
332072db 7054
d5b7b3ae
RE
7055 fix = minipool_fix_head;
7056
949d79eb 7057 /* Now scan the fixups and perform the required changes. */
d5b7b3ae 7058 while (fix)
949d79eb 7059 {
d5b7b3ae
RE
7060 Mfix * ftmp;
7061 Mfix * fdel;
7062 Mfix * last_added_fix;
7063 Mfix * last_barrier = NULL;
7064 Mfix * this_fix;
949d79eb
RE
7065
7066 /* Skip any further barriers before the next fix. */
7067 while (fix && GET_CODE (fix->insn) == BARRIER)
7068 fix = fix->next;
7069
d5b7b3ae 7070 /* No more fixes. */
949d79eb
RE
7071 if (fix == NULL)
7072 break;
332072db 7073
d5b7b3ae 7074 last_added_fix = NULL;
2b835d68 7075
d5b7b3ae 7076 for (ftmp = fix; ftmp; ftmp = ftmp->next)
949d79eb 7077 {
949d79eb 7078 if (GET_CODE (ftmp->insn) == BARRIER)
949d79eb 7079 {
d5b7b3ae
RE
7080 if (ftmp->address >= minipool_vector_head->max_address)
7081 break;
2b835d68 7082
d5b7b3ae 7083 last_barrier = ftmp;
2b835d68 7084 }
d5b7b3ae
RE
7085 else if ((ftmp->minipool = add_minipool_forward_ref (ftmp)) == NULL)
7086 break;
7087
7088 last_added_fix = ftmp; /* Keep track of the last fix added. */
2b835d68 7089 }
949d79eb 7090
d5b7b3ae
RE
7091 /* If we found a barrier, drop back to that; any fixes that we
7092 could have reached but come after the barrier will now go in
7093 the next mini-pool. */
949d79eb
RE
7094 if (last_barrier != NULL)
7095 {
d5b7b3ae
RE
7096 /* Reduce the refcount for those fixes that won't go into this
7097 pool after all. */
7098 for (fdel = last_barrier->next;
7099 fdel && fdel != ftmp;
7100 fdel = fdel->next)
7101 {
7102 fdel->minipool->refcount--;
7103 fdel->minipool = NULL;
7104 }
7105
949d79eb
RE
7106 ftmp = last_barrier;
7107 }
7108 else
2bfa88dc 7109 {
d5b7b3ae
RE
7110 /* ftmp is first fix that we can't fit into this pool and
7111 there no natural barriers that we could use. Insert a
7112 new barrier in the code somewhere between the previous
7113 fix and this one, and arrange to jump around it. */
7114 HOST_WIDE_INT max_address;
7115
7116 /* The last item on the list of fixes must be a barrier, so
7117 we can never run off the end of the list of fixes without
7118 last_barrier being set. */
7119 if (ftmp == NULL)
7120 abort ();
7121
7122 max_address = minipool_vector_head->max_address;
2bfa88dc
RE
7123 /* Check that there isn't another fix that is in range that
7124 we couldn't fit into this pool because the pool was
7125 already too large: we need to put the pool before such an
7126 instruction. */
d5b7b3ae
RE
7127 if (ftmp->address < max_address)
7128 max_address = ftmp->address;
7129
7130 last_barrier = create_fix_barrier (last_added_fix, max_address);
7131 }
7132
7133 assign_minipool_offsets (last_barrier);
7134
7135 while (ftmp)
7136 {
7137 if (GET_CODE (ftmp->insn) != BARRIER
7138 && ((ftmp->minipool = add_minipool_backward_ref (ftmp))
7139 == NULL))
7140 break;
2bfa88dc 7141
d5b7b3ae 7142 ftmp = ftmp->next;
2bfa88dc 7143 }
949d79eb
RE
7144
7145 /* Scan over the fixes we have identified for this pool, fixing them
7146 up and adding the constants to the pool itself. */
d5b7b3ae 7147 for (this_fix = fix; this_fix && ftmp != this_fix;
949d79eb
RE
7148 this_fix = this_fix->next)
7149 if (GET_CODE (this_fix->insn) != BARRIER)
7150 {
949d79eb
RE
7151 rtx addr
7152 = plus_constant (gen_rtx_LABEL_REF (VOIDmode,
7153 minipool_vector_label),
d5b7b3ae 7154 this_fix->minipool->offset);
949d79eb
RE
7155 *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr);
7156 }
7157
d5b7b3ae 7158 dump_minipool (last_barrier->insn);
949d79eb 7159 fix = ftmp;
2b835d68 7160 }
4b632bf1 7161
949d79eb
RE
7162 /* From now on we must synthesize any constants that we can't handle
7163 directly. This can happen if the RTL gets split during final
7164 instruction generation. */
4b632bf1 7165 after_arm_reorg = 1;
c7319d87
RE
7166
7167 /* Free the minipool memory. */
7168 obstack_free (&minipool_obstack, minipool_startobj);
2b835d68 7169}
cce8749e
CH
7170\f
7171/* Routines to output assembly language. */
7172
f3bb6135 7173/* If the rtx is the correct value then return the string of the number.
ff9940b0 7174 In this way we can ensure that valid double constants are generated even
6354dc9b 7175 when cross compiling. */
cd2b33d0 7176const char *
e32bac5b 7177fp_immediate_constant (rtx x)
ff9940b0
RE
7178{
7179 REAL_VALUE_TYPE r;
7180 int i;
7181
7182 if (!fpa_consts_inited)
7183 init_fpa_table ();
7184
7185 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
7186 for (i = 0; i < 8; i++)
7187 if (REAL_VALUES_EQUAL (r, values_fpa[i]))
7188 return strings_fpa[i];
f3bb6135 7189
ff9940b0
RE
7190 abort ();
7191}
7192
9997d19d 7193/* As for fp_immediate_constant, but value is passed directly, not in rtx. */
cd2b33d0 7194static const char *
e32bac5b 7195fp_const_from_val (REAL_VALUE_TYPE *r)
9997d19d
RE
7196{
7197 int i;
7198
5895f793 7199 if (!fpa_consts_inited)
9997d19d
RE
7200 init_fpa_table ();
7201
7202 for (i = 0; i < 8; i++)
7203 if (REAL_VALUES_EQUAL (*r, values_fpa[i]))
7204 return strings_fpa[i];
7205
7206 abort ();
7207}
ff9940b0 7208
cce8749e
CH
7209/* Output the operands of a LDM/STM instruction to STREAM.
7210 MASK is the ARM register set mask of which only bits 0-15 are important.
6d3d9133
NC
7211 REG is the base register, either the frame pointer or the stack pointer,
7212 INSTR is the possibly suffixed load or store instruction. */
d5b7b3ae 7213static void
e32bac5b 7214print_multi_reg (FILE *stream, const char *instr, int reg, int mask)
cce8749e
CH
7215{
7216 int i;
7217 int not_first = FALSE;
7218
1d5473cb 7219 fputc ('\t', stream);
dd18ae56 7220 asm_fprintf (stream, instr, reg);
1d5473cb 7221 fputs (", {", stream);
62b10bbc 7222
d5b7b3ae 7223 for (i = 0; i <= LAST_ARM_REGNUM; i++)
cce8749e
CH
7224 if (mask & (1 << i))
7225 {
7226 if (not_first)
7227 fprintf (stream, ", ");
62b10bbc 7228
dd18ae56 7229 asm_fprintf (stream, "%r", i);
cce8749e
CH
7230 not_first = TRUE;
7231 }
f3bb6135 7232
b17fe233
NC
7233 fprintf (stream, "}");
7234
7235 /* Add a ^ character for the 26-bit ABI, but only if we were loading
1ce53769
NC
7236 the PC. Otherwise we would generate an UNPREDICTABLE instruction.
7237 Strictly speaking the instruction would be unpredicatble only if
7238 we were writing back the base register as well, but since we never
7239 want to generate an LDM type 2 instruction (register bank switching)
7240 which is what you get if the PC is not being loaded, we do not need
7241 to check for writeback. */
b17fe233 7242 if (! TARGET_APCS_32
1ce53769 7243 && ((mask & (1 << PC_REGNUM)) != 0))
b17fe233
NC
7244 fprintf (stream, "^");
7245
7246 fprintf (stream, "\n");
f3bb6135 7247}
cce8749e 7248
6354dc9b 7249/* Output a 'call' insn. */
cd2b33d0 7250const char *
e32bac5b 7251output_call (rtx *operands)
cce8749e 7252{
6354dc9b 7253 /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
cce8749e 7254
62b10bbc 7255 if (REGNO (operands[0]) == LR_REGNUM)
cce8749e 7256 {
62b10bbc 7257 operands[0] = gen_rtx_REG (SImode, IP_REGNUM);
1d5473cb 7258 output_asm_insn ("mov%?\t%0, %|lr", operands);
cce8749e 7259 }
62b10bbc 7260
1d5473cb 7261 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
da6558fd 7262
6cfc7210 7263 if (TARGET_INTERWORK)
da6558fd
NC
7264 output_asm_insn ("bx%?\t%0", operands);
7265 else
7266 output_asm_insn ("mov%?\t%|pc, %0", operands);
7267
f3bb6135
RE
7268 return "";
7269}
cce8749e 7270
6354dc9b 7271/* Output a 'call' insn that is a reference in memory. */
cd2b33d0 7272const char *
e32bac5b 7273output_call_mem (rtx *operands)
ff9940b0 7274{
6cfc7210 7275 if (TARGET_INTERWORK)
da6558fd
NC
7276 {
7277 output_asm_insn ("ldr%?\t%|ip, %0", operands);
7278 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
7279 output_asm_insn ("bx%?\t%|ip", operands);
7280 }
6ab5da80
RE
7281 else if (regno_use_in (LR_REGNUM, operands[0]))
7282 {
7283 /* LR is used in the memory address. We load the address in the
7284 first instruction. It's safe to use IP as the target of the
7285 load since the call will kill it anyway. */
7286 output_asm_insn ("ldr%?\t%|ip, %0", operands);
7287 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
7288 output_asm_insn ("mov%?\t%|pc, %|ip", operands);
7289 }
da6558fd
NC
7290 else
7291 {
7292 output_asm_insn ("mov%?\t%|lr, %|pc", operands);
7293 output_asm_insn ("ldr%?\t%|pc, %0", operands);
7294 }
7295
f3bb6135
RE
7296 return "";
7297}
ff9940b0
RE
7298
7299
3b684012
RE
7300/* Output a move from arm registers to an fpa registers.
7301 OPERANDS[0] is an fpa register.
ff9940b0 7302 OPERANDS[1] is the first registers of an arm register pair. */
cd2b33d0 7303const char *
e32bac5b 7304output_mov_long_double_fpa_from_arm (rtx *operands)
ff9940b0
RE
7305{
7306 int arm_reg0 = REGNO (operands[1]);
7307 rtx ops[3];
7308
62b10bbc
NC
7309 if (arm_reg0 == IP_REGNUM)
7310 abort ();
f3bb6135 7311
43cffd11
RE
7312 ops[0] = gen_rtx_REG (SImode, arm_reg0);
7313 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
7314 ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
ff9940b0 7315
1d5473cb
RE
7316 output_asm_insn ("stm%?fd\t%|sp!, {%0, %1, %2}", ops);
7317 output_asm_insn ("ldf%?e\t%0, [%|sp], #12", operands);
62b10bbc 7318
f3bb6135
RE
7319 return "";
7320}
ff9940b0 7321
3b684012 7322/* Output a move from an fpa register to arm registers.
ff9940b0 7323 OPERANDS[0] is the first registers of an arm register pair.
3b684012 7324 OPERANDS[1] is an fpa register. */
cd2b33d0 7325const char *
e32bac5b 7326output_mov_long_double_arm_from_fpa (rtx *operands)
ff9940b0
RE
7327{
7328 int arm_reg0 = REGNO (operands[0]);
7329 rtx ops[3];
7330
62b10bbc
NC
7331 if (arm_reg0 == IP_REGNUM)
7332 abort ();
f3bb6135 7333
43cffd11
RE
7334 ops[0] = gen_rtx_REG (SImode, arm_reg0);
7335 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
7336 ops[2] = gen_rtx_REG (SImode, 2 + arm_reg0);
ff9940b0 7337
1d5473cb
RE
7338 output_asm_insn ("stf%?e\t%1, [%|sp, #-12]!", operands);
7339 output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1, %2}", ops);
f3bb6135
RE
7340 return "";
7341}
ff9940b0
RE
7342
7343/* Output a move from arm registers to arm registers of a long double
7344 OPERANDS[0] is the destination.
7345 OPERANDS[1] is the source. */
cd2b33d0 7346const char *
e32bac5b 7347output_mov_long_double_arm_from_arm (rtx *operands)
ff9940b0 7348{
6354dc9b 7349 /* We have to be careful here because the two might overlap. */
ff9940b0
RE
7350 int dest_start = REGNO (operands[0]);
7351 int src_start = REGNO (operands[1]);
7352 rtx ops[2];
7353 int i;
7354
7355 if (dest_start < src_start)
7356 {
7357 for (i = 0; i < 3; i++)
7358 {
43cffd11
RE
7359 ops[0] = gen_rtx_REG (SImode, dest_start + i);
7360 ops[1] = gen_rtx_REG (SImode, src_start + i);
9997d19d 7361 output_asm_insn ("mov%?\t%0, %1", ops);
ff9940b0
RE
7362 }
7363 }
7364 else
7365 {
7366 for (i = 2; i >= 0; i--)
7367 {
43cffd11
RE
7368 ops[0] = gen_rtx_REG (SImode, dest_start + i);
7369 ops[1] = gen_rtx_REG (SImode, src_start + i);
9997d19d 7370 output_asm_insn ("mov%?\t%0, %1", ops);
ff9940b0
RE
7371 }
7372 }
f3bb6135 7373
ff9940b0
RE
7374 return "";
7375}
7376
7377
3b684012
RE
7378/* Output a move from arm registers to an fpa registers.
7379 OPERANDS[0] is an fpa register.
cce8749e 7380 OPERANDS[1] is the first registers of an arm register pair. */
cd2b33d0 7381const char *
e32bac5b 7382output_mov_double_fpa_from_arm (rtx *operands)
cce8749e
CH
7383{
7384 int arm_reg0 = REGNO (operands[1]);
7385 rtx ops[2];
7386
62b10bbc
NC
7387 if (arm_reg0 == IP_REGNUM)
7388 abort ();
7389
43cffd11
RE
7390 ops[0] = gen_rtx_REG (SImode, arm_reg0);
7391 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
1d5473cb
RE
7392 output_asm_insn ("stm%?fd\t%|sp!, {%0, %1}", ops);
7393 output_asm_insn ("ldf%?d\t%0, [%|sp], #8", operands);
f3bb6135
RE
7394 return "";
7395}
cce8749e 7396
3b684012 7397/* Output a move from an fpa register to arm registers.
cce8749e 7398 OPERANDS[0] is the first registers of an arm register pair.
3b684012 7399 OPERANDS[1] is an fpa register. */
cd2b33d0 7400const char *
e32bac5b 7401output_mov_double_arm_from_fpa (rtx *operands)
cce8749e
CH
7402{
7403 int arm_reg0 = REGNO (operands[0]);
7404 rtx ops[2];
7405
62b10bbc
NC
7406 if (arm_reg0 == IP_REGNUM)
7407 abort ();
f3bb6135 7408
43cffd11
RE
7409 ops[0] = gen_rtx_REG (SImode, arm_reg0);
7410 ops[1] = gen_rtx_REG (SImode, 1 + arm_reg0);
1d5473cb
RE
7411 output_asm_insn ("stf%?d\t%1, [%|sp, #-8]!", operands);
7412 output_asm_insn ("ldm%?fd\t%|sp!, {%0, %1}", ops);
f3bb6135
RE
7413 return "";
7414}
cce8749e
CH
7415
7416/* Output a move between double words.
7417 It must be REG<-REG, REG<-CONST_DOUBLE, REG<-CONST_INT, REG<-MEM
7418 or MEM<-REG and all MEMs must be offsettable addresses. */
cd2b33d0 7419const char *
e32bac5b 7420output_move_double (rtx *operands)
cce8749e
CH
7421{
7422 enum rtx_code code0 = GET_CODE (operands[0]);
7423 enum rtx_code code1 = GET_CODE (operands[1]);
56636818 7424 rtx otherops[3];
cce8749e
CH
7425
7426 if (code0 == REG)
7427 {
7428 int reg0 = REGNO (operands[0]);
7429
43cffd11 7430 otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
aec3cfba 7431
cce8749e
CH
7432 if (code1 == REG)
7433 {
7434 int reg1 = REGNO (operands[1]);
62b10bbc
NC
7435 if (reg1 == IP_REGNUM)
7436 abort ();
f3bb6135 7437
6354dc9b 7438 /* Ensure the second source is not overwritten. */
c1c2bc04 7439 if (reg1 == reg0 + (WORDS_BIG_ENDIAN ? -1 : 1))
6cfc7210 7440 output_asm_insn ("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands);
cce8749e 7441 else
6cfc7210 7442 output_asm_insn ("mov%?\t%R0, %R1\n\tmov%?\t%Q0, %Q1", operands);
cce8749e 7443 }
5a9335ef
NC
7444 else if (code1 == CONST_VECTOR)
7445 {
7446 HOST_WIDE_INT hint = 0;
7447
7448 switch (GET_MODE (operands[1]))
7449 {
7450 case V2SImode:
7451 otherops[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 1)));
7452 operands[1] = GEN_INT (INTVAL (CONST_VECTOR_ELT (operands[1], 0)));
7453 break;
7454
7455 case V4HImode:
7456 if (BYTES_BIG_ENDIAN)
7457 {
7458 hint = INTVAL (CONST_VECTOR_ELT (operands[1], 2));
7459 hint <<= 16;
7460 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
7461 }
7462 else
7463 {
7464 hint = INTVAL (CONST_VECTOR_ELT (operands[1], 3));
7465 hint <<= 16;
7466 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
7467 }
7468
7469 otherops[1] = GEN_INT (hint);
7470 hint = 0;
7471
7472 if (BYTES_BIG_ENDIAN)
7473 {
7474 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
7475 hint <<= 16;
7476 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
7477 }
7478 else
7479 {
7480 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
7481 hint <<= 16;
7482 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
7483 }
7484
7485 operands[1] = GEN_INT (hint);
7486 break;
7487
7488 case V8QImode:
7489 if (BYTES_BIG_ENDIAN)
7490 {
7491 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4));
7492 hint <<= 8;
7493 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5));
7494 hint <<= 8;
7495 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6));
7496 hint <<= 8;
7497 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7));
7498 }
7499 else
7500 {
7501 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 7));
7502 hint <<= 8;
7503 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 6));
7504 hint <<= 8;
7505 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 5));
7506 hint <<= 8;
7507 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 4));
7508 }
7509
7510 otherops[1] = GEN_INT (hint);
7511 hint = 0;
7512
7513 if (BYTES_BIG_ENDIAN)
7514 {
7515 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
7516 hint <<= 8;
7517 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
7518 hint <<= 8;
7519 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
7520 hint <<= 8;
7521 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
7522 }
7523 else
7524 {
7525 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 3));
7526 hint <<= 8;
7527 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 2));
7528 hint <<= 8;
7529 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 1));
7530 hint <<= 8;
7531 hint |= INTVAL (CONST_VECTOR_ELT (operands[1], 0));
7532 }
7533
7534 operands[1] = GEN_INT (hint);
7535 break;
7536
7537 default:
7538 abort ();
7539 }
7540 output_mov_immediate (operands);
7541 output_mov_immediate (otherops);
7542 }
cce8749e
CH
7543 else if (code1 == CONST_DOUBLE)
7544 {
226a5051
RE
7545 if (GET_MODE (operands[1]) == DFmode)
7546 {
b216cd4a 7547 REAL_VALUE_TYPE r;
226a5051 7548 long l[2];
226a5051 7549
b216cd4a
ZW
7550 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
7551 REAL_VALUE_TO_TARGET_DOUBLE (r, l);
d5b7b3ae
RE
7552 otherops[1] = GEN_INT (l[1]);
7553 operands[1] = GEN_INT (l[0]);
226a5051 7554 }
c1c2bc04
RE
7555 else if (GET_MODE (operands[1]) != VOIDmode)
7556 abort ();
7557 else if (WORDS_BIG_ENDIAN)
7558 {
c1c2bc04
RE
7559 otherops[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
7560 operands[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
7561 }
226a5051
RE
7562 else
7563 {
7564 otherops[1] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
7565 operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
7566 }
6cfc7210 7567
c1c2bc04
RE
7568 output_mov_immediate (operands);
7569 output_mov_immediate (otherops);
cce8749e
CH
7570 }
7571 else if (code1 == CONST_INT)
7572 {
56636818
JL
7573#if HOST_BITS_PER_WIDE_INT > 32
7574 /* If HOST_WIDE_INT is more than 32 bits, the intval tells us
7575 what the upper word is. */
7576 if (WORDS_BIG_ENDIAN)
7577 {
7578 otherops[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
7579 operands[1] = GEN_INT (INTVAL (operands[1]) >> 32);
7580 }
7581 else
7582 {
7583 otherops[1] = GEN_INT (INTVAL (operands[1]) >> 32);
7584 operands[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
7585 }
7586#else
6354dc9b 7587 /* Sign extend the intval into the high-order word. */
c1c2bc04
RE
7588 if (WORDS_BIG_ENDIAN)
7589 {
7590 otherops[1] = operands[1];
7591 operands[1] = (INTVAL (operands[1]) < 0
7592 ? constm1_rtx : const0_rtx);
7593 }
ff9940b0 7594 else
c1c2bc04 7595 otherops[1] = INTVAL (operands[1]) < 0 ? constm1_rtx : const0_rtx;
56636818 7596#endif
c1c2bc04
RE
7597 output_mov_immediate (otherops);
7598 output_mov_immediate (operands);
cce8749e
CH
7599 }
7600 else if (code1 == MEM)
7601 {
ff9940b0 7602 switch (GET_CODE (XEXP (operands[1], 0)))
cce8749e 7603 {
ff9940b0 7604 case REG:
9997d19d 7605 output_asm_insn ("ldm%?ia\t%m1, %M0", operands);
ff9940b0 7606 break;
2b835d68 7607
ff9940b0 7608 case PRE_INC:
6354dc9b 7609 abort (); /* Should never happen now. */
ff9940b0 7610 break;
2b835d68 7611
ff9940b0 7612 case PRE_DEC:
2b835d68 7613 output_asm_insn ("ldm%?db\t%m1!, %M0", operands);
ff9940b0 7614 break;
2b835d68 7615
ff9940b0 7616 case POST_INC:
9997d19d 7617 output_asm_insn ("ldm%?ia\t%m1!, %M0", operands);
ff9940b0 7618 break;
2b835d68 7619
ff9940b0 7620 case POST_DEC:
6354dc9b 7621 abort (); /* Should never happen now. */
ff9940b0 7622 break;
2b835d68
RE
7623
7624 case LABEL_REF:
7625 case CONST:
7626 output_asm_insn ("adr%?\t%0, %1", operands);
7627 output_asm_insn ("ldm%?ia\t%0, %M0", operands);
7628 break;
7629
ff9940b0 7630 default:
aec3cfba
NC
7631 if (arm_add_operand (XEXP (XEXP (operands[1], 0), 1),
7632 GET_MODE (XEXP (XEXP (operands[1], 0), 1))))
cce8749e 7633 {
2b835d68
RE
7634 otherops[0] = operands[0];
7635 otherops[1] = XEXP (XEXP (operands[1], 0), 0);
7636 otherops[2] = XEXP (XEXP (operands[1], 0), 1);
1d6e90ac 7637
2b835d68
RE
7638 if (GET_CODE (XEXP (operands[1], 0)) == PLUS)
7639 {
7640 if (GET_CODE (otherops[2]) == CONST_INT)
7641 {
06bea5aa 7642 switch ((int) INTVAL (otherops[2]))
2b835d68
RE
7643 {
7644 case -8:
7645 output_asm_insn ("ldm%?db\t%1, %M0", otherops);
7646 return "";
7647 case -4:
7648 output_asm_insn ("ldm%?da\t%1, %M0", otherops);
7649 return "";
7650 case 4:
7651 output_asm_insn ("ldm%?ib\t%1, %M0", otherops);
7652 return "";
7653 }
1d6e90ac 7654
2b835d68
RE
7655 if (!(const_ok_for_arm (INTVAL (otherops[2]))))
7656 output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
7657 else
7658 output_asm_insn ("add%?\t%0, %1, %2", otherops);
7659 }
7660 else
7661 output_asm_insn ("add%?\t%0, %1, %2", otherops);
7662 }
7663 else
7664 output_asm_insn ("sub%?\t%0, %1, %2", otherops);
6cfc7210 7665
2b835d68
RE
7666 return "ldm%?ia\t%0, %M0";
7667 }
7668 else
7669 {
a4a37b30 7670 otherops[1] = adjust_address (operands[1], SImode, 4);
2b835d68
RE
7671 /* Take care of overlapping base/data reg. */
7672 if (reg_mentioned_p (operands[0], operands[1]))
7673 {
7674 output_asm_insn ("ldr%?\t%0, %1", otherops);
7675 output_asm_insn ("ldr%?\t%0, %1", operands);
7676 }
7677 else
7678 {
7679 output_asm_insn ("ldr%?\t%0, %1", operands);
7680 output_asm_insn ("ldr%?\t%0, %1", otherops);
7681 }
cce8749e
CH
7682 }
7683 }
7684 }
2b835d68 7685 else
6354dc9b 7686 abort (); /* Constraints should prevent this. */
cce8749e
CH
7687 }
7688 else if (code0 == MEM && code1 == REG)
7689 {
62b10bbc
NC
7690 if (REGNO (operands[1]) == IP_REGNUM)
7691 abort ();
2b835d68 7692
ff9940b0
RE
7693 switch (GET_CODE (XEXP (operands[0], 0)))
7694 {
7695 case REG:
9997d19d 7696 output_asm_insn ("stm%?ia\t%m0, %M1", operands);
ff9940b0 7697 break;
2b835d68 7698
ff9940b0 7699 case PRE_INC:
6354dc9b 7700 abort (); /* Should never happen now. */
ff9940b0 7701 break;
2b835d68 7702
ff9940b0 7703 case PRE_DEC:
2b835d68 7704 output_asm_insn ("stm%?db\t%m0!, %M1", operands);
ff9940b0 7705 break;
2b835d68 7706
ff9940b0 7707 case POST_INC:
9997d19d 7708 output_asm_insn ("stm%?ia\t%m0!, %M1", operands);
ff9940b0 7709 break;
2b835d68 7710
ff9940b0 7711 case POST_DEC:
6354dc9b 7712 abort (); /* Should never happen now. */
ff9940b0 7713 break;
2b835d68
RE
7714
7715 case PLUS:
7716 if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
7717 {
06bea5aa 7718 switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
2b835d68
RE
7719 {
7720 case -8:
7721 output_asm_insn ("stm%?db\t%m0, %M1", operands);
7722 return "";
7723
7724 case -4:
7725 output_asm_insn ("stm%?da\t%m0, %M1", operands);
7726 return "";
7727
7728 case 4:
7729 output_asm_insn ("stm%?ib\t%m0, %M1", operands);
7730 return "";
7731 }
7732 }
7733 /* Fall through */
7734
ff9940b0 7735 default:
a4a37b30 7736 otherops[0] = adjust_address (operands[0], SImode, 4);
43cffd11 7737 otherops[1] = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
9997d19d
RE
7738 output_asm_insn ("str%?\t%1, %0", operands);
7739 output_asm_insn ("str%?\t%1, %0", otherops);
cce8749e
CH
7740 }
7741 }
2b835d68 7742 else
1d6e90ac
NC
7743 /* Constraints should prevent this. */
7744 abort ();
cce8749e 7745
9997d19d
RE
7746 return "";
7747}
cce8749e
CH
7748
7749
7750/* Output an arbitrary MOV reg, #n.
7751 OPERANDS[0] is a register. OPERANDS[1] is a const_int. */
cd2b33d0 7752const char *
e32bac5b 7753output_mov_immediate (rtx *operands)
cce8749e 7754{
f3bb6135 7755 HOST_WIDE_INT n = INTVAL (operands[1]);
cce8749e 7756
1d6e90ac 7757 /* Try to use one MOV. */
cce8749e 7758 if (const_ok_for_arm (n))
1d6e90ac 7759 output_asm_insn ("mov%?\t%0, %1", operands);
cce8749e 7760
1d6e90ac
NC
7761 /* Try to use one MVN. */
7762 else if (const_ok_for_arm (~n))
cce8749e 7763 {
f3bb6135 7764 operands[1] = GEN_INT (~n);
9997d19d 7765 output_asm_insn ("mvn%?\t%0, %1", operands);
cce8749e 7766 }
1d6e90ac
NC
7767 else
7768 {
7769 int n_ones = 0;
7770 int i;
cce8749e 7771
1d6e90ac 7772 /* If all else fails, make it out of ORRs or BICs as appropriate. */
5a9335ef 7773 for (i = 0; i < 32; i++)
1d6e90ac 7774 if (n & 1 << i)
5a9335ef 7775 n_ones++;
cce8749e 7776
1d6e90ac
NC
7777 if (n_ones > 16) /* Shorter to use MVN with BIC in this case. */
7778 output_multi_immediate (operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1, ~ n);
7779 else
7780 output_multi_immediate (operands, "mov%?\t%0, %1", "orr%?\t%0, %0, %1", 1, n);
7781 }
f3bb6135
RE
7782
7783 return "";
7784}
cce8749e 7785
1d6e90ac
NC
7786/* Output an ADD r, s, #n where n may be too big for one instruction.
7787 If adding zero to one register, output nothing. */
cd2b33d0 7788const char *
e32bac5b 7789output_add_immediate (rtx *operands)
cce8749e 7790{
f3bb6135 7791 HOST_WIDE_INT n = INTVAL (operands[2]);
cce8749e
CH
7792
7793 if (n != 0 || REGNO (operands[0]) != REGNO (operands[1]))
7794 {
7795 if (n < 0)
7796 output_multi_immediate (operands,
9997d19d
RE
7797 "sub%?\t%0, %1, %2", "sub%?\t%0, %0, %2", 2,
7798 -n);
cce8749e
CH
7799 else
7800 output_multi_immediate (operands,
9997d19d
RE
7801 "add%?\t%0, %1, %2", "add%?\t%0, %0, %2", 2,
7802 n);
cce8749e 7803 }
f3bb6135
RE
7804
7805 return "";
7806}
cce8749e 7807
cce8749e
CH
7808/* Output a multiple immediate operation.
7809 OPERANDS is the vector of operands referred to in the output patterns.
7810 INSTR1 is the output pattern to use for the first constant.
7811 INSTR2 is the output pattern to use for subsequent constants.
7812 IMMED_OP is the index of the constant slot in OPERANDS.
7813 N is the constant value. */
cd2b33d0 7814static const char *
e32bac5b
RE
7815output_multi_immediate (rtx *operands, const char *instr1, const char *instr2,
7816 int immed_op, HOST_WIDE_INT n)
cce8749e 7817{
f3bb6135 7818#if HOST_BITS_PER_WIDE_INT > 32
30cf4896 7819 n &= 0xffffffff;
f3bb6135
RE
7820#endif
7821
cce8749e
CH
7822 if (n == 0)
7823 {
1d6e90ac 7824 /* Quick and easy output. */
cce8749e 7825 operands[immed_op] = const0_rtx;
1d6e90ac 7826 output_asm_insn (instr1, operands);
cce8749e
CH
7827 }
7828 else
7829 {
7830 int i;
cd2b33d0 7831 const char * instr = instr1;
cce8749e 7832
6354dc9b 7833 /* Note that n is never zero here (which would give no output). */
cce8749e
CH
7834 for (i = 0; i < 32; i += 2)
7835 {
7836 if (n & (3 << i))
7837 {
f3bb6135
RE
7838 operands[immed_op] = GEN_INT (n & (255 << i));
7839 output_asm_insn (instr, operands);
cce8749e
CH
7840 instr = instr2;
7841 i += 6;
7842 }
7843 }
7844 }
cd2b33d0 7845
f3bb6135 7846 return "";
9997d19d 7847}
cce8749e 7848
cce8749e
CH
7849/* Return the appropriate ARM instruction for the operation code.
7850 The returned result should not be overwritten. OP is the rtx of the
7851 operation. SHIFT_FIRST_ARG is TRUE if the first argument of the operator
7852 was shifted. */
cd2b33d0 7853const char *
e32bac5b 7854arithmetic_instr (rtx op, int shift_first_arg)
cce8749e 7855{
9997d19d 7856 switch (GET_CODE (op))
cce8749e
CH
7857 {
7858 case PLUS:
f3bb6135
RE
7859 return "add";
7860
cce8749e 7861 case MINUS:
f3bb6135
RE
7862 return shift_first_arg ? "rsb" : "sub";
7863
cce8749e 7864 case IOR:
f3bb6135
RE
7865 return "orr";
7866
cce8749e 7867 case XOR:
f3bb6135
RE
7868 return "eor";
7869
cce8749e 7870 case AND:
f3bb6135
RE
7871 return "and";
7872
cce8749e 7873 default:
f3bb6135 7874 abort ();
cce8749e 7875 }
f3bb6135 7876}
cce8749e 7877
cce8749e
CH
7878/* Ensure valid constant shifts and return the appropriate shift mnemonic
7879 for the operation code. The returned result should not be overwritten.
7880 OP is the rtx code of the shift.
9997d19d 7881 On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
6354dc9b 7882 shift. */
cd2b33d0 7883static const char *
e32bac5b 7884shift_op (rtx op, HOST_WIDE_INT *amountp)
cce8749e 7885{
cd2b33d0 7886 const char * mnem;
e2c671ba 7887 enum rtx_code code = GET_CODE (op);
cce8749e 7888
9997d19d
RE
7889 if (GET_CODE (XEXP (op, 1)) == REG || GET_CODE (XEXP (op, 1)) == SUBREG)
7890 *amountp = -1;
7891 else if (GET_CODE (XEXP (op, 1)) == CONST_INT)
7892 *amountp = INTVAL (XEXP (op, 1));
7893 else
7894 abort ();
7895
e2c671ba 7896 switch (code)
cce8749e
CH
7897 {
7898 case ASHIFT:
7899 mnem = "asl";
7900 break;
f3bb6135 7901
cce8749e
CH
7902 case ASHIFTRT:
7903 mnem = "asr";
cce8749e 7904 break;
f3bb6135 7905
cce8749e
CH
7906 case LSHIFTRT:
7907 mnem = "lsr";
cce8749e 7908 break;
f3bb6135 7909
9997d19d
RE
7910 case ROTATERT:
7911 mnem = "ror";
9997d19d
RE
7912 break;
7913
ff9940b0 7914 case MULT:
e2c671ba
RE
7915 /* We never have to worry about the amount being other than a
7916 power of 2, since this case can never be reloaded from a reg. */
9997d19d
RE
7917 if (*amountp != -1)
7918 *amountp = int_log2 (*amountp);
7919 else
7920 abort ();
f3bb6135
RE
7921 return "asl";
7922
cce8749e 7923 default:
f3bb6135 7924 abort ();
cce8749e
CH
7925 }
7926
e2c671ba
RE
7927 if (*amountp != -1)
7928 {
7929 /* This is not 100% correct, but follows from the desire to merge
7930 multiplication by a power of 2 with the recognizer for a
7931 shift. >=32 is not a valid shift for "asl", so we must try and
7932 output a shift that produces the correct arithmetical result.
ddd5a7c1 7933 Using lsr #32 is identical except for the fact that the carry bit
e2c671ba
RE
7934 is not set correctly if we set the flags; but we never use the
7935 carry bit from such an operation, so we can ignore that. */
7936 if (code == ROTATERT)
1d6e90ac
NC
7937 /* Rotate is just modulo 32. */
7938 *amountp &= 31;
e2c671ba
RE
7939 else if (*amountp != (*amountp & 31))
7940 {
7941 if (code == ASHIFT)
7942 mnem = "lsr";
7943 *amountp = 32;
7944 }
7945
7946 /* Shifts of 0 are no-ops. */
7947 if (*amountp == 0)
7948 return NULL;
7949 }
7950
9997d19d
RE
7951 return mnem;
7952}
cce8749e 7953
6354dc9b 7954/* Obtain the shift from the POWER of two. */
1d6e90ac 7955
18af7313 7956static HOST_WIDE_INT
e32bac5b 7957int_log2 (HOST_WIDE_INT power)
cce8749e 7958{
f3bb6135 7959 HOST_WIDE_INT shift = 0;
cce8749e 7960
30cf4896 7961 while ((((HOST_WIDE_INT) 1 << shift) & power) == 0)
cce8749e
CH
7962 {
7963 if (shift > 31)
f3bb6135 7964 abort ();
e32bac5b 7965 shift++;
cce8749e 7966 }
f3bb6135
RE
7967
7968 return shift;
7969}
cce8749e 7970
cce8749e
CH
7971/* Output a .ascii pseudo-op, keeping track of lengths. This is because
7972 /bin/as is horribly restrictive. */
6cfc7210 7973#define MAX_ASCII_LEN 51
cce8749e
CH
7974
7975void
e32bac5b 7976output_ascii_pseudo_op (FILE *stream, const unsigned char *p, int len)
cce8749e
CH
7977{
7978 int i;
6cfc7210 7979 int len_so_far = 0;
cce8749e 7980
6cfc7210
NC
7981 fputs ("\t.ascii\t\"", stream);
7982
cce8749e
CH
7983 for (i = 0; i < len; i++)
7984 {
1d6e90ac 7985 int c = p[i];
cce8749e 7986
6cfc7210 7987 if (len_so_far >= MAX_ASCII_LEN)
cce8749e 7988 {
6cfc7210 7989 fputs ("\"\n\t.ascii\t\"", stream);
cce8749e 7990 len_so_far = 0;
cce8749e
CH
7991 }
7992
6cfc7210 7993 switch (c)
cce8749e 7994 {
6cfc7210
NC
7995 case TARGET_TAB:
7996 fputs ("\\t", stream);
7997 len_so_far += 2;
7998 break;
7999
8000 case TARGET_FF:
8001 fputs ("\\f", stream);
8002 len_so_far += 2;
8003 break;
8004
8005 case TARGET_BS:
8006 fputs ("\\b", stream);
8007 len_so_far += 2;
8008 break;
8009
8010 case TARGET_CR:
8011 fputs ("\\r", stream);
8012 len_so_far += 2;
8013 break;
8014
8015 case TARGET_NEWLINE:
8016 fputs ("\\n", stream);
8017 c = p [i + 1];
8018 if ((c >= ' ' && c <= '~')
8019 || c == TARGET_TAB)
8020 /* This is a good place for a line break. */
8021 len_so_far = MAX_ASCII_LEN;
8022 else
8023 len_so_far += 2;
8024 break;
8025
8026 case '\"':
8027 case '\\':
8028 putc ('\\', stream);
5895f793 8029 len_so_far++;
6cfc7210 8030 /* drop through. */
f3bb6135 8031
6cfc7210
NC
8032 default:
8033 if (c >= ' ' && c <= '~')
8034 {
8035 putc (c, stream);
5895f793 8036 len_so_far++;
6cfc7210
NC
8037 }
8038 else
8039 {
8040 fprintf (stream, "\\%03o", c);
8041 len_so_far += 4;
8042 }
8043 break;
cce8749e 8044 }
cce8749e 8045 }
f3bb6135 8046
cce8749e 8047 fputs ("\"\n", stream);
f3bb6135 8048}
cce8749e 8049\f
121308d4
NC
8050/* Compute the register sabe mask for registers 0 through 12
8051 inclusive. This code is used by both arm_compute_save_reg_mask
8052 and arm_compute_initial_elimination_offset. */
6d3d9133 8053static unsigned long
e32bac5b 8054arm_compute_save_reg0_reg12_mask (void)
6d3d9133 8055{
121308d4 8056 unsigned long func_type = arm_current_func_type ();
6d3d9133
NC
8057 unsigned int save_reg_mask = 0;
8058 unsigned int reg;
6d3d9133 8059
7b8b8ade 8060 if (IS_INTERRUPT (func_type))
6d3d9133 8061 {
7b8b8ade 8062 unsigned int max_reg;
7b8b8ade
NC
8063 /* Interrupt functions must not corrupt any registers,
8064 even call clobbered ones. If this is a leaf function
8065 we can just examine the registers used by the RTL, but
8066 otherwise we have to assume that whatever function is
8067 called might clobber anything, and so we have to save
8068 all the call-clobbered registers as well. */
8069 if (ARM_FUNC_TYPE (func_type) == ARM_FT_FIQ)
8070 /* FIQ handlers have registers r8 - r12 banked, so
8071 we only need to check r0 - r7, Normal ISRs only
121308d4 8072 bank r14 and r15, so we must check up to r12.
7b8b8ade
NC
8073 r13 is the stack pointer which is always preserved,
8074 so we do not need to consider it here. */
8075 max_reg = 7;
8076 else
8077 max_reg = 12;
8078
8079 for (reg = 0; reg <= max_reg; reg++)
8080 if (regs_ever_live[reg]
8081 || (! current_function_is_leaf && call_used_regs [reg]))
6d3d9133
NC
8082 save_reg_mask |= (1 << reg);
8083 }
8084 else
8085 {
8086 /* In the normal case we only need to save those registers
8087 which are call saved and which are used by this function. */
8088 for (reg = 0; reg <= 10; reg++)
8089 if (regs_ever_live[reg] && ! call_used_regs [reg])
8090 save_reg_mask |= (1 << reg);
8091
8092 /* Handle the frame pointer as a special case. */
8093 if (! TARGET_APCS_FRAME
8094 && ! frame_pointer_needed
8095 && regs_ever_live[HARD_FRAME_POINTER_REGNUM]
8096 && ! call_used_regs[HARD_FRAME_POINTER_REGNUM])
8097 save_reg_mask |= 1 << HARD_FRAME_POINTER_REGNUM;
8098
8099 /* If we aren't loading the PIC register,
8100 don't stack it even though it may be live. */
8101 if (flag_pic
8102 && ! TARGET_SINGLE_PIC_BASE
8103 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
8104 save_reg_mask |= 1 << PIC_OFFSET_TABLE_REGNUM;
8105 }
8106
121308d4
NC
8107 return save_reg_mask;
8108}
8109
8110/* Compute a bit mask of which registers need to be
8111 saved on the stack for the current function. */
8112
8113static unsigned long
e32bac5b 8114arm_compute_save_reg_mask (void)
121308d4
NC
8115{
8116 unsigned int save_reg_mask = 0;
8117 unsigned long func_type = arm_current_func_type ();
8118
8119 if (IS_NAKED (func_type))
8120 /* This should never really happen. */
8121 return 0;
8122
8123 /* If we are creating a stack frame, then we must save the frame pointer,
8124 IP (which will hold the old stack pointer), LR and the PC. */
8125 if (frame_pointer_needed)
8126 save_reg_mask |=
8127 (1 << ARM_HARD_FRAME_POINTER_REGNUM)
8128 | (1 << IP_REGNUM)
8129 | (1 << LR_REGNUM)
8130 | (1 << PC_REGNUM);
8131
8132 /* Volatile functions do not return, so there
8133 is no need to save any other registers. */
8134 if (IS_VOLATILE (func_type))
8135 return save_reg_mask;
8136
8137 save_reg_mask |= arm_compute_save_reg0_reg12_mask ();
8138
6d3d9133
NC
8139 /* Decide if we need to save the link register.
8140 Interrupt routines have their own banked link register,
8141 so they never need to save it.
1768c26f 8142 Otherwise if we do not use the link register we do not need to save
6d3d9133
NC
8143 it. If we are pushing other registers onto the stack however, we
8144 can save an instruction in the epilogue by pushing the link register
8145 now and then popping it back into the PC. This incurs extra memory
72ac76be 8146 accesses though, so we only do it when optimizing for size, and only
6d3d9133 8147 if we know that we will not need a fancy return sequence. */
3a7731fd 8148 if (regs_ever_live [LR_REGNUM]
6d3d9133
NC
8149 || (save_reg_mask
8150 && optimize_size
3a7731fd 8151 && ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL))
6d3d9133
NC
8152 save_reg_mask |= 1 << LR_REGNUM;
8153
6f7ebcbb
NC
8154 if (cfun->machine->lr_save_eliminated)
8155 save_reg_mask &= ~ (1 << LR_REGNUM);
8156
5a9335ef
NC
8157 if (TARGET_REALLY_IWMMXT
8158 && ((bit_count (save_reg_mask)
8159 + ARM_NUM_INTS (current_function_pretend_args_size)) % 2) != 0)
8160 {
8161 unsigned int reg;
8162
8163 /* The total number of registers that are going to be pushed
8164 onto the stack is odd. We need to ensure that the stack
8165 is 64-bit aligned before we start to save iWMMXt registers,
8166 and also before we start to create locals. (A local variable
8167 might be a double or long long which we will load/store using
8168 an iWMMXt instruction). Therefore we need to push another
8169 ARM register, so that the stack will be 64-bit aligned. We
8170 try to avoid using the arg registers (r0 -r3) as they might be
8171 used to pass values in a tail call. */
8172 for (reg = 4; reg <= 12; reg++)
8173 if ((save_reg_mask & (1 << reg)) == 0)
8174 break;
8175
8176 if (reg <= 12)
8177 save_reg_mask |= (1 << reg);
8178 else
8179 {
8180 cfun->machine->sibcall_blocked = 1;
8181 save_reg_mask |= (1 << 3);
8182 }
8183 }
8184
6d3d9133
NC
8185 return save_reg_mask;
8186}
8187
699a4925 8188/* Generate a function exit sequence. If REALLY_RETURN is false, then do
6d3d9133 8189 everything bar the final return instruction. */
cd2b33d0 8190const char *
e32bac5b 8191output_return_instruction (rtx operand, int really_return, int reverse)
ff9940b0 8192{
6d3d9133 8193 char conditional[10];
ff9940b0 8194 char instr[100];
6d3d9133
NC
8195 int reg;
8196 unsigned long live_regs_mask;
8197 unsigned long func_type;
e26053d1 8198
6d3d9133 8199 func_type = arm_current_func_type ();
e2c671ba 8200
6d3d9133 8201 if (IS_NAKED (func_type))
d5b7b3ae 8202 return "";
6d3d9133
NC
8203
8204 if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
e2c671ba 8205 {
699a4925
RE
8206 /* If this function was declared non-returning, and we have
8207 found a tail call, then we have to trust that the called
8208 function won't return. */
3a5a4282
PB
8209 if (really_return)
8210 {
8211 rtx ops[2];
8212
8213 /* Otherwise, trap an attempted return by aborting. */
8214 ops[0] = operand;
8215 ops[1] = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)"
8216 : "abort");
8217 assemble_external_libcall (ops[1]);
8218 output_asm_insn (reverse ? "bl%D0\t%a1" : "bl%d0\t%a1", ops);
8219 }
8220
e2c671ba
RE
8221 return "";
8222 }
6d3d9133 8223
5895f793 8224 if (current_function_calls_alloca && !really_return)
62b10bbc 8225 abort ();
ff9940b0 8226
c414f8a9 8227 sprintf (conditional, "%%?%%%c0", reverse ? 'D' : 'd');
d5b7b3ae 8228
6d3d9133 8229 return_used_this_function = 1;
ff9940b0 8230
6d3d9133 8231 live_regs_mask = arm_compute_save_reg_mask ();
ff9940b0 8232
1768c26f 8233 if (live_regs_mask)
6d3d9133 8234 {
1768c26f
PB
8235 const char * return_reg;
8236
8237 /* If we do not have any special requirements for function exit
8238 (eg interworking, or ISR) then we can load the return address
8239 directly into the PC. Otherwise we must load it into LR. */
8240 if (really_return
1768c26f
PB
8241 && ! TARGET_INTERWORK)
8242 return_reg = reg_names[PC_REGNUM];
6d3d9133 8243 else
1768c26f
PB
8244 return_reg = reg_names[LR_REGNUM];
8245
6d3d9133
NC
8246 if ((live_regs_mask & (1 << IP_REGNUM)) == (1 << IP_REGNUM))
8247 /* There are two possible reasons for the IP register being saved.
8248 Either a stack frame was created, in which case IP contains the
8249 old stack pointer, or an ISR routine corrupted it. If this in an
8250 ISR routine then just restore IP, otherwise restore IP into SP. */
8251 if (! IS_INTERRUPT (func_type))
8252 {
8253 live_regs_mask &= ~ (1 << IP_REGNUM);
8254 live_regs_mask |= (1 << SP_REGNUM);
8255 }
f3bb6135 8256
3a7731fd
PB
8257 /* On some ARM architectures it is faster to use LDR rather than
8258 LDM to load a single register. On other architectures, the
8259 cost is the same. In 26 bit mode, or for exception handlers,
8260 we have to use LDM to load the PC so that the CPSR is also
8261 restored. */
8262 for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
6d3d9133 8263 {
3a7731fd
PB
8264 if (live_regs_mask == (unsigned int)(1 << reg))
8265 break;
8266 }
8267 if (reg <= LAST_ARM_REGNUM
8268 && (reg != LR_REGNUM
8269 || ! really_return
8270 || (TARGET_APCS_32 && ! IS_INTERRUPT (func_type))))
8271 {
8272 sprintf (instr, "ldr%s\t%%|%s, [%%|sp], #4", conditional,
8273 (reg == LR_REGNUM) ? return_reg : reg_names[reg]);
6d3d9133 8274 }
ff9940b0 8275 else
1d5473cb 8276 {
1768c26f
PB
8277 char *p;
8278 int first = 1;
6d3d9133 8279
699a4925
RE
8280 /* Generate the load multiple instruction to restore the
8281 registers. Note we can get here, even if
8282 frame_pointer_needed is true, but only if sp already
8283 points to the base of the saved core registers. */
8284 if (live_regs_mask & (1 << SP_REGNUM))
a72d4945
RE
8285 {
8286 unsigned HOST_WIDE_INT stack_adjust =
8287 arm_get_frame_size () + current_function_outgoing_args_size;
8288
8289 if (stack_adjust != 0 && stack_adjust != 4)
8290 abort ();
8291
8292 if (stack_adjust && arm_arch5)
8293 sprintf (instr, "ldm%sib\t%%|sp, {", conditional);
8294 else
8295 {
8296 /* If we can't use ldmib (SA110 bug), then try to pop r3
8297 instead. */
8298 if (stack_adjust)
8299 live_regs_mask |= 1 << 3;
8300 sprintf (instr, "ldm%sfd\t%%|sp, {", conditional);
8301 }
8302 }
da6558fd 8303 else
1768c26f
PB
8304 sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional);
8305
8306 p = instr + strlen (instr);
6d3d9133 8307
1768c26f
PB
8308 for (reg = 0; reg <= SP_REGNUM; reg++)
8309 if (live_regs_mask & (1 << reg))
8310 {
8311 int l = strlen (reg_names[reg]);
8312
8313 if (first)
8314 first = 0;
8315 else
8316 {
8317 memcpy (p, ", ", 2);
8318 p += 2;
8319 }
8320
8321 memcpy (p, "%|", 2);
8322 memcpy (p + 2, reg_names[reg], l);
8323 p += l + 2;
8324 }
8325
8326 if (live_regs_mask & (1 << LR_REGNUM))
8327 {
b17fe233
NC
8328 sprintf (p, "%s%%|%s}", first ? "" : ", ", return_reg);
8329 /* Decide if we need to add the ^ symbol to the end of the
8330 register list. This causes the saved condition codes
8331 register to be copied into the current condition codes
8332 register. We do the copy if we are conforming to the 32-bit
8333 ABI and this is an interrupt function, or if we are
8334 conforming to the 26-bit ABI. There is a special case for
8335 the 26-bit ABI however, which is if we are writing back the
8336 stack pointer but not loading the PC. In this case adding
8337 the ^ symbol would create a type 2 LDM instruction, where
8338 writeback is UNPREDICTABLE. We are safe in leaving the ^
8339 character off in this case however, since the actual return
8340 instruction will be a MOVS which will restore the CPSR. */
8341 if ((TARGET_APCS_32 && IS_INTERRUPT (func_type))
13eedc5a 8342 || (! TARGET_APCS_32 && really_return))
b17fe233 8343 strcat (p, "^");
1768c26f
PB
8344 }
8345 else
8346 strcpy (p, "}");
1d5473cb 8347 }
da6558fd 8348
1768c26f
PB
8349 output_asm_insn (instr, & operand);
8350
3a7731fd
PB
8351 /* See if we need to generate an extra instruction to
8352 perform the actual function return. */
8353 if (really_return
8354 && func_type != ARM_FT_INTERWORKED
8355 && (live_regs_mask & (1 << LR_REGNUM)) != 0)
da6558fd 8356 {
3a7731fd
PB
8357 /* The return has already been handled
8358 by loading the LR into the PC. */
8359 really_return = 0;
da6558fd 8360 }
ff9940b0 8361 }
e26053d1 8362
1768c26f 8363 if (really_return)
ff9940b0 8364 {
6d3d9133
NC
8365 switch ((int) ARM_FUNC_TYPE (func_type))
8366 {
8367 case ARM_FT_ISR:
8368 case ARM_FT_FIQ:
8369 sprintf (instr, "sub%ss\t%%|pc, %%|lr, #4", conditional);
8370 break;
8371
8372 case ARM_FT_INTERWORKED:
8373 sprintf (instr, "bx%s\t%%|lr", conditional);
8374 break;
8375
8376 case ARM_FT_EXCEPTION:
8377 sprintf (instr, "mov%ss\t%%|pc, %%|lr", conditional);
8378 break;
8379
8380 default:
1768c26f
PB
8381 /* ARMv5 implementations always provide BX, so interworking
8382 is the default unless APCS-26 is in use. */
8383 if ((insn_flags & FL_ARCH5) != 0 && TARGET_APCS_32)
8384 sprintf (instr, "bx%s\t%%|lr", conditional);
8385 else
8386 sprintf (instr, "mov%s%s\t%%|pc, %%|lr",
8387 conditional, TARGET_APCS_32 ? "" : "s");
6d3d9133
NC
8388 break;
8389 }
1768c26f
PB
8390
8391 output_asm_insn (instr, & operand);
ff9940b0 8392 }
f3bb6135 8393
ff9940b0
RE
8394 return "";
8395}
8396
ef179a26
NC
8397/* Write the function name into the code section, directly preceding
8398 the function prologue.
8399
8400 Code will be output similar to this:
8401 t0
8402 .ascii "arm_poke_function_name", 0
8403 .align
8404 t1
8405 .word 0xff000000 + (t1 - t0)
8406 arm_poke_function_name
8407 mov ip, sp
8408 stmfd sp!, {fp, ip, lr, pc}
8409 sub fp, ip, #4
8410
8411 When performing a stack backtrace, code can inspect the value
8412 of 'pc' stored at 'fp' + 0. If the trace function then looks
8413 at location pc - 12 and the top 8 bits are set, then we know
8414 that there is a function name embedded immediately preceding this
8415 location and has length ((pc[-3]) & 0xff000000).
8416
8417 We assume that pc is declared as a pointer to an unsigned long.
8418
8419 It is of no benefit to output the function name if we are assembling
8420 a leaf function. These function types will not contain a stack
8421 backtrace structure, therefore it is not possible to determine the
8422 function name. */
ef179a26 8423void
e32bac5b 8424arm_poke_function_name (FILE *stream, const char *name)
ef179a26
NC
8425{
8426 unsigned long alignlength;
8427 unsigned long length;
8428 rtx x;
8429
d5b7b3ae 8430 length = strlen (name) + 1;
0c2ca901 8431 alignlength = ROUND_UP_WORD (length);
ef179a26 8432
949d79eb 8433 ASM_OUTPUT_ASCII (stream, name, length);
ef179a26 8434 ASM_OUTPUT_ALIGN (stream, 2);
30cf4896 8435 x = GEN_INT ((unsigned HOST_WIDE_INT) 0xff000000 + alignlength);
301d03af 8436 assemble_aligned_integer (UNITS_PER_WORD, x);
ef179a26
NC
8437}
8438
6d3d9133
NC
8439/* Place some comments into the assembler stream
8440 describing the current function. */
08c148a8 8441static void
e32bac5b 8442arm_output_function_prologue (FILE *f, HOST_WIDE_INT frame_size)
cce8749e 8443{
6d3d9133 8444 unsigned long func_type;
08c148a8
NB
8445
8446 if (!TARGET_ARM)
8447 {
8448 thumb_output_function_prologue (f, frame_size);
8449 return;
8450 }
6d3d9133
NC
8451
8452 /* Sanity check. */
abaa26e5 8453 if (arm_ccfsm_state || arm_target_insn)
6d3d9133 8454 abort ();
31fdb4d5 8455
6d3d9133
NC
8456 func_type = arm_current_func_type ();
8457
8458 switch ((int) ARM_FUNC_TYPE (func_type))
8459 {
8460 default:
8461 case ARM_FT_NORMAL:
8462 break;
8463 case ARM_FT_INTERWORKED:
8464 asm_fprintf (f, "\t%@ Function supports interworking.\n");
8465 break;
8466 case ARM_FT_EXCEPTION_HANDLER:
8467 asm_fprintf (f, "\t%@ C++ Exception Handler.\n");
8468 break;
8469 case ARM_FT_ISR:
8470 asm_fprintf (f, "\t%@ Interrupt Service Routine.\n");
8471 break;
8472 case ARM_FT_FIQ:
8473 asm_fprintf (f, "\t%@ Fast Interrupt Service Routine.\n");
8474 break;
8475 case ARM_FT_EXCEPTION:
8476 asm_fprintf (f, "\t%@ ARM Exception Handler.\n");
8477 break;
8478 }
ff9940b0 8479
6d3d9133
NC
8480 if (IS_NAKED (func_type))
8481 asm_fprintf (f, "\t%@ Naked Function: prologue and epilogue provided by programmer.\n");
8482
8483 if (IS_VOLATILE (func_type))
8484 asm_fprintf (f, "\t%@ Volatile: function does not return.\n");
8485
8486 if (IS_NESTED (func_type))
8487 asm_fprintf (f, "\t%@ Nested: function declared inside another function.\n");
8488
c53dddc2 8489 asm_fprintf (f, "\t%@ args = %d, pretend = %d, frame = %wd\n",
dd18ae56
NC
8490 current_function_args_size,
8491 current_function_pretend_args_size, frame_size);
6d3d9133 8492
3cb66fd7 8493 asm_fprintf (f, "\t%@ frame_needed = %d, uses_anonymous_args = %d\n",
dd18ae56 8494 frame_pointer_needed,
3cb66fd7 8495 cfun->machine->uses_anonymous_args);
cce8749e 8496
6f7ebcbb
NC
8497 if (cfun->machine->lr_save_eliminated)
8498 asm_fprintf (f, "\t%@ link register save eliminated.\n");
8499
32de079a
RE
8500#ifdef AOF_ASSEMBLER
8501 if (flag_pic)
dd18ae56 8502 asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, PIC_OFFSET_TABLE_REGNUM);
32de079a 8503#endif
6d3d9133
NC
8504
8505 return_used_this_function = 0;
f3bb6135 8506}
cce8749e 8507
cd2b33d0 8508const char *
a72d4945 8509arm_output_epilogue (rtx sibling)
cce8749e 8510{
949d79eb 8511 int reg;
6f7ebcbb 8512 unsigned long saved_regs_mask;
6d3d9133 8513 unsigned long func_type;
c882c7ac
RE
8514 /* Floats_offset is the offset from the "virtual" frame. In an APCS
8515 frame that is $fp + 4 for a non-variadic function. */
8516 int floats_offset = 0;
cce8749e 8517 rtx operands[3];
0977774b 8518 int frame_size = arm_get_frame_size ();
d5b7b3ae 8519 FILE * f = asm_out_file;
6d3d9133 8520 rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
5a9335ef 8521 unsigned int lrm_count = 0;
a72d4945 8522 int really_return = (sibling == NULL);
cce8749e 8523
6d3d9133
NC
8524 /* If we have already generated the return instruction
8525 then it is futile to generate anything else. */
a72d4945 8526 if (use_return_insn (FALSE, sibling) && return_used_this_function)
949d79eb 8527 return "";
cce8749e 8528
6d3d9133 8529 func_type = arm_current_func_type ();
d5b7b3ae 8530
6d3d9133
NC
8531 if (IS_NAKED (func_type))
8532 /* Naked functions don't have epilogues. */
8533 return "";
0616531f 8534
6d3d9133 8535 if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN)
e2c671ba 8536 {
86efdc8e 8537 rtx op;
6d3d9133
NC
8538
8539 /* A volatile function should never return. Call abort. */
ed0e6530 8540 op = gen_rtx_SYMBOL_REF (Pmode, NEED_PLT_RELOC ? "abort(PLT)" : "abort");
2b835d68 8541 assemble_external_libcall (op);
e2c671ba 8542 output_asm_insn ("bl\t%a0", &op);
6d3d9133 8543
949d79eb 8544 return "";
e2c671ba
RE
8545 }
8546
6d3d9133
NC
8547 if (ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER
8548 && ! really_return)
8549 /* If we are throwing an exception, then we really must
8550 be doing a return, so we can't tail-call. */
8551 abort ();
8552
6f7ebcbb 8553 saved_regs_mask = arm_compute_save_reg_mask ();
5a9335ef
NC
8554
8555 if (TARGET_IWMMXT)
8556 lrm_count = bit_count (saved_regs_mask);
8557
c882c7ac
RE
8558 /* XXX We should adjust floats_offset for any anonymous args, and then
8559 re-adjust vfp_offset below to compensate. */
8560
6d3d9133 8561 /* Compute how far away the floats will be. */
5a9335ef 8562 for (reg = 0; reg <= LAST_ARM_REGNUM; reg++)
6f7ebcbb 8563 if (saved_regs_mask & (1 << reg))
6ed30148 8564 floats_offset += 4;
6d3d9133 8565
ff9940b0 8566 if (frame_pointer_needed)
cce8749e 8567 {
c882c7ac
RE
8568 int vfp_offset = 4;
8569
29ad9694 8570 if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
b111229a 8571 {
d5b7b3ae 8572 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
5895f793 8573 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
8574 {
8575 floats_offset += 12;
dd18ae56 8576 asm_fprintf (f, "\tldfe\t%r, [%r, #-%d]\n",
c882c7ac 8577 reg, FP_REGNUM, floats_offset - vfp_offset);
b111229a
RE
8578 }
8579 }
8580 else
8581 {
d5b7b3ae 8582 int start_reg = LAST_ARM_FP_REGNUM;
b111229a 8583
d5b7b3ae 8584 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
b111229a 8585 {
5895f793 8586 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
8587 {
8588 floats_offset += 12;
6cfc7210 8589
6354dc9b 8590 /* We can't unstack more than four registers at once. */
b111229a
RE
8591 if (start_reg - reg == 3)
8592 {
dd18ae56 8593 asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
c882c7ac 8594 reg, FP_REGNUM, floats_offset - vfp_offset);
b111229a
RE
8595 start_reg = reg - 1;
8596 }
8597 }
8598 else
8599 {
8600 if (reg != start_reg)
dd18ae56
NC
8601 asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
8602 reg + 1, start_reg - reg,
c882c7ac 8603 FP_REGNUM, floats_offset - vfp_offset);
b111229a
RE
8604 start_reg = reg - 1;
8605 }
8606 }
8607
8608 /* Just in case the last register checked also needs unstacking. */
8609 if (reg != start_reg)
dd18ae56
NC
8610 asm_fprintf (f, "\tlfm\t%r, %d, [%r, #-%d]\n",
8611 reg + 1, start_reg - reg,
c882c7ac 8612 FP_REGNUM, floats_offset - vfp_offset);
b111229a 8613 }
6d3d9133 8614
5a9335ef
NC
8615 if (TARGET_IWMMXT)
8616 {
8617 /* The frame pointer is guaranteed to be non-double-word aligned.
8618 This is because it is set to (old_stack_pointer - 4) and the
8619 old_stack_pointer was double word aligned. Thus the offset to
8620 the iWMMXt registers to be loaded must also be non-double-word
8621 sized, so that the resultant address *is* double-word aligned.
8622 We can ignore floats_offset since that was already included in
8623 the live_regs_mask. */
8624 lrm_count += (lrm_count % 2 ? 2 : 1);
8625
8626 for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
8627 if (regs_ever_live[reg] && !call_used_regs[reg])
8628 {
8629 asm_fprintf (f, "\twldrd\t%r, [%r, #-%d]\n",
8630 reg, FP_REGNUM, lrm_count * 4);
8631 lrm_count += 2;
8632 }
8633 }
8634
6f7ebcbb 8635 /* saved_regs_mask should contain the IP, which at the time of stack
6d3d9133
NC
8636 frame generation actually contains the old stack pointer. So a
8637 quick way to unwind the stack is just pop the IP register directly
8638 into the stack pointer. */
6f7ebcbb 8639 if ((saved_regs_mask & (1 << IP_REGNUM)) == 0)
6d3d9133 8640 abort ();
6f7ebcbb
NC
8641 saved_regs_mask &= ~ (1 << IP_REGNUM);
8642 saved_regs_mask |= (1 << SP_REGNUM);
6d3d9133 8643
6f7ebcbb 8644 /* There are two registers left in saved_regs_mask - LR and PC. We
6d3d9133
NC
8645 only need to restore the LR register (the return address), but to
8646 save time we can load it directly into the PC, unless we need a
8647 special function exit sequence, or we are not really returning. */
8648 if (really_return && ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL)
8649 /* Delete the LR from the register mask, so that the LR on
8650 the stack is loaded into the PC in the register mask. */
6f7ebcbb 8651 saved_regs_mask &= ~ (1 << LR_REGNUM);
b111229a 8652 else
6f7ebcbb 8653 saved_regs_mask &= ~ (1 << PC_REGNUM);
efc2515b
RE
8654
8655 /* We must use SP as the base register, because SP is one of the
8656 registers being restored. If an interrupt or page fault
8657 happens in the ldm instruction, the SP might or might not
8658 have been restored. That would be bad, as then SP will no
8659 longer indicate the safe area of stack, and we can get stack
8660 corruption. Using SP as the base register means that it will
8661 be reset correctly to the original value, should an interrupt
699a4925
RE
8662 occur. If the stack pointer already points at the right
8663 place, then omit the subtraction. */
8664 if (((frame_size + current_function_outgoing_args_size + floats_offset)
8665 != 4 * (1 + (int) bit_count (saved_regs_mask)))
8666 || current_function_calls_alloca)
8667 asm_fprintf (f, "\tsub\t%r, %r, #%d\n", SP_REGNUM, FP_REGNUM,
8668 4 * bit_count (saved_regs_mask));
efc2515b 8669 print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
7b8b8ade
NC
8670
8671 if (IS_INTERRUPT (func_type))
8672 /* Interrupt handlers will have pushed the
8673 IP onto the stack, so restore it now. */
f55d7103 8674 print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, 1 << IP_REGNUM);
cce8749e
CH
8675 }
8676 else
8677 {
d2288d8d 8678 /* Restore stack pointer if necessary. */
56636818 8679 if (frame_size + current_function_outgoing_args_size != 0)
d2288d8d
TG
8680 {
8681 operands[0] = operands[1] = stack_pointer_rtx;
56636818
JL
8682 operands[2] = GEN_INT (frame_size
8683 + current_function_outgoing_args_size);
d2288d8d
TG
8684 output_add_immediate (operands);
8685 }
8686
29ad9694 8687 if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
b111229a 8688 {
d5b7b3ae 8689 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
5895f793 8690 if (regs_ever_live[reg] && !call_used_regs[reg])
dd18ae56
NC
8691 asm_fprintf (f, "\tldfe\t%r, [%r], #12\n",
8692 reg, SP_REGNUM);
b111229a
RE
8693 }
8694 else
8695 {
d5b7b3ae 8696 int start_reg = FIRST_ARM_FP_REGNUM;
b111229a 8697
d5b7b3ae 8698 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
b111229a 8699 {
5895f793 8700 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
8701 {
8702 if (reg - start_reg == 3)
8703 {
dd18ae56
NC
8704 asm_fprintf (f, "\tlfmfd\t%r, 4, [%r]!\n",
8705 start_reg, SP_REGNUM);
b111229a
RE
8706 start_reg = reg + 1;
8707 }
8708 }
8709 else
8710 {
8711 if (reg != start_reg)
dd18ae56
NC
8712 asm_fprintf (f, "\tlfmfd\t%r, %d, [%r]!\n",
8713 start_reg, reg - start_reg,
8714 SP_REGNUM);
6cfc7210 8715
b111229a
RE
8716 start_reg = reg + 1;
8717 }
8718 }
8719
8720 /* Just in case the last register checked also needs unstacking. */
8721 if (reg != start_reg)
dd18ae56
NC
8722 asm_fprintf (f, "\tlfmfd\t%r, %d, [%r]!\n",
8723 start_reg, reg - start_reg, SP_REGNUM);
b111229a
RE
8724 }
8725
5a9335ef
NC
8726 if (TARGET_IWMMXT)
8727 for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
8728 if (regs_ever_live[reg] && !call_used_regs[reg])
8729 asm_fprintf (f, "\twldrd\t%r, [%r, #+8]!\n", reg, SP_REGNUM);
8730
6d3d9133
NC
8731 /* If we can, restore the LR into the PC. */
8732 if (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
8733 && really_return
8734 && current_function_pretend_args_size == 0
6f7ebcbb 8735 && saved_regs_mask & (1 << LR_REGNUM))
cce8749e 8736 {
6f7ebcbb
NC
8737 saved_regs_mask &= ~ (1 << LR_REGNUM);
8738 saved_regs_mask |= (1 << PC_REGNUM);
6d3d9133 8739 }
d5b7b3ae 8740
6d3d9133
NC
8741 /* Load the registers off the stack. If we only have one register
8742 to load use the LDR instruction - it is faster. */
6f7ebcbb 8743 if (saved_regs_mask == (1 << LR_REGNUM))
6d3d9133 8744 {
f4864588 8745 /* The exception handler ignores the LR, so we do
6d3d9133
NC
8746 not really need to load it off the stack. */
8747 if (eh_ofs)
8748 asm_fprintf (f, "\tadd\t%r, %r, #4\n", SP_REGNUM, SP_REGNUM);
32de079a 8749 else
6d3d9133 8750 asm_fprintf (f, "\tldr\t%r, [%r], #4\n", LR_REGNUM, SP_REGNUM);
cce8749e 8751 }
6f7ebcbb 8752 else if (saved_regs_mask)
f1acdf8b
NC
8753 {
8754 if (saved_regs_mask & (1 << SP_REGNUM))
8755 /* Note - write back to the stack register is not enabled
8756 (ie "ldmfd sp!..."). We know that the stack pointer is
8757 in the list of registers and if we add writeback the
8758 instruction becomes UNPREDICTABLE. */
8759 print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask);
8760 else
8761 print_multi_reg (f, "ldmfd\t%r!", SP_REGNUM, saved_regs_mask);
8762 }
6d3d9133
NC
8763
8764 if (current_function_pretend_args_size)
cce8749e 8765 {
6d3d9133
NC
8766 /* Unwind the pre-pushed regs. */
8767 operands[0] = operands[1] = stack_pointer_rtx;
8768 operands[2] = GEN_INT (current_function_pretend_args_size);
8769 output_add_immediate (operands);
8770 }
8771 }
32de079a 8772
f4864588
PB
8773 if (! really_return
8774 || (ARM_FUNC_TYPE (func_type) == ARM_FT_NORMAL
8775 && current_function_pretend_args_size == 0
8776 && saved_regs_mask & (1 << PC_REGNUM)))
6d3d9133 8777 return "";
d5b7b3ae 8778
6d3d9133
NC
8779 /* Generate the return instruction. */
8780 switch ((int) ARM_FUNC_TYPE (func_type))
8781 {
8782 case ARM_FT_EXCEPTION_HANDLER:
8783 /* Even in 26-bit mode we do a mov (rather than a movs)
8784 because we don't have the PSR bits set in the address. */
8785 asm_fprintf (f, "\tmov\t%r, %r\n", PC_REGNUM, EXCEPTION_LR_REGNUM);
8786 break;
0616531f 8787
6d3d9133
NC
8788 case ARM_FT_ISR:
8789 case ARM_FT_FIQ:
8790 asm_fprintf (f, "\tsubs\t%r, %r, #4\n", PC_REGNUM, LR_REGNUM);
8791 break;
8792
8793 case ARM_FT_EXCEPTION:
8794 asm_fprintf (f, "\tmovs\t%r, %r\n", PC_REGNUM, LR_REGNUM);
8795 break;
8796
8797 case ARM_FT_INTERWORKED:
8798 asm_fprintf (f, "\tbx\t%r\n", LR_REGNUM);
8799 break;
8800
8801 default:
8802 if (frame_pointer_needed)
6bc82793 8803 /* If we used the frame pointer then the return address
6d3d9133
NC
8804 will have been loaded off the stack directly into the
8805 PC, so there is no need to issue a MOV instruction
8806 here. */
8807 ;
8808 else if (current_function_pretend_args_size == 0
6f7ebcbb 8809 && (saved_regs_mask & (1 << LR_REGNUM)))
6d3d9133
NC
8810 /* Similarly we may have been able to load LR into the PC
8811 even if we did not create a stack frame. */
8812 ;
8813 else if (TARGET_APCS_32)
8814 asm_fprintf (f, "\tmov\t%r, %r\n", PC_REGNUM, LR_REGNUM);
8815 else
8816 asm_fprintf (f, "\tmovs\t%r, %r\n", PC_REGNUM, LR_REGNUM);
8817 break;
cce8749e 8818 }
f3bb6135 8819
949d79eb
RE
8820 return "";
8821}
8822
08c148a8 8823static void
e32bac5b
RE
8824arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
8825 HOST_WIDE_INT frame_size)
949d79eb 8826{
d5b7b3ae
RE
8827 if (TARGET_THUMB)
8828 {
8829 /* ??? Probably not safe to set this here, since it assumes that a
8830 function will be emitted as assembly immediately after we generate
8831 RTL for it. This does not happen for inline functions. */
8832 return_used_this_function = 0;
8833 }
8834 else
8835 {
0977774b
JT
8836 /* We need to take into account any stack-frame rounding. */
8837 frame_size = arm_get_frame_size ();
8838
a72d4945 8839 if (use_return_insn (FALSE, NULL)
d5b7b3ae
RE
8840 && return_used_this_function
8841 && (frame_size + current_function_outgoing_args_size) != 0
5895f793 8842 && !frame_pointer_needed)
d5b7b3ae 8843 abort ();
f3bb6135 8844
d5b7b3ae 8845 /* Reset the ARM-specific per-function variables. */
d5b7b3ae
RE
8846 after_arm_reorg = 0;
8847 }
f3bb6135 8848}
e2c671ba 8849
2c849145
JM
8850/* Generate and emit an insn that we will recognize as a push_multi.
8851 Unfortunately, since this insn does not reflect very well the actual
8852 semantics of the operation, we need to annotate the insn for the benefit
8853 of DWARF2 frame unwind information. */
2c849145 8854static rtx
e32bac5b 8855emit_multi_reg_push (int mask)
e2c671ba
RE
8856{
8857 int num_regs = 0;
9b598fa0 8858 int num_dwarf_regs;
e2c671ba
RE
8859 int i, j;
8860 rtx par;
2c849145 8861 rtx dwarf;
87e27392 8862 int dwarf_par_index;
2c849145 8863 rtx tmp, reg;
e2c671ba 8864
d5b7b3ae 8865 for (i = 0; i <= LAST_ARM_REGNUM; i++)
e2c671ba 8866 if (mask & (1 << i))
5895f793 8867 num_regs++;
e2c671ba
RE
8868
8869 if (num_regs == 0 || num_regs > 16)
8870 abort ();
8871
9b598fa0
RE
8872 /* We don't record the PC in the dwarf frame information. */
8873 num_dwarf_regs = num_regs;
8874 if (mask & (1 << PC_REGNUM))
8875 num_dwarf_regs--;
8876
87e27392 8877 /* For the body of the insn we are going to generate an UNSPEC in
05713b80 8878 parallel with several USEs. This allows the insn to be recognized
87e27392
NC
8879 by the push_multi pattern in the arm.md file. The insn looks
8880 something like this:
8881
8882 (parallel [
b15bca31
RE
8883 (set (mem:BLK (pre_dec:BLK (reg:SI sp)))
8884 (unspec:BLK [(reg:SI r4)] UNSPEC_PUSH_MULT))
87e27392
NC
8885 (use (reg:SI 11 fp))
8886 (use (reg:SI 12 ip))
8887 (use (reg:SI 14 lr))
8888 (use (reg:SI 15 pc))
8889 ])
8890
8891 For the frame note however, we try to be more explicit and actually
8892 show each register being stored into the stack frame, plus a (single)
8893 decrement of the stack pointer. We do it this way in order to be
8894 friendly to the stack unwinding code, which only wants to see a single
8895 stack decrement per instruction. The RTL we generate for the note looks
8896 something like this:
8897
8898 (sequence [
8899 (set (reg:SI sp) (plus:SI (reg:SI sp) (const_int -20)))
8900 (set (mem:SI (reg:SI sp)) (reg:SI r4))
8901 (set (mem:SI (plus:SI (reg:SI sp) (const_int 4))) (reg:SI fp))
8902 (set (mem:SI (plus:SI (reg:SI sp) (const_int 8))) (reg:SI ip))
8903 (set (mem:SI (plus:SI (reg:SI sp) (const_int 12))) (reg:SI lr))
87e27392
NC
8904 ])
8905
8906 This sequence is used both by the code to support stack unwinding for
8907 exceptions handlers and the code to generate dwarf2 frame debugging. */
8908
43cffd11 8909 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_regs));
9b598fa0 8910 dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_dwarf_regs + 1));
87e27392 8911 dwarf_par_index = 1;
e2c671ba 8912
d5b7b3ae 8913 for (i = 0; i <= LAST_ARM_REGNUM; i++)
e2c671ba
RE
8914 {
8915 if (mask & (1 << i))
8916 {
2c849145
JM
8917 reg = gen_rtx_REG (SImode, i);
8918
e2c671ba 8919 XVECEXP (par, 0, 0)
43cffd11
RE
8920 = gen_rtx_SET (VOIDmode,
8921 gen_rtx_MEM (BLKmode,
8922 gen_rtx_PRE_DEC (BLKmode,
8923 stack_pointer_rtx)),
8924 gen_rtx_UNSPEC (BLKmode,
2c849145 8925 gen_rtvec (1, reg),
9b598fa0 8926 UNSPEC_PUSH_MULT));
2c849145 8927
9b598fa0
RE
8928 if (i != PC_REGNUM)
8929 {
8930 tmp = gen_rtx_SET (VOIDmode,
8931 gen_rtx_MEM (SImode, stack_pointer_rtx),
8932 reg);
8933 RTX_FRAME_RELATED_P (tmp) = 1;
8934 XVECEXP (dwarf, 0, dwarf_par_index) = tmp;
8935 dwarf_par_index++;
8936 }
2c849145 8937
e2c671ba
RE
8938 break;
8939 }
8940 }
8941
8942 for (j = 1, i++; j < num_regs; i++)
8943 {
8944 if (mask & (1 << i))
8945 {
2c849145
JM
8946 reg = gen_rtx_REG (SImode, i);
8947
8948 XVECEXP (par, 0, j) = gen_rtx_USE (VOIDmode, reg);
8949
9b598fa0
RE
8950 if (i != PC_REGNUM)
8951 {
8952 tmp = gen_rtx_SET (VOIDmode,
8953 gen_rtx_MEM (SImode,
8954 plus_constant (stack_pointer_rtx,
8955 4 * j)),
8956 reg);
8957 RTX_FRAME_RELATED_P (tmp) = 1;
8958 XVECEXP (dwarf, 0, dwarf_par_index++) = tmp;
8959 }
8960
e2c671ba
RE
8961 j++;
8962 }
8963 }
b111229a 8964
2c849145 8965 par = emit_insn (par);
87e27392
NC
8966
8967 tmp = gen_rtx_SET (SImode,
8968 stack_pointer_rtx,
8969 gen_rtx_PLUS (SImode,
8970 stack_pointer_rtx,
8971 GEN_INT (-4 * num_regs)));
8972 RTX_FRAME_RELATED_P (tmp) = 1;
8973 XVECEXP (dwarf, 0, 0) = tmp;
8974
2c849145
JM
8975 REG_NOTES (par) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
8976 REG_NOTES (par));
8977 return par;
b111229a
RE
8978}
8979
2c849145 8980static rtx
e32bac5b 8981emit_sfm (int base_reg, int count)
b111229a
RE
8982{
8983 rtx par;
2c849145
JM
8984 rtx dwarf;
8985 rtx tmp, reg;
b111229a
RE
8986 int i;
8987
43cffd11 8988 par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2c849145 8989 dwarf = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2c849145
JM
8990
8991 reg = gen_rtx_REG (XFmode, base_reg++);
43cffd11
RE
8992
8993 XVECEXP (par, 0, 0)
8994 = gen_rtx_SET (VOIDmode,
8995 gen_rtx_MEM (BLKmode,
8996 gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
8997 gen_rtx_UNSPEC (BLKmode,
2c849145 8998 gen_rtvec (1, reg),
b15bca31 8999 UNSPEC_PUSH_MULT));
2c849145
JM
9000 tmp
9001 = gen_rtx_SET (VOIDmode,
9002 gen_rtx_MEM (XFmode,
9003 gen_rtx_PRE_DEC (BLKmode, stack_pointer_rtx)),
9004 reg);
9005 RTX_FRAME_RELATED_P (tmp) = 1;
9006 XVECEXP (dwarf, 0, count - 1) = tmp;
9007
b111229a 9008 for (i = 1; i < count; i++)
2c849145
JM
9009 {
9010 reg = gen_rtx_REG (XFmode, base_reg++);
9011 XVECEXP (par, 0, i) = gen_rtx_USE (VOIDmode, reg);
9012
9013 tmp = gen_rtx_SET (VOIDmode,
9014 gen_rtx_MEM (XFmode,
9015 gen_rtx_PRE_DEC (BLKmode,
9016 stack_pointer_rtx)),
9017 reg);
9018 RTX_FRAME_RELATED_P (tmp) = 1;
9019 XVECEXP (dwarf, 0, count - i - 1) = tmp;
9020 }
b111229a 9021
2c849145
JM
9022 par = emit_insn (par);
9023 REG_NOTES (par) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
9024 REG_NOTES (par));
9025 return par;
e2c671ba
RE
9026}
9027
095bb276
NC
9028/* Compute the distance from register FROM to register TO.
9029 These can be the arg pointer (26), the soft frame pointer (25),
9030 the stack pointer (13) or the hard frame pointer (11).
9031 Typical stack layout looks like this:
9032
9033 old stack pointer -> | |
9034 ----
9035 | | \
9036 | | saved arguments for
9037 | | vararg functions
9038 | | /
9039 --
9040 hard FP & arg pointer -> | | \
9041 | | stack
9042 | | frame
9043 | | /
9044 --
9045 | | \
9046 | | call saved
9047 | | registers
9048 soft frame pointer -> | | /
9049 --
9050 | | \
9051 | | local
9052 | | variables
9053 | | /
9054 --
9055 | | \
9056 | | outgoing
9057 | | arguments
9058 current stack pointer -> | | /
9059 --
9060
43aa4e05 9061 For a given function some or all of these stack components
095bb276
NC
9062 may not be needed, giving rise to the possibility of
9063 eliminating some of the registers.
9064
825dda42 9065 The values returned by this function must reflect the behavior
095bb276
NC
9066 of arm_expand_prologue() and arm_compute_save_reg_mask().
9067
9068 The sign of the number returned reflects the direction of stack
9069 growth, so the values are positive for all eliminations except
9070 from the soft frame pointer to the hard frame pointer. */
095bb276 9071unsigned int
e32bac5b 9072arm_compute_initial_elimination_offset (unsigned int from, unsigned int to)
095bb276 9073{
0977774b 9074 unsigned int local_vars = arm_get_frame_size ();
095bb276
NC
9075 unsigned int outgoing_args = current_function_outgoing_args_size;
9076 unsigned int stack_frame;
9077 unsigned int call_saved_registers;
9078 unsigned long func_type;
9079
9080 func_type = arm_current_func_type ();
9081
9082 /* Volatile functions never return, so there is
9083 no need to save call saved registers. */
9084 call_saved_registers = 0;
9085 if (! IS_VOLATILE (func_type))
9086 {
121308d4 9087 unsigned int reg_mask;
095bb276
NC
9088 unsigned int reg;
9089
1d6e90ac 9090 /* Make sure that we compute which registers will be saved
121308d4 9091 on the stack using the same algorithm that is used by
5a9335ef
NC
9092 the prologue creation code. */
9093 reg_mask = arm_compute_save_reg_mask ();
095bb276 9094
121308d4 9095 /* Now count the number of bits set in save_reg_mask.
5a9335ef
NC
9096 If we have already counted the registers in the stack
9097 frame, do not count them again. Non call-saved registers
9098 might be saved in the call-save area of the stack, if
9099 doing so will preserve the stack's alignment. Hence we
9100 must count them here. For each set bit we need 4 bytes
9101 of stack space. */
9102 if (frame_pointer_needed)
9103 reg_mask &= 0x07ff;
9104 call_saved_registers += 4 * bit_count (reg_mask);
ef7112de
NC
9105
9106 /* If the hard floating point registers are going to be
9107 used then they must be saved on the stack as well.
9108 Each register occupies 12 bytes of stack space. */
5a9335ef 9109 for (reg = FIRST_ARM_FP_REGNUM; reg <= LAST_ARM_FP_REGNUM; reg++)
ef7112de
NC
9110 if (regs_ever_live[reg] && ! call_used_regs[reg])
9111 call_saved_registers += 12;
5a9335ef
NC
9112
9113 if (TARGET_REALLY_IWMMXT)
9114 /* Check for the call-saved iWMMXt registers. */
9115 for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
9116 if (regs_ever_live[reg] && ! call_used_regs [reg])
9117 call_saved_registers += 8;
095bb276
NC
9118 }
9119
9120 /* The stack frame contains 4 registers - the old frame pointer,
9121 the old stack pointer, the return address and PC of the start
9122 of the function. */
9123 stack_frame = frame_pointer_needed ? 16 : 0;
9124
095bb276
NC
9125 /* OK, now we have enough information to compute the distances.
9126 There must be an entry in these switch tables for each pair
9127 of registers in ELIMINABLE_REGS, even if some of the entries
9128 seem to be redundant or useless. */
9129 switch (from)
9130 {
9131 case ARG_POINTER_REGNUM:
9132 switch (to)
9133 {
9134 case THUMB_HARD_FRAME_POINTER_REGNUM:
9135 return 0;
9136
9137 case FRAME_POINTER_REGNUM:
9138 /* This is the reverse of the soft frame pointer
9139 to hard frame pointer elimination below. */
9140 if (call_saved_registers == 0 && stack_frame == 0)
9141 return 0;
9142 return (call_saved_registers + stack_frame - 4);
9143
9144 case ARM_HARD_FRAME_POINTER_REGNUM:
9145 /* If there is no stack frame then the hard
9146 frame pointer and the arg pointer coincide. */
9147 if (stack_frame == 0 && call_saved_registers != 0)
9148 return 0;
9149 /* FIXME: Not sure about this. Maybe we should always return 0 ? */
9150 return (frame_pointer_needed
9151 && current_function_needs_context
3cb66fd7 9152 && ! cfun->machine->uses_anonymous_args) ? 4 : 0;
095bb276
NC
9153
9154 case STACK_POINTER_REGNUM:
9155 /* If nothing has been pushed on the stack at all
9156 then this will return -4. This *is* correct! */
9157 return call_saved_registers + stack_frame + local_vars + outgoing_args - 4;
9158
9159 default:
9160 abort ();
9161 }
9162 break;
9163
9164 case FRAME_POINTER_REGNUM:
9165 switch (to)
9166 {
9167 case THUMB_HARD_FRAME_POINTER_REGNUM:
9168 return 0;
9169
9170 case ARM_HARD_FRAME_POINTER_REGNUM:
9171 /* The hard frame pointer points to the top entry in the
9172 stack frame. The soft frame pointer to the bottom entry
9173 in the stack frame. If there is no stack frame at all,
9174 then they are identical. */
9175 if (call_saved_registers == 0 && stack_frame == 0)
9176 return 0;
9177 return - (call_saved_registers + stack_frame - 4);
9178
9179 case STACK_POINTER_REGNUM:
9180 return local_vars + outgoing_args;
9181
9182 default:
9183 abort ();
9184 }
9185 break;
9186
9187 default:
9188 /* You cannot eliminate from the stack pointer.
9189 In theory you could eliminate from the hard frame
9190 pointer to the stack pointer, but this will never
9191 happen, since if a stack frame is not needed the
9192 hard frame pointer will never be used. */
9193 abort ();
9194 }
9195}
9196
0977774b
JT
9197/* Calculate the size of the stack frame, taking into account any
9198 padding that is required to ensure stack-alignment. */
0977774b 9199HOST_WIDE_INT
e32bac5b 9200arm_get_frame_size (void)
0977774b
JT
9201{
9202 int regno;
9203
0c2ca901 9204 int base_size = ROUND_UP_WORD (get_frame_size ());
0977774b
JT
9205 int entry_size = 0;
9206 unsigned long func_type = arm_current_func_type ();
c231c91e 9207 int leaf;
0977774b
JT
9208
9209 if (! TARGET_ARM)
9210 abort();
9211
9212 if (! TARGET_ATPCS)
9213 return base_size;
9214
c231c91e
RE
9215 /* We need to know if we are a leaf function. Unfortunately, it
9216 is possible to be called after start_sequence has been called,
9217 which causes get_insns to return the insns for the sequence,
9218 not the function, which will cause leaf_function_p to return
9219 the incorrect result.
9220
9221 To work around this, we cache the computed frame size. This
9222 works because we will only be calling RTL expanders that need
9223 to know about leaf functions once reload has completed, and the
9224 frame size cannot be changed after that time, so we can safely
9225 use the cached value. */
9226
9227 if (reload_completed)
9228 return cfun->machine->frame_size;
9229
9230 leaf = leaf_function_p ();
9231
9232 /* A leaf function does not need any stack alignment if it has nothing
9233 on the stack. */
9234 if (leaf && base_size == 0)
9235 {
9236 cfun->machine->frame_size = 0;
9237 return 0;
9238 }
9239
0977774b
JT
9240 /* We know that SP will be word aligned on entry, and we must
9241 preserve that condition at any subroutine call. But those are
9242 the only constraints. */
9243
9244 /* Space for variadic functions. */
9245 if (current_function_pretend_args_size)
9246 entry_size += current_function_pretend_args_size;
9247
9248 /* Space for saved registers. */
9249 entry_size += bit_count (arm_compute_save_reg_mask ()) * 4;
9250
9251 /* Space for saved FPA registers. */
9252 if (! IS_VOLATILE (func_type))
9253 {
9254 for (regno = FIRST_ARM_FP_REGNUM; regno <= LAST_ARM_FP_REGNUM; regno++)
9255 if (regs_ever_live[regno] && ! call_used_regs[regno])
9256 entry_size += 12;
9257 }
9258
5a9335ef
NC
9259 if (TARGET_REALLY_IWMMXT)
9260 {
9261 /* Check for the call-saved iWMMXt registers. */
9262 for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
9263 if (regs_ever_live [regno] && ! call_used_regs [regno])
9264 entry_size += 8;
9265 }
9266
0977774b
JT
9267 if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
9268 base_size += 4;
9269 if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
9270 abort ();
9271
c231c91e
RE
9272 cfun->machine->frame_size = base_size;
9273
0977774b
JT
9274 return base_size;
9275}
9276
6d3d9133 9277/* Generate the prologue instructions for entry into an ARM function. */
e2c671ba 9278void
e32bac5b 9279arm_expand_prologue (void)
e2c671ba
RE
9280{
9281 int reg;
6d3d9133 9282 rtx amount;
2c849145 9283 rtx insn;
68dfd979 9284 rtx ip_rtx;
6d3d9133
NC
9285 unsigned long live_regs_mask;
9286 unsigned long func_type;
68dfd979 9287 int fp_offset = 0;
095bb276
NC
9288 int saved_pretend_args = 0;
9289 unsigned int args_to_push;
d3236b4d 9290
6d3d9133 9291 func_type = arm_current_func_type ();
e2c671ba 9292
31fdb4d5 9293 /* Naked functions don't have prologues. */
6d3d9133 9294 if (IS_NAKED (func_type))
31fdb4d5
DE
9295 return;
9296
095bb276
NC
9297 /* Make a copy of c_f_p_a_s as we may need to modify it locally. */
9298 args_to_push = current_function_pretend_args_size;
9299
6d3d9133
NC
9300 /* Compute which register we will have to save onto the stack. */
9301 live_regs_mask = arm_compute_save_reg_mask ();
e2c671ba 9302
68dfd979 9303 ip_rtx = gen_rtx_REG (SImode, IP_REGNUM);
d3236b4d 9304
e2c671ba
RE
9305 if (frame_pointer_needed)
9306 {
7b8b8ade
NC
9307 if (IS_INTERRUPT (func_type))
9308 {
9309 /* Interrupt functions must not corrupt any registers.
9310 Creating a frame pointer however, corrupts the IP
9311 register, so we must push it first. */
9312 insn = emit_multi_reg_push (1 << IP_REGNUM);
121308d4
NC
9313
9314 /* Do not set RTX_FRAME_RELATED_P on this insn.
9315 The dwarf stack unwinding code only wants to see one
9316 stack decrement per function, and this is not it. If
9317 this instruction is labeled as being part of the frame
9318 creation sequence then dwarf2out_frame_debug_expr will
9319 abort when it encounters the assignment of IP to FP
9320 later on, since the use of SP here establishes SP as
9321 the CFA register and not IP.
9322
9323 Anyway this instruction is not really part of the stack
9324 frame creation although it is part of the prologue. */
7b8b8ade
NC
9325 }
9326 else if (IS_NESTED (func_type))
68dfd979
NC
9327 {
9328 /* The Static chain register is the same as the IP register
9329 used as a scratch register during stack frame creation.
9330 To get around this need to find somewhere to store IP
9331 whilst the frame is being created. We try the following
9332 places in order:
9333
6d3d9133 9334 1. The last argument register.
68dfd979
NC
9335 2. A slot on the stack above the frame. (This only
9336 works if the function is not a varargs function).
095bb276
NC
9337 3. Register r3, after pushing the argument registers
9338 onto the stack.
6d3d9133 9339
34ce3d7b
JM
9340 Note - we only need to tell the dwarf2 backend about the SP
9341 adjustment in the second variant; the static chain register
9342 doesn't need to be unwound, as it doesn't contain a value
9343 inherited from the caller. */
d3236b4d 9344
68dfd979
NC
9345 if (regs_ever_live[3] == 0)
9346 {
9347 insn = gen_rtx_REG (SImode, 3);
9348 insn = gen_rtx_SET (SImode, insn, ip_rtx);
d3236b4d 9349 insn = emit_insn (insn);
68dfd979 9350 }
095bb276 9351 else if (args_to_push == 0)
68dfd979 9352 {
34ce3d7b 9353 rtx dwarf;
68dfd979
NC
9354 insn = gen_rtx_PRE_DEC (SImode, stack_pointer_rtx);
9355 insn = gen_rtx_MEM (SImode, insn);
9356 insn = gen_rtx_SET (VOIDmode, insn, ip_rtx);
9357 insn = emit_insn (insn);
34ce3d7b 9358
68dfd979 9359 fp_offset = 4;
34ce3d7b
JM
9360
9361 /* Just tell the dwarf backend that we adjusted SP. */
9362 dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
9363 gen_rtx_PLUS (SImode, stack_pointer_rtx,
9364 GEN_INT (-fp_offset)));
9365 RTX_FRAME_RELATED_P (insn) = 1;
9366 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9367 dwarf, REG_NOTES (insn));
68dfd979
NC
9368 }
9369 else
095bb276
NC
9370 {
9371 /* Store the args on the stack. */
3cb66fd7 9372 if (cfun->machine->uses_anonymous_args)
095bb276
NC
9373 insn = emit_multi_reg_push
9374 ((0xf0 >> (args_to_push / 4)) & 0xf);
9375 else
9376 insn = emit_insn
9377 (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
9378 GEN_INT (- args_to_push)));
9379
9380 RTX_FRAME_RELATED_P (insn) = 1;
9381
9382 saved_pretend_args = 1;
9383 fp_offset = args_to_push;
9384 args_to_push = 0;
9385
9386 /* Now reuse r3 to preserve IP. */
9387 insn = gen_rtx_REG (SImode, 3);
9388 insn = gen_rtx_SET (SImode, insn, ip_rtx);
9389 (void) emit_insn (insn);
9390 }
68dfd979
NC
9391 }
9392
68dfd979
NC
9393 if (fp_offset)
9394 {
9395 insn = gen_rtx_PLUS (SImode, stack_pointer_rtx, GEN_INT (fp_offset));
9396 insn = gen_rtx_SET (SImode, ip_rtx, insn);
9397 }
9398 else
9399 insn = gen_movsi (ip_rtx, stack_pointer_rtx);
9400
6d3d9133 9401 insn = emit_insn (insn);
8e56560e 9402 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba
RE
9403 }
9404
095bb276 9405 if (args_to_push)
e2c671ba 9406 {
6d3d9133 9407 /* Push the argument registers, or reserve space for them. */
3cb66fd7 9408 if (cfun->machine->uses_anonymous_args)
2c849145 9409 insn = emit_multi_reg_push
095bb276 9410 ((0xf0 >> (args_to_push / 4)) & 0xf);
e2c671ba 9411 else
2c849145
JM
9412 insn = emit_insn
9413 (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
095bb276 9414 GEN_INT (- args_to_push)));
2c849145 9415 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba
RE
9416 }
9417
06bea5aa
NC
9418 /* If this is an interrupt service routine, and the link register
9419 is going to be pushed, and we are not creating a stack frame,
9420 (which would involve an extra push of IP and a pop in the epilogue)
9421 subtracting four from LR now will mean that the function return
9422 can be done with a single instruction. */
3a7731fd 9423 if ((func_type == ARM_FT_ISR || func_type == ARM_FT_FIQ)
06bea5aa
NC
9424 && (live_regs_mask & (1 << LR_REGNUM)) != 0
9425 && ! frame_pointer_needed)
9426 emit_insn (gen_rtx_SET (SImode,
9427 gen_rtx_REG (SImode, LR_REGNUM),
9428 gen_rtx_PLUS (SImode,
9429 gen_rtx_REG (SImode, LR_REGNUM),
9430 GEN_INT (-4))));
3a7731fd 9431
e2c671ba
RE
9432 if (live_regs_mask)
9433 {
2c849145
JM
9434 insn = emit_multi_reg_push (live_regs_mask);
9435 RTX_FRAME_RELATED_P (insn) = 1;
e2c671ba 9436 }
d5b7b3ae 9437
5a9335ef
NC
9438 if (TARGET_IWMMXT)
9439 for (reg = FIRST_IWMMXT_REGNUM; reg <= LAST_IWMMXT_REGNUM; reg++)
9440 if (regs_ever_live[reg] && ! call_used_regs [reg])
9441 {
9442 insn = gen_rtx_PRE_DEC (V2SImode, stack_pointer_rtx);
9443 insn = gen_rtx_MEM (V2SImode, insn);
9444 insn = emit_insn (gen_rtx_SET (VOIDmode, insn,
9445 gen_rtx_REG (V2SImode, reg)));
9446 RTX_FRAME_RELATED_P (insn) = 1;
9447 }
9448
6d3d9133 9449 if (! IS_VOLATILE (func_type))
b111229a 9450 {
29ad9694
RE
9451 /* Save any floating point call-saved registers used by this
9452 function. */
9453 if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
b111229a 9454 {
29ad9694 9455 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
5895f793 9456 if (regs_ever_live[reg] && !call_used_regs[reg])
2c849145
JM
9457 {
9458 insn = gen_rtx_PRE_DEC (XFmode, stack_pointer_rtx);
9459 insn = gen_rtx_MEM (XFmode, insn);
9460 insn = emit_insn (gen_rtx_SET (VOIDmode, insn,
9461 gen_rtx_REG (XFmode, reg)));
9462 RTX_FRAME_RELATED_P (insn) = 1;
9463 }
b111229a
RE
9464 }
9465 else
9466 {
d5b7b3ae 9467 int start_reg = LAST_ARM_FP_REGNUM;
b111229a 9468
29ad9694 9469 for (reg = LAST_ARM_FP_REGNUM; reg >= FIRST_ARM_FP_REGNUM; reg--)
b111229a 9470 {
5895f793 9471 if (regs_ever_live[reg] && !call_used_regs[reg])
b111229a
RE
9472 {
9473 if (start_reg - reg == 3)
9474 {
2c849145
JM
9475 insn = emit_sfm (reg, 4);
9476 RTX_FRAME_RELATED_P (insn) = 1;
b111229a
RE
9477 start_reg = reg - 1;
9478 }
9479 }
9480 else
9481 {
9482 if (start_reg != reg)
2c849145
JM
9483 {
9484 insn = emit_sfm (reg + 1, start_reg - reg);
9485 RTX_FRAME_RELATED_P (insn) = 1;
9486 }
b111229a
RE
9487 start_reg = reg - 1;
9488 }
9489 }
9490
9491 if (start_reg != reg)
2c849145
JM
9492 {
9493 insn = emit_sfm (reg + 1, start_reg - reg);
9494 RTX_FRAME_RELATED_P (insn) = 1;
9495 }
b111229a
RE
9496 }
9497 }
e2c671ba
RE
9498
9499 if (frame_pointer_needed)
2c849145 9500 {
6d3d9133 9501 /* Create the new frame pointer. */
095bb276 9502 insn = GEN_INT (-(4 + args_to_push + fp_offset));
68dfd979 9503 insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx, ip_rtx, insn));
2c849145 9504 RTX_FRAME_RELATED_P (insn) = 1;
68dfd979 9505
6d3d9133 9506 if (IS_NESTED (func_type))
68dfd979
NC
9507 {
9508 /* Recover the static chain register. */
095bb276
NC
9509 if (regs_ever_live [3] == 0
9510 || saved_pretend_args)
1d6e90ac 9511 insn = gen_rtx_REG (SImode, 3);
68dfd979
NC
9512 else /* if (current_function_pretend_args_size == 0) */
9513 {
29ad9694
RE
9514 insn = gen_rtx_PLUS (SImode, hard_frame_pointer_rtx,
9515 GEN_INT (4));
68dfd979 9516 insn = gen_rtx_MEM (SImode, insn);
68dfd979 9517 }
1d6e90ac 9518
c14a3a45
NC
9519 emit_insn (gen_rtx_SET (SImode, ip_rtx, insn));
9520 /* Add a USE to stop propagate_one_insn() from barfing. */
6bacc7b0 9521 emit_insn (gen_prologue_use (ip_rtx));
68dfd979 9522 }
2c849145 9523 }
e2c671ba 9524
0977774b 9525 amount = GEN_INT (-(arm_get_frame_size ()
6d3d9133
NC
9526 + current_function_outgoing_args_size));
9527
e2c671ba
RE
9528 if (amount != const0_rtx)
9529 {
745b9093
JM
9530 /* This add can produce multiple insns for a large constant, so we
9531 need to get tricky. */
9532 rtx last = get_last_insn ();
2c849145
JM
9533 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
9534 amount));
745b9093
JM
9535 do
9536 {
9537 last = last ? NEXT_INSN (last) : get_insns ();
9538 RTX_FRAME_RELATED_P (last) = 1;
9539 }
9540 while (last != insn);
e04c2d6c
RE
9541
9542 /* If the frame pointer is needed, emit a special barrier that
9543 will prevent the scheduler from moving stores to the frame
9544 before the stack adjustment. */
9545 if (frame_pointer_needed)
3894f59e
RE
9546 insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
9547 hard_frame_pointer_rtx));
e2c671ba
RE
9548 }
9549
9550 /* If we are profiling, make sure no instructions are scheduled before
f5a1b0d2
NC
9551 the call to mcount. Similarly if the user has requested no
9552 scheduling in the prolog. */
70f4f91c 9553 if (current_function_profile || TARGET_NO_SCHED_PRO)
e2c671ba 9554 emit_insn (gen_blockage ());
6f7ebcbb
NC
9555
9556 /* If the link register is being kept alive, with the return address in it,
9557 then make sure that it does not get reused by the ce2 pass. */
9558 if ((live_regs_mask & (1 << LR_REGNUM)) == 0)
9559 {
6bacc7b0 9560 emit_insn (gen_prologue_use (gen_rtx_REG (SImode, LR_REGNUM)));
6f7ebcbb
NC
9561 cfun->machine->lr_save_eliminated = 1;
9562 }
e2c671ba 9563}
cce8749e 9564\f
9997d19d
RE
9565/* If CODE is 'd', then the X is a condition operand and the instruction
9566 should only be executed if the condition is true.
ddd5a7c1 9567 if CODE is 'D', then the X is a condition operand and the instruction
9997d19d
RE
9568 should only be executed if the condition is false: however, if the mode
9569 of the comparison is CCFPEmode, then always execute the instruction -- we
9570 do this because in these circumstances !GE does not necessarily imply LT;
9571 in these cases the instruction pattern will take care to make sure that
9572 an instruction containing %d will follow, thereby undoing the effects of
ddd5a7c1 9573 doing this instruction unconditionally.
9997d19d
RE
9574 If CODE is 'N' then X is a floating point operand that must be negated
9575 before output.
9576 If CODE is 'B' then output a bitwise inverted value of X (a const int).
9577 If X is a REG and CODE is `M', output a ldm/stm style multi-reg. */
9997d19d 9578void
e32bac5b 9579arm_print_operand (FILE *stream, rtx x, int code)
9997d19d
RE
9580{
9581 switch (code)
9582 {
9583 case '@':
f3139301 9584 fputs (ASM_COMMENT_START, stream);
9997d19d
RE
9585 return;
9586
d5b7b3ae
RE
9587 case '_':
9588 fputs (user_label_prefix, stream);
9589 return;
9590
9997d19d 9591 case '|':
f3139301 9592 fputs (REGISTER_PREFIX, stream);
9997d19d
RE
9593 return;
9594
9595 case '?':
9596 if (arm_ccfsm_state == 3 || arm_ccfsm_state == 4)
cca0a211
RE
9597 {
9598 if (TARGET_THUMB || current_insn_predicate != NULL)
9599 abort ();
9600
9601 fputs (arm_condition_codes[arm_current_cc], stream);
9602 }
9603 else if (current_insn_predicate)
9604 {
9605 enum arm_cond_code code;
9606
9607 if (TARGET_THUMB)
9608 abort ();
9609
9610 code = get_arm_condition_code (current_insn_predicate);
9611 fputs (arm_condition_codes[code], stream);
9612 }
9997d19d
RE
9613 return;
9614
9615 case 'N':
9616 {
9617 REAL_VALUE_TYPE r;
9618 REAL_VALUE_FROM_CONST_DOUBLE (r, x);
9619 r = REAL_VALUE_NEGATE (r);
9620 fprintf (stream, "%s", fp_const_from_val (&r));
9621 }
9622 return;
9623
9624 case 'B':
9625 if (GET_CODE (x) == CONST_INT)
4bc74ece
NC
9626 {
9627 HOST_WIDE_INT val;
5895f793 9628 val = ARM_SIGN_EXTEND (~INTVAL (x));
36ba9cb8 9629 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, val);
4bc74ece 9630 }
9997d19d
RE
9631 else
9632 {
9633 putc ('~', stream);
9634 output_addr_const (stream, x);
9635 }
9636 return;
9637
9638 case 'i':
9639 fprintf (stream, "%s", arithmetic_instr (x, 1));
9640 return;
9641
9b6b54e2
NC
9642 /* Truncate Cirrus shift counts. */
9643 case 's':
9644 if (GET_CODE (x) == CONST_INT)
9645 {
9646 fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x3f);
9647 return;
9648 }
9649 arm_print_operand (stream, x, 0);
9650 return;
9651
9997d19d
RE
9652 case 'I':
9653 fprintf (stream, "%s", arithmetic_instr (x, 0));
9654 return;
9655
9656 case 'S':
9657 {
9658 HOST_WIDE_INT val;
5895f793 9659 const char * shift = shift_op (x, &val);
9997d19d 9660
e2c671ba
RE
9661 if (shift)
9662 {
5895f793 9663 fprintf (stream, ", %s ", shift_op (x, &val));
e2c671ba
RE
9664 if (val == -1)
9665 arm_print_operand (stream, XEXP (x, 1), 0);
9666 else
4a0a75dd 9667 fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, val);
e2c671ba 9668 }
9997d19d
RE
9669 }
9670 return;
9671
d5b7b3ae
RE
9672 /* An explanation of the 'Q', 'R' and 'H' register operands:
9673
9674 In a pair of registers containing a DI or DF value the 'Q'
9675 operand returns the register number of the register containing
093354e0 9676 the least significant part of the value. The 'R' operand returns
d5b7b3ae
RE
9677 the register number of the register containing the most
9678 significant part of the value.
9679
9680 The 'H' operand returns the higher of the two register numbers.
9681 On a run where WORDS_BIG_ENDIAN is true the 'H' operand is the
093354e0 9682 same as the 'Q' operand, since the most significant part of the
d5b7b3ae
RE
9683 value is held in the lower number register. The reverse is true
9684 on systems where WORDS_BIG_ENDIAN is false.
9685
9686 The purpose of these operands is to distinguish between cases
9687 where the endian-ness of the values is important (for example
9688 when they are added together), and cases where the endian-ness
9689 is irrelevant, but the order of register operations is important.
9690 For example when loading a value from memory into a register
9691 pair, the endian-ness does not matter. Provided that the value
9692 from the lower memory address is put into the lower numbered
9693 register, and the value from the higher address is put into the
9694 higher numbered register, the load will work regardless of whether
9695 the value being loaded is big-wordian or little-wordian. The
9696 order of the two register loads can matter however, if the address
9697 of the memory location is actually held in one of the registers
9698 being overwritten by the load. */
c1c2bc04 9699 case 'Q':
d5b7b3ae 9700 if (REGNO (x) > LAST_ARM_REGNUM)
c1c2bc04 9701 abort ();
d5b7b3ae 9702 asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0));
c1c2bc04
RE
9703 return;
9704
9997d19d 9705 case 'R':
d5b7b3ae 9706 if (REGNO (x) > LAST_ARM_REGNUM)
9997d19d 9707 abort ();
d5b7b3ae
RE
9708 asm_fprintf (stream, "%r", REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1));
9709 return;
9710
9711 case 'H':
9712 if (REGNO (x) > LAST_ARM_REGNUM)
9713 abort ();
9714 asm_fprintf (stream, "%r", REGNO (x) + 1);
9997d19d
RE
9715 return;
9716
9717 case 'm':
d5b7b3ae
RE
9718 asm_fprintf (stream, "%r",
9719 GET_CODE (XEXP (x, 0)) == REG
9720 ? REGNO (XEXP (x, 0)) : REGNO (XEXP (XEXP (x, 0), 0)));
9997d19d
RE
9721 return;
9722
9723 case 'M':
dd18ae56 9724 asm_fprintf (stream, "{%r-%r}",
d5b7b3ae 9725 REGNO (x),
e9d7b180 9726 REGNO (x) + ARM_NUM_REGS (GET_MODE (x)) - 1);
9997d19d
RE
9727 return;
9728
9729 case 'd':
64e92a26
RE
9730 /* CONST_TRUE_RTX means always -- that's the default. */
9731 if (x == const_true_rtx)
d5b7b3ae
RE
9732 return;
9733
defc0463
RE
9734 fputs (arm_condition_codes[get_arm_condition_code (x)],
9735 stream);
9997d19d
RE
9736 return;
9737
9738 case 'D':
64e92a26
RE
9739 /* CONST_TRUE_RTX means not always -- ie never. We shouldn't ever
9740 want to do that. */
9741 if (x == const_true_rtx)
9742 abort ();
d5b7b3ae 9743
defc0463
RE
9744 fputs (arm_condition_codes[ARM_INVERSE_CONDITION_CODE
9745 (get_arm_condition_code (x))],
9746 stream);
9997d19d
RE
9747 return;
9748
9b6b54e2
NC
9749 /* Cirrus registers can be accessed in a variety of ways:
9750 single floating point (f)
9751 double floating point (d)
9752 32bit integer (fx)
9753 64bit integer (dx). */
9754 case 'W': /* Cirrus register in F mode. */
9755 case 'X': /* Cirrus register in D mode. */
9756 case 'Y': /* Cirrus register in FX mode. */
9757 case 'Z': /* Cirrus register in DX mode. */
9758 if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
9759 abort ();
9760
9761 fprintf (stream, "mv%s%s",
9762 code == 'W' ? "f"
9763 : code == 'X' ? "d"
9764 : code == 'Y' ? "fx" : "dx", reg_names[REGNO (x)] + 2);
9765
9766 return;
9767
9768 /* Print cirrus register in the mode specified by the register's mode. */
9769 case 'V':
9770 {
9771 int mode = GET_MODE (x);
9772
9773 if (GET_CODE (x) != REG || REGNO_REG_CLASS (REGNO (x)) != CIRRUS_REGS)
9774 abort ();
9775
9776 fprintf (stream, "mv%s%s",
9777 mode == DFmode ? "d"
9778 : mode == SImode ? "fx"
9779 : mode == DImode ? "dx"
9780 : "f", reg_names[REGNO (x)] + 2);
9781
9782 return;
9783 }
9784
5a9335ef
NC
9785 case 'U':
9786 if (GET_CODE (x) != REG
9787 || REGNO (x) < FIRST_IWMMXT_GR_REGNUM
9788 || REGNO (x) > LAST_IWMMXT_GR_REGNUM)
9789 /* Bad value for wCG register number. */
9790 abort ();
9791 else
9792 fprintf (stream, "%d", REGNO (x) - FIRST_IWMMXT_GR_REGNUM);
9793 return;
9794
9795 /* Print an iWMMXt control register name. */
9796 case 'w':
9797 if (GET_CODE (x) != CONST_INT
9798 || INTVAL (x) < 0
9799 || INTVAL (x) >= 16)
9800 /* Bad value for wC register number. */
9801 abort ();
9802 else
9803 {
9804 static const char * wc_reg_names [16] =
9805 {
9806 "wCID", "wCon", "wCSSF", "wCASF",
9807 "wC4", "wC5", "wC6", "wC7",
9808 "wCGR0", "wCGR1", "wCGR2", "wCGR3",
9809 "wC12", "wC13", "wC14", "wC15"
9810 };
9811
9812 fprintf (stream, wc_reg_names [INTVAL (x)]);
9813 }
9814 return;
9815
9997d19d
RE
9816 default:
9817 if (x == 0)
9818 abort ();
9819
9820 if (GET_CODE (x) == REG)
d5b7b3ae 9821 asm_fprintf (stream, "%r", REGNO (x));
9997d19d
RE
9822 else if (GET_CODE (x) == MEM)
9823 {
9824 output_memory_reference_mode = GET_MODE (x);
9825 output_address (XEXP (x, 0));
9826 }
9827 else if (GET_CODE (x) == CONST_DOUBLE)
9828 fprintf (stream, "#%s", fp_immediate_constant (x));
9829 else if (GET_CODE (x) == NEG)
6354dc9b 9830 abort (); /* This should never happen now. */
9997d19d
RE
9831 else
9832 {
9833 fputc ('#', stream);
9834 output_addr_const (stream, x);
9835 }
9836 }
9837}
cce8749e 9838\f
301d03af
RS
9839#ifndef AOF_ASSEMBLER
9840/* Target hook for assembling integer objects. The ARM version needs to
9841 handle word-sized values specially. */
301d03af 9842static bool
e32bac5b 9843arm_assemble_integer (rtx x, unsigned int size, int aligned_p)
301d03af
RS
9844{
9845 if (size == UNITS_PER_WORD && aligned_p)
9846 {
9847 fputs ("\t.word\t", asm_out_file);
9848 output_addr_const (asm_out_file, x);
9849
9850 /* Mark symbols as position independent. We only do this in the
9851 .text segment, not in the .data segment. */
9852 if (NEED_GOT_RELOC && flag_pic && making_const_table &&
9853 (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF))
9854 {
e26053d1 9855 if (GET_CODE (x) == SYMBOL_REF
14f583b8 9856 && (CONSTANT_POOL_ADDRESS_P (x)
94428622 9857 || SYMBOL_REF_LOCAL_P (x)))
301d03af
RS
9858 fputs ("(GOTOFF)", asm_out_file);
9859 else if (GET_CODE (x) == LABEL_REF)
9860 fputs ("(GOTOFF)", asm_out_file);
9861 else
9862 fputs ("(GOT)", asm_out_file);
9863 }
9864 fputc ('\n', asm_out_file);
9865 return true;
9866 }
1d6e90ac 9867
5a9335ef
NC
9868 if (VECTOR_MODE_SUPPORTED_P (GET_MODE (x)))
9869 {
9870 int i, units;
9871
9872 if (GET_CODE (x) != CONST_VECTOR)
9873 abort ();
9874
9875 units = CONST_VECTOR_NUNITS (x);
9876
9877 switch (GET_MODE (x))
9878 {
9879 case V2SImode: size = 4; break;
9880 case V4HImode: size = 2; break;
9881 case V8QImode: size = 1; break;
9882 default:
9883 abort ();
9884 }
9885
9886 for (i = 0; i < units; i++)
9887 {
9888 rtx elt;
9889
9890 elt = CONST_VECTOR_ELT (x, i);
9891 assemble_integer
9892 (elt, size, i == 0 ? BIGGEST_ALIGNMENT : size * BITS_PER_UNIT, 1);
9893 }
9894
9895 return true;
9896 }
9897
301d03af
RS
9898 return default_assemble_integer (x, size, aligned_p);
9899}
9900#endif
9901\f
cce8749e
CH
9902/* A finite state machine takes care of noticing whether or not instructions
9903 can be conditionally executed, and thus decrease execution time and code
9904 size by deleting branch instructions. The fsm is controlled by
9905 final_prescan_insn, and controls the actions of ASM_OUTPUT_OPCODE. */
9906
9907/* The state of the fsm controlling condition codes are:
9908 0: normal, do nothing special
9909 1: make ASM_OUTPUT_OPCODE not output this instruction
9910 2: make ASM_OUTPUT_OPCODE not output this instruction
9911 3: make instructions conditional
9912 4: make instructions conditional
9913
9914 State transitions (state->state by whom under condition):
9915 0 -> 1 final_prescan_insn if the `target' is a label
9916 0 -> 2 final_prescan_insn if the `target' is an unconditional branch
9917 1 -> 3 ASM_OUTPUT_OPCODE after not having output the conditional branch
9918 2 -> 4 ASM_OUTPUT_OPCODE after not having output the conditional branch
4977bab6 9919 3 -> 0 (*targetm.asm_out.internal_label) if the `target' label is reached
cce8749e
CH
9920 (the target label has CODE_LABEL_NUMBER equal to arm_target_label).
9921 4 -> 0 final_prescan_insn if the `target' unconditional branch is reached
9922 (the target insn is arm_target_insn).
9923
ff9940b0
RE
9924 If the jump clobbers the conditions then we use states 2 and 4.
9925
9926 A similar thing can be done with conditional return insns.
9927
cce8749e
CH
9928 XXX In case the `target' is an unconditional branch, this conditionalising
9929 of the instructions always reduces code size, but not always execution
9930 time. But then, I want to reduce the code size to somewhere near what
9931 /bin/cc produces. */
9932
cce8749e
CH
9933/* Returns the index of the ARM condition code string in
9934 `arm_condition_codes'. COMPARISON should be an rtx like
9935 `(eq (...) (...))'. */
84ed5e79 9936static enum arm_cond_code
e32bac5b 9937get_arm_condition_code (rtx comparison)
cce8749e 9938{
5165176d 9939 enum machine_mode mode = GET_MODE (XEXP (comparison, 0));
1d6e90ac
NC
9940 int code;
9941 enum rtx_code comp_code = GET_CODE (comparison);
5165176d
RE
9942
9943 if (GET_MODE_CLASS (mode) != MODE_CC)
84ed5e79 9944 mode = SELECT_CC_MODE (comp_code, XEXP (comparison, 0),
5165176d
RE
9945 XEXP (comparison, 1));
9946
9947 switch (mode)
cce8749e 9948 {
84ed5e79
RE
9949 case CC_DNEmode: code = ARM_NE; goto dominance;
9950 case CC_DEQmode: code = ARM_EQ; goto dominance;
9951 case CC_DGEmode: code = ARM_GE; goto dominance;
9952 case CC_DGTmode: code = ARM_GT; goto dominance;
9953 case CC_DLEmode: code = ARM_LE; goto dominance;
9954 case CC_DLTmode: code = ARM_LT; goto dominance;
9955 case CC_DGEUmode: code = ARM_CS; goto dominance;
9956 case CC_DGTUmode: code = ARM_HI; goto dominance;
9957 case CC_DLEUmode: code = ARM_LS; goto dominance;
9958 case CC_DLTUmode: code = ARM_CC;
9959
9960 dominance:
9961 if (comp_code != EQ && comp_code != NE)
9962 abort ();
9963
9964 if (comp_code == EQ)
9965 return ARM_INVERSE_CONDITION_CODE (code);
9966 return code;
9967
5165176d 9968 case CC_NOOVmode:
84ed5e79 9969 switch (comp_code)
5165176d 9970 {
84ed5e79
RE
9971 case NE: return ARM_NE;
9972 case EQ: return ARM_EQ;
9973 case GE: return ARM_PL;
9974 case LT: return ARM_MI;
5165176d
RE
9975 default: abort ();
9976 }
9977
9978 case CC_Zmode:
84ed5e79 9979 switch (comp_code)
5165176d 9980 {
84ed5e79
RE
9981 case NE: return ARM_NE;
9982 case EQ: return ARM_EQ;
5165176d
RE
9983 default: abort ();
9984 }
9985
defc0463
RE
9986 case CC_Nmode:
9987 switch (comp_code)
9988 {
9989 case NE: return ARM_MI;
9990 case EQ: return ARM_PL;
9991 default: abort ();
9992 }
9993
5165176d 9994 case CCFPEmode:
e45b72c4
RE
9995 case CCFPmode:
9996 /* These encodings assume that AC=1 in the FPA system control
9997 byte. This allows us to handle all cases except UNEQ and
9998 LTGT. */
84ed5e79
RE
9999 switch (comp_code)
10000 {
10001 case GE: return ARM_GE;
10002 case GT: return ARM_GT;
10003 case LE: return ARM_LS;
10004 case LT: return ARM_MI;
e45b72c4
RE
10005 case NE: return ARM_NE;
10006 case EQ: return ARM_EQ;
10007 case ORDERED: return ARM_VC;
10008 case UNORDERED: return ARM_VS;
10009 case UNLT: return ARM_LT;
10010 case UNLE: return ARM_LE;
10011 case UNGT: return ARM_HI;
10012 case UNGE: return ARM_PL;
10013 /* UNEQ and LTGT do not have a representation. */
10014 case UNEQ: /* Fall through. */
10015 case LTGT: /* Fall through. */
84ed5e79
RE
10016 default: abort ();
10017 }
10018
10019 case CC_SWPmode:
10020 switch (comp_code)
10021 {
10022 case NE: return ARM_NE;
10023 case EQ: return ARM_EQ;
10024 case GE: return ARM_LE;
10025 case GT: return ARM_LT;
10026 case LE: return ARM_GE;
10027 case LT: return ARM_GT;
10028 case GEU: return ARM_LS;
10029 case GTU: return ARM_CC;
10030 case LEU: return ARM_CS;
10031 case LTU: return ARM_HI;
10032 default: abort ();
10033 }
10034
bd9c7e23
RE
10035 case CC_Cmode:
10036 switch (comp_code)
10037 {
10038 case LTU: return ARM_CS;
10039 case GEU: return ARM_CC;
10040 default: abort ();
10041 }
10042
5165176d 10043 case CCmode:
84ed5e79 10044 switch (comp_code)
5165176d 10045 {
84ed5e79
RE
10046 case NE: return ARM_NE;
10047 case EQ: return ARM_EQ;
10048 case GE: return ARM_GE;
10049 case GT: return ARM_GT;
10050 case LE: return ARM_LE;
10051 case LT: return ARM_LT;
10052 case GEU: return ARM_CS;
10053 case GTU: return ARM_HI;
10054 case LEU: return ARM_LS;
10055 case LTU: return ARM_CC;
5165176d
RE
10056 default: abort ();
10057 }
10058
cce8749e
CH
10059 default: abort ();
10060 }
84ed5e79
RE
10061
10062 abort ();
f3bb6135 10063}
cce8749e 10064
cce8749e 10065void
e32bac5b 10066arm_final_prescan_insn (rtx insn)
cce8749e
CH
10067{
10068 /* BODY will hold the body of INSN. */
1d6e90ac 10069 rtx body = PATTERN (insn);
cce8749e
CH
10070
10071 /* This will be 1 if trying to repeat the trick, and things need to be
10072 reversed if it appears to fail. */
10073 int reverse = 0;
10074
ff9940b0
RE
10075 /* JUMP_CLOBBERS will be one implies that the conditions if a branch is
10076 taken are clobbered, even if the rtl suggests otherwise. It also
10077 means that we have to grub around within the jump expression to find
10078 out what the conditions are when the jump isn't taken. */
10079 int jump_clobbers = 0;
10080
6354dc9b 10081 /* If we start with a return insn, we only succeed if we find another one. */
ff9940b0
RE
10082 int seeking_return = 0;
10083
cce8749e
CH
10084 /* START_INSN will hold the insn from where we start looking. This is the
10085 first insn after the following code_label if REVERSE is true. */
10086 rtx start_insn = insn;
10087
10088 /* If in state 4, check if the target branch is reached, in order to
10089 change back to state 0. */
10090 if (arm_ccfsm_state == 4)
10091 {
10092 if (insn == arm_target_insn)
f5a1b0d2
NC
10093 {
10094 arm_target_insn = NULL;
10095 arm_ccfsm_state = 0;
10096 }
cce8749e
CH
10097 return;
10098 }
10099
10100 /* If in state 3, it is possible to repeat the trick, if this insn is an
10101 unconditional branch to a label, and immediately following this branch
10102 is the previous target label which is only used once, and the label this
10103 branch jumps to is not too far off. */
10104 if (arm_ccfsm_state == 3)
10105 {
10106 if (simplejump_p (insn))
10107 {
10108 start_insn = next_nonnote_insn (start_insn);
10109 if (GET_CODE (start_insn) == BARRIER)
10110 {
10111 /* XXX Isn't this always a barrier? */
10112 start_insn = next_nonnote_insn (start_insn);
10113 }
10114 if (GET_CODE (start_insn) == CODE_LABEL
10115 && CODE_LABEL_NUMBER (start_insn) == arm_target_label
10116 && LABEL_NUSES (start_insn) == 1)
10117 reverse = TRUE;
10118 else
10119 return;
10120 }
ff9940b0
RE
10121 else if (GET_CODE (body) == RETURN)
10122 {
10123 start_insn = next_nonnote_insn (start_insn);
10124 if (GET_CODE (start_insn) == BARRIER)
10125 start_insn = next_nonnote_insn (start_insn);
10126 if (GET_CODE (start_insn) == CODE_LABEL
10127 && CODE_LABEL_NUMBER (start_insn) == arm_target_label
10128 && LABEL_NUSES (start_insn) == 1)
10129 {
10130 reverse = TRUE;
10131 seeking_return = 1;
10132 }
10133 else
10134 return;
10135 }
cce8749e
CH
10136 else
10137 return;
10138 }
10139
10140 if (arm_ccfsm_state != 0 && !reverse)
10141 abort ();
10142 if (GET_CODE (insn) != JUMP_INSN)
10143 return;
10144
ddd5a7c1 10145 /* This jump might be paralleled with a clobber of the condition codes
ff9940b0
RE
10146 the jump should always come first */
10147 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
10148 body = XVECEXP (body, 0, 0);
10149
cce8749e
CH
10150 if (reverse
10151 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
10152 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
10153 {
bd9c7e23
RE
10154 int insns_skipped;
10155 int fail = FALSE, succeed = FALSE;
cce8749e
CH
10156 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
10157 int then_not_else = TRUE;
ff9940b0 10158 rtx this_insn = start_insn, label = 0;
cce8749e 10159
e45b72c4
RE
10160 /* If the jump cannot be done with one instruction, we cannot
10161 conditionally execute the instruction in the inverse case. */
ff9940b0 10162 if (get_attr_conds (insn) == CONDS_JUMP_CLOB)
5bbe2d40 10163 {
5bbe2d40
RE
10164 jump_clobbers = 1;
10165 return;
10166 }
ff9940b0 10167
cce8749e
CH
10168 /* Register the insn jumped to. */
10169 if (reverse)
ff9940b0
RE
10170 {
10171 if (!seeking_return)
10172 label = XEXP (SET_SRC (body), 0);
10173 }
cce8749e
CH
10174 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
10175 label = XEXP (XEXP (SET_SRC (body), 1), 0);
10176 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
10177 {
10178 label = XEXP (XEXP (SET_SRC (body), 2), 0);
10179 then_not_else = FALSE;
10180 }
ff9940b0
RE
10181 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
10182 seeking_return = 1;
10183 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
10184 {
10185 seeking_return = 1;
10186 then_not_else = FALSE;
10187 }
cce8749e
CH
10188 else
10189 abort ();
10190
10191 /* See how many insns this branch skips, and what kind of insns. If all
10192 insns are okay, and the label or unconditional branch to the same
10193 label is not too far away, succeed. */
10194 for (insns_skipped = 0;
b36ba79f 10195 !fail && !succeed && insns_skipped++ < max_insns_skipped;)
cce8749e
CH
10196 {
10197 rtx scanbody;
10198
10199 this_insn = next_nonnote_insn (this_insn);
10200 if (!this_insn)
10201 break;
10202
cce8749e
CH
10203 switch (GET_CODE (this_insn))
10204 {
10205 case CODE_LABEL:
10206 /* Succeed if it is the target label, otherwise fail since
10207 control falls in from somewhere else. */
10208 if (this_insn == label)
10209 {
ff9940b0
RE
10210 if (jump_clobbers)
10211 {
10212 arm_ccfsm_state = 2;
10213 this_insn = next_nonnote_insn (this_insn);
10214 }
10215 else
10216 arm_ccfsm_state = 1;
cce8749e
CH
10217 succeed = TRUE;
10218 }
10219 else
10220 fail = TRUE;
10221 break;
10222
ff9940b0 10223 case BARRIER:
cce8749e 10224 /* Succeed if the following insn is the target label.
ff9940b0
RE
10225 Otherwise fail.
10226 If return insns are used then the last insn in a function
6354dc9b 10227 will be a barrier. */
cce8749e 10228 this_insn = next_nonnote_insn (this_insn);
ff9940b0 10229 if (this_insn && this_insn == label)
cce8749e 10230 {
ff9940b0
RE
10231 if (jump_clobbers)
10232 {
10233 arm_ccfsm_state = 2;
10234 this_insn = next_nonnote_insn (this_insn);
10235 }
10236 else
10237 arm_ccfsm_state = 1;
cce8749e
CH
10238 succeed = TRUE;
10239 }
10240 else
10241 fail = TRUE;
10242 break;
10243
ff9940b0 10244 case CALL_INSN:
2b835d68 10245 /* If using 32-bit addresses the cc is not preserved over
914a3b8c 10246 calls. */
2b835d68 10247 if (TARGET_APCS_32)
bd9c7e23
RE
10248 {
10249 /* Succeed if the following insn is the target label,
10250 or if the following two insns are a barrier and
10251 the target label. */
10252 this_insn = next_nonnote_insn (this_insn);
10253 if (this_insn && GET_CODE (this_insn) == BARRIER)
10254 this_insn = next_nonnote_insn (this_insn);
10255
10256 if (this_insn && this_insn == label
b36ba79f 10257 && insns_skipped < max_insns_skipped)
bd9c7e23
RE
10258 {
10259 if (jump_clobbers)
10260 {
10261 arm_ccfsm_state = 2;
10262 this_insn = next_nonnote_insn (this_insn);
10263 }
10264 else
10265 arm_ccfsm_state = 1;
10266 succeed = TRUE;
10267 }
10268 else
10269 fail = TRUE;
10270 }
ff9940b0 10271 break;
2b835d68 10272
cce8749e
CH
10273 case JUMP_INSN:
10274 /* If this is an unconditional branch to the same label, succeed.
10275 If it is to another label, do nothing. If it is conditional,
10276 fail. */
e32bac5b
RE
10277 /* XXX Probably, the tests for SET and the PC are
10278 unnecessary. */
cce8749e 10279
ed4c4348 10280 scanbody = PATTERN (this_insn);
ff9940b0
RE
10281 if (GET_CODE (scanbody) == SET
10282 && GET_CODE (SET_DEST (scanbody)) == PC)
cce8749e
CH
10283 {
10284 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
10285 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
10286 {
10287 arm_ccfsm_state = 2;
10288 succeed = TRUE;
10289 }
10290 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
10291 fail = TRUE;
10292 }
b36ba79f
RE
10293 /* Fail if a conditional return is undesirable (eg on a
10294 StrongARM), but still allow this if optimizing for size. */
10295 else if (GET_CODE (scanbody) == RETURN
a72d4945 10296 && !use_return_insn (TRUE, NULL)
5895f793 10297 && !optimize_size)
b36ba79f 10298 fail = TRUE;
ff9940b0
RE
10299 else if (GET_CODE (scanbody) == RETURN
10300 && seeking_return)
10301 {
10302 arm_ccfsm_state = 2;
10303 succeed = TRUE;
10304 }
10305 else if (GET_CODE (scanbody) == PARALLEL)
10306 {
10307 switch (get_attr_conds (this_insn))
10308 {
10309 case CONDS_NOCOND:
10310 break;
10311 default:
10312 fail = TRUE;
10313 break;
10314 }
10315 }
4e67550b
RE
10316 else
10317 fail = TRUE; /* Unrecognized jump (eg epilogue). */
10318
cce8749e
CH
10319 break;
10320
10321 case INSN:
ff9940b0
RE
10322 /* Instructions using or affecting the condition codes make it
10323 fail. */
ed4c4348 10324 scanbody = PATTERN (this_insn);
5895f793
RE
10325 if (!(GET_CODE (scanbody) == SET
10326 || GET_CODE (scanbody) == PARALLEL)
74641843 10327 || get_attr_conds (this_insn) != CONDS_NOCOND)
cce8749e 10328 fail = TRUE;
9b6b54e2
NC
10329
10330 /* A conditional cirrus instruction must be followed by
10331 a non Cirrus instruction. However, since we
10332 conditionalize instructions in this function and by
10333 the time we get here we can't add instructions
10334 (nops), because shorten_branches() has already been
10335 called, we will disable conditionalizing Cirrus
10336 instructions to be safe. */
10337 if (GET_CODE (scanbody) != USE
10338 && GET_CODE (scanbody) != CLOBBER
f0375c66 10339 && get_attr_cirrus (this_insn) != CIRRUS_NOT)
9b6b54e2 10340 fail = TRUE;
cce8749e
CH
10341 break;
10342
10343 default:
10344 break;
10345 }
10346 }
10347 if (succeed)
10348 {
ff9940b0 10349 if ((!seeking_return) && (arm_ccfsm_state == 1 || reverse))
cce8749e 10350 arm_target_label = CODE_LABEL_NUMBER (label);
ff9940b0
RE
10351 else if (seeking_return || arm_ccfsm_state == 2)
10352 {
10353 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
10354 {
10355 this_insn = next_nonnote_insn (this_insn);
10356 if (this_insn && (GET_CODE (this_insn) == BARRIER
10357 || GET_CODE (this_insn) == CODE_LABEL))
10358 abort ();
10359 }
10360 if (!this_insn)
10361 {
10362 /* Oh, dear! we ran off the end.. give up */
df4ae160 10363 recog (PATTERN (insn), insn, NULL);
ff9940b0 10364 arm_ccfsm_state = 0;
abaa26e5 10365 arm_target_insn = NULL;
ff9940b0
RE
10366 return;
10367 }
10368 arm_target_insn = this_insn;
10369 }
cce8749e
CH
10370 else
10371 abort ();
ff9940b0
RE
10372 if (jump_clobbers)
10373 {
10374 if (reverse)
10375 abort ();
10376 arm_current_cc =
10377 get_arm_condition_code (XEXP (XEXP (XEXP (SET_SRC (body),
10378 0), 0), 1));
10379 if (GET_CODE (XEXP (XEXP (SET_SRC (body), 0), 0)) == AND)
10380 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
10381 if (GET_CODE (XEXP (SET_SRC (body), 0)) == NE)
10382 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
10383 }
10384 else
10385 {
10386 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
10387 what it was. */
10388 if (!reverse)
10389 arm_current_cc = get_arm_condition_code (XEXP (SET_SRC (body),
10390 0));
10391 }
cce8749e 10392
cce8749e
CH
10393 if (reverse || then_not_else)
10394 arm_current_cc = ARM_INVERSE_CONDITION_CODE (arm_current_cc);
10395 }
d5b7b3ae 10396
1ccbefce 10397 /* Restore recog_data (getting the attributes of other insns can
ff9940b0 10398 destroy this array, but final.c assumes that it remains intact
ddd5a7c1 10399 across this call; since the insn has been recognized already we
b020fd92 10400 call recog direct). */
df4ae160 10401 recog (PATTERN (insn), insn, NULL);
cce8749e 10402 }
f3bb6135 10403}
cce8749e 10404
4b02997f
NC
10405/* Returns true if REGNO is a valid register
10406 for holding a quantity of tyoe MODE. */
4b02997f 10407int
e32bac5b 10408arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
4b02997f
NC
10409{
10410 if (GET_MODE_CLASS (mode) == MODE_CC)
10411 return regno == CC_REGNUM;
10412
10413 if (TARGET_THUMB)
10414 /* For the Thumb we only allow values bigger than SImode in
10415 registers 0 - 6, so that there is always a second low
10416 register available to hold the upper part of the value.
10417 We probably we ought to ensure that the register is the
10418 start of an even numbered register pair. */
e9d7b180 10419 return (ARM_NUM_REGS (mode) < 2) || (regno < LAST_LO_REGNUM);
4b02997f 10420
9b6b54e2
NC
10421 if (IS_CIRRUS_REGNUM (regno))
10422 /* We have outlawed SI values in Cirrus registers because they
10423 reside in the lower 32 bits, but SF values reside in the
10424 upper 32 bits. This causes gcc all sorts of grief. We can't
10425 even split the registers into pairs because Cirrus SI values
10426 get sign extended to 64bits-- aldyh. */
10427 return (GET_MODE_CLASS (mode) == MODE_FLOAT) || (mode == DImode);
10428
5a9335ef
NC
10429 if (IS_IWMMXT_GR_REGNUM (regno))
10430 return mode == SImode;
10431
10432 if (IS_IWMMXT_REGNUM (regno))
10433 return VALID_IWMMXT_REG_MODE (mode);
10434
4b02997f 10435 if (regno <= LAST_ARM_REGNUM)
9a9f7594 10436 /* We allow any value to be stored in the general registers. */
3cb66fd7 10437 return 1;
4b02997f
NC
10438
10439 if ( regno == FRAME_POINTER_REGNUM
10440 || regno == ARG_POINTER_REGNUM)
10441 /* We only allow integers in the fake hard registers. */
10442 return GET_MODE_CLASS (mode) == MODE_INT;
10443
3b684012 10444 /* The only registers left are the FPA registers
4b02997f
NC
10445 which we only allow to hold FP values. */
10446 return GET_MODE_CLASS (mode) == MODE_FLOAT
10447 && regno >= FIRST_ARM_FP_REGNUM
10448 && regno <= LAST_ARM_FP_REGNUM;
10449}
10450
d5b7b3ae 10451int
e32bac5b 10452arm_regno_class (int regno)
d5b7b3ae
RE
10453{
10454 if (TARGET_THUMB)
10455 {
10456 if (regno == STACK_POINTER_REGNUM)
10457 return STACK_REG;
10458 if (regno == CC_REGNUM)
10459 return CC_REG;
10460 if (regno < 8)
10461 return LO_REGS;
10462 return HI_REGS;
10463 }
10464
10465 if ( regno <= LAST_ARM_REGNUM
10466 || regno == FRAME_POINTER_REGNUM
10467 || regno == ARG_POINTER_REGNUM)
10468 return GENERAL_REGS;
10469
10470 if (regno == CC_REGNUM)
10471 return NO_REGS;
10472
9b6b54e2
NC
10473 if (IS_CIRRUS_REGNUM (regno))
10474 return CIRRUS_REGS;
10475
5a9335ef
NC
10476 if (IS_IWMMXT_REGNUM (regno))
10477 return IWMMXT_REGS;
10478
e99faaaa
ILT
10479 if (IS_IWMMXT_GR_REGNUM (regno))
10480 return IWMMXT_GR_REGS;
10481
3b684012 10482 return FPA_REGS;
d5b7b3ae
RE
10483}
10484
10485/* Handle a special case when computing the offset
10486 of an argument from the frame pointer. */
10487int
e32bac5b 10488arm_debugger_arg_offset (int value, rtx addr)
d5b7b3ae
RE
10489{
10490 rtx insn;
10491
10492 /* We are only interested if dbxout_parms() failed to compute the offset. */
10493 if (value != 0)
10494 return 0;
10495
10496 /* We can only cope with the case where the address is held in a register. */
10497 if (GET_CODE (addr) != REG)
10498 return 0;
10499
10500 /* If we are using the frame pointer to point at the argument, then
10501 an offset of 0 is correct. */
cd2b33d0 10502 if (REGNO (addr) == (unsigned) HARD_FRAME_POINTER_REGNUM)
d5b7b3ae
RE
10503 return 0;
10504
10505 /* If we are using the stack pointer to point at the
10506 argument, then an offset of 0 is correct. */
5895f793 10507 if ((TARGET_THUMB || !frame_pointer_needed)
d5b7b3ae
RE
10508 && REGNO (addr) == SP_REGNUM)
10509 return 0;
10510
10511 /* Oh dear. The argument is pointed to by a register rather
10512 than being held in a register, or being stored at a known
10513 offset from the frame pointer. Since GDB only understands
10514 those two kinds of argument we must translate the address
10515 held in the register into an offset from the frame pointer.
10516 We do this by searching through the insns for the function
10517 looking to see where this register gets its value. If the
4912a07c 10518 register is initialized from the frame pointer plus an offset
d5b7b3ae
RE
10519 then we are in luck and we can continue, otherwise we give up.
10520
10521 This code is exercised by producing debugging information
10522 for a function with arguments like this:
10523
10524 double func (double a, double b, int c, double d) {return d;}
10525
10526 Without this code the stab for parameter 'd' will be set to
10527 an offset of 0 from the frame pointer, rather than 8. */
10528
10529 /* The if() statement says:
10530
10531 If the insn is a normal instruction
10532 and if the insn is setting the value in a register
10533 and if the register being set is the register holding the address of the argument
10534 and if the address is computing by an addition
10535 that involves adding to a register
10536 which is the frame pointer
10537 a constant integer
10538
10539 then... */
10540
10541 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
10542 {
10543 if ( GET_CODE (insn) == INSN
10544 && GET_CODE (PATTERN (insn)) == SET
10545 && REGNO (XEXP (PATTERN (insn), 0)) == REGNO (addr)
10546 && GET_CODE (XEXP (PATTERN (insn), 1)) == PLUS
10547 && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 0)) == REG
cd2b33d0 10548 && REGNO (XEXP (XEXP (PATTERN (insn), 1), 0)) == (unsigned) HARD_FRAME_POINTER_REGNUM
d5b7b3ae
RE
10549 && GET_CODE (XEXP (XEXP (PATTERN (insn), 1), 1)) == CONST_INT
10550 )
10551 {
10552 value = INTVAL (XEXP (XEXP (PATTERN (insn), 1), 1));
10553
10554 break;
10555 }
10556 }
10557
10558 if (value == 0)
10559 {
10560 debug_rtx (addr);
c725bd79 10561 warning ("unable to compute real location of stacked parameter");
d5b7b3ae
RE
10562 value = 8; /* XXX magic hack */
10563 }
10564
10565 return value;
10566}
d5b7b3ae 10567\f
5a9335ef
NC
10568#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
10569 do \
10570 { \
10571 if ((MASK) & insn_flags) \
10572 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE); \
10573 } \
10574 while (0)
10575
10576struct builtin_description
10577{
10578 const unsigned int mask;
10579 const enum insn_code icode;
10580 const char * const name;
10581 const enum arm_builtins code;
10582 const enum rtx_code comparison;
10583 const unsigned int flag;
10584};
10585
10586static const struct builtin_description bdesc_2arg[] =
10587{
10588#define IWMMXT_BUILTIN(code, string, builtin) \
10589 { FL_IWMMXT, CODE_FOR_##code, "__builtin_arm_" string, \
10590 ARM_BUILTIN_##builtin, 0, 0 },
10591
10592 IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
10593 IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
10594 IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
10595 IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
10596 IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
10597 IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
10598 IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
10599 IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
10600 IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
10601 IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
10602 IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
10603 IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
10604 IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
10605 IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
10606 IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
10607 IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
10608 IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
10609 IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
10610 IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
10611 IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsh", WMULSH)
10612 IWMMXT_BUILTIN (umulv4hi3_highpart, "wmuluh", WMULUH)
10613 IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
10614 IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
10615 IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
10616 IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
10617 IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
10618 IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
10619 IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
10620 IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
10621 IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
10622 IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
10623 IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
10624 IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
10625 IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
10626 IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
10627 IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
10628 IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
10629 IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
10630 IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
10631 IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
10632 IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
10633 IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
10634 IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
10635 IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
10636 IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
10637 IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
10638 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
10639 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
10640 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
10641 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
10642 IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
10643 IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
10644 IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
10645 IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
10646 IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
10647 IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
10648 IWMMXT_BUILTIN (iwmmxt_wmadds, "wmadds", WMADDS)
10649 IWMMXT_BUILTIN (iwmmxt_wmaddu, "wmaddu", WMADDU)
10650
10651#define IWMMXT_BUILTIN2(code, builtin) \
10652 { FL_IWMMXT, CODE_FOR_##code, NULL, ARM_BUILTIN_##builtin, 0, 0 },
10653
10654 IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
10655 IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
10656 IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
10657 IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
10658 IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
10659 IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
10660 IWMMXT_BUILTIN2 (ashlv4hi3_di, WSLLH)
10661 IWMMXT_BUILTIN2 (ashlv4hi3, WSLLHI)
10662 IWMMXT_BUILTIN2 (ashlv2si3_di, WSLLW)
10663 IWMMXT_BUILTIN2 (ashlv2si3, WSLLWI)
10664 IWMMXT_BUILTIN2 (ashldi3_di, WSLLD)
10665 IWMMXT_BUILTIN2 (ashldi3_iwmmxt, WSLLDI)
10666 IWMMXT_BUILTIN2 (lshrv4hi3_di, WSRLH)
10667 IWMMXT_BUILTIN2 (lshrv4hi3, WSRLHI)
10668 IWMMXT_BUILTIN2 (lshrv2si3_di, WSRLW)
10669 IWMMXT_BUILTIN2 (lshrv2si3, WSRLWI)
10670 IWMMXT_BUILTIN2 (lshrdi3_di, WSRLD)
10671 IWMMXT_BUILTIN2 (lshrdi3, WSRLDI)
10672 IWMMXT_BUILTIN2 (ashrv4hi3_di, WSRAH)
10673 IWMMXT_BUILTIN2 (ashrv4hi3, WSRAHI)
10674 IWMMXT_BUILTIN2 (ashrv2si3_di, WSRAW)
10675 IWMMXT_BUILTIN2 (ashrv2si3, WSRAWI)
10676 IWMMXT_BUILTIN2 (ashrdi3_di, WSRAD)
10677 IWMMXT_BUILTIN2 (ashrdi3, WSRADI)
10678 IWMMXT_BUILTIN2 (rorv4hi3_di, WRORH)
10679 IWMMXT_BUILTIN2 (rorv4hi3, WRORHI)
10680 IWMMXT_BUILTIN2 (rorv2si3_di, WRORW)
10681 IWMMXT_BUILTIN2 (rorv2si3, WRORWI)
10682 IWMMXT_BUILTIN2 (rordi3_di, WRORD)
10683 IWMMXT_BUILTIN2 (rordi3, WRORDI)
10684 IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
10685 IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
10686};
10687
10688static const struct builtin_description bdesc_1arg[] =
10689{
10690 IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
10691 IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
10692 IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
10693 IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
10694 IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
10695 IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
10696 IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
10697 IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
10698 IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
10699 IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
10700 IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
10701 IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
10702 IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
10703 IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
10704 IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
10705 IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
10706 IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
10707 IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
10708};
10709
10710/* Set up all the iWMMXt builtins. This is
10711 not called if TARGET_IWMMXT is zero. */
10712
10713static void
10714arm_init_iwmmxt_builtins (void)
10715{
10716 const struct builtin_description * d;
10717 size_t i;
10718 tree endlink = void_list_node;
10719
10720 tree int_ftype_int
10721 = build_function_type (integer_type_node,
10722 tree_cons (NULL_TREE, integer_type_node, endlink));
10723 tree v8qi_ftype_v8qi_v8qi_int
10724 = build_function_type (V8QI_type_node,
10725 tree_cons (NULL_TREE, V8QI_type_node,
10726 tree_cons (NULL_TREE, V8QI_type_node,
10727 tree_cons (NULL_TREE,
10728 integer_type_node,
10729 endlink))));
10730 tree v4hi_ftype_v4hi_int
10731 = build_function_type (V4HI_type_node,
10732 tree_cons (NULL_TREE, V4HI_type_node,
10733 tree_cons (NULL_TREE, integer_type_node,
10734 endlink)));
10735 tree v2si_ftype_v2si_int
10736 = build_function_type (V2SI_type_node,
10737 tree_cons (NULL_TREE, V2SI_type_node,
10738 tree_cons (NULL_TREE, integer_type_node,
10739 endlink)));
10740 tree v2si_ftype_di_di
10741 = build_function_type (V2SI_type_node,
10742 tree_cons (NULL_TREE, long_long_integer_type_node,
10743 tree_cons (NULL_TREE, long_long_integer_type_node,
10744 endlink)));
10745 tree di_ftype_di_int
10746 = build_function_type (long_long_integer_type_node,
10747 tree_cons (NULL_TREE, long_long_integer_type_node,
10748 tree_cons (NULL_TREE, integer_type_node,
10749 endlink)));
10750 tree di_ftype_di_int_int
10751 = build_function_type (long_long_integer_type_node,
10752 tree_cons (NULL_TREE, long_long_integer_type_node,
10753 tree_cons (NULL_TREE, integer_type_node,
10754 tree_cons (NULL_TREE,
10755 integer_type_node,
10756 endlink))));
10757 tree int_ftype_v8qi
10758 = build_function_type (integer_type_node,
10759 tree_cons (NULL_TREE, V8QI_type_node,
10760 endlink));
10761 tree int_ftype_v4hi
10762 = build_function_type (integer_type_node,
10763 tree_cons (NULL_TREE, V4HI_type_node,
10764 endlink));
10765 tree int_ftype_v2si
10766 = build_function_type (integer_type_node,
10767 tree_cons (NULL_TREE, V2SI_type_node,
10768 endlink));
10769 tree int_ftype_v8qi_int
10770 = build_function_type (integer_type_node,
10771 tree_cons (NULL_TREE, V8QI_type_node,
10772 tree_cons (NULL_TREE, integer_type_node,
10773 endlink)));
10774 tree int_ftype_v4hi_int
10775 = build_function_type (integer_type_node,
10776 tree_cons (NULL_TREE, V4HI_type_node,
10777 tree_cons (NULL_TREE, integer_type_node,
10778 endlink)));
10779 tree int_ftype_v2si_int
10780 = build_function_type (integer_type_node,
10781 tree_cons (NULL_TREE, V2SI_type_node,
10782 tree_cons (NULL_TREE, integer_type_node,
10783 endlink)));
10784 tree v8qi_ftype_v8qi_int_int
10785 = build_function_type (V8QI_type_node,
10786 tree_cons (NULL_TREE, V8QI_type_node,
10787 tree_cons (NULL_TREE, integer_type_node,
10788 tree_cons (NULL_TREE,
10789 integer_type_node,
10790 endlink))));
10791 tree v4hi_ftype_v4hi_int_int
10792 = build_function_type (V4HI_type_node,
10793 tree_cons (NULL_TREE, V4HI_type_node,
10794 tree_cons (NULL_TREE, integer_type_node,
10795 tree_cons (NULL_TREE,
10796 integer_type_node,
10797 endlink))));
10798 tree v2si_ftype_v2si_int_int
10799 = build_function_type (V2SI_type_node,
10800 tree_cons (NULL_TREE, V2SI_type_node,
10801 tree_cons (NULL_TREE, integer_type_node,
10802 tree_cons (NULL_TREE,
10803 integer_type_node,
10804 endlink))));
10805 /* Miscellaneous. */
10806 tree v8qi_ftype_v4hi_v4hi
10807 = build_function_type (V8QI_type_node,
10808 tree_cons (NULL_TREE, V4HI_type_node,
10809 tree_cons (NULL_TREE, V4HI_type_node,
10810 endlink)));
10811 tree v4hi_ftype_v2si_v2si
10812 = build_function_type (V4HI_type_node,
10813 tree_cons (NULL_TREE, V2SI_type_node,
10814 tree_cons (NULL_TREE, V2SI_type_node,
10815 endlink)));
10816 tree v2si_ftype_v4hi_v4hi
10817 = build_function_type (V2SI_type_node,
10818 tree_cons (NULL_TREE, V4HI_type_node,
10819 tree_cons (NULL_TREE, V4HI_type_node,
10820 endlink)));
10821 tree v2si_ftype_v8qi_v8qi
10822 = build_function_type (V2SI_type_node,
10823 tree_cons (NULL_TREE, V8QI_type_node,
10824 tree_cons (NULL_TREE, V8QI_type_node,
10825 endlink)));
10826 tree v4hi_ftype_v4hi_di
10827 = build_function_type (V4HI_type_node,
10828 tree_cons (NULL_TREE, V4HI_type_node,
10829 tree_cons (NULL_TREE,
10830 long_long_integer_type_node,
10831 endlink)));
10832 tree v2si_ftype_v2si_di
10833 = build_function_type (V2SI_type_node,
10834 tree_cons (NULL_TREE, V2SI_type_node,
10835 tree_cons (NULL_TREE,
10836 long_long_integer_type_node,
10837 endlink)));
10838 tree void_ftype_int_int
10839 = build_function_type (void_type_node,
10840 tree_cons (NULL_TREE, integer_type_node,
10841 tree_cons (NULL_TREE, integer_type_node,
10842 endlink)));
10843 tree di_ftype_void
10844 = build_function_type (long_long_unsigned_type_node, endlink);
10845 tree di_ftype_v8qi
10846 = build_function_type (long_long_integer_type_node,
10847 tree_cons (NULL_TREE, V8QI_type_node,
10848 endlink));
10849 tree di_ftype_v4hi
10850 = build_function_type (long_long_integer_type_node,
10851 tree_cons (NULL_TREE, V4HI_type_node,
10852 endlink));
10853 tree di_ftype_v2si
10854 = build_function_type (long_long_integer_type_node,
10855 tree_cons (NULL_TREE, V2SI_type_node,
10856 endlink));
10857 tree v2si_ftype_v4hi
10858 = build_function_type (V2SI_type_node,
10859 tree_cons (NULL_TREE, V4HI_type_node,
10860 endlink));
10861 tree v4hi_ftype_v8qi
10862 = build_function_type (V4HI_type_node,
10863 tree_cons (NULL_TREE, V8QI_type_node,
10864 endlink));
10865
10866 tree di_ftype_di_v4hi_v4hi
10867 = build_function_type (long_long_unsigned_type_node,
10868 tree_cons (NULL_TREE,
10869 long_long_unsigned_type_node,
10870 tree_cons (NULL_TREE, V4HI_type_node,
10871 tree_cons (NULL_TREE,
10872 V4HI_type_node,
10873 endlink))));
10874
10875 tree di_ftype_v4hi_v4hi
10876 = build_function_type (long_long_unsigned_type_node,
10877 tree_cons (NULL_TREE, V4HI_type_node,
10878 tree_cons (NULL_TREE, V4HI_type_node,
10879 endlink)));
10880
10881 /* Normal vector binops. */
10882 tree v8qi_ftype_v8qi_v8qi
10883 = build_function_type (V8QI_type_node,
10884 tree_cons (NULL_TREE, V8QI_type_node,
10885 tree_cons (NULL_TREE, V8QI_type_node,
10886 endlink)));
10887 tree v4hi_ftype_v4hi_v4hi
10888 = build_function_type (V4HI_type_node,
10889 tree_cons (NULL_TREE, V4HI_type_node,
10890 tree_cons (NULL_TREE, V4HI_type_node,
10891 endlink)));
10892 tree v2si_ftype_v2si_v2si
10893 = build_function_type (V2SI_type_node,
10894 tree_cons (NULL_TREE, V2SI_type_node,
10895 tree_cons (NULL_TREE, V2SI_type_node,
10896 endlink)));
10897 tree di_ftype_di_di
10898 = build_function_type (long_long_unsigned_type_node,
10899 tree_cons (NULL_TREE, long_long_unsigned_type_node,
10900 tree_cons (NULL_TREE,
10901 long_long_unsigned_type_node,
10902 endlink)));
10903
10904 /* Add all builtins that are more or less simple operations on two
10905 operands. */
e97a46ce 10906 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5a9335ef
NC
10907 {
10908 /* Use one of the operands; the target can have a different mode for
10909 mask-generating compares. */
10910 enum machine_mode mode;
10911 tree type;
10912
10913 if (d->name == 0)
10914 continue;
10915
10916 mode = insn_data[d->icode].operand[1].mode;
10917
10918 switch (mode)
10919 {
10920 case V8QImode:
10921 type = v8qi_ftype_v8qi_v8qi;
10922 break;
10923 case V4HImode:
10924 type = v4hi_ftype_v4hi_v4hi;
10925 break;
10926 case V2SImode:
10927 type = v2si_ftype_v2si_v2si;
10928 break;
10929 case DImode:
10930 type = di_ftype_di_di;
10931 break;
10932
10933 default:
10934 abort ();
10935 }
10936
10937 def_mbuiltin (d->mask, d->name, type, d->code);
10938 }
10939
10940 /* Add the remaining MMX insns with somewhat more complicated types. */
10941 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wzero", di_ftype_void, ARM_BUILTIN_WZERO);
10942 def_mbuiltin (FL_IWMMXT, "__builtin_arm_setwcx", void_ftype_int_int, ARM_BUILTIN_SETWCX);
10943 def_mbuiltin (FL_IWMMXT, "__builtin_arm_getwcx", int_ftype_int, ARM_BUILTIN_GETWCX);
10944
10945 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSLLH);
10946 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllw", v2si_ftype_v2si_di, ARM_BUILTIN_WSLLW);
10947 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslld", di_ftype_di_di, ARM_BUILTIN_WSLLD);
10948 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSLLHI);
10949 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsllwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSLLWI);
10950 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wslldi", di_ftype_di_int, ARM_BUILTIN_WSLLDI);
10951
10952 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRLH);
10953 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRLW);
10954 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrld", di_ftype_di_di, ARM_BUILTIN_WSRLD);
10955 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRLHI);
10956 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrlwi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRLWI);
10957 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrldi", di_ftype_di_int, ARM_BUILTIN_WSRLDI);
10958
10959 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrah", v4hi_ftype_v4hi_di, ARM_BUILTIN_WSRAH);
10960 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsraw", v2si_ftype_v2si_di, ARM_BUILTIN_WSRAW);
10961 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrad", di_ftype_di_di, ARM_BUILTIN_WSRAD);
10962 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrahi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSRAHI);
10963 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsrawi", v2si_ftype_v2si_int, ARM_BUILTIN_WSRAWI);
10964 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsradi", di_ftype_di_int, ARM_BUILTIN_WSRADI);
10965
10966 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorh", v4hi_ftype_v4hi_di, ARM_BUILTIN_WRORH);
10967 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorw", v2si_ftype_v2si_di, ARM_BUILTIN_WRORW);
10968 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrord", di_ftype_di_di, ARM_BUILTIN_WRORD);
10969 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorhi", v4hi_ftype_v4hi_int, ARM_BUILTIN_WRORHI);
10970 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrorwi", v2si_ftype_v2si_int, ARM_BUILTIN_WRORWI);
10971 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wrordi", di_ftype_di_int, ARM_BUILTIN_WRORDI);
10972
10973 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wshufh", v4hi_ftype_v4hi_int, ARM_BUILTIN_WSHUFH);
10974
10975 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadb", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADB);
10976 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadh", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADH);
10977 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadbz", v2si_ftype_v8qi_v8qi, ARM_BUILTIN_WSADBZ);
10978 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wsadhz", v2si_ftype_v4hi_v4hi, ARM_BUILTIN_WSADHZ);
10979
10980 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsb", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMSB);
10981 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMSH);
10982 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmsw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMSW);
10983 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmub", int_ftype_v8qi_int, ARM_BUILTIN_TEXTRMUB);
10984 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuh", int_ftype_v4hi_int, ARM_BUILTIN_TEXTRMUH);
10985 def_mbuiltin (FL_IWMMXT, "__builtin_arm_textrmuw", int_ftype_v2si_int, ARM_BUILTIN_TEXTRMUW);
10986 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrb", v8qi_ftype_v8qi_int_int, ARM_BUILTIN_TINSRB);
10987 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrh", v4hi_ftype_v4hi_int_int, ARM_BUILTIN_TINSRH);
10988 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tinsrw", v2si_ftype_v2si_int_int, ARM_BUILTIN_TINSRW);
10989
10990 def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccb", di_ftype_v8qi, ARM_BUILTIN_WACCB);
10991 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wacch", di_ftype_v4hi, ARM_BUILTIN_WACCH);
10992 def_mbuiltin (FL_IWMMXT, "__builtin_arm_waccw", di_ftype_v2si, ARM_BUILTIN_WACCW);
10993
10994 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskb", int_ftype_v8qi, ARM_BUILTIN_TMOVMSKB);
10995 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskh", int_ftype_v4hi, ARM_BUILTIN_TMOVMSKH);
10996 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmovmskw", int_ftype_v2si, ARM_BUILTIN_TMOVMSKW);
10997
10998 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhss", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHSS);
10999 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackhus", v8qi_ftype_v4hi_v4hi, ARM_BUILTIN_WPACKHUS);
11000 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwus", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWUS);
11001 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackwss", v4hi_ftype_v2si_v2si, ARM_BUILTIN_WPACKWSS);
11002 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdus", v2si_ftype_di_di, ARM_BUILTIN_WPACKDUS);
11003 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wpackdss", v2si_ftype_di_di, ARM_BUILTIN_WPACKDSS);
11004
11005 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHUB);
11006 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHUH);
11007 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehuw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHUW);
11008 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKEHSB);
11009 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKEHSH);
11010 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckehsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKEHSW);
11011 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelub", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELUB);
11012 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELUH);
11013 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckeluw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELUW);
11014 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsb", v4hi_ftype_v8qi, ARM_BUILTIN_WUNPCKELSB);
11015 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsh", v2si_ftype_v4hi, ARM_BUILTIN_WUNPCKELSH);
11016 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wunpckelsw", di_ftype_v2si, ARM_BUILTIN_WUNPCKELSW);
11017
11018 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacs", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACS);
11019 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacsz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACSZ);
11020 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacu", di_ftype_di_v4hi_v4hi, ARM_BUILTIN_WMACU);
11021 def_mbuiltin (FL_IWMMXT, "__builtin_arm_wmacuz", di_ftype_v4hi_v4hi, ARM_BUILTIN_WMACUZ);
11022
11023 def_mbuiltin (FL_IWMMXT, "__builtin_arm_walign", v8qi_ftype_v8qi_v8qi_int, ARM_BUILTIN_WALIGN);
11024 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmia", di_ftype_di_int_int, ARM_BUILTIN_TMIA);
11025 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiaph", di_ftype_di_int_int, ARM_BUILTIN_TMIAPH);
11026 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabb", di_ftype_di_int_int, ARM_BUILTIN_TMIABB);
11027 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiabt", di_ftype_di_int_int, ARM_BUILTIN_TMIABT);
11028 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatb", di_ftype_di_int_int, ARM_BUILTIN_TMIATB);
11029 def_mbuiltin (FL_IWMMXT, "__builtin_arm_tmiatt", di_ftype_di_int_int, ARM_BUILTIN_TMIATT);
11030}
11031
11032static void
11033arm_init_builtins (void)
11034{
11035 if (TARGET_REALLY_IWMMXT)
11036 arm_init_iwmmxt_builtins ();
11037}
11038
11039/* Errors in the source file can cause expand_expr to return const0_rtx
11040 where we expect a vector. To avoid crashing, use one of the vector
11041 clear instructions. */
11042
11043static rtx
11044safe_vector_operand (rtx x, enum machine_mode mode)
11045{
11046 if (x != const0_rtx)
11047 return x;
11048 x = gen_reg_rtx (mode);
11049
11050 emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
11051 : gen_rtx_SUBREG (DImode, x, 0)));
11052 return x;
11053}
11054
11055/* Subroutine of arm_expand_builtin to take care of binop insns. */
11056
11057static rtx
11058arm_expand_binop_builtin (enum insn_code icode,
11059 tree arglist, rtx target)
11060{
11061 rtx pat;
11062 tree arg0 = TREE_VALUE (arglist);
11063 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11064 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11065 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11066 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11067 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11068 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
11069
11070 if (VECTOR_MODE_P (mode0))
11071 op0 = safe_vector_operand (op0, mode0);
11072 if (VECTOR_MODE_P (mode1))
11073 op1 = safe_vector_operand (op1, mode1);
11074
11075 if (! target
11076 || GET_MODE (target) != tmode
11077 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11078 target = gen_reg_rtx (tmode);
11079
11080 /* In case the insn wants input operands in modes different from
11081 the result, abort. */
11082 if (GET_MODE (op0) != mode0 || GET_MODE (op1) != mode1)
11083 abort ();
11084
11085 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11086 op0 = copy_to_mode_reg (mode0, op0);
11087 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11088 op1 = copy_to_mode_reg (mode1, op1);
11089
11090 pat = GEN_FCN (icode) (target, op0, op1);
11091 if (! pat)
11092 return 0;
11093 emit_insn (pat);
11094 return target;
11095}
11096
11097/* Subroutine of arm_expand_builtin to take care of unop insns. */
11098
11099static rtx
11100arm_expand_unop_builtin (enum insn_code icode,
11101 tree arglist, rtx target, int do_load)
11102{
11103 rtx pat;
11104 tree arg0 = TREE_VALUE (arglist);
11105 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11106 enum machine_mode tmode = insn_data[icode].operand[0].mode;
11107 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
11108
11109 if (! target
11110 || GET_MODE (target) != tmode
11111 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11112 target = gen_reg_rtx (tmode);
11113 if (do_load)
11114 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
11115 else
11116 {
11117 if (VECTOR_MODE_P (mode0))
11118 op0 = safe_vector_operand (op0, mode0);
11119
11120 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11121 op0 = copy_to_mode_reg (mode0, op0);
11122 }
11123
11124 pat = GEN_FCN (icode) (target, op0);
11125 if (! pat)
11126 return 0;
11127 emit_insn (pat);
11128 return target;
11129}
11130
11131/* Expand an expression EXP that calls a built-in function,
11132 with result going to TARGET if that's convenient
11133 (and in mode MODE if that's convenient).
11134 SUBTARGET may be used as the target for computing one of EXP's operands.
11135 IGNORE is nonzero if the value is to be ignored. */
11136
11137static rtx
11138arm_expand_builtin (tree exp,
11139 rtx target,
11140 rtx subtarget ATTRIBUTE_UNUSED,
11141 enum machine_mode mode ATTRIBUTE_UNUSED,
11142 int ignore ATTRIBUTE_UNUSED)
11143{
11144 const struct builtin_description * d;
11145 enum insn_code icode;
11146 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
11147 tree arglist = TREE_OPERAND (exp, 1);
11148 tree arg0;
11149 tree arg1;
11150 tree arg2;
11151 rtx op0;
11152 rtx op1;
11153 rtx op2;
11154 rtx pat;
11155 int fcode = DECL_FUNCTION_CODE (fndecl);
11156 size_t i;
11157 enum machine_mode tmode;
11158 enum machine_mode mode0;
11159 enum machine_mode mode1;
11160 enum machine_mode mode2;
11161
11162 switch (fcode)
11163 {
11164 case ARM_BUILTIN_TEXTRMSB:
11165 case ARM_BUILTIN_TEXTRMUB:
11166 case ARM_BUILTIN_TEXTRMSH:
11167 case ARM_BUILTIN_TEXTRMUH:
11168 case ARM_BUILTIN_TEXTRMSW:
11169 case ARM_BUILTIN_TEXTRMUW:
11170 icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
11171 : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
11172 : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
11173 : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
11174 : CODE_FOR_iwmmxt_textrmw);
11175
11176 arg0 = TREE_VALUE (arglist);
11177 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11178 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11179 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11180 tmode = insn_data[icode].operand[0].mode;
11181 mode0 = insn_data[icode].operand[1].mode;
11182 mode1 = insn_data[icode].operand[2].mode;
11183
11184 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11185 op0 = copy_to_mode_reg (mode0, op0);
11186 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11187 {
11188 /* @@@ better error message */
11189 error ("selector must be an immediate");
11190 return gen_reg_rtx (tmode);
11191 }
11192 if (target == 0
11193 || GET_MODE (target) != tmode
11194 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11195 target = gen_reg_rtx (tmode);
11196 pat = GEN_FCN (icode) (target, op0, op1);
11197 if (! pat)
11198 return 0;
11199 emit_insn (pat);
11200 return target;
11201
11202 case ARM_BUILTIN_TINSRB:
11203 case ARM_BUILTIN_TINSRH:
11204 case ARM_BUILTIN_TINSRW:
11205 icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
11206 : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
11207 : CODE_FOR_iwmmxt_tinsrw);
11208 arg0 = TREE_VALUE (arglist);
11209 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11210 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11211 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11212 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11213 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
11214 tmode = insn_data[icode].operand[0].mode;
11215 mode0 = insn_data[icode].operand[1].mode;
11216 mode1 = insn_data[icode].operand[2].mode;
11217 mode2 = insn_data[icode].operand[3].mode;
11218
11219 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11220 op0 = copy_to_mode_reg (mode0, op0);
11221 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11222 op1 = copy_to_mode_reg (mode1, op1);
11223 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11224 {
11225 /* @@@ better error message */
11226 error ("selector must be an immediate");
11227 return const0_rtx;
11228 }
11229 if (target == 0
11230 || GET_MODE (target) != tmode
11231 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11232 target = gen_reg_rtx (tmode);
11233 pat = GEN_FCN (icode) (target, op0, op1, op2);
11234 if (! pat)
11235 return 0;
11236 emit_insn (pat);
11237 return target;
11238
11239 case ARM_BUILTIN_SETWCX:
11240 arg0 = TREE_VALUE (arglist);
11241 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11242 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11243 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11244 emit_insn (gen_iwmmxt_tmcr (op0, op1));
11245 return 0;
11246
11247 case ARM_BUILTIN_GETWCX:
11248 arg0 = TREE_VALUE (arglist);
11249 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11250 target = gen_reg_rtx (SImode);
11251 emit_insn (gen_iwmmxt_tmrc (target, op0));
11252 return target;
11253
11254 case ARM_BUILTIN_WSHUFH:
11255 icode = CODE_FOR_iwmmxt_wshufh;
11256 arg0 = TREE_VALUE (arglist);
11257 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11258 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11259 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11260 tmode = insn_data[icode].operand[0].mode;
11261 mode1 = insn_data[icode].operand[1].mode;
11262 mode2 = insn_data[icode].operand[2].mode;
11263
11264 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
11265 op0 = copy_to_mode_reg (mode1, op0);
11266 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
11267 {
11268 /* @@@ better error message */
11269 error ("mask must be an immediate");
11270 return const0_rtx;
11271 }
11272 if (target == 0
11273 || GET_MODE (target) != tmode
11274 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11275 target = gen_reg_rtx (tmode);
11276 pat = GEN_FCN (icode) (target, op0, op1);
11277 if (! pat)
11278 return 0;
11279 emit_insn (pat);
11280 return target;
11281
11282 case ARM_BUILTIN_WSADB:
11283 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadb, arglist, target);
11284 case ARM_BUILTIN_WSADH:
11285 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadh, arglist, target);
11286 case ARM_BUILTIN_WSADBZ:
11287 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, arglist, target);
11288 case ARM_BUILTIN_WSADHZ:
11289 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, arglist, target);
11290
11291 /* Several three-argument builtins. */
11292 case ARM_BUILTIN_WMACS:
11293 case ARM_BUILTIN_WMACU:
11294 case ARM_BUILTIN_WALIGN:
11295 case ARM_BUILTIN_TMIA:
11296 case ARM_BUILTIN_TMIAPH:
11297 case ARM_BUILTIN_TMIATT:
11298 case ARM_BUILTIN_TMIATB:
11299 case ARM_BUILTIN_TMIABT:
11300 case ARM_BUILTIN_TMIABB:
11301 icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
11302 : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
11303 : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
11304 : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
11305 : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
11306 : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
11307 : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
11308 : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
11309 : CODE_FOR_iwmmxt_walign);
11310 arg0 = TREE_VALUE (arglist);
11311 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
11312 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
11313 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
11314 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
11315 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
11316 tmode = insn_data[icode].operand[0].mode;
11317 mode0 = insn_data[icode].operand[1].mode;
11318 mode1 = insn_data[icode].operand[2].mode;
11319 mode2 = insn_data[icode].operand[3].mode;
11320
11321 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
11322 op0 = copy_to_mode_reg (mode0, op0);
11323 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
11324 op1 = copy_to_mode_reg (mode1, op1);
11325 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
11326 op2 = copy_to_mode_reg (mode2, op2);
11327 if (target == 0
11328 || GET_MODE (target) != tmode
11329 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
11330 target = gen_reg_rtx (tmode);
11331 pat = GEN_FCN (icode) (target, op0, op1, op2);
11332 if (! pat)
11333 return 0;
11334 emit_insn (pat);
11335 return target;
11336
11337 case ARM_BUILTIN_WZERO:
11338 target = gen_reg_rtx (DImode);
11339 emit_insn (gen_iwmmxt_clrdi (target));
11340 return target;
11341
11342 default:
11343 break;
11344 }
11345
e97a46ce 11346 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5a9335ef
NC
11347 if (d->code == (const enum arm_builtins) fcode)
11348 return arm_expand_binop_builtin (d->icode, arglist, target);
11349
e97a46ce 11350 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5a9335ef
NC
11351 if (d->code == (const enum arm_builtins) fcode)
11352 return arm_expand_unop_builtin (d->icode, arglist, target, 0);
11353
11354 /* @@@ Should really do something sensible here. */
11355 return NULL_RTX;
11356}
11357\f
d5b7b3ae
RE
11358/* Recursively search through all of the blocks in a function
11359 checking to see if any of the variables created in that
11360 function match the RTX called 'orig'. If they do then
11361 replace them with the RTX called 'new'. */
d5b7b3ae 11362static void
e32bac5b 11363replace_symbols_in_block (tree block, rtx orig, rtx new)
d5b7b3ae
RE
11364{
11365 for (; block; block = BLOCK_CHAIN (block))
11366 {
11367 tree sym;
11368
5895f793 11369 if (!TREE_USED (block))
d5b7b3ae
RE
11370 continue;
11371
11372 for (sym = BLOCK_VARS (block); sym; sym = TREE_CHAIN (sym))
11373 {
11374 if ( (DECL_NAME (sym) == 0 && TREE_CODE (sym) != TYPE_DECL)
11375 || DECL_IGNORED_P (sym)
11376 || TREE_CODE (sym) != VAR_DECL
11377 || DECL_EXTERNAL (sym)
5895f793 11378 || !rtx_equal_p (DECL_RTL (sym), orig)
d5b7b3ae
RE
11379 )
11380 continue;
11381
7b8b8ade 11382 SET_DECL_RTL (sym, new);
d5b7b3ae
RE
11383 }
11384
11385 replace_symbols_in_block (BLOCK_SUBBLOCKS (block), orig, new);
11386 }
11387}
11388
1d6e90ac
NC
11389/* Return the number (counting from 0) of
11390 the least significant set bit in MASK. */
11391
e32bac5b
RE
11392inline static int
11393number_of_first_bit_set (int mask)
d5b7b3ae
RE
11394{
11395 int bit;
11396
11397 for (bit = 0;
11398 (mask & (1 << bit)) == 0;
5895f793 11399 ++bit)
d5b7b3ae
RE
11400 continue;
11401
11402 return bit;
11403}
11404
11405/* Generate code to return from a thumb function.
11406 If 'reg_containing_return_addr' is -1, then the return address is
11407 actually on the stack, at the stack pointer. */
11408static void
e32bac5b 11409thumb_exit (FILE *f, int reg_containing_return_addr, rtx eh_ofs)
d5b7b3ae
RE
11410{
11411 unsigned regs_available_for_popping;
11412 unsigned regs_to_pop;
11413 int pops_needed;
11414 unsigned available;
11415 unsigned required;
11416 int mode;
11417 int size;
11418 int restore_a4 = FALSE;
11419
11420 /* Compute the registers we need to pop. */
11421 regs_to_pop = 0;
11422 pops_needed = 0;
11423
11424 /* There is an assumption here, that if eh_ofs is not NULL, the
11425 normal return address will have been pushed. */
11426 if (reg_containing_return_addr == -1 || eh_ofs)
11427 {
11428 /* When we are generating a return for __builtin_eh_return,
11429 reg_containing_return_addr must specify the return regno. */
11430 if (eh_ofs && reg_containing_return_addr == -1)
11431 abort ();
11432
11433 regs_to_pop |= 1 << LR_REGNUM;
5895f793 11434 ++pops_needed;
d5b7b3ae
RE
11435 }
11436
11437 if (TARGET_BACKTRACE)
11438 {
11439 /* Restore the (ARM) frame pointer and stack pointer. */
11440 regs_to_pop |= (1 << ARM_HARD_FRAME_POINTER_REGNUM) | (1 << SP_REGNUM);
11441 pops_needed += 2;
11442 }
11443
11444 /* If there is nothing to pop then just emit the BX instruction and
11445 return. */
11446 if (pops_needed == 0)
11447 {
11448 if (eh_ofs)
11449 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
11450
11451 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
11452 return;
11453 }
11454 /* Otherwise if we are not supporting interworking and we have not created
11455 a backtrace structure and the function was not entered in ARM mode then
11456 just pop the return address straight into the PC. */
5895f793
RE
11457 else if (!TARGET_INTERWORK
11458 && !TARGET_BACKTRACE
11459 && !is_called_in_ARM_mode (current_function_decl))
d5b7b3ae
RE
11460 {
11461 if (eh_ofs)
11462 {
11463 asm_fprintf (f, "\tadd\t%r, #4\n", SP_REGNUM);
11464 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
11465 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
11466 }
11467 else
11468 asm_fprintf (f, "\tpop\t{%r}\n", PC_REGNUM);
11469
11470 return;
11471 }
11472
11473 /* Find out how many of the (return) argument registers we can corrupt. */
11474 regs_available_for_popping = 0;
11475
11476 /* If returning via __builtin_eh_return, the bottom three registers
11477 all contain information needed for the return. */
11478 if (eh_ofs)
11479 size = 12;
11480 else
11481 {
11482#ifdef RTX_CODE
11483 /* If we can deduce the registers used from the function's
11484 return value. This is more reliable that examining
11485 regs_ever_live[] because that will be set if the register is
11486 ever used in the function, not just if the register is used
11487 to hold a return value. */
11488
11489 if (current_function_return_rtx != 0)
11490 mode = GET_MODE (current_function_return_rtx);
11491 else
11492#endif
11493 mode = DECL_MODE (DECL_RESULT (current_function_decl));
11494
11495 size = GET_MODE_SIZE (mode);
11496
11497 if (size == 0)
11498 {
11499 /* In a void function we can use any argument register.
11500 In a function that returns a structure on the stack
11501 we can use the second and third argument registers. */
11502 if (mode == VOIDmode)
11503 regs_available_for_popping =
11504 (1 << ARG_REGISTER (1))
11505 | (1 << ARG_REGISTER (2))
11506 | (1 << ARG_REGISTER (3));
11507 else
11508 regs_available_for_popping =
11509 (1 << ARG_REGISTER (2))
11510 | (1 << ARG_REGISTER (3));
11511 }
11512 else if (size <= 4)
11513 regs_available_for_popping =
11514 (1 << ARG_REGISTER (2))
11515 | (1 << ARG_REGISTER (3));
11516 else if (size <= 8)
11517 regs_available_for_popping =
11518 (1 << ARG_REGISTER (3));
11519 }
11520
11521 /* Match registers to be popped with registers into which we pop them. */
11522 for (available = regs_available_for_popping,
11523 required = regs_to_pop;
11524 required != 0 && available != 0;
11525 available &= ~(available & - available),
11526 required &= ~(required & - required))
11527 -- pops_needed;
11528
11529 /* If we have any popping registers left over, remove them. */
11530 if (available > 0)
5895f793 11531 regs_available_for_popping &= ~available;
d5b7b3ae
RE
11532
11533 /* Otherwise if we need another popping register we can use
11534 the fourth argument register. */
11535 else if (pops_needed)
11536 {
11537 /* If we have not found any free argument registers and
11538 reg a4 contains the return address, we must move it. */
11539 if (regs_available_for_popping == 0
11540 && reg_containing_return_addr == LAST_ARG_REGNUM)
11541 {
11542 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM, LAST_ARG_REGNUM);
11543 reg_containing_return_addr = LR_REGNUM;
11544 }
11545 else if (size > 12)
11546 {
11547 /* Register a4 is being used to hold part of the return value,
11548 but we have dire need of a free, low register. */
11549 restore_a4 = TRUE;
11550
11551 asm_fprintf (f, "\tmov\t%r, %r\n",IP_REGNUM, LAST_ARG_REGNUM);
11552 }
11553
11554 if (reg_containing_return_addr != LAST_ARG_REGNUM)
11555 {
11556 /* The fourth argument register is available. */
11557 regs_available_for_popping |= 1 << LAST_ARG_REGNUM;
11558
5895f793 11559 --pops_needed;
d5b7b3ae
RE
11560 }
11561 }
11562
11563 /* Pop as many registers as we can. */
11564 thumb_pushpop (f, regs_available_for_popping, FALSE);
11565
11566 /* Process the registers we popped. */
11567 if (reg_containing_return_addr == -1)
11568 {
11569 /* The return address was popped into the lowest numbered register. */
5895f793 11570 regs_to_pop &= ~(1 << LR_REGNUM);
d5b7b3ae
RE
11571
11572 reg_containing_return_addr =
11573 number_of_first_bit_set (regs_available_for_popping);
11574
11575 /* Remove this register for the mask of available registers, so that
6bc82793 11576 the return address will not be corrupted by further pops. */
5895f793 11577 regs_available_for_popping &= ~(1 << reg_containing_return_addr);
d5b7b3ae
RE
11578 }
11579
11580 /* If we popped other registers then handle them here. */
11581 if (regs_available_for_popping)
11582 {
11583 int frame_pointer;
11584
11585 /* Work out which register currently contains the frame pointer. */
11586 frame_pointer = number_of_first_bit_set (regs_available_for_popping);
11587
11588 /* Move it into the correct place. */
11589 asm_fprintf (f, "\tmov\t%r, %r\n",
11590 ARM_HARD_FRAME_POINTER_REGNUM, frame_pointer);
11591
11592 /* (Temporarily) remove it from the mask of popped registers. */
5895f793
RE
11593 regs_available_for_popping &= ~(1 << frame_pointer);
11594 regs_to_pop &= ~(1 << ARM_HARD_FRAME_POINTER_REGNUM);
d5b7b3ae
RE
11595
11596 if (regs_available_for_popping)
11597 {
11598 int stack_pointer;
11599
11600 /* We popped the stack pointer as well,
11601 find the register that contains it. */
11602 stack_pointer = number_of_first_bit_set (regs_available_for_popping);
11603
11604 /* Move it into the stack register. */
11605 asm_fprintf (f, "\tmov\t%r, %r\n", SP_REGNUM, stack_pointer);
11606
11607 /* At this point we have popped all necessary registers, so
11608 do not worry about restoring regs_available_for_popping
11609 to its correct value:
11610
11611 assert (pops_needed == 0)
11612 assert (regs_available_for_popping == (1 << frame_pointer))
11613 assert (regs_to_pop == (1 << STACK_POINTER)) */
11614 }
11615 else
11616 {
11617 /* Since we have just move the popped value into the frame
11618 pointer, the popping register is available for reuse, and
11619 we know that we still have the stack pointer left to pop. */
11620 regs_available_for_popping |= (1 << frame_pointer);
11621 }
11622 }
11623
11624 /* If we still have registers left on the stack, but we no longer have
11625 any registers into which we can pop them, then we must move the return
11626 address into the link register and make available the register that
11627 contained it. */
11628 if (regs_available_for_popping == 0 && pops_needed > 0)
11629 {
11630 regs_available_for_popping |= 1 << reg_containing_return_addr;
11631
11632 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM,
11633 reg_containing_return_addr);
11634
11635 reg_containing_return_addr = LR_REGNUM;
11636 }
11637
11638 /* If we have registers left on the stack then pop some more.
11639 We know that at most we will want to pop FP and SP. */
11640 if (pops_needed > 0)
11641 {
11642 int popped_into;
11643 int move_to;
11644
11645 thumb_pushpop (f, regs_available_for_popping, FALSE);
11646
11647 /* We have popped either FP or SP.
11648 Move whichever one it is into the correct register. */
11649 popped_into = number_of_first_bit_set (regs_available_for_popping);
11650 move_to = number_of_first_bit_set (regs_to_pop);
11651
11652 asm_fprintf (f, "\tmov\t%r, %r\n", move_to, popped_into);
11653
5895f793 11654 regs_to_pop &= ~(1 << move_to);
d5b7b3ae 11655
5895f793 11656 --pops_needed;
d5b7b3ae
RE
11657 }
11658
11659 /* If we still have not popped everything then we must have only
11660 had one register available to us and we are now popping the SP. */
11661 if (pops_needed > 0)
11662 {
11663 int popped_into;
11664
11665 thumb_pushpop (f, regs_available_for_popping, FALSE);
11666
11667 popped_into = number_of_first_bit_set (regs_available_for_popping);
11668
11669 asm_fprintf (f, "\tmov\t%r, %r\n", SP_REGNUM, popped_into);
11670 /*
11671 assert (regs_to_pop == (1 << STACK_POINTER))
11672 assert (pops_needed == 1)
11673 */
11674 }
11675
11676 /* If necessary restore the a4 register. */
11677 if (restore_a4)
11678 {
11679 if (reg_containing_return_addr != LR_REGNUM)
11680 {
11681 asm_fprintf (f, "\tmov\t%r, %r\n", LR_REGNUM, LAST_ARG_REGNUM);
11682 reg_containing_return_addr = LR_REGNUM;
11683 }
11684
11685 asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
11686 }
11687
11688 if (eh_ofs)
11689 asm_fprintf (f, "\tadd\t%r, %r\n", SP_REGNUM, REGNO (eh_ofs));
11690
11691 /* Return to caller. */
11692 asm_fprintf (f, "\tbx\t%r\n", reg_containing_return_addr);
11693}
11694
11695/* Emit code to push or pop registers to or from the stack. */
11696static void
e32bac5b 11697thumb_pushpop (FILE *f, int mask, int push)
d5b7b3ae
RE
11698{
11699 int regno;
11700 int lo_mask = mask & 0xFF;
11701
5895f793 11702 if (lo_mask == 0 && !push && (mask & (1 << 15)))
d5b7b3ae
RE
11703 {
11704 /* Special case. Do not generate a POP PC statement here, do it in
11705 thumb_exit() */
11706 thumb_exit (f, -1, NULL_RTX);
11707 return;
11708 }
11709
11710 fprintf (f, "\t%s\t{", push ? "push" : "pop");
11711
11712 /* Look at the low registers first. */
5895f793 11713 for (regno = 0; regno <= LAST_LO_REGNUM; regno++, lo_mask >>= 1)
d5b7b3ae
RE
11714 {
11715 if (lo_mask & 1)
11716 {
11717 asm_fprintf (f, "%r", regno);
11718
11719 if ((lo_mask & ~1) != 0)
11720 fprintf (f, ", ");
11721 }
11722 }
11723
11724 if (push && (mask & (1 << LR_REGNUM)))
11725 {
11726 /* Catch pushing the LR. */
11727 if (mask & 0xFF)
11728 fprintf (f, ", ");
11729
11730 asm_fprintf (f, "%r", LR_REGNUM);
11731 }
11732 else if (!push && (mask & (1 << PC_REGNUM)))
11733 {
11734 /* Catch popping the PC. */
11735 if (TARGET_INTERWORK || TARGET_BACKTRACE)
11736 {
11737 /* The PC is never poped directly, instead
11738 it is popped into r3 and then BX is used. */
11739 fprintf (f, "}\n");
11740
11741 thumb_exit (f, -1, NULL_RTX);
11742
11743 return;
11744 }
11745 else
11746 {
11747 if (mask & 0xFF)
11748 fprintf (f, ", ");
11749
11750 asm_fprintf (f, "%r", PC_REGNUM);
11751 }
11752 }
11753
11754 fprintf (f, "}\n");
11755}
11756\f
11757void
e32bac5b 11758thumb_final_prescan_insn (rtx insn)
d5b7b3ae 11759{
d5b7b3ae 11760 if (flag_print_asm_name)
9d98a694
AO
11761 asm_fprintf (asm_out_file, "%@ 0x%04x\n",
11762 INSN_ADDRESSES (INSN_UID (insn)));
d5b7b3ae
RE
11763}
11764
11765int
e32bac5b 11766thumb_shiftable_const (unsigned HOST_WIDE_INT val)
d5b7b3ae
RE
11767{
11768 unsigned HOST_WIDE_INT mask = 0xff;
11769 int i;
11770
11771 if (val == 0) /* XXX */
11772 return 0;
11773
11774 for (i = 0; i < 25; i++)
11775 if ((val & (mask << i)) == val)
11776 return 1;
11777
11778 return 0;
11779}
11780
825dda42 11781/* Returns nonzero if the current function contains,
d5b7b3ae
RE
11782 or might contain a far jump. */
11783int
e32bac5b 11784thumb_far_jump_used_p (int in_prologue)
d5b7b3ae
RE
11785{
11786 rtx insn;
11787
11788 /* This test is only important for leaf functions. */
5895f793 11789 /* assert (!leaf_function_p ()); */
d5b7b3ae
RE
11790
11791 /* If we have already decided that far jumps may be used,
11792 do not bother checking again, and always return true even if
11793 it turns out that they are not being used. Once we have made
11794 the decision that far jumps are present (and that hence the link
11795 register will be pushed onto the stack) we cannot go back on it. */
11796 if (cfun->machine->far_jump_used)
11797 return 1;
11798
11799 /* If this function is not being called from the prologue/epilogue
11800 generation code then it must be being called from the
11801 INITIAL_ELIMINATION_OFFSET macro. */
5895f793 11802 if (!in_prologue)
d5b7b3ae
RE
11803 {
11804 /* In this case we know that we are being asked about the elimination
11805 of the arg pointer register. If that register is not being used,
11806 then there are no arguments on the stack, and we do not have to
11807 worry that a far jump might force the prologue to push the link
11808 register, changing the stack offsets. In this case we can just
11809 return false, since the presence of far jumps in the function will
11810 not affect stack offsets.
11811
11812 If the arg pointer is live (or if it was live, but has now been
11813 eliminated and so set to dead) then we do have to test to see if
11814 the function might contain a far jump. This test can lead to some
11815 false negatives, since before reload is completed, then length of
11816 branch instructions is not known, so gcc defaults to returning their
11817 longest length, which in turn sets the far jump attribute to true.
11818
11819 A false negative will not result in bad code being generated, but it
11820 will result in a needless push and pop of the link register. We
11821 hope that this does not occur too often. */
11822 if (regs_ever_live [ARG_POINTER_REGNUM])
11823 cfun->machine->arg_pointer_live = 1;
5895f793 11824 else if (!cfun->machine->arg_pointer_live)
d5b7b3ae
RE
11825 return 0;
11826 }
11827
11828 /* Check to see if the function contains a branch
11829 insn with the far jump attribute set. */
11830 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
11831 {
11832 if (GET_CODE (insn) == JUMP_INSN
11833 /* Ignore tablejump patterns. */
11834 && GET_CODE (PATTERN (insn)) != ADDR_VEC
11835 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
11836 && get_attr_far_jump (insn) == FAR_JUMP_YES
11837 )
11838 {
9a9f7594 11839 /* Record the fact that we have decided that
d5b7b3ae
RE
11840 the function does use far jumps. */
11841 cfun->machine->far_jump_used = 1;
11842 return 1;
11843 }
11844 }
11845
11846 return 0;
11847}
11848
825dda42 11849/* Return nonzero if FUNC must be entered in ARM mode. */
d5b7b3ae 11850int
e32bac5b 11851is_called_in_ARM_mode (tree func)
d5b7b3ae
RE
11852{
11853 if (TREE_CODE (func) != FUNCTION_DECL)
11854 abort ();
11855
11856 /* Ignore the problem about functions whoes address is taken. */
11857 if (TARGET_CALLEE_INTERWORKING && TREE_PUBLIC (func))
11858 return TRUE;
11859
11860#ifdef ARM_PE
91d231cb 11861 return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
d5b7b3ae
RE
11862#else
11863 return FALSE;
11864#endif
11865}
11866
11867/* The bits which aren't usefully expanded as rtl. */
cd2b33d0 11868const char *
e32bac5b 11869thumb_unexpanded_epilogue (void)
d5b7b3ae
RE
11870{
11871 int regno;
11872 int live_regs_mask = 0;
11873 int high_regs_pushed = 0;
11874 int leaf_function = leaf_function_p ();
11875 int had_to_push_lr;
11876 rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
11877
11878 if (return_used_this_function)
11879 return "";
11880
58e60158
AN
11881 if (IS_NAKED (arm_current_func_type ()))
11882 return "";
11883
d5b7b3ae 11884 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
aeaf4d25 11885 if (THUMB_REG_PUSHED_P (regno))
d5b7b3ae
RE
11886 live_regs_mask |= 1 << regno;
11887
11888 for (regno = 8; regno < 13; regno++)
aeaf4d25
AN
11889 if (THUMB_REG_PUSHED_P (regno))
11890 high_regs_pushed++;
d5b7b3ae
RE
11891
11892 /* The prolog may have pushed some high registers to use as
093354e0 11893 work registers. eg the testsuite file:
d5b7b3ae
RE
11894 gcc/testsuite/gcc/gcc.c-torture/execute/complex-2.c
11895 compiles to produce:
11896 push {r4, r5, r6, r7, lr}
11897 mov r7, r9
11898 mov r6, r8
11899 push {r6, r7}
11900 as part of the prolog. We have to undo that pushing here. */
11901
11902 if (high_regs_pushed)
11903 {
11904 int mask = live_regs_mask;
11905 int next_hi_reg;
11906 int size;
11907 int mode;
11908
11909#ifdef RTX_CODE
11910 /* If we can deduce the registers used from the function's return value.
11911 This is more reliable that examining regs_ever_live[] because that
11912 will be set if the register is ever used in the function, not just if
11913 the register is used to hold a return value. */
11914
11915 if (current_function_return_rtx != 0)
11916 mode = GET_MODE (current_function_return_rtx);
11917 else
11918#endif
11919 mode = DECL_MODE (DECL_RESULT (current_function_decl));
11920
11921 size = GET_MODE_SIZE (mode);
11922
11923 /* Unless we are returning a type of size > 12 register r3 is
11924 available. */
11925 if (size < 13)
11926 mask |= 1 << 3;
11927
11928 if (mask == 0)
11929 /* Oh dear! We have no low registers into which we can pop
11930 high registers! */
400500c4
RK
11931 internal_error
11932 ("no low registers available for popping high registers");
d5b7b3ae
RE
11933
11934 for (next_hi_reg = 8; next_hi_reg < 13; next_hi_reg++)
aeaf4d25 11935 if (THUMB_REG_PUSHED_P (next_hi_reg))
d5b7b3ae
RE
11936 break;
11937
11938 while (high_regs_pushed)
11939 {
11940 /* Find lo register(s) into which the high register(s) can
11941 be popped. */
11942 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
11943 {
11944 if (mask & (1 << regno))
11945 high_regs_pushed--;
11946 if (high_regs_pushed == 0)
11947 break;
11948 }
11949
11950 mask &= (2 << regno) - 1; /* A noop if regno == 8 */
11951
11952 /* Pop the values into the low register(s). */
11953 thumb_pushpop (asm_out_file, mask, 0);
11954
11955 /* Move the value(s) into the high registers. */
11956 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
11957 {
11958 if (mask & (1 << regno))
11959 {
11960 asm_fprintf (asm_out_file, "\tmov\t%r, %r\n", next_hi_reg,
11961 regno);
11962
11963 for (next_hi_reg++; next_hi_reg < 13; next_hi_reg++)
aeaf4d25 11964 if (THUMB_REG_PUSHED_P (next_hi_reg))
d5b7b3ae
RE
11965 break;
11966 }
11967 }
11968 }
11969 }
11970
5895f793 11971 had_to_push_lr = (live_regs_mask || !leaf_function
d5b7b3ae
RE
11972 || thumb_far_jump_used_p (1));
11973
11974 if (TARGET_BACKTRACE
11975 && ((live_regs_mask & 0xFF) == 0)
11976 && regs_ever_live [LAST_ARG_REGNUM] != 0)
11977 {
11978 /* The stack backtrace structure creation code had to
11979 push R7 in order to get a work register, so we pop
11980 it now. */
11981 live_regs_mask |= (1 << LAST_LO_REGNUM);
11982 }
11983
11984 if (current_function_pretend_args_size == 0 || TARGET_BACKTRACE)
11985 {
11986 if (had_to_push_lr
5895f793
RE
11987 && !is_called_in_ARM_mode (current_function_decl)
11988 && !eh_ofs)
d5b7b3ae
RE
11989 live_regs_mask |= 1 << PC_REGNUM;
11990
11991 /* Either no argument registers were pushed or a backtrace
11992 structure was created which includes an adjusted stack
11993 pointer, so just pop everything. */
11994 if (live_regs_mask)
11995 thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
11996
11997 if (eh_ofs)
11998 thumb_exit (asm_out_file, 2, eh_ofs);
11999 /* We have either just popped the return address into the
12000 PC or it is was kept in LR for the entire function or
12001 it is still on the stack because we do not want to
12002 return by doing a pop {pc}. */
12003 else if ((live_regs_mask & (1 << PC_REGNUM)) == 0)
12004 thumb_exit (asm_out_file,
12005 (had_to_push_lr
12006 && is_called_in_ARM_mode (current_function_decl)) ?
12007 -1 : LR_REGNUM, NULL_RTX);
12008 }
12009 else
12010 {
12011 /* Pop everything but the return address. */
5895f793 12012 live_regs_mask &= ~(1 << PC_REGNUM);
d5b7b3ae
RE
12013
12014 if (live_regs_mask)
12015 thumb_pushpop (asm_out_file, live_regs_mask, FALSE);
12016
12017 if (had_to_push_lr)
12018 /* Get the return address into a temporary register. */
12019 thumb_pushpop (asm_out_file, 1 << LAST_ARG_REGNUM, 0);
12020
12021 /* Remove the argument registers that were pushed onto the stack. */
12022 asm_fprintf (asm_out_file, "\tadd\t%r, %r, #%d\n",
12023 SP_REGNUM, SP_REGNUM,
12024 current_function_pretend_args_size);
12025
12026 if (eh_ofs)
12027 thumb_exit (asm_out_file, 2, eh_ofs);
12028 else
12029 thumb_exit (asm_out_file,
12030 had_to_push_lr ? LAST_ARG_REGNUM : LR_REGNUM, NULL_RTX);
12031 }
12032
12033 return "";
12034}
12035
12036/* Functions to save and restore machine-specific function data. */
e2500fed 12037static struct machine_function *
e32bac5b 12038arm_init_machine_status (void)
d5b7b3ae 12039{
e2500fed
GK
12040 struct machine_function *machine;
12041 machine = (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
6d3d9133 12042
e2500fed
GK
12043#if ARM_FT_UNKNOWN != 0
12044 machine->func_type = ARM_FT_UNKNOWN;
6d3d9133 12045#endif
e2500fed 12046 return machine;
f7a80099
NC
12047}
12048
d5b7b3ae
RE
12049/* Return an RTX indicating where the return address to the
12050 calling function can be found. */
12051rtx
e32bac5b 12052arm_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
d5b7b3ae 12053{
d5b7b3ae
RE
12054 if (count != 0)
12055 return NULL_RTX;
12056
9e2f7ec7
DD
12057 if (TARGET_APCS_32)
12058 return get_hard_reg_initial_val (Pmode, LR_REGNUM);
12059 else
d5b7b3ae 12060 {
9e2f7ec7 12061 rtx lr = gen_rtx_AND (Pmode, gen_rtx_REG (Pmode, LR_REGNUM),
d5b7b3ae 12062 GEN_INT (RETURN_ADDR_MASK26));
9e2f7ec7 12063 return get_func_hard_reg_initial_val (cfun, lr);
d5b7b3ae 12064 }
d5b7b3ae
RE
12065}
12066
12067/* Do anything needed before RTL is emitted for each function. */
12068void
e32bac5b 12069arm_init_expanders (void)
d5b7b3ae
RE
12070{
12071 /* Arrange to initialize and mark the machine per-function status. */
12072 init_machine_status = arm_init_machine_status;
d5b7b3ae
RE
12073}
12074
0977774b 12075HOST_WIDE_INT
e32bac5b 12076thumb_get_frame_size (void)
0977774b
JT
12077{
12078 int regno;
12079
0c2ca901 12080 int base_size = ROUND_UP_WORD (get_frame_size ());
0977774b
JT
12081 int count_regs = 0;
12082 int entry_size = 0;
c231c91e 12083 int leaf;
0977774b
JT
12084
12085 if (! TARGET_THUMB)
12086 abort ();
12087
12088 if (! TARGET_ATPCS)
12089 return base_size;
12090
12091 /* We need to know if we are a leaf function. Unfortunately, it
12092 is possible to be called after start_sequence has been called,
12093 which causes get_insns to return the insns for the sequence,
12094 not the function, which will cause leaf_function_p to return
12095 the incorrect result.
12096
12097 To work around this, we cache the computed frame size. This
12098 works because we will only be calling RTL expanders that need
12099 to know about leaf functions once reload has completed, and the
12100 frame size cannot be changed after that time, so we can safely
12101 use the cached value. */
12102
12103 if (reload_completed)
12104 return cfun->machine->frame_size;
12105
c231c91e
RE
12106 leaf = leaf_function_p ();
12107
12108 /* A leaf function does not need any stack alignment if it has nothing
12109 on the stack. */
12110 if (leaf && base_size == 0)
12111 {
12112 cfun->machine->frame_size = 0;
12113 return 0;
12114 }
12115
0977774b
JT
12116 /* We know that SP will be word aligned on entry, and we must
12117 preserve that condition at any subroutine call. But those are
12118 the only constraints. */
12119
12120 /* Space for variadic functions. */
12121 if (current_function_pretend_args_size)
12122 entry_size += current_function_pretend_args_size;
12123
12124 /* Space for pushed lo registers. */
12125 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
12126 if (THUMB_REG_PUSHED_P (regno))
12127 count_regs++;
12128
12129 /* Space for backtrace structure. */
12130 if (TARGET_BACKTRACE)
12131 {
12132 if (count_regs == 0 && regs_ever_live[LAST_ARG_REGNUM] != 0)
12133 entry_size += 20;
12134 else
12135 entry_size += 16;
12136 }
12137
c231c91e 12138 if (count_regs || !leaf || thumb_far_jump_used_p (1))
0977774b
JT
12139 count_regs++; /* LR */
12140
12141 entry_size += count_regs * 4;
12142 count_regs = 0;
12143
12144 /* Space for pushed hi regs. */
12145 for (regno = 8; regno < 13; regno++)
12146 if (THUMB_REG_PUSHED_P (regno))
12147 count_regs++;
12148
12149 entry_size += count_regs * 4;
12150
12151 if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
12152 base_size += 4;
12153 if ((entry_size + base_size + current_function_outgoing_args_size) & 7)
12154 abort ();
12155
12156 cfun->machine->frame_size = base_size;
12157
12158 return base_size;
12159}
12160
d5b7b3ae
RE
12161/* Generate the rest of a function's prologue. */
12162void
e32bac5b 12163thumb_expand_prologue (void)
d5b7b3ae 12164{
0977774b 12165 HOST_WIDE_INT amount = (thumb_get_frame_size ()
d5b7b3ae 12166 + current_function_outgoing_args_size);
6d3d9133
NC
12167 unsigned long func_type;
12168
12169 func_type = arm_current_func_type ();
d5b7b3ae
RE
12170
12171 /* Naked functions don't have prologues. */
6d3d9133 12172 if (IS_NAKED (func_type))
d5b7b3ae
RE
12173 return;
12174
6d3d9133
NC
12175 if (IS_INTERRUPT (func_type))
12176 {
c725bd79 12177 error ("interrupt Service Routines cannot be coded in Thumb mode");
6d3d9133
NC
12178 return;
12179 }
12180
d5b7b3ae
RE
12181 if (frame_pointer_needed)
12182 emit_insn (gen_movsi (hard_frame_pointer_rtx, stack_pointer_rtx));
12183
12184 if (amount)
12185 {
0c2ca901 12186 amount = ROUND_UP_WORD (amount);
d5b7b3ae
RE
12187
12188 if (amount < 512)
12189 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1d6e90ac 12190 GEN_INT (- amount)));
d5b7b3ae
RE
12191 else
12192 {
12193 int regno;
12194 rtx reg;
12195
12196 /* The stack decrement is too big for an immediate value in a single
12197 insn. In theory we could issue multiple subtracts, but after
12198 three of them it becomes more space efficient to place the full
12199 value in the constant pool and load into a register. (Also the
12200 ARM debugger really likes to see only one stack decrement per
12201 function). So instead we look for a scratch register into which
12202 we can load the decrement, and then we subtract this from the
12203 stack pointer. Unfortunately on the thumb the only available
12204 scratch registers are the argument registers, and we cannot use
12205 these as they may hold arguments to the function. Instead we
12206 attempt to locate a call preserved register which is used by this
12207 function. If we can find one, then we know that it will have
12208 been pushed at the start of the prologue and so we can corrupt
12209 it now. */
12210 for (regno = LAST_ARG_REGNUM + 1; regno <= LAST_LO_REGNUM; regno++)
aeaf4d25 12211 if (THUMB_REG_PUSHED_P (regno)
5895f793
RE
12212 && !(frame_pointer_needed
12213 && (regno == THUMB_HARD_FRAME_POINTER_REGNUM)))
d5b7b3ae
RE
12214 break;
12215
aeaf4d25 12216 if (regno > LAST_LO_REGNUM) /* Very unlikely. */
d5b7b3ae
RE
12217 {
12218 rtx spare = gen_rtx (REG, SImode, IP_REGNUM);
12219
6bc82793 12220 /* Choose an arbitrary, non-argument low register. */
d5b7b3ae
RE
12221 reg = gen_rtx (REG, SImode, LAST_LO_REGNUM);
12222
12223 /* Save it by copying it into a high, scratch register. */
c14a3a45
NC
12224 emit_insn (gen_movsi (spare, reg));
12225 /* Add a USE to stop propagate_one_insn() from barfing. */
6bacc7b0 12226 emit_insn (gen_prologue_use (spare));
d5b7b3ae
RE
12227
12228 /* Decrement the stack. */
1d6e90ac 12229 emit_insn (gen_movsi (reg, GEN_INT (- amount)));
d5b7b3ae
RE
12230 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
12231 reg));
12232
12233 /* Restore the low register's original value. */
12234 emit_insn (gen_movsi (reg, spare));
12235
12236 /* Emit a USE of the restored scratch register, so that flow
12237 analysis will not consider the restore redundant. The
12238 register won't be used again in this function and isn't
12239 restored by the epilogue. */
6bacc7b0 12240 emit_insn (gen_prologue_use (reg));
d5b7b3ae
RE
12241 }
12242 else
12243 {
12244 reg = gen_rtx (REG, SImode, regno);
12245
1d6e90ac 12246 emit_insn (gen_movsi (reg, GEN_INT (- amount)));
d5b7b3ae
RE
12247 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
12248 reg));
12249 }
12250 }
12251 }
12252
70f4f91c 12253 if (current_function_profile || TARGET_NO_SCHED_PRO)
d5b7b3ae
RE
12254 emit_insn (gen_blockage ());
12255}
12256
12257void
e32bac5b 12258thumb_expand_epilogue (void)
d5b7b3ae 12259{
0977774b 12260 HOST_WIDE_INT amount = (thumb_get_frame_size ()
d5b7b3ae 12261 + current_function_outgoing_args_size);
defc0463
RE
12262 int regno;
12263
6d3d9133
NC
12264 /* Naked functions don't have prologues. */
12265 if (IS_NAKED (arm_current_func_type ()))
d5b7b3ae
RE
12266 return;
12267
12268 if (frame_pointer_needed)
12269 emit_insn (gen_movsi (stack_pointer_rtx, hard_frame_pointer_rtx));
12270 else if (amount)
12271 {
0c2ca901 12272 amount = ROUND_UP_WORD (amount);
d5b7b3ae
RE
12273
12274 if (amount < 512)
12275 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
12276 GEN_INT (amount)));
12277 else
12278 {
12279 /* r3 is always free in the epilogue. */
12280 rtx reg = gen_rtx (REG, SImode, LAST_ARG_REGNUM);
12281
12282 emit_insn (gen_movsi (reg, GEN_INT (amount)));
12283 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, reg));
12284 }
12285 }
12286
12287 /* Emit a USE (stack_pointer_rtx), so that
12288 the stack adjustment will not be deleted. */
6bacc7b0 12289 emit_insn (gen_prologue_use (stack_pointer_rtx));
d5b7b3ae 12290
70f4f91c 12291 if (current_function_profile || TARGET_NO_SCHED_PRO)
d5b7b3ae 12292 emit_insn (gen_blockage ());
defc0463
RE
12293
12294 /* Emit a clobber for each insn that will be restored in the epilogue,
12295 so that flow2 will get register lifetimes correct. */
12296 for (regno = 0; regno < 13; regno++)
12297 if (regs_ever_live[regno] && !call_used_regs[regno])
12298 emit_insn (gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, regno)));
12299
12300 if (! regs_ever_live[LR_REGNUM])
12301 emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, LR_REGNUM)));
d5b7b3ae
RE
12302}
12303
08c148a8 12304static void
e32bac5b 12305thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
d5b7b3ae
RE
12306{
12307 int live_regs_mask = 0;
12308 int high_regs_pushed = 0;
d5b7b3ae
RE
12309 int regno;
12310
6d3d9133 12311 if (IS_NAKED (arm_current_func_type ()))
d5b7b3ae
RE
12312 return;
12313
12314 if (is_called_in_ARM_mode (current_function_decl))
12315 {
12316 const char * name;
12317
12318 if (GET_CODE (DECL_RTL (current_function_decl)) != MEM)
12319 abort ();
12320 if (GET_CODE (XEXP (DECL_RTL (current_function_decl), 0)) != SYMBOL_REF)
12321 abort ();
12322 name = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
12323
12324 /* Generate code sequence to switch us into Thumb mode. */
12325 /* The .code 32 directive has already been emitted by
6d77b53e 12326 ASM_DECLARE_FUNCTION_NAME. */
d5b7b3ae
RE
12327 asm_fprintf (f, "\torr\t%r, %r, #1\n", IP_REGNUM, PC_REGNUM);
12328 asm_fprintf (f, "\tbx\t%r\n", IP_REGNUM);
12329
12330 /* Generate a label, so that the debugger will notice the
12331 change in instruction sets. This label is also used by
12332 the assembler to bypass the ARM code when this function
12333 is called from a Thumb encoded function elsewhere in the
12334 same file. Hence the definition of STUB_NAME here must
12335 agree with the definition in gas/config/tc-arm.c */
12336
12337#define STUB_NAME ".real_start_of"
12338
761c70aa 12339 fprintf (f, "\t.code\t16\n");
d5b7b3ae
RE
12340#ifdef ARM_PE
12341 if (arm_dllexport_name_p (name))
e5951263 12342 name = arm_strip_name_encoding (name);
d5b7b3ae
RE
12343#endif
12344 asm_fprintf (f, "\t.globl %s%U%s\n", STUB_NAME, name);
761c70aa 12345 fprintf (f, "\t.thumb_func\n");
d5b7b3ae
RE
12346 asm_fprintf (f, "%s%U%s:\n", STUB_NAME, name);
12347 }
12348
d5b7b3ae
RE
12349 if (current_function_pretend_args_size)
12350 {
3cb66fd7 12351 if (cfun->machine->uses_anonymous_args)
d5b7b3ae
RE
12352 {
12353 int num_pushes;
12354
761c70aa 12355 fprintf (f, "\tpush\t{");
d5b7b3ae 12356
e9d7b180 12357 num_pushes = ARM_NUM_INTS (current_function_pretend_args_size);
d5b7b3ae
RE
12358
12359 for (regno = LAST_ARG_REGNUM + 1 - num_pushes;
12360 regno <= LAST_ARG_REGNUM;
5895f793 12361 regno++)
d5b7b3ae
RE
12362 asm_fprintf (f, "%r%s", regno,
12363 regno == LAST_ARG_REGNUM ? "" : ", ");
12364
761c70aa 12365 fprintf (f, "}\n");
d5b7b3ae
RE
12366 }
12367 else
12368 asm_fprintf (f, "\tsub\t%r, %r, #%d\n",
12369 SP_REGNUM, SP_REGNUM,
12370 current_function_pretend_args_size);
12371 }
12372
5895f793 12373 for (regno = 0; regno <= LAST_LO_REGNUM; regno++)
aeaf4d25 12374 if (THUMB_REG_PUSHED_P (regno))
d5b7b3ae
RE
12375 live_regs_mask |= 1 << regno;
12376
5895f793 12377 if (live_regs_mask || !leaf_function_p () || thumb_far_jump_used_p (1))
d5b7b3ae
RE
12378 live_regs_mask |= 1 << LR_REGNUM;
12379
12380 if (TARGET_BACKTRACE)
12381 {
12382 int offset;
12383 int work_register = 0;
12384 int wr;
12385
12386 /* We have been asked to create a stack backtrace structure.
12387 The code looks like this:
12388
12389 0 .align 2
12390 0 func:
12391 0 sub SP, #16 Reserve space for 4 registers.
12392 2 push {R7} Get a work register.
12393 4 add R7, SP, #20 Get the stack pointer before the push.
12394 6 str R7, [SP, #8] Store the stack pointer (before reserving the space).
12395 8 mov R7, PC Get hold of the start of this code plus 12.
12396 10 str R7, [SP, #16] Store it.
12397 12 mov R7, FP Get hold of the current frame pointer.
12398 14 str R7, [SP, #4] Store it.
12399 16 mov R7, LR Get hold of the current return address.
12400 18 str R7, [SP, #12] Store it.
12401 20 add R7, SP, #16 Point at the start of the backtrace structure.
12402 22 mov FP, R7 Put this value into the frame pointer. */
12403
12404 if ((live_regs_mask & 0xFF) == 0)
12405 {
12406 /* See if the a4 register is free. */
12407
12408 if (regs_ever_live [LAST_ARG_REGNUM] == 0)
12409 work_register = LAST_ARG_REGNUM;
12410 else /* We must push a register of our own */
12411 live_regs_mask |= (1 << LAST_LO_REGNUM);
12412 }
12413
12414 if (work_register == 0)
12415 {
12416 /* Select a register from the list that will be pushed to
12417 use as our work register. */
12418 for (work_register = (LAST_LO_REGNUM + 1); work_register--;)
12419 if ((1 << work_register) & live_regs_mask)
12420 break;
12421 }
12422
12423 asm_fprintf
12424 (f, "\tsub\t%r, %r, #16\t%@ Create stack backtrace structure\n",
12425 SP_REGNUM, SP_REGNUM);
12426
12427 if (live_regs_mask)
12428 thumb_pushpop (f, live_regs_mask, 1);
12429
12430 for (offset = 0, wr = 1 << 15; wr != 0; wr >>= 1)
12431 if (wr & live_regs_mask)
12432 offset += 4;
12433
12434 asm_fprintf (f, "\tadd\t%r, %r, #%d\n", work_register, SP_REGNUM,
12435 offset + 16 + current_function_pretend_args_size);
12436
12437 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12438 offset + 4);
12439
12440 /* Make sure that the instruction fetching the PC is in the right place
12441 to calculate "start of backtrace creation code + 12". */
12442 if (live_regs_mask)
12443 {
12444 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, PC_REGNUM);
12445 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12446 offset + 12);
12447 asm_fprintf (f, "\tmov\t%r, %r\n", work_register,
12448 ARM_HARD_FRAME_POINTER_REGNUM);
12449 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12450 offset);
12451 }
12452 else
12453 {
12454 asm_fprintf (f, "\tmov\t%r, %r\n", work_register,
12455 ARM_HARD_FRAME_POINTER_REGNUM);
12456 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12457 offset);
12458 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, PC_REGNUM);
12459 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12460 offset + 12);
12461 }
12462
12463 asm_fprintf (f, "\tmov\t%r, %r\n", work_register, LR_REGNUM);
12464 asm_fprintf (f, "\tstr\t%r, [%r, #%d]\n", work_register, SP_REGNUM,
12465 offset + 8);
12466 asm_fprintf (f, "\tadd\t%r, %r, #%d\n", work_register, SP_REGNUM,
12467 offset + 12);
12468 asm_fprintf (f, "\tmov\t%r, %r\t\t%@ Backtrace structure created\n",
12469 ARM_HARD_FRAME_POINTER_REGNUM, work_register);
12470 }
12471 else if (live_regs_mask)
12472 thumb_pushpop (f, live_regs_mask, 1);
12473
12474 for (regno = 8; regno < 13; regno++)
e26053d1
NC
12475 if (THUMB_REG_PUSHED_P (regno))
12476 high_regs_pushed++;
d5b7b3ae
RE
12477
12478 if (high_regs_pushed)
12479 {
12480 int pushable_regs = 0;
12481 int mask = live_regs_mask & 0xff;
12482 int next_hi_reg;
12483
12484 for (next_hi_reg = 12; next_hi_reg > LAST_LO_REGNUM; next_hi_reg--)
e26053d1
NC
12485 if (THUMB_REG_PUSHED_P (next_hi_reg))
12486 break;
d5b7b3ae
RE
12487
12488 pushable_regs = mask;
12489
12490 if (pushable_regs == 0)
12491 {
12492 /* Desperation time -- this probably will never happen. */
aeaf4d25 12493 if (THUMB_REG_PUSHED_P (LAST_ARG_REGNUM))
d5b7b3ae
RE
12494 asm_fprintf (f, "\tmov\t%r, %r\n", IP_REGNUM, LAST_ARG_REGNUM);
12495 mask = 1 << LAST_ARG_REGNUM;
12496 }
12497
12498 while (high_regs_pushed > 0)
12499 {
12500 for (regno = LAST_LO_REGNUM; regno >= 0; regno--)
12501 {
12502 if (mask & (1 << regno))
12503 {
12504 asm_fprintf (f, "\tmov\t%r, %r\n", regno, next_hi_reg);
12505
5895f793 12506 high_regs_pushed--;
d5b7b3ae
RE
12507
12508 if (high_regs_pushed)
aeaf4d25
AN
12509 {
12510 for (next_hi_reg--; next_hi_reg > LAST_LO_REGNUM;
12511 next_hi_reg--)
12512 if (THUMB_REG_PUSHED_P (next_hi_reg))
d5b7b3ae 12513 break;
aeaf4d25 12514 }
d5b7b3ae
RE
12515 else
12516 {
5895f793 12517 mask &= ~((1 << regno) - 1);
d5b7b3ae
RE
12518 break;
12519 }
12520 }
12521 }
12522
12523 thumb_pushpop (f, mask, 1);
12524 }
12525
12526 if (pushable_regs == 0
aeaf4d25 12527 && (THUMB_REG_PUSHED_P (LAST_ARG_REGNUM)))
d5b7b3ae
RE
12528 asm_fprintf (f, "\tmov\t%r, %r\n", LAST_ARG_REGNUM, IP_REGNUM);
12529 }
12530}
12531
12532/* Handle the case of a double word load into a low register from
12533 a computed memory address. The computed address may involve a
12534 register which is overwritten by the load. */
cd2b33d0 12535const char *
e32bac5b 12536thumb_load_double_from_address (rtx *operands)
d5b7b3ae
RE
12537{
12538 rtx addr;
12539 rtx base;
12540 rtx offset;
12541 rtx arg1;
12542 rtx arg2;
12543
12544 if (GET_CODE (operands[0]) != REG)
400500c4 12545 abort ();
d5b7b3ae
RE
12546
12547 if (GET_CODE (operands[1]) != MEM)
400500c4 12548 abort ();
d5b7b3ae
RE
12549
12550 /* Get the memory address. */
12551 addr = XEXP (operands[1], 0);
12552
12553 /* Work out how the memory address is computed. */
12554 switch (GET_CODE (addr))
12555 {
12556 case REG:
12557 operands[2] = gen_rtx (MEM, SImode,
12558 plus_constant (XEXP (operands[1], 0), 4));
12559
12560 if (REGNO (operands[0]) == REGNO (addr))
12561 {
12562 output_asm_insn ("ldr\t%H0, %2", operands);
12563 output_asm_insn ("ldr\t%0, %1", operands);
12564 }
12565 else
12566 {
12567 output_asm_insn ("ldr\t%0, %1", operands);
12568 output_asm_insn ("ldr\t%H0, %2", operands);
12569 }
12570 break;
12571
12572 case CONST:
12573 /* Compute <address> + 4 for the high order load. */
12574 operands[2] = gen_rtx (MEM, SImode,
12575 plus_constant (XEXP (operands[1], 0), 4));
12576
12577 output_asm_insn ("ldr\t%0, %1", operands);
12578 output_asm_insn ("ldr\t%H0, %2", operands);
12579 break;
12580
12581 case PLUS:
12582 arg1 = XEXP (addr, 0);
12583 arg2 = XEXP (addr, 1);
12584
12585 if (CONSTANT_P (arg1))
12586 base = arg2, offset = arg1;
12587 else
12588 base = arg1, offset = arg2;
12589
12590 if (GET_CODE (base) != REG)
400500c4 12591 abort ();
d5b7b3ae
RE
12592
12593 /* Catch the case of <address> = <reg> + <reg> */
12594 if (GET_CODE (offset) == REG)
12595 {
12596 int reg_offset = REGNO (offset);
12597 int reg_base = REGNO (base);
12598 int reg_dest = REGNO (operands[0]);
12599
12600 /* Add the base and offset registers together into the
12601 higher destination register. */
12602 asm_fprintf (asm_out_file, "\tadd\t%r, %r, %r",
12603 reg_dest + 1, reg_base, reg_offset);
12604
12605 /* Load the lower destination register from the address in
12606 the higher destination register. */
12607 asm_fprintf (asm_out_file, "\tldr\t%r, [%r, #0]",
12608 reg_dest, reg_dest + 1);
12609
12610 /* Load the higher destination register from its own address
12611 plus 4. */
12612 asm_fprintf (asm_out_file, "\tldr\t%r, [%r, #4]",
12613 reg_dest + 1, reg_dest + 1);
12614 }
12615 else
12616 {
12617 /* Compute <address> + 4 for the high order load. */
12618 operands[2] = gen_rtx (MEM, SImode,
12619 plus_constant (XEXP (operands[1], 0), 4));
12620
12621 /* If the computed address is held in the low order register
12622 then load the high order register first, otherwise always
12623 load the low order register first. */
12624 if (REGNO (operands[0]) == REGNO (base))
12625 {
12626 output_asm_insn ("ldr\t%H0, %2", operands);
12627 output_asm_insn ("ldr\t%0, %1", operands);
12628 }
12629 else
12630 {
12631 output_asm_insn ("ldr\t%0, %1", operands);
12632 output_asm_insn ("ldr\t%H0, %2", operands);
12633 }
12634 }
12635 break;
12636
12637 case LABEL_REF:
12638 /* With no registers to worry about we can just load the value
12639 directly. */
12640 operands[2] = gen_rtx (MEM, SImode,
12641 plus_constant (XEXP (operands[1], 0), 4));
12642
12643 output_asm_insn ("ldr\t%H0, %2", operands);
12644 output_asm_insn ("ldr\t%0, %1", operands);
12645 break;
12646
12647 default:
400500c4 12648 abort ();
d5b7b3ae
RE
12649 break;
12650 }
12651
12652 return "";
12653}
12654
cd2b33d0 12655const char *
e32bac5b 12656thumb_output_move_mem_multiple (int n, rtx *operands)
d5b7b3ae
RE
12657{
12658 rtx tmp;
12659
12660 switch (n)
12661 {
12662 case 2:
ca356f3a 12663 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 12664 {
ca356f3a
RE
12665 tmp = operands[4];
12666 operands[4] = operands[5];
12667 operands[5] = tmp;
d5b7b3ae 12668 }
ca356f3a
RE
12669 output_asm_insn ("ldmia\t%1!, {%4, %5}", operands);
12670 output_asm_insn ("stmia\t%0!, {%4, %5}", operands);
d5b7b3ae
RE
12671 break;
12672
12673 case 3:
ca356f3a 12674 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 12675 {
ca356f3a
RE
12676 tmp = operands[4];
12677 operands[4] = operands[5];
12678 operands[5] = tmp;
d5b7b3ae 12679 }
ca356f3a 12680 if (REGNO (operands[5]) > REGNO (operands[6]))
d5b7b3ae 12681 {
ca356f3a
RE
12682 tmp = operands[5];
12683 operands[5] = operands[6];
12684 operands[6] = tmp;
d5b7b3ae 12685 }
ca356f3a 12686 if (REGNO (operands[4]) > REGNO (operands[5]))
d5b7b3ae 12687 {
ca356f3a
RE
12688 tmp = operands[4];
12689 operands[4] = operands[5];
12690 operands[5] = tmp;
d5b7b3ae
RE
12691 }
12692
ca356f3a
RE
12693 output_asm_insn ("ldmia\t%1!, {%4, %5, %6}", operands);
12694 output_asm_insn ("stmia\t%0!, {%4, %5, %6}", operands);
d5b7b3ae
RE
12695 break;
12696
12697 default:
12698 abort ();
12699 }
12700
12701 return "";
12702}
12703
1d6e90ac 12704/* Routines for generating rtl. */
d5b7b3ae 12705void
e32bac5b 12706thumb_expand_movstrqi (rtx *operands)
d5b7b3ae
RE
12707{
12708 rtx out = copy_to_mode_reg (SImode, XEXP (operands[0], 0));
12709 rtx in = copy_to_mode_reg (SImode, XEXP (operands[1], 0));
12710 HOST_WIDE_INT len = INTVAL (operands[2]);
12711 HOST_WIDE_INT offset = 0;
12712
12713 while (len >= 12)
12714 {
ca356f3a 12715 emit_insn (gen_movmem12b (out, in, out, in));
d5b7b3ae
RE
12716 len -= 12;
12717 }
12718
12719 if (len >= 8)
12720 {
ca356f3a 12721 emit_insn (gen_movmem8b (out, in, out, in));
d5b7b3ae
RE
12722 len -= 8;
12723 }
12724
12725 if (len >= 4)
12726 {
12727 rtx reg = gen_reg_rtx (SImode);
12728 emit_insn (gen_movsi (reg, gen_rtx (MEM, SImode, in)));
12729 emit_insn (gen_movsi (gen_rtx (MEM, SImode, out), reg));
12730 len -= 4;
12731 offset += 4;
12732 }
12733
12734 if (len >= 2)
12735 {
12736 rtx reg = gen_reg_rtx (HImode);
12737 emit_insn (gen_movhi (reg, gen_rtx (MEM, HImode,
12738 plus_constant (in, offset))));
12739 emit_insn (gen_movhi (gen_rtx (MEM, HImode, plus_constant (out, offset)),
12740 reg));
12741 len -= 2;
12742 offset += 2;
12743 }
12744
12745 if (len)
12746 {
12747 rtx reg = gen_reg_rtx (QImode);
12748 emit_insn (gen_movqi (reg, gen_rtx (MEM, QImode,
12749 plus_constant (in, offset))));
12750 emit_insn (gen_movqi (gen_rtx (MEM, QImode, plus_constant (out, offset)),
12751 reg));
12752 }
12753}
12754
12755int
e32bac5b 12756thumb_cmp_operand (rtx op, enum machine_mode mode)
d5b7b3ae
RE
12757{
12758 return ((GET_CODE (op) == CONST_INT
c769a35d
RE
12759 && INTVAL (op) < 256
12760 && INTVAL (op) >= 0)
defc0463 12761 || s_register_operand (op, mode));
d5b7b3ae
RE
12762}
12763
c769a35d
RE
12764int
12765thumb_cmpneg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
12766{
12767 return (GET_CODE (op) == CONST_INT
12768 && INTVAL (op) < 0
12769 && INTVAL (op) > -256);
12770}
12771
defc0463
RE
12772/* Return TRUE if a result can be stored in OP without clobbering the
12773 condition code register. Prior to reload we only accept a
12774 register. After reload we have to be able to handle memory as
12775 well, since a pseudo may not get a hard reg and reload cannot
12776 handle output-reloads on jump insns.
d5b7b3ae 12777
defc0463
RE
12778 We could possibly handle mem before reload as well, but that might
12779 complicate things with the need to handle increment
12780 side-effects. */
d5b7b3ae 12781
defc0463
RE
12782int
12783thumb_cbrch_target_operand (rtx op, enum machine_mode mode)
12784{
12785 return (s_register_operand (op, mode)
12786 || ((reload_in_progress || reload_completed)
12787 && memory_operand (op, mode)));
d5b7b3ae
RE
12788}
12789
12790/* Handle storing a half-word to memory during reload. */
12791void
e32bac5b 12792thumb_reload_out_hi (rtx *operands)
d5b7b3ae
RE
12793{
12794 emit_insn (gen_thumb_movhi_clobber (operands[0], operands[1], operands[2]));
12795}
12796
e32bac5b 12797/* Handle reading a half-word from memory during reload. */
d5b7b3ae 12798void
e32bac5b 12799thumb_reload_in_hi (rtx *operands ATTRIBUTE_UNUSED)
d5b7b3ae
RE
12800{
12801 abort ();
12802}
12803
c27ba912
DM
12804/* Return the length of a function name prefix
12805 that starts with the character 'c'. */
12806static int
e32bac5b 12807arm_get_strip_length (int c)
c27ba912
DM
12808{
12809 switch (c)
12810 {
12811 ARM_NAME_ENCODING_LENGTHS
12812 default: return 0;
12813 }
12814}
12815
12816/* Return a pointer to a function's name with any
12817 and all prefix encodings stripped from it. */
12818const char *
e32bac5b 12819arm_strip_name_encoding (const char *name)
c27ba912
DM
12820{
12821 int skip;
12822
12823 while ((skip = arm_get_strip_length (* name)))
12824 name += skip;
12825
12826 return name;
12827}
12828
e1944073
KW
12829/* If there is a '*' anywhere in the name's prefix, then
12830 emit the stripped name verbatim, otherwise prepend an
12831 underscore if leading underscores are being used. */
e1944073 12832void
e32bac5b 12833arm_asm_output_labelref (FILE *stream, const char *name)
e1944073
KW
12834{
12835 int skip;
12836 int verbatim = 0;
12837
12838 while ((skip = arm_get_strip_length (* name)))
12839 {
12840 verbatim |= (*name == '*');
12841 name += skip;
12842 }
12843
12844 if (verbatim)
12845 fputs (name, stream);
12846 else
12847 asm_fprintf (stream, "%U%s", name);
12848}
12849
e2500fed
GK
12850rtx aof_pic_label;
12851
2b835d68 12852#ifdef AOF_ASSEMBLER
6354dc9b 12853/* Special functions only needed when producing AOF syntax assembler. */
2b835d68 12854
32de079a
RE
12855struct pic_chain
12856{
62b10bbc 12857 struct pic_chain * next;
5f37d07c 12858 const char * symname;
32de079a
RE
12859};
12860
62b10bbc 12861static struct pic_chain * aof_pic_chain = NULL;
32de079a
RE
12862
12863rtx
e32bac5b 12864aof_pic_entry (rtx x)
32de079a 12865{
62b10bbc 12866 struct pic_chain ** chainp;
32de079a
RE
12867 int offset;
12868
12869 if (aof_pic_label == NULL_RTX)
12870 {
43cffd11 12871 aof_pic_label = gen_rtx_SYMBOL_REF (Pmode, "x$adcons");
32de079a
RE
12872 }
12873
12874 for (offset = 0, chainp = &aof_pic_chain; *chainp;
12875 offset += 4, chainp = &(*chainp)->next)
12876 if ((*chainp)->symname == XSTR (x, 0))
12877 return plus_constant (aof_pic_label, offset);
12878
12879 *chainp = (struct pic_chain *) xmalloc (sizeof (struct pic_chain));
12880 (*chainp)->next = NULL;
12881 (*chainp)->symname = XSTR (x, 0);
12882 return plus_constant (aof_pic_label, offset);
12883}
12884
12885void
e32bac5b 12886aof_dump_pic_table (FILE *f)
32de079a 12887{
62b10bbc 12888 struct pic_chain * chain;
32de079a
RE
12889
12890 if (aof_pic_chain == NULL)
12891 return;
12892
dd18ae56
NC
12893 asm_fprintf (f, "\tAREA |%r$$adcons|, BASED %r\n",
12894 PIC_OFFSET_TABLE_REGNUM,
12895 PIC_OFFSET_TABLE_REGNUM);
32de079a
RE
12896 fputs ("|x$adcons|\n", f);
12897
12898 for (chain = aof_pic_chain; chain; chain = chain->next)
12899 {
12900 fputs ("\tDCD\t", f);
12901 assemble_name (f, chain->symname);
12902 fputs ("\n", f);
12903 }
12904}
12905
2b835d68
RE
12906int arm_text_section_count = 1;
12907
12908char *
e32bac5b 12909aof_text_section (void )
2b835d68
RE
12910{
12911 static char buf[100];
2b835d68
RE
12912 sprintf (buf, "\tAREA |C$$code%d|, CODE, READONLY",
12913 arm_text_section_count++);
12914 if (flag_pic)
12915 strcat (buf, ", PIC, REENTRANT");
12916 return buf;
12917}
12918
12919static int arm_data_section_count = 1;
12920
12921char *
e32bac5b 12922aof_data_section (void)
2b835d68
RE
12923{
12924 static char buf[100];
12925 sprintf (buf, "\tAREA |C$$data%d|, DATA", arm_data_section_count++);
12926 return buf;
12927}
12928
12929/* The AOF assembler is religiously strict about declarations of
12930 imported and exported symbols, so that it is impossible to declare
956d6950 12931 a function as imported near the beginning of the file, and then to
2b835d68
RE
12932 export it later on. It is, however, possible to delay the decision
12933 until all the functions in the file have been compiled. To get
12934 around this, we maintain a list of the imports and exports, and
12935 delete from it any that are subsequently defined. At the end of
12936 compilation we spit the remainder of the list out before the END
12937 directive. */
12938
12939struct import
12940{
62b10bbc 12941 struct import * next;
5f37d07c 12942 const char * name;
2b835d68
RE
12943};
12944
62b10bbc 12945static struct import * imports_list = NULL;
2b835d68
RE
12946
12947void
e32bac5b 12948aof_add_import (const char *name)
2b835d68 12949{
62b10bbc 12950 struct import * new;
2b835d68
RE
12951
12952 for (new = imports_list; new; new = new->next)
12953 if (new->name == name)
12954 return;
12955
12956 new = (struct import *) xmalloc (sizeof (struct import));
12957 new->next = imports_list;
12958 imports_list = new;
12959 new->name = name;
12960}
12961
12962void
e32bac5b 12963aof_delete_import (const char *name)
2b835d68 12964{
62b10bbc 12965 struct import ** old;
2b835d68
RE
12966
12967 for (old = &imports_list; *old; old = & (*old)->next)
12968 {
12969 if ((*old)->name == name)
12970 {
12971 *old = (*old)->next;
12972 return;
12973 }
12974 }
12975}
12976
12977int arm_main_function = 0;
12978
a5fe455b 12979static void
e32bac5b 12980aof_dump_imports (FILE *f)
2b835d68
RE
12981{
12982 /* The AOF assembler needs this to cause the startup code to be extracted
12983 from the library. Brining in __main causes the whole thing to work
12984 automagically. */
12985 if (arm_main_function)
12986 {
12987 text_section ();
12988 fputs ("\tIMPORT __main\n", f);
12989 fputs ("\tDCD __main\n", f);
12990 }
12991
12992 /* Now dump the remaining imports. */
12993 while (imports_list)
12994 {
12995 fprintf (f, "\tIMPORT\t");
12996 assemble_name (f, imports_list->name);
12997 fputc ('\n', f);
12998 imports_list = imports_list->next;
12999 }
13000}
5eb99654
KG
13001
13002static void
e32bac5b 13003aof_globalize_label (FILE *stream, const char *name)
5eb99654
KG
13004{
13005 default_globalize_label (stream, name);
13006 if (! strcmp (name, "main"))
13007 arm_main_function = 1;
13008}
a5fe455b 13009
1bc7c5b6
ZW
13010static void
13011aof_file_start ()
13012{
13013 fputs ("__r0\tRN\t0\n", asm_out_file);
13014 fputs ("__a1\tRN\t0\n", asm_out_file);
13015 fputs ("__a2\tRN\t1\n", asm_out_file);
13016 fputs ("__a3\tRN\t2\n", asm_out_file);
13017 fputs ("__a4\tRN\t3\n", asm_out_file);
13018 fputs ("__v1\tRN\t4\n", asm_out_file);
13019 fputs ("__v2\tRN\t5\n", asm_out_file);
13020 fputs ("__v3\tRN\t6\n", asm_out_file);
13021 fputs ("__v4\tRN\t7\n", asm_out_file);
13022 fputs ("__v5\tRN\t8\n", asm_out_file);
13023 fputs ("__v6\tRN\t9\n", asm_out_file);
13024 fputs ("__sl\tRN\t10\n", asm_out_file);
13025 fputs ("__fp\tRN\t11\n", asm_out_file);
13026 fputs ("__ip\tRN\t12\n", asm_out_file);
13027 fputs ("__sp\tRN\t13\n", asm_out_file);
13028 fputs ("__lr\tRN\t14\n", asm_out_file);
13029 fputs ("__pc\tRN\t15\n", asm_out_file);
13030 fputs ("__f0\tFN\t0\n", asm_out_file);
13031 fputs ("__f1\tFN\t1\n", asm_out_file);
13032 fputs ("__f2\tFN\t2\n", asm_out_file);
13033 fputs ("__f3\tFN\t3\n", asm_out_file);
13034 fputs ("__f4\tFN\t4\n", asm_out_file);
13035 fputs ("__f5\tFN\t5\n", asm_out_file);
13036 fputs ("__f6\tFN\t6\n", asm_out_file);
13037 fputs ("__f7\tFN\t7\n", asm_out_file);
13038 text_section ();
13039}
13040
a5fe455b 13041static void
e32bac5b 13042aof_file_end (void)
a5fe455b
ZW
13043{
13044 if (flag_pic)
13045 aof_dump_pic_table (asm_out_file);
13046 aof_dump_imports (asm_out_file);
13047 fputs ("\tEND\n", asm_out_file);
13048}
2b835d68 13049#endif /* AOF_ASSEMBLER */
7c262518 13050
ebe413e5 13051#ifdef OBJECT_FORMAT_ELF
7c262518
RH
13052/* Switch to an arbitrary section NAME with attributes as specified
13053 by FLAGS. ALIGN specifies any known alignment requirements for
13054 the section; 0 if the default should be used.
13055
13056 Differs from the default elf version only in the prefix character
13057 used before the section type. */
13058
13059static void
e32bac5b 13060arm_elf_asm_named_section (const char *name, unsigned int flags)
7c262518 13061{
6a0a6ac4
AM
13062 char flagchars[10], *f = flagchars;
13063
13064 if (! named_section_first_declaration (name))
13065 {
13066 fprintf (asm_out_file, "\t.section\t%s\n", name);
13067 return;
13068 }
7c262518
RH
13069
13070 if (!(flags & SECTION_DEBUG))
13071 *f++ = 'a';
13072 if (flags & SECTION_WRITE)
13073 *f++ = 'w';
13074 if (flags & SECTION_CODE)
13075 *f++ = 'x';
13076 if (flags & SECTION_SMALL)
13077 *f++ = 's';
201556f0
JJ
13078 if (flags & SECTION_MERGE)
13079 *f++ = 'M';
13080 if (flags & SECTION_STRINGS)
13081 *f++ = 'S';
6a0a6ac4
AM
13082 if (flags & SECTION_TLS)
13083 *f++ = 'T';
7c262518
RH
13084 *f = '\0';
13085
6a0a6ac4 13086 fprintf (asm_out_file, "\t.section\t%s,\"%s\"", name, flagchars);
7c262518 13087
6a0a6ac4
AM
13088 if (!(flags & SECTION_NOTYPE))
13089 {
13090 const char *type;
13091
13092 if (flags & SECTION_BSS)
13093 type = "nobits";
13094 else
13095 type = "progbits";
13096
13097 fprintf (asm_out_file, ",%%%s", type);
13098
13099 if (flags & SECTION_ENTSIZE)
13100 fprintf (asm_out_file, ",%d", flags & SECTION_ENTSIZE);
13101 }
13102
13103 putc ('\n', asm_out_file);
7c262518 13104}
ebe413e5 13105#endif
fb49053f
RH
13106
13107#ifndef ARM_PE
13108/* Symbols in the text segment can be accessed without indirecting via the
13109 constant pool; it may take an extra binary operation, but this is still
13110 faster than indirecting via memory. Don't do this when not optimizing,
13111 since we won't be calculating al of the offsets necessary to do this
13112 simplification. */
13113
13114static void
e32bac5b 13115arm_encode_section_info (tree decl, rtx rtl, int first)
fb49053f
RH
13116{
13117 /* This doesn't work with AOF syntax, since the string table may be in
13118 a different AREA. */
13119#ifndef AOF_ASSEMBLER
13120 if (optimize > 0 && TREE_CONSTANT (decl)
13121 && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST))
c6a2438a 13122 SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
fb49053f
RH
13123#endif
13124
13125 /* If we are referencing a function that is weak then encode a long call
13126 flag in the function name, otherwise if the function is static or
13127 or known to be defined in this file then encode a short call flag. */
13128 if (first && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
13129 {
13130 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl))
13131 arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR);
13132 else if (! TREE_PUBLIC (decl))
13133 arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR);
13134 }
13135}
13136#endif /* !ARM_PE */
483ab821 13137
4977bab6 13138static void
e32bac5b 13139arm_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
4977bab6
ZW
13140{
13141 if (arm_ccfsm_state == 3 && (unsigned) arm_target_label == labelno
13142 && !strcmp (prefix, "L"))
13143 {
13144 arm_ccfsm_state = 0;
13145 arm_target_insn = NULL;
13146 }
13147 default_internal_label (stream, prefix, labelno);
13148}
13149
c590b625
RH
13150/* Output code to add DELTA to the first argument, and then jump
13151 to FUNCTION. Used for C++ multiple inheritance. */
c590b625 13152static void
e32bac5b
RE
13153arm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
13154 HOST_WIDE_INT delta,
13155 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
13156 tree function)
483ab821
MM
13157{
13158 int mi_delta = delta;
13159 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
13160 int shift = 0;
61f71b34 13161 int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function)
483ab821
MM
13162 ? 1 : 0);
13163 if (mi_delta < 0)
13164 mi_delta = - mi_delta;
13165 while (mi_delta != 0)
13166 {
13167 if ((mi_delta & (3 << shift)) == 0)
13168 shift += 2;
13169 else
13170 {
13171 asm_fprintf (file, "\t%s\t%r, %r, #%d\n",
13172 mi_op, this_regno, this_regno,
13173 mi_delta & (0xff << shift));
13174 mi_delta &= ~(0xff << shift);
13175 shift += 8;
13176 }
13177 }
13178 fputs ("\tb\t", file);
13179 assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
13180 if (NEED_PLT_RELOC)
13181 fputs ("(PLT)", file);
13182 fputc ('\n', file);
13183}
5a9335ef
NC
13184
13185int
6f5f2481 13186arm_emit_vector_const (FILE *file, rtx x)
5a9335ef
NC
13187{
13188 int i;
13189 const char * pattern;
13190
13191 if (GET_CODE (x) != CONST_VECTOR)
13192 abort ();
13193
13194 switch (GET_MODE (x))
13195 {
13196 case V2SImode: pattern = "%08x"; break;
13197 case V4HImode: pattern = "%04x"; break;
13198 case V8QImode: pattern = "%02x"; break;
13199 default: abort ();
13200 }
13201
13202 fprintf (file, "0x");
13203 for (i = CONST_VECTOR_NUNITS (x); i--;)
13204 {
13205 rtx element;
13206
13207 element = CONST_VECTOR_ELT (x, i);
13208 fprintf (file, pattern, INTVAL (element));
13209 }
13210
13211 return 1;
13212}
13213
13214const char *
6f5f2481 13215arm_output_load_gr (rtx *operands)
5a9335ef
NC
13216{
13217 rtx reg;
13218 rtx offset;
13219 rtx wcgr;
13220 rtx sum;
13221
13222 if (GET_CODE (operands [1]) != MEM
13223 || GET_CODE (sum = XEXP (operands [1], 0)) != PLUS
13224 || GET_CODE (reg = XEXP (sum, 0)) != REG
13225 || GET_CODE (offset = XEXP (sum, 1)) != CONST_INT
13226 || ((INTVAL (offset) < 1024) && (INTVAL (offset) > -1024)))
13227 return "wldrw%?\t%0, %1";
13228
13229 /* Fix up an out-of-range load of a GR register. */
13230 output_asm_insn ("str%?\t%0, [sp, #-4]!\t@ Start of GR load expansion", & reg);
13231 wcgr = operands[0];
13232 operands[0] = reg;
13233 output_asm_insn ("ldr%?\t%0, %1", operands);
13234
13235 operands[0] = wcgr;
13236 operands[1] = reg;
13237 output_asm_insn ("tmcr%?\t%0, %1", operands);
13238 output_asm_insn ("ldr%?\t%0, [sp], #4\t@ End of GR load expansion", & reg);
13239
13240 return "";
13241}
This page took 3.56309 seconds and 5 git commands to generate.