mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-28 15:18:37 +08:00
* config/tc-mips.h (tc_mips_regname_to_dw2regnum): Declare.
* config/tc-mipc.c (ABI_NEEDS_64BIT_REGS, ISA_HAS_64BIT_REGS, ISA_HAS_DROR, ISA_HAS_ROR): Reformat. (regname, RTYPE_MASK, RTYPE_NUM, RTYPE_FPU, RTYPE_FCC, RTYPE_VEC, RTYPE_GP, RTYPE_CP0, RTYPE_PC, RTYPE_ACC, RTYPE_CCC, RNUM_MASK, RWARN, GENERIC_REGISTER_NUMBERS, FPU_REGISTER_NAMES, FPU_CONDITION_CODE_NAMES, COPROC_CONDITION_CODE_NAMES, N32N64_SYMBOLIC_REGISTER_NAMES, O32_SYMBOLIC_REGISTER_NAMES, SYMBOLIC_REGISTER_NAMES, MIPS16_SPECIAL_REGISTER_NAMES, MDMX_VECTOR_REGISTER_NAMES, MIPS_DSP_ACCUMULATOR_NAMES, reg_names, reg_names_o32, reg_names_n32n64): Define register classes. (reg_lookup): New function, use register classes. (md_begin): Reserve register names in the symbol table. Simplify OBJ_ELF defines. (mips_ip): Fix comment formatting. Handle symbolic COP0 registers. Use reg_lookup. (mips16_ip): Use reg_lookup. (tc_get_register): Likewise. (tc_mips_regname_to_dw2regnum): New function. -------------------------------------------------------------------
This commit is contained in:
@ -1,3 +1,26 @@
|
||||
2006-05-19 Thiemo Seufer <ths@mips.com>
|
||||
David Ung <davidu@mips.com>
|
||||
|
||||
* config/tc-mips.h (tc_mips_regname_to_dw2regnum): Declare.
|
||||
* config/tc-mipc.c (ABI_NEEDS_64BIT_REGS, ISA_HAS_64BIT_REGS,
|
||||
ISA_HAS_DROR, ISA_HAS_ROR): Reformat.
|
||||
(regname, RTYPE_MASK, RTYPE_NUM, RTYPE_FPU, RTYPE_FCC, RTYPE_VEC,
|
||||
RTYPE_GP, RTYPE_CP0, RTYPE_PC, RTYPE_ACC, RTYPE_CCC, RNUM_MASK,
|
||||
RWARN, GENERIC_REGISTER_NUMBERS, FPU_REGISTER_NAMES,
|
||||
FPU_CONDITION_CODE_NAMES, COPROC_CONDITION_CODE_NAMES,
|
||||
N32N64_SYMBOLIC_REGISTER_NAMES, O32_SYMBOLIC_REGISTER_NAMES,
|
||||
SYMBOLIC_REGISTER_NAMES, MIPS16_SPECIAL_REGISTER_NAMES,
|
||||
MDMX_VECTOR_REGISTER_NAMES, MIPS_DSP_ACCUMULATOR_NAMES, reg_names,
|
||||
reg_names_o32, reg_names_n32n64): Define register classes.
|
||||
(reg_lookup): New function, use register classes.
|
||||
(md_begin): Reserve register names in the symbol table. Simplify
|
||||
OBJ_ELF defines.
|
||||
(mips_ip): Fix comment formatting. Handle symbolic COP0 registers.
|
||||
Use reg_lookup.
|
||||
(mips16_ip): Use reg_lookup.
|
||||
(tc_get_register): Likewise.
|
||||
(tc_mips_regname_to_dw2regnum): New function.
|
||||
|
||||
2006-05-19 Thiemo Seufer <ths@mips.com>
|
||||
|
||||
* config/tc-arm.c, config/tc-arm.h (tc_arm_regname_to_dw2regnum):
|
||||
|
@ -301,33 +301,31 @@ static int mips_32bitmode = 0;
|
||||
#define ABI_NEEDS_32BIT_REGS(ABI) ((ABI) == O32_ABI)
|
||||
|
||||
/* Likewise 64-bit registers. */
|
||||
#define ABI_NEEDS_64BIT_REGS(ABI) \
|
||||
((ABI) == N32_ABI \
|
||||
|| (ABI) == N64_ABI \
|
||||
#define ABI_NEEDS_64BIT_REGS(ABI) \
|
||||
((ABI) == N32_ABI \
|
||||
|| (ABI) == N64_ABI \
|
||||
|| (ABI) == O64_ABI)
|
||||
|
||||
/* Return true if ISA supports 64 bit gp register instructions. */
|
||||
#define ISA_HAS_64BIT_REGS(ISA) ( \
|
||||
(ISA) == ISA_MIPS3 \
|
||||
|| (ISA) == ISA_MIPS4 \
|
||||
|| (ISA) == ISA_MIPS5 \
|
||||
|| (ISA) == ISA_MIPS64 \
|
||||
|| (ISA) == ISA_MIPS64R2 \
|
||||
)
|
||||
#define ISA_HAS_64BIT_REGS(ISA) \
|
||||
((ISA) == ISA_MIPS3 \
|
||||
|| (ISA) == ISA_MIPS4 \
|
||||
|| (ISA) == ISA_MIPS5 \
|
||||
|| (ISA) == ISA_MIPS64 \
|
||||
|| (ISA) == ISA_MIPS64R2)
|
||||
|
||||
/* Return true if ISA supports 64-bit right rotate (dror et al.)
|
||||
instructions. */
|
||||
#define ISA_HAS_DROR(ISA) ( \
|
||||
(ISA) == ISA_MIPS64R2 \
|
||||
)
|
||||
#define ISA_HAS_DROR(ISA) \
|
||||
((ISA) == ISA_MIPS64R2)
|
||||
|
||||
/* Return true if ISA supports 32-bit right rotate (ror et al.)
|
||||
instructions. */
|
||||
#define ISA_HAS_ROR(ISA) ( \
|
||||
(ISA) == ISA_MIPS32R2 \
|
||||
|| (ISA) == ISA_MIPS64R2 \
|
||||
|| mips_opts.ase_smartmips \
|
||||
)
|
||||
#define ISA_HAS_ROR(ISA) \
|
||||
((ISA) == ISA_MIPS32R2 \
|
||||
|| (ISA) == ISA_MIPS64R2 \
|
||||
|| mips_opts.ase_smartmips)
|
||||
|
||||
|
||||
#define HAVE_32BIT_GPRS \
|
||||
(mips_opts.gp32 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))
|
||||
@ -1402,8 +1400,297 @@ init_vr4120_conflicts (void)
|
||||
#undef CONFLICT
|
||||
}
|
||||
|
||||
/* This function is called once, at assembler startup time. It should
|
||||
set up all the tables, etc. that the MD part of the assembler will need. */
|
||||
struct regname {
|
||||
const char *name;
|
||||
unsigned int num;
|
||||
};
|
||||
|
||||
#define RTYPE_MASK 0x1ff00
|
||||
#define RTYPE_NUM 0x00100
|
||||
#define RTYPE_FPU 0x00200
|
||||
#define RTYPE_FCC 0x00400
|
||||
#define RTYPE_VEC 0x00800
|
||||
#define RTYPE_GP 0x01000
|
||||
#define RTYPE_CP0 0x02000
|
||||
#define RTYPE_PC 0x04000
|
||||
#define RTYPE_ACC 0x08000
|
||||
#define RTYPE_CCC 0x10000
|
||||
#define RNUM_MASK 0x000ff
|
||||
#define RWARN 0x80000
|
||||
|
||||
#define GENERIC_REGISTER_NUMBERS \
|
||||
{"$0", RTYPE_NUM | 0}, \
|
||||
{"$1", RTYPE_NUM | 1}, \
|
||||
{"$2", RTYPE_NUM | 2}, \
|
||||
{"$3", RTYPE_NUM | 3}, \
|
||||
{"$4", RTYPE_NUM | 4}, \
|
||||
{"$5", RTYPE_NUM | 5}, \
|
||||
{"$6", RTYPE_NUM | 6}, \
|
||||
{"$7", RTYPE_NUM | 7}, \
|
||||
{"$8", RTYPE_NUM | 8}, \
|
||||
{"$9", RTYPE_NUM | 9}, \
|
||||
{"$10", RTYPE_NUM | 10}, \
|
||||
{"$11", RTYPE_NUM | 11}, \
|
||||
{"$12", RTYPE_NUM | 12}, \
|
||||
{"$13", RTYPE_NUM | 13}, \
|
||||
{"$14", RTYPE_NUM | 14}, \
|
||||
{"$15", RTYPE_NUM | 15}, \
|
||||
{"$16", RTYPE_NUM | 16}, \
|
||||
{"$17", RTYPE_NUM | 17}, \
|
||||
{"$18", RTYPE_NUM | 18}, \
|
||||
{"$19", RTYPE_NUM | 19}, \
|
||||
{"$20", RTYPE_NUM | 20}, \
|
||||
{"$21", RTYPE_NUM | 21}, \
|
||||
{"$22", RTYPE_NUM | 22}, \
|
||||
{"$23", RTYPE_NUM | 23}, \
|
||||
{"$24", RTYPE_NUM | 24}, \
|
||||
{"$25", RTYPE_NUM | 25}, \
|
||||
{"$26", RTYPE_NUM | 26}, \
|
||||
{"$27", RTYPE_NUM | 27}, \
|
||||
{"$28", RTYPE_NUM | 28}, \
|
||||
{"$29", RTYPE_NUM | 29}, \
|
||||
{"$30", RTYPE_NUM | 30}, \
|
||||
{"$31", RTYPE_NUM | 31}
|
||||
|
||||
#define FPU_REGISTER_NAMES \
|
||||
{"$f0", RTYPE_FPU | 0}, \
|
||||
{"$f1", RTYPE_FPU | 1}, \
|
||||
{"$f2", RTYPE_FPU | 2}, \
|
||||
{"$f3", RTYPE_FPU | 3}, \
|
||||
{"$f4", RTYPE_FPU | 4}, \
|
||||
{"$f5", RTYPE_FPU | 5}, \
|
||||
{"$f6", RTYPE_FPU | 6}, \
|
||||
{"$f7", RTYPE_FPU | 7}, \
|
||||
{"$f8", RTYPE_FPU | 8}, \
|
||||
{"$f9", RTYPE_FPU | 9}, \
|
||||
{"$f10", RTYPE_FPU | 10}, \
|
||||
{"$f11", RTYPE_FPU | 11}, \
|
||||
{"$f12", RTYPE_FPU | 12}, \
|
||||
{"$f13", RTYPE_FPU | 13}, \
|
||||
{"$f14", RTYPE_FPU | 14}, \
|
||||
{"$f15", RTYPE_FPU | 15}, \
|
||||
{"$f16", RTYPE_FPU | 16}, \
|
||||
{"$f17", RTYPE_FPU | 17}, \
|
||||
{"$f18", RTYPE_FPU | 18}, \
|
||||
{"$f19", RTYPE_FPU | 19}, \
|
||||
{"$f20", RTYPE_FPU | 20}, \
|
||||
{"$f21", RTYPE_FPU | 21}, \
|
||||
{"$f22", RTYPE_FPU | 22}, \
|
||||
{"$f23", RTYPE_FPU | 23}, \
|
||||
{"$f24", RTYPE_FPU | 24}, \
|
||||
{"$f25", RTYPE_FPU | 25}, \
|
||||
{"$f26", RTYPE_FPU | 26}, \
|
||||
{"$f27", RTYPE_FPU | 27}, \
|
||||
{"$f28", RTYPE_FPU | 28}, \
|
||||
{"$f29", RTYPE_FPU | 29}, \
|
||||
{"$f30", RTYPE_FPU | 30}, \
|
||||
{"$f31", RTYPE_FPU | 31}
|
||||
|
||||
#define FPU_CONDITION_CODE_NAMES \
|
||||
{"$fcc0", RTYPE_FCC | 0}, \
|
||||
{"$fcc1", RTYPE_FCC | 1}, \
|
||||
{"$fcc2", RTYPE_FCC | 2}, \
|
||||
{"$fcc3", RTYPE_FCC | 3}, \
|
||||
{"$fcc4", RTYPE_FCC | 4}, \
|
||||
{"$fcc5", RTYPE_FCC | 5}, \
|
||||
{"$fcc6", RTYPE_FCC | 6}, \
|
||||
{"$fcc7", RTYPE_FCC | 7}
|
||||
|
||||
#define COPROC_CONDITION_CODE_NAMES \
|
||||
{"$cc0", RTYPE_FCC | RTYPE_CCC | 0}, \
|
||||
{"$cc1", RTYPE_FCC | RTYPE_CCC | 1}, \
|
||||
{"$cc2", RTYPE_FCC | RTYPE_CCC | 2}, \
|
||||
{"$cc3", RTYPE_FCC | RTYPE_CCC | 3}, \
|
||||
{"$cc4", RTYPE_FCC | RTYPE_CCC | 4}, \
|
||||
{"$cc5", RTYPE_FCC | RTYPE_CCC | 5}, \
|
||||
{"$cc6", RTYPE_FCC | RTYPE_CCC | 6}, \
|
||||
{"$cc7", RTYPE_FCC | RTYPE_CCC | 7}
|
||||
|
||||
#define N32N64_SYMBOLIC_REGISTER_NAMES \
|
||||
{"$a4", RTYPE_GP | 8}, \
|
||||
{"$a5", RTYPE_GP | 9}, \
|
||||
{"$a6", RTYPE_GP | 10}, \
|
||||
{"$a7", RTYPE_GP | 11}, \
|
||||
{"$ta0", RTYPE_GP | 8}, /* alias for $a4 */ \
|
||||
{"$ta1", RTYPE_GP | 9}, /* alias for $a5 */ \
|
||||
{"$ta2", RTYPE_GP | 10}, /* alias for $a6 */ \
|
||||
{"$ta3", RTYPE_GP | 11}, /* alias for $a7 */ \
|
||||
{"$t0", RTYPE_GP | 12}, \
|
||||
{"$t1", RTYPE_GP | 13}, \
|
||||
{"$t2", RTYPE_GP | 14}, \
|
||||
{"$t3", RTYPE_GP | 15}
|
||||
|
||||
#define O32_SYMBOLIC_REGISTER_NAMES \
|
||||
{"$t0", RTYPE_GP | 8}, \
|
||||
{"$t1", RTYPE_GP | 9}, \
|
||||
{"$t2", RTYPE_GP | 10}, \
|
||||
{"$t3", RTYPE_GP | 11}, \
|
||||
{"$t4", RTYPE_GP | 12}, \
|
||||
{"$t5", RTYPE_GP | 13}, \
|
||||
{"$t6", RTYPE_GP | 14}, \
|
||||
{"$t7", RTYPE_GP | 15}, \
|
||||
{"$ta0", RTYPE_GP | 12}, /* alias for $t4 */ \
|
||||
{"$ta1", RTYPE_GP | 13}, /* alias for $t5 */ \
|
||||
{"$ta2", RTYPE_GP | 14}, /* alias for $t6 */ \
|
||||
{"$ta3", RTYPE_GP | 15} /* alias for $t7 */
|
||||
|
||||
/* Remaining symbolic register names */
|
||||
#define SYMBOLIC_REGISTER_NAMES \
|
||||
{"$zero", RTYPE_GP | 0}, \
|
||||
{"$at", RTYPE_GP | 1}, \
|
||||
{"$AT", RTYPE_GP | 1}, \
|
||||
{"$v0", RTYPE_GP | 2}, \
|
||||
{"$v1", RTYPE_GP | 3}, \
|
||||
{"$a0", RTYPE_GP | 4}, \
|
||||
{"$a1", RTYPE_GP | 5}, \
|
||||
{"$a2", RTYPE_GP | 6}, \
|
||||
{"$a3", RTYPE_GP | 7}, \
|
||||
{"$s0", RTYPE_GP | 16}, \
|
||||
{"$s1", RTYPE_GP | 17}, \
|
||||
{"$s2", RTYPE_GP | 18}, \
|
||||
{"$s3", RTYPE_GP | 19}, \
|
||||
{"$s4", RTYPE_GP | 20}, \
|
||||
{"$s5", RTYPE_GP | 21}, \
|
||||
{"$s6", RTYPE_GP | 22}, \
|
||||
{"$s7", RTYPE_GP | 23}, \
|
||||
{"$t8", RTYPE_GP | 24}, \
|
||||
{"$t9", RTYPE_GP | 25}, \
|
||||
{"$k0", RTYPE_GP | 26}, \
|
||||
{"$kt0", RTYPE_GP | 26}, \
|
||||
{"$k1", RTYPE_GP | 27}, \
|
||||
{"$kt1", RTYPE_GP | 27}, \
|
||||
{"$gp", RTYPE_GP | 28}, \
|
||||
{"$sp", RTYPE_GP | 29}, \
|
||||
{"$s8", RTYPE_GP | 30}, \
|
||||
{"$fp", RTYPE_GP | 30}, \
|
||||
{"$ra", RTYPE_GP | 31}
|
||||
|
||||
#define MIPS16_SPECIAL_REGISTER_NAMES \
|
||||
{"$pc", RTYPE_PC | 0}
|
||||
|
||||
#define MDMX_VECTOR_REGISTER_NAMES \
|
||||
/* {"$v0", RTYPE_VEC | 0}, clash with REG 2 above */ \
|
||||
/* {"$v1", RTYPE_VEC | 1}, clash with REG 3 above */ \
|
||||
{"$v2", RTYPE_VEC | 2}, \
|
||||
{"$v3", RTYPE_VEC | 3}, \
|
||||
{"$v4", RTYPE_VEC | 4}, \
|
||||
{"$v5", RTYPE_VEC | 5}, \
|
||||
{"$v6", RTYPE_VEC | 6}, \
|
||||
{"$v7", RTYPE_VEC | 7}, \
|
||||
{"$v8", RTYPE_VEC | 8}, \
|
||||
{"$v9", RTYPE_VEC | 9}, \
|
||||
{"$v10", RTYPE_VEC | 10}, \
|
||||
{"$v11", RTYPE_VEC | 11}, \
|
||||
{"$v12", RTYPE_VEC | 12}, \
|
||||
{"$v13", RTYPE_VEC | 13}, \
|
||||
{"$v14", RTYPE_VEC | 14}, \
|
||||
{"$v15", RTYPE_VEC | 15}, \
|
||||
{"$v16", RTYPE_VEC | 16}, \
|
||||
{"$v17", RTYPE_VEC | 17}, \
|
||||
{"$v18", RTYPE_VEC | 18}, \
|
||||
{"$v19", RTYPE_VEC | 19}, \
|
||||
{"$v20", RTYPE_VEC | 20}, \
|
||||
{"$v21", RTYPE_VEC | 21}, \
|
||||
{"$v22", RTYPE_VEC | 22}, \
|
||||
{"$v23", RTYPE_VEC | 23}, \
|
||||
{"$v24", RTYPE_VEC | 24}, \
|
||||
{"$v25", RTYPE_VEC | 25}, \
|
||||
{"$v26", RTYPE_VEC | 26}, \
|
||||
{"$v27", RTYPE_VEC | 27}, \
|
||||
{"$v28", RTYPE_VEC | 28}, \
|
||||
{"$v29", RTYPE_VEC | 29}, \
|
||||
{"$v30", RTYPE_VEC | 30}, \
|
||||
{"$v31", RTYPE_VEC | 31}
|
||||
|
||||
#define MIPS_DSP_ACCUMULATOR_NAMES \
|
||||
{"$ac0", RTYPE_ACC | 0}, \
|
||||
{"$ac1", RTYPE_ACC | 1}, \
|
||||
{"$ac2", RTYPE_ACC | 2}, \
|
||||
{"$ac3", RTYPE_ACC | 3}
|
||||
|
||||
static const struct regname reg_names[] = {
|
||||
GENERIC_REGISTER_NUMBERS,
|
||||
FPU_REGISTER_NAMES,
|
||||
FPU_CONDITION_CODE_NAMES,
|
||||
COPROC_CONDITION_CODE_NAMES,
|
||||
|
||||
/* The $txx registers depends on the abi,
|
||||
these will be added later into the symbol table from
|
||||
one of the tables below once mips_abi is set after
|
||||
parsing of arguments from the command line. */
|
||||
SYMBOLIC_REGISTER_NAMES,
|
||||
|
||||
MIPS16_SPECIAL_REGISTER_NAMES,
|
||||
MDMX_VECTOR_REGISTER_NAMES,
|
||||
MIPS_DSP_ACCUMULATOR_NAMES,
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static const struct regname reg_names_o32[] = {
|
||||
O32_SYMBOLIC_REGISTER_NAMES,
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static const struct regname reg_names_n32n64[] = {
|
||||
N32N64_SYMBOLIC_REGISTER_NAMES,
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static int
|
||||
reg_lookup (char **s, unsigned int types, unsigned int *regnop)
|
||||
{
|
||||
symbolS *symbolP;
|
||||
char *e;
|
||||
char save_c;
|
||||
int reg = -1;
|
||||
|
||||
/* Find end of name. */
|
||||
e = *s;
|
||||
if (is_name_beginner (*e))
|
||||
++e;
|
||||
while (is_part_of_name (*e))
|
||||
++e;
|
||||
|
||||
/* Terminate name. */
|
||||
save_c = *e;
|
||||
*e = '\0';
|
||||
|
||||
/* Look for a register symbol. */
|
||||
if ((symbolP = symbol_find (*s)) && S_GET_SEGMENT (symbolP) == reg_section)
|
||||
{
|
||||
int r = S_GET_VALUE (symbolP);
|
||||
if (r & types)
|
||||
reg = r & RNUM_MASK;
|
||||
else if ((types & RTYPE_VEC) && (r & ~1) == (RTYPE_GP | 2))
|
||||
/* Convert GP reg $v0/1 to MDMX reg $v0/1! */
|
||||
reg = (r & RNUM_MASK) - 2;
|
||||
}
|
||||
/* Else see if this is a register defined in an itbl entry. */
|
||||
else if ((types & RTYPE_GP) && itbl_have_entries)
|
||||
{
|
||||
char *n = *s;
|
||||
unsigned long r;
|
||||
|
||||
if (*n == '$')
|
||||
++n;
|
||||
if (itbl_get_reg_val (n, &r))
|
||||
reg = r & RNUM_MASK;
|
||||
}
|
||||
|
||||
/* Advance to next token if a register was recognised. */
|
||||
if (reg >= 0)
|
||||
*s = e;
|
||||
else if (types & RWARN)
|
||||
as_warn ("Unrecognized register name `%s'", *s);
|
||||
|
||||
*e = save_c;
|
||||
if (regnop)
|
||||
*regnop = reg;
|
||||
return reg >= 0;
|
||||
}
|
||||
|
||||
/* This function is called once, at assembler startup time. It should set up
|
||||
all the tables, etc. that the MD part of the assembler will need. */
|
||||
|
||||
void
|
||||
md_begin (void)
|
||||
@ -1490,46 +1777,20 @@ md_begin (void)
|
||||
|
||||
/* We add all the general register names to the symbol table. This
|
||||
helps us detect invalid uses of them. */
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
char buf[5];
|
||||
|
||||
sprintf (buf, "$%d", i);
|
||||
symbol_table_insert (symbol_new (buf, reg_section, i,
|
||||
for (i = 0; reg_names[i].name; i++)
|
||||
symbol_table_insert (symbol_new (reg_names[i].name, reg_section,
|
||||
reg_names[i].num, // & RNUM_MASK,
|
||||
&zero_address_frag));
|
||||
if (HAVE_NEWABI)
|
||||
for (i = 0; reg_names_n32n64[i].name; i++)
|
||||
symbol_table_insert (symbol_new (reg_names_n32n64[i].name, reg_section,
|
||||
reg_names_n32n64[i].num, // & RNUM_MASK,
|
||||
&zero_address_frag));
|
||||
}
|
||||
symbol_table_insert (symbol_new ("$ra", reg_section, RA,
|
||||
&zero_address_frag));
|
||||
symbol_table_insert (symbol_new ("$fp", reg_section, FP,
|
||||
&zero_address_frag));
|
||||
symbol_table_insert (symbol_new ("$sp", reg_section, SP,
|
||||
&zero_address_frag));
|
||||
symbol_table_insert (symbol_new ("$gp", reg_section, GP,
|
||||
&zero_address_frag));
|
||||
symbol_table_insert (symbol_new ("$at", reg_section, AT,
|
||||
&zero_address_frag));
|
||||
symbol_table_insert (symbol_new ("$kt0", reg_section, KT0,
|
||||
&zero_address_frag));
|
||||
symbol_table_insert (symbol_new ("$kt1", reg_section, KT1,
|
||||
&zero_address_frag));
|
||||
symbol_table_insert (symbol_new ("$zero", reg_section, ZERO,
|
||||
&zero_address_frag));
|
||||
symbol_table_insert (symbol_new ("$pc", reg_section, -1,
|
||||
&zero_address_frag));
|
||||
|
||||
/* If we don't add these register names to the symbol table, they
|
||||
may end up being added as regular symbols by operand(), and then
|
||||
make it to the object file as undefined in case they're not
|
||||
regarded as local symbols. They're local in o32, since `$' is a
|
||||
local symbol prefix, but not in n32 or n64. */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
char buf[6];
|
||||
|
||||
sprintf (buf, "$fcc%i", i);
|
||||
symbol_table_insert (symbol_new (buf, reg_section, -1,
|
||||
else
|
||||
for (i = 0; reg_names_o32[i].name; i++)
|
||||
symbol_table_insert (symbol_new (reg_names_o32[i].name, reg_section,
|
||||
reg_names_o32[i].num, // & RNUM_MASK,
|
||||
&zero_address_frag));
|
||||
}
|
||||
|
||||
mips_no_prev_insn ();
|
||||
|
||||
@ -1544,6 +1805,7 @@ md_begin (void)
|
||||
|
||||
bfd_set_gp_size (stdoutput, g_switch_value);
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
|
||||
{
|
||||
/* On a native system other than VxWorks, sections must be aligned
|
||||
@ -1582,9 +1844,7 @@ md_begin (void)
|
||||
bfd_set_section_flags (stdoutput, sec, flags);
|
||||
bfd_set_section_alignment (stdoutput, sec, HAVE_NEWABI ? 3 : 2);
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
mips_regmask_frag = frag_more (sizeof (Elf32_External_RegInfo));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1594,7 +1854,6 @@ md_begin (void)
|
||||
bfd_set_section_flags (stdoutput, sec, flags);
|
||||
bfd_set_section_alignment (stdoutput, sec, 3);
|
||||
|
||||
#ifdef OBJ_ELF
|
||||
/* Set up the option header. */
|
||||
{
|
||||
Elf_Internal_Options opthdr;
|
||||
@ -1611,7 +1870,6 @@ md_begin (void)
|
||||
|
||||
mips_regmask_frag = frag_more (sizeof (Elf64_External_RegInfo));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ECOFF_DEBUGGING)
|
||||
@ -1621,7 +1879,6 @@ md_begin (void)
|
||||
SEC_HAS_CONTENTS | SEC_READONLY);
|
||||
(void) bfd_set_section_alignment (stdoutput, sec, 2);
|
||||
}
|
||||
#ifdef OBJ_ELF
|
||||
else if (OUTPUT_FLAVOR == bfd_target_elf_flavour && mips_flag_pdr)
|
||||
{
|
||||
pdr_seg = subseg_new (".pdr", (subsegT) 0);
|
||||
@ -1630,11 +1887,11 @@ md_begin (void)
|
||||
| SEC_DEBUGGING);
|
||||
(void) bfd_set_section_alignment (stdoutput, pdr_seg, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
subseg_set (seg, subseg);
|
||||
}
|
||||
}
|
||||
#endif /* OBJ_ELF */
|
||||
|
||||
if (! ECOFF_DEBUGGING)
|
||||
md_obj_begin ();
|
||||
@ -7972,6 +8229,8 @@ mips_ip (char *str, struct mips_cl_insn *ip)
|
||||
char *s_reset;
|
||||
char save_c = 0;
|
||||
offsetT min_range, max_range;
|
||||
int argnum;
|
||||
unsigned int rtype;
|
||||
|
||||
insn_error = NULL;
|
||||
|
||||
@ -8079,6 +8338,7 @@ mips_ip (char *str, struct mips_cl_insn *ip)
|
||||
|
||||
create_insn (ip, insn);
|
||||
insn_error = NULL;
|
||||
argnum = 1;
|
||||
for (args = insn->args;; ++args)
|
||||
{
|
||||
int is_mdmx;
|
||||
@ -8495,11 +8755,11 @@ do_msbd:
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case 'T': /* Coprocessor register */
|
||||
case 'T': /* Coprocessor register. */
|
||||
/* +T is for disassembly only; never match. */
|
||||
break;
|
||||
|
||||
case 't': /* Coprocessor register number */
|
||||
case 't': /* Coprocessor register number. */
|
||||
if (s[0] == '$' && ISDIGIT (s[1]))
|
||||
{
|
||||
++s;
|
||||
@ -8633,7 +8893,7 @@ do_msbd:
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case 'P': /* Performance register */
|
||||
case 'P': /* Performance register. */
|
||||
my_getExpression (&imm_expr, s);
|
||||
check_absolute_expr (ip, &imm_expr);
|
||||
if (imm_expr.X_add_number != 0 && imm_expr.X_add_number != 1)
|
||||
@ -8644,6 +8904,20 @@ do_msbd:
|
||||
s = expr_end;
|
||||
continue;
|
||||
|
||||
case 'G': /* Coprocessor destination register. */
|
||||
if (((ip->insn_opcode >> OP_SH_OP) & OP_MASK_OP) == OP_OP_COP0)
|
||||
ok = reg_lookup (&s, RTYPE_NUM | RTYPE_CP0, ®no);
|
||||
else
|
||||
ok = reg_lookup (&s, RTYPE_NUM | RTYPE_GP, ®no);
|
||||
ip->insn_opcode |= regno << OP_SH_RD;
|
||||
if (ok)
|
||||
{
|
||||
lastregno = regno;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
case 'b': /* base register */
|
||||
case 'd': /* destination register */
|
||||
case 's': /* source register */
|
||||
@ -8652,106 +8926,22 @@ do_msbd:
|
||||
case 'v': /* both dest and source */
|
||||
case 'w': /* both dest and target */
|
||||
case 'E': /* coprocessor target register */
|
||||
case 'G': /* coprocessor destination register */
|
||||
case 'K': /* 'rdhwr' destination register */
|
||||
case 'x': /* ignore register name */
|
||||
case 'z': /* must be zero register */
|
||||
case 'U': /* destination register (clo/clz). */
|
||||
case 'g': /* coprocessor destination register */
|
||||
s_reset = s;
|
||||
if (s[0] == '$')
|
||||
s_reset = s;
|
||||
if (*args == 'E' || *args == 'K')
|
||||
ok = reg_lookup (&s, RTYPE_NUM, ®no);
|
||||
else
|
||||
{
|
||||
ok = reg_lookup (&s, RTYPE_NUM | RTYPE_GP, ®no);
|
||||
if (regno == AT && ! mips_opts.noat)
|
||||
as_warn ("Used $at without \".set noat\"");
|
||||
}
|
||||
if (ok)
|
||||
{
|
||||
if (ISDIGIT (s[1]))
|
||||
{
|
||||
++s;
|
||||
regno = 0;
|
||||
do
|
||||
{
|
||||
regno *= 10;
|
||||
regno += *s - '0';
|
||||
++s;
|
||||
}
|
||||
while (ISDIGIT (*s));
|
||||
if (regno > 31)
|
||||
as_bad (_("Invalid register number (%d)"), regno);
|
||||
}
|
||||
else if (*args == 'E' || *args == 'G' || *args == 'K')
|
||||
goto notreg;
|
||||
else
|
||||
{
|
||||
if (s[1] == 'r' && s[2] == 'a')
|
||||
{
|
||||
s += 3;
|
||||
regno = RA;
|
||||
}
|
||||
else if (s[1] == 'f' && s[2] == 'p')
|
||||
{
|
||||
s += 3;
|
||||
regno = FP;
|
||||
}
|
||||
else if (s[1] == 's' && s[2] == 'p')
|
||||
{
|
||||
s += 3;
|
||||
regno = SP;
|
||||
}
|
||||
else if (s[1] == 'g' && s[2] == 'p')
|
||||
{
|
||||
s += 3;
|
||||
regno = GP;
|
||||
}
|
||||
else if (s[1] == 'a' && s[2] == 't')
|
||||
{
|
||||
s += 3;
|
||||
regno = AT;
|
||||
}
|
||||
else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')
|
||||
{
|
||||
s += 4;
|
||||
regno = KT0;
|
||||
}
|
||||
else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')
|
||||
{
|
||||
s += 4;
|
||||
regno = KT1;
|
||||
}
|
||||
else if (s[1] == 'z' && s[2] == 'e' && s[3] == 'r' && s[4] == 'o')
|
||||
{
|
||||
s += 5;
|
||||
regno = ZERO;
|
||||
}
|
||||
else if (itbl_have_entries)
|
||||
{
|
||||
char *p, *n;
|
||||
unsigned long r;
|
||||
|
||||
p = s + 1; /* advance past '$' */
|
||||
n = itbl_get_field (&p); /* n is name */
|
||||
|
||||
/* See if this is a register defined in an
|
||||
itbl entry. */
|
||||
if (itbl_get_reg_val (n, &r))
|
||||
{
|
||||
/* Get_field advances to the start of
|
||||
the next field, so we need to back
|
||||
rack to the end of the last field. */
|
||||
if (p)
|
||||
s = p - 1;
|
||||
else
|
||||
s = strchr (s, '\0');
|
||||
regno = r;
|
||||
}
|
||||
else
|
||||
goto notreg;
|
||||
}
|
||||
else
|
||||
goto notreg;
|
||||
}
|
||||
if (regno == AT
|
||||
&& ! mips_opts.noat
|
||||
&& *args != 'E'
|
||||
&& *args != 'G'
|
||||
&& *args != 'K')
|
||||
as_warn (_("Used $at without \".set noat\""));
|
||||
c = *args;
|
||||
if (*s == ' ')
|
||||
++s;
|
||||
@ -8817,7 +9007,6 @@ do_msbd:
|
||||
lastregno = regno;
|
||||
continue;
|
||||
}
|
||||
notreg:
|
||||
switch (*args++)
|
||||
{
|
||||
case 'r':
|
||||
@ -8870,26 +9059,19 @@ do_msbd:
|
||||
case 'R': /* floating point source register */
|
||||
case 'V':
|
||||
case 'W':
|
||||
rtype = RTYPE_FPU;
|
||||
if (is_mdmx
|
||||
|| (mips_opts.ase_mdmx
|
||||
&& (ip->insn_mo->pinfo & FP_D)
|
||||
&& (ip->insn_mo->pinfo & (INSN_COPROC_MOVE_DELAY
|
||||
| INSN_COPROC_MEMORY_DELAY
|
||||
| INSN_LOAD_COPROC_DELAY
|
||||
| INSN_LOAD_MEMORY_DELAY
|
||||
| INSN_STORE_MEMORY))))
|
||||
rtype |= RTYPE_VEC;
|
||||
s_reset = s;
|
||||
/* Accept $fN for FP and MDMX register numbers, and in
|
||||
addition accept $vN for MDMX register numbers. */
|
||||
if ((s[0] == '$' && s[1] == 'f' && ISDIGIT (s[2]))
|
||||
|| (is_mdmx != 0 && s[0] == '$' && s[1] == 'v'
|
||||
&& ISDIGIT (s[2])))
|
||||
if (reg_lookup (&s, rtype, ®no))
|
||||
{
|
||||
s += 2;
|
||||
regno = 0;
|
||||
do
|
||||
{
|
||||
regno *= 10;
|
||||
regno += *s - '0';
|
||||
++s;
|
||||
}
|
||||
while (ISDIGIT (*s));
|
||||
|
||||
if (regno > 31)
|
||||
as_bad (_("Invalid float register number (%d)"), regno);
|
||||
|
||||
if ((regno & 1) != 0
|
||||
&& HAVE_32BIT_FPRS
|
||||
&& ! (strcmp (str, "mtc1") == 0
|
||||
@ -9291,19 +9473,11 @@ do_msbd:
|
||||
|
||||
case 'N': /* 3 bit branch condition code */
|
||||
case 'M': /* 3 bit compare condition code */
|
||||
if (strncmp (s, "$fcc", 4) != 0)
|
||||
rtype = RTYPE_CCC;
|
||||
if (ip->insn_mo->pinfo & (FP_D| FP_S))
|
||||
rtype |= RTYPE_FCC;
|
||||
if (!reg_lookup (&s, rtype, ®no))
|
||||
break;
|
||||
s += 4;
|
||||
regno = 0;
|
||||
do
|
||||
{
|
||||
regno *= 10;
|
||||
regno += *s - '0';
|
||||
++s;
|
||||
}
|
||||
while (ISDIGIT (*s));
|
||||
if (regno > 7)
|
||||
as_bad (_("Invalid condition code register $fcc%d"), regno);
|
||||
if ((strcmp(str + strlen(str) - 3, ".ps") == 0
|
||||
|| strcmp(str + strlen(str) - 5, "any2f") == 0
|
||||
|| strcmp(str + strlen(str) - 5, "any2t") == 0)
|
||||
@ -9614,70 +9788,19 @@ mips16_ip (char *str, struct mips_cl_insn *ip)
|
||||
case 'R':
|
||||
case 'X':
|
||||
case 'Y':
|
||||
if (s[0] != '$')
|
||||
break;
|
||||
s_reset = s;
|
||||
if (ISDIGIT (s[1]))
|
||||
s_reset = s;
|
||||
if (!reg_lookup (&s, RTYPE_NUM | RTYPE_GP, ®no))
|
||||
{
|
||||
++s;
|
||||
regno = 0;
|
||||
do
|
||||
if (c == 'v' || c == 'w')
|
||||
{
|
||||
regno *= 10;
|
||||
regno += *s - '0';
|
||||
++s;
|
||||
if (c == 'v')
|
||||
ip->insn_opcode |= lastregno << MIPS16OP_SH_RX;
|
||||
else
|
||||
ip->insn_opcode |= lastregno << MIPS16OP_SH_RY;
|
||||
++args;
|
||||
continue;
|
||||
}
|
||||
while (ISDIGIT (*s));
|
||||
if (regno > 31)
|
||||
{
|
||||
as_bad (_("invalid register number (%d)"), regno);
|
||||
regno = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s[1] == 'r' && s[2] == 'a')
|
||||
{
|
||||
s += 3;
|
||||
regno = RA;
|
||||
}
|
||||
else if (s[1] == 'f' && s[2] == 'p')
|
||||
{
|
||||
s += 3;
|
||||
regno = FP;
|
||||
}
|
||||
else if (s[1] == 's' && s[2] == 'p')
|
||||
{
|
||||
s += 3;
|
||||
regno = SP;
|
||||
}
|
||||
else if (s[1] == 'g' && s[2] == 'p')
|
||||
{
|
||||
s += 3;
|
||||
regno = GP;
|
||||
}
|
||||
else if (s[1] == 'a' && s[2] == 't')
|
||||
{
|
||||
s += 3;
|
||||
regno = AT;
|
||||
}
|
||||
else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')
|
||||
{
|
||||
s += 4;
|
||||
regno = KT0;
|
||||
}
|
||||
else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')
|
||||
{
|
||||
s += 4;
|
||||
regno = KT1;
|
||||
}
|
||||
else if (s[1] == 'z' && s[2] == 'e' && s[3] == 'r' && s[4] == 'o')
|
||||
{
|
||||
s += 5;
|
||||
regno = ZERO;
|
||||
}
|
||||
else
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*s == ' ')
|
||||
@ -9883,30 +10006,19 @@ mips16_ip (char *str, struct mips_cl_insn *ip)
|
||||
mask = 7 << 3;
|
||||
while (*s != '\0')
|
||||
{
|
||||
int freg, reg1, reg2;
|
||||
unsigned int freg, reg1, reg2;
|
||||
|
||||
while (*s == ' ' || *s == ',')
|
||||
++s;
|
||||
if (*s != '$')
|
||||
if (reg_lookup (&s, RTYPE_GP | RTYPE_NUM, ®1))
|
||||
freg = 0;
|
||||
else if (reg_lookup (&s, RTYPE_FPU, ®1))
|
||||
freg = 1;
|
||||
else
|
||||
{
|
||||
as_bad (_("can't parse register list"));
|
||||
break;
|
||||
}
|
||||
++s;
|
||||
if (*s != 'f')
|
||||
freg = 0;
|
||||
else
|
||||
{
|
||||
freg = 1;
|
||||
++s;
|
||||
}
|
||||
reg1 = 0;
|
||||
while (ISDIGIT (*s))
|
||||
{
|
||||
reg1 *= 10;
|
||||
reg1 += *s - '0';
|
||||
++s;
|
||||
}
|
||||
if (*s == ' ')
|
||||
++s;
|
||||
if (*s != '-')
|
||||
@ -9914,25 +10026,11 @@ mips16_ip (char *str, struct mips_cl_insn *ip)
|
||||
else
|
||||
{
|
||||
++s;
|
||||
if (*s != '$')
|
||||
break;
|
||||
++s;
|
||||
if (freg)
|
||||
if (!reg_lookup (&s, freg ? RTYPE_FPU
|
||||
: (RTYPE_GP | RTYPE_NUM), ®2))
|
||||
{
|
||||
if (*s == 'f')
|
||||
++s;
|
||||
else
|
||||
{
|
||||
as_bad (_("invalid register list"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
reg2 = 0;
|
||||
while (ISDIGIT (*s))
|
||||
{
|
||||
reg2 *= 10;
|
||||
reg2 += *s - '0';
|
||||
++s;
|
||||
as_bad (_("invalid register list"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (freg && reg1 == 0 && reg2 == 0 && c == 'L')
|
||||
@ -9997,39 +10095,26 @@ mips16_ip (char *str, struct mips_cl_insn *ip)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*s != '$')
|
||||
if (! reg_lookup (&s, RTYPE_GP | RTYPE_NUM, ®1))
|
||||
{
|
||||
as_bad (_("can't parse register list"));
|
||||
break;
|
||||
}
|
||||
++s;
|
||||
|
||||
reg1 = 0;
|
||||
while (ISDIGIT (*s))
|
||||
{
|
||||
reg1 *= 10;
|
||||
reg1 += *s - '0';
|
||||
++s;
|
||||
}
|
||||
SKIP_SPACE_TABS (s);
|
||||
while (*s == ' ')
|
||||
++s;
|
||||
|
||||
if (*s != '-')
|
||||
reg2 = reg1;
|
||||
else
|
||||
{
|
||||
++s;
|
||||
if (*s != '$')
|
||||
if (! reg_lookup (&s, RTYPE_GP | RTYPE_NUM, ®2)
|
||||
|| reg2 < reg1)
|
||||
{
|
||||
as_bad (_("can't parse register list"));
|
||||
break;
|
||||
}
|
||||
++s;
|
||||
reg2 = 0;
|
||||
while (ISDIGIT (*s))
|
||||
{
|
||||
reg2 *= 10;
|
||||
reg2 += *s - '0';
|
||||
++s;
|
||||
}
|
||||
}
|
||||
|
||||
while (reg1 <= reg2)
|
||||
@ -12786,73 +12871,11 @@ s_mips_weakext (int ignore ATTRIBUTE_UNUSED)
|
||||
int
|
||||
tc_get_register (int frame)
|
||||
{
|
||||
int reg;
|
||||
unsigned int reg;
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
if (*input_line_pointer++ != '$')
|
||||
{
|
||||
as_warn (_("expected `$'"));
|
||||
reg = ZERO;
|
||||
}
|
||||
else if (ISDIGIT (*input_line_pointer))
|
||||
{
|
||||
reg = get_absolute_expression ();
|
||||
if (reg < 0 || reg >= 32)
|
||||
{
|
||||
as_warn (_("Bad register number"));
|
||||
reg = ZERO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strncmp (input_line_pointer, "ra", 2) == 0)
|
||||
{
|
||||
reg = RA;
|
||||
input_line_pointer += 2;
|
||||
}
|
||||
else if (strncmp (input_line_pointer, "fp", 2) == 0)
|
||||
{
|
||||
reg = FP;
|
||||
input_line_pointer += 2;
|
||||
}
|
||||
else if (strncmp (input_line_pointer, "sp", 2) == 0)
|
||||
{
|
||||
reg = SP;
|
||||
input_line_pointer += 2;
|
||||
}
|
||||
else if (strncmp (input_line_pointer, "gp", 2) == 0)
|
||||
{
|
||||
reg = GP;
|
||||
input_line_pointer += 2;
|
||||
}
|
||||
else if (strncmp (input_line_pointer, "at", 2) == 0)
|
||||
{
|
||||
reg = AT;
|
||||
input_line_pointer += 2;
|
||||
}
|
||||
else if (strncmp (input_line_pointer, "kt0", 3) == 0)
|
||||
{
|
||||
reg = KT0;
|
||||
input_line_pointer += 3;
|
||||
}
|
||||
else if (strncmp (input_line_pointer, "kt1", 3) == 0)
|
||||
{
|
||||
reg = KT1;
|
||||
input_line_pointer += 3;
|
||||
}
|
||||
else if (strncmp (input_line_pointer, "zero", 4) == 0)
|
||||
{
|
||||
reg = ZERO;
|
||||
input_line_pointer += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
as_warn (_("Unrecognized register name"));
|
||||
reg = ZERO;
|
||||
while (ISALNUM(*input_line_pointer))
|
||||
input_line_pointer++;
|
||||
}
|
||||
}
|
||||
if (! reg_lookup (&input_line_pointer, RWARN | RTYPE_NUM | RTYPE_GP, ®))
|
||||
reg = 0;
|
||||
if (frame)
|
||||
{
|
||||
mips_frame_reg = reg != 0 ? reg : SP;
|
||||
@ -14708,3 +14731,14 @@ mips_cfi_frame_initial_instructions (void)
|
||||
cfi_add_CFA_def_cfa_register (SP);
|
||||
}
|
||||
|
||||
int
|
||||
tc_mips_regname_to_dw2regnum (char *regname)
|
||||
{
|
||||
unsigned int regnum = -1;
|
||||
unsigned int reg;
|
||||
|
||||
if (reg_lookup (®name, RTYPE_GP | RTYPE_NUM, ®))
|
||||
regnum = reg;
|
||||
|
||||
return regnum;
|
||||
}
|
||||
|
@ -160,6 +160,9 @@ extern int mips_dwarf2_addr_size (void);
|
||||
#define tc_cfi_frame_initial_instructions mips_cfi_frame_initial_instructions
|
||||
extern void mips_cfi_frame_initial_instructions (void);
|
||||
|
||||
#define tc_regname_to_dw2regnum tc_mips_regname_to_dw2regnum
|
||||
extern int tc_mips_regname_to_dw2regnum (char *regname);
|
||||
|
||||
#define DWARF2_DEFAULT_RETURN_COLUMN 31
|
||||
#define DWARF2_CIE_DATA_ALIGNMENT -4
|
||||
|
||||
|
Reference in New Issue
Block a user