1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* -*- mode: C; c-basic-offset: 3; -*- */
2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdio.h>   // fprintf
4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <assert.h>  // assert
5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined(__APPLE__)
6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <machine/endian.h>
7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define __BYTE_ORDER    BYTE_ORDER
8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define __LITTLE_ENDIAN LITTLE_ENDIAN
9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#else
10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <endian.h>
11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif
12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <inttypes.h>
13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "vbits.h"
14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "vtest.h"
15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Return the bits of V if they fit into 64-bit. If V has fewer than
18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   64 bits, the bit pattern is zero-extended to the left. */
19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic uint64_t
20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovget_bits64(vbits_t v)
21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v.num_bits) {
23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 1:  return v.bits.u32;
24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:  return v.bits.u8;
25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16: return v.bits.u16;
26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32: return v.bits.u32;
27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64: return v.bits.u64;
28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128:
29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256:
30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      /* fall through */
31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid
37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovprint_vbits(FILE *fp, vbits_t v)
38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v.num_bits) {
40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 1:   fprintf(fp, "%08x",   v.bits.u32); break;
41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:   fprintf(fp, "%02x",   v.bits.u8);  break;
42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:  fprintf(fp, "%04x",   v.bits.u16); break;
43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:  fprintf(fp, "%08x",   v.bits.u32); break;
44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:  fprintf(fp, "%016"PRIx64, v.bits.u64); break;
45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128:
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u128[1]);
48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u128[0]);
49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u128[0]);
51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u128[1]);
52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256:
55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u256[3]);
57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u256[2]);
58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u256[1]);
59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u256[0]);
60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u256[0]);
62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u256[1]);
63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u256[2]);
64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         fprintf(fp, "%016"PRIx64, v.bits.u256[3]);
65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Return a value where all bits are set to undefined. */
74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovundefined_vbits(unsigned num_bits)
76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = num_bits };
78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (num_bits) {
80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case   1: new.bits.u32 = 0x01;   break;
81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case   8: new.bits.u8  = 0xff;   break;
82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case  16: new.bits.u16 = 0xffff; break;
83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case  32: new.bits.u32 = ~0;     break;
84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case  64: new.bits.u64 = ~0ull;  break;
85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: new.bits.u128[0] = ~0ull;
86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u128[1] = ~0ull;
87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             break;
88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: new.bits.u256[0] = ~0ull;
89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[1] = ~0ull;
90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[2] = ~0ull;
91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[3] = ~0ull;
92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             break;
93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Return a value where all bits are set to defined. */
101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovdefined_vbits(unsigned num_bits)
103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = num_bits };
105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (num_bits) {
107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case   1: new.bits.u32 = 0x0; break;
108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case   8: new.bits.u8  = 0x0; break;
109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case  16: new.bits.u16 = 0x0; break;
110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case  32: new.bits.u32 = 0x0; break;
111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case  64: new.bits.u64 = 0x0; break;
112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: new.bits.u128[0] = 0x0;
113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u128[1] = 0x0;
114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             break;
115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: new.bits.u256[0] = 0x0;
116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[1] = 0x0;
117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[2] = 0x0;
118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[3] = 0x0;
119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             break;
120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Return 1, if equal. */
128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint
129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovequal_vbits(vbits_t v1, vbits_t v2)
130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(v1.num_bits == v2.num_bits);
132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v1.num_bits) {
134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 1:   return v1.bits.u32 == v2.bits.u32;
135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:   return v1.bits.u8  == v2.bits.u8;
136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:  return v1.bits.u16 == v2.bits.u16;
137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:  return v1.bits.u32 == v2.bits.u32;
138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:  return v1.bits.u64 == v2.bits.u64;
139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: return v1.bits.u128[0] == v2.bits.u128[0] &&
140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    v1.bits.u128[1] == v2.bits.u128[1];
141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: return v1.bits.u256[0] == v2.bits.u256[0] &&
142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    v1.bits.u256[1] == v2.bits.u256[1] &&
143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    v1.bits.u256[2] == v2.bits.u256[2] &&
144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                    v1.bits.u256[3] == v2.bits.u256[3];
145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Truncate the bit pattern in V1 to NUM_BITS bits */
152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtruncate_vbits(vbits_t v, unsigned num_bits)
154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(num_bits <= v.num_bits);
156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (num_bits == v.num_bits) return v;
158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = num_bits };
160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (num_bits <= 64) {
162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      uint64_t bits;
163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (v.num_bits <= 64)
165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         bits = get_bits64(v);
166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      else if (v.num_bits == 128)
167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (__BYTE_ORDER == __LITTLE_ENDIAN)
168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            bits = v.bits.u128[0];
169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         else
170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            bits = v.bits.u128[1];
171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      else if (v.num_bits == 256)
172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (__BYTE_ORDER == __LITTLE_ENDIAN)
173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            bits = v.bits.u256[0];
174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         else
175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            bits = v.bits.u256[3];
176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      else
177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         panic(__func__);
178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      switch (num_bits) {
180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 1:   new.bits.u32 = bits & 0x01;   break;
181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 8:   new.bits.u8  = bits & 0xff;   break;
182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 16:  new.bits.u16 = bits & 0xffff; break;
183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 32:  new.bits.u32 = bits & ~0u;    break;
184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 64:  new.bits.u64 = bits & ~0ll;   break;
185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      default:
186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         panic(__func__);
187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return new;
189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (num_bits == 128) {
192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      assert(v.num_bits == 256);
193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      /* From 256 bits to 128 */
194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[0] = v.bits.u256[0];
196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[1] = v.bits.u256[1];
197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[0] = v.bits.u256[2];
199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[1] = v.bits.u256[3];
200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return new;
202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Cannot truncate to 256 bits from something larger */
205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   panic(__func__);
206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Helper function to compute left_vbits */
210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic uint64_t
211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovleft64(uint64_t x)
212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   // left(x) = x | -x
214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return x | (~x + 1);
215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovleft_vbits(vbits_t v, unsigned num_bits)
220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(num_bits >= v.num_bits);
222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = num_bits };
224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (v.num_bits <= 64) {
226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      uint64_t bits = left64(get_bits64(v));
227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      switch (num_bits) {
229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 8:   new.bits.u8  = bits & 0xff;   break;
230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 16:  new.bits.u16 = bits & 0xffff; break;
231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 32:  new.bits.u32 = bits & ~0u;    break;
232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 64:  new.bits.u64 = bits & ~0ll;   break;
233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 128:
234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (__BYTE_ORDER == __LITTLE_ENDIAN) {
235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = bits;
236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (bits & (1ull << 63)) {  // MSB is set
237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u128[1] = ~0ull;
238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u128[1] = 0;
240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = bits;
243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (bits & (1ull << 63)) {  // MSB is set
244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u128[0] = ~0ull;
245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u128[0] = 0;
247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         break;
250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 256:
251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (__BYTE_ORDER == __LITTLE_ENDIAN) {
252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = bits;
253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (bits & (1ull << 63)) {  // MSB is set
254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[1] = ~0ull;
255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[2] = ~0ull;
256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[3] = ~0ull;
257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[1] = 0;
259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[2] = 0;
260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[3] = 0;
261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = bits;
264436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (bits & (1ull << 63)) {  // MSB is set
265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[0] = ~0ull;
266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[1] = ~0ull;
267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[2] = ~0ull;
268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[0] = 0;
270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[1] = 0;
271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u256[2] = 0;
272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
274436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         break;
275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      default:
276436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         panic(__func__);
277436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return new;
279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (v.num_bits == 128) {
282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (v.bits.u128[1] != 0) {
284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = v.bits.u128[0];
285436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = left64(v.bits.u128[1]);
286436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = left64(v.bits.u128[0]);
288436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (new.bits.u128[0] & (1ull << 63)) {  // MSB is set
289436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u128[1] = ~0ull;
290436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
291436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u128[1] = 0;
292436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
293436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
295436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (v.bits.u128[0] != 0) {
296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = left64(v.bits.u128[0]);
297436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = v.bits.u128[1];
298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = left64(v.bits.u128[1]);
300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            if (new.bits.u128[1] & (1ull << 63)) {  // MSB is set
301436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u128[0] = ~0ull;
302436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            } else {
303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov               new.bits.u128[0] = 0;
304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            }
305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (num_bits == 128) return new;
308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      assert(num_bits == 256);
310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
312436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         uint64_t b1 = new.bits.u128[1];
313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         uint64_t b0 = new.bits.u128[0];
314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[0] = b0;
316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[1] = b1;
317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (new.bits.u256[1] & (1ull << 63)) {  // MSB is set
319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = ~0ull;
320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = ~0ull;
321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 0;
324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         uint64_t b1 = new.bits.u128[0];
327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         uint64_t b0 = new.bits.u128[1];
328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[2] = b0;
330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[3] = b1;
331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (new.bits.u256[2] & (1ull << 63)) {  // MSB is set
333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = ~0ull;
334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = ~0ull;
335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 0;
337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return new;
341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   panic(__func__);
344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
347436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
348436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovor_vbits(vbits_t v1, vbits_t v2)
349436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
350436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(v1.num_bits == v2.num_bits);
351436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = v1.num_bits };
353436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v1.num_bits) {
355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:   new.bits.u8  = v1.bits.u8  | v2.bits.u8;  break;
356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:  new.bits.u16 = v1.bits.u16 | v2.bits.u16; break;
357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:  new.bits.u32 = v1.bits.u32 | v2.bits.u32; break;
358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:  new.bits.u64 = v1.bits.u64 | v2.bits.u64; break;
359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: new.bits.u128[0] = v1.bits.u128[0] | v2.bits.u128[0];
360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u128[1] = v1.bits.u128[1] | v2.bits.u128[1];
361436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             break;
362436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: new.bits.u256[0] = v1.bits.u256[0] | v2.bits.u256[0];
363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[1] = v1.bits.u256[1] | v2.bits.u256[1];
364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[2] = v1.bits.u256[2] | v2.bits.u256[2];
365436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[3] = v1.bits.u256[3] | v2.bits.u256[3];
366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             break;
367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovand_vbits(vbits_t v1, vbits_t v2)
377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(v1.num_bits == v2.num_bits);
379436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
380436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = v1.num_bits };
381436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
382436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v1.num_bits) {
383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:   new.bits.u8  = v1.bits.u8  & v2.bits.u8;  break;
384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:  new.bits.u16 = v1.bits.u16 & v2.bits.u16; break;
385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:  new.bits.u32 = v1.bits.u32 & v2.bits.u32; break;
386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:  new.bits.u64 = v1.bits.u64 & v2.bits.u64; break;
387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: new.bits.u128[0] = v1.bits.u128[0] & v2.bits.u128[0];
388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u128[1] = v1.bits.u128[1] & v2.bits.u128[1];
389436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             break;
390436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: new.bits.u256[0] = v1.bits.u256[0] & v2.bits.u256[0];
391436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[1] = v1.bits.u256[1] & v2.bits.u256[1];
392436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[2] = v1.bits.u256[2] & v2.bits.u256[2];
393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u256[3] = v1.bits.u256[3] & v2.bits.u256[3];
394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             break;
395436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
398436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
400436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
401436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
404436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovconcat_vbits(vbits_t v1, vbits_t v2)
405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(v1.num_bits == v2.num_bits);
407436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
408436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = v1.num_bits * 2 };
409436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
410436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v1.num_bits) {
411436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:   new.bits.u16 = (v1.bits.u8 << 8)    | v2.bits.u8;  break;
412436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:  new.bits.u32 = (v1.bits.u16 << 16)  | v2.bits.u16; break;
413436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:  new.bits.u64 =  v1.bits.u32;
414436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov             new.bits.u64 = (new.bits.u64 << 32) | v2.bits.u32; break;
415436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:
416436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
417436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[0] = v2.bits.u64;
418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[1] = v1.bits.u64;
419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
420436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[0] = v1.bits.u64;
421436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[1] = v2.bits.u64;
422436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
423436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128:
425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
426436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[0] = v2.bits.u128[0];
427436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[1] = v2.bits.u128[1];
428436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[2] = v1.bits.u128[0];
429436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[3] = v1.bits.u128[1];
430436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
431436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[0] = v1.bits.u128[0];
432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[1] = v1.bits.u128[1];
433436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[2] = v2.bits.u128[0];
434436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[3] = v2.bits.u128[1];
435436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
436436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
437436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: /* Fall through */
438436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
439436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
440436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
441436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
442436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
443436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
444436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
445436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
446436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovupper_vbits(vbits_t v)
448436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
449436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = v.num_bits / 2 };
450436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v.num_bits) {
452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:  new.bits.u8  = v.bits.u16 >> 8;  break;
453436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:  new.bits.u16 = v.bits.u32 >> 16; break;
454436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:  new.bits.u32 = v.bits.u64 >> 32; break;
455436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128:
456436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN)
457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u64 = v.bits.u128[1];
458436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      else
459436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u64 = v.bits.u128[0];
460436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
461436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256:
462436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
463436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[0] = v.bits.u256[2];
464436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[1] = v.bits.u256[3];
465436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
466436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[0] = v.bits.u256[0];
467436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u128[1] = v.bits.u256[1];
468436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
469436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
470436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:
471436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
472436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
473436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
474436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
475436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
476436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
477436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
478436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
479436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
480436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovzextend_vbits(vbits_t v, unsigned num_bits)
481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
482436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(num_bits >= v.num_bits);
483436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
484436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (num_bits == v.num_bits) return v;
485436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
486436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = num_bits };
487436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (v.num_bits <= 64) {
489436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      uint64_t bits = get_bits64(v);
490436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
491436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      switch (num_bits) {
492436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 8:   new.bits.u8  = bits; break;
493436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 16:  new.bits.u16 = bits; break;
494436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 32:  new.bits.u32 = bits; break;
495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 64:  new.bits.u64 = bits; break;
496436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 128:
497436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (__BYTE_ORDER == __LITTLE_ENDIAN) {
498436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = bits;
499436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = 0;
500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
501436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = 0;
502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = bits;
503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
504436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         break;
505436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      case 256:
506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (__BYTE_ORDER == __LITTLE_ENDIAN) {
507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = bits;
508436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
509436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
510436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 0;
511436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
512436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 0;
513436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
514436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
515436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = bits;
516436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
517436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         break;
518436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      default:
519436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         panic(__func__);
520436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
521436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return new;
522436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
524436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (v.num_bits == 128) {
525436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      assert(num_bits == 256);
526436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
527436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
528436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[0] = v.bits.u128[0];
529436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[1] = v.bits.u128[1];
530436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[2] = 0;
531436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[3] = 0;
532436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
533436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[0] = 0;
534436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[1] = 0;
535436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[2] = v.bits.u128[1];
536436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         new.bits.u256[3] = v.bits.u128[0];
537436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
538436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      return new;
539436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
540436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Cannot zero-extend a 256-bit value to something larger */
542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   panic(__func__);
543436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
544436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
545436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
546436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
547436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsextend_vbits(vbits_t v, unsigned num_bits)
548436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
549436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(num_bits >= v.num_bits);
550436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
551436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   int sextend = 0;
552436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
553436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v.num_bits) {
554436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:   if (v.bits.u8  == 0x80)             sextend = 1; break;
555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:  if (v.bits.u16 == 0x8000)           sextend = 1; break;
556436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:  if (v.bits.u32 == 0x80000000)       sextend = 1; break;
557436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:  if (v.bits.u64 == (1ull << 63))     sextend = 1; break;
558436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: if (v.bits.u128[1] == (1ull << 63)) sextend = 1; break;
559436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: if (v.bits.u256[3] == (1ull << 63)) sextend = 1; break;
560436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
561436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
562436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
564436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
565436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return sextend ? left_vbits(v, num_bits) : zextend_vbits(v, num_bits);
566436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
567436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
568436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
569436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
570436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovonehot_vbits(unsigned bitno, unsigned num_bits)
571436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
572436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(bitno < num_bits);
573436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
574436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = num_bits };
575436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
576436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (num_bits) {
577436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 1:   new.bits.u32 = 1    << bitno; break;
578436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:   new.bits.u8  = 1    << bitno; break;
579436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:  new.bits.u16 = 1    << bitno; break;
580436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:  new.bits.u32 = 1u   << bitno; break;
581436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:  new.bits.u64 = 1ull << bitno; break;
582436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128:
583436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
584436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (bitno < 64) {
585436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = 1ull << bitno;
586436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = 0;
587436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
588436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = 0;
589436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = 1ull << (bitno - 64);
590436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
591436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
592436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (bitno < 64) {
593436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = 0;
594436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = 1ull << bitno;
595436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
596436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[0] = 1ull << (bitno - 64);
597436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u128[1] = 0;
598436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
599436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
600436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
601436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256:
602436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      if (__BYTE_ORDER == __LITTLE_ENDIAN) {
603436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (bitno < 64) {
604436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 1ull << bitno;
605436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
606436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
607436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 0;
608436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else if (bitno < 128) {
609436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 0;
610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 1ull << (bitno - 64);
611436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
612436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 0;
613436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else if (bitno < 192) {
614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 0;
615436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
616436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 1ull << (bitno - 128);
617436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 0;
618436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
619436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 0;
620436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
621436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
622436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 1ull << (bitno - 192);
623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
624436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      } else {
625436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         if (bitno < 64) {
626436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 0;
627436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
628436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
629436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 1ull << bitno;
630436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else if (bitno < 128) {
631436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 0;
632436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 1ull << (bitno - 64);
634436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 0;
635436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else if (bitno < 192) {
636436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 0;
637436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 1ull << (bitno - 128);
638436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
639436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 0;
640436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } else {
641436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[0] = 1ull << (bitno - 192);
642436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[1] = 0;
643436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[2] = 0;
644436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            new.bits.u256[3] = 0;
645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         }
646436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      }
647436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
648436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
649436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
651436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
652436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
653436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
654436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
655436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint
656436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovcompletely_defined_vbits(vbits_t v)
657436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
658436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return equal_vbits(v, defined_vbits(v.num_bits));
659436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
660436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
661436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
662436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
663436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovshl_vbits(vbits_t v, unsigned shift_amount)
664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(shift_amount < v.num_bits);
666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = v;
668436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
669436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v.num_bits) {
670436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:  new.bits.u8  <<= shift_amount; break;
671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16: new.bits.u16 <<= shift_amount; break;
672436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32: new.bits.u32 <<= shift_amount; break;
673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64: new.bits.u64 <<= shift_amount; break;
674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: /* fall through */
675436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: /* fall through */
676436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
679436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
680436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
681436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
682436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
683436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
684436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
685436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovshr_vbits(vbits_t v, unsigned shift_amount)
686436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(shift_amount < v.num_bits);
688436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
689436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = v;
690436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
691436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v.num_bits) {
692436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:  new.bits.u8  >>= shift_amount; break;
693436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16: new.bits.u16 >>= shift_amount; break;
694436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32: new.bits.u32 >>= shift_amount; break;
695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64: new.bits.u64 >>= shift_amount; break;
696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: /* fall through */
697436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: /* fall through */
698436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
699436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
700436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
701436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
702436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
703436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
704436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
705436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
706436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
707436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovsar_vbits(vbits_t v, unsigned shift_amount)
708436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
709436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert(shift_amount < v.num_bits);
710436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
711436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = v;
712436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   int msb;
713436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
714436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v.num_bits) {
715436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 8:
716436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      new.bits.u8  >>= shift_amount;
717436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      msb = (v.bits.u8 & 0x80) != 0;
718436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
719436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 16:
720436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      new.bits.u16 >>= shift_amount;
721436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      msb = (v.bits.u16 & 0x8000) != 0;
722436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
723436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:
724436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      new.bits.u32 >>= shift_amount;
725436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      msb = (v.bits.u32 & (1u << 31)) != 0;
726436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
727436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:
728436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      new.bits.u64 >>= shift_amount;
729436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      msb = (v.bits.u64 & (1ull << 63)) != 0;
730436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
731436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 128: /* fall through */
732436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 256: /* fall through */
733436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
734436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
735436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
736436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
737436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (msb)
738436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      new = left_vbits(new, new.num_bits);
739436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
740436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
741436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
742436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Return a value for the POWER Iop_CmpORD class iops */
743436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvbits_t
744436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovcmpord_vbits(unsigned v1_num_bits, unsigned v2_num_bits)
745436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{
746436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   vbits_t new = { .num_bits = v1_num_bits };
747436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
748436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Size of values being compared must be the same */
749436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   assert( v1_num_bits == v2_num_bits);
750436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
751436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   /* Comparison only produces 32-bit or 64-bit value where
752436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    * the lower 3 bits are set to indicate, less than, equal and greater then.
753436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov    */
754436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   switch (v1_num_bits) {
755436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 32:
756436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      new.bits.u32 = 0xE;
757436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
758436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
759436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   case 64:
760436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      new.bits.u64 = 0xE;
761436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      break;
762436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
763436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   default:
764436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      panic(__func__);
765436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
766436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
767436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   return new;
768436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}
769