mirror of https://gitee.com/openkylin/qemu.git
target-ppc: convert logical instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5506 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
e1571908a2
commit
26d6736245
|
@ -7,3 +7,13 @@ DEF_HELPER(uint32_t, helper_fcmpu, (void))
|
||||||
|
|
||||||
DEF_HELPER(uint32_t, helper_load_cr, (void))
|
DEF_HELPER(uint32_t, helper_load_cr, (void))
|
||||||
DEF_HELPER(void, helper_store_cr, (target_ulong, uint32_t))
|
DEF_HELPER(void, helper_store_cr, (target_ulong, uint32_t))
|
||||||
|
|
||||||
|
DEF_HELPER(target_ulong, helper_cntlzw, (target_ulong t))
|
||||||
|
DEF_HELPER(target_ulong, helper_popcntb, (target_ulong val))
|
||||||
|
DEF_HELPER(target_ulong, helper_sraw, (target_ulong, target_ulong))
|
||||||
|
#if defined(TARGET_PPC64)
|
||||||
|
DEF_HELPER(target_ulong, helper_cntlzd, (target_ulong t))
|
||||||
|
DEF_HELPER(target_ulong, helper_popcntb_64, (target_ulong val))
|
||||||
|
DEF_HELPER(target_ulong, helper_srad, (target_ulong, target_ulong))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
248
target-ppc/op.c
248
target-ppc/op.c
|
@ -37,15 +37,6 @@ void OPPROTO op_debug (void)
|
||||||
do_raise_exception(EXCP_DEBUG);
|
do_raise_exception(EXCP_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load/store special registers */
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_store_pri (void)
|
|
||||||
{
|
|
||||||
do_store_pri(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
/* Segment registers load and store */
|
/* Segment registers load and store */
|
||||||
void OPPROTO op_load_sr (void)
|
void OPPROTO op_load_sr (void)
|
||||||
|
@ -921,101 +912,7 @@ void OPPROTO op_subfzeo_64 (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void OPPROTO op_popcntb (void)
|
|
||||||
{
|
|
||||||
do_popcntb();
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_popcntb_64 (void)
|
|
||||||
{
|
|
||||||
do_popcntb_64();
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*** Integer logical ***/
|
/*** Integer logical ***/
|
||||||
/* and */
|
|
||||||
void OPPROTO op_and (void)
|
|
||||||
{
|
|
||||||
T0 &= T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* andc */
|
|
||||||
void OPPROTO op_andc (void)
|
|
||||||
{
|
|
||||||
T0 &= ~T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* count leading zero */
|
|
||||||
void OPPROTO op_cntlzw (void)
|
|
||||||
{
|
|
||||||
do_cntlzw();
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_cntlzd (void)
|
|
||||||
{
|
|
||||||
do_cntlzd();
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* eqv */
|
|
||||||
void OPPROTO op_eqv (void)
|
|
||||||
{
|
|
||||||
T0 = ~(T0 ^ T1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extend sign byte */
|
|
||||||
void OPPROTO op_extsb (void)
|
|
||||||
{
|
|
||||||
#if defined (TARGET_PPC64)
|
|
||||||
T0 = (int64_t)((int8_t)T0);
|
|
||||||
#else
|
|
||||||
T0 = (int32_t)((int8_t)T0);
|
|
||||||
#endif
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extend sign half word */
|
|
||||||
void OPPROTO op_extsh (void)
|
|
||||||
{
|
|
||||||
#if defined (TARGET_PPC64)
|
|
||||||
T0 = (int64_t)((int16_t)T0);
|
|
||||||
#else
|
|
||||||
T0 = (int32_t)((int16_t)T0);
|
|
||||||
#endif
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined (TARGET_PPC64)
|
|
||||||
void OPPROTO op_extsw (void)
|
|
||||||
{
|
|
||||||
T0 = (int64_t)((int32_t)T0);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* nand */
|
|
||||||
void OPPROTO op_nand (void)
|
|
||||||
{
|
|
||||||
T0 = ~(T0 & T1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* nor */
|
|
||||||
void OPPROTO op_nor (void)
|
|
||||||
{
|
|
||||||
T0 = ~(T0 | T1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* or */
|
/* or */
|
||||||
void OPPROTO op_or (void)
|
void OPPROTO op_or (void)
|
||||||
{
|
{
|
||||||
|
@ -1023,34 +920,6 @@ void OPPROTO op_or (void)
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* orc */
|
|
||||||
void OPPROTO op_orc (void)
|
|
||||||
{
|
|
||||||
T0 |= ~T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ori */
|
|
||||||
void OPPROTO op_ori (void)
|
|
||||||
{
|
|
||||||
T0 |= (uint32_t)PARAM1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* xor */
|
|
||||||
void OPPROTO op_xor (void)
|
|
||||||
{
|
|
||||||
T0 ^= T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* xori */
|
|
||||||
void OPPROTO op_xori (void)
|
|
||||||
{
|
|
||||||
T0 ^= (uint32_t)PARAM1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Integer rotate ***/
|
/*** Integer rotate ***/
|
||||||
void OPPROTO op_rotl32_T0_T1 (void)
|
void OPPROTO op_rotl32_T0_T1 (void)
|
||||||
{
|
{
|
||||||
|
@ -1079,122 +948,13 @@ void OPPROTO op_rotli64_T0 (void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** Integer shift ***/
|
/*** Integer shift ***/
|
||||||
/* shift left word */
|
|
||||||
void OPPROTO op_slw (void)
|
|
||||||
{
|
|
||||||
if (T1 & 0x20) {
|
|
||||||
T0 = 0;
|
|
||||||
} else {
|
|
||||||
T0 = (uint32_t)(T0 << T1);
|
|
||||||
}
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_sld (void)
|
|
||||||
{
|
|
||||||
if (T1 & 0x40) {
|
|
||||||
T0 = 0;
|
|
||||||
} else {
|
|
||||||
T0 = T0 << T1;
|
|
||||||
}
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* shift right algebraic word */
|
|
||||||
void OPPROTO op_sraw (void)
|
|
||||||
{
|
|
||||||
do_sraw();
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_srad (void)
|
|
||||||
{
|
|
||||||
do_srad();
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* shift right algebraic word immediate */
|
|
||||||
void OPPROTO op_srawi (void)
|
|
||||||
{
|
|
||||||
uint32_t mask = (uint32_t)PARAM2;
|
|
||||||
|
|
||||||
T0 = (int32_t)T0 >> PARAM1;
|
|
||||||
if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
|
|
||||||
env->xer |= (1 << XER_CA);
|
|
||||||
} else {
|
|
||||||
env->xer &= ~(1 << XER_CA);
|
|
||||||
}
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_sradi (void)
|
|
||||||
{
|
|
||||||
uint64_t mask = ((uint64_t)PARAM2 << 32) | (uint64_t)PARAM3;
|
|
||||||
|
|
||||||
T0 = (int64_t)T0 >> PARAM1;
|
|
||||||
if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
|
|
||||||
env->xer |= (1 << XER_CA);
|
|
||||||
} else {
|
|
||||||
env->xer &= ~(1 << XER_CA);
|
|
||||||
}
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* shift right word */
|
/* shift right word */
|
||||||
void OPPROTO op_srw (void)
|
|
||||||
{
|
|
||||||
if (T1 & 0x20) {
|
|
||||||
T0 = 0;
|
|
||||||
} else {
|
|
||||||
T0 = (uint32_t)T0 >> T1;
|
|
||||||
}
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_srd (void)
|
|
||||||
{
|
|
||||||
if (T1 & 0x40) {
|
|
||||||
T0 = 0;
|
|
||||||
} else {
|
|
||||||
T0 = (uint64_t)T0 >> T1;
|
|
||||||
}
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OPPROTO op_sl_T0_T1 (void)
|
|
||||||
{
|
|
||||||
T0 = T0 << T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OPPROTO op_sli_T0 (void)
|
void OPPROTO op_sli_T0 (void)
|
||||||
{
|
{
|
||||||
T0 = T0 << PARAM1;
|
T0 = T0 << PARAM1;
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPPROTO op_srl_T0_T1 (void)
|
|
||||||
{
|
|
||||||
T0 = (uint32_t)T0 >> T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_srl_T0_T1_64 (void)
|
|
||||||
{
|
|
||||||
T0 = (uint32_t)T0 >> T1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OPPROTO op_srli_T0 (void)
|
void OPPROTO op_srli_T0 (void)
|
||||||
{
|
{
|
||||||
T0 = (uint32_t)T0 >> PARAM1;
|
T0 = (uint32_t)T0 >> PARAM1;
|
||||||
|
@ -1215,14 +975,6 @@ void OPPROTO op_srli_T1 (void)
|
||||||
RETURN();
|
RETURN();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO op_srli_T1_64 (void)
|
|
||||||
{
|
|
||||||
T1 = (uint64_t)T1 >> PARAM1;
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*** Floating-Point arithmetic ***/
|
/*** Floating-Point arithmetic ***/
|
||||||
/* fadd - fadd. */
|
/* fadd - fadd. */
|
||||||
void OPPROTO op_fadd (void)
|
void OPPROTO op_fadd (void)
|
||||||
|
|
|
@ -368,96 +368,98 @@ void do_subfzeo_64 (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void do_cntlzw (void)
|
target_ulong helper_cntlzw (target_ulong t)
|
||||||
{
|
{
|
||||||
T0 = clz32(T0);
|
return clz32(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
void do_cntlzd (void)
|
target_ulong helper_cntlzd (target_ulong t)
|
||||||
{
|
{
|
||||||
T0 = clz64(T0);
|
return clz64(t);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* shift right arithmetic helper */
|
/* shift right arithmetic helper */
|
||||||
void do_sraw (void)
|
target_ulong helper_sraw (target_ulong value, target_ulong shift)
|
||||||
{
|
{
|
||||||
int32_t ret;
|
int32_t ret;
|
||||||
|
|
||||||
if (likely(!(T1 & 0x20UL))) {
|
if (likely(!(shift & 0x20))) {
|
||||||
if (likely((uint32_t)T1 != 0)) {
|
if (likely((uint32_t)shift != 0)) {
|
||||||
ret = (int32_t)T0 >> (T1 & 0x1fUL);
|
shift &= 0x1f;
|
||||||
if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) {
|
ret = (int32_t)value >> shift;
|
||||||
|
if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
|
||||||
env->xer &= ~(1 << XER_CA);
|
env->xer &= ~(1 << XER_CA);
|
||||||
} else {
|
} else {
|
||||||
env->xer |= (1 << XER_CA);
|
env->xer |= (1 << XER_CA);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = T0;
|
ret = (int32_t)value;
|
||||||
env->xer &= ~(1 << XER_CA);
|
env->xer &= ~(1 << XER_CA);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = UINT32_MAX * ((uint32_t)T0 >> 31);
|
ret = (int32_t)value >> 31;
|
||||||
if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) {
|
if (ret) {
|
||||||
env->xer &= ~(1 << XER_CA);
|
|
||||||
} else {
|
|
||||||
env->xer |= (1 << XER_CA);
|
env->xer |= (1 << XER_CA);
|
||||||
|
} else {
|
||||||
|
env->xer &= ~(1 << XER_CA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
T0 = ret;
|
return (target_long)ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
void do_srad (void)
|
target_ulong helper_srad (target_ulong value, target_ulong shift)
|
||||||
{
|
{
|
||||||
int64_t ret;
|
int64_t ret;
|
||||||
|
|
||||||
if (likely(!(T1 & 0x40UL))) {
|
if (likely(!(shift & 0x40))) {
|
||||||
if (likely((uint64_t)T1 != 0)) {
|
if (likely((uint64_t)shift != 0)) {
|
||||||
ret = (int64_t)T0 >> (T1 & 0x3FUL);
|
shift &= 0x3f;
|
||||||
if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) {
|
ret = (int64_t)value >> shift;
|
||||||
|
if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
|
||||||
env->xer &= ~(1 << XER_CA);
|
env->xer &= ~(1 << XER_CA);
|
||||||
} else {
|
} else {
|
||||||
env->xer |= (1 << XER_CA);
|
env->xer |= (1 << XER_CA);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = T0;
|
ret = (int64_t)value;
|
||||||
env->xer &= ~(1 << XER_CA);
|
env->xer &= ~(1 << XER_CA);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = UINT64_MAX * ((uint64_t)T0 >> 63);
|
ret = (int64_t)value >> 63;
|
||||||
if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) {
|
if (ret) {
|
||||||
env->xer &= ~(1 << XER_CA);
|
|
||||||
} else {
|
|
||||||
env->xer |= (1 << XER_CA);
|
env->xer |= (1 << XER_CA);
|
||||||
|
} else {
|
||||||
|
env->xer &= ~(1 << XER_CA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
T0 = ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void do_popcntb (void)
|
target_ulong helper_popcntb (target_ulong val)
|
||||||
{
|
{
|
||||||
uint32_t ret;
|
uint32_t ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
for (i = 0; i < 32; i += 8)
|
for (i = 0; i < 32; i += 8)
|
||||||
ret |= ctpop8((T0 >> i) & 0xFF) << i;
|
ret |= ctpop8((val >> i) & 0xFF) << i;
|
||||||
T0 = ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
void do_popcntb_64 (void)
|
target_ulong helper_popcntb_64 (target_ulong val)
|
||||||
{
|
{
|
||||||
uint64_t ret;
|
uint64_t ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
for (i = 0; i < 64; i += 8)
|
for (i = 0; i < 64; i += 8)
|
||||||
ret |= ctpop8((T0 >> i) & 0xFF) << i;
|
ret |= ctpop8((val >> i) & 0xFF) << i;
|
||||||
T0 = ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1277,63 +1277,56 @@ GEN_INT_ARITH2 (divdu, 0x1F, 0x09, 0x0E, PPC_64B);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** Integer logical ***/
|
/*** Integer logical ***/
|
||||||
#define __GEN_LOGICAL2(name, opc2, opc3, type) \
|
#define GEN_LOGICAL2(name, tcg_op, opc, type) \
|
||||||
GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type) \
|
GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type) \
|
||||||
{ \
|
{ \
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); \
|
tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], \
|
||||||
tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); \
|
cpu_gpr[rB(ctx->opcode)]); \
|
||||||
gen_op_##name(); \
|
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); \
|
|
||||||
if (unlikely(Rc(ctx->opcode) != 0)) \
|
if (unlikely(Rc(ctx->opcode) != 0)) \
|
||||||
gen_set_Rc0(ctx, cpu_T[0]); \
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
|
||||||
}
|
}
|
||||||
#define GEN_LOGICAL2(name, opc, type) \
|
|
||||||
__GEN_LOGICAL2(name, 0x1C, opc, type)
|
|
||||||
|
|
||||||
#define GEN_LOGICAL1(name, opc, type) \
|
#define GEN_LOGICAL1(name, tcg_op, opc, type) \
|
||||||
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) \
|
GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type) \
|
||||||
{ \
|
{ \
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); \
|
tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); \
|
||||||
gen_op_##name(); \
|
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); \
|
|
||||||
if (unlikely(Rc(ctx->opcode) != 0)) \
|
if (unlikely(Rc(ctx->opcode) != 0)) \
|
||||||
gen_set_Rc0(ctx, cpu_T[0]); \
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and & and. */
|
/* and & and. */
|
||||||
GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
|
GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
|
||||||
/* andc & andc. */
|
/* andc & andc. */
|
||||||
GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
|
GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
|
||||||
/* andi. */
|
/* andi. */
|
||||||
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
|
||||||
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], UIMM(ctx->opcode));
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
gen_set_Rc0(ctx, cpu_T[0]);
|
|
||||||
}
|
}
|
||||||
/* andis. */
|
/* andis. */
|
||||||
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
|
||||||
tcg_gen_andi_tl(cpu_T[0], cpu_T[0], UIMM(ctx->opcode) << 16);
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
gen_set_Rc0(ctx, cpu_T[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cntlzw */
|
/* cntlzw */
|
||||||
GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
|
GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER)
|
||||||
|
{
|
||||||
|
tcg_gen_helper_1_1(helper_cntlzw, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx, cpu_gpr[rS(ctx->opcode)]);
|
||||||
|
}
|
||||||
/* eqv & eqv. */
|
/* eqv & eqv. */
|
||||||
GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
|
GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
|
||||||
/* extsb & extsb. */
|
/* extsb & extsb. */
|
||||||
GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
|
GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
|
||||||
/* extsh & extsh. */
|
/* extsh & extsh. */
|
||||||
GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
|
GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
|
||||||
/* nand & nand. */
|
/* nand & nand. */
|
||||||
GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
|
GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
|
||||||
/* nor & nor. */
|
/* nor & nor. */
|
||||||
GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
|
GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
|
||||||
|
|
||||||
/* or & or. */
|
/* or & or. */
|
||||||
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
|
@ -1344,55 +1337,54 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
|
||||||
rb = rB(ctx->opcode);
|
rb = rB(ctx->opcode);
|
||||||
/* Optimisation for mr. ri case */
|
/* Optimisation for mr. ri case */
|
||||||
if (rs != ra || rs != rb) {
|
if (rs != ra || rs != rb) {
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
|
if (rs != rb)
|
||||||
if (rs != rb) {
|
tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
|
||||||
tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]);
|
else
|
||||||
gen_op_or();
|
tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
|
||||||
}
|
|
||||||
tcg_gen_mov_tl(cpu_gpr[ra], cpu_T[0]);
|
|
||||||
if (unlikely(Rc(ctx->opcode) != 0))
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
gen_set_Rc0(ctx, cpu_T[0]);
|
gen_set_Rc0(ctx, cpu_gpr[ra]);
|
||||||
} else if (unlikely(Rc(ctx->opcode) != 0)) {
|
} else if (unlikely(Rc(ctx->opcode) != 0)) {
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rs]);
|
gen_set_Rc0(ctx, cpu_gpr[rs]);
|
||||||
gen_set_Rc0(ctx, cpu_T[0]);
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
} else {
|
} else {
|
||||||
|
int prio = 0;
|
||||||
|
|
||||||
switch (rs) {
|
switch (rs) {
|
||||||
case 1:
|
case 1:
|
||||||
/* Set process priority to low */
|
/* Set process priority to low */
|
||||||
gen_op_store_pri(2);
|
prio = 2;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
/* Set process priority to medium-low */
|
/* Set process priority to medium-low */
|
||||||
gen_op_store_pri(3);
|
prio = 3;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* Set process priority to normal */
|
/* Set process priority to normal */
|
||||||
gen_op_store_pri(4);
|
prio = 4;
|
||||||
break;
|
break;
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
case 31:
|
case 31:
|
||||||
if (ctx->supervisor > 0) {
|
if (ctx->supervisor > 0) {
|
||||||
/* Set process priority to very low */
|
/* Set process priority to very low */
|
||||||
gen_op_store_pri(1);
|
prio = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (ctx->supervisor > 0) {
|
if (ctx->supervisor > 0) {
|
||||||
/* Set process priority to medium-hight */
|
/* Set process priority to medium-hight */
|
||||||
gen_op_store_pri(5);
|
prio = 5;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (ctx->supervisor > 0) {
|
if (ctx->supervisor > 0) {
|
||||||
/* Set process priority to high */
|
/* Set process priority to high */
|
||||||
gen_op_store_pri(6);
|
prio = 6;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
if (ctx->supervisor > 1) {
|
if (ctx->supervisor > 1) {
|
||||||
/* Set process priority to very high */
|
/* Set process priority to very high */
|
||||||
gen_op_store_pri(7);
|
prio = 7;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1400,26 +1392,29 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
|
||||||
/* nop */
|
/* nop */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (prio) {
|
||||||
|
TCGv temp = tcg_temp_new(TCG_TYPE_TL);
|
||||||
|
tcg_gen_ld_tl(temp, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
|
||||||
|
tcg_gen_andi_tl(temp, temp, ~0x001C000000000000ULL);
|
||||||
|
tcg_gen_ori_tl(temp, temp, ((uint64_t)prio) << 50);
|
||||||
|
tcg_gen_st_tl(temp, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
|
||||||
|
tcg_temp_free(temp);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* orc & orc. */
|
/* orc & orc. */
|
||||||
GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
|
GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
|
||||||
/* xor & xor. */
|
/* xor & xor. */
|
||||||
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
|
||||||
/* Optimisation for "set to zero" case */
|
/* Optimisation for "set to zero" case */
|
||||||
if (rS(ctx->opcode) != rB(ctx->opcode)) {
|
if (rS(ctx->opcode) != rB(ctx->opcode))
|
||||||
tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
|
tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
|
||||||
gen_op_xor();
|
else
|
||||||
} else {
|
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
|
||||||
tcg_gen_movi_tl(cpu_T[0], 0);
|
|
||||||
}
|
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
if (unlikely(Rc(ctx->opcode) != 0))
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
gen_set_Rc0(ctx, cpu_T[0]);
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
}
|
}
|
||||||
/* ori */
|
/* ori */
|
||||||
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
|
@ -1431,10 +1426,7 @@ GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
/* XXX: should handle special NOPs for POWER series */
|
/* XXX: should handle special NOPs for POWER series */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
|
||||||
if (likely(uimm != 0))
|
|
||||||
gen_op_ori(uimm);
|
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
}
|
}
|
||||||
/* oris */
|
/* oris */
|
||||||
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
|
@ -1445,10 +1437,7 @@ GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
/* NOP */
|
/* NOP */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
|
||||||
if (likely(uimm != 0))
|
|
||||||
gen_op_ori(uimm << 16);
|
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
}
|
}
|
||||||
/* xori */
|
/* xori */
|
||||||
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
|
@ -1459,12 +1448,8 @@ GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
/* NOP */
|
/* NOP */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
|
||||||
if (likely(uimm != 0))
|
|
||||||
gen_op_xori(uimm);
|
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* xoris */
|
/* xoris */
|
||||||
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
|
@ -1474,30 +1459,29 @@ GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
/* NOP */
|
/* NOP */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
|
||||||
if (likely(uimm != 0))
|
|
||||||
gen_op_xori(uimm << 16);
|
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* popcntb : PowerPC 2.03 specification */
|
/* popcntb : PowerPC 2.03 specification */
|
||||||
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
|
GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
|
||||||
{
|
{
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
if (ctx->sf_mode)
|
if (ctx->sf_mode)
|
||||||
gen_op_popcntb_64();
|
tcg_gen_helper_1_1(helper_popcntb_64, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
gen_op_popcntb();
|
tcg_gen_helper_1_1(helper_popcntb, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
/* extsw & extsw. */
|
/* extsw & extsw. */
|
||||||
GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
|
GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
|
||||||
/* cntlzd */
|
/* cntlzd */
|
||||||
GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
|
GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B)
|
||||||
|
{
|
||||||
|
tcg_gen_helper_1_1(helper_cntlzd, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** Integer rotate ***/
|
/*** Integer rotate ***/
|
||||||
|
@ -1759,54 +1743,141 @@ GEN_PPC64_R4(rldimi, 0x1E, 0x06);
|
||||||
|
|
||||||
/*** Integer shift ***/
|
/*** Integer shift ***/
|
||||||
/* slw & slw. */
|
/* slw & slw. */
|
||||||
__GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
|
GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER)
|
||||||
|
{
|
||||||
|
TCGv temp;
|
||||||
|
int l1, l2;
|
||||||
|
l1 = gen_new_label();
|
||||||
|
l2 = gen_new_label();
|
||||||
|
|
||||||
|
temp = tcg_temp_local_new(TCG_TYPE_TL);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x20);
|
||||||
|
tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
|
||||||
|
tcg_gen_br(l2);
|
||||||
|
gen_set_label(l1);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x3f);
|
||||||
|
tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
|
||||||
|
tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
gen_set_label(l2);
|
||||||
|
tcg_temp_free(temp);
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
}
|
||||||
/* sraw & sraw. */
|
/* sraw & sraw. */
|
||||||
__GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
|
GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER)
|
||||||
|
{
|
||||||
|
tcg_gen_helper_1_2(helper_sraw, cpu_gpr[rA(ctx->opcode)],
|
||||||
|
cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
}
|
||||||
/* srawi & srawi. */
|
/* srawi & srawi. */
|
||||||
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
int mb, me;
|
int sh = SH(ctx->opcode);
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
if (sh != 0) {
|
||||||
if (SH(ctx->opcode) != 0) {
|
int l1, l2;
|
||||||
tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
|
TCGv temp;
|
||||||
mb = 32 - SH(ctx->opcode);
|
l1 = gen_new_label();
|
||||||
me = 31;
|
l2 = gen_new_label();
|
||||||
#if defined(TARGET_PPC64)
|
temp = tcg_temp_local_new(TCG_TYPE_TL);
|
||||||
mb += 32;
|
tcg_gen_ext32s_tl(temp, cpu_gpr[rS(ctx->opcode)]);
|
||||||
me += 32;
|
tcg_gen_brcondi_tl(TCG_COND_GE, temp, 0, l1);
|
||||||
#endif
|
tcg_gen_andi_tl(temp, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
|
||||||
gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
|
tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
|
||||||
|
tcg_gen_ori_i32(cpu_xer, cpu_xer, 1 << XER_CA);
|
||||||
|
tcg_gen_br(l2);
|
||||||
|
gen_set_label(l1);
|
||||||
|
tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
|
||||||
|
gen_set_label(l2);
|
||||||
|
tcg_gen_ext32s_tl(temp, cpu_gpr[rS(ctx->opcode)]);
|
||||||
|
tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], temp, sh);
|
||||||
|
tcg_temp_free(temp);
|
||||||
|
} else {
|
||||||
|
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
||||||
|
tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
|
||||||
}
|
}
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
if (unlikely(Rc(ctx->opcode) != 0))
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
gen_set_Rc0(ctx, cpu_T[0]);
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
}
|
}
|
||||||
/* srw & srw. */
|
/* srw & srw. */
|
||||||
__GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
|
GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER)
|
||||||
|
{
|
||||||
|
TCGv temp;
|
||||||
|
int l1, l2;
|
||||||
|
l1 = gen_new_label();
|
||||||
|
l2 = gen_new_label();
|
||||||
|
|
||||||
|
temp = tcg_temp_local_new(TCG_TYPE_TL);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x20);
|
||||||
|
tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
|
||||||
|
tcg_gen_br(l2);
|
||||||
|
gen_set_label(l1);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x3f);
|
||||||
|
tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
|
||||||
|
tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
gen_set_label(l2);
|
||||||
|
tcg_temp_free(temp);
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
}
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
/* sld & sld. */
|
/* sld & sld. */
|
||||||
__GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
|
GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B)
|
||||||
|
{
|
||||||
|
TCGv temp;
|
||||||
|
int l1, l2;
|
||||||
|
l1 = gen_new_label();
|
||||||
|
l2 = gen_new_label();
|
||||||
|
|
||||||
|
temp = tcg_temp_local_new(TCG_TYPE_TL);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x40);
|
||||||
|
tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
|
||||||
|
tcg_gen_br(l2);
|
||||||
|
gen_set_label(l1);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x7f);
|
||||||
|
tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
|
||||||
|
gen_set_label(l2);
|
||||||
|
tcg_temp_free(temp);
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
}
|
||||||
/* srad & srad. */
|
/* srad & srad. */
|
||||||
__GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
|
GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B)
|
||||||
|
{
|
||||||
|
tcg_gen_helper_1_2(helper_srad, cpu_gpr[rA(ctx->opcode)],
|
||||||
|
cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
}
|
||||||
/* sradi & sradi. */
|
/* sradi & sradi. */
|
||||||
static always_inline void gen_sradi (DisasContext *ctx, int n)
|
static always_inline void gen_sradi (DisasContext *ctx, int n)
|
||||||
{
|
{
|
||||||
uint64_t mask;
|
int sh = SH(ctx->opcode) + (n << 5);
|
||||||
int sh, mb, me;
|
|
||||||
|
|
||||||
tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]);
|
|
||||||
sh = SH(ctx->opcode) + (n << 5);
|
|
||||||
if (sh != 0) {
|
if (sh != 0) {
|
||||||
tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);
|
int l1, l2;
|
||||||
mb = 64 - SH(ctx->opcode);
|
TCGv temp;
|
||||||
me = 63;
|
l1 = gen_new_label();
|
||||||
mask = MASK(mb, me);
|
l2 = gen_new_label();
|
||||||
gen_op_sradi(sh, mask >> 32, mask);
|
tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
|
||||||
|
temp = tcg_temp_new(TCG_TYPE_TL);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
|
||||||
|
tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
|
||||||
|
tcg_gen_ori_i32(cpu_xer, cpu_xer, 1 << XER_CA);
|
||||||
|
tcg_gen_br(l2);
|
||||||
|
gen_set_label(l1);
|
||||||
|
tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
|
||||||
|
gen_set_label(l2);
|
||||||
|
tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
|
||||||
|
} else {
|
||||||
|
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
|
||||||
|
tcg_gen_andi_i32(cpu_xer, cpu_xer, ~(1 << XER_CA));
|
||||||
}
|
}
|
||||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]);
|
|
||||||
if (unlikely(Rc(ctx->opcode) != 0))
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
gen_set_Rc0(ctx, cpu_T[0]);
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
}
|
}
|
||||||
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
|
GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
|
||||||
{
|
{
|
||||||
|
@ -1817,7 +1888,26 @@ GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
|
||||||
gen_sradi(ctx, 1);
|
gen_sradi(ctx, 1);
|
||||||
}
|
}
|
||||||
/* srd & srd. */
|
/* srd & srd. */
|
||||||
__GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
|
GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B)
|
||||||
|
{
|
||||||
|
TCGv temp;
|
||||||
|
int l1, l2;
|
||||||
|
l1 = gen_new_label();
|
||||||
|
l2 = gen_new_label();
|
||||||
|
|
||||||
|
temp = tcg_temp_local_new(TCG_TYPE_TL);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x40);
|
||||||
|
tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
|
||||||
|
tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
|
||||||
|
tcg_gen_br(l2);
|
||||||
|
gen_set_label(l1);
|
||||||
|
tcg_gen_andi_tl(temp, cpu_gpr[rB(ctx->opcode)], 0x7f);
|
||||||
|
tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], temp);
|
||||||
|
gen_set_label(l2);
|
||||||
|
tcg_temp_free(temp);
|
||||||
|
if (unlikely(Rc(ctx->opcode) != 0))
|
||||||
|
gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** Floating-Point arithmetic ***/
|
/*** Floating-Point arithmetic ***/
|
||||||
|
|
Loading…
Reference in New Issue