From 37d94f4f4ea2fb0770c782d6d1c7aa2cd8a1fb7f Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Sun, 23 Aug 2015 20:46:58 +0200 Subject: [PATCH] ck_pr/arm : Add load, store and CAS for double. --- include/gcc/arm/ck_f_pr.h | 4 + include/gcc/arm/ck_pr.h | 156 +++++++++++++++++++++----------------- 2 files changed, 91 insertions(+), 69 deletions(-) diff --git a/include/gcc/arm/ck_f_pr.h b/include/gcc/arm/ck_f_pr.h index 0b9fe82..c508f85 100644 --- a/include/gcc/arm/ck_f_pr.h +++ b/include/gcc/arm/ck_f_pr.h @@ -23,6 +23,8 @@ #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) #define CK_F_PR_CAS_64 #define CK_F_PR_CAS_64_VALUE +#define CK_F_PR_CAS_DOUBLE +#define CK_F_PR_CAS_DOUBLE_VALUE #endif #define CK_F_PR_CAS_8 #define CK_F_PR_CAS_8_VALUE @@ -97,6 +99,7 @@ #define CK_F_PR_LOAD_32 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) #define CK_F_PR_LOAD_64 +#define CK_F_PR_LOAD_DOUBLE #endif #define CK_F_PR_LOAD_8 #define CK_F_PR_LOAD_CHAR @@ -133,6 +136,7 @@ #define CK_F_PR_STORE_32 #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) #define CK_F_PR_STORE_64 +#define CK_F_PR_STORE_DOUBLE #endif #define CK_F_PR_STORE_8 #define CK_F_PR_STORE_CHAR diff --git a/include/gcc/arm/ck_pr.h b/include/gcc/arm/ck_pr.h index 3fb303a..89f0c4d 100644 --- a/include/gcc/arm/ck_pr.h +++ b/include/gcc/arm/ck_pr.h @@ -133,18 +133,22 @@ CK_PR_LOAD_S(char, char, "ldrb") #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) -CK_CC_INLINE static uint64_t -ck_pr_md_load_64(const uint64_t *target) -{ - register uint64_t ret; - - __asm __volatile("ldrexd %0, [%1]" - : "=&r" (ret) - : "r" (target) - : "memory", "cc"); - return (ret); -} - +#define CK_PR_DOUBLE_LOAD(T, N) \ +CK_CC_INLINE static T \ +ck_pr_md_load_##N(const T *target) \ +{ \ + register T ret; \ + \ + __asm __volatile("ldrexd %0, [%1]" \ + : "=&r" (ret) \ + : "r" (target) \ + : "memory", "cc"); \ + return (ret); \ +} + +CK_PR_DOUBLE_LOAD(uint64_t, 64) +CK_PR_DOUBLE_LOAD(double, double) +#undef CK_PR_DOUBLE_LOAD #endif #define CK_PR_STORE(S, M, T, C, I) \ @@ -176,44 +180,56 @@ CK_PR_STORE_S(char, char, "strb") #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) -CK_CC_INLINE static void -ck_pr_md_store_64(const uint64_t *target, uint64_t value) -{ - uint64_t tmp; - uint32_t flag; - __asm __volatile("1: \n" - "ldrexd %0, [%2]\n" - "strexd %1, %3, [%2]\n" - "teq %1, #0\n" - "it ne \n" - "bne 1b\n" - : "=&r" (tmp), "=&r" (flag) - : "r" (target), "r" (value) - : "memory", "cc"); +#define CK_PR_DOUBLE_STORE(T, N) \ +CK_CC_INLINE static void \ +ck_pr_md_store_##N(const T *target, T value) \ +{ \ + T tmp; \ + uint32_t flag; \ + __asm __volatile("1: \n" \ + "ldrexd %0, [%2]\n" \ + "strexd %1, %3, [%2]\n" \ + "teq %1, #0\n" \ + "it ne \n" \ + "bne 1b\n" \ + : "=&r" (tmp), "=&r" (flag) \ + : "r" (target), "r" (value) \ + : "memory", "cc"); \ } -CK_CC_INLINE static bool -ck_pr_cas_64_value(uint64_t *target, uint64_t compare, uint64_t set, uint64_t *value) -{ - uint64_t previous; - int tmp; - - __asm__ __volatile__("1:" - "ldrexd %0, [%4];" - "cmp %Q0, %Q2;" - "ittt eq;" - "cmpeq %R0, %R2;" - "strexdeq %1, %3, [%4];" - "cmpeq %1, #1;" - "beq 1b;" - :"=&r" (previous), "=&r" (tmp) - : "r" (compare), "r" (set) , - "r"(target) - : "memory", "cc", "r4", "r5", "r6"); - *value = previous; - return (*value == compare); +CK_PR_DOUBLE_STORE(uint64_t, 64) +CK_PR_DOUBLE_STORE(double, double) + +#undef CK_PR_DOUBLE_STORE + +#define CK_PR_DOUBLE_CAS_VALUE(T, N) \ +CK_CC_INLINE static bool \ +ck_pr_cas_##N##_value(T *target, T compare, T set, T *value) \ +{ \ + T previous; \ + int tmp; \ + \ + __asm__ __volatile__("1:" \ + "ldrexd %0, [%4];" \ + "cmp %Q0, %Q2;" \ + "ittt eq;" \ + "cmpeq %R0, %R2;" \ + "strexdeq %1, %3, [%4];" \ + "cmpeq %1, #1;" \ + "beq 1b;" \ + :"=&r" (previous), "=&r" (tmp) \ + : "r" (compare), "r" (set) , \ + "r"(target) \ + : "memory", "cc"); \ + *value = previous; \ + return (*value == compare); \ } +CK_PR_DOUBLE_CAS_VALUE(uint64_t, 64) +CK_PR_DOUBLE_CAS_VALUE(double, double) + +#undef CK_PR_DOUBLE_CAS_VALUE + CK_CC_INLINE static bool ck_pr_cas_ptr_2_value(void *target, void *compare, void *set, void *value) { @@ -228,31 +244,33 @@ ck_pr_cas_ptr_2_value(void *target, void *compare, void *set, void *value) CK_CPP_CAST(uint64_t *, value))); } - -CK_CC_INLINE static bool -ck_pr_cas_64(uint64_t *target, uint64_t compare, uint64_t set) -{ - int ret; - uint64_t tmp; - - __asm__ __volatile__("1:" - "mov %0, #0;" - "ldrexd %1, [%4];" - "cmp %Q1, %Q2;" - "itttt eq;" - "cmpeq %R1, %R2;" - "strexdeq %1, %3, [%4];" - "moveq %0, #1;" - "cmpeq %1, #1;" - "beq 1b;" - : "=&r" (ret), "=&r" (tmp) - : "r" (compare), "r" (set) , - "r"(target) - : "memory", "cc"); - - return (ret); +#define CK_PR_DOUBLE_CAS(T, N) \ +CK_CC_INLINE static bool \ +ck_pr_cas_##N(T *target, T compare, T set) \ +{ \ + int ret; \ + T tmp; \ + \ + __asm__ __volatile__("1:" \ + "mov %0, #0;" \ + "ldrexd %1, [%4];" \ + "cmp %Q1, %Q2;" \ + "itttt eq;" \ + "cmpeq %R1, %R2;" \ + "strexdeq %1, %3, [%4];" \ + "moveq %0, #1;" \ + "cmpeq %1, #1;" \ + "beq 1b;" \ + : "=&r" (ret), "=&r" (tmp) \ + : "r" (compare), "r" (set) , \ + "r"(target) \ + : "memory", "cc"); \ + \ + return (ret); \ } +CK_PR_DOUBLE_CAS(uint64_t, 64) +CK_PR_DOUBLE_CAS(double, double) CK_CC_INLINE static bool ck_pr_cas_ptr_2(void *target, void *compare, void *set) {