*** empty log message ***
authorTimothy Moore <moore@gnu.org>
Wed, 14 Oct 1992 14:50:17 +0000 (14:50 +0000)
committerTimothy Moore <moore@gnu.org>
Wed, 14 Oct 1992 14:50:17 +0000 (14:50 +0000)
From-SVN: r2460

gcc/config/pa/pa-hpux.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md
gcc/config/pa/xm-pa.h
gcc/ginclude/va-pa.h

index d614cbc..52ab59b 100644 (file)
 
 #undef CPP_PREDEFINES
 #define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE"
+
+/* Link against shared libraries */
+#ifdef hpux8
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT 8 
+#undef LINK_SPEC
+#define LINK_SPEC "-u main %{g*:-a archive} %{p:-a archive} %{pg:-a archive}"
+#endif
index 7f34d80..ddc7f9e 100644 (file)
@@ -33,6 +33,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "tree.h"
 #include "c-tree.h"
 #include "expr.h"
+#include "obstack.h"
 
 /* Save the operands last given to a compare for use when we
    generate a scc or bcc insn.  */
@@ -204,6 +205,22 @@ fp_reg_operand (op, mode)
 {
   return reg_renumber && FP_REG_P (op);
 }
+
+int
+check_fp_mov (operands)
+     rtx *operands;
+{
+  enum machine_mode mode = GET_MODE (operands[0]);
+
+  if (fp_reg_operand (operands[0], mode))
+    return (register_operand (operands[1], mode)
+           || short_memory_operand (operands[1], mode));
+  else if (fp_reg_operand (operands[1], mode))
+    return (register_operand (operands[0], mode)
+           || short_memory_operand (operands[0], mode));
+  else
+    return 1;
+}
 \f
 extern int current_function_uses_pic_offset_table;
 extern rtx force_reg (), validize_mem ();
@@ -481,63 +498,6 @@ initialize_pic ()
 void
 finalize_pic ()
 {
-  /* The table we use to reference PIC data.  */
-  rtx global_offset_table;
-  /* Labels to get the PC in the prologue of this function.  */
-  rtx l1, l2;
-  rtx seq;
-  int orig_flag_pic = flag_pic;
-
-  if (current_function_uses_pic_offset_table == 0)
-    return;
-
-  if (! flag_pic)
-    abort ();
-
-  flag_pic = 0;
-  l1 = gen_label_rtx ();
-  l2 = gen_label_rtx ();
-
-  start_sequence ();
-
-  emit_label (l1);
-  /* Note that we pun calls and jumps here!  */
-  emit_jump_insn (gen_rtx (PARALLEL, VOIDmode,
-                         gen_rtvec (2,
-                                    gen_rtx (SET, VOIDmode, pc_rtx, gen_rtx (LABEL_REF, VOIDmode, l2)),
-                                    gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, 15), gen_rtx (LABEL_REF, VOIDmode, l2)))));
-  emit_label (l2);
-
-  /* Initialize every time through, since we can't easily
-     know this to be permanent.  */
-  global_offset_table = gen_rtx (SYMBOL_REF, Pmode, "*__GLOBAL_OFFSET_TABLE_");
-  pic_pc_rtx = gen_rtx (CONST, Pmode,
-                       gen_rtx (MINUS, Pmode,
-                                global_offset_table,
-                                gen_rtx (CONST, Pmode,
-                                         gen_rtx (MINUS, Pmode,
-                                                  gen_rtx (LABEL_REF, VOIDmode, l1),
-                                                  pc_rtx))));
-
-  emit_insn (gen_rtx (SET, VOIDmode, pic_offset_table_rtx,
-                     gen_rtx (HIGH, Pmode, pic_pc_rtx)));
-  emit_insn (gen_rtx (SET, VOIDmode,
-                     pic_offset_table_rtx,
-                     gen_rtx (LO_SUM, Pmode,
-                              pic_offset_table_rtx, pic_pc_rtx)));
-  emit_insn (gen_rtx (SET, VOIDmode,
-                     pic_offset_table_rtx,
-                     gen_rtx (PLUS, SImode,
-                              pic_offset_table_rtx, gen_rtx (REG, SImode, 15))));
-  /* emit_insn (gen_rtx (ASM_INPUT, VOIDmode, "!#PROLOGUE# 1")); */
-  LABEL_PRESERVE_P (l1) = 1;
-  LABEL_PRESERVE_P (l2) = 1;
-  flag_pic = orig_flag_pic;
-
-  seq = gen_sequence ();
-  end_sequence ();
-  emit_insn_after (seq, get_insns ());
-
   /* Need to emit this whether or not we obey regdecls,
      since setjmp/longjmp can cause life info to screw up.  */
   emit_insn (gen_rtx (USE, VOIDmode, pic_offset_table_rtx));
@@ -570,15 +530,36 @@ hppa_address_cost (X)
    normally.  */
 
 int
-emit_move_sequence (operands, mode)
+emit_move_sequence (operands, mode, scratch_reg)
      rtx *operands;
      enum machine_mode mode;
+     rtx scratch_reg;
 {
   register rtx operand0 = operands[0];
   register rtx operand1 = operands[1];
 
-  /* Handle most common case first: storing into a register.  */
-  if (register_operand (operand0, mode))
+  if (fp_reg_operand (operand0, mode)
+      && GET_CODE (operand1) == MEM
+      && !short_memory_operand  (operand1, mode)
+      && scratch_reg)
+    {
+      emit_move_insn (scratch_reg, XEXP (operand1 , 0));
+      emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MEM, mode,
+                                                           scratch_reg)));
+      return 1;
+    }
+  else if (fp_reg_operand (operand1, mode)
+          && GET_CODE (operand0) == MEM
+          && !short_memory_operand  (operand0, mode)
+          && scratch_reg)
+    {
+      emit_move_insn (scratch_reg, XEXP (operand0 , 0));
+      emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, mode,  scratch_reg),
+                         operand1));
+      return 1;
+    }
+  /* Handle most common case: storing into a register.  */
+  else if (register_operand (operand0, mode))
     {
       if (register_operand (operand1, mode)
          || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1))
@@ -608,21 +589,6 @@ emit_move_sequence (operands, mode)
     }
 
   /* Simplify the source if we need to.  */
-#if 0
-  if (GET_CODE (operand1) == HIGH
-      && symbolic_operand (XEXP (operand1, 0), mode)
-      && !read_only_operand (XEXP (operand1, 0)))
-    {
-      rtx temp = reload_in_progress ? operand0 : gen_reg_rtx (mode);
-      
-      emit_insn (gen_rtx (SET, VOIDmode, temp, operand1));
-      emit_insn (gen_rtx (SET, VOIDmode,
-                         operand0,
-                         gen_rtx (PLUS, mode,
-                                  temp, gen_rtx (REG, mode, 27))));
-      return 1;
-    }
-#endif
   if (GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
     {
       if (symbolic_operand (operand1, mode))
@@ -636,12 +602,28 @@ emit_move_sequence (operands, mode)
          /* use dp, register 27. */
          else if (read_only_operand (operand1))
            {
-             emit_insn (gen_rtx (SET, VOIDmode,
+             rtx set = gen_rtx (SET, VOIDmode,
                                  operand0,
-                                 gen_rtx (HIGH, mode, operand1)));
+                                 gen_rtx (LO_SUM, mode, operand0, operand1));
+                                
              emit_insn (gen_rtx (SET, VOIDmode,
                                  operand0,
-                                 gen_rtx (LO_SUM, mode, operand0, operand1)));
+                                 gen_rtx (HIGH, mode, operand1)));
+             if (TARGET_SHARED_LIBS
+                 && function_label_operand (operand1, mode))
+               {
+                 rtx temp = reload_in_progress ? scratch_reg
+                   : gen_reg_rtx (mode);
+                 if (!temp)
+                   abort ();
+                 emit_insn (gen_rtx (PARALLEL, VOIDmode,
+                                     gen_rtvec (2,
+                                                set,
+                                                gen_rtx (CLOBBER, VOIDmode,
+                                                         temp))));
+               }
+             else
+               emit_insn (set);
              return 1;
            }
          else
@@ -1223,7 +1205,7 @@ char *
 output_and (operands)
      rtx *operands;
 {
-  if (GET_CODE (operands[2]) == CONST_INT)
+  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
     {
       unsigned mask = INTVAL (operands[2]);
       int ls0, ls1, ms0, p, len;
@@ -1494,6 +1476,7 @@ output_function_prologue (file, size, leaf_function)
 {
   extern char call_used_regs[];
   extern int frame_pointer_needed;
+  extern int current_function_returns_struct;
   int i, offset;
 
   actual_fsize = compute_frame_size (size, leaf_function) + 32;
@@ -1537,6 +1520,12 @@ output_function_prologue (file, size, leaf_function)
        fprintf (file, "\taddil L'%d,30\n\tldo R'%d(1),30\n",
                 actual_fsize, actual_fsize);
     }
+  /* The hppa calling conventions say that that %r19, the pic offset 
+     register, is saved at sp - 32 (in this function's frame) */
+  if (flag_pic)
+    {
+      fprintf (file, "\tstw %%r19,-32(%%r30)\n");
+    }
   /* Instead of taking one argument, the counter label, as most normal
      mcounts do, _mcount appears to behave differently on the HPPA. It
      takes the return address of the caller, the address of this
@@ -1561,6 +1550,8 @@ output_function_prologue (file, size, leaf_function)
                                     : STACK_POINTER_REGNUM;
       offsetadj = frame_pointer_needed ? 0 : actual_fsize;
 
+      if (current_function_returns_struct)
+       print_stw (file, STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);
       for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
        if (regs_ever_live[i])
          {
@@ -1578,6 +1569,8 @@ output_function_prologue (file, size, leaf_function)
       for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
        if (regs_ever_live[i])
          print_ldw (file, i, arg_offset, basereg);
+      if (current_function_returns_struct)
+       print_ldw (file, STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);
     }
 
   /* Normal register save. */
@@ -2385,7 +2378,13 @@ secondary_reload_class (class, mode, in)
 {
   int regno = true_regnum (in);
 
-  if (class == SHIFT_REGS && (regno <= 0 || regno >= 32))
+  if ((TARGET_SHARED_LIBS && function_label_operand (in, mode))
+      || ((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
+         && ((mode == QImode || mode == HImode || mode == SImode
+              || mode == DImode) 
+             && (class == FP_REGS || class == SNAKE_FP_REGS
+                 || class == HI_SNAKE_FP_REGS)))
+      || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
     return GENERAL_REGS;
 
   return NO_REGS;
@@ -2448,3 +2447,31 @@ hppa_builtin_saveregs (arglist)
                                    current_function_internal_arg_pointer,
                                    offset, 0, 0, OPTAB_LIB_WIDEN));
 }
+
+extern struct obstack *saveable_obstack;
+
+/* In HPUX 8.0's shared library scheme, special relocations are needed
+   for function labels if they might be passed to a function 
+   in a shared library (because shared libraries don't live in code
+   space), and special magic is needed to construct their address. */
+
+void
+hppa_encode_label (sym)
+     rtx sym;
+{
+  char *str = XSTR (sym, 0);
+  int len = strlen (str);
+  char *newstr = obstack_alloc (saveable_obstack, len + 2) ;
+
+  strcpy (newstr + 1, str);
+  newstr[0] = '@';
+  XSTR (sym,0) = newstr;
+}
+  
+int
+function_label_operand  (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  return GET_CODE (op) == SYMBOL_REF && (XSTR (op, 0))[0] == '@';
+}
index bba8e6e..8ab5323 100644 (file)
@@ -106,6 +106,11 @@ extern int target_flags;
 
 #define TARGET_KERNEL (target_flags & 4)
 
+/* Generate code that will link against HPUX 8.0 shared libraries.
+   Older linkers and assemblers might not support this. */
+
+#define TARGET_SHARED_LIBS (target_flags & 8)
+
 /* Macro to define tables used to set the flags.
    This is a list in braces of pairs in braces,
    each pair being { "NAME", VALUE }
@@ -119,6 +124,8 @@ extern int target_flags;
    {"pa-risc-1-1", 1}, \
    {"no-bss", 2},      \
    {"kernel", 4},      \
+   {"shared-libs", 8}, \
+   {"no-shared-libs", -8},\
    { "", TARGET_DEFAULT}}
 
 #define TARGET_DEFAULT 0
@@ -233,7 +240,8 @@ extern int target_flags;
    Reg 3       = Unused
    Reg 4       = Frame Pointer (Gnu)
    Reg 5-18    = Preserved Registers
-   Reg 19-22   = Temporary Registers
+   Reg 19      = Linkage Table Register in HPUX 8.0 shared library scheme.
+   Reg 20-22   = Temporary Registers
    Reg 23-26   = Temporary/Parameter Registers
    Reg 27      = Global Data Pointer (hp)
    Reg 28      = Temporary/???/Return Value register
@@ -376,12 +384,20 @@ extern int target_flags;
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
    On the HP-PA, the cpu registers can hold any mode.  We
    force this to be an even register is it cannot hold the full mode.  */
+#if 0
 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
   ((REGNO) == 0 ? (MODE) == CCmode || (MODE) == CCFPmode               \
    : (REGNO) < 32 ? ((GET_MODE_SIZE (MODE) <= 4) ? 1 : ((REGNO) & 1) == 0)\
    : (REGNO) < 48 ? (GET_MODE_SIZE (MODE) >= 4)                                \
    : (GET_MODE_SIZE (MODE) > 4 ? ((REGNO) & 1) == 0                    \
       : GET_MODE_SIZE (MODE) == 4))
+#endif
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+  ((REGNO) == 0 ? (MODE) == CCmode || (MODE) == CCFPmode               \
+   : (REGNO) < 32 ? ((GET_MODE_SIZE (MODE) <= 4) ? 1 : ((REGNO) & 1) == 0)\
+   : (REGNO) < 48 ? (GET_MODE_SIZE (MODE) >= 4)                                \
+   : (GET_MODE_SIZE (MODE) > 4 ? ((REGNO) & 1) == 0                    \
+      : 1))
 
 /* Value is 1 if it is a good idea to tie two pseudo registers
    when one has mode MODE1 and one has mode MODE2.
@@ -431,7 +447,7 @@ extern int leaf_function;
 /* Register which holds offset table for position-independent
    data references.  */
 
-#define PIC_OFFSET_TABLE_REGNUM 18
+#define PIC_OFFSET_TABLE_REGNUM 19
 
 #define INITIALIZE_PIC initialize_pic ()
 #define FINALIZE_PIC finalize_pic ()
@@ -462,11 +478,14 @@ extern int leaf_function;
 
   /* The HP-PA has four kinds of registers: general regs, 1.0 fp regs,
      1.1 fp regs, and the high 1.1 fp regs, to which the operands of
-     fmpyadd and fmpysub are restricted. */
+     fmpyadd and fmpysub are restricted.
+
+     FP_OR_SNAKE_FP_REGS is for reload_{in,out}di only and isn't used
+     anywhere else.*/
 
 enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
   HI_SNAKE_FP_REGS, SNAKE_FP_REGS, GENERAL_OR_SNAKE_FP_REGS,
-  SHIFT_REGS, ALL_REGS, LIM_REG_CLASSES}; 
+  FP_OR_SNAKE_FP_REGS, SHIFT_REGS, ALL_REGS, LIM_REG_CLASSES}; 
 
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
@@ -475,7 +494,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
 #define REG_CLASS_NAMES \
   { "NO_REGS", "R1_REGS", "GENERAL_REGS", "FP_REGS", "GENERAL_OR_FP_REGS",\
     "HI_SNAKE_FP_REGS", "SNAKE_FP_REGS", "GENERAL_OR_SNAKE_FP_REGS",\
-    "SHIFT_REGS", "ALL_REGS"}
+    "FP_OR_SNAKE_FP_REGS","SHIFT_REGS", "ALL_REGS"}
 
 /* Define which registers fit in which classes.
    This is an initializer for a vector of HARD_REG_SET
@@ -491,6 +510,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
   {0, 0, 0xffff0000, 0xffff},  /* HI_SNAKE_FP_REGS */  \
   {0, 0xffff0000, ~0, 0xffff}, /* SNAKE_FP_REGS */     \
   {-2, 0xffff0000, ~0, 0xffff},        /* GENERAL_OR_SNAKE_FP_REGS */\
+  {0, ~0, ~0, 0xffff},         /* FP_OR_SNAKE_FP_REGS */\
   {0, 0, 0, 0x10000},          /* SHIFT_REGS */        \
   {-2, ~0, ~0, 0x1ffff}}       /* ALL_REGS */
 
@@ -519,7 +539,8 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FP_REGS, GENERAL_OR_FP_REGS,
    ((C) == 'x' ? (TARGET_SNAKE ? SNAKE_FP_REGS : NO_REGS) :    \
     ((C) == 'y' ? (TARGET_SNAKE ? HI_SNAKE_FP_REGS : NO_REGS) :        \
      ((C) == 'q' ? SHIFT_REGS :                                        \
-      ((C) == 'a' ? R1_REGS : NO_REGS)))))
+      ((C) == 'a' ? R1_REGS :                                  \
+       ((C) == 'z' ? FP_OR_SNAKE_FP_REGS : NO_REGS))))))
 
 /* The letters I, J, K, L and M in a register constraint string
    can be used to stand for particular ranges of immediate operands.
@@ -794,6 +815,13 @@ extern enum cmp_type hppa_branch_type;
   do { fprintf (FILE, ",ARGW%d=FU", (ARG0));           \
        fprintf (FILE, ",ARGW%d=FR", (ARG1));} while (0)
 #endif
+
+#ifdef BUGGY_GAS
+#define EXPORT_PARMS(FILE) fputs (",PRIV_LEV=3", FILE)
+#else
+#define EXPORT_PARMS(FILE) fputs (",ENTRY,PRIV_LEV=3", FILE)
+#endif
+
 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
     do { tree fntype = DECL_RESULT (DECL);                             \
         tree tree_type = TREE_TYPE (DECL);                             \
@@ -802,7 +830,7 @@ extern enum cmp_type hppa_branch_type;
         if (TREE_PUBLIC (DECL))                                        \
           { extern int current_function_varargs;                       \
             fputs ("\t.EXPORT ", FILE); assemble_name (FILE, NAME);    \
-            fputs (",PRIV_LEV=3", FILE);                               \
+            EXPORT_PARMS (FILE);                                       \
             for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4;   \
                  parm = TREE_CHAIN (parm))                             \
               {                                                        \
@@ -984,8 +1012,8 @@ extern union tree_node *current_function_decl;
 #define REGNO_OK_FOR_BASE_P(REGNO)  \
   ((REGNO) && ((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32))
 #define REGNO_OK_FOR_FP_P(REGNO) \
-  (((REGNO) >= 32 || reg_renumber[REGNO] >= 32)\
-   && ((REGNO) <= 111 || reg_renumber[REGNO] <= 111))
+  (((REGNO) >= 32 && (REGNO) <= 111)\
+   || (reg_renumber[REGNO] >= 32 && reg_renumber[REGNO] <= 111))
 
 /* Now macros that check whether X is a register and also,
    strictly, whether it is in a specified class.
@@ -1200,7 +1228,7 @@ extern union tree_node *current_function_decl;
   if (memory_address_p (MODE, X))                              \
     goto WIN;                                                  \
   if (flag_pic) (X) = legitimize_pic_address (X, MODE, gen_reg_rtx (Pmode));\
-  else if ((GET_CODE (X) == SYMBOL_REF && read_only_operand (X))\
+  else if ((GET_CODE (X) == SYMBOL_REF & read_only_operand (X))        \
            || GET_CODE (X) == LABEL_REF)                       \
     (X) = gen_rtx (LO_SUM, Pmode,                              \
                   copy_to_mode_reg (Pmode, gen_rtx (HIGH, Pmode, X)), X); \
@@ -1246,7 +1274,10 @@ extern union tree_node *current_function_decl;
 do                                                                     \
   {                                                                    \
     if (TREE_CODE (DECL) == FUNCTION_DECL)                             \
-      SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;                 \
+      {                                                                        \
+       hppa_encode_label (XEXP (DECL_RTL (DECL), 0));                  \
+       SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;                \
+      }                                                                        \
     else                                                               \
       {                                                                        \
        rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd'            \
@@ -1376,7 +1407,7 @@ while (0)
   case MOD:                                            \
   case UMOD:                                           \
     return COSTS_N_INSNS (60);                         \
-  case PLUS: /* this includes shNadd insns */          \
+   case PLUS: /* this includes shNadd insns */         \
     return COSTS_N_INSNS (1) + 2;
 
 /* Conditional branches with empty delay slots have a length of two.  */
@@ -1518,7 +1549,7 @@ bss_section ()                                                            \
    `assemble_name' uses this.  */
 
 #define ASM_OUTPUT_LABELREF(FILE,NAME) \
-  fprintf (FILE, "%s", NAME)
+  fprintf ((FILE), "%s", (NAME) + ((NAME)[0] == '@' ? 1 : 0))
 
 /* This is how to output an internal numbered label where
    PREFIX is the class of label and NUM is the number within the class.  */
@@ -1578,6 +1609,7 @@ bss_section ()                                                            \
 #define ASM_OUTPUT_ASCII(FILE, P, SIZE)  \
   output_ascii ((FILE), (P), (SIZE))
 
+#if 0
 #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
   fprintf (FILE, "\tstws,mb %s,4(0,30)\n", reg_names[REGNO])
 
@@ -1586,7 +1618,10 @@ bss_section ()                                                           \
 
 #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
   fprintf (FILE, "\tldws,ma -4(0,30),%s\n", reg_names[REGNO])
+#endif
 
+#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)
+#define ASM_OUTPUT_REG_POP(FILE,REGNO) 
 /* This is how to output an element of a case-vector that is absolute.
    Note that this method makes filling these branch delay slots
    virtually impossible.  */
@@ -1732,3 +1767,4 @@ extern void output_global_address ();
 extern struct rtx_def *legitimize_pic_address ();
 extern struct rtx_def *gen_cmp_fp ();
 extern struct rtx_def *gen_scond_fp ();
+extern void hppa_encode_label ();
index 1832f4c..7cdbcf1 100644 (file)
 
 (define_expand "seq"
   [(set (match_operand:SI 0 "register_operand" "")
-       (eq:CC (match_dup 1)
+       (eq:SI (match_dup 1)
               (match_dup 2)))]
   ""
   "
 
 (define_expand "sne"
   [(set (match_operand:SI 0 "register_operand" "")
-       (ne:CC (match_dup 1)
+       (ne:SI (match_dup 1)
               (match_dup 2)))]
   ""
   "
 
 (define_expand "slt"
   [(set (match_operand:SI 0 "register_operand" "")
-       (lt:CC (match_dup 1)
+       (lt:SI (match_dup 1)
               (match_dup 2)))]
   ""
   "
 
 (define_expand "sgt"
   [(set (match_operand:SI 0 "register_operand" "")
-       (gt:CC (match_dup 1)
+       (gt:SI (match_dup 1)
               (match_dup 2)))]
   ""
   "
 
 (define_expand "sle"
   [(set (match_operand:SI 0 "register_operand" "")
-       (le:CC (match_dup 1)
+       (le:SI (match_dup 1)
               (match_dup 2)))]
   ""
   "
 
 (define_expand "sge"
   [(set (match_operand:SI 0 "register_operand" "")
-       (ge:CC (match_dup 1)
+       (ge:SI (match_dup 1)
               (match_dup 2)))]
   ""
   "
 
 (define_expand "sltu"
   [(set (match_operand:SI 0 "register_operand" "")
-       (ltu:CC (match_dup 1)
+       (ltu:SI (match_dup 1)
                (match_dup 2)))]
   ""
   "
 
 (define_expand "sgtu"
   [(set (match_operand:SI 0 "register_operand" "")
-       (gtu:CC (match_dup 1)
+       (gtu:SI (match_dup 1)
                (match_dup 2)))]
   ""
   "
 
 (define_expand "sleu"
   [(set (match_operand:SI 0 "register_operand" "")
-       (leu:CC (match_dup 1)
+       (leu:SI (match_dup 1)
                (match_dup 2)))]
   ""
   "
 
 (define_expand "sgeu"
   [(set (match_operand:SI 0 "register_operand" "")
-       (geu:CC (match_dup 1)
+       (geu:SI (match_dup 1)
                (match_dup 2)))]
   ""
   "
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r,r")
-       (match_operator:CC 3 "comparison_operator"
+       (match_operator:SI 3 "comparison_operator"
                           [(match_operand:SI 1 "register_operand" "r,r")
                            (match_operand:SI 2  "arith11_operand" "r,I")]))]
   ""
   ""
   "
 {
-  if (emit_move_sequence (operands, SImode))
+  if (emit_move_sequence (operands, SImode, 0))
     DONE;
 }")
 
+;; Reloading an SImode or DImode value requires a scratch register if
+;; going in to or out of float point registers.
+
+(define_expand "reload_insi"
+  [(set (match_operand:SI 0 "register_operand" "=z")
+       (match_operand:SI 1 "general_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
+  ""
+  "
+{
+  if (emit_move_sequence (operands, SImode, operands[2]))
+    DONE;
+
+  /* We don't want the clobber emitted, so handle this ourselves.  */
+  emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
+  DONE;
+}")
+
+(define_expand "reload_outsi"
+  [(set (match_operand:SI 0 "general_operand" "")
+       (match_operand:SI 1  "register_operand""z"))
+   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
+  ""
+  "
+{
+  if (emit_move_sequence (operands, SImode, operands[2]))
+    DONE;
+
+  /* We don't want the clobber emitted, so handle this ourselves.  */
+  emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
+  DONE;
+}")
+
 ;; Moves to and from the shift register.
 
 (define_insn ""
   "mfctl 11,%0"
   [(set_attr "type" "move")])
 
+;;; Experimental
+
+(define_insn ""
+  [(set (match_operand:SI 0 "fp_reg_operand" "=fx")
+       (match_operand:SI 1 "short_memory_operand" "T"))]
+  ""
+  "fldws%F1 %1,%0"
+  [(set_attr "type" "fpload")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "short_memory_operand" "=T")
+       (match_operand:SI 1 "fp_reg_operand" "fx"))]
+  ""
+  "fstws%F0 %1,%0"
+  [(set_attr "type" "fpstore")
+   (set_attr "length" "1")])
+
+;;; pic symbol refrences
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
+                        (match_operand:SI 2 "symbolic_operand" ""))))]
+  "flag_pic && operands[1] == pic_offset_table_rtx"
+  "ldw T'%2(%1),%0"
+  [(set_attr "type" "load")
+   (set_attr "length" "1")])
+
 (define_insn ""
   [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
-                         "=r,r,Q,!r,!*f*x,!*f*x")
-       (match_operand:SI 1 "move_operand" "rM,Q,rM,!*f*x*y,!r,!*f*x"))]
+                         "=r,r,Q,!r,!fx,!fx")
+       (match_operand:SI 1 "move_operand" "rM,Q,rM,!fxy,!r,!fx"))]
   ""
   "@
    copy %r1,%0
   xoperands[2] = label_rtx;
   output_asm_insn (\"bl .+8,%0\;addil L'%1-%2,%0\", xoperands);
   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label_rtx));
-  output_asm_insn (\"ldo R'%1(1),%0\", xoperands);
+  output_asm_insn (\"ldo R'%1-%2(1),%0\", xoperands);
   return \"\";
   }
 "
 
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
+       (high:SI (match_operand:SI 1 "function_label_operand" "")))]
+  "TARGET_SHARED_LIBS"
+  "ldil LP'%G1,%0"
+  [(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
        (high:SI (match_operand 1 "" "")))]
   "check_pic (1)"
   "ldil L'%G1,%0"
 (define_insn ""
   [(set (match_operand:SI 0 "register_operand" "=r")
        (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+                  (match_operand:SI 2 "function_label_operand" "")))
+   (clobber (match_operand:SI 3 "register_operand" "=r"))]
+  "TARGET_SHARED_LIBS"
+  "ldo RP'%G2(%1),%0\;extru,= %0,31,1,%3\;ldw -4(%%r27),%3\;add %0,%3,%0"
+  [(set_attr "type" "multi")
+   (set_attr "length" "4")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
                   (match_operand:SI 2 "immediate_operand" "i")))]
   ""
   "ldo R'%G2(%1),%0"
   ;; is not an "arith_operand".
   [(set_attr "length" "1")])
 
-;;; Experimental
-
-(define_insn ""
-  [(set (match_operand:SI 0 "fp_reg_operand" "=*f*x")
-       (match_operand:SI 1 "short_memory_operand" "T"))]
-  ""
-  "fldws%F1 %1,%0"
-  [(set_attr "type" "fpload")
-   (set_attr "length" "1")])
-
-(define_insn ""
-  [(set (match_operand:SI 0 "short_memory_operand" "=T")
-       (match_operand:SI 1 "fp_reg_operand" "*f*x"))]
-  ""
-  "fstws%F0 %1,%0"
-  [(set_attr "type" "fpstore")
-   (set_attr "length" "1")])
-
 (define_expand "movhi"
   [(set (match_operand:HI 0 "general_operand" "")
        (match_operand:HI 1 "general_operand" ""))]
   ""
   "
 {
-  if (emit_move_sequence (operands, HImode))
+  if (emit_move_sequence (operands, HImode, 0))
     DONE;
 }")
 
 (define_insn ""
-  [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
-       (match_operand:HI 1 "move_operand" "rM,Q,rM"))]
+  [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q,!r,!*fx,!*fx")
+       (match_operand:HI 1 "move_operand" "rM,Q,rM,*fx,r,!*fx"))]
   ""
   "@
    copy %r1,%0
    ldh%M1 %1,%0
-   sth%M0 %r1,%0"
-  [(set_attr "type" "move,load,store")
-   (set_attr "length" "1,1,1")])
+   sth%M0 %r1,%0
+   fstws %1,-16(30)\;ldw -16(30),%0
+   stw %1,-16(30)\;fldws -16(30),%0
+   fcpy,sgl %1,%0"
+  [(set_attr "type" "move,load,store,move,move,fpalu")
+   (set_attr "length" "1,1,1,2,2,1")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
   ""
   "
 {
-  if (emit_move_sequence (operands, QImode))
+  if (emit_move_sequence (operands, QImode, 0))
     DONE;
 }")
 
 (define_insn ""
-  [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
-       (match_operand:QI 1 "move_operand" "rM,Q,rM"))]
+  [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,Q,!r,!*fx,!*fx")
+       (match_operand:QI 1 "move_operand" "rM,Q,rM,*fx,r,*fx"))]
   ""
   "@
    copy %r1,%0
    ldb%M1 %1,%0
-   stb%M0 %r1,%0"
-  [(set_attr "type" "move,load,store")
-   (set_attr "length" "1,1,1")])
+   stb%M0 %r1,%0
+   fstws %1,-16(30)\;ldw -16(30),%0
+   stw %1,-16(30)\;fldws -16(30),%0
+   fcpy,sgl %1,%0"
+  [(set_attr "type" "move,load,store,move,move,fpalu")
+   (set_attr "length" "1,1,1,2,2,1")])
 
 (define_insn ""
   [(set (match_operand:QI 0 "register_operand" "=r")
   "ldo R'%G2(%1),%0"
   [(set_attr "length" "1")])
 
+;; Sneaky ways of using index modes
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+                                 (const_int 4))
+                        (match_operand:SI 2 "register_operand" "r"))))]
+  ""
+  "ldwx,s %1(0,%2),%0"
+  [(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (mem:SI (match_operand:SI 1 "register_operand" "+r")))
+   (set (match_dup 1)
+       (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
+                         (const_int 4))
+                (match_dup 1)))]
+  ""
+  "ldwx,sm %2(0,%1),%0"
+  [(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (mem:SI (match_operand:SI 1 "register_operand" "+r")))
+   (set (match_dup 1)
+       (plus:SI (match_dup 1)
+                (match_operand:SI 2 "register_operand" "r")))]
+  ""
+  "ldwx,m %2(0,%1),%0"
+  [(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:HI 0 "register_operand" "=r")
+       (mem:HI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
+                                 (const_int 2))
+                        (match_operand:SI 1 "register_operand" "r"))))]
+  ""
+  "ldhx,s %2(0,%1),%0"
+  [(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:HI 0 "register_operand" "=r")
+       (mem:HI (match_operand:SI 1 "register_operand" "+r")))
+   (set (match_dup 1)
+       (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
+                         (const_int 2))
+                (match_dup 1)))]
+  ""
+  "ldhx,sm %2(0,%1),%0"
+  [(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:HI 0 "register_operand" "=r")
+       (mem:HI (match_operand:SI 1 "register_operand" "+r")))
+   (set (match_dup 1)
+       (plus:SI (match_dup 1)
+                (match_operand:SI 2 "register_operand" "r")))]
+  ""
+  "ldhx,m %2(0,%1),%0"
+  [(set_attr "type" "move")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:QI 0 "register_operand" "=r")
+       (mem:QI (match_operand:SI 1 "register_operand" "+r")))
+   (set (match_dup 1)
+       (plus:SI (match_dup 1)
+                (match_operand:SI 2 "register_operand" "r")))]
+  ""
+  "ldbx,m %2(0,%1),%0")
+
 ;; The definition of this insn does not really explain what it does,
 ;; but it should suffice
 ;; that anything generated as this insn will be recognized as one
   ""
   "
 {
-  if (emit_move_sequence (operands, DFmode))
+  if (emit_move_sequence (operands, DFmode, 0))
     DONE;
 }")
 
 (define_insn ""
   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
-                         "=fx,r,Q,Q,fx,&r,?fx,?r")
+                         "=fx,*r,Q,?Q,fx,*&r,?fx,?r")
        (match_operand:DF 1 "reg_or_nonsymb_mem_operand"
-                         "fx,r,fx,r,Q,Q,r,fx"))]
-  ""
+                         "fx,*r,fx,*r,Q,Q,*r,fx"))]
+  "register_operand (operands[0], DFmode)
+   || register_operand (operands[1], DFmode)"
   "*
 {
   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
   ""
   "
 {
-  if (emit_move_sequence (operands, DImode))
+  if (emit_move_sequence (operands, DImode, 0))
     DONE;
 }")
 
+(define_expand "reload_indi"
+  [(set (match_operand:DI 0 "register_operand" "=z")
+       (match_operand:DI 1 "general_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
+  ""
+  "
+{
+  if (emit_move_sequence (operands, DImode, operands[2]))
+    DONE;
+
+  /* We don't want the clobber emitted, so handle this ourselves.  */
+  emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
+  DONE;
+}")
+
+(define_expand "reload_outdi"
+  [(set (match_operand:DI 0 "general_operand" "")
+       (match_operand:DI 1 "register_operand" "z"))
+   (clobber (match_operand:SI 2 "register_operand" "=&r"))]
+  ""
+  "
+{
+  if (emit_move_sequence (operands, DImode, operands[2]))
+    DONE;
+
+  /* We don't want the clobber emitted, so handle this ourselves.  */
+  emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
+  DONE;
+}")
+
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
        (high:DI (match_operand 1 "" "")))]
   [(set_attr "type" "move")
    (set_attr "length" "2")])
 
+;;; Experimental
+
+(define_insn ""
+  [(set (match_operand:DI 0 "fp_reg_operand" "=fx")
+       (match_operand:DI 1 "short_memory_operand" "T"))]
+  ""
+  "fldds%F1 %1,%0"
+  [(set_attr "type" "fpload")
+   (set_attr "length" "1")])
+
+(define_insn ""
+  [(set (match_operand:DI 0 "short_memory_operand" "=T")
+       (match_operand:DI 1 "fp_reg_operand" "fx"))]
+  ""
+  "fstds%F0 %1,%0"
+  [(set_attr "type" "fpstore")
+   (set_attr "length" "1")])
+
 (define_insn ""
   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
-                         "=r,Q,&r,&r,*f*x,*f*x,*f*x,r,Q")
+                         "=r,Q,&r,&r,fx,fx,r")
        (match_operand:DI 1 "general_operand"
-                         "r,r,Q,i,r,*f*x,Q,*f*x,*f*x"))]
+                         "r,r,Q,i,r,fx,fx"))]
   ""
   "*
 {
     return output_fp_move_double (operands);
   return output_move_double (operands);
 }"
-  [(set_attr "type" "move,store,load,misc,multi,fpalu,fpload,multi,fpstore")
-   (set_attr "length" "2,3,3,3,3,2,3,3,3")])
+  [(set_attr "type" "move,store,load,misc,multi,fpalu,multi")
+   (set_attr "length" "2,3,3,3,3,2,3")])
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r,r")
   ""
   "
 {
-  if (emit_move_sequence (operands, SFmode))
+  if (emit_move_sequence (operands, SFmode, 0))
     DONE;
 }")
 
 ;; The mulsi3 insns set up registers for the millicode call.
 
 (define_expand "mulsi3"
-  [(set (reg:SI 26) (match_operand:SI 1 "srcsi_operand" ""))
-   (set (reg:SI 25) (match_operand:SI 2 "srcsi_operand" ""))
+  [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
+   (set (reg:SI 25) (match_operand:SI 2 "arith32_operand" ""))
    (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
              (clobber (match_scratch:SI 3 ""))
              (clobber (reg:SI 26))
              (clobber (reg:SI 31))])
    (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
   ""
-  "")
+  "
+{
+  if (TARGET_SNAKE && !(CONSTANT_P (operands[1]) || CONSTANT_P (operands[2])))
+    {
+      rtx scratch = gen_reg_rtx (DImode);
+      emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
+      emit_insn (gen_rtx (SET, VOIDmode,
+                         operands[0],
+                         gen_rtx (SUBREG, SImode, scratch, 1)));
+      DONE;
+    }
+}")
+
+(define_insn "umulsidi3"
+  [(set (match_operand:DI 0 "register_operand" "=x")
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "x"))
+                (zero_extend:DI (match_operand:SI 2 "register_operand" "x"))))]
+  "TARGET_SNAKE"
+  "xmpyu %1,%2,%0"
+  [(set_attr "type" "fpmul")])
 
 (define_insn ""
   [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
index 4f168a6..f6bdea8 100644 (file)
@@ -23,6 +23,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include <magic.h>
 #if defined(SHL_MAGIC)
 #define hpux8 1
+#define HAVE_VPRINTF
 #endif
 
 #define USG
index eb6c600..c01850a 100644 (file)
@@ -1,4 +1,3 @@
-#if __GNUC__ > 1
 
 /* Define __gnuc_va_list. */
 
@@ -11,12 +10,23 @@ typedef double *__gnuc_va_list;
 /* If this is for internal libc use, don't define anything but
    __gnuc_va_list.  */
 #if defined (_STDARG_H) || defined (_VARARGS_H)
+#if __GNUC__ > 1
+#define __va_ellipsis ...
+#define __gnuc_va_start(AP) ((AP) = (va_list)__builtin_saveregs())
+#else
+#define va_alist __va_a__, __va_b__, __va_c__, __va_d__
+#define __va_ellipsis 
+#define __gnuc_va_start(AP)\
+  (AP) = (double *) &__va_a__, &__va_b__, &__va_c__, &__va_d__, \
+  (AP) = (double *)((char *)(AP) + 4)
+#endif /* __GNUC__ > 1 */
+
 #ifdef _STDARG_H
-#define va_start(AP,LASTARG) ((AP) = (va_list)__builtin_saveregs())
+#define va_start(AP,LASTARG) __gnuc_va_start (AP)
 #else
 /* The ... causes current_function_varargs to be set in cc1.  */
-#define va_dcl long va_alist; ...
-#define va_start(AP) ((AP) = (va_list)__builtin_saveregs())
+#define va_dcl long va_alist; __va_ellipsis
+#define va_start(AP) __gnuc_va_start (AP)
 #endif
 
 #define va_arg(AP,TYPE)                                                \
@@ -31,8 +41,3 @@ typedef double *__gnuc_va_list;
 #define va_end(AP)
 
 #endif /* defined (_STDARG_H) || defined (_VARARGS_H) */
-
-#else /* not __GNUC__ > 1 */
-#include "/usr/local/lib/gcc-include/va-hp9k8.h"
-#define _VA_LIST_
-#endif