Commit 41795758 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/xtensa/tags/20190228-xtensa' into staging



target/xtensa: FLIX support, various fixes and test improvements

- add FLIX (flexible length instructions extension) support;
- make testsuite runnable on wider range of xtensa cores;
- add floating point opcode tests;
- don't add duplicate 'static' in import_core.sh script;
- fix undefined opcodes detection in test_mmuhifi_c3 overlay.

# gpg: Signature made Thu 28 Feb 2019 12:53:23 GMT
# gpg:                using RSA key 2B67854B98E5327DCDEB17D851F9CC91F83FA044
# gpg:                issuer "jcmvbkbc@gmail.com"
# gpg: Good signature from "Max Filippov <filippov@cadence.com>" [unknown]
# gpg:                 aka "Max Filippov <max.filippov@cogentembedded.com>" [full]
# gpg:                 aka "Max Filippov <jcmvbkbc@gmail.com>" [full]
# Primary key fingerprint: 2B67 854B 98E5 327D CDEB  17D8 51F9 CC91 F83F A044

* remotes/xtensa/tags/20190228-xtensa: (40 commits)
  tests/tcg/xtensa: add FPU2000 coprocessor tests
  tests/tcg/xtensa: add FP1 group tests
  tests/tcg/xtensa: add FP0 group conversion tests
  tests/tcg/xtensa: add FP0 group arithmetic tests
  tests/tcg/xtensa: add LSCI/LSCX group tests
  tests/tcg/xtensa: add test for FLIX
  tests/tcg/xtensa: conditionalize MMU-related tests
  tests/tcg/xtensa: conditionalize windowed register tests
  tests/tcg/xtensa: conditionalize and fix s32c1i tests
  tests/tcg/xtensa: fix SR tests for big endian configs
  tests/tcg/xtensa: conditionalize and expand SR tests
  tests/tcg/xtensa: conditionalize timer/CCOUNT tests
  tests/tcg/xtensa: conditionalize interrupt tests
  tests/tcg/xtensa: add straightforward conditionals
  tests/tcg/xtensa: conditionalize cache option tests
  tests/tcg/xtensa: conditionalize debug option tests
  tests/tcg/xtensa: enable boolean tests
  tests/tcg/xtensa: fix endianness issues in test_b
  tests/tcg/xtensa: don't use optional opcodes in generic code
  tests/tcg/xtensa: support configs with LITBASE
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 9403bccf de0cebd9
Loading
Loading
Loading
Loading
+661 −661

File changed.

Preview size limit exceeded, changes collapsed.

+32 −8
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ enum {
    ACCLO = 16,
    ACCHI = 17,
    MR = 32,
    PREFCTL = 40,
    WINDOW_BASE = 72,
    WINDOW_START = 73,
    PTEVADDR = 83,
@@ -345,14 +346,21 @@ typedef struct XtensaMemory {
    } location[MAX_NMEMORY];
} XtensaMemory;

typedef struct opcode_arg {
    uint32_t imm;
    uint32_t raw_imm;
    void *in;
    void *out;
} OpcodeArg;

typedef struct DisasContext DisasContext;
typedef void (*XtensaOpcodeOp)(DisasContext *dc, const uint32_t arg[],
typedef void (*XtensaOpcodeOp)(DisasContext *dc, const OpcodeArg arg[],
                               const uint32_t par[]);
typedef bool (*XtensaOpcodeBoolTest)(DisasContext *dc,
                                     const uint32_t arg[],
                                     const OpcodeArg arg[],
                                     const uint32_t par[]);
typedef uint32_t (*XtensaOpcodeUintTest)(DisasContext *dc,
                                         const uint32_t arg[],
                                         const OpcodeArg arg[],
                                         const uint32_t par[]);

enum {
@@ -368,19 +376,34 @@ enum {

    XTENSA_OP_DIVIDE_BY_ZERO = 0x100,

    /* Postprocessing flags */
    XTENSA_OP_CHECK_INTERRUPTS = 0x200,
    XTENSA_OP_EXIT_TB_M1 = 0x400,
    XTENSA_OP_EXIT_TB_0 = 0x800,
    XTENSA_OP_SYNC_REGISTER_WINDOW = 0x1000,

    XTENSA_OP_POSTPROCESS =
        XTENSA_OP_CHECK_INTERRUPTS |
        XTENSA_OP_EXIT_TB_M1 |
        XTENSA_OP_EXIT_TB_0 |
        XTENSA_OP_SYNC_REGISTER_WINDOW,

    XTENSA_OP_NAME_ARRAY = 0x8000,

    XTENSA_OP_CONTROL_FLOW = 0x10000,
    XTENSA_OP_STORE = 0x20000,
    XTENSA_OP_LOAD = 0x40000,
    XTENSA_OP_LOAD_STORE =
        XTENSA_OP_LOAD | XTENSA_OP_STORE,
};

typedef struct XtensaOpcodeOps {
    const char *name;
    const void *name;
    XtensaOpcodeOp translate;
    XtensaOpcodeBoolTest test_ill;
    XtensaOpcodeUintTest test_overflow;
    const uint32_t *par;
    uint32_t op_flags;
    uint32_t windowed_register_op;
    uint32_t coprocessor;
} XtensaOpcodeOps;

@@ -438,6 +461,8 @@ struct XtensaConfig {
    xtensa_isa isa;
    XtensaOpcodeOps **opcode_ops;
    const XtensaOpcodeTranslators **opcode_translators;
    xtensa_regfile a_regfile;
    void ***regfile;

    uint32_t clock_freq_khz;

@@ -474,6 +499,7 @@ typedef struct CPUXtensaState {
        float64 f64;
    } fregs[16];
    float_status fp_status;
    uint32_t windowbase_next;

#ifndef CONFIG_USER_ONLY
    xtensa_tlb_entry itlb[7][MAX_TLB_WAY_SIZE];
@@ -565,8 +591,8 @@ void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
    XTENSA_CPU_TYPE_NAME(XTENSA_DEFAULT_CPU_NOMMU_MODEL)

void xtensa_translate_init(void);
void **xtensa_get_regfile_by_name(const char *name);
void xtensa_breakpoint_handler(CPUState *cs);
void xtensa_finalize_config(XtensaConfig *config);
void xtensa_register_core(XtensaConfigList *node);
void xtensa_sim_open_console(Chardev *chr);
void check_interrupts(CPUXtensaState *s);
@@ -588,8 +614,6 @@ static inline void xtensa_select_static_vectors(CPUXtensaState *env,
    env->static_vectors = n;
}
void xtensa_runstall(CPUXtensaState *env, bool runstall);
XtensaOpcodeOps *xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
                                        const char *opcode);

#define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))
#define XTENSA_OPTION_ALL (~(uint64_t)0)
+82 −12
Original line number Diff line number Diff line
@@ -30,24 +30,60 @@
#include "exec/exec-all.h"
#include "exec/gdbstub.h"
#include "exec/helper-proto.h"
#include "qemu/error-report.h"
#include "qemu/host-utils.h"

static struct XtensaConfigList *xtensa_cores;

static void xtensa_core_class_init(ObjectClass *oc, void *data)
static void add_translator_to_hash(GHashTable *translator,
                                   const char *name,
                                   const XtensaOpcodeOps *opcode)
{
    CPUClass *cc = CPU_CLASS(oc);
    XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
    const XtensaConfig *config = data;
    if (!g_hash_table_insert(translator, (void *)name, (void *)opcode)) {
        error_report("Multiple definitions of '%s' opcode in a single table",
                     name);
    }
}

    xcc->config = config;
static GHashTable *hash_opcode_translators(const XtensaOpcodeTranslators *t)
{
    unsigned i, j;
    GHashTable *translator = g_hash_table_new(g_str_hash, g_str_equal);

    /* Use num_core_regs to see only non-privileged registers in an unmodified
     * gdb. Use num_regs to see all registers. gdb modification is required
     * for that: reset bit 0 in the 'flags' field of the registers definitions
     * in the gdb/xtensa-config.c inside gdb source tree or inside gdb overlay.
     */
    cc->gdb_num_core_regs = config->gdb_regmap.num_regs;
    for (i = 0; i < t->num_opcodes; ++i) {
        if (t->opcode[i].op_flags & XTENSA_OP_NAME_ARRAY) {
            const char * const *name = t->opcode[i].name;

            for (j = 0; name[j]; ++j) {
                add_translator_to_hash(translator,
                                       (void *)name[j],
                                       (void *)(t->opcode + i));
            }
        } else {
            add_translator_to_hash(translator,
                                   (void *)t->opcode[i].name,
                                   (void *)(t->opcode + i));
        }
    }
    return translator;
}

static XtensaOpcodeOps *
xtensa_find_opcode_ops(const XtensaOpcodeTranslators *t,
                       const char *name)
{
    static GHashTable *translators;
    GHashTable *translator;

    if (translators == NULL) {
        translators = g_hash_table_new(g_direct_hash, g_direct_equal);
    }
    translator = g_hash_table_lookup(translators, t);
    if (translator == NULL) {
        translator = hash_opcode_translators(t);
        g_hash_table_insert(translators, (void *)t, translator);
    }
    return g_hash_table_lookup(translator, name);
}

static void init_libisa(XtensaConfig *config)
@@ -55,11 +91,13 @@ static void init_libisa(XtensaConfig *config)
    unsigned i, j;
    unsigned opcodes;
    unsigned formats;
    unsigned regfiles;

    config->isa = xtensa_isa_init(config->isa_internal, NULL, NULL);
    assert(xtensa_isa_maxlength(config->isa) <= MAX_INSN_LENGTH);
    opcodes = xtensa_isa_num_opcodes(config->isa);
    formats = xtensa_isa_num_formats(config->isa);
    regfiles = xtensa_isa_num_regfiles(config->isa);
    config->opcode_ops = g_new(XtensaOpcodeOps *, opcodes);

    for (i = 0; i < formats; ++i) {
@@ -88,9 +126,23 @@ static void init_libisa(XtensaConfig *config)
#endif
        config->opcode_ops[i] = ops;
    }
    config->a_regfile = xtensa_regfile_lookup(config->isa, "AR");

    config->regfile = g_new(void **, regfiles);
    for (i = 0; i < regfiles; ++i) {
        const char *name = xtensa_regfile_name(config->isa, i);

        config->regfile[i] = xtensa_get_regfile_by_name(name);
#ifdef DEBUG
        if (config->regfile[i] == NULL) {
            fprintf(stderr, "regfile '%s' not found for %s\n",
                    name, config->name);
        }
#endif
    }
}

void xtensa_finalize_config(XtensaConfig *config)
static void xtensa_finalize_config(XtensaConfig *config)
{
    if (config->isa_internal) {
        init_libisa(config);
@@ -111,6 +163,24 @@ void xtensa_finalize_config(XtensaConfig *config)
    }
}

static void xtensa_core_class_init(ObjectClass *oc, void *data)
{
    CPUClass *cc = CPU_CLASS(oc);
    XtensaCPUClass *xcc = XTENSA_CPU_CLASS(oc);
    XtensaConfig *config = data;

    xtensa_finalize_config(config);
    xcc->config = config;

    /*
     * Use num_core_regs to see only non-privileged registers in an unmodified
     * gdb. Use num_regs to see all registers. gdb modification is required
     * for that: reset bit 0 in the 'flags' field of the registers definitions
     * in the gdb/xtensa-config.c inside gdb source tree or inside gdb overlay.
     */
    cc->gdb_num_core_regs = config->gdb_regmap.num_regs;
}

void xtensa_register_core(XtensaConfigList *node)
{
    TypeInfo type = {
+2 −3
Original line number Diff line number Diff line
@@ -3,12 +3,11 @@ DEF_HELPER_3(exception_cause, noreturn, env, i32, i32)
DEF_HELPER_4(exception_cause_vaddr, noreturn, env, i32, i32, i32)
DEF_HELPER_3(debug_exception, noreturn, env, i32, i32)

DEF_HELPER_2(wsr_windowbase, void, env, i32)
DEF_HELPER_1(sync_windowbase, void, env)
DEF_HELPER_4(entry, void, env, i32, i32, i32)
DEF_HELPER_2(test_ill_retw, void, env, i32)
DEF_HELPER_2(test_underflow_retw, void, env, i32)
DEF_HELPER_2(retw, i32, env, i32)
DEF_HELPER_2(rotw, void, env, i32)
DEF_HELPER_2(retw, void, env, i32)
DEF_HELPER_3(window_check, noreturn, env, i32, i32)
DEF_HELPER_1(restore_owb, void, env)
DEF_HELPER_2(movsp, void, env, i32)
+1 −1
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ tar -xf "$OVERLAY" -O gdb/xtensa-config.c | \
# Fix up known issues in the xtensa-modules.c
#
tar -xf "$OVERLAY" -O binutils/xtensa-modules.c | \
    sed -e 's/\(xtensa_opcode_encode_fn.*\[\] =\)/static \1/' \
    sed -e 's/^\(xtensa_opcode_encode_fn.*\[\] =\)/static \1/' \
        -e '/^int num_bypass_groups()/,/}/d' \
        -e '/^int num_bypass_group_chunks()/,/}/d' \
        -e '/^uint32 \*bypass_entry(int i)/,/}/d' \
Loading