* config/tc-rx.c (rx_fetchalign): Declare.

(md_pseudo_table): Add .fetchalign.
(RX_NBASE_FETCHALIGN): New.
(fetchalign_bytes): New.
(rx_fetchalign): New.
(rx_frag_init): If a "magic" value is found, also init the
machine-specific data.
(md_assemble): Note following opcode size if called for.
(rx_next_opcode): New.
(rx_relax_frag): Support .fetchalign.
(md_convert_frag): Likewise.
* doc/c-rx.texi (RX-Directives): Add .fetchalign.
This commit is contained in:
DJ Delorie 2012-05-15 03:04:47 +00:00
parent d051b294b9
commit 0e25bcb440
3 changed files with 121 additions and 3 deletions

View File

@ -1,3 +1,18 @@
2012-05-14 DJ Delorie <dj@redhat.com>
* config/tc-rx.c (rx_fetchalign): Declare.
(md_pseudo_table): Add .fetchalign.
(RX_NBASE_FETCHALIGN): New.
(fetchalign_bytes): New.
(rx_fetchalign): New.
(rx_frag_init): If a "magic" value is found, also init the
machine-specific data.
(md_assemble): Note following opcode size if called for.
(rx_next_opcode): New.
(rx_relax_frag): Support .fetchalign.
(md_convert_frag): Likewise.
* doc/c-rx.texi (RX-Directives): Add .fetchalign.
2012-05-14 James Lemke <jwlemke@codesourcery.com>
* config/tc-ppc.c (insn_validate): New func of existing code to call..

View File

@ -56,6 +56,8 @@ static int rx_num_int_regs = 0;
int rx_pid_register;
int rx_gp_register;
static void rx_fetchalign (int ignore ATTRIBUTE_UNUSED);
enum options
{
OPTION_BIG = OPTION_MD_BASE,
@ -600,6 +602,8 @@ const pseudo_typeS md_pseudo_table[] =
{ "int", cons, 4 },
{ "word", cons, 4 },
{ "fetchalign", rx_fetchalign, 0 },
/* End of list marker. */
{ NULL, NULL, 0 }
};
@ -648,9 +652,14 @@ md_begin (void)
char * rx_lex_start;
char * rx_lex_end;
/* These negative numbers are found in rx_bytesT.n_base for non-opcode
md_frags */
#define RX_NBASE_FETCHALIGN -1
typedef struct rx_bytesT
{
char base[4];
/* If this is negative, it's a special-purpose frag as per the defines above. */
int n_base;
char ops[8];
int n_ops;
@ -678,6 +687,31 @@ typedef struct rx_bytesT
} rx_bytesT;
static rx_bytesT rx_bytes;
/* We set n_ops to be "size of next opcode" if the next opcode doesn't relax. */
static rx_bytesT *fetchalign_bytes = NULL;
static void
rx_fetchalign (int ignore ATTRIBUTE_UNUSED)
{
char * bytes;
fragS * frag_then;
memset (& rx_bytes, 0, sizeof (rx_bytes));
rx_bytes.n_base = RX_NBASE_FETCHALIGN;
bytes = frag_more (8);
frag_then = frag_now;
frag_variant (rs_machine_dependent,
0 /* max_chars */,
0 /* var */,
0 /* subtype */,
0 /* symbol */,
0 /* offset */,
0 /* opcode */);
frag_then->fr_opcode = bytes;
frag_then->fr_subtype = 0;
fetchalign_bytes = frag_then->tc_frag_data;
}
void
rx_relax (int type, int pos)
@ -933,7 +967,7 @@ rx_wrap (void)
void
rx_frag_init (fragS * fragP)
{
if (rx_bytes.n_relax || rx_bytes.link_relax)
if (rx_bytes.n_relax || rx_bytes.link_relax || rx_bytes.n_base < 0)
{
fragP->tc_frag_data = malloc (sizeof (rx_bytesT));
memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT));
@ -1049,8 +1083,12 @@ md_assemble (char * str)
{
bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops);
frag_then = frag_now;
if (fetchalign_bytes)
fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops;
}
fetchalign_bytes = NULL;
APPEND (base, n_base);
APPEND (ops, n_ops);
@ -1413,6 +1451,18 @@ md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTR
return delta;
}
/* Given a frag FRAGP, return the "next" frag that contains an
opcode. Assumes the next opcode is relaxable, and thus rs_machine_dependent. */
static fragS *
rx_next_opcode (fragS *fragP)
{
do {
fragP = fragP->fr_next;
} while (fragP && fragP->fr_type != rs_machine_dependent);
return fragP;
}
/* Given the new addresses for this relax pass, figure out how big
each opcode must be. We store the total number of bytes needed in
fr_subtype. The return value is the difference between the size
@ -1437,6 +1487,34 @@ rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
(long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN)
{
unsigned int next_size;
if (fragP->fr_next == NULL)
return 0;
next_size = fragP->tc_frag_data->n_ops;
if (next_size == 0)
{
fragS *n = rx_next_opcode (fragP);
next_size = n->fr_subtype;
}
fragP->fr_subtype = (8-(mypc & 7)) & 7;
tprintf("subtype %u\n", fragP->fr_subtype);
if (fragP->fr_subtype >= next_size)
fragP->fr_subtype = 0;
tprintf ("\033[34m -> mypc %lu next_size %u new %d old %d delta %d (fetchalign)\033[0m\n",
mypc & 7,
next_size, fragP->fr_subtype, oldsize, fragP->fr_subtype-oldsize);
newsize = fragP->fr_subtype;
return newsize - oldsize;
}
optype = rx_opcode_type (fragP->fr_opcode);
/* In the one case where we have both a disp and imm relaxation, we want
@ -1485,7 +1563,6 @@ rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
return newsize - oldsize;
}
mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
if (sym_addr > mypc)
addr0 += stretch;
@ -1644,13 +1721,29 @@ md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
{
int i;
printf ("lit %08x opc %08x", (int) fragP->fr_literal, (int) fragP->fr_opcode);
printf ("lit 0x%p opc 0x%p", fragP->fr_literal, fragP->fr_opcode);
for (i = 0; i < 10; i++)
printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
printf ("\n");
}
#endif
if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN)
{
int count = fragP->fr_subtype;
if (count == 0)
;
else if (count > BIGGEST_NOP)
{
op[0] = 0x2e;
op[1] = count;
}
else if (count > 0)
{
memcpy (op, nops[count], count);
}
}
/* In the one case where we have both a disp and imm relaxation, we want
the imm relaxation here. */
ri = 0;

View File

@ -155,6 +155,16 @@ assembler directives:
@cindex RX assembler directive .3byte
Inserts a 3-byte value into the output file at the current location.
@item .fetchalign
@cindex assembler directive .fetchalign, RX
@cindex RX assembler directive .fetchalign
If the next opcode following this directive spans a fetch line
boundary (8 byte boundary), the opcode is aligned to that boundary.
If the next opcode does not span a fetch line, this directive has no
effect. Note that one or more labels may be between this directive
and the opcode; those labels are aligned as well. Any inserted bytes
due to alignment will form a NOP opcode.
@end table
@node RX-Float