summaryrefslogtreecommitdiffstats
path: root/gcc/config
diff options
context:
space:
mode:
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2001-03-01 14:20:17 +0000
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>2001-03-01 14:20:17 +0000
commit91ef57b052f228bdcbd40f921baecc6d9cf067d6 (patch)
tree2384e38fa40b32ba6e07e3f4721b903d5f7d71ab /gcc/config
parenta253b899907be0ef54bfc610f914fa19c0b76e64 (diff)
downloadppe42-gcc-91ef57b052f228bdcbd40f921baecc6d9cf067d6.tar.gz
ppe42-gcc-91ef57b052f228bdcbd40f921baecc6d9cf067d6.zip
Emit NOPs in the assembly output.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@40156 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/ia64/ia64.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index bfe0d551dad..1b49a5cd60b 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -4788,6 +4788,8 @@ static void find_best_packet PARAMS ((int *, const struct ia64_packet **,
static int itanium_reorder PARAMS ((FILE *, rtx *, rtx *, int));
static void dump_current_packet PARAMS ((FILE *));
static void schedule_stop PARAMS ((FILE *));
+static rtx gen_nop_type PARAMS ((enum attr_type));
+static void ia64_emit_nops PARAMS ((void));
/* Map a bundle number to its pseudo-op. */
@@ -5998,6 +6000,99 @@ emit_predicate_relation_info ()
}
}
+/* Generate a NOP instruction of type T. We will never generate L type
+ nops. */
+
+static rtx
+gen_nop_type (t)
+ enum attr_type t;
+{
+ switch (t)
+ {
+ case TYPE_M:
+ return gen_nop_m ();
+ case TYPE_I:
+ return gen_nop_i ();
+ case TYPE_B:
+ return gen_nop_b ();
+ case TYPE_F:
+ return gen_nop_f ();
+ case TYPE_X:
+ return gen_nop_x ();
+ default:
+ abort ();
+ }
+}
+
+/* After the last scheduling pass, fill in NOPs. It's easier to do this
+ here than while scheduling. */
+
+static void
+ia64_emit_nops ()
+{
+ rtx insn;
+ const struct bundle *b = 0;
+ int bundle_pos = 0;
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ rtx pat;
+ enum attr_type t;
+ pat = INSN_P (insn) ? PATTERN (insn) : const0_rtx;
+ if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
+ continue;
+ if ((GET_CODE (pat) == UNSPEC && XINT (pat, 1) == 22)
+ || GET_CODE (insn) == CODE_LABEL)
+ {
+ if (b)
+ while (bundle_pos < 3)
+ {
+ emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
+ bundle_pos++;
+ }
+ if (GET_CODE (insn) != CODE_LABEL)
+ b = bundle + INTVAL (XVECEXP (pat, 0, 0));
+ else
+ b = 0;
+ bundle_pos = 0;
+ continue;
+ }
+ else if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == 2)
+ {
+ int t = INTVAL (XVECEXP (pat, 0, 0));
+ if (b)
+ while (bundle_pos < t)
+ {
+ emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
+ bundle_pos++;
+ }
+ continue;
+ }
+
+ if (bundle_pos == 3)
+ b = 0;
+
+ if (b && INSN_P (insn))
+ {
+ t = ia64_safe_type (insn);
+ if (t == TYPE_UNKNOWN)
+ continue;
+ while (bundle_pos < 3)
+ {
+ if (t == b->t[bundle_pos]
+ || (t == TYPE_A && (b->t[bundle_pos] == TYPE_M
+ || b->t[bundle_pos] == TYPE_I)))
+ break;
+
+ emit_insn_before (gen_nop_type (b->t[bundle_pos]), insn);
+ bundle_pos++;
+ }
+ if (bundle_pos < 3)
+ bundle_pos++;
+ }
+ }
+}
+
/* Perform machine dependent operations on the rtl chain INSNS. */
void
@@ -6022,6 +6117,7 @@ ia64_reorg (insns)
/* This relies on the NOTE_INSN_BASIC_BLOCK notes to be in the same
place as they were during scheduling. */
emit_insn_group_barriers (rtl_dump_file, insns);
+ ia64_emit_nops ();
}
else
emit_all_insn_group_barriers (rtl_dump_file, insns);
OpenPOWER on IntegriCloud