linux/include/asm-generic/unaligned.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __ASM_GENERIC_UNALIGNED_H
   3#define __ASM_GENERIC_UNALIGNED_H
   4
   5/*
   6 * This is the most generic implementation of unaligned accesses
   7 * and should work almost anywhere.
   8 */
   9#include <linux/unaligned/packed_struct.h>
  10#include <asm/byteorder.h>
  11
  12#define __get_unaligned_t(type, ptr) ({                                         \
  13        const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);      \
  14        __pptr->x;                                                              \
  15})
  16
  17#define __put_unaligned_t(type, val, ptr) do {                                  \
  18        struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr);            \
  19        __pptr->x = (val);                                                      \
  20} while (0)
  21
  22#define get_unaligned(ptr)      __get_unaligned_t(typeof(*(ptr)), (ptr))
  23#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
  24
  25static inline u16 get_unaligned_le16(const void *p)
  26{
  27        return le16_to_cpu(__get_unaligned_t(__le16, p));
  28}
  29
  30static inline u32 get_unaligned_le32(const void *p)
  31{
  32        return le32_to_cpu(__get_unaligned_t(__le32, p));
  33}
  34
  35static inline u64 get_unaligned_le64(const void *p)
  36{
  37        return le64_to_cpu(__get_unaligned_t(__le64, p));
  38}
  39
  40static inline void put_unaligned_le16(u16 val, void *p)
  41{
  42        __put_unaligned_t(__le16, cpu_to_le16(val), p);
  43}
  44
  45static inline void put_unaligned_le32(u32 val, void *p)
  46{
  47        __put_unaligned_t(__le32, cpu_to_le32(val), p);
  48}
  49
  50static inline void put_unaligned_le64(u64 val, void *p)
  51{
  52        __put_unaligned_t(__le64, cpu_to_le64(val), p);
  53}
  54
  55static inline u16 get_unaligned_be16(const void *p)
  56{
  57        return be16_to_cpu(__get_unaligned_t(__be16, p));
  58}
  59
  60static inline u32 get_unaligned_be32(const void *p)
  61{
  62        return be32_to_cpu(__get_unaligned_t(__be32, p));
  63}
  64
  65static inline u64 get_unaligned_be64(const void *p)
  66{
  67        return be64_to_cpu(__get_unaligned_t(__be64, p));
  68}
  69
  70static inline void put_unaligned_be16(u16 val, void *p)
  71{
  72        __put_unaligned_t(__be16, cpu_to_be16(val), p);
  73}
  74
  75static inline void put_unaligned_be32(u32 val, void *p)
  76{
  77        __put_unaligned_t(__be32, cpu_to_be32(val), p);
  78}
  79
  80static inline void put_unaligned_be64(u64 val, void *p)
  81{
  82        __put_unaligned_t(__be64, cpu_to_be64(val), p);
  83}
  84
  85static inline u32 __get_unaligned_be24(const u8 *p)
  86{
  87        return p[0] << 16 | p[1] << 8 | p[2];
  88}
  89
  90static inline u32 get_unaligned_be24(const void *p)
  91{
  92        return __get_unaligned_be24(p);
  93}
  94
  95static inline u32 __get_unaligned_le24(const u8 *p)
  96{
  97        return p[0] | p[1] << 8 | p[2] << 16;
  98}
  99
 100static inline u32 get_unaligned_le24(const void *p)
 101{
 102        return __get_unaligned_le24(p);
 103}
 104
 105static inline void __put_unaligned_be24(const u32 val, u8 *p)
 106{
 107        *p++ = val >> 16;
 108        *p++ = val >> 8;
 109        *p++ = val;
 110}
 111
 112static inline void put_unaligned_be24(const u32 val, void *p)
 113{
 114        __put_unaligned_be24(val, p);
 115}
 116
 117static inline void __put_unaligned_le24(const u32 val, u8 *p)
 118{
 119        *p++ = val;
 120        *p++ = val >> 8;
 121        *p++ = val >> 16;
 122}
 123
 124static inline void put_unaligned_le24(const u32 val, void *p)
 125{
 126        __put_unaligned_le24(val, p);
 127}
 128
 129#endif /* __ASM_GENERIC_UNALIGNED_H */
 130