* cgen-asm.in (insert_normal): Use CGEN_BOOL_ATTR.

* cgen-asm.in (extract_normal): Ditto.
	* fr30-asm.c,fr30-dis.c,fr30-opc.h,fr30-opc.c: Regenerate.
	* i960c-asm.c,i960c-dis.c,i960c-opc.h,i960c-opc.c: Regenerate.
	* m32r-asm.c,m32r-dis.c,m32r-opc.h,m32r-opc.c: Regenerate.
This commit is contained in:
Doug Evans 1999-01-06 00:21:27 +00:00
parent 80909c45f8
commit 5730d39d2c
15 changed files with 2756 additions and 1990 deletions

View File

@ -1,3 +1,15 @@
1999-01-05 Doug Evans <devans@casey.cygnus.com>
start-sanitize-cygnus
* cgen-asm.in (insert_normal): Use CGEN_BOOL_ATTR.
* cgen-asm.in (extract_normal): Ditto.
end-sanitize-cygnus
start-sanitize-fr30
* fr30-asm.c,fr30-dis.c,fr30-opc.h,fr30-opc.c: Regenerate.
end-sanitize-fr30
* i960c-asm.c,i960c-dis.c,i960c-opc.h,i960c-opc.c: Regenerate.
* m32r-asm.c,m32r-dis.c,m32r-opc.h,m32r-opc.c: Regenerate.
1999-01-04 Jason Molenda (jsm@bugshack.cygnus.com)
* configure.in: Require autoconf 2.12.1 or higher.

View File

@ -30,127 +30,219 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
#include "@prefix@-opc.h"
#include "opintl.h"
/* ??? The layout of this stuff is still work in progress.
For speed in assembly/disassembly, we use inline functions. That of course
will only work for GCC. When this stuff is finished, we can decide whether
to keep the inline functions (and only get the performance increase when
compiled with GCC), or switch to macros, or use something else.
*/
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#undef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#undef INLINE
#ifdef __GNUC__
#define INLINE __inline__
#else
#define INLINE
#endif
/* Used by the ifield rtx function. */
#define FLD(f) (fields->f)
static const char * insert_normal
PARAMS ((long, unsigned int, int, int, int, char *));
PARAMS ((CGEN_OPCODE_DESC, long, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
static const char * parse_insn_normal
PARAMS ((const CGEN_INSN *, const char **, CGEN_FIELDS *));
PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
const char **, CGEN_FIELDS *));
static const char * insert_insn_normal
PARAMS ((const CGEN_INSN *, CGEN_FIELDS *, cgen_insn_t *, bfd_vma));
PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
/* -- assembler routines inserted here */
#if ! CGEN_INT_INSN_P
/* Subroutine of insert_normal. */
static INLINE void
insert_1 (od, value, start, length, word_length, bufp)
CGEN_OPCODE_DESC od;
unsigned long value;
int start,length,word_length;
unsigned char *bufp;
{
unsigned long x,mask;
int shift;
int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
switch (word_length)
{
case 8:
x = *bufp;
break;
case 16:
if (big_p)
x = bfd_getb16 (bufp);
else
x = bfd_getl16 (bufp);
break;
case 24:
/* ??? This may need reworking as these cases don't necessarily
want the first byte and the last two bytes handled like this. */
if (big_p)
x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
else
x = bfd_getl16 (bufp) | (bufp[2] << 16);
break;
case 32:
if (big_p)
x = bfd_getb32 (bufp);
else
x = bfd_getl32 (bufp);
break;
default :
abort ();
}
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
shift = (start + 1) - length;
else
shift = (word_length - (start + length));
x = (x & ~(mask << shift)) | ((value & mask) << shift);
switch (word_length)
{
case 8:
*bufp = x;
break;
case 16:
if (big_p)
bfd_putb16 (x, bufp);
else
bfd_putl16 (x, bufp);
break;
case 24:
/* ??? This may need reworking as these cases don't necessarily
want the first byte and the last two bytes handled like this. */
if (big_p)
{
bufp[0] = x >> 16;
bfd_putb16 (x, bufp + 1);
}
else
{
bfd_putl16 (x, bufp);
bufp[2] = x >> 16;
}
break;
case 32:
if (big_p)
bfd_putb32 (x, bufp);
else
bfd_putl32 (x, bufp);
break;
default :
abort ();
}
}
#endif /* ! CGEN_INT_INSN_P */
/* Default insertion routine.
ATTRS is a mask of the boolean attributes.
WORD_OFFSET is the offset in bits from the start of the insn of the value.
WORD_LENGTH is the length of the word in bits in which the value resides.
START is the starting bit number in the word, architecture origin.
LENGTH is the length of VALUE in bits.
TOTAL_LENGTH is the total length of the insn (currently 8,16,32).
TOTAL_LENGTH is the total length of the insn in bits.
The result is an error message or NULL if success. */
/* ??? This duplicates functionality with bfd's howto table and
bfd_install_relocation. */
/* ??? For architectures where insns can be representable as ints,
store insn in `field' struct and add registers, etc. while parsing? */
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static const char *
insert_normal (value, attrs, start, length, total_length, buffer)
insert_normal (od, value, attrs, word_offset, start, length, word_length,
total_length, buffer)
CGEN_OPCODE_DESC od;
long value;
unsigned int attrs;
int start;
int length;
int total_length;
char * buffer;
unsigned int word_offset, start, length, word_length, total_length;
CGEN_INSN_BYTES_PTR buffer;
{
bfd_vma x;
static char buf[100];
/* Written this way to avoid undefined behaviour.
Yes, `long' will be bfd_vma but not yet. */
long mask = (((1L << (length - 1)) - 1) << 1) | 1;
static char errbuf[100];
/* Written this way to avoid undefined behaviour. */
unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
/* If LENGTH is zero, this operand doesn't contribute to the value. */
if (length == 0)
return NULL;
if (CGEN_INT_INSN_P
&& word_offset != 0)
abort ();
if (word_length > 32)
abort ();
/* For architectures with insns smaller than the insn-base-bitsize,
word_length may be too big. */
#if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
if (word_offset == 0
&& word_length > total_length)
word_length = total_length;
#endif
/* Ensure VALUE will fit. */
if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0)
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
{
unsigned long max = mask;
if ((unsigned long) value > max)
unsigned long maxval = mask;
if ((unsigned long) value > maxval)
{
/* xgettext:c-format */
sprintf (buf, _("operand out of range (%lu not between 0 and %lu)"),
value, max);
return buf;
sprintf (errbuf,
_("operand out of range (%lu not between 0 and %lu)"),
value, maxval);
return errbuf;
}
}
else
{
long min = - (1L << (length - 1));
long max = (1L << (length - 1)) - 1;
if (value < min || value > max)
long minval = - (1L << (length - 1));
long maxval = (1L << (length - 1)) - 1;
if (value < minval || value > maxval)
{
sprintf
/* xgettext:c-format */
(buf, _("operand out of range (%ld not between %ld and %ld)"),
value, min, max);
return buf;
(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
value, minval, maxval);
return errbuf;
}
}
#if 0 /*def CGEN_INT_INSN*/
*buffer |= (value & mask) << (total_length - (start + length));
#else
switch (total_length)
{
case 8:
x = * (unsigned char *) buffer;
break;
case 16:
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
x = bfd_getb16 (buffer);
else
x = bfd_getl16 (buffer);
break;
case 32:
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
x = bfd_getb32 (buffer);
else
x = bfd_getl32 (buffer);
break;
default :
abort ();
}
#if CGEN_INT_INSN_P
x |= (value & mask) << (total_length - (start + length));
{
int shift;
switch (total_length)
{
case 8:
* buffer = value;
break;
case 16:
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
bfd_putb16 (x, buffer);
else
bfd_putl16 (x, buffer);
break;
case 32:
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
bfd_putb32 (x, buffer);
else
bfd_putl32 (x, buffer);
break;
default :
abort ();
}
#endif
if (CGEN_INSN_LSB0_P)
shift = (start + 1) - length;
else
shift = word_length - (start + length);
*buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
}
#else /* ! CGEN_INT_INSN_P */
{
unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
insert_1 (od, value, start, length, word_length, bufp);
}
#endif /* ! CGEN_INT_INSN_P */
return NULL;
}
@ -170,7 +262,8 @@ insert_normal (value, attrs, start, length, total_length, buffer)
*/
static const char *
parse_insn_normal (insn, strp, fields)
parse_insn_normal (od, insn, strp, fields)
CGEN_OPCODE_DESC od;
const CGEN_INSN * insn;
const char ** strp;
CGEN_FIELDS * fields;
@ -186,23 +279,25 @@ parse_insn_normal (insn, strp, fields)
#endif
/* For now we assume the mnemonic is first (there are no leading operands).
We can parse it without needing to set up operand parsing. */
We can parse it without needing to set up operand parsing.
GAS's input scrubber will ensure mnemonics are lowercase, but we may
not be called from GAS. */
p = CGEN_INSN_MNEMONIC (insn);
while (* p && * p == * str)
++ p, ++ str;
while (*p && tolower (*p) == tolower (*str))
++p, ++str;
if (* p || (* str && !isspace (* str)))
return _("unrecognized instruction");
CGEN_INIT_PARSE ();
cgen_init_parse_operand ();
CGEN_INIT_PARSE (od);
cgen_init_parse_operand (od);
#ifdef CGEN_MNEMONIC_OPERANDS
past_opcode_p = 0;
#endif
/* We don't check for (*str != '\0') here because we want to parse
any trailing fake arguments in the syntax string. */
syn = CGEN_SYNTAX_STRING (CGEN_INSN_SYNTAX (insn));
syn = CGEN_SYNTAX_STRING (syntax);
/* Mnemonics come first for now, ensure valid string. */
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
@ -235,8 +330,8 @@ parse_insn_normal (insn, strp, fields)
}
/* We have an operand of some sort. */
errmsg = @arch@_cgen_parse_operand (CGEN_SYNTAX_FIELD (*syn),
&str, fields);
errmsg = @arch@_cgen_parse_operand (od, CGEN_SYNTAX_FIELD (*syn),
&str, fields);
if (errmsg)
return errmsg;
@ -261,59 +356,50 @@ parse_insn_normal (insn, strp, fields)
}
/* We couldn't parse it. */
return "unrecognized instruction";
return _("unrecognized instruction");
}
/* Default insn builder (insert handler).
The instruction is recorded in target byte order.
The instruction is recorded in CGEN_INT_INSN_P byte order
(meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
recorded in host byte order, otherwise BUFFER is an array of bytes and the
value is recorded in target byte order).
The result is an error message or NULL if success. */
/* FIXME: change buffer to char *? */
static const char *
insert_insn_normal (insn, fields, buffer, pc)
insert_insn_normal (od, insn, fields, buffer, pc)
CGEN_OPCODE_DESC od;
const CGEN_INSN * insn;
CGEN_FIELDS * fields;
cgen_insn_t * buffer;
CGEN_INSN_BYTES_PTR buffer;
bfd_vma pc;
{
const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
bfd_vma value;
unsigned long value;
const unsigned char * syn;
CGEN_INIT_INSERT ();
value = CGEN_INSN_VALUE (insn);
CGEN_INIT_INSERT (od);
value = CGEN_INSN_BASE_VALUE (insn);
/* If we're recording insns as numbers (rather than a string of bytes),
target byte order handling is deferred until later. */
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#if 0 /*def CGEN_INT_INSN*/
*buffer = value;
#else
switch (min (CGEN_BASE_INSN_BITSIZE, CGEN_FIELDS_BITSIZE (fields)))
{
case 8:
* buffer = value;
break;
case 16:
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
bfd_putb16 (value, (char *) buffer);
else
bfd_putl16 (value, (char *) buffer);
break;
case 32:
if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
bfd_putb32 (value, (char *) buffer);
else
bfd_putl32 (value, (char *) buffer);
break;
default:
abort ();
}
#endif
/* ??? Rather than scanning the syntax string again, we could store
in `fields' a null terminated list of the fields that are present. */
#if CGEN_INT_INSN_P
*buffer = value;
#else
cgen_put_insn_value (od, buffer, min (CGEN_BASE_INSN_BITSIZE,
CGEN_FIELDS_BITSIZE (fields)),
value);
#endif /* ! CGEN_INT_INSN_P */
/* ??? It would be better to scan the format's fields.
Still need to be able to insert a value based on the operand though;
e.g. storing a branch displacement that got resolved later.
Needs more thought first. */
for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
{
@ -322,8 +408,8 @@ insert_insn_normal (insn, fields, buffer, pc)
if (CGEN_SYNTAX_CHAR_P (* syn))
continue;
errmsg = @arch@_cgen_insert_operand (CGEN_SYNTAX_FIELD (*syn), fields,
(char *) buffer, pc);
errmsg = @arch@_cgen_insert_operand (od, CGEN_SYNTAX_FIELD (*syn),
fields, buffer, pc);
if (errmsg)
return errmsg;
}
@ -335,8 +421,10 @@ insert_insn_normal (insn, fields, buffer, pc)
This routine is called for each instruction to be assembled.
STR points to the insn to be assembled.
We assume all necessary tables have been initialized.
The assembled instruction, less any fixups, is stored in buf.
[??? What byte order?]
The assembled instruction, less any fixups, is stored in BUF.
Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
still needs to be converted to target byte order, otherwise BUF is an array
of bytes in target byte order.
The result is a pointer to the insn's entry in the opcode table,
or NULL if an error occured (an error message will have already been
printed).
@ -345,10 +433,11 @@ insert_insn_normal (insn, fields, buffer, pc)
this function recurses. */
const CGEN_INSN *
@arch@_cgen_assemble_insn (str, fields, buf, errmsg)
@arch@_cgen_assemble_insn (od, str, fields, buf, errmsg)
CGEN_OPCODE_DESC od;
const char * str;
CGEN_FIELDS * fields;
cgen_insn_t * buf;
CGEN_INSN_BYTES_PTR buf;
char ** errmsg;
{
const char * start;
@ -360,7 +449,7 @@ const CGEN_INSN *
/* The instructions are stored in hashed lists.
Get the first in the list. */
ilist = CGEN_ASM_LOOKUP_INSN (str);
ilist = CGEN_ASM_LOOKUP_INSN (od, str);
/* Keep looking until we find a match. */
@ -371,7 +460,7 @@ const CGEN_INSN *
#if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
/* Is this insn supported by the selected cpu? */
if (! @arch@_cgen_insn_supported (insn))
if (! @arch@_cgen_insn_supported (od, insn))
continue;
#endif
@ -383,15 +472,13 @@ const CGEN_INSN *
str = start;
/* Record a default length for the insn. This will get set to the
correct value while parsing. */
/* FIXME: wip */
/* Allow parse/insert handlers to obtain length of insn. */
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
if (! CGEN_PARSE_FN (insn) (insn, & str, fields))
if (! CGEN_PARSE_FN (insn) (od, insn, & str, fields))
{
/* ??? 0 is passed for `pc' */
if (CGEN_INSERT_FN (insn) (insn, fields, buf, (bfd_vma) 0) != NULL)
if (CGEN_INSERT_FN (insn) (od, insn, fields, buf, (bfd_vma) 0) != NULL)
continue;
/* It is up to the caller to actually output the insn and any
queued relocs. */
@ -427,7 +514,8 @@ const CGEN_INSN *
FIXME: Not currently used. */
void
@arch@_cgen_asm_hash_keywords (opvals)
@arch@_cgen_asm_hash_keywords (od, opvals)
CGEN_OPCODE_DESC od;
CGEN_KEYWORD * opvals;
{
CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
@ -439,7 +527,7 @@ void
if (! @arch@_cgen_opval_supported (ke))
continue;
#endif
cgen_asm_record_register (ke->name, ke->value);
cgen_asm_record_register (od, ke->name, ke->value);
}
}

View File

@ -40,9 +40,13 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
/* Default text to print if an instruction isn't recognized. */
#define UNKNOWN_INSN_MSG _("*unknown*")
/* Used by the ifield rtx function. */
#define FLD(f) (fields->f)
static int extract_normal
PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_BYTES,
unsigned int, int, int, int, long *));
PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, bfd_vma, long *));
static void print_normal
PARAMS ((CGEN_OPCODE_DESC, PTR, long, unsigned int, bfd_vma, int));
static void print_address
@ -51,7 +55,7 @@ static void print_keyword
PARAMS ((CGEN_OPCODE_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
static int extract_insn_normal
PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
unsigned long, CGEN_FIELDS *, bfd_vma));
CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
static void print_insn_normal
PARAMS ((CGEN_OPCODE_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
bfd_vma, int));
@ -64,21 +68,68 @@ static int default_print_insn
#if ! CGEN_INT_INSN_P
/* Subroutine of extract_normal.
Ensure sufficient bytes are cached in EX_INFO.
OFFSET is the offset in bytes from the start of the insn of the value.
BYTES is the length of the needed value.
Returns 1 for success, 0 for failure. */
static INLINE int
fill_cache (od, ex_info, offset, bytes, pc)
CGEN_OPCODE_DESC od;
CGEN_EXTRACT_INFO *ex_info;
int offset, bytes;
bfd_vma pc;
{
/* It's doubtful that the middle part has already been fetched so
we don't optimize that case. kiss. */
int mask;
disassemble_info *info = (disassemble_info *) ex_info->dis_info;
/* First do a quick check. */
mask = (1 << bytes) - 1;
if (((ex_info->valid >> offset) & mask) == mask)
return 1;
/* Search for the first byte we need to read. */
for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
if (! (mask & ex_info->valid))
break;
if (bytes)
{
int status;
pc += offset;
status = (*info->read_memory_func)
(pc, ex_info->insn_bytes + offset, bytes, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return 0;
}
ex_info->valid |= ((1 << bytes) - 1) << offset;
}
return 1;
}
/* Subroutine of extract_normal. */
static INLINE long
extract_1 (od, ex_info, start, length, word_length, bufp)
extract_1 (od, ex_info, start, length, word_length, bufp, pc)
CGEN_OPCODE_DESC od;
CGEN_EXTRACT_INFO *info;
CGEN_EXTRACT_INFO *ex_info;
int start,length,word_length;
unsigned char *bufp;
bfd_vma pc;
{
unsigned long x,mask;
int shift;
int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
/* FIXME: Need to use ex_info to ensure bytes have been fetched. */
switch (word_length)
{
case 8:
@ -94,9 +145,9 @@ extract_1 (od, ex_info, start, length, word_length, bufp)
/* ??? This may need reworking as these cases don't necessarily
want the first byte and the last two bytes handled like this. */
if (big_p)
x = (bfd_getb8 (bufp) << 16) | bfd_getb16 (bufp + 1);
x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
else
x = bfd_getl16 (bufp) | (bfd_getb8 (bufp + 2) << 16);
x = bfd_getl16 (bufp) | (bufp[2] << 16);
break;
case 32:
if (big_p)
@ -111,7 +162,7 @@ extract_1 (od, ex_info, start, length, word_length, bufp)
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
shift = start;
shift = (start + 1) - length;
else
shift = (word_length - (start + length));
return (x >> shift) & mask;
@ -121,22 +172,36 @@ extract_1 (od, ex_info, start, length, word_length, bufp)
/* Default extraction routine.
ATTRS is a mask of the boolean attributes. We only need `unsigned',
but for generality we take a bitmask of all of them. */
INSN_VALUE is the first CGEN_BASE_INSN_SIZE bits of the insn in host order,
or sometimes less for cases like the m32r where the base insn size is 32
but some insns are 16 bits.
ATTRS is a mask of the boolean attributes. We only need `UNSIGNED',
but for generality we take a bitmask of all of them.
WORD_OFFSET is the offset in bits from the start of the insn of the value.
WORD_LENGTH is the length of the word in bits in which the value resides.
START is the starting bit number in the word, architecture origin.
LENGTH is the length of VALUE in bits.
TOTAL_LENGTH is the total length of the insn in bits.
Returns 1 for success, 0 for failure. */
/* ??? The return code isn't properly used. wip. */
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static int
extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, valuep)
extract_normal (od, ex_info, insn_value, attrs, word_offset, start, length,
word_length, total_length, pc, valuep)
CGEN_OPCODE_DESC od;
CGEN_EXTRACT_INFO *ex_info;
CGEN_INSN_BYTES insn_value;
CGEN_INSN_INT insn_value;
unsigned int attrs;
int start, length, total_length;
unsigned int word_offset, start, length, word_length, total_length;
bfd_vma pc;
long *valuep;
{
unsigned long value;
CGEN_INSN_INT value;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */
@ -146,100 +211,58 @@ extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, val
return 1;
}
#if CGEN_INT_INSN_P
if (CGEN_INT_INSN_P
&& word_offset != 0)
abort ();
{
/* Written this way to avoid undefined behaviour. */
unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (word_length > 32)
abort ();
if (CGEN_INSN_LSB0_P)
value = insn_value >> start;
else
value = insn_value >> (total_length - (start + length));
value &= mask;
/* sign extend? */
if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
&& (value & (1L << (length - 1))))
value |= ~mask;
}
#else
/* The hard case is probably too slow for the normal cases.
It's certainly more difficult to understand than the normal case.
Thus this is split into two. Keep it that way. The hard case is defined
to be when a field straddles a (loosely defined) word boundary
(??? which may require target specific help to determine). */
#if 0 /*wip*/
#define HARD_CASE_P 0 /* FIXME:wip */
if (HARD_CASE_P)
{
}
/* For architectures with insns smaller than the insn-base-bitsize,
word_length may be too big. */
#if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
if (word_offset == 0
&& word_length > total_length)
word_length = total_length;
#endif
/* Does the value reside in INSN_VALUE? */
if (word_offset == 0)
{
/* Written this way to avoid undefined behaviour. */
CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
value = insn_value >> ((start + 1) - length);
else
value = insn_value >> (word_length - (start + length));
value &= mask;
/* sign extend? */
if (! CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED)
&& (value & (1L << (length - 1))))
value |= ~mask;
}
#if ! CGEN_INT_INSN_P
else
{
unsigned char *bufp = (unsigned char *) insn_value;
unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
if (length > 32)
if (word_length > 32)
abort ();
/* Adjust start,total_length,bufp to point to the pseudo-word that holds
the value. For example in a 48 bit insn where the value to insert
(say an immediate value) is the last 16 bits then word_length here
would be 16. To handle a 24 bit insn with an 18 bit immediate,
extract_1 handles 24 bits (using a combination of bfd_get8,16). */
if (fill_cache (od, ex_info, word_offset / 8, word_length / 8, pc) == 0)
return 0;
if (total_length > 32)
{
int needed_width = start % 8 + length;
int fetch_length = (needed_width <= 8 ? 8
: needed_width <= 16 ? 16
: 32);
if (CGEN_INSN_LSB0_P)
{
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
{
abort (); /* wip */
}
else
{
int offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length -= offset;
}
}
else
{
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
{
int offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length -= offset;
}
else
{
abort (); /* wip */
}
}
}
/* FIXME: which bytes are being extracted have been lost. */
value = extract_1 (od, ex_info, start, length, total_length, bufp);
value = extract_1 (od, ex_info, start, length, word_length, bufp, pc);
}
#endif /* ! CGEN_INT_INSN_P */
*valuep = value;
/* FIXME: for now */
return 1;
}
@ -333,7 +356,7 @@ extract_insn_normal (od, insn, ex_info, insn_value, fields, pc)
CGEN_OPCODE_DESC od;
const CGEN_INSN *insn;
CGEN_EXTRACT_INFO *ex_info;
unsigned long insn_value;
CGEN_INSN_INT insn_value;
CGEN_FIELDS *fields;
bfd_vma pc;
{
@ -420,7 +443,7 @@ print_insn (od, pc, info, buf, buflen)
ex_info.dis_info = info;
ex_info.valid = (1 << CGEN_BASE_INSN_SIZE) - 1;
ex_info.bytes = buf;
ex_info.insn_bytes = buf;
switch (buflen)
{
@ -456,7 +479,8 @@ print_insn (od, pc, info, buf, buflen)
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
if ((insn_value & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
/* Printing is handled in two passes. The first pass parses the
machine insn and extracts the fields. The second pass prints

View File

@ -79,12 +79,13 @@ parse_register_number (strp)
}
static const char *
parse_register_list (od, strp, opindex, valuep, high_low)
parse_register_list (od, strp, opindex, valuep, high_low, load_store)
CGEN_OPCODE_DESC od;
const char **strp;
int opindex;
unsigned long *valuep;
int high_low;
int high_low; /* 0 == high, 1 == low */
int load_store; /* 0 == load, 1 == store */
{
int regno;
*valuep = 0;
@ -105,7 +106,10 @@ parse_register_list (od, strp, opindex, valuep, high_low)
if (high_low)
regno -= 8;
*valuep |= 1 << regno;
if (load_store) /* mask is reversed for store */
*valuep |= 0x80 >> regno;
else
*valuep |= 1 << regno;
if (**strp == ',')
{
@ -122,23 +126,43 @@ parse_register_list (od, strp, opindex, valuep, high_low)
}
static const char *
parse_low_register_list (od, strp, opindex, valuep)
parse_low_register_list_ld (od, strp, opindex, valuep)
CGEN_OPCODE_DESC od;
const char **strp;
int opindex;
unsigned long *valuep;
{
return parse_register_list (od, strp, opindex, valuep, 0/*low*/);
return parse_register_list (od, strp, opindex, valuep, 0/*low*/, 0/*load*/);
}
static const char *
parse_hi_register_list (od, strp, opindex, valuep)
parse_hi_register_list_ld (od, strp, opindex, valuep)
CGEN_OPCODE_DESC od;
const char **strp;
int opindex;
unsigned long *valuep;
{
return parse_register_list (od, strp, opindex, valuep, 1/*high*/);
return parse_register_list (od, strp, opindex, valuep, 1/*high*/, 0/*load*/);
}
static const char *
parse_low_register_list_st (od, strp, opindex, valuep)
CGEN_OPCODE_DESC od;
const char **strp;
int opindex;
unsigned long *valuep;
{
return parse_register_list (od, strp, opindex, valuep, 0/*low*/, 1/*store*/);
}
static const char *
parse_hi_register_list_st (od, strp, opindex, valuep)
CGEN_OPCODE_DESC od;
const char **strp;
int opindex;
unsigned long *valuep;
{
return parse_register_list (od, strp, opindex, valuep, 1/*high*/, 1/*store*/);
}
/* -- */
@ -266,11 +290,17 @@ fr30_cgen_parse_operand (od, opindex, strp, fields)
fields->f_rel12 = value;
}
break;
case FR30_OPERAND_REGLIST_LOW :
errmsg = parse_low_register_list (od, strp, FR30_OPERAND_REGLIST_LOW, &fields->f_reglist_low);
case FR30_OPERAND_REGLIST_LOW_LD :
errmsg = parse_low_register_list_ld (od, strp, FR30_OPERAND_REGLIST_LOW_LD, &fields->f_reglist_low_ld);
break;
case FR30_OPERAND_REGLIST_HI :
errmsg = parse_hi_register_list (od, strp, FR30_OPERAND_REGLIST_HI, &fields->f_reglist_hi);
case FR30_OPERAND_REGLIST_HI_LD :
errmsg = parse_hi_register_list_ld (od, strp, FR30_OPERAND_REGLIST_HI_LD, &fields->f_reglist_hi_ld);
break;
case FR30_OPERAND_REGLIST_LOW_ST :
errmsg = parse_low_register_list_st (od, strp, FR30_OPERAND_REGLIST_LOW_ST, &fields->f_reglist_low_st);
break;
case FR30_OPERAND_REGLIST_HI_ST :
errmsg = parse_hi_register_list_st (od, strp, FR30_OPERAND_REGLIST_HI_ST, &fields->f_reglist_hi_st);
break;
case FR30_OPERAND_CC :
errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_CC, &fields->f_cc);
@ -372,27 +402,27 @@ fr30_cgen_insert_operand (od, opindex, fields, buffer, pc)
}
break;
case FR30_OPERAND_DISP8 :
errmsg = insert_normal (od, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 4, 8, 16, total_length, buffer);
errmsg = insert_normal (od, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, buffer);
break;
case FR30_OPERAND_DISP9 :
{
long value = fields->f_disp9;
value = ((int) (value) >> (1));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 4, 8, 16, total_length, buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, buffer);
}
break;
case FR30_OPERAND_DISP10 :
{
long value = fields->f_disp10;
value = ((int) (value) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 4, 8, 16, total_length, buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, buffer);
}
break;
case FR30_OPERAND_S10 :
{
long value = fields->f_s10;
value = ((int) (value) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 8, 8, 16, total_length, buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 8, 8, 16, total_length, buffer);
}
break;
case FR30_OPERAND_U10 :
@ -447,21 +477,27 @@ do {
{
long value = fields->f_rel9;
value = ((int) (((value) - (((pc) + (2))))) >> (1));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 0, 8, 8, 16, total_length, buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
}
break;
case FR30_OPERAND_LABEL12 :
{
long value = fields->f_rel12;
value = ((int) (((value) - (((pc) + (2))))) >> (1));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 0, 5, 11, 16, total_length, buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
}
break;
case FR30_OPERAND_REGLIST_LOW :
errmsg = insert_normal (od, fields->f_reglist_low, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
case FR30_OPERAND_REGLIST_LOW_LD :
errmsg = insert_normal (od, fields->f_reglist_low_ld, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
break;
case FR30_OPERAND_REGLIST_HI :
errmsg = insert_normal (od, fields->f_reglist_hi, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
case FR30_OPERAND_REGLIST_HI_LD :
errmsg = insert_normal (od, fields->f_reglist_hi_ld, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
break;
case FR30_OPERAND_REGLIST_LOW_ST :
errmsg = insert_normal (od, fields->f_reglist_low_st, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
break;
case FR30_OPERAND_REGLIST_HI_ST :
errmsg = insert_normal (od, fields->f_reglist_hi_st, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
break;
case FR30_OPERAND_CC :
errmsg = insert_normal (od, fields->f_cc, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 16, total_length, buffer);
@ -638,7 +674,7 @@ insert_normal (od, value, attrs, word_offset, start, length, word_length,
#endif
/* Ensure VALUE will fit. */
if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0)
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
{
unsigned long maxval = mask;
if ((unsigned long) value > maxval)

View File

@ -68,28 +68,45 @@ static int default_print_insn
/* -- dis.c */
static void
print_register_list (dis_info, value, offset)
print_register_list (dis_info, value, offset, load_store)
PTR dis_info;
long value;
long offset;
int load_store; /* 0 == load, 1 == store */
{
disassemble_info *info = dis_info;
int mask = 1;
int mask;
int index = 0;
char* comma = "";
if (load_store)
mask = 0x80;
else
mask = 1;
if (value & mask)
(*info->fprintf_func) (info->stream, "r%i", index + offset);
{
(*info->fprintf_func) (info->stream, "r%i", index + offset);
comma = ",";
}
for (index = 1; index <= 7; ++index)
{
mask <<= 1;
if (load_store)
mask >>= 1;
else
mask <<= 1;
if (value & mask)
(*info->fprintf_func) (info->stream, ",r%i", index + offset);
{
(*info->fprintf_func) (info->stream, "%sr%i", comma, index + offset);
comma = ",";
}
}
}
static void
print_hi_register_list (od, dis_info, value, attrs, pc, length)
print_hi_register_list_ld (od, dis_info, value, attrs, pc, length)
CGEN_OPCODE_DESC od;
PTR dis_info;
long value;
@ -97,11 +114,11 @@ print_hi_register_list (od, dis_info, value, attrs, pc, length)
bfd_vma pc;
int length;
{
print_register_list (dis_info, value, 8);
print_register_list (dis_info, value, 8, 0/*load*/);
}
static void
print_low_register_list (od, dis_info, value, attrs, pc, length)
print_low_register_list_ld (od, dis_info, value, attrs, pc, length)
CGEN_OPCODE_DESC od;
PTR dis_info;
long value;
@ -109,7 +126,31 @@ print_low_register_list (od, dis_info, value, attrs, pc, length)
bfd_vma pc;
int length;
{
print_register_list (dis_info, value, 0);
print_register_list (dis_info, value, 0, 0/*load*/);
}
static void
print_hi_register_list_st (od, dis_info, value, attrs, pc, length)
CGEN_OPCODE_DESC od;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
print_register_list (dis_info, value, 8, 1/*store*/);
}
static void
print_low_register_list_st (od, dis_info, value, attrs, pc, length)
CGEN_OPCODE_DESC od;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
print_register_list (dis_info, value, 0, 1/*store*/);
}
static void
@ -211,12 +252,12 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
}
break;
case FR30_OPERAND_DISP8 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
break;
case FR30_OPERAND_DISP9 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, pc, & value);
value = ((value) << (1));
fields->f_disp9 = value;
}
@ -224,7 +265,7 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
case FR30_OPERAND_DISP10 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 4, 8, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_disp10 = value;
}
@ -232,7 +273,7 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
case FR30_OPERAND_S10 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 8, 8, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_s10 = value;
}
@ -287,7 +328,7 @@ do {
case FR30_OPERAND_LABEL9 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 8, 16, total_length, pc, & value);
value = ((((value) << (1))) + (((pc) + (2))));
fields->f_rel9 = value;
}
@ -295,16 +336,22 @@ do {
case FR30_OPERAND_LABEL12 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 0, 5, 11, 16, total_length, pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 5, 11, 16, total_length, pc, & value);
value = ((((value) << (1))) + (((pc) + (2))));
fields->f_rel12 = value;
}
break;
case FR30_OPERAND_REGLIST_LOW :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low);
case FR30_OPERAND_REGLIST_LOW_LD :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
break;
case FR30_OPERAND_REGLIST_HI :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi);
case FR30_OPERAND_REGLIST_HI_LD :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
break;
case FR30_OPERAND_REGLIST_LOW_ST :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
break;
case FR30_OPERAND_REGLIST_HI_ST :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
break;
case FR30_OPERAND_CC :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 16, total_length, pc, & fields->f_cc);
@ -401,16 +448,16 @@ fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
print_normal (od, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_DISP8 :
print_normal (od, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
print_normal (od, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case FR30_OPERAND_DISP9 :
print_normal (od, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
print_normal (od, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case FR30_OPERAND_DISP10 :
print_normal (od, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
print_normal (od, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case FR30_OPERAND_S10 :
print_normal (od, info, fields->f_s10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
print_normal (od, info, fields->f_s10, 0|(1<<CGEN_OPERAND_HASH_PREFIX), pc, length);
break;
case FR30_OPERAND_U10 :
print_normal (od, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
@ -434,16 +481,22 @@ fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
print_normal (od, info, fields->f_dir10, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_LABEL9 :
print_address (od, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), pc, length);
print_address (od, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case FR30_OPERAND_LABEL12 :
print_address (od, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), pc, length);
print_address (od, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case FR30_OPERAND_REGLIST_LOW :
print_low_register_list (od, info, fields->f_reglist_low, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
case FR30_OPERAND_REGLIST_LOW_LD :
print_low_register_list_ld (od, info, fields->f_reglist_low_ld, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_REGLIST_HI :
print_hi_register_list (od, info, fields->f_reglist_hi, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
case FR30_OPERAND_REGLIST_HI_LD :
print_hi_register_list_ld (od, info, fields->f_reglist_hi_ld, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_REGLIST_LOW_ST :
print_low_register_list_st (od, info, fields->f_reglist_low_st, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_REGLIST_HI_ST :
print_hi_register_list_st (od, info, fields->f_reglist_hi_st, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_CC :
print_normal (od, info, fields->f_cc, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
@ -653,7 +706,7 @@ extract_normal (od, ex_info, insn_value, attrs, word_offset, start, length,
value = insn_value >> (word_length - (start + length));
value &= mask;
/* sign extend? */
if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
if (! CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED)
&& (value & (1L << (length - 1))))
value |= ~mask;
}

File diff suppressed because it is too large Load Diff

View File

@ -103,11 +103,11 @@ typedef enum insn_cc {
/* Enum declaration for general registers. */
typedef enum h_gr {
H_GR_AC = 13, H_GR_FP = 14, H_GR_SP = 15, H_GR_R0 = 0
, H_GR_R1 = 1, H_GR_R2 = 2, H_GR_R3 = 3, H_GR_R4 = 4
, H_GR_R5 = 5, H_GR_R6 = 6, H_GR_R7 = 7, H_GR_R8 = 8
, H_GR_R9 = 9, H_GR_R10 = 10, H_GR_R11 = 11, H_GR_R12 = 12
, H_GR_R13 = 13, H_GR_R14 = 14, H_GR_R15 = 15
H_GR_R0 = 0, H_GR_R1 = 1, H_GR_R2 = 2, H_GR_R3 = 3
, H_GR_R4 = 4, H_GR_R5 = 5, H_GR_R6 = 6, H_GR_R7 = 7
, H_GR_R8 = 8, H_GR_R9 = 9, H_GR_R10 = 10, H_GR_R11 = 11
, H_GR_R12 = 12, H_GR_R13 = 13, H_GR_R14 = 14, H_GR_R15 = 15
, H_GR_AC = 13, H_GR_FP = 14, H_GR_SP = 15
} H_GR;
/* Enum declaration for coprocessor registers. */
@ -144,24 +144,7 @@ typedef enum h_r15 {
H_R15_R15
} H_R15;
/* Enum declaration for fr30 operand types. */
typedef enum cgen_operand_type {
FR30_OPERAND_PC, FR30_OPERAND_RI, FR30_OPERAND_RJ, FR30_OPERAND_RIC
, FR30_OPERAND_RJC, FR30_OPERAND_CRI, FR30_OPERAND_CRJ, FR30_OPERAND_RS1
, FR30_OPERAND_RS2, FR30_OPERAND_R13, FR30_OPERAND_R14, FR30_OPERAND_R15
, FR30_OPERAND_PS, FR30_OPERAND_U4, FR30_OPERAND_U4C, FR30_OPERAND_U8
, FR30_OPERAND_I8, FR30_OPERAND_UDISP6, FR30_OPERAND_DISP8, FR30_OPERAND_DISP9
, FR30_OPERAND_DISP10, FR30_OPERAND_S10, FR30_OPERAND_U10, FR30_OPERAND_I32
, FR30_OPERAND_M4, FR30_OPERAND_I20, FR30_OPERAND_DIR8, FR30_OPERAND_DIR9
, FR30_OPERAND_DIR10, FR30_OPERAND_LABEL9, FR30_OPERAND_LABEL12, FR30_OPERAND_REGLIST_LOW_LD
, FR30_OPERAND_REGLIST_HI_LD, FR30_OPERAND_REGLIST_LOW_ST, FR30_OPERAND_REGLIST_HI_ST, FR30_OPERAND_CC
, FR30_OPERAND_CCC, FR30_OPERAND_NBIT, FR30_OPERAND_VBIT, FR30_OPERAND_ZBIT
, FR30_OPERAND_CBIT, FR30_OPERAND_IBIT, FR30_OPERAND_SBIT, FR30_OPERAND_TBIT
, FR30_OPERAND_D0BIT, FR30_OPERAND_D1BIT, FR30_OPERAND_CCR, FR30_OPERAND_SCR
, FR30_OPERAND_ILM, FR30_OPERAND_MAX
} CGEN_OPERAND_TYPE;
/* Non-boolean attributes. */
/* Attributes. */
/* Enum declaration for machine type selection. */
typedef enum mach_attr {
@ -171,32 +154,16 @@ typedef enum mach_attr {
/* Number of architecture variants. */
#define MAX_MACHS ((int) MACH_MAX)
/* Number of operands types. */
#define MAX_OPERANDS ((int) FR30_OPERAND_MAX)
/* Maximum number of operands referenced by any insn. */
#define MAX_OPERAND_INSTANCES 12
/* Hardware, operand and instruction attribute indices. */
/* Enum declaration for cgen_hw attrs. */
typedef enum cgen_hw_attr {
CGEN_HW_CACHE_ADDR, CGEN_HW_FUN_ACCESS, CGEN_HW_PC, CGEN_HW_PROFILE
} CGEN_HW_ATTR;
/* Number of non-boolean elements in cgen_hw. */
#define CGEN_HW_NBOOL_ATTRS ((int) CGEN_HW_CACHE_ADDR)
/* Hardware, operand and instruction attribute indices. */
/* Ifield attribute indices. */
/* Enum declaration for cgen_ifld attrs. */
typedef enum cgen_ifld_attr {
CGEN_IFLD_ABS_ADDR, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_RESERVED, CGEN_IFLD_SIGN_OPT
, CGEN_IFLD_SIGNED, CGEN_IFLD_UNSIGNED, CGEN_IFLD_VIRTUAL
CGEN_IFLD_MACH, CGEN_IFLD_VIRTUAL, CGEN_IFLD_UNSIGNED, CGEN_IFLD_PCREL_ADDR
, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED, CGEN_IFLD_SIGN_OPT
} CGEN_IFLD_ATTR;
/* Number of non-boolean elements in cgen_ifld. */
#define CGEN_IFLD_NBOOL_ATTRS ((int) CGEN_IFLD_ABS_ADDR)
#define CGEN_IFLD_NBOOL_ATTRS ((int) CGEN_IFLD_VIRTUAL)
/* Enum declaration for fr30 ifield types. */
typedef enum ifield_type {
@ -215,25 +182,76 @@ typedef enum ifield_type {
#define MAX_IFLD ((int) FR30_F_MAX)
/* Hardware attribute indices. */
/* Enum declaration for cgen_hw attrs. */
typedef enum cgen_hw_attr {
CGEN_HW_MACH, CGEN_HW_VIRTUAL, CGEN_HW_UNSIGNED, CGEN_HW_SIGNED
, CGEN_HW_CACHE_ADDR, CGEN_HW_FUN_ACCESS, CGEN_HW_PC, CGEN_HW_PROFILE
} CGEN_HW_ATTR;
/* Number of non-boolean elements in cgen_hw. */
#define CGEN_HW_NBOOL_ATTRS ((int) CGEN_HW_VIRTUAL)
/* Enum declaration for fr30 hardware types. */
typedef enum hw_type {
HW_H_PC, HW_H_MEMORY, HW_H_SINT, HW_H_UINT
, HW_H_ADDR, HW_H_IADDR, HW_H_GR, HW_H_CR
, HW_H_DR, HW_H_PS, HW_H_R13, HW_H_R14
, HW_H_R15, HW_H_NBIT, HW_H_ZBIT, HW_H_VBIT
, HW_H_CBIT, HW_H_IBIT, HW_H_SBIT, HW_H_TBIT
, HW_H_D0BIT, HW_H_D1BIT, HW_H_CCR, HW_H_SCR
, HW_H_ILM, HW_MAX
} HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Operand attribute indices. */
/* Enum declaration for cgen_operand attrs. */
typedef enum cgen_operand_attr {
CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_HASH_PREFIX, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_PCREL_ADDR
, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY, CGEN_OPERAND_SIGN_OPT, CGEN_OPERAND_SIGNED
, CGEN_OPERAND_UNSIGNED, CGEN_OPERAND_VIRTUAL
CGEN_OPERAND_MACH, CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_UNSIGNED, CGEN_OPERAND_PCREL_ADDR
, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX
, CGEN_OPERAND_SEM_ONLY, CGEN_OPERAND_HASH_PREFIX
} CGEN_OPERAND_ATTR;
/* Number of non-boolean elements in cgen_operand. */
#define CGEN_OPERAND_NBOOL_ATTRS ((int) CGEN_OPERAND_ABS_ADDR)
#define CGEN_OPERAND_NBOOL_ATTRS ((int) CGEN_OPERAND_VIRTUAL)
/* Enum declaration for fr30 operand types. */
typedef enum cgen_operand_type {
FR30_OPERAND_PC, FR30_OPERAND_RI, FR30_OPERAND_RJ, FR30_OPERAND_RIC
, FR30_OPERAND_RJC, FR30_OPERAND_CRI, FR30_OPERAND_CRJ, FR30_OPERAND_RS1
, FR30_OPERAND_RS2, FR30_OPERAND_R13, FR30_OPERAND_R14, FR30_OPERAND_R15
, FR30_OPERAND_PS, FR30_OPERAND_U4, FR30_OPERAND_U4C, FR30_OPERAND_U8
, FR30_OPERAND_I8, FR30_OPERAND_UDISP6, FR30_OPERAND_DISP8, FR30_OPERAND_DISP9
, FR30_OPERAND_DISP10, FR30_OPERAND_S10, FR30_OPERAND_U10, FR30_OPERAND_I32
, FR30_OPERAND_M4, FR30_OPERAND_I20, FR30_OPERAND_DIR8, FR30_OPERAND_DIR9
, FR30_OPERAND_DIR10, FR30_OPERAND_LABEL9, FR30_OPERAND_LABEL12, FR30_OPERAND_REGLIST_LOW_LD
, FR30_OPERAND_REGLIST_HI_LD, FR30_OPERAND_REGLIST_LOW_ST, FR30_OPERAND_REGLIST_HI_ST, FR30_OPERAND_CC
, FR30_OPERAND_CCC, FR30_OPERAND_NBIT, FR30_OPERAND_VBIT, FR30_OPERAND_ZBIT
, FR30_OPERAND_CBIT, FR30_OPERAND_IBIT, FR30_OPERAND_SBIT, FR30_OPERAND_TBIT
, FR30_OPERAND_D0BIT, FR30_OPERAND_D1BIT, FR30_OPERAND_CCR, FR30_OPERAND_SCR
, FR30_OPERAND_ILM, FR30_OPERAND_MAX
} CGEN_OPERAND_TYPE;
/* Number of operands types. */
#define MAX_OPERANDS ((int) FR30_OPERAND_MAX)
/* Maximum number of operands referenced by any insn. */
#define MAX_OPERAND_INSTANCES 12
/* Insn attribute indices. */
/* Enum declaration for cgen_insn attrs. */
typedef enum cgen_insn_attr {
CGEN_INSN_ALIAS, CGEN_INSN_COND_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_NO_DIS
, CGEN_INSN_NOT_IN_DELAY_SLOT, CGEN_INSN_RELAX, CGEN_INSN_RELAXABLE, CGEN_INSN_SKIP_CTI
, CGEN_INSN_UNCOND_CTI, CGEN_INSN_VIRTUAL
CGEN_INSN_MACH, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI
, CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAX
, CGEN_INSN_ALIAS, CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_NOT_IN_DELAY_SLOT
} CGEN_INSN_ATTR;
/* Number of non-boolean elements in cgen_insn. */
#define CGEN_INSN_NBOOL_ATTRS ((int) CGEN_INSN_ALIAS)
#define CGEN_INSN_NBOOL_ATTRS ((int) CGEN_INSN_VIRTUAL)
/* Enum declaration for fr30 instruction types. */
typedef enum cgen_insn_type {
@ -341,19 +359,6 @@ extern const CGEN_ATTR_TABLE fr30_cgen_hw_attr_table[];
extern const CGEN_ATTR_TABLE fr30_cgen_operand_attr_table[];
extern const CGEN_ATTR_TABLE fr30_cgen_insn_attr_table[];
/* Enum declaration for fr30 hardware types. */
typedef enum hw_type {
HW_H_PC, HW_H_MEMORY, HW_H_SINT, HW_H_UINT
, HW_H_ADDR, HW_H_IADDR, HW_H_GR, HW_H_CR
, HW_H_DR, HW_H_PS, HW_H_R13, HW_H_R14
, HW_H_R15, HW_H_NBIT, HW_H_ZBIT, HW_H_VBIT
, HW_H_CBIT, HW_H_IBIT, HW_H_SBIT, HW_H_TBIT
, HW_H_D0BIT, HW_H_D1BIT, HW_H_CCR, HW_H_SCR
, HW_H_ILM, HW_MAX
} HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Hardware decls. */
extern CGEN_KEYWORD fr30_cgen_opval_h_gr;

View File

@ -219,7 +219,7 @@ i960_cgen_insert_operand (od, opindex, fields, buffer, pc)
{
long value = fields->f_br_disp;
value = ((int) (((value) - (pc))) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 19, 11, 32, total_length, buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 19, 11, 32, total_length, buffer);
}
break;
case I960_OPERAND_BR_LIT1 :
@ -229,7 +229,7 @@ i960_cgen_insert_operand (od, opindex, fields, buffer, pc)
{
long value = fields->f_ctrl_disp;
value = ((int) (((value) - (pc))) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 22, 32, total_length, buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 22, 32, total_length, buffer);
}
break;
@ -401,7 +401,7 @@ insert_normal (od, value, attrs, word_offset, start, length, word_length,
#endif
/* Ensure VALUE will fit. */
if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0)
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
{
unsigned long maxval = mask;
if ((unsigned long) value > maxval)

View File

@ -136,7 +136,7 @@ i960_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
case I960_OPERAND_BR_DISP :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 19, 11, 32, total_length, pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 19, 11, 32, total_length, pc, & value);
value = ((((value) << (2))) + (pc));
fields->f_br_disp = value;
}
@ -147,7 +147,7 @@ i960_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
case I960_OPERAND_CTRL_DISP :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 22, 32, total_length, pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 22, 32, total_length, pc, & value);
value = ((((value) << (2))) + (pc));
fields->f_ctrl_disp = value;
}
@ -229,13 +229,13 @@ i960_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
print_keyword (od, info, & i960_cgen_opval_h_gr, fields->f_br_src2, 0|(1<<CGEN_OPERAND_UNSIGNED));
break;
case I960_OPERAND_BR_DISP :
print_address (od, info, fields->f_br_disp, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
print_address (od, info, fields->f_br_disp, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
case I960_OPERAND_BR_LIT1 :
print_normal (od, info, fields->f_br_src1, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case I960_OPERAND_CTRL_DISP :
print_address (od, info, fields->f_ctrl_disp, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
print_address (od, info, fields->f_ctrl_disp, 0|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
break;
default :
@ -439,7 +439,7 @@ extract_normal (od, ex_info, insn_value, attrs, word_offset, start, length,
value = insn_value >> (word_length - (start + length));
value &= mask;
/* sign extend? */
if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
if (! CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED)
&& (value & (1L << (length - 1))))
value |= ~mask;
}

File diff suppressed because it is too large Load Diff

View File

@ -211,16 +211,7 @@ typedef enum h_cc {
H_CC_CC
} H_CC;
/* Enum declaration for i960 operand types. */
typedef enum cgen_operand_type {
I960_OPERAND_PC, I960_OPERAND_SRC1, I960_OPERAND_SRC2, I960_OPERAND_DST
, I960_OPERAND_LIT1, I960_OPERAND_LIT2, I960_OPERAND_ST_SRC, I960_OPERAND_ABASE
, I960_OPERAND_OFFSET, I960_OPERAND_SCALE, I960_OPERAND_INDEX, I960_OPERAND_OPTDISP
, I960_OPERAND_BR_SRC1, I960_OPERAND_BR_SRC2, I960_OPERAND_BR_DISP, I960_OPERAND_BR_LIT1
, I960_OPERAND_CTRL_DISP, I960_OPERAND_MAX
} CGEN_OPERAND_TYPE;
/* Non-boolean attributes. */
/* Attributes. */
/* Enum declaration for machine type selection. */
typedef enum mach_attr {
@ -230,32 +221,16 @@ typedef enum mach_attr {
/* Number of architecture variants. */
#define MAX_MACHS ((int) MACH_MAX)
/* Number of operands types. */
#define MAX_OPERANDS ((int) I960_OPERAND_MAX)
/* Maximum number of operands referenced by any insn. */
#define MAX_OPERAND_INSTANCES 54
/* Hardware, operand and instruction attribute indices. */
/* Enum declaration for cgen_hw attrs. */
typedef enum cgen_hw_attr {
CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE
} CGEN_HW_ATTR;
/* Number of non-boolean elements in cgen_hw. */
#define CGEN_HW_NBOOL_ATTRS ((int) CGEN_HW_CACHE_ADDR)
/* Hardware, operand and instruction attribute indices. */
/* Ifield attribute indices. */
/* Enum declaration for cgen_ifld attrs. */
typedef enum cgen_ifld_attr {
CGEN_IFLD_ABS_ADDR, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_RELOC, CGEN_IFLD_RESERVED
, CGEN_IFLD_UNSIGNED, CGEN_IFLD_VIRTUAL
CGEN_IFLD_MACH, CGEN_IFLD_VIRTUAL, CGEN_IFLD_UNSIGNED, CGEN_IFLD_PCREL_ADDR
, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED, CGEN_IFLD_SIGN_OPT
} CGEN_IFLD_ATTR;
/* Number of non-boolean elements in cgen_ifld. */
#define CGEN_IFLD_NBOOL_ATTRS ((int) CGEN_IFLD_ABS_ADDR)
#define CGEN_IFLD_NBOOL_ATTRS ((int) CGEN_IFLD_VIRTUAL)
/* Enum declaration for i960 ifield types. */
typedef enum ifield_type {
@ -270,24 +245,64 @@ typedef enum ifield_type {
#define MAX_IFLD ((int) I960_F_MAX)
/* Hardware attribute indices. */
/* Enum declaration for cgen_hw attrs. */
typedef enum cgen_hw_attr {
CGEN_HW_MACH, CGEN_HW_VIRTUAL, CGEN_HW_UNSIGNED, CGEN_HW_SIGNED
, CGEN_HW_CACHE_ADDR, CGEN_HW_FUN_ACCESS, CGEN_HW_PC, CGEN_HW_PROFILE
} CGEN_HW_ATTR;
/* Number of non-boolean elements in cgen_hw. */
#define CGEN_HW_NBOOL_ATTRS ((int) CGEN_HW_VIRTUAL)
/* Enum declaration for i960 hardware types. */
typedef enum hw_type {
HW_H_PC, HW_H_MEMORY, HW_H_SINT, HW_H_UINT
, HW_H_ADDR, HW_H_IADDR, HW_H_GR, HW_H_CC
, HW_MAX
} HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Operand attribute indices. */
/* Enum declaration for cgen_operand attrs. */
typedef enum cgen_operand_attr {
CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_RELAX
, CGEN_OPERAND_RELOC, CGEN_OPERAND_SEM_ONLY, CGEN_OPERAND_SIGN_OPT, CGEN_OPERAND_UNSIGNED
CGEN_OPERAND_MACH, CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_UNSIGNED, CGEN_OPERAND_PCREL_ADDR
, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX
, CGEN_OPERAND_SEM_ONLY
} CGEN_OPERAND_ATTR;
/* Number of non-boolean elements in cgen_operand. */
#define CGEN_OPERAND_NBOOL_ATTRS ((int) CGEN_OPERAND_ABS_ADDR)
#define CGEN_OPERAND_NBOOL_ATTRS ((int) CGEN_OPERAND_VIRTUAL)
/* Enum declaration for i960 operand types. */
typedef enum cgen_operand_type {
I960_OPERAND_PC, I960_OPERAND_SRC1, I960_OPERAND_SRC2, I960_OPERAND_DST
, I960_OPERAND_LIT1, I960_OPERAND_LIT2, I960_OPERAND_ST_SRC, I960_OPERAND_ABASE
, I960_OPERAND_OFFSET, I960_OPERAND_SCALE, I960_OPERAND_INDEX, I960_OPERAND_OPTDISP
, I960_OPERAND_BR_SRC1, I960_OPERAND_BR_SRC2, I960_OPERAND_BR_DISP, I960_OPERAND_BR_LIT1
, I960_OPERAND_CTRL_DISP, I960_OPERAND_MAX
} CGEN_OPERAND_TYPE;
/* Number of operands types. */
#define MAX_OPERANDS ((int) I960_OPERAND_MAX)
/* Maximum number of operands referenced by any insn. */
#define MAX_OPERAND_INSTANCES 54
/* Insn attribute indices. */
/* Enum declaration for cgen_insn attrs. */
typedef enum cgen_insn_attr {
CGEN_INSN_ALIAS, CGEN_INSN_COND_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_NO_DIS
, CGEN_INSN_RELAX, CGEN_INSN_RELAXABLE, CGEN_INSN_SKIP_CTI, CGEN_INSN_UNCOND_CTI
, CGEN_INSN_VIRTUAL
CGEN_INSN_MACH, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI
, CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAX
, CGEN_INSN_ALIAS, CGEN_INSN_NO_DIS, CGEN_INSN_PBB
} CGEN_INSN_ATTR;
/* Number of non-boolean elements in cgen_insn. */
#define CGEN_INSN_NBOOL_ATTRS ((int) CGEN_INSN_ALIAS)
#define CGEN_INSN_NBOOL_ATTRS ((int) CGEN_INSN_VIRTUAL)
/* Enum declaration for i960 instruction types. */
typedef enum cgen_insn_type {
@ -410,15 +425,6 @@ extern const CGEN_ATTR_TABLE i960_cgen_hw_attr_table[];
extern const CGEN_ATTR_TABLE i960_cgen_operand_attr_table[];
extern const CGEN_ATTR_TABLE i960_cgen_insn_attr_table[];
/* Enum declaration for i960 hardware types. */
typedef enum hw_type {
HW_H_PC, HW_H_MEMORY, HW_H_SINT, HW_H_UINT
, HW_H_ADDR, HW_H_IADDR, HW_H_GR, HW_H_CC
, HW_MAX
} HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Hardware decls. */
extern CGEN_KEYWORD i960_cgen_opval_h_gr;

View File

@ -42,9 +42,12 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
#define INLINE
#endif
/* Used by the ifield rtx function. */
#define FLD(f) (fields->f)
static const char * insert_normal
PARAMS ((CGEN_OPCODE_DESC, long, unsigned int, int, int, int,
CGEN_INSN_BYTES_PTR));
PARAMS ((CGEN_OPCODE_DESC, long, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
static const char * parse_insn_normal
PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
const char **, CGEN_FIELDS *));
@ -355,100 +358,101 @@ m32r_cgen_insert_operand (od, opindex, fields, buffer, pc)
bfd_vma pc;
{
const char * errmsg;
unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
switch (opindex)
{
case M32R_OPERAND_SR :
errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, buffer);
break;
case M32R_OPERAND_DR :
errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, buffer);
break;
case M32R_OPERAND_SRC1 :
errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, buffer);
break;
case M32R_OPERAND_SRC2 :
errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, buffer);
break;
case M32R_OPERAND_SCR :
errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, buffer);
break;
case M32R_OPERAND_DCR :
errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, buffer);
break;
case M32R_OPERAND_SIMM8 :
errmsg = insert_normal (od, fields->f_simm8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_simm8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 8, 8, 32, total_length, buffer);
break;
case M32R_OPERAND_SIMM16 :
errmsg = insert_normal (od, fields->f_simm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_simm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 16, 16, 32, total_length, buffer);
break;
case M32R_OPERAND_UIMM4 :
errmsg = insert_normal (od, fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, buffer);
break;
case M32R_OPERAND_UIMM5 :
errmsg = insert_normal (od, fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 11, 5, 32, total_length, buffer);
break;
case M32R_OPERAND_UIMM16 :
errmsg = insert_normal (od, fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, buffer);
break;
/* start-sanitize-m32rx */
case M32R_OPERAND_IMM1 :
{
long value = fields->f_imm1;
value = ((value) - (1));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 15, 1, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 15, 1, 32, total_length, buffer);
}
break;
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
case M32R_OPERAND_ACCD :
errmsg = insert_normal (od, fields->f_accd, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_accd, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 2, 32, total_length, buffer);
break;
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
case M32R_OPERAND_ACCS :
errmsg = insert_normal (od, fields->f_accs, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_accs, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 2, 32, total_length, buffer);
break;
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
case M32R_OPERAND_ACC :
errmsg = insert_normal (od, fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 1, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 1, 32, total_length, buffer);
break;
/* end-sanitize-m32rx */
case M32R_OPERAND_HASH :
errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
break;
case M32R_OPERAND_HI16 :
errmsg = insert_normal (od, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, buffer);
break;
case M32R_OPERAND_SLO16 :
errmsg = insert_normal (od, fields->f_simm16, 0, 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_simm16, 0, 0, 16, 16, 32, total_length, buffer);
break;
case M32R_OPERAND_ULO16 :
errmsg = insert_normal (od, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, buffer);
break;
case M32R_OPERAND_UIMM24 :
errmsg = insert_normal (od, fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 24, 32, total_length, buffer);
break;
case M32R_OPERAND_DISP8 :
{
long value = fields->f_disp8;
value = ((int) (((value) - (((pc) & (-4))))) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
}
break;
case M32R_OPERAND_DISP16 :
{
long value = fields->f_disp16;
value = ((int) (((value) - (pc))) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 16, 16, 32, total_length, buffer);
}
break;
case M32R_OPERAND_DISP24 :
{
long value = fields->f_disp24;
value = ((int) (((value) - (pc))) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 24, 32, total_length, buffer);
}
break;
@ -511,9 +515,9 @@ insert_1 (od, value, start, length, word_length, bufp)
/* ??? This may need reworking as these cases don't necessarily
want the first byte and the last two bytes handled like this. */
if (big_p)
x = (bfd_getb8 (bufp) << 16) | bfd_getb16 (bufp + 1);
x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
else
x = bfd_getl16 (bufp) | (bfd_getb8 (bufp + 2) << 16);
x = bfd_getl16 (bufp) | (bufp[2] << 16);
break;
case 32:
if (big_p)
@ -528,7 +532,7 @@ insert_1 (od, value, start, length, word_length, bufp)
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
shift = start;
shift = (start + 1) - length;
else
shift = (word_length - (start + length));
x = (x & ~(mask << shift)) | ((value & mask) << shift);
@ -549,13 +553,13 @@ insert_1 (od, value, start, length, word_length, bufp)
want the first byte and the last two bytes handled like this. */
if (big_p)
{
bfd_putb8 (x >> 16, bufp);
bufp[0] = x >> 16;
bfd_putb16 (x, bufp + 1);
}
else
{
bfd_putl16 (x, bufp);
bfd_putb8 (x >> 16, bufp + 2);
bufp[2] = x >> 16;
}
break;
case 32:
@ -574,33 +578,26 @@ insert_1 (od, value, start, length, word_length, bufp)
/* Default insertion routine.
ATTRS is a mask of the boolean attributes.
START is the starting bit number, architecture origin.
WORD_OFFSET is the offset in bits from the start of the insn of the value.
WORD_LENGTH is the length of the word in bits in which the value resides.
START is the starting bit number in the word, architecture origin.
LENGTH is the length of VALUE in bits.
TOTAL_LENGTH is the total length of the insn.
TOTAL_LENGTH is the total length of the insn in bits.
The result is an error message or NULL if success. */
/* ??? May need to know word length in order to properly place values as
an insn may be made of multiple words and the current bit number handling
may be insufficient. Word length is an architectural attribute and thus
methinks the way to go [if needed] is to fetch this value from OD or
define a macro in <arch>-opc.h rather than adding an extra argument -
after all that's how endianness is handled. */
/* ??? This duplicates functionality with bfd's howto table and
bfd_install_relocation. */
/* ??? For architectures where insns can be representable as ints,
store insn in `field' struct and add registers, etc. while parsing? */
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static const char *
insert_normal (od, value, attrs, start, length, total_length, buffer)
insert_normal (od, value, attrs, word_offset, start, length, word_length,
total_length, buffer)
CGEN_OPCODE_DESC od;
long value;
unsigned int attrs;
int start;
int length;
int total_length;
unsigned int word_offset, start, length, word_length, total_length;
CGEN_INSN_BYTES_PTR buffer;
{
static char errbuf[100];
@ -611,8 +608,23 @@ insert_normal (od, value, attrs, start, length, total_length, buffer)
if (length == 0)
return NULL;
if (CGEN_INT_INSN_P
&& word_offset != 0)
abort ();
if (word_length > 32)
abort ();
/* For architectures with insns smaller than the insn-base-bitsize,
word_length may be too big. */
#if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
if (word_offset == 0
&& word_length > total_length)
word_length = total_length;
#endif
/* Ensure VALUE will fit. */
if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0)
if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
{
unsigned long maxval = mask;
if ((unsigned long) value > maxval)
@ -640,152 +652,23 @@ insert_normal (od, value, attrs, start, length, total_length, buffer)
#if CGEN_INT_INSN_P
if (total_length > 32)
abort ();
{
int shift;
if (CGEN_INSN_LSB0_P)
shift = start;
shift = (start + 1) - length;
else
shift = total_length - (start + length);
shift = word_length - (start + length);
*buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
}
#else
#else /* ! CGEN_INT_INSN_P */
/* FIXME: unfinished and untested */
{
unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
/* ??? To be defined in <arch>-opc.h as necessary. */
#ifndef CGEN_WORD_ENDIAN
#define CGEN_WORD_ENDIAN(od) CGEN_OPCODE_ENDIAN (od)
#endif
#ifndef CGEN_INSN_WORD_ENDIAN
#define CGEN_INSN_WORD_ENDIAN(od) CGEN_WORD_ENDIAN (od)
#endif
/* The hard case is probably too slow for the normal cases.
It's certainly more difficult to understand than the normal case.
Thus this is split into two. Keep it that way. The hard case is defined
to be when a field straddles a (loosely defined) word boundary
(??? which may require target specific help to determine). */
#if 0 /*wip*/
#define HARD_CASE_P 0 /* FIXME:wip */
if (HARD_CASE_P)
{
unsigned char *bufp = (unsigned char *) buffer;
int insn_length_left = total_length;
if (CGEN_INSN_LSB0_P)
{
int word_offset = (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG
? ...
: start / CGEN_BASE_INSN_BITSIZE);
bufp += word_offset * (CGEN_BASE_INSN_BITSIZE / 8);
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
else
start -= word_offset * CGEN_BASE_INSN_BITSIZE;
}
else
{
int word_offset = (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG
? start / CGEN_BASE_INSN_BITSIZE
: ...);
bufp += word_offset * (CGEN_BASE_INSN_BITSIZE / 8);
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
start -= word_offset * CGEN_BASE_INSN_BITSIZE;
else
}
/* Loop so we handle a field straddling an insn word boundary
(remember, "insn word boundary" is loosely defined here). */
while (length > 0)
{
int this_pass_length = length;
int this_pass_start = start;
int this_pass_word_length = min (insn_length_left,
(CGEN_BASE_INSN_BITSIZE == 8
? 32
: CGEN_BASE_INSN_BITSIZE));
insert_1 (od, value, attrs,
this_pass_start, this_pass_length, this_pass_word_length,
bufp);
length -= this_pass_length;
insn_length_left -= this_pass_word_length;
if (???)
{
value >>= ???;
start += ???;
}
else
{
value >>= ???;
start += ???;
}
bufp += this_pass_word_length / 8;
}
}
else
#endif /* 0 */
{
unsigned char *bufp = (unsigned char *) buffer;
if (length > 32)
abort ();
/* Adjust start,total_length,bufp to point to the pseudo-word that holds
the value. For example in a 48 bit insn where the value to insert
(say an immediate value) is the last 16 bits then word_length here
would be 16. To handle a 24 bit insn with an 18 bit immediate,
insert_1 handles 24 bits (using a combination of bfd_get8,16). */
if (total_length > 32)
{
int needed_width = start % 8 + length;
int fetch_length = (needed_width <= 8 ? 8
: needed_width <= 16 ? 16
: 32);
if (CGEN_INSN_LSB0_P)
{
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
{
abort (); /* wip */
}
else
{
int offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length -= offset;
}
}
else
{
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
{
int offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length -= offset;
}
else
{
abort (); /* wip */
}
}
}
insert_1 (od, value, start, length, total_length, bufp);
}
insert_1 (od, value, start, length, word_length, bufp);
}
#endif /* ! CGEN_INT_INSN_P */
@ -924,7 +807,7 @@ insert_insn_normal (od, insn, fields, buffer, pc)
const unsigned char * syn;
CGEN_INIT_INSERT (od);
value = CGEN_INSN_VALUE (insn);
value = CGEN_INSN_BASE_VALUE (insn);
/* If we're recording insns as numbers (rather than a string of bytes),
target byte order handling is deferred until later. */
@ -935,14 +818,16 @@ insert_insn_normal (od, insn, fields, buffer, pc)
#else
cgen_insn_put_value (od, buffer, min (CGEN_BASE_INSN_BITSIZE,
cgen_put_insn_value (od, buffer, min (CGEN_BASE_INSN_BITSIZE,
CGEN_FIELDS_BITSIZE (fields)),
value);
#endif /* ! CGEN_INT_INSN_P */
/* ??? Rather than scanning the syntax string again, we could store
in `fields' a null terminated list of the fields that are present. */
/* ??? It would be better to scan the format's fields.
Still need to be able to insert a value based on the operand though;
e.g. storing a branch displacement that got resolved later.
Needs more thought first. */
for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
{
@ -1015,9 +900,7 @@ m32r_cgen_assemble_insn (od, str, fields, buf, errmsg)
str = start;
/* Record a default length for the insn. This will get set to the
correct value while parsing. */
/* FIXME: wip */
/* Allow parse/insert handlers to obtain length of insn. */
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
if (! CGEN_PARSE_FN (insn) (od, insn, & str, fields))

View File

@ -40,9 +40,13 @@ along with this program; if not, write to the Free Software Foundation, Inc.,
/* Default text to print if an instruction isn't recognized. */
#define UNKNOWN_INSN_MSG _("*unknown*")
/* Used by the ifield rtx function. */
#define FLD(f) (fields->f)
static int extract_normal
PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_BYTES,
unsigned int, int, int, int, long *));
PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, bfd_vma, long *));
static void print_normal
PARAMS ((CGEN_OPCODE_DESC, PTR, long, unsigned int, bfd_vma, int));
static void print_address
@ -51,7 +55,7 @@ static void print_keyword
PARAMS ((CGEN_OPCODE_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
static int extract_insn_normal
PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
unsigned long, CGEN_FIELDS *, bfd_vma));
CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
static void print_insn_normal
PARAMS ((CGEN_OPCODE_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
bfd_vma, int));
@ -160,52 +164,53 @@ m32r_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
CGEN_OPCODE_DESC od;
int opindex;
CGEN_EXTRACT_INFO *ex_info;
CGEN_INSN_BYTES insn_value;
CGEN_INSN_INT insn_value;
CGEN_FIELDS * fields;
bfd_vma pc;
{
int length;
unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
switch (opindex)
{
case M32R_OPERAND_SR :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_r2);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, pc, & fields->f_r2);
break;
case M32R_OPERAND_DR :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_r1);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, pc, & fields->f_r1);
break;
case M32R_OPERAND_SRC1 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_r1);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, pc, & fields->f_r1);
break;
case M32R_OPERAND_SRC2 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_r2);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, pc, & fields->f_r2);
break;
case M32R_OPERAND_SCR :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_r2);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, pc, & fields->f_r2);
break;
case M32R_OPERAND_DCR :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_r1);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, pc, & fields->f_r1);
break;
case M32R_OPERAND_SIMM8 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 8, 8, CGEN_FIELDS_BITSIZE (fields), & fields->f_simm8);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
break;
case M32R_OPERAND_SIMM16 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 16, 16, CGEN_FIELDS_BITSIZE (fields), & fields->f_simm16);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
break;
case M32R_OPERAND_UIMM4 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm4);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
break;
case M32R_OPERAND_UIMM5 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm5);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
break;
case M32R_OPERAND_UIMM16 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm16);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
break;
/* start-sanitize-m32rx */
case M32R_OPERAND_IMM1 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 15, 1, CGEN_FIELDS_BITSIZE (fields), & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 15, 1, 32, total_length, pc, & value);
value = ((value) + (1));
fields->f_imm1 = value;
}
@ -213,38 +218,38 @@ m32r_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
case M32R_OPERAND_ACCD :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 2, CGEN_FIELDS_BITSIZE (fields), & fields->f_accd);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 2, 32, total_length, pc, & fields->f_accd);
break;
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
case M32R_OPERAND_ACCS :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 2, CGEN_FIELDS_BITSIZE (fields), & fields->f_accs);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 2, 32, total_length, pc, & fields->f_accs);
break;
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
case M32R_OPERAND_ACC :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 1, CGEN_FIELDS_BITSIZE (fields), & fields->f_acc);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 1, 32, total_length, pc, & fields->f_acc);
break;
/* end-sanitize-m32rx */
case M32R_OPERAND_HASH :
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), & fields->f_nil);
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case M32R_OPERAND_HI16 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), & fields->f_hi16);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
break;
case M32R_OPERAND_SLO16 :
length = extract_normal (od, ex_info, insn_value, 0, 16, 16, CGEN_FIELDS_BITSIZE (fields), & fields->f_simm16);
length = extract_normal (od, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
break;
case M32R_OPERAND_ULO16 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm16);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
break;
case M32R_OPERAND_UIMM24 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, CGEN_FIELDS_BITSIZE (fields), & fields->f_uimm24);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 24, 32, total_length, pc, & fields->f_uimm24);
break;
case M32R_OPERAND_DISP8 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, CGEN_FIELDS_BITSIZE (fields), & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
value = ((((value) << (2))) + (((pc) & (-4))));
fields->f_disp8 = value;
}
@ -252,7 +257,7 @@ m32r_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
case M32R_OPERAND_DISP16 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, CGEN_FIELDS_BITSIZE (fields), & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 16, 16, 32, total_length, pc, & value);
value = ((((value) << (2))) + (pc));
fields->f_disp16 = value;
}
@ -260,7 +265,7 @@ m32r_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
case M32R_OPERAND_DISP24 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, CGEN_FIELDS_BITSIZE (fields), & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 24, 32, total_length, pc, & value);
value = ((((value) << (2))) + (pc));
fields->f_disp24 = value;
}
@ -410,21 +415,68 @@ m32r_cgen_init_dis (od)
#if ! CGEN_INT_INSN_P
/* Subroutine of extract_normal.
Ensure sufficient bytes are cached in EX_INFO.
OFFSET is the offset in bytes from the start of the insn of the value.
BYTES is the length of the needed value.
Returns 1 for success, 0 for failure. */
static INLINE int
fill_cache (od, ex_info, offset, bytes, pc)
CGEN_OPCODE_DESC od;
CGEN_EXTRACT_INFO *ex_info;
int offset, bytes;
bfd_vma pc;
{
/* It's doubtful that the middle part has already been fetched so
we don't optimize that case. kiss. */
int mask;
disassemble_info *info = (disassemble_info *) ex_info->dis_info;
/* First do a quick check. */
mask = (1 << bytes) - 1;
if (((ex_info->valid >> offset) & mask) == mask)
return 1;
/* Search for the first byte we need to read. */
for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
if (! (mask & ex_info->valid))
break;
if (bytes)
{
int status;
pc += offset;
status = (*info->read_memory_func)
(pc, ex_info->insn_bytes + offset, bytes, info);
if (status != 0)
{
(*info->memory_error_func) (status, pc, info);
return 0;
}
ex_info->valid |= ((1 << bytes) - 1) << offset;
}
return 1;
}
/* Subroutine of extract_normal. */
static INLINE long
extract_1 (od, ex_info, start, length, word_length, bufp)
extract_1 (od, ex_info, start, length, word_length, bufp, pc)
CGEN_OPCODE_DESC od;
CGEN_EXTRACT_INFO *info;
CGEN_EXTRACT_INFO *ex_info;
int start,length,word_length;
unsigned char *bufp;
bfd_vma pc;
{
unsigned long x,mask;
int shift;
int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
/* FIXME: Need to use ex_info to ensure bytes have been fetched. */
switch (word_length)
{
case 8:
@ -440,9 +492,9 @@ extract_1 (od, ex_info, start, length, word_length, bufp)
/* ??? This may need reworking as these cases don't necessarily
want the first byte and the last two bytes handled like this. */
if (big_p)
x = (bfd_getb8 (bufp) << 16) | bfd_getb16 (bufp + 1);
x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
else
x = bfd_getl16 (bufp) | (bfd_getb8 (bufp + 2) << 16);
x = bfd_getl16 (bufp) | (bufp[2] << 16);
break;
case 32:
if (big_p)
@ -457,7 +509,7 @@ extract_1 (od, ex_info, start, length, word_length, bufp)
/* Written this way to avoid undefined behaviour. */
mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
shift = start;
shift = (start + 1) - length;
else
shift = (word_length - (start + length));
return (x >> shift) & mask;
@ -467,22 +519,36 @@ extract_1 (od, ex_info, start, length, word_length, bufp)
/* Default extraction routine.
ATTRS is a mask of the boolean attributes. We only need `unsigned',
but for generality we take a bitmask of all of them. */
INSN_VALUE is the first CGEN_BASE_INSN_SIZE bits of the insn in host order,
or sometimes less for cases like the m32r where the base insn size is 32
but some insns are 16 bits.
ATTRS is a mask of the boolean attributes. We only need `UNSIGNED',
but for generality we take a bitmask of all of them.
WORD_OFFSET is the offset in bits from the start of the insn of the value.
WORD_LENGTH is the length of the word in bits in which the value resides.
START is the starting bit number in the word, architecture origin.
LENGTH is the length of VALUE in bits.
TOTAL_LENGTH is the total length of the insn in bits.
Returns 1 for success, 0 for failure. */
/* ??? The return code isn't properly used. wip. */
/* ??? This doesn't handle bfd_vma's. Create another function when
necessary. */
static int
extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, valuep)
extract_normal (od, ex_info, insn_value, attrs, word_offset, start, length,
word_length, total_length, pc, valuep)
CGEN_OPCODE_DESC od;
CGEN_EXTRACT_INFO *ex_info;
CGEN_INSN_BYTES insn_value;
CGEN_INSN_INT insn_value;
unsigned int attrs;
int start, length, total_length;
unsigned int word_offset, start, length, word_length, total_length;
bfd_vma pc;
long *valuep;
{
unsigned long value;
CGEN_INSN_INT value;
/* If LENGTH is zero, this operand doesn't contribute to the value
so give it a standard value of zero. */
@ -492,100 +558,58 @@ extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, val
return 1;
}
#if CGEN_INT_INSN_P
if (CGEN_INT_INSN_P
&& word_offset != 0)
abort ();
{
/* Written this way to avoid undefined behaviour. */
unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (word_length > 32)
abort ();
if (CGEN_INSN_LSB0_P)
value = insn_value >> start;
else
value = insn_value >> (total_length - (start + length));
value &= mask;
/* sign extend? */
if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
&& (value & (1L << (length - 1))))
value |= ~mask;
}
#else
/* The hard case is probably too slow for the normal cases.
It's certainly more difficult to understand than the normal case.
Thus this is split into two. Keep it that way. The hard case is defined
to be when a field straddles a (loosely defined) word boundary
(??? which may require target specific help to determine). */
#if 0 /*wip*/
#define HARD_CASE_P 0 /* FIXME:wip */
if (HARD_CASE_P)
{
}
/* For architectures with insns smaller than the insn-base-bitsize,
word_length may be too big. */
#if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
if (word_offset == 0
&& word_length > total_length)
word_length = total_length;
#endif
/* Does the value reside in INSN_VALUE? */
if (word_offset == 0)
{
/* Written this way to avoid undefined behaviour. */
CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
value = insn_value >> ((start + 1) - length);
else
value = insn_value >> (word_length - (start + length));
value &= mask;
/* sign extend? */
if (! CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED)
&& (value & (1L << (length - 1))))
value |= ~mask;
}
#if ! CGEN_INT_INSN_P
else
{
unsigned char *bufp = (unsigned char *) insn_value;
unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
if (length > 32)
if (word_length > 32)
abort ();
/* Adjust start,total_length,bufp to point to the pseudo-word that holds
the value. For example in a 48 bit insn where the value to insert
(say an immediate value) is the last 16 bits then word_length here
would be 16. To handle a 24 bit insn with an 18 bit immediate,
extract_1 handles 24 bits (using a combination of bfd_get8,16). */
if (fill_cache (od, ex_info, word_offset / 8, word_length / 8, pc) == 0)
return 0;
if (total_length > 32)
{
int needed_width = start % 8 + length;
int fetch_length = (needed_width <= 8 ? 8
: needed_width <= 16 ? 16
: 32);
if (CGEN_INSN_LSB0_P)
{
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
{
abort (); /* wip */
}
else
{
int offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length -= offset;
}
}
else
{
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
{
int offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length -= offset;
}
else
{
abort (); /* wip */
}
}
}
/* FIXME: which bytes are being extracted have been lost. */
value = extract_1 (od, ex_info, start, length, total_length, bufp);
value = extract_1 (od, ex_info, start, length, word_length, bufp, pc);
}
#endif /* ! CGEN_INT_INSN_P */
*valuep = value;
/* FIXME: for now */
return 1;
}
@ -679,7 +703,7 @@ extract_insn_normal (od, insn, ex_info, insn_value, fields, pc)
CGEN_OPCODE_DESC od;
const CGEN_INSN *insn;
CGEN_EXTRACT_INFO *ex_info;
unsigned long insn_value;
CGEN_INSN_INT insn_value;
CGEN_FIELDS *fields;
bfd_vma pc;
{
@ -766,7 +790,7 @@ print_insn (od, pc, info, buf, buflen)
ex_info.dis_info = info;
ex_info.valid = (1 << CGEN_BASE_INSN_SIZE) - 1;
ex_info.bytes = buf;
ex_info.insn_bytes = buf;
switch (buflen)
{
@ -802,7 +826,8 @@ print_insn (od, pc, info, buf, buflen)
/* Basic bit mask must be correct. */
/* ??? May wish to allow target to defer this check until the extract
handler. */
if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
if ((insn_value & CGEN_INSN_BASE_MASK (insn))
== CGEN_INSN_BASE_VALUE (insn))
{
/* Printing is handled in two passes. The first pass parses the
machine insn and extracts the fields. The second pass prints

File diff suppressed because it is too large Load Diff

View File

@ -27,15 +27,16 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define CGEN_ARCH m32r
/* Given symbol S, return m32r_cgen_<s>. */
/* Given symbol S, return m32r_cgen_<S>. */
#define CGEN_SYM(s) CONCAT3 (m32r,_cgen_,s)
/* Selected cpu families. */
#define HAVE_CPU_M32R
#define HAVE_CPU_M32RBF
/* start-sanitize-m32rx */
#define HAVE_CPU_M32RX
#define HAVE_CPU_M32RXF
/* end-sanitize-m32rx */
#define CGEN_INSN_LSB0_P 0
#define CGEN_WORD_BITSIZE 32
#define CGEN_DEFAULT_INSN_BITSIZE 32
#define CGEN_BASE_INSN_BITSIZE 32
@ -45,7 +46,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define CGEN_BASE_INSN_SIZE (CGEN_BASE_INSN_BITSIZE / 8)
#define CGEN_MIN_INSN_SIZE (CGEN_MIN_INSN_BITSIZE / 8)
#define CGEN_MAX_INSN_SIZE (CGEN_MAX_INSN_BITSIZE / 8)
#define CGEN_INT_INSN
#define CGEN_INT_INSN_P 1
/* FIXME: Need to compute CGEN_MAX_SYNTAX_BYTES. */
@ -56,6 +57,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
/* Maximum number of operands any insn or macro-insn has. */
#define CGEN_MAX_INSN_OPERANDS 16
/* Maximum number of fields in an instruction. */
#define CGEN_MAX_IFMT_OPERANDS 7
/* Enums. */
/* Enum declaration for insn format enums. */
@ -86,11 +90,11 @@ typedef enum h_gr {
/* Enum declaration for control registers. */
typedef enum h_cr {
H_CR_PSW = 0, H_CR_CBR = 1, H_CR_SPI = 2, H_CR_SPU = 3
, H_CR_BPC = 6, H_CR_CR0 = 0, H_CR_CR1 = 1, H_CR_CR2 = 2
, H_CR_CR3 = 3, H_CR_CR4 = 4, H_CR_CR5 = 5, H_CR_CR6 = 6
, H_CR_CR7 = 7, H_CR_CR8 = 8, H_CR_CR9 = 9, H_CR_CR10 = 10
, H_CR_CR11 = 11, H_CR_CR12 = 12, H_CR_CR13 = 13, H_CR_CR14 = 14
, H_CR_CR15 = 15
, H_CR_BPC = 6, H_CR_BBPSW = 8, H_CR_BBPC = 14, H_CR_CR0 = 0
, H_CR_CR1 = 1, H_CR_CR2 = 2, H_CR_CR3 = 3, H_CR_CR4 = 4
, H_CR_CR5 = 5, H_CR_CR6 = 6, H_CR_CR7 = 7, H_CR_CR8 = 8
, H_CR_CR9 = 9, H_CR_CR10 = 10, H_CR_CR11 = 11, H_CR_CR12 = 12
, H_CR_CR13 = 13, H_CR_CR14 = 14, H_CR_CR15 = 15
} H_CR;
/* start-sanitize-m32rx */
@ -100,6 +104,111 @@ typedef enum h_accums {
} H_ACCUMS;
/* end-sanitize-m32rx */
/* Attributes. */
/* Enum declaration for machine type selection. */
typedef enum mach_attr {
MACH_BASE, MACH_M32R
/* start-sanitize-m32rx */
, MACH_M32RX
/* end-sanitize-m32rx */
, MACH_MAX
} MACH_ATTR;
/* start-sanitize-m32rx */
/* Enum declaration for parallel execution pipeline selection. */
typedef enum pipe_attr {
PIPE_NONE, PIPE_O, PIPE_S, PIPE_OS
} PIPE_ATTR;
/* end-sanitize-m32rx */
/* Number of architecture variants. */
#define MAX_MACHS ((int) MACH_MAX)
/* Ifield attribute indices. */
/* Enum declaration for cgen_ifld attrs. */
typedef enum cgen_ifld_attr {
CGEN_IFLD_MACH, CGEN_IFLD_VIRTUAL, CGEN_IFLD_UNSIGNED, CGEN_IFLD_PCREL_ADDR
, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED, CGEN_IFLD_SIGN_OPT, CGEN_IFLD_RELOC
} CGEN_IFLD_ATTR;
/* Number of non-boolean elements in cgen_ifld. */
#define CGEN_IFLD_NBOOL_ATTRS ((int) CGEN_IFLD_VIRTUAL)
/* Enum declaration for m32r ifield types. */
typedef enum ifield_type {
M32R_F_NIL, M32R_F_OP1, M32R_F_OP2, M32R_F_COND
, M32R_F_R1, M32R_F_R2, M32R_F_SIMM8, M32R_F_SIMM16
, M32R_F_SHIFT_OP2, M32R_F_UIMM4, M32R_F_UIMM5, M32R_F_UIMM16
, M32R_F_UIMM24, M32R_F_HI16, M32R_F_DISP8, M32R_F_DISP16
, M32R_F_DISP24
/* start-sanitize-m32rx */
, M32R_F_OP23
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
, M32R_F_OP3
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
, M32R_F_ACC
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
, M32R_F_ACCS
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
, M32R_F_ACCD
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
, M32R_F_BITS67
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
, M32R_F_BIT14
/* end-sanitize-m32rx */
/* start-sanitize-m32rx */
, M32R_F_IMM1
/* end-sanitize-m32rx */
, M32R_F_MAX
} IFIELD_TYPE;
#define MAX_IFLD ((int) M32R_F_MAX)
/* Hardware attribute indices. */
/* Enum declaration for cgen_hw attrs. */
typedef enum cgen_hw_attr {
CGEN_HW_MACH, CGEN_HW_VIRTUAL, CGEN_HW_UNSIGNED, CGEN_HW_SIGNED
, CGEN_HW_CACHE_ADDR, CGEN_HW_FUN_ACCESS, CGEN_HW_PC, CGEN_HW_PROFILE
} CGEN_HW_ATTR;
/* Number of non-boolean elements in cgen_hw. */
#define CGEN_HW_NBOOL_ATTRS ((int) CGEN_HW_VIRTUAL)
/* Enum declaration for m32r hardware types. */
typedef enum hw_type {
HW_H_PC, HW_H_MEMORY, HW_H_SINT, HW_H_UINT
, HW_H_ADDR, HW_H_IADDR, HW_H_HI16, HW_H_SLO16
, HW_H_ULO16, HW_H_GR, HW_H_CR, HW_H_ACCUM
/* start-sanitize-m32rx */
, HW_H_ACCUMS
/* end-sanitize-m32rx */
, HW_H_COND, HW_H_PSW, HW_H_BPSW, HW_H_BBPSW
, HW_H_LOCK, HW_MAX
} HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Operand attribute indices. */
/* Enum declaration for cgen_operand attrs. */
typedef enum cgen_operand_attr {
CGEN_OPERAND_MACH, CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_UNSIGNED, CGEN_OPERAND_PCREL_ADDR
, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX
, CGEN_OPERAND_SEM_ONLY, CGEN_OPERAND_RELOC, CGEN_OPERAND_HASH_PREFIX
} CGEN_OPERAND_ATTR;
/* Number of non-boolean elements in cgen_operand. */
#define CGEN_OPERAND_NBOOL_ATTRS ((int) CGEN_OPERAND_VIRTUAL)
/* Enum declaration for m32r operand types. */
typedef enum cgen_operand_type {
M32R_OPERAND_PC, M32R_OPERAND_SR, M32R_OPERAND_DR, M32R_OPERAND_SRC1
@ -122,44 +231,13 @@ typedef enum cgen_operand_type {
, M32R_OPERAND_CONDBIT, M32R_OPERAND_ACCUM, M32R_OPERAND_MAX
} CGEN_OPERAND_TYPE;
/* Non-boolean attributes. */
/* Enum declaration for machine type selection. */
typedef enum mach_attr {
MACH_M32R
/* start-sanitize-m32rx */
, MACH_M32RX
/* end-sanitize-m32rx */
, MACH_MAX
} MACH_ATTR;
/* start-sanitize-m32rx */
/* Enum declaration for parallel execution pipeline selection. */
typedef enum pipe_attr {
PIPE_NONE, PIPE_O, PIPE_S, PIPE_OS
} PIPE_ATTR;
/* end-sanitize-m32rx */
/* Number of architecture variants. */
#define MAX_MACHS ((int) MACH_MAX)
/* Number of operands types. */
#define MAX_OPERANDS ((int) M32R_OPERAND_MAX)
/* Maximum number of operands referenced by any insn. */
#define MAX_OPERAND_INSTANCES 8
#define MAX_OPERAND_INSTANCES 11
/* Operand and instruction attribute indices. */
/* Enum declaration for cgen_operand attrs. */
typedef enum cgen_operand_attr {
CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_FAKE, CGEN_OPERAND_HASH_PREFIX, CGEN_OPERAND_NEGATIVE
, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_RELAX, CGEN_OPERAND_RELOC, CGEN_OPERAND_SIGN_OPT
, CGEN_OPERAND_UNSIGNED
} CGEN_OPERAND_ATTR;
/* Number of non-boolean elements in cgen_operand. */
#define CGEN_OPERAND_NBOOL_ATTRS ((int) CGEN_OPERAND_ABS_ADDR)
/* Insn attribute indices. */
/* Enum declaration for cgen_insn attrs. */
typedef enum cgen_insn_attr {
@ -167,17 +245,20 @@ typedef enum cgen_insn_attr {
/* start-sanitize-m32rx */
, CGEN_INSN_PIPE
/* end-sanitize-m32rx */
, CGEN_INSN_ALIAS, CGEN_INSN_COND_CTI, CGEN_INSN_FILL_SLOT, CGEN_INSN_NO_DIS
, CGEN_INSN_PARALLEL, CGEN_INSN_RELAX, CGEN_INSN_RELAXABLE, CGEN_INSN_SPECIAL
, CGEN_INSN_UNCOND_CTI
, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI, CGEN_INSN_SKIP_CTI
, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAX, CGEN_INSN_ALIAS
, CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_FILL_SLOT
/* start-sanitize-m32rx */
, CGEN_INSN_SPECIAL
/* end-sanitize-m32rx */
} CGEN_INSN_ATTR;
/* Number of non-boolean elements in cgen_insn. */
#define CGEN_INSN_NBOOL_ATTRS ((int) CGEN_INSN_ALIAS)
#define CGEN_INSN_NBOOL_ATTRS ((int) CGEN_INSN_VIRTUAL)
/* Enum declaration for m32r instruction types. */
typedef enum cgen_insn_type {
M32R_INSN_ILLEGAL, M32R_INSN_ADD, M32R_INSN_ADD3, M32R_INSN_AND
M32R_INSN_INVALID, M32R_INSN_ADD, M32R_INSN_ADD3, M32R_INSN_AND
, M32R_INSN_AND3, M32R_INSN_OR, M32R_INSN_OR3, M32R_INSN_XOR
, M32R_INSN_XOR3, M32R_INSN_ADDI, M32R_INSN_ADDV, M32R_INSN_ADDV3
, M32R_INSN_ADDX, M32R_INSN_BC8, M32R_INSN_BC24, M32R_INSN_BEQ
@ -321,8 +402,8 @@ typedef enum cgen_insn_type {
, M32R_INSN_MAX
} CGEN_INSN_TYPE;
/* Index of `illegal' insn place holder. */
#define CGEN_INSN_ILLEGAL M32R_INSN_ILLEGAL
/* Index of `invalid' insn place holder. */
#define CGEN_INSN_INVALID M32R_INSN_INVALID
/* Total number of insns in table. */
#define MAX_INSNS ((int) M32R_INSN_MAX)
@ -377,24 +458,10 @@ struct cgen_fields
};
/* Attributes. */
extern const CGEN_ATTR_TABLE m32r_cgen_hw_attr_table[];
extern const CGEN_ATTR_TABLE m32r_cgen_operand_attr_table[];
extern const CGEN_ATTR_TABLE m32r_cgen_insn_attr_table[];
/* Enum declaration for m32r hardware types. */
typedef enum hw_type {
HW_H_PC, HW_H_MEMORY, HW_H_SINT, HW_H_UINT
, HW_H_ADDR, HW_H_IADDR, HW_H_HI16, HW_H_SLO16
, HW_H_ULO16, HW_H_GR, HW_H_CR, HW_H_ACCUM
/* start-sanitize-m32rx */
, HW_H_ACCUMS
/* end-sanitize-m32rx */
, HW_H_COND, HW_H_SM, HW_H_BSM, HW_H_IE
, HW_H_BIE, HW_H_BCOND, HW_H_BPC, HW_H_LOCK
, HW_MAX
} HW_TYPE;
#define MAX_HW ((int) HW_MAX)
/* Hardware decls. */
extern CGEN_KEYWORD m32r_cgen_opval_h_gr;