aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJim Wilson <wilson@tuliptree.org>2004-02-04 04:40:24 +0000
committerJim Wilson <wilson@tuliptree.org>2004-02-04 04:40:24 +0000
commitd6e78c110540e7a4629363ccf4aa04cc71148a26 (patch)
treed34327f689b0a16170c199d4662d64deb16b85fa /gas
parentaaa08ee402b22eb5971890970a8384753345826e (diff)
downloadgdb-d6e78c110540e7a4629363ccf4aa04cc71148a26.zip
gdb-d6e78c110540e7a4629363ccf4aa04cc71148a26.tar.gz
gdb-d6e78c110540e7a4629363ccf4aa04cc71148a26.tar.bz2
Fix testcase from David Mosberger.
* config/tc-ia64.c (ia64_convert_frag): Call md_number_to_chars to fill padding bytes with zeroes. (emit_one_bundle): New locals last_ptr, end_ptr. Rewrite code that sets unwind_record slot_number and slot_frag fields.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-ia64.c76
2 files changed, 61 insertions, 22 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index b4edbbc..f589373 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2004-02-03 James E Wilson <wilson@specifixinc.com>
+
+ * config/tc-ia64.c (ia64_convert_frag): Call md_number_to_chars to
+ fill padding bytes with zeroes.
+ (emit_one_bundle): New locals last_ptr, end_ptr. Rewrite code that
+ sets unwind_record slot_number and slot_frag fields.
+
2004-02-02 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
* config/tc-mips.c (add_got_offset_hilo): New function.
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c
index a0fdc64..63eb5c0 100644
--- a/gas/config/tc-ia64.c
+++ b/gas/config/tc-ia64.c
@@ -2911,6 +2911,12 @@ ia64_convert_frag (fragS *frag)
/* Skip the header. */
vbyte_mem_ptr = frag->fr_literal + 8;
process_unw_records (list, output_vbyte_mem);
+
+ /* Fill the padding bytes with zeros. */
+ if (pad != 0)
+ md_number_to_chars (frag->fr_literal + len + 8 - md.pointer_size + pad, 0,
+ md.pointer_size - pad);
+
frag->fr_fix += size;
frag->fr_type = rs_fill;
frag->fr_var = 0;
@@ -6032,7 +6038,7 @@ emit_one_bundle ()
struct ia64_opcode *idesc;
int end_of_insn_group = 0, user_template = -1;
int n, i, j, first, curr;
- unw_rec_list *ptr;
+ unw_rec_list *ptr, *last_ptr, *end_ptr;
bfd_vma t0 = 0, t1 = 0;
struct label_fix *lfix;
struct insn_fix *ifix;
@@ -6076,18 +6082,39 @@ emit_one_bundle ()
end_of_insn_group = 0;
for (i = 0; i < 3 && md.num_slots_in_use > 0; ++i)
{
- /* Set the slot number for prologue/body records now as those
- refer to the current point, not the point after the
- instruction has been issued: */
- /* Don't try to delete prologue/body records here, as that will cause
- them to also be deleted from the master list of unwind records. */
- for (ptr = md.slot[curr].unwind_record; ptr; ptr = ptr->next)
- if (ptr->r.type == prologue || ptr->r.type == prologue_gr
- || ptr->r.type == body)
- {
- ptr->slot_number = (unsigned long) f + i;
- ptr->slot_frag = frag_now;
- }
+ /* If we have unwind records, we may need to update some now. */
+ ptr = md.slot[curr].unwind_record;
+ if (ptr)
+ {
+ /* Find the last prologue/body record in the list for the current
+ insn, and set the slot number for all records up to that point.
+ This needs to be done now, because prologue/body records refer to
+ the current point, not the point after the instruction has been
+ issued. This matters because there may have been nops emitted
+ meanwhile. Any non-prologue non-body record followed by a
+ prologue/body record must also refer to the current point. */
+ last_ptr = NULL;
+ end_ptr = md.slot[(curr + 1) % NUM_SLOTS].unwind_record;
+ for (; ptr != end_ptr; ptr = ptr->next)
+ if (ptr->r.type == prologue || ptr->r.type == prologue_gr
+ || ptr->r.type == body)
+ last_ptr = ptr;
+ if (last_ptr)
+ {
+ /* Make last_ptr point one after the last prologue/body
+ record. */
+ last_ptr = last_ptr->next;
+ for (ptr = md.slot[curr].unwind_record; ptr != last_ptr;
+ ptr = ptr->next)
+ {
+ ptr->slot_number = (unsigned long) f + i;
+ ptr->slot_frag = frag_now;
+ }
+ /* Remove the initialized records, so that we won't accidentally
+ update them again if we insert a nop and continue. */
+ md.slot[curr].unwind_record = last_ptr;
+ }
+ }
if (idesc->flags & IA64_OPCODE_SLOT2)
{
@@ -6292,15 +6319,20 @@ emit_one_bundle ()
build_insn (md.slot + curr, insn + i);
- /* Set slot counts for non prologue/body unwind records. */
- for (ptr = md.slot[curr].unwind_record; ptr; ptr = ptr->next)
- if (ptr->r.type != prologue && ptr->r.type != prologue_gr
- && ptr->r.type != body)
- {
- ptr->slot_number = (unsigned long) f + i;
- ptr->slot_frag = frag_now;
- }
- md.slot[curr].unwind_record = NULL;
+ ptr = md.slot[curr].unwind_record;
+ if (ptr)
+ {
+ /* Set slot numbers for all remaining unwind records belonging to the
+ current insn. There can not be any prologue/body unwind records
+ here. */
+ end_ptr = md.slot[(curr + 1) % NUM_SLOTS].unwind_record;
+ for (; ptr != end_ptr; ptr = ptr->next)
+ {
+ ptr->slot_number = (unsigned long) f + i;
+ ptr->slot_frag = frag_now;
+ }
+ md.slot[curr].unwind_record = NULL;
+ }
if (required_unit == IA64_UNIT_L)
{