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>
|
2001-02-20 Andreas Jaeger <aj@suse.de>
|
||||||
|
|
||||||
* elf64-x86-64.c (elf64_x86_64_finish_dynamic_symbol): Don't make
|
* 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.ccv", {{ 0, 0}}, 0, "ar.ccv" },
|
||||||
{ CST, ins_const, ext_const, "ar.pfs", {{ 0, 0}}, 0, "ar.pfs" },
|
{ 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, "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, "16", {{ 0, 0}}, 0, "16" },
|
||||||
{ CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" },
|
{ CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" },
|
||||||
{ CST, ins_const, ext_const, "ip", {{ 0, 0}}, 0, "ip" },
|
{ 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" },
|
"a 21-bit unsigned" },
|
||||||
{ ABS, ins_imms, ext_imms, 0, /* IMM22 */
|
{ ABS, ins_imms, ext_imms, 0, /* IMM22 */
|
||||||
{{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
|
{{ 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 */
|
{ ABS, ins_immu, ext_immu, 0, /* IMMU24 */
|
||||||
{{21, 6}, { 2, 31}, { 1, 36}}, 0,
|
{{21, 6}, { 2, 31}, { 1, 36}}, 0,
|
||||||
"a 24-bit unsigned" },
|
"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>
|
2001-02-21 David Mosberger <davidm@hpl.hp.com>
|
||||||
|
|
||||||
* config/tc-ia64.c (struct unwind): Add member "prologue_count".
|
* config/tc-ia64.c (struct unwind): Add member "prologue_count".
|
||||||
|
@ -124,6 +124,13 @@ enum dynreg_type
|
|||||||
DYNREG_NUM_TYPES
|
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
|
/* 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
|
instructions are packed into a bundle. To handle this, we keep
|
||||||
track of the list of labels that appear in front of each
|
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 symbolS *declare_register PARAMS ((const char *name, int regnum));
|
||||||
static void declare_register_set PARAMS ((const char *, int, int));
|
static void declare_register_set PARAMS ((const char *, int, int));
|
||||||
static unsigned int operand_width PARAMS ((enum ia64_opnd));
|
static unsigned int operand_width PARAMS ((enum ia64_opnd));
|
||||||
static int operand_match PARAMS ((const struct ia64_opcode *idesc,
|
static enum operand_match_result operand_match PARAMS ((const struct ia64_opcode *idesc,
|
||||||
int index, expressionS *e));
|
int index,
|
||||||
|
expressionS *e));
|
||||||
static int parse_operand PARAMS ((expressionS *e));
|
static int parse_operand PARAMS ((expressionS *e));
|
||||||
static struct ia64_opcode * parse_operands PARAMS ((struct ia64_opcode *));
|
static struct ia64_opcode * parse_operands PARAMS ((struct ia64_opcode *));
|
||||||
static void build_insn PARAMS ((struct slot *, bfd_vma *));
|
static void build_insn PARAMS ((struct slot *, bfd_vma *));
|
||||||
@ -4740,7 +4748,7 @@ operand_width (opnd)
|
|||||||
return bits;
|
return bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static enum operand_match_result
|
||||||
operand_match (idesc, index, e)
|
operand_match (idesc, index, e)
|
||||||
const struct ia64_opcode *idesc;
|
const struct ia64_opcode *idesc;
|
||||||
int index;
|
int index;
|
||||||
@ -4757,62 +4765,77 @@ operand_match (idesc, index, e)
|
|||||||
|
|
||||||
case IA64_OPND_AR_CCV:
|
case IA64_OPND_AR_CCV:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_AR + 32)
|
if (e->X_op == O_register && e->X_add_number == REG_AR + 32)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_AR_PFS:
|
case IA64_OPND_AR_PFS:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_AR + 64)
|
if (e->X_op == O_register && e->X_add_number == REG_AR + 64)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_GR0:
|
case IA64_OPND_GR0:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_GR + 0)
|
if (e->X_op == O_register && e->X_add_number == REG_GR + 0)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_IP:
|
case IA64_OPND_IP:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_IP)
|
if (e->X_op == O_register && e->X_add_number == REG_IP)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_PR:
|
case IA64_OPND_PR:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_PR)
|
if (e->X_op == O_register && e->X_add_number == REG_PR)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_PR_ROT:
|
case IA64_OPND_PR_ROT:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_PR_ROT)
|
if (e->X_op == O_register && e->X_add_number == REG_PR_ROT)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_PSR:
|
case IA64_OPND_PSR:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_PSR)
|
if (e->X_op == O_register && e->X_add_number == REG_PSR)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_PSR_L:
|
case IA64_OPND_PSR_L:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_PSR_L)
|
if (e->X_op == O_register && e->X_add_number == REG_PSR_L)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_PSR_UM:
|
case IA64_OPND_PSR_UM:
|
||||||
if (e->X_op == O_register && e->X_add_number == REG_PSR_UM)
|
if (e->X_op == O_register && e->X_add_number == REG_PSR_UM)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_C1:
|
case IA64_OPND_C1:
|
||||||
if (e->X_op == O_constant && e->X_add_number == 1)
|
if (e->X_op == O_constant)
|
||||||
return 1;
|
{
|
||||||
|
if (e->X_add_number == 1)
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_C8:
|
case IA64_OPND_C8:
|
||||||
if (e->X_op == O_constant && e->X_add_number == 8)
|
if (e->X_op == O_constant)
|
||||||
return 1;
|
{
|
||||||
|
if (e->X_add_number == 8)
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_C16:
|
case IA64_OPND_C16:
|
||||||
if (e->X_op == O_constant && e->X_add_number == 16)
|
if (e->X_op == O_constant)
|
||||||
return 1;
|
{
|
||||||
|
if (e->X_add_number == 16)
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* register operands: */
|
/* register operands: */
|
||||||
@ -4820,20 +4843,20 @@ operand_match (idesc, index, e)
|
|||||||
case IA64_OPND_AR3:
|
case IA64_OPND_AR3:
|
||||||
if (e->X_op == O_register && e->X_add_number >= REG_AR
|
if (e->X_op == O_register && e->X_add_number >= REG_AR
|
||||||
&& e->X_add_number < REG_AR + 128)
|
&& e->X_add_number < REG_AR + 128)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_B1:
|
case IA64_OPND_B1:
|
||||||
case IA64_OPND_B2:
|
case IA64_OPND_B2:
|
||||||
if (e->X_op == O_register && e->X_add_number >= REG_BR
|
if (e->X_op == O_register && e->X_add_number >= REG_BR
|
||||||
&& e->X_add_number < REG_BR + 8)
|
&& e->X_add_number < REG_BR + 8)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_CR3:
|
case IA64_OPND_CR3:
|
||||||
if (e->X_op == O_register && e->X_add_number >= REG_CR
|
if (e->X_op == O_register && e->X_add_number >= REG_CR
|
||||||
&& e->X_add_number < REG_CR + 128)
|
&& e->X_add_number < REG_CR + 128)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_F1:
|
case IA64_OPND_F1:
|
||||||
@ -4842,14 +4865,14 @@ operand_match (idesc, index, e)
|
|||||||
case IA64_OPND_F4:
|
case IA64_OPND_F4:
|
||||||
if (e->X_op == O_register && e->X_add_number >= REG_FR
|
if (e->X_op == O_register && e->X_add_number >= REG_FR
|
||||||
&& e->X_add_number < REG_FR + 128)
|
&& e->X_add_number < REG_FR + 128)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_P1:
|
case IA64_OPND_P1:
|
||||||
case IA64_OPND_P2:
|
case IA64_OPND_P2:
|
||||||
if (e->X_op == O_register && e->X_add_number >= REG_P
|
if (e->X_op == O_register && e->X_add_number >= REG_P
|
||||||
&& e->X_add_number < REG_P + 64)
|
&& e->X_add_number < REG_P + 64)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_R1:
|
case IA64_OPND_R1:
|
||||||
@ -4857,13 +4880,17 @@ operand_match (idesc, index, e)
|
|||||||
case IA64_OPND_R3:
|
case IA64_OPND_R3:
|
||||||
if (e->X_op == O_register && e->X_add_number >= REG_GR
|
if (e->X_op == O_register && e->X_add_number >= REG_GR
|
||||||
&& e->X_add_number < REG_GR + 128)
|
&& e->X_add_number < REG_GR + 128)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_R3_2:
|
case IA64_OPND_R3_2:
|
||||||
if (e->X_op == O_register && e->X_add_number >= REG_GR
|
if (e->X_op == O_register && e->X_add_number >= REG_GR)
|
||||||
&& e->X_add_number < REG_GR + 4)
|
{
|
||||||
return 1;
|
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;
|
break;
|
||||||
|
|
||||||
/* indirect operands: */
|
/* indirect operands: */
|
||||||
@ -4880,12 +4907,12 @@ operand_match (idesc, index, e)
|
|||||||
if (e->X_op == O_index && e->X_op_symbol
|
if (e->X_op == O_index && e->X_op_symbol
|
||||||
&& (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
|
&& (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
|
||||||
== opnd - IA64_OPND_CPUID_R3))
|
== opnd - IA64_OPND_CPUID_R3))
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_MR3:
|
case IA64_OPND_MR3:
|
||||||
if (e->X_op == O_index && !e->X_op_symbol)
|
if (e->X_op == O_index && !e->X_op_symbol)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* immediate operands: */
|
/* immediate operands: */
|
||||||
@ -4893,40 +4920,58 @@ operand_match (idesc, index, e)
|
|||||||
case IA64_OPND_LEN4:
|
case IA64_OPND_LEN4:
|
||||||
case IA64_OPND_LEN6:
|
case IA64_OPND_LEN6:
|
||||||
bits = operand_width (idesc->operands[index]);
|
bits = operand_width (idesc->operands[index]);
|
||||||
if (e->X_op == O_constant
|
if (e->X_op == O_constant)
|
||||||
&& (bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
|
{
|
||||||
return 1;
|
if ((bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_CNT2b:
|
case IA64_OPND_CNT2b:
|
||||||
if (e->X_op == O_constant
|
if (e->X_op == O_constant)
|
||||||
&& (bfd_vma) (e->X_add_number - 1) < 3)
|
{
|
||||||
return 1;
|
if ((bfd_vma) (e->X_add_number - 1) < 3)
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_CNT2c:
|
case IA64_OPND_CNT2c:
|
||||||
val = e->X_add_number;
|
val = e->X_add_number;
|
||||||
if (e->X_op == O_constant
|
if (e->X_op == O_constant)
|
||||||
&& (val == 0 || val == 7 || val == 15 || val == 16))
|
{
|
||||||
return 1;
|
if ((val == 0 || val == 7 || val == 15 || val == 16))
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_SOR:
|
case IA64_OPND_SOR:
|
||||||
/* SOR must be an integer multiple of 8 */
|
/* SOR must be an integer multiple of 8 */
|
||||||
if (e->X_add_number & 0x7)
|
if (e->X_op == O_constant && e->X_add_number & 0x7)
|
||||||
break;
|
return OPERAND_OUT_OF_RANGE;
|
||||||
case IA64_OPND_SOF:
|
case IA64_OPND_SOF:
|
||||||
case IA64_OPND_SOL:
|
case IA64_OPND_SOL:
|
||||||
if (e->X_op == O_constant &&
|
if (e->X_op == O_constant)
|
||||||
(bfd_vma) e->X_add_number <= 96)
|
{
|
||||||
return 1;
|
if ((bfd_vma) e->X_add_number <= 96)
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_IMMU62:
|
case IA64_OPND_IMMU62:
|
||||||
if (e->X_op == O_constant)
|
if (e->X_op == O_constant)
|
||||||
{
|
{
|
||||||
if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62))
|
if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62))
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4952,10 +4997,10 @@ operand_match (idesc, index, e)
|
|||||||
fix->expr = *e;
|
fix->expr = *e;
|
||||||
fix->is_pcrel = 0;
|
fix->is_pcrel = 0;
|
||||||
++CURR_SLOT.num_fixups;
|
++CURR_SLOT.num_fixups;
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
}
|
}
|
||||||
else if (e->X_op == O_constant)
|
else if (e->X_op == O_constant)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_CCNT5:
|
case IA64_OPND_CCNT5:
|
||||||
@ -4973,30 +5018,42 @@ operand_match (idesc, index, e)
|
|||||||
case IA64_OPND_MHTYPE8:
|
case IA64_OPND_MHTYPE8:
|
||||||
case IA64_OPND_POS6:
|
case IA64_OPND_POS6:
|
||||||
bits = operand_width (idesc->operands[index]);
|
bits = operand_width (idesc->operands[index]);
|
||||||
if (e->X_op == O_constant
|
if (e->X_op == O_constant)
|
||||||
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
|
{
|
||||||
return 1;
|
if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_IMMU9:
|
case IA64_OPND_IMMU9:
|
||||||
bits = operand_width (idesc->operands[index]);
|
bits = operand_width (idesc->operands[index]);
|
||||||
if (e->X_op == O_constant
|
if (e->X_op == O_constant)
|
||||||
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
|
{
|
||||||
|
if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
|
||||||
{
|
{
|
||||||
int lobits = e->X_add_number & 0x3;
|
int lobits = e->X_add_number & 0x3;
|
||||||
if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
|
if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
|
||||||
e->X_add_number |= (bfd_vma) 0x3;
|
e->X_add_number |= (bfd_vma) 0x3;
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_IMM44:
|
case IA64_OPND_IMM44:
|
||||||
/* least 16 bits must be zero */
|
/* least 16 bits must be zero */
|
||||||
if ((e->X_add_number & 0xffff) != 0)
|
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"));
|
as_warn (_("lower 16 bits of mask ignored"));
|
||||||
|
|
||||||
if (e->X_op == O_constant
|
if (e->X_op == O_constant)
|
||||||
&& ((e->X_add_number >= 0
|
{
|
||||||
|
if (((e->X_add_number >= 0
|
||||||
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 44))
|
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 44))
|
||||||
|| (e->X_add_number < 0
|
|| (e->X_add_number < 0
|
||||||
&& (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 44))))
|
&& (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);
|
e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1);
|
||||||
}
|
}
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_IMM17:
|
case IA64_OPND_IMM17:
|
||||||
/* bit 0 is a don't care (pr0 is hardwired to 1) */
|
/* bit 0 is a don't care (pr0 is hardwired to 1) */
|
||||||
if (e->X_op == O_constant
|
if (e->X_op == O_constant)
|
||||||
&& ((e->X_add_number >= 0
|
{
|
||||||
|
if (((e->X_add_number >= 0
|
||||||
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 17))
|
&& (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 17))
|
||||||
|| (e->X_add_number < 0
|
|| (e->X_add_number < 0
|
||||||
&& (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 17))))
|
&& (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);
|
e->X_add_number |= ~(((bfd_vma) 1 << 17) - 1);
|
||||||
}
|
}
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -5063,18 +5127,18 @@ operand_match (idesc, index, e)
|
|||||||
fix->expr = *e;
|
fix->expr = *e;
|
||||||
fix->is_pcrel = 0;
|
fix->is_pcrel = 0;
|
||||||
++CURR_SLOT.num_fixups;
|
++CURR_SLOT.num_fixups;
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
}
|
}
|
||||||
else if (e->X_op != O_constant
|
else if (e->X_op != O_constant
|
||||||
&& ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8))
|
&& ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8))
|
||||||
return 0;
|
return OPERAND_MISMATCH;
|
||||||
|
|
||||||
if (opnd == IA64_OPND_IMM8M1U4)
|
if (opnd == IA64_OPND_IMM8M1U4)
|
||||||
{
|
{
|
||||||
/* Zero is not valid for unsigned compares that take an adjusted
|
/* Zero is not valid for unsigned compares that take an adjusted
|
||||||
constant immediate range. */
|
constant immediate range. */
|
||||||
if (e->X_add_number == 0)
|
if (e->X_add_number == 0)
|
||||||
return 0;
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
|
||||||
/* Sign-extend 32-bit unsigned numbers, so that the following range
|
/* Sign-extend 32-bit unsigned numbers, so that the following range
|
||||||
checks will work. */
|
checks will work. */
|
||||||
@ -5086,7 +5150,7 @@ operand_match (idesc, index, e)
|
|||||||
/* Check for 0x100000000. This is valid because
|
/* Check for 0x100000000. This is valid because
|
||||||
0x100000000-1 is the same as ((uint32_t) -1). */
|
0x100000000-1 is the same as ((uint32_t) -1). */
|
||||||
if (val == ((bfd_signed_vma) 1 << 32))
|
if (val == ((bfd_signed_vma) 1 << 32))
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
|
|
||||||
val = val - 1;
|
val = val - 1;
|
||||||
}
|
}
|
||||||
@ -5095,7 +5159,7 @@ operand_match (idesc, index, e)
|
|||||||
/* Zero is not valid for unsigned compares that take an adjusted
|
/* Zero is not valid for unsigned compares that take an adjusted
|
||||||
constant immediate range. */
|
constant immediate range. */
|
||||||
if (e->X_add_number == 0)
|
if (e->X_add_number == 0)
|
||||||
return 0;
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
|
||||||
/* Check for 0x10000000000000000. */
|
/* Check for 0x10000000000000000. */
|
||||||
if (e->X_op == O_big)
|
if (e->X_op == O_big)
|
||||||
@ -5105,9 +5169,9 @@ operand_match (idesc, index, e)
|
|||||||
&& generic_bignum[2] == 0
|
&& generic_bignum[2] == 0
|
||||||
&& generic_bignum[3] == 0
|
&& generic_bignum[3] == 0
|
||||||
&& generic_bignum[4] == 1)
|
&& generic_bignum[4] == 1)
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
else
|
else
|
||||||
return 0;
|
return OPERAND_OUT_OF_RANGE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
val = e->X_add_number - 1;
|
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)))
|
if ((val >= 0 && (bfd_vma) val < ((bfd_vma) 1 << (bits - 1)))
|
||||||
|| (val < 0 && (bfd_vma) -val <= ((bfd_vma) 1 << (bits - 1))))
|
|| (val < 0 && (bfd_vma) -val <= ((bfd_vma) 1 << (bits - 1))))
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
break;
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
|
||||||
case IA64_OPND_INC3:
|
case IA64_OPND_INC3:
|
||||||
/* +/- 1, 4, 8, 16 */
|
/* +/- 1, 4, 8, 16 */
|
||||||
val = e->X_add_number;
|
val = e->X_add_number;
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
val = -val;
|
val = -val;
|
||||||
if (e->X_op == O_constant
|
if (e->X_op == O_constant)
|
||||||
&& (val == 1 || val == 4 || val == 8 || val == 16))
|
{
|
||||||
return 1;
|
if ((val == 1 || val == 4 || val == 8 || val == 16))
|
||||||
|
return OPERAND_MATCH;
|
||||||
|
else
|
||||||
|
return OPERAND_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IA64_OPND_TGT25:
|
case IA64_OPND_TGT25:
|
||||||
@ -5164,14 +5233,14 @@ operand_match (idesc, index, e)
|
|||||||
fix->expr = *e;
|
fix->expr = *e;
|
||||||
fix->is_pcrel = 1;
|
fix->is_pcrel = 1;
|
||||||
++CURR_SLOT.num_fixups;
|
++CURR_SLOT.num_fixups;
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
}
|
}
|
||||||
case IA64_OPND_TAG13:
|
case IA64_OPND_TAG13:
|
||||||
case IA64_OPND_TAG13b:
|
case IA64_OPND_TAG13b:
|
||||||
switch (e->X_op)
|
switch (e->X_op)
|
||||||
{
|
{
|
||||||
case O_constant:
|
case O_constant:
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
|
|
||||||
case O_symbol:
|
case O_symbol:
|
||||||
fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
|
fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
|
||||||
@ -5183,7 +5252,7 @@ operand_match (idesc, index, e)
|
|||||||
fix->expr = *e;
|
fix->expr = *e;
|
||||||
fix->is_pcrel = 1;
|
fix->is_pcrel = 1;
|
||||||
++CURR_SLOT.num_fixups;
|
++CURR_SLOT.num_fixups;
|
||||||
return 1;
|
return OPERAND_MATCH;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -5193,7 +5262,7 @@ operand_match (idesc, index, e)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return OPERAND_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -5241,8 +5310,9 @@ parse_operands (idesc)
|
|||||||
struct ia64_opcode *idesc;
|
struct ia64_opcode *idesc;
|
||||||
{
|
{
|
||||||
int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0;
|
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 ia64_opnd expected_operand = IA64_OPND_NIL;
|
||||||
|
enum operand_match_result result;
|
||||||
char mnemonic[129];
|
char mnemonic[129];
|
||||||
char *first_arg = 0, *end, *saved_input_pointer;
|
char *first_arg = 0, *end, *saved_input_pointer;
|
||||||
unsigned int sof;
|
unsigned int sof;
|
||||||
@ -5324,6 +5394,8 @@ parse_operands (idesc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
highest_unmatched_operand = 0;
|
highest_unmatched_operand = 0;
|
||||||
|
curr_out_of_range_pos = -1;
|
||||||
|
error_pos = 0;
|
||||||
expected_operand = idesc->operands[0];
|
expected_operand = idesc->operands[0];
|
||||||
for (; idesc; idesc = get_next_opcode (idesc))
|
for (; idesc; idesc = get_next_opcode (idesc))
|
||||||
{
|
{
|
||||||
@ -5331,16 +5403,52 @@ parse_operands (idesc)
|
|||||||
continue; /* mismatch in # of outputs */
|
continue; /* mismatch in # of outputs */
|
||||||
|
|
||||||
CURR_SLOT.num_fixups = 0;
|
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;
|
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];
|
expected_operand = idesc->operands[i];
|
||||||
|
error_pos = i;
|
||||||
|
}
|
||||||
|
curr_out_of_range_pos = out_of_range_pos;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -5355,7 +5463,7 @@ parse_operands (idesc)
|
|||||||
{
|
{
|
||||||
if (expected_operand)
|
if (expected_operand)
|
||||||
as_bad ("Operand %u of `%s' should be %s",
|
as_bad ("Operand %u of `%s' should be %s",
|
||||||
highest_unmatched_operand + 1, mnemonic,
|
error_pos + 1, mnemonic,
|
||||||
elf64_ia64_operands[expected_operand].desc);
|
elf64_ia64_operands[expected_operand].desc);
|
||||||
else
|
else
|
||||||
as_bad ("Operand mismatch");
|
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>
|
2001-02-21 Greg McGary <greg@mcgary.org>
|
||||||
|
|
||||||
* cgen-opc.c (cgen_get_insn_value): Add missing `return'.
|
* 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[] =
|
struct ia64_opcode ia64_opcodes_d[] =
|
||||||
{
|
{
|
||||||
{"add", IA64_TYPE_DYN, 1, 0, 0,
|
{"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}},
|
{"break", IA64_TYPE_DYN, 0, 0, 0, {IA64_OPND_IMMU21}},
|
||||||
{"chk.s", IA64_TYPE_DYN, 0, 0, 0, {IA64_OPND_R2, IA64_OPND_TGT25b}},
|
{"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}},
|
{"mov", IA64_TYPE_DYN, 1, 0, 0, {IA64_OPND_R1, IA64_OPND_AR3}},
|
||||||
|
Loading…
Reference in New Issue
Block a user