mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-01 13:26:47 +08:00
2013-10-14 Richard Sandiford <rdsandiford@googlemail.com>
Chao-ying Fu <Chao-ying.Fu@imgtec.com> * config/tc-mips.c (options): Add OPTION_MSA and OPTION_NO_MSA. (md_longopts): Add mmsa and mno-msa. (mips_ases): Add msa. (RTYPE_MASK): Update. (RTYPE_MSA): New define. (OT_REG_ELEMENT): Replace with... (OT_INTEGER_INDEX, OT_REG_INDEX): ...these new operand types. (mips_operand_token): Replace reg_element with index. (mips_parse_argument_token): Treat vector indices as separate tokens. Handle register indices. (md_begin): Add MSA register names. (operand_reg_mask): Handle cases for OP_IMM_INDEX and OP_REG_INDEX. (convert_reg_type): Handle cases for OP_REG_MSA and OP_REG_MSA_CTRL. (match_mdmx_imm_reg_operand): Update accordingly. (match_imm_index_operand): New function. (match_reg_index_operand): New function. (match_operand): Handle cases for OP_IMM_INDEX and OP_REG_INDEX. (md_convert_frag): Convert bz.b/h/w/d, bnz.b/h/w/d, bz.v bnz.v. (md_show_usage): Print -mmsa and -mno-msa. * doc/as.texinfo: Document -mmsa and -mno-msa. * doc/c-mips.texi: Document -mmsa and -mno-msa. Document .set msa and .set nomsa.
This commit is contained in:
parent
a9f581680f
commit
56d438b172
@ -1,3 +1,29 @@
|
||||
2013-10-14 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
Chao-ying Fu <Chao-ying.Fu@imgtec.com>
|
||||
|
||||
* config/tc-mips.c (options): Add OPTION_MSA and OPTION_NO_MSA.
|
||||
(md_longopts): Add mmsa and mno-msa.
|
||||
(mips_ases): Add msa.
|
||||
(RTYPE_MASK): Update.
|
||||
(RTYPE_MSA): New define.
|
||||
(OT_REG_ELEMENT): Replace with...
|
||||
(OT_INTEGER_INDEX, OT_REG_INDEX): ...these new operand types.
|
||||
(mips_operand_token): Replace reg_element with index.
|
||||
(mips_parse_argument_token): Treat vector indices as separate tokens.
|
||||
Handle register indices.
|
||||
(md_begin): Add MSA register names.
|
||||
(operand_reg_mask): Handle cases for OP_IMM_INDEX and OP_REG_INDEX.
|
||||
(convert_reg_type): Handle cases for OP_REG_MSA and OP_REG_MSA_CTRL.
|
||||
(match_mdmx_imm_reg_operand): Update accordingly.
|
||||
(match_imm_index_operand): New function.
|
||||
(match_reg_index_operand): New function.
|
||||
(match_operand): Handle cases for OP_IMM_INDEX and OP_REG_INDEX.
|
||||
(md_convert_frag): Convert bz.b/h/w/d, bnz.b/h/w/d, bz.v bnz.v.
|
||||
(md_show_usage): Print -mmsa and -mno-msa.
|
||||
* doc/as.texinfo: Document -mmsa and -mno-msa.
|
||||
* doc/c-mips.texi: Document -mmsa and -mno-msa.
|
||||
Document .set msa and .set nomsa.
|
||||
|
||||
2013-10-14 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* read.c (add_include_dir): Use xrealloc.
|
||||
|
@ -1329,6 +1329,8 @@ enum options
|
||||
OPTION_NO_MT,
|
||||
OPTION_VIRT,
|
||||
OPTION_NO_VIRT,
|
||||
OPTION_MSA,
|
||||
OPTION_NO_MSA,
|
||||
OPTION_SMARTMIPS,
|
||||
OPTION_NO_SMARTMIPS,
|
||||
OPTION_DSPR2,
|
||||
@ -1440,6 +1442,8 @@ struct option md_longopts[] =
|
||||
{"mno-mcu", no_argument, NULL, OPTION_NO_MCU},
|
||||
{"mvirt", no_argument, NULL, OPTION_VIRT},
|
||||
{"mno-virt", no_argument, NULL, OPTION_NO_VIRT},
|
||||
{"mmsa", no_argument, NULL, OPTION_MSA},
|
||||
{"mno-msa", no_argument, NULL, OPTION_NO_MSA},
|
||||
|
||||
/* Old-style architecture options. Don't add more of these. */
|
||||
{"m4650", no_argument, NULL, OPTION_M4650},
|
||||
@ -1586,6 +1590,10 @@ static const struct mips_ase mips_ases[] = {
|
||||
|
||||
{ "virt", ASE_VIRT, ASE_VIRT64,
|
||||
OPTION_VIRT, OPTION_NO_VIRT,
|
||||
2, 2, 2, 2 },
|
||||
|
||||
{ "msa", ASE_MSA, ASE_MSA64,
|
||||
OPTION_MSA, OPTION_NO_MSA,
|
||||
2, 2, 2, 2 }
|
||||
};
|
||||
|
||||
@ -2347,7 +2355,7 @@ struct regname {
|
||||
};
|
||||
|
||||
#define RNUM_MASK 0x00000ff
|
||||
#define RTYPE_MASK 0x0efff00
|
||||
#define RTYPE_MASK 0x0ffff00
|
||||
#define RTYPE_NUM 0x0000100
|
||||
#define RTYPE_FPU 0x0000200
|
||||
#define RTYPE_FCC 0x0000400
|
||||
@ -2363,6 +2371,7 @@ struct regname {
|
||||
#define RTYPE_R5900_Q 0x0100000
|
||||
#define RTYPE_R5900_R 0x0200000
|
||||
#define RTYPE_R5900_ACC 0x0400000
|
||||
#define RTYPE_MSA 0x0800000
|
||||
#define RWARN 0x8000000
|
||||
|
||||
#define GENERIC_REGISTER_NUMBERS \
|
||||
@ -2747,8 +2756,11 @@ enum mips_operand_token_type {
|
||||
/* A 4-bit XYZW channel mask. */
|
||||
OT_CHANNELS,
|
||||
|
||||
/* An element of a vector, e.g. $v0[1]. */
|
||||
OT_REG_ELEMENT,
|
||||
/* A constant vector index, e.g. [1]. */
|
||||
OT_INTEGER_INDEX,
|
||||
|
||||
/* A register vector index, e.g. [$2]. */
|
||||
OT_REG_INDEX,
|
||||
|
||||
/* A continuous range of registers, e.g. $s0-$s4. */
|
||||
OT_REG_RANGE,
|
||||
@ -2777,17 +2789,14 @@ struct mips_operand_token
|
||||
enum mips_operand_token_type type;
|
||||
union
|
||||
{
|
||||
/* The register symbol value for an OT_REG. */
|
||||
/* The register symbol value for an OT_REG or OT_REG_INDEX. */
|
||||
unsigned int regno;
|
||||
|
||||
/* The 4-bit channel mask for an OT_CHANNEL_SUFFIX. */
|
||||
unsigned int channels;
|
||||
|
||||
/* The register symbol value and index for an OT_REG_ELEMENT. */
|
||||
struct {
|
||||
unsigned int regno;
|
||||
addressT index;
|
||||
} reg_element;
|
||||
/* The integer value of an OT_INTEGER_INDEX. */
|
||||
addressT index;
|
||||
|
||||
/* The two register symbol values involved in an OT_REG_RANGE. */
|
||||
struct {
|
||||
@ -2948,20 +2957,32 @@ mips_parse_argument_token (char *s, char float_format)
|
||||
mips_add_token (&token, OT_REG_RANGE);
|
||||
return s;
|
||||
}
|
||||
else if (*s == '[')
|
||||
{
|
||||
/* A vector element. */
|
||||
expressionS element;
|
||||
|
||||
/* Add the register itself. */
|
||||
token.u.regno = regno1;
|
||||
mips_add_token (&token, OT_REG);
|
||||
|
||||
/* Check for a vector index. */
|
||||
if (*s == '[')
|
||||
{
|
||||
++s;
|
||||
SKIP_SPACE_TABS (s);
|
||||
my_getExpression (&element, s);
|
||||
if (element.X_op != O_constant)
|
||||
if (mips_parse_register (&s, &token.u.regno, NULL))
|
||||
mips_add_token (&token, OT_REG_INDEX);
|
||||
else
|
||||
{
|
||||
set_insn_error (0, _("vector element must be constant"));
|
||||
return 0;
|
||||
expressionS element;
|
||||
|
||||
my_getExpression (&element, s);
|
||||
if (element.X_op != O_constant)
|
||||
{
|
||||
set_insn_error (0, _("vector element must be constant"));
|
||||
return 0;
|
||||
}
|
||||
s = expr_end;
|
||||
token.u.index = element.X_add_number;
|
||||
mips_add_token (&token, OT_INTEGER_INDEX);
|
||||
}
|
||||
s = expr_end;
|
||||
SKIP_SPACE_TABS (s);
|
||||
if (*s != ']')
|
||||
{
|
||||
@ -2969,16 +2990,7 @@ mips_parse_argument_token (char *s, char float_format)
|
||||
return 0;
|
||||
}
|
||||
++s;
|
||||
|
||||
token.u.reg_element.regno = regno1;
|
||||
token.u.reg_element.index = element.X_add_number;
|
||||
mips_add_token (&token, OT_REG_ELEMENT);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Looks like just a plain register. */
|
||||
token.u.regno = regno1;
|
||||
mips_add_token (&token, OT_REG);
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -3460,6 +3472,10 @@ md_begin (void)
|
||||
symbol_table_insert (symbol_new (regname, reg_section,
|
||||
RTYPE_VI | i, &zero_address_frag));
|
||||
|
||||
/* MSA register. */
|
||||
snprintf (regname, sizeof (regname) - 1, "$w%d", i);
|
||||
symbol_table_insert (symbol_new (regname, reg_section,
|
||||
RTYPE_MSA | i, &zero_address_frag));
|
||||
}
|
||||
|
||||
obstack_init (&mips_operand_tokens);
|
||||
@ -4005,6 +4021,7 @@ operand_reg_mask (const struct mips_cl_insn *insn,
|
||||
case OP_PC:
|
||||
case OP_VU0_SUFFIX:
|
||||
case OP_VU0_MATCH_SUFFIX:
|
||||
case OP_IMM_INDEX:
|
||||
abort ();
|
||||
|
||||
case OP_REG:
|
||||
@ -4050,6 +4067,11 @@ operand_reg_mask (const struct mips_cl_insn *insn,
|
||||
if ((vsel & 0x18) == 0x18)
|
||||
return 0;
|
||||
return 1 << (uval & 31);
|
||||
|
||||
case OP_REG_INDEX:
|
||||
if (!(type_mask & (1 << OP_REG_GP)))
|
||||
return 0;
|
||||
return 1 << insn_extract_operand (insn, operand);
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
@ -4408,6 +4430,12 @@ convert_reg_type (const struct mips_opcode *opcode,
|
||||
|
||||
case OP_REG_R5900_ACC:
|
||||
return RTYPE_R5900_ACC;
|
||||
|
||||
case OP_REG_MSA:
|
||||
return RTYPE_MSA;
|
||||
|
||||
case OP_REG_MSA_CTRL:
|
||||
return RTYPE_NUM;
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
@ -5078,7 +5106,7 @@ match_mdmx_imm_reg_operand (struct mips_arg_info *arg,
|
||||
uval = mips_extract_operand (operand, opcode->match);
|
||||
is_qh = (uval != 0);
|
||||
|
||||
if (arg->token->type == OT_REG || arg->token->type == OT_REG_ELEMENT)
|
||||
if (arg->token->type == OT_REG)
|
||||
{
|
||||
if ((opcode->membership & INSN_5400)
|
||||
&& strcmp (opcode->name, "rzu.ob") == 0)
|
||||
@ -5088,20 +5116,21 @@ match_mdmx_imm_reg_operand (struct mips_arg_info *arg,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!match_regno (arg, OP_REG_VEC, arg->token->u.regno, ®no))
|
||||
return FALSE;
|
||||
++arg->token;
|
||||
|
||||
/* Check whether this is a vector register or a broadcast of
|
||||
a single element. */
|
||||
if (arg->token->type == OT_REG_ELEMENT)
|
||||
if (arg->token->type == OT_INTEGER_INDEX)
|
||||
{
|
||||
if (!match_regno (arg, OP_REG_VEC, arg->token->u.reg_element.regno,
|
||||
®no))
|
||||
return FALSE;
|
||||
if (arg->token->u.reg_element.index > (is_qh ? 3 : 7))
|
||||
if (arg->token->u.index > (is_qh ? 3 : 7))
|
||||
{
|
||||
set_insn_error (arg->argnum, _("invalid element selector"));
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
uval |= arg->token->u.reg_element.index << (is_qh ? 2 : 1) << 5;
|
||||
uval |= arg->token->u.index << (is_qh ? 2 : 1) << 5;
|
||||
++arg->token;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5115,15 +5144,12 @@ match_mdmx_imm_reg_operand (struct mips_arg_info *arg,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!match_regno (arg, OP_REG_VEC, arg->token->u.regno, ®no))
|
||||
return FALSE;
|
||||
if (is_qh)
|
||||
uval |= MDMX_FMTSEL_VEC_QH << 5;
|
||||
else
|
||||
uval |= MDMX_FMTSEL_VEC_OB << 5;
|
||||
}
|
||||
uval |= regno;
|
||||
++arg->token;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5146,6 +5172,47 @@ match_mdmx_imm_reg_operand (struct mips_arg_info *arg,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OP_IMM_INDEX matcher. */
|
||||
|
||||
static bfd_boolean
|
||||
match_imm_index_operand (struct mips_arg_info *arg,
|
||||
const struct mips_operand *operand)
|
||||
{
|
||||
unsigned int max_val;
|
||||
|
||||
if (arg->token->type != OT_INTEGER_INDEX)
|
||||
return FALSE;
|
||||
|
||||
max_val = (1 << operand->size) - 1;
|
||||
if (arg->token->u.index > max_val)
|
||||
{
|
||||
match_out_of_range (arg);
|
||||
return FALSE;
|
||||
}
|
||||
insn_insert_operand (arg->insn, operand, arg->token->u.index);
|
||||
++arg->token;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OP_REG_INDEX matcher. */
|
||||
|
||||
static bfd_boolean
|
||||
match_reg_index_operand (struct mips_arg_info *arg,
|
||||
const struct mips_operand *operand)
|
||||
{
|
||||
unsigned int regno;
|
||||
|
||||
if (arg->token->type != OT_REG_INDEX)
|
||||
return FALSE;
|
||||
|
||||
if (!match_regno (arg, OP_REG_GP, arg->token->u.regno, ®no))
|
||||
return FALSE;
|
||||
|
||||
insn_insert_operand (arg->insn, operand, regno);
|
||||
++arg->token;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OP_PC matcher. */
|
||||
|
||||
static bfd_boolean
|
||||
@ -5426,6 +5493,12 @@ match_operand (struct mips_arg_info *arg,
|
||||
|
||||
case OP_VU0_MATCH_SUFFIX:
|
||||
return match_vu0_suffix_operand (arg, operand, TRUE);
|
||||
|
||||
case OP_IMM_INDEX:
|
||||
return match_imm_index_operand (arg, operand);
|
||||
|
||||
case OP_REG_INDEX:
|
||||
return match_reg_index_operand (arg, operand);
|
||||
}
|
||||
abort ();
|
||||
}
|
||||
@ -16539,11 +16612,21 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
|
||||
switch ((insn >> 28) & 0xf)
|
||||
{
|
||||
case 4:
|
||||
/* bc[0-3][tf]l? instructions can have the condition
|
||||
reversed by tweaking a single TF bit, and their
|
||||
opcodes all have 0x4???????. */
|
||||
gas_assert ((insn & 0xf3e00000) == 0x41000000);
|
||||
insn ^= 0x00010000;
|
||||
if ((insn & 0xff000000) == 0x47000000
|
||||
|| (insn & 0xff600000) == 0x45600000)
|
||||
{
|
||||
/* BZ.df/BNZ.df, BZ.V/BNZ.V can have the condition
|
||||
reversed by tweaking bit 23. */
|
||||
insn ^= 0x00800000;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bc[0-3][tf]l? instructions can have the condition
|
||||
reversed by tweaking a single TF bit, and their
|
||||
opcodes all have 0x4???????. */
|
||||
gas_assert ((insn & 0xf3e00000) == 0x41000000);
|
||||
insn ^= 0x00010000;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
@ -16810,6 +16893,11 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
|
||||
|| (insn & 0xffe30000) == 0x42800000 /* bc2f */
|
||||
|| (insn & 0xffe30000) == 0x42a00000) /* bc2t */
|
||||
insn ^= 0x00200000;
|
||||
else if ((insn & 0xff000000) == 0x83000000 /* BZ.df
|
||||
BNZ.df */
|
||||
|| (insn & 0xff600000) == 0x81600000) /* BZ.V
|
||||
BNZ.V */
|
||||
insn ^= 0x00800000;
|
||||
else
|
||||
abort ();
|
||||
|
||||
@ -18021,6 +18109,9 @@ MIPS options:\n\
|
||||
-mmcu generate MCU instructions\n\
|
||||
-mno-mcu do not generate MCU instructions\n"));
|
||||
fprintf (stream, _("\
|
||||
-mmsa generate MSA instructions\n\
|
||||
-mno-msa do not generate MSA instructions\n"));
|
||||
fprintf (stream, _("\
|
||||
-mvirt generate Virtualization instructions\n\
|
||||
-mno-virt do not generate Virtualization instructions\n"));
|
||||
fprintf (stream, _("\
|
||||
|
@ -412,6 +412,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
|
||||
[@b{-mdmx}] [@b{-no-mdmx}]
|
||||
[@b{-mdsp}] [@b{-mno-dsp}]
|
||||
[@b{-mdspr2}] [@b{-mno-dspr2}]
|
||||
[@b{-mmsa}] [@b{-mno-msa}]
|
||||
[@b{-mmt}] [@b{-mno-mt}]
|
||||
[@b{-mmcu}] [@b{-mno-mcu}]
|
||||
[@b{-minsn32}] [@b{-mno-insn32}]
|
||||
@ -1329,6 +1330,12 @@ This option implies -mdsp.
|
||||
This tells the assembler to accept DSP Release 2 instructions.
|
||||
@samp{-mno-dspr2} turns off this option.
|
||||
|
||||
@item -mmsa
|
||||
@itemx -mno-msa
|
||||
Generate code for the MIPS SIMD Architecture Extension.
|
||||
This tells the assembler to accept MSA instructions.
|
||||
@samp{-mno-msa} turns off this option.
|
||||
|
||||
@item -mmt
|
||||
@itemx -mno-mt
|
||||
Generate code for the MT Application Specific Extension.
|
||||
|
@ -179,6 +179,12 @@ Generate code for the MCU Application Specific Extension.
|
||||
This tells the assembler to accept MCU instructions.
|
||||
@samp{-mno-mcu} turns off this option.
|
||||
|
||||
@item -mmsa
|
||||
@itemx -mno-msa
|
||||
Generate code for the MIPS SIMD Architecture Extension.
|
||||
This tells the assembler to accept MSA instructions.
|
||||
@samp{-mno-msa} turns off this option.
|
||||
|
||||
@item -mvirt
|
||||
@itemx -mno-virt
|
||||
Generate code for the Virtualization Application Specific Extension.
|
||||
@ -853,6 +859,14 @@ from the MCU Application Specific Extension from that point on
|
||||
in the assembly. The @code{.set nomcu} directive prevents MCU
|
||||
instructions from being accepted.
|
||||
|
||||
@cindex MIPS SIMD Architecture instruction generation override
|
||||
@kindex @code{.set msa}
|
||||
@kindex @code{.set nomsa}
|
||||
The directive @code{.set msa} makes the assembler accept instructions
|
||||
from the MIPS SIMD Architecture Extension from that point on
|
||||
in the assembly. The @code{.set nomsa} directive prevents MSA
|
||||
instructions from being accepted.
|
||||
|
||||
@cindex Virtualization instruction generation override
|
||||
@kindex @code{.set virt}
|
||||
@kindex @code{.set novirt}
|
||||
|
Loading…
Reference in New Issue
Block a user