unsigned int sat : 1;
unsigned int dz : 1;
unsigned int sz : 1;
+ unsigned int ff : 3 + 2; /* 3-bit plus RC1 */
};
+#define SVP64_RC1_ACTIVE (1U << 3U)
+#define SVP64_RC1_INVERT (SVP64_RC1_ACTIVE | (1U << 4U))
+
static jmp_buf svp64_exception;
#define svp64_raise(...) \
const char *str;
unsigned int len : 3;
unsigned int cr : 1;
- unsigned int mask : 3;
+ unsigned int mask : 3 + 2; /* 3-bit plus RC1 */
};
#define SVP64_PREDICATE_MAP(STR, MODE, MASK) \
{ STR, (sizeof (STR) - 1), MODE, MASK }
SVP64_PREDICATE_MAP ("un" , 1, 6), /* same value as so */
SVP64_PREDICATE_MAP ("ns" , 1, 7),
SVP64_PREDICATE_MAP ("nu" , 1, 7), /* same value as ns */
+ /* RC1 */
+ SVP64_PREDICATE_MAP ("RC1" , 0, SVP64_RC1_ACTIVE),
+ SVP64_PREDICATE_MAP ("~RC1" , 0, SVP64_RC1_INVERT),
};
for (i = 0; i < sizeof (table) / sizeof (table[0]); ++i)
return NULL;
}
+static char *
+svp64_decode_predicate_bo (char *str, unsigned int *mask)
+{
+ bool cr;
+ char *iter;
+
+ iter = svp64_decode_predicate (str, &cr, mask);
+ if (!iter || !(cr || ((*mask & SVP64_RC1_ACTIVE) != 0)))
+ return NULL;
+
+ *mask = ((((*mask >> 0) & 0x1) << 2) |
+ (((*mask >> 1) & 0x3) << 0));
+
+ return iter;
+}
+
struct svp64_decoder {
char *(*call)(char *str, struct svp64_ctx *svp64);
const char *str;
str += (sizeof ("m=") - 1);
iter = svp64_decode_predicate (str, &cr, &pmask);
- if (!iter)
+ if (!iter || ((pmask & SVP64_RC1_ACTIVE) != 0))
svp64_raise (_("unrecognized mode: `%s'"), str);
pmmode = (cr ? 1 : 0);
str += (sizeof ("dm=") - 1);
iter = svp64_decode_predicate (str, &cr, &pmask);
- if (!iter)
+ if (!iter || ((pmask & SVP64_RC1_ACTIVE) != 0))
svp64_raise (_("unrecognized mode: `%s'"), str);
pmmode = (cr ? 1 : 0);
str += (sizeof ("sm=") - 1);
iter = svp64_decode_predicate (str, &cr, &smask);
- if (!iter)
+ if (!iter || ((smask & SVP64_RC1_ACTIVE) != 0))
svp64_raise (_("unrecognized mode: `%s'"), str);
smmode = (cr ? 1 : 0);
return str;
}
+static char *
+svp64_decode_ff (char *str, struct svp64_ctx *svp64)
+{
+ char *iter;
+ unsigned int mask;
+
+ str += (sizeof ("ff=") - 1);
+ if (svp64->sv_mode_explicit)
+ svp64_raise (_("SV mode conflict: `%s'"), str);
+
+ iter = svp64_decode_predicate_bo (str, &mask);
+ if (!iter)
+ svp64_raise (_("unrecognized mode: `%s'"), str);
+
+ svp64->sv_mode_explicit = 1;
+ svp64->sv_mode = 0x1;
+ svp64->ff = mask;
+
+ return iter;
+}
+
static char *
svp64_decode_mode (char *str, struct svp64_ctx *svp64)
{
SVP64_DECODER ("zz" , svp64_decode_zz),
SVP64_DECODER ("dz" , svp64_decode_dz),
SVP64_DECODER ("sz" , svp64_decode_sz),
+ SVP64_DECODER ("ff=" , svp64_decode_ff),
};
for (i = 0; i < sizeof (table) / sizeof (table[0]); ++i)