#define _GNU_SOURCE | |
#include <stdio.h> | |
#include <stdlib.h> | |
static int clst(char sep, const char **s1, const char **s2) | |
{ | |
const char *r1 = *s1; | |
const char *r2 = *s2; | |
int cc; | |
do { | |
register int r0 asm("r0") = sep; | |
asm("clst %[r1],%[r2]\n" | |
"ipm %[cc]\n" | |
"srl %[cc],28" | |
: [r1] "+r" (r1), [r2] "+r" (r2), "+r" (r0), [cc] "=r" (cc) | |
: | |
: "cc"); | |
*s1 = r1; | |
*s2 = r2; | |
} while (cc == 3); | |
return cc; | |
} | |
static const struct test { | |
const char *name; | |
char sep; | |
const char *s1; | |
const char *s2; | |
int exp_cc; | |
int exp_off; | |
} tests[] = { | |
{ | |
.name = "cc0", | |
.sep = 0, | |
.s1 = "aa", | |
.s2 = "aa", | |
.exp_cc = 0, | |
.exp_off = 0, | |
}, | |
{ | |
.name = "cc1", | |
.sep = 1, | |
.s1 = "a\x01", | |
.s2 = "aa\x01", | |
.exp_cc = 1, | |
.exp_off = 1, | |
}, | |
{ | |
.name = "cc2", | |
.sep = 2, | |
.s1 = "abc\x02", | |
.s2 = "abb\x02", | |
.exp_cc = 2, | |
.exp_off = 2, | |
}, | |
}; | |
int main(void) | |
{ | |
const struct test *t; | |
const char *s1, *s2; | |
size_t i; | |
int cc; | |
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { | |
t = &tests[i]; | |
s1 = t->s1; | |
s2 = t->s2; | |
cc = clst(t->sep, &s1, &s2); | |
if (cc != t->exp_cc || | |
s1 != t->s1 + t->exp_off || | |
s2 != t->s2 + t->exp_off) { | |
fprintf(stderr, "%s\n", t->name); | |
return EXIT_FAILURE; | |
} | |
} | |
return EXIT_SUCCESS; | |
} |