--- /dev/null
+/* 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 ();
+ }
+}