github.com/apache/arrow/go/v14@v14.0.2/parquet/internal/utils/_lib/bit_packing_avx2.c (about) 1 // Licensed to the Apache Software Foundation (ASF) under one 2 // or more contributor license agreements. See the NOTICE file 3 // distributed with this work for additional information 4 // regarding copyright ownership. The ASF licenses this file 5 // to you under the Apache License, Version 2.0 (the 6 // "License"); you may not use this file except in compliance 7 // with the License. You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #include <stdint.h> 18 #include <immintrin.h> 19 #include <string.h> 20 21 inline const uint32_t* unpack0_32_avx2(const uint32_t* in, uint32_t* out) { 22 memset(out, 0x0, 32 * sizeof(*out)); 23 out += 32; 24 25 return in; 26 } 27 28 inline static const uint32_t* unpack1_32_avx2(const uint32_t* in, uint32_t* out) { 29 uint32_t mask = 0x1; 30 __m256i reg_shifts, reg_inls, reg_masks; 31 __m256i results; 32 33 reg_masks = _mm256_set1_epi32(mask); 34 35 // shift the first 8 outs 36 reg_shifts = _mm256_set_epi32(7, 6, 5, 4, 37 3, 2, 1, 0); 38 reg_inls = _mm256_set_epi32(in[0], in[0], 39 in[0], in[0], 40 in[0], in[0], 41 in[0], in[0]); 42 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 43 _mm256_storeu_si256((__m256i*)(out), results); 44 out += 8; 45 46 // shift the second 8 outs 47 reg_shifts = _mm256_set_epi32(15, 14, 13, 12, 48 11, 10, 9, 8); 49 reg_inls = _mm256_set_epi32(in[0], in[0], 50 in[0], in[0], 51 in[0], in[0], 52 in[0], in[0]); 53 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 54 _mm256_storeu_si256((__m256i*)(out), results); 55 out += 8; 56 57 // shift the third 8 outs 58 reg_shifts = _mm256_set_epi32(23, 22, 21, 20, 59 19, 18, 17, 16); 60 reg_inls = _mm256_set_epi32(in[0], in[0], 61 in[0], in[0], 62 in[0], in[0], 63 in[0], in[0]); 64 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 65 _mm256_storeu_si256((__m256i*)(out), results); 66 out += 8; 67 68 // shift the last 8 outs 69 reg_shifts = _mm256_set_epi32(31, 30, 29, 28, 70 27, 26, 25, 24); 71 reg_inls = _mm256_set_epi32(in[0], in[0], 72 in[0], in[0], 73 in[0], in[0], 74 in[0], in[0]); 75 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 76 _mm256_storeu_si256((__m256i*)(out), results); 77 out += 8; 78 79 in += 1; 80 81 return in; 82 } 83 84 inline static const uint32_t* unpack2_32_avx2(const uint32_t* in, uint32_t* out) { 85 uint32_t mask = 0x3; 86 __m256i reg_shifts, reg_inls, reg_masks; 87 __m256i results; 88 89 reg_masks = _mm256_set1_epi32(mask); 90 91 // shift the first 8 outs 92 reg_shifts = _mm256_set_epi32(14, 12, 10, 8, 93 6, 4, 2, 0); 94 reg_inls = _mm256_set_epi32(in[0], in[0], 95 in[0], in[0], 96 in[0], in[0], 97 in[0], in[0]); 98 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 99 _mm256_storeu_si256((__m256i*)(out), results); 100 out += 8; 101 102 // shift the second 8 outs 103 reg_shifts = _mm256_set_epi32(30, 28, 26, 24, 104 22, 20, 18, 16); 105 reg_inls = _mm256_set_epi32(in[0], in[0], 106 in[0], in[0], 107 in[0], in[0], 108 in[0], in[0]); 109 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 110 _mm256_storeu_si256((__m256i*)(out), results); 111 out += 8; 112 113 // shift the third 8 outs 114 reg_shifts = _mm256_set_epi32(14, 12, 10, 8, 115 6, 4, 2, 0); 116 reg_inls = _mm256_set_epi32(in[1], in[1], 117 in[1], in[1], 118 in[1], in[1], 119 in[1], in[1]); 120 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 121 _mm256_storeu_si256((__m256i*)(out), results); 122 out += 8; 123 124 // shift the last 8 outs 125 reg_shifts = _mm256_set_epi32(30, 28, 26, 24, 126 22, 20, 18, 16); 127 reg_inls = _mm256_set_epi32(in[1], in[1], 128 in[1], in[1], 129 in[1], in[1], 130 in[1], in[1]); 131 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 132 _mm256_storeu_si256((__m256i*)(out), results); 133 out += 8; 134 135 in += 2; 136 137 return in; 138 } 139 140 inline static const uint32_t* unpack3_32_avx2(const uint32_t* in, uint32_t* out) { 141 uint32_t mask = 0x7; 142 __m256i reg_shifts, reg_inls, reg_masks; 143 __m256i results; 144 145 reg_masks = _mm256_set1_epi32(mask); 146 147 // shift the first 8 outs 148 reg_shifts = _mm256_set_epi32(21, 18, 15, 12, 149 9, 6, 3, 0); 150 reg_inls = _mm256_set_epi32(in[0], in[0], 151 in[0], in[0], 152 in[0], in[0], 153 in[0], in[0]); 154 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 155 _mm256_storeu_si256((__m256i*)(out), results); 156 out += 8; 157 158 // shift the second 8 outs 159 reg_shifts = _mm256_set_epi32(13, 10, 7, 4, 160 1, 0, 27, 24); 161 reg_inls = _mm256_set_epi32(in[1], in[1], 162 in[1], in[1], 163 in[1], in[0] >> 30 | in[1] << 2, 164 in[0], in[0]); 165 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 166 _mm256_storeu_si256((__m256i*)(out), results); 167 out += 8; 168 169 // shift the third 8 outs 170 reg_shifts = _mm256_set_epi32(5, 2, 0, 28, 171 25, 22, 19, 16); 172 reg_inls = _mm256_set_epi32(in[2], in[2], 173 in[1] >> 31 | in[2] << 1, in[1], 174 in[1], in[1], 175 in[1], in[1]); 176 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 177 _mm256_storeu_si256((__m256i*)(out), results); 178 out += 8; 179 180 // shift the last 8 outs 181 reg_shifts = _mm256_set_epi32(29, 26, 23, 20, 182 17, 14, 11, 8); 183 reg_inls = _mm256_set_epi32(in[2], in[2], 184 in[2], in[2], 185 in[2], in[2], 186 in[2], in[2]); 187 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 188 _mm256_storeu_si256((__m256i*)(out), results); 189 out += 8; 190 191 in += 3; 192 193 return in; 194 } 195 196 inline static const uint32_t* unpack4_32_avx2(const uint32_t* in, uint32_t* out) { 197 uint32_t mask = 0xf; 198 __m256i reg_shifts, reg_inls, reg_masks; 199 __m256i results; 200 201 reg_masks = _mm256_set1_epi32(mask); 202 203 // shift the first 8 outs 204 reg_shifts = _mm256_set_epi32(28, 24, 20, 16, 205 12, 8, 4, 0); 206 reg_inls = _mm256_set_epi32(in[0], in[0], 207 in[0], in[0], 208 in[0], in[0], 209 in[0], in[0]); 210 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 211 _mm256_storeu_si256((__m256i*)(out), results); 212 out += 8; 213 214 // shift the second 8 outs 215 reg_shifts = _mm256_set_epi32(28, 24, 20, 16, 216 12, 8, 4, 0); 217 reg_inls = _mm256_set_epi32(in[1], in[1], 218 in[1], in[1], 219 in[1], in[1], 220 in[1], in[1]); 221 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 222 _mm256_storeu_si256((__m256i*)(out), results); 223 out += 8; 224 225 // shift the third 8 outs 226 reg_shifts = _mm256_set_epi32(28, 24, 20, 16, 227 12, 8, 4, 0); 228 reg_inls = _mm256_set_epi32(in[2], in[2], 229 in[2], in[2], 230 in[2], in[2], 231 in[2], in[2]); 232 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 233 _mm256_storeu_si256((__m256i*)(out), results); 234 out += 8; 235 236 // shift the last 8 outs 237 reg_shifts = _mm256_set_epi32(28, 24, 20, 16, 238 12, 8, 4, 0); 239 reg_inls = _mm256_set_epi32(in[3], in[3], 240 in[3], in[3], 241 in[3], in[3], 242 in[3], in[3]); 243 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 244 _mm256_storeu_si256((__m256i*)(out), results); 245 out += 8; 246 247 in += 4; 248 249 return in; 250 } 251 252 inline static const uint32_t* unpack5_32_avx2(const uint32_t* in, uint32_t* out) { 253 uint32_t mask = 0x1f; 254 __m256i reg_shifts, reg_inls, reg_masks; 255 __m256i results; 256 257 reg_masks = _mm256_set1_epi32(mask); 258 259 // shift the first 8 outs 260 reg_shifts = _mm256_set_epi32(3, 0, 25, 20, 261 15, 10, 5, 0); 262 reg_inls = _mm256_set_epi32(in[1], in[0] >> 30 | in[1] << 2, 263 in[0], in[0], 264 in[0], in[0], 265 in[0], in[0]); 266 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 267 _mm256_storeu_si256((__m256i*)(out), results); 268 out += 8; 269 270 // shift the second 8 outs 271 reg_shifts = _mm256_set_epi32(11, 6, 1, 0, 272 23, 18, 13, 8); 273 reg_inls = _mm256_set_epi32(in[2], in[2], 274 in[2], in[1] >> 28 | in[2] << 4, 275 in[1], in[1], 276 in[1], in[1]); 277 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 278 _mm256_storeu_si256((__m256i*)(out), results); 279 out += 8; 280 281 // shift the third 8 outs 282 reg_shifts = _mm256_set_epi32(19, 14, 9, 4, 283 0, 26, 21, 16); 284 reg_inls = _mm256_set_epi32(in[3], in[3], 285 in[3], in[3], 286 in[2] >> 31 | in[3] << 1, in[2], 287 in[2], in[2]); 288 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 289 _mm256_storeu_si256((__m256i*)(out), results); 290 out += 8; 291 292 // shift the last 8 outs 293 reg_shifts = _mm256_set_epi32(27, 22, 17, 12, 294 7, 2, 0, 24); 295 reg_inls = _mm256_set_epi32(in[4], in[4], 296 in[4], in[4], 297 in[4], in[4], 298 in[3] >> 29 | in[4] << 3, in[3]); 299 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 300 _mm256_storeu_si256((__m256i*)(out), results); 301 out += 8; 302 303 in += 5; 304 305 return in; 306 } 307 308 inline static const uint32_t* unpack6_32_avx2(const uint32_t* in, uint32_t* out) { 309 uint32_t mask = 0x3f; 310 __m256i reg_shifts, reg_inls, reg_masks; 311 __m256i results; 312 313 reg_masks = _mm256_set1_epi32(mask); 314 315 // shift the first 8 outs 316 reg_shifts = _mm256_set_epi32(10, 4, 0, 24, 317 18, 12, 6, 0); 318 reg_inls = _mm256_set_epi32(in[1], in[1], 319 in[0] >> 30 | in[1] << 2, in[0], 320 in[0], in[0], 321 in[0], in[0]); 322 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 323 _mm256_storeu_si256((__m256i*)(out), results); 324 out += 8; 325 326 // shift the second 8 outs 327 reg_shifts = _mm256_set_epi32(26, 20, 14, 8, 328 2, 0, 22, 16); 329 reg_inls = _mm256_set_epi32(in[2], in[2], 330 in[2], in[2], 331 in[2], in[1] >> 28 | in[2] << 4, 332 in[1], in[1]); 333 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 334 _mm256_storeu_si256((__m256i*)(out), results); 335 out += 8; 336 337 // shift the third 8 outs 338 reg_shifts = _mm256_set_epi32(10, 4, 0, 24, 339 18, 12, 6, 0); 340 reg_inls = _mm256_set_epi32(in[4], in[4], 341 in[3] >> 30 | in[4] << 2, in[3], 342 in[3], in[3], 343 in[3], in[3]); 344 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 345 _mm256_storeu_si256((__m256i*)(out), results); 346 out += 8; 347 348 // shift the last 8 outs 349 reg_shifts = _mm256_set_epi32(26, 20, 14, 8, 350 2, 0, 22, 16); 351 reg_inls = _mm256_set_epi32(in[5], in[5], 352 in[5], in[5], 353 in[5], in[4] >> 28 | in[5] << 4, 354 in[4], in[4]); 355 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 356 _mm256_storeu_si256((__m256i*)(out), results); 357 out += 8; 358 359 in += 6; 360 361 return in; 362 } 363 364 inline static const uint32_t* unpack7_32_avx2(const uint32_t* in, uint32_t* out) { 365 uint32_t mask = 0x7f; 366 __m256i reg_shifts, reg_inls, reg_masks; 367 __m256i results; 368 369 reg_masks = _mm256_set1_epi32(mask); 370 371 // shift the first 8 outs 372 reg_shifts = _mm256_set_epi32(17, 10, 3, 0, 373 21, 14, 7, 0); 374 reg_inls = _mm256_set_epi32(in[1], in[1], 375 in[1], in[0] >> 28 | in[1] << 4, 376 in[0], in[0], 377 in[0], in[0]); 378 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 379 _mm256_storeu_si256((__m256i*)(out), results); 380 out += 8; 381 382 // shift the second 8 outs 383 reg_shifts = _mm256_set_epi32(9, 2, 0, 20, 384 13, 6, 0, 24); 385 reg_inls = _mm256_set_epi32(in[3], in[3], 386 in[2] >> 27 | in[3] << 5, in[2], 387 in[2], in[2], 388 in[1] >> 31 | in[2] << 1, in[1]); 389 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 390 _mm256_storeu_si256((__m256i*)(out), results); 391 out += 8; 392 393 // shift the third 8 outs 394 reg_shifts = _mm256_set_epi32(1, 0, 19, 12, 395 5, 0, 23, 16); 396 reg_inls = _mm256_set_epi32(in[5], in[4] >> 26 | in[5] << 6, 397 in[4], in[4], 398 in[4], in[3] >> 30 | in[4] << 2, 399 in[3], in[3]); 400 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 401 _mm256_storeu_si256((__m256i*)(out), results); 402 out += 8; 403 404 // shift the last 8 outs 405 reg_shifts = _mm256_set_epi32(25, 18, 11, 4, 406 0, 22, 15, 8); 407 reg_inls = _mm256_set_epi32(in[6], in[6], 408 in[6], in[6], 409 in[5] >> 29 | in[6] << 3, in[5], 410 in[5], in[5]); 411 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 412 _mm256_storeu_si256((__m256i*)(out), results); 413 out += 8; 414 415 in += 7; 416 417 return in; 418 } 419 420 inline static const uint32_t* unpack8_32_avx2(const uint32_t* in, uint32_t* out) { 421 uint32_t mask = 0xff; 422 __m256i reg_shifts, reg_inls, reg_masks; 423 __m256i results; 424 425 reg_masks = _mm256_set1_epi32(mask); 426 427 // shift the first 8 outs 428 reg_shifts = _mm256_set_epi32(24, 16, 8, 0, 429 24, 16, 8, 0); 430 reg_inls = _mm256_set_epi32(in[1], in[1], 431 in[1], in[1], 432 in[0], in[0], 433 in[0], in[0]); 434 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 435 _mm256_storeu_si256((__m256i*)(out), results); 436 out += 8; 437 438 // shift the second 8 outs 439 reg_shifts = _mm256_set_epi32(24, 16, 8, 0, 440 24, 16, 8, 0); 441 reg_inls = _mm256_set_epi32(in[3], in[3], 442 in[3], in[3], 443 in[2], in[2], 444 in[2], in[2]); 445 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 446 _mm256_storeu_si256((__m256i*)(out), results); 447 out += 8; 448 449 // shift the third 8 outs 450 reg_shifts = _mm256_set_epi32(24, 16, 8, 0, 451 24, 16, 8, 0); 452 reg_inls = _mm256_set_epi32(in[5], in[5], 453 in[5], in[5], 454 in[4], in[4], 455 in[4], in[4]); 456 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 457 _mm256_storeu_si256((__m256i*)(out), results); 458 out += 8; 459 460 // shift the last 8 outs 461 reg_shifts = _mm256_set_epi32(24, 16, 8, 0, 462 24, 16, 8, 0); 463 reg_inls = _mm256_set_epi32(in[7], in[7], 464 in[7], in[7], 465 in[6], in[6], 466 in[6], in[6]); 467 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 468 _mm256_storeu_si256((__m256i*)(out), results); 469 out += 8; 470 471 in += 8; 472 473 return in; 474 } 475 476 inline static const uint32_t* unpack9_32_avx2(const uint32_t* in, uint32_t* out) { 477 uint32_t mask = 0x1ff; 478 __m256i reg_shifts, reg_inls, reg_masks; 479 __m256i results; 480 481 reg_masks = _mm256_set1_epi32(mask); 482 483 // shift the first 8 outs 484 reg_shifts = _mm256_set_epi32(0, 22, 13, 4, 485 0, 18, 9, 0); 486 reg_inls = _mm256_set_epi32(in[1] >> 31 | in[2] << 1, in[1], 487 in[1], in[1], 488 in[0] >> 27 | in[1] << 5, in[0], 489 in[0], in[0]); 490 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 491 _mm256_storeu_si256((__m256i*)(out), results); 492 out += 8; 493 494 // shift the second 8 outs 495 reg_shifts = _mm256_set_epi32(7, 0, 21, 12, 496 3, 0, 17, 8); 497 reg_inls = _mm256_set_epi32(in[4], in[3] >> 30 | in[4] << 2, 498 in[3], in[3], 499 in[3], in[2] >> 26 | in[3] << 6, 500 in[2], in[2]); 501 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 502 _mm256_storeu_si256((__m256i*)(out), results); 503 out += 8; 504 505 // shift the third 8 outs 506 reg_shifts = _mm256_set_epi32(15, 6, 0, 20, 507 11, 2, 0, 16); 508 reg_inls = _mm256_set_epi32(in[6], in[6], 509 in[5] >> 29 | in[6] << 3, in[5], 510 in[5], in[5], 511 in[4] >> 25 | in[5] << 7, in[4]); 512 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 513 _mm256_storeu_si256((__m256i*)(out), results); 514 out += 8; 515 516 // shift the last 8 outs 517 reg_shifts = _mm256_set_epi32(23, 14, 5, 0, 518 19, 10, 1, 0); 519 reg_inls = _mm256_set_epi32(in[8], in[8], 520 in[8], in[7] >> 28 | in[8] << 4, 521 in[7], in[7], 522 in[7], in[6] >> 24 | in[7] << 8); 523 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 524 _mm256_storeu_si256((__m256i*)(out), results); 525 out += 8; 526 527 in += 9; 528 529 return in; 530 } 531 532 inline static const uint32_t* unpack10_32_avx2(const uint32_t* in, uint32_t* out) { 533 uint32_t mask = 0x3ff; 534 __m256i reg_shifts, reg_inls, reg_masks; 535 __m256i results; 536 537 reg_masks = _mm256_set1_epi32(mask); 538 539 // shift the first 8 outs 540 reg_shifts = _mm256_set_epi32(6, 0, 18, 8, 541 0, 20, 10, 0); 542 reg_inls = _mm256_set_epi32(in[2], in[1] >> 28 | in[2] << 4, 543 in[1], in[1], 544 in[0] >> 30 | in[1] << 2, in[0], 545 in[0], in[0]); 546 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 547 _mm256_storeu_si256((__m256i*)(out), results); 548 out += 8; 549 550 // shift the second 8 outs 551 reg_shifts = _mm256_set_epi32(22, 12, 2, 0, 552 14, 4, 0, 16); 553 reg_inls = _mm256_set_epi32(in[4], in[4], 554 in[4], in[3] >> 24 | in[4] << 8, 555 in[3], in[3], 556 in[2] >> 26 | in[3] << 6, in[2]); 557 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 558 _mm256_storeu_si256((__m256i*)(out), results); 559 out += 8; 560 561 // shift the third 8 outs 562 reg_shifts = _mm256_set_epi32(6, 0, 18, 8, 563 0, 20, 10, 0); 564 reg_inls = _mm256_set_epi32(in[7], in[6] >> 28 | in[7] << 4, 565 in[6], in[6], 566 in[5] >> 30 | in[6] << 2, in[5], 567 in[5], in[5]); 568 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 569 _mm256_storeu_si256((__m256i*)(out), results); 570 out += 8; 571 572 // shift the last 8 outs 573 reg_shifts = _mm256_set_epi32(22, 12, 2, 0, 574 14, 4, 0, 16); 575 reg_inls = _mm256_set_epi32(in[9], in[9], 576 in[9], in[8] >> 24 | in[9] << 8, 577 in[8], in[8], 578 in[7] >> 26 | in[8] << 6, in[7]); 579 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 580 _mm256_storeu_si256((__m256i*)(out), results); 581 out += 8; 582 583 in += 10; 584 585 return in; 586 } 587 588 inline static const uint32_t* unpack11_32_avx2(const uint32_t* in, uint32_t* out) { 589 uint32_t mask = 0x7ff; 590 __m256i reg_shifts, reg_inls, reg_masks; 591 __m256i results; 592 593 reg_masks = _mm256_set1_epi32(mask); 594 595 // shift the first 8 outs 596 reg_shifts = _mm256_set_epi32(13, 2, 0, 12, 597 1, 0, 11, 0); 598 reg_inls = _mm256_set_epi32(in[2], in[2], 599 in[1] >> 23 | in[2] << 9, in[1], 600 in[1], in[0] >> 22 | in[1] << 10, 601 in[0], in[0]); 602 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 603 _mm256_storeu_si256((__m256i*)(out), results); 604 out += 8; 605 606 // shift the second 8 outs 607 reg_shifts = _mm256_set_epi32(5, 0, 15, 4, 608 0, 14, 3, 0); 609 reg_inls = _mm256_set_epi32(in[5], in[4] >> 26 | in[5] << 6, 610 in[4], in[4], 611 in[3] >> 25 | in[4] << 7, in[3], 612 in[3], in[2] >> 24 | in[3] << 8); 613 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 614 _mm256_storeu_si256((__m256i*)(out), results); 615 out += 8; 616 617 // shift the third 8 outs 618 reg_shifts = _mm256_set_epi32(0, 18, 7, 0, 619 17, 6, 0, 16); 620 reg_inls = _mm256_set_epi32(in[7] >> 29 | in[8] << 3, in[7], 621 in[7], in[6] >> 28 | in[7] << 4, 622 in[6], in[6], 623 in[5] >> 27 | in[6] << 5, in[5]); 624 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 625 _mm256_storeu_si256((__m256i*)(out), results); 626 out += 8; 627 628 // shift the last 8 outs 629 reg_shifts = _mm256_set_epi32(21, 10, 0, 20, 630 9, 0, 19, 8); 631 reg_inls = _mm256_set_epi32(in[10], in[10], 632 in[9] >> 31 | in[10] << 1, in[9], 633 in[9], in[8] >> 30 | in[9] << 2, 634 in[8], in[8]); 635 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 636 _mm256_storeu_si256((__m256i*)(out), results); 637 out += 8; 638 639 in += 11; 640 641 return in; 642 } 643 644 inline static const uint32_t* unpack12_32_avx2(const uint32_t* in, uint32_t* out) { 645 uint32_t mask = 0xfff; 646 __m256i reg_shifts, reg_inls, reg_masks; 647 __m256i results; 648 649 reg_masks = _mm256_set1_epi32(mask); 650 651 // shift the first 8 outs 652 reg_shifts = _mm256_set_epi32(20, 8, 0, 16, 653 4, 0, 12, 0); 654 reg_inls = _mm256_set_epi32(in[2], in[2], 655 in[1] >> 28 | in[2] << 4, in[1], 656 in[1], in[0] >> 24 | in[1] << 8, 657 in[0], in[0]); 658 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 659 _mm256_storeu_si256((__m256i*)(out), results); 660 out += 8; 661 662 // shift the second 8 outs 663 reg_shifts = _mm256_set_epi32(20, 8, 0, 16, 664 4, 0, 12, 0); 665 reg_inls = _mm256_set_epi32(in[5], in[5], 666 in[4] >> 28 | in[5] << 4, in[4], 667 in[4], in[3] >> 24 | in[4] << 8, 668 in[3], in[3]); 669 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 670 _mm256_storeu_si256((__m256i*)(out), results); 671 out += 8; 672 673 // shift the third 8 outs 674 reg_shifts = _mm256_set_epi32(20, 8, 0, 16, 675 4, 0, 12, 0); 676 reg_inls = _mm256_set_epi32(in[8], in[8], 677 in[7] >> 28 | in[8] << 4, in[7], 678 in[7], in[6] >> 24 | in[7] << 8, 679 in[6], in[6]); 680 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 681 _mm256_storeu_si256((__m256i*)(out), results); 682 out += 8; 683 684 // shift the last 8 outs 685 reg_shifts = _mm256_set_epi32(20, 8, 0, 16, 686 4, 0, 12, 0); 687 reg_inls = _mm256_set_epi32(in[11], in[11], 688 in[10] >> 28 | in[11] << 4, in[10], 689 in[10], in[9] >> 24 | in[10] << 8, 690 in[9], in[9]); 691 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 692 _mm256_storeu_si256((__m256i*)(out), results); 693 out += 8; 694 695 in += 12; 696 697 return in; 698 } 699 700 inline static const uint32_t* unpack13_32_avx2(const uint32_t* in, uint32_t* out) { 701 uint32_t mask = 0x1fff; 702 __m256i reg_shifts, reg_inls, reg_masks; 703 __m256i results; 704 705 reg_masks = _mm256_set1_epi32(mask); 706 707 // shift the first 8 outs 708 reg_shifts = _mm256_set_epi32(0, 14, 1, 0, 709 7, 0, 13, 0); 710 reg_inls = _mm256_set_epi32(in[2] >> 27 | in[3] << 5, in[2], 711 in[2], in[1] >> 20 | in[2] << 12, 712 in[1], in[0] >> 26 | in[1] << 6, 713 in[0], in[0]); 714 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 715 _mm256_storeu_si256((__m256i*)(out), results); 716 out += 8; 717 718 // shift the second 8 outs 719 reg_shifts = _mm256_set_epi32(3, 0, 9, 0, 720 15, 2, 0, 8); 721 reg_inls = _mm256_set_epi32(in[6], in[5] >> 22 | in[6] << 10, 722 in[5], in[4] >> 28 | in[5] << 4, 723 in[4], in[4], 724 in[3] >> 21 | in[4] << 11, in[3]); 725 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 726 _mm256_storeu_si256((__m256i*)(out), results); 727 out += 8; 728 729 // shift the third 8 outs 730 reg_shifts = _mm256_set_epi32(11, 0, 17, 4, 731 0, 10, 0, 16); 732 reg_inls = _mm256_set_epi32(in[9], in[8] >> 30 | in[9] << 2, 733 in[8], in[8], 734 in[7] >> 23 | in[8] << 9, in[7], 735 in[6] >> 29 | in[7] << 3, in[6]); 736 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 737 _mm256_storeu_si256((__m256i*)(out), results); 738 out += 8; 739 740 // shift the last 8 outs 741 reg_shifts = _mm256_set_epi32(19, 6, 0, 12, 742 0, 18, 5, 0); 743 reg_inls = _mm256_set_epi32(in[12], in[12], 744 in[11] >> 25 | in[12] << 7, in[11], 745 in[10] >> 31 | in[11] << 1, in[10], 746 in[10], in[9] >> 24 | in[10] << 8); 747 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 748 _mm256_storeu_si256((__m256i*)(out), results); 749 out += 8; 750 751 in += 13; 752 753 return in; 754 } 755 756 inline static const uint32_t* unpack14_32_avx2(const uint32_t* in, uint32_t* out) { 757 uint32_t mask = 0x3fff; 758 __m256i reg_shifts, reg_inls, reg_masks; 759 __m256i results; 760 761 reg_masks = _mm256_set1_epi32(mask); 762 763 // shift the first 8 outs 764 reg_shifts = _mm256_set_epi32(2, 0, 6, 0, 765 10, 0, 14, 0); 766 reg_inls = _mm256_set_epi32(in[3], in[2] >> 20 | in[3] << 12, 767 in[2], in[1] >> 24 | in[2] << 8, 768 in[1], in[0] >> 28 | in[1] << 4, 769 in[0], in[0]); 770 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 771 _mm256_storeu_si256((__m256i*)(out), results); 772 out += 8; 773 774 // shift the second 8 outs 775 reg_shifts = _mm256_set_epi32(18, 4, 0, 8, 776 0, 12, 0, 16); 777 reg_inls = _mm256_set_epi32(in[6], in[6], 778 in[5] >> 22 | in[6] << 10, in[5], 779 in[4] >> 26 | in[5] << 6, in[4], 780 in[3] >> 30 | in[4] << 2, in[3]); 781 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 782 _mm256_storeu_si256((__m256i*)(out), results); 783 out += 8; 784 785 // shift the third 8 outs 786 reg_shifts = _mm256_set_epi32(2, 0, 6, 0, 787 10, 0, 14, 0); 788 reg_inls = _mm256_set_epi32(in[10], in[9] >> 20 | in[10] << 12, 789 in[9], in[8] >> 24 | in[9] << 8, 790 in[8], in[7] >> 28 | in[8] << 4, 791 in[7], in[7]); 792 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 793 _mm256_storeu_si256((__m256i*)(out), results); 794 out += 8; 795 796 // shift the last 8 outs 797 reg_shifts = _mm256_set_epi32(18, 4, 0, 8, 798 0, 12, 0, 16); 799 reg_inls = _mm256_set_epi32(in[13], in[13], 800 in[12] >> 22 | in[13] << 10, in[12], 801 in[11] >> 26 | in[12] << 6, in[11], 802 in[10] >> 30 | in[11] << 2, in[10]); 803 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 804 _mm256_storeu_si256((__m256i*)(out), results); 805 out += 8; 806 807 in += 14; 808 809 return in; 810 } 811 812 inline static const uint32_t* unpack15_32_avx2(const uint32_t* in, uint32_t* out) { 813 uint32_t mask = 0x7fff; 814 __m256i reg_shifts, reg_inls, reg_masks; 815 __m256i results; 816 817 reg_masks = _mm256_set1_epi32(mask); 818 819 // shift the first 8 outs 820 reg_shifts = _mm256_set_epi32(9, 0, 11, 0, 821 13, 0, 15, 0); 822 reg_inls = _mm256_set_epi32(in[3], in[2] >> 26 | in[3] << 6, 823 in[2], in[1] >> 28 | in[2] << 4, 824 in[1], in[0] >> 30 | in[1] << 2, 825 in[0], in[0]); 826 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 827 _mm256_storeu_si256((__m256i*)(out), results); 828 out += 8; 829 830 // shift the second 8 outs 831 reg_shifts = _mm256_set_epi32(1, 0, 3, 0, 832 5, 0, 7, 0); 833 reg_inls = _mm256_set_epi32(in[7], in[6] >> 18 | in[7] << 14, 834 in[6], in[5] >> 20 | in[6] << 12, 835 in[5], in[4] >> 22 | in[5] << 10, 836 in[4], in[3] >> 24 | in[4] << 8); 837 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 838 _mm256_storeu_si256((__m256i*)(out), results); 839 out += 8; 840 841 // shift the third 8 outs 842 reg_shifts = _mm256_set_epi32(0, 10, 0, 12, 843 0, 14, 0, 16); 844 reg_inls = _mm256_set_epi32(in[10] >> 25 | in[11] << 7, in[10], 845 in[9] >> 27 | in[10] << 5, in[9], 846 in[8] >> 29 | in[9] << 3, in[8], 847 in[7] >> 31 | in[8] << 1, in[7]); 848 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 849 _mm256_storeu_si256((__m256i*)(out), results); 850 out += 8; 851 852 // shift the last 8 outs 853 reg_shifts = _mm256_set_epi32(17, 2, 0, 4, 854 0, 6, 0, 8); 855 reg_inls = _mm256_set_epi32(in[14], in[14], 856 in[13] >> 19 | in[14] << 13, in[13], 857 in[12] >> 21 | in[13] << 11, in[12], 858 in[11] >> 23 | in[12] << 9, in[11]); 859 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 860 _mm256_storeu_si256((__m256i*)(out), results); 861 out += 8; 862 863 in += 15; 864 865 return in; 866 } 867 868 inline static const uint32_t* unpack16_32_avx2(const uint32_t* in, uint32_t* out) { 869 uint32_t mask = 0xffff; 870 __m256i reg_shifts, reg_inls, reg_masks; 871 __m256i results; 872 873 reg_masks = _mm256_set1_epi32(mask); 874 875 // shift the first 8 outs 876 reg_shifts = _mm256_set_epi32(16, 0, 16, 0, 877 16, 0, 16, 0); 878 reg_inls = _mm256_set_epi32(in[3], in[3], 879 in[2], in[2], 880 in[1], in[1], 881 in[0], in[0]); 882 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 883 _mm256_storeu_si256((__m256i*)(out), results); 884 out += 8; 885 886 // shift the second 8 outs 887 reg_shifts = _mm256_set_epi32(16, 0, 16, 0, 888 16, 0, 16, 0); 889 reg_inls = _mm256_set_epi32(in[7], in[7], 890 in[6], in[6], 891 in[5], in[5], 892 in[4], in[4]); 893 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 894 _mm256_storeu_si256((__m256i*)(out), results); 895 out += 8; 896 897 // shift the third 8 outs 898 reg_shifts = _mm256_set_epi32(16, 0, 16, 0, 899 16, 0, 16, 0); 900 reg_inls = _mm256_set_epi32(in[11], in[11], 901 in[10], in[10], 902 in[9], in[9], 903 in[8], in[8]); 904 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 905 _mm256_storeu_si256((__m256i*)(out), results); 906 out += 8; 907 908 // shift the last 8 outs 909 reg_shifts = _mm256_set_epi32(16, 0, 16, 0, 910 16, 0, 16, 0); 911 reg_inls = _mm256_set_epi32(in[15], in[15], 912 in[14], in[14], 913 in[13], in[13], 914 in[12], in[12]); 915 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 916 _mm256_storeu_si256((__m256i*)(out), results); 917 out += 8; 918 919 in += 16; 920 921 return in; 922 } 923 924 inline static const uint32_t* unpack17_32_avx2(const uint32_t* in, uint32_t* out) { 925 uint32_t mask = 0x1ffff; 926 __m256i reg_shifts, reg_inls, reg_masks; 927 __m256i results; 928 929 reg_masks = _mm256_set1_epi32(mask); 930 931 // shift the first 8 outs 932 reg_shifts = _mm256_set_epi32(0, 6, 0, 4, 933 0, 2, 0, 0); 934 reg_inls = _mm256_set_epi32(in[3] >> 23 | in[4] << 9, in[3], 935 in[2] >> 21 | in[3] << 11, in[2], 936 in[1] >> 19 | in[2] << 13, in[1], 937 in[0] >> 17 | in[1] << 15, in[0]); 938 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 939 _mm256_storeu_si256((__m256i*)(out), results); 940 out += 8; 941 942 // shift the second 8 outs 943 reg_shifts = _mm256_set_epi32(0, 14, 0, 12, 944 0, 10, 0, 8); 945 reg_inls = _mm256_set_epi32(in[7] >> 31 | in[8] << 1, in[7], 946 in[6] >> 29 | in[7] << 3, in[6], 947 in[5] >> 27 | in[6] << 5, in[5], 948 in[4] >> 25 | in[5] << 7, in[4]); 949 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 950 _mm256_storeu_si256((__m256i*)(out), results); 951 out += 8; 952 953 // shift the third 8 outs 954 reg_shifts = _mm256_set_epi32(7, 0, 5, 0, 955 3, 0, 1, 0); 956 reg_inls = _mm256_set_epi32(in[12], in[11] >> 22 | in[12] << 10, 957 in[11], in[10] >> 20 | in[11] << 12, 958 in[10], in[9] >> 18 | in[10] << 14, 959 in[9], in[8] >> 16 | in[9] << 16); 960 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 961 _mm256_storeu_si256((__m256i*)(out), results); 962 out += 8; 963 964 // shift the last 8 outs 965 reg_shifts = _mm256_set_epi32(15, 0, 13, 0, 966 11, 0, 9, 0); 967 reg_inls = _mm256_set_epi32(in[16], in[15] >> 30 | in[16] << 2, 968 in[15], in[14] >> 28 | in[15] << 4, 969 in[14], in[13] >> 26 | in[14] << 6, 970 in[13], in[12] >> 24 | in[13] << 8); 971 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 972 _mm256_storeu_si256((__m256i*)(out), results); 973 out += 8; 974 975 in += 17; 976 977 return in; 978 } 979 980 inline static const uint32_t* unpack18_32_avx2(const uint32_t* in, uint32_t* out) { 981 uint32_t mask = 0x3ffff; 982 __m256i reg_shifts, reg_inls, reg_masks; 983 __m256i results; 984 985 reg_masks = _mm256_set1_epi32(mask); 986 987 // shift the first 8 outs 988 reg_shifts = _mm256_set_epi32(0, 12, 0, 8, 989 0, 4, 0, 0); 990 reg_inls = _mm256_set_epi32(in[3] >> 30 | in[4] << 2, in[3], 991 in[2] >> 26 | in[3] << 6, in[2], 992 in[1] >> 22 | in[2] << 10, in[1], 993 in[0] >> 18 | in[1] << 14, in[0]); 994 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 995 _mm256_storeu_si256((__m256i*)(out), results); 996 out += 8; 997 998 // shift the second 8 outs 999 reg_shifts = _mm256_set_epi32(14, 0, 10, 0, 1000 6, 0, 2, 0); 1001 reg_inls = _mm256_set_epi32(in[8], in[7] >> 28 | in[8] << 4, 1002 in[7], in[6] >> 24 | in[7] << 8, 1003 in[6], in[5] >> 20 | in[6] << 12, 1004 in[5], in[4] >> 16 | in[5] << 16); 1005 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1006 _mm256_storeu_si256((__m256i*)(out), results); 1007 out += 8; 1008 1009 // shift the third 8 outs 1010 reg_shifts = _mm256_set_epi32(0, 12, 0, 8, 1011 0, 4, 0, 0); 1012 reg_inls = _mm256_set_epi32(in[12] >> 30 | in[13] << 2, in[12], 1013 in[11] >> 26 | in[12] << 6, in[11], 1014 in[10] >> 22 | in[11] << 10, in[10], 1015 in[9] >> 18 | in[10] << 14, in[9]); 1016 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1017 _mm256_storeu_si256((__m256i*)(out), results); 1018 out += 8; 1019 1020 // shift the last 8 outs 1021 reg_shifts = _mm256_set_epi32(14, 0, 10, 0, 1022 6, 0, 2, 0); 1023 reg_inls = _mm256_set_epi32(in[17], in[16] >> 28 | in[17] << 4, 1024 in[16], in[15] >> 24 | in[16] << 8, 1025 in[15], in[14] >> 20 | in[15] << 12, 1026 in[14], in[13] >> 16 | in[14] << 16); 1027 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1028 _mm256_storeu_si256((__m256i*)(out), results); 1029 out += 8; 1030 1031 in += 18; 1032 1033 return in; 1034 } 1035 1036 inline static const uint32_t* unpack19_32_avx2(const uint32_t* in, uint32_t* out) { 1037 uint32_t mask = 0x7ffff; 1038 __m256i reg_shifts, reg_inls, reg_masks; 1039 __m256i results; 1040 1041 reg_masks = _mm256_set1_epi32(mask); 1042 1043 // shift the first 8 outs 1044 reg_shifts = _mm256_set_epi32(5, 0, 0, 12, 1045 0, 6, 0, 0); 1046 reg_inls = _mm256_set_epi32(in[4], in[3] >> 18 | in[4] << 14, 1047 in[2] >> 31 | in[3] << 1, in[2], 1048 in[1] >> 25 | in[2] << 7, in[1], 1049 in[0] >> 19 | in[1] << 13, in[0]); 1050 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1051 _mm256_storeu_si256((__m256i*)(out), results); 1052 out += 8; 1053 1054 // shift the second 8 outs 1055 reg_shifts = _mm256_set_epi32(0, 10, 0, 4, 1056 0, 0, 11, 0); 1057 reg_inls = _mm256_set_epi32(in[8] >> 29 | in[9] << 3, in[8], 1058 in[7] >> 23 | in[8] << 9, in[7], 1059 in[6] >> 17 | in[7] << 15, in[5] >> 30 | in[6] << 2, 1060 in[5], in[4] >> 24 | in[5] << 8); 1061 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1062 _mm256_storeu_si256((__m256i*)(out), results); 1063 out += 8; 1064 1065 // shift the third 8 outs 1066 reg_shifts = _mm256_set_epi32(0, 2, 0, 0, 1067 9, 0, 3, 0); 1068 reg_inls = _mm256_set_epi32(in[13] >> 21 | in[14] << 11, in[13], 1069 in[12] >> 15 | in[13] << 17, in[11] >> 28 | in[12] << 4, 1070 in[11], in[10] >> 22 | in[11] << 10, 1071 in[10], in[9] >> 16 | in[10] << 16); 1072 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1073 _mm256_storeu_si256((__m256i*)(out), results); 1074 out += 8; 1075 1076 // shift the last 8 outs 1077 reg_shifts = _mm256_set_epi32(13, 0, 7, 0, 1078 1, 0, 0, 8); 1079 reg_inls = _mm256_set_epi32(in[18], in[17] >> 26 | in[18] << 6, 1080 in[17], in[16] >> 20 | in[17] << 12, 1081 in[16], in[15] >> 14 | in[16] << 18, 1082 in[14] >> 27 | in[15] << 5, in[14]); 1083 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1084 _mm256_storeu_si256((__m256i*)(out), results); 1085 out += 8; 1086 1087 in += 19; 1088 1089 return in; 1090 } 1091 1092 inline static const uint32_t* unpack20_32_avx2(const uint32_t* in, uint32_t* out) { 1093 uint32_t mask = 0xfffff; 1094 __m256i reg_shifts, reg_inls, reg_masks; 1095 __m256i results; 1096 1097 reg_masks = _mm256_set1_epi32(mask); 1098 1099 // shift the first 8 outs 1100 reg_shifts = _mm256_set_epi32(12, 0, 4, 0, 1101 0, 8, 0, 0); 1102 reg_inls = _mm256_set_epi32(in[4], in[3] >> 24 | in[4] << 8, 1103 in[3], in[2] >> 16 | in[3] << 16, 1104 in[1] >> 28 | in[2] << 4, in[1], 1105 in[0] >> 20 | in[1] << 12, in[0]); 1106 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1107 _mm256_storeu_si256((__m256i*)(out), results); 1108 out += 8; 1109 1110 // shift the second 8 outs 1111 reg_shifts = _mm256_set_epi32(12, 0, 4, 0, 1112 0, 8, 0, 0); 1113 reg_inls = _mm256_set_epi32(in[9], in[8] >> 24 | in[9] << 8, 1114 in[8], in[7] >> 16 | in[8] << 16, 1115 in[6] >> 28 | in[7] << 4, in[6], 1116 in[5] >> 20 | in[6] << 12, in[5]); 1117 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1118 _mm256_storeu_si256((__m256i*)(out), results); 1119 out += 8; 1120 1121 // shift the third 8 outs 1122 reg_shifts = _mm256_set_epi32(12, 0, 4, 0, 1123 0, 8, 0, 0); 1124 reg_inls = _mm256_set_epi32(in[14], in[13] >> 24 | in[14] << 8, 1125 in[13], in[12] >> 16 | in[13] << 16, 1126 in[11] >> 28 | in[12] << 4, in[11], 1127 in[10] >> 20 | in[11] << 12, in[10]); 1128 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1129 _mm256_storeu_si256((__m256i*)(out), results); 1130 out += 8; 1131 1132 // shift the last 8 outs 1133 reg_shifts = _mm256_set_epi32(12, 0, 4, 0, 1134 0, 8, 0, 0); 1135 reg_inls = _mm256_set_epi32(in[19], in[18] >> 24 | in[19] << 8, 1136 in[18], in[17] >> 16 | in[18] << 16, 1137 in[16] >> 28 | in[17] << 4, in[16], 1138 in[15] >> 20 | in[16] << 12, in[15]); 1139 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1140 _mm256_storeu_si256((__m256i*)(out), results); 1141 out += 8; 1142 1143 in += 20; 1144 1145 return in; 1146 } 1147 1148 inline static const uint32_t* unpack21_32_avx2(const uint32_t* in, uint32_t* out) { 1149 uint32_t mask = 0x1fffff; 1150 __m256i reg_shifts, reg_inls, reg_masks; 1151 __m256i results; 1152 1153 reg_masks = _mm256_set1_epi32(mask); 1154 1155 // shift the first 8 outs 1156 reg_shifts = _mm256_set_epi32(0, 0, 9, 0, 1157 0, 10, 0, 0); 1158 reg_inls = _mm256_set_epi32(in[4] >> 19 | in[5] << 13, in[3] >> 30 | in[4] << 2, 1159 in[3], in[2] >> 20 | in[3] << 12, 1160 in[1] >> 31 | in[2] << 1, in[1], 1161 in[0] >> 21 | in[1] << 11, in[0]); 1162 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1163 _mm256_storeu_si256((__m256i*)(out), results); 1164 out += 8; 1165 1166 // shift the second 8 outs 1167 reg_shifts = _mm256_set_epi32(0, 6, 0, 0, 1168 7, 0, 0, 8); 1169 reg_inls = _mm256_set_epi32(in[9] >> 27 | in[10] << 5, in[9], 1170 in[8] >> 17 | in[9] << 15, in[7] >> 28 | in[8] << 4, 1171 in[7], in[6] >> 18 | in[7] << 14, 1172 in[5] >> 29 | in[6] << 3, in[5]); 1173 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1174 _mm256_storeu_si256((__m256i*)(out), results); 1175 out += 8; 1176 1177 // shift the third 8 outs 1178 reg_shifts = _mm256_set_epi32(3, 0, 0, 4, 1179 0, 0, 5, 0); 1180 reg_inls = _mm256_set_epi32(in[15], in[14] >> 14 | in[15] << 18, 1181 in[13] >> 25 | in[14] << 7, in[13], 1182 in[12] >> 15 | in[13] << 17, in[11] >> 26 | in[12] << 6, 1183 in[11], in[10] >> 16 | in[11] << 16); 1184 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1185 _mm256_storeu_si256((__m256i*)(out), results); 1186 out += 8; 1187 1188 // shift the last 8 outs 1189 reg_shifts = _mm256_set_epi32(11, 0, 1, 0, 1190 0, 2, 0, 0); 1191 reg_inls = _mm256_set_epi32(in[20], in[19] >> 22 | in[20] << 10, 1192 in[19], in[18] >> 12 | in[19] << 20, 1193 in[17] >> 23 | in[18] << 9, in[17], 1194 in[16] >> 13 | in[17] << 19, in[15] >> 24 | in[16] << 8); 1195 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1196 _mm256_storeu_si256((__m256i*)(out), results); 1197 out += 8; 1198 1199 in += 21; 1200 1201 return in; 1202 } 1203 1204 inline static const uint32_t* unpack22_32_avx2(const uint32_t* in, uint32_t* out) { 1205 uint32_t mask = 0x3fffff; 1206 __m256i reg_shifts, reg_inls, reg_masks; 1207 __m256i results; 1208 1209 reg_masks = _mm256_set1_epi32(mask); 1210 1211 // shift the first 8 outs 1212 reg_shifts = _mm256_set_epi32(0, 4, 0, 0, 1213 2, 0, 0, 0); 1214 reg_inls = _mm256_set_epi32(in[4] >> 26 | in[5] << 6, in[4], 1215 in[3] >> 14 | in[4] << 18, in[2] >> 24 | in[3] << 8, 1216 in[2], in[1] >> 12 | in[2] << 20, 1217 in[0] >> 22 | in[1] << 10, in[0]); 1218 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1219 _mm256_storeu_si256((__m256i*)(out), results); 1220 out += 8; 1221 1222 // shift the second 8 outs 1223 reg_shifts = _mm256_set_epi32(10, 0, 0, 8, 1224 0, 0, 6, 0); 1225 reg_inls = _mm256_set_epi32(in[10], in[9] >> 20 | in[10] << 12, 1226 in[8] >> 30 | in[9] << 2, in[8], 1227 in[7] >> 18 | in[8] << 14, in[6] >> 28 | in[7] << 4, 1228 in[6], in[5] >> 16 | in[6] << 16); 1229 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1230 _mm256_storeu_si256((__m256i*)(out), results); 1231 out += 8; 1232 1233 // shift the third 8 outs 1234 reg_shifts = _mm256_set_epi32(0, 4, 0, 0, 1235 2, 0, 0, 0); 1236 reg_inls = _mm256_set_epi32(in[15] >> 26 | in[16] << 6, in[15], 1237 in[14] >> 14 | in[15] << 18, in[13] >> 24 | in[14] << 8, 1238 in[13], in[12] >> 12 | in[13] << 20, 1239 in[11] >> 22 | in[12] << 10, in[11]); 1240 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1241 _mm256_storeu_si256((__m256i*)(out), results); 1242 out += 8; 1243 1244 // shift the last 8 outs 1245 reg_shifts = _mm256_set_epi32(10, 0, 0, 8, 1246 0, 0, 6, 0); 1247 reg_inls = _mm256_set_epi32(in[21], in[20] >> 20 | in[21] << 12, 1248 in[19] >> 30 | in[20] << 2, in[19], 1249 in[18] >> 18 | in[19] << 14, in[17] >> 28 | in[18] << 4, 1250 in[17], in[16] >> 16 | in[17] << 16); 1251 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1252 _mm256_storeu_si256((__m256i*)(out), results); 1253 out += 8; 1254 1255 in += 22; 1256 1257 return in; 1258 } 1259 1260 inline static const uint32_t* unpack23_32_avx2(const uint32_t* in, uint32_t* out) { 1261 uint32_t mask = 0x7fffff; 1262 __m256i reg_shifts, reg_inls, reg_masks; 1263 __m256i results; 1264 1265 reg_masks = _mm256_set1_epi32(mask); 1266 1267 // shift the first 8 outs 1268 reg_shifts = _mm256_set_epi32(1, 0, 0, 0, 1269 5, 0, 0, 0); 1270 reg_inls = _mm256_set_epi32(in[5], in[4] >> 10 | in[5] << 22, 1271 in[3] >> 19 | in[4] << 13, in[2] >> 28 | in[3] << 4, 1272 in[2], in[1] >> 14 | in[2] << 18, 1273 in[0] >> 23 | in[1] << 9, in[0]); 1274 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1275 _mm256_storeu_si256((__m256i*)(out), results); 1276 out += 8; 1277 1278 // shift the second 8 outs 1279 reg_shifts = _mm256_set_epi32(0, 2, 0, 0, 1280 0, 6, 0, 0); 1281 reg_inls = _mm256_set_epi32(in[10] >> 25 | in[11] << 7, in[10], 1282 in[9] >> 11 | in[10] << 21, in[8] >> 20 | in[9] << 12, 1283 in[7] >> 29 | in[8] << 3, in[7], 1284 in[6] >> 15 | in[7] << 17, in[5] >> 24 | in[6] << 8); 1285 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1286 _mm256_storeu_si256((__m256i*)(out), results); 1287 out += 8; 1288 1289 // shift the third 8 outs 1290 reg_shifts = _mm256_set_epi32(0, 0, 3, 0, 1291 0, 0, 7, 0); 1292 reg_inls = _mm256_set_epi32(in[16] >> 17 | in[17] << 15, in[15] >> 26 | in[16] << 6, 1293 in[15], in[14] >> 12 | in[15] << 20, 1294 in[13] >> 21 | in[14] << 11, in[12] >> 30 | in[13] << 2, 1295 in[12], in[11] >> 16 | in[12] << 16); 1296 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1297 _mm256_storeu_si256((__m256i*)(out), results); 1298 out += 8; 1299 1300 // shift the last 8 outs 1301 reg_shifts = _mm256_set_epi32(9, 0, 0, 4, 1302 0, 0, 0, 8); 1303 reg_inls = _mm256_set_epi32(in[22], in[21] >> 18 | in[22] << 14, 1304 in[20] >> 27 | in[21] << 5, in[20], 1305 in[19] >> 13 | in[20] << 19, in[18] >> 22 | in[19] << 10, 1306 in[17] >> 31 | in[18] << 1, in[17]); 1307 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1308 _mm256_storeu_si256((__m256i*)(out), results); 1309 out += 8; 1310 1311 in += 23; 1312 1313 return in; 1314 } 1315 1316 inline static const uint32_t* unpack24_32_avx2(const uint32_t* in, uint32_t* out) { 1317 uint32_t mask = 0xffffff; 1318 __m256i reg_shifts, reg_inls, reg_masks; 1319 __m256i results; 1320 1321 reg_masks = _mm256_set1_epi32(mask); 1322 1323 // shift the first 8 outs 1324 reg_shifts = _mm256_set_epi32(8, 0, 0, 0, 1325 8, 0, 0, 0); 1326 reg_inls = _mm256_set_epi32(in[5], in[4] >> 16 | in[5] << 16, 1327 in[3] >> 24 | in[4] << 8, in[3], 1328 in[2], in[1] >> 16 | in[2] << 16, 1329 in[0] >> 24 | in[1] << 8, in[0]); 1330 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1331 _mm256_storeu_si256((__m256i*)(out), results); 1332 out += 8; 1333 1334 // shift the second 8 outs 1335 reg_shifts = _mm256_set_epi32(8, 0, 0, 0, 1336 8, 0, 0, 0); 1337 reg_inls = _mm256_set_epi32(in[11], in[10] >> 16 | in[11] << 16, 1338 in[9] >> 24 | in[10] << 8, in[9], 1339 in[8], in[7] >> 16 | in[8] << 16, 1340 in[6] >> 24 | in[7] << 8, in[6]); 1341 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1342 _mm256_storeu_si256((__m256i*)(out), results); 1343 out += 8; 1344 1345 // shift the third 8 outs 1346 reg_shifts = _mm256_set_epi32(8, 0, 0, 0, 1347 8, 0, 0, 0); 1348 reg_inls = _mm256_set_epi32(in[17], in[16] >> 16 | in[17] << 16, 1349 in[15] >> 24 | in[16] << 8, in[15], 1350 in[14], in[13] >> 16 | in[14] << 16, 1351 in[12] >> 24 | in[13] << 8, in[12]); 1352 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1353 _mm256_storeu_si256((__m256i*)(out), results); 1354 out += 8; 1355 1356 // shift the last 8 outs 1357 reg_shifts = _mm256_set_epi32(8, 0, 0, 0, 1358 8, 0, 0, 0); 1359 reg_inls = _mm256_set_epi32(in[23], in[22] >> 16 | in[23] << 16, 1360 in[21] >> 24 | in[22] << 8, in[21], 1361 in[20], in[19] >> 16 | in[20] << 16, 1362 in[18] >> 24 | in[19] << 8, in[18]); 1363 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1364 _mm256_storeu_si256((__m256i*)(out), results); 1365 out += 8; 1366 1367 in += 24; 1368 1369 return in; 1370 } 1371 1372 inline static const uint32_t* unpack25_32_avx2(const uint32_t* in, uint32_t* out) { 1373 uint32_t mask = 0x1ffffff; 1374 __m256i reg_shifts, reg_inls, reg_masks; 1375 __m256i results; 1376 1377 reg_masks = _mm256_set1_epi32(mask); 1378 1379 // shift the first 8 outs 1380 reg_shifts = _mm256_set_epi32(0, 0, 0, 4, 1381 0, 0, 0, 0); 1382 reg_inls = _mm256_set_epi32(in[5] >> 15 | in[6] << 17, in[4] >> 22 | in[5] << 10, 1383 in[3] >> 29 | in[4] << 3, in[3], 1384 in[2] >> 11 | in[3] << 21, in[1] >> 18 | in[2] << 14, 1385 in[0] >> 25 | in[1] << 7, in[0]); 1386 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1387 _mm256_storeu_si256((__m256i*)(out), results); 1388 out += 8; 1389 1390 // shift the second 8 outs 1391 reg_shifts = _mm256_set_epi32(0, 0, 5, 0, 1392 0, 0, 1, 0); 1393 reg_inls = _mm256_set_epi32(in[11] >> 23 | in[12] << 9, in[10] >> 30 | in[11] << 2, 1394 in[10], in[9] >> 12 | in[10] << 20, 1395 in[8] >> 19 | in[9] << 13, in[7] >> 26 | in[8] << 6, 1396 in[7], in[6] >> 8 | in[7] << 24); 1397 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1398 _mm256_storeu_si256((__m256i*)(out), results); 1399 out += 8; 1400 1401 // shift the third 8 outs 1402 reg_shifts = _mm256_set_epi32(0, 6, 0, 0, 1403 0, 2, 0, 0); 1404 reg_inls = _mm256_set_epi32(in[17] >> 31 | in[18] << 1, in[17], 1405 in[16] >> 13 | in[17] << 19, in[15] >> 20 | in[16] << 12, 1406 in[14] >> 27 | in[15] << 5, in[14], 1407 in[13] >> 9 | in[14] << 23, in[12] >> 16 | in[13] << 16); 1408 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1409 _mm256_storeu_si256((__m256i*)(out), results); 1410 out += 8; 1411 1412 // shift the last 8 outs 1413 reg_shifts = _mm256_set_epi32(7, 0, 0, 0, 1414 3, 0, 0, 0); 1415 reg_inls = _mm256_set_epi32(in[24], in[23] >> 14 | in[24] << 18, 1416 in[22] >> 21 | in[23] << 11, in[21] >> 28 | in[22] << 4, 1417 in[21], in[20] >> 10 | in[21] << 22, 1418 in[19] >> 17 | in[20] << 15, in[18] >> 24 | in[19] << 8); 1419 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1420 _mm256_storeu_si256((__m256i*)(out), results); 1421 out += 8; 1422 1423 in += 25; 1424 1425 return in; 1426 } 1427 1428 inline static const uint32_t* unpack26_32_avx2(const uint32_t* in, uint32_t* out) { 1429 uint32_t mask = 0x3ffffff; 1430 __m256i reg_shifts, reg_inls, reg_masks; 1431 __m256i results; 1432 1433 reg_masks = _mm256_set1_epi32(mask); 1434 1435 // shift the first 8 outs 1436 reg_shifts = _mm256_set_epi32(0, 0, 2, 0, 1437 0, 0, 0, 0); 1438 reg_inls = _mm256_set_epi32(in[5] >> 22 | in[6] << 10, in[4] >> 28 | in[5] << 4, 1439 in[4], in[3] >> 8 | in[4] << 24, 1440 in[2] >> 14 | in[3] << 18, in[1] >> 20 | in[2] << 12, 1441 in[0] >> 26 | in[1] << 6, in[0]); 1442 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1443 _mm256_storeu_si256((__m256i*)(out), results); 1444 out += 8; 1445 1446 // shift the second 8 outs 1447 reg_shifts = _mm256_set_epi32(6, 0, 0, 0, 1448 0, 4, 0, 0); 1449 reg_inls = _mm256_set_epi32(in[12], in[11] >> 12 | in[12] << 20, 1450 in[10] >> 18 | in[11] << 14, in[9] >> 24 | in[10] << 8, 1451 in[8] >> 30 | in[9] << 2, in[8], 1452 in[7] >> 10 | in[8] << 22, in[6] >> 16 | in[7] << 16); 1453 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1454 _mm256_storeu_si256((__m256i*)(out), results); 1455 out += 8; 1456 1457 // shift the third 8 outs 1458 reg_shifts = _mm256_set_epi32(0, 0, 2, 0, 1459 0, 0, 0, 0); 1460 reg_inls = _mm256_set_epi32(in[18] >> 22 | in[19] << 10, in[17] >> 28 | in[18] << 4, 1461 in[17], in[16] >> 8 | in[17] << 24, 1462 in[15] >> 14 | in[16] << 18, in[14] >> 20 | in[15] << 12, 1463 in[13] >> 26 | in[14] << 6, in[13]); 1464 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1465 _mm256_storeu_si256((__m256i*)(out), results); 1466 out += 8; 1467 1468 // shift the last 8 outs 1469 reg_shifts = _mm256_set_epi32(6, 0, 0, 0, 1470 0, 4, 0, 0); 1471 reg_inls = _mm256_set_epi32(in[25], in[24] >> 12 | in[25] << 20, 1472 in[23] >> 18 | in[24] << 14, in[22] >> 24 | in[23] << 8, 1473 in[21] >> 30 | in[22] << 2, in[21], 1474 in[20] >> 10 | in[21] << 22, in[19] >> 16 | in[20] << 16); 1475 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1476 _mm256_storeu_si256((__m256i*)(out), results); 1477 out += 8; 1478 1479 in += 26; 1480 1481 return in; 1482 } 1483 1484 inline static const uint32_t* unpack27_32_avx2(const uint32_t* in, uint32_t* out) { 1485 uint32_t mask = 0x7ffffff; 1486 __m256i reg_shifts, reg_inls, reg_masks; 1487 __m256i results; 1488 1489 reg_masks = _mm256_set1_epi32(mask); 1490 1491 // shift the first 8 outs 1492 reg_shifts = _mm256_set_epi32(0, 2, 0, 0, 1493 0, 0, 0, 0); 1494 reg_inls = _mm256_set_epi32(in[5] >> 29 | in[6] << 3, in[5], 1495 in[4] >> 7 | in[5] << 25, in[3] >> 12 | in[4] << 20, 1496 in[2] >> 17 | in[3] << 15, in[1] >> 22 | in[2] << 10, 1497 in[0] >> 27 | in[1] << 5, in[0]); 1498 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1499 _mm256_storeu_si256((__m256i*)(out), results); 1500 out += 8; 1501 1502 // shift the second 8 outs 1503 reg_shifts = _mm256_set_epi32(0, 0, 0, 4, 1504 0, 0, 0, 0); 1505 reg_inls = _mm256_set_epi32(in[12] >> 21 | in[13] << 11, in[11] >> 26 | in[12] << 6, 1506 in[10] >> 31 | in[11] << 1, in[10], 1507 in[9] >> 9 | in[10] << 23, in[8] >> 14 | in[9] << 18, 1508 in[7] >> 19 | in[8] << 13, in[6] >> 24 | in[7] << 8); 1509 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1510 _mm256_storeu_si256((__m256i*)(out), results); 1511 out += 8; 1512 1513 // shift the third 8 outs 1514 reg_shifts = _mm256_set_epi32(0, 0, 0, 0, 1515 1, 0, 0, 0); 1516 reg_inls = _mm256_set_epi32(in[19] >> 13 | in[20] << 19, in[18] >> 18 | in[19] << 14, 1517 in[17] >> 23 | in[18] << 9, in[16] >> 28 | in[17] << 4, 1518 in[16], in[15] >> 6 | in[16] << 26, 1519 in[14] >> 11 | in[15] << 21, in[13] >> 16 | in[14] << 16); 1520 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1521 _mm256_storeu_si256((__m256i*)(out), results); 1522 out += 8; 1523 1524 // shift the last 8 outs 1525 reg_shifts = _mm256_set_epi32(5, 0, 0, 0, 1526 0, 0, 3, 0); 1527 reg_inls = _mm256_set_epi32(in[26], in[25] >> 10 | in[26] << 22, 1528 in[24] >> 15 | in[25] << 17, in[23] >> 20 | in[24] << 12, 1529 in[22] >> 25 | in[23] << 7, in[21] >> 30 | in[22] << 2, 1530 in[21], in[20] >> 8 | in[21] << 24); 1531 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1532 _mm256_storeu_si256((__m256i*)(out), results); 1533 out += 8; 1534 1535 in += 27; 1536 1537 return in; 1538 } 1539 1540 inline static const uint32_t* unpack28_32_avx2(const uint32_t* in, uint32_t* out) { 1541 uint32_t mask = 0xfffffff; 1542 __m256i reg_shifts, reg_inls, reg_masks; 1543 __m256i results; 1544 1545 reg_masks = _mm256_set1_epi32(mask); 1546 1547 // shift the first 8 outs 1548 reg_shifts = _mm256_set_epi32(4, 0, 0, 0, 1549 0, 0, 0, 0); 1550 reg_inls = _mm256_set_epi32(in[6], in[5] >> 8 | in[6] << 24, 1551 in[4] >> 12 | in[5] << 20, in[3] >> 16 | in[4] << 16, 1552 in[2] >> 20 | in[3] << 12, in[1] >> 24 | in[2] << 8, 1553 in[0] >> 28 | in[1] << 4, in[0]); 1554 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1555 _mm256_storeu_si256((__m256i*)(out), results); 1556 out += 8; 1557 1558 // shift the second 8 outs 1559 reg_shifts = _mm256_set_epi32(4, 0, 0, 0, 1560 0, 0, 0, 0); 1561 reg_inls = _mm256_set_epi32(in[13], in[12] >> 8 | in[13] << 24, 1562 in[11] >> 12 | in[12] << 20, in[10] >> 16 | in[11] << 16, 1563 in[9] >> 20 | in[10] << 12, in[8] >> 24 | in[9] << 8, 1564 in[7] >> 28 | in[8] << 4, in[7]); 1565 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1566 _mm256_storeu_si256((__m256i*)(out), results); 1567 out += 8; 1568 1569 // shift the third 8 outs 1570 reg_shifts = _mm256_set_epi32(4, 0, 0, 0, 1571 0, 0, 0, 0); 1572 reg_inls = _mm256_set_epi32(in[20], in[19] >> 8 | in[20] << 24, 1573 in[18] >> 12 | in[19] << 20, in[17] >> 16 | in[18] << 16, 1574 in[16] >> 20 | in[17] << 12, in[15] >> 24 | in[16] << 8, 1575 in[14] >> 28 | in[15] << 4, in[14]); 1576 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1577 _mm256_storeu_si256((__m256i*)(out), results); 1578 out += 8; 1579 1580 // shift the last 8 outs 1581 reg_shifts = _mm256_set_epi32(4, 0, 0, 0, 1582 0, 0, 0, 0); 1583 reg_inls = _mm256_set_epi32(in[27], in[26] >> 8 | in[27] << 24, 1584 in[25] >> 12 | in[26] << 20, in[24] >> 16 | in[25] << 16, 1585 in[23] >> 20 | in[24] << 12, in[22] >> 24 | in[23] << 8, 1586 in[21] >> 28 | in[22] << 4, in[21]); 1587 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1588 _mm256_storeu_si256((__m256i*)(out), results); 1589 out += 8; 1590 1591 in += 28; 1592 1593 return in; 1594 } 1595 1596 inline static const uint32_t* unpack29_32_avx2(const uint32_t* in, uint32_t* out) { 1597 uint32_t mask = 0x1fffffff; 1598 __m256i reg_shifts, reg_inls, reg_masks; 1599 __m256i results; 1600 1601 reg_masks = _mm256_set1_epi32(mask); 1602 1603 // shift the first 8 outs 1604 reg_shifts = _mm256_set_epi32(0, 0, 0, 0, 1605 0, 0, 0, 0); 1606 reg_inls = _mm256_set_epi32(in[6] >> 11 | in[7] << 21, in[5] >> 14 | in[6] << 18, 1607 in[4] >> 17 | in[5] << 15, in[3] >> 20 | in[4] << 12, 1608 in[2] >> 23 | in[3] << 9, in[1] >> 26 | in[2] << 6, 1609 in[0] >> 29 | in[1] << 3, in[0]); 1610 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1611 _mm256_storeu_si256((__m256i*)(out), results); 1612 out += 8; 1613 1614 // shift the second 8 outs 1615 reg_shifts = _mm256_set_epi32(0, 0, 0, 0, 1616 0, 2, 0, 0); 1617 reg_inls = _mm256_set_epi32(in[13] >> 19 | in[14] << 13, in[12] >> 22 | in[13] << 10, 1618 in[11] >> 25 | in[12] << 7, in[10] >> 28 | in[11] << 4, 1619 in[9] >> 31 | in[10] << 1, in[9], 1620 in[8] >> 5 | in[9] << 27, in[7] >> 8 | in[8] << 24); 1621 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1622 _mm256_storeu_si256((__m256i*)(out), results); 1623 out += 8; 1624 1625 // shift the third 8 outs 1626 reg_shifts = _mm256_set_epi32(0, 0, 1, 0, 1627 0, 0, 0, 0); 1628 reg_inls = _mm256_set_epi32(in[20] >> 27 | in[21] << 5, in[19] >> 30 | in[20] << 2, 1629 in[19], in[18] >> 4 | in[19] << 28, 1630 in[17] >> 7 | in[18] << 25, in[16] >> 10 | in[17] << 22, 1631 in[15] >> 13 | in[16] << 19, in[14] >> 16 | in[15] << 16); 1632 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1633 _mm256_storeu_si256((__m256i*)(out), results); 1634 out += 8; 1635 1636 // shift the last 8 outs 1637 reg_shifts = _mm256_set_epi32(3, 0, 0, 0, 1638 0, 0, 0, 0); 1639 reg_inls = _mm256_set_epi32(in[28], in[27] >> 6 | in[28] << 26, 1640 in[26] >> 9 | in[27] << 23, in[25] >> 12 | in[26] << 20, 1641 in[24] >> 15 | in[25] << 17, in[23] >> 18 | in[24] << 14, 1642 in[22] >> 21 | in[23] << 11, in[21] >> 24 | in[22] << 8); 1643 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1644 _mm256_storeu_si256((__m256i*)(out), results); 1645 out += 8; 1646 1647 in += 29; 1648 1649 return in; 1650 } 1651 1652 inline static const uint32_t* unpack30_32_avx2(const uint32_t* in, uint32_t* out) { 1653 uint32_t mask = 0x3fffffff; 1654 __m256i reg_shifts, reg_inls, reg_masks; 1655 __m256i results; 1656 1657 reg_masks = _mm256_set1_epi32(mask); 1658 1659 // shift the first 8 outs 1660 reg_shifts = _mm256_set_epi32(0, 0, 0, 0, 1661 0, 0, 0, 0); 1662 reg_inls = _mm256_set_epi32(in[6] >> 18 | in[7] << 14, in[5] >> 20 | in[6] << 12, 1663 in[4] >> 22 | in[5] << 10, in[3] >> 24 | in[4] << 8, 1664 in[2] >> 26 | in[3] << 6, in[1] >> 28 | in[2] << 4, 1665 in[0] >> 30 | in[1] << 2, in[0]); 1666 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1667 _mm256_storeu_si256((__m256i*)(out), results); 1668 out += 8; 1669 1670 // shift the second 8 outs 1671 reg_shifts = _mm256_set_epi32(2, 0, 0, 0, 1672 0, 0, 0, 0); 1673 reg_inls = _mm256_set_epi32(in[14], in[13] >> 4 | in[14] << 28, 1674 in[12] >> 6 | in[13] << 26, in[11] >> 8 | in[12] << 24, 1675 in[10] >> 10 | in[11] << 22, in[9] >> 12 | in[10] << 20, 1676 in[8] >> 14 | in[9] << 18, in[7] >> 16 | in[8] << 16); 1677 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1678 _mm256_storeu_si256((__m256i*)(out), results); 1679 out += 8; 1680 1681 // shift the third 8 outs 1682 reg_shifts = _mm256_set_epi32(0, 0, 0, 0, 1683 0, 0, 0, 0); 1684 reg_inls = _mm256_set_epi32(in[21] >> 18 | in[22] << 14, in[20] >> 20 | in[21] << 12, 1685 in[19] >> 22 | in[20] << 10, in[18] >> 24 | in[19] << 8, 1686 in[17] >> 26 | in[18] << 6, in[16] >> 28 | in[17] << 4, 1687 in[15] >> 30 | in[16] << 2, in[15]); 1688 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1689 _mm256_storeu_si256((__m256i*)(out), results); 1690 out += 8; 1691 1692 // shift the last 8 outs 1693 reg_shifts = _mm256_set_epi32(2, 0, 0, 0, 1694 0, 0, 0, 0); 1695 reg_inls = _mm256_set_epi32(in[29], in[28] >> 4 | in[29] << 28, 1696 in[27] >> 6 | in[28] << 26, in[26] >> 8 | in[27] << 24, 1697 in[25] >> 10 | in[26] << 22, in[24] >> 12 | in[25] << 20, 1698 in[23] >> 14 | in[24] << 18, in[22] >> 16 | in[23] << 16); 1699 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1700 _mm256_storeu_si256((__m256i*)(out), results); 1701 out += 8; 1702 1703 in += 30; 1704 1705 return in; 1706 } 1707 1708 inline static const uint32_t* unpack31_32_avx2(const uint32_t* in, uint32_t* out) { 1709 uint32_t mask = 0x7fffffff; 1710 __m256i reg_shifts, reg_inls, reg_masks; 1711 __m256i results; 1712 1713 reg_masks = _mm256_set1_epi32(mask); 1714 1715 // shift the first 8 outs 1716 reg_shifts = _mm256_set_epi32(0, 0, 0, 0, 1717 0, 0, 0, 0); 1718 reg_inls = _mm256_set_epi32(in[6] >> 25 | in[7] << 7, in[5] >> 26 | in[6] << 6, 1719 in[4] >> 27 | in[5] << 5, in[3] >> 28 | in[4] << 4, 1720 in[2] >> 29 | in[3] << 3, in[1] >> 30 | in[2] << 2, 1721 in[0] >> 31 | in[1] << 1, in[0]); 1722 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1723 _mm256_storeu_si256((__m256i*)(out), results); 1724 out += 8; 1725 1726 // shift the second 8 outs 1727 reg_shifts = _mm256_set_epi32(0, 0, 0, 0, 1728 0, 0, 0, 0); 1729 reg_inls = _mm256_set_epi32(in[14] >> 17 | in[15] << 15, in[13] >> 18 | in[14] << 14, 1730 in[12] >> 19 | in[13] << 13, in[11] >> 20 | in[12] << 12, 1731 in[10] >> 21 | in[11] << 11, in[9] >> 22 | in[10] << 10, 1732 in[8] >> 23 | in[9] << 9, in[7] >> 24 | in[8] << 8); 1733 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1734 _mm256_storeu_si256((__m256i*)(out), results); 1735 out += 8; 1736 1737 // shift the third 8 outs 1738 reg_shifts = _mm256_set_epi32(0, 0, 0, 0, 1739 0, 0, 0, 0); 1740 reg_inls = _mm256_set_epi32(in[22] >> 9 | in[23] << 23, in[21] >> 10 | in[22] << 22, 1741 in[20] >> 11 | in[21] << 21, in[19] >> 12 | in[20] << 20, 1742 in[18] >> 13 | in[19] << 19, in[17] >> 14 | in[18] << 18, 1743 in[16] >> 15 | in[17] << 17, in[15] >> 16 | in[16] << 16); 1744 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1745 _mm256_storeu_si256((__m256i*)(out), results); 1746 out += 8; 1747 1748 // shift the last 8 outs 1749 reg_shifts = _mm256_set_epi32(1, 0, 0, 0, 1750 0, 0, 0, 0); 1751 reg_inls = _mm256_set_epi32(in[30], in[29] >> 2 | in[30] << 30, 1752 in[28] >> 3 | in[29] << 29, in[27] >> 4 | in[28] << 28, 1753 in[26] >> 5 | in[27] << 27, in[25] >> 6 | in[26] << 26, 1754 in[24] >> 7 | in[25] << 25, in[23] >> 8 | in[24] << 24); 1755 results = _mm256_and_si256(_mm256_srlv_epi32(reg_inls, reg_shifts), reg_masks); 1756 _mm256_storeu_si256((__m256i*)(out), results); 1757 out += 8; 1758 1759 in += 31; 1760 1761 return in; 1762 } 1763 1764 inline const uint32_t* unpack32_32_avx2(const uint32_t* in, uint32_t* out) { 1765 memcpy(out, in, 32 * sizeof(*out)); 1766 in += 32; 1767 out += 32; 1768 1769 return in; 1770 } 1771 1772 int unpack32_avx2(const uint32_t* in, uint32_t* out, int batch_size, int num_bits) { 1773 batch_size = batch_size / 32 * 32; 1774 int num_loops = batch_size / 32; 1775 1776 switch (num_bits) { 1777 case 0: 1778 for (int i = 0; i < num_loops; ++i) in = unpack0_32_avx2(in, out + i * 32); 1779 break; 1780 case 1: 1781 for (int i = 0; i < num_loops; ++i) in = unpack1_32_avx2(in, out + i * 32); 1782 break; 1783 case 2: 1784 for (int i = 0; i < num_loops; ++i) in = unpack2_32_avx2(in, out + i * 32); 1785 break; 1786 case 3: 1787 for (int i = 0; i < num_loops; ++i) in = unpack3_32_avx2(in, out + i * 32); 1788 break; 1789 case 4: 1790 for (int i = 0; i < num_loops; ++i) in = unpack4_32_avx2(in, out + i * 32); 1791 break; 1792 case 5: 1793 for (int i = 0; i < num_loops; ++i) in = unpack5_32_avx2(in, out + i * 32); 1794 break; 1795 case 6: 1796 for (int i = 0; i < num_loops; ++i) in = unpack6_32_avx2(in, out + i * 32); 1797 break; 1798 case 7: 1799 for (int i = 0; i < num_loops; ++i) in = unpack7_32_avx2(in, out + i * 32); 1800 break; 1801 case 8: 1802 for (int i = 0; i < num_loops; ++i) in = unpack8_32_avx2(in, out + i * 32); 1803 break; 1804 case 9: 1805 for (int i = 0; i < num_loops; ++i) in = unpack9_32_avx2(in, out + i * 32); 1806 break; 1807 case 10: 1808 for (int i = 0; i < num_loops; ++i) in = unpack10_32_avx2(in, out + i * 32); 1809 break; 1810 case 11: 1811 for (int i = 0; i < num_loops; ++i) in = unpack11_32_avx2(in, out + i * 32); 1812 break; 1813 case 12: 1814 for (int i = 0; i < num_loops; ++i) in = unpack12_32_avx2(in, out + i * 32); 1815 break; 1816 case 13: 1817 for (int i = 0; i < num_loops; ++i) in = unpack13_32_avx2(in, out + i * 32); 1818 break; 1819 case 14: 1820 for (int i = 0; i < num_loops; ++i) in = unpack14_32_avx2(in, out + i * 32); 1821 break; 1822 case 15: 1823 for (int i = 0; i < num_loops; ++i) in = unpack15_32_avx2(in, out + i * 32); 1824 break; 1825 case 16: 1826 for (int i = 0; i < num_loops; ++i) in = unpack16_32_avx2(in, out + i * 32); 1827 break; 1828 case 17: 1829 for (int i = 0; i < num_loops; ++i) in = unpack17_32_avx2(in, out + i * 32); 1830 break; 1831 case 18: 1832 for (int i = 0; i < num_loops; ++i) in = unpack18_32_avx2(in, out + i * 32); 1833 break; 1834 case 19: 1835 for (int i = 0; i < num_loops; ++i) in = unpack19_32_avx2(in, out + i * 32); 1836 break; 1837 case 20: 1838 for (int i = 0; i < num_loops; ++i) in = unpack20_32_avx2(in, out + i * 32); 1839 break; 1840 case 21: 1841 for (int i = 0; i < num_loops; ++i) in = unpack21_32_avx2(in, out + i * 32); 1842 break; 1843 case 22: 1844 for (int i = 0; i < num_loops; ++i) in = unpack22_32_avx2(in, out + i * 32); 1845 break; 1846 case 23: 1847 for (int i = 0; i < num_loops; ++i) in = unpack23_32_avx2(in, out + i * 32); 1848 break; 1849 case 24: 1850 for (int i = 0; i < num_loops; ++i) in = unpack24_32_avx2(in, out + i * 32); 1851 break; 1852 case 25: 1853 for (int i = 0; i < num_loops; ++i) in = unpack25_32_avx2(in, out + i * 32); 1854 break; 1855 case 26: 1856 for (int i = 0; i < num_loops; ++i) in = unpack26_32_avx2(in, out + i * 32); 1857 break; 1858 case 27: 1859 for (int i = 0; i < num_loops; ++i) in = unpack27_32_avx2(in, out + i * 32); 1860 break; 1861 case 28: 1862 for (int i = 0; i < num_loops; ++i) in = unpack28_32_avx2(in, out + i * 32); 1863 break; 1864 case 29: 1865 for (int i = 0; i < num_loops; ++i) in = unpack29_32_avx2(in, out + i * 32); 1866 break; 1867 case 30: 1868 for (int i = 0; i < num_loops; ++i) in = unpack30_32_avx2(in, out + i * 32); 1869 break; 1870 case 31: 1871 for (int i = 0; i < num_loops; ++i) in = unpack31_32_avx2(in, out + i * 32); 1872 break; 1873 case 32: 1874 for (int i = 0; i < num_loops; ++i) in = unpack32_32_avx2(in, out + i * 32); 1875 break; 1876 } 1877 1878 return batch_size; 1879 }