Many changes:
- added floating point - improved assembler part, now uses short encodings when possible - reduced generated relocation - and name table
This commit is contained in:
parent
b61011fba9
commit
e0fc646222
12 changed files with 534 additions and 158 deletions
|
@ -61,7 +61,7 @@ C_loi
|
|||
"movl ~$1/4, r1";
|
||||
"addl2 ~$1, r0";
|
||||
"2:";
|
||||
"movl -(r0), -(sp)";
|
||||
"pushl -(r0)";
|
||||
"sobgtr r1, 2b".
|
||||
default ==> arg_error( "loi", $1).
|
||||
|
||||
|
@ -222,6 +222,37 @@ C_sru ==> "movl ~$1, r0";
|
|||
/* */
|
||||
/******************************************************************************/
|
||||
|
||||
C_adf
|
||||
$1 == 4 ==> "addf2 (sp)+, (sp)".
|
||||
$1 == 8 ==> "addd2 (sp)+, (sp)".
|
||||
default ==> arg_error( "adf", $1).
|
||||
|
||||
C_sbf
|
||||
$1 == 4 ==> "subf2 (sp)+, (sp)".
|
||||
$1 == 8 ==> "subd2 (sp)+, (sp)".
|
||||
default ==> arg_error( "sbf", $1).
|
||||
|
||||
C_mlf
|
||||
$1 == 4 ==> "mulf2 (sp)+, (sp)".
|
||||
$1 == 8 ==> "muld2 (sp)+, (sp)".
|
||||
default ==> arg_error( "mlf", $1).
|
||||
|
||||
C_dvf
|
||||
$1 == 4 ==> "divf2 (sp)+, (sp)".
|
||||
$1 == 8 ==> "divd2 (sp)+, (sp)".
|
||||
default ==> arg_error( "dvf", $1).
|
||||
|
||||
C_ngf
|
||||
$1 == 4 ==> "mnegf (sp), (sp)".
|
||||
$1 == 8 ==> "mnegd (sp), (sp)".
|
||||
default ==> arg_error( "ngf", $1).
|
||||
|
||||
C_fif ==> "movl ~$1,r0";
|
||||
"jsb .fif".
|
||||
|
||||
C_fef ==> "movl ~$1,r0";
|
||||
"jsb .fef".
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* Group 6 : Pointer arithmetic */
|
||||
|
@ -287,19 +318,19 @@ C_zer
|
|||
|
||||
C_cii ==> "jsb .cii".
|
||||
|
||||
C_cui ==> "jsb .cui".
|
||||
C_cui ==> C_cuu().
|
||||
|
||||
C_cfi ==> "jsb .cfi".
|
||||
|
||||
C_cif ==> "jsb cif".
|
||||
C_cif ==> "jsb .cif".
|
||||
|
||||
C_cuf ==> "jsb .cuf".
|
||||
|
||||
C_cff ==> "jsb .cff".
|
||||
|
||||
C_ciu ==> "jsb .cuu".
|
||||
C_ciu ==> C_cuu().
|
||||
|
||||
C_cuu ==> "jsb .cuu ".
|
||||
C_cuu ==> "addl2 ~8,sp".
|
||||
|
||||
C_cfu ==> "jsb .cfu".
|
||||
|
||||
|
@ -470,44 +501,62 @@ C_cmp ==> /* bug : "subl2 (sp)+, (sp)". */
|
|||
"br 2f";
|
||||
"1 : decl r0";
|
||||
"2 : pushl r0".
|
||||
C_cmf
|
||||
$1==4 ==> "clrl r0";
|
||||
"cmpf (sp)+, (sp)+";
|
||||
"beql 2f";
|
||||
"bgtr 1f";
|
||||
"incl r0";
|
||||
"br 2f";
|
||||
"1 : decl r0";
|
||||
"2 : pushl r0".
|
||||
$1==8 ==> "clrl r0";
|
||||
"cmpd (sp)+, (sp)+";
|
||||
"beql 2f";
|
||||
"bgtr 1f";
|
||||
"incl r0";
|
||||
"br 2f";
|
||||
"1 : decl r0";
|
||||
"2 : pushl r0".
|
||||
default ==> arg_error("cmf", $1).
|
||||
|
||||
C_tlt ==> "movl (sp)+, r0";
|
||||
"movl ~1, -(sp)";
|
||||
"pushl ~1";
|
||||
"tstl r0";
|
||||
"blss 1f";
|
||||
"clrl (sp)";
|
||||
"1:".
|
||||
|
||||
C_tle ==> "movl (sp)+, r0";
|
||||
"movl ~1, -(sp)";
|
||||
"pushl ~1";
|
||||
"tstl r0";
|
||||
"bleq 1f";
|
||||
"clrl (sp)";
|
||||
"1:".
|
||||
|
||||
C_teq ==> "movl (sp)+, r0";
|
||||
"movl ~1, -(sp)";
|
||||
"pushl ~1";
|
||||
"tstl r0";
|
||||
"beql 1f";
|
||||
"clrl (sp)";
|
||||
"1:".
|
||||
|
||||
C_tne ==> "movl (sp)+, r0";
|
||||
"movl ~1, -(sp)";
|
||||
"pushl ~1";
|
||||
"tstl r0";
|
||||
"bneq 1f";
|
||||
"clrl (sp)";
|
||||
"1:".
|
||||
|
||||
C_tge ==> "movl (sp)+, r0";
|
||||
"movl ~1, -(sp)";
|
||||
"pushl ~1";
|
||||
"tstl r0";
|
||||
"bgeq 1f";
|
||||
"clrl (sp)";
|
||||
"1:".
|
||||
|
||||
C_tgt ==> "movl (sp)+, r0";
|
||||
"movl ~1, -(sp)";
|
||||
"pushl ~1";
|
||||
"tstl r0";
|
||||
"bgtr 1f";
|
||||
"clrl (sp)";
|
||||
|
@ -643,7 +692,7 @@ C_dup
|
|||
default ==> "movl ~$1/4, r0";
|
||||
"addl3 ~$1, sp, r1";
|
||||
"1:";
|
||||
"movl -(r1), -(sp)";
|
||||
"pushl -(r1)";
|
||||
"sobgtr r0, 1b".
|
||||
|
||||
C_dus
|
||||
|
@ -651,7 +700,7 @@ C_dus
|
|||
"addl3 r0, sp, r1";
|
||||
"ashl ~-2, r0, r0";
|
||||
"1:";
|
||||
"movl -(r1), -(sp)";
|
||||
"pushl -(r1)";
|
||||
"sobgtr r0, 1b".
|
||||
default ==> arg_error( "dus", $1).
|
||||
|
||||
|
@ -663,7 +712,7 @@ C_fil.. ==> "moval $1 + $2, hol0 + 4".
|
|||
C_gto.. ==> "pushal $1+$2";
|
||||
"jmp .gto".
|
||||
|
||||
C_lim ==> "movl .trpim, -(sp)".
|
||||
C_lim ==> "pushl .trpim".
|
||||
|
||||
C_lin ==> "movl ~$1, hol0".
|
||||
|
||||
|
@ -715,6 +764,7 @@ C_trp ==> "jsb .trp".
|
|||
$2 == 2 ==> gen2( (short) atoi( $1)).
|
||||
$2 == 4 ==> gen4( (long) atol( $1)).
|
||||
default ==> arg_error( "icon", $2).
|
||||
..fcon ==> con_float($1, $2).
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ IDIRS=-I.\
|
|||
all : data.o con2.o con4.o relocation.o end_back.o gen1.o gen2.o\
|
||||
gen4.o init_back.o mysprint.o output.o reloc1.o reloc2.o reloc4.o\
|
||||
rom2.o rom4.o set_global.o set_local.o switchseg.o symboldef.o text2.o\
|
||||
text4.o do_open.o do_close.o memory.o label.o misc.o extnd.o symtable.o
|
||||
text4.o do_open.o do_close.o memory.o label.o misc.o extnd.o symtable.o\
|
||||
common.o
|
||||
|
||||
data.o : data.h back.h header.h $(SOURCE)/data.c
|
||||
$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/data.c
|
||||
|
@ -101,3 +102,5 @@ misc.o : data.h back.h ../mach.h $(SOURCE)/misc.c
|
|||
label.o : data.h back.h ../mach.h $(SOURCE)/label.c
|
||||
$(CC) $(CFLAGS) -c $(IDIRS) -I.. $(SOURCE)/label.c
|
||||
|
||||
common.o : data.h back.h header.h $(SOURCE)/common.c
|
||||
$(CC) $(CFLAGS) -c $(IDIRS) $(SOURCE)/common.c
|
||||
|
|
|
@ -57,10 +57,10 @@ char *m;
|
|||
|
||||
|
||||
process_operand( arg, op)
|
||||
char *arg;
|
||||
struct t_operand *op;
|
||||
register char *arg;
|
||||
register struct t_operand *op;
|
||||
{
|
||||
char *einde;
|
||||
register char *einde;
|
||||
|
||||
if ( n_index == 3)
|
||||
n_index = 0;
|
||||
|
@ -116,7 +116,7 @@ struct t_operand *op;
|
|||
|
||||
|
||||
char *ind( buf, str)
|
||||
char *buf, *str;
|
||||
register char *buf, *str;
|
||||
|
||||
/* Reads the index in front of '(register)'.
|
||||
*/
|
||||
|
@ -129,7 +129,7 @@ char *buf, *str;
|
|||
|
||||
|
||||
char *lab( buf, str)
|
||||
char *buf, *str;
|
||||
register char *buf, *str;
|
||||
|
||||
/* Reads 'label' in front of '+offset'.
|
||||
*/
|
||||
|
@ -146,8 +146,8 @@ char *buf, *str;
|
|||
|
||||
|
||||
int is_reg( str, num)
|
||||
char *str;
|
||||
int *num;
|
||||
register char *str;
|
||||
register int *num;
|
||||
|
||||
/* Is "str" a 'registers' ?
|
||||
*/
|
||||
|
@ -181,7 +181,7 @@ int *num;
|
|||
|
||||
|
||||
char *end_arg( str)
|
||||
char *str;
|
||||
register char *str;
|
||||
|
||||
/* Shift to the last character of "str".
|
||||
*/
|
||||
|
@ -193,7 +193,8 @@ char *str;
|
|||
|
||||
|
||||
char *match( str, sym)
|
||||
char *str, sym;
|
||||
register char *str;
|
||||
char sym;
|
||||
{
|
||||
while ( *str != sym)
|
||||
str++;
|
||||
|
@ -206,14 +207,27 @@ char *str, sym;
|
|||
char my_buf[256];
|
||||
|
||||
gen_operand( op)
|
||||
struct t_operand *op;
|
||||
register struct t_operand *op;
|
||||
|
||||
/* Generate object-code for a argument.
|
||||
*/
|
||||
{
|
||||
switch( op->type) {
|
||||
case CONST : @text1( 0x8f);
|
||||
@text4( %$(op->const));
|
||||
case CONST :
|
||||
if (isdigit(op->const[0])) {
|
||||
long l, atol();
|
||||
l = atol(op->const);
|
||||
if (fit_6bits(l)) {
|
||||
@text1(%$(op->const));
|
||||
}
|
||||
else {
|
||||
@text1( 0x8f);
|
||||
@text4( %$(op->const));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@as_const(%$(op->const));
|
||||
}
|
||||
break;
|
||||
case REGISTER: @text1( %d(0x50 | op->num));
|
||||
break;
|
||||
|
@ -223,8 +237,24 @@ struct t_operand *op;
|
|||
break;
|
||||
case AUTO_INC : @text1( %d(0x80 | op->num));
|
||||
break;
|
||||
case IND_REG : @text1( %d(0xe0 | op->num));
|
||||
@text4( %$(op->index));
|
||||
case IND_REG :
|
||||
if (isdigit(op->index[0])) {
|
||||
long l, atol();
|
||||
l = atol(op->index);
|
||||
if (fit_byte(l)) {
|
||||
@text1( %d(0xa0 | op->num));
|
||||
@text1( %$(op->index));
|
||||
} else if (fit_word(l)) {
|
||||
@text1( %d(0xc0 | op->num));
|
||||
@text2( %$(op->index));
|
||||
} else {
|
||||
@text1( %d(0xe0 | op->num));
|
||||
@text4( %$(op->index));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@as_indexed(%$(op->index) , %d(op->num));
|
||||
}
|
||||
break;
|
||||
case LABEL : @text1( 0xef);
|
||||
if ( strindex( op->lab, DOLLAR)) {
|
||||
|
|
|
@ -23,3 +23,7 @@ struct t_operand {
|
|||
int type, num;
|
||||
char *lab, *index, *const, *offset;
|
||||
};
|
||||
|
||||
#define fit_6bits(val) ((unsigned long)(val) < 64)
|
||||
#define fit_byte(val) ((unsigned long)((val)+128) < 256)
|
||||
#define fit_word(val) ((unsigned long)((val)+32768L) < 65536L)
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
addd2 src, dst ==>
|
||||
@text1( 0x60);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
addf2 src, dst ==>
|
||||
@text1( 0x40);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
addl2 src, dst ==>
|
||||
@text1( 0xc0);
|
||||
gen_operand( src);
|
||||
|
@ -110,6 +120,16 @@ clrq src ==>
|
|||
@text1( 0x7c);
|
||||
gen_operand( src).
|
||||
|
||||
cmpf src, dest ==>
|
||||
@text1( 0x51);
|
||||
gen_operand( src);
|
||||
gen_operand( dest).
|
||||
|
||||
cmpd src, dest ==>
|
||||
@text1( 0x71);
|
||||
gen_operand( src);
|
||||
gen_operand( dest).
|
||||
|
||||
cmpl src, dest ==>
|
||||
@text1( 0xd1);
|
||||
gen_operand( src);
|
||||
|
@ -124,6 +144,16 @@ decl src ==>
|
|||
@text1( 0xd7);
|
||||
gen_operand( src).
|
||||
|
||||
divf2 src, dst ==>
|
||||
@text1( 0x46);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
divd2 src, dst ==>
|
||||
@text1( 0x66);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
divl2 src, dst ==>
|
||||
@text1( 0xc6);
|
||||
gen_operand( src);
|
||||
|
@ -152,6 +182,16 @@ mcoml src, dst ==>
|
|||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
mnegf src, dst ==>
|
||||
@text1( 0x52);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
mnegd src, dst ==>
|
||||
@text1( 0x72);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
mnegl src, dst ==>
|
||||
@text1( 0xce);
|
||||
gen_operand( src);
|
||||
|
@ -189,6 +229,16 @@ movq src : const, dst ==>
|
|||
gen_operand( dst).
|
||||
|
||||
|
||||
mulf2 src, dst ==>
|
||||
@text1( 0x44);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
muld2 src, dst ==>
|
||||
@text1( 0x64);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
mull2 src, dst ==>
|
||||
@text1( 0xc4);
|
||||
gen_operand( src);
|
||||
|
@ -216,6 +266,16 @@ sobgtr tel, ilb ==>
|
|||
gen_operand( tel);
|
||||
gen_operand( ilb).
|
||||
|
||||
subf2 src, dst ==>
|
||||
@text1( 0x42);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
subd2 src, dst ==>
|
||||
@text1( 0x62);
|
||||
gen_operand( src);
|
||||
gen_operand( dst).
|
||||
|
||||
subl2 src, dst ==>
|
||||
@text1( 0xc2);
|
||||
gen_operand( src);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
extern File *out_file;
|
||||
|
||||
do_close()
|
||||
close_back()
|
||||
{
|
||||
sys_close( out_file);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
File *out_file;
|
||||
|
||||
do_open( filename)
|
||||
open_back( filename)
|
||||
char *filename;
|
||||
{
|
||||
if ( filename == (char *) '\0')
|
||||
|
|
|
@ -4,16 +4,18 @@
|
|||
#include "back.h"
|
||||
#include "header.h"
|
||||
|
||||
static do_algn();
|
||||
|
||||
end_back()
|
||||
{
|
||||
sync();
|
||||
do_algn();
|
||||
do_local_relocation();
|
||||
output();
|
||||
}
|
||||
|
||||
|
||||
sync()
|
||||
static
|
||||
do_algn()
|
||||
{
|
||||
while ( ( text - text_area) % EM_WSIZE != 0 )
|
||||
text1( '\0');
|
||||
|
|
|
@ -10,3 +10,171 @@ int arg;
|
|||
{
|
||||
fprint( STDERR, "arg_error %s %d\n", s, arg);
|
||||
}
|
||||
|
||||
#define OWNFLOAT /* compile on VAX, generate code for VAX FP ... */
|
||||
|
||||
con_float(str, argval)
|
||||
char *str;
|
||||
int argval;
|
||||
{
|
||||
#ifdef NOFLOAT
|
||||
|
||||
static int been_here;
|
||||
if (argval != 4 && argval != 8)
|
||||
arg_error("fcon", argval);
|
||||
if (argval == 8)
|
||||
gen4((FOUR_BYTES) 0);
|
||||
gen4((FOUR_BYTES) 0);
|
||||
if ( !been_here++)
|
||||
{
|
||||
fputs("Warning : dummy float-constant(s)\n", stderr);
|
||||
}
|
||||
#else
|
||||
double f;
|
||||
double atof();
|
||||
int i;
|
||||
int j;
|
||||
double frexp();
|
||||
#ifndef OWNFLOAT
|
||||
int sign = 0;
|
||||
int fraction[4] ;
|
||||
#else OWNFLOAT
|
||||
float fl;
|
||||
char *p;
|
||||
#endif OWNFLOAT
|
||||
|
||||
if (argval!= 4 && argval!= 8) {
|
||||
arg_error("fcon", argval);
|
||||
argval = 8;
|
||||
}
|
||||
f = atof(str);
|
||||
if (f == 0) {
|
||||
if (argval == 8) gen4((FOUR_BYTES) 0);
|
||||
gen4((FOUR_BYTES) 0);
|
||||
return;
|
||||
}
|
||||
#ifdef OWNFLOAT
|
||||
if (argval == 4) {
|
||||
/* careful: avoid overflow */
|
||||
fl = frexp(f, &i);
|
||||
fl = frexp(fl,&j);
|
||||
if (i+j > 127) {
|
||||
/* overflow situation */
|
||||
gen1(0377);
|
||||
gen1(f<0?0377:0177);
|
||||
gen1(0377);
|
||||
gen1(0377);
|
||||
return;
|
||||
}
|
||||
if (i+j < -127) {
|
||||
/* underflow situation */
|
||||
gen1(0200);
|
||||
gen1(f<0?0200:0);
|
||||
gen1(0);
|
||||
gen1(0);
|
||||
return;
|
||||
}
|
||||
fl = f;
|
||||
p = (char *) &fl;
|
||||
}
|
||||
else {
|
||||
p = (char *) &f;
|
||||
}
|
||||
gen1(*p++&0377);
|
||||
for (i = argval-1; i; i--) {
|
||||
gen1(*p++&0377);
|
||||
}
|
||||
#else OWNFLOAT
|
||||
f = frexp(f, &i);
|
||||
if (f < 0) {
|
||||
f = -f;
|
||||
sign = 1;
|
||||
}
|
||||
while (f < 0.5) {
|
||||
f += f;
|
||||
i --;
|
||||
}
|
||||
f = 2*f - 1.0; /* hidden bit */
|
||||
i--; /* exponent is one lower for SUN floating point! */
|
||||
#ifdef IEEEFLOAT
|
||||
if (argval == 4) {
|
||||
#endif IEEEFLOAT
|
||||
i = (i + 128) & 0377;
|
||||
fraction[0] = (sign << 15) | (i << 7);
|
||||
for (j = 6; j>= 0; j--) {
|
||||
f *= 2;
|
||||
if (f >= 1.0) {
|
||||
f -= 1.0;
|
||||
fraction[0] |= (1 << j);
|
||||
}
|
||||
}
|
||||
#ifdef IEEEFLOAT
|
||||
}
|
||||
else {
|
||||
i = (i + 1024) & 03777;
|
||||
fraction[0] = (sign << 15) | (i << 4);
|
||||
for (j = 3; j>= 0; j--) {
|
||||
f *= 2;
|
||||
if (f >= 1.0) {
|
||||
fraction[0] |= (1 << j);
|
||||
f -= 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif IEEEFLOAT
|
||||
for (i = 1; i < argval / 2; i++) {
|
||||
fraction[i] = 0;
|
||||
for (j = 15; j>= 0; j--) {
|
||||
f *= 2;
|
||||
if (f >= 1.0) {
|
||||
fraction[i] |= (1 << j);
|
||||
f -= 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f >= 0.5) {
|
||||
for (i = argval/2 - 1; i >= 0; i--) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (fraction[i] & (1 << j)) {
|
||||
fraction[i] &= ~(1 << j);
|
||||
}
|
||||
else {
|
||||
fraction[i] |= (1 << j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j != 16) break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < argval/2; i++) {
|
||||
gen1(fraction[i]&0377);
|
||||
gen1((fraction[i]>>8)&0377);
|
||||
}
|
||||
#endif OWNFLOAT
|
||||
#endif
|
||||
}
|
||||
|
||||
as_indexed(val, num)
|
||||
{
|
||||
if (fit_byte(val)) {
|
||||
text1( 0xa0 | num);
|
||||
text1( val);
|
||||
} else if (fit_word(val)) {
|
||||
text1( 0xc0 | num);
|
||||
text2( val);
|
||||
} else {
|
||||
text1( 0xe0 | num);
|
||||
text4( val);
|
||||
}
|
||||
}
|
||||
|
||||
as_const(val)
|
||||
{
|
||||
if (fit_6bits(val)) {
|
||||
text1(val);
|
||||
}
|
||||
else {
|
||||
text1(0x8f);
|
||||
text4(val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#define ONE_BYTE char
|
||||
#define TWO_BYTES short
|
||||
#define ONE_BYTE int
|
||||
#define TWO_BYTES int
|
||||
#define FOUR_BYTES long
|
||||
|
||||
#define EM_WSIZE 4
|
||||
|
@ -10,10 +10,11 @@
|
|||
|
||||
#define NAME_FMT "_%s"
|
||||
#define DNAM_FMT "_%s"
|
||||
#define DLB_FMT "_%ld"
|
||||
#define DLB_FMT "I_%ld"
|
||||
#define ILB_FMT "I%03d%ld"
|
||||
#define HOL_FMT "hol%d"
|
||||
|
||||
#define GENLAB 'I' /* compiler generated labels start with I */
|
||||
|
||||
#define ALIGN_FMT ""
|
||||
|
||||
|
@ -33,4 +34,8 @@
|
|||
#define RELOC1_FMT ".byte %s + %ld\n"
|
||||
#define RELOC2_FMT ".word %s + %ld\n"
|
||||
#define RELOC4_FMT ".long %s + %ld\n"
|
||||
|
||||
#define fit_6bits(val) ((unsigned long)(val) < 64)
|
||||
#define fit_byte(val) ((unsigned long)((val)+128) < 256)
|
||||
#define fit_word(val) ((unsigned long)((val)+32768L) < 65536L)
|
||||
|
||||
|
|
|
@ -5,50 +5,79 @@
|
|||
#include "back.h"
|
||||
#include "data.h"
|
||||
|
||||
/* Unportable code. Written for VAX, meant to be run on a VAX.
|
||||
*/
|
||||
#ifndef vax
|
||||
Read above comment ...
|
||||
#endif
|
||||
|
||||
extern File *out_file;
|
||||
|
||||
/* This program converts an ACK a.out format to A BSD4.1 a.out.
|
||||
* It is written for the a.out's generated by a code expander. So be
|
||||
* carefull it is not very powerfull.
|
||||
*/
|
||||
|
||||
|
||||
#include <a.out.h>
|
||||
#include <alloc.h>
|
||||
|
||||
struct exec u_header;
|
||||
struct relocation_info u_reloc;
|
||||
struct nlist u_name;
|
||||
static struct exec u_header;
|
||||
|
||||
long ntext, ndata, nrelo, nchar, base_address();
|
||||
int trsize=0, drsize=0;
|
||||
static int trsize=0, drsize=0;
|
||||
|
||||
static struct relocation_info *u_reloc;
|
||||
|
||||
static reduce_name_table();
|
||||
|
||||
output()
|
||||
{
|
||||
register int i;
|
||||
register struct nlist *u_name;
|
||||
|
||||
/*
|
||||
* Convert relocation data structures. This also requires
|
||||
* some re-ordering, as SUN .o format needs has text relocation
|
||||
* structures in front of the data relocation structures, whereas in
|
||||
* ACK they can be in any order.
|
||||
*/
|
||||
|
||||
nrelo = relo - reloc_info;
|
||||
u_reloc = (struct relocation_info *)
|
||||
Malloc((unsigned)nrelo*sizeof(struct relocation_info));
|
||||
|
||||
for (i = 0; i < nrelo; i++) {
|
||||
if ( ( reloc_info[i].or_sect-S_MIN) == SEGTXT &&
|
||||
convert_reloc( &reloc_info[i], u_reloc)) {
|
||||
trsize++;
|
||||
u_reloc++;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nrelo; i++) {
|
||||
if ( ( reloc_info[i].or_sect-S_MIN) != SEGTXT &&
|
||||
convert_reloc( &reloc_info[i], u_reloc)) {
|
||||
u_reloc++;
|
||||
drsize++;
|
||||
}
|
||||
}
|
||||
|
||||
nrelo = trsize + drsize;
|
||||
u_reloc -= nrelo;
|
||||
|
||||
reduce_name_table();
|
||||
|
||||
init_unixheader();
|
||||
|
||||
putbuf( (char *) &u_header, 32);
|
||||
putbuf( (char *) &u_header, sizeof(struct exec));
|
||||
putbuf( (char *) text_area, ntext);
|
||||
putbuf( (char *) data_area, ndata);
|
||||
putbuf((char *) u_reloc, sizeof(struct relocation_info)*nrelo);
|
||||
free(u_reloc);
|
||||
|
||||
for (i = 0; i < nrelo; i++) {
|
||||
if ( ( reloc_info[i].or_sect-S_MIN) == SEGTXT) {
|
||||
convert_reloc( &reloc_info[i], &u_reloc);
|
||||
putbuf((char *) &u_reloc, 8);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < nrelo; i++) {
|
||||
if (( reloc_info[i].or_sect-S_MIN) != SEGTXT) {
|
||||
convert_reloc( &reloc_info[i], &u_reloc);
|
||||
putbuf((char *) &u_reloc, 8);
|
||||
}
|
||||
}
|
||||
u_name = (struct nlist *)
|
||||
Malloc((unsigned)nname * sizeof(struct nlist));
|
||||
|
||||
for (i = 0; i < nname ; i++) { /* The segment names can be omitted */
|
||||
convert_name( &symbol_table[i], &u_name);
|
||||
putbuf((char *) &u_name, 12);
|
||||
convert_name( &symbol_table[i], u_name++);
|
||||
}
|
||||
u_name -= nname;
|
||||
putbuf((char *) u_name, sizeof(struct nlist)*nname);
|
||||
free(u_name);
|
||||
|
||||
/* print( "size string_area %d\n", nchar); */
|
||||
|
||||
|
@ -56,30 +85,84 @@ output()
|
|||
putbuf((char *) string_area, nchar);
|
||||
}
|
||||
|
||||
static
|
||||
reduce_name_table()
|
||||
{
|
||||
/*
|
||||
* Reduce the name table size. This is done by first marking
|
||||
* the name-table entries that are needed for relocation, then
|
||||
* removing the entries that are compiler-generated and not
|
||||
* needed for relocation, while remembering how many entries were
|
||||
* removed at each point, and then updating the relocation info.
|
||||
* After that, the string table is reduced.
|
||||
*/
|
||||
|
||||
#define S_NEEDED 0x8000
|
||||
#define removable(nm) (!(nm.on_type & S_NEEDED) && *(nm.on_foff+string_area) == GENLAB)
|
||||
|
||||
register int *diff_index =
|
||||
(int *) Malloc((unsigned)(nname + 1) * sizeof(int));
|
||||
register int i;
|
||||
char *new_str;
|
||||
register char *p, *q;
|
||||
|
||||
*diff_index++ = 0;
|
||||
for (i = 0; i < nrelo; i++) {
|
||||
if (u_reloc[i].r_extern) {
|
||||
symbol_table[u_reloc[i].r_symbolnum].on_type |= S_NEEDED;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nname; i++) {
|
||||
int old_diff_index = diff_index[i-1];
|
||||
|
||||
if (removable(symbol_table[i])) {
|
||||
diff_index[i] = old_diff_index + 1;
|
||||
}
|
||||
else {
|
||||
diff_index[i] = old_diff_index;
|
||||
if (old_diff_index) {
|
||||
symbol_table[i - old_diff_index] = symbol_table[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
nname -= diff_index[nname - 1];
|
||||
|
||||
for (i = 0; i < nrelo; i++) {
|
||||
register struct relocation_info *rp = &u_reloc[i];
|
||||
|
||||
if (rp->r_extern) {
|
||||
rp->r_symbolnum -= diff_index[rp->r_symbolnum];
|
||||
}
|
||||
}
|
||||
|
||||
free((char *)(diff_index-1));
|
||||
|
||||
new_str = q = Malloc((unsigned)(string - string_area));
|
||||
for (i = 0; i < nname; i++) {
|
||||
p = symbol_table[i].on_foff + string_area;
|
||||
symbol_table[i].on_foff = q - new_str;
|
||||
while (*q++ = *p) p++;
|
||||
}
|
||||
free(string_area);
|
||||
string_area = new_str;
|
||||
string = q;
|
||||
}
|
||||
|
||||
init_unixheader()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for ( i = 0; i < (relo - reloc_info); i++)
|
||||
if ( ( reloc_info[ i].or_sect - S_MIN) == SEGTXT)
|
||||
trsize++;
|
||||
else
|
||||
drsize++;
|
||||
|
||||
ntext = text - text_area;
|
||||
ndata = data - data_area;
|
||||
nchar = string - string_area;
|
||||
nrelo = relo - reloc_info;
|
||||
|
||||
u_header.a_magic = OMAGIC;
|
||||
u_header.a_text = ntext;
|
||||
u_header.a_data = ndata;
|
||||
u_header.a_bss = nbss;
|
||||
u_header.a_syms = nname * 12;
|
||||
u_header.a_syms = nname * sizeof(struct nlist);
|
||||
u_header.a_entry = 0;
|
||||
u_header.a_trsize = trsize * 8;
|
||||
u_header.a_drsize = drsize * 8;
|
||||
u_header.a_trsize = trsize * sizeof(struct relocation_info);
|
||||
u_header.a_drsize = drsize * sizeof(struct relocation_info);
|
||||
/* print( "header %o %d %d %d %d %d %d %d\n",
|
||||
u_header.a_magic, u_header.a_text, u_header.a_data,
|
||||
u_header.a_bss, u_header.a_syms, u_header.a_entry,
|
||||
|
@ -91,17 +174,23 @@ convert_reloc( a_relo, u_relo)
|
|||
struct outrelo *a_relo;
|
||||
struct relocation_info *u_relo;
|
||||
{
|
||||
int retval = 1;
|
||||
|
||||
u_relo->r_address = a_relo->or_addr;
|
||||
u_relo->r_symbolnum = a_relo->or_nami;
|
||||
u_relo->r_pcrel = (a_relo->or_type & RELPC) >> 3;
|
||||
u_relo->r_length = convert_length( (a_relo->or_type) & RELSZ);
|
||||
if ( symbol_table[ a_relo->or_nami].on_valu == -1)
|
||||
u_relo->r_length = 2;
|
||||
if ( symbol_table[ a_relo->or_nami].on_valu == -1 ||
|
||||
(symbol_table[ a_relo->or_nami].on_type & S_COM))
|
||||
u_relo->r_extern = 1;
|
||||
else
|
||||
u_relo->r_extern = 0;
|
||||
if ( symbol_table[ a_relo->or_nami].on_valu != -1) {
|
||||
if ( u_relo->r_extern == 0) {
|
||||
switch ( (symbol_table[ a_relo->or_nami].on_type & S_TYP) - S_MIN) {
|
||||
case SEGTXT : u_relo->r_symbolnum = N_TEXT;
|
||||
if (u_relo->r_pcrel &&
|
||||
(a_relo->or_sect-S_MIN == SEGTXT))
|
||||
retval = 0;
|
||||
break;
|
||||
case SEGCON : u_relo->r_symbolnum = N_DATA;
|
||||
break;
|
||||
|
@ -112,27 +201,12 @@ struct relocation_info *u_relo;
|
|||
(symbol_table[ a_relo->or_nami].on_type & S_TYP) - S_MIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int convert_length( length)
|
||||
int length;
|
||||
{
|
||||
if ( length & RELO1)
|
||||
return( 0);
|
||||
else if ( length & RELO2)
|
||||
return( 1);
|
||||
else if ( length & RELO4)
|
||||
return( 2);
|
||||
else
|
||||
fprint( STDERR, "convert_length(): size is impossible %d\n",
|
||||
length);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define n_mptr n_un.n_name
|
||||
#define n_str n_un.n_strx
|
||||
|
||||
|
||||
convert_name( a_name, u_name)
|
||||
struct outname *a_name;
|
||||
struct nlist *u_name;
|
||||
|
@ -143,7 +217,9 @@ struct nlist *u_name;
|
|||
fill_type( &(u_name->n_type), &(a_name->on_type), a_name->on_valu);
|
||||
u_name->n_other = '\0';
|
||||
u_name->n_desc = 0;
|
||||
if ( a_name->on_valu != -1)
|
||||
if (a_name->on_type & S_COM)
|
||||
u_name->n_value = a_name->on_valu;
|
||||
else if ( a_name->on_valu != -1)
|
||||
u_name->n_value = a_name->on_valu +
|
||||
base_address( ( a_name->on_type & S_TYP) - S_MIN);
|
||||
else
|
||||
|
@ -158,10 +234,9 @@ long valu;
|
|||
{
|
||||
int sect;
|
||||
|
||||
*u_type = '\0';
|
||||
*u_type |= ( *a_type & S_EXT) ? N_EXT : N_UNDF;
|
||||
*u_type = ((*a_type&S_TYP) == S_UND || (*a_type & S_EXT)) ? N_EXT : 0;
|
||||
|
||||
if ( valu != -1) {
|
||||
if ( valu != -1 && (! (*a_type & S_COM))) {
|
||||
sect = ( *a_type & S_TYP ) - S_MIN;
|
||||
switch ( sect) {
|
||||
case SEGTXT: *u_type |= N_TEXT;
|
||||
|
@ -193,9 +268,9 @@ int seg;
|
|||
}
|
||||
|
||||
put_stringtablesize( n)
|
||||
int n;
|
||||
long n;
|
||||
{
|
||||
putbuf( (char *)&n, 4);
|
||||
putbuf( (char *)&n, 4L);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,74 +3,53 @@
|
|||
#include "data.h"
|
||||
#include "back.h"
|
||||
|
||||
#define seg_index( s) ( nname - SEGBSS - 1 + s)
|
||||
|
||||
long get4();
|
||||
long base_adres();
|
||||
extern long base_address();
|
||||
/*
|
||||
extern short get2();
|
||||
extern char get1();
|
||||
|
||||
*/
|
||||
|
||||
do_local_relocation()
|
||||
{
|
||||
register struct outrelo *ptr;
|
||||
register int s;
|
||||
register struct outrelo *rp;
|
||||
|
||||
/* print( "n relocation records %d\n", relo - reloc_info); */
|
||||
|
||||
for ( ptr = reloc_info; ptr < relo; ptr++) {
|
||||
s = ptr->or_nami;
|
||||
if ( symbol_table[ s].on_valu != -1)
|
||||
do_relo(&symbol_table[ s], ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
do_relo(np,rp)
|
||||
struct outname *np;
|
||||
struct outrelo *rp;
|
||||
{
|
||||
long oldval,newval;
|
||||
char *sect;
|
||||
|
||||
switch( rp->or_sect - S_MIN) {
|
||||
case SEGTXT:
|
||||
sect = text_area;
|
||||
break;
|
||||
case SEGCON:
|
||||
sect = data_area;
|
||||
break;
|
||||
default:
|
||||
fprint( STDERR,
|
||||
"do_local_relo(): bad section %d\n",
|
||||
rp->or_sect - S_MIN);
|
||||
break;
|
||||
}
|
||||
oldval = get4( sect, rp->or_addr);
|
||||
newval = oldval + np->on_valu +
|
||||
base_address( (np->on_type & S_TYP) -S_MIN);
|
||||
if ( rp->or_type & RELO4)
|
||||
put4( sect, rp->or_addr, newval);
|
||||
else if ( rp->or_type & RELO2)
|
||||
put2( sect, rp->or_addr, (int) newval);
|
||||
else if ( rp->or_type & RELO1)
|
||||
put1( sect, rp->or_addr, (char) newval);
|
||||
else
|
||||
print( STDERR, "do_relo() : bad relocation size\n");
|
||||
/* print( "reloc %s adrr=%ld sect=%ld oldval=%ld newval=%ld def = %ld\n",
|
||||
np->on_foff + string_area, rp->or_addr, rp->or_sect-S_MIN, oldval, newval,
|
||||
np->on_valu);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
long base_adres( seg)
|
||||
int seg;
|
||||
{
|
||||
switch ( seg) {
|
||||
case SEGTXT : return( 0);
|
||||
case SEGCON : return( text-text_area);
|
||||
case SEGBSS : return( text-text_area + data-data_area);
|
||||
default : fprint( STDERR, "base_adres() wrong seg %d\n", seg);
|
||||
for ( rp = reloc_info; rp < relo; rp++) {
|
||||
register struct outname *np = &symbol_table[rp->or_nami];
|
||||
|
||||
if ( np->on_valu != -1 && ! (np->on_type & S_COM)) {
|
||||
register long oldval,newval;
|
||||
register char *sect;
|
||||
|
||||
switch( rp->or_sect - S_MIN) {
|
||||
case SEGTXT:
|
||||
sect = text_area;
|
||||
break;
|
||||
case SEGCON:
|
||||
sect = data_area;
|
||||
break;
|
||||
default:
|
||||
fprint( STDERR,
|
||||
"do_local_relo(): bad section %d\n",
|
||||
rp->or_sect - S_MIN);
|
||||
break;
|
||||
}
|
||||
oldval = get4( sect, rp->or_addr);
|
||||
newval = oldval + np->on_valu +
|
||||
base_address( (np->on_type & S_TYP) -S_MIN);
|
||||
if ( rp->or_type & RELO4)
|
||||
put4( sect, rp->or_addr, newval);
|
||||
/*
|
||||
else if ( rp->or_type & RELO2)
|
||||
put2( sect, rp->or_addr, (int) newval);
|
||||
else if ( rp->or_type & RELO1)
|
||||
put1( sect, rp->or_addr, (char) newval);
|
||||
*/
|
||||
else
|
||||
print( STDERR,
|
||||
"do_relo() : bad relocation size\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue