* config/tc-dvp.h (ELF_TC_SPECIAL_SECTIONS): Add .vuoverlay_table.
authorDoug Evans <dje@google.com>
Thu, 28 May 1998 23:29:19 +0000 (23:29 +0000)
committerDoug Evans <dje@google.com>
Thu, 28 May 1998 23:29:19 +0000 (23:29 +0000)
(dvp_frob_file): Declare.
(tc_frob_file): Define.
(VUOVERLAY_SECTION_PREFIX,VUOVERLAY_TABLE_SECTION_NAME): New macros.
* config/tc-dvp.c (VUOVERLAY_START_PREFIX): New macro.
(vuoverlay_section_name,create_vuoverlay_section): New functions.
(vuoverlay_section,vuoverlay_table_section): New static globals.
(ovlysym_table): New static global.
(md_begin): Create .vuoverlay_table section.
(assemble_vif): Call create_vuoverlay_section for each mpg.
(dvp_frob_label): Record vu labels in ovlysym_table for later
movement from absolute section to their overlay section.
(dvp_frob_file): New function.
(md_apply_fix3): For 8/16/32/64 bit relocs, only process if fx_done.

gas/ChangeLog
gas/config/tc-dvp.c
gas/config/tc-dvp.h

index 8e152e35362227095874fcf5cb3a506cbc511f4d..449c66afe05057c1408e026b966e0edd0edad89a 100644 (file)
@@ -1,3 +1,22 @@
+start-sanitize-sky
+Thu May 28 16:23:08 1998  Doug Evans  <devans@canuck.cygnus.com>
+
+       * config/tc-dvp.h (ELF_TC_SPECIAL_SECTIONS): Add .vuoverlay_table.
+       (dvp_frob_file): Declare.
+       (tc_frob_file): Define.
+       (VUOVERLAY_SECTION_PREFIX,VUOVERLAY_TABLE_SECTION_NAME): New macros.
+       * config/tc-dvp.c (VUOVERLAY_START_PREFIX): New macro.
+       (vuoverlay_section_name,create_vuoverlay_section): New functions.
+       (vuoverlay_section,vuoverlay_table_section): New static globals.
+       (ovlysym_table): New static global.
+       (md_begin): Create .vuoverlay_table section.
+       (assemble_vif): Call create_vuoverlay_section for each mpg.
+       (dvp_frob_label): Record vu labels in ovlysym_table for later
+       movement from absolute section to their overlay section.
+       (dvp_frob_file): New function.
+       (md_apply_fix3): For 8/16/32/64 bit relocs, only process if fx_done.
+
+end-sanitize-sky
 Wed May 27 11:16:25 1998  Ian Lance Taylor  <ian@cygnus.com>
 
        * read.c (s_org): Call md_flush_pending_output if it is defined.
index 9b02c3e8ac8e804ac03817e08d87d46620451677..6188902e8d84edf4823317a0d630860aeb495570 100644 (file)
    Note that symbols that begin with '$' are local symbols
    on mips targets, so we can't begin it with '$'.  */
 #define VU_LABEL_PREFIX "_$"
+/* Prefix for symbols at start of vu overlays, in r5900 space.  */
+#define VUOVERLAY_START_PREFIX "__start_"
 
 static long parse_float PARAMS ((char **, const char **));
 static symbolS * create_label PARAMS ((const char *, const char *));
 static symbolS * create_colon_label PARAMS ((int, const char *, const char *));
 static char * unique_name PARAMS ((const char *));
+static char * vuoverlay_section_name PARAMS ((offsetT));
+static void create_vuoverlay_section PARAMS ((const char *, offsetT,
+                                             symbolS *, symbolS *));
 static symbolS * compute_mpgloc PARAMS ((symbolS *, symbolS *, symbolS *));
 static int compute_nloop PARAMS ((gif_type, int, int));
 static void check_nloop PARAMS ((gif_type, int, int, int,
@@ -152,9 +157,28 @@ static symbolS *vif_data_start;
 /* Label at end of insn's data.  */
 static symbolS *vif_data_end;
 
-/* Special symbol $.mpgloc.  The value is in bytes.  */
+/* Special symbol $.mpgloc.  The value is in bytes.
+   This value is kept absolute, for simplicity.  */
 static symbolS *mpgloc_sym;
 
+/* Handle of the current .vuoverlay.foo section.  */
+static segT vuoverlay_section;
+
+/* The .overlay section is a table mapping lma's to vma's.  */
+static segT vuoverlay_table_section;
+
+/* Table to map vu space labels to their overlay sections.
+   Labels in vu space are first put in the ABS section to simplify
+   PC relative branch calculations (s1 - s2 isn't supported if they're
+   in different sections).  Before the file is written out the labels
+   are moved to their overlay section.  */
+typedef struct ovlysym {
+  struct ovlysym *next;
+  segT sec;
+  symbolS *sym;
+} ovlysymS;
+static ovlysymS *ovlysym_table;
+
 /* GIF insn support.  */
 /* Type of insn.  */
 static int gif_insn_type;
@@ -287,9 +311,18 @@ md_begin ()
   /* Disable automatic mpg insertion.  */
   vu_count = -1;
 
-  /* Create special symbols.  */
+  /* Initialize $.mpgloc.  */
   mpgloc_sym = expr_build_uconstant (0);
 
+  /* Create the vu overlay table section.  */
+  {
+    /* Must preserve the current seg/subseg.  It is the initial one.  */
+    segT orig_seg = now_seg;
+    subsegT orig_subseg = now_subseg;
+    vuoverlay_table_section = subseg_new (VUOVERLAY_TABLE_SECTION_NAME, 0);
+    subseg_set (orig_seg, orig_subseg);
+  }
+
   /* Set the type of the output file to r5900.  */
   bfd_set_arch_mach (stdoutput, bfd_arch_mips, 5900);
 }
@@ -628,21 +661,25 @@ assemble_vif (str)
 
          /* Put a symbol at the start of data.  The relaxation code uses
             this to figure out how many bytes to insert.  $.mpgloc
-            calculations also use it.  */
-         vif_data_start = create_colon_label (STO_DVP_VU, LOCAL_LABEL_PREFIX,
-                                              unique_name ("mpg"));
-         insn_frag->fr_symbol = vif_data_start;
-
-         /* Get the value of mpgloc.  If it wasn't '*'
-            then update $.mpgloc.  */
+            calculations use it.  The disassembler uses it.  The overlay
+            tracking table uses it.  */
          {
            int mpgloc = vif_get_mpgloc ();
+           offsetT addr = mpgloc * 8;
+           const char * section_name = vuoverlay_section_name (addr);
+           vif_data_start = create_colon_label (STO_DVP_VU,
+                                                VUOVERLAY_START_PREFIX,
+                                                section_name);
+           insn_frag->fr_symbol = vif_data_start;
+
+           /* Get the value of mpgloc.  If it wasn't '*'
+              then update $.mpgloc.  */
+           /* FIXME: Need to handle `*' case as well.  */
            if (mpgloc != -1)
              {
-               mpgloc_sym->sy_value.X_op = O_constant;
                /* The value is recorded in bytes.  */
-               mpgloc_sym->sy_value.X_add_number = mpgloc * 8;
-               mpgloc_sym->sy_value.X_unsigned = 1;
+               create_vuoverlay_section (section_name, addr,
+                                         vif_data_start, vif_data_end);
              }
          }
        }
@@ -1150,16 +1187,9 @@ assemble_one_insn (cpu, opcode, operand_table, init_fixup_count, fixup_offset,
              if (!(operand->flags & DVP_OPERAND_SUFFIX))
                as_fatal ("internal error: bad opcode table, missing suffix flag");
 
-             /* If we're at a space in the input string, we want to skip the
-                remaining suffixes.  There may be some fake ones though, so
-                just go on to try the next one.  */
-             if (*str == ' ')
-               {
-                 ++syn;
-                 continue;
-               }
-
-             /* Parse the suffix.  */
+             /* Parse the suffix.  If we're at a space in the input string
+                there are no more suffixes.  Suffix parse routines must be
+                prepared to deal with this.  */
              errmsg = NULL;
              suf_value = (*operand->parse) (opcode, operand, mods, &str,
                                             &errmsg);
@@ -1495,10 +1525,23 @@ dvp_frob_label (sym)
       /* Check for recursive invocation creating the _$name.  */
       && strncmp (name, VU_LABEL_PREFIX, sizeof (VU_LABEL_PREFIX) - 1) != 0)
     {
-      /* Move this symbol to vu space.  */
+      /* Move this symbol to the vu overlay.  */
       symbolS * cur_mpgloc = compute_mpgloc (mpgloc_sym, vif_data_start,
                                             expr_build_dot ());
+#if 0 /* Don't do this now, leave in ABS and then move to overlay
+        section before file is written.  */
+      S_SET_SEGMENT (sym, vuoverlay_section);
+#else
+      /* Record the overlay section this symbol is in.  */
+      {
+       ovlysymS *p = (ovlysymS *) xmalloc (sizeof (ovlysymS));
+       p->next = ovlysym_table;
+       p->sec = vuoverlay_section;
+       p->sym = sym;
+       ovlysym_table = p;
+      }
       S_SET_SEGMENT (sym, expr_section);
+#endif
       sym->sy_value = cur_mpgloc->sy_value;
       sym->sy_frag = &zero_address_frag;
 
@@ -1506,6 +1549,24 @@ dvp_frob_label (sym)
       create_colon_label (STO_DVP_VU, VU_LABEL_PREFIX, name);
     }
 }
+
+/* Move vu space symbols into their overlay sections.
+   Called via tc_frob_file.  */
+
+void
+dvp_frob_file ()
+{
+  ovlysymS *p;
+
+  for (p = ovlysym_table; p; p = p->next)
+    {
+      /* See the comment near tc_frob_file in write.c.
+        We are responsible for updating sym->bsym->value.  */
+      S_SET_SEGMENT (p->sym, p->sec);
+      /* Adjust for the section's vma.  */
+      p->sym->bsym->value -= bfd_get_section_vma (stdoutput, p->sec);
+    }
+}
 \f
 /* mpg/direct alignment is handled via relaxation */
 
@@ -1885,8 +1946,10 @@ md_apply_fix3 (fixP, valueP, seg)
          return 1;
        }
     }
-  else
+  else if (fixP->fx_done)
     {
+      /* We're finished with this fixup.  Install it because
+        bfd_install_relocation won't be called to do it.  */
       switch (fixP->fx_r_type)
        {
        case BFD_RELOC_8:
@@ -1902,7 +1965,13 @@ md_apply_fix3 (fixP, valueP, seg)
          as_fatal ("internal error: unexpected fixup");
        }
     }
+  else
+    {
+      /* bfd_install_relocation will be called to finish things up.  */
+    }
 
+  /* Tuck `value' away for use by tc_gen_reloc.
+     See the comment describing fx_addnumber in write.h.  */
   fixP->fx_addnumber = value;
 
   return 1;
@@ -2169,6 +2238,99 @@ unique_name (prefix)
   ++counter;
   return result;
 }
+\f
+/* VU support.  */
+
+/* Return the name of the overlay section.
+   It must be unique among all overlays in the executable.  */
+
+static char *
+vuoverlay_section_name (addr)
+     offsetT addr;
+{
+  char *section_name;
+  char *file;
+  unsigned int lineno;
+  unsigned int fileno;
+  /* One mpg may actually result in several, counter keeps track of this.  */
+  static int counter;
+
+  as_where (&file, &lineno);
+  for (fileno = 0; *file; ++file)
+    fileno = (fileno << 1) + *file;
+  asprintf (&section_name, "%s0x%x.%u.%u.%d", VUOVERLAY_SECTION_PREFIX,
+           (int) addr, fileno, lineno, counter);
+  ++counter;
+  return section_name;
+}
+
+/* Create a shadow section for VU code that starts at ADDR in vu space.
+   START_LABEL and END_LABEL, if non-NULL, are symbols marking the start and
+   end of the section.  If NULL, no overlay tracking information is output.  */
+
+static void
+create_vuoverlay_section (section_name, addr, start_label, end_label)
+     const char *section_name;
+     offsetT addr;
+     symbolS *start_label, *end_label;
+{
+  /* Must preserve the current seg/subseg.  */
+  segT orig_seg = now_seg;
+  subsegT orig_subseg = now_subseg;
+
+  /* Create and get handle of .vuoverlay section.  All vu symbols go here.
+     The section name must be unique in the entire executable.
+     We achieve this by encoding the source file name and file number.  Ick.
+     ??? A cleaner way would be if mpg took a new argument that named the
+     overlay.  */
+  vuoverlay_section = subseg_new (section_name, 0);
+  bfd_set_section_flags (stdoutput, vuoverlay_section, 0);
+  /* There's no point in setting the section vma as we can't get the linker
+     to preserve it.  But what the heck ...  It might be useful to the
+     objdump user.  */
+  bfd_set_section_vma (stdoutput, vuoverlay_section, addr);
+  /* The size of the section won't be known until we see the .endmpg,
+     but we can compute it from the start and end labels.  */
+  /* FIXME: This causes the section to occupy space in the file.  */
+  if (start_label)
+    frag_var (rs_space, 1, 1, (relax_substateT) 0,
+             expr_build_binary (O_subtract, end_label, start_label),
+             (offsetT) 0, (char *) 0);
+#if 0
+  /* Create a symbol marking the start of the section.  */
+  begin_label = create_colon_label (STO_DVP_VU, "__start_", section_name);
+#endif
+
+  /* Initialize $.mpgloc.  */
+  mpgloc_sym = expr_build_uconstant (addr);
+
+#if 0 /* $.mpgloc is kept in the ABS section.  */
+  S_SET_SEGMENT (mpgloc_sym, vuoverlay_section);
+#endif
+
+  /* Add an entry to the vu overlay table.  */
+  if (start_label)
+    {
+      /* FIXME: should be a service routine to do these.  */
+      expressionS exp;
+
+      subseg_set (vuoverlay_table_section, 0);
+
+      /* The section's lma.  */
+      exp.X_op = O_symbol;
+      exp.X_add_symbol = start_label;
+      exp.X_add_number = 0;
+      emit_expr (&exp, 8);
+
+      /* The section's vma.  */
+      exp.X_op = O_constant;
+      exp.X_add_number = addr;
+      emit_expr (&exp, 8);
+    }
+
+  /* Restore the original seg/subseg.  */
+  subseg_set (orig_seg, orig_subseg);
+}
 
 /* Compute a value for $.mpgloc given a symbol at the start of a chunk
    of code, the $.mpgloc value for the start, and a symbol at the end
@@ -2971,8 +3133,12 @@ s_state (state)
         in use versions of these.  Also need to worry about which section
         the .vu is issued in.  On the other hand, ".vu" isn't intended
         to be supported everywhere.  */
-      mpgloc_sym = expr_build_uconstant (0);
       vif_data_start = expr_build_dot ();
+#if 0
+      create_vuoverlay_section (vuoverlay_section_name (0), 0, NULL, NULL);
+#else
+      mpgloc_sym = expr_build_uconstant (0);
+#endif
     }
 
   set_asm_state (state);
index 869ef72a93ba902f6d3e3c67f556ca8b47e62675..af5f196ec95e8d2c7fe4b0bf140b46db1c7df9ba 100644 (file)
 /* We don't need to handle .word strangely.  */
 #define WORKING_DOT_WORD
 
-#define md_convert_frag(b,s,f)         {as_fatal ("dvp convert_frag\n");}
-#define md_estimate_size_before_relax(f,s) \
-                       (as_fatal("estimate_size_before_relax called"),1)
+/* Handle mpg/direct alignment requirements with relaxation.  */
+extern long dvp_relax_frag PARAMS ((fragS *, long));
+#define md_relax_frag(fragP,stretch) dvp_relax_frag ((fragP), (stretch))
 
 #define MD_APPLY_FIX3
 
+/* Ensure insns at labels have their mach type properly recorded.  */
+int force_mach_label PARAMS ((void));
+#define TC_START_LABEL(ch, ptr)        (ch == ':' && force_mach_label ())
+
 #define TC_HANDLES_FX_DONE
 
+/* Record user specified val, for cases where we can't compute the actual
+   value until the end of assembly.  */
+#define TC_FIX_TYPE \
+struct { \
+  int type; /* gif_type, or vif type */ \
+  int nregs; /* for gif insns only */ \
+  short wl; short cl; /* for unpack only */ \
+  int user_value; \
+}
+/* Code to initialize it.  */
+#define TC_INIT_FIX_DATA(fixP) \
+do { memset (&fixP->tc_fix_data, 0, sizeof (fixP->tc_fix_data)); } while (0)
+
 /* Called after parsing a file.  */
 extern void dvp_parse_done PARAMS ((void));
 #define md_after_pass_hook() dvp_after_pass_hook ()
 
+/* Called for each label.  */
 extern void dvp_frob_label PARAMS ((struct symbol *));
 #define tc_frob_label(sym) dvp_frob_label (sym)
 
+/* Called just before writing the file out.  */
+extern void dvp_frob_file PARAMS ((void));
+#define tc_frob_file() dvp_frob_file ()
+
 /* Default section names. */
 #define TEXT_SECTION_NAME      ".vutext"
 #define DATA_SECTION_NAME      ".vudata"
 #define BSS_SECTION_NAME       ".vubss"
 
+/* Other special section names.  */
+#define VUOVERLAY_SECTION_PREFIX       ".vuoverlay."
+#define VUOVERLAY_TABLE_SECTION_NAME   ".vuoverlay_table"
+
 #define ELF_TC_SPECIAL_SECTIONS \
   { ".vubss",  SHT_NOBITS,     SHF_ALLOC + SHF_WRITE           }, \
   { ".vudata", SHT_PROGBITS,   SHF_ALLOC + SHF_WRITE           }, \
-  { ".vutext", SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       },
-
+  { ".vutext", SHT_PROGBITS,   SHF_ALLOC + SHF_EXECINSTR       }, \
+  { ".vuoverlay_table", SHT_NOBITS, SHF_ALLOC + SHF_WRITE      },