X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Funaligned.h;h=f1aab23adc814b8ac3dd7b29955228548e394405;hb=6da1e8091eb2e19de7ba5e0c73ac3e7dd437743d;hp=4540c31bbb6e690003cf84ecc666a58947ee3ea3;hpb=10a24935c9d382e4d85b05d9616843f3d3bb4983;p=sliver-openvswitch.git diff --git a/lib/unaligned.h b/lib/unaligned.h index 4540c31bb..f1aab23ad 100644 --- a/lib/unaligned.h +++ b/lib/unaligned.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Nicira Networks. + * Copyright (c) 2010, 2011 Nicira Networks. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ #include #include "byte-order.h" +#include "openvswitch/types.h" /* Public API. */ static inline uint16_t get_unaligned_u16(const uint16_t *); @@ -28,33 +29,44 @@ static inline void put_unaligned_u16(uint16_t *, uint16_t); static inline void put_unaligned_u32(uint32_t *, uint32_t); static inline void put_unaligned_u64(uint64_t *, uint64_t); +static inline ovs_be16 get_unaligned_be16(const ovs_be16 *); +static inline ovs_be32 get_unaligned_be32(const ovs_be32 *); +static inline ovs_be64 get_unaligned_be64(const ovs_be64 *); +static inline void put_unaligned_be16(ovs_be16 *, ovs_be16); +static inline void put_unaligned_be32(ovs_be32 *, ovs_be32); +static inline void put_unaligned_be64(ovs_be64 *, ovs_be64); + #ifdef __GNUC__ /* GCC implementations. */ -#define GCC_UNALIGNED_ACCESSORS(SIZE) \ -struct unaligned_u##SIZE { \ - uint##SIZE##_t x __attribute__((__packed__)); \ -}; \ -static inline struct unaligned_u##SIZE * \ -unaligned_u##SIZE(const uint##SIZE##_t *p) \ -{ \ - return (struct unaligned_u##SIZE *) p; \ -} \ - \ -static inline uint##SIZE##_t \ -get_unaligned_u##SIZE(const uint##SIZE##_t *p) \ -{ \ - return unaligned_u##SIZE(p)->x; \ -} \ - \ -static inline void \ -put_unaligned_u##SIZE(uint##SIZE##_t *p, uint##SIZE##_t x) \ -{ \ - unaligned_u##SIZE(p)->x = x; \ +#define GCC_UNALIGNED_ACCESSORS(TYPE, ABBREV) \ +struct unaligned_##ABBREV { \ + TYPE x __attribute__((__packed__)); \ +}; \ +static inline struct unaligned_##ABBREV * \ +unaligned_##ABBREV(const TYPE *p) \ +{ \ + return (struct unaligned_##ABBREV *) p; \ +} \ + \ +static inline TYPE \ +get_unaligned_##ABBREV(const TYPE *p) \ +{ \ + return unaligned_##ABBREV(p)->x; \ +} \ + \ +static inline void \ +put_unaligned_##ABBREV(TYPE *p, TYPE x) \ +{ \ + unaligned_##ABBREV(p)->x = x; \ } -GCC_UNALIGNED_ACCESSORS(16); -GCC_UNALIGNED_ACCESSORS(32); -GCC_UNALIGNED_ACCESSORS(64); +GCC_UNALIGNED_ACCESSORS(uint16_t, u16); +GCC_UNALIGNED_ACCESSORS(uint32_t, u32); +GCC_UNALIGNED_ACCESSORS(uint64_t, u64); + +GCC_UNALIGNED_ACCESSORS(ovs_be16, be16); +GCC_UNALIGNED_ACCESSORS(ovs_be32, be32); +GCC_UNALIGNED_ACCESSORS(ovs_be64, be64); #else /* Generic implementations. */ @@ -117,6 +129,62 @@ static inline void put_unaligned_u64(uint64_t *p_, uint64_t x_) p[6] = x >> 8; p[7] = x; } + +/* Only sparse cares about the difference between uint_t and ovs_be, and + * that takes the GCC branch, so there's no point in working too hard on these + * accessors. */ +#define get_unaligned_be16 get_unaligned_u16 +#define get_unaligned_be32 get_unaligned_u32 +#define get_unaligned_be64 get_unaligned_u64 +#define put_unaligned_be16 put_unaligned_u16 +#define put_unaligned_be32 put_unaligned_u32 +#define put_unaligned_be64 put_unaligned_u64 +#endif + +/* Returns the value in 'x'. */ +static inline uint64_t +get_32aligned_u64(const ovs_32aligned_u64 *x) +{ + return ((uint64_t) x->hi << 32) | x->lo; +} + +/* Stores 'value' in 'x'. */ +static inline void +put_32aligned_u64(ovs_32aligned_u64 *x, uint64_t value) +{ + x->hi = value >> 32; + x->lo = value; +} + +#ifndef __CHECKER__ +/* Returns the value of 'x'. */ +static inline ovs_be64 +get_32aligned_be64(const ovs_32aligned_be64 *x) +{ +#ifdef WORDS_BIGENDIAN + return ((ovs_be64) x->hi << 32) | x->lo; +#else + return ((ovs_be64) x->lo << 32) | x->hi; +#endif +} + +/* Stores network byte order 'value' into 'x'. */ +static inline void +put_32aligned_be64(ovs_32aligned_be64 *x, ovs_be64 value) +{ +#if WORDS_BIGENDIAN + x->hi = value >> 32; + x->lo = value; +#else + x->hi = value; + x->lo = value >> 32; +#endif +} +#else /* __CHECKER__ */ +/* Making sparse happy with these functions also makes them unreadable, so + * don't bother to show it their implementations. */ +ovs_be64 get_32aligned_be64(const ovs_32aligned_be64 *); +void put_32aligned_be64(ovs_32aligned_be64 *, ovs_be64); #endif #endif /* unaligned.h */