Support on-demand global register allocation by passing on
authorHans-Peter Nilsson <hp@axis.com>
Fri, 1 Feb 2002 08:09:47 +0000 (08:09 +0000)
committerHans-Peter Nilsson <hp@axis.com>
Fri, 1 Feb 2002 08:09:47 +0000 (08:09 +0000)
base-plus-offset relocs to the linker.
* config/tc-mmix.c: Tweak and fix typos in comments.
  (allocate_undefined_gregs_in_linker): New variable.
(OPTION_LINKER_ALLOCATED_GREGS): New option macro.
(md_longopts): Add --linker-allocated-gregs.
(md_parse_option) <case 'x'>: Imply --linker-allocated-gregs.
<case OPTION_LINKER_ALLOCATED_GREGS>: New.
(md_show_usage): Update text for -x.  Add text for
--linker-allocated-gregs.
(tc_gen_reloc): Derive default value for addend from val and
baddsy.  Use addsec and bfd_is_abs_section in more places.  Don't
emit error for BFD_RELOC_MMIX_BASE_PLUS_OFFSET without suitable
GREG if allocate_undefined_gregs_in_linker.
* doc/as.texinfo (Overview) <Target MMIX options>: Add
--linker-allocated-gregs.
* doc/c-mmix.texi (MMIX-Opts): Add blurb about
--linker-allocated-gregs.  Mention that it's implied by -x.
(MMIX-Pseudos) <GREG>: Mention when and how a GREG can be omitted.
(MMIX-mmixal): Clarify dated comparison and location of MMIXware.

* config/tc-mmix.h (md_parse_name): Use ISUPPER, not isupper.

gas/ChangeLog
gas/config/tc-mmix.c
gas/config/tc-mmix.h
gas/doc/as.texinfo
gas/doc/c-mmix.texi

index fa1a2fd..e0c8b43 100644 (file)
@@ -1,3 +1,28 @@
+2002-02-01  Hans-Peter Nilsson  <hp@bitrange.com>
+
+       Support on-demand global register allocation by passing on
+       base-plus-offset relocs to the linker.
+       * config/tc-mmix.c: Tweak and fix typos in comments.
+       (allocate_undefined_gregs_in_linker): New variable.
+       (OPTION_LINKER_ALLOCATED_GREGS): New option macro.
+       (md_longopts): Add --linker-allocated-gregs.
+       (md_parse_option) <case 'x'>: Imply --linker-allocated-gregs.
+       <case OPTION_LINKER_ALLOCATED_GREGS>: New.
+       (md_show_usage): Update text for -x.  Add text for
+       --linker-allocated-gregs.
+       (tc_gen_reloc): Derive default value for addend from val and
+       baddsy.  Use addsec and bfd_is_abs_section in more places.  Don't
+       emit error for BFD_RELOC_MMIX_BASE_PLUS_OFFSET without suitable
+       GREG if allocate_undefined_gregs_in_linker.
+       * doc/as.texinfo (Overview) <Target MMIX options>: Add
+       --linker-allocated-gregs.
+       * doc/c-mmix.texi (MMIX-Opts): Add blurb about
+       --linker-allocated-gregs.  Mention that it's implied by -x.
+       (MMIX-Pseudos) <GREG>: Mention when and how a GREG can be omitted.
+       (MMIX-mmixal): Clarify dated comparison and location of MMIXware.
+
+       * config/tc-mmix.h (md_parse_name): Use ISUPPER, not isupper.
+
 2002-02-01  Alan Modra  <amodra@bigpond.net.au>
 
        * Makefile.am: Run "make dep-am"
index fcd7f1e..e396027 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-mmix.c -- Assembler for Don Knuth's MMIX.
-   Copyright (C) 2001 Free Software Foundation.
+   Copyright (C) 2001, 2002 Free Software Foundation.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -154,11 +154,15 @@ static int warn_on_expansion = 1;
 /* Should we merge non-zero GREG register definitions?  */
 static int merge_gregs = 1;
 
+/* Should we pass on undefined BFD_RELOC_MMIX_BASE_PLUS_OFFSET relocs
+   (missing suitable GREG definitions) to the linker?  */
+static int allocate_undefined_gregs_in_linker = 0;
+
 /* Should we emit built-in symbols?  */
 static int predefined_syms = 1;
 
-/* Should we anything but the listed special register name (e.g. equated
-   symbols)?  */
+/* Should we allow anything but the listed special register name
+   (e.g. equated symbols)?  */
 static int equated_spec_regs = 1;
 
 /* Do we require standard GNU syntax?  */
@@ -185,6 +189,7 @@ struct option md_longopts[] =
 #define OPTION_GNU_SYNTAX  (OPTION_NOSYMS + 1)
 #define OPTION_GLOBALIZE_SYMBOLS  (OPTION_GNU_SYNTAX + 1)
 #define OPTION_FIXED_SPEC_REGS  (OPTION_GLOBALIZE_SYMBOLS + 1)
+#define OPTION_LINKER_ALLOCATED_GREGS  (OPTION_FIXED_SPEC_REGS + 1)
    {"linkrelax", no_argument, NULL, OPTION_RELAX},
    {"no-expand", no_argument, NULL, OPTION_NOEXPAND},
    {"no-merge-gregs", no_argument, NULL, OPTION_NOMERGEGREG},
@@ -193,6 +198,8 @@ struct option md_longopts[] =
    {"globalize-symbols", no_argument, NULL, OPTION_GLOBALIZE_SYMBOLS},
    {"fixed-special-register-names", no_argument, NULL,
     OPTION_FIXED_SPEC_REGS},
+   {"linker-allocated-gregs", no_argument, NULL,
+    OPTION_LINKER_ALLOCATED_GREGS},
    {NULL, no_argument, NULL, 0}
  };
 
@@ -621,6 +628,7 @@ md_parse_option (c, arg)
     {
     case 'x':
       warn_on_expansion = 0;
+      allocate_undefined_gregs_in_linker = 1;
       break;
 
     case OPTION_RELAX:
@@ -653,6 +661,10 @@ md_parse_option (c, arg)
       equated_spec_regs = 0;
       break;
 
+    case OPTION_LINKER_ALLOCATED_GREGS:
+      allocate_undefined_gregs_in_linker = 1;
+      break;
+
     default:
       return 0;
     }
@@ -685,9 +697,13 @@ md_show_usage (stream)
   fprintf (stream, _("\
   -no-merge-gregs         Do not merge GREG definitions with nearby values.\n"));
   fprintf (stream, _("\
+  -linker-allocated-gregs If there's no suitable GREG definition for the\
+                          operands of an instruction, let the linker resolve.\n"));
+  fprintf (stream, _("\
   -x                      Do not warn when an operand to GETA, a branch,\n\
                           PUSHJ or JUMP is not known to be within range.\n\
-                          The linker will catch any errors.\n"));
+                          The linker will catch any errors.  Implies\n\
+                          -linker-allocated-gregs."));
 }
 
 /* Step to end of line, but don't step over the end of the line.  */
@@ -1031,10 +1047,10 @@ md_assemble (str)
       current_fb_label = -1;
     }
 
-  /* We also assume that the length of the instruction is determinable
-     from the first format character.  Currently *all* the information is
-     in the first character.  We need a self-contained frag since we want
-     the relocation to point to the instruction, not the variant part.  */
+  /* We also assume that the length of the instruction is at least 4, the
+     size of an unexpanded instruction.  We need a self-contained frag
+     since we want the relocation to point to the instruction, not the
+     variant part.  */
 
   opcodep = frag_more (4);
   mmix_opcode_frag = opc_fragP = frag_now;
@@ -2577,8 +2593,8 @@ tc_gen_reloc (section, fixP)
   char *buf  = fixP->fx_where + fixP->fx_frag->fr_literal;
   symbolS *addsy = fixP->fx_addsy;
   asection *addsec = addsy == NULL ? NULL : S_GET_SEGMENT (addsy);
-  bfd_vma addend = fixP->fx_offset;
   asymbol *baddsy = addsy != NULL ? symbol_get_bfdsym (addsy) : NULL;
+  bfd_vma addend = val - (baddsy == NULL ? 0 : bfd_asymbol_value (baddsy));
 
   /* A single " LOCAL expression" in the wrong section will not work when
      linking to MMO; relocations for zero-content sections are then
@@ -2608,8 +2624,7 @@ tc_gen_reloc (section, fixP)
     case BFD_RELOC_8:
       code = fixP->fx_r_type;
 
-      if (addsy == NULL
-         || bfd_is_abs_section (S_GET_SEGMENT (addsy)))
+      if (addsy == NULL || bfd_is_abs_section (addsec))
        {
          /* Resolve this reloc now, as md_apply_fix3 would have done (not
             called if -linkrelax).  There is no point in keeping a reloc
@@ -2658,7 +2673,7 @@ tc_gen_reloc (section, fixP)
         register contents section (that is, to a register), then we can't
         resolve the relocation here.  */
       if (addsy != NULL
-         && (bfd_is_und_section (S_GET_SEGMENT (addsy))
+         && (bfd_is_und_section (addsec)
              || strcmp (bfd_get_section_name (addsec->owner, addsec),
                         MMIX_REG_CONTENTS_SECTION_NAME) == 0))
        {
@@ -2672,14 +2687,13 @@ tc_gen_reloc (section, fixP)
          && (S_GET_SEGMENT (addsy) != real_reg_section
              || val > 255
              || val < 0)
-         && ! bfd_is_abs_section (S_GET_SEGMENT (addsy)))
+         && ! bfd_is_abs_section (addsec))
        goto badop;
 
       /* Set the "immediate" bit of the insn if this relocation is to Z
         field when the value is a numeric value, i.e. not a register.  */
       if ((fixP->fx_where & 3) == 3
-         && (addsy == NULL
-             || S_GET_SEGMENT (addsy) == absolute_section))
+         && (addsy == NULL || bfd_is_abs_section (addsec)))
        buf[-3] |= IMM_OFFSET_BIT;
 
       buf[0] = val;
@@ -2687,8 +2701,8 @@ tc_gen_reloc (section, fixP)
 
     case BFD_RELOC_MMIX_BASE_PLUS_OFFSET:
       if (addsy != NULL
-         &&  strcmp (bfd_get_section_name (addsec->owner, addsec),
-                     MMIX_REG_CONTENTS_SECTION_NAME) == 0)
+         && strcmp (bfd_get_section_name (addsec->owner, addsec),
+                    MMIX_REG_CONTENTS_SECTION_NAME) == 0)
        {
          /* This changed into a register; the relocation is for the
             register-contents section.  The constant part remains zero.  */
@@ -2701,16 +2715,14 @@ tc_gen_reloc (section, fixP)
 
         If we encounter any other defined symbol, then we must find a
         suitable register and emit a reloc.  */
-      if (addsy == NULL
-         || S_GET_SEGMENT (addsy) != real_reg_section)
+      if (addsy == NULL || addsec != real_reg_section)
        {
          struct mmix_symbol_gregs *gregs;
          struct mmix_symbol_greg_fixes *fix;
 
          if (S_IS_DEFINED (addsy))
            {
-             if (! symbol_section_p (addsy)
-                 && ! bfd_is_abs_section (S_GET_SEGMENT (addsy)))
+             if (! symbol_section_p (addsy) && ! bfd_is_abs_section (addsec))
                as_fatal (_("internal: BFD_RELOC_MMIX_BASE_PLUS_OFFSET not resolved to section"));
 
              /* If this is an absolute symbol sufficiently near
@@ -2720,7 +2732,7 @@ tc_gen_reloc (section, fixP)
                 comparisons.  */
              if (lowest_data_loc != (bfd_vma) -1
                  && (bfd_vma) val + 256 > lowest_data_loc
-                 && bfd_is_abs_section (S_GET_SEGMENT (addsy)))
+                 && bfd_is_abs_section (addsec))
                {
                  val -= (offsetT) lowest_data_loc;
                  addsy = section_symbol (data_section);
@@ -2728,7 +2740,7 @@ tc_gen_reloc (section, fixP)
              /* Likewise text section.  */
              else if (lowest_text_loc != (bfd_vma) -1
                       && (bfd_vma) val + 256 > lowest_text_loc
-                      && bfd_is_abs_section (S_GET_SEGMENT (addsy)))
+                      && bfd_is_abs_section (addsec))
                {
                  val -= (offsetT) lowest_text_loc;
                  addsy = section_symbol (text_section);
@@ -2738,8 +2750,7 @@ tc_gen_reloc (section, fixP)
          gregs = *symbol_get_tc (addsy);
 
          /* If that symbol does not have any associated GREG definitions,
-            we can't do anything.  FIXME: implement allocate-on-demand in
-            the linker.  */
+            we can't do anything.  */
          if (gregs == NULL
              || (fix = bsearch (&val, gregs->greg_fixes, gregs->n_gregs,
                                 sizeof (gregs->greg_fixes[0]),
@@ -2750,8 +2761,17 @@ tc_gen_reloc (section, fixP)
                 before the address we want.  */
              || fix->offs + 255 < val)
            {
-             as_bad_where (fixP->fx_file, fixP->fx_line,
-                           _("no suitable GREG definition for operands"));
+             /* We can either let the linker allocate GREGs
+                automatically, or emit an error.  */
+             if (allocate_undefined_gregs_in_linker)
+               {
+                 /* The values in baddsy and addend are right.  */
+                 code = fixP->fx_r_type;
+                 break;
+               }
+             else
+               as_bad_where (fixP->fx_file, fixP->fx_line,
+                             _("no suitable GREG definition for operands"));
              return NULL;
            }
          else
@@ -2781,7 +2801,7 @@ tc_gen_reloc (section, fixP)
 
     case BFD_RELOC_MMIX_REG:
       if (addsy != NULL
-         && (bfd_is_und_section (S_GET_SEGMENT (addsy))
+         && (bfd_is_und_section (addsec)
              || strcmp (bfd_get_section_name (addsec->owner, addsec),
                         MMIX_REG_CONTENTS_SECTION_NAME) == 0))
        {
@@ -2790,10 +2810,10 @@ tc_gen_reloc (section, fixP)
        }
 
       if (addsy != NULL
-         && (S_GET_SEGMENT (addsy) != real_reg_section
+         && (addsec != real_reg_section
              || val > 255
              || val < 0)
-         && ! bfd_is_und_section (S_GET_SEGMENT (addsy)))
+         && ! bfd_is_und_section (addsec))
        /* Drop through to error message.  */
        ;
       else
index e0b6f49..53d4df2 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-mmix.h -- Header file for tc-mmix.c.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
    Written by Hans-Peter Nilsson (hp@bitrange.com).
 
    This file is part of GAS, the GNU Assembler.
@@ -75,7 +75,7 @@ extern int mmix_gnu_syntax;
   && (name[0] == '@'                                           \
       ? (! is_part_of_name (name[1])                           \
         && mmix_current_location (current_location, exp))      \
-      : ((name[0] == ':' || isupper (name[0]))                 \
+      : ((name[0] == ':' || ISUPPER (name[0]))                 \
         && mmix_parse_predefined_name (name, exp))))
 
 extern char *mmix_prefix_name PARAMS ((char *));
index 3d7fef5..6d04ac4 100644 (file)
@@ -1,6 +1,6 @@
 \input texinfo @c                               -*-Texinfo-*-
 @c  Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-@c  2001
+@c  2001, 2002
 @c  Free Software Foundation, Inc.
 @c UPDATE!!  On future updates--
 @c   (1)   check for new machine-dep cmdline options in
@@ -127,7 +127,7 @@ END-INFO-DIR-ENTRY
 This file documents the GNU Assembler "@value{AS}".
 
 @c man begin COPYRIGHT
-Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc.
+Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.1
@@ -180,7 +180,7 @@ done.
 @end tex
 
 @vskip 0pt plus 1filll
-Copyright @copyright{} 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001 Free Software Foundation, Inc.
+Copyright @copyright{} 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000, 2001, 2002 Free Software Foundation, Inc.
 
       Permission is granted to copy, distribute and/or modify this document
       under the terms of the GNU Free Documentation License, Version 1.1
@@ -354,6 +354,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
    [@b{--fixed-special-register-names}] [@b{--globalize-symbols}]
    [@b{--gnu-syntax}] [@b{--relax}] [@b{--no-predefined-symbols}]
    [@b{--no-expand}] [@b{--no-merge-gregs}] [@b{-x}]
+   [@b{--linker-allocated-gregs}]
 @end ifset
 @ifset PDP11
 
index dd18765..e3622ac 100644 (file)
@@ -1,4 +1,4 @@
-@c Copyright 2001 Free Software Foundation, Inc.
+@c Copyright 2001, 2002 Free Software Foundation, Inc.
 @c This is part of the GAS manual.
 @c For copying conditions, see the file as.texinfo.
 @c MMIX description by Hans-Peter Nilsson, hp@bitrange.com
@@ -79,7 +79,15 @@ is specified, and assembly fails otherwise, when an instruction needs to
 be expanded.  It needs to be kept in mind that @code{mmixal} is both an
 assembler and linker, while @code{@value{AS}} will expand instructions
 that at link stage can be contracted.  (Though linker relaxation isn't yet
-implemented in @code{@value{LD}}.)
+implemented in @code{@value{LD}}.)  The option @samp{-x} also imples
+@samp{--linker-allocated-gregs}.
+
+@cindex @samp{--linker-allocated-gregs} command line option, MMIX
+Usually a two-operand-expression (@pxref{GREG-base}) without a matching
+@samp{GREG} directive is treated as an error by @code{@value{AS}}.  When
+the option @samp{--linker-allocated-gregs} is in effect, they are instead
+passed through to the linker, which will allocate as many global registers
+as is needed.
 
 @node MMIX-Expand
 @section Instruction expansion
@@ -381,7 +389,10 @@ Global registers allocated with this directive are allocated in order
 higher-to-lower within a file.  Other than that, the exact order of
 register allocation and elimination is undefined.  For example, the order
 is undefined when more than one file with such directives are linked
-together.
+together.  With the options @samp{-x} and @samp{--linker-allocated-gregs},
+@samp{GREG} directives for two-operand cases like the one mentioned above
+can be omitted.  Sufficient global registers will then be allocated by the
+linker.
 
 @item BYTE
 @cindex assembler directive BYTE, MMIX
@@ -544,10 +555,11 @@ upper-case characters.
 
 There's no unicode support.
 
-The following is a list of programs in
-@url{http://www-cs-faculty.stanford.edu/~knuth/mmix-news.html} dated
-2001-08-25 (md5sum c393470cfc86fac040487d22d2bf0172) that assemble with
-@code{mmixal} but do not assemble with @code{@value{AS}}:
+The following is a list of programs in @samp{mmix.tar.gz}, available at
+@url{http://www-cs-faculty.stanford.edu/~knuth/mmix-news.html}, last
+checked with the version dated 2001-08-25 (md5sum
+c393470cfc86fac040487d22d2bf0172) that assemble with @code{mmixal} but do
+not assemble with @code{@value{AS}}:
 
 @table @code
 @item silly.mms