OpenBSD-4.6/usr.bin/pcc/i386/table.c
/* $OpenBSD: table.c,v 1.7 2008/08/17 18:40:13 ragge Exp $ */
/*
* Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
# include "pass2.h"
# define TLL TLONGLONG|TULONGLONG
# define ANYSIGNED TINT|TLONG|TSHORT|TCHAR
# define ANYUSIGNED TUNSIGNED|TULONG|TUSHORT|TUCHAR
# define ANYFIXED ANYSIGNED|ANYUSIGNED
# define TUWORD TUNSIGNED|TULONG
# define TSWORD TINT|TLONG
# define TWORD TUWORD|TSWORD
#define SHINT SAREG /* short and int */
#define ININT INAREG
#define SHCH SBREG /* shape for char */
#define INCH INBREG
#define SHLL SCREG /* shape for long long */
#define INLL INCREG
#define SHFL SDREG /* shape for float/double */
#define INFL INDREG /* shape for float/double */
struct optab table[] = {
/* First entry must be an empty entry */
{ -1, FOREFF, SANY, TANY, SANY, TANY, 0, 0, "", },
/* PCONVs are usually not necessary */
{ PCONV, INAREG,
SAREG, TWORD|TPOINT,
SAREG, TWORD|TPOINT,
0, RLEFT,
"", },
/*
* A bunch conversions of integral<->integral types
* There are lots of them, first in table conversions to itself
* and then conversions from each type to the others.
*/
/* itself to itself, including pointers */
/* convert (u)char to (u)char. */
{ SCONV, INCH,
SHCH, TCHAR|TUCHAR,
SHCH, TCHAR|TUCHAR,
0, RLEFT,
"", },
/* convert pointers to int. */
{ SCONV, ININT,
SHINT, TPOINT|TWORD,
SANY, TWORD,
0, RLEFT,
"", },
/* convert (u)longlong to (u)longlong. */
{ SCONV, INLL,
SHLL, TLL,
SHLL, TLL,
0, RLEFT,
"", },
/* convert double <-> float. nothing to do here */
{ SCONV, INFL,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
0, RLEFT,
"", },
/* convert pointers to pointers. */
{ SCONV, ININT,
SHINT, TPOINT,
SANY, TPOINT,
0, RLEFT,
"", },
/* char to something */
/* convert char to (unsigned) short. */
{ SCONV, ININT,
SBREG|SOREG|SNAME, TCHAR,
SAREG, TSHORT|TUSHORT,
NASL|NAREG, RESC1,
" movsbw AL,A1\n", },
/* convert unsigned char to (u)short. */
{ SCONV, ININT,
SHCH|SOREG|SNAME, TUCHAR,
SAREG, TSHORT|TUSHORT,
NASL|NAREG, RESC1,
" movzbw AL,A1\n", },
/* convert signed char to int (or pointer). */
{ SCONV, ININT,
SHCH|SOREG|SNAME, TCHAR,
SAREG, TWORD|TPOINT,
NASL|NAREG, RESC1,
" movsbl AL,A1\n", },
/* convert unsigned char to (u)int. */
{ SCONV, ININT,
SHCH|SOREG|SNAME, TUCHAR,
SAREG, TWORD,
NASL|NAREG, RESC1,
" movzbl AL,A1\n", },
/* convert char to (u)long long */
{ SCONV, INLL,
SHCH|SOREG|SNAME, TCHAR,
SANY, TLL,
NSPECIAL|NCREG|NCSL, RESC1,
" movsbl AL,%eax\n cltd\n", },
/* convert unsigned char to (u)long long */
{ SCONV, INLL,
SHCH|SOREG|SNAME, TUCHAR,
SANY, TLL,
NCREG|NCSL, RESC1,
" movzbl AL,A1\n xorl U1,U1\n", },
/* convert char (in register) to double XXX - use NTEMP */
{ SCONV, INFL,
SHCH|SOREG|SNAME, TCHAR,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
NAREG|NASL|NDREG, RESC2,
" movsbl AL,A1\n pushl A1\n"
" fildl (%esp)\n addl $4,%esp\n", },
/* convert (u)char (in register) to double XXX - use NTEMP */
{ SCONV, INFL,
SHCH|SOREG|SNAME, TUCHAR,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
NAREG|NASL|NDREG, RESC2,
" movzbl AL,A1\n pushl A1\n"
" fildl (%esp)\n addl $4,%esp\n", },
/* short to something */
/* convert short (in memory) to char */
{ SCONV, INCH,
SNAME|SOREG, TSHORT|TUSHORT,
SHCH, TCHAR|TUCHAR,
NBREG|NBSL, RESC1,
" movb AL,A1\n", },
/* convert short (in reg) to char. */
{ SCONV, INCH,
SAREG|SNAME|SOREG, TSHORT|TUSHORT,
SHCH, TCHAR|TUCHAR,
NSPECIAL|NBREG|NBSL, RESC1,
"ZM", },
/* convert short to (u)int. */
{ SCONV, ININT,
SAREG|SOREG|SNAME, TSHORT,
SAREG, TWORD,
NASL|NAREG, RESC1,
" movswl AL,A1\n", },
/* convert unsigned short to (u)int. */
{ SCONV, ININT,
SAREG|SOREG|SNAME, TUSHORT,
SAREG, TWORD,
NASL|NAREG, RESC1,
" movzwl AL,A1\n", },
/* convert short to (u)long long */
{ SCONV, INLL,
SAREG|SOREG|SNAME, TSHORT,
SHLL, TLL,
NSPECIAL|NCREG|NCSL, RESC1,
" movswl AL,%eax\n cltd\n", },
/* convert unsigned short to (u)long long */
{ SCONV, INLL,
SAREG|SOREG|SNAME, TUSHORT,
SHLL, TLL,
NCREG|NCSL, RESC1,
" movzwl AL,A1\n xorl U1,U1\n", },
/* convert short (in memory) to float/double */
{ SCONV, INFL,
SOREG|SNAME, TSHORT,
SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
NDREG, RESC1,
" fild AL\n", },
/* convert short (in register) to float/double */
{ SCONV, INFL,
SAREG, TSHORT,
SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
NTEMP|NDREG, RESC1,
" pushw AL\n fild (%esp)\n addl $2,%esp\n", },
/* convert unsigned short to double XXX - use NTEMP */
{ SCONV, INFL,
SAREG|SOREG|SNAME, TUSHORT,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
NAREG|NASL|NDREG|NTEMP, RESC2,
" movzwl AL,A1\n pushl A1\n"
" fildl (%esp)\n addl $4,%esp\n", },
/* int to something */
/* convert int to char. This is done when register is loaded */
{ SCONV, INCH,
SAREG, TWORD|TPOINT,
SANY, TCHAR|TUCHAR,
NSPECIAL|NBREG|NBSL, RESC1,
"ZM", },
/* convert int to short. Nothing to do */
{ SCONV, INAREG,
SAREG, TWORD,
SANY, TSHORT|TUSHORT,
0, RLEFT,
"", },
/* convert signed int to (u)long long */
{ SCONV, INLL,
SHINT, TSWORD,
SHLL, TLL,
NSPECIAL|NCREG|NCSL, RESC1,
" cltd\n", },
/* convert unsigned int to (u)long long */
{ SCONV, INLL,
SHINT|SOREG|SNAME, TUWORD|TPOINT,
SHLL, TLL,
NCSL|NCREG, RESC1,
" movl AL,A1\n xorl U1,U1\n", },
/* convert int (in memory) to double */
{ SCONV, INFL,
SOREG|SNAME, TWORD,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
NDREG, RESC1,
" fildl AL\n", },
/* convert int (in register) to double */
{ SCONV, INFL,
SAREG, TWORD,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
NTEMP|NDREG, RESC1,
" pushl AL\n fildl (%esp)\n addl $4,%esp\n", },
/* long long to something */
/* convert (u)long long to (u)char (mem->reg) */
{ SCONV, INCH,
SOREG|SNAME, TLL,
SANY, TCHAR|TUCHAR,
NBREG|NBSL, RESC1,
" movb AL,A1\n", },
/* convert (u)long long to (u)char (reg->reg, hopefully nothing) */
{ SCONV, INCH,
SHLL, TLL,
SANY, TCHAR|TUCHAR,
NBREG|NBSL, RESC1,
"ZS", },
/* convert (u)long long to (u)short (mem->reg) */
{ SCONV, INAREG,
SOREG|SNAME, TLL,
SAREG, TSHORT|TUSHORT,
NAREG|NASL, RESC1,
" movw AL,A1\n", },
/* convert (u)long long to (u)short (reg->reg, hopefully nothing) */
{ SCONV, INAREG,
SHLL|SOREG|SNAME, TLL,
SAREG, TSHORT|TUSHORT,
NAREG|NASL, RESC1,
"ZS", },
/* convert long long to int (mem->reg) */
{ SCONV, INAREG,
SOREG|SNAME, TLL,
SAREG, TWORD|TPOINT,
NAREG|NASL, RESC1,
" movl AL,A1\n", },
/* convert long long to int (reg->reg, hopefully nothing) */
{ SCONV, INAREG,
SHLL|SOREG|SNAME, TLL,
SAREG, TWORD|TPOINT,
NAREG|NASL, RESC1,
"ZS", },
/* convert long long (in memory) to floating */
{ SCONV, INFL,
SOREG|SNAME, TLONGLONG,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
NDREG, RESC1,
" fildq AL\n", },
/* convert long long (in register) to floating */
{ SCONV, INFL,
SHLL, TLONGLONG,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
NTEMP|NDREG, RESC1,
" pushl UL\n pushl AL\n"
" fildq (%esp)\n addl $8,%esp\n", },
/* convert unsigned long long to floating */
{ SCONV, INFL,
SCREG, TULONGLONG,
SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
NDREG, RESC1,
"ZJ", },
/* float to something */
#if 0 /* go via int by adding an extra sconv in clocal() */
/* convert float/double to (u) char. XXX should use NTEMP here */
{ SCONV, INCH,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHCH, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NBREG, RESC1,
" subl $4,%esp\n fistpl (%esp)\n popl A1\n", },
/* convert float/double to (u) int/short/char. XXX should use NTEMP here */
{ SCONV, INCH,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHCH, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NCREG, RESC1,
" subl $4,%esp\n fistpl (%esp)\n popl A1\n", },
#endif
/* convert float/double to (u)int. XXX should use NTEMP here */
{ SCONV, INAREG,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SAREG, TWORD,
NAREG, RESC1,
#ifdef notdef /* Must round down and nothing else */
" subl $4,%esp\n fistpl (%esp)\n popl A1\n", },
#else
" subl $12,%esp\n"
" fnstcw (%esp)\n"
" fnstcw 4(%esp)\n"
" movb $12,1(%esp)\n"
" fldcw (%esp)\n"
" fistpl 8(%esp)\n"
" movl 8(%esp),A1\n"
" fldcw 4(%esp)\n"
" addl $12,%esp\n", },
#endif
/* convert float/double (in register) to (unsigned) long long */
/* XXX - unsigned is not handled correct */
{ SCONV, INLL,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHLL, TLONGLONG|TULONGLONG,
NCREG, RESC1,
#ifdef notdef /* Must round down and nothing else */
" subl $8,%esp\n fistpq (%esp)\n"
" popl A1\n popl U1\n", },
#else
" subl $16,%esp\n"
" fnstcw (%esp)\n"
" fnstcw 4(%esp)\n"
" movb $12,1(%esp)\n"
" fldcw (%esp)\n"
" fistpq 8(%esp)\n"
" movl 8(%esp),A1\n"
" movl 12(%esp),U1\n"
" fldcw 4(%esp)\n"
" addl $16,%esp\n", },
#endif
/* slut sconv */
/*
* Subroutine calls.
*/
{ CALL, FOREFF,
SCON, TANY,
SANY, TANY,
0, 0,
" call CL\nZC", },
{ UCALL, FOREFF,
SCON, TANY,
SAREG, TWORD|TPOINT,
0, 0,
" call CL\n", },
{ CALL, INAREG,
SCON, TANY,
SAREG, TSHORT|TUSHORT|TWORD|TPOINT,
NAREG|NASL, RESC1, /* should be 0 */
" call CL\nZC", },
{ UCALL, INAREG,
SCON, TANY,
SAREG, TSHORT|TUSHORT|TWORD|TPOINT,
NAREG|NASL, RESC1, /* should be 0 */
" call CL\n", },
{ CALL, INBREG,
SCON, TANY,
SBREG, TCHAR|TUCHAR,
NBREG, RESC1, /* should be 0 */
" call CL\nZC", },
{ UCALL, INBREG,
SCON, TANY,
SBREG, TCHAR|TUCHAR,
NBREG, RESC1, /* should be 0 */
" call CL\n", },
{ CALL, INCREG,
SCON, TANY,
SCREG, TANY,
NCREG|NCSL, RESC1, /* should be 0 */
" call CL\nZC", },
{ UCALL, INCREG,
SCON, TANY,
SCREG, TANY,
NCREG|NCSL, RESC1, /* should be 0 */
" call CL\n", },
{ CALL, INDREG,
SCON, TANY,
SDREG, TANY,
NDREG|NDSL, RESC1, /* should be 0 */
" call CL\nZC", },
{ UCALL, INDREG,
SCON, TANY,
SDREG, TANY,
NDREG|NDSL, RESC1, /* should be 0 */
" call CL\nZC", },
{ CALL, FOREFF,
SAREG, TANY,
SANY, TANY,
0, 0,
" call *AL\nZC", },
{ UCALL, FOREFF,
SAREG, TANY,
SANY, TANY,
0, 0,
" call *AL\nZC", },
{ CALL, INAREG,
SAREG, TANY,
SANY, TANY,
NAREG|NASL, RESC1, /* should be 0 */
" call *AL\nZC", },
{ UCALL, INAREG,
SAREG, TANY,
SANY, TANY,
NAREG|NASL, RESC1, /* should be 0 */
" call *AL\nZC", },
{ CALL, INBREG,
SAREG, TANY,
SANY, TANY,
NBREG|NBSL, RESC1, /* should be 0 */
" call *AL\nZC", },
{ UCALL, INBREG,
SAREG, TANY,
SANY, TANY,
NBREG|NBSL, RESC1, /* should be 0 */
" call *AL\nZC", },
{ CALL, INCREG,
SAREG, TANY,
SANY, TANY,
NCREG|NCSL, RESC1, /* should be 0 */
" call *AL\nZC", },
{ UCALL, INCREG,
SAREG, TANY,
SANY, TANY,
NCREG|NCSL, RESC1, /* should be 0 */
" call *AL\nZC", },
{ CALL, INDREG,
SAREG, TANY,
SANY, TANY,
NDREG|NDSL, RESC1, /* should be 0 */
" call *AL\nZC", },
{ UCALL, INDREG,
SAREG, TANY,
SANY, TANY,
NDREG|NDSL, RESC1, /* should be 0 */
" call *AL\nZC", },
/* struct return */
{ USTCALL, FOREFF,
SCON, TANY,
SANY, TANY,
NAREG|NASL, 0,
"ZP call CL\nZC", },
{ USTCALL, INAREG,
SCON, TANY,
SANY, TANY,
NAREG|NASL, RESC1, /* should be 0 */
"ZP call CL\nZC", },
{ USTCALL, INAREG,
SNAME|SAREG, TANY,
SANY, TANY,
NAREG|NASL, RESC1, /* should be 0 */
"ZP call *AL\nZC", },
{ STCALL, FOREFF,
SCON, TANY,
SANY, TANY,
NAREG|NASL, 0,
"ZP call CL\nZC", },
{ STCALL, INAREG,
SCON, TANY,
SANY, TANY,
NAREG|NASL, RESC1, /* should be 0 */
"ZP call CL\nZC", },
{ STCALL, INAREG,
SNAME|SAREG, TANY,
SANY, TANY,
NAREG|NASL, RESC1, /* should be 0 */
"ZP call *AL\nZC", },
/*
* The next rules handle all binop-style operators.
*/
/* Special treatment for long long */
{ PLUS, INLL|FOREFF,
SHLL, TLL,
SHLL|SNAME|SOREG, TLL,
0, RLEFT,
" addl AR,AL\n adcl UR,UL\n", },
/* Special treatment for long long XXX - fix commutative check */
{ PLUS, INLL|FOREFF,
SHLL|SNAME|SOREG, TLL,
SHLL, TLL,
0, RRIGHT,
" addl AL,AR\n adcl UL,UR\n", },
{ PLUS, INFL,
SHFL, TDOUBLE,
SNAME|SOREG, TDOUBLE,
0, RLEFT,
" faddl AR\n", },
{ PLUS, INFL|FOREFF,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
0, RLEFT,
" faddp\n", },
{ PLUS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TWORD|TPOINT,
SONE, TANY,
0, RLEFT,
" incl AL\n", },
{ PLUS, INAREG,
SAREG, TWORD|TPOINT,
SCON, TANY,
NAREG|NASL, RESC1,
" leal CR(AL),A1\n", },
{ PLUS, INCH|FOREFF,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
SONE, TANY,
0, RLEFT,
" incb AL\n", },
{ PLUS, INAREG,
SAREG, TWORD,
SAREG, TWORD,
NAREG|NASL|NASR, RESC1,
" leal (AL,AR),A1\n", },
{ MINUS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TWORD|TPOINT,
SONE, TANY,
0, RLEFT,
" decl AL\n", },
{ MINUS, INCH|FOREFF,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
SONE, TANY,
0, RLEFT,
" decb AL\n", },
/* address as register offset, negative */
{ MINUS, INAREG,
SAREG, TWORD|TPOINT,
SPCON, TANY,
NAREG|NASL, RESC1,
" leal -CR(AL),A1\n", },
{ MINUS, INLL|FOREFF,
SHLL, TLL,
SHLL|SNAME|SOREG, TLL,
0, RLEFT,
" subl AR,AL\n sbbl UR,UL\n", },
{ MINUS, INFL,
SHFL, TDOUBLE,
SNAME|SOREG, TDOUBLE,
0, RLEFT,
" fsubl AR\n", },
{ MINUS, INFL|FOREFF,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
0, RLEFT,
" fsubZAp\n", },
/* Simple r/m->reg ops */
{ OPSIMP, INAREG|FOREFF,
SAREG, TWORD|TPOINT,
SAREG|SNAME|SOREG, TWORD|TPOINT,
0, RLEFT,
" Ol AR,AL\n", },
{ OPSIMP, INAREG|FOREFF,
SHINT, TSHORT|TUSHORT,
SHINT|SNAME|SOREG, TSHORT|TUSHORT,
0, RLEFT,
" Ow AR,AL\n", },
{ OPSIMP, INCH|FOREFF,
SHCH, TCHAR|TUCHAR,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
0, RLEFT,
" Ob AR,AL\n", },
{ OPSIMP, INAREG|FOREFF,
SAREG, TWORD|TPOINT,
SCON, TWORD|TPOINT,
0, RLEFT,
" Ol AR,AL\n", },
{ OPSIMP, INAREG|FOREFF,
SHINT|SNAME|SOREG, TSHORT|TUSHORT,
SCON, TANY,
0, RLEFT,
" Ow AR,AL\n", },
{ OPSIMP, INCH|FOREFF,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
SCON, TANY,
0, RLEFT,
" Ob AR,AL\n", },
{ OPSIMP, INLL|FOREFF,
SHLL, TLL,
SHLL|SNAME|SOREG, TLL,
0, RLEFT,
" Ol AR,AL\n Ol UR,UL\n", },
/*
* The next rules handle all shift operators.
*/
/* (u)longlong left shift is emulated */
{ LS, INCREG,
SCREG|SNAME|SOREG|SCON, TLL,
SAREG|SNAME|SOREG|SCON, TINT, /* will be int */
NSPECIAL|NCREG|NCSL|NCSR, RESC1,
"ZO", },
{ LS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TWORD,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" sall AR,AL\n", },
{ LS, INAREG|FOREFF,
SAREG, TWORD,
SCON, TANY,
0, RLEFT,
" sall AR,AL\n", },
{ LS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TSHORT|TUSHORT,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" shlw AR,AL\n", },
{ LS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TSHORT|TUSHORT,
SCON, TANY,
0, RLEFT,
" shlw AR,AL\n", },
{ LS, INCH|FOREFF,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" salb AR,AL\n", },
{ LS, INCH|FOREFF,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
SCON, TANY,
0, RLEFT,
" salb AR,AL\n", },
/* (u)longlong right shift is emulated */
{ RS, INCREG,
SCREG|SNAME|SOREG|SCON, TLL,
SAREG|SNAME|SOREG|SCON, TINT, /* will be int */
NSPECIAL|NCREG|NCSL|NCSR, RESC1,
"ZO", },
{ RS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TSWORD,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" sarl AR,AL\n", },
{ RS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TSWORD,
SCON, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
0, RLEFT,
" sarl AR,AL\n", },
{ RS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TUWORD,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" shrl AR,AL\n", },
{ RS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TUWORD,
SCON, TWORD|TCHAR|TUCHAR|TSHORT|TUSHORT,
0, RLEFT,
" shrl AR,AL\n", },
{ RS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TSHORT,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" sarw AR,AL\n", },
{ RS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TSHORT,
SCON, TANY,
0, RLEFT,
" sarw AR,AL\n", },
{ RS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TUSHORT,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" shrw AR,AL\n", },
{ RS, INAREG|FOREFF,
SAREG|SNAME|SOREG, TUSHORT,
SCON, TANY,
0, RLEFT,
" shrw AR,AL\n", },
{ RS, INCH|FOREFF,
SHCH|SNAME|SOREG, TCHAR,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" sarb AR,AL\n", },
{ RS, INCH|FOREFF,
SHCH|SNAME|SOREG, TCHAR,
SCON, TANY,
0, RLEFT,
" sarb AR,AL\n", },
{ RS, INCH|FOREFF,
SHCH|SNAME|SOREG, TUCHAR,
SHCH, TCHAR|TUCHAR,
NSPECIAL, RLEFT,
" shrb AR,AL\n", },
{ RS, INCH|FOREFF,
SHCH|SNAME|SOREG, TUCHAR,
SCON, TANY,
0, RLEFT,
" shrb AR,AL\n", },
/*
* The next rules takes care of assignments. "=".
*/
{ ASSIGN, FORCC|FOREFF|INLL,
SHLL, TLL,
SMIXOR, TANY,
0, RDEST,
" xorl AL,AL\n xorl UL,UL\n", },
{ ASSIGN, FORCC|FOREFF|INLL,
SHLL, TLL,
SMILWXOR, TANY,
0, RDEST,
" xorl AL,AL\n movl UR,UL\n", },
{ ASSIGN, FORCC|FOREFF|INLL,
SHLL, TLL,
SMIHWXOR, TANY,
0, RDEST,
" movl AR,AL\n xorl UL,UL\n", },
{ ASSIGN, FOREFF|INLL,
SHLL, TLL,
SCON, TANY,
0, RDEST,
" movl AR,AL\n movl UR,UL\n", },
{ ASSIGN, FOREFF,
SHLL|SNAME|SOREG, TLL,
SCON, TANY,
0, 0,
" movl AR,AL\n movl UR,UL\n", },
{ ASSIGN, FORCC|FOREFF|INAREG,
SAREG, TWORD|TPOINT,
SMIXOR, TANY,
0, RDEST,
" xorl AL,AL\n", },
{ ASSIGN, FOREFF,
SAREG|SNAME|SOREG, TWORD|TPOINT,
SCON, TANY,
0, 0,
" movl AR,AL\n", },
{ ASSIGN, FOREFF|INAREG,
SAREG, TWORD|TPOINT,
SCON, TANY,
0, RDEST,
" movl AR,AL\n", },
{ ASSIGN, FORCC|FOREFF|INAREG,
SAREG, TSHORT|TUSHORT,
SMIXOR, TANY,
0, RDEST,
" xorw AL,AL\n", },
{ ASSIGN, FOREFF,
SAREG|SNAME|SOREG, TSHORT|TUSHORT,
SCON, TANY,
0, 0,
" movw AR,AL\n", },
{ ASSIGN, FOREFF|INAREG,
SAREG, TSHORT|TUSHORT,
SCON, TANY,
0, RDEST,
" movw AR,AL\n", },
{ ASSIGN, FOREFF,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
SCON, TANY,
0, 0,
" movb AR,AL\n", },
{ ASSIGN, FOREFF|INCH,
SHCH, TCHAR|TUCHAR,
SCON, TANY,
0, RDEST,
" movb AR,AL\n", },
{ ASSIGN, FOREFF|INLL,
SHLL|SNAME|SOREG, TLL,
SHLL, TLL,
0, RDEST,
" movl AR,AL\n movl UR,UL\n", },
{ ASSIGN, FOREFF|INAREG,
SAREG|SNAME|SOREG, TWORD|TPOINT,
SAREG, TWORD|TPOINT,
0, RDEST,
" movl AR,AL\n", },
{ ASSIGN, FOREFF|INAREG,
SAREG, TWORD|TPOINT,
SAREG|SNAME|SOREG, TWORD|TPOINT,
0, RDEST,
" movl AR,AL\n", },
{ ASSIGN, FOREFF|INAREG,
SAREG|SNAME|SOREG, TSHORT|TUSHORT,
SAREG, TSHORT|TUSHORT,
0, RDEST,
" movw AR,AL\n", },
{ ASSIGN, FOREFF|INCH,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
SHCH, TCHAR|TUCHAR|TWORD,
0, RDEST,
" movb AR,AL\n", },
{ ASSIGN, FOREFF|INBREG,
SFLD, TCHAR|TUCHAR,
SBREG|SCON, TCHAR|TUCHAR,
NAREG|NBREG, RDEST,
" movb AR,A2\n"
" movzbl A2,A1\n"
" andl $N,AL\n"
" sall $H,A1\n"
" andl $M,A1\n"
" orl A1,AL\n"
"F movb AR,AD\n"
"FZE", },
{ ASSIGN, FOREFF|INAREG,
SFLD, TSHORT|TUSHORT,
SAREG|SCON, TSHORT|TUSHORT,
NAREG, RDEST,
" movw AR,A1\n"
" movzwl A1,ZN\n"
" andl $N,AL\n"
" sall $H,ZN\n"
" andl $M,ZN\n"
" orl ZN,AL\n"
"F movw AR,AD\n"
"FZE", },
{ ASSIGN, FOREFF|INAREG,
SFLD, TWORD,
SAREG|SNAME|SOREG|SCON, TWORD,
NAREG, RDEST,
" movl AR,A1\n"
" andl $N,AL\n"
" sall $H,A1\n"
" andl $M,A1\n"
" orl A1,AL\n"
"F movl AR,AD\n"
"FZE", },
{ ASSIGN, INDREG|FOREFF,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
0, RDEST,
"", }, /* This will always be in the correct register */
/* order of table entries is very important here! */
{ ASSIGN, INFL,
SNAME|SOREG, TLDOUBLE,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
0, RDEST,
" fst AL\n", },
{ ASSIGN, FOREFF,
SNAME|SOREG, TLDOUBLE,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
0, 0,
" fstpt AL\n", },
{ ASSIGN, INFL,
SNAME|SOREG, TDOUBLE,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
0, RDEST,
" fstl AL\n", },
{ ASSIGN, FOREFF,
SNAME|SOREG, TDOUBLE,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
0, 0,
" fstpl AL\n", },
{ ASSIGN, INFL,
SNAME|SOREG, TFLOAT,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
0, RDEST,
" fsts AL\n", },
{ ASSIGN, FOREFF,
SNAME|SOREG, TFLOAT,
SHFL, TFLOAT|TDOUBLE|TLDOUBLE,
0, 0,
" fstps AL\n", },
/* end very important order */
{ ASSIGN, INFL|FOREFF,
SHFL, TLDOUBLE,
SHFL|SOREG|SNAME, TLDOUBLE,
0, RDEST,
" fldt AR\n", },
{ ASSIGN, INFL|FOREFF,
SHFL, TDOUBLE,
SHFL|SOREG|SNAME, TDOUBLE,
0, RDEST,
" fldl AR\n", },
{ ASSIGN, INFL|FOREFF,
SHFL, TFLOAT,
SHFL|SOREG|SNAME, TFLOAT,
0, RDEST,
" flds AR\n", },
/* Do not generate memcpy if return from funcall */
#if 0
{ STASG, INAREG|FOREFF,
SOREG|SNAME|SAREG, TPTRTO|TSTRUCT,
SFUNCALL, TPTRTO|TSTRUCT,
0, RRIGHT,
"", },
#endif
{ STASG, INAREG|FOREFF,
SOREG|SNAME, TANY,
SAREG|SOREG|SNAME, TPTRTO|TANY,
NSPECIAL, RRIGHT,
"ZQ", },
/*
* DIV/MOD/MUL
*/
/* long long div is emulated */
{ DIV, INCREG,
SCREG|SNAME|SOREG|SCON, TLL,
SCREG|SNAME|SOREG|SCON, TLL,
NSPECIAL|NCREG|NCSL|NCSR, RESC1,
"ZO", },
{ DIV, INAREG,
SAREG, TSWORD,
SAREG|SNAME|SOREG, TWORD,
NSPECIAL, RDEST,
" cltd\n idivl AR\n", },
{ DIV, INAREG,
SAREG, TUWORD|TPOINT,
SAREG|SNAME|SOREG, TUWORD|TPOINT,
NSPECIAL, RDEST,
" xorl %edx,%edx\n divl AR\n", },
{ DIV, INAREG,
SAREG, TUSHORT,
SAREG|SNAME|SOREG, TUSHORT,
NSPECIAL, RDEST,
" xorl %edx,%edx\n divw AR\n", },
{ DIV, INCH,
SHCH, TUCHAR,
SHCH|SNAME|SOREG, TUCHAR,
NSPECIAL, RDEST,
" xorb %ah,%ah\n divb AR\n", },
{ DIV, INFL,
SHFL, TDOUBLE,
SNAME|SOREG, TDOUBLE,
0, RLEFT,
" fdivl AR\n", },
{ DIV, INFL,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
0, RLEFT,
" fdivZAp\n", },
/* (u)longlong mod is emulated */
{ MOD, INCREG,
SCREG|SNAME|SOREG|SCON, TLL,
SCREG|SNAME|SOREG|SCON, TLL,
NSPECIAL|NCREG|NCSL|NCSR, RESC1,
"ZO", },
{ MOD, INAREG,
SAREG, TSWORD,
SAREG|SNAME|SOREG, TSWORD,
NAREG|NSPECIAL, RESC1,
" cltd\n idivl AR\n", },
{ MOD, INAREG,
SAREG, TWORD|TPOINT,
SAREG|SNAME|SOREG, TUWORD|TPOINT,
NAREG|NSPECIAL, RESC1,
" xorl %edx,%edx\n divl AR\n", },
{ MOD, INAREG,
SAREG, TUSHORT,
SAREG|SNAME|SOREG, TUSHORT,
NAREG|NSPECIAL, RESC1,
" xorl %edx,%edx\n divw AR\n", },
{ MOD, INCH,
SHCH, TUCHAR,
SHCH|SNAME|SOREG, TUCHAR,
NBREG|NSPECIAL, RESC1,
" xorb %ah,%ah\n divb AR\n", },
/* (u)longlong mul is emulated */
{ MUL, INCREG,
SCREG|SNAME|SOREG|SCON, TLL,
SCREG|SNAME|SOREG|SCON, TLL,
NSPECIAL|NCREG|NCSL|NCSR, RESC1,
"ZO", },
{ MUL, INAREG,
SAREG, TWORD|TPOINT,
SAREG|SNAME|SOREG|SCON, TWORD|TPOINT,
0, RLEFT,
" imull AR,AL\n", },
{ MUL, INAREG,
SAREG, TSHORT|TUSHORT,
SAREG|SNAME|SOREG, TSHORT|TUSHORT,
0, RLEFT,
" imulw AR,AL\n", },
{ MUL, INCH,
SHCH, TCHAR|TUCHAR,
SHCH|SNAME|SOREG, TCHAR|TUCHAR,
NSPECIAL, RDEST,
" imulb AR\n", },
{ MUL, INFL,
SHFL, TDOUBLE,
SNAME|SOREG, TDOUBLE,
0, RLEFT,
" fmull AR\n", },
{ MUL, INFL,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
0, RLEFT,
" fmulp\n", },
/*
* Indirection operators.
*/
{ UMUL, INLL,
SANY, TANY,
SOREG, TLL,
NCREG, RESC1,
" movl UL,U1\n movl AL,A1\n", },
{ UMUL, INAREG,
SANY, TPOINT|TWORD,
SOREG, TPOINT|TWORD,
NAREG|NASL, RESC1,
" movl AL,A1\n", },
{ UMUL, INCH,
SANY, TANY,
SOREG, TCHAR|TUCHAR,
NBREG|NBSL, RESC1,
" movb AL,A1\n", },
{ UMUL, INAREG,
SANY, TANY,
SOREG, TSHORT|TUSHORT,
NAREG|NASL, RESC1,
" movw AL,A1\n", },
{ UMUL, INFL,
SANY, TANY,
SOREG, TLDOUBLE,
NDREG|NDSL, RESC1,
" fldt AL\n", },
{ UMUL, INFL,
SANY, TANY,
SOREG, TDOUBLE,
NDREG|NDSL, RESC1,
" fldl AL\n", },
{ UMUL, INFL,
SANY, TANY,
SOREG, TFLOAT,
NDREG|NDSL, RESC1,
" flds AL\n", },
/*
* Logical/branching operators
*/
/* Comparisions, take care of everything */
{ OPLOG, FORCC,
SHLL|SOREG|SNAME, TLL,
SHLL, TLL,
0, 0,
"ZD", },
{ OPLOG, FORCC,
SAREG|SOREG|SNAME, TWORD|TPOINT,
SCON|SAREG, TWORD|TPOINT,
0, RESCC,
" cmpl AR,AL\n", },
{ OPLOG, FORCC,
SCON|SAREG, TWORD|TPOINT,
SAREG|SOREG|SNAME, TWORD|TPOINT,
0, RESCC,
" cmpl AR,AL\n", },
{ OPLOG, FORCC,
SAREG|SOREG|SNAME, TSHORT|TUSHORT,
SCON|SAREG, TANY,
0, RESCC,
" cmpw AR,AL\n", },
{ OPLOG, FORCC,
SBREG|SOREG|SNAME, TCHAR|TUCHAR,
SCON|SBREG, TANY,
0, RESCC,
" cmpb AR,AL\n", },
{ OPLOG, FORCC,
SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
NSPECIAL, 0,
"ZG", },
{ OPLOG, FORCC,
SOREG|SNAME, TDOUBLE|TFLOAT,
SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
NSPECIAL, 0,
"ZG", },
#if 0
/* Ppro and later only */
{ OPLOG, FORCC,
SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
SDREG, TLDOUBLE|TDOUBLE|TFLOAT,
0, RESCC,
"ZA fucomip %st,%st(1)\n", },
#endif
{ OPLOG, FORCC,
SANY, TANY,
SANY, TANY,
REWRITE, 0,
"diediedie!", },
/* AND/OR/ER/NOT */
{ AND, INAREG|FOREFF,
SAREG|SOREG|SNAME, TWORD,
SCON|SAREG, TWORD,
0, RLEFT,
" andl AR,AL\n", },
{ AND, INCREG|FOREFF,
SCREG, TLL,
SCREG|SOREG|SNAME, TLL,
0, RLEFT,
" andl AR,AL\n andl UR,UL\n", },
{ AND, INAREG|FOREFF,
SAREG, TWORD,
SAREG|SOREG|SNAME, TWORD,
0, RLEFT,
" andl AR,AL\n", },
{ AND, INAREG|FOREFF,
SAREG|SOREG|SNAME, TSHORT|TUSHORT,
SCON|SAREG, TSHORT|TUSHORT,
0, RLEFT,
" andw AR,AL\n", },
{ AND, INAREG|FOREFF,
SAREG, TSHORT|TUSHORT,
SAREG|SOREG|SNAME, TSHORT|TUSHORT,
0, RLEFT,
" andw AR,AL\n", },
{ AND, INBREG|FOREFF,
SBREG|SOREG|SNAME, TCHAR|TUCHAR,
SCON|SBREG, TCHAR|TUCHAR,
0, RLEFT,
" andb AR,AL\n", },
{ AND, INBREG|FOREFF,
SBREG, TCHAR|TUCHAR,
SBREG|SOREG|SNAME, TCHAR|TUCHAR,
0, RLEFT,
" andb AR,AL\n", },
/* AND/OR/ER/NOT */
/*
* Jumps.
*/
{ GOTO, FOREFF,
SCON, TANY,
SANY, TANY,
0, RNOP,
" jmp LL\n", },
#if defined(GCC_COMPAT) || defined(LANG_F77)
{ GOTO, FOREFF,
SAREG, TANY,
SANY, TANY,
0, RNOP,
" jmp *AL\n", },
#endif
/*
* Convert LTYPE to reg.
*/
{ OPLTYPE, FORCC|INLL,
SCREG, TLL,
SMIXOR, TANY,
NCREG, RESC1,
" xorl U1,U1\n xorl A1,A1\n", },
{ OPLTYPE, FORCC|INLL,
SCREG, TLL,
SMILWXOR, TANY,
NCREG, RESC1,
" movl UL,U1\n xorl A1,A1\n", },
{ OPLTYPE, FORCC|INLL,
SCREG, TLL,
SMIHWXOR, TANY,
NCREG, RESC1,
" xorl U1,U1\n movl AL,A1\n", },
{ OPLTYPE, INLL,
SANY, TANY,
SCREG|SCON|SOREG|SNAME, TLL,
NCREG, RESC1,
" movl UL,U1\n movl AL,A1\n", },
{ OPLTYPE, FORCC|INAREG,
SAREG, TWORD|TPOINT,
SMIXOR, TANY,
NAREG|NASL, RESC1,
" xorl A1,A1\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SAREG|SCON|SOREG|SNAME, TWORD|TPOINT,
NAREG|NASL, RESC1,
" movl AL,A1\n", },
{ OPLTYPE, INBREG,
SANY, TANY,
SBREG|SOREG|SNAME|SCON, TCHAR|TUCHAR,
NBREG, RESC1,
" movb AL,A1\n", },
{ OPLTYPE, FORCC|INAREG,
SAREG, TSHORT|TUSHORT,
SMIXOR, TANY,
NAREG, RESC1,
" xorw A1,A1\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SAREG|SOREG|SNAME|SCON, TSHORT|TUSHORT,
NAREG, RESC1,
" movw AL,A1\n", },
{ OPLTYPE, INDREG,
SANY, TLDOUBLE,
SOREG|SNAME, TLDOUBLE,
NDREG, RESC1,
" fldt AL\n", },
{ OPLTYPE, INDREG,
SANY, TDOUBLE,
SOREG|SNAME, TDOUBLE,
NDREG, RESC1,
" fldl AL\n", },
{ OPLTYPE, INDREG,
SANY, TFLOAT,
SOREG|SNAME, TFLOAT,
NDREG, RESC1,
" flds AL\n", },
/* Only used in ?: constructs. The stack already contains correct value */
{ OPLTYPE, INDREG,
SANY, TFLOAT|TDOUBLE|TLDOUBLE,
SDREG, TFLOAT|TDOUBLE|TLDOUBLE,
NDREG, RESC1,
"", },
/*
* Negate a word.
*/
{ UMINUS, INCREG|FOREFF,
SCREG, TLL,
SCREG, TLL,
0, RLEFT,
" negl AL\n adcl $0,UL\n negl UL\n", },
{ UMINUS, INAREG|FOREFF,
SAREG, TWORD|TPOINT,
SAREG, TWORD|TPOINT,
0, RLEFT,
" negl AL\n", },
{ UMINUS, INAREG|FOREFF,
SAREG, TSHORT|TUSHORT,
SAREG, TSHORT|TUSHORT,
0, RLEFT,
" negw AL\n", },
{ UMINUS, INBREG|FOREFF,
SBREG, TCHAR|TUCHAR,
SBREG, TCHAR|TUCHAR,
0, RLEFT,
" negb AL\n", },
{ UMINUS, INFL|FOREFF,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
SHFL, TLDOUBLE|TDOUBLE|TFLOAT,
0, RLEFT,
" fchs\n", },
{ COMPL, INCREG,
SCREG, TLL,
SANY, TANY,
0, RLEFT,
" notl AL\n notl UL\n", },
{ COMPL, INAREG,
SAREG, TWORD,
SANY, TANY,
0, RLEFT,
" notl AL\n", },
{ COMPL, INAREG,
SAREG, TSHORT|TUSHORT,
SANY, TANY,
0, RLEFT,
" notw AL\n", },
{ COMPL, INBREG,
SBREG, TCHAR|TUCHAR,
SANY, TANY,
0, RLEFT,
" notb AL\n", },
/*
* Arguments to functions.
*/
{ FUNARG, FOREFF,
SCON|SCREG|SNAME|SOREG, TLL,
SANY, TLL,
0, RNULL,
" pushl UL\n pushl AL\n", },
{ FUNARG, FOREFF,
SCON|SAREG|SNAME|SOREG, TWORD|TPOINT,
SANY, TWORD|TPOINT,
0, RNULL,
" pushl AL\n", },
{ FUNARG, FOREFF,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SANY, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
0, RNULL,
" pushl AL\n", },
{ FUNARG, FOREFF,
SAREG|SNAME|SOREG, TSHORT,
SANY, TSHORT,
NAREG, 0,
" movswl AL,ZN\n pushl ZN\n", },
{ FUNARG, FOREFF,
SAREG|SNAME|SOREG, TUSHORT,
SANY, TUSHORT,
NAREG, 0,
" movzwl AL,ZN\n pushl ZN\n", },
{ FUNARG, FOREFF,
SHCH|SNAME|SOREG, TCHAR,
SANY, TCHAR,
NAREG, 0,
" movsbl AL,A1\n pushl A1\n", },
{ FUNARG, FOREFF,
SHCH|SNAME|SOREG, TUCHAR,
SANY, TUCHAR,
NAREG, 0,
" movzbl AL,A1\n pushl A1\n", },
{ FUNARG, FOREFF,
SNAME|SOREG, TDOUBLE,
SANY, TDOUBLE,
0, 0,
" pushl UL\n pushl AL\n", },
{ FUNARG, FOREFF,
SDREG, TDOUBLE,
SANY, TDOUBLE,
0, 0,
" subl $8,%esp\n fstpl (%esp)\n", },
{ FUNARG, FOREFF,
SNAME|SOREG, TFLOAT,
SANY, TFLOAT,
0, 0,
" pushl AL\n", },
{ FUNARG, FOREFF,
SDREG, TFLOAT,
SANY, TFLOAT,
0, 0,
" subl $4,%esp\n fstps (%esp)\n", },
{ FUNARG, FOREFF,
SDREG, TLDOUBLE,
SANY, TLDOUBLE,
0, 0,
" subl $12,%esp\n fstpt (%esp)\n", },
{ STARG, FOREFF,
SAREG|SOREG|SNAME|SCON, TANY,
SANY, TSTRUCT,
NSPECIAL|NAREG, 0,
"ZF", },
# define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
{ UMUL, DF( UMUL ), },
{ ASSIGN, DF(ASSIGN), },
{ STASG, DF(STASG), },
{ FLD, DF(FLD), },
{ OPLEAF, DF(NAME), },
/* { INIT, DF(INIT), }, */
{ OPUNARY, DF(UMINUS), },
{ OPANY, DF(BITYPE), },
{ FREE, FREE, FREE, FREE, FREE, FREE, FREE, FREE, "help; I'm in trouble\n" },
};
int tablesize = sizeof(table)/sizeof(table[0]);