diff options
Diffstat (limited to 'binutils-2.25/gas/config')
24 files changed, 557 insertions, 749 deletions
diff --git a/binutils-2.25/gas/config/bfin-aux.h b/binutils-2.25/gas/config/bfin-aux.h index 44665b95..44665b95 100644..100755 --- a/binutils-2.25/gas/config/bfin-aux.h +++ b/binutils-2.25/gas/config/bfin-aux.h diff --git a/binutils-2.25/gas/config/m68k-parse.y b/binutils-2.25/gas/config/m68k-parse.y index d5c59a18..3c7051cb 100644 --- a/binutils-2.25/gas/config/m68k-parse.y +++ b/binutils-2.25/gas/config/m68k-parse.y @@ -685,8 +685,7 @@ static char *strorig; *CCP. Otherwise don't change *CCP, and return 0. */ static enum m68k_register -m68k_reg_parse (ccp) - register char **ccp; +m68k_reg_parse (char **ccp) { char *start = *ccp; char c; @@ -748,7 +747,7 @@ m68k_reg_parse (ccp) /* The lexer. */ static int -yylex () +yylex (void) { enum m68k_register reg; char *s; @@ -1091,9 +1090,7 @@ yylex () from outside this file. */ int -m68k_ip_op (s, oparg) - char *s; - struct m68k_op *oparg; +m68k_ip_op (char *s, struct m68k_op *oparg) { memset (oparg, 0, sizeof *oparg); oparg->error = NULL; @@ -1111,8 +1108,7 @@ m68k_ip_op (s, oparg) /* The error handler. */ static void -yyerror (s) - const char *s; +yyerror (const char *s) { op->error = s; } diff --git a/binutils-2.25/gas/config/obj-elf.c b/binutils-2.25/gas/config/obj-elf.c index e2ef99e2..50a5d1c5 100644 --- a/binutils-2.25/gas/config/obj-elf.c +++ b/binutils-2.25/gas/config/obj-elf.c @@ -125,8 +125,10 @@ static const pseudo_typeS elf_pseudo_table[] = {"8byte", cons, 8}, /* These are used for dwarf2. */ { "file", (void (*) (int)) dwarf2_directive_file, 0 }, - { "loc", dwarf2_directive_loc, 0 }, + { "loc", dwarf2_directive_loc, 0 }, { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 }, + { "lloc", dwarf2_directive_loc, 1 }, + { "subprog", dwarf2_directive_subprog, 0 }, /* We need to trap the section changing calls to handle .previous. */ {"data", obj_elf_data, 0}, diff --git a/binutils-2.25/gas/config/tc-aarch64.c b/binutils-2.25/gas/config/tc-aarch64.c index 0e587646..4f3fe474 100644 --- a/binutils-2.25/gas/config/tc-aarch64.c +++ b/binutils-2.25/gas/config/tc-aarch64.c @@ -3939,11 +3939,11 @@ output_info (const char *format, ...) static void output_operand_error_record (const operand_error_record *record, char *str) { - int idx = record->detail.index; + const aarch64_operand_error *detail = &record->detail; + int idx = detail->index; const aarch64_opcode *opcode = record->opcode; - enum aarch64_opnd opd_code = (idx != -1 ? opcode->operands[idx] + enum aarch64_opnd opd_code = (idx >= 0 ? opcode->operands[idx] : AARCH64_OPND_NIL); - const aarch64_operand_error *detail = &record->detail; switch (detail->kind) { @@ -3955,20 +3955,22 @@ output_operand_error_record (const operand_error_record *record, char *str) case AARCH64_OPDE_RECOVERABLE: case AARCH64_OPDE_FATAL_SYNTAX_ERROR: case AARCH64_OPDE_OTHER_ERROR: - gas_assert (idx >= 0); /* Use the prepared error message if there is, otherwise use the operand description string to describe the error. */ if (detail->error != NULL) { - if (detail->index == -1) + if (idx < 0) as_bad (_("%s -- `%s'"), detail->error, str); else as_bad (_("%s at operand %d -- `%s'"), - detail->error, detail->index + 1, str); + detail->error, idx + 1, str); } else - as_bad (_("operand %d should be %s -- `%s'"), idx + 1, + { + gas_assert (idx >= 0); + as_bad (_("operand %d should be %s -- `%s'"), idx + 1, aarch64_get_operand_desc (opd_code), str); + } break; case AARCH64_OPDE_INVALID_VARIANT: @@ -4073,28 +4075,28 @@ output_operand_error_record (const operand_error_record *record, char *str) if (detail->data[0] != detail->data[1]) as_bad (_("%s out of range %d to %d at operand %d -- `%s'"), detail->error ? detail->error : _("immediate value"), - detail->data[0], detail->data[1], detail->index + 1, str); + detail->data[0], detail->data[1], idx + 1, str); else as_bad (_("%s expected to be %d at operand %d -- `%s'"), detail->error ? detail->error : _("immediate value"), - detail->data[0], detail->index + 1, str); + detail->data[0], idx + 1, str); break; case AARCH64_OPDE_REG_LIST: if (detail->data[0] == 1) as_bad (_("invalid number of registers in the list; " "only 1 register is expected at operand %d -- `%s'"), - detail->index + 1, str); + idx + 1, str); else as_bad (_("invalid number of registers in the list; " "%d registers are expected at operand %d -- `%s'"), - detail->data[0], detail->index + 1, str); + detail->data[0], idx + 1, str); break; case AARCH64_OPDE_UNALIGNED: as_bad (_("immediate value should be a multiple of " "%d at operand %d -- `%s'"), - detail->data[0], detail->index + 1, str); + detail->data[0], idx + 1, str); break; default: @@ -7184,20 +7186,10 @@ static const struct aarch64_cpu_option_table aarch64_cpus[] = { AARCH64_FEATURE_CRC), "Cortex-A53"}, {"cortex-a57", AARCH64_FEATURE(AARCH64_ARCH_V8, AARCH64_FEATURE_CRC), "Cortex-A57"}, - /* The 'xgene-1' name is an older name for 'xgene1', which was used - in earlier releases and is superseded by 'xgene1' in all - tools. */ + {"thunderx", AARCH64_ARCH_V8, "Cavium ThunderX"}, {"xgene-1", AARCH64_ARCH_V8, "APM X-Gene 1"}, - {"xgene1", AARCH64_ARCH_V8, "APM X-Gene 1"}, - {"xgene2", AARCH64_FEATURE(AARCH64_ARCH_V8, - AARCH64_FEATURE_CRC), "APM X-Gene 2"}, {"generic", AARCH64_ARCH_V8, NULL}, - /* These two are example CPUs supported in GCC, once we have real - CPUs they will be removed. */ - {"example-1", AARCH64_ARCH_V8, NULL}, - {"example-2", AARCH64_ARCH_V8, NULL}, - {NULL, AARCH64_ARCH_NONE, NULL} }; diff --git a/binutils-2.25/gas/config/tc-alpha.c b/binutils-2.25/gas/config/tc-alpha.c index ea6aa190..f91c4ca9 100644 --- a/binutils-2.25/gas/config/tc-alpha.c +++ b/binutils-2.25/gas/config/tc-alpha.c @@ -4482,7 +4482,7 @@ s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED) { char *name; char name_end; - register char *p; + char *p; expressionS exp; symbolS *entry_sym; const char *entry_sym_name; diff --git a/binutils-2.25/gas/config/tc-bfin.c b/binutils-2.25/gas/config/tc-bfin.c index 447a477d..66464826 100644 --- a/binutils-2.25/gas/config/tc-bfin.c +++ b/binutils-2.25/gas/config/tc-bfin.c @@ -111,7 +111,7 @@ bfin_pic_ptr (int nbytes) static void bfin_s_bss (int ignore ATTRIBUTE_UNUSED) { - register int temp; + int temp; temp = get_absolute_expression (); subseg_set (bss_section, (subsegT) temp); diff --git a/binutils-2.25/gas/config/tc-d10v.c b/binutils-2.25/gas/config/tc-d10v.c index 8e3d171c..dacfeb74 100644 --- a/binutils-2.25/gas/config/tc-d10v.c +++ b/binutils-2.25/gas/config/tc-d10v.c @@ -1226,9 +1226,7 @@ find_opcode (struct d10v_opcode *opcode, expressionS myops[]) sym_frag = symbol_get_frag (myops[opnum].X_add_symbol); found_symbol = FALSE; - current_position = - obstack_next_free (&frchain_now->frch_obstack) - - frag_now->fr_literal; + current_position = frag_now_fix_octets (); symbol_position = S_GET_VALUE (myops[opnum].X_add_symbol); for (f = frchain_now->frch_root; f; f = f->fr_next) diff --git a/binutils-2.25/gas/config/tc-d30v.c b/binutils-2.25/gas/config/tc-d30v.c index 9076e412..a73f9b1f 100644 --- a/binutils-2.25/gas/config/tc-d30v.c +++ b/binutils-2.25/gas/config/tc-d30v.c @@ -1242,12 +1242,10 @@ find_format (struct d30v_opcode *opcode, /* Calculate the current address by running through the previous frags and adding our current offset. */ - value = 0; + value = frag_now_fix_octets (); for (f = frchain_now->frch_root; f; f = f->fr_next) value += f->fr_fix + f->fr_offset; - value = (S_GET_VALUE (myops[j].X_add_symbol) - value - - (obstack_next_free (&frchain_now->frch_obstack) - - frag_now->fr_literal)); + value = S_GET_VALUE (myops[j].X_add_symbol) - value; if (check_range (value, bits, flags)) match = 0; } diff --git a/binutils-2.25/gas/config/tc-epiphany.c b/binutils-2.25/gas/config/tc-epiphany.c index ebaedc41..ebaedc41 100644..100755 --- a/binutils-2.25/gas/config/tc-epiphany.c +++ b/binutils-2.25/gas/config/tc-epiphany.c diff --git a/binutils-2.25/gas/config/tc-epiphany.h b/binutils-2.25/gas/config/tc-epiphany.h index ddfb4756..ddfb4756 100644..100755 --- a/binutils-2.25/gas/config/tc-epiphany.h +++ b/binutils-2.25/gas/config/tc-epiphany.h diff --git a/binutils-2.25/gas/config/tc-i386-intel.c b/binutils-2.25/gas/config/tc-i386-intel.c index 86b96ebe..b55d985f 100644 --- a/binutils-2.25/gas/config/tc-i386-intel.c +++ b/binutils-2.25/gas/config/tc-i386-intel.c @@ -141,7 +141,9 @@ operatorT i386_operator (const char *name, unsigned int operands, char *pc) int adjust = 0; char *gotfree_input_line = lex_got (&i.reloc[this_operand], &adjust, - &intel_state.reloc_types); + &intel_state.reloc_types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); if (!gotfree_input_line) break; diff --git a/binutils-2.25/gas/config/tc-i386.c b/binutils-2.25/gas/config/tc-i386.c index 6f7a1ae7..97e326c2 100644 --- a/binutils-2.25/gas/config/tc-i386.c +++ b/binutils-2.25/gas/config/tc-i386.c @@ -2830,6 +2830,7 @@ static bfd_reloc_code_real_type reloc (unsigned int size, int pcrel, int sign, + int bnd_prefix, bfd_reloc_code_real_type other) { if (other != NO_RELOC) @@ -2842,6 +2843,9 @@ reloc (unsigned int size, case BFD_RELOC_X86_64_GOT32: return BFD_RELOC_X86_64_GOT64; break; + case BFD_RELOC_X86_64_GOTPLT64: + return BFD_RELOC_X86_64_GOTPLT64; + break; case BFD_RELOC_X86_64_PLTOFF64: return BFD_RELOC_X86_64_PLTOFF64; break; @@ -2905,7 +2909,9 @@ reloc (unsigned int size, { case 1: return BFD_RELOC_8_PCREL; case 2: return BFD_RELOC_16_PCREL; - case 4: return BFD_RELOC_32_PCREL; + case 4: return (bnd_prefix && object_64bit + ? BFD_RELOC_X86_64_PC32_BND + : BFD_RELOC_32_PCREL); case 8: return BFD_RELOC_64_PCREL; } as_bad (_("cannot do %u byte pc-relative relocation"), size); @@ -6770,7 +6776,13 @@ output_branch (void) /* 1 possible extra opcode + 4 byte displacement go in var part. Pass reloc in fr_var. */ - frag_var (rs_machine_dependent, 5, i.reloc[0], subtype, sym, off, p); + frag_var (rs_machine_dependent, 5, + ((!object_64bit + || i.reloc[0] != NO_RELOC + || (i.bnd_prefix == NULL && !add_bnd_prefix)) + ? i.reloc[0] + : BFD_RELOC_X86_64_PC32_BND), + subtype, sym, off, p); } static void @@ -6846,7 +6858,10 @@ output_jump (void) } fixP = fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[0].disps, 1, reloc (size, 1, 1, i.reloc[0])); + i.op[0].disps, 1, reloc (size, 1, 1, + (i.bnd_prefix != NULL + || add_bnd_prefix), + i.reloc[0])); /* All jumps handled here are signed, but don't use a signed limit check for 32 and 16 bit jumps as we want to allow wrap around at @@ -6912,7 +6927,7 @@ output_interseg_jump (void) } else fix_new_exp (frag_now, p - frag_now->fr_literal, size, - i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1])); + i.op[1].imms, 0, reloc (size, 0, 0, 0, i.reloc[1])); if (i.op[0].imms->X_op != O_constant) as_bad (_("can't handle non absolute segment in `%s'"), i.tm.name); @@ -7191,7 +7206,10 @@ output_disp (fragS *insn_start_frag, offsetT insn_start_off) } p = frag_more (size); - reloc_type = reloc (size, pcrel, sign, i.reloc[n]); + reloc_type = reloc (size, pcrel, sign, + (i.bnd_prefix != NULL + || add_bnd_prefix), + i.reloc[n]); if (GOT_symbol && GOT_symbol == i.op[n].disps->X_add_symbol && (((reloc_type == BFD_RELOC_32 @@ -7282,7 +7300,7 @@ output_imm (fragS *insn_start_frag, offsetT insn_start_off) sign = 0; p = frag_more (size); - reloc_type = reloc (size, 0, sign, i.reloc[n]); + reloc_type = reloc (size, 0, sign, 0, i.reloc[n]); /* This is tough to explain. We end up with this one if we * have operands that look like @@ -7375,7 +7393,7 @@ void x86_cons_fix_new (fragS *frag, unsigned int off, unsigned int len, expressionS *exp, bfd_reloc_code_real_type r) { - r = reloc (len, 0, cons_sign, r); + r = reloc (len, 0, cons_sign, 0, r); #ifdef TE_PE if (exp->X_op == O_secrel) @@ -7401,7 +7419,7 @@ x86_address_bytes (void) #if !(defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) || defined (OBJ_MACH_O)) \ || defined (LEX_AT) -# define lex_got(reloc, adjust, types) NULL +# define lex_got(reloc, adjust, types, bnd_prefix) NULL #else /* Parse operands of the form <symbol>@GOTOFF+<nnn> @@ -7415,7 +7433,8 @@ x86_address_bytes (void) static char * lex_got (enum bfd_reloc_code_real *rel, int *adjust, - i386_operand_type *types) + i386_operand_type *types, + int bnd_prefix) { /* Some of the relocations depend on the size of what field is to be relocated. But in our callers i386_immediate and i386_displacement @@ -7550,6 +7569,8 @@ lex_got (enum bfd_reloc_code_real *rel, *adjust = len; memcpy (tmpbuf + first, past_reloc, second); tmpbuf[first + second] = '\0'; + if (bnd_prefix && *rel == BFD_RELOC_X86_64_PLT32) + *rel = BFD_RELOC_X86_64_PLT32_BND; return tmpbuf; } @@ -7582,7 +7603,8 @@ lex_got (enum bfd_reloc_code_real *rel, static char * lex_got (enum bfd_reloc_code_real *rel ATTRIBUTE_UNUSED, int *adjust ATTRIBUTE_UNUSED, - i386_operand_type *types) + i386_operand_type *types, + int bnd_prefix ATTRIBUTE_UNUSED) { static const struct { @@ -7683,7 +7705,7 @@ x86_cons (expressionS *exp, int size) int adjust = 0; save = input_line_pointer; - gotfree_input_line = lex_got (&got_reloc, &adjust, NULL); + gotfree_input_line = lex_got (&got_reloc, &adjust, NULL, 0); if (gotfree_input_line) input_line_pointer = gotfree_input_line; @@ -7917,7 +7939,9 @@ i386_immediate (char *imm_start) save_input_line_pointer = input_line_pointer; input_line_pointer = imm_start; - gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types); + gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); if (gotfree_input_line) input_line_pointer = gotfree_input_line; @@ -8174,7 +8198,9 @@ i386_displacement (char *disp_start, char *disp_end) *displacement_string_end = '0'; } #endif - gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types); + gotfree_input_line = lex_got (&i.reloc[this_operand], NULL, &types, + (i.bnd_prefix != NULL + || add_bnd_prefix)); if (gotfree_input_line) input_line_pointer = gotfree_input_line; @@ -9134,7 +9160,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) && (fixP->fx_r_type == BFD_RELOC_32_PCREL || fixP->fx_r_type == BFD_RELOC_64_PCREL || fixP->fx_r_type == BFD_RELOC_16_PCREL - || fixP->fx_r_type == BFD_RELOC_8_PCREL) + || fixP->fx_r_type == BFD_RELOC_8_PCREL + || fixP->fx_r_type == BFD_RELOC_X86_64_PC32_BND) && !use_rela_relocations) { /* This is a hack. There should be a better way to handle this. @@ -9203,6 +9230,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) { case BFD_RELOC_386_PLT32: case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: /* Make the jump instruction point to the address of the operand. At runtime we merely add the offset to the actual PLT entry. */ value = -4; @@ -10326,6 +10354,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) #endif case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: case BFD_RELOC_X86_64_GOT32: case BFD_RELOC_X86_64_GOTPCREL: case BFD_RELOC_386_PLT32: @@ -10386,7 +10415,10 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) break; case 1: code = BFD_RELOC_8_PCREL; break; case 2: code = BFD_RELOC_16_PCREL; break; - case 4: code = BFD_RELOC_32_PCREL; break; + case 4: + code = (fixp->fx_r_type == BFD_RELOC_X86_64_PC32_BND + ? fixp-> fx_r_type : BFD_RELOC_32_PCREL); + break; #ifdef BFD64 case 8: code = BFD_RELOC_64_PCREL; break; #endif @@ -10479,6 +10511,7 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) switch (code) { case BFD_RELOC_X86_64_PLT32: + case BFD_RELOC_X86_64_PLT32_BND: case BFD_RELOC_X86_64_GOT32: case BFD_RELOC_X86_64_GOTPCREL: case BFD_RELOC_X86_64_TLSGD: diff --git a/binutils-2.25/gas/config/tc-i860.c b/binutils-2.25/gas/config/tc-i860.c index 1b55b807..dd51c26d 100644 --- a/binutils-2.25/gas/config/tc-i860.c +++ b/binutils-2.25/gas/config/tc-i860.c @@ -1028,7 +1028,7 @@ md_number_to_chars (char *buf, valueT val, int n) /* This should never be called for i860. */ int -md_estimate_size_before_relax (register fragS *fragP ATTRIBUTE_UNUSED, +md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, segT segtype ATTRIBUTE_UNUSED) { as_fatal (_("relaxation not supported\n")); diff --git a/binutils-2.25/gas/config/tc-m68hc11.c b/binutils-2.25/gas/config/tc-m68hc11.c index 36419123..9026ff40 100644 --- a/binutils-2.25/gas/config/tc-m68hc11.c +++ b/binutils-2.25/gas/config/tc-m68hc11.c @@ -3958,7 +3958,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, asection *sec ATTRIBUTE_UNUSED, char *buffer_address = fragP->fr_literal; /* Address in object code of the displacement. */ - register int object_address = fragP->fr_fix + fragP->fr_address; + int object_address = fragP->fr_fix + fragP->fr_address; buffer_address += fragP->fr_fix; diff --git a/binutils-2.25/gas/config/tc-m68k.c b/binutils-2.25/gas/config/tc-m68k.c index 7fc4efeb..dbcd87b2 100644 --- a/binutils-2.25/gas/config/tc-m68k.c +++ b/binutils-2.25/gas/config/tc-m68k.c @@ -1395,11 +1395,11 @@ static struct hash_control *op_hash; static void m68k_ip (char *instring) { - register char *p; - register struct m68k_op *opP; - register const struct m68k_incant *opcode; - register const char *s; - register int tmpreg = 0, baseo = 0, outro = 0, nextword; + char *p; + struct m68k_op *opP; + const struct m68k_incant *opcode; + const char *s; + int tmpreg = 0, baseo = 0, outro = 0, nextword; char *pdot, *pdotmove; enum m68k_size siz1, siz2; char c; @@ -3955,9 +3955,9 @@ install_gen_operand (int mode, int val) static char * crack_operand (char *str, struct m68k_op *opP) { - register int parens; - register int c; - register char *beg_str; + int parens; + int c; + char *beg_str; int inquote = 0; if (!str) @@ -5033,12 +5033,12 @@ md_convert_frag_1 (fragS *fragP) fixS *fixP = NULL; /* Address in object code of the displacement. */ - register int object_address = fragP->fr_fix + fragP->fr_address; + int object_address = fragP->fr_fix + fragP->fr_address; /* Address in gas core of the place to store the displacement. */ /* This convinces the native rs6000 compiler to generate the code we want. */ - register char *buffer_address = fragP->fr_literal; + char *buffer_address = fragP->fr_literal; buffer_address += fragP->fr_fix; /* End ibm compiler workaround. */ @@ -5663,8 +5663,8 @@ s_bss (int ignore ATTRIBUTE_UNUSED) static void s_even (int ignore ATTRIBUTE_UNUSED) { - register int temp; - register long temp_fill; + int temp; + long temp_fill; temp = 1; /* JF should be 2? */ temp_fill = get_absolute_expression (); diff --git a/binutils-2.25/gas/config/tc-mips.c b/binutils-2.25/gas/config/tc-mips.c index 0f7e0c58..59f7a733 100644 --- a/binutils-2.25/gas/config/tc-mips.c +++ b/binutils-2.25/gas/config/tc-mips.c @@ -510,7 +510,8 @@ static int mips_32bitmode = 0; #define CPU_HAS_ROR(CPU) CPU_HAS_DROR (CPU) /* True if CPU is in the Octeon family */ -#define CPU_IS_OCTEON(CPU) ((CPU) == CPU_OCTEON || (CPU) == CPU_OCTEONP || (CPU) == CPU_OCTEON2) +#define CPU_IS_OCTEON(CPU) ((CPU) == CPU_OCTEON || (CPU) == CPU_OCTEONP \ + || (CPU) == CPU_OCTEON2 || (CPU) == CPU_OCTEON3) /* True if CPU has seq/sne and seqi/snei instructions. */ #define CPU_HAS_SEQ(CPU) (CPU_IS_OCTEON (CPU)) @@ -1878,7 +1879,7 @@ static void mips_compressed_mark_labels (void); static inline void mips_clear_insn_labels (void) { - register struct insn_label_list **pl; + struct insn_label_list **pl; segment_info_type *si; if (now_seg) @@ -18825,6 +18826,7 @@ static const struct mips_cpu_info mips_cpu_info_table[] = { "octeon", 0, 0, ISA_MIPS64R2, CPU_OCTEON }, { "octeon+", 0, 0, ISA_MIPS64R2, CPU_OCTEONP }, { "octeon2", 0, 0, ISA_MIPS64R2, CPU_OCTEON2 }, + { "octeon3", 0, ASE_VIRT | ASE_VIRT64, ISA_MIPS64R5, CPU_OCTEON3 }, /* RMI Xlr */ { "xlr", 0, 0, ISA_MIPS64, CPU_XLR }, diff --git a/binutils-2.25/gas/config/tc-mn10200.c b/binutils-2.25/gas/config/tc-mn10200.c index f76fb083..7462d932 100644 --- a/binutils-2.25/gas/config/tc-mn10200.c +++ b/binutils-2.25/gas/config/tc-mn10200.c @@ -686,7 +686,7 @@ void md_begin (void) { char *prev_name = ""; - register const struct mn10200_opcode *op; + const struct mn10200_opcode *op; mn10200_hash = hash_new (); diff --git a/binutils-2.25/gas/config/tc-nios2.c b/binutils-2.25/gas/config/tc-nios2.c index 21f42886..7691fd1e 100644 --- a/binutils-2.25/gas/config/tc-nios2.c +++ b/binutils-2.25/gas/config/tc-nios2.c @@ -139,6 +139,10 @@ typedef struct nios2_insn_info { /* Assembled instruction. */ unsigned long insn_code; + + /* Constant bits masked into insn_code for self-check mode. */ + unsigned long constant_bits; + /* Pointer to the relevant bit of the opcode table. */ const struct nios2_opcode *insn_nios2_opcode; /* After parsing ptrs to the tokens in the instruction fill this array @@ -152,15 +156,6 @@ typedef struct nios2_insn_info nios2_insn_relocS *insn_reloc; } nios2_insn_infoS; -/* This struct associates an argument assemble function with - an argument syntax string. Used by the assembler to find out - how to parse and assemble a set of instruction operands and - return the instruction field values. */ -typedef struct nios2_arg_info -{ - const char *args; - void (*assemble_args_func) (nios2_insn_infoS *insn_info); -} nios2_arg_infoS; /* This struct is used to convert Nios II pseudo-ops into the corresponding real op. */ @@ -196,10 +191,6 @@ static struct hash_control *nios2_reg_hash = NULL; #define nios2_reg_lookup(NAME) \ ((struct nios2_reg *) hash_find (nios2_reg_hash, (NAME))) -/* Parse args hash table. */ -static struct hash_control *nios2_arg_hash = NULL; -#define nios2_arg_lookup(NAME) \ - ((nios2_arg_infoS *) hash_find (nios2_arg_hash, (NAME))) /* Pseudo-op hash table. */ static struct hash_control *nios2_ps_hash = NULL; @@ -303,27 +294,6 @@ md_atof (int type, char *litP, int *sizeP) #define strprefix(STR, PREFIX) \ (strncmp ((STR), PREFIX, strlen (PREFIX)) == 0) -/* Return true if STR is prefixed with a control register name. */ -static int -nios2_control_register_arg_p (const char *str) -{ - return (strprefix (str, "ctl") - || strprefix (str, "cpuid") - || strprefix (str, "status") - || strprefix (str, "estatus") - || strprefix (str, "bstatus") - || strprefix (str, "ienable") - || strprefix (str, "ipending") - || strprefix (str, "exception") - || strprefix (str, "pteaddr") - || strprefix (str, "tlbacc") - || strprefix (str, "tlbmisc") - || strprefix (str, "eccinj") - || strprefix (str, "config") - || strprefix (str, "mpubase") - || strprefix (str, "mpuacc") - || strprefix (str, "badaddr")); -} /* Return true if STR is prefixed with a special relocation operator. */ static int @@ -345,24 +315,6 @@ nios2_special_relocation_p (const char *str) || strprefix (str, "%gotoff")); } -/* Checks whether the register name is a coprocessor - register - returns TRUE if it is, FALSE otherwise. */ -static bfd_boolean -nios2_coproc_reg (const char *reg_name) -{ - gas_assert (reg_name != NULL); - - /* Check that we do have a valid register name and that it is a - coprocessor register. - It must begin with c, not be a control register, and be a valid - register name. */ - if (strprefix (reg_name, "c") - && !strprefix (reg_name, "ctl") - && hash_find (nios2_reg_hash, reg_name) != NULL) - return TRUE; - else - return FALSE; -} /* nop fill pattern for text section. */ static char const nop[4] = { 0x3a, 0x88, 0x01, 0x00 }; @@ -816,9 +768,9 @@ nios2_relax_frag (segT segment, fragS *fragp, long stretch) target = fragp->fr_next->fr_address + stretch; } - /* We subtract 4 because all pc relative branches are - from the next instruction. */ - offset = target - fragp->fr_address - fragp->fr_fix - 4; + /* We subtract fr_var (4 for 32-bit insns) because all pc relative + branches are from the next instruction. */ + offset = target - fragp->fr_address - fragp->fr_fix - fragp->fr_var; if (offset >= -32768 && offset <= 32764) /* Fits in PC-relative branch. */ n = 0; @@ -902,6 +854,7 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED, if (IS_CBRANCH (subtype)) { unsigned int br_opcode; + unsigned int old_op, new_op; int nbytes; /* Account for the nextpc and jmp in the pc-relative case, or the two @@ -912,25 +865,26 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED, nbytes = 12; br_opcode = md_chars_to_number (buffer, 4); - switch (br_opcode & OP_MASK_OP) + old_op = GET_IW_R1_OP (br_opcode); + switch (old_op) { - case OP_MATCH_BEQ: - br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BNE; + case R1_OP_BEQ: + new_op = R1_OP_BNE; break; - case OP_MATCH_BNE: - br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BEQ ; + case R1_OP_BNE: + new_op = R1_OP_BEQ; break; - case OP_MATCH_BGE: - br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BLT ; + case R1_OP_BGE: + new_op = R1_OP_BLT; break; - case OP_MATCH_BGEU: - br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BLTU ; + case R1_OP_BGEU: + new_op = R1_OP_BLTU; break; - case OP_MATCH_BLT: - br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BGE ; + case R1_OP_BLT: + new_op = R1_OP_BGE; break; - case OP_MATCH_BLTU: - br_opcode = (br_opcode & ~OP_MASK_OP) | OP_MATCH_BGEU ; + case R1_OP_BLTU: + new_op = R1_OP_BGEU; break; default: as_bad_where (fragp->fr_file, fragp->fr_line, @@ -938,7 +892,8 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED, abort (); } - br_opcode = br_opcode | (nbytes << OP_SH_IMM16); + br_opcode = (br_opcode & ~IW_R1_OP_SHIFTED_MASK) | SET_IW_R1_OP (new_op); + br_opcode = br_opcode | SET_IW_I_IMM16 (nbytes); md_number_to_chars (buffer, br_opcode, 4); fragp->fr_fix += 4; buffer += 4; @@ -949,7 +904,7 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED, { /* Insert the nextpc instruction. */ md_number_to_chars (buffer, - OP_MATCH_NEXTPC | (AT_REGNUM << OP_SH_RRD), 4); + MATCH_R1_NEXTPC | SET_IW_R_C (AT_REGNUM), 4); fragp->fr_fix += 4; buffer += 4; @@ -960,12 +915,12 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED, addend = 32767; else addend = -32768; - addend_mask = (((unsigned int)addend) & 0xffff) << OP_SH_IMM16; + addend_mask = SET_IW_I_IMM16 ((unsigned int)addend); /* Insert n-1 addi instructions. */ - addi_mask = (OP_MATCH_ADDI - | (AT_REGNUM << OP_SH_IRD) - | (AT_REGNUM << OP_SH_IRS)); + addi_mask = (MATCH_R1_ADDI + | SET_IW_I_B (AT_REGNUM) + | SET_IW_I_A (AT_REGNUM)); for (i = 0; i < n - 1; i ++) { md_number_to_chars (buffer, addi_mask | addend_mask, 4); @@ -976,7 +931,7 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED, /* Insert the last addi instruction to hold the remainder. */ remainder = offset - addend * (n - 1); gas_assert (remainder >= -32768 && remainder <= 32767); - addend_mask = (((unsigned int)remainder) & 0xffff) << OP_SH_IMM16; + addend_mask = SET_IW_I_IMM16 ((unsigned int)remainder); md_number_to_chars (buffer, addi_mask | addend_mask, 4); fragp->fr_fix += 4; buffer += 4; @@ -985,12 +940,18 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED, /* Load at for the absolute case. */ else { - md_number_to_chars (buffer, OP_MATCH_ORHI | 0x00400000, 4); + md_number_to_chars (buffer, + (MATCH_R1_ORHI | SET_IW_I_B (AT_REGNUM) + | SET_IW_I_A (0)), + 4); fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_NIOS2_HI16); fragp->fr_fix += 4; buffer += 4; - md_number_to_chars (buffer, OP_MATCH_ORI | 0x08400000, 4); + md_number_to_chars (buffer, + (MATCH_R1_ORI | SET_IW_I_B (AT_REGNUM) + | SET_IW_I_A (AT_REGNUM)), + 4); fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol, fragp->fr_offset, 0, BFD_RELOC_NIOS2_LO16); fragp->fr_fix += 4; @@ -998,7 +959,7 @@ md_convert_frag (bfd *headers ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED, } /* Insert the jmp instruction. */ - md_number_to_chars (buffer, OP_MATCH_JMP | (AT_REGNUM << OP_SH_RRS), 4); + md_number_to_chars (buffer, MATCH_R1_JMP | SET_IW_R_A (AT_REGNUM), 4); fragp->fr_fix += 4; buffer += 4; } @@ -1071,9 +1032,10 @@ nios2_diagnose_overflow (valueT fixup, reloc_howto_type *howto, unsigned int range_min; unsigned int range_max; unsigned int address; - gas_assert (fixP->fx_size == 4); - opcode = nios2_find_opcode_hash (value); + + opcode = nios2_find_opcode_hash (value, bfd_get_mach (stdoutput)); gas_assert (opcode); + gas_assert (fixP->fx_size == opcode->size); overflow_msg_type = opcode->overflow_msg; switch (overflow_msg_type) { @@ -1240,7 +1202,8 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) FIXME : for some reason fixP->fx_pcrel isn't 1 when it should be so I'm using the howto structure instead to determine this. */ if (howto->pc_relative == 1) - fixup = fixup - (fixP->fx_frag->fr_address + fixP->fx_where + 4); + fixup = fixup - (fixP->fx_frag->fr_address + fixP->fx_where + + fixP->fx_size); /* Get the instruction or data to be fixed up. */ buf = fixP->fx_frag->fr_literal + fixP->fx_where; @@ -1297,6 +1260,16 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) /** Instruction parsing support. */ +/* General internal error routine. */ + +static void +bad_opcode (const struct nios2_opcode *op) +{ + fprintf (stderr, _("internal error: broken opcode descriptor for `%s %s'\n"), + op->name, op->args); + as_fatal (_("Broken assembler. No assembly attempted.")); +} + /* Special relocation directive strings. */ struct nios2_special_relocS @@ -1363,6 +1336,54 @@ nios2_insn_reloc_destroy (nios2_insn_relocS *reloc) } #endif +/* Look up a register name and validate it for the given regtype. + Return the register mapping or NULL on failure. */ +static struct nios2_reg * +nios2_parse_reg (const char *token, unsigned long regtype) +{ + struct nios2_reg *reg = nios2_reg_lookup (token); + + if (reg == NULL) + { + as_bad (_("unknown register %s"), token); + return NULL; + } + + /* Matched a register, but is it the wrong type? */ + if (!(regtype & reg->regtype)) + { + if (regtype & REG_CONTROL) + as_bad (_("expecting control register")); + else if (reg->regtype & REG_CONTROL) + as_bad (_("illegal use of control register")); + else if (reg->regtype & REG_COPROCESSOR) + as_bad (_("illegal use of coprocessor register")); + else + as_bad (_("invalid register %s"), token); + return NULL; + } + + /* Warn for explicit use of special registers. */ + if (reg->regtype & REG_NORMAL) + { + if (!nios2_as_options.noat && reg->index == 1) + as_warn (_("Register at (r1) can sometimes be corrupted by " + "assembler optimizations.\n" + "Use .set noat to turn off those optimizations " + "(and this warning).")); + if (!nios2_as_options.nobreak && reg->index == 25) + as_warn (_("The debugger will corrupt bt (r25).\n" + "If you don't need to debug this " + "code use .set nobreak to turn off this warning.")); + if (!nios2_as_options.nobreak && reg->index == 30) + as_warn (_("The debugger will corrupt sstatus/ba (r30).\n" + "If you don't need to debug this " + "code use .set nobreak to turn off this warning.")); + } + + return reg; +} + /* The various nios2_assemble_* functions call this function to generate an expression from a string representing an expression. It then tries to evaluate the expression, and if it can, returns its value. @@ -1371,7 +1392,6 @@ nios2_insn_reloc_destroy (nios2_insn_relocS *reloc) static unsigned long nios2_assemble_expression (const char *exprstr, nios2_insn_infoS *insn, - nios2_insn_relocS *prev_reloc, bfd_reloc_code_real_type reloc_type, unsigned int pcrel) { @@ -1407,10 +1427,8 @@ nios2_assemble_expression (const char *exprstr, /* We potentially have a relocation. */ reloc = nios2_insn_reloc_new (reloc_type, pcrel); - if (prev_reloc != NULL) - prev_reloc->reloc_next = reloc; - else - insn->insn_reloc = reloc; + reloc->reloc_next = insn->insn_reloc; + insn->insn_reloc = reloc; /* Parse the expression string. */ saved_line_ptr = input_line_pointer; @@ -1429,480 +1447,310 @@ nios2_assemble_expression (const char *exprstr, return (unsigned long) value; } -/* Argument assemble functions. - All take an instruction argument string, and a pointer - to an instruction opcode. Upon return the insn_opcode - has the relevant fields filled in to represent the arg - string. The return value is NULL if successful, or - an error message if an error was detected. - - The naming conventions for these functions match the args template - in the nios2_opcode structure, as documented in include/opcode/nios2.h. - For example, nios2_assemble_args_dst is used for instructions with - "d,s,t" args. - See nios2_arg_info_structs below for the exact correspondence. */ -static void -nios2_assemble_args_dst (nios2_insn_infoS *insn_info) +/* Argument assemble functions. */ +static void +nios2_assemble_arg_c (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL - && insn_info->insn_tokens[2] != NULL - && insn_info->insn_tokens[3] != NULL) - { - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]); - struct nios2_reg *src2 = nios2_reg_lookup (insn_info->insn_tokens[3]); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index); + struct nios2_reg *reg = nios2_parse_reg (token, REG_CONTROL); + const struct nios2_opcode *op = insn->insn_nios2_opcode; - if (src1 == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); - else - SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index); - - if (src2 == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[3]); - else - SET_INSN_FIELD (RRT, insn_info->insn_code, src2->index); + if (reg == NULL) + return; - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]); + switch (op->format) + { + case iw_r_type: + insn->insn_code |= SET_IW_R_IMM5 (reg->index); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_tsi (nios2_insn_infoS *insn_info) +static void +nios2_assemble_arg_d (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL && - insn_info->insn_tokens[2] != NULL && insn_info->insn_tokens[3] != NULL) - { - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]); - unsigned int src2 - = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info, - insn_info->insn_reloc, BFD_RELOC_NIOS2_S16, - 0); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (IRT, insn_info->insn_code, dst->index); - - if (src1 == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); - else - SET_INSN_FIELD (IRS, insn_info->insn_code, src1->index); + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned long regtype = REG_NORMAL; + struct nios2_reg *reg; - SET_INSN_FIELD (IMM16, insn_info->insn_code, src2); - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]); - SET_INSN_FIELD (IMM16, insn_info->insn_code, 0); - } -} + if (op->format == iw_custom_type) + regtype |= REG_COPROCESSOR; + reg = nios2_parse_reg (token, regtype); + if (reg == NULL) + return; -static void -nios2_assemble_args_tsu (nios2_insn_infoS *insn_info) -{ - if (insn_info->insn_tokens[1] != NULL - && insn_info->insn_tokens[2] != NULL - && insn_info->insn_tokens[3] != NULL) + switch (op->format) { - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]); - unsigned int src2 - = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info, - insn_info->insn_reloc, BFD_RELOC_NIOS2_U16, - 0); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (IRT, insn_info->insn_code, dst->index); - - if (src1 == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); + case iw_r_type: + insn->insn_code |= SET_IW_R_C (reg->index); + break; + case iw_custom_type: + insn->insn_code |= SET_IW_CUSTOM_C (reg->index); + if (reg->regtype & REG_COPROCESSOR) + insn->insn_code |= SET_IW_CUSTOM_READC (0); else - SET_INSN_FIELD (IRS, insn_info->insn_code, src1->index); - - SET_INSN_FIELD (IMM16, insn_info->insn_code, src2); - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]); - SET_INSN_FIELD (IMM16, insn_info->insn_code, 0); + insn->insn_code |= SET_IW_CUSTOM_READC (1); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_sto (nios2_insn_infoS *insn_info) +static void +nios2_assemble_arg_s (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL - && insn_info->insn_tokens[2] != NULL - && insn_info->insn_tokens[3] != NULL) - { - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]); - unsigned int src2 - = nios2_assemble_expression (insn_info->insn_tokens[3], insn_info, - insn_info->insn_reloc, BFD_RELOC_16_PCREL, - 1); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (IRS, insn_info->insn_code, dst->index); + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned long regtype = REG_NORMAL; + struct nios2_reg *reg; - if (src1 == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); - else - SET_INSN_FIELD (IRT, insn_info->insn_code, src1->index); + if (op->format == iw_custom_type) + regtype |= REG_COPROCESSOR; + reg = nios2_parse_reg (token, regtype); + if (reg == NULL) + return; - SET_INSN_FIELD (IMM16, insn_info->insn_code, src2); - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]); - SET_INSN_FIELD (IMM16, insn_info->insn_code, 0); - } -} - -static void -nios2_assemble_args_o (nios2_insn_infoS *insn_info) -{ - if (insn_info->insn_tokens[1] != NULL) + switch (op->format) { - unsigned long immed - = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info, - insn_info->insn_reloc, BFD_RELOC_16_PCREL, - 1); - SET_INSN_FIELD (IMM16, insn_info->insn_code, immed); - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]); - SET_INSN_FIELD (IMM16, insn_info->insn_code, 0); + case iw_r_type: + insn->insn_code |= SET_IW_R_A (reg->index); + break; + case iw_i_type: + insn->insn_code |= SET_IW_I_A (reg->index); + break; + case iw_custom_type: + insn->insn_code |= SET_IW_CUSTOM_A (reg->index); + if (reg->regtype & REG_COPROCESSOR) + insn->insn_code |= SET_IW_CUSTOM_READA (0); + else + insn->insn_code |= SET_IW_CUSTOM_READA (1); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_is (nios2_insn_infoS *insn_info) +static void +nios2_assemble_arg_t (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL) - { - struct nios2_reg *addr_src = nios2_reg_lookup (insn_info->insn_tokens[2]); - unsigned long immed - = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info, - insn_info->insn_reloc, BFD_RELOC_NIOS2_S16, - 0); + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned long regtype = REG_NORMAL; + struct nios2_reg *reg; - SET_INSN_FIELD (IMM16, insn_info->insn_code, immed); + if (op->format == iw_custom_type) + regtype |= REG_COPROCESSOR; + reg = nios2_parse_reg (token, regtype); + if (reg == NULL) + return; - if (addr_src == NULL) - as_bad (_("unknown base register %s"), insn_info->insn_tokens[2]); + switch (op->format) + { + case iw_r_type: + insn->insn_code |= SET_IW_R_B (reg->index); + break; + case iw_i_type: + insn->insn_code |= SET_IW_I_B (reg->index); + break; + case iw_custom_type: + insn->insn_code |= SET_IW_CUSTOM_B (reg->index); + if (reg->regtype & REG_COPROCESSOR) + insn->insn_code |= SET_IW_CUSTOM_READB (0); else - SET_INSN_FIELD (RRS, insn_info->insn_code, addr_src->index); - - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]); - SET_INSN_FIELD (IMM16, insn_info->insn_code, 0); + insn->insn_code |= SET_IW_CUSTOM_READB (1); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_m (nios2_insn_infoS *insn_info) +static void +nios2_assemble_arg_i (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL) - { - unsigned long immed - = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info, - insn_info->insn_reloc, - (nios2_as_options.noat - ? BFD_RELOC_NIOS2_CALL26_NOAT - : BFD_RELOC_NIOS2_CALL26), - 0); - - SET_INSN_FIELD (IMM26, insn_info->insn_code, immed); - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]); - SET_INSN_FIELD (IMM26, insn_info->insn_code, 0); - } -} + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned int val; -static void -nios2_assemble_args_s (nios2_insn_infoS *insn_info) -{ - if (insn_info->insn_tokens[1] != NULL) + switch (op->format) { - struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[1]); - if (src == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (RRS, insn_info->insn_code, src->index); - - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]); + case iw_i_type: + val = nios2_assemble_expression (token, insn, + BFD_RELOC_NIOS2_S16, 0); + insn->constant_bits |= SET_IW_I_IMM16 (val); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_tis (nios2_insn_infoS *insn_info) +static void +nios2_assemble_arg_u (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL - && insn_info->insn_tokens[2] != NULL - && insn_info->insn_tokens[3] != NULL) - { - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - struct nios2_reg *addr_src = nios2_reg_lookup (insn_info->insn_tokens[3]); - unsigned long immed - = nios2_assemble_expression (insn_info->insn_tokens[2], insn_info, - insn_info->insn_reloc, BFD_RELOC_NIOS2_S16, - 0); - - if (addr_src == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[3]); - else - SET_INSN_FIELD (RRS, insn_info->insn_code, addr_src->index); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (RRT, insn_info->insn_code, dst->index); + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned int val; - SET_INSN_FIELD (IMM16, insn_info->insn_code, immed); - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]); - SET_INSN_FIELD (IMM16, insn_info->insn_code, 0); - } -} - -static void -nios2_assemble_args_dc (nios2_insn_infoS *insn_info) -{ - if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL) + switch (op->format) { - struct nios2_reg *ctl = nios2_reg_lookup (insn_info->insn_tokens[2]); - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - - if (ctl == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (RCTL, insn_info->insn_code, ctl->index); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); - else - SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index); - - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]); + case iw_i_type: + val = nios2_assemble_expression (token, insn, + BFD_RELOC_NIOS2_U16, 0); + insn->constant_bits |= SET_IW_I_IMM16 (val); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_cs (nios2_insn_infoS *insn_info) +static void +nios2_assemble_arg_o (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL) - { - struct nios2_reg *ctl = nios2_reg_lookup (insn_info->insn_tokens[1]); - struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[2]); - - if (ctl == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else if (ctl->index == 4) - as_bad (_("ipending control register (ctl4) is read-only\n")); - else - SET_INSN_FIELD (RCTL, insn_info->insn_code, ctl->index); + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned int val; - if (src == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); - else - SET_INSN_FIELD (RRS, insn_info->insn_code, src->index); - - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]); + switch (op->format) + { + case iw_i_type: + val = nios2_assemble_expression (token, insn, + BFD_RELOC_16_PCREL, 1); + insn->constant_bits |= SET_IW_I_IMM16 (val); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_ds (nios2_insn_infoS * insn_info) +static void +nios2_assemble_arg_j (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL && insn_info->insn_tokens[2] != NULL) - { - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - struct nios2_reg *src = nios2_reg_lookup (insn_info->insn_tokens[2]); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index); - - if (src == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); - else - SET_INSN_FIELD (RRS, insn_info->insn_code, src->index); + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned int val; - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[3]); + switch (op->format) + { + case iw_r_type: + val = nios2_assemble_expression (token, insn, + BFD_RELOC_NIOS2_IMM5, 0); + insn->constant_bits |= SET_IW_R_IMM5 (val); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_ldst (nios2_insn_infoS *insn_info) +static void +nios2_assemble_arg_l (const char *token, nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL - && insn_info->insn_tokens[2] != NULL - && insn_info->insn_tokens[3] != NULL - && insn_info->insn_tokens[4] != NULL) - { - unsigned long custom_n - = nios2_assemble_expression (insn_info->insn_tokens[1], insn_info, - insn_info->insn_reloc, - BFD_RELOC_NIOS2_IMM8, 0); - - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[2]); - struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[3]); - struct nios2_reg *src2 = nios2_reg_lookup (insn_info->insn_tokens[4]); + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned int val; - SET_INSN_FIELD (CUSTOM_N, insn_info->insn_code, custom_n); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); - else - SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index); - - if (src1 == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[3]); - else - SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index); - - if (src2 == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[4]); - else - SET_INSN_FIELD (RRT, insn_info->insn_code, src2->index); - - /* Set or clear the bits to indicate whether coprocessor registers are - used. */ - if (nios2_coproc_reg (insn_info->insn_tokens[2])) - SET_INSN_FIELD (CUSTOM_C, insn_info->insn_code, 0); - else - SET_INSN_FIELD (CUSTOM_C, insn_info->insn_code, 1); - - if (nios2_coproc_reg (insn_info->insn_tokens[3])) - SET_INSN_FIELD (CUSTOM_A, insn_info->insn_code, 0); - else - SET_INSN_FIELD (CUSTOM_A, insn_info->insn_code, 1); - - if (nios2_coproc_reg (insn_info->insn_tokens[4])) - SET_INSN_FIELD (CUSTOM_B, insn_info->insn_code, 0); - else - SET_INSN_FIELD (CUSTOM_B, insn_info->insn_code, 1); - - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[5]); + switch (op->format) + { + case iw_custom_type: + val = nios2_assemble_expression (token, insn, + BFD_RELOC_NIOS2_IMM8, 0); + insn->constant_bits |= SET_IW_CUSTOM_N (val); + break; + default: + bad_opcode (op); } } -static void -nios2_assemble_args_none (nios2_insn_infoS *insn_info ATTRIBUTE_UNUSED) +static void +nios2_assemble_arg_m (const char *token, nios2_insn_infoS *insn) { - /* Nothing to do. */ -} + const struct nios2_opcode *op = insn->insn_nios2_opcode; + unsigned int val; -static void -nios2_assemble_args_dsj (nios2_insn_infoS *insn_info) -{ - if (insn_info->insn_tokens[1] != NULL - && insn_info->insn_tokens[2] != NULL - && insn_info->insn_tokens[3] != NULL) + switch (op->format) { - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - struct nios2_reg *src1 = nios2_reg_lookup (insn_info->insn_tokens[2]); - - /* A 5-bit constant expression. */ - unsigned int src2 = - nios2_assemble_expression (insn_info->insn_tokens[3], insn_info, - insn_info->insn_reloc, - BFD_RELOC_NIOS2_IMM5, 0); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index); - - if (src1 == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[2]); - else - SET_INSN_FIELD (RRS, insn_info->insn_code, src1->index); - - SET_INSN_FIELD (IMM5, insn_info->insn_code, src2); - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[4]); - SET_INSN_FIELD (IMM5, insn_info->insn_code, 0); + case iw_j_type: + val = nios2_assemble_expression (token, insn, + (nios2_as_options.noat + ? BFD_RELOC_NIOS2_CALL26_NOAT + : BFD_RELOC_NIOS2_CALL26), + 0); + insn->constant_bits |= SET_IW_J_IMM26 (val); + break; + default: + bad_opcode (op); } } static void -nios2_assemble_args_d (nios2_insn_infoS *insn_info) +nios2_assemble_args (nios2_insn_infoS *insn) { - if (insn_info->insn_tokens[1] != NULL) - { - struct nios2_reg *dst = nios2_reg_lookup (insn_info->insn_tokens[1]); - - if (dst == NULL) - as_bad (_("unknown register %s"), insn_info->insn_tokens[1]); - else - SET_INSN_FIELD (RRD, insn_info->insn_code, dst->index); + const struct nios2_opcode *op = insn->insn_nios2_opcode; + const char *argptr; + unsigned int tokidx, ntok; - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]); - } -} + /* Make sure there are enough arguments. */ + ntok = (op->pinfo & NIOS2_INSN_OPTARG) ? op->num_args - 1 : op->num_args; + for (tokidx = 1; tokidx <= ntok; tokidx++) + if (insn->insn_tokens[tokidx] == NULL) + { + as_bad ("missing argument"); + return; + } -static void -nios2_assemble_args_b (nios2_insn_infoS *insn_info) -{ - unsigned int imm5 = 0; + for (argptr = op->args, tokidx = 1; + *argptr && insn->insn_tokens[tokidx]; + argptr++) + switch (*argptr) + { + case ',': + case '(': + case ')': + break; - if (insn_info->insn_tokens[1] != NULL) - { - /* A 5-bit constant expression. */ - imm5 = nios2_assemble_expression (insn_info->insn_tokens[1], - insn_info, insn_info->insn_reloc, - BFD_RELOC_NIOS2_IMM5, 0); - SET_INSN_FIELD (TRAP_IMM5, insn_info->insn_code, imm5); - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]); - } + case 'c': + nios2_assemble_arg_c (insn->insn_tokens[tokidx++], insn); + break; + + case 'd': + nios2_assemble_arg_d (insn->insn_tokens[tokidx++], insn); + break; + + case 's': + nios2_assemble_arg_s (insn->insn_tokens[tokidx++], insn); + break; + + case 't': + nios2_assemble_arg_t (insn->insn_tokens[tokidx++], insn); + break; + + case 'i': + nios2_assemble_arg_i (insn->insn_tokens[tokidx++], insn); + break; + + case 'u': + nios2_assemble_arg_u (insn->insn_tokens[tokidx++], insn); + break; + + case 'o': + nios2_assemble_arg_o (insn->insn_tokens[tokidx++], insn); + break; + + case 'j': + nios2_assemble_arg_j (insn->insn_tokens[tokidx++], insn); + break; + + case 'l': + nios2_assemble_arg_l (insn->insn_tokens[tokidx++], insn); + break; + + case 'm': + nios2_assemble_arg_m (insn->insn_tokens[tokidx++], insn); + break; + + default: + bad_opcode (op); + break; + } - SET_INSN_FIELD (TRAP_IMM5, insn_info->insn_code, imm5); - - nios2_check_assembly (insn_info->insn_code, insn_info->insn_tokens[2]); -} - -/* This table associates pointers to functions that parse the arguments to an - instruction and fill in the relevant fields of the instruction. */ -const nios2_arg_infoS nios2_arg_info_structs[] = { - /* args, assemble_args_func */ - {"d,s,t", nios2_assemble_args_dst}, - {"d,s,t,E", nios2_assemble_args_dst}, - {"t,s,i", nios2_assemble_args_tsi}, - {"t,s,i,E", nios2_assemble_args_tsi}, - {"t,s,u", nios2_assemble_args_tsu}, - {"t,s,u,E", nios2_assemble_args_tsu}, - {"s,t,o", nios2_assemble_args_sto}, - {"s,t,o,E", nios2_assemble_args_sto}, - {"o", nios2_assemble_args_o}, - {"o,E", nios2_assemble_args_o}, - {"s", nios2_assemble_args_s}, - {"s,E", nios2_assemble_args_s}, - {"", nios2_assemble_args_none}, - {"E", nios2_assemble_args_none}, - {"i(s)", nios2_assemble_args_is}, - {"i(s)E", nios2_assemble_args_is}, - {"m", nios2_assemble_args_m}, - {"m,E", nios2_assemble_args_m}, - {"t,i(s)", nios2_assemble_args_tis}, - {"t,i(s)E", nios2_assemble_args_tis}, - {"d,c", nios2_assemble_args_dc}, - {"d,c,E", nios2_assemble_args_dc}, - {"c,s", nios2_assemble_args_cs}, - {"c,s,E", nios2_assemble_args_cs}, - {"d,s", nios2_assemble_args_ds}, - {"d,s,E", nios2_assemble_args_ds}, - {"l,d,s,t", nios2_assemble_args_ldst}, - {"l,d,s,t,E", nios2_assemble_args_ldst}, - {"d,s,j", nios2_assemble_args_dsj}, - {"d,s,j,E", nios2_assemble_args_dsj}, - {"d", nios2_assemble_args_d}, - {"d,E", nios2_assemble_args_d}, - {"b", nios2_assemble_args_b}, - {"b,E", nios2_assemble_args_b} -}; + /* Perform argument checking. */ + nios2_check_assembly (insn->insn_code | insn->constant_bits, + insn->insn_tokens[tokidx]); +} -#define NIOS2_NUM_ARGS \ - ((sizeof(nios2_arg_info_structs)/sizeof(nios2_arg_info_structs[0]))) -const int nios2_num_arg_info_structs = NIOS2_NUM_ARGS; /* The function consume_arg takes a pointer into a string of instruction tokens (args) and a pointer into a string @@ -1911,73 +1759,18 @@ const int nios2_num_arg_info_structs = NIOS2_NUM_ARGS; expected type, throwing an error if it is not, and returns the pointer argstr. */ static char * -nios2_consume_arg (nios2_insn_infoS *insn, char *argstr, const char *parsestr) +nios2_consume_arg (char *argstr, const char *parsestr) { char *temp; - int regno = -1; switch (*parsestr) { case 'c': - if (!nios2_control_register_arg_p (argstr)) - as_bad (_("expecting control register")); - break; case 'd': case 's': case 't': - - /* We check to make sure we don't have a control register. */ - if (nios2_control_register_arg_p (argstr)) - as_bad (_("illegal use of control register")); - - /* And whether coprocessor registers are valid here. */ - if (nios2_coproc_reg (argstr) - && insn->insn_nios2_opcode->match != OP_MATCH_CUSTOM) - as_bad (_("illegal use of coprocessor register\n")); - - /* Extract a register number if the register is of the - form r[0-9]+, if it is a normal register, set - regno to its number (0-31), else set regno to -1. */ - if (argstr[0] == 'r' && ISDIGIT (argstr[1])) - { - char *p = argstr; - - ++p; - regno = 0; - do - { - regno *= 10; - regno += *p - '0'; - ++p; - } - while (ISDIGIT (*p)); - } - else - regno = -1; - - /* And whether we are using at. */ - if (!nios2_as_options.noat - && (regno == 1 || strprefix (argstr, "at"))) - as_warn (_("Register at (r1) can sometimes be corrupted by assembler " - "optimizations.\n" - "Use .set noat to turn off those optimizations (and this " - "warning).")); - - /* And whether we are using oci registers. */ - if (!nios2_as_options.nobreak - && (regno == 25 || strprefix (argstr, "bt"))) - as_warn (_("The debugger will corrupt bt (r25).\n" - "If you don't need to debug this " - "code use .set nobreak to turn off this warning.")); - - if (!nios2_as_options.nobreak - && (regno == 30 - || strprefix (argstr, "ba") - || strprefix (argstr, "sstatus"))) - as_warn (_("The debugger will corrupt sstatus/ba (r30).\n" - "If you don't need to debug this " - "code use .set nobreak to turn off this warning.")); break; + case 'i': case 'u': if (*argstr == '%') @@ -2000,7 +1793,6 @@ nios2_consume_arg (nios2_insn_infoS *insn, char *argstr, const char *parsestr) case 'm': case 'j': case 'l': - case 'b': /* We can't have %hi, %lo or %hiadj here. */ if (*argstr == '%') as_bad (_("badly formed expression near %s"), argstr); @@ -2038,8 +1830,6 @@ nios2_consume_separator (char *argstr, const char *separator) if (p != NULL) *p++ = 0; - else - as_bad (_("expecting %c near %s"), *separator, argstr); return p; } @@ -2069,23 +1859,25 @@ nios2_parse_args (nios2_insn_infoS *insn, char *argstr, while (p != NULL && !terminate && i < NIOS2_MAX_INSN_TOKENS) { - parsed_args[i] = nios2_consume_arg (insn, p, parsestr); + parsed_args[i] = nios2_consume_arg (p, parsestr); ++parsestr; - if (*parsestr != '\0') + while (*parsestr == '(' || *parsestr == ')' || *parsestr == ',') { + char *context = p; p = nios2_consume_separator (p, parsestr); + /* Check for missing separators. */ + if (!p && !(insn->insn_nios2_opcode->pinfo & NIOS2_INSN_OPTARG)) + { + as_bad (_("expecting %c near %s"), *parsestr, context); + break; + } ++parsestr; } - else + + if (*parsestr == '\0') { /* Check that the argument string has no trailing arguments. */ - /* If we've got a %lo etc relocation, we've zapped the parens with - spaces. */ - if (nios2_special_relocation_p (p)) - end = strpbrk (p, ","); - else - end = strpbrk (p, " ,"); - + end = strpbrk (p, ","); if (end != NULL) as_bad (_("too many arguments")); } @@ -2096,13 +1888,6 @@ nios2_parse_args (nios2_insn_infoS *insn, char *argstr, } parsed_args[i] = NULL; - - /* The argument to break and trap instructions is optional; complain - for other cases of missing arguments. */ - if (*parsestr != '\0' - && insn->insn_nios2_opcode->match != OP_MATCH_BREAK - && insn->insn_nios2_opcode->match != OP_MATCH_TRAP) - as_bad (_("missing argument")); } @@ -2310,17 +2095,18 @@ static void output_insn (nios2_insn_infoS *insn) { char *f; - nios2_insn_relocS *reloc; - - f = frag_more (4); + nios2_insn_relocS *reloc; + f = frag_more (insn->insn_nios2_opcode->size); /* This allocates enough space for the instruction and puts it in the current frag. */ - md_number_to_chars (f, insn->insn_code, 4); + md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size); /* Emit debug info. */ - dwarf2_emit_insn (4); + dwarf2_emit_insn (insn->insn_nios2_opcode->size); /* Create any fixups to be acted on later. */ + for (reloc = insn->insn_reloc; reloc != NULL; reloc = reloc->reloc_next) - fix_new_exp (frag_now, f - frag_now->fr_literal, 4, + fix_new_exp (frag_now, f - frag_now->fr_literal, + insn->insn_nios2_opcode->size, &reloc->reloc_expression, reloc->reloc_pcrel, reloc->reloc_type); } @@ -2346,10 +2132,10 @@ output_ubranch (nios2_insn_infoS *insn) to accommodate the largest possible instruction sequence this may generate. */ f = frag_var (rs_machine_dependent, - UBRANCH_MAX_SIZE, 4, UBRANCH_SUBTYPE (0), - symp, offset, NULL); + UBRANCH_MAX_SIZE, insn->insn_nios2_opcode->size, + UBRANCH_SUBTYPE (0), symp, offset, NULL); - md_number_to_chars (f, insn->insn_code, 4); + md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size); /* We leave fixup generation to md_convert_frag. */ } @@ -2376,10 +2162,10 @@ output_cbranch (nios2_insn_infoS *insn) to accommodate the largest possible instruction sequence this may generate. */ f = frag_var (rs_machine_dependent, - CBRANCH_MAX_SIZE, 4, CBRANCH_SUBTYPE (0), - symp, offset, NULL); + CBRANCH_MAX_SIZE, insn->insn_nios2_opcode->size, + CBRANCH_SUBTYPE (0), symp, offset, NULL); - md_number_to_chars (f, insn->insn_code, 4); + md_number_to_chars (f, insn->insn_code, insn->insn_nios2_opcode->size); /* We leave fixup generation to md_convert_frag. */ } @@ -2399,15 +2185,21 @@ output_call (nios2_insn_infoS *insn) char *f = frag_more (12); nios2_insn_relocS *reloc = insn->insn_reloc; - md_number_to_chars (f, OP_MATCH_ORHI | 0x00400000, 4); + md_number_to_chars (f, + (MATCH_R1_ORHI | SET_IW_I_B (AT_REGNUM) + | SET_IW_I_A (0)), + 4); dwarf2_emit_insn (4); fix_new_exp (frag_now, f - frag_now->fr_literal, 4, &reloc->reloc_expression, 0, BFD_RELOC_NIOS2_HI16); - md_number_to_chars (f + 4, OP_MATCH_ORI | 0x08400000, 4); + md_number_to_chars (f + 4, + (MATCH_R1_ORI | SET_IW_I_B (AT_REGNUM) + | SET_IW_I_A (AT_REGNUM)), + 4); dwarf2_emit_insn (4); fix_new_exp (frag_now, f - frag_now->fr_literal + 4, 4, &reloc->reloc_expression, 0, BFD_RELOC_NIOS2_LO16); - md_number_to_chars (f + 8, OP_MATCH_CALLR | 0x08000000, 4); + md_number_to_chars (f + 8, MATCH_R1_CALLR | SET_IW_R_A (AT_REGNUM), 4); dwarf2_emit_insn (4); } @@ -2419,14 +2211,18 @@ output_addi (nios2_insn_infoS *insn) if (can_evaluate_expr (insn)) { int expr_val = get_expr_value (insn); - if (GET_INSN_FIELD (RRS, insn->insn_code) == 0 + unsigned int rega = GET_IW_I_A (insn->insn_code); + unsigned int regb = GET_IW_I_B (insn->insn_code); + + if (rega == 0 && (expr_val & 0xffff) == 0 && expr_val != 0) { /* We really want a movhi (orhi) here. */ - insn->insn_code = (insn->insn_code & ~OP_MATCH_ADDI) | OP_MATCH_ORHI; - insn->insn_reloc->reloc_expression.X_add_number = - (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff; + insn->insn_code + = MATCH_R1_ORHI | SET_IW_I_A (rega) | SET_IW_I_B (regb); + insn->insn_reloc->reloc_expression.X_add_number + = (expr_val >> 16) & 0xffff; insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16; } } @@ -2443,10 +2239,14 @@ output_andi (nios2_insn_infoS *insn) int expr_val = get_expr_value (insn); if (expr_val != 0 && (expr_val & 0xffff) == 0) { - /* We really want a movhi (orhi) here. */ - insn->insn_code = (insn->insn_code & ~OP_MATCH_ANDI) | OP_MATCH_ANDHI; - insn->insn_reloc->reloc_expression.X_add_number = - (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff; + unsigned int rega = GET_IW_I_A (insn->insn_code); + unsigned int regb = GET_IW_I_B (insn->insn_code); + + /* We really want an andhi here. */ + insn->insn_code + = MATCH_R1_ANDHI | SET_IW_I_A (rega) | SET_IW_I_B (regb); + insn->insn_reloc->reloc_expression.X_add_number + = (expr_val >> 16) & 0xffff; insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16; } } @@ -2463,10 +2263,14 @@ output_ori (nios2_insn_infoS *insn) int expr_val = get_expr_value (insn); if (expr_val != 0 && (expr_val & 0xffff) == 0) { + unsigned int rega = GET_IW_I_A (insn->insn_code); + unsigned int regb = GET_IW_I_B (insn->insn_code); + /* We really want a movhi (orhi) here. */ - insn->insn_code = (insn->insn_code & ~OP_MATCH_ORI) | OP_MATCH_ORHI; - insn->insn_reloc->reloc_expression.X_add_number = - (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff; + insn->insn_code + = MATCH_R1_ORHI | SET_IW_I_A (rega) | SET_IW_I_B (regb); + insn->insn_reloc->reloc_expression.X_add_number + = (expr_val >> 16) & 0xffff; insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16; } } @@ -2483,10 +2287,14 @@ output_xori (nios2_insn_infoS *insn) int expr_val = get_expr_value (insn); if (expr_val != 0 && (expr_val & 0xffff) == 0) { - /* We really want a movhi (orhi) here. */ - insn->insn_code = (insn->insn_code & ~OP_MATCH_XORI) | OP_MATCH_XORHI; - insn->insn_reloc->reloc_expression.X_add_number = - (insn->insn_reloc->reloc_expression.X_add_number >> 16) & 0xffff; + unsigned int rega = GET_IW_I_A (insn->insn_code); + unsigned int regb = GET_IW_I_B (insn->insn_code); + + /* We really want an xorhi here. */ + insn->insn_code + = MATCH_R1_XORHI | SET_IW_I_A (rega) | SET_IW_I_B (regb); + insn->insn_reloc->reloc_expression.X_add_number + = (expr_val >> 16) & 0xffff; insn->insn_reloc->reloc_type = BFD_RELOC_NIOS2_U16; } } @@ -2504,22 +2312,22 @@ output_movia (nios2_insn_infoS *insn) and puts it in the current frag. */ char *f = frag_more (8); nios2_insn_relocS *reloc = insn->insn_reloc; - unsigned long reg_index = GET_INSN_FIELD (IRT, insn->insn_code); + unsigned long reg_index = GET_IW_I_B (insn->insn_code); /* If the reloc is NULL, there was an error assembling the movia. */ if (reloc != NULL) { md_number_to_chars (f, insn->insn_code, 4); dwarf2_emit_insn (4); - md_number_to_chars (f + 4, - (OP_MATCH_ADDI | (reg_index << OP_SH_IRT) - | (reg_index << OP_SH_IRS)), - 4); - dwarf2_emit_insn (4); fix_new (frag_now, f - frag_now->fr_literal, 4, reloc->reloc_expression.X_add_symbol, reloc->reloc_expression.X_add_number, 0, BFD_RELOC_NIOS2_HIADJ16); + md_number_to_chars (f + 4, + (MATCH_R1_ADDI | SET_IW_I_A (reg_index) + | SET_IW_I_B (reg_index)), + 4); + dwarf2_emit_insn (4); fix_new (frag_now, f + 4 - frag_now->fr_literal, 4, reloc->reloc_expression.X_add_symbol, reloc->reloc_expression.X_add_number, 0, BFD_RELOC_NIOS2_LO16); @@ -2599,10 +2407,9 @@ md_begin (void) arguments. */ nios2_opcode_hash = hash_new (); nios2_reg_hash = hash_new (); - nios2_arg_hash = hash_new (); nios2_ps_hash = hash_new (); - for (i = 0; i < NUMOPCODES; ++i) + for (i = 0; i < nios2_num_opcodes; ++i) { inserted = hash_insert (nios2_opcode_hash, nios2_opcodes[i].name, @@ -2631,20 +2438,6 @@ md_begin (void) } - for (i = 0; i < nios2_num_arg_info_structs; ++i) - { - inserted - = hash_insert (nios2_arg_hash, nios2_arg_info_structs[i].args, - (PTR) & nios2_arg_info_structs[i]); - if (inserted != NULL) - { - fprintf (stderr, _("internal error: can't hash `%s': %s\n"), - nios2_arg_info_structs[i].args, inserted); - /* Probably a memory allocation problem? Give up now. */ - as_fatal (_("Broken assembler. No assembly attempted.")); - } - } - for (i = 0; i < nios2_num_ps_insn_info_structs; ++i) { inserted @@ -2680,7 +2473,6 @@ md_assemble (char *op_str) { char *argstr; char *op_strdup = NULL; - nios2_arg_infoS *arg_info; unsigned long saved_pinfo = 0; nios2_insn_infoS thisinsn; nios2_insn_infoS *insn = &thisinsn; @@ -2707,6 +2499,7 @@ md_assemble (char *op_str) nios2_ps_insn_infoS *ps_insn = NULL; /* Set the opcode for the instruction. */ insn->insn_code = insn->insn_nios2_opcode->match; + insn->constant_bits = 0; /* Parse the arguments pointed to by argstr. */ if (nios2_mode == NIOS2_MODE_ASSEMBLE) @@ -2726,53 +2519,41 @@ md_assemble (char *op_str) == NIOS2_INSN_MACRO) ps_insn = nios2_translate_pseudo_insn (insn); - /* Find the assemble function, and call it. */ - arg_info = nios2_arg_lookup (insn->insn_nios2_opcode->args); - if (arg_info != NULL) - { - arg_info->assemble_args_func (insn); - - if (nios2_as_options.relax != relax_none - && !nios2_as_options.noat - && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH) - output_ubranch (insn); - else if (nios2_as_options.relax != relax_none - && !nios2_as_options.noat - && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH) - output_cbranch (insn); - else if (nios2_as_options.relax == relax_all - && !nios2_as_options.noat - && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL - && insn->insn_reloc - && ((insn->insn_reloc->reloc_type - == BFD_RELOC_NIOS2_CALL26) - || (insn->insn_reloc->reloc_type - == BFD_RELOC_NIOS2_CALL26_NOAT))) - output_call (insn); - else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ANDI) - output_andi (insn); - else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ORI) - output_ori (insn); - else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_XORI) - output_xori (insn); - else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ADDI) - output_addi (insn); - else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA) - output_movia (insn); - else - output_insn (insn); - if (ps_insn) - nios2_cleanup_pseudo_insn (insn, ps_insn); - } + /* Assemble the parsed arguments into the instruction word. */ + nios2_assemble_args (insn); + + /* Handle relaxation and other transformations. */ + if (nios2_as_options.relax != relax_none + && !nios2_as_options.noat + && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH) + output_ubranch (insn); + else if (nios2_as_options.relax != relax_none + && !nios2_as_options.noat + && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH) + output_cbranch (insn); + else if (nios2_as_options.relax == relax_all + && !nios2_as_options.noat + && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL + && insn->insn_reloc + && ((insn->insn_reloc->reloc_type + == BFD_RELOC_NIOS2_CALL26) + || (insn->insn_reloc->reloc_type + == BFD_RELOC_NIOS2_CALL26_NOAT))) + output_call (insn); + else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ANDI) + output_andi (insn); + else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ORI) + output_ori (insn); + else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_XORI) + output_xori (insn); + else if (insn->insn_nios2_opcode->pinfo & NIOS2_INSN_ADDI) + output_addi (insn); + else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA) + output_movia (insn); else - { - /* The assembler is broken. */ - fprintf (stderr, - _("internal error: %s is not a valid argument syntax\n"), - insn->insn_nios2_opcode->args); - /* Probably a memory allocation problem. Give up now. */ - as_fatal (_("Broken assembler. No assembly attempted.")); - } + output_insn (insn); + if (ps_insn) + nios2_cleanup_pseudo_insn (insn, ps_insn); } else /* Unrecognised instruction - error. */ diff --git a/binutils-2.25/gas/config/tc-s390.c b/binutils-2.25/gas/config/tc-s390.c index 59f6ab6c..60a7dacf 100644 --- a/binutils-2.25/gas/config/tc-s390.c +++ b/binutils-2.25/gas/config/tc-s390.c @@ -489,7 +489,7 @@ md_show_usage (FILE *stream) static void s390_setup_opcodes (void) { - register const struct s390_opcode *op; + const struct s390_opcode *op; const struct s390_opcode *op_end; bfd_boolean dup_insn = FALSE; const char *retval; @@ -536,7 +536,7 @@ s390_setup_opcodes (void) void md_begin (void) { - register const struct s390_opcode *op; + const struct s390_opcode *op; const struct s390_opcode *op_end; const char *retval; diff --git a/binutils-2.25/gas/config/tc-sh.c b/binutils-2.25/gas/config/tc-sh.c index 6e9ae921..888a51f1 100644 --- a/binutils-2.25/gas/config/tc-sh.c +++ b/binutils-2.25/gas/config/tc-sh.c @@ -811,7 +811,7 @@ sh_cons_fix_new (fragS *frag, int off, int size, expressionS *exp, /* Clobbers input_line_pointer, checks end-of-line. */ /* NBYTES 1=.byte, 2=.word, 4=.long */ static void -sh_elf_cons (register int nbytes) +sh_elf_cons (int nbytes) { expressionS exp; diff --git a/binutils-2.25/gas/config/tc-sparc.c b/binutils-2.25/gas/config/tc-sparc.c index 758fcc81..e3fd64ae 100644 --- a/binutils-2.25/gas/config/tc-sparc.c +++ b/binutils-2.25/gas/config/tc-sparc.c @@ -863,9 +863,9 @@ cmp_reg_entry (const void *parg, const void *qarg) void md_begin (void) { - register const char *retval = NULL; + const char *retval = NULL; int lose = 0; - register unsigned int i = 0; + unsigned int i = 0; /* We don't get a chance to initialize anything before md_parse_option is called, and it may not be called, so handle default initialization diff --git a/binutils-2.25/gas/config/tc-tic30.c b/binutils-2.25/gas/config/tc-tic30.c index dbcbf3c8..436aaebf 100644 --- a/binutils-2.25/gas/config/tc-tic30.c +++ b/binutils-2.25/gas/config/tc-tic30.c @@ -1116,7 +1116,7 @@ md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED, void md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED, - register fragS *fragP ATTRIBUTE_UNUSED) + fragS *fragP ATTRIBUTE_UNUSED) { debug ("In md_convert_frag()\n"); } diff --git a/binutils-2.25/gas/config/tc-tic4x.c b/binutils-2.25/gas/config/tc-tic4x.c index dc821680..12d8ec95 100644 --- a/binutils-2.25/gas/config/tc-tic4x.c +++ b/binutils-2.25/gas/config/tc-tic4x.c @@ -831,7 +831,7 @@ tic4x_globl (int ignore ATTRIBUTE_UNUSED) static void tic4x_cons (int bytes) { - register unsigned int c; + unsigned int c; do { SKIP_WHITESPACE (); @@ -875,7 +875,7 @@ static void tic4x_stringer (int append_zero) { int bytes; - register unsigned int c; + unsigned int c; bytes = 0; do diff --git a/binutils-2.25/gas/config/tc-z80.c b/binutils-2.25/gas/config/tc-z80.c index 54fa322c..a602dc74 100644 --- a/binutils-2.25/gas/config/tc-z80.c +++ b/binutils-2.25/gas/config/tc-z80.c @@ -557,6 +557,8 @@ parse_exp_not_indexed (const char *s, expressionS *op) case O_illegal: error (_("bad expression syntax")); break; + default: + break; } return input_line_pointer; } @@ -604,6 +606,8 @@ parse_exp (const char *s, expressionS *op) op->X_op = O_md1; } break; + default: + break; } return res; } |