mirror of https://github.com/xemu-project/xemu.git
PowerPC improvments:
- add missing 64 bits rotate instructions - safely define TARGET_PPCSPE when 64 bits registers are used a separate target will be needed to use it in 32 bits mode on 32 bits hosts. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2527 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
e864cabdc0
commit
51789c410b
|
@ -23,13 +23,18 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(TARGET_PPC64) || (HOST_LONG_BITS >= 64)
|
||||||
|
/* When using 64 bits temporary registers,
|
||||||
|
* we can use 64 bits GPR with no extra cost
|
||||||
|
*/
|
||||||
|
#define TARGET_PPCSPE
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined (TARGET_PPC64)
|
#if defined (TARGET_PPC64)
|
||||||
typedef uint64_t ppc_gpr_t;
|
typedef uint64_t ppc_gpr_t;
|
||||||
#define TARGET_LONG_BITS 64
|
#define TARGET_LONG_BITS 64
|
||||||
#define TARGET_GPR_BITS 64
|
#define TARGET_GPR_BITS 64
|
||||||
#define REGX "%016" PRIx64
|
#define REGX "%016" PRIx64
|
||||||
/* We can safely use PowerPC SPE extension when compiling PowerPC 64 */
|
|
||||||
#define TARGET_PPCSPE
|
|
||||||
#elif defined(TARGET_PPCSPE)
|
#elif defined(TARGET_PPCSPE)
|
||||||
/* GPR are 64 bits: used by vector extension */
|
/* GPR are 64 bits: used by vector extension */
|
||||||
typedef uint64_t ppc_gpr_t;
|
typedef uint64_t ppc_gpr_t;
|
||||||
|
|
|
@ -1444,6 +1444,20 @@ void OPPROTO op_rotli32_T0 (void)
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(TARGET_PPC64)
|
||||||
|
void OPPROTO op_rotl64_T0_T1 (void)
|
||||||
|
{
|
||||||
|
T0 = rotl64(T0, T1 & 0x3F);
|
||||||
|
RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OPPROTO op_rotli64_T0 (void)
|
||||||
|
{
|
||||||
|
T0 = rotl64(T0, PARAM1);
|
||||||
|
RETURN();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*** Integer shift ***/
|
/*** Integer shift ***/
|
||||||
/* shift left word */
|
/* shift left word */
|
||||||
void OPPROTO op_slw (void)
|
void OPPROTO op_slw (void)
|
||||||
|
|
|
@ -1109,12 +1109,10 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
target_ulong mask;
|
target_ulong mask;
|
||||||
uint32_t mb, me, sh;
|
uint32_t mb, me, sh;
|
||||||
int n;
|
|
||||||
|
|
||||||
mb = MB(ctx->opcode);
|
mb = MB(ctx->opcode);
|
||||||
me = ME(ctx->opcode);
|
me = ME(ctx->opcode);
|
||||||
sh = SH(ctx->opcode);
|
sh = SH(ctx->opcode);
|
||||||
n = me + 1 - mb;
|
|
||||||
if (likely(sh == 0)) {
|
if (likely(sh == 0)) {
|
||||||
if (likely(mb == 0 && me == 31)) {
|
if (likely(mb == 0 && me == 31)) {
|
||||||
gen_op_load_gpr_T0(rS(ctx->opcode));
|
gen_op_load_gpr_T0(rS(ctx->opcode));
|
||||||
|
@ -1231,68 +1229,130 @@ GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \
|
||||||
{ \
|
{ \
|
||||||
gen_##name(ctx, 1, 1); \
|
gen_##name(ctx, 1, 1); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me,
|
||||||
|
uint32_t sh)
|
||||||
|
{
|
||||||
|
gen_op_load_gpr_T0(rS(ctx->opcode));
|
||||||
|
if (likely(sh == 0)) {
|
||||||
|
goto do_mask;
|
||||||
|
}
|
||||||
|
if (likely(mb == 0)) {
|
||||||
|
if (likely(me == 63)) {
|
||||||
|
gen_op_rotli32_T0(sh);
|
||||||
|
goto do_store;
|
||||||
|
} else if (likely(me == (63 - sh))) {
|
||||||
|
gen_op_sli_T0(sh);
|
||||||
|
goto do_store;
|
||||||
|
}
|
||||||
|
} else if (likely(me == 63)) {
|
||||||
|
if (likely(sh == (64 - mb))) {
|
||||||
|
gen_op_srli_T0(mb);
|
||||||
|
goto do_store;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gen_op_rotli64_T0(sh);
|
||||||
|
do_mask:
|
||||||
|
gen_op_andi_T0(MASK(mb, me));
|
||||||
|
do_store:
|
||||||
|
gen_op_store_T0_gpr(rA(ctx->opcode));
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx);
|
||||||
|
}
|
||||||
/* rldicl - rldicl. */
|
/* rldicl - rldicl. */
|
||||||
static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
|
static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
|
||||||
{
|
{
|
||||||
int sh, mb;
|
uint32_t sh, mb;
|
||||||
|
|
||||||
sh = SH(ctx->opcode) | (1 << shn);
|
sh = SH(ctx->opcode) | (1 << shn);
|
||||||
mb = (MB(ctx->opcode) << 1) | mbn;
|
mb = (MB(ctx->opcode) << 1) | mbn;
|
||||||
/* XXX: TODO */
|
gen_rldinm(ctx, mb, 63, sh);
|
||||||
RET_INVAL(ctx);
|
|
||||||
}
|
}
|
||||||
GEN_PPC64_R4(rldicl, 0x1E, 0x00)
|
GEN_PPC64_R4(rldicl, 0x1E, 0x00);
|
||||||
/* rldicr - rldicr. */
|
/* rldicr - rldicr. */
|
||||||
static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
|
static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
|
||||||
{
|
{
|
||||||
int sh, me;
|
uint32_t sh, me;
|
||||||
|
|
||||||
sh = SH(ctx->opcode) | (1 << shn);
|
sh = SH(ctx->opcode) | (1 << shn);
|
||||||
me = (MB(ctx->opcode) << 1) | men;
|
me = (MB(ctx->opcode) << 1) | men;
|
||||||
/* XXX: TODO */
|
gen_rldinm(ctx, 0, me, sh);
|
||||||
RET_INVAL(ctx);
|
|
||||||
}
|
}
|
||||||
GEN_PPC64_R4(rldicr, 0x1E, 0x02)
|
GEN_PPC64_R4(rldicr, 0x1E, 0x02);
|
||||||
/* rldic - rldic. */
|
/* rldic - rldic. */
|
||||||
static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
|
static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
|
||||||
{
|
{
|
||||||
int sh, mb;
|
uint32_t sh, mb;
|
||||||
|
|
||||||
sh = SH(ctx->opcode) | (1 << shn);
|
sh = SH(ctx->opcode) | (1 << shn);
|
||||||
mb = (MB(ctx->opcode) << 1) | mbn;
|
mb = (MB(ctx->opcode) << 1) | mbn;
|
||||||
/* XXX: TODO */
|
gen_rldinm(ctx, mb, 63 - sh, sh);
|
||||||
RET_INVAL(ctx);
|
|
||||||
}
|
}
|
||||||
GEN_PPC64_R4(rldic, 0x1E, 0x04)
|
GEN_PPC64_R4(rldic, 0x1E, 0x04);
|
||||||
|
|
||||||
|
static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me)
|
||||||
|
{
|
||||||
|
gen_op_load_gpr_T0(rS(ctx->opcode));
|
||||||
|
gen_op_load_gpr_T1(rB(ctx->opcode));
|
||||||
|
gen_op_rotl64_T0_T1();
|
||||||
|
if (unlikely(mb != 0 || me != 63)) {
|
||||||
|
gen_op_andi_T0(MASK(mb, me));
|
||||||
|
}
|
||||||
|
gen_op_store_T0_gpr(rA(ctx->opcode));
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
/* rldcl - rldcl. */
|
/* rldcl - rldcl. */
|
||||||
static inline void gen_rldcl (DisasContext *ctx, int mbn)
|
static inline void gen_rldcl (DisasContext *ctx, int mbn)
|
||||||
{
|
{
|
||||||
int mb;
|
uint32_t mb;
|
||||||
|
|
||||||
mb = (MB(ctx->opcode) << 1) | mbn;
|
mb = (MB(ctx->opcode) << 1) | mbn;
|
||||||
/* XXX: TODO */
|
gen_rldnm(ctx, mb, 63);
|
||||||
RET_INVAL(ctx);
|
|
||||||
}
|
}
|
||||||
GEN_PPC64_R2(rldcl, 0x1E, 0x08)
|
GEN_PPC64_R2(rldcl, 0x1E, 0x08)
|
||||||
/* rldcr - rldcr. */
|
/* rldcr - rldcr. */
|
||||||
static inline void gen_rldcr (DisasContext *ctx, int men)
|
static inline void gen_rldcr (DisasContext *ctx, int men)
|
||||||
{
|
{
|
||||||
int me;
|
uint32_t me;
|
||||||
|
|
||||||
me = (MB(ctx->opcode) << 1) | men;
|
me = (MB(ctx->opcode) << 1) | men;
|
||||||
/* XXX: TODO */
|
gen_rldnm(ctx, 0, me);
|
||||||
RET_INVAL(ctx);
|
|
||||||
}
|
}
|
||||||
GEN_PPC64_R2(rldcr, 0x1E, 0x09)
|
GEN_PPC64_R2(rldcr, 0x1E, 0x09)
|
||||||
/* rldimi - rldimi. */
|
/* rldimi - rldimi. */
|
||||||
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
|
static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
|
||||||
{
|
{
|
||||||
int sh, mb;
|
uint64_t mask;
|
||||||
|
uint32_t sh, mb;
|
||||||
|
|
||||||
sh = SH(ctx->opcode) | (1 << shn);
|
sh = SH(ctx->opcode) | (1 << shn);
|
||||||
mb = (MB(ctx->opcode) << 1) | mbn;
|
mb = (MB(ctx->opcode) << 1) | mbn;
|
||||||
/* XXX: TODO */
|
if (likely(sh == 0)) {
|
||||||
RET_INVAL(ctx);
|
if (likely(mb == 0)) {
|
||||||
|
gen_op_load_gpr_T0(rS(ctx->opcode));
|
||||||
|
goto do_store;
|
||||||
|
} else if (likely(mb == 63)) {
|
||||||
|
gen_op_load_gpr_T0(rA(ctx->opcode));
|
||||||
|
goto do_store;
|
||||||
|
}
|
||||||
|
gen_op_load_gpr_T0(rS(ctx->opcode));
|
||||||
|
gen_op_load_gpr_T1(rA(ctx->opcode));
|
||||||
|
goto do_mask;
|
||||||
|
}
|
||||||
|
gen_op_load_gpr_T0(rS(ctx->opcode));
|
||||||
|
gen_op_load_gpr_T1(rA(ctx->opcode));
|
||||||
|
gen_op_rotli64_T0(SH(ctx->opcode));
|
||||||
|
do_mask:
|
||||||
|
mask = MASK(mb, 63 - sh);
|
||||||
|
gen_op_andi_T0(mask);
|
||||||
|
gen_op_andi_T1(~mask);
|
||||||
|
gen_op_or();
|
||||||
|
do_store:
|
||||||
|
gen_op_store_T0_gpr(rA(ctx->opcode));
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx);
|
||||||
}
|
}
|
||||||
GEN_PPC64_R4(rldimi, 0x1E, 0x06)
|
GEN_PPC64_R4(rldimi, 0x1E, 0x06)
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue