6943 lines
194 KiB
Plaintext
6943 lines
194 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
|
|
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
|
|
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
|
|
/* 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_REG: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
|
|
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).
|
|
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).
|
|
/* 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).
|
|
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
|
|
|
|
#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
|
|
|
|
#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
|
|
|
|
#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 */
|
|
|
|
#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 */
|
|
|
|
#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
|
|
|
|
#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
|
|
|
|
#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
|
|
|
|
/************************************************
|
|
* 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 */
|
|
|
|
#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 */
|
|
|
|
#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 */
|
|
|
|
pat slu leaving sli $1
|
|
|
|
#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
|
|
|
|
/************************************************
|
|
* 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 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>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>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>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
|
|
|
|
#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
|
|
|
|
|
|
|
|
|
|
/************************************************
|
|
* 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"}
|
|
|
|
#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 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, ".filn"}
|
|
|
|
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, ".trpim"}
|
|
|
|
pat lin
|
|
kills posextern
|
|
gen move_i {const, $1}, {absolute_int, ".lino"}
|
|
|
|
pat lni
|
|
kills posextern
|
|
gen add_i {const, 1}, {absolute_int, ".lino"}
|
|
|
|
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, ".trpim"}
|
|
|
|
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")
|
|
|
|
|
|
#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 */
|
|
|
|
|
|
/* 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
|