mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
Improve gas error messages for invalid instructions.
* cpu-ia64-opc.c (elf64_ia64_operands}: Fix typo: error string for C8 said "1" instead of "8". Clarify error string for IMM22: "signed integer" instead of just "integer". * config/tc-ia64.c (enum operand_match_result): New type. (operand_match): Change return type to operand_match_result. Fix all returns appropriately, adding support for returning the out-of-range result. (parse_operands): New locals result, error_pos, out_of_range_pos, curr_out_of_range_pos. Rewrite operand matching loop to give better error messages. * ia64-opc-d.c (ia64_opcodes_d): Break the "add" pattern into two separate variants: one for IMM22 and the other for IMM14. * ia64-asmtab.c: Regenerate.
This commit is contained in:
parent
aacc1edd3a
commit
87f8eb977e
@ -1,3 +1,9 @@
|
||||
2001-02-21 David Mosberger <davidm@hpl.hp.com>
|
||||
|
||||
* cpu-ia64-opc.c (elf64_ia64_operands}: Fix typo: error string for
|
||||
C8 said "1" instead of "8". Clarify error string for IMM22:
|
||||
"signed integer" instead of just "integer".
|
||||
|
||||
2001-02-20 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* elf64-x86-64.c (elf64_x86_64_finish_dynamic_symbol): Don't make
|
||||
|
@ -421,7 +421,7 @@ const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
|
||||
{ CST, ins_const, ext_const, "ar.ccv", {{ 0, 0}}, 0, "ar.ccv" },
|
||||
{ CST, ins_const, ext_const, "ar.pfs", {{ 0, 0}}, 0, "ar.pfs" },
|
||||
{ CST, ins_const, ext_const, "1", {{ 0, 0}}, 0, "1" },
|
||||
{ CST, ins_const, ext_const, "8", {{ 0, 0}}, 0, "1" },
|
||||
{ CST, ins_const, ext_const, "8", {{ 0, 0}}, 0, "8" },
|
||||
{ CST, ins_const, ext_const, "16", {{ 0, 0}}, 0, "16" },
|
||||
{ CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" },
|
||||
{ CST, ins_const, ext_const, "ip", {{ 0, 0}}, 0, "ip" },
|
||||
@ -551,7 +551,7 @@ const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
|
||||
"a 21-bit unsigned" },
|
||||
{ ABS, ins_imms, ext_imms, 0, /* IMM22 */
|
||||
{{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
|
||||
"a 22-bit integer" },
|
||||
"a 22-bit signed integer" },
|
||||
{ ABS, ins_immu, ext_immu, 0, /* IMMU24 */
|
||||
{{21, 6}, { 2, 31}, { 1, 36}}, 0,
|
||||
"a 24-bit unsigned" },
|
||||
|
@ -1,3 +1,13 @@
|
||||
2001-02-21 David Mosberger <davidm@hpl.hp.com>
|
||||
|
||||
* config/tc-ia64.c (enum operand_match_result): New type.
|
||||
(operand_match): Change return type to operand_match_result.
|
||||
Fix all returns appropriately, adding support for returning the
|
||||
out-of-range result.
|
||||
(parse_operands): New locals result, error_pos, out_of_range_pos,
|
||||
curr_out_of_range_pos. Rewrite operand matching loop to give better
|
||||
error messages.
|
||||
|
||||
2001-02-21 David Mosberger <davidm@hpl.hp.com>
|
||||
|
||||
* config/tc-ia64.c (struct unwind): Add member "prologue_count".
|
||||
|
@ -124,6 +124,13 @@ enum dynreg_type
|
||||
DYNREG_NUM_TYPES
|
||||
};
|
||||
|
||||
enum operand_match_result
|
||||
{
|
||||
OPERAND_MATCH,
|
||||
OPERAND_OUT_OF_RANGE,
|
||||
OPERAND_MISMATCH
|
||||
};
|
||||
|
||||
/* On the ia64, we can't know the address of a text label until the
|
||||
instructions are packed into a bundle. To handle this, we keep
|
||||
track of the list of labels that appear in front of each
|
||||
@ -690,8 +697,9 @@ static void add_unwind_entry PARAMS((unw_rec_list *ptr));
|
||||
static symbolS *declare_register PARAMS ((const char *name, int regnum));
|
||||
static void declare_register_set PARAMS ((const char *, int, int));
|
||||
static unsigned int operand_width PARAMS ((enum ia64_opnd));
|
||||
static int operand_match PARAMS ((const struct ia64_opcode *idesc,
|
||||
int index, expressionS *e));
|
||||
static enum operand_match_result operand_match PARAMS ((const struct ia64_opcode *idesc,
|
||||
int index,
|
||||
expressionS *e));
|
||||
static int parse_operand PARAMS ((expressionS *e));
|
||||
static struct ia64_opcode * parse_operands PARAMS ((struct ia64_opcode *));
|
||||
static void build_insn PARAMS ((struct slot *, bfd_vma *));
|
||||
@ -4740,7 +4748,7 @@ operand_width (opnd)
|
||||
return bits;
|
||||
}
|
||||
|
||||
static int
|
||||
static enum operand_match_result
|
||||
operand_match (idesc, index, e)
|
||||
const struct ia64_opcode *idesc;
|
||||
int index;
|
||||
@ -4757,62 +4765,77 @@ operand_match (idesc, index, e)
|
||||
|
||||
case IA64_OPND_AR_CCV:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_AR + 32)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_AR_PFS:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_AR + 64)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_GR0:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_GR + 0)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_IP:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_IP)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_PR:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_PR)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_PR_ROT:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_PR_ROT)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_PSR:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_PSR)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_PSR_L:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_PSR_L)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_PSR_UM:
|
||||
if (e->X_op == O_register && e->X_add_number == REG_PSR_UM)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_C1:
|
||||
if (e->X_op == O_constant && e->X_add_number == 1)
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if (e->X_add_number == 1)
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_C8:
|
||||
if (e->X_op == O_constant && e->X_add_number == 8)
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if (e->X_add_number == 8)
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_C16:
|
||||
if (e->X_op == O_constant && e->X_add_number == 16)
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if (e->X_add_number == 16)
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* register operands: */
|
||||
@ -4820,20 +4843,20 @@ operand_match (idesc, index, e)
|
||||
case IA64_OPND_AR3:
|
||||
if (e->X_op == O_register && e->X_add_number >= REG_AR
|
||||
&& e->X_add_number < REG_AR + 128)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_B1:
|
||||
case IA64_OPND_B2:
|
||||
if (e->X_op == O_register && e->X_add_number >= REG_BR
|
||||
&& e->X_add_number < REG_BR + 8)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_CR3:
|
||||
if (e->X_op == O_register && e->X_add_number >= REG_CR
|
||||
&& e->X_add_number < REG_CR + 128)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_F1:
|
||||
@ -4842,14 +4865,14 @@ operand_match (idesc, index, e)
|
||||
case IA64_OPND_F4:
|
||||
if (e->X_op == O_register && e->X_add_number >= REG_FR
|
||||
&& e->X_add_number < REG_FR + 128)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_P1:
|
||||
case IA64_OPND_P2:
|
||||
if (e->X_op == O_register && e->X_add_number >= REG_P
|
||||
&& e->X_add_number < REG_P + 64)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_R1:
|
||||
@ -4857,13 +4880,17 @@ operand_match (idesc, index, e)
|
||||
case IA64_OPND_R3:
|
||||
if (e->X_op == O_register && e->X_add_number >= REG_GR
|
||||
&& e->X_add_number < REG_GR + 128)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_R3_2:
|
||||
if (e->X_op == O_register && e->X_add_number >= REG_GR
|
||||
&& e->X_add_number < REG_GR + 4)
|
||||
return 1;
|
||||
if (e->X_op == O_register && e->X_add_number >= REG_GR)
|
||||
{
|
||||
if (e->X_add_number < REG_GR + 4)
|
||||
return OPERAND_MATCH;
|
||||
else if (e->X_add_number < REG_GR + 128)
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* indirect operands: */
|
||||
@ -4880,12 +4907,12 @@ operand_match (idesc, index, e)
|
||||
if (e->X_op == O_index && e->X_op_symbol
|
||||
&& (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
|
||||
== opnd - IA64_OPND_CPUID_R3))
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_MR3:
|
||||
if (e->X_op == O_index && !e->X_op_symbol)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
/* immediate operands: */
|
||||
@ -4893,40 +4920,58 @@ operand_match (idesc, index, e)
|
||||
case IA64_OPND_LEN4:
|
||||
case IA64_OPND_LEN6:
|
||||
bits = operand_width (idesc->operands[index]);
|
||||
if (e->X_op == O_constant
|
||||
&& (bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if ((bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_CNT2b:
|
||||
if (e->X_op == O_constant
|
||||
&& (bfd_vma) (e->X_add_number - 1) < 3)
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if ((bfd_vma) (e->X_add_number - 1) < 3)
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_CNT2c:
|
||||
val = e->X_add_number;
|
||||
if (e->X_op == O_constant
|
||||
&& (val == 0 || val == 7 || val == 15 || val == 16))
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if ((val == 0 || val == 7 || val == 15 || val == 16))
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_SOR:
|
||||
/* SOR must be an integer multiple of 8 */
|
||||
if (e->X_add_number & 0x7)
|
||||
break;
|
||||
if (e->X_op == O_constant && e->X_add_number & 0x7)
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
case IA64_OPND_SOF:
|
||||
case IA64_OPND_SOL:
|
||||
if (e->X_op == O_constant &&
|
||||
(bfd_vma) e->X_add_number <= 96)
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if ((bfd_vma) e->X_add_number <= 96)
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_IMMU62:
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62))
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4952,10 +4997,10 @@ operand_match (idesc, index, e)
|
||||
fix->expr = *e;
|
||||
fix->is_pcrel = 0;
|
||||
++CURR_SLOT.num_fixups;
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
}
|
||||
else if (e->X_op == O_constant)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
break;
|
||||
|
||||
case IA64_OPND_CCNT5:
|
||||
@ -4973,30 +5018,42 @@ operand_match (idesc, index, e)
|
||||
case IA64_OPND_MHTYPE8:
|
||||
case IA64_OPND_POS6:
|
||||
bits = operand_width (idesc->operands[index]);
|
||||
if (e->X_op == O_constant
|
||||
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_IMMU9:
|
||||
bits = operand_width (idesc->operands[index]);
|
||||
if (e->X_op == O_constant
|
||||
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
|
||||
{
|
||||
int lobits = e->X_add_number & 0x3;
|
||||
if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
|
||||
e->X_add_number |= (bfd_vma) 0x3;
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
}
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_IMM44:
|
||||
/* least 16 bits must be zero */
|
||||
if ((e->X_add_number & 0xffff) != 0)
|
||||
/* XXX technically, this is wrong: we should not be issuing warning
|
||||
messages until we're sure this instruction pattern is going to
|
||||
be used! */
|
||||
as_warn (_("lower 16 bits of mask ignored"));
|
||||
|
||||
if (e->X_op == O_constant
|
||||
&& ((e->X_add_number >= 0
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if (((e->X_add_number >= 0
|
||||
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 44))
|
||||
|| (e->X_add_number < 0
|
||||
&& (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 44))))
|
||||
@ -5007,14 +5064,18 @@ operand_match (idesc, index, e)
|
||||
{
|
||||
e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1);
|
||||
}
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
}
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_IMM17:
|
||||
/* bit 0 is a don't care (pr0 is hardwired to 1) */
|
||||
if (e->X_op == O_constant
|
||||
&& ((e->X_add_number >= 0
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if (((e->X_add_number >= 0
|
||||
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 17))
|
||||
|| (e->X_add_number < 0
|
||||
&& (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 17))))
|
||||
@ -5025,7 +5086,10 @@ operand_match (idesc, index, e)
|
||||
{
|
||||
e->X_add_number |= ~(((bfd_vma) 1 << 17) - 1);
|
||||
}
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
}
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -5063,18 +5127,18 @@ operand_match (idesc, index, e)
|
||||
fix->expr = *e;
|
||||
fix->is_pcrel = 0;
|
||||
++CURR_SLOT.num_fixups;
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
}
|
||||
else if (e->X_op != O_constant
|
||||
&& ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8))
|
||||
return 0;
|
||||
return OPERAND_MISMATCH;
|
||||
|
||||
if (opnd == IA64_OPND_IMM8M1U4)
|
||||
{
|
||||
/* Zero is not valid for unsigned compares that take an adjusted
|
||||
constant immediate range. */
|
||||
if (e->X_add_number == 0)
|
||||
return 0;
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
|
||||
/* Sign-extend 32-bit unsigned numbers, so that the following range
|
||||
checks will work. */
|
||||
@ -5086,7 +5150,7 @@ operand_match (idesc, index, e)
|
||||
/* Check for 0x100000000. This is valid because
|
||||
0x100000000-1 is the same as ((uint32_t) -1). */
|
||||
if (val == ((bfd_signed_vma) 1 << 32))
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
|
||||
val = val - 1;
|
||||
}
|
||||
@ -5095,7 +5159,7 @@ operand_match (idesc, index, e)
|
||||
/* Zero is not valid for unsigned compares that take an adjusted
|
||||
constant immediate range. */
|
||||
if (e->X_add_number == 0)
|
||||
return 0;
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
|
||||
/* Check for 0x10000000000000000. */
|
||||
if (e->X_op == O_big)
|
||||
@ -5105,9 +5169,9 @@ operand_match (idesc, index, e)
|
||||
&& generic_bignum[2] == 0
|
||||
&& generic_bignum[3] == 0
|
||||
&& generic_bignum[4] == 1)
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return 0;
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
else
|
||||
val = e->X_add_number - 1;
|
||||
@ -5128,17 +5192,22 @@ operand_match (idesc, index, e)
|
||||
|
||||
if ((val >= 0 && (bfd_vma) val < ((bfd_vma) 1 << (bits - 1)))
|
||||
|| (val < 0 && (bfd_vma) -val <= ((bfd_vma) 1 << (bits - 1))))
|
||||
return 1;
|
||||
break;
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
|
||||
case IA64_OPND_INC3:
|
||||
/* +/- 1, 4, 8, 16 */
|
||||
val = e->X_add_number;
|
||||
if (val < 0)
|
||||
val = -val;
|
||||
if (e->X_op == O_constant
|
||||
&& (val == 1 || val == 4 || val == 8 || val == 16))
|
||||
return 1;
|
||||
if (e->X_op == O_constant)
|
||||
{
|
||||
if ((val == 1 || val == 4 || val == 8 || val == 16))
|
||||
return OPERAND_MATCH;
|
||||
else
|
||||
return OPERAND_OUT_OF_RANGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case IA64_OPND_TGT25:
|
||||
@ -5164,14 +5233,14 @@ operand_match (idesc, index, e)
|
||||
fix->expr = *e;
|
||||
fix->is_pcrel = 1;
|
||||
++CURR_SLOT.num_fixups;
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
}
|
||||
case IA64_OPND_TAG13:
|
||||
case IA64_OPND_TAG13b:
|
||||
switch (e->X_op)
|
||||
{
|
||||
case O_constant:
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
|
||||
case O_symbol:
|
||||
fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
|
||||
@ -5183,7 +5252,7 @@ operand_match (idesc, index, e)
|
||||
fix->expr = *e;
|
||||
fix->is_pcrel = 1;
|
||||
++CURR_SLOT.num_fixups;
|
||||
return 1;
|
||||
return OPERAND_MATCH;
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -5193,7 +5262,7 @@ operand_match (idesc, index, e)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return OPERAND_MISMATCH;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -5241,8 +5310,9 @@ parse_operands (idesc)
|
||||
struct ia64_opcode *idesc;
|
||||
{
|
||||
int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0;
|
||||
int sep = 0;
|
||||
int error_pos, out_of_range_pos, curr_out_of_range_pos, sep = 0;
|
||||
enum ia64_opnd expected_operand = IA64_OPND_NIL;
|
||||
enum operand_match_result result;
|
||||
char mnemonic[129];
|
||||
char *first_arg = 0, *end, *saved_input_pointer;
|
||||
unsigned int sof;
|
||||
@ -5324,6 +5394,8 @@ parse_operands (idesc)
|
||||
}
|
||||
|
||||
highest_unmatched_operand = 0;
|
||||
curr_out_of_range_pos = -1;
|
||||
error_pos = 0;
|
||||
expected_operand = idesc->operands[0];
|
||||
for (; idesc; idesc = get_next_opcode (idesc))
|
||||
{
|
||||
@ -5331,16 +5403,52 @@ parse_operands (idesc)
|
||||
continue; /* mismatch in # of outputs */
|
||||
|
||||
CURR_SLOT.num_fixups = 0;
|
||||
for (i = 0; i < num_operands && idesc->operands[i]; ++i)
|
||||
if (!operand_match (idesc, i, CURR_SLOT.opnd + i))
|
||||
break;
|
||||
|
||||
if (i != num_operands)
|
||||
/* Try to match all operands. If we see an out-of-range operand,
|
||||
then continue trying to match the rest of the operands, since if
|
||||
the rest match, then this idesc will give the best error message. */
|
||||
|
||||
out_of_range_pos = -1;
|
||||
for (i = 0; i < num_operands && idesc->operands[i]; ++i)
|
||||
{
|
||||
if (i > highest_unmatched_operand)
|
||||
result = operand_match (idesc, i, CURR_SLOT.opnd + i);
|
||||
if (result != OPERAND_MATCH)
|
||||
{
|
||||
if (result != OPERAND_OUT_OF_RANGE)
|
||||
break;
|
||||
if (out_of_range_pos < 0)
|
||||
/* remember position of the first out-of-range operand: */
|
||||
out_of_range_pos = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we did not match all operands, or if at least one operand was
|
||||
out-of-range, then this idesc does not match. Keep track of which
|
||||
idesc matched the most operands before failing. If we have two
|
||||
idescs that failed at the same position, and one had an out-of-range
|
||||
operand, then prefer the out-of-range operand. Thus if we have
|
||||
"add r0=0x1000000,r1" we get an error saying the constant is out
|
||||
of range instead of an error saying that the constant should have been
|
||||
a register. */
|
||||
|
||||
if (i != num_operands || out_of_range_pos >= 0)
|
||||
{
|
||||
if (i > highest_unmatched_operand
|
||||
|| (i == highest_unmatched_operand
|
||||
&& out_of_range_pos > curr_out_of_range_pos))
|
||||
{
|
||||
highest_unmatched_operand = i;
|
||||
if (out_of_range_pos >= 0)
|
||||
{
|
||||
expected_operand = idesc->operands[out_of_range_pos];
|
||||
error_pos = out_of_range_pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
expected_operand = idesc->operands[i];
|
||||
error_pos = i;
|
||||
}
|
||||
curr_out_of_range_pos = out_of_range_pos;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -5355,7 +5463,7 @@ parse_operands (idesc)
|
||||
{
|
||||
if (expected_operand)
|
||||
as_bad ("Operand %u of `%s' should be %s",
|
||||
highest_unmatched_operand + 1, mnemonic,
|
||||
error_pos + 1, mnemonic,
|
||||
elf64_ia64_operands[expected_operand].desc);
|
||||
else
|
||||
as_bad ("Operand mismatch");
|
||||
|
@ -1,3 +1,9 @@
|
||||
2001-02-21 David Mosberger <davidm@hpl.hp.com>
|
||||
|
||||
* ia64-opc-d.c (ia64_opcodes_d): Break the "add" pattern into two
|
||||
separate variants: one for IMM22 and the other for IMM14.
|
||||
* ia64-asmtab.c: Regenerate.
|
||||
|
||||
2001-02-21 Greg McGary <greg@mcgary.org>
|
||||
|
||||
* cgen-opc.c (cgen_get_insn_value): Add missing `return'.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,9 @@
|
||||
struct ia64_opcode ia64_opcodes_d[] =
|
||||
{
|
||||
{"add", IA64_TYPE_DYN, 1, 0, 0,
|
||||
{IA64_OPND_R1, IA64_OPND_IMM22, IA64_OPND_R3}},
|
||||
{IA64_OPND_R1, IA64_OPND_IMM22, IA64_OPND_R3_2}},
|
||||
{"add", IA64_TYPE_DYN, 1, 0, 0,
|
||||
{IA64_OPND_R1, IA64_OPND_IMM14, IA64_OPND_R3}},
|
||||
{"break", IA64_TYPE_DYN, 0, 0, 0, {IA64_OPND_IMMU21}},
|
||||
{"chk.s", IA64_TYPE_DYN, 0, 0, 0, {IA64_OPND_R2, IA64_OPND_TGT25b}},
|
||||
{"mov", IA64_TYPE_DYN, 1, 0, 0, {IA64_OPND_R1, IA64_OPND_AR3}},
|
||||
|
Loading…
Reference in New Issue
Block a user