/* ** print all assembler info before any code is generated */ header() { beglab=getlabel(); #ifndef LINK if(beglab < 3) #endif /* LINK */ { #ifdef LINK jump(beglab); #endif /* LINK */ } } /* ** print any assembler stuff needed at the end */ trailer() { ol("END"); } /* ** load # args before function call */ loadargc(val) int val; { #ifdef HASH if(search("NOCCARGC", macn, NAMESIZE+2, MACNEND, MACNBR, 0)==0) { #else /* HASH */ if(findmac("NOCCARGC")==0) { #endif /* HASH */ ot("MVI A,"); outdec(val); nl(); } } /* ** declare entry point */ entry() { #ifdef LINK if (!m80flg) { ot("PUBLIC "); ol(ssname); } #endif /* LINK */ outstr(ssname); col(); #ifdef LINK if (m80flg) { col(); } #endif /* LINK */ nl(); } /* ** declare external reference */ external(name) char *name; { #ifdef LINK ot("EXTRN "); outstr(name); nl(); #endif } /* ** fetch object indirect to primary register */ indirect(lval) int lval[]; { if(lval[1]==CCHAR) zzcall("CCGCHAR"); else zzcall("CCGINT"); } /* ** fetch a static memory cell into primary register */ getmem(lval) int lval[]; { char *sym; sym=lval[0]; if((sym[IDENT]!=POINTER)&(sym[TYPE]==CCHAR)) { ot("LDA "); outstr(sym+NAME); nl(); zzcall("CCSXT"); } else { ot("LHLD "); outstr(sym+NAME); nl(); } } /* ** fetch addr of the specified symbol into primary register */ getloc(sym) char *sym; { const(getint(sym+OFFSET, OFFSIZE)-csp); ol("DAD SP"); } /* ** store primary register into static cell */ putmem(lval) int lval[]; { char *sym; sym=lval[0]; if((sym[IDENT]!=POINTER)&(sym[TYPE]==CCHAR)) { ol("MOV A,L"); ot("STA "); } else ot("SHLD "); outstr(sym+NAME); nl(); } /* ** put on the stack the type object in primary register */ putstk(lval) int lval[]; { if(lval[1]==CCHAR) { ol("MOV A,L"); ol("STAX D"); } else zzcall("CCPINT"); } /* ** move primary register to secondary */ move() { ol("MOV D,H"); ol("MOV E,L"); } /* ** swap primary and secondary registers */ swap() { ol("XCHG;;"); /* peephole() uses trailing ";;" */ } /* ** partial instruction to get immediate value ** into the primary register */ immed() { ot("LXI H,"); } /* ** partial instruction to get immediate operand ** into secondary register */ immed2() { ot("LXI D,"); } /* ** push primary register onto stack */ zzpush() { ol("PUSH H"); csp=csp-BPW; } /* ** unpush or pop as required */ smartpop(lval, start) int lval[]; char *start; { if(lval[5]) zzpop(); /* secondary was used */ else unpush(start); } /* ** replace a push with a swap */ unpush(dest) char *dest; { int i; char *sour; #ifdef TAB sour="\tXCHG;;"; /* peephole() uses trailing ";;" */ #else /* TAB */ sour=" XCHG;;"; /* peephole() uses trailing ";;" */ #endif /* TAB */ while(*sour) *dest++ = *sour++; sour=stagenext; while(--sour > dest) { /* adjust stack references */ #ifdef TAB if(streq(sour,"\tDAD SP")) { #else /* TAB */ if(streq(sour," DAD SP")) { #endif /* TAB */ --sour; i=BPW; while(numeric(*(--sour))) { if((*sour = *sour-i) < '0') { *sour = *sour+10; i=1; } else i=0; } } } csp=csp+BPW; } /* ** pop stack to the secondary register */ zzpop() { ol("POP D"); csp=csp+BPW; } /* ** swap primary register and stack */ swapstk() { ol("XTHL"); } /* ** process switch statement */ sw() { zzcall("CCSWITCH"); } /* ** call specified subroutine name */ zzcall(sname) char *sname; { ot("CALL "); outstr(sname); nl(); } /* ** return from subroutine */ zzret() { ol("RET"); } /* ** perform subroutine call to value on stack */ callstk() { immed(); outstr("$+5"); nl(); swapstk(); ol("PCHL"); csp=csp+BPW; } /* ** jump to internal label number */ jump(label) int label; { ot("JMP "); printlabel(label); nl(); } /* ** test primary register and jump if false */ testjump(label) int label; { ol("MOV A,H"); ol("ORA L"); ot("JZ "); printlabel(label); nl(); } /* ** test primary register against zero and jump if false */ #ifdef FULLC zerojump(oper, label, lval) int (*oper)(), label, lval[]; { clearstage(lval[7], 0); /* purge conventional code */ (*oper)(label); } #else /* FULLC */ zerojump(oper, label, lval) int oper, label, lval[]; { clearstage(lval[7], 0); /* purge conventional code */ oper(label); } #endif /* FULLC */ /* ** define storage according to size */ defstorage(size) int size; { if(size==1) ot("DB "); else ot("DW "); } /* ** point to following object(s) */ point() { ol("DW $+2"); } /* ** modify stack pointer to value given */ modstk(newsp, save) int newsp, save; { int k; k=newsp-csp; if(k==0)return newsp; if(k>=0) { if(k<7) { if(k&1) { ol("INX SP"); k--; } while(k) { ol("POP B"); k=k-BPW; } return newsp; } } if(k<0) { if(k>-7) { if(k&1) { ol("DCX SP"); k++; } while(k) { ol("PUSH B"); k=k+BPW; } return newsp; } } if(save) swap(); const(k); ol("DAD SP"); ol("SPHL"); if(save) swap(); return newsp; } /* ** double primary register */ doublereg() {ol("DAD H");}