Polishing m68k support.
authorK. Richard Pixley <rich@cygnus>
Sat, 27 Jul 1991 02:34:20 +0000 (02:34 +0000)
committerK. Richard Pixley <rich@cygnus>
Sat, 27 Jul 1991 02:34:20 +0000 (02:34 +0000)
gas/config/ho-sun3.h
gas/config/obj-aout.h
gas/config/tc-a29k.c
gas/config/tc-m68k.c
gas/write.c

index 33b74c37d749d41b3d19b2fd7629ae65afde2852..41d2f96825d97aa7d383c69a80c31fb224bda38b 100644 (file)
@@ -2,6 +2,4 @@
 
 #include <ho-sunos.h>
 
-extern int sprintf();
-
 /* end of ho-sun3.h */
index d2152db51a938ace8dbc1ce5c2049b2dc69397bf..44e2c3a5346f9622765e7767f5bb6d19e044b9c1 100644 (file)
@@ -5,7 +5,7 @@ This file is part of GAS, the GNU Assembler.
 
 GAS is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 1,
+published by the Free Software Foundation; either version 2,
 or (at your option) any later version.
 
 GAS is distributed in the hope that it will be useful, but
@@ -133,13 +133,15 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */
 
 /* File header macro and type definition */
 
-#define H_GET_FILE_SIZE(h)     (sizeof(struct exec) + \
-                                H_GET_TEXT_SIZE(h) + H_GET_DATA_SIZE(h) + \
-                                H_GET_SYMBOL_TABLE_SIZE(h) + \
-                                H_GET_TEXT_RELOCATION_SIZE(h) + \
-                                H_GET_DATA_RELOCATION_SIZE(h) + \
-                                (h)->string_table_size)
+#define H_GET_FILE_SIZE(h)     (H_GET_HEADER_SIZE(h) \
+                                + H_GET_TEXT_SIZE(h) \
+                                + H_GET_DATA_SIZE(h) \
+                                + H_GET_SYMBOL_TABLE_SIZE(h) \
+                                + H_GET_TEXT_RELOCATION_SIZE(h) \
+                                + H_GET_DATA_RELOCATION_SIZE(h) \
+                                + H_GET_STRING_SIZE(h))
 
+#define H_GET_HEADER_SIZE(h)           (sizeof(struct exec))
 #define H_GET_TEXT_SIZE(h)             ((h)->header.a_text)
 #define H_GET_DATA_SIZE(h)             ((h)->header.a_data)
 #define H_GET_BSS_SIZE(h)              ((h)->header.a_bss)
@@ -149,9 +151,12 @@ typedef struct nlist obj_symbol_type; /* Symbol table entry */
 #define H_GET_MAGIC_NUMBER(h)          ((h)->header.a_info)
 #define H_GET_ENTRY_POINT(h)           ((h)->header.a_entry)
 #define H_GET_STRING_SIZE(h)           ((h)->string_table_size)
+#define H_GET_LINENO_SIZE(h)           (0)
+
 #ifdef EXEC_MACHINE_TYPE
 #define H_GET_MACHINE_TYPE(h)          ((h)->header.a_machtype)
 #endif /* EXEC_MACHINE_TYPE */
+
 #ifdef EXEC_VERSION
 #define H_GET_VERSION(h)               ((h)->header.a_version)
 #endif /* EXEC_VERSION */
index cee99f922e27abdc3503966946336a90c09a6bd8..fecdc5d2e9da8a1dbd85fcd110eb150664ffebd9 100644 (file)
@@ -927,7 +927,8 @@ md_ri_to_chars(the_bytes, ri)
 }
 
 /* should never be called for 29k */
-void md_convert_frag(fragP)
+void md_convert_frag(headers, fragP)
+object_headers *headers;
     register fragS *fragP;
 {
     fprintf(stderr, "sparc_convert_frag\n");
index c2ba22831c697068d5557310e96b1a445f968a42..ea60b6935bba0672b230df8264ecfc7572ff59e5 100644 (file)
@@ -6,7 +6,7 @@ This file is part of GAS, the GNU Assembler.
 
 GAS is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GAS is distributed in the hope that it will be useful,
@@ -26,6 +26,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
  /* note that this file includes real declarations and thus can only be included by one source file per executable. */
 #include "m68k-opcode.h"
+#ifdef TE_SUN
+/* This variable contains the value to write out at the beginning of
+   the a.out file.  The 2<<16 means that this is a 68020 file instead
+   of an old-style 68000 file */
+
+long omagic = 2<<16|OMAGIC;    /* Magic byte for header file */
+#else
+long omagic = OMAGIC;
+#endif
 
 /* This array holds the chars that always start a comment.  If the
    pre-processor is disabled, these aren't very useful */
@@ -74,6 +83,76 @@ static struct obstack robyn;
 #define DBCC            5
 #define PCLEA          6
 
+/* Operands we can parse:  (And associated modes)
+
+numb:  8 bit num
+numw:  16 bit num
+numl:  32 bit num
+dreg:  data reg 0-7
+reg:   address or data register
+areg:  address register
+apc:   address register, PC, ZPC or empty string
+num:   16 or 32 bit num
+num2:  like num
+sz:    w or l          if omitted, l assumed
+scale: 1 2 4 or 8      if omitted, 1 assumed
+
+7.4 IMMED #num                         --> NUM
+0.? DREG  dreg                         --> dreg
+1.? AREG  areg                         --> areg
+2.? AINDR areg@                                --> *(areg)
+3.? AINC  areg@+                       --> *(areg++)
+4.? ADEC  areg@-                       --> *(--areg)
+5.? AOFF  apc@(numw)                   --> *(apc+numw) -- empty string and ZPC not allowed here
+6.? AINDX apc@(num,reg:sz:scale)       --> *(apc+num+reg*scale)
+6.? AINDX apc@(reg:sz:scale)           --> same, with num=0
+6.? APODX apc@(num)@(num2,reg:sz:scale)        --> *(*(apc+num)+num2+reg*scale)
+6.? APODX apc@(num)@(reg:sz:scale)     --> same, with num2=0
+6.? AMIND apc@(num)@(num2)             --> *(*(apc+num)+num2) (previous mode without an index reg)
+6.? APRDX apc@(num,reg:sz:scale)@(num2)        --> *(*(apc+num+reg*scale)+num2)
+6.? APRDX apc@(reg:sz:scale)@(num2)    --> same, with num=0
+7.0 ABSL  num:sz                       --> *(num)
+          num                          --> *(num) (sz L assumed)
+*** MSCR  otherreg                     --> Magic
+With -l option
+5.? AOFF  apc@(num)                    --> *(apc+num) -- empty string and ZPC not allowed here still
+
+examples:
+       #foo    #0x35   #12
+       d2
+       a4
+       a3@
+       a5@+
+       a6@-
+       a2@(12) pc@(14)
+       a1@(5,d2:w:1)   @(45,d6:l:4)
+       pc@(a2)         @(d4)
+       etc . . .
+
+
+#name@(numw)   -->turn into PC rel mode
+apc@(num8,reg:sz:scale)                --> *(apc+num8+reg*scale)
+
+*/
+
+enum operand_type {
+    IMMED = 1,
+    DREG,
+    AREG,
+    AINDR,
+    ADEC,
+    AINC,
+    AOFF,
+    AINDX,
+    APODX,
+    AMIND,
+    APRDX,
+    ABSL,
+    MSCR,
+    REGLST,
+};
+
+
 struct m68k_exp {
        char    *e_beg;
        char    *e_end;
@@ -84,7 +163,7 @@ struct m68k_exp {
 /* Internal form of an operand.  */
 struct m68k_op {
        char    *error;         /* Couldn't parse it */
-       int     mode;           /* What mode this instruction is in.  */
+       enum operand_type mode; /* What mode this instruction is in.  */
        unsigned long   reg;            /* Base register */
        struct m68k_exp *con1;
        int     ireg;           /* Index register */
@@ -313,73 +392,6 @@ const pseudo_typeS md_pseudo_table[] = {
 
 extern char *input_line_pointer;
 
-/* Operands we can parse:  (And associated modes)
-
-numb:  8 bit num
-numw:  16 bit num
-numl:  32 bit num
-dreg:  data reg 0-7
-reg:   address or data register
-areg:  address register
-apc:   address register, PC, ZPC or empty string
-num:   16 or 32 bit num
-num2:  like num
-sz:    w or l          if omitted, l assumed
-scale: 1 2 4 or 8      if omitted, 1 assumed
-
-7.4 IMMED #num                         --> NUM
-0.? DREG  dreg                         --> dreg
-1.? AREG  areg                         --> areg
-2.? AINDR areg@                                --> *(areg)
-3.? AINC  areg@+                       --> *(areg++)
-4.? ADEC  areg@-                       --> *(--areg)
-5.? AOFF  apc@(numw)                   --> *(apc+numw) -- empty string and ZPC not allowed here
-6.? AINDX apc@(num,reg:sz:scale)       --> *(apc+num+reg*scale)
-6.? AINDX apc@(reg:sz:scale)           --> same, with num=0
-6.? APODX apc@(num)@(num2,reg:sz:scale)        --> *(*(apc+num)+num2+reg*scale)
-6.? APODX apc@(num)@(reg:sz:scale)     --> same, with num2=0
-6.? AMIND apc@(num)@(num2)             --> *(*(apc+num)+num2) (previous mode without an index reg)
-6.? APRDX apc@(num,reg:sz:scale)@(num2)        --> *(*(apc+num+reg*scale)+num2)
-6.? APRDX apc@(reg:sz:scale)@(num2)    --> same, with num=0
-7.0 ABSL  num:sz                       --> *(num)
-          num                          --> *(num) (sz L assumed)
-*** MSCR  otherreg                     --> Magic
-With -l option
-5.? AOFF  apc@(num)                    --> *(apc+num) -- empty string and ZPC not allowed here still
-
-examples:
-       #foo    #0x35   #12
-       d2
-       a4
-       a3@
-       a5@+
-       a6@-
-       a2@(12) pc@(14)
-       a1@(5,d2:w:1)   @(45,d6:l:4)
-       pc@(a2)         @(d4)
-       etc . . .
-
-
-#name@(numw)   -->turn into PC rel mode
-apc@(num8,reg:sz:scale)                --> *(apc+num8+reg*scale)
-
-*/
-
-#define IMMED  1
-#define DREG   2
-#define AREG   3
-#define AINDR  4
-#define ADEC   5
-#define AINC   6
-#define AOFF   7
-#define AINDX  8
-#define APODX  9
-#define AMIND  10
-#define APRDX  11
-#define ABSL   12
-#define MSCR   13
-#define REGLST 14
-
 #define FAIL   0
 #define OK     1
 
@@ -677,6 +689,7 @@ register struct m68k_op *opP;
 {
        char    *strend;
        long    i;
+       char    *parse_index();
 
        if(*str==' ')
                str++;
@@ -705,7 +718,7 @@ register struct m68k_op *opP;
                        opP->mode=REGLST;
                        return get_regs(i,str,opP);
                }
-               if((stmp=strchr(str,'@')) != '\0') {
+               if ((stmp=strchr(str,'@')) != '\0') {
                        opP->con1=add_exp(str,stmp-1);
                        if(stmp==strend) {
                                opP->mode=AINDX;
@@ -1018,6 +1031,7 @@ char      *instring;
        char    c;
        int     losing;
        int     opsfound;
+       char    *crack_operand();
        LITTLENUM_TYPE words[6];
        LITTLENUM_TYPE *wordp;
 
@@ -1033,7 +1047,7 @@ char      *instring;
 
        if (p == instring) {
                the_ins.error = "No operator";
-               the_ins.opcode[0] = (short) NULL;
+               the_ins.opcode[0] = NULL;
                /* the_ins.numo=1; */
                return;
        }
@@ -1048,7 +1062,7 @@ char      *instring;
 
        if (opcode == NULL) {
                the_ins.error = "Unknown operator";
-               the_ins.opcode[0] = (short) NULL;
+               the_ins.opcode[0] = NULL;
                /* the_ins.numo=1; */
                return;
        }
@@ -1385,7 +1399,7 @@ char      *instring;
                        switch(opP->mode) {
                        case IMMED:
                                tmpreg=0x3c;    /* 7.4 */
-                               if(strchr("bwl",s[1])) nextword=get_num(opP->con1,80);
+                               if (strchr("bwl",s[1])) nextword=get_num(opP->con1,80);
                                else nextword=nextword=get_num(opP->con1,0);
                                if(isvar(opP->con1))
                                        add_fix(s[1],opP->con1,0);
@@ -1434,7 +1448,7 @@ char      *instring;
                                /* We gotta put out some float */
                                if(seg(opP->con1)!=SEG_BIG) {
                                        int_to_gen(nextword);
-                                       gen_to_words(words,baseo,(long)outro);
+                                       gen_to_words(words,baseo,(long int)outro);
                                        for(wordp=words;baseo--;wordp++)
                                                addword(*wordp);
                                        break;
@@ -1442,7 +1456,7 @@ char      *instring;
                                if(offs(opP->con1)>0) {
                                        as_warn("Bignum assumed to be binary bit-pattern");
                                        if(offs(opP->con1)>baseo) {
-                                               as_bad("Bignum too big for %c format; truncated",s[1]);
+                                               as_warn("Bignum too big for %c format; truncated",s[1]);
                                                offs(opP->con1)=baseo;
                                        }
                                        baseo-=offs(opP->con1);
@@ -1453,7 +1467,7 @@ char      *instring;
                                        break;
                                }
                                gen_to_words(words,baseo,(long)outro);
-                               for(wordp=words;baseo--;wordp++)
+                               for (wordp=words;baseo--;wordp++)
                                        addword(*wordp);
                                break;
                        case DREG:
@@ -1664,16 +1678,21 @@ char    *instring;
                                nextword=get_num(opP->con1,80);
                                switch(opP->con1->e_siz) {
                                default:
-                                       as_bad("Unknown size for absolute reference");
+                                       as_warn("Unknown size for absolute reference");
                                case 0:
                                        if(!isvar(opP->con1) && issword(offs(opP->con1))) {
                                                tmpreg=0x38; /* 7.0 */
                                                addword(nextword);
                                                break;
                                        }
+                                       /* Don't generate pc relative code
+                                          on 68010 and 68000 */
                                        if(isvar(opP->con1) &&
                                           !subs(opP->con1) &&
-                                          !strchr("~%&$?", s[0])) {
+                                          seg(opP->con1)==SEG_TEXT &&
+                                          now_seg==SEG_TEXT &&
+                                          flagseen['m']==0 &&
+                                           !strchr("~%&$?", s[0])) {
                                                tmpreg=0x3A; /* 7.2 */
                                                add_frag(adds(opP->con1),
                                                         offs(opP->con1),
@@ -1769,46 +1788,46 @@ char    *instring;
                case 'B':
                        tmpreg=get_num(opP->con1,80);
                        switch(s[1]) {
+                       case 'B':
+                               /* Needs no offsetting */
+                               add_fix('B',opP->con1,1);
+                               break;
+                       case 'W':
+                               /* Offset the displacement to be relative to byte disp location */
+                               opP->con1->e_exp.X_add_number+=2;
+                               add_fix('w',opP->con1,1);
+                               addword(0);
+                               break;
+                       case 'L':
+                       long_branch:
+                               if(flagseen['m'])       /* 68000 or 010 */
+                                       as_warn("Can't use long branches on 68000/68010");
+                               the_ins.opcode[the_ins.numo-1]|=0xff;
+                               /* Offset the displacement to be relative to byte disp location */
+                               opP->con1->e_exp.X_add_number+=4;
+                               add_fix('l',opP->con1,1);
+                               addword(0);
+                               addword(0);
+                               break;
                        case 'g':
-                               if(opP->con1->e_siz) {  /* Deal with fixed size stuff by hand */
-                                       switch(opP->con1->e_siz) {
-                                       case 1:
-                                               add_fix('b',opP->con1,1);
-                                               break;
-                                       case 2:
-                                               add_fix('w',opP->con1,1);
-                                               addword(0);
-                                               break;
-                                       case 3:
-                                               add_fix('l',opP->con1,1);
-                                               addword(0);
-                                               addword(0);
-                                               break;
-                                       default:
-                                               as_bad("Bad size for expression %d", opP->con1->e_siz);
-                                       }
-                               } else if(subs(opP->con1)) {
-                                               /* We can't relax it */
-                                       the_ins.opcode[the_ins.numo-1]|=0xff;
-                                       add_fix('l',opP->con1,1);
-                                       addword(0);
-                                       addword(0);
-                               } else if(adds(opP->con1)) {
-                                       if (flagseen['m'] && 
-                                           (the_ins.opcode[0] >= 0x6200) &&
-                                           (the_ins.opcode[0] <= 0x6f00)) {
-                                         add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF));
-                                       } else {
-                                               add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF));
-                                       }
+                               if(subs(opP->con1))      /* We can't relax it */
+                                       goto long_branch;
+
+                               /* This could either be a symbol, or an
+                                  absolute address.  No matter, the
+                                  frag hacking will finger it out.
+                                  Not quite: it can't switch from
+                                  BRANCH to BCC68000 for the case
+                                  where opnd is absolute (it needs
+                                  to use the 68000 hack since no
+                                  conditional abs jumps).  */
+                               if(
+                                (flagseen['m'] || (0==adds(opP->con1)))
+                                && (the_ins.opcode[0] >= 0x6200) &&
+                                   (the_ins.opcode[0] <= 0x6f00)) {
+                                 add_frag(adds(opP->con1),offs(opP->con1),TAB(BCC68000,SZ_UNDEF));
                                } else {
-                                       /* JF:  This is the WRONG thing to do
-                                       add_frag((symbolS *)0,offs(opP->con1),TAB(BRANCH,BYTE)); */
-                                       the_ins.opcode[the_ins.numo-1]|=0xff;
-                                       offs(opP->con1)+=4;
-                                       add_fix('l',opP->con1,1);
-                                       addword(0);
-                                       addword(0);
+                                 add_frag(adds(opP->con1),offs(opP->con1),TAB(BRANCH,SZ_UNDEF));
                                }
                                break;
                        case 'w':
@@ -1827,24 +1846,18 @@ char    *instring;
                                }
                                addword(0);
                                break;
-                       case 'c':
-                               if(opP->con1->e_siz) {
-                                       switch(opP->con1->e_siz) {
-                                       case 2:
-                                               add_fix('w',opP->con1,1)
-                                               addword(0);
-                                               break;
-                                       case 3:
-                                               the_ins.opcode[the_ins.numo-1]|=0x40;
-                                               add_fix('l',opP->con1,1);
-                                               addword(0);
-                                               addword(0);
-                                               break;
-                                       default:
-                                               as_bad("Bad size for offset, must be word or long");
-                                               break;
-                                       }
-                               } else if(subs(opP->con1)) {
+                       case 'C':               /* Fixed size LONG coproc branches */
+                               the_ins.opcode[the_ins.numo-1]|=0x40;
+                               /* Offset the displacement to be relative to byte disp location */
+                               /* Coproc branches don't have a byte disp option, but they are
+                                  compatible with the ordinary branches, which do... */
+                               opP->con1->e_exp.X_add_number+=4;
+                               add_fix('l',opP->con1,1);
+                               addword(0);
+                               addword(0);
+                               break;
+                       case 'c':               /* Var size Coprocesssor branches */
+                               if(subs(opP->con1)) {
                                        add_fix('l',opP->con1,1);
                                        add_frag((symbolS *)0,(long)0,TAB(FBRANCH,LONG));
                                } else if(adds(opP->con1)) {
@@ -1884,7 +1897,7 @@ char      *instring;
                        }
                        tmpreg=get_num(opP->con1,80);
                        if(!issword(tmpreg)) {
-                               as_bad("Expression out of range, using 0");
+                               as_warn("Expression out of range, using 0");
                                tmpreg=0;
                        }
                        addword(tmpreg);
@@ -2357,7 +2370,7 @@ char *s;
                return 0;
        if(*s!=':') return 1;
                /* This kludge here is for the division cmd, which is a kludge */
-       if(strchr("aAdD#",s[1])) return 0;
+       if(index("aAdD#",s[1])) return 0;
        return 1;
 }
 #endif
@@ -2552,7 +2565,7 @@ obstack_alloc(&robyn,sizeof(struct m68_incant));
                retval = hash_insert (op_hash, ins->name,(char *)hack);
                        /* Didn't his mommy tell him about null pointers? */
                if(retval && *retval)
-                       as_fatal("Internal Error:  Can't hash %s: %s", ins->name,retval);
+                       as_fatal("Internal Error:  Can't hash %s: %s",ins->name,retval);
        }
 
        for (i = 0; i < sizeof(mklower_table) ; i++)
@@ -2608,6 +2621,7 @@ int *sizeP;
        LITTLENUM_TYPE words[MAX_LITTLENUMS];
        LITTLENUM_TYPE *wordP;
        char    *t;
+       char    *atof_ieee();
 
        switch(type) {
        case 'f':
@@ -2714,21 +2728,31 @@ md_apply_fix(fixP, val)
    MAGIC here. ..
  */
 void
-md_convert_frag(fragP)
+md_convert_frag(headers, fragP)
+object_headers *headers;
 register fragS *fragP;
 {
   long disp;
   long ext;
 
-  /* Address in gas core of the place to store the displacement.  */
-  register char *buffer_address = fragP -> fr_fix + fragP -> fr_literal;
   /* Address in object code of the displacement.  */
   register int object_address = fragP -> fr_fix + fragP -> fr_address;
 
-  know(fragP->fr_symbol);
+#ifdef IBM_COMPILER_SUX
+ /* This is wrong but it convinces the native rs6000 compiler to
+    generate the code we want. */
+  register char *buffer_address = fragP -> fr_literal;
+  buffer_address += fragP -> fr_fix;
+#else /* IBM_COMPILER_SUX */
+  /* Address in gas core of the place to store the displacement.  */
+  register char *buffer_address = fragP->fr_fix + fragP->fr_literal;
+#endif /* IBM_COMPILER_SUX */
+
+  /* No longer true:   know(fragP->fr_symbol); */
 
   /* The displacement of the address, from current location.  */
-  disp = (S_GET_VALUE(fragP->fr_symbol) + fragP->fr_offset) - object_address;
+  disp = fragP->fr_symbol ? S_GET_VALUE(fragP->fr_symbol) : 0;
+  disp = (disp + fragP->fr_offset) - object_address;
 
   switch(fragP->fr_subtype) {
   case TAB(BCC68000,BYTE):
@@ -2753,7 +2777,7 @@ register fragS *fragP;
     if(flagseen['m']) {
       if(fragP->fr_opcode[0]==0x61) {
        fragP->fr_opcode[0]= 0x4E;
-       fragP->fr_opcode[1]= 0xB9;      /* JSR with ABSL LONG offset */
+       fragP->fr_opcode[1]= 0xB9;      /* JBSR with ABSL LONG offset */
        subseg_change(SEG_TEXT, 0);
 
        fix_new(fragP,
@@ -2833,21 +2857,20 @@ register fragS *fragP;
     ext=2;
     break;
   case TAB(PCREL,LONG):
-    /* FIXME-SOMEDAY, this should allow pcrel-long to be generated if -pic is on.
-       Else we can't handle position independent code.  Pcrel-long costs an
-       extra index word though.  Doing it requires more relax tables and
-       stuff elsewhere in this module though. */
     /* The thing to do here is force it to ABSOLUTE LONG, since
        PCREL is really trying to shorten an ABSOLUTE address anyway */
+    /* JF FOO This code has not been tested */
     subseg_change(SEG_TEXT,0);
-    fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0,
-                               NO_RELOC);
+    fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
     if((fragP->fr_opcode[1] & 0x3F) != 0x3A)
        as_bad("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx",
                fragP->fr_opcode[0],fragP->fr_address);
     fragP->fr_opcode[1]&= ~0x3F;
     fragP->fr_opcode[1]|=0x39; /* Mode 7.1 */
     fragP->fr_fix+=4;
+    /* md_number_to_chars(buffer_address,
+                      (long)(fragP->fr_symbol->sy_value + fragP->fr_offset),
+                      4); */
     ext=0;
     break;
   case TAB(PCLEA,SHORT):
@@ -2869,12 +2892,20 @@ register fragS *fragP;
     ext=4;
     break;
 
-  }
-  if(ext) {
-    md_number_to_chars(buffer_address,(long)disp,(int)ext);
-    fragP->fr_fix+=ext;
-  }
-}
+  } /* switch on subtype */
+
+  if (ext) {
+         md_number_to_chars(buffer_address, (long) disp, (int) ext);
+         fragP->fr_fix += ext;
+/*       H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */
+  } /* if extending */
+
+  know((fragP->fr_next == NULL)
+       || ((fragP->fr_next->fr_address - fragP->fr_address)
+          == (fragP->fr_fix)));
+
+  return;
+} /* md_convert_frag() */
 
 /* Force truly undefined symbols to their maximum size, and generally set up
    the frag list to be relaxed
@@ -2890,105 +2921,10 @@ segT segment;
 
        /* handle SZ_UNDEF first, it can be changed to BYTE or SHORT */
        switch(fragP->fr_subtype) {
-       case TAB(BRANCH,SZ_UNDEF):
-               if(S_GET_SEGMENT(fragP->fr_symbol) == segment) {
-                       /* Symbol now defined; start at byte-size.  */
-                       fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
-                       break;
-               } else if(!flagseen['p'] || (!flagseen['l'] && flagseen['m'])) {
-                       /* Symbol in another segment, or undef.
-                          If we don't care about position independent code,
-                          or if we're using long displacements on a 68000,
-                          rewrite to short or long absolute. */
-                       if(fragP->fr_opcode[0]==0x61) {
-                               if(flagseen['l']) {
-                                       fragP->fr_opcode[0]= 0x4E;
-                                       fragP->fr_opcode[1]= 0xB9;      /* JBSR with ABSL WORD offset */
-                                       subseg_change(SEG_TEXT, 0);
-                                       fix_new(fragP, fragP->fr_fix, 2, 
-                                               fragP->fr_symbol, 0, fragP->fr_offset, 0,
-                               NO_RELOC);
-                                       fragP->fr_fix+=2;
-                               } else {
-                                       fragP->fr_opcode[0]= 0x4E;
-                                       fragP->fr_opcode[1]= 0xB9;      /* JBSR with ABSL LONG offset */
-                                       subseg_change(SEG_TEXT, 0);
-                                       fix_new(fragP, fragP->fr_fix, 4, 
-                                               fragP->fr_symbol, 0, fragP->fr_offset, 0,
-                               NO_RELOC);
-                                       fragP->fr_fix+=4;
-                               }
-                               frag_wane(fragP);
-                       } else if(fragP->fr_opcode[0]==0x60) {
-                               if(flagseen['l']) {
-                                       fragP->fr_opcode[0]= 0x4E;
-                                       fragP->fr_opcode[1]= 0xF8;      /* JMP  with ABSL WORD offset */
-                                       subseg_change(SEG_TEXT, 0);
-                                       fix_new(fragP, fragP->fr_fix, 2, 
-                                               fragP->fr_symbol, 0, fragP->fr_offset, 0,
-                               NO_RELOC);
-                                       fragP->fr_fix+=2;
-                               } else {
-                                       fragP->fr_opcode[0]= 0x4E;
-                                       fragP->fr_opcode[1]= 0xF9;      /* JMP  with ABSL LONG offset */
-                                       subseg_change(SEG_TEXT, 0);
-                                       fix_new(fragP, fragP->fr_fix, 4, 
-                                               fragP->fr_symbol, 0, fragP->fr_offset, 0,
-                               NO_RELOC);
-                                       fragP->fr_fix+=4;
-                               }
-                               frag_wane(fragP);
-                       } else {
-                               as_bad("Long branch offset to extern symbol not supported.");
-                       }
-               } else if(flagseen['l']) {
-                       /* Symbol in other seg or undefined, and user
-                          wants short pcrel offsets (-l).  Set size to 2, fix
-                          pcrel displacement after relax.  */
-                       fix_new(fragP,(int)(fragP->fr_fix),2,fragP->fr_symbol,
-                               (symbolS *)0,fragP->fr_offset+2,1,
-                               NO_RELOC);
-                       fragP->fr_fix+=2;
-                       fragP->fr_opcode[1]=0x00;
-                       frag_wane(fragP);
-               } else {
-                       /* Symbol in other seg or undefined, and user
-                          wants long pcrel offsets.  Set size to 4, and fix
-                          pcrel displacement after relax.  */
-                       fix_new(fragP,(int)(fragP->fr_fix),4,fragP->fr_symbol,
-                               (symbolS *)0,fragP->fr_offset + 4,1,
-                               NO_RELOC);
-                       fragP->fr_fix+=4;
-                       fragP->fr_opcode[1]=0xff;
-                       frag_wane(fragP);
-                       break;
-               }
-               break;
-
-       case TAB(FBRANCH,SZ_UNDEF):
-               if(S_GET_SEGMENT(fragP->fr_symbol) == segment
-                  || flagseen['l']) {
-                       fragP->fr_subtype=TAB(FBRANCH,SHORT);
-                       fragP->fr_var+=2;
-               } else {
-                       fragP->fr_subtype=TAB(FBRANCH,LONG);
-                       fragP->fr_var+=4;
-               }
-               break;
 
-       case TAB(PCREL,SZ_UNDEF):
-               if(S_GET_SEGMENT(fragP->fr_symbol) == segment
-                  || flagseen['l']) {
-                       fragP->fr_subtype=TAB(PCREL,SHORT);
-                       fragP->fr_var+=2;
-               } else {
-                       fragP->fr_subtype=TAB(PCREL,LONG);
-                       fragP->fr_var+=4;
-               }
-               break;
-
-       case TAB(BCC68000,SZ_UNDEF):
-               if(S_GET_SEGMENT(fragP->fr_symbol) == segment) {
+       case TAB(BCC68000,SZ_UNDEF): {
+               if((fragP->fr_symbol != NULL)
+                  && S_GET_SEGMENT(fragP->fr_symbol) == segment) {
                        fragP->fr_subtype=TAB(BCC68000,BYTE);
                        break;
                }
@@ -3003,8 +2939,7 @@ segT segment;
                        fragP->fr_fix += 2;          /* account for jmp instruction */
                        subseg_change(SEG_TEXT,0);
                        fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, 
-                                                        fragP->fr_offset,0,
-                               NO_RELOC);
+                                                        fragP->fr_offset, 0, NO_RELOC);
                        fragP->fr_fix += 2;
                } else {
                        fragP->fr_opcode[1] = 0x06;   /* branch offset = 6 */
@@ -3014,15 +2949,15 @@ segT segment;
                        fragP->fr_fix += 2;          /* account for jmp instruction */
                        subseg_change(SEG_TEXT,0);
                        fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, 
-                                                        fragP->fr_offset,0,
-                               NO_RELOC);
+                                                        fragP->fr_offset, 0, NO_RELOC);
                        fragP->fr_fix += 4;
                }
                frag_wane(fragP);
                break;
+       } /* case TAB(BCC68000,SZ_UNDEF) */
 
-       case TAB(DBCC,SZ_UNDEF):
-               if(S_GET_SEGMENT(fragP->fr_symbol) == segment) {
+       case TAB(DBCC,SZ_UNDEF): {
+               if (fragP->fr_symbol != NULL && S_GET_SEGMENT(fragP->fr_symbol) == segment) {
                        fragP->fr_subtype=TAB(DBCC,SHORT);
                        fragP->fr_var+=2;
                        break;
@@ -3032,7 +2967,8 @@ segT segment;
                /* JF: these used to be fr_opcode[2-4], which is wrong. */
                buffer_address[0] = 0x00;  /* branch offset = 4 */
                buffer_address[1] = 0x04;  
-               buffer_address[2] = 0x60;  /* put in bra pc + ... */ 
+               buffer_address[2] = 0x60;  /* put in bra pc + ... */
                if(flagseen['l']) {
                        /* JF: these were fr_opcode[5-7] */
                        buffer_address[3] = 0x04; /* plus 4 */
@@ -3041,9 +2977,8 @@ segT segment;
                        fragP->fr_fix += 6;       /* account for bra/jmp instruction */
                        subseg_change(SEG_TEXT,0);
                        fix_new(fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0, 
-                                                        fragP->fr_offset,0,
-                               NO_RELOC);
-                       fragP->fr_fix+=2;
+                                                        fragP->fr_offset, 0, NO_RELOC);
+                       fragP->fr_fix += 2;
                } else {
                        /* JF: these were fr_opcode[5-7] */
                        buffer_address[3] = 0x06;  /* Plus 6 */
@@ -3052,15 +2987,53 @@ segT segment;
                        fragP->fr_fix += 6;       /* account for bra/jmp instruction */
                        subseg_change(SEG_TEXT,0);
                        fix_new(fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, 
-                                                        fragP->fr_offset,0,
-                               NO_RELOC);
+                                                        fragP->fr_offset, 0, NO_RELOC);
                        fragP->fr_fix += 4;
                }
+
                frag_wane(fragP);
                break;
+       } /* case TAB(DBCC,SZ_UNDEF) */
 
-       case TAB(PCLEA,SZ_UNDEF):
-               if((S_GET_SEGMENT(fragP->fr_symbol))==segment || flagseen['l']) {
+       case TAB(BRANCH,SZ_UNDEF): {
+               if((fragP->fr_symbol != NULL)   /* Not absolute */
+                  && S_GET_SEGMENT(fragP->fr_symbol) == segment) {
+                        fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),BYTE);
+                        break;
+               } else if((fragP->fr_symbol == 0) || flagseen['m']) {
+                       /* On 68000, or for absolute value, switch to abs long */
+                       /* FIXME, we should check abs val, pick short or long */
+                       if(fragP->fr_opcode[0]==0x61) {
+                               fragP->fr_opcode[0]= 0x4E;
+                               fragP->fr_opcode[1]= 0xB9;      /* JBSR with ABSL LONG offset */
+                               subseg_change(SEG_TEXT, 0);
+                               fix_new(fragP, fragP->fr_fix, 4, 
+                                       fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
+                               fragP->fr_fix+=4;
+                               frag_wane(fragP);
+                       } else if(fragP->fr_opcode[0]==0x60) {
+                               fragP->fr_opcode[0]= 0x4E;
+                               fragP->fr_opcode[1]= 0xF9;  /* JMP  with ABSL LONG offset */
+                               subseg_change(SEG_TEXT, 0);
+                               fix_new(fragP, fragP->fr_fix, 4, 
+                                       fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
+                               fragP->fr_fix+=4;
+                               frag_wane(fragP);
+                       } else {
+                               as_warn("Long branch offset to extern symbol not supported.");
+                       }
+               } else {        /* Symbol is still undefined.  Make it simple */
+                       fix_new(fragP, (int)(fragP->fr_fix), 4, fragP->fr_symbol,
+                               (symbolS *)0, fragP->fr_offset+4, 1, NO_RELOC);
+                       fragP->fr_fix+=4;
+                       fragP->fr_opcode[1]=0xff;
+                       frag_wane(fragP);
+                       break;
+               }
+       } /* case TAB(BRANCH,SZ_UNDEF) */
+
+       case TAB(PCLEA,SZ_UNDEF): {
+               if ((S_GET_SEGMENT(fragP->fr_symbol))==segment || flagseen['l']) {
                        fragP->fr_subtype=TAB(PCLEA,SHORT);
                        fragP->fr_var+=2;
                } else {
@@ -3068,6 +3041,18 @@ segT segment;
                        fragP->fr_var+=6;
                }
                break;
+       } /* TAB(PCLEA,SZ_UNDEF) */
+
+       case TAB(PCREL,SZ_UNDEF): {
+               if(S_GET_SEGMENT(fragP->fr_symbol) == segment || flagseen['l']) {
+                       fragP->fr_subtype = TAB(PCREL,SHORT);
+                       fragP->fr_var += 2;
+               } else {
+                       fragP->fr_subtype = TAB(PCREL,LONG);
+                       fragP->fr_var += 4;
+               }
+               break;
+       } /* TAB(PCREL,SZ_UNDEF) */
 
        default:
                break;
@@ -3079,7 +3064,7 @@ segT segment;
        case TAB(BRANCH,BYTE):
                        /* We can't do a short jump to the next instruction,
                           so we force word mode.  */
-               if(fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 &&
+               if (fragP->fr_symbol && S_GET_VALUE(fragP->fr_symbol)==0 &&
  fragP->fr_symbol->sy_frag==fragP->fr_next) {
                        fragP->fr_subtype=TAB(TABTYPE(fragP->fr_subtype),SHORT);
                        fragP->fr_var+=2;
@@ -3148,7 +3133,7 @@ symbolS   *to_symbol;
 {
        long offset;
 
-       if(flagseen['m']) {
+       if (flagseen['m']) {
                offset=to_addr-S_GET_VALUE(to_symbol);
                md_number_to_chars(ptr  ,(long)0x4EF9,2);
                md_number_to_chars(ptr+2,(long)offset,4);
@@ -3207,7 +3192,7 @@ int ok;
                adds(exp)=0;
                subs(exp)=0;
                offs(exp)= (ok==10) ? 1 : 0;
-               as_bad("Null expression defaults to %ld", offs(exp));
+               as_warn("Null expression defaults to %ld",offs(exp));
                return 0;
        }
 
@@ -3229,7 +3214,7 @@ int ok;
                        exp->e_siz=3;
                        break;
                default:
-                       as_bad("Unknown size for expression \"%c\"", exp->e_end[0]);
+                       as_bad("Unknown size for expression \"%c\"",exp->e_end[0]);
                }
                exp->e_end-=2;
        }
@@ -3243,7 +3228,7 @@ int ok;
                adds(exp)=0;
                subs(exp)=0;
                offs(exp)= (ok==10) ? 1 : 0;
-               as_bad("Unknown expression: '%s' defaulting to %d",exp->e_beg,offs(exp));
+               as_warn("Unknown expression: '%s' defaulting to %d",exp->e_beg,offs(exp));
                break;
 
        case SEG_ABSENT:
@@ -3253,7 +3238,7 @@ int ok;
                subs(exp)=0;
                offs(exp)=0;
                if(ok==10) {
-                       as_bad("expression out of range: defaulting to 1");
+                       as_warn("expression out of range: defaulting to 1");
                        offs(exp)=1;
                }
                break;
@@ -3261,7 +3246,7 @@ int ok;
                switch(ok) {
                case 10:
                        if(offs(exp)<1 || offs(exp)>8) {
-                               as_bad("expression out of range: defaulting to 1");
+                               as_warn("expression out of range: defaulting to 1");
                                offs(exp)=1;
                        }
                        break;
@@ -3292,7 +3277,7 @@ int ok;
                case 70:
                        if(offs(exp)<0 || offs(exp)>4095) {
                        outrange:
-                               as_bad("expression out of range: defaulting to 0");
+                               as_warn("expression out of range: defaulting to 0");
                                offs(exp)=0;
                        }
                        break;
@@ -3310,7 +3295,7 @@ int ok;
                        adds(exp)=0;
                        subs(exp)=0;
                        offs(exp)= (ok==10) ? 1 : 0;
-                       as_bad("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
+                       as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
                }
                break;
        case SEG_BIG:
@@ -3327,7 +3312,7 @@ int ok;
                        adds(exp)=0;
                        subs(exp)=0;
                        offs(exp)= (ok==10) ? 1 : 0;
-                       as_bad("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
+                       as_warn("Can't deal with expression \"%s\": defaulting to %ld",exp->e_beg,offs(exp));
                }
                break;
        default:
@@ -3341,11 +3326,11 @@ int ok;
                switch(exp->e_siz) {
                case 1:
                        if(!isbyte(offs(exp)))
-                               as_bad("expression doesn't fit in BYTE");
+                               as_warn("expression doesn't fit in BYTE");
                        break;
                case 2:
                        if(!isword(offs(exp)))
-                               as_bad("expression doesn't fit in WORD");
+                               as_warn("expression doesn't fit in WORD");
                        break;
                }
        }
@@ -3354,6 +3339,7 @@ int ok;
 } /* get_num() */
 
 /* These are the back-ends for the various machine dependent pseudo-ops.  */
+void demand_empty_rest_of_line();      /* Hate those extra verbose names */
 
 static void s_data1() {
        subseg_new(SEG_DATA,1);
@@ -3396,8 +3382,8 @@ int *cntP;
 char ***vecP;
 {
        switch(**argP) {
-       case 'l':       /* -l means keep externals to 2 byte branch offsets
-                          rather than 4 byte branch offsets */
+       case 'l':       /* -l means keep external to 2 bit offset
+                          rather than 16 bit one */
                break;
 
        case 'm':
@@ -3409,7 +3395,7 @@ char ***vecP;
                        flagseen['m']=2;
                else if(!strcmp(*argP,"68010")) {
 #ifdef TE_SUN
-                       magic_number_for_object_file = 1<<16|OMAGIC;
+                       omagic= 1<<16|OMAGIC;
 #endif
                        flagseen['m']=1;
                } else if(!strcmp(*argP,"68020"))
@@ -3619,7 +3605,7 @@ This file is part of GDB, the GNU Debugger and GAS, the GNU Assembler.
 
 Both GDB and GAS are free software; you can redistribute and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GDB and GAS are distributed in the hope that it will be useful,
index a0b36c35173c2c48288dfb33c80919777fb0a5be..7dce445d8f647694b3d1f0aed957130a6b48a965 100644 (file)
@@ -5,7 +5,7 @@ This file is part of GAS, the GNU Assembler.
 
 GAS is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GAS is distributed in the hope that it will be useful,
@@ -115,7 +115,6 @@ enum reloc_type     r_type; /* Relocation type */
   fixP->fx_offset      = offset;
   fixP->fx_pcrel       = pcrel;
   fixP->fx_r_type      = r_type;
-  fixP->fx_next        = NULL;
 
   /* JF these 'cuz of the NS32K stuff */
   fixP->fx_im_disp     = 0;
@@ -123,15 +122,32 @@ enum reloc_type   r_type; /* Relocation type */
   fixP->fx_bsr = 0;
   fixP->fx_bit_fixP    = 0;
 
+ /* usually, we want relocs sorted numerically, but while
+    comparing to older versions of gas that have relocs
+    reverse sorted, it is convenient to have this compile
+    time option.  xoxorich. */
+
+#ifdef REVERSE_SORT_RELOCS
+
+  fixP->fx_next = *seg_fix_rootP;
+  *seg_fix_rootP = fixP;
+
+#else /* REVERSE_SORT_RELOCS */
+
+  fixP->fx_next        = NULL;
+
   if (*seg_fix_tailP)
     (*seg_fix_tailP)->fx_next = fixP;
   else
     *seg_fix_rootP = fixP;
   *seg_fix_tailP = fixP;
+
+#endif /* REVERSE_SORT_RELOCS */
+
   fixP->fx_callj = 0;
   return fixP;
 }
-\f
+
 void write_object_file() {
   register struct frchain *    frchainP; /* Track along all frchains. */
   register fragS *             fragP;  /* Track along all frags. */
@@ -190,7 +206,7 @@ void write_object_file() {
          /* know( frags . obstack_c_base == frags . obstack_c_next_free ); */
          /* Above shows we haven't left a half-completed object on obstack. */
   } /* walk the frag chain */
-\f
+
   /*
    * From now on, we don't care about sub-segments.
    * Build one frag chain for each segment. Linked thru fr_next.
@@ -240,8 +256,8 @@ void write_object_file() {
    */
 
   know(text_last_frag->fr_type == rs_fill && text_last_frag->fr_offset == 0);
-  H_SET_TEXT_SIZE(&headers,text_last_frag->fr_address);
-  text_last_frag->fr_address=H_GET_TEXT_SIZE(&headers);
+  H_SET_TEXT_SIZE(&headers, text_last_frag->fr_address);
+  text_last_frag->fr_address = H_GET_TEXT_SIZE(&headers);
 
   /*
    * Join the 2 segments into 1 huge segment.
@@ -251,20 +267,20 @@ void write_object_file() {
    * Determine a_data [length of data segment].
    */
   if (data_frag_root) {
-         register relax_addressT       slide;
+         register relax_addressT slide;
          
-         know(   text_last_frag->fr_type   == rs_fill && text_last_frag->fr_offset == 0 );
+         know((text_last_frag->fr_type == rs_fill)
+              && (text_last_frag->fr_offset == 0));
+
          H_SET_DATA_SIZE(&headers, data_last_frag->fr_address);
          data_last_frag->fr_address = H_GET_DATA_SIZE(&headers);
          slide = H_GET_TEXT_SIZE(&headers); /* & in file of the data segment. */
          
-         for (fragP = data_frag_root;
-              fragP;
-              fragP = fragP->fr_next)
-             {
-                     fragP->fr_address += slide;
-             }
-         know( text_last_frag );
+         for (fragP = data_frag_root; fragP; fragP = fragP->fr_next) {
+                 fragP->fr_address += slide;
+         } /* for each data frag */
+
+         know(text_last_frag != 0);
          text_last_frag->fr_next = data_frag_root;
   } else {
          H_SET_DATA_SIZE(&headers,0);
@@ -321,25 +337,25 @@ void write_object_file() {
          case rs_align:
          case rs_org:
                  fragP->fr_type = rs_fill;
-                 know( fragP->fr_var == 1 );
-                 know( fragP->fr_next );
-                 fragP->fr_offset
-                     =     fragP->fr_next->fr_address
-                         -   fragP->fr_address
-                             - fragP->fr_fix;
+                 know(fragP->fr_var == 1);
+                 know(fragP->fr_next != NULL);
+
+                 fragP->fr_offset = (fragP->fr_next->fr_address
+                                     - fragP->fr_address
+                                     - fragP->fr_fix);
                  break;
                  
          case rs_fill:
                  break;
                  
          case rs_machine_dependent:
-                 md_convert_frag (fragP);
+                 md_convert_frag(&headers, fragP);
                  /*
                   * After md_convert_frag, we make the frag into a ".space 0".
                   * Md_convert_frag() should set up any fixSs and constants
                   * required.
                   */
-                 frag_wane (fragP);
+                 frag_wane(fragP);
                  break;
                  
 #ifndef WORKING_DOT_WORD
@@ -463,13 +479,13 @@ void write_object_file() {
          
  /* FIXME move this stuff into the pre-write-hook */
          H_SET_MAGIC_NUMBER(&headers, magic_number_for_object_file);
-         H_SET_ENTRY_POINT(&headers,0);
+         H_SET_ENTRY_POINT(&headers, 0);
          
 #ifdef EXEC_MACHINE_TYPE
-         H_SET_MACHINE_TYPE(&headers,EXEC_MACHINE_TYPE);
+         H_SET_MACHINE_TYPE(&headers, EXEC_MACHINE_TYPE);
 #endif
 #ifdef EXEC_VERSION
-         H_SET_VERSION(&headers,EXEC_VERSION);
+         H_SET_VERSION(&headers, EXEC_VERSION);
 #endif
          
          obj_pre_write_hook(&headers); /* extra coff stuff */
@@ -493,29 +509,42 @@ void write_object_file() {
          output_file_create(out_file_name);
          
          obj_header_append(&next_object_file_charP, &headers);
-         
+         know((next_object_file_charP - the_object_file) == H_GET_HEADER_SIZE(&headers));
+
          /*
           * Emit code.
           */
          for (fragP = text_frag_root;  fragP;  fragP = fragP->fr_next) {
-                 register long         count;
-                 register char *               fill_literal;
-                 register long         fill_size;
+                 register long count;
+                 register char *fill_literal;
+                 register long fill_size;
                  
-                 know( fragP->fr_type == rs_fill );
-                 append (& next_object_file_charP, fragP->fr_literal, (unsigned long)fragP->fr_fix);
-                 fill_literal= fragP->fr_literal + fragP->fr_fix;
-                 fill_size   = fragP->fr_var;
-                 know( fragP->fr_offset >= 0 );
-                 for (count = fragP->fr_offset;  count;  count --)
-                     append (& next_object_file_charP, fill_literal, (unsigned long)fill_size);
+                 know(fragP->fr_type == rs_fill);
+                 append(&next_object_file_charP, fragP->fr_literal, (unsigned long) fragP->fr_fix);
+                 fill_literal = fragP->fr_literal + fragP->fr_fix;
+                 fill_size = fragP->fr_var;
+                 know(fragP->fr_offset >= 0);
+
+                 for (count = fragP->fr_offset; count; count--) {
+                         append(&next_object_file_charP, fill_literal, (unsigned long) fill_size);
+                 } /* for each  */
+
          } /* for each code frag. */
+
+         know((next_object_file_charP - the_object_file)
+              == (H_GET_HEADER_SIZE(&headers)
+                  + H_GET_TEXT_SIZE(&headers)
+                  + H_GET_DATA_SIZE(&headers)));
          
          /*
           * Emit relocations.
           */
          obj_emit_relocations(&next_object_file_charP, text_fix_root, (relax_addressT)0);
-         
+         know((next_object_file_charP - the_object_file)
+              == (H_GET_HEADER_SIZE(&headers)
+                  + H_GET_TEXT_SIZE(&headers)
+                  + H_GET_DATA_SIZE(&headers)
+                  + H_GET_TEXT_RELOCATION_SIZE(&headers)));
 #ifdef TC_I960
          /* Make addresses in data relocation directives relative to beginning of
           * first data fragment, not end of last text fragment:  alignment of the
@@ -526,16 +555,38 @@ void write_object_file() {
          obj_emit_relocations(&next_object_file_charP, data_fix_root, text_last_frag->fr_address);
 #endif /* TC_I960 */
          
+         know((next_object_file_charP - the_object_file)
+              == (H_GET_HEADER_SIZE(&headers)
+                  + H_GET_TEXT_SIZE(&headers)
+                  + H_GET_DATA_SIZE(&headers)
+                  + H_GET_TEXT_RELOCATION_SIZE(&headers)
+                  + H_GET_DATA_RELOCATION_SIZE(&headers)));
+
          /*
           * Emit line number entries.
           */
          OBJ_EMIT_LINENO(&next_object_file_charP, lineno_rootP, the_object_file);
+         know((next_object_file_charP - the_object_file)
+              == (H_GET_HEADER_SIZE(&headers)
+                  + H_GET_TEXT_SIZE(&headers)
+                  + H_GET_DATA_SIZE(&headers)
+                  + H_GET_TEXT_RELOCATION_SIZE(&headers)
+                  + H_GET_DATA_RELOCATION_SIZE(&headers)
+                  + H_GET_LINENO_SIZE(&headers)));
          
          /*
           * Emit symbols.
           */
          obj_emit_symbols(&next_object_file_charP, symbol_rootP);
-         
+         know((next_object_file_charP - the_object_file)
+              == (H_GET_HEADER_SIZE(&headers)
+                  + H_GET_TEXT_SIZE(&headers)
+                  + H_GET_DATA_SIZE(&headers)
+                  + H_GET_TEXT_RELOCATION_SIZE(&headers)
+                  + H_GET_DATA_RELOCATION_SIZE(&headers)
+                  + H_GET_LINENO_SIZE(&headers)
+                  + H_GET_SYMBOL_TABLE_SIZE(&headers)));
+
          /*
           * Emit strings.
           */
@@ -544,6 +595,16 @@ void write_object_file() {
                  obj_emit_strings(&next_object_file_charP);
          } /* only if we have a string table */
          
+         know((next_object_file_charP - the_object_file)
+              == (H_GET_HEADER_SIZE(&headers)
+                  + H_GET_TEXT_SIZE(&headers)
+                  + H_GET_DATA_SIZE(&headers)
+                  + H_GET_TEXT_RELOCATION_SIZE(&headers)
+                  + H_GET_DATA_RELOCATION_SIZE(&headers)
+                  + H_GET_LINENO_SIZE(&headers)
+                  + H_GET_SYMBOL_TABLE_SIZE(&headers)
+                  + H_GET_STRING_SIZE(&headers)));
+
          know(next_object_file_charP == the_object_file + object_file_size);
          /* Write the data to the file */
          output_file_append(the_object_file,object_file_size,out_file_name);
@@ -581,303 +642,297 @@ void write_object_file() {
 #ifndef        VMS
 static
 #endif /* not VMS */
-void relax_segment(segment_frag_root, segment_type)
+void relax_segment(segment_frag_root, segment)
      struct frag *     segment_frag_root;
-     segT              segment_type; /* SEG_DATA or SEG_TEXT */
+     segT              segment; /* SEG_DATA or SEG_TEXT */
 {
-  register struct frag *       fragP;
-  register relax_addressT      address;
-  /* register relax_addressT   old_address; JF unused */
-  /* register relax_addressT   new_address; JF unused */
-
-  know( segment_type == SEG_DATA || segment_type == SEG_TEXT );
-
-  /* In case md_estimate_size_before_relax() wants to make fixSs. */
-  subseg_change(segment_type, 0);
-
-  /*
-   * For each frag in segment: count and store  (a 1st guess of) fr_address.
-   */
-  address = 0;
-  for ( fragP = segment_frag_root;   fragP;   fragP = fragP->fr_next )
-    {
-      fragP->fr_address = address;
-      address += fragP->fr_fix;
-      switch (fragP->fr_type)
-       {
-       case rs_fill:
-         address += fragP->fr_offset * fragP->fr_var;
-         break;
-
-       case rs_align:
-         address += relax_align(address, fragP->fr_offset);
-         break;
-
-       case rs_org:
-         /*
-          * Assume .org is nugatory. It will grow with 1st relax.
-          */
-         break;
-
-       case rs_machine_dependent:
-         address += md_estimate_size_before_relax(fragP, segment_type);
-         break;
-
+       register struct frag *  fragP;
+       register relax_addressT address;
+       /* register relax_addressT      old_address; JF unused */
+       /* register relax_addressT      new_address; JF unused */
+       
+       know( segment == SEG_DATA || segment == SEG_TEXT );
+       
+       /* In case md_estimate_size_before_relax() wants to make fixSs. */
+       subseg_change(segment, 0);
+       
+       /*
+        * For each frag in segment: count and store  (a 1st guess of) fr_address.
+        */
+       address = 0;
+       for (fragP = segment_frag_root; fragP; fragP = fragP->fr_next) {
+               fragP->fr_address = address;
+               address += fragP->fr_fix;
+               
+               switch (fragP->fr_type) {
+               case rs_fill:
+                       address += fragP->fr_offset * fragP->fr_var;
+                       break;
+                       
+               case rs_align:
+                       address += relax_align(address, fragP->fr_offset);
+                       break;
+                       
+               case rs_org:
+                       /*
+                        * Assume .org is nugatory. It will grow with 1st relax.
+                        */
+                       break;
+                       
+               case rs_machine_dependent:
+                       address += md_estimate_size_before_relax(fragP, segment);
+                       break;
+                       
 #ifndef WORKING_DOT_WORD
-               /* Broken words don't concern us yet */
-       case rs_broken_word:
-               break;
+                       /* Broken words don't concern us yet */
+               case rs_broken_word:
+                       break;
 #endif
-
-       default:
-         BAD_CASE( fragP->fr_type );
-         break;
-       }                       /* switch(fr_type) */
-    }                          /* for each frag in the segment */
-\f
-  /*
-   * Do relax().
-   */
-  {
-    register long      stretch; /* May be any size, 0 or negative. */
-                               /* Cumulative number of addresses we have */
-                               /* relaxed this pass. */
-                               /* We may have relaxed more than one address. */
-    register long stretched;  /* Have we stretched on this pass? */
-                                 /* This is 'cuz stretch may be zero, when,
-                                    in fact some piece of code grew, and
-                                    another shrank.  If a branch instruction
-                                    doesn't fit anymore, we could be scrod */
-
-    do
-      {
-       stretch = stretched = 0;
-       for (fragP = segment_frag_root;  fragP;  fragP = fragP->fr_next)
-         {
-           register long growth = 0;
-           register unsigned long was_address;
-           /* register long var; */
-           register long offset;
-           register symbolS *symbolP;
-           register long target;
-           register long after;
-           register long aim;
-
-           was_address = fragP->fr_address;
-           address = fragP->fr_address += stretch;
-           symbolP = fragP->fr_symbol;
-           offset = fragP->fr_offset;
-           /* var = fragP->fr_var; */
-           switch (fragP->fr_type)
-             {
-             case rs_fill:     /* .fill never relaxes. */
-               growth = 0;
-               break;
-
+                       
+               default:
+                       BAD_CASE(fragP->fr_type);
+                       break;
+               } /* switch(fr_type) */
+       } /* for each frag in the segment */
+       
+       /*
+        * Do relax().
+        */
+       {
+               register long   stretch; /* May be any size, 0 or negative. */
+               /* Cumulative number of addresses we have */
+               /* relaxed this pass. */
+               /* We may have relaxed more than one address. */
+               register long stretched;  /* Have we stretched on this pass? */
+               /* This is 'cuz stretch may be zero, when,
+                  in fact some piece of code grew, and
+                  another shrank.  If a branch instruction
+                  doesn't fit anymore, we could be scrod */
+               
+               do {
+                       stretch = stretched = 0;
+                       for (fragP = segment_frag_root;  fragP;  fragP = fragP->fr_next) {
+                               register long growth = 0;
+                               register unsigned long was_address;
+                               /* register long var; */
+                               register long offset;
+                               register symbolS *symbolP;
+                               register long target;
+                               register long after;
+                               register long aim;
+                               
+                               was_address = fragP->fr_address;
+                               address = fragP->fr_address += stretch;
+                               symbolP = fragP->fr_symbol;
+                               offset = fragP->fr_offset;
+                               /* var = fragP->fr_var; */
+
+                               switch (fragP->fr_type) {
+                               case rs_fill:   /* .fill never relaxes. */
+                                       growth = 0;
+                                       break;
+                                       
 #ifndef WORKING_DOT_WORD
-               /* JF:  This is RMS's idea.  I do *NOT* want to be blamed
-                  for it I do not want to write it.  I do not want to have
-                  anything to do with it.  This is not the proper way to
-                  implement this misfeature. */
-             case rs_broken_word:
-               {
-               struct broken_word *lie;
-               struct broken_word *untruth;
-               extern int md_short_jump_size;
-               extern int md_long_jump_size;
-
-                       /* Yes this is ugly (storing the broken_word pointer
-                          in the symbol slot).  Still, this whole chunk of
-                          code is ugly, and I don't feel like doing anything
-                          about it.  Think of it as stubbornness in action */
-               growth=0;
-               for (lie=(struct broken_word *)(fragP->fr_symbol);
-                   lie && lie->dispfrag==fragP;
-                   lie=lie->next_broken_word) {
-
-                       if (lie->added)
-                               continue;
-                       offset=  lie->add->sy_frag->fr_address+ S_GET_VALUE(lie->add) + lie->addnum -
-                               (lie->sub->sy_frag->fr_address+ S_GET_VALUE(lie->sub));
-                       if (offset<=-32768 || offset>=32767) {
-                               if (flagseen['k'])
-                                       as_warn(".word %s-%s+%ld didn't fit",
-                                               S_GET_NAME(lie->add),
-                                               S_GET_NAME(lie->sub),
-                                               lie->addnum);
-                               lie->added=1;
-                               if (fragP->fr_subtype==0) {
-                                       fragP->fr_subtype++;
-                                       growth+=md_short_jump_size;
-                               }
-                               for (untruth=lie->next_broken_word;untruth && untruth->dispfrag==lie->dispfrag;untruth=untruth->next_broken_word)
-                                       if ((untruth->add->sy_frag == lie->add->sy_frag)
-                                           && S_GET_VALUE(untruth->add) == S_GET_VALUE(lie->add)) {
-                                               untruth->added=2;
-                                               untruth->use_jump=lie;
+                                       /* JF:  This is RMS's idea.  I do *NOT* want to be blamed
+                                          for it I do not want to write it.  I do not want to have
+                                          anything to do with it.  This is not the proper way to
+                                          implement this misfeature. */
+                               case rs_broken_word: {
+                                       struct broken_word *lie;
+                                       struct broken_word *untruth;
+                                       extern int md_short_jump_size;
+                                       extern int md_long_jump_size;
+                                       
+                                       /* Yes this is ugly (storing the broken_word pointer
+                                          in the symbol slot).  Still, this whole chunk of
+                                          code is ugly, and I don't feel like doing anything
+                                          about it.  Think of it as stubbornness in action */
+                                       growth=0;
+                                       for (lie=(struct broken_word *)(fragP->fr_symbol);
+                                            lie && lie->dispfrag==fragP;
+                                            lie=lie->next_broken_word) {
+                                               
+                                               if (lie->added)
+                                                   continue;
+
+                                               offset=  lie->add->sy_frag->fr_address+ S_GET_VALUE(lie->add) + lie->addnum -
+                                                   (lie->sub->sy_frag->fr_address+ S_GET_VALUE(lie->sub));
+                                               if (offset<=-32768 || offset>=32767) {
+                                                       if (flagseen['k'])
+                                                           as_warn(".word %s-%s+%ld didn't fit",
+                                                                   S_GET_NAME(lie->add),
+                                                                   S_GET_NAME(lie->sub),
+                                                                   lie->addnum);
+                                                       lie->added=1;
+                                                       if (fragP->fr_subtype==0) {
+                                                               fragP->fr_subtype++;
+                                                               growth+=md_short_jump_size;
+                                                       }
+                                                       for (untruth=lie->next_broken_word;untruth && untruth->dispfrag==lie->dispfrag;untruth=untruth->next_broken_word)
+                                                           if ((untruth->add->sy_frag == lie->add->sy_frag)
+                                                               && S_GET_VALUE(untruth->add) == S_GET_VALUE(lie->add)) {
+                                                                   untruth->added=2;
+                                                                   untruth->use_jump=lie;
+                                                           }
+                                                       growth+=md_long_jump_size;
+                                               }
                                        }
-                               growth+=md_long_jump_size;
-                       }
-                   }
-               }
-               break;
+                                       
+                                       break;
+                               } /* case rs_broken_word */
 #endif
-             case rs_align:
-               growth = relax_align ((relax_addressT)(address + fragP->fr_fix), offset)
-                 - relax_align ((relax_addressT)(was_address +  fragP->fr_fix), offset);
-               break;
-
-             case rs_org:
-               target = offset;
-               if (symbolP)
-                 {
-                   know((S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) ||
-                        (S_GET_SEGMENT(symbolP) == SEG_DATA) ||
-                        (S_GET_SEGMENT(symbolP) == SEG_TEXT));
-                   know(symbolP->sy_frag);
-                   know(!(S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) || 
-                        symbolP->sy_frag==&zero_address_frag );
-                   target +=
-                     S_GET_VALUE(symbolP)
-                       + symbolP->sy_frag->fr_address;
-                 }
-               know( fragP->fr_next );
-               after = fragP->fr_next->fr_address;
-               growth = ((target - after ) > 0) ? (target - after) : 0;
-                               /* Growth may be -ve, but variable part */
-                               /* of frag cannot have < 0 chars. */
-                               /* That is, we can't .org backwards. */
-
-               growth -= stretch;      /* This is an absolute growth factor */
-               break;
-
-             case rs_machine_dependent:
-               {
-                 register const relax_typeS *  this_type;
-                 register const relax_typeS *  start_type;
-                 register relax_substateT      next_state;
-                 register relax_substateT      this_state;
-
-                 start_type = this_type
-                   = md_relax_table + (this_state = fragP->fr_subtype);
-               target = offset;
-               if (symbolP)
-                 {
-                   know((S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) ||
-                        (S_GET_SEGMENT(symbolP) == SEG_DATA) ||
-                        (S_GET_SEGMENT(symbolP) == SEG_TEXT));
-                   know(symbolP->sy_frag);
-                   know(!(S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) || 
-                        symbolP->sy_frag==&zero_address_frag );
-                   target +=
-                     S_GET_VALUE(symbolP)
-                       + symbolP->sy_frag->fr_address;
-
-                       /* If frag has yet to be reached on this pass,
-                          assume it will move by STRETCH just as we did.
-                          If this is not so, it will be because some frag
-                          between grows, and that will force another pass.  */
-
-                               /* JF was just address */
-                               /* JF also added is_dnrange hack */
-                               /* There's gotta be a better/faster/etc way
-                                  to do this. . . */
-                       /* gnu@cygnus.com:  I changed this from > to >=
-                          because I ran into a zero-length frag (fr_fix=0)
-                          which was created when the obstack needed a new
-                          chunk JUST AFTER the opcode of a branch.  Since
-                          fr_fix is zero, fr_address of this frag is the same
-                          as fr_address of the next frag.  This
-                          zero-length frag was variable and jumped to .+2
-                          (in the next frag), but since the > comparison
-                          below failed (the two were =, not >), "stretch"
-                          was not added to the target.  Stretch was 178, so
-                          the offset appeared to be .-176 instead, which did
-                          not fit into a byte branch, so the assembler
-                          relaxed the branch to a word.  This didn't compare
-                          with what happened when the same source file was
-                          assembled on other machines, which is how I found it.
-                          You might want to think about what other places have
-                          trouble with zero length frags... */
-
-                   if (symbolP->sy_frag->fr_address >= was_address && is_dnrange(fragP,symbolP->sy_frag))
-                     target += stretch;
-
-                 }
-                 aim = target - address - fragP->fr_fix;
-                 /* The displacement is affected by the instruction size
-                  * for the 32k architecture. I think we ought to be able
-                  * to add fragP->fr_pcrel_adjust in all cases (it should be
-                  * zero if not used), but just in case it breaks something
-                  * else we'll put this inside #ifdef NS32K ... #endif
-                  */
+                               case rs_align:
+                                       growth = relax_align((relax_addressT) (address + fragP->fr_fix), offset)
+                                           - relax_align((relax_addressT) (was_address + fragP->fr_fix), offset);
+                                       break;
+                                       
+                               case rs_org:
+                                       target = offset;
+
+                                       if (symbolP) {
+                                               know((S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE)
+                                                    || (S_GET_SEGMENT(symbolP) == SEG_DATA)
+                                                    || (S_GET_SEGMENT(symbolP) == SEG_TEXT));
+                                               know(symbolP->sy_frag);
+                                               know(!(S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE)
+                                                    || (symbolP->sy_frag == &zero_address_frag));
+                                               target += S_GET_VALUE(symbolP)
+                                                   + symbolP->sy_frag->fr_address;
+                                       } /* if we have a symbol */
+
+                                       know(fragP->fr_next);
+                                       after = fragP->fr_next->fr_address;
+                                       growth = ((target - after ) > 0) ? (target - after) : 0;
+                                       /* Growth may be -ve, but variable part */
+                                       /* of frag cannot have < 0 chars. */
+                                       /* That is, we can't .org backwards. */
+                                       
+                                       growth -= stretch;      /* This is an absolute growth factor */
+                                       break;
+                                       
+                               case rs_machine_dependent: {
+                                       register const relax_typeS *    this_type;
+                                       register const relax_typeS *    start_type;
+                                       register relax_substateT        next_state;
+                                       register relax_substateT        this_state;
+                                       
+                                       start_type = this_type = md_relax_table + (this_state = fragP->fr_subtype);
+                                       target = offset;
+
+                                       if (symbolP) {
+                                               know((S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) ||
+                                                    (S_GET_SEGMENT(symbolP) == SEG_DATA) ||
+                                                    (S_GET_SEGMENT(symbolP) == SEG_TEXT));
+                                               know(symbolP->sy_frag);
+                                               know(!(S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) || 
+                                                    symbolP->sy_frag==&zero_address_frag );
+                                               target +=
+                                                   S_GET_VALUE(symbolP)
+                                                       + symbolP->sy_frag->fr_address;
+                                               
+                                               /* If frag has yet to be reached on this pass,
+                                                  assume it will move by STRETCH just as we did.
+                                                  If this is not so, it will be because some frag
+                                                  between grows, and that will force another pass.  */
+                                               
+                                               /* JF was just address */
+                                               /* JF also added is_dnrange hack */
+                                               /* There's gotta be a better/faster/etc way
+                                                  to do this. . . */
+                                               /* gnu@cygnus.com:  I changed this from > to >=
+                                                  because I ran into a zero-length frag (fr_fix=0)
+                                                  which was created when the obstack needed a new
+                                                  chunk JUST AFTER the opcode of a branch.  Since
+                                                  fr_fix is zero, fr_address of this frag is the same
+                                                  as fr_address of the next frag.  This
+                                                  zero-length frag was variable and jumped to .+2
+                                                  (in the next frag), but since the > comparison
+                                                  below failed (the two were =, not >), "stretch"
+                                                  was not added to the target.  Stretch was 178, so
+                                                  the offset appeared to be .-176 instead, which did
+                                                  not fit into a byte branch, so the assembler
+                                                  relaxed the branch to a word.  This didn't compare
+                                                  with what happened when the same source file was
+                                                  assembled on other machines, which is how I found it.
+                                                  You might want to think about what other places have
+                                                  trouble with zero length frags... */
+                                               
+                                               if (symbolP->sy_frag->fr_address >= was_address
+                                                   && is_dnrange(fragP,symbolP->sy_frag)) {
+                                                       target += stretch;
+                                               } /*  */
+                                               
+                                       } /* if there's a symbol attached */
+
+                                       aim = target - address - fragP->fr_fix;
+                                       /* The displacement is affected by the instruction size
+                                        * for the 32k architecture. I think we ought to be able
+                                        * to add fragP->fr_pcrel_adjust in all cases (it should be
+                                        * zero if not used), but just in case it breaks something
+                                        * else we'll put this inside #ifdef NS32K ... #endif
+                                        */
 #ifdef TC_NS32K
-                 aim += fragP->fr_pcrel_adjust;
+                                       aim += fragP->fr_pcrel_adjust;
 #endif /* TC_NS32K */
-
-                 if (aim < 0)
-                   {
-                     /* Look backwards. */
-                     for (next_state = this_type->rlx_more;  next_state;  )
-                       {
-                         if (aim >= this_type->rlx_backward)
-                             next_state = 0;
-                         else
-                           {   /* Grow to next state. */
-                             this_type = md_relax_table + (this_state = next_state);
-                             next_state = this_type->rlx_more;
-                           }
-                       }
-                   }
-                 else
-                   {
+                                       
+                                       if (aim < 0) {
+                                               /* Look backwards. */
+                                               for (next_state = this_type->rlx_more; next_state; ) {
+                                                       if (aim >= this_type->rlx_backward) {
+                                                               next_state = 0;
+                                                       } else { /* Grow to next state. */
+                                                               this_type = md_relax_table + (this_state = next_state);
+                                                               next_state = this_type->rlx_more;
+                                                       }
+                                               }
+                                       } else {
 #ifdef DONTDEF
-/* JF these next few lines of code are for the mc68020 which can't handle short
-   offsets of zero in branch instructions.  What a kludge! */
- if (aim==0 && this_state==(1<<2+0)) { /* FOO hard encoded from m.c */
-       aim=this_type->rlx_forward+1;   /* Force relaxation into word mode */
- }
+                                               /* JF these next few lines of code are for the mc68020 which can't handle short
+                                                  offsets of zero in branch instructions.  What a kludge! */
                                              if (aim==0 && this_state==(1<<2+0)) { /* FOO hard encoded from m.c */
+                                                       aim=this_type->rlx_forward+1; /* Force relaxation into word mode */
                                              }
 #endif
-/* JF end of 68020 code */
-                     /* Look forwards. */
-                     for (next_state = this_type->rlx_more;  next_state;  )
-                       {
-                         if (aim <= this_type->rlx_forward)
-                             next_state = 0;
-                         else
-                           {   /* Grow to next state. */
-                             this_type = md_relax_table + (this_state = next_state);
-                             next_state = this_type->rlx_more;
-                           }
-                       }
-                   }
-                 if ((growth = this_type->rlx_length - start_type->rlx_length) != 0)
-                     fragP->fr_subtype = this_state;
-               }
-               break;
-
-             default:
-               BAD_CASE( fragP->fr_type );
-               break;
-             }
-           if (growth) {
-             stretch += growth;
-             stretched++;
-           }
-         }                     /* For each frag in the segment. */
-      } while (stretched);     /* Until nothing further to relax. */
-  }
+                                               /* JF end of 68020 code */
+                                               /* Look forwards. */
+                                               for (next_state = this_type->rlx_more; next_state; ) {
+                                                       if (aim <= this_type->rlx_forward) {
+                                                               next_state = 0;
+                                                       } else { /* Grow to next state. */
+                                                               this_type = md_relax_table + (this_state = next_state);
+                                                               next_state = this_type->rlx_more;
+                                                       }
+                                               }
+                                       }
 
-  /*
-   * We now have valid fr_address'es for each frag.
-   */
+                                       if ((growth = this_type->rlx_length - start_type->rlx_length) != 0)
+                                           fragP->fr_subtype = this_state;
+
+                                       break;
+                               } /* case rs_machine_dependent */
+                                       
+                               default:
+                                       BAD_CASE( fragP->fr_type );
+                                       break;
+                               }
+                               if (growth) {
+                                       stretch += growth;
+                                       stretched++;
+                               }
+                       } /* For each frag in the segment. */
+               } while (stretched);    /* Until nothing further to relax. */
+       } /* do_relax */
+       
+       /*
+        * We now have valid fr_address'es for each frag.
+        */
+       
+       /*
+        * All fr_address's are correct, relative to their own segment.
+        * We have made all the fixS we will ever make.
+        */
+} /* relax_segment() */
 
-  /*
-   * All fr_address's are correct, relative to their own segment.
-   * We have made all the fixS we will ever make.
-   */
-}                              /* relax_segment() */
-\f
 /*
  * Relax_align. Advance location counter to next address that has 'alignment'
  * lowest order bits all 0s.
@@ -895,7 +950,7 @@ register long alignment; /* Alignment (binary). */
   new_address = (address + mask) & (~ mask);
   return (new_address - address);
 } /* relax_align() */
-\f
+
 /* fixup_segment()
 
    Go through all the fixS's in a segment and see which ones can be
@@ -921,7 +976,6 @@ segT                this_segment_type; /* N_TYPE bits for segment. */
        register char pcrel;
        register fragS *fragP;
        register segT add_symbol_segment = SEG_ABSOLUTE;
-       fixS *topP = fixP;
        
        
        seg_reloc_count = 0;
@@ -1093,12 +1147,16 @@ segT            this_segment_type; /* N_TYPE bits for segment. */
        
 #ifdef OBJ_COFF
 #ifdef TC_I960
-       /* two relocs per callj under coff. */
-       for (fixP = topP; fixP; fixP = fixP->fx_next) {
-               if (fixP->fx_callj && fixP->fx_addsy != 0) {
-                       ++seg_reloc_count;
-               } /* if callj and not already fixed. */
-       } /* for each fix */
+       {
+               fixS *topP = fixP;
+               
+               /* two relocs per callj under coff. */
+               for (fixP = topP; fixP; fixP = fixP->fx_next) {
+                       if (fixP->fx_callj && fixP->fx_addsy != 0) {
+                               ++seg_reloc_count;
+                       } /* if callj and not already fixed. */
+               } /* for each fix */
+       }
 #endif /* TC_I960 */
 #endif /* OBJ_COFF */
        return(seg_reloc_count);