#include "helper_regs.h"
#include "op_helper.h"
-#define REG 0
-#include "op_template.h"
-
-#define REG 1
-#include "op_template.h"
-
-#define REG 2
-#include "op_template.h"
-
-#define REG 3
-#include "op_template.h"
-
-#define REG 4
-#include "op_template.h"
-
-#define REG 5
-#include "op_template.h"
-
-#define REG 6
-#include "op_template.h"
-
-#define REG 7
-#include "op_template.h"
-
-#define REG 8
-#include "op_template.h"
-
-#define REG 9
-#include "op_template.h"
-
-#define REG 10
-#include "op_template.h"
-
-#define REG 11
-#include "op_template.h"
-
-#define REG 12
-#include "op_template.h"
-
-#define REG 13
-#include "op_template.h"
-
-#define REG 14
-#include "op_template.h"
-
-#define REG 15
-#include "op_template.h"
-
-#define REG 16
-#include "op_template.h"
-
-#define REG 17
-#include "op_template.h"
-
-#define REG 18
-#include "op_template.h"
-
-#define REG 19
-#include "op_template.h"
-
-#define REG 20
-#include "op_template.h"
-
-#define REG 21
-#include "op_template.h"
-
-#define REG 22
-#include "op_template.h"
-
-#define REG 23
-#include "op_template.h"
-
-#define REG 24
-#include "op_template.h"
-
-#define REG 25
-#include "op_template.h"
-
-#define REG 26
-#include "op_template.h"
-
-#define REG 27
-#include "op_template.h"
-
-#define REG 28
-#include "op_template.h"
-
-#define REG 29
-#include "op_template.h"
-
-#define REG 30
-#include "op_template.h"
-
-#define REG 31
-#include "op_template.h"
-
-void OPPROTO op_print_mem_EA (void)
-{
- do_print_mem_EA(T0);
- RETURN();
-}
-
-/* PowerPC state maintenance operations */
-/* set_Rc0 */
-void OPPROTO op_set_Rc0 (void)
-{
- env->crf[0] = T0 | xer_so;
- RETURN();
-}
-
-/* Constants load */
-void OPPROTO op_reset_T0 (void)
-{
- T0 = 0;
- RETURN();
-}
-
-void OPPROTO op_set_T0 (void)
-{
- T0 = (uint32_t)PARAM1;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_set_T0_64 (void)
-{
- T0 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
- RETURN();
-}
-#endif
-
-void OPPROTO op_set_T1 (void)
-{
- T1 = (uint32_t)PARAM1;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_set_T1_64 (void)
-{
- T1 = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
- RETURN();
-}
-#endif
-
-#if 0 // unused
-void OPPROTO op_set_T2 (void)
-{
- T2 = (uint32_t)PARAM1;
- RETURN();
-}
-#endif
-
-void OPPROTO op_move_T1_T0 (void)
-{
- T1 = T0;
- RETURN();
-}
-
-void OPPROTO op_move_T2_T0 (void)
-{
- T2 = T0;
- RETURN();
-}
-
-void OPPROTO op_moven_T2_T0 (void)
-{
- T2 = ~T0;
- RETURN();
-}
-
/* Generate exceptions */
void OPPROTO op_raise_exception_err (void)
{
do_raise_exception_err(PARAM1, PARAM2);
}
-void OPPROTO op_update_nip (void)
-{
- env->nip = (uint32_t)PARAM1;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_update_nip_64 (void)
-{
- env->nip = ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
- RETURN();
-}
-#endif
-
void OPPROTO op_debug (void)
{
do_raise_exception(EXCP_DEBUG);
}
-void OPPROTO op_exit_tb (void)
-{
- EXIT_TB();
-}
-
/* Load/store special registers */
-void OPPROTO op_load_cr (void)
-{
- do_load_cr();
- RETURN();
-}
-
-void OPPROTO op_store_cr (void)
-{
- do_store_cr(PARAM1);
- RETURN();
-}
-
-void OPPROTO op_load_cro (void)
-{
- T0 = env->crf[PARAM1];
- RETURN();
-}
-
-void OPPROTO op_store_cro (void)
-{
- env->crf[PARAM1] = T0;
- RETURN();
-}
-
-void OPPROTO op_load_xer_cr (void)
-{
- T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
- RETURN();
-}
-
-void OPPROTO op_clear_xer_ov (void)
-{
- xer_so = 0;
- xer_ov = 0;
- RETURN();
-}
-
-void OPPROTO op_clear_xer_ca (void)
-{
- xer_ca = 0;
- RETURN();
-}
-
-void OPPROTO op_load_xer_bc (void)
-{
- T1 = xer_bc;
- RETURN();
-}
-
-void OPPROTO op_store_xer_bc (void)
-{
- xer_bc = T0;
- RETURN();
-}
-
-void OPPROTO op_load_xer (void)
-{
- T0 = hreg_load_xer(env);
- RETURN();
-}
-
-void OPPROTO op_store_xer (void)
-{
- hreg_store_xer(env, T0);
- RETURN();
-}
-
#if defined(TARGET_PPC64)
void OPPROTO op_store_pri (void)
{
RETURN();
}
-void OPPROTO op_load_lr (void)
-{
- T0 = env->lr;
- RETURN();
-}
-
-void OPPROTO op_store_lr (void)
-{
- env->lr = T0;
- RETURN();
-}
-
-void OPPROTO op_load_ctr (void)
-{
- T0 = env->ctr;
- RETURN();
-}
-
-void OPPROTO op_store_ctr (void)
-{
- env->ctr = T0;
- RETURN();
-}
-
void OPPROTO op_load_tbl (void)
{
T0 = cpu_ppc_load_tbl(env);
}
#endif
-#if defined(WORDS_BIGENDIAN)
-#define WORD0 0
-#define WORD1 1
-#else
-#define WORD0 1
-#define WORD1 0
-#endif
void OPPROTO op_load_fpscr_FT0 (void)
{
/* The 32 MSB of the target fpr are undefined.
* They'll be zero...
*/
- union {
- float64 d;
- struct {
- uint32_t u[2];
- } s;
- } u;
-
- u.s.u[WORD0] = 0;
- u.s.u[WORD1] = env->fpscr;
- FT0 = u.d;
- RETURN();
-}
+ CPU_DoubleU u;
-void OPPROTO op_set_FT0 (void)
-{
- union {
- float64 d;
- struct {
- uint32_t u[2];
- } s;
- } u;
-
- u.s.u[WORD0] = 0;
- u.s.u[WORD1] = PARAM1;
+ u.l.upper = 0;
+ u.l.lower = env->fpscr;
FT0 = u.d;
RETURN();
}
-#undef WORD0
-#undef WORD1
-
-void OPPROTO op_load_fpscr_T0 (void)
-{
- T0 = (env->fpscr >> PARAM1) & 0xF;
- RETURN();
-}
-
-void OPPROTO op_load_fpcc (void)
-{
- T0 = fpscr_fpcc;
- RETURN();
-}
void OPPROTO op_fpscr_resetbit (void)
{
}
/* Branch */
-#define EIP env->nip
-
void OPPROTO op_setlr (void)
{
env->lr = (uint32_t)PARAM1;
}
#endif
-void OPPROTO op_goto_tb0 (void)
-{
- GOTO_TB(op_goto_tb0, PARAM1, 0);
-}
-
-void OPPROTO op_goto_tb1 (void)
-{
- GOTO_TB(op_goto_tb1, PARAM1, 1);
-}
-
-void OPPROTO op_b_T1 (void)
-{
- env->nip = (uint32_t)(T1 & ~3);
- RETURN();
-}
-
-#if defined (TARGET_PPC64)
-void OPPROTO op_b_T1_64 (void)
-{
- env->nip = (uint64_t)(T1 & ~3);
- RETURN();
-}
-#endif
-
void OPPROTO op_jz_T0 (void)
{
if (!T0)
/*** Integer arithmetic ***/
/* add */
-void OPPROTO op_add (void)
-{
- T0 += T1;
- RETURN();
-}
-
void OPPROTO op_check_addo (void)
{
- xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
+ int ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
- xer_so |= xer_ov;
+ if (ov) {
+ env->xer |= (1 << XER_OV) | (1 << XER_SO);
+ } else {
+ env->xer &= ~(1 << XER_OV);
+ }
RETURN();
}
#if defined(TARGET_PPC64)
void OPPROTO op_check_addo_64 (void)
{
- xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
+ int ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
- xer_so |= xer_ov;
+ if (ov) {
+ env->xer |= (1 << XER_OV) | (1 << XER_SO);
+ } else {
+ env->xer &= ~(1 << XER_OV);
+ }
RETURN();
}
#endif
void OPPROTO op_check_addc (void)
{
if (likely((uint32_t)T0 >= (uint32_t)T2)) {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
} else {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
}
RETURN();
}
void OPPROTO op_check_addc_64 (void)
{
if (likely((uint64_t)T0 >= (uint64_t)T2)) {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
} else {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
}
RETURN();
}
}
#endif
-/* add immediate */
-void OPPROTO op_addi (void)
-{
- T0 += (int32_t)PARAM1;
- RETURN();
-}
-
/* add to minus one extended */
void OPPROTO op_add_me (void)
{
T0 += xer_ca + (-1);
if (likely((uint32_t)T1 != 0))
- xer_ca = 1;
- else
- xer_ca = 0;
+ env->xer |= (1 << XER_CA);
RETURN();
}
{
T0 += xer_ca + (-1);
if (likely((uint64_t)T1 != 0))
- xer_ca = 1;
- else
- xer_ca = 0;
+ env->xer |= (1 << XER_CA);
RETURN();
}
#endif
/* multiply low word */
void OPPROTO op_mullw (void)
{
+#if defined(TARGET_PPC64)
+ T0 = (int64_t)(int32_t)T0 * (int64_t)(int32_t)T1;
+#else
T0 = (int32_t)(T0 * T1);
+#endif
RETURN();
}
}
#endif
-/* subtract from */
-void OPPROTO op_subf (void)
-{
- T0 = T1 - T0;
- RETURN();
-}
-
/* subtract from carrying */
void OPPROTO op_check_subfc (void)
{
if (likely((uint32_t)T0 > (uint32_t)T1)) {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
} else {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
}
RETURN();
}
void OPPROTO op_check_subfc_64 (void)
{
if (likely((uint64_t)T0 > (uint64_t)T1)) {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
} else {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
}
RETURN();
}
{
T0 = (int32_t)PARAM1 + ~T0 + 1;
if ((uint32_t)T0 <= (uint32_t)PARAM1) {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
} else {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
}
RETURN();
}
{
T0 = (int64_t)PARAM1 + ~T0 + 1;
if ((uint64_t)T0 <= (uint64_t)PARAM1) {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
} else {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
}
RETURN();
}
{
T0 = ~T0 + xer_ca - 1;
if (likely((uint32_t)T0 != UINT32_MAX))
- xer_ca = 1;
- else
- xer_ca = 0;
+ env->xer |= (1 << XER_CA);
RETURN();
}
{
T0 = ~T0 + xer_ca - 1;
if (likely((uint64_t)T0 != UINT64_MAX))
- xer_ca = 1;
- else
- xer_ca = 0;
+ env->xer |= (1 << XER_CA);
RETURN();
}
#endif
T1 = ~T0;
T0 = T1 + xer_ca;
if ((uint32_t)T0 < (uint32_t)T1) {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
} else {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
}
RETURN();
}
T1 = ~T0;
T0 = T1 + xer_ca;
if ((uint64_t)T0 < (uint64_t)T1) {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
} else {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
}
RETURN();
}
}
#endif
-/*** Integer comparison ***/
-/* compare */
-void OPPROTO op_cmp (void)
-{
- if ((int32_t)T0 < (int32_t)T1) {
- T0 = 0x08;
- } else if ((int32_t)T0 > (int32_t)T1) {
- T0 = 0x04;
- } else {
- T0 = 0x02;
- }
- T0 |= xer_so;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_cmp_64 (void)
-{
- if ((int64_t)T0 < (int64_t)T1) {
- T0 = 0x08;
- } else if ((int64_t)T0 > (int64_t)T1) {
- T0 = 0x04;
- } else {
- T0 = 0x02;
- }
- T0 |= xer_so;
- RETURN();
-}
-#endif
-
-/* compare immediate */
-void OPPROTO op_cmpi (void)
-{
- if ((int32_t)T0 < (int32_t)PARAM1) {
- T0 = 0x08;
- } else if ((int32_t)T0 > (int32_t)PARAM1) {
- T0 = 0x04;
- } else {
- T0 = 0x02;
- }
- T0 |= xer_so;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_cmpi_64 (void)
-{
- if ((int64_t)T0 < (int64_t)((int32_t)PARAM1)) {
- T0 = 0x08;
- } else if ((int64_t)T0 > (int64_t)((int32_t)PARAM1)) {
- T0 = 0x04;
- } else {
- T0 = 0x02;
- }
- T0 |= xer_so;
- RETURN();
-}
-#endif
-
-/* compare logical */
-void OPPROTO op_cmpl (void)
-{
- if ((uint32_t)T0 < (uint32_t)T1) {
- T0 = 0x08;
- } else if ((uint32_t)T0 > (uint32_t)T1) {
- T0 = 0x04;
- } else {
- T0 = 0x02;
- }
- T0 |= xer_so;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_cmpl_64 (void)
-{
- if ((uint64_t)T0 < (uint64_t)T1) {
- T0 = 0x08;
- } else if ((uint64_t)T0 > (uint64_t)T1) {
- T0 = 0x04;
- } else {
- T0 = 0x02;
- }
- T0 |= xer_so;
- RETURN();
-}
-#endif
-
-/* compare logical immediate */
-void OPPROTO op_cmpli (void)
-{
- if ((uint32_t)T0 < (uint32_t)PARAM1) {
- T0 = 0x08;
- } else if ((uint32_t)T0 > (uint32_t)PARAM1) {
- T0 = 0x04;
- } else {
- T0 = 0x02;
- }
- T0 |= xer_so;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_cmpli_64 (void)
-{
- if ((uint64_t)T0 < (uint64_t)PARAM1) {
- T0 = 0x08;
- } else if ((uint64_t)T0 > (uint64_t)PARAM1) {
- T0 = 0x04;
- } else {
- T0 = 0x02;
- }
- T0 |= xer_so;
- RETURN();
-}
-#endif
-
-void OPPROTO op_isel (void)
-{
- if (T0)
- T0 = T1;
- else
- T0 = T2;
- RETURN();
-}
-
void OPPROTO op_popcntb (void)
{
do_popcntb();
RETURN();
}
-/* andi. */
-void OPPROTO op_andi_T0 (void)
-{
- T0 &= (uint32_t)PARAM1;
- RETURN();
-}
-
-void OPPROTO op_andi_T1 (void)
-{
- T1 &= (uint32_t)PARAM1;
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_andi_T0_64 (void)
-{
- T0 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
- RETURN();
-}
-
-void OPPROTO op_andi_T1_64 (void)
-{
- T1 &= ((uint64_t)PARAM1 << 32) | (uint64_t)PARAM2;
- RETURN();
-}
-#endif
-
/* count leading zero */
void OPPROTO op_cntlzw (void)
{
T0 = (int32_t)T0 >> PARAM1;
if ((int32_t)T1 < 0 && (T1 & mask) != 0) {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
} else {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
}
RETURN();
}
T0 = (int64_t)T0 >> PARAM1;
if ((int64_t)T1 < 0 && ((uint64_t)T1 & mask) != 0) {
- xer_ca = 1;
+ env->xer |= (1 << XER_CA);
} else {
- xer_ca = 0;
+ env->xer &= ~(1 << XER_CA);
}
RETURN();
}
RETURN();
}
-void OPPROTO op_sli_T1 (void)
-{
- T1 = T1 << PARAM1;
- RETURN();
-}
-
void OPPROTO op_srl_T0_T1 (void)
{
T0 = (uint32_t)T0 >> T1;
RETURN();
}
-/*** Floating-Point compare ***/
-/* fcmpu */
-void OPPROTO op_fcmpu (void)
-{
- do_fcmpu();
- RETURN();
-}
-
-/* fcmpo */
-void OPPROTO op_fcmpo (void)
-{
- do_fcmpo();
- RETURN();
-}
-
/*** Floating-point move ***/
/* fabs */
void OPPROTO op_fabs (void)
/* nabs never overflows */
if (T0 > 0)
T0 = -T0;
- xer_ov = 0;
+ env->xer &= ~(1 << XER_OV);
RETURN();
}
void OPPROTO op_405_check_ovu (void)
{
if (likely(T0 >= T2)) {
- xer_ov = 0;
+ env->xer &= ~(1 << XER_OV);
} else {
- xer_ov = 1;
- xer_so = 1;
+ env->xer |= (1 << XER_OV) | (1 << XER_SO);
}
RETURN();
}
RETURN();
}
-void OPPROTO op_evand (void)
-{
- T0_64 &= T1_64;
- RETURN();
-}
-
-void OPPROTO op_evandc (void)
-{
- T0_64 &= ~T1_64;
- RETURN();
-}
-
-void OPPROTO op_evor (void)
-{
- T0_64 |= T1_64;
- RETURN();
-}
-
-void OPPROTO op_evxor (void)
-{
- T0_64 ^= T1_64;
- RETURN();
-}
-
-void OPPROTO op_eveqv (void)
-{
- T0_64 = ~(T0_64 ^ T1_64);
- RETURN();
-}
-
-void OPPROTO op_evnor (void)
-{
- T0_64 = ~(T0_64 | T1_64);
- RETURN();
-}
-
-void OPPROTO op_evorc (void)
-{
- T0_64 |= ~T1_64;
- RETURN();
-}
-
-void OPPROTO op_evnand (void)
-{
- T0_64 = ~(T0_64 & T1_64);
- RETURN();
-}
-
void OPPROTO op_evsrws (void)
{
do_evsrws();
void OPPROTO op_efdsub (void)
{
- union {
- uint64_t u;
- float64 f;
- } u1, u2;
- u1.u = T0_64;
- u2.u = T1_64;
- u1.f = float64_sub(u1.f, u2.f, &env->spe_status);
- T0_64 = u1.u;
+ CPU_DoubleU u1, u2;
+ u1.ll = T0_64;
+ u2.ll = T1_64;
+ u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
+ T0_64 = u1.ll;
RETURN();
}
void OPPROTO op_efdadd (void)
{
- union {
- uint64_t u;
- float64 f;
- } u1, u2;
- u1.u = T0_64;
- u2.u = T1_64;
- u1.f = float64_add(u1.f, u2.f, &env->spe_status);
- T0_64 = u1.u;
+ CPU_DoubleU u1, u2;
+ u1.ll = T0_64;
+ u2.ll = T1_64;
+ u1.d = float64_add(u1.d, u2.d, &env->spe_status);
+ T0_64 = u1.ll;
RETURN();
}
void OPPROTO op_efddiv (void)
{
- union {
- uint64_t u;
- float64 f;
- } u1, u2;
- u1.u = T0_64;
- u2.u = T1_64;
- u1.f = float64_div(u1.f, u2.f, &env->spe_status);
- T0_64 = u1.u;
+ CPU_DoubleU u1, u2;
+ u1.ll = T0_64;
+ u2.ll = T1_64;
+ u1.d = float64_div(u1.d, u2.d, &env->spe_status);
+ T0_64 = u1.ll;
RETURN();
}
void OPPROTO op_efdmul (void)
{
- union {
- uint64_t u;
- float64 f;
- } u1, u2;
- u1.u = T0_64;
- u2.u = T1_64;
- u1.f = float64_mul(u1.f, u2.f, &env->spe_status);
- T0_64 = u1.u;
+ CPU_DoubleU u1, u2;
+ u1.ll = T0_64;
+ u2.ll = T1_64;
+ u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
+ T0_64 = u1.ll;
RETURN();
}