Commit 4e9f853731f060236d9036663c12ca0594395d0d
1 parent
0e21e12b
Fix [ls][wd][lr] instructions, by Aurelien Jarno.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3372 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
207 additions
and
68 deletions
Makefile.target
... | ... | @@ -658,7 +658,7 @@ endif |
658 | 658 | ifeq ($(TARGET_BASE_ARCH), mips) |
659 | 659 | helper.o: cpu.h exec-all.h |
660 | 660 | op.o: op_template.c fop_template.c op_mem.c exec.h cpu.h |
661 | -op_helper.o: op_helper_mem.c exec.h softmmu_template.h cpu.h | |
661 | +op_helper.o: exec.h softmmu_template.h cpu.h | |
662 | 662 | translate.o: translate_init.c exec-all.h disas.h |
663 | 663 | endif |
664 | 664 | ... | ... |
target-mips/exec.h
... | ... | @@ -100,36 +100,6 @@ void fpu_dump_state(CPUState *env, FILE *f, |
100 | 100 | int (*fpu_fprintf)(FILE *f, const char *fmt, ...), |
101 | 101 | int flags); |
102 | 102 | void dump_sc (void); |
103 | -void do_lwl_raw (uint32_t); | |
104 | -void do_lwr_raw (uint32_t); | |
105 | -uint32_t do_swl_raw (uint32_t); | |
106 | -uint32_t do_swr_raw (uint32_t); | |
107 | -#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) | |
108 | -void do_ldl_raw (uint64_t); | |
109 | -void do_ldr_raw (uint64_t); | |
110 | -uint64_t do_sdl_raw (uint64_t); | |
111 | -uint64_t do_sdr_raw (uint64_t); | |
112 | -#endif | |
113 | -#if !defined(CONFIG_USER_ONLY) | |
114 | -void do_lwl_user (uint32_t); | |
115 | -void do_lwl_kernel (uint32_t); | |
116 | -void do_lwr_user (uint32_t); | |
117 | -void do_lwr_kernel (uint32_t); | |
118 | -uint32_t do_swl_user (uint32_t); | |
119 | -uint32_t do_swl_kernel (uint32_t); | |
120 | -uint32_t do_swr_user (uint32_t); | |
121 | -uint32_t do_swr_kernel (uint32_t); | |
122 | -#if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) | |
123 | -void do_ldl_user (uint64_t); | |
124 | -void do_ldl_kernel (uint64_t); | |
125 | -void do_ldr_user (uint64_t); | |
126 | -void do_ldr_kernel (uint64_t); | |
127 | -uint64_t do_sdl_user (uint64_t); | |
128 | -uint64_t do_sdl_kernel (uint64_t); | |
129 | -uint64_t do_sdr_user (uint64_t); | |
130 | -uint64_t do_sdr_kernel (uint64_t); | |
131 | -#endif | |
132 | -#endif | |
133 | 103 | void do_pmon (int function); |
134 | 104 | |
135 | 105 | void dump_sc (void); | ... | ... |
target-mips/op_helper.c
... | ... | @@ -62,18 +62,6 @@ void do_raise_exception_direct (uint32_t exception) |
62 | 62 | do_raise_exception_direct_err (exception, 0); |
63 | 63 | } |
64 | 64 | |
65 | -#define MEMSUFFIX _raw | |
66 | -#include "op_helper_mem.c" | |
67 | -#undef MEMSUFFIX | |
68 | -#if !defined(CONFIG_USER_ONLY) | |
69 | -#define MEMSUFFIX _user | |
70 | -#include "op_helper_mem.c" | |
71 | -#undef MEMSUFFIX | |
72 | -#define MEMSUFFIX _kernel | |
73 | -#include "op_helper_mem.c" | |
74 | -#undef MEMSUFFIX | |
75 | -#endif | |
76 | - | |
77 | 65 | #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) |
78 | 66 | #if TARGET_LONG_BITS > HOST_LONG_BITS |
79 | 67 | /* Those might call libgcc functions. */ | ... | ... |
target-mips/op_mem.c
... | ... | @@ -75,34 +75,92 @@ void glue(op_sw, MEMSUFFIX) (void) |
75 | 75 | |
76 | 76 | /* "half" load and stores. We must do the memory access inline, |
77 | 77 | or fault handling won't work. */ |
78 | -/* XXX: This is broken, CP0_BADVADDR has the wrong (aligned) value. */ | |
78 | + | |
79 | +#ifdef TARGET_WORDS_BIGENDIAN | |
80 | +#define GET_LMASK(v) ((v) & 3) | |
81 | +#define GET_OFFSET(addr, offset) (addr + (offset)) | |
82 | +#else | |
83 | +#define GET_LMASK(v) (((v) & 3) ^ 3) | |
84 | +#define GET_OFFSET(addr, offset) (addr - (offset)) | |
85 | +#endif | |
86 | + | |
79 | 87 | void glue(op_lwl, MEMSUFFIX) (void) |
80 | 88 | { |
81 | - uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3); | |
82 | - CALL_FROM_TB1(glue(do_lwl, MEMSUFFIX), tmp); | |
89 | + target_ulong tmp; | |
90 | + | |
91 | + tmp = glue(ldub, MEMSUFFIX)(T0); | |
92 | + T1 = (int32_t)((T1 & 0x00FFFFFF) | (tmp << 24)); | |
93 | + | |
94 | + if (GET_LMASK(T0) <= 2) { | |
95 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1)); | |
96 | + T1 = (T1 & 0xFF00FFFF) | (tmp << 16); | |
97 | + } | |
98 | + | |
99 | + if (GET_LMASK(T0) <= 1) { | |
100 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2)); | |
101 | + T1 = (T1 & 0xFFFF00FF) | (tmp << 8); | |
102 | + } | |
103 | + | |
104 | + if (GET_LMASK(T0) == 0) { | |
105 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3)); | |
106 | + T1 = (T1 & 0xFFFFFF00) | tmp; | |
107 | + } | |
83 | 108 | RETURN(); |
84 | 109 | } |
85 | 110 | |
86 | 111 | void glue(op_lwr, MEMSUFFIX) (void) |
87 | 112 | { |
88 | - uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3); | |
89 | - CALL_FROM_TB1(glue(do_lwr, MEMSUFFIX), tmp); | |
113 | + target_ulong tmp; | |
114 | + | |
115 | + tmp = glue(ldub, MEMSUFFIX)(T0); | |
116 | + T1 = (T1 & 0xFFFFFF00) | tmp; | |
117 | + | |
118 | + if (GET_LMASK(T0) >= 1) { | |
119 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1)); | |
120 | + T1 = (T1 & 0xFFFF00FF) | (tmp << 8); | |
121 | + } | |
122 | + | |
123 | + if (GET_LMASK(T0) >= 2) { | |
124 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2)); | |
125 | + T1 = (T1 & 0xFF00FFFF) | (tmp << 16); | |
126 | + } | |
127 | + | |
128 | + if (GET_LMASK(T0) == 3) { | |
129 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3)); | |
130 | + T1 = (T1 & 0x00FFFFFF) | (tmp << 24); | |
131 | + } | |
90 | 132 | RETURN(); |
91 | 133 | } |
92 | 134 | |
93 | 135 | void glue(op_swl, MEMSUFFIX) (void) |
94 | 136 | { |
95 | - uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3); | |
96 | - tmp = CALL_FROM_TB1(glue(do_swl, MEMSUFFIX), tmp); | |
97 | - glue(stl, MEMSUFFIX)(T0 & ~3, tmp); | |
137 | + glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 24)); | |
138 | + | |
139 | + if (GET_LMASK(T0) <= 2) | |
140 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16)); | |
141 | + | |
142 | + if (GET_LMASK(T0) <= 1) | |
143 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8)); | |
144 | + | |
145 | + if (GET_LMASK(T0) == 0) | |
146 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)T1); | |
147 | + | |
98 | 148 | RETURN(); |
99 | 149 | } |
100 | 150 | |
101 | 151 | void glue(op_swr, MEMSUFFIX) (void) |
102 | 152 | { |
103 | - uint32_t tmp = glue(ldl, MEMSUFFIX)(T0 & ~3); | |
104 | - tmp = CALL_FROM_TB1(glue(do_swr, MEMSUFFIX), tmp); | |
105 | - glue(stl, MEMSUFFIX)(T0 & ~3, tmp); | |
153 | + glue(stb, MEMSUFFIX)(T0, (uint8_t)T1); | |
154 | + | |
155 | + if (GET_LMASK(T0) >= 1) | |
156 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); | |
157 | + | |
158 | + if (GET_LMASK(T0) >= 2) | |
159 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); | |
160 | + | |
161 | + if (GET_LMASK(T0) == 3) | |
162 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); | |
163 | + | |
106 | 164 | RETURN(); |
107 | 165 | } |
108 | 166 | |
... | ... | @@ -145,33 +203,156 @@ void glue(op_sd, MEMSUFFIX) (void) |
145 | 203 | |
146 | 204 | /* "half" load and stores. We must do the memory access inline, |
147 | 205 | or fault handling won't work. */ |
206 | + | |
207 | +#ifdef TARGET_WORDS_BIGENDIAN | |
208 | +#define GET_LMASK64(v) ((v) & 7) | |
209 | +#else | |
210 | +#define GET_LMASK64(v) (((v) & 7) ^ 7) | |
211 | +#endif | |
212 | + | |
148 | 213 | void glue(op_ldl, MEMSUFFIX) (void) |
149 | 214 | { |
150 | - target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7); | |
151 | - CALL_FROM_TB1(glue(do_ldl, MEMSUFFIX), tmp); | |
215 | + uint64_t tmp; | |
216 | + | |
217 | + tmp = glue(ldub, MEMSUFFIX)(T0); | |
218 | + T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); | |
219 | + | |
220 | + if (GET_LMASK64(T0) <= 6) { | |
221 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1)); | |
222 | + T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); | |
223 | + } | |
224 | + | |
225 | + if (GET_LMASK64(T0) <= 5) { | |
226 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2)); | |
227 | + T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); | |
228 | + } | |
229 | + | |
230 | + if (GET_LMASK64(T0) <= 4) { | |
231 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3)); | |
232 | + T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); | |
233 | + } | |
234 | + | |
235 | + if (GET_LMASK64(T0) <= 3) { | |
236 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 4)); | |
237 | + T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); | |
238 | + } | |
239 | + | |
240 | + if (GET_LMASK64(T0) <= 2) { | |
241 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 5)); | |
242 | + T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); | |
243 | + } | |
244 | + | |
245 | + if (GET_LMASK64(T0) <= 1) { | |
246 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 6)); | |
247 | + T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); | |
248 | + } | |
249 | + | |
250 | + if (GET_LMASK64(T0) == 0) { | |
251 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 7)); | |
252 | + T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; | |
253 | + } | |
254 | + | |
152 | 255 | RETURN(); |
153 | 256 | } |
154 | 257 | |
155 | 258 | void glue(op_ldr, MEMSUFFIX) (void) |
156 | 259 | { |
157 | - target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7); | |
158 | - CALL_FROM_TB1(glue(do_ldr, MEMSUFFIX), tmp); | |
260 | + uint64_t tmp; | |
261 | + | |
262 | + tmp = glue(ldub, MEMSUFFIX)(T0); | |
263 | + T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; | |
264 | + | |
265 | + if (GET_LMASK64(T0) >= 1) { | |
266 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1)); | |
267 | + T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); | |
268 | + } | |
269 | + | |
270 | + if (GET_LMASK64(T0) >= 2) { | |
271 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2)); | |
272 | + T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); | |
273 | + } | |
274 | + | |
275 | + if (GET_LMASK64(T0) >= 3) { | |
276 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3)); | |
277 | + T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); | |
278 | + } | |
279 | + | |
280 | + if (GET_LMASK64(T0) >= 4) { | |
281 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -4)); | |
282 | + T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); | |
283 | + } | |
284 | + | |
285 | + if (GET_LMASK64(T0) >= 5) { | |
286 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -5)); | |
287 | + T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); | |
288 | + } | |
289 | + | |
290 | + if (GET_LMASK64(T0) >= 6) { | |
291 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -6)); | |
292 | + T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); | |
293 | + } | |
294 | + | |
295 | + if (GET_LMASK64(T0) == 7) { | |
296 | + tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -7)); | |
297 | + T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); | |
298 | + } | |
299 | + | |
159 | 300 | RETURN(); |
160 | 301 | } |
161 | 302 | |
162 | 303 | void glue(op_sdl, MEMSUFFIX) (void) |
163 | 304 | { |
164 | - target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7); | |
165 | - tmp = CALL_FROM_TB1(glue(do_sdl, MEMSUFFIX), tmp); | |
166 | - glue(stq, MEMSUFFIX)(T0 & ~7, tmp); | |
305 | + glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 56)); | |
306 | + | |
307 | + if (GET_LMASK64(T0) <= 6) | |
308 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48)); | |
309 | + | |
310 | + if (GET_LMASK64(T0) <= 5) | |
311 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40)); | |
312 | + | |
313 | + if (GET_LMASK64(T0) <= 4) | |
314 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32)); | |
315 | + | |
316 | + if (GET_LMASK64(T0) <= 3) | |
317 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24)); | |
318 | + | |
319 | + if (GET_LMASK64(T0) <= 2) | |
320 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16)); | |
321 | + | |
322 | + if (GET_LMASK64(T0) <= 1) | |
323 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8)); | |
324 | + | |
325 | + if (GET_LMASK64(T0) <= 0) | |
326 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 7), (uint8_t)T1); | |
327 | + | |
167 | 328 | RETURN(); |
168 | 329 | } |
169 | 330 | |
170 | 331 | void glue(op_sdr, MEMSUFFIX) (void) |
171 | 332 | { |
172 | - target_long tmp = glue(ldq, MEMSUFFIX)(T0 & ~7); | |
173 | - tmp = CALL_FROM_TB1(glue(do_sdr, MEMSUFFIX), tmp); | |
174 | - glue(stq, MEMSUFFIX)(T0 & ~7, tmp); | |
333 | + glue(stb, MEMSUFFIX)(T0, (uint8_t)T1); | |
334 | + | |
335 | + if (GET_LMASK64(T0) >= 1) | |
336 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); | |
337 | + | |
338 | + if (GET_LMASK64(T0) >= 2) | |
339 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); | |
340 | + | |
341 | + if (GET_LMASK64(T0) >= 3) | |
342 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); | |
343 | + | |
344 | + if (GET_LMASK64(T0) >= 4) | |
345 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32)); | |
346 | + | |
347 | + if (GET_LMASK64(T0) >= 5) | |
348 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40)); | |
349 | + | |
350 | + if (GET_LMASK64(T0) >= 6) | |
351 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48)); | |
352 | + | |
353 | + if (GET_LMASK64(T0) == 7) | |
354 | + glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56)); | |
355 | + | |
175 | 356 | RETURN(); |
176 | 357 | } |
177 | 358 | ... | ... |
target-mips/translate.c
... | ... | @@ -889,7 +889,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
889 | 889 | case OPC_LDL: |
890 | 890 | GEN_LOAD_REG_TN(T1, rt); |
891 | 891 | op_ldst(ldl); |
892 | - GEN_STORE_TN_REG(rt, T0); | |
892 | + GEN_STORE_TN_REG(rt, T1); | |
893 | 893 | opn = "ldl"; |
894 | 894 | break; |
895 | 895 | case OPC_SDL: |
... | ... | @@ -900,7 +900,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
900 | 900 | case OPC_LDR: |
901 | 901 | GEN_LOAD_REG_TN(T1, rt); |
902 | 902 | op_ldst(ldr); |
903 | - GEN_STORE_TN_REG(rt, T0); | |
903 | + GEN_STORE_TN_REG(rt, T1); | |
904 | 904 | opn = "ldr"; |
905 | 905 | break; |
906 | 906 | case OPC_SDR: |
... | ... | @@ -952,7 +952,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
952 | 952 | case OPC_LWL: |
953 | 953 | GEN_LOAD_REG_TN(T1, rt); |
954 | 954 | op_ldst(lwl); |
955 | - GEN_STORE_TN_REG(rt, T0); | |
955 | + GEN_STORE_TN_REG(rt, T1); | |
956 | 956 | opn = "lwl"; |
957 | 957 | break; |
958 | 958 | case OPC_SWL: |
... | ... | @@ -963,7 +963,7 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, |
963 | 963 | case OPC_LWR: |
964 | 964 | GEN_LOAD_REG_TN(T1, rt); |
965 | 965 | op_ldst(lwr); |
966 | - GEN_STORE_TN_REG(rt, T0); | |
966 | + GEN_STORE_TN_REG(rt, T1); | |
967 | 967 | opn = "lwr"; |
968 | 968 | break; |
969 | 969 | case OPC_SWR: | ... | ... |