Thu Oct 14 11:33:25 1993 Michael Meissner (meissner@osf.org)
authorIan Lance Taylor <ian@airs.com>
Thu, 14 Oct 1993 15:41:52 +0000 (15:41 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 14 Oct 1993 15:41:52 +0000 (15:41 +0000)
* config/tc-i386.c: (md_begin): Do not zero static arrays.  Don't
call strchr for each character to see if it is a special char,
instead add a second loop over special_chars.  Set alignment
of text, data and bss sections to 4.
(pi, te, pt, pe, ps): Add declarations so that DEBUG386 can be
used again.
(reloc): Don't return 8 and 16 bit non-PC relative relocations on
ELF, since the ELF object format does not have these type of
relocations.  Change the abort into as as_bad and return
BFD_RELOC_NONE to silence compiler warnings.
(md_assemble): Keep track of the instruction size.  Allow white
space between the $ and the constant for compatibility with older
gases and other assemblers.
(i386_operand): Skip spaces between $ and expression.
(tc_gen_reloc): Don't allow anything but 32 bit relocations on
ELF.  Convert abort into an as_bad and assert into as_fatal.

gas/ChangeLog
gas/config/tc-i386.c

index c25c2bd80beed4dbd0e0030b33e8fdcee0e1581d..18aefddc14961099b8c8dd805318813362e3ec1d 100644 (file)
@@ -1,3 +1,22 @@
+Thu Oct 14 11:33:25 1993  Michael Meissner  (meissner@osf.org)
+
+       * config/tc-i386.c: (md_begin): Do not zero static arrays.  Don't
+       call strchr for each character to see if it is a special char,
+       instead add a second loop over special_chars.  Set alignment
+       of text, data and bss sections to 4.
+       (pi, te, pt, pe, ps): Add declarations so that DEBUG386 can be
+       used again.
+       (reloc): Don't return 8 and 16 bit non-PC relative relocations on
+       ELF, since the ELF object format does not have these type of
+       relocations.  Change the abort into as as_bad and return
+       BFD_RELOC_NONE to silence compiler warnings.
+       (md_assemble): Keep track of the instruction size.  Allow white
+       space between the $ and the constant for compatibility with older
+       gases and other assemblers.
+       (i386_operand): Skip spaces between $ and expression.
+       (tc_gen_reloc): Don't allow anything but 32 bit relocations on
+       ELF.  Convert abort into an as_bad and assert into as_fatal.
+
 Wed Oct 13 16:50:55 1993  Ken Raeburn  (raeburn@cambridge.cygnus.com)
 
        * config/obj-coffbfd.c (fixup_segment) [DIFF_EXPR_OK]: If
index f1d92ef69578a22466127c60dafcc2619d84859c..415e955f2d8900a1d468cb3d12e0ec195a40fead 100644 (file)
@@ -106,7 +106,7 @@ const char comment_chars[] = "#";
 /* Also note that comments started like this one will always work if
    '/' isn't otherwise defined. */
 #if defined (TE_I386AIX) || defined (OBJ_ELF)
-const char line_comment_chars[];
+const char line_comment_chars[] = "";
 #else
 const char line_comment_chars[] = "/";
 #endif
@@ -184,7 +184,8 @@ static int this_operand;    /* current operand we are working on */
 #endif
 #endif
 
-#define ENCODE_RELAX_STATE(type,size) ((type<<2) | (size))
+#define ENCODE_RELAX_STATE(type,size) \
+  ((relax_substateT)((type<<2) | (size)))
 #define SIZE_FROM_RELAX_STATE(s) \
     ( (((s) & 0x3) == BYTE ? 1 : (((s) & 0x3) == WORD ? 2 : 4)) )
 
@@ -227,7 +228,7 @@ static char *output_invalid PARAMS ((int c));
 static int i386_operand PARAMS ((char *operand_string));
 static reg_entry *parse_register PARAMS ((char *reg_string));
 #ifndef I386COFF
-static void s_bss PARAMS ((void));
+static void s_bss PARAMS ((int));
 #endif
 
 static INLINE unsigned long
@@ -237,6 +238,8 @@ mode_from_disp_size (t)
   return (t & Disp8) ? 1 : (t & Disp32) ? 2 : 0;
 }
 
+#if 0
+/* Not used.  */
 /* convert opcode suffix ('b' 'w' 'l' typically) into type specifier */
 
 static INLINE unsigned long
@@ -247,6 +250,7 @@ opcode_suffix_to_type (s)
          ? Byte : (s == WORD_OPCODE_SUFFIX
                    ? Word : DWord));
 }                              /* opcode_suffix_to_type() */
+#endif
 
 static INLINE int
 fits_in_signed_byte (num)
@@ -291,15 +295,6 @@ smallest_imm_type (num)
          : (Imm32));
 }                              /* smallest_imm_type() */
 
-/* Ignore certain directives generated by gcc. This probably should
-   not be here. */
-void
-dummy ()
-{
-  while (*input_line_pointer && *input_line_pointer != '\n')
-    input_line_pointer++;
-}
-
 const pseudo_typeS md_pseudo_table[] =
 {
 #ifndef I386COFF
@@ -339,7 +334,7 @@ static struct hash_control *prefix_hash = (struct hash_control *) 0;
 void
 md_begin ()
 {
-  char *hash_err;
+  const char *hash_err;
 
   obstack_begin (&o, 4096);
 
@@ -372,7 +367,7 @@ md_begin ()
            core_optab->end = (template *) obstack_next_free (&o);
            core_optab->start = (template *) obstack_finish (&o);
            hash_err = hash_insert (op_hash, prev_name, (char *) core_optab);
-           if (hash_err && *hash_err)
+           if (hash_err)
              {
              hash_error:
                as_fatal ("Internal Error:  Can't hash %s: %s", prev_name,
@@ -392,8 +387,8 @@ md_begin ()
 
     for (regtab = i386_regtab; regtab < i386_regtab_end; regtab++)
       {
-       hash_err = hash_insert (reg_hash, regtab->reg_name, regtab);
-       if (hash_err && *hash_err)
+       hash_err = hash_insert (reg_hash, regtab->reg_name, (PTR) regtab);
+       if (hash_err)
          goto hash_error;
       }
   }
@@ -409,21 +404,17 @@ md_begin ()
     for (prefixtab = i386_prefixtab;
         prefixtab < i386_prefixtab_end; prefixtab++)
       {
-       hash_err = hash_insert (prefix_hash, prefixtab->prefix_name, prefixtab);
-       if (hash_err && *hash_err)
+       hash_err = hash_insert (prefix_hash, prefixtab->prefix_name,
+                               (PTR) prefixtab);
+       if (hash_err)
          goto hash_error;
       }
   }
 
   /* fill in lexical tables:  opcode_chars, operand_chars, space_chars */
   {
-    register unsigned int c;
-
-    memset (opcode_chars, '\0', sizeof (opcode_chars));
-    memset (operand_chars, '\0', sizeof (operand_chars));
-    memset (space_chars, '\0', sizeof (space_chars));
-    memset (identifier_chars, '\0', sizeof (identifier_chars));
-    memset (digit_chars, '\0', sizeof (digit_chars));
+    register int c;
+    register char *p;
 
     for (c = 0; c < 256; c++)
       {
@@ -448,8 +439,6 @@ md_begin ()
 
        if (isupper (c) || islower (c) || isdigit (c))
          operand_chars[c] = c;
-       else if (c && strchr (operand_special_chars, c))
-         operand_chars[c] = c;
 
        if (isdigit (c) || c == '-')
          digit_chars[c] = c;
@@ -460,7 +449,16 @@ md_begin ()
        if (c == ' ' || c == '\t')
          space_chars[c] = c;
       }
+
+    for (p = operand_special_chars; *p != '\0'; p++)
+      operand_chars[(unsigned char) *p] = *p;
   }
+
+#ifdef OBJ_ELF
+  record_alignment (text_section, 2);
+  record_alignment (data_section, 2);
+  record_alignment (bss_section, 2);
+#endif
 }
 
 void
@@ -472,7 +470,11 @@ md_end ()
 #ifdef DEBUG386
 
 /* debugging routines for md_assemble */
-/* static void pi (), pte (), pt (), pe (), ps (); */
+static void pi PARAMS ((char *, i386_insn *));
+static void pte PARAMS ((template *));
+static void pt PARAMS ((unsigned int));
+static void pe PARAMS ((expressionS *));
+static void ps PARAMS ((symbolS *));
 
 static void
 pi (line, x)
@@ -625,18 +627,25 @@ reloc (size, pcrel)
   if (pcrel)
     switch (size)
       {
+#ifndef OBJ_ELF
       case 1: return BFD_RELOC_8_PCREL;
       case 2: return BFD_RELOC_16_PCREL;
+#endif
       case 4: return BFD_RELOC_32_PCREL;
       }
   else
     switch (size)
       {
+#ifndef OBJ_ELF
       case 1: return BFD_RELOC_8;
       case 2: return BFD_RELOC_16;
+#endif
       case 4: return BFD_RELOC_32;
       }
-  abort ();
+
+  as_bad ("Can not do %d byte %srelocation", size,
+         pcrel ? "pc-relative" : "");
+  return BFD_RELOC_NONE;
 }
 #else
 #define reloc(SIZE,PCREL)      0
@@ -651,9 +660,12 @@ void
 md_assemble (line)
      char *line;
 {
-  /* Holds temlate once we've found it. */
+  /* Holds template once we've found it. */
   register template *t;
 
+  /* Count the size of the instruction generated.  */
+  int insn_size = 0;
+
   /* Possible templates for current insn */
   templates *current_templates = (templates *) 0;
 
@@ -806,7 +818,7 @@ md_assemble (line)
                    else
                      break;    /* we are done */
                  }
-               else if (!is_operand_char (*l))
+               else if (!is_operand_char (*l) && !is_space_char (*l))
                  {
                    as_bad ("invalid character %s in %s operand",
                            output_invalid (*l),
@@ -987,13 +999,13 @@ md_assemble (line)
        /* We take i.suffix from the LAST register operand specified.  This
           assumes that the last register operands is the destination register
           operand. */
-       int o;
-       for (o = 0; o < MAX_OPERANDS; o++)
-         if (i.types[o] & Reg)
+       int op;
+       for (op = 0; op < MAX_OPERANDS; op++)
+         if (i.types[op] & Reg)
            {
-             i.suffix = (i.types[o] == Reg8) ? BYTE_OPCODE_SUFFIX :
-               (i.types[o] == Reg16) ? WORD_OPCODE_SUFFIX :
-               DWORD_OPCODE_SUFFIX;
+             i.suffix = ((i.types[op] == Reg8) ? BYTE_OPCODE_SUFFIX :
+                         (i.types[op] == Reg16) ? WORD_OPCODE_SUFFIX :
+                         DWORD_OPCODE_SUFFIX);
            }
       }
 
@@ -1113,9 +1125,9 @@ md_assemble (line)
        if (t->opcode_modifier & ShortForm)
          {
            /* The register or float register operand is in operand 0 or 1. */
-           unsigned int o = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
+           unsigned int op = (i.types[0] & (Reg | FloatReg)) ? 0 : 1;
            /* Register goes in low 3 bits of opcode. */
-           t->base_opcode |= i.regs[o]->reg_num;
+           t->base_opcode |= i.regs[op]->reg_num;
          }
        else if (t->opcode_modifier & ShortFormW)
          {
@@ -1178,7 +1190,7 @@ md_assemble (line)
                if (i.mem_operands)
                  {
                    unsigned int fake_zero_displacement = 0;
-                   unsigned int o = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2);
+                   unsigned int op = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2);
 
                    /* Encode memory operand into modrm byte and base index
                       byte. */
@@ -1188,25 +1200,25 @@ md_assemble (line)
                        /* <disp>(%esp) becomes two byte modrm with no index
                           register. */
                        i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
-                       i.rm.mode = mode_from_disp_size (i.types[o]);
+                       i.rm.mode = mode_from_disp_size (i.types[op]);
                        i.bi.base = ESP_REG_NUM;
                        i.bi.index = NO_INDEX_REGISTER;
                        i.bi.scale = 0; /* Must be zero! */
                      }
                    else if (i.base_reg == ebp && !i.index_reg)
                      {
-                       if (!(i.types[o] & Disp))
+                       if (!(i.types[op] & Disp))
                          {
                            /* Must fake a zero byte displacement.  There is
                               no direct way to code '(%ebp)' directly. */
                            fake_zero_displacement = 1;
                            /* fake_zero_displacement code does not set this. */
-                           i.types[o] |= Disp8;
+                           i.types[op] |= Disp8;
                          }
-                       i.rm.mode = mode_from_disp_size (i.types[o]);
+                       i.rm.mode = mode_from_disp_size (i.types[op]);
                        i.rm.regmem = EBP_REG_NUM;
                      }
-                   else if (!i.base_reg && (i.types[o] & BaseIndex))
+                   else if (!i.base_reg && (i.types[op] & BaseIndex))
                      {
                        /* There are three cases here.
                           Case 1:  '<32bit disp>(,1)' -- indirect absolute.
@@ -1217,8 +1229,8 @@ md_assemble (line)
                        i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
                        i.rm.mode = 0;  /* 32bit mode */
                        i.bi.base = NO_BASE_REGISTER;
-                       i.types[o] &= ~Disp;
-                       i.types[o] |= Disp32;   /* Must be 32bit! */
+                       i.types[op] &= ~Disp;
+                       i.types[op] |= Disp32;  /* Must be 32bit! */
                        if (i.index_reg)
                          {     /* case 2 or case 3 */
                            i.bi.index = i.index_reg->reg_num;
@@ -1237,14 +1249,14 @@ md_assemble (line)
                        /* Operand is just <32bit disp> */
                        i.rm.regmem = EBP_REG_NUM;
                        i.rm.mode = 0;
-                       i.types[o] &= ~Disp;
-                       i.types[o] |= Disp32;
+                       i.types[op] &= ~Disp;
+                       i.types[op] |= Disp32;
                      }
                    else
                      {
                        /* It's not a special case; rev'em up. */
                        i.rm.regmem = i.base_reg->reg_num;
-                       i.rm.mode = mode_from_disp_size (i.types[o]);
+                       i.rm.mode = mode_from_disp_size (i.types[op]);
                        if (i.index_reg)
                          {
                            i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
@@ -1254,17 +1266,17 @@ md_assemble (line)
                            if (i.base_reg == ebp && i.disp_operands == 0)
                              { /* pace */
                                fake_zero_displacement = 1;
-                               i.types[o] |= Disp8;
-                               i.rm.mode = mode_from_disp_size (i.types[o]);
+                               i.types[op] |= Disp8;
+                               i.rm.mode = mode_from_disp_size (i.types[op]);
                              }
                          }
                      }
                    if (fake_zero_displacement)
                      {
-                       /* Fakes a zero displacement assuming that i.types[o]
+                       /* Fakes a zero displacement assuming that i.types[op]
                           holds the correct displacement size. */
                        exp = &disp_expressions[i.disp_operands++];
-                       i.disps[o] = exp;
+                       i.disps[op] = exp;
                        exp->X_op = O_constant;
                        exp->X_add_number = 0;
                        exp->X_add_symbol = (symbolS *) 0;
@@ -1308,15 +1320,15 @@ md_assemble (line)
                   registers are coded into the i.rm.reg field. */
                if (i.reg_operands)
                  {
-                   unsigned int o =
+                   unsigned int op =
                    (i.types[0] & (Reg | SReg2 | SReg3 | Control | Debug | Test)) ? 0 :
                    (i.types[1] & (Reg | SReg2 | SReg3 | Control | Debug | Test)) ? 1 : 2;
                    /* If there is an extension opcode to put here, the
                       register number must be put into the regmem field. */
                    if (t->extension_opcode != None)
-                     i.rm.regmem = i.regs[o]->reg_num;
+                     i.rm.regmem = i.regs[op]->reg_num;
                    else
-                     i.rm.reg = i.regs[o]->reg_num;
+                     i.rm.reg = i.regs[op]->reg_num;
 
                    /* Now, if no memory operand has set i.rm.mode = 0, 1, 2
                       we must set it to 3 to indicate this is a register
@@ -1347,13 +1359,14 @@ md_assemble (line)
     /* Output jumps. */
     if (t->opcode_modifier & Jump)
       {
-       int n = i.disps[0]->X_add_number;
+       unsigned long n = i.disps[0]->X_add_number;
 
        if (i.disps[0]->X_op == O_constant)
          {
            if (fits_in_signed_byte (n))
              {
                p = frag_more (2);
+               insn_size += 2;
                p[0] = t->base_opcode;
                p[1] = n;
              }
@@ -1361,9 +1374,10 @@ md_assemble (line)
            else if (fits_in_signed_word (n))
              {
                p = frag_more (4);
+               insn_size += 4;
                p[0] = WORD_PREFIX_OPCODE;
                p[1] = t->base_opcode;
-               md_number_to_chars (&p[2], n, 2);
+               md_number_to_chars (&p[2], (valueT) n, 2);
              }
 #endif
            else
@@ -1372,16 +1386,18 @@ md_assemble (line)
                  {             /* pace */
                    /* unconditional jump */
                    p = frag_more (5);
+                   insn_size += 5;
                    p[0] = (char) 0xe9;
-                   md_number_to_chars (&p[1], n, 4);
+                   md_number_to_chars (&p[1], (valueT) n, 4);
                  }
                else
                  {
                    /* conditional jump */
                    p = frag_more (6);
+                   insn_size += 6;
                    p[0] = TWO_BYTE_OPCODE_ESCAPE;
                    p[1] = t->base_opcode + 0x10;
-                   md_number_to_chars (&p[2], n, 4);
+                   md_number_to_chars (&p[2], (valueT) n, 4);
                  }
              }
          }
@@ -1396,6 +1412,7 @@ md_assemble (line)
                frag_new (0);
              }
            p = frag_more (1);
+           insn_size += 1;
            p[0] = t->base_opcode;
            frag_var (rs_machine_dependent,
                      6,        /* 2 opcode/prefix + 4 displacement */
@@ -1404,33 +1421,36 @@ md_assemble (line)
                       ? ENCODE_RELAX_STATE (UNCOND_JUMP, BYTE)
                       : ENCODE_RELAX_STATE (COND_JUMP, BYTE)),
                      i.disps[0]->X_add_symbol,
-                     n, p);
+                     (long) n, p);
          }
       }
     else if (t->opcode_modifier & (JumpByte | JumpDword))
       {
        int size = (t->opcode_modifier & JumpByte) ? 1 : 4;
-       int n = i.disps[0]->X_add_number;
+       unsigned long n = i.disps[0]->X_add_number;
 
        if (fits_in_unsigned_byte (t->base_opcode))
          {
            FRAG_APPEND_1_CHAR (t->base_opcode);
+           insn_size += 1;
          }
        else
          {
            p = frag_more (2);  /* opcode can be at most two bytes */
+           insn_size += 2;
            /* put out high byte first: can't use md_number_to_chars! */
            *p++ = (t->base_opcode >> 8) & 0xff;
            *p = t->base_opcode & 0xff;
          }
 
        p = frag_more (size);
+       insn_size += size;
        if (i.disps[0]->X_op == O_constant)
          {
-           md_number_to_chars (p, n, size);
+           md_number_to_chars (p, (valueT) n, size);
            if (size == 1 && !fits_in_signed_byte (n))
              {
-               as_bad ("loop/jecx only takes byte displacement; %d shortened to %d",
+               as_bad ("loop/jecx only takes byte displacement; %lu shortened to %d",
                        n, *p);
              }
          }
@@ -1443,15 +1463,16 @@ md_assemble (line)
     else if (t->opcode_modifier & JumpInterSegment)
       {
        p = frag_more (1 + 2 + 4);      /* 1 opcode; 2 segment; 4 offset */
+       insn_size += 1 + 2 + 4;
        p[0] = t->base_opcode;
        if (i.imms[1]->X_op == O_constant)
-         md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4);
+         md_number_to_chars (p + 1, (valueT) i.imms[1]->X_add_number, 4);
        else
          fix_new_exp (frag_now, p + 1 - frag_now->fr_literal, 4,
                       i.imms[1], 0, BFD_RELOC_32);
        if (i.imms[0]->X_op != O_constant)
          as_bad ("can't handle non absolute segment in long call/jmp");
-       md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2);
+       md_number_to_chars (p + 5, (valueT) i.imms[0]->X_add_number, 2);
       }
     else
       {
@@ -1462,17 +1483,20 @@ md_assemble (line)
        for (q = i.prefix; q < i.prefix + i.prefixes; q++)
          {
            p = frag_more (1);
-           md_number_to_chars (p, (unsigned int) *q, 1);
+           insn_size += 1;
+           md_number_to_chars (p, (valueT) *q, 1);
          }
 
        /* Now the opcode; be careful about word order here! */
        if (fits_in_unsigned_byte (t->base_opcode))
          {
            FRAG_APPEND_1_CHAR (t->base_opcode);
+           insn_size += 1;
          }
        else if (fits_in_unsigned_word (t->base_opcode))
          {
            p = frag_more (2);
+           insn_size += 2;
            /* put out high byte first: can't use md_number_to_chars! */
            *p++ = (t->base_opcode >> 8) & 0xff;
            *p = t->base_opcode & 0xff;
@@ -1482,10 +1506,14 @@ md_assemble (line)
            if (t->base_opcode & 0xff000000)
              {
                p = frag_more (4);
+               insn_size += 4;
                *p++ = (t->base_opcode >> 24) & 0xff;
              }
            else
-             p = frag_more (3);
+             {
+               p = frag_more (3);
+               insn_size += 3;
+             }
            *p++ = (t->base_opcode >> 16) & 0xff;
            *p++ = (t->base_opcode >> 8) & 0xff;
            *p = (t->base_opcode) & 0xff;
@@ -1495,15 +1523,24 @@ md_assemble (line)
        if (t->opcode_modifier & Modrm)
          {
            p = frag_more (1);
+           insn_size += 1;
            /* md_number_to_chars (p, i.rm, 1); */
-           md_number_to_chars (p, (i.rm.regmem << 0 | i.rm.reg << 3 | i.rm.mode << 6), 1);
+           md_number_to_chars (p,
+                               (valueT) (i.rm.regmem << 0
+                                         | i.rm.reg << 3
+                                         | i.rm.mode << 6),
+                               1);
            /* If i.rm.regmem == ESP (4) && i.rm.mode != Mode 3 (Register mode)
                                   ==> need second modrm byte. */
            if (i.rm.regmem == ESCAPE_TO_TWO_BYTE_ADDRESSING && i.rm.mode != 3)
              {
                p = frag_more (1);
+               insn_size += 1;
                /* md_number_to_chars (p, i.bi, 1); */
-               md_number_to_chars (p, (i.bi.base << 0 | i.bi.index << 3 | i.bi.scale << 6), 1);
+               md_number_to_chars (p, (valueT) (i.bi.base << 0
+                                                | i.bi.index << 3
+                                                | i.bi.scale << 6),
+                                   1);
              }
          }
 
@@ -1520,23 +1557,33 @@ md_assemble (line)
                        if (i.types[n] & (Disp8 | Abs8))
                          {
                            p = frag_more (1);
-                           md_number_to_chars (p, i.disps[n]->X_add_number, 1);
+                           insn_size += 1;
+                           md_number_to_chars (p,
+                                               (valueT) i.disps[n]->X_add_number,
+                                               1);
                          }
                        else if (i.types[n] & (Disp16 | Abs16))
                          {
                            p = frag_more (2);
-                           md_number_to_chars (p, i.disps[n]->X_add_number, 2);
+                           insn_size += 2;
+                           md_number_to_chars (p,
+                                               (valueT) i.disps[n]->X_add_number,
+                                               2);
                          }
                        else
                          {     /* Disp32|Abs32 */
                            p = frag_more (4);
-                           md_number_to_chars (p, i.disps[n]->X_add_number, 4);
+                           insn_size += 4;
+                           md_number_to_chars (p,
+                                               (valueT) i.disps[n]->X_add_number,
+                                               4);
                          }
                      }
                    else
                      {         /* not absolute_section */
                        /* need a 32-bit fixup (don't support 8bit non-absolute disps) */
                        p = frag_more (4);
+                       insn_size += 4;
                        fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
                                     i.disps[n], 0, BFD_RELOC_32);
                      }
@@ -1558,17 +1605,26 @@ md_assemble (line)
                        if (i.types[n] & (Imm8 | Imm8S))
                          {
                            p = frag_more (1);
-                           md_number_to_chars (p, i.imms[n]->X_add_number, 1);
+                           insn_size += 1;
+                           md_number_to_chars (p,
+                                               (valueT) i.imms[n]->X_add_number,
+                                               1);
                          }
                        else if (i.types[n] & Imm16)
                          {
                            p = frag_more (2);
-                           md_number_to_chars (p, i.imms[n]->X_add_number, 2);
+                           insn_size += 2;
+                           md_number_to_chars (p,
+                                               (valueT) i.imms[n]->X_add_number,
+                                               2);
                          }
                        else
                          {
                            p = frag_more (4);
-                           md_number_to_chars (p, i.imms[n]->X_add_number, 4);
+                           insn_size += 4;
+                           md_number_to_chars (p,
+                                               (valueT) i.imms[n]->X_add_number,
+                                               4);
                          }
                      }
                    else
@@ -1583,6 +1639,7 @@ md_assemble (line)
                        else
                          size = 4;
                        p = frag_more (size);
+                       insn_size += size;
                        fix_new_exp (frag_now, p - frag_now->fr_literal, size,
                                     i.imms[n], 0, reloc (size, 0));
                      }
@@ -1696,6 +1753,7 @@ i386_operand (operand_string)
       i.imms[this_operand] = exp;
       save_input_line_pointer = input_line_pointer;
       input_line_pointer = ++op_string;        /* must advance op_string! */
+      SKIP_WHITESPACE ();
       exp_seg = expression (exp);
       input_line_pointer = save_input_line_pointer;
 
@@ -1712,7 +1770,8 @@ i386_operand (operand_string)
        }
       else if (exp->X_op == O_constant)
        {
-         i.types[this_operand] |= smallest_imm_type (exp->X_add_number);
+         i.types[this_operand] |=
+           smallest_imm_type ((unsigned long) exp->X_add_number);
        }
 #ifdef OBJ_AOUT
       else if (exp_seg != text_section
@@ -2152,7 +2211,7 @@ md_convert_frag (abfd, sec, fragP)
     }
   /* now put displacement after opcode */
   md_number_to_chars ((char *) where_to_put_displacement,
-                     displacement_from_opcode_start - extension,
+                     (valueT) (displacement_from_opcode_start - extension),
                      SIZE_FROM_RELAX_STATE (fragP->fr_subtype));
   fragP->fr_fix += extension;
 }
@@ -2172,8 +2231,8 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
   long offset;
 
   offset = to_addr - (from_addr + 2);
-  md_number_to_chars (ptr, (long) 0xeb, 1);    /* opcode for byte-disp jump */
-  md_number_to_chars (ptr + 1, offset, 1);
+  md_number_to_chars (ptr, (valueT) 0xeb, 1);  /* opcode for byte-disp jump */
+  md_number_to_chars (ptr + 1, (valueT) offset, 1);
 }
 
 void
@@ -2188,16 +2247,16 @@ md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
   if (flagseen['m'])
     {
       offset = to_addr - S_GET_VALUE (to_symbol);
-      md_number_to_chars (ptr, 0xe9, 1);       /* opcode for long jmp */
-      md_number_to_chars (ptr + 1, offset, 4);
+      md_number_to_chars (ptr, (valueT) 0xe9, 1);/* opcode for long jmp */
+      md_number_to_chars (ptr + 1, (valueT) offset, 4);
       fix_new (frag, (ptr + 1) - frag->fr_literal, 4,
               to_symbol, (offsetT) 0, 0, BFD_RELOC_32);
     }
   else
     {
       offset = to_addr - (from_addr + 5);
-      md_number_to_chars (ptr, (long) 0xe9, 1);
-      md_number_to_chars (ptr + 1, offset, 4);
+      md_number_to_chars (ptr, (valueT) 0xe9, 1);
+      md_number_to_chars (ptr + 1, (valueT) offset, 4);
     }
 }
 \f
@@ -2294,6 +2353,8 @@ md_apply_fix (fixP, val)
 }
 #endif
 
+#if 0
+/* This is never used.  */
 long                           /* Knows about the byte order in a word. */
 md_chars_to_number (con, nbytes)
      unsigned char con[];      /* Low order byte 1st. */
@@ -2307,7 +2368,7 @@ md_chars_to_number (con, nbytes)
     }
   return retval;
 }
-
+#endif /* 0 */
 \f
 
 #define MAX_LITTLENUMS 6
@@ -2356,7 +2417,7 @@ md_atof (type, litP, sizeP)
      the bigendian 386.  */
   for (wordP = words + prec - 1; prec--;)
     {
-      md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
+      md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
       litP += sizeof (LITTLENUM_TYPE);
     }
   return 0;
@@ -2439,16 +2500,13 @@ md_pcrel_from (fixP)
 #ifndef I386COFF
 
 static void
-s_bss ()
+s_bss (ignore)
+     int ignore;
 {
   register int temp;
 
   temp = get_absolute_expression ();
-#ifdef BFD_ASSEMBLER
   subseg_set (bss_section, (subsegT) temp);
-#else
-  subseg_new (bss_section, (subsegT) temp);
-#endif
   demand_empty_rest_of_line ();
 }
 
@@ -2462,38 +2520,52 @@ tc_gen_reloc (section, fixp)
      asection *section;
      fixS *fixp;
 {
-  arelent *reloc;
+  arelent *rel;
   bfd_reloc_code_real_type code;
 
 #define F(SZ,PCREL)            (((SZ) << 1) + (PCREL))
   switch (F (fixp->fx_size, fixp->fx_pcrel))
     {
 #define MAP(SZ,PCREL,TYPE)     case F(SZ,PCREL): code = (TYPE); break
+#ifndef OBJ_ELF
       MAP (1, 0, BFD_RELOC_8);
       MAP (2, 0, BFD_RELOC_16);
+#endif
       MAP (4, 0, BFD_RELOC_32);
+#ifndef OBJ_ELF
       MAP (1, 1, BFD_RELOC_8_PCREL);
       MAP (2, 1, BFD_RELOC_16_PCREL);
+#endif
       MAP (4, 1, BFD_RELOC_32_PCREL);
     default:
-      abort ();
+      as_bad ("Can not do %d byte %srelocation", fixp->fx_size,
+             fixp->fx_pcrel ? "pc-relative" : "");
     }
 #undef MAP
 #undef F
 
-  reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
-  assert (reloc != 0);
-  reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
-  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+  rel = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
+  assert (rel != 0);
+  rel->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+  rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
   if (fixp->fx_pcrel)
-    reloc->addend = fixp->fx_addnumber;
+    rel->addend = fixp->fx_addnumber;
   else
-    reloc->addend = 0;
+    rel->addend = 0;
 
-  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
-  assert (reloc->howto != 0);
+  rel->howto = bfd_reloc_type_lookup (stdoutput, code);
+  if (!rel->howto)
+    {
+      const char *name;
+
+      name = S_GET_NAME (fixp->fx_addsy);
+      if (name == NULL)
+       name = "<unknown>";
+      as_fatal ("Cannot find relocation type for symbol %s, code %d",
+               name, (int) code);
+    }
 
-  return reloc;
+  return rel;
 }
 
 #else /* ! BFD_ASSEMBLER */
@@ -2516,7 +2588,8 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
   know (fixP->fx_addsy != NULL);
 
   md_number_to_chars (where,
-       fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+                     (valueT) (fixP->fx_frag->fr_address
+                               + fixP->fx_where - segment_address_in_file),
                      4);
 
   r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)