LCOV - code coverage report
Current view: top level - zephyr/arch/riscv - atomic.h Coverage Total Hit
Test: new.info Lines: 16.7 % 6 1
Test Date: 2025-09-05 20:47:19

            Line data    Source code
       1            0 : /**
       2              :  * Copyright (c) 2024 NextSilicon
       3              :  * SPDX-License-Identifier: Apache-2.0
       4              :  */
       5              : 
       6              : #ifndef ZEPHYR_INCLUDE_ARCH_RISCV_ATOMIC_H_
       7              : #define ZEPHYR_INCLUDE_ARCH_RISCV_ATOMIC_H_
       8              : 
       9              : #ifdef __cplusplus
      10              : extern "C" {
      11              : #endif
      12              : 
      13              : /* The standard RISC-V atomic-instruction extension, "A", specifies
      14              :  * the number of instructions that atomically read-modify-write memory,
      15              :  * which RISC-V harts should support in order to synchronise harts
      16              :  * running in the same memory space. This is the subset of RISC-V
      17              :  * atomic-instructions not present in atomic_builtin.h file.
      18              :  */
      19              : 
      20              : #ifdef CONFIG_64BIT
      21              : static ALWAYS_INLINE atomic_val_t atomic_swap(const atomic_t *target, atomic_val_t newval)
      22              : {
      23              :         atomic_val_t ret;
      24              : 
      25              :         __asm__ volatile("amoswap.d.aq  %0, %1, %2"
      26              :                          : "=r"(ret)
      27              :                          : "r"(newval), "A"(*target)
      28              :                          : "memory");
      29              : 
      30              :         return ret;
      31              : }
      32              : 
      33              : static ALWAYS_INLINE atomic_val_t atomic_max(atomic_t *target, atomic_val_t value)
      34              : {
      35              :         atomic_val_t ret;
      36              : 
      37              :         __asm__ volatile("amomax.d.aq  %0, %1, %2"
      38              :                          : "=r"(ret)
      39              :                          : "r"(value), "A"(*target)
      40              :                          : "memory");
      41              : 
      42              :         return ret;
      43              : }
      44              : 
      45              : static ALWAYS_INLINE atomic_val_t atomic_min(atomic_t *target, atomic_val_t value)
      46              : {
      47              :         atomic_val_t ret;
      48              : 
      49              :         __asm__ volatile("amomin.d.aq  %0, %1, %2"
      50              :                          : "=r"(ret)
      51              :                          : "r"(value), "A"(*target)
      52              :                          : "memory");
      53              : 
      54              :         return ret;
      55              : }
      56              : 
      57              : static ALWAYS_INLINE atomic_val_t atomic_maxu(unsigned long *target, unsigned long value)
      58              : {
      59              :         unsigned long ret;
      60              : 
      61              :         __asm__ volatile("amomaxu.d.aq  %0, %1, %2"
      62              :                          : "=r"(ret)
      63              :                          : "r"(value), "A"(*target)
      64              :                          : "memory");
      65              : 
      66              :         return ret;
      67              : }
      68              : 
      69              : static ALWAYS_INLINE atomic_val_t atomic_minu(unsigned long *target, unsigned long value)
      70              : {
      71              :         unsigned long ret;
      72              : 
      73              :         __asm__ volatile("amominu.d.aq  %0, %1, %2"
      74              :                          : "=r"(ret)
      75              :                          : "r"(value), "A"(*target)
      76              :                          : "memory");
      77              : 
      78              :         return ret;
      79              : }
      80              : 
      81              : #else
      82              : 
      83            1 : static ALWAYS_INLINE atomic_val_t atomic_swap(const atomic_t *target, atomic_val_t newval)
      84              : {
      85              :         atomic_val_t ret;
      86              : 
      87              :         __asm__ volatile("amoswap.w.aq  %0, %1, %2"
      88              :                          : "=r"(ret)
      89              :                          : "r"(newval), "A"(*target)
      90              :                          : "memory");
      91              : 
      92              :         return ret;
      93              : }
      94              : 
      95            0 : static ALWAYS_INLINE atomic_val_t atomic_max(atomic_t *target, atomic_val_t value)
      96              : {
      97              :         atomic_val_t ret;
      98              : 
      99              :         __asm__ volatile("amomax.w.aq  %0, %1, %2"
     100              :                          : "=r"(ret)
     101              :                          : "r"(value), "A"(*target)
     102              :                          : "memory");
     103              : 
     104              :         return ret;
     105              : }
     106              : 
     107            0 : static ALWAYS_INLINE atomic_val_t atomic_min(atomic_t *target, atomic_val_t value)
     108              : {
     109              :         atomic_val_t ret;
     110              : 
     111              :         __asm__ volatile("amomin.w.aq  %0, %1, %2"
     112              :                          : "=r"(ret)
     113              :                          : "r"(value), "A"(*target)
     114              :                          : "memory");
     115              : 
     116              :         return ret;
     117              : }
     118              : 
     119            0 : static ALWAYS_INLINE unsigned long atomic_maxu(unsigned long *target, unsigned long value)
     120              : {
     121              :         unsigned long ret;
     122              : 
     123              :         __asm__ volatile("amomaxu.w.aq  %0, %1, %2"
     124              :                          : "=r"(ret)
     125              :                          : "r"(value), "A"(*target)
     126              :                          : "memory");
     127              : 
     128              :         return ret;
     129              : }
     130              : 
     131            0 : static ALWAYS_INLINE unsigned long atomic_minu(unsigned long *target, unsigned long value)
     132              : {
     133              :         unsigned long ret;
     134              : 
     135              :         __asm__ volatile("amominu.w.aq  %0, %1, %2"
     136              :                          : "=r"(ret)
     137              :                          : "r"(value), "A"(*target)
     138              :                          : "memory");
     139              : 
     140              :         return ret;
     141              : }
     142              : 
     143              : #endif /* CONFIG_64BIT */
     144              : 
     145              : #ifdef __cplusplus
     146              : }
     147              : #endif
     148              : 
     149              : #endif /* ZEPHYR_INCLUDE_ARCH_RISCV_ATOMIC_H_ */
        

Generated by: LCOV version 2.0-1