This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] ia64 bundling issues


Various inconsistencies were observable in manual bundling mode, mostly
resulting in errors where there shouldn't be any (and the Intel
assembler
accepting the same code) or errors not getting generated when they
should
be.
For example,

- when a bundle has less than 3 instructions and the last one is
required to
go into slot 2, there is no problem doing so
- when a label is in the middle of a bundle (past slot 0 and before
slot 2),
this is always an error, while a label before slot 0 or after slot 2 is
valid
- an MII bundle with only two (explicit) insns and a stop between them
is
valid

Built and tested on ia64-unknown-linux-gnu.

Jan

gas/
2005-01-24  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.

gas/testsuite/
2005-01-24  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.

---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/config/tc-ia64.c	2005-01-18
10:43:33.000000000 +0100
+++ 2005-01-24.08.40/gas/config/tc-ia64.c	2005-01-24
10:51:55.557354855 +0100
@@ -6145,8 +6145,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;
@@ -6241,13 +6240,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)
 	{
@@ -6280,10 +6291,18 @@ 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
+		      && (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;
@@ -6302,24 +6321,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
@@ -6347,12 +6358,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;
@@ -6513,7 +6529,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)
 	{
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/bundling.d	1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/bundling.d	2005-01-21
15:47:09.000000000 +0100
@@ -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;;
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/bundling.s	1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/bundling.s	2005-01-21
15:49:31.000000000 +0100
@@ -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
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/ia64.exp	2004-07-02
08:26:34.000000000 +0200
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/ia64.exp	2005-01-24
10:51:55.558331417 +0100
@@ -58,4 +58,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" ""
 }
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/label.l	1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/label.l	2005-01-21
15:52:42.000000000 +0100
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:11: Error: Label must be first in a bundle
+.*:18: Error: Label must be first in a bundle
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/label.s	1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/label.s	2005-01-20
11:37:08.000000000 +0100
@@ -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:
+}
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/last.l	1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/last.l	2005-01-21
15:55:05.000000000 +0100
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:4: Error: .* must be last in instruction group
+.*:10: Error: .* must be last in instruction group
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/last.s	1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/last.s	2005-01-21
16:00:49.000000000 +0100
@@ -0,0 +1,12 @@
+.explicit
+_start:
+{.mib
+	itc.d	r0
+}	;;
+{.mib
+	cover
+}	;;
+{.mbb
+	cover
+	nop	0
+}	;;
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/slot2.l	1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/slot2.l	2005-01-21
16:02:23.000000000 +0100
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:11: Error: .* must be last in bundle
+.*:16: Error: .* must be last in bundle
---
/home/jbeulich/src/binutils/mainline/2005-01-24.08.40/gas/testsuite/gas/ia64/slot2.s	1970-01-01
01:00:00.000000000 +0100
+++ 2005-01-24.08.40/gas/testsuite/gas/ia64/slot2.s	2005-01-21
16:00:27.000000000 +0100
@@ -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
+}	;;

Attachment: binutils-mainline-ia64-bundling.patch
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]