gas/
* config/tc-mips.c (insn_insert_operand): New function. (macro_build, mips16_macro_build): Put null character check in the for loop and convert continues to breaks. Use operand structures to handle constant operands.
This commit is contained in:
parent
c3c0747817
commit
e077a1c8de
2 changed files with 53 additions and 238 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2013-07-14 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
|
* config/tc-mips.c (insn_insert_operand): New function.
|
||||||
|
(macro_build, mips16_macro_build): Put null character check
|
||||||
|
in the for loop and convert continues to breaks. Use operand
|
||||||
|
structures to handle constant operands.
|
||||||
|
|
||||||
2013-07-14 Richard Sandiford <rdsandiford@googlemail.com>
|
2013-07-14 Richard Sandiford <rdsandiford@googlemail.com>
|
||||||
|
|
||||||
* config/tc-mips.c (validate_mips_insn): Move further up file.
|
* config/tc-mips.c (validate_mips_insn): Move further up file.
|
||||||
|
|
|
@ -2044,6 +2044,15 @@ create_insn (struct mips_cl_insn *insn, const struct mips_opcode *mo)
|
||||||
insn->cleared_p = 0;
|
insn->cleared_p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Install UVAL as the value of OPERAND in INSN. */
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
insn_insert_operand (struct mips_cl_insn *insn,
|
||||||
|
const struct mips_operand *operand, unsigned int uval)
|
||||||
|
{
|
||||||
|
insn->insn_opcode = mips_insert_operand (operand, insn->insn_opcode, uval);
|
||||||
|
}
|
||||||
|
|
||||||
/* Record the current MIPS16/microMIPS mode in now_seg. */
|
/* Record the current MIPS16/microMIPS mode in now_seg. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -5401,9 +5410,11 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
|
||||||
const struct mips_opcode *mo = NULL;
|
const struct mips_opcode *mo = NULL;
|
||||||
bfd_reloc_code_real_type r[3];
|
bfd_reloc_code_real_type r[3];
|
||||||
const struct mips_opcode *amo;
|
const struct mips_opcode *amo;
|
||||||
|
const struct mips_operand *operand;
|
||||||
struct hash_control *hash;
|
struct hash_control *hash;
|
||||||
struct mips_cl_insn insn;
|
struct mips_cl_insn insn;
|
||||||
va_list args;
|
va_list args;
|
||||||
|
unsigned int uval;
|
||||||
|
|
||||||
va_start (args, fmt);
|
va_start (args, fmt);
|
||||||
|
|
||||||
|
@ -5453,152 +5464,15 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
|
||||||
|
|
||||||
gas_assert (mo);
|
gas_assert (mo);
|
||||||
create_insn (&insn, mo);
|
create_insn (&insn, mo);
|
||||||
for (;;)
|
for (; *fmt; ++fmt)
|
||||||
{
|
{
|
||||||
switch (*fmt++)
|
switch (*fmt)
|
||||||
{
|
{
|
||||||
case '\0':
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
case '(':
|
case '(':
|
||||||
case ')':
|
case ')':
|
||||||
continue;
|
|
||||||
|
|
||||||
case '+':
|
|
||||||
switch (*fmt++)
|
|
||||||
{
|
|
||||||
case 'A':
|
|
||||||
case 'E':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips,
|
|
||||||
EXTLSB, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'B':
|
|
||||||
case 'F':
|
|
||||||
/* Note that in the macro case, these arguments are already
|
|
||||||
in MSB form. (When handling the instruction in the
|
|
||||||
non-macro case, these arguments are sizes from which
|
|
||||||
MSB values must be calculated.) */
|
|
||||||
INSERT_OPERAND (mips_opts.micromips,
|
|
||||||
INSMSB, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'J':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (0, CODE10, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'C':
|
|
||||||
case 'G':
|
|
||||||
case 'H':
|
|
||||||
/* Note that in the macro case, these arguments are already
|
|
||||||
in MSBD form. (When handling the instruction in the
|
|
||||||
non-macro case, these arguments are sizes from which
|
|
||||||
MSBD values must be calculated.) */
|
|
||||||
INSERT_OPERAND (mips_opts.micromips,
|
|
||||||
EXTMSBD, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'Q':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (0, SEQI, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'j':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips, EVAOFFSET, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
default:
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case '2':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips, BP, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'n':
|
|
||||||
gas_assert (mips_opts.micromips);
|
|
||||||
case 't':
|
|
||||||
case 'w':
|
|
||||||
case 'E':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips, RT, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips, CODE, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'W':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
case 'T':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips, FT, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'G':
|
|
||||||
if (mips_opts.micromips)
|
|
||||||
INSERT_OPERAND (1, RS, insn, va_arg (args, int));
|
|
||||||
else
|
|
||||||
INSERT_OPERAND (0, RD, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'K':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
case 'd':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips, RD, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'U':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
{
|
|
||||||
int tmp = va_arg (args, int);
|
|
||||||
|
|
||||||
INSERT_OPERAND (0, RT, insn, tmp);
|
|
||||||
INSERT_OPERAND (0, RD, insn, tmp);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'V':
|
|
||||||
case 'S':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (0, FS, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'z':
|
case 'z':
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case '<':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips,
|
|
||||||
SHAMT, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'D':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (0, FD, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'B':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (0, CODE20, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'J':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (0, CODE19, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'q':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (0, CODE2, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'b':
|
|
||||||
case 's':
|
|
||||||
case 'r':
|
|
||||||
case 'v':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips, RS, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'j':
|
case 'j':
|
||||||
|
@ -5608,11 +5482,11 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
|
||||||
|| *r == BFD_RELOC_HI16_S
|
|| *r == BFD_RELOC_HI16_S
|
||||||
|| *r == BFD_RELOC_LO16
|
|| *r == BFD_RELOC_LO16
|
||||||
|| *r == BFD_RELOC_MIPS_GOT_OFST);
|
|| *r == BFD_RELOC_MIPS_GOT_OFST);
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
macro_read_relocs (&args, r);
|
macro_read_relocs (&args, r);
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
macro_read_relocs (&args, r);
|
macro_read_relocs (&args, r);
|
||||||
|
@ -5625,7 +5499,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
|
||||||
|| *r == BFD_RELOC_GPREL16
|
|| *r == BFD_RELOC_GPREL16
|
||||||
|| *r == BFD_RELOC_MIPS_GOT_HI16
|
|| *r == BFD_RELOC_MIPS_GOT_HI16
|
||||||
|| *r == BFD_RELOC_MIPS_CALL_HI16))));
|
|| *r == BFD_RELOC_MIPS_CALL_HI16))));
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case 'p':
|
case 'p':
|
||||||
gas_assert (ep != NULL);
|
gas_assert (ep != NULL);
|
||||||
|
@ -5654,74 +5528,30 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*r = BFD_RELOC_16_PCREL_S2;
|
*r = BFD_RELOC_16_PCREL_S2;
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
gas_assert (ep != NULL);
|
gas_assert (ep != NULL);
|
||||||
*r = BFD_RELOC_MIPS_JMP;
|
*r = BFD_RELOC_MIPS_JMP;
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'C':
|
|
||||||
gas_assert (!mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (0, COPZ, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'k':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips,
|
|
||||||
CACHE, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case '|':
|
|
||||||
gas_assert (mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (1, TRAP, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case '.':
|
|
||||||
gas_assert (mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (1, OFFSET10, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case '\\':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips,
|
|
||||||
3BITPOS, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case '~':
|
|
||||||
INSERT_OPERAND (mips_opts.micromips,
|
|
||||||
OFFSET12, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'N':
|
|
||||||
gas_assert (mips_opts.micromips);
|
|
||||||
INSERT_OPERAND (1, BCC, insn, va_arg (args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'm': /* Opcode extension character. */
|
|
||||||
gas_assert (mips_opts.micromips);
|
|
||||||
switch (*fmt++)
|
|
||||||
{
|
|
||||||
case 'j':
|
|
||||||
INSERT_OPERAND (1, MJ, insn, va_arg (args, int));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'p':
|
|
||||||
INSERT_OPERAND (1, MP, insn, va_arg (args, int));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'F':
|
|
||||||
INSERT_OPERAND (1, IMMF, insn, va_arg (args, int));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
operand = (mips_opts.micromips
|
||||||
|
? decode_micromips_operand (fmt)
|
||||||
|
: decode_mips_operand (fmt));
|
||||||
|
if (!operand)
|
||||||
abort ();
|
abort ();
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
default:
|
uval = va_arg (args, int);
|
||||||
abort ();
|
if (operand->type == OP_CLO_CLZ_DEST)
|
||||||
}
|
uval |= (uval << 5);
|
||||||
|
insn_insert_operand (&insn, operand, uval);
|
||||||
|
|
||||||
|
if (*fmt == '+' || *fmt == 'm')
|
||||||
|
++fmt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
va_end (args);
|
va_end (args);
|
||||||
gas_assert (*r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
|
gas_assert (*r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
|
||||||
|
|
||||||
|
@ -5734,6 +5564,7 @@ mips16_macro_build (expressionS *ep, const char *name, const char *fmt,
|
||||||
{
|
{
|
||||||
struct mips_opcode *mo;
|
struct mips_opcode *mo;
|
||||||
struct mips_cl_insn insn;
|
struct mips_cl_insn insn;
|
||||||
|
const struct mips_operand *operand;
|
||||||
bfd_reloc_code_real_type r[3]
|
bfd_reloc_code_real_type r[3]
|
||||||
= {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
|
= {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
|
||||||
|
|
||||||
|
@ -5749,48 +5580,23 @@ mips16_macro_build (expressionS *ep, const char *name, const char *fmt,
|
||||||
}
|
}
|
||||||
|
|
||||||
create_insn (&insn, mo);
|
create_insn (&insn, mo);
|
||||||
for (;;)
|
for (; *fmt; ++fmt)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = *fmt++;
|
c = *fmt;
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case '\0':
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ',':
|
case ',':
|
||||||
case '(':
|
case '(':
|
||||||
case ')':
|
case ')':
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case 'y':
|
|
||||||
case 'w':
|
|
||||||
MIPS16_INSERT_OPERAND (RY, insn, va_arg (*args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'x':
|
|
||||||
case 'v':
|
|
||||||
MIPS16_INSERT_OPERAND (RX, insn, va_arg (*args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'z':
|
|
||||||
MIPS16_INSERT_OPERAND (RZ, insn, va_arg (*args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'Z':
|
|
||||||
MIPS16_INSERT_OPERAND (MOVE32Z, insn, va_arg (*args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case '0':
|
case '0':
|
||||||
case 'S':
|
case 'S':
|
||||||
case 'P':
|
case 'P':
|
||||||
case 'R':
|
case 'R':
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
case 'X':
|
|
||||||
MIPS16_INSERT_OPERAND (REGR32, insn, va_arg (*args, int));
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case '<':
|
case '<':
|
||||||
case '>':
|
case '>':
|
||||||
|
@ -5822,14 +5628,16 @@ mips16_macro_build (expressionS *ep, const char *name, const char *fmt,
|
||||||
*r = BFD_RELOC_UNUSED;
|
*r = BFD_RELOC_UNUSED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
|
|
||||||
case '6':
|
|
||||||
MIPS16_INSERT_OPERAND (IMM6, insn, va_arg (*args, int));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
operand = decode_mips16_operand (c, FALSE);
|
||||||
|
if (!operand)
|
||||||
|
abort ();
|
||||||
|
|
||||||
|
insn_insert_operand (&insn, operand, va_arg (args, int));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gas_assert (*r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
|
gas_assert (*r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue