Loading target-ppc/helper.h +3 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,9 @@ DEF_HELPER_3(td, void, tl, tl, i32) DEF_HELPER_2(lmw, void, tl, i32) DEF_HELPER_2(stmw, void, tl, i32) DEF_HELPER_3(lsw, void, tl, i32, i32) DEF_HELPER_4(lswx, void, tl, i32, i32, i32) DEF_HELPER_3(stsw, void, tl, i32, i32) DEF_HELPER_1(dcbz, void, tl) DEF_HELPER_1(dcbz_970, void, tl) DEF_HELPER_1(icbi, void, tl) Loading target-ppc/op_helper.c +93 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,99 @@ void helper_stmw (target_ulong addr, uint32_t reg) } } void helper_lsw(target_ulong addr, uint32_t nb, uint32_t reg) { int sh; #ifdef CONFIG_USER_ONLY #define ldfunl ldl_raw #define ldfunb ldub_raw #else int (*ldfunl)(target_ulong); int (*ldfunb)(target_ulong); switch (env->mmu_idx) { default: case 0: ldfunl = ldl_user; ldfunb = ldub_user; break; case 1: ldfunl = ldl_kernel; ldfunb = ldub_kernel; break; case 2: ldfunl = ldl_hypv; ldfunb = ldub_hypv; break; } #endif for (; nb > 3; nb -= 4, addr += 4) { env->gpr[reg] = ldfunl(get_addr(addr)); reg = (reg + 1) % 32; } if (unlikely(nb > 0)) { env->gpr[reg] = 0; for (sh = 24; nb > 0; nb--, addr++, sh -= 8) { env->gpr[reg] |= ldfunb(get_addr(addr)) << sh; } } } /* PPC32 specification says we must generate an exception if * rA is in the range of registers to be loaded. * In an other hand, IBM says this is valid, but rA won't be loaded. * For now, I'll follow the spec... */ void helper_lswx(target_ulong addr, uint32_t reg, uint32_t ra, uint32_t rb) { if (likely(xer_bc != 0)) { if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) || (reg < rb && (reg + xer_bc) > rb))) { raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX); } else { helper_lsw(addr, xer_bc, reg); } } } void helper_stsw(target_ulong addr, uint32_t nb, uint32_t reg) { int sh; #ifdef CONFIG_USER_ONLY #define stfunl stl_raw #define stfunb stb_raw #else void (*stfunl)(target_ulong, int); void (*stfunb)(target_ulong, int); switch (env->mmu_idx) { default: case 0: stfunl = stl_user; stfunb = stb_user; break; case 1: stfunl = stl_kernel; stfunb = stb_kernel; break; case 2: stfunl = stl_hypv; stfunb = stb_hypv; break; } #endif for (; nb > 3; nb -= 4, addr += 4) { stfunl(get_addr(addr), env->gpr[reg]); reg = (reg + 1) % 32; } if (unlikely(nb > 0)) { for (sh = 24; nb > 0; nb--, addr++, sh -= 8) stfunb(get_addr(addr), (env->gpr[reg] >> sh) & 0xFF); } } static void do_dcbz(target_ulong addr, int dcache_line_size) { target_long mask = get_addr(~(dcache_line_size - 1)); Loading target-ppc/op_helper.h +0 −7 Original line number Diff line number Diff line Loading @@ -21,19 +21,12 @@ #if defined(MEMSUFFIX) /* Memory load/store helpers */ void glue(do_lsw, MEMSUFFIX) (int dst); void glue(do_stsw, MEMSUFFIX) (int src); void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); void glue(do_POWER2_lfq, MEMSUFFIX) (void); void glue(do_POWER2_lfq_le, MEMSUFFIX) (void); void glue(do_POWER2_stfq, MEMSUFFIX) (void); void glue(do_POWER2_stfq_le, MEMSUFFIX) (void); #if defined(TARGET_PPC64) void glue(do_lsw_64, MEMSUFFIX) (int dst); void glue(do_stsw_64, MEMSUFFIX) (int src); #endif #else void do_print_mem_EA (target_ulong EA); Loading target-ppc/op_helper_mem.h +0 −72 Original line number Diff line number Diff line Loading @@ -20,78 +20,6 @@ #include "op_mem_access.h" void glue(do_lsw, MEMSUFFIX) (int dst) { uint32_t tmp; int sh; for (; T1 > 3; T1 -= 4, T0 += 4) { env->gpr[dst++] = glue(ldu32, MEMSUFFIX)((uint32_t)T0); if (unlikely(dst == 32)) dst = 0; } if (unlikely(T1 != 0)) { tmp = 0; for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { tmp |= glue(ldu8, MEMSUFFIX)((uint32_t)T0) << sh; } env->gpr[dst] = tmp; } } #if defined(TARGET_PPC64) void glue(do_lsw_64, MEMSUFFIX) (int dst) { uint32_t tmp; int sh; for (; T1 > 3; T1 -= 4, T0 += 4) { env->gpr[dst++] = glue(ldu32, MEMSUFFIX)((uint64_t)T0); if (unlikely(dst == 32)) dst = 0; } if (unlikely(T1 != 0)) { tmp = 0; for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { tmp |= glue(ldu8, MEMSUFFIX)((uint64_t)T0) << sh; } env->gpr[dst] = tmp; } } #endif void glue(do_stsw, MEMSUFFIX) (int src) { int sh; for (; T1 > 3; T1 -= 4, T0 += 4) { glue(st32, MEMSUFFIX)((uint32_t)T0, env->gpr[src++]); if (unlikely(src == 32)) src = 0; } if (unlikely(T1 != 0)) { for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) glue(st8, MEMSUFFIX)((uint32_t)T0, (env->gpr[src] >> sh) & 0xFF); } } #if defined(TARGET_PPC64) void glue(do_stsw_64, MEMSUFFIX) (int src) { int sh; for (; T1 > 3; T1 -= 4, T0 += 4) { glue(st32, MEMSUFFIX)((uint64_t)T0, env->gpr[src++]); if (unlikely(src == 32)) src = 0; } if (unlikely(T1 != 0)) { for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) glue(st8, MEMSUFFIX)((uint64_t)T0, (env->gpr[src] >> sh) & 0xFF); } } #endif /* PowerPC 601 specific instructions (POWER bridge) */ // XXX: to be tested void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) Loading target-ppc/op_mem.h +0 −68 Original line number Diff line number Diff line Loading @@ -20,74 +20,6 @@ #include "op_mem_access.h" /*** Integer load and store strings ***/ void OPPROTO glue(op_lswi, MEMSUFFIX) (void) { glue(do_lsw, MEMSUFFIX)(PARAM1); RETURN(); } #if defined(TARGET_PPC64) void OPPROTO glue(op_lswi_64, MEMSUFFIX) (void) { glue(do_lsw_64, MEMSUFFIX)(PARAM1); RETURN(); } #endif /* PPC32 specification says we must generate an exception if * rA is in the range of registers to be loaded. * In an other hand, IBM says this is valid, but rA won't be loaded. * For now, I'll follow the spec... */ void OPPROTO glue(op_lswx, MEMSUFFIX) (void) { /* Note: T1 comes from xer_bc then no cast is needed */ if (likely(T1 != 0)) { if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX); } else { glue(do_lsw, MEMSUFFIX)(PARAM1); } } RETURN(); } #if defined(TARGET_PPC64) void OPPROTO glue(op_lswx_64, MEMSUFFIX) (void) { /* Note: T1 comes from xer_bc then no cast is needed */ if (likely(T1 != 0)) { if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX); } else { glue(do_lsw_64, MEMSUFFIX)(PARAM1); } } RETURN(); } #endif void OPPROTO glue(op_stsw, MEMSUFFIX) (void) { glue(do_stsw, MEMSUFFIX)(PARAM1); RETURN(); } #if defined(TARGET_PPC64) void OPPROTO glue(op_stsw_64, MEMSUFFIX) (void) { glue(do_stsw_64, MEMSUFFIX)(PARAM1); RETURN(); } #endif /* Load and set reservation */ void OPPROTO glue(op_lwarx, MEMSUFFIX) (void) { Loading Loading
target-ppc/helper.h +3 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,9 @@ DEF_HELPER_3(td, void, tl, tl, i32) DEF_HELPER_2(lmw, void, tl, i32) DEF_HELPER_2(stmw, void, tl, i32) DEF_HELPER_3(lsw, void, tl, i32, i32) DEF_HELPER_4(lswx, void, tl, i32, i32, i32) DEF_HELPER_3(stsw, void, tl, i32, i32) DEF_HELPER_1(dcbz, void, tl) DEF_HELPER_1(dcbz_970, void, tl) DEF_HELPER_1(icbi, void, tl) Loading
target-ppc/op_helper.c +93 −0 Original line number Diff line number Diff line Loading @@ -170,6 +170,99 @@ void helper_stmw (target_ulong addr, uint32_t reg) } } void helper_lsw(target_ulong addr, uint32_t nb, uint32_t reg) { int sh; #ifdef CONFIG_USER_ONLY #define ldfunl ldl_raw #define ldfunb ldub_raw #else int (*ldfunl)(target_ulong); int (*ldfunb)(target_ulong); switch (env->mmu_idx) { default: case 0: ldfunl = ldl_user; ldfunb = ldub_user; break; case 1: ldfunl = ldl_kernel; ldfunb = ldub_kernel; break; case 2: ldfunl = ldl_hypv; ldfunb = ldub_hypv; break; } #endif for (; nb > 3; nb -= 4, addr += 4) { env->gpr[reg] = ldfunl(get_addr(addr)); reg = (reg + 1) % 32; } if (unlikely(nb > 0)) { env->gpr[reg] = 0; for (sh = 24; nb > 0; nb--, addr++, sh -= 8) { env->gpr[reg] |= ldfunb(get_addr(addr)) << sh; } } } /* PPC32 specification says we must generate an exception if * rA is in the range of registers to be loaded. * In an other hand, IBM says this is valid, but rA won't be loaded. * For now, I'll follow the spec... */ void helper_lswx(target_ulong addr, uint32_t reg, uint32_t ra, uint32_t rb) { if (likely(xer_bc != 0)) { if (unlikely((ra != 0 && reg < ra && (reg + xer_bc) > ra) || (reg < rb && (reg + xer_bc) > rb))) { raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX); } else { helper_lsw(addr, xer_bc, reg); } } } void helper_stsw(target_ulong addr, uint32_t nb, uint32_t reg) { int sh; #ifdef CONFIG_USER_ONLY #define stfunl stl_raw #define stfunb stb_raw #else void (*stfunl)(target_ulong, int); void (*stfunb)(target_ulong, int); switch (env->mmu_idx) { default: case 0: stfunl = stl_user; stfunb = stb_user; break; case 1: stfunl = stl_kernel; stfunb = stb_kernel; break; case 2: stfunl = stl_hypv; stfunb = stb_hypv; break; } #endif for (; nb > 3; nb -= 4, addr += 4) { stfunl(get_addr(addr), env->gpr[reg]); reg = (reg + 1) % 32; } if (unlikely(nb > 0)) { for (sh = 24; nb > 0; nb--, addr++, sh -= 8) stfunb(get_addr(addr), (env->gpr[reg] >> sh) & 0xFF); } } static void do_dcbz(target_ulong addr, int dcache_line_size) { target_long mask = get_addr(~(dcache_line_size - 1)); Loading
target-ppc/op_helper.h +0 −7 Original line number Diff line number Diff line Loading @@ -21,19 +21,12 @@ #if defined(MEMSUFFIX) /* Memory load/store helpers */ void glue(do_lsw, MEMSUFFIX) (int dst); void glue(do_stsw, MEMSUFFIX) (int src); void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb); void glue(do_POWER2_lfq, MEMSUFFIX) (void); void glue(do_POWER2_lfq_le, MEMSUFFIX) (void); void glue(do_POWER2_stfq, MEMSUFFIX) (void); void glue(do_POWER2_stfq_le, MEMSUFFIX) (void); #if defined(TARGET_PPC64) void glue(do_lsw_64, MEMSUFFIX) (int dst); void glue(do_stsw_64, MEMSUFFIX) (int src); #endif #else void do_print_mem_EA (target_ulong EA); Loading
target-ppc/op_helper_mem.h +0 −72 Original line number Diff line number Diff line Loading @@ -20,78 +20,6 @@ #include "op_mem_access.h" void glue(do_lsw, MEMSUFFIX) (int dst) { uint32_t tmp; int sh; for (; T1 > 3; T1 -= 4, T0 += 4) { env->gpr[dst++] = glue(ldu32, MEMSUFFIX)((uint32_t)T0); if (unlikely(dst == 32)) dst = 0; } if (unlikely(T1 != 0)) { tmp = 0; for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { tmp |= glue(ldu8, MEMSUFFIX)((uint32_t)T0) << sh; } env->gpr[dst] = tmp; } } #if defined(TARGET_PPC64) void glue(do_lsw_64, MEMSUFFIX) (int dst) { uint32_t tmp; int sh; for (; T1 > 3; T1 -= 4, T0 += 4) { env->gpr[dst++] = glue(ldu32, MEMSUFFIX)((uint64_t)T0); if (unlikely(dst == 32)) dst = 0; } if (unlikely(T1 != 0)) { tmp = 0; for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) { tmp |= glue(ldu8, MEMSUFFIX)((uint64_t)T0) << sh; } env->gpr[dst] = tmp; } } #endif void glue(do_stsw, MEMSUFFIX) (int src) { int sh; for (; T1 > 3; T1 -= 4, T0 += 4) { glue(st32, MEMSUFFIX)((uint32_t)T0, env->gpr[src++]); if (unlikely(src == 32)) src = 0; } if (unlikely(T1 != 0)) { for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) glue(st8, MEMSUFFIX)((uint32_t)T0, (env->gpr[src] >> sh) & 0xFF); } } #if defined(TARGET_PPC64) void glue(do_stsw_64, MEMSUFFIX) (int src) { int sh; for (; T1 > 3; T1 -= 4, T0 += 4) { glue(st32, MEMSUFFIX)((uint64_t)T0, env->gpr[src++]); if (unlikely(src == 32)) src = 0; } if (unlikely(T1 != 0)) { for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) glue(st8, MEMSUFFIX)((uint64_t)T0, (env->gpr[src] >> sh) & 0xFF); } } #endif /* PowerPC 601 specific instructions (POWER bridge) */ // XXX: to be tested void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb) Loading
target-ppc/op_mem.h +0 −68 Original line number Diff line number Diff line Loading @@ -20,74 +20,6 @@ #include "op_mem_access.h" /*** Integer load and store strings ***/ void OPPROTO glue(op_lswi, MEMSUFFIX) (void) { glue(do_lsw, MEMSUFFIX)(PARAM1); RETURN(); } #if defined(TARGET_PPC64) void OPPROTO glue(op_lswi_64, MEMSUFFIX) (void) { glue(do_lsw_64, MEMSUFFIX)(PARAM1); RETURN(); } #endif /* PPC32 specification says we must generate an exception if * rA is in the range of registers to be loaded. * In an other hand, IBM says this is valid, but rA won't be loaded. * For now, I'll follow the spec... */ void OPPROTO glue(op_lswx, MEMSUFFIX) (void) { /* Note: T1 comes from xer_bc then no cast is needed */ if (likely(T1 != 0)) { if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX); } else { glue(do_lsw, MEMSUFFIX)(PARAM1); } } RETURN(); } #if defined(TARGET_PPC64) void OPPROTO glue(op_lswx_64, MEMSUFFIX) (void) { /* Note: T1 comes from xer_bc then no cast is needed */ if (likely(T1 != 0)) { if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { raise_exception_err(env, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX); } else { glue(do_lsw_64, MEMSUFFIX)(PARAM1); } } RETURN(); } #endif void OPPROTO glue(op_stsw, MEMSUFFIX) (void) { glue(do_stsw, MEMSUFFIX)(PARAM1); RETURN(); } #if defined(TARGET_PPC64) void OPPROTO glue(op_stsw_64, MEMSUFFIX) (void) { glue(do_stsw_64, MEMSUFFIX)(PARAM1); RETURN(); } #endif /* Load and set reservation */ void OPPROTO glue(op_lwarx, MEMSUFFIX) (void) { Loading