Make overly-clever SPR accessor functions that allow a non-constant
SPR number to be specified. This will be used to restructure test
in the next change.

Signed-off-by: Nicholas Piggin <npig...@gmail.com>
---
 powerpc/sprs.c | 63 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 54 insertions(+), 9 deletions(-)

diff --git a/powerpc/sprs.c b/powerpc/sprs.c
index 45f77a5..b633ea8 100644
--- a/powerpc/sprs.c
+++ b/powerpc/sprs.c
@@ -28,21 +28,66 @@
 #include <asm/processor.h>
 #include <asm/barrier.h>
 
-#define mfspr(nr) ({ \
-       uint64_t ret; \
-       asm volatile("mfspr %0,%1" : "=r"(ret) : "i"(nr)); \
-       ret; \
-})
+/* "Indirect" mfspr/mtspr which accept a non-constant spr number */
+static uint64_t mfspr(unsigned spr)
+{
+       uint64_t tmp;
+       uint64_t ret;
+
+       asm volatile(
+"      bcl     20, 31, 1f              \n"
+"1:    mflr    %0                      \n"
+"      addi    %0, %0, (2f-1b)         \n"
+"      add     %0, %0, %2              \n"
+"      mtctr   %0                      \n"
+"      bctr                            \n"
+"2:                                    \n"
+".LSPR=0                               \n"
+".rept 1024                            \n"
+"      mfspr   %1, .LSPR               \n"
+"      b       3f                      \n"
+"      .LSPR=.LSPR+1                   \n"
+".endr                                 \n"
+"3:                                    \n"
+       : "=&r"(tmp),
+         "=r"(ret)
+       : "r"(spr*8) /* 8 bytes per 'mfspr ; b' block */
+       : "lr", "ctr");
+
+       return ret;
+}
 
-#define mtspr(nr, val) \
-       asm volatile("mtspr %0,%1" : : "i"(nr), "r"(val))
+static void mtspr(unsigned spr, uint64_t val)
+{
+       uint64_t tmp;
+
+       asm volatile(
+"      bcl     20, 31, 1f              \n"
+"1:    mflr    %0                      \n"
+"      addi    %0, %0, (2f-1b)         \n"
+"      add     %0, %0, %2              \n"
+"      mtctr   %0                      \n"
+"      bctr                            \n"
+"2:                                    \n"
+".LSPR=0                               \n"
+".rept 1024                            \n"
+"      mtspr   .LSPR, %1               \n"
+"      b       3f                      \n"
+"      .LSPR=.LSPR+1                   \n"
+".endr                                 \n"
+"3:                                    \n"
+       : "=&r"(tmp)
+       : "r"(val),
+         "r"(spr*8) /* 8 bytes per 'mfspr ; b' block */
+       : "lr", "ctr", "xer");
+}
 
 uint64_t before[1024], after[1024];
 
 /* Common SPRs for all PowerPC CPUs */
 static void set_sprs_common(uint64_t val)
 {
-       mtspr(9, val);          /* CTR */
+       // mtspr(9, val);       /* CTR */ /* Used by mfspr/mtspr */
        // mtspr(273, val);     /* SPRG1 */  /* Used by our exception handler */
        mtspr(274, val);        /* SPRG2 */
        mtspr(275, val);        /* SPRG3 */
@@ -156,7 +201,7 @@ static void set_sprs(uint64_t val)
 
 static void get_sprs_common(uint64_t *v)
 {
-       v[9] = mfspr(9);        /* CTR */
+       v[9] = mfspr(9);        /* CTR */ /* Used by mfspr/mtspr */
        // v[273] = mfspr(273); /* SPRG1 */ /* Used by our exception handler */
        v[274] = mfspr(274);    /* SPRG2 */
        v[275] = mfspr(275);    /* SPRG3 */
-- 
2.37.2

Reply via email to