From c58492b45bc3f26ec9805a3b27f3823b9335302e Mon Sep 17 00:00:00 2001 From: sater Date: Sat, 19 May 1984 12:48:59 +0000 Subject: [PATCH] Initial revision --- mach/pdp/cg/mach.c | 167 +++ mach/pdp/cg/mach.h | 21 + mach/pdp/cg/table | 2447 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2635 insertions(+) create mode 100644 mach/pdp/cg/mach.c create mode 100644 mach/pdp/cg/mach.h create mode 100644 mach/pdp/cg/table diff --git a/mach/pdp/cg/mach.c b/mach/pdp/cg/mach.c new file mode 100644 index 000000000..1f8c0dea7 --- /dev/null +++ b/mach/pdp/cg/mach.c @@ -0,0 +1,167 @@ +/* + * (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 + * + * Author: Hans van Staveren + */ + +/* + * machine dependent back end routines for the PDP-11 + */ + +#define REGPATCH + +con_part(sz,w) register sz; word w; { + + while (part_size % sz) + part_size++; + if (part_size == EM_WSIZE) + part_flush(); + if (sz == 1) { + w &= 0xFF; + if (part_size) + w <<= 8; + part_word |= w; + } else { + assert(sz == 2); + part_word = w; + } + part_size += sz; +} + +con_mult(sz) word sz; { + long l; + + if (sz != 4) + fatal("bad icon/ucon size"); + l = atol(str); + fprintf(codefile,"\t%o;%o\n",(int)(l>>16),(int)l); +} + +con_float() { + double f; + register short *p,i; + + if (argval != 4 && argval != 8) + fatal("bad fcon size"); + f = atof(str); + p = (short *) &f; + i = *p++; + if (argval == 8) { + fprintf(codefile,"\t%o;%o;",i,*p++); + i = *p++; + } + fprintf(codefile,"\t%o;%o\n",i,*p++); +} + +#ifdef REGVARS + +char Rstring[10] = "RT"; + +regscore(off,size,typ,score,totyp) long off; { + + if (size != 2) + return(-1); + score -= 1; /* allow for save/restore */ + if (off>=0) + score -= 2; + if (typ==reg_pointer) + score *= 17; + else if (typ==reg_loop) + score = 10*score+50; /* Guestimate */ + else + score *= 10; + return(score); /* estimated # of words of profit */ +} + +i_regsave() { + + Rstring[2] = 0; +} + +f_regsave() {} + +regsave(regstr,off,size) char *regstr; long off; { + + fprintf(codefile,"/ Local %ld into %s\n",off,regstr); +#ifndef REGPATCH + fprintf(codefile,"mov %s,-(sp)\n",regstr); +#endif + strcat(Rstring,regstr); + if (off>=0) + fprintf(codefile,"mov 0%lo(r5),%s\n",off,regstr); +} + +regreturn() { + +#ifdef REGPATCH + fprintf(codefile,"jmp eret\n"); +#else + fprintf(codefile,"jmp %s\n",Rstring); +#endif +} + +#endif + +prolog(nlocals) full nlocals; { + +#ifdef REGPATCH + fprintf(codefile,"mov r2,-(sp)\nmov r4,-(sp)\n"); +#endif + fprintf(codefile,"mov r5,-(sp)\nmov sp,r5\n"); + if (nlocals == 0) + return; + if (nlocals == 2) + fprintf(codefile,"tst -(sp)\n"); + else + fprintf(codefile,"sub $0%o,sp\n",nlocals); +} + +dlbdlb(as,ls) string as,ls; { + + if (strlen(as)+strlen(ls)+24 * + * * + * 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 */ + +#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:\tmov 4(%[a]),%[a]" /* SL */ + "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:\tmov 4(%[a]),%[a]" /* SL */ + "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~" | | | +los !defined($1)| source2 | + remove(all) + "cmp %[1],$$2" + "beq 1f;jmp unknown~;1:" + "mov (sp)+,r0" + "mov (sp)+,r1" + "jsr pc,los2~" | | | +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)}) | | | +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]}) | | | +... | NC regconst2 source1or2 | + INDSTORE + move(%[2],{regind1,%[1.reg],%[1.ind]}) | | | +... | NC ADDR_EXTERNAL source1or2 | + INDSTORE + move(%[2],{relative1,%[1.ind]}) | | | +... | NC ADDR_LOCAL source1or2 | + INDSTORE + move(%[2],{regind1, lb, tostring(%[1.ind])}) | | | +... | NC relative2 source1or2 | + INDSTORE + move(%[2],{reldef1,%[1.ind]}) | | | +... | NC regind2 source1or2 | + INDSTORE + move(%[2],{reginddef1,%[1.reg],%[1.ind]}) | | | +sti $1==4 | NC dadres2 FLT_REG | + INDSTORE + "movfo %[2],*%[1]" + samecc | | | +... | NC dadres2 ftolong | + INDSTORE + "setl\nmovfi %[2.reg],*%[1]\nseti" + samecc | | | +... | NC regconst2 FLT_REG | + INDSTORE + "movfo %[2],%[1.ind](%[1.reg])" + samecc | | | +... | NC regconst2 ftolong | + INDSTORE + "setl\nmovfi %[2.reg],%[1.ind](%[1.reg])\nseti" + samecc | | | +... | NC ADDR_LOCAL FLT_REG | + INDSTORE + "movfo %[2],%[1.ind](r5)" + samecc | | | +... | NC ADDR_LOCAL ftolong | + INDSTORE + "setl\nmovfi %[2.reg],%[1.ind](r5)\nseti" + samecc | | | +... | NC ADDR_EXTERNAL FLT_REG | + INDSTORE + "movfo %[2],%[1.ind]" + samecc | | | +... | NC 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 | NC dadres2 DBL_REG | + INDSTORE + "movf %[2],*%[1]" + samecc | | | +... | NC regconst2 DBL_REG | + INDSTORE + "movf %[2],%[1.ind](%[1.reg])" + samecc | | | +... | NC ADDR_LOCAL DBL_REG | + INDSTORE + "movf %[2],%[1.ind](r5)" + samecc | | | +... | NC 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 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] +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] +adi !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,adi~" | | | +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] +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] +sbi !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,sbi~" | | | +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 | | +mli !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,mli~" | | | +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 | | +dvi !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,dvi~" | | | +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 | | +rmi !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,rmi~" | | | +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) +ngi !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,ngi~" | | | +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] | | +sli !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,sli~" | | | +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] | | +sri !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,sri~" | | | + +/************************************************ + * 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 | | +mlu !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,mlu~" | | | +dvu $1==2 | | remove(all) + "jsr pc,dvu2~" | r0 | | +dvu $1==4 | | remove(all) + "jsr pc,dvu4~" | r1 r0 | | +dvu !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,dvu~" | | | +rmu $1==2 | | remove(all) + "jsr pc,rmu2~" | r1 | | +rmu $1==4 | | remove(all) + "jsr pc,rmu4~" | r1 r0 | | +rmu !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,rmu~" | | | +slu | | | | sli $1 | +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) | | | +sru !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,sru~" | | | + +/************************************************ + * 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] +adf !defined($1)| source2 | + remove(ALL) + move(%[1],r0) + "jsr pc,adf~" | | | +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] +sbf !defined($1)| source2 | + remove(ALL) + move(%[1],r0) + "jsr pc,sbf~" | | | +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] +mlf !defined($1)| source2 | + remove(ALL) + move(%[1],r0) + "jsr pc,mlf~" | | | +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] +dvf !defined($1)| source2 | + remove(ALL) + move(%[1],r0) + "jsr pc,dvf~" | | | +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) +ngf !defined($1)| source2 | + remove(ALL) + move(%[1],r0) + "jsr pc,ngf~" | | | +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] +fif !defined($1)| source2 | + remove(ALL) + move(%[1],r0) + "jsr pc,fif~" | | | +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) +fef !defined($1)| source2 | + remove(ALL) + move(%[1],r0) + "jsr pc,fef~" | | | + +/**************************************** + * 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}) | | | +ine | | remove(posextern) + "inc $1" + setcc({relative2,$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 adp stl $1==$3 && $2==1 && inreg($1)==2 | | + remove(regvar($1)) + "inc %(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 | | + 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 | | + 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 * + ****************************************/ + +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~" | | | +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 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) | | | +and !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,and~" + erase(r0) | | | +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) +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]) | | | +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) | | | +xor !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,xor~" + erase(r0) | | | +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) +com !defined($1)| SCR_REG | + remove(all) + allocate(REG) + "asr %[1]" + "mov sp,%[a]" + "1:\tcom (%[a])+" + "sob %[1],1b" + erase(%[1]) | | | +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) | | | +rol !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,rol~" + erase(r0) | | | +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) | | | +ror !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,ror~" + erase(r0) | | | +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 | | +inn !defined($1)| source2 | + remove(all) + move(%[1],r0) + "mov (sp)+,r1" + "jsr pc,inn~" + erase(r01) | r0 | | +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) | | | +aar !defined($1) | | remove(all) + "jsr pc,iaar~" | | | +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) | | | +sar !defined($1) | | remove(all) + "jsr pc,isar~" | | | +lar $1==2 | | + remove(all) + "mov (sp)+,r0" + "mov (sp)+,r1" + "jsr pc,lar~" + erase(r01) | | | +lar !defined($1) | | remove(all) + "jsr pc,ilar~" | | | + +/**************************************** + * 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 | | +cmi !defined($1) | source2 | + remove(all) + move(%[1],r0) + "jsr pc,cmi~" + erase(r0) | r0 | | +cmf defined($1) | | remove(ALL) + move({CONST2,$1},r0) + "jsr pc,cmf~" + erase(r0) | r0 | | +cmf !defined($1)| source2 | + remove(ALL) + move(%[1],r0) + "jsr pc,cmf~" + erase(r0) | r0 | | +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 | | +cmu !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,cmu~" + erase(r0) | r0 | | +cms $1==2 | | | | cmi $1 | +cms defined($1) | | remove(all) + move({CONST2,$1},r0) + "jsr pc,cms~" + erase(r0) | r0 | | +cms !defined($1)| source2 | + remove(all) + move(%[1],r0) + "jsr pc,cms~" + erase(r0) | r0 | | +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 | source2 source2 | + remove(all) + "cmp %[2],%[1]" + "jeq $1" | | | +bne | 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 | | 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" | | | +ass !defined($1)| source2 | + remove(all) + "cmp %[1],$$2" + "beq 1f;jmp unknown~;1:" + "add (sp)+,sp" | | | + +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) | | | +bls !defined($1)| source2 source2 | + remove(all) + "cmp %[1],$$2" + "beq 1f;jmp unknown~;1:" + move(%[2],r0) + "jsr pc,blm~" + erase(r01) | | | +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~" | | | +csa !defined($1)| source2 | + remove(all) + "cmp %[1],$$2" + "beq 1f;jmp unknown~;1:" + "mov (sp)+,r0" + "mov (sp)+,r1" + "jmp csa~" | | | +lae csb $2==2 | source2 | + remove(all) + move(%[1],r1) + move({ADDR_EXTERNAL,$1},r0) + "jmp csb~" | | | + +csb $1==2 | | + remove(all) + "mov (sp)+,r0" + "mov (sp)+,r1" + "jmp csb~" | | | +csb !defined($1)| source2 | + remove(all) + "cmp %[1],$$2" + "beq 1f;jmp unknown~;1:" + "mov (sp)+,r0" + "mov (sp)+,r1" + "jmp csb~" | | | +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) | | | +dus !defined($1)| source2 | + remove(all) + "cmp %[1],$$2" + "beq 1f;jmp unknown~;1:" + "mov (sp)+,r0" + "jsr pc,dup~" + erase(r01) | | | +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~" | | | +rck !defined($1)| source2 source2 | + remove(all) + "cmp %[1],$$2" + "beq 1f;jmp unknown~;1:" + move(%[2],r0) + "jsr pc,rck~" | | | +#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" )