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