aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog19
-rw-r--r--gas/config/tc-dvp.c216
-rw-r--r--gas/config/tc-dvp.h36
3 files changed, 241 insertions, 30 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 8e152e3..449c66a 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/config/tc-dvp.c b/gas/config/tc-dvp.c
index 9b02c3e..6188902 100644
--- a/gas/config/tc-dvp.c
+++ b/gas/config/tc-dvp.c
@@ -52,11 +52,16 @@
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);
+ }
+}
/* 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;
}
+
+/* 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);
diff --git a/gas/config/tc-dvp.h b/gas/config/tc-dvp.h
index 869ef72..af5f196 100644
--- a/gas/config/tc-dvp.h
+++ b/gas/config/tc-dvp.h
@@ -45,28 +45,54 @@
/* 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 },