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