diff options
Diffstat (limited to 'src/core/moves.h')
| -rw-r--r-- | src/core/moves.h | 68 |
1 files changed, 17 insertions, 51 deletions
diff --git a/src/core/moves.h b/src/core/moves.h index 820406b..e56d5c8 100644 --- a/src/core/moves.h +++ b/src/core/moves.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | STATIC_INLINE bool allowednextmove(size_t n, const uint8_t [n]); | 4 | STATIC_INLINE bool allowednextmove(size_t n, const uint8_t [n]); |
| 5 | STATIC_INLINE uint32_t allowednextmove_mask(size_t n, const uint8_t [n]); | 5 | STATIC_INLINE uint32_t allowednextmove_mask(size_t n, const uint8_t [n]); |
| 6 | STATIC bool allowedmoves(size_t n, const uint8_t [n]); | ||
| 6 | 7 | ||
| 7 | STATIC_INLINE uint8_t movebase(uint8_t); | 8 | STATIC_INLINE uint8_t movebase(uint8_t); |
| 8 | STATIC_INLINE uint8_t moveaxis(uint8_t); | 9 | STATIC_INLINE uint8_t moveaxis(uint8_t); |
| @@ -13,11 +14,9 @@ STATIC_INLINE uint32_t disable_moves(uint32_t, uint8_t); | |||
| 13 | STATIC cube_t move(cube_t, uint8_t); | 14 | STATIC cube_t move(cube_t, uint8_t); |
| 14 | STATIC cube_t premove(cube_t, uint8_t); | 15 | STATIC cube_t premove(cube_t, uint8_t); |
| 15 | STATIC uint8_t inverse_move(uint8_t); | 16 | STATIC uint8_t inverse_move(uint8_t); |
| 16 | STATIC void invertmoves(size_t n, const uint8_t [n], uint8_t [n]); | 17 | STATIC void sortparallel_moves(size_t n, uint8_t [n]); |
| 17 | STATIC void sortparallel(size_t n, uint8_t [n]); | ||
| 18 | STATIC bool are_lastmoves_singlecw(size_t n, uint8_t [n]); | 18 | STATIC bool are_lastmoves_singlecw(size_t n, uint8_t [n]); |
| 19 | 19 | ||
| 20 | STATIC int readmoves(const char *, int, uint8_t *); | ||
| 21 | STATIC cube_t applymoves(cube_t, const char *); | 20 | STATIC cube_t applymoves(cube_t, const char *); |
| 22 | 21 | ||
| 23 | #define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ | 22 | #define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ |
| @@ -75,6 +74,18 @@ allowednextmove_mask(size_t n, const uint8_t moves[n]) | |||
| 75 | return result; | 74 | return result; |
| 76 | } | 75 | } |
| 77 | 76 | ||
| 77 | STATIC bool | ||
| 78 | allowedmoves(size_t n, const uint8_t moves[n]) | ||
| 79 | { | ||
| 80 | uint8_t j; | ||
| 81 | |||
| 82 | for (j = 2; j < n; j++) | ||
| 83 | if (!allowednextmove(j, moves)) | ||
| 84 | return false; | ||
| 85 | |||
| 86 | return true; | ||
| 87 | } | ||
| 88 | |||
| 78 | STATIC_INLINE uint32_t | 89 | STATIC_INLINE uint32_t |
| 79 | disable_moves(uint32_t current_result, uint8_t base_index) | 90 | disable_moves(uint32_t current_result, uint8_t base_index) |
| 80 | { | 91 | { |
| @@ -210,44 +221,13 @@ inverse_move(uint8_t m) | |||
| 210 | return m - 2 * (m % 3) + 2; | 221 | return m - 2 * (m % 3) + 2; |
| 211 | } | 222 | } |
| 212 | 223 | ||
| 213 | /* | ||
| 214 | GCC has issues when -Wstringop-overflow is used together with O3. It produces | ||
| 215 | warnings like the following: | ||
| 216 | |||
| 217 | In function 'invertmoves', | ||
| 218 | inlined from 'solve_h48_appendsolution' at src/solvers/h48/solve.h:81:3, | ||
| 219 | inlined from 'solve_h48_dfs.isra' at src/solvers/h48/solve.h:139:3: | ||
| 220 | warning: writing 32 bytes into a region of size 0 [-Wstringop-overflow=] | ||
| 221 | 197 | ret[i] = inverse_move(moves[nmoves - i - 1]); | ||
| 222 | | ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 223 | In function 'solve_h48_dfs.isra': | ||
| 224 | note: at offset 192 into destination object 'invertedpremoves' of size 20 | ||
| 225 | 71 | uint8_t invertedpremoves[MAXLEN]; | ||
| 226 | |||
| 227 | Clang does not give any warning. | ||
| 228 | Someone else complained here: https://access.redhat.com/solutions/6755371 | ||
| 229 | |||
| 230 | To solve this issue temporarily, we use a lower optimization setting for | ||
| 231 | this function only. | ||
| 232 | |||
| 233 | TODO check if the issue is resolved | ||
| 234 | */ | ||
| 235 | #pragma GCC push_options | ||
| 236 | #pragma GCC optimize ("O2") | ||
| 237 | STATIC void | 224 | STATIC void |
| 238 | invertmoves(size_t n, const uint8_t moves[n], uint8_t ret[n]) | 225 | sortparallel_moves(size_t n, uint8_t moves[n]) |
| 239 | { | 226 | { |
| 240 | uint8_t i; | 227 | uint8_t i; |
| 241 | 228 | ||
| 242 | for (i = 0; i < n; i++) | 229 | if (n < 2) |
| 243 | ret[i] = inverse_move(moves[n - i - 1]); | 230 | return; |
| 244 | } | ||
| 245 | #pragma GCC pop_options | ||
| 246 | |||
| 247 | STATIC void | ||
| 248 | sortparallel(size_t n, uint8_t moves[n]) | ||
| 249 | { | ||
| 250 | uint8_t i; | ||
| 251 | 231 | ||
| 252 | for (i = 0; i < n-1; i++) | 232 | for (i = 0; i < n-1; i++) |
| 253 | if (moveaxis(moves[i]) == moveaxis(moves[i+1]) && | 233 | if (moveaxis(moves[i]) == moveaxis(moves[i+1]) && |
| @@ -268,20 +248,6 @@ are_lastmoves_singlecw(size_t n, uint8_t moves[n]) | |||
| 268 | return isbase(moves[n-1]) && (!two || isbase(moves[n-2])); | 248 | return isbase(moves[n-1]) && (!two || isbase(moves[n-2])); |
| 269 | } | 249 | } |
| 270 | 250 | ||
| 271 | STATIC int | ||
| 272 | readmoves(const char *buf, int max, uint8_t *ret) | ||
| 273 | { | ||
| 274 | uint8_t m; | ||
| 275 | int c; | ||
| 276 | |||
| 277 | FOREACH_READMOVE(buf, m, c, max, NISSY_ERROR_INVALID_MOVES, | ||
| 278 | if (ret != NULL) | ||
| 279 | ret[c] = m; | ||
| 280 | ) | ||
| 281 | |||
| 282 | return c; | ||
| 283 | } | ||
| 284 | |||
| 285 | STATIC cube_t | 251 | STATIC cube_t |
| 286 | applymoves(cube_t cube, const char *buf) | 252 | applymoves(cube_t cube, const char *buf) |
| 287 | { | 253 | { |
