* Copyright (c) 1980 The Regents of the University of California.
* %sccs.include.proprietary.c%
static char sccsid
[] = "@(#)vax.c 5.4 (Berkeley) %G%";
* VAX specific routines for the F77 compiler, pass 1
* University of Utah CS Dept modification history:
* Revision 5.2 85/08/10 05:06:30 donn
* Deleted intcon[] and realcon[], since they are now made redundant by
* changes in intr.c. From Jerry Berkman.
* Revision 5.1 85/08/10 03:50:38 donn
* Revision 3.1 85/02/27 19:14:58 donn
* Changed to use pcc.h instead of pccdefs.h.
* Revision 2.3 85/02/22 01:09:22 donn
* memname() didn't know about intrinsic functions...
* Revision 2.2 85/02/12 17:56:44 donn
* Put the argument to the profiling routine in data space instead of
* constant space. From Jerry Berkman.
* Revision 2.1 84/07/19 12:05:08 donn
* Changed comment headers for UofU.
* Revision 1.2 84/02/26 06:41:04 donn
* Added Berkeley changes to move data around to produce shorter offsets.
int maxregvar
= MAXREGVAR
;
int regnum
[] = { 10, 9, 8, 7, 6 } ;
static int regmask
[] = { 0x800, 0xc00, 0xe00, 0xf00, 0xf80, 0xfc0 };
* The VAX assembler has a serious and not easily fixable problem
* with generating instructions that contain expressions of the form
* label1-label2 where there are .align's in-between the labels.
* Therefore, the compiler must keep track of the offsets and output
LOCAL
int i_offset
; /* initfile offset */
LOCAL
int a_offset
; /* asmfile offset */
pruse(asmfile
, USEINIT
); /* This is not a constant */
fprintf(asmfile
, "L%d:\t.space\t4\n", proflab
);
pruse(asmfile
, USECONST
);
p2pi("\tmovab\tL%d,r0", proflab
);
p2pi("\tsubl2\t$LF%d,sp", procno
);
* move argument slot arg1 (relative to ap)
* to slot arg2 (relative to ARGREG)
p2pij("\tmovl\t%d(ap),%d(fp)", arg1
+ARGOFFSET
, arg2
+argloc
);
fprintf(fp
, "L%d:\n", k
);
fprintf(fp
, "\t.word\t%ld\n", n
);
fprintf(fp
, "\t.long\t%ld\n", n
);
fprintf(fp
, "\t.long\tL%ld\n", a
);
fprintf(fp
, "\t%s\t0f%e\n", (type
==TYREAL
? ".float" : ".double"), x
);
/* non-portable cheat to preserve bit patterns */
union { double xd
; long int xl
[2]; } cheat
;
fprintf(fp
, "\t.long\t0x%X\n", *(long *) &y
);
fprintf(fp
, "\t.long\t0x%X,0x%X\n", cheat
.xl
[0], cheat
.xl
[1]);
praddr(fp
, stg
, varno
, offset
)
fprintf(fp
, "\t.long\t0\n");
fprintf(fp
, "\t.long\t%s", memname(stg
,varno
));
fprintf(fp
, "+%ld", offset
);
fprintf(initfile
, "\t.space\t%d\n", lg
);
fprintf(initfile
, "\t.space\t%d\n", n
);
fprintf(asmfile
, "\t.space\t%d\n", lg
);
fprintf(asmfile
, "\t.space\t%d\n", n
);
vaxgoto(index
, nlab
, labs
)
struct Labelblock
*labs
[];
p2pi("\tcasel\tr0,$1,$%d", nlab
-1);
p2pi("L%d:", arrlab
= newlabel() );
for(i
= 0; i
< nlab
; ++i
)
p2pij("\t.word\tL%d-L%d", labs
[i
]->labelno
, arrlab
);
type
= p
->headblock
.vtype
;
else if (type
== TYSHORT
)
p2pi("\tjlss\tL%d", neg
);
p2pi("\tjeql\tL%d", zer
);
sprintf(s
, "_%s", varstr(XL
, extsymtab
[mem
].extname
) );
sprintf(s
, "q.%d", mem
+eqvstart
);
fprintf(asmfile
, "\t.lcomm\t%s,%ld\n", s
, len
);
*((short *) shrt
) = (short) cp
->constant
.ci
;
*((int *) lng
) = cp
->constant
.ci
;
jp
= (int *) &(cp
->constant
.cd
[0]);
jp
= (int *) &(cp
->constant
.cd
[0]);
jp
= (int *) &(cp
->constant
.cd
[0]);
badtype("packbytes", cp
->vtype
);
static char *longfmt
= "\t.long\t0x%x\n";
static char *wordfmt
= "\t.word\t0x%x\n";
static char *bytefmt
= "\t.byte\t0x%x\n";
fprintf(initfile
, longfmt
, *((int *) s
));
fprintf(initfile
, wordfmt
, 0xffff & (*((short *) (s
+ i
))));
fprintf(initfile
,bytefmt
, 0xff & s
[i
]);
static char *quadfmt1
= "\t.quad\t0x%x\n";
static char *quadfmt2
= "\t.quad\t0x%x%08x\n";
if ( *((int *) (s
+ 4)) == 0 )
fprintf(initfile
, quadfmt1
, *((int *) s
));
fprintf(initfile
, quadfmt2
, *((int *) (s
+ 4)), *((int *) s
));
/* The code for generating .fill directives has been */
/* ifdefed out because of bugs in the UCB VAX assembler. */
/* If those bugs are ever fixed (and it seems unlikely), */
/* the NOTDEF's should be replaced by UCBVAXASM. */
static char *fillfmt1
= "\t.fill\t%d,8,0x%x\n";
static char *fillfmt2
= "\t.fill\t%d,8,0x%x%08x\n";
if (*((int *) (s
+ 4)) == 0)
fprintf(initfile
, fillfmt1
, n
, *((int *) s
));
fprintf(initfile
, fillfmt2
, n
, *((int *) (s
+ 4)), *((int *) s
));
register struct Extsym
*ep
;
static char *globlfmt
= "\t.globl\t_%s\n";
static char *commfmt
= "\t.comm\t_%s,%ld\n";
static char *labelfmt
= "_%s:\n";
static char *seekerror
= "seek error on tmp file";
static char *readerror
= "read error on tmp file";
tag
= varstr(XL
, ep
->extname
);
fprintf(asmfile
, globlfmt
, tag
);
fprintf(asmfile
, commfmt
, tag
, leng
);
fprintf(asmfile
, globlfmt
, tag
);
fprintf(initfile
, labelfmt
, tag
);
pos
= lseek(cdatafile
, ep
->initoffset
, 0);
*((int *) (oldvalue
+ 4)) = 0;
n
= read(cdatafile
, oldvalue
, 8);
while (i
> 0 && oldvalue
[--i
] == '\0') /* SKIP */;
*((int *) (newvalue
+ 4)) = 0;
n
= read(cdatafile
, newvalue
, 8);
if (*((int *) oldvalue
) == *((int *) newvalue
)
&& *((int *) (oldvalue
+ 4)) == *((int *) (newvalue
+ 4)))
if (*((int *) oldvalue
) == 0
&& *((int *) (oldvalue
+ 4)) == 0)
*((int *) oldvalue
) = *((int *) newvalue
);
*((int *) (oldvalue
+ 4)) = *((int *) (newvalue
+ 4));
*((int *) (newvalue
+ 4)) = 0;
n
= read(cdatafile
, newvalue
, leng
);
if (*((int *) (oldvalue
+ 4)) == 0
&& *((int *) oldvalue
) == 0
&& *((int *) (newvalue
+ 4)) == 0
&& *((int *) newvalue
) == 0)
if (*((int *) (oldvalue
+ 4)) == 0
&& *((int *) oldvalue
) == 0)
prlocdata(sname
, leng
, type
, initoffset
, inlcomm
)
static char *seekerror
= "seek error on tmp file";
static char *readerror
= "read error on tmp file";
static char *labelfmt
= "%s:\n";
pos
= lseek(vdatafile
, initoffset
, 0);
*((int *) (oldvalue
+ 4)) = 0;
n
= read(vdatafile
, oldvalue
, 8);
while (i
> 0 && oldvalue
[--i
] == '\0')
pralign(typealign
[type
]);
fprintf(initfile
, labelfmt
, sname
);
fprintf(initfile
, labelfmt
, sname
);
*((int *) (newvalue
+ 4)) = 0;
n
= read(vdatafile
, newvalue
, 8);
if (*((int *) oldvalue
) == *((int *) newvalue
)
&& *((int *) (oldvalue
+ 4)) == *((int *) (newvalue
+ 4)))
pralign(typealign
[type
]);
fprintf(initfile
, labelfmt
, sname
);
if (*((int *) oldvalue
) == 0
&& *((int *) (oldvalue
+ 4)) == 0)
*((int *) oldvalue
) = *((int *) newvalue
);
*((int *) (oldvalue
+ 4)) = *((int *) (newvalue
+ 4));
*((int *) (newvalue
+ 4)) = 0;
n
= read(vdatafile
, newvalue
, k
);
if (*((int *) (oldvalue
+ 4)) == 0
&& *((int *) oldvalue
) == 0
&& *((int *) (newvalue
+ 4)) == 0
&& *((int *) newvalue
) == 0)
if (first
== YES
&& !SMALLVAR(leng
))
pralign(typealign
[type
]);
fprintf(initfile
, labelfmt
, sname
);
pralign(typealign
[type
]);
fprintf(initfile
, labelfmt
, sname
);
if (*((int *) (oldvalue
+ 4)) == 0
&& *((int *) oldvalue
) == 0)
register struct Dimblock
*dp
;
if(procclass
== CLMAIN
) {
p2ps("_%s:", varstr(XL
, ep
->entryname
->extname
));
p2pi("\t.word\tLWM%d", procno
);
if(ep
->entryname
== NULL
)
p2pi("\t.word\tLWM%d", procno
);
p2ps("_%s:", varstr(XL
, ep
->entryname
->extname
));
p2pi("\t.word\tLWM%d", procno
);
sprintf(buff
, "\tmovl\t$v.%d,r11", bsslabel
);
if (argvec
->tag
!= TADDR
) badtag ("prolog",argvec
->tag
);
argloc
= argvec
->memoffset
->constblock
.constant
.ci
+ SZINT
;
/* first slot holds count */
mvarg(TYADDR
, 0, chslot
);
mvarg(TYLENG
, SZADDR
, chlgslot
);
argslot
= SZADDR
+ SZLENG
;
else if( ISCOMPLEX(proctype
) )
mvarg(TYADDR
, 0, cxslot
);
for(p
= ep
->arglist
; p
; p
=p
->nextp
)
mvarg(TYADDR
, argslot
, q
->vardesc
.varno
);
for(p
= ep
->arglist
; p
; p
= p
->nextp
)
if(q
->vtype
==TYCHAR
&& q
->vclass
!=CLPROC
)
if(q
->vleng
&& ! ISCONST(q
->vleng
) )
q
->vleng
->addrblock
.memno
);
p2pi("\taddl3\t$%d,fp,ap", argloc
-ARGOFFSET
);
p2pi("\tmovl\t$%d,(ap)\n", lastargslot
/SZADDR
);
for(p
= ep
->arglist
; p
; p
= p
->nextp
)
for(i
= 0 ; i
< dp
->ndim
; ++i
)
puteq( fixtype(cpexpr(dp
->dims
[i
].dimsize
)),
fixtype(cpexpr(dp
->dims
[i
].dimexpr
)));
for(i
= 0 ; i
< dp
->ndim
; ++i
) {
puteq( fixtype(cpexpr(dp
->dims
[i
].lbaddr
)),
fixtype(cpexpr(dp
->dims
[i
].lb
)));
puteq( fixtype(cpexpr(dp
->dims
[i
].ubaddr
)),
fixtype(cpexpr(dp
->dims
[i
].ub
)));
size
= typesize
[ q
->vtype
];
size
*= q
->vleng
->constblock
.constant
.ci
;
/* on VAX, get more efficient subscripting if subscripts
have zero-base, so fudge the argument pointers for arrays.
Not done if array bounds are being checked.
puteq( cpexpr(fixtype(dp
->baseoffset
)),
cpexpr(fixtype(dp
->basexpr
)));
if( (! checksubs
) && (! sdbflag
) )
tp
= (expptr
) ICON(size
);
tp
= (expptr
) cpexpr(q
->vleng
);
fixtype( mkexpr(OPSTAR
, tp
,
cpexpr(dp
->baseoffset
)) ));
p2pi("\tsubl2\tr0,%d(ap)",
p
->datap
->nameblock
.vardesc
.varno
+
else if(dp
->baseoffset
->constblock
.constant
.ci
!= 0)
sprintf(buff
, "\tsubl2\t$%ld,%d(ap)",
dp
->baseoffset
->constblock
.constant
.ci
* size
,
p
->datap
->nameblock
.vardesc
.varno
+
putforce(TYINT
, mkexpr(OPSTAR
, cpexpr(dp
->baseoffset
),
sprintf(buff
, "\tsubl2\tr0,%d(ap)",
p
->datap
->nameblock
.vardesc
.varno
+
puteq( cpexpr(typeaddr
), mkaddcon(ep
->typelabel
) );
/* replace to avoid long jump problem
p2pi("\tjbr\tL%d", ep
->entrylabel
);
fprintf(asmfile
, "\t.set\tLWM%d,0x%x\n",
procno
, regmask
[highregvar
]);
p2triple(PCCF_FLBRAC
, ARGREG
-highregvar
, procno
);
p2word( (long) (BITSPERCHAR
*autoleng
) );