/* 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;
if( ISPTR( p
->left
->type
) || ISPTR( p
->right
->type
) ){
/* do pointer conversions for char and longs */
if( ( ml
==CHAR
|| ml
==UCHAR
|| ml
==LONG
|| ml
==ULONG
) && 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
= (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
==LONG
|| ml
==ULONG
) break;
else if( m
==INT
|| m
==UNSIGNED
){
if( ml
==LONG
|| ml
==ULONG
) break;
else if( m
==LONG
|| m
==ULONG
){
if( ml
!=LONG
&& ml
!= ULONG
) break;
return( p
->left
); /* conversion gets clobbered */
/* get rid of SCONV for assignments
if( p
->right
->op
== SCONV
) {
ml
= p
->right
->left
->type
;
if( ( m
==LONG
|| m
==ULONG
) &&
ml
!=FLOAT
&& ml
!=DOUBLE
) {
p
->right
= p
->right
->left
;
if( p
->right
->op
!= ICON
) cerror( "bad conversion", 0);
return( buildtree( o
==PMCONV
?MUL
:DIV
, p
->left
, p
->right
) );
/* optimize address calculations with long indexes */
if( ISPTR( p
->type
) || ISARY( p
->type
) ) {
if( p
->left
->type
==LONG
|| p
->left
->type
==ULONG
)
p
->left
= cast( p
->left
, INT
);
if( p
->right
->type
==LONG
|| p
->right
->type
==ULONG
)
p
->right
= cast( p
->right
, INT
);
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
|| ISPTR(t
) ) return(1);
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");
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! */
register int *mi
= (int *)&d
;
printf( " %o; %o; %o; %o\n", mi
[0], mi
[1], mi
[2], mi
[3] );
printf( " %o; %o\n", mi
[0], mi
[1] );
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 */
/* 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
) TWORD type
; { /* map types which are not defined on the local machine */
noinit() { /* 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.. */