Initial revision
From-SVN: r350
This commit is contained in:
parent
0aaa6af8c2
commit
9c21a7e7ae
296
gcc/config/vax/vax.c
Normal file
296
gcc/config/vax/vax.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 ();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user