mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 09:58:19 +08:00
* cgen-asm.c (cgen_current_opcode_table): Renamed from ..._data.
(asm_hash_table_entries): New variable. (cgen_asm_init): Free asm_hash_table_entries. (hash_insn_array,hash_insn_list): New functions. (build_asm_hash_table): Use them. Hash macro insns as well. (cgen_asm_lookup_insn): Update. * cgen_dis.c (cgen_current_opcode_table): Renamed from ..._data. (dis_hash_table_entries): New variable. (cgen_dis_init): Free dis_hash_table_entries. (hash_insn_array,hash_insn_list): New functions. (build_dis_hash_table): Use them. Hash macro insns as well. (cgen_dis_lookup_insn): Update. * cgen-opc.c (cgen_current_opcode_table): Renamed from ..._data. (cgen_set_cpu,cgen_hw_lookup,cgen_insn_count): Update. (cgen_macro_insn_count): New function. * cgen-opc.in (@arch@_cgen_lookup_insn): New arg alias_p. All callers updated. Sanity check result of extract fn. (@arch@_cgen_get_insn_operands): Change result type to void. Delete args insn_value, length. New arg fields. All callers updated. (@arch@_cgen_lookup_get_insn_operands): New function.
This commit is contained in:
@ -1,3 +1,26 @@
|
||||
Mon Apr 27 10:33:56 1998 Doug Evans <devans@seba.cygnus.com>
|
||||
|
||||
* cgen-asm.c (cgen_current_opcode_table): Renamed from ..._data.
|
||||
(asm_hash_table_entries): New variable.
|
||||
(cgen_asm_init): Free asm_hash_table_entries.
|
||||
(hash_insn_array,hash_insn_list): New functions.
|
||||
(build_asm_hash_table): Use them. Hash macro insns as well.
|
||||
(cgen_asm_lookup_insn): Update.
|
||||
* cgen_dis.c (cgen_current_opcode_table): Renamed from ..._data.
|
||||
(dis_hash_table_entries): New variable.
|
||||
(cgen_dis_init): Free dis_hash_table_entries.
|
||||
(hash_insn_array,hash_insn_list): New functions.
|
||||
(build_dis_hash_table): Use them. Hash macro insns as well.
|
||||
(cgen_dis_lookup_insn): Update.
|
||||
* cgen-opc.c (cgen_current_opcode_table): Renamed from ..._data.
|
||||
(cgen_set_cpu,cgen_hw_lookup,cgen_insn_count): Update.
|
||||
(cgen_macro_insn_count): New function.
|
||||
* cgen-opc.in (@arch@_cgen_lookup_insn): New arg alias_p.
|
||||
All callers updated. Sanity check result of extract fn.
|
||||
(@arch@_cgen_get_insn_operands): Change result type to void.
|
||||
Delete args insn_value, length. New arg fields. All callers updated.
|
||||
(@arch@_cgen_lookup_get_insn_operands): New function.
|
||||
|
||||
Fri Apr 24 16:07:57 1998 Alan Modra <alan@spri.levels.unisa.edu.au>
|
||||
|
||||
* i386-dis.c (OP_DSSI): Print segment override.
|
||||
|
@ -1,34 +1,30 @@
|
||||
/* CGEN generic assembler support code.
|
||||
|
||||
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Binutils and GDB, the GNU debugger.
|
||||
This file is part of the GNU Binutils and GDB, the GNU debugger.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "config.h"
|
||||
#include "sysdep.h"
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "ansidecl.h"
|
||||
#include "libiberty.h"
|
||||
#include "bfd.h"
|
||||
#include "symcat.h"
|
||||
#include "opcode/cgen.h"
|
||||
|
||||
/* Operand parsing callback. */
|
||||
@ -38,10 +34,11 @@ const char * (*cgen_parse_operand_fn)
|
||||
|
||||
/* This is not published as part of the public interface so we don't
|
||||
declare this in cgen.h. */
|
||||
extern CGEN_OPCODE_DATA *cgen_current_opcode_data;
|
||||
extern CGEN_OPCODE_TABLE *cgen_current_opcode_table;
|
||||
|
||||
/* Assembler instruction hash table. */
|
||||
static CGEN_INSN_LIST **asm_hash_table;
|
||||
static CGEN_INSN_LIST *asm_hash_table_entries;
|
||||
|
||||
/* Called once at startup and whenever machine/endian change. */
|
||||
|
||||
@ -51,7 +48,9 @@ cgen_asm_init ()
|
||||
if (asm_hash_table)
|
||||
{
|
||||
free (asm_hash_table);
|
||||
free (asm_hash_table_entries);
|
||||
asm_hash_table = NULL;
|
||||
asm_hash_table_entries = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,61 +64,131 @@ cgen_init_parse_operand ()
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/* Subroutine of build_asm_hash_table to add INSNS to the hash table.
|
||||
|
||||
COUNT is the number of elements in INSNS.
|
||||
ENTSIZE is sizeof (CGEN_INSN) for the target.
|
||||
This is a bit tricky as the size of the attribute member of CGEN_INSN
|
||||
is variable among architectures. This code could be moved to
|
||||
cgen-asm.in, but I prefer to keep it here for now.
|
||||
OTABLE is the opcode table.
|
||||
HTABLE points to the hash table.
|
||||
HENTBUF is a pointer to sufficiently large buffer of hash entries.
|
||||
The result is a pointer to the next entry to use.
|
||||
|
||||
The table is scanned backwards as additions are made to the front of the
|
||||
list and we want earlier ones to be prefered. */
|
||||
|
||||
static CGEN_INSN_LIST *
|
||||
hash_insn_array (insns, count, entsize, otable, htable, hentbuf)
|
||||
const CGEN_INSN * insns;
|
||||
int count;
|
||||
int entsize;
|
||||
const CGEN_OPCODE_TABLE * otable;
|
||||
CGEN_INSN_LIST ** htable;
|
||||
CGEN_INSN_LIST * hentbuf;
|
||||
{
|
||||
const CGEN_INSN * insn;
|
||||
|
||||
for (insn = (CGEN_INSN *) ((char *) insns + entsize * (count - 1));
|
||||
insn >= insns;
|
||||
insn = (CGEN_INSN *) ((char *) insn - entsize), ++ hentbuf)
|
||||
{
|
||||
unsigned int hash;
|
||||
|
||||
if (! (*otable->asm_hash_p) (insn))
|
||||
continue;
|
||||
hash = (*otable->asm_hash) (CGEN_INSN_MNEMONIC (insn));
|
||||
hentbuf->next = htable[hash];
|
||||
hentbuf->insn = insn;
|
||||
htable[hash] = hentbuf;
|
||||
}
|
||||
|
||||
return hentbuf;
|
||||
}
|
||||
|
||||
/* Subroutine of build_asm_hash_table to add INSNS to the hash table.
|
||||
This function is identical to hash_insn_array except the insns are
|
||||
in a list. */
|
||||
|
||||
static CGEN_INSN_LIST *
|
||||
hash_insn_list (insns, otable, htable, hentbuf)
|
||||
const CGEN_INSN_LIST * insns;
|
||||
const CGEN_OPCODE_TABLE * otable;
|
||||
CGEN_INSN_LIST ** htable;
|
||||
CGEN_INSN_LIST * hentbuf;
|
||||
{
|
||||
const CGEN_INSN_LIST * ilist;
|
||||
|
||||
for (ilist = insns; ilist != NULL; ilist = ilist->next, ++ hentbuf)
|
||||
{
|
||||
unsigned int hash;
|
||||
|
||||
if (! (*otable->asm_hash_p) (ilist->insn))
|
||||
continue;
|
||||
hash = (*otable->asm_hash) (CGEN_INSN_MNEMONIC (ilist->insn));
|
||||
hentbuf->next = htable[hash];
|
||||
hentbuf->insn = ilist->insn;
|
||||
asm_hash_table[hash] = hentbuf;
|
||||
}
|
||||
|
||||
return hentbuf;
|
||||
}
|
||||
|
||||
/* Build the assembler instruction hash table. */
|
||||
|
||||
static void
|
||||
build_asm_hash_table ()
|
||||
{
|
||||
int i;
|
||||
unsigned int hash;
|
||||
int count = cgen_insn_count ();
|
||||
CGEN_OPCODE_DATA *data = cgen_current_opcode_data;
|
||||
CGEN_INSN_TABLE *insn_table = data->insn_table;
|
||||
unsigned int hash_size = insn_table->asm_hash_table_size;
|
||||
const CGEN_INSN *insn;
|
||||
CGEN_INSN_LIST *insn_lists,*new_insns;
|
||||
int count = cgen_insn_count () + cgen_macro_insn_count ();
|
||||
CGEN_OPCODE_TABLE *opcode_table = cgen_current_opcode_table;
|
||||
CGEN_INSN_TABLE *insn_table = opcode_table->insn_table;
|
||||
CGEN_INSN_TABLE *macro_insn_table = opcode_table->macro_insn_table;
|
||||
unsigned int hash_size = opcode_table->asm_hash_table_size;
|
||||
CGEN_INSN_LIST *hash_entry_buf;
|
||||
|
||||
/* The space allocated for the hash table consists of two parts:
|
||||
the hash table and the hash lists. */
|
||||
|
||||
asm_hash_table = (CGEN_INSN_LIST **)
|
||||
xmalloc (hash_size * sizeof (CGEN_INSN_LIST *)
|
||||
+ count * sizeof (CGEN_INSN_LIST));
|
||||
memset (asm_hash_table, 0,
|
||||
hash_size * sizeof (CGEN_INSN_LIST *)
|
||||
+ count * sizeof (CGEN_INSN_LIST));
|
||||
insn_lists = (CGEN_INSN_LIST *) (asm_hash_table + hash_size);
|
||||
xmalloc (hash_size * sizeof (CGEN_INSN_LIST *));
|
||||
memset (asm_hash_table, 0, hash_size * sizeof (CGEN_INSN_LIST *));
|
||||
asm_hash_table_entries = hash_entry_buf = (CGEN_INSN_LIST *)
|
||||
xmalloc (count * sizeof (CGEN_INSN_LIST));
|
||||
|
||||
/* Add compiled in insns.
|
||||
The table is scanned backwards as later additions are inserted in
|
||||
front of earlier ones and we want earlier ones to be prefered.
|
||||
We stop at the first one as it is a reserved entry. */
|
||||
Don't include the first one as it is a reserved entry. */
|
||||
/* ??? It was the end of all hash chains, and also the special
|
||||
"illegal insn" marker. May be able to do it differently now. */
|
||||
|
||||
for (insn = insn_table->init_entries + insn_table->num_init_entries - 1;
|
||||
insn > insn_table->init_entries;
|
||||
--insn, ++insn_lists)
|
||||
{
|
||||
hash = (*insn_table->asm_hash) (insn->syntax.mnemonic);
|
||||
insn_lists->next = asm_hash_table[hash];
|
||||
insn_lists->insn = insn;
|
||||
asm_hash_table[hash] = insn_lists;
|
||||
}
|
||||
hash_entry_buf = hash_insn_array ((CGEN_INSN *) ((char *) insn_table->init_entries
|
||||
+ insn_table->entry_size),
|
||||
insn_table->num_init_entries - 1,
|
||||
insn_table->entry_size,
|
||||
opcode_table, asm_hash_table, hash_entry_buf);
|
||||
|
||||
/* Add compiled in macro-insns. */
|
||||
|
||||
hash_entry_buf = hash_insn_array (macro_insn_table->init_entries,
|
||||
macro_insn_table->num_init_entries,
|
||||
macro_insn_table->entry_size,
|
||||
opcode_table, asm_hash_table, hash_entry_buf);
|
||||
|
||||
/* Add runtime added insns.
|
||||
??? Currently later added insns will be prefered over earlier ones.
|
||||
Not sure this is a bug or not. */
|
||||
for (new_insns = insn_table->new_entries;
|
||||
new_insns != NULL;
|
||||
new_insns = new_insns->next, ++insn_lists)
|
||||
{
|
||||
hash = (*insn_table->asm_hash) (new_insns->insn->syntax.mnemonic);
|
||||
insn_lists->next = asm_hash_table[hash];
|
||||
insn_lists->insn = new_insns->insn;
|
||||
asm_hash_table[hash] = insn_lists;
|
||||
}
|
||||
Later added insns will be prefered over earlier ones. */
|
||||
|
||||
hash_entry_buf = hash_insn_list (insn_table->new_entries, opcode_table,
|
||||
asm_hash_table, hash_entry_buf);
|
||||
|
||||
/* Add runtime added macro-insns. */
|
||||
|
||||
hash_insn_list (macro_insn_table->new_entries,
|
||||
opcode_table, asm_hash_table, hash_entry_buf);
|
||||
}
|
||||
|
||||
/* Return the first entry in the hash list for INSN. */
|
||||
/* Return the first entry in the hash list for INSN.
|
||||
??? Of course it would be better to pass in a pointer to the
|
||||
opcode data structure, rather than reference a global. Later. */
|
||||
|
||||
CGEN_INSN_LIST *
|
||||
cgen_asm_lookup_insn (insn)
|
||||
@ -130,7 +199,7 @@ cgen_asm_lookup_insn (insn)
|
||||
if (asm_hash_table == NULL)
|
||||
build_asm_hash_table ();
|
||||
|
||||
hash = (*cgen_current_opcode_data->insn_table->asm_hash) (insn);
|
||||
hash = (*cgen_current_opcode_table->asm_hash) (insn);
|
||||
return asm_hash_table[hash];
|
||||
}
|
||||
|
||||
@ -145,35 +214,40 @@ cgen_asm_lookup_insn (insn)
|
||||
const char *
|
||||
cgen_parse_keyword (strp, keyword_table, valuep)
|
||||
const char **strp;
|
||||
struct cgen_keyword *keyword_table;
|
||||
CGEN_KEYWORD *keyword_table;
|
||||
long *valuep;
|
||||
{
|
||||
const struct cgen_keyword_entry *ke;
|
||||
const CGEN_KEYWORD_ENTRY *ke;
|
||||
char buf[256];
|
||||
const char *p;
|
||||
const char *p,*start;
|
||||
|
||||
p = *strp;
|
||||
p = start = *strp;
|
||||
|
||||
/* Allow any first character. */
|
||||
/* Allow any first character.
|
||||
Note that this allows recognizing ",a" for the annul flag in sparc
|
||||
even though "," is subsequently not a valid keyword char. */
|
||||
if (*p)
|
||||
++p;
|
||||
|
||||
/* Now allow letters, digits, and _. */
|
||||
while (isalnum (*p) || *p == '_')
|
||||
while (((p - start) < (int) sizeof (buf))
|
||||
&& (isalnum ((unsigned char) *p) || *p == '_'))
|
||||
++p;
|
||||
|
||||
if (p - *strp > 255)
|
||||
if (p - start >= (int) sizeof (buf))
|
||||
return "unrecognized keyword/register name";
|
||||
|
||||
memcpy (buf, *strp, p - *strp);
|
||||
buf[p - *strp] = 0;
|
||||
memcpy (buf, start, p - start);
|
||||
buf[p - start] = 0;
|
||||
|
||||
ke = cgen_keyword_lookup_name (keyword_table, buf);
|
||||
|
||||
if (ke != NULL)
|
||||
{
|
||||
*valuep = ke->value;
|
||||
*strp = p;
|
||||
/* Don't advance pointer if we recognized the null keyword. */
|
||||
if (ke->name[0] != 0)
|
||||
*strp = p;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -183,13 +257,12 @@ cgen_parse_keyword (strp, keyword_table, valuep)
|
||||
/* Signed integer parser. */
|
||||
|
||||
const char *
|
||||
cgen_parse_signed_integer (strp, opindex, min, max, valuep)
|
||||
cgen_parse_signed_integer (strp, opindex, valuep)
|
||||
const char **strp;
|
||||
int opindex;
|
||||
long min, max;
|
||||
long *valuep;
|
||||
{
|
||||
long value;
|
||||
bfd_vma value;
|
||||
enum cgen_parse_operand_result result;
|
||||
const char *errmsg;
|
||||
|
||||
@ -198,24 +271,19 @@ cgen_parse_signed_integer (strp, opindex, min, max, valuep)
|
||||
&result, &value);
|
||||
/* FIXME: Examine `result'. */
|
||||
if (!errmsg)
|
||||
{
|
||||
if (value < min || value > max)
|
||||
return "integer operand out of range";
|
||||
*valuep = value;
|
||||
}
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* Unsigned integer parser. */
|
||||
|
||||
const char *
|
||||
cgen_parse_unsigned_integer (strp, opindex, min, max, valuep)
|
||||
cgen_parse_unsigned_integer (strp, opindex, valuep)
|
||||
const char **strp;
|
||||
int opindex;
|
||||
unsigned long min, max;
|
||||
unsigned long *valuep;
|
||||
{
|
||||
unsigned long value;
|
||||
bfd_vma value;
|
||||
enum cgen_parse_operand_result result;
|
||||
const char *errmsg;
|
||||
|
||||
@ -224,33 +292,32 @@ cgen_parse_unsigned_integer (strp, opindex, min, max, valuep)
|
||||
&result, &value);
|
||||
/* FIXME: Examine `result'. */
|
||||
if (!errmsg)
|
||||
{
|
||||
if (value < min || value > max)
|
||||
return "integer operand out of range";
|
||||
*valuep = value;
|
||||
}
|
||||
*valuep = value;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/* Address parser. */
|
||||
|
||||
const char *
|
||||
cgen_parse_address (strp, opindex, opinfo, valuep)
|
||||
cgen_parse_address (strp, opindex, opinfo, resultp, valuep)
|
||||
const char **strp;
|
||||
int opindex;
|
||||
int opinfo;
|
||||
enum cgen_parse_operand_result *resultp;
|
||||
long *valuep;
|
||||
{
|
||||
long value;
|
||||
enum cgen_parse_operand_result result;
|
||||
bfd_vma value;
|
||||
enum cgen_parse_operand_result result_type;
|
||||
const char *errmsg;
|
||||
|
||||
errmsg = (*cgen_parse_operand_fn) (CGEN_PARSE_OPERAND_ADDRESS, strp,
|
||||
opindex, opinfo,
|
||||
&result, &value);
|
||||
&result_type, &value);
|
||||
/* FIXME: Examine `result'. */
|
||||
if (!errmsg)
|
||||
{
|
||||
if (resultp != NULL)
|
||||
*resultp = result_type;
|
||||
*valuep = value;
|
||||
}
|
||||
return errmsg;
|
||||
|
@ -30,10 +30,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
#include "@arch@-opc.h"
|
||||
|
||||
/* Look up instruction INSN_VALUE and extract its fields.
|
||||
If non-null INSN is the insn table entry.
|
||||
INSN, if non-null, is the insn table entry.
|
||||
Otherwise INSN_VALUE is examined to compute it.
|
||||
LENGTH is the bit length of INSN_VALUE if known, otherwise 0.
|
||||
0 is only valid if `insn == NULL && ! defined (CGEN_INT_INSN)'.
|
||||
If INSN != NULL, LENGTH must be valid.
|
||||
ALIAS_P is non-zero if alias insns are to be included in the search.
|
||||
|
||||
The result a pointer to the insn table entry, or NULL if the instruction
|
||||
wasn't recognized. */
|
||||
|
||||
@ -43,6 +46,7 @@ const CGEN_INSN *
|
||||
cgen_insn_t insn_value;
|
||||
int length;
|
||||
CGEN_FIELDS *fields;
|
||||
int alias_p;
|
||||
{
|
||||
char buf[16];
|
||||
|
||||
@ -91,9 +95,15 @@ const CGEN_INSN *
|
||||
extract handler. */
|
||||
if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
|
||||
{
|
||||
length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, fields);
|
||||
if (length > 0)
|
||||
return insn;
|
||||
int elength = (*CGEN_EXTRACT_FN (insn)) (insn, NULL,
|
||||
insn_value, fields);
|
||||
if (elength > 0)
|
||||
{
|
||||
/* sanity check */
|
||||
if (length != 0 && length != elength)
|
||||
abort ();
|
||||
return insn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,43 +116,34 @@ const CGEN_INSN *
|
||||
if (! alias_p
|
||||
&& CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
|
||||
abort ();
|
||||
/* Sanity check: length must be correct. */
|
||||
if (length != CGEN_INSN_BITSIZE (insn))
|
||||
abort ();
|
||||
|
||||
length = (*CGEN_EXTRACT_FN (insn)) (insn, NULL, insn_value, fields);
|
||||
if (length > 0)
|
||||
return insn;
|
||||
/* Sanity check: must succeed.
|
||||
Could relax this later if it ever proves useful. */
|
||||
if (length == 0)
|
||||
abort ();
|
||||
return insn;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Fill in the operand instances used by insn INSN_VALUE.
|
||||
If non-null INS is the insn table entry.
|
||||
Otherwise INSN_VALUE is examined to compute it.
|
||||
LENGTH is the number of bits in INSN_VALUE if known, otherwise 0.
|
||||
/* Fill in the operand instances used by INSN whose operands are FIELDS.
|
||||
INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
|
||||
in.
|
||||
The result a pointer to the insn table entry, or NULL if the instruction
|
||||
wasn't recognized. */
|
||||
in. */
|
||||
|
||||
const CGEN_INSN *
|
||||
@arch@_cgen_get_insn_operands (insn, insn_value, length, indices)
|
||||
const CGEN_INSN *insn;
|
||||
cgen_insn_t insn_value;
|
||||
int length;
|
||||
void
|
||||
@arch@_cgen_get_insn_operands (insn, fields, indices)
|
||||
const CGEN_INSN * insn;
|
||||
const CGEN_FIELDS * fields;
|
||||
int *indices;
|
||||
{
|
||||
CGEN_FIELDS fields;
|
||||
const CGEN_OPERAND_INSTANCE *opinst;
|
||||
int i;
|
||||
|
||||
/* FIXME: ALIAS insns are in transition from being record in the insn table
|
||||
to being recorded separately as macros. They don't have semantic code
|
||||
so they can't be used here. Thus we currently always ignore the INSN
|
||||
argument. */
|
||||
insn = @arch@_cgen_lookup_insn (NULL, insn_value, length, &fields, 0);
|
||||
if (! insn)
|
||||
return NULL;
|
||||
|
||||
for (i = 0, opinst = CGEN_INSN_OPERANDS (insn);
|
||||
opinst != NULL
|
||||
&& CGEN_OPERAND_INSTANCE_TYPE (opinst) != CGEN_OPERAND_INSTANCE_END;
|
||||
@ -152,8 +153,34 @@ const CGEN_INSN *
|
||||
if (op == NULL)
|
||||
indices[i] = CGEN_OPERAND_INSTANCE_INDEX (opinst);
|
||||
else
|
||||
indices[i] = @arch@_cgen_get_operand (CGEN_OPERAND_INDEX (op), &fields);
|
||||
indices[i] = @arch@_cgen_get_operand (CGEN_OPERAND_INDEX (op), fields);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cover function to @arch@_cgen_get_insn_operands when either INSN or FIELDS
|
||||
isn't known.
|
||||
The INSN, INSN_VALUE, and LENGTH arguments are passed to
|
||||
@arch@_cgen_lookup_insn unchanged.
|
||||
|
||||
The result is the insn table entry or NULL if the instruction wasn't
|
||||
recognized. */
|
||||
|
||||
const CGEN_INSN *
|
||||
@arch@_cgen_lookup_get_insn_operands (insn, insn_value, length, indices)
|
||||
const CGEN_INSN *insn;
|
||||
cgen_insn_t insn_value;
|
||||
int length;
|
||||
int *indices;
|
||||
{
|
||||
CGEN_FIELDS fields;
|
||||
|
||||
/* Pass non-zero for ALIAS_P only if INSN != NULL.
|
||||
If INSN == NULL, we want a real insn. */
|
||||
insn = @arch@_cgen_lookup_insn (insn, insn_value, length, &fields,
|
||||
insn != NULL);
|
||||
if (! insn)
|
||||
return NULL;
|
||||
|
||||
@arch@_cgen_get_insn_operands (insn, &fields, indices);
|
||||
return insn;
|
||||
}
|
||||
|
Reference in New Issue
Block a user