home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 7
/
FreshFishVol7.bin
/
bbs
/
gnu
/
gcc-2.3.3-src.lha
/
GNU
/
src
/
amiga
/
gcc-2.3.3
/
config
/
gmicro.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-06
|
21KB
|
984 lines
/* Subroutines for insn-output.c for the Gmicro.
Ported by Masanobu Yuhara, Fujitsu Laboratories LTD.
(yuhara@flab.fujitsu.co.jp)
Copyright (C) 1990, 1991 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.
Among other things, the copyright
notice and this notice must be preserved on all copies.
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"
extern char *rtx_name[];
mypr (s, a1, a2, a3, a4, a5)
char *s;
int a1, a2, a3, a4, a5;
{
fprintf (stderr, s, a1, a2, a3, a4, a5);
}
myprcode (i)
int i;
{
if (i < 0 || i > 90)
fprintf (stderr, "code = %d\n", i);
else
fprintf (stderr, "code = %s\n", rtx_name[i]);
}
myabort (i)
int i;
{
fprintf (stderr, "myabort");
myprcode (i);
}
/* This is how to output an ascii string. */
/* See ASM_OUTPUT_ASCII in gmicro.h. */
output_ascii (file, p, size)
FILE *file;
char *p;
int size;
{
int i;
int in_quote = 0;
register int c;
fprintf (file, "\t.sdata ");
for (i = 0; i < size; i++)
{
c = p[i];
if (c >= ' ' && c < 0x7f)
{
if (!in_quote)
{
putc ('"', file);
in_quote = 1;
}
putc (c, file);
}
else
{
if (in_quote)
{
putc ('"', file);
in_quote = 0;
}
fprintf (file, "<%d>", c);
}
}
if (in_quote)
putc ('"', file);
putc ('\n', file);
}
/* call this when GET_CODE (index) is MULT. */
print_scaled_index (file, index)
FILE *file;
register rtx index;
{
register rtx ireg;
int scale;
if (GET_CODE (XEXP (index, 0)) == REG)
{
ireg = XEXP (index, 0);
scale = INTVAL (XEXP (index, 1));
}
else
{
ireg = XEXP (index, 1);
scale = INTVAL (XEXP (index, 0));
}
if (scale == 1)
fprintf (file, "%s", reg_names[REGNO (ireg)]);
else
fprintf (file, "%s*%d", reg_names[REGNO (ireg)], scale);
}
print_operand_address (file, addr)
FILE *file;
register rtx addr;
{
register rtx xtmp0, xtmp1, breg, ixreg;
int scale;
int needcomma = 0;
rtx offset;
fprintf (file, "@");
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 MULT:
print_scaled_index (file, 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:
xtmp0 = XEXP (addr, 0);
xtmp1 = XEXP (addr, 1);
ixreg = 0; breg = 0;
offset = 0;
if (CONSTANT_ADDRESS_P (xtmp0))
{
offset = xtmp0;
breg = xtmp1;
}
else if (CONSTANT_ADDRESS_P (xtmp1))
{
offset = xtmp1;
breg = xtmp0;
}
else
{
goto NOT_DISP;
}
if (REG_CODE_BASE_P (breg))
goto PRINT_MEM;
if (GET_CODE (breg) == MULT)
{
if (REG_CODE_INDEX_P (XEXP (breg, 0)))
{
ixreg = XEXP (breg, 0);
scale = INTVAL (XEXP (breg, 1));
breg = 0;
}
else
{
ixreg = XEXP (breg, 1);
scale = INTVAL (XEXP (breg, 0));
breg = 0;
}
goto PRINT_MEM;
}
/* GET_CODE (breg) must be PLUS here. */
xtmp0 = XEXP (breg, 0);
xtmp1 = XEXP (breg, 1);
if (REG_CODE_BASE_P (xtmp0))
{
breg = xtmp0;
xtmp0 = xtmp1;
}
else
{
breg = xtmp1;
/* xtmp0 = xtmp0; */
}
if (GET_CODE (xtmp0) == MULT)
{
if (REG_CODE_INDEX_P (XEXP (xtmp0, 0)))
{
ixreg = XEXP (xtmp0, 0);
scale = INTVAL (XEXP (xtmp0, 1));
}
else
{
ixreg = XEXP (xtmp0, 1);
scale = INTVAL (XEXP (xtmp0, 0));
}
}
else
{
ixreg = xtmp0;
scale = 1;
}
goto PRINT_MEM;
NOT_DISP:
if (REG_CODE_BASE_P (xtmp0))
{
breg = xtmp0;
xtmp0 = xtmp1;
}
else if (REG_CODE_BASE_P (xtmp1))
{
breg = xtmp1;
/* xtmp0 = xtmp0; */
}
else
goto NOT_BASE;
if (REG_CODE_INDEX_P (xtmp0))
{
ixreg = xtmp0;
scale = 1;
goto PRINT_MEM;
}
else if (CONSTANT_ADDRESS_P (xtmp0))
{
offset = xtmp0;
goto PRINT_MEM;
}
else if (GET_CODE (xtmp0) == MULT)
{
if (REG_CODE_INDEX_P (XEXP (xtmp0, 0)))
{
ixreg = XEXP (xtmp0, 0);
scale = INTVAL (XEXP (xtmp0, 1));
}
else
{
ixreg = XEXP (xtmp0, 1);
scale = INTVAL (XEXP (xtmp0, 0));
}
goto PRINT_MEM;
}
/* GET_CODE (xtmp0) must be PLUS. */
xtmp1 = XEXP (xtmp0, 1);
xtmp0 = XEXP (xtmp0, 0);
if (CONSTANT_ADDRESS_P (xtmp0))
{
offset = xtmp0;
xtmp0 = xtmp1;
}
else
{
offset = xtmp1;
/* xtmp0 = xtmp0; */
}
if (REG_CODE_INDEX_P (xtmp0))
{
ixreg = xtmp0;
}
else
{ /* GET_CODE (xtmp0) must be MULT. */
if (REG_CODE_INDEX_P (XEXP (xtmp0, 0)))
{
ixreg = XEXP (xtmp0, 0);
scale = INTVAL (XEXP (xtmp0, 1));
}
else
{
ixreg = XEXP (xtmp0, 1);
scale = INTVAL (XEXP (xtmp0, 0));
}
}
goto PRINT_MEM;
NOT_BASE:
if (GET_CODE (xtmp0) == PLUS)
{
ixreg = xtmp1;
/* xtmp0 = xtmp0; */
}
else
{
ixreg = xtmp0;
xtmp0 = xtmp1;
}
if (REG_CODE_INDEX_P (ixreg))
{
scale = 1;
}
else if (REG_CODE_INDEX_P (XEXP (ixreg, 0)))
{
scale = INTVAL (XEXP (ixreg, 1));
ixreg = XEXP (ixreg, 0);
}
else
{ /* was else if with no condition. OK ??? */
scale = INTVAL (XEXP (ixreg, 0));
ixreg = XEXP (ixreg, 1);
}
if (REG_CODE_BASE_P (XEXP (xtmp0, 0)))
{
breg = XEXP (xtmp0, 0);
offset = XEXP (xtmp0, 1);
}
else
{
breg = XEXP (xtmp0, 1);
offset = XEXP (xtmp0, 0);
}
PRINT_MEM:
if (breg == 0 && ixreg == 0)
{
output_address (offset);
break;
}
else if (ixreg == 0 && offset == 0)
{
fprintf (file, "%s", reg_names[REGNO (breg)]);
break;
}
else
{
fprintf (file, "(");
if (offset != 0)
{
output_addr_const (file, offset);
needcomma = 1;
}
if (breg != 0)
{
if (needcomma)
fprintf (file, ",");
fprintf (file, "%s", reg_names[REGNO (breg)]);
needcomma = 1;
}
if (ixreg != 0)
{
if (needcomma)
fprintf (file, ",");
fprintf (file, "%s", reg_names[REGNO (ixreg)]);
if (scale != 1)
fprintf (file,"*%d", scale);
}
fprintf (file, ")");
break;
}
default:
output_addr_const (file, addr);
}
}
/* Return a REG that occurs in ADDR with coefficient 1.
ADDR can be effectively incremented by incrementing REG. */
static rtx
find_addr_reg (addr)
rtx addr;
{
while (GET_CODE (addr) == PLUS)
{
if (GET_CODE (XEXP (addr, 0)) == REG)
addr = XEXP (addr, 0);
else if (GET_CODE (XEXP (addr, 1)) == REG)
addr = XEXP (addr, 1);
else if (GET_CODE (XEXP (addr, 0)) == PLUS)
addr = XEXP (addr, 0);
else if (GET_CODE (XEXP (addr, 1)) == PLUS)
addr = XEXP (addr, 1);
}
if (GET_CODE (addr) == REG)
return addr;
return 0;
}
/* Return the best assembler insn template
for moving operands[1] into operands[0] as a fullword. */
static char *
singlemove_string (operands)
rtx *operands;
{
if (FPU_REG_P (operands[0]) || FPU_REG_P