[ARC] Add checking for LP_COUNT reg usage, improve error reporting.

gas/
2016-11-29  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/tc-arc.c (find_opcode_match): New function argument
	errmsg.
	(assemble_tokens): Collect and report the eventual error message
	found during opcode matching process.
	* testsuite/gas/arc/lpcount-err.s: New file.
	* testsuite/gas/arc/add_s-err.s: Update error message.

opcode/
2016-11-29  Claudiu Zissulescu  <claziss@synopsys.com>

	* arc-opc.c (insert_ra_chk): New function.
	(insert_rb_chk): Likewise.
	(insert_rad): Update text error message.
	(insert_rcd): Likewise.
	(insert_rhv2): Likewise.
	(insert_r0): Likewise.
	(insert_r1): Likewise.
	(insert_r2): Likewise.
	(insert_r3): Likewise.
	(insert_sp): Likewise.
	(insert_gp): Likewise.
	(insert_pcl): Likewise.
	(insert_blink): Likewise.
	(insert_ilink1): Likewise.
	(insert_ilink2): Likewise.
	(insert_ras): Likewise.
	(insert_rbs): Likewise.
	(insert_rcs): Likewise.
	(insert_simm3s): Likewise.
	(insert_rrange): Likewise.
	(insert_fpel): Likewise.
	(insert_blinkel): Likewise.
	(insert_pcel): Likewise.
	(insert_nps_3bit_dst): Likewise.
	(insert_nps_3bit_dst_short): Likewise.
	(insert_nps_3bit_src2_short): Likewise.
	(insert_nps_bitop_size_2b): Likewise.
	(MAKE_SRC_POS_INSERT_EXTRACT_FUNCS): Likewise.
	(RA_CHK): Define.
	(RB): Adjust.
	(RB_CHK): Define.
	(RC): Adjust.
	* arc-dis.c (print_insn_arc): Add LOAD and STORE class.
	* arc-tbl.h (div, divu): All instructions are DIVREM class.
	Change first insn argument to check for LP_COUNT usage.
	(rem): Likewise.
	(ld, ldd): All instructions are LOAD class.  Change first insn
	argument to check for LP_COUNT usage.
	(st, std): All instructions are STORE class.
	(mac, mpy, dmac, mul, dmpy): All instructions are MPY class.
	Change first insn argument to check for LP_COUNT usage.
	(mov): All instructions are MOVE class.  Change first insn
	argument to check for LP_COUNT usage.

include/
2016-11-29  Claudiu Zissulescu  <claziss@synopsys.com>

	* opcode/arc.h (insn_class_t): Add DIVREM, LOAD, MOVE, MPY, STORE
	instruction classes.
This commit is contained in:
Claudiu Zissulescu 2016-11-15 15:11:47 +01:00
parent ee881e5d33
commit abe7c33b45
10 changed files with 2390 additions and 2280 deletions

View File

@ -1,3 +1,12 @@
2016-11-29 Claudiu Zissulescu <claziss@synopsys.com>
* config/tc-arc.c (find_opcode_match): New function argument
errmsg.
(assemble_tokens): Collect and report the eventual error message
found during opcode matching process.
* testsuite/gas/arc/lpcount-err.s: New file.
* testsuite/gas/arc/add_s-err.s: Update error message.
2016-11-28 Ramiro Polla <ramiro@hex-rays.com>
Amit Pawar <amit.pawar@amd.com>

View File

@ -1710,7 +1710,8 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
int *pntok,
struct arc_flags *first_pflag,
int nflgs,
int *pcpumatch)
int *pcpumatch,
const char **errmsg)
{
const struct arc_opcode *opcode;
struct arc_opcode_hash_entry_iterator iter;
@ -1765,7 +1766,7 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
{
case ARC_OPERAND_ADDRTYPE:
{
const char *errmsg = NULL;
*errmsg = NULL;
/* Check to be an address type. */
if (tok[tokidx].X_op != O_addrtype)
@ -1776,8 +1777,8 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
address type. */
gas_assert (operand->insert != NULL);
(*operand->insert) (0, tok[tokidx].X_add_number,
&errmsg);
if (errmsg != NULL)
errmsg);
if (*errmsg != NULL)
goto match_failed;
}
break;
@ -1803,11 +1804,11 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
/* Special handling? */
if (operand->insert)
{
const char *errmsg = NULL;
*errmsg = NULL;
(*operand->insert)(0,
regno (tok[tokidx].X_add_number),
&errmsg);
if (errmsg)
errmsg);
if (*errmsg)
{
if (operand->flags & ARC_OPERAND_IGNORE)
{
@ -1923,11 +1924,11 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
{
if (operand->insert)
{
const char *errmsg = NULL;
*errmsg = NULL;
(*operand->insert)(0,
tok[tokidx].X_add_number,
&errmsg);
if (errmsg)
errmsg);
if (*errmsg)
goto match_failed;
}
else if (!(operand->flags & ARC_OPERAND_IGNORE))
@ -1948,11 +1949,11 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
regs |= get_register (tok[tokidx].X_op_symbol);
if (operand->insert)
{
const char *errmsg = NULL;
*errmsg = NULL;
(*operand->insert)(0,
regs,
&errmsg);
if (errmsg)
errmsg);
if (*errmsg)
goto match_failed;
}
else
@ -2326,6 +2327,7 @@ assemble_tokens (const char *opname,
bfd_boolean found_something = FALSE;
const struct arc_opcode_hash_entry *entry;
int cpumatch = 1;
const char *errmsg = NULL;
/* Search opcodes. */
entry = arc_find_opcode (opname);
@ -2342,7 +2344,7 @@ assemble_tokens (const char *opname,
frag_now->fr_file, frag_now->fr_line, opname);
found_something = TRUE;
opcode = find_opcode_match (entry, tok, &ntok, pflags,
nflgs, &cpumatch);
nflgs, &cpumatch, &errmsg);
if (opcode != NULL)
{
struct arc_insn insn;
@ -2356,7 +2358,10 @@ assemble_tokens (const char *opname,
if (found_something)
{
if (cpumatch)
as_bad (_("inappropriate arguments for opcode '%s'"), opname);
if (errmsg)
as_bad (_("%s for instruction '%s'"), errmsg, opname);
else
as_bad (_("inappropriate arguments for opcode '%s'"), opname);
else
as_bad (_("opcode '%s' not supported for target %s"), opname,
selected_cpu.name);

View File

@ -4,7 +4,7 @@
; { dg-do assemble { target arc*-*-* } }
; { dg-options "--mcpu=arc700" }
;; The following insns are accepted by ARCv2 only
add_s r4,r4,-1 ; { dg-error "Error: inappropriate arguments for opcode 'add_s'" }
add_s r4,r4,-1 ; { dg-error "Error: Register must be either r0-r3 or r12-r15 for instruction." }
add_s 0,0xAAAA5555,-1 ; { dg-error "Error: inappropriate arguments for opcode 'add_s'" }
add_s r0,r15,0x20 ; { dg-error "Error: inappropriate arguments for opcode 'add_s'" }
add_s r1,r15,0x20 ; { dg-error "Error: inappropriate arguments for opcode 'add_s'" }

View File

@ -0,0 +1,9 @@
;; LP_COUNT register cannot be used with multi-cycle instructions such as:
;; load, lr, multiply and divide.
; { dg-do assemble { target arc*-*-* } }
.cpu HS
mpy lp_count,r0,r1 ; { dg-error "Error: LP_COUNT register cannot be used as destination register." }
ld lp_count,[r2,1] ; { dg-error "Error: LP_COUNT register cannot be used as destination register." }
div lp_count,r12,r1 ; { dg-error "Error: LP_COUNT register cannot be used as destination register." }

View File

@ -1,3 +1,8 @@
2016-11-29 Claudiu Zissulescu <claziss@synopsys.com>
* opcode/arc.h (insn_class_t): Add DIVREM, LOAD, MOVE, MPY, STORE
instruction classes.
2016-11-22 Jose E. Marchesi <jose.marchesi@oracle.com>
* opcode/sparc.h (sparc_opcode_arch): New fields hwcaps and

View File

@ -47,17 +47,22 @@ typedef enum
BMU,
BRANCH,
CONTROL,
DIVREM,
DPI,
DSP,
FLOAT,
INVALID,
JUMP,
KERNEL,
LOAD,
LOGICAL,
MEMORY,
MOVE,
MPY,
NET,
PROTOCOL_DECODE,
PMU,
STORE,
XY
} insn_class_t;

View File

@ -1,3 +1,49 @@
2016-11-29 Claudiu Zissulescu <claziss@synopsys.com>
* arc-opc.c (insert_ra_chk): New function.
(insert_rb_chk): Likewise.
(insert_rad): Update text error message.
(insert_rcd): Likewise.
(insert_rhv2): Likewise.
(insert_r0): Likewise.
(insert_r1): Likewise.
(insert_r2): Likewise.
(insert_r3): Likewise.
(insert_sp): Likewise.
(insert_gp): Likewise.
(insert_pcl): Likewise.
(insert_blink): Likewise.
(insert_ilink1): Likewise.
(insert_ilink2): Likewise.
(insert_ras): Likewise.
(insert_rbs): Likewise.
(insert_rcs): Likewise.
(insert_simm3s): Likewise.
(insert_rrange): Likewise.
(insert_fpel): Likewise.
(insert_blinkel): Likewise.
(insert_pcel): Likewise.
(insert_nps_3bit_dst): Likewise.
(insert_nps_3bit_dst_short): Likewise.
(insert_nps_3bit_src2_short): Likewise.
(insert_nps_bitop_size_2b): Likewise.
(MAKE_SRC_POS_INSERT_EXTRACT_FUNCS): Likewise.
(RA_CHK): Define.
(RB): Adjust.
(RB_CHK): Define.
(RC): Adjust.
* arc-dis.c (print_insn_arc): Add LOAD and STORE class.
* arc-tbl.h (div, divu): All instructions are DIVREM class.
Change first insn argument to check for LP_COUNT usage.
(rem): Likewise.
(ld, ldd): All instructions are LOAD class. Change first insn
argument to check for LP_COUNT usage.
(st, std): All instructions are STORE class.
(mac, mpy, dmac, mul, dmpy): All instructions are MPY class.
Change first insn argument to check for LP_COUNT usage.
(mov): All instructions are MOVE class. Change first insn
argument to check for LP_COUNT usage.
2016-11-29 Claudiu Zissulescu <claziss@synopsys.com>
* arc-dis.c (is_compatible_p): Remove function.

View File

@ -750,8 +750,10 @@ arc_opcode_to_insn_type (const struct arc_opcode *opcode)
insn_type = dis_branch;
}
break;
case LOAD:
case STORE:
case MEMORY:
insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
insn_type = dis_dref;
break;
default:
insn_type = dis_nonbranch;

View File

@ -30,6 +30,17 @@
instructions. All NPS400 features are built into all ARC target builds as
this reduces the chances that regressions might creep in. */
/* Insert RA register into a 32-bit opcode, with checks. */
static unsigned long long
insert_ra_chk (unsigned long long insn,
long long int value,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value == 60)
*errmsg = _("LP_COUNT register cannot be used as destination register");
return insn | (value & 0x3F);
}
/* Insert RB register into a 32-bit opcode. */
static unsigned long long
insert_rb (unsigned long long insn,
@ -39,6 +50,18 @@ insert_rb (unsigned long long insn,
return insn | ((value & 0x07) << 24) | (((value >> 3) & 0x07) << 12);
}
/* Insert RB register with checks. */
static unsigned long long
insert_rb_chk (unsigned long long insn,
long long int value,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value == 60)
*errmsg = _("LP_COUNT register cannot be used as destination register");
return insn | ((value & 0x07) << 24) | (((value >> 3) & 0x07) << 12);
}
static long long int
extract_rb (unsigned long long insn ATTRIBUTE_UNUSED,
bfd_boolean * invalid ATTRIBUTE_UNUSED)
@ -58,7 +81,9 @@ insert_rad (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value & 0x01)
*errmsg = _("Improper register value.");
*errmsg = _("cannot use odd number destination register");
if (value == 60)
*errmsg = _("LP_COUNT register cannot be used as destination register");
return insn | (value & 0x3F);
}
@ -69,7 +94,7 @@ insert_rcd (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value & 0x01)
*errmsg = _("Improper register value.");
*errmsg = _("cannot use odd number source register");
return insn | ((value & 0x3F) << 6);
}
@ -142,7 +167,7 @@ insert_rhv2 (unsigned long long insn,
{
if (value == 0x1E)
*errmsg =
_("Register R30 is a limm indicator for this type of instruction.");
_("Register R30 is a limm indicator");
return insn |= ((value & 0x07) << 5) | ((value >> 3) & 0x03);
}
@ -161,7 +186,7 @@ insert_r0 (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 0)
*errmsg = _("Register must be R0.");
*errmsg = _("Register must be R0");
return insn;
}
@ -179,7 +204,7 @@ insert_r1 (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 1)
*errmsg = _("Register must be R1.");
*errmsg = _("Register must be R1");
return insn;
}
@ -196,7 +221,7 @@ insert_r2 (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 2)
*errmsg = _("Register must be R2.");
*errmsg = _("Register must be R2");
return insn;
}
@ -213,7 +238,7 @@ insert_r3 (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 3)
*errmsg = _("Register must be R3.");
*errmsg = _("Register must be R3");
return insn;
}
@ -230,7 +255,7 @@ insert_sp (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 28)
*errmsg = _("Register must be SP.");
*errmsg = _("Register must be SP");
return insn;
}
@ -247,7 +272,7 @@ insert_gp (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 26)
*errmsg = _("Register must be GP.");
*errmsg = _("Register must be GP");
return insn;
}
@ -264,7 +289,7 @@ insert_pcl (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 63)
*errmsg = _("Register must be PCL.");
*errmsg = _("Register must be PCL");
return insn;
}
@ -281,7 +306,7 @@ insert_blink (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 31)
*errmsg = _("Register must be BLINK.");
*errmsg = _("Register must be BLINK");
return insn;
}
@ -298,7 +323,7 @@ insert_ilink1 (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 29)
*errmsg = _("Register must be ILINK1.");
*errmsg = _("Register must be ILINK1");
return insn;
}
@ -315,7 +340,7 @@ insert_ilink2 (unsigned long long insn,
const char **errmsg ATTRIBUTE_UNUSED)
{
if (value != 30)
*errmsg = _("Register must be ILINK2.");
*errmsg = _("Register must be ILINK2");
return insn;
}
@ -346,7 +371,7 @@ insert_ras (unsigned long long insn,
insn |= (value - 8);
break;
default:
*errmsg = _("Register must be either r0-r3 or r12-r15.");
*errmsg = _("Register must be either r0-r3 or r12-r15");
break;
}
return insn;
@ -383,7 +408,7 @@ insert_rbs (unsigned long long insn,
insn |= ((value - 8)) << 8;
break;
default:
*errmsg = _("Register must be either r0-r3 or r12-r15.");
*errmsg = _("Register must be either r0-r3 or r12-r15");
break;
}
return insn;
@ -420,7 +445,7 @@ insert_rcs (unsigned long long insn,
insn |= ((value - 8)) << 5;
break;
default:
*errmsg = _("Register must be either r0-r3 or r12-r15.");
*errmsg = _("Register must be either r0-r3 or r12-r15");
break;
}
return insn;
@ -470,7 +495,7 @@ insert_simm3s (unsigned long long insn,
tmp = 0x06;
break;
default:
*errmsg = _("Accepted values are from -1 to 6.");
*errmsg = _("Accepted values are from -1 to 6");
break;
}
@ -498,12 +523,12 @@ insert_rrange (unsigned long long insn,
int reg2 = value & 0xFFFF;
if (reg1 != 13)
{
*errmsg = _("First register of the range should be r13.");
*errmsg = _("First register of the range should be r13");
return insn;
}
if (reg2 < 13 || reg2 > 26)
{
*errmsg = _("Last register of the range doesn't fit.");
*errmsg = _("Last register of the range doesn't fit");
return insn;
}
insn |= ((reg2 - 12) & 0x0F) << 1;
@ -524,7 +549,7 @@ insert_fpel (unsigned long long insn,
{
if (value != 27)
{
*errmsg = _("Invalid register number, should be fp.");
*errmsg = _("Invalid register number, should be fp");
return insn;
}
@ -546,7 +571,7 @@ insert_blinkel (unsigned long long insn,
{
if (value != 31)
{
*errmsg = _("Invalid register number, should be blink.");
*errmsg = _("Invalid register number, should be blink");
return insn;
}
@ -568,7 +593,7 @@ insert_pclel (unsigned long long insn,
{
if (value != 63)
{
*errmsg = _("Invalid register number, should be pcl.");
*errmsg = _("Invalid register number, should be pcl");
return insn;
}
@ -664,7 +689,7 @@ insert_nps_3bit_reg_at_##OFFSET##_##NAME \
insn |= (value - 8) << (OFFSET); \
break; \
default: \
*errmsg = _("Register must be either r0-r3 or r12-r15."); \
*errmsg = _("Register must be either r0-r3 or r12-r15"); \
break; \
} \
return insn; \
@ -712,7 +737,7 @@ insert_nps_bitop_size_2b (unsigned long long insn ATTRIBUTE_UNUSED,
break;
default:
value = 0;
*errmsg = _("Invalid size, should be 1, 2, 4, or 8.");
*errmsg = _("Invalid size, should be 1, 2, 4, or 8");
break;
}
@ -822,7 +847,7 @@ insert_nps_##NAME##_pos (unsigned long long insn ATTRIBUTE_UNUSED, \
value = value / 8; \
break; \
default: \
*errmsg = _("Invalid position, should be 0, 8, 16, or 24."); \
*errmsg = _("Invalid position, should be 0, 8, 16, or 24"); \
value = 0; \
} \
insn |= (value << SHIFT); \
@ -1529,9 +1554,13 @@ const struct arc_operand arc_operands[] =
instructions. */
#define RA (IGNORED + 1)
{ 6, 0, 0, ARC_OPERAND_IR, 0, 0 },
#define RB (RA + 1)
#define RA_CHK (RA + 1)
{ 6, 0, 0, ARC_OPERAND_IR, insert_ra_chk, 0 },
#define RB (RA_CHK + 1)
{ 6, 12, 0, ARC_OPERAND_IR, insert_rb, extract_rb },
#define RC (RB + 1)
#define RB_CHK (RB + 1)
{ 6, 12, 0, ARC_OPERAND_IR, insert_rb_chk, extract_rb },
#define RC (RB_CHK + 1)
{ 6, 6, 0, ARC_OPERAND_IR, 0, 0 },
#define RBdup (RC + 1)
{ 6, 12, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, insert_rb, extract_rb },

File diff suppressed because it is too large Load Diff