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
@@ -7,6 +7,9 @@ DEF_HELPER_3(tw, void, tl, tl, i32) | @@ -7,6 +7,9 @@ DEF_HELPER_3(tw, void, tl, tl, i32) | ||
7 | DEF_HELPER_3(td, void, tl, tl, i32) | 7 | DEF_HELPER_3(td, void, tl, tl, i32) |
8 | #endif | 8 | #endif |
9 | 9 | ||
10 | +DEF_HELPER_2(lmw, void, tl, i32) | ||
11 | +DEF_HELPER_2(stmw, void, tl, i32) | ||
12 | + | ||
10 | DEF_HELPER_2(fcmpo, i32, i64, i64) | 13 | DEF_HELPER_2(fcmpo, i32, i64, i64) |
11 | DEF_HELPER_2(fcmpu, i32, i64, i64) | 14 | DEF_HELPER_2(fcmpu, i32, i64, i64) |
12 | 15 |
target-ppc/op_helper.c
@@ -109,6 +109,69 @@ void ppc_store_dump_spr (int sprn, target_ulong val) | @@ -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 | /* Fixed point operations helpers */ | 175 | /* Fixed point operations helpers */ |
113 | #if defined(TARGET_PPC64) | 176 | #if defined(TARGET_PPC64) |
114 | 177 |
target-ppc/op_helper.h
@@ -23,10 +23,6 @@ | @@ -23,10 +23,6 @@ | ||
23 | /* Memory load/store helpers */ | 23 | /* Memory load/store helpers */ |
24 | void glue(do_lsw, MEMSUFFIX) (int dst); | 24 | void glue(do_lsw, MEMSUFFIX) (int dst); |
25 | void glue(do_stsw, MEMSUFFIX) (int src); | 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 | void glue(do_icbi, MEMSUFFIX) (void); | 26 | void glue(do_icbi, MEMSUFFIX) (void); |
31 | void glue(do_dcbz, MEMSUFFIX) (void); | 27 | void glue(do_dcbz, MEMSUFFIX) (void); |
32 | void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); | 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,10 +34,6 @@ void glue(do_POWER2_stfq_le, MEMSUFFIX) (void); | ||
38 | #if defined(TARGET_PPC64) | 34 | #if defined(TARGET_PPC64) |
39 | void glue(do_lsw_64, MEMSUFFIX) (int dst); | 35 | void glue(do_lsw_64, MEMSUFFIX) (int dst); |
40 | void glue(do_stsw_64, MEMSUFFIX) (int src); | 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 | void glue(do_icbi_64, MEMSUFFIX) (void); | 37 | void glue(do_icbi_64, MEMSUFFIX) (void); |
46 | void glue(do_dcbz_64, MEMSUFFIX) (void); | 38 | void glue(do_dcbz_64, MEMSUFFIX) (void); |
47 | #endif | 39 | #endif |
target-ppc/op_helper_mem.h
@@ -20,71 +20,6 @@ | @@ -20,71 +20,6 @@ | ||
20 | 20 | ||
21 | #include "op_mem_access.h" | 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 | void glue(do_lsw, MEMSUFFIX) (int dst) | 23 | void glue(do_lsw, MEMSUFFIX) (int dst) |
89 | { | 24 | { |
90 | uint32_t tmp; | 25 | uint32_t tmp; |
target-ppc/op_mem.h
@@ -20,63 +20,6 @@ | @@ -20,63 +20,6 @@ | ||
20 | 20 | ||
21 | #include "op_mem_access.h" | 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 | /*** Integer load and store strings ***/ | 23 | /*** Integer load and store strings ***/ |
81 | void OPPROTO glue(op_lswi, MEMSUFFIX) (void) | 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,30 +3092,30 @@ void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags) | ||
3092 | GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER); | 3092 | GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER); |
3093 | 3093 | ||
3094 | /*** Integer load and store multiple ***/ | 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 | /* lmw */ | 3095 | /* lmw */ |
3104 | GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | 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 | /* NIP cannot be restored if the memory exception comes from an helper */ | 3100 | /* NIP cannot be restored if the memory exception comes from an helper */ |
3107 | gen_update_nip(ctx, ctx->nip - 4); | 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 | /* stmw */ | 3108 | /* stmw */ |
3113 | GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | 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 | /* NIP cannot be restored if the memory exception comes from an helper */ | 3113 | /* NIP cannot be restored if the memory exception comes from an helper */ |
3116 | gen_update_nip(ctx, ctx->nip - 4); | 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 | /*** Integer load and store strings ***/ | 3121 | /*** Integer load and store strings ***/ |