8sa1-gcc/gcc/config/vax/vax.c
Richard Stallman 2a4bfeed8e *** empty log message ***
From-SVN: r513
1992-03-17 21:16:42 +00:00

279 lines
6.2 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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"
/* This is like nonimmediate_operand with a restriction on the type of MEM. */
void
split_quadword_operands (operands, low, n)
rtx *operands, *low;
{
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);
}
}
}
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 if (GET_CODE (XEXP (addr, 0)) == REG)
{
reg1 = XEXP (addr, 0);
addr = XEXP (addr, 1);
}
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);
}
}
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 ();
}
}