/* Copyright (c) 1979 Regents of the University of California */
static char sccsid
[] = "@(#)put.c 1.17 %G%";
* If DEBUG is defined, include the table
* of the printing opcode names.
* Put is responsible for the interpreter equivalent of code
* generation. Since the interpreter is specifically designed
* for Pascal, little work is required here.
int n
, subop
, suboppr
, op
, oldlc
, w
;
* It would be nice to do some more
* optimizations here. The work
* done to collapse offsets in lval
* should be done here, the IFEQ etc
* relational operators could be used
* code disabled - do nothing
suboppr
= subop
= (*p
>> 8) & 0377;
if ((cp
= otext
[op
]) == NIL
) {
if (p
[1] < 128 && p
[1] >= -128) {
printf ( "%5d\tCON8\t%22.14e\n" ,
* ( ( double * ) &p
[1] ) );
for ( i
= 1 ; i
<= 4 ; i
++ )
if (op
>= O_REL2
&& op
<= O_REL84
) {
if ((i
= (subop
>> INDX
) * 5 ) >= 30)
string
= &"IFEQ\0IFNE\0IFLT\0IFGT\0IFLE\0IFGE"[i
];
/* relative addressing */
p
[1] -= ( unsigned ) lc
+ sizeof(short);
/* sub opcode optimization */
if (p
[1] < 128 && p
[1] >= -128 && p
[1] != 0) {
/* relative addressing */
p
[n
- 1] -= ( unsigned ) lc
+ (n
- 1) * sizeof(short);
(string
= "'x'")[1] = p
[1];
(string
= "'x'")[1] = p
[1];
printf("%5d\tCASE1\t%d\n"
, lc
- HEADER_BYTES
, p
[1]);
* this to build a byte size case table
* saving bytes across calls in casewrd
* so they can be put out by word()
casewrd
= (p
[1] & 0377) << 8;
word(((p
[1] & 0377) << 8) | casewrd
);
word((p
[1] & 0377) | casewrd
);
printf("%5d\tCASE2\t%d\n"
, lc
- HEADER_BYTES
, p
[1]);
/* sub opcode optimization */
if (*lp
< 128 && *lp
>= -128 && *lp
!= 0) {
p
+= (sizeof(long) / sizeof(int));
/* relative addressing */
p
[1 + (n
- 2) * (sizeof(long) / sizeof(int))] -=
(unsigned)lc
+ (sizeof(short) +
/* sub opcode optimization */
if (*lp
< 128 && *lp
>= -128 && *lp
!= 0) {
p
+= (sizeof(long) / sizeof(int));
/* absolute long addressing */
* positive offsets represent arguments
* and must use "ap" display entry rather
* offsets out of range of word addressing
* must use long offset opcodes
if (p
[1] < SHORTADDR
&& p
[1] >= -SHORTADDR
)
if ( op
== O_LRV
|| op
== O_FOR4U
|| op
== O_FOR4D
)
printf("%5d\t%s", lc
- HEADER_BYTES
, cp
+1);
for ( i
= 2, lp
= (long *)&p
[1]; i
< n
; i
+= sizeof ( long )/sizeof ( short ) )
printf( "\t%D " , *lp
++ );
word((op
& 0377) | subop
<< 8);
word(op
<< 8 | (subop
& 0377));
for ( i
= 1, sp
= (short *)&p
[1]; i
< n
; i
++)
printf("%5d\t%s", lc
- HEADER_BYTES
, cp
+1);
word((op
& 0377) | subop
<< 8);
word(op
<< 8 | (subop
& 0377));
* listnames outputs a list of enumerated type names which
* can then be selected from to output a TSCAL
* a pointer to the address in the code of the namelist
* is kept in value[ NL_ELABEL ].
/* code is off - do nothing */
if (ap
->value
[ NL_ELABEL
] != 0) {
/* the list already exists */
return( ap
-> value
[ NL_ELABEL
] );
ap
->value
[ NL_ELABEL
] = lc
;
putprintf( " .data" , 0 );
putprintf( " .align 1" , 0 );
ap
-> value
[ NL_ELABEL
] = getlab();
putlab( ap
-> value
[ NL_ELABEL
] );
len
= next
->range
[1]-next
->range
[0]+1;
putprintf( " .word %d" , 0 , len
);
/* offsets of each scalar name */
len
= (len
+1)*sizeof(short);
putprintf( " .word %d" , 0 , len
);
for(strptr
= next
->symbol
; *strptr
++; len
++)
putprintf( " .word %d" , 0 , len
);
} while (next
= next
->chain
);
/* list of scalar names */
strptr
= getnext(ap
, &next
);
strptr
= getnext(next
, &next
);
strptr
= getnext(next
, &next
);
putprintf( " .byte 0%o" , 1 , *strptr
++ );
for ( w
= 2 ; ( w
<= 8 ) && *strptr
; w
++ ) {
putprintf( ",0%o" , 1 , *strptr
++ );
putprintf( " .byte 0" , 0 );
strptr
= getnext( next
, &next
);
putprintf( " .text" , 0 );
return( ap
-> value
[ NL_ELABEL
] );
if (opt('k') && CGENNING
)
printf("%5d\t\t\"%s\"\n", lc
-HEADER_BYTES
, next
->symbol
);
* Putspace puts out a table
* of nothing to leave space
* for the case branch table e.g.
* code disabled - do nothing
printf("%5d\t.=.+%d\n", lc
- HEADER_BYTES
, n
);
for (i
= even(n
); i
> 0; i
-= 2)
register unsigned short w
;
register char *strptr
= sptr
;
register int pad
= padding
;
* code disabled - do nothing
printf("%5d\t\t\"%s\"\n", lc
-HEADER_BYTES
, strptr
);
w
= (unsigned short) * strptr
;
w
= (unsigned short)*strptr
<<8;
w
= (unsigned short) * strptr
;
w
= (unsigned short)*strptr
<<8;
register char *strptr
= sptr
;
* Patch repairs the branch
* at location loc to come
* to the current location.
* for PC, this puts down the label
* and the branch just references that label.
* lets here it for two pass assemblers.
patchfil(loc
, (long)(lc
-loc
-2), 1);
patchfil(loc
, (long)(lc
- HEADER_BYTES
), 2);
* Patchfil makes loc+2 have jmploc
patchfil(loc
, jmploc
, words
)
printf("\tpatch %u %D\n", loc
- HEADER_BYTES
, jmploc
);
i
= ((unsigned) loc
+ 2 - ((unsigned) lc
& ~01777))/2;
lseek(ofil
, (long) loc
+2, 0);
lseek(ofil
, (long) 0, 2);
* Put the word o into the code
i
= (obufp
- ( ( short * ) obuf
) ) * 2;
if (i
!= 0 && write(ofil
, obuf
, i
) != i
)
perror(obj
), pexit(DIED
);
* Getlab - returns the location counter.
* included here for the eventual code generator.
* Putlab - lay down a label.
* for PC, just print the label name with a colon after it.
putprintf( PREFIXFORMAT
, 1 , LABELPREFIX
, l
);