"$Header$" /******************************************************** * Back end tables for pdp 11 * * Authors : Ceriel J.H. Jacobs,Hans van Staveren * * * * wordsize = 2 bytes, pointersize = 2 bytes. * * * * Register r5 is used for the LB, the stack pointer * * is used for SP. Also some global variables are used: * * - reghp~ : the heap pointer * * - trpim~ : trap ignore mask * * - trppc~ : address of user defined trap handler * * - retar : function return area for size>4 * * * * Timing is based on the timing information available * * for the 11/45. Hardware floating point processor is * * assumed. * ********************************************************/ /* * (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 * */ /* #define REGPATCH \* save all registers in link block */ /* #define UNTESTED \* include untested rules */ #ifdef REGPATCH #define SL 8 #define SSL "010" #else REGPATCH #define SL 4 #define SSL "4" #endif REGPATCH #define NC nocoercions: /* options */ /* #define DORCK \* rck is expanded instead of thrown away */ #define REGVARS /* use register variables */ EM_WSIZE=2 EM_PSIZE=2 EM_BSIZE=SL TIMEFACTOR= 1/300 FORMAT="0%o" REGISTERS: r0 = ("r0", 2), REG. r1 = ("r1", 2), REG, ODD_REG. #ifdef REGVARS r2 = ("r2", 2) regvar, REG. #else /* r2 = ("r2", 2), REG. */ #endif r3 = ("r3", 2), REG, ODD_REG. #ifdef REGVARS r4 = ("r4", 2) regvar, REG. #else /* r4 = ("r4", 2), REG. */ #endif lb = ("r5", 2), localbase. r01 = ("r0", 4, r0, r1), REG_PAIR. #ifndef REGVARS /* r23 = ("r2", 4, r2, r3), REG_PAIR. */ #endif fr0 = ("fr0", 4), FLT_REG. fr1 = ("fr1", 4), FLT_REG. fr2 = ("fr2", 4), FLT_REG. fr3 = ("fr3", 4), FLT_REG. fr01 = ("fr0", 8, fr0, fr1), FLT_REG_PAIR. fr23 = ("fr2", 8, fr2, fr3), FLT_REG_PAIR. dr0 = ("fr0", 8, fr0), DBL_REG. dr1 = ("fr1", 8, fr1), DBL_REG. dr2 = ("fr2", 8, fr2), DBL_REG. dr3 = ("fr3", 8, fr3), DBL_REG. dr01 = ("fr0", 16, dr0, dr1), DBL_REG_PAIR. dr23 = ("fr2", 16, dr2, dr3), DBL_REG_PAIR. TOKENS: /******************************** * Types on the EM-machine * ********************************/ CONST2 = {INT num;} 2 cost=(2,300) "$%[num]" LOCAL2 = {INT ind,size;} 2 cost=(2,600) "%[ind](r5)" LOCAL4 = {INT ind,size;} 4 cost=(2,1200) "%[ind](r5)" ADDR_LOCAL = {INT ind;} 2 ADDR_EXTERNAL = {STRING ind;} 2 cost=(2,300) "$%[ind]" /******************************************************** * Now mostly addressing modes of target machine * ********************************************************/ regdef2 = {REGISTER reg;} 2 cost=(0,300) "*%[reg]" regind2 = {REGISTER reg; STRING ind;} 2 cost=(2,600) "%[ind](%[reg])" reginddef2 = {REGISTER reg; STRING ind;} 2 cost=(2,1050) "*%[ind](%[reg])" regconst2 = {REGISTER reg; STRING ind;} 2 /******************************************************** * This means : add "reg" and "ind" to get address. * * Not really addressable on the PDP 11 * ********************************************************/ relative2 = {STRING ind;} 2 cost=(2,600) "%[ind]" reldef2 = {STRING ind;} 2 cost=(2,1050) "*%[ind]" regdef1 = {REGISTER reg;} 2 cost=(0,300) "*%[reg]" regind1 = {REGISTER reg; STRING ind;} 2 cost=(2,600) "%[ind](%[reg])" reginddef1 = {REGISTER reg; STRING ind;} 2 cost=(2,1050) "*%[ind](%[reg])" relative1 = {STRING ind;} 2 cost=(2,600) "%[ind]" reldef1 = {STRING ind;} 2 cost=(2,1050) "*%[ind]" /************************************************************************ * fto* are floats converted to *, conversion is delayed to be combined * * with store. * ************************************************************************/ ftoint = {REGISTER reg;} 2 ftolong = {REGISTER reg;} 4 /************************************************************************ * ...4 and ...8 are only addressable by the floating point processor. * ************************************************************************/ regind4 = {REGISTER reg; STRING ind; } 4 cost=(2,3630) "%[ind](%[reg])" relative4 = {STRING ind; } 4 cost=(2,3630) "%[ind]" regdef4 = {REGISTER reg;} 4 cost=(2,3240) "*%[reg]" regdef8 = {REGISTER reg;} 8 cost=(2,5220) "*%[reg]" relative8 = {STRING ind; } 8 cost=(2,5610) "%[ind]" regind8 = {REGISTER reg; STRING ind;} 8 cost=(2,5610) "%[ind](%[reg])" TOKENEXPRESSIONS: SCR_REG = REG * SCRATCH SCR_FLT_REG = FLT_REG * SCRATCH SCR_DBL_REG = DBL_REG * SCRATCH SCR_ODD_REG = ODD_REG * SCRATCH SCR_REG_PAIR = REG_PAIR * SCRATCH all= ALL source2 = REG + regdef2 + regind2 + reginddef2 + localbase + relative2 + reldef2 + ADDR_EXTERNAL + CONST2 + LOCAL2 xsource2 = source2 + ftoint source1 = regdef1 + regind1 + reginddef1 + relative1 + reldef1 source1or2 = source1 + source2 long4 = relative4 + regdef4 + LOCAL4 + regind4 + REG_PAIR longf4 = long4 + FLT_REG - REG_PAIR double8 = relative8 + regdef8 + regind8 + DBL_REG indexed2 = regind2 + reginddef2 indexed4 = regind4 indexed8 = regind8 indexed = indexed2 + indexed4 + indexed8 regdeferred = regdef2 + regdef4 + regdef8 indordef = indexed + regdeferred locals = LOCAL2 + LOCAL4 variable2 = relative2 + reldef2 variable4 = relative4 variable8 = relative8 variable = variable2 + variable4 + variable8 dadres2 = relative2 + REG + regind2 regs = REG + REG_PAIR + FLT_REG + FLT_REG_PAIR + DBL_REG + DBL_REG_PAIR noconst2 = source2 - CONST2 - ADDR_EXTERNAL allexeptcon = all - regs - CONST2 - ADDR_LOCAL - ADDR_EXTERNAL externals = relative1 + relative2 + relative4 + relative8 posextern = variable + regdeferred + indexed + externals diradr2 = regconst2 + ADDR_EXTERNAL #ifdef REGVARS #define INDSTORE remove(allexeptcon-locals) remove(locals, inreg(%[ind])==0) #else #define INDSTORE remove(allexeptcon) #endif CODE: /******************************************************** * Group 1 : load instructions. * * * * For most load instructions no code is generated. * * Action : put something on the fake-stack. * ********************************************************/ loc | | | {CONST2, $1} | | ldc | | | {CONST2, loww(1)} {CONST2, highw(1)} | | #ifdef REGVARS lol inreg($1)==2| | | regvar($1) | | #endif lol | | | {LOCAL2, $1,2} | | loe | | | {relative2, $1} | | #ifdef REGVARS lil inreg($1)==2| | | {regdef2, regvar($1)} | | #endif lil | | | {reginddef2, lb, tostring($1)} | | lof | REG | | {regind2,%[1],tostring($1)} | | ... | NC regconst2 | | {regind2,%[1.reg],tostring($1)+"+"+%[1.ind]} | | ... | NC ADDR_EXTERNAL | | {relative2,tostring($1)+"+"+%[1.ind]} | | ... | NC ADDR_LOCAL | | {LOCAL2, %[1.ind] + $1,2} | | #ifdef REGVARS lol lof inreg($1)!=2 | | allocate(REG={LOCAL2, $1,2}) | {regind2,%[a],tostring($2)} | | #endif lal | | | {ADDR_LOCAL, $1} | | lae | | | {ADDR_EXTERNAL, $1} | | lpb | | | | adp SL | lxl $1==0 | | | lb | | lxl $1==1 | | | {LOCAL2 ,SL,2} | | lxl $1==2 | | allocate(REG={LOCAL2, SL, 2}) | {regind2,%[a], SSL} | | lxl $1==3 | | allocate(REG={LOCAL2, SL, 2}) move({regind2,%[a], SSL},%[a]) | {regind2,%[a], SSL} | | lxl $1>3 | | allocate(REG={LOCAL2, SL, 2}, REG={CONST2,$1-1}) "1:" move({regind2,%[a], SSL},%[a]) "sob %[b],1b" setcc(%[a]) erase(%[a]) erase(%[b]) | %[a] | | lxa $1==0 | | | {ADDR_LOCAL, SL} | | lxa $1==1 | | allocate(REG={LOCAL2, SL, 2 }) | {regconst2, %[a], SSL } | | lxa $1==2 | | allocate(REG={LOCAL2, SL, 2 }) move({regind2, %[a], SSL }, %[a]) | {regconst2, %[a], SSL } | | lxa $1==3 | | allocate(REG={LOCAL2, SL, 2 }) move({regind2, %[a], SSL }, %[a]) move({regind2, %[a], SSL }, %[a]) | {regconst2, %[a], SSL } | | lxa $1 > 3 | | allocate(REG={LOCAL2, SL, 2}, REG={CONST2,$1-1}) "1:" move({regind2,%[a], SSL},%[a]) "sob %[b],1b" setcc(%[a]) erase(%[a]) erase(%[b]) | {regconst2, %[a], SSL } | | dch | | | | loi 2 | loi $1==2 | REG | | {regdef2, %[1]} | | ... | NC regconst2 | | {regind2, %[1.reg], %[1.ind]} | | ... | NC relative2 | | {reldef2, %[1.ind]} | | ... | NC regind2 | | {reginddef2, %[1.reg], %[1.ind]} | | ... | NC regdef2 | | {reginddef2, %[1.reg], "0"}| | ... | NC ADDR_LOCAL | | {LOCAL2, %[1.ind],2} | | ... | NC ADDR_EXTERNAL | | {relative2, %[1.ind]} | | ... | NC LOCAL2 | |{reginddef2, lb, tostring(%[1.ind])}| | loi $1==1 | REG | | {regdef1, %[1]} | | ... | NC regconst2 | | {regind1, %[1.reg], %[1.ind]} | | ... | NC ADDR_EXTERNAL | | {relative1, %[1.ind]} | | ... | NC ADDR_LOCAL| |{regind1, lb, tostring(%[1.ind])} | | ... | NC relative2 | | {reldef1, %[1.ind]} | | ... | NC regind2 | | {reginddef1, %[1.reg], %[1.ind]} | | ... | NC regdef2 | | {reginddef1, %[1.reg], "0"}| | ... | NC LOCAL2 | |{reginddef1, lb, tostring(%[1.ind])} | | loi $1==4 | REG | | {regdef4, %[1]} | | ... | NC regconst2 | | {regind4, %[1.reg], %[1.ind]} | | ... | NC ADDR_LOCAL | | {LOCAL4,%[1.ind],4} | | ... | NC ADDR_EXTERNAL | | {relative4, %[1.ind]} | | loi $1==8 | REG | | {regdef8, %[1]} | | ... | NC regconst2 | | {regind8, %[1.reg], %[1.ind]} | | ... | NC ADDR_LOCAL | | {regind8, lb , tostring(%[1.ind])} | | ... | NC ADDR_EXTERNAL | | {relative8, %[1.ind]} | | loi | NC ADDR_LOCAL | remove(all) allocate(REG={CONST2,$1/2},REG) move(lb,%[b]) "add $$%(%[1.ind]+$1%),%[b]" "1:\tmov -(%[b]),-(sp)" "sob %[a],1b" erase(%[a]) erase(%[b]) | | | ... | NC ADDR_EXTERNAL | remove(all) allocate(REG={CONST2,$1/2},REG) "mov $$%[1.ind]+$1,%[b]" "1:\tmov -(%[b]),-(sp)" "sob %[a],1b" erase(%[a]) erase(%[b]) | | | ... | SCR_REG | remove(all) allocate(REG={CONST2,$1}) "add %[a],%[1]" "asr %[a]" "1:\tmov -(%[1]),-(sp)" "sob %[a],1b" erase(%[1]) erase(%[a]) | | | los $1==2 | | remove(all) "mov (sp)+,r0" "mov (sp)+,r1" "jsr pc,los2~" | | | #ifdef UNTESTED los !defined($1)| source2 | remove(all) "cmp %[1],$$2" "beq 1f;jmp unknown~;1:" "mov (sp)+,r0" "mov (sp)+,r1" "jsr pc,los2~" | | | #endif ldl | | | {LOCAL4, $1,4} | | lde | | | {relative4, $1} | | ldf | regconst2 | | {regind4,%[1.reg], tostring($1)+"+"+%[1.ind]} | | ... | NC ADDR_EXTERNAL | | {relative4, tostring($1)+"+"+%[1.ind]} | | ... | NC ADDR_LOCAL | | {LOCAL4, %[1.ind]+$1,4} | | lpi | | | {ADDR_EXTERNAL, $1} | | /**************************************************************** * Group 2 : Store instructions. * * * * These instructions are likely to ruin the fake-stack. * * We don't expect many items on the fake-stack anyway * * because we seem to have evaluated an expression just now. * ****************************************************************/ #ifdef REGVARS stl inreg($1)==2| xsource2 | remove(regvar($1)) move(%[1],regvar($1)) | | | #endif stl | xsource2 | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) move(%[1],{LOCAL2,$1,2}) | | | ste | xsource2 | remove(posextern) move(%[1], {relative2, $1 }) | | | #ifdef REGVARS sil inreg($1)==2| xsource2 | INDSTORE move(%[1], {regdef2,regvar($1)}) | | | #endif sil | xsource2 | INDSTORE move(%[1], {reginddef2,lb,tostring($1)}) | | | stf | regconst2 xsource2 | INDSTORE move(%[2],{regind2,%[1.reg],tostring($1)+"+"+%[1.ind]}) | | | ... | ADDR_EXTERNAL xsource2 | INDSTORE move(%[2],{relative2,tostring($1)+"+"+%[1.ind]})| | | #ifdef REGVARS lol stf inreg($1)!=2 | xsource2 | INDSTORE allocate(REG={LOCAL2, $1,2}) move(%[1],{regind2,%[a],tostring($2)}) | | | lae lol ads sti $3==2 && inreg($2)==2 | | | {regconst2, regvar($2), $1} | sti $4 | lae lol ads loi $3==2 && inreg($2)==2 | | | {regconst2, regvar($2), $1} | loi $4 | #endif sti $1==2 | REG xsource2 | INDSTORE move(%[2],{regdef2,%[1]}) | | | ... | regconst2 xsource2 | INDSTORE move(%[2],{regind2,%[1.reg],%[1.ind]}) | | | ... | ADDR_EXTERNAL xsource2 | INDSTORE move(%[2],{relative2,%[1.ind]}) | | | ... | ADDR_LOCAL xsource2 | INDSTORE move(%[2],{LOCAL2, %[1.ind], 2}) | | | ... | relative2 xsource2 | INDSTORE move(%[2],{reldef2,%[1.ind]}) | | | ... | regind2 xsource2 | INDSTORE move(%[2],{reginddef2,%[1.reg],%[1.ind]}) | | | sti $1==1 | REG source1or2 | INDSTORE move(%[2],{regdef1,%[1]}) | | | ... | regconst2 source1or2 | INDSTORE move(%[2],{regind1,%[1.reg],%[1.ind]}) | | | ... | ADDR_EXTERNAL source1or2 | INDSTORE move(%[2],{relative1,%[1.ind]}) | | | ... | ADDR_LOCAL source1or2 | INDSTORE move(%[2],{regind1, lb, tostring(%[1.ind])}) | | | ... | relative2 source1or2 | INDSTORE move(%[2],{reldef1,%[1.ind]}) | | | ... | regind2 source1or2 | INDSTORE move(%[2],{reginddef1,%[1.reg],%[1.ind]}) | | | sti $1==4 | dadres2 FLT_REG | INDSTORE "movfo %[2],*%[1]" samecc | | | ... | dadres2 ftolong | INDSTORE "setl\nmovfi %[2.reg],*%[1]\nseti" samecc | | | ... | regconst2 FLT_REG | INDSTORE "movfo %[2],%[1.ind](%[1.reg])" samecc | | | ... | regconst2 ftolong | INDSTORE "setl\nmovfi %[2.reg],%[1.ind](%[1.reg])\nseti" samecc | | | ... | ADDR_LOCAL FLT_REG | INDSTORE "movfo %[2],%[1.ind](r5)" samecc | | | ... | ADDR_LOCAL ftolong | INDSTORE "setl\nmovfi %[2.reg],%[1.ind](r5)\nseti" samecc | | | ... | ADDR_EXTERNAL FLT_REG | INDSTORE "movfo %[2],%[1.ind]" samecc | | | ... | ADDR_EXTERNAL ftolong | INDSTORE "setl\nmovfi %[2.reg],%[1.ind]\nseti" samecc | | | ... | REG source2 source2 | INDSTORE move(%[2],{regdef2,%[1]}) move(%[3],{regind2,%[1],"2"}) | | | ... | SCR_REG STACK | "mov (sp)+,(%[1])+" "mov (sp)+,(%[1])" erase(%[1]) | | | (4,2040) sti $1==8 | dadres2 DBL_REG | INDSTORE "movf %[2],*%[1]" samecc | | | ... | regconst2 DBL_REG | INDSTORE "movf %[2],%[1.ind](%[1.reg])" samecc | | | ... | ADDR_LOCAL DBL_REG | INDSTORE "movf %[2],%[1.ind](r5)" samecc | | | ... | ADDR_EXTERNAL DBL_REG | INDSTORE "movf %[2],%[1.ind]" samecc | | | ... | SCR_REG regind8 | INDSTORE "mov %[2.ind](%[2.reg]),(%[1])+" "mov 2+%[2.ind](%[2.reg]),(%[1])+" "mov 4+%[2.ind](%[2.reg]),(%[1])+" "mov 6+%[2.ind](%[2.reg]),(%[1])" erase(%[1]) | | | ... | SCR_REG relative8 | INDSTORE allocate(REG={ADDR_EXTERNAL,%[2.ind]}) "mov (%[a])+,(%[1])+" "mov (%[a])+,(%[1])+" "mov (%[a])+,(%[1])+" "mov (%[a]),(%[1])" erase(%[1]) erase(%[a]) | | | ... | SCR_REG | remove(all) "mov (sp)+,(%[1])+" "mov (sp)+,(%[1])+" "mov (sp)+,(%[1])+" "mov (sp)+,(%[1])" erase(%[1]) | | | (8,4080) sti | SCR_REG | remove(all) allocate(REG={CONST2,$1/2}) "1:\tmov (sp)+,(%[1])+" "sob %[a],1b" erase(%[1]) erase(%[a]) | | | (8,1500+$1*825) lal sti $2>2 && $2<=8 | NC xsource2 | | %[1] | stl $1 lal $1+2 sti $2-2 | ... | | | {ADDR_LOCAL,$1} | sti $2 | sts $1==2 | | remove(all) "mov (sp)+,r0" "mov (sp)+,r1" "jsr pc,sto2~" erase(r01) | | | sdl | NC FLT_REG | remove(indordef) remove(locals, %[ind] <= $1+2 && %[ind]+%[size] > $1) move(%[1],{LOCAL4,$1,4}) | | | ... | NC ftolong | remove(indordef) remove(locals, %[ind] <= $1+2 && %[ind]+%[size] > $1) "setl\nmovfi %[1.reg],$1(r5)\nseti" samecc | | | ... | source2 source2 | remove(indordef) remove(locals, %[ind] <= $1+2 && %[ind]+%[size] > $1) move(%[1],{LOCAL2,$1,2}) move(%[2],{LOCAL2,$1+2,2}) | | | sde | NC FLT_REG | remove(posextern) move(%[1],{relative4,$1}) | | | ... | NC ftolong | remove(posextern) "setl\nmovfi %[1.reg],$1\nseti" samecc | | | ... | source2 source2 | remove(posextern) move(%[1], {relative2, $1 }) move(%[2], {relative2, $1+"+2" }) | | | sdf | NC regconst2 FLT_REG | INDSTORE move(%[2],{regind4,%[1.reg],tostring($1)+"+"+%[1.ind]}) | | | ... | NC regconst2 ftolong | INDSTORE "setl\nmovfi %[2.reg],$1+%[1.ind](%[1.reg])\nseti" samecc | | | ... | NC ADDR_EXTERNAL FLT_REG | INDSTORE move(%[2],{relative4,tostring($1)+"+"+%[1.ind]})| | | ... | NC ADDR_EXTERNAL ftolong | INDSTORE "setl\nmovfi %[2.reg],$1+%[1.ind]\nseti" samecc | | | ... | regconst2 source2 source2 | INDSTORE move(%[2],{regind2,%[1.reg],tostring($1)+"+"+%[1.ind]}) move(%[3],{regind2,%[1.reg],tostring($1+2)+"+"+%[1.ind]}) | | | ... | ADDR_EXTERNAL source2 source2 | INDSTORE move(%[2],{relative2,tostring($1)+"+"+%[1.ind]}) move(%[3],{relative2,tostring($1+2)+"+"+%[1.ind]}) | | | /**************************************************************** * Group 3 : Integer arithmetic. * * * * Implemented (sometimes with the use of subroutines) : * * all 2 and 4 byte arithmetic. * ****************************************************************/ adi $1==2 | NC SCR_REG CONST2 | | {regconst2,%[1],tostring(%[2.num])} | | ... | NC SCR_REG ADDR_EXTERNAL | | {regconst2,%[1],%[2.ind]} | | ... | NC SCR_REG ADDR_LOCAL | "add r5,%[1]" erase(%[1]) | {regconst2,%[1],tostring(%[2.ind])} | | (2,450) ... | NC REG ADDR_LOCAL | allocate(REG) "mov r5,%[a]" "add %[1],%[a]" erase(%[a]) | {regconst2,%[a],tostring(%[2.ind])} | | (4,900) ... | NC SCR_REG regconst2 | "add %[2.reg],%[1]" erase(%[1]) | {regconst2,%[1],%[2.ind]} | | (2,450) ... | NC CONST2+ADDR_EXTERNAL+ADDR_LOCAL+regconst2 SCR_REG | | %[1] %[2] | adi 2 | ... | NC source2-REG CONST2+ADDR_EXTERNAL+ADDR_LOCAL | allocate(%[1],REG=%[1]) | %[2] %[a] | adi 2 | ... | NC regconst2 CONST2 | | {regconst2,%[1.reg], tostring(%[2.num])+"+"+%[1.ind]} | | ... | NC regconst2 ADDR_EXTERNAL | | {regconst2,%[1.reg], %[2.ind]+"+"+%[1.ind]} | | ... | NC regconst2 ADDR_LOCAL | "add r5,%[1.reg]" erase(%[1.reg]) | {regconst2,%[1.reg], tostring(%[2.ind])+"+"+%[1.ind]} | | (2,450) ... | NC regconst2 regconst2 | "add %[2.reg],%[1.reg]" erase(%[1.reg]) | {regconst2,%[1.reg],%[2.ind]+"+"+%[1.ind]} | | (2,450) ... | NC regconst2 noconst2 | "add %[2],%[1.reg]" erase(%[1.reg]) | %[1] | | (2,450)+%[2] ... | NC SCR_REG noconst2 | "add %[2],%[1]" setcc(%[1]) erase(%[1]) | %[1] | | (2,450)+%[2] ... | NC source2 regconst2 | "add %[1],%[2.reg]" erase(%[2.reg]) | %[2] | | (2,450)+%[1] ... | NC regconst2 source2 | "add %[2],%[1.reg]" erase(%[1.reg]) | %[1] | | (2,450)+%[2] ... | source2 SCR_REG | "add %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | (2,450)+%[1] ldc adi $2==4 && highw(1)==0 | SCR_REG SCR_REG | "add $$%(loww(1)%),%[2]" "adc %[1]" erase(%[1]) erase(%[2]) | %[2] %[1] | | ldc adi $2==4 | SCR_REG SCR_REG | "add $$%(loww(1)%),%[2]" "adc %[1]" "add $$%(highw(1)%),%[1]" erase(%[1]) erase(%[2]) | %[2] %[1] | | adi $1==4 | SCR_REG SCR_REG source2 source2 | "add %[4],%[2]" "adc %[1]" "add %[3],%[1]" setcc(%[1]) erase(%[1]) erase(%[2]) | %[2] %[1] | | (6,1200)+%[4]+%[3] ... | SCR_REG SCR_REG source2 STACK | "add (sp)+,%[2]" "adc %[1]" "add %[3],%[1]" setcc(%[1]) erase(%[1]) erase(%[2]) | %[2] %[1] | | (6,1900)+%[3] ... | SCR_REG SCR_REG STACK | "add (sp)+,%[1]" "add (sp)+,%[2]" "adc %[1]" setcc(%[1]) erase(%[1]) erase(%[2]) | %[2] %[1] | | (6,2800) ... | source2 source2 SCR_REG SCR_REG | "add %[2],%[4]" "adc %[3]" "add %[1],%[3]" setcc(%[3]) erase(%[3]) erase(%[4]) | %[4] %[3] | | (6,1200)+%[1]+%[2] #ifdef UNTESTED adi !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,adi~" | | | #endif loc sbi $2==2 | | | | loc 0-$1 adi 2 | sbi $1==2 | source2 SCR_REG | "sub %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | (2,450)+%[1] ... | NC SCR_REG source2-REG | "sub %[2],%[1]" "neg %[1]" setcc(%[1]) erase(%[1]) | %[1] | | (4,750)+%[2] ldc sbi $2==4 && highw(1)==0 | SCR_REG SCR_REG | "sub $$%(loww(1)%),%[2]" "sbc %[1]" erase(%[1]) erase(%[2]) | %[2] %[1] | | ldc sbi $2==4 | SCR_REG SCR_REG | "sub $$%(loww(1)%),%[2]" "sbc %[1]" "sub $$%(highw(1)%),%[1]" erase(%[1]) erase(%[2]) | %[2] %[1] | | sbi $1==4 | source2-REG source2-REG SCR_REG SCR_REG | "sub %[2],%[4]" "sbc %[3]" "sub %[1],%[3]" setcc(%[3]) erase(%[3]) erase(%[4]) | %[4] %[3] | | (6,1200)+%[1]+%[2] ... | source2 source2 STACK | "sub %[2],2(sp)" "sbc (sp)" "sub %[1],(sp)" | | | (10,2800)+%[1]+%[2] #ifdef UNTESTED sbi !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,sbi~" | | | #endif mli $1==2 | SCR_ODD_REG source2 | "mul %[2],%[1]" setcc(%[1]) erase(%[1]) | %[1] | |(2,3300)+%[2] ... | source2 SCR_ODD_REG | "mul %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | |(2,3300)+%[1] mli $1==4 | | remove(all) "jsr pc,mli4~" | r1 r0 | | #ifdef UNTESTED mli !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,mli~" | | | #endif dvi $1==2 | source2 source2 | allocate(%[2],REG_PAIR) "mov %[2],%[a.2]" "sxt %[a.1]" "div %[1],%[a.1]" | %[a.1] | | ... | source2 source2 | INDSTORE "mov %[1],-(sp)" "mov %[2],r1" "sxt r0" "div (sp)+,r0" | r0 | |(100,10000) dvi $1==4 | | remove(all) "jsr pc,dvi4~" | r1 r0 | | #ifdef UNTESTED dvi !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,dvi~" | | | #endif rmi $1==2 | source2 source2 | allocate(%[2],REG_PAIR) "mov %[2],%[a.2]" "sxt %[a.1]" "div %[1],%[a.1]" | %[a.2] | | ... | source2 source2 | INDSTORE "mov %[1],-(sp)" "mov %[2],r1" "sxt r0" "div (sp)+,r0" | r1 | |(100,10000) rmi $1==4 | | remove(all) "jsr pc,rmi4~" | r1 r0 | | #ifdef UNTESTED rmi !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,rmi~" | | | #endif ngi $1==2 | SCR_REG | "neg %[1]" setcc(%[1]) erase(%[1]) | %[1] | | (2,750) ngi $1==4 | SCR_REG SCR_REG | "neg %[1]" "neg %[2]" "sbc %[1]" setcc(%[1]) erase(%[1]) erase(%[2]) | %[2] %[1] | | (6,1800) #ifdef UNTESTED ngi !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,ngi~" | | | #endif loc sli $1==1 && $2==2 | SCR_REG | "asl %[1]" setcc(%[1]) erase(%[1]) | %[1]| | sli $1==2 | source2 SCR_REG | "ash %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | sli $1==4 | source2 SCR_REG_PAIR | "ashc %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | #ifdef UNTESTED sli !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,sli~" | | | #endif loc sri $1==1 && $2==2 | SCR_REG | "asr %[1]" setcc(%[1]) erase(%[1]) | %[1]| | loc sri $2==2 | SCR_REG | "ash $$%(0-$1%),%[1]" setcc(%[1]) erase(%[1]) | %[1]| | sri $1==2 | SCR_REG SCR_REG | "neg %[1]" "ash %[1], %[2]" setcc(%[2]) erase(%[1]) erase(%[2]) | %[2] | | loc sri $2==4 | SCR_REG_PAIR | "ashc $$%(0-$1%),%[1]" setcc(%[1]) erase(%[1]) | %[1] | | sri $1==4 | SCR_REG SCR_REG_PAIR | "neg %[1]" "ashc %[1],%[2]" setcc(%[2]) erase(%[1]) erase(%[2]) | %[2] | | #ifdef UNTESTED sri !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,sri~" | | | #endif /************************************************ * Group 4 : unsigned arithmetic * * * * adu = adi * * sbu = sbi * * slu = sli * * * * Supported : 2- and 4 byte arithmetic. * ************************************************/ adu | | | | adi $1 | sbu | | | | sbi $1 | mlu $1==2 | | | | mli $1 | mlu $1==4 | | remove(all) "jsr pc,mlu4~" | r1 r0 | | #ifdef UNTESTED mlu !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,mlu~" | | | #endif dvu $1==2 | | remove(all) "jsr pc,dvu2~" | r0 | | dvu $1==4 | | remove(all) "jsr pc,dvu4~" | r1 r0 | | #ifdef UNTESTED dvu !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,dvu~" | | | #endif rmu $1==2 | | remove(all) "jsr pc,rmu2~" | r1 | | rmu $1==4 | | remove(all) "jsr pc,rmu4~" | r1 r0 | | #ifdef UNTESTED rmu !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,rmu~" | | | #endif slu | | | | sli $1 | loc slu | | | | loc $1 sli $2 | sru $1==2 | SCR_REG xsource2 | allocate(%[2],REG_PAIR) move(%[2],%[a.2]) move({CONST2,0},%[a.1]) "neg %[1]" "ashc %[1],%[a]" erase(%[a]) | %[a.2] | | loc sru $2==2 | xsource2 | allocate(%[1],REG_PAIR) move(%[1],%[a.2]) move({CONST2,0},%[a.1]) "ashc $$%(0-$1%),%[a]" erase(%[a]) | %[a.2] | | sru $1==4 | | remove(all) move({CONST2,$1},r0) "jsr pc,sru~" erase(r0) | | | #ifdef UNTESTED sru !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,sru~" | | | #endif /************************************************ * Group 5 : Floating point arithmetic * * * * Supported : 4- and 8 byte arithmetic. * ************************************************/ adf $1==4 | FLT_REG SCR_FLT_REG | "addf %[1],%[2]" samecc erase(%[2]) | %[2] | | (2,5000)+%[1] ... | SCR_FLT_REG FLT_REG | "addf %[2],%[1]" samecc erase(%[1]) | %[1] | | (2,5000)+%[2] adf $1==8 | double8 SCR_DBL_REG | "addf %[1],%[2]" samecc erase(%[2]) | %[2] | | (2,6000)+%[1] ... | SCR_DBL_REG double8 | "addf %[2],%[1]" samecc erase(%[1]) | %[1] | | (2,6000)+%[2] #ifdef UNTESTED adf !defined($1)| source2 | remove(ALL) move(%[1],r0) "jsr pc,adf~" | | | #endif sbf $1==4 | FLT_REG SCR_FLT_REG | "subf %[1],%[2]" samecc erase(%[2]) | %[2] | | (2,5000)+%[1] sbf $1==8 | double8 SCR_DBL_REG | "subf %[1],%[2]" samecc erase(%[2]) | %[2] | | (2,6000)+%[1] #ifdef UNTESTED sbf !defined($1)| source2 | remove(ALL) move(%[1],r0) "jsr pc,sbf~" | | | #endif mlf $1==4 | FLT_REG SCR_FLT_REG | "mulf %[1],%[2]" samecc erase(%[2]) | %[2] | | (2,7000)+%[1] ... | SCR_FLT_REG FLT_REG | "mulf %[2],%[1]" samecc erase(%[1]) | %[1] | | (2,7000)+%[2] mlf $1==8 | double8 SCR_DBL_REG | "mulf %[1],%[2]" samecc erase(%[2]) | %[2] | | (2,10000)+%[1] ... | SCR_DBL_REG double8 | "mulf %[2],%[1]" samecc erase(%[1]) | %[1] | | (2,10000)+%[2] #ifdef UNTESTED mlf !defined($1)| source2 | remove(ALL) move(%[1],r0) "jsr pc,mlf~" | | | #endif dvf $1==4 | FLT_REG SCR_FLT_REG | "divf %[1],%[2]" samecc erase(%[2]) | %[2] | | (2,8000)+%[1] dvf $1==8 | double8 SCR_DBL_REG | "divf %[1],%[2]" samecc erase(%[2]) | %[2] | | (2,12000)+%[1] #ifdef UNTESTED dvf !defined($1)| source2 | remove(ALL) move(%[1],r0) "jsr pc,dvf~" | | | #endif ngf $1==4 | SCR_FLT_REG | "negf %[1]" samecc erase(%[1]) | %[1] | |(2,2700) ngf $1==8 | SCR_DBL_REG | "negf %[1]" samecc erase(%[1]) | %[1] | |(2,2700) #ifdef UNTESTED ngf !defined($1)| source2 | remove(ALL) move(%[1],r0) "jsr pc,ngf~" | | | #endif fif $1==4 | longf4 FLT_REG | allocate(FLT_REG_PAIR) move(%[1],%[a.1]) "modf %[2],%[a]" samecc erase(%[a.1]) | %[a.1] %[a.2] | | (2,7500)+%[2] fif $1==8 | double8 double8 | allocate(DBL_REG_PAIR) move(%[1],%[a.1]) "modf %[2],%[a]" samecc erase(%[a.1]) | %[a.1] %[a.2] | | (2,15000)+%[2] #ifdef UNTESTED fif !defined($1)| source2 | remove(ALL) move(%[1],r0) "jsr pc,fif~" | | | #endif fef $1==4 | FLT_REG | allocate(REG) "movei %[1],%[a]" "movie $$0,%[1]" samecc erase(%[1]) |%[1] %[a] | | (4,5000) fef $1==8 | DBL_REG | allocate(REG) "movei %[1],%[a]" "movie $$0,%[1]" samecc erase(%[1]) |%[1] %[a] | | (4,5000) #ifdef UNTESTED fef !defined($1)| source2 | remove(ALL) move(%[1],r0) "jsr pc,fef~" | | | #endif /**************************************** * Group 6 : pointer arithmetic. * * * * Pointers have size 2 bytes. * ****************************************/ adp | SCR_REG | | {regconst2, %[1], tostring($1)} | | ... | NC regconst2 | | {regconst2, %[1.reg], tostring($1)+"+"+%[1.ind]} | | ... | NC ADDR_EXTERNAL | | {ADDR_EXTERNAL, tostring($1)+"+"+%[1.ind]} | | ... | NC ADDR_LOCAL | | {ADDR_LOCAL,%[1.ind]+$1} | | ads $1==2 | | | | adi $1 | sbs $1==2 | | | | sbi $1 | /**************************************** * Group 7 : increment/decrement/zero * ****************************************/ inc | SCR_REG | "inc %[1]" setcc(%[1]) erase(%[1]) | %[1] | | #ifdef REGVARS inl inreg($1)==2| | remove(regvar($1)) "inc %(regvar($1)%)" erase(regvar($1)) | | | #endif inl | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "inc $1(r5)" setcc({LOCAL2,$1,2}) | | | ldl ldc adi sdl $1==$4 && $3==4 && highw(2)==0 | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "add $$%(loww(2)%),2+$1(r5)" "adc $1(r5)" | | | ldl ldc adi sdl $1==$4 && $3==4 | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "add $$%(loww(2)%),2+$1(r5)" "adc $1(r5)" "add $$%(highw(2)%),$1(r5)" | | | ine | | remove(posextern) "inc $1" setcc({relative2,$1}) | | | lde ldc adi sde $1==$4 && $3==4 && highw(2)==0 | | remove(posextern) "add $$%(loww(2)%),2+$1" "adc $1" | | | lde ldc adi sde $1==$4 && $3==4 | | remove(posextern) "add $$%(loww(2)%),2+$1" "adc $1" "add $$%(highw(2)%),$1" | | | dec | SCR_REG | "dec %[1]" setcc(%[1]) erase(%[1]) | %[1] | | #ifdef REGVARS del inreg($1)==2| | remove(regvar($1)) "dec %(regvar($1)%)" erase(regvar($1)) | | | #endif del | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "dec $1(r5)" setcc({LOCAL2,$1,2}) | | | dee | | remove(posextern) "dec $1" setcc({relative2,$1}) | | | (4,900) #ifdef REGVARS lol loc sbi stl $1==$4 && $3==2 && inreg($1)==2 | | remove(regvar($1)) "sub $$$2,%(regvar($1)%)" erase(regvar($1)) | | | lol ngi stl $1==$3 && $2==2 && inreg($1)==2 | | remove(regvar($1)) "neg %(regvar($1)%)" erase(regvar($1)) | | | lil ngi sil $1==$3 && $2==2 && inreg($1)==2 | | INDSTORE "neg *%(regvar($1)%)" | | | lil inc sil $1==$3 && inreg($1)==2 | | INDSTORE "inc *%(regvar($1)%)" | | | lol adi stl $2==2 && $1==$3 && inreg($1)==2 | source2 | remove(regvar($1)) "add %[1],%(regvar($1)%)" erase(regvar($1)) | | | lol lol adp stl loi $1==$2 && $2==$4 && inreg($1)==2 && $3==1 && $5==1 | | allocate(REG={CONST2, 0}) remove(regvar($1)) "bisb (%(regvar($1)%))+,%[a]" | %[a] | | lol lol adp stl loi $1==$2 && $2==$4 && inreg($1)==2 && $3==2 && $5==2 | | allocate(REG) remove(regvar($1)) "mov (%(regvar($1)%))+,%[a]" | %[a] | | lol lol adp stl sti $1==$2 && $2==$4 && inreg($1)==2 && $3==1 && $5==1 | source1or2| remove(regvar($1)) "movb %[1],(%(regvar($1)%))+" | | | lol lol adp stl sti $1==$2 && $2==$4 && inreg($1)==2 && $3==2 && $5==2 | source2 | remove(regvar($1)) "mov %[1],(%(regvar($1)%))+" | | | lol lol adp stl $1==$2 && $2==$4 && inreg($1)==2 | | allocate(REG=regvar($1)) | %[a] | lol $2 adp $3 stl $2 | lol lol adp stl $1==$2 && $2==$4 | | allocate(REG={LOCAL2, $1, 2}) | %[a] | lol $2 adp $3 stl $2 | lol inl $1==$2 && inreg($1)==2 | | allocate(REG=regvar($1)) | %[a] | inl $2 | lol inl $1==$2 | | allocate(REG={LOCAL2, $1, 2}) | %[a] | inl $2 | lol adp dup stl $1==$4 && $3==2 && inreg($1)==2 | | | | lol $1 adp $2 stl $1 lol $1 | lol adp stl $1==$3 && $2==1 && inreg($1)==2 | | remove(regvar($1)) "inc %(regvar($1)%)" erase(regvar($1)) | | | lol adp stl $1==$3 && $2==0-1 && inreg($1)==2 | | remove(regvar($1)) "dec %(regvar($1)%)" erase(regvar($1)) | | | lol adp stl $1==$3 && inreg($1)==2 | | remove(regvar($1)) "add $$$2,%(regvar($1)%)" erase(regvar($1)) | | | #endif lol loc sbi stl $1==$4 && $3==2 | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "sub $$$2,$1(r5)" setcc({LOCAL2,$1,2}) | | | lol ngi stl $1==$3 && $2==2 | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "neg $1(r5)" setcc({LOCAL2,$1,2}) | | | lil ngi sil $1==$3 && $2==2 | | INDSTORE "neg *$1(r5)" | | | lil inc sil $1==$3 | | INDSTORE "inc *$1(r5)" | | | lol adi stl $2==2 && $1==$3 | source2 | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "add %[1],$1(r5)" setcc({LOCAL2,$1,2}) | | | lol adp stl $1==$3 && $2==1 | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "inc $1(r5)" setcc({LOCAL2,$1,2}) | | | lol adp stl $1==$3 && $2==0-1 | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "dec $1(r5)" setcc({LOCAL2,$1,2}) | | | lol adp stl $1==$3 | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "add $$$2,$1(r5)" setcc({LOCAL2,$1,2}) | | | loe adi ste $2==2 && $1==$3 | source2 | remove(posextern) "add %[1],$1" setcc({relative2,$1}) | | | loe adp ste $1==$3 && $2==1 | | remove(posextern) "inc $1" setcc({relative2,$1}) | | | loe adp ste $1==$3 && $2==0-1 | | remove(posextern) "dec $1" setcc({relative2,$1}) | | | loe adp ste $1==$3 | | remove(posextern) "add $$$2,$1" setcc({relative2,$1}) | | | #ifdef REGVARS lol ior stl $2==2 && $1==$3 && inreg($1)==2 | source2 | remove(regvar($1)) "bis %[1],%(regvar($1)%)" erase(regvar($1)) | | | #endif lol ior stl $2==2 && $1==$3 | source2 | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "bis %[1],$1(r5)" setcc({LOCAL2,$1,2}) | | | loe ior ste $2==2 && $1==$3 | source2 | remove(posextern) "bis %[1],$1" setcc({relative2,$1}) | | | #ifdef REGVARS lol and stl $2==2 && $1==$3 && inreg($1)==2 | SCR_REG | remove(regvar($1)) "com %[1]" "bic %[1],%(regvar($1)%)" erase(%[1]) erase(regvar($1)) | | | #endif lol and stl $2==2 && $1==$3 | SCR_REG | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "com %[1]" "bic %[1],$1(r5)" erase(%[1]) setcc({LOCAL2,$1,2}) | | | loe and ste $2==2 && $1==$3 | SCR_REG | remove(posextern) "com %[1]" "bic %[1],$1" erase(%[1]) setcc({relative2,$1}) | | | #ifdef REGVARS loc lol and stl $3==2 && $2==$4 && inreg($2)==2 | | remove(regvar($2)) "bic $$%(~$1%),%(regvar($2)%)" erase(regvar($2)) | | | #endif loc lol and stl $3==2 && $2==$4 | | remove(indordef) remove(locals, %[ind] <= $2 && %[ind]+%[size] > $2) "bic $$%(~$1%),$2(r5)" setcc({LOCAL2,$2,2}) | | | loc loe and ste $3==2 && $2==$4 | | remove(posextern) "bic $$%(~$1%),$2" setcc({relative2,$2}) | | | #ifdef REGVARS zrl inreg($1)==2| | remove(regvar($1)) "clr %(regvar($1)%)" erase(regvar($1)) | | | (4,900) #endif zrl | | remove(indordef) remove(locals, %[ind] <= $1 && %[ind]+%[size] > $1) "clr $1(r5)" setcc({LOCAL2,$1,2}) | | | (4,900) zre | | remove(posextern) "clr $1" setcc({relative2,$1}) | | | (4,900) zrf $1==4 | | allocate(FLT_REG) "clrf %[a]" | %[a] | | (2,2200) zrf $1==8 | | allocate(DBL_REG) "clrf %[a]" | %[a] | | (2,2400) zrf !defined($1)| | | | zer | zrf defined($1) | | | | zer $1 | zer $1==2 | | | {CONST2, 0} | | zer $1==4 | | | {CONST2,0} {CONST2,0} | | zer $1==6 | | | {CONST2,0} {CONST2,0} {CONST2,0} | | zer $1==8 | | | {CONST2,0} {CONST2,0} {CONST2, 0} {CONST2,0} | | zer defined($1) | | remove(all) move({CONST2,$1/2},r0) "1:\tclr -(sp)" "sob r0,1b" erase(r0) | | |(8,1500+$1*375) zer !defined($1)| SCR_REG | remove(all) "asr %[1]" "1:\tclr -(sp)" "sob %[1],1b" erase(%[1]) | | | /**************************************** * Group 8 : Convert instructions * ****************************************/ #ifdef UNTESTED cii | | remove(all) "jsr pc,cii~" | | | cfi | | | | cfu | cfu | | remove(ALL) "jsr pc,cfi~" | | | cif | | remove(ALL) "jsr pc,cif~" | | | cuf | | remove(ALL) "jsr pc,cuf~" | | | cff | | remove(ALL) "jsr pc,cff~" | | | ciu | | | | cuu | cui | | | | cuu | cuu | | remove(all) "jsr pc,cuu~" | | | #endif loc loc cii $1==1 && $2==2 | source1or2 | allocate(%[1],REG) "movb %[1],%[a]" /* movb does sign extend if dest is register */ | %[a] | | loc loc cii $1==1 && $2==4 | source1or2 | allocate(%[1],REG,REG) "movb %[1],%[a]" "sxt %[b]" | %[a] %[b] | | loc loc cii $1==2 && $2==4 | source2 | allocate(%[1],REG,REG) move(%[1],%[a]) test(%[a]) "sxt %[b]" | %[a] %[b] | | loc loc loc cii $1>=0 && $2==2 && $3==4 | | | | loc $1 loc 0 | loc loc loc cii $1< 0 && $2==2 && $3==4 | | | | loc $1 loc 0-1 | loc loc cii $1==4 && $2==2 | source2 source2 | | %[2] | | loc loc ciu | | | | loc $1 loc $2 cuu | loc loc cui | | | | loc $1 loc $2 cuu | loc loc cuu $1==2 && $2==4 | | | {CONST2,0} | | loc loc cuu $1==4 && $2==2 | source2 | | | | loc loc cfi | | | | loc $1 loc $2 cfu | loc loc cfu $1==4 && $2==2 | FLT_REG | | {ftoint,%[1]} | | loc loc cfu $1==4 && $2==4 | FLT_REG | | {ftolong,%[1]} | | loc loc cfu $1==8 && $2==2 | DBL_REG | | {ftoint,%[1]} | | loc loc cfu $1==8 && $2==4 | DBL_REG | | {ftolong,%[1]} | | loc loc cif $1==2 && $2==4 | source2 | allocate(FLT_REG) "movif %[1],%[a]" samecc | %[a] | | loc loc cif $1==2 && $2==8 | source2 | allocate(DBL_REG) "movif %[1],%[a]" samecc | %[a] | | loc loc cif $1==4 && $2==4 | NC long4-REG_PAIR | allocate(FLT_REG) "setl" "movif %[1],%[a]" "seti" samecc | %[a] | | ... | | remove(all) allocate(FLT_REG) "setl" "movif (sp)+,%[a]" "seti" samecc | %[a] | | loc loc cif $1==4 && $2==8 | NC long4-REG_PAIR | allocate(DBL_REG) "setl" "movif %[1],%[a]" "seti" samecc | %[a] | | ... | | remove(all) allocate(DBL_REG) "setl" "movif (sp)+,%[a]" "seti" samecc | %[a] | | loc loc cuf $1==2 && $2==4 | | remove(all) allocate(FLT_REG) "clr -(sp)" "setl" "movif (sp)+,%[a]" "seti" | %[a] | | loc loc cuf $1==2 && $2==8 | | remove(all) allocate(DBL_REG) "clr -(sp)" "setl" "movif (sp)+,%[a]" "seti" | %[a] | | loc loc cuf $1==4 && ($2==8 || $2==4) | | | | loc $1 loc $2 cif | loc loc cff $1==4 && $2==8 | longf4 - FLT_REG | allocate(DBL_REG) "movof %[1],%[a]" samecc | %[a] | | ... | FLT_REG | allocate(DBL_REG) move(%[1],%[a.1]) samecc | %[a] | | loc loc cff $1==8 && $2==4 | DBL_REG | | %[1.1] | | /**************************************** * Group 9 : Logical instructions * ****************************************/ and $1==2 | CONST2 SCR_REG | "bic $$%(~%[1.num]%),%[2]" setcc(%[2]) erase(%[2]) | %[2] | | (4,750) ... | SCR_REG CONST2 | "bic $$%(~%[2.num]%),%[1]" setcc(%[1]) erase(%[1]) | %[1] | | (4,750) ... | SCR_REG SCR_REG | "com %[1]" "bic %[1],%[2]" setcc(%[2]) erase(%[1]) erase(%[2]) | %[2] | | (4,600) and defined($1) | | remove(all) move({CONST2,$1}, r0) "jsr pc,and~" erase(r0) | | | #ifdef UNTESTED and !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,and~" erase(r0) | | | #endif ior $1==2 | SCR_REG source2 | "bis %[2],%[1]" setcc(%[1]) erase(%[1]) | %[1] | | (2,450)+%[2] ... | source2 SCR_REG | "bis %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | (2,450)+%[1] ior $1==8 | NC source2 source2 source2 source2 | remove(all) "bis %[1],(sp)" "bis %[2],2(sp)" "bis %[3],4(sp)" "bis %[4],6(sp)" | | | ... | | remove(all) allocate(REG={CONST2,$1}) "add sp,%[a]" "bis (sp)+,(%[a])+" "bis (sp)+,(%[a])+" "bis (sp)+,(%[a])+" "bis (sp)+,(%[a])+" erase(%[a]) | | | ior defined($1) | | remove(all) allocate(REG={CONST2,$1},REG={CONST2,$1/2}) "add sp,%[a]" "1:\tbis (sp)+,(%[a])+" "sob %[b],1b" erase(%[a]) erase(%[b]) | | | (12,2100+$1*975) #ifdef UNTESTED ior !defined($1)| SCR_REG | remove(all) allocate(REG=%[1]) "asr %[1]" "add sp,%[a]" "1:\tbis (sp)+,(%[a])+" "sob %[1],1b" erase(%[1]) erase(%[a]) | | | #endif xor $1==2 | REG SCR_REG | "xor %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | (2,300) ... | SCR_REG REG | "xor %[2],%[1]" setcc(%[1]) erase(%[1]) | %[1] | | (2,300) xor defined($1) | | remove(all) move({CONST2,$1},r0) "jsr pc,xor~" erase(r0) | | | #ifdef UNTESTED xor !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,xor~" erase(r0) | | | #endif com $1==2 | SCR_REG | "com %[1]" setcc(%[1]) erase(%[1]) | %[1] | | (2,300) com defined($1) | | remove(all) allocate(REG={CONST2,$1/2},REG) "mov sp,%[b]" "1:\tcom (%[b])+" "sob %[a],1b" erase(%[a]) | | | (10,1800+$1*825) #ifdef UNTESTED com !defined($1)| SCR_REG | remove(all) allocate(REG) "asr %[1]" "mov sp,%[a]" "1:\tcom (%[a])+" "sob %[1],1b" erase(%[1]) | | | #endif rol $1==2 | CONST2 SCR_ODD_REG | "ashc $$%(%[1.num]-16%),%[2]" setcc(%[2]) erase(%[2]) | %[2] | | ... | SCR_REG SCR_ODD_REG | "sub $$16,%[1]" "ashc %[1],%[2]" setcc(%[2]) erase(%[1]) erase(%[2]) | %[2] | | rol defined($1) | | remove(all) move({CONST2,$1},r0) "jsr pc,rol~" erase(r0) | | | #ifdef UNTESTED rol !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,rol~" erase(r0) | | | #endif ror $1==2 | CONST2 SCR_ODD_REG | "ashc $$%(0-%[1.num]%),%[2]" setcc(%[2]) erase(%[2]) | %[2] | | ... | SCR_REG SCR_ODD_REG | "neg %[1]" "ashc %[1],%[2]" setcc(%[2]) erase(%[1]) erase(%[2]) | %[2] | | ror defined($1) | | remove(all) move({CONST2,$1},r0) "jsr pc,ror~" erase(r0) | | | #ifdef UNTESTED ror !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,ror~" erase(r0) | | | #endif com and $1==2 && $2==2 | source2 SCR_REG | "bic %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | (2,450)+%[1] com and $1==$2 | | remove(all) allocate(REG={CONST2,$1},REG) "mov sp,%[b]" "add %[a],%[b]" "asr %[a]" "1:\tbic (sp)+,(%[b])+" "sob %[a],1b" erase(%[a]) | | | (12,2100+$1*975) /******************************** * Group 10 : Set instructions * ********************************/ inn $1==2 | SCR_REG SCR_REG | "neg %[1]" "ash %[1],%[2]" "bic $$177776,%[2]" erase(%[1]) erase(%[2]) | %[2] | | loc inn $2==2 && $1==0 | SCR_REG | "bic $$177776,%[1]" erase(%[1]) | %[1] | | loc inn $2==2 && $1==1 | SCR_REG | "asr %[1]" "bic $$177776,%[1]" erase(%[1]) | %[1] | | loc inn $2==2 | SCR_REG | "ash $$%(0-$1%),%[1]" "bic $$177776,%[1]" erase(%[1]) | %[1] | | loc inn zeq $2==2 | | | {CONST2, 1<<$1} | and 2 zeq $3 | inn zeq $1==2 | source2 | allocate(REG={CONST2,1}) "ash %[1],%[a]" | %[a] | and 2 zeq $2 | loc inn zne $2==2 | | | {CONST2, 1<<$1} | and 2 zne $3 | inn zne $1==2 | source2 | allocate(REG={CONST2,1}) "ash %[1],%[a]" | %[a] | and 2 zne $2 | inn defined($1) | source2 | remove(all) move(%[1],r1) move({CONST2,$1},r0) "jsr pc,inn~" erase(r01) | r0 | | #ifdef UNTESTED inn !defined($1)| source2 | remove(all) move(%[1],r0) "mov (sp)+,r1" "jsr pc,inn~" erase(r01) | r0 | | #endif set $1==2 | REG | allocate(REG={CONST2,1}) "ash %[1],%[a]" erase(%[a]) | %[a] | | set defined($1) | source2 | remove(all) move(%[1],r1) move({CONST2,$1},r0) "jsr pc,set~" erase(r01) | | | set !defined($1)| source2 | remove(all) move(%[1],r0) "mov (sp)+,r1" "jsr pc,set~" erase(r01) | | | /**************************************** * Group 11 : Array instructions * ****************************************/ lae aar $2==2 && rom(1,3)==1 && rom(1,1)==0 | | | | adi 2 | lae aar $2==2 && rom(1,3)==1 && rom(1,1)!=0 | | | | adi 2 adp 0-rom(1,1) | lae aar $2==2 && rom(1,3)==2 && rom(1,1)==0 | SCR_REG | "asl %[1]" erase(%[1]) | %[1] | adi 2 | lae aar $2==2 && rom(1,3)==2 && rom(1,1)!=0 | SCR_REG | "asl %[1]" erase(%[1]) | {regconst2,%[1],tostring((0-2)*rom(1,1))} | adi 2 | lae aar $2==2 && rom(1,3)==4 && rom(1,1)==0 | SCR_REG | "ash $$2,%[1]" erase(%[1]) | %[1] | adi 2 | lae aar $2==2 && rom(1,3)==4 && rom(1,1)!=0 | SCR_REG | "ash $$2,%[1]" erase(%[1]) | {regconst2,%[1],tostring((0-4)*rom(1,1))} | adi 2 | lae aar $2==2 && rom(1,3)==8 && rom(1,1)==0 | SCR_REG | "ash $$3,%[1]" erase(%[1]) | %[1] | adi 2 | lae aar $2==2 && rom(1,3)==8 && rom(1,1)!=0 | SCR_REG | "ash $$3,%[1]" erase(%[1]) | {regconst2,%[1],tostring((0-8)*rom(1,1))} | adi 2 | lae aar $2==2 && rom(1,1)==0 | SCR_ODD_REG | "mul $$%(rom(1,3)%),%[1]" erase(%[1]) | %[1] | adi 2 | lae aar $2==2 && defined(rom(1,1)) | SCR_ODD_REG | "mul $$%(rom(1,3)%),%[1]" erase(%[1]) | {regconst2,%[1],tostring((0-rom(1,3))*rom(1,1))} | adi 2 | aar $1==2 | | remove(all) "mov (sp)+,r0" "mov (sp)+,r1" "jsr pc,aar~" erase(r01) | | | #ifdef UNTESTED aar !defined($1) | | remove(all) "jsr pc,iaar~" | | | #endif lae sar defined(rom(1,3)) | | | | lae $1 aar $2 sti rom(1,3) | lae lar defined(rom(1,3)) | | | | lae $1 aar $2 loi rom(1,3) | sar $1==2 | | remove(all) "mov (sp)+,r0" "mov (sp)+,r1" "jsr pc,sar~" erase(r01) | | | #ifdef UNTESTED sar !defined($1) | | remove(all) "jsr pc,isar~" | | | #endif lar $1==2 | | remove(all) "mov (sp)+,r0" "mov (sp)+,r1" "jsr pc,lar~" erase(r01) | | | #ifdef UNTESTED lar !defined($1) | | remove(all) "jsr pc,ilar~" | | | #endif /**************************************** * group 12 : Compare instructions * ****************************************/ cmi $1==2 | source2 SCR_REG | "sub %[1],%[2]" setcc(%[2]) erase(%[2]) | %[2] | | ... | SCR_REG source2 | "sub %[2],%[1]" "neg %[1]" setcc(%[1]) erase(%[1]) | %[1] | | cmi $1==4 | | remove(all) "jsr pc,cmi4~" | r0 | | #ifdef UNTESTED cmi !defined($1) | source2 | remove(all) move(%[1],r0) "jsr pc,cmi~" erase(r0) | r0 | | #endif cmf defined($1) | | remove(ALL) move({CONST2,$1},r0) "jsr pc,cmf~" erase(r0) | r0 | | #ifdef UNTESTED cmf !defined($1)| source2 | remove(ALL) move(%[1],r0) "jsr pc,cmf~" erase(r0) | r0 | | #endif cmu $1==2 | | | | cmp | cmu $1==4 | | remove(all) "jsr pc,cmu4~" | r0 | | cmu defined($1) | | remove(all) move({CONST2,$1},r0) "jsr pc,cmu~" | r0 | | #ifdef UNTESTED cmu !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,cmu~" erase(r0) | r0 | | #endif cms $1==2 | | | | cmi $1 | ldc cms zeq $2==4 && loww(1)==0 && highw(1)==0 | source2 SCR_REG | remove(all) "bis %[1],%[2]" "jeq $3" | | | ldc cms zne $2==4 && loww(1)==0 && highw(1)==0 | source2 SCR_REG | remove(all) "bis %[1],%[2]" "jne $3" | | | ldc cms zeq $2==4 | source2 source2 | remove(all) "cmp $$%(loww(1)%),%[2]" "bne 1f" "cmp $$%(highw(1)%),%[1]" "jeq $3" "1:" | | | ldc cms zne $2==4 | source2 source2 | remove(all) "cmp $$%(loww(1)%),%[2]" "jne $3" "cmp $$%(highw(1)%),%[1]" "jne $3" | | | cms defined($1) | | remove(all) move({CONST2,$1},r0) "jsr pc,cms~" erase(r0) | r0 | | #ifdef UNTESTED cms !defined($1)| source2 | remove(all) move(%[1],r0) "jsr pc,cms~" erase(r0) | r0 | | #endif cmp | source2 source2 | allocate(REG = {CONST2,0}) "cmp %[1],%[2]" "beq 2f" "bhi 1f" "inc %[a]" "br 2f" "1:\tdec %[a]\n2:" setcc(%[a]) erase(%[a]) | %[a] | | tlt and $2==2 | source2 SCR_REG | test(%[1]) "blt 1f" "clr %[2]\n1:" erase(%[2]) | %[2] | | tlt ior $2==2 | source2 SCR_REG | test(%[1]) "bge 1f" "bis $$1,%[2]\n1:" erase(%[2]) | %[2] | | tlt | source2 | allocate(REG={CONST2,0}) test(%[1]) "bge 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | tle and $2==2 | source2 SCR_REG | test(%[1]) "ble 1f" "clr %[2]\n1:" erase(%[2]) | %[2] | | tle ior $2==2 | source2 SCR_REG | test(%[1]) "bgt 1f" "bis $$1,%[2]\n1:" erase(%[2]) | %[2] | | tle | source2 | allocate(REG={CONST2,0}) test(%[1]) "bgt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | teq and $2==2 | source1or2 SCR_REG | test(%[1]) "beq 1f" "clr %[2]\n1:" erase(%[2]) | %[2] | | teq ior $2==2 | source1or2 SCR_REG | test(%[1]) "bne 1f" "bis $$1,%[2]\n1:" erase(%[2]) | %[2] | | teq | source1or2 | allocate(REG={CONST2,0}) test(%[1]) "bne 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | tne and $2==2 | source1or2 SCR_REG | test(%[1]) "bne 1f" "clr %[2]\n1:" erase(%[2]) | %[2] | | tne ior $2==2 | source1or2 SCR_REG | test(%[1]) "beq 1f" "bis $$1,%[2]\n1:" erase(%[2]) | %[2] | | tne | source1or2 | allocate(REG={CONST2,0}) test(%[1]) "beq 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | tgt and $2==2 | source2 SCR_REG | test(%[1]) "bgt 1f" "clr %[2]\n1:" erase(%[2]) | %[2] | | tgt ior $2==2 | source2 SCR_REG | test(%[1]) "ble 1f" "bis $$1,%[2]\n1:" erase(%[2]) | %[2] | | tgt | source2 | allocate(REG={CONST2,0}) test(%[1]) "ble 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | tge and $2==2 | source2 SCR_REG | test(%[1]) "bge 1f" "clr %[2]\n1:" erase(%[2]) | %[2] | | tge ior $2==2 | source2 SCR_REG | test(%[1]) "blt 1f" "bis $$1,%[2]\n1:" erase(%[2]) | %[2] | | tge | source2 | allocate(REG={CONST2,0}) test(%[1]) "blt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | and tne $1==2 | source2 source2 | allocate(REG={CONST2,0}) "bit %[1],%[2]" "beq 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | and teq $1==2 | source2 source2 | allocate(REG={CONST2,0}) "bit %[1],%[2]" "bne 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmi tlt and $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "blt 1f" "clr %[3]\n1:" erase(%[3]) | %[3] | | cmi tlt ior $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "bge 1f" "bis $$1,%[3]\n1:" erase(%[3]) | %[3] | | cmi tlt $1==2 | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "bge 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmi tle and $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "ble 1f" "clr %[3]\n1:" erase(%[3]) | %[3] | | cmi tle ior $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "bgt 1f" "bis $$1,%[3]\n1:" erase(%[3]) | %[3] | | cmi tle $1==2 | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "bgt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmi teq and $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "beq 1f" "clr %[3]\n1:" erase(%[3]) | %[3] | | cmi teq ior $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "bne 1f" "bis $$1,%[3]\n1:" erase(%[3]) | %[3] | | cmi teq $1==2 | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "bne 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | loc cmi teq and $1>=0 && $1<=127 && $2==2 && $4==2 | NC source1 SCR_REG | "cmpb %[1],$$$1" "beq 1f" "clr %[2]\n1:" erase(%[2]) | %[2] | | ... | | | {CONST2, $1} | cmi 2 teq and 2 | loc cmi teq ior $1>=0 && $1<=127 && $2==2 && $4==2 | NC source1 SCR_REG | "cmpb %[1],$$$1" "bne 1f" "bis $$1,%[2]\n1:" erase(%[2]) | %[2] | | ... | | | {CONST2, $1} | cmi 2 teq ior 2 | loc cmi teq $1>=0 && $1<=127 && $2==2 | NC source1 | allocate(REG={CONST2,0}) "cmpb %[1],$$$1" "bne 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | ... | | | {CONST2, $1} | cmi 2 teq | cmi tne and $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "bne 1f" "clr %[3]\n1:" erase(%[3]) | %[3] | | cmi tne ior $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "beq 1f" "bis $$1,%[3]\n1:" erase(%[3]) | %[3] | | cmi tne $1==2 | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "beq 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | loc cmi tne and $1>=0 && $1<=127 && $2==2 && $4==2 | NC source1 SCR_REG | "cmpb %[1],$$$1" "bne 1f" "clr %[2]\n1:" erase(%[2]) | %[2] | | ... | | | {CONST2, $1} | cmi 2 tne and 2 | loc cmi tne ior $1>=0 && $1<=127 && $2==2 && $4==2 | NC source1 SCR_REG | "cmpb %[1],$$$1" "beq 1f" "bis $$1,%[2]\n1:" erase(%[2]) | %[2] | | ... | | | {CONST2, $1} | cmi 2 tne ior 2 | loc cmi tne $1>=0 && $1<=127 && $2==2 | NC source1 | allocate(REG={CONST2,0}) "cmpb %[1],$$$1" "beq 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | ... | | | {CONST2, $1} | cmi 2 tne | cmi tge and $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "bge 1f" "clr %[3]\n1:" erase(%[3]) | %[3] | | cmi tge ior $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "blt 1f" "bis $$1,%[3]\n1:" erase(%[3]) | %[3] | | cmi tge $1==2 | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "blt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmi tgt and $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "bgt 1f" "clr %[3]\n1:" erase(%[3]) | %[3] | | cmi tgt ior $1==2 && $3==2 | source2 source2 SCR_REG | "cmp %[2],%[1]" "ble 1f" "bis $$1,%[3]\n1:" erase(%[3]) | %[3] | | cmi tgt $1==2 | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "ble 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmp tlt | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "bhis 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmp tle | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "bhi 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmp teq | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "bne 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmp tne | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "beq 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmp tge | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "blo 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmp tgt | source2 source2 | allocate(REG={CONST2,0}) "cmp %[2],%[1]" "blos 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tlt $1==4 | FLT_REG FLT_REG | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "bge 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tle $1==4 | FLT_REG FLT_REG | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "bgt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf teq $1==4 | FLT_REG FLT_REG | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "bne 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tne $1==4 | FLT_REG FLT_REG | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "beq 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tgt $1==4 | FLT_REG FLT_REG | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "ble 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tge $1==4 | FLT_REG FLT_REG | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "blt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tlt $1==8 | DBL_REG double8 | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "bge 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | ... | double8 DBL_REG | allocate(REG={CONST2,0}) "cmpf %[1],%[2]\ncfcc" "ble 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tle $1==8 | DBL_REG double8 | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "bgt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | ... | double8 DBL_REG | allocate(REG={CONST2,0}) "cmpf %[1],%[2]\ncfcc" "blt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf teq $1==8 | DBL_REG double8 | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "bne 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | ... | double8 DBL_REG | allocate(REG={CONST2,0}) "cmpf %[1],%[2]\ncfcc" "bne 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tne $1==8 | DBL_REG double8 | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "beq 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | ... | double8 DBL_REG | allocate(REG={CONST2,0}) "cmpf %[1],%[2]\ncfcc" "beq 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tgt $1==8 | DBL_REG double8 | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "ble 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | ... | double8 DBL_REG | allocate(REG={CONST2,0}) "cmpf %[1],%[2]\ncfcc" "bge 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | cmf tge $1==8 | DBL_REG double8 | allocate(REG={CONST2,0}) "cmpf %[2],%[1]\ncfcc" "blt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | ... | double8 DBL_REG | allocate(REG={CONST2,0}) "cmpf %[1],%[2]\ncfcc" "bgt 1f" "inc %[a]\n1:" erase(%[a]) | %[a] | | /**************************************** * Group 13 : Branch instructions * ****************************************/ bra | | remove(all) "jbr $1" samecc | | | blt | source2 source2 | remove(all) "cmp %[2],%[1]" "jlt $1" | | | ble | source2 source2 | remove(all) "cmp %[2],%[1]" "jle $1" | | | beq | NC source1 source1 | remove(all) "cmpb %[2],%[1]" "jeq $1" | | | ... | source2 source2 | remove(all) "cmp %[2],%[1]" "jeq $1" | | | bne | NC source1 source1 | remove(all) "cmpb %[2],%[1]" "jne $1" | | | ... | source2 source2 | remove(all) "cmp %[2],%[1]" "jne $1" | | | bge | source2 source2 | remove(all) "cmp %[2],%[1]" "jge $1" | | | bgt | source2 source2 | remove(all) "cmp %[2],%[1]" "jgt $1" | | | loc beq $1>=0 && $1<=127 | NC source1 | remove(all) "cmpb %[1],$$$1" "jeq $2" | | | ... | | | {CONST2, $1} | beq $2 | loc bne $1>=0 && $1<=127 | NC source1 | remove(all) "cmpb %[1],$$$1" "jne $2" | | | ... | | | {CONST2, $1} | bne $2 | zlt | source2 | remove(all) test(%[1]) "jlt $1" samecc | | | zle | source2 | remove(all) test(%[1]) "jle $1" samecc | | | zeq | source1or2 | remove(all) test(%[1]) "jeq $1" samecc | | | zne | source1or2 | remove(all) test(%[1]) "jne $1" samecc | | | zge | source2 | remove(all) test(%[1]) "jge $1" samecc | | | zgt | source2 | remove(all) test(%[1]) "jgt $1" samecc | | | cmp zlt | source2 source2 | remove(all) "cmp %[2],%[1]" "jlo $2" | | | cmp zle | source2 source2 | remove(all) "cmp %[2],%[1]" "jlos $2" | | | cmp zeq | source2 source2 | remove(all) "cmp %[2],%[1]" "jeq $2" | | | cmp zne | source2 source2 | remove(all) "cmp %[2],%[1]" "jne $2" | | | cmp zgt | source2 source2 | remove(all) "cmp %[2],%[1]" "jhi $2" | | | cmp zge | source2 source2 | remove(all) "cmp %[2],%[1]" "jhis $2" | | | cmf zlt $1==4 | FLT_REG FLT_REG | remove(all) "cmpf %[2],%[1]\ncfcc" "jlt $2" | | | cmf zle $1==4 | FLT_REG FLT_REG | remove(all) "cmpf %[2],%[1]\ncfcc" "jle $2" | | | cmf zeq $1==4 | FLT_REG FLT_REG | remove(all) "cmpf %[2],%[1]\ncfcc" "jeq $2" | | | cmf zne $1==4 | FLT_REG FLT_REG | remove(all) "cmpf %[2],%[1]\ncfcc" "jne $2" | | | cmf zgt $1==4 | FLT_REG FLT_REG | remove(all) "cmpf %[2],%[1]\ncfcc" "jgt $2" | | | cmf zge $1==4 | FLT_REG FLT_REG | remove(all) "cmpf %[2],%[1]\ncfcc" "jge $2" | | | cmf zlt $1==8 | DBL_REG double8 | remove(all) "cmpf %[2],%[1]\ncfcc" "jlt $2" | | | ... | double8 DBL_REG | remove(all) "cmpf %[1],%[2]\ncfcc" "jgt $2" | | | cmf zle $1==8 | DBL_REG double8 | remove(all) "cmpf %[2],%[1]\ncfcc" "jle $2" | | | ... | double8 DBL_REG | remove(all) "cmpf %[1],%[2]\ncfcc" "jge $2" | | | cmf zeq $1==8 | DBL_REG double8 | remove(all) "cmpf %[2],%[1]\ncfcc" "jeq $2" | | | ... | double8 DBL_REG | remove(all) "cmpf %[1],%[2]\ncfcc" "jeq $2" | | | cmf zne $1==8 | DBL_REG double8 | remove(all) "cmpf %[2],%[1]\ncfcc" "jne $2" | | | ... | double8 DBL_REG | remove(all) "cmpf %[1],%[2]\ncfcc" "jne $2" | | | cmf zgt $1==8 | DBL_REG double8 | remove(all) "cmpf %[2],%[1]\ncfcc" "jgt $2" | | | ... | double8 DBL_REG | remove(all) "cmpf %[1],%[2]\ncfcc" "jlt $2" | | | cmf zge $1==8 | DBL_REG double8 | remove(all) "cmpf %[2],%[1]\ncfcc" "jge $2" | | | ... | double8 DBL_REG | remove(all) "cmpf %[1],%[2]\ncfcc" "jle $2" | | | and zeq $1==2 | source2 source2 | remove(all) "bit %[1],%[2]" "jeq $2" | | | and zne $1==2 | source2 source2 | remove(all) "bit %[1],%[2]" "jne $2" | | | /************************************************ * group 14 : Procedure call instructions * ************************************************/ cal | | remove(ALL) "jsr pc,$1" | | | cai | REG | remove(ALL) "jsr pc,(%[1])" | | | lfr $1==2 | | | r0 | | lfr $1==4 | | | r1 r0 | | lfr $1==8 | | | {relative8,"retar"} | | lfr | | remove(all) move({CONST2,$1},r0) "jsr pc,lfr~" erase(r0) | | | lfr ret $1==$2 | | | | ret 0 | #ifndef REGVARS asp lfr ret $2==$3 | | | | ret 0 | asp ret $2==0 | | | | ret 0 | #endif ret $1==0 | | remove(all) #ifdef REGVARS return | | | #else "mov r5,sp\nmov (sp)+,r5\nrts pc" | | | #endif ret $1==2 | source2 | remove(all) move(%[1],r0) #ifdef REGVARS return | | | #else "mov r5,sp\nmov (sp)+,r5\nrts pc" | | | #endif ret $1==4 | | remove(all) "mov (sp)+,r0" "mov (sp)+,r1" #ifdef REGVARS return | | | #else "mov r5,sp\nmov (sp)+,r5\nrts pc" | | | #endif ret $1==8 | | | {ADDR_EXTERNAL, "retar"} | sti 8 ret 0 | ret | | remove(all) move({CONST2,$1},r0) "jmp ret~" | | | /************************************************ * Group 15 : Miscellaneous instructions * ************************************************/ asp $1==2 | NC xsource2 | | | | ... | | remove(all) "tst (sp)+" | | | asp $1==4 | | remove(all) "cmp (sp)+,(sp)+" | | | asp $1==0-2 | | remove(all) "tst -(sp)" | | | asp | | remove(all) "add $$$1,sp" | | | ass $1==2 | | remove(all) "add (sp)+,sp" | | | #ifdef UNTESTED ass !defined($1)| source2 | remove(all) "cmp %[1],$$2" "beq 1f;jmp unknown~;1:" "add (sp)+,sp" | | | #endif blm $1==4 | SCR_REG SCR_REG | "mov (%[2])+,(%[1])+" "mov (%[2]),(%[1])" erase(%[1]) erase(%[2]) | | | blm $1==6 | SCR_REG SCR_REG | "mov (%[2])+,(%[1])+" "mov (%[2])+,(%[1])+" "mov (%[2]),(%[1])" erase(%[1]) erase(%[2]) | | | blm $1==8 | SCR_REG SCR_REG | "mov (%[2])+,(%[1])+" "mov (%[2])+,(%[1])+" "mov (%[2])+,(%[1])+" "mov (%[2]),(%[1])" erase(%[1]) erase(%[2]) | | | blm | SCR_REG SCR_REG | allocate(REG={CONST2,$1/2}) "1:mov (%[2])+,(%[1])+\nsob %[a],1b" erase(%[1]) erase (%[2]) erase(%[a]) | | | bls $1==2 | source2 | remove(all) move(%[1],r0) "jsr pc,blm~" erase(r01) | | | #ifdef UNTESTED bls !defined($1)| source2 source2 | remove(all) "cmp %[1],$$2" "beq 1f;jmp unknown~;1:" move(%[2],r0) "jsr pc,blm~" erase(r01) | | | #endif lae csa $2==2 | source2 | remove(all) move(%[1],r1) move({ADDR_EXTERNAL,$1},r0) "jmp csa~" | | | csa $1==2 | | remove(all) "mov (sp)+,r0" "mov (sp)+,r1" "jmp csa~" | | | #ifdef UNTESTED csa !defined($1)| source2 | remove(all) "cmp %[1],$$2" "beq 1f;jmp unknown~;1:" "mov (sp)+,r0" "mov (sp)+,r1" "jmp csa~" | | | #endif lae csb $2==2 | NC source2 | remove(all) move(%[1],r1) move({ADDR_EXTERNAL,$1},r0) "jmp csb~" | | | ... | | remove(all) move({ADDR_EXTERNAL,$1},r0) "mov (sp)+,r1" "jmp csb~" | | | csb $1==2 | | remove(all) "mov (sp)+,r0" "mov (sp)+,r1" "jmp csb~" | | | #ifdef UNTESTED csb !defined($1)| source2 | remove(all) "cmp %[1],$$2" "beq 1f;jmp unknown~;1:" "mov (sp)+,r0" "mov (sp)+,r1" "jmp csb~" | | | #endif dup $1==2 | REG | | %[1] %[1] | | dup $1==4 | NC longf4 | | %[1] %[1] | | ... | source2 source2 | | %[2] %[1] %[2] %[1] | | dup $1==8 | NC double8| | %[1] %[1] | | ... | | remove(all) move({CONST2, $1}, r0) "jsr pc,dup~" erase(r01) | | | dup | | remove(all) move({CONST2, $1}, r0) "jsr pc,dup~" erase(r01) | | | dus $1==2 | source2 | remove(all) move(%[1],r0) "jsr pc,dup~" erase(r01) | | | #ifdef UNTESTED dus !defined($1)| source2 | remove(all) "cmp %[1],$$2" "beq 1f;jmp unknown~;1:" "mov (sp)+,r0" "jsr pc,dup~" erase(r01) | | | #endif gto | | remove(all) "mov $$$1,-(sp)" "jmp gto~" | | | fil | | "mov $$$1,hol0+4" | | | lim | | | { relative2, "trpim~"} | | lin | | "mov $$$1,hol0" | | | lni | | "inc hol0" | | | lor $1==0 | | | lb | | lor $1==1 | | remove(all) allocate(REG) "mov sp,%[a]" | %[a] | | lor $1==2 | | | {relative2,"reghp~"} | | mon | | remove(all) "jsr pc,mon~" | | | nop | | remove(all) "jsr pc,nop~" | | | #ifdef DORCK rck $1==2 | source2 | remove(all) move(%[1],r0) "jsr pc,rck~" | | | #ifdef UNTESTED rck !defined($1)| source2 source2 | remove(all) "cmp %[1],$$2" "beq 1f;jmp unknown~;1:" move(%[2],r0) "jsr pc,rck~" | | | #endif #else rck $1==2 | source2 | | | | rck !defined($1)| source2 source2 | | | | #endif rtt | | | | ret 0 | sig | source2 | allocate(REG) move({relative2,"trppc~"},%[a]) "mov %[1],trppc~" | %[a] | | sim | | remove(all) "jsr pc,sim~" | | | str $1==0 | source2 | "mov %[1],r5" | | | str $1==1 | source2 | remove(all) "mov %[1],sp" | | | str $1==2 | | remove(all) "jsr pc,strhp~" | | | trp | | remove(all) "jsr pc,trp~" | | | exg $1==2 | source2 source2 | | %[1] %[2] | | exg defined($1) | | remove(all) move({CONST2,$1},r0) "jsr pc,exg~" | | | exg | source2 | remove(all) move(%[1],r0) "jsr pc,exg" | | | lol lal sti $1==$2 && $3==1| | | | | /* throw away funny C-proc-prolog */ /******************************** * Coercions * * * * From EM-tokens to PDP-tokens * ********************************/ | LOCAL2 | | {regind2,lb,tostring(%[1.ind])} | | | LOCAL4 | | {regind4,lb,tostring(%[1.ind])} | | /******************************** * From source to register * ********************************/ | regconst2 | allocate(%[1],REG=%[1.reg]) "add $$%[1.ind],%[a]" setcc(%[a]) | %[a] | |(6,1050) | ADDR_LOCAL | allocate(REG) "mov r5,%[a]" "add $$%[1.ind],%[a]" setcc(%[a]) | %[a] | |(6,1050) | REG | | {regconst2, %[1], "0"} | | (2,600) | xsource2 | allocate(%[1], REG=%[1]) | %[a] | | | xsource2 | allocate(%[1], REG=%[1]) | {regconst2, %[a], "0"} | | | longf4 | allocate(FLT_REG) move( %[1],%[a]) | %[a] | | (20,20000) + %[1] | double8 | allocate(DBL_REG) move(%[1],%[a]) | %[a] | | (20,30000) + %[1] /******************************** * From source1 to source2 * ********************************/ | source1 | allocate(REG={CONST2,0}) "bisb %[1],%[a]" erase(%[a]) setcc(%[a]) | %[a] | | (6,1050)+%[1] /******************************** * From long4 to source2 * ********************************/ | REG_PAIR | | %[1.2] %[1.1] | | | regind4 | | {regind2,%[1.reg],"2+"+%[1.ind]} {regind2,%[1.reg],%[1.ind]} | | | relative4 | | {relative2,"2+"+%[1.ind]} {relative2,%[1.ind]} | | | regdef4 | | {regind2,%[1.reg],"2"} {regdef2,%[1.reg]} | | | LOCAL4 | | {LOCAL2, %[1.ind]+2, 2} {LOCAL2, %[1.ind], 2} | | /******************************** * from double8 to long4 * ********************************/ | regind8 | | {regind4,%[1.reg],"4+"+%[1.ind]} {regind4,%[1.reg],%[1.ind]} | | | relative8 | | {relative4,"4+"+%[1.ind]} {relative4,%[1.ind]} | | | regdef8 | | {regdef4,%[1.reg]} {regind4,%[1.reg],"4"} | | /************************ * From STACK coercions * ************************/ | STACK | allocate(REG) "mov (sp)+,%[a]" setcc(%[a]) | %[a] | | (2,750) | STACK | allocate(REG) "mov (sp)+,%[a]" setcc(%[a]) | {regconst2, %[a], "0"} | | (2,750) | STACK | allocate(FLT_REG) "movof (sp)+,%[a]" samecc | %[a] | | (20,47400) /* /10 */ | STACK | allocate(DBL_REG) "movf (sp)+,%[a]" samecc | %[a] | | (20,69200) /* /10 */ | STACK | allocate(REG_PAIR) "mov (sp)+,%[a.1]" "mov (sp)+,%[a.2]" setcc(%[a.2]) | %[a] | | (4,1500) MOVES: (CONST2 %[num] == 0, source2, "clr %[2]" setcc(%[2]),(2,300)) (source2, source2, "mov %[1],%[2]" setcc(%[2]),(2,300)+%[1]+%[2]) (FLT_REG, longf4-FLT_REG,"movfo %[1],%[2]" samecc, (2,880) + %[2]) (longf4-FLT_REG,FLT_REG, "movof %[1],%[2]" samecc, (2,1500) + %[2]) (FLT_REG, FLT_REG, "movf %[1],%[2]" samecc,(2,880)) (DBL_REG,double8, "movf %[1],%[2]" samecc,(2,880) + %[2]) (double8,DBL_REG, "movf %[1],%[2]" samecc,(2,1700) + %[1]) (CONST2 %[num] == 0,source1, "clrb %[2]" setcc(%[2]),(2,450)+%[2]) (source1or2,source1, "movb %[1],%[2]" setcc(%[2]),(2,300)+%[1]+%[2]) (ftoint,source2, "movfi %[1.reg],%[2]" samecc) TESTS: (source2, "tst %[1]" ,(2,300) + %[1]) (source1, "tstb %[1]",(2,400) + %[1]) (FLT_REG+DBL_REG, "tstf %[1]\ncfcc" ,(4,2600)) /* (DBL_REG, "tstf %[1]\ncfcc" ,(4,2600)) */ STACKS: ( CONST2 %[num]==0 ,, "clr -(sp)" ) ( source2 ,, "mov %[1],-(sp)" setcc(%[1]), (2,900)+%[1]) ( regconst2 ,, "mov %[1.reg],-(sp)\nadd $$%[1.ind],(sp)" , (6,2250)) ( ADDR_LOCAL,, "mov r5,-(sp)" "add $$%[1.ind],(sp)", (6,2250)) ( DBL_REG ,, "movf %[1],-(sp)" samecc , (2,6100)) ( FLT_REG ,, "movfo %[1],-(sp)" samecc , (2,4120)) ( REG_PAIR ,, "mov %[1.2],-(sp)" "mov %[1.1],-(sp)" , (4,1800)) ( regind4 ,, "mov 2+%[1.ind](%[1.reg]),-(sp)" "mov %[1.ind](%[1.reg]),-(sp)" , (8,3000)) ( relative4 ,, "mov 2+%[1.ind],-(sp)" "mov %[1.ind],-(sp)" , (8,3000)) ( regdef4 ,, "mov 2(%[1.reg]),-(sp)" "mov (%[1.reg]),-(sp)" , (6,2700)) ( regind8 ,REG, move(%[1.reg],%[a]) "add $$%(8%)+%[1.ind],%[a]" "mov -(%[a]),-(sp)" "mov -(%[a]),-(sp)" "mov -(%[a]),-(sp)" "mov -(%[a]),-(sp)" erase(%[a]) , (14,6000)) ( regind8 ,, "mov 6+%[1.ind](%[1.reg]),-(sp)" "mov 4+%[1.ind](%[1.reg]),-(sp)" "mov 2+%[1.ind](%[1.reg]),-(sp)" "mov %[1.ind](%[1.reg]),-(sp)" , (16,6000)) ( relative8 ,REG,"mov $$%(8%)+%[1.ind],%[a]" "mov -(%[a]),-(sp)" "mov -(%[a]),-(sp)" "mov -(%[a]),-(sp)" "mov -(%[a]),-(sp)" , (12,5000)) ( relative8 ,, "mov 6+%[1.ind],-(sp)" "mov 4+%[1.ind],-(sp)" "mov 2+%[1.ind],-(sp)" "mov %[1.ind],-(sp)" , (16,6000)) ( regdef8 ,, "mov 6(%[1.reg]),-(sp)" "mov 4(%[1.reg]),-(sp)" "mov 2(%[1.reg]),-(sp)" "mov (%[1.reg]),-(sp)" , (14,5700)) ( LOCAL4 ,, "mov 2+%[1.ind](r5),-(sp)" "mov %[1.ind](r5),-(sp)" , (8,3000)) ( source1 ,, "clr -(sp)" "movb %[1],(sp)" , (4,1800)+%[1]) ( ftoint ,, "movfi %[1.reg],-(sp)" ) ( ftolong ,, "setl\nmovfi %[1.reg],-(sp)\nseti" )