* fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerate.

This commit is contained in:
Doug Evans
1998-12-03 08:14:46 +00:00
parent 1c3cd1b020
commit a73911a767
5 changed files with 791 additions and 568 deletions

View File

@ -1,3 +1,9 @@
start-sanitize-fr30
Thu Dec 3 00:09:17 1998 Doug Evans <devans@canuck.cygnus.com>
* fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerate.
end-sanitize-fr30
1998-11-30 Doug Evans <devans@casey.cygnus.com>
* cgen-dis.c (hash_insn_array): CGEN_INSN_VALUE ->

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 *));
@ -184,6 +187,16 @@ fr30_cgen_parse_operand (od, opindex, strp, fields)
case FR30_OPERAND_I32 :
errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_I32, &fields->f_i32);
break;
case FR30_OPERAND_I20 :
errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_I20, &fields->f_i20);
break;
case FR30_OPERAND_LABEL9 :
{
bfd_vma value;
errmsg = cgen_parse_address (od, strp, FR30_OPERAND_LABEL9, 0, NULL, & value);
fields->f_rel9 = value;
}
break;
case FR30_OPERAND_DIR8 :
errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_DIR8, &fields->f_dir8);
break;
@ -193,11 +206,12 @@ fr30_cgen_parse_operand (od, opindex, strp, fields)
case FR30_OPERAND_DIR10 :
errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_DIR10, &fields->f_dir10);
break;
case FR30_OPERAND_LABEL9 :
errmsg = cgen_parse_unsigned_integer (od, strp, FR30_OPERAND_LABEL9, &fields->f_rel9);
break;
case FR30_OPERAND_LABEL12 :
errmsg = cgen_parse_signed_integer (od, strp, FR30_OPERAND_LABEL12, &fields->f_rel12);
{
bfd_vma value;
errmsg = cgen_parse_address (od, strp, FR30_OPERAND_LABEL12, 0, NULL, & value);
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);
@ -245,147 +259,162 @@ fr30_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 FR30_OPERAND_RI :
errmsg = insert_normal (od, fields->f_Ri, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_Ri, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_RJ :
errmsg = insert_normal (od, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_RIC :
errmsg = insert_normal (od, fields->f_Ric, 0|(1<<CGEN_OPERAND_UNSIGNED), 28, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_Ric, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 12, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_RJC :
errmsg = insert_normal (od, fields->f_Rjc, 0|(1<<CGEN_OPERAND_UNSIGNED), 24, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_Rjc, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_CRI :
errmsg = insert_normal (od, fields->f_CRi, 0|(1<<CGEN_OPERAND_UNSIGNED), 28, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_CRi, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 12, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_CRJ :
errmsg = insert_normal (od, fields->f_CRj, 0|(1<<CGEN_OPERAND_UNSIGNED), 24, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_CRj, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_RS1 :
errmsg = insert_normal (od, fields->f_Rs1, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_Rs1, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_RS2 :
errmsg = insert_normal (od, fields->f_Rs2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_Rs2, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_R13 :
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 FR30_OPERAND_R14 :
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 FR30_OPERAND_R15 :
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 FR30_OPERAND_PS :
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 FR30_OPERAND_U4 :
errmsg = insert_normal (od, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_U4C :
errmsg = insert_normal (od, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_M4 :
{
long value = fields->f_m4;
value = ((value) & (15));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
}
break;
case FR30_OPERAND_U8 :
errmsg = insert_normal (od, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
break;
case FR30_OPERAND_I8 :
errmsg = insert_normal (od, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 8, 16, total_length, buffer);
break;
case FR30_OPERAND_UDISP6 :
{
long value = fields->f_udisp6;
value = ((unsigned int) (value) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, buffer);
}
break;
case FR30_OPERAND_DISP8 :
errmsg = insert_normal (od, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 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), 4, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 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), 4, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 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), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 0, 8, 8, 16, total_length, buffer);
}
break;
case FR30_OPERAND_U10 :
{
long value = fields->f_u10;
value = ((unsigned int) (value) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
}
break;
case FR30_OPERAND_I32 :
errmsg = insert_normal (od, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 32, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 0, 32, 32, total_length, buffer);
break;
case FR30_OPERAND_DIR8 :
errmsg = insert_normal (od, fields->f_dir8, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
break;
case FR30_OPERAND_DIR9 :
case FR30_OPERAND_I20 :
{
long value = fields->f_dir9;
value = ((unsigned int) (value) >> (1));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
}
break;
case FR30_OPERAND_DIR10 :
{
long value = fields->f_dir10;
value = ((unsigned int) (value) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
do {
FLD (f_i20_4) = ((unsigned int) (FLD (f_i20)) >> (16));
FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
} while (0);
errmsg = insert_normal (od, fields->f_i20_4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED)|(1<<CGEN_OPERAND_VIRTUAL), 0, 8, 4, 16, total_length, buffer);
if (errmsg)
break;
errmsg = insert_normal (od, fields->f_i20_16, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED)|(1<<CGEN_OPERAND_VIRTUAL), 16, 0, 16, 16, total_length, buffer);
if (errmsg)
break;
}
break;
case FR30_OPERAND_LABEL9 :
{
long value = fields->f_rel9;
value = ((int) (((value) - (((pc) + (2))))) >> (1));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 0, 8, 8, 16, total_length, buffer);
}
break;
case FR30_OPERAND_DIR8 :
errmsg = insert_normal (od, fields->f_dir8, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
break;
case FR30_OPERAND_DIR9 :
{
long value = fields->f_dir9;
value = ((unsigned int) (value) >> (1));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, buffer);
}
break;
case FR30_OPERAND_DIR10 :
{
long value = fields->f_dir10;
value = ((unsigned int) (value) >> (2));
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_UNSIGNED), 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), 5, 11, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 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), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_reglist_low, 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), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_reglist_hi, 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), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_cc, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 16, total_length, buffer);
break;
case FR30_OPERAND_CCC :
errmsg = insert_normal (od, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
errmsg = insert_normal (od, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 0, 8, 16, total_length, buffer);
break;
default :
@ -464,7 +493,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);
@ -510,27 +539,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. */
/* ??? 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];
@ -541,6 +569,21 @@ 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)
{
@ -570,144 +613,23 @@ insert_normal (od, value, attrs, start, length, total_length, buffer)
#if CGEN_INT_INSN_P
if (total_length > 32) /* 32 bits in a portable host int */
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;
/* 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. 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 fetch_length here
would be 16. To handle a 24 bit insn with an 18 bit immediate,
insert_1 handles 24 bits. */
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 = fetch_length;
}
}
else
{
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
{
int offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length = fetch_length;
}
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 */
@ -846,7 +768,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. */
@ -863,8 +785,10 @@ insert_insn_normal (od, insn, fields, buffer, pc)
#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)
{
@ -937,9 +861,7 @@ fr30_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_INT,
unsigned int, int, int, int, bfd_vma, long *));
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
@ -108,19 +112,6 @@ print_low_register_list (od, dis_info, value, attrs, pc, length)
print_register_list (dis_info, value, 0);
}
static void
print_label9 (od, dis_info, value, attrs, pc, length)
CGEN_OPCODE_DESC od;
PTR dis_info;
long value;
unsigned int attrs;
bfd_vma pc;
int length;
{
disassemble_info *info = (disassemble_info *) dis_info;
(*info->fprintf_func) (info->stream, "0x%lx", value);
}
/* -- */
/* Main entry point for operand extraction.
@ -147,80 +138,81 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
bfd_vma pc;
{
int length;
unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
switch (opindex)
{
case FR30_OPERAND_RI :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Ri);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
break;
case FR30_OPERAND_RJ :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rj);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
break;
case FR30_OPERAND_RIC :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 28, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Ric);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
break;
case FR30_OPERAND_RJC :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 24, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rjc);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
break;
case FR30_OPERAND_CRI :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 28, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_CRi);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
break;
case FR30_OPERAND_CRJ :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 24, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_CRj);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
break;
case FR30_OPERAND_RS1 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rs1);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
break;
case FR30_OPERAND_RS2 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rs2);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
break;
case FR30_OPERAND_R13 :
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case FR30_OPERAND_R14 :
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case FR30_OPERAND_R15 :
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case FR30_OPERAND_PS :
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
length = extract_normal (od, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
break;
case FR30_OPERAND_U4 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u4);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & fields->f_u4);
break;
case FR30_OPERAND_U4C :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u4c);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
break;
case FR30_OPERAND_M4 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & value);
value = ((value) | ((! (15))));
fields->f_m4 = value;
}
break;
case FR30_OPERAND_U8 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u8);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_u8);
break;
case FR30_OPERAND_I8 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_i8);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_i8);
break;
case FR30_OPERAND_UDISP6 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 4, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_udisp6 = value;
}
break;
case FR30_OPERAND_DISP8 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_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);
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), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & 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);
value = ((value) << (1));
fields->f_disp9 = value;
}
@ -228,7 +220,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), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & 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);
value = ((value) << (2));
fields->f_disp10 = value;
}
@ -236,7 +228,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), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & 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);
value = ((value) << (2));
fields->f_s10 = value;
}
@ -244,21 +236,38 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
case FR30_OPERAND_U10 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_u10 = value;
}
break;
case FR30_OPERAND_I32 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 32, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_i32);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
break;
case FR30_OPERAND_I20 :
{
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED)|(1<<CGEN_OPERAND_VIRTUAL), 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED)|(1<<CGEN_OPERAND_VIRTUAL), 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
do {
FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
} while (0);
}
break;
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);
value = ((((value) << (1))) + (((pc) + (2))));
fields->f_rel9 = value;
}
break;
case FR30_OPERAND_DIR8 :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_dir8);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
break;
case FR30_OPERAND_DIR9 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & value);
value = ((value) << (1));
fields->f_dir9 = value;
}
@ -266,38 +275,30 @@ fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
case FR30_OPERAND_DIR10 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 8, 16, total_length, pc, & value);
value = ((value) << (2));
fields->f_dir10 = value;
}
break;
case FR30_OPERAND_LABEL9 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
value = ((((value) << (1))) + (((pc) + (2))));
fields->f_rel9 = value;
}
break;
case FR30_OPERAND_LABEL12 :
{
long value;
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 5, 11, CGEN_FIELDS_BITSIZE (fields), pc, & 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);
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), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_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);
break;
case FR30_OPERAND_REGLIST_HI :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_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);
break;
case FR30_OPERAND_CC :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_cc);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 16, total_length, pc, & fields->f_cc);
break;
case FR30_OPERAND_CCC :
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_ccc);
length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
break;
default :
@ -408,6 +409,12 @@ fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
case FR30_OPERAND_I32 :
print_normal (od, info, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_I20 :
print_normal (od, info, fields->f_i20, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED)|(1<<CGEN_OPERAND_VIRTUAL), 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);
break;
case FR30_OPERAND_DIR8 :
print_normal (od, info, fields->f_dir8, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
@ -417,11 +424,8 @@ fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
case FR30_OPERAND_DIR10 :
print_normal (od, info, fields->f_dir10, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
break;
case FR30_OPERAND_LABEL9 :
print_label9 (od, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), pc, length);
break;
case FR30_OPERAND_LABEL12 :
print_normal (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)|(1<<CGEN_OPERAND_SIGNED), 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);
@ -468,6 +472,8 @@ fr30_cgen_init_dis (od)
/* 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
@ -558,7 +564,7 @@ extract_1 (od, ex_info, start, length, word_length, bufp, pc)
/* 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;
@ -571,26 +577,33 @@ extract_1 (od, ex_info, start, length, word_length, bufp, pc)
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',
ATTRS is a mask of the boolean attributes. We only need `UNSIGNED',
but for generality we take a bitmask of all of them.
TOTAL_LENGTH is the length of the insn in bits.
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, pc, 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_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. */
@ -601,17 +614,31 @@ extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, pc,
}
if (CGEN_INT_INSN_P
|| (CGEN_INSN_LSB0_P
? ((total_length - start) <= CGEN_BASE_INSN_BITSIZE)
: ((start + length) <= CGEN_BASE_INSN_BITSIZE)))
&& 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
/* Does the value reside in INSN_VALUE? */
if (word_offset == 0)
{
/* Written this way to avoid undefined behaviour. */
unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
if (CGEN_INSN_LSB0_P)
value = insn_value >> start;
value = insn_value >> ((start + 1) - length);
else
value = insn_value >> (total_length - (start + length));
value = insn_value >> (word_length - (start + length));
value &= mask;
/* sign extend? */
if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
@ -621,75 +648,17 @@ extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, pc,
#if ! CGEN_INT_INSN_P
/* 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. The hard case is defined
to be when a field straddles a (loosely defined) word boundary
(??? which may require target specific help to determine). */
#define HARD_CASE_P 0 /* FIXME:wip */
else if (HARD_CASE_P)
{
}
else
{
unsigned char *bufp = ex_info->insn_bytes;
int offset = 0;
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 fetch_length here
would be 16. To handle a 24 bit insn with an 18 bit immediate,
extract_1 handles 24 bits. */
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
{
offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length = fetch_length;
}
}
else
{
if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
{
offset = start & ~7;
bufp += offset / 8;
start -= offset;
total_length = fetch_length;
}
else
{
abort (); /* wip */
}
}
}
if (fill_cache (od, ex_info, offset / 8, total_length / 8, pc) == 0)
if (fill_cache (od, ex_info, word_offset / 8, word_length / 8, pc) == 0)
return 0;
value = extract_1 (od, ex_info, start, length, total_length, bufp, pc);
value = extract_1 (od, ex_info, start, length, word_length, bufp, pc);
}
#endif /* ! CGEN_INT_INSN_P */
@ -912,7 +881,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,7 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define CGEN_ARCH fr30
/* Given symbol S, return fr30_cgen_<s>. */
/* Given symbol S, return fr30_cgen_<S>. */
#define CGEN_SYM(s) CONCAT3 (fr30,_cgen_,s)
/* Selected cpu families. */
@ -54,6 +54,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 op1 enums. */
@ -149,11 +152,11 @@ typedef enum cgen_operand_type {
, FR30_OPERAND_PS, FR30_OPERAND_U4, FR30_OPERAND_U4C, FR30_OPERAND_M4
, 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_DIR8, FR30_OPERAND_DIR9, FR30_OPERAND_DIR10
, FR30_OPERAND_LABEL9, FR30_OPERAND_LABEL12, FR30_OPERAND_REGLIST_LOW, FR30_OPERAND_REGLIST_HI
, 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_MAX
, FR30_OPERAND_I32, FR30_OPERAND_I20, FR30_OPERAND_LABEL9, FR30_OPERAND_DIR8
, FR30_OPERAND_DIR9, FR30_OPERAND_DIR10, FR30_OPERAND_LABEL12, FR30_OPERAND_REGLIST_LOW
, FR30_OPERAND_REGLIST_HI, 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_MAX
} CGEN_OPERAND_TYPE;
/* Non-boolean attributes. */
@ -182,11 +185,38 @@ typedef enum 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. */
/* 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_ATTR;
/* Number of non-boolean elements in cgen_ifld. */
#define CGEN_IFLD_NBOOL_ATTRS ((int) CGEN_IFLD_ABS_ADDR)
/* Enum declaration for fr30 ifield types. */
typedef enum ifield_type {
FR30_F_NIL, FR30_F_OP1, FR30_F_OP2, FR30_F_OP3
, FR30_F_OP4, FR30_F_OP5, FR30_F_CC, FR30_F_CCC
, FR30_F_RJ, FR30_F_RI, FR30_F_RS1, FR30_F_RS2
, FR30_F_RJC, FR30_F_RIC, FR30_F_CRJ, FR30_F_CRI
, FR30_F_U4, FR30_F_U4C, FR30_F_I4, FR30_F_M4
, FR30_F_U8, FR30_F_I8, FR30_F_I20_4, FR30_F_I20_16
, FR30_F_I20, FR30_F_I32, FR30_F_UDISP6, FR30_F_DISP8
, FR30_F_DISP9, FR30_F_DISP10, FR30_F_S10, FR30_F_U10
, FR30_F_REL9, FR30_F_DIR8, FR30_F_DIR9, FR30_F_DIR10
, FR30_F_REL12, FR30_F_REGLIST_HI, FR30_F_REGLIST_LOW, FR30_F_MAX
} IFIELD_TYPE;
#define MAX_IFLD ((int) FR30_F_MAX)
/* 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_UNSIGNED, CGEN_OPERAND_VIRTUAL
} CGEN_OPERAND_ATTR;
/* Number of non-boolean elements in cgen_operand. */
@ -194,8 +224,9 @@ typedef enum cgen_operand_attr {
/* Enum declaration for cgen_insn attrs. */
typedef enum cgen_insn_attr {
CGEN_INSN_ALIAS, CGEN_INSN_COND_CTI, CGEN_INSN_NO_DIS, CGEN_INSN_RELAX
, CGEN_INSN_RELAXABLE, CGEN_INSN_SKIP_CTI, CGEN_INSN_UNCOND_CTI, CGEN_INSN_VIRTUAL
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_ATTR;
/* Number of non-boolean elements in cgen_insn. */
@ -216,35 +247,35 @@ typedef enum cgen_insn_type {
, FR30_INSN_DIV1, FR30_INSN_DIV2, FR30_INSN_DIV3, FR30_INSN_DIV4S
, FR30_INSN_LSL, FR30_INSN_LSLI, FR30_INSN_LSL2, FR30_INSN_LSR
, FR30_INSN_LSRI, FR30_INSN_LSR2, FR30_INSN_ASR, FR30_INSN_ASRI
, FR30_INSN_ASR2, FR30_INSN_LDI_8, FR30_INSN_LDI32, FR30_INSN_LD
, FR30_INSN_LDUH, FR30_INSN_LDUB, FR30_INSN_LDR13, FR30_INSN_LDR13UH
, FR30_INSN_LDR13UB, FR30_INSN_LDR14, FR30_INSN_LDR14UH, FR30_INSN_LDR14UB
, FR30_INSN_LDR15, FR30_INSN_LDR15GR, FR30_INSN_LDR15DR, FR30_INSN_LDR15PS
, FR30_INSN_ST, FR30_INSN_STH, FR30_INSN_STB, FR30_INSN_STR13
, FR30_INSN_STR13H, FR30_INSN_STR13B, FR30_INSN_STR14, FR30_INSN_STR14H
, FR30_INSN_STR14B, FR30_INSN_STR15, FR30_INSN_STR15GR, FR30_INSN_STR15DR
, FR30_INSN_STR15PS, FR30_INSN_MOV, FR30_INSN_MOVDR, FR30_INSN_MOVPS
, FR30_INSN_MOV2DR, FR30_INSN_MOV2PS, FR30_INSN_JMP, FR30_INSN_JMPD
, FR30_INSN_CALLR, FR30_INSN_CALLRD, FR30_INSN_CALL, FR30_INSN_CALLD
, FR30_INSN_RET, FR30_INSN_RETD, FR30_INSN_INT, FR30_INSN_INTE
, FR30_INSN_RETI, FR30_INSN_BRA, FR30_INSN_BNO, FR30_INSN_BEQ
, FR30_INSN_BNE, FR30_INSN_BC, FR30_INSN_BNC, FR30_INSN_BN
, FR30_INSN_BP, FR30_INSN_BV, FR30_INSN_BNV, FR30_INSN_BLT
, FR30_INSN_BGE, FR30_INSN_BLE, FR30_INSN_BGT, FR30_INSN_BLS
, FR30_INSN_BHI, FR30_INSN_BRAD, FR30_INSN_BNOD, FR30_INSN_BEQD
, FR30_INSN_BNED, FR30_INSN_BCD, FR30_INSN_BNCD, FR30_INSN_BND
, FR30_INSN_BPD, FR30_INSN_BVD, FR30_INSN_BNVD, FR30_INSN_BLTD
, FR30_INSN_BGED, FR30_INSN_BLED, FR30_INSN_BGTD, FR30_INSN_BLSD
, FR30_INSN_BHID, FR30_INSN_DMOVR13, FR30_INSN_DMOVR13H, FR30_INSN_DMOVR13B
, FR30_INSN_DMOVR13PI, FR30_INSN_DMOVR13PIH, FR30_INSN_DMOVR13PIB, FR30_INSN_DMOVR15PI
, FR30_INSN_DMOV2R13, FR30_INSN_DMOV2R13H, FR30_INSN_DMOV2R13B, FR30_INSN_DMOV2R13PI
, FR30_INSN_DMOV2R13PIH, FR30_INSN_DMOV2R13PIB, FR30_INSN_DMOV2R15PD, FR30_INSN_LDRES
, FR30_INSN_STRES, FR30_INSN_COPOP, FR30_INSN_COPLD, FR30_INSN_COPST
, FR30_INSN_COPSV, FR30_INSN_NOP, FR30_INSN_ANDCCR, FR30_INSN_ORCCR
, FR30_INSN_STILM, FR30_INSN_ADDSP, FR30_INSN_EXTSB, FR30_INSN_EXTUB
, FR30_INSN_EXTSH, FR30_INSN_EXTUH, FR30_INSN_LDM0, FR30_INSN_LDM1
, FR30_INSN_STM0, FR30_INSN_STM1, FR30_INSN_ENTER, FR30_INSN_LEAVE
, FR30_INSN_XCHB, FR30_INSN_MAX
, FR30_INSN_ASR2, FR30_INSN_LDI8, FR30_INSN_LDI20, FR30_INSN_LDI32
, FR30_INSN_LD, FR30_INSN_LDUH, FR30_INSN_LDUB, FR30_INSN_LDR13
, FR30_INSN_LDR13UH, FR30_INSN_LDR13UB, FR30_INSN_LDR14, FR30_INSN_LDR14UH
, FR30_INSN_LDR14UB, FR30_INSN_LDR15, FR30_INSN_LDR15GR, FR30_INSN_LDR15DR
, FR30_INSN_LDR15PS, FR30_INSN_ST, FR30_INSN_STH, FR30_INSN_STB
, FR30_INSN_STR13, FR30_INSN_STR13H, FR30_INSN_STR13B, FR30_INSN_STR14
, FR30_INSN_STR14H, FR30_INSN_STR14B, FR30_INSN_STR15, FR30_INSN_STR15GR
, FR30_INSN_STR15DR, FR30_INSN_STR15PS, FR30_INSN_MOV, FR30_INSN_MOVDR
, FR30_INSN_MOVPS, FR30_INSN_MOV2DR, FR30_INSN_MOV2PS, FR30_INSN_JMP
, FR30_INSN_JMPD, FR30_INSN_CALLR, FR30_INSN_CALLRD, FR30_INSN_CALL
, FR30_INSN_CALLD, FR30_INSN_RET, FR30_INSN_RETD, FR30_INSN_INT
, FR30_INSN_INTE, FR30_INSN_RETI, FR30_INSN_BRA, FR30_INSN_BNO
, FR30_INSN_BEQ, FR30_INSN_BNE, FR30_INSN_BC, FR30_INSN_BNC
, FR30_INSN_BN, FR30_INSN_BP, FR30_INSN_BV, FR30_INSN_BNV
, FR30_INSN_BLT, FR30_INSN_BGE, FR30_INSN_BLE, FR30_INSN_BGT
, FR30_INSN_BLS, FR30_INSN_BHI, FR30_INSN_BRAD, FR30_INSN_BNOD
, FR30_INSN_BEQD, FR30_INSN_BNED, FR30_INSN_BCD, FR30_INSN_BNCD
, FR30_INSN_BND, FR30_INSN_BPD, FR30_INSN_BVD, FR30_INSN_BNVD
, FR30_INSN_BLTD, FR30_INSN_BGED, FR30_INSN_BLED, FR30_INSN_BGTD
, FR30_INSN_BLSD, FR30_INSN_BHID, FR30_INSN_DMOVR13, FR30_INSN_DMOVR13H
, FR30_INSN_DMOVR13B, FR30_INSN_DMOVR13PI, FR30_INSN_DMOVR13PIH, FR30_INSN_DMOVR13PIB
, FR30_INSN_DMOVR15PI, FR30_INSN_DMOV2R13, FR30_INSN_DMOV2R13H, FR30_INSN_DMOV2R13B
, FR30_INSN_DMOV2R13PI, FR30_INSN_DMOV2R13PIH, FR30_INSN_DMOV2R13PIB, FR30_INSN_DMOV2R15PD
, FR30_INSN_LDRES, FR30_INSN_STRES, FR30_INSN_COPOP, FR30_INSN_COPLD
, FR30_INSN_COPST, FR30_INSN_COPSV, FR30_INSN_NOP, FR30_INSN_ANDCCR
, FR30_INSN_ORCCR, FR30_INSN_STILM, FR30_INSN_ADDSP, FR30_INSN_EXTSB
, FR30_INSN_EXTUB, FR30_INSN_EXTSH, FR30_INSN_EXTUH, FR30_INSN_LDM0
, FR30_INSN_LDM1, FR30_INSN_STM0, FR30_INSN_STM1, FR30_INSN_ENTER
, FR30_INSN_LEAVE, FR30_INSN_XCHB, FR30_INSN_MAX
} CGEN_INSN_TYPE;
/* Index of `invalid' insn place holder. */
@ -280,6 +311,9 @@ struct cgen_fields
long f_m4;
long f_u8;
long f_i8;
long f_i20_4;
long f_i20_16;
long f_i20;
long f_i32;
long f_udisp6;
long f_disp8;
@ -336,6 +370,15 @@ extern CGEN_KEYWORD fr30_cgen_opval_h_r15;
{\
}
/* -- opc.h */
/* ??? This can be improved upon. */
#undef CGEN_DIS_HASH_SIZE
#define CGEN_DIS_HASH_SIZE 16
#undef CGEN_DIS_HASH
#define CGEN_DIS_HASH(buffer, value) (((unsigned char *) (buffer))[0] >> 4)
/* -- */
#endif /* FR30_OPC_H */