diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/io_moves.h | 41 | ||||
| -rw-r--r-- | src/core/moves.h | 68 |
2 files changed, 55 insertions, 54 deletions
diff --git a/src/core/io_moves.h b/src/core/io_moves.h index fa91e8b..8c56a9f 100644 --- a/src/core/io_moves.h +++ b/src/core/io_moves.h | |||
| @@ -1,6 +1,26 @@ | |||
| 1 | STATIC uint8_t readmove(char); | 1 | STATIC uint8_t readmove(char); |
| 2 | STATIC int64_t readmoves(const char *, size_t n, uint8_t [n]); | ||
| 2 | STATIC uint8_t readmodifier(char); | 3 | STATIC uint8_t readmodifier(char); |
| 3 | STATIC int64_t writemoves(size_t n, uint8_t [n], size_t m, char [m]); | 4 | STATIC int64_t writemoves(size_t n, const uint8_t [n], size_t m, char [m]); |
| 5 | |||
| 6 | #define FOREACH_READMOVE(ARG_BUF, ARG_MOVE, ARG_C, ARG_MAX, \ | ||
| 7 | RET_ERROR, ARG_ACTION) \ | ||
| 8 | const char *VAR_B; \ | ||
| 9 | uint8_t VAR_MOVE_NOMOD, VAR_MOD; \ | ||
| 10 | for (VAR_B = ARG_BUF, ARG_C = 0; *VAR_B != '\0'; VAR_B++, ARG_C++) { \ | ||
| 11 | while (*VAR_B == ' ' || *VAR_B == '\t' || *VAR_B == '\n') \ | ||
| 12 | VAR_B++; \ | ||
| 13 | if (*VAR_B == '\0' || ARG_C == ARG_MAX) \ | ||
| 14 | break; \ | ||
| 15 | if ((VAR_MOVE_NOMOD = readmove(*VAR_B)) == UINT8_ERROR) { \ | ||
| 16 | LOG("Error: unknown move '%c'\n", *VAR_B); \ | ||
| 17 | return RET_ERROR; \ | ||
| 18 | } \ | ||
| 19 | if ((VAR_MOD = readmodifier(*(VAR_B+1))) != 0) \ | ||
| 20 | VAR_B++; \ | ||
| 21 | ARG_MOVE = VAR_MOVE_NOMOD + VAR_MOD; \ | ||
| 22 | ARG_ACTION \ | ||
| 23 | } | ||
| 4 | 24 | ||
| 5 | STATIC uint8_t | 25 | STATIC uint8_t |
| 6 | readmove(char c) | 26 | readmove(char c) |
| @@ -39,9 +59,22 @@ readmodifier(char c) | |||
| 39 | } | 59 | } |
| 40 | 60 | ||
| 41 | STATIC int64_t | 61 | STATIC int64_t |
| 62 | readmoves(const char *buf, size_t n, uint8_t ret[n]) | ||
| 63 | { | ||
| 64 | uint8_t m; | ||
| 65 | uint64_t c; | ||
| 66 | |||
| 67 | FOREACH_READMOVE(buf, m, c, n, NISSY_ERROR_INVALID_MOVES, | ||
| 68 | ret[c] = m; | ||
| 69 | ) | ||
| 70 | |||
| 71 | return (int64_t)c; | ||
| 72 | } | ||
| 73 | |||
| 74 | STATIC int64_t | ||
| 42 | writemoves( | 75 | writemoves( |
| 43 | size_t nmoves, | 76 | size_t nmoves, |
| 44 | uint8_t m[nmoves], | 77 | const uint8_t m[nmoves], |
| 45 | size_t buf_size, | 78 | size_t buf_size, |
| 46 | char buf[buf_size] | 79 | char buf[buf_size] |
| 47 | ) | 80 | ) |
| @@ -69,7 +102,9 @@ writemoves( | |||
| 69 | *b = ' '; | 102 | *b = ' '; |
| 70 | } | 103 | } |
| 71 | 104 | ||
| 72 | if (b != buf) | 105 | if (b == buf) |
| 106 | written = 1; /* Nothing written, only NULL-terminator */ | ||
| 107 | else | ||
| 73 | b--; /* Remove last space */ | 108 | b--; /* Remove last space */ |
| 74 | *b = '\0'; | 109 | *b = '\0'; |
| 75 | 110 | ||
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 | { |
