2a4bfeed8e
From-SVN: r513
279 lines
6.2 KiB
C
279 lines
6.2 KiB
C
/* 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 ();
|
||
}
|
||
}
|