target/arm: Use uint32_t instead of bitmap for sve vq's

The bitmap need only hold 15 bits; bitmap is over-complicated.
We can simplify operations quite a bit with plain logical ops.

The introduction of SVE_VQ_POW2_MAP eliminates the need for
looping in order to search for powers of two.  Simply perform
the logical ops and use count leading or trailing zeros as
required to find the result.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20220607203306.657998-12-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2022-06-08 19:38:57 +01:00 committed by Peter Maydell
parent 9b5f422559
commit 886902ece7
6 changed files with 75 additions and 105 deletions

View file

@ -760,15 +760,13 @@ bool kvm_arm_steal_time_supported(void)
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map)
uint32_t kvm_arm_sve_get_vls(CPUState *cs)
{
/* Only call this function if kvm_arm_sve_supported() returns true. */
static uint64_t vls[KVM_ARM64_SVE_VLS_WORDS];
static bool probed;
uint32_t vq = 0;
int i, j;
bitmap_zero(map, ARM_MAX_VQ);
int i;
/*
* KVM ensures all host CPUs support the same set of vector lengths.
@ -809,46 +807,24 @@ void kvm_arm_sve_get_vls(CPUState *cs, unsigned long *map)
if (vq > ARM_MAX_VQ) {
warn_report("KVM supports vector lengths larger than "
"QEMU can enable");
vls[0] &= MAKE_64BIT_MASK(0, ARM_MAX_VQ);
}
}
for (i = 0; i < KVM_ARM64_SVE_VLS_WORDS; ++i) {
if (!vls[i]) {
continue;
}
for (j = 1; j <= 64; ++j) {
vq = j + i * 64;
if (vq > ARM_MAX_VQ) {
return;
}
if (vls[i] & (1UL << (j - 1))) {
set_bit(vq - 1, map);
}
}
}
return vls[0];
}
static int kvm_arm_sve_set_vls(CPUState *cs)
{
uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] = {0};
ARMCPU *cpu = ARM_CPU(cs);
uint64_t vls[KVM_ARM64_SVE_VLS_WORDS] = { cpu->sve_vq_map };
struct kvm_one_reg reg = {
.id = KVM_REG_ARM64_SVE_VLS,
.addr = (uint64_t)&vls[0],
};
ARMCPU *cpu = ARM_CPU(cs);
uint32_t vq;
int i, j;
assert(cpu->sve_max_vq <= KVM_ARM64_SVE_VQ_MAX);
for (vq = 1; vq <= cpu->sve_max_vq; ++vq) {
if (test_bit(vq - 1, cpu->sve_vq_map)) {
i = (vq - 1) / 64;
j = (vq - 1) % 64;
vls[i] |= 1UL << j;
}
}
return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
}