Add support for .extInstruction pseudo-op.

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

	* testsuite/gas/arc/textinsn-errors.d: New File.
	* testsuite/gas/arc/textinsn-errors.err: Likewise.
	* testsuite/gas/arc/textinsn-errors.s: Likewise.
	* testsuite/gas/arc/textinsn2op.d: Likewise.
	* testsuite/gas/arc/textinsn2op.s: Likewise.
	* testsuite/gas/arc/textinsn2op01.d: Likewise.
	* testsuite/gas/arc/textinsn2op01.s: Likewise.
	* testsuite/gas/arc/textinsn3op.d: Likewise.
	* testsuite/gas/arc/textinsn3op.s: Likewise.
	* doc/c-arc.texi (ARC Directives): Add .extInstruction
	documentation.
	* config/tc-arc.c (arcext_section): New variable.
	(arc_extinsn): New function.
	(md_pseudo_table): Add .extInstruction pseudo op.
	(attributes_t): New type.
	(suffixclass, syntaxclass, syntaxclassmod): New constant
	structures.
	(find_opcode_match): Remove arc_num_opcodes.
	(md_begin): Likewise.
	(tokenize_extinsn): New function.
	(arc_set_ext_seg): Likewise.
	(create_extinst_section): Likewise.

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

	* opcode/arc.h (arc_num_opcodes): Remove.
	(ARC_SYNTAX_3OP, ARC_SYNTAX_2OP, ARC_OP1_MUST_BE_IMM)
	(ARC_OP1_IMM_IMPLIED, ARC_SUFFIX_NONE, ARC_SUFFIX_COND)
	(ARC_SUFFIX_FLAG): Define.
	(flags_none, flags_f, flags_cc, flags_ccf): Declare.
	(arg_none, arg_32bit_rarbrc, arg_32bit_zarbrc, arg_32bit_rbrbrc)
	(arg_32bit_rarbu6, arg_32bit_zarbu6, arg_32bit_rbrbu6)
	(arg_32bit_rbrbs12, arg_32bit_ralimmrc, arg_32bit_rarblimm)
	(arg_32bit_zalimmrc, arg_32bit_zarblimm, arg_32bit_rbrblimm)
	(arg_32bit_ralimmu6, arg_32bit_zalimmu6, arg_32bit_zalimms12)
	(arg_32bit_ralimmlimm, arg_32bit_zalimmlimm, arg_32bit_rbrc)
	(arg_32bit_zarc, arg_32bit_rbu6, arg_32bit_zau6, arg_32bit_rblimm)
	(arg_32bit_zalimm, arg_32bit_limmrc, arg_32bit_limmu6)
	(arg_32bit_limms12, arg_32bit_limmlimm): Likewise.

opcodes/
2016-04-04  Claudiu Zissulescu  <claziss@synopsys.com>

	* arc-opc.c (flags_none, flags_f, flags_cc, flags_ccf):
	Initialize.
	(arg_none, arg_32bit_rarbrc, arg_32bit_zarbrc, arg_32bit_rbrbrc)
	(arg_32bit_rarbu6, arg_32bit_zarbu6, arg_32bit_rbrbu6)
	(arg_32bit_rbrbs12, arg_32bit_ralimmrc, arg_32bit_rarblimm)
	(arg_32bit_zalimmrc, arg_32bit_zarblimm, arg_32bit_rbrblimm)
	(arg_32bit_ralimmu6, arg_32bit_zalimmu6, arg_32bit_zalimms12)
	(arg_32bit_ralimmlimm, arg_32bit_zalimmlimm, arg_32bit_rbrc)
	(arg_32bit_zarc, arg_32bit_rbu6, arg_32bit_zau6, arg_32bit_rblimm)
	(arg_32bit_zalimm, arg_32bit_limmrc, arg_32bit_limmu6)
	(arg_32bit_limms12, arg_32bit_limmlimm): Likewise.
	(arc_opcode arc_opcodes): Null terminate the array.
	(arc_num_opcodes): Remove.
	* arc-ext.h (INSERT_XOP): Define.
	(extInstruction_t): Likewise.
	(arcExtMap_instName): Delete.
	(arcExtMap_insn): New function.
	(arcExtMap_genOpcode): Likewise.
	* arc-ext.c (ExtInstruction): Remove.
	(create_map): Zero initialize instruction fields.
	(arcExtMap_instName): Remove.
	(arcExtMap_insn): New function.
	(dump_ARC_extmap): More info while debuging.
	(arcExtMap_genOpcode): New function.
	* arc-dis.c (find_format): New function.
	(print_insn_arc): Use find_format.
	(arc_get_disassembler): Enable dump_ARC_extmap only when
	debugging.

Signed-off-by: Claudiu Zissulescu <claziss@synopsys.com>
This commit is contained in:
Claudiu Zissulescu 2016-04-04 16:03:53 +02:00
parent 37ab977937
commit b99747aeed
19 changed files with 1341 additions and 200 deletions

View File

@ -1,3 +1,28 @@
2016-04-12 Claudiu Zissulescu <claziss@synopsys.com>
* testsuite/gas/arc/textinsn-errors.d: New File.
* testsuite/gas/arc/textinsn-errors.err: Likewise.
* testsuite/gas/arc/textinsn-errors.s: Likewise.
* testsuite/gas/arc/textinsn2op.d: Likewise.
* testsuite/gas/arc/textinsn2op.s: Likewise.
* testsuite/gas/arc/textinsn2op01.d: Likewise.
* testsuite/gas/arc/textinsn2op01.s: Likewise.
* testsuite/gas/arc/textinsn3op.d: Likewise.
* testsuite/gas/arc/textinsn3op.s: Likewise.
* doc/c-arc.texi (ARC Directives): Add .extInstruction
documentation.
* config/tc-arc.c (arcext_section): New variable.
(arc_extinsn): New function.
(md_pseudo_table): Add .extInstruction pseudo op.
(attributes_t): New type.
(suffixclass, syntaxclass, syntaxclassmod): New constant
structures.
(find_opcode_match): Remove arc_num_opcodes.
(md_begin): Likewise.
(tokenize_extinsn): New function.
(arc_set_ext_seg): Likewise.
(create_extinst_section): Likewise.
2016-04-12 Claudiu Zissulescu <claziss@synopsys.com>
* config/tc-arc.c (preprocess_operands): Mark AUX symbol.

View File

@ -29,6 +29,7 @@
#include "opcode/arc.h"
#include "elf/arc.h"
#include "../opcodes/arc-ext.h"
/* Defines section. */
@ -126,6 +127,9 @@ extern int target_big_endian;
const char *arc_target_format = DEFAULT_TARGET_FORMAT;
static int byte_order = DEFAULT_BYTE_ORDER;
/* Arc extension section. */
static segT arcext_section;
/* By default relaxation is disabled. */
static int relaxation_state = 0;
@ -135,7 +139,7 @@ extern int arc_get_mach (char *);
static void arc_lcomm (int);
static void arc_option (int);
static void arc_extra_reloc (int);
static void arc_extinsn (int);
const pseudo_typeS md_pseudo_table[] =
{
@ -147,6 +151,8 @@ const pseudo_typeS md_pseudo_table[] =
{ "lcommon", arc_lcomm, 0 },
{ "cpu", arc_option, 0 },
{ "extinstruction", arc_extinsn, 0 },
{ "tls_gd_ld", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_LD },
{ "tls_gd_call", arc_extra_reloc, BFD_RELOC_ARC_TLS_GD_CALL },
@ -308,6 +314,35 @@ static struct arc_last_insn
bfd_boolean has_delay_slot;
} arc_last_insns[2];
/* Extension instruction suffix classes. */
typedef struct
{
const char *name;
int len;
int class;
} attributes_t;
static const attributes_t suffixclass[] =
{
{ "SUFFIX_FLAG", 11, ARC_SUFFIX_FLAG },
{ "SUFFIX_COND", 11, ARC_SUFFIX_COND },
{ "SUFFIX_NONE", 11, ARC_SUFFIX_NONE }
};
/* Extension instruction syntax classes. */
static const attributes_t syntaxclass[] =
{
{ "SYNTAX_3OP", 10, ARC_SYNTAX_3OP },
{ "SYNTAX_2OP", 10, ARC_SYNTAX_2OP }
};
/* Extension instruction syntax classes modifiers. */
static const attributes_t syntaxclassmod[] =
{
{ "OP1_IMM_IMPLIED" , 15, ARC_OP1_IMM_IMPLIED },
{ "OP1_MUST_BE_IMM" , 15, ARC_OP1_MUST_BE_IMM }
};
/* Structure to hold an entry in ARC_OPCODE_HASH. */
struct arc_opcode_hash_entry
{
@ -615,8 +650,8 @@ arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry,
const char *old_name = iter->opcode->name;
iter->opcode++;
if ((iter->opcode - arc_opcodes >= (int) arc_num_opcodes)
|| (strcmp (old_name, iter->opcode->name) != 0))
if (iter->opcode->name
&& (strcmp (old_name, iter->opcode->name) != 0))
{
iter->index++;
if (iter->index == entry->count)
@ -629,6 +664,40 @@ arc_opcode_hash_entry_iterator_next (const struct arc_opcode_hash_entry *entry,
return iter->opcode;
}
/* Insert an opcode into opcode hash structure. */
static void
arc_insert_opcode (const struct arc_opcode *opcode)
{
const char *name, *retval;
struct arc_opcode_hash_entry *entry;
name = opcode->name;
entry = hash_find (arc_opcode_hash, name);
if (entry == NULL)
{
entry = xmalloc (sizeof (*entry));
entry->count = 0;
entry->opcode = NULL;
retval = hash_insert (arc_opcode_hash, name, (void *) entry);
if (retval)
as_fatal (_("internal error: can't hash opcode '%s': %s"),
name, retval);
}
entry->opcode = xrealloc (entry->opcode,
sizeof (const struct arc_opcode *)
* (entry->count + 1));
if (entry->opcode == NULL)
as_fatal (_("Virtual memory exhausted"));
entry->opcode[entry->count] = opcode;
entry->count++;
}
/* Like md_number_to_chars but used for limms. The 4-byte limm value,
is encoded as 'middle-endian' for a little-endian target. FIXME!
this function is used for regular 4 byte instructions as well. */
@ -1611,7 +1680,7 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
from BKTOK. */
tok[tokidx].X_op = O_constant;
tok[tokidx].X_add_number = auxr->address;
ARC_SET_FLAG (tok[i].X_add_symbol, ARC_FLAG_AUX);
ARC_SET_FLAG (tok[tokidx].X_add_symbol, ARC_FLAG_AUX);
break;
}
@ -2218,7 +2287,7 @@ declare_register_set (void)
void
md_begin (void)
{
unsigned int i;
const struct arc_opcode *opcode = arc_opcodes;
if (!mach_type_specified_p)
arc_select_cpu ("arc700");
@ -2238,37 +2307,17 @@ md_begin (void)
as_fatal (_("Virtual memory exhausted"));
/* Initialize the hash table with the insns. */
for (i = 0; i < arc_num_opcodes;)
do
{
const char *name, *retval;
struct arc_opcode_hash_entry *entry;
const char *name = opcode->name;
name = arc_opcodes[i].name;
arc_insert_opcode (opcode);
entry = hash_find (arc_opcode_hash, name);
if (entry == NULL)
{
entry = xmalloc (sizeof (*entry));
entry->count = 0;
entry->opcode = NULL;
retval = hash_insert (arc_opcode_hash, name, (void *) entry);
if (retval)
as_fatal (_("internal error: can't hash opcode '%s': %s"),
name, retval);
}
entry->opcode = xrealloc (entry->opcode,
sizeof (const struct arc_opcode *)
* entry->count + 1);
entry->opcode [entry->count] = &arc_opcodes[i];
entry->count++;
while (++i < arc_num_opcodes
&& (arc_opcodes[i].name == name
|| !strcmp (arc_opcodes[i].name, name)))
while (++opcode && opcode->name
&& (opcode->name == name
|| !strcmp (opcode->name, name)))
continue;
}
}while (opcode->name);
/* Register declaration. */
arc_reg_hash = hash_new ();
@ -3877,3 +3926,275 @@ arc_adjust_symtab (void)
/* Now do generic ELF adjustments. */
elf_adjust_symtab ();
}
static void
tokenize_extinsn (extInstruction_t *einsn)
{
char *p, c;
char *insn_name;
unsigned char major_opcode;
unsigned char sub_opcode;
unsigned char syntax_class = 0;
unsigned char syntax_class_modifiers = 0;
unsigned char suffix_class = 0;
unsigned int i;
SKIP_WHITESPACE ();
/* 1st: get instruction name. */
p = input_line_pointer;
c = get_symbol_name (&p);
insn_name = xstrdup (p);
restore_line_pointer (c);
/* 2nd: get major opcode. */
if (*input_line_pointer != ',')
{
as_bad (_("expected comma after instruction name"));
ignore_rest_of_line ();
return;
}
input_line_pointer++;
major_opcode = get_absolute_expression ();
/* 3rd: get sub-opcode. */
SKIP_WHITESPACE ();
if (*input_line_pointer != ',')
{
as_bad (_("expected comma after major opcode"));
ignore_rest_of_line ();
return;
}
input_line_pointer++;
sub_opcode = get_absolute_expression ();
/* 4th: get suffix class. */
SKIP_WHITESPACE ();
if (*input_line_pointer != ',')
{
as_bad ("expected comma after sub opcode");
ignore_rest_of_line ();
return;
}
input_line_pointer++;
while (1)
{
SKIP_WHITESPACE ();
for (i = 0; i < ARRAY_SIZE (suffixclass); i++)
{
if (!strncmp (suffixclass[i].name, input_line_pointer,
suffixclass[i].len))
{
suffix_class |= suffixclass[i].class;
input_line_pointer += suffixclass[i].len;
break;
}
}
if (i == ARRAY_SIZE (suffixclass))
{
as_bad ("invalid suffix class");
ignore_rest_of_line ();
return;
}
SKIP_WHITESPACE ();
if (*input_line_pointer == '|')
input_line_pointer++;
else
break;
}
/* 5th: get syntax class and syntax class modifiers. */
if (*input_line_pointer != ',')
{
as_bad ("expected comma after suffix class");
ignore_rest_of_line ();
return;
}
input_line_pointer++;
while (1)
{
SKIP_WHITESPACE ();
for (i = 0; i < ARRAY_SIZE (syntaxclassmod); i++)
{
if (!strncmp (syntaxclassmod[i].name,
input_line_pointer,
syntaxclassmod[i].len))
{
syntax_class_modifiers |= syntaxclassmod[i].class;
input_line_pointer += syntaxclassmod[i].len;
break;
}
}
if (i == ARRAY_SIZE (syntaxclassmod))
{
for (i = 0; i < ARRAY_SIZE (syntaxclass); i++)
{
if (!strncmp (syntaxclass[i].name,
input_line_pointer,
syntaxclass[i].len))
{
syntax_class |= syntaxclass[i].class;
input_line_pointer += syntaxclass[i].len;
break;
}
}
if (i == ARRAY_SIZE (syntaxclass))
{
as_bad ("missing syntax class");
ignore_rest_of_line ();
return;
}
}
SKIP_WHITESPACE ();
if (*input_line_pointer == '|')
input_line_pointer++;
else
break;
}
demand_empty_rest_of_line ();
einsn->name = insn_name;
einsn->major = major_opcode;
einsn->minor = sub_opcode;
einsn->syntax = syntax_class;
einsn->modsyn = syntax_class_modifiers;
einsn->suffix = suffix_class;
einsn->flags = syntax_class
| (syntax_class_modifiers & ARC_OP1_IMM_IMPLIED ? 0x10 : 0);
}
/* Generate an extension section. */
static int
arc_set_ext_seg (void)
{
if (!arcext_section)
{
arcext_section = subseg_new (".arcextmap", 0);
bfd_set_section_flags (stdoutput, arcext_section,
SEC_READONLY | SEC_HAS_CONTENTS);
}
else
subseg_set (arcext_section, 0);
return 1;
}
/* Create an extension instruction description in the arc extension
section of the output file.
The structure for an instruction is like this:
[0]: Length of the record.
[1]: Type of the record.
[2]: Major opcode.
[3]: Sub-opcode.
[4]: Syntax (flags).
[5]+ Name instruction.
The sequence is terminated by an empty entry. */
static void
create_extinst_section (extInstruction_t *einsn)
{
segT old_sec = now_seg;
int old_subsec = now_subseg;
char *p;
int name_len = strlen (einsn->name);
arc_set_ext_seg ();
p = frag_more (1);
*p = 5 + name_len + 1;
p = frag_more (1);
*p = EXT_INSTRUCTION;
p = frag_more (1);
*p = einsn->major;
p = frag_more (1);
*p = einsn->minor;
p = frag_more (1);
*p = einsn->flags;
p = frag_more (name_len + 1);
strcpy (p, einsn->name);
subseg_set (old_sec, old_subsec);
}
/* Handler .extinstruction pseudo-op. */
static void
arc_extinsn (int ignore ATTRIBUTE_UNUSED)
{
extInstruction_t einsn;
struct arc_opcode *arc_ext_opcodes;
const char *errmsg = NULL;
unsigned char moplow, mophigh;
memset (&einsn, 0, sizeof (einsn));
tokenize_extinsn (&einsn);
/* Check if the name is already used. */
if (arc_find_opcode (einsn.name))
as_warn (_("Pseudocode already used %s"), einsn.name);
/* Check the opcode ranges. */
moplow = 0x05;
mophigh = (arc_target & (ARC_OPCODE_ARCv2EM
| ARC_OPCODE_ARCv2HS)) ? 0x07 : 0x0a;
if ((einsn.major > mophigh) || (einsn.major < moplow))
as_fatal (_("major opcode not in range [0x%02x - 0x%02x]"), moplow, mophigh);
if ((einsn.minor > 0x3f) && (einsn.major != 0x0a)
&& (einsn.major != 5) && (einsn.major != 9))
as_fatal (_("minor opcode not in range [0x00 - 0x3f]"));
switch (einsn.syntax & (ARC_SYNTAX_3OP | ARC_SYNTAX_2OP))
{
case ARC_SYNTAX_3OP:
if (einsn.modsyn & ARC_OP1_IMM_IMPLIED)
as_fatal (_("Improper use of OP1_IMM_IMPLIED"));
break;
case ARC_SYNTAX_2OP:
if (einsn.modsyn & ARC_OP1_MUST_BE_IMM)
as_fatal (_("Improper use of OP1_MUST_BE_IMM"));
break;
default:
break;
}
arc_ext_opcodes = arcExtMap_genOpcode (&einsn, arc_target, &errmsg);
if (arc_ext_opcodes == NULL)
{
if (errmsg)
as_fatal ("%s", errmsg);
else
as_fatal (_("Couldn't generate extension instruction opcodes"));
}
else if (errmsg)
as_warn ("%s", errmsg);
/* Insert the extension instruction. */
arc_insert_opcode ((const struct arc_opcode *) arc_ext_opcodes);
create_extinst_section (&einsn);
}
/* Local variables:
eval: (c-set-style "gnu")
indent-tabs-mode: t
End: */

View File

@ -320,7 +320,7 @@ machine directives:
@table @code
@cindex @code{lcomm} directive
@item .lcomm @var{symbol} , @var{length}[, @var{alignment}]
@item .lcomm @var{symbol}, @var{length}[, @var{alignment}]
Reserve @var{length} (an absolute expression) bytes for a local common
denoted by @var{symbol}. The section and value of @var{symbol} are
those of the new local common. The addresses are allocated in the bss
@ -336,11 +336,11 @@ largest power of two less than or equal to the size of the symbol, up
to a maximum of 16.
@cindex @code{lcommon} directive
@item .lcommon @var{symbol} , @var{length}[, @var{alignment}]
@item .lcommon @var{symbol}, @var{length}[, @var{alignment}]
The same as @code{lcomm} directive.
@cindex @code{cpu} directive, ARC
@cindex @code{cpu} directive, ARC
@cindex @code{cpu} directive
@item .cpu @var{cpu}
The @code{.cpu} directive must be followed by the desired core
version. Permitted values for CPU are:
@table @code
@ -361,6 +361,93 @@ Assemble for the ARC HS instruction set.
Note: the @code{.cpu} directive overrides the command line option
@code{-mcpu=@var{cpu}}; a warning is emitted when the version is not
consistent between the two.
@item .extInstruction @var{name}, @var{opcode}, @var{subopcode}, @var{suffixclass}, @var{syntaxclass}
@cindex @code{extInstruction} directive
ARC allows the user to specify extension instructions. These
extension instructions are not macros; the assembler creates encodings
for use of these instructions according to the specification by the
user.
The first argument, @var{name}, gives the name of the instruction.
The second argument, @var{opcode}, is the opcode to be used (bits 31:27
in the encoding).
The third argument, @var{subopcode}, is the sub-opcode to be used, but
the correct value also depends on the fifth argument,
@var{syntaxclass}
The fourth argument, @var{suffixclass}, determines the kinds of
suffixes to be allowed. Valid values are:
@table @code
@item SUFFIX_NONE
No suffixes are permitted;
@item SUFFIX_COND
Conditional suffixes are permitted;
@item SUFFIX_FLAG
Flag setting suffixes are permitted.
@item SUFFIX_COND|SUFFIX_FLAG
Both conditional and flag setting suffices are permitted.
@end table
The fifth and final argument, @var{syntaxclass}, determines the syntax
class for the instruction. It can have the following values:
@table @code
@item SYNTAX_2OP
Two Operand Instruction;
@item SYNTAX_3OP
Three Operand Instruction.
@end table
The syntax class may be followed by @samp{|} and one of the following
modifiers.
@table @code
@item OP1_MUST_BE_IMM
Modifies syntax class @code{SYNTAX_3OP}, specifying that the first
operand of a three-operand instruction must be an immediate (i.e., the
result is discarded). This is usually used to set the flags using
specific instructions and not retain results.
@item OP1_IMM_IMPLIED
Modifies syntax class @code{SYNTAX_20P}, specifying that there is an
implied immediate destination operand which does not appear in the
syntax.
For example, if the source code contains an instruction like:
@example
inst r1,r2
@end example
the first argument is an implied immediate (that is, the result is
discarded). This is the same as though the source code were: inst
0,r1,r2.
@end table
For example, defining a 64-bit multiplier with immediate operands:
@example
.extInstruction mp64, 0x07, 0x2d, SUFFIX_COND|SUFFIX_FLAG,
SYNTAX_3OP|OP1_MUST_BE_IMM
@end example
which specifies an extension instruction named @code{mp64} with 3
operands. It sets the flags and can be used with a condition code,
for which the first operand is an immediate, i.e. equivalent to
discarding the result of the operation.
A two operands instruction variant would be:
@example
.extInstruction mul64, 0x07, 0x2d, SUFFIX_COND,
SYNTAX_2OP|OP1_IMM_IMPLIED
@end example
which describes a two operand instruction with an implicit first
immediate operand. The result of this operation would be discarded.
@end table
@node ARC Modifiers

View File

@ -0,0 +1 @@
#error-output: textinsn-errors.err

View File

@ -0,0 +1,2 @@
[^:]*: Assembler messages:
[^:]*:1: Warning: Suffix SUFFIX_COND ignored

View File

@ -0,0 +1 @@
.extInstruction myinsn0, 0x07, 0x2d, SUFFIX_FLAG|SUFFIX_COND, SYNTAX_2OP

View File

@ -0,0 +1,24 @@
#objdump: -dr
.*: +file format .*arc.*
Disassembly of section .text:
[0-9a-f]+ <.text>:
0: 382f 006d myinsn r0,r1
4: 3b2f 372d myinsn fp,sp
8: 386f 002d myinsn r0,0
c: 392f 0fad ffff ffff myinsn r1,0xffffffff
14: 3e2f 70ad myinsn 0,r2
18: 3c2f 0fad 0000 00ff myinsn r4,0xff
20: 3e2f 0fad ffff ff00 myinsn r6,0xffffff00
28: 382f 1fad 0000 0100 myinsn r8,0x100
30: 392f 1fad ffff feff myinsn r9,0xfffffeff
38: 3b2f 1fad 4242 4242 myinsn r11,0x42424242
40: 382f 0fad 0000 0000 myinsn r0,0
44: R_ARC_32_ME foo
48: 382f 806d myinsn.f r0,r1
4c: 3a6f 806d myinsn.f r2,0x1
50: 3e2f f12d myinsn.f 0,r4
54: 3d2f 8fad 0000 0200 myinsn.f r5,0x200

View File

@ -0,0 +1,22 @@
# Insn 3 .extInstruction test
.extInstruction myinsn, 0x07, 0x2d, SUFFIX_FLAG, SYNTAX_2OP
myinsn r0,r1
myinsn fp,sp
myinsn r0,0
myinsn r1,-1
myinsn 0,r2
myinsn r4,255
myinsn r6,-256
myinsn r8,256
myinsn r9,-257
myinsn r11,0x42424242
myinsn r0,foo
myinsn.f r0,r1
myinsn.f r2,1
myinsn.f 0,r4
myinsn.f r5,512

View File

@ -0,0 +1,27 @@
#objdump: -dr
.*: +file format .*arc.*
Disassembly of section .text:
[0-9a-f]+ <.text>:
0: 382d 007e myinsn r0,r1
4: 3b2d 373e myinsn fp,sp
8: 386d 003e myinsn r0,0
c: 392d 0fbe ffff ffff myinsn r1,0xffffffff
14: 3eed 7080 0000 0000 myinsn 0,r2
1c: 3c2d 0fbe 0000 00ff myinsn r4,0xff
24: 3e2d 0fbe ffff ff00 myinsn r6,0xffffff00
2c: 382d 1fbe 0000 0100 myinsn r8,0x100
34: 392d 1fbe ffff feff myinsn r9,0xfffffeff
3c: 3b2d 1fbe 4242 4242 myinsn r11,0x42424242
44: 382d 0fbe 0000 0000 myinsn r0,0
48: R_ARC_32_ME foo
4c: 382d 807e myinsn.f r0,r1
50: 3a6d 807e myinsn.f r2,0x1
54: 3eed f100 0000 0000 myinsn.f 0,r4
5c: 3d2d 8fbe 0000 0200 myinsn.f r5,0x200
64: 3eed f102 0000 0000 myinsn.ne.f 0,r4
6c: 3eed ff85 dead beef myinsn.c.f 0xdeadbeef,0xdeadbeef
74: 3eed f0a6 dead beef myinsn.nc.f 0xdeadbeef,0x2

View File

@ -0,0 +1,26 @@
# Insn 2op .extInstruction test
.extInstruction myinsn, 0x07, 0x2d, SUFFIX_FLAG|SUFFIX_COND, SYNTAX_2OP|OP1_IMM_IMPLIED
myinsn r0,r1
myinsn fp,sp
myinsn r0,0
myinsn r1,-1
myinsn 0,r2
myinsn r4,255
myinsn r6,-256
myinsn r8,256
myinsn r9,-257
myinsn r11,0x42424242
myinsn r0,foo
myinsn.f r0,r1
myinsn.f r2,1
myinsn.f 0,r4
myinsn.f r5,512
myinsn.ne.f 0,r4
myinsn.c.f 0xdeadbeef, 0xdeadbeef
myinsn.nc.f 0xdeadbeef, 0x02

View File

@ -0,0 +1,63 @@
#objdump: -dr
.*: +file format .*arc.*
Disassembly of section .text:
[0-9a-f]+ <.text>:
0: 392d 0080 myinsn r0,r1,r2
4: 3b2d 371a myinsn gp,fp,sp
8: 3e2d 37dd myinsn ilink,r30,blink
c: 396d 0000 myinsn r0,r1,0
10: 3e2d 7080 0000 0000 myinsn r0,0,r2
18: 392d 00be myinsn 0,r1,r2
1c: 392d 0f80 ffff ffff myinsn r0,r1,0xffffffff
24: 3e2d 7080 ffff ffff myinsn r0,0xffffffff,r2
2c: 392d 0f80 0000 00ff myinsn r0,r1,0xff
34: 3e2d 7080 0000 00ff myinsn r0,0xff,r2
3c: 392d 0f80 ffff ff00 myinsn r0,r1,0xffffff00
44: 3e2d 7080 ffff ff00 myinsn r0,0xffffff00,r2
4c: 392d 0f80 0000 0100 myinsn r0,r1,0x100
54: 3e2d 7080 ffff feff myinsn r0,0xfffffeff,r2
5c: 3e2d 7f80 0000 0100 myinsn r0,0x100,0x100
64: 392d 0f80 0000 0000 myinsn r0,r1,0
68: R_ARC_32_ME foo
6c: 38ed 0080 myinsn r0,r0,r2
70: 3bed 0140 myinsn r3,r3,r5
74: 3eed 0201 myinsn.eq r6,r6,r8
78: 39ed 12c1 myinsn.eq r9,r9,r11
7c: 3ced 1382 myinsn.ne r12,r12,r14
80: 3fed 1442 myinsn.ne r15,r15,r17
84: 3aed 2503 myinsn.p r18,r18,r20
88: 3ded 25c3 myinsn.p r21,r21,r23
8c: 38ed 3684 myinsn.n r24,r24,gp
90: 3bed 3744 myinsn.n fp,fp,ilink
94: 3eed 37c5 myinsn.c r30,r30,blink
98: 3bed 00c5 myinsn.c r3,r3,r3
9c: 3bed 0205 myinsn.c r3,r3,r8
a0: 3bed 0106 myinsn.nc r3,r3,r4
a4: 3ced 0106 myinsn.nc r4,r4,r4
a8: 3ced 01c6 myinsn.nc r4,r4,r7
ac: 3ced 0147 myinsn.v r4,r4,r5
b0: 3ded 0147 myinsn.v r5,r5,r5
b4: 3ded 0148 myinsn.nv r5,r5,r5
b8: 3ded 0148 myinsn.nv r5,r5,r5
bc: 3eed 0009 myinsn.gt r6,r6,r0
c0: 38ed 002a myinsn.ge r0,r0,0
c4: 39ed 006b myinsn.lt r1,r1,0x1
c8: 3bed 00ed myinsn.hi r3,r3,0x3
cc: 3ced 012e myinsn.ls r4,r4,0x4
d0: 3ded 016f myinsn.pnz r5,r5,0x5
d4: 392d 8080 myinsn.f r0,r1,r2
d8: 396d 8040 myinsn.f r0,r1,0x1
dc: 3e2d f080 0000 0001 myinsn.f r0,0x1,r2
e4: 392d 80be myinsn.f 0,r1,r2
e8: 392d 8f80 0000 0200 myinsn.f r0,r1,0x200
f0: 3e2d f080 0000 0200 myinsn.f r0,0x200,r2
f8: 39ed 8081 myinsn.eq.f r1,r1,r2
fc: 38ed 8022 myinsn.ne.f r0,r0,0
100: 3aed 808b myinsn.lt.f r2,r2,r2
104: 3eed f0a9 0000 0001 myinsn.gt.f 0,0x1,0x2
10c: 3eed ff8c 0000 0200 myinsn.le.f 0,0x200,0x200
114: 3eed f0aa 0000 0200 myinsn.ge.f 0,0x200,0x2

View File

@ -0,0 +1,64 @@
# Insn 3op .extInstruction test
.extInstruction myinsn, 0x07, 0x2d, SUFFIX_FLAG|SUFFIX_COND, SYNTAX_3OP
myinsn r0,r1,r2
myinsn r26,fp,sp
myinsn ilink1,ilink2,blink
myinsn r0,r1,0
myinsn r0,0,r2
myinsn 0,r1,r2
myinsn r0,r1,-1
myinsn r0,-1,r2
myinsn r0,r1,255
myinsn r0,255,r2
myinsn r0,r1,-256
myinsn r0,-256,r2
myinsn r0,r1,256
myinsn r0,-257,r2
myinsn r0,256,256
myinsn r0,r1,foo
myinsn.al r0,r0,r2
myinsn.ra r3,r3,r5
myinsn.eq r6,r6,r8
myinsn.z r9,r9,r11
myinsn.ne r12,r12,r14
myinsn.nz r15,r15,r17
myinsn.pl r18,r18,r20
myinsn.p r21,r21,r23
myinsn.mi r24,r24,r26
myinsn.n r27,r27,r29
myinsn.cs r30,r30,r31
myinsn.c r3,r3,r3
myinsn.lo r3,r3,r8
myinsn.cc r3,r3,r4
myinsn.nc r4,r4,r4
myinsn.hs r4,r4,r7
myinsn.vs r4,r4,r5
myinsn.v r5,r5,r5
myinsn.vc r5,r5,r5
myinsn.nv r5,r5,r5
myinsn.gt r6,r6,r0
myinsn.ge r0,r0,0
myinsn.lt r1,r1,1
myinsn.hi r3,r3,3
myinsn.ls r4,r4,4
myinsn.pnz r5,r5,5
myinsn.f r0,r1,r2
myinsn.f r0,r1,1
myinsn.f r0,1,r2
myinsn.f 0,r1,r2
myinsn.f r0,r1,512
myinsn.f r0,512,r2
myinsn.eq.f r1,r1,r2
myinsn.ne.f r0,r0,0
myinsn.lt.f r2,r2,r2
myinsn.gt.f 0,1,2
myinsn.le.f 0,512,512
myinsn.ge.f 0,512,2

View File

@ -1,30 +1,47 @@
22016-04-05 Claudiu Zissulescu <claziss@synopsys.com>
2016-04-12 Claudiu Zissulescu <claziss@synopsys.com>
* opcode/arc.h (DPA, DPX, SPX): New subclass enums.
(ARC_FPUDA): Define.
(arc_aux_reg): Add new field.
* opcode/arc.h (arc_num_opcodes): Remove.
(ARC_SYNTAX_3OP, ARC_SYNTAX_2OP, ARC_OP1_MUST_BE_IMM)
(ARC_OP1_IMM_IMPLIED, ARC_SUFFIX_NONE, ARC_SUFFIX_COND)
(ARC_SUFFIX_FLAG): Define.
(flags_none, flags_f, flags_cc, flags_ccf): Declare.
(arg_none, arg_32bit_rarbrc, arg_32bit_zarbrc, arg_32bit_rbrbrc)
(arg_32bit_rarbu6, arg_32bit_zarbu6, arg_32bit_rbrbu6)
(arg_32bit_rbrbs12, arg_32bit_ralimmrc, arg_32bit_rarblimm)
(arg_32bit_zalimmrc, arg_32bit_zarblimm, arg_32bit_rbrblimm)
(arg_32bit_ralimmu6, arg_32bit_zalimmu6, arg_32bit_zalimms12)
(arg_32bit_ralimmlimm, arg_32bit_zalimmlimm, arg_32bit_rbrc)
(arg_32bit_zarc, arg_32bit_rbu6, arg_32bit_zau6, arg_32bit_rblimm)
(arg_32bit_zalimm, arg_32bit_limmrc, arg_32bit_limmu6)
(arg_32bit_limms12, arg_32bit_limmlimm): Likewise.
016-04-05 Cupertino Miranda <cmiranda@synopsys.com>
2016-04-05 Claudiu Zissulescu <claziss@synopsys.com>
* opcode/arc.h (DPA, DPX, SPX): New subclass enums.
(ARC_FPUDA): Define.
(arc_aux_reg): Add new field.
2016-04-05 Cupertino Miranda <cmiranda@synopsys.com>
* opcode/arc-func.h (replace_bits24): Changed.
(replace_bits24_be): Created.
2016-03-29 Claudiu Zissulescu <claziss@synopsys.com>
* opcode/arc.h (insn_subclass_t): Add QUARKSE subclass.
(FIELDA, FIELDB, FIELDC, FIELDF, FIELDQ, INSN3OP, INSN2OP)
(INSN2OP, INSN3OP_ABC, INSN3OP_ALC, INSN3OP_ABL, INSN3OP_ALL)
(INSN3OP_0BC, INSN3OP_0LC, INSN3OP_0BL, INSN3OP_0LL, INSN3OP_ABU)
(INSN3OP_ALU, INSN3OP_0BU, INSN3OP_0LU, INSN3OP_BBS, INSN3OP_0LS)
(INSN3OP_CBBC, INSN3OP_CBBL, INSN3OP_C0LC, INSN3OP_C0LL)
(INSN3OP_CBBU, INSN3OP_C0LU, MINSN3OP_ABC, MINSN3OP_ALC)
(MINSN3OP_ABL, MINSN3OP_ALL, MINSN3OP_0BC, MINSN3OP_0LC)
(MINSN3OP_0BL, MINSN3OP_0LL, MINSN3OP_ABU, MINSN3OP_ALU)
(MINSN3OP_0BU, MINSN3OP_0LU, MINSN3OP_BBS, MINSN3OP_0LS)
(MINSN3OP_CBBC, MINSN3OP_CBBL, MINSN3OP_C0LC, MINSN3OP_C0LL)
(MINSN3OP_CBBU, MINSN3OP_C0LU, INSN2OP_BC, INSN2OP_BL, INSN2OP_0C)
(INSN2OP_0L INSN2OP_BU, INSN2OP_0U, MINSN2OP_BC, MINSN2OP_BL)
(MINSN2OP_0C, MINSN2OP_0L, MINSN2OP_BU, MINSN2OP_0U): Define.
* opcode/arc.h (insn_subclass_t): Add QUARKSE subclass.
(FIELDA, FIELDB, FIELDC, FIELDF, FIELDQ, INSN3OP, INSN2OP)
(INSN2OP, INSN3OP_ABC, INSN3OP_ALC, INSN3OP_ABL, INSN3OP_ALL)
(INSN3OP_0BC, INSN3OP_0LC, INSN3OP_0BL, INSN3OP_0LL, INSN3OP_ABU)
(INSN3OP_ALU, INSN3OP_0BU, INSN3OP_0LU, INSN3OP_BBS, INSN3OP_0LS)
(INSN3OP_CBBC, INSN3OP_CBBL, INSN3OP_C0LC, INSN3OP_C0LL)
(INSN3OP_CBBU, INSN3OP_C0LU, MINSN3OP_ABC, MINSN3OP_ALC)
(MINSN3OP_ABL, MINSN3OP_ALL, MINSN3OP_0BC, MINSN3OP_0LC)
(MINSN3OP_0BL, MINSN3OP_0LL, MINSN3OP_ABU, MINSN3OP_ALU)
(MINSN3OP_0BU, MINSN3OP_0LU, MINSN3OP_BBS, MINSN3OP_0LS)
(MINSN3OP_CBBC, MINSN3OP_CBBL, MINSN3OP_C0LC, MINSN3OP_C0LL)
(MINSN3OP_CBBU, MINSN3OP_C0LU, INSN2OP_BC, INSN2OP_BL, INSN2OP_0C)
(INSN2OP_0L INSN2OP_BU, INSN2OP_0U, MINSN2OP_BC, MINSN2OP_BL)
(MINSN2OP_0C, MINSN2OP_0L, MINSN2OP_BU, MINSN2OP_0U): Define.
2016-03-22 Trevor Saunders <tbsaunde+binutils@tbsaunde.org>
@ -124,8 +141,8 @@
2016-02-10 Claudiu Zissulescu <claziss@synopsys.com>
Janek van Oirschot <jvanoirs@synopsys.com>
* opcode/arc.h (arc_opcode arc_relax_opcodes, arc_num_relax_opcodes):
Declare.
* opcode/arc.h (arc_opcode arc_relax_opcodes)
(arc_num_relax_opcodes): Declare.
2016-02-09 Nick Clifton <nickc@redhat.com>

View File

@ -130,7 +130,6 @@ struct arc_opcode
in the order in which the disassembler should consider
instructions. */
extern const struct arc_opcode arc_opcodes[];
extern const unsigned arc_num_opcodes;
/* CPU Availability. */
#define ARC_OPCODE_ARC600 0x0001 /* ARC 600 specific insns. */
@ -494,4 +493,54 @@ extern const unsigned arc_num_relax_opcodes;
#define MINSN2OP_BU (~(FIELDF | FIELDB (63) | FIELDC (63)))
#define MINSN2OP_0U (~(FIELDF | FIELDC (63)))
/* Various constants used when defining an extension instruction. */
#define ARC_SYNTAX_3OP (1 << 0)
#define ARC_SYNTAX_2OP (1 << 1)
#define ARC_OP1_MUST_BE_IMM (1 << 2)
#define ARC_OP1_IMM_IMPLIED (1 << 3)
#define ARC_SUFFIX_NONE (1 << 0)
#define ARC_SUFFIX_COND (1 << 1)
#define ARC_SUFFIX_FLAG (1 << 2)
/* Constants needed to initialize extension instructions. */
extern const unsigned char flags_none[MAX_INSN_FLGS + 1];
extern const unsigned char flags_f[MAX_INSN_FLGS + 1];
extern const unsigned char flags_cc[MAX_INSN_FLGS + 1];
extern const unsigned char flags_ccf[MAX_INSN_FLGS + 1];
extern const unsigned char arg_none[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rarbrc[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zarbrc[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rbrbrc[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rarbu6[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zarbu6[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rbrbu6[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rbrbs12[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_ralimmrc[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rarblimm[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zalimmrc[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zarblimm[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rbrblimm[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_ralimmu6[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zalimmu6[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zalimms12[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_ralimmlimm[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zalimmlimm[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rbrc[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zarc[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rbu6[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zau6[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_rblimm[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_zalimm[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_limmrc[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_limmu6[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_limms12[MAX_INSN_ARGS + 1];
extern const unsigned char arg_32bit_limmlimm[MAX_INSN_ARGS + 1];
#endif /* OPCODE_ARC_H */

View File

@ -1,3 +1,34 @@
2016-04-12 Claudiu Zissulescu <claziss@synopsys.com>
* arc-opc.c (flags_none, flags_f, flags_cc, flags_ccf):
Initialize.
(arg_none, arg_32bit_rarbrc, arg_32bit_zarbrc, arg_32bit_rbrbrc)
(arg_32bit_rarbu6, arg_32bit_zarbu6, arg_32bit_rbrbu6)
(arg_32bit_rbrbs12, arg_32bit_ralimmrc, arg_32bit_rarblimm)
(arg_32bit_zalimmrc, arg_32bit_zarblimm, arg_32bit_rbrblimm)
(arg_32bit_ralimmu6, arg_32bit_zalimmu6, arg_32bit_zalimms12)
(arg_32bit_ralimmlimm, arg_32bit_zalimmlimm, arg_32bit_rbrc)
(arg_32bit_zarc, arg_32bit_rbu6, arg_32bit_zau6, arg_32bit_rblimm)
(arg_32bit_zalimm, arg_32bit_limmrc, arg_32bit_limmu6)
(arg_32bit_limms12, arg_32bit_limmlimm): Likewise.
(arc_opcode arc_opcodes): Null terminate the array.
(arc_num_opcodes): Remove.
* arc-ext.h (INSERT_XOP): Define.
(extInstruction_t): Likewise.
(arcExtMap_instName): Delete.
(arcExtMap_insn): New function.
(arcExtMap_genOpcode): Likewise.
* arc-ext.c (ExtInstruction): Remove.
(create_map): Zero initialize instruction fields.
(arcExtMap_instName): Remove.
(arcExtMap_insn): New function.
(dump_ARC_extmap): More info while debuging.
(arcExtMap_genOpcode): New function.
* arc-dis.c (find_format): New function.
(print_insn_arc): Use find_format.
(arc_get_disassembler): Enable dump_ARC_extmap only when
debugging.
2016-04-11 Maciej W. Rozycki <macro@imgtec.com>
* mips-dis.c (print_mips16_insn_arg): Mask unused extended
@ -27,12 +58,12 @@
2016-04-05 Claudiu Zissulescu <claziss@synopsys.com>
* arc-regs.h: Add a new subclass field. Add double assist
accumulator register values.
* arc-tbl.h: Use DPA subclass to mark the double assist
instructions. Use DPX/SPX subclas to mark the FPX instructions.
* arc-opc.c (RSP): Define instead of SP.
(arc_aux_regs): Add the subclass field.
* arc-regs.h: Add a new subclass field. Add double assist
accumulator register values.
* arc-tbl.h: Use DPA subclass to mark the double assist
instructions. Use DPX/SPX subclas to mark the FPX instructions.
* arc-opc.c (RSP): Define instead of SP.
(arc_aux_regs): Add the subclass field.
2016-04-05 Jiong Wang <jiong.wang@arm.com>
@ -50,23 +81,23 @@
2016-03-30 Claudiu Zissulescu <claziss@synopsys.com>
* arc-regs.h (IC_RAM_ADDRESS, IC_TAG, IC_WP, IC_DATA, CONTROL0)
(AX2, AY2, MX2, MY2, AY0, AY1, DC_RAM_ADDR, DC_TAG, CONTROL1)
(RTT): Remove duplicate.
(LCDINSTR, LCDDATA, LCDSTAT, CC_*, PCT_COUNT*, PCT_SNAP*)
(PCT_CONFIG*): Remove.
(D1L, D1H, D2H, D2L): Define.
* arc-regs.h (IC_RAM_ADDRESS, IC_TAG, IC_WP, IC_DATA, CONTROL0)
(AX2, AY2, MX2, MY2, AY0, AY1, DC_RAM_ADDR, DC_TAG, CONTROL1)
(RTT): Remove duplicate.
(LCDINSTR, LCDDATA, LCDSTAT, CC_*, PCT_COUNT*, PCT_SNAP*)
(PCT_CONFIG*): Remove.
(D1L, D1H, D2H, D2L): Define.
2016-03-29 Claudiu Zissulescu <claziss@synopsys.com>
* arc-ext-tbl.h (dsp_fp_i2flt): Fix typo.
* arc-ext-tbl.h (dsp_fp_i2flt): Fix typo.
2016-03-29 Claudiu Zissulescu <claziss@synopsys.com>
* arc-tbl.h (invld07): Remove.
* arc-ext-tbl.h: New file.
* arc-dis.c (FIELDA, FIELDB, FIELDC): Remove.
* arc-opc.c (arc_opcodes): Add ext-tbl include.
* arc-tbl.h (invld07): Remove.
* arc-ext-tbl.h: New file.
* arc-dis.c (FIELDA, FIELDB, FIELDC): Remove.
* arc-opc.c (arc_opcodes): Add ext-tbl include.
2016-03-24 Jan Kratochvil <jan.kratochvil@redhat.com>
@ -164,8 +195,8 @@
2016-02-10 Claudiu Zissulescu <claziss@synopsys.com>
Janek van Oirschot <jvanoirs@synopsys.com>
* arc-opc.c (arc_relax_opcodes, arc_num_relax_opcodes): New
variable.
* arc-opc.c (arc_relax_opcodes, arc_num_relax_opcodes): New
variable.
2016-02-04 Nick Clifton <nickc@redhat.com>

View File

@ -102,6 +102,107 @@ special_flag_p (const char *opname,
return 0;
}
/* Find proper format for the given opcode. */
static const struct arc_opcode *
find_format (const struct arc_opcode *arc_table,
unsigned *insn, int insnLen,
unsigned isa_mask)
{
unsigned int i = 0;
const struct arc_opcode *opcode = NULL;
const unsigned char *opidx;
const unsigned char *flgidx;
do {
bfd_boolean invalid = FALSE;
opcode = &arc_table[i++];
if (ARC_SHORT (opcode->mask) && (insnLen == 2))
{
if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
continue;
}
else if (!ARC_SHORT (opcode->mask) && (insnLen == 4))
{
if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
continue;
}
else
continue;
if ((insn[0] ^ opcode->opcode) & opcode->mask)
continue;
if (!(opcode->cpu & isa_mask))
continue;
/* Possible candidate, check the operands. */
for (opidx = opcode->operands; *opidx; opidx++)
{
int value;
const struct arc_operand *operand = &arc_operands[*opidx];
if (operand->flags & ARC_OPERAND_FAKE)
continue;
if (operand->extract)
value = (*operand->extract) (insn[0], &invalid);
else
value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
/* Check for LIMM indicator. If it is there, then make sure
we pick the right format. */
if (operand->flags & ARC_OPERAND_IR
&& !(operand->flags & ARC_OPERAND_LIMM))
{
if ((value == 0x3E && insnLen == 4)
|| (value == 0x1E && insnLen == 2))
{
invalid = TRUE;
break;
}
}
}
/* Check the flags. */
for (flgidx = opcode->flags; *flgidx; flgidx++)
{
/* Get a valid flag class. */
const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
const unsigned *flgopridx;
int foundA = 0, foundB = 0;
for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
{
const struct arc_flag_operand *flg_operand =
&arc_flag_operands[*flgopridx];
unsigned int value;
value = (insn[0] >> flg_operand->shift)
& ((1 << flg_operand->bits) - 1);
if (value == flg_operand->code)
foundA = 1;
if (value)
foundB = 1;
}
if (!foundA && foundB)
{
invalid = TRUE;
break;
}
}
if (invalid)
continue;
/* The instruction is valid. */
return opcode;
} while (opcode->mask);
return NULL;
}
/* Disassemble ARC instructions. */
static int
@ -111,15 +212,13 @@ print_insn_arc (bfd_vma memaddr,
bfd_byte buffer[4];
unsigned int lowbyte, highbyte;
int status;
unsigned int i;
int insnLen = 0;
unsigned insn[2] = { 0, 0 };
unsigned isa_mask;
const unsigned char *opidx;
const unsigned char *flgidx;
const struct arc_opcode *opcode;
const char *instrName;
int flags;
const extInstruction_t *einsn;
bfd_boolean need_comma;
bfd_boolean open_braket;
int size;
@ -218,7 +317,7 @@ print_insn_arc (bfd_vma memaddr,
return size;
}
if ( (((buffer[lowbyte] & 0xf8) > 0x38)
if ((((buffer[lowbyte] & 0xf8) > 0x38)
&& ((buffer[lowbyte] & 0xf8) != 0x48))
|| ((info->mach == bfd_mach_arc_arcv2)
&& ((buffer[lowbyte] & 0xF8) == 0x48)) /* FIXME! ugly. */
@ -254,110 +353,40 @@ print_insn_arc (bfd_vma memaddr,
info->disassembler_needs_relocs = TRUE;
/* Find the first match in the opcode table. */
for (i = 0; i < arc_num_opcodes; i++)
opcode = find_format (arc_opcodes, insn, insnLen, isa_mask);
if (!opcode)
{
bfd_boolean invalid = FALSE;
opcode = &arc_opcodes[i];
if (ARC_SHORT (opcode->mask) && (insnLen == 2))
/* No instruction found. Try the extensions. */
einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
if (einsn)
{
if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
continue;
}
else if (!ARC_SHORT (opcode->mask) && (insnLen == 4))
{
if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
continue;
const char *errmsg = NULL;
opcode = arcExtMap_genOpcode (einsn, isa_mask, &errmsg);
if (opcode == NULL)
{
(*info->fprintf_func) (info->stream,
"An error occured while "
"generating the extension instruction "
"operations");
return -1;
}
opcode = find_format (opcode, insn, insnLen, isa_mask);
assert (opcode != NULL);
}
else
continue;
if ((insn[0] ^ opcode->opcode) & opcode->mask)
continue;
if (!(opcode->cpu & isa_mask))
continue;
/* Possible candidate, check the operands. */
for (opidx = opcode->operands; *opidx; opidx++)
{
int value;
const struct arc_operand *operand = &arc_operands[*opidx];
if (operand->flags & ARC_OPERAND_FAKE)
continue;
if (operand->extract)
value = (*operand->extract) (insn[0], &invalid);
if (insnLen == 2)
(*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
else
value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
(*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
/* Check for LIMM indicator. If it is there, then make sure
we pick the right format. */
if (operand->flags & ARC_OPERAND_IR
&& !(operand->flags & ARC_OPERAND_LIMM))
{
if ((value == 0x3E && insnLen == 4)
|| (value == 0x1E && insnLen == 2))
{
invalid = TRUE;
break;
}
}
info->insn_type = dis_noninsn;
return insnLen;
}
/* Check the flags. */
for (flgidx = opcode->flags; *flgidx; flgidx++)
{
/* Get a valid flag class. */
const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
const unsigned *flgopridx;
int foundA = 0, foundB = 0;
for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
{
const struct arc_flag_operand *flg_operand = &arc_flag_operands[*flgopridx];
unsigned int value;
value = (insn[0] >> flg_operand->shift) & ((1 << flg_operand->bits) - 1);
if (value == flg_operand->code)
foundA = 1;
if (value)
foundB = 1;
}
if (!foundA && foundB)
{
invalid = TRUE;
break;
}
}
if (invalid)
continue;
/* The instruction is valid. */
goto found;
}
/* No instruction found. Try the extenssions. */
instrName = arcExtMap_instName (OPCODE (insn[0]), insn[0], &flags);
if (instrName)
{
opcode = &arc_opcodes[0];
(*info->fprintf_func) (info->stream, "%s", instrName);
goto print_flags;
}
if (insnLen == 2)
(*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
else
(*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
info->insn_type = dis_noninsn;
return insnLen;
found:
/* Print the mnemonic. */
(*info->fprintf_func) (info->stream, "%s", opcode->name);
@ -382,7 +411,6 @@ print_insn_arc (bfd_vma memaddr,
pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
print_flags:
/* Now extract and print the flags. */
for (flgidx = opcode->flags; *flgidx; flgidx++)
{
@ -557,7 +585,9 @@ arc_get_disassembler (bfd *abfd)
{
/* Read the extenssion insns and registers, if any. */
build_ARC_extmap (abfd);
#ifdef DEBUG
dump_ARC_extmap ();
#endif
return print_insn_arc;
}

View File

@ -27,7 +27,6 @@
#include "elf/arc.h"
#include "libiberty.h"
/* This module provides support for extensions to the ARC processor
architecture. */
@ -52,15 +51,6 @@
/* These types define the information stored in the table. */
struct ExtInstruction
{
char major;
char minor;
char flags;
char* name;
struct ExtInstruction* next;
};
struct ExtAuxRegister
{
long address;
@ -141,6 +131,9 @@ create_map (unsigned char *block,
insn->minor = minor;
insn->flags = p[4];
insn->next = *bucket;
insn->suffix = 0;
insn->syntax = 0;
insn->modsyn = 0;
*bucket = insn;
break;
}
@ -285,10 +278,8 @@ ExtReadWrite_image (enum ExtReadWrite val)
/* Get the name of an extension instruction. */
const char *
arcExtMap_instName (int opcode,
int insn,
int *flags)
const extInstruction_t *
arcExtMap_insn (int opcode, int insn)
{
/* Here the following tasks need to be done. First of all, the
opcode stored in the Extension Map is the real opcode. However,
@ -306,7 +297,7 @@ arcExtMap_instName (int opcode,
then un-mangle using iiiiiI else iiiiii. */
unsigned char minor;
struct ExtInstruction *temp;
extInstruction_t *temp;
/* 16-bit instructions. */
if (0x08 <= opcode && opcode <= 0x0b)
@ -367,8 +358,7 @@ arcExtMap_instName (int opcode,
{
if ((temp->major == opcode) && (temp->minor == minor))
{
*flags = temp->flags;
return temp->name;
return temp;
}
temp = temp->next;
}
@ -459,6 +449,8 @@ build_ARC_extmap (bfd *text_bfd)
}
}
/* Debug function used to dump the ARC information fount in arcextmap
sections. */
void
dump_ARC_extmap (void)
@ -480,8 +472,20 @@ dump_ARC_extmap (void)
for (insn = arc_extension_map.instructions[i];
insn != NULL; insn = insn->next)
printf ("INST: %d %d %x %s\n", insn->major, insn->minor,
insn->flags, insn->name);
{
printf ("INST: 0x%02x 0x%02x ", insn->major, insn->minor);
if (insn->flags & ARC_SYNTAX_2OP)
printf ("SYNTAX_2OP");
else if (insn->flags & ARC_SYNTAX_3OP)
printf ("SYNTAX_3OP");
else
printf ("SYNTAX_UNK");
if (insn->flags & 0x10)
printf ("|MODIFIER");
printf (" %s\n", insn->name);
}
}
for (i = 0; i < NUM_EXT_CORE; i++)
@ -497,3 +501,267 @@ dump_ARC_extmap (void)
if (arc_extension_map.condCodes[i])
printf ("COND: %s\n", arc_extension_map.condCodes[i]);
}
/* For a given extension instruction generate the equivalent arc
opcode structure. */
struct arc_opcode *
arcExtMap_genOpcode (const extInstruction_t *einsn,
unsigned arc_target,
const char **errmsg)
{
struct arc_opcode *q, *arc_ext_opcodes = NULL;
const unsigned char *lflags_f;
const unsigned char *lflags_ccf;
int count;
/* Check for the class to see how many instructions we generate. */
switch (einsn->flags & (ARC_SYNTAX_3OP | ARC_SYNTAX_2OP))
{
case ARC_SYNTAX_3OP:
count = (einsn->modsyn & ARC_OP1_MUST_BE_IMM) ? 10 : 20;
break;
case ARC_SYNTAX_2OP:
count = (einsn->flags & 0x10) ? 7 : 6;
break;
default:
count = 0;
break;
}
/* Allocate memory. */
arc_ext_opcodes = (struct arc_opcode *)
xmalloc ((count + 1) * sizeof (*arc_ext_opcodes));
if (arc_ext_opcodes == NULL)
{
*errmsg = "Virtual memory exhausted";
return NULL;
}
/* Generate the patterns. */
q = arc_ext_opcodes;
if (einsn->suffix)
{
lflags_f = flags_none;
lflags_ccf = flags_none;
}
else
{
lflags_f = flags_f;
lflags_ccf = flags_ccf;
}
if (einsn->suffix & ARC_SUFFIX_COND)
lflags_ccf = flags_cc;
if (einsn->suffix & ARC_SUFFIX_FLAG)
{
lflags_f = flags_f;
lflags_ccf = flags_f;
}
if (einsn->suffix & (ARC_SUFFIX_FLAG | ARC_SUFFIX_COND))
lflags_ccf = flags_ccf;
if (einsn->flags & ARC_SYNTAX_2OP
&& !(einsn->flags & 0x10))
{
/* Regular 2OP instruction. */
if (einsn->suffix & ARC_SUFFIX_COND)
*errmsg = "Suffix SUFFIX_COND ignored";
INSERT_XOP (q, einsn->name,
INSN2OP_BC (einsn->major, einsn->minor), MINSN2OP_BC,
arc_target, arg_32bit_rbrc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN2OP_0C (einsn->major, einsn->minor), MINSN2OP_0C,
arc_target, arg_32bit_zarc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN2OP_BU (einsn->major, einsn->minor), MINSN2OP_BU,
arc_target, arg_32bit_rbu6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN2OP_0U (einsn->major, einsn->minor), MINSN2OP_0U,
arc_target, arg_32bit_zau6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN2OP_BL (einsn->major, einsn->minor), MINSN2OP_BL,
arc_target, arg_32bit_rblimm, lflags_f);
INSERT_XOP (q, einsn->name,
INSN2OP_0L (einsn->major, einsn->minor), MINSN2OP_0L,
arc_target, arg_32bit_zalimm, lflags_f);
}
else if (einsn->flags & (0x10 | ARC_SYNTAX_2OP))
{
/* This is actually a 3OP pattern. The first operand is
immplied and is set to zero. */
INSERT_XOP (q, einsn->name,
INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
arc_target, arg_32bit_rbrc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
arc_target, arg_32bit_rbu6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
arc_target, arg_32bit_rblimm, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
arc_target, arg_32bit_limmrc, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
arc_target, arg_32bit_limmu6, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
arc_target, arg_32bit_limms12, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
arc_target, arg_32bit_limmlimm, lflags_ccf);
}
else if (einsn->flags & ARC_SYNTAX_3OP
&& !(einsn->modsyn & ARC_OP1_MUST_BE_IMM))
{
/* Regular 3OP instruction. */
INSERT_XOP (q, einsn->name,
INSN3OP_ABC (einsn->major, einsn->minor), MINSN3OP_ABC,
arc_target, arg_32bit_rarbrc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
arc_target, arg_32bit_zarbrc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_CBBC (einsn->major, einsn->minor), MINSN3OP_CBBC,
arc_target, arg_32bit_rbrbrc, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_ABU (einsn->major, einsn->minor), MINSN3OP_ABU,
arc_target, arg_32bit_rarbu6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
arc_target, arg_32bit_zarbu6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_CBBU (einsn->major, einsn->minor), MINSN3OP_CBBU,
arc_target, arg_32bit_rbrbu6, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_BBS (einsn->major, einsn->minor), MINSN3OP_BBS,
arc_target, arg_32bit_rbrbs12, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_ALC (einsn->major, einsn->minor), MINSN3OP_ALC,
arc_target, arg_32bit_ralimmrc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_ABL (einsn->major, einsn->minor), MINSN3OP_ABL,
arc_target, arg_32bit_rarblimm, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0LC (einsn->major, einsn->minor), MINSN3OP_0LC,
arc_target, arg_32bit_zalimmrc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
arc_target, arg_32bit_zarblimm, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
arc_target, arg_32bit_zalimmrc, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_CBBL (einsn->major, einsn->minor), MINSN3OP_CBBL,
arc_target, arg_32bit_rbrblimm, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_ALU (einsn->major, einsn->minor), MINSN3OP_ALU,
arc_target, arg_32bit_ralimmu6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0LU (einsn->major, einsn->minor), MINSN3OP_0LU,
arc_target, arg_32bit_zalimmu6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
arc_target, arg_32bit_zalimmu6, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
arc_target, arg_32bit_zalimms12, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_ALL (einsn->major, einsn->minor), MINSN3OP_ALL,
arc_target, arg_32bit_ralimmlimm, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0LL (einsn->major, einsn->minor), MINSN3OP_0LL,
arc_target, arg_32bit_zalimmlimm, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
arc_target, arg_32bit_zalimmlimm, lflags_ccf);
}
else if (einsn->flags & ARC_SYNTAX_3OP)
{
/* 3OP instruction which accepts only zero as first
argument. */
INSERT_XOP (q, einsn->name,
INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
arc_target, arg_32bit_zarbrc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
arc_target, arg_32bit_zarbu6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0LC (einsn->major, einsn->minor), MINSN3OP_0LC,
arc_target, arg_32bit_zalimmrc, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
arc_target, arg_32bit_zarblimm, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
arc_target, arg_32bit_zalimmrc, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_0LU (einsn->major, einsn->minor), MINSN3OP_0LU,
arc_target, arg_32bit_zalimmu6, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
arc_target, arg_32bit_zalimmu6, lflags_ccf);
INSERT_XOP (q, einsn->name,
INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
arc_target, arg_32bit_zalimms12, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_0LL (einsn->major, einsn->minor), MINSN3OP_0LL,
arc_target, arg_32bit_zalimmlimm, lflags_f);
INSERT_XOP (q, einsn->name,
INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
arc_target, arg_32bit_zalimmlimm, lflags_ccf);
}
else
{
*errmsg = "Unknown syntax";
return NULL;
}
/* End marker. */
memset (q, 0, sizeof (*arc_ext_opcodes));
return arc_ext_opcodes;
}

View File

@ -39,13 +39,14 @@
#ifndef ARC_EXTENSIONS_H
#define ARC_EXTENSIONS_H
#include "opcode/arc.h"
#define IGNORE_FIRST_OPD 1
/* Define this if we do not want to encode instructions based on the
ARCompact Programmer's Reference. */
#define UNMANGLED
/* This defines the kinds of extensions which may be read from the
ections in the executable files. */
enum ExtOperType
@ -63,7 +64,6 @@ enum ExtOperType
EXT_CORE_REGISTER_CLASS = 9
};
enum ExtReadWrite
{
REG_INVALID,
@ -72,6 +72,48 @@ enum ExtReadWrite
REG_READWRITE
};
/* Macro used when generating the patterns for an extension
instruction. */
#define INSERT_XOP(OP, NAME, CODE, MASK, CPU, ARG, FLG) \
do { \
(OP)->name = NAME; \
(OP)->opcode = CODE; \
(OP)->mask = MASK; \
(OP)->cpu = CPU; \
(OP)->class = ARITH; \
(OP)->subclass = NONE; \
memcpy ((OP)->operands, (ARG), MAX_INSN_ARGS); \
memcpy ((OP)->flags, (FLG), MAX_INSN_FLGS); \
(OP++); \
} while (0)
/* Typedef to hold the extension instruction definition. */
typedef struct ExtInstruction
{
/* Name. */
char *name;
/* Major opcode. */
char major;
/* Minor(sub) opcode. */
char minor;
/* Flags, holds the syntax class and modifiers. */
char flags;
/* Syntax class. Use by assembler. */
unsigned char syntax;
/* Syntax class modifier. Used by assembler. */
unsigned char modsyn;
/* Suffix class. Used by assembler. */
unsigned char suffix;
/* Pointer to the next extension instruction. */
struct ExtInstruction* next;
} extInstruction_t;
/* Constructor function. */
extern void build_ARC_extmap (bfd *);
@ -81,7 +123,10 @@ extern enum ExtReadWrite arcExtMap_coreReadWrite (int);
extern const char * arcExtMap_coreRegName (int);
extern const char * arcExtMap_auxRegName (long);
extern const char * arcExtMap_condCodeName (int);
extern const char * arcExtMap_instName (int, int, int *);
extern const extInstruction_t *arcExtMap_insn (int, int);
extern struct arc_opcode *arcExtMap_genOpcode (const extInstruction_t *,
unsigned arc_target,
const char **errmsg);
/* Dump function (for debugging). */
extern void dump_ARC_extmap (void);

View File

@ -1136,6 +1136,11 @@ const struct arc_flag_class arc_flag_classes[] =
};
const unsigned char flags_none[] = { 0 };
const unsigned char flags_f[] = { C_F };
const unsigned char flags_cc[] = { C_CC };
const unsigned char flags_ccf[] = { C_CC, C_F };
/* The operands table.
The format of the operands table is:
@ -1499,6 +1504,39 @@ const unsigned arc_num_operands = ARRAY_SIZE (arc_operands);
const unsigned arc_Toperand = FKT_T;
const unsigned arc_NToperand = FKT_NT;
const unsigned char arg_none[] = { 0 };
const unsigned char arg_32bit_rarbrc[] = { RA, RB, RC };
const unsigned char arg_32bit_zarbrc[] = { ZA, RB, RC };
const unsigned char arg_32bit_rbrbrc[] = { RB, RBdup, RC };
const unsigned char arg_32bit_rarbu6[] = { RA, RB, UIMM6_20 };
const unsigned char arg_32bit_zarbu6[] = { ZA, RB, UIMM6_20 };
const unsigned char arg_32bit_rbrbu6[] = { RB, RBdup, UIMM6_20 };
const unsigned char arg_32bit_rbrbs12[] = { RB, RBdup, SIMM12_20 };
const unsigned char arg_32bit_ralimmrc[] = { RA, LIMM, RC };
const unsigned char arg_32bit_rarblimm[] = { RA, RB, LIMM };
const unsigned char arg_32bit_zalimmrc[] = { ZA, LIMM, RC };
const unsigned char arg_32bit_zarblimm[] = { ZA, RB, LIMM };
const unsigned char arg_32bit_rbrblimm[] = { RB, RBdup, LIMM };
const unsigned char arg_32bit_ralimmu6[] = { RA, LIMM, UIMM6_20 };
const unsigned char arg_32bit_zalimmu6[] = { ZA, LIMM, UIMM6_20 };
const unsigned char arg_32bit_zalimms12[] = { ZA, LIMM, SIMM12_20 };
const unsigned char arg_32bit_ralimmlimm[] = { RA, LIMM, LIMMdup };
const unsigned char arg_32bit_zalimmlimm[] = { ZA, LIMM, LIMMdup };
const unsigned char arg_32bit_rbrc[] = { RB, RC };
const unsigned char arg_32bit_zarc[] = { ZA, RC };
const unsigned char arg_32bit_rbu6[] = { RB, UIMM6_20 };
const unsigned char arg_32bit_zau6[] = { ZA, UIMM6_20 };
const unsigned char arg_32bit_rblimm[] = { RB, LIMM };
const unsigned char arg_32bit_zalimm[] = { ZA, LIMM };
const unsigned char arg_32bit_limmrc[] = { LIMM, RC };
const unsigned char arg_32bit_limmu6[] = { LIMM, UIMM6_20 };
const unsigned char arg_32bit_limms12[] = { LIMM, SIMM12_20 };
const unsigned char arg_32bit_limmlimm[] = { LIMM, LIMMdup };
/* The opcode table.
The format of the opcode table is:
@ -1539,9 +1577,9 @@ const struct arc_opcode arc_opcodes[] =
#include "arc-tbl.h"
#include "arc-nps400-tbl.h"
#include "arc-ext-tbl.h"
};
const unsigned arc_num_opcodes = ARRAY_SIZE (arc_opcodes);
{ NULL, 0, 0, 0, 0, 0, { 0 }, { 0 } }
};
/* List with special cases instructions and the applicable flags. */
const struct arc_flag_special arc_flag_special_cases[] =