* [Qemu-devel] [PATCH, MIPS64] 64-bit addressing fixes @ 2007-05-20 23:01 Aurelien Jarno 2007-05-21 13:52 ` Blue Swirl 0 siblings, 1 reply; 3+ messages in thread From: Aurelien Jarno @ 2007-05-20 23:01 UTC (permalink / raw) To: qemu-devel Hi, The patch below fixes 64-bit addresses when manipulating the program counter, the branch target or the branch link register. dyngen currently does not support passing 64-bit values to PARAM1 and PARAM2, they are limited to 32-bit. This patch creates a new op_set64 function to set a register with a 64-bit value, by passing high and low word in PARAM1 and PARAM2. The same thing is done for the op_save_btarget and op_save_pc instructions. Unfortunately it is not possible to pass the value via T0, T1 or T2, and then move it to btarget or pc, because those functions are used in save_cpu_state where T0, T1 or T2 may already be used. With this patch I am now able to run o32, n32 and n64 binaries without problem. Cheers, Aurelien Index: target-mips/op.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/op.c,v retrieving revision 1.60 diff -u -d -p -r1.60 op.c --- target-mips/op.c 20 May 2007 01:36:28 -0000 1.60 +++ target-mips/op.c 20 May 2007 22:52:49 -0000 @@ -972,7 +972,11 @@ void op_breg (void) void op_save_btarget (void) { +#ifdef TARGET_MIPS64 + env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; +#else env->btarget = PARAM1; +#endif RETURN(); } @@ -2415,7 +2419,11 @@ void op_save_state (void) void op_save_pc (void) { +#ifdef TARGET_MIPS64 + env->PC = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; +#else env->PC = PARAM1; +#endif RETURN(); } Index: target-mips/op_template.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/op_template.c,v retrieving revision 1.5 diff -u -d -p -r1.5 op_template.c --- target-mips/op_template.c 29 Apr 2007 21:19:03 -0000 1.5 +++ target-mips/op_template.c 20 May 2007 22:52:49 -0000 @@ -68,4 +68,20 @@ SET_RESET(T1, _T1) SET_RESET(T2, _T2) #undef SET_RESET + +#ifdef TARGET_MIPS64 +#define SET64(treg, tregname) \ + void glue(op_set64, tregname)(void) \ + { \ + treg = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; \ + RETURN(); \ + } + +SET64(T0, _T0) +SET64(T1, _T1) +SET64(T2, _T2) + +#undef SET64 + +#endif #endif Index: target-mips/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/translate.c,v retrieving revision 1.85 diff -u -d -p -r1.85 translate.c --- target-mips/translate.c 20 May 2007 13:27:58 -0000 1.85 +++ target-mips/translate.c 20 May 2007 22:52:49 -0000 @@ -604,7 +604,11 @@ static inline void save_cpu_state (Disas } #endif if (do_save_pc && ctx->pc != ctx->saved_pc) { +#ifdef TARGET_MIPS64 + gen_op_save_pc(ctx->pc >> 32, (uint32_t)ctx->pc); +#else gen_op_save_pc(ctx->pc); +#endif ctx->saved_pc = ctx->pc; } if (ctx->hflags != ctx->saved_hflags) { @@ -621,7 +625,11 @@ static inline void save_cpu_state (Disas /* bcond was already saved by the BL insn */ /* fall through */ case MIPS_HFLAG_B: +#ifdef TARGET_MIPS64 + gen_op_save_btarget(ctx->btarget >> 32, (uint32_t)ctx->btarget); +#else gen_op_save_btarget(ctx->btarget); +#endif break; } } @@ -1491,10 +1499,18 @@ static inline void gen_goto_tb(DisasCont gen_op_goto_tb0(TBPARAM(tb)); else gen_op_goto_tb1(TBPARAM(tb)); +#ifdef TARGET_MIPS64 + gen_op_save_pc(dest >> 32, (uint32_t)dest); +#else gen_op_save_pc(dest); +#endif gen_op_set_T0((long)tb + n); } else { +#ifdef TARGET_MIPS64 + gen_op_save_pc(dest >> 32, (uint32_t)dest); +#else gen_op_save_pc(dest); +#endif gen_op_reset_T0(); } gen_op_exit_tb(); @@ -1556,7 +1572,7 @@ static void gen_compute_branch (DisasCon case OPC_J: case OPC_JAL: /* Jump to immediate */ - btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset; + btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset; break; case OPC_JR: case OPC_JALR: @@ -1602,12 +1618,20 @@ static void gen_compute_branch (DisasCon MIPS_DEBUG("bnever (NOP)"); return; case OPC_BLTZAL: /* 0 < 0 */ +#ifdef TARGET_MIPS64 + gen_op_set64_T0((ctx->pc + 8) >> 32, (uint32_t)(ctx->pc + 8)); +#else gen_op_set_T0(ctx->pc + 8); +#endif gen_op_store_T0_gpr(31); MIPS_DEBUG("bnever and link"); return; case OPC_BLTZALL: /* 0 < 0 likely */ +#ifdef TARGET_MIPS64 + gen_op_set64_T0((ctx->pc + 8) >> 32, (uint32_t)(ctx->pc + 8)); +#else gen_op_set_T0(ctx->pc + 8); +#endif gen_op_store_T0_gpr(31); /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever, link and skip"); @@ -1732,9 +1756,14 @@ static void gen_compute_branch (DisasCon } MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, blink, ctx->hflags, btarget); + ctx->btarget = btarget; if (blink > 0) { +#ifdef TARGET_MIPS64 + gen_op_set64_T0((ctx->pc + 8) >> 32, (uint32_t)(ctx->pc + 8)); +#else gen_op_set_T0(ctx->pc + 8); +#endif gen_op_store_T0_gpr(blink); } } -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' aurel32@debian.org | aurelien@aurel32.net `- people.debian.org/~aurel32 | www.aurel32.net ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH, MIPS64] 64-bit addressing fixes 2007-05-20 23:01 [Qemu-devel] [PATCH, MIPS64] 64-bit addressing fixes Aurelien Jarno @ 2007-05-21 13:52 ` Blue Swirl 2007-05-26 21:15 ` Aurelien Jarno 0 siblings, 1 reply; 3+ messages in thread From: Blue Swirl @ 2007-05-21 13:52 UTC (permalink / raw) To: qemu-devel On 5/21/07, Aurelien Jarno <aurelien@aurel32.net> wrote: > dyngen currently does not support passing 64-bit values to PARAM1 and > PARAM2, they are limited to 32-bit. This patch creates a new op_set64 > function to set a register with a 64-bit value, by passing high and low > word in PARAM1 and PARAM2. The same thing is done for the > op_save_btarget and op_save_pc instructions. Unfortunately it is not > possible to pass the value via T0, T1 or T2, and then move it to btarget > or pc, because those functions are used in save_cpu_state where T0, T1 > or T2 may already be used. I don't know MIPS, but perhaps you could try this trick used in Sparc: static inline void gen_jmp_im(target_ulong pc) { #ifdef TARGET_SPARC64 if (pc == (uint32_t)pc) { gen_op_jmp_im(pc); } else { gen_op_jmp_im64(pc >> 32, pc); } #else gen_op_jmp_im(pc); #endif } ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH, MIPS64] 64-bit addressing fixes 2007-05-21 13:52 ` Blue Swirl @ 2007-05-26 21:15 ` Aurelien Jarno 0 siblings, 0 replies; 3+ messages in thread From: Aurelien Jarno @ 2007-05-26 21:15 UTC (permalink / raw) To: qemu-devel On Mon, May 21, 2007 at 04:52:05PM +0300, Blue Swirl wrote: > I don't know MIPS, but perhaps you could try this trick used in Sparc: > static inline void gen_jmp_im(target_ulong pc) > { > #ifdef TARGET_SPARC64 > if (pc == (uint32_t)pc) { > gen_op_jmp_im(pc); > } else { > gen_op_jmp_im64(pc >> 32, pc); > } > #else > gen_op_jmp_im(pc); > #endif > } > Here is a new patch using the same trick as the one used in Sparc. It renders the code clearer. Sorry for the delay. Index: target-mips/op.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/op.c,v retrieving revision 1.62 diff -u -d -p -r1.62 op.c --- target-mips/op.c 23 May 2007 08:24:25 -0000 1.62 +++ target-mips/op.c 26 May 2007 21:12:05 -0000 @@ -976,6 +976,14 @@ void op_save_btarget (void) RETURN(); } +#ifdef TARGET_MIPS64 +void op_save_btarget64 (void) +{ + env->btarget = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; + RETURN(); +} +#endif + /* Conditional branch */ void op_set_bcond (void) { @@ -2409,6 +2417,14 @@ void op_save_pc (void) RETURN(); } +#ifdef TARGET_MIPS64 +void op_save_pc64 (void) +{ + env->PC = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; + RETURN(); +} +#endif + void op_interrupt_restart (void) { if (!(env->CP0_Status & (1 << CP0St_EXL)) && Index: target-mips/op_template.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/op_template.c,v retrieving revision 1.5 diff -u -d -p -r1.5 op_template.c --- target-mips/op_template.c 29 Apr 2007 21:19:03 -0000 1.5 +++ target-mips/op_template.c 26 May 2007 21:12:05 -0000 @@ -68,4 +68,20 @@ SET_RESET(T1, _T1) SET_RESET(T2, _T2) #undef SET_RESET + +#ifdef TARGET_MIPS64 +#define SET64(treg, tregname) \ + void glue(op_set64, tregname)(void) \ + { \ + treg = ((uint64_t)PARAM1 << 32) | (uint32_t)PARAM2; \ + RETURN(); \ + } + +SET64(T0, _T0) +SET64(T1, _T1) +SET64(T2, _T2) + +#undef SET64 + +#endif #endif Index: target-mips/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/translate.c,v retrieving revision 1.87 diff -u -d -p -r1.87 translate.c --- target-mips/translate.c 23 May 2007 08:24:25 -0000 1.87 +++ target-mips/translate.c 26 May 2007 21:12:05 -0000 @@ -569,6 +569,18 @@ do { } \ } while (0) +#ifdef TARGET_MIPS64 +#define GEN_LOAD_IMM_TN(Tn, Imm) \ +do { \ + if (Imm == 0) { \ + glue(gen_op_reset_, Tn)(); \ + } else if ((int32_t)Imm == Imm) { \ + glue(gen_op_set_, Tn)(Imm); \ + } else { \ + glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm); \ + } \ +} while (0) +#else #define GEN_LOAD_IMM_TN(Tn, Imm) \ do { \ if (Imm == 0) { \ @@ -577,6 +589,7 @@ do { glue(gen_op_set_, Tn)(Imm); \ } \ } while (0) +#endif #define GEN_STORE_TN_REG(Rn, Tn) \ do { \ @@ -595,6 +608,32 @@ do { glue(gen_op_store_fpr_, FTn)(Fn); \ } while (0) +static inline void gen_save_pc(target_ulong pc) +{ +#ifdef TARGET_MIPS64 + if (pc == (int32_t)pc) { + gen_op_save_pc(pc); + } else { + gen_op_save_pc64(pc >> 32, (uint32_t)pc); + } +#else + gen_op_save_pc(pc); +#endif +} + +static inline void gen_save_btarget(target_ulong btarget) +{ +#ifdef TARGET_MIPS64 + if (btarget == (int32_t)btarget) { + gen_op_save_btarget(btarget); + } else { + gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget); + } +#else + gen_op_save_btarget(btarget); +#endif +} + static inline void save_cpu_state (DisasContext *ctx, int do_save_pc) { #if defined MIPS_DEBUG_DISAS @@ -604,7 +643,7 @@ static inline void save_cpu_state (Disas } #endif if (do_save_pc && ctx->pc != ctx->saved_pc) { - gen_op_save_pc(ctx->pc); + gen_save_pc(ctx->pc); ctx->saved_pc = ctx->pc; } if (ctx->hflags != ctx->saved_hflags) { @@ -621,7 +660,7 @@ static inline void save_cpu_state (Disas /* bcond was already saved by the BL insn */ /* fall through */ case MIPS_HFLAG_B: - gen_op_save_btarget(ctx->btarget); + gen_save_btarget(ctx->btarget); break; } } @@ -946,7 +985,7 @@ static void gen_arith_imm (DisasContext GEN_LOAD_IMM_TN(T1, uimm); break; case OPC_LUI: - GEN_LOAD_IMM_TN(T0, uimm << 16); + GEN_LOAD_IMM_TN(T0, imm << 16); break; case OPC_SLL: case OPC_SRA: @@ -1491,10 +1530,10 @@ static inline void gen_goto_tb(DisasCont gen_op_goto_tb0(TBPARAM(tb)); else gen_op_goto_tb1(TBPARAM(tb)); - gen_op_save_pc(dest); + gen_save_pc(dest); gen_op_set_T0((long)tb + n); } else { - gen_op_save_pc(dest); + gen_save_pc(dest); gen_op_reset_T0(); } gen_op_exit_tb(); @@ -1556,7 +1595,7 @@ static void gen_compute_branch (DisasCon case OPC_J: case OPC_JAL: /* Jump to immediate */ - btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | offset; + btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset; break; case OPC_JR: case OPC_JALR: @@ -1602,12 +1641,12 @@ static void gen_compute_branch (DisasCon MIPS_DEBUG("bnever (NOP)"); return; case OPC_BLTZAL: /* 0 < 0 */ - gen_op_set_T0(ctx->pc + 8); + GEN_LOAD_IMM_TN(T0, ctx->pc + 8); gen_op_store_T0_gpr(31); MIPS_DEBUG("bnever and link"); return; case OPC_BLTZALL: /* 0 < 0 likely */ - gen_op_set_T0(ctx->pc + 8); + GEN_LOAD_IMM_TN(T0, ctx->pc + 8); gen_op_store_T0_gpr(31); /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever, link and skip"); @@ -1732,9 +1771,10 @@ static void gen_compute_branch (DisasCon } MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx, blink, ctx->hflags, btarget); + ctx->btarget = btarget; if (blink > 0) { - gen_op_set_T0(ctx->pc + 8); + GEN_LOAD_IMM_TN(T0, ctx->pc + 8); gen_op_store_T0_gpr(blink); } } -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' aurel32@debian.org | aurelien@aurel32.net `- people.debian.org/~aurel32 | www.aurel32.net ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-05-26 21:15 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-05-20 23:01 [Qemu-devel] [PATCH, MIPS64] 64-bit addressing fixes Aurelien Jarno 2007-05-21 13:52 ` Blue Swirl 2007-05-26 21:15 ` Aurelien Jarno
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).