36f16b0cb8
Edit C code to reduce warnings from clang. Most warnings are for
implicit declarations of functions, but some warnings want me to add
parentheses or curly braces, or to cast arguments for printf().
Make a few other changes, like declaring float_cst() in h/con_float to
be static, and using C99 bool in ego/ra/makeitems.c and
ego/share/makecldef.c. Such changes don't silence warnings; I make
such changes while I silence warnings in the same file. In
float_cst(), rename parameter `str` to `float_str`, so it doesn't
share a name with the global variable `str`.
Remove `const` from `newmodule(const char *)` in mach/proto/as to
silence a warning. I wrongly added the `const` in d347207
.
For warnings about implicit declarations of functions, the fix is to
declare the function before calling it. For example, my OpenBSD
system needs <sys/wait.h> to declare wait().
In util/int, add "whatever.h" to declare more functions. Remove old
declarations from "mem.h", to prefer the newer declarations of the
same functions in "data.h" and "stack.h".
7353 lines
204 KiB
Plaintext
7353 lines
204 KiB
Plaintext
/*
|
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
*/
|
|
|
|
rscid = "$Id$"
|
|
|
|
/********************************
|
|
* *
|
|
* 68000, 68010 and 68020 *
|
|
* back end table *
|
|
* *
|
|
********************************/
|
|
|
|
#include "whichone.h"
|
|
|
|
#if TBL68881 && ! TBL68020
|
|
Something very wrong here!
|
|
#endif
|
|
#if WORD_SIZE!=2 && WORD_SIZE!=4
|
|
Something very wrong here!
|
|
#endif
|
|
|
|
#if TBL68020
|
|
#define SYNTAX_68020 1
|
|
#endif
|
|
|
|
/* #define FANCY_MODES 1 */
|
|
/* On the M68020, there are some real fancy addressing modes.
|
|
Their use makes the code a bit shorter, but also much slower.
|
|
The FANCY_MODES #define enables the use of these addressing
|
|
modes.
|
|
*/
|
|
|
|
#define small(x) ((x)>=1 && (x)<=8)
|
|
#define directadd(x) (small(x) || (x)>128)
|
|
#define directsub(x) (directadd(0-x))
|
|
#define nicesize(x) ((x)==1||(x)==2||(x)==4||(x)==8)
|
|
#define low8(x) ((x) & 0377)
|
|
#define low16(x) ((x) & 0177777)
|
|
#define in_1(x) sfit(x,8)
|
|
#define in_2(x) sfit(x,16)
|
|
|
|
|
|
EM_WSIZE = WORD_SIZE
|
|
EM_PSIZE = 4
|
|
EM_BSIZE = 8
|
|
|
|
SL = 8
|
|
|
|
TIMEFACTOR = 1/2
|
|
|
|
|
|
PROPERTIES
|
|
|
|
D_REG /* data registers */
|
|
A_REG(4) /* address registers */
|
|
DD_REG /* allocatable D_REG, may not be a register variable */
|
|
AA_REG(4) /* allocatable A_REG, may not be a register variable */
|
|
RD_REG /* data register, register var */
|
|
RA_REG(4) /* address register, register var */
|
|
#if WORD_SIZE==2
|
|
D_REG4(4) /* data register, 4 bytes */
|
|
DD_REG4(4) /* allocatable D_REG, 4 bytes */
|
|
#else
|
|
#define D_REG4 D_REG
|
|
#define DD_REG4 DD_REG
|
|
#endif
|
|
#if TBL68881
|
|
FS_REG(4) /* floating point register */
|
|
FD_REG(8) /* double floating point register */
|
|
#endif
|
|
|
|
|
|
|
|
REGISTERS
|
|
|
|
d0, d1, d2 :D_REG, DD_REG.
|
|
d3, d4, d5, d6, d7 :D_REG, RD_REG regvar.
|
|
#if WORD_SIZE==2
|
|
dl0("d0")=d0, dl1("d1")=d1, dl2("d2")=d2 :D_REG4, DD_REG4.
|
|
#else
|
|
#define dl0 d0
|
|
#define dl1 d1
|
|
#define dl2 d2
|
|
#endif
|
|
a0, a1 :A_REG, AA_REG.
|
|
a2, a3, a4, a5 :A_REG, RA_REG regvar(reg_pointer).
|
|
lb ("a6"), sp :A_REG. /* localbase and stack pointer */
|
|
#if TBL68881
|
|
F0 ("fp0"), F1 ("fp1"), F2 ("fp2"), F3 ("fp3"), F4 ("fp4"), F5 ("fp5"),
|
|
F6 ("fp6"), F7 ("fp7") :FS_REG.
|
|
fp0=F0,fp1=F1,fp2=F2,fp3=F3,fp4=F4,fp5=F5,fp6=F6,fp7=F7
|
|
:FD_REG.
|
|
#endif
|
|
|
|
|
|
|
|
TOKENS
|
|
|
|
/* Not all addressing modes available on the MC68020 are used in this
|
|
* table. E.g (Dn), data register indirect is not used. Compared to
|
|
* (An), address register indirect, (Dn) requires two more bytes and
|
|
* several more clock cycles. Using (Dn) is even more expensive in
|
|
* time than first moving Dn to an address register An, and then using
|
|
* (An). For this kind of reasons several addressing modes are
|
|
* not used in this table.
|
|
*
|
|
* Cost in bytes may sometimes be incorrect. Several effective addresses
|
|
* use displacements that can occupy either 2 or 4 bytes. These are not
|
|
* considered different TOKENS in this table.
|
|
*
|
|
* Data registers are the only registers used as index registers in this
|
|
* table; address registers are only used to hold addresses.
|
|
*
|
|
* For the m68k2 and m68k4 table: the MC68000 and MC68010 have two
|
|
* modes that use displacements (offsets) of limited size:
|
|
* - offset(A_REG, Index_reg), where offset is only 8 bits, and
|
|
* - offset(A_REG), where offset can only be 16 bits.
|
|
* To make sure that no output is given with offsets too large, two
|
|
* extra tokens are declared: t_regAregXcon and t_regAcon. These are
|
|
* used as addresses to these modes. Whenever the displacements become
|
|
* too large, they are transformed into different tokens.
|
|
*
|
|
* Sometimes some TOKENS are used with displacements (offsets) of 0.
|
|
* It would have been possible to provide separate TOKENS for these, in
|
|
* case the assembler doesn't handle zero offsets optimally. This
|
|
* however would mean a very large amount of extra TOKENS and SETS for
|
|
* a very small profit in code bytes, so we won't do that.
|
|
*
|
|
* To prevent the TOKENS list from getting too unreadable, #ifdefs are
|
|
* used to form three parts:
|
|
* (i) the common part;
|
|
* (ii) the m68k2 and m68k4 part;
|
|
* (iii) the m68020 part;
|
|
*/
|
|
|
|
/* Part (i) */
|
|
zero_const = {INT num;} WORD_SIZE cost(0,0) "#" num .
|
|
small_const = {INT num;} WORD_SIZE cost(0,0) "#" num .
|
|
bconst = {INT num;} WORD_SIZE cost(0,0) "#" num .
|
|
const = {INT num;} WORD_SIZE cost(4,4) "#" num .
|
|
#if WORD_SIZE==2
|
|
/* ??? "string+const */
|
|
zero_const4 = {INT num;} 4 cost(0,0) "#" num .
|
|
small_const4 = {INT num;} 4 cost(0,0) "#" num .
|
|
bconst4 = {INT num;} 4 cost(0,0) "#" num .
|
|
const4 = {ADDR num;} 4 cost(4,4) "#" num .
|
|
#endif
|
|
indirect4 = {A_REG reg;} 4 cost(0,4) "(" reg ")" .
|
|
post_inc4 = {A_REG reg;} 4 cost(0,4) "(" reg ")+" .
|
|
pre_dec4 = {A_REG reg;} 4 cost(0,5) "-(" reg ")" .
|
|
dreg4 = {D_REG4 reg;} 4 cost(0,0) reg .
|
|
areg = {A_REG reg;} 4 cost(0,0) reg .
|
|
dreg2 = {D_REG reg;} WORD_SIZE cost(0,0) reg .
|
|
indirect2 = {A_REG reg;} WORD_SIZE cost(0,4) "(" reg ")" .
|
|
post_inc2 = {A_REG reg;} WORD_SIZE cost(0,4) "(" reg ")+" .
|
|
pre_dec2 = {A_REG reg;} WORD_SIZE cost(0,5) "-(" reg ")" .
|
|
dreg1 = {D_REG reg;} WORD_SIZE cost(0,0) reg .
|
|
indirect1 = {A_REG reg;} WORD_SIZE cost(0,4) "(" reg ")" .
|
|
post_inc1 = {A_REG reg;} WORD_SIZE cost(0,4) "(" reg ")+" .
|
|
pre_dec1 = {A_REG reg;} WORD_SIZE cost(0,5) "-(" reg ")" .
|
|
|
|
ext_addr = {ADDR bd;} 4 cost(4,5) "#" bd .
|
|
llabel = {ADDR bd;} 4 cost(2,0) bd .
|
|
slabel = {ADDR bd;} 4 cost(0,0) bd .
|
|
|
|
/* check this out */
|
|
extend1 = {D_REG reg;} WORD_SIZE cost(0,0) reg .
|
|
#if WORD_SIZE==2
|
|
extend1_4 = {D_REG4 reg;} 4 cost(0,0) reg .
|
|
#else
|
|
#define extend1_4 extend1
|
|
#endif
|
|
extend2 = {D_REG4 reg;} 4 cost(0,0) reg .
|
|
|
|
#ifndef SYNTAX_68020
|
|
/* Part (ii) in m68k2/4 syntax */
|
|
absolute4 = {ADDR bd;} 4 cost(4,8) bd .
|
|
offsetted4 = {A_REG reg; INT bd;} 4 cost(2,6) bd "(" reg ")" .
|
|
index_off4 = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(2,7)
|
|
bd "(" reg "," xreg ".l)" .
|
|
absolute2 = {ADDR bd;} WORD_SIZE cost(4,6) bd .
|
|
offsetted2 = {A_REG reg; INT bd;} WORD_SIZE cost(2,4) bd "(" reg ")" .
|
|
index_off2 = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} WORD_SIZE cost(2,5)
|
|
bd "(" reg "," xreg ".l)" .
|
|
absolute1 = {ADDR bd;} WORD_SIZE cost(4,6) bd .
|
|
offsetted1 = {A_REG reg; INT bd;} WORD_SIZE cost(2,4) bd "(" reg ")" .
|
|
index_off1 = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} WORD_SIZE cost(2,5)
|
|
bd "(" reg "," xreg ".l)" .
|
|
|
|
LOCAL = {INT bd;} WORD_SIZE cost(2,6) bd "(a6)" .
|
|
#if WORD_SIZE==2
|
|
/* pointers may go into DLOCAL's */
|
|
DLOCAL = {INT bd;} 4 cost(2,6) bd "(a6)" .
|
|
#endif
|
|
|
|
local_addr = {INT bd;} 4 cost(2,6) bd "(a6)" .
|
|
regAcon = {A_REG reg; INT bd;} 4 cost(2,6) bd "(" reg ")" .
|
|
regAregXcon = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(2,8)
|
|
bd "(" reg "," xreg ".l)" .
|
|
/* note: in the m68k[24] version %sc always equals 1 */
|
|
#endif
|
|
|
|
#ifdef SYNTAX_68020
|
|
/* Part (ii) in m68020 syntax */
|
|
absolute4 = {ADDR bd;} 4 cost(4,7) "(" bd ")" .
|
|
offsetted4 = {A_REG reg; INT bd;} 4 cost(2,6) "(" bd "," reg ")" .
|
|
index_off4 = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(4,9)
|
|
"(" bd "," reg "," xreg ".l*" sc ")" .
|
|
absolute2 = {ADDR bd;} WORD_SIZE cost(4,7) "(" bd ")" .
|
|
offsetted2 = {A_REG reg; INT bd;} WORD_SIZE cost(2,6) "(" bd "," reg ")" .
|
|
index_off2 = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} WORD_SIZE cost(4,9)
|
|
"(" bd "," reg "," xreg ".l*" sc ")" .
|
|
absolute1 = {ADDR bd;} WORD_SIZE cost(4,7) "(" bd ")" .
|
|
offsetted1 = {A_REG reg; INT bd;} WORD_SIZE cost(2,6) "(" bd "," reg ")" .
|
|
index_off1 = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} WORD_SIZE cost(4,9)
|
|
"(" bd "," reg "," xreg ".l*" sc ")" .
|
|
|
|
LOCAL = {INT bd;} WORD_SIZE cost(2,6) "(" bd ",a6)" .
|
|
#if WORD_SIZE==2
|
|
/* pointers may go into DLOCAL's */
|
|
DLOCAL = {INT bd;} 4 cost(2,6) "(" bd ",a6)" .
|
|
#endif
|
|
local_addr = {INT bd;} 4 cost(2,3) "(" bd ",a6)" .
|
|
regAcon = {A_REG reg; INT bd;} 4 cost(2,3) "(" bd "," reg ")" .
|
|
regAregXcon = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(2,7)
|
|
"(" bd "," reg "," xreg ".l*" sc ")" .
|
|
#endif
|
|
#ifdef TBL68020
|
|
/* Part (iii) */
|
|
abs_index4 = {INT sc; D_REG4 xreg; ADDR bd;} 4 cost(6,9)
|
|
"(" bd "," xreg ".l*" sc ")" .
|
|
OFF_off4 = {A_REG reg; INT bd; ADDR od;} 4 cost(6,19)
|
|
"([" bd "," reg "]," od ")" .
|
|
OFF_indoff4 = {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} 4 cost(6,19)
|
|
"([" bd "," reg "]," xreg ".l*" sc "," od ")" .
|
|
INDOFF_off4 = {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} 4 cost(6,19)
|
|
"([" bd "," reg "," xreg ".l*" sc "]," od ")" .
|
|
ABS_off4 = {ADDR bd; ADDR od;} 4 cost(8,22) "([" bd "]," od ")" .
|
|
ABS_indoff4 = {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} 4 cost(8,22)
|
|
"([" bd "]," xreg ".l*" sc "," od ")" .
|
|
ABSIND_off4 = {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} 4 cost(8,22)
|
|
"([" bd "," xreg ".l*" sc "]," od ")" .
|
|
|
|
abs_index2 = {INT sc; D_REG4 xreg; ADDR bd;} WORD_SIZE cost(6,9)
|
|
"(" bd "," xreg ".l*" sc ")" .
|
|
OFF_off2 = {A_REG reg; INT bd; ADDR od;} WORD_SIZE cost(6,19)
|
|
"([" bd "," reg "]," od ")" .
|
|
OFF_indoff2 = {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} WORD_SIZE cost(6,19)
|
|
"([" bd "," reg "]," xreg ".l*" sc "," od ")" .
|
|
INDOFF_off2 = {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} WORD_SIZE cost(6,19)
|
|
"([" bd "," reg "," xreg ".l*" sc "]," od ")" .
|
|
ABS_off2 = {ADDR bd; ADDR od;} WORD_SIZE cost(8,22) "([" bd "]," od ")" .
|
|
ABS_indoff2 = {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} WORD_SIZE cost(8,22)
|
|
"([" bd "]," xreg ".l*" sc "," od ")" .
|
|
ABSIND_off2 = {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} WORD_SIZE cost(8,22)
|
|
"([" bd "," xreg ".l*" sc "]," od ")" .
|
|
|
|
abs_index1 = {INT sc; D_REG4 xreg; ADDR bd;} WORD_SIZE cost(6,9)
|
|
"(" bd "," xreg ".l*" sc ")" .
|
|
OFF_off1 = {A_REG reg; INT bd; ADDR od;} WORD_SIZE cost(6,19)
|
|
"([" bd "," reg "]," od ")" .
|
|
OFF_indoff1 = {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} WORD_SIZE cost(6,19)
|
|
"([" bd "," reg "]," xreg ".l*" sc "," od ")" .
|
|
INDOFF_off1 = {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} WORD_SIZE cost(6,19)
|
|
"([" bd "," reg "," xreg ".l*" sc "]," od ")" .
|
|
ABS_off1 = {ADDR bd; ADDR od;} WORD_SIZE cost(8,22) "([" bd "]," od ")" .
|
|
ABS_indoff1 = {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} WORD_SIZE cost(8,22)
|
|
"([" bd "]," xreg ".l*" sc "," od ")" .
|
|
ABSIND_off1 = {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} WORD_SIZE cost(8,22)
|
|
"([" bd "," xreg ".l*" sc "]," od ")" .
|
|
|
|
ILOCAL = {INT bd;} WORD_SIZE cost(4,16) "([" bd ",a6])" .
|
|
|
|
off_con = {A_REG reg; INT bd; ADDR od;} 4 cost(6,18)
|
|
"([" bd "," reg "]," od ")".
|
|
off_regXcon = {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} 4 cost(6,18)
|
|
"([" bd "," reg "]," xreg ".l*" sc "," od ")" .
|
|
indoff_con = {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} 4 cost(6,18)
|
|
"([" bd "," reg "," xreg ".l*" sc "]," od ")" .
|
|
abs_con = {ADDR bd; ADDR od;} 4 cost(8,21) "([" bd "]," od ")" .
|
|
abs_regXcon = {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} 4 cost(8,21)
|
|
"([" bd "]," xreg ".l*" sc "," od ")" .
|
|
absind_con = {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} 4 cost(8,21)
|
|
"([" bd "," xreg ".l*" sc "]," od ")" .
|
|
ext_regX = {INT sc; D_REG4 xreg; ADDR bd;} 4 cost(6,15)
|
|
"(" bd "," xreg ".l*" sc ")" .
|
|
|
|
regX = {INT sc; D_REG4 xreg;} 4 cost(2,7) "(" xreg ".l*" sc ")" .
|
|
DREG_pair = {D_REG4 reg1; D_REG4 reg2;} 8 cost(2,0) reg1 ":" reg2 .
|
|
|
|
#define t_regAregXcon regAregXcon
|
|
#define t_regAcon regAcon
|
|
|
|
#else /* TBL68020 */
|
|
t_regAregXcon = {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(2,8) .
|
|
t_regAcon = {A_REG reg; INT bd;} 4 cost(2,6) .
|
|
#endif
|
|
|
|
#if WORD_SIZE!=2
|
|
#define DLOCAL LOCAL
|
|
#endif
|
|
|
|
SETS
|
|
|
|
/* The SETS list cannot be kept as 'readable' as the TOKENS
|
|
* list because cgg is one pass.
|
|
* We makes use of the fact that sets are indeed sets. Thus
|
|
* D_REG + D_REG4 == D_REG, when the wordsize is 4.
|
|
*/
|
|
|
|
sconsts = small_const + bconst .
|
|
consts = const + sconsts + zero_const.
|
|
#if WORD_SIZE!=2
|
|
#define small_const4 small_const
|
|
#define zero_const4 zero_const
|
|
#define bconst4 bconst
|
|
#define const4 const
|
|
#define sconsts4 sconsts
|
|
#define consts4 consts
|
|
#else
|
|
sconsts4 = small_const4 + bconst4 .
|
|
consts4 = const4 + sconsts4 + zero_const4.
|
|
#endif
|
|
|
|
#ifndef TBL68020
|
|
/* A m68k2/m68k4 part */
|
|
data4 = D_REG4 + DLOCAL + consts4 + post_inc4 + pre_dec4 +
|
|
indirect4 + offsetted4 + index_off4 + absolute4 +
|
|
ext_addr + dreg4 .
|
|
memory4 = data4 - D_REG4 - dreg4 .
|
|
control4 = indirect4 + offsetted4 + index_off4 + absolute4 +
|
|
DLOCAL.
|
|
alterable4 = data4 + A_REG - consts4 - ext_addr .
|
|
any4 = data4 + A_REG . /* all four above together */
|
|
|
|
#if WORD_SIZE==2
|
|
data2 = D_REG + LOCAL + dreg2 + post_inc2 + pre_dec2 +
|
|
indirect2 + offsetted2 + index_off2 + absolute2 +
|
|
consts .
|
|
memory2 = data2 - D_REG - dreg2 .
|
|
control2 = indirect2 + offsetted2 + index_off2 + absolute2 + LOCAL.
|
|
#else
|
|
data2 = dreg2 + post_inc2 + pre_dec2 + indirect2 +
|
|
offsetted2 + index_off2 + absolute2 + consts .
|
|
memory2 = data2 - dreg2 .
|
|
control2 = indirect2 + offsetted2 + index_off2 + absolute2 .
|
|
#endif
|
|
alterable2 = data2 + D_REG - consts .
|
|
any2 = data2 + D_REG .
|
|
|
|
data1 = dreg1 + post_inc1 + pre_dec1 + indirect1 +
|
|
offsetted1 + index_off1 + absolute1 + consts .
|
|
memory1 = data1 - dreg1 .
|
|
control1 = indirect1 + offsetted1 + index_off1 + absolute1 .
|
|
alterable1 = data1 + D_REG - consts .
|
|
any1 = data1 + D_REG .
|
|
|
|
#else /* TBL68020 */
|
|
|
|
data4 = D_REG4 + indirect4 + post_inc4 + pre_dec4 + index_off4 +
|
|
offsetted4 + OFF_off4 + OFF_indoff4 +
|
|
INDOFF_off4 + dreg4 +
|
|
ABS_off4 + ABS_indoff4 + ABSIND_off4 +
|
|
absolute4 + abs_index4 + consts4 + ext_addr +
|
|
DLOCAL
|
|
#if WORD_SIZE!=2
|
|
+ ILOCAL
|
|
#endif
|
|
.
|
|
memory4 = data4 - D_REG4 - dreg4 .
|
|
control4 = memory4 - (post_inc4 + pre_dec4 + consts4 + ext_addr).
|
|
alterable4 = data4 + A_REG - consts - ext_addr .
|
|
any4 = data4 + A_REG . /* all four above together */
|
|
|
|
#if WORD_SIZE==2
|
|
data2 = D_REG + LOCAL+ ILOCAL+
|
|
dreg2 + indirect2 + post_inc2 + pre_dec2 + index_off2 +
|
|
offsetted2 + OFF_off2 + OFF_indoff2 +
|
|
INDOFF_off2 +
|
|
ABS_off2 + ABS_indoff2 + ABSIND_off2 +
|
|
absolute2 + abs_index2 + consts .
|
|
memory2 = data2 - D_REG - dreg2 .
|
|
#else
|
|
data2 = dreg2 + indirect2 + post_inc2 + pre_dec2 + index_off2 +
|
|
offsetted2 + OFF_off2 + OFF_indoff2 +
|
|
INDOFF_off2 +
|
|
ABS_off2 + ABS_indoff2 + ABSIND_off2 +
|
|
absolute2 + abs_index2 + consts .
|
|
memory2 = data2 - dreg2 .
|
|
#endif
|
|
control2 = memory2 - (post_inc2 + pre_dec2 + consts ) .
|
|
alterable2 = data2 + D_REG - consts .
|
|
any2 = data2 + D_REG. /* all four above together */
|
|
|
|
data1 = dreg1 + indirect1 + post_inc1 + pre_dec1 + index_off1 +
|
|
offsetted1 + OFF_off1 + OFF_indoff1 +
|
|
INDOFF_off1 +
|
|
ABS_off1 + ABS_indoff1 + ABSIND_off1 +
|
|
absolute1 + abs_index1 + consts .
|
|
memory1 = data1 - dreg1 .
|
|
control1 = memory1 - (post_inc1 + pre_dec1 + consts ) .
|
|
alterable1 = data1 + D_REG - consts .
|
|
any1 = data1 + D_REG. /* all four above together */
|
|
|
|
#endif /* TBL68020 */
|
|
/* This is a common part */
|
|
#if WORD_SIZE==2
|
|
/* Not any4, since any is used in 'with' and not in 'kills' */
|
|
any = any2 + any1 .
|
|
#else
|
|
any = any4 + any2 + any1 .
|
|
#endif
|
|
control = control4 + control2 + control1 .
|
|
indirect = indirect4 + indirect2 + indirect1 .
|
|
offsetted = offsetted4 + offsetted2 + offsetted1 .
|
|
index_off = index_off4 + index_off2 + index_off1 .
|
|
absolute = absolute4 + absolute2 + absolute1 .
|
|
pre_post = pre_dec4 + pre_dec2 + pre_dec1 +
|
|
post_inc4 + post_inc2 + post_inc1 .
|
|
|
|
#ifndef TBL68020
|
|
/* A m68k2/m68k4 part */
|
|
regind_addr = regAcon + regAregXcon + t_regAcon + t_regAregXcon .
|
|
address = ext_addr + local_addr + regAcon + regAregXcon .
|
|
all_regind = indirect + offsetted + pre_post + index_off +
|
|
regind_addr + areg .
|
|
all_indir = all_regind .
|
|
allexceptcon = ALL - ( D_REG + A_REG + consts + dreg2 + dreg1 +
|
|
local_addr + ext_addr + regAcon + regAregXcon +
|
|
t_regAcon + t_regAregXcon ) .
|
|
use_index = index_off4 + index_off2 + index_off1 .
|
|
|
|
#else /* TBL68020 */
|
|
|
|
reg_memind4 = OFF_off4 + OFF_indoff4 + INDOFF_off4 .
|
|
memind4 = reg_memind4 +
|
|
ABS_off4 + ABS_indoff4 .
|
|
reg_memind2 = OFF_off2 + OFF_indoff2 + INDOFF_off2 .
|
|
memind2 = reg_memind2 +
|
|
ABS_off2 + ABS_indoff2 .
|
|
reg_memind1 = OFF_off1 + OFF_indoff1 + INDOFF_off1 .
|
|
memind1 = reg_memind1 +
|
|
ABS_off1 + ABS_indoff1 .
|
|
reg_memind = reg_memind4 + reg_memind2 + reg_memind1 .
|
|
memind = memind4 + memind2 + memind1 .
|
|
regind_addr = regAcon + regAregXcon +
|
|
off_con + off_regXcon +
|
|
indoff_con .
|
|
address = regind_addr +
|
|
ext_addr + local_addr +
|
|
abs_con + abs_regXcon +
|
|
absind_con +
|
|
ext_regX .
|
|
all_regind = indirect + offsetted + index_off + pre_post +
|
|
reg_memind + regind_addr + areg .
|
|
all_indir = all_regind + memind + ILOCAL .
|
|
allexceptcon = ALL - ( D_REG + A_REG + consts + dreg2 + dreg1 +
|
|
local_addr + ext_addr + regAcon + regAregXcon + ext_regX ) .
|
|
use_index4 = index_off4 + abs_index4 +
|
|
OFF_indoff4 + INDOFF_off4 +
|
|
ABS_indoff4 + ABSIND_off4 .
|
|
use_index2 = index_off2 + abs_index2 +
|
|
OFF_indoff2 + INDOFF_off2 +
|
|
ABS_indoff2 + ABSIND_off2 .
|
|
use_index1 = index_off1 + abs_index1 +
|
|
OFF_indoff1 + INDOFF_off1 +
|
|
ABS_indoff1 + ABSIND_off1 .
|
|
use_indaddr = regAregXcon +
|
|
off_regXcon + indoff_con +
|
|
abs_regXcon + absind_con +
|
|
ext_regX .
|
|
|
|
use_index = use_index4 + use_index2 + use_index1 + use_indaddr + regX .
|
|
|
|
#endif /* TBL68020 */
|
|
/* A common part */
|
|
posextern = absolute + all_indir .
|
|
|
|
#if WORD_SIZE==2
|
|
genreg2 = D_REG .
|
|
#define genreg genreg2
|
|
#else
|
|
#define genreg genreg4
|
|
#endif
|
|
genreg4 = D_REG4 + A_REG.
|
|
label = llabel + slabel .
|
|
immediate4 = consts4 + ext_addr .
|
|
#if WORD_SIZE==2
|
|
immediate2 = consts .
|
|
#endif
|
|
conreg4 = D_REG4 + immediate4 .
|
|
conreg2 = dreg2 + consts + D_REG .
|
|
conreg1 = dreg1 + consts + D_REG .
|
|
#if WORD_SIZE==2
|
|
conreg = conreg1 + conreg2 .
|
|
#else
|
|
conreg = conreg1 + conreg2 + conreg4 .
|
|
#endif
|
|
shconreg = D_REG + small_const .
|
|
datalt4 = data4 * alterable4 .
|
|
datalt2 = data2 * alterable2 .
|
|
datalt1 = data1 * alterable1 .
|
|
datalt = datalt4 + datalt2 + datalt1 .
|
|
memalt4 = memory4 * alterable4 .
|
|
memalt2 = memory2 * alterable2 .
|
|
memalt1 = memory1 * alterable1 .
|
|
|
|
#ifndef TBL68020
|
|
/* A m68k2/m68k4 part */
|
|
imm_cmp4 = alterable4 - A_REG .
|
|
imm_cmp2 = alterable2 + D_REG .
|
|
imm_cmp1 = datalt1 + D_REG .
|
|
|
|
test_set4 = datalt4 + extend2 + extend1_4 .
|
|
#if WORD_SIZE==2
|
|
test_set2 = datalt2 + extend1 .
|
|
#else
|
|
test_set2 = datalt2 .
|
|
#endif
|
|
test_set1 = datalt1 .
|
|
|
|
#else /* TBL68020 */
|
|
|
|
imm_cmp4 = any4 - immediate4 - A_REG .
|
|
imm_cmp2 = any2 - consts .
|
|
imm_cmp1 = any1 - consts .
|
|
|
|
test_set4 = any4 - immediate4 + extend2 + extend1_4 .
|
|
#if WORD_SIZE==2
|
|
test_set2 = data2 + extend1 - immediate2 .
|
|
#else
|
|
test_set2 = data2 - consts .
|
|
#endif
|
|
test_set1 = data1 - consts .
|
|
|
|
#endif /* TBL68020 */
|
|
|
|
test_set = test_set4 + test_set2 + test_set1 .
|
|
|
|
#ifndef TBL68020
|
|
t_address = address + t_regAregXcon + t_regAcon .
|
|
#else /* TBL68020 */
|
|
#define t_address address
|
|
#endif /* TBL68020 */
|
|
|
|
#if TBL68881
|
|
freg = FD_REG + FS_REG .
|
|
store4 = any4 + FS_REG .
|
|
#else
|
|
store4 = any4 .
|
|
#endif
|
|
#if WORD_SIZE==2
|
|
dups2 = genreg2 .
|
|
#endif
|
|
dups4 = genreg4 .
|
|
|
|
#include "instrmacs.h"
|
|
|
|
INSTRUCTIONS
|
|
|
|
/* Since the 68000 , the 68010 and the 68020 instruction sets are rather
|
|
* extensive, especially because e.g. 'add.l' and 'add.w' are
|
|
* considered different instructions, only those instructions are
|
|
* listed here that are used in the rest of this table.
|
|
*
|
|
* Instruction timing cost cannot be accurately given, nor the timing
|
|
* cost for getting operands. Detailed information about this can be
|
|
* found in the "MC68020 User's Manual", section 9, about instruction
|
|
* timing. The cost used in this table are 'worst case' cost, as
|
|
* mentioned in section 9 of the user's manual. Furthermore, the
|
|
* timing information for the 68k[24] and the 68020 differ, which
|
|
* means that the 68k[24] will not always have the best code
|
|
* possible.
|
|
*
|
|
* The first few instructions had to be added because register
|
|
* variables are used. The LOCALs below are register variables.
|
|
* One may not conclude that these operations are also allowed
|
|
* on LOCALs that are not register variables.
|
|
* The cost have been adapted, but are not accurate; when 'real'
|
|
* LOCALs are used the cost are very inaccurate.
|
|
*/
|
|
|
|
add_i ADD_I any_int:ro, LOCAL:rw:cc cost(0,0).
|
|
sub_i SUB_I any_int:ro, LOCAL:rw:cc cost(0,0).
|
|
lea address:ro, DLOCAL:wo cost(0,0).
|
|
sh "illegal" shconreg+LOCAL:ro, LOCAL:rw:cc cost(0,0).
|
|
xxx "illegal" data4:ro, LOCAL:rw:cc cost(0,0).
|
|
xxx "illegal" LOCAL:ro, alterable4:rw:cc cost(0,0).
|
|
#if WORD_SIZE==2
|
|
/* divs_w "divs.w" data2:ro, LOCAL:rw:cc cost(0,56). */
|
|
/* divu_w "divu.w" data2:ro, LOCAL:rw:cc cost(0,44). */
|
|
muls_w "muls.w" data2:ro, LOCAL:rw:cc cost(0,28).
|
|
mulu_w "mulu.w" data2:ro, LOCAL:rw:cc cost(0,28).
|
|
#endif
|
|
#if TBL68020 && WORD_SIZE!=2
|
|
divs_l "divs.l" data4:ro, LOCAL:rw:cc cost(0,90).
|
|
divu_l "divu.l" data4:ro, LOCAL:rw:cc cost(0,78).
|
|
muls_l "muls.l" data4:ro, LOCAL:rw:cc cost(0,44).
|
|
mulu_l "mulu.l" data4:ro, LOCAL:rw:cc cost(0,44).
|
|
#endif /* TBL68020 */
|
|
|
|
#if WORD_SIZE==2
|
|
add_l "add.l" any4:ro, D_REG4:rw:cc cost(2,3).
|
|
#else
|
|
add_l "add.l" any4:ro, D_REG+LOCAL:rw:cc cost(2,3).
|
|
#endif
|
|
add_l "add.l" any4:ro, A_REG+DLOCAL+areg:rw cost(2,3).
|
|
add_l "add.l" conreg4:ro, alterable4:rw:cc cost(2,6).
|
|
#if WORD_SIZE==2
|
|
add_w "add.w" any2:ro, D_REG+LOCAL:rw:cc cost(2,3).
|
|
add_w "add.w" conreg2:ro, alterable2:rw:cc cost(2,6).
|
|
#endif
|
|
addx_l "addx.l" D_REG4:ro, D_REG4:rw kills :cc cost(2,3).
|
|
and_l "and.l" data4:ro, D_REG4:rw:cc cost(2,3).
|
|
and_l "and.l" D_REG4:ro, memalt4:rw:cc cost(2,6).
|
|
and_l "and.l" consts4:ro, datalt4:rw:cc cost(2,6).
|
|
#if WORD_SIZE==2
|
|
and_w "and.w" data2:ro, D_REG:rw:cc cost(2,3).
|
|
and_w "and.w" D_REG:ro, memalt2:rw:cc cost(2,6).
|
|
and_w "and.w" consts:ro, datalt2:rw:cc cost(2,6).
|
|
#endif
|
|
asl_l "asl.l" shconreg:ro, D_REG4:rw:cc cost(2,5).
|
|
asl "asl #1," memalt2:rw:cc cost(2,4).
|
|
asr_l "asr.l" shconreg:ro, D_REG4:rw:cc cost(2,4).
|
|
asr "asr #1," memalt2:rw:cc cost(2,4).
|
|
#if WORD_SIZE==2
|
|
asl_w "asl.w" shconreg:ro, D_REG:rw:cc cost(2,5).
|
|
asr_w "asr.w" shconreg:ro, D_REG:rw:cc cost(2,4).
|
|
#endif
|
|
bchg const:ro, D_REG:rw kills:cc cost(2,4).
|
|
bclr const:ro, D_REG:rw kills:cc cost(2,4).
|
|
bra label cost(2,5).
|
|
bcc label cost(2,5).
|
|
bcs label cost(2,5).
|
|
beq label cost(2,5).
|
|
bge label cost(2,5).
|
|
bgt label cost(2,5).
|
|
bhi label cost(2,5).
|
|
ble label cost(2,5).
|
|
bls label cost(2,5).
|
|
blt label cost(2,5).
|
|
bmi label cost(2,5).
|
|
bne label cost(2,5).
|
|
bpl label cost(2,5).
|
|
bvc label cost(2,5).
|
|
bvs label cost(2,5).
|
|
bset conreg2:ro, D_REG+D_REG4:rw kills :cc cost(2,4).
|
|
btst conreg2:ro, any1:rw kills :cc cost(2,3).
|
|
/* Check dreg[21] for m68020 and m68k2 */
|
|
clr_l "clr.l" D_REG4+dreg4:wo:cc cost(2,3).
|
|
clr_l "clr.l" memalt4:wo:cc cost(2,6).
|
|
clr_w "clr.w" D_REG+dreg2:wo:cc cost(2,2).
|
|
clr_w "clr.w" memalt2:wo:cc cost(2,4).
|
|
clr_b "clr.b" D_REG+dreg1:wo:cc cost(2,2).
|
|
clr_b "clr.b" memalt1:wo:cc cost(2,4).
|
|
cmp_l "cmp.l" any4:ro, genreg4:ro kills :cc cost(2,3).
|
|
cmp_l "cmp.l" post_inc4:ro, post_inc4:ro kills :cc cost(2,2).
|
|
cmp_l "cmp.l" immediate4:ro, imm_cmp4:ro kills :cc cost(2,2).
|
|
#if WORD_SIZE==2
|
|
cmp_w "cmp.w" any2+extend2:ro, D_REG+dreg2+extend2:ro kills :cc cost(2,2).
|
|
#else
|
|
cmp_w "cmp.w" any2+extend2:ro, dreg2+extend2:ro kills :cc cost(2,2).
|
|
#endif
|
|
cmp_w "cmp.w" post_inc2:ro, post_inc2:ro kills :cc cost(2,2).
|
|
cmp_w "cmp.w" consts:ro, imm_cmp2:ro kills :cc cost(2,2).
|
|
cmp_b "cmp.b" any1+extend1+extend1_4:ro, dreg1+extend1+extend1_4:ro kills :cc cost(2,3).
|
|
cmp_b "cmp.b" post_inc1:ro, post_inc1:ro kills :cc cost(2,2).
|
|
cmp_b "cmp.b" consts:ro, imm_cmp1:ro kills :cc cost(2,2).
|
|
dbf D_REG4:rw, label cost(2,5).
|
|
eor_l "eor.l" conreg4:ro, datalt4:rw:cc cost(2,6).
|
|
#if WORD_SIZE==2
|
|
eor_w "eor.w" conreg2:ro, datalt2:rw:cc cost(2,4).
|
|
#endif
|
|
exg genreg4:rw, genreg4:rw cost(2,3).
|
|
/* in the next two instructions: LOCAL only allowed if register var */
|
|
ext_l "ext.l" D_REG+LOCAL+D_REG4:rw:cc cost(2,2).
|
|
ext_w "ext.w" D_REG+LOCAL+D_REG4:rw:cc cost(2,2).
|
|
jmp address+control4 cost(2,0).
|
|
jsr address+control4 kills :cc d0 d1 d2 a0 a1 cost(2,3).
|
|
lea address+control4:ro, A_REG+areg:wo cost(2,0).
|
|
lsl_l "lsl.l" shconreg:ro, D_REG4:rw:cc cost(2,4).
|
|
/*
|
|
lsl "lsl #1," memalt2:rw:cc cost(2,4).
|
|
*/
|
|
lsr_l "lsr.l" shconreg:ro, D_REG4:rw:cc cost(2,4).
|
|
#if WORD_SIZE==2
|
|
lsr_w "lsr.w" shconreg:ro, D_REG:rw:cc cost(2,4).
|
|
#endif
|
|
lsr "lsr #1," memalt2:rw:cc cost(2,4).
|
|
/* move_l does not set the condition codes if the destination is an
|
|
address register!
|
|
*/
|
|
move_l "move.l" any4:ro, A_REG+areg:wo cost(2,2).
|
|
move_l "move.l" any4:ro, alterable4+dreg4-(areg+A_REG):wo:cc cost(2,2).
|
|
#if WORD_SIZE==2
|
|
move_l "move.l" sconsts:ro, D_REG+dreg2:wo:cc cost(2,2).
|
|
/*
|
|
move_l "move.l" any2:ro, alterable4+dreg4-(areg+A_REG):wo:cc cost(2,2).
|
|
*/
|
|
move_w "move.w" any2:ro, alterable2+dreg2:wo:cc cost(2,2).
|
|
move_b "move.b" any1:ro, alterable1+dreg2:wo:cc cost(2,2).
|
|
#else
|
|
move_w "move.w" any2:ro, alterable2+dreg4:wo:cc cost(2,2).
|
|
move_b "move.b" any1:ro, alterable1+dreg4:wo:cc cost(2,2).
|
|
#endif
|
|
neg_b "neg.b" D_REG:rw:cc cost(2,3).
|
|
neg_w "neg.w" D_REG:rw:cc cost(2,3).
|
|
neg_l "neg.l" D_REG4:rw:cc cost(2,3).
|
|
neg_l "neg.l" memory4:rw:cc cost(2,6).
|
|
#if WORD_SIZE==2
|
|
neg_w "neg.w" memory2:rw:cc cost(2,6).
|
|
#endif
|
|
negx_l "negx.l" D_REG4:rw:cc cost(2,3).
|
|
negx_l "negx.l" memory4:rw:cc cost(2,6).
|
|
not_l "not.l" D_REG4:rw:cc cost(2,3).
|
|
not_l "not.l" memory4:rw:cc cost(2,6).
|
|
#if WORD_SIZE==2
|
|
not_w "not.w" D_REG:rw:cc cost(2,3).
|
|
not_w "not.w" memory2:rw:cc cost(2,6).
|
|
#endif
|
|
or_l "or.l" data4:ro, D_REG4:rw:cc cost(2,3).
|
|
or_l "or.l" D_REG4:ro, memalt4:rw:cc cost(2,6).
|
|
or_l "or.l" consts4:ro, datalt4:rw:cc cost(2,6).
|
|
#if WORD_SIZE==2
|
|
or_w "or.w" data2:ro, D_REG:rw:cc cost(2,3).
|
|
or_w "or.w" D_REG:ro, memalt2:rw:cc cost(2,6).
|
|
or_w "or.w" consts:ro, datalt2:rw:cc cost(2,6).
|
|
#endif
|
|
rol_l "rol.l" shconreg:ro, D_REG4:rw:cc cost(2,4).
|
|
rol "rol #1," memalt2:rw:cc cost(2,4).
|
|
ror_l "ror.l" shconreg:ro, D_REG4:rw:cc cost(2,4).
|
|
ror "ror #1," memalt2:rw:cc cost(2,4).
|
|
#if WORD_SIZE==2
|
|
rol_w "rol.w" shconreg:ro, D_REG:rw:cc cost(2,4).
|
|
ror_w "ror.w" shconreg:ro, D_REG:rw:cc cost(2,4).
|
|
#endif
|
|
roxl "roxl #1," memalt2:rw:cc cost(2,4).
|
|
roxr "roxr #1," memalt2:rw:cc cost(2,4).
|
|
slt datalt1:rw cost(2,3).
|
|
sne datalt1:rw cost(2,3).
|
|
sub_l "sub.l" any4:ro, D_REG4:rw:cc cost(2,3).
|
|
sub_l "sub.l" any4+areg:ro, A_REG+areg:rw cost(2,3).
|
|
sub_l "sub.l" conreg4:ro, alterable4:rw:cc cost(2,6).
|
|
#if WORD_SIZE==2
|
|
sub_w "sub.w" any2:ro, D_REG+LOCAL:rw:cc cost(2,3).
|
|
sub_w "sub.w" conreg2:ro, alterable2:rw:cc cost(2,6).
|
|
#endif
|
|
subx_l "subx.l" D_REG4:ro, D_REG4:rw kills :cc cost(2,3).
|
|
#if WORD_SIZE==2
|
|
/* On a swap, we only want the lower part of D_REG, so don't set cc */
|
|
swap D_REG:rw kills :cc cost(2,2).
|
|
#endif
|
|
tst_l "tst.l" test_set4:ro:cc cost(2,3).
|
|
tst_w "tst.w" test_set2+extend2:ro:cc cost(2,3).
|
|
tst_b "tst.b" test_set1+extend1+extend1_4:ro:cc cost(2,3).
|
|
unlk A_REG cost(2,6).
|
|
|
|
bxx "illegal" label cost(2,5).
|
|
sxx "illegal" any_int:wo cost(2,5).
|
|
#if WORD_SIZE==2
|
|
s4xx "illegal" any4:wo cost(2,5).
|
|
xxx "illegal" any4+any2:ro, any4+any2:rw:cc cost(2,3).
|
|
bit "illegal" control4+control2:rw:cc cost(2,6).
|
|
#else
|
|
xxx "illegal" any4:ro, any4:rw:cc cost(2,3).
|
|
bit "illegal" control4:rw:cc cost(2,6).
|
|
#endif
|
|
sh "illegal" shconreg:ro, D_REG:rw:cc cost(2,4).
|
|
shw "illegal" control2:rw:cc cost(2,4).
|
|
|
|
#if WORD_SIZE==2
|
|
divs_w "divs.w" data2:ro, D_REG:rw:cc cost(0,56).
|
|
divu_w "divu.w" data2:ro, D_REG:rw:cc cost(0,44).
|
|
muls_w "muls.w" data2:ro, D_REG:rw:cc cost(0,28).
|
|
mulu_w "mulu.w" data2:ro, D_REG:rw:cc cost(0,28).
|
|
#endif
|
|
#ifdef TBL68020
|
|
cmp2_l "cmp2.l" address+control4:ro, genreg4:ro kills :cc cost(2,18).
|
|
divs_l "divs.l" data4:ro, D_REG4:rw:cc cost(2,90).
|
|
divu_l "divu.l" data4:ro, D_REG4:rw:cc cost(2,78).
|
|
divsl_l "divsl.l" data4:ro, DREG_pair:rw kills :cc cost(2,90).
|
|
divul_l "divul.l" data4:ro, DREG_pair:rw kills :cc cost(2,78).
|
|
mulu_l "mulu.l" data4:ro, DREG_pair:rw kills :cc cost(2,44).
|
|
pea address+control4+regX cost(2,4).
|
|
#if WORD_SIZE==2
|
|
cmp2_w "cmp2.w" address+control2:ro, genreg2:ro kills :cc cost(2,18).
|
|
extb_l "extb.l" extend1_4+D_REG4:rw:cc cost(2,4).
|
|
muls_l "muls.l" data4:ro, D_REG4:rw:cc cost(2,44).
|
|
mulu_l "mulu.l" data4:ro, D_REG4:rw:cc cost(2,44).
|
|
#else
|
|
/* in the next instruction: LOCAL only allowed if register var */
|
|
extb_l "extb.l" extend1_4+D_REG+LOCAL:rw:cc cost(2,4).
|
|
muls_l "muls.l" data4:ro, D_REG+LOCAL:rw:cc cost(2,44).
|
|
mulu_l "mulu.l" data4:ro, D_REG+LOCAL:rw:cc cost(2,44).
|
|
#endif
|
|
#else /* TBL68020 */
|
|
pea address+control4 cost(2,4).
|
|
#endif /* TBL68020 */
|
|
|
|
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
* Extra pseudo instruction; it just kills a D_REG;
|
|
* it is necessary with long divides where remainders are important;
|
|
* see also: 'pat rmi' and 'pat rmu'
|
|
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
|
|
killreg "! kill" D_REG+D_REG4+A_REG:wo cost(0,0).
|
|
killcc "! killcc" kills :cc cost(0,0).
|
|
#if TBL68881
|
|
/* These descriptions are not very accurate, because we have no
|
|
other 8-byte objects in the table.
|
|
*/
|
|
fmove_s "fmove.s" data4:ro, freg:wo cost(4,100).
|
|
fmove_s "fmove.s" freg:ro, data4:wo cost(4,100).
|
|
fmove_d "fmove.d" freg:ro, data4:wo cost(4,100).
|
|
fmove_d "fmove.d" data4:ro, freg:ro cost(4,100).
|
|
fmove_l "fmove.l" freg:ro, D_REG:wo cost(4,100).
|
|
fmove_l "fmove.l" data4:ro, freg:wo cost(4,100).
|
|
fmove freg:ro,freg:wo cost(4,100).
|
|
fadd_s "fadd.s" data4:ro, freg:rw cost(4,100).
|
|
fadd_d "fadd.d" data4:ro, freg:rw cost(4,100).
|
|
fsub_s "fsub.s" data4:ro, freg:rw cost(4,100).
|
|
fsub_d "fsub.d" data4:ro, freg:rw cost(4,100).
|
|
fsub freg:ro, freg:rw cost(4,100).
|
|
fmul freg:ro, freg:rw cost(4,100).
|
|
fmul_s "fmul.s" data4:ro, freg:rw cost(4,100).
|
|
fmul_d "fmul.d" data4:ro, freg:rw cost(4,100).
|
|
fdiv freg:ro, freg:rw cost(4,100).
|
|
fdiv_s "fdiv.s" data4:ro, freg:rw cost(4,100).
|
|
fdiv_d "fdiv.d" data4:ro, freg:rw cost(4,100).
|
|
fcmp freg:ro, freg:ro cost(4,100).
|
|
fbeq label:ro cost(4,4).
|
|
fblt label:ro cost(4,4).
|
|
fmovecr const:ro, freg:rw cost(4,100).
|
|
fabs freg:rw cost(4,100).
|
|
fneg freg:rw cost(4,100).
|
|
fgetman freg:rw cost(4,100).
|
|
fintrz freg:ro, freg:wo cost(4,100).
|
|
fgetexp freg:ro, freg:wo cost(4,100).
|
|
fsub_l "fsub.l" const:ro, freg:rw cost(4,100).
|
|
#endif
|
|
|
|
|
|
MOVES
|
|
|
|
from consts %num==0 to D_REG4+dreg4
|
|
gen clr_l %2
|
|
|
|
#if WORD_SIZE==2
|
|
from zero_const4 %num==0 to A_REG+areg
|
|
gen sub_l %2,%2
|
|
|
|
from zero_const4 %num==0 to D_REG4+dreg4
|
|
gen clr_l %2
|
|
#endif
|
|
|
|
from consts %num==0 to A_REG+areg
|
|
gen sub_l %2,%2
|
|
|
|
#if WORD_SIZE==2
|
|
from consts %num==0 to D_REG+dreg2
|
|
gen clr_w %2
|
|
|
|
from sconsts to D_REG+dreg2
|
|
gen move_l %1,%2 /* uses moveq */
|
|
|
|
from consts to D_REG4+dreg4
|
|
gen move_l {const4, %1.num},%2
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
from sconsts4+zero_const4 %num==0 to memalt4
|
|
#else
|
|
from consts %num==0 to memalt4
|
|
#endif
|
|
gen clr_l %2
|
|
|
|
from consts %num==0 to memalt2
|
|
gen clr_w %2
|
|
|
|
from consts %num==0 to memalt1
|
|
gen clr_b %2
|
|
|
|
from consts to memalt1
|
|
gen move_b {const, low8(%1.num)}, %2
|
|
|
|
#if WORD_SIZE!=2
|
|
from consts to memalt2
|
|
gen move_w {const, low16(%1.num)}, %2
|
|
#endif
|
|
|
|
from regAcon %bd==0 to A_REG+areg
|
|
gen move_l %1.reg, %2
|
|
|
|
#ifndef TBL68020
|
|
from t_regAregXcon sfit(%bd, 8) to A_REG+areg
|
|
gen lea {regAregXcon, %1.reg, %1.xreg, 1, %1.bd}, %2
|
|
|
|
from t_regAregXcon to A_REG+areg
|
|
gen lea {regAregXcon, %1.reg, %1.xreg, 1, 0}, %2
|
|
add_l {const4, %1.bd}, %2
|
|
|
|
from t_regAcon sfit(%bd, 16) to A_REG+areg
|
|
gen lea {regAcon, %1.reg, %1.bd}, %2
|
|
|
|
from t_regAcon to A_REG+areg
|
|
gen move_l %1.reg, %2
|
|
add_l {const4, %1.bd}, %2
|
|
#endif /* TBL68020 */
|
|
|
|
from address - ext_addr to A_REG+areg
|
|
gen lea %1, %2
|
|
|
|
#if WORD_SIZE==2
|
|
from ext_addr to A_REG+areg
|
|
gen lea {absolute4, %1.bd}, %2
|
|
#endif
|
|
|
|
from any4 to areg+A_REG
|
|
gen move_l %1, %2
|
|
|
|
from any4 to alterable4-(areg+A_REG)
|
|
gen move_l %1, %2
|
|
|
|
from any2 to alterable2
|
|
gen move_w %1, %2
|
|
|
|
from any1 to alterable1
|
|
gen move_b %1, %2
|
|
|
|
#if WORD_SIZE!=2
|
|
from any4-sconsts4 to A_REG+areg
|
|
gen move_l %1, %2
|
|
|
|
from any2 to dreg4
|
|
gen clr_l %2
|
|
move_w %1, %2
|
|
#endif
|
|
|
|
from any1 to dreg_int
|
|
gen clr_i %2
|
|
move_b %1, %2
|
|
|
|
#if WORD_SIZE==2
|
|
from any1 to dreg2
|
|
gen clr_w %2
|
|
move_b %1, %2
|
|
#endif
|
|
|
|
#if TBL68881
|
|
from data4 to FS_REG
|
|
gen fmove_s %1, %2
|
|
|
|
from FS_REG to datalt4
|
|
gen fmove_s %1, %2
|
|
#endif
|
|
|
|
TESTS
|
|
|
|
/* For the 68020 and m68k4, the extend1_4 will be extend1 */
|
|
to test test_set4-(extend2+extend1+extend1_4)
|
|
gen tst_l %1
|
|
|
|
to test test_set2+extend2
|
|
gen tst_w %1
|
|
|
|
to test test_set1+extend1+extend1_4
|
|
gen tst_b %1
|
|
|
|
|
|
STACKINGRULES
|
|
|
|
|
|
#if WORD_SIZE!=2
|
|
from consts %num==0 to STACK
|
|
gen clr_l {pre_dec4, sp}
|
|
#else
|
|
from zero_const4 to STACK
|
|
gen clr_l {pre_dec4, sp}
|
|
from consts %num==0 to STACK
|
|
gen clr_w {pre_dec2, sp}
|
|
#endif
|
|
|
|
#ifndef TBL68020
|
|
from t_regAregXcon sfit(%bd, 8) to STACK
|
|
gen pea {regAregXcon, %1.reg, %1.xreg, 1, %1.bd}
|
|
|
|
from t_regAregXcon to STACK
|
|
gen pea {regAregXcon, %1.reg, %1.xreg, 1, 0}
|
|
add_l {const4, %1.bd}, {indirect4, sp}
|
|
|
|
from t_regAcon sfit(%bd, 16) to STACK
|
|
gen pea {regAcon, %1.reg, %1.bd}
|
|
|
|
from t_regAcon to STACK
|
|
gen move_l %1.reg, {pre_dec4, sp}
|
|
add_l {const4, %1.bd}, {indirect4, sp}
|
|
#endif /* TBL68020 */
|
|
|
|
from A_REG to STACK
|
|
gen pea {indirect4, %1}
|
|
|
|
from address - ext_addr to STACK
|
|
gen pea %1
|
|
|
|
from ext_addr to STACK
|
|
gen pea {absolute4, %1.bd}
|
|
|
|
#if WORD_SIZE!=2
|
|
from consts to STACK
|
|
gen pea {absolute4, %1.num}
|
|
#else
|
|
from sconsts4 to STACK
|
|
gen pea {absolute4, %1.num}
|
|
from const4 to STACK
|
|
gen pea {absolute4, %1.num}
|
|
#endif
|
|
|
|
from any4 to STACK
|
|
gen move_l %1, {pre_dec4, sp}
|
|
|
|
#if WORD_SIZE!=2
|
|
from any2 to STACK
|
|
uses DD_REG
|
|
gen clr_l %a
|
|
move_w %1, {dreg2, %a}
|
|
move_l %a, {pre_dec4, sp}
|
|
|
|
from any2 to STACK
|
|
gen clr_l {pre_dec4, sp}
|
|
move_w %1, {offsetted2, sp, 2}
|
|
#else
|
|
from any2 to STACK
|
|
gen move_w %1, {pre_dec2, sp}
|
|
#endif
|
|
|
|
from data1 to STACK
|
|
uses DD_REG
|
|
#if WORD_SIZE!=2
|
|
gen clr_l %a
|
|
move_b %1, {dreg1, %a}
|
|
move_l %a, {pre_dec4, sp}
|
|
#else
|
|
gen clr_w %a
|
|
move_b %1, {dreg1, %a}
|
|
move_w %a, {pre_dec2, sp}
|
|
#endif
|
|
|
|
from data1 to STACK
|
|
#if WORD_SIZE!=2
|
|
gen clr_l {pre_dec4, sp}
|
|
move_b %1, {offsetted1, sp, 3}
|
|
#else
|
|
gen clr_w {pre_dec2, sp}
|
|
move_b %1, {offsetted1, sp, 1}
|
|
#endif
|
|
|
|
from extend2 to STACK
|
|
gen ext_l %1.reg
|
|
move_l %1.reg,{pre_dec4, sp}
|
|
|
|
from extend1_4 to STACK
|
|
#ifdef TBL68020
|
|
gen extb_l %1.reg
|
|
#else
|
|
gen ext_w %1.reg
|
|
ext_l %1.reg
|
|
#endif
|
|
move_l %1.reg,{pre_dec4, sp}
|
|
|
|
#if WORD_SIZE==2
|
|
from extend1 to STACK
|
|
gen ext_w %1.reg
|
|
move_w %1.reg,{pre_dec2, sp}
|
|
#endif
|
|
|
|
#ifdef TBL68020
|
|
from regX to STACK
|
|
gen pea %1
|
|
#endif /* TBL68020 */
|
|
/* This last stackingrule is never used: whenever regX is put on
|
|
* the fakestack, some em-instuctions are left that remove it
|
|
* immediately. However cgg complained about not having a
|
|
* stackingrule for regX, so here it is
|
|
*/
|
|
|
|
#if TBL68881
|
|
from FS_REG to STACK
|
|
gen fmove_s %1,{pre_dec4,sp}
|
|
|
|
from FD_REG to STACK
|
|
gen fmove_d %1,{pre_dec4,sp}
|
|
#endif
|
|
COERCIONS
|
|
|
|
|
|
from STACK
|
|
uses DD_REG4
|
|
gen move_l {post_inc4, sp}, %a
|
|
yields %a
|
|
|
|
#if WORD_SIZE==2
|
|
from STACK
|
|
uses DD_REG
|
|
gen move_w {post_inc2,sp}, %a
|
|
yields %a
|
|
#endif
|
|
|
|
from STACK
|
|
uses AA_REG
|
|
gen move_l {post_inc4, sp}, %a
|
|
yields %a
|
|
|
|
#ifdef TBL68881
|
|
from STACK
|
|
uses FS_REG
|
|
gen fmove_s {post_inc4, sp}, %a
|
|
yields %a
|
|
from STACK
|
|
uses FD_REG
|
|
gen fmove_d {post_inc4, sp}, %a
|
|
yields %a
|
|
#endif
|
|
|
|
#ifndef TBL68020
|
|
from t_regAregXcon sfit(%bd, 8)
|
|
yields {regAregXcon, %1.reg, %1.xreg, 1, %1.bd}
|
|
|
|
from t_regAregXcon
|
|
uses AA_REG=%1.reg
|
|
gen add_l {const4, %1.bd}, %a
|
|
yields {regAregXcon, %a, %1.xreg, 1, 0}
|
|
|
|
/*
|
|
* The following coercions are necessary because the code generator
|
|
* must be able to make the token from the real stack, otherwise the
|
|
* coercion will not be made. Unfortunatly, inside a coercion, we are only
|
|
* allowed to allocate 1 register, which means that there is no way to make
|
|
* a regAregXcon from the stack, which, in its turn, means that the other
|
|
* coercions will not be taken.
|
|
*
|
|
/*from STACK
|
|
uses AA_REG, DD_REG4 = {zero_const4, 0}
|
|
gen move_l {post_inc4, sp}, %a
|
|
yields {regAregXcon, %a, %b, 1, 0}
|
|
*/
|
|
from STACK
|
|
uses AA_REG
|
|
gen move_l {post_inc4, sp}, %a
|
|
yields {regAcon, %a, 0}
|
|
|
|
from t_regAcon sfit(%bd, 16)
|
|
yields {regAcon, %1.reg, %1.bd}
|
|
|
|
from t_regAcon
|
|
uses reusing %1, AA_REG=%1.reg
|
|
gen add_l {const4, %1.bd}, %a
|
|
yields %a
|
|
#endif /* TBL68020 */
|
|
|
|
#if WORD_SIZE==2
|
|
from regAregXcon %bd==0 && %sc==1
|
|
uses reusing %1, AA_REG = %1.reg
|
|
gen add_l {dreg4,%1.xreg},%a
|
|
yields %a
|
|
|
|
from regAregXcon %sc==1
|
|
uses reusing %1, AA_REG = %1.reg
|
|
gen add_l {dreg4, %1.xreg}, %a
|
|
yields {regAcon, %a, %1.bd}
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
from sconsts
|
|
uses DD_REG4={const4, %1.num} /* uses moveq */
|
|
yields %a.1
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
from any2
|
|
uses reusing %1, DD_REG = %1 yields %a
|
|
#endif
|
|
|
|
from any4
|
|
uses reusing %1, DD_REG4 = %1
|
|
yields %a
|
|
|
|
from any4
|
|
uses reusing %1, AA_REG = %1
|
|
yields %a
|
|
|
|
from t_address
|
|
uses reusing %1, AA_REG = %1
|
|
yields %a
|
|
|
|
#if TBL68881
|
|
from data4
|
|
uses reusing %1, FS_REG = %1
|
|
yields %a
|
|
#endif
|
|
|
|
from memory2
|
|
uses DD_REG
|
|
#if WORD_SIZE!=2
|
|
= {zero_const, 0}
|
|
#endif
|
|
gen move_w %1, %a yields %a
|
|
|
|
from memory1
|
|
uses DD_REG = {zero_const, 0}
|
|
gen move_b %1, %a yields %a
|
|
|
|
from memory2
|
|
uses DD_REG
|
|
gen move_w %1, %a yields {dreg2, %a}
|
|
|
|
from memory1
|
|
uses DD_REG
|
|
gen move_b %1, %a yields {dreg1, %a}
|
|
|
|
from extend2
|
|
gen ext_l %1.reg yields %1.reg
|
|
|
|
#if WORD_SIZE==2
|
|
from extend1
|
|
gen ext_w %1.reg yields %1.reg
|
|
#endif
|
|
|
|
from extend1_4
|
|
#ifdef TBL68020
|
|
gen extb_l %1.reg
|
|
#else
|
|
gen ext_w %1.reg
|
|
ext_l %1.reg
|
|
#endif
|
|
yields %1.reg
|
|
|
|
PATTERNS
|
|
|
|
/********************************
|
|
* First some longer patterns *
|
|
********************************/
|
|
|
|
pat lol sbi stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
with any_int
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen sub_i %1, {LOCAL, $1}
|
|
neg_i {LOCAL, $1}
|
|
|
|
pat lol sbi stl $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_pointer
|
|
with conreg_int-bconst
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen sub_i %1, {LOCAL, $1}
|
|
neg_i {LOCAL, $1}
|
|
|
|
pat lol sbu stl $1==$3 && $2==WORD_SIZE
|
|
leaving lol $1 sbi WORD_SIZE stl $1
|
|
|
|
pat lil sbi sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
gen sub_i %1, {indirect_int, regvar($1, reg_pointer)}
|
|
neg_i {indirect_int, regvar($1, reg_pointer)}
|
|
|
|
pat lil sbi sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen sub_i %1, {indirect_int, %a}
|
|
neg_i {indirect_int, %a}
|
|
|
|
pat lil sbu sil $1==$3 && $2==WORD_SIZE
|
|
leaving lil $1 sbi WORD_SIZE sil $1
|
|
|
|
proc lolrbitstl example lol ngi stl
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen bit* {LOCAL, $1}
|
|
|
|
pat lol ngi stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
call lolrbitstl(NEG_I)
|
|
pat lol com stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
call lolrbitstl(NOT_I)
|
|
|
|
proc lolbitstl example lol ngi stl
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen bit* {LOCAL, $1}
|
|
|
|
pat lol ngi stl $1==$3 && $2==WORD_SIZE call lolbitstl(NEG_I)
|
|
pat lol com stl $1==$3 && $2==WORD_SIZE call lolbitstl(NOT_I)
|
|
#if WORD_SIZE==2
|
|
proc ldlbitsdl example ldl ngi sdl
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen bit* {DLOCAL, $1}
|
|
|
|
pat ldl ngi sdl $1==$3 && $2==4 call ldlbitsdl("neg.l")
|
|
pat ldl com sdl $1==$3 && $2==4 call ldlbitsdl("not.l")
|
|
#endif
|
|
|
|
proc loebitste example loe ngi ste
|
|
kills posextern
|
|
gen bit* {absolute_int, $1}
|
|
|
|
pat loe ngi ste $1==$3 && $2==WORD_SIZE call loebitste(NEG_I)
|
|
pat loe com ste $1==$3 && $2==WORD_SIZE call loebitste(NOT_I)
|
|
#if WORD_SIZE==2
|
|
proc ldebitsde example lde ngi sde
|
|
kills posextern
|
|
gen bit* {absolute4, $1}
|
|
|
|
pat lde ngi sde $1==$3 && $2==4 call ldebitsde("neg.l")
|
|
pat lde com sde $1==$3 && $2==4 call ldebitsde("not.l")
|
|
#endif
|
|
|
|
proc lilrbitsil example lil ngi sil
|
|
kills allexceptcon
|
|
gen bit* {indirect_int, regvar($1, reg_pointer)}
|
|
|
|
pat lil ngi sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilrbitsil(NEG_I)
|
|
pat lil com sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilrbitsil(NOT_I)
|
|
pat lil dec sil $1==$3 && inreg($1)==reg_pointer
|
|
call lilrbitsil(DEC)
|
|
pat lil inc sil $1==$3 && inreg($1)==reg_pointer
|
|
call lilrbitsil(INC)
|
|
|
|
proc lilbitsil example lil ngi sil
|
|
kills allexceptcon
|
|
#if TBL68020
|
|
gen bit* {ILOCAL, $1}
|
|
#else
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen bit* {indirect_int, %a}
|
|
#endif
|
|
|
|
pat lil ngi sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilbitsil(NEG_I)
|
|
pat lil com sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilbitsil(NOT_I)
|
|
pat lil dec sil $1==$3 && inreg($1)!=reg_any
|
|
call lilbitsil(DEC)
|
|
pat lil inc sil $1==$3 && inreg($1)!=reg_any
|
|
call lilbitsil(INC)
|
|
|
|
proc lolcshstl example lol loc sli stl
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen sh* {small_const, $2}, {LOCAL, $1}
|
|
|
|
pat lol loc sli stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcshstl(ASL_I)
|
|
pat lol loc sri stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcshstl(ASR_I)
|
|
pat lol loc slu stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcshstl(ASL_I)
|
|
pat lol loc sru stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcshstl(LSR_I)
|
|
pat lol loc rol stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcshstl(ROL_I)
|
|
pat lol loc ror stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcshstl(ROR_I)
|
|
|
|
proc lolrshstl example lol lol sli stl
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen sh* {LOCAL, $2}, {LOCAL, $1}
|
|
|
|
pat lol lol sli stl $1==$4 && inreg($1)==reg_any && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any
|
|
call lolrshstl(ASL_I)
|
|
pat lol lol slu stl $1==$4 && inreg($1)==reg_any && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any
|
|
call lolrshstl(ASL_I)
|
|
pat lol lol sri stl $1==$4 && inreg($1)==reg_any && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any
|
|
call lolrshstl(ASR_I)
|
|
pat lol lol sru stl $1==$4 && inreg($1)==reg_any && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any
|
|
call lolrshstl(LSR_I)
|
|
pat lol lol rol stl $1==$4 && inreg($2)==reg_any && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any
|
|
call lolrshstl(ROL_I)
|
|
pat lol lol ror stl $1==$4 && inreg($2)==reg_any && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any
|
|
call lolrshstl(ROR_I)
|
|
|
|
#if WORD_SIZE!=2
|
|
proc lil1shlsil example lil loc sli sil /* only left */
|
|
kills allexceptcon
|
|
gen shw* {offsetted2, regvar($1, reg_pointer), 2}
|
|
roxl {indirect2, regvar($1, reg_pointer)}
|
|
|
|
pat lil loc sli sil $1==$4 && $2==1 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lil1shlsil("asl #1,")
|
|
pat lil loc slu sil $1==$4 && $2==1 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lil1shlsil("asl #1,")
|
|
|
|
proc lil1shrsil example lil loc sli sil /* only right */
|
|
kills allexceptcon
|
|
gen shw* {indirect2, regvar($1, reg_pointer)}
|
|
roxr {offsetted2, regvar($1, reg_pointer), 2}
|
|
|
|
pat lil loc sri sil $1==$4 && $2==1 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lil1shrsil("asr #1,")
|
|
pat lil loc sru sil $1==$4 && $2==1 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lil1shrsil("lsr #1,")
|
|
|
|
#endif
|
|
|
|
|
|
pat LLP lof inc LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
gen add_i {const, 1}, {offsetted_int, regvar($1, reg_pointer), $2}
|
|
|
|
pat LLP lof dec LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
gen sub_i {const, 1}, {offsetted_int, regvar($1, reg_pointer), $2}
|
|
|
|
/* the patterns with adp should use add_l */
|
|
pat LLP LFP adp LLP SFP $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
gen add_l {const4, $3}, {offsetted4, regvar($1, reg_pointer), $2}
|
|
|
|
pat LEP LFP adp LEP SFP $1==$4 && $2==$5
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen add_l {const4, $3}, {ABS_off4, $1, $2}
|
|
#else
|
|
uses AA_REG={absolute4, $1}
|
|
gen add_l {const4, $3}, {offsetted4, %a, $2}
|
|
#endif
|
|
|
|
pat LEP loi adp LEP sti $1==$4 && $2==4 && $5==4
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen add_l {const4, $3}, {ABS_off4, $1, 0}
|
|
#else
|
|
uses AA_REG={absolute4, $1}
|
|
gen add_l {const4, $3}, {indirect4, %a}
|
|
#endif
|
|
|
|
#if WORD_SIZE!=2
|
|
pat lil lof adp lil stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen add_l {const4, $3}, {OFF_off4, regvar($1, reg_pointer), 0, $2}
|
|
#else
|
|
uses AA_REG={indirect4, regvar($1, reg_pointer)}
|
|
gen add_l {const4, $3}, {offsetted4, %a, $2}
|
|
#endif
|
|
|
|
pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen add_l {const4, $3}, {OFF_off4, regvar($1, reg_pointer), 0, 0}
|
|
#else
|
|
uses AA_REG={indirect4, regvar($1, reg_pointer)}
|
|
gen add_l {const4, $3}, {indirect4, %a}
|
|
#endif
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
pat lol inl $1==$2 && inreg($1)==reg_any
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
uses DD_REG = {LOCAL, $1}
|
|
gen add_i {const, 1}, {LOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lol del $1==$2 && inreg($1)==reg_any
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
uses DD_REG = {LOCAL, $1}
|
|
gen sub_i {const, 1}, {LOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
/* the following rules are for unsigneds, since del and inl work on ints */
|
|
pat lol loc lol adu stl $1==$3 && $3==$5 && $4==WORD_SIZE && inreg($1)==reg_any
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
uses DD_REG = {LOCAL, $1}
|
|
gen add_i {const, $2}, {LOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lol loc lol adu stl $1==$3 && $3==$5 && $4==WORD_SIZE
|
|
kills all_indir, LOCAL %bd==$1
|
|
uses DD_REG = {LOCAL, $1}
|
|
gen add_i {const, $2}, {LOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lol dup loc sbu stl $1==$5 && $2==WORD_SIZE && $4==WORD_SIZE && inreg($1)==reg_any
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
uses DD_REG = {LOCAL, $1}
|
|
gen sub_i {const, $3}, {LOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lol dup loc sbu stl $1==$5 && $2==WORD_SIZE && $4==WORD_SIZE
|
|
kills all_indir, LOCAL %bd==$1
|
|
uses DD_REG = {LOCAL, $1}
|
|
gen sub_i {const, $3}, {LOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat loe loc loe adu ste $1==$3 && $3==$5 && $4==WORD_SIZE
|
|
kills posextern
|
|
uses DD_REG = {absolute_int, $1}
|
|
gen add_i {const,$2}, {absolute_int, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat loe dup loc sbu ste $1==$5 && $2==WORD_SIZE && $4==WORD_SIZE
|
|
kills posextern
|
|
uses DD_REG = {absolute_int, $1}
|
|
gen sub_i {const,$3}, {absolute_int, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lil loc lil adu sil $1==$3 && $3==$5 && $4==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
uses DD_REG = {indirect_int, regvar($1, reg_pointer)}
|
|
gen add_i {const, $2}, {indirect_int, regvar($1, reg_pointer)}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lil dup loc sbu sil $1==$5 && $2==WORD_SIZE && $4==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
uses DD_REG = {indirect_int, regvar($1, reg_pointer)}
|
|
gen sub_i {const, $3}, {indirect_int, regvar($1, reg_pointer)}
|
|
killreg %a
|
|
yields %a
|
|
|
|
proc lolxxstl example lol and stl
|
|
with data_int-bconst
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen xxx* %1, {LOCAL, $1}
|
|
|
|
pat lol adi stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
call lolxxstl(ADD_I)
|
|
pat lol adu stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
call lolxxstl(ADD_I)
|
|
pat lol and stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
call lolxxstl(AND_I)
|
|
pat lol ior stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
call lolxxstl(OR_I)
|
|
pat lol xor stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
with conreg_int-bconst
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen eor_i %1, {LOCAL, $1}
|
|
|
|
#if TBL68020 || WORD_SIZE==2
|
|
pat lol mli stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
with data_int
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen muls_i %1, {LOCAL, $1}
|
|
pat lol mlu stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
|
|
with data_int
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen mulu_i %1, {LOCAL, $1}
|
|
#endif /* TBL68020 */
|
|
|
|
proc lolxxxstl example lol adi stl
|
|
with conreg_int-bconst
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen xxx* %1, {LOCAL, $1}
|
|
|
|
pat lol adi stl $1==$3 && $2==WORD_SIZE call lolxxxstl(ADD_I)
|
|
pat lol adu stl $1==$3 && $2==WORD_SIZE call lolxxxstl(ADD_I)
|
|
pat lol and stl $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_pointer
|
|
call lolxxxstl(AND_I)
|
|
pat lol ior stl $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_pointer
|
|
call lolxxxstl(OR_I)
|
|
pat lol xor stl $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_pointer
|
|
call lolxxxstl(EOR_I)
|
|
|
|
#if WORD_SIZE==2
|
|
proc ldlxxxsdl example lol adi stl
|
|
with conreg4-bconst4
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen xxx* %1, {DLOCAL, $1}
|
|
|
|
pat ldl adi sdl $1==$3 && $2==4 call ldlxxxsdl("add.l")
|
|
pat ldl adu sdl $1==$3 && $2==4 call ldlxxxsdl("add.l")
|
|
pat ldl and sdl $1==$3 && $2==4 && inreg($1)!=reg_pointer
|
|
call ldlxxxsdl("and.l")
|
|
pat ldl ior sdl $1==$3 && $2==4 && inreg($1)!=reg_pointer
|
|
call ldlxxxsdl("or.l")
|
|
pat ldl xor sdl $1==$3 && $2==4 && inreg($1)!=reg_pointer
|
|
call ldlxxxsdl("eor.l")
|
|
#endif
|
|
|
|
proc lilxxsil example lil and sil
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
gen xxx* %1, {indirect_int, regvar($1, reg_pointer)}
|
|
|
|
pat lil adi sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilxxsil(ADD_I)
|
|
pat lil adu sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilxxsil(ADD_I)
|
|
pat lil and sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilxxsil(AND_I)
|
|
pat lil ior sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilxxsil(OR_I)
|
|
pat lil xor sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilxxsil(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat lil ads sil $1==$3 && $2==4 && inreg($1)==reg_pointer
|
|
call lilxxsil("add.l")
|
|
#endif
|
|
|
|
proc lilxxxsil example lil adi sil
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
#if TBL68020
|
|
gen xxx* %1, {ILOCAL, $1}
|
|
#else
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen xxx* %1, {indirect_int, %a}
|
|
#endif
|
|
|
|
pat lil adi sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilxxxsil(ADD_I)
|
|
pat lil adu sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilxxxsil(ADD_I)
|
|
pat lil and sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilxxxsil(AND_I)
|
|
pat lil ior sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilxxxsil(OR_I)
|
|
pat lil xor sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilxxxsil(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat lil ads sil $1==$3 && $2==4 && inreg($1)!=reg_any
|
|
call lilxxxsil("add.l")
|
|
#endif
|
|
|
|
proc loexxxste example loe adi ste
|
|
with conreg_int-bconst
|
|
kills posextern
|
|
gen xxx* %1, {absolute_int, $1}
|
|
|
|
pat loe adi ste $1==$3 && $2==WORD_SIZE call loexxxste(ADD_I)
|
|
pat loe adu ste $1==$3 && $2==WORD_SIZE call loexxxste(ADD_I)
|
|
pat loe and ste $1==$3 && $2==WORD_SIZE call loexxxste(AND_I)
|
|
pat loe ior ste $1==$3 && $2==WORD_SIZE call loexxxste(OR_I)
|
|
pat loe xor ste $1==$3 && $2==WORD_SIZE call loexxxste(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat loe ads ste $1==$3 && $2==4 call loexxxste("add.l")
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
proc ldexxxsde example lde adi sde
|
|
with conreg4-bconst4
|
|
kills posextern
|
|
gen xxx* %1, {absolute4, $1}
|
|
|
|
pat lde adi sde $1==$3 && $2==4 call ldexxxsde("add.l")
|
|
pat lde adu sde $1==$3 && $2==4 call ldexxxsde("add.l")
|
|
pat lde and sde $1==$3 && $2==4 call ldexxxsde("and.l")
|
|
pat lde ior sde $1==$3 && $2==4 call ldexxxsde("or.l")
|
|
pat lde xor sde $1==$3 && $2==4 call ldexxxsde("eor.l")
|
|
#endif
|
|
|
|
proc lollilxxxstl example lol lil adi stl
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen xxx* {indirect_int, regvar($2, reg_pointer)}, {LOCAL, $1}
|
|
|
|
pat lol lil adi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollilxxxstl(ADD_I)
|
|
pat lol lil adu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollilxxxstl(ADD_I)
|
|
pat lol lil sbi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollilxxxstl(SUB_I)
|
|
pat lol lil sbu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollilxxxstl(SUB_I)
|
|
pat lol lil and stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollilxxxstl(AND_I)
|
|
pat lol lil ior stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollilxxxstl(OR_I)
|
|
|
|
proc lollfixxxstl example lol LLP lof adi stl
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen xxx* {offsetted_int, regvar($2, reg_pointer), $3}, {LOCAL, $1}
|
|
|
|
pat lol LLP lof adi stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollfixxxstl(ADD_I)
|
|
pat lol LLP lof adu stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollfixxxstl(ADD_I)
|
|
pat lol LLP lof sbi stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollfixxxstl(SUB_I)
|
|
pat lol LLP lof sbu stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollfixxxstl(SUB_I)
|
|
pat lol LLP lof and stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollfixxxstl(AND_I)
|
|
pat lol LLP lof ior stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
|
|
&& inreg($2)==reg_pointer
|
|
call lollfixxxstl(OR_I)
|
|
|
|
|
|
proc lolfrxlolf example LLP lof and LLP stf
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
gen xxx* %1, {offsetted_int, regvar($1, reg_pointer), $2}
|
|
|
|
pat LLP lof adi LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
call lolfrxlolf(ADD_I)
|
|
pat LLP lof adu LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
call lolfrxlolf(ADD_I)
|
|
pat LLP lof and LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
call lolfrxlolf(AND_I)
|
|
pat LLP lof ior LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
call lolfrxlolf(OR_I)
|
|
pat LLP lof xor LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
call lolfrxlolf(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat LLP lof ads LLP stf $1==$4 && $2==$5 && $3==4
|
|
&& inreg($1)==reg_pointer
|
|
call lolfrxlolf("add.l")
|
|
#endif
|
|
|
|
proc lolfxxlolf example LLP lof and LLP stf
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen xxx* %1, {OFF_off_int, lb, $1, $2}
|
|
#else
|
|
uses AA_REG={DLOCAL, $1}
|
|
gen xxx* %1, {offsetted_int, %a, $2}
|
|
#endif
|
|
|
|
pat LLP lof adi LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lolfxxlolf(ADD_I)
|
|
pat LLP lof adu LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lolfxxlolf(ADD_I)
|
|
pat LLP lof and LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lolfxxlolf(AND_I)
|
|
pat LLP lof ior LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lolfxxlolf(OR_I)
|
|
pat LLP lof xor LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lolfxxlolf(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat LLP lof ads LLP stf $1==$4 && $2==$5 && $3==4
|
|
call lolfxxlolf("add.l")
|
|
#endif
|
|
|
|
#if WORD_SIZE!=2
|
|
proc lilfxxlilf example lil lof and lil stf
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen xxx* %1, {OFF_off4, regvar($1, reg_pointer), 0, $2}
|
|
#else
|
|
uses AA_REG={indirect4, regvar($1, reg_pointer)}
|
|
gen xxx* %1, {offsetted_int, %a, $2}
|
|
#endif
|
|
|
|
pat lil lof adi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
|
|
call lilfxxlilf("add.l")
|
|
pat lil lof adu lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
|
|
call lilfxxlilf("add.l")
|
|
pat lil lof and lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
|
|
call lilfxxlilf("and.l")
|
|
pat lil lof ior lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
|
|
call lilfxxlilf("or.l")
|
|
pat lil lof xor lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
|
|
call lilfxxlilf("eor.l")
|
|
pat lil lof ads lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
|
|
call lilfxxlilf("add.l")
|
|
#endif
|
|
|
|
proc lefxxxsef example loe lof and loe stf
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen xxx* %1, {ABS_off_int, $1, $2}
|
|
#else
|
|
uses AA_REG={absolute4, $1}
|
|
gen xxx* %1, {offsetted_int, %a, $2}
|
|
#endif
|
|
|
|
pat LEP lof adi LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lefxxxsef(ADD_I)
|
|
pat LEP lof adu LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lefxxxsef(ADD_I)
|
|
pat LEP lof and LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lefxxxsef(AND_I)
|
|
pat LEP lof ior LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lefxxxsef(OR_I)
|
|
pat LEP lof xor LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lefxxxsef(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat LEP lof ads LEP stf $1==$4 && $2==$5 && $3==4
|
|
call lefxxxsef("add.l")
|
|
#endif
|
|
|
|
/* lil gets a word, not necessarily a pointer */
|
|
#if WORD_SIZE!=2
|
|
proc lilixxlili example lil loi and lil sti
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen xxx* %1, {OFF_off4, regvar($1, reg_pointer), 0, 0}
|
|
#else
|
|
uses AA_REG={indirect4, regvar($1, reg_pointer)}
|
|
gen xxx* %1, {indirect4, %a}
|
|
#endif
|
|
|
|
pat lil loi adi lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
|
|
&& inreg($1)==reg_pointer
|
|
call lilixxlili("add.l")
|
|
pat lil loi adu lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
|
|
&& inreg($1)==reg_pointer
|
|
call lilixxlili("add.l")
|
|
pat lil loi and lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
|
|
&& inreg($1)==reg_pointer
|
|
call lilixxlili("and.l")
|
|
pat lil loi ior lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
|
|
&& inreg($1)==reg_pointer
|
|
call lilixxlili("or.l")
|
|
pat lil loi xor lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
|
|
&& inreg($1)==reg_pointer
|
|
call lilixxlili("eor.l")
|
|
pat lil loi ads lil sti $1==$4 && $2==$3 && $2==$5 && $3==4
|
|
&& inreg($1)==reg_pointer
|
|
call lilixxlili("add.l")
|
|
#endif
|
|
|
|
proc leixxxsei example loe loi and loe sti
|
|
with conreg_int-bconst
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen xxx* %1, {ABS_off_int, $1, 0}
|
|
#else
|
|
uses AA_REG={absolute4, $1}
|
|
gen xxx* %1, {indirect_int, %a}
|
|
#endif
|
|
|
|
pat LEP loi adi LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
|
|
call leixxxsei(ADD_I)
|
|
pat LEP loi adu LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
|
|
call leixxxsei(ADD_I)
|
|
pat LEP loi and LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
|
|
call leixxxsei(AND_I)
|
|
pat LEP loi ior LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
|
|
call leixxxsei(OR_I)
|
|
pat LEP loi xor LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
|
|
call leixxxsei(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat LEP loi ads LEP sti $1==$4 && $2==$3 && $2==$5 && $2==4
|
|
call leixxxsei("add.l")
|
|
#endif
|
|
|
|
proc lofruxxsof example LLP lof inc LLP stf
|
|
kills allexceptcon
|
|
gen bit* {offsetted_int, regvar($1, reg_pointer), $2}
|
|
|
|
pat LLP lof inc LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
call lofruxxsof(INC)
|
|
pat LLP lof dec LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
call lofruxxsof(DEC)
|
|
pat LLP lof ngi LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
&& $3==WORD_SIZE
|
|
call lofruxxsof(NEG_I)
|
|
pat LLP lof com LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
&& $3==WORD_SIZE
|
|
call lofruxxsof(NOT_I)
|
|
|
|
proc lofuxxsof example LLP lof inc LLP stf
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen bit* {OFF_off_int, lb, $1, $2}
|
|
#else
|
|
uses AA_REG={DLOCAL,$1}
|
|
gen bit* {offsetted_int,%a,$2}
|
|
#endif
|
|
|
|
pat LLP lof inc LLP stf $1==$4 && $2==$5
|
|
call lofuxxsof(INC)
|
|
pat LLP lof dec LLP stf $1==$4 && $2==$5
|
|
call lofuxxsof(DEC)
|
|
pat LLP lof ngi LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lofuxxsof(NEG_I)
|
|
pat LLP lof com LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
|
|
call lofuxxsof(NOT_I)
|
|
|
|
#if WORD_SIZE!=2
|
|
proc lifuxxsif example lil lof inc lil stf
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen bit* {OFF_off4, regvar($1, reg_pointer), 0, $2}
|
|
#else
|
|
uses AA_REG={indirect4, regvar($1, reg_pointer)}
|
|
gen bit* {offsetted4,%a,$2}
|
|
#endif
|
|
|
|
pat lil lof inc lil stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
call lifuxxsif("add.l #1,")
|
|
pat lil lof dec lil stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
|
|
call lifuxxsif("sub.l #1,")
|
|
pat lil lof ngi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
|
|
call lifuxxsif("neg.l")
|
|
pat lil lof com lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
|
|
call lifuxxsif("not.l")
|
|
#endif
|
|
|
|
#if WORD_SIZE!=2
|
|
proc liiuxxsii example lil loi inc lil sti
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen bit* {OFF_off4, regvar($1, reg_pointer), 0, 0}
|
|
#else
|
|
uses AA_REG={indirect4, regvar($1, reg_pointer)}
|
|
gen bit* {indirect4, %a}
|
|
#endif
|
|
|
|
pat lil loi inc lil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_pointer
|
|
call liiuxxsii("add.l #1,")
|
|
pat lil loi dec lil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_pointer
|
|
call liiuxxsii("sub.l #1,")
|
|
pat lil loi ngi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)==reg_pointer
|
|
call liiuxxsii("neg.l")
|
|
pat lil loi com lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)==reg_pointer
|
|
call liiuxxsii("not.l")
|
|
#endif
|
|
|
|
proc lefuxxsef example loe lof inc loe stf
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen bit* {ABS_off_int, $1, $2}
|
|
#else
|
|
uses AA_REG={absolute4, $1}
|
|
gen bit* {offsetted_int, %a, $2}
|
|
#endif
|
|
|
|
pat LEP lof inc LEP stf $1==$4 && $2==$5
|
|
call lefuxxsef(INC)
|
|
pat LEP lof dec LEP stf $1==$4 && $2==$5
|
|
call lefuxxsef(DEC)
|
|
pat LEP lof ngi LEP stf $1==$4 && $2==$5 && $3==4
|
|
call lefuxxsef(NEG_I)
|
|
pat LEP lof com LEP stf $1==$4 && $2==$5 && $3==4
|
|
call lefuxxsef(NOT_I)
|
|
|
|
proc leiuxxsei example loe loi inc loe sti
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen bit* {ABS_off_int, $1, 0}
|
|
#else
|
|
uses AA_REG={absolute4, $1}
|
|
gen bit* {indirect_int, %a}
|
|
#endif
|
|
|
|
pat LEP loi inc LEP sti $1==$4 && $2==$5 && $2==WORD_SIZE
|
|
call leiuxxsei(INC)
|
|
pat LEP loi dec LEP sti $1==$4 && $2==$5 && $2==WORD_SIZE
|
|
call leiuxxsei(DEC)
|
|
pat LEP loi ngi LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
|
|
call leiuxxsei(NEG_I)
|
|
pat LEP loi com LEP sti $1==$4 && $2==$3 && 2==$5 && $2==WORD_SIZE
|
|
call leiuxxsei(NOT_I)
|
|
|
|
proc lolcxxstl example lol loc and stl
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen xxx* {const, $2}, {LOCAL, $1}
|
|
|
|
/*
|
|
pat lol loc adi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(ADD_I)
|
|
pat lol loc adu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(ADD_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
pat lol loc sbi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(SUB_I)
|
|
pat lol loc sbu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(SUB_I)
|
|
/*
|
|
pat lol loc and stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(AND_I)
|
|
pat lol loc ior stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(OR_I)
|
|
pat lol loc xor stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(EOR_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
#if TBL68020 || WORDSIZE==2
|
|
#if WORD_SIZE==4
|
|
pat lol loc dvi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(DIVS_I)
|
|
pat lol loc dvu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(DIVU_I)
|
|
#endif
|
|
pat lol loc mli stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(MULS_I)
|
|
pat lol loc mlu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
|
|
call lolcxxstl(MULU_I)
|
|
#endif
|
|
|
|
proc lolcxxxstl example lol loc adi stl
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen xxx* {const, $2}, {LOCAL, $1}
|
|
|
|
/*
|
|
pat lol loc adi stl $1==$4 && $3==WORD_SIZE call lolcxxxstl(ADD_I)
|
|
pat lol loc adu stl $1==$4 && $3==WORD_SIZE call lolcxxxstl(ADD_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
pat lol loc sbi stl $1==$4 && $3==WORD_SIZE call lolcxxxstl(SUB_I)
|
|
pat lol loc sbu stl $1==$4 && $3==WORD_SIZE call lolcxxxstl(SUB_I)
|
|
/*
|
|
pat lol loc and stl $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_pointer
|
|
call lolcxxxstl(AND_I)
|
|
pat lol loc ior stl $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_pointer
|
|
call lolcxxxstl(OR_I)
|
|
pat lol loc xor stl $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_pointer
|
|
call lolcxxxstl(EOR_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
#if WORD_SIZE==2
|
|
proc ldlcxxxsdl example ldl ldc adi sdl
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen xxx* {const4, $2}, {DLOCAL, $1}
|
|
|
|
pat ldl ldc sbi sdl $1==$4 && $3==4 call ldlcxxxsdl("sub.l")
|
|
pat ldl ldc sbu sdl $1==$4 && $3==4 call ldlcxxxsdl("sub.l")
|
|
#endif
|
|
|
|
proc lilcxxsil example lil loc and sil
|
|
kills allexceptcon
|
|
gen xxx* {const, $2}, {indirect_int, regvar($1, reg_pointer)}
|
|
|
|
pat lil loc adi sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilcxxsil(ADD_I)
|
|
pat lil loc adu sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilcxxsil(ADD_I)
|
|
pat lil loc sbi sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilcxxsil(SUB_I)
|
|
pat lil loc sbu sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilcxxsil(SUB_I)
|
|
pat lil loc and sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilcxxsil(AND_I)
|
|
pat lil loc ior sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilcxxsil(OR_I)
|
|
pat lil loc xor sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
call lilcxxsil(EOR_I)
|
|
|
|
proc lilcxxxsil example lil loc adi sil
|
|
kills allexceptcon
|
|
#if TBL68020
|
|
gen xxx* {const, $2}, {ILOCAL, $1}
|
|
#else
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen xxx* {const, $2}, {indirect_int, %a}
|
|
#endif
|
|
|
|
pat lil loc adi sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilcxxxsil(ADD_I)
|
|
pat lil loc adu sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilcxxxsil(ADD_I)
|
|
pat lil loc sbi sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilcxxxsil(SUB_I)
|
|
pat lil loc sbu sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilcxxxsil(SUB_I)
|
|
pat lil loc and sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilcxxxsil(AND_I)
|
|
pat lil loc ior sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilcxxxsil(OR_I)
|
|
pat lil loc xor sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
|
|
call lilcxxxsil(EOR_I)
|
|
|
|
proc loecxxxste example loe loc adi ste
|
|
kills posextern
|
|
gen xxx* {const, $2}, {absolute4, $1}
|
|
|
|
/*
|
|
pat loe loc adi ste $1==$4 && $3==WORD_SIZE call loecxxxste(ADD_I)
|
|
pat loe loc adu ste $1==$4 && $3==WORD_SIZE call loecxxxste(ADD_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
pat loe loc sbi ste $1==$4 && $3==WORD_SIZE call loecxxxste(SUB_I)
|
|
pat loe loc sbu ste $1==$4 && $3==WORD_SIZE call loecxxxste(SUB_I)
|
|
/*
|
|
pat loe loc and ste $1==$4 && $3==WORD_SIZE call loecxxxste(AND_I)
|
|
pat loe loc ior ste $1==$4 && $3==WORD_SIZE call loecxxxste(OR_I)
|
|
pat loe loc xor ste $1==$4 && $3==WORD_SIZE call loecxxxste(EOR_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
|
|
proc lolrxxstl example lol lol and stl
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen xxx* {LOCAL, $2}, {LOCAL, $1}
|
|
|
|
/*
|
|
pat lol lol adi stl $1==$4 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any && inreg($2)==reg_any
|
|
call lolrxxstl(ADD_I)
|
|
pat lol lol adu stl $1==$4 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any && inreg($2)==reg_any
|
|
call lolrxxstl(ADD_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
pat lol lol sbi stl $1==$4 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any && inreg($2)==reg_any
|
|
call lolrxxstl(SUB_I)
|
|
pat lol lol sbu stl $1==$4 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any && inreg($2)==reg_any
|
|
call lolrxxstl(SUB_I)
|
|
/*
|
|
pat lol lol and stl $1==$4 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any && inreg($2)==reg_any
|
|
call lolrxxstl(AND_I)
|
|
pat lol lol ior stl $1==$4 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any && inreg($2)==reg_any
|
|
call lolrxxstl(OR_I)
|
|
pat lol lol xor stl $1==$4 && $3==WORD_SIZE
|
|
&& inreg($1)==reg_any && inreg($2)==reg_any
|
|
call lolrxxstl(EOR_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
|
|
proc lolrxxxstl example lol lol adi stl
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen xxx* {LOCAL, $2}, {LOCAL, $1}
|
|
|
|
/*
|
|
pat lol lol adi stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call lolrxxxstl(ADD_I)
|
|
pat lol lol adu stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call lolrxxxstl(ADD_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
#if WORD_SIZE!=2
|
|
pat lol lol ads stl $1==$4 && $3==4 && inreg($2)==reg_any
|
|
call lolrxxxstl("add.l")
|
|
#endif
|
|
pat lol lol sbi stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call lolrxxxstl(SUB_I)
|
|
pat lol lol sbu stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call lolrxxxstl(SUB_I)
|
|
/*
|
|
pat lol lol and stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any && inreg($1)!=reg_pointer
|
|
call lolrxxxstl(AND_I)
|
|
pat lol lol ior stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any &&
|
|
inreg($1)!=reg_pointer
|
|
call lolrxxxstl(OR_I)
|
|
pat lol lol xor stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any &&
|
|
inreg($1)!=reg_pointer
|
|
call lolrxxxstl(EOR_I)
|
|
peephole optimizer replaces these
|
|
*/
|
|
|
|
proc lilrxxsil example lil lol and sil
|
|
kills allexceptcon
|
|
gen xxx* {LOCAL, $2}, {indirect_int, regvar($1, reg_pointer)}
|
|
|
|
pat lil lol adi sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
|
|
inreg($2)==reg_any
|
|
call lilrxxsil(ADD_I)
|
|
pat lil lol adu sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
|
|
inreg($2)==reg_any
|
|
call lilrxxsil(ADD_I)
|
|
pat lil lol sbi sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
|
|
inreg($2)==reg_any
|
|
call lilrxxsil(SUB_I)
|
|
pat lil lol sbu sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
|
|
inreg($2)==reg_any
|
|
call lilrxxsil(SUB_I)
|
|
pat lil lol and sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
|
|
inreg($2)==reg_any
|
|
call lilrxxsil(AND_I)
|
|
pat lil lol ior sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
|
|
inreg($2)==reg_any
|
|
call lilrxxsil(OR_I)
|
|
pat lil lol xor sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
|
|
inreg($2)==reg_any
|
|
call lilrxxsil(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat lil lol ads sil $1==$4 && $3==4 && inreg($1)==reg_pointer &&
|
|
inreg($2)==reg_any
|
|
call lilrxxsil("add.l")
|
|
#endif
|
|
|
|
proc lilrxxxsil example lil lol adi sil
|
|
kills allexceptcon
|
|
#if TBL68020
|
|
gen xxx* {LOCAL, $2}, {ILOCAL, $1}
|
|
#else
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen xxx* {LOCAL, $2}, {indirect_int, %a}
|
|
#endif
|
|
|
|
pat lil lol adi sil $1==$4 && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any && inreg($1)!=reg_any
|
|
call lilrxxxsil(ADD_I)
|
|
pat lil lol adu sil $1==$4 && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any && inreg($1)!=reg_any
|
|
call lilrxxxsil(ADD_I)
|
|
pat lil lol sbi sil $1==$4 && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any && inreg($1)!=reg_any
|
|
call lilrxxxsil(SUB_I)
|
|
pat lil lol sbu sil $1==$4 && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any && inreg($1)!=reg_any
|
|
call lilrxxxsil(SUB_I)
|
|
pat lil lol and sil $1==$4 && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any && inreg($1)!=reg_any
|
|
call lilrxxxsil(AND_I)
|
|
pat lil lol ior sil $1==$4 && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any && inreg($1)!=reg_any
|
|
call lilrxxxsil(OR_I)
|
|
pat lil lol xor sil $1==$4 && $3==WORD_SIZE
|
|
&& inreg($2)==reg_any && inreg($1)!=reg_any
|
|
call lilrxxxsil(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat lil lol ads sil $1==$4 && $3==4 && inreg($2)==reg_any && inreg($1)!=reg_any
|
|
call lilrxxxsil("add.l")
|
|
#endif
|
|
|
|
proc loerxxxste example loe lol adi ste
|
|
kills posextern
|
|
gen xxx* {LOCAL, $2}, {absolute_int, $1}
|
|
|
|
pat loe lol adi ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call loerxxxste(ADD_I)
|
|
pat loe lol adu ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call loerxxxste(ADD_I)
|
|
pat loe lol sbi ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call loerxxxste(SUB_I)
|
|
pat loe lol sbu ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call loerxxxste(SUB_I)
|
|
pat loe lol and ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call loerxxxste(AND_I)
|
|
pat loe lol ior ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call loerxxxste(OR_I)
|
|
pat loe lol xor ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
|
|
call loerxxxste(EOR_I)
|
|
#if WORD_SIZE!=2
|
|
pat loe lol ads ste $1==$4 && $3==4 && inreg($2)==reg_any
|
|
call loerxxxste("add.l")
|
|
#endif
|
|
|
|
proc xxxstl example adi stl
|
|
with any_int-RD_REG-dreg_int any-RD_REG-dreg_int
|
|
kills regvar($2, reg_any), use_index %xreg==regvar($2, reg_any)
|
|
gen move %2,{dreg_int, regvar($2)}
|
|
xxx* %1,{LOCAL,$2}
|
|
with exact any_int-RD_REG-dreg_int STACK
|
|
kills regvar($2, reg_any), use_index %xreg==regvar($2, reg_any)
|
|
gen move_i {post_inc_int, sp}, {dreg_int, regvar($2)}
|
|
xxx* %1,{LOCAL,$2}
|
|
|
|
pat adi stl $1==WORD_SIZE && inreg($2)==reg_any call xxxstl(ADD_I)
|
|
pat adu stl $1==WORD_SIZE && inreg($2)==reg_any call xxxstl(ADD_I)
|
|
pat sbi stl $1==WORD_SIZE && inreg($2)==reg_any call xxxstl(SUB_I)
|
|
pat sbu stl $1==WORD_SIZE && inreg($2)==reg_any call xxxstl(SUB_I)
|
|
pat and stl $1==WORD_SIZE && inreg($2)==reg_any call xxxstl(AND_I)
|
|
pat ior stl $1==WORD_SIZE && inreg($2)==reg_any call xxxstl(OR_I)
|
|
|
|
pat xor stl $1==WORD_SIZE && inreg($2)==reg_any
|
|
with D_REG any_int
|
|
kills regvar($2, reg_any), use_index %xreg==regvar($2, reg_any)
|
|
gen move %2,{dreg_int, regvar($2)}
|
|
eor_i %1,{dreg_int, regvar($2)}
|
|
|
|
pat ads SLP $1==4 && inreg($2)==reg_pointer
|
|
with any4-areg-RA_REG any4+address-areg-RA_REG
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move %2,{areg,regvar($2,reg_pointer)}
|
|
add_l %1,{areg,regvar($2,reg_pointer)}
|
|
#ifdef TBL68020
|
|
with regX any4+address-areg-RA_REG
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move %2,{areg,regvar($2,reg_pointer)}
|
|
move {regAregXcon, regvar($2,reg_pointer), %1.xreg, %1.sc, 0},{areg,regvar($2,reg_pointer)}
|
|
with exact regX STACK
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_l {post_inc4, sp},{areg,regvar($2,reg_pointer)}
|
|
move {regAregXcon, regvar($2,reg_pointer), %1.xreg, %1.sc, 0},{areg,regvar($2,reg_pointer)}
|
|
with exact regX regAcon
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {regAregXcon, %2.reg, %1.xreg, %1.sc, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact regX local_addr
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {regAregXcon, lb, %1.xreg, %1.sc, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
#ifdef FANCY_MODES
|
|
with exact regX indirect4
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_regXcon, %2.reg, %1.xreg,%1.sc,0,0},{areg,regvar($2,reg_pointer)}
|
|
with exact regX offsetted4
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_regXcon, %2.reg, %1.xreg, %1.sc, %2.bd, 0},{areg,regvar($2,reg_pointer)}
|
|
with exact regX LOCAL
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_regXcon, lb, %1.xreg, %1.sc, %2.bd, 0},{areg,regvar($2,reg_pointer)}
|
|
with exact regX off_con
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_regXcon, %2.reg, %1.xreg,%1.sc,%2.bd,%2.od},{areg,regvar($2,reg_pointer)}
|
|
with exact regX ext_addr
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move{ext_regX, %1.sc, %1.xreg, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact regX absolute4
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {abs_regXcon, %1.sc, %1.xreg, %2.bd, 0},{areg,regvar($2,reg_pointer)}
|
|
with exact regX abs_con
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {abs_regXcon, %1.sc, %1.xreg, %2.bd, %2.od},{areg,regvar($2,reg_pointer)}
|
|
with exact indirect4 ext_addr
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_con, %1.reg, 0, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact offsetted4 ext_addr
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_con, %1.reg, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact LOCAL ext_addr
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_con, lb, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact index_off4 ext_addr
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {indoff_con, %1.reg, %1.xreg, %1.sc,%1.bd,%2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact absolute4 ext_addr
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {abs_con, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact abs_index4 ext_addr
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {absind_con, %1.sc, %1.xreg, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact indirect4 ext_regX
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_regXcon, %1.reg, %2.xreg, %2.sc, 0, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact offsetted4 ext_regX
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_regXcon, %1.reg, %2.xreg,%2.sc,%1.bd,%2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact LOCAL ext_regX
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {off_regXcon, lb, %2.xreg, %2.sc, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
with exact absolute4 ext_regX
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move {abs_regXcon, %2.sc, %2.xreg, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
|
|
proc xxxdupstl example adi dup stl
|
|
with any_int-RD_REG-dreg_int any-RD_REG-dreg_int
|
|
kills regvar($3, reg_any), use_index %xreg==regvar($3, reg_any)
|
|
gen move %2,{dreg_int, regvar($3)}
|
|
xxx* %1,{LOCAL,$3} yields {LOCAL, $3}
|
|
with exact any_int-RD_REG-dreg_int STACK
|
|
kills regvar($3, reg_any), use_index %xreg==regvar($3, reg_any)
|
|
gen move_i {post_inc_int, sp}, {dreg_int, regvar($3)}
|
|
xxx* %1,{LOCAL,$3} yields {LOCAL, $3}
|
|
|
|
pat adi dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
|
|
call xxxdupstl(ADD_I)
|
|
pat adu dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
|
|
call xxxdupstl(ADD_I)
|
|
pat sbi dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
|
|
call xxxdupstl(SUB_I)
|
|
pat sbu dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
|
|
call xxxdupstl(SUB_I)
|
|
pat and dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
|
|
call xxxdupstl(AND_I)
|
|
pat ior dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
|
|
call xxxdupstl(OR_I)
|
|
/*
|
|
pat xor dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
|
|
call xxxdupstl(EOR_I)
|
|
incorrect for eor.l !!!
|
|
*/
|
|
|
|
pat dup stl $1==WORD_SIZE && inreg($2)==reg_any
|
|
with any_int
|
|
kills regvar($2, reg_any), use_index %xreg==regvar($2, reg_any)
|
|
gen move %1,{dreg_int, regvar($2,reg_any)}
|
|
yields {LOCAL, $2}
|
|
|
|
pat dup stl $1==4 && inreg($2)==reg_pointer
|
|
with any4
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_l %1,{areg, regvar($2, reg_pointer)}
|
|
yields {DLOCAL, $2}
|
|
|
|
pat dup LLP sti LLP adp SLP zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$4 && $2==$6 && $3==1 && $5==1
|
|
with any1
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_b %1,{post_inc1, regvar($2,reg_pointer)}
|
|
bne {llabel, $7}
|
|
|
|
pat dup LLP sti LLP adp SLP zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$4 && $2==$6 && $3==1 && $5==1
|
|
with any1
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_b %1,{post_inc1, regvar($2,reg_pointer)}
|
|
beq {llabel, $7}
|
|
|
|
/* Normally, LLP sti wth word size will be optimized to sil */
|
|
pat dup LLP sti LLP adp SLP zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$4 && $2==$6 && $3==2 && $5==2
|
|
with any2
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_w %1,{post_inc2, regvar($2,reg_pointer)}
|
|
bne {llabel, $7}
|
|
|
|
pat dup LLP sti LLP adp SLP zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$4 && $2==$6 && $3==2 && $5==2
|
|
with any2
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_w %1,{post_inc2, regvar($2,reg_pointer)}
|
|
beq {llabel, $7}
|
|
|
|
#if WORD_SIZE!=2
|
|
/* m68k2 can't do zne/zeq on 4-byte */
|
|
pat dup LLP sti LLP adp SLP zne $1==4 && inreg($2)==reg_pointer &&
|
|
$2==$4 && $2==$6 && $3==4 && $5==4
|
|
with any4
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_l %1,{post_inc4, regvar($2,reg_pointer)}
|
|
bne {llabel, $7}
|
|
|
|
pat dup LLP sti LLP adp SLP zeq $1==4 && inreg($2)==reg_pointer &&
|
|
$2==$4 && $2==$6 && $3==4 && $5==4
|
|
with any4
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_l %1,{post_inc4, regvar($2,reg_pointer)}
|
|
beq {llabel, $7}
|
|
#endif
|
|
|
|
pat dup sil LLP adp SLP zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$3 && $3==$5 && $4==WORD_SIZE
|
|
with any_int
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_i %1,{post_inc_int, regvar($2, reg_pointer)}
|
|
bne {llabel, $6}
|
|
|
|
pat dup sil LLP adp SLP zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$3 && $3==$5 && $4==WORD_SIZE
|
|
with any_int
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_i %1,{post_inc_int, regvar($2, reg_pointer)}
|
|
beq {llabel, $6}
|
|
|
|
pat sil lil LLP adp SLP zne $1==$2 && $2==$3 && $3==$5 && $4==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
with any_int
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen move_i %1,{post_inc_int, regvar($1,reg_pointer)}
|
|
bne {llabel, $6}
|
|
|
|
pat sil lil LLP adp SLP zeq $1==$2 && $2==$3 && $3==$5 && $4==WORD_SIZE
|
|
&& inreg($1)==reg_pointer
|
|
with any_int
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen move_i %1,{post_inc_int, regvar($1,reg_pointer)}
|
|
beq {llabel, $6}
|
|
|
|
pat dup LLP adp SLP LLP sti zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$4 && $4==$5 && $6==1 && $4==(0-1)
|
|
with any1
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_b %1,{pre_dec1, regvar($2,reg_pointer)}
|
|
bne {llabel, $7}
|
|
|
|
pat dup LLP adp SLP LLP sti zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$4 && $4==$5 && $6==1 && $4==(0-1)
|
|
with any1
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_b %1,{pre_dec1, regvar($2,reg_pointer)}
|
|
beq {llabel, $7}
|
|
|
|
#if WORD_SIZE!=2
|
|
pat dup LLP adp SLP LLP sti zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$4 && $4==$5 && $6==2 && $4==(0-2)
|
|
with any2
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_w %1,{pre_dec2, regvar($2,reg_pointer)}
|
|
bne {llabel, $7}
|
|
|
|
pat dup LLP adp SLP LLP sti zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
|
|
$2==$4 && $4==$5 && $6==2 && $4==(0-2)
|
|
with any2
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_w %1,{pre_dec2, regvar($2,reg_pointer)}
|
|
beq {llabel, $7}
|
|
#endif
|
|
|
|
#if WORD_SIZE!=2
|
|
pat dup lol adp stl lol sti zne $1==4 && inreg($2)==reg_pointer &&
|
|
$2==$4 && $4==$5 && $6==4 && $4==(0-4)
|
|
with any4
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_l %1,{pre_dec4, regvar($2,reg_pointer)}
|
|
bne {llabel, $7}
|
|
|
|
pat dup lol adp stl lol sti zeq $1==4 && inreg($2)==reg_pointer &&
|
|
$2==$4 && $4==$5 && $6==4 && $4==(0-4)
|
|
with any4
|
|
kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
|
|
gen move_l %1,{pre_dec4, regvar($2,reg_pointer)}
|
|
beq {llabel, $7}
|
|
#endif
|
|
|
|
pat LLP ads SLP $1==$3 && $2==4 && inreg($1)==reg_pointer
|
|
with data4-sconsts
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen add_l %1, {DLOCAL, $1}
|
|
|
|
pat lil dup inc sil $1==$4 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
uses DD_REG = {indirect_int, regvar($1, reg_pointer)}
|
|
gen add_i {const, 1}, {indirect_int, regvar($1, reg_pointer)}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lil dup dec sil $1==$4 && $2==WORD_SIZE && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
uses DD_REG = {indirect_int, regvar($1, reg_pointer)}
|
|
gen sub_i {const, 1}, {indirect_int, regvar($1, reg_pointer)}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LLP LFP dup adp LLP SFP sti $3==4 && $1==$5 && $2==$6 && inreg($1)==reg_pointer && $7 <= 4
|
|
with conreg
|
|
kills allexceptcon
|
|
uses AA_REG = {offsetted4, regvar($1, reg_pointer), $2}
|
|
gen add_l {const4, $4}, {offsetted4, regvar($1, reg_pointer), $2}
|
|
killreg %a
|
|
yields %1 %a leaving sti $7
|
|
|
|
pat LLP LFP dup adp LLP SFP $3==4 && $1==$5 && $2==$6 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
uses AA_REG = {offsetted4, regvar($1, reg_pointer), $2}
|
|
gen add_l {const4, $4}, {offsetted4, regvar($1, reg_pointer), $2}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LLP LFP dup adp LLP SFP sti $3==4 && $1==$5 && $2==$6 && $7 <= 4
|
|
with conreg
|
|
kills allexceptcon
|
|
uses AA_REG = {DLOCAL, $1}, AA_REG
|
|
gen move_l {offsetted4, %a, $2}, %b
|
|
add_l {const4, $4}, {offsetted4, %a, $2}
|
|
yields %1 %b leaving sti $7
|
|
|
|
pat LLP LFP dup adp LLP SFP $3==4 && $1==$5 && $2==$6
|
|
kills allexceptcon
|
|
uses AA_REG = {DLOCAL, $1}, AA_REG
|
|
gen move_l {offsetted4, %a, $2}, %b
|
|
add_l {const4, $4}, {offsetted4, %a, $2}
|
|
yields %b
|
|
|
|
pat LEP LFP dup adp LEP SFP sti $3==4 && $1==$5 && $2==$6 && $7 <= 4
|
|
with conreg
|
|
kills allexceptcon
|
|
uses AA_REG = {absolute4, $1}, AA_REG
|
|
gen move_l {offsetted4, %a, $2}, %b
|
|
add_l {const4, $4}, {offsetted4, %a, $2}
|
|
yields %1 %b leaving sti $7
|
|
|
|
pat LEP LFP dup adp LEP SFP $3==4 && $1==$5 && $2==$6
|
|
kills allexceptcon
|
|
uses AA_REG = {absolute4, $1}, AA_REG
|
|
gen move_l {offsetted4, %a, $2}, %b
|
|
add_l {const4, $4}, {offsetted4, %a, $2}
|
|
yields %b
|
|
|
|
#if WORD_SIZE!=2
|
|
pat lil lof dup adp lil stf sti $3==4 && $1==$5 && $2==$6 && inreg($1)==reg_pointer && $7 <= 4
|
|
with conreg
|
|
kills allexceptcon
|
|
uses AA_REG = {indirect4, regvar($1, reg_pointer)}, AA_REG
|
|
gen move_l {offsetted4, %a, $2}, %b
|
|
add_l {const4, $4}, {offsetted4, %a, $2}
|
|
yields %1 %b leaving sti $7
|
|
|
|
pat lil lof dup adp lil stf $3==4 && $1==$5 && $2==$6 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
uses AA_REG = {indirect4, regvar($1, reg_pointer)}, AA_REG
|
|
gen move_l {offsetted4, %a, $2}, %b
|
|
add_l {const4, $4}, {offsetted4, %a, $2}
|
|
yields %b
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
pat LEP loi dup adp LEP sti sti $3==4 && $1==$5 && $2==4 && $6==4 && $7 <= 4
|
|
with conreg
|
|
kills allexceptcon
|
|
uses AA_REG = {absolute4, $1}, AA_REG
|
|
gen move_l {indirect4, %a}, %b
|
|
add_l {const4, $4}, {indirect4, %a}
|
|
yields %1 %b leaving sti $7
|
|
|
|
pat LEP loi dup adp LEP sti $3==4 && $1==$5 && $2==4 && $6==4
|
|
kills allexceptcon
|
|
uses AA_REG = {absolute4, $1}, AA_REG
|
|
gen move_l {indirect4, %a}, %b
|
|
add_l {const4, $4}, {indirect4, %a}
|
|
yields %b
|
|
|
|
#if WORD_SIZE!=2
|
|
pat lil loi dup adp lil sti sti $3==4 && $1==$5 && $2==4 && $6==4 && $7 <= 4
|
|
with conreg
|
|
kills allexceptcon
|
|
uses AA_REG = {indirect4, regvar($1, reg_pointer)}, AA_REG
|
|
gen move_l {indirect4, %a}, %b
|
|
add_l {const4, $4}, {indirect4, %a}
|
|
yields %1 %b leaving sti $7
|
|
|
|
pat lil loi dup adp lil sti $3==4 && $1==$5 && $2==4 && $6==4
|
|
kills allexceptcon
|
|
uses AA_REG = {indirect4, regvar($1, reg_pointer)}, AA_REG
|
|
gen move_l {indirect4, %a}, %b
|
|
add_l {const4, $4}, {indirect4, %a}
|
|
yields %b
|
|
#endif
|
|
|
|
pat LLP dup adp SLP lae cmp $1==$4 && $2==4 && inreg($1)==reg_pointer && $3 < 0
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen sub_l {const4,0-$3},{DLOCAL,$1}
|
|
yields {DLOCAL,$1} {ext_addr, $5+$3}
|
|
leaving cmu 4
|
|
|
|
pat LLP dup adp SLP lae cmp $1==$4 && $2==4 && inreg($1)==reg_pointer && $3 > 0
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen add_l {const4,$3},{DLOCAL,$1}
|
|
yields {DLOCAL,$1} {ext_addr, $5+$3}
|
|
leaving cmu 4
|
|
|
|
pat LLP dup adp SLP loi $1==$4 && $2==4 && $3==4 && $5==4 &&
|
|
inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {post_inc4, regvar($1, reg_pointer)}
|
|
|
|
pat LLP dup adp SLP loi $1==$4 && $2==4 && $3==$5 && inreg($1)==reg_pointer
|
|
leaving LLP $1 loi $5 LLP $4 adp $3 SLP $4
|
|
|
|
pat LLP loi LLP adp SLP $1==$3 && $1==$5 && $2==1 && $4==1 &&
|
|
inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {post_inc1, regvar($1, reg_pointer)}
|
|
|
|
/* Normally, LLP loi will be optimized to lil */
|
|
pat LLP loi LLP adp SLP $1==$3 && $1==$5 && $2==2 && $4==2 &&
|
|
inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {post_inc2, regvar($1, reg_pointer)}
|
|
|
|
pat LLP loi LLP adp SLP $1==$3 && $1==$5 && $2==4 && $4==4 &&
|
|
inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {post_inc4, regvar($1, reg_pointer)}
|
|
|
|
pat lil LLP adp SLP $1==$2 && $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {post_inc_int, regvar($1, reg_pointer)}
|
|
|
|
pat LLP dup adp SLP sti $1==$4 && $2==4 && $3==$5 && inreg($1)==reg_pointer
|
|
leaving LLP $1 sti $5 LLP $4 adp $3 SLP $4
|
|
|
|
pat LLP sti LLP adp SLP $1==$3 && $1==$5 && $2==1 && $4==1 &&
|
|
inreg($1)==reg_pointer
|
|
with any1
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {post_inc1, regvar($1, reg_pointer)}
|
|
|
|
/* Normally, LLP sti will ve optimzed into sil */
|
|
pat LLP sti LLP adp SLP $1==$3 && $1==$5 && $2==2 && $4==2 &&
|
|
inreg($1)==reg_pointer
|
|
with any2
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {post_inc2, regvar($1, reg_pointer)}
|
|
|
|
pat LLP sti LLP adp SLP $1==$3 && $1==$5 && $2==4 && $4==4 &&
|
|
inreg($1)==reg_pointer
|
|
with any4
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {post_inc4, regvar($1, reg_pointer)}
|
|
|
|
pat LLP dup adp SLP sti $1==$4 && $2==4 && $3==WORD_SIZE && $5==WORD_SIZE &&
|
|
inreg($1)==reg_pointer
|
|
with any_int-sconsts
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {post_inc_int, regvar($1, reg_pointer)}
|
|
|
|
pat sil LLP adp SLP $1==$2 && $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
|
|
with any_int-sconsts
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {post_inc_int, regvar($1, reg_pointer)}
|
|
|
|
pat LLP adp SLP LLP loi $1==$3 && $1==$4 && $2==0-1 && $5==1 &&
|
|
inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {pre_dec1, regvar($1, reg_pointer)}
|
|
|
|
/* Normally, LLP loi will be optimized to lil */
|
|
pat LLP adp SLP LLP loi $1==$3 && $1==$4 && $2==0-2 && $5==2 &&
|
|
inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {pre_dec2, regvar($1, reg_pointer)}
|
|
|
|
pat LLP adp SLP LLP loi $1==$3 && $1==$4 && $2==0-4 && $5==4 &&
|
|
inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {pre_dec4, regvar($1, reg_pointer)}
|
|
|
|
pat LLP adp SLP lil $1==$3 && $1==$4 && $2==0-WORD_SIZE &&
|
|
inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
yields {pre_dec_int, regvar($1, reg_pointer)}
|
|
|
|
pat LLP adp SLP LLP sti $1==$3 && $1==$4 && $2==0-1 && $5==1 &&
|
|
inreg($1)==reg_pointer
|
|
with any1
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {pre_dec1, regvar($1, reg_pointer)}
|
|
|
|
#if WORD_SIZE!=2
|
|
pat LLP adp SLP LLP sti $1==$3 && $1==$4 && $2==0-2 && $5==2 &&
|
|
inreg($1)==reg_pointer
|
|
with any2
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {pre_dec2, regvar($1, reg_pointer)}
|
|
#else
|
|
pat LLP adp SLP LLP sti $1==$3 && $1==$4 && $2==0-4 && $5==4 &&
|
|
inreg($1)==reg_pointer
|
|
with any4
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {pre_dec4, regvar($1, reg_pointer)}
|
|
#endif
|
|
|
|
pat LLP adp SLP sil $1==$3 && $1==$4 && $2==0-WORD_SIZE &&
|
|
inreg($1)==reg_pointer
|
|
with any_int-sconsts
|
|
kills allexceptcon, regvar($1, reg_pointer)
|
|
gen move %1, {pre_dec_int, regvar($1, reg_pointer)}
|
|
|
|
pat LLP dup adp SLP $1==$4 && $2==4 && inreg($1)==reg_pointer && directadd($3)
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen add_l {const4, $3}, {DLOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LLP dup adp SLP $1==$4 && $2==4 && inreg($1)==reg_pointer && directsub($3)
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen sub_l {const4, 0-$3}, {DLOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LLP dup adp SLP $1==$4 && $2==4 && inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
uses AA_REG = {DLOCAL, $1}, DD_REG4 = {const4, $3}
|
|
gen add_l %b, {DLOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LLP dup adp SLP $1==$4 && $2==4 && directadd($3)
|
|
kills all_indir, DLOCAL %bd==$1
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen add_l {const4, $3}, {DLOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LLP dup adp SLP $1==$4 && $2==4 && directsub($3)
|
|
kills all_indir, DLOCAL %bd==$1
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen sub_l {const4, 0-$3}, {DLOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LLP dup adp SLP $1==$4 && $2==4
|
|
kills all_indir, DLOCAL %bd==$1
|
|
uses AA_REG = {DLOCAL, $1}, DD_REG4 = {const4, $3}
|
|
gen add_l %b, {DLOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LLP adp SLP $1==$3 && inreg($1)==reg_pointer && directadd($2)
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen add_l {const4, $2}, {DLOCAL, $1}
|
|
|
|
pat LLP adp SLP $1==$3 && inreg($1)==reg_pointer && directsub($2)
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen sub_l {const4, 0-$2}, {DLOCAL, $1}
|
|
|
|
pat LLP adp SLP $1==$3 && inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
uses DD_REG4 = {const4, $2}
|
|
gen add_l %a, {DLOCAL, $1}
|
|
|
|
pat LLP adp SLP $1==$3 && directadd($2)
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen add_l {const4, $2}, {DLOCAL, $1}
|
|
|
|
pat LLP adp SLP $1==$3 && directsub($2)
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen sub_l {const4, 0-$2}, {DLOCAL, $1}
|
|
|
|
pat LLP adp SLP $1==$3
|
|
kills all_indir, DLOCAL %bd==$1
|
|
uses DD_REG4 = {const4, $2}
|
|
gen add_l %a, {DLOCAL, $1}
|
|
|
|
#if WORD_SIZE!=2
|
|
pat lil dup adp sil sti $1==$4 && $2==4 && inreg($1)==reg_pointer && $5<=4
|
|
with conreg
|
|
kills allexceptcon
|
|
uses AA_REG = {indirect4, regvar($1, reg_pointer)}
|
|
gen add_l {const, $3}, {indirect4, regvar($1, reg_pointer)}
|
|
killreg %a
|
|
yields %1 %a leaving sti $5
|
|
|
|
pat lil dup adp sil $1==$4 && $2==4 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
uses AA_REG = {indirect4, regvar($1, reg_pointer)}
|
|
gen add_l {const, $3}, {indirect4, regvar($1, reg_pointer)}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lil dup adp sil $1==$4 && $2==4
|
|
kills allexceptcon
|
|
uses AA_REG, AA_REG = {LOCAL, $1}
|
|
gen move {indirect4, %b}, %a
|
|
add_l {const, $3}, {indirect4, %b}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat lil adp sil $1==$3 && inreg($1)==reg_pointer
|
|
kills allexceptcon
|
|
gen add_l {const, $2}, {indirect4, regvar($1, reg_pointer)}
|
|
|
|
pat lil adp sil $1==$3 && inreg($1)!=reg_any
|
|
kills allexceptcon
|
|
#if TBL68020 /* WORD_SIZE==4 */
|
|
gen add_l {const, $2}, {ILOCAL,$1}
|
|
#else
|
|
uses AA_REG = {LOCAL, $1}
|
|
gen add_l {const, $2}, {indirect4, %a}
|
|
#endif
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
pat LEP dup adp SEP $1==$4 && $2==4
|
|
kills posextern
|
|
uses AA_REG = {absolute4, $1}
|
|
gen add_l {const4, $3}, {absolute4, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat LEP adp SEP $1==$3
|
|
kills posextern
|
|
gen add_l {const4, $2}, {absolute4, $1}
|
|
|
|
pat loc and $1==255 && $2==WORD_SIZE
|
|
#if WORD_SIZE==2
|
|
with exact absolute_int yields {absolute1,%1.bd+1}
|
|
with exact offsetted_int yields {offsetted1,%1.reg,%1.bd+1}
|
|
with exact LOCAL yields {offsetted1,lb,%1.bd+1}
|
|
#else
|
|
with exact absolute_int yields {absolute1,%1.bd+3}
|
|
with exact offsetted_int yields {offsetted1,%1.reg,%1.bd+3}
|
|
with exact LOCAL yields {offsetted1,lb,%1.bd+3}
|
|
#endif
|
|
with yields {const, $1} leaving and WORD_SIZE
|
|
|
|
/************************************************
|
|
* Group 1: load instructions *
|
|
************************************************/
|
|
|
|
pat loc $1==0 yields {zero_const, $1}
|
|
|
|
pat loc small($1) yields {small_const, $1}
|
|
|
|
pat loc in_1($1) yields {bconst, $1}
|
|
|
|
pat loc yields {const, $1}
|
|
|
|
#if WORD_SIZE!=2
|
|
pat ldc leaving loc 18 trp
|
|
#else
|
|
pat ldc highw($1)==0 && loww($1)==0 yields {zero_const4, 0}
|
|
|
|
pat ldc highw($1)==0 && small(loww($1)) yields {small_const4, loww($1)}
|
|
|
|
pat ldc highw($1)==0 && in_1(loww($1)) yields {bconst4, loww($1)}
|
|
|
|
pat ldc yields {const4, $1}
|
|
#endif
|
|
|
|
pat LLP inreg($1)==reg_pointer
|
|
kills pre_post %reg==regvar($1, reg_pointer)
|
|
yields {DLOCAL, $1}
|
|
|
|
pat lol yields {LOCAL, $1}
|
|
|
|
#if WORD_SIZE!=2
|
|
pat ldl leaving lol $1+4 lol $1
|
|
#else
|
|
pat ldl yields {DLOCAL, $1}
|
|
#endif
|
|
|
|
pat loe yields {absolute_int, $1}
|
|
|
|
/* replace ste loe by dup ste, but not if followed by a test ... */
|
|
proc steloezxx example ste loe zne
|
|
with any_int-sconsts
|
|
kills posextern
|
|
gen move_i %1, {absolute_int, $1}
|
|
bxx* {llabel, $3}
|
|
with exact STACK
|
|
kills posextern
|
|
gen move_i {post_inc_int, sp}, {absolute_int, $1}
|
|
bxx* {llabel, $3}
|
|
|
|
pat ste loe zlt $1==$2 call steloezxx("blt")
|
|
pat ste loe zle $1==$2 call steloezxx("ble")
|
|
pat ste loe zeq $1==$2 call steloezxx("beq")
|
|
pat ste loe zne $1==$2 call steloezxx("bne")
|
|
pat ste loe zge $1==$2 call steloezxx("bge")
|
|
pat ste loe zgt $1==$2 call steloezxx("bgt")
|
|
|
|
pat ste loe $1==$2 leaving dup WORD_SIZE ste $1
|
|
|
|
pat lil inreg($1)==reg_pointer
|
|
kills pre_post %reg==regvar($1, reg_pointer)
|
|
yields {indirect_int, regvar($1, reg_pointer)}
|
|
#if WORD_SIZE==4
|
|
pat lil inreg($1)==reg_any
|
|
uses AA_REG = {DLOCAL, $1}
|
|
yields {indirect_int, %a}
|
|
#endif
|
|
|
|
pat lil
|
|
#if TBL68020
|
|
yields {ILOCAL, $1}
|
|
#else
|
|
uses AA_REG = {DLOCAL, $1}
|
|
yields {indirect_int, %a}
|
|
#endif
|
|
|
|
/* When using the 'offsetted' intructions regAregXcon cannot be used
|
|
* for the m68k[24]; there is no way of knowing about the size of
|
|
* %1.bd+$1, because expressions are not allowed in stack patterns, and
|
|
* this may lead to outputting too large displacements. With regAcon
|
|
* the chance that this will happen is very slim, because it can
|
|
* have displacements of 16 bits. Besides, leaving out regAcon here
|
|
* would make it very hard to handle this instruction efficiently.
|
|
*/
|
|
pat lof
|
|
with A_REG yields {offsetted_int, %1, $1}
|
|
with exact local_addr yields {LOCAL, %1.bd+$1}
|
|
with exact ext_addr yields {absolute_int, %1.bd+$1}
|
|
#ifndef TBL68020
|
|
with regAcon yields {offsetted_int, %1.reg, %1.bd+$1}
|
|
#else /* TBL68020 */
|
|
with exact regAcon yields {offsetted_int, %1.reg, %1.bd+$1}
|
|
with exact regAregXcon yields {index_off_int, %1.reg, %1.xreg, %1.sc, %1.bd+$1}
|
|
#ifdef FANCY_MODES
|
|
with exact offsetted4 yields {OFF_off_int, %1.reg, %1.bd, $1}
|
|
with exact indirect yields {OFF_off_int, %1.reg, 0, $1}
|
|
with exact DLOCAL yields {OFF_off_int, lb, %1.bd, $1}
|
|
with exact off_con yields {OFF_off_int, %1.reg, %1.bd, %1.od+$1}
|
|
with exact index_off4 yields {INDOFF_off_int, %1.reg, %1.xreg, %1.sc, %1.bd, $1}
|
|
with exact indoff_con yields {INDOFF_off_int,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
|
|
with exact off_regXcon yields {OFF_indoff_int,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
|
|
with exact absolute4 yields {ABS_off_int, %1.bd, $1}
|
|
with exact abs_con yields {ABS_off_int, %1.bd, %1.od+$1}
|
|
with exact abs_regXcon yields {ABS_indoff_int, %1.sc, %1.xreg, %1.bd, %1.od+$1}
|
|
with exact abs_index4 yields {ABSIND_off_int, %1.sc, %1.xreg, %1.bd, $1}
|
|
with exact absind_con yields {ABSIND_off_int, %1.sc, %1.xreg, %1.bd, %1.od+$1}
|
|
with exact ext_regX yields {abs_index_int, %1.sc, %1.xreg, %1.bd+$1}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
pat lal yields {local_addr, $1}
|
|
|
|
pat lae yields {ext_addr, $1}
|
|
|
|
pat lxl $1==0 yields lb
|
|
|
|
pat lxl $1==1 yields {DLOCAL, SL}
|
|
|
|
pat lxl $1==2
|
|
#if TBL68020 && FANCY_MODES
|
|
yields {OFF_off4, lb, SL, SL}
|
|
#else
|
|
uses AA_REG = {DLOCAL, SL}
|
|
yields {offsetted4, %a, SL}
|
|
#endif
|
|
|
|
pat lxl $1==3
|
|
#if TBL68020 && FANCY_MODES
|
|
uses AA_REG = {OFF_off4, lb, SL, SL}
|
|
#else
|
|
uses AA_REG = {DLOCAL, SL}
|
|
gen move_l {offsetted4, %a, SL}, %a
|
|
#endif
|
|
yields {offsetted4, %a, SL}
|
|
|
|
pat lxl $1>3
|
|
uses AA_REG = {DLOCAL, SL},
|
|
DD_REG4 = {const, $1-2}
|
|
gen 1:
|
|
move_l {offsetted4, %a, SL} ,%a
|
|
dbf %b, {slabel, 1b}
|
|
yields %a
|
|
|
|
pat lxa $1==0 yields {local_addr, SL}
|
|
|
|
pat lxa $1==1
|
|
#if TBL68020 && FANCY_MODES
|
|
yields {off_con, lb, SL, SL}
|
|
#else
|
|
uses AA_REG = {DLOCAL, SL}
|
|
yields {regAcon, %a, SL}
|
|
#endif
|
|
|
|
pat lxa $1==2
|
|
#if TBL68020 && FANCY_MODES
|
|
uses AA_REG = {OFF_off4, lb, SL, SL}
|
|
#else
|
|
uses AA_REG = {DLOCAL, SL}
|
|
gen move_l {offsetted4, %a, SL}, %a
|
|
#endif
|
|
yields {regAcon, %a, SL}
|
|
|
|
pat lxa $1>2
|
|
uses AA_REG = {DLOCAL, SL},
|
|
DD_REG4 = {const, $1-2}
|
|
gen 1:
|
|
move_l {offsetted4, %a, SL} ,%a
|
|
dbf %b, {slabel, 1b}
|
|
yields {regAcon, %a, SL}
|
|
|
|
pat loi $1==1
|
|
with A_REG yields {indirect1, %1}
|
|
with exact local_addr yields {offsetted1, lb, %1.bd}
|
|
with exact ext_addr yields {absolute1, %1.bd}
|
|
#ifndef TBL68020
|
|
with regAcon yields {offsetted1, %1.reg, %1.bd}
|
|
with regAregXcon yields {index_off1, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#else /* TBL68020 */
|
|
with exact regAcon yields {offsetted1, %1.reg, %1.bd}
|
|
with exact regAregXcon yields {index_off1, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#ifdef FANCY_MODES
|
|
with exact indirect4 yields {OFF_off1, %1.reg, 0, 0}
|
|
with exact offsetted4 yields {OFF_off1, %1.reg, %1.bd, 0}
|
|
with exact LOCAL yields {OFF_off1, lb, %1.bd, 0}
|
|
with exact off_con yields {OFF_off1, %1.reg, %1.bd, %1.od}
|
|
with exact index_off4 yields {INDOFF_off1, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
|
|
with exact indoff_con yields {INDOFF_off1,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact off_regXcon yields {OFF_indoff1,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact absolute4 yields {ABS_off1, %1.bd, 0}
|
|
with exact abs_con yields {ABS_off1, %1.bd, %1.od}
|
|
with exact abs_regXcon yields {ABS_indoff1, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact abs_index4 yields {ABSIND_off1, %1.sc, %1.xreg, %1.bd, 0}
|
|
with exact absind_con yields {ABSIND_off1, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact ext_regX yields {abs_index1, %1.sc, %1.xreg, %1.bd}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
pat loi $1==2
|
|
with A_REG yields {indirect2, %1}
|
|
#if WORD_SIZE!=2
|
|
with exact local_addr yields {offsetted2, lb, %1.bd}
|
|
#else
|
|
with exact local_addr yields {LOCAL, %1.bd}
|
|
#endif
|
|
with exact ext_addr yields {absolute2, %1.bd}
|
|
#ifndef TBL68020
|
|
with regAcon yields {offsetted2, %1.reg, %1.bd}
|
|
with regAregXcon yields {index_off2, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#else /* TBL68020 */
|
|
with exact regAcon yields {offsetted2, %1.reg, %1.bd}
|
|
with exact regAregXcon yields {index_off2, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#if WORD_SIZE==2
|
|
with exact DLOCAL yields {ILOCAL, %1.bd}
|
|
#endif
|
|
#ifdef FANCY_MODES
|
|
with exact indirect4 yields {OFF_off2, %1.reg, 0, 0}
|
|
with exact offsetted4 yields {OFF_off2, %1.reg, %1.bd, 0}
|
|
with exact LOCAL yields {OFF_off2, lb, %1.bd, 0}
|
|
with exact off_con yields {OFF_off2, %1.reg, %1.bd, %1.od}
|
|
with exact index_off4 yields {INDOFF_off2, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
|
|
with exact indoff_con yields {INDOFF_off2,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact off_regXcon yields {OFF_indoff2,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact absolute4 yields {ABS_off2, %1.bd, 0}
|
|
with exact abs_con yields {ABS_off2, %1.bd, %1.od}
|
|
with exact abs_regXcon yields {ABS_indoff2, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact abs_index4 yields {ABSIND_off2, %1.sc, %1.xreg, %1.bd, 0}
|
|
with exact absind_con yields {ABSIND_off2, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact ext_regX yields {abs_index2, %1.sc, %1.xreg, %1.bd}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
pat loi $1==4
|
|
with A_REG yields {indirect4, %1}
|
|
with exact local_addr yields {DLOCAL, %1.bd}
|
|
with exact ext_addr yields {absolute4, %1.bd}
|
|
#ifndef TBL68020
|
|
with regAcon yields {offsetted4, %1.reg, %1.bd}
|
|
with regAregXcon yields {index_off4, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#else /* TBL68020 */
|
|
with exact regAcon yields {offsetted4, %1.reg, %1.bd}
|
|
with exact regAregXcon yields {index_off4, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#if WORD_SIZE==4
|
|
with exact LOCAL yields {ILOCAL, %1.bd}
|
|
#endif
|
|
#ifdef FANCY_MODES
|
|
with exact indirect4 yields {OFF_off4, %1.reg, 0, 0}
|
|
with exact offsetted4 yields {OFF_off4, %1.reg, %1.bd, 0}
|
|
with exact off_con yields {OFF_off4, %1.reg, %1.bd, %1.od}
|
|
with exact index_off4 yields {INDOFF_off4, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
|
|
with exact indoff_con yields {INDOFF_off4,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact off_regXcon yields {OFF_indoff4,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact absolute4 yields {ABS_off4, %1.bd, 0}
|
|
with exact abs_con yields {ABS_off4, %1.bd, %1.od}
|
|
with exact abs_regXcon yields {ABS_indoff4, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact abs_index4 yields {ABSIND_off4, %1.sc, %1.xreg, %1.bd, 0}
|
|
with exact absind_con yields {ABSIND_off4, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact ext_regX yields {abs_index4, %1.sc, %1.xreg, %1.bd}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
#if WORD_SIZE==2
|
|
pat loi $1==6
|
|
with AA_REG
|
|
yields {offsetted2, %1, 4} {indirect4, %1}
|
|
with exact local_addr
|
|
yields {offsetted2, lb, %1.bd+4} {offsetted4, lb, %1.bd}
|
|
with exact ext_addr
|
|
yields {absolute2, %1.bd + 4} {absolute4, %1.bd}
|
|
#endif
|
|
|
|
pat loi $1==8
|
|
#if WORD_SIZE!=2
|
|
leaving ldf 0
|
|
#else
|
|
with AA_REG
|
|
yields {offsetted4, %1, 4} {indirect4, %1}
|
|
with exact local_addr
|
|
yields {offsetted4, lb, %1.bd+4} {offsetted4, lb, %1.bd}
|
|
with exact ext_addr
|
|
yields {absolute4, %1.bd + 4} {absolute4, %1.bd}
|
|
#endif
|
|
|
|
#if WORD_SIZE==4
|
|
pat loi $1==3*WORD_SIZE
|
|
with AA_REG STACK
|
|
kills ALL
|
|
uses DD_REG4={const,$1}
|
|
gen add_l %a, %1
|
|
move_i {pre_dec_int, %1},{pre_dec_int, sp}
|
|
move_i {pre_dec_int, %1},{pre_dec_int, sp}
|
|
move_i {pre_dec_int, %1},{pre_dec_int, sp}
|
|
|
|
pat loi $1==4*WORD_SIZE
|
|
with AA_REG STACK
|
|
kills ALL
|
|
uses DD_REG4={const4,$1}
|
|
gen add_l %a, %1
|
|
move_i {pre_dec_int, %1},{pre_dec_int, sp}
|
|
move_i {pre_dec_int, %1},{pre_dec_int, sp}
|
|
move_i {pre_dec_int, %1},{pre_dec_int, sp}
|
|
move_i {pre_dec_int, %1},{pre_dec_int, sp}
|
|
#endif
|
|
|
|
pat loi $1>4*WORD_SIZE && $1/WORD_SIZE <= 65536
|
|
with AA_REG STACK
|
|
kills ALL
|
|
uses DD_REG4 = {const, $1/WORD_SIZE -1}
|
|
gen add_l {const4, $1}, %1
|
|
1:
|
|
move_i {pre_dec_int, %1}, {pre_dec_int, sp}
|
|
dbf %a, {slabel, 1b}
|
|
|
|
pat loi
|
|
with STACK
|
|
kills ALL
|
|
gen move_i {const,$1},{pre_dec_int, sp}
|
|
jsr {absolute4, ".los"}
|
|
|
|
pat los $1==WORD_SIZE
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".los"}
|
|
#if WORD_SIZE==2
|
|
pat los $1==4
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".los4"}
|
|
#endif
|
|
|
|
pat lde
|
|
#if WORD_SIZE==2
|
|
yields {absolute4, $1}
|
|
#else
|
|
yields {absolute4, $1+4}
|
|
{absolute4, $1}
|
|
#endif
|
|
|
|
pat ldf
|
|
#if WORD_SIZE==2
|
|
with A_REG yields {offsetted4, %1, $1}
|
|
with exact local_addr yields {DLOCAL, %1.bd+$1}
|
|
with regAcon yields {offsetted4, %1.reg, %1.bd+$1}
|
|
#else
|
|
with A_REG yields {offsetted4, %1, $1+4}
|
|
{offsetted4, %1, $1}
|
|
with exact local_addr yields {LOCAL, %1.bd+$1+4}
|
|
{LOCAL, %1.bd+$1}
|
|
with regAcon yields {offsetted4, %1.reg, %1.bd+$1+4}
|
|
{offsetted4, %1.reg, %1.bd+$1}
|
|
#endif
|
|
|
|
pat lpi yields {ext_addr, $1}
|
|
|
|
/************************************************
|
|
* Group 2: store instructions *
|
|
************************************************/
|
|
|
|
pat stl inreg($1)==reg_any
|
|
with exact memory1-consts
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen clr_i {LOCAL, $1}
|
|
move_b %1, {dreg1, regvar($1,reg_any)}
|
|
#if WORD_SIZE==2
|
|
with any2
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen move %1, {LOCAL, $1}
|
|
#else
|
|
with exact memory2-consts
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen clr_i {LOCAL, $1}
|
|
move_w %1, {dreg2, regvar($1,reg_any)}
|
|
with store4
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen move %1, {LOCAL, $1}
|
|
#endif
|
|
with exact STACK
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen move_i {post_inc_int, sp}, {LOCAL, $1}
|
|
|
|
pat SLP inreg($1)==reg_pointer
|
|
with any4
|
|
#if WORD_SIZE!=2
|
|
-sconsts4
|
|
#endif
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen move %1, {areg, regvar($1, reg_pointer)}
|
|
with exact ext_addr
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen move_l %1, {areg, regvar($1, reg_pointer)}
|
|
with address-ext_addr
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen lea %1, {areg, regvar($1, reg_pointer)}
|
|
with exact STACK
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen move_l {post_inc4, sp}, {areg, regvar($1, reg_pointer)}
|
|
|
|
pat stl
|
|
with store_int-sconsts
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen move %1, {LOCAL, $1}
|
|
with exact STACK
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen move_i {post_inc_int,sp}, {LOCAL, $1}
|
|
|
|
pat ste
|
|
with store_int-sconsts
|
|
kills posextern
|
|
gen move %1, {absolute_int, $1}
|
|
with exact STACK
|
|
kills posextern
|
|
gen move_i {post_inc_int, sp}, {absolute_int, $1}
|
|
|
|
pat sil inreg($1)==reg_pointer
|
|
with store_int-sconsts
|
|
kills allexceptcon
|
|
gen move %1, {indirect_int, regvar($1, reg_pointer)}
|
|
with exact STACK
|
|
kills allexceptcon
|
|
gen move_i {post_inc_int, sp}, {indirect_int, regvar($1, reg_pointer)}
|
|
|
|
#if WORD_SIZE==4
|
|
pat sil inreg($1)==reg_any
|
|
with store_int-sconsts
|
|
kills allexceptcon
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen move %1, {indirect_int, %a}
|
|
with exact STACK
|
|
kills allexceptcon
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen move_i {post_inc_int, sp}, {indirect_int, %a}
|
|
#endif
|
|
|
|
pat sil
|
|
#if TBL68020
|
|
with store_int-sconsts
|
|
kills allexceptcon
|
|
gen move %1, {ILOCAL, $1}
|
|
with exact STACK
|
|
kills allexceptcon
|
|
gen move_i {post_inc_int, sp}, {ILOCAL, $1}
|
|
#else
|
|
with store_int-sconsts
|
|
kills allexceptcon
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen move %1, {indirect_int, %a}
|
|
with exact STACK
|
|
kills allexceptcon
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen move_i {post_inc_int, sp}, {indirect_int, %a}
|
|
#endif
|
|
|
|
pat stf
|
|
with A_REG store_int-sconsts
|
|
kills allexceptcon
|
|
gen move %2, {offsetted_int, %1, $1}
|
|
with exact any4 STACK
|
|
kills allexceptcon
|
|
uses AA_REG = %1
|
|
gen move_i {post_inc_int, sp}, {offsetted_int, %a, $1}
|
|
with exact STACK
|
|
kills allexceptcon
|
|
uses AA_REG
|
|
gen move_l {post_inc4, sp}, %a
|
|
move_i {post_inc_int, sp}, {offsetted_int, %a, $1}
|
|
with exact local_addr store_int
|
|
kills allexceptcon
|
|
gen move %2, {LOCAL, %1.bd+$1}
|
|
with exact ext_addr store_int
|
|
kills allexceptcon
|
|
gen move %2, {absolute_int, %1.bd+$1}
|
|
#if TBL68000
|
|
#if WORD_SIZE==4
|
|
with regAcon store_int
|
|
kills allexceptcon
|
|
gen move %2, {offsetted_int, %1.reg, %1.bd+$1}
|
|
#endif
|
|
#else /* TBL68020 */
|
|
with exact regAcon store_int
|
|
kills allexceptcon
|
|
gen move %2, {offsetted_int, %1.reg, %1.bd+$1}
|
|
with exact regAregXcon store_int
|
|
kills allexceptcon
|
|
gen move %2, {index_off_int, %1.reg, %1.xreg, %1.sc, %1.bd+$1}
|
|
#ifdef FANCY_MODES
|
|
with exact indirect4 store_int
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off_int, %1.reg, 0, $1}
|
|
with exact offsetted4 store_int
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off_int, %1.reg, %1.bd, $1}
|
|
with exact DLOCAL store_int
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off_int, lb, %1.bd, $1}
|
|
with exact off_con store_int
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off_int, %1.reg, %1.bd, %1.od+$1}
|
|
with exact index_off4 store_int
|
|
kills allexceptcon
|
|
gen move %2, {INDOFF_off_int, %1.reg, %1.xreg, %1.sc, %1.bd, $1}
|
|
with exact indoff_con store_int
|
|
kills allexceptcon
|
|
gen move %2, {INDOFF_off_int, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
|
|
with exact off_regXcon store_int
|
|
kills allexceptcon
|
|
gen move %2, {OFF_indoff_int, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
|
|
with exact absolute4 store_int
|
|
kills allexceptcon
|
|
gen move %2, {ABS_off_int, %1.bd, $1}
|
|
with exact abs_con store_int
|
|
kills allexceptcon
|
|
gen move %2, {ABS_off_int, %1.bd, %1.od+$1}
|
|
with exact abs_regXcon store_int
|
|
kills allexceptcon
|
|
gen move %2, {ABS_indoff_int, %1.sc, %1.xreg, %1.bd, %1.od+$1}
|
|
with exact abs_index4 store_int
|
|
kills allexceptcon
|
|
gen move %2, {ABSIND_off_int, %1.sc, %1.xreg, %1.bd, $1}
|
|
with exact absind_con store_int
|
|
kills allexceptcon
|
|
gen move %2, {ABSIND_off_int, %1.sc, %1.xreg, %1.bd, %1.od+$1}
|
|
with exact ext_regX store_int
|
|
kills allexceptcon
|
|
gen move %2, {abs_index_int, %1.sc, %1.xreg, %1.bd+$1}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
pat sti $1==1
|
|
with A_REG any1
|
|
kills allexceptcon
|
|
gen move %2, {indirect1, %1}
|
|
with local_addr any1
|
|
kills allexceptcon
|
|
gen move %2, {offsetted1, lb, %1.bd}
|
|
with exact ext_addr any1
|
|
kills allexceptcon
|
|
gen move %2, {absolute1, %1.bd}
|
|
#ifndef TBL68020
|
|
with regAcon any1
|
|
kills allexceptcon
|
|
gen move %2, {offsetted1, %1.reg, %1.bd}
|
|
with regAregXcon any1
|
|
kills allexceptcon
|
|
gen move %2, {index_off1, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#else /* TBL68020 */
|
|
with exact regAcon any1
|
|
kills allexceptcon
|
|
gen move %2, {offsetted1, %1.reg, %1.bd}
|
|
with exact regAregXcon any1
|
|
kills allexceptcon
|
|
gen move %2, {index_off1, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#ifdef FANCY_MODES
|
|
with exact indirect4 any1
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off1, %1.reg, 0, 0}
|
|
with exact offsetted4 any1
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off1, %1.reg, %1.bd, 0}
|
|
with exact LOCAL any1
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off1, lb, %1.bd, 0}
|
|
with exact off_con any1
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off1, %1.reg, %1.bd, %1.od}
|
|
with exact index_off4 any1
|
|
kills allexceptcon
|
|
gen move %2, {INDOFF_off1, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
|
|
with exact indoff_con any1
|
|
kills allexceptcon
|
|
gen move %2, {INDOFF_off1, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact off_regXcon any1
|
|
kills allexceptcon
|
|
gen move %2, {OFF_indoff1, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact absolute4 any1
|
|
kills allexceptcon
|
|
gen move %2, {ABS_off1, %1.bd, 0}
|
|
with exact abs_con any1
|
|
kills allexceptcon
|
|
gen move %2, {ABS_off1, %1.bd, %1.od}
|
|
with exact abs_regXcon any1
|
|
kills allexceptcon
|
|
gen move %2, {ABS_indoff1, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact abs_index4 any1
|
|
kills allexceptcon
|
|
gen move %2, {ABSIND_off1, %1.sc, %1.xreg, %1.bd, 0}
|
|
with exact absind_con any1
|
|
kills allexceptcon
|
|
gen move %2, {ABSIND_off1, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact ext_regX any1
|
|
kills allexceptcon
|
|
gen move %2, {abs_index1, %1.sc, %1.xreg, %1.bd}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
pat sti $1==2
|
|
with A_REG any2
|
|
kills allexceptcon
|
|
gen move %2, {indirect2, %1}
|
|
with local_addr any2
|
|
kills allexceptcon
|
|
gen move %2, {offsetted2, lb, %1.bd}
|
|
with exact ext_addr any2
|
|
kills allexceptcon
|
|
gen move %2, {absolute2, %1.bd}
|
|
#ifndef TBL68020
|
|
with regAcon any2
|
|
kills allexceptcon
|
|
gen move %2, {offsetted2, %1.reg, %1.bd}
|
|
with regAregXcon any2
|
|
kills allexceptcon
|
|
gen move %2, {index_off2, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#else /* TBL68020 */
|
|
with exact regAcon any2
|
|
kills allexceptcon
|
|
gen move %2, {offsetted2, %1.reg, %1.bd}
|
|
with exact regAregXcon any2
|
|
kills allexceptcon
|
|
gen move %2, {index_off2, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#if WORD_SIZE==2
|
|
with exact DLOCAL any2
|
|
kills allexceptcon
|
|
gen move %2, {ILOCAL, %1.bd}
|
|
#endif
|
|
#ifdef FANCY_MODES
|
|
with exact indirect4 any2
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off2, %1.reg, 0, 0}
|
|
with exact offsetted4 any2
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off2, %1.reg, %1.bd, 0}
|
|
with exact LOCAL any2
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off2, lb, %1.bd, 0}
|
|
with exact off_con any2
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off2, %1.reg, %1.bd, %1.od}
|
|
with exact index_off4 any2
|
|
kills allexceptcon
|
|
gen move %2, {INDOFF_off2, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
|
|
with exact indoff_con any2
|
|
kills allexceptcon
|
|
gen move %2, {INDOFF_off2, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact off_regXcon any2
|
|
kills allexceptcon
|
|
gen move %2, {OFF_indoff2, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact absolute4 any2
|
|
kills allexceptcon
|
|
gen move %2, {ABS_off2, %1.bd, 0}
|
|
with exact abs_con any2
|
|
kills allexceptcon
|
|
gen move %2, {ABS_off2, %1.bd, %1.od}
|
|
with exact abs_regXcon any2
|
|
kills allexceptcon
|
|
gen move %2, {ABS_indoff2, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact abs_index4 any2
|
|
kills allexceptcon
|
|
gen move %2, {ABSIND_off2, %1.sc, %1.xreg, %1.bd, 0}
|
|
with exact absind_con any2
|
|
kills allexceptcon
|
|
gen move %2, {ABSIND_off2, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact ext_regX any2
|
|
kills allexceptcon
|
|
gen move %2, {abs_index2, %1.sc, %1.xreg, %1.bd}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
pat sti $1==4
|
|
with A_REG store4-sconsts4
|
|
kills allexceptcon
|
|
gen move %2, {indirect4, %1}
|
|
with exact any4 STACK
|
|
kills allexceptcon
|
|
uses AA_REG = %1
|
|
gen move_l {post_inc4, sp}, {indirect4, %a}
|
|
with exact STACK
|
|
kills allexceptcon
|
|
uses AA_REG
|
|
gen move_l {post_inc4, sp}, %a
|
|
move_l {post_inc4, sp}, {indirect4, %a}
|
|
with exact local_addr store4
|
|
kills allexceptcon
|
|
gen move %2, {DLOCAL, %1.bd}
|
|
with exact ext_addr store4
|
|
kills allexceptcon
|
|
gen move %2, {absolute4, %1.bd}
|
|
#ifndef TBL68020
|
|
with regAcon store4-sconsts4
|
|
kills allexceptcon
|
|
gen move %2, {offsetted4, %1.reg, %1.bd}
|
|
with regAregXcon store4-sconsts4
|
|
kills allexceptcon
|
|
gen move %2, {index_off4, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#else /* TBL68020 */
|
|
with exact regAcon store4
|
|
kills allexceptcon
|
|
gen move %2, {offsetted4, %1.reg, %1.bd}
|
|
with exact regAregXcon store4
|
|
kills allexceptcon
|
|
gen move %2, {index_off4, %1.reg, %1.xreg, %1.sc, %1.bd}
|
|
#if WORD_SIZE==4
|
|
with exact LOCAL store4
|
|
kills allexceptcon
|
|
gen move %2, {ILOCAL, %1.bd}
|
|
#endif
|
|
#ifdef FANCY_MODES
|
|
with exact indirect4 store4
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off4, %1.reg, 0, 0}
|
|
with exact offsetted4 store4
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off4, %1.reg, %1.bd, 0}
|
|
with exact off_con store4
|
|
kills allexceptcon
|
|
gen move %2, {OFF_off4, %1.reg, %1.bd, %1.od}
|
|
with exact index_off4 store4
|
|
kills allexceptcon
|
|
gen move %2, {INDOFF_off4, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
|
|
with exact indoff_con store4
|
|
kills allexceptcon
|
|
gen move %2, {INDOFF_off4, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact off_regXcon store4
|
|
kills allexceptcon
|
|
gen move %2, {OFF_indoff4, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
|
|
with exact absolute4 store4
|
|
kills allexceptcon
|
|
gen move %2, {ABS_off4, %1.bd, 0}
|
|
with exact abs_con store4
|
|
kills allexceptcon
|
|
gen move %2, {ABS_off4, %1.bd, %1.od}
|
|
with exact abs_regXcon store4
|
|
kills allexceptcon
|
|
gen move %2, {ABS_indoff4, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact abs_index4 store4
|
|
kills allexceptcon
|
|
gen move %2, {ABSIND_off4, %1.sc, %1.xreg, %1.bd, 0}
|
|
with exact absind_con store4
|
|
kills allexceptcon
|
|
gen move %2, {ABSIND_off4, %1.sc, %1.xreg, %1.bd, %1.od}
|
|
with exact ext_regX store4
|
|
kills allexceptcon
|
|
gen move %2, {abs_index4, %1.sc, %1.xreg, %1.bd}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
#if WORD_SIZE==2
|
|
pat sti $1==6
|
|
with A_REG any4 any2
|
|
kills ALL
|
|
gen move %2, {indirect4, %1}
|
|
move %3, {offsetted2, %1, 4}
|
|
with AA_REG any4 any2
|
|
kills ALL
|
|
gen move %2, {post_inc4, %1}
|
|
move %3, {post_inc2, %1}
|
|
with exact A_REG STACK
|
|
kills ALL
|
|
gen move_l {post_inc4, sp}, {indirect4, %1}
|
|
move_w {post_inc2, sp}, {offsetted2, %1, 4}
|
|
with exact AA_REG STACK
|
|
kills ALL
|
|
gen move_l {post_inc4, sp}, {post_inc4, %1}
|
|
move_w {post_inc2, sp}, {post_inc2, %1}
|
|
#endif
|
|
|
|
pat sti $1==8
|
|
#if WORD_SIZE!=2
|
|
leaving sdf 0
|
|
#else
|
|
with AA_REG any4-pre_post any4-pre_post
|
|
kills ALL
|
|
gen move_l %2,{indirect4, %1}
|
|
move_l %3,{offsetted4, %1, 4}
|
|
with exact local_addr any4-pre_post any4-pre_post
|
|
kills ALL
|
|
gen move_l %2,{offsetted4, lb, %1.bd}
|
|
move_l %3,{offsetted4, lb, %1.bd+4}
|
|
with exact ext_addr any4-pre_post any4-pre_post
|
|
kills ALL
|
|
gen move_l %2,{absolute4, %1.bd}
|
|
move_l %3,{absolute4, %1.bd+4}
|
|
#endif
|
|
|
|
|
|
#if WORD_SIZE==4
|
|
pat sti $1==3*WORD_SIZE
|
|
with AA_REG STACK
|
|
kills ALL
|
|
gen move_i {post_inc_int, sp},{post_inc_int,%1}
|
|
move_i {post_inc_int, sp},{post_inc_int,%1}
|
|
move_i {post_inc_int, sp},{post_inc_int,%1}
|
|
|
|
pat sti $1==4*WORD_SIZE
|
|
with AA_REG STACK
|
|
kills ALL
|
|
gen move_i {post_inc_int, sp},{post_inc_int,%1}
|
|
move_i {post_inc_int, sp},{post_inc_int,%1}
|
|
move_i {post_inc_int, sp},{post_inc_int,%1}
|
|
move_i {post_inc_int, sp},{post_inc_int,%1}
|
|
#endif
|
|
|
|
pat sti $1>4*WORD_SIZE && $1/WORD_SIZE <= 65536
|
|
with AA_REG STACK
|
|
kills ALL
|
|
uses DD_REG4 = {const, $1/WORD_SIZE -1}
|
|
gen 1:
|
|
move_i {post_inc_int, sp}, {post_inc_int, %1}
|
|
dbf %a, {slabel, 1b}
|
|
|
|
pat sti
|
|
with STACK
|
|
kills ALL
|
|
gen move_i {const, $1}, {pre_dec_int, sp}
|
|
jsr {absolute4, ".sts"}
|
|
|
|
pat sts $1==WORD_SIZE
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".sts"}
|
|
#if WORD_SIZE==2
|
|
pat sts $1==4
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".sts4"}
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
pat sdl
|
|
with store4-sconsts4
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen move %1, {DLOCAL, $1}
|
|
with exact STACK
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen move_l {post_inc4,sp}, {DLOCAL, $1}
|
|
#else
|
|
pat sdl
|
|
with any4-sconsts any4-sconsts
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen move %1, {LOCAL, $1}
|
|
move %2, {LOCAL, $1+4}
|
|
#if TBL68881
|
|
with exact FD_REG
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen fmove_d %1, {LOCAL, $1}
|
|
#endif
|
|
with exact STACK
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen move_l {post_inc4, sp}, {LOCAL,$1}
|
|
move_l {post_inc4, sp}, {LOCAL,$1+4}
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
pat sde
|
|
#if WORD_SIZE==2
|
|
with any4-sconsts4
|
|
kills posextern
|
|
gen move_l %1, {absolute4, $1}
|
|
with exact STACK
|
|
kills posextern
|
|
gen move_l {post_inc4, sp}, {absolute4, $1}
|
|
#else
|
|
with any4-sconsts any4-sconsts
|
|
kills posextern
|
|
gen move %1, {absolute4, $1}
|
|
move %2, {absolute4, $1+4}
|
|
#if TBL68881
|
|
with exact FD_REG
|
|
kills posextern
|
|
gen fmove_d %1, {absolute4, $1}
|
|
#endif
|
|
with exact STACK
|
|
kills posextern
|
|
gen move_l {post_inc4, sp}, {absolute4,$1}
|
|
move_l {post_inc4, sp}, {absolute4,$1+4}
|
|
#endif
|
|
|
|
pat sdf
|
|
#if WORD_SIZE==2
|
|
with A_REG any4-sconsts4
|
|
kills allexceptcon
|
|
gen move_l %2, {offsetted4, %1, $1}
|
|
with exact A_REG STACK
|
|
kills allexceptcon
|
|
gen move_l {post_inc4, sp}, {offsetted4, %1, $1}
|
|
#else
|
|
with A_REG any4-sconsts any4-sconsts
|
|
kills allexceptcon
|
|
gen move %2, {offsetted4, %1, $1}
|
|
move %3, {offsetted4, %1, $1+4}
|
|
with exact local_addr any4 any4
|
|
kills allexceptcon
|
|
gen move %2, {LOCAL, %1.bd+$1}
|
|
move %3, {LOCAL, %1.bd+$1+4}
|
|
with regAcon any4-sconsts any4-sconsts
|
|
kills allexceptcon
|
|
gen move %2, {offsetted4, %1.reg, %1.bd+$1}
|
|
move %3, {offsetted4, %1.reg, %1.bd+$1+4}
|
|
#endif
|
|
|
|
|
|
|
|
/************************************************
|
|
* Group 3: integer arithmetic. *
|
|
************************************************/
|
|
|
|
#if WORD_SIZE==2
|
|
pat adi $1==2
|
|
with any2-bconst DD_REG
|
|
gen add_w %1, %2 yields %2
|
|
with DD_REG any2-DD_REG-bconst
|
|
gen add_w %2, %1 yields %1
|
|
with exact any2 STACK
|
|
uses reusing %1,DD_REG=%1
|
|
gen add_w {post_inc2, sp}, %a
|
|
yields %a
|
|
#endif
|
|
|
|
pat adi $1==4
|
|
with any4-bconst4 DD_REG4
|
|
gen add_l %1, %2 yields %2
|
|
with DD_REG4 any4-DD_REG4-bconst4
|
|
gen add_l %2, %1 yields %1
|
|
with exact any4 STACK
|
|
uses reusing %1,DD_REG4=%1
|
|
gen add_l {post_inc4, sp}, %a
|
|
yields %a
|
|
|
|
pat adi $1==8
|
|
with exact any4 any4 DD_REG4 DD_REG4
|
|
uses reusing %1, DD_REG4 = %1
|
|
gen add_l %2, %4
|
|
addx_l %a, %3 yields %4 %3
|
|
with DD_REG4 DD_REG4 D_REG4 any4
|
|
gen add_l %4, %2
|
|
addx_l %3, %1 yields %2 %1
|
|
with DD_REG4 DD_REG4 D_REG4 STACK
|
|
gen add_l {post_inc4, sp}, %2
|
|
addx_l %3, %1 yields %2 %1
|
|
|
|
#if WORD_SIZE==2
|
|
pat sbi $1==2
|
|
with any2-bconst DD_REG
|
|
gen sub_w %1, %2 yields %2
|
|
with DD_REG any2-DD_REG-bconst
|
|
gen sub_w %2, %1
|
|
neg_w %1 yields %1
|
|
with exact any2 STACK
|
|
uses reusing %1,DD_REG=%1
|
|
gen sub_w {post_inc2, sp}, %a
|
|
neg_w %a yields %a
|
|
#endif
|
|
|
|
pat sbi $1==4
|
|
with any4-bconst4 DD_REG4
|
|
gen sub_l %1, %2 yields %2
|
|
with DD_REG4 any4-DD_REG4-bconst4
|
|
gen sub_l %2, %1
|
|
neg_l %1 yields %1
|
|
with exact any4 STACK
|
|
uses reusing %1,DD_REG4=%1
|
|
gen sub_l {post_inc4, sp}, %a
|
|
neg_l %a yields %a
|
|
with any4-bconst4 AA_REG
|
|
gen sub_l %1, %2 yields %2
|
|
|
|
pat sbi $1==8
|
|
with D_REG4 any4-D_REG4 DD_REG4 DD_REG4
|
|
/* only 3 of DD_REG4; may unstack %2 into AA_REG */
|
|
gen sub_l %2, %4
|
|
subx_l %1, %3 yields %4 %3
|
|
|
|
#if WORD_SIZE==2
|
|
pat loc loc cii ldc mli $1==2 && $2==4 && highw($4)==0 && loww($4)>0 && $5==4
|
|
with any2-pre_post
|
|
uses reusing %1, DD_REG4
|
|
gen move %1, %a.1
|
|
muls_w {const, loww($4)}, %a.1
|
|
yields %a
|
|
|
|
pat mli $1==2
|
|
with any2-pre_post any2-pre_post
|
|
uses reusing %2,DD_REG = %2
|
|
gen muls_w %1, %a yields %a
|
|
#endif
|
|
|
|
pat mli $1==4
|
|
#ifdef TBL68020
|
|
with data4 DD_REG4
|
|
gen muls_l %1, %2 yields %2
|
|
#else /* TBL68020 */
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".mli"}
|
|
yields dl1
|
|
#endif
|
|
|
|
#ifdef TBL68020
|
|
pat mli $1==8
|
|
with exact data4 data4 DD_REG4 DD_REG4 /* yh yl xh xl */
|
|
uses DD_REG4 = %4
|
|
gen mulu_l %1, %a /* xl * yh */
|
|
mulu_l %2, %3 /* xh * yl */
|
|
add_l %3, %a
|
|
mulu_l %2, {DREG_pair, %3, %4} /* xl * yl */
|
|
add_l %a, %3
|
|
yields %4 %3
|
|
with DD_REG4 DD_REG4 data4 data4 /* yh yl xh xl */
|
|
uses DD_REG = %2
|
|
gen mulu_l %3, %a /* yl * xh */
|
|
mulu_l %4, %1 /* yh * xl */
|
|
add_l %1, %a
|
|
mulu_l %4, {DREG_pair, %1, %2} /* yl * xl */
|
|
add_l %a, %1
|
|
yields %2 %1
|
|
with DD_REG4 DD_REG4 STACK /* yh yl xh xl */
|
|
uses DD_REG4 = %2
|
|
gen mulu_l {post_inc4, sp}, %a /* yl * xh */
|
|
mulu_l {indirect4, sp}, %1 /* yh * xl */
|
|
add_l %1, %a
|
|
mulu_l {post_inc4, sp}, {DREG_pair, %1, %2} /* yl * xl */
|
|
add_l %a, %1
|
|
yields %2 %1
|
|
#endif /* TBL68020 */
|
|
|
|
#if WORD_SIZE==2
|
|
pat dvi $1==2
|
|
with data2-sconsts DD_REG
|
|
gen ext_l %2
|
|
divs_w %1, %2
|
|
yields %2
|
|
#endif
|
|
|
|
pat dvi $1==4
|
|
#ifdef TBL68020
|
|
with data4-sconsts4 DD_REG4
|
|
gen divs_l %1, %2 yields %2
|
|
#else /* TBL68020 */
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".dvi"}
|
|
yields dl1
|
|
#endif /* TBL68020 */
|
|
|
|
#ifdef TBL68020
|
|
pat dvi $1==8
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".dvi8"}
|
|
yields dl1 dl0
|
|
#endif /* TBL68020 */
|
|
|
|
#if WORD_SIZE==2
|
|
pat rmi $1==2
|
|
with data2-sconsts DD_REG
|
|
gen ext_l %2
|
|
divs_w %1, %2
|
|
swap %2
|
|
killreg %2
|
|
yields %2
|
|
#endif
|
|
|
|
pat rmi $1==4
|
|
#ifdef TBL68020
|
|
with data4-sconsts4 DD_REG4
|
|
uses DD_REG4
|
|
gen divsl_l %1, {DREG_pair, %a, %2}
|
|
killreg %2
|
|
/* !!!! contents of %2 have changed: make this known to cg */
|
|
yields %a
|
|
#else /* TBL68020 */
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".dvi"}
|
|
yields dl2
|
|
#endif /* TBL68020 */
|
|
|
|
#ifdef TBL68020
|
|
pat rmi $1==8
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".rmi8"}
|
|
yields dl1 dl0
|
|
#endif /* TBL68020 */
|
|
|
|
#if WORD_SIZE==2
|
|
pat ngi $1==2
|
|
with DD_REG
|
|
gen neg_w %1 yields %1
|
|
#endif
|
|
|
|
pat ngi $1==4
|
|
with DD_REG4
|
|
gen neg_l %1 yields %1
|
|
|
|
pat ngi $1==8
|
|
with DD_REG4 DD_REG4
|
|
gen neg_l %2
|
|
negx_l %1 yields %2 %1
|
|
|
|
#if WORD_SIZE==2
|
|
pat sli $1==2
|
|
with shconreg DD_REG
|
|
gen asl_w %1, %2 yields %2
|
|
#endif
|
|
|
|
pat sli $1==4
|
|
with shconreg DD_REG4
|
|
gen asl_l %1, %2 yields %2
|
|
|
|
pat sli $1==8
|
|
with DD_REG4 DD_REG4 DD_REG4
|
|
uses AA_REG = %3 /* no 4th DD_REG */
|
|
gen lsl_l %1, %3
|
|
lsl_l %1, %2 /* shift by %1 modulo 64 */
|
|
bchg {const, 5}, %1
|
|
bne {slabel, 1f} /* jump if shift >= 32 */
|
|
neg_l %1
|
|
exg %a, %3
|
|
lsr_l %1, %3 /* (32 - shift) modulo 64 */
|
|
or_l %3, %2 /* shift bits from %3 to %2 */
|
|
move %a, %3
|
|
bra {slabel, 2f}
|
|
1:
|
|
move %a, %2
|
|
lsl_l %1, %2 /* (shift - 32) modulo 64 */
|
|
2: yields %3 %2
|
|
|
|
pat loc sli ($1&32)==0 && $2==8
|
|
with DD_REG4 DD_REG4
|
|
uses AA_REG = %2, DD_REG = {bconst, $1&31}
|
|
gen lsl_l %b, %2
|
|
lsl_l %b, %1
|
|
bset {const, 5}, %b
|
|
neg_l %b
|
|
exg %a, %2
|
|
lsr_l %b, %2
|
|
or_l %2, %1
|
|
move %a, %2
|
|
yields %2 %1
|
|
pat loc sli ($1&63)==32 && $2==8
|
|
with any4 any4 yields {zero_const, 0} %2
|
|
pat loc sli ($1&32)!=0 && $2==8
|
|
with any4 DD_REG4
|
|
uses reusing %1, DD_REG = {bconst, $1&31}
|
|
gen lsl_l %a, %2 yields {zero_const, 0} %2
|
|
|
|
#if WORD_SIZE==2
|
|
pat sri $1==2
|
|
with shconreg DD_REG
|
|
gen asr_w %1, %2 yields %2
|
|
#endif
|
|
|
|
pat sri $1==4
|
|
with shconreg DD_REG4
|
|
gen asr_l %1, %2 yields %2
|
|
|
|
pat sri $1==8
|
|
with DD_REG4 DD_REG4 DD_REG4
|
|
uses AA_REG = %2 /* no 4th DD_REG */
|
|
gen asr_l %1, %2
|
|
lsr_l %1, %3 /* shift by %1 modulo 64 */
|
|
bchg {const, 5}, %1
|
|
bne {slabel, 1f} /* jump if shift >= 32 */
|
|
neg_l %1
|
|
exg %a, %2
|
|
lsl_l %1, %2 /* (32 - shift) modulo 64 */
|
|
or_l %2, %3 /* shift bits from %2 to %3 */
|
|
move %a, %2
|
|
bra {slabel, 2f}
|
|
1:
|
|
move %a, %3
|
|
asr_l %1, %3 /* (shift - 32) modulo 64 */
|
|
2: yields %3 %2
|
|
|
|
pat loc sri ($1&32)==0 && $2==8
|
|
with DD_REG4 DD_REG4
|
|
uses AA_REG = %1, DD_REG = {bconst, $1&31}
|
|
gen asr_l %b, %1
|
|
lsr_l %b, %2
|
|
bset {const, 5}, %b
|
|
neg_l %b
|
|
exg %a, %1
|
|
lsl_l %b, %1
|
|
or_l %1, %2
|
|
move %a, %1
|
|
yields %2 %1
|
|
pat loc sri ($1&63)==32 && $2==8
|
|
with DD_REG4 any4 yields %1 leaving loc 4 loc 8 cii
|
|
pat loc sri ($1&32)!=0 && $2==8
|
|
with DD_REG4 any4
|
|
uses reusing %2, DD_REG = {bconst, $1&31}
|
|
gen asr_l %a, %1 yields %1 leaving loc 4 loc 8 cii
|
|
|
|
/************************************************
|
|
* Group 4: unsigned arithmetic. *
|
|
************************************************/
|
|
|
|
pat adu leaving adi $1
|
|
|
|
pat sbu leaving sbi $1
|
|
|
|
#if WORD_SIZE==2
|
|
pat mlu $1==2
|
|
with any2-pre_post any2-pre_post
|
|
uses reusing %2,DD_REG = %2
|
|
gen mulu_w %1, %a yields %a
|
|
#endif
|
|
|
|
pat mlu $1==4
|
|
#ifdef TBL68020
|
|
with data4-sconsts4 DD_REG4
|
|
gen mulu_l %1, %2 yields %2
|
|
#else /* TBL68020 */
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".mlu"}
|
|
yields dl1
|
|
#endif /* TBL68020 */
|
|
|
|
pat mlu $1==8 leaving mli 8
|
|
|
|
#if WORD_SIZE==2
|
|
pat dvu $1==2
|
|
with data2-sconsts data2
|
|
uses DD_REG4 = {zero_const4,0}
|
|
gen move %2,%a.1
|
|
divu_w %1, %a.1 yields %a.1
|
|
#endif
|
|
|
|
pat dvu $1==4
|
|
#ifdef TBL68020
|
|
with data4-sconsts4 DD_REG4
|
|
gen divu_l %1, %2 yields %2
|
|
#else /* TBL68020 */
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".dvu"}
|
|
yields dl1
|
|
#endif /* TBL68020 */
|
|
|
|
#ifdef TBL68020
|
|
pat dvu $1==8
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".dvu8"}
|
|
yields dl1 dl0
|
|
#endif /* TBL68020 */
|
|
|
|
#if WORD_SIZE==2
|
|
pat rmu $1==2
|
|
with data2-sconsts data2
|
|
uses DD_REG4 = {zero_const4, 0}
|
|
gen move %2,%a.1
|
|
divu_w %1, %a.1
|
|
swap %a.1
|
|
killreg %a
|
|
yields %a.1
|
|
#endif
|
|
|
|
pat rmu $1==4
|
|
#ifdef TBL68020
|
|
with data4-sconsts4 DD_REG4
|
|
uses DD_REG4
|
|
gen divul_l %1, {DREG_pair, %a, %2}
|
|
killreg %2
|
|
/* !!!! contents of %2 have changed: make this known to cg */
|
|
yields %a
|
|
#else /* TBL68020 */
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".dvu"}
|
|
yields dl2
|
|
#endif /* TBL68020 */
|
|
|
|
#ifdef TBL68020
|
|
pat rmu $1==8
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".rmu8"}
|
|
yields dl1 dl0
|
|
#endif /* TBL68020 */
|
|
|
|
pat slu leaving sli $1
|
|
|
|
pat loc slu $2==8 leaving loc $1 sli 8
|
|
|
|
#if WORD_SIZE==2
|
|
pat sru $1==2
|
|
with shconreg DD_REG
|
|
gen lsr_w %1, %2 yields %2
|
|
#endif
|
|
|
|
pat sru $1==4
|
|
with shconreg DD_REG4
|
|
gen lsr_l %1, %2 yields %2
|
|
|
|
pat sru $1==8
|
|
with DD_REG4 DD_REG4 DD_REG4
|
|
uses AA_REG = %2 /* no 4th DD_REG */
|
|
gen lsr_l %1, %2
|
|
lsr_l %1, %3 /* shift by %1 modulo 64 */
|
|
bchg {const, 5}, %1
|
|
bne {slabel, 1f} /* jump if shift >= 32 */
|
|
neg_l %1
|
|
exg %a, %2
|
|
lsl_l %1, %2 /* (32 - shift) modulo 64 */
|
|
or_l %2, %3 /* shift bits from %2 to %3 */
|
|
move %a, %2
|
|
bra {slabel, 2f}
|
|
1:
|
|
move %a, %3
|
|
lsr_l %1, %3 /* (shift - 32) modulo 64 */
|
|
2: yields %3 %2
|
|
|
|
pat loc sru ($1&32)==0 && $2==8
|
|
with DD_REG4 DD_REG4
|
|
uses AA_REG = %2, DD_REG = {bconst, $1&31}
|
|
gen lsr_l %b, %1
|
|
lsr_l %b, %2
|
|
bset {const, 5}, %b
|
|
neg_l %b
|
|
exg %a, %1
|
|
lsl_l %b, %1
|
|
or_l %1, %2
|
|
move %a, %1
|
|
yields %2 %1
|
|
pat loc sru ($1&63)==32 && $2==8
|
|
with any4 any4 yields %1 {zero_const, 0}
|
|
pat loc sru ($1&32)!=0 && $2==8
|
|
with DD_REG4 any4
|
|
uses reusing %2, DD_REG = {bconst, $1&31}
|
|
gen lsr_l %a, %1 yields %1 {zero_const, 0}
|
|
|
|
/************************************************
|
|
* Group 5: floating point arithmetic *
|
|
************************************************/
|
|
|
|
/* Floating point stuff
|
|
* Arithmetic instructions
|
|
*/
|
|
|
|
#if TBL68881
|
|
pat adf stl $1==4
|
|
with FS_REG STACK
|
|
gen fadd_s {post_inc4,sp},%1 yields %1 leaving stl $2
|
|
pat adf sdl $1==8
|
|
with FD_REG STACK
|
|
gen fadd_d {post_inc4,sp},%1 yields %1 leaving sdl $2
|
|
pat sbf stl $1==4
|
|
with FS_REG FS_REG STACK
|
|
gen fsub %1,%2 yields %2 leaving stl $2
|
|
pat sbf sdl $1==8
|
|
with FD_REG FD_REG STACK
|
|
gen fsub %1,%2 yields %2 leaving sdl $2
|
|
pat mlf stl $1==4
|
|
with FS_REG STACK
|
|
gen fmul_s {post_inc4,sp},%1 yields %1 leaving stl $2
|
|
pat mlf sdl $1==8
|
|
with FD_REG STACK
|
|
gen fmul_d {post_inc4,sp},%1 yields %1 leaving sdl $2
|
|
pat dvf stl $1==4
|
|
with FS_REG FS_REG STACK
|
|
gen fdiv %1,%2 yields %2 leaving stl $2
|
|
pat dvf sdl $1==8
|
|
with FD_REG FD_REG STACK
|
|
gen fdiv %1,%2 yields %2 leaving sdl $2
|
|
pat ngf stl $1==4
|
|
with FS_REG STACK
|
|
gen fneg %1 yields %1 leaving stl $2
|
|
pat ngf sdl $1==8
|
|
with FD_REG STACK
|
|
gen fneg %1 yields %1 leaving sdl $2
|
|
|
|
pat adf ste $1==4
|
|
with FS_REG STACK
|
|
gen fadd_s {post_inc4,sp},%1 yields %1 leaving ste $2
|
|
pat adf sde $1==8
|
|
with FD_REG STACK
|
|
gen fadd_d {post_inc4,sp},%1 yields %1 leaving sde $2
|
|
pat sbf ste $1==4
|
|
with FS_REG FS_REG STACK
|
|
gen fsub %1,%2 yields %2 leaving ste $2
|
|
pat sbf sde $1==8
|
|
with FD_REG FD_REG STACK
|
|
gen fsub %1,%2 yields %2 leaving sde $2
|
|
pat mlf ste $1==4
|
|
with FS_REG STACK
|
|
gen fmul_s {post_inc4,sp},%1 yields %1 leaving ste $2
|
|
pat mlf sde $1==8
|
|
with FD_REG STACK
|
|
gen fmul_d {post_inc4,sp},%1 yields %1 leaving sde $2
|
|
pat dvf ste $1==4
|
|
with FS_REG FS_REG STACK
|
|
gen fdiv %1,%2 yields %2 leaving ste $2
|
|
pat dvf sde $1==8
|
|
with FD_REG FD_REG STACK
|
|
gen fdiv %1,%2 yields %2 leaving sde $2
|
|
pat ngf ste $1==4
|
|
with FS_REG STACK
|
|
gen fneg %1 yields %1 leaving ste $2
|
|
pat ngf sde $1==8
|
|
with FD_REG STACK
|
|
gen fneg %1 yields %1 leaving sde $2
|
|
|
|
pat adf $1==4
|
|
with FS_REG STACK
|
|
gen fadd_s {indirect4,sp},%1
|
|
fmove_s %1,{indirect4,sp}
|
|
pat adf $1==8
|
|
with FD_REG STACK
|
|
gen fadd_d {indirect4,sp},%1
|
|
fmove_d %1,{indirect4,sp}
|
|
pat sbf $1==4
|
|
with FS_REG FS_REG STACK
|
|
gen fsub %1,%2
|
|
fmove_s %2,{pre_dec4,sp}
|
|
pat sbf $1==8
|
|
with FD_REG FD_REG STACK
|
|
gen fsub %1,%2
|
|
fmove_d %2,{pre_dec4,sp}
|
|
pat mlf $1==4
|
|
with FS_REG STACK
|
|
gen fmul_s {indirect4,sp},%1
|
|
fmove_s %1,{indirect4,sp}
|
|
pat mlf $1==8
|
|
with FD_REG STACK
|
|
gen fmul_d {indirect4,sp},%1
|
|
fmove_d %1,{indirect4,sp}
|
|
pat dvf $1==4
|
|
with FS_REG FS_REG STACK
|
|
gen fdiv %1,%2
|
|
fmove_s %2,{pre_dec4,sp}
|
|
pat dvf $1==8
|
|
with FD_REG FD_REG STACK
|
|
gen fdiv %1,%2
|
|
fmove_d %2,{pre_dec4,sp}
|
|
pat ngf $1==4
|
|
with FS_REG STACK
|
|
gen fneg %1
|
|
fmove_s %1,{pre_dec4,sp}
|
|
pat ngf $1==8
|
|
with FD_REG STACK
|
|
gen fneg %1
|
|
fmove_d %1,{pre_dec4,sp}
|
|
pat fif $1==4
|
|
with FS_REG FS_REG STACK
|
|
gen fmul %1,%2
|
|
fintrz %2,%1
|
|
fsub %1,%2
|
|
fmove_s %2,{pre_dec4,sp}
|
|
fmove_s %1,{pre_dec4,sp}
|
|
pat fif $1==8
|
|
with FD_REG FD_REG STACK
|
|
gen fmul %1,%2
|
|
fintrz %2,%1
|
|
fsub %1,%2
|
|
fmove_d %2,{pre_dec4,sp}
|
|
fmove_d %1,{pre_dec4,sp}
|
|
#else
|
|
pat adf $1==4 leaving cal ".adf4" asp 4
|
|
pat adf $1==8 leaving cal ".adf8" asp 8
|
|
pat sbf $1==4 leaving cal ".sbf4" asp 4
|
|
pat sbf $1==8 leaving cal ".sbf8" asp 8
|
|
pat mlf $1==4 leaving cal ".mlf4" asp 4
|
|
pat mlf $1==8 leaving cal ".mlf8" asp 8
|
|
pat dvf $1==4 leaving cal ".dvf4" asp 4
|
|
pat dvf $1==8 leaving cal ".dvf8" asp 8
|
|
pat ngf $1==4 leaving cal ".ngf4"
|
|
pat ngf $1==8 leaving cal ".ngf8"
|
|
pat fif $1==4 leaving lor 1 cal ".fif4" asp 4
|
|
pat fif $1==8 leaving lor 1 cal ".fif8" asp 4
|
|
#endif
|
|
#if WORD_SIZE==2
|
|
pat fef $1==4 leaving lor 1 adp 0-2 cal ".fef4" asp 2
|
|
pat fef $1==8 leaving lor 1 adp 0-2 cal ".fef8" asp 2
|
|
#else
|
|
pat fef $1==4 leaving lor 1 adp 0-4 cal ".fef4"
|
|
pat fef $1==8 leaving lor 1 adp 0-4 cal ".fef8"
|
|
#endif
|
|
|
|
/************************************************
|
|
* Group 6: pointer arithmetic *
|
|
************************************************/
|
|
|
|
pat adp $1==0 /* skip; array instructions might 'leave' this */
|
|
|
|
pat adp
|
|
with A_REG yields {t_regAcon, %1, $1}
|
|
with exact local_addr yields {local_addr, %1.bd+$1}
|
|
with exact ext_addr yields {ext_addr, %1.bd+$1}
|
|
with exact regAcon + t_regAcon
|
|
yields {t_regAcon, %1.reg, %1.bd+$1}
|
|
with exact regAregXcon + t_regAregXcon
|
|
yields {t_regAregXcon,%1.reg, %1.xreg, %1.sc, %1.bd+$1}
|
|
#if TBL68020 && FANCY_MODES
|
|
with exact indirect4 yields {off_con, %1.reg, 0, $1}
|
|
with exact LOCAL yields {off_con, lb, %1.bd, $1}
|
|
with exact offsetted4 yields {off_con, %1.reg, %1.bd, $1}
|
|
with exact off_con yields {off_con, %1.reg, %1.bd, %1.od+$1}
|
|
with exact index_off4 yields {indoff_con, %1.reg, %1.xreg, %1.sc, %1.bd, $1}
|
|
with exact indoff_con yields {indoff_con,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
|
|
with exact off_regXcon yields {off_regXcon,
|
|
%1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
|
|
with exact absolute4 yields {abs_con, %1.bd, $1}
|
|
with exact abs_con yields {abs_con, %1.bd, %1.od+$1}
|
|
with exact abs_regXcon yields {abs_regXcon, %1.sc, %1.xreg, %1.bd, %1.od+$1}
|
|
with exact abs_index4 yields {absind_con, %1.sc, %1.xreg, %1.bd, $1}
|
|
with exact absind_con yields {absind_con, %1.sc, %1.xreg, %1.bd, %1.od+$1}
|
|
with exact ext_regX yields {ext_regX, %1.sc, %1.xreg, %1.bd+$1}
|
|
#endif
|
|
|
|
pat ads cmp $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving cmu 4
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving cmu 4
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving cmu 4
|
|
#endif
|
|
|
|
#if WORD_SIZE!=2
|
|
pat ads bne $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving bne $2
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving bne $2
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving bne $2
|
|
#endif
|
|
|
|
pat ads beq $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving beq $2
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving beq $2
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving beq $2
|
|
#endif
|
|
|
|
pat ads LEP bne $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving LEP $2 bne $3
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving LEP $2 bne $3
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving loe $2 bne $3
|
|
#endif
|
|
|
|
pat ads LEP beq $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving LEP $2 beq $3
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving LEP $2 beq $3
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving loe $2 beq $3
|
|
#endif
|
|
|
|
pat ads LEP cmp $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving LEP $2 cmu 4
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving LEP $2 cmu 4
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving LEP $2 cmu 4
|
|
#endif
|
|
|
|
pat ads lae bne $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving lae $2 bne $3
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving lae $2 bne $3
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lae $2 bne $3
|
|
#endif
|
|
|
|
pat ads lae beq $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving lae $2 beq $3
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving lae $2 beq $3
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lae $2 beq $3
|
|
#endif
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
pat ads lae cmp $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving lae $2 cmu 4
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving lae $2 cmu 4
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lae $2 cmu 4
|
|
#endif
|
|
|
|
#if WORD_SIZE!=2
|
|
pat ads lal bne $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving lal $2 bne $3
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving lal $2 bne $3
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lal $2 bne $3
|
|
#endif
|
|
|
|
pat ads lal beq $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving lal $2 beq $3
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving lal $2 beq $3
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lal $2 beq $3
|
|
#endif
|
|
|
|
pat ads lal cmp $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving lal $2 cmu 4
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving lal $2 cmu 4
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lal $2 cmu 4
|
|
#endif
|
|
|
|
pat ads LLP bne $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving LLP $2 bne $3
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving LLP $2 bne $3
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lol $2 bne $3
|
|
#endif
|
|
|
|
pat ads LLP beq $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving LLP $2 beq $3
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving LLP $2 beq $3
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lol $2 beq $3
|
|
#endif
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
pat ads LLP cmp $1==4
|
|
with DD_REG4 any4
|
|
gen add_l %2, %1 yields %1 leaving LLP $2 cmu 4
|
|
with any4 DD_REG4
|
|
gen add_l %1, %2 yields %2 leaving LLP $2 cmu 4
|
|
#ifdef TBL68020
|
|
with regX AA_REG
|
|
gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
|
|
yields %2 leaving lol $2 cmu 4
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
pat ads $1==2
|
|
leaving loc 2 loc 4 cii ads 4
|
|
#endif
|
|
|
|
pat ads $1==4
|
|
with D_REG4 A_REG yields {regAregXcon, %2, %1, 1, 0}
|
|
with D_REG4 regAcon + t_regAcon
|
|
yields {t_regAregXcon, %2.reg, %1, 1, %2.bd}
|
|
with D_REG4 local_addr yields {t_regAregXcon, lb, %1, 1, %2.bd}
|
|
with any4 AA_REG
|
|
gen add_l %1, %2 yields %2
|
|
|
|
#ifdef TBL68020
|
|
|
|
with D_REG4 yields {regX, 1, %1}
|
|
leaving ads 4
|
|
with regX A_REG yields {regAregXcon, %2, %1.xreg, %1.sc, 0}
|
|
with exact regX regAcon yields {regAregXcon, %2.reg, %1.xreg, %1.sc, %2.bd}
|
|
with exact regX local_addr
|
|
yields {regAregXcon, lb, %1.xreg, %1.sc, %2.bd}
|
|
#ifdef FANCY_MODES
|
|
with exact regX indirect4
|
|
yields {off_regXcon, %2.reg, %1.xreg,%1.sc,0,0}
|
|
with exact regX offsetted4
|
|
yields {off_regXcon, %2.reg, %1.xreg, %1.sc, %2.bd, 0}
|
|
with exact regX DLOCAL yields {off_regXcon, lb, %1.xreg, %1.sc, %2.bd, 0}
|
|
with exact regX off_con yields {off_regXcon, %2.reg, %1.xreg,%1.sc,%2.bd,%2.od}
|
|
with exact regX ext_addr
|
|
yields {ext_regX, %1.sc, %1.xreg, %2.bd}
|
|
with exact regX absolute4
|
|
yields {abs_regXcon, %1.sc, %1.xreg, %2.bd, 0}
|
|
with exact regX abs_con yields {abs_regXcon, %1.sc, %1.xreg, %2.bd, %2.od}
|
|
with exact indirect4 ext_addr
|
|
yields {off_con, %1.reg, 0, %2.bd}
|
|
with exact offsetted4 ext_addr
|
|
yields {off_con, %1.reg, %1.bd, %2.bd}
|
|
with exact LOCAL ext_addr
|
|
yields {off_con, lb, %1.bd, %2.bd}
|
|
with exact index_off4 ext_addr
|
|
yields {indoff_con, %1.reg, %1.xreg, %1.sc,%1.bd,%2.bd}
|
|
with exact absolute4 ext_addr
|
|
yields {abs_con, %1.bd, %2.bd}
|
|
with exact abs_index4 ext_addr
|
|
yields {absind_con, %1.sc, %1.xreg, %1.bd, %2.bd}
|
|
with exact indirect4 ext_regX
|
|
yields {off_regXcon, %1.reg, %2.xreg, %2.sc, 0, %2.bd}
|
|
with exact offsetted4 ext_regX
|
|
yields {off_regXcon, %1.reg, %2.xreg,%2.sc,%1.bd,%2.bd}
|
|
with exact LOCAL ext_regX
|
|
yields {off_regXcon, lb, %2.xreg, %2.sc, %1.bd, %2.bd}
|
|
with exact absolute4 ext_regX
|
|
yields {abs_regXcon, %2.sc, %2.xreg, %1.bd, %2.bd}
|
|
#endif /* FANCY_MODES */
|
|
#endif /* TBL68020 */
|
|
|
|
/* I WOULD ALSO LIKE THIS:
|
|
* pat ads
|
|
* with const leaving adp %1.num
|
|
* BUT THAT DOESN'T WORK.
|
|
*/
|
|
|
|
#if WORD_SIZE==2
|
|
pat sbs $1==2
|
|
leaving sbs 4 loc 4 loc 2 cii
|
|
#endif
|
|
|
|
pat sbs $1==4 leaving sbi 4
|
|
|
|
/* regX type OK ??? */
|
|
#ifdef TBL68020
|
|
pat loc slu $2==4 leaving loc $1 sli 4
|
|
|
|
pat loc sli ads $1==1 && $2==4 && $3==4
|
|
with D_REG4 yields {regX, 2, %1}
|
|
leaving ads 4
|
|
|
|
pat loc sli ads $1==2 && $2==4 && $3==4
|
|
with D_REG4 yields {regX, 4, %1}
|
|
leaving ads 4
|
|
|
|
pat loc sli ads $1==3 && $2==4 && $3==4
|
|
with D_REG4 yields {regX, 8, %1}
|
|
leaving ads 4
|
|
#else
|
|
|
|
pat loc sli $1==1 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen add_i %1, %1 yields %1
|
|
|
|
#if WORD_SIZE==2
|
|
pat loc sli $1==1 && $2==4
|
|
with DD_REG4
|
|
gen add_l %1, %1 yields %1
|
|
#endif
|
|
|
|
#endif /* TBL68020 */
|
|
|
|
|
|
/************************************************
|
|
* Group 7: increment / decrement / zero *
|
|
************************************************/
|
|
|
|
pat inc leaving loc 1 adi WORD_SIZE
|
|
|
|
pat inl inreg($1)==reg_any
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen add_i {const, 1}, {LOCAL, $1}
|
|
|
|
pat inl
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen add_i {const, 1}, {LOCAL, $1}
|
|
|
|
pat lol inl $1==$2
|
|
kills all_indir, LOCAL %bd==$1
|
|
uses DD_REG = {LOCAL, $1}
|
|
gen add_i {const, 1}, {LOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat ine
|
|
kills posextern
|
|
gen add_i {const, 1}, {absolute_int, $1}
|
|
|
|
pat dec leaving loc 1 sbi WORD_SIZE
|
|
|
|
pat del inreg($1)==reg_any
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen sub_i {const, 1}, {LOCAL, $1}
|
|
|
|
pat del
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen sub_i {const, 1}, {LOCAL, $1}
|
|
|
|
pat lol del $1==$2
|
|
kills all_indir, LOCAL %bd==$1
|
|
uses DD_REG = {LOCAL, $1}
|
|
gen sub_i {const, 1}, {LOCAL, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat dee
|
|
kills posextern
|
|
gen sub_i {const, 1}, {absolute_int, $1}
|
|
|
|
pat zrl inreg($1)==reg_any
|
|
kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
|
|
gen clr_i {LOCAL, $1}
|
|
|
|
pat zrl inreg($1)==reg_pointer
|
|
kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
|
|
gen move {const4,0}, {areg, regvar($1, reg_pointer)}
|
|
|
|
pat zrl
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen clr_i {LOCAL, $1}
|
|
|
|
pat zrl lol $1==$2 && inreg($1) < 0
|
|
kills all_indir, LOCAL %bd==$1
|
|
gen clr_i {LOCAL, $1} yields {zero_const, 0}
|
|
|
|
pat zre
|
|
kills posextern
|
|
gen clr_i {absolute_int, $1}
|
|
|
|
pat zre loe $1==$2
|
|
kills posextern
|
|
gen clr_i {absolute_int, $1} yields {zero_const, 0}
|
|
|
|
pat zer $1==4 yields {zero_const4, 0}
|
|
#if WORD_SIZE==2
|
|
pat zer $1==6 yields {zero_const, 0} {zero_const, 0} {zero_const, 0}
|
|
#else
|
|
pat zer $1==8 yields {zero_const, 0} {zero_const, 0}
|
|
pat zer $1==12 yields {zero_const, 0} {zero_const, 0} {zero_const, 0}
|
|
#endif
|
|
|
|
pat zer $1/WORD_SIZE <= 65536
|
|
with STACK
|
|
uses DD_REG4 = {const, $1/WORD_SIZE -1}
|
|
gen 1:
|
|
clr_i {pre_dec_int, sp}
|
|
dbf %a, {slabel, 1b}
|
|
|
|
pat zer
|
|
with STACK
|
|
uses DD_REG4 = {const, $1/WORD_SIZE}
|
|
gen 1:
|
|
clr_i {pre_dec_int, sp}
|
|
sub_l {const4,1}, %a
|
|
bne {slabel, 1b}
|
|
|
|
/************************************************
|
|
* Group 8: convert instructions *
|
|
************************************************/
|
|
|
|
|
|
|
|
pat cii
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".cii"}
|
|
|
|
#if WORD_SIZE==2
|
|
/* No sign-extension, though this is probably not what you may want.
|
|
* This will teach compiler writers not to convert between unsigneds and
|
|
* integers of a different size.
|
|
*/
|
|
pat loc loc ciu $1==2 && $2==4
|
|
with zero_const
|
|
yields {zero_const4, 0}
|
|
with any
|
|
uses DD_REG4 = {zero_const4, 0}
|
|
gen move %1,%a.1
|
|
yields %a
|
|
|
|
pat loc loc ciu $1==4 && $2==2
|
|
with zero_const4
|
|
yields {zero_const, 0}
|
|
with any4
|
|
uses reusing %1, DD_REG4 = %1
|
|
yields %a.1
|
|
|
|
pat loc loc cui $1==2 && $2==4
|
|
with any2
|
|
uses DD_REG4={zero_const4,0}
|
|
gen move %1,%a.1 yields %a
|
|
|
|
pat loc loc cui $1==4 && $2==2
|
|
with DD_REG4
|
|
yields %1.1
|
|
|
|
pat loc loc cuu $1==2 && $2==4
|
|
with any2
|
|
uses reusing %1,DD_REG4
|
|
gen move %1,%a.1
|
|
and_l {const4,65535}, %a yields %a
|
|
with any2
|
|
uses DD_REG4={zero_const4,0}
|
|
gen move %1,%a.1 yields %a
|
|
|
|
pat loc loc cuu $1==4 && $2==2
|
|
with DD_REG4
|
|
yields %1.1
|
|
#endif
|
|
|
|
pat cuu
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".cuu"}
|
|
|
|
pat ciu leaving cuu
|
|
|
|
pat cui leaving cuu
|
|
|
|
#if TBL68881
|
|
pat loc loc cif $1==4 && $2==4
|
|
with data4 STACK
|
|
uses FS_REG
|
|
gen fmove_l %1,%a
|
|
fmove_s %a,{pre_dec4,sp}
|
|
pat loc loc cif $1==4 && $2==8
|
|
with data4 STACK
|
|
uses FD_REG
|
|
gen fmove_l %1,%a
|
|
fmove_d %a,{pre_dec4,sp}
|
|
pat loc loc cuf $1==4 && $2==4
|
|
with D_REG STACK
|
|
uses FS_REG
|
|
gen fmove_l %1,%a
|
|
tst_l %1
|
|
bge {slabel, 1f}
|
|
fsub_l {const,0-2147483648},%a
|
|
fsub_l {const,0-2147483648},%a
|
|
1:
|
|
fmove_s %a,{pre_dec4,sp}
|
|
pat loc loc cuf $1==4 && $2==8
|
|
with D_REG STACK
|
|
uses FD_REG
|
|
gen fmove_l %1,%a
|
|
tst_l %1
|
|
bge {slabel, 1f}
|
|
fsub_l {const,0-2147483648},%a
|
|
fsub_l {const,0-2147483648},%a
|
|
1:
|
|
fmove_d %a,{pre_dec4,sp}
|
|
pat loc loc cfi $1==4 && $2==4
|
|
with FS_REG
|
|
uses D_REG
|
|
gen fintrz %1,%1
|
|
fmove_l %1,%a yields %a
|
|
pat loc loc cfi $1==8 && $2==4
|
|
with FD_REG
|
|
uses D_REG
|
|
gen fintrz %1,%1
|
|
fmove_l %1,%a yields %a
|
|
pat loc loc cfu $1==4 && $2==4
|
|
with FS_REG
|
|
uses D_REG
|
|
gen fabs %1
|
|
fintrz %1,%1
|
|
fmove_l %1,%a yields %a
|
|
pat loc loc cfu $1==8 && $2==4
|
|
with FD_REG
|
|
uses D_REG
|
|
gen fabs %1
|
|
fintrz %1,%1
|
|
fmove_l %1,%a yields %a
|
|
pat loc loc cff $1==4 && $2==8
|
|
with FS_REG STACK
|
|
gen fmove_d %1,{pre_dec4,sp}
|
|
pat loc loc cff $1==8 && $2==4
|
|
with FD_REG STACK
|
|
gen fmove_s %1,{pre_dec4,sp}
|
|
#else
|
|
/*
|
|
* Floating point stuff
|
|
* Conversion
|
|
*/
|
|
#if WORD_SIZE==2
|
|
/* The patterns need some room on the stack first */
|
|
pat loc loc cif $1==2 && $2==4 leaving loc $1 cal ".cif4"
|
|
|
|
pat loc loc cif $1==2 && $2==8
|
|
with any2
|
|
kills ALL
|
|
gen clr_l {pre_dec4, sp}
|
|
move_w %1,{pre_dec2, sp} leaving loc $1 cal ".cif8"
|
|
|
|
pat loc loc cif $1==4 && $2==4 leaving loc $1 cal ".cif4" asp 2
|
|
|
|
pat loc loc cif $1==4 && $2==8
|
|
with any4
|
|
kills ALL
|
|
gen clr_w {pre_dec2, sp}
|
|
move_l %1,{pre_dec4, sp} leaving loc $1 cal ".cif8"
|
|
|
|
pat loc loc cuf $1==2 && $2==4 leaving loc $1 cal ".cuf4"
|
|
|
|
pat loc loc cuf $1==2 && $2==8
|
|
with any2
|
|
kills ALL
|
|
gen clr_l {pre_dec4, sp}
|
|
move_w %1,{pre_dec2, sp} leaving loc $1 cal ".cuf8"
|
|
|
|
pat loc loc cuf $1==4 && $2==4 leaving loc $1 cal ".cuf4" asp 2
|
|
|
|
pat loc loc cuf $1==4 && $2==8
|
|
with any4
|
|
kills ALL
|
|
gen clr_w {pre_dec2, sp}
|
|
move_l %1,{pre_dec4, sp} leaving loc $1 cal ".cuf8"
|
|
|
|
pat loc loc cfi $1==4 && ($2==2 || $2==4)
|
|
leaving loc $1 loc $2 cal ".cfi" asp 8-$2
|
|
|
|
pat loc loc cfi $1==8 && ($2==2 || $2==4)
|
|
leaving loc $1 loc $2 cal ".cfi" asp 12-$2
|
|
|
|
pat loc loc cfu $1==4 && ($2==2 || $2==4)
|
|
leaving loc $1 loc $2 cal ".cfu" asp 8-$2
|
|
pat loc loc cfu $1==8 && ($2==2 || $2==4)
|
|
leaving loc $1 loc $2 cal ".cfu" asp 12-$2
|
|
#else
|
|
pat loc loc cif $1==4 && $2==4 leaving loc 4 cal ".cif4" asp 4
|
|
pat loc loc cif $1==4 && $2==8 leaving loc 4 cal ".cif8"
|
|
pat loc loc cuf $1==4 && $2==4 leaving loc 4 cal ".cuf4" asp 4
|
|
pat loc loc cuf $1==4 && $2==8 leaving loc 4 cal ".cuf8"
|
|
pat loc loc cfi leaving loc $1 loc $2 cal ".cfi" asp $1+4
|
|
pat loc loc cfu leaving loc $1 loc $2 cal ".cfu" asp $1+4
|
|
#endif
|
|
pat loc loc cff $1==8 && $2==4 leaving cal ".cff4" asp 4
|
|
pat loc loc cff $1==4 && $2==8
|
|
leaving zer 4 exg 4 cal ".cff8"
|
|
#endif /* TBL68881 */
|
|
|
|
/************************************************
|
|
* Group 9: logical instructions *
|
|
************************************************/
|
|
|
|
|
|
#if WORD_SIZE==2
|
|
proc log2w
|
|
with datalt4+consts4-sconsts4 DD_REG4
|
|
gen xxx* %1, %2 yields %2
|
|
with DD_REG4 datalt4+consts4-sconsts4
|
|
gen xxx* %2, %1 yields %1
|
|
with exact any4 STACK
|
|
uses reusing %1,DD_REG4=%1
|
|
gen xxx* {post_inc4, sp}, %a yields %a
|
|
#endif
|
|
|
|
proc logw
|
|
with datalt_int+consts-sconsts DD_REG
|
|
gen xxx* %1, %2 yields %2
|
|
with DD_REG datalt_int+consts-sconsts
|
|
gen xxx* %2, %1 yields %1
|
|
with exact any_int STACK
|
|
uses reusing %1,DD_REG=%1
|
|
gen xxx* {post_inc_int, sp}, %a yields %a
|
|
|
|
proc log8 example and
|
|
with exact data4 data4 DD_REG4 DD_REG4
|
|
gen xxx* %1, %3
|
|
xxx* %2, %4 yields %4 %3
|
|
with DD_REG4 DD_REG4 data4 data4
|
|
gen xxx* %3, %1
|
|
xxx* %4, %2 yields %2 %1
|
|
with DD_REG4 DD_REG4 STACK
|
|
gen xxx* {post_inc4, sp}, %1
|
|
xxx* {post_inc4, sp}, %2 yields %2 %1
|
|
|
|
proc logdef example and
|
|
with STACK
|
|
uses DD_REG4 = {const, $1/WORD_SIZE -1},
|
|
AA_REG,
|
|
DD_REG
|
|
gen
|
|
lea {regAcon, sp, $1}, %b
|
|
1:
|
|
move_i {post_inc_int, sp}, %c
|
|
xxx* %c, {post_inc_int, %b}
|
|
dbf %a, {slabel, 1b}
|
|
|
|
#if WORD_SIZE==4
|
|
proc logndef
|
|
with DD_REG4 STACK
|
|
uses AA_REG,
|
|
DD_REG
|
|
gen
|
|
lea {regAregXcon, sp, %1, 1, 0},%a
|
|
asr_l {small_const, 2}, %1
|
|
1:
|
|
move_i {post_inc_int, sp}, %b
|
|
xxx* %b, {post_inc_int, %a}
|
|
sub_l {const4,1}, %1
|
|
bne {slabel, 1b}
|
|
#else
|
|
proc logndef
|
|
with any_int STACK
|
|
uses AA_REG,
|
|
DD_REG,
|
|
DD_REG4={const,0}
|
|
gen
|
|
move %1, %c.1
|
|
lea {regAregXcon, sp, %c, 1, 0},%a
|
|
asr_l {small_const, 1}, %c
|
|
sub_l {const4,1}, %c
|
|
1:
|
|
move_i {post_inc_int, sp}, %b
|
|
xxx* %b, {post_inc_int, %a}
|
|
dbf %c, {slabel, 1b}
|
|
#endif
|
|
|
|
proc logbdef example and
|
|
with STACK
|
|
uses AA_REG,
|
|
DD_REG,
|
|
DD_REG4
|
|
gen
|
|
move_l {const4,$1/WORD_SIZE}, %c
|
|
lea {regAregXcon, sp, %c, 1, 0},%a
|
|
1:
|
|
move_i {post_inc_int, sp}, %b
|
|
xxx* %b, {post_inc_int, %a}
|
|
sub_l {const4,1}, %c
|
|
bne {slabel, 1b}
|
|
|
|
pat and $1==WORD_SIZE call logw(AND_I)
|
|
#if WORD_SIZE==2
|
|
pat and $1==2*WORD_SIZE call log2w("and.l")
|
|
#endif
|
|
pat and $1==8 call log8("and.l")
|
|
pat and $1>4 && $1/WORD_SIZE<=65536 call logdef(AND_I)
|
|
pat and defined($1) call logbdef(AND_I)
|
|
pat and !defined($1) call logndef(AND_I)
|
|
|
|
pat ior $1==WORD_SIZE call logw(OR_I)
|
|
#if WORD_SIZE==2
|
|
pat ior $1==2*WORD_SIZE call log2w("or.l")
|
|
#endif
|
|
pat ior $1==8 call log8("or.l")
|
|
pat ior $1>2 && $1/WORD_SIZE<=65536 call logdef(OR_I)
|
|
pat ior defined($1) call logbdef(OR_I)
|
|
pat ior !defined($1) call logndef(OR_I)
|
|
|
|
#if WORD_SIZE==2
|
|
pat xor $1==2
|
|
with DD_REG conreg2-bconst
|
|
gen eor_w %2, %1 yields %1
|
|
#endif
|
|
|
|
pat xor $1==4
|
|
with DD_REG4 conreg4-bconst4
|
|
gen eor_l %2, %1 yields %1
|
|
|
|
pat xor $1==8
|
|
with exact any4 any4 DD_REG4 DD_REG4
|
|
uses reusing %1, DD_REG4 = %1
|
|
gen eor_l %a, %3
|
|
move %2, %a
|
|
eor_l %a, %4 yields %4 %3
|
|
with DD_REG4 DD_REG4 D_REG4 any4
|
|
gen eor_l %3, %1
|
|
move %4, %3
|
|
eor_l %3, %2 yields %2 %1
|
|
with DD_REG4 DD_REG4 DD_REG4 STACK
|
|
gen eor_l %3, %1
|
|
move_l {post_inc4, sp}, %3
|
|
eor_l %3, %2 yields %2 %1
|
|
|
|
pat xor $1>4 && $1/WORD_SIZE<=65536 call logdef(EOR_I)
|
|
pat xor defined($1) call logbdef(EOR_I)
|
|
pat xor !defined($1) call logndef(EOR_I)
|
|
|
|
#if WORD_SIZE==2
|
|
pat com $1==2
|
|
with DD_REG
|
|
gen not_w %1 yields %1
|
|
#endif
|
|
|
|
pat com $1==4
|
|
with DD_REG4
|
|
gen not_l %1 yields %1
|
|
|
|
pat com $1==8
|
|
with DD_REG4 DD_REG4
|
|
gen not_l %1
|
|
not_l %2 yields %2 %1
|
|
|
|
pat com $1>8 && $1/WORD_SIZE<=65536
|
|
with STACK
|
|
uses AA_REG,
|
|
DD_REG4 = {const, $1/WORD_SIZE -1}
|
|
gen move_l sp, %a
|
|
1:
|
|
not_i {post_inc_int, %a}
|
|
dbf %b, {slabel, 1b}
|
|
|
|
pat com defined($1)
|
|
with STACK
|
|
uses AA_REG,
|
|
DD_REG4 = {const, $1/WORD_SIZE}
|
|
gen move_l sp, %a
|
|
1:
|
|
not_i {post_inc_int, %a}
|
|
sub_l {const4, 1}, %b
|
|
bne {slabel, 1b}
|
|
|
|
#if WORD_SIZE==4
|
|
pat com !defined($1)
|
|
with DD_REG STACK
|
|
uses AA_REG
|
|
gen move_l sp, %a
|
|
asr_l {small_const, 2}, %1
|
|
1:
|
|
not_i {post_inc_int, %a}
|
|
sub_l {const4, 1}, %1
|
|
bne {slabel, 1b}
|
|
#else
|
|
pat com !defined($1)
|
|
with any_int STACK
|
|
uses AA_REG,
|
|
DD_REG4={const,0}
|
|
gen move %1, %b.1
|
|
move_l sp, %a
|
|
asr_l {small_const, 1}, %b
|
|
sub_l {const4, 1}, %b
|
|
1:
|
|
not_i {post_inc_int, %a}
|
|
dbf %b, {slabel, 1b}
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
pat rol $1==2
|
|
with shconreg DD_REG
|
|
gen rol_w %1, %2 yields %2
|
|
#endif
|
|
|
|
pat rol $1==4
|
|
with shconreg DD_REG4
|
|
gen rol_l %1, %2 yields %2
|
|
|
|
pat rol $1==8
|
|
with DD_REG4 DD_REG4 DD_REG4
|
|
uses AA_REG, AA_REG /* no 4th DD_REG */
|
|
gen bclr {const, 5}, %1
|
|
beq {slabel, 1f}
|
|
exg %2, %3 /* rotate left 32 */
|
|
1:
|
|
move %2, %a
|
|
move %3, %b
|
|
lsl_l %1, %2
|
|
lsl_l %1, %3
|
|
bset {const, 5}, %1
|
|
neg_l %1 /* (32 - shift) modulo 64 */
|
|
exg %a, %2
|
|
lsr_l %1, %2
|
|
or_l %2, %3 /* rotate bits from %2 to %3 */
|
|
move %a, %2
|
|
exg %b, %3
|
|
lsr_l %1, %3
|
|
or_l %3, %2 /* rotate bits from %3 to %2 */
|
|
move %b, %3
|
|
yields %3 %2
|
|
|
|
pat loc rol ($1&32)==0 && $2==8
|
|
with DD_REG4 DD_REG4
|
|
uses AA_REG, AA_REG, DD_REG = {bconst, $1&31}
|
|
gen move %1, %a
|
|
move %2, %b
|
|
lsl_l %c, %1
|
|
lsl_l %c, %2
|
|
bset {const, 5}, %c
|
|
neg_l %c
|
|
exg %a, %1
|
|
lsr_l %c, %1
|
|
or_l %1, %2
|
|
move %a, %1
|
|
exg %b, %2
|
|
lsr_l %c, %2
|
|
or_l %2, %1
|
|
move %b, %2
|
|
yields %2 %1
|
|
pat loc rol ($1&63)==32 && $2==8 leaving exg 4
|
|
pat loc rol ($1&32)!=0 && $2==8 leaving loc (0-$1)&31 ror 8
|
|
|
|
#if WORD_SIZE==2
|
|
pat ror $1==2
|
|
with shconreg DD_REG
|
|
gen ror_w %1, %2 yields %2
|
|
#endif
|
|
|
|
pat ror $1==4
|
|
with shconreg DD_REG4
|
|
gen ror_l %1, %2 yields %2
|
|
|
|
pat ror $1==8
|
|
with DD_REG4 DD_REG4 DD_REG4
|
|
uses AA_REG, AA_REG /* no 4th DD_REG */
|
|
gen bclr {const, 5}, %1
|
|
beq {slabel, 1f}
|
|
exg %2, %3 /* rotate right 32 */
|
|
1:
|
|
move %2, %a
|
|
move %3, %b
|
|
lsr_l %1, %2
|
|
lsr_l %1, %3
|
|
bset {const, 5}, %1
|
|
neg_l %1 /* (32 - shift) modulo 64 */
|
|
exg %a, %2
|
|
lsl_l %1, %2
|
|
or_l %2, %3 /* rotate bits from %2 to %3 */
|
|
move %a, %2
|
|
exg %b, %3
|
|
lsl_l %1, %3
|
|
or_l %3, %2 /* rotate bits from %3 to %2 */
|
|
move %b, %3
|
|
yields %3 %2
|
|
|
|
pat loc ror ($1&32)==0 && $2==8
|
|
with DD_REG4 DD_REG4
|
|
uses AA_REG, AA_REG, DD_REG = {bconst, $1&31}
|
|
gen move %1, %a
|
|
move %2, %b
|
|
lsr_l %c, %1
|
|
lsr_l %c, %2
|
|
bset {const, 5}, %c
|
|
neg_l %c
|
|
exg %a, %1
|
|
lsl_l %c, %1
|
|
or_l %1, %2
|
|
move %a, %1
|
|
exg %b, %2
|
|
lsl_l %c, %2
|
|
or_l %2, %1
|
|
move %b, %2
|
|
yields %2 %1
|
|
pat loc ror ($1&63)==32 && $2==8 leaving exg 4
|
|
pat loc ror ($1&32)!=0 && $2==8 leaving loc (0-$1)&31 rol 8
|
|
|
|
|
|
|
|
|
|
/************************************************
|
|
* Group 10: sets *
|
|
************************************************/
|
|
|
|
#if WORD_SIZE==2
|
|
pat inn $1==4
|
|
with conreg2 DD_REG4
|
|
gen btst %1, %2.1
|
|
sne {dreg1, %2.1}
|
|
and_l {const4, 1}, %2
|
|
yields %2.1
|
|
#endif
|
|
|
|
pat inn $1==WORD_SIZE
|
|
with conreg2 DD_REG
|
|
gen btst %1, %2
|
|
sne {dreg1, %2}
|
|
and_i {const, 1}, %2
|
|
yields %2
|
|
|
|
/* The interface for the .inn differ for m68k2 and m68k4. */
|
|
/* ??? Work out a cleaner interface, that is similar for all tables */
|
|
#if WORD_SIZE==2
|
|
pat inn defined($1)
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".inn"}
|
|
killreg d0
|
|
yields d0
|
|
|
|
pat inn !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".inn"}
|
|
killreg d0
|
|
yields d0
|
|
#else
|
|
pat inn defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
move {const, $1}, d1
|
|
jsr {absolute4, ".inn"}
|
|
killreg d0
|
|
yields d0
|
|
|
|
pat inn !defined($1)
|
|
with any_int any_int STACK
|
|
kills ALL
|
|
gen move %2, d0
|
|
move %1, d1
|
|
jsr {absolute4, ".inn"}
|
|
killreg d0
|
|
yields d0
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
pat loc inn $2==WORD_SIZE && small($1)
|
|
with DD_REG
|
|
gen asr_i {small_const, $1}, %1
|
|
and_i {const, 1}, %1
|
|
yields %1
|
|
|
|
#if WORD_SIZE==2
|
|
pat set $1==2
|
|
with conreg2
|
|
uses DD_REG = {zero_const, 0}
|
|
gen bset %1, %a yields %a
|
|
#else
|
|
|
|
pat set $1==4
|
|
with conreg2
|
|
uses DD_REG4 = {zero_const4, 0}
|
|
gen bset %1, %a yields %a
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
pat set $1>2
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".set"}
|
|
|
|
pat set !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".set"}
|
|
#else
|
|
pat set $1>4
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
move {const, $1}, d1
|
|
jsr {absolute4, ".set"}
|
|
|
|
pat set !defined($1)
|
|
with any_int any_int STACK
|
|
kills ALL
|
|
gen move %2, d0
|
|
move %1, d1
|
|
jsr {absolute4, ".set"}
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
|
|
|
|
|
|
/************************************************
|
|
* Group 11: arrays *
|
|
************************************************/
|
|
|
|
/* ??? interface */
|
|
#if WORD_SIZE==2
|
|
pat lar defined($1) && $1 == WORD_SIZE
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".lar"}
|
|
|
|
pat sar defined($1) && $1 == WORD_SIZE
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".sar"}
|
|
|
|
pat aar defined($1) && $1 == WORD_SIZE
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".aar"}
|
|
#else
|
|
pat lar defined($1)
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".lar"}
|
|
|
|
pat lar !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".lar"}
|
|
|
|
pat sar defined($1)
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".sar"}
|
|
|
|
pat sar !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".sar"}
|
|
|
|
pat aar defined($1)
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".aar"}
|
|
yields a0
|
|
|
|
pat aar !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".aar"}
|
|
yields a0
|
|
|
|
#if ARR_OPT
|
|
pat lae lar $2==4 && nicesize(rom($1,3))
|
|
leaving lae $1 aar 4 loi rom($1, 3)
|
|
pat lae sar $2==4 && nicesize(rom($1,3))
|
|
leaving lae $1 aar 4 sti rom($1, 3)
|
|
|
|
pat lae aar $2==4 && rom($1,3)==1
|
|
leaving ads 4 adp 0-rom($1,1)
|
|
|
|
#ifdef TBL68020
|
|
pat lae aar $2==4 && nicesize(rom($1,3))
|
|
with D_REG yields {regX, rom($1,3), %1}
|
|
leaving ads 4 adp rom($1,3)*(0-rom($1,1))
|
|
#else /* TBL68020 */
|
|
pat lae aar $2==4 && rom($1,3)==2
|
|
with DD_REG
|
|
gen asl_l {small_const, 1}, %1
|
|
yields %1
|
|
leaving ads 4 adp (0 - rom($1,1))<<1
|
|
|
|
pat lae aar $2==4 && rom($1,3)==4
|
|
with DD_REG
|
|
gen asl_l {small_const, 2}, %1
|
|
yields %1
|
|
leaving ads 4 adp (0 - rom($1,1))<<2
|
|
|
|
pat lae aar $2==4 && rom($1,3)==8
|
|
with DD_REG
|
|
gen asl_l {small_const, 3}, %1
|
|
yields %1
|
|
leaving ads 4 adp (0 - rom($1,1))<<3
|
|
#endif /* TBL68020 */
|
|
#endif /* ARR_OPT */
|
|
#endif /* WORD_SIZE!=2 */
|
|
|
|
/* I WOULD ALSO LIKE THESE:
|
|
* pat lae aar $2==4 && defined(rom($1,3))
|
|
* with const leaving adp rom($1,3)*(%1.num-rom($1,1))
|
|
* pat lae lar $2==4 && defined(rom($1,3))
|
|
* with const leaving adp rom($1,3)*(%1.num-rom($1,1))
|
|
* loi rom($1,3)
|
|
* pat lae sar $2==4 && defined(rom($1,3))
|
|
* with const leaving adp rom($1,3)*(%1.num-rom($1,1))
|
|
* sti rom($1,3)
|
|
* BUT THEY DON'T WORK.
|
|
*/
|
|
|
|
|
|
|
|
/************************************************
|
|
* Group 12: compare instructions *
|
|
************************************************/
|
|
|
|
|
|
#if WORD_SIZE==2
|
|
pat cmi defined($1) && $1==2
|
|
with any2 DD_REG
|
|
uses DD_REG = {zero_const, 0}
|
|
gen cmp_w %1,%2
|
|
beq {slabel,2f}
|
|
bgt {slabel,1f}
|
|
add_w {small_const, 1},%a
|
|
bra {slabel,2f}
|
|
1:
|
|
sub_w {small_const, 1},%a
|
|
2:
|
|
yields %a
|
|
|
|
pat cmi defined($1) && $1==4
|
|
with STACK
|
|
gen jsr {absolute4, ".cmi"} yields d1
|
|
#else
|
|
/* pat cmi $1==4 leaving sbi 4
|
|
WRONG !!
|
|
*/
|
|
|
|
pat cmi defined($1)
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".cmi"}
|
|
yields d0
|
|
|
|
pat cmi !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".cmi"}
|
|
yields d0
|
|
#endif
|
|
|
|
/* pat cmu $1==4 leaving sbi 4
|
|
WRONG !!
|
|
*/
|
|
|
|
#if WORD_SIZE==2
|
|
pat cmu defined($1)
|
|
with STACK
|
|
gen move {const, $1},d0
|
|
jsr {absolute4, ".cmu"}
|
|
|
|
pat cmu !defined($1)
|
|
with any STACK
|
|
gen move %1,d0
|
|
jsr {absolute4, ".cmu"}
|
|
#else
|
|
pat cmu defined($1)
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".cmu"}
|
|
yields d0
|
|
|
|
pat cmu !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".cmu"}
|
|
yields d0
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
#if WORD_SIZE==2
|
|
pat cms $1==2 leaving cmi 2
|
|
pat cms $1==4 leaving cmi 4
|
|
#else
|
|
pat cms $1==4 leaving cmi 4
|
|
#endif
|
|
|
|
pat cms defined($1)
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".cms"}
|
|
yields d0
|
|
|
|
pat cms !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".cms"}
|
|
yields d0
|
|
|
|
pat cmp leaving cmu 4
|
|
|
|
#ifndef XXXXX
|
|
proc txx
|
|
with test_set_int
|
|
uses reusing %1,DD_REG
|
|
gen test %1
|
|
bxx[1] {slabel,1f}
|
|
clr_i %a
|
|
bra {slabel,2f}
|
|
1:
|
|
move_i {small_const,1},%a
|
|
2:
|
|
yields %a
|
|
#if WORD_SIZE==2
|
|
with test_set1
|
|
#else
|
|
with test_set1 + test_set2
|
|
#endif
|
|
uses reusing %1,DD_REG
|
|
gen test %1
|
|
bxx[2] {slabel,1f}
|
|
clr_i %a
|
|
bra {slabel,2f}
|
|
1:
|
|
move_i {small_const,1},%a
|
|
2:
|
|
yields %a
|
|
|
|
/* for some branches, we need to get rid of the overflow bit first.
|
|
The easiest way to do this is to just test ....
|
|
*/
|
|
proc txx_ouch
|
|
with test_set_int
|
|
uses reusing %1,DD_REG
|
|
gen killcc.
|
|
test %1
|
|
bxx[1] {slabel,1f}
|
|
clr_i %a
|
|
bra {slabel,2f}
|
|
1:
|
|
move_i {small_const,1},%a
|
|
2:
|
|
yields %a
|
|
#if WORD_SIZE==2
|
|
with test_set1
|
|
#else
|
|
with test_set1 + test_set2
|
|
#endif
|
|
uses reusing %1,DD_REG
|
|
gen test %1
|
|
bxx[2] {slabel,1f}
|
|
clr_i %a
|
|
bra {slabel,2f}
|
|
1:
|
|
move_i {small_const,1},%a
|
|
2:
|
|
yields %a
|
|
|
|
pat tlt call txx("bmi", "bcs")
|
|
pat tle call txx_ouch("ble", "bls")
|
|
pat teq call txx("beq", "beq")
|
|
pat tne call txx("bne", "bne")
|
|
pat tge call txx("bpl", "bcc")
|
|
pat tgt call txx_ouch("bgt", "bhi")
|
|
#else
|
|
proc txx
|
|
with test_set_int
|
|
uses reusing %1,DD_REG
|
|
gen test %1
|
|
sxx[1] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
|
|
#if WORD_SIZE==2
|
|
with test_set1
|
|
#else
|
|
with test_set1 + test_set2
|
|
#endif
|
|
uses reusing %1,DD_REG
|
|
gen test %1
|
|
sxx[2] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
|
|
pat tlt call txx("smi", "scs")
|
|
pat tle call txx("sle", "sls")
|
|
pat teq call txx("seq", "seq")
|
|
pat tne call txx("sne", "sne")
|
|
pat tge call txx("spl", "scc")
|
|
pat tgt call txx("sgt", "shi")
|
|
#endif
|
|
|
|
/*
|
|
* Floating point
|
|
* Comparision
|
|
*/
|
|
#if TBL68881
|
|
pat cmf $1==4
|
|
with FS_REG FS_REG
|
|
uses D_REG={const,0}
|
|
gen fcmp %1,%2
|
|
fbeq {slabel,2f}
|
|
fblt {slabel,1f}
|
|
add_l {const,1},%a
|
|
bra {slabel,2f}
|
|
1:
|
|
sub_l {const,1},%a
|
|
2: yields %a
|
|
pat cmf $1==8
|
|
with FD_REG FD_REG
|
|
uses D_REG={const,0}
|
|
gen fcmp %1,%2
|
|
fbeq {slabel,2f}
|
|
fblt {slabel,1f}
|
|
add_l {const,1},%a
|
|
bra {slabel,2f}
|
|
1:
|
|
sub_l {const,1},%a
|
|
2: yields %a
|
|
#else
|
|
pat cmf $1==4 leaving cal ".cmf4" asp 8 lfr WORD_SIZE
|
|
pat cmf $1==8 leaving cal ".cmf8" asp 16 lfr WORD_SIZE
|
|
#endif
|
|
/*
|
|
* Floating Point
|
|
* Zero Constants
|
|
*/
|
|
pat zrf leaving zer $1
|
|
|
|
/************************************************
|
|
* Group 13: branch instructions *
|
|
************************************************/
|
|
|
|
#if WORD_SIZE==2
|
|
pat lab topeltsize($1)==4 && !fallthrough($1)
|
|
kills ALL
|
|
gen labeldef $1 yields dl0
|
|
|
|
pat lab topeltsize($1)==4 && fallthrough($1)
|
|
with any4 STACK
|
|
kills ALL
|
|
gen move %1, dl0
|
|
killreg dl0
|
|
labeldef $1 yields dl0
|
|
#endif
|
|
|
|
pat lab topeltsize($1)==WORD_SIZE && !fallthrough($1)
|
|
kills ALL
|
|
gen labeldef $1 yields d0
|
|
|
|
pat lab topeltsize($1)==WORD_SIZE && fallthrough($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1,d0
|
|
killreg d0
|
|
labeldef $1 yields d0
|
|
|
|
pat lab
|
|
with STACK
|
|
kills ALL
|
|
gen labeldef $1
|
|
|
|
#if WORD_SIZE==2
|
|
pat bra topeltsize($1)==4
|
|
with any4 STACK
|
|
gen move %1,dl0
|
|
bra {llabel, $1}
|
|
#endif
|
|
|
|
pat bra topeltsize($1)==WORD_SIZE
|
|
with any_int STACK
|
|
gen move %1,d0
|
|
bra {llabel, $1}
|
|
|
|
pat bra
|
|
with STACK
|
|
gen bra {llabel, $1}
|
|
|
|
proc brxx example beq
|
|
with exact extend1 extend1
|
|
kills ALL
|
|
gen cmp_b %1,%2
|
|
bxx[1] {llabel, $1}
|
|
#if WORD_SIZE!=2
|
|
with exact extend2 extend2
|
|
kills ALL
|
|
gen cmp_w %1,%2
|
|
bxx[1] {llabel, $1}
|
|
#endif
|
|
with exact sconsts any_int
|
|
kills ALL
|
|
uses DD_REG=%1
|
|
gen cmp_i %2, %a
|
|
bxx[2] {llabel, $1}
|
|
with exact any_int sconsts
|
|
kills ALL
|
|
uses DD_REG=%2
|
|
gen cmp_i %1, %a
|
|
bxx[1] {llabel, $1}
|
|
with any_int-sconsts genreg STACK
|
|
gen cmp_i %1, %2
|
|
bxx[1] {llabel, $1}
|
|
with genreg any_int-sconsts STACK
|
|
gen cmp_i %2, %1
|
|
bxx[2] {llabel, $1}
|
|
with exact immediate_int-sconsts imm_cmp_int
|
|
kills ALL
|
|
gen cmp_i %1, %2
|
|
bxx[1] {llabel, $1}
|
|
with exact imm_cmp_int immediate_int-sconsts
|
|
kills ALL
|
|
gen cmp_i %2, %1
|
|
bxx[2] {llabel, $1}
|
|
with exact immediate_int-sconsts STACK
|
|
gen cmp_i %1, {post_inc_int, sp}
|
|
bxx[1] {llabel, $1}
|
|
with exact any_int STACK
|
|
uses reusing %1,DD_REG=%1
|
|
gen cmp_i {post_inc_int, sp}, %a
|
|
bxx[2] {llabel, $1}
|
|
with exact STACK
|
|
uses DD_REG
|
|
gen move_i {post_inc_int, sp},%a
|
|
cmp_i {post_inc_int, sp},%a
|
|
bxx[2] {llabel, $1}
|
|
#if WORD_SIZE==4
|
|
with exact post_inc4 post_inc4
|
|
gen cmp_l %1,%2
|
|
bxx[1] {llabel, $1}
|
|
#endif
|
|
with exact post_inc2 post_inc2
|
|
gen cmp_w %1,%2
|
|
bxx[1] {llabel, $1}
|
|
with exact post_inc1 post_inc1
|
|
gen cmp_b %1,%2
|
|
bxx[1] {llabel, $1}
|
|
|
|
pat blt call brxx("blt","bgt")
|
|
pat ble call brxx("ble","bge")
|
|
pat beq call brxx("beq","beq")
|
|
pat bne call brxx("bne","bne")
|
|
pat bge call brxx("bge","ble")
|
|
pat bgt call brxx("bgt","blt")
|
|
|
|
proc zxx example zeq
|
|
with test_set_int STACK
|
|
gen test %1
|
|
bxx[1] {llabel, $1}
|
|
#if WORD_SIZE==2
|
|
with test_set1 STACK
|
|
#else
|
|
with test_set1 + test_set2 STACK
|
|
#endif
|
|
gen test %1
|
|
bxx[2] {llabel, $1}
|
|
with exact STACK
|
|
gen tst_i {post_inc_int, sp}
|
|
bxx[1] {llabel, $1}
|
|
|
|
/* for some branches, we need to get rid of the overflow bit first.
|
|
The easiest way to do this is to just test ....
|
|
*/
|
|
proc zxx_ouch example zeq
|
|
with test_set_int STACK
|
|
gen killcc.
|
|
test %1
|
|
bxx[1] {llabel, $1}
|
|
#if WORD_SIZE==2
|
|
with test_set1 STACK
|
|
#else
|
|
with test_set1 + test_set2 STACK
|
|
#endif
|
|
gen test %1
|
|
bxx[2] {llabel, $1}
|
|
with exact STACK
|
|
gen tst_i {post_inc_int, sp}
|
|
bxx[1] {llabel, $1}
|
|
|
|
pat zlt call zxx("bmi", "bcs")
|
|
pat zle call zxx_ouch("ble", "bls")
|
|
pat zeq call zxx("beq", "beq")
|
|
pat zne call zxx("bne", "bne")
|
|
pat zge call zxx("bpl", "bcc")
|
|
pat zgt call zxx_ouch("bgt", "bhi")
|
|
|
|
/************************************************
|
|
* Group 14: procedure calls instructions *
|
|
************************************************/
|
|
|
|
|
|
pat cai
|
|
with exact ext_addr
|
|
kills ALL
|
|
gen jsr {absolute4, %1.bd}
|
|
with A_REG STACK
|
|
kills ALL
|
|
gen jsr {indirect4, %1}
|
|
with STACK
|
|
kills ALL
|
|
uses AA_REG = {post_inc4, sp}
|
|
gen jsr {indirect4, %a}
|
|
with address STACK
|
|
kills ALL
|
|
gen jsr %1
|
|
|
|
pat cal
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, $1}
|
|
|
|
#if WORD_SIZE==2
|
|
pat lfr $1==2 yields d0
|
|
pat lfr $1==4 yields dl0
|
|
pat lfr $1==8 yields dl1 dl0
|
|
#else
|
|
pat lfr $1==4 yields d0
|
|
pat lfr $1==8 yields d1 d0
|
|
#endif
|
|
|
|
pat ret $1==0
|
|
gen return
|
|
|
|
pat asp ret $2==0
|
|
gen return
|
|
|
|
#if WORD_SIZE==2
|
|
pat ret $1==2
|
|
with any2
|
|
gen move %1, d0
|
|
return
|
|
with exact STACK
|
|
gen move_w {post_inc2, sp}, d0
|
|
return
|
|
#endif
|
|
|
|
pat ret $1==4
|
|
with any4
|
|
gen move %1, dl0
|
|
return
|
|
with exact STACK
|
|
gen move_l {post_inc4, sp}, dl0
|
|
return
|
|
|
|
pat ret $1==8
|
|
with any4 any4
|
|
gen move %1, dl0
|
|
move %2, dl1
|
|
return
|
|
with exact any4 STACK
|
|
gen move %1, dl0
|
|
move_l {post_inc4, sp}, dl1
|
|
return
|
|
with exact STACK
|
|
gen move_l {post_inc4, sp}, dl0
|
|
move_l {post_inc4, sp}, dl1
|
|
return
|
|
|
|
|
|
/************************************************
|
|
* Group 15: miscellaneous instructions *
|
|
************************************************/
|
|
|
|
#if WORD_SIZE==2
|
|
pat asp $1==2
|
|
with any2-pre_post
|
|
with STACK
|
|
gen add_l {const4, $1}, sp
|
|
#endif
|
|
|
|
pat asp $1==4
|
|
#if WORD_SIZE==2
|
|
with any-pre_post any-pre_post
|
|
#endif
|
|
with any4-pre_post
|
|
with STACK
|
|
gen add_l {const4, $1}, sp
|
|
|
|
#if WORD_SIZE==2
|
|
pat asp $1==6
|
|
with any4-pre_post any-pre_post
|
|
with any-pre_post any4-pre_post
|
|
with any-pre_post any-pre_post any-pre_post
|
|
with STACK
|
|
gen add_l {const4, $1}, sp
|
|
#endif
|
|
|
|
pat asp $1==8
|
|
with any4-pre_post any4-pre_post
|
|
with STACK
|
|
gen add_l {const4, $1}, sp
|
|
|
|
pat asp
|
|
with STACK
|
|
gen lea {regAcon, sp, $1}, sp
|
|
|
|
/* ??? DD_REG$ ??? */
|
|
#if WORD_SIZE==2
|
|
pat ass $1==2
|
|
with any2 STACK
|
|
uses reusing %1,DD_REG4
|
|
gen move %1,%a.1
|
|
ext_l %a.1
|
|
add_l %a, sp
|
|
#endif
|
|
|
|
pat ass $1==4
|
|
with any4 STACK
|
|
gen add_l %1, sp
|
|
|
|
#if WORD_SIZE==2
|
|
pat blm $1==2
|
|
with A_REG A_REG
|
|
kills allexceptcon
|
|
gen move_w {indirect2, %2}, {indirect2, %1}
|
|
#endif
|
|
|
|
pat blm $1==4
|
|
with A_REG A_REG
|
|
kills allexceptcon
|
|
gen move_l {indirect4, %2}, {indirect4, %1}
|
|
|
|
#if WORD_SIZE==2
|
|
pat blm $1==6
|
|
with A_REG A_REG
|
|
kills allexceptcon
|
|
gen move_l {indirect4, %2}, {indirect4, %1}
|
|
move_w {offsetted2, %2, 4}, {offsetted2, %1, 4}
|
|
#endif
|
|
|
|
pat blm $1==8
|
|
with A_REG A_REG
|
|
kills allexceptcon
|
|
gen move_l {indirect4, %2}, {indirect4, %1}
|
|
move_l {offsetted4, %2, 4}, {offsetted4, %1, 4}
|
|
|
|
pat blm $1>2*WORD_SIZE && $1/WORD_SIZE <= 65536
|
|
with AA_REG AA_REG
|
|
kills ALL
|
|
uses DD_REG4={const, $1/WORD_SIZE -1}
|
|
gen 1:
|
|
move_i {post_inc_int, %2}, {post_inc_int, %1}
|
|
dbf %a, {slabel, 1b}
|
|
|
|
pat blm
|
|
with AA_REG AA_REG
|
|
kills ALL
|
|
uses DD_REG4={const,$1/WORD_SIZE}
|
|
gen 1:
|
|
move_i {post_inc_int, %2}, {post_inc_int, %1}
|
|
sub_l {const4, 1}, %a
|
|
bne {slabel, 1b}
|
|
|
|
#if WORD_SIZE==2
|
|
pat bls $1==2
|
|
with DD_REG AA_REG AA_REG
|
|
kills ALL
|
|
gen asr_w {small_const, 1}, %1
|
|
beq {slabel, 2f}
|
|
1:
|
|
move_w {post_inc2, %3}, {post_inc2, %2}
|
|
sub_w {const, 1}, %1
|
|
bne {slabel, 1b}
|
|
2:
|
|
#endif
|
|
|
|
pat bls $1==4
|
|
with DD_REG4 AA_REG AA_REG
|
|
kills ALL
|
|
gen
|
|
#if WORD_SIZE==2
|
|
asr_l {small_const, 1}, %1
|
|
#else
|
|
asr_l {small_const, 2}, %1
|
|
#endif
|
|
beq {slabel, 2f}
|
|
1:
|
|
move_i {post_inc_int, %3}, {post_inc_int, %2}
|
|
sub_l {const4, 1}, %1
|
|
bne {slabel, 1b}
|
|
2:
|
|
|
|
#if WORD_SIZE==2
|
|
pat csa $1==2
|
|
#if TBL68020
|
|
with any4 D_REG+LOCAL+const+ILOCAL+absolute2 STACK
|
|
#else
|
|
with any4 D_REG+LOCAL+const+absolute2 STACK
|
|
#endif
|
|
gen move %1,a0
|
|
move %2,d0
|
|
jmp {absolute4, ".csa2"}
|
|
#endif
|
|
|
|
pat csa $1==4
|
|
#if TBL68020 && WORD_SIZE==4
|
|
with any4 D_REG4+DLOCAL+const4+ILOCAL+absolute4 STACK
|
|
#else
|
|
with any4 D_REG4+DLOCAL+const4+absolute4 STACK
|
|
#endif
|
|
gen move %1,a0
|
|
move %2,dl0
|
|
jmp {absolute4, ".csa4"}
|
|
|
|
pat csa $1==8
|
|
with any4 STACK
|
|
gen move %1,a0
|
|
jmp {absolute4, ".csa8"}
|
|
|
|
#if WORD_SIZE==2
|
|
pat csb $1==2
|
|
#if TBL68020
|
|
with any4 D_REG+LOCAL+const+ILOCAL+absolute2 STACK
|
|
#else
|
|
with any4 D_REG+LOCAL+const+absolute2 STACK
|
|
#endif
|
|
gen move %1,a0
|
|
move %2,d0
|
|
jmp {absolute4, ".csb2"}
|
|
#endif
|
|
|
|
pat csb $1==4
|
|
#if TBL68020 && WORD_SIZE==4
|
|
with any4 D_REG4+DLOCAL+const4+ILOCAL+absolute4 STACK
|
|
#else
|
|
with any4 D_REG4+DLOCAL+const4+absolute4 STACK
|
|
#endif
|
|
gen move %1,a0
|
|
move %2,dl0
|
|
jmp {absolute4, ".csb4"}
|
|
|
|
pat csb $1==8
|
|
with any4 STACK
|
|
gen move %1,a0
|
|
jmp {absolute4, ".csb8"}
|
|
|
|
pat dch leaving loi 4
|
|
|
|
#if WORD_SIZE==2
|
|
pat dup $1==2
|
|
with dups2 yields %1 %1
|
|
#endif
|
|
|
|
pat dup $1==4
|
|
#if WORD_SIZE==2
|
|
with dups2 dups2 yields %2 %1 %2 %1
|
|
#endif
|
|
with dups4 yields %1 %1
|
|
|
|
pat dup $1==8
|
|
with dups4 dups4 yields %2 %1 %2 %1
|
|
|
|
pat dup $1>2*WORD_SIZE && $1/WORD_SIZE<=65536
|
|
with STACK
|
|
uses DD_REG4 = {const, $1/WORD_SIZE -1}
|
|
gen 1:
|
|
move_i {offsetted_int, sp, $1 -WORD_SIZE}, {pre_dec_int, sp}
|
|
dbf %a, {slabel, 1b}
|
|
|
|
pat dup
|
|
with STACK
|
|
uses DD_REG4 = {const, $1/WORD_SIZE}
|
|
gen 1:
|
|
move_i {offsetted_int, sp, $1 -WORD_SIZE}, {pre_dec_int, sp}
|
|
sub_l {const4, 1}, %a
|
|
bne {slabel, 1b}
|
|
|
|
#if WORD_SIZE==2
|
|
pat dus $1==2
|
|
with any2 STACK
|
|
uses DD_REG4 = {zero_const4, 0}, AA_REG
|
|
gen
|
|
move_w %1, %a.1
|
|
lea {regAregXcon, sp, %a, 1, 0}, %b
|
|
asr_l {small_const, 1}, %a
|
|
beq {slabel, 2f}
|
|
1:
|
|
move_w {pre_dec2, %b}, {pre_dec2, sp}
|
|
sub_l {const4, 1}, %a
|
|
bne {slabel, 1b}
|
|
2:
|
|
#endif
|
|
|
|
pat dus $1==4
|
|
with DD_REG4 STACK
|
|
uses AA_REG
|
|
gen
|
|
lea {regAregXcon, sp, %1, 1, 0}, %a
|
|
#if WORD_SIZE==2
|
|
asr_l {small_const, 1}, %1
|
|
#else
|
|
asr_l {small_const, 2}, %1
|
|
#endif
|
|
beq {slabel, 2f}
|
|
1:
|
|
move_i {pre_dec_int, %a}, {pre_dec_int, sp}
|
|
sub_l {const4, 1}, %1
|
|
bne {slabel, 1b}
|
|
2:
|
|
|
|
#if WORD_SIZE==2
|
|
pat exg $1==2
|
|
with any2 any2 yields %1 %2
|
|
#endif
|
|
|
|
pat exg $1==4
|
|
with any4 any4 yields %1 %2
|
|
|
|
pat exg defined($1)
|
|
with STACK
|
|
kills ALL
|
|
gen move {const, $1}, d0
|
|
jsr {absolute4, ".exg"}
|
|
|
|
pat exg !defined($1)
|
|
with any_int STACK
|
|
kills ALL
|
|
gen move %1, d0
|
|
jsr {absolute4, ".exg"}
|
|
|
|
pat fil
|
|
gen move_l {ext_addr, $1}, {absolute4, "hol0+4"}
|
|
|
|
pat gto
|
|
with STACK
|
|
uses AA_REG = {ext_addr, $1}
|
|
gen move_l {offsetted4, %a, 8}, lb
|
|
move_l {offsetted4, %a, 4}, sp
|
|
#if TBL68020 && FANCY_MODES
|
|
jmp {OFF_off4, %a, 0, 0}
|
|
#else
|
|
move_l {indirect4, %a}, %a
|
|
jmp {indirect4, %a}
|
|
#endif
|
|
|
|
pat lim yields {absolute_int, ".ignmask"}
|
|
|
|
pat lin
|
|
kills posextern
|
|
gen move_i {const, $1}, {absolute_int, "hol0"}
|
|
|
|
pat lni
|
|
kills posextern
|
|
gen add_i {const, 1}, {absolute_int, "hol0"}
|
|
|
|
pat lor $1==0 yields lb
|
|
|
|
pat lor $1==1
|
|
with STACK
|
|
uses AA_REG = sp yields %a
|
|
|
|
pat lor $1==2 yields {absolute4, ".reghp"}
|
|
|
|
pat lpb leaving adp 8
|
|
|
|
pat mon
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".mon"}
|
|
|
|
pat nop
|
|
with STACK
|
|
kills ALL
|
|
#ifdef DEBUG
|
|
gen jsr {absolute4, ".nop"}
|
|
#endif
|
|
|
|
#if WORD_SIZE==2
|
|
pat rck $1==2
|
|
#ifdef TBL68020
|
|
with ext_addr D_REG
|
|
gen cmp2_w {absolute2, %1.bd}, %2
|
|
bcc {slabel, 1f}
|
|
move_w {small_const, 1}, {pre_dec2, sp} /* push constant 1 == ERANGE */
|
|
jsr {absolute4, ".trp"}
|
|
1: yields %2
|
|
with address-ext_addr D_REG
|
|
gen cmp2_w %1, %2
|
|
bcc {slabel, 1f}
|
|
move_w {small_const, 1}, {pre_dec2, sp} /* push constant 1 == ERANGE */
|
|
jsr {absolute4, ".trp"}
|
|
1: yields %2
|
|
with A_REG D_REG
|
|
gen cmp2_w {indirect2, %1}, %2
|
|
bcc {slabel, 1f}
|
|
move_w {small_const, 1}, {pre_dec2, sp} /* push constant 1 == ERANGE */
|
|
jsr {absolute4, ".trp"}
|
|
1: yields %2
|
|
#else
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".rck"}
|
|
#endif
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
#if WORD_SIZE==4 || TBL68020
|
|
pat rck $1==4
|
|
#ifdef TBL68020
|
|
with ext_addr D_REG4
|
|
gen cmp2_l {absolute4, %1.bd}, %2
|
|
bcc {slabel, 1f}
|
|
pea {absolute4, 1} /* push constant 1 == ERANGE */
|
|
jsr {absolute4, ".trp"}
|
|
1: yields %2
|
|
with address-ext_addr D_REG4
|
|
gen cmp2_l %1, %2
|
|
bcc {slabel, 1f}
|
|
pea {absolute4, 1} /* push constant 1 == ERANGE */
|
|
jsr {absolute4, ".trp"}
|
|
1: yields %2
|
|
with A_REG D_REG4
|
|
gen cmp2_l {indirect4, %1}, %2
|
|
bcc {slabel, 1f}
|
|
pea {absolute4, 1} /* push constant 1 == ERANGE */
|
|
jsr {absolute4, ".trp"}
|
|
1: yields %2
|
|
#else /* TBL68020 */
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".rck"}
|
|
#endif /* TBL68020 */
|
|
#endif /* WORD_SIZE==4 || TBL68020 */
|
|
|
|
pat rtt leaving ret 0
|
|
|
|
pat sig
|
|
with any4
|
|
kills posextern
|
|
uses AA_REG
|
|
gen move_l {absolute4, ".trppc"}, %a
|
|
move_l %1, {absolute4, ".trppc"}
|
|
yields %a
|
|
|
|
pat sim
|
|
with any_int
|
|
kills posextern
|
|
gen move_i %1, {absolute_int, ".ignmask"}
|
|
|
|
pat str $1==0
|
|
with any4 STACK
|
|
kills ALL
|
|
gen move_l %1, lb
|
|
|
|
pat str $1==1
|
|
with any4 STACK
|
|
gen move_l %1, sp
|
|
|
|
pat str $1==2
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".strhp"}
|
|
|
|
pat trp
|
|
with STACK
|
|
kills ALL
|
|
gen jsr {absolute4, ".trp"}
|
|
|
|
|
|
|
|
/************************************************
|
|
* more rules for long EM-patterns *
|
|
************************************************/
|
|
|
|
pat loe ine $1==$2
|
|
kills posextern
|
|
uses DD_REG = {absolute_int, $1}
|
|
gen add_i {const,1}, {absolute_int, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
pat loe dee $1==$2
|
|
kills posextern
|
|
uses DD_REG = {absolute_int, $1}
|
|
gen sub_i {const,1}, {absolute_int, $1}
|
|
killreg %a
|
|
yields %a
|
|
|
|
|
|
proc llol1shstl example lol loc sli stl /* only left */
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen shw* {offsetted2, lb, $1+2}
|
|
roxl {offsetted2, lb, $1}
|
|
|
|
proc lloe1shste example loe loc sli ste /* only left */
|
|
kills posextern
|
|
gen shw* {absolute2, $1+2}
|
|
roxl {absolute2, $1}
|
|
|
|
proc llil1shsil example lil loc sli sil /* only left */
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen shw* {OFF_off2, lb, $1, 2}
|
|
roxl {OFF_off2, lb, $1, 0}
|
|
#else
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen shw* {offsetted2, %a, 2}
|
|
roxl {indirect2, %a}
|
|
#endif
|
|
|
|
proc rlol1shstl example lol loc sri stl /* only right */
|
|
kills all_indir, DLOCAL %bd==$1
|
|
gen shw* {offsetted2, lb, $1}
|
|
roxr {offsetted2, lb, $1+2}
|
|
|
|
proc rloe1shste example loe loc sri ste /* only right */
|
|
kills posextern
|
|
gen shw* {absolute2, $1}
|
|
roxr {absolute2, $1+2}
|
|
|
|
proc rlil1shsil example lil loc sri sil /* only right */
|
|
kills allexceptcon
|
|
#if TBL68020 && FANCY_MODES
|
|
gen shw* {OFF_off2, lb, $1, 0}
|
|
roxr {OFF_off2, lb, $1, 2}
|
|
#else
|
|
uses AA_REG = {DLOCAL, $1}
|
|
gen shw* {indirect2, %a}
|
|
roxr {offsetted2, %a, 2}
|
|
#endif
|
|
|
|
pat lol loc sli stl $1==$4 && $2==1 && $3==4 call llol1shstl("asl #1,")
|
|
pat loe loc sli ste $1==$4 && $2==1 && $3==4 call lloe1shste("asl #1,")
|
|
pat lil loc sli sil $1==$4 && $2==1 && $3==4 call llil1shsil("asl #1,")
|
|
pat lol loc sri stl $1==$4 && $2==1 && $3==4 call rlol1shstl("asr #1,")
|
|
pat loe loc sri ste $1==$4 && $2==1 && $3==4 call rloe1shste("asr #1,")
|
|
pat lil loc sri sil $1==$4 && $2==1 && $3==4 call rlil1shsil("asr #1,")
|
|
pat lol loc slu stl $1==$4 && $2==1 && $3==4 call llol1shstl("asl #1,")
|
|
pat loe loc slu ste $1==$4 && $2==1 && $3==4 call lloe1shste("asl #1,")
|
|
pat lil loc slu sil $1==$4 && $2==1 && $3==4 call llil1shsil("asl #1,")
|
|
pat lol loc sru stl $1==$4 && $2==1 && $3==4 call rlol1shstl("lsr #1,")
|
|
pat loe loc sru ste $1==$4 && $2==1 && $3==4 call rloe1shste("lsr #1,")
|
|
pat lil loc sru sil $1==$4 && $2==1 && $3==4 call rlil1shsil("lsr #1,")
|
|
|
|
|
|
proc txxand
|
|
with test_set_int DD_REG
|
|
gen test %1
|
|
bxx[1] {slabel, 1f}
|
|
bclr {const,0}, %2
|
|
1: yields %2
|
|
#if WORD_SIZE==2
|
|
with test_set1 DD_REG
|
|
#else
|
|
with test_set1 + test_set2 DD_REG
|
|
#endif
|
|
gen test %1
|
|
bxx[2] {slabel, 1f}
|
|
bclr {const,0}, %2
|
|
1: yields %2
|
|
|
|
proc txxior
|
|
with test_set_int DD_REG
|
|
gen test %1
|
|
bxx[1] {slabel, 1f}
|
|
bset {zero_const, 0}, %2
|
|
1: yields %2
|
|
#if WORD_SIZE==2
|
|
with test_set1 DD_REG
|
|
#else
|
|
with test_set1 + test_set2 DD_REG
|
|
#endif
|
|
gen test %1
|
|
bxx[2] {slabel, 1f}
|
|
bset {zero_const, 0}, %2
|
|
1: yields %2
|
|
|
|
proc txxand_ouch
|
|
with test_set_int DD_REG
|
|
gen killcc.
|
|
test %1
|
|
bxx[1] {slabel, 1f}
|
|
bclr {const,0}, %2
|
|
1: yields %2
|
|
#if WORD_SIZE==2
|
|
with test_set1 DD_REG
|
|
#else
|
|
with test_set1 + test_set2 DD_REG
|
|
#endif
|
|
gen test %1
|
|
bxx[2] {slabel, 1f}
|
|
bclr {const,0}, %2
|
|
1: yields %2
|
|
|
|
proc txxior_ouch
|
|
with test_set_int DD_REG
|
|
gen killcc.
|
|
test %1
|
|
bxx[1] {slabel, 1f}
|
|
bset {zero_const, 0}, %2
|
|
1: yields %2
|
|
#if WORD_SIZE==2
|
|
with test_set1 DD_REG
|
|
#else
|
|
with test_set1 + test_set2 DD_REG
|
|
#endif
|
|
gen test %1
|
|
bxx[2] {slabel, 1f}
|
|
bset {zero_const, 0}, %2
|
|
1: yields %2
|
|
|
|
pat tlt and $2==WORD_SIZE call txxand("bmi", "bcs")
|
|
pat tle and $2==WORD_SIZE call txxand_ouch("ble", "bls")
|
|
pat teq and $2==WORD_SIZE call txxand("beq", "beq")
|
|
pat tne and $2==WORD_SIZE call txxand("bne", "bne")
|
|
pat tge and $2==WORD_SIZE call txxand("bpl", "bcc")
|
|
pat tgt and $2==WORD_SIZE call txxand_ouch("bgt", "bhi")
|
|
|
|
pat tlt ior $2==WORD_SIZE call txxior("bpl", "bcc")
|
|
pat tle ior $2==WORD_SIZE call txxior_ouch("bgt", "bhi")
|
|
pat teq ior $2==WORD_SIZE call txxior("bne", "bne")
|
|
pat tne ior $2==WORD_SIZE call txxior("beq", "beq")
|
|
pat tge ior $2==WORD_SIZE call txxior("bmi", "bcs")
|
|
pat tgt ior $2==WORD_SIZE call txxior_ouch("ble", "bls")
|
|
|
|
proc cmxtxxand
|
|
with exact extend1 extend1 DD_REG
|
|
gen cmp_b %2, %1
|
|
bxx[2] {llabel,1f}
|
|
bclr {const,0}, %3
|
|
1: yields %3
|
|
with exact extend2 extend2 DD_REG
|
|
gen cmp_w %2, %1
|
|
bxx[2] {llabel,1f}
|
|
bclr {const,0}, %3
|
|
1: yields %3
|
|
with exact sconsts any_int DD_REG
|
|
uses DD_REG=%1
|
|
gen cmp_i %2, %a
|
|
bxx[2] {slabel, 1f}
|
|
bclr {const,0}, %3
|
|
1: yields %3
|
|
with exact any_int sconsts DD_REG
|
|
uses DD_REG=%2
|
|
gen cmp_i %1, %a
|
|
bxx[1] {slabel, 1f}
|
|
bclr {const,0}, %3
|
|
1: yields %3
|
|
with any_int-sconsts genreg DD_REG
|
|
gen cmp_i %1, %2
|
|
bxx[1] {slabel, 1f}
|
|
bclr {const,0}, %3
|
|
1: yields %3
|
|
with genreg any_int-sconsts DD_REG
|
|
gen cmp_i %2, %1
|
|
bxx[2] {slabel, 1f}
|
|
bclr {const,0}, %3
|
|
1: yields %3
|
|
with exact immediate_int-sconsts imm_cmp_int DD_REG
|
|
gen cmp_i %1, %2
|
|
bxx[1] {slabel, 1f}
|
|
bclr {const,0}, %3
|
|
1: yields %3
|
|
with exact imm_cmp_int immediate_int-sconsts DD_REG
|
|
gen cmp_i %2, %1
|
|
bxx[2] {slabel, 1f}
|
|
bclr {const,0}, %3
|
|
1: yields %3
|
|
|
|
proc cmxtxxior
|
|
with exact extend1 extend1 DD_REG
|
|
gen cmp_b %2, %1
|
|
bxx[2] {llabel,1f}
|
|
bset {zero_const, 0}, %3
|
|
1: yields %3
|
|
with exact extend2 extend2 DD_REG
|
|
gen cmp_w %2, %1
|
|
bxx[2] {llabel,1f}
|
|
bset {zero_const, 0}, %3
|
|
1: yields %3
|
|
with exact sconsts any_int DD_REG
|
|
uses DD_REG=%1
|
|
gen cmp_i %2, %a
|
|
bxx[2] {slabel, 1f}
|
|
bset {zero_const, 0}, %3
|
|
1: yields %3
|
|
with exact any_int sconsts DD_REG
|
|
uses DD_REG=%2
|
|
gen cmp_i %1, %a
|
|
bxx[1] {slabel, 1f}
|
|
bset {zero_const, 0}, %3
|
|
1: yields %3
|
|
with any_int-sconsts genreg DD_REG
|
|
gen cmp_i %1, %2
|
|
bxx[1] {slabel, 1f}
|
|
bset {zero_const, 0}, %3
|
|
1: yields %3
|
|
with genreg any_int-sconsts DD_REG
|
|
gen cmp_i %2, %1
|
|
bxx[2] {slabel, 1f}
|
|
bset {zero_const, 0}, %3
|
|
1: yields %3
|
|
with exact immediate_int-sconsts imm_cmp_int DD_REG
|
|
gen cmp_i %1, %2
|
|
bxx[1] {slabel, 1f}
|
|
bset {zero_const, 0}, %3
|
|
1: yields %3
|
|
with exact imm_cmp_int immediate_int-sconsts DD_REG
|
|
gen cmp_i %2, %1
|
|
bxx[2] {slabel, 1f}
|
|
bset {zero_const, 0}, %3
|
|
1: yields %3
|
|
|
|
proc cmxtxx
|
|
with exact sconsts any_int
|
|
uses DD_REG=%1
|
|
gen cmp_i %2, %a
|
|
sxx[2] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with exact any_int sconsts
|
|
uses DD_REG=%2
|
|
gen cmp_i %1, %a
|
|
sxx[1] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with any_int-sconsts genreg
|
|
uses reusing %1,reusing %2,DD_REG
|
|
gen cmp_i %1, %2
|
|
sxx[1] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with genreg any_int-sconsts
|
|
uses reusing %1,reusing %2,DD_REG
|
|
gen cmp_i %2, %1
|
|
sxx[2] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with exact extend1 extend1
|
|
uses reusing %1,reusing %2,DD_REG
|
|
gen cmp_b %2, %1
|
|
sxx[2] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with exact extend2 extend2
|
|
uses reusing %1,reusing %2,DD_REG
|
|
gen cmp_w %2, %1
|
|
sxx[2] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with exact immediate_int-sconsts imm_cmp_int
|
|
uses reusing %2,DD_REG
|
|
gen cmp_i %1, %2
|
|
sxx[1] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with exact imm_cmp_int immediate_int-sconsts
|
|
uses reusing %1,DD_REG
|
|
gen cmp_i %2, %1
|
|
sxx[2] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with exact immediate_int-sconsts STACK
|
|
uses DD_REG
|
|
gen cmp_i %1, {post_inc_int, sp}
|
|
sxx[1] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with exact any_int STACK
|
|
uses reusing %1,DD_REG=%1
|
|
gen cmp_i {post_inc_int, sp}, %a
|
|
sxx[2] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
with exact STACK
|
|
uses DD_REG
|
|
gen move_i {post_inc_int, sp},%a
|
|
cmp_i {post_inc_int, sp},%a
|
|
sxx[2] %a
|
|
neg_b %a
|
|
yields {extend1, %a}
|
|
|
|
pat cmi tlt and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("blt","bgt")
|
|
pat cmi tle and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("ble","bge")
|
|
pat cmi teq and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("beq","beq")
|
|
pat cmi tne and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("bne","bne")
|
|
pat cmi tge and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("bge","ble")
|
|
pat cmi tgt and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("bgt","blt")
|
|
|
|
pat cmu tlt and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("bcs","bhi")
|
|
pat cmu tle and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("bls","bcc")
|
|
pat cmu teq and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("beq","beq")
|
|
pat cmu tne and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("bne","bne")
|
|
pat cmu tge and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("bcc","bls")
|
|
pat cmu tgt and $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxand("bhi","bcs")
|
|
|
|
pat cmi tlt ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("bge","ble")
|
|
pat cmi tle ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("bgt","blt")
|
|
pat cmi teq ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("bne","bne")
|
|
pat cmi tne ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("beq","beq")
|
|
pat cmi tge ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("blt","bgt")
|
|
pat cmi tgt ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("ble","bge")
|
|
|
|
pat cmu tlt ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("bcc","bls")
|
|
pat cmu tle ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("bhi","bcs")
|
|
pat cmu teq ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("bne","bne")
|
|
pat cmu tne ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("beq","beq")
|
|
pat cmu tge ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("bcs","bhi")
|
|
pat cmu tgt ior $1==WORD_SIZE && $3==WORD_SIZE call cmxtxxior("bls","bcc")
|
|
|
|
pat cmi tlt $1==WORD_SIZE call cmxtxx("slt","sgt")
|
|
pat cmi tle $1==WORD_SIZE call cmxtxx("sle","sge")
|
|
pat cmi teq $1==WORD_SIZE call cmxtxx("seq","seq")
|
|
pat cmi tne $1==WORD_SIZE call cmxtxx("sne","sne")
|
|
pat cmi tge $1==WORD_SIZE call cmxtxx("sge","sle")
|
|
pat cmi tgt $1==WORD_SIZE call cmxtxx("sgt","slt")
|
|
|
|
pat cmu tlt $1==WORD_SIZE call cmxtxx("scs","shi")
|
|
pat cmu tle $1==WORD_SIZE call cmxtxx("sls","scc")
|
|
pat cmu teq $1==WORD_SIZE call cmxtxx("seq","seq")
|
|
pat cmu tne $1==WORD_SIZE call cmxtxx("sne","sne")
|
|
pat cmu tge $1==WORD_SIZE call cmxtxx("scc","sls")
|
|
pat cmu tgt $1==WORD_SIZE call cmxtxx("shi","scs")
|
|
|
|
|
|
proc cmuzxx example cmu zlt
|
|
with exact sconsts any_int
|
|
kills ALL
|
|
uses DD_REG=%1
|
|
gen cmp_i %2, %a
|
|
bxx[2] {llabel, $2}
|
|
with exact any_int sconsts
|
|
kills ALL
|
|
uses DD_REG=%2
|
|
gen cmp_i %1, %a
|
|
bxx[1] {llabel, $2}
|
|
with any_int-sconsts genreg STACK
|
|
gen cmp_i %1, %2
|
|
bxx[1] {llabel, $2}
|
|
with genreg any_int-sconsts STACK
|
|
gen cmp_i %2, %1
|
|
bxx[2] {llabel, $2}
|
|
with exact immediate_int-sconsts imm_cmp_int
|
|
kills ALL
|
|
gen cmp_i %1, %2
|
|
bxx[1] {llabel, $2}
|
|
with exact imm_cmp_int immediate_int-sconsts
|
|
kills ALL
|
|
gen cmp_i %2, %1
|
|
bxx[2] {llabel, $2}
|
|
with exact immediate_int-sconsts STACK
|
|
gen cmp_i %1, {post_inc_int, sp}
|
|
bxx[1] {llabel, $2}
|
|
with exact any_int STACK
|
|
uses reusing %1, DD_REG=%1
|
|
gen cmp_i {post_inc_int, sp}, %a
|
|
bxx[2] {llabel, $2}
|
|
with exact STACK
|
|
uses DD_REG
|
|
gen move_i {post_inc_int, sp},%a
|
|
cmp_i {post_inc_int, sp},%a
|
|
bxx[2] {llabel, $2}
|
|
with data2-sconsts dreg2 STACK
|
|
gen cmp_w %1, %2
|
|
bxx[1] {llabel, $2}
|
|
with dreg2 data2-conreg2-sconsts STACK
|
|
gen cmp_w %2, %1
|
|
bxx[2] {llabel, $2}
|
|
with data1 dreg1 STACK
|
|
gen cmp_b %1, %2
|
|
bxx[1] {llabel, $2}
|
|
with dreg1 data1-conreg1 STACK
|
|
gen cmp_b %2, %1
|
|
bxx[2] {llabel, $2}
|
|
|
|
pat cmu zlt $1==WORD_SIZE call cmuzxx("bcs","bhi")
|
|
pat cmu zle $1==WORD_SIZE call cmuzxx("bls","bcc")
|
|
pat cmu zeq $1==WORD_SIZE call cmuzxx("beq","beq")
|
|
pat cmu zne $1==WORD_SIZE call cmuzxx("bne","bne")
|
|
pat cmu zge $1==WORD_SIZE call cmuzxx("bcc","bls")
|
|
pat cmu zgt $1==WORD_SIZE call cmuzxx("bhi","bcs")
|
|
|
|
|
|
proc cmx8txx example cmi tlt
|
|
with exact DD_REG4 DD_REG4 any4 any4
|
|
uses reusing %3, DD_REG4 = %3
|
|
gen sub_l %4, %2
|
|
subx_l %a, %1 /* keep overflow flag */
|
|
sxx[2] %1
|
|
neg_b %1 yields {dreg1, %1}
|
|
with D_REG4 any4-D_REG4 DD_REG4 DD_REG4
|
|
/* only 3 of DD_REG4; may unstack %2 into AA_REG */
|
|
gen sub_l %2, %4
|
|
subx_l %1, %3
|
|
sxx[1] %3
|
|
neg_b %3 yields {dreg1, %3}
|
|
|
|
pat cmi tlt $1==8 call cmx8txx("slt","sgt")
|
|
pat cmi tle $1==8 call cmx8txx("sle","sge")
|
|
pat cmi tge $1==8 call cmx8txx("sge","sle")
|
|
pat cmi tgt $1==8 call cmx8txx("sgt","slt")
|
|
pat cms teq $1==8 call cmx8txx("seq","seq")
|
|
pat cms tne $1==8 call cmx8txx("sne","sne")
|
|
pat cmu tlt $1==8 call cmx8txx("scs","shi")
|
|
pat cmu tle $1==8 call cmx8txx("sls","scc")
|
|
pat cmu tge $1==8 call cmx8txx("scc","sls")
|
|
pat cmu tgt $1==8 call cmx8txx("shi","scs")
|
|
|
|
proc cmx8zxx example cmi zlt
|
|
with exact DD_REG4 DD_REG4 any4 any4
|
|
kills ALL
|
|
uses reusing %3, DD_REG4 = %3
|
|
gen sub_l %4, %2
|
|
subx_l %a, %1
|
|
bxx[2] {llabel, $2}
|
|
with D_REG4 any4-D_REG4 DD_REG4 DD_REG4 STACK
|
|
gen sub_l %2, %4
|
|
subx_l %1, %3
|
|
bxx[1] {llabel, $2}
|
|
|
|
pat cmi zlt $1==8 call cmx8zxx("blt","bgt")
|
|
pat cmi zle $1==8 call cmx8zxx("ble","bge")
|
|
pat cmi zge $1==8 call cmx8zxx("bge","ble")
|
|
pat cmi zgt $1==8 call cmx8zxx("bgt","blt")
|
|
pat cms zeq $1==8 call cmx8zxx("beq","beq")
|
|
pat cms zne $1==8 call cmx8zxx("bne","bne")
|
|
pat cmu zlt $1==8 call cmx8zxx("bcs","bhi")
|
|
pat cmu zle $1==8 call cmx8zxx("bls","bcc")
|
|
pat cmu zge $1==8 call cmx8zxx("bcc","bls")
|
|
pat cmu zgt $1==8 call cmx8zxx("bhi","bcs")
|
|
|
|
|
|
#if TBL68881
|
|
proc cmf4zxx example cmf zlt
|
|
with FS_REG FS_REG
|
|
gen fcmp %1,%2
|
|
bxx* {llabel, $2}
|
|
|
|
pat cmf zlt $1==4 call cmf4zxx("fblt")
|
|
pat cmf zle $1==4 call cmf4zxx("fble")
|
|
pat cmf zne $1==4 call cmf4zxx("fbne")
|
|
pat cmf zeq $1==4 call cmf4zxx("fbeq")
|
|
pat cmf zge $1==4 call cmf4zxx("fbge")
|
|
pat cmf zgt $1==4 call cmf4zxx("fbgt")
|
|
|
|
proc cmf8zxx example cmf zlt
|
|
with FD_REG FD_REG
|
|
gen fcmp %1,%2
|
|
bxx* {llabel, $2}
|
|
|
|
pat cmf zlt $1==8 call cmf8zxx("fblt")
|
|
pat cmf zle $1==8 call cmf8zxx("fble")
|
|
pat cmf zne $1==8 call cmf8zxx("fbne")
|
|
pat cmf zeq $1==8 call cmf8zxx("fbeq")
|
|
pat cmf zge $1==8 call cmf8zxx("fbge")
|
|
pat cmf zgt $1==8 call cmf8zxx("fbgt")
|
|
#endif
|
|
|
|
|
|
proc loc1locciibxx example loc loc cii bne
|
|
with any1 extend1 STACK
|
|
gen cmp_b %1,%2
|
|
bxx[1] {llabel, $4}
|
|
with any1 any_int STACK
|
|
uses reusing %1, DD_REG = %1
|
|
#if TBL68020 && WORD_SIZE==4
|
|
gen extb_l %a
|
|
#else
|
|
gen ext_w %a
|
|
#if WORD_SIZE==4
|
|
ext_l %a
|
|
#endif
|
|
#endif
|
|
cmp_i %2,%a
|
|
bxx[2] {llabel, $4}
|
|
|
|
pat loc loc cii blt $1==1 && $2==EM_WSIZE call loc1locciibxx("blt","bgt")
|
|
pat loc loc cii ble $1==1 && $2==EM_WSIZE call loc1locciibxx("ble","bge")
|
|
pat loc loc cii bne $1==1 && $2==EM_WSIZE call loc1locciibxx("bne","bne")
|
|
pat loc loc cii beq $1==1 && $2==EM_WSIZE call loc1locciibxx("beq","beq")
|
|
pat loc loc cii bge $1==1 && $2==EM_WSIZE call loc1locciibxx("bge","ble")
|
|
pat loc loc cii bgt $1==1 && $2==EM_WSIZE call loc1locciibxx("bgt","blt")
|
|
|
|
#if WORD_SIZE==4
|
|
proc loc2locciibxx example loc loc cii bne
|
|
with any2 extend2 STACK
|
|
gen cmp_w %1,%2
|
|
bxx[1] {llabel, $4}
|
|
with any2 any4 STACK
|
|
uses reusing %1, DD_REG = %1
|
|
gen ext_l %a
|
|
cmp_l %2,%a
|
|
bxx[2] {llabel, $4}
|
|
|
|
pat loc loc cii blt $1==2 && $2==EM_WSIZE call loc2locciibxx("blt","bgt")
|
|
pat loc loc cii blt $1==2 && $2==EM_WSIZE call loc2locciibxx("blt","bgt")
|
|
pat loc loc cii ble $1==2 && $2==EM_WSIZE call loc2locciibxx("ble","bge")
|
|
pat loc loc cii bne $1==2 && $2==EM_WSIZE call loc2locciibxx("bne","bne")
|
|
pat loc loc cii beq $1==2 && $2==EM_WSIZE call loc2locciibxx("beq","beq")
|
|
pat loc loc cii bge $1==2 && $2==EM_WSIZE call loc2locciibxx("bge","ble")
|
|
pat loc loc cii bgt $1==2 && $2==EM_WSIZE call loc2locciibxx("bgt","blt")
|
|
#endif
|
|
|
|
proc bxx1_in example loc loc cii loc bne
|
|
with imm_cmp1 STACK
|
|
gen cmp_b {const, low8($4)}, %1
|
|
bxx* {llabel, $5}
|
|
|
|
#if WORD_SIZE!=2
|
|
proc bxx2_in example loc loc cii loc bne
|
|
with imm_cmp2 STACK
|
|
gen cmp_w {const, loww($4)}, %1
|
|
bxx* {llabel, $5}
|
|
#endif
|
|
|
|
proc bxx1_small example loc bne
|
|
with imm_cmp1-D_REG STACK
|
|
gen cmp_b {const, $1}, %1
|
|
bxx[1] {llabel, $2}
|
|
with imm_cmp2-D_REG STACK
|
|
gen cmp_w {const, $1}, %1
|
|
bxx[1] {llabel, $2}
|
|
with data_int STACK
|
|
uses DD_REG = {small_const, $1} /* uses moveq */
|
|
gen cmp_i %1,%a
|
|
bxx[2] {llabel, $2}
|
|
|
|
#if WORD_SIZE!=2
|
|
proc bxx2_small example loc bne
|
|
with imm_cmp2-D_REG STACK
|
|
gen cmp_w {const, $1}, %1
|
|
bxx[1] {llabel, $2}
|
|
with imm_cmp4 STACK
|
|
gen cmp_l {const, $1}, %1
|
|
bxx[2] {llabel, $2}
|
|
#endif
|
|
|
|
proc zxx1_in example loc loc cii zne
|
|
with test_set1 STACK
|
|
gen test %1
|
|
bxx* {llabel, $4}
|
|
with D_REG STACK
|
|
gen test {dreg1, %1}
|
|
bxx* {llabel, $4}
|
|
|
|
#if WORD_SIZE!=2
|
|
proc zxx2_in example loc loc cii zne
|
|
with test_set2 STACK
|
|
gen test %1
|
|
bxx* {llabel, $4}
|
|
with D_REG STACK
|
|
gen test {dreg2, %1}
|
|
bxx* {llabel, $4}
|
|
#endif
|
|
|
|
pat loc loc cii zlt $1==1 && $2==WORD_SIZE call zxx1_in("blt")
|
|
pat loc loc cii zle $1==1 && $2==WORD_SIZE call zxx1_in("ble")
|
|
pat loc loc cii zne $1==1 && $2==WORD_SIZE call zxx1_in("bne")
|
|
pat loc loc cii zeq $1==1 && $2==WORD_SIZE call zxx1_in("beq")
|
|
pat loc loc cii zge $1==1 && $2==WORD_SIZE call zxx1_in("bge")
|
|
pat loc loc cii zgt $1==1 && $2==WORD_SIZE call zxx1_in("bgt")
|
|
|
|
#if WORD_SIZE!=2
|
|
pat loc loc cii zlt $1==2 && $2==4 call zxx2_in("blt")
|
|
pat loc loc cii zle $1==2 && $2==4 call zxx2_in("ble")
|
|
pat loc loc cii zne $1==2 && $2==4 call zxx2_in("bne")
|
|
pat loc loc cii zeq $1==2 && $2==4 call zxx2_in("beq")
|
|
pat loc loc cii zge $1==2 && $2==4 call zxx2_in("bge")
|
|
pat loc loc cii zgt $1==2 && $2==4 call zxx2_in("bgt")
|
|
#endif
|
|
|
|
pat loc loc cii loc blt $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("blt")
|
|
pat loc loc cii loc ble $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("ble")
|
|
pat loc loc cii loc beq $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("beq")
|
|
pat loc loc cii loc bne $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("bne")
|
|
pat loc loc cii loc bge $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("bge")
|
|
pat loc loc cii loc bgt $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("bgt")
|
|
|
|
#if WORD_SIZE!=2
|
|
pat loc loc cii loc blt $1==2 && $2==4 && in_2($4) call bxx2_in("blt")
|
|
pat loc loc cii loc ble $1==2 && $2==4 && in_2($4) call bxx2_in("ble")
|
|
pat loc loc cii loc beq $1==2 && $2==4 && in_2($4) call bxx2_in("beq")
|
|
pat loc loc cii loc bne $1==2 && $2==4 && in_2($4) call bxx2_in("bne")
|
|
pat loc loc cii loc bge $1==2 && $2==4 && in_2($4) call bxx2_in("bge")
|
|
pat loc loc cii loc bgt $1==2 && $2==4 && in_2($4) call bxx2_in("bgt")
|
|
#endif
|
|
|
|
/* the second instruction for bxx1_small is the other way around! */
|
|
pat loc blt $1>=0 && $1<128 call bxx1_small("bcs", "bgt")
|
|
pat loc ble $1>=0 && $1<128 call bxx1_small("bls", "bge")
|
|
pat loc beq $1>=0 && $1<128 call bxx1_small("beq", "beq")
|
|
pat loc bne $1>=0 && $1<128 call bxx1_small("bne", "bne")
|
|
pat loc bge $1>=0 && $1<128 call bxx1_small("bcc", "ble")
|
|
pat loc bgt $1>=0 && $1<128 call bxx1_small("bhi", "blt")
|
|
|
|
#if WORD_SIZE!=2
|
|
pat loc blt $1>=128 && $1<32768 call bxx2_small("bcs", "blt")
|
|
pat loc ble $1>=128 && $1<32768 call bxx2_small("bls", "ble")
|
|
pat loc beq $1>=128 && $1<32768 call bxx2_small("beq", "beq")
|
|
pat loc bne $1>=128 && $1<32768 call bxx2_small("bne", "bne")
|
|
pat loc bge $1>=128 && $1<32768 call bxx2_small("bcc", "bge")
|
|
pat loc bgt $1>=128 && $1<32768 call bxx2_small("bhi", "bgt")
|
|
#endif
|
|
|
|
|
|
pat loc loc cii lal sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
|
|
leaving lal $4 sti $5
|
|
pat loc loc cii lol sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
|
|
leaving lol $4 sti $5
|
|
pat loc loc cii lil sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
|
|
leaving lil $4 sti $5
|
|
pat loc loc cii LLP lof sti $1 <= WORD_SIZE && $1>=$6 && $2==WORD_SIZE
|
|
leaving LLP $4 lof $5 sti $6
|
|
pat loc loc cii lae sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
|
|
leaving lae $4 sti $5
|
|
pat loc loc cii loe sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
|
|
leaving loe $4 sti $5
|
|
|
|
pat loc loc cii stl $1==1 && $2==WORD_SIZE && inreg($4)==reg_any
|
|
with memory1+DD_REG
|
|
kills regvar($4, reg_any), use_index %xreg==regvar($4, reg_any)
|
|
gen move_b %1, {dreg1, regvar($4,reg_any)}
|
|
#if WORD_SIZE==2
|
|
ext_w {LOCAL,$4}
|
|
#else
|
|
#ifdef TBL68020
|
|
extb_l {LOCAL,$4}
|
|
#else /* TBL68020 */
|
|
ext_w {LOCAL,$4}
|
|
ext_l {LOCAL,$4}
|
|
#endif /* TBL68020 */
|
|
#endif
|
|
|
|
pat loc loc cii $1==2 && $2==4
|
|
#if WORD_SIZE==2
|
|
with D_REG
|
|
uses reusing %1, DD_REG4
|
|
gen move %1,%a.1 yields {extend2, %a}
|
|
with exact extend1
|
|
uses reusing %1,DD_REG4
|
|
gen move %1.reg,%a.1 yields {extend1_4, %a}
|
|
with exact memory2
|
|
uses reusing %1,DD_REG4
|
|
gen move %1, %a.1 yields {extend2, %a}
|
|
#else
|
|
with DD_REG yields {extend2, %1}
|
|
with exact memory2
|
|
uses reusing %1,DD_REG=%1
|
|
yields {extend2, %a}
|
|
#endif
|
|
|
|
pat loc loc cii $1==1 && $2==WORD_SIZE
|
|
with DD_REG yields {extend1, %1}
|
|
with exact memory1
|
|
uses reusing %1,DD_REG = %1
|
|
yields {extend1, %a}
|
|
|
|
#if WORD_SIZE==2
|
|
pat loc loc cii $1==1 && $2==4
|
|
with DD_REG
|
|
uses reusing %1, DD_REG4
|
|
gen move %1, %a.1
|
|
yields {extend1_4, %a}
|
|
with exact memory1
|
|
uses reusing %1,DD_REG4
|
|
gen move %1,%a.1 yields {extend1_4, %a}
|
|
#endif
|
|
|
|
pat loc loc ciu $1==$2 /* skip this */
|
|
pat loc loc cui $1==$2 /* skip this */
|
|
|
|
pat loc loc cii $1==4 && $2==8
|
|
with exact test_set1+test_set2
|
|
yields %1 {zero_const, 0}
|
|
with test_set4
|
|
uses DD_REG4
|
|
gen test %1
|
|
slt {dreg1, %a}
|
|
#ifdef TBL68020
|
|
extb_l %a
|
|
#else
|
|
ext_w %a
|
|
ext_l %a
|
|
#endif
|
|
yields %1 %a
|
|
|
|
pat loc loc cii $1<4 && $2==8
|
|
leaving loc $1 loc 4 cii loc 4 loc 8 cii
|
|
|
|
pat loc loc ciu $1==4 && $2==8 yields {zero_const, 0}
|
|
pat loc loc cui $1==4 && $2==8 yields {zero_const, 0}
|
|
pat loc loc cuu $1==4 && $2==8 yields {zero_const, 0}
|
|
|
|
pat loc loc cii $1==8 && $2==4 leaving asp 4
|
|
pat loc loc ciu $1==8 && $2==4 leaving asp 4
|
|
pat loc loc cui $1==8 && $2==4 leaving asp 4
|
|
pat loc loc cuu $1==8 && $2==4 leaving asp 4
|
|
|
|
|
|
/* The following rules should be handled by the peephole optimizer, I think */
|
|
|
|
#if WORD_SIZE==2
|
|
pat ldc dvu highw($1)==0 && loww($1)==2 && $2==4 leaving loc 1 sru 4
|
|
pat ldc dvu highw($1)==0 && loww($1)==4 && $2==4 leaving loc 2 sru 4
|
|
pat ldc dvu highw($1)==0 && loww($1)==8 && $2==4 leaving loc 3 sru 4
|
|
pat ldc dvu highw($1)==0 && loww($1)==16 && $2==4 leaving loc 4 sru 4
|
|
pat ldc dvu highw($1)==0 && loww($1)==32 && $2==4 leaving loc 5 sru 4
|
|
pat ldc dvu highw($1)==0 && loww($1)==64 && $2==4 leaving loc 6 sru 4
|
|
pat ldc dvu highw($1)==0 && loww($1)==128 && $2==4 leaving loc 7 sru 4
|
|
pat ldc dvu highw($1)==0 && loww($1)==256 && $2==4 leaving loc 8 sru 4
|
|
#endif
|
|
|
|
pat loc dvu $1==2 && $2==WORD_SIZE leaving loc 1 sru WORD_SIZE
|
|
pat loc dvu $1==4 && $2==WORD_SIZE leaving loc 2 sru WORD_SIZE
|
|
pat loc dvu $1==8 && $2==WORD_SIZE leaving loc 3 sru WORD_SIZE
|
|
pat loc dvu $1==16 && $2==WORD_SIZE leaving loc 4 sru WORD_SIZE
|
|
pat loc dvu $1==32 && $2==WORD_SIZE leaving loc 5 sru WORD_SIZE
|
|
pat loc dvu $1==64 && $2==WORD_SIZE leaving loc 6 sru WORD_SIZE
|
|
pat loc dvu $1==128 && $2==WORD_SIZE leaving loc 7 sru WORD_SIZE
|
|
pat loc dvu $1==256 && $2==WORD_SIZE leaving loc 8 sru WORD_SIZE
|
|
|
|
#if WORD_SIZE==2
|
|
pat ldc dvi highw($1)==0 && loww($1)==2 && $2==4
|
|
with DD_REG4
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_l {const4,loww($1)-1},%1
|
|
1: yields %1 leaving loc 1 sri 4
|
|
|
|
pat ldc dvi highw($1)==0 && loww($1)==4 && $2==4
|
|
with DD_REG4
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_l {const4,loww($1)-1},%1
|
|
1: yields %1 leaving loc 2 sri 4
|
|
|
|
pat ldc dvi highw($1)==0 && loww($1)==8 && $2==4
|
|
with DD_REG4
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_l {const4,loww($1)-1},%1
|
|
1: yields %1 leaving loc 3 sri 4
|
|
|
|
pat ldc dvi highw($1)==0 && loww($1)==16 && $2==4
|
|
with DD_REG4
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_l {const4,loww($1)-1},%1
|
|
1: yields %1 leaving loc 4 sri 4
|
|
|
|
pat ldc dvi highw($1)==0 && loww($1)==32 && $2==4
|
|
with DD_REG4
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_l {const4,loww($1)-1},%1
|
|
1: yields %1 leaving loc 5 sri 4
|
|
|
|
pat ldc dvi highw($1)==0 && loww($1)==64 && $2==4
|
|
with DD_REG4
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_l {const4,loww($1)-1},%1
|
|
1: yields %1 leaving loc 6 sri 4
|
|
|
|
pat ldc dvi highw($1)==0 && loww($1)==128 && $2==4
|
|
with DD_REG4
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_l {const4,loww($1)-1},%1
|
|
1: yields %1 leaving loc 7 sri 4
|
|
|
|
pat ldc dvi highw($1)==0 && loww($1)==256 && $2==4
|
|
with DD_REG4
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_l {const4,loww($1)-1},%1
|
|
1: yields %1 leaving loc 8 sri 4
|
|
#endif /* WORD_SIZE==2 */
|
|
|
|
pat loc dvi $1==2 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_i {const,$1-1},%1
|
|
1: yields %1 leaving loc 1 sri WORD_SIZE
|
|
|
|
pat loc dvi $1==4 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_i {const,$1-1},%1
|
|
1: yields %1 leaving loc 2 sri WORD_SIZE
|
|
|
|
pat loc dvi $1==8 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_i {const,$1-1},%1
|
|
1: yields %1 leaving loc 3 sri WORD_SIZE
|
|
|
|
pat loc dvi $1==16 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_i {const,$1-1},%1
|
|
1: yields %1 leaving loc 4 sri WORD_SIZE
|
|
|
|
pat loc dvi $1==32 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_i {const,$1-1},%1
|
|
1: yields %1 leaving loc 5 sri WORD_SIZE
|
|
|
|
pat loc dvi $1==64 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_i {const,$1-1},%1
|
|
1: yields %1 leaving loc 6 sri WORD_SIZE
|
|
|
|
pat loc dvi $1==128 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_i {const,$1-1},%1
|
|
1: yields %1 leaving loc 7 sri WORD_SIZE
|
|
|
|
pat loc dvi $1==256 && $2==WORD_SIZE
|
|
with DD_REG
|
|
gen test %1
|
|
bpl {slabel,1f}
|
|
add_i {const,$1-1},%1
|
|
1: yields %1 leaving loc 8 sri WORD_SIZE
|
|
|
|
/* The rest is all 2-bytes stuff */
|
|
#if WORD_SIZE==2
|
|
pat loc loc cii $1==4 && $2==2
|
|
with D_REG4
|
|
yields %1.1
|
|
with any2-pre_post any2-pre_post
|
|
yields %2
|
|
|
|
proc cmqtxx
|
|
with exact sconsts4 any4
|
|
uses DD_REG4=%1
|
|
gen cmp_l %2, %a
|
|
s4xx[2] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with exact any4 sconsts4
|
|
uses DD_REG4=%2
|
|
gen cmp_l %1, %a
|
|
s4xx[1] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with any4-sconsts4 genreg4
|
|
uses reusing %1,reusing %2,DD_REG4
|
|
gen cmp_l %1, %2
|
|
s4xx[1] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with genreg4 any4-sconsts4
|
|
uses reusing %1,reusing %2,DD_REG4
|
|
gen cmp_l %2, %1
|
|
s4xx[2] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with exact extend1_4 extend1_4
|
|
uses reusing %1,reusing %2,DD_REG4
|
|
gen cmp_b %2, %1
|
|
s4xx[2] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with exact extend2 extend2
|
|
uses reusing %1,reusing %2,DD_REG4
|
|
gen cmp_w %2, %1
|
|
s4xx[2] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with exact immediate4-sconsts4 imm_cmp4
|
|
uses reusing %2,DD_REG4
|
|
gen cmp_l %1, %2
|
|
s4xx[1] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with exact imm_cmp4 immediate4-sconsts4
|
|
uses reusing %1,DD_REG4
|
|
gen cmp_l %2, %1
|
|
s4xx[2] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with exact immediate4-sconsts4 STACK
|
|
uses DD_REG4
|
|
gen cmp_l %1, {post_inc4, sp}
|
|
s4xx[1] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with exact any4 STACK
|
|
uses reusing %1,DD_REG4=%1
|
|
gen cmp_l {post_inc4, sp}, %a
|
|
s4xx[2] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
with exact STACK
|
|
uses DD_REG4
|
|
gen move_l {post_inc4, sp},%a
|
|
cmp_l {post_inc4, sp},%a
|
|
s4xx[2] %a
|
|
neg_b %a.1
|
|
yields {extend1, %a.1}
|
|
|
|
pat cmi tlt $1==4 call cmqtxx("slt","sgt")
|
|
pat cmi tle $1==4 call cmqtxx("sle","sge")
|
|
pat cmi teq $1==4 call cmqtxx("seq","seq")
|
|
pat cmi tne $1==4 call cmqtxx("sne","sne")
|
|
pat cmi tge $1==4 call cmqtxx("sge","sle")
|
|
pat cmi tgt $1==4 call cmqtxx("sgt","slt")
|
|
|
|
pat cmu tlt $1==4 call cmqtxx("scs","shi")
|
|
pat cmu tle $1==4 call cmqtxx("sls","scc")
|
|
pat cmu teq $1==4 call cmqtxx("seq","seq")
|
|
pat cmu tne $1==4 call cmqtxx("sne","sne")
|
|
pat cmu tge $1==4 call cmqtxx("scc","sls")
|
|
pat cmu tgt $1==4 call cmqtxx("shi","scs")
|
|
|
|
|
|
proc cmqzxx example cmu zlt
|
|
with zero_const4 test_set4 STACK
|
|
/* kills ALL */
|
|
gen test %2
|
|
bxx[1] {llabel, $2}
|
|
with exact sconsts4-zero_const4 any4
|
|
kills ALL
|
|
uses DD_REG4=%1
|
|
gen cmp_l %2, %a
|
|
bxx[2] {llabel, $2}
|
|
with exact any4 sconsts4
|
|
kills ALL
|
|
uses DD_REG4=%2
|
|
gen cmp_l %1, %a
|
|
bxx[1] {llabel, $2}
|
|
with any4-sconsts4-zero_const4 genreg4 STACK
|
|
gen cmp_l %1, %2
|
|
bxx[1] {llabel, $2}
|
|
with genreg4 any4-sconsts4-zero_const4 STACK
|
|
gen cmp_l %2, %1
|
|
bxx[2] {llabel, $2}
|
|
with exact immediate4-sconsts4-zero_const4 imm_cmp4
|
|
kills ALL
|
|
gen cmp_l %1, %2
|
|
bxx[1] {llabel, $2}
|
|
with exact imm_cmp4 immediate4-sconsts4-zero_const4
|
|
kills ALL
|
|
gen cmp_l %2, %1
|
|
bxx[2] {llabel, $2}
|
|
with exact immediate4-sconsts4-zero_const4 STACK
|
|
gen cmp_l %1, {post_inc4, sp}
|
|
bxx[1] {llabel, $2}
|
|
with exact any4 STACK
|
|
uses reusing %1, DD_REG4=%1
|
|
gen cmp_l {post_inc4, sp}, %a
|
|
bxx[2] {llabel, $2}
|
|
with exact STACK
|
|
uses DD_REG4
|
|
gen move_l {post_inc4, sp},%a
|
|
cmp_l {post_inc4, sp},%a
|
|
bxx[2] {llabel, $2}
|
|
with data2-sconsts dreg2 STACK
|
|
gen cmp_w %1, %2
|
|
bxx[1] {llabel, $2}
|
|
with dreg2 data2-conreg2-sconsts STACK
|
|
gen cmp_w %2, %1
|
|
bxx[2] {llabel, $2}
|
|
with data1 dreg1 STACK
|
|
gen cmp_b %1, %2
|
|
bxx[1] {llabel, $2}
|
|
with dreg1 data1-conreg1 STACK
|
|
gen cmp_b %2, %1
|
|
bxx[2] {llabel, $2}
|
|
|
|
pat cmi zlt $1==4 call cmqzxx("blt","bgt")
|
|
pat cmi zle $1==4 call cmqzxx("ble","bge")
|
|
pat cmi zeq $1==4 call cmqzxx("beq","beq")
|
|
pat cmi zne $1==4 call cmqzxx("bne","bne")
|
|
pat cmi zge $1==4 call cmqzxx("bge","ble")
|
|
pat cmi zgt $1==4 call cmqzxx("bgt","blt")
|
|
|
|
pat cms zeq $1==4 call cmqzxx("beq","beq")
|
|
pat cms zne $1==4 call cmqzxx("bne","bne")
|
|
|
|
pat cmu zlt $1==4 call cmqzxx("bcs","bhi")
|
|
pat cmu zle $1==4 call cmqzxx("bls","bcc")
|
|
pat cmu zeq $1==4 call cmqzxx("beq","beq")
|
|
pat cmu zne $1==4 call cmqzxx("bne","bne")
|
|
pat cmu zge $1==4 call cmqzxx("bcc","bls")
|
|
pat cmu zgt $1==4 call cmqzxx("bhi","bcs")
|
|
|
|
pat ldc cms zeq loww($1)==0 && highw($1)==0 && $2==4
|
|
with test_set4 STACK
|
|
gen test %1
|
|
beq {llabel, $3}
|
|
|
|
pat ldc cms zne loww($1)==0 && highw($1)==0 && $2==4
|
|
with test_set4 STACK
|
|
gen test %1
|
|
bne {llabel, $3}
|
|
#endif
|