diff options
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/config/tc-ia64.c | 69 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/bundling.d | 14 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/bundling.s | 15 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/ia64.exp | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/label.l | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/label.s | 25 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/last.l | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/last.s | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/slot2.l | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/ia64/slot2.s | 18 |
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 +} ;; |