1: #include "defs" 2: #if FAMILY == DMR 3: # include "dmrdefs" 4: #endif 5: #if FAMILY==SCJ && OUTPUT==BINARY 6: # include "scjdefs" 7: #endif 8: 9: /* 10: PDP 11-SPECIFIC PRINTING ROUTINES 11: */ 12: 13: int maxregvar = 0; 14: static char textline[50]; 15: int regnum[] = { 3, 2 }; 16: 17: 18: prsave() 19: { 20: } 21: 22: 23: 24: goret(type) 25: int type; 26: { 27: #if FAMILY == DMR 28: p2op(P2RETURN); 29: #endif 30: #if FAMILY==SCJ 31: p2pass(sprintf(textline, "\tjmp\tcret")); 32: #endif 33: } 34: 35: 36: 37: 38: /* 39: * move argument slot arg1 (relative to ap) 40: * to slot arg2 (relative to ARGREG) 41: */ 42: 43: mvarg(type, arg1, arg2) 44: int type, arg1, arg2; 45: { 46: mvarg1(arg1+4, arg2); 47: if(type == TYLONG) 48: mvarg1(arg1+6, arg2+2); 49: } 50: 51: 52: 53: 54: mvarg1(m, n) 55: int m, n; 56: { 57: #if FAMILY == DMR 58: p2reg(ARGREG, P2SHORT|P2PTR); 59: p2op2(P2ICON, P2SHORT); 60: p2i(n); 61: p2op2(P2PLUS, P2SHORT|P2PTR); 62: p2op2(P2INDIRECT, P2SHORT); 63: p2reg(AUTOREG, P2SHORT|P2PTR); 64: p2op2(P2ICON, P2SHORT); 65: p2i(m); 66: p2op2(P2PLUS, P2SHORT|P2PTR); 67: p2op2(P2INDIRECT, P2SHORT); 68: p2op2(P2ASSIGN, P2SHORT); 69: putstmt(); 70: #endif 71: #if FAMILY == SCJ 72: p2pass(sprintf(textline, "\tmov\t%d.(r5),%d.(r4)", m, n)); 73: #endif 74: } 75: 76: 77: 78: 79: prlabel(fp, k) 80: FILEP fp; 81: int k; 82: { 83: fprintf(fp, "L%d:\n", k); 84: } 85: 86: 87: 88: prconi(fp, type, n) 89: FILEP fp; 90: int type; 91: ftnint n; 92: { 93: register int *np; 94: np = &n; 95: if(type == TYLONG) 96: fprintf(fp, "\t%d.;%d.\n", np[0], np[1]); 97: else 98: fprintf(fp, "\t%d.\n", np[1]); 99: } 100: 101: 102: 103: prcona(fp, a) 104: FILEP fp; 105: ftnint a; 106: { 107: fprintf(fp, "L%ld\n", a); 108: } 109: 110: 111: 112: #if HERE!=PDP11 113: BAD NEWS 114: #endif 115: 116: #if HERE==PDP11 117: prconr(fp, type, x) 118: FILEP fp; 119: int type; 120: double x; 121: { 122: register int k, *n; 123: n = &x; /* nonportable cheat */ 124: k = (type==TYREAL ? 2 : 4); 125: fprintf(fp, "\t"); 126: while(--k >= 0) 127: fprintf(fp, "%d.%c", *n++, (k==0 ? '\n' : ';') ); 128: } 129: #endif 130: 131: 132: 133: 134: preven(k) 135: int k; 136: { 137: if(k > 1) 138: fprintf(asmfile, "\t.even\n", k); 139: } 140: 141: 142: 143: #if FAMILY == SCJ 144: 145: prcmgoto(p, nlab, skiplabel, labarray) 146: expptr p; 147: int nlab, skiplabel, labarray; 148: { 149: int regno; 150: 151: putforce(p->vtype, p); 152: 153: if(p->vtype == TYLONG) 154: { 155: regno = 1; 156: p2pass(sprintf(textline, "\ttst\tr0")); 157: p2pass(sprintf(textline, "\tbne\tL%d", skiplabel)); 158: } 159: else 160: regno = 0; 161: 162: p2pass(sprintf(textline, "\tcmp\tr%d,$%d.", regno, nlab)); 163: p2pass(sprintf(textline, "\tbhi\tL%d", skiplabel)); 164: p2pass(sprintf(textline, "\tasl\tr%d", regno)); 165: p2pass(sprintf(textline, "\tjmp\t*L%d(r%d)", labarray, regno)); 166: } 167: 168: 169: prarif(p, neg,zer,pos) 170: expptr p; 171: int neg, zer, pos; 172: { 173: register int ptype; 174: 175: putforce( ptype = p->vtype, p); 176: if( ISINT(ptype) ) 177: { 178: p2pass(sprintf(textline, "\ttst\tr0")); 179: p2pass(sprintf(textline, "\tjlt\tL%d", neg)); 180: p2pass(sprintf(textline, "\tjgt\tL%d", pos)); 181: if(ptype != TYSHORT) 182: { 183: p2pass(sprintf(textline, "\ttst\tr1")); 184: p2pass(sprintf(textline, "\tjeq\tL%d", zer)); 185: } 186: p2pass(sprintf(textline, "\tjbr\tL%d", pos)); 187: } 188: else 189: { 190: p2pass(sprintf(textline, "\ttstf\tr0")); 191: p2pass(sprintf(textline, "\tcfcc")); 192: p2pass(sprintf(textline, "\tjeq\tL%d", zer)); 193: p2pass(sprintf(textline, "\tjlt\tL%d", neg)); 194: p2pass(sprintf(textline, "\tjmp\tL%d", pos)); 195: } 196: } 197: 198: #endif 199: 200: 201: 202: 203: char *memname(stg, mem) 204: int stg, mem; 205: { 206: static char s[20]; 207: 208: switch(stg) 209: { 210: case STGCOMMON: 211: case STGEXT: 212: sprintf(s, "_%s", varstr(XL, extsymtab[mem].extname) ); 213: break; 214: 215: case STGBSS: 216: case STGINIT: 217: sprintf(s, "v.%d", mem); 218: break; 219: 220: case STGCONST: 221: sprintf(s, "L%d", mem); 222: break; 223: 224: case STGEQUIV: 225: sprintf(s, "q.%d", mem); 226: break; 227: 228: default: 229: fatal1("memname: invalid vstg %d", stg); 230: } 231: return(s); 232: } 233: 234: 235: prlocvar(s, len) 236: char *s; 237: ftnint len; 238: { 239: fprintf(asmfile, "%s:", s); 240: prskip(asmfile, len); 241: } 242: 243: 244: 245: prext(name, leng, init) 246: char *name; 247: ftnint leng; 248: int init; 249: { 250: if(leng==0 || init) 251: fprintf(asmfile, "\t.globl\t_%s\n", name); 252: else 253: fprintf(asmfile, "\t.comm\t_%s,%ld.\n", name, leng); 254: } 255: 256: 257: 258: prendproc() 259: { 260: } 261: 262: 263: 264: prtail() 265: { 266: #if FAMILY == SCJ 267: p2pass(sprintf(textline, "\t.globl\tcsv,cret")); 268: #else 269: p2op(P2EOF); 270: #endif 271: } 272: 273: 274: 275: prolog(ep, argvec) 276: struct entrypoint *ep; 277: struct addrblock *argvec; 278: { 279: int i, argslot, proflab; 280: register chainp p; 281: register struct nameblock *q; 282: register struct dimblock *dp; 283: struct constblock *mkaddcon(); 284: 285: if(procclass == CLMAIN) 286: prentry("MAIN__"); 287: 288: if(ep->entryname) 289: prentry( varstr(XL, ep->entryname->extname) ); 290: 291: if(procclass == CLBLOCK) 292: return; 293: if(profileflag) 294: proflab = newlabel(); 295: #if FAMILY == SCJ 296: if(profileflag) 297: { 298: fprintf(asmfile, "L%d:\t. = .+2\n", proflab); 299: p2pass(sprintf(textline, "\tmov\t$L%d,r0", proflab)); 300: p2pass(sprintf(textline, "\tjsr\tpc,mcount")); 301: } 302: p2pass(sprintf(textline, "\tjsr\tr5,csv")); 303: p2pass(sprintf(textline, "\tsub\t$.F%d,sp", procno)); 304: #else 305: if(profileflag) 306: p2op2(P2PROFILE, proflab); 307: p2op(P2SAVE); 308: p2op2(P2SETSTK, ( (((int) autoleng)+1) & ~01) ); 309: #endif 310: 311: if(argvec == NULL) 312: addreg(argloc = 4); 313: else 314: { 315: addreg( argloc = argvec->memoffset->const.ci ); 316: if(proctype == TYCHAR) 317: { 318: mvarg(TYADDR, 0, chslot); 319: mvarg(TYLENG, SZADDR, chlgslot); 320: argslot = SZADDR + SZLENG; 321: } 322: else if( ISCOMPLEX(proctype) ) 323: { 324: mvarg(TYADDR, 0, cxslot); 325: argslot = SZADDR; 326: } 327: else 328: argslot = 0; 329: 330: for(p = ep->arglist ; p ; p =p->nextp) 331: { 332: q = p->datap; 333: mvarg(TYADDR, argslot, q->vardesc.varno); 334: argslot += SZADDR; 335: } 336: for(p = ep->arglist ; p ; p = p->nextp) 337: { 338: q = p->datap; 339: if(q->vtype==TYCHAR || q->vclass==CLPROC) 340: { 341: if( q->vleng && ! ISCONST(q->vleng) ) 342: mvarg(TYLENG, argslot, q->vleng->memno); 343: argslot += SZLENG; 344: } 345: } 346: } 347: 348: for(p = ep->arglist ; p ; p = p->nextp) 349: if(dp = ( (struct nameblock *) (p->datap) ) ->vdim) 350: { 351: for(i = 0 ; i < dp->ndim ; ++i) 352: if(dp->dims[i].dimexpr) 353: puteq( fixtype(cpexpr(dp->dims[i].dimsize)), 354: fixtype(cpexpr(dp->dims[i].dimexpr))); 355: if(dp->basexpr) 356: puteq( cpexpr(fixtype(dp->baseoffset)), 357: cpexpr(fixtype(dp->basexpr))); 358: } 359: 360: if(typeaddr) 361: puteq( cpexpr(typeaddr), mkaddcon(ep->typelabel) ); 362: putgoto(ep->entrylabel); 363: } 364: 365: 366: 367: prentry(s) 368: char *s; 369: { 370: #if FAMILY == SCJ 371: p2pass(sprintf(textline, "_%s:", s)); 372: #else 373: p2op(P2RLABEL); 374: putc('_', textfile); 375: p2str(s); 376: #endif 377: } 378: 379: 380: 381: 382: addreg(k) 383: int k; 384: { 385: #if FAMILY == SCJ 386: p2pass(sprintf(textline, "\tmov\tr5,r4")); 387: p2pass(sprintf(textline, "\tadd\t$%d.,r4", k)); 388: #else 389: p2reg(ARGREG, P2SHORT); 390: p2reg(AUTOREG, P2SHORT); 391: p2op2(P2ICON, P2SHORT); 392: p2i(k); 393: p2op2(P2PLUS, P2SHORT); 394: p2op2(P2ASSIGN, P2SHORT); 395: putstmt(); 396: #endif 397: } 398: 399: 400: 401: 402: 403: prhead(fp) 404: FILEP fp; 405: { 406: #if FAMILY==SCJ 407: # if OUTPUT == BINARY 408: p2triple(P2LBRACKET, ARGREG-1-highregvar, procno); 409: p2word( (long) (BITSPERCHAR*autoleng) ); 410: p2flush(); 411: # else 412: fprintf(fp, "[%02d\t%06ld\t%02d\t\n", procno, 413: BITSPERCHAR*autoleng, ARGREG-1-highregvar); 414: # endif 415: #endif 416: } 417: 418: prdbginfo() 419: { 420: register char *s; 421: char *t, buff[50]; 422: register struct nameblock *p; 423: struct hashentry *hp; 424: 425: if(s = entries->entryname->extname) 426: s = varstr(XL, s); 427: else if(procclass == CLMAIN) 428: s = "MAIN__"; 429: else 430: return; 431: 432: if(procclass != CLBLOCK) 433: fprintf(asmfile, "~~%s = _%s\n", s, s); 434: 435: for(hp = hashtab ; hp<lasthash ; ++hp) 436: if(p = hp->varp) 437: { 438: s = NULL; 439: if(p->vstg == STGARG) 440: s = sprintf(buff, "%o", p->vardesc.varno+argloc); 441: else if(p->vclass == CLVAR) 442: switch(p->vstg) 443: { 444: case STGBSS: 445: case STGINIT: 446: case STGEQUIV: 447: t = memname(p->vstg, p->vardesc.varno); 448: if(p->voffset) 449: s = sprintf(buff, "%s+%o", t, p->voffset); 450: else 451: s = sprintf(buff, "%s", t); 452: break; 453: 454: case STGAUTO: 455: s = sprintf(buff, "%o", p->voffset); 456: break; 457: 458: default: 459: break; 460: } 461: if(s) 462: fprintf(asmfile, "~%s = %s\n", varstr(VL,p->varname), s); 463: } 464: fprintf(asmfile, "~~:\n"); 465: }