/* Definitions of target machine for GNU compiler, for ARM.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
#define TARGET_CPU_CPP_BUILTINS() \
do \
{ \
+ if (TARGET_DSP_MULTIPLY) \
+ builtin_define ("__ARM_FEATURE_DSP"); \
/* Define __arm__ even when in thumb mode, for \
consistency with armcc. */ \
builtin_define ("__arm__"); \
if (arm_arch_iwmmxt) \
builtin_define ("__IWMMXT__"); \
if (TARGET_AAPCS_BASED) \
- builtin_define ("__ARM_EABI__"); \
+ { \
+ if (arm_pcs_default == ARM_PCS_AAPCS_VFP) \
+ builtin_define ("__ARM_PCS_VFP"); \
+ else if (arm_pcs_default == ARM_PCS_AAPCS) \
+ builtin_define ("__ARM_PCS"); \
+ builtin_define ("__ARM_EABI__"); \
+ } \
+ if (TARGET_IDIV) \
+ builtin_define ("__ARM_ARCH_EXT_IDIV__"); \
} while (0)
-/* The various ARM cores. */
-enum processor_type
-{
-#define ARM_CORE(NAME, IDENT, ARCH, FLAGS, COSTS) \
- IDENT,
-#include "arm-cores.def"
-#undef ARM_CORE
- /* Used to indicate that no processor has been specified. */
- arm_none
-};
+#include "config/arm/arm-opts.h"
enum target_cpus
{
/* The processor for which instructions should be scheduled. */
extern enum processor_type arm_tune;
+enum arm_sync_generator_tag
+ {
+ arm_sync_generator_omn,
+ arm_sync_generator_omrn
+ };
+
+/* Wrapper to pass around a polymorphic pointer to a sync instruction
+ generator and. */
+struct arm_sync_generator
+{
+ enum arm_sync_generator_tag op;
+ union
+ {
+ rtx (* omn) (rtx, rtx, rtx);
+ rtx (* omrn) (rtx, rtx, rtx, rtx);
+ } u;
+};
+
typedef enum arm_cond_code
{
ARM_EQ = 0, ARM_NE, ARM_CS, ARM_CC, ARM_MI, ARM_PL, ARM_VS, ARM_VC,
#undef CPP_SPEC
#define CPP_SPEC "%(subtarget_cpp_spec) \
-%{msoft-float:%{mhard-float: \
- %e-msoft-float and -mhard_float may not be used together}} \
+%{mfloat-abi=soft:%{mfloat-abi=hard: \
+ %e-mfloat-abi=soft and -mfloat-abi=hard may not be used together}} \
%{mbig-endian:%{mlittle-endian: \
%e-mbig-endian and -mlittle-endian may not be used together}}"
Do not define this macro if it does not need to do anything. */
#define EXTRA_SPECS \
{ "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \
+ { "asm_cpu_spec", ASM_CPU_SPEC }, \
SUBTARGET_EXTRA_SPECS
#ifndef SUBTARGET_EXTRA_SPECS
#endif
\f
/* Run-time Target Specification. */
-#ifndef TARGET_VERSION
-#define TARGET_VERSION fputs (" (ARM/generic)", stderr);
-#endif
-
#define TARGET_SOFT_FLOAT (arm_float_abi == ARM_FLOAT_ABI_SOFT)
/* Use hardware floating point instructions. */
#define TARGET_HARD_FLOAT (arm_float_abi != ARM_FLOAT_ABI_SOFT)
#define TARGET_HARD_TP (target_thread_pointer == TP_CP15)
#define TARGET_SOFT_TP (target_thread_pointer == TP_SOFT)
+#define TARGET_GNU2_TLS (target_tls_dialect == TLS_GNU2)
/* Only 16-bit thumb code. */
#define TARGET_THUMB1 (TARGET_THUMB && !arm_arch_thumb2)
(TARGET_32BIT && arm_arch6 && (arm_arch_notm || arm_arch7em))
/* Should MOVW/MOVT be used in preference to a constant pool. */
-#define TARGET_USE_MOVT (arm_arch_thumb2 && !optimize_size)
+#define TARGET_USE_MOVT \
+ (arm_arch_thumb2 && !optimize_size && !current_tune->prefer_constant_pool)
/* We could use unified syntax for arm mode, but for now we just use it
for Thumb-2. */
#define TARGET_UNIFIED_ASM TARGET_THUMB2
+/* Nonzero if this chip provides the DMB instruction. */
+#define TARGET_HAVE_DMB (arm_arch7)
+
+/* Nonzero if this chip implements a memory barrier via CP15. */
+#define TARGET_HAVE_DMB_MCR (arm_arch6k && ! TARGET_HAVE_DMB)
+
+/* Nonzero if this chip implements a memory barrier instruction. */
+#define TARGET_HAVE_MEMORY_BARRIER (TARGET_HAVE_DMB || TARGET_HAVE_DMB_MCR)
+
+/* Nonzero if this chip supports ldrex and strex */
+#define TARGET_HAVE_LDREX ((arm_arch6 && TARGET_ARM) || arm_arch7)
+
+/* Nonzero if this chip supports ldrex{bhd} and strex{bhd}. */
+#define TARGET_HAVE_LDREXBHD ((arm_arch6k && TARGET_ARM) || arm_arch7)
+
+/* Nonzero if integer division instructions supported. */
+#define TARGET_IDIV ((TARGET_ARM && arm_arch_arm_hwdiv) \
+ || (TARGET_THUMB2 && arm_arch_thumb_hwdiv))
/* True iff the full BPABI is being used. If TARGET_BPABI is true,
then TARGET_AAPCS_BASED must be true -- but the converse does not
by --with-arch.
--with-tune is ignored if -mtune or -mcpu are specified (but not affected
by -march).
- --with-float is ignored if -mhard-float, -msoft-float or -mfloat-abi are
- specified.
+ --with-float is ignored if -mfloat-abi is specified.
--with-fpu is ignored if -mfpu is specified.
- --with-abi is ignored is -mabi is specified. */
+ --with-abi is ignored if -mabi is specified.
+ --with-tls is ignored if -mtls-dialect is specified. */
#define OPTION_DEFAULT_SPECS \
{"arch", "%{!march=*:%{!mcpu=*:-march=%(VALUE)}}" }, \
{"cpu", "%{!march=*:%{!mcpu=*:-mcpu=%(VALUE)}}" }, \
{"tune", "%{!mcpu=*:%{!mtune=*:-mtune=%(VALUE)}}" }, \
- {"float", \
- "%{!msoft-float:%{!mhard-float:%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}}}" }, \
+ {"float", "%{!mfloat-abi=*:-mfloat-abi=%(VALUE)}" }, \
{"fpu", "%{!mfpu=*:-mfpu=%(VALUE)}"}, \
{"abi", "%{!mabi=*:-mabi=%(VALUE)}"}, \
- {"mode", "%{!marm:%{!mthumb:-m%(VALUE)}}"},
+ {"mode", "%{!marm:%{!mthumb:-m%(VALUE)}}"}, \
+ {"tls", "%{!mtls-dialect=*:-mtls-dialect=%(VALUE)}"},
/* Which floating point model to use. */
enum arm_fp_model
/* Which floating point hardware to schedule for. */
extern int arm_fpu_attr;
-enum float_abi_type
-{
- ARM_FLOAT_ABI_SOFT,
- ARM_FLOAT_ABI_SOFTFP,
- ARM_FLOAT_ABI_HARD
-};
-
-extern enum float_abi_type arm_float_abi;
-
#ifndef TARGET_DEFAULT_FLOAT_ABI
#define TARGET_DEFAULT_FLOAT_ABI ARM_FLOAT_ABI_SOFT
#endif
-/* Which __fp16 format to use.
- The enumeration values correspond to the numbering for the
- Tag_ABI_FP_16bit_format attribute.
- */
-enum arm_fp16_format_type
-{
- ARM_FP16_FORMAT_NONE = 0,
- ARM_FP16_FORMAT_IEEE = 1,
- ARM_FP16_FORMAT_ALTERNATIVE = 2
-};
-
-extern enum arm_fp16_format_type arm_fp16_format;
#define LARGEST_EXPONENT_IS_NORMAL(bits) \
((bits) == 16 && arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
-/* Which ABI to use. */
-enum arm_abi_type
-{
- ARM_ABI_APCS,
- ARM_ABI_ATPCS,
- ARM_ABI_AAPCS,
- ARM_ABI_IWMMXT,
- ARM_ABI_AAPCS_LINUX
-};
-
-extern enum arm_abi_type arm_abi;
-
#ifndef ARM_DEFAULT_ABI
#define ARM_DEFAULT_ABI ARM_ABI_APCS
#endif
-/* Which thread pointer access sequence to use. */
-enum arm_tp_type {
- TP_AUTO,
- TP_SOFT,
- TP_CP15
-};
-
-extern enum arm_tp_type target_thread_pointer;
-
/* Nonzero if this chip supports the ARM Architecture 3M extensions. */
extern int arm_arch3m;
/* Nonzero if this chip supports the ARM Architecture 6 extensions. */
extern int arm_arch6;
+/* Nonzero if this chip supports the ARM Architecture 6k extensions. */
+extern int arm_arch6k;
+
+/* Nonzero if this chip supports the ARM Architecture 7 extensions. */
+extern int arm_arch7;
+
/* Nonzero if instructions not present in the 'M' profile can be used. */
extern int arm_arch_notm;
/* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched;
-/* Nonzero if generating thumb code. */
+/* Nonzero if generating Thumb code, either Thumb-1 or Thumb-2. */
extern int thumb_code;
+/* Nonzero if generating Thumb-1 code. */
+extern int thumb1_code;
+
/* Nonzero if this chip is a StrongARM. */
extern int arm_tune_strongarm;
/* Nonzero if chip supports Thumb 2. */
extern int arm_arch_thumb2;
-/* Nonzero if chip supports integer division instruction. */
-extern int arm_arch_hwdiv;
+/* Nonzero if chip supports integer division instruction in ARM mode. */
+extern int arm_arch_arm_hwdiv;
+
+/* Nonzero if chip supports integer division instruction in Thumb mode. */
+extern int arm_arch_thumb_hwdiv;
#ifndef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_APCS_FRAME)
#endif
-/* The frame pointer register used in gcc has nothing to do with debugging;
- that is controlled by the APCS-FRAME option. */
-#define CAN_DEBUG_WITHOUT_FP
-
-#define OVERRIDE_OPTIONS arm_override_options ()
-
-#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \
- arm_optimization_options ((LEVEL), (SIZE))
-
/* Nonzero if PIC code requires explicit qualifiers to generate
PLT and GOT relocs rather than the assembler doing so implicitly.
Subtargets can override these if required. */
This is always false, even when in big-endian mode. */
#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN && ! TARGET_LITTLE_WORDS)
-/* LIBGCC2_WORDS_BIG_ENDIAN has to be a constant, so we define this based
- on processor pre-defineds when compiling libgcc2.c. */
-#if defined(__ARMEB__) && !defined(__ARMWEL__)
-#define LIBGCC2_WORDS_BIG_ENDIAN 1
-#else
-#define LIBGCC2_WORDS_BIG_ENDIAN 0
-#endif
-
/* Define this if most significant word of doubles is the lowest numbered.
The rules are different based on whether or not we use FPA-format,
VFP-format or some other floating point co-processor's format doubles. */
#define UNITS_PER_WORD 4
-/* Use the option -mvectorize-with-neon-quad to override the use of doubleword
- registers when autovectorizing for Neon, at least until multiple vector
- widths are supported properly by the middle-end. */
-#define UNITS_PER_SIMD_WORD(MODE) \
- (TARGET_NEON ? (TARGET_NEON_VECTORIZE_QUAD ? 16 : 8) : UNITS_PER_WORD)
-
/* True if natural alignment is used for doubleword types. */
#define ARM_DOUBLEWORD_ALIGN TARGET_AAPCS_BASED
/* Align definitions of arrays, unions and structures so that
initializations and copies can be made more efficient. This is not
ABI-changing, so it only affects places where we can see the
- definition. */
-#define DATA_ALIGNMENT(EXP, ALIGN) \
- ((((ALIGN) < BITS_PER_WORD) \
+ definition. Increasing the alignment tends to introduce padding,
+ so don't do this when optimizing for size/conserving stack space. */
+#define ARM_EXPAND_ALIGNMENT(COND, EXP, ALIGN) \
+ (((COND) && ((ALIGN) < BITS_PER_WORD) \
&& (TREE_CODE (EXP) == ARRAY_TYPE \
|| TREE_CODE (EXP) == UNION_TYPE \
|| TREE_CODE (EXP) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
+/* Align global data. */
+#define DATA_ALIGNMENT(EXP, ALIGN) \
+ ARM_EXPAND_ALIGNMENT(!optimize_size, EXP, ALIGN)
+
/* Similarly, make sure that objects on the stack are sensibly aligned. */
-#define LOCAL_ALIGNMENT(EXP, ALIGN) DATA_ALIGNMENT(EXP, ALIGN)
+#define LOCAL_ALIGNMENT(EXP, ALIGN) \
+ ARM_EXPAND_ALIGNMENT(!flag_conserve_stack, EXP, ALIGN)
/* Setting STRUCTURE_SIZE_BOUNDARY to 32 produces more efficient code, but the
value set in previous versions of this toolchain was 8, which produces more
0020D) page 2-20 says "Structures are aligned on word boundaries".
The AAPCS specifies a value of 8. */
#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
-extern int arm_structure_size_boundary;
/* This is the value used to initialize arm_structure_size_boundary. If a
particular arm target wants to change the default value it should change
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#endif
+/* Sized for fixed-point types. */
+
+#define SHORT_FRACT_TYPE_SIZE 8
+#define FRACT_TYPE_SIZE 16
+#define LONG_FRACT_TYPE_SIZE 32
+#define LONG_LONG_FRACT_TYPE_SIZE 64
+
+#define SHORT_ACCUM_TYPE_SIZE 16
+#define ACCUM_TYPE_SIZE 32
+#define LONG_ACCUM_TYPE_SIZE 64
+#define LONG_LONG_ACCUM_TYPE_SIZE 64
+
+#define MAX_FIXED_MODE_SIZE 64
+
#ifndef SIZE_TYPE
#define SIZE_TYPE (TARGET_AAPCS_BASED ? "unsigned int" : "long unsigned int")
#endif
elimination code won't get rid of sfp. It tracks
fp exactly at all times.
- *: See CONDITIONAL_REGISTER_USAGE */
+ *: See TARGET_CONDITIONAL_REGISTER_USAGE */
/*
mvf0 Cirrus floating point result
#define SUBTARGET_CONDITIONAL_REGISTER_USAGE
#endif
-#define CONDITIONAL_REGISTER_USAGE \
-{ \
- int regno; \
- \
- if (TARGET_SOFT_FLOAT || TARGET_THUMB1 || !TARGET_FPA) \
- { \
- for (regno = FIRST_FPA_REGNUM; \
- regno <= LAST_FPA_REGNUM; ++regno) \
- fixed_regs[regno] = call_used_regs[regno] = 1; \
- } \
- \
- if (TARGET_THUMB1 && optimize_size) \
- { \
- /* When optimizing for size on Thumb-1, it's better not \
- to use the HI regs, because of the overhead of \
- stacking them. */ \
- for (regno = FIRST_HI_REGNUM; \
- regno <= LAST_HI_REGNUM; ++regno) \
- fixed_regs[regno] = call_used_regs[regno] = 1; \
- } \
- \
- /* The link register can be clobbered by any branch insn, \
- but we have no way to track that at present, so mark \
- it as unavailable. */ \
- if (TARGET_THUMB1) \
- fixed_regs[LR_REGNUM] = call_used_regs[LR_REGNUM] = 1; \
- \
- if (TARGET_32BIT && TARGET_HARD_FLOAT) \
- { \
- if (TARGET_MAVERICK) \
- { \
- for (regno = FIRST_FPA_REGNUM; \
- regno <= LAST_FPA_REGNUM; ++ regno) \
- fixed_regs[regno] = call_used_regs[regno] = 1; \
- for (regno = FIRST_CIRRUS_FP_REGNUM; \
- regno <= LAST_CIRRUS_FP_REGNUM; ++ regno) \
- { \
- fixed_regs[regno] = 0; \
- call_used_regs[regno] = regno < FIRST_CIRRUS_FP_REGNUM + 4; \
- } \
- } \
- if (TARGET_VFP) \
- { \
- /* VFPv3 registers are disabled when earlier VFP \
- versions are selected due to the definition of \
- LAST_VFP_REGNUM. */ \
- for (regno = FIRST_VFP_REGNUM; \
- regno <= LAST_VFP_REGNUM; ++ regno) \
- { \
- fixed_regs[regno] = 0; \
- call_used_regs[regno] = regno < FIRST_VFP_REGNUM + 16 \
- || regno >= FIRST_VFP_REGNUM + 32; \
- } \
- } \
- } \
- \
- if (TARGET_REALLY_IWMMXT) \
- { \
- regno = FIRST_IWMMXT_GR_REGNUM; \
- /* The 2002/10/09 revision of the XScale ABI has wCG0 \
- and wCG1 as call-preserved registers. The 2002/11/21 \
- revision changed this so that all wCG registers are \
- scratch registers. */ \
- for (regno = FIRST_IWMMXT_GR_REGNUM; \
- regno <= LAST_IWMMXT_GR_REGNUM; ++ regno) \
- fixed_regs[regno] = 0; \
- /* The XScale ABI has wR0 - wR9 as scratch registers, \
- the rest as call-preserved registers. */ \
- for (regno = FIRST_IWMMXT_REGNUM; \
- regno <= LAST_IWMMXT_REGNUM; ++ regno) \
- { \
- fixed_regs[regno] = 0; \
- call_used_regs[regno] = regno < FIRST_IWMMXT_REGNUM + 10; \
- } \
- } \
- \
- if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \
- { \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- } \
- else if (TARGET_APCS_STACK) \
- { \
- fixed_regs[10] = 1; \
- call_used_regs[10] = 1; \
- } \
- /* -mcaller-super-interworking reserves r11 for calls to \
- _interwork_r11_call_via_rN(). Making the register global \
- is an easy way of ensuring that it remains valid for all \
- calls. */ \
- if (TARGET_APCS_FRAME || TARGET_CALLER_INTERWORKING \
- || TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME) \
- { \
- fixed_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \
- call_used_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \
- if (TARGET_CALLER_INTERWORKING) \
- global_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \
- } \
- SUBTARGET_CONDITIONAL_REGISTER_USAGE \
-}
-
/* These are a couple of extensions to the formats accepted
by asm_fprintf:
%@ prints out ASM_COMMENT_START
#define FIRST_HI_REGNUM 8
#define LAST_HI_REGNUM 11
-#ifndef TARGET_UNWIND_INFO
-/* We use sjlj exceptions for backwards compatibility. */
-#define MUST_USE_SJLJ_EXCEPTIONS 1
+/* Overridden by config/arm/bpabi.h. */
+#ifndef ARM_UNWIND_INFO
+#define ARM_UNWIND_INFO 0
#endif
-/* We can generate DWARF2 Unwind info, even though we don't use it. */
-#define DWARF2_UNWIND_INFO 1
-
/* Use r0 and r1 to pass exception handling information. */
#define EH_RETURN_DATA_REGNO(N) (((N) < 2) ? N : INVALID_REGNUM)
#define ARM_EH_STACKADJ_REGNUM 2
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (SImode, ARM_EH_STACKADJ_REGNUM)
+#ifndef ARM_TARGET2_DWARF_FORMAT
+#define ARM_TARGET2_DWARF_FORMAT DW_EH_PE_pcrel
+
+/* ttype entries (the only interesting data references used)
+ use TARGET2 relocations. */
+#define ASM_PREFERRED_EH_DATA_FORMAT(code, data) \
+ (((code) == 0 && (data) == 1 && ARM_UNWIND_INFO) ? ARM_TARGET2_DWARF_FORMAT \
+ : DW_EH_PE_absptr)
+#endif
+
/* The native (Norcroft) Pascal compiler for the ARM passes the static chain
as an invisible last argument (possible since varargs don't exist in
Pascal), so the following is not true. */
? ARM_HARD_FRAME_POINTER_REGNUM \
: THUMB_HARD_FRAME_POINTER_REGNUM)
+#define HARD_FRAME_POINTER_IS_FRAME_POINTER 0
+#define HARD_FRAME_POINTER_IS_ARG_POINTER 0
+
#define FP_REGNUM HARD_FRAME_POINTER_REGNUM
/* Register to use for pushing function arguments. */
((MODE) == TImode || (MODE) == EImode || (MODE) == OImode \
|| (MODE) == CImode || (MODE) == XImode)
+/* The register numbers in sequence, for passing to arm_gen_load_multiple. */
+extern int arm_regs_in_sequence[];
+
/* The order in which register should be allocated. It is good to use ip
since no saving is required (though calls clobber it) and it never contains
function parameters. It is quite good to use lr since other calls may
{ 0x0000DF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */ \
{ 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* CC_REG */ \
{ 0x00000000, 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */ \
- { 0x0200DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
- { 0x0200FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \
+ { 0x0000DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
+ { 0x0000FFFF, 0x00000000, 0x00000000, 0x00000000 }, /* CORE_REGS */ \
{ 0xFAFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x7FFFFFFF } /* ALL_REGS */ \
}
or could index an array. */
#define REGNO_REG_CLASS(REGNO) arm_regno_class (REGNO)
-/* The following macro defines cover classes for Integrated Register
- Allocator. Cover classes is a set of non-intersected register
- classes covering all hard registers used for register allocation
- purpose. Any move between two registers of a cover class should be
- cheaper than load or store of the registers. The macro value is
- array of register classes with LIM_REG_CLASSES used as the end
- marker. */
-
-#define IRA_COVER_CLASSES \
-{ \
- GENERAL_REGS, FPA_REGS, CIRRUS_REGS, VFP_REGS, IWMMXT_GR_REGS, IWMMXT_REGS,\
- LIM_REG_CLASSES \
-}
-
/* FPA registers can't do subreg as all values are reformatted to internal
- precision. VFP registers may only be accessed in the mode they
- were set. */
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? reg_classes_intersect_p (FPA_REGS, (CLASS)) \
- || reg_classes_intersect_p (VFP_REGS, (CLASS)) \
+ precision. In VFPv1, VFP registers could only be accessed in the mode
+ they were set, so subregs would be invalid there too. However, we don't
+ support VFPv1 at the moment, and the restriction was lifted in VFPv2. */
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
+ ? reg_classes_intersect_p (FPA_REGS, (CLASS)) \
: 0)
-/* We need to define this for LO_REGS on thumb. Otherwise we can end up
- using r0-r4 for function arguments, r7 for the stack frame and don't
- have enough left over to do doubleword arithmetic. */
-#define CLASS_LIKELY_SPILLED_P(CLASS) \
- ((TARGET_THUMB && (CLASS) == LO_REGS) \
- || (CLASS) == CC_REG)
-
/* The class value for index registers, and the one for base regs. */
#define INDEX_REG_CLASS (TARGET_THUMB1 ? LO_REGS : GENERAL_REGS)
#define BASE_REG_CLASS (TARGET_THUMB1 ? LO_REGS : CORE_REGS)
when addressing quantities in QI or HI mode; if we don't know the
mode, then we must be conservative. */
#define MODE_BASE_REG_CLASS(MODE) \
- (TARGET_32BIT ? CORE_REGS : \
+ (TARGET_ARM || (TARGET_THUMB2 && !optimize_size) ? CORE_REGS : \
(((MODE) == SImode) ? BASE_REGS : LO_REGS))
/* For Thumb we can not support SP+reg addressing, so we return LO_REGS
instead of BASE_REGS. */
#define MODE_BASE_REG_REG_CLASS(MODE) BASE_REG_CLASS
-/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows
+/* When this hook returns true for MODE, the compiler allows
registers explicitly used in the rtl to be used as spill registers
but prevents the compiler from extending the lifetime of these
registers. */
-#define SMALL_REGISTER_CLASSES TARGET_THUMB1
+#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P \
+ arm_small_register_classes_for_mode_p
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
#define ARM_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND, WIN) \
do \
{ \
- if (GET_CODE (X) == PLUS \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \
- && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
- HOST_WIDE_INT low, high; \
- \
- if (MODE == DImode || (MODE == DFmode && TARGET_SOFT_FLOAT)) \
- low = ((val & 0xf) ^ 0x8) - 0x8; \
- else if (TARGET_MAVERICK && TARGET_HARD_FLOAT) \
- /* Need to be careful, -256 is not a valid offset. */ \
- low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
- else if (MODE == SImode \
- || (MODE == SFmode && TARGET_SOFT_FLOAT) \
- || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \
- /* Need to be careful, -4096 is not a valid offset. */ \
- low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff); \
- else if ((MODE == HImode || MODE == QImode) && arm_arch4) \
- /* Need to be careful, -256 is not a valid offset. */ \
- low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \
- else if (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && TARGET_HARD_FLOAT && TARGET_FPA) \
- /* Need to be careful, -1024 is not a valid offset. */ \
- low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff); \
- else \
- break; \
- \
- high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff) \
- ^ (unsigned HOST_WIDE_INT) 0x80000000) \
- - (unsigned HOST_WIDE_INT) 0x80000000); \
- /* Check for overflow or zero */ \
- if (low == 0 || high == 0 || (high + low != val)) \
- break; \
- \
- /* Reload the high part into a base reg; leave the low part \
- in the mem. */ \
- X = gen_rtx_PLUS (GET_MODE (X), \
- gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \
- GEN_INT (high)), \
- GEN_INT (low)); \
- push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
- MODE_BASE_REG_CLASS (MODE), GET_MODE (X), \
- VOIDmode, 0, 0, OPNUM, TYPE); \
- goto WIN; \
- } \
+ if (arm_legitimize_reload_address (&X, MODE, OPNUM, TYPE, IND)) \
+ goto WIN; \
} \
while (0)
/* Offset of first parameter from the argument pointer register value. */
#define FIRST_PARM_OFFSET(FNDECL) (TARGET_ARM ? 4 : 0)
-/* Value is the number of byte of arguments automatically
- popped when returning from a subroutine call.
- FUNDECL is the declaration node of the function (as a tree),
- FUNTYPE is the data type of the function (as a tree),
- or for a library call it is an identifier node for the subroutine name.
- SIZE is the number of bytes of arguments passed on the stack.
-
- On the ARM, the caller does not pop any of its arguments that were passed
- on the stack. */
-#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0
-
/* Define how to find the value returned by a library function
assuming the value has mode MODE. */
#define LIBCALL_VALUE(MODE) \
}
arm_stack_offsets;
+#ifndef GENERATOR_FILE
/* A C structure for machine-specific, per-function data.
This is added to the cfun structure. */
typedef struct GTY(()) machine_function
/* Set to 1 when a return insn is output, this means that the epilogue
is not needed. */
int return_used_this_function;
+ /* When outputting Thumb-1 code, record the last insn that provides
+ information about condition codes, and the comparison operands. */
+ rtx thumb1_cc_insn;
+ rtx thumb1_cc_op0;
+ rtx thumb1_cc_op1;
+ /* Also record the CC mode that is supported. */
+ enum machine_mode thumb1_cc_mode;
}
machine_function;
+#endif
/* As in the machine_function, a global set of call-via labels, for code
that is in text_section. */
ARM_PCS_UNKNOWN
};
+/* Default procedure calling standard of current compilation unit. */
+extern enum arm_pcs arm_pcs_default;
+
/* A C type for declaring a variable that is used as the first argument of
`FUNCTION_ARG' and other related values. */
typedef struct
MACHMODE aapcs_vfp_rmode;
} CUMULATIVE_ARGS;
-/* Define where to put the arguments to a function.
- Value is zero to push the argument on the stack,
- or a hard register in which to store the argument.
-
- MODE is the argument's machine mode.
- TYPE is the data type of the argument (as a tree).
- This is null for libcalls where that information may
- not be available.
- CUM is a variable of type CUMULATIVE_ARGS which gives info about
- the preceding args and about the function being called.
- NAMED is nonzero if this argument is a named parameter
- (otherwise it is an extra parameter matching an ellipsis).
-
- On the ARM, normally the first 16 bytes are passed in registers r0-r3; all
- other arguments are passed on the stack. If (NAMED == 0) (which happens
- only in assign_parms, since TARGET_SETUP_INCOMING_VARARGS is
- defined), say it is passed in the stack (function_prologue will
- indeed make it pass in the stack if necessary). */
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
- arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED))
-
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
(arm_pad_arg_upward (MODE, TYPE) ? upward : downward)
#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL))
-/* Update the data in CUM to advance over an argument
- of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
- arm_function_arg_advance (&(CUM), (MODE), (TYPE), (NAMED))
-
-/* If defined, a C expression that gives the alignment boundary, in bits, of an
- argument with the specified mode and type. If it is not defined,
- `PARM_BOUNDARY' is used for all arguments. */
-#define FUNCTION_ARG_BOUNDARY(MODE,TYPE) \
- ((ARM_DOUBLEWORD_ALIGN && arm_needs_doubleword_align (MODE, TYPE)) \
- ? DOUBLEWORD_ALIGNMENT \
- : PARM_BOUNDARY )
-
/* 1 if N is a possible register number for function argument passing.
On the ARM, r0-r3 are used to pass args. */
#define FUNCTION_ARG_REGNO_P(REGNO) \
/* Determine if the epilogue should be output as RTL.
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
-/* This is disabled for Thumb-2 because it will confuse the
- conditional insn counter. */
#define USE_RETURN_INSN(ISCOND) \
- (TARGET_ARM ? use_return_insn (ISCOND, NULL) : 0)
+ (TARGET_32BIT ? use_return_insn (ISCOND, NULL) : 0)
/* Definitions for register eliminations.
#define TARGET_DEFAULT_WORD_RELOCATIONS 0
#endif
-/* Nonzero if the constant value X is a legitimate general operand.
- It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
-
- On the ARM, allow any integer (invalid ones are removed later by insn
- patterns), nice doubles and symbol_refs which refer to the function's
- constant pool XXX.
-
- When generating pic allow anything. */
-#define ARM_LEGITIMATE_CONSTANT_P(X) (flag_pic || ! label_mentioned_p (X))
-
-#define THUMB_LEGITIMATE_CONSTANT_P(X) \
- ( GET_CODE (X) == CONST_INT \
- || GET_CODE (X) == CONST_DOUBLE \
- || CONSTANT_ADDRESS_P (X) \
- || flag_pic)
-
-#define LEGITIMATE_CONSTANT_P(X) \
- (!arm_cannot_force_const_mem (X) \
- && (TARGET_32BIT ? ARM_LEGITIMATE_CONSTANT_P (X) \
- : THUMB_LEGITIMATE_CONSTANT_P (X)))
-
#ifndef SUBTARGET_NAME_ENCODING_LENGTHS
#define SUBTARGET_NAME_ENCODING_LENGTHS
#endif
#define ARM_OUTPUT_FN_UNWIND(F, PROLOGUE) arm_output_fn_unwind (F, PROLOGUE)
-#ifdef TARGET_UNWIND_INFO
-#define ARM_EABI_UNWIND_TABLES \
- ((!USING_SJLJ_EXCEPTIONS && flag_exceptions) || flag_unwind_tables)
-#else
-#define ARM_EABI_UNWIND_TABLES 0
-#endif
-
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
#define ARM_INDEX_REGISTER_RTX_P(X) \
(GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
\f
-/* Define this for compatibility reasons. */
-#define HANDLE_PRAGMA_PACK_PUSH_POP
-
/* Specify the machine mode that this machine uses
for the index in the tablejump instruction. */
#define CASE_VECTOR_MODE Pmode
: min >= -4096 && max < 4096 \
? (ADDR_DIFF_VEC_FLAGS (body).offset_unsigned = 0, HImode) \
: SImode) \
- : ((min < 0 || max >= 0x2000 || !TARGET_THUMB2) ? SImode \
+ : ((min < 0 || max >= 0x20000 || !TARGET_THUMB2) ? SImode \
: (max >= 0x200) ? HImode \
: QImode))
/* Try to generate sequences that don't involve branches, we can then use
conditional instructions */
#define BRANCH_COST(speed_p, predictable_p) \
- (TARGET_32BIT ? 4 : (optimize > 0 ? 2 : 0))
+ (current_tune->branch_cost (speed_p, predictable_p))
+
\f
/* Position Independent Code. */
/* We decide which register to use based on the compilation options and
: reverse_condition (code))
#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
- do \
- { \
- if (GET_CODE (OP1) == CONST_INT \
- && ! (const_ok_for_arm (INTVAL (OP1)) \
- || (const_ok_for_arm (- INTVAL (OP1))))) \
- { \
- rtx const_op = OP1; \
- CODE = arm_canonicalize_comparison ((CODE), GET_MODE (OP0), \
- &const_op); \
- OP1 = const_op; \
- } \
- } \
- while (0)
+ (CODE) = arm_canonicalize_comparison (CODE, &(OP0), &(OP1))
/* The arm5 clz instruction returns 32. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 32, 1)
\f
+#define CC_STATUS_INIT \
+ do { cfun->machine->thumb1_cc_insn = NULL_RTX; } while (0)
+
#undef ASM_APP_OFF
#define ASM_APP_OFF (TARGET_THUMB1 ? "\t.code\t16\n" : \
TARGET_THUMB2 ? "\t.thumb\n" : "")
else if (TARGET_THUMB1) \
thumb1_final_prescan_insn (INSN)
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
- (CODE == '@' || CODE == '|' || CODE == '.' \
- || CODE == '(' || CODE == ')' || CODE == '#' \
- || (TARGET_32BIT && (CODE == '?')) \
- || (TARGET_THUMB2 && (CODE == '!')) \
- || (TARGET_THUMB && (CODE == '_')))
-
-/* Output an operand of an instruction. */
-#define PRINT_OPERAND(STREAM, X, CODE) \
- arm_print_operand (STREAM, X, CODE)
-
#define ARM_SIGN_EXTEND(x) ((HOST_WIDE_INT) \
(HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x) \
: ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0xffffffff) |\
& ~ (unsigned HOST_WIDE_INT) 0xffffffff) \
: 0))))
-/* Output the address of an operand. */
-#define ARM_PRINT_OPERAND_ADDRESS(STREAM, X) \
-{ \
- int is_minus = GET_CODE (X) == MINUS; \
- \
- if (GET_CODE (X) == REG) \
- asm_fprintf (STREAM, "[%r, #0]", REGNO (X)); \
- else if (GET_CODE (X) == PLUS || is_minus) \
- { \
- rtx base = XEXP (X, 0); \
- rtx index = XEXP (X, 1); \
- HOST_WIDE_INT offset = 0; \
- if (GET_CODE (base) != REG \
- || (GET_CODE (index) == REG && REGNO (index) == SP_REGNUM)) \
- { \
- /* Ensure that BASE is a register. */ \
- /* (one of them must be). */ \
- /* Also ensure the SP is not used as in index register. */ \
- rtx temp = base; \
- base = index; \
- index = temp; \
- } \
- switch (GET_CODE (index)) \
- { \
- case CONST_INT: \
- offset = INTVAL (index); \
- if (is_minus) \
- offset = -offset; \
- asm_fprintf (STREAM, "[%r, #%wd]", \
- REGNO (base), offset); \
- break; \
- \
- case REG: \
- asm_fprintf (STREAM, "[%r, %s%r]", \
- REGNO (base), is_minus ? "-" : "", \
- REGNO (index)); \
- break; \
- \
- case MULT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- case ASHIFT: \
- case ROTATERT: \
- { \
- asm_fprintf (STREAM, "[%r, %s%r", \
- REGNO (base), is_minus ? "-" : "", \
- REGNO (XEXP (index, 0))); \
- arm_print_operand (STREAM, index, 'S'); \
- fputs ("]", STREAM); \
- break; \
- } \
- \
- default: \
- gcc_unreachable (); \
- } \
- } \
- else if (GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC \
- || GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC) \
- { \
- extern enum machine_mode output_memory_reference_mode; \
- \
- gcc_assert (GET_CODE (XEXP (X, 0)) == REG); \
- \
- if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \
- asm_fprintf (STREAM, "[%r, #%s%d]!", \
- REGNO (XEXP (X, 0)), \
- GET_CODE (X) == PRE_DEC ? "-" : "", \
- GET_MODE_SIZE (output_memory_reference_mode)); \
- else \
- asm_fprintf (STREAM, "[%r], #%s%d", \
- REGNO (XEXP (X, 0)), \
- GET_CODE (X) == POST_DEC ? "-" : "", \
- GET_MODE_SIZE (output_memory_reference_mode)); \
- } \
- else if (GET_CODE (X) == PRE_MODIFY) \
- { \
- asm_fprintf (STREAM, "[%r, ", REGNO (XEXP (X, 0))); \
- if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT) \
- asm_fprintf (STREAM, "#%wd]!", \
- INTVAL (XEXP (XEXP (X, 1), 1))); \
- else \
- asm_fprintf (STREAM, "%r]!", \
- REGNO (XEXP (XEXP (X, 1), 1))); \
- } \
- else if (GET_CODE (X) == POST_MODIFY) \
- { \
- asm_fprintf (STREAM, "[%r], ", REGNO (XEXP (X, 0))); \
- if (GET_CODE (XEXP (XEXP (X, 1), 1)) == CONST_INT) \
- asm_fprintf (STREAM, "#%wd", \
- INTVAL (XEXP (XEXP (X, 1), 1))); \
- else \
- asm_fprintf (STREAM, "%r", \
- REGNO (XEXP (XEXP (X, 1), 1))); \
- } \
- else output_addr_const (STREAM, X); \
-}
-
-#define THUMB_PRINT_OPERAND_ADDRESS(STREAM, X) \
-{ \
- if (GET_CODE (X) == REG) \
- asm_fprintf (STREAM, "[%r]", REGNO (X)); \
- else if (GET_CODE (X) == POST_INC) \
- asm_fprintf (STREAM, "%r!", REGNO (XEXP (X, 0))); \
- else if (GET_CODE (X) == PLUS) \
- { \
- gcc_assert (GET_CODE (XEXP (X, 0)) == REG); \
- if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
- asm_fprintf (STREAM, "[%r, #%wd]", \
- REGNO (XEXP (X, 0)), \
- INTVAL (XEXP (X, 1))); \
- else \
- asm_fprintf (STREAM, "[%r, %r]", \
- REGNO (XEXP (X, 0)), \
- REGNO (XEXP (X, 1))); \
- } \
- else \
- output_addr_const (STREAM, X); \
-}
-
-#define PRINT_OPERAND_ADDRESS(STREAM, X) \
- if (TARGET_32BIT) \
- ARM_PRINT_OPERAND_ADDRESS (STREAM, X) \
- else \
- THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
-
-#define OUTPUT_ADDR_CONST_EXTRA(file, x, fail) \
- if (arm_output_addr_const_extra (file, x) == FALSE) \
- goto fail
-
/* A C expression whose value is RTL representing the value of the return
address for the frame COUNT steps up from the current frame. */
: arm_gen_return_addr_mask ())
\f
-/* Neon defines builtins from ARM_BUILTIN_MAX upwards, though they don't have
- symbolic names defined here (which would require too much duplication).
- FIXME? */
-enum arm_builtins
-{
- ARM_BUILTIN_GETWCX,
- ARM_BUILTIN_SETWCX,
-
- ARM_BUILTIN_WZERO,
-
- ARM_BUILTIN_WAVG2BR,
- ARM_BUILTIN_WAVG2HR,
- ARM_BUILTIN_WAVG2B,
- ARM_BUILTIN_WAVG2H,
-
- ARM_BUILTIN_WACCB,
- ARM_BUILTIN_WACCH,
- ARM_BUILTIN_WACCW,
-
- ARM_BUILTIN_WMACS,
- ARM_BUILTIN_WMACSZ,
- ARM_BUILTIN_WMACU,
- ARM_BUILTIN_WMACUZ,
-
- ARM_BUILTIN_WSADB,
- ARM_BUILTIN_WSADBZ,
- ARM_BUILTIN_WSADH,
- ARM_BUILTIN_WSADHZ,
-
- ARM_BUILTIN_WALIGN,
-
- ARM_BUILTIN_TMIA,
- ARM_BUILTIN_TMIAPH,
- ARM_BUILTIN_TMIABB,
- ARM_BUILTIN_TMIABT,
- ARM_BUILTIN_TMIATB,
- ARM_BUILTIN_TMIATT,
-
- ARM_BUILTIN_TMOVMSKB,
- ARM_BUILTIN_TMOVMSKH,
- ARM_BUILTIN_TMOVMSKW,
-
- ARM_BUILTIN_TBCSTB,
- ARM_BUILTIN_TBCSTH,
- ARM_BUILTIN_TBCSTW,
-
- ARM_BUILTIN_WMADDS,
- ARM_BUILTIN_WMADDU,
-
- ARM_BUILTIN_WPACKHSS,
- ARM_BUILTIN_WPACKWSS,
- ARM_BUILTIN_WPACKDSS,
- ARM_BUILTIN_WPACKHUS,
- ARM_BUILTIN_WPACKWUS,
- ARM_BUILTIN_WPACKDUS,
-
- ARM_BUILTIN_WADDB,
- ARM_BUILTIN_WADDH,
- ARM_BUILTIN_WADDW,
- ARM_BUILTIN_WADDSSB,
- ARM_BUILTIN_WADDSSH,
- ARM_BUILTIN_WADDSSW,
- ARM_BUILTIN_WADDUSB,
- ARM_BUILTIN_WADDUSH,
- ARM_BUILTIN_WADDUSW,
- ARM_BUILTIN_WSUBB,
- ARM_BUILTIN_WSUBH,
- ARM_BUILTIN_WSUBW,
- ARM_BUILTIN_WSUBSSB,
- ARM_BUILTIN_WSUBSSH,
- ARM_BUILTIN_WSUBSSW,
- ARM_BUILTIN_WSUBUSB,
- ARM_BUILTIN_WSUBUSH,
- ARM_BUILTIN_WSUBUSW,
-
- ARM_BUILTIN_WAND,
- ARM_BUILTIN_WANDN,
- ARM_BUILTIN_WOR,
- ARM_BUILTIN_WXOR,
-
- ARM_BUILTIN_WCMPEQB,
- ARM_BUILTIN_WCMPEQH,
- ARM_BUILTIN_WCMPEQW,
- ARM_BUILTIN_WCMPGTUB,
- ARM_BUILTIN_WCMPGTUH,
- ARM_BUILTIN_WCMPGTUW,
- ARM_BUILTIN_WCMPGTSB,
- ARM_BUILTIN_WCMPGTSH,
- ARM_BUILTIN_WCMPGTSW,
-
- ARM_BUILTIN_TEXTRMSB,
- ARM_BUILTIN_TEXTRMSH,
- ARM_BUILTIN_TEXTRMSW,
- ARM_BUILTIN_TEXTRMUB,
- ARM_BUILTIN_TEXTRMUH,
- ARM_BUILTIN_TEXTRMUW,
- ARM_BUILTIN_TINSRB,
- ARM_BUILTIN_TINSRH,
- ARM_BUILTIN_TINSRW,
-
- ARM_BUILTIN_WMAXSW,
- ARM_BUILTIN_WMAXSH,
- ARM_BUILTIN_WMAXSB,
- ARM_BUILTIN_WMAXUW,
- ARM_BUILTIN_WMAXUH,
- ARM_BUILTIN_WMAXUB,
- ARM_BUILTIN_WMINSW,
- ARM_BUILTIN_WMINSH,
- ARM_BUILTIN_WMINSB,
- ARM_BUILTIN_WMINUW,
- ARM_BUILTIN_WMINUH,
- ARM_BUILTIN_WMINUB,
-
- ARM_BUILTIN_WMULUM,
- ARM_BUILTIN_WMULSM,
- ARM_BUILTIN_WMULUL,
-
- ARM_BUILTIN_PSADBH,
- ARM_BUILTIN_WSHUFH,
-
- ARM_BUILTIN_WSLLH,
- ARM_BUILTIN_WSLLW,
- ARM_BUILTIN_WSLLD,
- ARM_BUILTIN_WSRAH,
- ARM_BUILTIN_WSRAW,
- ARM_BUILTIN_WSRAD,
- ARM_BUILTIN_WSRLH,
- ARM_BUILTIN_WSRLW,
- ARM_BUILTIN_WSRLD,
- ARM_BUILTIN_WRORH,
- ARM_BUILTIN_WRORW,
- ARM_BUILTIN_WRORD,
- ARM_BUILTIN_WSLLHI,
- ARM_BUILTIN_WSLLWI,
- ARM_BUILTIN_WSLLDI,
- ARM_BUILTIN_WSRAHI,
- ARM_BUILTIN_WSRAWI,
- ARM_BUILTIN_WSRADI,
- ARM_BUILTIN_WSRLHI,
- ARM_BUILTIN_WSRLWI,
- ARM_BUILTIN_WSRLDI,
- ARM_BUILTIN_WRORHI,
- ARM_BUILTIN_WRORWI,
- ARM_BUILTIN_WRORDI,
-
- ARM_BUILTIN_WUNPCKIHB,
- ARM_BUILTIN_WUNPCKIHH,
- ARM_BUILTIN_WUNPCKIHW,
- ARM_BUILTIN_WUNPCKILB,
- ARM_BUILTIN_WUNPCKILH,
- ARM_BUILTIN_WUNPCKILW,
-
- ARM_BUILTIN_WUNPCKEHSB,
- ARM_BUILTIN_WUNPCKEHSH,
- ARM_BUILTIN_WUNPCKEHSW,
- ARM_BUILTIN_WUNPCKEHUB,
- ARM_BUILTIN_WUNPCKEHUH,
- ARM_BUILTIN_WUNPCKEHUW,
- ARM_BUILTIN_WUNPCKELSB,
- ARM_BUILTIN_WUNPCKELSH,
- ARM_BUILTIN_WUNPCKELSW,
- ARM_BUILTIN_WUNPCKELUB,
- ARM_BUILTIN_WUNPCKELUH,
- ARM_BUILTIN_WUNPCKELUW,
-
- ARM_BUILTIN_THREAD_POINTER,
-
- ARM_BUILTIN_NEON_BASE,
-
- ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE /* FIXME: Wrong! */
-};
-
/* Do not emit .note.GNU-stack by default. */
#ifndef NEED_INDICATE_EXEC_STACK
#define NEED_INDICATE_EXEC_STACK 0
#endif
+/* The maximum number of parallel loads or stores we support in an ldm/stm
+ instruction. */
+#define MAX_LDM_STM_OPS 4
+
+#define ASM_CPU_SPEC \
+ " %{mcpu=generic-*:-march=%*;" \
+ " :%{mcpu=*:-mcpu=%*} %{march=*:-march=%*}}"
+
#endif /* ! GCC_ARM_H */