2007-03-01 Paul Brook <paul@codesourcery.com>
[official-gcc.git] / gcc / config / arm / arm.c
Commit [+]AuthorDateLineData
129a2fe4 rearnsha1999-02-06 04:09:55 +00001/* Output routines for GCC for ARM.
a941568e rearnsha2004-01-13 13:24:37 +00002 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
25f905c2 pbrook2007-01-03 23:48:10 +00003 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
8cd42699 mycroft1992-03-14 05:17:02 +00004 Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
ad87de1e law1997-12-07 00:31:01 +00005 and Martin Simmons (@harleqn.co.uk).
129a2fe4 rearnsha1999-02-06 04:09:55 +00006 More major hacks by Richard Earnshaw (rearnsha@arm.com).
8cd42699 mycroft1992-03-14 05:17:02 +00007
acf6ed70 nickc2003-02-10 16:33:09 +00008 This file is part of GCC.
8cd42699 mycroft1992-03-14 05:17:02 +00009
acf6ed70 nickc2003-02-10 16:33:09 +000010 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.
8cd42699 mycroft1992-03-14 05:17:02 +000014
acf6ed70 nickc2003-02-10 16:33:09 +000015 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.
8cd42699 mycroft1992-03-14 05:17:02 +000019
acf6ed70 nickc2003-02-10 16:33:09 +000020 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING. If not, write to
dbddc6c4 kcook2005-06-25 01:22:41 +000022 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, USA. */
9e7454d0 echristo2004-08-24 00:30:52 +000024
6019008a law1997-11-03 02:26:49 +000025#include "config.h"
76676c8e rearnsha1999-02-13 05:41:18 +000026#include "system.h"
805e22b2 zack2002-12-16 18:23:00 +000027#include "coretypes.h"
28#include "tm.h"
8cd42699 mycroft1992-03-14 05:17:02 +000029#include "rtl.h"
cffb2a26 rearnsha2000-04-08 14:29:53 +000030#include "tree.h"
a220ccce rearnsha2000-10-13 15:54:16 +000031#include "obstack.h"
8cd42699 mycroft1992-03-14 05:17:02 +000032#include "regs.h"
33#include "hard-reg-set.h"
34#include "real.h"
35#include "insn-config.h"
36#include "conditions.h"
8cd42699 mycroft1992-03-14 05:17:02 +000037#include "output.h"
38#include "insn-attr.h"
39#include "flags.h"
9c1b36a9 kenner1993-10-19 21:40:00 +000040#include "reload.h"
0a893c29 crux1999-08-09 14:00:21 +000041#include "function.h"
411b0ddb erich1994-06-27 15:24:36 +000042#include "expr.h"
d8fc4d0b zack2001-08-13 15:56:51 +000043#include "optabs.h"
ecd3fcc7 rearnsha1998-05-26 09:30:56 +000044#include "toplev.h"
82ec49ae nickc1999-03-17 14:47:27 +000045#include "recog.h"
db80f614 rearnsha1999-09-09 14:30:54 +000046#include "ggc.h"
cffb2a26 rearnsha2000-04-08 14:29:53 +000047#include "except.h"
1fcd08b1 zack2000-09-07 22:24:34 +000048#include "c-pragma.h"
2d9065d3 nickc2001-06-24 09:46:02 +000049#include "integrate.h"
78fe751b nickc2000-02-29 01:42:52 +000050#include "tm_p.h"
a767736d neil2001-06-26 18:09:27 +000051#include "target.h"
52#include "target-def.h"
37826745 drow2004-01-22 17:00:56 +000053#include "debug.h"
e60d3615 jsm282004-07-17 19:35:04 +000054#include "langhooks.h"
8cd42699 mycroft1992-03-14 05:17:02 +000055
cffb2a26 rearnsha2000-04-08 14:29:53 +000056/* Forward definitions of types. */
57typedef struct minipool_node Mnode;
58typedef struct minipool_fixup Mfix;
59
a12be13c nickc2002-01-16 12:25:53 +000060const struct attribute_spec arm_attribute_table[];
61
cffb2a26 rearnsha2000-04-08 14:29:53 +000062/* Forward function declarations. */
f9273c43 pbrook2004-03-24 17:20:16 +000063static arm_stack_offsets *arm_get_frame_offsets (void);
ebd88a36 rearnsha2003-06-10 18:55:17 +000064static void arm_add_gc_roots (void);
96f57e36 mmitchel2004-04-01 23:30:25 +000065static int arm_gen_constant (enum rtx_code, enum machine_mode, rtx,
66 HOST_WIDE_INT, rtx, rtx, int, int);
ebd88a36 rearnsha2003-06-10 18:55:17 +000067static unsigned bit_count (unsigned long);
68static int arm_address_register_rtx_p (rtx, int);
b4e8a300 rearnsha2004-03-13 11:19:23 +000069static int arm_legitimate_index_p (enum machine_mode, rtx, RTX_CODE, int);
25f905c2 pbrook2007-01-03 23:48:10 +000070static int thumb2_legitimate_index_p (enum machine_mode, rtx, int);
71static int thumb1_base_register_rtx_p (rtx, enum machine_mode, int);
72inline static int thumb1_index_register_rtx_p (rtx, int);
f9273c43 pbrook2004-03-24 17:20:16 +000073static int thumb_far_jump_used_p (void);
237533cc pbrook2004-08-11 20:59:15 +000074static bool thumb_force_lr_save (void);
25f905c2 pbrook2007-01-03 23:48:10 +000075static unsigned long thumb1_compute_save_reg_mask (void);
ebd88a36 rearnsha2003-06-10 18:55:17 +000076static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
ebd88a36 rearnsha2003-06-10 18:55:17 +000077static rtx emit_sfm (int, int);
0858d94e pbrook2005-05-13 21:13:17 +000078static int arm_size_return_regs (void);
58356836 rsandifo2001-12-17 15:05:40 +000079#ifndef AOF_ASSEMBLER
ebd88a36 rearnsha2003-06-10 18:55:17 +000080static bool arm_assemble_integer (rtx, unsigned int, int);
58356836 rsandifo2001-12-17 15:05:40 +000081#endif
ebd88a36 rearnsha2003-06-10 18:55:17 +000082static const char *fp_const_from_val (REAL_VALUE_TYPE *);
83static arm_cc get_arm_condition_code (rtx);
ebd88a36 rearnsha2003-06-10 18:55:17 +000084static HOST_WIDE_INT int_log2 (HOST_WIDE_INT);
85static rtx is_jump_table (rtx);
86static const char *output_multi_immediate (rtx *, const char *, const char *,
87 int, HOST_WIDE_INT);
ebd88a36 rearnsha2003-06-10 18:55:17 +000088static const char *shift_op (rtx, HOST_WIDE_INT *);
89static struct machine_function *arm_init_machine_status (void);
4c44712e pbrook2004-08-10 16:22:47 +000090static void thumb_exit (FILE *, int);
ebd88a36 rearnsha2003-06-10 18:55:17 +000091static rtx is_jump_table (rtx);
92static HOST_WIDE_INT get_jump_table_size (rtx);
93static Mnode *move_minipool_fix_forward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
94static Mnode *add_minipool_forward_ref (Mfix *);
95static Mnode *move_minipool_fix_backward_ref (Mnode *, Mnode *, HOST_WIDE_INT);
96static Mnode *add_minipool_backward_ref (Mfix *);
97static void assign_minipool_offsets (Mfix *);
98static void arm_print_value (FILE *, rtx);
99static void dump_minipool (rtx);
100static int arm_barrier_cost (rtx);
101static Mfix *create_fix_barrier (Mfix *, HOST_WIDE_INT);
102static void push_minipool_barrier (rtx, HOST_WIDE_INT);
103static void push_minipool_fix (rtx, HOST_WIDE_INT, rtx *, enum machine_mode,
104 rtx);
105static void arm_reorg (void);
106static bool note_invalid_constants (rtx, HOST_WIDE_INT, int);
107static int current_file_function_operand (rtx);
108static unsigned long arm_compute_save_reg0_reg12_mask (void);
109static unsigned long arm_compute_save_reg_mask (void);
110static unsigned long arm_isr_value (tree);
111static unsigned long arm_compute_func_type (void);
112static tree arm_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
113static tree arm_handle_isr_attribute (tree *, tree, tree, int, bool *);
56826b58 rearnsha2004-11-08 17:17:30 +0000114#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
a79b1d93 mmitchel2004-11-05 00:18:51 +0000115static tree arm_handle_notshared_attribute (tree *, tree, tree, int, bool *);
56826b58 rearnsha2004-11-08 17:17:30 +0000116#endif
ebd88a36 rearnsha2003-06-10 18:55:17 +0000117static void arm_output_function_epilogue (FILE *, HOST_WIDE_INT);
118static void arm_output_function_prologue (FILE *, HOST_WIDE_INT);
25f905c2 pbrook2007-01-03 23:48:10 +0000119static void thumb1_output_function_prologue (FILE *, HOST_WIDE_INT);
ebd88a36 rearnsha2003-06-10 18:55:17 +0000120static int arm_comp_type_attributes (tree, tree);
121static void arm_set_default_type_attributes (tree);
122static int arm_adjust_cost (rtx, rtx, rtx, int);
ebd88a36 rearnsha2003-06-10 18:55:17 +0000123static int count_insns_for_constant (HOST_WIDE_INT, int);
124static int arm_get_strip_length (int);
125static bool arm_function_ok_for_sibcall (tree, tree);
126static void arm_internal_label (FILE *, const char *, unsigned long);
127static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
128 tree);
129static int arm_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
c1877da8 rearnsha2004-08-18 22:23:57 +0000130static bool arm_size_rtx_costs (rtx, int, int, int *);
a2cd141b pbrook2004-02-03 14:45:44 +0000131static bool arm_slowmul_rtx_costs (rtx, int, int, int *);
132static bool arm_fastmul_rtx_costs (rtx, int, int, int *);
133static bool arm_xscale_rtx_costs (rtx, int, int, int *);
134static bool arm_9e_rtx_costs (rtx, int, int, int *);
ebd88a36 rearnsha2003-06-10 18:55:17 +0000135static int arm_address_cost (rtx);
136static bool arm_memory_load_p (rtx);
137static bool arm_cirrus_insn_p (rtx);
138static void cirrus_reorg (rtx);
755eb2b4 nickc2003-06-18 16:36:13 +0000139static void arm_init_builtins (void);
140static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
141static void arm_init_iwmmxt_builtins (void);
142static rtx safe_vector_operand (rtx, enum machine_mode);
143static rtx arm_expand_binop_builtin (enum insn_code, tree, rtx);
144static rtx arm_expand_unop_builtin (enum insn_code, tree, rtx, int);
145static rtx arm_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
96f57e36 mmitchel2004-04-01 23:30:25 +0000146static void emit_constant_insn (rtx cond, rtx pattern);
0083a3b9 rearnsha2005-11-22 14:30:10 +0000147static rtx emit_set_insn (rtx, rtx);
f054eb3c rth2004-12-30 03:08:18 +0000148static int arm_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
149 tree, bool);
755eb2b4 nickc2003-06-18 16:36:13 +0000150
d24bc145 jules2005-04-29 14:09:45 +0000151#ifdef OBJECT_FORMAT_ELF
152static void arm_elf_asm_constructor (rtx, int);
153#endif
7811991d rth2002-05-19 05:23:27 +0000154#ifndef ARM_PE
ebd88a36 rearnsha2003-06-10 18:55:17 +0000155static void arm_encode_section_info (tree, rtx, int);
7811991d rth2002-05-19 05:23:27 +0000156#endif
afe27f3b rearnsha2005-01-14 13:58:40 +0000157
158static void arm_file_end (void);
5fad5123 pbrook2006-11-03 17:49:43 +0000159static void arm_file_start (void);
afe27f3b rearnsha2005-01-14 13:58:40 +0000160
67c1e638 ghazi2002-08-21 02:41:51 +0000161#ifdef AOF_ASSEMBLER
ebd88a36 rearnsha2003-06-10 18:55:17 +0000162static void aof_globalize_label (FILE *, const char *);
163static void aof_dump_imports (FILE *);
164static void aof_dump_pic_table (FILE *);
92c473b8 zack2003-06-19 21:47:26 +0000165static void aof_file_start (void);
ebd88a36 rearnsha2003-06-10 18:55:17 +0000166static void aof_file_end (void);
2f14b1f9 rsandifo2005-12-07 07:53:14 +0000167static void aof_asm_init_sections (void);
67c1e638 ghazi2002-08-21 02:41:51 +0000168#endif
4c66acf1 kazu2004-01-26 16:35:44 +0000169static void arm_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
170 tree, int *, int);
b981d932 rth2004-07-14 06:24:27 +0000171static bool arm_pass_by_reference (CUMULATIVE_ARGS *,
172 enum machine_mode, tree, bool);
72f1246c pbrook2004-04-27 14:20:10 +0000173static bool arm_promote_prototypes (tree);
7faec15f pbrook2004-05-13 11:16:27 +0000174static bool arm_default_short_enums (void);
25ba5be6 pbrook2004-05-14 12:53:11 +0000175static bool arm_align_anon_bitfield (void);
46b5d878 jules2005-04-26 16:30:37 +0000176static bool arm_return_in_msb (tree);
177static bool arm_must_pass_in_stack (enum machine_mode, tree);
1774763d pbrook2005-06-28 19:52:27 +0000178#ifdef TARGET_UNWIND_INFO
179static void arm_unwind_emit (FILE *, rtx);
180static bool arm_output_ttype (rtx);
181#endif
25f905c2 pbrook2007-01-03 23:48:10 +0000182static void arm_dwarf_handle_frame_unspec (const char *, rtx, int);
747af5e7 zack2001-08-18 20:25:54 +0000183
c1dc02de pbrook2004-06-25 17:15:46 +0000184static tree arm_cxx_guard_type (void);
185static bool arm_cxx_guard_mask_bit (void);
600f4be7 pbrook2004-06-29 14:50:35 +0000186static tree arm_get_cookie_size (tree);
187static bool arm_cookie_has_size (void);
853b7640 pbrook2004-08-04 15:33:51 +0000188static bool arm_cxx_cdtor_returns_this (void);
4fc9a8ec mmitchel2004-09-01 03:45:30 +0000189static bool arm_cxx_key_method_may_be_inline (void);
7908506d mmitchel2005-04-12 06:33:48 +0000190static void arm_cxx_determine_class_data_visibility (tree);
191static bool arm_cxx_class_data_always_comdat (void);
46b9ff5e jules2005-04-25 19:35:18 +0000192static bool arm_cxx_use_aeabi_atexit (void);
30e9913f mmitchel2004-08-11 02:50:14 +0000193static void arm_init_libfuncs (void);
81f6de2f rsandifo2005-05-05 12:09:00 +0000194static bool arm_handle_option (size_t, const char *, int);
c49547c4 rsandifo2004-09-04 08:50:36 +0000195static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
f655717d drow2005-11-04 15:02:51 +0000196static bool arm_cannot_copy_insn_p (rtx);
197static bool arm_tls_symbol_p (rtx x);
198
a767736d neil2001-06-26 18:09:27 +0000199\f
200/* Initialize the GCC target structure. */
3aa0c315 mmitchel2004-08-06 02:03:29 +0000201#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
a12be13c nickc2002-01-16 12:25:53 +0000202#undef TARGET_MERGE_DECL_ATTRIBUTES
a767736d neil2001-06-26 18:09:27 +0000203#define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
204#endif
a690ede2 erich1994-06-01 17:09:29 +0000205
a12be13c nickc2002-01-16 12:25:53 +0000206#undef TARGET_ATTRIBUTE_TABLE
e3c541f0 jsm282001-09-21 01:27:06 +0000207#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
a767736d neil2001-06-26 18:09:27 +0000208
5fad5123 pbrook2006-11-03 17:49:43 +0000209#undef TARGET_ASM_FILE_START
210#define TARGET_ASM_FILE_START arm_file_start
afe27f3b rearnsha2005-01-14 13:58:40 +0000211#undef TARGET_ASM_FILE_END
212#define TARGET_ASM_FILE_END arm_file_end
213
58356836 rsandifo2001-12-17 15:05:40 +0000214#ifdef AOF_ASSEMBLER
a12be13c nickc2002-01-16 12:25:53 +0000215#undef TARGET_ASM_BYTE_OP
58356836 rsandifo2001-12-17 15:05:40 +0000216#define TARGET_ASM_BYTE_OP "\tDCB\t"
a12be13c nickc2002-01-16 12:25:53 +0000217#undef TARGET_ASM_ALIGNED_HI_OP
58356836 rsandifo2001-12-17 15:05:40 +0000218#define TARGET_ASM_ALIGNED_HI_OP "\tDCW\t"
a12be13c nickc2002-01-16 12:25:53 +0000219#undef TARGET_ASM_ALIGNED_SI_OP
58356836 rsandifo2001-12-17 15:05:40 +0000220#define TARGET_ASM_ALIGNED_SI_OP "\tDCD\t"
67c1e638 ghazi2002-08-21 02:41:51 +0000221#undef TARGET_ASM_GLOBALIZE_LABEL
222#define TARGET_ASM_GLOBALIZE_LABEL aof_globalize_label
92c473b8 zack2003-06-19 21:47:26 +0000223#undef TARGET_ASM_FILE_START
224#define TARGET_ASM_FILE_START aof_file_start
f6940372 zack2003-06-07 17:11:48 +0000225#undef TARGET_ASM_FILE_END
226#define TARGET_ASM_FILE_END aof_file_end
58356836 rsandifo2001-12-17 15:05:40 +0000227#else
a12be13c nickc2002-01-16 12:25:53 +0000228#undef TARGET_ASM_ALIGNED_SI_OP
58356836 rsandifo2001-12-17 15:05:40 +0000229#define TARGET_ASM_ALIGNED_SI_OP NULL
a12be13c nickc2002-01-16 12:25:53 +0000230#undef TARGET_ASM_INTEGER
58356836 rsandifo2001-12-17 15:05:40 +0000231#define TARGET_ASM_INTEGER arm_assemble_integer
232#endif
233
a12be13c nickc2002-01-16 12:25:53 +0000234#undef TARGET_ASM_FUNCTION_PROLOGUE
17d9b0c3 neil2001-07-06 18:40:17 +0000235#define TARGET_ASM_FUNCTION_PROLOGUE arm_output_function_prologue
236
a12be13c nickc2002-01-16 12:25:53 +0000237#undef TARGET_ASM_FUNCTION_EPILOGUE
17d9b0c3 neil2001-07-06 18:40:17 +0000238#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
239
81f6de2f rsandifo2005-05-05 12:09:00 +0000240#undef TARGET_DEFAULT_TARGET_FLAGS
241#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_SCHED_PROLOG)
242#undef TARGET_HANDLE_OPTION
243#define TARGET_HANDLE_OPTION arm_handle_option
244
a12be13c nickc2002-01-16 12:25:53 +0000245#undef TARGET_COMP_TYPE_ATTRIBUTES
f32321da jsm282001-06-29 17:21:16 +0000246#define TARGET_COMP_TYPE_ATTRIBUTES arm_comp_type_attributes
247
a12be13c nickc2002-01-16 12:25:53 +0000248#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
f32321da jsm282001-06-29 17:21:16 +0000249#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES arm_set_default_type_attributes
250
a12be13c nickc2002-01-16 12:25:53 +0000251#undef TARGET_SCHED_ADJUST_COST
747af5e7 zack2001-08-18 20:25:54 +0000252#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
253
7811991d rth2002-05-19 05:23:27 +0000254#undef TARGET_ENCODE_SECTION_INFO
255#ifdef ARM_PE
256#define TARGET_ENCODE_SECTION_INFO arm_pe_encode_section_info
257#else
258#define TARGET_ENCODE_SECTION_INFO arm_encode_section_info
259#endif
260
755eb2b4 nickc2003-06-18 16:36:13 +0000261#undef TARGET_STRIP_NAME_ENCODING
7b4a38a6 rth2002-05-19 07:55:48 +0000262#define TARGET_STRIP_NAME_ENCODING arm_strip_name_encoding
263
755eb2b4 nickc2003-06-18 16:36:13 +0000264#undef TARGET_ASM_INTERNAL_LABEL
805e22b2 zack2002-12-16 18:23:00 +0000265#define TARGET_ASM_INTERNAL_LABEL arm_internal_label
266
755eb2b4 nickc2003-06-18 16:36:13 +0000267#undef TARGET_FUNCTION_OK_FOR_SIBCALL
805e22b2 zack2002-12-16 18:23:00 +0000268#define TARGET_FUNCTION_OK_FOR_SIBCALL arm_function_ok_for_sibcall
269
755eb2b4 nickc2003-06-18 16:36:13 +0000270#undef TARGET_ASM_OUTPUT_MI_THUNK
6988553d rth2002-10-20 22:37:14 +0000271#define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
755eb2b4 nickc2003-06-18 16:36:13 +0000272#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
eb344f43 rth2002-10-22 23:05:28 +0000273#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
6988553d rth2002-10-20 22:37:14 +0000274
a2cd141b pbrook2004-02-03 14:45:44 +0000275/* This will be overridden in arm_override_options. */
755eb2b4 nickc2003-06-18 16:36:13 +0000276#undef TARGET_RTX_COSTS
a2cd141b pbrook2004-02-03 14:45:44 +0000277#define TARGET_RTX_COSTS arm_slowmul_rtx_costs
755eb2b4 nickc2003-06-18 16:36:13 +0000278#undef TARGET_ADDRESS_COST
ec0457a8 rth2003-01-28 18:08:56 +0000279#define TARGET_ADDRESS_COST arm_address_cost
fab7adbf rth2003-01-28 04:46:33 +0000280
c49547c4 rsandifo2004-09-04 08:50:36 +0000281#undef TARGET_SHIFT_TRUNCATION_MASK
282#define TARGET_SHIFT_TRUNCATION_MASK arm_shift_truncation_mask
9e7454d0 echristo2004-08-24 00:30:52 +0000283#undef TARGET_VECTOR_MODE_SUPPORTED_P
284#define TARGET_VECTOR_MODE_SUPPORTED_P arm_vector_mode_supported_p
285
755eb2b4 nickc2003-06-18 16:36:13 +0000286#undef TARGET_MACHINE_DEPENDENT_REORG
2efea8c0 rsandifo2003-05-14 07:29:54 +0000287#define TARGET_MACHINE_DEPENDENT_REORG arm_reorg
288
755eb2b4 nickc2003-06-18 16:36:13 +0000289#undef TARGET_INIT_BUILTINS
290#define TARGET_INIT_BUILTINS arm_init_builtins
291#undef TARGET_EXPAND_BUILTIN
292#define TARGET_EXPAND_BUILTIN arm_expand_builtin
293
30e9913f mmitchel2004-08-11 02:50:14 +0000294#undef TARGET_INIT_LIBFUNCS
295#define TARGET_INIT_LIBFUNCS arm_init_libfuncs
296
f2eb2b4d kazu2004-01-26 15:40:04 +0000297#undef TARGET_PROMOTE_FUNCTION_ARGS
298#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
19347327 pbrook2004-04-08 18:26:09 +0000299#undef TARGET_PROMOTE_FUNCTION_RETURN
300#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
f2eb2b4d kazu2004-01-26 15:40:04 +0000301#undef TARGET_PROMOTE_PROTOTYPES
72f1246c pbrook2004-04-27 14:20:10 +0000302#define TARGET_PROMOTE_PROTOTYPES arm_promote_prototypes
b981d932 rth2004-07-14 06:24:27 +0000303#undef TARGET_PASS_BY_REFERENCE
304#define TARGET_PASS_BY_REFERENCE arm_pass_by_reference
f054eb3c rth2004-12-30 03:08:18 +0000305#undef TARGET_ARG_PARTIAL_BYTES
306#define TARGET_ARG_PARTIAL_BYTES arm_arg_partial_bytes
f2eb2b4d kazu2004-01-26 15:40:04 +0000307
4c66acf1 kazu2004-01-26 16:35:44 +0000308#undef TARGET_SETUP_INCOMING_VARARGS
309#define TARGET_SETUP_INCOMING_VARARGS arm_setup_incoming_varargs
310
7faec15f pbrook2004-05-13 11:16:27 +0000311#undef TARGET_DEFAULT_SHORT_ENUMS
312#define TARGET_DEFAULT_SHORT_ENUMS arm_default_short_enums
313
25ba5be6 pbrook2004-05-14 12:53:11 +0000314#undef TARGET_ALIGN_ANON_BITFIELD
315#define TARGET_ALIGN_ANON_BITFIELD arm_align_anon_bitfield
316
5f458503 pbrook2006-03-29 15:21:13 +0000317#undef TARGET_NARROW_VOLATILE_BITFIELD
318#define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
319
c1dc02de pbrook2004-06-25 17:15:46 +0000320#undef TARGET_CXX_GUARD_TYPE
321#define TARGET_CXX_GUARD_TYPE arm_cxx_guard_type
322
323#undef TARGET_CXX_GUARD_MASK_BIT
324#define TARGET_CXX_GUARD_MASK_BIT arm_cxx_guard_mask_bit
325
600f4be7 pbrook2004-06-29 14:50:35 +0000326#undef TARGET_CXX_GET_COOKIE_SIZE
327#define TARGET_CXX_GET_COOKIE_SIZE arm_get_cookie_size
328
329#undef TARGET_CXX_COOKIE_HAS_SIZE
330#define TARGET_CXX_COOKIE_HAS_SIZE arm_cookie_has_size
331
853b7640 pbrook2004-08-04 15:33:51 +0000332#undef TARGET_CXX_CDTOR_RETURNS_THIS
333#define TARGET_CXX_CDTOR_RETURNS_THIS arm_cxx_cdtor_returns_this
334
4fc9a8ec mmitchel2004-09-01 03:45:30 +0000335#undef TARGET_CXX_KEY_METHOD_MAY_BE_INLINE
336#define TARGET_CXX_KEY_METHOD_MAY_BE_INLINE arm_cxx_key_method_may_be_inline
337
46b9ff5e jules2005-04-25 19:35:18 +0000338#undef TARGET_CXX_USE_AEABI_ATEXIT
339#define TARGET_CXX_USE_AEABI_ATEXIT arm_cxx_use_aeabi_atexit
340
7908506d mmitchel2005-04-12 06:33:48 +0000341#undef TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY
342#define TARGET_CXX_DETERMINE_CLASS_DATA_VISIBILITY \
343 arm_cxx_determine_class_data_visibility
344
345#undef TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT
346#define TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT arm_cxx_class_data_always_comdat
4fc9a8ec mmitchel2004-09-01 03:45:30 +0000347
46b5d878 jules2005-04-26 16:30:37 +0000348#undef TARGET_RETURN_IN_MSB
349#define TARGET_RETURN_IN_MSB arm_return_in_msb
350
351#undef TARGET_MUST_PASS_IN_STACK
352#define TARGET_MUST_PASS_IN_STACK arm_must_pass_in_stack
353
1774763d pbrook2005-06-28 19:52:27 +0000354#ifdef TARGET_UNWIND_INFO
355#undef TARGET_UNWIND_EMIT
356#define TARGET_UNWIND_EMIT arm_unwind_emit
357
358/* EABI unwinding tables use a different format for the typeinfo tables. */
359#undef TARGET_ASM_TTYPE
360#define TARGET_ASM_TTYPE arm_output_ttype
361
362#undef TARGET_ARM_EABI_UNWINDER
363#define TARGET_ARM_EABI_UNWINDER true
364#endif /* TARGET_UNWIND_INFO */
365
25f905c2 pbrook2007-01-03 23:48:10 +0000366#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
367#define TARGET_DWARF_HANDLE_FRAME_UNSPEC arm_dwarf_handle_frame_unspec
368
f655717d drow2005-11-04 15:02:51 +0000369#undef TARGET_CANNOT_COPY_INSN_P
370#define TARGET_CANNOT_COPY_INSN_P arm_cannot_copy_insn_p
371
372#ifdef HAVE_AS_TLS
373#undef TARGET_HAVE_TLS
374#define TARGET_HAVE_TLS true
375#endif
376
377#undef TARGET_CANNOT_FORCE_CONST_MEM
378#define TARGET_CANNOT_FORCE_CONST_MEM arm_tls_referenced_p
379
57e4bbfb shebs2001-07-07 01:07:22 +0000380struct gcc_target targetm = TARGET_INITIALIZER;
a767736d neil2001-06-26 18:09:27 +0000381\f
a220ccce rearnsha2000-10-13 15:54:16 +0000382/* Obstack for minipool constant handling. */
383static struct obstack minipool_obstack;
a12be13c nickc2002-01-16 12:25:53 +0000384static char * minipool_startobj;
a220ccce rearnsha2000-10-13 15:54:16 +0000385
a12be13c nickc2002-01-16 12:25:53 +0000386/* The maximum number of insns skipped which
387 will be conditionalised if possible. */
78fe751b nickc2000-02-29 01:42:52 +0000388static int max_insns_skipped = 5;
389
390extern FILE * asm_out_file;
391
66aacf41 nickc2000-03-29 19:15:36 +0000392/* True if we are currently building a constant table. */
c9ba03f2 nickc1999-05-22 09:40:04 +0000393int making_const_table;
394
2485f877 nickc1999-06-21 07:25:35 +0000395/* Define the information needed to generate branch insns. This is
66aacf41 nickc2000-03-29 19:15:36 +0000396 stored from the compare operation. */
9c08d1fa erich1993-10-03 16:33:02 +0000397rtx arm_compare_op0, arm_compare_op1;
9c08d1fa erich1993-10-03 16:33:02 +0000398
a2cd141b pbrook2004-02-03 14:45:44 +0000399/* The processor for which instructions should be scheduled. */
400enum processor_type arm_tune = arm_none;
401
fa7637bd kazu2006-12-02 02:26:04 +0000402/* The default processor used if not overridden by commandline. */
5fad5123 pbrook2006-11-03 17:49:43 +0000403static enum processor_type arm_default_cpu = arm_none;
404
a2cd141b pbrook2004-02-03 14:45:44 +0000405/* Which floating point model to use. */
406enum arm_fp_model arm_fp_model;
411b0ddb erich1994-06-27 15:24:36 +0000407
a2cd141b pbrook2004-02-03 14:45:44 +0000408/* Which floating point hardware is available. */
c7f506fd rearnsha2003-03-10 17:53:19 +0000409enum fputype arm_fpu_arch;
f21249d5 erich1997-07-16 14:54:40 +0000410
a2cd141b pbrook2004-02-03 14:45:44 +0000411/* Which floating point hardware to schedule for. */
412enum fputype arm_fpu_tune;
413
414/* Whether to use floating point hardware. */
415enum float_abi_type arm_float_abi;
416
f9273c43 pbrook2004-03-24 17:20:16 +0000417/* Which ABI to use. */
418enum arm_abi_type arm_abi;
419
f655717d drow2005-11-04 15:02:51 +0000420/* Which thread pointer model to use. */
421enum arm_tp_type target_thread_pointer = TP_AUTO;
422
6cd47762 nickc1998-10-27 11:13:39 +0000423/* Used to parse -mstructure_size_boundary command line option. */
8fa0c55d nickc1999-10-28 09:28:04 +0000424int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
6cd47762 nickc1998-10-27 11:13:39 +0000425
afe27f3b rearnsha2005-01-14 13:58:40 +0000426/* Used for Thumb call_via trampolines. */
a52972b8 pbrook2005-04-01 15:59:09 +0000427rtx thumb_call_via_label[14];
afe27f3b rearnsha2005-01-14 13:58:40 +0000428static int thumb_call_reg_needed;
429
82ec49ae nickc1999-03-17 14:47:27 +0000430/* Bit values used to identify processor capabilities. */
bba10fb8 nickc1999-07-05 08:44:36 +0000431#define FL_CO_PROC (1 << 0) /* Has external co-processor bus */
a2cd141b pbrook2004-02-03 14:45:44 +0000432#define FL_ARCH3M (1 << 1) /* Extended multiply */
bba10fb8 nickc1999-07-05 08:44:36 +0000433#define FL_MODE26 (1 << 2) /* 26-bit mode support */
434#define FL_MODE32 (1 << 3) /* 32-bit mode support */
435#define FL_ARCH4 (1 << 4) /* Architecture rel 4 */
436#define FL_ARCH5 (1 << 5) /* Architecture rel 5 */
437#define FL_THUMB (1 << 6) /* Thumb aware */
438#define FL_LDSCHED (1 << 7) /* Load scheduling necessary */
439#define FL_STRONG (1 << 8) /* StrongARM */
b89db9a7 kazu2003-01-31 02:20:48 +0000440#define FL_ARCH5E (1 << 9) /* DSP extensions to v5 */
331beb1a nickc2000-12-04 00:23:35 +0000441#define FL_XSCALE (1 << 10) /* XScale */
7d57ec45 nickc2003-02-10 11:45:26 +0000442#define FL_CIRRUS (1 << 11) /* Cirrus/DSP. */
a2cd141b pbrook2004-02-03 14:45:44 +0000443#define FL_ARCH6 (1 << 12) /* Architecture rel 6. Adds
2515f61d mmitchel2003-10-20 06:27:32 +0000444 media instructions. */
445#define FL_VFPV2 (1 << 13) /* Vector Floating Point V2. */
74a71f7d rearnsha2005-04-09 12:03:54 +0000446#define FL_WBUF (1 << 14) /* Schedule for write buffer ops.
447 Note: ARM6 & 7 derivatives only. */
f655717d drow2005-11-04 15:02:51 +0000448#define FL_ARCH6K (1 << 15) /* Architecture rel 6 K extensions. */
25f905c2 pbrook2007-01-03 23:48:10 +0000449#define FL_THUMB2 (1 << 16) /* Thumb-2. */
450#define FL_NOTM (1 << 17) /* Instructions not present in the 'M'
451 profile. */
542d5028 kazu2007-01-08 01:17:57 +0000452#define FL_DIV (1 << 18) /* Hardware divide. */
82ec49ae nickc1999-03-17 14:47:27 +0000453
a2cd141b pbrook2004-02-03 14:45:44 +0000454#define FL_IWMMXT (1 << 29) /* XScale v2 or "Intel Wireless MMX technology". */
455
25f905c2 pbrook2007-01-03 23:48:10 +0000456#define FL_FOR_ARCH2 FL_NOTM
457#define FL_FOR_ARCH3 (FL_FOR_ARCH2 | FL_MODE32)
e65e4284 pbrook2004-04-30 12:13:49 +0000458#define FL_FOR_ARCH3M (FL_FOR_ARCH3 | FL_ARCH3M)
459#define FL_FOR_ARCH4 (FL_FOR_ARCH3M | FL_ARCH4)
460#define FL_FOR_ARCH4T (FL_FOR_ARCH4 | FL_THUMB)
461#define FL_FOR_ARCH5 (FL_FOR_ARCH4 | FL_ARCH5)
462#define FL_FOR_ARCH5T (FL_FOR_ARCH5 | FL_THUMB)
463#define FL_FOR_ARCH5E (FL_FOR_ARCH5 | FL_ARCH5E)
464#define FL_FOR_ARCH5TE (FL_FOR_ARCH5E | FL_THUMB)
465#define FL_FOR_ARCH5TEJ FL_FOR_ARCH5TE
466#define FL_FOR_ARCH6 (FL_FOR_ARCH5TE | FL_ARCH6)
467#define FL_FOR_ARCH6J FL_FOR_ARCH6
f655717d drow2005-11-04 15:02:51 +0000468#define FL_FOR_ARCH6K (FL_FOR_ARCH6 | FL_ARCH6K)
6b4d6063 pbrook2004-10-12 15:38:30 +0000469#define FL_FOR_ARCH6Z FL_FOR_ARCH6
f655717d drow2005-11-04 15:02:51 +0000470#define FL_FOR_ARCH6ZK FL_FOR_ARCH6K
25f905c2 pbrook2007-01-03 23:48:10 +0000471#define FL_FOR_ARCH6T2 (FL_FOR_ARCH6 | FL_THUMB2)
472#define FL_FOR_ARCH7 (FL_FOR_ARCH6T2 &~ FL_NOTM)
473#define FL_FOR_ARCH7A (FL_FOR_ARCH7 | FL_NOTM)
474#define FL_FOR_ARCH7R (FL_FOR_ARCH7A | FL_DIV)
475#define FL_FOR_ARCH7M (FL_FOR_ARCH7 | FL_DIV)
e65e4284 pbrook2004-04-30 12:13:49 +0000476
a12be13c nickc2002-01-16 12:25:53 +0000477/* The bits in this mask specify which
478 instructions we are allowed to generate. */
a7712927 thorpej2002-11-07 18:32:00 +0000479static unsigned long insn_flags = 0;
cffb2a26 rearnsha2000-04-08 14:29:53 +0000480
82ec49ae nickc1999-03-17 14:47:27 +0000481/* The bits in this mask specify which instruction scheduling options should
a2cd141b pbrook2004-02-03 14:45:44 +0000482 be used. */
a7712927 thorpej2002-11-07 18:32:00 +0000483static unsigned long tune_flags = 0;
82ec49ae nickc1999-03-17 14:47:27 +0000484
485/* The following are used in the arm.md file as equivalents to bits
486 in the above two flag variables. */
487
a2cd141b pbrook2004-02-03 14:45:44 +0000488/* Nonzero if this chip supports the ARM Architecture 3M extensions. */
489int arm_arch3m = 0;
64266206 erich1995-12-06 11:41:39 +0000490
66aacf41 nickc2000-03-29 19:15:36 +0000491/* Nonzero if this chip supports the ARM Architecture 4 extensions. */
64266206 erich1995-12-06 11:41:39 +0000492int arm_arch4 = 0;
493
f1039640 rearnsha2004-06-25 10:42:21 +0000494/* Nonzero if this chip supports the ARM Architecture 4t extensions. */
495int arm_arch4t = 0;
496
66aacf41 nickc2000-03-29 19:15:36 +0000497/* Nonzero if this chip supports the ARM Architecture 5 extensions. */
bba10fb8 nickc1999-07-05 08:44:36 +0000498int arm_arch5 = 0;
499
e1159bbe rearnsha2001-01-08 15:33:06 +0000500/* Nonzero if this chip supports the ARM Architecture 5E extensions. */
501int arm_arch5e = 0;
502
a2cd141b pbrook2004-02-03 14:45:44 +0000503/* Nonzero if this chip supports the ARM Architecture 6 extensions. */
504int arm_arch6 = 0;
505
f655717d drow2005-11-04 15:02:51 +0000506/* Nonzero if this chip supports the ARM 6K extensions. */
507int arm_arch6k = 0;
508
25f905c2 pbrook2007-01-03 23:48:10 +0000509/* Nonzero if instructions not present in the 'M' profile can be used. */
510int arm_arch_notm = 0;
511
82ec49ae nickc1999-03-17 14:47:27 +0000512/* Nonzero if this chip can benefit from load scheduling. */
9888ad6d nickc1999-02-22 16:47:59 +0000513int arm_ld_sched = 0;
514
515/* Nonzero if this chip is a StrongARM. */
74a71f7d rearnsha2005-04-09 12:03:54 +0000516int arm_tune_strongarm = 0;
9888ad6d nickc1999-02-22 16:47:59 +0000517
e65e4284 pbrook2004-04-30 12:13:49 +0000518/* Nonzero if this chip is a Cirrus variant. */
519int arm_arch_cirrus = 0;
520
755eb2b4 nickc2003-06-18 16:36:13 +0000521/* Nonzero if this chip supports Intel Wireless MMX technology. */
522int arm_arch_iwmmxt = 0;
523
331beb1a nickc2000-12-04 00:23:35 +0000524/* Nonzero if this chip is an XScale. */
f8e17552 pb2003-05-15 18:38:21 +0000525int arm_arch_xscale = 0;
526
527/* Nonzero if tuning for XScale */
528int arm_tune_xscale = 0;
331beb1a nickc2000-12-04 00:23:35 +0000529
a60f1840 nickc2005-10-10 07:57:21 +0000530/* Nonzero if we want to tune for stores that access the write-buffer.
bf2fbc3d kazu2005-04-10 17:26:03 +0000531 This typically means an ARM6 or ARM7 with MMU or MPU. */
74a71f7d rearnsha2005-04-09 12:03:54 +0000532int arm_tune_wbuf = 0;
f21249d5 erich1997-07-16 14:54:40 +0000533
1c494086 rearnsha2000-05-06 18:13:35 +0000534/* Nonzero if generating Thumb instructions. */
535int thumb_code = 0;
536
80b6339a rearnsha2004-07-09 09:30:46 +0000537/* Nonzero if we should define __THUMB_INTERWORK__ in the
9e7454d0 echristo2004-08-24 00:30:52 +0000538 preprocessor.
80b6339a rearnsha2004-07-09 09:30:46 +0000539 XXX This is a bit of a hack, it's intended to help work around
540 problems in GLD which doesn't understand that armv5t code is
541 interworking clean. */
542int arm_cpp_interwork = 0;
543
25f905c2 pbrook2007-01-03 23:48:10 +0000544/* Nonzero if chip supports Thumb 2. */
545int arm_arch_thumb2;
546
547/* Nonzero if chip supports integer division instruction. */
548int arm_arch_hwdiv;
549
8cd42699 mycroft1992-03-14 05:17:02 +0000550/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
551 must report the mode of the memory reference from PRINT_OPERAND to
552 PRINT_OPERAND_ADDRESS. */
a690ede2 erich1994-06-01 17:09:29 +0000553enum machine_mode output_memory_reference_mode;
8cd42699 mycroft1992-03-14 05:17:02 +0000554
69120d26 erich1997-05-08 22:17:34 +0000555/* The register number to be used for the PIC offset register. */
2cb7d577 rearnsha2006-01-17 20:22:19 +0000556unsigned arm_pic_register = INVALID_REGNUM;
69120d26 erich1997-05-08 22:17:34 +0000557
9c08d1fa erich1993-10-03 16:33:02 +0000558/* Set to 1 when a return insn is output, this means that the epilogue
66aacf41 nickc2000-03-29 19:15:36 +0000559 is not needed. */
cffb2a26 rearnsha2000-04-08 14:29:53 +0000560int return_used_this_function;
9c08d1fa erich1993-10-03 16:33:02 +0000561
82ec49ae nickc1999-03-17 14:47:27 +0000562/* Set to 1 after arm_reorg has started. Reset to start at the start of
563 the next function. */
11de4c7f rearnsha1999-03-13 11:40:25 +0000564static int after_arm_reorg = 0;
565
82ec49ae nickc1999-03-17 14:47:27 +0000566/* The maximum number of insns to be used when loading a constant. */
64266206 erich1995-12-06 11:41:39 +0000567static int arm_constant_limit = 3;
568
8cd42699 mycroft1992-03-14 05:17:02 +0000569/* For an explanation of these variables, see final_prescan_insn below. */
570int arm_ccfsm_state;
25f905c2 pbrook2007-01-03 23:48:10 +0000571/* arm_current_cc is also used for Thumb-2 cond_exec blocks. */
1275b964 erich1996-02-27 13:15:13 +0000572enum arm_cond_code arm_current_cc;
8cd42699 mycroft1992-03-14 05:17:02 +0000573rtx arm_target_insn;
574int arm_target_label;
25f905c2 pbrook2007-01-03 23:48:10 +0000575/* The number of conditionally executed insns, including the current insn. */
576int arm_condexec_count = 0;
577/* A bitmask specifying the patterns for the IT block.
578 Zero means do not output an IT block before this insn. */
579int arm_condexec_mask = 0;
580/* The number of bits used in arm_condexec_mask. */
581int arm_condexec_masklen = 0;
f6b01912 erich1994-06-02 18:41:52 +0000582
583/* The condition codes of the ARM, and the inverse function. */
a12be13c nickc2002-01-16 12:25:53 +0000584static const char * const arm_condition_codes[] =
f6b01912 erich1994-06-02 18:41:52 +0000585{
586 "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
587 "hi", "ls", "ge", "lt", "gt", "le", "al", "nv"
588};
589
25f905c2 pbrook2007-01-03 23:48:10 +0000590#define ARM_LSL_NAME (TARGET_UNIFIED_ASM ? "lsl" : "asl")
9888ad6d nickc1999-02-22 16:47:59 +0000591#define streq(string1, string2) (strcmp (string1, string2) == 0)
25f905c2 pbrook2007-01-03 23:48:10 +0000592
593#define THUMB2_WORK_REGS (0xff & ~( (1 << THUMB_HARD_FRAME_POINTER_REGNUM) \
594 | (1 << SP_REGNUM) | (1 << PC_REGNUM) \
595 | (1 << PIC_OFFSET_TABLE_REGNUM)))
64266206 erich1995-12-06 11:41:39 +0000596\f
66aacf41 nickc2000-03-29 19:15:36 +0000597/* Initialization code. */
64266206 erich1995-12-06 11:41:39 +0000598
64266206 erich1995-12-06 11:41:39 +0000599struct processors
600{
e99c3a1d ghazi2001-10-07 16:51:11 +0000601 const char *const name;
a2cd141b pbrook2004-02-03 14:45:44 +0000602 enum processor_type core;
e65e4284 pbrook2004-04-30 12:13:49 +0000603 const char *arch;
a7712927 thorpej2002-11-07 18:32:00 +0000604 const unsigned long flags;
a2cd141b pbrook2004-02-03 14:45:44 +0000605 bool (* rtx_costs) (rtx, int, int, int *);
64266206 erich1995-12-06 11:41:39 +0000606};
607
608/* Not all of these give usefully different compilation alternatives,
609 but there is no simple way of generalizing them. */
e99c3a1d ghazi2001-10-07 16:51:11 +0000610static const struct processors all_cores[] =
9888ad6d nickc1999-02-22 16:47:59 +0000611{
612 /* ARM Cores */
61b58075 rearnsha2004-09-01 12:49:30 +0000613#define ARM_CORE(NAME, IDENT, ARCH, FLAGS, COSTS) \
614 {NAME, arm_none, #ARCH, FLAGS | FL_FOR_ARCH##ARCH, arm_##COSTS##_rtx_costs},
a2cd141b pbrook2004-02-03 14:45:44 +0000615#include "arm-cores.def"
616#undef ARM_CORE
e65e4284 pbrook2004-04-30 12:13:49 +0000617 {NULL, arm_none, NULL, 0, NULL}
9888ad6d nickc1999-02-22 16:47:59 +0000618};
619
e99c3a1d ghazi2001-10-07 16:51:11 +0000620static const struct processors all_architectures[] =
64266206 erich1995-12-06 11:41:39 +0000621{
9888ad6d nickc1999-02-22 16:47:59 +0000622 /* ARM Architectures */
a2cd141b pbrook2004-02-03 14:45:44 +0000623 /* We don't specify rtx_costs here as it will be figured out
624 from the core. */
9e7454d0 echristo2004-08-24 00:30:52 +0000625
e65e4284 pbrook2004-04-30 12:13:49 +0000626 {"armv2", arm2, "2", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH2, NULL},
627 {"armv2a", arm2, "2", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH2, NULL},
628 {"armv3", arm6, "3", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH3, NULL},
629 {"armv3m", arm7m, "3M", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH3M, NULL},
630 {"armv4", arm7tdmi, "4", FL_CO_PROC | FL_MODE26 | FL_FOR_ARCH4, NULL},
f21249d5 erich1997-07-16 14:54:40 +0000631 /* Strictly, FL_MODE26 is a permitted option for v4t, but there are no
632 implementations that support it, so we will leave it out for now. */
e65e4284 pbrook2004-04-30 12:13:49 +0000633 {"armv4t", arm7tdmi, "4T", FL_CO_PROC | FL_FOR_ARCH4T, NULL},
634 {"armv5", arm10tdmi, "5", FL_CO_PROC | FL_FOR_ARCH5, NULL},
635 {"armv5t", arm10tdmi, "5T", FL_CO_PROC | FL_FOR_ARCH5T, NULL},
636 {"armv5e", arm1026ejs, "5E", FL_CO_PROC | FL_FOR_ARCH5E, NULL},
637 {"armv5te", arm1026ejs, "5TE", FL_CO_PROC | FL_FOR_ARCH5TE, NULL},
638 {"armv6", arm1136js, "6", FL_CO_PROC | FL_FOR_ARCH6, NULL},
639 {"armv6j", arm1136js, "6J", FL_CO_PROC | FL_FOR_ARCH6J, NULL},
6b4d6063 pbrook2004-10-12 15:38:30 +0000640 {"armv6k", mpcore, "6K", FL_CO_PROC | FL_FOR_ARCH6K, NULL},
641 {"armv6z", arm1176jzs, "6Z", FL_CO_PROC | FL_FOR_ARCH6Z, NULL},
642 {"armv6zk", arm1176jzs, "6ZK", FL_CO_PROC | FL_FOR_ARCH6ZK, NULL},
25f905c2 pbrook2007-01-03 23:48:10 +0000643 {"armv6t2", arm1156t2s, "6T2", FL_CO_PROC | FL_FOR_ARCH6T2, NULL},
644 {"armv7", cortexa8, "7", FL_CO_PROC | FL_FOR_ARCH7, NULL},
645 {"armv7-a", cortexa8, "7A", FL_CO_PROC | FL_FOR_ARCH7A, NULL},
646 {"armv7-r", cortexr4, "7R", FL_CO_PROC | FL_FOR_ARCH7R, NULL},
647 {"armv7-m", cortexm3, "7M", FL_CO_PROC | FL_FOR_ARCH7M, NULL},
e65e4284 pbrook2004-04-30 12:13:49 +0000648 {"ep9312", ep9312, "4T", FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4, NULL},
649 {"iwmmxt", iwmmxt, "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL},
650 {NULL, arm_none, NULL, 0 , NULL}
9888ad6d nickc1999-02-22 16:47:59 +0000651};
652
81f6de2f rsandifo2005-05-05 12:09:00 +0000653struct arm_cpu_select
654{
655 const char * string;
656 const char * name;
657 const struct processors * processors;
658};
659
8d232dc7 kazu2003-07-12 23:02:23 +0000660/* This is a magic structure. The 'string' field is magically filled in
9888ad6d nickc1999-02-22 16:47:59 +0000661 with a pointer to the value specified by the user on the command line
662 assuming that the user has specified such a value. */
663
81f6de2f rsandifo2005-05-05 12:09:00 +0000664static struct arm_cpu_select arm_select[] =
9888ad6d nickc1999-02-22 16:47:59 +0000665{
9e7454d0 echristo2004-08-24 00:30:52 +0000666 /* string name processors */
9888ad6d nickc1999-02-22 16:47:59 +0000667 { NULL, "-mcpu=", all_cores },
668 { NULL, "-march=", all_architectures },
669 { NULL, "-mtune=", all_cores }
64266206 erich1995-12-06 11:41:39 +0000670};
671
c37752cc rearnsha2005-05-09 14:15:47 +0000672/* Defines representing the indexes into the above table. */
673#define ARM_OPT_SET_CPU 0
674#define ARM_OPT_SET_ARCH 1
675#define ARM_OPT_SET_TUNE 2
e65e4284 pbrook2004-04-30 12:13:49 +0000676
15b00d63 nickc2006-10-19 08:10:08 +0000677/* The name of the preprocessor macro to define for this architecture. */
e65e4284 pbrook2004-04-30 12:13:49 +0000678
679char arm_arch_name[] = "__ARM_ARCH_0UNK__";
680
a2cd141b pbrook2004-02-03 14:45:44 +0000681struct fpu_desc
682{
683 const char * name;
684 enum fputype fpu;
685};
686
687
cb4213cd reichelt2006-01-02 17:28:54 +0000688/* Available values for -mfpu=. */
a2cd141b pbrook2004-02-03 14:45:44 +0000689
690static const struct fpu_desc all_fpus[] =
691{
692 {"fpa", FPUTYPE_FPA},
693 {"fpe2", FPUTYPE_FPA_EMU2},
694 {"fpe3", FPUTYPE_FPA_EMU2},
695 {"maverick", FPUTYPE_MAVERICK},
696 {"vfp", FPUTYPE_VFP}
697};
698
699
700/* Floating point models used by the different hardware.
701 See fputype in arm.h. */
702
703static const enum fputype fp_model_for_fpu[] =
704{
705 /* No FP hardware. */
706 ARM_FP_MODEL_UNKNOWN, /* FPUTYPE_NONE */
707 ARM_FP_MODEL_FPA, /* FPUTYPE_FPA */
708 ARM_FP_MODEL_FPA, /* FPUTYPE_FPA_EMU2 */
709 ARM_FP_MODEL_FPA, /* FPUTYPE_FPA_EMU3 */
710 ARM_FP_MODEL_MAVERICK, /* FPUTYPE_MAVERICK */
711 ARM_FP_MODEL_VFP /* FPUTYPE_VFP */
712};
713
714
715struct float_abi
716{
717 const char * name;
718 enum float_abi_type abi_type;
719};
720
721
722/* Available values for -mfloat-abi=. */
723
724static const struct float_abi all_float_abis[] =
725{
726 {"soft", ARM_FLOAT_ABI_SOFT},
727 {"softfp", ARM_FLOAT_ABI_SOFTFP},
728 {"hard", ARM_FLOAT_ABI_HARD}
729};
730
731
f9273c43 pbrook2004-03-24 17:20:16 +0000732struct abi_name
733{
734 const char *name;
735 enum arm_abi_type abi_type;
736};
737
738
739/* Available values for -mabi=. */
740
741static const struct abi_name arm_all_abis[] =
742{
743 {"apcs-gnu", ARM_ABI_APCS},
744 {"atpcs", ARM_ABI_ATPCS},
745 {"aapcs", ARM_ABI_AAPCS},
6783d878 kazu2005-10-08 18:17:20 +0000746 {"iwmmxt", ARM_ABI_IWMMXT},
747 {"aapcs-linux", ARM_ABI_AAPCS_LINUX}
f9273c43 pbrook2004-03-24 17:20:16 +0000748};
749
f655717d drow2005-11-04 15:02:51 +0000750/* Supported TLS relocations. */
751
752enum tls_reloc {
753 TLS_GD32,
754 TLS_LDM32,
755 TLS_LDO32,
756 TLS_IE32,
757 TLS_LE32
758};
759
0083a3b9 rearnsha2005-11-22 14:30:10 +0000760/* Emit an insn that's a simple single-set. Both the operands must be known
761 to be valid. */
762inline static rtx
763emit_set_insn (rtx x, rtx y)
764{
765 return emit_insn (gen_rtx_SET (VOIDmode, x, y));
766}
767
a7712927 thorpej2002-11-07 18:32:00 +0000768/* Return the number of bits set in VALUE. */
769static unsigned
ebd88a36 rearnsha2003-06-10 18:55:17 +0000770bit_count (unsigned long value)
82ec49ae nickc1999-03-17 14:47:27 +0000771{
cffb2a26 rearnsha2000-04-08 14:29:53 +0000772 unsigned long count = 0;
9e7454d0 echristo2004-08-24 00:30:52 +0000773
82ec49ae nickc1999-03-17 14:47:27 +0000774 while (value)
775 {
a7712927 thorpej2002-11-07 18:32:00 +0000776 count++;
777 value &= value - 1; /* Clear the least-significant set bit. */
82ec49ae nickc1999-03-17 14:47:27 +0000778 }
779
780 return count;
781}
782
84cbcde5 kazu2004-09-10 11:55:21 +0000783/* Set up library functions unique to ARM. */
30e9913f mmitchel2004-08-11 02:50:14 +0000784
785static void
786arm_init_libfuncs (void)
787{
788 /* There are no special library functions unless we are using the
789 ARM BPABI. */
790 if (!TARGET_BPABI)
791 return;
792
793 /* The functions below are described in Section 4 of the "Run-Time
794 ABI for the ARM architecture", Version 1.0. */
795
796 /* Double-precision floating-point arithmetic. Table 2. */
797 set_optab_libfunc (add_optab, DFmode, "__aeabi_dadd");
798 set_optab_libfunc (sdiv_optab, DFmode, "__aeabi_ddiv");
799 set_optab_libfunc (smul_optab, DFmode, "__aeabi_dmul");
800 set_optab_libfunc (neg_optab, DFmode, "__aeabi_dneg");
801 set_optab_libfunc (sub_optab, DFmode, "__aeabi_dsub");
802
84cbcde5 kazu2004-09-10 11:55:21 +0000803 /* Double-precision comparisons. Table 3. */
30e9913f mmitchel2004-08-11 02:50:14 +0000804 set_optab_libfunc (eq_optab, DFmode, "__aeabi_dcmpeq");
805 set_optab_libfunc (ne_optab, DFmode, NULL);
806 set_optab_libfunc (lt_optab, DFmode, "__aeabi_dcmplt");
807 set_optab_libfunc (le_optab, DFmode, "__aeabi_dcmple");
808 set_optab_libfunc (ge_optab, DFmode, "__aeabi_dcmpge");
809 set_optab_libfunc (gt_optab, DFmode, "__aeabi_dcmpgt");
810 set_optab_libfunc (unord_optab, DFmode, "__aeabi_dcmpun");
811
812 /* Single-precision floating-point arithmetic. Table 4. */
813 set_optab_libfunc (add_optab, SFmode, "__aeabi_fadd");
814 set_optab_libfunc (sdiv_optab, SFmode, "__aeabi_fdiv");
815 set_optab_libfunc (smul_optab, SFmode, "__aeabi_fmul");
816 set_optab_libfunc (neg_optab, SFmode, "__aeabi_fneg");
817 set_optab_libfunc (sub_optab, SFmode, "__aeabi_fsub");
9e7454d0 echristo2004-08-24 00:30:52 +0000818
84cbcde5 kazu2004-09-10 11:55:21 +0000819 /* Single-precision comparisons. Table 5. */
30e9913f mmitchel2004-08-11 02:50:14 +0000820 set_optab_libfunc (eq_optab, SFmode, "__aeabi_fcmpeq");
821 set_optab_libfunc (ne_optab, SFmode, NULL);
822 set_optab_libfunc (lt_optab, SFmode, "__aeabi_fcmplt");
823 set_optab_libfunc (le_optab, SFmode, "__aeabi_fcmple");
824 set_optab_libfunc (ge_optab, SFmode, "__aeabi_fcmpge");
825 set_optab_libfunc (gt_optab, SFmode, "__aeabi_fcmpgt");
826 set_optab_libfunc (unord_optab, SFmode, "__aeabi_fcmpun");
827
828 /* Floating-point to integer conversions. Table 6. */
829 set_conv_libfunc (sfix_optab, SImode, DFmode, "__aeabi_d2iz");
830 set_conv_libfunc (ufix_optab, SImode, DFmode, "__aeabi_d2uiz");
831 set_conv_libfunc (sfix_optab, DImode, DFmode, "__aeabi_d2lz");
832 set_conv_libfunc (ufix_optab, DImode, DFmode, "__aeabi_d2ulz");
833 set_conv_libfunc (sfix_optab, SImode, SFmode, "__aeabi_f2iz");
834 set_conv_libfunc (ufix_optab, SImode, SFmode, "__aeabi_f2uiz");
835 set_conv_libfunc (sfix_optab, DImode, SFmode, "__aeabi_f2lz");
836 set_conv_libfunc (ufix_optab, DImode, SFmode, "__aeabi_f2ulz");
837
838 /* Conversions between floating types. Table 7. */
839 set_conv_libfunc (trunc_optab, SFmode, DFmode, "__aeabi_d2f");
840 set_conv_libfunc (sext_optab, DFmode, SFmode, "__aeabi_f2d");
841
84cbcde5 kazu2004-09-10 11:55:21 +0000842 /* Integer to floating-point conversions. Table 8. */
30e9913f mmitchel2004-08-11 02:50:14 +0000843 set_conv_libfunc (sfloat_optab, DFmode, SImode, "__aeabi_i2d");
844 set_conv_libfunc (ufloat_optab, DFmode, SImode, "__aeabi_ui2d");
845 set_conv_libfunc (sfloat_optab, DFmode, DImode, "__aeabi_l2d");
846 set_conv_libfunc (ufloat_optab, DFmode, DImode, "__aeabi_ul2d");
847 set_conv_libfunc (sfloat_optab, SFmode, SImode, "__aeabi_i2f");
848 set_conv_libfunc (ufloat_optab, SFmode, SImode, "__aeabi_ui2f");
849 set_conv_libfunc (sfloat_optab, SFmode, DImode, "__aeabi_l2f");
850 set_conv_libfunc (ufloat_optab, SFmode, DImode, "__aeabi_ul2f");
851
852 /* Long long. Table 9. */
853 set_optab_libfunc (smul_optab, DImode, "__aeabi_lmul");
854 set_optab_libfunc (sdivmod_optab, DImode, "__aeabi_ldivmod");
855 set_optab_libfunc (udivmod_optab, DImode, "__aeabi_uldivmod");
856 set_optab_libfunc (ashl_optab, DImode, "__aeabi_llsl");
857 set_optab_libfunc (lshr_optab, DImode, "__aeabi_llsr");
858 set_optab_libfunc (ashr_optab, DImode, "__aeabi_lasr");
859 set_optab_libfunc (cmp_optab, DImode, "__aeabi_lcmp");
860 set_optab_libfunc (ucmp_optab, DImode, "__aeabi_ulcmp");
861
862 /* Integer (32/32->32) division. \S 4.3.1. */
863 set_optab_libfunc (sdivmod_optab, SImode, "__aeabi_idivmod");
864 set_optab_libfunc (udivmod_optab, SImode, "__aeabi_uidivmod");
865
866 /* The divmod functions are designed so that they can be used for
867 plain division, even though they return both the quotient and the
868 remainder. The quotient is returned in the usual location (i.e.,
869 r0 for SImode, {r0, r1} for DImode), just as would be expected
870 for an ordinary division routine. Because the AAPCS calling
871 conventions specify that all of { r0, r1, r2, r3 } are
872 callee-saved registers, there is no need to tell the compiler
873 explicitly that those registers are clobbered by these
874 routines. */
875 set_optab_libfunc (sdiv_optab, DImode, "__aeabi_ldivmod");
876 set_optab_libfunc (udiv_optab, DImode, "__aeabi_uldivmod");
3da35908 drow2005-11-04 15:29:01 +0000877
878 /* For SImode division the ABI provides div-without-mod routines,
879 which are faster. */
880 set_optab_libfunc (sdiv_optab, SImode, "__aeabi_idiv");
881 set_optab_libfunc (udiv_optab, SImode, "__aeabi_uidiv");
b027ddbf jules2005-04-19 18:50:14 +0000882
883 /* We don't have mod libcalls. Fortunately gcc knows how to use the
884 divmod libcalls instead. */
885 set_optab_libfunc (smod_optab, DImode, NULL);
886 set_optab_libfunc (umod_optab, DImode, NULL);
887 set_optab_libfunc (smod_optab, SImode, NULL);
888 set_optab_libfunc (umod_optab, SImode, NULL);
30e9913f mmitchel2004-08-11 02:50:14 +0000889}
890
81f6de2f rsandifo2005-05-05 12:09:00 +0000891/* Implement TARGET_HANDLE_OPTION. */
892
893static bool
894arm_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
895{
896 switch (code)
897 {
81f6de2f rsandifo2005-05-05 12:09:00 +0000898 case OPT_march_:
899 arm_select[1].string = arg;
900 return true;
901
902 case OPT_mcpu_:
903 arm_select[0].string = arg;
904 return true;
905
81f6de2f rsandifo2005-05-05 12:09:00 +0000906 case OPT_mhard_float:
907 target_float_abi_name = "hard";
908 return true;
909
81f6de2f rsandifo2005-05-05 12:09:00 +0000910 case OPT_msoft_float:
911 target_float_abi_name = "soft";
912 return true;
913
81f6de2f rsandifo2005-05-05 12:09:00 +0000914 case OPT_mtune_:
915 arm_select[2].string = arg;
916 return true;
917
918 default:
919 return true;
920 }
921}
922
64266206 erich1995-12-06 11:41:39 +0000923/* Fix up any incompatible options that the user has specified.
924 This has now turned into a maze. */
925void
ebd88a36 rearnsha2003-06-10 18:55:17 +0000926arm_override_options (void)
64266206 erich1995-12-06 11:41:39 +0000927{
ae175e8f rearnsha1998-06-26 07:13:25 +0000928 unsigned i;
c37752cc rearnsha2005-05-09 14:15:47 +0000929 enum processor_type target_arch_cpu = arm_none;
a2cd141b pbrook2004-02-03 14:45:44 +0000930
9888ad6d nickc1999-02-22 16:47:59 +0000931 /* Set up the flags based on the cpu/architecture selected by the user. */
3098b2d3 gkm2000-08-24 20:31:35 +0000932 for (i = ARRAY_SIZE (arm_select); i--;)
9480e6c7 erich1996-05-04 16:13:28 +0000933 {
9888ad6d nickc1999-02-22 16:47:59 +0000934 struct arm_cpu_select * ptr = arm_select + i;
9e7454d0 echristo2004-08-24 00:30:52 +0000935
9888ad6d nickc1999-02-22 16:47:59 +0000936 if (ptr->string != NULL && ptr->string[0] != '\0')
9480e6c7 erich1996-05-04 16:13:28 +0000937 {
c9ba03f2 nickc1999-05-22 09:40:04 +0000938 const struct processors * sel;
9480e6c7 erich1996-05-04 16:13:28 +0000939
215b30b3 rearnsha2000-10-09 18:42:34 +0000940 for (sel = ptr->processors; sel->name != NULL; sel++)
9888ad6d nickc1999-02-22 16:47:59 +0000941 if (streq (ptr->string, sel->name))
9480e6c7 erich1996-05-04 16:13:28 +0000942 {
e65e4284 pbrook2004-04-30 12:13:49 +0000943 /* Set the architecture define. */
c37752cc rearnsha2005-05-09 14:15:47 +0000944 if (i != ARM_OPT_SET_TUNE)
e65e4284 pbrook2004-04-30 12:13:49 +0000945 sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
946
a2cd141b pbrook2004-02-03 14:45:44 +0000947 /* Determine the processor core for which we should
948 tune code-generation. */
949 if (/* -mcpu= is a sensible default. */
c37752cc rearnsha2005-05-09 14:15:47 +0000950 i == ARM_OPT_SET_CPU
a2cd141b pbrook2004-02-03 14:45:44 +0000951 /* -mtune= overrides -mcpu= and -march=. */
c37752cc rearnsha2005-05-09 14:15:47 +0000952 || i == ARM_OPT_SET_TUNE)
a2cd141b pbrook2004-02-03 14:45:44 +0000953 arm_tune = (enum processor_type) (sel - ptr->processors);
954
c37752cc rearnsha2005-05-09 14:15:47 +0000955 /* Remember the CPU associated with this architecture.
956 If no other option is used to set the CPU type,
957 we'll use this to guess the most suitable tuning
958 options. */
959 if (i == ARM_OPT_SET_ARCH)
960 target_arch_cpu = sel->core;
a60f1840 nickc2005-10-10 07:57:21 +0000961
c37752cc rearnsha2005-05-09 14:15:47 +0000962 if (i != ARM_OPT_SET_TUNE)
f21249d5 erich1997-07-16 14:54:40 +0000963 {
82ec49ae nickc1999-03-17 14:47:27 +0000964 /* If we have been given an architecture and a processor
965 make sure that they are compatible. We only generate
966 a warning though, and we prefer the CPU over the
66aacf41 nickc2000-03-29 19:15:36 +0000967 architecture. */
82ec49ae nickc1999-03-17 14:47:27 +0000968 if (insn_flags != 0 && (insn_flags ^ sel->flags))
c3ceba8e dj2005-04-23 21:29:07 +0000969 warning (0, "switch -mcpu=%s conflicts with -march= switch",
82ec49ae nickc1999-03-17 14:47:27 +0000970 ptr->string);
9e7454d0 echristo2004-08-24 00:30:52 +0000971
82ec49ae nickc1999-03-17 14:47:27 +0000972 insn_flags = sel->flags;
f21249d5 erich1997-07-16 14:54:40 +0000973 }
9e7454d0 echristo2004-08-24 00:30:52 +0000974
9480e6c7 erich1996-05-04 16:13:28 +0000975 break;
976 }
977
978 if (sel->name == NULL)
979 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
980 }
981 }
9e7454d0 echristo2004-08-24 00:30:52 +0000982
c37752cc rearnsha2005-05-09 14:15:47 +0000983 /* Guess the tuning options from the architecture if necessary. */
984 if (arm_tune == arm_none)
985 arm_tune = target_arch_cpu;
986
9888ad6d nickc1999-02-22 16:47:59 +0000987 /* If the user did not specify a processor, choose one for them. */
82ec49ae nickc1999-03-17 14:47:27 +0000988 if (insn_flags == 0)
9888ad6d nickc1999-02-22 16:47:59 +0000989 {
e99c3a1d ghazi2001-10-07 16:51:11 +0000990 const struct processors * sel;
82ec49ae nickc1999-03-17 14:47:27 +0000991 unsigned int sought;
e65e4284 pbrook2004-04-30 12:13:49 +0000992 enum processor_type cpu;
82ec49ae nickc1999-03-17 14:47:27 +0000993
e65e4284 pbrook2004-04-30 12:13:49 +0000994 cpu = TARGET_CPU_DEFAULT;
995 if (cpu == arm_none)
996 {
997#ifdef SUBTARGET_CPU_DEFAULT
998 /* Use the subtarget default CPU if none was specified by
999 configure. */
1000 cpu = SUBTARGET_CPU_DEFAULT;
1001#endif
1002 /* Default to ARM6. */
1003 if (cpu == arm_none)
1004 cpu = arm6;
1005 }
1006 sel = &all_cores[cpu];
82ec49ae nickc1999-03-17 14:47:27 +00001007
1008 insn_flags = sel->flags;
a2cd141b pbrook2004-02-03 14:45:44 +00001009
82ec49ae nickc1999-03-17 14:47:27 +00001010 /* Now check to see if the user has specified some command line
1011 switch that require certain abilities from the cpu. */
1012 sought = 0;
9e7454d0 echristo2004-08-24 00:30:52 +00001013
cffb2a26 rearnsha2000-04-08 14:29:53 +00001014 if (TARGET_INTERWORK || TARGET_THUMB)
9888ad6d nickc1999-02-22 16:47:59 +00001015 {
82ec49ae nickc1999-03-17 14:47:27 +00001016 sought |= (FL_THUMB | FL_MODE32);
9e7454d0 echristo2004-08-24 00:30:52 +00001017
cffb2a26 rearnsha2000-04-08 14:29:53 +00001018 /* There are no ARM processors that support both APCS-26 and
82ec49ae nickc1999-03-17 14:47:27 +00001019 interworking. Therefore we force FL_MODE26 to be removed
1020 from insn_flags here (if it was set), so that the search
1021 below will always be able to find a compatible processor. */
215b30b3 rearnsha2000-10-09 18:42:34 +00001022 insn_flags &= ~FL_MODE26;
9888ad6d nickc1999-02-22 16:47:59 +00001023 }
9e7454d0 echristo2004-08-24 00:30:52 +00001024
82ec49ae nickc1999-03-17 14:47:27 +00001025 if (sought != 0 && ((sought & insn_flags) != sought))
9888ad6d nickc1999-02-22 16:47:59 +00001026 {
82ec49ae nickc1999-03-17 14:47:27 +00001027 /* Try to locate a CPU type that supports all of the abilities
1028 of the default CPU, plus the extra abilities requested by
1029 the user. */
215b30b3 rearnsha2000-10-09 18:42:34 +00001030 for (sel = all_cores; sel->name != NULL; sel++)
82ec49ae nickc1999-03-17 14:47:27 +00001031 if ((sel->flags & sought) == (sought | insn_flags))
9888ad6d nickc1999-02-22 16:47:59 +00001032 break;
1033
1034 if (sel->name == NULL)
82ec49ae nickc1999-03-17 14:47:27 +00001035 {
a7712927 thorpej2002-11-07 18:32:00 +00001036 unsigned current_bit_count = 0;
e99c3a1d ghazi2001-10-07 16:51:11 +00001037 const struct processors * best_fit = NULL;
9e7454d0 echristo2004-08-24 00:30:52 +00001038
82ec49ae nickc1999-03-17 14:47:27 +00001039 /* Ideally we would like to issue an error message here
1040 saying that it was not possible to find a CPU compatible
1041 with the default CPU, but which also supports the command
1042 line options specified by the programmer, and so they
1043 ought to use the -mcpu=<name> command line option to
1044 override the default CPU type.
1045
c1a66faf rearnsha2004-05-15 12:41:35 +00001046 If we cannot find a cpu that has both the
1047 characteristics of the default cpu and the given
1048 command line options we scan the array again looking
1049 for a best match. */
215b30b3 rearnsha2000-10-09 18:42:34 +00001050 for (sel = all_cores; sel->name != NULL; sel++)
82ec49ae nickc1999-03-17 14:47:27 +00001051 if ((sel->flags & sought) == sought)
1052 {
a7712927 thorpej2002-11-07 18:32:00 +00001053 unsigned count;
82ec49ae nickc1999-03-17 14:47:27 +00001054
1055 count = bit_count (sel->flags & insn_flags);
1056
1057 if (count >= current_bit_count)
1058 {
1059 best_fit = sel;
1060 current_bit_count = count;
1061 }
1062 }
9888ad6d nickc1999-02-22 16:47:59 +00001063
ed29c566 nathan2005-04-27 16:09:03 +00001064 gcc_assert (best_fit);
1065 sel = best_fit;
82ec49ae nickc1999-03-17 14:47:27 +00001066 }
1067
1068 insn_flags = sel->flags;
9888ad6d nickc1999-02-22 16:47:59 +00001069 }
e65e4284 pbrook2004-04-30 12:13:49 +00001070 sprintf (arm_arch_name, "__ARM_ARCH_%s__", sel->arch);
5fad5123 pbrook2006-11-03 17:49:43 +00001071 arm_default_cpu = (enum processor_type) (sel - all_cores);
a2cd141b pbrook2004-02-03 14:45:44 +00001072 if (arm_tune == arm_none)
5fad5123 pbrook2006-11-03 17:49:43 +00001073 arm_tune = arm_default_cpu;
9888ad6d nickc1999-02-22 16:47:59 +00001074 }
9e7454d0 echristo2004-08-24 00:30:52 +00001075
a2cd141b pbrook2004-02-03 14:45:44 +00001076 /* The processor for which we should tune should now have been
1077 chosen. */
ed29c566 nathan2005-04-27 16:09:03 +00001078 gcc_assert (arm_tune != arm_none);
9e7454d0 echristo2004-08-24 00:30:52 +00001079
a2cd141b pbrook2004-02-03 14:45:44 +00001080 tune_flags = all_cores[(int)arm_tune].flags;
c1877da8 rearnsha2004-08-18 22:23:57 +00001081 if (optimize_size)
1082 targetm.rtx_costs = arm_size_rtx_costs;
1083 else
1084 targetm.rtx_costs = all_cores[(int)arm_tune].rtx_costs;
9f468b67 nickc2002-08-08 11:24:01 +00001085
9888ad6d nickc1999-02-22 16:47:59 +00001086 /* Make sure that the processor choice does not conflict with any of the
1087 other command line choices. */
25f905c2 pbrook2007-01-03 23:48:10 +00001088 if (TARGET_ARM && !(insn_flags & FL_NOTM))
1089 error ("target CPU does not support ARM mode");
1090
96576951 nickc1999-07-17 13:44:35 +00001091 if (TARGET_INTERWORK && !(insn_flags & FL_THUMB))
9888ad6d nickc1999-02-22 16:47:59 +00001092 {
c3ceba8e dj2005-04-23 21:29:07 +00001093 warning (0, "target CPU does not support interworking" );
81f6de2f rsandifo2005-05-05 12:09:00 +00001094 target_flags &= ~MASK_INTERWORK;
9888ad6d nickc1999-02-22 16:47:59 +00001095 }
9e7454d0 echristo2004-08-24 00:30:52 +00001096
cffb2a26 rearnsha2000-04-08 14:29:53 +00001097 if (TARGET_THUMB && !(insn_flags & FL_THUMB))
1098 {
c3ceba8e dj2005-04-23 21:29:07 +00001099 warning (0, "target CPU does not support THUMB instructions");
81f6de2f rsandifo2005-05-05 12:09:00 +00001100 target_flags &= ~MASK_THUMB;
cffb2a26 rearnsha2000-04-08 14:29:53 +00001101 }
1102
1103 if (TARGET_APCS_FRAME && TARGET_THUMB)
1104 {
c3ceba8e dj2005-04-23 21:29:07 +00001105 /* warning (0, "ignoring -mapcs-frame because -mthumb was used"); */
81f6de2f rsandifo2005-05-05 12:09:00 +00001106 target_flags &= ~MASK_APCS_FRAME;
cffb2a26 rearnsha2000-04-08 14:29:53 +00001107 }
331beb1a nickc2000-12-04 00:23:35 +00001108
551836e5 rearnsha2005-08-11 14:20:23 +00001109 /* Callee super interworking implies thumb interworking. Adding
1110 this to the flags here simplifies the logic elsewhere. */
1111 if (TARGET_THUMB && TARGET_CALLEE_INTERWORKING)
1112 target_flags |= MASK_INTERWORK;
1113
cffb2a26 rearnsha2000-04-08 14:29:53 +00001114 /* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done
1115 from here where no function is being compiled currently. */
81f6de2f rsandifo2005-05-05 12:09:00 +00001116 if ((TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME) && TARGET_ARM)
c3ceba8e dj2005-04-23 21:29:07 +00001117 warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb");
cffb2a26 rearnsha2000-04-08 14:29:53 +00001118
1119 if (TARGET_ARM && TARGET_CALLEE_INTERWORKING)
c3ceba8e dj2005-04-23 21:29:07 +00001120 warning (0, "enabling callee interworking support is only meaningful when compiling for the Thumb");
cffb2a26 rearnsha2000-04-08 14:29:53 +00001121
1122 if (TARGET_ARM && TARGET_CALLER_INTERWORKING)
c3ceba8e dj2005-04-23 21:29:07 +00001123 warning (0, "enabling caller interworking support is only meaningful when compiling for the Thumb");
cffb2a26 rearnsha2000-04-08 14:29:53 +00001124
215b30b3 rearnsha2000-10-09 18:42:34 +00001125 if (TARGET_APCS_STACK && !TARGET_APCS_FRAME)
9888ad6d nickc1999-02-22 16:47:59 +00001126 {
c3ceba8e dj2005-04-23 21:29:07 +00001127 warning (0, "-mapcs-stack-check incompatible with -mno-apcs-frame");
81f6de2f rsandifo2005-05-05 12:09:00 +00001128 target_flags |= MASK_APCS_FRAME;
9888ad6d nickc1999-02-22 16:47:59 +00001129 }
9e7454d0 echristo2004-08-24 00:30:52 +00001130
64266206 erich1995-12-06 11:41:39 +00001131 if (TARGET_POKE_FUNCTION_NAME)
81f6de2f rsandifo2005-05-05 12:09:00 +00001132 target_flags |= MASK_APCS_FRAME;
9e7454d0 echristo2004-08-24 00:30:52 +00001133
64266206 erich1995-12-06 11:41:39 +00001134 if (TARGET_APCS_REENT && flag_pic)
f060a027 kenner2001-02-04 22:44:12 +00001135 error ("-fpic and -mapcs-reent are incompatible");
9e7454d0 echristo2004-08-24 00:30:52 +00001136
64266206 erich1995-12-06 11:41:39 +00001137 if (TARGET_APCS_REENT)
c3ceba8e dj2005-04-23 21:29:07 +00001138 warning (0, "APCS reentrant code not supported. Ignored");
9e7454d0 echristo2004-08-24 00:30:52 +00001139
cffb2a26 rearnsha2000-04-08 14:29:53 +00001140 /* If this target is normally configured to use APCS frames, warn if they
1141 are turned off and debugging is turned on. */
1142 if (TARGET_ARM
1143 && write_symbols != NO_DEBUG
215b30b3 rearnsha2000-10-09 18:42:34 +00001144 && !TARGET_APCS_FRAME
81f6de2f rsandifo2005-05-05 12:09:00 +00001145 && (TARGET_DEFAULT & MASK_APCS_FRAME))
c3ceba8e dj2005-04-23 21:29:07 +00001146 warning (0, "-g with -mno-apcs-frame may not give sensible debugging");
9e7454d0 echristo2004-08-24 00:30:52 +00001147
64266206 erich1995-12-06 11:41:39 +00001148 if (TARGET_APCS_FLOAT)
c3ceba8e dj2005-04-23 21:29:07 +00001149 warning (0, "passing floating point arguments in fp regs not yet supported");
9e7454d0 echristo2004-08-24 00:30:52 +00001150
457275b6 kazu2002-09-14 15:51:45 +00001151 /* Initialize boolean versions of the flags, for use in the arm.md file. */
a2cd141b pbrook2004-02-03 14:45:44 +00001152 arm_arch3m = (insn_flags & FL_ARCH3M) != 0;
1153 arm_arch4 = (insn_flags & FL_ARCH4) != 0;
f1039640 rearnsha2004-06-25 10:42:21 +00001154 arm_arch4t = arm_arch4 & ((insn_flags & FL_THUMB) != 0);
a2cd141b pbrook2004-02-03 14:45:44 +00001155 arm_arch5 = (insn_flags & FL_ARCH5) != 0;
1156 arm_arch5e = (insn_flags & FL_ARCH5E) != 0;
1157 arm_arch6 = (insn_flags & FL_ARCH6) != 0;
f655717d drow2005-11-04 15:02:51 +00001158 arm_arch6k = (insn_flags & FL_ARCH6K) != 0;
25f905c2 pbrook2007-01-03 23:48:10 +00001159 arm_arch_notm = (insn_flags & FL_NOTM) != 0;
1160 arm_arch_thumb2 = (insn_flags & FL_THUMB2) != 0;
a2cd141b pbrook2004-02-03 14:45:44 +00001161 arm_arch_xscale = (insn_flags & FL_XSCALE) != 0;
e65e4284 pbrook2004-04-30 12:13:49 +00001162 arm_arch_cirrus = (insn_flags & FL_CIRRUS) != 0;
a2cd141b pbrook2004-02-03 14:45:44 +00001163
1164 arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
74a71f7d rearnsha2005-04-09 12:03:54 +00001165 arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
a2cd141b pbrook2004-02-03 14:45:44 +00001166 thumb_code = (TARGET_ARM == 0);
74a71f7d rearnsha2005-04-09 12:03:54 +00001167 arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
a2cd141b pbrook2004-02-03 14:45:44 +00001168 arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
1169 arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
25f905c2 pbrook2007-01-03 23:48:10 +00001170 arm_arch_hwdiv = (insn_flags & FL_DIV) != 0;
755eb2b4 nickc2003-06-18 16:36:13 +00001171
f1039640 rearnsha2004-06-25 10:42:21 +00001172 /* V5 code we generate is completely interworking capable, so we turn off
1173 TARGET_INTERWORK here to avoid many tests later on. */
80b6339a rearnsha2004-07-09 09:30:46 +00001174
1175 /* XXX However, we must pass the right pre-processor defines to CPP
1176 or GLD can get confused. This is a hack. */
1177 if (TARGET_INTERWORK)
1178 arm_cpp_interwork = 1;
1179
f1039640 rearnsha2004-06-25 10:42:21 +00001180 if (arm_arch5)
81f6de2f rsandifo2005-05-05 12:09:00 +00001181 target_flags &= ~MASK_INTERWORK;
f1039640 rearnsha2004-06-25 10:42:21 +00001182
f9273c43 pbrook2004-03-24 17:20:16 +00001183 if (target_abi_name)
1184 {
1185 for (i = 0; i < ARRAY_SIZE (arm_all_abis); i++)
1186 {
1187 if (streq (arm_all_abis[i].name, target_abi_name))
1188 {
1189 arm_abi = arm_all_abis[i].abi_type;
1190 break;
1191 }
1192 }
1193 if (i == ARRAY_SIZE (arm_all_abis))
1194 error ("invalid ABI option: -mabi=%s", target_abi_name);
1195 }
1196 else
13a46000 nickc2004-04-16 13:20:37 +00001197 arm_abi = ARM_DEFAULT_ABI;
f9273c43 pbrook2004-03-24 17:20:16 +00001198
1199 if (TARGET_IWMMXT && !ARM_DOUBLEWORD_ALIGN)
1200 error ("iwmmxt requires an AAPCS compatible ABI for proper operation");
1201
1202 if (TARGET_IWMMXT_ABI && !TARGET_IWMMXT)
1203 error ("iwmmxt abi requires an iwmmxt capable cpu");
89b30d75 nickc2000-12-22 18:22:03 +00001204
a2cd141b pbrook2004-02-03 14:45:44 +00001205 arm_fp_model = ARM_FP_MODEL_UNKNOWN;
1206 if (target_fpu_name == NULL && target_fpe_name != NULL)
7d57ec45 nickc2003-02-10 11:45:26 +00001207 {
a2cd141b pbrook2004-02-03 14:45:44 +00001208 if (streq (target_fpe_name, "2"))
1209 target_fpu_name = "fpe2";
1210 else if (streq (target_fpe_name, "3"))
1211 target_fpu_name = "fpe3";
1212 else
1213 error ("invalid floating point emulation option: -mfpe=%s",
1214 target_fpe_name);
1215 }
1216 if (target_fpu_name != NULL)
1217 {
1218 /* The user specified a FPU. */
1219 for (i = 0; i < ARRAY_SIZE (all_fpus); i++)
1220 {
1221 if (streq (all_fpus[i].name, target_fpu_name))
1222 {
1223 arm_fpu_arch = all_fpus[i].fpu;
1224 arm_fpu_tune = arm_fpu_arch;
1225 arm_fp_model = fp_model_for_fpu[arm_fpu_arch];
1226 break;
1227 }
1228 }
1229 if (arm_fp_model == ARM_FP_MODEL_UNKNOWN)
1230 error ("invalid floating point option: -mfpu=%s", target_fpu_name);
7d57ec45 nickc2003-02-10 11:45:26 +00001231 }
1232 else
64266206 erich1995-12-06 11:41:39 +00001233 {
a2cd141b pbrook2004-02-03 14:45:44 +00001234#ifdef FPUTYPE_DEFAULT
e65e4284 pbrook2004-04-30 12:13:49 +00001235 /* Use the default if it is specified for this platform. */
a2cd141b pbrook2004-02-03 14:45:44 +00001236 arm_fpu_arch = FPUTYPE_DEFAULT;
1237 arm_fpu_tune = FPUTYPE_DEFAULT;
1238#else
1239 /* Pick one based on CPU type. */
e65e4284 pbrook2004-04-30 12:13:49 +00001240 /* ??? Some targets assume FPA is the default.
a2cd141b pbrook2004-02-03 14:45:44 +00001241 if ((insn_flags & FL_VFP) != 0)
1242 arm_fpu_arch = FPUTYPE_VFP;
e65e4284 pbrook2004-04-30 12:13:49 +00001243 else
1244 */
1245 if (arm_arch_cirrus)
a2cd141b pbrook2004-02-03 14:45:44 +00001246 arm_fpu_arch = FPUTYPE_MAVERICK;
1247 else
c7f506fd rearnsha2003-03-10 17:53:19 +00001248 arm_fpu_arch = FPUTYPE_FPA_EMU2;
a2cd141b pbrook2004-02-03 14:45:44 +00001249#endif
1250 if (tune_flags & FL_CO_PROC && arm_fpu_arch == FPUTYPE_FPA_EMU2)
1251 arm_fpu_tune = FPUTYPE_FPA;
64266206 erich1995-12-06 11:41:39 +00001252 else
a2cd141b pbrook2004-02-03 14:45:44 +00001253 arm_fpu_tune = arm_fpu_arch;
1254 arm_fp_model = fp_model_for_fpu[arm_fpu_arch];
ed29c566 nathan2005-04-27 16:09:03 +00001255 gcc_assert (arm_fp_model != ARM_FP_MODEL_UNKNOWN);
a2cd141b pbrook2004-02-03 14:45:44 +00001256 }
1257
1258 if (target_float_abi_name != NULL)
1259 {
1260 /* The user specified a FP ABI. */
1261 for (i = 0; i < ARRAY_SIZE (all_float_abis); i++)
1262 {
1263 if (streq (all_float_abis[i].name, target_float_abi_name))
1264 {
1265 arm_float_abi = all_float_abis[i].abi_type;
1266 break;
1267 }
1268 }
1269 if (i == ARRAY_SIZE (all_float_abis))
1270 error ("invalid floating point abi: -mfloat-abi=%s",
1271 target_float_abi_name);
64266206 erich1995-12-06 11:41:39 +00001272 }
87f8017f pbrook2004-11-18 15:59:48 +00001273 else
1274 arm_float_abi = TARGET_DEFAULT_FLOAT_ABI;
a2cd141b pbrook2004-02-03 14:45:44 +00001275
eb03dcf8 pbrook2004-08-24 11:32:53 +00001276 if (arm_float_abi == ARM_FLOAT_ABI_HARD && TARGET_VFP)
1277 sorry ("-mfloat-abi=hard and VFP");
1278
7f5997af pbrook2006-04-21 17:05:51 +00001279 /* FPA and iWMMXt are incompatible because the insn encodings overlap.
1280 VFP and iWMMXt can theoretically coexist, but it's unlikely such silicon
1281 will ever exist. GCC makes no attempt to support this combination. */
1282 if (TARGET_IWMMXT && !TARGET_SOFT_FLOAT)
1283 sorry ("iWMMXt and hardware floating point");
1284
25f905c2 pbrook2007-01-03 23:48:10 +00001285 /* ??? iWMMXt insn patterns need auditing for Thumb-2. */
1286 if (TARGET_THUMB2 && TARGET_IWMMXT)
1287 sorry ("Thumb-2 iWMMXt");
1288
a2cd141b pbrook2004-02-03 14:45:44 +00001289 /* If soft-float is specified then don't use FPU. */
1290 if (TARGET_SOFT_FLOAT)
1291 arm_fpu_arch = FPUTYPE_NONE;
9e7454d0 echristo2004-08-24 00:30:52 +00001292
9888ad6d nickc1999-02-22 16:47:59 +00001293 /* For arm2/3 there is no need to do any scheduling if there is only
1294 a floating point emulator, or we are doing software floating-point. */
a2cd141b pbrook2004-02-03 14:45:44 +00001295 if ((TARGET_SOFT_FLOAT
1296 || arm_fpu_tune == FPUTYPE_FPA_EMU2
1297 || arm_fpu_tune == FPUTYPE_FPA_EMU3)
55c1e470 rearnsha1999-07-23 13:19:49 +00001298 && (tune_flags & FL_MODE32) == 0)
9888ad6d nickc1999-02-22 16:47:59 +00001299 flag_schedule_insns = flag_schedule_insns_after_reload = 0;
9e7454d0 echristo2004-08-24 00:30:52 +00001300
f655717d drow2005-11-04 15:02:51 +00001301 if (target_thread_switch)
1302 {
1303 if (strcmp (target_thread_switch, "soft") == 0)
1304 target_thread_pointer = TP_SOFT;
1305 else if (strcmp (target_thread_switch, "auto") == 0)
1306 target_thread_pointer = TP_AUTO;
1307 else if (strcmp (target_thread_switch, "cp15") == 0)
1308 target_thread_pointer = TP_CP15;
1309 else
1310 error ("invalid thread pointer option: -mtp=%s", target_thread_switch);
1311 }
1312
1313 /* Use the cp15 method if it is available. */
1314 if (target_thread_pointer == TP_AUTO)
1315 {
1316 if (arm_arch6k && !TARGET_THUMB)
1317 target_thread_pointer = TP_CP15;
1318 else
1319 target_thread_pointer = TP_SOFT;
1320 }
1321
25f905c2 pbrook2007-01-03 23:48:10 +00001322 if (TARGET_HARD_TP && TARGET_THUMB1)
1323 error ("can not use -mtp=cp15 with 16-bit Thumb");
f655717d drow2005-11-04 15:02:51 +00001324
f9273c43 pbrook2004-03-24 17:20:16 +00001325 /* Override the default structure alignment for AAPCS ABI. */
6783d878 kazu2005-10-08 18:17:20 +00001326 if (TARGET_AAPCS_BASED)
f9273c43 pbrook2004-03-24 17:20:16 +00001327 arm_structure_size_boundary = 8;
1328
6cd47762 nickc1998-10-27 11:13:39 +00001329 if (structure_size_string != NULL)
1330 {
1331 int size = strtol (structure_size_string, NULL, 0);
f9273c43 pbrook2004-03-24 17:20:16 +00001332
1333 if (size == 8 || size == 32
1334 || (ARM_DOUBLEWORD_ALIGN && size == 64))
6cd47762 nickc1998-10-27 11:13:39 +00001335 arm_structure_size_boundary = size;
1336 else
c3ceba8e dj2005-04-23 21:29:07 +00001337 warning (0, "structure size boundary can only be set to %s",
f9273c43 pbrook2004-03-24 17:20:16 +00001338 ARM_DOUBLEWORD_ALIGN ? "8, 32 or 64": "8 or 32");
6cd47762 nickc1998-10-27 11:13:39 +00001339 }
55c1e470 rearnsha1999-07-23 13:19:49 +00001340
1ad38120 pbrook2007-02-14 00:29:52 +00001341 /* If stack checking is disabled, we can use r10 as the PIC register,
1342 which keeps r9 available. The EABI specifies r9 as the PIC register. */
1343 if (flag_pic && TARGET_SINGLE_PIC_BASE)
1344 arm_pic_register = (TARGET_APCS_STACK || TARGET_AAPCS_BASED) ? 9 : 10;
1345
55c1e470 rearnsha1999-07-23 13:19:49 +00001346 if (arm_pic_register_string != NULL)
1347 {
df9f5cf8 rth2002-03-13 05:42:40 +00001348 int pic_register = decode_reg_name (arm_pic_register_string);
9f468b67 nickc2002-08-08 11:24:01 +00001349
215b30b3 rearnsha2000-10-09 18:42:34 +00001350 if (!flag_pic)
c3ceba8e dj2005-04-23 21:29:07 +00001351 warning (0, "-mpic-register= is useless without -fpic");
55c1e470 rearnsha1999-07-23 13:19:49 +00001352
55c1e470 rearnsha1999-07-23 13:19:49 +00001353 /* Prevent the user from choosing an obviously stupid PIC register. */
df9f5cf8 rth2002-03-13 05:42:40 +00001354 else if (pic_register < 0 || call_used_regs[pic_register]
1355 || pic_register == HARD_FRAME_POINTER_REGNUM
1356 || pic_register == STACK_POINTER_REGNUM
1357 || pic_register >= PC_REGNUM)
68435912 neil2001-12-03 19:15:19 +00001358 error ("unable to use '%s' for PIC register", arm_pic_register_string);
55c1e470 rearnsha1999-07-23 13:19:49 +00001359 else
1360 arm_pic_register = pic_register;
1361 }
cffb2a26 rearnsha2000-04-08 14:29:53 +00001362
25f905c2 pbrook2007-01-03 23:48:10 +00001363 /* ??? We might want scheduling for thumb2. */
cffb2a26 rearnsha2000-04-08 14:29:53 +00001364 if (TARGET_THUMB && flag_schedule_insns)
1365 {
1366 /* Don't warn since it's on by default in -O2. */
1367 flag_schedule_insns = 0;
1368 }
1369
9888ad6d nickc1999-02-22 16:47:59 +00001370 if (optimize_size)
dde5cb68 nico2003-10-21 01:56:49 +00001371 {
7e28d849 rearnsha2003-10-30 10:26:04 +00001372 arm_constant_limit = 1;
dde5cb68 nico2003-10-21 01:56:49 +00001373
1374 /* If optimizing for size, bump the number of instructions that we
674a8f0b kazu2003-12-25 15:17:37 +00001375 are prepared to conditionally execute (even on a StrongARM). */
dde5cb68 nico2003-10-21 01:56:49 +00001376 max_insns_skipped = 6;
1377 }
1378 else
1379 {
1380 /* For processors with load scheduling, it never costs more than
1381 2 cycles to load a constant, and the load scheduler may well
1382 reduce that to 1. */
359a6e9f rearnsha2004-11-20 11:21:55 +00001383 if (arm_ld_sched)
dde5cb68 nico2003-10-21 01:56:49 +00001384 arm_constant_limit = 1;
1385
1386 /* On XScale the longer latency of a load makes it more difficult
1387 to achieve a good schedule, so it's faster to synthesize
674a8f0b kazu2003-12-25 15:17:37 +00001388 constants that can be done in two insns. */
dde5cb68 nico2003-10-21 01:56:49 +00001389 if (arm_tune_xscale)
1390 arm_constant_limit = 2;
1391
1392 /* StrongARM has early execution of branches, so a sequence
1393 that is worth skipping is shorter. */
74a71f7d rearnsha2005-04-09 12:03:54 +00001394 if (arm_tune_strongarm)
dde5cb68 nico2003-10-21 01:56:49 +00001395 max_insns_skipped = 3;
1396 }
db80f614 rearnsha1999-09-09 14:30:54 +00001397
1398 /* Register global variables with the garbage collector. */
1399 arm_add_gc_roots ();
1400}
1401
1402static void
ebd88a36 rearnsha2003-06-10 18:55:17 +00001403arm_add_gc_roots (void)
db80f614 rearnsha1999-09-09 14:30:54 +00001404{
a220ccce rearnsha2000-10-13 15:54:16 +00001405 gcc_obstack_init(&minipool_obstack);
1406 minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
64266206 erich1995-12-06 11:41:39 +00001407}
8cd42699 mycroft1992-03-14 05:17:02 +00001408\f
e27ad2d5 nickc2000-12-08 19:25:33 +00001409/* A table of known ARM exception types.
1410 For use with the interrupt function attribute. */
1411
1412typedef struct
1413{
e99c3a1d ghazi2001-10-07 16:51:11 +00001414 const char *const arg;
1415 const unsigned long return_value;
e27ad2d5 nickc2000-12-08 19:25:33 +00001416}
1417isr_attribute_arg;
1418
e99c3a1d ghazi2001-10-07 16:51:11 +00001419static const isr_attribute_arg isr_attribute_args [] =
e27ad2d5 nickc2000-12-08 19:25:33 +00001420{
1421 { "IRQ", ARM_FT_ISR },
1422 { "irq", ARM_FT_ISR },
1423 { "FIQ", ARM_FT_FIQ },
1424 { "fiq", ARM_FT_FIQ },
1425 { "ABORT", ARM_FT_ISR },
1426 { "abort", ARM_FT_ISR },
1427 { "ABORT", ARM_FT_ISR },
1428 { "abort", ARM_FT_ISR },
1429 { "UNDEF", ARM_FT_EXCEPTION },
1430 { "undef", ARM_FT_EXCEPTION },
1431 { "SWI", ARM_FT_EXCEPTION },
1432 { "swi", ARM_FT_EXCEPTION },
1433 { NULL, ARM_FT_NORMAL }
1434};
1435
1436/* Returns the (interrupt) function type of the current
1437 function, or ARM_FT_UNKNOWN if the type cannot be determined. */
1438
1439static unsigned long
ebd88a36 rearnsha2003-06-10 18:55:17 +00001440arm_isr_value (tree argument)
e27ad2d5 nickc2000-12-08 19:25:33 +00001441{
e99c3a1d ghazi2001-10-07 16:51:11 +00001442 const isr_attribute_arg * ptr;
a12be13c nickc2002-01-16 12:25:53 +00001443 const char * arg;
e27ad2d5 nickc2000-12-08 19:25:33 +00001444
25f905c2 pbrook2007-01-03 23:48:10 +00001445 if (!arm_arch_notm)
1446 return ARM_FT_NORMAL | ARM_FT_STACKALIGN;
1447
e27ad2d5 nickc2000-12-08 19:25:33 +00001448 /* No argument - default to IRQ. */
1449 if (argument == NULL_TREE)
1450 return ARM_FT_ISR;
1451
1452 /* Get the value of the argument. */
1453 if (TREE_VALUE (argument) == NULL_TREE
1454 || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
1455 return ARM_FT_UNKNOWN;
1456
1457 arg = TREE_STRING_POINTER (TREE_VALUE (argument));
1458
1459 /* Check it against the list of known arguments. */
755eb2b4 nickc2003-06-18 16:36:13 +00001460 for (ptr = isr_attribute_args; ptr->arg != NULL; ptr++)
a12be13c nickc2002-01-16 12:25:53 +00001461 if (streq (arg, ptr->arg))
1462 return ptr->return_value;
e27ad2d5 nickc2000-12-08 19:25:33 +00001463
a2f10574 kazu2002-09-15 18:24:08 +00001464 /* An unrecognized interrupt type. */
e27ad2d5 nickc2000-12-08 19:25:33 +00001465 return ARM_FT_UNKNOWN;
1466}
1467
1468/* Computes the type of the current function. */
1469
1470static unsigned long
ebd88a36 rearnsha2003-06-10 18:55:17 +00001471arm_compute_func_type (void)
e27ad2d5 nickc2000-12-08 19:25:33 +00001472{
1473 unsigned long type = ARM_FT_UNKNOWN;
1474 tree a;
1475 tree attr;
9e7454d0 echristo2004-08-24 00:30:52 +00001476
ed29c566 nathan2005-04-27 16:09:03 +00001477 gcc_assert (TREE_CODE (current_function_decl) == FUNCTION_DECL);
e27ad2d5 nickc2000-12-08 19:25:33 +00001478
1479 /* Decide if the current function is volatile. Such functions
1480 never return, and many memory cycles can be saved by not storing
1481 register values that will never be needed again. This optimization
1482 was added to speed up context switching in a kernel application. */
1483 if (optimize > 0
c4d51de2 pbrook2006-01-20 00:01:56 +00001484 && (TREE_NOTHROW (current_function_decl)
1485 || !(flag_unwind_tables
1486 || (flag_exceptions && !USING_SJLJ_EXCEPTIONS)))
e27ad2d5 nickc2000-12-08 19:25:33 +00001487 && TREE_THIS_VOLATILE (current_function_decl))
1488 type |= ARM_FT_VOLATILE;
9e7454d0 echristo2004-08-24 00:30:52 +00001489
4ee9c684 dnovillo2004-05-13 06:41:07 +00001490 if (cfun->static_chain_decl != NULL)
e27ad2d5 nickc2000-12-08 19:25:33 +00001491 type |= ARM_FT_NESTED;
1492
e3c541f0 jsm282001-09-21 01:27:06 +00001493 attr = DECL_ATTRIBUTES (current_function_decl);
9e7454d0 echristo2004-08-24 00:30:52 +00001494
e27ad2d5 nickc2000-12-08 19:25:33 +00001495 a = lookup_attribute ("naked", attr);
1496 if (a != NULL_TREE)
1497 type |= ARM_FT_NAKED;
1498
4c44712e pbrook2004-08-10 16:22:47 +00001499 a = lookup_attribute ("isr", attr);
1500 if (a == NULL_TREE)
1501 a = lookup_attribute ("interrupt", attr);
9e7454d0 echristo2004-08-24 00:30:52 +00001502
4c44712e pbrook2004-08-10 16:22:47 +00001503 if (a == NULL_TREE)
1504 type |= TARGET_INTERWORK ? ARM_FT_INTERWORKED : ARM_FT_NORMAL;
e27ad2d5 nickc2000-12-08 19:25:33 +00001505 else
4c44712e pbrook2004-08-10 16:22:47 +00001506 type |= arm_isr_value (TREE_VALUE (a));
9e7454d0 echristo2004-08-24 00:30:52 +00001507
e27ad2d5 nickc2000-12-08 19:25:33 +00001508 return type;
1509}
1510
1511/* Returns the type of the current function. */
1512
1513unsigned long
ebd88a36 rearnsha2003-06-10 18:55:17 +00001514arm_current_func_type (void)
e27ad2d5 nickc2000-12-08 19:25:33 +00001515{
1516 if (ARM_FUNC_TYPE (cfun->machine->func_type) == ARM_FT_UNKNOWN)
1517 cfun->machine->func_type = arm_compute_func_type ();
1518
1519 return cfun->machine->func_type;
1520}
1521\f
9e7454d0 echristo2004-08-24 00:30:52 +00001522/* Return 1 if it is possible to return using a single instruction.
ffc9d00c rearnsha2003-11-20 11:44:19 +00001523 If SIBLING is non-null, this is a test for a return before a sibling
1524 call. SIBLING is the call insn, so we can examine its register usage. */
e27ad2d5 nickc2000-12-08 19:25:33 +00001525
9c08d1fa erich1993-10-03 16:33:02 +00001526int
ffc9d00c rearnsha2003-11-20 11:44:19 +00001527use_return_insn (int iscond, rtx sibling)
9c08d1fa erich1993-10-03 16:33:02 +00001528{
1529 int regno;
5cf3595a rearnsha2001-01-15 18:13:26 +00001530 unsigned int func_type;
50368af8 rearnsha2002-11-01 14:41:57 +00001531 unsigned long saved_int_regs;
ffc9d00c rearnsha2003-11-20 11:44:19 +00001532 unsigned HOST_WIDE_INT stack_adjust;
f9273c43 pbrook2004-03-24 17:20:16 +00001533 arm_stack_offsets *offsets;
9c08d1fa erich1993-10-03 16:33:02 +00001534
cffb2a26 rearnsha2000-04-08 14:29:53 +00001535 /* Never use a return instruction before reload has run. */
e27ad2d5 nickc2000-12-08 19:25:33 +00001536 if (!reload_completed)
1537 return 0;
01c5c234 nathan2003-10-17 14:45:47 +00001538
5cf3595a rearnsha2001-01-15 18:13:26 +00001539 func_type = arm_current_func_type ();
1540
25f905c2 pbrook2007-01-03 23:48:10 +00001541 /* Naked, volatile and stack alignment functions need special
4a5f62e2 pb2002-02-19 18:08:10 +00001542 consideration. */
25f905c2 pbrook2007-01-03 23:48:10 +00001543 if (func_type & (ARM_FT_VOLATILE | ARM_FT_NAKED | ARM_FT_STACKALIGN))
e27ad2d5 nickc2000-12-08 19:25:33 +00001544 return 0;
000c5098 nickc2003-01-24 15:50:44 +00001545
8b438b4f pbrook2007-01-04 00:09:48 +00001546 /* So do interrupt functions that use the frame pointer and Thumb
1547 interrupt functions. */
1548 if (IS_INTERRUPT (func_type) && (frame_pointer_needed || TARGET_THUMB))
000c5098 nickc2003-01-24 15:50:44 +00001549 return 0;
ffc9d00c rearnsha2003-11-20 11:44:19 +00001550
f9273c43 pbrook2004-03-24 17:20:16 +00001551 offsets = arm_get_frame_offsets ();
1552 stack_adjust = offsets->outgoing_args - offsets->saved_regs;
ffc9d00c rearnsha2003-11-20 11:44:19 +00001553
e27ad2d5 nickc2000-12-08 19:25:33 +00001554 /* As do variadic functions. */
1555 if (current_function_pretend_args_size
71904594 nickc2002-02-04 20:23:07 +00001556 || cfun->machine->uses_anonymous_args
8d69f2ad rearnsha2003-10-28 09:47:45 +00001557 /* Or if the function calls __builtin_eh_return () */
4c44712e pbrook2004-08-10 16:22:47 +00001558 || current_function_calls_eh_return
8d69f2ad rearnsha2003-10-28 09:47:45 +00001559 /* Or if the function calls alloca */
1560 || current_function_calls_alloca
ffc9d00c rearnsha2003-11-20 11:44:19 +00001561 /* Or if there is a stack adjustment. However, if the stack pointer
1562 is saved on the stack, we can use a pre-incrementing stack load. */
1563 || !(stack_adjust == 0 || (frame_pointer_needed && stack_adjust == 4)))
9c08d1fa erich1993-10-03 16:33:02 +00001564 return 0;
1565
50368af8 rearnsha2002-11-01 14:41:57 +00001566 saved_int_regs = arm_compute_save_reg_mask ();
1567
ffc9d00c rearnsha2003-11-20 11:44:19 +00001568 /* Unfortunately, the insn
1569
1570 ldmib sp, {..., sp, ...}
1571
1572 triggers a bug on most SA-110 based devices, such that the stack
1573 pointer won't be correctly restored if the instruction takes a
efee20da kazu2003-12-13 04:44:12 +00001574 page fault. We work around this problem by popping r3 along with
ffc9d00c rearnsha2003-11-20 11:44:19 +00001575 the other registers, since that is never slower than executing
9e7454d0 echristo2004-08-24 00:30:52 +00001576 another instruction.
ffc9d00c rearnsha2003-11-20 11:44:19 +00001577
1578 We test for !arm_arch5 here, because code for any architecture
1579 less than this could potentially be run on one of the buggy
1580 chips. */
25f905c2 pbrook2007-01-03 23:48:10 +00001581 if (stack_adjust == 4 && !arm_arch5 && TARGET_ARM)
ffc9d00c rearnsha2003-11-20 11:44:19 +00001582 {
1583 /* Validate that r3 is a call-clobbered register (always true in
674a8f0b kazu2003-12-25 15:17:37 +00001584 the default abi) ... */
ffc9d00c rearnsha2003-11-20 11:44:19 +00001585 if (!call_used_regs[3])
1586 return 0;
1587
0858d94e pbrook2005-05-13 21:13:17 +00001588 /* ... that it isn't being used for a return value ... */
1589 if (arm_size_return_regs () >= (4 * UNITS_PER_WORD))
1590 return 0;
1591
1592 /* ... or for a tail-call argument ... */
ffc9d00c rearnsha2003-11-20 11:44:19 +00001593 if (sibling)
1594 {
ed29c566 nathan2005-04-27 16:09:03 +00001595 gcc_assert (GET_CODE (sibling) == CALL_INSN);
ffc9d00c rearnsha2003-11-20 11:44:19 +00001596
1597 if (find_regno_fusage (sibling, USE, 3))
1598 return 0;
1599 }
1600
1601 /* ... and that there are no call-saved registers in r0-r2
1602 (always true in the default ABI). */
1603 if (saved_int_regs & 0x7)
1604 return 0;
1605 }
1606
f21249d5 erich1997-07-16 14:54:40 +00001607 /* Can't be done if interworking with Thumb, and any registers have been
50368af8 rearnsha2002-11-01 14:41:57 +00001608 stacked. */
8b438b4f pbrook2007-01-04 00:09:48 +00001609 if (TARGET_INTERWORK && saved_int_regs != 0 && !IS_INTERRUPT(func_type))
129a2fe4 rearnsha1999-02-06 04:09:55 +00001610 return 0;
50368af8 rearnsha2002-11-01 14:41:57 +00001611
1612 /* On StrongARM, conditional returns are expensive if they aren't
1613 taken and multiple registers have been stacked. */
74a71f7d rearnsha2005-04-09 12:03:54 +00001614 if (iscond && arm_tune_strongarm)
0eb4b5ff rearnsha1999-06-19 05:34:51 +00001615 {
9e7454d0 echristo2004-08-24 00:30:52 +00001616 /* Conditional return when just the LR is stored is a simple
50368af8 rearnsha2002-11-01 14:41:57 +00001617 conditional-load instruction, that's not expensive. */
1618 if (saved_int_regs != 0 && saved_int_regs != (1 << LR_REGNUM))
1619 return 0;
0eb4b5ff rearnsha1999-06-19 05:34:51 +00001620
2cb7d577 rearnsha2006-01-17 20:22:19 +00001621 if (flag_pic
1622 && arm_pic_register != INVALID_REGNUM
1623 && regs_ever_live[PIC_OFFSET_TABLE_REGNUM])
f21249d5 erich1997-07-16 14:54:40 +00001624 return 0;
0eb4b5ff rearnsha1999-06-19 05:34:51 +00001625 }
50368af8 rearnsha2002-11-01 14:41:57 +00001626
1627 /* If there are saved registers but the LR isn't saved, then we need
1628 two instructions for the return. */
1629 if (saved_int_regs && !(saved_int_regs & (1 << LR_REGNUM)))
1630 return 0;
1631
e8ff69a4 rearnsha2003-03-08 16:23:20 +00001632 /* Can't be done if any of the FPA regs are pushed,
e27ad2d5 nickc2000-12-08 19:25:33 +00001633 since this also requires an insn. */
a2cd141b pbrook2004-02-03 14:45:44 +00001634 if (TARGET_HARD_FLOAT && TARGET_FPA)
1635 for (regno = FIRST_FPA_REGNUM; regno <= LAST_FPA_REGNUM; regno++)
1636 if (regs_ever_live[regno] && !call_used_regs[regno])
1637 return 0;
1638
1639 /* Likewise VFP regs. */
1640 if (TARGET_HARD_FLOAT && TARGET_VFP)
1641 for (regno = FIRST_VFP_REGNUM; regno <= LAST_VFP_REGNUM; regno++)
215b30b3 rearnsha2000-10-09 18:42:34 +00001642 if (regs_ever_live[regno] && !call_used_regs[regno])
cffb2a26 rearnsha2000-04-08 14:29:53 +00001643 return 0;
9c08d1fa erich1993-10-03 16:33:02 +00001644
755eb2b4 nickc2003-06-18 16:36:13 +00001645 if (TARGET_REALLY_IWMMXT)
1646 for (regno = FIRST_IWMMXT_REGNUM; regno <= LAST_IWMMXT_REGNUM; regno++)
1647 if (regs_ever_live[regno] && ! call_used_regs [regno])
1648 return 0;
1649
9c08d1fa erich1993-10-03 16:33:02 +00001650 return 1;
1651}
1652
8cd42699 mycroft1992-03-14 05:17:02 +00001653/* Return TRUE if int I is a valid immediate ARM constant. */
1654
1655int
ebd88a36 rearnsha2003-06-10 18:55:17 +00001656const_ok_for_arm (HOST_WIDE_INT i)
8cd42699 mycroft1992-03-14 05:17:02 +00001657{
eaae9d8c rearnsha2005-05-09 22:09:47 +00001658 int lowbit;
a60f1840 nickc2005-10-10 07:57:21 +00001659
9e7454d0 echristo2004-08-24 00:30:52 +00001660 /* For machines with >32 bit HOST_WIDE_INT, the bits above bit 31 must
6019008a law1997-11-03 02:26:49 +00001661 be all zero, or all one. */
35cea10c ghazi2001-10-22 19:36:24 +00001662 if ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff) != 0
1663 && ((i & ~(unsigned HOST_WIDE_INT) 0xffffffff)
1664 != ((~(unsigned HOST_WIDE_INT) 0)
1665 & ~(unsigned HOST_WIDE_INT) 0xffffffff)))
6019008a law1997-11-03 02:26:49 +00001666 return FALSE;
9e7454d0 echristo2004-08-24 00:30:52 +00001667
eaae9d8c rearnsha2005-05-09 22:09:47 +00001668 i &= (unsigned HOST_WIDE_INT) 0xffffffff;
a60f1840 nickc2005-10-10 07:57:21 +00001669
eaae9d8c rearnsha2005-05-09 22:09:47 +00001670 /* Fast return for 0 and small values. We must do this for zero, since
1671 the code below can't handle that one case. */
1672 if ((i & ~(unsigned HOST_WIDE_INT) 0xff) == 0)
4b6897e9 erich1994-06-23 16:02:41 +00001673 return TRUE;
1674
25f905c2 pbrook2007-01-03 23:48:10 +00001675 /* Get the number of trailing zeros. */
1676 lowbit = ffs((int) i) - 1;
1677
1678 /* Only even shifts are allowed in ARM mode so round down to the
1679 nearest even number. */
1680 if (TARGET_ARM)
1681 lowbit &= ~1;
eaae9d8c rearnsha2005-05-09 22:09:47 +00001682
1683 if ((i & ~(((unsigned HOST_WIDE_INT) 0xff) << lowbit)) == 0)
1684 return TRUE;
25f905c2 pbrook2007-01-03 23:48:10 +00001685
1686 if (TARGET_ARM)
1687 {
1688 /* Allow rotated constants in ARM mode. */
1689 if (lowbit <= 4
eaae9d8c rearnsha2005-05-09 22:09:47 +00001690 && ((i & ~0xc000003f) == 0
1691 || (i & ~0xf000000f) == 0
1692 || (i & ~0xfc000003) == 0))
25f905c2 pbrook2007-01-03 23:48:10 +00001693 return TRUE;
1694 }
1695 else
1696 {
1697 HOST_WIDE_INT v;
1698
1699 /* Allow repeated pattern. */
1700 v = i & 0xff;
1701 v |= v << 16;
1702 if (i == v || i == (v | (v << 8)))
1703 return TRUE;
1704 }
8cd42699 mycroft1992-03-14 05:17:02 +00001705
a690ede2 erich1994-06-01 17:09:29 +00001706 return FALSE;
1707}
8cd42699 mycroft1992-03-14 05:17:02 +00001708
66aacf41 nickc2000-03-29 19:15:36 +00001709/* Return true if I is a valid constant for the operation CODE. */
016696d4 nickc1999-03-22 16:32:31 +00001710static int
ebd88a36 rearnsha2003-06-10 18:55:17 +00001711const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
4b6897e9 erich1994-06-23 16:02:41 +00001712{
1713 if (const_ok_for_arm (i))
1714 return 1;
1715
1716 switch (code)
1717 {
1718 case PLUS:
1719 return const_ok_for_arm (ARM_SIGN_EXTEND (-i));
1720
1721 case MINUS: /* Should only occur with (MINUS I reg) => rsb */
1722 case XOR:
1723 case IOR:
1724 return 0;
1725
1726 case AND:
1727 return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
1728
1729 default:
ed29c566 nathan2005-04-27 16:09:03 +00001730 gcc_unreachable ();
4b6897e9 erich1994-06-23 16:02:41 +00001731 }
1732}
1733
1734/* Emit a sequence of insns to handle a large constant.
1735 CODE is the code of the operation required, it can be any of SET, PLUS,
1736 IOR, AND, XOR, MINUS;
1737 MODE is the mode in which the operation is being performed;
1738 VAL is the integer to operate on;
1739 SOURCE is the other operand (a register, or a null-pointer for SET);
1740 SUBTARGETS means it is safe to create scratch registers if that will
64266206 erich1995-12-06 11:41:39 +00001741 either produce a simpler sequence, or we will want to cse the values.
1742 Return value is the number of insns emitted. */
4b6897e9 erich1994-06-23 16:02:41 +00001743
25f905c2 pbrook2007-01-03 23:48:10 +00001744/* ??? Tweak this for thumb2. */
4b6897e9 erich1994-06-23 16:02:41 +00001745int
96f57e36 mmitchel2004-04-01 23:30:25 +00001746arm_split_constant (enum rtx_code code, enum machine_mode mode, rtx insn,
ebd88a36 rearnsha2003-06-10 18:55:17 +00001747 HOST_WIDE_INT val, rtx target, rtx source, int subtargets)
4b6897e9 erich1994-06-23 16:02:41 +00001748{
96f57e36 mmitchel2004-04-01 23:30:25 +00001749 rtx cond;
1750
1751 if (insn && GET_CODE (PATTERN (insn)) == COND_EXEC)
1752 cond = COND_EXEC_TEST (PATTERN (insn));
1753 else
1754 cond = NULL_RTX;
1755
64266206 erich1995-12-06 11:41:39 +00001756 if (subtargets || code == SET
1757 || (GET_CODE (target) == REG && GET_CODE (source) == REG
1758 && REGNO (target) != REGNO (source)))
1759 {
11de4c7f rearnsha1999-03-13 11:40:25 +00001760 /* After arm_reorg has been called, we can't fix up expensive
a2f10574 kazu2002-09-15 18:24:08 +00001761 constants by pushing them into memory so we must synthesize
11de4c7f rearnsha1999-03-13 11:40:25 +00001762 them in-line, regardless of the cost. This is only likely to
1763 be more costly on chips that have load delay slots and we are
1764 compiling without running the scheduler (so no splitting
82ec49ae nickc1999-03-17 14:47:27 +00001765 occurred before the final instruction emission).
1766
1767 Ref: gcc -O1 -mcpu=strongarm gcc.c-torture/compile/980506-2.c
82ec49ae nickc1999-03-17 14:47:27 +00001768 */
215b30b3 rearnsha2000-10-09 18:42:34 +00001769 if (!after_arm_reorg
96f57e36 mmitchel2004-04-01 23:30:25 +00001770 && !cond
9e7454d0 echristo2004-08-24 00:30:52 +00001771 && (arm_gen_constant (code, mode, NULL_RTX, val, target, source,
96f57e36 mmitchel2004-04-01 23:30:25 +00001772 1, 0)
11de4c7f rearnsha1999-03-13 11:40:25 +00001773 > arm_constant_limit + (code != SET)))
64266206 erich1995-12-06 11:41:39 +00001774 {
1775 if (code == SET)
1776 {
1777 /* Currently SET is the only monadic value for CODE, all
1778 the rest are diadic. */
0083a3b9 rearnsha2005-11-22 14:30:10 +00001779 emit_set_insn (target, GEN_INT (val));
64266206 erich1995-12-06 11:41:39 +00001780 return 1;
1781 }
1782 else
1783 {
1784 rtx temp = subtargets ? gen_reg_rtx (mode) : target;
1785
0083a3b9 rearnsha2005-11-22 14:30:10 +00001786 emit_set_insn (temp, GEN_INT (val));
64266206 erich1995-12-06 11:41:39 +00001787 /* For MINUS, the value is subtracted from, since we never
1788 have subtraction of a constant. */
1789 if (code == MINUS)
0083a3b9 rearnsha2005-11-22 14:30:10 +00001790 emit_set_insn (target, gen_rtx_MINUS (mode, temp, source));
64266206 erich1995-12-06 11:41:39 +00001791 else
0083a3b9 rearnsha2005-11-22 14:30:10 +00001792 emit_set_insn (target,
1793 gen_rtx_fmt_ee (code, mode, source, temp));
64266206 erich1995-12-06 11:41:39 +00001794 return 2;
1795 }
1796 }
1797 }
1798
9e7454d0 echristo2004-08-24 00:30:52 +00001799 return arm_gen_constant (code, mode, cond, val, target, source, subtargets,
96f57e36 mmitchel2004-04-01 23:30:25 +00001800 1);
64266206 erich1995-12-06 11:41:39 +00001801}
1802
25f905c2 pbrook2007-01-03 23:48:10 +00001803/* Return the number of ARM instructions required to synthesize the given
1804 constant. */
cd8df93e pb2001-01-04 20:19:48 +00001805static int
ebd88a36 rearnsha2003-06-10 18:55:17 +00001806count_insns_for_constant (HOST_WIDE_INT remainder, int i)
cd8df93e pb2001-01-04 20:19:48 +00001807{
1808 HOST_WIDE_INT temp1;
1809 int num_insns = 0;
1810 do
1811 {
1812 int end;
9e7454d0 echristo2004-08-24 00:30:52 +00001813
cd8df93e pb2001-01-04 20:19:48 +00001814 if (i <= 0)
1815 i += 32;
1816 if (remainder & (3 << (i - 2)))
1817 {
1818 end = i - 8;
1819 if (end < 0)
1820 end += 32;
1821 temp1 = remainder & ((0x0ff << end)
1822 | ((i < end) ? (0xff >> (32 - end)) : 0));
1823 remainder &= ~temp1;
1824 num_insns++;
1825 i -= 6;
1826 }
1827 i -= 2;
1828 } while (remainder);
1829 return num_insns;
1830}
1831
96f57e36 mmitchel2004-04-01 23:30:25 +00001832/* Emit an instruction with the indicated PATTERN. If COND is
1833 non-NULL, conditionalize the execution of the instruction on COND
1834 being true. */
1835
1836static void
1837emit_constant_insn (rtx cond, rtx pattern)
1838{
1839 if (cond)
1840 pattern = gen_rtx_COND_EXEC (VOIDmode, copy_rtx (cond), pattern);
1841 emit_insn (pattern);
1842}
1843
64266206 erich1995-12-06 11:41:39 +00001844/* As above, but extra parameter GENERATE which, if clear, suppresses
1845 RTL generation. */
25f905c2 pbrook2007-01-03 23:48:10 +00001846/* ??? This needs more work for thumb2. */
a12be13c nickc2002-01-16 12:25:53 +00001847
cffb2a26 rearnsha2000-04-08 14:29:53 +00001848static int
96f57e36 mmitchel2004-04-01 23:30:25 +00001849arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
ebd88a36 rearnsha2003-06-10 18:55:17 +00001850 HOST_WIDE_INT val, rtx target, rtx source, int subtargets,
1851 int generate)
64266206 erich1995-12-06 11:41:39 +00001852{
4b6897e9 erich1994-06-23 16:02:41 +00001853 int can_invert = 0;
1854 int can_negate = 0;
1855 int can_negate_initial = 0;
1856 int can_shift = 0;
1857 int i;
1858 int num_bits_set = 0;
1859 int set_sign_bit_copies = 0;
1860 int clear_sign_bit_copies = 0;
1861 int clear_zero_bit_copies = 0;
1862 int set_zero_bit_copies = 0;
1863 int insns = 0;
4b6897e9 erich1994-06-23 16:02:41 +00001864 unsigned HOST_WIDE_INT temp1, temp2;
35cea10c ghazi2001-10-22 19:36:24 +00001865 unsigned HOST_WIDE_INT remainder = val & 0xffffffff;
4b6897e9 erich1994-06-23 16:02:41 +00001866
cffb2a26 rearnsha2000-04-08 14:29:53 +00001867 /* Find out which operations are safe for a given CODE. Also do a quick
4b6897e9 erich1994-06-23 16:02:41 +00001868 check for degenerate cases; these can occur when DImode operations
1869 are split. */
1870 switch (code)
1871 {
1872 case SET:
1873 can_invert = 1;
1874 can_shift = 1;
1875 can_negate = 1;
1876 break;
1877
1878 case PLUS:
1879 can_negate = 1;
1880 can_negate_initial = 1;
1881 break;
1882
1883 case IOR:
35cea10c ghazi2001-10-22 19:36:24 +00001884 if (remainder == 0xffffffff)
4b6897e9 erich1994-06-23 16:02:41 +00001885 {
64266206 erich1995-12-06 11:41:39 +00001886 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00001887 emit_constant_insn (cond,
1888 gen_rtx_SET (VOIDmode, target,
1889 GEN_INT (ARM_SIGN_EXTEND (val))));
4b6897e9 erich1994-06-23 16:02:41 +00001890 return 1;
1891 }
1892 if (remainder == 0)
1893 {
1894 if (reload_completed && rtx_equal_p (target, source))
1895 return 0;
64266206 erich1995-12-06 11:41:39 +00001896 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00001897 emit_constant_insn (cond,
1898 gen_rtx_SET (VOIDmode, target, source));
4b6897e9 erich1994-06-23 16:02:41 +00001899 return 1;
1900 }
1901 break;
1902
1903 case AND:
1904 if (remainder == 0)
1905 {
64266206 erich1995-12-06 11:41:39 +00001906 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00001907 emit_constant_insn (cond,
1908 gen_rtx_SET (VOIDmode, target, const0_rtx));
4b6897e9 erich1994-06-23 16:02:41 +00001909 return 1;
1910 }
35cea10c ghazi2001-10-22 19:36:24 +00001911 if (remainder == 0xffffffff)
4b6897e9 erich1994-06-23 16:02:41 +00001912 {
1913 if (reload_completed && rtx_equal_p (target, source))
1914 return 0;
64266206 erich1995-12-06 11:41:39 +00001915 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00001916 emit_constant_insn (cond,
1917 gen_rtx_SET (VOIDmode, target, source));
4b6897e9 erich1994-06-23 16:02:41 +00001918 return 1;
1919 }
1920 can_invert = 1;
1921 break;
1922
1923 case XOR:
1924 if (remainder == 0)
1925 {
1926 if (reload_completed && rtx_equal_p (target, source))
1927 return 0;
64266206 erich1995-12-06 11:41:39 +00001928 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00001929 emit_constant_insn (cond,
1930 gen_rtx_SET (VOIDmode, target, source));
4b6897e9 erich1994-06-23 16:02:41 +00001931 return 1;
1932 }
a60f1840 nickc2005-10-10 07:57:21 +00001933
ed29c566 nathan2005-04-27 16:09:03 +00001934 /* We don't know how to handle other cases yet. */
1935 gcc_assert (remainder == 0xffffffff);
a60f1840 nickc2005-10-10 07:57:21 +00001936
ed29c566 nathan2005-04-27 16:09:03 +00001937 if (generate)
1938 emit_constant_insn (cond,
1939 gen_rtx_SET (VOIDmode, target,
1940 gen_rtx_NOT (mode, source)));
1941 return 1;
4b6897e9 erich1994-06-23 16:02:41 +00001942
1943 case MINUS:
1944 /* We treat MINUS as (val - source), since (source - val) is always
1945 passed as (source + (-val)). */
1946 if (remainder == 0)
1947 {
64266206 erich1995-12-06 11:41:39 +00001948 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00001949 emit_constant_insn (cond,
1950 gen_rtx_SET (VOIDmode, target,
1951 gen_rtx_NEG (mode, source)));
4b6897e9 erich1994-06-23 16:02:41 +00001952 return 1;
1953 }
1954 if (const_ok_for_arm (val))
1955 {
64266206 erich1995-12-06 11:41:39 +00001956 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00001957 emit_constant_insn (cond,
9e7454d0 echristo2004-08-24 00:30:52 +00001958 gen_rtx_SET (VOIDmode, target,
96f57e36 mmitchel2004-04-01 23:30:25 +00001959 gen_rtx_MINUS (mode, GEN_INT (val),
1960 source)));
4b6897e9 erich1994-06-23 16:02:41 +00001961 return 1;
1962 }
1963 can_negate = 1;
1964
1965 break;
1966
1967 default:
ed29c566 nathan2005-04-27 16:09:03 +00001968 gcc_unreachable ();
4b6897e9 erich1994-06-23 16:02:41 +00001969 }
1970
66aacf41 nickc2000-03-29 19:15:36 +00001971 /* If we can do it in one insn get out quickly. */
4b6897e9 erich1994-06-23 16:02:41 +00001972 if (const_ok_for_arm (val)
1973 || (can_negate_initial && const_ok_for_arm (-val))
1974 || (can_invert && const_ok_for_arm (~val)))
1975 {
64266206 erich1995-12-06 11:41:39 +00001976 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00001977 emit_constant_insn (cond,
1978 gen_rtx_SET (VOIDmode, target,
9e7454d0 echristo2004-08-24 00:30:52 +00001979 (source
96f57e36 mmitchel2004-04-01 23:30:25 +00001980 ? gen_rtx_fmt_ee (code, mode, source,
1981 GEN_INT (val))
1982 : GEN_INT (val))));
4b6897e9 erich1994-06-23 16:02:41 +00001983 return 1;
1984 }
1985
4b6897e9 erich1994-06-23 16:02:41 +00001986 /* Calculate a few attributes that may be useful for specific
66aacf41 nickc2000-03-29 19:15:36 +00001987 optimizations. */
4b6897e9 erich1994-06-23 16:02:41 +00001988 for (i = 31; i >= 0; i--)
1989 {
1990 if ((remainder & (1 << i)) == 0)
1991 clear_sign_bit_copies++;
1992 else
1993 break;
1994 }
1995
1996 for (i = 31; i >= 0; i--)
1997 {
1998 if ((remainder & (1 << i)) != 0)
1999 set_sign_bit_copies++;
2000 else
2001 break;
2002 }
2003
2004 for (i = 0; i <= 31; i++)
2005 {
2006 if ((remainder & (1 << i)) == 0)
2007 clear_zero_bit_copies++;
2008 else
2009 break;
2010 }
2011
2012 for (i = 0; i <= 31; i++)
2013 {
2014 if ((remainder & (1 << i)) != 0)
2015 set_zero_bit_copies++;
2016 else
2017 break;
2018 }
2019
2020 switch (code)
2021 {
2022 case SET:
25f905c2 pbrook2007-01-03 23:48:10 +00002023 /* See if we can use movw. */
2024 if (arm_arch_thumb2 && (remainder & 0xffff0000) == 0)
2025 {
2026 if (generate)
2027 emit_constant_insn (cond, gen_rtx_SET (VOIDmode, target,
2028 GEN_INT (val)));
2029 return 1;
2030 }
2031
4b6897e9 erich1994-06-23 16:02:41 +00002032 /* See if we can do this by sign_extending a constant that is known
2033 to be negative. This is a good, way of doing it, since the shift
2034 may well merge into a subsequent insn. */
2035 if (set_sign_bit_copies > 1)
2036 {
2037 if (const_ok_for_arm
9e7454d0 echristo2004-08-24 00:30:52 +00002038 (temp1 = ARM_SIGN_EXTEND (remainder
4b6897e9 erich1994-06-23 16:02:41 +00002039 << (set_sign_bit_copies - 1))))
2040 {
64266206 erich1995-12-06 11:41:39 +00002041 if (generate)
2042 {
997e4174 rearnsha1998-05-27 02:52:25 +00002043 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
96f57e36 mmitchel2004-04-01 23:30:25 +00002044 emit_constant_insn (cond,
9e7454d0 echristo2004-08-24 00:30:52 +00002045 gen_rtx_SET (VOIDmode, new_src,
96f57e36 mmitchel2004-04-01 23:30:25 +00002046 GEN_INT (temp1)));
2047 emit_constant_insn (cond,
9e7454d0 echristo2004-08-24 00:30:52 +00002048 gen_ashrsi3 (target, new_src,
96f57e36 mmitchel2004-04-01 23:30:25 +00002049 GEN_INT (set_sign_bit_copies - 1)));
64266206 erich1995-12-06 11:41:39 +00002050 }
4b6897e9 erich1994-06-23 16:02:41 +00002051 return 2;
2052 }
2053 /* For an inverted constant, we will need to set the low bits,
2054 these will be shifted out of harm's way. */
2055 temp1 |= (1 << (set_sign_bit_copies - 1)) - 1;
2056 if (const_ok_for_arm (~temp1))
2057 {
64266206 erich1995-12-06 11:41:39 +00002058 if (generate)
2059 {
997e4174 rearnsha1998-05-27 02:52:25 +00002060 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
96f57e36 mmitchel2004-04-01 23:30:25 +00002061 emit_constant_insn (cond,
2062 gen_rtx_SET (VOIDmode, new_src,
2063 GEN_INT (temp1)));
2064 emit_constant_insn (cond,
9e7454d0 echristo2004-08-24 00:30:52 +00002065 gen_ashrsi3 (target, new_src,
96f57e36 mmitchel2004-04-01 23:30:25 +00002066 GEN_INT (set_sign_bit_copies - 1)));
64266206 erich1995-12-06 11:41:39 +00002067 }
4b6897e9 erich1994-06-23 16:02:41 +00002068 return 2;
2069 }
2070 }
2071
d430cffb rearnsha2005-05-09 22:00:06 +00002072 /* See if we can calculate the value as the difference between two
2073 valid immediates. */
2074 if (clear_sign_bit_copies + clear_zero_bit_copies <= 16)
2075 {
2076 int topshift = clear_sign_bit_copies & ~1;
2077
3b85fd4d rearnsha2005-05-12 10:36:03 +00002078 temp1 = ARM_SIGN_EXTEND ((remainder + (0x00800000 >> topshift))
2079 & (0xff000000 >> topshift));
d430cffb rearnsha2005-05-09 22:00:06 +00002080
2081 /* If temp1 is zero, then that means the 9 most significant
2082 bits of remainder were 1 and we've caused it to overflow.
2083 When topshift is 0 we don't need to do anything since we
2084 can borrow from 'bit 32'. */
2085 if (temp1 == 0 && topshift != 0)
2086 temp1 = 0x80000000 >> (topshift - 1);
2087
3b85fd4d rearnsha2005-05-12 10:36:03 +00002088 temp2 = ARM_SIGN_EXTEND (temp1 - remainder);
a60f1840 nickc2005-10-10 07:57:21 +00002089
d430cffb rearnsha2005-05-09 22:00:06 +00002090 if (const_ok_for_arm (temp2))
2091 {
2092 if (generate)
2093 {
2094 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
2095 emit_constant_insn (cond,
2096 gen_rtx_SET (VOIDmode, new_src,
2097 GEN_INT (temp1)));
2098 emit_constant_insn (cond,
2099 gen_addsi3 (target, new_src,
2100 GEN_INT (-temp2)));
2101 }
2102
2103 return 2;
2104 }
2105 }
2106
4b6897e9 erich1994-06-23 16:02:41 +00002107 /* See if we can generate this by setting the bottom (or the top)
2108 16 bits, and then shifting these into the other half of the
2109 word. We only look for the simplest cases, to do more would cost
2110 too much. Be careful, however, not to generate this when the
2111 alternative would take fewer insns. */
35cea10c ghazi2001-10-22 19:36:24 +00002112 if (val & 0xffff0000)
4b6897e9 erich1994-06-23 16:02:41 +00002113 {
35cea10c ghazi2001-10-22 19:36:24 +00002114 temp1 = remainder & 0xffff0000;
4b6897e9 erich1994-06-23 16:02:41 +00002115 temp2 = remainder & 0x0000ffff;
2116
66aacf41 nickc2000-03-29 19:15:36 +00002117 /* Overlaps outside this range are best done using other methods. */
4b6897e9 erich1994-06-23 16:02:41 +00002118 for (i = 9; i < 24; i++)
2119 {
35cea10c ghazi2001-10-22 19:36:24 +00002120 if ((((temp2 | (temp2 << i)) & 0xffffffff) == remainder)
215b30b3 rearnsha2000-10-09 18:42:34 +00002121 && !const_ok_for_arm (temp2))
4b6897e9 erich1994-06-23 16:02:41 +00002122 {
997e4174 rearnsha1998-05-27 02:52:25 +00002123 rtx new_src = (subtargets
2124 ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
2125 : target);
96f57e36 mmitchel2004-04-01 23:30:25 +00002126 insns = arm_gen_constant (code, mode, cond, temp2, new_src,
64266206 erich1995-12-06 11:41:39 +00002127 source, subtargets, generate);
4b6897e9 erich1994-06-23 16:02:41 +00002128 source = new_src;
64266206 erich1995-12-06 11:41:39 +00002129 if (generate)
9e7454d0 echristo2004-08-24 00:30:52 +00002130 emit_constant_insn
96f57e36 mmitchel2004-04-01 23:30:25 +00002131 (cond,
2132 gen_rtx_SET
2133 (VOIDmode, target,
2134 gen_rtx_IOR (mode,
2135 gen_rtx_ASHIFT (mode, source,
2136 GEN_INT (i)),
2137 source)));
4b6897e9 erich1994-06-23 16:02:41 +00002138 return insns + 1;
2139 }
2140 }
2141
66aacf41 nickc2000-03-29 19:15:36 +00002142 /* Don't duplicate cases already considered. */
4b6897e9 erich1994-06-23 16:02:41 +00002143 for (i = 17; i < 24; i++)
2144 {
2145 if (((temp1 | (temp1 >> i)) == remainder)
215b30b3 rearnsha2000-10-09 18:42:34 +00002146 && !const_ok_for_arm (temp1))
4b6897e9 erich1994-06-23 16:02:41 +00002147 {
997e4174 rearnsha1998-05-27 02:52:25 +00002148 rtx new_src = (subtargets
2149 ? (generate ? gen_reg_rtx (mode) : NULL_RTX)
2150 : target);
96f57e36 mmitchel2004-04-01 23:30:25 +00002151 insns = arm_gen_constant (code, mode, cond, temp1, new_src,
64266206 erich1995-12-06 11:41:39 +00002152 source, subtargets, generate);
4b6897e9 erich1994-06-23 16:02:41 +00002153 source = new_src;
64266206 erich1995-12-06 11:41:39 +00002154 if (generate)
96f57e36 mmitchel2004-04-01 23:30:25 +00002155 emit_constant_insn
2156 (cond,
2157 gen_rtx_SET (VOIDmode, target,
76676c8e rearnsha1999-02-13 05:41:18 +00002158 gen_rtx_IOR
2159 (mode,
2160 gen_rtx_LSHIFTRT (mode, source,
2161 GEN_INT (i)),
2162 source)));
4b6897e9 erich1994-06-23 16:02:41 +00002163 return insns + 1;
2164 }
2165 }
2166 }
2167 break;
2168
2169 case IOR:
2170 case XOR:
57f96f27 erich1996-12-12 10:53:05 +00002171 /* If we have IOR or XOR, and the constant can be loaded in a
2172 single instruction, and we can find a temporary to put it in,
4b6897e9 erich1994-06-23 16:02:41 +00002173 then this can be done in two instructions instead of 3-4. */
2174 if (subtargets
997e4174 rearnsha1998-05-27 02:52:25 +00002175 /* TARGET can't be NULL if SUBTARGETS is 0 */
215b30b3 rearnsha2000-10-09 18:42:34 +00002176 || (reload_completed && !reg_mentioned_p (target, source)))
4b6897e9 erich1994-06-23 16:02:41 +00002177 {
215b30b3 rearnsha2000-10-09 18:42:34 +00002178 if (const_ok_for_arm (ARM_SIGN_EXTEND (~val)))
4b6897e9 erich1994-06-23 16:02:41 +00002179 {
64266206 erich1995-12-06 11:41:39 +00002180 if (generate)
2181 {
2182 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
4b6897e9 erich1994-06-23 16:02:41 +00002183
96f57e36 mmitchel2004-04-01 23:30:25 +00002184 emit_constant_insn (cond,
9e7454d0 echristo2004-08-24 00:30:52 +00002185 gen_rtx_SET (VOIDmode, sub,
96f57e36 mmitchel2004-04-01 23:30:25 +00002186 GEN_INT (val)));
2187 emit_constant_insn (cond,
9e7454d0 echristo2004-08-24 00:30:52 +00002188 gen_rtx_SET (VOIDmode, target,
96f57e36 mmitchel2004-04-01 23:30:25 +00002189 gen_rtx_fmt_ee (code, mode,
2190 source, sub)));
64266206 erich1995-12-06 11:41:39 +00002191 }
4b6897e9 erich1994-06-23 16:02:41 +00002192 return 2;
2193 }
2194 }
2195
2196 if (code == XOR)
2197 break;
2198
2199 if (set_sign_bit_copies > 8
2200 && (val & (-1 << (32 - set_sign_bit_copies))) == val)
2201 {
64266206 erich1995-12-06 11:41:39 +00002202 if (generate)
2203 {
2204 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
2205 rtx shift = GEN_INT (set_sign_bit_copies);
2206
9e7454d0 echristo2004-08-24 00:30:52 +00002207 emit_constant_insn
96f57e36 mmitchel2004-04-01 23:30:25 +00002208 (cond,
2209 gen_rtx_SET (VOIDmode, sub,
9e7454d0 echristo2004-08-24 00:30:52 +00002210 gen_rtx_NOT (mode,
96f57e36 mmitchel2004-04-01 23:30:25 +00002211 gen_rtx_ASHIFT (mode,
9e7454d0 echristo2004-08-24 00:30:52 +00002212 source,
96f57e36 mmitchel2004-04-01 23:30:25 +00002213 shift))));
9e7454d0 echristo2004-08-24 00:30:52 +00002214 emit_constant_insn
96f57e36 mmitchel2004-04-01 23:30:25 +00002215 (cond,
2216 gen_rtx_SET (VOIDmode, target,
2217 gen_rtx_NOT (mode,
2218 gen_rtx_LSHIFTRT (mode, sub,
2219 shift))));
64266206 erich1995-12-06 11:41:39 +00002220 }
4b6897e9 erich1994-06-23 16:02:41 +00002221 return 2;
2222 }
2223
2224 if (set_zero_bit_copies > 8
2225 && (remainder & ((1 << set_zero_bit_copies) - 1)) == remainder)
2226 {
64266206 erich1995-12-06 11:41:39 +00002227 if (generate)
2228 {
2229 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
2230 rtx shift = GEN_INT (set_zero_bit_copies);
2231
96f57e36 mmitchel2004-04-01 23:30:25 +00002232 emit_constant_insn
2233 (cond,
2234 gen_rtx_SET (VOIDmode, sub,
2235 gen_rtx_NOT (mode,
2236 gen_rtx_LSHIFTRT (mode,
2237 source,
2238 shift))));
9e7454d0 echristo2004-08-24 00:30:52 +00002239 emit_constant_insn
96f57e36 mmitchel2004-04-01 23:30:25 +00002240 (cond,
2241 gen_rtx_SET (VOIDmode, target,
2242 gen_rtx_NOT (mode,
2243 gen_rtx_ASHIFT (mode, sub,
2244 shift))));
64266206 erich1995-12-06 11:41:39 +00002245 }
4b6897e9 erich1994-06-23 16:02:41 +00002246 return 2;
2247 }
2248
215b30b3 rearnsha2000-10-09 18:42:34 +00002249 if (const_ok_for_arm (temp1 = ARM_SIGN_EXTEND (~val)))
4b6897e9 erich1994-06-23 16:02:41 +00002250 {
64266206 erich1995-12-06 11:41:39 +00002251 if (generate)
2252 {
2253 rtx sub = subtargets ? gen_reg_rtx (mode) : target;
96f57e36 mmitchel2004-04-01 23:30:25 +00002254 emit_constant_insn (cond,
2255 gen_rtx_SET (VOIDmode, sub,
2256 gen_rtx_NOT (mode, source)));
64266206 erich1995-12-06 11:41:39 +00002257 source = sub;
2258 if (subtargets)
2259 sub = gen_reg_rtx (mode);
96f57e36 mmitchel2004-04-01 23:30:25 +00002260 emit_constant_insn (cond,
2261 gen_rtx_SET (VOIDmode, sub,
9e7454d0 echristo2004-08-24 00:30:52 +00002262 gen_rtx_AND (mode, source,
96f57e36 mmitchel2004-04-01 23:30:25 +00002263 GEN_INT (temp1))));
2264 emit_constant_insn (cond,
2265 gen_rtx_SET (VOIDmode, target,
2266 gen_rtx_NOT (mode, sub)));
64266206 erich1995-12-06 11:41:39 +00002267 }
4b6897e9 erich1994-06-23 16:02:41 +00002268 return 3;
2269 }
2270 break;
2271
2272 case AND:
2273 /* See if two shifts will do 2 or more insn's worth of work. */
2274 if (clear_sign_bit_copies >= 16 && clear_sign_bit_copies < 24)
2275 {
35cea10c ghazi2001-10-22 19:36:24 +00002276 HOST_WIDE_INT shift_mask = ((0xffffffff
4b6897e9 erich1994-06-23 16:02:41 +00002277 << (32 - clear_sign_bit_copies))
35cea10c ghazi2001-10-22 19:36:24 +00002278 & 0xffffffff);
4b6897e9 erich1994-06-23 16:02:41 +00002279
35cea10c ghazi2001-10-22 19:36:24 +00002280 if ((remainder | shift_mask) != 0xffffffff)
4b6897e9 erich1994-06-23 16:02:41 +00002281 {
64266206 erich1995-12-06 11:41:39 +00002282 if (generate)
2283 {
997e4174 rearnsha1998-05-27 02:52:25 +00002284 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
9e7454d0 echristo2004-08-24 00:30:52 +00002285 insns = arm_gen_constant (AND, mode, cond,
96f57e36 mmitchel2004-04-01 23:30:25 +00002286 remainder | shift_mask,
997e4174 rearnsha1998-05-27 02:52:25 +00002287 new_src, source, subtargets, 1);
2288 source = new_src;
64266206 erich1995-12-06 11:41:39 +00002289 }
2290 else
997e4174 rearnsha1998-05-27 02:52:25 +00002291 {
2292 rtx targ = subtargets ? NULL_RTX : target;
96f57e36 mmitchel2004-04-01 23:30:25 +00002293 insns = arm_gen_constant (AND, mode, cond,
2294 remainder | shift_mask,
997e4174 rearnsha1998-05-27 02:52:25 +00002295 targ, source, subtargets, 0);
2296 }
64266206 erich1995-12-06 11:41:39 +00002297 }
2298
2299 if (generate)
2300 {
997e4174 rearnsha1998-05-27 02:52:25 +00002301 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
2302 rtx shift = GEN_INT (clear_sign_bit_copies);
2303
2304 emit_insn (gen_ashlsi3 (new_src, source, shift));
2305 emit_insn (gen_lshrsi3 (target, new_src, shift));
4b6897e9 erich1994-06-23 16:02:41 +00002306 }
2307
4b6897e9 erich1994-06-23 16:02:41 +00002308 return insns + 2;
2309 }
2310
2311 if (clear_zero_bit_copies >= 16 && clear_zero_bit_copies < 24)
2312 {
2313 HOST_WIDE_INT shift_mask = (1 << clear_zero_bit_copies) - 1;
9e7454d0 echristo2004-08-24 00:30:52 +00002314
35cea10c ghazi2001-10-22 19:36:24 +00002315 if ((remainder | shift_mask) != 0xffffffff)
4b6897e9 erich1994-06-23 16:02:41 +00002316 {
64266206 erich1995-12-06 11:41:39 +00002317 if (generate)
2318 {
997e4174 rearnsha1998-05-27 02:52:25 +00002319 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
2320
96f57e36 mmitchel2004-04-01 23:30:25 +00002321 insns = arm_gen_constant (AND, mode, cond,
2322 remainder | shift_mask,
997e4174 rearnsha1998-05-27 02:52:25 +00002323 new_src, source, subtargets, 1);
2324 source = new_src;
64266206 erich1995-12-06 11:41:39 +00002325 }
2326 else
997e4174 rearnsha1998-05-27 02:52:25 +00002327 {
2328 rtx targ = subtargets ? NULL_RTX : target;
2329
96f57e36 mmitchel2004-04-01 23:30:25 +00002330 insns = arm_gen_constant (AND, mode, cond,
2331 remainder | shift_mask,
997e4174 rearnsha1998-05-27 02:52:25 +00002332 targ, source, subtargets, 0);
2333 }
64266206 erich1995-12-06 11:41:39 +00002334 }
2335
2336 if (generate)
2337 {
997e4174 rearnsha1998-05-27 02:52:25 +00002338 rtx new_src = subtargets ? gen_reg_rtx (mode) : target;
2339 rtx shift = GEN_INT (clear_zero_bit_copies);
2340
2341 emit_insn (gen_lshrsi3 (new_src, source, shift));
2342 emit_insn (gen_ashlsi3 (target, new_src, shift));
4b6897e9 erich1994-06-23 16:02:41 +00002343 }
2344
4b6897e9 erich1994-06-23 16:02:41 +00002345 return insns + 2;
2346 }
2347
2348 break;
2349
2350 default:
2351 break;
2352 }
2353
2354 for (i = 0; i < 32; i++)
2355 if (remainder & (1 << i))
2356 num_bits_set++;
2357
2358 if (code == AND || (can_invert && num_bits_set > 16))
35cea10c ghazi2001-10-22 19:36:24 +00002359 remainder = (~remainder) & 0xffffffff;
4b6897e9 erich1994-06-23 16:02:41 +00002360 else if (code == PLUS && num_bits_set > 16)
35cea10c ghazi2001-10-22 19:36:24 +00002361 remainder = (-remainder) & 0xffffffff;
4b6897e9 erich1994-06-23 16:02:41 +00002362 else
2363 {
2364 can_invert = 0;
2365 can_negate = 0;
2366 }
2367
2368 /* Now try and find a way of doing the job in either two or three
2369 instructions.
2370 We start by looking for the largest block of zeros that are aligned on
2371 a 2-bit boundary, we then fill up the temps, wrapping around to the
2372 top of the word when we drop off the bottom.
25f905c2 pbrook2007-01-03 23:48:10 +00002373 In the worst case this code should produce no more than four insns.
2374 Thumb-2 constants are shifted, not rotated, so the MSB is always the
2375 best place to start. */
2376
2377 /* ??? Use thumb2 replicated constants when the high and low halfwords are
2378 the same. */
4b6897e9 erich1994-06-23 16:02:41 +00002379 {
2380 int best_start = 0;
25f905c2 pbrook2007-01-03 23:48:10 +00002381 if (!TARGET_THUMB2)
4b6897e9 erich1994-06-23 16:02:41 +00002382 {
25f905c2 pbrook2007-01-03 23:48:10 +00002383 int best_consecutive_zeros = 0;
4b6897e9 erich1994-06-23 16:02:41 +00002384
25f905c2 pbrook2007-01-03 23:48:10 +00002385 for (i = 0; i < 32; i += 2)
4b6897e9 erich1994-06-23 16:02:41 +00002386 {
25f905c2 pbrook2007-01-03 23:48:10 +00002387 int consecutive_zeros = 0;
2388
2389 if (!(remainder & (3 << i)))
4b6897e9 erich1994-06-23 16:02:41 +00002390 {
25f905c2 pbrook2007-01-03 23:48:10 +00002391 while ((i < 32) && !(remainder & (3 << i)))
2392 {
2393 consecutive_zeros += 2;
2394 i += 2;
2395 }
2396 if (consecutive_zeros > best_consecutive_zeros)
2397 {
2398 best_consecutive_zeros = consecutive_zeros;
2399 best_start = i - consecutive_zeros;
2400 }
2401 i -= 2;
4b6897e9 erich1994-06-23 16:02:41 +00002402 }
4b6897e9 erich1994-06-23 16:02:41 +00002403 }
cd8df93e pb2001-01-04 20:19:48 +00002404
25f905c2 pbrook2007-01-03 23:48:10 +00002405 /* So long as it won't require any more insns to do so, it's
2406 desirable to emit a small constant (in bits 0...9) in the last
2407 insn. This way there is more chance that it can be combined with
2408 a later addressing insn to form a pre-indexed load or store
2409 operation. Consider:
2410
2411 *((volatile int *)0xe0000100) = 1;
2412 *((volatile int *)0xe0000110) = 2;
2413
2414 We want this to wind up as:
2415
2416 mov rA, #0xe0000000
2417 mov rB, #1
2418 str rB, [rA, #0x100]
2419 mov rB, #2
2420 str rB, [rA, #0x110]
2421
2422 rather than having to synthesize both large constants from scratch.
2423
2424 Therefore, we calculate how many insns would be required to emit
2425 the constant starting from `best_start', and also starting from
2426 zero (i.e. with bit 31 first to be output). If `best_start' doesn't
2427 yield a shorter sequence, we may as well use zero. */
2428 if (best_start != 0
2429 && ((((unsigned HOST_WIDE_INT) 1) << best_start) < remainder)
2430 && (count_insns_for_constant (remainder, 0) <=
2431 count_insns_for_constant (remainder, best_start)))
2432 best_start = 0;
2433 }
cd8df93e pb2001-01-04 20:19:48 +00002434
2435 /* Now start emitting the insns. */
4b6897e9 erich1994-06-23 16:02:41 +00002436 i = best_start;
2437 do
2438 {
2439 int end;
2440
2441 if (i <= 0)
2442 i += 32;
2443 if (remainder & (3 << (i - 2)))
2444 {
2445 end = i - 8;
2446 if (end < 0)
2447 end += 32;
2448 temp1 = remainder & ((0x0ff << end)
2449 | ((i < end) ? (0xff >> (32 - end)) : 0));
2450 remainder &= ~temp1;
2451
997e4174 rearnsha1998-05-27 02:52:25 +00002452 if (generate)
4b6897e9 erich1994-06-23 16:02:41 +00002453 {
6382d316 rth2002-01-09 21:01:11 +00002454 rtx new_src, temp1_rtx;
2455
2456 if (code == SET || code == MINUS)
2457 {
2458 new_src = (subtargets ? gen_reg_rtx (mode) : target);
b6557085 nickc2002-01-11 16:15:36 +00002459 if (can_invert && code != MINUS)
6382d316 rth2002-01-09 21:01:11 +00002460 temp1 = ~temp1;
2461 }
2462 else
2463 {
b6557085 nickc2002-01-11 16:15:36 +00002464 if (remainder && subtargets)
6382d316 rth2002-01-09 21:01:11 +00002465 new_src = gen_reg_rtx (mode);
b6557085 nickc2002-01-11 16:15:36 +00002466 else
2467 new_src = target;
6382d316 rth2002-01-09 21:01:11 +00002468 if (can_invert)
2469 temp1 = ~temp1;
2470 else if (can_negate)
2471 temp1 = -temp1;
2472 }
2473
2474 temp1 = trunc_int_for_mode (temp1, mode);
2475 temp1_rtx = GEN_INT (temp1);
997e4174 rearnsha1998-05-27 02:52:25 +00002476
2477 if (code == SET)
6382d316 rth2002-01-09 21:01:11 +00002478 ;
997e4174 rearnsha1998-05-27 02:52:25 +00002479 else if (code == MINUS)
6382d316 rth2002-01-09 21:01:11 +00002480 temp1_rtx = gen_rtx_MINUS (mode, temp1_rtx, source);
997e4174 rearnsha1998-05-27 02:52:25 +00002481 else
6382d316 rth2002-01-09 21:01:11 +00002482 temp1_rtx = gen_rtx_fmt_ee (code, mode, source, temp1_rtx);
2483
96f57e36 mmitchel2004-04-01 23:30:25 +00002484 emit_constant_insn (cond,
9e7454d0 echristo2004-08-24 00:30:52 +00002485 gen_rtx_SET (VOIDmode, new_src,
96f57e36 mmitchel2004-04-01 23:30:25 +00002486 temp1_rtx));
997e4174 rearnsha1998-05-27 02:52:25 +00002487 source = new_src;
4b6897e9 erich1994-06-23 16:02:41 +00002488 }
2489
997e4174 rearnsha1998-05-27 02:52:25 +00002490 if (code == SET)
2491 {
2492 can_invert = 0;
2493 code = PLUS;
2494 }
2495 else if (code == MINUS)
2496 code = PLUS;
2497
4b6897e9 erich1994-06-23 16:02:41 +00002498 insns++;
25f905c2 pbrook2007-01-03 23:48:10 +00002499 if (TARGET_ARM)
2500 i -= 6;
2501 else
2502 i -= 7;
4b6897e9 erich1994-06-23 16:02:41 +00002503 }
542d5028 kazu2007-01-08 01:17:57 +00002504 /* Arm allows rotates by a multiple of two. Thumb-2 allows arbitrary
25f905c2 pbrook2007-01-03 23:48:10 +00002505 shifts. */
2506 if (TARGET_ARM)
2507 i -= 2;
2508 else
2509 i--;
a12be13c nickc2002-01-16 12:25:53 +00002510 }
2511 while (remainder);
4b6897e9 erich1994-06-23 16:02:41 +00002512 }
a12be13c nickc2002-01-16 12:25:53 +00002513
4b6897e9 erich1994-06-23 16:02:41 +00002514 return insns;
2515}
2516
9480e6c7 erich1996-05-04 16:13:28 +00002517/* Canonicalize a comparison so that we are more likely to recognize it.
2518 This can be done for a few constant compares, where we can make the
2519 immediate value easier to load. */
a12be13c nickc2002-01-16 12:25:53 +00002520
9480e6c7 erich1996-05-04 16:13:28 +00002521enum rtx_code
aa3c2d40 pbrook2005-07-30 00:11:27 +00002522arm_canonicalize_comparison (enum rtx_code code, enum machine_mode mode,
2523 rtx * op1)
9480e6c7 erich1996-05-04 16:13:28 +00002524{
ecd3fcc7 rearnsha1998-05-26 09:30:56 +00002525 unsigned HOST_WIDE_INT i = INTVAL (*op1);
aa3c2d40 pbrook2005-07-30 00:11:27 +00002526 unsigned HOST_WIDE_INT maxval;
2527 maxval = (((unsigned HOST_WIDE_INT) 1) << (GET_MODE_BITSIZE(mode) - 1)) - 1;
9480e6c7 erich1996-05-04 16:13:28 +00002528
2529 switch (code)
2530 {
2531 case EQ:
2532 case NE:
2533 return code;
2534
2535 case GT:
2536 case LE:
aa3c2d40 pbrook2005-07-30 00:11:27 +00002537 if (i != maxval
215b30b3 rearnsha2000-10-09 18:42:34 +00002538 && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
9480e6c7 erich1996-05-04 16:13:28 +00002539 {
215b30b3 rearnsha2000-10-09 18:42:34 +00002540 *op1 = GEN_INT (i + 1);
9480e6c7 erich1996-05-04 16:13:28 +00002541 return code == GT ? GE : LT;
2542 }
2543 break;
2544
2545 case GE:
2546 case LT:
aa3c2d40 pbrook2005-07-30 00:11:27 +00002547 if (i != ~maxval
215b30b3 rearnsha2000-10-09 18:42:34 +00002548 && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
9480e6c7 erich1996-05-04 16:13:28 +00002549 {
215b30b3 rearnsha2000-10-09 18:42:34 +00002550 *op1 = GEN_INT (i - 1);
9480e6c7 erich1996-05-04 16:13:28 +00002551 return code == GE ? GT : LE;
2552 }
2553 break;
2554
2555 case GTU:
2556 case LEU:
35cea10c ghazi2001-10-22 19:36:24 +00002557 if (i != ~((unsigned HOST_WIDE_INT) 0)
215b30b3 rearnsha2000-10-09 18:42:34 +00002558 && (const_ok_for_arm (i + 1) || const_ok_for_arm (-(i + 1))))
9480e6c7 erich1996-05-04 16:13:28 +00002559 {
2560 *op1 = GEN_INT (i + 1);
2561 return code == GTU ? GEU : LTU;
2562 }
2563 break;
2564
2565 case GEU:
2566 case LTU:
2567 if (i != 0
215b30b3 rearnsha2000-10-09 18:42:34 +00002568 && (const_ok_for_arm (i - 1) || const_ok_for_arm (-(i - 1))))
9480e6c7 erich1996-05-04 16:13:28 +00002569 {
2570 *op1 = GEN_INT (i - 1);
2571 return code == GEU ? GTU : LEU;
2572 }
2573 break;
2574
2575 default:
ed29c566 nathan2005-04-27 16:09:03 +00002576 gcc_unreachable ();
9480e6c7 erich1996-05-04 16:13:28 +00002577 }
2578
2579 return code;
2580}
9480e6c7 erich1996-05-04 16:13:28 +00002581
19347327 pbrook2004-04-08 18:26:09 +00002582
2583/* Define how to find the value returned by a function. */
2584
ccd90aaa rearnsha2005-02-16 21:57:10 +00002585rtx
2586arm_function_value(tree type, tree func ATTRIBUTE_UNUSED)
19347327 pbrook2004-04-08 18:26:09 +00002587{
2588 enum machine_mode mode;
2589 int unsignedp ATTRIBUTE_UNUSED;
2590 rtx r ATTRIBUTE_UNUSED;
2591
19347327 pbrook2004-04-08 18:26:09 +00002592 mode = TYPE_MODE (type);
2593 /* Promote integer types. */
2594 if (INTEGRAL_TYPE_P (type))
2595 PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
46b5d878 jules2005-04-26 16:30:37 +00002596
2597 /* Promotes small structs returned in a register to full-word size
2598 for big-endian AAPCS. */
2599 if (arm_return_in_msb (type))
2600 {
2601 HOST_WIDE_INT size = int_size_in_bytes (type);
2602 if (size % UNITS_PER_WORD != 0)
2603 {
2604 size += UNITS_PER_WORD - size % UNITS_PER_WORD;
2605 mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
2606 }
2607 }
a60f1840 nickc2005-10-10 07:57:21 +00002608
19347327 pbrook2004-04-08 18:26:09 +00002609 return LIBCALL_VALUE(mode);
2610}
2611
a60f1840 nickc2005-10-10 07:57:21 +00002612/* Determine the amount of memory needed to store the possible return
ccd90aaa rearnsha2005-02-16 21:57:10 +00002613 registers of an untyped call. */
2614int
2615arm_apply_result_size (void)
2616{
2617 int size = 16;
2618
2619 if (TARGET_ARM)
2620 {
2621 if (TARGET_HARD_FLOAT_ABI)
2622 {
2623 if (TARGET_FPA)
2624 size += 12;
2625 if (TARGET_MAVERICK)
2626 size += 8;
2627 }
2628 if (TARGET_IWMMXT_ABI)
2629 size += 8;
2630 }
2631
2632 return size;
2633}
19347327 pbrook2004-04-08 18:26:09 +00002634
9888ad6d nickc1999-02-22 16:47:59 +00002635/* Decide whether a type should be returned in memory (true)
2636 or in a register (false). This is called by the macro
2637 RETURN_IN_MEMORY. */
64266206 erich1995-12-06 11:41:39 +00002638int
ebd88a36 rearnsha2003-06-10 18:55:17 +00002639arm_return_in_memory (tree type)
64266206 erich1995-12-06 11:41:39 +00002640{
1e00c159 thorpej2002-09-05 17:11:47 +00002641 HOST_WIDE_INT size;
2642
1a3ba46f pbrook2005-01-05 18:53:08 +00002643 if (!AGGREGATE_TYPE_P (type) &&
b3582e6a jules2005-05-13 16:44:16 +00002644 (TREE_CODE (type) != VECTOR_TYPE) &&
1a3ba46f pbrook2005-01-05 18:53:08 +00002645 !(TARGET_AAPCS_BASED && TREE_CODE (type) == COMPLEX_TYPE))
2646 /* All simple types are returned in registers.
2647 For AAPCS, complex types are treated the same as aggregates. */
29a6fe51 nickc2000-03-15 22:06:16 +00002648 return 0;
1e00c159 thorpej2002-09-05 17:11:47 +00002649
2650 size = int_size_in_bytes (type);
2651
f9273c43 pbrook2004-03-24 17:20:16 +00002652 if (arm_abi != ARM_ABI_APCS)
1e00c159 thorpej2002-09-05 17:11:47 +00002653 {
f9273c43 pbrook2004-03-24 17:20:16 +00002654 /* ATPCS and later return aggregate types in memory only if they are
1e00c159 thorpej2002-09-05 17:11:47 +00002655 larger than a word (or are variable size). */
2656 return (size < 0 || size > UNITS_PER_WORD);
2657 }
9e7454d0 echristo2004-08-24 00:30:52 +00002658
b3582e6a jules2005-05-13 16:44:16 +00002659 /* To maximize backwards compatibility with previous versions of gcc,
2660 return vectors up to 4 words in registers. */
2661 if (TREE_CODE (type) == VECTOR_TYPE)
2662 return (size < 0 || size > (4 * UNITS_PER_WORD));
2663
b89db9a7 kazu2003-01-31 02:20:48 +00002664 /* For the arm-wince targets we choose to be compatible with Microsoft's
cffb2a26 rearnsha2000-04-08 14:29:53 +00002665 ARM and Thumb compilers, which always return aggregates in memory. */
2666#ifndef ARM_WINCE
b7e2e8e6 nickc2001-11-05 17:00:45 +00002667 /* All structures/unions bigger than one word are returned in memory.
2668 Also catch the case where int_size_in_bytes returns -1. In this case
b89db9a7 kazu2003-01-31 02:20:48 +00002669 the aggregate is either huge or of variable size, and in either case
b7e2e8e6 nickc2001-11-05 17:00:45 +00002670 we will want to return it via memory and not in a register. */
1e00c159 thorpej2002-09-05 17:11:47 +00002671 if (size < 0 || size > UNITS_PER_WORD)
29a6fe51 nickc2000-03-15 22:06:16 +00002672 return 1;
9e7454d0 echristo2004-08-24 00:30:52 +00002673
29a6fe51 nickc2000-03-15 22:06:16 +00002674 if (TREE_CODE (type) == RECORD_TYPE)
64266206 erich1995-12-06 11:41:39 +00002675 {
2676 tree field;
2677
3accc59a nickc1999-10-19 14:27:00 +00002678 /* For a struct the APCS says that we only return in a register
2679 if the type is 'integer like' and every addressable element
2680 has an offset of zero. For practical purposes this means
2681 that the structure can have at most one non bit-field element
2682 and that this element must be the first one in the structure. */
9e7454d0 echristo2004-08-24 00:30:52 +00002683
9888ad6d nickc1999-02-22 16:47:59 +00002684 /* Find the first field, ignoring non FIELD_DECL things which will
2685 have been created by C++. */
2686 for (field = TYPE_FIELDS (type);
2687 field && TREE_CODE (field) != FIELD_DECL;
2688 field = TREE_CHAIN (field))
2689 continue;
9e7454d0 echristo2004-08-24 00:30:52 +00002690
9888ad6d nickc1999-02-22 16:47:59 +00002691 if (field == NULL)
f5daaea4 nickc2000-03-19 21:57:35 +00002692 return 0; /* An empty structure. Allowed by an extension to ANSI C. */
9888ad6d nickc1999-02-22 16:47:59 +00002693
cffb2a26 rearnsha2000-04-08 14:29:53 +00002694 /* Check that the first field is valid for returning in a register. */
2695
2696 /* ... Floats are not allowed */
f5daaea4 nickc2000-03-19 21:57:35 +00002697 if (FLOAT_TYPE_P (TREE_TYPE (field)))
3accc59a nickc1999-10-19 14:27:00 +00002698 return 1;
2699
cffb2a26 rearnsha2000-04-08 14:29:53 +00002700 /* ... Aggregates that are not themselves valid for returning in
2701 a register are not allowed. */
f5daaea4 nickc2000-03-19 21:57:35 +00002702 if (RETURN_IN_MEMORY (TREE_TYPE (field)))
3accc59a nickc1999-10-19 14:27:00 +00002703 return 1;
89b30d75 nickc2000-12-22 18:22:03 +00002704
3accc59a nickc1999-10-19 14:27:00 +00002705 /* Now check the remaining fields, if any. Only bitfields are allowed,
2706 since they are not addressable. */
9888ad6d nickc1999-02-22 16:47:59 +00002707 for (field = TREE_CHAIN (field);
2708 field;
2709 field = TREE_CHAIN (field))
2710 {
2711 if (TREE_CODE (field) != FIELD_DECL)
2712 continue;
9e7454d0 echristo2004-08-24 00:30:52 +00002713
215b30b3 rearnsha2000-10-09 18:42:34 +00002714 if (!DECL_BIT_FIELD_TYPE (field))
9888ad6d nickc1999-02-22 16:47:59 +00002715 return 1;
2716 }
64266206 erich1995-12-06 11:41:39 +00002717
2718 return 0;
2719 }
9e7454d0 echristo2004-08-24 00:30:52 +00002720
29a6fe51 nickc2000-03-15 22:06:16 +00002721 if (TREE_CODE (type) == UNION_TYPE)
64266206 erich1995-12-06 11:41:39 +00002722 {
2723 tree field;
2724
2725 /* Unions can be returned in registers if every element is
2726 integral, or can be returned in an integer register. */
9888ad6d nickc1999-02-22 16:47:59 +00002727 for (field = TYPE_FIELDS (type);
2728 field;
2729 field = TREE_CHAIN (field))
64266206 erich1995-12-06 11:41:39 +00002730 {
9888ad6d nickc1999-02-22 16:47:59 +00002731 if (TREE_CODE (field) != FIELD_DECL)
2732 continue;
2733
7bd8ccc9 nickc1999-02-25 10:20:21 +00002734 if (FLOAT_TYPE_P (TREE_TYPE (field)))
2735 return 1;
9e7454d0 echristo2004-08-24 00:30:52 +00002736
9888ad6d nickc1999-02-22 16:47:59 +00002737 if (RETURN_IN_MEMORY (TREE_TYPE (field)))
64266206 erich1995-12-06 11:41:39 +00002738 return 1;
2739 }
9e7454d0 echristo2004-08-24 00:30:52 +00002740
64266206 erich1995-12-06 11:41:39 +00002741 return 0;
2742 }
9e7454d0 echristo2004-08-24 00:30:52 +00002743#endif /* not ARM_WINCE */
2744
cffb2a26 rearnsha2000-04-08 14:29:53 +00002745 /* Return all other types in memory. */
64266206 erich1995-12-06 11:41:39 +00002746 return 1;
2747}
2748
674a8f0b kazu2003-12-25 15:17:37 +00002749/* Indicate whether or not words of a double are in big-endian order. */
3d94d3fa thorpej2002-09-05 16:45:24 +00002750
2751int
ebd88a36 rearnsha2003-06-10 18:55:17 +00002752arm_float_words_big_endian (void)
3d94d3fa thorpej2002-09-05 16:45:24 +00002753{
a2cd141b pbrook2004-02-03 14:45:44 +00002754 if (TARGET_MAVERICK)
7d57ec45 nickc2003-02-10 11:45:26 +00002755 return 0;
3d94d3fa thorpej2002-09-05 16:45:24 +00002756
2757 /* For FPA, float words are always big-endian. For VFP, floats words
2758 follow the memory system mode. */
2759
a2cd141b pbrook2004-02-03 14:45:44 +00002760 if (TARGET_FPA)
3d94d3fa thorpej2002-09-05 16:45:24 +00002761 {
3d94d3fa thorpej2002-09-05 16:45:24 +00002762 return 1;
2763 }
2764
2765 if (TARGET_VFP)
2766 return (TARGET_BIG_END ? 1 : 0);
2767
2768 return 1;
2769}
2770
a52eca60 nickc2000-02-09 20:00:29 +00002771/* Initialize a variable CUM of type CUMULATIVE_ARGS
2772 for a call to a function whose data type is FNTYPE.
2773 For a library call, FNTYPE is NULL. */
2774void
9e7454d0 echristo2004-08-24 00:30:52 +00002775arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
ebd88a36 rearnsha2003-06-10 18:55:17 +00002776 rtx libname ATTRIBUTE_UNUSED,
2777 tree fndecl ATTRIBUTE_UNUSED)
a52eca60 nickc2000-02-09 20:00:29 +00002778{
2779 /* On the ARM, the offset starts at 0. */
f2be8f2b rearnsha2006-05-10 21:54:06 +00002780 pcum->nregs = 0;
755eb2b4 nickc2003-06-18 16:36:13 +00002781 pcum->iwmmxt_nregs = 0;
f9273c43 pbrook2004-03-24 17:20:16 +00002782 pcum->can_split = true;
9e7454d0 echristo2004-08-24 00:30:52 +00002783
a52eca60 nickc2000-02-09 20:00:29 +00002784 pcum->call_cookie = CALL_NORMAL;
2785
2786 if (TARGET_LONG_CALLS)
2787 pcum->call_cookie = CALL_LONG;
9e7454d0 echristo2004-08-24 00:30:52 +00002788
a52eca60 nickc2000-02-09 20:00:29 +00002789 /* Check for long call/short call attributes. The attributes
2790 override any command line option. */
2791 if (fntype)
2792 {
2793 if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (fntype)))
2794 pcum->call_cookie = CALL_SHORT;
2795 else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (fntype)))
2796 pcum->call_cookie = CALL_LONG;
2797 }
755eb2b4 nickc2003-06-18 16:36:13 +00002798
2799 /* Varargs vectors are treated the same as long long.
2800 named_count avoids having to change the way arm handles 'named' */
2801 pcum->named_count = 0;
2802 pcum->nargs = 0;
2803
2804 if (TARGET_REALLY_IWMMXT && fntype)
2805 {
2806 tree fn_arg;
2807
2808 for (fn_arg = TYPE_ARG_TYPES (fntype);
2809 fn_arg;
2810 fn_arg = TREE_CHAIN (fn_arg))
2811 pcum->named_count += 1;
2812
2813 if (! pcum->named_count)
2814 pcum->named_count = INT_MAX;
2815 }
a52eca60 nickc2000-02-09 20:00:29 +00002816}
2817
f9273c43 pbrook2004-03-24 17:20:16 +00002818
2819/* Return true if mode/type need doubleword alignment. */
2820bool
2821arm_needs_doubleword_align (enum machine_mode mode, tree type)
2822{
9c291064 pbrook2004-04-30 10:54:37 +00002823 return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY
2824 || (type && TYPE_ALIGN (type) > PARM_BOUNDARY));
f9273c43 pbrook2004-03-24 17:20:16 +00002825}
2826
2827
a52eca60 nickc2000-02-09 20:00:29 +00002828/* Determine where to put an argument to a function.
2829 Value is zero to push the argument on the stack,
2830 or a hard register in which to store the argument.
2831
2832 MODE is the argument's machine mode.
2833 TYPE is the data type of the argument (as a tree).
2834 This is null for libcalls where that information may