OSDN Git Service

Apply Philip Blundell's patch to fix PIC operands.
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Feb 2000 20:00:29 +0000 (20:00 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 9 Feb 2000 20:00:29 +0000 (20:00 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31867 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.h

index 30f0230..2e17b20 100644 (file)
@@ -1,3 +1,12 @@
+2000-02-09  Philip Blundell  <pb@futuretv.com>
+
+        * config/arm/arm.c (legitimize_pic_address): Handle LABEL_REF
+        correctly.
+
+        * config/arm/arm.h (LEGITIMATE_CONSTANT_P): Allow anything when
+        generating PIC.
+        (LEGITIMATE_PIC_OPERAND): Disallow references to labels.
+
 2000-02-09  Zack Weinberg  <zack@wolery.cumb.org>
 
        * cpplib.c (cpp_define, cpp_undef): Make sure the stacked buffer
index c3c5360..6560893 100644 (file)
@@ -1476,6 +1476,181 @@ arm_return_in_memory (type)
   return 1;
 }
 
+/* Initialize a variable CUM of type CUMULATIVE_ARGS
+   for a call to a function whose data type is FNTYPE.
+   For a library call, FNTYPE is NULL.  */
+void
+arm_init_cumulative_args (pcum, fntype, libname, indirect)
+     CUMULATIVE_ARGS * pcum;
+     tree fntype;
+     rtx libname  ATTRIBUTE_UNUSED;
+     int indirect ATTRIBUTE_UNUSED;
+{
+  /* On the ARM, the offset starts at 0.  */
+  pcum->nregs = ((fntype && aggregate_value_p (TREE_TYPE (fntype)))
+                ? 1 : 0);
+
+  pcum->call_cookie = CALL_NORMAL;
+
+  if (TARGET_LONG_CALLS)
+    pcum->call_cookie = CALL_LONG;
+    
+  /* Check for long call/short call attributes.  The attributes
+     override any command line option.  */
+  if (fntype)
+    {
+      if (lookup_attribute ("short_call", TYPE_ATTRIBUTES (fntype)))
+       pcum->call_cookie = CALL_SHORT;
+      else if (lookup_attribute ("long_call", TYPE_ATTRIBUTES (fntype)))
+       pcum->call_cookie = CALL_LONG;
+    }
+}
+
+/* Determine where to put an argument to a function.
+   Value is zero to push the argument on the stack,
+   or a hard register in which to store the argument.
+
+   MODE is the argument's machine mode.
+   TYPE is the data type of the argument (as a tree).
+    This is null for libcalls where that information may
+    not be available.
+   CUM is a variable of type CUMULATIVE_ARGS which gives info about
+    the preceding args and about the function being called.
+   NAMED is nonzero if this argument is a named parameter
+    (otherwise it is an extra parameter matching an ellipsis).  */
+rtx
+arm_function_arg (pcum, mode, type, named)
+     CUMULATIVE_ARGS * pcum;
+     enum machine_mode mode;
+     tree type ATTRIBUTE_UNUSED;
+     int named;
+{
+  if (mode == VOIDmode)
+    /* Compute operand 2 of the call insn.  */
+    return GEN_INT (pcum->call_cookie);
+  
+  if (! named || pcum->nregs >= NUM_ARG_REGS)
+    return NULL_RTX;
+  
+  return gen_rtx_REG (mode, pcum->nregs);
+}
+
+\f
+/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
+   this file.  */
+static int
+current_file_function_operand (sym_ref)
+  rtx sym_ref;
+{
+  return (SYMBOL_REF_FLAG (sym_ref)
+         || sym_ref == XEXP (DECL_RTL (current_function_decl), 0));
+}
+
+/* Return non-zero if a 32 bit "long call" should be generated for this
+   call.
+
+   We generate a long call if the function is not declared
+   __attribute__ ((short_call),
+
+   AND:
+   
+     (1)  the function is declared __attribute__ ((long_call))
+
+   OR
+
+     (2) -mlong-calls is enabled and we don't know whether the target
+         function is declared in this file.
+        
+   This function will typically be called by C fragments in the machine
+   description file.  CALL_REF is the matched rtl operand.  CALL_COOKIE
+   describes the value of the long_call and short_call attributes for
+   the called functiion.  CALL_SYMBOL is used to distinguish between
+   two different callers of the function.  It is set to 1 in the "call_symbol"
+   and "call_symbol_value" patterns in arm.md and to 0 in the "call" and
+   "call_value" patterns.  This is because of the difference of SYM_REFs passed
+   from "call_symbol" and "call"  patterns.  */
+int
+arm_is_longcall_p (sym_ref, call_cookie, call_symbol)
+  rtx sym_ref;
+  int call_cookie;
+  int call_symbol;
+{
+  if (! call_symbol)
+    {
+      if (GET_CODE (sym_ref) != MEM)
+       return 0;
+
+      sym_ref = XEXP (sym_ref, 0);
+    }
+
+  if (GET_CODE (sym_ref) != SYMBOL_REF)
+    return 0;
+
+  if (call_cookie & CALL_SHORT)
+    return 0;
+
+  if (TARGET_LONG_CALLS && flag_function_sections)
+    return 1;
+  
+  if (current_file_function_operand (sym_ref, VOIDmode))
+    return 0;
+  
+  return (call_cookie & CALL_LONG) || TARGET_LONG_CALLS;
+}
+\f
+/* Return nonzero if IDENTIFIER with arguments ARGS is a valid machine specific
+   attribute for TYPE.  The attributes in ATTRIBUTES have previously been
+   assigned to TYPE.  */
+int
+arm_valid_type_attribute_p (type, attributes, identifier, args)
+     tree type;
+     tree attributes ATTRIBUTE_UNUSED;
+     tree identifier;
+     tree args;
+{
+  if (   TREE_CODE (type) != FUNCTION_TYPE
+      && TREE_CODE (type) != METHOD_TYPE
+      && TREE_CODE (type) != FIELD_DECL
+      && TREE_CODE (type) != TYPE_DECL)
+    return 0;
+
+  /* Function calls made to this symbol must be done indirectly, because
+     it may lie outside of the 26 bit addressing range of a normal function
+     call.  */
+  if (is_attribute_p ("long_call", identifier))
+    return (args == NULL_TREE);
+
+  /* Whereas these functions are always known to reside within the 26 bit
+     addressing range.  */
+  if (is_attribute_p ("short_call", identifier))
+    return (args == NULL_TREE);
+  
+  return 0;
+}
+
+/* Return 0 if the attributes for two types are incompatible, 1 if they
+   are compatible, and 2 if they are nearly compatible (which causes a
+   warning to be generated).  */
+int
+arm_comp_type_attributes (type1, type2)
+     tree type1;
+     tree type2;
+{
+  int l1, l2, s1, s2;
+  /* Check for mismatch of non-default calling convention.  */
+  if (TREE_CODE (type1) != FUNCTION_TYPE)
+    return 1;
+
+  /* Check for mismatched call attributes.  */
+  l1 = ! lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1));
+  l2 = ! lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2));
+  s1 = ! lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1));
+  s2 = ! lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2));
+
+  return ! ((l1 ^ l2) || (s1 ^s2) || (l1 | s2) || (s1 | l2));
+}
+
+\f
 int
 legitimate_pic_operand_p (x)
      rtx x;
@@ -1590,7 +1765,20 @@ legitimize_pic_address (orig, mode, reg)
       return gen_rtx_PLUS (Pmode, base, offset);
     }
   else if (GET_CODE (orig) == LABEL_REF)
-    current_function_uses_pic_offset_table = 1;
+    {
+      current_function_uses_pic_offset_table = 1;
+      
+      if (NEED_GOT_RELOC)
+        {
+          rtx pic_ref, address = gen_reg_rtx (Pmode);
+          
+          emit_insn (gen_pic_load_addr (address, orig));
+          pic_ref = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, address);
+          
+          emit_move_insn (address, pic_ref);
+          return address;
+        }
+    }
 
   return orig;
 }
index 33f5932..f457f92 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for ARM.
-   Copyright (C) 1991, 93-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1991, 93, 94, 05, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
    Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
    and Martin Simmons (@harleqn.co.uk).
    More major hacks by Richard Earnshaw (rearnsha@arm.com)
@@ -48,7 +48,7 @@ Boston, MA 02111-1307, USA.  */
 #define TARGET_CPU_strongarm1100 0x0040
 #define TARGET_CPU_arm9                0x0080
 #define TARGET_CPU_arm9tdmi    0x0080
-/* Configure didn't specify */
+/* Configure didn't specify */
 #define TARGET_CPU_generic     0x8000
 
 enum arm_cond_code
@@ -365,7 +365,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
      "Generate re-entrant, PIC code" },                                \
   {"no-apcs-reentrant",               -ARM_FLAG_APCS_REENT, "" },      \
   {"alignment-traps",           ARM_FLAG_MMU_TRAPS,            \
-     "The MMU will trap on unaligned accesses" },\
+     "The MMU will trap on unaligned accesses" },              \
   {"no-alignment-traps",       -ARM_FLAG_MMU_TRAPS, "" },      \
   {"short-load-bytes",         ARM_FLAG_MMU_TRAPS, "" },       \
   {"no-short-load-bytes",      -ARM_FLAG_MMU_TRAPS, "" },      \
@@ -385,7 +385,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
      "Support calls between THUMB and ARM instructions sets" },        \
   {"no-thumb-interwork",       -ARM_FLAG_INTERWORK, "" },      \
   {"abort-on-noreturn",         ARM_FLAG_ABORT_NORETURN,       \
-   "Generate a call to abort if a noreturn function returns"}, \
+     "Generate a call to abort if a noreturn function returns"},\
   {"no-abort-on-noreturn",     -ARM_FLAG_ABORT_NORETURN, ""},  \
   {"sched-prolog",             -ARM_FLAG_NO_SCHED_PRO,         \
      "Do not move instructions into a function's prologue" },  \
@@ -394,7 +394,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
      "Do not load the PIC register in function prologues" },   \
   {"no-single-pic-base",       -ARM_FLAG_SINGLE_PIC_BASE, "" },        \
   {"long-calls",               ARM_FLAG_LONG_CALLS,            \
-   "Generate all call instructions as indirect calls"},                \
+     "Generate all call instructions as indirect calls"},      \
   {"no-long-calls",           -ARM_FLAG_LONG_CALLS, ""},       \
   SUBTARGET_SWITCHES                                           \
   {"",                         TARGET_DEFAULT, "" }            \
@@ -411,7 +411,7 @@ Unrecognized value in TARGET_CPU_DEFAULT.
   {"fp=",   & target_fp_name,                                  \
      "Specify the version of the floating point emulator" },   \
   { "structure-size-boundary=", & structure_size_string,       \
-     "Specify the minumum bit alignment of structures" },      \
+     "Specify the minimum bit alignment of structures" },      \
   { "pic-register=", & arm_pic_register_string,                        \
      "Specify the register to be used for PIC addressing" }    \
 }
@@ -1136,6 +1136,23 @@ enum reg_class
    than a word, or if they contain elements offset from zero in the struct. */
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
+/* A C type for declaring a variable that is used as the first argument of
+   `FUNCTION_ARG' and other related values.  For some target machines, the
+   type `int' suffices and can hold the number of bytes of argument so far.  */
+typedef struct
+{
+  /* This is the number of argument registers scanned so far.  */
+  int nregs;
+  /* instructions on how to process this call.  */
+  int call_cookie;
+}
+CUMULATIVE_ARGS;
+
+/* Flags for the call_cookie field of CUMULATIVE_ARGS.  */
+#define CALL_NORMAL            0       /* No special processing.  */
+#define CALL_LONG              1       /* Always call indirect.  */
+#define CALL_SHORT             2       /* Never call indirect.  */
+
 /* Define where to put the arguments to a function.
    Value is zero to push the argument on the stack,
    or a hard register in which to store the argument.
@@ -1154,38 +1171,29 @@ enum reg_class
    only in assign_parms, since SETUP_INCOMING_VARARGS is defined), say it is
    passed in the stack (function_prologue will indeed make it pass in the
    stack if necessary).  */
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)           \
-  ((NAMED)                                             \
-   ? ((CUM) >= NUM_ARG_REGS ? 0 : gen_rtx_REG (MODE, CUM))\
-   : 0)
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+  arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED))
 
 /* For an arg passed partly in registers and partly in memory,
    this is the number of registers used.
    For args passed entirely in registers or entirely in memory, zero.  */
 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED)     \
-  (    NUM_ARG_REGS > (CUM)                                    \
-   && (NUM_ARG_REGS < ((CUM) + NUM_REGS2 (MODE, TYPE)))                \
-   ?   NUM_ARG_REGS - (CUM) : 0)
-
-/* A C type for declaring a variable that is used as the first argument of
-   `FUNCTION_ARG' and other related values.  For some target machines, the
-   type `int' suffices and can hold the number of bytes of argument so far.
-
-   On the ARM, this is the number of bytes of arguments scanned so far.  */
-#define CUMULATIVE_ARGS  int
+  (    NUM_ARG_REGS > (CUM).nregs                              \
+   && (NUM_ARG_REGS < ((CUM).nregs + NUM_REGS2 (MODE, TYPE)))  \
+   ?   NUM_ARG_REGS - (CUM).nregs : 0)
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.
    On the ARM, the offset starts at 0.  */
-#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT)  \
-  ((CUM) = (((FNTYPE) && aggregate_value_p (TREE_TYPE ((FNTYPE)))) ? 1 : 0))
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
+  arm_init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (INDIRECT))
 
 /* Update the data in CUM to advance over an argument
    of mode MODE and data type TYPE.
    (TYPE is null for libcalls where that information may not be available.)  */
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)   \
-  (CUM) += NUM_REGS2 (MODE, TYPE)
+  (CUM).nregs += NUM_REGS2 (MODE, TYPE)
 
 /* 1 if N is a possible register number for function argument passing.
    On the ARM, r0-r3 are used to pass args.  */
@@ -1209,8 +1217,8 @@ enum reg_class
 {                                                                      \
   extern int current_function_anonymous_args;                          \
   current_function_anonymous_args = 1;                                 \
-  if ((CUM) < NUM_ARG_REGS)                                            \
-    (PRETEND_SIZE) = (NUM_ARG_REGS - (CUM)) * UNITS_PER_WORD;          \
+  if ((CUM).nregs < NUM_ARG_REGS)                                      \
+    (PRETEND_SIZE) = (NUM_ARG_REGS - (CUM).nregs) * UNITS_PER_WORD;    \
 }
 
 /* Generate assembly output for the start of a function.  */
@@ -1437,8 +1445,18 @@ enum reg_class
 
    On the ARM, allow any integer (invalid ones are removed later by insn
    patterns), nice doubles and symbol_refs which refer to the function's
-   constant pool XXX.  */
-#define LEGITIMATE_CONSTANT_P(X)       (! label_mentioned_p (X))
+   constant pool XXX.  
+   
+   When generating pic allow anything.  */
+#define LEGITIMATE_CONSTANT_P(X)       (flag_pic || ! label_mentioned_p (X))
+
+/* If we are referencing a function that is static or is known to be 
+   in this file, make the SYMBOL_REF special.  We can use this to indicate
+   that we can do direct call to that function.  */
+#define ARM_MARK_NEARBY_FUNCTION(decl)                                 \
+  if (TREE_CODE (decl) == FUNCTION_DECL                                        \
+      && (TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl)))             \
+    SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;                    \
 
 /* Symbols in the text segment can be accessed without indirecting via the
    constant pool; it may take an extra binary operation, but this is still
@@ -1457,6 +1475,13 @@ enum reg_class
                  ? TREE_CST_RTL (decl) : DECL_RTL (decl));             \
       SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;                             \
     }                                                                  \
+                                                                       \
+  ARM_MARK_NEARBY_FUNCTION (decl)                                      \
+}
+#else
+#define ENCODE_SECTION_INFO(decl)                                      \
+{                                                                      \
+  ARM_MARK_NEARBY_FUNCTION (decl)                                      \
 }
 #endif
 
@@ -1875,16 +1900,30 @@ extern const char * arm_pic_register_string;
 
 /* We can't directly access anything that contains a symbol,
    nor can we indirect via the constant pool.  */
-#define LEGITIMATE_PIC_OPERAND_P(X)                            \
-       (! symbol_mentioned_p (X)                               \
-        && (! CONSTANT_POOL_ADDRESS_P (X)                      \
-            || ! symbol_mentioned_p (get_pool_constant (X))))
+#define LEGITIMATE_PIC_OPERAND_P(X)                                    \
+       (   ! symbol_mentioned_p (X)                                    \
+        && ! label_mentioned_p (X)                                     \
+        && (! CONSTANT_POOL_ADDRESS_P (X)                              \
+            || (   ! symbol_mentioned_p (get_pool_constant (X)))       \
+                && ! label_mentioned_p (get_pool_constant (X))))
      
 /* We need to know when we are making a constant pool; this determines
    whether data needs to be in the GOT or can be referenced via a GOT
    offset.  */
 extern int making_const_table;
-
+\f
+/* If defined, a C expression whose value is nonzero if IDENTIFIER
+   with arguments ARGS is a valid machine specific attribute for TYPE.
+   The attributes in ATTRIBUTES have previously been assigned to TYPE.  */
+#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, NAME, ARGS) \
+  (arm_valid_type_attribute_p (TYPE, ATTRIBUTES, NAME, ARGS))
+
+/* If defined, a C expression whose value is zero if the attributes on
+   TYPE1 and TYPE2 are incompatible, one if they are compatible, and
+   two if they are nearly compatible (which causes a warning to be
+   generated).  */
+#define COMP_TYPE_ATTRIBUTES(TYPE1, TYPE2) \
+  (arm_comp_type_attributes (TYPE1, TYPE2))
 \f
 /* Condition code information. */
 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,