Commit bdb4b68907a88090148c5ab9aea17b67f9ef2542
1 parent
dfbc799d
target-ppc: convert lscbx instruction to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5829 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
53 additions
and
122 deletions
target-ppc/helper.h
... | ... | @@ -15,6 +15,8 @@ DEF_HELPER_3(stsw, void, tl, i32, i32) |
15 | 15 | DEF_HELPER_1(dcbz, void, tl) |
16 | 16 | DEF_HELPER_1(dcbz_970, void, tl) |
17 | 17 | DEF_HELPER_1(icbi, void, tl) |
18 | +DEF_HELPER_4(lscbx, tl, tl, i32, i32, i32) | |
19 | + | |
18 | 20 | |
19 | 21 | DEF_HELPER_2(fcmpo, i32, i64, i64) |
20 | 22 | DEF_HELPER_2(fcmpu, i32, i64, i64) | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -24,21 +24,6 @@ |
24 | 24 | #include "helper_regs.h" |
25 | 25 | #include "op_helper.h" |
26 | 26 | |
27 | -#define MEMSUFFIX _raw | |
28 | -#include "op_helper.h" | |
29 | -#include "op_helper_mem.h" | |
30 | -#if !defined(CONFIG_USER_ONLY) | |
31 | -#define MEMSUFFIX _user | |
32 | -#include "op_helper.h" | |
33 | -#include "op_helper_mem.h" | |
34 | -#define MEMSUFFIX _kernel | |
35 | -#include "op_helper.h" | |
36 | -#include "op_helper_mem.h" | |
37 | -#define MEMSUFFIX _hypv | |
38 | -#include "op_helper.h" | |
39 | -#include "op_helper_mem.h" | |
40 | -#endif | |
41 | - | |
42 | 27 | //#define DEBUG_OP |
43 | 28 | //#define DEBUG_EXCEPTIONS |
44 | 29 | //#define DEBUG_SOFTWARE_TLB |
... | ... | @@ -329,6 +314,45 @@ void helper_icbi(target_ulong addr) |
329 | 314 | tb_invalidate_page_range(addr, addr + env->icache_line_size); |
330 | 315 | } |
331 | 316 | |
317 | +// XXX: to be tested | |
318 | +target_ulong helper_lscbx (target_ulong addr, uint32_t reg, uint32_t ra, uint32_t rb) | |
319 | +{ | |
320 | + int i, c, d; | |
321 | +#ifdef CONFIG_USER_ONLY | |
322 | +#define ldfun ldub_raw | |
323 | +#else | |
324 | + int (*ldfun)(target_ulong); | |
325 | + | |
326 | + switch (env->mmu_idx) { | |
327 | + default: | |
328 | + case 0: ldfun = ldub_user; | |
329 | + break; | |
330 | + case 1: ldfun = ldub_kernel; | |
331 | + break; | |
332 | + case 2: ldfun = ldub_hypv; | |
333 | + break; | |
334 | + } | |
335 | +#endif | |
336 | + d = 24; | |
337 | + for (i = 0; i < xer_bc; i++) { | |
338 | + c = ldfun((uint32_t)addr++); | |
339 | + /* ra (if not 0) and rb are never modified */ | |
340 | + if (likely(reg != rb && (ra == 0 || reg != ra))) { | |
341 | + env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d); | |
342 | + } | |
343 | + if (unlikely(c == xer_cmp)) | |
344 | + break; | |
345 | + if (likely(d != 0)) { | |
346 | + d -= 8; | |
347 | + } else { | |
348 | + d = 24; | |
349 | + reg++; | |
350 | + reg = reg & 0x1F; | |
351 | + } | |
352 | + } | |
353 | + return i; | |
354 | +} | |
355 | + | |
332 | 356 | /*****************************************************************************/ |
333 | 357 | /* Fixed point operations helpers */ |
334 | 358 | #if defined(TARGET_PPC64) | ... | ... |
target-ppc/op_helper.h
... | ... | @@ -18,17 +18,6 @@ |
18 | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | 19 | */ |
20 | 20 | |
21 | -#if defined(MEMSUFFIX) | |
22 | - | |
23 | -/* Memory load/store helpers */ | |
24 | -void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); | |
25 | -void glue(do_POWER2_lfq, MEMSUFFIX) (void); | |
26 | -void glue(do_POWER2_lfq_le, MEMSUFFIX) (void); | |
27 | -void glue(do_POWER2_stfq, MEMSUFFIX) (void); | |
28 | -void glue(do_POWER2_stfq_le, MEMSUFFIX) (void); | |
29 | - | |
30 | -#else | |
31 | - | |
32 | 21 | void do_print_mem_EA (target_ulong EA); |
33 | 22 | |
34 | 23 | /* Registers load and stores */ |
... | ... | @@ -94,5 +83,3 @@ void do_440_dlmzb (void); |
94 | 83 | void do_load_403_pb (int num); |
95 | 84 | void do_store_403_pb (int num); |
96 | 85 | #endif |
97 | - | |
98 | -#endif | ... | ... |
target-ppc/op_helper_mem.h deleted
100644 โ 0
1 | -/* | |
2 | - * PowerPC emulation micro-operations helpers for qemu. | |
3 | - * | |
4 | - * Copyright (c) 2003-2007 Jocelyn Mayer | |
5 | - * | |
6 | - * This library is free software; you can redistribute it and/or | |
7 | - * modify it under the terms of the GNU Lesser General Public | |
8 | - * License as published by the Free Software Foundation; either | |
9 | - * version 2 of the License, or (at your option) any later version. | |
10 | - * | |
11 | - * This library is distributed in the hope that it will be useful, | |
12 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | - * Lesser General Public License for more details. | |
15 | - * | |
16 | - * You should have received a copy of the GNU Lesser General Public | |
17 | - * License along with this library; if not, write to the Free Software | |
18 | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | - */ | |
20 | - | |
21 | -#include "op_mem_access.h" | |
22 | - | |
23 | -/* PowerPC 601 specific instructions (POWER bridge) */ | |
24 | -// XXX: to be tested | |
25 | -void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) | |
26 | -{ | |
27 | - int i, c, d, reg; | |
28 | - | |
29 | - d = 24; | |
30 | - reg = dest; | |
31 | - for (i = 0; i < T1; i++) { | |
32 | - c = glue(ldu8, MEMSUFFIX)((uint32_t)T0++); | |
33 | - /* ra (if not 0) and rb are never modified */ | |
34 | - if (likely(reg != rb && (ra == 0 || reg != ra))) { | |
35 | - env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d); | |
36 | - } | |
37 | - if (unlikely(c == T2)) | |
38 | - break; | |
39 | - if (likely(d != 0)) { | |
40 | - d -= 8; | |
41 | - } else { | |
42 | - d = 24; | |
43 | - reg++; | |
44 | - reg = reg & 0x1F; | |
45 | - } | |
46 | - } | |
47 | - T0 = i; | |
48 | -} | |
49 | - | |
50 | -#undef MEMSUFFIX |
target-ppc/op_mem.h
... | ... | @@ -303,15 +303,4 @@ void OPPROTO glue(op_ecowx_le_64, MEMSUFFIX) (void) |
303 | 303 | } |
304 | 304 | #endif |
305 | 305 | |
306 | -/* XXX: those micro-ops need tests ! */ | |
307 | -/* PowerPC 601 specific instructions (POWER bridge) */ | |
308 | -void OPPROTO glue(op_POWER_lscbx, MEMSUFFIX) (void) | |
309 | -{ | |
310 | - /* When byte count is 0, do nothing */ | |
311 | - if (likely(T1 != 0)) { | |
312 | - glue(do_POWER_lscbx, MEMSUFFIX)(PARAM1, PARAM2, PARAM3); | |
313 | - } | |
314 | - RETURN(); | |
315 | -} | |
316 | - | |
317 | 306 | #undef MEMSUFFIX | ... | ... |
target-ppc/translate.c
... | ... | @@ -4526,47 +4526,26 @@ GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR) |
4526 | 4526 | tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); |
4527 | 4527 | } |
4528 | 4528 | |
4529 | -/* As lscbx load from memory byte after byte, it's always endian safe. | |
4530 | - * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones | |
4531 | - */ | |
4532 | -#define op_POWER_lscbx(start, ra, rb) \ | |
4533 | -(*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb) | |
4534 | -#define gen_op_POWER_lscbx_64_raw gen_op_POWER_lscbx_raw | |
4535 | -#define gen_op_POWER_lscbx_64_user gen_op_POWER_lscbx_user | |
4536 | -#define gen_op_POWER_lscbx_64_kernel gen_op_POWER_lscbx_kernel | |
4537 | -#define gen_op_POWER_lscbx_64_hypv gen_op_POWER_lscbx_hypv | |
4538 | -#define gen_op_POWER_lscbx_le_raw gen_op_POWER_lscbx_raw | |
4539 | -#define gen_op_POWER_lscbx_le_user gen_op_POWER_lscbx_user | |
4540 | -#define gen_op_POWER_lscbx_le_kernel gen_op_POWER_lscbx_kernel | |
4541 | -#define gen_op_POWER_lscbx_le_hypv gen_op_POWER_lscbx_hypv | |
4542 | -#define gen_op_POWER_lscbx_le_64_raw gen_op_POWER_lscbx_raw | |
4543 | -#define gen_op_POWER_lscbx_le_64_user gen_op_POWER_lscbx_user | |
4544 | -#define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel | |
4545 | -#define gen_op_POWER_lscbx_le_64_hypv gen_op_POWER_lscbx_hypv | |
4546 | -static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = { | |
4547 | - GEN_MEM_FUNCS(POWER_lscbx), | |
4548 | -}; | |
4549 | - | |
4550 | 4529 | /* lscbx - lscbx. */ |
4551 | 4530 | GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR) |
4552 | 4531 | { |
4553 | - int ra = rA(ctx->opcode); | |
4554 | - int rb = rB(ctx->opcode); | |
4532 | + TCGv t0 = tcg_temp_new(); | |
4533 | + TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode)); | |
4534 | + TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode)); | |
4535 | + TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode)); | |
4555 | 4536 | |
4556 | - gen_addr_reg_index(cpu_T[0], ctx); | |
4557 | - if (ra == 0) { | |
4558 | - ra = rb; | |
4559 | - } | |
4537 | + gen_addr_reg_index(t0, ctx); | |
4560 | 4538 | /* NIP cannot be restored if the memory exception comes from an helper */ |
4561 | 4539 | gen_update_nip(ctx, ctx->nip - 4); |
4562 | - tcg_gen_andi_tl(cpu_T[1], cpu_xer, 0x7F); | |
4563 | - tcg_gen_shri_tl(cpu_T[2], cpu_xer, XER_CMP); | |
4564 | - tcg_gen_andi_tl(cpu_T[2], cpu_T[2], 0xFF); | |
4565 | - op_POWER_lscbx(rD(ctx->opcode), ra, rb); | |
4540 | + gen_helper_lscbx(t0, t0, t1, t2, t3); | |
4541 | + tcg_temp_free_i32(t1); | |
4542 | + tcg_temp_free_i32(t2); | |
4543 | + tcg_temp_free_i32(t3); | |
4566 | 4544 | tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F); |
4567 | - tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]); | |
4545 | + tcg_gen_or_tl(cpu_xer, cpu_xer, t0); | |
4568 | 4546 | if (unlikely(Rc(ctx->opcode) != 0)) |
4569 | - gen_set_Rc0(ctx, cpu_T[0]); | |
4547 | + gen_set_Rc0(ctx, t0); | |
4548 | + tcg_temp_free(t0); | |
4570 | 4549 | } |
4571 | 4550 | |
4572 | 4551 | /* maskg - maskg. */ | ... | ... |