(TARGET_CPU_arm*, TARGET_CPU_strongarm*, TARGET_CPU_generic):
authorRichard Earnshaw <erich@gnu.org>
Thu, 8 May 1997 22:17:34 +0000 (22:17 +0000)
committerRichard Earnshaw <erich@gnu.org>
Thu, 8 May 1997 22:17:34 +0000 (22:17 +0000)
define.
(CPP_ARCH_DEFAULT_SPEC): Set up based on setting of TARGET_CPU_DEFAULT.
(CPP_SPEC): Split up into sub-rule calls.
(CPP_CPU_SPEC): Add default definition.
(CPP_APCS_PC_SPEC, CPP_APCS_PC_DEFAULT_SPEC): Add definitions.
(CPP_FLOAT_SPEC, CPP_FLOAT_DEFAULT_SPEC): Add definitions.
(CPP_ENDIAN_SPEC, CPP_ENDIAN_DEFAULT_SPEC): Add definitions.
(CC1_SPEC): Map legacy -m[236] onto -mcpu=.. and -mapcs-{26,32} as
appropriate. Similarly for -mbe and -mle to -m{big,little}-endian.
(EXTRA_SPECS): Define.
(enum processor_type): New types for arm8 and strongarm.
(CONDITIONAL_REGISTER_USAGE): Handle flag_pic.
(LEGITIMIZE_ADDRESS): Likewise.
(ADJUST_COST): Define.
(PIC_OFFSET_TABLE_REGNUM): Define.
(FINALIZE_PIC): Define.
(LEGITIMATE_PIC_OPERAND_P): Define.
(OUTPUT_INT_ADDR_CONST): Define.
(ASM_OUTPUT_MI_THUNK): Delete calls to arm_increase_location.
(MASK_RETURN_ADDR): Use TARGET_APCS_32 not TARGET_6.

From-SVN: r14051

gcc/config/arm/arm.h

index 520e61bdd77520ca5364d560bd439433d9a551d6..4a566d319fbbd57e9bbed38a171ff305b34b5b32 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for Acorn RISC Machine.
-   Copyright (C) 1991, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1991, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
    More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
@@ -29,7 +29,7 @@ Boston, MA 02111-1307, USA.  */
    should default to that used by the OS.
 */
 
-extern void output_func_prologue ();
+
 extern void output_func_epilogue ();
 extern char *output_add_immediate ();
 extern char *output_call ();
@@ -51,6 +51,33 @@ extern struct rtx_def *gen_compare_reg ();
 extern struct rtx_def *arm_gen_store_multiple ();
 extern struct rtx_def *arm_gen_load_multiple ();
 extern struct rtx_def *gen_rotated_half_load ();
+extern int is_pic ();
+#ifdef AOF_ASSEMBLER
+extern struct rtx_def *aof_pic_entry ();
+#endif
+
+#define TARGET_CPU_arm2                0x0000
+#define TARGET_CPU_arm250      0x0000
+#define TARGET_CPU_arm3                0x0000
+#define TARGET_CPU_arm6                0x0001
+#define TARGET_CPU_arm600      0x0001
+#define TARGET_CPU_arm610      0x0002
+#define TARGET_CPU_arm7                0x0001
+#define TARGET_CPU_arm7m       0x0004
+#define TARGET_CPU_arm7dm      0x0004
+#define TARGET_CPU_arm7dmi     0x0004
+#define TARGET_CPU_arm700      0x0001
+#define TARGET_CPU_arm710      0x0002
+#define TARGET_CPU_arm7100     0x0002
+#define TARGET_CPU_arm7500     0x0002
+#define TARGET_CPU_arm7500fe   0x1001
+#define TARGET_CPU_arm7tdmi    0x0008
+#define TARGET_CPU_arm8                0x0010
+#define TARGET_CPU_arm810      0x0020
+#define TARGET_CPU_strongarm   0x0040
+#define TARGET_CPU_strongarm110 0x0040
+/* Configure didn't specify */
+#define TARGET_CPU_generic     0x8000
 
 enum arm_cond_code
 {
@@ -66,25 +93,156 @@ extern char *arm_condition_codes[];
 extern int frame_pointer_needed;
 
 \f
+/* Just in case configure has failed to define anything. */
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT TARGET_CPU_generic
+#endif
+
+/* If the configuration file doesn't specify the cpu, the subtarget may
+   override it.  If it doesn't, then default to an ARM6. */
+#if TARGET_CPU_DEFAULT == TARGET_CPU_generic
+#undef TARGET_CPU_DEFAULT
+#ifdef SUBTARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT SUBTARGET_CPU_DEFAULT
+#else
+#define TARGET_CPU_DEFAULT TARGET_CPU_arm6
+#endif
+#endif
+
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm2
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_2__"
+#else
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm6 || TARGET_CPU_DEFUALT == TARGET_CPU_arm610 || TARGET_CPU_DEFAULT == TARGET_CPU_arm7500fe
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3__"
+#else
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7m
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_3M__"
+#else
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm7tdmi
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4T__"
+#else
+#if TARGET_CPU_DEFAULT == TARGET_CPU_arm8 || TARGET_CPU_DEFAULT == TARGET_CPU_arm810 || TARGET_CPU_DEFAULT == TARGET_CPU_strongarm
+#define CPP_ARCH_DEFAULT_SPEC "-D__ARM_ARCH_4__"
+#else
+Unrecognized value in TARGET_CPU_DEFAULT.
+#endif
+#endif
+#endif
+#endif
+#endif
+
 #ifndef CPP_PREDEFINES
 #define CPP_PREDEFINES  "-Darm -Acpu(arm) -Amachine(arm)"
 #endif
 
-#ifndef CPP_SPEC
-#define CPP_SPEC "%{m6:-D__arm6__} \
-%{mcpu-*:-D__%*} \
-%{mcpu=*:-D__%*} \
-%{mapcs-32:-D__APCS_32__ -U__APCS_26__} \
-%{mapcs-26:-D__APCS_26__ -U__APCS_32__} \
-%{!mapcs-32: %{!mapcs-26:-D__APCS_26__}} \
-%{msoft-float:-D__SOFTFP__} \
-%{mhard-float:-U__SOFTFP__} \
-%{!mhard-float: %{!msoft-float:-U__SOFTFP__}} \
-%{mbig-endian:-D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__}} \
-%{mbe:-D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__}} \
-%{!mbe: %{!mbig-endian:-D__ARMEL__}} \
+#define CPP_SPEC "%(cpp_cpu_arch) %(cpp_apcs_pc) %(cpp_float) %(cpp_enidan)"
+
+#define CPP_CPU_ARCH_SPEC "\
+%{m2:-D__arm2__ -D__ARM_ARCH_2__} \
+%{m3:-D__arm2__ -D__ARM_ARCH_2__} \
+%{m6:-D__arm6__ -D__ARM_ARCH_3__} \
+%{mcpu=arm2:-D__ARM_ARCH_2__} \
+%{mcpu=arm250:-D__ARM_ARCH_2__} \
+%{mcpu=arm3:-D__ARM_ARCH_2__} \
+%{mcpu=arm6:-D__ARM_ARCH_3__} \
+%{mcpu=arm600:-D__ARM_ARCH_3__} \
+%{mcpu=arm610:-D__ARM_ARCH_3__} \
+%{mcpu=arm7:-D__ARM_ARCH_3__} \
+%{mcpu=arm700:-D__ARM_ARCH_3__} \
+%{mcpu=arm710:-D__ARM_ARCH_3__} \
+%{mcpu=arm7100:-D__ARM_ARCH_3__} \
+%{mcpu=arm7500:-D__ARM_ARCH_3__} \
+%{mcpu=arm7500fe:-D__ARM_ARCH_3__} \
+%{mcpu=arm7m:-D__ARM_ARCH_3M__} \
+%{mcpu=arm7dm:-D__ARM_ARCH_3M__} \
+%{mcpu=arm7dmi:-D__ARM_ARCH_3M__} \
+%{mcpu=arm7tdmi:-D__ARM_ARCH_4T__} \
+%{mcpu=arm8:-D__ARM_ARCH_4__} \
+%{mcpu=arm810:-D__ARM_ARCH_4__} \
+%{mcpu=strongarm:-D__ARM_ARCH_4__} \
+%{mcpu=strongarm110:-D__ARM_ARCH_4__} \
+%{!mcpu*:%{!m6:%{!m2:%{!m3:%(cpp_cpu_arch_default)}}}} \
 "
-#endif
+
+/* Define __APCS_26__ if the PC also contains the PSR */
+/* This also examines deprecated -m[236] if neither of -mapcs-{26,32} is set,
+   ??? Delete this for 2.9.  */
+#define CPP_APCS_PC_SPEC "\
+%{mapcs-32:%{mapcs-26:%e-mapcs-26 and -mapcs-32 may not be used together} \
+ -D__APCS_32__} \
+%{mapcs-26:-D__APCS_26__} \
+%{!mapcs-32: %{!mapcs-26:%{m6:-D__APCS_32__} %{m2:-D__APCS_26__} \
+ %{m3:-D__APCS_26__} %{!m6:%{!m3:%{!m2:%(cpp_apcs_pc_default)}}}}} \
+"
+
+#define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_26__"
+
+#define CPP_FLOAT_SPEC "\
+%{msoft-float:\
+  %{mhard-float:%e-msoft-float and -mhard_float may not be used together} \
+  -D__SOFTFP__} \
+%{!mhard-float:%{!msoft-float:%(cpp_float_default)}} \
+"
+
+/* Default is hard float, which doesn't define anything */
+#define CPP_FLOAT_DEFAULT_SPEC ""
+
+#define CPP_ENDIAN_SPEC "\
+%{mbig-endian: \
+  %{mlittle-endian: \
+    %e-mbig-endian and -mlittle-endian may not be used together} \
+  -D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__} \
+  %{mle: \
+    %e-mbig-endian and -mle may not be used together} \
+  -D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__}} \
+%{mbe: \
+  %{mlittle-endian: \
+    %e-mbe and -mlittle-endian may not be used together} \
+  -D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__} \
+  %{mle: \
+    %e-mbe and -mle may not be used together} \
+  -D__ARMEB__ %{mwords-little-endian:-D__ARMWEL__}} \
+%{!mlittle-endian:%{!mbig-endian:%{!mbe:%{!mle:%(cpp_endian_default)}}}} \
+"
+
+/* Default is little endian, which doesn't define anything. */
+#define CPP_ENDIAN_DEFAULT_SPEC ""
+
+/* Translate (for now) the old -m[236] option into the appropriate -mcpu=...
+   and -mapcs-xx equivalents. 
+   ??? Remove support for this style in 2.9.
+   Also handle -mbe and -mle by expanding them into big-endian and
+   little-endian.  */
+#define CC1_SPEC "\
+%{m2:-mcpu=arm2 -mapcs-26} \
+%{m3:-mcpu=arm3 -mapcs-26} \
+%{m6:-mcpu=arm6 -mapcs-32} \
+%{mbe:-mbig-endian} \
+%{mle:-mlittle-endian} \
+"
+
+/* This macro defines names of additional specifications to put in the specs
+   that can be used in various specifications like CC1_SPEC.  Its definition
+   is an initializer with a subgrouping for each command option.
+
+   Each subgrouping contains a string constant, that defines the
+   specification name, and a string constant that used by the GNU CC driver
+   program.
+
+   Do not define this macro if it does not need to do anything.  */
+#define EXTRA_SPECS                                            \
+  { "cpp_cpu_arch",            CPP_CPU_ARCH_SPEC },            \
+  { "cpp_cpu_arch_default",    CPP_ARCH_DEFAULT_SPEC },        \
+  { "cpp_apcs_pc",             CPP_APCS_PC_SPEC },             \
+  { "cpp_apcs_pc_default",     CPP_APCS_PC_DEFAULT_SPEC },     \
+  { "cpp_float",               CPP_FLOAT_SPEC },               \
+  { "cpp_float_default",       CPP_FLOAT_DEFAULT_SPEC },       \
+  { "cpp_endian",              CPP_ENDIAN_SPEC },              \
+  { "cpp_endian_default",      CPP_ENDIAN_DEFAULT_SPEC },      \
+  SUBTARGET_EXTRA_SPECS
+
+#define SUBTARGET_EXTRA_SPECS
+
 \f
 /* Run-time Target Specification.  */
 #ifndef TARGET_VERSION
@@ -243,7 +401,9 @@ enum processor_type
   PROCESSOR_ARM2,
   PROCESSOR_ARM3,
   PROCESSOR_ARM6,
-  PROCESSOR_ARM7
+  PROCESSOR_ARM7,
+  PROCESSOR_ARM8,
+  PROCESSOR_STARM
 };
 
 /* Recast the cpu class to be the cpu attribute. */
@@ -513,6 +673,11 @@ extern int arm_arch4;
       for (regno = 16; regno < 24; ++regno)            \
        fixed_regs[regno] = call_used_regs[regno] = 1;  \
     }                                                  \
+  if (flag_pic)                                                \
+    {                                                  \
+      fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;         \
+      call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 0;     \
+    }                                                  \
 }
 
 /* Return number of consecutive hard regs needed starting at reg REGNO
@@ -678,12 +843,13 @@ enum reg_class
    address.  This means that the symbol is in the text segment and can be
    accessed without using a load. */
 
-#define EXTRA_CONSTRAINT(OP, C)                                         \
-  ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG  \
-   : (C) == 'R' ? (GET_CODE (OP) == MEM                                        \
-                  && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF             \
-                  && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0)))           \
-   : (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) : 0)
+#define EXTRA_CONSTRAINT(OP, C)                                                    \
+  ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG     \
+   : (C) == 'R' ? (GET_CODE (OP) == MEM                                            \
+                  && GET_CODE (XEXP (OP, 0)) == SYMBOL_REF                 \
+                  && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0)))               \
+   : (C) == 'S' ? (optimize > 0 && CONSTANT_ADDRESS_P (OP))                \
+   : 0)
 
 /* Constant letter 'G' for the FPU immediate constants. 
    'H' means the same constant negated.  */
@@ -876,7 +1042,7 @@ enum reg_class
   output_func_prologue ((STREAM), (SIZE))
 
 /* Call the function profiler with a given profile label.  The Acorn compiler
-   puts this BEFORE the prolog but gcc pust it afterwards.  The ``mov ip,lr''
+   puts this BEFORE the prolog but gcc puts it afterwards.  The ``mov ip,lr''
    seems like a good idea to stick with cc convention.  ``prof'' doesn't seem
    to mind about this!  */
 #define FUNCTION_PROFILER(STREAM,LABELNO)                                  \
@@ -1082,6 +1248,7 @@ enum reg_class
     }                                                                  \
 }
 #endif
+
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
    We have two alternate definitions for each of them.
@@ -1261,6 +1428,7 @@ do                                                                        \
    On the ARM, try to convert [REG, #BIGCONST]
    into ADD BASE, REG, #UPPERCONST and [BASE, #VALIDCONST],
    where VALIDCONST == 0 in case of TImode.  */
+extern struct rtx_def *legitimize_pic_address ();
 #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                          \
 {                                                                       \
   if (GET_CODE (X) == PLUS)                                             \
@@ -1316,6 +1484,8 @@ do                                                                        \
       if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1))                   \
        (X) = gen_rtx (MINUS, SImode, xop0, xop1);                       \
     }                                                                   \
+  if (flag_pic)                                                                 \
+    (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);                \
   if (memory_address_p (MODE, X))                                       \
     goto WIN;                                                           \
 }
@@ -1468,6 +1638,27 @@ do                                                                       \
 /* Try to generate sequences that don't involve branches, we can then use
    conditional instructions */
 #define BRANCH_COST 4
+
+/* A C statement to update the variable COST based on the relationship
+   between INSN that is dependent on DEP through dependence LINK.  */
+#define ADJUST_COST(INSN,LINK,DEP,COST) \
+  (COST) = arm_adjust_cost ((INSN), (LINK), (DEP), (COST))
+\f
+/* Position Independent Code.  */
+/* We decide which register to use based on the compilation options and
+   the assembler in use; this is more general than the APCS restriction of
+   using sb (r9) all the time.  */
+extern int arm_pic_register;
+
+/* The register number of the register used to address a table of static
+   data addresses in memory.  */
+#define PIC_OFFSET_TABLE_REGNUM arm_pic_register
+
+#define FINALIZE_PIC arm_finalize_pic ()
+
+#define LEGITIMATE_PIC_OPERAND_P(X) (! symbol_mentioned_p (X))
+
 \f
 /* Condition code information. */
 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
@@ -1690,6 +1881,19 @@ extern int arm_compare_fp;
   else output_addr_const(STREAM, X);                                   \
 }
 
+/* Handles PIC addr specially */
+#define OUTPUT_INT_ADDR_CONST(STREAM,X) \
+  {                                                                    \
+    if (flag_pic && GET_CODE(X) == CONST && is_pic(X))                 \
+      {                                                                        \
+       output_addr_const(STREAM, XEXP (XEXP (XEXP (X, 0), 0), 0));     \
+       fputs(" - (", STREAM);                                          \
+       output_addr_const(STREAM, XEXP (XEXP (XEXP (X, 0), 1), 0));     \
+       fputs(")", STREAM);                                             \
+      }                                                                        \
+    else output_addr_const(STREAM, X);                                 \
+  }
+
 /* Output code to add DELTA to the first argument, and then jump to FUNCTION.
    Used for C++ multiple inheritance.  */
 #define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION)       \
@@ -1710,14 +1914,12 @@ do {                                                                    \
                   mi_op, REGISTER_PREFIX, reg_names[this_regno],       \
                   REGISTER_PREFIX, reg_names[this_regno],              \
                   mi_delta & (0xff << shift));                         \
-         arm_increase_location (4);                                    \
          mi_delta &= ~(0xff << shift);                                 \
          shift += 8;                                                   \
        }                                                               \
     }                                                                  \
   fprintf (FILE, "\tldr\t%spc, [%spc, #-4]\n", REGISTER_PREFIX,                \
           REGISTER_PREFIX);                                            \
-  arm_increase_location (4);                                           \
   ASM_OUTPUT_INT (FILE, XEXP (DECL_RTL (FUNCTION), 0));                        \
 } while (0)
 
@@ -1736,4 +1938,4 @@ do {                                                                      \
      in 26 bit mode, the condition codes must be masked out of the     \
      return address.  This does not apply to ARM6 and later processors \
      when running in 32 bit mode.  */                                  \
-  ((!TARGET_6) ? (GEN_INT (0x03fffffc)) : (GEN_INT (0xffffffff)))
+  ((!TARGET_APCS_32) ? (GEN_INT (0x03fffffc)) : (GEN_INT (0xffffffff)))