introduce another vinstr temp
[xonotic/gmqcc.git] / util.cpp
1 #include <stdlib.h>
2 #include <string.h>
3 #include "gmqcc.h"
4
5 const char *util_instr_str[VINSTR_END] = {
6     "DONE",       "MUL_F",      "MUL_V",      "MUL_FV",
7     "MUL_VF",     "DIV_F",      "ADD_F",      "ADD_V",
8     "SUB_F",      "SUB_V",      "EQ_F",       "EQ_V",
9     "EQ_S",       "EQ_E",       "EQ_FNC",     "NE_F",
10     "NE_V",       "NE_S",       "NE_E",       "NE_FNC",
11     "LE",         "GE",         "LT",         "GT",
12     "LOAD_F",     "LOAD_V",     "LOAD_S",     "LOAD_ENT",
13     "LOAD_FLD",   "LOAD_FNC",   "ADDRESS",    "STORE_F",
14     "STORE_V",    "STORE_S",    "STORE_ENT",  "STORE_FLD",
15     "STORE_FNC",  "STOREP_F",   "STOREP_V",   "STOREP_S",
16     "STOREP_ENT", "STOREP_FLD", "STOREP_FNC", "RETURN",
17     "NOT_F",      "NOT_V",      "NOT_S",      "NOT_ENT",
18     "NOT_FNC",    "IF",         "IFNOT",      "CALL0",
19     "CALL1",      "CALL2",      "CALL3",      "CALL4",
20     "CALL5",      "CALL6",      "CALL7",      "CALL8",
21     "STATE",      "GOTO",       "AND",        "OR",
22     "BITAND",     "BITOR"
23 };
24
25 /*
26  * only required if big endian .. otherwise no need to swap
27  * data.
28  */
29 #if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_BIG || PLATFORM_BYTE_ORDER == -1
30     static GMQCC_INLINE void util_swap16(uint16_t *d, size_t l) {
31         while (l--) {
32             d[l] = (d[l] << 8) | (d[l] >> 8);
33         }
34     }
35
36     static GMQCC_INLINE void util_swap32(uint32_t *d, size_t l) {
37         while (l--) {
38             uint32_t v;
39             v = ((d[l] << 8) & 0xFF00FF00) | ((d[l] >> 8) & 0x00FF00FF);
40             d[l] = (v << 16) | (v >> 16);
41         }
42     }
43
44     /* Some strange system doesn't like constants that big, AND doesn't recognize an ULL suffix
45      * so let's go the safe way
46      */
47     static GMQCC_INLINE void util_swap64(uint32_t *d, size_t l) {
48         while (l--) {
49             uint64_t v;
50             v = ((d[l] << 8) & 0xFF00FF00FF00FF00) | ((d[l] >> 8) & 0x00FF00FF00FF00FF);
51             v = ((v << 16) & 0xFFFF0000FFFF0000) | ((v >> 16) & 0x0000FFFF0000FFFF);
52             d[l] = (v << 32) | (v >> 32);
53         }
54     }
55 #endif
56
57 void util_endianswap(void *_data, size_t count, unsigned int typesize) {
58 #   if PLATFORM_BYTE_ORDER == -1 /* runtime check */
59     if (*((char*)&typesize))
60         return;
61 #else
62
63 #   if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_LITTLE
64         /* prevent unused warnings */
65         (void) _data;
66         (void) count;
67         (void) typesize;
68         return;
69 #   else
70         switch (typesize) {
71             case 1: return;
72             case 2:
73                 util_swap16((uint16_t*)_data, count);
74                 return;
75             case 4:
76                 util_swap32((uint32_t*)_data, count);
77                 return;
78             case 8:
79                 util_swap64((uint32_t*)_data, count);
80                 return;
81
82             default:
83                 con_err ("util_endianswap: I don't know how to swap a %u byte structure!\n", typesize);
84                 exit(EXIT_FAILURE); /* please blow the fuck up! */
85         }
86 #   endif
87 #endif
88 }
89
90 void util_swap_header(prog_header_t &code_header) {
91     util_endianswap(&code_header.version,              1, sizeof(code_header.version));
92     util_endianswap(&code_header.crc16,                1, sizeof(code_header.crc16));
93     util_endianswap(&code_header.statements.offset,    1, sizeof(code_header.statements.offset));
94     util_endianswap(&code_header.statements.length,    1, sizeof(code_header.statements.length));
95     util_endianswap(&code_header.defs.offset,          1, sizeof(code_header.defs.offset));
96     util_endianswap(&code_header.defs.length,          1, sizeof(code_header.defs.length));
97     util_endianswap(&code_header.fields.offset,        1, sizeof(code_header.fields.offset));
98     util_endianswap(&code_header.fields.length,        1, sizeof(code_header.fields.length));
99     util_endianswap(&code_header.functions.offset,     1, sizeof(code_header.functions.offset));
100     util_endianswap(&code_header.functions.length,     1, sizeof(code_header.functions.length));
101     util_endianswap(&code_header.strings.offset,       1, sizeof(code_header.strings.offset));
102     util_endianswap(&code_header.strings.length,       1, sizeof(code_header.strings.length));
103     util_endianswap(&code_header.globals.offset,       1, sizeof(code_header.globals.offset));
104     util_endianswap(&code_header.globals.length,       1, sizeof(code_header.globals.length));
105     util_endianswap(&code_header.entfield,             1, sizeof(code_header.entfield));
106 }
107
108 void util_swap_statements(std::vector<prog_section_statement_t> &statements) {
109     for (auto &it : statements) {
110         util_endianswap(&it.opcode,  1, sizeof(it.opcode));
111         util_endianswap(&it.o1,      1, sizeof(it.o1));
112         util_endianswap(&it.o2,      1, sizeof(it.o2));
113         util_endianswap(&it.o3,      1, sizeof(it.o3));
114     }
115 }
116
117 void util_swap_defs_fields(std::vector<prog_section_both_t> &section) {
118     for (auto &it : section) {
119         util_endianswap(&it.type,   1, sizeof(it.type));
120         util_endianswap(&it.offset, 1, sizeof(it.offset));
121         util_endianswap(&it.name,   1, sizeof(it.name));
122     }
123 }
124
125 void util_swap_functions(std::vector<prog_section_function_t> &functions) {
126     for (auto &it : functions) {
127         util_endianswap(&it.entry,        1, sizeof(it.entry));
128         util_endianswap(&it.firstlocal,   1, sizeof(it.firstlocal));
129         util_endianswap(&it.locals,       1, sizeof(it.locals));
130         util_endianswap(&it.profile,      1, sizeof(it.profile));
131         util_endianswap(&it.name,         1, sizeof(it.name));
132         util_endianswap(&it.file,         1, sizeof(it.file));
133         util_endianswap(&it.nargs,        1, sizeof(it.nargs));
134         /* Don't swap argsize[] - it's just a byte array, which Quake uses only as such. */
135     }
136 }
137
138 void util_swap_globals(std::vector<int32_t> &globals) {
139     util_endianswap(&globals[0], globals.size(), sizeof(int32_t));
140 }
141
142 /*
143 * Based On:
144 *   Slicing-by-8 algorithms by Michael E.
145 *       Kounavis and Frank L. Berry from Intel Corp.
146 *       http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
147 *
148 *   This code was made to be slightly less confusing with macros, which
149 *   I suppose is somewhat ironic.
150 *
151 *   The code had to be changed for non reflected on the output register
152 *   since that's the method Quake uses.
153 *
154 *   The code also had to be changed for CRC16, which is slightly harder
155 *   since the CRC32 method in the original Intel paper used a different
156 *   bit order convention.
157 *
158 * Notes about the table:
159 *   - It's exactly 4K in size
160 *   - 64 elements fit in a cache line
161 *   - can do 8 iterations unrolled 8 times for free
162 *   - The first 256 elements of the table are standard CRC16 table
163 *
164 * Table can be generated with the following utility:
165 */
166 #if 0
167 #include <stdio.h>
168 #include <stdint.h>
169 int main(void) {
170     for (unsigned i = 0; i < 0x100; ++i) {
171         uint16_t x = i << 8;
172         for (int j = 0; j < 8; ++j)
173             x = (x << 1) ^ ((x & 0x8000) ? 0x1021 : 0);
174         tab[0][i] = x;
175     }
176     for (unsigned i = 0; i < 0x100; ++i) {
177         uint16_t c = tab[0][i];
178         for (unsigned j = 1; j < 8; ++j) {
179             c = tab[0][c >> 8] ^ (c << 8);
180             tab[j][i] = c;
181         }
182     }
183     printf("static const uint16_t util_crc16_table[8][256] = {");
184     for (int i = 0; i < 8; ++i) {
185         printf("{\n");
186         for (int j = 0; j < 0x100; ++j) {
187             printf((j & 7) ? " " : "    ");
188             printf((j != 0x100-1) ? "0x%04X," : "0x%04X", tab[i][j]);
189             if ((j & 7) == 7)
190                 printf("\n");
191         }
192         printf((i != 7) ? "}," : "}");
193     }
194     printf("};\n");
195     return 0;
196 }
197 #endif
198 /*
199  * Non-Reflective version is present as well as a reference.
200  *
201  * TODO:
202  *  combine the crc16 into u32s and mask off low high for byte order
203  *  to make the arrays smaller.
204  */
205
206 static const uint16_t util_crc16_table[8][256] = {{
207     0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
208     0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
209     0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
210     0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
211     0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
212     0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
213     0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
214     0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
215     0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
216     0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
217     0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
218     0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
219     0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
220     0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
221     0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
222     0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
223     0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
224     0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
225     0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
226     0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
227     0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
228     0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
229     0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
230     0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
231     0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
232     0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
233     0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
234     0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
235     0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
236     0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
237     0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
238     0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
239 },{
240     0x0000, 0x3331, 0x6662, 0x5553, 0xCCC4, 0xFFF5, 0xAAA6, 0x9997,
241     0x89A9, 0xBA98, 0xEFCB, 0xDCFA, 0x456D, 0x765C, 0x230F, 0x103E,
242     0x0373, 0x3042, 0x6511, 0x5620, 0xCFB7, 0xFC86, 0xA9D5, 0x9AE4,
243     0x8ADA, 0xB9EB, 0xECB8, 0xDF89, 0x461E, 0x752F, 0x207C, 0x134D,
244     0x06E6, 0x35D7, 0x6084, 0x53B5, 0xCA22, 0xF913, 0xAC40, 0x9F71,
245     0x8F4F, 0xBC7E, 0xE92D, 0xDA1C, 0x438B, 0x70BA, 0x25E9, 0x16D8,
246     0x0595, 0x36A4, 0x63F7, 0x50C6, 0xC951, 0xFA60, 0xAF33, 0x9C02,
247     0x8C3C, 0xBF0D, 0xEA5E, 0xD96F, 0x40F8, 0x73C9, 0x269A, 0x15AB,
248     0x0DCC, 0x3EFD, 0x6BAE, 0x589F, 0xC108, 0xF239, 0xA76A, 0x945B,
249     0x8465, 0xB754, 0xE207, 0xD136, 0x48A1, 0x7B90, 0x2EC3, 0x1DF2,
250     0x0EBF, 0x3D8E, 0x68DD, 0x5BEC, 0xC27B, 0xF14A, 0xA419, 0x9728,
251     0x8716, 0xB427, 0xE174, 0xD245, 0x4BD2, 0x78E3, 0x2DB0, 0x1E81,
252     0x0B2A, 0x381B, 0x6D48, 0x5E79, 0xC7EE, 0xF4DF, 0xA18C, 0x92BD,
253     0x8283, 0xB1B2, 0xE4E1, 0xD7D0, 0x4E47, 0x7D76, 0x2825, 0x1B14,
254     0x0859, 0x3B68, 0x6E3B, 0x5D0A, 0xC49D, 0xF7AC, 0xA2FF, 0x91CE,
255     0x81F0, 0xB2C1, 0xE792, 0xD4A3, 0x4D34, 0x7E05, 0x2B56, 0x1867,
256     0x1B98, 0x28A9, 0x7DFA, 0x4ECB, 0xD75C, 0xE46D, 0xB13E, 0x820F,
257     0x9231, 0xA100, 0xF453, 0xC762, 0x5EF5, 0x6DC4, 0x3897, 0x0BA6,
258     0x18EB, 0x2BDA, 0x7E89, 0x4DB8, 0xD42F, 0xE71E, 0xB24D, 0x817C,
259     0x9142, 0xA273, 0xF720, 0xC411, 0x5D86, 0x6EB7, 0x3BE4, 0x08D5,
260     0x1D7E, 0x2E4F, 0x7B1C, 0x482D, 0xD1BA, 0xE28B, 0xB7D8, 0x84E9,
261     0x94D7, 0xA7E6, 0xF2B5, 0xC184, 0x5813, 0x6B22, 0x3E71, 0x0D40,
262     0x1E0D, 0x2D3C, 0x786F, 0x4B5E, 0xD2C9, 0xE1F8, 0xB4AB, 0x879A,
263     0x97A4, 0xA495, 0xF1C6, 0xC2F7, 0x5B60, 0x6851, 0x3D02, 0x0E33,
264     0x1654, 0x2565, 0x7036, 0x4307, 0xDA90, 0xE9A1, 0xBCF2, 0x8FC3,
265     0x9FFD, 0xACCC, 0xF99F, 0xCAAE, 0x5339, 0x6008, 0x355B, 0x066A,
266     0x1527, 0x2616, 0x7345, 0x4074, 0xD9E3, 0xEAD2, 0xBF81, 0x8CB0,
267     0x9C8E, 0xAFBF, 0xFAEC, 0xC9DD, 0x504A, 0x637B, 0x3628, 0x0519,
268     0x10B2, 0x2383, 0x76D0, 0x45E1, 0xDC76, 0xEF47, 0xBA14, 0x8925,
269     0x991B, 0xAA2A, 0xFF79, 0xCC48, 0x55DF, 0x66EE, 0x33BD, 0x008C,
270     0x13C1, 0x20F0, 0x75A3, 0x4692, 0xDF05, 0xEC34, 0xB967, 0x8A56,
271     0x9A68, 0xA959, 0xFC0A, 0xCF3B, 0x56AC, 0x659D, 0x30CE, 0x03FF
272 },{
273     0x0000, 0x3730, 0x6E60, 0x5950, 0xDCC0, 0xEBF0, 0xB2A0, 0x8590,
274     0xA9A1, 0x9E91, 0xC7C1, 0xF0F1, 0x7561, 0x4251, 0x1B01, 0x2C31,
275     0x4363, 0x7453, 0x2D03, 0x1A33, 0x9FA3, 0xA893, 0xF1C3, 0xC6F3,
276     0xEAC2, 0xDDF2, 0x84A2, 0xB392, 0x3602, 0x0132, 0x5862, 0x6F52,
277     0x86C6, 0xB1F6, 0xE8A6, 0xDF96, 0x5A06, 0x6D36, 0x3466, 0x0356,
278     0x2F67, 0x1857, 0x4107, 0x7637, 0xF3A7, 0xC497, 0x9DC7, 0xAAF7,
279     0xC5A5, 0xF295, 0xABC5, 0x9CF5, 0x1965, 0x2E55, 0x7705, 0x4035,
280     0x6C04, 0x5B34, 0x0264, 0x3554, 0xB0C4, 0x87F4, 0xDEA4, 0xE994,
281     0x1DAD, 0x2A9D, 0x73CD, 0x44FD, 0xC16D, 0xF65D, 0xAF0D, 0x983D,
282     0xB40C, 0x833C, 0xDA6C, 0xED5C, 0x68CC, 0x5FFC, 0x06AC, 0x319C,
283     0x5ECE, 0x69FE, 0x30AE, 0x079E, 0x820E, 0xB53E, 0xEC6E, 0xDB5E,
284     0xF76F, 0xC05F, 0x990F, 0xAE3F, 0x2BAF, 0x1C9F, 0x45CF, 0x72FF,
285     0x9B6B, 0xAC5B, 0xF50B, 0xC23B, 0x47AB, 0x709B, 0x29CB, 0x1EFB,
286     0x32CA, 0x05FA, 0x5CAA, 0x6B9A, 0xEE0A, 0xD93A, 0x806A, 0xB75A,
287     0xD808, 0xEF38, 0xB668, 0x8158, 0x04C8, 0x33F8, 0x6AA8, 0x5D98,
288     0x71A9, 0x4699, 0x1FC9, 0x28F9, 0xAD69, 0x9A59, 0xC309, 0xF439,
289     0x3B5A, 0x0C6A, 0x553A, 0x620A, 0xE79A, 0xD0AA, 0x89FA, 0xBECA,
290     0x92FB, 0xA5CB, 0xFC9B, 0xCBAB, 0x4E3B, 0x790B, 0x205B, 0x176B,
291     0x7839, 0x4F09, 0x1659, 0x2169, 0xA4F9, 0x93C9, 0xCA99, 0xFDA9,
292     0xD198, 0xE6A8, 0xBFF8, 0x88C8, 0x0D58, 0x3A68, 0x6338, 0x5408,
293     0xBD9C, 0x8AAC, 0xD3FC, 0xE4CC, 0x615C, 0x566C, 0x0F3C, 0x380C,
294     0x143D, 0x230D, 0x7A5D, 0x4D6D, 0xC8FD, 0xFFCD, 0xA69D, 0x91AD,
295     0xFEFF, 0xC9CF, 0x909F, 0xA7AF, 0x223F, 0x150F, 0x4C5F, 0x7B6F,
296     0x575E, 0x606E, 0x393E, 0x0E0E, 0x8B9E, 0xBCAE, 0xE5FE, 0xD2CE,
297     0x26F7, 0x11C7, 0x4897, 0x7FA7, 0xFA37, 0xCD07, 0x9457, 0xA367,
298     0x8F56, 0xB866, 0xE136, 0xD606, 0x5396, 0x64A6, 0x3DF6, 0x0AC6,
299     0x6594, 0x52A4, 0x0BF4, 0x3CC4, 0xB954, 0x8E64, 0xD734, 0xE004,
300     0xCC35, 0xFB05, 0xA255, 0x9565, 0x10F5, 0x27C5, 0x7E95, 0x49A5,
301     0xA031, 0x9701, 0xCE51, 0xF961, 0x7CF1, 0x4BC1, 0x1291, 0x25A1,
302     0x0990, 0x3EA0, 0x67F0, 0x50C0, 0xD550, 0xE260, 0xBB30, 0x8C00,
303     0xE352, 0xD462, 0x8D32, 0xBA02, 0x3F92, 0x08A2, 0x51F2, 0x66C2,
304     0x4AF3, 0x7DC3, 0x2493, 0x13A3, 0x9633, 0xA103, 0xF853, 0xCF63
305 },{
306     0x0000, 0x76B4, 0xED68, 0x9BDC, 0xCAF1, 0xBC45, 0x2799, 0x512D,
307     0x85C3, 0xF377, 0x68AB, 0x1E1F, 0x4F32, 0x3986, 0xA25A, 0xD4EE,
308     0x1BA7, 0x6D13, 0xF6CF, 0x807B, 0xD156, 0xA7E2, 0x3C3E, 0x4A8A,
309     0x9E64, 0xE8D0, 0x730C, 0x05B8, 0x5495, 0x2221, 0xB9FD, 0xCF49,
310     0x374E, 0x41FA, 0xDA26, 0xAC92, 0xFDBF, 0x8B0B, 0x10D7, 0x6663,
311     0xB28D, 0xC439, 0x5FE5, 0x2951, 0x787C, 0x0EC8, 0x9514, 0xE3A0,
312     0x2CE9, 0x5A5D, 0xC181, 0xB735, 0xE618, 0x90AC, 0x0B70, 0x7DC4,
313     0xA92A, 0xDF9E, 0x4442, 0x32F6, 0x63DB, 0x156F, 0x8EB3, 0xF807,
314     0x6E9C, 0x1828, 0x83F4, 0xF540, 0xA46D, 0xD2D9, 0x4905, 0x3FB1,
315     0xEB5F, 0x9DEB, 0x0637, 0x7083, 0x21AE, 0x571A, 0xCCC6, 0xBA72,
316     0x753B, 0x038F, 0x9853, 0xEEE7, 0xBFCA, 0xC97E, 0x52A2, 0x2416,
317     0xF0F8, 0x864C, 0x1D90, 0x6B24, 0x3A09, 0x4CBD, 0xD761, 0xA1D5,
318     0x59D2, 0x2F66, 0xB4BA, 0xC20E, 0x9323, 0xE597, 0x7E4B, 0x08FF,
319     0xDC11, 0xAAA5, 0x3179, 0x47CD, 0x16E0, 0x6054, 0xFB88, 0x8D3C,
320     0x4275, 0x34C1, 0xAF1D, 0xD9A9, 0x8884, 0xFE30, 0x65EC, 0x1358,
321     0xC7B6, 0xB102, 0x2ADE, 0x5C6A, 0x0D47, 0x7BF3, 0xE02F, 0x969B,
322     0xDD38, 0xAB8C, 0x3050, 0x46E4, 0x17C9, 0x617D, 0xFAA1, 0x8C15,