From 918692a5cc5fa2dab2fa9018c4db22af7a79b99f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 7 Jul 1993 17:23:39 +0000 Subject: [PATCH 1/1] * config/mips-opcode.h: Moved to opcode/mips.h. * config/tc-mips.c: Include opcode/mips.h rather than mips-opcode.h. (append_insn): An extra NOP is only needed after instructions which set HI or LO, not after instructions which read it. (macro_build, mips_ip): Support new 'E', 'G' and 'B' arguments. (macro): cfc1 and ctc1 now take "t,G" rather than "t,d". * config/tc-mips.h (struct mips_opcode): Don't define. * config/mips-big.mt, config/mips-lit.mt (TARG_CPU_DEPENDENTS): Set to $(srcdir)/../include/opcode/mips.h. Get the MIPS assembler up to speed with other gas changes: * config/obj-ecoff.c (ecoff_set_vma, ecoff_frob_symbol): Removed; don't change the symbol value. (ecoff_build_symbols, ecoff_build_procs, ecoff_frob_file): Use bfd_asymbol_value rather than S_GET_VALUE to include section vma in symbol value. (ecoff_frob_file): Ignore BSF_SECTION_SYM symbols, since ECOFF doesn't output them. Set the vma of sections. * config/obj-ecoff.h: Don't define obj_frob_symbol. * config/tc-mips.c (tc_gen_reloc): Adjustment by section vma is no longer necessary. (various): use valueT rather than long. --- gas/config/.Sanitize | 1 - gas/config/mips-big.mt | 1 + gas/config/mips-lit.mt | 1 + gas/config/obj-ecoff.c | 154 +++++++++++++++++++++++++---------------- gas/config/tc-mips.c | 57 +++++++++------ gas/config/tc-mips.h | 14 +--- 6 files changed, 135 insertions(+), 93 deletions(-) diff --git a/gas/config/.Sanitize b/gas/config/.Sanitize index 79b1eb26dd..b4ee3c1a05 100644 --- a/gas/config/.Sanitize +++ b/gas/config/.Sanitize @@ -63,7 +63,6 @@ m88k-opcode.h m88k.patches mips-big.mt mips-lit.mt -mips-opcode.h obj-aout.c obj-aout.h obj-bout.c diff --git a/gas/config/mips-big.mt b/gas/config/mips-big.mt index 31e773a14d..a26f4846d2 100644 --- a/gas/config/mips-big.mt +++ b/gas/config/mips-big.mt @@ -1 +1,2 @@ TDEFINES=-DTARGET_BYTES_BIG_ENDIAN +TARG_CPU_DEPENDENTS=$(srcdir)/../include/opcode/mips.h diff --git a/gas/config/mips-lit.mt b/gas/config/mips-lit.mt index 9e240e8166..9faa183399 100644 --- a/gas/config/mips-lit.mt +++ b/gas/config/mips-lit.mt @@ -1 +1,2 @@ TDEFINES=-DTARGET_BYTES_LITTLE_ENDIAN +TARG_CPU_DEPENDENTS=$(srcdir)/../include/opcode/mips.h diff --git a/gas/config/obj-ecoff.c b/gas/config/obj-ecoff.c index 35567f11bf..69ecbc21c6 100644 --- a/gas/config/obj-ecoff.c +++ b/gas/config/obj-ecoff.c @@ -35,6 +35,9 @@ /* Why isn't this in coff/sym.h? */ #define ST_RFDESCAPE 0xfff +/* Why isn't this in listing.h? */ +extern int listing; + /* The ECOFF file format uses COFF style sections, but with a unique debugging format. We just build generic BFD sections since BFD knows how to write them out. The debugging format, however, we @@ -975,7 +978,7 @@ static const efdr_t init_file = 0, /* rfdBase: index into the file indirect table */ 0, /* crfd: count file indirect entries */ langC, /* lang: language for this file */ - 1, /* fMerge: whether this file can be merged */ + 0, /* fMerge: whether this file can be merged */ 0, /* fReadin: true if read in (not just created) */ #ifdef TARGET_BYTES_BIG_ENDIAN 1, /* fBigendian: if 1, compiled on big endian machine */ @@ -1479,7 +1482,6 @@ static long ecoff_build_ss PARAMS ((char **buf, char **bufend, long offset)); static long ecoff_build_fdr PARAMS ((char **buf, char **bufend, long offset)); -static void ecoff_set_vma PARAMS ((void)); static page_t *allocate_cluster PARAMS ((unsigned long npages)); static page_t *allocate_page PARAMS ((void)); static scope_t *allocate_scope PARAMS ((void)); @@ -1563,8 +1565,6 @@ void obj_read_begin_hook () { tag_hash = hash_new (); - if (tag_hash == (struct hash_control *) NULL) - as_fatal ("Can't create hash table"); top_tag_head = allocate_thead (); top_tag_head->first_tag = (tag_t *) NULL; top_tag_head->free = (thead_t *) NULL; @@ -1578,6 +1578,8 @@ void obj_symbol_new_hook (symbolP) symbolS *symbolP; { + if (cur_file_ptr == (efdr_t *) NULL) + add_file ((const char *) NULL, 0); symbolP->ecoff_file = cur_file_ptr; symbolP->ecoff_symbol = 0; symbolP->ecoff_undefined = 0; @@ -1679,7 +1681,7 @@ add_ecoff_symbol (str, type, storage, sym_value, value, indx) register thead_t *ptag_head; register tag_t *ptag; register tag_t *ptag_next; - register varray_t *vp = &cur_file_ptr->symbols; + register varray_t *vp; register int scope_delta = 0; shash_t *hash_ptr = (shash_t *) NULL; @@ -2266,6 +2268,11 @@ add_file (file_name, indx) } } +#ifndef NO_LISTING + if (listing) + listing_source_file (file_name); +#endif + /* If we're creating stabs, then we don't actually make a new FDR. Instead, we just create a stabs symbol. */ if (stabs_seen) @@ -2307,8 +2314,6 @@ add_file (file_name, indx) /* Allocate the string hash table. */ fil_ptr->str_hash = hash_new (); - if (fil_ptr->str_hash == (struct hash_control *) NULL) - as_fatal ("Can't create hash table"); /* Make sure 0 byte in string table is null */ add_string (&fil_ptr->strings, @@ -3216,6 +3221,7 @@ obj_ecoff_loc (ignore) int ignore; { lineno_list_t *list; + int lineno; if (cur_file_ptr == (efdr_t *) NULL) { @@ -3236,6 +3242,13 @@ obj_ecoff_loc (ignore) get_absolute_expression (); SKIP_WHITESPACE (); + lineno = get_absolute_expression (); + +#ifndef NO_LISTING + if (listing) + listing_source_line (lineno); +#endif + /* If we're building stabs, then output a special label rather than ECOFF line number info. */ if (stabs_seen) @@ -3243,7 +3256,7 @@ obj_ecoff_loc (ignore) (void) add_ecoff_symbol ((char *) NULL, st_Label, sc_Text, symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now), - 0, get_absolute_expression ()); + 0, lineno); return; } @@ -3254,7 +3267,7 @@ obj_ecoff_loc (ignore) list->proc = cur_proc_ptr; list->frag = frag_now; list->paddr = frag_now_fix (); - list->lineno = get_absolute_expression (); + list->lineno = lineno; /* A .loc directive will sometimes appear before a .ent directive, which means that cur_proc_ptr will be NULL here. Arrange to @@ -3332,6 +3345,12 @@ obj_ecoff_stab (type) st_t st; sc_t sc; + if (cur_file_ptr == (efdr_t *) NULL) + { + add_file ((const char *) NULL, 0); + save_file_ptr = cur_file_ptr; + } + if (stabs_seen == 0) mark_stabs (0); @@ -3393,6 +3412,11 @@ obj_ecoff_stab (type) code = (symint_t) get_absolute_expression (); +#ifndef NO_LISTING + if (listing) + listing_source_line (code); +#endif + if (*input_line_pointer++ != ',') { as_warn ("Bad .stab%c directive", type); @@ -3423,6 +3447,11 @@ obj_ecoff_stab (type) } else { +#ifndef NO_LISTING + if (listing && (code == N_SO || code == N_SOL)) + listing_source_file (string); +#endif + /* The next number is sometimes the line number of the declaration. We have nowhere to put it, so we just ignore it. */ @@ -3551,6 +3580,9 @@ ecoff_build_lineno (buf, bufend, offset, linecntptr) long iline; long totcount; + if (linecntptr != (long *) NULL) + *linecntptr = 0; + bufptr = *buf + offset; file = (efdr_t *) NULL; @@ -3591,6 +3623,9 @@ ecoff_build_lineno (buf, bufend, offset, linecntptr) /* The cline field is ill-documented. This is a guess at the right value. */ file->fdr.cline = totcount + count; + if (linecntptr != (long *) NULL) + *linecntptr += totcount + count; + totcount = 0; } if (l->file != file) @@ -3710,10 +3745,10 @@ ecoff_build_lineno (buf, bufend, offset, linecntptr) file->fdr.cline = totcount; } - c = ecoff_longword_adjust (buf, bufend, c, &bufptr); - if (linecntptr != (long *) NULL) - *linecntptr = totcount; + *linecntptr += totcount; + + c = ecoff_longword_adjust (buf, bufend, c, &bufptr); return c; } @@ -3815,11 +3850,20 @@ ecoff_build_symbols (buf, { know (sym_ptr->proc_ptr != (proc_t *) NULL); sym_ptr->ecoff_sym.value = - (S_GET_VALUE (as_sym) - - S_GET_VALUE (sym_ptr->proc_ptr->sym->as_sym)); + (bfd_asymbol_value (as_sym->bsym) + - bfd_asymbol_value (sym_ptr->proc_ptr->sym + ->as_sym->bsym)); } else - sym_ptr->ecoff_sym.value = S_GET_VALUE (as_sym); + sym_ptr->ecoff_sym.value = + bfd_asymbol_value (as_sym->bsym); + + /* Set st_Proc to st_StaticProc for local + functions. */ + if (sym_ptr->ecoff_sym.st == st_Proc + && S_IS_DEFINED (as_sym) + && ! S_IS_EXTERNAL (as_sym)) + sym_ptr->ecoff_sym.st = st_StaticProc; /* Get the type and storage class based on where the symbol actually wound up. Traditionally, @@ -3878,6 +3922,8 @@ ecoff_build_symbols (buf, sc = sc_Bss; else if (strcmp (segname, ".sbss") == 0) sc = sc_SBss; + else if (seg == &bfd_abs_section) + sc = sc_Abs; else abort (); @@ -3955,8 +4001,8 @@ ecoff_build_symbols (buf, know (as_sym != (symbolS *) NULL); know (begin_ptr->as_sym != (symbolS *) NULL); sym_ptr->ecoff_sym.value = - (S_GET_VALUE (as_sym) - - S_GET_VALUE (begin_ptr->as_sym)); + (bfd_asymbol_value (as_sym->bsym) + - bfd_asymbol_value (begin_ptr->as_sym->bsym)); } else if (begin_type == st_Block && sym_ptr->ecoff_sym.sc != (int) sc_Info) @@ -3964,8 +4010,9 @@ ecoff_build_symbols (buf, know (as_sym != (symbolS *) NULL); know (sym_ptr->proc_ptr != (proc_t *) NULL); sym_ptr->ecoff_sym.value = - (S_GET_VALUE (as_sym) - - S_GET_VALUE (sym_ptr->proc_ptr->sym->as_sym)); + (bfd_asymbol_value (as_sym->bsym) + - bfd_asymbol_value (sym_ptr->proc_ptr->sym + ->as_sym->bsym)); } } @@ -4008,6 +4055,12 @@ ecoff_build_symbols (buf, memset (&ext, 0, sizeof ext); ext.asym = sym_ptr->ecoff_sym; + if (sym_ptr->ecoff_sym.st == st_Proc + || sym_ptr->ecoff_sym.st == st_StaticProc) + { + know (local); + ext.asym.index = isym - ifilesym - 1; + } ext.ifd = fil_ptr->file_index; ext.asym.iss = add_string (ext_strings, ext_str_hash, @@ -4043,11 +4096,13 @@ ecoff_build_procs (buf, bufend, offset) long offset; { struct pdr_ext *pdr_out; + int first_fil; long iproc; vlinks_t *file_link; pdr_out = (struct pdr_ext *) (*buf + offset); + first_fil = 1; iproc = 0; /* The procedures are stored by file. */ @@ -4090,10 +4145,13 @@ ecoff_build_procs (buf, bufend, offset) { unsigned long adr; - adr = S_GET_VALUE (proc_ptr->sym->as_sym); + adr = bfd_asymbol_value (proc_ptr->sym->as_sym->bsym); if (first) { - fil_ptr->fdr.adr = adr; + if (first_fil) + first_fil = 0; + else + fil_ptr->fdr.adr = adr; first = 0; } proc_ptr->pdr.adr = adr - fil_ptr->fdr.adr; @@ -4349,42 +4407,6 @@ ecoff_build_fdr (buf, bufend, offset) return offset + ifile * sizeof (struct fdr_ext); } -/* Set the vma for all the sections. */ - -static void -ecoff_set_vma () -{ - register bfd_vma addr; - register asection *sec; - - addr = 0; - for (sec = stdoutput->sections; sec != (asection *) NULL; sec = sec->next) - { - bfd_set_section_vma (stdoutput, sec, addr); - addr += bfd_section_size (stdoutput, sec); - } -} - -/* Adjust the value of a symbol by the vma of the section. */ - -void -ecoff_frob_symbol (sym) - symbolS *sym; -{ - static int setvma = 0; - - if (! setvma) - { - ecoff_set_vma (); - setvma = 1; - } - - S_SET_VALUE (sym, - (S_GET_VALUE (sym) - + bfd_get_section_vma (stdoutput, - bfd_get_section (sym->bsym)))); -} - /* Swap out the symbols and debugging information for BFD. */ void @@ -4395,6 +4417,8 @@ ecoff_frob_file () efdr_t *fil_ptr; efdr_t *hold_file_ptr; proc_t * hold_proc_ptr; + bfd_vma addr; + asection *sec; symbolS *sym; HDRR *hdr; char *buf; @@ -4442,6 +4466,14 @@ ecoff_frob_file () (symint_t) 0); } + /* Set the section VMA values. */ + addr = 0; + for (sec = stdoutput->sections; sec != (asection *) NULL; sec = sec->next) + { + bfd_set_section_vma (stdoutput, sec, addr); + addr += bfd_section_size (stdoutput, sec); + } + /* Look through the symbols. Add debugging information for each symbol that has not already received it. */ hold_file_ptr = cur_file_ptr; @@ -4450,12 +4482,13 @@ ecoff_frob_file () for (sym = symbol_rootP; sym != (symbolS *) NULL; sym = symbol_next (sym)) { if (sym->ecoff_symbol - || sym->ecoff_file == (efdr_t *) NULL) + || sym->ecoff_file == (efdr_t *) NULL + || (sym->bsym->flags & BSF_SECTION_SYM) != 0) continue; cur_file_ptr = sym->ecoff_file; add_ecoff_symbol ((const char *) NULL, st_Nil, sc_Nil, sym, - S_GET_VALUE (sym), indexNil); + bfd_asymbol_value (sym->bsym), indexNil); } cur_proc_ptr = hold_proc_ptr; cur_file_ptr = hold_file_ptr; @@ -4571,6 +4604,9 @@ ecoff_frob_file () hdr->magic = magicSym; /* FIXME: what should hdr->vstamp be? */ + + bfd_set_symtab (stdoutput, bfd_get_outsymbols (stdoutput), + hdr->isymMax + hdr->iextMax); } /* Allocate a cluster of pages. */ diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 6a5e79f1ec..709b5d5e1e 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -38,7 +38,7 @@ #endif /* NO_VARARGS */ #endif /* NO_STDARG */ -#include "mips-opcode.h" +#include "opcode/mips.h" #define AT 1 #define GP 28 @@ -212,7 +212,7 @@ const pseudo_typeS md_pseudo_table[] = const relax_typeS md_relax_table[] = { - 0 + { 0 } }; @@ -287,7 +287,9 @@ md_assemble (str) /* set the default alignment for the text section (2**2) */ /* This should go in md_begin but text_section isn't initialized then */ record_alignment (text_section, 2); +#ifdef OBJ_ECOFF bfd_set_gp_size (stdoutput, g_switch_value); +#endif init = 1; } @@ -389,7 +391,7 @@ append_insn (ip, address_expr, reloc_type) }; /* One extra nop */ - if (ip->insn_mo->pinfo & INSN_EXTRA_DELAY) + if (ip->insn_mo->pinfo & (INSN_READ_HI | INSN_READ_LO)) { f = frag_more (4); md_number_to_chars (f, 0, 4); @@ -508,6 +510,7 @@ macro_build (counter, ep, name, fmt, va_alist) case 't': case 'w': + case 'E': insn.insn_opcode |= va_arg (args, int) << 16; continue; @@ -518,6 +521,7 @@ macro_build (counter, ep, name, fmt, va_alist) continue; case 'd': + case 'G': insn.insn_opcode |= va_arg (args, int) << 11; continue; @@ -534,6 +538,10 @@ macro_build (counter, ep, name, fmt, va_alist) insn.insn_opcode |= va_arg (args, int) << 6; continue; + case 'B': + insn.insn_opcode |= va_arg (args, int) << 6; + continue; + case 'b': case 's': case 'r': @@ -1776,18 +1784,18 @@ macro (ip) */ save_reorder_condition = mips_noreorder; mips_noreorder = 1; - macro_build (&icnt, NULL, "cfc1", "t,d", treg, 31); - macro_build (&icnt, NULL, "cfc1", "t,d", treg, 31); + macro_build (&icnt, NULL, "cfc1", "t,G", treg, 31); + macro_build (&icnt, NULL, "cfc1", "t,G", treg, 31); macro_build (&icnt, NULL, "nop", ""); expr1.X_add_number = 3; macro_build (&icnt, &expr1, "ori", "t,r,i", AT, treg); expr1.X_add_number = 2; macro_build (&icnt, &expr1, "xori", "t,r,i", AT, AT); - macro_build (&icnt, NULL, "ctc1", "t,d", AT, 31); + macro_build (&icnt, NULL, "ctc1", "t,G", AT, 31); macro_build (&icnt, NULL, "nop", ""); macro_build (&icnt, NULL, mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S", dreg, sreg); - macro_build (&icnt, NULL, "ctc1", "t,d", treg, 31); + macro_build (&icnt, NULL, "ctc1", "t,G", treg, 31); macro_build (&icnt, NULL, "nop", ""); mips_noreorder = save_reorder_condition; break; @@ -2025,6 +2033,16 @@ mips_ip (str, ip) s = expr_end; continue; + case 'B': /* syscall code */ + my_getExpression (&imm_expr, s); + check_absolute_expr (ip, &imm_expr); + if ((unsigned) imm_expr.X_add_number > 0xfffff) + as_warn ("Illegal syscall code (%d)", imm_expr.X_add_number); + ip->insn_opcode |= imm_expr.X_add_number << 6; + imm_expr.X_seg = absent_section; + s = expr_end; + continue; + case 'b': /* base register */ case 'd': /* destination register */ case 's': /* source register */ @@ -2032,6 +2050,8 @@ mips_ip (str, ip) case 'r': /* both target and source */ case 'v': /* both dest and source */ case 'w': /* both dest and target */ + case 'E': /* coprocessor target register */ + case 'G': /* coprocessor destination register */ s_reset = s; if (s[0] == '$') { @@ -2094,10 +2114,12 @@ mips_ip (str, ip) ip->insn_opcode |= regno << 21; break; case 'd': + case 'G': ip->insn_opcode |= regno << 11; break; case 'w': case 't': + case 'E': ip->insn_opcode |= regno << 16; } lastregno = regno; @@ -2424,7 +2446,7 @@ md_atof (type, litP, sizeP) void md_number_to_chars (buf, val, n) char *buf; - long val; + valueT val; int n; { switch (byte_order) @@ -2527,7 +2549,7 @@ md_pcrel_from (fixP) int md_apply_fix (fixP, valueP) fixS *fixP; - long *valueP; + valueT *valueP; { unsigned char *buf; long insn, value; @@ -2577,7 +2599,7 @@ md_apply_fix (fixP, valueP) return 0; } insn |= value & 0xFFFF; - md_number_to_chars (buf, insn, 4); + md_number_to_chars ((char *) buf, insn, 4); break; default: @@ -2628,10 +2650,12 @@ printInsn (oc) continue; case 'd': + case 'G': printf ("$%d", dreg); continue; case 't': + case 'E': printf ("$%d", treg); continue; @@ -3042,23 +3066,14 @@ tc_gen_reloc (section, fixp) reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); assert (reloc->howto != 0); -#ifdef OBJ_ECOFF - /* FIXME: This does the right thing, but it's confusing. There - should be a more coherent approach, but I don't know what it - would be. */ - reloc->addend -= - bfd_get_section_vma (stdoutput, - bfd_get_section (fixp->fx_addsy->bsym)); -#endif - return reloc; } /* should never be called */ -long +valueT md_section_align (seg, addr) asection *seg; - long addr; + valueT addr; { int align = bfd_get_section_alignment (stdoutput, seg); diff --git a/gas/config/tc-mips.h b/gas/config/tc-mips.h index b0fb9f7b46..c4f7563f97 100644 --- a/gas/config/tc-mips.h +++ b/gas/config/tc-mips.h @@ -24,16 +24,14 @@ #define TARGET_ARCH bfd_arch_mips -#define NO_LISTING #define ONLY_STANDARD_ESCAPES #define BACKSLASH_V #define WORKING_DOT_WORD 1 #define OLD_FLOAT_READS +#define REPEAT_CONS_EXPRESSIONS #define LOCAL_LABELS_FB -#ifdef OBJ_ECOFF -#define LOCAL_LABEL(name) ((name)[0] == '$' && (name)[1] == 'L') -#endif +#define LOCAL_LABEL(name) ((name)[0] == '$') #define md_undefined_symbol(name) (0) #define md_operand(x) @@ -72,14 +70,6 @@ #endif /* OBJ_ECOFF */ #endif /* ! defined (TARGET_FORMAT) */ -struct mips_opcode { - const char *name; - const char *args; - unsigned long match; - unsigned long mask; /* used only for error checking */ - unsigned long pinfo; /* Information used for insn/pipeline scheduling. */ -}; - struct mips_cl_insn { unsigned long insn_opcode; const struct mips_opcode *insn_mo; -- 2.34.1