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