aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2020-01-25 00:53:39 -0800
committerMax Filippov <jcmvbkbc@gmail.com>2020-08-21 12:48:15 -0700
commited07f685adcd2c3496dbbaefc07f7e1a996fce58 (patch)
tree6f46c1884f00dee74831503e218ab01caa8c92bf /target
parentee659da21af5707191ef35e8de549d028790e7f5 (diff)
downloadqemu-ed07f685adcd2c3496dbbaefc07f7e1a996fce58.zip
qemu-ed07f685adcd2c3496dbbaefc07f7e1a996fce58.tar.gz
qemu-ed07f685adcd2c3496dbbaefc07f7e1a996fce58.tar.bz2
target/xtensa: support copying registers up to 64 bits wide
FLIX dependency breaking code assumes that all registers are 32 bit wide. This may not always be correct. Extract actual register width from the associated register file and use it to create temporaries of correct width and generate correct data movement instructions. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'target')
-rw-r--r--target/xtensa/cpu.h1
-rw-r--r--target/xtensa/translate.c26
2 files changed, 22 insertions, 5 deletions
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 0409aa6..960f657 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -359,6 +359,7 @@ typedef struct opcode_arg {
uint32_t raw_imm;
void *in;
void *out;
+ uint32_t num_bits;
} OpcodeArg;
typedef struct DisasContext DisasContext;
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 9838bf6..bc01a72 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -943,10 +943,10 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
for (opnd = vopnd = 0; opnd < opnds; ++opnd) {
void **register_file = NULL;
+ xtensa_regfile rf;
if (xtensa_operand_is_register(isa, opc, opnd)) {
- xtensa_regfile rf = xtensa_operand_regfile(isa, opc, opnd);
-
+ rf = xtensa_operand_regfile(isa, opc, opnd);
register_file = dc->config->regfile[rf];
if (rf == dc->config->a_regfile) {
@@ -972,6 +972,9 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
if (register_file) {
arg[vopnd].in = register_file[v];
arg[vopnd].out = register_file[v];
+ arg[vopnd].num_bits = xtensa_regfile_num_bits(isa, rf);
+ } else {
+ arg[vopnd].num_bits = 32;
}
++vopnd;
}
@@ -1111,8 +1114,15 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
for (i = j = 0; i < n_arg_copy; ++i) {
if (i == 0 || arg_copy[i].resource != resource) {
resource = arg_copy[i].resource;
- temp = tcg_temp_local_new();
- tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
+ if (arg_copy[i].arg->num_bits <= 32) {
+ temp = tcg_temp_local_new_i32();
+ tcg_gen_mov_i32(temp, arg_copy[i].arg->in);
+ } else if (arg_copy[i].arg->num_bits <= 64) {
+ temp = tcg_temp_local_new_i64();
+ tcg_gen_mov_i64(temp, arg_copy[i].arg->in);
+ } else {
+ g_assert_not_reached();
+ }
arg_copy[i].temp = temp;
if (i != j) {
@@ -1143,7 +1153,13 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
}
for (i = 0; i < n_arg_copy; ++i) {
- tcg_temp_free(arg_copy[i].temp);
+ if (arg_copy[i].arg->num_bits <= 32) {
+ tcg_temp_free_i32(arg_copy[i].temp);
+ } else if (arg_copy[i].arg->num_bits <= 64) {
+ tcg_temp_free_i64(arg_copy[i].temp);
+ } else {
+ g_assert_not_reached();
+ }
}
if (dc->base.is_jmp == DISAS_NEXT) {