return sum;
}
+/* C.f. Arm pseudocode PredCountTest */
+static uint32_t pred_count_test(uint32_t elements, uint32_t count, bool invert)
+{
+ uint32_t flags;
+
+ if (count == 0) {
+ flags = 1; /* !N, Z, C */
+ } else if (!invert) {
+ flags = (1u << 31) | 2; /* N, !Z */
+ flags |= count != elements; /* C */
+ } else {
+ flags = 2; /* !Z, !C */
+ flags |= (count == elements) << 31; /* N */
+ }
+ return flags;
+}
+
uint32_t HELPER(sve_whilel)(void *vd, uint32_t count, uint32_t pred_desc)
{
intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
uint64_t esz_mask = pred_esz_masks[esz];
ARMPredicateReg *d = vd;
- uint32_t flags;
- intptr_t i;
+ intptr_t i, oprbits = oprsz * 8;
- /* Begin with a zero predicate register. */
- flags = do_zero(d, oprsz);
- if (count == 0) {
- return flags;
- }
+ tcg_debug_assert(count <= oprbits);
- /* Set all of the requested bits. */
- for (i = 0; i < count / 64; ++i) {
- d->p[i] = esz_mask;
- }
- if (count & 63) {
- d->p[i] = MAKE_64BIT_MASK(0, count & 63) & esz_mask;
+ /* Begin with a zero predicate register. */
+ do_zero(d, oprsz);
+ if (count) {
+ /* Set all of the requested bits. */
+ for (i = 0; i < count / 64; ++i) {
+ d->p[i] = esz_mask;
+ }
+ if (count & 63) {
+ d->p[i] = MAKE_64BIT_MASK(0, count & 63) & esz_mask;
+ }
}
- return predtest_ones(d, oprsz, esz_mask);
+ return pred_count_test(oprbits, count, false);
}
uint32_t HELPER(sve_whileg)(void *vd, uint32_t count, uint32_t pred_desc)
intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
uint64_t esz_mask = pred_esz_masks[esz];
ARMPredicateReg *d = vd;
- intptr_t i, invcount, oprbits;
+ intptr_t i, invcount, oprbits = oprsz * 8;
uint64_t bits;
- if (count == 0) {
- return do_zero(d, oprsz);
- }
-
- oprbits = oprsz * 8;
tcg_debug_assert(count <= oprbits);
- bits = esz_mask;
- if (oprbits & 63) {
- bits &= MAKE_64BIT_MASK(0, oprbits & 63);
- }
-
- invcount = oprbits - count;
- for (i = (oprsz - 1) / 8; i > invcount / 64; --i) {
- d->p[i] = bits;
+ /* Begin with a zero predicate register. */
+ do_zero(d, oprsz);
+ if (count) {
+ /* Set all of the requested bits. */
bits = esz_mask;
- }
-
- d->p[i] = bits & MAKE_64BIT_MASK(invcount & 63, 64);
+ if (oprbits & 63) {
+ bits &= MAKE_64BIT_MASK(0, oprbits & 63);
+ }
- while (--i >= 0) {
- d->p[i] = 0;
+ invcount = oprbits - count;
+ for (i = (oprsz - 1) / 8; i > invcount / 64; --i) {
+ d->p[i] = bits;
+ bits = esz_mask;
+ }
+ d->p[i] = bits & MAKE_64BIT_MASK(invcount & 63, 64);
}
- return predtest_ones(d, oprsz, esz_mask);
+ return pred_count_test(oprbits, count, true);
}
/* Recursive reduction on a function;