Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
bswap: Add the ability to store to an unaligned 24 bit field
CXL has 24 bit unaligned fields which need to be stored to.  CXL is
specified as little endian.

Define st24_le_p() and the supporting functions to store such a field
from a 32 bit host native value.

The use of b, w, l, q as the size specifier is limiting.  So "24" was
used for the size part of the function name.

Reviewed-by: Fan Ni <fan.ni@samsung.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20230526170010.574-2-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
weiny2 authored and mstsirkin committed Jun 22, 2023
1 parent b455ce4 commit 14180d6
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/devel/loads-stores.rst
Expand Up @@ -36,6 +36,7 @@ store: ``st{size}_{endian}_p(ptr, val)``
``size``
- ``b`` : 8 bits
- ``w`` : 16 bits
- ``24`` : 24 bits
- ``l`` : 32 bits
- ``q`` : 64 bits
Expand Down Expand Up @@ -65,6 +66,7 @@ of size ``sz`` bytes.
Regexes for git grep
- ``\<ld[us]\?[bwlq]\(_[hbl]e\)\?_p\>``
- ``\<st[bwlq]\(_[hbl]e\)\?_p\>``
- ``\<st24\(_[hbl]e\)\?_p\>``
- ``\<ldn_\([hbl]e\)?_p\>``
- ``\<stn_\([hbl]e\)?_p\>``
Expand Down
25 changes: 25 additions & 0 deletions include/qemu/bswap.h
Expand Up @@ -8,11 +8,23 @@
#undef bswap64
#define bswap64(_x) __builtin_bswap64(_x)

static inline uint32_t bswap24(uint32_t x)
{
return (((x & 0x000000ffU) << 16) |
((x & 0x0000ff00U) << 0) |
((x & 0x00ff0000U) >> 16));
}

static inline void bswap16s(uint16_t *s)
{
*s = __builtin_bswap16(*s);
}

static inline void bswap24s(uint32_t *s)
{
*s = bswap24(*s & 0x00ffffffU);
}

static inline void bswap32s(uint32_t *s)
{
*s = __builtin_bswap32(*s);
Expand All @@ -26,11 +38,13 @@ static inline void bswap64s(uint64_t *s)
#if HOST_BIG_ENDIAN
#define be_bswap(v, size) (v)
#define le_bswap(v, size) glue(__builtin_bswap, size)(v)
#define le_bswap24(v) bswap24(v)
#define be_bswaps(v, size)
#define le_bswaps(p, size) \
do { *p = glue(__builtin_bswap, size)(*p); } while (0)
#else
#define le_bswap(v, size) (v)
#define le_bswap24(v) (v)
#define be_bswap(v, size) glue(__builtin_bswap, size)(v)
#define le_bswaps(v, size)
#define be_bswaps(p, size) \
Expand Down Expand Up @@ -176,6 +190,7 @@ CPU_CONVERT(le, 64, uint64_t)
* size is:
* b: 8 bits
* w: 16 bits
* 24: 24 bits
* l: 32 bits
* q: 64 bits
*
Expand Down Expand Up @@ -248,6 +263,11 @@ static inline void stw_he_p(void *ptr, uint16_t v)
__builtin_memcpy(ptr, &v, sizeof(v));
}

static inline void st24_he_p(void *ptr, uint32_t v)
{
__builtin_memcpy(ptr, &v, 3);
}

static inline int ldl_he_p(const void *ptr)
{
int32_t r;
Expand Down Expand Up @@ -297,6 +317,11 @@ static inline void stw_le_p(void *ptr, uint16_t v)
stw_he_p(ptr, le_bswap(v, 16));
}

static inline void st24_le_p(void *ptr, uint32_t v)
{
st24_he_p(ptr, le_bswap24(v));
}

static inline void stl_le_p(void *ptr, uint32_t v)
{
stl_he_p(ptr, le_bswap(v, 32));
Expand Down

0 comments on commit 14180d6

Please sign in to comment.