+}
+
+static int ymm_registers_available_p(void)
+{
+ struct xcr xcr0;
+ int f;
+
+ f = cpuid_feature_p(CPUID_1_C, CPUID1C_OSXSAVE);
+ dispatch_debug("XGETBV %savailable", f ? "" : "not ");
+ if (!f) return (0);
+
+ dispatch_x86ish_xgetbv(&xcr0, 0); f = (xcr0.lo&0x06) == 0x06;
+ dispatch_debug("YMM state %senabled", f ? "" : "not ");
+ if (!f) return (0);
+
+ return (1);
+}
+
+/* --- @rdrand_works_p@ --- *
+ *
+ *
+ * Arguments: ---
+ *
+ * Returns: Nonzero if the `rdrand' instruction actually works. Assumes
+ * that it's already been verified to be safe to issue.
+ */
+
+enum { OP_RDRAND, OP_RDSEED };
+
+static int rdrand_works_p(unsigned op)
+{
+ unsigned ref, x, i;
+ const char *what;
+
+ switch (op) {
+ case OP_RDRAND: what = "RDRAND"; break;
+ case OP_RDSEED: what = "RDSEED"; break;
+ default: assert(!"unexpected op");
+ }
+
+ /* Check that it doesn't always give the same answer. Try four times: this
+ * will fail with probability %$2^{-128}$% with a truly random generator,
+ * which seems fair enough.
+ */
+ if (dispatch_x86ish_rdrand(op, &ref)) goto fail;
+ for (i = 0; i < 4; i++) {
+ if (dispatch_x86ish_rdrand(op, &x)) goto fail;
+ if (x != ref) goto not_stuck;
+ }
+ dispatch_debug("%s always returns 0x%08x!", what, ref);
+ return (0);
+
+not_stuck:
+ dispatch_debug("%s instruction looks plausible", what);
+ return (1);
+
+fail:
+ dispatch_debug("%s instruction fails too often", what);