From: Doug Evans Date: Thu, 28 May 1998 23:29:19 +0000 (+0000) Subject: * config/tc-dvp.h (ELF_TC_SPECIAL_SECTIONS): Add .vuoverlay_table. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1554baf3cb417eee611e452a47d889252a4924ce;p=binutils-gdb.git * 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. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 8e152e35362..449c66afe05 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,22 @@ +start-sanitize-sky +Thu May 28 16:23:08 1998 Doug Evans + + * 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 * 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 9b02c3e8ac8..6188902e8d8 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 (§ion_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 869ef72a93b..af5f196ec95 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 },