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