Commit 2bf5f3f9 authored by Richard Henderson's avatar Richard Henderson Committed by Peter Maydell
Browse files

target/arm: Dump SVE state if enabled



Also fold the FPCR/FPSR state onto the same line as PSTATE,
and mention but do not dump disabled FPU state.

Cc: qemu-stable@nongnu.org (3.0.1)
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Reviewed-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Tested-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 3cb506a3
Loading
Loading
Loading
Loading
+82 −11
Original line number Diff line number Diff line
@@ -152,8 +152,7 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
    } else {
        ns_status = "";
    }

    cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
    cpu_fprintf(f, "PSTATE=%08x %c%c%c%c %sEL%d%c",
                psr,
                psr & PSTATE_N ? 'N' : '-',
                psr & PSTATE_Z ? 'Z' : '-',
@@ -163,17 +162,89 @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
                el,
                psr & PSTATE_SP ? 'h' : 't');

    if (flags & CPU_DUMP_FPU) {
        int numvfpregs = 32;
        for (i = 0; i < numvfpregs; i++) {
            uint64_t *q = aa64_vfp_qreg(env, i);
            uint64_t vlo = q[0];
            uint64_t vhi = q[1];
            cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "%c",
                        i, vhi, vlo, (i & 1 ? '\n' : ' '));
    if (!(flags & CPU_DUMP_FPU)) {
        cpu_fprintf(f, "\n");
        return;
    }
        cpu_fprintf(f, "FPCR: %08x  FPSR: %08x\n",
    cpu_fprintf(f, "     FPCR=%08x FPSR=%08x\n",
                vfp_get_fpcr(env), vfp_get_fpsr(env));

    if (arm_feature(env, ARM_FEATURE_SVE)) {
        int j, zcr_len = env->vfp.zcr_el[1] & 0xf; /* fix for system mode */

        for (i = 0; i <= FFR_PRED_NUM; i++) {
            bool eol;
            if (i == FFR_PRED_NUM) {
                cpu_fprintf(f, "FFR=");
                /* It's last, so end the line.  */
                eol = true;
            } else {
                cpu_fprintf(f, "P%02d=", i);
                switch (zcr_len) {
                case 0:
                    eol = i % 8 == 7;
                    break;
                case 1:
                    eol = i % 6 == 5;
                    break;
                case 2:
                case 3:
                    eol = i % 3 == 2;
                    break;
                default:
                    /* More than one quadword per predicate.  */
                    eol = true;
                    break;
                }
            }
            for (j = zcr_len / 4; j >= 0; j--) {
                int digits;
                if (j * 4 + 4 <= zcr_len + 1) {
                    digits = 16;
                } else {
                    digits = (zcr_len % 4 + 1) * 4;
                }
                cpu_fprintf(f, "%0*" PRIx64 "%s", digits,
                            env->vfp.pregs[i].p[j],
                            j ? ":" : eol ? "\n" : " ");
            }
        }

        for (i = 0; i < 32; i++) {
            if (zcr_len == 0) {
                cpu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
                            i, env->vfp.zregs[i].d[1],
                            env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
            } else if (zcr_len == 1) {
                cpu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
                            ":%016" PRIx64 ":%016" PRIx64 "\n",
                            i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
                            env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
            } else {
                for (j = zcr_len; j >= 0; j--) {
                    bool odd = (zcr_len - j) % 2 != 0;
                    if (j == zcr_len) {
                        cpu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
                    } else if (!odd) {
                        if (j > 0) {
                            cpu_fprintf(f, "   [%x-%x]=", j, j - 1);
                        } else {
                            cpu_fprintf(f, "     [%x]=", j);
                        }
                    }
                    cpu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
                                env->vfp.zregs[i].d[j * 2 + 1],
                                env->vfp.zregs[i].d[j * 2],
                                odd || j == 0 ? "\n" : ":");
                }
            }
        }
    } else {
        for (i = 0; i < 32; i++) {
            uint64_t *q = aa64_vfp_qreg(env, i);
            cpu_fprintf(f, "Q%02d=%016" PRIx64 ":%016" PRIx64 "%s",
                        i, q[1], q[0], (i & 1 ? "\n" : " "));
        }
    }
}