/* Definitions of target machine for GNU compiler, for ARM.
- Copyright (C) 1991, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ 2001 Free Software Foundation, Inc.
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
and Martin Simmons (@harleqn.co.uk).
More major hacks by Richard Earnshaw (rearnsha@arm.com)
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#ifndef __ARM_H__
-#define __ARM_H__
+#ifndef GCC_ARM_H
+#define GCC_ARM_H
#define TARGET_CPU_arm2 0x0000
#define TARGET_CPU_arm250 0x0000
#define TARGET_CPU_strongarm1100 0x0040
#define TARGET_CPU_arm9 0x0080
#define TARGET_CPU_arm9tdmi 0x0080
+#define TARGET_CPU_xscale 0x0100
/* Configure didn't specify. */
#define TARGET_CPU_generic 0x8000
arm_cc;
extern arm_cc arm_current_cc;
-extern const char * arm_condition_codes[];
#define ARM_INVERSE_CONDITION_CODE(X) ((arm_cc) (((int)X) ^ 1))
#endif
/* If the configuration file doesn't specify the cpu, the subtarget may
- override it. If it doesn't, then default to an ARM6. */
+ override it. If it doesn't, then default to an ARM6. */
#if TARGET_CPU_DEFAULT == TARGET_CPU_generic
#undef TARGET_CPU_DEFAULT
+
#ifdef SUBTARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT SUBTARGET_CPU_DEFAULT
#else
#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__"
#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_arm9
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_arm9 || TARGET_CPU_DEFAULT == TARGET_CPU_arm9tdmi
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__"
#else
-#if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm110 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm1100
#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4__"
#else
+#if TARGET_CPU_DEFAULT == TARGET_CPU_xscale
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__"
+#else
Unrecognized value in TARGET_CPU_DEFAULT.
#endif
#endif
#endif
#endif
#endif
+#endif
#ifndef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Acpu(arm) -Amachine(arm)"
+#define CPP_PREDEFINES "-Acpu=arm -Amachine=arm"
#endif
#define CPP_SPEC "\
%(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) \
%(cpp_endian) %(subtarget_cpp_spec) %(cpp_isa) %(cpp_interwork)"
-#define CPP_ISA_SPEC "%{mthumb:-Dthumb -D__thumb__} %{!mthumb:-Darm -D__arm__}"
+#define CPP_ISA_SPEC "%{mthumb:-D__thumb__} %{!mthumb:-D__arm__}"
/* Set the architecture define -- if -march= is set, then it overrides
the -mcpu= setting. */
%{march=strongarm:-D__ARM_ARCH_4__} \
%{march=strongarm110:-D__ARM_ARCH_4__} \
%{march=strongarm1100:-D__ARM_ARCH_4__} \
+%{march=xscale:-D__ARM_ARCH_5TE__} \
+%{march=xscale:-D__XSCALE__} \
%{march=armv2:-D__ARM_ARCH_2__} \
%{march=armv2a:-D__ARM_ARCH_2__} \
%{march=armv3:-D__ARM_ARCH_3__} \
%{mcpu=strongarm:-D__ARM_ARCH_4__} \
%{mcpu=strongarm110:-D__ARM_ARCH_4__} \
%{mcpu=strongarm1100:-D__ARM_ARCH_4__} \
+ %{mcpu=xscale:-D__ARM_ARCH_5TE__} \
+ %{mcpu=xscale:-D__XSCALE__} \
%{!mcpu*:%(cpp_cpu_arch_default)}} \
"
%{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}} \
"
+#ifndef CC1_SPEC
#define CC1_SPEC ""
+#endif
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
{"no-poke-function-name", -ARM_FLAG_POKE, "" }, \
{"fpe", ARM_FLAG_FPE, "" }, \
{"apcs-32", ARM_FLAG_APCS_32, \
- N_("Use the 32bit version of the APCS") }, \
+ N_("Use the 32-bit version of the APCS") }, \
{"apcs-26", -ARM_FLAG_APCS_32, \
- N_("Use the 26bit version of the APCS") }, \
+ N_("Use the 26-bit version of the APCS") }, \
{"apcs-stack-check", ARM_FLAG_APCS_STACK, "" }, \
{"no-apcs-stack-check", -ARM_FLAG_APCS_STACK, "" }, \
{"apcs-float", ARM_FLAG_APCS_FLOAT, \
{"words-little-endian", ARM_FLAG_LITTLE_WORDS, \
N_("Assume big endian bytes, little endian words") }, \
{"thumb-interwork", ARM_FLAG_INTERWORK, \
- N_("Support calls between THUMB and ARM instructions sets") }, \
+ N_("Support calls between Thumb and ARM instruction sets") }, \
{"no-thumb-interwork", -ARM_FLAG_INTERWORK, "" }, \
{"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \
N_("Generate a call to abort if a noreturn function returns")}, \
{"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, "" }, \
- {"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, \
+ {"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, \
N_("Do not move instructions into a function's prologue") }, \
- {"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, "" }, \
+ {"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, "" }, \
{"single-pic-base", ARM_FLAG_SINGLE_PIC_BASE, \
N_("Do not load the PIC register in function prologues") }, \
{"no-single-pic-base", -ARM_FLAG_SINGLE_PIC_BASE, "" }, \
/* Default floating point architecture. Override in sub-target if
necessary. */
+#ifndef FP_DEFAULT
#define FP_DEFAULT FP_SOFT2
+#endif
/* Nonzero if the processor has a fast multiply insn, and one that does
a 64-bit multiply of two 32-bit values. */
/* Nonzero if this chip supports the ARM Architecture 5 extensions */
extern int arm_arch5;
+/* Nonzero if this chip supports the ARM Architecture 5E extensions */
+extern int arm_arch5e;
+
/* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched;
/* Nonzero if this chip is a StrongARM. */
extern int arm_is_strong;
+/* Nonzero if this chip is an XScale. */
+extern int arm_is_xscale;
+
/* Nonzero if this chip is a an ARM6 or an ARM7. */
extern int arm_is_6_or_7;
that is controlled by the APCS-FRAME option. */
#define CAN_DEBUG_WITHOUT_FP
+#undef TARGET_MEM_FUNCTIONS
#define TARGET_MEM_FUNCTIONS 1
#define OVERRIDE_OPTIONS arm_override_options ()
#define FUNCTION_BOUNDARY 32
+/* The lowest bit is used to indicate Thumb-mode functions, so the
+ vbit must go into the delta field of pointers to member
+ functions. */
+#define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_delta
+
#define EMPTY_FIELD_BOUNDARY 32
#define BIGGEST_ALIGNMENT 32
/* Make strings word-aligned so strcpy from constants will be faster. */
-#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
- (TREE_CODE (EXP) == STRING_CST \
- && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
+#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_is_xscale ? 1 : 2)
+
+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
+ ((TREE_CODE (EXP) == STRING_CST \
+ && (ALIGN) < BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR) \
+ ? BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR : (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
compact structures. The command line option -mstructure_size_boundary=<n>
- can be used to change this value. For compatability with the ARM SDK
+ can be used to change this value. For compatibility with the ARM SDK
however the value should be left at 32. ARM SDT Reference Manual (ARM DUI
0020D) page 2-20 says "Structures are aligned on word boundaries". */
#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary
/* Return the regiser number of the N'th (integer) argument. */
#define ARG_REGISTER(N) (N - 1)
-/* Register in which address to store a structure value
- is passed to a function. */
-#define STRUCT_VALUE_REGNUM ARG_REGISTER (1)
+/* RTX for structure returns. NULL means use a hidden first argument. */
+#define STRUCT_VALUE 0
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
#define LAST_ARG_REGNUM ARG_REGISTER (NUM_ARG_REGS)
/* The number of the last "lo" register (thumb). */
-#define LAST_LO_REGNUM 7
+#define LAST_LO_REGNUM 7
+
+/* The register that holds the return address in exception handlers. */
+#define EXCEPTION_LR_REGNUM 2
/* 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. */
-#define STATIC_CHAIN_REGNUM (TARGET_ARM ? 8 : 9)
+#define STATIC_CHAIN_REGNUM (TARGET_ARM ? 12 : 9)
/* Define this to be where the real frame pointer is if it is not possible to
work out the offset between the frame pointer and the automatic variables
pointer. */
#define ARM_HARD_FRAME_POINTER_REGNUM 11
#define THUMB_HARD_FRAME_POINTER_REGNUM 7
-#define HARD_FRAME_POINTER_REGNUM (TARGET_ARM ? ARM_HARD_FRAME_POINTER_REGNUM : THUMB_HARD_FRAME_POINTER_REGNUM)
-#define FP_REGNUM HARD_FRAME_POINTER_REGNUM
-
-/* Scratch register - used in all kinds of places, eg trampolines. */
-#define IP_REGNUM 12
-/* Register to use for pushing function arguments. */
-#define STACK_POINTER_REGNUM 13
-#define SP_REGNUM STACK_POINTER_REGNUM
+#define HARD_FRAME_POINTER_REGNUM \
+ (TARGET_ARM \
+ ? ARM_HARD_FRAME_POINTER_REGNUM \
+ : THUMB_HARD_FRAME_POINTER_REGNUM)
-/* Register which holds return address from a subroutine call. */
-#define LR_REGNUM 14
-
-/* Define this if the program counter is overloaded on a register. */
-#define PC_REGNUM 15
+#define FP_REGNUM HARD_FRAME_POINTER_REGNUM
-/* The number of the last ARM (integer) register. */
-#define LAST_ARM_REGNUM 15
+/* Register to use for pushing function arguments. */
+#define STACK_POINTER_REGNUM SP_REGNUM
/* ARM floating pointer registers. */
#define FIRST_ARM_FP_REGNUM 16
#define LAST_ARM_FP_REGNUM 23
-/* Internal, so that we don't need to refer to a raw number */
-#define CC_REGNUM 24
-
/* Base register for access to local variables of the function. */
#define FRAME_POINTER_REGNUM 25
If we have to have a frame pointer we might as well make use of it.
APCS says that the frame pointer does not need to be pushed in leaf
functions, or simple tail call functions. */
-#define FRAME_POINTER_REQUIRED \
- (current_function_has_nonlocal_label \
+#define FRAME_POINTER_REQUIRED \
+ (current_function_has_nonlocal_label \
|| (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()))
/* Return number of consecutive hard regs needed starting at reg REGNO
else \
break; \
\
- high = ((((val - low) & HOST_UINT (0xffffffff)) \
- ^ HOST_UINT (0x80000000)) \
- - HOST_UINT (0x80000000)); \
+ 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; \
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_PTR, \
+ push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \
BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \
OPNUM, TYPE); \
goto WIN; \
&& GET_CODE (XEXP (X, 0)) == REG \
&& XEXP (X, 0) == stack_pointer_rtx \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
- && ! LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
+ && ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
{ \
rtx orig_X = X; \
X = copy_rtx (X); \
- push_reload (orig_X, NULL_RTX, &X, NULL_PTR, \
+ push_reload (orig_X, NULL_RTX, &X, NULL, \
BASE_REG_CLASS, \
Pmode, VOIDmode, 0, 0, OPNUM, TYPE); \
goto WIN; \
((CLASS) == FPU_REGS ? 1 : NUM_REGS (MODE))
/* Moves between FPU_REGS and GENERAL_REGS are two memory insns. */
-#define REGISTER_MOVE_COST(FROM, TO) \
+#define REGISTER_MOVE_COST(MODE, FROM, TO) \
(TARGET_ARM ? \
((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 : \
(FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2) \
#define CALL_LONG 0x00000001 /* Always call indirect. */
#define CALL_SHORT 0x00000002 /* Never call indirect. */
-/* A C structure for machine-specific, per-function data. This is added
- to the cfun structure. */
-struct machine_function
+/* These bits describe the different types of function supported
+ by the ARM backend. They are exclusive. ie a function cannot be both a
+ normal function and an interworked function, for example. Knowing the
+ type of a function is important for determining its prologue and
+ epilogue sequences.
+ Note value 7 is currently unassigned. Also note that the interrupt
+ function types all have bit 2 set, so that they can be tested for easily.
+ Note that 0 is deliberately chosen for ARM_FT_UNKNOWN so that when the
+ machine_function structure is initialised (to zero) func_type will
+ default to unknown. This will force the first use of arm_current_func_type
+ to call arm_compute_func_type. */
+#define ARM_FT_UNKNOWN 0 /* Type has not yet been determined. */
+#define ARM_FT_NORMAL 1 /* Your normal, straightforward function. */
+#define ARM_FT_INTERWORKED 2 /* A function that supports interworking. */
+#define ARM_FT_EXCEPTION_HANDLER 3 /* A C++ exception handler. */
+#define ARM_FT_ISR 4 /* An interrupt service routine. */
+#define ARM_FT_FIQ 5 /* A fast interrupt service routine. */
+#define ARM_FT_EXCEPTION 6 /* An ARM exception handler (subcase of ISR). */
+
+#define ARM_FT_TYPE_MASK ((1 << 3) - 1)
+
+/* In addition functions can have several type modifiers,
+ outlined by these bit masks: */
+#define ARM_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR and above. */
+#define ARM_FT_NAKED (1 << 3) /* No prologue or epilogue. */
+#define ARM_FT_VOLATILE (1 << 4) /* Does not return. */
+#define ARM_FT_NESTED (1 << 5) /* Embedded inside another func. */
+
+/* Some macros to test these flags. */
+#define ARM_FUNC_TYPE(t) (t & ARM_FT_TYPE_MASK)
+#define IS_INTERRUPT(t) (t & ARM_FT_INTERRUPT)
+#define IS_VOLATILE(t) (t & ARM_FT_VOLATILE)
+#define IS_NAKED(t) (t & ARM_FT_NAKED)
+#define IS_NESTED(t) (t & ARM_FT_NESTED)
+
+/* A C structure for machine-specific, per-function data.
+ This is added to the cfun structure. */
+typedef struct machine_function
{
- /* Records __builtin_return address. */
- struct rtx_def *ra_rtx;
/* Additionsl stack adjustment in __builtin_eh_throw. */
struct rtx_def *eh_epilogue_sp_ofs;
/* Records if LR has to be saved for far jumps. */
int far_jump_used;
/* Records if ARG_POINTER was ever live. */
int arg_pointer_live;
-};
+ /* Records if the save of LR has been eliminated. */
+ int lr_save_eliminated;
+ /* Records the type of the current function. */
+ unsigned long func_type;
+}
+machine_function;
/* A C type for declaring a variable that is used as the first argument of
`FUNCTION_ARG' and other related values. For some target machines, the
/* 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) \
- ((REGNO) >= 0 && (REGNO) <= 3)
+#define FUNCTION_ARG_REGNO_P(REGNO) (IN_RANGE ((REGNO), 0, 3))
+
+\f
+/* Tail calling. */
+
+/* A C expression that evaluates to true if it is ok to perform a sibling
+ call to DECL. */
+#define FUNCTION_OK_FOR_SIBCALL(DECL) arm_function_ok_for_sibcall ((DECL))
/* Perform any actions needed for a function that is receiving a variable
number of arguments. CUM is as above. MODE and TYPE are the mode and type
(PRETEND_SIZE) = (NUM_ARG_REGS - (CUM).nregs) * UNITS_PER_WORD; \
}
-/* Generate assembly output for the start of a function. */
-#define FUNCTION_PROLOGUE(STREAM, SIZE) \
- do \
- { \
- if (TARGET_ARM) \
- output_arm_prologue (STREAM, SIZE); \
- else \
- output_thumb_prologue (STREAM); \
- } \
- while (0)
-
/* If your target environment doesn't prefix user functions with an
underscore, you may wish to re-define this to prevent any conflicts.
e.g. AOF may prefix mcount with an underscore. */
The ``mov ip,lr'' seems like a good idea to stick with cc convention.
``prof'' doesn't seem to mind about this! */
+#ifndef ARM_FUNCTION_PROFILER
#define ARM_FUNCTION_PROFILER(STREAM, LABELNO) \
{ \
char temp[20]; \
sym = gen_rtx (SYMBOL_REF, Pmode, temp); \
ASM_OUTPUT_INT (STREAM, sym); \
}
+#endif
#define THUMB_FUNCTION_PROFILER(STREAM, LABELNO) \
{ \
frame. */
#define EXIT_IGNORE_STACK 1
-/* Generate the assembly code for function exit. */
-#define FUNCTION_EPILOGUE(STREAM, SIZE) \
- output_func_epilogue (SIZE)
+#define EPILOGUE_USES(REGNO) (reload_completed && (REGNO) == LR_REGNUM)
/* Determine if the epilogue should be output as RTL.
You should override this if you define FUNCTION_EXTRA_EPILOGUE. */
/* Define the offset between two registers, one to be eliminated, and the
other its replacement, at the start of a routine. */
#define ARM_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-{ \
- int volatile_func = arm_volatile_func (); \
- if ((FROM) == ARG_POINTER_REGNUM && (TO) == HARD_FRAME_POINTER_REGNUM)\
- (OFFSET) = 0; \
- else if ((FROM) == FRAME_POINTER_REGNUM \
- && (TO) == STACK_POINTER_REGNUM) \
- (OFFSET) = current_function_outgoing_args_size \
- + ROUND_UP (get_frame_size ()); \
- else \
+ do \
{ \
- int regno; \
- int offset = 12; \
- int saved_hard_reg = 0; \
- \
- if (! volatile_func) \
- { \
- for (regno = 0; regno <= 10; regno++) \
- if (regs_ever_live[regno] && ! call_used_regs[regno]) \
- saved_hard_reg = 1, offset += 4; \
- if (! TARGET_APCS_FRAME \
- && ! frame_pointer_needed \
- && regs_ever_live[HARD_FRAME_POINTER_REGNUM] \
- && ! call_used_regs[HARD_FRAME_POINTER_REGNUM]) \
- saved_hard_reg = 1, offset += 4; \
- /* PIC register is a fixed reg, so call_used_regs set. */ \
- if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) \
- saved_hard_reg = 1, offset += 4; \
- for (regno = FIRST_ARM_FP_REGNUM; \
- regno <= LAST_ARM_FP_REGNUM; regno++) \
- if (regs_ever_live[regno] && ! call_used_regs[regno]) \
- offset += 12; \
- } \
- if ((FROM) == FRAME_POINTER_REGNUM) \
- (OFFSET) = - offset; \
- else \
- { \
- if (! frame_pointer_needed) \
- offset -= 16; \
- if (! volatile_func \
- && (regs_ever_live[LR_REGNUM] || saved_hard_reg)) \
- offset += 4; \
- offset += current_function_outgoing_args_size; \
- (OFFSET) = ROUND_UP (get_frame_size ()) + offset; \
- } \
+ (OFFSET) = arm_compute_initial_elimination_offset (FROM, TO); \
} \
-}
+ while (0)
/* Note: This macro must match the code in thumb_function_prologue(). */
#define THUMB_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
if (TARGET_ARM) \
- ARM_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET) \
+ ARM_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET); \
else \
THUMB_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET)
((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
/* On the ARM, don't allow the pc to be used. */
-#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
- (TARGET_THUMB ? \
- ( TEST_REGNO (REGNO, <=, LAST_LO_REGNUM) \
- || (GET_MODE_SIZE (MODE) >= 4 \
- && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM))) \
- :( \
- TEST_REGNO (REGNO, <, PC_REGNUM) \
- || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM) \
- || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM)))
-
-/* This is like REGNO_MODE_OF_FOR_BASE_P, except that in Thumb mode
- the stack pointer is always acceptable, hence the passing of SImode */
-#define REGNO_OK_FOR_BASE_P(REGNO) \
- REGNO_MODE_OK_FOR_BASE_P (REGNO, SImode)
-
-/* We play tricks with REGNO_MODE_OK... here, so that for ARM the macros
- are the same, but for Thumb only registers 0 - 7 are OK. */
+#define ARM_REGNO_OK_FOR_BASE_P(REGNO) \
+ (TEST_REGNO (REGNO, <, PC_REGNUM) \
+ || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM) \
+ || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM))
+
+#define THUMB_REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
+ (TEST_REGNO (REGNO, <=, LAST_LO_REGNUM) \
+ || (GET_MODE_SIZE (MODE) >= 4 \
+ && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM)))
+
+#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \
+ (TARGET_THUMB \
+ ? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE) \
+ : ARM_REGNO_OK_FOR_BASE_P (REGNO))
+
+/* For ARM code, we don't care about the mode, but for Thumb, the index
+ must be suitable for use in a QImode load. */
#define REGNO_OK_FOR_INDEX_P(REGNO) \
REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode)
`assemble_name' uses this. */
#undef ASM_OUTPUT_LABELREF
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
- fprintf (FILE, "%s%s", USER_LABEL_PREFIX, arm_strip_name_encoding (NAME))
+ asm_fprintf (FILE, "%U%s", arm_strip_name_encoding (NAME))
/* If we are referencing a function that is weak then encode a long call
flag in the function name, otherwise if the function is static or
The symbol REG_OK_STRICT causes the latter definition to be used. */
#ifndef REG_OK_STRICT
-#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
- (TARGET_THUMB ? \
- ( REGNO (X) <= LAST_LO_REGNUM \
- || REGNO (X) >= FIRST_PSEUDO_REGISTER \
- || (GET_MODE_SIZE (MODE) >= 4 \
- && (REGNO (X) == STACK_POINTER_REGNUM \
- || (X) == hard_frame_pointer_rtx \
- || (X) == arg_pointer_rtx))) \
- :( \
- REGNO (X) <= LAST_ARM_REGNUM \
- || REGNO (X) >= FIRST_PSEUDO_REGISTER \
- || REGNO (X) == FRAME_POINTER_REGNUM \
- || REGNO (X) == ARG_POINTER_REGNUM))
-
-/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) \
- REG_MODE_OK_FOR_BASE_P (X, SImode)
-
-/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg. On the Thumb, the stack pointer
- is not suitable. */
-#define REG_OK_FOR_INDEX_P(X) \
- REG_MODE_OK_FOR_BASE_P (X, QImode)
+#define ARM_REG_OK_FOR_BASE_P(X) \
+ (REGNO (X) <= LAST_ARM_REGNUM \
+ || REGNO (X) >= FIRST_PSEUDO_REGISTER \
+ || REGNO (X) == FRAME_POINTER_REGNUM \
+ || REGNO (X) == ARG_POINTER_REGNUM)
-/* Just like REG_OK_FOR_BASE_P except that we also allow the PC. */
-#define REG_OK_FOR_PRE_POST_P(X) \
- (REG_OK_FOR_BASE_P (X) || REGNO(X) == PC_REGNUM)
+#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
+ (REGNO (X) <= LAST_LO_REGNUM \
+ || REGNO (X) >= FIRST_PSEUDO_REGISTER \
+ || (GET_MODE_SIZE (MODE) >= 4 \
+ && (REGNO (X) == STACK_POINTER_REGNUM \
+ || (X) == hard_frame_pointer_rtx \
+ || (X) == arg_pointer_rtx)))
#else /* REG_OK_STRICT */
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+#define ARM_REG_OK_FOR_BASE_P(X) \
+ ARM_REGNO_OK_FOR_BASE_P (REGNO (X))
-/* Just like REG_OK_FOR_BASE_P except that we also allow the PC. */
-#define REG_OK_FOR_PRE_POST_P(X) \
- (REG_OK_FOR_BASE_P (X) || TEST_REGNO (REGNO (X), ==, PC_REGNUM))
+#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \
+ THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE)
#endif /* REG_OK_STRICT */
+
+/* Now define some helpers in terms of the above. */
+
+#define REG_MODE_OK_FOR_BASE_P(X, MODE) \
+ (TARGET_THUMB \
+ ? THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE) \
+ : ARM_REG_OK_FOR_BASE_P (X))
+
+#define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X)
+
+/* For Thumb, a valid index register is anything that can be used in
+ a byte load instruction. */
+#define THUMB_REG_OK_FOR_INDEX_P(X) THUMB_REG_MODE_OK_FOR_BASE_P (X, QImode)
+
+/* Nonzero if X is a hard reg that can be used as an index
+ or if it is a pseudo reg. On the Thumb, the stack pointer
+ is not suitable. */
+#define REG_OK_FOR_INDEX_P(X) \
+ (TARGET_THUMB \
+ ? THUMB_REG_OK_FOR_INDEX_P (X) \
+ : ARM_REG_OK_FOR_INDEX_P (X))
+
\f
/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
that is a valid memory address for an instruction.
The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */
/* --------------------------------arm version----------------------------- */
-#define BASE_REGISTER_RTX_P(X) \
- (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
+#define ARM_BASE_REGISTER_RTX_P(X) \
+ (GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X))
-#define INDEX_REGISTER_RTX_P(X) \
- (GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))
+#define ARM_INDEX_REGISTER_RTX_P(X) \
+ (GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X))
/* A C statement (sans semicolon) to jump to LABEL for legitimate index RTXs
used by the macro GO_IF_LEGITIMATE_ADDRESS. Floating point indices can
only be small constants. */
-#define GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \
- do \
- { \
- HOST_WIDE_INT range; \
- enum rtx_code code = GET_CODE (INDEX); \
- \
- if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
- { \
- if (code == CONST_INT && INTVAL (INDEX) < 1024 \
- && INTVAL (INDEX) > -1024 \
- && (INTVAL (INDEX) & 3) == 0) \
- goto LABEL; \
- } \
- else \
- { \
- if (INDEX_REGISTER_RTX_P (INDEX) && GET_MODE_SIZE (MODE) <= 4) \
- goto LABEL; \
- if (GET_MODE_SIZE (MODE) <= 4 && code == MULT \
- && (! arm_arch4 || (MODE) != HImode)) \
- { \
- rtx xiop0 = XEXP (INDEX, 0); \
- rtx xiop1 = XEXP (INDEX, 1); \
- if (INDEX_REGISTER_RTX_P (xiop0) \
- && power_of_two_operand (xiop1, SImode)) \
- goto LABEL; \
- if (INDEX_REGISTER_RTX_P (xiop1) \
- && power_of_two_operand (xiop0, SImode)) \
- goto LABEL; \
- } \
- if (GET_MODE_SIZE (MODE) <= 4 \
- && (code == LSHIFTRT || code == ASHIFTRT \
- || code == ASHIFT || code == ROTATERT) \
- && (! arm_arch4 || (MODE) != HImode)) \
- { \
- rtx op = XEXP (INDEX, 1); \
- if (INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \
- && GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \
- && INTVAL (op) <= 31) \
- goto LABEL; \
- } \
- /* NASTY: Since this limits the addressing of unsigned byte loads */ \
- range = ((MODE) == HImode || (MODE) == QImode) \
- ? (arm_arch4 ? 256 : 4095) : 4096; \
- if (code == CONST_INT && INTVAL (INDEX) < range \
- && INTVAL (INDEX) > -range) \
- goto LABEL; \
- } \
- } \
+#define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \
+ do \
+ { \
+ HOST_WIDE_INT range; \
+ enum rtx_code code = GET_CODE (INDEX); \
+ \
+ if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
+ { \
+ if (code == CONST_INT && INTVAL (INDEX) < 1024 \
+ && INTVAL (INDEX) > -1024 \
+ && (INTVAL (INDEX) & 3) == 0) \
+ goto LABEL; \
+ } \
+ else \
+ { \
+ if (ARM_INDEX_REGISTER_RTX_P (INDEX) \
+ && GET_MODE_SIZE (MODE) <= 4) \
+ goto LABEL; \
+ if (GET_MODE_SIZE (MODE) <= 4 && code == MULT \
+ && (! arm_arch4 || (MODE) != HImode)) \
+ { \
+ rtx xiop0 = XEXP (INDEX, 0); \
+ rtx xiop1 = XEXP (INDEX, 1); \
+ if (ARM_INDEX_REGISTER_RTX_P (xiop0) \
+ && power_of_two_operand (xiop1, SImode)) \
+ goto LABEL; \
+ if (ARM_INDEX_REGISTER_RTX_P (xiop1) \
+ && power_of_two_operand (xiop0, SImode)) \
+ goto LABEL; \
+ } \
+ if (GET_MODE_SIZE (MODE) <= 4 \
+ && (code == LSHIFTRT || code == ASHIFTRT \
+ || code == ASHIFT || code == ROTATERT) \
+ && (! arm_arch4 || (MODE) != HImode)) \
+ { \
+ rtx op = XEXP (INDEX, 1); \
+ if (ARM_INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \
+ && GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \
+ && INTVAL (op) <= 31) \
+ goto LABEL; \
+ } \
+ /* NASTY: Since this limits the addressing of unsigned \
+ byte loads. */ \
+ range = ((MODE) == HImode || (MODE) == QImode) \
+ ? (arm_arch4 ? 256 : 4095) : 4096; \
+ if (code == CONST_INT && INTVAL (INDEX) < range \
+ && INTVAL (INDEX) > -range) \
+ goto LABEL; \
+ } \
+ } \
while (0)
-/* Jump to LABEL if X is a valid address RTX. This must also take
- REG_OK_STRICT into account when deciding about valid registers, but it uses
- the above macros so we are in luck. Allow REG, REG+REG, REG+INDEX,
- INDEX+REG, REG-INDEX, and non floating SYMBOL_REF to the constant pool.
- Allow REG-only and AUTINC-REG if handling TImode or HImode. Other symbol
- refs must be forced though a static cell to ensure addressability. */
-#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
+/* Jump to LABEL if X is a valid address RTX. This must take
+ REG_OK_STRICT into account when deciding about valid registers.
+
+ Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non
+ floating SYMBOL_REF to the constant pool. Allow REG-only and
+ AUTINC-REG if handling TImode or HImode. Other symbol refs must be
+ forced though a static cell to ensure addressability. */
+#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
{ \
- if (BASE_REGISTER_RTX_P (X)) \
+ if (ARM_BASE_REGISTER_RTX_P (X)) \
goto LABEL; \
else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \
&& GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \
+ && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
goto LABEL; \
else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \
&& (GET_CODE (X) == LABEL_REF \
else if ((MODE) == TImode) \
; \
else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode)) \
- { \
- if (GET_CODE (X) == PLUS && BASE_REGISTER_RTX_P (XEXP (X, 0)) \
- && GET_CODE (XEXP (X, 1)) == CONST_INT) \
- { \
- HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
+ { \
+ if (GET_CODE (X) == PLUS && ARM_BASE_REGISTER_RTX_P (XEXP (X, 0)) \
+ && GET_CODE (XEXP (X, 1)) == CONST_INT) \
+ { \
+ HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \
if (val == 4 || val == -4 || val == -8) \
goto LABEL; \
} \
rtx xop0 = XEXP (X, 0); \
rtx xop1 = XEXP (X, 1); \
\
- if (BASE_REGISTER_RTX_P (xop0)) \
- GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \
- else if (BASE_REGISTER_RTX_P (xop1)) \
- GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \
+ if (ARM_BASE_REGISTER_RTX_P (xop0)) \
+ ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \
+ else if (ARM_BASE_REGISTER_RTX_P (xop1)) \
+ ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \
} \
/* Reload currently can't handle MINUS, so disable this for now */ \
/* else if (GET_CODE (X) == MINUS) \
rtx xop0 = XEXP (X,0); \
rtx xop1 = XEXP (X,1); \
\
- if (BASE_REGISTER_RTX_P (xop0)) \
- GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL); \
+ if (ARM_BASE_REGISTER_RTX_P (xop0)) \
+ ARM_GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL); \
} */ \
else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \
&& GET_CODE (X) == SYMBOL_REF \
else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \
&& (GET_MODE_SIZE (MODE) <= 4) \
&& GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_PRE_POST_P (XEXP (X, 0))) \
+ && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \
goto LABEL; \
}
/* ---------------------thumb version----------------------------------*/
-#define LEGITIMATE_OFFSET(MODE, VAL) \
+#define THUMB_LEGITIMATE_OFFSET(MODE, VAL) \
(GET_MODE_SIZE (MODE) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32) \
: GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64 \
&& ((VAL) & 1) == 0) \
better ways to solve some of these problems. */
/* Although it is not incorrect, we don't accept QImode and HImode
- addresses based on the frame pointer or arg pointer until the reload pass starts.
- This is so that eliminating such addresses into stack based ones
- won't produce impossible code. */
+ addresses based on the frame pointer or arg pointer until the
+ reload pass starts. This is so that eliminating such addresses
+ into stack based ones won't produce impossible code. */
#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \
{ \
/* ??? Not clear if this is right. Experiment. */ \
|| reg_mentioned_p (virtual_stack_vars_rtx, X))) \
; \
/* Accept any base register. SP only in SImode or larger. */ \
- else if (GET_CODE (X) == REG && REG_MODE_OK_FOR_BASE_P (X, MODE)) \
+ else if (GET_CODE (X) == REG \
+ && THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE)) \
goto WIN; \
/* This is PC relative data before MACHINE_DEPENDENT_REORG runs. */ \
else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \
/* Post-inc indexing only supported for SImode and larger. */ \
else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4 \
&& GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_INDEX_P (XEXP (X, 0))) \
+ && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))) \
goto WIN; \
else if (GET_CODE (X) == PLUS) \
{ \
&& XEXP (X, 1) != frame_pointer_rtx \
&& XEXP (X, 0) != virtual_stack_vars_rtx \
&& XEXP (X, 1) != virtual_stack_vars_rtx \
- && REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
- && REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
+ && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
+ && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1))) \
goto WIN; \
/* REG+const has 5-7 bit offset for non-SP registers. */ \
else if (GET_CODE (XEXP (X, 0)) == REG \
- && (REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
+ && (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \
|| XEXP (X, 0) == arg_pointer_rtx) \
&& GET_CODE (XEXP (X, 1)) == CONST_INT \
- && LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
+ && THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \
goto WIN; \
/* REG+const has 10 bit offset for SP, but only SImode and \
larger is supported. */ \
xop0 = force_reg (SImode, xop0); \
if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
xop1 = force_reg (SImode, xop1); \
- if (BASE_REGISTER_RTX_P (xop0) && GET_CODE (xop1) == CONST_INT) \
+ if (ARM_BASE_REGISTER_RTX_P (xop0) \
+ && GET_CODE (xop1) == CONST_INT) \
{ \
HOST_WIDE_INT n, low_n; \
rtx base_reg, val; \
in one reasonably fast instruction. */
#define MOVE_MAX 4
+#undef MOVE_RATIO
+#define MOVE_RATIO (arm_is_xscale ? 4 : 2)
+
/* Define if operations between registers always perform the operation
on the full register even if a narrower mode is specified. */
#define WORD_REGISTER_OPERATIONS
conditional instructions */
#define BRANCH_COST \
(TARGET_ARM ? 4 : (optimize > 1 ? 1 : 0))
-
-/* A C statement to update the variable COST based on the relationship
- between INSN that is dependent on DEP through dependence LINK. */
-#define ADJUST_COST(INSN, LINK, DEP, COST) \
- (COST) = arm_adjust_cost (INSN, LINK, DEP, COST)
\f
/* Position Independent Code. */
/* We decide which register to use based on the compilation options and
data addresses in memory. */
#define PIC_OFFSET_TABLE_REGNUM arm_pic_register
-#define FINALIZE_PIC arm_finalize_pic ()
+#define FINALIZE_PIC arm_finalize_pic (1)
/* We can't directly access anything that contains a symbol,
nor can we indirect via the constant pool. */
offset. */
extern int making_const_table;
\f
-/* If defined, a C expression whose value is nonzero if IDENTIFIER
- with arguments ARGS is a valid machine specific attribute for TYPE.
- The attributes in ATTRIBUTES have previously been assigned to TYPE. */
-#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \
- (arm_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
-
-/* If defined, a C expression whose value is zero if the attributes on
- TYPE1 and TYPE2 are incompatible, one if they are compatible, and
- two if they are nearly compatible (which causes a warning to be
- generated). */
-#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
- (arm_comp_type_attributes (TYPE1, TYPE2))
-
-/* If defined, a C statement that assigns default attributes to newly
- defined TYPE. */
-#define SET_DEFAULT_TYPE_ATTRIBUTES(TYPE) \
- arm_set_default_type_attributes (TYPE)
-
/* Handle pragmas for compatibility with Intel's compilers. */
-#define HANDLE_PRAGMA(GET, UNGET, NAME) arm_process_pragma (GET, UNGET, NAME)
-\f
+#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
+ cpp_register_pragma (PFILE, 0, "long_calls", arm_pr_long_calls); \
+ cpp_register_pragma (PFILE, 0, "no_long_calls", arm_pr_no_long_calls); \
+ cpp_register_pragma (PFILE, 0, "long_calls_off", arm_pr_long_calls_off); \
+} while (0)
+
/* Condition code information. */
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
return the mode to be used for the comparison.
/* This is how to output a label which precedes a jumptable. Since
Thumb instructions are 2 bytes, we may need explicit alignment here. */
+#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \
do \
{ \
#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL1, DECL2) \
do \
{ \
- char * LABEL1 = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
- char * LABEL2 = IDENTIFIER_POINTER (DECL2); \
+ const char *const LABEL1 = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
+ const char *const LABEL2 = IDENTIFIER_POINTER (DECL2); \
\
if (TARGET_THUMB && TREE_CODE (DECL1) == FUNCTION_DECL) \
{ \
} \
while (0)
-/* Target characters. */
-#define TARGET_BELL 007
-#define TARGET_BS 010
-#define TARGET_TAB 011
-#define TARGET_NEWLINE 012
-#define TARGET_VT 013
-#define TARGET_FF 014
-#define TARGET_CR 015
+#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN
+/* To support -falign-* switches we need to use .p2align so
+ that alignment directives in code sections will be padded
+ with no-op instructions, rather than zeroes. */
+#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \
+ if ((LOG) != 0) \
+ { \
+ if ((MAX_SKIP) == 0) \
+ fprintf ((FILE), "\t.p2align %d\n", (LOG)); \
+ else \
+ fprintf ((FILE), "\t.p2align %d,,%d\n", \
+ (LOG), (MAX_SKIP)); \
+ }
+#endif
\f
/* Only perform branch elimination (by making instructions conditional) if
we're optimising. Otherwise it's of no use anyway. */
#define PRINT_OPERAND(STREAM, X, CODE) \
arm_print_operand (STREAM, X, CODE)
-/* Create an [unsigned] host sized integer declaration that
- avoids compiler warnings. */
-#ifdef __STDC__
-#define HOST_INT(x) ((signed HOST_WIDE_INT) x##UL)
-#define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x##UL)
-#else
-#define HOST_INT(x) ((HOST_WIDE_INT) x)
-#define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x)
-#endif
-
-#define ARM_SIGN_EXTEND(x) ((HOST_WIDE_INT) \
- (HOST_BITS_PER_WIDE_INT <= 32 ? (x) \
- : (((x) & HOST_UINT (0xffffffff)) | \
- (((x) & HOST_UINT (0x80000000)) \
- ? ((~ HOST_INT (0)) \
- & ~ HOST_UINT(0xffffffff)) \
+#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)(x)) & (unsigned HOST_WIDE_INT) 0x80000000) \
+ ? ((~ (unsigned HOST_WIDE_INT) 0) \
+ & ~ (unsigned HOST_WIDE_INT) 0xffffffff) \
: 0))))
/* Output the address of an operand. */
else \
THUMB_PRINT_OPERAND_ADDRESS (STREAM, X)
-/* Handles PIC addr specially */
#define OUTPUT_INT_ADDR_CONST(STREAM, X) \
{ \
- if (flag_pic && GET_CODE (X) == CONST && is_pic (X)) \
- { \
- output_addr_const (STREAM, XEXP (XEXP (XEXP (X, 0), 0), 0)); \
- fputs (" - (", STREAM); \
- output_addr_const (STREAM, XEXP (XEXP (XEXP (X, 0), 1), 0)); \
- fputs (")", STREAM); \
- } \
- else \
- output_addr_const (STREAM, X); \
+ output_addr_const (STREAM, X); \
\
/* Mark symbols as position independent. We only do this in the \
.text segment, not in the .data segment. */ \
do \
{ \
int mi_delta = (DELTA); \
- const char * mi_op = mi_delta < 0 ? "sub" : "add"; \
+ const char *const mi_op = mi_delta < 0 ? "sub" : "add"; \
int shift = 0; \
int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) \
? 1 : 0); \
/* Define the codes that are matched by predicates in arm.c */
#define PREDICATE_CODES \
{"s_register_operand", {SUBREG, REG}}, \
+ {"arm_hard_register_operand", {REG}}, \
{"f_register_operand", {SUBREG, REG}}, \
{"arm_add_operand", {SUBREG, REG, CONST_INT}}, \
{"fpu_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \
{"load_multiple_operation", {PARALLEL}}, \
{"store_multiple_operation", {PARALLEL}}, \
{"equality_operator", {EQ, NE}}, \
+ {"arm_comparison_operator", {EQ, NE, LE, LT, GE, GT, GEU, GTU, LEU, \
+ LTU, UNORDERED, ORDERED, UNLT, UNLE, \
+ UNGE, UNGT}}, \
{"arm_rhsm_operand", {SUBREG, REG, CONST_INT, MEM}}, \
{"const_shift_operand", {CONST_INT}}, \
{"multi_register_push", {PARALLEL}}, \
#define SPECIAL_MODE_PREDICATES \
"cc_register", "dominant_cc_register",
-#endif /* __ARM_H__ */
+enum arm_builtins
+{
+ ARM_BUILTIN_CLZ,
+ ARM_BUILTIN_PREFETCH,
+ ARM_BUILTIN_MAX
+};
+#endif /* ! GCC_ARM_H */