Module Name: src
Committed By: nakayama
Date: Sat Dec 5 07:58:57 UTC 2009
Modified Files:
src/sys/arch/sparc64/include: ctlreg.h
Log Message:
Bring together similar inline asm codes of ld*a and st*a definitions
using macro, also remove unnecessary membar #Sync and %asi restore in
the case of 32-bit kernel.
While there, introduce an optimization case that asi is constant if
we are using gcc.
To generate a diff of this commit:
cvs rdiff -u -r1.46 -r1.47 src/sys/arch/sparc64/include/ctlreg.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/sparc64/include/ctlreg.h
diff -u src/sys/arch/sparc64/include/ctlreg.h:1.46 src/sys/arch/sparc64/include/ctlreg.h:1.47
--- src/sys/arch/sparc64/include/ctlreg.h:1.46 Sat Nov 28 21:07:02 2009
+++ src/sys/arch/sparc64/include/ctlreg.h Sat Dec 5 07:58:57 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: ctlreg.h,v 1.46 2009/11/28 21:07:02 mrg Exp $ */
+/* $NetBSD: ctlreg.h,v 1.47 2009/12/05 07:58:57 nakayama Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath
@@ -477,490 +477,372 @@
*/
#ifdef __arch64__
-static __inline u_char
-lduba(paddr_t loc, int asi)
-{
- register unsigned int _lduba_v;
-
- __asm volatile(
- "wr %2, %%g0, %%asi; "
- "lduba [%1]%%asi, %0 "
- : "=r" (_lduba_v)
- : "r" ((unsigned long)(loc)), "r" (asi));
- return (_lduba_v);
-}
-#else
-static __inline u_char
-lduba(paddr_t loc, int asi)
-{
- register unsigned int _lduba_v, _loc_hi, _pstate;
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "sllx %3,32,%0; "
- "rdpr %%pstate,%1; "
- "or %0,%2,%0; "
- "wrpr %1,8,%%pstate; "
- "membar #Sync; "
- "lduba [%0]%%asi,%0; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lduba_v), "=&r" (_pstate)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- } else {
- __asm volatile(
- "wr %3,%%g0,%%asi; "
- "sllx %2,32,%0; "
- "or %0,%1,%0; "
- "lduba [%0]%%asi,%0; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lduba_v)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- }
- return (_lduba_v);
+/* 64-bit kernel, non-constant */
+#define SPARC64_LD_NONCONST(ld) \
+ __asm volatile( \
+ "wr %2,%%g0,%%asi; " \
+ #ld " [%1]%%asi,%0 " \
+ : "=r" (_v) \
+ : "r" ((__uintptr_t)(loc)), "r" (asi))
+
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define SPARC64_LD_DEF(ld, type, vtype) \
+static __inline type ld(paddr_t loc, int asi) \
+{ \
+ vtype _v; \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ #ld " [%1]%2,%0 " \
+ : "=r" (_v) \
+ : "r" ((__uintptr_t)(loc)), "n" (asi)); \
+ else \
+ SPARC64_LD_NONCONST(ld); \
+ return _v; \
+}
+#else
+#define SPARC64_LD_DEF(ld, type, vtype) \
+static __inline type ld(paddr_t loc, int asi) \
+{ \
+ vtype _v; \
+ SPARC64_LD_NONCONST(ld); \
+ return _v; \
}
#endif
+#define SPARC64_LD_DEF64(ld, type) SPARC64_LD_DEF(ld, type, uint64_t)
-#ifdef __arch64__
-/* load half-word from alternate address space */
-static __inline u_short
-lduha(paddr_t loc, int asi)
-{
- register unsigned int _lduha_v;
-
- __asm volatile(
- "wr %2, %%g0, %%asi; "
- "lduha [%1]%%asi, %0 "
- : "=r" (_lduha_v)
- : "r" ((unsigned long)(loc)), "r" (asi));
- return (_lduha_v);
-}
-#else
-/* load half-word from alternate address space */
-static __inline u_short
-lduha(paddr_t loc, int asi) {
- register unsigned int _lduha_v, _loc_hi, _pstate;
-
- _loc_hi = (((uint64_t)loc)>>32);
+#else /* __arch64__ */
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "sllx %3,32,%0; "
- "rdpr %%pstate,%1; "
- "wrpr %1,8,%%pstate; "
- "or %0,%2,%0; "
- "membar #Sync; "
- "lduha [%0]%%asi,%0; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lduha_v), "=&r" (_pstate)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- } else {
- __asm volatile(
- "wr %3,%%g0,%%asi; "
- "sllx %2,32,%0; "
- "or %0,%1,%0; "
- "lduha [%0]%%asi,%0; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lduha_v)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- }
- return (_lduha_v);
+/* 32-bit kernel, MMU bypass, non-constant */
+#define SPARC64_LD_PHYS_NONCONST(ld) \
+ __asm volatile( \
+ "rdpr %%pstate,%1; " \
+ "sllx %3,32,%0; " \
+ "wrpr %1,8,%%pstate; " \
+ "or %0,%2,%0; " \
+ "wr %4,%%g0,%%asi; " \
+ #ld " [%0]%%asi,%0; " \
+ "wrpr %1,0,%%pstate " \
+ : "=&r" (_v), "=&r" (_pstate) \
+ : "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi))
+/* 32-bit kernel, non-constant */
+#define SPARC64_LD_NONCONST(ld) \
+ __asm volatile( \
+ "wr %2,%%g0,%%asi; " \
+ #ld " [%1]%%asi,%0 " \
+ : "=&r" (_v) \
+ : "r" ((uint32_t)(loc)), "r" (asi))
+/* 32-bit kernel, MMU bypass, non-constant, 64-bit value */
+#define SPARC64_LD_PHYS_NONCONST64(ld) \
+ __asm volatile( \
+ "rdpr %%pstate,%1; " \
+ "sllx %3,32,%0; " \
+ "wrpr %1,8,%%pstate; " \
+ "or %0,%2,%0; " \
+ "wr %4,%%g0,%%asi; " \
+ #ld " [%0]%%asi,%0; " \
+ "wrpr %1,0,%%pstate; " \
+ "srlx %0,32,%1; " \
+ "srl %0,0,%0 " \
+ : "=&r" (_vlo), "=&r" (_vhi) \
+ : "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi))
+/* 32-bit kernel, non-constant, 64-bit value */
+#define SPARC64_LD_NONCONST64(ld) \
+ __asm volatile( \
+ "wr %3,%%g0,%%asi; " \
+ #ld " [%2]%%asi,%0; " \
+ "srlx %0,32,%1; " \
+ "srl %0,0,%0 " \
+ : "=&r" (_vlo), "=&r" (_vhi) \
+ : "r" ((uint32_t)(loc)), "r" (asi))
+
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define SPARC64_LD_DEF(ld, type, vtype) \
+static __inline type ld(paddr_t loc, int asi) \
+{ \
+ vtype _v; \
+ uint32_t _hi, _pstate; \
+ if (PHYS_ASI(asi)) { \
+ _hi = (uint64_t)(loc) >> 32; \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ "rdpr %%pstate,%1; " \
+ "sllx %3,32,%0; " \
+ "wrpr %1,8,%%pstate; " \
+ "or %0,%2,%0; " \
+ #ld " [%0]%4,%0; " \
+ "wrpr %1,0,%%pstate; " \
+ : "=&r" (_v), "=&r" (_pstate) \
+ : "r" ((uint32_t)(loc)), "r" (_hi), \
+ "n" (asi)); \
+ else \
+ SPARC64_LD_PHYS_NONCONST(ld); \
+ } else { \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ #ld " [%1]%2,%0 " \
+ : "=&r" (_v) \
+ : "r" ((uint32_t)(loc)), "n" (asi)); \
+ else \
+ SPARC64_LD_NONCONST(ld); \
+ } \
+ return _v; \
+}
+#define SPARC64_LD_DEF64(ld, type) \
+static __inline type ld(paddr_t loc, int asi) \
+{ \
+ uint32_t _vlo, _vhi, _hi; \
+ if (PHYS_ASI(asi)) { \
+ _hi = (uint64_t)(loc) >> 32; \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ "rdpr %%pstate,%1; " \
+ "sllx %3,32,%0; " \
+ "wrpr %1,8,%%pstate; " \
+ "or %0,%2,%0; " \
+ #ld " [%0]%4,%0; " \
+ "wrpr %1,0,%%pstate; " \
+ "srlx %0,32,%1; " \
+ "srl %0,0,%0 " \
+ : "=&r" (_vlo), "=&r" (_vhi) \
+ : "r" ((uint32_t)(loc)), "r" (_hi), \
+ "n" (asi)); \
+ else \
+ SPARC64_LD_PHYS_NONCONST64(ld); \
+ } else { \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ #ld " [%2]%3,%0; " \
+ "srlx %0,32,%1; " \
+ "srl %0,0,%0 " \
+ : "=&r" (_vlo), "=&r" (_vhi) \
+ : "r" ((uint32_t)(loc)), "n" (asi)); \
+ else \
+ SPARC64_LD_NONCONST64(ld); \
+ } \
+ return ((uint64_t)_vhi << 32) | _vlo; \
+}
+#else
+#define SPARC64_LD_DEF(ld, type, vtype) \
+static __inline type ld(paddr_t loc, int asi) \
+{ \
+ vtype _v; \
+ uint32_t _hi, _pstate; \
+ if (PHYS_ASI(asi)) { \
+ _hi = (uint64_t)(loc) >> 32; \
+ SPARC64_LD_PHYS_NONCONST(ld); \
+ } else \
+ SPARC64_LD_NONCONST(ld); \
+ return _v; \
+}
+#define SPARC64_LD_DEF64(ld, type) \
+static __inline type ld(paddr_t loc, int asi) \
+{ \
+ uint32_t _vlo, _vhi, _hi; \
+ if (PHYS_ASI(asi)) { \
+ _hi = (uint64_t)(loc) >> 32; \
+ SPARC64_LD_PHYS_NONCONST64(ld); \
+ } else \
+ SPARC64_LD_NONCONST64(ld); \
+ return ((uint64_t)_vhi << 32) | _vlo; \
}
#endif
+#endif /* __arch64__ */
-#ifdef __arch64__
-/* load unsigned int from alternate address space */
-static __inline u_int
-lda(paddr_t loc, int asi)
-{
- register unsigned int _lda_v;
-
- __asm volatile(
- "wr %2,%%g0,%%asi; "
- "lda [%1]%%asi,%0 "
- : "=r" (_lda_v)
- : "r" ((unsigned long)(loc)), "r" (asi));
- return (_lda_v);
-}
-
-/* load signed int from alternate address space */
-static __inline int
-ldswa(paddr_t loc, int asi)
-{
- register int _lda_v;
-
- __asm volatile(
- "wr %2,%%g0,%%asi; "
- "ldswa [%1]%%asi,%0; "
- : "=r" (_lda_v)
- : "r" ((unsigned long)(loc)), "r" (asi));
- return (_lda_v);
-}
-#else /* __arch64__ */
+/* load byte from alternate address space */
+SPARC64_LD_DEF(lduba, uint8_t, uint32_t)
+/* load half-word from alternate address space */
+SPARC64_LD_DEF(lduha, uint16_t, uint32_t)
/* load unsigned int from alternate address space */
-static __inline u_int
-lda(paddr_t loc, int asi)
-{
- register unsigned int _lda_v, _loc_hi, _pstate;
-
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "rdpr %%pstate,%1; "
- "sllx %3,32,%0; "
- "wrpr %1,8,%%pstate; "
- "or %0,%2,%0; "
- "membar #Sync; "
- "lda [%0]%%asi,%0; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lda_v), "=&r" (_pstate)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- } else {
- __asm volatile(
- "wr %3,%%g0,%%asi; "
- "sllx %2,32,%0; "
- "or %0,%1,%0; "
- "lda [%0]%%asi,%0; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lda_v)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- }
- return (_lda_v);
-}
-
+SPARC64_LD_DEF(lda, uint32_t, uint32_t)
/* load signed int from alternate address space */
-static __inline int
-ldswa(paddr_t loc, int asi)
-{
- register int _lda_v, _loc_hi, _pstate;
-
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "rdpr %%pstate,%1; "
- "wrpr %1,8,%%pstate; "
- "sllx %3,32,%0; "
- " or %0,%2,%0; "
- "membar #Sync; "
- "ldswa [%0]%%asi,%0; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lda_v), "=&r" (_pstate)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- } else {
- __asm volatile(
- "wr %3,%%g0,%%asi; "
- "sllx %2,32,%0; "
- "or %0,%1,%0; "
- "ldswa [%0]%%asi,%0; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lda_v)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- }
- return (_lda_v);
-}
-#endif /* __arch64__ */
-
-#ifdef __arch64__
-/* load 64-bit int from alternate address space -- these should never be used */
-static __inline uint64_t
-ldda(paddr_t loc, int asi)
-{
- register long long _lda_v;
-
- __asm volatile(
- "wr %2,%%g0,%%asi; "
- "ldda [%1]%%asi,%0 "
- : "=r" (_lda_v)
- : "r" ((unsigned long)(loc)), "r" (asi));
- return (_lda_v);
-}
-#else
-/* load 64-bit int from alternate address space */
-static __inline uint64_t
-ldda(paddr_t loc, int asi)
-{
- register long long _lda_v, _loc_hi, _pstate;
-
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "rdpr %%pstate,%1; "
- "wrpr %1,8,%%pstate; "
- "sllx %3,32,%0; "
- "or %0,%2,%0; "
- "membar #Sync; "
- "ldda [%0]%%asi,%0; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lda_v), "=&r" (_pstate)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- } else {
- __asm volatile(
- "wr %3,%%g0,%%asi; "
- "sllx %2,32,%0; "
- " or %0,%1,%0; "
- "ldda [%0]%%asi,%0; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_lda_v)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- }
- return (_lda_v);
-}
-#endif
+SPARC64_LD_DEF(ldswa, int, int)
+/* load 64-bit unsigned int from alternate address space */
+SPARC64_LD_DEF64(ldxa, uint64_t)
#ifdef __arch64__
-/* native load 64-bit int from alternate address space w/64-bit compiler*/
-static __inline uint64_t
-ldxa(paddr_t loc, int asi)
-{
- register unsigned long _lda_v;
-
- __asm volatile(
- "wr %2,%%g0,%%asi; "
- "ldxa [%1]%%asi,%0 "
- : "=r" (_lda_v)
- : "r" ((unsigned long)(loc)), "r" (asi));
- return (_lda_v);
-}
-#else
-/* native load 64-bit int from alternate address space w/32-bit compiler*/
-static __inline uint64_t
-ldxa(paddr_t loc, int asi)
-{
- register unsigned long _ldxa_lo, _ldxa_hi, _loc_hi;
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "rdpr %%pstate,%1; "
- "sllx %3,32,%0; "
- "wrpr %1,8,%%pstate; "
- "or %0, %2, %0; "
- "membar #Sync; "
- "ldxa [%0]%%asi,%0; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "srlx %0, 32, %1; "
- "srl %0, 0, %0; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_ldxa_lo), "=&r" (_ldxa_hi)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- } else {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "sllx %3,32,%0; "
- "or %0,%2,%0; "
- "ldxa [%0]%%asi,%0; "
- "srlx %0,32,%1; "
- "srl %0, 0, %0; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_ldxa_lo), "=&r" (_ldxa_hi)
- : "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- }
- return ((((int64_t)_ldxa_hi)<<32)|_ldxa_lo);
+/* 64-bit kernel, non-constant */
+#define SPARC64_ST_NONCONST(st) \
+ __asm volatile( \
+ "wr %2,%%g0,%%asi; " \
+ #st " %0,[%1]%%asi " \
+ : : "r" (value), "r" ((__uintptr_t)(loc)), \
+ "r" (asi))
+
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define SPARC64_ST_DEF(st, type) \
+static __inline void st(paddr_t loc, int asi, type value) \
+{ \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ #st " %0,[%1]%2 " \
+ : : "r" (value), "r" ((__uintptr_t)(loc)), \
+ "n" (asi)); \
+ else \
+ SPARC64_ST_NONCONST(st); \
+}
+#else
+#define SPARC64_ST_DEF(st, type) \
+static __inline void st(paddr_t loc, int asi, type value) \
+{ \
+ SPARC64_ST_NONCONST(st); \
}
#endif
+#define SPARC64_ST_DEF64(st, type) SPARC64_ST_DEF(st, type)
-/* store byte to alternate address space */
-#ifdef __arch64__
-static __inline void
-stba(paddr_t loc, int asi, u_char value)
-{
- __asm volatile(
- "wr %2, %%g0, %%asi; "
- "stba %0, [%1]%%asi "
- : : "r" ((int)(value)), "r" ((unsigned long)(loc)), "r" (asi));
-}
-#else
-static __inline void
-stba(paddr_t loc, int asi, u_char value)
-{
- register int _loc_hi, _pstate;
-
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %5,%%g0,%%asi; "
- "sllx %4,32,%0; "
- "rdpr %%pstate,%1; "
- "or %3,%0,%0; "
- "wrpr %1,8,%%pstate; "
- "stba %2,[%0]%%asi; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi), "=&r" (_pstate)
- : "r" ((int)(value)), "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- } else {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "sllx %3,32,%0; "
- "or %2,%0,%0; "
- "stba %1,[%0]%%asi; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi)
- : "r" ((int)(value)), "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi));
- }
-}
-#endif
-
-/* store half-word to alternate address space */
-#ifdef __arch64__
-static __inline void
-stha(paddr_t loc, int asi, u_short value)
-{
- __asm volatile(
- "wr %2,%%g0,%%asi; "
- "stha %0,[%1]%%asi "
- : : "r" ((int)(value)), "r" ((unsigned long)(loc)),
- "r" (asi) : "memory");
-}
-#else
-static __inline void
-stha(paddr_t loc, int asi, u_short value)
-{
- register int _loc_hi, _pstate;
+#else /* __arch64__ */
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %5,%%g0,%%asi; "
- "sllx %4,32,%0; "
- "rdpr %%pstate,%1; "
- "or %3,%0,%0; "
- "wrpr %1,8,%%pstate; "
- "stha %2,[%0]%%asi; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi), "=&r" (_pstate)
- : "r" ((int)(value)), "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi)
- : "memory");
- } else {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "sllx %3,32,%0; "
- "or %2,%0,%0; "
- "stha %1,[%0]%%asi; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi)
- : "r" ((int)(value)), "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi)
- : "memory");
- }
+/* 32-bit kernel, MMU bypass, non-constant */
+#define SPARC64_ST_PHYS_NONCONST(st) \
+ __asm volatile( \
+ "rdpr %%pstate,%1; " \
+ "sllx %4,32,%0; " \
+ "wrpr %1,8,%%pstate; " \
+ "or %0,%3,%0; " \
+ "wr %5,%%g0,%%asi; " \
+ #st " %2,[%0]%%asi; " \
+ "wrpr %1,0,%%pstate " \
+ : "=&r" (_hi), "=&r" (_pstate) \
+ : "r" (value), "r" ((uint32_t)(loc)), \
+ "r" (_hi), "r" (asi))
+/* 32-bit kernel, non-constant */
+#define SPARC64_ST_NONCONST(st) \
+ __asm volatile( \
+ "wr %2,%%g0,%%asi; " \
+ #st " %0,[%1]%%asi " \
+ : : "r" (value), "r" ((uint32_t)(loc)), "r" (asi))
+/* 32-bit kernel, MMU bypass, non-constant, 64-bit value */
+#define SPARC64_ST_PHYS_NONCONST64(st) \
+ __asm volatile( \
+ "sllx %4,32,%1; " \
+ "sllx %6,32,%0; " \
+ "rdpr %%pstate,%2; " \
+ "or %1,%3,%1; " \
+ "wrpr %2,8,%%pstate; " \
+ "or %0,%5,%0; " \
+ "wr %7,%%g0,%%asi; " \
+ #st " %1,[%0]%%asi; " \
+ "wrpr %2,0,%%pstate " \
+ : "=&r" (_hi), "=&r" (_vhi), "=&r" (_vlo) \
+ : "r" (_vlo), "r" (_vhi), \
+ "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi))
+/* 32-bit kernel, non-constant, 64-bit value */
+#define SPARC64_ST_NONCONST64(st) \
+ __asm volatile( \
+ "sllx %2,32,%0; " \
+ "or %0,%1,%0; " \
+ "wr %4,%%g0,%%asi; " \
+ #st " %0,[%3]%%asi " \
+ : "=&r" (_vhi) \
+ : "r" (_vlo), "r" (_vhi), \
+ "r" ((uint32_t)(loc)), "r" (asi))
+
+#if defined(__GNUC__) && defined(__OPTIMIZE__)
+#define SPARC64_ST_DEF(st, type) \
+static __inline void st(paddr_t loc, int asi, type value) \
+{ \
+ uint32_t _hi, _pstate; \
+ if (PHYS_ASI(asi)) { \
+ _hi = (uint64_t)(loc) >> 32; \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ "sllx %4,32,%0; " \
+ "rdpr %%pstate,%1; " \
+ "or %0,%3,%0; " \
+ "wrpr %1,8,%%pstate; " \
+ #st " %2,[%0]%5; " \
+ "wrpr %1,0,%%pstate " \
+ : "=&r" (_hi), "=&r" (_pstate) \
+ : "r" (value), "r" ((uint32_t)(loc)), \
+ "r" (_hi), "n" (asi)); \
+ else \
+ SPARC64_ST_PHYS_NONCONST(st); \
+ } else { \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ #st " %0,[%1]%2 " \
+ : : "r" (value), "r" ((uint32_t)(loc)), \
+ "n" (asi)); \
+ else \
+ SPARC64_ST_NONCONST(st); \
+ } \
+}
+#define SPARC64_ST_DEF64(st, type) \
+static __inline void st(paddr_t loc, int asi, type value) \
+{ \
+ uint32_t _vlo, _vhi, _hi; \
+ _vlo = value; \
+ _vhi = (uint64_t)(value) >> 32; \
+ if (PHYS_ASI(asi)) { \
+ _hi = (uint64_t)(loc) >> 32; \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ "sllx %4,32,%1; " \
+ "sllx %6,32,%0; " \
+ "rdpr %%pstate,%2; " \
+ "or %1,%3,%1; " \
+ "or %0,%5,%0; " \
+ "wrpr %2,8,%%pstate; " \
+ #st " %1,[%0]%7; " \
+ "wrpr %2,0,%%pstate " \
+ : "=&r" (_hi), "=&r" (_vhi), "=&r" (_vlo) \
+ : "r" (_vlo), "r" (_vhi), \
+ "r" ((uint32_t)(loc)), "r" (_hi), \
+ "n" (asi)); \
+ else \
+ SPARC64_ST_PHYS_NONCONST64(st); \
+ } else { \
+ if (__builtin_constant_p(asi)) \
+ __asm volatile( \
+ "sllx %2,32,%0; " \
+ "or %0,%1,%0; " \
+ #st " %0,[%3]%4 " \
+ : "=&r" (_vhi) \
+ : "r" (_vlo), "r" (_vhi), \
+ "r" ((uint32_t)(loc)), "n" (asi)); \
+ else \
+ SPARC64_ST_NONCONST64(st); \
+ } \
+}
+#else
+#define SPARC64_ST_DEF(st, type) \
+static __inline void st(paddr_t loc, int asi, type value) \
+{ \
+ uint32_t _hi, _pstate; \
+ if (PHYS_ASI(asi)) { \
+ _hi = (uint64_t)(loc) >> 32; \
+ SPARC64_ST_PHYS_NONCONST(st); \
+ } else \
+ SPARC64_ST_NONCONST(st); \
+}
+#define SPARC64_ST_DEF64(st, type) \
+static __inline void st(paddr_t loc, int asi, type value) \
+{ \
+ uint32_t _vlo, _vhi, _hi; \
+ _vlo = value; \
+ _vhi = (uint64_t)(value) >> 32; \
+ if (PHYS_ASI(asi)) { \
+ _hi = (uint64_t)(loc) >> 32; \
+ SPARC64_ST_PHYS_NONCONST64(st); \
+ } else \
+ SPARC64_ST_NONCONST64(st); \
}
#endif
+#endif /* __arch64__ */
-/* store int to alternate address space */
-#ifdef __arch64__
-static __inline void
-sta(paddr_t loc, int asi, u_int value)
-{
- __asm volatile(
- "wr %2,%%g0,%%asi; "
- "sta %0,[%1]%%asi "
- : : "r" ((int)(value)), "r" ((unsigned long)(loc)),
- "r" (asi) : "memory");
-}
-#else
-static __inline void
-sta(paddr_t loc, int asi, u_int value)
-{
- register int _loc_hi, _pstate;
-
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %5,%%g0,%%asi; "
- "sllx %4,32,%0; "
- "rdpr %%pstate,%1; "
- "or %3,%0,%0; "
- "wrpr %1,8,%%pstate; "
- "sta %2,[%0]%%asi; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi), "=&r" (_pstate)
- : "r" ((int)(value)), "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi)
- : "memory");
- } else {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "sllx %3,32,%0; "
- "or %2,%0,%0; "
- "sta %1,[%0]%%asi; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi)
- : "r" ((int)(value)), "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi)
- : "memory");
- }
-}
-#endif
-
-/* store 64-bit int to alternate address space */
-#ifdef __arch64__
-static __inline void
-stda(paddr_t loc, int asi, uint64_t value)
-{
- __asm volatile(
- "wr %2,%%g0,%%asi; "
- "stda %0,[%1]%%asi "
- : : "r" ((long long)(value)), "r" ((unsigned long)(loc)), "r" (asi)
- : "memory");
-}
-#else
-static __inline void
-stda(paddr_t loc, int asi, uint64_t value)
-{
- register int _loc_hi, _pstate;
+/* store byte to alternate address space */
+SPARC64_ST_DEF(stba, uint8_t)
+/* store half-word to alternate address space */
+SPARC64_ST_DEF(stha, uint16_t)
+/* store unsigned int to alternate address space */
+SPARC64_ST_DEF(sta, uint32_t)
+/* store 64-bit unsigned int to alternate address space */
+SPARC64_ST_DEF64(stxa, uint64_t)
- _loc_hi = (((uint64_t)loc)>>32);
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %5,%%g0,%%asi; "
- "sllx %4,32,%0; "
- "rdpr %%pstate,%1; "
- "or %3,%0,%0; "
- "wrpr %1,8,%%pstate; "
- "stda %2,[%0]%%asi; "
- "wrpr %1,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi), "=&r" (_pstate)
- : "r" ((long long)(value)), "r" ((unsigned long)(loc)),
- "r" (_loc_hi), "r" (asi)
- : "memory");
- } else {
- __asm volatile(
- "wr %4,%%g0,%%asi; "
- "sllx %3,32,%0; "
- "or %2,%0,%0; "
- "stda %1,[%0]%%asi; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi)
- : "r" ((long long)(value)), "r" ((unsigned long)(loc)),
- "r" (_loc_hi), "r" (asi)
- : "memory");
- }
-}
-#endif
/* set dmmu secondary context */
static __inline void
@@ -969,69 +851,11 @@
__asm volatile(
"stxa %0,[%1]%2; "
"membar #Sync "
- : : "r" (ctx),
- "r" (CTX_SECONDARY), "n" (ASI_DMMU)
+ : : "r" (ctx), "r" (CTX_SECONDARY), "n" (ASI_DMMU)
: "memory");
}
#ifdef __arch64__
-/* native store 64-bit int to alternate address space w/64-bit compiler*/
-static __inline void
-stxa(paddr_t loc, int asi, uint64_t value)
-{
- __asm volatile(
- "wr %2,%%g0,%%asi; "
- "stxa %0,[%1]%%asi "
- : : "r" ((unsigned long)(value)),
- "r" ((unsigned long)(loc)), "r" (asi)
- : "memory");
-}
-#else
-/* native store 64-bit int to alternate address space w/32-bit compiler*/
-static __inline void
-stxa(paddr_t loc, int asi, uint64_t value)
-{
- int _stxa_lo, _stxa_hi, _loc_hi;
-
- _stxa_lo = value;
- _stxa_hi = ((uint64_t)value)>>32;
- _loc_hi = (((uint64_t)loc)>>32);
-
- if (PHYS_ASI(asi)) {
- __asm volatile(
- "wr %7,%%g0,%%asi; "
- "sllx %4,32,%1; "
- "sllx %6,32,%0; "
- "or %1,%3,%1; "
- "rdpr %%pstate,%2; "
- "or %0,%5,%0; "
- "wrpr %2,8,%%pstate; "
- "stxa %1,[%0]%%asi; "
- "wrpr %2,0,%%pstate; "
- "membar #Sync; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi), "=&r" (_stxa_hi), "=&r" ((int)(_stxa_lo))
- : "r" ((int)(_stxa_lo)), "r" ((int)(_stxa_hi)),
- "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi)
- : "memory");
- } else {
- __asm volatile(
- "wr %6,%%g0,%%asi; "
- "sllx %3,32,%1; "
- "sllx %5,32,%0; "
- "or %1,%2,%1; "
- "or %0,%4,%0; "
- "stxa %1,[%0]%%asi; "
- "wr %%g0, 0x82, %%asi "
- : "=&r" (_loc_hi), "=&r" (_stxa_hi)
- : "r" ((int)(_stxa_lo)), "r" ((int)(_stxa_hi)),
- "r" ((unsigned long)(loc)), "r" (_loc_hi), "r" (asi)
- : "memory");
- }
-}
-#endif
-
-#ifdef __arch64__
/* native store 32-bit int to alternate address space w/64-bit compiler*/
static __inline uint32_t
casa(paddr_t loc, int asi, uint32_t value, uint32_t oldvalue)