diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-03-01 14:20:17 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-03-01 14:20:17 +0000 |
commit | 91ef57b052f228bdcbd40f921baecc6d9cf067d6 (patch) | |
tree | 2384e38fa40b32ba6e07e3f4721b903d5f7d71ab | |
parent | a253b899907be0ef54bfc610f914fa19c0b76e64 (diff) | |
download | gcc-91ef57b052f228bdcbd40f921baecc6d9cf067d6.tar.gz |
Emit NOPs in the assembly output.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@40156 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.c | 96 |
2 files changed, 99 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ca9c9b1a43..c72d69ed0fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -2,6 +2,9 @@ * config/ia64/ia64.c (ia64_hard_regno_rename_ok): Disallow renaming from reg 4 if current_function_calls_setjmp. + (gen_nop_type): New function. + (ia64_emit_nops): New function. + (ia64_reorg): Call it. * reload1.c (eliminate_regs_in_insn): Restrict the special case code not to try to optimize adds with anything but a REG destination. 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); |