/* this file contains code which is dependent on the target machine */
cast( p
, t
) register NODE
*p
; TWORD t
; {
/* cast node p to type t */
p
= buildtree( CAST
, block( NAME
, NIL
, NIL
, t
, 0, (int)t
), p
);
/* this is called to do local transformations on
an expression tree preparitory to its being
written out in intermediate code.
/* the major essential job is rewriting the
automatic variables and arguments in terms of
/* conversion ops which are not necessary are also clobbered here */
/* in addition, any special features (such as rewriting
exclusive or) are easily handled here as well */
register struct symtab
*q
;
if( p
->rval
< 0 ) { /* already processed; ignore... */
/* fake up a structure reference */
r
= block( REG
, NIL
, NIL
, PTR
+STRTY
, 0, 0 );
r
->rval
= (q
->sclass
==AUTO
?STKREG
:ARGREG
);
p
= stref( block( STREF
, r
, p
, 0, 0, 0 ) );
if( q
->slevel
== 0 ) break;
/* do pointer conversions for char and longs */
if( ( ml
==CHAR
|| ml
==UCHAR
|| ml
==SHORT
|| ml
==USHORT
) && p
->left
->op
!= ICON
) break;
/* pointers all have the same representation; the type is inherited */
m
= (p
->type
== FLOAT
|| p
->type
== DOUBLE
);
ml
= (p
->left
->type
== FLOAT
|| p
->left
->type
== DOUBLE
);
/* now, look for conversions downwards */
if( p
->left
->op
== ICON
){ /* simulate the conversion here */
p
->left
->lval
= (char) val
;
p
->left
->lval
= val
& 0XFF;
p
->left
->lval
= val
& 0XFFFFL
;
p
->left
->lval
= (short)val
;
p
->left
->lval
= val
& 0xFFFFFFFFL
;
p
->left
->lval
= (int)val
;
/* meaningful ones are conversion of int to char, int to short,
and short to char, and unsigned version of them */
if( m
==CHAR
|| m
==UCHAR
){
if( ml
!=CHAR
&& ml
!= UCHAR
) break;
else if( m
==SHORT
|| m
==USHORT
){
if( ml
!=CHAR
&& ml
!=UCHAR
&& ml
!=SHORT
&& ml
!=USHORT
) break;
if( tlen(p
) == tlen(p
->left
) ) goto inherit
;
return( p
->left
); /* conversion gets clobbered */
if( p
->right
->op
!= ICON
) cerror( "bad conversion", 0);
return( buildtree( o
==PMCONV
?MUL
:DIV
, p
->left
, p
->right
) );
/* convert >> to << with negative shift count */
/* only if type of left operand is not unsigned */
if( ISUNSIGNED(p
->left
->type
) ) break;
p
->right
= buildtree( UNARY MINUS
, p
->right
, NIL
);
if( p
->op
== RS
) p
->op
= LS
;
if( p
->left
->op
== UNARY MUL
&& (r
=p
->left
->left
)->op
== PCONV
)
if( r
->left
->op
== PLUS
|| r
->left
->op
== MINUS
)
if( ISUNSIGNED(p
->left
->type
) )
return(1); /* all names can have & taken on them */
cendarg(){ /* at the end of the arguments of a ftn, set the automatic offset */
cisreg( t
) TWORD t
; { /* is an automatic variable of type t OK for a register variable */
if( t
==INT
|| t
==UNSIGNED
|| t
==LONG
|| t
==ULONG
/* tbl */
|| t
==CHAR
|| t
==UCHAR
|| t
==SHORT
|| t
==USHORT
/* tbl */
|| t
==FLOAT
|| t
==DOUBLE
|| ISPTR(t
)) return(1); /* tbl */
offcon( off
, t
, d
, s
) OFFSZ off
; TWORD t
; {
/* return a node, for structure references, which is suitable for
being added to a pointer of type t, in order to be off bits offset
/* t, d, and s are the type, dimension offset, and sizeoffset */
/* in general they are necessary for offcon, but not on H'well */
static inwd
/* current bit offsed in word */;
static word
/* word being built from fields */;
incode( p
, sz
) register NODE
*p
; {
/* generate initialization code for assigning a constant c
to a field of width sz */
/* we assume that the proper alignment has been obtained */
/* inoff is updated to have the proper final value */
/* we also assume sz < SZINT */
if((sz
+inwd
) > SZINT
) cerror("incode: field > int");
word
|= ((unsigned)(p
->lval
<<(32-sz
))) >> (32-sz
-inwd
);
printf( " .long 0x%x\n", word
);
fincode( d
, sz
) double d
; {
/* output code to initialize space of size sz to the value d */
/* the proper alignment has been obtained */
/* inoff is updated to have the proper final value */
/* on the target machine, write it out in octal! */
printf(" %s 0%c%.20e\n", sz
== SZDOUBLE
? ".double" : ".float",
sz
== SZDOUBLE
? 'd' : 'f', d
);
cinit( p
, sz
) NODE
*p
; {
/* arrange for the initialization of p into a space of
/* the proper alignment has been opbtained */
/* inoff is updated to have the proper final value */
vfdzero( n
){ /* define n bits of zeros in a vfd */
printf( " .long 0x%x\n", word
);
/* make a name look like an external name in the local machine */
static char text
[NCHNAM
+1];
for( i
=1; *p
&&i
<NCHNAM
; ++i
){
text
[NCHNAM
] = '\0'; /* truncate */
ctype( type
){ /* map types which are not defined on the local machine */
noinit( t
) { /* curid is a variable which is defined but
is not initialized (and not a function );
This routine returns the stroage class for an uninitialized declaration */
commdec( id
){ /* make a common declaration for id, if reasonable */
register struct symtab
*q
;
printf( " .comm %s,", exname( q
->sname
) );
off
= tsize( q
->stype
, q
->dimoff
, q
->sizoff
);
printf( CONFMT
, off
/SZCHAR
);
isitlong( cb
, ce
){ /* is lastcon to be long or short */
/* cb is the first character of the representation, ce the last */
if( ce
== 'l' || ce
== 'L' ||
lastcon
>= (1L << (SZINT
-1) ) ) return (1);
isitfloat( s
) char *s
; {
/* walk the tree and write out the nodes.. */
printf("0,%d,%d\n", ptype
, (-poffset
)/SZCHAR
);
printf("0,%d,0\n", ptype
);
printf("0,%d,L%d\n", ptype
, poffset
);
printf("0,%d,%s\n", ptype
, exname(pname
));
printf("0,%d,%d\n", ptype
, poffset
);
printf("0,%d,%d\n", ptype
, poffset
/SZCHAR
);
/* parameter stab entries are processed in dclargs() */
if (ddebug
) printf(" No .stab for %.8s\n", pname
);
printf("\t.stabs\t\"%.8s\", ", name
);
if (c
= name
[i
]) printf("'%c,", c
);
printf("0%o,0,0%o\n",type
, value
);
register struct symtab
*p
; {
if ((s
= dimtab
[p
->sizoff
]/SZCHAR
) > 1) {
while ( *cq
) if ( *cp
++ != *cq
++ ) goto neq
;
if ( *cp
== '\0' ) goto eq
;
neq
: for (i
=0; i
<100; i
++)
for ( cp
= ititle
+1; *(cp
-1); cp
+= 8 ) {
* We use the old style stab to introduce the
* name of the file. This is the only place
* where we could use a stab, with the last
* expression the '.', but this is also the only
* place where the first argument to the stab is
* a string (namely the name of the file).
if (gdebug
) printf("0,0,LL%d\n", labelno
);
printf("LL%d:\n", labelno
++);
eq
: if (lineno
== lastlineno
) return;
pstabdot(N_SLINE
, lineno
);
pstab(NULLNAME
, N_SLINE
);
printf("0,%d,LL%d\n", lineno
, labelno
);
printf("LL%d:\n", labelno
++);
pstabdot(N_LBRAC
, level
);
pstab(NULLNAME
, N_LBRAC
);
printf("0,%d,LL%d\n", level
, labelno
);
printf("LL%d:\n", labelno
++);
pstabdot(N_RBRAC
, level
);
pstab(NULLNAME
, N_RBRAC
);
printf("0,%d,LL%d\n", level
, labelno
);
printf("LL%d:\n", labelno
++);
printf("0,%d,_%.7s\n", lineno
, sname
);