xref: /csrg-svn/usr.bin/f77/pass1.vax/vax.c (revision 47955)
1*47955Sbostic /*-
2*47955Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47955Sbostic  * All rights reserved.
4*47955Sbostic  *
5*47955Sbostic  * %sccs.include.proprietary.c%
622879Smckusick  */
722879Smckusick 
822879Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)vax.c	5.4 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122879Smckusick 
1222879Smckusick /*
1322879Smckusick  * vax.c
1422879Smckusick  *
1522879Smckusick  * VAX specific routines for the F77 compiler, pass 1
1622879Smckusick  *
1722879Smckusick  * University of Utah CS Dept modification history:
1822879Smckusick  *
1922879Smckusick  * $Log:	vax.c,v $
2024483Sdonn  * Revision 5.2  85/08/10  05:06:30  donn
2124483Sdonn  * Deleted intcon[] and realcon[], since they are now made redundant by
2224483Sdonn  * changes in intr.c.  From Jerry Berkman.
2324483Sdonn  *
2424483Sdonn  * Revision 5.1  85/08/10  03:50:38  donn
2524483Sdonn  * 4.3 alpha
2624483Sdonn  *
2722879Smckusick  * Revision 3.1  85/02/27  19:14:58  donn
2822879Smckusick  * Changed to use pcc.h instead of pccdefs.h.
2922879Smckusick  *
3022879Smckusick  * Revision 2.3  85/02/22  01:09:22  donn
3122879Smckusick  * memname() didn't know about intrinsic functions...
3222879Smckusick  *
3322879Smckusick  * Revision 2.2  85/02/12  17:56:44  donn
3422879Smckusick  * Put the argument to the profiling routine in data space instead of
3522879Smckusick  * constant space.  From Jerry Berkman.
3622879Smckusick  *
3722879Smckusick  * Revision 2.1  84/07/19  12:05:08  donn
3822879Smckusick  * Changed comment headers for UofU.
3922879Smckusick  *
4022879Smckusick  * Revision 1.2  84/02/26  06:41:04  donn
4122879Smckusick  * Added Berkeley changes to move data around to produce shorter offsets.
4222879Smckusick  *
4322879Smckusick  */
4422879Smckusick 
4522879Smckusick #include "defs.h"
4622879Smckusick 
4722879Smckusick #ifdef SDB
4822879Smckusick #	include <a.out.h>
4922879Smckusick extern int types2[];
5022879Smckusick #	ifndef N_SO
5122879Smckusick #		include <stab.h>
5222879Smckusick #	endif
5322879Smckusick #endif
5422879Smckusick 
5522879Smckusick #include <pcc.h>
5622879Smckusick 
5722879Smckusick 
5822879Smckusick 
5922879Smckusick int maxregvar = MAXREGVAR;
6022879Smckusick int regnum[] =  { 10, 9, 8, 7, 6 } ;
6122879Smckusick static int regmask[] = { 0x800, 0xc00, 0xe00, 0xf00, 0xf80, 0xfc0 };
6222879Smckusick 
6322879Smckusick 
6422879Smckusick /*
6522879Smckusick  * The VAX assembler has a serious and not easily fixable problem
6622879Smckusick  * with generating instructions that contain expressions of the form
6722879Smckusick  * label1-label2 where there are .align's in-between the labels.
6822879Smckusick  * Therefore, the compiler must keep track of the offsets and output
6922879Smckusick  * .space where needed.
7022879Smckusick  */
7122879Smckusick LOCAL int i_offset;		/* initfile offset */
7222879Smckusick LOCAL int a_offset;		/* asmfile offset */
7322879Smckusick 
7422879Smckusick 
7522879Smckusick 
prsave(proflab)7622879Smckusick prsave(proflab)
7722879Smckusick int proflab;
7822879Smckusick {
7922879Smckusick if(profileflag)
8022879Smckusick 	{
8122879Smckusick 	pruse(asmfile, USEINIT);	/* This is not a constant */
8222879Smckusick 	fprintf(asmfile, "L%d:\t.space\t4\n", proflab);
8322879Smckusick 	pruse(asmfile, USECONST);
8422879Smckusick 	p2pi("\tmovab\tL%d,r0", proflab);
8522879Smckusick 	p2pass("\tjsb\tmcount");
8622879Smckusick 	}
8722879Smckusick p2pi("\tsubl2\t$LF%d,sp", procno);
8822879Smckusick }
8922879Smckusick 
9022879Smckusick 
9122879Smckusick 
goret(type)9222879Smckusick goret(type)
9322879Smckusick int type;
9422879Smckusick {
9522879Smckusick p2pass("\tret");
9622879Smckusick }
9722879Smckusick 
9822879Smckusick 
9922879Smckusick 
10022879Smckusick 
10122879Smckusick /*
10222879Smckusick  * move argument slot arg1 (relative to ap)
10322879Smckusick  * to slot arg2 (relative to ARGREG)
10422879Smckusick  */
10522879Smckusick 
mvarg(type,arg1,arg2)10622879Smckusick mvarg(type, arg1, arg2)
10722879Smckusick int type, arg1, arg2;
10822879Smckusick {
10922879Smckusick p2pij("\tmovl\t%d(ap),%d(fp)", arg1+ARGOFFSET, arg2+argloc);
11022879Smckusick }
11122879Smckusick 
11222879Smckusick 
11322879Smckusick 
11422879Smckusick 
prlabel(fp,k)11522879Smckusick prlabel(fp, k)
11622879Smckusick FILEP fp;
11722879Smckusick int k;
11822879Smckusick {
11922879Smckusick fprintf(fp, "L%d:\n", k);
12022879Smckusick }
12122879Smckusick 
12222879Smckusick 
12322879Smckusick 
prconi(fp,type,n)12422879Smckusick prconi(fp, type, n)
12522879Smckusick FILEP fp;
12622879Smckusick int type;
12722879Smckusick ftnint n;
12822879Smckusick {
12922879Smckusick register int i;
13022879Smckusick 
13122879Smckusick if(type == TYSHORT)
13222879Smckusick 	{
13322879Smckusick 	fprintf(fp, "\t.word\t%ld\n", n);
13422879Smckusick 	i = SZSHORT;
13522879Smckusick 	}
13622879Smckusick else
13722879Smckusick 	{
13822879Smckusick 	fprintf(fp, "\t.long\t%ld\n", n);
13922879Smckusick 	i = SZLONG;
14022879Smckusick 	}
14122879Smckusick if(fp == initfile)
14222879Smckusick 	i_offset += i;
14322879Smckusick else
14422879Smckusick 	a_offset += i;
14522879Smckusick }
14622879Smckusick 
14722879Smckusick 
14822879Smckusick 
prcona(fp,a)14922879Smckusick prcona(fp, a)
15022879Smckusick FILEP fp;
15122879Smckusick ftnint a;
15222879Smckusick {
15322879Smckusick fprintf(fp, "\t.long\tL%ld\n", a);
15422879Smckusick if(fp == initfile)
15522879Smckusick 	i_offset += SZLONG;
15622879Smckusick else
15722879Smckusick 	a_offset += SZLONG;
15822879Smckusick }
15922879Smckusick 
16022879Smckusick 
16122879Smckusick 
16222879Smckusick #ifndef vax
prconr(fp,type,x)16322879Smckusick prconr(fp, type, x)
16422879Smckusick FILEP fp;
16522879Smckusick int type;
16622879Smckusick float x;
16722879Smckusick {
16822879Smckusick fprintf(fp, "\t%s\t0f%e\n", (type==TYREAL ? ".float" : ".double"), x);
16922879Smckusick }
17022879Smckusick #endif
17122879Smckusick 
17222879Smckusick #ifdef vax
prconr(fp,type,x)17322879Smckusick prconr(fp, type, x)
17422879Smckusick FILEP fp;
17522879Smckusick int type;
17622879Smckusick double x;
17722879Smckusick {
17822879Smckusick /* non-portable cheat to preserve bit patterns */
17922879Smckusick union { double xd; long int xl[2]; } cheat;
18022879Smckusick register int i;
18122879Smckusick 
18222879Smckusick cheat.xd = x;
18322879Smckusick if(type == TYREAL)
18422879Smckusick 	{
18522879Smckusick 	float y = x;
18622879Smckusick 
18722879Smckusick 	fprintf(fp, "\t.long\t0x%X\n", *(long *) &y);
18822879Smckusick 	i = SZFLOAT;
18922879Smckusick 	}
19022879Smckusick else
19122879Smckusick 	{
19222879Smckusick 	fprintf(fp, "\t.long\t0x%X,0x%X\n", cheat.xl[0], cheat.xl[1]);
19322879Smckusick 	i = SZDOUBLE;
19422879Smckusick 	}
19522879Smckusick if(fp == initfile)
19622879Smckusick 	i_offset += i;
19722879Smckusick else
19822879Smckusick 	a_offset += i;
19922879Smckusick }
20022879Smckusick #endif
20122879Smckusick 
20222879Smckusick 
20322879Smckusick 
praddr(fp,stg,varno,offset)20422879Smckusick praddr(fp, stg, varno, offset)
20522879Smckusick FILE *fp;
20622879Smckusick int stg, varno;
20722879Smckusick ftnint offset;
20822879Smckusick {
20922879Smckusick char *memname();
21022879Smckusick 
21122879Smckusick if(stg == STGNULL)
21222879Smckusick 	fprintf(fp, "\t.long\t0\n");
21322879Smckusick else
21422879Smckusick 	{
21522879Smckusick 	fprintf(fp, "\t.long\t%s", memname(stg,varno));
21622879Smckusick 	if(offset)
21722879Smckusick 		fprintf(fp, "+%ld", offset);
21822879Smckusick 	fprintf(fp, "\n");
21922879Smckusick 	}
22022879Smckusick if(fp == initfile)
22122879Smckusick 	i_offset += SZADDR;
22222879Smckusick else
22322879Smckusick 	a_offset += SZADDR;
22422879Smckusick }
22522879Smckusick 
22622879Smckusick 
pralign(k)22722879Smckusick pralign(k)
22822879Smckusick int k;
22922879Smckusick {
23022879Smckusick register int lg = 0;
23122879Smckusick 
23222879Smckusick if(k > 4)
23322879Smckusick 	{
23422879Smckusick 	if(i_offset & 7)
23522879Smckusick 		lg = 8 - (i_offset & 7);
23622879Smckusick 	}
23722879Smckusick else if(k > 2)
23822879Smckusick 	{
23922879Smckusick 	if(i_offset & 3)
24022879Smckusick 		lg = 4 - (i_offset & 3);
24122879Smckusick 	}
24222879Smckusick else if(k > 1)
24322879Smckusick 	{
24422879Smckusick 	if(i_offset & 1)
24522879Smckusick 		lg = 1;
24622879Smckusick 	}
24722879Smckusick else
24822879Smckusick 	return;
24922879Smckusick if(lg > 0)
25022879Smckusick 	{
25122879Smckusick 	fprintf(initfile, "\t.space\t%d\n", lg);
25222879Smckusick 	i_offset += lg;
25322879Smckusick 	}
25422879Smckusick }
25522879Smckusick 
25622879Smckusick 
25722879Smckusick 
prspace(n)25822879Smckusick prspace(n)
25922879Smckusick int n;
26022879Smckusick {
26122879Smckusick 
26222879Smckusick fprintf(initfile, "\t.space\t%d\n", n);
26322879Smckusick i_offset += n;
26422879Smckusick }
26522879Smckusick 
26622879Smckusick 
preven(k)26722879Smckusick preven(k)
26822879Smckusick int k;
26922879Smckusick {
27022879Smckusick register int lg = 0;
27122879Smckusick 
27222879Smckusick if(k > 4)
27322879Smckusick 	{
27422879Smckusick 	if(a_offset & 7)
27522879Smckusick 		lg = 8 - (a_offset & 7);
27622879Smckusick 	}
27722879Smckusick else if(k > 2)
27822879Smckusick 	{
27922879Smckusick 	if(a_offset & 3)
28022879Smckusick 		lg = 4 - (a_offset & 3);
28122879Smckusick 	}
28222879Smckusick else if(k > 1)
28322879Smckusick 	{
28422879Smckusick 	if(a_offset & 1)
28522879Smckusick 		lg = 1;
28622879Smckusick 	}
28722879Smckusick else
28822879Smckusick 	return;
28922879Smckusick if(lg > 0)
29022879Smckusick 	{
29122879Smckusick 	fprintf(asmfile, "\t.space\t%d\n", lg);
29222879Smckusick 	a_offset += lg;
29322879Smckusick 	}
29422879Smckusick }
29522879Smckusick 
29622879Smckusick 
29722879Smckusick 
praspace(n)29822879Smckusick praspace(n)
29922879Smckusick int n;
30022879Smckusick {
30122879Smckusick 
30222879Smckusick fprintf(asmfile, "\t.space\t%d\n", n);
30322879Smckusick a_offset += n;
30422879Smckusick }
30522879Smckusick 
30622879Smckusick 
30722879Smckusick 
vaxgoto(index,nlab,labs)30822879Smckusick vaxgoto(index, nlab, labs)
30922879Smckusick expptr index;
31022879Smckusick register int nlab;
31122879Smckusick struct Labelblock *labs[];
31222879Smckusick {
31322879Smckusick register int i;
31422879Smckusick register int arrlab;
31522879Smckusick 
31622879Smckusick putforce(TYINT, index);
31722879Smckusick p2pi("\tcasel\tr0,$1,$%d", nlab-1);
31822879Smckusick p2pi("L%d:", arrlab = newlabel() );
31922879Smckusick for(i = 0; i< nlab ; ++i)
32022879Smckusick 	if( labs[i] )
32122879Smckusick 		p2pij("\t.word\tL%d-L%d", labs[i]->labelno, arrlab);
32222879Smckusick }
32322879Smckusick 
32422879Smckusick 
prarif(p,neg,zer,pos)32522879Smckusick prarif(p, neg, zer, pos)
32622879Smckusick expptr p;
32722879Smckusick int neg, zer, pos;
32822879Smckusick {
32922879Smckusick int type;
33022879Smckusick 
33122879Smckusick type = p->headblock.vtype;
33222879Smckusick putforce(type, p);
33322879Smckusick if(type == TYLONG)
33422879Smckusick 	p2pass("\ttstl\tr0");
33522879Smckusick else if (type == TYSHORT)
33622879Smckusick 	p2pass("\ttstw\tr0");
33722879Smckusick else
33822879Smckusick 	p2pass("\ttstd\tr0");
33922879Smckusick p2pi("\tjlss\tL%d", neg);
34022879Smckusick p2pi("\tjeql\tL%d", zer);
34122879Smckusick p2pi("\tjbr\tL%d", pos);
34222879Smckusick }
34322879Smckusick 
34422879Smckusick 
34522879Smckusick 
34622879Smckusick 
memname(stg,mem)34722879Smckusick char *memname(stg, mem)
34822879Smckusick int stg, mem;
34922879Smckusick {
35022879Smckusick static char s[20];
35122879Smckusick 
35222879Smckusick switch(stg)
35322879Smckusick 	{
35422879Smckusick 	case STGCOMMON:
35522879Smckusick 	case STGEXT:
35622879Smckusick 	case STGINTR:
35722879Smckusick 		sprintf(s, "_%s", varstr(XL, extsymtab[mem].extname) );
35822879Smckusick 		break;
35922879Smckusick 
36022879Smckusick 	case STGBSS:
36122879Smckusick 	case STGINIT:
36222879Smckusick 		sprintf(s, "v.%d", mem);
36322879Smckusick 		break;
36422879Smckusick 
36522879Smckusick 	case STGCONST:
36622879Smckusick 		sprintf(s, "L%d", mem);
36722879Smckusick 		break;
36822879Smckusick 
36922879Smckusick 	case STGEQUIV:
37022879Smckusick 		sprintf(s, "q.%d", mem+eqvstart);
37122879Smckusick 		break;
37222879Smckusick 
37322879Smckusick 	default:
37422879Smckusick 		badstg("memname", stg);
37522879Smckusick 	}
37622879Smckusick return(s);
37722879Smckusick }
37822879Smckusick 
37922879Smckusick 
38022879Smckusick 
38122879Smckusick 
prlocvar(s,len)38222879Smckusick prlocvar(s, len)
38322879Smckusick char *s;
38422879Smckusick ftnint len;
38522879Smckusick {
38622879Smckusick fprintf(asmfile, "\t.lcomm\t%s,%ld\n", s, len);
38722879Smckusick }
38822879Smckusick 
38922879Smckusick 
39022879Smckusick 
39122879Smckusick 
39222879Smckusick char *
packbytes(cp)39322879Smckusick packbytes(cp)
39422879Smckusick register Constp cp;
39522879Smckusick {
39622879Smckusick   static char shrt[2];
39722879Smckusick   static char lng[4];
39822879Smckusick   static char quad[8];
39922879Smckusick   static char oct[16];
40022879Smckusick 
40122879Smckusick   register int type;
40222879Smckusick   register int *ip, *jp;
40322879Smckusick 
40422879Smckusick   switch (cp->vtype)
40522879Smckusick     {
40622879Smckusick     case TYSHORT:
40733257Sbostic       *((short *) shrt) = (short) cp->constant.ci;
40822879Smckusick       return (shrt);
40922879Smckusick 
41022879Smckusick     case TYLONG:
41122879Smckusick     case TYLOGICAL:
41222879Smckusick     case TYREAL:
41333257Sbostic       *((int *) lng) = cp->constant.ci;
41422879Smckusick       return (lng);
41522879Smckusick 
41622879Smckusick     case TYDREAL:
41722879Smckusick       ip = (int *) quad;
41833257Sbostic       jp = (int *) &(cp->constant.cd[0]);
41922879Smckusick       ip[0] = jp[0];
42022879Smckusick       ip[1] = jp[1];
42122879Smckusick       return (quad);
42222879Smckusick 
42322879Smckusick     case TYCOMPLEX:
42422879Smckusick       ip = (int *) quad;
42533257Sbostic       jp = (int *) &(cp->constant.cd[0]);
42622879Smckusick       ip[0] = jp[0];
42722879Smckusick       ip[1] = jp[2];
42822879Smckusick       return (quad);
42922879Smckusick 
43022879Smckusick     case TYDCOMPLEX:
43122879Smckusick       ip = (int *) oct;
43233257Sbostic       jp = (int *) &(cp->constant.cd[0]);
43322879Smckusick       *ip++ = *jp++;
43422879Smckusick       *ip++ = *jp++;
43522879Smckusick       *ip++ = *jp++;
43622879Smckusick       *ip = *jp;
43722879Smckusick       return (oct);
43822879Smckusick 
43922879Smckusick     default:
44022879Smckusick       badtype("packbytes", cp->vtype);
44122879Smckusick     }
44222879Smckusick }
44322879Smckusick 
44422879Smckusick 
44522879Smckusick 
44622879Smckusick 
prsdata(s,len)44722879Smckusick prsdata(s, len)
44822879Smckusick register char *s;
44922879Smckusick register int len;
45022879Smckusick {
45122879Smckusick   static char *longfmt = "\t.long\t0x%x\n";
45222879Smckusick   static char *wordfmt = "\t.word\t0x%x\n";
45322879Smckusick   static char *bytefmt = "\t.byte\t0x%x\n";
45422879Smckusick 
45522879Smckusick   register int i;
45622879Smckusick 
45722879Smckusick   i = 0;
45822879Smckusick   if ((len - i) >= 4)
45922879Smckusick     {
46022879Smckusick       fprintf(initfile, longfmt, *((int *) s));
46122879Smckusick       i += 4;
46222879Smckusick     }
46322879Smckusick   if ((len - i) >= 2)
46422879Smckusick     {
46522879Smckusick       fprintf(initfile, wordfmt, 0xffff & (*((short *) (s + i))));
46622879Smckusick       i += 2;
46722879Smckusick     }
46822879Smckusick   if ((len - i) > 0)
46922879Smckusick     fprintf(initfile,bytefmt, 0xff & s[i]);
47022879Smckusick 
47122879Smckusick   i_offset += len;
47222879Smckusick   return;
47322879Smckusick }
47422879Smckusick 
47522879Smckusick 
47622879Smckusick 
prquad(s)47722879Smckusick prquad(s)
47822879Smckusick char *s;
47922879Smckusick {
48022879Smckusick   static char *quadfmt1 = "\t.quad\t0x%x\n";
48122879Smckusick   static char *quadfmt2 = "\t.quad\t0x%x%08x\n";
48222879Smckusick 
48322879Smckusick   if ( *((int *) (s + 4)) == 0 )
48422879Smckusick     fprintf(initfile, quadfmt1, *((int *) s));
48522879Smckusick   else
48622879Smckusick     fprintf(initfile, quadfmt2, *((int *) (s + 4)), *((int *) s));
48722879Smckusick 
48822879Smckusick   i_offset += 8;
48922879Smckusick   return;
49022879Smckusick }
49122879Smckusick 
49222879Smckusick 
49322879Smckusick 
49422879Smckusick #ifdef NOTDEF
49522879Smckusick 
49622879Smckusick /*  The code for generating .fill directives has been      */
49722879Smckusick /*  ifdefed out because of bugs in the UCB VAX assembler.  */
49822879Smckusick /*  If those bugs are ever fixed (and it seems unlikely),  */
49922879Smckusick /*  the NOTDEF's should be replaced by UCBVAXASM.          */
50022879Smckusick 
50122879Smckusick 
prfill(n,s)50222879Smckusick prfill(n, s)
50322879Smckusick int n;
50422879Smckusick register char *s;
50522879Smckusick {
50622879Smckusick   static char *fillfmt1 = "\t.fill\t%d,8,0x%x\n";
50722879Smckusick   static char *fillfmt2 = "\t.fill\t%d,8,0x%x%08x\n";
50822879Smckusick 
50922879Smckusick   if (*((int *) (s + 4)) == 0)
51022879Smckusick     fprintf(initfile, fillfmt1, n, *((int *) s));
51122879Smckusick   else
51222879Smckusick     fprintf(initfile, fillfmt2, n, *((int *) (s + 4)), *((int *) s));
51322879Smckusick 
51422879Smckusick   return;
51522879Smckusick }
51622879Smckusick 
51722879Smckusick #endif
51822879Smckusick 
51922879Smckusick 
52022879Smckusick 
prext(ep)52122879Smckusick prext(ep)
52222879Smckusick register struct Extsym *ep;
52322879Smckusick {
52422879Smckusick   static char *globlfmt = "\t.globl\t_%s\n";
52522879Smckusick   static char *commfmt = "\t.comm\t_%s,%ld\n";
52622879Smckusick   static char *labelfmt = "_%s:\n";
52722879Smckusick 
52822879Smckusick   static char *seekerror = "seek error on tmp file";
52922879Smckusick   static char *readerror = "read error on tmp file";
53022879Smckusick 
53122879Smckusick   char *tag;
53222879Smckusick   register int leng;
53322879Smckusick   long pos;
53422879Smckusick   register int i;
53522879Smckusick   char oldvalue[8];
53622879Smckusick   char newvalue[8];
53722879Smckusick   register int n;
53822879Smckusick   register int repl;
53922879Smckusick 
54022879Smckusick   tag = varstr(XL, ep->extname);
54122879Smckusick   leng = ep->maxleng;
54222879Smckusick 
54322879Smckusick   if (leng == 0)
54422879Smckusick     {
54522879Smckusick       fprintf(asmfile, globlfmt, tag);
54622879Smckusick       return;
54722879Smckusick     }
54822879Smckusick 
54922879Smckusick   if (ep->init == NO)
55022879Smckusick     {
55122879Smckusick       fprintf(asmfile, commfmt, tag, leng);
55222879Smckusick       return;
55322879Smckusick     }
55422879Smckusick 
55522879Smckusick   fprintf(asmfile, globlfmt, tag);
55622879Smckusick   pralign(ALIDOUBLE);
55722879Smckusick   fprintf(initfile, labelfmt, tag);
55822879Smckusick 
55922879Smckusick   pos = lseek(cdatafile, ep->initoffset, 0);
56022879Smckusick   if (pos == -1)
56122879Smckusick     {
56222879Smckusick       err(seekerror);
56322879Smckusick       done(1);
56422879Smckusick     }
56522879Smckusick 
56622879Smckusick   *((int *) oldvalue) = 0;
56722879Smckusick   *((int *) (oldvalue + 4)) = 0;
56822879Smckusick   n = read(cdatafile, oldvalue, 8);
56922879Smckusick   if (n < 0)
57022879Smckusick     {
57122879Smckusick       err(readerror);
57222879Smckusick       done(1);
57322879Smckusick     }
57422879Smckusick 
57522879Smckusick   if (leng <= 8)
57622879Smckusick     {
57722879Smckusick       i = leng;
57822879Smckusick       while (i > 0 && oldvalue[--i] == '\0') /* SKIP */;
57922879Smckusick       if (oldvalue[i] == '\0')
58022879Smckusick 	prspace(leng);
58122879Smckusick       else if (leng == 8)
58222879Smckusick 	prquad(oldvalue);
58322879Smckusick       else
58422879Smckusick 	prsdata(oldvalue, leng);
58522879Smckusick 
58622879Smckusick       return;
58722879Smckusick     }
58822879Smckusick 
58922879Smckusick   repl = 1;
59022879Smckusick   leng -= 8;
59122879Smckusick 
59222879Smckusick   while (leng >= 8)
59322879Smckusick     {
59422879Smckusick       *((int *) newvalue) = 0;
59522879Smckusick       *((int *) (newvalue + 4)) = 0;
59622879Smckusick 
59722879Smckusick       n = read(cdatafile, newvalue, 8);
59822879Smckusick       if (n < 0)
59922879Smckusick 	{
60022879Smckusick 	  err(readerror);
60122879Smckusick 	  done(1);
60222879Smckusick 	}
60322879Smckusick 
60422879Smckusick       leng -= 8;
60522879Smckusick 
60622879Smckusick       if (*((int *) oldvalue) == *((int *) newvalue)
60722879Smckusick 	  && *((int *) (oldvalue + 4)) == *((int *) (newvalue + 4)))
60822879Smckusick 	repl++;
60922879Smckusick       else
61022879Smckusick 	{
61122879Smckusick 	  if (*((int *) oldvalue) == 0
61222879Smckusick 	      && *((int *) (oldvalue + 4)) == 0)
61322879Smckusick 	    prspace(8*repl);
61422879Smckusick 	  else if (repl == 1)
61522879Smckusick 	    prquad(oldvalue);
61622879Smckusick 	  else
61722879Smckusick #ifdef NOTDEF
61822879Smckusick 	    prfill(repl, oldvalue);
61922879Smckusick #else
62022879Smckusick 	    {
62122879Smckusick 	      while (repl-- > 0)
62222879Smckusick 		prquad(oldvalue);
62322879Smckusick 	    }
62422879Smckusick #endif
62522879Smckusick 	  *((int *) oldvalue) = *((int *) newvalue);
62622879Smckusick 	  *((int *) (oldvalue + 4)) = *((int *) (newvalue + 4));
62722879Smckusick 	  repl = 1;
62822879Smckusick 	}
62922879Smckusick     }
63022879Smckusick 
63122879Smckusick   *((int *) newvalue) = 0;
63222879Smckusick   *((int *) (newvalue + 4)) = 0;
63322879Smckusick 
63422879Smckusick   if (leng > 0)
63522879Smckusick     {
63622879Smckusick       n = read(cdatafile, newvalue, leng);
63722879Smckusick       if (n < 0)
63822879Smckusick 	{
63922879Smckusick 	  err(readerror);
64022879Smckusick 	  done(1);
64122879Smckusick 	}
64222879Smckusick     }
64322879Smckusick 
64422879Smckusick   if (*((int *) (oldvalue + 4)) == 0
64522879Smckusick       && *((int *) oldvalue) == 0
64622879Smckusick       && *((int *) (newvalue + 4)) == 0
64722879Smckusick       && *((int *) newvalue) == 0)
64822879Smckusick     {
64922879Smckusick       prspace(8*repl + leng);
65022879Smckusick       return;
65122879Smckusick     }
65222879Smckusick 
65322879Smckusick   if (*((int *) (oldvalue + 4)) == 0
65422879Smckusick       && *((int *) oldvalue) == 0)
65522879Smckusick     prspace(8*repl);
65622879Smckusick   else if (repl == 1)
65722879Smckusick     prquad(oldvalue);
65822879Smckusick   else
65922879Smckusick #ifdef NOTDEF
66022879Smckusick     prfill(repl, oldvalue);
66122879Smckusick #else
66222879Smckusick     {
66322879Smckusick       while (repl-- > 0)
66422879Smckusick 	prquad(oldvalue);
66522879Smckusick     }
66622879Smckusick #endif
66722879Smckusick 
66822879Smckusick   prsdata(newvalue, leng);
66922879Smckusick 
67022879Smckusick   return;
67122879Smckusick }
67222879Smckusick 
67322879Smckusick 
67422879Smckusick 
prlocdata(sname,leng,type,initoffset,inlcomm)67522879Smckusick prlocdata(sname, leng, type, initoffset, inlcomm)
67622879Smckusick char *sname;
67722879Smckusick ftnint leng;
67822879Smckusick int type;
67922879Smckusick long initoffset;
68022879Smckusick char *inlcomm;
68122879Smckusick {
68222879Smckusick   static char *seekerror = "seek error on tmp file";
68322879Smckusick   static char *readerror = "read error on tmp file";
68422879Smckusick 
68522879Smckusick   static char *labelfmt = "%s:\n";
68622879Smckusick 
68722879Smckusick   register int k;
68822879Smckusick   register int i;
68922879Smckusick   register int repl;
69022879Smckusick   register int first;
69122879Smckusick   register long pos;
69222879Smckusick   register long n;
69322879Smckusick   char oldvalue[8];
69422879Smckusick   char newvalue[8];
69522879Smckusick 
69622879Smckusick   *inlcomm = NO;
69722879Smckusick 
69822879Smckusick   k = leng;
69922879Smckusick   first = YES;
70022879Smckusick 
70122879Smckusick   pos = lseek(vdatafile, initoffset, 0);
70222879Smckusick   if (pos == -1)
70322879Smckusick     {
70422879Smckusick       err(seekerror);
70522879Smckusick       done(1);
70622879Smckusick     }
70722879Smckusick 
70822879Smckusick   *((int *) oldvalue) = 0;
70922879Smckusick   *((int *) (oldvalue + 4)) = 0;
71022879Smckusick   n = read(vdatafile, oldvalue, 8);
71122879Smckusick   if (n < 0)
71222879Smckusick     {
71322879Smckusick       err(readerror);
71422879Smckusick       done(1);
71522879Smckusick     }
71622879Smckusick 
71722879Smckusick   if (k <= 8)
71822879Smckusick     {
71922879Smckusick       i = k;
72022879Smckusick       while (i > 0 && oldvalue[--i] == '\0')
72122879Smckusick 	/*  SKIP  */ ;
72222879Smckusick       if (oldvalue[i] == '\0')
72322879Smckusick 	{
72422879Smckusick 	  if (SMALLVAR(leng))
72522879Smckusick 	    {
72622879Smckusick 	      pralign(typealign[type]);
72722879Smckusick 	      fprintf(initfile, labelfmt, sname);
72822879Smckusick 	      prspace(leng);
72922879Smckusick 	    }
73022879Smckusick 	  else
73122879Smckusick 	    {
73222879Smckusick 	      preven(ALIDOUBLE);
73322879Smckusick 	      prlocvar(sname, leng);
73422879Smckusick 	      *inlcomm = YES;
73522879Smckusick 	    }
73622879Smckusick 	}
73722879Smckusick       else
73822879Smckusick 	{
73922879Smckusick 	  fprintf(initfile, labelfmt, sname);
74022879Smckusick 	  if (leng == 8)
74122879Smckusick 	    prquad(oldvalue);
74222879Smckusick 	  else
74322879Smckusick 	    prsdata(oldvalue, leng);
74422879Smckusick 	}
74522879Smckusick       return;
74622879Smckusick     }
74722879Smckusick 
74822879Smckusick   repl = 1;
74922879Smckusick   k -= 8;
75022879Smckusick 
75122879Smckusick   while (k >=8)
75222879Smckusick     {
75322879Smckusick       *((int *) newvalue) = 0;
75422879Smckusick       *((int *) (newvalue + 4)) = 0;
75522879Smckusick 
75622879Smckusick       n = read(vdatafile, newvalue, 8);
75722879Smckusick       if (n < 0)
75822879Smckusick 	{
75922879Smckusick 	  err(readerror);
76022879Smckusick 	  done(1);
76122879Smckusick 	}
76222879Smckusick 
76322879Smckusick       k -= 8;
76422879Smckusick 
76522879Smckusick       if (*((int *) oldvalue) == *((int *) newvalue)
76622879Smckusick 	  && *((int *) (oldvalue + 4)) == *((int *) (newvalue + 4)))
76722879Smckusick 	repl++;
76822879Smckusick       else
76922879Smckusick 	{
77022879Smckusick 	  if (first == YES)
77122879Smckusick 	    {
77222879Smckusick 	      pralign(typealign[type]);
77322879Smckusick 	      fprintf(initfile, labelfmt, sname);
77422879Smckusick 	      first = NO;
77522879Smckusick 	    }
77622879Smckusick 
77722879Smckusick 	  if (*((int *) oldvalue) == 0
77822879Smckusick 	      && *((int *) (oldvalue + 4)) == 0)
77922879Smckusick 	    prspace(8*repl);
78022879Smckusick 	  else
78122879Smckusick 	    {
78222879Smckusick 	      while (repl-- > 0)
78322879Smckusick 		prquad(oldvalue);
78422879Smckusick 	    }
78522879Smckusick 	  *((int *) oldvalue) = *((int *) newvalue);
78622879Smckusick 	  *((int *) (oldvalue + 4)) = *((int *) (newvalue + 4));
78722879Smckusick 	  repl = 1;
78822879Smckusick 	}
78922879Smckusick     }
79022879Smckusick 
79122879Smckusick   *((int *) newvalue) = 0;
79222879Smckusick   *((int *) (newvalue + 4)) = 0;
79322879Smckusick 
79422879Smckusick   if (k > 0)
79522879Smckusick     {
79622879Smckusick       n = read(vdatafile, newvalue, k);
79722879Smckusick       if (n < 0)
79822879Smckusick 	{
79922879Smckusick 	  err(readerror);
80022879Smckusick 	  done(1);
80122879Smckusick 	}
80222879Smckusick     }
80322879Smckusick 
80422879Smckusick   if (*((int *) (oldvalue + 4)) == 0
80522879Smckusick       && *((int *) oldvalue) == 0
80622879Smckusick       && *((int *) (newvalue + 4)) == 0
80722879Smckusick       && *((int *) newvalue) == 0)
80822879Smckusick     {
80922879Smckusick       if (first == YES && !SMALLVAR(leng))
81022879Smckusick 	{
81122879Smckusick 	  prlocvar(sname, leng);
81222879Smckusick 	  *inlcomm = YES;
81322879Smckusick 	}
81422879Smckusick       else
81522879Smckusick 	{
81622879Smckusick 	  if (first == YES)
81722879Smckusick 	    {
81822879Smckusick 	      pralign(typealign[type]);
81922879Smckusick 	      fprintf(initfile, labelfmt, sname);
82022879Smckusick 	    }
82122879Smckusick 	  prspace(8*repl + k);
82222879Smckusick 	}
82322879Smckusick       return;
82422879Smckusick     }
82522879Smckusick 
82622879Smckusick   if (first == YES)
82722879Smckusick     {
82822879Smckusick       pralign(typealign[type]);
82922879Smckusick       fprintf(initfile, labelfmt, sname);
83022879Smckusick     }
83122879Smckusick 
83222879Smckusick   if (*((int *) (oldvalue + 4)) == 0
83322879Smckusick       && *((int *) oldvalue) == 0)
83422879Smckusick     prspace(8*repl);
83522879Smckusick   else
83622879Smckusick     {
83722879Smckusick       while (repl-- > 0)
83822879Smckusick 	prquad(oldvalue);
83922879Smckusick     }
84022879Smckusick 
84122879Smckusick   prsdata(newvalue, k);
84222879Smckusick 
84322879Smckusick   return;
84422879Smckusick }
84522879Smckusick 
84622879Smckusick 
84722879Smckusick 
84822879Smckusick 
prendproc()84922879Smckusick prendproc()
85022879Smckusick {
85122879Smckusick }
85222879Smckusick 
85322879Smckusick 
85422879Smckusick 
85522879Smckusick 
prtail()85622879Smckusick prtail()
85722879Smckusick {
85822879Smckusick }
85922879Smckusick 
86022879Smckusick 
86122879Smckusick 
86222879Smckusick 
86322879Smckusick 
86422879Smckusick prolog(ep, argvec)
86522879Smckusick struct Entrypoint *ep;
86622879Smckusick Addrp  argvec;
86722879Smckusick {
86822879Smckusick int i, argslot, proflab;
86922879Smckusick int size;
87022879Smckusick register chainp p;
87122879Smckusick register Namep q;
87222879Smckusick register struct Dimblock *dp;
87322879Smckusick expptr tp;
87422879Smckusick 
87522879Smckusick p2pass("\t.align\t1");
87622879Smckusick 
87722879Smckusick 
87822879Smckusick if(procclass == CLMAIN) {
87922879Smckusick 	if(fudgelabel)
88022879Smckusick 		{
88122879Smckusick 		if(ep->entryname) {
88222879Smckusick 			p2ps("_%s:",  varstr(XL, ep->entryname->extname));
88322879Smckusick 			p2pi("\t.word\tLWM%d", procno);
88422879Smckusick 		}
88522879Smckusick 		putlabel(fudgelabel);
88622879Smckusick 		fudgelabel = 0;
88722879Smckusick 		fixlwm();
88822879Smckusick 		}
88922879Smckusick 	else
89022879Smckusick 		{
89122879Smckusick 		p2pass( "_MAIN_:" );
89222879Smckusick 		if(ep->entryname == NULL)
89322879Smckusick 			p2pi("\t.word\tLWM%d", procno);
89422879Smckusick 		}
89522879Smckusick 
89622879Smckusick } else if(ep->entryname)
89722879Smckusick 	if(fudgelabel)
89822879Smckusick 		{
89922879Smckusick 		putlabel(fudgelabel);
90022879Smckusick 		fudgelabel = 0;
90122879Smckusick 		fixlwm();
90222879Smckusick 		}
90322879Smckusick 	else
90422879Smckusick 		{
90522879Smckusick 		p2ps("_%s:",  varstr(XL, ep->entryname->extname));
90622879Smckusick 		p2pi("\t.word\tLWM%d", procno);
90722879Smckusick 		prsave(newlabel());
90822879Smckusick 		}
90922879Smckusick 
91022879Smckusick if(procclass == CLBLOCK)
91122879Smckusick 	return;
91222879Smckusick if (anylocals == YES)
91322879Smckusick 	{
91422879Smckusick 	char buff[30];
91522879Smckusick 	sprintf(buff, "\tmovl\t$v.%d,r11", bsslabel);
91622879Smckusick 	p2pass(buff);
91722879Smckusick 	}
91822879Smckusick if(argvec)
91922879Smckusick 	{
92022879Smckusick 	if (argvec->tag != TADDR) badtag ("prolog",argvec->tag);
92133257Sbostic 	argloc = argvec->memoffset->constblock.constant.ci + SZINT;
92222879Smckusick 			/* first slot holds count */
92322879Smckusick 	if(proctype == TYCHAR)
92422879Smckusick 		{
92522879Smckusick 		mvarg(TYADDR, 0, chslot);
92622879Smckusick 		mvarg(TYLENG, SZADDR, chlgslot);
92722879Smckusick 		argslot = SZADDR + SZLENG;
92822879Smckusick 		}
92922879Smckusick 	else if( ISCOMPLEX(proctype) )
93022879Smckusick 		{
93122879Smckusick 		mvarg(TYADDR, 0, cxslot);
93222879Smckusick 		argslot = SZADDR;
93322879Smckusick 		}
93422879Smckusick 	else
93522879Smckusick 		argslot = 0;
93622879Smckusick 
93722879Smckusick 	for(p = ep->arglist ; p ; p =p->nextp)
93822879Smckusick 		{
93922879Smckusick 		q = (Namep) (p->datap);
94022879Smckusick 		mvarg(TYADDR, argslot, q->vardesc.varno);
94122879Smckusick 		argslot += SZADDR;
94222879Smckusick 		}
94322879Smckusick 	for(p = ep->arglist ; p ; p = p->nextp)
94422879Smckusick 		{
94522879Smckusick 		q = (Namep) (p->datap);
94622879Smckusick 		if(q->vtype==TYCHAR && q->vclass!=CLPROC)
94722879Smckusick 			{
94822879Smckusick 			if(q->vleng && ! ISCONST(q->vleng) )
94922879Smckusick 				mvarg(TYLENG, argslot,
95022879Smckusick 					q->vleng->addrblock.memno);
95122879Smckusick 			argslot += SZLENG;
95222879Smckusick 			}
95322879Smckusick 		}
95422879Smckusick 	p2pi("\taddl3\t$%d,fp,ap", argloc-ARGOFFSET);
95522879Smckusick 	p2pi("\tmovl\t$%d,(ap)\n", lastargslot/SZADDR);
95622879Smckusick 	}
95722879Smckusick 
95822879Smckusick for(p = ep->arglist ; p ; p = p->nextp)
95922879Smckusick 	{
96022879Smckusick 	q = (Namep) (p->datap);
96122879Smckusick 	if(dp = q->vdim)
96222879Smckusick 		{
96322879Smckusick 		for(i = 0 ; i < dp->ndim ; ++i)
96422879Smckusick 			if(dp->dims[i].dimexpr)
96522879Smckusick 				puteq( fixtype(cpexpr(dp->dims[i].dimsize)),
96622879Smckusick 					fixtype(cpexpr(dp->dims[i].dimexpr)));
96722879Smckusick #ifdef SDB
96822879Smckusick                 if(sdbflag) {
96922879Smckusick 		for(i = 0 ; i < dp->ndim ; ++i) {
97022879Smckusick 			if(dp->dims[i].lbaddr)
97122879Smckusick 				puteq( fixtype(cpexpr(dp->dims[i].lbaddr)),
97222879Smckusick 					fixtype(cpexpr(dp->dims[i].lb)));
97322879Smckusick 			if(dp->dims[i].ubaddr)
97422879Smckusick 				puteq( fixtype(cpexpr(dp->dims[i].ubaddr)),
97522879Smckusick 					fixtype(cpexpr(dp->dims[i].ub)));
97622879Smckusick 
97722879Smckusick                                                 }
97822879Smckusick                             }
97922879Smckusick #endif
98022879Smckusick 		size = typesize[ q->vtype ];
98122879Smckusick 		if(q->vtype == TYCHAR)
98222879Smckusick 			if( ISICON(q->vleng) )
98333257Sbostic 				size *= q->vleng->constblock.constant.ci;
98422879Smckusick 			else
98522879Smckusick 				size = -1;
98622879Smckusick 
98722879Smckusick 		/* on VAX, get more efficient subscripting if subscripts
98822879Smckusick 		   have zero-base, so fudge the argument pointers for arrays.
98922879Smckusick 		   Not done if array bounds are being checked.
99022879Smckusick 		*/
99122879Smckusick 		if(dp->basexpr)
99222879Smckusick 			puteq( 	cpexpr(fixtype(dp->baseoffset)),
99322879Smckusick 				cpexpr(fixtype(dp->basexpr)));
99422879Smckusick #ifdef SDB
99522879Smckusick 		if( (! checksubs) && (! sdbflag) )
99622879Smckusick #else
99722879Smckusick 		if(! checksubs)
99822879Smckusick #endif
99922879Smckusick 			{
100022879Smckusick 			if(dp->basexpr)
100122879Smckusick 				{
100222879Smckusick 				if(size > 0)
100322879Smckusick 					tp = (expptr) ICON(size);
100422879Smckusick 				else
100522879Smckusick 					tp = (expptr) cpexpr(q->vleng);
100622879Smckusick 				putforce(TYINT,
100722879Smckusick 					fixtype( mkexpr(OPSTAR, tp,
100822879Smckusick 						cpexpr(dp->baseoffset)) ));
100922879Smckusick 				p2pi("\tsubl2\tr0,%d(ap)",
101022879Smckusick 					p->datap->nameblock.vardesc.varno +
101122879Smckusick 						ARGOFFSET);
101222879Smckusick 				}
101333257Sbostic 			else if(dp->baseoffset->constblock.constant.ci != 0)
101422879Smckusick 				{
101522879Smckusick 				char buff[25];
101622879Smckusick 				if(size > 0)
101722879Smckusick 					{
101822879Smckusick 					sprintf(buff, "\tsubl2\t$%ld,%d(ap)",
101933257Sbostic 						dp->baseoffset->constblock.constant.ci * size,
102022879Smckusick 						p->datap->nameblock.vardesc.varno +
102122879Smckusick 							ARGOFFSET);
102222879Smckusick 					}
102322879Smckusick 				else	{
102422879Smckusick 					putforce(TYINT, mkexpr(OPSTAR, cpexpr(dp->baseoffset),
102522879Smckusick 						cpexpr(q->vleng) ));
102622879Smckusick 					sprintf(buff, "\tsubl2\tr0,%d(ap)",
102722879Smckusick 						p->datap->nameblock.vardesc.varno +
102822879Smckusick 							ARGOFFSET);
102922879Smckusick 					}
103022879Smckusick 				p2pass(buff);
103122879Smckusick 				}
103222879Smckusick 			}
103322879Smckusick 		}
103422879Smckusick 	}
103522879Smckusick 
103622879Smckusick if(typeaddr)
103722879Smckusick 	puteq( cpexpr(typeaddr), mkaddcon(ep->typelabel) );
103822879Smckusick /* replace to avoid long jump problem
103922879Smckusick putgoto(ep->entrylabel);
104022879Smckusick */
104122879Smckusick p2pi("\tjbr\tL%d", ep->entrylabel);
104222879Smckusick }
104322879Smckusick 
fixlwm()104422879Smckusick fixlwm()
104522879Smckusick {
104622879Smckusick 	extern lwmno;
104722879Smckusick 	if (lwmno == procno)
104822879Smckusick 		return;
104922879Smckusick 	fprintf(asmfile, "\t.set\tLWM%d,0x%x\n",
105022879Smckusick 		procno, regmask[highregvar]);
105122879Smckusick 	lwmno = procno;
105222879Smckusick }
105322879Smckusick 
105422879Smckusick 
prhead(fp)105522879Smckusick prhead(fp)
105622879Smckusick FILEP fp;
105722879Smckusick {
105822879Smckusick #if FAMILY==PCC
105922879Smckusick 	p2triple(PCCF_FLBRAC, ARGREG-highregvar, procno);
106022879Smckusick 	p2word( (long) (BITSPERCHAR*autoleng) );
106122879Smckusick 	p2flush();
106222879Smckusick #endif
106322879Smckusick }
1064