mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-28 05:50:37 +00:00
target/xtensa: reorganize register handling in translators
To support circular register dependencies in FLIX bundles opcode inputs and outputs must be separate and adjustable. Circular dependencies can be broken by making temporary copies of opcode inputs and substituting them into the arguments array instead of the original registers. E.g. the circular register dependency in the following bundle: { mov a2, a3 ; mov a3, a2 } can be resolved by making copy a2' = a2 and substituting it as input argument of the second opcode: { mov a2, a3 ; mov a3, a2' } Change opcode translator prototype to accept OpcodeArg array as argument. For each register argument initialize OpcodeArg::{in,out} with TCGv_* of the respective register. Don't explicitly use cpu_R in the opcode translators, use OpcodeArg::{in,out} instead. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
parent
c949009bc0
commit
b0b24bdcd9
@ -345,14 +345,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 {
|
||||
@ -450,6 +457,7 @@ struct XtensaConfig {
|
||||
XtensaOpcodeOps **opcode_ops;
|
||||
const XtensaOpcodeTranslators **opcode_translators;
|
||||
xtensa_regfile a_regfile;
|
||||
void ***regfile;
|
||||
|
||||
uint32_t clock_freq_khz;
|
||||
|
||||
@ -578,6 +586,7 @@ 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_register_core(XtensaConfigList *node);
|
||||
void xtensa_sim_open_console(Chardev *chr);
|
||||
|
@ -91,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) {
|
||||
@ -125,6 +127,19 @@ static void init_libisa(XtensaConfig *config)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
static void xtensa_finalize_config(XtensaConfig *config)
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user