#define SVP64_SEP '/'
+static inline char *
+svp64_expression (char *str, expressionS *exp)
+{
+ char old_sep;
+ char *str_tail;
+ char *str_head = str;
+ char *old_ilp = input_line_pointer;
+
+ memset (exp, 0, sizeof *exp);
+
+ while (! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0')
+ ++str;
+ if (*str != '\0')
+ *str++ = '\0';
+ str_tail = str;
+ old_sep = *str;
+ *str = '\0';
+ str = str_head;
+ input_line_pointer = str;
+
+ expression (exp);
+ resolve_register (exp);
+
+ input_line_pointer = old_ilp;
+ *str_tail = old_sep;
+
+ return ((exp->X_op == O_absent) ? str_head : str_tail);
+}
+
struct svp64_predicate_map {
const char *str;
unsigned int len : 3;
struct svp64_width_map {
const char *str;
- unsigned int len;
- unsigned int width;
+ unsigned int len : 2;
+ unsigned int num : 6;
+ unsigned int width : 8;
};
-#define SVP64_WIDTH_MAP(STR, WIDTH) \
- { STR, (sizeof (STR) - 1), WIDTH }
+#define SVP64_WIDTH_MAP(NUM, WIDTH) \
+ { #NUM, (sizeof (#NUM) - 1), NUM, WIDTH }
static char *
svp64_decode_width (char *str, unsigned int *width)
{
size_t i;
+ char *origin;
+ expressionS exp;
static const struct svp64_width_map table[] = {
- SVP64_WIDTH_MAP ("8", 3),
- SVP64_WIDTH_MAP ("16", 2),
- SVP64_WIDTH_MAP ("32", 1),
+ SVP64_WIDTH_MAP (8, 3),
+ SVP64_WIDTH_MAP (16, 2),
+ SVP64_WIDTH_MAP (32, 1),
};
- for (i = 0; i < (sizeof (table) / sizeof (table[0])); ++i)
+ origin = str;
+ str = svp64_expression (str, &exp);
+ if ((str != origin) && (exp.X_op == O_constant))
{
- const struct svp64_width_map *entry = &table[i];
-
- if (strncmp (str, entry->str, entry->len) != 0)
- continue;
-
- str += entry->len;
- if (! ISSPACE (*str) && *str != SVP64_SEP && *str != '\0')
+ for (i = 0; i < (sizeof (table) / sizeof (table[0])); ++i)
{
- str -= entry->len;
- continue;
- }
-
- *width = entry->width;
-
- *str++ = '\0';
+ const struct svp64_width_map *entry = &table[i];
- return str;
+ if (entry->num == exp.X_add_number)
+ {
+ *width = entry->width;
+ return str;
+ }
+ }
}
return NULL;