|
|
1.1 root 1: #include "defs"
2:
3: #ifdef SDB
4: # include <a.out.h>
5: extern int types2[];
6: # ifndef N_SO
7: # include <stab.h>
8: # endif
9: #endif
10:
11: #include "pccdefs"
12:
13: /*
14: VAX-11/780 - SPECIFIC ROUTINES
15: */
16:
17:
18: int maxregvar = MAXREGVAR;
19: int regnum[] = {
20: 11, 10, 9, 8, 7, 6 };
21: static int regmask[] = {
22: 0, 0x800, 0xc00, 0xe00, 0xf00, 0xf80, 0xfc0 };
23:
24:
25:
26: ftnint intcon[14] =
27: {
28: 2, 2, 2, 2,
29: 15, 31, 24, 56,
30: -128, -128, 127, 127,
31: 32767, 2147483647 };
32:
33: #if HERE == VAX
34: /* then put in constants in octal */
35: long realcon[6][2] =
36: {
37: { 0200, 0 },
38: { 0200, 0 },
39: { 037777677777, 0 },
40: { 037777677777, 037777777777 },
41: { 032200, 0 },
42: { 022200, 0 }
43: };
44:
45: #else
46: double realcon[6] =
47: {
48: 2.9387358771e-39,
49: 2.938735877055718800e-39
50: 1.7014117332e+38,
51: 1.701411834604692250e+38
52: 5.960464e-8,
53: 1.38777878078144567e-17,
54: };
55: #endif
56:
57:
58:
59:
60: prsave(proflab)
61: int proflab;
62: {
63: if(profileflag)
64: {
65: fprintf(asmfile, "L%d:\t.space\t4\n", proflab);
66: p2pi("\tmovab\tL%d,r0", proflab);
67: p2pass("\tjsb\tmcount");
68: }
69: p2pi("\tsubl2\t$LF%d,sp", procno);
70: }
71:
72:
73:
74: goret(type)
75: int type;
76: {
77: #ifdef SDB
78: char *stabdline();
79:
80: if (sdbflag)
81: p2pass(stabdline(N_RFUN, lineno));
82: #endif
83: p2pass("\tret");
84: }
85:
86:
87:
88:
89: /*
90: * move argument slot arg1 (relative to ap)
91: * to slot arg2 (relative to ARGREG)
92: */
93:
94: mvarg(type, arg1, arg2)
95: int type, arg1, arg2;
96: {
97: p2pij("\tmovl\t%d(ap),%d(fp)", arg1+ARGOFFSET, arg2+argloc);
98: }
99:
100:
101:
102:
103: prlabel(fp, k)
104: FILEP fp;
105: int k;
106: {
107: fprintf(fp, "L%d:\n", k);
108: }
109:
110:
111:
112: prconi(fp, type, n)
113: FILEP fp;
114: int type;
115: ftnint n;
116: {
117: fprintf(fp, "\t%s\t%ld\n", (type==TYSHORT ? ".word" : ".long"), n);
118: }
119:
120:
121:
122: prcona(fp, a)
123: FILEP fp;
124: ftnint a;
125: {
126: fprintf(fp, "\t.long\tL%ld\n", a);
127: }
128:
129:
130:
131: #ifndef vax
132: prconr(fp, type, x)
133: FILEP fp;
134: int type;
135: float x;
136: {
137: fprintf(fp, "\t%s\t0f%e\n", (type==TYREAL ? ".float" : ".double"), x);
138: }
139: #endif
140:
141: #ifdef vax
142: prconr(fp, type, x)
143: FILEP fp;
144: int type;
145: double x;
146: {
147: /* non-portable cheat to preserve bit patterns */
148: union {
149: double xd;
150: long int xl[2];
151: } cheat;
152: cheat.xd = x;
153: if(type == TYREAL)
154: {
155: float y = x;
156: fprintf(fp, "\t.long\t0x%X\n", *(long *) &y);
157: }
158: else
159: fprintf(fp, "\t.long\t0x%X,0x%X\n", cheat.xl[0], cheat.xl[1]);
160: }
161: #endif
162:
163:
164:
165: praddr(fp, stg, varno, offset)
166: FILE *fp;
167: int stg, varno;
168: ftnint offset;
169: {
170: char *memname();
171:
172: if(stg == STGNULL)
173: fprintf(fp, "\t.long\t0\n");
174: else
175: {
176: fprintf(fp, "\t.long\t%s", memname(stg,varno));
177: if(offset)
178: fprintf(fp, "+%ld", offset);
179: fprintf(fp, "\n");
180: }
181: }
182:
183:
184:
185:
186: preven(k)
187: int k;
188: {
189: register int lg;
190:
191: if(k > 4)
192: lg = 3;
193: else if(k > 2)
194: lg = 2;
195: else if(k > 1)
196: lg = 1;
197: else
198: return;
199: fprintf(asmfile, "\t.align\t%d\n", lg);
200: }
201:
202:
203:
204: vaxgoto(index, nlab, labs)
205: expptr index;
206: register int nlab;
207: struct Labelblock *labs[];
208: {
209: register int i;
210: register int arrlab;
211:
212: putforce(TYINT, index);
213: p2pi("\tcasel\tr0,$1,$%d", nlab-1);
214: p2pi("L%d:", arrlab = newlabel() );
215: for(i = 0; i< nlab ; ++i)
216: if( labs[i] )
217: p2pij("\t.word\tL%d-L%d", labs[i]->labelno, arrlab);
218: }
219:
220:
221: prarif(p, neg, zer, pos)
222: expptr p;
223: int neg, zer, pos;
224: {
225: int vtype = p->headblock.vtype; /* putforce() will free p */
226: putforce(p->headblock.vtype, p);
227: if( ISINT(vtype) )
228: p2pass("\ttstl\tr0");
229: else
230: p2pass("\ttstd\tr0");
231: p2pi("\tjlss\tL%d", neg);
232: p2pi("\tjeql\tL%d", zer);
233: p2pi("\tjbr\tL%d", pos);
234: }
235:
236:
237:
238:
239: char *memname(stg, mem)
240: int stg, mem;
241: {
242: static char s[20];
243:
244: switch(stg)
245: {
246: case STGCOMMON:
247: case STGEXT:
248: sprintf(s, "_%s", varstr(XL, extsymtab[mem].extname) );
249: break;
250:
251: case STGBSS:
252: case STGINIT:
253: sprintf(s, "v.%d", mem);
254: break;
255:
256: case STGCONST:
257: sprintf(s, "L%d", mem);
258: break;
259:
260: case STGEQUIV:
261: sprintf(s, "q.%d", mem+eqvstart);
262: break;
263:
264: default:
265: badstg("memname", stg);
266: }
267: return(s);
268: }
269:
270: /*
271: * this shouldn't be here (or memname shouldn't)
272: * but i'm too lazy to fix it
273: */
274:
275: char *
276: ftnname(stg, name)
277: char *name;
278: {
279: static char s[40];
280:
281: switch (stg) {
282: case STGCOMMON:
283: case STGEXT:
284: sprintf(s, "_%s", varstr(XL, name) );
285: break;
286: default:
287: badstg("ftnname", stg);
288: }
289: return (s);
290: }
291:
292:
293:
294:
295: prlocvar(s, len)
296: char *s;
297: ftnint len;
298: {
299: fprintf(asmfile, "\t.lcomm\t%s,%ld\n", s, len);
300: }
301:
302:
303:
304: prext(name, leng, init)
305: char *name;
306: ftnint leng;
307: int init;
308: {
309: if(leng == 0)
310: fprintf(asmfile, "\t.globl\t_%s\n", name);
311: else
312: fprintf(asmfile, "\t.comm\t_%s,%ld\n", name, leng);
313: }
314:
315:
316:
317:
318:
319: prendproc()
320: {
321: }
322:
323:
324:
325:
326: prtail()
327: {
328: }
329:
330:
331:
332:
333:
334: prolog(ep, argvec)
335: struct Entrypoint *ep;
336: Addrp argvec;
337: {
338: int i, argslot;
339: int size;
340: register chainp p;
341: register Namep q;
342: register struct Dimblock *dp;
343: expptr tp;
344:
345: p2pass("\t.align\t1");
346:
347:
348: if(procclass == CLMAIN) {
349: if(fudgelabel)
350: {
351: if(ep->entryname) {
352: p2ps("_%s:", varstr(XL, ep->entryname->extname));
353: p2pi("\t.word\tLWM%d", procno);
354: }
355: putlabel(fudgelabel);
356: fudgelabel = 0;
357: fixlwm();
358: }
359: else
360: {
361: p2pass( "_MAIN__:" );
362: if(ep->entryname == NULL)
363: p2pi("\t.word\tLWM%d", procno);
364: }
365:
366: } else if(ep->entryname)
367: if(fudgelabel)
368: {
369: putlabel(fudgelabel);
370: fudgelabel = 0;
371: fixlwm();
372: }
373: else
374: {
375: p2ps("_%s:", varstr(XL, ep->entryname->extname));
376: p2pi("\t.word\tLWM%d", procno);
377: prsave(newlabel());
378: }
379:
380: if(procclass == CLBLOCK)
381: return;
382: if(argvec)
383: {
384: argloc = argvec->memoffset->constblock.Const.ci + SZINT;
385: /* first slot holds count */
386: if(proctype == TYCHAR)
387: {
388: mvarg(TYADDR, 0, chslot);
389: mvarg(TYLENG, SZADDR, chlgslot);
390: argslot = SZADDR + SZLENG;
391: }
392: else if( ISCOMPLEX(proctype) )
393: {
394: mvarg(TYADDR, 0, cxslot);
395: argslot = SZADDR;
396: }
397: else
398: argslot = 0;
399:
400: for(p = ep->arglist ; p ; p =p->nextp)
401: {
402: q = (Namep) (p->datap);
403: mvarg(TYADDR, argslot, q->vardesc.varno);
404: argslot += SZADDR;
405: }
406: for(p = ep->arglist ; p ; p = p->nextp)
407: {
408: q = (Namep) (p->datap);
409: if(q->vtype==TYCHAR && q->vclass!=CLPROC)
410: {
411: if(q->vleng && ! ISCONST(q->vleng) )
412: mvarg(TYLENG, argslot,
413: q->vleng->addrblock.memno);
414: argslot += SZLENG;
415: }
416: }
417: p2pi("\taddl3\t$%d,fp,ap", argloc-ARGOFFSET);
418: p2pi("\tmovl\t$%d,(ap)\n", lastargslot/SZADDR);
419: }
420:
421: for(p = ep->arglist ; p ; p = p->nextp)
422: {
423: q = (Namep) (p->datap);
424: if(dp = q->vdim)
425: {
426: for(i = 0 ; i < dp->ndim ; ++i)
427: if(dp->dims[i].dimexpr)
428: puteq( fixtype(cpexpr(dp->dims[i].dimsize)),
429: fixtype(cpexpr(dp->dims[i].dimexpr)));
430: size = typesize[ q->vtype ];
431: if(q->vtype == TYCHAR)
432: if( ISICON(q->vleng) )
433: size *= q->vleng->constblock.Const.ci;
434: else
435: size = -1;
436:
437: /* on VAX, get more efficient subscripting if subscripts
438: have zero-base, so fudge the argument pointers for arrays.
439: Not done if array bounds are being checked.
440: */
441: if(dp->basexpr)
442: puteq( cpexpr(fixtype(dp->baseoffset)),
443: cpexpr(dp->basexpr = fixtype(dp->basexpr)));
444:
445: if(! checksubs)
446: {
447: if(dp->basexpr)
448: {
449: if(size > 0)
450: tp = (expptr) ICON(size);
451: else
452: tp = (expptr) cpexpr(q->vleng);
453: putforce(TYINT,
454: fixtype( mkexpr(OPSTAR, tp,
455: cpexpr(dp->baseoffset)) ));
456: p2pi("\tsubl2\tr0,%d(ap)",
457: p->datap->nameblock.vardesc.varno +
458: ARGOFFSET);
459: }
460: else if(dp->baseoffset->constblock.Const.ci != 0)
461: {
462: char buff[25];
463: if(size > 0)
464: {
465: sprintf(buff, "\tsubl2\t$%ld,%d(ap)",
466: dp->baseoffset->constblock.Const.ci * size,
467: p->datap->nameblock.vardesc.varno +
468: ARGOFFSET);
469: }
470: else {
471: putforce(TYINT, mkexpr(OPSTAR, cpexpr(dp->baseoffset),
472: cpexpr(q->vleng) ));
473: sprintf(buff, "\tsubl2\tr0,%d(ap)",
474: p->datap->nameblock.vardesc.varno +
475: ARGOFFSET);
476: }
477: p2pass(buff);
478: }
479: }
480: }
481: }
482:
483: if(typeaddr)
484: puteq( cpexpr(typeaddr), mkaddcon(ep->typelabel) );
485: /* replace to avoid long jump problem
486: putgoto(ep->entrylabel);
487: */
488: p2pi("\tjmp\tL%d", ep->entrylabel);
489: }
490:
491: fixlwm()
492: {
493: extern lwmno;
494: if (lwmno == procno)
495: return;
496: fprintf(asmfile, "\t.set\tLWM%d,0x%x\n",
497: procno, regmask[highregvar]);
498: lwmno = procno;
499: }
500:
501:
502: prhead(fp)
503: FILEP fp;
504: {
505: #if FAMILY==PCC
506: p2triple(P2LBRACKET, ARGREG-highregvar, procno);
507: p2word( (long) (BITSPERCHAR*autoleng) );
508: p2flush();
509: #endif
510: }
511:
512:
513:
514: prdbginfo()
515: {
516: }
517:
518: #ifdef SDB
519:
520:
521: # ifdef UCBVAXASM
522: char *stabdline(code, type)
523: int code;
524: int type;
525: {
526: static char buff[30];
527:
528: sprintf(buff, "\t.stabd\t0x%x,0,%d", code, type);
529: return(buff);
530: }
531: # endif
532:
533:
534: prstab(s, code, type, loc)
535: char *s, *loc;
536: int code, type;
537: {
538: char * stabline();
539:
540: if(sdbflag)
541: p2pass( stabline(s,code,type,loc) );
542: }
543:
544:
545:
546: char *stabline(s, code, type, loc)
547: register char *s;
548: int code;
549: int type;
550: char *loc;
551: {
552: static char buff[512] = "\t.stab\t\t";
553: register char *t;
554: register int i = 0;
555:
556: #ifdef UCBVAXASM
557: t = buff + 8;
558: if(s == NULL)
559: buff[6] = 'n'; /* .stabn line */
560: else
561: {
562: buff[6] = 's'; /* .stabs line */
563: *t++ = '"';
564: while(*s!='\0' && *s!=' ')
565: {
566: #ifndef UCBPASS2
567: if (i == 8)
568: break;
569: #endif
570: *t++ = *s++;
571: ++i;
572: }
573: *t++ = '"';
574: *t++ = ',';
575: }
576:
577: #else
578: t = buff + 7;
579: if(s)
580: while( *s!='\0' && *s!=' ' && i<8 )
581: {
582: *t++ = '\'';
583: *t++ = *s++;
584: *t++ = ',';
585: ++i;
586: }
587: for( ; i<8 ; ++i)
588: {
589: *t++ = '0';
590: *t++ = ',';
591: }
592: #endif
593:
594:
595: sprintf(t, "0x%x,0,%d,%s", code, type, (loc? loc : "0") );
596: return(buff);
597: }
598:
599:
600: /* type cookies for pi */
601:
602: #define BASIC 5 /* width of basic type */
603: #define PTR 01 /* pointer */
604: #define FTN 02 /* function */
605: #define ARY 03 /* array */
606: #define OF 2 /* shift for `ftn ary ptr of' */
607:
608: /*
609: * extra table of our types to sdb's types
610: * our code generator is still pcc1, but sdb expects pcc2
611: * to be safe, say exactly what we mean here
612: */
613:
614: int sdbtypes[] = {
615: 0, /* TYUNKNOWN 0 */
616: PTR|4, /* TYADDR 1 == ptr to int. eh? */
617: 3, /* TYSHORT 2 */
618: 5, /* TYLONG 3 */
619: 6, /* TYREAL 4 */
620: 7, /* TYDREAL 5 */
621: 6, /* TYCOMPLEX 6 == float */
622: 7, /* TYDCOMPLEX 7 == double */
623: 5, /* TYLOGICAL 8 == long? */
624: 2, /* TYCHAR 9 */
625: 4, /* TYSUBR 10 == int */
626: 0, /* TYERROR 11 */
627: };
628:
629: #define STRTY 8
630: #define VOID 16
631:
632: stabtype(p)
633: register Namep p;
634: {
635: register int func = 0, type = 0, vt = p->vtype;
636: if(p->vstg == STGARG) {
637: type = PTR;
638: if(p->vclass == CLPROC) {
639: type = (FTN << OF) | PTR;
640: func = 1;
641: }
642: }
643: else if(p->vdim)
644: type = ARY;
645: else if(p->vclass == CLPROC) {
646: type = FTN;
647: func = 1;
648: }
649: type <<= BASIC;
650: if (func && (ISCOMPLEX(vt) || vt == TYCHAR))
651: type |= VOID;
652: else
653: type |= ISCOMPLEX(vt) ? STRTY : types2[vt];
654: if (type == 2) type |= (ARY << BASIC);
655: return type;
656: }
657:
658: prstabtype(xp, q, stype, loc)
659: struct Extsym *xp;
660: register Namep q;
661: char *loc;
662: {
663: int i;
664: char *name, *tyid = 0;
665: ftnint nelt = 0;
666: static char *dc[2] = {
667: "complex", "dcomplex" };
668:
669: prstab(name = varstr(VL,q->varname), stype, i = stabtype(q), loc);
670: if (ISCOMPLEX(q->vtype))
671: prstab(tyid = dc[q->vtype - TYCOMPLEX], N_TYID, 0, CNULL);
672: if (ISARRAY(i))
673: p2pass(stabdline(N_DIM, (int)(nelt = i1arrlen(q))));
674: if (xp)
675: commvar(name, nelt, q, tyid, i, xp);
676: }
677:
678:
679:
680: prcomssym(np, xp)
681: register Namep np;
682: register struct Extsym *xp;
683: {
684: char nbuf[40];
685:
686: sprintf(nbuf, "%d", np->voffset);
687: prstabtype(xp, np, N_SSYM, nbuf);
688: }
689:
690: #define Sgulp 2040
691: #define CVgulp 120
692:
693: /* For each common block, save the first appearance of each */
694: /* variable, along with its offset and type, for adding common */
695: /* block structures to pi's global menu */
696: commvar(name, nelt, p, tyid, type, v)
697: register char *name;
698: ftnint nelt;
699: Namep p;
700: char *tyid;
701: register struct Extsym *v;
702: {
703: static char *slast, *snext;
704: static struct Comvar *cvlast, *cvnext;
705: char *malloc(), *strcpy();
706: char *s;
707: struct Comvar *cv, *cv0, *ncv;
708: int k;
709:
710: for (cv = cv0 = v->cv; cv; cv0 = cv, cv = cv->next)
711: if (!strcmp(name, cv->name))
712: return;
713: k = strlen(name) + 1;
714: s = snext;
715: snext += k;
716: if (snext > slast) {
717: if (!(s = malloc(Sgulp)))
718: mfailure:
719: fatal("Out of memory in commvar");
720: snext = s + k;
721: slast = s + Sgulp;
722: }
723: if (cvnext >= cvlast) {
724: cvnext = (struct Comvar *)
725: malloc(CVgulp*sizeof(struct Comvar));
726: if (!cvnext)
727: goto mfailure;
728: cvlast = cvnext + CVgulp;
729: }
730: ncv = cvnext++;
731: if (cv0) cv0->next = ncv;
732: else v->cv = ncv;
733: ncv->next = 0;
734: ncv->name = strcpy(s,name);
735: ncv->type = type;
736: ncv->tyid = tyid;
737: ncv->offset = p->voffset;
738: ncv->nelt = nelt;
739: }
740: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.