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,6 +15,8 @@ DEF_HELPER_3(stsw, void, tl, i32, i32) | ||
15 | DEF_HELPER_1(dcbz, void, tl) | 15 | DEF_HELPER_1(dcbz, void, tl) |
16 | DEF_HELPER_1(dcbz_970, void, tl) | 16 | DEF_HELPER_1(dcbz_970, void, tl) |
17 | DEF_HELPER_1(icbi, void, tl) | 17 | DEF_HELPER_1(icbi, void, tl) |
18 | +DEF_HELPER_4(lscbx, tl, tl, i32, i32, i32) | ||
19 | + | ||
18 | 20 | ||
19 | DEF_HELPER_2(fcmpo, i32, i64, i64) | 21 | DEF_HELPER_2(fcmpo, i32, i64, i64) |
20 | DEF_HELPER_2(fcmpu, i32, i64, i64) | 22 | DEF_HELPER_2(fcmpu, i32, i64, i64) |
target-ppc/op_helper.c
@@ -24,21 +24,6 @@ | @@ -24,21 +24,6 @@ | ||
24 | #include "helper_regs.h" | 24 | #include "helper_regs.h" |
25 | #include "op_helper.h" | 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 | //#define DEBUG_OP | 27 | //#define DEBUG_OP |
43 | //#define DEBUG_EXCEPTIONS | 28 | //#define DEBUG_EXCEPTIONS |
44 | //#define DEBUG_SOFTWARE_TLB | 29 | //#define DEBUG_SOFTWARE_TLB |
@@ -329,6 +314,45 @@ void helper_icbi(target_ulong addr) | @@ -329,6 +314,45 @@ void helper_icbi(target_ulong addr) | ||
329 | tb_invalidate_page_range(addr, addr + env->icache_line_size); | 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 | /* Fixed point operations helpers */ | 357 | /* Fixed point operations helpers */ |
334 | #if defined(TARGET_PPC64) | 358 | #if defined(TARGET_PPC64) |
target-ppc/op_helper.h
@@ -18,17 +18,6 @@ | @@ -18,17 +18,6 @@ | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 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 | void do_print_mem_EA (target_ulong EA); | 21 | void do_print_mem_EA (target_ulong EA); |
33 | 22 | ||
34 | /* Registers load and stores */ | 23 | /* Registers load and stores */ |
@@ -94,5 +83,3 @@ void do_440_dlmzb (void); | @@ -94,5 +83,3 @@ void do_440_dlmzb (void); | ||
94 | void do_load_403_pb (int num); | 83 | void do_load_403_pb (int num); |
95 | void do_store_403_pb (int num); | 84 | void do_store_403_pb (int num); |
96 | #endif | 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,15 +303,4 @@ void OPPROTO glue(op_ecowx_le_64, MEMSUFFIX) (void) | ||
303 | } | 303 | } |
304 | #endif | 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 | #undef MEMSUFFIX | 306 | #undef MEMSUFFIX |
target-ppc/translate.c
@@ -4526,47 +4526,26 @@ GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR) | @@ -4526,47 +4526,26 @@ GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR) | ||
4526 | tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | 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 | /* lscbx - lscbx. */ | 4529 | /* lscbx - lscbx. */ |
4551 | GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR) | 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 | /* NIP cannot be restored if the memory exception comes from an helper */ | 4538 | /* NIP cannot be restored if the memory exception comes from an helper */ |
4561 | gen_update_nip(ctx, ctx->nip - 4); | 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 | tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F); | 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 | if (unlikely(Rc(ctx->opcode) != 0)) | 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 | /* maskg - maskg. */ | 4551 | /* maskg - maskg. */ |