arm.h revision 104752
190075Sobrien/* Definitions of target machine for GNU compiler, for ARM. 290075Sobrien Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 390075Sobrien 2001, 2002 Free Software Foundation, Inc. 490075Sobrien Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) 590075Sobrien and Martin Simmons (@harleqn.co.uk). 690075Sobrien More major hacks by Richard Earnshaw (rearnsha@arm.com) 790075Sobrien Minor hacks by Nick Clifton (nickc@cygnus.com) 890075Sobrien 990075SobrienThis file is part of GNU CC. 1090075Sobrien 1190075SobrienGNU CC is free software; you can redistribute it and/or modify 1290075Sobrienit under the terms of the GNU General Public License as published by 1390075Sobrienthe Free Software Foundation; either version 2, or (at your option) 1490075Sobrienany later version. 1590075Sobrien 1690075SobrienGNU CC is distributed in the hope that it will be useful, 1790075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1890075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1990075SobrienGNU General Public License for more details. 2090075Sobrien 2190075SobrienYou should have received a copy of the GNU General Public License 2290075Sobrienalong with GNU CC; see the file COPYING. If not, write to 2390075Sobrienthe Free Software Foundation, 59 Temple Place - Suite 330, 2490075SobrienBoston, MA 02111-1307, USA. */ 2590075Sobrien 2690075Sobrien#ifndef GCC_ARM_H 2790075Sobrien#define GCC_ARM_H 2890075Sobrien 2990075Sobrien#define TARGET_CPU_arm2 0x0000 3090075Sobrien#define TARGET_CPU_arm250 0x0000 3190075Sobrien#define TARGET_CPU_arm3 0x0000 3290075Sobrien#define TARGET_CPU_arm6 0x0001 3390075Sobrien#define TARGET_CPU_arm600 0x0001 3490075Sobrien#define TARGET_CPU_arm610 0x0002 3590075Sobrien#define TARGET_CPU_arm7 0x0001 3690075Sobrien#define TARGET_CPU_arm7m 0x0004 3790075Sobrien#define TARGET_CPU_arm7dm 0x0004 3890075Sobrien#define TARGET_CPU_arm7dmi 0x0004 3990075Sobrien#define TARGET_CPU_arm700 0x0001 4090075Sobrien#define TARGET_CPU_arm710 0x0002 4190075Sobrien#define TARGET_CPU_arm7100 0x0002 4290075Sobrien#define TARGET_CPU_arm7500 0x0002 4390075Sobrien#define TARGET_CPU_arm7500fe 0x1001 4490075Sobrien#define TARGET_CPU_arm7tdmi 0x0008 4590075Sobrien#define TARGET_CPU_arm8 0x0010 4690075Sobrien#define TARGET_CPU_arm810 0x0020 4790075Sobrien#define TARGET_CPU_strongarm 0x0040 4890075Sobrien#define TARGET_CPU_strongarm110 0x0040 4990075Sobrien#define TARGET_CPU_strongarm1100 0x0040 5090075Sobrien#define TARGET_CPU_arm9 0x0080 5190075Sobrien#define TARGET_CPU_arm9tdmi 0x0080 5290075Sobrien#define TARGET_CPU_xscale 0x0100 5390075Sobrien/* Configure didn't specify. */ 5490075Sobrien#define TARGET_CPU_generic 0x8000 5590075Sobrien 5690075Sobrientypedef enum arm_cond_code 5790075Sobrien{ 5890075Sobrien ARM_EQ = 0, ARM_NE, ARM_CS, ARM_CC, ARM_MI, ARM_PL, ARM_VS, ARM_VC, 5990075Sobrien ARM_HI, ARM_LS, ARM_GE, ARM_LT, ARM_GT, ARM_LE, ARM_AL, ARM_NV 6090075Sobrien} 6190075Sobrienarm_cc; 6290075Sobrien 6390075Sobrienextern arm_cc arm_current_cc; 6490075Sobrien 6590075Sobrien#define ARM_INVERSE_CONDITION_CODE(X) ((arm_cc) (((int)X) ^ 1)) 6690075Sobrien 6790075Sobrienextern int arm_target_label; 6890075Sobrienextern int arm_ccfsm_state; 6990075Sobrienextern struct rtx_def * arm_target_insn; 7090075Sobrien/* Run-time compilation parameters selecting different hardware subsets. */ 7190075Sobrienextern int target_flags; 7290075Sobrien/* The floating point instruction architecture, can be 2 or 3 */ 7390075Sobrienextern const char * target_fp_name; 7490075Sobrien/* Define the information needed to generate branch insns. This is 7590075Sobrien stored from the compare operation. Note that we can't use "rtx" here 7690075Sobrien since it hasn't been defined! */ 7790075Sobrienextern struct rtx_def * arm_compare_op0; 7890075Sobrienextern struct rtx_def * arm_compare_op1; 7990075Sobrien/* The label of the current constant pool. */ 8090075Sobrienextern struct rtx_def * pool_vector_label; 8190075Sobrien/* Set to 1 when a return insn is output, this means that the epilogue 8290075Sobrien is not needed. */ 8390075Sobrienextern int return_used_this_function; 8490075Sobrien 8590075Sobrien/* Just in case configure has failed to define anything. */ 8690075Sobrien#ifndef TARGET_CPU_DEFAULT 8790075Sobrien#define TARGET_CPU_DEFAULT TARGET_CPU_generic 8890075Sobrien#endif 8990075Sobrien 9090075Sobrien/* If the configuration file doesn't specify the cpu, the subtarget may 9190075Sobrien override it. If it doesn't, then default to an ARM6. */ 9290075Sobrien#if TARGET_CPU_DEFAULT == TARGET_CPU_generic 9390075Sobrien#undef TARGET_CPU_DEFAULT 9490075Sobrien 9590075Sobrien#ifdef SUBTARGET_CPU_DEFAULT 9690075Sobrien#define TARGET_CPU_DEFAULT SUBTARGET_CPU_DEFAULT 9790075Sobrien#else 9890075Sobrien#define TARGET_CPU_DEFAULT TARGET_CPU_arm6 9990075Sobrien#endif 10090075Sobrien#endif 10190075Sobrien 10290075Sobrien#if TARGET_CPU_DEFAULT == TARGET_CPU_arm2 10390075Sobrien#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_2__" 10490075Sobrien#else 10590075Sobrien#if TARGET_CPU_DEFAULT == TARGET_CPU_arm6 || TARGET_CPU_DEFAULT == TARGET_CPU_arm610 || TARGET_CPU_DEFAULT == TARGET_CPU_arm7500fe 10690075Sobrien#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3__" 10790075Sobrien#else 10890075Sobrien#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m 10990075Sobrien#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__" 11090075Sobrien#else 11190075Sobrien#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi || TARGET_CPU_DEFAULT == TARGET_CPU_arm9 || TARGET_CPU_DEFAULT == TARGET_CPU_arm9tdmi 11290075Sobrien#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__" 11390075Sobrien#else 11490075Sobrien#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 11590075Sobrien#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4__" 11690075Sobrien#else 11790075Sobrien#if TARGET_CPU_DEFAULT == TARGET_CPU_xscale 11890075Sobrien#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_5TE__ -D__XSCALE__" 11990075Sobrien#else 12090075SobrienUnrecognized value in TARGET_CPU_DEFAULT. 12190075Sobrien#endif 12290075Sobrien#endif 12390075Sobrien#endif 12490075Sobrien#endif 12590075Sobrien#endif 12690075Sobrien#endif 12790075Sobrien 12890075Sobrien#undef CPP_SPEC 12990075Sobrien#define CPP_SPEC "\ 13090075Sobrien%(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) \ 13190075Sobrien%(cpp_endian) %(subtarget_cpp_spec) %(cpp_isa) %(cpp_interwork)" 13290075Sobrien 13390075Sobrien#define CPP_ISA_SPEC "%{mthumb:-D__thumb__} %{!mthumb:-D__arm__}" 13490075Sobrien 13590075Sobrien/* Set the architecture define -- if -march= is set, then it overrides 13690075Sobrien the -mcpu= setting. */ 13790075Sobrien#define CPP_CPU_ARCH_SPEC "\ 13890075Sobrien-Acpu=arm -Amachine=arm \ 13990075Sobrien%{march=arm2:-D__ARM_ARCH_2__} \ 14090075Sobrien%{march=arm250:-D__ARM_ARCH_2__} \ 14190075Sobrien%{march=arm3:-D__ARM_ARCH_2__} \ 14290075Sobrien%{march=arm6:-D__ARM_ARCH_3__} \ 14390075Sobrien%{march=arm600:-D__ARM_ARCH_3__} \ 14490075Sobrien%{march=arm610:-D__ARM_ARCH_3__} \ 14590075Sobrien%{march=arm7:-D__ARM_ARCH_3__} \ 14690075Sobrien%{march=arm700:-D__ARM_ARCH_3__} \ 14790075Sobrien%{march=arm710:-D__ARM_ARCH_3__} \ 14890075Sobrien%{march=arm720:-D__ARM_ARCH_3__} \ 14990075Sobrien%{march=arm7100:-D__ARM_ARCH_3__} \ 15090075Sobrien%{march=arm7500:-D__ARM_ARCH_3__} \ 15190075Sobrien%{march=arm7500fe:-D__ARM_ARCH_3__} \ 15290075Sobrien%{march=arm7m:-D__ARM_ARCH_3M__} \ 15390075Sobrien%{march=arm7dm:-D__ARM_ARCH_3M__} \ 15490075Sobrien%{march=arm7dmi:-D__ARM_ARCH_3M__} \ 15590075Sobrien%{march=arm7tdmi:-D__ARM_ARCH_4T__} \ 15690075Sobrien%{march=arm8:-D__ARM_ARCH_4__} \ 15790075Sobrien%{march=arm810:-D__ARM_ARCH_4__} \ 15890075Sobrien%{march=arm9:-D__ARM_ARCH_4T__} \ 15990075Sobrien%{march=arm920:-D__ARM_ARCH_4__} \ 16090075Sobrien%{march=arm920t:-D__ARM_ARCH_4T__} \ 16190075Sobrien%{march=arm9tdmi:-D__ARM_ARCH_4T__} \ 16290075Sobrien%{march=strongarm:-D__ARM_ARCH_4__} \ 16390075Sobrien%{march=strongarm110:-D__ARM_ARCH_4__} \ 16490075Sobrien%{march=strongarm1100:-D__ARM_ARCH_4__} \ 16590075Sobrien%{march=xscale:-D__ARM_ARCH_5TE__} \ 16690075Sobrien%{march=xscale:-D__XSCALE__} \ 16790075Sobrien%{march=armv2:-D__ARM_ARCH_2__} \ 16890075Sobrien%{march=armv2a:-D__ARM_ARCH_2__} \ 16990075Sobrien%{march=armv3:-D__ARM_ARCH_3__} \ 17090075Sobrien%{march=armv3m:-D__ARM_ARCH_3M__} \ 17190075Sobrien%{march=armv4:-D__ARM_ARCH_4__} \ 17290075Sobrien%{march=armv4t:-D__ARM_ARCH_4T__} \ 17390075Sobrien%{march=armv5:-D__ARM_ARCH_5__} \ 17490075Sobrien%{march=armv5t:-D__ARM_ARCH_5T__} \ 17590075Sobrien%{march=armv5e:-D__ARM_ARCH_5E__} \ 17690075Sobrien%{march=armv5te:-D__ARM_ARCH_5TE__} \ 17790075Sobrien%{!march=*: \ 17890075Sobrien %{mcpu=arm2:-D__ARM_ARCH_2__} \ 17990075Sobrien %{mcpu=arm250:-D__ARM_ARCH_2__} \ 18090075Sobrien %{mcpu=arm3:-D__ARM_ARCH_2__} \ 18190075Sobrien %{mcpu=arm6:-D__ARM_ARCH_3__} \ 18290075Sobrien %{mcpu=arm600:-D__ARM_ARCH_3__} \ 18390075Sobrien %{mcpu=arm610:-D__ARM_ARCH_3__} \ 18490075Sobrien %{mcpu=arm7:-D__ARM_ARCH_3__} \ 18590075Sobrien %{mcpu=arm700:-D__ARM_ARCH_3__} \ 18690075Sobrien %{mcpu=arm710:-D__ARM_ARCH_3__} \ 18790075Sobrien %{mcpu=arm720:-D__ARM_ARCH_3__} \ 18890075Sobrien %{mcpu=arm7100:-D__ARM_ARCH_3__} \ 18990075Sobrien %{mcpu=arm7500:-D__ARM_ARCH_3__} \ 19090075Sobrien %{mcpu=arm7500fe:-D__ARM_ARCH_3__} \ 19190075Sobrien %{mcpu=arm7m:-D__ARM_ARCH_3M__} \ 19290075Sobrien %{mcpu=arm7dm:-D__ARM_ARCH_3M__} \ 19390075Sobrien %{mcpu=arm7dmi:-D__ARM_ARCH_3M__} \ 19490075Sobrien %{mcpu=arm7tdmi:-D__ARM_ARCH_4T__} \ 19590075Sobrien %{mcpu=arm8:-D__ARM_ARCH_4__} \ 19690075Sobrien %{mcpu=arm810:-D__ARM_ARCH_4__} \ 19790075Sobrien %{mcpu=arm9:-D__ARM_ARCH_4T__} \ 19890075Sobrien %{mcpu=arm920:-D__ARM_ARCH_4__} \ 19990075Sobrien %{mcpu=arm920t:-D__ARM_ARCH_4T__} \ 20090075Sobrien %{mcpu=arm9tdmi:-D__ARM_ARCH_4T__} \ 20190075Sobrien %{mcpu=strongarm:-D__ARM_ARCH_4__} \ 20290075Sobrien %{mcpu=strongarm110:-D__ARM_ARCH_4__} \ 20390075Sobrien %{mcpu=strongarm1100:-D__ARM_ARCH_4__} \ 20490075Sobrien %{mcpu=xscale:-D__ARM_ARCH_5TE__} \ 20590075Sobrien %{mcpu=xscale:-D__XSCALE__} \ 20690075Sobrien %{!mcpu*:%(cpp_cpu_arch_default)}} \ 20790075Sobrien" 20890075Sobrien 20990075Sobrien/* Define __APCS_26__ if the PC also contains the PSR */ 21090075Sobrien#define CPP_APCS_PC_SPEC "\ 21190075Sobrien%{mapcs-32:%{mapcs-26:%e-mapcs-26 and -mapcs-32 may not be used together} \ 21290075Sobrien -D__APCS_32__} \ 21390075Sobrien%{mapcs-26:-D__APCS_26__} \ 21490075Sobrien%{!mapcs-32: %{!mapcs-26:%(cpp_apcs_pc_default)}} \ 21590075Sobrien" 21690075Sobrien 21790075Sobrien#ifndef CPP_APCS_PC_DEFAULT_SPEC 21890075Sobrien#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_26__" 21990075Sobrien#endif 22090075Sobrien 22190075Sobrien#define CPP_FLOAT_SPEC "\ 22290075Sobrien%{msoft-float:\ 22390075Sobrien %{mhard-float:%e-msoft-float and -mhard_float may not be used together} \ 22490075Sobrien -D__SOFTFP__} \ 22590075Sobrien%{!mhard-float:%{!msoft-float:%(cpp_float_default)}} \ 22690075Sobrien" 22790075Sobrien 22890075Sobrien/* Default is hard float, which doesn't define anything */ 22990075Sobrien#define CPP_FLOAT_DEFAULT_SPEC "" 23090075Sobrien 23190075Sobrien#define CPP_ENDIAN_SPEC "\ 23290075Sobrien%{mbig-endian: \ 23390075Sobrien %{mlittle-endian: \ 23490075Sobrien %e-mbig-endian and -mlittle-endian may not be used together} \ 23590075Sobrien -D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__} %{mthumb:-D__THUMBEB__}}\ 23690075Sobrien%{mlittle-endian:-D__ARMEL__ %{mthumb:-D__THUMBEL__}} \ 23790075Sobrien%{!mlittle-endian:%{!mbig-endian:%(cpp_endian_default)}} \ 23890075Sobrien" 23990075Sobrien 24090075Sobrien/* Default is little endian. */ 24190075Sobrien#define CPP_ENDIAN_DEFAULT_SPEC "-D__ARMEL__ %{mthumb:-D__THUMBEL__}" 24290075Sobrien 24390075Sobrien/* Add a define for interworking. Needed when building libgcc.a. 24490075Sobrien This must define __THUMB_INTERWORK__ to the pre-processor if 24590075Sobrien interworking is enabled by default. */ 24690075Sobrien#ifndef CPP_INTERWORK_DEFAULT_SPEC 24790075Sobrien#define CPP_INTERWORK_DEFAULT_SPEC "" 24890075Sobrien#endif 24990075Sobrien 25090075Sobrien#define CPP_INTERWORK_SPEC " \ 25190075Sobrien%{mthumb-interwork: \ 25290075Sobrien %{mno-thumb-interwork: %eincompatible interworking options} \ 25390075Sobrien -D__THUMB_INTERWORK__} \ 25490075Sobrien%{!mthumb-interwork:%{!mno-thumb-interwork:%(cpp_interwork_default)}} \ 25590075Sobrien" 25690075Sobrien 25790075Sobrien#ifndef CPP_PREDEFINES 25890075Sobrien#define CPP_PREDEFINES "" 25990075Sobrien#endif 26090075Sobrien 26190075Sobrien#ifndef CC1_SPEC 26290075Sobrien#define CC1_SPEC "" 26390075Sobrien#endif 26490075Sobrien 26590075Sobrien/* This macro defines names of additional specifications to put in the specs 26690075Sobrien that can be used in various specifications like CC1_SPEC. Its definition 26790075Sobrien is an initializer with a subgrouping for each command option. 26890075Sobrien 26990075Sobrien Each subgrouping contains a string constant, that defines the 27090075Sobrien specification name, and a string constant that used by the GNU CC driver 27190075Sobrien program. 27290075Sobrien 27390075Sobrien Do not define this macro if it does not need to do anything. */ 27490075Sobrien#define EXTRA_SPECS \ 27590075Sobrien { "cpp_cpu_arch", CPP_CPU_ARCH_SPEC }, \ 27690075Sobrien { "cpp_cpu_arch_default", CPP_ARCH_DEFAULT_SPEC }, \ 27790075Sobrien { "cpp_apcs_pc", CPP_APCS_PC_SPEC }, \ 27890075Sobrien { "cpp_apcs_pc_default", CPP_APCS_PC_DEFAULT_SPEC }, \ 27990075Sobrien { "cpp_float", CPP_FLOAT_SPEC }, \ 28090075Sobrien { "cpp_float_default", CPP_FLOAT_DEFAULT_SPEC }, \ 28190075Sobrien { "cpp_endian", CPP_ENDIAN_SPEC }, \ 28290075Sobrien { "cpp_endian_default", CPP_ENDIAN_DEFAULT_SPEC }, \ 28390075Sobrien { "cpp_isa", CPP_ISA_SPEC }, \ 28490075Sobrien { "cpp_interwork", CPP_INTERWORK_SPEC }, \ 28590075Sobrien { "cpp_interwork_default", CPP_INTERWORK_DEFAULT_SPEC }, \ 28690075Sobrien { "subtarget_cpp_spec", SUBTARGET_CPP_SPEC }, \ 28790075Sobrien SUBTARGET_EXTRA_SPECS 28890075Sobrien 28990075Sobrien#ifndef SUBTARGET_EXTRA_SPECS 29090075Sobrien#define SUBTARGET_EXTRA_SPECS 29190075Sobrien#endif 29290075Sobrien 29390075Sobrien#ifndef SUBTARGET_CPP_SPEC 29490075Sobrien#define SUBTARGET_CPP_SPEC "" 29590075Sobrien#endif 29690075Sobrien 29790075Sobrien/* Run-time Target Specification. */ 29890075Sobrien#ifndef TARGET_VERSION 29990075Sobrien#define TARGET_VERSION fputs (" (ARM/generic)", stderr); 30090075Sobrien#endif 30190075Sobrien 30290075Sobrien/* Nonzero if the function prologue (and epilogue) should obey 30390075Sobrien the ARM Procedure Call Standard. */ 30490075Sobrien#define ARM_FLAG_APCS_FRAME (1 << 0) 30590075Sobrien 30690075Sobrien/* Nonzero if the function prologue should output the function name to enable 30790075Sobrien the post mortem debugger to print a backtrace (very useful on RISCOS, 30890075Sobrien unused on RISCiX). Specifying this flag also enables 30990075Sobrien -fno-omit-frame-pointer. 31090075Sobrien XXX Must still be implemented in the prologue. */ 31190075Sobrien#define ARM_FLAG_POKE (1 << 1) 31290075Sobrien 31390075Sobrien/* Nonzero if floating point instructions are emulated by the FPE, in which 31490075Sobrien case instruction scheduling becomes very uninteresting. */ 31590075Sobrien#define ARM_FLAG_FPE (1 << 2) 31690075Sobrien 31790075Sobrien/* Nonzero if destined for a processor in 32-bit program mode. Takes out bit 31890075Sobrien that assume restoration of the condition flags when returning from a 31990075Sobrien branch and link (ie a function). */ 32090075Sobrien#define ARM_FLAG_APCS_32 (1 << 3) 32190075Sobrien 32290075Sobrien/* FLAGS 0x0008 and 0x0010 are now spare (used to be arm3/6 selection). */ 32390075Sobrien 32490075Sobrien/* Nonzero if stack checking should be performed on entry to each function 32590075Sobrien which allocates temporary variables on the stack. */ 32690075Sobrien#define ARM_FLAG_APCS_STACK (1 << 4) 32790075Sobrien 32890075Sobrien/* Nonzero if floating point parameters should be passed to functions in 32990075Sobrien floating point registers. */ 33090075Sobrien#define ARM_FLAG_APCS_FLOAT (1 << 5) 33190075Sobrien 33290075Sobrien/* Nonzero if re-entrant, position independent code should be generated. 33390075Sobrien This is equivalent to -fpic. */ 33490075Sobrien#define ARM_FLAG_APCS_REENT (1 << 6) 33590075Sobrien 33690075Sobrien/* Nonzero if the MMU will trap unaligned word accesses, so shorts must 33790075Sobrien be loaded using either LDRH or LDRB instructions. */ 33890075Sobrien#define ARM_FLAG_MMU_TRAPS (1 << 7) 33990075Sobrien 34090075Sobrien/* Nonzero if all floating point instructions are missing (and there is no 34190075Sobrien emulator either). Generate function calls for all ops in this case. */ 34290075Sobrien#define ARM_FLAG_SOFT_FLOAT (1 << 8) 34390075Sobrien 34490075Sobrien/* Nonzero if we should compile with BYTES_BIG_ENDIAN set to 1. */ 34590075Sobrien#define ARM_FLAG_BIG_END (1 << 9) 34690075Sobrien 34790075Sobrien/* Nonzero if we should compile for Thumb interworking. */ 34890075Sobrien#define ARM_FLAG_INTERWORK (1 << 10) 34990075Sobrien 35090075Sobrien/* Nonzero if we should have little-endian words even when compiling for 35190075Sobrien big-endian (for backwards compatibility with older versions of GCC). */ 35290075Sobrien#define ARM_FLAG_LITTLE_WORDS (1 << 11) 35390075Sobrien 35490075Sobrien/* Nonzero if we need to protect the prolog from scheduling */ 35590075Sobrien#define ARM_FLAG_NO_SCHED_PRO (1 << 12) 35690075Sobrien 35790075Sobrien/* Nonzero if a call to abort should be generated if a noreturn 35890075Sobrien function tries to return. */ 35990075Sobrien#define ARM_FLAG_ABORT_NORETURN (1 << 13) 36090075Sobrien 36190075Sobrien/* Nonzero if function prologues should not load the PIC register. */ 36290075Sobrien#define ARM_FLAG_SINGLE_PIC_BASE (1 << 14) 36390075Sobrien 36490075Sobrien/* Nonzero if all call instructions should be indirect. */ 36590075Sobrien#define ARM_FLAG_LONG_CALLS (1 << 15) 36690075Sobrien 36790075Sobrien/* Nonzero means that the target ISA is the THUMB, not the ARM. */ 36890075Sobrien#define ARM_FLAG_THUMB (1 << 16) 36990075Sobrien 37090075Sobrien/* Set if a TPCS style stack frame should be generated, for non-leaf 37190075Sobrien functions, even if they do not need one. */ 37290075Sobrien#define THUMB_FLAG_BACKTRACE (1 << 17) 37390075Sobrien 37490075Sobrien/* Set if a TPCS style stack frame should be generated, for leaf 37590075Sobrien functions, even if they do not need one. */ 37690075Sobrien#define THUMB_FLAG_LEAF_BACKTRACE (1 << 18) 37790075Sobrien 37890075Sobrien/* Set if externally visible functions should assume that they 37990075Sobrien might be called in ARM mode, from a non-thumb aware code. */ 38090075Sobrien#define THUMB_FLAG_CALLEE_SUPER_INTERWORKING (1 << 19) 38190075Sobrien 38290075Sobrien/* Set if calls via function pointers should assume that their 38390075Sobrien destination is non-Thumb aware. */ 38490075Sobrien#define THUMB_FLAG_CALLER_SUPER_INTERWORKING (1 << 20) 38590075Sobrien 38690075Sobrien#define TARGET_APCS_FRAME (target_flags & ARM_FLAG_APCS_FRAME) 38790075Sobrien#define TARGET_POKE_FUNCTION_NAME (target_flags & ARM_FLAG_POKE) 38890075Sobrien#define TARGET_FPE (target_flags & ARM_FLAG_FPE) 38990075Sobrien#define TARGET_APCS_32 (target_flags & ARM_FLAG_APCS_32) 39090075Sobrien#define TARGET_APCS_STACK (target_flags & ARM_FLAG_APCS_STACK) 39190075Sobrien#define TARGET_APCS_FLOAT (target_flags & ARM_FLAG_APCS_FLOAT) 39290075Sobrien#define TARGET_APCS_REENT (target_flags & ARM_FLAG_APCS_REENT) 39390075Sobrien#define TARGET_MMU_TRAPS (target_flags & ARM_FLAG_MMU_TRAPS) 39490075Sobrien#define TARGET_SOFT_FLOAT (target_flags & ARM_FLAG_SOFT_FLOAT) 39590075Sobrien#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT) 39690075Sobrien#define TARGET_BIG_END (target_flags & ARM_FLAG_BIG_END) 39790075Sobrien#define TARGET_INTERWORK (target_flags & ARM_FLAG_INTERWORK) 39890075Sobrien#define TARGET_LITTLE_WORDS (target_flags & ARM_FLAG_LITTLE_WORDS) 39990075Sobrien#define TARGET_NO_SCHED_PRO (target_flags & ARM_FLAG_NO_SCHED_PRO) 40090075Sobrien#define TARGET_ABORT_NORETURN (target_flags & ARM_FLAG_ABORT_NORETURN) 40190075Sobrien#define TARGET_SINGLE_PIC_BASE (target_flags & ARM_FLAG_SINGLE_PIC_BASE) 40290075Sobrien#define TARGET_LONG_CALLS (target_flags & ARM_FLAG_LONG_CALLS) 40390075Sobrien#define TARGET_THUMB (target_flags & ARM_FLAG_THUMB) 40490075Sobrien#define TARGET_ARM (! TARGET_THUMB) 40590075Sobrien#define TARGET_EITHER 1 /* (TARGET_ARM | TARGET_THUMB) */ 40690075Sobrien#define TARGET_CALLEE_INTERWORKING (target_flags & THUMB_FLAG_CALLEE_SUPER_INTERWORKING) 40790075Sobrien#define TARGET_CALLER_INTERWORKING (target_flags & THUMB_FLAG_CALLER_SUPER_INTERWORKING) 40890075Sobrien#define TARGET_BACKTRACE (leaf_function_p () \ 40990075Sobrien ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE) \ 41090075Sobrien : (target_flags & THUMB_FLAG_BACKTRACE)) 41190075Sobrien 41290075Sobrien/* SUBTARGET_SWITCHES is used to add flags on a per-config basis. 41390075Sobrien Bit 31 is reserved. See riscix.h. */ 41490075Sobrien#ifndef SUBTARGET_SWITCHES 41590075Sobrien#define SUBTARGET_SWITCHES 41690075Sobrien#endif 41790075Sobrien 41890075Sobrien#define TARGET_SWITCHES \ 41990075Sobrien{ \ 42090075Sobrien {"apcs", ARM_FLAG_APCS_FRAME, "" }, \ 42190075Sobrien {"apcs-frame", ARM_FLAG_APCS_FRAME, \ 42290075Sobrien N_("Generate APCS conformant stack frames") }, \ 42390075Sobrien {"no-apcs-frame", -ARM_FLAG_APCS_FRAME, "" }, \ 42490075Sobrien {"poke-function-name", ARM_FLAG_POKE, \ 42590075Sobrien N_("Store function names in object code") }, \ 42690075Sobrien {"no-poke-function-name", -ARM_FLAG_POKE, "" }, \ 42790075Sobrien {"fpe", ARM_FLAG_FPE, "" }, \ 42890075Sobrien {"apcs-32", ARM_FLAG_APCS_32, \ 42990075Sobrien N_("Use the 32-bit version of the APCS") }, \ 43090075Sobrien {"apcs-26", -ARM_FLAG_APCS_32, \ 43190075Sobrien N_("Use the 26-bit version of the APCS") }, \ 43290075Sobrien {"apcs-stack-check", ARM_FLAG_APCS_STACK, "" }, \ 43390075Sobrien {"no-apcs-stack-check", -ARM_FLAG_APCS_STACK, "" }, \ 43490075Sobrien {"apcs-float", ARM_FLAG_APCS_FLOAT, \ 43590075Sobrien N_("Pass FP arguments in FP registers") }, \ 43690075Sobrien {"no-apcs-float", -ARM_FLAG_APCS_FLOAT, "" }, \ 43790075Sobrien {"apcs-reentrant", ARM_FLAG_APCS_REENT, \ 43890075Sobrien N_("Generate re-entrant, PIC code") }, \ 43990075Sobrien {"no-apcs-reentrant", -ARM_FLAG_APCS_REENT, "" }, \ 44090075Sobrien {"alignment-traps", ARM_FLAG_MMU_TRAPS, \ 44190075Sobrien N_("The MMU will trap on unaligned accesses") }, \ 44290075Sobrien {"no-alignment-traps", -ARM_FLAG_MMU_TRAPS, "" }, \ 44390075Sobrien {"short-load-bytes", ARM_FLAG_MMU_TRAPS, "" }, \ 44490075Sobrien {"no-short-load-bytes", -ARM_FLAG_MMU_TRAPS, "" }, \ 44590075Sobrien {"short-load-words", -ARM_FLAG_MMU_TRAPS, "" }, \ 44690075Sobrien {"no-short-load-words", ARM_FLAG_MMU_TRAPS, "" }, \ 44790075Sobrien {"soft-float", ARM_FLAG_SOFT_FLOAT, \ 44890075Sobrien N_("Use library calls to perform FP operations") }, \ 44990075Sobrien {"hard-float", -ARM_FLAG_SOFT_FLOAT, \ 45090075Sobrien N_("Use hardware floating point instructions") }, \ 45190075Sobrien {"big-endian", ARM_FLAG_BIG_END, \ 45290075Sobrien N_("Assume target CPU is configured as big endian") }, \ 45390075Sobrien {"little-endian", -ARM_FLAG_BIG_END, \ 45490075Sobrien N_("Assume target CPU is configured as little endian") }, \ 45590075Sobrien {"words-little-endian", ARM_FLAG_LITTLE_WORDS, \ 45690075Sobrien N_("Assume big endian bytes, little endian words") }, \ 45790075Sobrien {"thumb-interwork", ARM_FLAG_INTERWORK, \ 45890075Sobrien N_("Support calls between Thumb and ARM instruction sets") }, \ 45990075Sobrien {"no-thumb-interwork", -ARM_FLAG_INTERWORK, "" }, \ 46090075Sobrien {"abort-on-noreturn", ARM_FLAG_ABORT_NORETURN, \ 46190075Sobrien N_("Generate a call to abort if a noreturn function returns")}, \ 46290075Sobrien {"no-abort-on-noreturn", -ARM_FLAG_ABORT_NORETURN, "" }, \ 46390075Sobrien {"no-sched-prolog", ARM_FLAG_NO_SCHED_PRO, \ 46490075Sobrien N_("Do not move instructions into a function's prologue") }, \ 46590075Sobrien {"sched-prolog", -ARM_FLAG_NO_SCHED_PRO, "" }, \ 46690075Sobrien {"single-pic-base", ARM_FLAG_SINGLE_PIC_BASE, \ 46790075Sobrien N_("Do not load the PIC register in function prologues") }, \ 46890075Sobrien {"no-single-pic-base", -ARM_FLAG_SINGLE_PIC_BASE, "" }, \ 46990075Sobrien {"long-calls", ARM_FLAG_LONG_CALLS, \ 47090075Sobrien N_("Generate call insns as indirect calls, if necessary") }, \ 47190075Sobrien {"no-long-calls", -ARM_FLAG_LONG_CALLS, "" }, \ 47290075Sobrien {"thumb", ARM_FLAG_THUMB, \ 47390075Sobrien N_("Compile for the Thumb not the ARM") }, \ 47490075Sobrien {"no-thumb", -ARM_FLAG_THUMB, "" }, \ 47590075Sobrien {"arm", -ARM_FLAG_THUMB, "" }, \ 47690075Sobrien {"tpcs-frame", THUMB_FLAG_BACKTRACE, \ 47790075Sobrien N_("Thumb: Generate (non-leaf) stack frames even if not needed") }, \ 47890075Sobrien {"no-tpcs-frame", -THUMB_FLAG_BACKTRACE, "" }, \ 47990075Sobrien {"tpcs-leaf-frame", THUMB_FLAG_LEAF_BACKTRACE, \ 48090075Sobrien N_("Thumb: Generate (leaf) stack frames even if not needed") }, \ 48190075Sobrien {"no-tpcs-leaf-frame", -THUMB_FLAG_LEAF_BACKTRACE, "" }, \ 48290075Sobrien {"callee-super-interworking", THUMB_FLAG_CALLEE_SUPER_INTERWORKING, \ 48390075Sobrien N_("Thumb: Assume non-static functions may be called from ARM code") }, \ 48490075Sobrien {"no-callee-super-interworking", -THUMB_FLAG_CALLEE_SUPER_INTERWORKING, \ 48590075Sobrien "" }, \ 48690075Sobrien {"caller-super-interworking", THUMB_FLAG_CALLER_SUPER_INTERWORKING, \ 48790075Sobrien N_("Thumb: Assume function pointers may go to non-Thumb aware code") }, \ 48890075Sobrien {"no-caller-super-interworking", -THUMB_FLAG_CALLER_SUPER_INTERWORKING, \ 48990075Sobrien "" }, \ 49090075Sobrien SUBTARGET_SWITCHES \ 49190075Sobrien {"", TARGET_DEFAULT, "" } \ 49290075Sobrien} 49390075Sobrien 49490075Sobrien#define TARGET_OPTIONS \ 49590075Sobrien{ \ 49690075Sobrien {"cpu=", & arm_select[0].string, \ 49790075Sobrien N_("Specify the name of the target CPU") }, \ 49890075Sobrien {"arch=", & arm_select[1].string, \ 49990075Sobrien N_("Specify the name of the target architecture") }, \ 50090075Sobrien {"tune=", & arm_select[2].string, "" }, \ 50190075Sobrien {"fpe=", & target_fp_name, "" }, \ 50290075Sobrien {"fp=", & target_fp_name, \ 50390075Sobrien N_("Specify the version of the floating point emulator") }, \ 50490075Sobrien {"structure-size-boundary=", & structure_size_string, \ 50590075Sobrien N_("Specify the minimum bit alignment of structures") }, \ 50690075Sobrien {"pic-register=", & arm_pic_register_string, \ 50790075Sobrien N_("Specify the register to be used for PIC addressing") } \ 50890075Sobrien} 50990075Sobrien 51090075Sobrienstruct arm_cpu_select 51190075Sobrien{ 51290075Sobrien const char * string; 51390075Sobrien const char * name; 51490075Sobrien const struct processors * processors; 51590075Sobrien}; 51690075Sobrien 51790075Sobrien/* This is a magic array. If the user specifies a command line switch 51890075Sobrien which matches one of the entries in TARGET_OPTIONS then the corresponding 51990075Sobrien string pointer will be set to the value specified by the user. */ 52090075Sobrienextern struct arm_cpu_select arm_select[]; 52190075Sobrien 52290075Sobrienenum prog_mode_type 52390075Sobrien{ 52490075Sobrien prog_mode26, 52590075Sobrien prog_mode32 52690075Sobrien}; 52790075Sobrien 52890075Sobrien/* Recast the program mode class to be the prog_mode attribute */ 52990075Sobrien#define arm_prog_mode ((enum attr_prog_mode) arm_prgmode) 53090075Sobrien 53190075Sobrienextern enum prog_mode_type arm_prgmode; 53290075Sobrien 53390075Sobrien/* What sort of floating point unit do we have? Hardware or software. 53490075Sobrien If software, is it issue 2 or issue 3? */ 53590075Sobrienenum floating_point_type 53690075Sobrien{ 53790075Sobrien FP_HARD, 53890075Sobrien FP_SOFT2, 53990075Sobrien FP_SOFT3 54090075Sobrien}; 54190075Sobrien 54290075Sobrien/* Recast the floating point class to be the floating point attribute. */ 54390075Sobrien#define arm_fpu_attr ((enum attr_fpu) arm_fpu) 54490075Sobrien 54590075Sobrien/* What type of floating point to tune for */ 54690075Sobrienextern enum floating_point_type arm_fpu; 54790075Sobrien 54890075Sobrien/* What type of floating point instructions are available */ 54990075Sobrienextern enum floating_point_type arm_fpu_arch; 55090075Sobrien 55190075Sobrien/* Default floating point architecture. Override in sub-target if 55290075Sobrien necessary. */ 55390075Sobrien#ifndef FP_DEFAULT 55490075Sobrien#define FP_DEFAULT FP_SOFT2 55590075Sobrien#endif 55690075Sobrien 55790075Sobrien/* Nonzero if the processor has a fast multiply insn, and one that does 55890075Sobrien a 64-bit multiply of two 32-bit values. */ 55990075Sobrienextern int arm_fast_multiply; 56090075Sobrien 56190075Sobrien/* Nonzero if this chip supports the ARM Architecture 4 extensions */ 56290075Sobrienextern int arm_arch4; 56390075Sobrien 56490075Sobrien/* Nonzero if this chip supports the ARM Architecture 5 extensions */ 56590075Sobrienextern int arm_arch5; 56690075Sobrien 56790075Sobrien/* Nonzero if this chip supports the ARM Architecture 5E extensions */ 56890075Sobrienextern int arm_arch5e; 56990075Sobrien 57090075Sobrien/* Nonzero if this chip can benefit from load scheduling. */ 57190075Sobrienextern int arm_ld_sched; 57290075Sobrien 57390075Sobrien/* Nonzero if generating thumb code. */ 57490075Sobrienextern int thumb_code; 57590075Sobrien 57690075Sobrien/* Nonzero if this chip is a StrongARM. */ 57790075Sobrienextern int arm_is_strong; 57890075Sobrien 57990075Sobrien/* Nonzero if this chip is an XScale. */ 58090075Sobrienextern int arm_is_xscale; 58190075Sobrien 58290075Sobrien/* Nonzero if this chip is an ARM6 or an ARM7. */ 58390075Sobrienextern int arm_is_6_or_7; 58490075Sobrien 58590075Sobrien#ifndef TARGET_DEFAULT 58690075Sobrien#define TARGET_DEFAULT (ARM_FLAG_APCS_FRAME) 58790075Sobrien#endif 58890075Sobrien 58990075Sobrien/* The frame pointer register used in gcc has nothing to do with debugging; 59090075Sobrien that is controlled by the APCS-FRAME option. */ 59190075Sobrien#define CAN_DEBUG_WITHOUT_FP 59290075Sobrien 59390075Sobrien#undef TARGET_MEM_FUNCTIONS 59490075Sobrien#define TARGET_MEM_FUNCTIONS 1 59590075Sobrien 59690075Sobrien#define OVERRIDE_OPTIONS arm_override_options () 59790075Sobrien 59890075Sobrien/* Nonzero if PIC code requires explicit qualifiers to generate 59990075Sobrien PLT and GOT relocs rather than the assembler doing so implicitly. 60090075Sobrien Subtargets can override these if required. */ 60190075Sobrien#ifndef NEED_GOT_RELOC 60290075Sobrien#define NEED_GOT_RELOC 0 60390075Sobrien#endif 60490075Sobrien#ifndef NEED_PLT_RELOC 60590075Sobrien#define NEED_PLT_RELOC 0 60690075Sobrien#endif 60790075Sobrien 60890075Sobrien/* Nonzero if we need to refer to the GOT with a PC-relative 60990075Sobrien offset. In other words, generate 61090075Sobrien 61190075Sobrien .word _GLOBAL_OFFSET_TABLE_ - [. - (.Lxx + 8)] 61290075Sobrien 61390075Sobrien rather than 61490075Sobrien 61590075Sobrien .word _GLOBAL_OFFSET_TABLE_ - (.Lxx + 8) 61690075Sobrien 61790075Sobrien The default is true, which matches NetBSD. Subtargets can 61890075Sobrien override this if required. */ 61990075Sobrien#ifndef GOT_PCREL 62090075Sobrien#define GOT_PCREL 1 62190075Sobrien#endif 62290075Sobrien 62390075Sobrien/* Target machine storage Layout. */ 62490075Sobrien 62590075Sobrien 62690075Sobrien/* Define this macro if it is advisable to hold scalars in registers 62790075Sobrien in a wider mode than that declared by the program. In such cases, 62890075Sobrien the value is constrained to be within the bounds of the declared 62990075Sobrien type, but kept valid in the wider mode. The signedness of the 63090075Sobrien extension may differ from that of the type. */ 63190075Sobrien 63290075Sobrien/* It is far faster to zero extend chars than to sign extend them */ 63390075Sobrien 63490075Sobrien#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ 63590075Sobrien if (GET_MODE_CLASS (MODE) == MODE_INT \ 63690075Sobrien && GET_MODE_SIZE (MODE) < 4) \ 63790075Sobrien { \ 63890075Sobrien if (MODE == QImode) \ 63990075Sobrien UNSIGNEDP = 1; \ 64090075Sobrien else if (MODE == HImode) \ 64190075Sobrien UNSIGNEDP = TARGET_MMU_TRAPS != 0; \ 64290075Sobrien (MODE) = SImode; \ 64390075Sobrien } 64490075Sobrien 64590075Sobrien/* Define this macro if the promotion described by `PROMOTE_MODE' 64690075Sobrien should also be done for outgoing function arguments. */ 64790075Sobrien/* This is required to ensure that push insns always push a word. */ 64890075Sobrien#define PROMOTE_FUNCTION_ARGS 64990075Sobrien 65090075Sobrien/* Define for XFmode extended real floating point support. 65190075Sobrien This will automatically cause REAL_ARITHMETIC to be defined. */ 65290075Sobrien/* For the ARM: 65390075Sobrien I think I have added all the code to make this work. Unfortunately, 65490075Sobrien early releases of the floating point emulation code on RISCiX used a 65590075Sobrien different format for extended precision numbers. On my RISCiX box there 65690075Sobrien is a bug somewhere which causes the machine to lock up when running enquire 65790075Sobrien with long doubles. There is the additional aspect that Norcroft C 65890075Sobrien treats long doubles as doubles and we ought to remain compatible. 65990075Sobrien Perhaps someone with an FPA coprocessor and not running RISCiX would like 66090075Sobrien to try this someday. */ 66190075Sobrien/* #define LONG_DOUBLE_TYPE_SIZE 96 */ 66290075Sobrien 66390075Sobrien/* Disable XFmode patterns in md file */ 66490075Sobrien#define ENABLE_XF_PATTERNS 0 66590075Sobrien 66690075Sobrien/* Define if you don't want extended real, but do want to use the 66790075Sobrien software floating point emulator for REAL_ARITHMETIC and 66890075Sobrien decimal <-> binary conversion. */ 66990075Sobrien/* See comment above */ 67090075Sobrien#define REAL_ARITHMETIC 67190075Sobrien 67290075Sobrien/* Define this if most significant bit is lowest numbered 67390075Sobrien in instructions that operate on numbered bit-fields. */ 67490075Sobrien#define BITS_BIG_ENDIAN 0 67590075Sobrien 67690075Sobrien/* Define this if most significant byte of a word is the lowest numbered. 67790075Sobrien Most ARM processors are run in little endian mode, so that is the default. 67890075Sobrien If you want to have it run-time selectable, change the definition in a 67990075Sobrien cover file to be TARGET_BIG_ENDIAN. */ 68090075Sobrien#define BYTES_BIG_ENDIAN (TARGET_BIG_END != 0) 68190075Sobrien 68290075Sobrien/* Define this if most significant word of a multiword number is the lowest 68390075Sobrien numbered. 68490075Sobrien This is always false, even when in big-endian mode. */ 68590075Sobrien#define WORDS_BIG_ENDIAN (BYTES_BIG_ENDIAN && ! TARGET_LITTLE_WORDS) 68690075Sobrien 68790075Sobrien/* LIBGCC2_WORDS_BIG_ENDIAN has to be a constant, so we define this based 68890075Sobrien on processor pre-defineds when compiling libgcc2.c. */ 68990075Sobrien#if defined(__ARMEB__) && !defined(__ARMWEL__) 69090075Sobrien#define LIBGCC2_WORDS_BIG_ENDIAN 1 69190075Sobrien#else 69290075Sobrien#define LIBGCC2_WORDS_BIG_ENDIAN 0 69390075Sobrien#endif 69490075Sobrien 69590075Sobrien/* Define this if most significant word of doubles is the lowest numbered. 69690075Sobrien This is always true, even when in little-endian mode. */ 69790075Sobrien#define FLOAT_WORDS_BIG_ENDIAN 1 69890075Sobrien 69990075Sobrien/* Number of bits in an addressable storage unit */ 70090075Sobrien#define BITS_PER_UNIT 8 70190075Sobrien 70290075Sobrien#define BITS_PER_WORD 32 70390075Sobrien 70490075Sobrien#define UNITS_PER_WORD 4 70590075Sobrien 70690075Sobrien#define POINTER_SIZE 32 70790075Sobrien 70890075Sobrien#define PARM_BOUNDARY 32 70990075Sobrien 71090075Sobrien#define STACK_BOUNDARY 32 71190075Sobrien 71290075Sobrien#define FUNCTION_BOUNDARY 32 71390075Sobrien 71490075Sobrien/* The lowest bit is used to indicate Thumb-mode functions, so the 71590075Sobrien vbit must go into the delta field of pointers to member 71690075Sobrien functions. */ 71790075Sobrien#define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_delta 71890075Sobrien 71990075Sobrien#define EMPTY_FIELD_BOUNDARY 32 72090075Sobrien 72190075Sobrien#define BIGGEST_ALIGNMENT 32 72290075Sobrien 72390075Sobrien/* Make strings word-aligned so strcpy from constants will be faster. */ 72490075Sobrien#define CONSTANT_ALIGNMENT_FACTOR (TARGET_THUMB || ! arm_is_xscale ? 1 : 2) 72590075Sobrien 72690075Sobrien#define CONSTANT_ALIGNMENT(EXP, ALIGN) \ 72790075Sobrien ((TREE_CODE (EXP) == STRING_CST \ 72890075Sobrien && (ALIGN) < BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR) \ 72990075Sobrien ? BITS_PER_WORD * CONSTANT_ALIGNMENT_FACTOR : (ALIGN)) 73090075Sobrien 73190075Sobrien/* Setting STRUCTURE_SIZE_BOUNDARY to 32 produces more efficient code, but the 73290075Sobrien value set in previous versions of this toolchain was 8, which produces more 73390075Sobrien compact structures. The command line option -mstructure_size_boundary=<n> 73490075Sobrien can be used to change this value. For compatibility with the ARM SDK 73590075Sobrien however the value should be left at 32. ARM SDT Reference Manual (ARM DUI 73690075Sobrien 0020D) page 2-20 says "Structures are aligned on word boundaries". */ 73790075Sobrien#define STRUCTURE_SIZE_BOUNDARY arm_structure_size_boundary 73890075Sobrienextern int arm_structure_size_boundary; 73990075Sobrien 74090075Sobrien/* This is the value used to initialise arm_structure_size_boundary. If a 74190075Sobrien particular arm target wants to change the default value it should change 74290075Sobrien the definition of this macro, not STRUCTRUE_SIZE_BOUNDARY. See netbsd.h 74390075Sobrien for an example of this. */ 74490075Sobrien#ifndef DEFAULT_STRUCTURE_SIZE_BOUNDARY 74590075Sobrien#define DEFAULT_STRUCTURE_SIZE_BOUNDARY 32 74690075Sobrien#endif 74790075Sobrien 74890075Sobrien/* Used when parsing command line option -mstructure_size_boundary. */ 74990075Sobrienextern const char * structure_size_string; 75090075Sobrien 75190075Sobrien/* Non-zero if move instructions will actually fail to work 75290075Sobrien when given unaligned data. */ 75390075Sobrien#define STRICT_ALIGNMENT 1 75490075Sobrien 75590075Sobrien#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT 75690075Sobrien 75790075Sobrien 75890075Sobrien/* Standard register usage. */ 75990075Sobrien 76090075Sobrien/* Register allocation in ARM Procedure Call Standard (as used on RISCiX): 76190075Sobrien (S - saved over call). 76290075Sobrien 76390075Sobrien r0 * argument word/integer result 76490075Sobrien r1-r3 argument word 76590075Sobrien 76690075Sobrien r4-r8 S register variable 76790075Sobrien r9 S (rfp) register variable (real frame pointer) 76890075Sobrien 76990075Sobrien r10 F S (sl) stack limit (used by -mapcs-stack-check) 77090075Sobrien r11 F S (fp) argument pointer 77190075Sobrien r12 (ip) temp workspace 77290075Sobrien r13 F S (sp) lower end of current stack frame 77390075Sobrien r14 (lr) link address/workspace 77490075Sobrien r15 F (pc) program counter 77590075Sobrien 77690075Sobrien f0 floating point result 77790075Sobrien f1-f3 floating point scratch 77890075Sobrien 77990075Sobrien f4-f7 S floating point variable 78090075Sobrien 78190075Sobrien cc This is NOT a real register, but is used internally 78290075Sobrien to represent things that use or set the condition 78390075Sobrien codes. 78490075Sobrien sfp This isn't either. It is used during rtl generation 78590075Sobrien since the offset between the frame pointer and the 78690075Sobrien auto's isn't known until after register allocation. 78790075Sobrien afp Nor this, we only need this because of non-local 78890075Sobrien goto. Without it fp appears to be used and the 78990075Sobrien elimination code won't get rid of sfp. It tracks 79090075Sobrien fp exactly at all times. 79190075Sobrien 79290075Sobrien *: See CONDITIONAL_REGISTER_USAGE */ 79390075Sobrien 79490075Sobrien/* The stack backtrace structure is as follows: 79590075Sobrien fp points to here: | save code pointer | [fp] 79690075Sobrien | return link value | [fp, #-4] 79790075Sobrien | return sp value | [fp, #-8] 79890075Sobrien | return fp value | [fp, #-12] 79990075Sobrien [| saved r10 value |] 80090075Sobrien [| saved r9 value |] 80190075Sobrien [| saved r8 value |] 80290075Sobrien [| saved r7 value |] 80390075Sobrien [| saved r6 value |] 80490075Sobrien [| saved r5 value |] 80590075Sobrien [| saved r4 value |] 80690075Sobrien [| saved r3 value |] 80790075Sobrien [| saved r2 value |] 80890075Sobrien [| saved r1 value |] 80990075Sobrien [| saved r0 value |] 81090075Sobrien [| saved f7 value |] three words 81190075Sobrien [| saved f6 value |] three words 81290075Sobrien [| saved f5 value |] three words 81390075Sobrien [| saved f4 value |] three words 81490075Sobrien r0-r3 are not normally saved in a C function. */ 81590075Sobrien 81690075Sobrien/* 1 for registers that have pervasive standard uses 81790075Sobrien and are not available for the register allocator. */ 81890075Sobrien#define FIXED_REGISTERS \ 81990075Sobrien{ \ 82090075Sobrien 0,0,0,0,0,0,0,0, \ 82190075Sobrien 0,0,0,0,0,1,0,1, \ 82290075Sobrien 0,0,0,0,0,0,0,0, \ 82390075Sobrien 1,1,1 \ 82490075Sobrien} 82590075Sobrien 82690075Sobrien/* 1 for registers not available across function calls. 82790075Sobrien These must include the FIXED_REGISTERS and also any 82890075Sobrien registers that can be used without being saved. 82990075Sobrien The latter must include the registers where values are returned 83090075Sobrien and the register where structure-value addresses are passed. 83190075Sobrien Aside from that, you can include as many other registers as you like. 83290075Sobrien The CC is not preserved over function calls on the ARM 6, so it is 83390075Sobrien easier to assume this for all. SFP is preserved, since FP is. */ 83490075Sobrien#define CALL_USED_REGISTERS \ 83590075Sobrien{ \ 83690075Sobrien 1,1,1,1,0,0,0,0, \ 83790075Sobrien 0,0,0,0,1,1,1,1, \ 83890075Sobrien 1,1,1,1,0,0,0,0, \ 83990075Sobrien 1,1,1 \ 84090075Sobrien} 84190075Sobrien 84290075Sobrien#ifndef SUBTARGET_CONDITIONAL_REGISTER_USAGE 84390075Sobrien#define SUBTARGET_CONDITIONAL_REGISTER_USAGE 84490075Sobrien#endif 84590075Sobrien 84690075Sobrien#define CONDITIONAL_REGISTER_USAGE \ 84790075Sobrien{ \ 84890075Sobrien int regno; \ 84990075Sobrien \ 85090075Sobrien if (TARGET_SOFT_FLOAT || TARGET_THUMB) \ 85190075Sobrien { \ 85290075Sobrien for (regno = FIRST_ARM_FP_REGNUM; \ 85390075Sobrien regno <= LAST_ARM_FP_REGNUM; ++regno) \ 85490075Sobrien fixed_regs[regno] = call_used_regs[regno] = 1; \ 85590075Sobrien } \ 85696263Sobrien if (PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM) \ 85790075Sobrien { \ 85890075Sobrien fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ 85990075Sobrien call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ 86090075Sobrien } \ 86190075Sobrien else if (TARGET_APCS_STACK) \ 86290075Sobrien { \ 86390075Sobrien fixed_regs[10] = 1; \ 86490075Sobrien call_used_regs[10] = 1; \ 86590075Sobrien } \ 86690075Sobrien if (TARGET_APCS_FRAME) \ 86790075Sobrien { \ 86890075Sobrien fixed_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \ 86990075Sobrien call_used_regs[ARM_HARD_FRAME_POINTER_REGNUM] = 1; \ 87090075Sobrien } \ 87190075Sobrien SUBTARGET_CONDITIONAL_REGISTER_USAGE \ 87290075Sobrien} 87390075Sobrien 87490075Sobrien/* These are a couple of extensions to the formats accecpted 87590075Sobrien by asm_fprintf: 87690075Sobrien %@ prints out ASM_COMMENT_START 87790075Sobrien %r prints out REGISTER_PREFIX reg_names[arg] */ 87890075Sobrien#define ASM_FPRINTF_EXTENSIONS(FILE, ARGS, P) \ 87990075Sobrien case '@': \ 88090075Sobrien fputs (ASM_COMMENT_START, FILE); \ 88190075Sobrien break; \ 88290075Sobrien \ 88390075Sobrien case 'r': \ 88490075Sobrien fputs (REGISTER_PREFIX, FILE); \ 88590075Sobrien fputs (reg_names [va_arg (ARGS, int)], FILE); \ 88690075Sobrien break; 88790075Sobrien 88890075Sobrien/* Round X up to the nearest word. */ 88990075Sobrien#define ROUND_UP(X) (((X) + 3) & ~3) 89090075Sobrien 89190075Sobrien/* Convert fron bytes to ints. */ 89290075Sobrien#define NUM_INTS(X) (((X) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) 89390075Sobrien 89490075Sobrien/* The number of (integer) registers required to hold a quantity of type MODE. */ 89590075Sobrien#define NUM_REGS(MODE) \ 89690075Sobrien NUM_INTS (GET_MODE_SIZE (MODE)) 89790075Sobrien 89890075Sobrien/* The number of (integer) registers required to hold a quantity of TYPE MODE. */ 89990075Sobrien#define NUM_REGS2(MODE, TYPE) \ 90090075Sobrien NUM_INTS ((MODE) == BLKmode ? \ 90190075Sobrien int_size_in_bytes (TYPE) : GET_MODE_SIZE (MODE)) 90290075Sobrien 90390075Sobrien/* The number of (integer) argument register available. */ 90490075Sobrien#define NUM_ARG_REGS 4 90590075Sobrien 90690075Sobrien/* Return the regiser number of the N'th (integer) argument. */ 90790075Sobrien#define ARG_REGISTER(N) (N - 1) 90890075Sobrien 90990075Sobrien#if 0 /* FIXME: The ARM backend has special code to handle structure 91090075Sobrien returns, and will reserve its own hidden first argument. So 91190075Sobrien if this macro is enabled a *second* hidden argument will be 91290075Sobrien reserved, which will break binary compatibility with old 91390075Sobrien toolchains and also thunk handling. One day this should be 91490075Sobrien fixed. */ 91590075Sobrien/* RTX for structure returns. NULL means use a hidden first argument. */ 91690075Sobrien#define STRUCT_VALUE 0 91790075Sobrien#else 91890075Sobrien/* Register in which address to store a structure value 91990075Sobrien is passed to a function. */ 92090075Sobrien#define STRUCT_VALUE_REGNUM ARG_REGISTER (1) 92190075Sobrien#endif 92290075Sobrien 92390075Sobrien/* Specify the registers used for certain standard purposes. 92490075Sobrien The values of these macros are register numbers. */ 92590075Sobrien 92690075Sobrien/* The number of the last argument register. */ 92790075Sobrien#define LAST_ARG_REGNUM ARG_REGISTER (NUM_ARG_REGS) 92890075Sobrien 92990075Sobrien/* The number of the last "lo" register (thumb). */ 93090075Sobrien#define LAST_LO_REGNUM 7 93190075Sobrien 93290075Sobrien/* The register that holds the return address in exception handlers. */ 93390075Sobrien#define EXCEPTION_LR_REGNUM 2 93490075Sobrien 93590075Sobrien/* The native (Norcroft) Pascal compiler for the ARM passes the static chain 93690075Sobrien as an invisible last argument (possible since varargs don't exist in 93790075Sobrien Pascal), so the following is not true. */ 93890075Sobrien#define STATIC_CHAIN_REGNUM (TARGET_ARM ? 12 : 9) 93990075Sobrien 94090075Sobrien/* Define this to be where the real frame pointer is if it is not possible to 94190075Sobrien work out the offset between the frame pointer and the automatic variables 94290075Sobrien until after register allocation has taken place. FRAME_POINTER_REGNUM 94390075Sobrien should point to a special register that we will make sure is eliminated. 94490075Sobrien 94590075Sobrien For the Thumb we have another problem. The TPCS defines the frame pointer 94690075Sobrien as r11, and GCC belives that it is always possible to use the frame pointer 94790075Sobrien as base register for addressing purposes. (See comments in 94890075Sobrien find_reloads_address()). But - the Thumb does not allow high registers, 94990075Sobrien including r11, to be used as base address registers. Hence our problem. 95090075Sobrien 95190075Sobrien The solution used here, and in the old thumb port is to use r7 instead of 95290075Sobrien r11 as the hard frame pointer and to have special code to generate 95390075Sobrien backtrace structures on the stack (if required to do so via a command line 95490075Sobrien option) using r11. This is the only 'user visable' use of r11 as a frame 95590075Sobrien pointer. */ 95690075Sobrien#define ARM_HARD_FRAME_POINTER_REGNUM 11 95790075Sobrien#define THUMB_HARD_FRAME_POINTER_REGNUM 7 95890075Sobrien 95990075Sobrien#define HARD_FRAME_POINTER_REGNUM \ 96090075Sobrien (TARGET_ARM \ 96190075Sobrien ? ARM_HARD_FRAME_POINTER_REGNUM \ 96290075Sobrien : THUMB_HARD_FRAME_POINTER_REGNUM) 96390075Sobrien 96490075Sobrien#define FP_REGNUM HARD_FRAME_POINTER_REGNUM 96590075Sobrien 96690075Sobrien/* Register to use for pushing function arguments. */ 96790075Sobrien#define STACK_POINTER_REGNUM SP_REGNUM 96890075Sobrien 96990075Sobrien/* ARM floating pointer registers. */ 97090075Sobrien#define FIRST_ARM_FP_REGNUM 16 97190075Sobrien#define LAST_ARM_FP_REGNUM 23 97290075Sobrien 97390075Sobrien/* Base register for access to local variables of the function. */ 97490075Sobrien#define FRAME_POINTER_REGNUM 25 97590075Sobrien 97690075Sobrien/* Base register for access to arguments of the function. */ 97790075Sobrien#define ARG_POINTER_REGNUM 26 97890075Sobrien 97990075Sobrien/* The number of hard registers is 16 ARM + 8 FPU + 1 CC + 1 SFP. */ 98090075Sobrien#define FIRST_PSEUDO_REGISTER 27 98190075Sobrien 98290075Sobrien/* Value should be nonzero if functions must have frame pointers. 98390075Sobrien Zero means the frame pointer need not be set up (and parms may be accessed 98490075Sobrien via the stack pointer) in functions that seem suitable. 98590075Sobrien If we have to have a frame pointer we might as well make use of it. 98690075Sobrien APCS says that the frame pointer does not need to be pushed in leaf 98790075Sobrien functions, or simple tail call functions. */ 98890075Sobrien#define FRAME_POINTER_REQUIRED \ 98990075Sobrien (current_function_has_nonlocal_label \ 99090075Sobrien || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ())) 99190075Sobrien 99290075Sobrien/* Return number of consecutive hard regs needed starting at reg REGNO 99390075Sobrien to hold something of mode MODE. 99490075Sobrien This is ordinarily the length in words of a value of mode MODE 99590075Sobrien but can be less for certain modes in special long registers. 99690075Sobrien 99790075Sobrien On the ARM regs are UNITS_PER_WORD bits wide; FPU regs can hold any FP 99890075Sobrien mode. */ 99990075Sobrien#define HARD_REGNO_NREGS(REGNO, MODE) \ 100090075Sobrien ((TARGET_ARM \ 100190075Sobrien && REGNO >= FIRST_ARM_FP_REGNUM \ 100290075Sobrien && REGNO != FRAME_POINTER_REGNUM \ 100390075Sobrien && REGNO != ARG_POINTER_REGNUM) \ 100490075Sobrien ? 1 : NUM_REGS (MODE)) 100590075Sobrien 100690075Sobrien/* Return true if REGNO is suitable for holding a quantity of type MODE. */ 100790075Sobrien#define HARD_REGNO_MODE_OK(REGNO, MODE) \ 100890075Sobrien arm_hard_regno_mode_ok ((REGNO), (MODE)) 100990075Sobrien 101090075Sobrien/* Value is 1 if it is a good idea to tie two pseudo registers 101190075Sobrien when one has mode MODE1 and one has mode MODE2. 101290075Sobrien If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, 101390075Sobrien for any hard reg, then this must be 0 for correct output. */ 101490075Sobrien#define MODES_TIEABLE_P(MODE1, MODE2) \ 101590075Sobrien (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2)) 101690075Sobrien 101790075Sobrien/* The order in which register should be allocated. It is good to use ip 101890075Sobrien since no saving is required (though calls clobber it) and it never contains 101990075Sobrien function parameters. It is quite good to use lr since other calls may 102090075Sobrien clobber it anyway. Allocate r0 through r3 in reverse order since r3 is 102190075Sobrien least likely to contain a function parameter; in addition results are 102290075Sobrien returned in r0. */ 102390075Sobrien#define REG_ALLOC_ORDER \ 102490075Sobrien{ \ 102590075Sobrien 3, 2, 1, 0, 12, 14, 4, 5, \ 102690075Sobrien 6, 7, 8, 10, 9, 11, 13, 15, \ 102790075Sobrien 16, 17, 18, 19, 20, 21, 22, 23, \ 102890075Sobrien 24, 25, 26 \ 102990075Sobrien} 103096263Sobrien 103196263Sobrien/* Interrupt functions can only use registers that have already been 103296263Sobrien saved by the prologue, even if they would normally be 103396263Sobrien call-clobbered. */ 103496263Sobrien#define HARD_REGNO_RENAME_OK(SRC, DST) \ 103596263Sobrien (! IS_INTERRUPT (cfun->machine->func_type) || \ 103696263Sobrien regs_ever_live[DST]) 103790075Sobrien 103890075Sobrien/* Register and constant classes. */ 103990075Sobrien 104090075Sobrien/* Register classes: used to be simple, just all ARM regs or all FPU regs 104190075Sobrien Now that the Thumb is involved it has become more complicated. */ 104290075Sobrienenum reg_class 104390075Sobrien{ 104490075Sobrien NO_REGS, 104590075Sobrien FPU_REGS, 104690075Sobrien LO_REGS, 104790075Sobrien STACK_REG, 104890075Sobrien BASE_REGS, 104990075Sobrien HI_REGS, 105090075Sobrien CC_REG, 105190075Sobrien GENERAL_REGS, 105290075Sobrien ALL_REGS, 105390075Sobrien LIM_REG_CLASSES 105490075Sobrien}; 105590075Sobrien 105690075Sobrien#define N_REG_CLASSES (int) LIM_REG_CLASSES 105790075Sobrien 105890075Sobrien/* Give names of register classes as strings for dump file. */ 105990075Sobrien#define REG_CLASS_NAMES \ 106090075Sobrien{ \ 106190075Sobrien "NO_REGS", \ 106290075Sobrien "FPU_REGS", \ 106390075Sobrien "LO_REGS", \ 106490075Sobrien "STACK_REG", \ 106590075Sobrien "BASE_REGS", \ 106690075Sobrien "HI_REGS", \ 106790075Sobrien "CC_REG", \ 106890075Sobrien "GENERAL_REGS", \ 106990075Sobrien "ALL_REGS", \ 107090075Sobrien} 107190075Sobrien 107290075Sobrien/* Define which registers fit in which classes. 107390075Sobrien This is an initializer for a vector of HARD_REG_SET 107490075Sobrien of length N_REG_CLASSES. */ 107590075Sobrien#define REG_CLASS_CONTENTS \ 107690075Sobrien{ \ 107790075Sobrien { 0x0000000 }, /* NO_REGS */ \ 107890075Sobrien { 0x0FF0000 }, /* FPU_REGS */ \ 107990075Sobrien { 0x00000FF }, /* LO_REGS */ \ 108090075Sobrien { 0x0002000 }, /* STACK_REG */ \ 108190075Sobrien { 0x00020FF }, /* BASE_REGS */ \ 108290075Sobrien { 0x000FF00 }, /* HI_REGS */ \ 108390075Sobrien { 0x1000000 }, /* CC_REG */ \ 108490075Sobrien { 0x200FFFF }, /* GENERAL_REGS */ \ 108590075Sobrien { 0x2FFFFFF } /* ALL_REGS */ \ 108690075Sobrien} 108790075Sobrien 108890075Sobrien/* The same information, inverted: 108990075Sobrien Return the class number of the smallest class containing 109090075Sobrien reg number REGNO. This could be a conditional expression 109190075Sobrien or could index an array. */ 109290075Sobrien#define REGNO_REG_CLASS(REGNO) arm_regno_class (REGNO) 109390075Sobrien 109490075Sobrien/* The class value for index registers, and the one for base regs. */ 109590075Sobrien#define INDEX_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS) 1096104752Skan#define BASE_REG_CLASS (TARGET_THUMB ? LO_REGS : GENERAL_REGS) 109790075Sobrien 1098104752Skan/* For the Thumb the high registers cannot be used as base registers 1099104752Skan when addressing quanitities in QI or HI mode; if we don't know the 1100104752Skan mode, then we must be conservative. After reload we must also be 1101104752Skan conservative, since we can't support SP+reg addressing, and we 1102104752Skan can't fix up any bad substitutions. */ 110390075Sobrien#define MODE_BASE_REG_CLASS(MODE) \ 1104104752Skan (TARGET_ARM ? GENERAL_REGS : \ 1105104752Skan (((MODE) == SImode && !reload_completed) ? BASE_REGS : LO_REGS)) 110690075Sobrien 110790075Sobrien/* When SMALL_REGISTER_CLASSES is nonzero, the compiler allows 110890075Sobrien registers explicitly used in the rtl to be used as spill registers 110990075Sobrien but prevents the compiler from extending the lifetime of these 111090075Sobrien registers. */ 111190075Sobrien#define SMALL_REGISTER_CLASSES TARGET_THUMB 111290075Sobrien 111390075Sobrien/* Get reg_class from a letter such as appears in the machine description. 111490075Sobrien We only need constraint `f' for FPU_REGS (`r' == GENERAL_REGS) for the 111590075Sobrien ARM, but several more letters for the Thumb. */ 111690075Sobrien#define REG_CLASS_FROM_LETTER(C) \ 111790075Sobrien ( (C) == 'f' ? FPU_REGS \ 111890075Sobrien : (C) == 'l' ? (TARGET_ARM ? GENERAL_REGS : LO_REGS) \ 111990075Sobrien : TARGET_ARM ? NO_REGS \ 112090075Sobrien : (C) == 'h' ? HI_REGS \ 112190075Sobrien : (C) == 'b' ? BASE_REGS \ 112290075Sobrien : (C) == 'k' ? STACK_REG \ 112390075Sobrien : (C) == 'c' ? CC_REG \ 112490075Sobrien : NO_REGS) 112590075Sobrien 112690075Sobrien/* The letters I, J, K, L and M in a register constraint string 112790075Sobrien can be used to stand for particular ranges of immediate operands. 112890075Sobrien This macro defines what the ranges are. 112990075Sobrien C is the letter, and VALUE is a constant value. 113090075Sobrien Return 1 if VALUE is in the range specified by C. 113190075Sobrien I: immediate arithmetic operand (i.e. 8 bits shifted as required). 113290075Sobrien J: valid indexing constants. 113390075Sobrien K: ~value ok in rhs argument of data operand. 113490075Sobrien L: -value ok in rhs argument of data operand. 113590075Sobrien M: 0..32, or a power of 2 (for shifts, or mult done by shift). */ 113690075Sobrien#define CONST_OK_FOR_ARM_LETTER(VALUE, C) \ 113790075Sobrien ((C) == 'I' ? const_ok_for_arm (VALUE) : \ 113890075Sobrien (C) == 'J' ? ((VALUE) < 4096 && (VALUE) > -4096) : \ 113990075Sobrien (C) == 'K' ? (const_ok_for_arm (~(VALUE))) : \ 114090075Sobrien (C) == 'L' ? (const_ok_for_arm (-(VALUE))) : \ 114190075Sobrien (C) == 'M' ? (((VALUE >= 0 && VALUE <= 32)) \ 114290075Sobrien || (((VALUE) & ((VALUE) - 1)) == 0)) \ 114390075Sobrien : 0) 114490075Sobrien 114590075Sobrien#define CONST_OK_FOR_THUMB_LETTER(VAL, C) \ 114690075Sobrien ((C) == 'I' ? (unsigned HOST_WIDE_INT) (VAL) < 256 : \ 114790075Sobrien (C) == 'J' ? (VAL) > -256 && (VAL) < 0 : \ 114890075Sobrien (C) == 'K' ? thumb_shiftable_const (VAL) : \ 114990075Sobrien (C) == 'L' ? (VAL) > -8 && (VAL) < 8 : \ 115090075Sobrien (C) == 'M' ? ((unsigned HOST_WIDE_INT) (VAL) < 1024 \ 115190075Sobrien && ((VAL) & 3) == 0) : \ 115290075Sobrien (C) == 'N' ? ((unsigned HOST_WIDE_INT) (VAL) < 32) : \ 115390075Sobrien (C) == 'O' ? ((VAL) >= -508 && (VAL) <= 508) \ 115490075Sobrien : 0) 115590075Sobrien 115690075Sobrien#define CONST_OK_FOR_LETTER_P(VALUE, C) \ 115790075Sobrien (TARGET_ARM ? \ 115890075Sobrien CONST_OK_FOR_ARM_LETTER (VALUE, C) : CONST_OK_FOR_THUMB_LETTER (VALUE, C)) 115990075Sobrien 116090075Sobrien/* Constant letter 'G' for the FPU immediate constants. 116190075Sobrien 'H' means the same constant negated. */ 116290075Sobrien#define CONST_DOUBLE_OK_FOR_ARM_LETTER(X, C) \ 116390075Sobrien ((C) == 'G' ? const_double_rtx_ok_for_fpu (X) : \ 116490075Sobrien (C) == 'H' ? neg_const_double_rtx_ok_for_fpu (X) : 0) 116590075Sobrien 116690075Sobrien#define CONST_DOUBLE_OK_FOR_LETTER_P(X, C) \ 116790075Sobrien (TARGET_ARM ? \ 116890075Sobrien CONST_DOUBLE_OK_FOR_ARM_LETTER (X, C) : 0) 116990075Sobrien 117090075Sobrien/* For the ARM, `Q' means that this is a memory operand that is just 117190075Sobrien an offset from a register. 117290075Sobrien `S' means any symbol that has the SYMBOL_REF_FLAG set or a CONSTANT_POOL 117390075Sobrien address. This means that the symbol is in the text segment and can be 117490075Sobrien accessed without using a load. */ 117590075Sobrien 117690075Sobrien#define EXTRA_CONSTRAINT_ARM(OP, C) \ 117790075Sobrien ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG : \ 117890075Sobrien (C) == 'R' ? (GET_CODE (OP) == MEM \ 117990075Sobrien && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF \ 118090075Sobrien && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \ 118190075Sobrien (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) \ 118290075Sobrien : 0) 118390075Sobrien 118490075Sobrien#define EXTRA_CONSTRAINT_THUMB(X, C) \ 118590075Sobrien ((C) == 'Q' ? (GET_CODE (X) == MEM \ 118690075Sobrien && GET_CODE (XEXP (X, 0)) == LABEL_REF) : 0) 118790075Sobrien 118890075Sobrien#define EXTRA_CONSTRAINT(X, C) \ 118990075Sobrien (TARGET_ARM ? \ 119090075Sobrien EXTRA_CONSTRAINT_ARM (X, C) : EXTRA_CONSTRAINT_THUMB (X, C)) 119190075Sobrien 119290075Sobrien/* Given an rtx X being reloaded into a reg required to be 119390075Sobrien in class CLASS, return the class of reg to actually use. 119490075Sobrien In general this is just CLASS, but for the Thumb we prefer 119590075Sobrien a LO_REGS class or a subset. */ 119690075Sobrien#define PREFERRED_RELOAD_CLASS(X, CLASS) \ 119790075Sobrien (TARGET_ARM ? (CLASS) : \ 119890075Sobrien ((CLASS) == BASE_REGS ? (CLASS) : LO_REGS)) 119990075Sobrien 120090075Sobrien/* Must leave BASE_REGS reloads alone */ 120190075Sobrien#define THUMB_SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \ 120290075Sobrien ((CLASS) != LO_REGS && (CLASS) != BASE_REGS \ 120390075Sobrien ? ((true_regnum (X) == -1 ? LO_REGS \ 120490075Sobrien : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS \ 120590075Sobrien : NO_REGS)) \ 120690075Sobrien : NO_REGS) 120790075Sobrien 120890075Sobrien#define THUMB_SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ 120990075Sobrien ((CLASS) != LO_REGS \ 121090075Sobrien ? ((true_regnum (X) == -1 ? LO_REGS \ 121190075Sobrien : (true_regnum (X) + HARD_REGNO_NREGS (0, MODE) > 8) ? LO_REGS \ 121290075Sobrien : NO_REGS)) \ 121390075Sobrien : NO_REGS) 121490075Sobrien 121590075Sobrien/* Return the register class of a scratch register needed to copy IN into 121690075Sobrien or out of a register in CLASS in MODE. If it can be done directly, 121790075Sobrien NO_REGS is returned. */ 121890075Sobrien#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ 121990075Sobrien (TARGET_ARM ? \ 122090075Sobrien (((MODE) == HImode && ! arm_arch4 && true_regnum (X) == -1) \ 122190075Sobrien ? GENERAL_REGS : NO_REGS) \ 122290075Sobrien : THUMB_SECONDARY_OUTPUT_RELOAD_CLASS (CLASS, MODE, X)) 122390075Sobrien 122490075Sobrien/* If we need to load shorts byte-at-a-time, then we need a scratch. */ 122590075Sobrien#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \ 122690075Sobrien (TARGET_ARM ? \ 122790075Sobrien (((MODE) == HImode && ! arm_arch4 && TARGET_MMU_TRAPS \ 122890075Sobrien && (GET_CODE (X) == MEM \ 122990075Sobrien || ((GET_CODE (X) == REG || GET_CODE (X) == SUBREG) \ 123090075Sobrien && true_regnum (X) == -1))) \ 123190075Sobrien ? GENERAL_REGS : NO_REGS) \ 123290075Sobrien : THUMB_SECONDARY_INPUT_RELOAD_CLASS (CLASS, MODE, X)) 123390075Sobrien 123490075Sobrien/* Try a machine-dependent way of reloading an illegitimate address 123590075Sobrien operand. If we find one, push the reload and jump to WIN. This 123690075Sobrien macro is used in only one place: `find_reloads_address' in reload.c. 123790075Sobrien 123890075Sobrien For the ARM, we wish to handle large displacements off a base 123990075Sobrien register by splitting the addend across a MOV and the mem insn. 124090075Sobrien This can cut the number of reloads needed. */ 124190075Sobrien#define ARM_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND, WIN) \ 124290075Sobrien do \ 124390075Sobrien { \ 124490075Sobrien if (GET_CODE (X) == PLUS \ 124590075Sobrien && GET_CODE (XEXP (X, 0)) == REG \ 124690075Sobrien && REGNO (XEXP (X, 0)) < FIRST_PSEUDO_REGISTER \ 124790075Sobrien && REG_MODE_OK_FOR_BASE_P (XEXP (X, 0), MODE) \ 124890075Sobrien && GET_CODE (XEXP (X, 1)) == CONST_INT) \ 124990075Sobrien { \ 125090075Sobrien HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \ 125190075Sobrien HOST_WIDE_INT low, high; \ 125290075Sobrien \ 125390075Sobrien if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \ 125490075Sobrien low = ((val & 0xf) ^ 0x8) - 0x8; \ 125590075Sobrien else if (MODE == SImode \ 125690075Sobrien || (MODE == SFmode && TARGET_SOFT_FLOAT) \ 125790075Sobrien || ((MODE == HImode || MODE == QImode) && ! arm_arch4)) \ 125890075Sobrien /* Need to be careful, -4096 is not a valid offset. */ \ 125990075Sobrien low = val >= 0 ? (val & 0xfff) : -((-val) & 0xfff); \ 126090075Sobrien else if ((MODE == HImode || MODE == QImode) && arm_arch4) \ 126190075Sobrien /* Need to be careful, -256 is not a valid offset. */ \ 126290075Sobrien low = val >= 0 ? (val & 0xff) : -((-val) & 0xff); \ 126390075Sobrien else if (GET_MODE_CLASS (MODE) == MODE_FLOAT \ 126490075Sobrien && TARGET_HARD_FLOAT) \ 126590075Sobrien /* Need to be careful, -1024 is not a valid offset. */ \ 126690075Sobrien low = val >= 0 ? (val & 0x3ff) : -((-val) & 0x3ff); \ 126790075Sobrien else \ 126890075Sobrien break; \ 126990075Sobrien \ 127090075Sobrien high = ((((val - low) & (unsigned HOST_WIDE_INT) 0xffffffff) \ 127190075Sobrien ^ (unsigned HOST_WIDE_INT) 0x80000000) \ 127290075Sobrien - (unsigned HOST_WIDE_INT) 0x80000000); \ 127390075Sobrien /* Check for overflow or zero */ \ 127490075Sobrien if (low == 0 || high == 0 || (high + low != val)) \ 127590075Sobrien break; \ 127690075Sobrien \ 127790075Sobrien /* Reload the high part into a base reg; leave the low part \ 127890075Sobrien in the mem. */ \ 127990075Sobrien X = gen_rtx_PLUS (GET_MODE (X), \ 128090075Sobrien gen_rtx_PLUS (GET_MODE (X), XEXP (X, 0), \ 128190075Sobrien GEN_INT (high)), \ 128290075Sobrien GEN_INT (low)); \ 128390075Sobrien push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \ 128490075Sobrien MODE_BASE_REG_CLASS (MODE), GET_MODE (X), \ 128590075Sobrien VOIDmode, 0, 0, OPNUM, TYPE); \ 128690075Sobrien goto WIN; \ 128790075Sobrien } \ 128890075Sobrien } \ 128990075Sobrien while (0) 129090075Sobrien 129190075Sobrien/* ??? If an HImode FP+large_offset address is converted to an HImode 129290075Sobrien SP+large_offset address, then reload won't know how to fix it. It sees 129390075Sobrien only that SP isn't valid for HImode, and so reloads the SP into an index 129490075Sobrien register, but the resulting address is still invalid because the offset 129590075Sobrien is too big. We fix it here instead by reloading the entire address. */ 129690075Sobrien/* We could probably achieve better results by defining PROMOTE_MODE to help 129790075Sobrien cope with the variances between the Thumb's signed and unsigned byte and 129890075Sobrien halfword load instructions. */ 129990075Sobrien#define THUMB_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \ 130090075Sobrien{ \ 130190075Sobrien if (GET_CODE (X) == PLUS \ 130290075Sobrien && GET_MODE_SIZE (MODE) < 4 \ 130390075Sobrien && GET_CODE (XEXP (X, 0)) == REG \ 130490075Sobrien && XEXP (X, 0) == stack_pointer_rtx \ 130590075Sobrien && GET_CODE (XEXP (X, 1)) == CONST_INT \ 130690075Sobrien && ! THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \ 130790075Sobrien { \ 130890075Sobrien rtx orig_X = X; \ 130990075Sobrien X = copy_rtx (X); \ 131090075Sobrien push_reload (orig_X, NULL_RTX, &X, NULL, \ 131190075Sobrien MODE_BASE_REG_CLASS (MODE), \ 131290075Sobrien Pmode, VOIDmode, 0, 0, OPNUM, TYPE); \ 131390075Sobrien goto WIN; \ 131490075Sobrien } \ 131590075Sobrien} 131690075Sobrien 131790075Sobrien#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \ 131890075Sobrien if (TARGET_ARM) \ 131990075Sobrien ARM_LEGITIMIZE_RELOAD_ADDRESS (X, MODE, OPNUM, TYPE, IND_LEVELS, WIN); \ 132090075Sobrien else \ 132190075Sobrien THUMB_LEGITIMIZE_RELOAD_ADDRESS (X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) 132290075Sobrien 132390075Sobrien/* Return the maximum number of consecutive registers 132490075Sobrien needed to represent mode MODE in a register of class CLASS. 132590075Sobrien ARM regs are UNITS_PER_WORD bits while FPU regs can hold any FP mode */ 132690075Sobrien#define CLASS_MAX_NREGS(CLASS, MODE) \ 132790075Sobrien ((CLASS) == FPU_REGS ? 1 : NUM_REGS (MODE)) 132890075Sobrien 132990075Sobrien/* Moves between FPU_REGS and GENERAL_REGS are two memory insns. */ 133090075Sobrien#define REGISTER_MOVE_COST(MODE, FROM, TO) \ 133190075Sobrien (TARGET_ARM ? \ 133290075Sobrien ((FROM) == FPU_REGS && (TO) != FPU_REGS ? 20 : \ 133390075Sobrien (FROM) != FPU_REGS && (TO) == FPU_REGS ? 20 : 2) \ 133490075Sobrien : \ 133590075Sobrien ((FROM) == HI_REGS || (TO) == HI_REGS) ? 4 : 2) 133690075Sobrien 133790075Sobrien/* Stack layout; function entry, exit and calling. */ 133890075Sobrien 133990075Sobrien/* Define this if pushing a word on the stack 134090075Sobrien makes the stack pointer a smaller address. */ 134190075Sobrien#define STACK_GROWS_DOWNWARD 1 134290075Sobrien 134390075Sobrien/* Define this if the nominal address of the stack frame 134490075Sobrien is at the high-address end of the local variables; 134590075Sobrien that is, each additional local variable allocated 134690075Sobrien goes at a more negative offset in the frame. */ 134790075Sobrien#define FRAME_GROWS_DOWNWARD 1 134890075Sobrien 134990075Sobrien/* Offset within stack frame to start allocating local variables at. 135090075Sobrien If FRAME_GROWS_DOWNWARD, this is the offset to the END of the 135190075Sobrien first local allocated. Otherwise, it is the offset to the BEGINNING 135290075Sobrien of the first local allocated. */ 135390075Sobrien#define STARTING_FRAME_OFFSET 0 135490075Sobrien 135590075Sobrien/* If we generate an insn to push BYTES bytes, 135690075Sobrien this says how many the stack pointer really advances by. */ 135790075Sobrien/* The push insns do not do this rounding implicitly. 135890075Sobrien So don't define this. */ 135990075Sobrien/* #define PUSH_ROUNDING(NPUSHED) ROUND_UP (NPUSHED) */ 136090075Sobrien 136190075Sobrien/* Define this if the maximum size of all the outgoing args is to be 136290075Sobrien accumulated and pushed during the prologue. The amount can be 136390075Sobrien found in the variable current_function_outgoing_args_size. */ 136490075Sobrien#define ACCUMULATE_OUTGOING_ARGS 1 136590075Sobrien 136690075Sobrien/* Offset of first parameter from the argument pointer register value. */ 136790075Sobrien#define FIRST_PARM_OFFSET(FNDECL) (TARGET_ARM ? 4 : 0) 136890075Sobrien 136990075Sobrien/* Value is the number of byte of arguments automatically 137090075Sobrien popped when returning from a subroutine call. 137190075Sobrien FUNDECL is the declaration node of the function (as a tree), 137290075Sobrien FUNTYPE is the data type of the function (as a tree), 137390075Sobrien or for a library call it is an identifier node for the subroutine name. 137490075Sobrien SIZE is the number of bytes of arguments passed on the stack. 137590075Sobrien 137690075Sobrien On the ARM, the caller does not pop any of its arguments that were passed 137790075Sobrien on the stack. */ 137890075Sobrien#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, SIZE) 0 137990075Sobrien 138090075Sobrien/* Define how to find the value returned by a library function 138190075Sobrien assuming the value has mode MODE. */ 138290075Sobrien#define LIBCALL_VALUE(MODE) \ 138390075Sobrien (TARGET_ARM && TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT \ 138490075Sobrien ? gen_rtx_REG (MODE, FIRST_ARM_FP_REGNUM) \ 138590075Sobrien : gen_rtx_REG (MODE, ARG_REGISTER (1))) 138690075Sobrien 138790075Sobrien/* Define how to find the value returned by a function. 138890075Sobrien VALTYPE is the data type of the value (as a tree). 138990075Sobrien If the precise function being called is known, FUNC is its FUNCTION_DECL; 139090075Sobrien otherwise, FUNC is 0. */ 139190075Sobrien#define FUNCTION_VALUE(VALTYPE, FUNC) \ 139290075Sobrien LIBCALL_VALUE (TYPE_MODE (VALTYPE)) 139390075Sobrien 139490075Sobrien/* 1 if N is a possible register number for a function value. 139590075Sobrien On the ARM, only r0 and f0 can return results. */ 139690075Sobrien#define FUNCTION_VALUE_REGNO_P(REGNO) \ 139790075Sobrien ((REGNO) == ARG_REGISTER (1) \ 139890075Sobrien || (TARGET_ARM && ((REGNO) == FIRST_ARM_FP_REGNUM) && TARGET_HARD_FLOAT)) 139990075Sobrien 140090075Sobrien/* How large values are returned */ 140190075Sobrien/* A C expression which can inhibit the returning of certain function values 140290075Sobrien in registers, based on the type of value. */ 140390075Sobrien#define RETURN_IN_MEMORY(TYPE) arm_return_in_memory (TYPE) 140490075Sobrien 140590075Sobrien/* Define DEFAULT_PCC_STRUCT_RETURN to 1 if all structure and union return 140690075Sobrien values must be in memory. On the ARM, they need only do so if larger 140790075Sobrien than a word, or if they contain elements offset from zero in the struct. */ 140890075Sobrien#define DEFAULT_PCC_STRUCT_RETURN 0 140990075Sobrien 141090075Sobrien/* Flags for the call/call_value rtl operations set up by function_arg. */ 141190075Sobrien#define CALL_NORMAL 0x00000000 /* No special processing. */ 141290075Sobrien#define CALL_LONG 0x00000001 /* Always call indirect. */ 141390075Sobrien#define CALL_SHORT 0x00000002 /* Never call indirect. */ 141490075Sobrien 141590075Sobrien/* These bits describe the different types of function supported 141690075Sobrien by the ARM backend. They are exclusive. ie a function cannot be both a 141790075Sobrien normal function and an interworked function, for example. Knowing the 141890075Sobrien type of a function is important for determining its prologue and 141990075Sobrien epilogue sequences. 142090075Sobrien Note value 7 is currently unassigned. Also note that the interrupt 142190075Sobrien function types all have bit 2 set, so that they can be tested for easily. 142290075Sobrien Note that 0 is deliberately chosen for ARM_FT_UNKNOWN so that when the 142390075Sobrien machine_function structure is initialised (to zero) func_type will 142490075Sobrien default to unknown. This will force the first use of arm_current_func_type 142590075Sobrien to call arm_compute_func_type. */ 142690075Sobrien#define ARM_FT_UNKNOWN 0 /* Type has not yet been determined. */ 142790075Sobrien#define ARM_FT_NORMAL 1 /* Your normal, straightforward function. */ 142890075Sobrien#define ARM_FT_INTERWORKED 2 /* A function that supports interworking. */ 142990075Sobrien#define ARM_FT_EXCEPTION_HANDLER 3 /* A C++ exception handler. */ 143090075Sobrien#define ARM_FT_ISR 4 /* An interrupt service routine. */ 143190075Sobrien#define ARM_FT_FIQ 5 /* A fast interrupt service routine. */ 143290075Sobrien#define ARM_FT_EXCEPTION 6 /* An ARM exception handler (subcase of ISR). */ 143390075Sobrien 143490075Sobrien#define ARM_FT_TYPE_MASK ((1 << 3) - 1) 143590075Sobrien 143690075Sobrien/* In addition functions can have several type modifiers, 143790075Sobrien outlined by these bit masks: */ 143890075Sobrien#define ARM_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR and above. */ 143990075Sobrien#define ARM_FT_NAKED (1 << 3) /* No prologue or epilogue. */ 144090075Sobrien#define ARM_FT_VOLATILE (1 << 4) /* Does not return. */ 144190075Sobrien#define ARM_FT_NESTED (1 << 5) /* Embedded inside another func. */ 144290075Sobrien 144390075Sobrien/* Some macros to test these flags. */ 144490075Sobrien#define ARM_FUNC_TYPE(t) (t & ARM_FT_TYPE_MASK) 144590075Sobrien#define IS_INTERRUPT(t) (t & ARM_FT_INTERRUPT) 144690075Sobrien#define IS_VOLATILE(t) (t & ARM_FT_VOLATILE) 144790075Sobrien#define IS_NAKED(t) (t & ARM_FT_NAKED) 144890075Sobrien#define IS_NESTED(t) (t & ARM_FT_NESTED) 144990075Sobrien 145090075Sobrien/* A C structure for machine-specific, per-function data. 145190075Sobrien This is added to the cfun structure. */ 145290075Sobrientypedef struct machine_function 145390075Sobrien{ 145490075Sobrien /* Additionsl stack adjustment in __builtin_eh_throw. */ 145590075Sobrien struct rtx_def *eh_epilogue_sp_ofs; 145690075Sobrien /* Records if LR has to be saved for far jumps. */ 145790075Sobrien int far_jump_used; 145890075Sobrien /* Records if ARG_POINTER was ever live. */ 145990075Sobrien int arg_pointer_live; 146090075Sobrien /* Records if the save of LR has been eliminated. */ 146190075Sobrien int lr_save_eliminated; 146290075Sobrien /* Records the type of the current function. */ 146390075Sobrien unsigned long func_type; 146496263Sobrien /* Record if the function has a variable argument list. */ 146596263Sobrien int uses_anonymous_args; 146690075Sobrien} 146790075Sobrienmachine_function; 146890075Sobrien 146990075Sobrien/* A C type for declaring a variable that is used as the first argument of 147090075Sobrien `FUNCTION_ARG' and other related values. For some target machines, the 147190075Sobrien type `int' suffices and can hold the number of bytes of argument so far. */ 147290075Sobrientypedef struct 147390075Sobrien{ 147490075Sobrien /* This is the number of registers of arguments scanned so far. */ 147590075Sobrien int nregs; 147690075Sobrien /* One of CALL_NORMAL, CALL_LONG or CALL_SHORT . */ 147790075Sobrien int call_cookie; 147890075Sobrien} CUMULATIVE_ARGS; 147990075Sobrien 148090075Sobrien/* Define where to put the arguments to a function. 148190075Sobrien Value is zero to push the argument on the stack, 148290075Sobrien or a hard register in which to store the argument. 148390075Sobrien 148490075Sobrien MODE is the argument's machine mode. 148590075Sobrien TYPE is the data type of the argument (as a tree). 148690075Sobrien This is null for libcalls where that information may 148790075Sobrien not be available. 148890075Sobrien CUM is a variable of type CUMULATIVE_ARGS which gives info about 148990075Sobrien the preceding args and about the function being called. 149090075Sobrien NAMED is nonzero if this argument is a named parameter 149190075Sobrien (otherwise it is an extra parameter matching an ellipsis). 149290075Sobrien 149390075Sobrien On the ARM, normally the first 16 bytes are passed in registers r0-r3; all 149490075Sobrien other arguments are passed on the stack. If (NAMED == 0) (which happens 149590075Sobrien only in assign_parms, since SETUP_INCOMING_VARARGS is defined), say it is 149690075Sobrien passed in the stack (function_prologue will indeed make it pass in the 149790075Sobrien stack if necessary). */ 149890075Sobrien#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ 149990075Sobrien arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED)) 150090075Sobrien 150190075Sobrien/* For an arg passed partly in registers and partly in memory, 150290075Sobrien this is the number of registers used. 150390075Sobrien For args passed entirely in registers or entirely in memory, zero. */ 150490075Sobrien#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ 150590075Sobrien ( NUM_ARG_REGS > (CUM).nregs \ 150690075Sobrien && (NUM_ARG_REGS < ((CUM).nregs + NUM_REGS2 (MODE, TYPE))) \ 150790075Sobrien ? NUM_ARG_REGS - (CUM).nregs : 0) 150890075Sobrien 150990075Sobrien/* Initialize a variable CUM of type CUMULATIVE_ARGS 151090075Sobrien for a call to a function whose data type is FNTYPE. 151190075Sobrien For a library call, FNTYPE is 0. 151290075Sobrien On the ARM, the offset starts at 0. */ 151390075Sobrien#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \ 151490075Sobrien arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (INDIRECT)) 151590075Sobrien 151690075Sobrien/* Update the data in CUM to advance over an argument 151790075Sobrien of mode MODE and data type TYPE. 151890075Sobrien (TYPE is null for libcalls where that information may not be available.) */ 151990075Sobrien#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ 152090075Sobrien (CUM).nregs += NUM_REGS2 (MODE, TYPE) 152190075Sobrien 152290075Sobrien/* 1 if N is a possible register number for function argument passing. 152390075Sobrien On the ARM, r0-r3 are used to pass args. */ 152490075Sobrien#define FUNCTION_ARG_REGNO_P(REGNO) (IN_RANGE ((REGNO), 0, 3)) 152590075Sobrien 152690075Sobrien 152790075Sobrien/* Tail calling. */ 152890075Sobrien 152990075Sobrien/* A C expression that evaluates to true if it is ok to perform a sibling 153090075Sobrien call to DECL. */ 153190075Sobrien#define FUNCTION_OK_FOR_SIBCALL(DECL) arm_function_ok_for_sibcall ((DECL)) 153290075Sobrien 153390075Sobrien/* Perform any actions needed for a function that is receiving a variable 153490075Sobrien number of arguments. CUM is as above. MODE and TYPE are the mode and type 153590075Sobrien of the current parameter. PRETEND_SIZE is a variable that should be set to 153690075Sobrien the amount of stack that must be pushed by the prolog to pretend that our 153790075Sobrien caller pushed it. 153890075Sobrien 153990075Sobrien Normally, this macro will push all remaining incoming registers on the 154090075Sobrien stack and set PRETEND_SIZE to the length of the registers pushed. 154190075Sobrien 154290075Sobrien On the ARM, PRETEND_SIZE is set in order to have the prologue push the last 154390075Sobrien named arg and all anonymous args onto the stack. 154490075Sobrien XXX I know the prologue shouldn't be pushing registers, but it is faster 154590075Sobrien that way. */ 154690075Sobrien#define SETUP_INCOMING_VARARGS(CUM, MODE, TYPE, PRETEND_SIZE, NO_RTL) \ 154790075Sobrien{ \ 154896263Sobrien cfun->machine->uses_anonymous_args = 1; \ 154990075Sobrien if ((CUM).nregs < NUM_ARG_REGS) \ 155090075Sobrien (PRETEND_SIZE) = (NUM_ARG_REGS - (CUM).nregs) * UNITS_PER_WORD; \ 155190075Sobrien} 155290075Sobrien 155390075Sobrien/* If your target environment doesn't prefix user functions with an 155490075Sobrien underscore, you may wish to re-define this to prevent any conflicts. 155590075Sobrien e.g. AOF may prefix mcount with an underscore. */ 155690075Sobrien#ifndef ARM_MCOUNT_NAME 155790075Sobrien#define ARM_MCOUNT_NAME "*mcount" 155890075Sobrien#endif 155990075Sobrien 156090075Sobrien/* Call the function profiler with a given profile label. The Acorn 156190075Sobrien compiler puts this BEFORE the prolog but gcc puts it afterwards. 156290075Sobrien On the ARM the full profile code will look like: 156390075Sobrien .data 156490075Sobrien LP1 156590075Sobrien .word 0 156690075Sobrien .text 156790075Sobrien mov ip, lr 156890075Sobrien bl mcount 156990075Sobrien .word LP1 157090075Sobrien 157190075Sobrien profile_function() in final.c outputs the .data section, FUNCTION_PROFILER 157290075Sobrien will output the .text section. 157390075Sobrien 157490075Sobrien The ``mov ip,lr'' seems like a good idea to stick with cc convention. 157590075Sobrien ``prof'' doesn't seem to mind about this! */ 157690075Sobrien#ifndef ARM_FUNCTION_PROFILER 157790075Sobrien#define ARM_FUNCTION_PROFILER(STREAM, LABELNO) \ 157890075Sobrien{ \ 157990075Sobrien char temp[20]; \ 158090075Sobrien rtx sym; \ 158190075Sobrien \ 158290075Sobrien asm_fprintf (STREAM, "\tmov\t%r, %r\n\tbl\t", \ 158390075Sobrien IP_REGNUM, LR_REGNUM); \ 158490075Sobrien assemble_name (STREAM, ARM_MCOUNT_NAME); \ 158590075Sobrien fputc ('\n', STREAM); \ 158690075Sobrien ASM_GENERATE_INTERNAL_LABEL (temp, "LP", LABELNO); \ 158790075Sobrien sym = gen_rtx (SYMBOL_REF, Pmode, temp); \ 158890075Sobrien assemble_aligned_integer (UNITS_PER_WORD, sym); \ 158990075Sobrien} 159090075Sobrien#endif 159190075Sobrien 159290075Sobrien#ifndef THUMB_FUNCTION_PROFILER 159390075Sobrien#define THUMB_FUNCTION_PROFILER(STREAM, LABELNO) \ 159490075Sobrien{ \ 159590075Sobrien fprintf (STREAM, "\tmov\tip, lr\n"); \ 159690075Sobrien fprintf (STREAM, "\tbl\tmcount\n"); \ 159790075Sobrien fprintf (STREAM, "\t.word\tLP%d\n", LABELNO); \ 159890075Sobrien} 159990075Sobrien#endif 160090075Sobrien 160190075Sobrien#define FUNCTION_PROFILER(STREAM, LABELNO) \ 160290075Sobrien if (TARGET_ARM) \ 160390075Sobrien ARM_FUNCTION_PROFILER (STREAM, LABELNO) \ 160490075Sobrien else \ 160590075Sobrien THUMB_FUNCTION_PROFILER (STREAM, LABELNO) 160690075Sobrien 160790075Sobrien/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, 160890075Sobrien the stack pointer does not matter. The value is tested only in 160990075Sobrien functions that have frame pointers. 161090075Sobrien No definition is equivalent to always zero. 161190075Sobrien 161290075Sobrien On the ARM, the function epilogue recovers the stack pointer from the 161390075Sobrien frame. */ 161490075Sobrien#define EXIT_IGNORE_STACK 1 161590075Sobrien 161690075Sobrien#define EPILOGUE_USES(REGNO) (reload_completed && (REGNO) == LR_REGNUM) 161790075Sobrien 161890075Sobrien/* Determine if the epilogue should be output as RTL. 161990075Sobrien You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ 162090075Sobrien#define USE_RETURN_INSN(ISCOND) \ 162190075Sobrien (TARGET_ARM ? use_return_insn (ISCOND) : 0) 162290075Sobrien 162390075Sobrien/* Definitions for register eliminations. 162490075Sobrien 162590075Sobrien This is an array of structures. Each structure initializes one pair 162690075Sobrien of eliminable registers. The "from" register number is given first, 162790075Sobrien followed by "to". Eliminations of the same "from" register are listed 162890075Sobrien in order of preference. 162990075Sobrien 163090075Sobrien We have two registers that can be eliminated on the ARM. First, the 163190075Sobrien arg pointer register can often be eliminated in favor of the stack 163290075Sobrien pointer register. Secondly, the pseudo frame pointer register can always 163390075Sobrien be eliminated; it is replaced with either the stack or the real frame 163490075Sobrien pointer. Note we have to use {ARM|THUMB}_HARD_FRAME_POINTER_REGNUM 163590075Sobrien because the definition of HARD_FRAME_POINTER_REGNUM is not a constant. */ 163690075Sobrien 163790075Sobrien#define ELIMINABLE_REGS \ 163890075Sobrien{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM },\ 163990075Sobrien { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM },\ 164090075Sobrien { ARG_POINTER_REGNUM, ARM_HARD_FRAME_POINTER_REGNUM },\ 164190075Sobrien { ARG_POINTER_REGNUM, THUMB_HARD_FRAME_POINTER_REGNUM },\ 164290075Sobrien { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM },\ 164390075Sobrien { FRAME_POINTER_REGNUM, ARM_HARD_FRAME_POINTER_REGNUM },\ 164490075Sobrien { FRAME_POINTER_REGNUM, THUMB_HARD_FRAME_POINTER_REGNUM }} 164590075Sobrien 164690075Sobrien/* Given FROM and TO register numbers, say whether this elimination is 164790075Sobrien allowed. Frame pointer elimination is automatically handled. 164890075Sobrien 164990075Sobrien All eliminations are permissible. Note that ARG_POINTER_REGNUM and 165090075Sobrien HARD_FRAME_POINTER_REGNUM are in fact the same thing. If we need a frame 165190075Sobrien pointer, we must eliminate FRAME_POINTER_REGNUM into 165290075Sobrien HARD_FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM or 165390075Sobrien ARG_POINTER_REGNUM. */ 165490075Sobrien#define CAN_ELIMINATE(FROM, TO) \ 165590075Sobrien (((TO) == FRAME_POINTER_REGNUM && (FROM) == ARG_POINTER_REGNUM) ? 0 : \ 165690075Sobrien ((TO) == STACK_POINTER_REGNUM && frame_pointer_needed) ? 0 : \ 165790075Sobrien ((TO) == ARM_HARD_FRAME_POINTER_REGNUM && TARGET_THUMB) ? 0 : \ 165890075Sobrien ((TO) == THUMB_HARD_FRAME_POINTER_REGNUM && TARGET_ARM) ? 0 : \ 165990075Sobrien 1) 166090075Sobrien 166190075Sobrien/* Define the offset between two registers, one to be eliminated, and the 166290075Sobrien other its replacement, at the start of a routine. */ 166390075Sobrien#define ARM_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ 166490075Sobrien do \ 166590075Sobrien { \ 166690075Sobrien (OFFSET) = arm_compute_initial_elimination_offset (FROM, TO); \ 166790075Sobrien } \ 166890075Sobrien while (0) 166990075Sobrien 167090075Sobrien/* Note: This macro must match the code in thumb_function_prologue(). */ 167190075Sobrien#define THUMB_INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ 167290075Sobrien{ \ 167390075Sobrien (OFFSET) = 0; \ 167490075Sobrien if ((FROM) == ARG_POINTER_REGNUM) \ 167590075Sobrien { \ 167690075Sobrien int count_regs = 0; \ 167790075Sobrien int regno; \ 167890075Sobrien for (regno = 8; regno < 13; regno ++) \ 167990075Sobrien if (regs_ever_live[regno] && ! call_used_regs[regno]) \ 168090075Sobrien count_regs ++; \ 168190075Sobrien if (count_regs) \ 168290075Sobrien (OFFSET) += 4 * count_regs; \ 168390075Sobrien count_regs = 0; \ 168490075Sobrien for (regno = 0; regno <= LAST_LO_REGNUM; regno ++) \ 168590075Sobrien if (regs_ever_live[regno] && ! call_used_regs[regno]) \ 168690075Sobrien count_regs ++; \ 168790075Sobrien if (count_regs || ! leaf_function_p () || thumb_far_jump_used_p (0))\ 168890075Sobrien (OFFSET) += 4 * (count_regs + 1); \ 168990075Sobrien if (TARGET_BACKTRACE) \ 169090075Sobrien { \ 169190075Sobrien if ((count_regs & 0xFF) == 0 && (regs_ever_live[3] != 0)) \ 169290075Sobrien (OFFSET) += 20; \ 169390075Sobrien else \ 169490075Sobrien (OFFSET) += 16; \ 169590075Sobrien } \ 169690075Sobrien } \ 169790075Sobrien if ((TO) == STACK_POINTER_REGNUM) \ 169890075Sobrien { \ 169990075Sobrien (OFFSET) += current_function_outgoing_args_size; \ 170090075Sobrien (OFFSET) += ROUND_UP (get_frame_size ()); \ 170190075Sobrien } \ 170290075Sobrien} 170390075Sobrien 170490075Sobrien#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ 170590075Sobrien if (TARGET_ARM) \ 170690075Sobrien ARM_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET); \ 170790075Sobrien else \ 170890075Sobrien THUMB_INITIAL_ELIMINATION_OFFSET (FROM, TO, OFFSET) 170990075Sobrien 171090075Sobrien/* Special case handling of the location of arguments passed on the stack. */ 171190075Sobrien#define DEBUGGER_ARG_OFFSET(value, addr) value ? value : arm_debugger_arg_offset (value, addr) 171290075Sobrien 171390075Sobrien/* Initialize data used by insn expanders. This is called from insn_emit, 171490075Sobrien once for every function before code is generated. */ 171590075Sobrien#define INIT_EXPANDERS arm_init_expanders () 171690075Sobrien 171790075Sobrien/* Output assembler code for a block containing the constant parts 171890075Sobrien of a trampoline, leaving space for the variable parts. 171990075Sobrien 172090075Sobrien On the ARM, (if r8 is the static chain regnum, and remembering that 172190075Sobrien referencing pc adds an offset of 8) the trampoline looks like: 172290075Sobrien ldr r8, [pc, #0] 172390075Sobrien ldr pc, [pc] 172490075Sobrien .word static chain value 172590075Sobrien .word function's address 172690075Sobrien ??? FIXME: When the trampoline returns, r8 will be clobbered. */ 172790075Sobrien#define ARM_TRAMPOLINE_TEMPLATE(FILE) \ 172890075Sobrien{ \ 172990075Sobrien asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n", \ 173090075Sobrien STATIC_CHAIN_REGNUM, PC_REGNUM); \ 173190075Sobrien asm_fprintf (FILE, "\tldr\t%r, [%r, #0]\n", \ 173290075Sobrien PC_REGNUM, PC_REGNUM); \ 173390075Sobrien assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); \ 173490075Sobrien assemble_aligned_integer (UNITS_PER_WORD, const0_rtx); \ 173590075Sobrien} 173690075Sobrien 173790075Sobrien/* On the Thumb we always switch into ARM mode to execute the trampoline. 173890075Sobrien Why - because it is easier. This code will always be branched to via 173990075Sobrien a BX instruction and since the compiler magically generates the address 174090075Sobrien of the function the linker has no opportunity to ensure that the 174190075Sobrien bottom bit is set. Thus the processor will be in ARM mode when it 174290075Sobrien reaches this code. So we duplicate the ARM trampoline code and add 174390075Sobrien a switch into Thumb mode as well. */ 174490075Sobrien#define THUMB_TRAMPOLINE_TEMPLATE(FILE) \ 174590075Sobrien{ \ 174690075Sobrien fprintf (FILE, "\t.code 32\n"); \ 174790075Sobrien fprintf (FILE, ".Ltrampoline_start:\n"); \ 174890075Sobrien asm_fprintf (FILE, "\tldr\t%r, [%r, #8]\n", \ 174990075Sobrien STATIC_CHAIN_REGNUM, PC_REGNUM); \ 175090075Sobrien asm_fprintf (FILE, "\tldr\t%r, [%r, #8]\n", \ 175190075Sobrien IP_REGNUM, PC_REGNUM); \ 175290075Sobrien asm_fprintf (FILE, "\torr\t%r, %r, #1\n", \ 175390075Sobrien IP_REGNUM, IP_REGNUM); \ 175490075Sobrien asm_fprintf (FILE, "\tbx\t%r\n", IP_REGNUM); \ 175590075Sobrien fprintf (FILE, "\t.word\t0\n"); \ 175690075Sobrien fprintf (FILE, "\t.word\t0\n"); \ 175790075Sobrien fprintf (FILE, "\t.code 16\n"); \ 175890075Sobrien} 175990075Sobrien 176090075Sobrien#define TRAMPOLINE_TEMPLATE(FILE) \ 176190075Sobrien if (TARGET_ARM) \ 176290075Sobrien ARM_TRAMPOLINE_TEMPLATE (FILE) \ 176390075Sobrien else \ 176490075Sobrien THUMB_TRAMPOLINE_TEMPLATE (FILE) 176590075Sobrien 176690075Sobrien/* Length in units of the trampoline for entering a nested function. */ 176790075Sobrien#define TRAMPOLINE_SIZE (TARGET_ARM ? 16 : 24) 176890075Sobrien 176990075Sobrien/* Alignment required for a trampoline in bits. */ 177090075Sobrien#define TRAMPOLINE_ALIGNMENT 32 177190075Sobrien 177290075Sobrien/* Emit RTL insns to initialize the variable parts of a trampoline. 177390075Sobrien FNADDR is an RTX for the address of the function's pure code. 177490075Sobrien CXT is an RTX for the static chain value for the function. */ 177590075Sobrien#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ 177690075Sobrien{ \ 177790075Sobrien emit_move_insn \ 177890075Sobrien (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 8 : 16)), CXT); \ 177990075Sobrien emit_move_insn \ 178090075Sobrien (gen_rtx_MEM (SImode, plus_constant (TRAMP, TARGET_ARM ? 12 : 20)), FNADDR); \ 178190075Sobrien} 178290075Sobrien 178390075Sobrien 178490075Sobrien/* Addressing modes, and classification of registers for them. */ 178590075Sobrien#define HAVE_POST_INCREMENT 1 178690075Sobrien#define HAVE_PRE_INCREMENT TARGET_ARM 178790075Sobrien#define HAVE_POST_DECREMENT TARGET_ARM 178890075Sobrien#define HAVE_PRE_DECREMENT TARGET_ARM 178990075Sobrien 179090075Sobrien/* Macros to check register numbers against specific register classes. */ 179190075Sobrien 179290075Sobrien/* These assume that REGNO is a hard or pseudo reg number. 179390075Sobrien They give nonzero only if REGNO is a hard reg of the suitable class 179490075Sobrien or a pseudo reg currently allocated to a suitable hard reg. 179590075Sobrien Since they use reg_renumber, they are safe only once reg_renumber 179690075Sobrien has been allocated, which happens in local-alloc.c. */ 179790075Sobrien#define TEST_REGNO(R, TEST, VALUE) \ 179890075Sobrien ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE)) 179990075Sobrien 180090075Sobrien/* On the ARM, don't allow the pc to be used. */ 180190075Sobrien#define ARM_REGNO_OK_FOR_BASE_P(REGNO) \ 180290075Sobrien (TEST_REGNO (REGNO, <, PC_REGNUM) \ 180390075Sobrien || TEST_REGNO (REGNO, ==, FRAME_POINTER_REGNUM) \ 180490075Sobrien || TEST_REGNO (REGNO, ==, ARG_POINTER_REGNUM)) 180590075Sobrien 180690075Sobrien#define THUMB_REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \ 180790075Sobrien (TEST_REGNO (REGNO, <=, LAST_LO_REGNUM) \ 180890075Sobrien || (GET_MODE_SIZE (MODE) >= 4 \ 180990075Sobrien && TEST_REGNO (REGNO, ==, STACK_POINTER_REGNUM))) 181090075Sobrien 181190075Sobrien#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) \ 181290075Sobrien (TARGET_THUMB \ 181390075Sobrien ? THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO, MODE) \ 181490075Sobrien : ARM_REGNO_OK_FOR_BASE_P (REGNO)) 181590075Sobrien 181690075Sobrien/* For ARM code, we don't care about the mode, but for Thumb, the index 181790075Sobrien must be suitable for use in a QImode load. */ 181890075Sobrien#define REGNO_OK_FOR_INDEX_P(REGNO) \ 181990075Sobrien REGNO_MODE_OK_FOR_BASE_P (REGNO, QImode) 182090075Sobrien 182190075Sobrien/* Maximum number of registers that can appear in a valid memory address. 182290075Sobrien Shifts in addresses can't be by a register. */ 182390075Sobrien#define MAX_REGS_PER_ADDRESS 2 182490075Sobrien 182590075Sobrien/* Recognize any constant value that is a valid address. */ 182690075Sobrien/* XXX We can address any constant, eventually... */ 182790075Sobrien 182890075Sobrien#ifdef AOF_ASSEMBLER 182990075Sobrien 183090075Sobrien#define CONSTANT_ADDRESS_P(X) \ 183190075Sobrien (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X)) 183290075Sobrien 183390075Sobrien#else 183490075Sobrien 183590075Sobrien#define CONSTANT_ADDRESS_P(X) \ 183690075Sobrien (GET_CODE (X) == SYMBOL_REF \ 183790075Sobrien && (CONSTANT_POOL_ADDRESS_P (X) \ 183890075Sobrien || (TARGET_ARM && optimize > 0 && SYMBOL_REF_FLAG (X)))) 183990075Sobrien 184090075Sobrien#endif /* AOF_ASSEMBLER */ 184190075Sobrien 184290075Sobrien/* Nonzero if the constant value X is a legitimate general operand. 184390075Sobrien It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. 184490075Sobrien 184590075Sobrien On the ARM, allow any integer (invalid ones are removed later by insn 184690075Sobrien patterns), nice doubles and symbol_refs which refer to the function's 184790075Sobrien constant pool XXX. 184890075Sobrien 184990075Sobrien When generating pic allow anything. */ 185090075Sobrien#define ARM_LEGITIMATE_CONSTANT_P(X) (flag_pic || ! label_mentioned_p (X)) 185190075Sobrien 185290075Sobrien#define THUMB_LEGITIMATE_CONSTANT_P(X) \ 185390075Sobrien ( GET_CODE (X) == CONST_INT \ 185490075Sobrien || GET_CODE (X) == CONST_DOUBLE \ 185596263Sobrien || CONSTANT_ADDRESS_P (X) \ 185696263Sobrien || flag_pic) 185790075Sobrien 185890075Sobrien#define LEGITIMATE_CONSTANT_P(X) \ 185990075Sobrien (TARGET_ARM ? ARM_LEGITIMATE_CONSTANT_P (X) : THUMB_LEGITIMATE_CONSTANT_P (X)) 186090075Sobrien 186190075Sobrien/* Special characters prefixed to function names 186290075Sobrien in order to encode attribute like information. 186390075Sobrien Note, '@' and '*' have already been taken. */ 186490075Sobrien#define SHORT_CALL_FLAG_CHAR '^' 186590075Sobrien#define LONG_CALL_FLAG_CHAR '#' 186690075Sobrien 186790075Sobrien#define ENCODED_SHORT_CALL_ATTR_P(SYMBOL_NAME) \ 186890075Sobrien (*(SYMBOL_NAME) == SHORT_CALL_FLAG_CHAR) 186990075Sobrien 187090075Sobrien#define ENCODED_LONG_CALL_ATTR_P(SYMBOL_NAME) \ 187190075Sobrien (*(SYMBOL_NAME) == LONG_CALL_FLAG_CHAR) 187290075Sobrien 187390075Sobrien#ifndef SUBTARGET_NAME_ENCODING_LENGTHS 187490075Sobrien#define SUBTARGET_NAME_ENCODING_LENGTHS 187590075Sobrien#endif 187690075Sobrien 187790075Sobrien/* This is a C fragement for the inside of a switch statement. 187890075Sobrien Each case label should return the number of characters to 187990075Sobrien be stripped from the start of a function's name, if that 188090075Sobrien name starts with the indicated character. */ 188190075Sobrien#define ARM_NAME_ENCODING_LENGTHS \ 188290075Sobrien case SHORT_CALL_FLAG_CHAR: return 1; \ 188390075Sobrien case LONG_CALL_FLAG_CHAR: return 1; \ 188490075Sobrien case '*': return 1; \ 188590075Sobrien SUBTARGET_NAME_ENCODING_LENGTHS 188690075Sobrien 188790075Sobrien/* This has to be handled by a function because more than part of the 188890075Sobrien ARM backend uses function name prefixes to encode attributes. */ 188990075Sobrien#undef STRIP_NAME_ENCODING 189090075Sobrien#define STRIP_NAME_ENCODING(VAR, SYMBOL_NAME) \ 189190075Sobrien (VAR) = arm_strip_name_encoding (SYMBOL_NAME) 189290075Sobrien 189390075Sobrien/* This is how to output a reference to a user-level label named NAME. 189490075Sobrien `assemble_name' uses this. */ 189590075Sobrien#undef ASM_OUTPUT_LABELREF 189690075Sobrien#define ASM_OUTPUT_LABELREF(FILE, NAME) \ 189790075Sobrien asm_fprintf (FILE, "%U%s", arm_strip_name_encoding (NAME)) 189890075Sobrien 189990075Sobrien/* If we are referencing a function that is weak then encode a long call 190090075Sobrien flag in the function name, otherwise if the function is static or 190190075Sobrien or known to be defined in this file then encode a short call flag. 190290075Sobrien This macro is used inside the ENCODE_SECTION macro. */ 190390075Sobrien#define ARM_ENCODE_CALL_TYPE(decl) \ 190496263Sobrien if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd') \ 190590075Sobrien { \ 190696263Sobrien if (TREE_CODE (decl) == FUNCTION_DECL && DECL_WEAK (decl)) \ 190790075Sobrien arm_encode_call_attribute (decl, LONG_CALL_FLAG_CHAR); \ 190890075Sobrien else if (! TREE_PUBLIC (decl)) \ 190990075Sobrien arm_encode_call_attribute (decl, SHORT_CALL_FLAG_CHAR); \ 191090075Sobrien } 191190075Sobrien 191290075Sobrien/* Symbols in the text segment can be accessed without indirecting via the 191390075Sobrien constant pool; it may take an extra binary operation, but this is still 191490075Sobrien faster than indirecting via memory. Don't do this when not optimizing, 191590075Sobrien since we won't be calculating al of the offsets necessary to do this 191690075Sobrien simplification. */ 191790075Sobrien/* This doesn't work with AOF syntax, since the string table may be in 191890075Sobrien a different AREA. */ 191990075Sobrien#ifndef AOF_ASSEMBLER 192090075Sobrien#define ENCODE_SECTION_INFO(decl) \ 192190075Sobrien{ \ 192290075Sobrien if (optimize > 0 && TREE_CONSTANT (decl) \ 192390075Sobrien && (!flag_writable_strings || TREE_CODE (decl) != STRING_CST)) \ 192490075Sobrien { \ 192590075Sobrien rtx rtl = (TREE_CODE_CLASS (TREE_CODE (decl)) != 'd' \ 192690075Sobrien ? TREE_CST_RTL (decl) : DECL_RTL (decl)); \ 192790075Sobrien SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1; \ 192890075Sobrien } \ 192990075Sobrien ARM_ENCODE_CALL_TYPE (decl) \ 193090075Sobrien} 193190075Sobrien#else 193290075Sobrien#define ENCODE_SECTION_INFO(decl) \ 193390075Sobrien{ \ 193490075Sobrien ARM_ENCODE_CALL_TYPE (decl) \ 193590075Sobrien} 193690075Sobrien#endif 193790075Sobrien 193890075Sobrien#define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \ 193990075Sobrien arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR) 194090075Sobrien 194190075Sobrien/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx 194290075Sobrien and check its validity for a certain class. 194390075Sobrien We have two alternate definitions for each of them. 194490075Sobrien The usual definition accepts all pseudo regs; the other rejects 194590075Sobrien them unless they have been allocated suitable hard regs. 194690075Sobrien The symbol REG_OK_STRICT causes the latter definition to be used. */ 194790075Sobrien#ifndef REG_OK_STRICT 194890075Sobrien 194990075Sobrien#define ARM_REG_OK_FOR_BASE_P(X) \ 195090075Sobrien (REGNO (X) <= LAST_ARM_REGNUM \ 195190075Sobrien || REGNO (X) >= FIRST_PSEUDO_REGISTER \ 195290075Sobrien || REGNO (X) == FRAME_POINTER_REGNUM \ 195390075Sobrien || REGNO (X) == ARG_POINTER_REGNUM) 195490075Sobrien 195590075Sobrien#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \ 195690075Sobrien (REGNO (X) <= LAST_LO_REGNUM \ 195790075Sobrien || REGNO (X) >= FIRST_PSEUDO_REGISTER \ 195890075Sobrien || (GET_MODE_SIZE (MODE) >= 4 \ 195990075Sobrien && (REGNO (X) == STACK_POINTER_REGNUM \ 196090075Sobrien || (X) == hard_frame_pointer_rtx \ 196190075Sobrien || (X) == arg_pointer_rtx))) 196290075Sobrien 196390075Sobrien#else /* REG_OK_STRICT */ 196490075Sobrien 196590075Sobrien#define ARM_REG_OK_FOR_BASE_P(X) \ 196690075Sobrien ARM_REGNO_OK_FOR_BASE_P (REGNO (X)) 196790075Sobrien 196890075Sobrien#define THUMB_REG_MODE_OK_FOR_BASE_P(X, MODE) \ 196990075Sobrien THUMB_REGNO_MODE_OK_FOR_BASE_P (REGNO (X), MODE) 197090075Sobrien 197190075Sobrien#endif /* REG_OK_STRICT */ 197290075Sobrien 197390075Sobrien/* Now define some helpers in terms of the above. */ 197490075Sobrien 197590075Sobrien#define REG_MODE_OK_FOR_BASE_P(X, MODE) \ 197690075Sobrien (TARGET_THUMB \ 197790075Sobrien ? THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE) \ 197890075Sobrien : ARM_REG_OK_FOR_BASE_P (X)) 197990075Sobrien 198090075Sobrien#define ARM_REG_OK_FOR_INDEX_P(X) ARM_REG_OK_FOR_BASE_P (X) 198190075Sobrien 198290075Sobrien/* For Thumb, a valid index register is anything that can be used in 198390075Sobrien a byte load instruction. */ 198490075Sobrien#define THUMB_REG_OK_FOR_INDEX_P(X) THUMB_REG_MODE_OK_FOR_BASE_P (X, QImode) 198590075Sobrien 198690075Sobrien/* Nonzero if X is a hard reg that can be used as an index 198790075Sobrien or if it is a pseudo reg. On the Thumb, the stack pointer 198890075Sobrien is not suitable. */ 198990075Sobrien#define REG_OK_FOR_INDEX_P(X) \ 199090075Sobrien (TARGET_THUMB \ 199190075Sobrien ? THUMB_REG_OK_FOR_INDEX_P (X) \ 199290075Sobrien : ARM_REG_OK_FOR_INDEX_P (X)) 199390075Sobrien 199490075Sobrien 199590075Sobrien/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression 199690075Sobrien that is a valid memory address for an instruction. 199790075Sobrien The MODE argument is the machine mode for the MEM expression 199890075Sobrien that wants to use this address. 199990075Sobrien 200090075Sobrien The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS. */ 200190075Sobrien 200290075Sobrien/* --------------------------------arm version----------------------------- */ 200390075Sobrien#define ARM_BASE_REGISTER_RTX_P(X) \ 200490075Sobrien (GET_CODE (X) == REG && ARM_REG_OK_FOR_BASE_P (X)) 200590075Sobrien 200690075Sobrien#define ARM_INDEX_REGISTER_RTX_P(X) \ 200790075Sobrien (GET_CODE (X) == REG && ARM_REG_OK_FOR_INDEX_P (X)) 200890075Sobrien 200990075Sobrien/* A C statement (sans semicolon) to jump to LABEL for legitimate index RTXs 201090075Sobrien used by the macro GO_IF_LEGITIMATE_ADDRESS. Floating point indices can 201190075Sobrien only be small constants. */ 201290075Sobrien#define ARM_GO_IF_LEGITIMATE_INDEX(MODE, BASE_REGNO, INDEX, LABEL) \ 201390075Sobrien do \ 201490075Sobrien { \ 201590075Sobrien HOST_WIDE_INT range; \ 201690075Sobrien enum rtx_code code = GET_CODE (INDEX); \ 201790075Sobrien \ 201890075Sobrien if (TARGET_HARD_FLOAT && GET_MODE_CLASS (MODE) == MODE_FLOAT) \ 201990075Sobrien { \ 202090075Sobrien if (code == CONST_INT && INTVAL (INDEX) < 1024 \ 202190075Sobrien && INTVAL (INDEX) > -1024 \ 202290075Sobrien && (INTVAL (INDEX) & 3) == 0) \ 202390075Sobrien goto LABEL; \ 202490075Sobrien } \ 202590075Sobrien else \ 202690075Sobrien { \ 202790075Sobrien if (ARM_INDEX_REGISTER_RTX_P (INDEX) \ 202890075Sobrien && GET_MODE_SIZE (MODE) <= 4) \ 202990075Sobrien goto LABEL; \ 203090075Sobrien if (GET_MODE_SIZE (MODE) <= 4 && code == MULT \ 203190075Sobrien && (! arm_arch4 || (MODE) != HImode)) \ 203290075Sobrien { \ 203390075Sobrien rtx xiop0 = XEXP (INDEX, 0); \ 203490075Sobrien rtx xiop1 = XEXP (INDEX, 1); \ 203590075Sobrien if (ARM_INDEX_REGISTER_RTX_P (xiop0) \ 203690075Sobrien && power_of_two_operand (xiop1, SImode)) \ 203790075Sobrien goto LABEL; \ 203890075Sobrien if (ARM_INDEX_REGISTER_RTX_P (xiop1) \ 203990075Sobrien && power_of_two_operand (xiop0, SImode)) \ 204090075Sobrien goto LABEL; \ 204190075Sobrien } \ 204290075Sobrien if (GET_MODE_SIZE (MODE) <= 4 \ 204390075Sobrien && (code == LSHIFTRT || code == ASHIFTRT \ 204490075Sobrien || code == ASHIFT || code == ROTATERT) \ 204590075Sobrien && (! arm_arch4 || (MODE) != HImode)) \ 204690075Sobrien { \ 204790075Sobrien rtx op = XEXP (INDEX, 1); \ 204890075Sobrien if (ARM_INDEX_REGISTER_RTX_P (XEXP (INDEX, 0)) \ 204990075Sobrien && GET_CODE (op) == CONST_INT && INTVAL (op) > 0 \ 205090075Sobrien && INTVAL (op) <= 31) \ 205190075Sobrien goto LABEL; \ 205290075Sobrien } \ 205390075Sobrien /* NASTY: Since this limits the addressing of unsigned \ 205490075Sobrien byte loads. */ \ 205590075Sobrien range = ((MODE) == HImode || (MODE) == QImode) \ 205690075Sobrien ? (arm_arch4 ? 256 : 4095) : 4096; \ 205790075Sobrien if (code == CONST_INT && INTVAL (INDEX) < range \ 205890075Sobrien && INTVAL (INDEX) > -range) \ 205990075Sobrien goto LABEL; \ 206090075Sobrien } \ 206190075Sobrien } \ 206290075Sobrien while (0) 206390075Sobrien 206490075Sobrien/* Jump to LABEL if X is a valid address RTX. This must take 206590075Sobrien REG_OK_STRICT into account when deciding about valid registers. 206690075Sobrien 206790075Sobrien Allow REG, REG+REG, REG+INDEX, INDEX+REG, REG-INDEX, and non 206890075Sobrien floating SYMBOL_REF to the constant pool. Allow REG-only and 206990075Sobrien AUTINC-REG if handling TImode or HImode. Other symbol refs must be 207090075Sobrien forced though a static cell to ensure addressability. */ 207190075Sobrien#define ARM_GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \ 207290075Sobrien{ \ 207390075Sobrien if (ARM_BASE_REGISTER_RTX_P (X)) \ 207490075Sobrien goto LABEL; \ 207590075Sobrien else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC) \ 207690075Sobrien && GET_CODE (XEXP (X, 0)) == REG \ 207790075Sobrien && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \ 207890075Sobrien goto LABEL; \ 207990075Sobrien else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \ 208090075Sobrien && (GET_CODE (X) == LABEL_REF \ 208190075Sobrien || (GET_CODE (X) == CONST \ 208290075Sobrien && GET_CODE (XEXP ((X), 0)) == PLUS \ 208390075Sobrien && GET_CODE (XEXP (XEXP ((X), 0), 0)) == LABEL_REF \ 208490075Sobrien && GET_CODE (XEXP (XEXP ((X), 0), 1)) == CONST_INT)))\ 208590075Sobrien goto LABEL; \ 208690075Sobrien else if ((MODE) == TImode) \ 208790075Sobrien ; \ 208890075Sobrien else if ((MODE) == DImode || (TARGET_SOFT_FLOAT && (MODE) == DFmode)) \ 208990075Sobrien { \ 209090075Sobrien if (GET_CODE (X) == PLUS && ARM_BASE_REGISTER_RTX_P (XEXP (X, 0)) \ 209190075Sobrien && GET_CODE (XEXP (X, 1)) == CONST_INT) \ 209290075Sobrien { \ 209390075Sobrien HOST_WIDE_INT val = INTVAL (XEXP (X, 1)); \ 209490075Sobrien if (val == 4 || val == -4 || val == -8) \ 209590075Sobrien goto LABEL; \ 209690075Sobrien } \ 209790075Sobrien } \ 209890075Sobrien else if (GET_CODE (X) == PLUS) \ 209990075Sobrien { \ 210090075Sobrien rtx xop0 = XEXP (X, 0); \ 210190075Sobrien rtx xop1 = XEXP (X, 1); \ 210290075Sobrien \ 210390075Sobrien if (ARM_BASE_REGISTER_RTX_P (xop0)) \ 210490075Sobrien ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop0), xop1, LABEL); \ 210590075Sobrien else if (ARM_BASE_REGISTER_RTX_P (xop1)) \ 210690075Sobrien ARM_GO_IF_LEGITIMATE_INDEX (MODE, REGNO (xop1), xop0, LABEL); \ 210790075Sobrien } \ 210890075Sobrien /* Reload currently can't handle MINUS, so disable this for now */ \ 210990075Sobrien /* else if (GET_CODE (X) == MINUS) \ 211090075Sobrien { \ 211190075Sobrien rtx xop0 = XEXP (X,0); \ 211290075Sobrien rtx xop1 = XEXP (X,1); \ 211390075Sobrien \ 211490075Sobrien if (ARM_BASE_REGISTER_RTX_P (xop0)) \ 211590075Sobrien ARM_GO_IF_LEGITIMATE_INDEX (MODE, -1, xop1, LABEL); \ 211690075Sobrien } */ \ 211790075Sobrien else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \ 211890075Sobrien && GET_CODE (X) == SYMBOL_REF \ 211990075Sobrien && CONSTANT_POOL_ADDRESS_P (X) \ 212090075Sobrien && ! (flag_pic \ 212190075Sobrien && symbol_mentioned_p (get_pool_constant (X)))) \ 212290075Sobrien goto LABEL; \ 212390075Sobrien else if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_DEC) \ 212490075Sobrien && (GET_MODE_SIZE (MODE) <= 4) \ 212590075Sobrien && GET_CODE (XEXP (X, 0)) == REG \ 212690075Sobrien && ARM_REG_OK_FOR_BASE_P (XEXP (X, 0))) \ 212790075Sobrien goto LABEL; \ 212890075Sobrien} 212990075Sobrien 213090075Sobrien/* ---------------------thumb version----------------------------------*/ 213190075Sobrien#define THUMB_LEGITIMATE_OFFSET(MODE, VAL) \ 213290075Sobrien (GET_MODE_SIZE (MODE) == 1 ? ((unsigned HOST_WIDE_INT) (VAL) < 32) \ 213390075Sobrien : GET_MODE_SIZE (MODE) == 2 ? ((unsigned HOST_WIDE_INT) (VAL) < 64 \ 213490075Sobrien && ((VAL) & 1) == 0) \ 213590075Sobrien : ((VAL) >= 0 && ((VAL) + GET_MODE_SIZE (MODE)) <= 128 \ 213690075Sobrien && ((VAL) & 3) == 0)) 213790075Sobrien 213890075Sobrien/* The AP may be eliminated to either the SP or the FP, so we use the 213990075Sobrien least common denominator, e.g. SImode, and offsets from 0 to 64. */ 214090075Sobrien 214190075Sobrien/* ??? Verify whether the above is the right approach. */ 214290075Sobrien 214390075Sobrien/* ??? Also, the FP may be eliminated to the SP, so perhaps that 214490075Sobrien needs special handling also. */ 214590075Sobrien 214690075Sobrien/* ??? Look at how the mips16 port solves this problem. It probably uses 214790075Sobrien better ways to solve some of these problems. */ 214890075Sobrien 214990075Sobrien/* Although it is not incorrect, we don't accept QImode and HImode 215090075Sobrien addresses based on the frame pointer or arg pointer until the 215190075Sobrien reload pass starts. This is so that eliminating such addresses 215290075Sobrien into stack based ones won't produce impossible code. */ 215390075Sobrien#define THUMB_GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \ 215490075Sobrien{ \ 215590075Sobrien/* ??? Not clear if this is right. Experiment. */ \ 215690075Sobrien if (GET_MODE_SIZE (MODE) < 4 \ 215790075Sobrien && ! (reload_in_progress || reload_completed) \ 215890075Sobrien && ( reg_mentioned_p (frame_pointer_rtx, X) \ 215990075Sobrien || reg_mentioned_p (arg_pointer_rtx, X) \ 216090075Sobrien || reg_mentioned_p (virtual_incoming_args_rtx, X) \ 216190075Sobrien || reg_mentioned_p (virtual_outgoing_args_rtx, X) \ 216290075Sobrien || reg_mentioned_p (virtual_stack_dynamic_rtx, X) \ 216390075Sobrien || reg_mentioned_p (virtual_stack_vars_rtx, X))) \ 216490075Sobrien ; \ 216590075Sobrien /* Accept any base register. SP only in SImode or larger. */ \ 216690075Sobrien else if (GET_CODE (X) == REG \ 216790075Sobrien && THUMB_REG_MODE_OK_FOR_BASE_P (X, MODE)) \ 216890075Sobrien goto WIN; \ 216990075Sobrien /* This is PC relative data before MACHINE_DEPENDENT_REORG runs. */ \ 217090075Sobrien else if (GET_MODE_SIZE (MODE) >= 4 && CONSTANT_P (X) \ 217190075Sobrien && CONSTANT_POOL_ADDRESS_P (X) && ! flag_pic) \ 217290075Sobrien goto WIN; \ 217390075Sobrien /* This is PC relative data after MACHINE_DEPENDENT_REORG runs. */ \ 217490075Sobrien else if (GET_MODE_SIZE (MODE) >= 4 && reload_completed \ 217590075Sobrien && (GET_CODE (X) == LABEL_REF \ 217690075Sobrien || (GET_CODE (X) == CONST \ 217790075Sobrien && GET_CODE (XEXP (X, 0)) == PLUS \ 217890075Sobrien && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF \ 217990075Sobrien && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT))) \ 218090075Sobrien goto WIN; \ 218190075Sobrien /* Post-inc indexing only supported for SImode and larger. */ \ 218290075Sobrien else if (GET_CODE (X) == POST_INC && GET_MODE_SIZE (MODE) >= 4 \ 218390075Sobrien && GET_CODE (XEXP (X, 0)) == REG \ 218490075Sobrien && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0))) \ 218590075Sobrien goto WIN; \ 218690075Sobrien else if (GET_CODE (X) == PLUS) \ 218790075Sobrien { \ 218890075Sobrien /* REG+REG address can be any two index registers. */ \ 218990075Sobrien /* We disallow FRAME+REG addressing since we know that FRAME \ 219090075Sobrien will be replaced with STACK, and SP relative addressing only \ 219190075Sobrien permits SP+OFFSET. */ \ 219290075Sobrien if (GET_MODE_SIZE (MODE) <= 4 \ 219390075Sobrien && GET_CODE (XEXP (X, 0)) == REG \ 219490075Sobrien && GET_CODE (XEXP (X, 1)) == REG \ 219590075Sobrien && XEXP (X, 0) != frame_pointer_rtx \ 219690075Sobrien && XEXP (X, 1) != frame_pointer_rtx \ 219790075Sobrien && XEXP (X, 0) != virtual_stack_vars_rtx \ 219890075Sobrien && XEXP (X, 1) != virtual_stack_vars_rtx \ 219990075Sobrien && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \ 220090075Sobrien && THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 1))) \ 220190075Sobrien goto WIN; \ 220290075Sobrien /* REG+const has 5-7 bit offset for non-SP registers. */ \ 220390075Sobrien else if (GET_CODE (XEXP (X, 0)) == REG \ 220490075Sobrien && (THUMB_REG_OK_FOR_INDEX_P (XEXP (X, 0)) \ 220590075Sobrien || XEXP (X, 0) == arg_pointer_rtx) \ 220690075Sobrien && GET_CODE (XEXP (X, 1)) == CONST_INT \ 220790075Sobrien && THUMB_LEGITIMATE_OFFSET (MODE, INTVAL (XEXP (X, 1)))) \ 220890075Sobrien goto WIN; \ 220990075Sobrien /* REG+const has 10 bit offset for SP, but only SImode and \ 221090075Sobrien larger is supported. */ \ 221190075Sobrien /* ??? Should probably check for DI/DFmode overflow here \ 221290075Sobrien just like GO_IF_LEGITIMATE_OFFSET does. */ \ 221390075Sobrien else if (GET_CODE (XEXP (X, 0)) == REG \ 221490075Sobrien && REGNO (XEXP (X, 0)) == STACK_POINTER_REGNUM \ 221590075Sobrien && GET_MODE_SIZE (MODE) >= 4 \ 221690075Sobrien && GET_CODE (XEXP (X, 1)) == CONST_INT \ 221790075Sobrien && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (X, 1)) \ 221890075Sobrien + GET_MODE_SIZE (MODE)) <= 1024 \ 221990075Sobrien && (INTVAL (XEXP (X, 1)) & 3) == 0) \ 222090075Sobrien goto WIN; \ 222190075Sobrien else if (GET_CODE (XEXP (X, 0)) == REG \ 222290075Sobrien && REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM \ 222390075Sobrien && GET_MODE_SIZE (MODE) >= 4 \ 222490075Sobrien && GET_CODE (XEXP (X, 1)) == CONST_INT \ 222590075Sobrien && (INTVAL (XEXP (X, 1)) & 3) == 0) \ 222690075Sobrien goto WIN; \ 222790075Sobrien } \ 222890075Sobrien else if (GET_MODE_CLASS (MODE) != MODE_FLOAT \ 222990075Sobrien && GET_CODE (X) == SYMBOL_REF \ 223090075Sobrien && CONSTANT_POOL_ADDRESS_P (X) \ 223190075Sobrien && ! (flag_pic \ 223290075Sobrien && symbol_mentioned_p (get_pool_constant (X)))) \ 223390075Sobrien goto WIN; \ 223490075Sobrien} 223590075Sobrien 223690075Sobrien/* ------------------------------------------------------------------- */ 223790075Sobrien#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN) \ 223890075Sobrien if (TARGET_ARM) \ 223990075Sobrien ARM_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN) \ 224090075Sobrien else /* if (TARGET_THUMB) */ \ 224190075Sobrien THUMB_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN) 224290075Sobrien/* ------------------------------------------------------------------- */ 224390075Sobrien 224490075Sobrien/* Try machine-dependent ways of modifying an illegitimate address 224590075Sobrien to be legitimate. If we find one, return the new, valid address. 224690075Sobrien This macro is used in only one place: `memory_address' in explow.c. 224790075Sobrien 224890075Sobrien OLDX is the address as it was before break_out_memory_refs was called. 224990075Sobrien In some cases it is useful to look at this to decide what needs to be done. 225090075Sobrien 225190075Sobrien MODE and WIN are passed so that this macro can use 225290075Sobrien GO_IF_LEGITIMATE_ADDRESS. 225390075Sobrien 225490075Sobrien It is always safe for this macro to do nothing. It exists to recognize 225590075Sobrien opportunities to optimize the output. 225690075Sobrien 225790075Sobrien On the ARM, try to convert [REG, #BIGCONST] 225890075Sobrien into ADD BASE, REG, #UPPERCONST and [BASE, #VALIDCONST], 225990075Sobrien where VALIDCONST == 0 in case of TImode. */ 226090075Sobrien#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ 226190075Sobrien{ \ 226290075Sobrien if (GET_CODE (X) == PLUS) \ 226390075Sobrien { \ 226490075Sobrien rtx xop0 = XEXP (X, 0); \ 226590075Sobrien rtx xop1 = XEXP (X, 1); \ 226690075Sobrien \ 226790075Sobrien if (CONSTANT_P (xop0) && ! symbol_mentioned_p (xop0)) \ 226890075Sobrien xop0 = force_reg (SImode, xop0); \ 226990075Sobrien if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \ 227090075Sobrien xop1 = force_reg (SImode, xop1); \ 227190075Sobrien if (ARM_BASE_REGISTER_RTX_P (xop0) \ 227290075Sobrien && GET_CODE (xop1) == CONST_INT) \ 227390075Sobrien { \ 227490075Sobrien HOST_WIDE_INT n, low_n; \ 227590075Sobrien rtx base_reg, val; \ 227690075Sobrien n = INTVAL (xop1); \ 227790075Sobrien \ 227890075Sobrien if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \ 227990075Sobrien { \ 228090075Sobrien low_n = n & 0x0f; \ 228190075Sobrien n &= ~0x0f; \ 228290075Sobrien if (low_n > 4) \ 228390075Sobrien { \ 228490075Sobrien n += 16; \ 228590075Sobrien low_n -= 16; \ 228690075Sobrien } \ 228790075Sobrien } \ 228890075Sobrien else \ 228990075Sobrien { \ 229090075Sobrien low_n = ((MODE) == TImode ? 0 \ 229190075Sobrien : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff)); \ 229290075Sobrien n -= low_n; \ 229390075Sobrien } \ 229490075Sobrien base_reg = gen_reg_rtx (SImode); \ 229590075Sobrien val = force_operand (gen_rtx_PLUS (SImode, xop0, \ 229690075Sobrien GEN_INT (n)), NULL_RTX); \ 229790075Sobrien emit_move_insn (base_reg, val); \ 229890075Sobrien (X) = (low_n == 0 ? base_reg \ 229990075Sobrien : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n))); \ 230090075Sobrien } \ 230190075Sobrien else if (xop0 != XEXP (X, 0) || xop1 != XEXP (x, 1)) \ 230290075Sobrien (X) = gen_rtx_PLUS (SImode, xop0, xop1); \ 230390075Sobrien } \ 230490075Sobrien else if (GET_CODE (X) == MINUS) \ 230590075Sobrien { \ 230690075Sobrien rtx xop0 = XEXP (X, 0); \ 230790075Sobrien rtx xop1 = XEXP (X, 1); \ 230890075Sobrien \ 230990075Sobrien if (CONSTANT_P (xop0)) \ 231090075Sobrien xop0 = force_reg (SImode, xop0); \ 231190075Sobrien if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \ 231290075Sobrien xop1 = force_reg (SImode, xop1); \ 231390075Sobrien if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1)) \ 231490075Sobrien (X) = gen_rtx_MINUS (SImode, xop0, xop1); \ 231590075Sobrien } \ 231690075Sobrien if (flag_pic) \ 231790075Sobrien (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \ 231890075Sobrien if (memory_address_p (MODE, X)) \ 231990075Sobrien goto WIN; \ 232090075Sobrien} 232190075Sobrien 232290075Sobrien#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ 232390075Sobrien if (flag_pic) \ 232490075Sobrien (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); 232590075Sobrien 232690075Sobrien#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \ 232790075Sobrien if (TARGET_ARM) \ 232890075Sobrien ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN) \ 232990075Sobrien else \ 233090075Sobrien THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN) 233190075Sobrien 233290075Sobrien/* Go to LABEL if ADDR (a legitimate address expression) 233390075Sobrien has an effect that depends on the machine mode it is used for. */ 233490075Sobrien#define ARM_GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ 233590075Sobrien{ \ 233690075Sobrien if ( GET_CODE (ADDR) == PRE_DEC || GET_CODE (ADDR) == POST_DEC \ 233790075Sobrien || GET_CODE (ADDR) == PRE_INC || GET_CODE (ADDR) == POST_INC) \ 233890075Sobrien goto LABEL; \ 233990075Sobrien} 234090075Sobrien 234190075Sobrien/* Nothing helpful to do for the Thumb */ 234290075Sobrien#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \ 234390075Sobrien if (TARGET_ARM) \ 234490075Sobrien ARM_GO_IF_MODE_DEPENDENT_ADDRESS (ADDR, LABEL) 234590075Sobrien 234690075Sobrien 234790075Sobrien/* Specify the machine mode that this machine uses 234890075Sobrien for the index in the tablejump instruction. */ 234990075Sobrien#define CASE_VECTOR_MODE Pmode 235090075Sobrien 235190075Sobrien/* Define as C expression which evaluates to nonzero if the tablejump 235290075Sobrien instruction expects the table to contain offsets from the address of the 235390075Sobrien table. 235490075Sobrien Do not define this if the table should contain absolute addresses. */ 235590075Sobrien/* #define CASE_VECTOR_PC_RELATIVE 1 */ 235690075Sobrien 235790075Sobrien/* signed 'char' is most compatible, but RISC OS wants it unsigned. 235890075Sobrien unsigned is probably best, but may break some code. */ 235990075Sobrien#ifndef DEFAULT_SIGNED_CHAR 236090075Sobrien#define DEFAULT_SIGNED_CHAR 0 236190075Sobrien#endif 236290075Sobrien 236390075Sobrien/* Don't cse the address of the function being compiled. */ 236490075Sobrien#define NO_RECURSIVE_FUNCTION_CSE 1 236590075Sobrien 236690075Sobrien/* Max number of bytes we can move from memory to memory 236790075Sobrien in one reasonably fast instruction. */ 236890075Sobrien#define MOVE_MAX 4 236990075Sobrien 237090075Sobrien#undef MOVE_RATIO 237190075Sobrien#define MOVE_RATIO (arm_is_xscale ? 4 : 2) 237290075Sobrien 237390075Sobrien/* Define if operations between registers always perform the operation 237490075Sobrien on the full register even if a narrower mode is specified. */ 237590075Sobrien#define WORD_REGISTER_OPERATIONS 237690075Sobrien 237790075Sobrien/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD 237890075Sobrien will either zero-extend or sign-extend. The value of this macro should 237990075Sobrien be the code that says which one of the two operations is implicitly 238090075Sobrien done, NIL if none. */ 238190075Sobrien#define LOAD_EXTEND_OP(MODE) \ 238290075Sobrien (TARGET_THUMB ? ZERO_EXTEND : \ 238390075Sobrien ((arm_arch4 || (MODE) == QImode) ? ZERO_EXTEND \ 238490075Sobrien : ((BYTES_BIG_ENDIAN && (MODE) == HImode) ? SIGN_EXTEND : NIL))) 238590075Sobrien 238690075Sobrien/* Nonzero if access to memory by bytes is slow and undesirable. */ 238790075Sobrien#define SLOW_BYTE_ACCESS 0 238890075Sobrien 238990075Sobrien#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 1 239090075Sobrien 239190075Sobrien/* Immediate shift counts are truncated by the output routines (or was it 239290075Sobrien the assembler?). Shift counts in a register are truncated by ARM. Note 239390075Sobrien that the native compiler puts too large (> 32) immediate shift counts 239490075Sobrien into a register and shifts by the register, letting the ARM decide what 239590075Sobrien to do instead of doing that itself. */ 239690075Sobrien/* This is all wrong. Defining SHIFT_COUNT_TRUNCATED tells combine that 239790075Sobrien code like (X << (Y % 32)) for register X, Y is equivalent to (X << Y). 239890075Sobrien On the arm, Y in a register is used modulo 256 for the shift. Only for 239990075Sobrien rotates is modulo 32 used. */ 240090075Sobrien/* #define SHIFT_COUNT_TRUNCATED 1 */ 240190075Sobrien 240290075Sobrien/* All integers have the same format so truncation is easy. */ 240390075Sobrien#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 240490075Sobrien 240590075Sobrien/* Calling from registers is a massive pain. */ 240690075Sobrien#define NO_FUNCTION_CSE 1 240790075Sobrien 240890075Sobrien/* Chars and shorts should be passed as ints. */ 240990075Sobrien#define PROMOTE_PROTOTYPES 1 241090075Sobrien 241190075Sobrien/* The machine modes of pointers and functions */ 241290075Sobrien#define Pmode SImode 241390075Sobrien#define FUNCTION_MODE Pmode 241490075Sobrien 241590075Sobrien#define ARM_FRAME_RTX(X) \ 241690075Sobrien ( (X) == frame_pointer_rtx || (X) == stack_pointer_rtx \ 241790075Sobrien || (X) == arg_pointer_rtx) 241890075Sobrien 241990075Sobrien#define DEFAULT_RTX_COSTS(X, CODE, OUTER_CODE) \ 242090075Sobrien return arm_rtx_costs (X, CODE, OUTER_CODE); 242190075Sobrien 242290075Sobrien/* Moves to and from memory are quite expensive */ 242390075Sobrien#define MEMORY_MOVE_COST(M, CLASS, IN) \ 242490075Sobrien (TARGET_ARM ? 10 : \ 242590075Sobrien ((GET_MODE_SIZE (M) < 4 ? 8 : 2 * GET_MODE_SIZE (M)) \ 242690075Sobrien * (CLASS == LO_REGS ? 1 : 2))) 242790075Sobrien 242890075Sobrien/* All address computations that can be done are free, but rtx cost returns 242990075Sobrien the same for practically all of them. So we weight the different types 243090075Sobrien of address here in the order (most pref first): 243190075Sobrien PRE/POST_INC/DEC, SHIFT or NON-INT sum, INT sum, REG, MEM or LABEL. */ 243290075Sobrien#define ARM_ADDRESS_COST(X) \ 243390075Sobrien (10 - ((GET_CODE (X) == MEM || GET_CODE (X) == LABEL_REF \ 243490075Sobrien || GET_CODE (X) == SYMBOL_REF) \ 243590075Sobrien ? 0 \ 243690075Sobrien : ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC \ 243790075Sobrien || GET_CODE (X) == POST_INC || GET_CODE (X) == POST_DEC) \ 243890075Sobrien ? 10 \ 243990075Sobrien : (((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS) \ 244090075Sobrien ? 6 + (GET_CODE (XEXP (X, 1)) == CONST_INT ? 2 \ 244190075Sobrien : ((GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == '2' \ 244290075Sobrien || GET_RTX_CLASS (GET_CODE (XEXP (X, 0))) == 'c' \ 244390075Sobrien || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == '2' \ 244490075Sobrien || GET_RTX_CLASS (GET_CODE (XEXP (X, 1))) == 'c') \ 244590075Sobrien ? 1 : 0)) \ 244690075Sobrien : 4))))) 244790075Sobrien 244890075Sobrien#define THUMB_ADDRESS_COST(X) \ 244990075Sobrien ((GET_CODE (X) == REG \ 245090075Sobrien || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG \ 245190075Sobrien && GET_CODE (XEXP (X, 1)) == CONST_INT)) \ 245290075Sobrien ? 1 : 2) 245390075Sobrien 245490075Sobrien#define ADDRESS_COST(X) \ 245590075Sobrien (TARGET_ARM ? ARM_ADDRESS_COST (X) : THUMB_ADDRESS_COST (X)) 245690075Sobrien 245790075Sobrien/* Try to generate sequences that don't involve branches, we can then use 245890075Sobrien conditional instructions */ 245990075Sobrien#define BRANCH_COST \ 246090075Sobrien (TARGET_ARM ? 4 : (optimize > 1 ? 1 : 0)) 246190075Sobrien 246290075Sobrien/* Position Independent Code. */ 246390075Sobrien/* We decide which register to use based on the compilation options and 246490075Sobrien the assembler in use; this is more general than the APCS restriction of 246590075Sobrien using sb (r9) all the time. */ 246690075Sobrienextern int arm_pic_register; 246790075Sobrien 246890075Sobrien/* Used when parsing command line option -mpic-register=. */ 246990075Sobrienextern const char * arm_pic_register_string; 247090075Sobrien 247190075Sobrien/* The register number of the register used to address a table of static 247290075Sobrien data addresses in memory. */ 247390075Sobrien#define PIC_OFFSET_TABLE_REGNUM arm_pic_register 247490075Sobrien 247590075Sobrien#define FINALIZE_PIC arm_finalize_pic (1) 247690075Sobrien 247790075Sobrien/* We can't directly access anything that contains a symbol, 247890075Sobrien nor can we indirect via the constant pool. */ 247990075Sobrien#define LEGITIMATE_PIC_OPERAND_P(X) \ 248090075Sobrien ( ! symbol_mentioned_p (X) \ 248190075Sobrien && ! label_mentioned_p (X) \ 248290075Sobrien && (! CONSTANT_POOL_ADDRESS_P (X) \ 248390075Sobrien || ( ! symbol_mentioned_p (get_pool_constant (X)) \ 248490075Sobrien && ! label_mentioned_p (get_pool_constant (X))))) 248590075Sobrien 248690075Sobrien/* We need to know when we are making a constant pool; this determines 248790075Sobrien whether data needs to be in the GOT or can be referenced via a GOT 248890075Sobrien offset. */ 248990075Sobrienextern int making_const_table; 249090075Sobrien 249190075Sobrien/* Handle pragmas for compatibility with Intel's compilers. */ 249290075Sobrien#define REGISTER_TARGET_PRAGMAS(PFILE) do { \ 249390075Sobrien cpp_register_pragma (PFILE, 0, "long_calls", arm_pr_long_calls); \ 249490075Sobrien cpp_register_pragma (PFILE, 0, "no_long_calls", arm_pr_no_long_calls); \ 249590075Sobrien cpp_register_pragma (PFILE, 0, "long_calls_off", arm_pr_long_calls_off); \ 249690075Sobrien} while (0) 249790075Sobrien 249890075Sobrien/* Condition code information. */ 249990075Sobrien/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, 250090075Sobrien return the mode to be used for the comparison. 250190075Sobrien CCFPEmode should be used with floating inequalities, 250290075Sobrien CCFPmode should be used with floating equalities. 250390075Sobrien CC_NOOVmode should be used with SImode integer equalities. 250490075Sobrien CC_Zmode should be used if only the Z flag is set correctly 250590075Sobrien CCmode should be used otherwise. */ 250690075Sobrien 250790075Sobrien#define EXTRA_CC_MODES \ 250890075Sobrien CC(CC_NOOVmode, "CC_NOOV") \ 250990075Sobrien CC(CC_Zmode, "CC_Z") \ 251090075Sobrien CC(CC_SWPmode, "CC_SWP") \ 251190075Sobrien CC(CCFPmode, "CCFP") \ 251290075Sobrien CC(CCFPEmode, "CCFPE") \ 251390075Sobrien CC(CC_DNEmode, "CC_DNE") \ 251490075Sobrien CC(CC_DEQmode, "CC_DEQ") \ 251590075Sobrien CC(CC_DLEmode, "CC_DLE") \ 251690075Sobrien CC(CC_DLTmode, "CC_DLT") \ 251790075Sobrien CC(CC_DGEmode, "CC_DGE") \ 251890075Sobrien CC(CC_DGTmode, "CC_DGT") \ 251990075Sobrien CC(CC_DLEUmode, "CC_DLEU") \ 252090075Sobrien CC(CC_DLTUmode, "CC_DLTU") \ 252190075Sobrien CC(CC_DGEUmode, "CC_DGEU") \ 252290075Sobrien CC(CC_DGTUmode, "CC_DGTU") \ 252390075Sobrien CC(CC_Cmode, "CC_C") 252490075Sobrien 252590075Sobrien#define SELECT_CC_MODE(OP, X, Y) arm_select_cc_mode (OP, X, Y) 252690075Sobrien 252790075Sobrien#define REVERSIBLE_CC_MODE(MODE) ((MODE) != CCFPEmode) 252890075Sobrien 252990075Sobrien#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \ 253090075Sobrien do \ 253190075Sobrien { \ 253290075Sobrien if (GET_CODE (OP1) == CONST_INT \ 253390075Sobrien && ! (const_ok_for_arm (INTVAL (OP1)) \ 253490075Sobrien || (const_ok_for_arm (- INTVAL (OP1))))) \ 253590075Sobrien { \ 253690075Sobrien rtx const_op = OP1; \ 253790075Sobrien CODE = arm_canonicalize_comparison ((CODE), &const_op); \ 253890075Sobrien OP1 = const_op; \ 253990075Sobrien } \ 254090075Sobrien } \ 254190075Sobrien while (0) 254290075Sobrien 254390075Sobrien#define STORE_FLAG_VALUE 1 254490075Sobrien 254590075Sobrien 254690075Sobrien 254790075Sobrien/* Gcc puts the pool in the wrong place for ARM, since we can only 254890075Sobrien load addresses a limited distance around the pc. We do some 254990075Sobrien special munging to move the constant pool values to the correct 255090075Sobrien point in the code. */ 255190075Sobrien#define MACHINE_DEPENDENT_REORG(INSN) \ 255290075Sobrien arm_reorg (INSN); \ 255390075Sobrien 255490075Sobrien#undef ASM_APP_OFF 255590075Sobrien#define ASM_APP_OFF (TARGET_THUMB ? "\t.code\t16\n" : "") 255690075Sobrien 255790075Sobrien/* Output an internal label definition. */ 255890075Sobrien#ifndef ASM_OUTPUT_INTERNAL_LABEL 255990075Sobrien#define ASM_OUTPUT_INTERNAL_LABEL(STREAM, PREFIX, NUM) \ 256090075Sobrien do \ 256190075Sobrien { \ 256290075Sobrien char * s = (char *) alloca (40 + strlen (PREFIX)); \ 256390075Sobrien \ 256490075Sobrien if (arm_ccfsm_state == 3 && arm_target_label == (NUM) \ 256590075Sobrien && !strcmp (PREFIX, "L")) \ 256690075Sobrien { \ 256790075Sobrien arm_ccfsm_state = 0; \ 256890075Sobrien arm_target_insn = NULL; \ 256990075Sobrien } \ 257090075Sobrien ASM_GENERATE_INTERNAL_LABEL (s, (PREFIX), (NUM)); \ 257190075Sobrien ASM_OUTPUT_LABEL (STREAM, s); \ 257290075Sobrien } \ 257390075Sobrien while (0) 257490075Sobrien#endif 257590075Sobrien 257690075Sobrien/* Output a push or a pop instruction (only used when profiling). */ 257790075Sobrien#define ASM_OUTPUT_REG_PUSH(STREAM, REGNO) \ 257890075Sobrien if (TARGET_ARM) \ 257990075Sobrien asm_fprintf (STREAM,"\tstmfd\t%r!,{%r}\n", \ 258090075Sobrien STACK_POINTER_REGNUM, REGNO); \ 258190075Sobrien else \ 258290075Sobrien asm_fprintf (STREAM, "\tpush {%r}\n", REGNO) 258390075Sobrien 258490075Sobrien 258590075Sobrien#define ASM_OUTPUT_REG_POP(STREAM, REGNO) \ 258690075Sobrien if (TARGET_ARM) \ 258790075Sobrien asm_fprintf (STREAM, "\tldmfd\t%r!,{%r}\n", \ 258890075Sobrien STACK_POINTER_REGNUM, REGNO); \ 258990075Sobrien else \ 259090075Sobrien asm_fprintf (STREAM, "\tpop {%r}\n", REGNO) 259190075Sobrien 259290075Sobrien/* This is how to output a label which precedes a jumptable. Since 259390075Sobrien Thumb instructions are 2 bytes, we may need explicit alignment here. */ 259490075Sobrien#undef ASM_OUTPUT_CASE_LABEL 259590075Sobrien#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \ 259690075Sobrien do \ 259790075Sobrien { \ 259890075Sobrien if (TARGET_THUMB) \ 259990075Sobrien ASM_OUTPUT_ALIGN (FILE, 2); \ 260090075Sobrien ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \ 260190075Sobrien } \ 260290075Sobrien while (0) 260390075Sobrien 260490075Sobrien#define ARM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \ 260590075Sobrien do \ 260690075Sobrien { \ 260790075Sobrien if (TARGET_THUMB) \ 260890075Sobrien { \ 260990075Sobrien if (is_called_in_ARM_mode (DECL)) \ 261090075Sobrien fprintf (STREAM, "\t.code 32\n") ; \ 261190075Sobrien else \ 261290075Sobrien fprintf (STREAM, "\t.thumb_func\n") ; \ 261390075Sobrien } \ 261490075Sobrien if (TARGET_POKE_FUNCTION_NAME) \ 261590075Sobrien arm_poke_function_name (STREAM, (char *) NAME); \ 261690075Sobrien } \ 261790075Sobrien while (0) 261890075Sobrien 261990075Sobrien/* For aliases of functions we use .thumb_set instead. */ 262090075Sobrien#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL1, DECL2) \ 262190075Sobrien do \ 262290075Sobrien { \ 262390075Sobrien const char *const LABEL1 = XSTR (XEXP (DECL_RTL (decl), 0), 0); \ 262490075Sobrien const char *const LABEL2 = IDENTIFIER_POINTER (DECL2); \ 262590075Sobrien \ 262690075Sobrien if (TARGET_THUMB && TREE_CODE (DECL1) == FUNCTION_DECL) \ 262790075Sobrien { \ 262890075Sobrien fprintf (FILE, "\t.thumb_set "); \ 262990075Sobrien assemble_name (FILE, LABEL1); \ 263090075Sobrien fprintf (FILE, ","); \ 263190075Sobrien assemble_name (FILE, LABEL2); \ 263290075Sobrien fprintf (FILE, "\n"); \ 263390075Sobrien } \ 263490075Sobrien else \ 263590075Sobrien ASM_OUTPUT_DEF (FILE, LABEL1, LABEL2); \ 263690075Sobrien } \ 263790075Sobrien while (0) 263890075Sobrien 263990075Sobrien#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN 264090075Sobrien/* To support -falign-* switches we need to use .p2align so 264190075Sobrien that alignment directives in code sections will be padded 264290075Sobrien with no-op instructions, rather than zeroes. */ 264390075Sobrien#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \ 264490075Sobrien if ((LOG) != 0) \ 264590075Sobrien { \ 264690075Sobrien if ((MAX_SKIP) == 0) \ 264790075Sobrien fprintf ((FILE), "\t.p2align %d\n", (LOG)); \ 264890075Sobrien else \ 264990075Sobrien fprintf ((FILE), "\t.p2align %d,,%d\n", \ 265090075Sobrien (LOG), (MAX_SKIP)); \ 265190075Sobrien } 265290075Sobrien#endif 265390075Sobrien 265490075Sobrien/* Only perform branch elimination (by making instructions conditional) if 265590075Sobrien we're optimising. Otherwise it's of no use anyway. */ 265690075Sobrien#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ 265790075Sobrien if (TARGET_ARM && optimize) \ 265890075Sobrien arm_final_prescan_insn (INSN); \ 265990075Sobrien else if (TARGET_THUMB) \ 266090075Sobrien thumb_final_prescan_insn (INSN) 266190075Sobrien 266290075Sobrien#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ 266390075Sobrien (CODE == '@' || CODE == '|' \ 266490075Sobrien || (TARGET_ARM && (CODE == '?')) \ 266590075Sobrien || (TARGET_THUMB && (CODE == '_'))) 266690075Sobrien 266790075Sobrien/* Output an operand of an instruction. */ 266890075Sobrien#define PRINT_OPERAND(STREAM, X, CODE) \ 266990075Sobrien arm_print_operand (STREAM, X, CODE) 267090075Sobrien 267190075Sobrien#define ARM_SIGN_EXTEND(x) ((HOST_WIDE_INT) \ 267290075Sobrien (HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x) \ 267390075Sobrien : ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0xffffffff) |\ 267490075Sobrien ((((unsigned HOST_WIDE_INT)(x)) & (unsigned HOST_WIDE_INT) 0x80000000) \ 267590075Sobrien ? ((~ (unsigned HOST_WIDE_INT) 0) \ 267690075Sobrien & ~ (unsigned HOST_WIDE_INT) 0xffffffff) \ 267790075Sobrien : 0)))) 267890075Sobrien 267990075Sobrien/* Output the address of an operand. */ 268090075Sobrien#define ARM_PRINT_OPERAND_ADDRESS(STREAM, X) \ 268190075Sobrien{ \ 268290075Sobrien int is_minus = GET_CODE (X) == MINUS; \ 268390075Sobrien \ 268490075Sobrien if (GET_CODE (X) == REG) \ 268590075Sobrien asm_fprintf (STREAM, "[%r, #0]", REGNO (X)); \ 268690075Sobrien else if (GET_CODE (X) == PLUS || is_minus) \ 268790075Sobrien { \ 268890075Sobrien rtx base = XEXP (X, 0); \ 268990075Sobrien rtx index = XEXP (X, 1); \ 269090075Sobrien HOST_WIDE_INT offset = 0; \ 269190075Sobrien if (GET_CODE (base) != REG) \ 269290075Sobrien { \ 269390075Sobrien /* Ensure that BASE is a register */ \ 269490075Sobrien /* (one of them must be). */ \ 269590075Sobrien rtx temp = base; \ 269690075Sobrien base = index; \ 269790075Sobrien index = temp; \ 269890075Sobrien } \ 269990075Sobrien switch (GET_CODE (index)) \ 270090075Sobrien { \ 270190075Sobrien case CONST_INT: \ 270290075Sobrien offset = INTVAL (index); \ 270390075Sobrien if (is_minus) \ 270490075Sobrien offset = -offset; \ 270590075Sobrien asm_fprintf (STREAM, "[%r, #%d]", \ 270690075Sobrien REGNO (base), offset); \ 270790075Sobrien break; \ 270890075Sobrien \ 270990075Sobrien case REG: \ 271090075Sobrien asm_fprintf (STREAM, "[%r, %s%r]", \ 271190075Sobrien REGNO (base), is_minus ? "-" : "", \ 271290075Sobrien REGNO (index)); \ 271390075Sobrien break; \ 271490075Sobrien \ 271590075Sobrien case MULT: \ 271690075Sobrien case ASHIFTRT: \ 271790075Sobrien case LSHIFTRT: \ 271890075Sobrien case ASHIFT: \ 271990075Sobrien case ROTATERT: \ 272090075Sobrien { \ 272190075Sobrien asm_fprintf (STREAM, "[%r, %s%r", \ 272290075Sobrien REGNO (base), is_minus ? "-" : "", \ 272390075Sobrien REGNO (XEXP (index, 0))); \ 272490075Sobrien arm_print_operand (STREAM, index, 'S'); \ 272590075Sobrien fputs ("]", STREAM); \ 272690075Sobrien break; \ 272790075Sobrien } \ 272890075Sobrien \ 272990075Sobrien default: \ 273090075Sobrien abort(); \ 273190075Sobrien } \ 273290075Sobrien } \ 273390075Sobrien else if ( GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC\ 273490075Sobrien || GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC)\ 273590075Sobrien { \ 273690075Sobrien extern int output_memory_reference_mode; \ 273790075Sobrien \ 273890075Sobrien if (GET_CODE (XEXP (X, 0)) != REG) \ 273990075Sobrien abort (); \ 274090075Sobrien \ 274190075Sobrien if (GET_CODE (X) == PRE_DEC || GET_CODE (X) == PRE_INC) \ 274290075Sobrien asm_fprintf (STREAM, "[%r, #%s%d]!", \ 274390075Sobrien REGNO (XEXP (X, 0)), \ 274490075Sobrien GET_CODE (X) == PRE_DEC ? "-" : "", \ 274590075Sobrien GET_MODE_SIZE (output_memory_reference_mode));\ 274690075Sobrien else \ 274790075Sobrien asm_fprintf (STREAM, "[%r], #%s%d", \ 274890075Sobrien REGNO (XEXP (X, 0)), \ 274990075Sobrien GET_CODE (X) == POST_DEC ? "-" : "", \ 275090075Sobrien GET_MODE_SIZE (output_memory_reference_mode));\ 275190075Sobrien } \ 275290075Sobrien else output_addr_const (STREAM, X); \ 275390075Sobrien} 275490075Sobrien 275590075Sobrien#define THUMB_PRINT_OPERAND_ADDRESS(STREAM, X) \ 275690075Sobrien{ \ 275790075Sobrien if (GET_CODE (X) == REG) \ 275890075Sobrien asm_fprintf (STREAM, "[%r]", REGNO (X)); \ 275990075Sobrien else if (GET_CODE (X) == POST_INC) \ 276090075Sobrien asm_fprintf (STREAM, "%r!", REGNO (XEXP (X, 0))); \ 276190075Sobrien else if (GET_CODE (X) == PLUS) \ 276290075Sobrien { \ 276390075Sobrien if (GET_CODE (XEXP (X, 1)) == CONST_INT) \ 276490075Sobrien asm_fprintf (STREAM, "[%r, #%d]", \ 276590075Sobrien REGNO (XEXP (X, 0)), \ 276690075Sobrien (int) INTVAL (XEXP (X, 1))); \ 276790075Sobrien else \ 276890075Sobrien asm_fprintf (STREAM, "[%r, %r]", \ 276990075Sobrien REGNO (XEXP (X, 0)), \ 277090075Sobrien REGNO (XEXP (X, 1))); \ 277190075Sobrien } \ 277290075Sobrien else \ 277390075Sobrien output_addr_const (STREAM, X); \ 277490075Sobrien} 277590075Sobrien 277690075Sobrien#define PRINT_OPERAND_ADDRESS(STREAM, X) \ 277790075Sobrien if (TARGET_ARM) \ 277890075Sobrien ARM_PRINT_OPERAND_ADDRESS (STREAM, X) \ 277990075Sobrien else \ 278090075Sobrien THUMB_PRINT_OPERAND_ADDRESS (STREAM, X) 278190075Sobrien 278290075Sobrien/* Output code to add DELTA to the first argument, and then jump to FUNCTION. 278390075Sobrien Used for C++ multiple inheritance. */ 278490075Sobrien#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \ 278590075Sobrien do \ 278690075Sobrien { \ 278790075Sobrien int mi_delta = (DELTA); \ 278890075Sobrien const char *const mi_op = mi_delta < 0 ? "sub" : "add"; \ 278990075Sobrien int shift = 0; \ 279090075Sobrien int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) \ 279190075Sobrien ? 1 : 0); \ 279290075Sobrien if (mi_delta < 0) \ 279390075Sobrien mi_delta = - mi_delta; \ 279490075Sobrien while (mi_delta != 0) \ 279590075Sobrien { \ 279690075Sobrien if ((mi_delta & (3 << shift)) == 0) \ 279790075Sobrien shift += 2; \ 279890075Sobrien else \ 279990075Sobrien { \ 280090075Sobrien asm_fprintf (FILE, "\t%s\t%r, %r, #%d\n", \ 280190075Sobrien mi_op, this_regno, this_regno, \ 280290075Sobrien mi_delta & (0xff << shift)); \ 280390075Sobrien mi_delta &= ~(0xff << shift); \ 280490075Sobrien shift += 8; \ 280590075Sobrien } \ 280690075Sobrien } \ 280790075Sobrien fputs ("\tb\t", FILE); \ 280890075Sobrien assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ 280990075Sobrien if (NEED_PLT_RELOC) \ 281090075Sobrien fputs ("(PLT)", FILE); \ 281190075Sobrien fputc ('\n', FILE); \ 281290075Sobrien } \ 281390075Sobrien while (0) 281490075Sobrien 281590075Sobrien/* A C expression whose value is RTL representing the value of the return 281690075Sobrien address for the frame COUNT steps up from the current frame. */ 281790075Sobrien 281890075Sobrien#define RETURN_ADDR_RTX(COUNT, FRAME) \ 281990075Sobrien arm_return_addr (COUNT, FRAME) 282090075Sobrien 282190075Sobrien/* Mask of the bits in the PC that contain the real return address 282290075Sobrien when running in 26-bit mode. */ 282390075Sobrien#define RETURN_ADDR_MASK26 (0x03fffffc) 282490075Sobrien 282590075Sobrien/* Pick up the return address upon entry to a procedure. Used for 282690075Sobrien dwarf2 unwind information. This also enables the table driven 282790075Sobrien mechanism. */ 282890075Sobrien#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM) 282990075Sobrien#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LR_REGNUM) 283090075Sobrien 283190075Sobrien/* Used to mask out junk bits from the return address, such as 283290075Sobrien processor state, interrupt status, condition codes and the like. */ 283390075Sobrien#define MASK_RETURN_ADDR \ 283490075Sobrien /* If we are generating code for an ARM2/ARM3 machine or for an ARM6 \ 283590075Sobrien in 26 bit mode, the condition codes must be masked out of the \ 283690075Sobrien return address. This does not apply to ARM6 and later processors \ 283790075Sobrien when running in 32 bit mode. */ \ 283890075Sobrien ((!TARGET_APCS_32) ? (GEN_INT (RETURN_ADDR_MASK26)) \ 283990075Sobrien : (GEN_INT ((unsigned long)0xffffffff))) 284090075Sobrien 284190075Sobrien 284290075Sobrien/* Define the codes that are matched by predicates in arm.c */ 284390075Sobrien#define PREDICATE_CODES \ 284490075Sobrien {"s_register_operand", {SUBREG, REG}}, \ 284590075Sobrien {"arm_hard_register_operand", {REG}}, \ 284690075Sobrien {"f_register_operand", {SUBREG, REG}}, \ 284790075Sobrien {"arm_add_operand", {SUBREG, REG, CONST_INT}}, \ 284890075Sobrien {"fpu_add_operand", {SUBREG, REG, CONST_DOUBLE}}, \ 284990075Sobrien {"fpu_rhs_operand", {SUBREG, REG, CONST_DOUBLE}}, \ 285090075Sobrien {"arm_rhs_operand", {SUBREG, REG, CONST_INT}}, \ 285190075Sobrien {"arm_not_operand", {SUBREG, REG, CONST_INT}}, \ 285290075Sobrien {"reg_or_int_operand", {SUBREG, REG, CONST_INT}}, \ 285390075Sobrien {"index_operand", {SUBREG, REG, CONST_INT}}, \ 285490075Sobrien {"thumb_cmp_operand", {SUBREG, REG, CONST_INT}}, \ 285590075Sobrien {"offsettable_memory_operand", {MEM}}, \ 285690075Sobrien {"bad_signed_byte_operand", {MEM}}, \ 285790075Sobrien {"alignable_memory_operand", {MEM}}, \ 285890075Sobrien {"shiftable_operator", {PLUS, MINUS, AND, IOR, XOR}}, \ 285990075Sobrien {"minmax_operator", {SMIN, SMAX, UMIN, UMAX}}, \ 286090075Sobrien {"shift_operator", {ASHIFT, ASHIFTRT, LSHIFTRT, ROTATERT, MULT}}, \ 286190075Sobrien {"di_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM}}, \ 286290075Sobrien {"nonimmediate_di_operand", {SUBREG, REG, MEM}}, \ 286390075Sobrien {"soft_df_operand", {SUBREG, REG, CONST_DOUBLE, MEM}}, \ 286490075Sobrien {"nonimmediate_soft_df_operand", {SUBREG, REG, MEM}}, \ 286590075Sobrien {"load_multiple_operation", {PARALLEL}}, \ 286690075Sobrien {"store_multiple_operation", {PARALLEL}}, \ 286790075Sobrien {"equality_operator", {EQ, NE}}, \ 286890075Sobrien {"arm_comparison_operator", {EQ, NE, LE, LT, GE, GT, GEU, GTU, LEU, \ 286990075Sobrien LTU, UNORDERED, ORDERED, UNLT, UNLE, \ 287090075Sobrien UNGE, UNGT}}, \ 287190075Sobrien {"arm_rhsm_operand", {SUBREG, REG, CONST_INT, MEM}}, \ 287290075Sobrien {"const_shift_operand", {CONST_INT}}, \ 287390075Sobrien {"multi_register_push", {PARALLEL}}, \ 287490075Sobrien {"cc_register", {REG}}, \ 287590075Sobrien {"logical_binary_operator", {AND, IOR, XOR}}, \ 287690075Sobrien {"dominant_cc_register", {REG}}, 287790075Sobrien 287890075Sobrien/* Define this if you have special predicates that know special things 287990075Sobrien about modes. Genrecog will warn about certain forms of 288090075Sobrien match_operand without a mode; if the operand predicate is listed in 288190075Sobrien SPECIAL_MODE_PREDICATES, the warning will be suppressed. */ 288290075Sobrien#define SPECIAL_MODE_PREDICATES \ 288390075Sobrien "cc_register", "dominant_cc_register", 288490075Sobrien 288590075Sobrienenum arm_builtins 288690075Sobrien{ 288790075Sobrien ARM_BUILTIN_CLZ, 288890075Sobrien ARM_BUILTIN_MAX 288990075Sobrien}; 289090075Sobrien#endif /* ! GCC_ARM_H */ 2891