Commit ff4a62cd8100f373ce0195d5e888c191a1a07516
1 parent
931ff272
target-ppc: convert load/store multiple instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5825 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
78 additions
and
142 deletions
target-ppc/helper.h
target-ppc/op_helper.c
| ... | ... | @@ -109,6 +109,69 @@ void ppc_store_dump_spr (int sprn, target_ulong val) |
| 109 | 109 | } |
| 110 | 110 | |
| 111 | 111 | /*****************************************************************************/ |
| 112 | +/* Memory load and stores */ | |
| 113 | + | |
| 114 | +static always_inline target_ulong get_addr(target_ulong addr) | |
| 115 | +{ | |
| 116 | +#if defined(TARGET_PPC64) | |
| 117 | + if (msr_sf) | |
| 118 | + return addr; | |
| 119 | + else | |
| 120 | +#endif | |
| 121 | + return (uint32_t)addr; | |
| 122 | +} | |
| 123 | + | |
| 124 | +void helper_lmw (target_ulong addr, uint32_t reg) | |
| 125 | +{ | |
| 126 | +#ifdef CONFIG_USER_ONLY | |
| 127 | +#define ldfun ldl_raw | |
| 128 | +#else | |
| 129 | + int (*ldfun)(target_ulong); | |
| 130 | + | |
| 131 | + switch (env->mmu_idx) { | |
| 132 | + default: | |
| 133 | + case 0: ldfun = ldl_user; | |
| 134 | + break; | |
| 135 | + case 1: ldfun = ldl_kernel; | |
| 136 | + break; | |
| 137 | + case 2: ldfun = ldl_hypv; | |
| 138 | + break; | |
| 139 | + } | |
| 140 | +#endif | |
| 141 | + for (; reg < 32; reg++, addr += 4) { | |
| 142 | + if (msr_le) | |
| 143 | + env->gpr[reg] = bswap32(ldfun(get_addr(addr))); | |
| 144 | + else | |
| 145 | + env->gpr[reg] = ldfun(get_addr(addr)); | |
| 146 | + } | |
| 147 | +} | |
| 148 | + | |
| 149 | +void helper_stmw (target_ulong addr, uint32_t reg) | |
| 150 | +{ | |
| 151 | +#ifdef CONFIG_USER_ONLY | |
| 152 | +#define stfun stl_raw | |
| 153 | +#else | |
| 154 | + void (*stfun)(target_ulong, int); | |
| 155 | + | |
| 156 | + switch (env->mmu_idx) { | |
| 157 | + default: | |
| 158 | + case 0: stfun = stl_user; | |
| 159 | + break; | |
| 160 | + case 1: stfun = stl_kernel; | |
| 161 | + break; | |
| 162 | + case 2: stfun = stl_hypv; | |
| 163 | + break; | |
| 164 | + } | |
| 165 | +#endif | |
| 166 | + for (; reg < 32; reg++, addr += 4) { | |
| 167 | + if (msr_le) | |
| 168 | + stfun(get_addr(addr), bswap32((uint32_t)env->gpr[reg])); | |
| 169 | + else | |
| 170 | + stfun(get_addr(addr), (uint32_t)env->gpr[reg]); | |
| 171 | + } | |
| 172 | +} | |
| 173 | + | |
| 174 | +/*****************************************************************************/ | |
| 112 | 175 | /* Fixed point operations helpers */ |
| 113 | 176 | #if defined(TARGET_PPC64) |
| 114 | 177 | ... | ... |
target-ppc/op_helper.h
| ... | ... | @@ -23,10 +23,6 @@ |
| 23 | 23 | /* Memory load/store helpers */ |
| 24 | 24 | void glue(do_lsw, MEMSUFFIX) (int dst); |
| 25 | 25 | void glue(do_stsw, MEMSUFFIX) (int src); |
| 26 | -void glue(do_lmw, MEMSUFFIX) (int dst); | |
| 27 | -void glue(do_lmw_le, MEMSUFFIX) (int dst); | |
| 28 | -void glue(do_stmw, MEMSUFFIX) (int src); | |
| 29 | -void glue(do_stmw_le, MEMSUFFIX) (int src); | |
| 30 | 26 | void glue(do_icbi, MEMSUFFIX) (void); |
| 31 | 27 | void glue(do_dcbz, MEMSUFFIX) (void); |
| 32 | 28 | void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); |
| ... | ... | @@ -38,10 +34,6 @@ void glue(do_POWER2_stfq_le, MEMSUFFIX) (void); |
| 38 | 34 | #if defined(TARGET_PPC64) |
| 39 | 35 | void glue(do_lsw_64, MEMSUFFIX) (int dst); |
| 40 | 36 | void glue(do_stsw_64, MEMSUFFIX) (int src); |
| 41 | -void glue(do_lmw_64, MEMSUFFIX) (int dst); | |
| 42 | -void glue(do_lmw_le_64, MEMSUFFIX) (int dst); | |
| 43 | -void glue(do_stmw_64, MEMSUFFIX) (int src); | |
| 44 | -void glue(do_stmw_le_64, MEMSUFFIX) (int src); | |
| 45 | 37 | void glue(do_icbi_64, MEMSUFFIX) (void); |
| 46 | 38 | void glue(do_dcbz_64, MEMSUFFIX) (void); |
| 47 | 39 | #endif | ... | ... |
target-ppc/op_helper_mem.h
| ... | ... | @@ -20,71 +20,6 @@ |
| 20 | 20 | |
| 21 | 21 | #include "op_mem_access.h" |
| 22 | 22 | |
| 23 | -/* Multiple word / string load and store */ | |
| 24 | -void glue(do_lmw, MEMSUFFIX) (int dst) | |
| 25 | -{ | |
| 26 | - for (; dst < 32; dst++, T0 += 4) { | |
| 27 | - env->gpr[dst] = glue(ldu32, MEMSUFFIX)((uint32_t)T0); | |
| 28 | - } | |
| 29 | -} | |
| 30 | - | |
| 31 | -#if defined(TARGET_PPC64) | |
| 32 | -void glue(do_lmw_64, MEMSUFFIX) (int dst) | |
| 33 | -{ | |
| 34 | - for (; dst < 32; dst++, T0 += 4) { | |
| 35 | - env->gpr[dst] = glue(ldu32, MEMSUFFIX)((uint64_t)T0); | |
| 36 | - } | |
| 37 | -} | |
| 38 | -#endif | |
| 39 | - | |
| 40 | -void glue(do_stmw, MEMSUFFIX) (int src) | |
| 41 | -{ | |
| 42 | - for (; src < 32; src++, T0 += 4) { | |
| 43 | - glue(st32, MEMSUFFIX)((uint32_t)T0, env->gpr[src]); | |
| 44 | - } | |
| 45 | -} | |
| 46 | - | |
| 47 | -#if defined(TARGET_PPC64) | |
| 48 | -void glue(do_stmw_64, MEMSUFFIX) (int src) | |
| 49 | -{ | |
| 50 | - for (; src < 32; src++, T0 += 4) { | |
| 51 | - glue(st32, MEMSUFFIX)((uint64_t)T0, env->gpr[src]); | |
| 52 | - } | |
| 53 | -} | |
| 54 | -#endif | |
| 55 | - | |
| 56 | -void glue(do_lmw_le, MEMSUFFIX) (int dst) | |
| 57 | -{ | |
| 58 | - for (; dst < 32; dst++, T0 += 4) { | |
| 59 | - env->gpr[dst] = glue(ldu32r, MEMSUFFIX)((uint32_t)T0); | |
| 60 | - } | |
| 61 | -} | |
| 62 | - | |
| 63 | -#if defined(TARGET_PPC64) | |
| 64 | -void glue(do_lmw_le_64, MEMSUFFIX) (int dst) | |
| 65 | -{ | |
| 66 | - for (; dst < 32; dst++, T0 += 4) { | |
| 67 | - env->gpr[dst] = glue(ldu32r, MEMSUFFIX)((uint64_t)T0); | |
| 68 | - } | |
| 69 | -} | |
| 70 | -#endif | |
| 71 | - | |
| 72 | -void glue(do_stmw_le, MEMSUFFIX) (int src) | |
| 73 | -{ | |
| 74 | - for (; src < 32; src++, T0 += 4) { | |
| 75 | - glue(st32r, MEMSUFFIX)((uint32_t)T0, env->gpr[src]); | |
| 76 | - } | |
| 77 | -} | |
| 78 | - | |
| 79 | -#if defined(TARGET_PPC64) | |
| 80 | -void glue(do_stmw_le_64, MEMSUFFIX) (int src) | |
| 81 | -{ | |
| 82 | - for (; src < 32; src++, T0 += 4) { | |
| 83 | - glue(st32r, MEMSUFFIX)((uint64_t)T0, env->gpr[src]); | |
| 84 | - } | |
| 85 | -} | |
| 86 | -#endif | |
| 87 | - | |
| 88 | 23 | void glue(do_lsw, MEMSUFFIX) (int dst) |
| 89 | 24 | { |
| 90 | 25 | uint32_t tmp; | ... | ... |
target-ppc/op_mem.h
| ... | ... | @@ -20,63 +20,6 @@ |
| 20 | 20 | |
| 21 | 21 | #include "op_mem_access.h" |
| 22 | 22 | |
| 23 | -/*** Integer load and store multiple ***/ | |
| 24 | -void OPPROTO glue(op_lmw, MEMSUFFIX) (void) | |
| 25 | -{ | |
| 26 | - glue(do_lmw, MEMSUFFIX)(PARAM1); | |
| 27 | - RETURN(); | |
| 28 | -} | |
| 29 | - | |
| 30 | -#if defined(TARGET_PPC64) | |
| 31 | -void OPPROTO glue(op_lmw_64, MEMSUFFIX) (void) | |
| 32 | -{ | |
| 33 | - glue(do_lmw_64, MEMSUFFIX)(PARAM1); | |
| 34 | - RETURN(); | |
| 35 | -} | |
| 36 | -#endif | |
| 37 | - | |
| 38 | -void OPPROTO glue(op_lmw_le, MEMSUFFIX) (void) | |
| 39 | -{ | |
| 40 | - glue(do_lmw_le, MEMSUFFIX)(PARAM1); | |
| 41 | - RETURN(); | |
| 42 | -} | |
| 43 | - | |
| 44 | -#if defined(TARGET_PPC64) | |
| 45 | -void OPPROTO glue(op_lmw_le_64, MEMSUFFIX) (void) | |
| 46 | -{ | |
| 47 | - glue(do_lmw_le_64, MEMSUFFIX)(PARAM1); | |
| 48 | - RETURN(); | |
| 49 | -} | |
| 50 | -#endif | |
| 51 | - | |
| 52 | -void OPPROTO glue(op_stmw, MEMSUFFIX) (void) | |
| 53 | -{ | |
| 54 | - glue(do_stmw, MEMSUFFIX)(PARAM1); | |
| 55 | - RETURN(); | |
| 56 | -} | |
| 57 | - | |
| 58 | -#if defined(TARGET_PPC64) | |
| 59 | -void OPPROTO glue(op_stmw_64, MEMSUFFIX) (void) | |
| 60 | -{ | |
| 61 | - glue(do_stmw_64, MEMSUFFIX)(PARAM1); | |
| 62 | - RETURN(); | |
| 63 | -} | |
| 64 | -#endif | |
| 65 | - | |
| 66 | -void OPPROTO glue(op_stmw_le, MEMSUFFIX) (void) | |
| 67 | -{ | |
| 68 | - glue(do_stmw_le, MEMSUFFIX)(PARAM1); | |
| 69 | - RETURN(); | |
| 70 | -} | |
| 71 | - | |
| 72 | -#if defined(TARGET_PPC64) | |
| 73 | -void OPPROTO glue(op_stmw_le_64, MEMSUFFIX) (void) | |
| 74 | -{ | |
| 75 | - glue(do_stmw_le_64, MEMSUFFIX)(PARAM1); | |
| 76 | - RETURN(); | |
| 77 | -} | |
| 78 | -#endif | |
| 79 | - | |
| 80 | 23 | /*** Integer load and store strings ***/ |
| 81 | 24 | void OPPROTO glue(op_lswi, MEMSUFFIX) (void) |
| 82 | 25 | { | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -3092,30 +3092,30 @@ void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags) |
| 3092 | 3092 | GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER); |
| 3093 | 3093 | |
| 3094 | 3094 | /*** Integer load and store multiple ***/ |
| 3095 | -#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg) | |
| 3096 | -static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = { | |
| 3097 | - GEN_MEM_FUNCS(lmw), | |
| 3098 | -}; | |
| 3099 | -static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = { | |
| 3100 | - GEN_MEM_FUNCS(stmw), | |
| 3101 | -}; | |
| 3102 | - | |
| 3103 | 3095 | /* lmw */ |
| 3104 | 3096 | GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
| 3105 | 3097 | { |
| 3098 | + TCGv t0 = tcg_temp_new(); | |
| 3099 | + TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode)); | |
| 3106 | 3100 | /* NIP cannot be restored if the memory exception comes from an helper */ |
| 3107 | 3101 | gen_update_nip(ctx, ctx->nip - 4); |
| 3108 | - gen_addr_imm_index(cpu_T[0], ctx, 0); | |
| 3109 | - op_ldstm(lmw, rD(ctx->opcode)); | |
| 3102 | + gen_addr_imm_index(t0, ctx, 0); | |
| 3103 | + gen_helper_lmw(t0, t1); | |
| 3104 | + tcg_temp_free(t0); | |
| 3105 | + tcg_temp_free_i32(t1); | |
| 3110 | 3106 | } |
| 3111 | 3107 | |
| 3112 | 3108 | /* stmw */ |
| 3113 | 3109 | GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
| 3114 | 3110 | { |
| 3111 | + TCGv t0 = tcg_temp_new(); | |
| 3112 | + TCGv_i32 t1 = tcg_const_i32(rS(ctx->opcode)); | |
| 3115 | 3113 | /* NIP cannot be restored if the memory exception comes from an helper */ |
| 3116 | 3114 | gen_update_nip(ctx, ctx->nip - 4); |
| 3117 | - gen_addr_imm_index(cpu_T[0], ctx, 0); | |
| 3118 | - op_ldstm(stmw, rS(ctx->opcode)); | |
| 3115 | + gen_addr_imm_index(t0, ctx, 0); | |
| 3116 | + gen_helper_stmw(t0, t1); | |
| 3117 | + tcg_temp_free(t0); | |
| 3118 | + tcg_temp_free_i32(t1); | |
| 3119 | 3119 | } |
| 3120 | 3120 | |
| 3121 | 3121 | /*** Integer load and store strings ***/ | ... | ... |