diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2023-10-28 20:42:24 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2023-10-28 20:42:24 +0200 |
| commit | b05fa355c49c619cce1226716a395381a944f578 (patch) | |
| tree | b46416e2fbbc70f3d780f4e0ea3de7763115efe0 /src/cube.c | |
| parent | fabb1ae495c4404af0f26380c97d0bca7e881a27 (diff) | |
| download | nissy-core-b05fa355c49c619cce1226716a395381a944f578.tar.gz nissy-core-b05fa355c49c619cce1226716a395381a944f578.zip | |
Started working on AVX2 (not working yet)
Diffstat (limited to 'src/cube.c')
| -rw-r--r-- | src/cube.c | 296 |
1 files changed, 100 insertions, 196 deletions
| @@ -2,6 +2,10 @@ | |||
| 2 | #include <stdbool.h> | 2 | #include <stdbool.h> |
| 3 | #include <string.h> | 3 | #include <string.h> |
| 4 | 4 | ||
| 5 | #ifdef CUBE_AVX2 | ||
| 6 | #include <immintrin.h> | ||
| 7 | #endif | ||
| 8 | |||
| 5 | #ifdef DEBUG | 9 | #ifdef DEBUG |
| 6 | #include <stdio.h> | 10 | #include <stdio.h> |
| 7 | #endif | 11 | #endif |
| @@ -10,6 +14,12 @@ | |||
| 10 | 14 | ||
| 11 | #include "_constants.c" | 15 | #include "_constants.c" |
| 12 | 16 | ||
| 17 | #ifdef CUBE_AVX2 | ||
| 18 | #include "_base_avx2.c" | ||
| 19 | #else | ||
| 20 | #include "_base_arr.c" | ||
| 21 | #endif | ||
| 22 | |||
| 13 | static bool isconsistent(cube_t); | 23 | static bool isconsistent(cube_t); |
| 14 | static cube_t flipallcorners(cube_t); | 24 | static cube_t flipallcorners(cube_t); |
| 15 | static uint8_t readco(char *); | 25 | static uint8_t readco(char *); |
| @@ -90,7 +100,7 @@ readcube_H48(char *buf) | |||
| 90 | { | 100 | { |
| 91 | int i; | 101 | int i; |
| 92 | uint8_t piece, orient; | 102 | uint8_t piece, orient; |
| 93 | cube_t ret = {0}; | 103 | cube_t ret = zerocube; |
| 94 | char *b = buf; | 104 | char *b = buf; |
| 95 | 105 | ||
| 96 | for (i = 0; i < 12; i++) { | 106 | for (i = 0; i < 12; i++) { |
| @@ -102,7 +112,7 @@ readcube_H48(char *buf) | |||
| 102 | if ((orient = readeo(b)) == _error) | 112 | if ((orient = readeo(b)) == _error) |
| 103 | return errorcube; | 113 | return errorcube; |
| 104 | b++; | 114 | b++; |
| 105 | ret.e[i] = piece | orient; | 115 | set_edge(&ret, i, piece | orient); |
| 106 | } | 116 | } |
| 107 | for (i = 0; i < 8; i++) { | 117 | for (i = 0; i < 8; i++) { |
| 108 | while (*b == ' ' || *b == '\t' || *b == '\n') | 118 | while (*b == ' ' || *b == '\t' || *b == '\n') |
| @@ -113,7 +123,7 @@ readcube_H48(char *buf) | |||
| 113 | if ((orient = readco(b)) == _error) | 123 | if ((orient = readco(b)) == _error) |
| 114 | return errorcube; | 124 | return errorcube; |
| 115 | b++; | 125 | b++; |
| 116 | ret.c[i] = piece | orient; | 126 | set_corner(&ret, i, piece | orient); |
| 117 | } | 127 | } |
| 118 | 128 | ||
| 119 | return ret; | 129 | return ret; |
| @@ -145,23 +155,25 @@ readcube(format_t format, char *buf) | |||
| 145 | static void | 155 | static void |
| 146 | writecube_H48(cube_t cube, char *buf) | 156 | writecube_H48(cube_t cube, char *buf) |
| 147 | { | 157 | { |
| 148 | uint8_t piece, orient; | 158 | uint8_t piece, perm, orient; |
| 149 | int i; | 159 | int i; |
| 150 | 160 | ||
| 151 | for (i = 0; i < 12; i++) { | 161 | for (i = 0; i < 12; i++) { |
| 152 | piece = cube.e[i] & _pbits; | 162 | piece = get_edge(cube, i); |
| 153 | orient = (cube.e[i] & _eobit) >> _eoshift; | 163 | perm = piece & _pbits; |
| 154 | buf[4*i ] = edgestr[piece][0]; | 164 | orient = (piece & _eobit) >> _eoshift; |
| 155 | buf[4*i + 1] = edgestr[piece][1]; | 165 | buf[4*i ] = edgestr[perm][0]; |
| 166 | buf[4*i + 1] = edgestr[perm][1]; | ||
| 156 | buf[4*i + 2] = orient + '0'; | 167 | buf[4*i + 2] = orient + '0'; |
| 157 | buf[4*i + 3] = ' '; | 168 | buf[4*i + 3] = ' '; |
| 158 | } | 169 | } |
| 159 | for (i = 0; i < 8; i++) { | 170 | for (i = 0; i < 8; i++) { |
| 160 | piece = cube.c[i] & _pbits; | 171 | piece = get_corner(cube, i); |
| 161 | orient = (cube.c[i] & _cobits) >> _coshift; | 172 | perm = piece & _pbits; |
| 162 | buf[48 + 5*i ] = cornerstr[piece][0]; | 173 | orient = (piece & _cobits) >> _coshift; |
| 163 | buf[48 + 5*i + 1] = cornerstr[piece][1]; | 174 | buf[48 + 5*i ] = cornerstr[perm][0]; |
| 164 | buf[48 + 5*i + 2] = cornerstr[piece][2]; | 175 | buf[48 + 5*i + 1] = cornerstr[perm][1]; |
| 176 | buf[48 + 5*i + 2] = cornerstr[perm][2]; | ||
| 165 | buf[48 + 5*i + 3] = orient + '0'; | 177 | buf[48 + 5*i + 3] = orient + '0'; |
| 166 | buf[48 + 5*i + 4] = ' '; | 178 | buf[48 + 5*i + 4] = ' '; |
| 167 | } | 179 | } |
| @@ -196,18 +208,23 @@ static void | |||
| 196 | writecube_SRC(cube_t cube, char *buf) | 208 | writecube_SRC(cube_t cube, char *buf) |
| 197 | { | 209 | { |
| 198 | int i, ptr; | 210 | int i, ptr; |
| 211 | uint8_t piece; | ||
| 199 | 212 | ||
| 200 | memcpy(buf, "{\n\t.c = {", 9); | 213 | memcpy(buf, "{\n\t.c = {", 9); |
| 201 | ptr = 9; | 214 | ptr = 9; |
| 202 | 215 | ||
| 203 | for (i = 0; i < 8; i++) | 216 | for (i = 0; i < 8; i++) { |
| 204 | ptr += writepiece_SRC(cube.c[i], buf + ptr); | 217 | piece = get_corner(cube, i); |
| 218 | ptr += writepiece_SRC(piece, buf + ptr); | ||
| 219 | } | ||
| 205 | 220 | ||
| 206 | memcpy(buf+ptr-2, "},\n\t.e = {", 10); | 221 | memcpy(buf+ptr-2, "},\n\t.e = {", 10); |
| 207 | ptr += 8; | 222 | ptr += 8; |
| 208 | 223 | ||
| 209 | for (i = 0; i < 12; i++) | 224 | for (i = 0; i < 12; i++) { |
| 210 | ptr += writepiece_SRC(cube.e[i], buf + ptr); | 225 | piece = get_edge(cube, i); |
| 226 | ptr += writepiece_SRC(piece, buf + ptr); | ||
| 227 | } | ||
| 211 | 228 | ||
| 212 | memcpy(buf+ptr-2, "}\n}\0", 4); | 229 | memcpy(buf+ptr-2, "}\n}\0", 4); |
| 213 | } | 230 | } |
| @@ -364,7 +381,7 @@ permsign(uint8_t *a, int n) | |||
| 364 | 381 | ||
| 365 | for (i = 0; i < n; i++) | 382 | for (i = 0; i < n; i++) |
| 366 | for (j = i+1; j < n; j++) | 383 | for (j = i+1; j < n; j++) |
| 367 | ret += (a[i] & _pbits) > (a[j] & _pbits) ? 1 : 0; | 384 | ret += a[i] > a[j] ? 1 : 0; |
| 368 | 385 | ||
| 369 | return ret % 2; | 386 | return ret % 2; |
| 370 | } | 387 | } |
| @@ -372,14 +389,15 @@ permsign(uint8_t *a, int n) | |||
| 372 | static bool | 389 | static bool |
| 373 | isconsistent(cube_t c) | 390 | isconsistent(cube_t c) |
| 374 | { | 391 | { |
| 375 | uint8_t i, p, e; | 392 | uint8_t i, p, e, piece; |
| 376 | bool found[12]; | 393 | bool found[12]; |
| 377 | 394 | ||
| 378 | for (i = 0; i < 12; i++) | 395 | for (i = 0; i < 12; i++) |
| 379 | found[i] = false; | 396 | found[i] = false; |
| 380 | for (i = 0; i < 12; i++) { | 397 | for (i = 0; i < 12; i++) { |
| 381 | p = c.e[i] & _pbits; | 398 | piece = get_edge(c, i); |
| 382 | e = c.e[i] & ~_pbits; | 399 | p = piece & _pbits; |
| 400 | e = piece & _eobit; | ||
| 383 | if (p >= 12) | 401 | if (p >= 12) |
| 384 | goto inconsistent_ep; | 402 | goto inconsistent_ep; |
| 385 | if (e != 0 && e != _eobit) | 403 | if (e != 0 && e != _eobit) |
| @@ -393,8 +411,9 @@ isconsistent(cube_t c) | |||
| 393 | for (i = 0; i < 8; i++) | 411 | for (i = 0; i < 8; i++) |
| 394 | found[i] = false; | 412 | found[i] = false; |
| 395 | for (i = 0; i < 8; i++) { | 413 | for (i = 0; i < 8; i++) { |
| 396 | p = c.c[i] & _pbits; | 414 | piece = get_corner(c, i); |
| 397 | e = c.c[i] & ~_pbits; | 415 | p = piece & _pbits; |
| 416 | e = piece & _cobits; | ||
| 398 | if (p >= 8) | 417 | if (p >= 8) |
| 399 | goto inconsistent_cp; | 418 | goto inconsistent_cp; |
| 400 | if (e != 0 && e != _ctwist_cw && e != _ctwist_ccw) | 419 | if (e != 0 && e != _ctwist_cw && e != _ctwist_ccw) |
| @@ -432,7 +451,7 @@ inconsistent_co: | |||
| 432 | bool | 451 | bool |
| 433 | issolvable(cube_t cube) | 452 | issolvable(cube_t cube) |
| 434 | { | 453 | { |
| 435 | int8_t i, eo, co; | 454 | uint8_t i, eo, co, piece, e[12], c[8]; |
| 436 | 455 | ||
| 437 | #ifdef DEBUG | 456 | #ifdef DEBUG |
| 438 | if (!isconsistent(cube)) { | 457 | if (!isconsistent(cube)) { |
| @@ -441,18 +460,27 @@ issolvable(cube_t cube) | |||
| 441 | } | 460 | } |
| 442 | #endif | 461 | #endif |
| 443 | 462 | ||
| 444 | if (permsign(cube.e, 12) != permsign(cube.c, 8)) | 463 | for (i = 0; i < 12; i++) |
| 464 | e[i] = get_edge(cube, i) & _pbits; | ||
| 465 | for (i = 0; i < 8; i++) | ||
| 466 | c[i] = get_corner(cube, i) & _pbits; | ||
| 467 | |||
| 468 | if (permsign(e, 12) != permsign(c, 8)) | ||
| 445 | goto issolvable_parity; | 469 | goto issolvable_parity; |
| 446 | 470 | ||
| 447 | eo = 0; | 471 | eo = 0; |
| 448 | for (i = 0; i < 12; i++) | 472 | for (i = 0; i < 12; i++) { |
| 449 | eo += (cube.e[i] & _eobit) >> _eoshift; | 473 | piece = get_edge(cube, i); |
| 474 | eo += (piece & _eobit) >> _eoshift; | ||
| 475 | } | ||
| 450 | if (eo % 2 != 0) | 476 | if (eo % 2 != 0) |
| 451 | goto issolvable_eo; | 477 | goto issolvable_eo; |
| 452 | 478 | ||
| 453 | co = 0; | 479 | co = 0; |
| 454 | for (i = 0; i < 8; i++) | 480 | for (i = 0; i < 8; i++) { |
| 455 | co += (cube.c[i] & _cobits) >> _coshift; | 481 | piece = get_corner(cube, i); |
| 482 | co += (piece & _cobits) >> _coshift; | ||
| 483 | } | ||
| 456 | if (co % 3 != 0) | 484 | if (co % 3 != 0) |
| 457 | goto issolvable_co; | 485 | goto issolvable_co; |
| 458 | 486 | ||
| @@ -478,6 +506,15 @@ issolvable_co: | |||
| 478 | bool | 506 | bool |
| 479 | equal(cube_t cube1, cube_t cube2) | 507 | equal(cube_t cube1, cube_t cube2) |
| 480 | { | 508 | { |
| 509 | #ifdef CUBE_AVX2 | ||
| 510 | uint32_t mask; | ||
| 511 | __m256i cmp; | ||
| 512 | |||
| 513 | cmp = _mm256_cmpeq_epi8(cube1, cube2); | ||
| 514 | mask = _mm256_movemask_epi8(cmp); | ||
| 515 | |||
| 516 | return mask == 0xffffffffU; | ||
| 517 | #else | ||
| 481 | uint8_t i; | 518 | uint8_t i; |
| 482 | 519 | ||
| 483 | for (i = 0; i < 12; i++) | 520 | for (i = 0; i < 12; i++) |
| @@ -489,6 +526,7 @@ equal(cube_t cube1, cube_t cube2) | |||
| 489 | return false; | 526 | return false; |
| 490 | 527 | ||
| 491 | return true; | 528 | return true; |
| 529 | #endif | ||
| 492 | } | 530 | } |
| 493 | 531 | ||
| 494 | bool | 532 | bool |
| @@ -506,9 +544,6 @@ iserror(cube_t cube) | |||
| 506 | cube_t | 544 | cube_t |
| 507 | move(cube_t c, move_t m) | 545 | move(cube_t c, move_t m) |
| 508 | { | 546 | { |
| 509 | cube_t ret; | ||
| 510 | uint8_t aux, auy, auz; | ||
| 511 | |||
| 512 | #ifdef DEBUG | 547 | #ifdef DEBUG |
| 513 | if (!isconsistent(c)) { | 548 | if (!isconsistent(c)) { |
| 514 | fprintf(stderr, "move error, inconsistent cube\n"); | 549 | fprintf(stderr, "move error, inconsistent cube\n"); |
| @@ -516,154 +551,11 @@ move(cube_t c, move_t m) | |||
| 516 | } | 551 | } |
| 517 | #endif | 552 | #endif |
| 518 | 553 | ||
| 519 | #define PERM4(r, i, j, k, l) \ | 554 | #ifdef CUBE_AVX2 |
| 520 | aux = r[i]; \ | 555 | #include "_move_logic_avx2.c" |
| 521 | r[i] = r[l]; \ | 556 | #else |
| 522 | r[l] = r[k]; \ | 557 | #include "_move_logic_arr.c" |
| 523 | r[k] = r[j]; \ | ||
| 524 | r[j] = aux; | ||
| 525 | #define PERM22(r, i, j, k, l) \ | ||
| 526 | aux = r[i]; \ | ||
| 527 | r[i] = r[j]; \ | ||
| 528 | r[j] = aux; \ | ||
| 529 | aux = r[k]; \ | ||
| 530 | r[k] = r[l]; \ | ||
| 531 | r[l] = aux; | ||
| 532 | #define CO(a, b) \ | ||
| 533 | aux = (a & _cobits) + (b & _cobits); \ | ||
| 534 | auy = (aux + _ctwist_cw) >> 2U; \ | ||
| 535 | auz = (aux + auy) & _cobits2; \ | ||
| 536 | a = (a & _pbits) | auz; | ||
| 537 | #define CO4(r, i, j, k, l) \ | ||
| 538 | CO(r[i], _ctwist_cw) \ | ||
| 539 | CO(r[j], _ctwist_cw) \ | ||
| 540 | CO(r[k], _ctwist_ccw) \ | ||
| 541 | CO(r[l], _ctwist_ccw) | ||
| 542 | #define EO4(r, i, j, k, l) \ | ||
| 543 | r[i] ^= _eobit; \ | ||
| 544 | r[j] ^= _eobit; \ | ||
| 545 | r[k] ^= _eobit; \ | ||
| 546 | r[l] ^= _eobit; | ||
| 547 | |||
| 548 | ret = c; | ||
| 549 | |||
| 550 | switch (m) { | ||
| 551 | case U: | ||
| 552 | PERM4(ret.e, _e_uf, _e_ul, _e_ub, _e_ur) | ||
| 553 | PERM4(ret.c, _c_ufr, _c_ufl, _c_ubl, _c_ubr) | ||
| 554 | |||
| 555 | return ret; | ||
| 556 | case U2: | ||
| 557 | PERM22(ret.e, _e_uf, _e_ub, _e_ul, _e_ur) | ||
| 558 | PERM22(ret.c, _c_ufr, _c_ubl, _c_ufl, _c_ubr) | ||
| 559 | |||
| 560 | return ret; | ||
| 561 | case U3: | ||
| 562 | PERM4(ret.e, _e_uf, _e_ur, _e_ub, _e_ul) | ||
| 563 | PERM4(ret.c, _c_ufr, _c_ubr, _c_ubl, _c_ufl) | ||
| 564 | |||
| 565 | return ret; | ||
| 566 | case D: | ||
| 567 | PERM4(ret.e, _e_df, _e_dr, _e_db, _e_dl) | ||
| 568 | PERM4(ret.c, _c_dfr, _c_dbr, _c_dbl, _c_dfl) | ||
| 569 | |||
| 570 | return ret; | ||
| 571 | case D2: | ||
| 572 | PERM22(ret.e, _e_df, _e_db, _e_dr, _e_dl) | ||
| 573 | PERM22(ret.c, _c_dfr, _c_dbl, _c_dbr, _c_dfl) | ||
| 574 | |||
| 575 | return ret; | ||
| 576 | case D3: | ||
| 577 | PERM4(ret.e, _e_df, _e_dl, _e_db, _e_dr) | ||
| 578 | PERM4(ret.c, _c_dfr, _c_dfl, _c_dbl, _c_dbr) | ||
| 579 | |||
| 580 | return ret; | ||
| 581 | case R: | ||
| 582 | PERM4(ret.e, _e_ur, _e_br, _e_dr, _e_fr) | ||
| 583 | PERM4(ret.c, _c_ufr, _c_ubr, _c_dbr, _c_dfr) | ||
| 584 | |||
| 585 | CO4(ret.c, _c_ubr, _c_dfr, _c_ufr, _c_dbr) | ||
| 586 | |||
| 587 | return ret; | ||
| 588 | case R2: | ||
| 589 | PERM22(ret.e, _e_ur, _e_dr, _e_fr, _e_br) | ||
| 590 | PERM22(ret.c, _c_ufr, _c_dbr, _c_ubr, _c_dfr) | ||
| 591 | |||
| 592 | return ret; | ||
| 593 | case R3: | ||
| 594 | PERM4(ret.e, _e_ur, _e_fr, _e_dr, _e_br) | ||
| 595 | PERM4(ret.c, _c_ufr, _c_dfr, _c_dbr, _c_ubr) | ||
| 596 | |||
| 597 | CO4(ret.c, _c_ubr, _c_dfr, _c_ufr, _c_dbr) | ||
| 598 | |||
| 599 | return ret; | ||
| 600 | case L: | ||
| 601 | PERM4(ret.e, _e_ul, _e_fl, _e_dl, _e_bl) | ||
| 602 | PERM4(ret.c, _c_ufl, _c_dfl, _c_dbl, _c_ubl) | ||
| 603 | |||
| 604 | CO4(ret.c, _c_ufl, _c_dbl, _c_dfl, _c_ubl) | ||
| 605 | |||
| 606 | return ret; | ||
| 607 | case L2: | ||
| 608 | PERM22(ret.e, _e_ul, _e_dl, _e_fl, _e_bl) | ||
| 609 | PERM22(ret.c, _c_ufl, _c_dbl, _c_ubl, _c_dfl) | ||
| 610 | |||
| 611 | return ret; | ||
| 612 | case L3: | ||
| 613 | PERM4(ret.e, _e_ul, _e_bl, _e_dl, _e_fl) | ||
| 614 | PERM4(ret.c, _c_ufl, _c_ubl, _c_dbl, _c_dfl) | ||
| 615 | |||
| 616 | CO4(ret.c, _c_ufl, _c_dbl, _c_dfl, _c_ubl) | ||
| 617 | |||
| 618 | return ret; | ||
| 619 | case F: | ||
| 620 | PERM4(ret.e, _e_uf, _e_fr, _e_df, _e_fl) | ||
| 621 | PERM4(ret.c, _c_ufr, _c_dfr, _c_dfl, _c_ufl) | ||
| 622 | |||
| 623 | EO4(ret.e, _e_uf, _e_fr, _e_df, _e_fl) | ||
| 624 | CO4(ret.c, _c_ufr, _c_dfl, _c_dfr, _c_ufl) | ||
| 625 | |||
| 626 | return ret; | ||
| 627 | case F2: | ||
| 628 | PERM22(ret.e, _e_uf, _e_df, _e_fr, _e_fl) | ||
| 629 | PERM22(ret.c, _c_ufr, _c_dfl, _c_ufl, _c_dfr) | ||
| 630 | |||
| 631 | return ret; | ||
| 632 | case F3: | ||
| 633 | PERM4(ret.e, _e_uf, _e_fl, _e_df, _e_fr) | ||
| 634 | PERM4(ret.c, _c_ufr, _c_ufl, _c_dfl, _c_dfr) | ||
| 635 | |||
| 636 | EO4(ret.e, _e_uf, _e_fr, _e_df, _e_fl) | ||
| 637 | CO4(ret.c, _c_ufr, _c_dfl, _c_dfr, _c_ufl) | ||
| 638 | |||
| 639 | return ret; | ||
| 640 | case B: | ||
| 641 | PERM4(ret.e, _e_ub, _e_bl, _e_db, _e_br) | ||
| 642 | PERM4(ret.c, _c_ubr, _c_ubl, _c_dbl, _c_dbr) | ||
| 643 | |||
| 644 | EO4(ret.e, _e_ub, _e_br, _e_db, _e_bl) | ||
| 645 | CO4(ret.c, _c_ubl, _c_dbr, _c_dbl, _c_ubr) | ||
| 646 | |||
| 647 | return ret; | ||
| 648 | case B2: | ||
| 649 | PERM22(ret.e, _e_ub, _e_db, _e_br, _e_bl) | ||
| 650 | PERM22(ret.c, _c_ubr, _c_dbl, _c_ubl, _c_dbr) | ||
| 651 | |||
| 652 | return ret; | ||
| 653 | case B3: | ||
| 654 | PERM4(ret.e, _e_ub, _e_br, _e_db, _e_bl) | ||
| 655 | PERM4(ret.c, _c_ubr, _c_dbr, _c_dbl, _c_ubl) | ||
| 656 | |||
| 657 | EO4(ret.e, _e_ub, _e_br, _e_db, _e_bl) | ||
| 658 | CO4(ret.c, _c_ubl, _c_dbr, _c_dbl, _c_ubr) | ||
| 659 | |||
| 660 | return ret; | ||
| 661 | default: | ||
| 662 | #ifdef DEBUG | ||
| 663 | fprintf(stderr, "mover error, unknown move\n"); | ||
| 664 | #endif | 558 | #endif |
| 665 | goto move_error; | ||
| 666 | } | ||
| 667 | 559 | ||
| 668 | move_error: | 560 | move_error: |
| 669 | return errorcube; | 561 | return errorcube; |
| @@ -672,8 +564,9 @@ move_error: | |||
| 672 | cube_t | 564 | cube_t |
| 673 | inverse(cube_t c) | 565 | inverse(cube_t c) |
| 674 | { | 566 | { |
| 567 | /* TODO: optimize for avx2 */ | ||
| 675 | uint8_t i, piece, orien; | 568 | uint8_t i, piece, orien; |
| 676 | cube_t ret = {0}; | 569 | cube_t ret = zerocube; |
| 677 | 570 | ||
| 678 | #ifdef DEBUG | 571 | #ifdef DEBUG |
| 679 | if (!isconsistent(c)) { | 572 | if (!isconsistent(c)) { |
| @@ -683,15 +576,15 @@ inverse(cube_t c) | |||
| 683 | #endif | 576 | #endif |
| 684 | 577 | ||
| 685 | for (i = 0; i < 12; i++) { | 578 | for (i = 0; i < 12; i++) { |
| 686 | piece = c.e[i & _pbits]; | 579 | piece = get_edge(c, i); |
| 687 | orien = piece & _eobit; | 580 | orien = piece & _eobit; |
| 688 | ret.e[piece & _pbits] = i | orien; | 581 | set_edge(&ret, piece & _pbits, i | orien); |
| 689 | } | 582 | } |
| 690 | 583 | ||
| 691 | for (i = 0; i < 8; i++) { | 584 | for (i = 0; i < 8; i++) { |
| 692 | piece = c.c[i & _pbits]; | 585 | piece = get_corner(c, i); |
| 693 | orien = ((piece << 1) | (piece >> 1)) & _cobits2; | 586 | orien = ((piece << 1) | (piece >> 1)) & _cobits2; |
| 694 | ret.c[piece & _pbits] = i | orien; | 587 | set_corner(&ret, piece & _pbits, i | orien); |
| 695 | } | 588 | } |
| 696 | 589 | ||
| 697 | return ret; | 590 | return ret; |
| @@ -700,8 +593,9 @@ inverse(cube_t c) | |||
| 700 | cube_t | 593 | cube_t |
| 701 | compose(cube_t c1, cube_t c2) | 594 | compose(cube_t c1, cube_t c2) |
| 702 | { | 595 | { |
| 703 | uint8_t i, piece, orien, aux, auy; | 596 | /* TODO: optimize for avx2 */ |
| 704 | cube_t ret = {0}; | 597 | uint8_t i, piece1, piece2, p, orien, aux, auy; |
| 598 | cube_t ret = zerocube; | ||
| 705 | 599 | ||
| 706 | #ifdef DEBUG | 600 | #ifdef DEBUG |
| 707 | if (!isconsistent(c1) || !isconsistent(c2)) { | 601 | if (!isconsistent(c1) || !isconsistent(c2)) { |
| @@ -711,17 +605,21 @@ compose(cube_t c1, cube_t c2) | |||
| 711 | #endif | 605 | #endif |
| 712 | 606 | ||
| 713 | for (i = 0; i < 12; i++) { | 607 | for (i = 0; i < 12; i++) { |
| 714 | piece = c2.e[i] & _pbits; | 608 | piece2 = get_edge(c2, i); |
| 715 | orien = (c2.e[i] ^ c1.e[piece]) & _eobit; | 609 | p = piece2 & _pbits; |
| 716 | ret.e[i] = (c1.e[piece] & _pbits) | orien; | 610 | piece1 = get_edge(c1, p); |
| 611 | orien = (piece2 ^ piece1) & _eobit; | ||
| 612 | set_edge(&ret, i, (piece1 & _pbits) | orien); | ||
| 717 | } | 613 | } |
| 718 | 614 | ||
| 719 | for (i = 0; i < 8; i++) { | 615 | for (i = 0; i < 8; i++) { |
| 720 | piece = c2.c[i] & _pbits; | 616 | piece2 = get_corner(c2, i); |
| 721 | aux = (c2.c[i] & _cobits) + (c1.c[piece] & _cobits); | 617 | p = piece2 & _pbits; |
| 618 | piece1 = get_corner(c1, p); | ||
| 619 | aux = (piece2 & _cobits) + (piece1 & _cobits); | ||
| 722 | auy = (aux + _ctwist_cw) >> 2U; | 620 | auy = (aux + _ctwist_cw) >> 2U; |
| 723 | orien = (aux + auy) & _cobits2; | 621 | orien = (aux + auy) & _cobits2; |
| 724 | ret.c[i] = (c1.c[piece] & _pbits) | orien; | 622 | set_corner(&ret, i, (piece1 & _pbits) | orien); |
| 725 | } | 623 | } |
| 726 | 624 | ||
| 727 | return ret; | 625 | return ret; |
| @@ -730,14 +628,16 @@ compose(cube_t c1, cube_t c2) | |||
| 730 | static cube_t | 628 | static cube_t |
| 731 | flipallcorners(cube_t c) | 629 | flipallcorners(cube_t c) |
| 732 | { | 630 | { |
| 631 | /* TODO: optimize for avx2, can be a couple of instructions */ | ||
| 632 | |||
| 733 | uint8_t i, piece, orien; | 633 | uint8_t i, piece, orien; |
| 734 | cube_t ret; | 634 | cube_t ret; |
| 735 | 635 | ||
| 736 | ret = c; | 636 | ret = c; |
| 737 | for (i = 0; i < 8; i++) { | 637 | for (i = 0; i < 8; i++) { |
| 738 | piece = ret.c[i]; | 638 | piece = get_corner(c, i); |
| 739 | orien = ((piece << 1) | (piece >> 1)) & _cobits2; | 639 | orien = ((piece << 1) | (piece >> 1)) & _cobits2; |
| 740 | ret.c[i] = (piece & _pbits) | orien; | 640 | set_corner(&ret, i, (piece & _pbits) | orien); |
| 741 | } | 641 | } |
| 742 | 642 | ||
| 743 | return ret; | 643 | return ret; |
| @@ -746,8 +646,6 @@ flipallcorners(cube_t c) | |||
| 746 | cube_t | 646 | cube_t |
| 747 | transform(cube_t c, trans_t t) | 647 | transform(cube_t c, trans_t t) |
| 748 | { | 648 | { |
| 749 | #include "_trans_move_arr.c" | ||
| 750 | |||
| 751 | cube_t ret; | 649 | cube_t ret; |
| 752 | 650 | ||
| 753 | #ifdef DEBUG | 651 | #ifdef DEBUG |
| @@ -761,6 +659,12 @@ transform(cube_t c, trans_t t) | |||
| 761 | } | 659 | } |
| 762 | #endif | 660 | #endif |
| 763 | 661 | ||
| 662 | #ifdef CUBE_AVX2 | ||
| 663 | #include "_trans_move_avx2.c" | ||
| 664 | #else | ||
| 665 | #include "_trans_move_arr.c" | ||
| 666 | #endif | ||
| 667 | |||
| 764 | ret = compose(solvedcube, trans_move_cube[t]); | 668 | ret = compose(solvedcube, trans_move_cube[t]); |
| 765 | ret = compose(ret, c); | 669 | ret = compose(ret, c); |
| 766 | ret = compose(ret, trans_move_cube_inverse[t]); | 670 | ret = compose(ret, trans_move_cube_inverse[t]); |
