diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2004-03-03 04:37:38 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2004-03-03 04:37:38 +0000 |
commit | 9545c4ce8548ba44d2401ce85aafb8c51b03c667 (patch) | |
tree | 9af1d72bde85b8a0ae5763932b90b041ca0f35b4 /gas/config | |
parent | 284a7efdbe31e61152c5fad03ced4f4e0b84f700 (diff) | |
download | gdb-9545c4ce8548ba44d2401ce85aafb8c51b03c667.zip gdb-9545c4ce8548ba44d2401ce85aafb8c51b03c667.tar.gz gdb-9545c4ce8548ba44d2401ce85aafb8c51b03c667.tar.bz2 |
2004-03-02 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-ia64.c (align_frag): New.
(md_assemble): Set the tc_frag_data field in align_frag for
IA64_OPCODE_FIRST instructions.
(ia64_md_do_align): Set align_frag.
(ia64_handle_align): Add a stop bit if needed.
* config/tc-ia64.h (TC_FRAG_TYPE): New.
(TC_FRAG_INIT): New.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-ia64.c | 33 | ||||
-rw-r--r-- | gas/config/tc-ia64.h | 4 |
2 files changed, 35 insertions, 2 deletions
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index 57a6b1d..96a0ef5 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -636,6 +636,9 @@ static struct gr { valueT value; } gr_values[128] = {{ 1, 0, 0 }}; +/* Remember the alignment frag. */ +static fragS *align_frag; + /* These are the routines required to output the various types of unwind records. */ @@ -9990,7 +9993,24 @@ md_assemble (str) flags = idesc->flags; if ((flags & IA64_OPCODE_FIRST) != 0) - insn_group_break (1, 0, 0); + { + /* The alignment frag has to end with a stop bit only if the + next instruction after the alignment directive has to be + the first instruction in an instruction group. */ + if (align_frag) + { + while (align_frag->fr_type != rs_align_code) + { + align_frag = align_frag->fr_next; + assert (align_frag); + } + if (align_frag->fr_next == frag_now) + align_frag->tc_frag_data = 1; + } + + insn_group_break (1, 0, 0); + } + align_frag = NULL; if ((flags & IA64_OPCODE_NO_PRED) != 0 && qp_regno != 0) { @@ -10808,6 +10828,8 @@ ia64_md_do_align (n, fill, len, max) int len ATTRIBUTE_UNUSED; int max ATTRIBUTE_UNUSED; { + /* The current frag is an alignment frag. */ + align_frag = frag_now; if (subseg_text_p (now_seg)) ia64_flush_insns (); } @@ -10823,13 +10845,20 @@ ia64_handle_align (fragp) static const unsigned char le_nop[] = { 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00}; + static const unsigned char le_nop_stop[] + = { 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00}; int bytes; char *p; + const unsigned char *nop; if (fragp->fr_type != rs_align_code) return; + /* Check if this frag has to end with a stop bit. */ + nop = fragp->tc_frag_data ? le_nop_stop : le_nop; + bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; p = fragp->fr_literal + fragp->fr_fix; @@ -10845,7 +10874,7 @@ ia64_handle_align (fragp) } /* Instruction bundles are always little-endian. */ - memcpy (p, le_nop, 16); + memcpy (p, nop, 16); fragp->fr_var = 16; } diff --git a/gas/config/tc-ia64.h b/gas/config/tc-ia64.h index e27f5e0..b112e75 100644 --- a/gas/config/tc-ia64.h +++ b/gas/config/tc-ia64.h @@ -155,6 +155,10 @@ extern void ia64_convert_frag (fragS *); #define TC_DWARF2_EMIT_OFFSET ia64_dwarf2_emit_offset #define tc_check_label(l) ia64_check_label (l) +/* Record if an alignment frag should end with a stop bit. */ +#define TC_FRAG_TYPE int +#define TC_FRAG_INIT(FRAGP) do {(FRAGP)->tc_frag_data = 0;}while (0) + #define MAX_MEM_FOR_RS_ALIGN_CODE (15 + 16) #define WORKING_DOT_WORD /* don't do broken word processing for now */ |