* Claudiu Zissulescu <claz...@gmail.com> [2018-11-12 13:29:33 +0200]:

> From: claziss <claz...@synopsys.com>
> 
> Hi Andrew,
> 
> This is a patch which fixes and sets LRA by default.
> 
> OK to apply?
> Claudiu
> 
>  **** Commit message ****
> 
> LP_COUNT register cannot be freely allocated by the compiler as it
> size, and/or content may change depending on the ARC hardware
> configuration. Thus, make this register fixed.
> 
> Remove register classes and unused constraint letters.
> 
> Cleanup the implementation of conditional_register_usage hook by using
> macros instead of magic constants and removing all references to
> reg_class_contents which are bringing so much grief when lra is enabled.
> 
> gcc/
> xxxx-xx-xx  Claudiu Zissulescu  <claz...@synopsys.com>
> 
>       * config/arc/arc.h (reg_class): Reorder registers classes, remove
>       unused register classes.
>       (REG_CLASS_NAMES): Likewise.
>       (REG_CLASS_CONTENTS): Likewise.
>       (FIXED_REGISTERS): Make lp_count fixed.
>       (BASE_REG_CLASS): Remove ACC16_BASE_REGS reference.
>       (PROGRAM_COUNTER_REGNO): Remove.
>       * config/arc/arc.c (arc_conditional_register_usage): Remove unused
>       register classes, use constants for register numbers, remove
>       reg_class_contents references.
>       (arc_process_double_reg_moves): Add asserts.
>       (arc_secondary_reload): Remove LPCOUNT_REG reference, use
>       lra_in_progress predicate.
>       (arc_init_reg_tables): Remove unused register classes.
>       (arc_register_move_cost): Likewise.
>       (arc_preferred_reload_class): Likewise.
>       (hwloop_optimize): Update rtx patterns involving lp_count
>       register.
>       (arc_return_address_register): Rename ILINK1, INLINK2 regnums
>       macros.
>       * config/arc/constraints.md ("c"): Choose between GENERAL_REGS and
>       CHEAP_CORE_REGS.  Former one will be used for LRA.
>       ("Rac"): Choose between GENERAL_REGS and ALL_CORE_REGS.  Former
>       one will be used for LRA.
>       ("w"): Choose between GENERAL_REGS and WRITABLE_CORE_REGS.  Former
>       one will be used for LRA.
>       ("W"): Choose between GENERAL_REGS and MPY_WRITABLE_CORE_REGS.
>       Former one will be used for LRA.
>       ("f"): Delete constraint.
>       ("k"): Likewise.
>       ("e"): Likewise.

The entries below this are for arc.md, but you're missing the filename
in the ChangeLog format.

>       (movqi_insn): Remove unsed lp_count constraints.
>       (movhi_insn): Likewise.
>       (movsi_insn): Update pattern.
>       (arc_lp): Likewise.
>       (dbnz): Likewise.
>       ("l"): Change it from register constraint to constraint.
>       (stack_tie): Remove 'b' constraint letter.
>       (R4_REG): Define.
>       (R9_REG, R15_REG, R16_REG, R25_REG): Likewise.
>       (R32_REG, R40_REG, R41_REG, R42_REG, R43_REG, R44_REG): Likewise.
>       (R57_REG, R59_REG, PCL_REG): Likewise.
>       (ILINK1_REGNUM): Renamed to ILINK1_REG.
>       (ILINK2_REGNUM): Renamed to ILINK2_REG.
>       (Rgp): Remove.
>       (SP_REGS): Likewise.
>       (Rcw): Remove unused reg classes.
>       * config/arc/predicates.md (dest_reg_operand): Just default on
>       register_operand predicate.
>       (mpy_dest_reg_operand): Likewise.
>       (move_dest_operand): Use macros instead of constants.

I'm basically happy with this.  There's a few formatting issues as we
saw in previous patches - tabs instead of whitespace in comments and
single whitespace instead of two at the end of a sentence.  But with
that fixed (and the doc fix Eric suggested) I'm happy.

Thanks,
Andrew


> ---
>  gcc/config/arc/arc.c          | 331 +++++++++++++---------------------
>  gcc/config/arc/arc.h          | 106 ++++-------
>  gcc/config/arc/arc.md         |  57 ++++--
>  gcc/config/arc/arc.opt        |   7 +-
>  gcc/config/arc/constraints.md |  45 ++---
>  gcc/config/arc/predicates.md  |  28 +--
>  6 files changed, 222 insertions(+), 352 deletions(-)
> 
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 75c2384eede..6802ca66554 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -734,11 +734,6 @@ arc_secondary_reload (bool in_p,
>    if (cl == DOUBLE_REGS)
>      return GENERAL_REGS;
>  
> -  /* The loop counter register can be stored, but not loaded directly.  */
> -  if ((cl == LPCOUNT_REG || cl == WRITABLE_CORE_REGS)
> -      && in_p && MEM_P (x))
> -    return GENERAL_REGS;
> -
>   /* If we have a subreg (reg), where reg is a pseudo (that will end in
>      a memory location), then we may need a scratch register to handle
>      the fp/sp+largeoffset address.  */
> @@ -756,8 +751,9 @@ arc_secondary_reload (bool in_p,
>         if (regno != -1)
>           return NO_REGS;
>  
> -       /* It is a pseudo that ends in a stack location.  */
> -       if (reg_equiv_mem (REGNO (x)))
> +       /* It is a pseudo that ends in a stack location.  This
> +          procedure only works with the old reload step.  */
> +       if (reg_equiv_mem (REGNO (x)) && !lra_in_progress)
>           {
>             /* Get the equivalent address and check the range of the
>                offset.  */
> @@ -1659,8 +1655,6 @@ enum reg_class 
> arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
>  enum reg_class
>  arc_preferred_reload_class (rtx, enum reg_class cl)
>  {
> -  if ((cl) == CHEAP_CORE_REGS  || (cl) == WRITABLE_CORE_REGS)
> -    return GENERAL_REGS;
>    return cl;
>  }
>  
> @@ -1758,25 +1752,21 @@ arc_conditional_register_usage (void)
>        strcpy (rname29, "ilink");
>        strcpy (rname30, "r30");
>  
> -      if (!TEST_HARD_REG_BIT (overrideregs, 30))
> +      if (!TEST_HARD_REG_BIT (overrideregs, R30_REG))
>       {
>         /* No user interference.  Set the r30 to be used by the
>            compiler.  */
> -       call_used_regs[30] = 1;
> -       fixed_regs[30] = 0;
> +       call_used_regs[R30_REG] = 1;
> +       fixed_regs[R30_REG] = 0;
>  
> -       arc_regno_reg_class[30] = WRITABLE_CORE_REGS;
> -       SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], 30);
> -       SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], 30);
> -       SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], 30);
> -       SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], 30);
> +       arc_regno_reg_class[R30_REG] = GENERAL_REGS;
>       }
>     }
>  
>    if (TARGET_MUL64_SET)
>      {
> -      fix_start = 57;
> -      fix_end = 59;
> +      fix_start = R57_REG;
> +      fix_end = R59_REG;
>  
>        /* We don't provide a name for mmed.  In rtl / assembly resource lists,
>        you are supposed to refer to it as mlo & mhi, e.g
> @@ -1799,8 +1789,8 @@ arc_conditional_register_usage (void)
>  
>    if (TARGET_MULMAC_32BY16_SET)
>      {
> -      fix_start = 56;
> -      fix_end = fix_end > 57 ? fix_end : 57;
> +      fix_start = MUL32x16_REG;
> +      fix_end = fix_end > R57_REG ? fix_end : R57_REG;
>        strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2");
>        strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1");
>      }
> @@ -1862,130 +1852,59 @@ arc_conditional_register_usage (void)
>    /* Reduced configuration: don't use r4-r9, r16-r25.  */
>    if (TARGET_RF16)
>      {
> -      for (i = 4; i <= 9; i++)
> -     {
> -       fixed_regs[i] = call_used_regs[i] = 1;
> -     }
> -      for (i = 16; i <= 25; i++)
> -     {
> -       fixed_regs[i] = call_used_regs[i] = 1;
> -     }
> -    }
> -
> -  for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
> -    if (!call_used_regs[regno])
> -      CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
> -  for (regno = 32; regno < 60; regno++)
> -    if (!fixed_regs[regno])
> -      SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], regno);
> -  if (!TARGET_ARC600_FAMILY)
> -    {
> -      for (regno = 32; regno <= 60; regno++)
> -     CLEAR_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], regno);
> -
> -      /* If they have used -ffixed-lp_count, make sure it takes
> -      effect.  */
> -      if (fixed_regs[LP_COUNT])
> -     {
> -       CLEAR_HARD_REG_BIT (reg_class_contents[LPCOUNT_REG], LP_COUNT);
> -       CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT);
> -       CLEAR_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], LP_COUNT);
> -
> -       /* Instead of taking out SF_MODE like below, forbid it outright.  */
> -       arc_hard_regno_modes[60] = 0;
> -     }
> -      else
> -     arc_hard_regno_modes[60] = 1 << (int) S_MODE;
> +      for (i = R4_REG; i <= R9_REG; i++)
> +     fixed_regs[i] = call_used_regs[i] = 1;
> +      for (i = R16_REG; i <= R25_REG; i++)
> +     fixed_regs[i] = call_used_regs[i] = 1;
>      }
>  
>    /* ARCHS has 64-bit data-path which makes use of the even-odd paired
>       registers.  */
>    if (TARGET_HS)
> -    {
> -      for (regno = 1; regno < 32; regno +=2)
> -     {
> -       arc_hard_regno_modes[regno] = S_MODES;
> -     }
> -    }
> +    for (regno = R1_REG; regno < R32_REG; regno +=2)
> +      arc_hard_regno_modes[regno] = S_MODES;
>  
>    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
> -    {
> -      if (i < 29)
> -     {
> -       if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
> -           && ((i <= 3) || ((i >= 12) && (i <= 15))))
> -         arc_regno_reg_class[i] = ARCOMPACT16_REGS;
> -       else
> -         arc_regno_reg_class[i] = GENERAL_REGS;
> -     }
> -      else if (i < 60)
> -     arc_regno_reg_class[i]
> -       = (fixed_regs[i]
> -          ? (TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i)
> -             ? CHEAP_CORE_REGS : ALL_CORE_REGS)
> -          : (((!TARGET_ARC600_FAMILY)
> -              && TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i))
> -             ? CHEAP_CORE_REGS : WRITABLE_CORE_REGS));
> -      else
> -     arc_regno_reg_class[i] = NO_REGS;
> -    }
> -
> -  /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
> -     has not been activated.  */
> -  if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
> -    CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
> -  if (!TARGET_Q_CLASS)
> -    CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
> -
> -  gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
> +    if (i < ILINK1_REG)
> +      {
> +     if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
> +         && ((i <= R3_REG) || ((i >= R12_REG) && (i <= R15_REG))))
> +       arc_regno_reg_class[i] = ARCOMPACT16_REGS;
> +     else
> +       arc_regno_reg_class[i] = GENERAL_REGS;
> +      }
> +    else if (i < LP_COUNT)
> +      arc_regno_reg_class[i] = GENERAL_REGS;
> +    else
> +      arc_regno_reg_class[i] = NO_REGS;
>  
>    /* Handle Special Registers.  */
> -  arc_regno_reg_class[29] = LINK_REGS; /* ilink1 register.  */
> -  if (!TARGET_V2)
> -    arc_regno_reg_class[30] = LINK_REGS; /* ilink2 register.  */
> -  arc_regno_reg_class[31] = LINK_REGS; /* blink register.  */
> -  arc_regno_reg_class[60] = LPCOUNT_REG;
> -  arc_regno_reg_class[61] = NO_REGS;      /* CC_REG: must be NO_REGS.  */
> +  arc_regno_reg_class[CC_REG] = NO_REGS;      /* CC_REG: must be NO_REGS.  */
>    arc_regno_reg_class[62] = GENERAL_REGS;
>  
>    if (TARGET_DPFP)
> -    {
> -      for (i = 40; i < 44; ++i)
> -     {
> -       arc_regno_reg_class[i] = DOUBLE_REGS;
> -
> -       /* Unless they want us to do 'mov d1, 0x00000000' make sure
> -          no attempt is made to use such a register as a destination
> -          operand in *movdf_insn.  */
> -       if (!TARGET_ARGONAUT_SET)
> -         {
> -         /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
> -            interpreted to mean they can use D1 or D2 in their insn.  */
> -         CLEAR_HARD_REG_BIT(reg_class_contents[CHEAP_CORE_REGS       ], i);
> -         CLEAR_HARD_REG_BIT(reg_class_contents[ALL_CORE_REGS         ], i);
> -         CLEAR_HARD_REG_BIT(reg_class_contents[WRITABLE_CORE_REGS    ], i);
> -         CLEAR_HARD_REG_BIT(reg_class_contents[MPY_WRITABLE_CORE_REGS], i);
> -         }
> -     }
> -    }
> +    for (i = R40_REG; i < R44_REG; ++i)
> +      {
> +     arc_regno_reg_class[i] = DOUBLE_REGS;
> +     if (!TARGET_ARGONAUT_SET)
> +       CLEAR_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i);
> +      }
>    else
>      {
> -      /* Disable all DOUBLE_REGISTER settings,
> -      if not generating DPFP code.  */
> -      arc_regno_reg_class[40] = ALL_REGS;
> -      arc_regno_reg_class[41] = ALL_REGS;
> -      arc_regno_reg_class[42] = ALL_REGS;
> -      arc_regno_reg_class[43] = ALL_REGS;
> +      /* Disable all DOUBLE_REGISTER settings, if not generating DPFP
> +      code.  */
> +      arc_regno_reg_class[R40_REG] = ALL_REGS;
> +      arc_regno_reg_class[R41_REG] = ALL_REGS;
> +      arc_regno_reg_class[R42_REG] = ALL_REGS;
> +      arc_regno_reg_class[R43_REG] = ALL_REGS;
>  
> -      fixed_regs[40] = 1;
> -      fixed_regs[41] = 1;
> -      fixed_regs[42] = 1;
> -      fixed_regs[43] = 1;
> +      fixed_regs[R40_REG] = 1;
> +      fixed_regs[R41_REG] = 1;
> +      fixed_regs[R42_REG] = 1;
> +      fixed_regs[R43_REG] = 1;
>  
> -      arc_hard_regno_modes[40] = 0;
> -      arc_hard_regno_modes[42] = 0;
> -
> -      CLEAR_HARD_REG_SET(reg_class_contents [DOUBLE_REGS]);
> +      arc_hard_regno_modes[R40_REG] = 0;
> +      arc_hard_regno_modes[R42_REG] = 0;
>      }
>  
>    if (TARGET_SIMD_SET)
> @@ -2007,23 +1926,15 @@ arc_conditional_register_usage (void)
>      }
>  
>    /* pc : r63 */
> -  arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS;
> +  arc_regno_reg_class[PCL_REG] = NO_REGS;
>  
>    /*ARCV2 Accumulator.  */
>    if ((TARGET_V2
>         && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
>        || TARGET_PLUS_DMPY)
>    {
> -    arc_regno_reg_class[ACCL_REGNO] = WRITABLE_CORE_REGS;
> -    arc_regno_reg_class[ACCH_REGNO] = WRITABLE_CORE_REGS;
> -    SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCL_REGNO);
> -    SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCH_REGNO);
> -    SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCL_REGNO);
> -    SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCH_REGNO);
> -    SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCL_REGNO);
> -    SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCH_REGNO);
> -    SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], 
> ACCL_REGNO);
> -    SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], 
> ACCH_REGNO);
> +    arc_regno_reg_class[ACCL_REGNO] = GENERAL_REGS;
> +    arc_regno_reg_class[ACCH_REGNO] = GENERAL_REGS;
>  
>      /* Allow the compiler to freely use them.  */
>      if (!TEST_HARD_REG_BIT (overrideregs, ACCL_REGNO))
> @@ -7798,6 +7709,25 @@ hwloop_fail (hwloop_info loop)
>    delete_insn (loop->loop_end);
>  }
>  
> +/* Return the next insn after INSN that is not a NOTE, but stop the
> +   search before we enter another basic block.  This routine does not
> +   look inside SEQUENCEs.  */
> +
> +static rtx_insn *
> +next_nonnote_insn_bb (rtx_insn *insn)
> +{
> +  while (insn)
> +    {
> +      insn = NEXT_INSN (insn);
> +      if (insn == 0 || !NOTE_P (insn))
> +     break;
> +      if (NOTE_INSN_BASIC_BLOCK_P (insn))
> +     return NULL;
> +    }
> +
> +  return insn;
> +}
> +
>  /* Optimize LOOP.  */
>  
>  static bool
> @@ -7815,41 +7745,41 @@ hwloop_optimize (hwloop_info loop)
>    if (loop->depth > 1)
>      {
>        if (dump_file)
> -        fprintf (dump_file, ";; loop %d is not innermost\n",
> -                 loop->loop_no);
> +     fprintf (dump_file, ";; loop %d is not innermost\n",
> +              loop->loop_no);
>        return false;
>      }
>  
>    if (!loop->incoming_dest)
>      {
>        if (dump_file)
> -        fprintf (dump_file, ";; loop %d has more than one entry\n",
> -                 loop->loop_no);
> +     fprintf (dump_file, ";; loop %d has more than one entry\n",
> +              loop->loop_no);
>        return false;
>      }
>  
>    if (loop->incoming_dest != loop->head)
>      {
>        if (dump_file)
> -        fprintf (dump_file, ";; loop %d is not entered from head\n",
> -                 loop->loop_no);
> +     fprintf (dump_file, ";; loop %d is not entered from head\n",
> +              loop->loop_no);
>        return false;
>      }
>  
>    if (loop->has_call || loop->has_asm)
>      {
>        if (dump_file)
> -        fprintf (dump_file, ";; loop %d has invalid insn\n",
> -                 loop->loop_no);
> +     fprintf (dump_file, ";; loop %d has invalid insn\n",
> +              loop->loop_no);
>        return false;
>      }
>  
> -  /* Scan all the blocks to make sure they don't use iter_reg.  */
> +  /* Scan all the blocks to make sure they don't use iter_reg.       */
>    if (loop->iter_reg_used || loop->iter_reg_used_outside)
>      {
>        if (dump_file)
> -        fprintf (dump_file, ";; loop %d uses iterator\n",
> -                 loop->loop_no);
> +     fprintf (dump_file, ";; loop %d uses iterator\n",
> +              loop->loop_no);
>        return false;
>      }
>  
> @@ -7863,8 +7793,8 @@ hwloop_optimize (hwloop_info loop)
>    if (!insn)
>      {
>        if (dump_file)
> -        fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
> -                 loop->loop_no);
> +     fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
> +              loop->loop_no);
>        return false;
>      }
>  
> @@ -7882,12 +7812,21 @@ hwloop_optimize (hwloop_info loop)
>        return false;
>      }
>  
> -  /* Check if we use a register or not.  */
> +  /* Check if we use a register or not.       */
>    if (!REG_P (loop->iter_reg))
>      {
>        if (dump_file)
> -        fprintf (dump_file, ";; loop %d iterator is MEM\n",
> -                 loop->loop_no);
> +     fprintf (dump_file, ";; loop %d iterator is MEM\n",
> +              loop->loop_no);
> +      return false;
> +    }
> +
> +  /* Check if we use a register or not.       */
> +  if (!REG_P (loop->iter_reg))
> +    {
> +      if (dump_file)
> +     fprintf (dump_file, ";; loop %d iterator is MEM\n",
> +              loop->loop_no);
>        return false;
>      }
>  
> @@ -7905,7 +7844,11 @@ hwloop_optimize (hwloop_info loop)
>         || (loop->incoming_src
>             && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
>                                 LP_COUNT)))
> -     return false;
> +     {
> +       if (dump_file)
> +         fprintf (dump_file, ";; loop %d, lp_count is alive", loop->loop_no);
> +       return false;
> +     }
>        else
>       need_fix = true;
>      }
> @@ -8020,7 +7963,7 @@ hwloop_optimize (hwloop_info loop)
>      {
>        /* The loop uses a R-register, but the lp_count is free, thus
>        use lp_count.  */
> -      emit_insn (gen_movsi (lp_reg, iter_reg));
> +      emit_insn (gen_rtx_SET (lp_reg, iter_reg));
>        SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
>        iter_reg = lp_reg;
>        if (dump_file)
> @@ -8030,8 +7973,7 @@ hwloop_optimize (hwloop_info loop)
>       }
>      }
>  
> -  insn = emit_insn (gen_arc_lp (iter_reg,
> -                             loop->start_label,
> +  insn = emit_insn (gen_arc_lp (loop->start_label,
>                               loop->end_label));
>  
>    seq = get_insns ();
> @@ -8049,12 +7991,12 @@ hwloop_optimize (hwloop_info loop)
>        seq = emit_label_before (gen_label_rtx (), seq);
>        new_bb = create_basic_block (seq, insn, entry_bb);
>        FOR_EACH_EDGE (e, ei, loop->incoming)
> -        {
> -          if (!(e->flags & EDGE_FALLTHRU))
> -            redirect_edge_and_branch_force (e, new_bb);
> -          else
> -            redirect_edge_succ (e, new_bb);
> -        }
> +     {
> +       if (!(e->flags & EDGE_FALLTHRU))
> +         redirect_edge_and_branch_force (e, new_bb);
> +       else
> +         redirect_edge_succ (e, new_bb);
> +     }
>  
>        make_edge (new_bb, loop->head, 0);
>      }
> @@ -8062,17 +8004,19 @@ hwloop_optimize (hwloop_info loop)
>      {
>  #if 0
>        while (DEBUG_INSN_P (entry_after)
> -             || (NOTE_P (entry_after)
> -              && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK))
> +          || (NOTE_P (entry_after)
> +              && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK
> +              /* Make sure we don't split a call and its corresponding
> +                 CALL_ARG_LOCATION note.  */
> +              && NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION))
>          entry_after = NEXT_INSN (entry_after);
>  #endif
> -      entry_after = next_nonnote_nondebug_insn_bb (entry_after);
> +      entry_after = next_nonnote_insn_bb (entry_after);
>  
>        gcc_assert (entry_after);
>        emit_insn_before (seq, entry_after);
>      }
>  
> -  delete_insn (loop->loop_end);
>    /* Insert the loop end label before the last instruction of the
>       loop.  */
>    emit_label_after (end_label, loop->last_insn);
> @@ -8724,26 +8668,6 @@ int
>  arc_register_move_cost (machine_mode,
>                       enum reg_class from_class, enum reg_class to_class)
>  {
> -  /* The ARC600 has no bypass for extension registers, hence a nop might be
> -     needed to be inserted after a write so that reads are safe.  */
> -  if (TARGET_ARC600)
> -    {
> -      if (to_class == MPY_WRITABLE_CORE_REGS)
> -     return 3;
> -     /* Instructions modifying LP_COUNT need 4 additional cycles before
> -     the register will actually contain the value.  */
> -      else if (to_class == LPCOUNT_REG)
> -     return 6;
> -      else if (to_class == WRITABLE_CORE_REGS)
> -     return 6;
> -    }
> -
> -  /* Using lp_count as scratch reg is a VERY bad idea.  */
> -  if (from_class == LPCOUNT_REG)
> -    return 1000;
> -  if (to_class == LPCOUNT_REG)
> -    return 6;
> -
>    /* Force an attempt to 'mov Dy,Dx' to spill.  */
>    if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
>        && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
> @@ -9962,17 +9886,20 @@ split_subsi (rtx *operands)
>  static bool
>  arc_process_double_reg_moves (rtx *operands)
>  {
> -  rtx dest = operands[0];
> -  rtx src  = operands[1];
> -
>    enum usesDxState { none, srcDx, destDx, maxDx };
>    enum usesDxState state = none;
> +  rtx dest = operands[0];
> +  rtx src  = operands[1];
>  
>    if (refers_to_regno_p (40, 44, src, 0))
> -    state = srcDx;
> +    {
> +      state = srcDx;
> +      gcc_assert (REG_P (dest));
> +    }
>    if (refers_to_regno_p (40, 44, dest, 0))
>      {
>        /* Via arc_register_move_cost, we should never see D,D moves.  */
> +      gcc_assert (REG_P (src));
>        gcc_assert (state == none);
>        state = destDx;
>      }
> @@ -10324,11 +10251,11 @@ arc_return_address_register (unsigned int fn_type)
>    if (ARC_INTERRUPT_P (fn_type))
>      {
>        if ((fn_type & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_FIRQ)) != 0)
> -        regno = ILINK1_REGNUM;
> +     regno = ILINK1_REG;
>        else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
> -        regno = ILINK2_REGNUM;
> +     regno = ILINK2_REG;
>        else
> -        gcc_unreachable ();
> +     gcc_unreachable ();
>      }
>    else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
>      regno = RETURN_ADDR_REGNUM;
> @@ -10379,14 +10306,12 @@ arc_eh_uses (int regno)
>    return false;
>  }
>  
> -#ifndef TARGET_NO_LRA
> -#define TARGET_NO_LRA !TARGET_LRA
> -#endif
> +/* Return true if we use LRA instead of reload pass.  */
>  
> -static bool
> +bool
>  arc_lra_p (void)
>  {
> -  return !TARGET_NO_LRA;
> +  return arc_lra_flag;
>  }
>  
>  /* ??? Should we define TARGET_REGISTER_PRIORITY?  We might perfer to use
> @@ -11325,7 +11250,7 @@ operands_ok_ldd_std (rtx rt, rtx rt2, HOST_WIDE_INT 
> offset)
>    t = REGNO (rt);
>    t2 = REGNO (rt2);
>  
> -  if ((t2 == PROGRAM_COUNTER_REGNO)
> +  if ((t2 == PCL_REG)
>        || (t % 2 != 0)        /* First destination register is not even.  */
>        || (t2 != t + 1))
>        return false;
> diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
> index d8ea7769db8..afd6d7681cf 100644
> --- a/gcc/config/arc/arc.h
> +++ b/gcc/config/arc/arc.h
> @@ -312,8 +312,6 @@ if (GET_MODE_CLASS (MODE) == MODE_INT             \
>  #undef WCHAR_TYPE_SIZE
>  #define WCHAR_TYPE_SIZE 32
>  
> -#define PROGRAM_COUNTER_REGNO 63
> -
>  /* Standard register usage.  */
>  
>  /* Number of actual hardware registers.
> @@ -373,7 +371,7 @@ if (GET_MODE_CLASS (MODE) == MODE_INT             \
>    1, 1, 1, 1, 1, 1, 1, 1,    \
>    0, 0, 0, 0, 1, 1, 1, 1,    \
>    1, 1, 1, 1, 1, 1, 1, 1,    \
> -  1, 1, 1, 1, 0, 1, 1, 1,       \
> +  1, 1, 1, 1, 1, 1, 1, 1,       \
>                               \
>    0, 0, 0, 0, 0, 0, 0, 0,       \
>    0, 0, 0, 0, 0, 0, 0, 0,       \
> @@ -470,25 +468,15 @@ enum reg_class
>  {
>     NO_REGS,
>     R0_REGS,                  /* 'x' */
> -   GP_REG,                   /* 'Rgp' */
> -   FP_REG,                   /* 'f' */
> -   SP_REGS,                  /* 'b' */
> -   LPCOUNT_REG,              /* 'l' */
> -   LINK_REGS,                        /* 'k' */
> -   DOUBLE_REGS,                      /* D0, D1 */
> -   SIMD_VR_REGS,             /* VR00-VR63 */
> -   SIMD_DMA_CONFIG_REGS,     /* DI0-DI7,DO0-DO7 */
> +   R0R1_CD_REGS,             /* 'Rsd' */
> +   R0R3_CD_REGS,             /* 'Rcd' */
>     ARCOMPACT16_REGS,         /* 'q' */
> -   AC16_BASE_REGS,           /* 'e' */
>     SIBCALL_REGS,             /* "Rsc" */
> -   GENERAL_REGS,             /* 'r' */
> -   MPY_WRITABLE_CORE_REGS,   /* 'W' */
> -   WRITABLE_CORE_REGS,               /* 'w' */
> -   CHEAP_CORE_REGS,          /* 'c' */
> -   ALL_CORE_REGS,            /* 'Rac' */
> -   R0R3_CD_REGS,             /* 'Rcd' */
> -   R0R1_CD_REGS,             /* 'Rsd' */
>     AC16_H_REGS,                      /* 'h' */
> +   DOUBLE_REGS,                      /* 'D' */
> +   GENERAL_REGS,             /* 'r' */
> +   SIMD_VR_REGS,             /* 'v' */
> +   SIMD_DMA_CONFIG_REGS,     /* 'd' */
>     ALL_REGS,
>     LIM_REG_CLASSES
>  };
> @@ -497,29 +485,19 @@ enum reg_class
>  
>  /* Give names of register classes as strings for dump file.   */
>  #define REG_CLASS_NAMES        \
> -{                         \
> -  "NO_REGS",                   \
> -  "R0_REGS",                   \
> -  "GP_REG",                    \
> -  "FP_REG",                    \
> -  "SP_REGS",           \
> -  "LPCOUNT_REG",       \
> -  "LINK_REGS",                 \
> -  "DOUBLE_REGS",          \
> -  "SIMD_VR_REGS",         \
> -  "SIMD_DMA_CONFIG_REGS", \
> -  "ARCOMPACT16_REGS",          \
> -  "AC16_BASE_REGS",       \
> +{                      \
> +  "NO_REGS",           \
> +  "R0_REGS",           \
> +  "R0R1_CD_REGS",      \
> +  "R0R3_CD_REGS",      \
> +  "ARCOMPACT16_REGS",          \
>    "SIBCALL_REGS",      \
> -  "GENERAL_REGS",              \
> -  "MPY_WRITABLE_CORE_REGS",   \
> -  "WRITABLE_CORE_REGS",   \
> -  "CHEAP_CORE_REGS",   \
> -  "ALL_CORE_REGS",     \
> -  "R0R3_CD_REGS", \
> -  "R0R1_CD_REGS", \
> -  "AC16_H_REGS",         \
> -  "ALL_REGS"                   \
> +  "AC16_H_REGS",       \
> +  "DOUBLE_REGS",       \
> +  "GENERAL_REGS",      \
> +  "SIMD_VR_REGS",      \
> +  "SIMD_DMA_CONFIG_REGS", \
> +  "ALL_REGS"           \
>  }
>  
>  /* Define which registers fit in which classes.
> @@ -527,33 +505,19 @@ enum reg_class
>     of length N_REG_CLASSES.  */
>  
>  #define REG_CLASS_CONTENTS \
> -{                                                                            
>                         \
> -  {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},           /* 
> No Registers */                 \
> -  {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 'x', 
> r0 register , r0 */     \
> -  {0x04000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 
> 'Rgp', Global Pointer, r26 */        \
> -  {0x08000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 'f', 
> Frame Pointer, r27 */   \
> -  {0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 'b', 
> Stack Pointer, r28 */   \
> -  {0x00000000, 0x10000000, 0x00000000, 0x00000000, 0x00000000},      /* 'l', 
> LPCOUNT Register, r60 */        \
> -  {0xe0000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 'k', 
> LINK Registers, r29-r31 */      \
> -  {0x00000000, 0x00000f00, 0x00000000, 0x00000000, 0x00000000},      /* 'D', 
> D1, D2 Registers */     \
> -  {0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000},      /* 'V', 
> VR00-VR63 Registers */  \
> -  {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000ffff},      /* 'V', 
> DI0-7,DO0-7 Registers */        \
> -  {0x0000f00f, 0x00000000, 0x00000000, 0x00000000, 0x00000000},           /* 
> 'q', r0-r3, r12-r15 */          \
> -  {0x1000f00f, 0x00000000, 0x00000000, 0x00000000, 0x00000000},           /* 
> 'e', r0-r3, r12-r15, sp */      \
> -  {0x1c001fff, 0x00000000, 0x00000000, 0x00000000, 0x00000000},    /* "Rsc", 
> r0-r12 */ \
> -  {0x9fffffff, 0x80000000, 0x00000000, 0x00000000, 0x00000000},      /* 'r', 
> r0-r28, blink, ap and pcl */    \
> -  {0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 'W', 
>  r0-r31 */ \
> -  /* Include ap / pcl in WRITABLE_CORE_REGS for sake of symmetry.  As these \
> -     registers are fixed, it does not affect the literal meaning of the \
> -     constraints, but it makes it a superset of GENERAL_REGS, thus \
> -     enabling some operations that would otherwise not be possible.  */ \
> -  {0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 'w', 
> r0-r31, r60 */ \
> -  {0xffffffff, 0x9fffffff, 0x00000000, 0x00000000, 0x00000000},      /* 'c', 
> r0-r60, ap, pcl */ \
> -  {0xffffffff, 0x9fffffff, 0x00000000, 0x00000000, 0x00000000},      /* 
> 'Rac', r0-r60, ap, pcl */ \
> -  {0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 
> 'Rcd', r0-r3 */ \
> -  {0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 
> 'Rsd', r0-r1 */ \
> -  {0x9fffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 'h', 
>  r0-28, r30 */ \
> -  {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff}       /* All 
> Registers */             \
> +{                                                                    \
> +  {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},      /* 
> NO_REGS  */ \
> +  {0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'x' */ \
> +  {0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rsd' */ \
> +  {0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rcd' */ \
> +  {0x0000f00f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'q' */ \
> +  {0x1c001fff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rsc' */ \
> +  {0x9fffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'h' */ \
> +  {0x00000000, 0x00000f00, 0x00000000, 0x00000000, 0x00000000}, /* 'D' */ \
> +  {0xffffffff, 0x8fffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'r' */ \
> +  {0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000}, /* 'v' */ \
> +  {0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000ffff}, /* 'd' */ \
> +  {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff}  /* ALL_REGS 
> */\
>  }
>  
>  /* Local macros to mark the first and last regs of different classes.  */
> @@ -590,7 +554,7 @@ extern enum reg_class arc_regno_reg_class[];
>  /* The class value for valid base registers. A base register is one used in
>     an address which is the register value plus a displacement.  */
>  
> -#define BASE_REG_CLASS (TARGET_MIXED_CODE ? AC16_BASE_REGS : GENERAL_REGS)
> +#define BASE_REG_CLASS GENERAL_REGS
>  
>  /* These assume that REGNO is a hard or pseudo reg number.
>     They give nonzero only if REGNO is a hard reg of the suitable class
> @@ -1658,4 +1622,8 @@ enum
>  /* The default option for BI/BIH instructions.  */
>  #define DEFAULT_BRANCH_INDEX 0
>  
> +#ifndef TARGET_LRA
> +#define TARGET_LRA arc_lra_p()
> +#endif
> +
>  #endif /* GCC_ARC_H */
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index 3c0931947d9..a28c67ac184 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -170,18 +170,37 @@
>     (R1_REG 1)
>     (R2_REG 2)
>     (R3_REG 3)
> +   (R4_REG 4)
> +
> +   (R9_REG 9)
>     (R10_REG 10)
> +
>     (R12_REG 12)
> +
> +   (R15_REG 15)
> +   (R16_REG 16)
> +
> +   (R25_REG 25)
>     (SP_REG 28)
> -   (ILINK1_REGNUM 29)
> -   (ILINK2_REGNUM 30)
> +   (ILINK1_REG 29)
> +   (ILINK2_REG 30)
> +   (R30_REG 30)
>     (RETURN_ADDR_REGNUM 31)
> +   (R32_REG 32)
> +   (R40_REG 40)
> +   (R41_REG 41)
> +   (R42_REG 42)
> +   (R43_REG 43)
> +   (R44_REG 44)
> +   (R57_REG 57)
>     (MUL64_OUT_REG 58)
>     (MUL32x16_REG 56)
>     (ARCV2_ACC 58)
> +   (R59_REG 59)
>  
>     (LP_COUNT 60)
>     (CC_REG 61)
> +   (PCL_REG 63)
>     (LP_START 144)
>     (LP_END 145)
>    ]
> @@ -651,8 +670,8 @@ core_3, archs4x, archs4xd, archs4xd_slow"
>  ; The iscompact attribute allows the epilogue expander to know for which
>  ; insns it should lengthen the return insn.
>  (define_insn "*movqi_insn"
> -  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   
> h,w*l,w*l,???w,h,w*l,Rcq,  S,!*x,  r,r, Ucm,m,???m,  m,Usc")
> -     (match_operand:QI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1, 
> cL,  I,?Rac,i, ?i,  T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
> +  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   
> h, w, w,???w,h, w,Rcq,  S,!*x,  r,r, Ucm,m,???m,  m,Usc")
> +     (match_operand:QI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    
> P,hCm1,cL, I,?Rac,i,?i,  T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
>    "register_operand (operands[0], QImode)
>     || register_operand (operands[1], QImode)"
>    "@
> @@ -688,8 +707,8 @@ core_3, archs4x, archs4xd, archs4xd_slow"
>    "if (prepare_move_operands (operands, HImode)) DONE;")
>  
>  (define_insn "*movhi_insn"
> -  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   
> h,w*l,w*l,???w,Rcq#q,h,w*l,Rcq,  S,  r,r, Ucm,m,???m,  m,VUsc")
> -     (match_operand:HI 1 "move_src_operand" "   cL,   cP,Rcq#q,    P,hCm1, 
> cL,  I,?Rac,    i,i, ?i,  T,Rcq,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
> +  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   
> h, w, w,???w,Rcq#q,h, w,Rcq,  S,  r,r, Ucm,m,???m,  m,VUsc")
> +     (match_operand:HI 1 "move_src_operand" "   cL,   cP,Rcq#q,    
> P,hCm1,cL, I,?Rac,    i,i,?i,  T,Rcq,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
>    "register_operand (operands[0], HImode)
>     || register_operand (operands[1], HImode)
>     || (CONSTANT_P (operands[1])
> @@ -739,9 +758,9 @@ core_3, archs4x, archs4xd, archs4xd_slow"
>  ; the iscompact attribute allows the epilogue expander to know for which
>  ; insns it should lengthen the return insn.
>  ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
> -(define_insn "*movsi_insn"                      ;   0     1     2     3    4 
>  5    6   7   8   9   10    11  12  13    14  15   16  17  18     19     20  
> 21  22    23    24 25 26    27 28  29  30   31
> -  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   
> h,w*l,w*l,  w,  w,  w,  w,  ???w, ?w,  w,Rcq#q,  h, w*l,Rcq,  S,   
> Us<,RcqRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,???m,  m,VUsc")
> -     (match_operand:SI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    P,hCm1, 
> cL,  I,Crr,Clo,Chi,Cbi,?Rac*l,Cpc,Clb, ?Cal,Cal,?Cal,Uts,Rcq,RcqRck,   
> Us>,Usd,Ucm,  Usd,  Ucd,m,  w,!*Rzd,c,?Rac,Cm3, C32"))]
> +(define_insn "*movsi_insn"                      ;   0     1     2     3    4 
>  5  6   7   8   9   10  11  12  13    14  15   16  17  18     19     20  21  
> 22    23    24 25 26    27 28  29  30   31
> +  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,    w,Rcq#q,   
> h,wl, w,  w,  w,  w,  w,???w, ?w,  w,Rcq#q,  h,  wl,Rcq,  S,   
> Us<,RcqRck,!*x,  r,!*Rsd,!*Rcd,r,Ucm,  Usd,m,???m,  m,VUsc")
> +     (match_operand:SI 1 "move_src_operand"  "  cL,   cP,Rcq#q,    
> P,hCm1,cL, I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal,Uts,Rcq,RcqRck,   
> Us>,Usd,Ucm,  Usd,  Ucd,m,  w,!*Rzd,c,?Rac,Cm3, C32"))]
>    "register_operand (operands[0], SImode)
>     || register_operand (operands[1], SImode)
>     || (CONSTANT_P (operands[1])
> @@ -5001,12 +5020,12 @@ core_3, archs4x, archs4xd, archs4xd_slow"
>  })
>  
>  (define_insn "arc_lp"
> -  [(unspec:SI [(match_operand:SI 0 "register_operand" "l")]
> +  [(unspec:SI [(reg:SI LP_COUNT)]
>             UNSPEC_ARC_LP)
> -   (use (label_ref (match_operand 1 "" "")))
> -   (use (label_ref (match_operand 2 "" "")))]
> +   (use (label_ref (match_operand 0 "" "")))
> +   (use (label_ref (match_operand 1 "" "")))]
>    ""
> -  "lp\\t@%l2\\t; %0:@%l1->@%l2"
> +  "lp\\t@%l1\\t; lp_count:@%l0->@%l1"
>    [(set_attr "type" "loop_setup")
>     (set_attr "length" "4")])
>  
> @@ -5014,16 +5033,16 @@ core_3, archs4x, archs4xd, archs4xd_slow"
>  ;; register, instead of going to memory.
>  (define_insn "loop_end"
>    [(set (pc)
> -     (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,0")
> +     (if_then_else (ne (match_operand:SI 2 "nonimmediate_operand" "0,m")
>                         (const_int 1))
>                     (label_ref (match_operand 1 "" ""))
>                     (pc)))
> -   (set (match_operand:SI 0 "nonimmediate_operand" "=l!r,m")
> +   (set (match_operand:SI 0 "nonimmediate_operand" "=r,m")
>       (plus (match_dup 2) (const_int -1)))
>     (unspec [(const_int 0)] UNSPEC_ARC_LP)
>     (clobber (match_scratch:SI 3 "=X,&r"))]
>    ""
> -  "\\t;%0 %1 %2"
> +  "; ZOL_END, begins @%l1"
>    [(set_attr "length" "0")
>     (set_attr "predicable" "no")
>     (set_attr "type" "loop_end")])
> @@ -5068,7 +5087,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
>  (define_insn_and_split "dbnz"
>    [(set (pc)
>       (if_then_else
> -      (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+r!l,m")
> +      (ne (plus:SI (match_operand:SI 0 "nonimmediate_operand" "+rl,m")
>                     (const_int -1))
>            (const_int 0))
>        (label_ref (match_operand 1 "" ""))
> @@ -6282,8 +6301,8 @@ core_3, archs4x, archs4xd, archs4xd_slow"
>  
>  (define_insn "stack_tie"
>    [(set (mem:BLK (scratch))
> -     (unspec:BLK [(match_operand:SI 0 "register_operand" "rb")
> -                  (match_operand:SI 1 "register_operand" "rb")]
> +     (unspec:BLK [(match_operand:SI 0 "register_operand" "r")
> +                  (match_operand:SI 1 "register_operand" "r")]
>                   UNSPEC_ARC_STKTIE))]
>    ""
>    ""
> diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
> index e8f97e4d1af..af9e2d16ca0 100644
> --- a/gcc/config/arc/arc.opt
> +++ b/gcc/config/arc/arc.opt
> @@ -401,12 +401,9 @@ Target
>  Pass -marclinux_prof option through to linker.
>  
>  ;; lra is still unproven for ARC, so allow to fall back to reload with 
> -mno-lra.
> -;Target InverseMask(NO_LRA)
> -; lra still won't allow to configure libgcc; see PR rtl-optimization/55464.
> -; so don't enable by default.
>  mlra
> -Target Mask(LRA)
> -Enable lra.
> +Target Report Var(arc_lra_flag) Init(1) Save
> +Use LRA instead of reload.
>  
>  mlra-priority-none
>  Target RejectNegative Var(arc_lra_priority_tag, ARC_LRA_PRIORITY_NONE)
> diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
> index cbb31249240..064718972d1 100644
> --- a/gcc/config/arc/constraints.md
> +++ b/gcc/config/arc/constraints.md
> @@ -24,48 +24,33 @@
>  ; result registers of ARC600.
>  ; First, define a class for core registers that can be read cheaply.  This
>  ; is most or all core registers for ARC600, but only r0-r31 for ARC700
> -(define_register_constraint "c" "CHEAP_CORE_REGS"
> -  "core register @code{r0}-@code{r31}, @code{ap},@code{pcl}")
> +(define_register_constraint "c" "GENERAL_REGS"
> +  "Legacy, core register @code{r0}-@code{r31}, @code{ap},@code{pcl}")
>  
>  ; All core regs - e.g. for when we must have a way to reload a register.
> -(define_register_constraint "Rac" "ALL_CORE_REGS"
> -  "core register @code{r0}-@code{r60}, @code{ap},@code{pcl}")
> +(define_register_constraint "Rac" "GENERAL_REGS"
> +  "Legacy, core register @code{r0}-@code{r60}, @code{ap},@code{pcl}")
>  
>  ; Some core registers (.e.g lp_count) aren't general registers because they
>  ; can't be used as the destination of a multi-cycle operation like
>  ; load and/or multiply, yet they are still writable in the sense that
>  ; register-register moves and single-cycle arithmetic (e.g "add", "and",
>  ; but not "mpy") can write to them.
> -(define_register_constraint "w" "WRITABLE_CORE_REGS"
> -  "writable core register: @code{r0}-@code{r31}, @code{r60}, nonfixed core 
> register")
> +(define_register_constraint "w" "GENERAL_REGS"
> +  "Legacy, writable core register: @code{r0}-@code{r31}, @code{r60}, 
> nonfixed core register")
>  
> -(define_register_constraint "W" "MPY_WRITABLE_CORE_REGS"
> -  "writable core register except @code{LP_COUNT} (@code{r60}): 
> @code{r0}-@code{r31}, nonfixed core register")
> +(define_register_constraint "W" "GENERAL_REGS"
> +  "Legacy, writable core register except @code{LP_COUNT} (@code{r60}): 
> @code{r0}-@code{r31}, nonfixed core register")
>  
> -(define_register_constraint "l" "LPCOUNT_REG"
> +(define_constraint "l"
>    "@internal
> -   Loop count register @code{r60}")
> +   Loop count register @code{r60}"
> +  (and (match_code "reg")
> +       (match_test "REGNO (op) == LP_COUNT")))
>  
>  (define_register_constraint "x" "R0_REGS"
>    "@code{R0} register.")
>  
> -(define_register_constraint "Rgp" "GP_REG"
> -  "@internal
> -   Global Pointer register @code{r26}")
> -
> -(define_register_constraint "f" "FP_REG"
> -  "@internal
> -   Frame Pointer register @code{r27}")
> -
> -(define_register_constraint "b" "SP_REGS"
> -  "@internal
> -   Stack Pointer register @code{r28}")
> -
> -(define_register_constraint "k" "LINK_REGS"
> -  "@internal
> -   Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30},
> -   @code{blink}:@code{r31},")
> -
>  (define_register_constraint "q" "TARGET_Q_CLASS ? ARCOMPACT16_REGS : NO_REGS"
>    "Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3},
>     @code{r12}-@code{r15}")
> @@ -78,10 +63,6 @@
>    "Registers usable in NPS400 bitfield instructions: @code{r0}-@code{r3},
>     @code{r12}-@code{r15}")
>  
> -(define_register_constraint "e" "AC16_BASE_REGS"
> -  "Registers usable as base-regs of memory addresses in ARCompact 16-bit 
> memory
> -   instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}")
> -
>  (define_register_constraint "D" "DOUBLE_REGS"
>    "ARC FPX (dpfp) 64-bit registers. @code{D0}, @code{D1}")
>  
> @@ -472,7 +453,7 @@
>         (match_test
>       "TARGET_Rcw
>        && REGNO (op) < FIRST_PSEUDO_REGISTER
> -      && TEST_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS],
> +      && TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS],
>                              REGNO (op))")))
>  
>  (define_constraint "Rcr"
> diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
> index efa3650e1fa..c4be56f766e 100644
> --- a/gcc/config/arc/predicates.md
> +++ b/gcc/config/arc/predicates.md
> @@ -20,33 +20,12 @@
>  (define_predicate "dest_reg_operand"
>    (match_code "reg,subreg")
>  {
> -  rtx op0 = op;
> -
> -  if (GET_CODE (op0) == SUBREG)
> -    op0 = SUBREG_REG (op0);
> -  if (REG_P (op0) && REGNO (op0) < FIRST_PSEUDO_REGISTER
> -      && TEST_HARD_REG_BIT (reg_class_contents[ALL_CORE_REGS],
> -                         REGNO (op0))
> -      && !TEST_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS],
> -                         REGNO (op0)))
> -    return 0;
>    return register_operand (op, mode);
>  })
>  
>  (define_predicate "mpy_dest_reg_operand"
>    (match_code "reg,subreg")
>  {
> -  rtx op0 = op;
> -
> -  if (GET_CODE (op0) == SUBREG)
> -    op0 = SUBREG_REG (op0);
> -  if (REG_P (op0) && REGNO (op0) < FIRST_PSEUDO_REGISTER
> -      && TEST_HARD_REG_BIT (reg_class_contents[ALL_CORE_REGS],
> -                         REGNO (op0))
> -      /* Make sure the destination register is not LP_COUNT.  */
> -      && !TEST_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS],
> -                         REGNO (op0)))
> -    return 0;
>    return register_operand (op, mode);
>  })
>  
> @@ -358,13 +337,14 @@
>      case REG :
>       /* Program Counter register cannot be the target of a move.  It is
>        a readonly register.  */
> -      if (REGNO (op) == PROGRAM_COUNTER_REGNO)
> +      if (REGNO (op) == PCL_REG)
>       return 0;
>        else if (TARGET_MULMAC_32BY16_SET
> -            && (REGNO (op) == 56 || REGNO(op) == 57))
> +            && (REGNO (op) == MUL32x16_REG || REGNO (op) == R57_REG))
>       return 0;
>        else if (TARGET_MUL64_SET
> -            && (REGNO (op) == 57 || REGNO(op) == 58 || REGNO(op) == 59 ))
> +            && (REGNO (op) == R57_REG || REGNO (op) == MUL64_OUT_REG
> +                || REGNO (op) == R59_REG))
>       return 0;
>        else if (REGNO (op) == LP_COUNT)
>          return 1;
> -- 
> 2.19.1
> 

Reply via email to