OpenBSD-4.6/usr.bin/pcc/mips/table.c
/* $OpenBSD: table.c,v 1.5 2008/04/11 20:45:52 stefan 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.
*/
/*
* MIPS port by Jan Enoksson (janeno-1@student.ltu.se) and
* Simon Olsson (simols-1@student.ltu.se) 2005.
*
* It appears that the target machine was big endian. The original
* code contained many endian aspects which are now handled in
* machine-independent code.
*
* On MIPS, the assembler does an amazing amount of work for us.
* We don't have to worry about PIC, nor about finding the address
* of SNAMES. Whenever possible, we defer the work to the assembler.
*/
#include "pass2.h"
#define TUWORD TUNSIGNED|TULONG
#define TSWORD TINT|TLONG
#define TWORD TUWORD|TSWORD
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,
" # convert between word and pointer", },
/*
* Conversions of integral<->integral types
*/
{ SCONV, INAREG,
SOREG, TCHAR,
SAREG, TSWORD|TSHORT,
NAREG, RESC1,
" lb A1,AL # convert oreg char to short/int\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
NAREG, RESC1,
" lbu A1,AL # conver oreg char to uchar/ushort/uint\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT,
NAREG, RESC1,
" lbu A1,AL # convert oreg uchar to (u)short/(u)int\n"
" nop\n", },
{ SCONV, INBREG,
SOREG, TCHAR,
SBREG, TLONGLONG,
NBREG, RESC1,
" lb A1,AL # convert oreg char to longlong\n"
" nop\n"
" sra U1,A1,31\n", },
/* chor -> ulonglong handled later */
{ SCONV, INBREG,
SOREG, TUCHAR,
SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lbu A1,AL # convert oreg uchar to (u)longlong\n"
" move U1,$zero\n", },
{ SCONV, INAREG,
SOREG, TSHORT|TUSHORT,
SAREG, TCHAR,
NAREG, RESC1,
" lb A1,AL # convert oreg (u)short to char (endianness problem?)\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TSHORT|TUSHORT,
SAREG, TUCHAR,
NAREG, RESC1,
" lbu A1,AL # convert oreg (u)short to uchar (endianness problem?)\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TSHORT,
SAREG, TSWORD,
NAREG, RESC1,
" lh A1,AL # convert oreg short to int\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TSHORT,
SAREG, TUWORD,
NAREG, RESC1,
" lhu A1,AL # convert oreg short to uint\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TUSHORT,
SAREG, TWORD,
NAREG, RESC1,
" lhu A1,AL # convert oreg ushort to (u)int\n"
" nop\n", },
{ SCONV, INBREG,
SOREG, TSHORT,
SBREG, TLONGLONG,
NBREG, RESC1,
" lh A1,AL # convert oreg short to longlong\n"
" nop\n"
" sra U1,A1,31\n", },
{ SCONV, INBREG,
SOREG, TSHORT,
SBREG, TULONGLONG,
NBREG, RESC1,
" lhu A1,AL # convert oreg short to ulonglong\n"
" nop\n"
" move U1,$zero\n", },
{ SCONV, INBREG,
SOREG, TUSHORT,
SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lhu A1,AL # convert oreg ushort to (u)longlong\n"
" move U1,$zero\n", },
{ SCONV, INAREG,
SOREG, TWORD,
SAREG, TCHAR,
NAREG, RESC1,
" lb A1,AL # convert oreg word to char (endianness problem here?)\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TWORD,
SAREG, TUCHAR,
NAREG, RESC1,
" lbu A1,AL # convert oreg word to uchar (endianness problem here?)\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TWORD,
SAREG, TSHORT,
NAREG, RESC1,
" lh A1,AL # convert oreg word to short (endianness problem here?)\n"
" nop\n", },
/* convert (u)long to ushort */
{ SCONV, INAREG,
SOREG, TWORD,
SAREG, TUSHORT,
NAREG, RESC1,
" lhu A1,AL # convert oreg word to ushort (endianness problem here?)\n"
" nop\n", },
{ SCONV, INBREG,
SOREG, TSWORD,
SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw A1,AL # convert oreg int/long to (u)llong (endianness problem here?)\n"
" nop\n"
" sra U1,A1,31\n" },
{ SCONV, INBREG,
SOREG, TUWORD,
SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw A1,AL # convert oreg (u)int to (u)llong (endianness problem here?)\n"
" move U1,$zero\n", },
{ SCONV, INAREG,
SOREG, TLONGLONG|TULONGLONG,
SAREG, TCHAR,
NAREG, RESC1,
" lb A1,AL # convert oreg (u)llong to char (endianness problem here?)\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TLONGLONG|TULONGLONG,
SAREG, TUCHAR,
NAREG, RESC1,
" lbu A1,AL # convert oreg (u)llong to uchar (endianness problem?)\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TLONGLONG|TULONGLONG,
SAREG, TSHORT,
NAREG, RESC1,
" lh A1,AL # convert oreg (u)llong to short (endianness problem?)\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TLONGLONG|TULONGLONG,
SAREG, TUSHORT,
NAREG, RESC1,
" lhu A1,AL # convert oreg (u)llong to ushort (endianness problem here?)\n"
" nop\n", },
{ SCONV, INAREG,
SOREG, TLONGLONG|TULONGLONG,
SAREG, TWORD,
NAREG, RESC1,
" lw A1,AL # convert oreg (u)llong to (u)int (endianness problem here?)\n"
" nop\n", },
/*
* Conversions of integral types (register-register)
*
* For each deunsigned type, they look something like this:
*
* signed -> bigger signed - nothing to do
* signed -> bigger unsigned - clear the top bits (of source type)
*
* signed -> smaller signed - sign-extend the bits (to dest type)
* signed -> smaller unsigned - clear the top bits (of dest type)
* unsigned -> smaller signed - sign-extend top bits (to dest type)
* unsigned -> smaller unsigned - clear the top bits (of dest type)
*
* unsigned -> bigger - nothing to do
*/
{ SCONV, INAREG,
SAREG, TPOINT|TWORD,
SAREG, TPOINT|TWORD,
0, RLEFT,
" # convert int to int\n", },
{ SCONV, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
0, RLEFT,
" # convert (u)longlong to (u)longlong", },
{ SCONV, INAREG,
SAREG, TCHAR,
SAREG, TSWORD|TSHORT,
0, RLEFT,
" # convert char to short/int\n", },
{ SCONV, INAREG,
SAREG, TCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
NAREG|NASL, RESC1,
" andi A1,AL,255 # convert char to uchar/ushort/uint\n", },
{ SCONV, INAREG,
SAREG, TUCHAR,
SAREG, TCHAR,
NAREG|NASL, RESC1,
" sll A1,AL,24 # convert uchar to char\n"
" sra A1,A1,24\n", },
{ SCONV, INAREG,
SAREG, TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT,
0, RLEFT,
" # convert uchar to (u)short/(u)int\n", },
{ SCONV, INAREG,
SAREG, TSHORT,
SAREG, TCHAR,
NAREG|NASL, RESC1,
" sll A1,AL,24 # convert short to char\n"
" sra A1,A1,24\n", },
{ SCONV, INAREG,
SAREG, TSHORT,
SAREG, TUCHAR,
NAREG|NASL, RESC1,
" andi A1,AL,255 # convert short to uchar\n", },
{ SCONV, INAREG,
SAREG, TSHORT,
SAREG, TUWORD|TUSHORT,
NAREG|NASL, RESC1,
" andi A1,AL,65535 # convert short to ushort\n", },
{ SCONV, INAREG,
SAREG, TSHORT,
SAREG, TSWORD,
NAREG|NASL, RESC1,
" sll A1,AL,16 # convert short to ushort\n"
" sra A1,A1,16\n", },
{ SCONV, INAREG,
SAREG, TUSHORT,
SAREG, TCHAR,
NAREG|NASL, RESC1,
" sll A1,AL,24 # convert short to char\n"
" sra A1,A1,24\n", },
{ SCONV, INAREG,
SAREG, TUSHORT,
SAREG, TUCHAR,
NAREG|NASL, RESC1,
" andi A1,AL,255 # convert ushort to char\n", },
{ SCONV, INAREG,
SAREG, TUSHORT,
SAREG, TSHORT,
NAREG|NASL, RESC1,
" sll A1,AL,16 # convert short to ushort\n"
" sra A1,A1,16\n", },
{ SCONV, INAREG,
SAREG, TUSHORT,
SAREG, TWORD,
0, RDEST,
" # convert ushort to (u)int\n", },
{ SCONV, INAREG,
SAREG, TSWORD,
SAREG, TCHAR,
NAREG|NASL, RESC1,
" sll A1,AL,8 # convert int to char\n"
" sra A1,A1,8\n", },
{ SCONV, INAREG,
SAREG, TSWORD,
SAREG, TUCHAR,
NAREG|NASL, RESC1,
" andi A1,AL,255 # convert int to uchar\n", },
{ SCONV, INAREG,
SAREG, TSWORD,
SAREG, TSHORT,
NAREG|NASL, RESC1,
" sll A1,AL,16 # convert int to short\n"
" sra A1,A1,16\n", },
{ SCONV, INAREG,
SAREG, TSWORD,
SAREG, TUSHORT,
NAREG|NASL, RESC1,
" andi A1,AL,65535 # convert int to ushort\n", },
{ SCONV, INAREG,
SAREG, TUWORD,
SAREG, TCHAR,
NAREG|NASL, RESC1,
" sll A1,AL,24 # convert int to char\n"
" sra A1,A1,24\n", },
{ SCONV, INAREG,
SAREG, TUWORD,
SAREG, TUCHAR,
NAREG|NASL, RESC1,
" andi A1,AL,255 # convert int to uchar\n", },
{ SCONV, INAREG,
SAREG, TUWORD,
SAREG, TSHORT,
NAREG|NASL, RESC1,
" sll A1,AL,16 # convert int to short\n"
" sra A1,A1,16\n", },
{ SCONV, INAREG,
SAREG, TUWORD,
SAREG, TUSHORT,
NAREG|NASL, RESC1,
" andi A1,AL,65535 # convert int to ushort\n", },
{ SCONV, INBREG,
SAREG, TSWORD|TSHORT|TCHAR,
SBREG, TLONGLONG,
NBREG, RESC1,
" move A1,AL # convert int/short/char to longlong\n"
" sra U1,AL,31\n", },
{ SCONV, INBREG,
SAREG, TSWORD|TSHORT|TCHAR,
SBREG, TULONGLONG,
NBREG, RESC1,
" move A1,AL # convert int/short/char to ulonglong\n"
" move U1,$zero\n", },
{ SCONV, INBREG,
SAREG, TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
SBREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" move A1,AL # convert (u)int/(u)short/(u)char to ulonglong\n"
" move U1,$zero\n", },
{ SCONV, INAREG,
SBREG, TLONGLONG|TULONGLONG,
SAREG, TWORD,
NAREG, RESC1,
" move A1,AL # convert (u)longlong to int\n", },
{ SCONV, INAREG,
SBREG, TLONGLONG|TULONGLONG,
SAREG, TSHORT,
NAREG, RESC1,
" sll A1,AL,16 # convert (u)longlong to short\n"
" sra A1,AL,16\n", },
{ SCONV, INAREG,
SBREG, TLONGLONG|TULONGLONG,
SAREG, TCHAR,
NAREG, RESC1,
" sll A1,AL,24 # convert (u)longlong to char\n"
" sra A1,AL,24\n", },
{ SCONV, INAREG,
SBREG, TLONGLONG|TULONGLONG,
SAREG, TUSHORT,
NAREG, RESC1,
" andi A1,AL,65535 # convert (u)longlong to ushort\n", },
{ SCONV, INAREG,
SBREG, TLONGLONG|TULONGLONG,
SAREG, TUCHAR,
NAREG, RESC1,
" andi A1,AL,255 # convert (u)longlong to uchar\n", },
{ SCONV, INCREG,
SCREG, TFLOAT,
SCREG, TDOUBLE|TLDOUBLE,
NCREG, RESC1,
" cvt.d.s A1,AL # convert float to (l)double\n", },
{ SCONV, INCREG,
SCREG, TDOUBLE|TLDOUBLE,
SCREG, TFLOAT,
NCREG, RESC1,
" cvt.s.d A1,AL # convert (l)double to float\n", },
{ SCONV, INCREG,
SAREG, TWORD,
SCREG, TFLOAT,
NCREG, RESC1,
" mtc1 AL,A1 # convert (u)int to float\n"
" nop\n"
" cvt.s.w A1,A1\n", },
{ SCONV, INCREG,
SOREG, TWORD,
SCREG, TFLOAT,
NCREG, RESC1,
" l.s A1,AL # convert (u)int to float\n"
" nop\n"
" cvt.s.w A1,A1\n", },
{ SCONV, INCREG,
SAREG, TWORD,
SCREG, TDOUBLE|TLDOUBLE,
NCREG, RESC1,
" mtc1 AL,A1 # convert (u)int to (l)double\n"
" nop\n"
" cvt.d.w A1,A1\n", },
{ SCONV, INCREG,
SOREG, TWORD,
SCREG, TDOUBLE|TLDOUBLE,
NCREG, RESC1,
" l.d A1,AL # convert (u)int to (l)double\n"
" nop\n"
" cvt.d.w A1,A1\n", },
{ SCONV, INAREG,
SCREG, TFLOAT,
SAREG, TWORD,
NCREG|NAREG, RESC1,
" cvt.w.s A2,AL # convert float to (u)int\n"
" mfc1 A1,A2\n"
" nop\n", },
{ SCONV, FOREFF,
SCREG, TFLOAT,
SOREG, TWORD,
NCREG, RDEST,
" cvt.w.s A1,AL # convert float to (u)int\n"
" s.s A1,AR\n"
" nop\n", },
{ SCONV, INAREG,
SCREG, TDOUBLE|TLDOUBLE,
SAREG, TWORD,
NCREG|NAREG, RESC1,
" cvt.w.d A2,AL # convert (l)double to (u)int\n"
" mfc1 A1,A2\n"
" nop\n", },
{ SCONV, INCREG,
SCREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
0, RLEFT,
" # convert between double and ldouble\n", },
{ SCONV, INCREG,
SBREG, TLONGLONG|TULONGLONG,
SCREG, TFLOAT,
NSPECIAL|NCREG, RESC1,
"ZF", },
{ SCONV, INCREG,
SBREG, TLONGLONG|TULONGLONG,
SCREG, TDOUBLE|TLDOUBLE,
NSPECIAL|NCREG, RESC1,
"ZF", },
{ SCONV, INBREG,
SCREG, TDOUBLE|TLDOUBLE,
SBREG, TLONGLONG|TULONGLONG,
NSPECIAL|NBREG, RESC1,
"ZF", },
{ SCONV, INBREG,
SCREG, TFLOAT,
SBREG, TLONGLONG|TULONGLONG,
NSPECIAL|NBREG, RESC1,
"ZF", },
/*
* Multiplication and division
*/
{ MUL, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
NAREG|NASR|NASL, RESC1,
" multu AL,AR # unsigned multiply\n"
" mflo A1\n"
" nop\n"
" nop\n", },
/* this previous will match on unsigned/unsigned multiplication first */
{ MUL, INAREG,
SAREG, TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
SAREG, TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
NAREG|NASR|NASL, RESC1,
" mult AL,AR # signed multiply\n"
" mflo A1\n"
" nop\n"
" nop\n", },
{ MUL, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
2*NBREG, RESC1,
" multu AL,AR\n"
" mfhi U1\n"
" mflo A1\n"
" mult AL,UR\n"
" mflo A2\n"
" nop\n"
" nop\n"
" addu A2,U1,A2\n"
" mult UL,AR\n"
" mflo U2\n"
" nop\n"
" nop\n"
" addu U1,A2,U2\n", },
{ MUL, INCREG,
SCREG, TFLOAT,
SCREG, TFLOAT,
NCREG, RESC1,
" mul.s A1,AL,AR # floating-point multiply\n", },
{ MUL, INCREG,
SCREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
NCREG, RESC1,
" mul.d A1,AL,AR # double-floating-point multiply\n", },
{ DIV, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
NAREG|NASR|NASL, RESC1,
" divu AL,AR # unsigned division\n"
" mflo A1\n"
" nop\n"
" nop\n", },
/* the previous rule will match unsigned/unsigned first */
{ DIV, INAREG,
SAREG, TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
SAREG, TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
NAREG|NASR|NASL, RESC1,
" div AL,AR # signed division\n"
" mflo A1\n"
" nop\n"
" nop\n", },
{ DIV, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NSPECIAL|NBREG, RESC1,
"ZE", },
{ DIV, INCREG,
SCREG, TFLOAT,
SCREG, TFLOAT,
NCREG, RESC1,
" div.s A1,AL,AR # floating-point division\n", },
{ DIV, INCREG,
SCREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
NCREG, RESC1,
" div.d A1,AL,AR # double-floating-point division\n", },
{ MOD, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
NAREG, RESC1,
" divu AL,AR # signed modulo\n"
" mfhi A1\n"
" nop\n"
" nop\n", },
/* the previous rule will match unsigned%unsigned first */
{ MOD, INAREG,
SAREG, TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
SAREG, TWORD|TUSHORT|TSHORT|TUCHAR|TCHAR,
NAREG, RESC1,
" div AL,AR # signed modulo\n"
" mfhi A1\n"
" nop\n"
" nop\n", },
{ MOD, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NSPECIAL|NBREG, RESC1,
"ZE", },
/*
* Templates for unsigned values needs to come before OPSIMP
*/
{ PLUS, INBREG,
SBREG, TULONGLONG|TLONGLONG,
SBREG, TULONGLONG|TLONGLONG,
2*NBREG, RESC1,
" addu A1,AL,AR # 64-bit addition\n"
" sltu A2,A1,AR\n"
" addu U1,UL,UR\n"
" addu U1,U1,A2\n", },
{ PLUS, INAREG,
SAREG, TSWORD|TSHORT|TCHAR,
SAREG, TSWORD|TSHORT|TCHAR,
NAREG|NASL, RESC1,
" add A1,AL,AR\n", },
{ PLUS, INAREG,
SAREG, TSWORD|TSHORT|TCHAR,
SSCON, TWORD,
NAREG|NASL, RESC1,
" addi A1,AL,AR\n", },
{ PLUS, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SSCON, TWORD,
NAREG|NASL, RESC1,
" addiu A1,AL,AR\n", },
{ PLUS, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
NAREG|NASL, RESC1,
" addu A1,AL,AR\n", },
{ PLUS, INCREG,
SCREG, TFLOAT,
SCREG, TFLOAT,
NCREG|NCSL, RESC1,
" add.s A1,AL,AR\n", },
{ PLUS, INCREG,
SCREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
NCREG|NCSL, RESC1,
" add.d A1,AL,AR\n", },
{ MINUS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
2*NBREG, RESC1,
" sltu A2,AL,AR # 64-bit subtraction\n"
" subu A1,AL,AR\n"
" subu U1,UL,UR\n"
" subu U1,U1,A2\n", },
{ MINUS, INAREG,
SAREG, TSWORD|TSHORT|TCHAR,
SAREG, TSWORD|TSHORT|TCHAR,
NAREG|NASL, RESC1,
" sub A1,AL,AR\n", },
{ MINUS, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TUWORD|TUSHORT|TUCHAR,
NAREG|NASL, RESC1,
" subu A1,AL,AR\n", },
{ MINUS, INAREG,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SSCON, TANY,
NAREG|NASL, RESC1,
" subu A1,AL,AR\n", },
{ MINUS, INCREG,
SCREG, TFLOAT,
SCREG, TFLOAT,
NCREG|NCSL, RESC1,
" sub.s A1,AL,AR\n", },
{ MINUS, INCREG,
SCREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
NCREG|NCSL, RESC1,
" sub.d A1,AL,AR\n", },
{ UMINUS, INAREG,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SANY, TANY,
NAREG|NASL, RESC1,
" neg A1,AL\n", },
{ UMINUS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SANY, TANY,
NBREG|NAREG|NBSL, RESC1,
" subu A1,$zero,AL\n"
" subu U1,$zero,UL\n"
" sltu A2,$zero,A1\n"
" subu U1,U1,A2\n", },
{ UMINUS, INCREG,
SCREG, TFLOAT,
SCREG, TFLOAT,
NCREG|NCSL, RESC1,
" neg.s A1,AL\n", },
{ UMINUS, INCREG,
SCREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
NCREG|NCSL, RESC1,
" neg.d A1,AL\n", },
/* Simple 'op rd, rs, rt' or 'op rt, rs, imm' operations */
{ OPSIMP, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NBREG|NBSR|NBSL, RESC1,
" O A1,AL,AR\n"
" O U1,UL,UR\n", },
{ OPSIMP, INAREG,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TUCHAR|TCHAR,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TUCHAR|TCHAR,
NAREG|NASR|NASL, RESC1,
" O A1,AL,AR\n", },
{ OPSIMP, INAREG,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TUCHAR|TCHAR,
SPCON, TSHORT|TUSHORT|TUCHAR|TCHAR,
NAREG|NASL, RESC1,
" Oi A1,AL,AR\n", },
/*
* Shift instructions
*/
{ RS, INAREG,
SAREG, TSWORD|TSHORT|TCHAR,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" sra A1,AL,AR # shift right by constant\n", },
{ RS, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" srl A1,AL,AR # shift right by constant\n", },
{ LS, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" sll A1,AL,AR # shift left by constant\n", },
{ RS, INAREG,
SAREG, TSWORD|TSHORT|TCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" srav A1,AL,AR # shift right by register\n", },
{ RS, INAREG,
SAREG, TUWORD|TUSHORT|TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" srlv A1,AL,AR # shift right by register\n", },
{ LS, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" sllv A1,AL,AR # shift left by register\n", },
{ RS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NBREG, RESC1,
"ZO", },
{ LS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NBREG, RESC1,
"ZO", },
{ RS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NSPECIAL|NBREG, RESC1,
"ZE", },
{ LS, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NSPECIAL|NBREG, RESC1,
"ZE", },
/*
* Rule for unary one's complement
*/
{ COMPL, INAREG,
SAREG, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
SANY, TANY,
NAREG|NASL, RESC1,
" nor A1,$zero,AL # complement\n", },
{ COMPL, INBREG,
SBREG, TLONGLONG|TULONGLONG,
SANY, TANY,
NBREG|NBSL, RESC1,
" nor A1,$zero,AL # complement\n"
" nor U1,$zero,UL\n", },
/*
* The next rules takes care of assignments. "=".
*/
{ ASSIGN, FOREFF|INAREG,
SOREG|SNAME, TWORD|TPOINT,
SAREG, TWORD|TPOINT,
0, RDEST,
" sw AR,AL # store (u)int/(u)long\n"
" nop\n", },
{ ASSIGN, FOREFF|INAREG,
SOREG|SNAME, TSHORT|TUSHORT,
SAREG, TSHORT|TUSHORT,
0, RDEST,
" sh AR,AL # store (u)short\n"
" nop\n", },
{ ASSIGN, FOREFF|INAREG,
SOREG|SNAME, TCHAR|TUCHAR,
SAREG, TCHAR|TUCHAR,
0, RDEST,
" sb AR,AL # store (u)char\n"
" nop\n", },
{ ASSIGN, FOREFF|INBREG,
SOREG|SNAME, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
0, RDEST,
" sw UR,UL # store (u)longlong\n"
" nop\n"
" sw AR,AL\n"
" nop\n", },
{ ASSIGN, FOREFF|INBREG,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
0, RDEST,
" move UL,UR # register move\n"
" move AL,AR\n", },
{ ASSIGN, FOREFF|INAREG,
SAREG, TANY,
SAREG, TANY,
0, RDEST,
" move AL,AR # register move\n", },
{ ASSIGN, FOREFF|INCREG,
SCREG, TFLOAT,
SCREG, TFLOAT,
0, RDEST,
" mov.s AL,AR # register move\n", },
{ ASSIGN, FOREFF|INCREG,
SCREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
0, RDEST,
" mov.d AL,AR # register move\n", },
{ ASSIGN, FOREFF|INCREG,
SNAME|SOREG, TFLOAT,
SCREG, TFLOAT,
0, RDEST,
" s.s AR,AL # store floating-point reg to oreg/sname\n"
" nop\n", },
{ ASSIGN, FOREFF|INCREG,
SNAME|SOREG, TDOUBLE|TLDOUBLE,
SCREG, TDOUBLE|TLDOUBLE,
0, RDEST,
" s.d AR,AL # store double floating-point reg to oreg/sname\n"
" nop\n", },
{ ASSIGN, FOREFF|INAREG,
SFLD, TANY,
SOREG|SNAME, TANY,
3*NAREG, RDEST,
" lw A1,AR # bit-field assignment\n"
" li A3,M\n"
" lw A2,AL\n"
" sll A1,A1,H\n"
" and A1,A1,A3\n"
" nor A3,$zero,A3\n"
" and A2,A2,A3\n"
" or A2,A2,A1\n"
" sw A2,AL\n"
"F lw AD,AR\n"
"F nop\n"
"F sll AD,AD,32-S\n"
"F sra AD,AD,32-S\n", },
/* XXX we can optimise this away */
{ ASSIGN, FOREFF|INAREG,
SFLD, TANY,
SCON, TANY,
3*NAREG, RDEST,
" li A1,AR # bit-field assignment\n"
" lw A2,AL\n"
" li A3,M\n"
" sll A1,A1,H\n"
" and A1,A1,A3\n"
" nor A3,$zero,A3\n"
" and A2,A2,A3\n"
" or A2,A2,A1\n"
" sw A2,AL\n"
"F li AD,AR\n"
"F sll AD,AD,32-S\n"
"F sra AD,AD,32-S\n", },
{ ASSIGN, FOREFF|INAREG,
SFLD, TANY,
SAREG, TANY,
3*NAREG, RDEST,
" move A1,AR # bit-field assignment\n"
" lw A2,AL\n"
" li A3,M\n"
" sll A1,A1,H\n"
" and A1,A1,A3\n"
" nor A3,$zero,A3\n"
" and A2,A2,A3\n"
" or A2,A2,A1\n"
" sw A2,AL\n"
"F move AR,AD\n"
"F sll AD,AD,32-S\n"
"F sra AD,AD,32-S\n", },
{ STASG, INAREG|FOREFF,
SOREG|SNAME, TANY,
SAREG, TPTRTO|TANY,
NSPECIAL, RRIGHT,
"ZQ", },
/*
* Compare instructions
*/
{ EQ, FORCC,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
0, RESCC,
" beq AL,AR,LC\n"
" nop\n", },
{ NE, FORCC,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
0, RESCC,
" bne AL,AR,LC\n"
" nop\n", },
{ OPLOG, FORCC,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SZERO, TANY,
0, RESCC,
" O AL,LC\n"
" nop\n", },
{ OPLOG, FORCC,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESCC,
" sub A1,AL,AR\n"
" O A1,LC\n"
" nop\n", },
{ OPLOG, FORCC,
SAREG, TWORD|TPOINT|TSHORT|TUSHORT|TCHAR|TUCHAR,
SSCON, TWORD|TSHORT|TUSHORT|TCHAR|TUCHAR,
NAREG|NASL, RESCC,
" sub A1,AL,AR\n"
" O A1,LC\n"
" nop\n", },
{ OPLOG, FORCC,
SBREG, TLONGLONG|TULONGLONG,
SBREG, TLONGLONG|TULONGLONG,
NAREG, RESCC,
"ZD", },
{ OPLOG, FORCC,
SCREG, TFLOAT|TDOUBLE|TLDOUBLE,
SCREG, TFLOAT|TDOUBLE|TLDOUBLE,
0, RESCC,
"ZG", },
/*
* Convert LTYPE to reg.
*/
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG|SNAME, TCHAR,
NAREG, RESC1,
" lb A1,AL # load char to reg\n"
" nop\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG|SNAME, TUCHAR,
NAREG, RESC1,
" lbu A1,AL # load uchar to reg\n"
" nop\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG|SNAME, TSHORT,
NAREG, RESC1,
" lh A1,AL # load short to reg\n"
" nop\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG|SNAME, TUSHORT,
NAREG, RESC1,
" lhu A1,AL # load ushort to reg\n"
" nop\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SOREG|SNAME, TWORD|TPOINT,
NAREG, RESC1,
" lw A1,AL # load (u)int/(u)long to reg\n"
" nop\n", },
{ OPLTYPE, INBREG,
SANY, TANY,
SOREG|SNAME, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw U1,UL # load (u)longlong to reg\n"
" nop\n"
" lw A1,AL\n"
" nop\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SCON, TPOINT,
NAREG, RESC1,
" la A1,AL # load constant address to reg\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SZERO, TANY,
NAREG, RESC1,
" move A1,$zero # load 0 to reg\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SCON, TANY,
NAREG, RESC1,
" li A1,AL # load constant to reg\n", },
{ OPLTYPE, INBREG,
SANY, TANY,
SZERO, TANY,
NBREG, RESC1,
" move A1,$zero # load 0 to reg\n"
" move U1,$zero\n", },
{ OPLTYPE, INBREG,
SANY, TANY,
SCON, TANY,
NBREG, RESC1,
" li A1,AL # load constant to reg\n"
" li U1,UL\n", },
{ OPLTYPE, INAREG,
SANY, TANY,
SANY, TANY,
NAREG, RESC1,
" move A1,AL\n", },
{ OPLTYPE, INCREG,
SANY, TANY,
SZERO, TFLOAT,
NCREG, RESC1,
" mtc1 $zero,A1 # load 0 to float reg\n"
" nop\n", },
{ OPLTYPE, INCREG,
SANY, TANY,
SZERO, TDOUBLE|TLDOUBLE,
NCREG, RESC1,
" mtc1 $zero,A1 # load 0 to (l)double reg\n"
" mtc1 $zero,U1\n"
" nop\n", },
{ OPLTYPE, INCREG,
SANY, TANY,
SOREG|SNAME, TFLOAT,
NCREG, RESC1,
" l.s A1,AL # load into floating-point reg\n"
" nop\n", },
{ OPLTYPE, INCREG,
SANY, TANY,
OREG|SNAME, TDOUBLE|TLDOUBLE,
NCREG, RESC1,
" l.d A1,AL # load into double floating-point reg\n"
" nop\n", },
/*
* Jumps.
*/
{ GOTO, FOREFF,
SCON, TANY,
SANY, TANY,
0, RNOP,
" j LL # goto label\n"
" nop\n"
" nop\n", },
/*
* Subroutine calls.
*/
{ CALL, FOREFF,
SCON, TANY,
SANY, TANY,
0, 0,
" subu $sp,$sp,16 # call (args, no result) to scon/sname\n"
" jal CL\n"
" nop\n"
"ZC", },
{ UCALL, FOREFF,
SCON, TANY,
SANY, TANY,
0, 0,
" jal CL # call (no args, no result) to scon/sname\n"
" nop\n", },
{ CALL, INAREG,
SCON, TANY,
SAREG, TANY,
NAREG, RESC1, /* should be 0 */
" subu $sp,$sp,16 # call (args, result in v0) to scon/sname\n"
" jal CL\n"
" nop\n"
"ZC", },
{ UCALL, INAREG,
SCON, TANY,
SAREG, TANY,
NAREG, RESC1, /* should be 0 */
" jal CL # call (no args, result in v0) to scon/sname\n"
" nop\n",
},
{ CALL, INBREG,
SCON, TANY,
SBREG, TANY,
NBREG, RESC1, /* should be 0 */
" subu $sp,$sp,16 # call (args, result in v0:v1) to scon/sname\n"
" jal CL\n"
" nop\n"
"ZC", },
{ UCALL, INBREG,
SCON, TANY,
SBREG, TANY,
NBREG, RESC1, /* should be 0 */
" jal CL # call (no args, result in v0:v1) to scon/sname\n"
" nop\n",
},
{ CALL, INCREG,
SCON, TANY,
SCREG, TANY,
NCREG, RESC1, /* should be 0 */
" subu $sp,$sp,16 # call (args, result in f0:f1) to scon/sname\n"
" jal CL\n"
" nop\n"
"ZC", },
{ UCALL, INCREG,
SCON, TANY,
SCREG, TANY,
NCREG, RESC1, /* should be 0 */
" jal CL # call (no args, result in v0:v1) to scon/sname\n"
" nop\n",
},
{ CALL, FOREFF,
SAREG, TANY,
SANY, TANY,
0, 0,
" subu $sp,$sp,16 # call (args, no result) to reg\n"
" move $25,AL\n"
" jal $25\n"
" nop\n"
"ZC", },
{ UCALL, FOREFF,
SAREG, TANY,
SANY, TANY,
0, 0,
" move $25,AL\n"
" jal $25 # call (no args, no result) to reg\n"
" nop\n", },
{ CALL, INAREG,
SAREG, TANY,
SAREG, TANY,
NAREG, RESC1, /* should be 0 */
" subu $sp,$sp,16 # call (args, result) to reg\n"
" move $25,AL\n"
" jal $25\n"
" nop\n"
"ZC", },
{ UCALL, INAREG,
SAREG, TANY,
SAREG, TANY,
NAREG, RESC1, /* should be 0 */
" move $25,AL\n"
" jal $25 # call (no args, result) to reg\n"
" nop\n", },
{ CALL, INBREG,
SAREG, TANY,
SBREG, TANY,
NBREG, RESC1, /* should be 0 */
" subu $sp,$sp,16 # call (args, result) to reg\n"
" move $25,AL\n"
" jal $25\n"
" nop\n"
"ZC", },
{ UCALL, INBREG,
SAREG, TANY,
SBREG, TANY,
NBREG, RESC1, /* should be 0 */
" move $25,AL\n"
" jal $25 # call (no args, result) to reg\n"
" nop\n", },
{ CALL, INCREG,
SAREG, TANY,
SCREG, TANY,
NCREG, RESC1, /* should be 0 */
" subu $sp,$sp,16 # call (args, result) to reg\n"
" move $25,AL\n"
" jal $25\n"
" nop\n"
"ZC", },
{ UCALL, INCREG,
SCREG, TANY,
SCREG, TANY,
NCREG, RESC1, /* should be 0 */
" move $25,AL\n"
" jal $25 # call (no args, result) to reg\n"
" nop\n", },
/* struct return */
{ USTCALL, FOREFF,
SCON|SNAME, TANY,
SANY, TANY,
0, 0,
" jal CL\n"
" nop\n", },
{ USTCALL, FOREFF,
SAREG, TANY,
SANY, TANY,
0, 0,
" move $25,AL\n"
" jal $25\n"
" nop\n", },
{ USTCALL, INAREG,
SCON|SNAME, TANY,
SANY, TANY,
NAREG|NASL, RESC1,
" jal CL\n"
" nop\n", },
{ USTCALL, INAREG,
SAREG, TANY,
SANY, TANY,
NAREG|NASL, RESC1,
" move $25,AL\n"
" jal $25\n"
" nop\n", },
{ STCALL, FOREFF,
SCON|SNAME, TANY,
SANY, TANY,
0, 0,
" jal CL\n"
" nop\n"
"ZC", },
{ STCALL, FOREFF,
SAREG, TANY,
SANY, TANY,
0, 0,
" move $25,AL\n"
" jal $25\n"
" nop\n"
"ZC", },
{ STCALL, INAREG,
SCON|SNAME, TANY,
SANY, TANY,
NAREG|NASL, RESC1,
" jal CL\n"
" nop\n"
"ZC", },
{ STCALL, INAREG,
SAREG, TANY,
SANY, TANY,
0, 0,
" move $25,AL\n"
" jal $25\n"
" nop\n"
"ZC", },
/*
* Function arguments
*/
/* intentionally write out the register for (u)short/(u)char */
{ FUNARG, FOREFF,
SAREG, TWORD|TPOINT|TUSHORT|TSHORT|TUCHAR|TCHAR,
SANY, TWORD|TPOINT|TUSHORT|TSHORT|TUCHAR|TCHAR,
0, 0,
" subu $sp,$sp,4 # save function arg to stack\n"
" sw AL,($sp)\n"
" #nop\n", },
{ FUNARG, FOREFF,
SBREG, TLONGLONG|TULONGLONG,
SANY, TLONGLONG|TULONGLONG,
0, 0,
" addi $sp,$sp,-8 # save function arg to stack (endian problem here?\n"
" sw UL,4($sp)\n"
" sw AL,($sp)\n"
" #nop\n", },
{ FUNARG, FOREFF,
SCREG, TFLOAT,
SANY, TFLOAT,
0, 0,
" addi $sp,$sp,-4 # save function arg to stack\n"
" s.s AL,($sp)\n"
" #nop\n", },
{ FUNARG, FOREFF,
SCREG, TDOUBLE|TLDOUBLE,
SANY, TDOUBLE|TLDOUBLE,
0, 0,
" addi $sp,$sp,-8 # save function arg to stack\n"
" s.d AL,($sp)\n"
" #nop\n", },
{ STARG, FOREFF,
SAREG, TANY,
SANY, TSTRUCT,
NSPECIAL, 0,
"ZH", },
/*
* Indirection operators.
*/
{ UMUL, INAREG,
SANY, TPOINT|TWORD,
SOREG, TPOINT|TWORD,
NAREG, RESC1,
" lw A1,AL # word load\n"
" nop\n", },
{ UMUL, INAREG,
SANY, TSHORT|TUSHORT,
SOREG, TSHORT|TUSHORT,
NAREG, RESC1,
" lh A1,AL # (u)short load\n"
" nop\n", },
{ UMUL, INAREG,
SANY, TCHAR|TUCHAR,
SOREG, TCHAR|TUCHAR,
NAREG, RESC1,
" lb A1,AL # (u)char load\n"
" nop\n", },
{ UMUL, INBREG,
SANY, TLONGLONG|TULONGLONG,
SOREG, TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw A1,AL # (u)longlong load - endian problem here?\n"
" nop\n"
" lw U1,UL\n"
" nop\n", },
{ UMUL, INCREG,
SANY, TFLOAT,
SOREG, TFLOAT,
NCREG, RESC1,
" l.s A1,AL # float load\n"
" nop\n", },
{ UMUL, INCREG,
SANY, TDOUBLE|TLDOUBLE,
SOREG, TDOUBLE|TLDOUBLE,
NCREG, RESC1,
" l.d A1,AL # float load\n"
" nop\n", },
#if 0
{ UMUL, INCREG,
SANY, TDOUBLE|TLDOUBLE,
SAREG, TPOINT,
NCREG, RESC1,
" l.d A1,(AL)\n"
" nop\n", },
{ UMUL, INAREG,
SANY, TPOINT|TWORD,
SNAME, TPOINT|TWORD,
NAREG, RESC1,
" la A1,AL # sname word load\n"
" lw A1,(A1)\n"
" nop\n", },
{ UMUL, INAREG,
SANY, TSHORT|TUSHORT,
SNAME, TSHORT|TUSHORT,
NAREG, RESC1,
" la A1,AL # sname (u)short load\n"
" lh A1,(A1)\n"
" nop\n", },
{ UMUL, INAREG,
SANY, TCHAR|TUCHAR,
SNAME, TCHAR|TUCHAR,
NAREG, RESC1,
" la A1,AL # sname (u)char load\n"
" lb A1,(A1)\n"
" nop\n", },
{ UMUL, INBREG,
SANY, TLONGLONG|TULONGLONG,
SNAME, TLONGLONG|TULONGLONG,
NBREG|NAREG, RESC1,
" la A2,AL # sname (u)long long load - endian problems here?\n"
" lw A1,(A1)\n"
" nop\n"
" lw U1,4(A1)\n"
" nop\n", },
#endif
{ UMUL, INAREG,
SANY, TPOINT|TWORD,
SAREG, TPOINT|TWORD,
NAREG, RESC1,
" lw A1,(AL) # word load\n"
" nop\n", },
#if 0
{ UMUL, INAREG,
SANY, TSHORT|TUSHORT,
SAREG, TPTRTO|TSHORT|TUSHORT,
NAREG, RESC1,
" lh A1,(AL) # (u)short load\n"
" nop\n", },
{ UMUL, INAREG,
SANY, TCHAR|TUCHAR,
SAREG, TPTRTO|TCHAR|TUCHAR,
NAREG|NASL, RESC1,
" lb A1,(AL) # (u)char load\n"
" nop\n", },
{ UMUL, INBREG,
SANY, TLONGLONG|TULONGLONG,
SAREG, TPTRTO|TLONGLONG|TULONGLONG,
NBREG, RESC1,
" lw A1,(AL) # (u)long long load - endianness problems?\n"
" nop\n"
" lw U1,4(AL)"
" nop\n", },
#endif
#define DF(x) FORREW,SANY,TANY,SANY,TANY,REWRITE,x,""
{ FLD, DF(FLD), },
{ FREE, FREE, FREE, FREE, FREE, FREE, FREE, FREE, "help; I'm in trouble\n" },
};
int tablesize = sizeof(table)/sizeof(table[0]);