* config/tc-sh.c (sh_relax): Rename from relax, and make global.
authorIan Lance Taylor <ian@airs.com>
Wed, 19 Jul 1995 16:14:49 +0000 (16:14 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 19 Jul 1995 16:14:49 +0000 (16:14 +0000)
Renamed all uses.
(insert): Pass a size of 2, not 4.
(build_relax): Remove unused len variable.
(md_show_usage): Mention -little option.
(md_convert_frag): Add segT argument.  Rewrite to generate relocs
rather than to generate complete instructions here.
(md_apply_fix): Adjust and clarify R_SH_PCRELIMM8BY4 case for
changes in insert and md_pcrel_from.  Add cases for R_SH_PCDISP
and R_SH_PCDISP8BY2.
(md_pcrel_from): Don't subtract 1, add 2.
(tc_coff_fix2rtype): Remove.
(sh_coff_reloc_mangle): New function.
* config/tc-sh.h (TC_COFF_FIX2RTYPE): Just return fx_r_type.
(sh_relax): Declare.
(TC_COUNT_RELOC): If relaxing, count PC relative relocs.
(TC_RELOC_MANGLE): Define.
(sh_coff_reloc_mangle): Declare.
(tc_coff_sizemachdep): Declare.
* tc.h (md_convert_frag): Add segT parameter to non BFD_ASSEMBLER
declaration.
* write.c (cvt_frag_to_fill): Add sec argument to non
BFD_ASSEMBLER version.  Pass it to md_convert_frag.
(write_object_file): Pass SEG_TEXT to cvs_frag_to_fill.
* config/obj-coff.c (do_relocs_for): Pass segment info to
TC_RELOC_MANGLE.
(fixup_mdeps): Pass segment type to md_convert_frag.
* config/tc-a29k.c (md_convert_frag): Add segT argument.
* config/tc-h8300.c (md_convert_frag): Likewise.
* config/tc-h8500.c (md_convert_frag): Likewise.
* config/tc-i386.c (md_convert_frag): Likewise.
* config/tc-i860.c (md_convert_frag): Likewise.
* config/tc-i960.c (md_convert_frag): Likewise.
* config/tc-m68k.c (md_convert_frag): Likewise.
* config/tc-m88k.h (md_convert_frag): Likewise.
* config/tc-ns32k.c (md_convert_frag): Likewise.
* config/tc-rce.c (md_convert_frag): Likewise.
* config/tc-tahoe.c (md_convert_frag): Likewise.
* config/tc-vax.c (md_convert_frag): Likewise.
* config/tc-w65.c (md_convert_frag): Likewise.
* config/tc-z8k.c (md_convert_frag): Likewise.
* config/tc-h8300.h (TC_RELOC_MANGLE): Add segment argument.
* config/tc-h8500.h (TC_RELOC_MANGLE): Likewise.
* config/tc-rce.h (TC_RELOC_MANGLE): Likewise.
* config/tc-w65.h (TC_RELOC_MANGLE): Likewise.
* config/tc-z8k.h (TC_RELOC_MANGLE): Likewise.

gas/ChangeLog
gas/config/tc-a29k.c
gas/config/tc-h8500.c
gas/config/tc-h8500.h
gas/config/tc-m68k.c
gas/config/tc-m88k.h
gas/config/tc-rce.c
gas/config/tc-rce.h
gas/config/tc-tahoe.c
gas/config/tc-w65.c
gas/config/tc-w65.h

index 81e46af6c830918df6ff39ef3c6ce8a027caf6fe..ca7975989241705aae0e6e751199fdecbef118f4 100644 (file)
@@ -1,3 +1,66 @@
+Wed Jul 19 11:49:25 1995  Ian Lance Taylor  <ian@cygnus.com>
+
+       * config/tc-sh.c (sh_relax): Rename from relax, and make global.
+       Renamed all uses.
+       (insert): Pass a size of 2, not 4.
+       (build_relax): Remove unused len variable.
+       (md_show_usage): Mention -little option.
+       (md_convert_frag): Add segT argument.  Rewrite to generate relocs
+       rather than to generate complete instructions here.
+       (md_apply_fix): Adjust and clarify R_SH_PCRELIMM8BY4 case for
+       changes in insert and md_pcrel_from.  Add cases for R_SH_PCDISP
+       and R_SH_PCDISP8BY2.
+       (md_pcrel_from): Don't subtract 1, add 2.
+       (tc_coff_fix2rtype): Remove.
+       (sh_coff_reloc_mangle): New function.
+       * config/tc-sh.h (TC_COFF_FIX2RTYPE): Just return fx_r_type.
+       (sh_relax): Declare.
+       (TC_COUNT_RELOC): If relaxing, count PC relative relocs.
+       (TC_RELOC_MANGLE): Define.
+       (sh_coff_reloc_mangle): Declare.
+       (tc_coff_sizemachdep): Declare.
+       * tc.h (md_convert_frag): Add segT parameter to non BFD_ASSEMBLER
+       declaration.
+       * write.c (cvt_frag_to_fill): Add sec argument to non
+       BFD_ASSEMBLER version.  Pass it to md_convert_frag.
+       (write_object_file): Pass SEG_TEXT to cvs_frag_to_fill.
+       * config/obj-coff.c (do_relocs_for): Pass segment info to
+       TC_RELOC_MANGLE.
+       (fixup_mdeps): Pass segment type to md_convert_frag.
+       * config/tc-a29k.c (md_convert_frag): Add segT argument.
+       * config/tc-h8300.c (md_convert_frag): Likewise.
+       * config/tc-h8500.c (md_convert_frag): Likewise.
+       * config/tc-i386.c (md_convert_frag): Likewise.
+       * config/tc-i860.c (md_convert_frag): Likewise.
+       * config/tc-i960.c (md_convert_frag): Likewise.
+       * config/tc-m68k.c (md_convert_frag): Likewise.
+       * config/tc-m88k.h (md_convert_frag): Likewise.
+       * config/tc-ns32k.c (md_convert_frag): Likewise.
+       * config/tc-rce.c (md_convert_frag): Likewise.
+       * config/tc-tahoe.c (md_convert_frag): Likewise.
+       * config/tc-vax.c (md_convert_frag): Likewise.
+       * config/tc-w65.c (md_convert_frag): Likewise.
+       * config/tc-z8k.c (md_convert_frag): Likewise.
+       * config/tc-h8300.h (TC_RELOC_MANGLE): Add segment argument.
+       * config/tc-h8500.h (TC_RELOC_MANGLE): Likewise.
+       * config/tc-rce.h (TC_RELOC_MANGLE): Likewise.
+       * config/tc-w65.h (TC_RELOC_MANGLE): Likewise.
+       * config/tc-z8k.h (TC_RELOC_MANGLE): Likewise.
+
+Mon Jul 17 15:02:54 1995  Pat Rankin  <rankin@eql.caltech.edu>
+
+       * config/obj-vms.c (Current_Routine, Text_Psect): Delete as file
+       scope variables.
+       (Define_Routine, Define_Local_Symbols): Take Current_Routine and
+       Text_Psect as arguments.
+       (VMS_DBG_Define_Routine): Delete.
+       (VMS_TBT_Block_End): Change `Size' argument from int to valueT.
+       (vms_write_object_file: text and data fixup loops): Difference
+       of two symbols has type offsetT rather than int; convert with
+       md_number_to_chars before passing to VMS_Store_Immediate_Data.
+       (vms_write_object_file: debug symbol loop): Call Define_Routine
+       instead of VMS_DBG_Define_Routine.
+
 Sat Jul 15 00:01:35 1995  Michael Meissner  <meissner@cygnus.com>
 
        * config/tc-ppc.c (ppc_elf_suffix): Add @fixup so that the
index 4aa5933310580f67128c208f4d1fdf56b11eb79a..9832a3808ed7b7f6005eb4335cf01c42634480e3 100644 (file)
@@ -925,8 +925,9 @@ md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
 
 /* should never be called for 29k */
 void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, seg, fragP)
      object_headers *headers;
+     segT seg;
      register fragS *fragP;
 {
   as_fatal ("a29k_convert_frag\n");
index 866da9a9345b83cbfa46722818d4e08a838db3fb..5a09e4ad40aceb30610b989926a2bb097d7a1804 100644 (file)
@@ -1348,10 +1348,10 @@ wordify_scb (buffer, disp_size, inst_size)
 called after relaxing, change the frags so they know how big they are
 */
 void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, seg, fragP)
      object_headers *headers;
+     segT seg;
      fragS *fragP;
-
 {
   int disp_size = 0;
   int inst_size = 0;
index 28f5da64c81e7011507f8f423ebde329a0c0a04e..5644a1bf0077d3d6c21494163e38057b3b89f5ba 100644 (file)
@@ -28,7 +28,7 @@
 #define TC_COUNT_RELOC(x) ((x)->fx_addsy||(x)->fx_subsy)
 #define IGNORE_NONSTANDARD_ESCAPES
 
-#define TC_RELOC_MANGLE(a,b,c) tc_reloc_mangle(a,b,c)
+#define TC_RELOC_MANGLE(s,a,b,c) tc_reloc_mangle(a,b,c)
 
 #define DO_NOT_STRIP 0
 #define DO_STRIP 0
index fd3ff1e6eed96084cce55afba36b307791de3f47..d0b74ff56b65ec4eeabaf3ae0ac11eff7ab8a396 100644 (file)
@@ -17,7 +17,7 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to
-   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include <ctype.h>
 #define  NO_RELOC 0
 
 /* This array holds the chars that always start a comment.  If the
    pre-processor is disabled, these aren't very useful */
+#ifdef OBJ_ELF
+CONST char comment_chars[] = "|#";
+#else
 CONST char comment_chars[] = "|";
+#endif
 
 /* This array holds the chars that only start a comment at the beginning of
    a line.  If the line seems to have the form '# 123 filename'
@@ -398,6 +402,14 @@ struct m68k_it
        expressionS exp;
        char wid;
        char pcrel;
+       /* In a pc relative address the difference between the address
+          of the offset and the address that the offset is relative
+          to.  This depends on the addressing mode.  Basically this
+          is the value to put in the offset field to address the
+          first byte of the offset, without regarding the special
+          significance of some values (in the branch instruction, for
+          example).  */
+       int pcrel_fix;
       }
     reloc[5];                  /* Five is enough??? */
   };
@@ -429,6 +441,8 @@ insop (w, opcode)
     the_ins.opcode[z]=the_ins.opcode[z-1];
   for(z=0;z<the_ins.nrel;z++)
     the_ins.reloc[z].n+=2;
+  for (z = 0; z < the_ins.nfrag; z++)
+    the_ins.fragb[z].fragoff++;
   the_ins.opcode[opcode->m_codenum]=w;
   the_ins.numo++;
 }
@@ -447,21 +461,33 @@ add_exp (beg, end)
 /* The numo+1 kludge is so we can hit the low order byte of the prev word.
    Blecch.  */
 static void
-add_fix (width, exp, pc_rel)
+add_fix (width, exp, pc_rel, pc_fix)
      char width;
      struct m68k_exp *exp;
      int pc_rel;
+     int pc_fix;
 {
   the_ins.reloc[the_ins.nrel].n = (((width)=='B')
                                   ? (the_ins.numo*2-1)
                                   : (((width)=='b')
-                                     ? ((the_ins.numo-1)*2)
+                                     ? (the_ins.numo*2+1)
                                      : (the_ins.numo*2)));
   the_ins.reloc[the_ins.nrel].exp = exp->e_exp;
   the_ins.reloc[the_ins.nrel].wid = width;
+  the_ins.reloc[the_ins.nrel].pcrel_fix = pc_fix;
   the_ins.reloc[the_ins.nrel++].pcrel = pc_rel;
 }
 
+/* Cause an extra frag to be generated here, inserting up to 10 bytes
+   (that value is chosen in the frag_var call in md_assemble).  TYPE
+   is the subtype of the frag to be generated; its primary type is
+   rs_machine_dependent.
+
+   The TYPE parameter is also used by md_convert_frag_1 and
+   md_estimate_size_before_relax.  The appropriate type of fixup will
+   be emitted by md_convert_frag_1.
+
+   ADD becomes the FR_SYMBOL field of the frag, and OFF the FR_OFFSET.  */
 static void
 add_frag(add,off,type)
      symbolS *add;
@@ -517,6 +543,7 @@ static const struct m68k_cpu archs[] = {
   { cpu32,  "68332" },
   { cpu32,  "68333" },
   { cpu32,  "68340" },
+  { cpu32,  "68360" },
   { m68881, "68882" },
 };
 
@@ -602,6 +629,9 @@ CONST pseudo_typeS md_pseudo_table[] =
   {"proc", s_proc, 0},
 #ifdef TE_SUN3
   {"align", s_align_bytes, 0},
+#endif
+#ifdef OBJ_ELF
+  {"swbeg", s_ignore, 0},
 #endif
   {0, 0, 0}
 };
@@ -2204,7 +2234,7 @@ m68k_ip (instring)
              else
                nextword = get_num (opP->con1, 0);
              if (isvar (opP->con1))
-               add_fix (s[1], opP->con1, 0);
+               add_fix (s[1], opP->con1, 0, 0);
              switch (s[1])
                {
                case 'b':
@@ -2331,8 +2361,7 @@ m68k_ip (instring)
                        {
 #if 0
                          addword (0x0170);
-                         opP->con1->e_exp.X_add_number += 6;
-                         add_fix ('l', opP->con1, 1);
+                         add_fix ('l', opP->con1, 1, 2);
                          addword (0), addword (0);
 #else
                          add_frag (adds (opP->con1),
@@ -2344,7 +2373,7 @@ m68k_ip (instring)
                      else
                        {
                          addword (0x0170);
-                         add_fix ('l', opP->con1, 0);
+                         add_fix ('l', opP->con1, 0, 0);
                        }
                    }
                  else
@@ -2362,11 +2391,10 @@ m68k_ip (instring)
                    {
                      if (opP->reg == PC)
                        {
-                         opP->con1->e_exp.X_add_number += 2;
-                         add_fix ('w', opP->con1, 1);
+                         add_fix ('w', opP->con1, 1, 0);
                        }
                      else
-                       add_fix ('w', opP->con1, 0);
+                       add_fix ('w', opP->con1, 0, 0);
                    }
                }
              addword (nextword);
@@ -2441,37 +2469,42 @@ m68k_ip (instring)
                          /* doesn't support wider modes */
                          || cpu_of_arch (current_architecture) < m68020
                          /* simple enough to do relaxation */
-                         || op (opP->con1) == O_symbol
+                         || subs (opP->con1) == NULL
                          ))
                    {
-                     if (isvar (opP->con1))
-                       {
-                         if (op (opP->con1) != O_symbol)
-                           {
-                             /* Can't handle more complex expressions
-                                here yet.  Should only wind up here
-                                if the CPU doesn't support wider
-                                modes or byte mode was explcitly
-                                specified, so do a byte relocation
-                                and let the fixup processing later
-                                complain if it won't reach.  */
-                             nextword += baseo & 0xff;
-                             addword (nextword);
-                             add_fix ('B', opP->con1, 0);
-                           }
-                         else if (opP->reg != PC)
-                           {
-                             goto no_pc_relax;
-                           }
-                         else
+                     if (((!isvar (opP->con1)
+                           || subs (opP->con1) != NULL)
+                          && siz1 == 0)
+                         || siz1 == 1)
+                       {
+                         /* Can't handle more complex expressions
+                            here yet.  Should only wind up here if
+                            the CPU doesn't support wider modes, so
+                            do a byte relocation and let the fixup
+                            processing later complain if it won't
+                            reach.  */
+                         nextword += baseo & 0xff;
+                         addword (nextword);
+                         if (isvar (opP->con1))
                            {
-                             nextword += baseo & 0xff;
-                             addword (nextword);
-                             add_frag (adds (opP->con1), offs (opP->con1),
-                                       TAB (PCINDEX, SZ_UNDEF));
+                             if (opP->reg == PC)
+                               add_fix ('B', opP->con1, 1, 1);
+                             else
+                               add_fix ('B', opP->con1, 0, 0);
                            }
-                       }
-                     break;
+                       }
+                     else if (opP->reg != PC || siz1 != 0)
+                       {
+                         goto no_pc_relax;
+                       }
+                     else
+                       {
+                         nextword += baseo & 0xff;
+                         addword (nextword);
+                         add_frag (adds (opP->con1), offs (opP->con1),
+                                   TAB (PCINDEX, SZ_UNDEF));
+                       }
+                     break;
                    }
                }
              else
@@ -2547,11 +2580,10 @@ m68k_ip (instring)
                {
                  if (opP->reg == PC || opP->reg == ZPC)
                    {
-                     opP->con1->e_exp.X_add_number += 6;
-                     add_fix (siz1 == 3 ? 'l' : 'w', opP->con1, 1);
+                     add_fix (siz1 == 3 ? 'l' : 'w', opP->con1, 1, 2);
                    }
                  else
-                   add_fix (siz1 == 3 ? 'l' : 'w', opP->con1, 0);
+                   add_fix (siz1 == 3 ? 'l' : 'w', opP->con1, 0, 0);
                }
              if (siz1 == 3)
                addword (baseo >> 16);
@@ -2559,15 +2591,7 @@ m68k_ip (instring)
                addword (baseo);
 
              if (isvar (opP->con2))
-               {
-                 if (opP->reg == PC || opP->reg == ZPC)
-                   {
-                     opP->con1->e_exp.X_add_number += 6;
-                     add_fix (siz2 == 3 ? 'l' : 'w', opP->con2, 1);
-                   }
-                 else
-                   add_fix (siz2 == 3 ? 'l' : 'w', opP->con2, 0);
-               }
+               add_fix (siz2 == 3 ? 'l' : 'w', opP->con2, 0, 0);
              if (siz2 == 3)
                addword (outro >> 16);
              if (siz2)
@@ -2607,7 +2631,7 @@ m68k_ip (instring)
                  /* Fall through into long */
                case 3:
                  if (isvar (opP->con1))
-                   add_fix ('l', opP->con1, 0);
+                   add_fix ('l', opP->con1, 0, 0);
 
                  tmpreg = 0x39;/* 7.1 mode */
                  addword (nextword >> 16);
@@ -2616,7 +2640,7 @@ m68k_ip (instring)
 
                case 2: /* Word */
                  if (isvar (opP->con1))
-                   add_fix ('w', opP->con1, 0);
+                   add_fix ('w', opP->con1, 0, 0);
 
                  tmpreg = 0x38;/* 7.0 mode */
                  addword (nextword);
@@ -2654,7 +2678,7 @@ m68k_ip (instring)
            }
          tmpreg = get_num (opP->con1, tmpreg);
          if (isvar (opP->con1))
-           add_fix (s[1], opP->con1, 0);
+           add_fix (s[1], opP->con1, 0, 0);
          switch (s[1])
            {
            case 'b':           /* Danger:  These do no check for
@@ -2704,13 +2728,10 @@ m68k_ip (instring)
          switch (s[1])
            {
            case 'B':
-             /* Needs no offsetting */
-             add_fix ('B', opP->con1, 1);
+             add_fix ('B', opP->con1, 1, -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);
+             add_fix ('w', opP->con1, 1, 0);
              addword (0);
              break;
            case 'L':
@@ -2718,9 +2739,7 @@ m68k_ip (instring)
              if (cpu_of_arch (current_architecture) < m68020)  /* 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);
+             add_fix ('l', opP->con1, 1, 0);
              addword (0);
              addword (0);
              break;
@@ -2762,26 +2781,19 @@ m68k_ip (instring)
                      break;
                    }
 #endif
-                 /* Don't ask! */
-                 opP->con1->e_exp.X_add_number += 2;
-                 add_fix ('w', opP->con1, 1);
+                 add_fix ('w', opP->con1, 1, 0);
                }
              addword (0);
              break;
            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);
+             add_fix ('l', opP->con1, 1, 0);
              addword (0);
              addword (0);
              break;
            case 'c':           /* Var size Coprocesssor branches */
              if (subs (opP->con1))
                {
-                 add_fix ('l', opP->con1, 1);
+                 add_fix ('l', opP->con1, 1, 0);
                  add_frag ((symbolS *) 0, (long) 0, TAB (FBRANCH, LONG));
                }
              else if (adds (opP->con1))
@@ -2792,9 +2804,9 @@ m68k_ip (instring)
                {
                  /* add_frag((symbolS *)0,offs(opP->con1),TAB(FBRANCH,SHORT)); */
                  the_ins.opcode[the_ins.numo - 1] |= 0x40;
-                 add_fix ('l', opP->con1, 1);
+                 add_fix ('l', opP->con1, 1, 0);
+                 addword (0);
                  addword (0);
-                 addword (4);
                }
              break;
            default:
@@ -3642,6 +3654,7 @@ md_assemble (str)
   int m, n = 0;
   char *to_beg_P;
   int shorts_this_frag;
+  fixS *fixP;
 
   memset ((char *) (&the_ins), '\0', sizeof (the_ins));
   m68k_ip (str);
@@ -3697,13 +3710,14 @@ md_assemble (str)
                        the_ins.reloc[m].wid);
            }
 
-         fix_new_exp (frag_now,
-                      ((toP - frag_now->fr_literal)
-                       - the_ins.numo * 2 + the_ins.reloc[m].n),
-                      n,
-                      &the_ins.reloc[m].exp,
-                      the_ins.reloc[m].pcrel,
-                      NO_RELOC);
+         fixP = fix_new_exp (frag_now,
+                             ((toP - frag_now->fr_literal)
+                              - the_ins.numo * 2 + the_ins.reloc[m].n),
+                             n,
+                             &the_ins.reloc[m].exp,
+                             the_ins.reloc[m].pcrel,
+                             NO_RELOC);
+         fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
        }
       return;
     }
@@ -3740,13 +3754,14 @@ md_assemble (str)
          the_ins.reloc[m].wid = 0;
          wid = (wid == 'b') ? 1 : (wid == 'w') ? 2 : (wid == 'l') ? 4 : 4000;
 
-         fix_new_exp (frag_now,
-                      ((toP - frag_now->fr_literal)
-                       - the_ins.numo * 2 + the_ins.reloc[m].n),
-                      wid,
-                      &the_ins.reloc[m].exp,
-                      the_ins.reloc[m].pcrel,
-                      NO_RELOC);
+         fixP = fix_new_exp (frag_now,
+                             ((toP - frag_now->fr_literal)
+                              - the_ins.numo * 2 + the_ins.reloc[m].n),
+                             wid,
+                             &the_ins.reloc[m].exp,
+                             the_ins.reloc[m].pcrel,
+                             NO_RELOC);
+         fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
        }
       (void) frag_var (rs_machine_dependent, 10, 0,
                       (relax_substateT) (the_ins.fragb[n].fragty),
@@ -3775,28 +3790,31 @@ md_assemble (str)
       the_ins.reloc[m].wid = 0;
       wid = (wid == 'b') ? 1 : (wid == 'w') ? 2 : (wid == 'l') ? 4 : 4000;
 
-      fix_new_exp (frag_now,
-                  ((the_ins.reloc[m].n + toP - frag_now->fr_literal)
-                   - shorts_this_frag * 2),
-                  wid,
-                  &the_ins.reloc[m].exp,
-                  the_ins.reloc[m].pcrel,
-                  NO_RELOC);
+      fixP = fix_new_exp (frag_now,
+                         ((the_ins.reloc[m].n + toP - frag_now->fr_literal)
+                          - shorts_this_frag * 2),
+                         wid,
+                         &the_ins.reloc[m].exp,
+                         the_ins.reloc[m].pcrel,
+                         NO_RELOC);
+      fixP->fx_pcrel_adjust = the_ins.reloc[m].pcrel_fix;
     }
 }
 
 /* See BREAK_UP_BIG_DECL definition, above.  */
+#ifdef DO_BREAK_UP_BIG_DECL
 static const struct m68k_opcode *
 opcode_ptr (i)
      int i;
 {
-#ifdef DO_BREAK_UP_BIG_DECL
   int lim1 = sizeof (m68k_opcodes) / sizeof (m68k_opcodes[0]);
   if (i >= lim1)
     return m68k_opcodes_2 + (i - lim1);
-#endif
   return m68k_opcodes + i;
 }
+#else
+#define opcode_ptr(i) (m68k_opcodes + i)
+#endif
 
 void
 md_begin ()
@@ -3880,6 +3898,7 @@ md_begin ()
   alt_notend_table['d'] = 1;
   alt_notend_table['D'] = 1;
   alt_notend_table['#'] = 1;
+  alt_notend_table['&'] = 1;
   alt_notend_table['f'] = 1;
   alt_notend_table['F'] = 1;
 #ifdef REGISTER_PREFIX
@@ -4143,7 +4162,7 @@ md_apply_fix_2 (fixP, val)
 int
 md_apply_fix (fixP, valp)
      fixS *fixP;
-     long *valp;
+     valueT *valp;
 {
   md_apply_fix_2 (fixP, (addressT) *valp);
   return 1;
@@ -4167,6 +4186,7 @@ md_convert_frag_1 (fragP)
 {
   long disp;
   long ext = 0;
+  fixS *fixP;
 
   /* Address in object code of the displacement.  */
   register int object_address = fragP->fr_fix + fragP->fr_address;
@@ -4182,6 +4202,10 @@ md_convert_frag_1 (fragP)
   disp = fragP->fr_symbol ? S_GET_VALUE (fragP->fr_symbol) : 0;
   disp = (disp + fragP->fr_offset) - object_address;
 
+#ifdef BFD_ASSEMBLER
+  disp += fragP->fr_symbol->sy_frag->fr_address;
+#endif
+
   switch (fragP->fr_subtype)
     {
     case TAB (BCC68000, BYTE):
@@ -4318,8 +4342,9 @@ md_convert_frag_1 (fragP)
       break;
     case TAB (PCLEA, LONG):
       subseg_change (text_section, 0);
-      fix_new (fragP, (int) (fragP->fr_fix) + 2, 4, fragP->fr_symbol,
-              fragP->fr_offset + 4, 1, NO_RELOC);
+      fixP = fix_new (fragP, (int) (fragP->fr_fix) + 2, 4, fragP->fr_symbol,
+                     fragP->fr_offset, 1, NO_RELOC);
+      fixP->fx_pcrel_adjust = 2;
       /* Already set to mode 7.3; this indicates: PC indirect with
         suppressed index, 32-bit displacement.  */
       *buffer_address++ = 0x01;
@@ -4335,29 +4360,34 @@ md_convert_frag_1 (fragP)
          as_bad ("displacement doesn't fit in one byte");
          disp = 0;
        }
-      fragP->fr_opcode[2] &= ~1;
-      fragP->fr_opcode[3] = disp;
+      assert (fragP->fr_fix >= 2);
+      buffer_address[-2] &= ~1;
+      buffer_address[-1] = disp;
       ext = 0;
       break;
     case TAB (PCINDEX, SHORT):
       subseg_change (text_section, 0);
       disp += 2;
       assert (issword (disp));
-      fragP->fr_opcode[2] |= 0x1;
-      fragP->fr_opcode[3] = 0x20;
-      fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
-              fragP->fr_offset + 4, (fragP->fr_opcode[1] & 077) == 073,
-              NO_RELOC);
+      assert (fragP->fr_fix >= 2);
+      buffer_address[-2] |= 0x1;
+      buffer_address[-1] = 0x20;
+      fixP = fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
+                     fragP->fr_offset, (fragP->fr_opcode[1] & 077) == 073,
+                     NO_RELOC);
+      fixP->fx_pcrel_adjust = 2;
       ext = 2;
       break;
     case TAB (PCINDEX, LONG):
       subseg_change (text_section, 0);
       disp += 2;
-      fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
-              fragP->fr_offset + 6, (fragP->fr_opcode[1] & 077) == 073,
-              NO_RELOC);
-      fragP->fr_opcode[2] |= 0x1;
-      fragP->fr_opcode[3] = 0x30;
+      fixP = fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
+                     fragP->fr_offset, (fragP->fr_opcode[1] & 077) == 073,
+                     NO_RELOC);
+      fixP->fx_pcrel_adjust = 2;
+      assert (fragP->fr_fix >= 2);
+      buffer_address[-2] |= 0x1;
+      buffer_address[-1] = 0x30;
       ext = 4;
       break;
     }
@@ -4372,8 +4402,9 @@ md_convert_frag_1 (fragP)
 #ifndef BFD_ASSEMBLER
 
 void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, seg, fragP)
      object_headers *headers;
+     segT seg;
      fragS *fragP;
 {
   md_convert_frag_1 (fragP);
@@ -4384,7 +4415,7 @@ md_convert_frag (headers, fragP)
 void
 md_convert_frag (abfd, sec, fragP)
      bfd *abfd;
-     asection sec;
+     segT sec;
      fragS *fragP;
 {
   md_convert_frag_1 (fragP);
@@ -4448,7 +4479,7 @@ md_estimate_size_before_relax (fragP, segment)
        else
          {                     /* Symbol is still undefined.  Make it simple */
            fix_new (fragP, (int) (fragP->fr_fix), 4, fragP->fr_symbol,
-                    fragP->fr_offset + 4, 1, NO_RELOC);
+                    fragP->fr_offset, 1, NO_RELOC);
            fragP->fr_fix += 4;
            fragP->fr_opcode[1] = (char) 0xff;
            frag_wane (fragP);
@@ -4467,8 +4498,11 @@ md_estimate_size_before_relax (fragP, segment)
          }
        else
          {
-           fragP->fr_subtype = TAB (FBRANCH, LONG);
-           fragP->fr_var += 4;
+           fix_new (fragP, (int) fragP->fr_fix, 4, fragP->fr_symbol,
+                    fragP->fr_offset, 1, NO_RELOC);
+           fragP->fr_fix += 4;
+           fragP->fr_opcode[1] |= 0x40; /* Turn on LONG bit */
+           frag_wane (fragP);
          }
        break;
       }                                /* TAB(FBRANCH,SZ_UNDEF) */
@@ -4599,7 +4633,7 @@ md_estimate_size_before_relax (fragP, segment)
       else
        {
          fragP->fr_subtype = TAB (PCINDEX, LONG);
-         fragP->fr_var += 6;
+         fragP->fr_var += 4;
        }
       break;
 
@@ -5027,7 +5061,12 @@ s_proc (ignore)
  *
  */
 
+#ifdef OBJ_ELF
+CONST char *md_shortopts = "lSA:m:kQ:V";
+#else
 CONST char *md_shortopts = "lSA:m:k";
+#endif
+
 struct option md_longopts[] = {
 #define OPTION_PIC (OPTION_MD_BASE)
   {"pic", no_argument, NULL, OPTION_PIC},
@@ -5142,6 +5181,10 @@ md_parse_option (c, arg)
       flag_reg_prefix_optional = 1;
       break;
 
+    case 'Q':
+    case 'V':
+      break;
+
     default:
       return 0;
     }
@@ -5156,8 +5199,9 @@ md_show_usage (stream)
   fprintf(stream, "\
 680X0 options:\n\
 -l                     use 1 word for refs to undefined symbols [default 2]\n\
--m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040\n\
- | -m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -mcpu32\n\
+-m68000 | -m68008 | -m68010 | -m68020 | -m68030 | -m68040 | -m68060\n\
+ | -m68302 | -m68331 | -m68332 | -m68333 | -m68340 | -m68360\n\
+ | -mcpu32\n\
                        specify variant of 680X0 architecture [default 68020]\n\
 -m68881 | -m68882 | -mno-68881 | -mno-68882\n\
                        target has/lacks floating-point coprocessor\n\
@@ -5281,13 +5325,14 @@ md_section_align (segment, size)
 }
 
 /* Exactly what point is a PC-relative offset relative TO?
-   On the 68k, they're relative to the address of the offset, plus
-   its size. (??? Is this right?  FIXME-SOON!) */
+   On the 68k, it is relative to the address of the first extension
+   word.  The difference between the addresses of the offset and the
+   first extension word is stored in fx_pcrel_adjust. */
 long
 md_pcrel_from (fixP)
      fixS *fixP;
 {
-  return (fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address);
+  return (fixP->fx_where + fixP->fx_frag->fr_address - fixP->fx_pcrel_adjust);
 }
 
 #ifndef BFD_ASSEMBLER
index afffbb1679b8113dbe6f46fff34b93642c7a4c19..9508b49ccf954cc975e6a5bbde095e1ceae6a5aa 100644 (file)
@@ -69,11 +69,7 @@ struct reloc_info_m88k
 /* Don't warn on word overflow; it happens on %hi relocs.  */
 #undef WARN_SIGNED_OVERFLOW_WORD
 
-#ifndef BFD_ASSEMBLER
-#define md_convert_frag(h,f)           {as_fatal ("m88k convert_frag\n");}
-#else
 #define md_convert_frag(b,s,f)         {as_fatal ("m88k convert_frag\n");}
-#endif
 
 /* We don't need to do anything special for undefined symbols.  */
 #define md_undefined_symbol(s) 0
index 63452e8912f8abd2f0415b8064c251ab32ba91cc..0dc7a9f4cb1e8c7d3f0fc9a37566c3cd40739502 100644 (file)
@@ -827,8 +827,9 @@ called after relaxing, change the frags so they know how big they are
 */
 #ifndef BFD_ASSEMBLER
 void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, seg, fragP)
      object_headers *headers;
+     segT seg;
      register fragS *fragP;
 #else
 void
index bf2cfbef59e3fcd205d2cef51474f9a3544b711a..1eb893f76e356042e7b4fd76f84da090c3c1f164 100644 (file)
@@ -43,7 +43,7 @@
 #define TC_COUNT_RELOC(x) (((x)->fx_addsy||(x)->fx_subsy)&&(x)->fx_r_type < 22)
 #define IGNORE_NONSTANDARD_ESCAPES
 
-#define TC_RELOC_MANGLE(a,b,c) tc_reloc_mangle(a,b,c)
+#define TC_RELOC_MANGLE(s,a,b,c) tc_reloc_mangle(a,b,c)
 
 #define DO_NOT_STRIP 0
 #define DO_STRIP 0
index b9be45ade23a383061fdf97f1d87edc57dbb04cd..eef0113c426d375cd6601baa9e3d6f5e8b4114c4 100644 (file)
@@ -732,8 +732,9 @@ md_estimate_size_before_relax (fragP, segment_type)
  *     Caller will turn frag into a ".space 0".
  */
 void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, seg, fragP)
      object_headers *headers;
+     segT seg;
      register fragS *fragP;
 {
   register char *addressP;     /* -> _var to change. */
index ef3f863bdd483444520050f9c14f6b05cb6cfaad..d62e1859a34154ee9478869db7aa2a779782a57b 100644 (file)
@@ -912,10 +912,10 @@ md_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
 called after relaxing, change the frags so they know how big they are
 */
 void
-md_convert_frag (headers, fragP)
+md_convert_frag (headers, seg, fragP)
      object_headers *headers;
+     segT seg;
      fragS *fragP;
-
 {
   int disp_size = 0;
   int inst_size = 0;
index 1638f8b3c48bd3de0ab43a74b9599bba2b3ae605..1356aeaa5bf19f3a1ab3c4253212182bbbe48e38 100644 (file)
@@ -29,7 +29,7 @@
 
 #define IGNORE_NONSTANDARD_ESCAPES
 
-#define TC_RELOC_MANGLE(a,b,c) tc_reloc_mangle(a,b,c)
+#define TC_RELOC_MANGLE(s,a,b,c) tc_reloc_mangle(a,b,c)
 
 #define DO_NOT_STRIP 0
 #define DO_STRIP 0