9#ifndef BOTAN_LOAD_STORE_H__
10#define BOTAN_LOAD_STORE_H__
12#include <botan/types.h>
13#include <botan/bswap.h>
14#include <botan/get_byte.h>
17#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
19#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
21#define BOTAN_ENDIAN_N2B(x) (x)
22#define BOTAN_ENDIAN_B2N(x) (x)
24#define BOTAN_ENDIAN_N2L(x) reverse_bytes(x)
25#define BOTAN_ENDIAN_L2N(x) reverse_bytes(x)
27#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
29#define BOTAN_ENDIAN_N2L(x) (x)
30#define BOTAN_ENDIAN_L2N(x) (x)
32#define BOTAN_ENDIAN_N2B(x) reverse_bytes(x)
33#define BOTAN_ENDIAN_B2N(x) reverse_bytes(x)
49 return ((
static_cast<u16bit>(i0) << 8) | i1);
62 return ((
static_cast<u32bit>(i0) << 24) |
63 (
static_cast<u32bit>(i1) << 16) |
64 (
static_cast<u32bit>(i2) << 8) |
65 (
static_cast<u32bit>(i3)));
81 byte i4,
byte i5,
byte i6,
byte i7)
83 return ((
static_cast<u64bit>(i0) << 56) |
84 (
static_cast<u64bit>(i1) << 48) |
85 (
static_cast<u64bit>(i2) << 40) |
86 (
static_cast<u64bit>(i3) << 32) |
87 (
static_cast<u64bit>(i4) << 24) |
88 (
static_cast<u64bit>(i5) << 16) |
89 (
static_cast<u64bit>(i6) << 8) |
90 (
static_cast<u64bit>(i7)));
102 in += off *
sizeof(T);
104 for(
size_t i = 0; i !=
sizeof(T); ++i)
105 out = (out << 8) | in[i];
118 in += off *
sizeof(T);
120 for(
size_t i = 0; i !=
sizeof(T); ++i)
121 out = (out << 8) | in[
sizeof(T)-1-i];
134#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
135 return BOTAN_ENDIAN_N2B(*(
reinterpret_cast<const u16bit*
>(in) + off));
137 in += off *
sizeof(
u16bit);
151#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
152 return BOTAN_ENDIAN_N2L(*(
reinterpret_cast<const u16bit*
>(in) + off));
154 in += off *
sizeof(
u16bit);
168#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
169 return BOTAN_ENDIAN_N2B(*(
reinterpret_cast<const u32bit*
>(in) + off));
171 in += off *
sizeof(
u32bit);
185#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
186 return BOTAN_ENDIAN_N2L(*(
reinterpret_cast<const u32bit*
>(in) + off));
188 in += off *
sizeof(
u32bit);
202#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
203 return BOTAN_ENDIAN_N2B(*(
reinterpret_cast<const u64bit*
>(in) + off));
205 in += off *
sizeof(
u64bit);
207 in[4], in[5], in[6], in[7]);
220#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
221 return BOTAN_ENDIAN_N2L(*(
reinterpret_cast<const u64bit*
>(in) + off));
223 in += off *
sizeof(
u64bit);
225 in[3], in[2], in[1], in[0]);
236inline void load_le(
const byte in[], T& x0, T& x1)
252 T& x0, T& x1, T& x2, T& x3)
274 T& x0, T& x1, T& x2, T& x3,
275 T& x4, T& x5, T& x6, T& x7)
298#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS)
299 std::memcpy(out, in,
sizeof(T)*count);
301#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
302 const size_t blocks = count - (count % 4);
303 const size_t left = count - blocks;
305 for(
size_t i = 0; i != blocks; i += 4)
308 for(
size_t i = 0; i != left; ++i)
313 for(
size_t i = 0; i != count; ++i)
325inline void load_be(
const byte in[], T& x0, T& x1)
341 T& x0, T& x1, T& x2, T& x3)
363 T& x0, T& x1, T& x2, T& x3,
364 T& x4, T& x5, T& x6, T& x7)
387#if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS)
388 std::memcpy(out, in,
sizeof(T)*count);
390#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
391 const size_t blocks = count - (count % 4);
392 const size_t left = count - blocks;
394 for(
size_t i = 0; i != blocks; i += 4)
397 for(
size_t i = 0; i != left; ++i)
402 for(
size_t i = 0; i != count; ++i)
414#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
415 *
reinterpret_cast<u16bit*
>(out) = BOTAN_ENDIAN_B2N(in);
429#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
430 *
reinterpret_cast<u16bit*
>(out) = BOTAN_ENDIAN_L2N(in);
444#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
445 *
reinterpret_cast<u32bit*
>(out) = BOTAN_ENDIAN_B2N(in);
461#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
462 *
reinterpret_cast<u32bit*
>(out) = BOTAN_ENDIAN_L2N(in);
478#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
479 *
reinterpret_cast<u64bit*
>(out) = BOTAN_ENDIAN_B2N(in);
499#if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK
500 *
reinterpret_cast<u64bit*
>(out) = BOTAN_ENDIAN_L2N(in);
522 store_le(x0, out + (0 *
sizeof(T)));
523 store_le(x1, out + (1 *
sizeof(T)));
535 store_be(x0, out + (0 *
sizeof(T)));
536 store_be(x1, out + (1 *
sizeof(T)));
548inline void store_le(
byte out[], T x0, T x1, T x2, T x3)
550 store_le(x0, out + (0 *
sizeof(T)));
551 store_le(x1, out + (1 *
sizeof(T)));
552 store_le(x2, out + (2 *
sizeof(T)));
553 store_le(x3, out + (3 *
sizeof(T)));
565inline void store_be(
byte out[], T x0, T x1, T x2, T x3)
567 store_be(x0, out + (0 *
sizeof(T)));
568 store_be(x1, out + (1 *
sizeof(T)));
569 store_be(x2, out + (2 *
sizeof(T)));
570 store_be(x3, out + (3 *
sizeof(T)));
586inline void store_le(
byte out[], T x0, T x1, T x2, T x3,
587 T x4, T x5, T x6, T x7)
589 store_le(x0, out + (0 *
sizeof(T)));
590 store_le(x1, out + (1 *
sizeof(T)));
591 store_le(x2, out + (2 *
sizeof(T)));
592 store_le(x3, out + (3 *
sizeof(T)));
593 store_le(x4, out + (4 *
sizeof(T)));
594 store_le(x5, out + (5 *
sizeof(T)));
595 store_le(x6, out + (6 *
sizeof(T)));
596 store_le(x7, out + (7 *
sizeof(T)));
612inline void store_be(
byte out[], T x0, T x1, T x2, T x3,
613 T x4, T x5, T x6, T x7)
615 store_be(x0, out + (0 *
sizeof(T)));
616 store_be(x1, out + (1 *
sizeof(T)));
617 store_be(x2, out + (2 *
sizeof(T)));
618 store_be(x3, out + (3 *
sizeof(T)));
619 store_be(x4, out + (4 *
sizeof(T)));
620 store_be(x5, out + (5 *
sizeof(T)));
621 store_be(x6, out + (6 *
sizeof(T)));
622 store_be(x7, out + (7 *
sizeof(T)));
u16bit reverse_bytes(u16bit val)
byte get_byte(size_t byte_num, T input)
T load_be(const byte in[], size_t off)
u64bit make_u64bit(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7)
unsigned long long u64bit
u32bit make_u32bit(byte i0, byte i1, byte i2, byte i3)
T load_le(const byte in[], size_t off)
u16bit make_u16bit(byte i0, byte i1)
void store_be(u16bit in, byte out[2])
void store_le(u16bit in, byte out[2])