word.h 2.34 KB
Newer Older
Martin Schläffer committed
1 2 3 4 5
#ifndef WORD_H_
#define WORD_H_

#include <stdint.h>

Martin Schläffer committed
6
#include "endian.h"
Enrico Pozzobon committed
7
#include "forceinline.h"
Martin Schläffer committed
8
#include "interleave.h"
Martin Schläffer committed
9 10 11 12 13 14

typedef struct {
  uint32_t e;
  uint32_t o;
} word_t;

Enrico Pozzobon committed
15
forceinline uint32_t ROR32(uint32_t x, int n) {
Martin Schläffer committed
16 17 18
  return (n == 0) ? x : x >> n | x << (32 - n);
}

Enrico Pozzobon committed
19
forceinline word_t ROR(word_t x, int n) {
Martin Schläffer committed
20 21 22 23 24 25
  word_t r;
  r.e = (n % 2) ? ROR32(x.o, (n - 1) / 2) : ROR32(x.e, n / 2);
  r.o = (n % 2) ? ROR32(x.e, (n + 1) / 2) : ROR32(x.o, n / 2);
  return r;
}

Enrico Pozzobon committed
26
forceinline word_t WORD_T(uint64_t x) { return (word_t){.o = x >> 32, .e = x}; }
Martin Schläffer committed
27

Enrico Pozzobon committed
28
forceinline uint64_t UINT64_T(word_t x) { return (uint64_t)x.o << 32 | x.e; }
Martin Schläffer committed
29

Enrico Pozzobon committed
30
forceinline word_t U64TOWORD(uint64_t x) { return WORD_T(deinterleave32(x)); }
Martin Schläffer committed
31

Enrico Pozzobon committed
32
forceinline uint64_t WORDTOU64(word_t w) { return interleave32(UINT64_T(w)); }
Martin Schläffer committed
33

Enrico Pozzobon committed
34
forceinline word_t NOT(word_t a) {
Martin Schläffer committed
35 36 37
  a.e = ~a.e;
  a.o = ~a.o;
  return a;
Martin Schläffer committed
38 39
}

Enrico Pozzobon committed
40
forceinline word_t XOR(word_t a, word_t b) {
Martin Schläffer committed
41 42 43
  a.e ^= b.e;
  a.o ^= b.o;
  return a;
Martin Schläffer committed
44 45
}

Enrico Pozzobon committed
46
forceinline word_t AND(word_t a, word_t b) {
Martin Schläffer committed
47 48 49
  a.e &= b.e;
  a.o &= b.o;
  return a;
Martin Schläffer committed
50 51
}

Enrico Pozzobon committed
52
forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) {
Martin Schläffer committed
53 54
  word_t r;
  r.e = lo2hi.e << 16 | hi2lo.e >> 16;
Enrico Pozzobon committed
55
  r.o = lo2hi.o << 16 | hi2lo.o >> 16;
Martin Schläffer committed
56 57 58
  return r;
}

Enrico Pozzobon committed
59
forceinline int NOTZERO(word_t a, word_t b) {
Martin Schläffer committed
60 61 62
  uint32_t result = a.e | a.o | b.e | b.o;
  result |= result >> 16;
  result |= result >> 8;
Enrico Pozzobon committed
63
  return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1;
Martin Schläffer committed
64 65
}

Enrico Pozzobon committed
66 67
forceinline word_t PAD(int i) {
  return WORD_T((uint64_t)(0x8ul << (28 - 4 * i)) << 32);
Martin Schläffer committed
68 69
}

Enrico Pozzobon committed
70
forceinline word_t CLEAR(word_t w, int n) {
Martin Schläffer committed
71
  /* undefined for n == 0 */
Martin Schläffer committed
72
  uint32_t mask = 0x0fffffff >> (n * 4 - 4);
Enrico Pozzobon committed
73 74 75
  w.e &= mask;
  w.o &= mask;
  return w;
Martin Schläffer committed
76 77
}

Enrico Pozzobon committed
78
forceinline uint64_t MASK(int n) {
Martin Schläffer committed
79 80 81 82
  /* undefined for n == 0 */
  return ~0ull >> (64 - 8 * n);
}

Enrico Pozzobon committed
83
forceinline word_t LOAD(const uint8_t* bytes, int n) {
Martin Schläffer committed
84 85 86 87
  uint64_t x = *(uint64_t*)bytes & MASK(n);
  return U64TOWORD(U64BIG(x));
}

Enrico Pozzobon committed
88
forceinline void STORE(uint8_t* bytes, word_t w, int n) {
Martin Schläffer committed
89 90 91 92 93
  uint64_t x = WORDTOU64(w);
  *(uint64_t*)bytes &= ~MASK(n);
  *(uint64_t*)bytes |= U64BIG(x);
}

Enrico Pozzobon committed
94
forceinline word_t LOADBYTES(const uint8_t* bytes, int n) {
Martin Schläffer committed
95 96 97 98 99
  uint64_t x = 0;
  for (int i = 0; i < n; ++i) ((uint8_t*)&x)[7 - i] = bytes[i];
  return U64TOWORD(x);
}

Enrico Pozzobon committed
100
forceinline void STOREBYTES(uint8_t* bytes, word_t w, int n) {
Martin Schläffer committed
101 102
  uint64_t x = WORDTOU64(w);
  for (int i = 0; i < n; ++i) bytes[i] = ((uint8_t*)&x)[7 - i];
Martin Schläffer committed
103 104 105
}

#endif /* WORD_H_ */