unsigned int rg : 1;
unsigned int crm : 1;
unsigned int svm : 1;
+ unsigned int type : 2;
};
#define SVP64_RC1_ACTIVE (1U << 3U)
#define SVP64_RC1_INVERT (SVP64_RC1_ACTIVE | (1U << 4U))
+enum svp64_type {
+ SVP64_TYPE_NONE,
+ SVP64_TYPE_LD,
+ SVP64_TYPE_ST,
+ SVP64_TYPE_BC,
+};
+
static jmp_buf svp64_exception;
#define svp64_raise(...) \
return NULL;
}
+struct svp64_str_map {
+ const char *str;
+ size_t len;
+};
+#define SVP64_STR_MAP(STR) \
+ { STR, (sizeof (STR) - 1) }
+
+static bool
+svp64_str_map_cmp(const char *str, size_t len,
+ const struct svp64_str_map *map, size_t cnt)
+{
+ size_t i;
+
+ for (i = 0; i < cnt; ++i) {
+ const struct svp64_str_map *entry = &map[i];
+
+ if ((entry->len == len) && (memcmp(entry->str, str, len) == 0))
+ return true;
+ }
+
+ return false;
+}
+#define SVP64_STR_MAP_CMP(STR, LEN, MAP) \
+ svp64_str_map_cmp(STR, LEN, MAP, (sizeof (MAP) / sizeof (*MAP)))
+
+static bool
+svp64_is_ld(const char *str, size_t len)
+{
+ static const struct svp64_str_map table[] = {
+ /* load byte */
+ SVP64_STR_MAP ("lbarx"),
+ SVP64_STR_MAP ("lbz"),
+ SVP64_STR_MAP ("lbzu"),
+ SVP64_STR_MAP ("lbzux"),
+ SVP64_STR_MAP ("lbzx"),
+ /* load double */
+ SVP64_STR_MAP ("ld"),
+ SVP64_STR_MAP ("ldarx"),
+ SVP64_STR_MAP ("ldbrx"),
+ SVP64_STR_MAP ("ldu"),
+ SVP64_STR_MAP ("ldux"),
+ SVP64_STR_MAP ("ldx"),
+ /* FP load single */
+ SVP64_STR_MAP ("lfs"),
+ SVP64_STR_MAP ("lfsx"),
+ SVP64_STR_MAP ("lfsu"),
+ SVP64_STR_MAP ("lfsux"),
+ /* FP load double */
+ SVP64_STR_MAP ("lfd"),
+ SVP64_STR_MAP ("lfdx"),
+ SVP64_STR_MAP ("lfdu"),
+ SVP64_STR_MAP ("lfdux"),
+ SVP64_STR_MAP ("lfiwzx"),
+ SVP64_STR_MAP ("lfiwax"),
+ /* load half */
+ SVP64_STR_MAP ("lha"),
+ SVP64_STR_MAP ("lharx"),
+ SVP64_STR_MAP ("lhau"),
+ SVP64_STR_MAP ("lhaux"),
+ SVP64_STR_MAP ("lhax"),
+ SVP64_STR_MAP ("lhbrx"),
+ SVP64_STR_MAP ("lhz"),
+ SVP64_STR_MAP ("lhzu"),
+ SVP64_STR_MAP ("lhzux"),
+ SVP64_STR_MAP ("lhzx"),
+ /* load word */
+ SVP64_STR_MAP ("lwa"),
+ SVP64_STR_MAP ("lwarx"),
+ SVP64_STR_MAP ("lwaux"),
+ SVP64_STR_MAP ("lwax"),
+ SVP64_STR_MAP ("lwbrx"),
+ SVP64_STR_MAP ("lwz"),
+ SVP64_STR_MAP ("lwzcix"),
+ SVP64_STR_MAP ("lwzu"),
+ SVP64_STR_MAP ("lwzux"),
+ SVP64_STR_MAP ("lwzx"),
+ };
+
+ return SVP64_STR_MAP_CMP(str, len, table);
+}
+
+static bool
+svp64_is_st(const char *str, size_t len)
+{
+ static const struct svp64_str_map table[] = {
+ /* store byte */
+ SVP64_STR_MAP ("stb"),
+ SVP64_STR_MAP ("stbcix"),
+ SVP64_STR_MAP ("stbcx"),
+ SVP64_STR_MAP ("stbu"),
+ SVP64_STR_MAP ("stbux"),
+ SVP64_STR_MAP ("stbx"),
+ /* store double */
+ SVP64_STR_MAP ("std"),
+ SVP64_STR_MAP ("stdbrx"),
+ SVP64_STR_MAP ("stdcx"),
+ SVP64_STR_MAP ("stdu"),
+ SVP64_STR_MAP ("stdux"),
+ SVP64_STR_MAP ("stdx"),
+ /* FP store single */
+ SVP64_STR_MAP ("stfs"),
+ SVP64_STR_MAP ("stfsx"),
+ SVP64_STR_MAP ("stfsu"),
+ SVP64_STR_MAP ("stfux"),
+ /* FP store double */
+ SVP64_STR_MAP ("stfd"),
+ SVP64_STR_MAP ("stfdx"),
+ SVP64_STR_MAP ("stfdu"),
+ SVP64_STR_MAP ("stfdux"),
+ SVP64_STR_MAP ("stfiwx"),
+ /* store half */
+ SVP64_STR_MAP ("sth"),
+ SVP64_STR_MAP ("sthbrx"),
+ SVP64_STR_MAP ("sthcx"),
+ SVP64_STR_MAP ("sthu"),
+ SVP64_STR_MAP ("sthux"),
+ SVP64_STR_MAP ("sthx"),
+ /* store word */
+ SVP64_STR_MAP ("stw"),
+ SVP64_STR_MAP ("stwbrx"),
+ SVP64_STR_MAP ("stwcx"),
+ SVP64_STR_MAP ("stwu"),
+ SVP64_STR_MAP ("stwux"),
+ SVP64_STR_MAP ("stwx"),
+ };
+
+ return SVP64_STR_MAP_CMP(str, len, table);
+}
+
+static bool
+svp64_is_bc(const char *str, size_t len)
+{
+ static const struct svp64_str_map table[] = {
+ SVP64_STR_MAP ("bc"),
+ SVP64_STR_MAP ("bclr"),
+ };
+
+ return SVP64_STR_MAP_CMP(str, len, table);
+}
+
static void
svp64_decode (char *str, struct svp64_ctx *svp64)
{
char *opc;
+ size_t opclen;
char *iter;
str += (sizeof ("sv.") - 1);
opc = str;
for (; ! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0'; ++str)
;
+ opclen = (str - opc);
if (*str != '\0')
*str++ = '\0';
+ if (svp64_is_ld (opc, opclen))
+ svp64->type = SVP64_TYPE_LD;
+ else if (svp64_is_st (opc, opclen))
+ svp64->type = SVP64_TYPE_ST;
+ else if (svp64_is_bc (opc, opclen))
+ svp64->type = SVP64_TYPE_BC;
+
for (; (iter = svp64_decode_mode (str, svp64)) != NULL; str = iter)
;