From c625fc23ba7d7b641d27b95dbc3d25f72df6ca22 Mon Sep 17 00:00:00 2001 From: Jackie Smith Cashion Date: Mon, 23 Oct 1995 11:20:02 +0000 Subject: [PATCH] Added command-line support for NEC VR4100, to allow support for 4100-specific instructions. --- gas/ChangeLog | 11 +++++ gas/config/tc-mips.c | 136 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 125 insertions(+), 22 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index b6ccbd6..8cecc9c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,15 @@ +Mon Oct 23 11:15:44 1995 James G. Smith + + * config/tc-mips.c: Added mips_4100 control, and support for + accepting the 4100 as a MIPS architecture variant (md_begin, + macro_build, mips_ip, md_parse_option). Adding suitable + command-line OPTIONs, and updating the help text (md_show_usage). + Wed Oct 18 13:20:32 1995 Ken Raeburn + * subsegs.c (subseg_begin): Only set absolute_frchain.fix_* when + BFD_ASSEMBLER is defined. + * Use one active frag and one obstack per frag chain: * frags.c (frags): Variable deleted. (frag_alloc): New function. @@ -25,6 +35,7 @@ Wed Oct 18 13:20:32 1995 Ken Raeburn frch_last and frag_now match on entry and exit. Initialize per-chain obstack, and under gcc, set required alignment to that needed by fragS structure. + * write.c (chain_frchains_together_1): Verify fr_type is nonzero. * stabs.c (get_stab_string_offset): Only copy input string if a diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index a89c190..970b313 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -63,6 +63,7 @@ static int mips_output_flavor () { return OUTPUT_FLAVOR; } #endif #ifndef ECOFF_DEBUGGING +#define NO_ECOFF_DEBUGGING #define ECOFF_DEBUGGING 0 #endif @@ -129,6 +130,9 @@ static int mips_4650 = -1; /* Whether the 4010 instructions are permitted. */ static int mips_4010 = -1; +/* Whether the 4100 MADD16 and DMADD16 are permitted. */ +static int mips_4100 = -1; + /* Whether the processor uses hardware interlocks, and thus does not require nops to be inserted. */ static int interlocks = -1; @@ -377,9 +381,13 @@ static void append_insn PARAMS ((char *place, bfd_reloc_code_real_type r)); static void mips_no_prev_insn PARAMS ((void)); static void mips_emit_delays PARAMS ((void)); +#ifdef USE_STDARG static void macro_build PARAMS ((char *place, int *counter, expressionS * ep, const char *name, const char *fmt, ...)); +#else +static void macro_build (); +#endif static void macro_build_lui PARAMS ((char *place, int *counter, expressionS * ep, int regnum)); static void set_at PARAMS ((int *counter, int reg, int unsignedp)); @@ -496,15 +504,6 @@ static const pseudo_typeS mips_nonecoff_pseudo_table[] = { { 0 }, }; -static const pseudo_typeS mips_elf_pseudo_table[] = { - /* Redirect additional ELF data allocation pseudo-ops. */ - {"2byte", s_cons, 2}, - {"4byte", s_cons, 4}, - {"8byte", s_cons, 8}, - /* Sentinel. */ - {NULL} -}; - extern void pop_insert PARAMS ((const pseudo_typeS *)); void @@ -513,8 +512,6 @@ mips_pop_insert () pop_insert (mips_pseudo_table); if (! ECOFF_DEBUGGING) pop_insert (mips_nonecoff_pseudo_table); - if (OUTPUT_FLAVOR == bfd_target_elf_flavour) - pop_insert (mips_elf_pseudo_table); } static char *expr_end; @@ -591,6 +588,20 @@ md_begin () if (mips_4650 == -1) mips_4650 = 1; } + else if (strcmp (cpu, "mips64vr4300") == 0) + { + mips_isa = 3; + if (mips_cpu == -1) + mips_cpu = 4300; + } + else if (strcmp (cpu, "mips64vr4100") == 0) + { + mips_isa = 3; + if (mips_cpu == -1) + mips_cpu = 4100; + if (mips_4100 == -1) + mips_4100 = 1; + } else if (strcmp (cpu, "r4010") == 0) { mips_isa = 2; @@ -629,7 +640,10 @@ md_begin () if (mips_4010 < 0) mips_4010 = 0; - if (mips_4650 || mips_4010) + if (mips_4100 < 0) + mips_4100 = 0; + + if (mips_4650 || mips_4010 || mips_4100) interlocks = 1; else interlocks = 0; @@ -958,7 +972,7 @@ append_insn (place, ip, address_expr, reloc_type) { /* The previous instruction reads the LO register; if the current instruction writes to the LO register, we must - insert two NOPS. The R4650 has interlocks. */ + insert two NOPS. The R4650 and VR4100 have interlocks. */ if (! interlocks && (mips_optimize == 0 || (pinfo & INSN_WRITE_LO))) @@ -968,7 +982,7 @@ append_insn (place, ip, address_expr, reloc_type) { /* The previous instruction reads the HI register; if the current instruction writes to the HI register, we must - insert a NOP. The R4650 has interlocks. */ + insert a NOP. The R4650 and VR4100 have interlocks. */ if (! interlocks && (mips_optimize == 0 || (pinfo & INSN_WRITE_HI))) @@ -980,9 +994,10 @@ append_insn (place, ip, address_expr, reloc_type) coprocessor instruction which requires a general coprocessor delay and then reading the condition codes 2) reading the HI or LO register and then writing to it (except on the R4650, - which has interlocks). If we are not already emitting a NOP - instruction, we must check for these cases compared to the - instruction previous to the previous instruction. */ + and VR4100 which have interlocks). If we are not already + emitting a NOP instruction, we must check for these cases + compared to the instruction previous to the previous + instruction. */ if (nops == 0 && ((mips_isa < 4 && (prev_prev_insn.insn_mo->pinfo & INSN_COPROC_MOVE_DELAY) @@ -1445,7 +1460,19 @@ macro_build (place, counter, ep, name, fmt, va_alist) assert (strcmp (name, insn.insn_mo->name) == 0); while (strcmp (fmt, insn.insn_mo->args) != 0 - || insn.insn_mo->pinfo == INSN_MACRO) + || insn.insn_mo->pinfo == INSN_MACRO + || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA2 + && mips_isa < 2) + || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA3 + && mips_isa < 3) + || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_ISA4 + && mips_isa < 4) + || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_4650 + && ! mips_4650) + || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_4010 + && ! mips_4010) + || ((insn.insn_mo->pinfo & INSN_ISA) == INSN_4100 + && ! mips_4100)) { ++insn.insn_mo; assert (insn.insn_mo->name); @@ -4186,6 +4213,10 @@ macro2 (ip) off = 3; ulwa: load_address (&icnt, AT, &offset_expr); + if (breg != 0) + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, + mips_isa < 3 ? "addu" : "daddu", + "d,v,t", AT, AT, breg); if (byte_order == LITTLE_ENDIAN) expr1.X_add_number = off; else @@ -4203,6 +4234,10 @@ macro2 (ip) case M_ULH_A: case M_ULHU_A: load_address (&icnt, AT, &offset_expr); + if (breg != 0) + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, + mips_isa < 3 ? "addu" : "daddu", + "d,v,t", AT, AT, breg); if (byte_order == BIG_ENDIAN) expr1.X_add_number = 0; macro_build ((char *) NULL, &icnt, &expr1, @@ -4271,6 +4306,10 @@ macro2 (ip) off = 3; uswa: load_address (&icnt, AT, &offset_expr); + if (breg != 0) + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, + mips_isa < 3 ? "addu" : "daddu", + "d,v,t", AT, AT, breg); if (byte_order == LITTLE_ENDIAN) expr1.X_add_number = off; else @@ -4287,6 +4326,10 @@ macro2 (ip) case M_USH_A: load_address (&icnt, AT, &offset_expr); + if (breg != 0) + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, + mips_isa < 3 ? "addu" : "daddu", + "d,v,t", AT, AT, breg); if (byte_order == LITTLE_ENDIAN) expr1.X_add_number = 0; macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg, @@ -4341,7 +4384,7 @@ mips_ip (str, ip) insn_error = NULL; - for (s = str; islower (*s) || (*s >= '0' && *s <= '3') || *s == '.'; ++s) + for (s = str; islower (*s) || (*s >= '0' && *s <= '3') || *s == '6' || *s == '.'; ++s) continue; switch (*s) { @@ -4383,7 +4426,9 @@ mips_ip (str, ip) || ((insn->pinfo & INSN_ISA) == INSN_4650 && ! mips_4650) || ((insn->pinfo & INSN_ISA) == INSN_4010 - && ! mips_4010)) + && ! mips_4010) + || ((insn->pinfo & INSN_ISA) == INSN_4100 + && ! mips_4100)) { if (insn + 1 < &mips_opcodes[NUMOPCODES] && strcmp (insn->name, insn[1].name) == 0) @@ -5270,6 +5315,10 @@ struct option md_longopts[] = { {"m4010", no_argument, NULL, OPTION_M4010}, #define OPTION_NO_M4010 (OPTION_MD_BASE + 16) {"no-m4010", no_argument, NULL, OPTION_NO_M4010}, +#define OPTION_M4100 (OPTION_MD_BASE + 17) + {"m4100", no_argument, NULL, OPTION_M4100}, +#define OPTION_NO_M4100 (OPTION_MD_BASE + 18) + {"no-m4100", no_argument, NULL, OPTION_NO_M4100}, #define OPTION_CALL_SHARED (OPTION_MD_BASE + 7) #define OPTION_NON_SHARED (OPTION_MD_BASE + 8) @@ -5360,6 +5409,16 @@ md_parse_option (c, arg) mips_cpu = -1; else { + int sv = 0; + + /* We need to cope with the various "vr" prefixes for the 4300 + processor. */ + if (*p == 'v' || *p == 'V') + { + sv = 1; + p++; + } + if (*p == 'r' || *p == 'R') p++; @@ -5392,6 +5451,14 @@ md_parse_option (c, arg) || strcmp (p, "4k") == 0 || strcmp (p, "4K") == 0) mips_cpu = 4000; + else if (strcmp (p, "4100") == 0) + { + mips_cpu = 4100; + if (mips_4100 < 0) + mips_4100 = 1; + } + else if (strcmp (p, "4300") == 0) + mips_cpu = 4300; else if (strcmp (p, "4400") == 0) mips_cpu = 4400; else if (strcmp (p, "4600") == 0) @@ -5430,6 +5497,12 @@ md_parse_option (c, arg) break; } + if (sv && mips_cpu != 4300 && mips_cpu != 4100) + { + as_bad ("ignoring invalid leading 'v' in -mcpu=%s switch", arg); + return 0; + } + if (mips_cpu == -1) { as_bad ("invalid architecture -mcpu=%s", arg); @@ -5455,6 +5528,14 @@ md_parse_option (c, arg) mips_4010 = 0; break; + case OPTION_M4100: + mips_4100 = 1; + break; + + case OPTION_NO_M4100: + mips_4100 = 0; + break; + case OPTION_MEMBEDDED_PIC: mips_pic = EMBEDDED_PIC; if (USE_GLOBAL_POINTER_OPT && g_switch_seen) @@ -5532,10 +5613,14 @@ MIPS options:\n\ -mips2, -mcpu=r6000 generate code for r6000\n\ -mips3, -mcpu=r4000 generate code for r4000\n\ -mips4, -mcpu=r8000 generate code for r8000\n\ +-mcpu=vr4300 generate code for vr4300\n\ -m4650 permit R4650 instructions\n\ -no-m4650 do not permit R4650 instructions\n\ -m4010 permit R4010 instructions\n\ -no-m4010 do not permit R4010 instructions\n\ +-m4100 permit VR4100 instructions\n\ +-no-m4100 do not permit VR4100 instructions\n"); + fprintf(stream, "\ -O0 remove unneeded NOPs, do not swap branches\n\ -O remove unneeded NOPs and swap branches\n\ --trap, --no-break trap exception on div by 0 and mult overflow\n\ @@ -6105,8 +6190,10 @@ s_extern (x) size = get_absolute_expression (); S_SET_EXTERNAL (symbolP); +#ifndef NO_ECOFF_DEBUGGING if (ECOFF_DEBUGGING) symbolP->ecoff_extern_size = size; +#endif } static void @@ -6543,8 +6630,11 @@ nopic_need_relax (sym) || strcmp (symname, "_gp_disp") == 0)) change = 1; else if (! S_IS_DEFINED (sym) - && ((sym->ecoff_extern_size != 0 - && sym->ecoff_extern_size <= g_switch_value) + && (0 +#ifndef NO_ECOFF_DEBUGGING + || (sym->ecoff_extern_size != 0 + && sym->ecoff_extern_size <= g_switch_value) +#endif || (S_GET_VALUE (sym) != 0 && S_GET_VALUE (sym) <= g_switch_value))) change = 0; @@ -6801,6 +6891,7 @@ int mips_local_label (name) const char *name; { +#ifndef NO_ECOFF_DEBUGGING if (ECOFF_DEBUGGING && mips_debug != 0 && ! ecoff_debugging_seen) @@ -6811,6 +6902,7 @@ mips_local_label (name) generate all local labels. */ return 0; } +#endif /* Here it's OK to discard local labels. */ -- 2.7.4