* Claudiu Zissulescu <claudiu.zissule...@synopsys.com> [2017-05-05 13:02:44 
+0200]:

> When a processor enters a fast interrupts handler, and duplicate
> register banks are configured, the processor saves the user context by
> saving the registers in the main register bank to these additional
> registers in the duplicate register bank.  In this fast interrupt
> context, when you specify the rgf_banked_regs option,the compiler does
> not save the registers duplicated in the additional register bank are
> not saved.
> 
> gcc/
> 2016-10-04  Claudiu Zissulescu  <claz...@synopsys.com>
>           Andrew Burgess  <andrew.burg...@embecosm.com>
> 
>       * config/arc/arc.c (ARC_AUTOBLINK_IRQ_P): Consider fast interrupts
>       case also.
>       (ARC_AUTOFP_IRQ_P): Likewise.
>       (ARC_AUTO_IRQ_P): Likewise.
>       (rgf_banked_register_count): New variable.
>       (parse_mrgf_banked_regs_option): New function.
>       (arc_override_options): Handle rgf_banked_regs option.
>       (arc_handle_interrupt_attribute): Add firq option.
>       (arc_compute_function_type): Return fast irq type when required.
>       (arc_must_save_register): Handle fast interrupts.
>       (arc_expand_prologue): Do not emit dwarf info for fast interrupts.
>       (arc_return_address_regs): Update.
>       * config/arc/arc.h (arc_return_address_regs): Update.
>       (arc_function_type): Add fast interrupt type.
>       (ARC_INTERRUPT_P): Update.
>       (RC_FAST_INTERRUPT_P): Define.
>       * config/arc/arc.md (simple_return): Update for fast interrupts.
>       (p_return_i): Likewise.
>       * config/arc/arc.opt (mrgf-banked-regs): New option.
>       * doc/invoke.texi (mrgf-banked-regs): Document.
>       * testsuite/gcc.target/arc/firq-1.c: New file.
>       * testsuite/gcc.target/arc/firq-2.c: Likewise.
>       * testsuite/gcc.target/arc/firq-3.c: Likewise.
>       * testsuite/gcc.target/arc/firq-4.c: Likewise.
>       * testsuite/gcc.target/arc/firq-5.c: Likewise.
>       * testsuite/gcc.target/arc/firq-6.c: Likewise.

Looks fine to me,

Thanks,
Andrew



> ---
>  gcc/config/arc/arc.c                  | 106 
> +++++++++++++++++++++++++++-------
>  gcc/config/arc/arc.h                  |  13 +++--
>  gcc/config/arc/arc.md                 |   9 ++-
>  gcc/config/arc/arc.opt                |   4 ++
>  gcc/doc/invoke.texi                   |  10 ++++
>  gcc/testsuite/gcc.target/arc/firq-1.c |  27 +++++++++
>  gcc/testsuite/gcc.target/arc/firq-2.c |  31 ++++++++++
>  gcc/testsuite/gcc.target/arc/firq-3.c |  40 +++++++++++++
>  gcc/testsuite/gcc.target/arc/firq-4.c |  31 ++++++++++
>  gcc/testsuite/gcc.target/arc/firq-5.c |  15 +++++
>  gcc/testsuite/gcc.target/arc/firq-6.c |  21 +++++++
>  11 files changed, 277 insertions(+), 30 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/firq-1.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/firq-2.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/firq-3.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/firq-4.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/firq-5.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/firq-6.c
> 
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index a61faef..a0cd597 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -125,16 +125,25 @@ typedef struct irq_ctrl_saved_t
>  static irq_ctrl_saved_t irq_ctrl_saved;
>  
>  #define ARC_AUTOBLINK_IRQ_P(FNTYPE)                          \
> -  (ARC_INTERRUPT_P (FNTYPE) && irq_ctrl_saved.irq_save_blink)
> -
> -#define ARC_AUTOFP_IRQ_P(FNTYPE)                                     \
> -  (ARC_INTERRUPT_P (FNTYPE) && (irq_ctrl_saved.irq_save_last_reg > 26))
> -
> -#define ARC_AUTO_IRQ_P(FNTYPE)                               \
> -  (ARC_INTERRUPT_P (FNTYPE)                          \
> -   && (irq_ctrl_saved.irq_save_blink                 \
> +  ((ARC_INTERRUPT_P (FNTYPE)                                 \
> +    && irq_ctrl_saved.irq_save_blink)                                \
> +   || (ARC_FAST_INTERRUPT_P (FNTYPE)                         \
> +       && rgf_banked_register_count > 8))
> +
> +#define ARC_AUTOFP_IRQ_P(FNTYPE)                             \
> +  ((ARC_INTERRUPT_P (FNTYPE)                                 \
> +    && (irq_ctrl_saved.irq_save_last_reg > 26))                      \
> +  || (ARC_FAST_INTERRUPT_P (FNTYPE)                          \
> +      && rgf_banked_register_count > 8))
> +
> +#define ARC_AUTO_IRQ_P(FNTYPE)                                       \
> +  (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE)        \
> +   && (irq_ctrl_saved.irq_save_blink                         \
>         || (irq_ctrl_saved.irq_save_last_reg >= 0)))
>  
> +/* Number of registers in second bank for FIRQ support.  */
> +static int rgf_banked_register_count;
> +
>  #define arc_ccfsm_current cfun->machine->ccfsm_current
>  
>  #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
> @@ -924,6 +933,27 @@ irq_range (const char *cstr)
>    irq_ctrl_saved.irq_save_lpcount  = (lpcount == 60);
>  }
>  
> +/* Parse -mrgf-banked-regs=NUM option string.  Valid values for NUM are 4,
> +   8, 16, or 32.  */
> +
> +static void
> +parse_mrgf_banked_regs_option (const char *arg)
> +{
> +  long int val;
> +  char *end_ptr;
> +
> +  errno = 0;
> +  val = strtol (arg, &end_ptr, 10);
> +  if (errno != 0 || *arg == '\0' || *end_ptr != '\0'
> +      || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32))
> +    {
> +      error ("invalid number in -mrgf-banked-regs=%s "
> +          "valid values are 0, 4, 8, 16, or 32", arg);
> +      return;
> +    }
> +  rgf_banked_register_count = (int) val;
> +}
> +
>  /* Check ARC options, generate derived target attributes.  */
>  
>  static void
> @@ -966,6 +996,8 @@ arc_override_options (void)
>    irq_ctrl_saved.irq_save_blink    = false;
>    irq_ctrl_saved.irq_save_lpcount  = false;
>  
> +  rgf_banked_register_count = 0;
> +
>    /* Handle the deferred options.  */
>    if (vopt)
>      FOR_EACH_VEC_ELT (*vopt, i, opt)
> @@ -979,6 +1011,13 @@ arc_override_options (void)
>             warning (0, "option -mirq-ctrl-saved valid only for ARC v2 
> processors");
>           break;
>  
> +       case OPT_mrgf_banked_regs_:
> +         if (TARGET_V2)
> +           parse_mrgf_banked_regs_option (opt->arg);
> +         else
> +           warning (0, "option -mrgf-banked-regs valid only for ARC v2 
> processors");
> +         break;
> +
>         default:
>           gcc_unreachable();
>         }
> @@ -1787,9 +1826,9 @@ arc_handle_interrupt_attribute (tree *, tree name, tree 
> args, int,
>              name);
>        *no_add_attrs = true;
>      }
> -  else if (strcmp (TREE_STRING_POINTER (value), "ilink1")
> -        && strcmp (TREE_STRING_POINTER (value), "ilink2")
> -        && !TARGET_V2)
> +  else if (!TARGET_V2
> +        && strcmp (TREE_STRING_POINTER (value), "ilink1")
> +        && strcmp (TREE_STRING_POINTER (value), "ilink2"))
>      {
>        warning (OPT_Wattributes,
>              "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
> @@ -1797,10 +1836,11 @@ arc_handle_interrupt_attribute (tree *, tree name, 
> tree args, int,
>        *no_add_attrs = true;
>      }
>    else if (TARGET_V2
> -        && strcmp (TREE_STRING_POINTER (value), "ilink"))
> +        && strcmp (TREE_STRING_POINTER (value), "ilink")
> +        && strcmp (TREE_STRING_POINTER (value), "firq"))
>      {
>        warning (OPT_Wattributes,
> -            "argument of %qE attribute is not \"ilink\"",
> +            "argument of %qE attribute is not \"ilink\" or \"firq\"",
>              name);
>        *no_add_attrs = true;
>      }
> @@ -2360,6 +2400,8 @@ arc_compute_function_type (struct function *fun)
>           fn_type = ARC_FUNCTION_ILINK1;
>         else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
>           fn_type = ARC_FUNCTION_ILINK2;
> +       else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
> +         fn_type = ARC_FUNCTION_FIRQ;
>         else
>           gcc_unreachable ();
>         break;
> @@ -2386,7 +2428,29 @@ arc_must_save_register (int regno, struct function 
> *func)
>  {
>    enum arc_function_type fn_type = arc_compute_function_type (func);
>    bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
> -                       && ARC_INTERRUPT_P (fn_type));
> +                       && ARC_AUTO_IRQ_P (fn_type));
> +  bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type);
> +
> +  switch (rgf_banked_register_count)
> +    {
> +    case 4:
> +      firq_auto_save_p &= (regno < 4);
> +      break;
> +    case 8:
> +      firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16)));
> +      break;
> +    case 16:
> +      firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16))
> +                        || ((regno > 25) && (regno < 29))
> +                        || ((regno > 29) && (regno < 32)));
> +      break;
> +    case 32:
> +      firq_auto_save_p &= (regno != 29) && (regno < 32);
> +      break;
> +    default:
> +      firq_auto_save_p = false;
> +      break;
> +    }
>  
>    if ((regno) != RETURN_ADDR_REGNUM
>        && (regno) != FRAME_POINTER_REGNUM
> @@ -2394,7 +2458,8 @@ arc_must_save_register (int regno, struct function 
> *func)
>        && (!call_used_regs[regno]
>         || ARC_INTERRUPT_P (fn_type))
>        /* Do not emit code for auto saved regs.  */
> -      && !irq_auto_save_p)
> +      && !irq_auto_save_p
> +      && !firq_auto_save_p)
>      return true;
>  
>    if (flag_pic && crtl->uses_pic_offset_table
> @@ -2723,11 +2788,6 @@ arc_save_restore (rtx base_reg,
>      }
>  } /* arc_save_restore */
>  
> -
> -int arc_return_address_regs[4]
> -  = {0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM};
> -
> -
>  /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
>     mechanism.  */
>  
> @@ -2841,7 +2901,8 @@ arc_expand_prologue (void)
>  
>    /* IRQ using automatic save mechanism will save the register before
>       anything we do.  */
> -  if (ARC_AUTO_IRQ_P (fn_type))
> +  if (ARC_AUTO_IRQ_P (fn_type)
> +      && !ARC_FAST_INTERRUPT_P (fn_type))
>      {
>        arc_dwarf_emit_irq_save_regs ();
>      }
> @@ -9700,6 +9761,9 @@ arc_can_follow_jump (const rtx_insn *follower, const 
> rtx_insn *followee)
>    return true;
>  }
>  
> +int arc_return_address_regs[5] =
> +  {0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM, ILINK1_REGNUM};
> +
>  /* Implement EPILOGUE__USES.
>     Return true if REGNO should be added to the deemed uses of the epilogue.
>  
> diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
> index 5491130..52f121f 100644
> --- a/gcc/config/arc/arc.h
> +++ b/gcc/config/arc/arc.h
> @@ -1364,7 +1364,7 @@ do { \
>  
>  /* To translate the return value of arc_function_type into a register number
>     to jump through for function return.  */
> -extern int arc_return_address_regs[4];
> +extern int arc_return_address_regs[5];
>  
>  /* Debugging information.  */
>  
> @@ -1501,10 +1501,15 @@ enum arc_function_type {
>    ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL,
>    /* These are interrupt handlers.  The name corresponds to the register
>       name that contains the return address.  */
> -  ARC_FUNCTION_ILINK1, ARC_FUNCTION_ILINK2
> +  ARC_FUNCTION_ILINK1, ARC_FUNCTION_ILINK2,
> +  /* Fast interrupt is only available on ARCv2 processors.  */
> +  ARC_FUNCTION_FIRQ
>  };
> -#define ARC_INTERRUPT_P(TYPE) \
> -((TYPE) == ARC_FUNCTION_ILINK1 || (TYPE) == ARC_FUNCTION_ILINK2)
> +#define ARC_INTERRUPT_P(TYPE)                                                
> \
> +  (((TYPE) == ARC_FUNCTION_ILINK1) || ((TYPE) == ARC_FUNCTION_ILINK2)        
> \
> +   || ((TYPE) == ARC_FUNCTION_FIRQ))
> +
> +#define ARC_FAST_INTERRUPT_P(TYPE) ((TYPE) == ARC_FUNCTION_FIRQ)
>  
>  /* Compute the type of a function from its DECL.  Needed for EPILOGUE_USES.  
> */
>  struct function;
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index 2221fb5..5c3766c 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -4740,8 +4740,8 @@
>      = gen_rtx_REG (Pmode,
>                  arc_return_address_regs[arc_compute_function_type (cfun)]);
>  
> -  if (arc_compute_function_type (cfun) == ARC_FUNCTION_ILINK1
> -      && TARGET_V2)
> +  if (TARGET_V2
> +      && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
>    {
>      return \"rtie\";
>    }
> @@ -4751,8 +4751,7 @@
>    return \"\";
>  }
>    [(set (attr "type")
> -     (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
> -                     (symbol_ref "ARC_FUNCTION_ILINK1"))
> +     (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type 
> (cfun))")
>                   (match_test "TARGET_V2"))
>              (const_string "brcc_no_delay_slot")]
>             (const_string "return")))
> @@ -4782,7 +4781,7 @@
>                     (simple_return) (pc)))]
>    "reload_completed
>     && !(TARGET_V2
> -     && arc_compute_function_type (cfun) == ARC_FUNCTION_ILINK1)"
> +     && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))"
>  {
>    rtx xop[2];
>    xop[0] = operands[0];
> diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
> index 483470d..f01a2ff 100644
> --- a/gcc/config/arc/arc.opt
> +++ b/gcc/config/arc/arc.opt
> @@ -490,3 +490,7 @@ Enable unaligned word and halfword accesses to packed 
> data.
>  mirq-ctrl-saved=
>  Target RejectNegative Joined Var(arc_deferred_options) Defer
>  Specifies the registers that the processor saves on an interrupt entry and 
> exit.
> +
> +mrgf-banked-regs=
> +Target RejectNegative Joined Var(arc_deferred_options) Defer
> +Specifies the number of registers replicated in second register bank on 
> entry to fast interrupt.
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index bd3b339..35c97f0 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -607,6 +607,7 @@ Objective-C and Objective-C++ Dialects}.
>  -mcrc  -mdsp-packa  -mdvbf  -mlock  -mmac-d16  -mmac-24  -mrtsc  -mswape @gol
>  -mtelephony  -mxy  -misize  -mannotate-align  -marclinux  -marclinux_prof 
> @gol
>  -mlong-calls  -mmedium-calls  -msdata -mirq-ctrl-saved @gol
> +-mrgf-banked-regs @gol
>  -mvolatile-cache  -mtp-regno=@var{regno} @gol
>  -malign-call  -mauto-modify-reg  -mbbit-peephole  -mno-brcc @gol
>  -mcase-vector-pcrel  -mcompact-casesi  -mno-cond-exec  -mearly-cbranchsi @gol
> @@ -14554,6 +14555,15 @@ always starts with @code{r0}, the upper limit is 
> @code{fp} register.
>  @var{blink} and @var{lp_count} are optional.  This option is only
>  valid for ARC EM and ARC HS cores.
>  
> +@item -mrgf-banked-regs=@var{number}
> +@opindex mrgf-banked-regs
> +Specifies the number of registers replicated in second register bank
> +on entry to fast interrupt.  Fast interrupts are interrupts with the
> +highest priority level P0.  These interrupts save only PC and STATUS32
> +registers to avoid memory transactions during interrupt entry and exit
> +sequences.  Use this option when you are using fast interrupts in an
> +ARC V2 family processor.  Permitted values are 4, 8, 16, and 32.
> +
>  @end table
>  
>  The following options are passed through to the assembler, and also
> diff --git a/gcc/testsuite/gcc.target/arc/firq-1.c 
> b/gcc/testsuite/gcc.target/arc/firq-1.c
> new file mode 100644
> index 0000000..87f4087
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/firq-1.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target archs }*/
> +/* { dg-options "-O0 -mll64 -mirq-ctrl-saved=r0-r9" } */
> +
> +/* Check that on archs the 'firq' interrupt function type is
> +   available, these are the fast interrupts.  For fast interrupts,
> +   despite the use of 'irq-ctrl-saved', no registers are automatically
> +   saved on entry to the function, and so, in the following register
> +   r0 to r9 should all be saved to the stack.
> +
> +   We also take the opportunity to check the use of the 'rtie'
> +   instruction at the end of the interrupt function.  */
> +
> +void __attribute__ ((interrupt("firq")))
> +handler1 (void)
> +{
> +  asm (""
> +       :
> +       :
> +       : "r0", "r1", "r2", "r3", "r4",
> +      "r5", "r6", "r7", "r8", "r9");
> +}
> +/* { dg-final { scan-assembler-times "r2,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r4,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r6,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r8,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler "rtie" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/firq-2.c 
> b/gcc/testsuite/gcc.target/arc/firq-2.c
> new file mode 100644
> index 0000000..dc7dafc
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/firq-2.c
> @@ -0,0 +1,31 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target archs }*/
> +/* { dg-options "-O0 -mll64 -mirq-ctrl-saved=r0-r9 -mrgf-banked-regs=4" } */
> +
> +/* Check that on archs the 'firq' interrupt function type is
> +   available, these are the fast interrupts.  For fast interrupts,
> +   despite the use of 'irq-ctrl-saved', no registers are automatically
> +   saved on stack on entry to the function.  However, the cpu save via
> +   bank switch R0-R3.
> +
> +   We also take the opportunity to check the use of the 'rtie' instruction
> +   at the end of the interrupt function.  */
> +
> +void __attribute__ ((interrupt("firq")))
> +handler1 (void)
> +{
> +  asm (""
> +       :
> +       :
> +       : "r0", "r1", "r2", "r3", "r4",
> +         "r5", "r6", "r7", "r8", "r9");
> +}
> +/* { dg-final { scan-assembler-not "r0,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "push.*r0" } } */
> +/* { dg-final { scan-assembler-not "r1,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "r2,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "r3,\\\[sp" } } */
> +/* { dg-final { scan-assembler "st.*r4,\\\[sp" } } */
> +/* { dg-final { scan-assembler "st.*r6,\\\[sp,\[0-9\]+\\\]" } } */
> +/* { dg-final { scan-assembler "st.*r8,\\\[sp,\[0-9\]+\\\]" } } */
> +/* { dg-final { scan-assembler "rtie" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/firq-3.c 
> b/gcc/testsuite/gcc.target/arc/firq-3.c
> new file mode 100644
> index 0000000..a1d604d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/firq-3.c
> @@ -0,0 +1,40 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target archs }*/
> +/* { dg-options "-O2 -mll64 -mrgf-banked-regs=8" } */
> +
> +/* Check if R4 to R11 and R16-R27 are correctly saved on stack.  */
> +
> +void __attribute__ ((interrupt("firq")))
> +handler1 (void)
> +{
> +  asm volatile (""
> +             :
> +             :
> +             : "r0", "r1", "r2", "r3", "r4",
> +               "r5", "r6", "r7", "r8", "r9",
> +               "r10", "r11", "r12", "r13", "r14",
> +               "r15", "r16", "r17", "r18", "r19",
> +               "r20", "r21", "r22", "r23", "r24",
> +               "r25", "fp");
> +}
> +/* { dg-final { scan-assembler-not "r0,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "push.*r0" } } */
> +/* { dg-final { scan-assembler-not "r1,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "r2,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "r3,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "r12,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "r13,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "r14,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "r15,\\\[sp" } } */
> +
> +/* { dg-final { scan-assembler-times "r4,\\\[sp" 2 } } */
> +/* { dg-final { scan-assembler-times "r6,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r8,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r10,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r16,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r18,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r20,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r24,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "fp,\\\[sp," 2 } } */
> +
> +/* { dg-final { scan-assembler "rtie" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/firq-4.c 
> b/gcc/testsuite/gcc.target/arc/firq-4.c
> new file mode 100644
> index 0000000..03d3746
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/firq-4.c
> @@ -0,0 +1,31 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target archs }*/
> +/* { dg-options "-O2 -mll64 -mrgf-banked-regs=16" } */
> +
> +/* Check if R4-R9 and R16-R25 are correctly saved on stack.  */
> +
> +void __attribute__ ((interrupt("firq")))
> +handler1 (void)
> +{
> +  asm volatile (""
> +             :
> +             :
> +             : "r0", "r1", "r2", "r3", "r4",
> +               "r5", "r6", "r7", "r8", "r9",
> +               "r10", "r11", "r12", "r13", "r14",
> +               "r15", "r16", "r17", "r18", "r19",
> +               "r20", "r21", "r22", "r23", "r24",
> +               "r25", "fp");
> +}
> +/* { dg-final { scan-assembler-times "r4,\\\[sp" 2 } } */
> +/* { dg-final { scan-assembler-times "r6,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r8,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +
> +/* { dg-final { scan-assembler-times "r16,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r18,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r20,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +/* { dg-final { scan-assembler-times "r24,\\\[sp,\[0-9\]+\\\]" 2 } } */
> +
> +/* { dg-final { scan-assembler-not "fp,\\\[sp" } } */
> +/* { dg-final { scan-assembler-not "push.*fp" } } */
> +/* { dg-final { scan-assembler "mov_s.*fp,sp" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/firq-5.c 
> b/gcc/testsuite/gcc.target/arc/firq-5.c
> new file mode 100644
> index 0000000..29f17a3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/firq-5.c
> @@ -0,0 +1,15 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target archs }*/
> +/* { dg-options "-O2 -mrgf-banked-regs=16" } */
> +
> +/* Check if blink is pushed on the stack or not.   */
> +
> +extern void bar (void);
> +
> +void __attribute__ ((interrupt("firq")))
> +handler1 (void)
> +{
> +  bar ();
> +}
> +/* { dg-final { scan-assembler-not "push.*blink" } } */
> +/* { dg-final { scan-assembler-not "pop.*blink" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/firq-6.c 
> b/gcc/testsuite/gcc.target/arc/firq-6.c
> new file mode 100644
> index 0000000..9421200
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/firq-6.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-require-effective-target archs }*/
> +/* { dg-options "-O2 -mll64 -mrgf-banked-regs=32" } */
> +
> +/* Check if we have any register saved on stack.  */
> +
> +void __attribute__ ((interrupt("firq")))
> +handler1 (void)
> +{
> +  asm volatile (""
> +             :
> +             :
> +             : "r0", "r1", "r2", "r3", "r4",
> +               "r5", "r6", "r7", "r8", "r9",
> +               "r10", "r11", "r12", "r13", "r14",
> +               "r15", "r16", "r17", "r18", "r19",
> +               "r20", "r21", "r22", "r23", "r24",
> +               "r25", "fp");
> +}
> +/* { dg-final { scan-assembler-not 
> "(s|l)(t|d)d.*r\[0-9\]+,\\\[sp,\[0-9\]+\\\]" } } */
> +/* { dg-final { scan-assembler "mov_s.*fp,sp" } } */
> -- 
> 1.9.1
> 

Reply via email to