*** empty log message ***
authorJim Wilson <wilson@gcc.gnu.org>
Sun, 3 May 1992 23:57:21 +0000 (16:57 -0700)
committerJim Wilson <wilson@gcc.gnu.org>
Sun, 3 May 1992 23:57:21 +0000 (16:57 -0700)
From-SVN: r874

gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/config/sparc/sysv4.h
gcc/sched.c

index c74275a..f02f77c 100644 (file)
@@ -2602,3 +2602,112 @@ sparc_type_code (type)
         }
     }
 }
+\f
+#ifdef HANDLE_PRAGMA
+
+/* Handle a pragma directive.  HANDLE_PRAGMA conspires to parse the
+   input following #pragma into tokens based on yylex.  TOKEN is the
+   current token, and STRING is its printable form.  */
+
+void
+handle_pragma_token (string, token)
+     char *string;
+     tree token;
+{
+  static enum pragma_state
+    {
+      ps_start,
+      ps_done,
+      ps_bad,
+      ps_weak,
+      ps_name,
+      ps_equals,
+      ps_value,
+      } state = ps_start, type;
+  static char *name;
+  static char *value;
+  static int align;
+
+  if (string == 0)
+    {
+#ifdef WEAK_ASM_OP
+      if (type == ps_weak)
+       {
+         if (state == ps_name || state == ps_value)
+           {
+             fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
+             ASM_OUTPUT_LABELREF (asm_out_file, name);
+             fputc ('\n', asm_out_file);
+             if (state == ps_value)
+               {
+                 fputc ('\t', asm_out_file);
+                 ASM_OUTPUT_LABELREF (asm_out_file, name);
+                 fputs (" = ", asm_out_file);
+                 ASM_OUTPUT_LABELREF (asm_out_file, value);
+                 fputc ('\n', asm_out_file);
+               }
+           }
+         else if (! (state == ps_done || state == ps_start))
+           warning ("ignoring malformed #pragma weak symbol [=value]");
+       }
+#endif /* WEAK_ASM_OP */
+
+      type = state = ps_start;
+      return;
+    }
+
+  switch (state)
+    {
+    case ps_start:
+      if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+#ifdef WEAK_ASM_OP
+         if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
+           type = state = ps_weak;
+         else
+#endif
+           type = state = ps_done;
+       }
+      else
+       type = state = ps_done;
+      break;
+
+#ifdef WEAK_ASM_OP
+    case ps_weak:
+      if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+         name = IDENTIFIER_POINTER (token);
+         state = ps_name;
+       }
+      else
+       state = ps_bad;
+      break;
+
+    case ps_name:
+      state = (strcmp (string, "=") ? ps_bad : ps_equals);
+      break;
+
+    case ps_equals:
+      if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+         value = IDENTIFIER_POINTER (token);
+         state = ps_value;
+       }
+      else
+       state = ps_bad;
+      break;
+
+    case ps_value:
+      state = ps_bad;
+      break;
+#endif /* WEAK_ASM_OP */
+
+    case ps_bad:
+    case ps_done:
+      break;
+
+    default:
+      abort ();
+    }
+}
+#endif /* HANDLE_PRAGMA */
index a3bbdf9..857046c 100644 (file)
 ;; FiTOs/d     9/5
 
 ;; The CY7C602 can only support 2 fp isnsn simultaneously.
-;; More insns cause the chip to stall.  Until we handle this
-;; better in the scheduler, we use excess cycle times to
-;; more evenly spread out fp insns.
-
-(define_function_unit "fp_alu" 1 2 (eq_attr "type" "fp") 8 0)
-(define_function_unit "fp_mul" 1 2 (eq_attr "type" "fpmul") 10 0)
-(define_function_unit "fp_div" 1 2 (eq_attr "type" "fpdiv") 23 0)
-(define_function_unit "fp_sqrt" 1 2 (eq_attr "type" "fpsqrt") 34 0)
+;; More insns cause the chip to stall.
+
+(define_function_unit "fp_alu" 1 2 (eq_attr "type" "fp") 5 0)
+(define_function_unit "fp_mul" 1 2 (eq_attr "type" "fpmul") 7 0)
+(define_function_unit "fp_div" 1 2 (eq_attr "type" "fpdiv") 37 0)
+(define_function_unit "fp_sqrt" 1 2 (eq_attr "type" "fpsqrt") 63 0)
 \f
 ;; Compare instructions.
 ;; This controls RTL generation and register allocation.
index 2e91601..3b9d500 100644 (file)
@@ -56,6 +56,24 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define CPP_PREDEFINES \
   "-Dsparc -Dunix -D__svr4__ -Asystem(unix) -Acpu(sparc) -Amachine(sparc)"
 
+/* The specialized code which needs to appear in the .init section prior
+   to the prologue code for `__do_global_ctors' (see crtstuff.c).
+
+   On Sparcs running svr4, the /usr/ccs/lib/crti.o file (with gets linked
+   in prior to the crtbegin.o file) has a single `save' instruction in its
+   .init section.  That `save' instruction tries to setup a stack frame for
+   the sake of any subsequent code in the .init section.  Unfortunately,
+   the size it uses for the stack frame is only a guess, and is not really
+   adequate for our purposes.  More importantly, we independently put our
+   own standard function prologue (for __do_global_ctors) into the .init
+   section and that function prologue includes its own `save' instruction!
+   Thus, unless we do something to correct the situation, we'll get *two*
+   stack frames allocated when crt0.o calls the code in the .init section,
+   and havoc will ensue.  The following macro definition prevents such woes.
+*/
+
+#define INIT_SECTION_PREAMBLE  asm ("restore")
+
 /* This is the string used to begin an assembly language comment for the
    Sparc/svr4 assembler.  */
 
@@ -83,7 +101,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* This is the format used to print a .pushsection pseudo-op (and its operand)
    for the Sparc/svr4 assembler.  */
 
-#define PUSHSECTION_FORMAT     "%s\t\"%s\"\n"
+#define PUSHSECTION_FORMAT     "\t%s\t\"%s\"\n"
 
 /* This is how to equate one symbol to another symbol.  The syntax used is
    `SYM1=SYM2'.  Note that this is different from the way equates are done
@@ -181,3 +199,32 @@ do {                                                                       \
 #define INIT_SECTION_ASM_OP    ".section\t\".init\",#alloc"
 #define CTORS_SECTION_ASM_OP    ".section\t\".ctors\",#alloc"
 #define DTORS_SECTION_ASM_OP    ".section\t\".dtors\",#alloc"
+
+/* Code to handle #pragma directives.  The interface is a bit messy,
+   but there's no simpler way to do this while still using yylex.  */
+#define HANDLE_PRAGMA(FILE)                                    \
+  do {                                                         \
+    while (c == ' ' || c == '\t')                              \
+      c = getc (FILE);                                         \
+    if (c == '\n' || c == EOF)                                 \
+      {                                                                \
+       handle_pragma_token (0, 0);                             \
+       return c;                                               \
+      }                                                                \
+    ungetc (c, FILE);                                          \
+    switch (yylex ())                                          \
+      {                                                                \
+      case IDENTIFIER:                                         \
+      case TYPENAME:                                           \
+      case STRING:                                             \
+      case CONSTANT:                                           \
+       handle_pragma_token (token_buffer, yylval.ttype);       \
+       break;                                                  \
+      default:                                                 \
+       handle_pragma_token (token_buffer, 0);                  \
+      }                                                                \
+    if (nextchar >= 0)                                         \
+      c = nextchar, nextchar = -1;                             \
+    else                                                       \
+      c = getc (FILE);                                         \
+  } while (1)
index 0897dd3..ce4e59d 100644 (file)
@@ -2391,11 +2391,9 @@ schedule_block (b, file)
      high priorities to these insns to guarantee that they get scheduled last.
      If these insns are ignored, as is currently done, the register life info
      may be incorrectly computed.  */
-  if (GET_CODE (tail) == INSN
-      && GET_CODE (PATTERN (tail)) == USE
-      && next_nonnote_insn (tail) == 0)
+  if (GET_CODE (tail) == INSN && GET_CODE (PATTERN (tail)) == USE)
     {
-      /* Don't try to reorder any USE insns at the end of a function.
+      /* Don't try to reorder any USE insns at the end of any block.
         They must be last to ensure proper register allocation.
         Exclude them all from scheduling.  */
       do