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

#include <stdint.h>

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

typedef union {
  uint64_t w;
  uint8_t b[8];
} word_t;

Enrico Pozzobon committed
15
forceinline uint8_t ROR8(uint8_t a, int n) { return a >> n | a << (8 - n); }
Martin Schläffer committed
16

Enrico Pozzobon committed
17
forceinline word_t ROR(word_t a, int n) {
Martin Schläffer committed
18 19 20 21 22 23 24 25 26 27 28 29
  word_t b;
  b.b[0] = ROR8(a.b[(n + 0) & 0x7], (n + 0) >> 3);
  b.b[1] = ROR8(a.b[(n + 1) & 0x7], (n + 1) >> 3);
  b.b[2] = ROR8(a.b[(n + 2) & 0x7], (n + 2) >> 3);
  b.b[3] = ROR8(a.b[(n + 3) & 0x7], (n + 3) >> 3);
  b.b[4] = ROR8(a.b[(n + 4) & 0x7], (n + 4) >> 3);
  b.b[5] = ROR8(a.b[(n + 5) & 0x7], (n + 5) >> 3);
  b.b[6] = ROR8(a.b[(n + 6) & 0x7], (n + 6) >> 3);
  b.b[7] = ROR8(a.b[(n + 7) & 0x7], (n + 7) >> 3);
  return b;
}

Enrico Pozzobon committed
30
forceinline word_t WORD_T(uint64_t x) {
Martin Schläffer committed
31 32 33 34 35
  word_t w;
  w.w = x;
  return w;
}

Enrico Pozzobon committed
36
forceinline uint64_t UINT64_T(word_t w) {
Martin Schläffer committed
37 38 39 40 41
  uint64_t x;
  x = w.w;
  return x;
}

Enrico Pozzobon committed
42
forceinline word_t U64TOWORD(uint64_t x) { return WORD_T(interleave8(x)); }
Martin Schläffer committed
43

Enrico Pozzobon committed
44
forceinline uint64_t WORDTOU64(word_t w) { return interleave8(UINT64_T(w)); }
Martin Schläffer committed
45

Enrico Pozzobon committed
46
forceinline word_t NOT(word_t a) {
Martin Schläffer committed
47 48 49 50
  a.w = ~a.w;
  return a;
}

Enrico Pozzobon committed
51
forceinline word_t XOR(word_t a, word_t b) {
Martin Schläffer committed
52 53 54 55
  a.w ^= b.w;
  return a;
}

Enrico Pozzobon committed
56
forceinline word_t AND(word_t a, word_t b) {
Martin Schläffer committed
57 58 59 60
  a.w &= b.w;
  return a;
}

Enrico Pozzobon committed
61
forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) {
Martin Schläffer committed
62 63 64 65 66
  word_t w;
  w.w = lo2hi.w << 32 | hi2lo.w >> 32;
  return w;
}

Enrico Pozzobon committed
67
forceinline int NOTZERO(word_t a, word_t b) {
Martin Schläffer committed
68 69 70 71
  uint64_t result = a.w | b.w;
  result |= result >> 32;
  result |= result >> 16;
  result |= result >> 8;
Enrico Pozzobon committed
72
  return ((((int)(result & 0xff) - 1) >> 8) & 1) - 1;
Martin Schläffer committed
73 74
}

Enrico Pozzobon committed
75
forceinline word_t PAD(int i) { return (word_t){.b[7] = 0x80 >> i}; }
Martin Schläffer committed
76

Enrico Pozzobon committed
77
forceinline word_t CLEAR(word_t w, int n) {
Martin Schläffer committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
  /* undefined for n == 0 */
  uint8_t m = 0xff >> n;
  word_t mask = {
      .b[0] = m,
      .b[1] = m,
      .b[2] = m,
      .b[3] = m,
      .b[4] = m,
      .b[5] = m,
      .b[6] = m,
      .b[7] = m,
  };
  return AND(w, mask);
}

Enrico Pozzobon committed
93
forceinline uint64_t MASK(int n) {
Martin Schläffer committed
94 95 96 97
  /* undefined for n == 0 */
  return ~0ull >> (64 - 8 * n);
}

Enrico Pozzobon committed
98
forceinline word_t LOAD(const uint8_t* bytes, int n) {
Martin Schläffer committed
99 100 101 102
  uint64_t x = *(uint64_t*)bytes & MASK(n);
  return U64TOWORD(U64BIG(x));
}

Enrico Pozzobon committed
103
forceinline void STORE(uint8_t* bytes, word_t w, int n) {
Martin Schläffer committed
104 105 106 107 108
  uint64_t x = WORDTOU64(w);
  *(uint64_t*)bytes &= ~MASK(n);
  *(uint64_t*)bytes |= U64BIG(x);
}

Enrico Pozzobon committed
109
forceinline word_t LOADBYTES(const uint8_t* bytes, int n) {
Martin Schläffer committed
110 111 112 113 114
  uint64_t x = 0;
  for (int i = 0; i < n; ++i) ((uint8_t*)&x)[7 - i] = bytes[i];
  return U64TOWORD(x);
}

Enrico Pozzobon committed
115
forceinline void STOREBYTES(uint8_t* bytes, word_t w, int n) {
Martin Schläffer committed
116 117 118 119 120
  uint64_t x = WORDTOU64(w);
  for (int i = 0; i < n; ++i) bytes[i] = ((uint8_t*)&x)[7 - i];
}

#endif /* WORD_H_ */