This is an automated email from the ASF dual-hosted git repository.

pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 1c94cb5324e9d91e0ed4611bf21ff4cff3230041
Author: Abdelatif Guettouche <[email protected]>
AuthorDate: Sat Jun 11 16:05:19 2022 +0200

    arch/xtensa: Refactor the differences in ABI calls.
    
    Signed-off-by: Abdelatif Guettouche <[email protected]>
---
 arch/xtensa/include/xtensa/xtensa_abi.h      | 27 +++++++++-
 arch/xtensa/src/common/xtensa_int_handlers.S | 78 ++++++++--------------------
 arch/xtensa/src/common/xtensa_panic.S        | 20 +++----
 arch/xtensa/src/common/xtensa_user_handler.S | 56 ++++++--------------
 4 files changed, 71 insertions(+), 110 deletions(-)

diff --git a/arch/xtensa/include/xtensa/xtensa_abi.h 
b/arch/xtensa/include/xtensa/xtensa_abi.h
index 123b003326..e3b7177a86 100644
--- a/arch/xtensa/include/xtensa/xtensa_abi.h
+++ b/arch/xtensa/include/xtensa/xtensa_abi.h
@@ -112,9 +112,10 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-/* MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
+/* MACROS TO HANDLE ABI SPECIFICS OF FUNCTION CALL, ENTRY AND RETURN
  *
  * Convenient where the frame size requirements are the same for both ABIs.
+ *   CALL, ARGx are used to make a call to a C function.
  *   ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
  *   ENTRY0,    RET0    are for frameless functions (no locals, no calls).
  *
@@ -149,6 +150,15 @@
 #  define RET(sz)       ret1    sz
 #  define RET0          ret
 
+#  define CALL          call0
+#  define ARG1          a2
+#  define ARG2          a3
+#  define ARG3          a4
+#  define ARG4          a5
+#  define ARG5          a6
+#  define ARG6          a7
+#  define RETVAL        a2
+
 #else
   /* Windowed */
 
@@ -157,6 +167,21 @@
 #  define RET(sz)       retw
 #  define RET0          retw
 
+/* These macros are used only in assembly code when calling C functions
+ * with CALL4.  This is to help refactor common code with the CALL0 ABI.
+ * call0 can still be used to call assembly function not conforming to the
+ * windowed ABI.
+ */
+
+#  define CALL          call4
+#  define ARG1          a6
+#  define ARG2          a7
+#  define ARG3          a8
+#  define ARG4          a9
+#  define ARG5          a10
+#  define ARG6          a11
+#  define RETVAL        a6
+
 #endif
 
 /* Index into stack frame.
diff --git a/arch/xtensa/src/common/xtensa_int_handlers.S 
b/arch/xtensa/src/common/xtensa_int_handlers.S
index 28946006f9..052cce6e0c 100644
--- a/arch/xtensa/src/common/xtensa_int_handlers.S
+++ b/arch/xtensa/src/common/xtensa_int_handlers.S
@@ -131,66 +131,32 @@ g_intstacktop:
 
        ps_setup        \level \tmp
 
-#ifdef __XTENSA_CALL0_ABI__
        /* Get mask of pending, enabled interrupts at this level into a2. */
 
-       rsr             a2, INTENABLE
+       rsr             ARG1, INTENABLE
        rsr             a3, INTERRUPT
        movi    a4, \mask
-       and             a2, a2, a3
-       and             a2, a2, a4                              /* a2 = Set of 
pending, enabled interrupts for this level */
-       beqz    a2, 1f                                          /* Nothing to 
do */
+       and             ARG1, ARG1, a3
+       and             ARG1, ARG1, a4                          /* Set of 
pending, enabled interrupts for this level */
+       beqz    ARG1, 1f                                        /* Nothing to 
do */
 
-       /* Call xtensa_int_decode passing the address of the register save area
-        * as a parameter (A3).
-        */
-
-                                                                         /* 
Argument 1: Set of CPU interrupt to dispatch */
-       mov             a3, a12                                     /* Argument 
2: Top of stack = register save area */
-       call0   xtensa_int_decode         /* Call xtensa_int_decode */
-
-       /* On return from xtensa_int_decode, a2 will contain the address of the 
new
-        * register save area.  Usually this would be the same as the current 
SP.
-        * But in the event of a context switch, a2 will instead refer to the 
TCB
-        * register save area.  This may or may not reside on a stack.
-        */
-
-       mov             a12, a2                                         /* 
Switch to the save area of the new thread */
-
-#else
-       /* Get mask of pending, enabled interrupts at this level into a6. */
-
-       rsr             a6, INTENABLE
-       rsr             a2, INTERRUPT
-       movi    a3, \mask
-       and             a6, a6, a2
-       and             a6, a6, a3                              /* a6 = Set of 
pending, enabled interrupts for this level */
-       beqz    a6, 1f                                          /* Nothing to 
do */
-
-       /* At this point, the exception frame should have been allocated and 
filled,
-        * and current sp points to the interrupt stack (if enabled). Copy the
-        * pre-exception's base save area below the current SP. We saved the SP 
in A12
-        * before getting here.
+       /* Link the pre-exception frame for debugging. At this point, a12 
points to the
+        * allocated and filled exception stack frame (old value of SP in case 
of
+        * an interrupt stack).
         */
 
        exception_backtrace a12 \level
 
-       /* Call xtensa_int_decode passing the address of the register save area
-        * as a parameter (A7).
-        */
-
-                                                                               
        /* Argument 1: Set of CPU interrupt to dispatch */
-       mov             a7, a12                                         /* 
Argument 2: Top of stack = register save area */
-       call4   xtensa_int_decode               /* Call xtensa_int_decode */
+                                                                   /* Argument 
1: Set of CPU interrupt to dispatch */
+       mov             ARG2, a12                                       /* 
Argument 2: Top of stack = register save area */
+       CALL    xtensa_int_decode
 
-       /* On return from xtensa_int_decode, a6 will contain the address of the 
new
-        * register save area.  Usually this would be the same as the current 
SP.
-        * But in the event of a context switch, a6 will instead refer to the 
TCB
-        * register save area.  This may or may not reside on a stack.
+       /* xtensa_int_decode returns the address of the new register save area.
+        * Usually this would be the same as the current SP. But in the event of
+        * a context switch, it will instead refer to the TCB register save 
area.
         */
 
-       mov             a12, a6                                         /* 
Switch to the save area of the new thread */
-#endif
+       mov             a12, RETVAL                                     /* 
Switch to the save area of the new thread */
 
 #if CONFIG_ARCH_INTERRUPTSTACK < 15
        addi    sp, sp, XCPTCONTEXT_SIZE
@@ -232,17 +198,17 @@ _xtensa_level1_handler:
 
        call0   _xtensa_context_save
 
-  /* Save current SP before (possibly) overwriting it, it's the register save
-   * area. This value will be used later by dispatch_c_isr to retrieve the
-   * register save area.
-   */
-
-  mov  a12, sp
+       /* Save current SP before (possibly) overwriting it, it's the register 
save
+        * area. This value will be used later by dispatch_c_isr to retrieve the
+        * register save area.
+        */
+       
+       mov  a12, sp
 
-  /* Switch to an interrupt stack if we have one */
+       /* Switch to an interrupt stack if we have one */
 
 #if CONFIG_ARCH_INTERRUPTSTACK > 15
-  setintstack a13 a14
+       setintstack a13 a14
 #endif
 
        /* Decode and dispatch the interrupt.  In the event of an interrupt
diff --git a/arch/xtensa/src/common/xtensa_panic.S 
b/arch/xtensa/src/common/xtensa_panic.S
index dbd2ce7099..05eef85e6e 100644
--- a/arch/xtensa/src/common/xtensa_panic.S
+++ b/arch/xtensa/src/common/xtensa_panic.S
@@ -62,6 +62,7 @@
 
 #include <arch/irq.h>
 #include <arch/xtensa/core.h>
+#include <arch/xtensa/xtensa_abi.h>
 #include <arch/xtensa/xtensa_specregs.h>
 
 #include "xtensa_macros.S"
@@ -129,21 +130,16 @@ _xtensa_panic:
 
        /* Set up PS for C, re-enable hi-pri interrupts, and clear EXCM. */
 
-  ps_setup XCHAL_EXCM_LEVEL a0
+       ps_setup XCHAL_EXCM_LEVEL a0
 
-       /* Call C panic handler:  Arg1 (A2) = Exception code; Arg 2 (A3) = start
-        * of the register save area.
+       /* Call C panic handler: 
+        *  Arg1  = Exception code.
+        *  Arg 2 = Start of the register save area.
         */
 
-#ifdef __XTENSA_CALL0_ABI__
-       rsr             a2, EXCSAVE_1
-       mov             a3, a12
-       call0   xtensa_panic                                    /* Call 
xtensa_panic. Should not return */
-#else
-       rsr             a6, EXCSAVE_1
-       mov             a7, a12
-       call4   xtensa_panic                                    /* Call 
xtensa_panic. Should not return */
-#endif
+       rsr             ARG1, EXCSAVE_1
+       mov             ARG2, a12
+       CALL    xtensa_panic                                    /* Call 
xtensa_panic. Should not return */
 
 1:     j               1b                                                      
        /* loop infinitely */
        retw
diff --git a/arch/xtensa/src/common/xtensa_user_handler.S 
b/arch/xtensa/src/common/xtensa_user_handler.S
index 47adb53634..dd5cd26da1 100644
--- a/arch/xtensa/src/common/xtensa_user_handler.S
+++ b/arch/xtensa/src/common/xtensa_user_handler.S
@@ -62,6 +62,7 @@
 
 #include <arch/irq.h>
 #include <arch/xtensa/core.h>
+#include <arch/xtensa/xtensa_abi.h>
 #include <arch/xtensa/xtensa_specregs.h>
 
 #include "xtensa_macros.S"
@@ -184,7 +185,7 @@ _xtensa_user_handler:
 
        ps_setup        1 a0
 
-       /* Create pseudo base save area. At this point, a12 points to the
+       /* Link the pre-exception frame for debugging. At this point, a12 
points to the
         * allocated and filled exception stack frame (old value of SP in case 
of
         * an interrupt stack).
         */
@@ -195,16 +196,9 @@ _xtensa_user_handler:
         * beginning of the register save area.
         */
 
-#ifdef __XTENSA_CALL0_ABI__
-       rsr             a2, EXCCAUSE                                    /* 
Argument 1 (a2) = EXCCAUSE */
-       mov             a3, a12                                                 
/* Argument 2 (a3) = pointer to register save area */
-       calx0   xtensa_user                                             /* Call 
xtensa_user */
-#else
-       rsr             a6, EXCCAUSE                                    /* 
Argument 1 (a6) = EXCCAUSE */
-       mov             a7, a12                                                 
/* Argument 2 (a7) = pointer to register save area */
-       call4   xtensa_user                                             /* Call 
xtensa_user */
-       mov             a12, a6
-#endif
+       rsr             ARG1, EXCCAUSE                                  /* 
Argument 1 = EXCCAUSE */
+       mov             ARG2, a12                                               
/* Argument 2 = pointer to register save area */
+       CALL    xtensa_user                                             /* Call 
xtensa_user */
 
        /* Restore registers in preparation to return from interrupt */
 
@@ -312,30 +306,16 @@ _xtensa_syscall_handler:
 
        ps_setup        1 a0
 
-#ifdef __XTENSA_CALL0_ABI__
-       movi    a2, XTENSA_IRQ_SYSCALL                  /* Argument 1: IRQ 
number */
-       mov             a3, a12                                                 
/* Argument 2: Top of stack = register save area */
-       call0   xtensa_irq_dispatch                             /* Call 
xtensa_int_decode */
-
-       /* On return from xtensa_irq_dispatch, A2 will contain the address of 
the new
-        * register save area.  Usually this would be the same as the current 
SP.
-        * But in the event of a context switch, A2 will instead refer to the 
TCB
-        * register save area.
-        */
+       movi    ARG1, XTENSA_IRQ_SYSCALL                        /* Argument 1: 
IRQ number */
+       mov             ARG2, a12                                               
        /* Argument 2: Top of stack = register save area */
+       CALL    xtensa_irq_dispatch                                     /* Call 
xtensa_int_decode */
 
-#else
-       movi    a6, XTENSA_IRQ_SYSCALL                  /* Argument 1: IRQ 
number */
-       mov             a7, a12                                                 
/* Argument 2: Top of stack = register save area */
-       call4   xtensa_irq_dispatch                             /* Call 
xtensa_int_decode */
-
-       /* On return from xtensa_irq_dispatch, A6 will contain the address of 
the new
-        * register save area.  Usually this would be the same as the current 
SP.
-        * But in the event of a context switch, A6 will instead refer to the 
TCB
-        * register save area.
+       /* xtensa_irq_dispatch returns the address of the new register save 
area.
+        * Usually this would be the same as the current SP. But in the event of
+        * a context switch, it will instead refer to the TCB register save 
area.
         */
 
-       mov             a2, a6                                                  
/* Switch to the new register save area */
-#endif
+       mov             a2, RETVAL                                              
        /* Switch to the new register save area */
 
        /* Restore registers in preparation to return from interrupt */
 
@@ -447,15 +427,9 @@ _xtensa_coproc_handler:
         * beginning of the register save area.
         */
 
-#ifdef __XTENSA_CALL0_ABI__
-       rsr             a2, EXCCAUSE                                    /* 
Argument 1 (a2) = EXCCAUSE */
-       mov             a3, sp                                                  
/* Argument 2 (a2) = pointer to register save area */
-       calx0   xtensa_user_panic                               /* Call 
xtensa_user_panic */
-#else
-       rsr             a6, EXCCAUSE                                    /* 
Argument 1 (a2) = EXCCAUSE */
-       mov             a7, sp                                                  
/* Argument 2 (a2) = pointer to register save area */
-       call4   xtensa_user_panic                               /* Call 
xtensa_user_panic */
-#endif
+       rsr             ARG1, EXCCAUSE                                  /* 
Argument 1 = EXCCAUSE */
+       mov             ARG2, sp                                                
/* Argument 2 = pointer to register save area */
+       CALL    xtensa_user_panic                               /* Call 
xtensa_user_panic */
 
        /* xtensa_user_panic should not return */
 

Reply via email to