Initial revision
authorRichard Stallman <rms@gnu.org>
Fri, 21 Feb 1992 06:17:54 +0000 (06:17 +0000)
committerRichard Stallman <rms@gnu.org>
Fri, 21 Feb 1992 06:17:54 +0000 (06:17 +0000)
From-SVN: r350

gcc/config/vax/vax.c [new file with mode: 0644]

diff --git a/gcc/config/vax/vax.c b/gcc/config/vax/vax.c
new file mode 100644 (file)
index 0000000..68743cd
--- /dev/null
@@ -0,0 +1,296 @@
+/* Subroutines for insn-output.c for Vax.
+   Copyright (C) 1987 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <stdio.h>
+#include "config.h"
+#include "rtl.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "real.h"
+#include "insn-config.h"
+#include "conditions.h"
+#include "insn-flags.h"
+#include "output.h"
+#include "insn-attr.h"
+
+/* Return 1 if the operand is a REG, a SUBREG, or a MEM that is does not
+   have an index.  This is used when we are using an operand in a different
+   mode than the hardware expects.  See jlbc/jlbs.
+
+   This is nonimmedate_operand with a restriction on the type of MEM.  */
+
+int
+reg_or_nxmem_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (! nonimmediate_operand (op, mode))
+    return 0;
+
+  if (GET_CODE (op) != MEM)
+    return 1;
+
+  GO_IF_NONINDEXED_ADDRESS (XEXP (op, 0), nonidx);
+
+  return 0;
+
+ nonidx:
+  return 1;
+}
+
+void
+split_quadword_operands (operands, low, n)
+     rtx *operands, *low;
+     int n;
+{
+  int i;
+  /* Split operands.  */
+
+  low[0] = low[1] = low[2] = 0;
+  for (i = 0; i < 3; i++)
+    {
+      if (low[i])
+       /* it's already been figured out */;
+      else if (GET_CODE (operands[i]) == MEM
+              && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
+       {
+         rtx addr = XEXP (operands[i], 0);
+         operands[i] = low[i] = gen_rtx (MEM, SImode, addr);
+         if (which_alternative == 0 && i == 0)
+           {
+             addr = XEXP (operands[i], 0);
+             operands[i+1] = low[i+1] = gen_rtx (MEM, SImode, addr);
+           }
+       }
+      else
+       {
+         low[i] = operand_subword (operands[i], 0, 0, DImode);
+         operands[i] = operand_subword (operands[i], 1, 0, DImode);
+       }
+    }
+}
+\f
+print_operand_address (file, addr)
+     FILE *file;
+     register rtx addr;
+{
+  register rtx reg1, reg2, breg, ireg;
+  rtx offset;
+
+ retry:
+  switch (GET_CODE (addr))
+    {
+    case MEM:
+      fprintf (file, "*");
+      addr = XEXP (addr, 0);
+      goto retry;
+
+    case REG:
+      fprintf (file, "(%s)", reg_names[REGNO (addr)]);
+      break;
+
+    case PRE_DEC:
+      fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
+      break;
+
+    case POST_INC:
+      fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
+      break;
+
+    case PLUS:
+      /* There can be either two or three things added here.  One must be a
+        REG.  One can be either a REG or a MULT of a REG and an appropriate
+        constant, and the third can only be a constant or a MEM.
+
+        We get these two or three things and put the constant or MEM in
+        OFFSET, the MULT or REG in IREG, and the REG in BREG.  If we have
+        a register and can't tell yet if it is a base or index register,
+        put it into REG1.  */
+
+      reg1 = 0; ireg = 0; breg = 0; offset = 0;
+
+      if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
+         || GET_CODE (XEXP (addr, 0)) == MEM)
+       {
+         offset = XEXP (addr, 0);
+         addr = XEXP (addr, 1);
+       }
+      else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
+              || GET_CODE (XEXP (addr, 1)) == MEM)
+       {
+         offset = XEXP (addr, 1);
+         addr = XEXP (addr, 0);
+       }
+      else if (GET_CODE (XEXP (addr, 1)) == MULT)
+       {
+         ireg = XEXP (addr, 1);
+         addr = XEXP (addr, 0);
+       }
+      else if (GET_CODE (XEXP (addr, 0)) == MULT)
+       {
+         ireg = XEXP (addr, 0);
+         addr = XEXP (addr, 1);
+       }
+      else if (GET_CODE (XEXP (addr, 1)) == REG)
+       {
+         reg1 = XEXP (addr, 1);
+         addr = XEXP (addr, 0);
+       }
+      else
+       abort ();
+
+      if (GET_CODE (addr) == REG)
+       {
+         if (reg1)
+           ireg = addr;
+         else
+           reg1 = addr;
+       }
+      else if (GET_CODE (addr) == MULT)
+       ireg = addr;
+      else if (GET_CODE (addr) == PLUS)
+       {
+         if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
+             || GET_CODE (XEXP (addr, 0)) == MEM)
+           {
+             if (offset)
+               {
+                 if (GET_CODE (offset) == CONST_INT)
+                   offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
+                 else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
+                   offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
+                 else
+                   abort ();
+               }
+             offset = XEXP (addr, 0);
+           }
+         else if (GET_CODE (XEXP (addr, 0)) == REG)
+           {
+             if (reg1)
+               ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
+             else
+               reg1 = XEXP (addr, 0);
+           }
+         else if (GET_CODE (XEXP (addr, 0)) == MULT)
+           {
+             if (ireg)
+               abort ();
+             ireg = XEXP (addr, 0);
+           }
+         else
+           abort ();
+
+         if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
+             || GET_CODE (XEXP (addr, 1)) == MEM)
+           {
+             if (offset)
+               {
+                 if (GET_CODE (offset) == CONST_INT)
+                   offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
+                 else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
+                   offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
+                 else
+                   abort ();
+               }
+             offset = XEXP (addr, 1);
+           }
+         else if (GET_CODE (XEXP (addr, 1)) == REG)
+           {
+             if (reg1)
+               ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
+             else
+               reg1 = XEXP (addr, 1);
+           }
+         else if (GET_CODE (XEXP (addr, 1)) == MULT)
+           {
+             if (ireg)
+               abort ();
+             ireg = XEXP (addr, 1);
+           }
+         else
+           abort ();
+       }
+      else
+       abort ();
+
+      /* If REG1 is non-zero, figure out if it is a base or index register.  */
+      if (reg1)
+       {
+         if (breg != 0 || (offset && GET_CODE (offset) == MEM))
+           {
+             if (ireg)
+               abort ();
+             ireg = reg1;
+           }
+         else
+           breg = reg1;
+       }
+
+      if (offset != 0)
+       output_address (offset);
+
+      if (breg != 0)
+       fprintf (file, "(%s)", reg_names[REGNO (breg)]);
+
+      if (ireg != 0)
+       {
+         if (GET_CODE (ireg) == MULT)
+           ireg = XEXP (ireg, 0);
+         if (GET_CODE (ireg) != REG)
+           abort ();
+         fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
+       }
+      break;
+
+    default:
+      output_addr_const (file, addr);
+    }
+}
+\f
+char *
+rev_cond_name (op)
+     rtx op;
+{
+  switch (GET_CODE (op))
+    {
+    case EQ:
+      return "neq";
+    case NE:
+      return "eql";
+    case LT:
+      return "geq";
+    case LE:
+      return "gtr";
+    case GT:
+      return "leq";
+    case GE:
+      return "lss";
+    case LTU:
+      return "gequ";
+    case LEU:
+      return "gtru";
+    case GTU:
+      return "lequ";
+    case GEU:
+      return "lssu";
+
+    default:
+      abort ();
+    }
+}