aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog11
-rw-r--r--gas/config/tc-ia64.c69
-rw-r--r--gas/testsuite/ChangeLog8
-rw-r--r--gas/testsuite/gas/ia64/bundling.d14
-rw-r--r--gas/testsuite/gas/ia64/bundling.s15
-rw-r--r--gas/testsuite/gas/ia64/ia64.exp5
-rw-r--r--gas/testsuite/gas/ia64/label.l3
-rw-r--r--gas/testsuite/gas/ia64/label.s25
-rw-r--r--gas/testsuite/gas/ia64/last.l3
-rw-r--r--gas/testsuite/gas/ia64/last.s12
-rw-r--r--gas/testsuite/gas/ia64/slot2.l3
-rw-r--r--gas/testsuite/gas/ia64/slot2.s18
12 files changed, 160 insertions, 26 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index c109bd6..73079cf 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,16 @@
2005-01-31 Jan Beulich <jbeulich@novell.com>
+ * config/tc-ia64.c (emit_one_bundle): Snapshot manual bundling state
+ before actually using it. Don't generate an error in manual bundling
+ mode when looking at an insn requiring slot 2 but not yet at slot 2.
+ Don't generate an error in manual bundling mode when looking at an
+ insn required to be last in its group but the required slot hasn't
+ been reached, yet. Allow conversion from MII to MI;I for bundle
+ consisting of only 2 insns with the stop between them. Suppress
+ various meaningless errors resulting from detecting earlier ones.
+
+2005-01-31 Jan Beulich <jbeulich@novell.com>
+
* config/tc-ia64.c (parse_operands): Also handle alloc without first
input being ar.pfs.
diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c
index 6415647..51bf2ed 100644
--- a/gas/config/tc-ia64.c
+++ b/gas/config/tc-ia64.c
@@ -6157,8 +6157,7 @@ build_insn (slot, insnp)
static void
emit_one_bundle ()
{
- unsigned int manual_bundling_on = 0, manual_bundling_off = 0;
- unsigned int manual_bundling = 0;
+ int manual_bundling_off = 0, manual_bundling = 0;
enum ia64_unit required_unit, insn_unit = 0;
enum ia64_insn_type type[3], insn_type;
unsigned int template, orig_template;
@@ -6253,13 +6252,25 @@ emit_one_bundle ()
}
}
- if (idesc->flags & IA64_OPCODE_SLOT2)
+ manual_bundling_off = md.slot[curr].manual_bundling_off;
+ if (md.slot[curr].manual_bundling_on)
{
- if (manual_bundling && i != 2)
- as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
- "`%s' must be last in bundle", idesc->name);
+ if (curr == first)
+ manual_bundling = 1;
else
- i = 2;
+ break; /* Need to start a new bundle. */
+ }
+
+ if (idesc->flags & IA64_OPCODE_SLOT2)
+ {
+ if (manual_bundling && !manual_bundling_off)
+ {
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "`%s' must be last in bundle", idesc->name);
+ if (i < 2)
+ manual_bundling = -1; /* Suppress meaningless post-loop errors. */
+ }
+ i = 2;
}
if (idesc->flags & IA64_OPCODE_LAST)
{
@@ -6292,10 +6303,19 @@ emit_one_bundle ()
required_slot = i;
break;
}
- if (manual_bundling && i != required_slot)
- as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
- "`%s' must be last in instruction group",
- idesc->name);
+ if (manual_bundling
+ && (i > required_slot
+ || (required_slot == 2 && !manual_bundling_off)
+ || (user_template >= 0
+ /* Changing from MMI to M;MI is OK. */
+ && (template ^ required_template) > 1)))
+ {
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ "`%s' must be last in instruction group",
+ idesc->name);
+ if (i < 2 && required_slot == 2 && !manual_bundling_off)
+ manual_bundling = -1; /* Suppress meaningless post-loop errors. */
+ }
if (required_slot < i)
/* Can't fit this instruction. */
break;
@@ -6314,24 +6334,16 @@ emit_one_bundle ()
}
if (curr != first && md.slot[curr].label_fixups)
{
- if (manual_bundling_on)
- as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
+ if (manual_bundling)
+ {
+ as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
"Label must be first in a bundle");
+ manual_bundling = -1; /* Suppress meaningless post-loop errors. */
+ }
/* This insn must go into the first slot of a bundle. */
break;
}
- manual_bundling_on = md.slot[curr].manual_bundling_on;
- manual_bundling_off = md.slot[curr].manual_bundling_off;
-
- if (manual_bundling_on)
- {
- if (curr == first)
- manual_bundling = 1;
- else
- break; /* need to start a new bundle */
- }
-
if (end_of_insn_group && md.num_slots_in_use >= 1)
{
/* We need an instruction group boundary in the middle of a
@@ -6359,12 +6371,17 @@ emit_one_bundle ()
reason we have to check for this is that otherwise we
may end up generating "MI;;I M.." which has the deadly
effect that the second M instruction is no longer the
- first in the bundle! --davidm 99/12/16 */
+ first in the group! --davidm 99/12/16 */
&& (idesc->flags & IA64_OPCODE_FIRST) == 0)
{
template = 1;
end_of_insn_group = 0;
}
+ else if (i == 1
+ && user_template == 0
+ && !(idesc->flags & IA64_OPCODE_FIRST))
+ /* Use the next slot. */
+ continue;
else if (curr != first)
/* can't fit this insn */
break;
@@ -6542,7 +6559,7 @@ emit_one_bundle ()
curr = (curr + 1) % NUM_SLOTS;
idesc = md.slot[curr].idesc;
}
- if (manual_bundling)
+ if (manual_bundling > 0)
{
if (md.num_slots_in_use > 0)
{
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 004ed44..bfc1de6 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,5 +1,13 @@
2005-01-31 Jan Beulich <jbeulich@novell.com>
+ * gas/ia64/bundling.[ds]: New.
+ * gas/ia64/label.[ls]: New.
+ * gas/ia64/last.[ls]: New.
+ * gas/ia64/slot2.[ls]: New.
+ * gas/ia64/ia64.exp: Run new tests.
+
+2005-01-31 Jan Beulich <jbeulich@novell.com>
+
* gas/ia64/pseudo.[ds]: New.
* gas/ia64/ia64.exp: Run new test.
diff --git a/gas/testsuite/gas/ia64/bundling.d b/gas/testsuite/gas/ia64/bundling.d
new file mode 100644
index 0000000..2ddece1
--- /dev/null
+++ b/gas/testsuite/gas/ia64/bundling.d
@@ -0,0 +1,14 @@
+# objdump: -d
+# name: ia64 explicit bundling
+
+.*: +file format .*
+
+Disassembly of section \.text:
+
+0+0 <_start>:
+[[:space:]]*[[:xdigit:]]*:[[:space:][:xdigit:]]+\[MII] nop\.m 0x0
+[[:space:]]*[[:xdigit:]]*:[[:space:][:xdigit:]]+nop\.i 0x0;;
+[[:space:]]*[[:xdigit:]]*:[[:space:][:xdigit:]]+mov\.i r31=ar\.lc;;
+[[:space:]]*[[:xdigit:]]*:[[:space:][:xdigit:]]+\[..B] nop\.. 0x0
+[[:space:]]*[[:xdigit:]]*:[[:space:][:xdigit:]]+nop\.. 0x0
+[[:space:]]*[[:xdigit:]]*:[[:space:][:xdigit:]]+br\.ret\.sptk\.few b0;;
diff --git a/gas/testsuite/gas/ia64/bundling.s b/gas/testsuite/gas/ia64/bundling.s
new file mode 100644
index 0000000..23a987d
--- /dev/null
+++ b/gas/testsuite/gas/ia64/bundling.s
@@ -0,0 +1,15 @@
+.explicit
+.proc _start
+_start:
+ .prologue
+{.mii
+ nop.m 0
+ ;;
+ .save ar.lc, r31
+ mov r31 = ar.lc
+} ;;
+ .body
+{.mfb
+ br.ret.sptk rp
+} ;;
+.endp _start
diff --git a/gas/testsuite/gas/ia64/ia64.exp b/gas/testsuite/gas/ia64/ia64.exp
index 8419410..57cea89 100644
--- a/gas/testsuite/gas/ia64/ia64.exp
+++ b/gas/testsuite/gas/ia64/ia64.exp
@@ -61,4 +61,9 @@ if [istarget "ia64-*"] then {
run_dump_test "alias"
run_dump_test "group-1"
}
+
+ run_dump_test "bundling"
+ run_list_test "label" ""
+ run_list_test "last" ""
+ run_list_test "slot2" ""
}
diff --git a/gas/testsuite/gas/ia64/label.l b/gas/testsuite/gas/ia64/label.l
new file mode 100644
index 0000000..288fce5
--- /dev/null
+++ b/gas/testsuite/gas/ia64/label.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:11: Error: Label must be first in a bundle
+.*:18: Error: Label must be first in a bundle
diff --git a/gas/testsuite/gas/ia64/label.s b/gas/testsuite/gas/ia64/label.s
new file mode 100644
index 0000000..6eff4c9
--- /dev/null
+++ b/gas/testsuite/gas/ia64/label.s
@@ -0,0 +1,25 @@
+start:
+{.mii
+label0:
+ nop 0
+ nop 0
+ nop 0
+}
+{.mii
+ nop 0
+label1:
+ nop 0
+ nop 0
+}
+{.mii
+ nop 0
+ nop 0
+label2:
+ nop 0
+}
+{.mii
+ nop 0
+ nop 0
+ nop 0
+label3:
+}
diff --git a/gas/testsuite/gas/ia64/last.l b/gas/testsuite/gas/ia64/last.l
new file mode 100644
index 0000000..946b4d2
--- /dev/null
+++ b/gas/testsuite/gas/ia64/last.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:4: Error: .* must be last in instruction group
+.*:10: Error: .* must be last in instruction group
diff --git a/gas/testsuite/gas/ia64/last.s b/gas/testsuite/gas/ia64/last.s
new file mode 100644
index 0000000..d7b0de0
--- /dev/null
+++ b/gas/testsuite/gas/ia64/last.s
@@ -0,0 +1,12 @@
+.explicit
+_start:
+{.mib
+ itc.d r0
+} ;;
+{.mib
+ cover
+} ;;
+{.mbb
+ cover
+ nop 0
+} ;;
diff --git a/gas/testsuite/gas/ia64/slot2.l b/gas/testsuite/gas/ia64/slot2.l
new file mode 100644
index 0000000..f52299a
--- /dev/null
+++ b/gas/testsuite/gas/ia64/slot2.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:11: Error: .* must be last in bundle
+.*:16: Error: .* must be last in bundle
diff --git a/gas/testsuite/gas/ia64/slot2.s b/gas/testsuite/gas/ia64/slot2.s
new file mode 100644
index 0000000..030db8e
--- /dev/null
+++ b/gas/testsuite/gas/ia64/slot2.s
@@ -0,0 +1,18 @@
+.explicit
+_start:
+{.mib
+ br.cloop.sptk start
+} ;;
+{.mib
+ nop 0
+ br.cloop.sptk start
+} ;;
+{.mbb
+ br.cloop.sptk start
+ nop 0
+} ;;
+{.mbb
+ nop 0
+ br.cloop.sptk start
+ nop 0
+} ;;