| 1 | #define _GNU_SOURCE |
| 2 | #include <stdio.h> |
| 3 | #include <stdlib.h> |
| 4 | |
| 5 | static int clst(char sep, const char **s1, const char **s2) |
| 6 | { |
| 7 | const char *r1 = *s1; |
| 8 | const char *r2 = *s2; |
| 9 | int cc; |
| 10 | |
| 11 | do { |
| 12 | register int r0 asm("r0") = sep; |
| 13 | |
| 14 | asm("clst %[r1],%[r2]\n" |
| 15 | "ipm %[cc]\n" |
| 16 | "srl %[cc],28" |
| 17 | : [r1] "+r" (r1), [r2] "+r" (r2), "+r" (r0), [cc] "=r" (cc) |
| 18 | : |
| 19 | : "cc"); |
| 20 | *s1 = r1; |
| 21 | *s2 = r2; |
| 22 | } while (cc == 3); |
| 23 | |
| 24 | return cc; |
| 25 | } |
| 26 | |
| 27 | static const struct test { |
| 28 | const char *name; |
| 29 | char sep; |
| 30 | const char *s1; |
| 31 | const char *s2; |
| 32 | int exp_cc; |
| 33 | int exp_off; |
| 34 | } tests[] = { |
| 35 | { |
| 36 | .name = "cc0", |
| 37 | .sep = 0, |
| 38 | .s1 = "aa", |
| 39 | .s2 = "aa", |
| 40 | .exp_cc = 0, |
| 41 | .exp_off = 0, |
| 42 | }, |
| 43 | { |
| 44 | .name = "cc1", |
| 45 | .sep = 1, |
| 46 | .s1 = "a\x01", |
| 47 | .s2 = "aa\x01", |
| 48 | .exp_cc = 1, |
| 49 | .exp_off = 1, |
| 50 | }, |
| 51 | { |
| 52 | .name = "cc2", |
| 53 | .sep = 2, |
| 54 | .s1 = "abc\x02", |
| 55 | .s2 = "abb\x02", |
| 56 | .exp_cc = 2, |
| 57 | .exp_off = 2, |
| 58 | }, |
| 59 | }; |
| 60 | |
| 61 | int main(void) |
| 62 | { |
| 63 | const struct test *t; |
| 64 | const char *s1, *s2; |
| 65 | size_t i; |
| 66 | int cc; |
| 67 | |
| 68 | for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { |
| 69 | t = &tests[i]; |
| 70 | s1 = t->s1; |
| 71 | s2 = t->s2; |
| 72 | cc = clst(t->sep, &s1, &s2); |
| 73 | if (cc != t->exp_cc || |
| 74 | s1 != t->s1 + t->exp_off || |
| 75 | s2 != t->s2 + t->exp_off) { |
| 76 | fprintf(stderr, "%s\n", t->name); |
| 77 | return EXIT_FAILURE; |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | return EXIT_SUCCESS; |
| 82 | } |