"$Header$" /* * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands. * * This product is part of the Amsterdam Compiler Kit. * * Permission to use, sell, duplicate or disclose this software must be * obtained in writing. Requests for such permissions may be sent to * * Dr. Andrew S. Tanenbaum * Wiskundig Seminarium * Vrije Universiteit * Postbox 7161 * 1007 MC Amsterdam * The Netherlands * */ /*********************************************************************** ***** ***** ***** 6 8 0 0 0 B A C K E N D T A B L E S ***** ***** ***** ***********************************************************************/ /* * INTEGER SIZE: 16 bits * POINTER SIZE: 32 bits */ #define REGVARS EM_WSIZE = 2 EM_PSIZE = 4 EM_BSIZE = 8 /*************************** ** R E G I S T E R S ** ***************************/ REGISTERS: D0 = ("d0",2) DATAREG. D1 = ("d1",2) DATAREG. D2 = ("d2",2) DATAREG. /* Note: the order of the registers is important: it is used by * the .gto routine in the tail_em library. */ #ifdef REGVARS D7 = ("d7",2) regvar, DATAREG. D6 = ("d6",2) regvar, DATAREG. D5 = ("d5",2) regvar, DATAREG. D4 = ("d4",2) regvar, DATAREG. D3 = ("d3",2) regvar, DATAREG. #else D3 = ("d3",2) DATAREG. D4 = ("d4",2) DATAREG. D5 = ("d5",2) DATAREG. D6 = ("d6",2) DATAREG. D7 = ("d7",2) DATAREG. #endif #ifndef REGVARS DD7 = ("d7",4,D7) DATAREG4. DD6 = ("d6",4,D6) DATAREG4. DD5 = ("d5",4,D5) DATAREG4. DD4 = ("d4",4,D4) DATAREG4. DD3 = ("d3",4,D3) DATAREG4. #endif DD2 = ("d2",4,D2) DATAREG4. DD1 = ("d1",4,D1) DATAREG4. DD0 = ("d0",4,D0) DATAREG4. A0 = ("a0",4) ADDREG. A1 = ("a1",4) ADDREG. #ifdef REGVARS A5 = ("a5",4) regvar(pointer), ADDREG. A4 = ("a4",4) regvar(pointer), ADDREG. A3 = ("a3",4) regvar(pointer), ADDREG. A2 = ("a2",4) regvar(pointer), ADDREG. #else A2 = ("a2",4) ADDREG. A3 = ("a3",4) ADDREG. A4 = ("a4",4) ADDREG. A5 = ("a5",4) ADDREG. #endif LB = ("a6",4) LOCALBASE. /***************** ** T O K E N S ** *****************/ TOKENS: IADDREG = {REGISTER reg;} 2 cost=(0,2) "(%[reg])" /* indirect address reg. */ IADDREG1 = {REGISTER reg;} 2 cost=(0,2) "(%[reg])" DISPL = {REGISTER reg; INT dis;} 2 cost=(2,4) "%[dis](%[reg])" /* displacement */ DISPL1 = {REGISTER reg; INT dis;} 2 cost=(2,4) "%[dis](%[reg])" INDEXED = {REGISTER reg,ireg; INT di;} 2 cost=(2,5) "%[di](%[reg],%[ireg].w)" ABS = {STRING addr;} 2 cost=(3,5) "%[addr]" ABS1 = {STRING addr;} 2 cost=(3,5) "%[addr]" IMMEDIATE = {INT cc;} 2 cost=(1,2) "#%[cc]" LOCAL_ADDR = {INT off;} 4 /* not really addressable */ REGOFF_ADDR = {REGISTER reg; INT off;} 4 /* not really addressable */ EXTERNAL_ADDR = {STRING off;} 4 cost=(4,4) "#%[off]" INDEX_ADDR = {REGISTER reg,ireg; INT di;} 4 IADDREG4 = {REGISTER reg;} 4 cost=(0,4) "(%[reg])" /* indirect address reg. */ DISPL4 = {REGISTER reg; INT dis;} 4 cost=(2,6) "%[dis](%[reg])" /* disisplacement */ INDEXED4 = {REGISTER reg,ireg; INT di;} 4 cost=(2,7) "%[di](%[reg],%[ireg].w)" /* The ABS addressing mode requires either 1 or 2 words of extension. * We just use the average (1.5 words=2bytes). The access time is either * 4 or 6 cycles, so we use 5. */ ABS4 = {STRING addr;} 4 cost=(3,7) "%[addr]" IMMEDIATE4 = {INT cc;} 4 cost=(4,4) "#%[cc]" DOUBLE = {STRING cc;} 4 cost=(4,4) "#%[cc]" DOUBLEZERO = { } 4 /************************************* ** T O K E N E X P R E S S I O N S ** *************************************/ TOKENEXPRESSIONS: DATA = DATAREG + IADDREG + DISPL + INDEXED + ABS + IMMEDIATE MEMORY = DATA - DATAREG CONTROL = MEMORY - IMMEDIATE ALTERABLE = DATAREG + IADDREG + DISPL + INDEXED + ABS ANY = DATA + MEMORY + CONTROL + ALTERABLE DATA_ALT = DATA * ALTERABLE ALT_MEM = ALTERABLE * MEMORY DATASCR = DATAREG * SCRATCH ADDSCR = ADDREG * SCRATCH MEM_ALL = ALL - DATAREG - DATAREG4 - ADDREG - IMMEDIATE - IMMEDIATE4 - LOCAL_ADDR -REGOFF_ADDR - EXTERNAL_ADDR - DOUBLE - DOUBLEZERO ALL_ACCESSIBLE = IADDREG + IADDREG4 + IADDREG1 + INDEXED + INDEXED4 ANY1 = DISPL1 + ABS1 + IADDREG1 DATA_ALT1 = ANY1 DATA_ALT_1OR2 = DATA_ALT + DATA_ALT1 REG4 = DATAREG4 + ADDREG DATA4 = DATAREG4 + IADDREG4 + DISPL4 + INDEXED4 + ABS4 + IMMEDIATE4 + DOUBLE MEMORY4 = DATA4 - DATAREG4 CONTROL4 = MEMORY4 - IMMEDIATE4 - DOUBLE ALTERABLE4 = DATAREG4 + ADDREG + IADDREG4 + DISPL4 + INDEXED4 + ABS4 ANY4 = DATA4 + MEMORY4 + CONTROL4 + ALTERABLE4 + LOCALBASE + EXTERNAL_ADDR DATA_ALT4 = DATA4 * ALTERABLE4 ALT_MEM4 = ALTERABLE4 * MEMORY4 DATASCR4 = DATAREG4 * SCRATCH /************* ** C O D E ** *************/ CODE: /* G R O U P I : L O A D S */ loc | | | {IMMEDIATE,$1} | | loc loc $1==0 && $2==0 | | | {DOUBLEZERO} | | ldc | | | {DOUBLE, $1} | | #ifdef REGVARS lol inreg($1)==2 | | | regvar($1) | | #endif lol | | | {DISPL,LB,$1} | | #ifdef REGVARS ldl inreg($1)==2 | | | regvar($1) | | #endif ldl | | | {DISPL4,LB,$1} | | loe | | | {ABS,$1} | | lde | | | {ABS4,$1} | | #ifdef REGVARS lil inreg($1) == 2 | | | {IADDREG, regvar($1)} | | #endif lil | | allocate(ADDREG = {DISPL4,LB,$1})| {IADDREG,%[a]} | | lof | ADDREG | | {DISPL,%[1],$1} | | ... | nocoercions: EXTERNAL_ADDR | | {ABS,%[1.off]+"+"+tostring($1)} | | ... | nocoercions: LOCAL_ADDR | | {DISPL,LB,%[1.off]+$1} | | ... | nocoercions: REGOFF_ADDR | | {DISPL,%[1.reg],%[1.off]+$1} | | ldf | ADDREG | | {DISPL4,%[1],$1} | | ... | nocoercions: EXTERNAL_ADDR | | {ABS4,%[1.off]+"+"+tostring($1)} | | ... | nocoercions: LOCAL_ADDR | | {DISPL4,LB,%[1.off]+$1} | | ... | nocoercions: REGOFF_ADDR | | {DISPL4,%[1.reg],%[1.off]+$1} | | lal | | | {LOCAL_ADDR,$1} | | | LOCAL_ADDR | allocate(ADDREG) "lea %[1.off](a6),%[a]" samecc | %[a] | | | REGOFF_ADDR | allocate(ADDREG) "lea %[1.off](%[1.reg]),%[a]" samecc | %[a] | | lae | | | {EXTERNAL_ADDR,$1} | | | EXTERNAL_ADDR | allocate(ADDREG) "lea %[1.off],%[a]" samecc | %[a] | | (3,5) /* For the lxl and lxa instructions we assume that the static link * (i.e. a pointer to the LB of the lexically enclosing subprogram) * is passed as zero-th actual parameter. The distance (in bytes) * between LB and the zero-th parameter is the constant EM_BSIZE */ lxl $1 == 0 | | | LB | | lxl $1 == 1 | | | {DISPL4,LB,8} | | lxl $1 == 2 | | allocate(ADDREG) "move.l 8(a6),%[a]" "move.l 8(%[a]),%[a]" | %[a] | | lxl $1>1 | | allocate(ADDREG,DATAREG = {IMMEDIATE,$1-1}) "move.l a6,%[a]" "1:" "move.l 8(%[a]),%[a]" "dbf %[b],1b" erase(%[b]) | %[a] | | lxa $1 == 0 | | allocate(ADDREG = {IMMEDIATE4,8}) "add.l a6,%[a]" erase(%[a]) | %[a] | | lxa $1 > 0 | | allocate(ADDREG, DATAREG = {IMMEDIATE,$1-1}) "move.l a6,%[a]" "1:" "move.l 8(%[a]),%[a]" "dbf %[b],1b" "add.l #8,%[a]" erase(%[b]) | %[a] | | loi $1 == 1 | ADDREG | | {IADDREG1, %[1]} | | ... | nocoercions: LOCAL_ADDR | | {DISPL1,LB,%[1.off]} | | ... | nocoercions: REGOFF_ADDR | | {DISPL1,%[1.reg],%[1.off]} | | ... | nocoercions: EXTERNAL_ADDR | | {ABS1,%[1.off]} | | loi $1 == 2 | ADDREG | | {IADDREG,%[1]} | | loi $1 == 4 | ADDREG | | {IADDREG4,%[1]} | | lal loi $2 == 6 | | remove(ALL) "move.w $1+4(a6),-(sp)" "move.l $1(a6),-(sp)" | | | lal loi $2 == 8 | | remove(ALL) "move.l $1+4(a6),-(sp)" "move.l $1(a6),-(sp)" | | | lae loi $2 == 6 | | remove(ALL) "move.w $1+4,-(sp)" "move.l $1,-(sp)" | | | lae loi $2 == 8 | | remove(ALL) "move.l $1+4,-(sp)" "move.l $1,-(sp)" | | | loi $1 == 6 | ADDREG | | {DISPL,%[1],4} {IADDREG4,%[1]} | | loi $1 == 8 | ADDREG | | {DISPL4,%[1],4} {IADDREG4,%[1]} | | loi $1 > 8 | ADDSCR | remove(ALL) allocate(DATAREG4= {IMMEDIATE4,$1/2-1}) "add.l #$1,%[1]" "1:" "move.w -(%[1]),-(sp)" "dbf %[a],1b" erase(%[a]) | | | ... | nocoercions: LOCAL_ADDR | remove(ALL) allocate(DATAREG4 = {IMMEDIATE4,$1/2-1}, ADDREG) "lea %[1.off]+$1(a6),%[b]" "1:" "move.w -(%[b]),-(sp)" "dbf %[a],1b" erase(%[a]) | | | ... | nocoercions: EXTERNAL_ADDR | remove(ALL) allocate(DATAREG4={IMMEDIATE4,$1/2-1}, ADDREG) "lea %[1.off]+$1,%[b]" "1:" "move.w -(%[b]),-(sp)" "dbf %[a],1b" erase(%[a]) | | | los $1 == 2 | | remove(ALL) "jsr .los" | | | lpi | | | {EXTERNAL_ADDR,$1} | | /* G R O U P II : S T O R E S */ /* A store instruction can always corrupt part of the fakestack, * so some items of the stack have to be removed (i.e. pushed on * the real stack or stored in a register). Registers on the * fakestack will never be corrupted, because they can never be * the destination. * For most store instructions (e.g. sil,stf) we have hardly any * idea what the destination will be, so everything on the * fakestack (except registers) is removed (i.e. remove(MEM_ALL)). * For a stl,sdl,ste and sde we remove only those items that may * be affected, assuming that a stl only affects locals and a * ste only affects externals. Care has to be taken that doubles * and singles may overlap, e.g. "lol 6 sdl 4". * Furthermore, stacktoken instances that resulted from a lof,lif * or loi may be corrupted too. */ #ifdef REGVARS stl inreg($1)==2 | nocoercions: ANY | remove(regvar($1)) move(%[1],regvar($1)) | | | ... | STACK | "move.w (sp)+,%(regvar($1)%)" | | | #endif stl | nocoercions: ANY | remove(DISPL,%[reg] == LB && %[dis] == $1) remove(DISPL4,%[reg] == LB && (%[dis] == $1-2 || %[dis] == $1)) remove(DISPL1,%[reg] == LB && (%[dis] == $1 || %[dis] == $1+1)) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) move(%[1],{DISPL,LB,$1}) | | | ... | STACK | "move.w (sp)+,$1(a6)" | | | ste | ANY | remove(ABS) remove(ABS4) remove(ABS1) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) move(%[1],{ABS,$1}) | | | #ifdef REGVARS sil inreg($1)==2 | ANY | remove(MEM_ALL) move(%[1],{IADDREG,regvar($1)}) | | | #endif sil | ANY | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) move(%[1],{IADDREG,%[a]}) setcc({IADDREG,%[a]}) | | | stf | ADDREG ANY | remove(MEM_ALL) move(%[2],{DISPL,%[1],$1}) | | | sti $1 == 1 | ADDREG DATAREG | remove(MEM_ALL) move(%[2], {IADDREG1,%[1]}) | | | ... | ADDREG IADDREG | remove(MEM_ALL) move({DISPL,%[2.reg],1}, {IADDREG1,%[1]}) | | | ... | ADDREG DISPL | remove(MEM_ALL) move({DISPL,%[2.reg],%[2.dis]+1}, {IADDREG1,%[1]}) | | | ... | ADDREG INDEXED | remove(MEM_ALL) move({INDEXED,%[2.reg],%[2.ireg],%[2.di]+1}, {IADDREG1,%[1]}) | | | ... | ADDREG ABS | remove(MEM_ALL) move({ABS,%[2.addr]+"+1"}, {IADDREG1,%[1]}) | | | ... | ADDREG IMMEDIATE | remove(MEM_ALL) move({IMMEDIATE,(%[2.cc]-((%[2.cc]>>8)<<8)+128)%256-128}, {IADDREG1,%[1]}) | | | ... | ADDREG ANY1 | remove(MEM_ALL) move(%[2],{IADDREG1,%[1]}) | | | ... | nocoercions: LOCAL_ADDR DATAREG | remove(MEM_ALL) move(%[2], {DISPL1,LB,%[1.off]}) | | | ... | nocoercions: LOCAL_ADDR IADDREG | remove(MEM_ALL) move({DISPL,%[2.reg],1}, {DISPL1,LB,%[1.off]}) | | | ... | nocoercions: LOCAL_ADDR DISPL | remove(MEM_ALL) move({DISPL,%[2.reg],%[2.dis]+1}, {DISPL1,LB,%[1.off]}) | | | ... | nocoercions: LOCAL_ADDR INDEXED | remove(MEM_ALL) move({INDEXED,%[2.reg],%[2.ireg],%[2.di]+1}, {DISPL1,LB,%[1.off]}) | | | ... | nocoercions: LOCAL_ADDR ABS | remove(MEM_ALL) move({ABS,%[2.addr]+"+1"}, {DISPL1,LB,%[1.off]}) | | | ... | nocoercions: LOCAL_ADDR IMMEDIATE | remove(MEM_ALL) move({IMMEDIATE,(%[2.cc]-((%[2.cc]>>8)<<8)+128)%256-128}, {DISPL1,LB,%[1.off]}) | | | ... | nocoercions: LOCAL_ADDR ANY1 | remove(MEM_ALL) move(%[2],{DISPL1,LB,%[1.off]}) | | | ... | nocoercions: REGOFF_ADDR DATAREG | remove(MEM_ALL) move(%[2], {DISPL1,%[1.reg],%[1.off]}) | | | ... | nocoercions: REGOFF_ADDR IADDREG | remove(MEM_ALL) move({DISPL,%[2.reg],1}, {DISPL1,%[1.reg],%[1.off]}) | | | ... | nocoercions: REGOFF_ADDR DISPL | remove(MEM_ALL) move({DISPL,%[2.reg],%[2.dis]+1}, {DISPL1,%[1.reg],%[1.off]}) | | | ... | nocoercions: REGOFF_ADDR INDEXED | remove(MEM_ALL) move({INDEXED,%[2.reg],%[2.ireg],%[2.di]+1}, {DISPL1,%[1.reg],%[1.off]}) | | | ... | nocoercions: REGOFF_ADDR ABS | remove(MEM_ALL) move({ABS,%[2.addr]+"+1"}, {DISPL1,%[1.reg],%[1.off]}) | | | ... | nocoercions: REGOFF_ADDR IMMEDIATE | remove(MEM_ALL) move({IMMEDIATE,(%[2.cc]-((%[2.cc]>>8)<<8)+128)%256-128}, {DISPL1,%[1.reg],%[1.off]}) | | | ... | nocoercions: REGOFF_ADDR ANY1 | remove(MEM_ALL) move(%[2],{DISPL1,%[1.reg],%[1.off]}) | | | ... | nocoercions: EXTERNAL_ADDR DATAREG | remove(MEM_ALL) move(%[2], {ABS1,%[1.off]}) | | | ... | nocoercions: EXTERNAL_ADDR IADDREG | remove(MEM_ALL) move({DISPL,%[2.reg],1}, {ABS1,%[1.off]}) | | | ... | nocoercions: EXTERNAL_ADDR DISPL | remove(MEM_ALL) move({DISPL,%[2.reg],%[2.dis]+1}, {ABS1,%[1.off]}) | | | ... | nocoercions: EXTERNAL_ADDR INDEXED | remove(MEM_ALL) move({INDEXED,%[2.reg],%[2.ireg],%[2.di]+1}, {ABS1,%[1.off]}) | | | ... | nocoercions: EXTERNAL_ADDR ABS | remove(MEM_ALL) move({ABS,%[2.addr]+"+1"}, {ABS1,%[1.off]}) | | | ... | nocoercions: EXTERNAL_ADDR IMMEDIATE | remove(MEM_ALL) move({IMMEDIATE,(%[2.cc]-((%[2.cc]>>8)<<8)+128)%256-128}, {ABS1,%[1.off]}) | | | ... | nocoercions: EXTERNAL_ADDR ANY1 | remove(MEM_ALL) move(%[2],{ABS1,%[1.off]}) | | | sti $1 == 2 | ADDREG ANY | remove(MEM_ALL) move(%[2],{IADDREG,%[1]}) | | | sti $1 == 4 | ADDREG ANY4 | remove(MEM_ALL) move(%[2],{IADDREG4,%[1]}) | | | sti $1 > 4 | ADDSCR | remove(ALL) allocate(DATAREG4={IMMEDIATE4,$1/2-1}) "1:" "move.w (sp)+,(%[1])+" "dbf %[a], 1b" setcc({IADDREG,%[1]}) | | | sts $1 == 2 | | remove(ALL) "jsr .sts" | | | #ifdef REGVARS sdl inreg($1)==2 | nocoercions: ANY4 | remove(regvar($1)) move (%[1],regvar($1)) | | | ... | STACK | "move.l (sp)+,%(regvar($1)%)" | | | #endif sdl | nocoercions: ANY4 | remove(DISPL,%[reg] == LB && (%[dis] == $1 || %[dis] == $1+2)) remove(DISPL4,%[reg] == LB && (%[dis] >= $1-2 && %[dis] <= $1+2)) remove(DISPL1,%[reg] == LB && (%[dis] >= $1 && %[dis] <= $1+3)) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) move(%[1],{DISPL4,LB,$1}) | | | ... | STACK | "move.l (sp)+,$1(a6)" | | | sde | ANY4 | remove(ABS) remove(ABS4) remove(ABS1) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) move(%[1],{ABS4,$1}) | | | sdf | ADDREG ANY4 | remove(MEM_ALL) move(%[2],{DISPL4,%[1],$1}) | | | #ifdef REGVARS /* R U L E S F O R R E G I S T E R V A R I A B L E S */ /* Note that these rules should come before the normal patterns for * local variables that are not register-variables. */ ldl ldl adp sdl loi $1==$2 && $2==$4 && inreg($1)==2 && $3==1 && $5==1 | | allocate(DATAREG={IMMEDIATE,0}) remove(regvar($1)) "move.b (%(regvar($1)%))+,%[a]" | %[a] | | ldl ldl adp sdl loi $1==$2 && $2==$4 && inreg($1)==2 && $3==2 && $5==2 | | allocate(DATAREG) remove(regvar($1)) "move.w (%(regvar($1)%))+,%[a]" | %[a] | | ldl ldl adp sdl sti $1==$2 && $2==$4 && inreg($1)==2 && $3==1 && $5==1 | DATAREG | remove(regvar($1)) "move.b %[1],(%(regvar($1)%))+" | | | ldl ldl adp sdl sti $1==$2 && $2==$4 && inreg($1)==2 && $3==2 && $5==2 | ANY | remove(regvar($1)) "move.w %[1],(%(regvar($1)%))+" | | | ldl ldl adp sdl $1==$2 && $2==$4 && inreg($1)==2 | | allocate(ADDREG=regvar($1)) | %[a] | ldl $2 adp $3 sdl $2 | lol inl $1==$2 && inreg($1)==2 | | allocate(DATAREG=regvar($1)) | %[a] | inl $2 | lol inl $1==$2 | | allocate(DATAREG={DISPL,LB,$1}) | %[a] | inl $2 | lol del $1==$2 && inreg($1)==2 | | allocate(DATAREG=regvar($1)) | %[a] | del $2 | lol del $1==$2 | | allocate(DATAREG={DISPL,LB,$1}) | %[a] | del $2 | loe ine $1==$2 | | allocate(DATAREG={ABS,$1}) | %[a] | ine $2 | loe dee $1==$2 | | allocate(DATAREG={ABS,$1}) | %[a] | dee $2 | lol adi stl $1 == $3 && $2 == 2 && inreg($1)==2 | ANY | remove(regvar($1)) "add.w %[1],%(regvar($1)%)" erase(regvar($1)) | | | loc lil adi sil $2 == $4 && $3 == 2 && inreg($2)==2 | | remove(MEM_ALL) "add.w #$1,(%(regvar($2)%))" | | | lil adi sil $1 == $3 && $2 == 2 && inreg($1)==2 | DATAREG | remove(ALL) "add.w %[1],(%(regvar($1)%))" | | | ldl ldc adi sdl $1 == $4 && $3 == 4 && inreg($1)==2 | | remove(regvar($1)) "add.l #$2,%(regvar($1)%)" erase(regvar($1)) | | | ldc ldl adi sdl $2 == $4 && $3 == 4 && inreg($2)==2 | | remove(regvar($2)) "add.l #$1,%(regvar($2)%)" erase(regvar($2)) | | | ldl adi sdl $1 == $3 && $2 == 4 && inreg($1)==2 | DATAREG4 | remove(regvar($1)) "add.l %[1],%(regvar($1)%)" erase(regvar($1)) | | | lol loc sbi stl $1 == $4 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "sub.w #$2,%(regvar($1)%)" erase(regvar($1)) | | | lil loc adi sil $1 == $4 && $3 == 2 && inreg($1)==2 | | remove(MEM_ALL) "add.w #$2,(%(regvar($1)%))" | | | ldl ldc sbi sdl $1 == $4 && $3 == 4 && inreg($1)==2 | | remove(regvar($1)) "sub.l #$2,%(regvar($1)%)" erase(regvar($1)) | | | lol ngi stl $1 == $3 && $2 == 2 && inreg($1)==2 | | remove(regvar($1)) "neg.w %(regvar($1)%)" erase(regvar($1)) | | | lil ngi sil $1 == $3 && $2 == 2 && inreg($1)==2 | | remove(MEM_ALL) "neg.w (%(regvar($1)%))" | | | lol ngi stl $1 == $3 && $2 == 4 && inreg($1)==2 | | remove(regvar($1)) "neg.l %(regvar($1)%)" erase(regvar($1)) | | | lol loc sli stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "asl.w #1, %(regvar($1)%)" erase(regvar($1)) | | | lol loc sri stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "asr.w #1,%(regvar($1)%)" erase(regvar($1)) | | | lol loc sru stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "lsr.w #1,%(regvar($1)%)" erase(regvar($1)) | | | lol loc adu stl $1 == $4 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "add.w #$2,%(regvar($1)%)" erase(regvar($1)) | | | lol adu stl $1 == $3 && $2 == 2 && inreg($1)==2 | ANY | remove(regvar($1)) "add.w %[1],%(regvar($1)%)" erase(regvar($1)) | | | loc lil adu sil $2 == $4 && $3 == 2 && inreg($2)==2 | | remove(MEM_ALL) "add.w #$1,(%(regvar($2)%))" | | | lil adu sil $1 == $3 && $2 == 2 && inreg($1)==2 | DATAREG | remove(MEM_ALL) "add.w %[1],(%(regvar($1)%))" | | | ldl ldc adu sdl $1 == $4 && $3 == 4 && inreg($1)==2 | | remove(regvar($1)) "add.l #$2,%(regvar($1)%)" erase(regvar($1)) | | | ldc ldl adu sdl $2 == $4 && $3 == 4 && inreg($2)==2 | | remove(regvar($2)) "add.l #$1,%(regvar($2)%)" erase(regvar($2)) | | | ldl adu sdl $1 == $3 && $2 == 4 && inreg($1)==2 | DATAREG4 | remove(regvar($1)) "add.l %[1],%(regvar($1)%)" erase(regvar($1)) | | | lol loc sbu stl $1 == $4 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "sub.w #$2,%(regvar($1)%)" erase(regvar($1)) | | | lil loc adu sil $1 == $4 && $3 == 2 && inreg($1)==2 | | remove(MEM_ALL) "add.w #$2,(%(regvar($1)%))" | | | ldl ldc sbu sdl $1 == $4 && $3 == 4 && inreg($1)==2 | | remove(regvar($1)) "sub.l #$2,%(regvar($1)%)" erase(regvar($1)) | | | lol loc slu stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "asl.w #1,%(regvar($1)%)" erase(regvar($1)) | | | ldl adp sdl $1 == $3 && inreg($1)==2 | | remove(regvar($1)) "add.l #$2,%(regvar($1)%)" erase(regvar($1)) | | | ldl adp dup sdl loi inreg($1) == 2 && $1 == $4 && $3 == 4 && $5 == 4 | | | | ldl $1 adp $2 sdl $1 ldl $1 loi 4 | ldl loi ldl loi adp ldl sti $2==4&&$4==4&&$7==4&&$1==$3&&$1==$6&&inreg($1)==2 | | remove(MEM_ALL) allocate(ADDREG = {IADDREG4,regvar($1)}) "add.l #$5,(%(regvar($1)%))" | %[a] | | loc ldl ads sdl $2 == $4 && $3 == 2 && inreg($2)==2 | | remove(regvar($2)) "add.l #$1,%(regvar($2)%)" erase(regvar($2)) | | | ldl ldc ads sdl $1 == $4 && $3 == 4 && inreg($1)==2 | | remove(regvar($1)) "add.l #$2,%(regvar($1)%)" erase(regvar($1)) | | | ldc ldl ads sdl $2 == $4 && $3 == 4 && inreg($2)==2 | | remove(regvar($2)) "add.l #$1,%(regvar($2)%)" erase(regvar($2)) | | | lil inc sil $1==$3 && inreg($1)==2 | | remove(MEM_ALL) "add.w #1,(%(regvar($1)%))" setcc({IADDREG,regvar($1)}) | | | lil dec sil $1==$3 && inreg($1)==2 | | remove(MEM_ALL) "sub.w #1,(%(regvar($1)%))" setcc({IADDREG,regvar($1)}) | | | lol and stl $1 == $3 && $2 == 2 && inreg($1)==2 | ANY | remove(regvar($1)) "and.w %[1],%(regvar($1)%)" erase(regvar($1)) | | | loc lil and sil $2 == $4 && $3 == 2 && inreg($2)==2 | | remove(MEM_ALL) "and.w #$1,(%(regvar($2)%))" | | | lil and sil $1 == $3 && $2 == 2 && inreg($1)==2 | DATAREG | remove(MEM_ALL) "and.w %[1],(%(regvar($1)%))" | | | lol ior stl $1 == $3 && $2 == 2 && inreg($1)==2 | ANY | remove(regvar($1)) "or.w %[1],%(regvar($1)%)" erase(regvar($1)) | | | lil ior sil $1 == $3 && $2 == 2 && inreg($1)==2 | DATAREG | remove(MEM_ALL) "or.w %[1],(%(regvar($1)%))" | | | loc lil ior sil $2 == $4 && $3 == 2 && inreg($2)==2 | | remove(MEM_ALL) "or.w #$1,(%(regvar($2)%))" | | | lol loc xor stl $1 == $4 && $3 == 2 && inreg($1)==2 | | remove(regvar($1)) "eor.w #$2,%(regvar($1)%)" erase(regvar($1)) | | | loc lol xor stl $2 == $4 && $3 == 2 && inreg($2)==2 | | remove(regvar($2)) "eor.w #$1,%(regvar($2)%)" erase(regvar($2)) | | | loc lil xor sil $2 == $4 && $3 == 2 && inreg($2)==2 | | remove(MEM_ALL) "eor.w #$1,(%(regvar($2)%))" | | | lol xor stl $1 == $3 && $2 == 2 && inreg($1)==2 | DATAREG | remove(regvar($1)) "eor.w %[1],%(regvar($1)%)" erase(regvar($1)) | | | lil xor sil $1 == $3 && $2 == 2 && inreg($1)==2 | DATAREG | remove(MEM_ALL) "eor.w %[1],(%(regvar($1)%))" | | | #endif /* G R O U P III AND IV : I N T E G E R A R I T H M E T I C */ adi $1 == 2 | ANY DATASCR | "add.w %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | (2,2)+%[1] ... | DATASCR ANY | "add.w %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | (2,2)+%[2] loc lol adi stl $2 == $4 && $3 == 2 && inreg($2) < 2 | | remove(MEM_ALL) "add.w #$1,$2(a6)" | | | (6,10) loc lil adi sil $2 == $4 && $3 == 2 | | allocate(ADDREG = {DISPL4,LB,$2}) remove(MEM_ALL) "add.w #$1,(%[a])" | | | lol adi stl $1 == $3 && $2 == 2 && inreg($1) < 2 | DATAREG | remove(MEM_ALL) "add.w %[1],$1(a6)" | | | loe adi ste $1 == $3 && $2 == 2 | DATAREG | remove(MEM_ALL) "add.w %[1],$1" | | | lil adi sil $1 == $3 && $2 == 2 | DATAREG | allocate(ADDREG={DISPL4,LB,$1}) remove(ALL) "add.w %[1],(%[a])" | | | loe loc adi ste $3 == 2 && $1 == $4 | | remove(MEM_ALL) "add.w #$2,$1" | | | (7,11) loc loe adi ste $3 == 2 && $2 == $4 | | remove(MEM_ALL) "add.w #$1,$2" | | | (7,11) adi $1 == 4 | ANY4 DATASCR4 | "add.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | (2,3)+%[1] ... | DATASCR4 ANY4 | "add.l %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | (2,3)+%[2] ldl ldc adi sdl $1 == $4 && $3 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "add.l #$2,$1(a6)" | | | (8,16) ldc ldl adi sdl $2 == $4 && $3 == 4 && inreg($2) < 2 | | remove(MEM_ALL) "add.l #$1,$2(a6)" | | | (8,16) lde ldc adi sde $3 == 4 && $1 == $4 | | remove(MEM_ALL) "add.l #$2,$1" | | | (9,17) ldc lde adi sde $3 == 4 && $2 == $4 | | remove(MEM_ALL) "add.l #$1,$2" | | | (9,17) ldl adi sdl $1 == $3 && $2 == 4 && inreg($1) < 2 | DATAREG4 | remove(MEM_ALL) "add.l %[1],$1(a6)" | | | lde adi sde $1 == $3 && $2 == 4 | DATAREG4 | remove(MEM_ALL) "add.l %[1],$1" | | | sbi $1 == 2 | ANY DATASCR | "sub.w %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | (2,2)+%[1] lol loc sbi stl $1 == $4 && $3 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "sub.w #$2,$1(a6)" | | | (6,10) loe loc sbi ste $3 == 2 && $1 == $4 | | remove(MEM_ALL) "sub.w #$2,$1" | | | (7,11) lil loc adi sil $1 == $4 && $3 == 2 | | allocate(ADDREG = {DISPL4,LB,$1}) remove(MEM_ALL) "add.w #$2,(%[a])" | | | sbi $1 == 4 | ANY4 DATASCR4 | "sub.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | (2,3)+%[1] ldl ldc sbi sdl $1 == $4 && $3 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "sub.l #$2,$1(a6)" | | | (8,16) lde ldc sbi sde $3 == 4 && $1 == $4 | | remove(MEM_ALL) "sub.l #$2,$1" | | | (9,17) mli $1 == 2 | DATASCR ANY | "muls %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | mli $1 == 2 | ANY DATASCR | "muls %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | ldc mli loww(1) == 1 && highw(1) == 0 && $2 == 4 | | | | | ldc mli loww(1) == 2 && highw(1) == 0 && $2 == 4 | | | | loc 1 sli 4 | mli $1 == 4 | | remove(ALL) "jsr .mli" | DD1 | | dvi $1 == 2 | ANY DATASCR | "ext.l %[2]" "divs %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | dvi $1 == 4 | | remove(ALL) "jsr .dvi" | DD1 | | rmi $1 == 2 | ANY DATASCR | "ext.l %[2]" "divs %[1],%[2]" "swap %[2]" erase(%[2]) | %[2] | | rmi $1 == 4 | | remove(ALL) "jsr .dvi" | DD2 | | ngi $1 == 2 | DATASCR | "neg %[1]" erase(%[1]) setcc(%[1]) | %[1] | | lol ngi stl $1 == $3 && $2 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "neg.w $1(a6)" | | | loe ngi ste $1 == $3 && $2 == 2 | | remove(MEM_ALL) "neg.w $1" | | | lil ngi sil $1 == $3 && $2 == 2 | | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) "neg.w (%[a])" | | | ngi $1 == 4 | DATASCR4 | "neg.l %[1]" erase(%[1]) setcc(%[1]) | %[1] | | lol ngi stl $1 == $3 && $2 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "neg.l $1(a6)" | | | loe ngi ste $1 == $3 && $2 == 4 | | remove(MEM_ALL) "neg.l $1" | | | loc sli $1 == 1 && $2 == 2 | DATASCR | "add.w %[1],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | loc sli $1 > 1 && $1 <= 8 && $2 == 2 | DATASCR | "asl.w #$1,%[1]" erase(%[1]) | %[1] | | loc sli $1 == 1 && $2 == 4 | DATASCR4 | "add.l %[1],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | loc sli $1 > 1 && $1 <= 8 && $2 == 4 | DATASCR4 | "asl.l #$1,%[1]" erase(%[1]) | %[1] | | lol loc sli ads inreg($1) == 2 && $2 == 1 && $3 == 2 && $4 == 2 | ADDSCR | "add.w %(regvar($1)%),%[1]" "add.w %(regvar($1)%),%[1]" erase(%[1]) | %[1] | | lol loc sli stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "asl.w #1, $1(a6)" | | | loe loc sli ste $1 == $4 && $2 == 1 && $3 == 2 | | remove(MEM_ALL) "asl.w #1, $1" | | | sli $1 == 2 | DATAREG DATASCR | "asl %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | sli $1 == 4 | DATAREG DATASCR4 | "asl.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | loc sri $1 >= 1 && $1 <= 8 && $2 == 2 | DATASCR | "asr.w #$1,%[1]" erase(%[1]) | %[1] | | loc sri $1 >= 1 && $1 <= 8 && $2 == 4 | DATASCR4 | "asr.l #$1,%[1]" erase(%[1]) | %[1] | | lol loc sri stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "asr.w #1,$1(a6)" | | | loe loc sri ste $1 == $4 && $2 == 1 && $3 == 2 | | remove(MEM_ALL) "asr.w #1,$1" | | | sri $1 == 2 | DATAREG DATASCR | "asr %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | sri $1 == 4 | DATAREG DATASCR4 | "asr.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | mlu $1 == 2 | ANY DATASCR | "mulu %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | mlu $1 == 4 | | remove(ALL) "jsr .mlu" | DD1 | | dvu $1 == 2 | ANY ANY | allocate(DATAREG) "clr.l %[a]" "move.w %[2],%[a]" "divu %[1],%[a]" | %[a] | | dvu $1 == 4 | | remove(ALL) "jsr .dvu" | DD1 | | rmu $1 == 2 | ANY ANY | allocate(DATAREG) "clr.l %[a]" "move.w %[2],%[a]" "divu %[1],%[a]" "swap %[a]" | %[a] | | rmu $1 == 4 | | remove(ALL) "jsr .dvu" | DD2 | | loc sru $1 >= 1 && $1 <= 8 && $2 == 2 | DATASCR | "lsr.w #$1,%[1]" erase(%[1]) | %[1] | | loc sru $1 >= 1 && $1 <= 8 && $2 == 4 | DATASCR4 | "lsr.l #$1,%[1]" erase(%[1]) | %[1] | | lol loc sru stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "lsr.w #1,$1(a6)" | | | loe loc sru ste $1 == $4 && $2 == 1 && $3 == 2 | | remove(MEM_ALL) "lsr.w #1,$1" | | | sru $1 == 2 | DATAREG DATASCR | "lsr %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | sru $1 == 4 | DATAREG DATASCR4 | "lsr.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | /* The adu instruction has precisely the same effect as an adi. * The same applies to (sbu,sbi) and (slu,sli) */ lol loc adu stl $1 == $4 && $3 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "add.w #$2,$1(a6)" | | | loc lol adu stl $2 == $4 && $3 == 2 && inreg($2) < 2 | | remove(MEM_ALL) "add.w #$1,$2(a6)" | | | loc lil adu sil $2 == $4 && $3 == 2 | | allocate(ADDREG = {DISPL4,LB,$2}) remove(MEM_ALL) "add.w #$1,(%[a])" | | | lol adu stl $1 == $3 && $2 == 2 && inreg($1) < 2 | DATAREG | remove(MEM_ALL) "add.w %[1],$1(a6)" | | | loe adu ste $1 == $3 && $2 == 2 | DATAREG | remove(MEM_ALL) "add.w %[1],$1" | | | lil adu sil $1 == $3 && $2 == 2 | DATAREG | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) "add.w %[1],(%[a])" | | | loe loc adu ste $3 == 2 && $1 == $4 | | remove(MEM_ALL) "add.w #$2,$1" | | | (7,11) loc loe adu ste $3 == 2 && $2 == $4 | | remove(MEM_ALL) "add.w #$1,$2" | | | (7,11) ldl ldc adu sdl $1 == $4 && $3 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "add.l #$2,$1(a6)" | | | (8,16) ldc ldl adu sdl $2 == $4 && $3 == 4 && inreg($2) < 2 | | remove(MEM_ALL) "add.l #$1,$2(a6)" | | | (8,16) lde ldc adu sde $3 == 4 && $1 == $4 | | remove(MEM_ALL) "add.l #$2,$1" | | | (9,17) ldc lde adu sde $3 == 4 && $2 == $4 | | remove(MEM_ALL) "add.l #$1,$2" | | | (9,17) ldl adu sdl $1 == $3 && $2 == 4 && inreg($1) < 2 | DATAREG4 | remove(MEM_ALL) "add.l %[1],$1(a6)" | | | lde adu sde $1 == $3 && $2 == 4 | DATAREG4 | remove(MEM_ALL) "add.l %[1],$1" | | | lol loc sbu stl $1 == $4 && $3 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "sub.w #$2,$1(a6)" | | | (6,10) loe loc sbu ste $3 == 2 && $1 == $4 | | remove(MEM_ALL) "sub.w #$2,$1" | | | (7,11) lil loc adu sil $1 == $4 && $3 == 2 | | allocate(ADDREG = {DISPL4,LB,$1}) remove(MEM_ALL) "add.w #$2,(%[a])" | | | ldl ldc sbu sdl $1 == $4 && $3 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "sub.l #$2,$1(a6)" | | | (8,16) lde ldc sbu sde $3 == 4 && $1 == $4 | | remove(MEM_ALL) "sub.l #$2,$1" | | | (9,17) loc slu $1 >= 1 && $1 <= 8 && $2 == 2 | DATASCR | "asl.w #$1,%[1]" erase(%[1]) | %[1] | | loc slu $1 >= 1 && $1 <= 8 && $2 == 4 | DATASCR4 | "asl.l #$1,%[1]" erase(%[1]) | %[1] | | lol loc slu stl $1 == $4 && $2 == 1 && $3 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "asl.w #1,$1(a6)" | | | loe loc slu ste $1 == $4 && $2 == 1 && $3 == 2 | | remove(MEM_ALL) "asl.w #1,$1" | | | adu | | | | adi $1 | sbu | | | | sbi $1 | slu | | | | sli $1 | /* Floating point stuff */ adf $1==4 | | remove(ALL) "jsr .adf4" | | asp 8 lfr 4 | adf $1==8 | | remove(ALL) "jsr .adf8" | | asp 16 lfr 4 loi 8 | sbf $1==4 | | remove(ALL) "jsr .sbf4" | | asp 8 lfr 4 | sbf $1==8 | | remove(ALL) "jsr .sbf8" | | asp 16 lfr 4 loi 8 | mlf $1==4 | | remove(ALL) "jsr .mlf4" | | asp 8 lfr 4 | mlf $1==8 | | remove(ALL) "jsr .mlf8" | | asp 16 lfr 4 loi 8 | dvf $1==4 | | remove(ALL) "jsr .dvf4" | | asp 8 lfr 4 | dvf $1==8 | | remove(ALL) "jsr .dvf8" | | asp 16 lfr 4 loi 8 | ngf $1==4 | | remove(ALL) "jsr .ngf4" | | asp 4 lfr 4 | ngf $1==8 | | remove(ALL) "jsr .ngf8" | | asp 8 lfr 4 loi 8 | fif $1==4 | | remove(ALL) "jsr .fif4" | | asp 8 lfr 4 loi 8 | fif $1==8 | | remove(ALL) "jsr .fif8" | | asp 16 lfr 4 loi 16 | fef $1==4 | | remove(ALL) "jsr .fef4" | | asp 4 lfr 4 loi 8 | fef $1==8 | | remove(ALL) "jsr .fef8" | | asp 8 lfr 4 loi 12 | /* G R O U P VI : P O I N T E R A R I T H M E T I C */ adp $1 >= 1 && $1 <= 8 | nocoercions: EXTERNAL_ADDR | | {EXTERNAL_ADDR,%[1.off] + "+" + tostring($1)} | | ... | nocoercions: LOCAL_ADDR | | {LOCAL_ADDR,%[1.off]+$1} | | ... | nocoercions: REGOFF_ADDR | | {REGOFF_ADDR,%[1.reg],%[1.off]+$1} | | ... | nocoercions: ADDREG | | {REGOFF_ADDR,%[1],$1} | | ... | ADDSCR | "add.l #$1,%[1]" erase(%[1]) setcc(%[1]) | %[1] | | adp $1 >= 0-32767 && $1 <= 32767 | nocoercions: EXTERNAL_ADDR | | {EXTERNAL_ADDR,%[1.off] + "+" + tostring($1)} | | ... | nocoercions: LOCAL_ADDR | | {LOCAL_ADDR,%[1.off]+$1} | | ... | nocoercions: REGOFF_ADDR | | {REGOFF_ADDR,%[1.reg],%[1.off]+$1} | | ... | nocoercions: ADDREG | | {REGOFF_ADDR,%[1],$1} | | ... | ADDSCR | | {REGOFF_ADDR,%[1],$1} | | adp | nocoercions: EXTERNAL_ADDR | | {EXTERNAL_ADDR,%[1.off] + "+" + tostring($1)} | | ... | ADDSCR | "add.l #$1,%[1]" erase(%[1]) setcc(%[1]) | %[1] | | /* The next patterns are for efficient translation of "*p++" in C */ ldl ldl adp sdl $1 == $2 && $2 == $4 && inreg($1) < 2 | | allocate(ADDREG={DISPL4,LB,$1}) remove(DISPL,%[reg] == LB && (%[dis] == $1 || %[dis] == $1+2)) remove(DISPL4,%[reg] == LB && (%[dis] >= $1-2 && %[dis] <= $1+2)) remove(DISPL1,%[reg] == LB && (%[dis] >= $1 && %[dis] <= $1+3)) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) "add.l #$3,$1(a6)" | %[a] | | lde lde adp sde $1 == $2 && $2 == $4 | | allocate(ADDREG={ABS4,$1}) remove(ABS) remove(ABS4) remove(ABS1) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) "add.l #$3,$1" | %[a] | | ldl adp sdl $1 == $3 && inreg($1) < 2 | | remove(MEM_ALL) "add.l #$2,$1(a6)" | | | (8,16) lde adp sde $1 == $3 | | remove(MEM_ALL) "add.l #$2,$1" | | | (9,17) ldc ads loww(1) == 0 && highw(1) == 0 && $2 == 4 | | | | | ldc ads highw(1) == 0 && $2 == 4 | ADDREG | | {REGOFF_ADDR,%[1],loww(1)} | | ads $1 == 2 | ANY ADDSCR | "add.w %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | ads $1 == 4 | ANY4 ADDSCR | "add.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | loc ldl ads sdl $2 == $4 && $3 == 2 && inreg($2) < 2 | | remove(MEM_ALL) "add.l #$1,$2(a6)" | | | (8,16) lde loc ads sde $3 == 2 && $1 == $4 | | remove(MEM_ALL) "add.l #$2,$1" | | | (9,17) ldl ldc ads sdl $1 == $4 && $3 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "add.l #$2,$1(a6)" | | | (8,16) ldc ldl ads sdl $2 == $4 && $3 == 4 && inreg($2) < 2 | | remove(MEM_ALL) "add.l #$1,$2(a6)" | | | (8,16) lde ldc ads sde $3 == 4 && $1 == $4 | | remove(MEM_ALL) "add.l #$2,$1" | | | (9,17) ldc lde ads sde $3 == 4 && $2 == $4 | | remove(MEM_ALL) "add.l #$1,$2" | | | (9,17) sbs $1 == 2 | ANY4 DATASCR4 | "sub.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2.1] | | sbs $1 == 4 | ANY4 DATASCR4 | "sub.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | /* G R O U P VII : I N C R E M E N T / D E C R E M E N T */ inc | DATASCR | "add.w #1,%[1]" erase(%[1]) setcc(%[1]) | %[1] | | ... | STACK | "add.w #1,(sp)" | | | #ifdef REGVARS lil inc sil $1==$3 && inreg($1) == 2 | | remove(MEM_ALL) "add.w #1,(%(regvar($1)%))" setcc({IADDREG,regvar($1)}) | | | lil dec sil $1==$3 && inreg($1) == 2 | | remove(MEM_ALL) "sub.w #1,(%(regvar($1)%))" setcc({IADDREG,regvar($1)}) | | | #endif lil inc sil $1==$3 | | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) "add.w #1,(%[a])" | | | lil dec sil $1==$3 | | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) "sub.w #1,(%[a])" | | | #ifdef REGVARS inl inreg($1)==2 | | remove(regvar($1)) "add.w #1,%(regvar($1)%)" erase(regvar($1)) setcc(regvar($1)) | | | del inreg($1)==2 | | remove(regvar($1)) "sub.w #1,%(regvar($1)%)" erase(regvar($1)) setcc(regvar($1)) | | | zrl inreg($1)==2 | | remove(regvar($1)) "clr.w %(regvar($1)%)" erase(regvar($1)) setcc(regvar($1)) | | | #endif inl inreg($1) < 2 | | remove(DISPL,%[reg] == LB && %[dis] == $1) remove(DISPL4,%[reg] == LB && (%[dis] == $1-2 || %[dis] == $1)) remove(DISPL1,%[reg] == LB && (%[dis] == $1 || %[dis] == $1+1)) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) "add.w #1,$1(a6)" setcc({DISPL,LB,$1}) | | | ine | | remove(ABS) remove(ABS4) remove(ABS1) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) "add.w #1,$1" setcc({ABS,$1}) | | | dec | DATASCR | "sub.w #1,%[1]" erase(%[1]) setcc(%[1]) | %[1] | | ... | STACK | "sub.w #1,(sp)" | | | del inreg($1) < 2 | | remove(DISPL,%[reg] == LB && %[dis] == $1) remove(DISPL4,%[reg] == LB && (%[dis] == $1-2 || %[dis] == $1)) remove(DISPL1,%[reg] == LB && (%[dis] == $1 || %[dis] == $1+1)) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) "sub.w #1,$1(a6)" setcc({DISPL,LB,$1}) | | | dee | | remove(ABS) remove(ABS4) remove(ABS1) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) "sub.w #1,$1" setcc({ABS,$1}) | | | zrl inreg($1) < 2 | | remove(DISPL,%[reg] == LB && %[dis] == $1) remove(DISPL4,%[reg] == LB && (%[dis] == $1-2 || %[dis] == $1)) remove(DISPL1,%[reg] == LB && (%[dis] == $1 || %[dis] == $1+1)) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) "clr $1(a6)" setcc({DISPL,LB,$1}) | | | zre | | remove(ABS) remove(ABS4) remove(ABS1) remove(DISPL,%[reg] != LB) remove(DISPL4,%[reg] != LB) remove(DISPL1,%[reg] != LB) remove(ALL_ACCESSIBLE) "clr $1" setcc({ABS,$1}) | | | zrf $1 == 4 | | | {IMMEDIATE4,0} | | zrf $1 == 8 | | | {IMMEDIATE4,0} {IMMEDIATE4,0} | | zer $1 == 2 | | | {IMMEDIATE,0} | | zer $1 == 4 | | | | ldc 0 | zer $1 == 6 | | remove(ALL) "clr.l -(sp)" "clr.w -(sp)" | | | zer $1 == 8 | | remove(ALL) "clr.l -(sp)" "clr.l -(sp)" | | | zer $1 == 10 | | remove(ALL) "clr.l -(sp)" "clr.l -(sp)" "clr.w -(sp)" | | | zer $1 == 12 | | remove(ALL) "clr.l -(sp)" "clr.l -(sp)" "clr.l -(sp)" | | | zer $1 > 12 | | remove(ALL) allocate(DATAREG4) "move.l #$1/2-1,%[a]" "1:" "clr -(sp)" "dbf %[a],1b" | | | zrf | | | | zer $1 | /* G R O U P VIII : C O N V E R T */ loc loc cii $1==$2 | | | | | loc loc cuu $1==$2 | | | | | loc loc ciu $1==$2 | | | | | loc loc cui $1==$2 | | | | | cii | | remove(ALL) "jsr .cii" | | | cuu | | remove(ALL) "jsr .cuu" | | | cui | | | | cuu | ciu | | | | cuu | loc loc cii $1==1 && $2==2 | DATASCR | "ext.w %[1]" erase(%[1]) setcc(%[1]) | %[1] | | loc loc cii $1==1 && $2==4 | ANY | allocate(%[1],DATAREG4) move(%[1],%[a.1]) "ext.w %[a]" "ext.l %[a]" erase(%[a]) setcc(%[a]) | %[a] | | loc loc cuu $1==1 && $2==4 | nocoercions: DATASCR | "and.l #255,%[1]" erase(%[1]) setcc(%[1]) | %[1] | | ... | ANY | allocate(DATAREG4) "clr.l %[a]" move(%[1],%[a.1]) erase(%[a]) | %[a] | | ... | ANY1 | allocate(DATAREG4) "clr.l %[a]" "move.b %[1],%[a.1]" erase(%[a]) | %[a] | | loc loc cii $1==2 && $2==4 | ANY | allocate(%[1],DATAREG4) move(%[1],%[a.1]) "ext.l %[a]" erase(%[a]) setcc(%[a]) | %[a] | | loc loc cuu $1==2 && $2==4 | | | {IMMEDIATE,0} | | loc loc ciu $1==2 && $2==4 | | | {IMMEDIATE,0} | | loc loc cui $1==2 && $2==4 | | | {IMMEDIATE,0} | | loc loc loc cuu $1 == 0 && $2 == 1 && $3 == 4 | | | {DOUBLE,"0"} | | loc loc loc ciu $1 == 0 && $2 == 1 && $3 == 4 | | | {DOUBLE,"0"} | | loc loc loc cui $1 == 0 && $2 == 1 && $3 == 4 | | | {DOUBLE,"0"} | | loc loc loc cuu $1 == 0 && $2 == 2 && $3 == 4 | | | {DOUBLE,"0"} | | loc loc loc ciu $1 == 0 && $2 == 2 && $3 == 4 | | | {DOUBLE,"0"} | | loc loc loc cui $1 == 0 && $2 == 2 && $3 == 4 | | | {DOUBLE,"0"} | | loc loc cii $1==4 && $2==2 | DATAREG4 | | %[1.1] | | ... | ANY ANY | | %[2] | | loc loc cuu $1==4 && $2==2 | DATAREG4 | | %[1.1] | | ... | ANY | | | | loc loc ciu $1==4 && $2==2 | DATAREG4 | | %[1.1] | | ... | ANY | | | | loc loc cui $1==4 && $2==2 | DATAREG4 | | %[1.1] | | ... | ANY | | | | loc loc loc cuu $2 == 1 && $3 == 4 && $1 > 0 && $1 < 128 | | | | ldc $1 | /* Floating point stuff */ loc loc cif $1==2 && $2==4 | | remove(ALL) "move.w #$1,-(sp)" "jsr .cif4" | | asp 4 lfr 4 | loc loc cif $1==2 && $2==8 | | remove(ALL) "move.w #$1,-(sp)" "jsr .cif8" | | asp 4 lfr 4 loi 8 | loc loc cif $1==4 && $2==4 | | remove(ALL) "move.w #$1,-(sp)" "jsr .cif4" | | asp 6 lfr 4 | loc loc cif $1==4 && $2==8 | | remove(ALL) "move.w #$1,-(sp)" "jsr .cif8" | | asp 6 lfr 4 loi 8 | loc loc cuf $1==2 && $2==4 | | remove(ALL) "move.w #$1,-(sp)" "jsr .cuf4" | | asp 4 lfr 4 | loc loc cuf $1==2 && $2==8 | | remove(ALL) "move.w #$1,-(sp)" "jsr .cuf8" | | asp 4 lfr 4 loi 8 | loc loc cuf $1==4 && $2==4 | | remove(ALL) "move.w #$1,-(sp)" "jsr .cuf4" | | asp 6 lfr 4 | loc loc cuf $1==4 && $2==8 | | remove(ALL) "move.w #$1,-(sp)" "jsr .cuf8" | | asp 6 lfr 4 loi 8 | loc loc cfi $1==4 && $2==2 | | remove(ALL) "move.w #$1,-(sp)" "move.w #$2,-(sp)" "jsr .cfi" | | asp 8 lfr 2 | loc loc cfi $1==4 && $2==4 | | remove(ALL) "move.w #$1,-(sp)" "move.w #$2,-(sp)" "jsr .cfi" | | asp 8 lfr 4 | loc loc cfi $1==8 && $2==2 | | remove(ALL) "move.w #$1,-(sp)" "move.w #$2,-(sp)" "jsr .cfi" | | asp 12 lfr 2 | loc loc cfi $1==8 && $2==4 | | remove(ALL) "move.w #$1,-(sp)" "move.w #$2,-(sp)" "jsr .cfi" | | asp 12 lfr 4 | loc loc cfu $1==4 && $2==2 | | remove(ALL) "move.w #$1,-(sp)" "move.w #$2,-(sp)" "jsr .cfu" | | asp 8 lfr 2 | loc loc cfu $1==4 && $2==4 | | remove(ALL) "move.w #$1,-(sp)" "move.w #$2,-(sp)" "jsr .cfu" | | asp 8 lfr 4 | loc loc cfu $1==8 && $2==2 | | remove(ALL) "move.w #$1,-(sp)" "move.w #$2,-(sp)" "jsr .cfu" | | asp 12 lfr 2 | loc loc cfu $1==8 && $2==4 | | remove(ALL) "move.w #$1,-(sp)" "move.w #$2,-(sp)" "jsr .cfu" | | asp 12 lfr 4 | loc loc cff $1==8 && $2==4 | | remove(ALL) "jsr .cff4" | | asp 8 lfr 4 | loc loc cff $1==4 && $2==8 | | remove(ALL) "jsr .cff8" | | asp 4 lfr 4 loi 8 | /* G R O U P IX : L O G I C A L */ and defined($1) && $1 == 2 | ANY DATASCR | "and %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | (2,2)+%[1] ... | DATASCR ANY | "and %[2],%[1]" setcc(%[1]) erase(%[1]) | %[1] | | (2,2)+%[2] lol loc and $2 == 255 && inreg($1) < 2 && $3 == 2 | | | {DISPL1,LB,$1+1} | | lal loi and lal sti $1 == $4 && $2 == 1 && $3 == 2 && $5 == 1 && inreg($1) < 2 | DATAREG | remove(MEM_ALL) "and.b %[1],$1(a6)" | | | loc lol and stl $2 == $4 && $3 == 2 && inreg($2) < 2 | | remove(MEM_ALL) "and.w #$1,$2(a6)" | | | (6,10) loe loc and ste $3 == 2 && $1 == $4 | | remove(MEM_ALL) "and.w #$2,$1" | | | (7,11) loc loe and ste $3 == 2 && $2 == $4 | | remove(MEM_ALL) "and.w #$1,$2" | | | (7,11) loc lil and sil $2 == $4 && $3 == 2 | | allocate(ADDREG = {DISPL4,LB,$2}) remove(MEM_ALL) "and.w #$1,(%[a])" | | | lol and stl $1 == $3 && $2 == 2 && inreg($1) < 2 | DATAREG | remove(MEM_ALL) "and.w %[1],$1(a6)" | | | loe and ste $1 == $3 && $2 == 2 | DATAREG | remove(MEM_ALL) "and.w %[1],$1" | | | lil and sil $1 == $3 && $2 == 2 | DATAREG | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) "and.w %[1],(%[a])" | | | /* Note that the contents of an address register may not be used as * operand of a and, or etc. instruction */ and defined($1) && $1 == 4 | ANY4-ADDREG DATASCR4 | "and.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | (2,3)+%[1] ... | DATASCR4 ANY4-ADDREG | "and.l %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | (2,3)+%[2] ldl ldc and sdl $1 == $4 && $3 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "and.l #$2,$1(a6)" | | | (8,16) ldc ldl and sdl $2 == $4 && $3 == 4 && inreg($2) < 2 | | remove(MEM_ALL) "and.l #$1,$2(a6)" | | | (8,16) lde ldc and sde $3 == 4 && $1 == $4 | | remove(MEM_ALL) "and.l #$2,$1" | | | (9,17) ldc lde and sde $3 == 4 && $2 == $4 | | remove(MEM_ALL) "and.l #$1,$2" | | | (9,17) ldl and sdl $1 == $3 && $2 == 4 && inreg($1) < 2 | DATAREG4 | remove(MEM_ALL) "and.l %[1],$1(a6)" | | | lde and sde $1 == $3 && $2 == 4 | DATAREG4 | remove(MEM_ALL) "and.l %[1],$1" | | | and defined($1) && $1 > 4 | STACK | allocate(DATAREG4,ADDREG,DATAREG) "move.l #$1/2-1,%[a]" "move.l sp,%[b]" "add.l #$1,%[b]" "1:" "move.w (sp)+,%[c]" "and %[c],(%[b])+" "dbf %[a],1b" | | | and !defined($1) | DATASCR STACK | allocate(ADDREG,DATAREG) "move.l sp,%[a]" "sub.w #1,%[1]" "asr #1,%[1]" "1:" "move.w (sp)+,%[b]" "and %[b],(%[a])+" "dbf %[1],1b" erase(%[1]) | | | ior defined($1) && $1 == 2 | ANY DATASCR | "or %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | (2,2)+%[1] ... | DATASCR ANY | "or %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | (2,2)+%[2] lal loi ior lal sti $1 == $4 && $2 == 1 && $3 == 2 && $5 == 1 && inreg($1) < 2 | DATAREG | remove(MEM_ALL) "or.b %[1],$1(a6)" | | | loc lol ior stl $2 == $4 && $3 == 2 && inreg($2) < 2 | | remove(MEM_ALL) "or.w #$1,$2(a6)" | | | (6,10) lol ior stl $1 == $3 && $2 == 2 && inreg($1) < 2 | DATAREG | remove(MEM_ALL) "or.w %[1],$1(a6)" | | | loe ior ste $1 == $3 && $2 == 2 | DATAREG | remove(MEM_ALL) "or.w %[1],$1" | | | lil ior sil $1 == $3 && $2 == 2 | DATAREG | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) "or.w %[1],(%[a])" | | | loe loc ior ste $3 == 2 && $1 == $4 | | remove(MEM_ALL) "or.w #$2,$1" | | | (7,11) loc loe ior ste $3 == 2 && $2 == $4 | | remove(MEM_ALL) "or.w #$1,$2" | | | (7,11) loc lil ior sil $2 == $4 && $3 == 2 | | allocate(ADDREG = {DISPL4,LB,$2}) remove(MEM_ALL) "or.w #$1,(%[a])" | | | ior defined($1) && $1 == 4 | ANY4-ADDREG DATASCR4 | "or.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | |(2,3)+%[1] ... | DATASCR4 ANY4-ADDREG | "or.l %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | |(2,3)+%[2] ldl ldc ior sdl $1 == $4 && $3 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "or.l #$2,$1(a6)" | | | (8,16) ldc ldl ior sdl $2 == $4 && $3 == 4 && inreg($2) < 2 | | remove(MEM_ALL) "or.l #$1,$2(a6)" | | | (8,16) lde ldc ior sde $3 == 4 && $1 == $4 | | remove(MEM_ALL) "or.l #$2,$1" | | | (9,17) ldc lde ior sde $3 == 4 && $2 == $4 | | remove(MEM_ALL) "or.l #$1,$2" | | | (9,17) ldl ior sdl $1 == $3 && $2 == 4 && inreg($1) < 2 | DATAREG4 | remove(MEM_ALL) "or.l %[1],$1(a6)" | | | lde ior sde $1 == $3 && $2 == 4 | DATAREG4 | remove(MEM_ALL) "or.l %[1],$1" | | | ior defined($1) && $1 > 4 | STACK | allocate(DATAREG4,ADDREG,DATAREG) "move.l #$1/2-1,%[a]" "move.l sp,%[b]" "add.l #$1,%[b]" "1:" "move.w (sp)+,%[c]" "or %[c],(%[b])+" "dbf %[a],1b" | | | ior !defined($1) | DATASCR STACK | allocate(ADDREG,DATAREG) "move.l sp,%[a]" "sub.w #1,%[1]" "asr #1,%[1]" "1:" "move.w (sp)+,%[b]" "or %[b],(%[a])+" "dbf %[1],1b" erase(%[1]) | | | xor defined($1) && $1 == 2 | DATAREG DATASCR | "eor %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | (2,2)+%[1] ... | DATASCR DATAREG | "eor %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | (2,2)+%[2] lal loi xor lal sti $1 == $4 && $2 == 1 && $3 == 2 && $5 == 1 && inreg($1) < 2 | DATAREG | remove(MEM_ALL) "eor.b %[1],$1(a6)" | | | lol loc xor stl $1 == $4 && $3 == 2 && inreg($1) < 2 | | remove(MEM_ALL) "eor.w #$2,$1(a6)" | | | (6,10) loc lol xor stl $2 == $4 && $3 == 2 && inreg($2) < 2 | | remove(MEM_ALL) "eor.w #$1,$2(a6)" | | | (6,10) loe loc xor ste $3 == 2 && $1 == $4 | | remove(MEM_ALL) "eor.w #$2,$1" | | | (7,11) loc loe xor ste $3 == 2 && $2 == $4 | | remove(MEM_ALL) "eor.w #$1,$2" | | | (7,11) loc lil xor sil $2 == $4 && $3 == 2 | | allocate(ADDREG = {DISPL4,LB,$2}) remove(MEM_ALL) "eor.w #$1,(%[a])" | | | lol xor stl $1 == $3 && $2 == 2 && inreg($1) < 2 | DATAREG | remove(MEM_ALL) "eor.w %[1],$1(a6)" | | | loe xor ste $1 == $3 && $2 == 2 | DATAREG | remove(MEM_ALL) "eor.w %[1],$1" | | | lil xor sil $1 == $3 && $2 == 2 | DATAREG | allocate(ADDREG={DISPL4,LB,$1}) remove(MEM_ALL) "eor.w %[1],(%[a])" | | | xor defined($1) && $1 == 4 | DATAREG4 DATASCR4 | "eor.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | (2,3)+%[1] ... | DATASCR4 DATAREG4 | "eor.l %[2],%[1]" erase(%[1]) setcc(%[1]) | %[1] | | (2,3)+%[2] ldl ldc xor sdl $1 == $4 && $3 == 4 && inreg($1) < 2 | | remove(MEM_ALL) "eor.l #$2,$1(a6)" | | | (8,16) ldc ldl xor sdl $2 == $4 && $3 == 4 && inreg($2) < 2 | | remove(MEM_ALL) "eor.l #$1,$2(a6)" | | | (8,16) lde ldc xor sde $3 == 4 && $1 == $4 | | remove(MEM_ALL) "eor.l #$2,$1" | | | (9,17) ldc lde xor sde $3 == 4 && $2 == $4 | | remove(MEM_ALL) "eor.l #$1,$2" | | | (9,17) ldl xor sdl $1 == $3 && $2 == 4 && inreg($1) < 2 | DATAREG4 | remove(MEM_ALL) "eor.l %[1],$1(a6)" | | | lde xor sde $1 == $3 && $2 == 4 | DATAREG4 | remove(MEM_ALL) "eor.l %[1],$1" | | | xor defined($1) && $1 > 4 | STACK | allocate(DATAREG4,ADDREG,DATAREG) "move.l #$1/2-1,%[a]" "move.l sp,%[b]" "add.l #$1,%[b]" "1:" "move.w (sp)+,%[c]" "eor %[c],(%[b])+" "dbf %[a],1b" | | | xor !defined($1) | DATASCR STACK | allocate(ADDREG,DATAREG) "move.l sp,%[a]" "sub.w #1,%[1]" "asr #1,%[1]" "1:" "move.w (sp)+,%[b]" "eor %[b],(%[a])+" "dbf %[1],1b" erase(%[1]) | | | com defined($1) && $1 == 2 | DATASCR | "not %[1]" erase(%[1]) setcc(%[1]) | %[1] | | com defined($1) && $1 == 4 | DATASCR4 | "not.l %[1]" erase(%[1]) setcc(%[1]) | %[1] | | com defined($1) && $1 > 4 | STACK | allocate(DATAREG4,ADDREG) "move.l #$1/2-1,%[a]" "move.l sp,%[b]" "1:" "not (%[b])+" "dbf %[a],1b" | | | com !defined($1) | DATASCR STACK | allocate(ADDREG) "sub.w #1,%[1]" "asr #1,%[1]" "move.w sp,%[a]" "1:" "not (%[a])+" "dbf %[1],1b" | | | rol defined($1) && $1 == 2 | DATAREG DATASCR | "rol %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | rol defined($1) && $1 == 4 | DATAREG DATASCR4 | "rol.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | ror defined($1) && $1 == 2 | DATAREG DATAREG | "ror %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | ror defined($1) && $1 == 4 | DATAREG DATAREG4 | "ror.l %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | /* G R O U P X : S E T S */ inn defined($1) | | remove(ALL) move({IMMEDIATE,$1},D0) "jsr .inn" erase(D0) | D0 | | inn !defined($1) | ANY | remove(ALL) move(%[1],D0) "jsr .inn" erase(D0) | D0 | | set defined($1) | | remove(ALL) move({IMMEDIATE,$1},D0) "jsr .set" erase(D0) | | | set !defined($1) | ANY | remove(ALL) move(%[1],D0) "jsr .set" erase(D0) | | | /* G R O U P XI : A R R A Y S */ /* In general, array references are resolved via a subroutine call. * Only for two very simple cases we use a more efficient method. * The array must be static, i.e. its element size and its index * range must be static. In these cases the array descriptor will * normally be stored in a rom and an element will be accessed via * the sequence "lae lar", in which lae puts the address of the * descriptor on the stack. The efficient method is used only if the * element size is 2 or 4 bytes. We also make sure that * the offset generated fits in 8 bits. */ lae lar $2 == 2 && rom(1,3) == 2 && rom(1,1) >= (0-63) && rom(1,1) <= 63 | DATASCR ADDREG | "asl #1,%[1]" erase(%[1]) setcc(%[1]) | {INDEXED,%[2],%[1], (0-2)*rom(1,1)} | | lae lar $2 == 2 && rom(1,3) == 4 && rom(1,1) >= (0-31) && rom(1,1) <= 31 | DATASCR ADDREG | "asl #2,%[1]" erase(%[1]) setcc(%[1]) | {INDEXED4,%[2],%[1], (0-4)*rom(1,1)} | | lar $1 == 2 | | remove(ALL) "jsr .lar" | | | lae sar $2 == 2 && rom(1,3) == 2 && rom(1,1) >= (0-63) && rom(1,1) <= 63 | DATASCR ADDREG ANY | remove(MEM_ALL) "asl #1,%[1]" move(%[3],{INDEXED,%[2],%[1], (0-2)*rom(1,1)} ) erase(%[1]) | | | lae sar $2 == 2 && rom(1,3) == 4 && rom(1,1) >= (0-31) && rom(1,1) <= 31 | DATASCR ADDREG ANY4 | remove(MEM_ALL) "asl #2,%[1]" move(%[3],{INDEXED4,%[2],%[1], (0-4)*rom(1,1)}) erase(%[1]) | | | sar $1 == 2 | | remove(ALL) "jsr .sar" | | | lae aar $2 == 2 && rom(1,3) == 2 && rom(1,1) >= (0-63) && rom(1,1) <= 63 | DATASCR ADDREG | "asl #1,%[1]" erase(%[1]) setcc(%[1]) | {INDEX_ADDR,%[2],%[1], (0-2)*rom(1,1)} | | lae aar $2 == 2 && rom(1,3) == 4 && rom(1,1) >= (0-31) && rom(1,1) <= 31 | DATASCR ADDREG | "asl #2,%[1]" erase(%[1]) setcc(%[1]) | {INDEX_ADDR,%[2],%[1], (0-4)*rom(1,1)} | | | INDEX_ADDR | allocate(ADDREG) "lea %[1.di](%[1.reg],%[1.ireg].w),%[a]" samecc | %[a] | | aar $1 == 2 | | remove(ALL) "jsr .aar" | | | lar !defined($1) | | remove(ALL) "jsr .lari" | | | sar !defined($1) | | remove(ALL) "jsr .sari" | | | aar !defined($1) | | remove(ALL) "jsr .aari" | | | /* G R O U P XII : C O M P A R E */ cmi $1 == 2 | ANY DATASCR | "sub.w %[1],%[2]" erase(%[2]) setcc(%[2]) | %[2] | | cmi $1 == 4 | | remove(ALL) "jsr .cmi" | D1 | | cmu $1 == 4 | | | | cmp | cmu defined($1) | | remove(ALL) "move.w #$1,d0" "jsr .cmu" | D1 | | cmu !defined($1) | ANY | remove(ALL) move(%[1],D0) erase(D0) "jsr .cmu" | D1 | | cms $1 == 2 | ANY DATASCR | "sub.w %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | ... | DATASCR ANY | "sub.w %[2],%[1]" setcc(%[1]) erase(%[1]) | %[1] | | cms $1==4 | | | | cmi $1 | cms defined($1) | | remove(ALL) "move.w #$1,d0" "jsr .cms" | | | cms !defined($1) | ANY | remove(ALL) move(%[1],D0) "jsr .cms" erase(D0) | | | cmp | | remove(ALL) "jsr .cmp" | D1 | | /* floating point */ cmf $1==4 | | remove(ALL) "jsr .cmf4" | | asp 8 lfr 2 | cmf $1==8 | | remove(ALL) "jsr .cmf8" | | asp 16 lfr 2 | cmi tlt and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "blt 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tlt ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bge 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tle and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "ble 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tle ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bgt 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi teq and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "beq 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi teq ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bne 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tne and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bne 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tne ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "beq 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tge and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bge 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tge ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "blt 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tgt and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bgt 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tgt ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "ble 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmu tlt and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bcs 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmu tlt ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bcc 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmu tle and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bls 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmu tle ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bhi 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmu teq and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "beq 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmu teq ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bne 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmu tne and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bne 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmu tne ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "beq 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmu tge and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bcc 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmu tge ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bcs 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmu tgt and $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bhi 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmu tgt ior $1==2 && $3==2 | ANY DATAREG DATASCR | "cmp %[1],%[2]" "bls 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmu zlt $1==2 | ANY DATAREG STACK | "cmp.w %[1],%[2]" "bcs $2" | | | cmu zle $1==2 | ANY DATAREG STACK | "cmp.w %[1],%[2]" "bls $2" | | | cmu zeq $1==2 | ANY DATAREG STACK | "cmp.w %[1],%[2]" "beq $2" | | | cmu zne $1==2 | ANY DATAREG STACK | "cmp.w %[1],%[2]" "bne $2" | | | cmu zge $1==2 | ANY DATAREG STACK | "cmp.w %[1],%[2]" "bcc $2" | | | cmu zgt $1==2 | ANY DATAREG STACK | "cmp.w %[1],%[2]" "bhi $2" | | | cmi tlt and $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "blt 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tlt ior $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "bge 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tle and $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "ble 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tle ior $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "bgt 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi teq and $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "beq 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi teq ior $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "bne 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tne and $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "bne 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tne ior $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "beq 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tge and $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "bge 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tge ior $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "blt 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tgt and $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "bgt 1f" "clr %[3]" "1:" erase(%[3]) | %[3] | | cmi tgt ior $1==4 && $3==2 | ANY4 DATAREG4 DATASCR | "cmp.l %[1],%[2]" "ble 1f" "bset #0,%[3]" "1:" erase(%[3]) | %[3] | | cmi tlt $1==4 | ANY4 DATAREG4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "blt 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | cmi tle $1==4 | ANY4 DATAREG4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "ble 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | cmi teq $1==4 | ANY4 DATAREG4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "beq 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | cmi tne $1==4 | ANY4 DATAREG4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bne 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | cmi tge $1==4 | ANY4 DATAREG4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bge 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | cmi tgt $1==4 | ANY4 DATAREG4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bgt 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | ldc cmi tlt and loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "blt 1f" "clr %[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tlt ior loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "bge 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tle and loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "ble 1f" "clr %[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tle ior loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "bgt 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | ldc cmi teq and loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "beq 1f" "clr %[2]" "1:" erase(%[2]) | %[2] | | ldc cmi teq ior loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "bne 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tne and loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "bne 1f" "clr %[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tne ior loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "beq 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tge and loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "bge 1f" "clr %[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tge ior loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "blt 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tgt and loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "bgt 1f" "clr %[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tgt ior loww(1)==0&&highw(1)==0 && $2==4 && $4==2 | DATA_ALT4 DATASCR | "tst.l %[1]" "ble 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | ldc cmi tlt loww(1)==0&&highw(1)==0 | DATA_ALT4 | allocate(DATAREG={IMMEDIATE,1}) "tst.l %[1]" "blt 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | ldc cmi tle loww(1)==0&&highw(1)==0 | DATA_ALT4 | allocate(DATAREG={IMMEDIATE,1}) "tst.l %[1]" "ble 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | ldc cmi teq loww(1)==0&&highw(1)==0 | DATA_ALT4 | allocate(DATAREG={IMMEDIATE,1}) "tst.l %[1]" "beq 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | ldc cmi tne loww(1)==0&&highw(1)==0 | DATA_ALT4 | allocate(DATAREG={IMMEDIATE,1}) "tst.l %[1]" "bne 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | ldc cmi tge loww(1)==0&&highw(1)==0 | DATA_ALT4 | allocate(DATAREG={IMMEDIATE,1}) "tst.l %[1]" "bge 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | ldc cmi tgt loww(1)==0&&highw(1)==0 | DATA_ALT4 | allocate(DATAREG={IMMEDIATE,1}) "tst.l %[1]" "bgt 1f" "clr %[a]" "1:" erase(%[a]) | %[a] | | cmi zlt $1==4 | ANY4 REG4 STACK | "cmp.l %[1],%[2]" "blt $2" | | | cmi zle $1==4 | ANY4 REG4 STACK | "cmp.l %[1],%[2]" "ble $2" | | | cmi zeq $1==4 | ANY4 REG4 STACK | "cmp.l %[1],%[2]" "beq $2" | | | cmi zne $1==4 | ANY4 REG4 STACK | "cmp.l %[1],%[2]" "bne $2" | | | cmi zge $1==4 | ANY4 REG4 STACK | "cmp.l %[1],%[2]" "bge $2" | | | cmi zgt $1==4 | ANY4 REG4 STACK | "cmp.l %[1],%[2]" "bgt $2" | | | ldc cmi zlt loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | test(%[1]) "blt $3" | | | ldc cmi zle loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | test(%[1]) "ble $3" | | | ldc cmi zeq loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | test(%[1]) "beq $3" | | | ldc cmi zne loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | test(%[1]) "bne $3" | | | ldc cmi zge loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | test(%[1]) "bge $3" | | | ldc cmi zgt loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | test(%[1]) "bgt $3" | | | ldc cmi zlt $2==4 | DATA_ALT4 STACK | "cmp.l #$1,%[1]" "blt $3" | | | ldc cmi zle $2==4 | DATA_ALT4 STACK | "cmp.l #$1,%[1]" "ble $3" | | | ldc cmi zeq $2==4 | DATA_ALT4 STACK | "cmp.l #$1,%[1]" "beq $3" | | | ldc cmi zne $2==4 | DATA_ALT4 STACK | "cmp.l #$1,%[1]" "bne $3" | | | ldc cmi zge $2==4 | DATA_ALT4 STACK | "cmp.l #$1,%[1]" "bge $3" | | | ldc cmi zgt $2==4 | DATA_ALT4 STACK | "cmp.l #$1,%[1]" "bgt $3" | | | ldc cms zeq loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | test(%[1]) "beq $3" | | | ldc cms zne loww(1)==0&&highw(1)==0 && $2==4 | DATA_ALT4 STACK | test(%[1]) "bne $3" | | | ldc cms zeq $2==4 | DATA_ALT4 STACK | "cmp.l #$1,%[1]" "beq $3" | | | ldc cms zne $2==4 | DATA_ALT4 STACK | "cmp.l #$1,%[1]" "bne $3" | | | cmp tlt | ANY4 ADDREG | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bcs 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | ... | nocoercions: EXTERNAL_ADDR ANY4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bcs 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | cmp tle | ANY4 ADDREG | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bls 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | ... | nocoercions: EXTERNAL_ADDR ANY4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bls 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | cmp teq | ANY4 ADDREG | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "beq 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | ... | nocoercions: EXTERNAL_ADDR ANY4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "beq 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | cmp bne | ANY4 ADDREG | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bne 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | ... | nocoercions: EXTERNAL_ADDR ANY4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bne 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | cmp tge | ANY4 ADDREG | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bcc 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | ... | nocoercions: EXTERNAL_ADDR ANY4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bcc 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | cmp tgt | ANY4 ADDREG | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bhi 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | ... | nocoercions: EXTERNAL_ADDR ANY4 | allocate(DATAREG={IMMEDIATE,1}) "cmp.l %[1],%[2]" "bhi 1f" "clr.w %[a]" "1:" erase(%[a]) | %[a] | | cmp zlt | ANY4 ADDREG | remove(ALL) "cmp.l %[1],%[2]" "bcs $2" | | | ... | nocoercions: EXTERNAL_ADDR ANY4 | remove(ALL) "cmp.l %[1],%[2]" "bcs $2" | | | cmp zle | ANY4 ADDREG | remove(ALL) "cmp.l %[1],%[2]" "bls $2" | | | ... | nocoercions: EXTERNAL_ADDR ANY4 | remove(ALL) "cmp.l %[1],%[2]" "bls $2" | | | cmp zeq | ANY4 ADDREG | remove(ALL) "cmp.l %[1],%[2]" "beq $2" | | | ... | nocoercions: EXTERNAL_ADDR ANY4 | remove(ALL) "cmp.l %[1],%[2]" "beq $2" | | | cmp zne | ANY4 ADDREG | remove(ALL) "cmp.l %[1],%[2]" "bne $2" | | | ... | nocoercions: EXTERNAL_ADDR ANY4 | remove(ALL) "cmp.l %[1],%[2]" "bne $2" | | | cmp zge | ANY4 ADDREG | remove(ALL) "cmp.l %[1],%[2]" "bcc $2" | | | ... | nocoercions: EXTERNAL_ADDR ANY4 | remove(ALL) "cmp.l %[1],%[2]" "bcc $2" | | | cmp zgt | ANY4 ADDREG | remove(ALL) "cmp.l %[1],%[2]" "bhi $2" | | | ... | nocoercions: EXTERNAL_ADDR ANY4 | remove(ALL) "cmp.l %[1],%[2]" "bhi $2" | | | tlt and $2==2 | DATA_ALT DATASCR | test(%[1]) "blt 1f" "clr.w %[2]" "1:" erase(%[2]) | %[2] | | tlt ior $2==2 | DATA_ALT DATASCR | test(%[1]) "bge 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | tlt | DATA_ALT | allocate(DATAREG={IMMEDIATE,1}) test(%[1]) "blt 1f" "clr %[a]" "1:" | %[a] | | tle and $2==2 | DATA_ALT DATASCR | test(%[1]) "ble 1f" "clr.w %[2]" "1:" erase(%[2]) | %[2] | | tle ior $2==2 | DATA_ALT DATASCR | test(%[1]) "bgt 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | tle | DATA_ALT | allocate(DATAREG={IMMEDIATE,1}) test(%[1]) "ble 1f" "clr %[a]" "1:" | %[a] | | teq and $2==2 | DATA_ALT_1OR2 DATASCR | test(%[1]) "beq 1f" "clr.w %[2]" "1:" erase(%[2]) | %[2] | | teq ior $2==2 | DATA_ALT_1OR2 DATASCR | test(%[1]) "bne 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | teq | DATA_ALT_1OR2 | allocate(DATAREG={IMMEDIATE,1}) test(%[1]) "beq 1f" "clr %[a]" "1:" | %[a] | | tne and $2==2 | DATA_ALT_1OR2 DATASCR | test(%[1]) "bne 1f" "clr.w %[2]" "1:" erase(%[2]) | %[2] | | tne ior $2==2 | DATA_ALT_1OR2 DATASCR | test(%[1]) "beq 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | tne | DATA_ALT_1OR2 | allocate(DATAREG={IMMEDIATE,1}) test(%[1]) "bne 1f" "clr %[a]" "1:" | %[a] | | tge and $2==2 | DATA_ALT DATASCR | test(%[1]) "bge 1f" "clr.w %[2]" "1:" erase(%[2]) | %[2] | | tge ior $2==2 | DATA_ALT DATASCR | test(%[1]) "blt 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | tge | DATA_ALT | allocate(DATAREG={IMMEDIATE,1}) test(%[1]) "bge 1f" "clr %[a]" "1:" | %[a] | | tgt and $2==2 | DATA_ALT DATASCR | test(%[1]) "bgt 1f" "clr.w %[2]" "1:" erase(%[2]) | %[2] | | tgt ior $2==2 | DATA_ALT DATASCR | test(%[1]) "ble 1f" "bset #0,%[2]" "1:" erase(%[2]) | %[2] | | tgt | DATA_ALT | allocate(DATAREG={IMMEDIATE,1}) test(%[1]) "bgt 1f" "clr %[a]" "1:" | %[a] | | /* G R O U P XIII : B R A N C H */ bra | STACK | "bra $1" | | | /* byte comparisons */ loc beq $1 >= 0 && $1 < 128 | nocoercions: DATA_ALT1 | remove(ALL) "cmp.b #$1,%[1]" "beq $2" | | | ... | DATA_ALT STACK | "cmp #$1,%[1]" "beq $2" | | | loc bne $1 >= 0 && $1 < 128 | nocoercions: DATA_ALT1 | remove(ALL) "cmp.b #$1,%[1]" "bne $2" | | | ... | DATA_ALT STACK | "cmp #$1,%[1]" "bne $2" | | | blt | IMMEDIATE DATA_ALT STACK | "cmp %[1],%[2]" "blt $1" | | | ... | ANY DATAREG STACK | "cmp %[1],%[2]" "blt $1" | | | ... | DATA_ALT IMMEDIATE STACK | "cmp %[2],%[1]" "bgt $1" | | | ... | DATAREG ANY STACK | "cmp %[2],%[1]" "bgt $1" | | | ble | IMMEDIATE DATA_ALT STACK | "cmp %[1],%[2]" "ble $1" | | | ... | ANY DATAREG STACK | "cmp %[1],%[2]" "ble $1" | | | ... | DATA_ALT IMMEDIATE STACK | "cmp %[2],%[1]" "bge $1" | | | ... | DATAREG ANY STACK | "cmp %[2],%[1]" "bge $1" | | | beq | IMMEDIATE DATA_ALT STACK | "cmp %[1],%[2]" "beq $1" | | | ... | ANY DATAREG STACK | "cmp %[1],%[2]" "beq $1" | | | ... | DATA_ALT IMMEDIATE STACK | "cmp %[2],%[1]" "beq $1" | | | ... | DATAREG ANY STACK | "cmp %[2],%[1]" "beq $1" | | | bne | IMMEDIATE DATA_ALT STACK | "cmp %[1],%[2]" "bne $1" | | | ... | ANY DATAREG STACK | "cmp %[1],%[2]" "bne $1" | | | ... | DATA_ALT IMMEDIATE STACK | "cmp %[2],%[1]" "bne $1" | | | ... | DATAREG ANY STACK | "cmp %[2],%[1]" "bne $1" | | | bge | IMMEDIATE DATA_ALT STACK | "cmp %[1],%[2]" "bge $1" | | | ... | ANY DATAREG STACK | "cmp %[1],%[2]" "bge $1" | | | ... | DATA_ALT IMMEDIATE STACK | "cmp %[2],%[1]" "ble $1" | | | ... | DATAREG ANY STACK | "cmp %[2],%[1]" "ble $1" | | | bgt | IMMEDIATE DATA_ALT STACK | "cmp %[1],%[2]" "bgt $1" | | | ... | ANY DATAREG STACK | "cmp %[1],%[2]" "bgt $1" | | | ... | DATAREG ANY STACK | "cmp %[2],%[1]" "blt $1" | | | ... | DATA_ALT IMMEDIATE STACK | "cmp %[2],%[1]" "blt $1" | | | zlt | DATA_ALT | remove(ALL) test(%[1]) "blt $1" | | | zle | DATA_ALT | remove(ALL) test(%[1]) "ble $1" | | | zeq | DATA_ALT_1OR2 | remove(ALL) test(%[1]) "beq $1" | | | zne | DATA_ALT_1OR2 | remove(ALL) test(%[1]) "bne $1" | | | zge | DATA_ALT | remove(ALL) test(%[1]) "bge $1" | | | zgt | DATA_ALT | remove(ALL) test(%[1]) "bgt $1" | | | /* G R O U P : XIV P R O C E D U R E C A L L S */ lpi cai | | | | cal $1 | cai | ADDREG | remove(ALL) "jsr (%[1])" | | | cal | | remove(ALL) "jsr $1" | | | lfr $1 == 2 | | | D0 | | lfr $1 == 4 | | | DD0 | | lfr $1 == 8 | | | DD1 DD0 | | ret $1 == 0 | STACK | #ifdef REGVARS return | | | #else "unlk a6" "rts" | | | #endif ret $1 == 2 | ANY STACK | move(%[1],D0) #ifdef REGVARS return | | | #else "unlk a6" "rts" | | | #endif ... | STACK | "move.w (sp)+,d0" #ifdef REGVARS return | | | #else "unlk a6" "rts" | | | #endif ret $1 == 4 | ANY4 STACK | move(%[1],DD0) #ifdef REGVARS return | | | #else "unlk a6" "rts" | | | #endif ... | STACK | "move.l (sp)+,d0" #ifdef REGVARS return | | | #else "unlk a6" "rts" | | | #endif ret $1 == 8 | ANY4 ANY4 STACK | move(%[1],DD0) move(%[2],DD1) #ifdef REGVARS return | | | #else "unlk a6" "rts" | | | #endif ... | STACK | "move.l (sp)+,d0" "move.l (sp)+,d1" #ifdef REGVARS return | | | #else "unlk a6" "rts" | | | #endif /* G R O U P XV : M I S C E L L A N E O U S */ asp $1 >= 1 && $1 <= 8 | STACK | "add.l #$1,sp" | | | asp | STACK | "lea $1(sp),sp" | | | ass $1 == 2 | DATAREG STACK | "add.l %[1],sp" | | | blm $1 == 2 | ADDREG ADDREG | remove(MEM_ALL) move({IADDREG,%[2]}, {IADDREG,%[1]}) | | | blm $1 == 4 | ADDREG ADDREG | remove(MEM_ALL) move({IADDREG4,%[2]}, {IADDREG4,%[1]}) | | | blm $1 == 6 | ADDSCR ADDSCR | remove(MEM_ALL) "move.w (%[2])+,(%[1])+" "move.l (%[2]),(%[1])" erase(%[1]) erase(%[2]) | | | blm $1 == 8 | ADDSCR ADDSCR | remove(MEM_ALL) "move.l (%[2])+,(%[1])+" "move.l (%[2]),(%[1])" erase(%[1]) erase(%[2]) | | | blm $1 == 10 | ADDSCR ADDSCR | remove(MEM_ALL) "move.w (%[2])+,(%[1])+" "move.l (%[2])+,(%[1])+" "move.l (%[2]),(%[1])" erase(%[1]) erase(%[2]) | | | blm $1 == 12 | ADDSCR ADDSCR | remove(MEM_ALL) "move.l (%[2])+,(%[1])+" "move.l (%[2])+,(%[1])+" "move.l (%[2]),(%[1])" erase(%[1]) erase(%[2]) | | | blm $1 > 12 | ADDSCR ADDSCR | remove(MEM_ALL) allocate(DATAREG4={IMMEDIATE4,$1/2-1}) "1:" "move.w (%[2])+,(%[1])+" "dbf %[a],1b" erase(%[a]) erase(%[1]) erase(%[2]) | | | /* Wait for restriction nregneeded<2 to be removed bls $1 == 2 | DATASCR ADDSCR ADDSCR | remove(MEM_ALL) "asr #1,%[1]" "sub.w #1,%[1]" "blt 2f" "1:" "move.w (%[3])+,(%[2])+" "dbf %[1],1b" "2:" erase(%[1]) erase(%[2]) erase(%[3]) | | | */ bls $1 == 2 | STACK | allocate(ADDREG,ADDREG,DATAREG) "move.w (sp)+,%[c]" "move.l (sp)+,%[b]" "move.l (sp)+,%[a]" "asr #1,%[c]" "sub.w #1,%[c]" "blt 2f" "1:" "move.w (%[a])+,(%[b])+" "dbf %[c],1b" "2:" | | | /* For csa and csb we just jump to a piece of code that computes * the jump-address and jumps to this address */ csa $1 == 2 | | remove(ALL) "jmp .csa" | | | csb $1 == 2 | | remove(ALL) "jmp .csb" | | | dch | | | | loi 4 | dup $1 == 2 | ANY | | %[1] %[1] | | dup $1 == 4 | ANY4 | | %[1] %[1] | | ... | ANY ANY | | %[2] %[1] %[2] %[1] | | dup $1 > 4 | STACK | allocate(ADDREG,DATAREG4) "move.l sp,%[a]" "add.l #$1,%[a]" "move.l #$1/2-1,%[b]" "1:" "move.w -(%[a]),-(sp)" "dbf %[b],1b" | | | dus $1 == 2 | DATASCR | remove(ALL) allocate(ADDREG) "move.l sp,%[a]" "add.l %[1],%[a]" "sub.w #1,%[1]" "asr #1,%[1]" "1:" "move.w -(%[a]),-(sp)" "dbf %[1],1b" | | | exg | STACK | "move.w #$1,d0" "jsr .exg" | | | fil | | "move.l #$1,.filn" | | | gto | STACK | allocate(ADDREG) "lea $1,%[a]" "move.l 4(%[a]),sp" "move.l 8(%[a]),a6" "move.l (%[a]),%[a]" "jmp (%[a])" | | | lin | | "move.w #$1,.lino" | | | lni | | "add.w #1,.lino" | | | mon | STACK | "jsr .mon" | | | nop | STACK | "jsr .nop" | | | lim | | | {ABS4,".trpim"} | | lor $1 == 0 | | | LB | | #ifdef REGVARS lor sdl $1 == 1 && inreg($2) == 2 | STACK | "move.l sp,%(regvar($1)%)" | | | #endif lor sdl $1 == 1 | STACK | "move.l sp,$2(a6)" | | | lor adp $1 == 1 | STACK | allocate(ADDREG) "move.l sp,%[a]" "add.l #$2,%[a]" | %[a] | | lor ldf $1 == 1 | STACK | allocate(ADDREG) "move.l $2(sp),%[a]" | %[a] | | lor $1 == 1 | STACK | "move.l sp,-(sp)" | | | lor $1 == 2 | | | {ABS4,".reghp"} | | lpb | | | | adp 8 | rck $1 == 2 | | remove(ALL) "jsr .rck" | | | rtt | | | | ret 0 | sig | STACK | "jsr .sig" | | | sim | | remove(ALL) "move.w (sp)+,.trpim" | | | str $1 == 0 | ANY4 STACK | "move.l %[1],a6" | | | str $1 == 1 | STACK | "move.l (sp)+,sp" | | | str $1 == 2 | | remove(ALL) "jsr .strhp" | | | trp | STACK | "jsr .trp" | | | /* C O E R C I O N S */ /* from stack */ | STACK | allocate(DATAREG) "move.w (sp)+,%[a]" setcc(%[a]) | %[a] | | (2,4) | STACK | allocate(DATAREG4) "move.l (sp)+,%[a]" setcc(%[a]) | %[a] | | (2,6) | STACK | allocate(ADDREG) "move.l (sp)+,%[a]" setcc(%[a]) | %[a] | | (2,6) /* to a register, for efficiency */ | ANY | allocate(%[1],DATAREG=%[1]) | %[a] | | (2,2) | ANY4 | allocate(%[1],DATAREG4=%[1]) | %[a] | | (2,2) | ANY4 | allocate(%[1],ADDREG=%[1]) | %[a] | | (2,2) /* from double to 2 singles */ | DOUBLEZERO | | {IMMEDIATE,0} {IMMEDIATE,0} | | | DISPL4 | | {DISPL,%[1.reg],%[1.dis]+2} {DISPL,%[1.reg],%[1.dis]} | | /* impossible to add string and integer: | ABS4 | | {ABS,%[1.addr]} {ABS,[%1.addr]+2} | | */ /* | INDEXED4 | | {INDEXED,%[1.reg],%[1.ireg],%[1.di]} {INDEXED,%[1.reg],%[1.ireg],%[1.di]+2} | | */ /* from 1 to 2 bytes */ | ANY1 | allocate(DATAREG = {IMMEDIATE,0}) "move.b %[1],%[a]" erase(%[a]) | %[a] | | MOVES: (IMMEDIATE %[cc] == 0, DATA_ALT, "clr.w %[2]" setcc(%[2]),(2,3)+%[2] ) (IMMEDIATE (%[cc] >= 0-128 && %[cc] <= 127), DATAREG, "move.l %[1],%[2]" setcc(%[2]),(2,2)) (ANY, DATA_ALT, "move.w %[1], %[2]"setcc(%[2]),(2,2)+%[1]+%[2]) (IMMEDIATE %[cc] == 0, ANY1, "clr.b %[2]" setcc(%[2]),(2,3)+%[2] ) (ANY+ANY1, ANY1, "move.b %[1], %[2]"setcc(%[2]),(2,2)+%[1]+%[2]) (IMMEDIATE4 %[cc] == 0, DATA_ALT4, "clr.l %[2]"setcc(%[2]),(2,5)+%[2]) (DOUBLEZERO, DATA_ALT4, "clr.l %[2]"setcc(%[2]),(2,5)+%[2]) (DOUBLE %[cc] == "0", DATA_ALT4, "clr.l %[2]"setcc(%[2]),(2,5)+%[2]) (IMMEDIATE4 (%[cc] >= 0-128 && %[cc] <= 127),DATAREG4, "move.l %[1],%[2]" setcc(%[2]),(2,2)) (IMMEDIATE4, ADDREG, "lea %[1.cc],%[2]" nocc, (4,4)) (EXTERNAL_ADDR, ADDREG, "lea %[1.off],%[2]" nocc, (5,5)) (ANY4, DATA_ALT4, "move.l %[1], %[2]"setcc(%[2]),(2,2)+%[1]+%[2]) (ANY, ADDREG, "move.w %[1], %[2]"samecc,(2,2)+%[1]) (ANY4,ADDREG, "move.l %[1], %[2]"samecc,(2,2)+%[1]) TESTS: (DATA_ALT, "tst %[1]",(2,2)+%[1]) (DATA_ALT4,"tst.l %[1]",(2,2)+%[1]) (ANY1,"tst.b %[1]",(2,2)+%[1]) STACKS: (IMMEDIATE %[cc] == 0, , "clr.w -(sp)" setcc(%[1])) (ANY, , "move.w %[1],-(sp)" setcc(%[1]), (2,4) + %[1]) (EXTERNAL_ADDR, , "pea %[1.off]" nocc) (LOCAL_ADDR, , "pea %[1.off](a6)" nocc) (REGOFF_ADDR, , "pea %[1.off](%[1.reg])" nocc) (INDEX_ADDR, , "pea %[1.di](%[1.reg],%[1.ireg].w)" nocc) (IMMEDIATE4 %[cc] == 0, , "clr.l -(sp)") (IMMEDIATE4, , "pea %[1.cc]" nocc) (DOUBLEZERO, , "clr.l -(sp)", (2,4)) (ANY4, , "move.l %[1],-(sp)" setcc(%[1]), (2,6) + %[1]) (ANY1, , "clr.w -(sp)" "move.b %[1],1(sp)")