aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-ia64.c59
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/ia64/ia64.exp1
-rw-r--r--gas/testsuite/gas/ia64/no-fit.l8
-rw-r--r--gas/testsuite/gas/ia64/no-fit.s33
6 files changed, 87 insertions, 26 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index f178fa1..9aa62bc 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,12 @@
2005-03-08 Jan Beulich <jbeulich@novell.com>
+ * config/tc-ia64.c (emit_one_bundle): Track last slot user insn was
+ emitted to. Add more precise diagnostics for non-fitting insns based
+ on that. Eliminate now superfluous special casing of MLX. Clear out
+ slot information when dropping an insn.
+
+2005-03-08 Jan Beulich <jbeulich@novell.com>
+
* config/tc-ia64.c (parse_section_name): Rename to...
(cross_section): In addition to separating the name from the rest of
the arguments, also carry out the operation.
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c
index 751488b..b959cdc 100644
--- a/gas/config/tc-ia64.c
+++ b/gas/config/tc-ia64.c
@@ -6459,7 +6459,7 @@ emit_one_bundle ()
bfd_vma insn[3] = { -1, -1, -1 };
struct ia64_opcode *idesc;
int end_of_insn_group = 0, user_template = -1;
- int n, i, j, first, curr;
+ int n, i, j, first, curr, last_slot;
unw_rec_list *ptr, *last_ptr, *end_ptr;
bfd_vma t0 = 0, t1 = 0;
struct label_fix *lfix;
@@ -6511,6 +6511,7 @@ emit_one_bundle ()
curr = first;
idesc = md.slot[curr].idesc;
end_of_insn_group = 0;
+ last_slot = -1;
for (i = 0; i < 3 && md.num_slots_in_use > 0; ++i)
{
/* If we have unwind records, we may need to update some now. */
@@ -6776,27 +6777,7 @@ emit_one_bundle ()
}
if (insn_unit != required_unit)
- {
- if (required_unit == IA64_UNIT_L
- && insn_unit == IA64_UNIT_I
- && !(idesc->flags & IA64_OPCODE_X_IN_MLX))
- {
- /* we got ourselves an MLX template but the current
- instruction isn't an X-unit, or an I-unit instruction
- that can go into the X slot of an MLX template. Duh. */
- if (md.num_slots_in_use >= NUM_SLOTS)
- {
- as_bad_where (md.slot[curr].src_file,
- md.slot[curr].src_line,
- "`%s' can't go in X slot of "
- "MLX template", idesc->name);
- /* drop this insn so we don't livelock: */
- --md.num_slots_in_use;
- }
- break;
- }
- continue; /* try next slot */
- }
+ continue; /* Try next slot. */
if (debug_type == DEBUG_DWARF2 || md.slot[curr].loc_directive_seen)
{
@@ -6830,6 +6811,7 @@ emit_one_bundle ()
++i;
}
--md.num_slots_in_use;
+ last_slot = i;
/* now is a good time to fix up the labels for this insn: */
for (lfix = md.slot[curr].label_fixups; lfix; lfix = lfix->next)
@@ -6874,10 +6856,35 @@ emit_one_bundle ()
{
if (md.num_slots_in_use > 0)
{
- as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
- "`%s' does not fit into %s template",
- idesc->name, ia64_templ_desc[template].name);
- --md.num_slots_in_use;
+ if (last_slot >= 2)
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "`%s' does not fit into bundle", idesc->name);
+ else if (last_slot < 0)
+ {
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "`%s' does not fit into %s template",
+ idesc->name, ia64_templ_desc[template].name);
+ /* Drop first insn so we don't livelock. */
+ --md.num_slots_in_use;
+ know (curr == first);
+ ia64_free_opcode (md.slot[curr].idesc);
+ memset (md.slot + curr, 0, sizeof (md.slot[curr]));
+ md.slot[curr].user_template = -1;
+ }
+ else
+ {
+ const char *where;
+
+ if (template == 2)
+ where = "X slot";
+ else if (last_slot == 0)
+ where = "slots 2 or 3";
+ else
+ where = "slot 3";
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "`%s' can't go in %s of %s template",
+ idesc->name, where, ia64_templ_desc[template].name);
+ }
}
else
as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 4f1d9f0..6ce90b0 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2005-03-08 Jan Beulich <jbeulich@novell.com>
+ * gas/ia64/no-fit.[ls]: New.
+ * gas/ia64/ia64.exp: Run new test.
+
+2005-03-08 Jan Beulich <jbeulich@novell.com>
+
* gas/ia64/xdata.[sd], gas/ia64/xdata-ilp32.d: New.
* gas/ia64/ia64.exp: Run new tests.
diff --git a/gas/testsuite/gas/ia64/ia64.exp b/gas/testsuite/gas/ia64/ia64.exp
index 9485fe4..cf384a4 100644
--- a/gas/testsuite/gas/ia64/ia64.exp
+++ b/gas/testsuite/gas/ia64/ia64.exp
@@ -76,6 +76,7 @@ if [istarget "ia64-*"] then {
run_dump_test "bundling"
run_list_test "label" ""
run_list_test "last" ""
+ run_list_test "no-fit" ""
run_list_test "pound" "-al"
run_list_test "proc" "-munwind-check=error"
run_list_test "slot2" ""
diff --git a/gas/testsuite/gas/ia64/no-fit.l b/gas/testsuite/gas/ia64/no-fit.l
new file mode 100644
index 0000000..1dec89c
--- /dev/null
+++ b/gas/testsuite/gas/ia64/no-fit.l
@@ -0,0 +1,8 @@
+.*: Assembler messages:
+.*:5: Error: .nop\.i.[[:space:]]+[^23]*[[:space:]]+MFB[[:space:]]+.*
+.*:8: Error: .nop\.f.[[:space:]]+[^23]*[[:space:]]+MLX[[:space:]]+.*
+.*:12: Error: .nop\.i.[[:space:]]+.*[[:space:]]+2[[:space:]]+.*[[:space:]]+3[[:space:]]+.*[[:space:]]+MFB[[:space:]]+.*
+.*:17: Error: .nop\.i.[[:space:]]+[^2]*[[:space:]]+3[[:space:]]+.*[[:space:]]+MFB[[:space:]]+.*
+.*:21: Error: .nop\.f.[[:space:]]+.*[[:space:]]+X[[:space:]]+.*[[:space:]]+MLX[[:space:]]+.*
+.*:27: Error: .nop.[[:space:]]+[^23M]*
+.*:32: Error: .nop.[[:space:]]+[^23M]*
diff --git a/gas/testsuite/gas/ia64/no-fit.s b/gas/testsuite/gas/ia64/no-fit.s
new file mode 100644
index 0000000..dc992a5
--- /dev/null
+++ b/gas/testsuite/gas/ia64/no-fit.s
@@ -0,0 +1,33 @@
+.explicit
+.text
+_start:
+{.mfb
+ nop.i 0
+}
+{.mlx
+ nop.f 0
+}
+{.mfb
+ nop.m 0
+ nop.i 0
+}
+{.mfb
+ nop.m 0
+ nop.f 0
+ nop.i 0
+}
+{.mlx
+ nop.m 0
+ nop.f 0
+}
+{.mfb
+ nop 0
+ nop 0
+ nop 0
+ nop 0
+}
+{.mlx
+ nop 0
+ nop 0
+ nop 0
+}