1*47951Sbostic /*-
2*47951Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47951Sbostic  * All rights reserved.
4*47951Sbostic  *
5*47951Sbostic  * %sccs.include.proprietary.c%
6*47951Sbostic  */
7*47951Sbostic 
8*47951Sbostic #ifndef lint
9*47951Sbostic static char sccsid[] = "@(#)tahoe.c	5.3 (Berkeley) 04/12/91";
10*47951Sbostic #endif /* not lint */
11*47951Sbostic 
1243225Sbostic #include "defs.h"
1343225Sbostic 
1443225Sbostic #ifdef SDB
1543225Sbostic #	include <a.out.h>
1643225Sbostic extern int types2[];
1743225Sbostic #	ifndef N_SO
1843225Sbostic #		include <stab.h>
1943225Sbostic #	endif
2043225Sbostic #endif
2143225Sbostic 
2243225Sbostic #include "pcc.h"
2343225Sbostic 
2443225Sbostic /*
2543225Sbostic 	TAHOE - SPECIFIC ROUTINES
2643225Sbostic */
2743225Sbostic 
2843225Sbostic int maxregvar = MAXREGVAR;
2943225Sbostic int regnum[] =  { 10, 9, 8, 7, 6 } ;
3043225Sbostic 
3143225Sbostic ftnint intcon[14] =
3243225Sbostic 	{ 2, 2, 2, 2,
3343225Sbostic 	  15, 31, 24, 56,
3443225Sbostic 	  -128, -128, 127, 127,
3543225Sbostic 	  0x7FFF, 0x7FFFFFFF };
3643225Sbostic 
3743225Sbostic #if HERE == VAX || HERE == TAHOE
3843225Sbostic 	/* then put in constants in hex */
3943225Sbostic short realcon[6][4] =
4043225Sbostic 	{
4143225Sbostic 		{ 0x80, 0, 0, 0 },
4243225Sbostic 		{ 0x80, 0, 0, 0 },
4343225Sbostic 		{ 0x7FFF, 0xFFFF, 0, 0 },
4443225Sbostic 		{ 0x7FFF, 0xFFFF, 0xFFFF, 0xFFFF },
4543225Sbostic 		{ 0x3480, 0, 0, 0 },
4643225Sbostic 		{ 0x2480, 0, 0, 0 },
4743225Sbostic 	};
4843225Sbostic #else
4943225Sbostic double realcon[6] =
5043225Sbostic 	{
5143225Sbostic 	2.9387358771e-39,		/* 2 ** -128 */
5243225Sbostic 	2.938735877055718800e-39,	/* 2 ** -128 */
5343225Sbostic 	1.7014117332e+38,		/* 2**127 * (1 - 2**-24) */
5443225Sbostic 	1.701411834604692250e+38,	/* 2**127 * (1 - 2**-56) */
5543225Sbostic 	5.960464e-8,			/* 2 ** -24 */
5643225Sbostic 	1.38777878078144567e-17,	/* 2 ** -56 */
5743225Sbostic 	};
5843225Sbostic #endif
5943225Sbostic 
6043225Sbostic /*
6143225Sbostic  * The VAX assembler has a serious and not easily fixable problem
6243225Sbostic  * with generating instructions that contain expressions of the form
6343225Sbostic  * label1-label2 where there are .align's in-between the labels.
6443225Sbostic  * Therefore, the compiler must keep track of the offsets and output
6543225Sbostic  * .space where needed.
6643225Sbostic  */
6743225Sbostic LOCAL int i_offset;		/* initfile offset */
6843225Sbostic LOCAL int a_offset;		/* asmfile offset */
6943225Sbostic 
prsave(proflab)7043225Sbostic prsave(proflab)
7143225Sbostic int proflab;
7243225Sbostic {
7343225Sbostic if(profileflag)
7443225Sbostic 	{
7543225Sbostic 	fprintf(asmfile, "\t.align\t2\n");
7643225Sbostic 	fprintf(asmfile, "L%d:\t.long\t0\n", proflab);
7743225Sbostic 	p2pi("\tpushl\t$L%d", proflab);
7843225Sbostic 	p2pass("\tcallf\t$8,mcount");
7943225Sbostic 	}
8043225Sbostic p2pi("\tsubl3\t$LF%d,fp,sp", procno);
8143225Sbostic }
8243225Sbostic 
goret(type)8343225Sbostic goret(type)
8443225Sbostic int type;
8543225Sbostic {
8643225Sbostic register int r = 0;
8743225Sbostic switch(type) {	/* from retval */
8843225Sbostic 	case TYDREAL:
8943225Sbostic 		r++;
9043225Sbostic 
9143225Sbostic 	case TYLOGICAL:
9243225Sbostic 	case TYADDR:
9343225Sbostic 	case TYSHORT:
9443225Sbostic 	case TYLONG:
9543225Sbostic 	case TYREAL:
9643225Sbostic 		r++;
9743225Sbostic 
9843225Sbostic 	case TYCHAR:
9943225Sbostic 	case TYCOMPLEX:
10043225Sbostic 	case TYDCOMPLEX:
10143225Sbostic 		break;
10243225Sbostic 	case TYSUBR:
10343225Sbostic 		if (substars) r++;
10443225Sbostic 		break;
10543225Sbostic 	default:
10643225Sbostic 		badtype("goret", type);
10743225Sbostic 	}
10843225Sbostic p2pi("\tret#%d", r);
10943225Sbostic }
11043225Sbostic 
11143225Sbostic /*
11243225Sbostic  * move argument slot arg1 (relative to fp)
11343225Sbostic  * to slot arg2 (relative to ARGREG)
11443225Sbostic  */
mvarg(type,arg1,arg2)11543225Sbostic mvarg(type, arg1, arg2)
11643225Sbostic int type, arg1, arg2;
11743225Sbostic {
11843225Sbostic p2pij("\tmovl\t%d(fp),%d(fp)", arg1+ARGOFFSET, arg2+argloc);
11943225Sbostic }
12043225Sbostic 
prlabel(fp,k)12143225Sbostic prlabel(fp, k)
12243225Sbostic FILEP fp;
12343225Sbostic int k;
12443225Sbostic {
12543225Sbostic fprintf(fp, "L%d:\n", k);
12643225Sbostic }
12743225Sbostic 
prconi(fp,type,n)12843225Sbostic prconi(fp, type, n)
12943225Sbostic FILEP fp;
13043225Sbostic int type;
13143225Sbostic ftnint n;
13243225Sbostic {
13343225Sbostic register int i;
13443225Sbostic 
13543225Sbostic if(type == TYSHORT)
13643225Sbostic 	{
13743225Sbostic 	fprintf(fp, "\t.word\t%ld\n", n);
13843225Sbostic 	i = SZSHORT;
13943225Sbostic 	}
14043225Sbostic else
14143225Sbostic 	{
14243225Sbostic 	fprintf(fp, "\t.long\t%ld\n", n);
14343225Sbostic 	i = SZLONG;
14443225Sbostic 	}
14543225Sbostic if(fp == initfile)
14643225Sbostic 	i_offset += i;
14743225Sbostic else
14843225Sbostic 	a_offset += i;
14943225Sbostic }
15043225Sbostic 
prcona(fp,a)15143225Sbostic prcona(fp, a)
15243225Sbostic FILEP fp;
15343225Sbostic ftnint a;
15443225Sbostic {
15543225Sbostic fprintf(fp, "\t.long\tL%ld\n", a);
15643225Sbostic if(fp == initfile)
15743225Sbostic 	i_offset += SZLONG;
15843225Sbostic else
15943225Sbostic 	a_offset += SZLONG;
16043225Sbostic }
16143225Sbostic 
prconr(fp,type,x)16243225Sbostic prconr(fp, type, x)
16343225Sbostic FILEP fp;
16443225Sbostic int type;
16543225Sbostic double x;
16643225Sbostic {
16743225Sbostic /*
16843225Sbostic fprintf(fp, "\t%s\t0f%e\n", (type==TYREAL ? ".float" : ".double"), x);
16943225Sbostic */
17043225Sbostic 	/* non-portable cheat to preserve bit patterns */
17143225Sbostic 	/* this code should be the same for PDP, VAX and Tahoe */
17243225Sbostic 
17343225Sbostic 	register struct sh4 {
17443225Sbostic 		unsigned short sh[4];
17543225Sbostic 	} *cheat;
17643225Sbostic 	register int i;
17743225Sbostic 
17843225Sbostic 	cheat = (struct sh4 *)&x;
17943225Sbostic 	if(type == TYREAL) {	/* force rounding */
18043225Sbostic 		float f;
18143225Sbostic 		f = x;
18243225Sbostic 		x = f;
18343225Sbostic 	}
18443225Sbostic 	fprintf(fp, "	.long	0x%04x%04x", cheat->sh[0], cheat->sh[1]);
18543225Sbostic 	if(type == TYDREAL) {
18643225Sbostic 		fprintf(fp, ", 0x%04x%04x", cheat->sh[2], cheat->sh[3]);
18743225Sbostic 		fprintf(fp, "	# .double %.17g\n", x);
18843225Sbostic 		i = SZDOUBLE;
18943225Sbostic 	}
19043225Sbostic 	else
19143225Sbostic 	{
19243225Sbostic 		fprintf(fp, "	# .float %.8g\n", x);
19343225Sbostic 		i = SZFLOAT;
19443225Sbostic 	}
19543225Sbostic if(fp == initfile)
19643225Sbostic 	i_offset += i;
19743225Sbostic else
19843225Sbostic 	a_offset += i;
19943225Sbostic }
20043225Sbostic 
praddr(fp,stg,varno,offset)20143225Sbostic praddr(fp, stg, varno, offset)
20243225Sbostic FILE *fp;
20343225Sbostic int stg, varno;
20443225Sbostic ftnint offset;
20543225Sbostic {
20643225Sbostic char *memname();
20743225Sbostic 
20843225Sbostic if(stg == STGNULL)
20943225Sbostic 	fprintf(fp, "\t.long\t0\n");
21043225Sbostic else
21143225Sbostic 	{
21243225Sbostic 	fprintf(fp, "\t.long\t%s", memname(stg,varno));
21343225Sbostic 	if(offset)
21443225Sbostic 		fprintf(fp, "+%ld", offset);
21543225Sbostic 	fprintf(fp, "\n");
21643225Sbostic 	}
21743225Sbostic if(fp == initfile)
21843225Sbostic 	i_offset += SZADDR;
21943225Sbostic else
22043225Sbostic 	a_offset += SZADDR;
22143225Sbostic }
pralign(k)22243225Sbostic pralign(k)
22343225Sbostic int k;
22443225Sbostic {
22543225Sbostic   register int lg;
22643225Sbostic 
22743225Sbostic   if (k > 4)
22843225Sbostic     lg = 3;
22943225Sbostic   else if (k > 2)
23043225Sbostic     lg = 2;
23143225Sbostic   else if (k > 1)
23243225Sbostic     lg = 1;
23343225Sbostic   else
23443225Sbostic     return;
23543225Sbostic   fprintf(initfile, "\t.align\t%d\n", lg);
23643225Sbostic i_offset += lg;
23743225Sbostic   return;
23843225Sbostic }
23943225Sbostic 
24043225Sbostic 
24143225Sbostic 
prspace(n)24243225Sbostic prspace(n)
24343225Sbostic int n;
24443225Sbostic {
24543225Sbostic 
24643225Sbostic fprintf(initfile, "\t.space\t%d\n", n);
24743225Sbostic i_offset += n;
24843225Sbostic }
24943225Sbostic 
25043225Sbostic 
preven(k)25143225Sbostic preven(k)
25243225Sbostic int k;
25343225Sbostic {
25443225Sbostic register int lg;
25543225Sbostic 
25643225Sbostic if(k > 4)
25743225Sbostic 	lg = 3;
25843225Sbostic else if(k > 2)
25943225Sbostic 	lg = 2;
26043225Sbostic else if(k > 1)
26143225Sbostic 	lg = 1;
26243225Sbostic else
26343225Sbostic 	return;
26443225Sbostic fprintf(asmfile, "\t.align\t%d\n", lg);
26543225Sbostic a_offset += lg;
26643225Sbostic }
26743225Sbostic 
praspace(n)26843225Sbostic praspace(n)
26943225Sbostic int n;
27043225Sbostic {
27143225Sbostic 
27243225Sbostic fprintf(asmfile, "\t.space\t%d\n", n);
27343225Sbostic a_offset += n;
27443225Sbostic }
27543225Sbostic 
27643225Sbostic 
casegoto(index,nlab,labs)27743225Sbostic casegoto(index, nlab, labs)
27843225Sbostic expptr index;
27943225Sbostic register int nlab;
28043225Sbostic struct Labelblock *labs[];
28143225Sbostic {
28243225Sbostic register int i;
28343225Sbostic register int arrlab;
28443225Sbostic 
28543225Sbostic putforce(TYINT, index);
28643225Sbostic p2pi("\tcasel\tr0,$1,$%d\n\t.align 1", nlab-1);
28743225Sbostic p2pi("L%d:", arrlab = newlabel() );
28843225Sbostic for(i = 0; i< nlab ; ++i)
28943225Sbostic 	if( labs[i] )
29043225Sbostic 		p2pij("\t.word\tL%d-L%d", labs[i]->labelno, arrlab);
29143225Sbostic }
29243225Sbostic 
29343225Sbostic 
prarif(p,neg,zer,pos)29443225Sbostic prarif(p, neg, zer, pos)
29543225Sbostic expptr p;
29643225Sbostic int neg, zer, pos;
29743225Sbostic {
29843225Sbostic putforce(p->headblock.vtype, p);
29943225Sbostic p2pass("\ttstl\tr0");
30043225Sbostic p2pi("\tjlss\tL%d", neg);
30143225Sbostic p2pi("\tjeql\tL%d", zer);
30243225Sbostic p2pi("\tjbr\tL%d", pos);
30343225Sbostic }
30443225Sbostic 
memname(stg,mem)30543225Sbostic char *memname(stg, mem)
30643225Sbostic int stg, mem;
30743225Sbostic {
30843225Sbostic static char s[20];
30943225Sbostic 
31043225Sbostic switch(stg)
31143225Sbostic 	{
31243225Sbostic 	case STGEXT:
31343225Sbostic 	case STGINTR:
31443225Sbostic 		if(extsymtab[mem].extname[0] == '@') {	/* function opcodes */
31543225Sbostic 			strcpy(s, varstr(XL, extsymtab[mem].extname));
31643225Sbostic 			break;
31743225Sbostic 		}
31843225Sbostic 	case STGCOMMON:
31943225Sbostic 		sprintf(s, "_%s", varstr(XL, extsymtab[mem].extname) );
32043225Sbostic 		break;
32143225Sbostic 
32243225Sbostic 	case STGBSS:
32343225Sbostic 	case STGINIT:
32443225Sbostic 		sprintf(s, "v.%d", mem);
32543225Sbostic 		break;
32643225Sbostic 
32743225Sbostic 	case STGCONST:
32843225Sbostic 		sprintf(s, "L%d", mem);
32943225Sbostic 		break;
33043225Sbostic 
33143225Sbostic 	case STGEQUIV:
33243225Sbostic 		sprintf(s, "q.%d", mem+eqvstart);
33343225Sbostic 		break;
33443225Sbostic 
33543225Sbostic 	default:
33643225Sbostic 		badstg("memname", stg);
33743225Sbostic 	}
33843225Sbostic return(s);
33943225Sbostic }
34043225Sbostic 
prlocvar(s,len)34143225Sbostic prlocvar(s, len)
34243225Sbostic char *s;
34343225Sbostic ftnint len;
34443225Sbostic {
34543225Sbostic int sz;
34643225Sbostic sz = len;
34743225Sbostic if (sz % SZINT)
34843225Sbostic 	sz += SZINT - (sz % SZINT);
34943225Sbostic fprintf(asmfile, "\t.lcomm\t%s,%ld\n", s, sz);
35043225Sbostic }
35143225Sbostic 
35243225Sbostic char *
packbytes(cp)35343225Sbostic packbytes(cp)
35443225Sbostic register Constp cp;
35543225Sbostic {
35643225Sbostic #if HERE == VAX
35743225Sbostic   static char shrt[16];
35843225Sbostic   static char lng[4];
35943225Sbostic #endif
36043225Sbostic 
36143225Sbostic   switch (cp->vtype)
36243225Sbostic     {
36343225Sbostic #if HERE == TAHOE
36443225Sbostic     case TYSHORT:
36543225Sbostic     { static short shrt;
36646308Sbostic       shrt = cp->constant.ci;
36743225Sbostic       return ((char *)&shrt);
36843225Sbostic     }
36943225Sbostic     case TYLONG:
37043225Sbostic     case TYLOGICAL:
37143225Sbostic     case TYREAL:
37243225Sbostic     case TYDREAL:
37343225Sbostic     case TYDCOMPLEX:
37446308Sbostic       return ((char *)&cp->constant);
37543225Sbostic     case TYCOMPLEX:
37643225Sbostic       { static float quad[2];
37746308Sbostic       quad[0] = cp->constant.cd[0];
37846308Sbostic       quad[1] = cp->constant.cd[1];
37943225Sbostic       return ((char *)quad);
38043225Sbostic       }
38143225Sbostic #endif
38243225Sbostic 
38343225Sbostic #if HERE == VAX
38443225Sbostic     case TYLONG:
38543225Sbostic     case TYLOGICAL:
38646308Sbostic       swab4((char *)&cp->constant.ci, lng, 4);
38743225Sbostic       return (lng);
38843225Sbostic 
38943225Sbostic     case TYSHORT:
39043225Sbostic     case TYREAL:
39143225Sbostic     case TYDREAL:
39243225Sbostic     case TYDCOMPLEX:
39346308Sbostic       swab((char *)cp->constant.cd, shrt, typesize[cp->vtype]);
39443225Sbostic       return (shrt);
39543225Sbostic     case TYCOMPLEX:
39646308Sbostic       swab((char *)cp->constant.cd, shrt, 4);
39746308Sbostic       swab((char *)&(cp->constant.cd[1]), &shrt[4], 4);
39843225Sbostic       return (shrt);
39943225Sbostic #endif
40043225Sbostic 
40143225Sbostic     default:
40243225Sbostic       badtype("packbytes", cp->vtype);
40343225Sbostic     }
40443225Sbostic }
40543225Sbostic 
40643225Sbostic #if HERE == VAX
40743225Sbostic /* correct the byte order in longs */
swab4(from,to,n)40843225Sbostic LOCAL swab4(from, to, n)
40943225Sbostic   register char *to, *from;
41043225Sbostic   register int n;
41143225Sbostic {
41243225Sbostic   while(n >= 4) {
41343225Sbostic     *to++ = from[3];
41443225Sbostic     *to++ = from[2];
41543225Sbostic     *to++ = from[1];
41643225Sbostic     *to++ = from[0];
41743225Sbostic     from += 4;
41843225Sbostic     n -= 4;
41943225Sbostic   }
42043225Sbostic   while(n >= 2) {
42143225Sbostic     *to++ = from[1];
42243225Sbostic     *to++ = from[0];
42343225Sbostic     from += 2;
42443225Sbostic     n -= 2;
42543225Sbostic   }
42643225Sbostic   if(n > 0)
42743225Sbostic 	*to = *from;
42843225Sbostic }
42943225Sbostic #endif
43043225Sbostic 
prsdata(s,len)43143225Sbostic prsdata(s, len)
43243225Sbostic register char *s; /* must be aligned if HERE==TAHOE */
43343225Sbostic register int len;
43443225Sbostic {
43543225Sbostic   static char longfmt[] = "\t.long\t0x%x\n";
43643225Sbostic   static char wordfmt[] = "\t.word\t0x%x\n";
43743225Sbostic   static char bytefmt[] = "\t.byte\t0x%x\n";
43843225Sbostic 
43943225Sbostic   register int i;
44043225Sbostic #if HERE == VAX
44143225Sbostic   char quad[8];
44243225Sbostic   swab4(s, quad, len);
44343225Sbostic   s = quad;
44443225Sbostic #endif
44543225Sbostic 
44643225Sbostic   i = 0;
44743225Sbostic   if ((len - i) >= 4)
44843225Sbostic     {
44943225Sbostic       fprintf(initfile, longfmt, *((int *) s));
45043225Sbostic       i += 4;
45143225Sbostic     }
45243225Sbostic   if ((len - i) >= 2)
45343225Sbostic     {
45443225Sbostic       fprintf(initfile, wordfmt, 0xffff & (*((short *) (s + i))));
45543225Sbostic       i += 2;
45643225Sbostic     }
45743225Sbostic   if ((len - i) > 0)
45843225Sbostic     fprintf(initfile,bytefmt, 0xff & s[i]);
45943225Sbostic 
46043225Sbostic   i_offset += len;
46143225Sbostic   return;
46243225Sbostic }
46343225Sbostic 
prquad(s)46443225Sbostic prquad(s)
46543225Sbostic register long *s;
46643225Sbostic {
46743225Sbostic   static char quadfmt1[] = "\t.quad\t0x%x\n";
46843225Sbostic   static char quadfmt2[] = "\t.quad\t0x%x%08x\n";
46943225Sbostic #if HERE == VAX
47043225Sbostic   char quad[8];
47143225Sbostic   swab4((char *)s, quad, 8);
47243225Sbostic   s = (long *)quad;
47343225Sbostic #endif
47443225Sbostic 
47543225Sbostic   if (s[0] == 0 )
47643225Sbostic     fprintf(initfile, quadfmt1, s[1]);
47743225Sbostic   else
47843225Sbostic     fprintf(initfile, quadfmt2, s[0], s[1]);
47943225Sbostic 
48043225Sbostic   return;
48143225Sbostic }
48243225Sbostic 
48343225Sbostic #ifdef UCBVAXASM
prfill(n,s)48443225Sbostic prfill(n, s)
48543225Sbostic int n;
48643225Sbostic register long *s;
48743225Sbostic {
48843225Sbostic   static char fillfmt1[] = "\t.fill\t%d,8,0x%x\n";
48943225Sbostic   static char fillfmt2[] = "\t.fill\t%d,8,0x%x%08x\n";
49043225Sbostic #if HERE == VAX
49143225Sbostic   char quad[8];
49243225Sbostic   swab4((char *)s, quad, 8);
49343225Sbostic   s = (long *)quad;
49443225Sbostic #endif
49543225Sbostic 
49643225Sbostic   if (s[0] == 0 )
49743225Sbostic     fprintf(initfile, fillfmt1, n, s[1]);
49843225Sbostic   else
49943225Sbostic     fprintf(initfile, fillfmt2, n, s[0], s[1]);
50043225Sbostic 
50143225Sbostic   return;
50243225Sbostic }
50343225Sbostic #endif
50443225Sbostic 
prext(ep)50543225Sbostic prext(ep)
50643225Sbostic register struct Extsym *ep;
50743225Sbostic {
50843225Sbostic   static char globlfmt[] = "\t.globl\t_%s\n";
50943225Sbostic   static char commfmt[] = "\t.comm\t_%s,%ld\n";
51043225Sbostic   static char align2fmt[] = "\t.align\t2\n";
51143225Sbostic   static char labelfmt[] = "_%s:\n";
51243225Sbostic 
51343225Sbostic   static char seekerror[] = "seek error on tmp file";
51443225Sbostic   static char readerror[] = "read error on tmp file";
51543225Sbostic 
51643225Sbostic   char *tag;
51743225Sbostic   register int leng;
51843225Sbostic   long pos;
51943225Sbostic   register char *p;
52043225Sbostic   long oldvalue[2];
52143225Sbostic   long newvalue[2];
52243225Sbostic   register int n;
52343225Sbostic   register int repl;
52443225Sbostic 
52543225Sbostic   tag = varstr(XL, ep->extname);
52643225Sbostic   leng = ep->maxleng;
52743225Sbostic 
52843225Sbostic   if (leng == 0)
52943225Sbostic     {
53043225Sbostic       if(*tag != '@')	/* function opcodes */
53143225Sbostic       fprintf(asmfile, globlfmt, tag);
53243225Sbostic       return;
53343225Sbostic     }
53443225Sbostic 
53543225Sbostic   if (ep->init == NO)
53643225Sbostic     {
53743225Sbostic       fprintf(asmfile, commfmt, tag, leng);
53843225Sbostic       return;
53943225Sbostic     }
54043225Sbostic 
54143225Sbostic   fprintf(asmfile, globlfmt, tag);
54243225Sbostic   fprintf(initfile, align2fmt);
54343225Sbostic   fprintf(initfile, labelfmt, tag);
54443225Sbostic 
54543225Sbostic   pos = lseek(cdatafile, ep->initoffset, 0);
54643225Sbostic   if (pos == -1)
54743225Sbostic     {
54843225Sbostic       err(seekerror);
54943225Sbostic       done(1);
55043225Sbostic     }
55143225Sbostic 
55243225Sbostic   oldvalue[0] = 0;
55343225Sbostic   oldvalue[1] = 0;
55443225Sbostic   n = read(cdatafile, oldvalue, 8);
55543225Sbostic   if (n < 0)
55643225Sbostic     {
55743225Sbostic       err(readerror);
55843225Sbostic       done(1);
55943225Sbostic     }
56043225Sbostic 
56143225Sbostic   if (leng <= 8)
56243225Sbostic     {
56343225Sbostic       p = (char *)oldvalue + leng;
56443225Sbostic       while (p > (char *)oldvalue && *--p == '\0') /* SKIP */;
56543225Sbostic       if (*p == '\0')
56643225Sbostic 	prspace(leng);
56743225Sbostic       else if (leng == 8)
56843225Sbostic 	prquad(oldvalue);
56943225Sbostic       else
57043225Sbostic 	prsdata(oldvalue, leng);
57143225Sbostic 
57243225Sbostic       return;
57343225Sbostic     }
57443225Sbostic 
57543225Sbostic   repl = 1;
57643225Sbostic   leng -= 8;
57743225Sbostic 
57843225Sbostic   while (leng >= 8)
57943225Sbostic     {
58043225Sbostic       newvalue[0] = 0;
58143225Sbostic       newvalue[1] = 0;
58243225Sbostic 
58343225Sbostic       n = read(cdatafile, newvalue, 8);
58443225Sbostic       if (n < 0)
58543225Sbostic 	{
58643225Sbostic 	  err(readerror);
58743225Sbostic 	  done(1);
58843225Sbostic 	}
58943225Sbostic 
59043225Sbostic       leng -= 8;
59143225Sbostic 
59243225Sbostic       if (oldvalue[0] == newvalue[0]
59343225Sbostic 	  && oldvalue[1] == newvalue[1])
59443225Sbostic 	repl++;
59543225Sbostic       else
59643225Sbostic 	{
59743225Sbostic 	  if (oldvalue[0] == 0
59843225Sbostic 	      && oldvalue[1] == 0)
59943225Sbostic 	    prspace(8*repl);
60043225Sbostic 	  else if (repl == 1)
60143225Sbostic 	    prquad(oldvalue);
60243225Sbostic 	  else
60343225Sbostic #ifdef UCBVAXASM
60443225Sbostic 	    prfill(repl, oldvalue);
60543225Sbostic #else
60643225Sbostic 	    {
60743225Sbostic 	      while (repl-- > 0)
60843225Sbostic 		prquad(oldvalue);
60943225Sbostic 	    }
61043225Sbostic #endif
61143225Sbostic 	  oldvalue[0] = newvalue[0];
61243225Sbostic 	  oldvalue[1] = newvalue[1];
61343225Sbostic 	  repl = 1;
61443225Sbostic 	}
61543225Sbostic     }
61643225Sbostic 
61743225Sbostic   newvalue[0] = 0;
61843225Sbostic   newvalue[1] = 0;
61943225Sbostic 
62043225Sbostic   if (leng > 0)
62143225Sbostic     {
62243225Sbostic       n = read(cdatafile, newvalue, leng);
62343225Sbostic       if (n < 0)
62443225Sbostic 	{
62543225Sbostic 	  err(readerror);
62643225Sbostic 	  done(1);
62743225Sbostic 	}
62843225Sbostic     }
62943225Sbostic 
63043225Sbostic   if (oldvalue[1] == 0
63143225Sbostic       && oldvalue[0] == 0
63243225Sbostic       && newvalue[1] == 0
63343225Sbostic       && newvalue[0] == 0)
63443225Sbostic     {
63543225Sbostic       prspace(8*repl + leng);
63643225Sbostic       return;
63743225Sbostic     }
63843225Sbostic 
63943225Sbostic   if (oldvalue[1] == 0
64043225Sbostic       && oldvalue[0] == 0)
64143225Sbostic     prspace(8*repl);
64243225Sbostic   else if (repl == 1)
64343225Sbostic     prquad(oldvalue);
64443225Sbostic   else
64543225Sbostic #ifdef UCBVAXASM
64643225Sbostic     prfill(repl, oldvalue);
64743225Sbostic #else
64843225Sbostic     {
64943225Sbostic       while (repl-- > 0)
65043225Sbostic 	prquad(oldvalue);
65143225Sbostic     }
65243225Sbostic #endif
65343225Sbostic 
65443225Sbostic   prsdata(newvalue, leng);
65543225Sbostic 
65643225Sbostic   return;
65743225Sbostic }
65843225Sbostic 
prlocdata(sname,leng,type,initoffset,inlcomm)65943225Sbostic prlocdata(sname, leng, type, initoffset, inlcomm)
66043225Sbostic char *sname;
66143225Sbostic ftnint leng;
66243225Sbostic int type;
66343225Sbostic long initoffset;
66443225Sbostic char *inlcomm;
66543225Sbostic {
66643225Sbostic   static char seekerror[] = "seek error on tmp file";
66743225Sbostic   static char readerror[] = "read error on tmp file";
66843225Sbostic 
66943225Sbostic   static char labelfmt[] = "%s:\n";
67043225Sbostic 
67143225Sbostic   register int k;
67243225Sbostic   register char *p;
67343225Sbostic   register int repl;
67443225Sbostic   register int first;
67543225Sbostic   register long pos;
67643225Sbostic   register long n;
67743225Sbostic   long oldvalue[2];
67843225Sbostic   long newvalue[2];
67943225Sbostic 
68043225Sbostic   *inlcomm = NO;
68143225Sbostic 
68243225Sbostic   k = leng;
68343225Sbostic   first = YES;
68443225Sbostic 
68543225Sbostic   pos = lseek(vdatafile, initoffset, 0);
68643225Sbostic   if (pos == -1)
68743225Sbostic     {
68843225Sbostic       err(seekerror);
68943225Sbostic       done(1);
69043225Sbostic     }
69143225Sbostic 
69243225Sbostic   oldvalue[0] = 0;
69343225Sbostic   oldvalue[1] = 0;
69443225Sbostic   n = read(vdatafile, oldvalue, 8);
69543225Sbostic   if (n < 0)
69643225Sbostic     {
69743225Sbostic       err(readerror);
69843225Sbostic       done(1);
69943225Sbostic     }
70043225Sbostic 
70143225Sbostic   if (k <= 8)
70243225Sbostic     {
70343225Sbostic       p = (char *)oldvalue + k;
70443225Sbostic       while (p > (char *)oldvalue && *--p == '\0')
70543225Sbostic 	/*  SKIP  */ ;
70643225Sbostic       if (*p == '\0')
70743225Sbostic 	{
70843225Sbostic 	  if (SMALLVAR(leng))
70943225Sbostic 	    {
71043225Sbostic 	      pralign(typealign[type]);
71143225Sbostic 	      fprintf(initfile, labelfmt, sname);
71243225Sbostic 	      prspace(leng);
71343225Sbostic 	    }
71443225Sbostic 	  else
71543225Sbostic 	    {
71643225Sbostic 	      preven(ALIDOUBLE);
71743225Sbostic 	      prlocvar(sname, leng);
71843225Sbostic 	      *inlcomm = YES;
71943225Sbostic 	    }
72043225Sbostic 	}
72143225Sbostic       else
72243225Sbostic 	{
72343225Sbostic 	  fprintf(initfile, labelfmt, sname);
72443225Sbostic 	  if (leng == 8)
72543225Sbostic 	    prquad(oldvalue);
72643225Sbostic 	  else
72743225Sbostic 	    prsdata(oldvalue, leng);
72843225Sbostic 	}
72943225Sbostic       return;
73043225Sbostic     }
73143225Sbostic 
73243225Sbostic   repl = 1;
73343225Sbostic   k -= 8;
73443225Sbostic 
73543225Sbostic   while (k >=8)
73643225Sbostic     {
73743225Sbostic       newvalue[0] = 0;
73843225Sbostic       newvalue[1] = 0;
73943225Sbostic 
74043225Sbostic       n = read(vdatafile, newvalue, 8);
74143225Sbostic       if (n < 0)
74243225Sbostic 	{
74343225Sbostic 	  err(readerror);
74443225Sbostic 	  done(1);
74543225Sbostic 	}
74643225Sbostic 
74743225Sbostic       k -= 8;
74843225Sbostic 
74943225Sbostic       if (oldvalue[0] == newvalue[0]
75043225Sbostic 	  && oldvalue[1] == newvalue[1])
75143225Sbostic 	repl++;
75243225Sbostic       else
75343225Sbostic 	{
75443225Sbostic 	  if (first == YES)
75543225Sbostic 	    {
75643225Sbostic 	      pralign(typealign[type]);
75743225Sbostic 	      fprintf(initfile, labelfmt, sname);
75843225Sbostic 	      first = NO;
75943225Sbostic 	    }
76043225Sbostic 
76143225Sbostic 	  if (oldvalue[0] == 0
76243225Sbostic 	      && oldvalue[1] == 0)
76343225Sbostic 	    prspace(8*repl);
76443225Sbostic 	  else
76543225Sbostic 	    {
76643225Sbostic 	      while (repl-- > 0)
76743225Sbostic 		prquad(oldvalue);
76843225Sbostic 	    }
76943225Sbostic 	  oldvalue[0] = newvalue[0];
77043225Sbostic 	  oldvalue[1] = newvalue[1];
77143225Sbostic 	  repl = 1;
77243225Sbostic 	}
77343225Sbostic     }
77443225Sbostic 
77543225Sbostic   newvalue[0] = 0;
77643225Sbostic   newvalue[1] = 0;
77743225Sbostic 
77843225Sbostic   if (k > 0)
77943225Sbostic     {
78043225Sbostic       n = read(vdatafile, newvalue, k);
78143225Sbostic       if (n < 0)
78243225Sbostic 	{
78343225Sbostic 	  err(readerror);
78443225Sbostic 	  done(1);
78543225Sbostic 	}
78643225Sbostic     }
78743225Sbostic 
78843225Sbostic   if (oldvalue[1] == 0
78943225Sbostic       && oldvalue[0] == 0
79043225Sbostic       && newvalue[1] == 0
79143225Sbostic       && newvalue[0] == 0)
79243225Sbostic     {
79343225Sbostic       if (first == YES && !SMALLVAR(leng))
79443225Sbostic 	{
79543225Sbostic 	  prlocvar(sname, leng);
79643225Sbostic 	  *inlcomm = YES;
79743225Sbostic 	}
79843225Sbostic       else
79943225Sbostic 	{
80043225Sbostic 	  if (first == YES)
80143225Sbostic 	    {
80243225Sbostic 	      pralign(typealign[type]);
80343225Sbostic 	      fprintf(initfile, labelfmt, sname);
80443225Sbostic 	    }
80543225Sbostic 	  prspace(8*repl + k);
80643225Sbostic 	}
80743225Sbostic       return;
80843225Sbostic     }
80943225Sbostic 
81043225Sbostic   if (first == YES)
81143225Sbostic     {
81243225Sbostic       pralign(typealign[type]);
81343225Sbostic       fprintf(initfile, labelfmt, sname);
81443225Sbostic     }
81543225Sbostic 
81643225Sbostic   if (oldvalue[1] == 0
81743225Sbostic       && oldvalue[0] == 0)
81843225Sbostic     	prspace(8*repl);
81943225Sbostic   else
82043225Sbostic     {
82143225Sbostic       while (repl-- > 0)
82243225Sbostic 	prquad(oldvalue);
82343225Sbostic     }
82443225Sbostic 
82543225Sbostic   prsdata(newvalue, k);
82643225Sbostic 
82743225Sbostic   return;
82843225Sbostic }
82943225Sbostic 
prendproc()83043225Sbostic prendproc()
83143225Sbostic {
83243225Sbostic }
83343225Sbostic 
prtail()83443225Sbostic prtail()
83543225Sbostic {
83643225Sbostic }
83743225Sbostic 
83843225Sbostic prolog(ep, argvec)
83943225Sbostic struct Entrypoint *ep;
84043225Sbostic Addrp  argvec;
84143225Sbostic {
84243225Sbostic int i, argslot, proflab;
84343225Sbostic int size;
84443225Sbostic register chainp p;
84543225Sbostic register Namep q;
84643225Sbostic register struct Dimblock *dp;
84743225Sbostic expptr tp;
84843225Sbostic static char maskfmt[] = "\t.word\tLWM%d";
84943225Sbostic static char align1fmt[] = "\t.align\t1";
85043225Sbostic 
85143225Sbostic if(procclass == CLMAIN) {
85243225Sbostic 	if(fudgelabel)
85343225Sbostic 		{
85443225Sbostic 		if(ep->entryname) {
85543225Sbostic 			p2pass(align1fmt);
85643225Sbostic 			p2ps("_%s:",  varstr(XL, ep->entryname->extname));
85743225Sbostic 			p2pi(maskfmt, procno);
85843225Sbostic 		}
85943225Sbostic 		putlabel(fudgelabel);
86043225Sbostic 		fudgelabel = 0;
86143225Sbostic 		}
86243225Sbostic 	else
86343225Sbostic 		{
86443225Sbostic 		p2pass(align1fmt);
86543225Sbostic 		p2pass( "_MAIN_:" );
86643225Sbostic 		if(ep->entryname == NULL)
86743225Sbostic 			p2pi(maskfmt, procno);
86843225Sbostic 		}
86943225Sbostic 
87043225Sbostic } else if(ep->entryname)
87143225Sbostic 	if(fudgelabel)
87243225Sbostic 		{
87343225Sbostic 		putlabel(fudgelabel);
87443225Sbostic 		fudgelabel = 0;
87543225Sbostic 		}
87643225Sbostic 	else
87743225Sbostic 		{
87843225Sbostic 		p2pass(align1fmt);
87943225Sbostic 		p2ps("_%s:",  varstr(XL, ep->entryname->extname));
88043225Sbostic 		p2pi(maskfmt, procno);
88143225Sbostic 		prsave(newlabel());
88243225Sbostic 		}
88343225Sbostic 
88443225Sbostic if(procclass == CLBLOCK)
88543225Sbostic 	return;
88643225Sbostic if (anylocals == YES)
88743225Sbostic 	p2pi("\tmovl\t$v.%d,r11", bsslabel);
88843225Sbostic if(argvec)
88943225Sbostic 	{
89043225Sbostic 	if (argvec->tag != TADDR) badtag ("prolog",argvec->tag);
89146308Sbostic 	argloc = argvec->memoffset->constblock.constant.ci + SZINT;
89243225Sbostic 			/* first slot holds count */
89343225Sbostic 	if(proctype == TYCHAR)
89443225Sbostic 		{
89543225Sbostic 		mvarg(TYADDR, 0, chslot);
89643225Sbostic 		mvarg(TYLENG, SZADDR, chlgslot);
89743225Sbostic 		argslot = SZADDR + SZLENG;
89843225Sbostic 		}
89943225Sbostic 	else if( ISCOMPLEX(proctype) )
90043225Sbostic 		{
90143225Sbostic 		mvarg(TYADDR, 0, cxslot);
90243225Sbostic 		argslot = SZADDR;
90343225Sbostic 		}
90443225Sbostic 	else
90543225Sbostic 		argslot = 0;
90643225Sbostic 
90743225Sbostic 	for(p = ep->arglist ; p ; p =p->nextp)
90843225Sbostic 		{
90943225Sbostic 		q = (Namep) (p->datap);
91043225Sbostic 		mvarg(TYADDR, argslot, q->vardesc.varno);
91143225Sbostic 		argslot += SZADDR;
91243225Sbostic 		}
91343225Sbostic 	for(p = ep->arglist ; p ; p = p->nextp)
91443225Sbostic 		{
91543225Sbostic 		q = (Namep) (p->datap);
91643225Sbostic 		if(q->vtype==TYCHAR && q->vclass!=CLPROC)
91743225Sbostic 			{
91843225Sbostic 			if(q->vleng && ! ISCONST(q->vleng) )
91943225Sbostic 				mvarg(TYLENG, argslot,
92043225Sbostic 					q->vleng->addrblock.memno);
92143225Sbostic 			argslot += SZLENG;
92243225Sbostic 			}
92343225Sbostic 		}
92443225Sbostic 	if ((ep->enamep->vtype == TYCOMPLEX) && (!ep->arglist))
92543225Sbostic 		p2pass("\tmovl\tfp,r12");
92643225Sbostic 	else
92743225Sbostic 		p2pi("\tsubl3\t$%d,fp,r12", ARGOFFSET-argloc);
92843225Sbostic 	} else
92943225Sbostic 	if((ep->arglist) || (ISCOMPLEX(proctype)) || (proctype == TYCHAR))
93043225Sbostic 		p2pass("\tmovl\tfp,r12");
93143225Sbostic 
93243225Sbostic for(p = ep->arglist ; p ; p = p->nextp)
93343225Sbostic 	{
93443225Sbostic 	q = (Namep) (p->datap);
93543225Sbostic 	if(dp = q->vdim)
93643225Sbostic 		{
93743225Sbostic 		for(i = 0 ; i < dp->ndim ; ++i)
93843225Sbostic 			if(dp->dims[i].dimexpr)
93943225Sbostic 				puteq( fixtype(cpexpr(dp->dims[i].dimsize)),
94043225Sbostic 					fixtype(cpexpr(dp->dims[i].dimexpr)));
94143225Sbostic #ifdef SDB
94243225Sbostic                 if(sdbflag) {
94343225Sbostic 		for(i = 0 ; i < dp->ndim ; ++i) {
94443225Sbostic 			if(dp->dims[i].lbaddr)
94543225Sbostic 				puteq( fixtype(cpexpr(dp->dims[i].lbaddr)),
94643225Sbostic 					fixtype(cpexpr(dp->dims[i].lb)));
94743225Sbostic 			if(dp->dims[i].ubaddr)
94843225Sbostic 				puteq( fixtype(cpexpr(dp->dims[i].ubaddr)),
94943225Sbostic 					fixtype(cpexpr(dp->dims[i].ub)));
95043225Sbostic 
95143225Sbostic                                                 }
95243225Sbostic                             }
95343225Sbostic #endif
95443225Sbostic 		size = typesize[ q->vtype ];
95543225Sbostic 		if(q->vtype == TYCHAR)
95643225Sbostic 			if( ISICON(q->vleng) )
95746308Sbostic 				size *= q->vleng->constblock.constant.ci;
95843225Sbostic 			else
95943225Sbostic 				size = -1;
96043225Sbostic 
96143225Sbostic 		/* on TAHOE, get more efficient subscripting if subscripts
96243225Sbostic 		   have zero-base, so fudge the argument pointers for arrays.
96343225Sbostic 		   Not done if array bounds are being checked.
96443225Sbostic 		*/
96543225Sbostic 		if(dp->basexpr)
96643225Sbostic 			puteq( 	cpexpr(fixtype(dp->baseoffset)),
96743225Sbostic 				cpexpr(fixtype(dp->basexpr)));
96843225Sbostic #ifdef SDB
96943225Sbostic 		if( (! checksubs) && (! sdbflag) )
97043225Sbostic #else
97143225Sbostic 		if(! checksubs)
97243225Sbostic #endif
97343225Sbostic 			{
97443225Sbostic 			if(dp->basexpr)
97543225Sbostic 				{
97643225Sbostic 				if(size > 0)
97743225Sbostic 					tp = (expptr) ICON(size);
97843225Sbostic 				else
97943225Sbostic 					tp = (expptr) cpexpr(q->vleng);
98043225Sbostic 				putforce(TYINT,
98143225Sbostic 					fixtype( mkexpr(OPSTAR, tp,
98243225Sbostic 						cpexpr(dp->baseoffset)) ));
98343225Sbostic 				p2pi("\tsubl2\tr0,%d(r12)",
98443225Sbostic 					p->datap->nameblock.vardesc.varno +
98543225Sbostic 						ARGOFFSET);
98643225Sbostic 				}
98746308Sbostic 			else if(dp->baseoffset->constblock.constant.ci != 0)
98843225Sbostic 				{
98943225Sbostic 				if(size > 0)
99043225Sbostic 					{
99143225Sbostic 					p2pij("\tsubl2\t$%ld,%d(r12)",
99246308Sbostic 						dp->baseoffset->constblock.constant.ci * size,
99343225Sbostic 						p->datap->nameblock.vardesc.varno +
99443225Sbostic 							ARGOFFSET);
99543225Sbostic 					}
99643225Sbostic 				else	{
99743225Sbostic 					putforce(TYINT, mkexpr(OPSTAR, cpexpr(dp->baseoffset),
99843225Sbostic 						cpexpr(q->vleng) ));
99943225Sbostic 					p2pi("\tsubl2\tr0,%d(r12)",
100043225Sbostic 						p->datap->nameblock.vardesc.varno +
100143225Sbostic 							ARGOFFSET);
100243225Sbostic 					}
100343225Sbostic 				}
100443225Sbostic 			}
100543225Sbostic 		}
100643225Sbostic 	}
100743225Sbostic 
100843225Sbostic if(typeaddr)
100943225Sbostic 	puteq( cpexpr(typeaddr), mkaddcon(ep->typelabel) );
101043225Sbostic /* replace to avoid long jump problem
101143225Sbostic putgoto(ep->entrylabel);
101243225Sbostic */
101343225Sbostic p2pi("\tjbr\tL%d", ep->entrylabel);
101443225Sbostic }
101543225Sbostic 
prhead(fp)101643225Sbostic prhead(fp)
101743225Sbostic FILEP fp;
101843225Sbostic {
101943225Sbostic #if FAMILY==PCC
102043225Sbostic 	p2triple(PCCF_FLBRAC, ARGREG-highregvar, procno);
102143225Sbostic 	p2word( (long) (BITSPERCHAR*autoleng) );
102243225Sbostic 	p2flush();
102343225Sbostic #endif
102443225Sbostic }
1025