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 ***/ | ... | ... |