> 2017-11-17  Daniel Cederman  <ceder...@gaisler.com>
> 
>       * config/sparc/sparc.c (fpop_insn_p): New function.
>       (sparc_do_work_around_errata): Insert NOP instructions to
>       prevent sequences that could trigger the TN-0012 errata for
>       GR712RC.
>       (pass_work_around_errata::gate): Also test sparc_fix_gr712rc.
>       * config/sparc/sparc.md (fix_gr712rc): New attribute.
>       (in_branch_annul_delay): Prevent floating-point instructions
>       in delay slot of annulled integer branch.

OK for mainline and 7 branch modulo the following nits:

> +/* True if floating-point instruction.  */
> +
> +static int
> +fpop_insn_p (rtx_insn *insn)

'bool' instead of 'int'.  "True if INSN is a floating-point instruction."

> +{
> +  if ( GET_CODE (PATTERN (insn)) != SET)
> +    return false;

No space before GET_CODE.

>  /* We use a machine specific pass to enable workarounds for errata.
> 
>     We need to have the (essentially) final form of the insn stream in order
> @@ -970,11 +995,31 @@ sparc_do_work_around_errata (void)
>      {
>        bool insert_nop = false;
>        rtx set;
> +      rtx_insn *jump = 0;
> 
>        /* Look into the instruction in a delay slot.  */
>        if (NONJUMP_INSN_P (insn))
>       if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
> -       insn = seq->insn (1);
> +       {
> +         jump = seq->insn (0);
> +         insn = seq->insn (1);
> +       }

This should be changed into:

      rtx_insn jump;

      /* Look into the instruction in a delay slot.  */
      if (NONJUMP_INSN_P (insn)
          && (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
        {
          jump = seq->insn (0);
          insn = seq->insn (1);
        }
      else if (JUMP_P (insn))
        jump = insn
      else
        jump = NULL_RTX;

and the block below simplified accordingly.

> +      /* Place a NOP at the branch target of an integer branch if it is
> +      a floating-point operation or a floating-point branch.  */
> +      if (sparc_fix_gr712rc
> +       && (JUMP_P (insn) || jump)
> +       && get_attr_branch_type (jump ? jump : insn) == BRANCH_TYPE_ICC)
> +     {
> +       rtx_insn *target;
> +
> +       target = next_active_insn (JUMP_LABEL_AS_INSN (jump ? jump : insn));

          rtx_insn *target = next_active_insn (JUMP_LABEL_AS_INSN (jump));

>        /* Look for either of these two sequences:
> 
> @@ -1303,7 +1348,8 @@ public:
>    /* opt_pass methods: */
>    virtual bool gate (function *)
>      {
> -      return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst;
> +      return sparc_fix_at697f || sparc_fix_ut699 || sparc_fix_b2bst
> +     || sparc_fix_gr712rc;
>      }

"|| sparc_fix_gr712rc" lined up under sparc_fix_at697f.

> @@ -602,6 +615,10 @@
>  (define_delay (eq_attr "type" "branch")
>    [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay"
> "true")])
> 
> +(define_delay (and (eq_attr "type" "branch") (eq_attr "branch_type" "icc"))
> +  [(eq_attr "in_branch_delay" "true") (nil)
> +  (eq_attr "in_branch_annul_delay" "true")])
> +

I think that we'd better keep the various define_delay's mutually exclusive.

-- 
Eric Botcazou

Reply via email to