more small data support
authorMichael Meissner <meissner@gcc.gnu.org>
Thu, 25 Jan 1996 15:48:40 +0000 (15:48 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Thu, 25 Jan 1996 15:48:40 +0000 (15:48 +0000)
From-SVN: r11101

gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/sysv4.h

index 47e1f35af8fda2485bd7d32f0253e7439f077d7e..24cbc8123c4f8b4a8291371ffca735145e112093 100644 (file)
@@ -836,6 +836,13 @@ input_operand (op, mode)
       && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF))
     return 1;
 
+  /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
+     to be valid.  */
+  if (DEFAULT_ABI == ABI_V4
+      && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
+      && small_data_operand (op, Pmode))
+    return 1;
+
   /* Otherwise, we will be doing this SET with an add, so anything valid
      for an add will be valid.  */
   return add_operand (op, mode);
@@ -853,11 +860,19 @@ small_data_operand (op, mode)
   if (DEFAULT_ABI != ABI_V4)
     return 0;
 
-  if (GET_CODE (op) != SYMBOL_REF && GET_CODE (op) != CONST)
+  if (GET_CODE (op) == SYMBOL_REF)
+    sym_ref = op;
+
+  else if (GET_CODE (op) != CONST
+          || GET_CODE (XEXP (op, 0)) != PLUS
+          || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
+          || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
     return 0;
 
-  sym_ref = eliminate_constant_term (op, &const_part);
-  if (!sym_ref || GET_CODE (sym_ref) != SYMBOL_REF || *XSTR (sym_ref, 0) != '@')
+  else
+    sym_ref = XEXP (XEXP (op, 0), 0);
+
+  if (*XSTR (sym_ref, 0) != '@')
     return 0;
 
   return 1;
@@ -2071,9 +2086,9 @@ print_operand (file, x, code)
             we have already done it, we can just use an offset of four.  */
          if (GET_CODE (XEXP (x, 0)) == PRE_INC
              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
-           output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
+           print_operand_address (file, plus_constant (XEXP (XEXP (x, 0), 0), 4));
          else
-           output_address (plus_constant (XEXP (x, 0), 4));
+           print_operand_address (file, plus_constant (XEXP (x, 0), 4));
        }
       return;
                            
@@ -2281,9 +2296,9 @@ print_operand (file, x, code)
        {
          if (GET_CODE (XEXP (x, 0)) == PRE_INC
              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
-           output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
+           print_operand_address (file, plus_constant (XEXP (XEXP (x, 0), 0), 8));
          else
-           output_address (plus_constant (XEXP (x, 0), 8));
+           print_operand_address (file, plus_constant (XEXP (x, 0), 8));
        }
       return;
                            
@@ -2327,9 +2342,9 @@ print_operand (file, x, code)
        {
          if (GET_CODE (XEXP (x, 0)) == PRE_INC
              || GET_CODE (XEXP (x, 0)) == PRE_DEC)
-           output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
+           print_operand_address (file, plus_constant (XEXP (XEXP (x, 0), 0), 12));
          else
-           output_address (plus_constant (XEXP (x, 0), 12));
+           print_operand_address (file, plus_constant (XEXP (x, 0), 12));
        }
       return;
                            
@@ -2347,10 +2362,10 @@ print_operand (file, x, code)
            fprintf (file, "%d(%d)", - GET_MODE_SIZE (GET_MODE (x)),
                     REGNO (XEXP (XEXP (x, 0), 0)));
          else
-           output_address (XEXP (x, 0));
+           print_operand_address (file, XEXP (x, 0));
        }
       else
-       output_addr_const (file, x);
+       print_operand_address (file, x);
       return;
 
     default:
@@ -4152,8 +4167,6 @@ rs6000_select_rtx_section (mode, x)
 {
   if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x))
     toc_section ();
-  else if (TARGET_SDATA && GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) <= 8)
-    sdata2_section ();
   else
     const_section ();
 }
@@ -4172,12 +4185,8 @@ rs6000_select_section (decl, reloc)
 
   if (TREE_CODE (decl) == STRING_CST)
     {
-      if ((! flag_writable_strings) && TARGET_SDATA && (size <= 8))
-       sdata2_section ();
-      else if (! flag_writable_strings)
+      if (! flag_writable_strings)
        const_section ();
-      else if (TARGET_SDATA && (size <= 8))
-       sdata_section ();
       else
        data_section ();
     }
@@ -4190,14 +4199,14 @@ rs6000_select_section (decl, reloc)
          || (DECL_INITIAL (decl) != error_mark_node
              && !TREE_CONSTANT (DECL_INITIAL (decl))))
        {
-         if (TARGET_SDATA && (size <= 8) && (size > 0))
+         if (TARGET_SDATA && (size > 0) && (size <= g_switch_value))
            sdata_section ();
          else
            data_section ();
        }
       else
        {
-         if (TARGET_SDATA && (size <= 8) && (size > 0))
+         if (TARGET_SDATA && (size > 0) && (size <= g_switch_value))
            sdata2_section ();
          else
            const_section ();
index 0ecc03c2b95be6043d69133d405753601c6123e8..6a5264bbceaa03e58f22908d9592a43b5469c628 100644 (file)
@@ -1005,13 +1005,15 @@ enum reg_class
    'Q' means that is a memory operand that is just an offset from a reg.
    'R' is for AIX TOC entries.
    'S' is for Windows NT SYMBOL_REFs
-   'T' is for Windows NT LABEL_REFs.  */
+   'T' is for Windows NT LABEL_REFs.
+   'U' is for V.4 small data references.  */
 
 #define EXTRA_CONSTRAINT(OP, C)                                                \
   ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) == REG \
    : (C) == 'R' ? LEGITIMATE_CONSTANT_POOL_ADDRESS_P (OP)              \
    : (C) == 'S' ? (TARGET_WINDOWS_NT && DEFAULT_ABI == ABI_NT && GET_CODE (OP) == SYMBOL_REF)\
    : (C) == 'T' ? (TARGET_WINDOWS_NT && DEFAULT_ABI == ABI_NT && GET_CODE (OP) == LABEL_REF) \
+   : (C) == 'U' ? (DEFAULT_ABI == ABI_V4 && small_data_operand (OP, GET_MODE (OP))) \
    : 0)
 
 /* Given an rtx X being reloaded into a reg required to be
@@ -1687,7 +1689,9 @@ typedef struct rs6000_args
        && LEGITIMATE_CONSTANT_POOL_BASE_P (XEXP (XEXP (X, 0), 0))))
 
 #define LEGITIMATE_SMALL_DATA_P(MODE, X)                               \
-  (DEFAULT_ABI == ABI_V4 && small_data_operand (X, MODE))
+  (DEFAULT_ABI == ABI_V4                                               \
+   && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST)            \
+   && small_data_operand (X, MODE))
 
 #define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET)                         \
  (GET_CODE (X) == CONST_INT                                            \
index 8131d84c6277eace6fe105ecc40bf8a4bd8bbd8f..12d9a8518fb57d5a4cca2f50271c7fe4439ecf6c 100644 (file)
   if (GET_CODE (operands[1]) == CONST_DOUBLE)
     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
 
+  /* Use default pattern for address of ELF small data */
+  if (TARGET_ELF
+      && TARGET_SDATA
+      && (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
+      && !small_data_operand (operands[1], SImode))
+    {
+      emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
+      DONE;
+    }
+
   if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
       && CONSTANT_P (operands[1])
       && GET_CODE (operands[1]) != HIGH
 }")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
-       (match_operand:SI 1 "input_operand" "r,S,T,m,r,I,J,n,R,*h,r,r,0"))]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r,r,r,r,r,*q,*c*l,*h")
+       (match_operand:SI 1 "input_operand" "r,S,T,U,m,r,I,J,n,R,*h,r,r,0"))]
   "gpc_reg_operand (operands[0], SImode)
    || gpc_reg_operand (operands[1], SImode)"
   "@
    mr %0,%1
    {l|lwz} %0,[toc]%1(2)
    {l|lwz} %0,[toc]%l1(2)
+   {cal|la} %0,%1
    {l%U1%X1|lwz%U1%X1} %0,%1
    {st%U0%X0|stw%U0%X0} %1,%0
    {lil|li} %0,%1
    mt%0 %1
    mt%0 %1
    cror 0,0,0"
-  [(set_attr "type" "*,load,load,load,*,*,*,*,*,*,*,mtjmpr,*")
-   (set_attr "length" "4,4,4,4,4,4,4,8,4,4,4,4,4")])
+  [(set_attr "type" "*,load,load,*,load,*,*,*,*,*,*,*,mtjmpr,*")
+   (set_attr "length" "4,4,4,4,4,4,4,4,8,4,4,4,4,4")])
 
 ;; Split a load of a large constant into the appropriate two-insn
 ;; sequence.
index 183be95a485fe5d8ed5e093f15b740a85f362ed9..36d61eb05b69af8e2b571d0f7a83de7fb54022d5 100644 (file)
@@ -99,6 +99,15 @@ Boston, MA 02111-1307, USA.  */
   { "mvme",             0 },                                           \
   { "emb",              0 },                                           \
 
+/* Max # of bytes for variables to automatically be put into the .sdata
+   or .sdata2 sections.  */
+extern int g_switch_value;             /* value of the -G xx switch */
+extern int g_switch_set;               /* whether -G xx was passed.  */
+
+#ifndef SDATA_DEFAULT_SIZE
+#define SDATA_DEFAULT_SIZE 8
+#endif
+
 /* Sometimes certain combinations of command options do not make sense
    on a particular target machine.  You can define a macro
    `OVERRIDE_OPTIONS' to take account of this.  This macro, if
@@ -110,11 +119,19 @@ Boston, MA 02111-1307, USA.  */
 
 #define SUBTARGET_OVERRIDE_OPTIONS                                     \
 do {                                                                   \
+  if (!g_switch_set)                                                   \
+    g_switch_value = SDATA_DEFAULT_SIZE;                               \
+                                                                       \
   rs6000_current_abi = ((TARGET_AIXDESC_CALLS) ? ABI_AIX :             \
                        (TARGET_NT_CALLS)      ? ABI_NT :               \
                        (TARGET_AIX_CALLS)     ? ABI_AIX_NODESC :       \
                                                 ABI_V4);               \
                                                                        \
+  /* CYGNUS LOCAL -fcombine-statics vs. -msdata */                     \
+  if (TARGET_SDATA)                                                    \
+    flag_combine_statics = 0;                                          \
+  /* END CYGNUS LOCAL -fcombine-statics vs. -msdata */                 \
+                                                                       \
   if (TARGET_RELOCATABLE && TARGET_SDATA)                              \
     {                                                                  \
       target_flags &= ~MASK_SDATA;                                     \
@@ -499,6 +516,19 @@ extern int rs6000_pic_labelno;
 %{mrelocatable} %{mrelocatable-lib} %{memb} %{msdata: -memb} \
 %{mlittle} %{mlittle-endian} %{mbig} %{mbig-endian}"
 
+#undef CC1_SPEC
+/* Pass -G xxx to the compiler */
+#define CC1_SPEC "%{G*}"
+
+/* Switch  Recognition by gcc.c.  Add -G xx support */
+
+#undef SWITCH_TAKES_ARG
+#define SWITCH_TAKES_ARG(CHAR)                                         \
+  ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o'                     \
+   || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u'                  \
+   || (CHAR) == 'I' || (CHAR) == 'm'                                   \
+   || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'G')
+
 /* Output .file and comments listing what options there are */
 #undef ASM_FILE_START
 #define ASM_FILE_START(FILE)                                           \
@@ -664,7 +694,7 @@ do {                                                                        \
 
 #undef LINK_SPEC
 #define LINK_SPEC "\
-%{h*} %{V} %{v:%{!V:-V}} \
+%{h*} %{V} %{v:%{!V:-V}} %{G*} \
 %{b} %{Wl,*:%*} \
 %{static:-dn -Bstatic} \
 %{shared:-G -dy -z text %{!h*:%{o*:-h %*}}} \