* no more relocation_info structures. We now squirt directly from
authorK. Richard Pixley <rich@cygnus>
Wed, 14 Aug 1991 00:26:06 +0000 (00:26 +0000)
committerK. Richard Pixley <rich@cygnus>
Wed, 14 Aug 1991 00:26:06 +0000 (00:26 +0000)
  fixS's.

* i960-bout and i960-coff "tested" against their predecessors.

gas/config/obj-bout.c
gas/config/obj-bout.h
gas/config/tc-a29k.c
gas/config/tc-i960.c
gas/config/tc-m68k.c
gas/config/tc-sparc.c

index b759ff040b401cd13ce56559b42ab67177d9123c..74cd5f7b510f31e7a5b27e8f86caba292a65f00a 100644 (file)
@@ -93,16 +93,6 @@ const pseudo_typeS obj_pseudo_table[] = {
 
 /* Relocation. */
 
-/*
- * In: length of relocation (or of address) in chars: 1, 2 or 4.
- * Out: GNU LD relocation length code: 0, 1, or 2.
- */
-
-static unsigned char
-nbytes_r_length [] = {
-  42, 0, 1, 42, 2
-  };
-
 /*
  *             emit_relocations()
  *
@@ -113,40 +103,13 @@ char **where;
 fixS *fixP;    /* Fixup chain for this segment. */
 relax_addressT segment_address_in_file;
 {
-       struct relocation_info  ri;
-       register symbolS *              symbolP;
-       
-       /* If a machine dependent emitter is needed, call it instead. */
-       if (md_emit_relocations) {
-               (*md_emit_relocations) (fixP, segment_address_in_file);
-               return;
-       }
-       
-       
-       /* JF this is for paranoia */
-       bzero((char *)&ri,sizeof(ri));
-       for (;  fixP;  fixP = fixP->fx_next) {
-               if ((symbolP = fixP->fx_addsy) != 0) {
-                       ri . r_bsr              = fixP->fx_bsr;
-                       ri . r_disp             = fixP->fx_im_disp;
-                       ri . r_callj            = fixP->fx_callj;
-                       ri . r_length           = nbytes_r_length [fixP->fx_size];
-                       ri . r_pcrel            = fixP->fx_pcrel;
-                       ri . r_address  = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file;
-                       
-                       if (S_GET_TYPE(symbolP) == N_UNDF) {
-                               ri . r_extern   = 1;
-                               ri . r_symbolnum        = symbolP->sy_number;
-                       } else {
-                               ri . r_extern   = 0;
-                               ri . r_symbolnum        = S_GET_TYPE(symbolP);
-                       }
-                       
-                       /* Output the relocation information in machine-dependent form. */
-                       md_ri_to_chars(*where, &ri);
-                       *where += md_reloc_size;
-               }
-       }
+       for (; fixP; fixP = fixP->fx_next) {
+               if (fixP->fx_addsy != NULL) {
+                       tc_bout_fix_to_chars(*where, fixP, segment_address_in_file);
+                       where += sizeof(struct relocation_info);
+               } /* if there's a symbol */
+       } /* for each fixup */
+
 } /* emit_relocations() */
 
 /* Aout file generation & utilities */
@@ -168,7 +131,7 @@ object_headers *headers;
        headers->header.a_balign = section_alignment[SEG_BSS];
 
        headers->header.a_tload = 0;
-       headers->header.a_dload = md_section_align(SEG_DATA, headers->header.a_text);
+       headers->header.a_dload = md_section_align(SEG_DATA, H_GET_TEXT_SIZE(headers));
 
        append(where, (char *) &headers->header, sizeof(headers->header));
 } /* a_header_append() */
index 00ba2a408dc6b49ffd3e8259867c0244960412ba..1b0743e3e2dd15ec7e4658149d40f8db2e2c3814 100644 (file)
@@ -247,6 +247,7 @@ struct relocation_info {
                                 H_GET_DATA_RELOCATION_SIZE(h) + \
                                 (h)->string_table_size)
 
+#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)
@@ -256,6 +257,8 @@ struct relocation_info {
 #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 */
@@ -263,9 +266,9 @@ struct relocation_info {
 #define H_GET_VERSION(h)               ((h)->header.a_version)
 #endif /* EXEC_VERSION */
 
-#define H_SET_TEXT_SIZE(h,v)           ((h)->header.a_text = md_section_align(SEG_TEXT, (v)))
-#define H_SET_DATA_SIZE(h,v)           ((h)->header.a_data = md_section_align(SEG_DATA, (v)))
-#define H_SET_BSS_SIZE(h,v)            ((h)->header.a_bss = md_section_align(SEG_BSS, (v)))
+#define H_SET_TEXT_SIZE(h,v)           ((h)->header.a_text = (v))
+#define H_SET_DATA_SIZE(h,v)           ((h)->header.a_data = (v))
+#define H_SET_BSS_SIZE(h,v)            ((h)->header.a_bss = (v))
 
 #define H_SET_RELOCATION_SIZE(h,t,d)   (H_SET_TEXT_RELOCATION_SIZE((h),(t)),\
                                         H_SET_DATA_RELOCATION_SIZE((h),(d)))
@@ -302,6 +305,13 @@ typedef struct {
 #define OBJ_EMIT_LINENO(a, b, c)       ;
 #define obj_pre_write_hook(a)          ;
 
+#ifdef __STDC__
+struct fix;
+void tc_aout_fix_to_chars(char *where, struct fix *fixP, relax_addressT segment_address);
+#else
+void tc_aout_fix_to_chars();
+#endif /* __STDC__ */
+
 /*
  * Local Variables:
  * comment-column: 0
index fecdc5d2e9da8a1dbd85fcd110eb150664ffebd9..80a6382ba7caf197382753c530060efc1b1c2416 100644 (file)
@@ -903,29 +903,6 @@ symbolS *to_symbol;
     abort();
 }
 
-/* Translate internal representation of relocation info to target format.
-
-   On sparc/29k: first 4 bytes are normal unsigned long address, next three
-   bytes are index, most sig. byte first.  Byte 7 is broken up with
-   bit 7 as external, bits 6 & 5 unused, and the lower
-   five bits as relocation type.  Next 4 bytes are long addend. */
-/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
-void
-md_ri_to_chars(the_bytes, ri)
-     char *the_bytes;
-     struct reloc_info_generic *ri;
-{
-  /* this is easy */
-  md_number_to_chars(the_bytes, ri->r_address, 4);
-  /* now the fun stuff */
-  the_bytes[4] = (ri->r_index >> 16) & 0x0ff;
-  the_bytes[5] = (ri->r_index >> 8) & 0x0ff;
-  the_bytes[6] = ri->r_index & 0x0ff;
-  the_bytes[7] = ((ri->r_extern << 7)  & 0x80) | (0 & 0x60) | (ri->r_type & 0x1F);
-  /* Also easy */
-  md_number_to_chars(&the_bytes[8], ri->r_addend, 4);
-}
-
 /* should never be called for 29k */
 void md_convert_frag(headers, fragP)
 object_headers *headers;
@@ -1012,48 +989,45 @@ print_insn(insn)
 }
 #endif
 
-/*
- * Sparc/A29K relocations are completely different, so it needs
- * this machine dependent routine to emit them.
- */
-#ifdef OBJ_AOUT
-static void emit_machine_reloc(fixP, segment_address_in_file)
-register fixS *fixP;
-relax_addressT segment_address_in_file;
-{
-    struct reloc_info_generic ri;
-    register symbolS *symbolP;
-    extern char *next_object_file_charP;
-/* !!!!    long add_number; */
-
-    bzero((char *) &ri, sizeof(ri));
-    for (; fixP; fixP = fixP->fx_next) {
+/* Translate internal representation of relocation info to target format.
 
-       if (fixP->fx_r_type >= NO_RELOC) {
-           fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
-           abort();
-       }
+   On sparc/29k: first 4 bytes are normal unsigned long address, next three
+   bytes are index, most sig. byte first.  Byte 7 is broken up with
+   bit 7 as external, bits 6 & 5 unused, and the lower
+   five bits as relocation type.  Next 4 bytes are long addend. */
+/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
 
-       if ((symbolP = fixP->fx_addsy) != NULL) {
-           ri.r_address = fixP->fx_frag->fr_address +
-               fixP->fx_where - segment_address_in_file;
-           ri.r_addend = fixP->fx_addnumber;
-           if (!S_IS_DEFINED(symbolP)) {
-               ri.r_extern = 1;
-               ri.r_index = symbolP->sy_number;
-           } else {
-               ri.r_extern = 0;
-               ri.r_index = S_GET_TYPE(symbolP);
-           }
-           ri.r_type = fixP->fx_r_type;
+#ifdef OBJ_AOUT
 
-           md_ri_to_chars (next_object_file_charP, &ri);
-           next_object_file_charP += md_reloc_size;
-       }
-    }
-} /* emit_machine_reloc() */
+void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
+char *where;
+fixS *fixP;
+relax_addressT segment_address_in_file;
+{
+       long r_index;
+       
+       know(fixP->fx_r_type < NO_RELOC);
+       know(fixP->fx_addsy != NULL);
+       
+       r_index = (S_IS_DEFINED(fixP->fx_addsy)
+                  ? S_GET_TYPE(fixP->fx_addsy)
+                  : fixP->fx_addsy->sy_number);
+       
+       /* this is easy */
+       md_number_to_chars(where,
+                          fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+                          4);
+       
+       /* now the fun stuff */
+       where[4] = (r_index >> 16) & 0x0ff;
+       where[5] = (r_index >> 8) & 0x0ff;
+       where[6] = r_index & 0x0ff;
+       where[7] = (((!S_IS_DEFINED(fixP->fx_addsy)) << 7)  & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
+       /* Also easy */
+       md_number_to_chars(&where[8], fixP->fx_addnumber, 4);
 
-void (*md_emit_relocations)() = emit_machine_reloc;
+       return;
+} /* tc_aout_fix_to_chars() */
 
 #endif /* OBJ_AOUT */
 
index a32325b12d45d8736ec1199ee94e4711895d7ea7..a5513762cec0bcaa517f105d6cd9b4157fa3002b 100644 (file)
@@ -5,7 +5,7 @@ This file is part of GAS.
 
 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,
@@ -86,7 +86,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 extern char *input_line_pointer;
 extern struct hash_control *po_hash;
-extern unsigned char nbytes_r_length[];
 extern char *next_object_file_charP;
 
 #ifdef OBJ_COFF
@@ -95,20 +94,6 @@ int md_reloc_size = sizeof(struct reloc);
 int md_reloc_size = sizeof(struct relocation_info);
 #endif /* OBJ_COFF */
 
-#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
-#ifdef __STDC__
-
-static void emit_machine_reloc(fixS *fixP, relax_addressT segment_address_in_file);
-
-#else /* __STDC__ */
-
-static void emit_machine_reloc();
-
-#endif /* __STDC__ */
-
-void (*md_emit_relocations)() = emit_machine_reloc;
-#endif /* OBJ_AOUT or OBJ_BOUT */
-
        /***************************
         *  Local i80960 routines  *
         ************************** */
@@ -621,6 +606,8 @@ md_number_to_chars(buf, value, n)
        if (value != 0 && value != -1){
                as_bad("Displacement too long for instruction field length.");
        }
+
+       return;
 } /* md_number_to_chars() */
 
 /*****************************************************************************
@@ -892,7 +879,8 @@ md_parse_option(argP, cntP, vecP)
  *
  **************************************************************************** */
 void
-md_convert_frag(fragP)
+md_convert_frag(headers, fragP)
+object_headers *headers;
     fragS * fragP;
 {
        fixS *fixP;     /* Structure describing needed address fix */
@@ -959,27 +947,13 @@ md_estimate_size_before_relax(fragP, segment_type)
  *     we leave it in host byte order.
  *
  **************************************************************************** */
-void md_ri_to_chars(the_bytes, ri)
-char *the_bytes;
-struct reloc_info_generic *ri;
+void md_ri_to_chars(where, ri)
+char *where;
+struct relocation_info *ri;
 {
-       struct relocation_info br;
-
-       (void) bzero(&br, sizeof(br));
-
-       br.r_address = ri->r_address;
-       br.r_index = ri->r_index;
-       br.r_pcrel = ri->r_pcrel;
-       br.r_length = ri->r_length;
-       br.r_extern = ri->r_extern;
-       br.r_bsr = ri->r_bsr;
-       br.r_disp = ri->r_disp;
-       br.r_callj = ri->r_callj;
-
-       *((struct relocation_info *) the_bytes) = br;
+       *((struct relocation_info *) where) = *ri; /* structure assignment */
 } /* md_ri_to_chars() */
 
-
 #ifndef WORKING_DOT_WORD
 
 int md_short_jump_size = 0;
@@ -1393,14 +1367,14 @@ get_ispec(textP)
 
        /* Find opening square bracket, if any
         */
-       start = index(textP, '[');
+       start = strchr(textP, '[');
 
        if (start != NULL){
 
                /* Eliminate '[', detach from rest of operand */
                *start++ = '\0';
 
-               end = index(start, ']');
+               end = strchr(start, ']');
 
                if (end == NULL){
                        as_bad("unmatched '['");
@@ -2569,54 +2543,41 @@ md_apply_fix(fixP, val)
 } /* md_apply_fix() */
 
 #if defined(OBJ_AOUT) | defined(OBJ_BOUT)
-/*
- *             emit_relocations()
- *
- * Crawl along a fixS chain. Emit the segment's relocations.
- */
-static void
-emit_machine_reloc (fixP, segment_address_in_file)
-     register fixS *   fixP;   /* Fixup chain for this segment. */
-     relax_addressT    segment_address_in_file;
+void tc_bout_fix_to_chars(where, fixP, segment_address_in_file)
+char *where;
+fixS *fixP;
+relax_addressT segment_address_in_file;
 {
-  struct reloc_info_generic    ri;
-  register symbolS *           symbolP;
-
+       static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 };
+       struct relocation_info ri;
+       symbolS *symbolP;
+       
        /* JF this is for paranoia */
-  bzero((char *)&ri,sizeof(ri));
-  for (;  fixP;  fixP = fixP->fx_next)
-    {
-      if ((symbolP = fixP->fx_addsy) != 0)
-       {
-         /* These two 'cuz of NS32K */
-         ri . r_bsr            = fixP->fx_bsr;
-         ri . r_disp           = fixP->fx_im_disp;
-
-         ri . r_callj          = fixP->fx_callj;
-
-         ri . r_length         = nbytes_r_length [fixP->fx_size];
-         ri . r_pcrel          = fixP->fx_pcrel;
-         ri . r_address        = fixP->fx_frag->fr_address
-           +   fixP->fx_where
-             - segment_address_in_file;
-         if (!S_IS_DEFINED(symbolP))
-           {
-             ri . r_extern     = 1;
-             ri . r_symbolnum  = symbolP->sy_number;
-           }
-         else
-           {
-             ri . r_extern     = 0;
-             ri . r_symbolnum  = S_GET_TYPE(symbolP);
-           }
-
-         /* Output the relocation information in machine-dependent form. */
-         md_ri_to_chars(next_object_file_charP, &ri);
-         next_object_file_charP += sizeof(struct relocation_info);
+       bzero((char *)&ri, sizeof(ri));
+       
+       know((symbolP = fixP->fx_addsy) != 0);
+       
+       /* These two 'cuz of NS32K */
+       ri.r_callj = fixP->fx_callj;
+       
+       ri.r_length = nbytes_r_length[fixP->fx_size];
+       ri.r_pcrel = fixP->fx_pcrel;
+       ri.r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file;
+       
+       if (!S_IS_DEFINED(symbolP)) {
+               ri.r_extern = 1;
+               ri.r_index = symbolP->sy_number;
+       } else {
+               ri.r_extern = 0;
+               ri.r_index = S_GET_TYPE(symbolP);
        }
-    }
+       
+       /* Output the relocation information in machine-dependent form. */
+       md_ri_to_chars(where, &ri);
+       
+       return;
+} /* tc_bout_fix_to_chars() */
 
-} /* emit_machine_reloc() */
 #endif /* OBJ_AOUT or OBJ_BOUT */
 
 /* Align an address by rounding it up to the specified boundary.
index 9c30a040b8420e81853598cad457c67dee7bd0d5..c6924dbedfcdeec7f2d54ee517abdbd8622e8159 100644 (file)
@@ -1009,7 +1009,7 @@ static struct hash_control*   op_hash = NULL;     /* handle of the OPCODE hash table
  * No argument string should generate such an error string:
  * it means a bug in our code, not in the user's text.
  *
- * You MUST have called m86_ip_begin() once and m86_ip_end() never before using
+ * You MUST have called m68_ip_begin() once and m86_ip_end() never before using
  * this function.
  */
 
@@ -1068,9 +1068,13 @@ char     *instring;
        }
 
   /* found a legitimate opcode, start matching operands */
-       for(opP= &the_ins.operands[0];*p;opP++) {
-               p = crack_operand (p, opP);
-               if(opP->error) {
+       while (*p == ' ') ++p;
+
+       for(opP = &the_ins.operands[0]; *p; opP++) {
+
+               p = crack_operand(p, opP);
+
+               if (opP->error) {
                        the_ins.error=opP->error;
                        return;
                }
@@ -3089,6 +3093,7 @@ bit 7 as pcrel, bits 6 & 5 as length, bit 4 as pcrel, and the lower
 nibble as nuthin. (on Sun 3 at least) */
 /* Translate the internal relocation information into target-specific
    format. */
+#ifdef comment
 void
 md_ri_to_chars(the_bytes, ri)
      char *the_bytes;
@@ -3103,6 +3108,46 @@ md_ri_to_chars(the_bytes, ri)
   the_bytes[7] = (((ri->r_pcrel << 7)  & 0x80) | ((ri->r_length << 5) & 0x60) | 
     ((ri->r_extern << 4)  & 0x10)); 
 }
+#endif /* comment */
+
+void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
+char *where;
+fixS *fixP;
+relax_addressT segment_address_in_file;
+{
+       /*
+        * In: length of relocation (or of address) in chars: 1, 2 or 4.
+        * Out: GNU LD relocation length code: 0, 1, or 2.
+        */
+       
+       static unsigned char nbytes_r_length [] = { 42, 0, 1, 42, 2 };
+       
+       long r_extern;
+       long r_symbolnum;
+       
+       /* this is easy */
+       md_number_to_chars(where,
+                          fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+                          4);
+       
+       /* now the fun stuff */
+       if (S_GET_TYPE(fixP->fx_addsy) == N_UNDF) {
+               r_extern        = 1;
+               r_symbolnum     = fixP->fx_addsy->sy_number;
+       } else {
+               r_extern        = 0;
+               r_symbolnum     = S_GET_TYPE(fixP->fx_addsy);
+       }
+       
+       where[4] = (r_symbolnum >> 16) & 0x0ff;
+       where[5] = (r_symbolnum >> 8) & 0x0ff;
+       where[6] = r_symbolnum & 0x0ff;
+       where[7] = (((fixP->fx_pcrel << 7)  & 0x80) | ((nbytes_r_length[fixP->fx_size] << 5) & 0x60) | 
+                   ((r_extern << 4)  & 0x10)); 
+       
+       return;
+} /* tc_aout_fix_to_chars() */
+
 #endif /* OBJ_AOUT or OBJ_BOUT */
 
 #ifndef WORKING_DOT_WORD
index 47fdbd2660aad654e3a71fc8907270bed4122337..1f41129708b650baa4b6bde242b0cc056256b923 100644 (file)
@@ -42,7 +42,7 @@ static void sparc_ip();
 
 static enum sparc_architecture current_architecture = v6;
 static int architecture_requested = 0;
-static int warn_on_bump = 1;
+static int warn_on_bump = 0;
 
 const relax_typeS md_relax_table[] = {
        0 };
@@ -428,7 +428,7 @@ char *str;
        struct sparc_opcode *insn;
        char *argsStart;
        unsigned long opcode;
-       unsigned int mask;
+       unsigned int mask = 0;
        int match = 0;
        int comma = 0;
        
@@ -787,44 +787,134 @@ char *str;
  /* start-sanitize-v9 */
 #ifndef NO_V9
                        case 'j':
+                       case 'u':
+                       case 'U':
 #endif /* NO_V9 */
  /* end-sanitize-v9 */
                        case 'e': /* next operand is a floating point register */
+                       case 'v':
+                       case 'V':
+
                        case 'f':
+                       case 'B':
+                       case 'R':
+
                        case 'g':
-                               if (*s++ == '%' && *s++ == 'f' && isdigit(*s)) {
-                                       mask = *s++;
-                                       if (isdigit(*s)) {
-                                               mask = 10 * (mask - '0') + (*s++ - '0');
+                       case 'H':
+                       case 'J': {
+                               char format;
+
+                               if (*s++ == '%'
+
+ /* start-sanitize-v9 */
+#ifndef NO_V9
+                                   && ((format = *s) == 'f'
+                                   || *s == 'd'
+                                   || *s == 'q')
+#else
+ /* end-sanitize-v9 */
+                                   && ((format = *s) == 'f')
+
+ /* start-sanitize-v9 */
+#endif /* NO_V9 */
+ /* end-sanitize-v9 */
+                                   && isdigit(*++s)) {
+
+
+
+                                       for (mask = 0; isdigit(*s); ++s) {
+                                               mask = 10 * mask + (*s - '0');
+                                       } /* read the number */
+
+                                       if ((*args == 'u'
+                                            || *args == 'v'
+                                            || *args == 'B'
+                                            || *args == 'H')
+                                           && (mask & 1)) {
+                                               break;
+                                       } /* register must be even numbered */
+
+                                       if ((*args == 'U'
+                                            || *args == 'V'
+                                            || *args == 'R'
+                                            || *args == 'J')
+                                           && (mask & 3)) {
+                                               break;
+                                       } /* register must be multiple of 4 */
+
+                                       if (format == 'f') {
                                                if (mask >= 32) {
-                                                       break;
-                                               }
+                                                       error_message = ": There are only 32 f registers; [0-31]";
+                                                       goto error;
+                                               } /* on error */
+ /* start-sanitize-v9 */
+#ifndef NO_V9
                                        } else {
-                                               mask -= '0';
-                                       }
-                                       switch (*args) {
-                                               
-                                       case 'e':
-                                               opcode |= RS1(mask);
-                                               continue;
-                                               
-                                       case 'f':
-                                               opcode |= RS2(mask);
-                                               continue;
+                                               if (format == 'd') {
+                                                       if (mask >= 64) {
+                                                               error_message = ": There are only 32 d registers [0, 2, ... 62].";
+                                                               goto error;
+                                                       } else if (mask & 1) {
+                                                               error_message = ": Only even numbered d registers exist.";
+                                                               goto error;
+                                                       } /* on error */
+                                                       
+                                               } else if (format == 'q') {
+                                                       if (mask >= 64) {
+                                                               error_message =
+                                                                   ": There are only 16 q registers [0, 4, ... 60].";
+                                                               goto error;
+                                                       } else if (mask & 3) {
+                                                               error_message =
+                                                                   ": Only q registers evenly divisible by four exist.";
+                                                               goto error;
+                                                       } /* on error */
+                                               } else {
+                                                       know(0);
+                                               } /* depending on format */
                                                
-                                       case 'g':
-                                               opcode |= RD(mask);
-                                               continue;
+                                               if (mask >= 32) {
+                                                       mask -= 31;
+                                               } /* wrap high bit */
+                                       } /* if not an 'f' register. */
+#endif /* NO_V9 */
+ /* end-sanitize-v9 */
+                               } /* on error */
+
+                               switch (*args) {
  /* start-sanitize-v9 */
 #ifndef NO_V9
-                                       case 'j':
-                                               opcode |= (mask & 0x1f) << 9;
-                                               continue;
+                               case 'j':
+                               case 'u':
+                               case 'U':
+                                       opcode |= (mask & 0x1f) << 9;
+                                       continue;
 #endif /* NO_V9 */
  /* end-sanitize-v9 */
-                                       }
-                               }
+
+                               case 'v':
+                               case 'V':
+                               case 'e':
+                                       opcode |= RS1(mask);
+                                       continue;
+                                       
+
+                               case 'f':
+                               case 'B':
+                               case 'R':
+                                       opcode |= RS2(mask);
+                                       continue;
+                                       
+                               case 'g':
+                               case 'H':
+                               case 'J':
+                                       opcode |= RD(mask);
+                                       continue;
+                               } /* pack it in. */
+
+                               know(0);
                                break;
+                       } /* float arg */
                                
                        case 'F':
                                if (strncmp(s, "%fsr", 4) == 0) {
@@ -1208,28 +1298,20 @@ long val;
  /* start-sanitize-v9 */
 #ifndef NO_V9
        case RELOC_11:
-#if 0
-               /* ??? Bogus overflow test.  This is a signed value, so
-                  the upper bits can be set if the sign bit is set.  */
-               if (val & ~0x7ff) {
+               if (((val > 0) && (val & ~0x7ff))
+                   || ((val < 0) && (~val & ~0x7ff))) {
                        as_bad("relocation overflow.");
                } /* on overflow */
-#endif
 
                buf[2] = (val >> 8) & 0x7;
                buf[3] = val & 0xff;
                break;
 
        case RELOC_WDISP2_14:
-#if 0
-               /* ??? Bogus overflow test.  This is a signed value, so
-                  the upper bits can be set if the sign bit is set.  */
-               /* ??? This tests the wrong 16 bits also, should test
-                  ~0x3fffc0.  */
-               if (val & ~0xffff) {
+               if (((val > 0) && (val & ~0x3fffc))
+                   || ((val < 0) && (~val & ~0x3fffc))) {
                        as_bad("relocation overflow.");
                } /* on overflow */
-#endif
 
                val = (val >>= 2) + 1;
                buf[1] |= ((val >> 14) & 0x3) << 3;
@@ -1238,15 +1320,10 @@ long val;
                break;
 
        case RELOC_WDISP19:
-#if 0
-               /* ??? Bogus overflow test.  This is a signed value, so
-                  the upper bits can be set if the sign bit is set.  */
-               /* ??? This tests the wrong 19 bits also, should test
-                  ~0x1ffffc0.  */
-               if (val & ~0x7ffff) {
+               if (((val > 0) && (val & ~0x1ffffc))
+                   || ((val < 0) && (~val & ~0x1ffffc))) {
                        as_bad("relocation overflow.");
                } /* on overflow */
-#endif
 
                val = (val >>= 2) + 1;
                buf[1] |= (val >> 16) & 0x7;
@@ -1255,7 +1332,7 @@ long val;
                break;
 
        case RELOC_HHI22:
-               val >> 32;
+               val >>= 32;
  /* intentional fallthrough */
 #endif /* NO_V9 */
  /* end-sanitize-v9 */
@@ -1345,23 +1422,56 @@ symbolS *to_symbol;
    bit 7 as external, bits 6 & 5 unused, and the lower
    five bits as relocation type.  Next 4 bytes are long addend. */
 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
-void md_ri_to_chars(the_bytes, ri)
-char *the_bytes;
-struct reloc_info_generic *ri;
+void tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
+char *where;
+fixS *fixP;
+relax_addressT segment_address_in_file;
 {
+       long r_index;
+       long r_extern;
+       long r_addend;
+       long r_address;
+
+       know(fixP->fx_addsy);
+
+       if ((S_GET_TYPE(fixP->fx_addsy)) == N_UNDF) {
+               r_extern = 1;
+               r_index = fixP->fx_addsy->sy_number;
+       } else {
+               r_extern = 0;
+               r_index = S_GET_TYPE(fixP->fx_addsy);
+       }
+                       
        /* this is easy */
-       md_number_to_chars(the_bytes, ri->r_address, 4);
+       md_number_to_chars(where,
+                          r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+                          4);
+
        /* now the fun stuff */
-       the_bytes[4] = (ri->r_index >> 16) & 0x0ff;
-       the_bytes[5] = (ri->r_index >> 8) & 0x0ff;
-       the_bytes[6] = ri->r_index & 0x0ff;
-       the_bytes[7] = ((ri->r_extern << 7)  & 0x80) | (0 & 0x60) | (ri->r_type & 0x1F);
+       where[4] = (r_index >> 16) & 0x0ff;
+       where[5] = (r_index >> 8) & 0x0ff;
+       where[6] = r_index & 0x0ff;
+       where[7] = ((r_extern << 7)  & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
+
        /* Also easy */
-       md_number_to_chars(&the_bytes[8], ri->r_addend, 4);
-} /* md_ri_to_chars() */
+       if (fixP->fx_addsy->sy_frag) {
+               r_addend = fixP->fx_addsy->sy_frag->fr_address;
+       }
+       
+       if (fixP->fx_pcrel) {
+               r_addend -= r_address;
+       } else {
+               r_addend = fixP->fx_addnumber;
+       }
+       
+       md_number_to_chars(&where[8], r_addend, 4);
+
+       return;
+} /* tc_aout_fix_to_chars() */
 
 /* should never be called for sparc */
-void md_convert_frag(fragP)
+void md_convert_frag(headers, fragP)
+object_headers *headers;
 register fragS *fragP;
 {
        fprintf(stderr, "sparc_convert_frag\n");
@@ -1450,8 +1560,10 @@ struct sparc_it *insn;
 
 /* Set the hook... */
 
-void emit_sparc_reloc();
-void (*md_emit_relocations)() = emit_sparc_reloc;
+/* void emit_sparc_reloc();
+void (*md_emit_relocations)() = emit_sparc_reloc; */
+
+#ifdef comment
 
 /*
  * Sparc/AM29K relocations are completely different, so it needs
@@ -1503,6 +1615,7 @@ relax_addressT segment_address_in_file;
        return;
 } /* emit_sparc_reloc() */
 #endif /* aout or bout */
+#endif /* comment */
 
 /*
  * md_parse_option