Many changes:
authorceriel <none@none>
Thu, 20 Oct 1988 14:21:37 +0000 (14:21 +0000)
committerceriel <none@none>
Thu, 20 Oct 1988 14:21:37 +0000 (14:21 +0000)
- added floating point
- improved assembler part, now uses short encodings when possible
- reduced generated relocation - and name table

12 files changed:
mach/vax4/ce/EM_table
mach/vax4/ce/Make.back
mach/vax4/ce/as.c
mach/vax4/ce/as.h
mach/vax4/ce/as_table
mach/vax4/ce/do_close.c
mach/vax4/ce/do_open.c
mach/vax4/ce/end_back.c
mach/vax4/ce/mach.c
mach/vax4/ce/mach.h
mach/vax4/ce/output.c
mach/vax4/ce/relocation.c

index fce731c..8a59faa 100644 (file)
@@ -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).
 
 /*****************************************************************************/
 
index 8ec23d6..cecf394 100644 (file)
@@ -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
index 89a3a93..3a97c6b 100644 (file)
@@ -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)) {
index b50763e..841c708 100644 (file)
@@ -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)
index 6602679..de0ebc1 100644 (file)
@@ -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);
index 5bb0fbd..a9f3721 100644 (file)
@@ -2,7 +2,7 @@
 
 extern File *out_file;
 
-do_close()
+close_back()
 {
        sys_close( out_file);
 }
index 83f529a..337fc62 100644 (file)
@@ -2,7 +2,7 @@
 
 File *out_file;
 
-do_open( filename)
+open_back( filename)
 char *filename;
 {
        if ( filename == (char *) '\0')
index 60d42a1..f776e41 100644 (file)
@@ -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');
index 5598352..11c878f 100644 (file)
@@ -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);
+       }
+}
index f19995e..eff4e29 100644 (file)
@@ -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
 
 #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)
  
index 34f98ee..f344d1e 100644 (file)
@@ -5,50 +5,79 @@
 #include "back.h"
 #include "data.h"
 
-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.
- */
+/*     Unportable code. Written for VAX, meant to be run on a VAX.
+*/
+#ifndef vax
+Read above comment ...
+#endif
 
+extern File *out_file;
 
 #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;
 
-       init_unixheader();
+       /*
+        * 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));
 
-       putbuf( (char *) &u_header, 32);
-       putbuf( (char *) text_area,  ntext);
-       putbuf( (char *) data_area, ndata);
-       
        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);
+               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);
-                       putbuf((char *) &u_reloc, 8);
+               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, 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);
+       
+       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);
 }
 
-
-init_unixheader()
+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;
 
-       for ( i = 0; i < (relo - reloc_info); i++) 
-               if ( ( reloc_info[ i].or_sect - S_MIN) == SEGTXT)
-                       trsize++;
-               else
-                       drsize++;
+       *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()
+{
        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);
 }
 
 
index ab4b44f..e4a92c5 100644 (file)
@@ -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");
+               }
        }
 }