summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-06-09 16:18:19 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-06-09 16:18:19 +0000
commit748e83917aa691852b7226ba8426cb6abac93739 (patch)
tree626edd2f4f92a4bd40c77685bc8fad6ac5dbedf4 /src
parent7ebd242d8b2599d73fca136450345e720c6f0b1d (diff)
PPC DRC:
* minor flags optimizations: - broke CR into several individual bits of state - extracted the SO bit from XER into its own state
Diffstat (limited to 'src')
-rw-r--r--src/emu/cpu/powerpc/ppccom.c67
-rw-r--r--src/emu/cpu/powerpc/ppccom.h11
-rw-r--r--src/emu/cpu/powerpc/ppcdrc.c478
3 files changed, 311 insertions, 245 deletions
diff --git a/src/emu/cpu/powerpc/ppccom.c b/src/emu/cpu/powerpc/ppccom.c
index 755bd5994ac..d0f6353e583 100644
--- a/src/emu/cpu/powerpc/ppccom.c
+++ b/src/emu/cpu/powerpc/ppccom.c
@@ -106,6 +106,61 @@ INLINE int tlb_entry_allocate(powerpc_state *ppc, int entrynum, offs_t address,
/*-------------------------------------------------
+ get_cr - return the current CR value
+-------------------------------------------------*/
+
+INLINE UINT32 get_cr(powerpc_state *ppc)
+{
+ return ((ppc->cr[0] & 0x0f) << 28) |
+ ((ppc->cr[1] & 0x0f) << 24) |
+ ((ppc->cr[2] & 0x0f) << 20) |
+ ((ppc->cr[3] & 0x0f) << 16) |
+ ((ppc->cr[4] & 0x0f) << 12) |
+ ((ppc->cr[5] & 0x0f) << 8) |
+ ((ppc->cr[6] & 0x0f) << 4) |
+ ((ppc->cr[7] & 0x0f) << 0);
+}
+
+
+/*-------------------------------------------------
+ set_cr - set the current CR value
+-------------------------------------------------*/
+
+INLINE void set_cr(powerpc_state *ppc, UINT32 value)
+{
+ ppc->cr[0] = value >> 28;
+ ppc->cr[1] = value >> 24;
+ ppc->cr[2] = value >> 20;
+ ppc->cr[3] = value >> 16;
+ ppc->cr[4] = value >> 12;
+ ppc->cr[5] = value >> 8;
+ ppc->cr[6] = value >> 4;
+ ppc->cr[7] = value >> 0;
+}
+
+
+/*-------------------------------------------------
+ get_xer - return the current XER value
+-------------------------------------------------*/
+
+INLINE UINT32 get_xer(powerpc_state *ppc)
+{
+ return ppc->spr[SPR_XER] | (ppc->xerso << 31);
+}
+
+
+/*-------------------------------------------------
+ set_xer - set the current XER value
+-------------------------------------------------*/
+
+INLINE void set_xer(powerpc_state *ppc, UINT32 value)
+{
+ ppc->spr[SPR_XER] = value & ~XER_SO;
+ ppc->xerso = value >> 31;
+}
+
+
+/*-------------------------------------------------
get_timebase - return the current timebase
value
-------------------------------------------------*/
@@ -984,10 +1039,10 @@ void ppccom_set_info(powerpc_state *ppc, UINT32 state, cpuinfo *info)
case CPUINFO_INT_PC:
case CPUINFO_INT_REGISTER + PPC_PC: ppc->pc = info->i; break;
case CPUINFO_INT_REGISTER + PPC_MSR: ppc->msr = info->i; break;
- case CPUINFO_INT_REGISTER + PPC_CR: ppc->cr = info->i; break;
+ case CPUINFO_INT_REGISTER + PPC_CR: set_cr(ppc, info->i); break;
case CPUINFO_INT_REGISTER + PPC_LR: ppc->spr[SPR_LR] = info->i; break;
case CPUINFO_INT_REGISTER + PPC_CTR: ppc->spr[SPR_CTR] = info->i; break;
- case CPUINFO_INT_REGISTER + PPC_XER: ppc->spr[SPR_XER] = info->i; break;
+ case CPUINFO_INT_REGISTER + PPC_XER: set_xer(ppc, info->i); break;
case CPUINFO_INT_REGISTER + PPC_SRR0: ppc->spr[SPROEA_SRR0] = info->i; break;
case CPUINFO_INT_REGISTER + PPC_SRR1: ppc->spr[SPROEA_SRR1] = info->i; break;
case CPUINFO_INT_REGISTER + PPC_SPRG0: ppc->spr[SPROEA_SPRG0] = info->i; break;
@@ -1074,10 +1129,10 @@ void ppccom_get_info(powerpc_state *ppc, UINT32 state, cpuinfo *info)
case CPUINFO_INT_PC:
case CPUINFO_INT_REGISTER + PPC_PC: info->i = ppc->pc; break;
case CPUINFO_INT_REGISTER + PPC_MSR: info->i = ppc->msr; break;
- case CPUINFO_INT_REGISTER + PPC_CR: info->i = ppc->cr; break;
+ case CPUINFO_INT_REGISTER + PPC_CR: info->i = get_cr(ppc); break;
case CPUINFO_INT_REGISTER + PPC_LR: info->i = ppc->spr[SPR_LR]; break;
case CPUINFO_INT_REGISTER + PPC_CTR: info->i = ppc->spr[SPR_CTR]; break;
- case CPUINFO_INT_REGISTER + PPC_XER: info->i = ppc->spr[SPR_XER]; break;
+ case CPUINFO_INT_REGISTER + PPC_XER: info->i = get_xer(ppc); break;
case CPUINFO_INT_REGISTER + PPC_SRR0: info->i = ppc->spr[SPROEA_SRR0]; break;
case CPUINFO_INT_REGISTER + PPC_SRR1: info->i = ppc->spr[SPROEA_SRR1]; break;
case CPUINFO_INT_REGISTER + PPC_SPRG0: info->i = ppc->spr[SPROEA_SPRG0]; break;
@@ -1150,10 +1205,10 @@ void ppccom_get_info(powerpc_state *ppc, UINT32 state, cpuinfo *info)
case CPUINFO_STR_REGISTER + PPC_PC: sprintf(info->s, "PC: %08X", ppc->pc); break;
case CPUINFO_STR_REGISTER + PPC_MSR: sprintf(info->s, "MSR:%08X", ppc->msr); break;
- case CPUINFO_STR_REGISTER + PPC_CR: sprintf(info->s, "CR: %08X", ppc->cr); break;
+ case CPUINFO_STR_REGISTER + PPC_CR: sprintf(info->s, "CR: %08X", get_cr(ppc)); break;
case CPUINFO_STR_REGISTER + PPC_LR: sprintf(info->s, "LR: %08X", ppc->spr[SPR_LR]); break;
case CPUINFO_STR_REGISTER + PPC_CTR: sprintf(info->s, "CTR:%08X", ppc->spr[SPR_CTR]); break;
- case CPUINFO_STR_REGISTER + PPC_XER: sprintf(info->s, "XER:%08X", ppc->spr[SPR_XER]); break;
+ case CPUINFO_STR_REGISTER + PPC_XER: sprintf(info->s, "XER:%08X", get_xer(ppc)); break;
case CPUINFO_STR_REGISTER + PPC_SRR0: sprintf(info->s, "SRR0: %08X", ppc->spr[SPROEA_SRR0]); break;
case CPUINFO_STR_REGISTER + PPC_SRR1: sprintf(info->s, "SRR1: %08X", ppc->spr[SPROEA_SRR1]); break;
case CPUINFO_STR_REGISTER + PPC_SPRG0: sprintf(info->s, "SPRG0: %08X", ppc->spr[SPROEA_SPRG0]); break;
diff --git a/src/emu/cpu/powerpc/ppccom.h b/src/emu/cpu/powerpc/ppccom.h
index 7eb79fc4370..17cac4c3c23 100644
--- a/src/emu/cpu/powerpc/ppccom.h
+++ b/src/emu/cpu/powerpc/ppccom.h
@@ -14,14 +14,6 @@
/***************************************************************************
- WIDE-SCALE CONTROLS
-***************************************************************************/
-
-#define SIMULATE_603_TLB (0)
-
-
-
-/***************************************************************************
CONSTANTS
***************************************************************************/
@@ -524,7 +516,8 @@ struct _powerpc_state
int icount;
UINT32 r[32];
double f[32];
- UINT32 cr;
+ UINT32 cr[8];
+ UINT32 xerso;
UINT32 fpscr;
UINT32 msr;
UINT32 sr[16];
diff --git a/src/emu/cpu/powerpc/ppcdrc.c b/src/emu/cpu/powerpc/ppcdrc.c
index 910735aeb58..e45b6a7ba05 100644
--- a/src/emu/cpu/powerpc/ppcdrc.c
+++ b/src/emu/cpu/powerpc/ppcdrc.c
@@ -90,9 +90,10 @@ extern offs_t ppc_dasm_one(char *buffer, UINT32 pc, UINT32 op);
#define R32(reg) ppc->impstate->regmap[reg].type, ppc->impstate->regmap[reg].value
#define R32Z(reg) (((reg) == 0) ? DRCUML_PTYPE_IMMEDIATE : ppc->impstate->regmap[reg].type), (((reg) == 0) ? 0 : ppc->impstate->regmap[reg].value)
#define F64(reg) ppc->impstate->fdregmap[reg].type, ppc->impstate->fdregmap[reg].value
-#define CR32 MEM(&ppc->cr)
+#define CR32(reg) MEM(&ppc->cr[reg])
#define FPSCR32 MEM(&ppc->fpscr)
#define MSR32 MEM(&ppc->msr)
+#define XERSO32 MEM(&ppc->xerso)
#define SR32(reg) MEM(&ppc->sr[reg])
#define SPR32(reg) MEM(&ppc->spr[reg])
@@ -184,10 +185,10 @@ struct _ppcimp_state
/* tables */
UINT8 fpmode[4]; /* FPU mode table */
- UINT32 sz_cr_table[32]; /* SZ CR table */
- UINT32 cmp_cr_table[32]; /* CMP CR table */
- UINT32 cmpl_cr_table[32]; /* CMPL CR table */
- UINT32 fcmp_cr_table[32]; /* FCMP CR table */
+ UINT8 sz_cr_table[32]; /* SZ CR table */
+ UINT8 cmp_cr_table[32]; /* CMP CR table */
+ UINT8 cmpl_cr_table[32]; /* CMPL CR table */
+ UINT8 fcmp_cr_table[32]; /* FCMP CR table */
/* internal stuff */
UINT8 cache_dirty; /* true if we need to flush the cache */
@@ -289,151 +290,151 @@ static const UINT8 fpmode_source[4] =
};
/* flag lookup table for SZ */
-static const UINT32 sz_cr_table_source[32] =
+static const UINT8 sz_cr_table_source[32] =
{
- /* ..... */ 0x40000000,
- /* ....C */ 0x42000000,
- /* ...V. */ 0x4c000000,
- /* ...VC */ 0x4e000000,
- /* ..Z.. */ 0x20000000,
- /* ..Z.C */ 0x22000000,
- /* ..ZV. */ 0x2c000000,
- /* ..ZVC */ 0x2e000000,
- /* .S... */ 0x80000000,
- /* .S..C */ 0x82000000,
- /* .S.V. */ 0x8c000000,
- /* .S.VC */ 0x8e000000,
- /* .SZ.. */ 0x20000000,
- /* .SZ.C */ 0x22000000,
- /* .SZV. */ 0x2c000000,
- /* .SZVC */ 0x2e000000,
- /* U.... */ 0x40000000,
- /* U...C */ 0x42000000,
- /* U..V. */ 0x4c000000,
- /* U..VC */ 0x4e000000,
- /* U.Z.. */ 0x20000000,
- /* U.Z.C */ 0x22000000,
- /* U.ZV. */ 0x2c000000,
- /* U.ZVC */ 0x2e000000,
- /* US... */ 0x80000000,
- /* US..C */ 0x82000000,
- /* US.V. */ 0x8c000000,
- /* US.VC */ 0x8e000000,
- /* USZ.. */ 0x20000000,
- /* USZ.C */ 0x22000000,
- /* USZV. */ 0x2c000000,
- /* USZVC */ 0x2e000000
+ /* ..... */ 0x4,
+ /* ....C */ 0x4,
+ /* ...V. */ 0x4,
+ /* ...VC */ 0x4,
+ /* ..Z.. */ 0x2,
+ /* ..Z.C */ 0x2,
+ /* ..ZV. */ 0x2,
+ /* ..ZVC */ 0x2,
+ /* .S... */ 0x8,
+ /* .S..C */ 0x8,
+ /* .S.V. */ 0x8,
+ /* .S.VC */ 0x8,
+ /* .SZ.. */ 0x2,
+ /* .SZ.C */ 0x2,
+ /* .SZV. */ 0x2,
+ /* .SZVC */ 0x2,
+ /* U.... */ 0x4,
+ /* U...C */ 0x4,
+ /* U..V. */ 0x4,
+ /* U..VC */ 0x4,
+ /* U.Z.. */ 0x2,
+ /* U.Z.C */ 0x2,
+ /* U.ZV. */ 0x2,
+ /* U.ZVC */ 0x2,
+ /* US... */ 0x8,
+ /* US..C */ 0x8,
+ /* US.V. */ 0x8,
+ /* US.VC */ 0x8,
+ /* USZ.. */ 0x2,
+ /* USZ.C */ 0x2,
+ /* USZV. */ 0x2,
+ /* USZVC */ 0x2
};
/* flag lookup table for CMP */
-static const UINT32 cmp_cr_table_source[32] =
+static const UINT8 cmp_cr_table_source[32] =
{
- /* ..... */ 0x44444444,
- /* ....C */ 0x44444444,
- /* ...V. */ 0x88888888,
- /* ...VC */ 0x88888888,
- /* ..Z.. */ 0x22222222,
- /* ..Z.C */ 0x22222222,
- /* ..ZV. */ 0x22222222,
- /* ..ZVC */ 0x22222222,
- /* .S... */ 0x88888888,
- /* .S..C */ 0x88888888,
- /* .S.V. */ 0x44444444,
- /* .S.VC */ 0x44444444,
- /* .SZ.. */ 0x22222222,
- /* .SZ.C */ 0x22222222,
- /* .SZV. */ 0x22222222,
- /* .SZVC */ 0x22222222,
- /* U.... */ 0x44444444,
- /* U...C */ 0x44444444,
- /* U..V. */ 0x88888888,
- /* U..VC */ 0x88888888,
- /* U.Z.. */ 0x22222222,
- /* U.Z.C */ 0x22222222,
- /* U.ZV. */ 0x22222222,
- /* U.ZVC */ 0x22222222,
- /* US... */ 0x88888888,
- /* US..C */ 0x88888888,
- /* US.V. */ 0x44444444,
- /* US.VC */ 0x44444444,
- /* USZ.. */ 0x22222222,
- /* USZ.C */ 0x22222222,
- /* USZV. */ 0x22222222,
- /* USZVC */ 0x22222222
+ /* ..... */ 0x4,
+ /* ....C */ 0x4,
+ /* ...V. */ 0x8,
+ /* ...VC */ 0x8,
+ /* ..Z.. */ 0x2,
+ /* ..Z.C */ 0x2,
+ /* ..ZV. */ 0x2,
+ /* ..ZVC */ 0x2,
+ /* .S... */ 0x8,
+ /* .S..C */ 0x8,
+ /* .S.V. */ 0x4,
+ /* .S.VC */ 0x4,
+ /* .SZ.. */ 0x2,
+ /* .SZ.C */ 0x2,
+ /* .SZV. */ 0x2,
+ /* .SZVC */ 0x2,
+ /* U.... */ 0x4,
+ /* U...C */ 0x4,
+ /* U..V. */ 0x8,
+ /* U..VC */ 0x8,
+ /* U.Z.. */ 0x2,
+ /* U.Z.C */ 0x2,
+ /* U.ZV. */ 0x2,
+ /* U.ZVC */ 0x2,
+ /* US... */ 0x8,
+ /* US..C */ 0x8,
+ /* US.V. */ 0x4,
+ /* US.VC */ 0x4,
+ /* USZ.. */ 0x2,
+ /* USZ.C */ 0x2,
+ /* USZV. */ 0x2,
+ /* USZVC */ 0x2
};
/* flag lookup table for CMPL */
-static const UINT32 cmpl_cr_table_source[32] =
+static const UINT8 cmpl_cr_table_source[32] =
{
- /* ..... */ 0x44444444,
- /* ....C */ 0x88888888,
- /* ...V. */ 0x44444444,
- /* ...VC */ 0x88888888,
- /* ..Z.. */ 0x22222222,
- /* ..Z.C */ 0x22222222,
- /* ..ZV. */ 0x22222222,
- /* ..ZVC */ 0x22222222,
- /* .S... */ 0x44444444,
- /* .S..C */ 0x88888888,
- /* .S.V. */ 0x44444444,
- /* .S.VC */ 0x88888888,
- /* .SZ.. */ 0x22222222,
- /* .SZ.C */ 0x22222222,
- /* .SZV. */ 0x22222222,
- /* .SZVC */ 0x22222222,
- /* U.... */ 0x44444444,
- /* U...C */ 0x88888888,
- /* U..V. */ 0x44444444,
- /* U..VC */ 0x88888888,
- /* U.Z.. */ 0x22222222,
- /* U.Z.C */ 0x22222222,
- /* U.ZV. */ 0x22222222,
- /* U.ZVC */ 0x22222222,
- /* US... */ 0x44444444,
- /* US..C */ 0x88888888,
- /* US.V. */ 0x44444444,
- /* US.VC */ 0x88888888,
- /* USZ.. */ 0x22222222,
- /* USZ.C */ 0x22222222,
- /* USZV. */ 0x22222222,
- /* USZVC */ 0x22222222
+ /* ..... */ 0x4,
+ /* ....C */ 0x8,
+ /* ...V. */ 0x4,
+ /* ...VC */ 0x8,
+ /* ..Z.. */ 0x2,
+ /* ..Z.C */ 0x2,
+ /* ..ZV. */ 0x2,
+ /* ..ZVC */ 0x2,
+ /* .S... */ 0x4,
+ /* .S..C */ 0x8,
+ /* .S.V. */ 0x4,
+ /* .S.VC */ 0x8,
+ /* .SZ.. */ 0x2,
+ /* .SZ.C */ 0x2,
+ /* .SZV. */ 0x2,
+ /* .SZVC */ 0x2,
+ /* U.... */ 0x4,
+ /* U...C */ 0x8,
+ /* U..V. */ 0x4,
+ /* U..VC */ 0x8,
+ /* U.Z.. */ 0x2,
+ /* U.Z.C */ 0x2,
+ /* U.ZV. */ 0x2,
+ /* U.ZVC */ 0x2,
+ /* US... */ 0x4,
+ /* US..C */ 0x8,
+ /* US.V. */ 0x4,
+ /* US.VC */ 0x8,
+ /* USZ.. */ 0x2,
+ /* USZ.C */ 0x2,
+ /* USZV. */ 0x2,
+ /* USZVC */ 0x2
};
/* flag lookup table for FCMP */
-static const UINT32 fcmp_cr_table_source[32] =
+static const UINT8 fcmp_cr_table_source[32] =
{
- /* ..... */ 0x44444444,
- /* ....C */ 0x88888888,
- /* ...V. */ 0x44444444,
- /* ...VC */ 0x88888888,
- /* ..Z.. */ 0x22222222,
- /* ..Z.C */ 0xaaaaaaaa,
- /* ..ZV. */ 0x22222222,
- /* ..ZVC */ 0xaaaaaaaa,
- /* .S... */ 0x44444444,
- /* .S..C */ 0x88888888,
- /* .S.V. */ 0x44444444,
- /* .S.VC */ 0x88888888,
- /* .SZ.. */ 0x22222222,
- /* .SZ.C */ 0xaaaaaaaa,
- /* .SZV. */ 0x22222222,
- /* .SZVC */ 0xaaaaaaaa,
- /* U.... */ 0x55555555,
- /* U...C */ 0x99999999,
- /* U..V. */ 0x55555555,
- /* U..VC */ 0x99999999,
- /* U.Z.. */ 0x33333333,
- /* U.Z.C */ 0xbbbbbbbb,
- /* U.ZV. */ 0x33333333,
- /* U.ZVC */ 0xbbbbbbbb,
- /* US... */ 0x55555555,
- /* US..C */ 0x99999999,
- /* US.V. */ 0x55555555,
- /* US.VC */ 0x99999999,
- /* USZ.. */ 0x33333333,
- /* USZ.C */ 0xbbbbbbbb,
- /* USZV. */ 0x33333333,
- /* USZVC */ 0xbbbbbbbb
+ /* ..... */ 0x4,
+ /* ....C */ 0x8,
+ /* ...V. */ 0x4,
+ /* ...VC */ 0x8,
+ /* ..Z.. */ 0x2,
+ /* ..Z.C */ 0xa,
+ /* ..ZV. */ 0x2,
+ /* ..ZVC */ 0xa,
+ /* .S... */ 0x4,
+ /* .S..C */ 0x8,
+ /* .S.V. */ 0x4,
+ /* .S.VC */ 0x8,
+ /* .SZ.. */ 0x2,
+ /* .SZ.C */ 0xa,
+ /* .SZV. */ 0x2,
+ /* .SZVC */ 0xa,
+ /* U.... */ 0x5,
+ /* U...C */ 0x9,
+ /* U..V. */ 0x5,
+ /* U..VC */ 0x9,
+ /* U.Z.. */ 0x3,
+ /* U.Z.C */ 0xb,
+ /* U.ZV. */ 0x3,
+ /* U.ZVC */ 0xb,
+ /* US... */ 0x5,
+ /* US..C */ 0x9,
+ /* US.V. */ 0x5,
+ /* US.VC */ 0x9,
+ /* USZ.. */ 0x3,
+ /* USZ.C */ 0xb,
+ /* USZV. */ 0x3,
+ /* USZVC */ 0xb
};
@@ -598,7 +599,12 @@ static void ppcdrc_init(powerpc_flavor flavor, UINT8 cap, int tb_divisor, int cl
sprintf(buf, "fpr%d", regnum);
drcuml_symbol_add(ppc->impstate->drcuml, &ppc->f[regnum], sizeof(ppc->r[regnum]), buf);
}
- drcuml_symbol_add(ppc->impstate->drcuml, &ppc->cr, sizeof(ppc->cr), "cr");
+ for (regnum = 0; regnum < 8; regnum++)
+ {
+ char buf[10];
+ sprintf(buf, "cr%d", regnum);
+ drcuml_symbol_add(ppc->impstate->drcuml, &ppc->cr[regnum], sizeof(ppc->cr[regnum]), buf);
+ }
drcuml_symbol_add(ppc->impstate->drcuml, &ppc->fpscr, sizeof(ppc->fpscr), "fpscr");
drcuml_symbol_add(ppc->impstate->drcuml, &ppc->msr, sizeof(ppc->msr), "msr");
drcuml_symbol_add(ppc->impstate->drcuml, &ppc->sr, sizeof(ppc->sr), "sr");
@@ -1316,7 +1322,7 @@ static void static_generate_exception(drcuml_state *drcuml, UINT8 exception, int
else if (exception == EXCEPTION_DTLBMISSL)
UML_OR(block, SPR32(SPROEA_SRR1), SPR32(SPROEA_SRR1), IMM(0x00010000)); // or [srr1],0x00010000
if (exception == EXCEPTION_ITLBMISS || exception == EXCEPTION_DTLBMISSL || exception == EXCEPTION_DTLBMISSS)
- UML_ROLINS(block, SPR32(SPROEA_SRR1), CR32, IMM(0), IMM(CRMASK(0))); // rolins [srr1],[cr],0,crmask(0)
+ UML_ROLINS(block, SPR32(SPROEA_SRR1), CR32(0), IMM(28), IMM(CRMASK(0))); // rolins [srr1],[cr0],28,crmask(0)
}
/* update MSR */
@@ -1484,7 +1490,7 @@ static void static_generate_memory_accessor(drcuml_state *drcuml, int mode, int
if (((ppc->cap & PPCCAP_OEA) && (mode & MODE_DATA_TRANSLATION)) || (iswrite && (ppc->cap & PPCCAP_4XX) && (mode & MODE_PROTECTION)))
{
UML_SHR(block, IREG(3), IREG(0), IMM(12)); // shr i3,i0,12
- UML_LOAD(block, IREG(3), ppc->tlb_table, IREG(3), DWORD); // load i3,[tlb_table],i3,dword
+ UML_LOAD(block, IREG(3), ppc->tlb_table, IREG(3), BYTE); // load i3,[tlb_table],i3,byte
UML_TEST(block, IREG(3), IMM(iswrite ? TLB_WRITE : TLB_READ)); // test i3,iswrite ? TLB_WRITE : TLB_READ
UML_JMPc(block, IF_Z, tlbmiss = label++); // jmp tlbmiss,z
UML_LABEL(block, tlbreturn = label++); // tlbreturn:
@@ -1779,7 +1785,7 @@ static void static_generate_memory_accessor(drcuml_state *drcuml, int mode, int
UML_CMP(block, MEM(&ppc->param0), IMM(1)); // cmp [param0],1
UML_JMPc(block, IF_A, dsi = label++); // jmp dsi,A
UML_SHR(block, IREG(3), IREG(0), IMM(12)); // shr i3,i0,12
- UML_LOAD(block, IREG(3), ppc->tlb_table, IREG(3), DWORD); // load i3,[tlb_table],i3,dword
+ UML_LOAD(block, IREG(3), ppc->tlb_table, IREG(3), BYTE); // load i3,[tlb_table],i3,byte
UML_JMP(block, tlbreturn); // jmp tlbreturn
UML_LABEL(block, dsi); // dsi:
@@ -2196,7 +2202,6 @@ static void generate_sequence_instruction(drcuml_block *block, compiler_state *c
static void generate_compute_flags(drcuml_block *block, int updatecr, UINT32 xermask, int invertcarry)
{
int xerflags = ((xermask & XER_OV) ? DRCUML_FLAG_V : 0) | ((xermask & XER_CA) ? DRCUML_FLAG_C : 0);
- UINT32 xermask_so = xermask | ((xermask & XER_OV) ? XER_SO : 0);
/* easy case: nothing to do */
if (!updatecr && xermask == 0)
@@ -2205,13 +2210,9 @@ static void generate_compute_flags(drcuml_block *block, int updatecr, UINT32 xer
/* semi-easy case: crfield only */
if (xermask == 0)
{
- UML_MOV(block, IREG(0), CR32); // mov i0,cr32
- UML_GETFLGS(block, IREG(1), DRCUML_FLAG_S | DRCUML_FLAG_Z); // getflgs i1,sz
- UML_LOAD(block, IREG(1), ppc->impstate->sz_cr_table, IREG(1), DWORD); // load i1,sz_cr_table,i1,dword
- UML_ROLINS(block, IREG(0), IREG(1), IMM(0), IMM(CRMASK(0))); // rolins i0,i1,0,crmask(field)
- UML_AND(block, IREG(1), SPR32(SPR_XER), IMM(XER_SO)); // and i1,[xer],XER_SO
- UML_SHR(block, IREG(1), IREG(1), IMM(3)); // shr i1,i1,3
- UML_OR(block, CR32, IREG(0), IREG(1)); // or [cr],i0,i1
+ UML_GETFLGS(block, IREG(0), DRCUML_FLAG_S | DRCUML_FLAG_Z); // getflgs i0,sz
+ UML_LOAD(block, IREG(0), ppc->impstate->sz_cr_table, IREG(0), BYTE); // load i0,sz_cr_table,i0,byte
+ UML_OR(block, CR32(0), IREG(0), XERSO32); // or [cr0],i0,[xerso]
return;
}
@@ -2220,14 +2221,12 @@ static void generate_compute_flags(drcuml_block *block, int updatecr, UINT32 xer
{
if (xermask & XER_OV)
{
- UML_MOV(block, IREG(0), SPR32(SPR_XER)); // mov i0,[xer]
- UML_GETFLGS(block, IREG(1), xerflags); // getflgs i1,xerflags
+ UML_GETFLGS(block, IREG(0), xerflags); // getflgs i0,xerflags
if (invertcarry && (xermask & XER_CA))
- UML_XOR(block, IREG(1), IREG(1), IMM(DRCUML_FLAG_C)); // xor i1,i1,FLAG_C
- UML_ROLINS(block, IREG(0), IREG(1), IMM(29), IMM(xermask)); // rolins i0,i1,29,crmask(xermask)
- UML_AND(block, IREG(1), SPR32(SPR_XER), IMM(XER_OV)); // and i1,[xer],XER_OV
- UML_SHL(block, IREG(1), IREG(1), IMM(1)); // shl i1,i1,1
- UML_OR(block, SPR32(SPR_XER), IREG(0), IREG(1)); // or [xer],i0,i1
+ UML_XOR(block, IREG(0), IREG(0), IMM(DRCUML_FLAG_C)); // xor i0,i0,FLAG_C
+ UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(xermask)); // rolins [xer],i0,29,xermask
+ UML_SHR(block, IREG(0), IREG(0), IMM(1)); // shr i0,i0,1
+ UML_OR(block, XERSO32, XERSO32, IREG(0)); // or [xerso],i0
}
else
{
@@ -2238,19 +2237,14 @@ static void generate_compute_flags(drcuml_block *block, int updatecr, UINT32 xer
}
/* tricky case: both */
- UML_GETFLGS(block, IREG(0), DRCUML_FLAG_S | DRCUML_FLAG_Z | xerflags); // getflgs i0,sz|xerflags
+ UML_GETFLGS(block, IREG(0), DRCUML_FLAG_S | DRCUML_FLAG_Z | xerflags); // getflgs i0,SZ | xerflags
+ UML_LOAD(block, IREG(1), ppc->impstate->sz_cr_table, IREG(0), BYTE); // load i1,sz_cr_table,i0,byte
if (invertcarry && (xermask & XER_CA))
UML_XOR(block, IREG(0), IREG(0), IMM(DRCUML_FLAG_C)); // xor i0,i0,FLAG_C
- UML_LOAD(block, IREG(0), ppc->impstate->sz_cr_table, IREG(0), DWORD); // load i0,sz_cr_table,i0,dword
- UML_AND(block, IREG(1), SPR32(SPR_XER), IMM(~xermask)); // and i1,[xer],~xermask
- UML_SHL(block, IREG(2), IREG(0), IMM(4)); // shl i2,i0,4
- if (xermask_so != (XER_CA | XER_OV | XER_SO))
- UML_AND(block, IREG(2), IREG(2), IMM(xermask_so)); // and i2,i2,xermask
- UML_OR(block, IREG(1), IREG(1), IREG(2)); // or i1,i1,i2
- UML_MOV(block, SPR32(SPR_XER), IREG(1)); // mov [xer],i1
- UML_SHR(block, IREG(1), IREG(1), IMM(3)); // shr i1,i1,3
- UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i0,i1
- UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(0))); // rolins [cr],i0,0,crmask(0)
+ UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(xermask)); // rolins [xer],i0,29,xermask
+ UML_ROLAND(block, IREG(0), IREG(0), IMM(31), IMM(1)); // roland i0,i0,31,0x0001
+ UML_OR(block, XERSO32, XERSO32, IREG(0)); // or [xerso],i0
+ UML_OR(block, CR32(0), IREG(1), IREG(0)); // or [cr0],i1,i0
}
@@ -2315,7 +2309,7 @@ static void generate_branch_bo(drcuml_block *block, compiler_state *compiler, co
}
if (!(bo & 0x10))
{
- UML_TEST(block, CR32, IMM(0x80000000 >> bi)); // test cr32,0x80000000 >> bi
+ UML_TEST(block, CR32(bi / 4), IMM(8 >> (bi % 4))); // test cr32(bi/4),8 >> (bi % 4)
UML_JMPc(block, (bo & 0x08) ? IF_Z : IF_NZ, skip); // jmp skip,z/nz
}
generate_branch(block, compiler, desc, source, link); // <branch>
@@ -2372,19 +2366,15 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
case 0x0a: /* CMPLI */
UML_CMP(block, R32(G_RA(op)), IMM(G_UIMM(op))); // cmp ra,uimm
UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C); // getflgs i0,zc
- UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), DWORD); // load i0,cmpl_cr_table,i0,dword
- UML_ROLINS(block, IREG(0), SPR32(SPR_XER), IMM(32 - (3 + 4 * G_CRFD(op))), IMM(CRMASK(G_CRFD(op)) & 0x11111111));
- // rolins i0,[xer],32-(3+4*crfd),0x11111111 & crmask[cr]
- UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op)))); // rolins cr,i0,0,crmask[cr]
+ UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), BYTE); // load i0,cmpl_cr_table,i0,byte
+ UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso]
return TRUE;
case 0x0b: /* CMPI */
UML_CMP(block, R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // cmp ra,uimm
UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C | DRCUML_FLAG_S); // getflgs i0,zcs
- UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), DWORD); // load i0,cmp_cr_table,i0,dword
- UML_ROLINS(block, IREG(0), SPR32(SPR_XER), IMM(32 - (3 + 4 * G_CRFD(op))), IMM(CRMASK(G_CRFD(op)) & 0x11111111));
- // rolins i0,[xer],32-(3+4*crfd),0x11111111 & crmask[cr]
- UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op)))); // rolins cr,i0,0,crmask[cr]
+ UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), BYTE); // load i0,cmp_cr_table,i0,byte
+ UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso]
return TRUE;
case 0x08: /* SUBFIC */
@@ -2731,77 +2721,76 @@ static int generate_instruction_13(drcuml_block *block, compiler_state *compiler
return TRUE;
case 0x000: /* MCRF */
- UML_ROLINS(block, CR32, CR32, IMM(((G_CRFS(op) - G_CRFD(op)) & 7) * 4), IMM(CRMASK(G_CRFD(op))));
- // rolins cr,cr,4*(crfs-crfd),crmask[crfd]
+ UML_MOV(block, CR32(G_CRFD(op)), CR32(G_CRFS(op))); // mov [crd],[crs]
return TRUE;
case 0x101: /* CRAND */
- UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op))); // shl i0,cr,crba(op)
- UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op))); // shl i1,cr,crbb(op)
+ UML_SHL(block, IREG(0), CR32(G_CRBA(op) / 4), IMM(G_CRBA(op) % 4)); // shl i0,cr(a / 4),a % 4
+ UML_SHL(block, IREG(1), CR32(G_CRBB(op) / 4), IMM(G_CRBB(op) % 4)); // shl i1,cr(b / 4),b % 4
UML_AND(block, IREG(0), IREG(0), IREG(1)); // and i0,i1
- UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
- // rolins cr,i0,32-crbd,1<<crbd
+ UML_ROLINS(block, CR32(G_CRBD(op) / 4), IREG(0), IMM(32 - G_CRBD(op) % 4), IMM(8 >> (G_CRBD(op) % 4)));
+ // rolins cr(d / 4),i0,32-(d % 4),8 >> (d % 4)
return TRUE;
case 0x081: /* CRANDC */
- UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op))); // shl i0,cr,crba(op)
- UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op))); // shl i1,cr,crbb(op)
+ UML_SHL(block, IREG(0), CR32(G_CRBA(op) / 4), IMM(G_CRBA(op) % 4)); // shl i0,cr(a / 4),a % 4
+ UML_SHL(block, IREG(1), CR32(G_CRBB(op) / 4), IMM(G_CRBB(op) % 4)); // shl i1,cr(b / 4),b % 4
UML_XOR(block, IREG(1), IREG(1), IMM(~0)); // xor i1,~0
UML_AND(block, IREG(0), IREG(0), IREG(1)); // and i0,i1
- UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
- // rolins cr,i0,32-crbd,1<<crbd
+ UML_ROLINS(block, CR32(G_CRBD(op) / 4), IREG(0), IMM(32 - G_CRBD(op) % 4), IMM(8 >> (G_CRBD(op) % 4)));
+ // rolins cr(d / 4),i0,32-(d % 4),8 >> (d % 4)
return TRUE;
case 0x0e1: /* CRNAND */
- UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op))); // shl i0,cr,crba(op)
- UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op))); // shl i1,cr,crbb(op)
+ UML_SHL(block, IREG(0), CR32(G_CRBA(op) / 4), IMM(G_CRBA(op) % 4)); // shl i0,cr(a / 4),a % 4
+ UML_SHL(block, IREG(1), CR32(G_CRBB(op) / 4), IMM(G_CRBB(op) % 4)); // shl i1,cr(b / 4),b % 4
UML_AND(block, IREG(0), IREG(0), IREG(1)); // and i0,i1
UML_XOR(block, IREG(0), IREG(0), IMM(~0)); // xor i0,~0
- UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
- // rolins cr,i0,32-crbd,1<<crbd
+ UML_ROLINS(block, CR32(G_CRBD(op) / 4), IREG(0), IMM(32 - G_CRBD(op) % 4), IMM(8 >> (G_CRBD(op) % 4)));
+ // rolins cr(d / 4),i0,32-(d % 4),8 >> (d % 4)
return TRUE;
case 0x1c1: /* CROR */
- UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op))); // shl i0,cr,crba(op)
- UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op))); // shl i1,cr,crbb(op)
+ UML_SHL(block, IREG(0), CR32(G_CRBA(op) / 4), IMM(G_CRBA(op) % 4)); // shl i0,cr(a / 4),a % 4
+ UML_SHL(block, IREG(1), CR32(G_CRBB(op) / 4), IMM(G_CRBB(op) % 4)); // shl i1,cr(b / 4),b % 4
UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i1
- UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
- // rolins cr,i0,32-crbd,1<<crbd
+ UML_ROLINS(block, CR32(G_CRBD(op) / 4), IREG(0), IMM(32 - G_CRBD(op) % 4), IMM(8 >> (G_CRBD(op) % 4)));
+ // rolins cr(d / 4),i0,32-(d % 4),8 >> (d % 4)
return TRUE;
case 0x1a1: /* CRORC */
- UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op))); // shl i0,cr,crba(op)
- UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op))); // shl i1,cr,crbb(op)
+ UML_SHL(block, IREG(0), CR32(G_CRBA(op) / 4), IMM(G_CRBA(op) % 4)); // shl i0,cr(a / 4),a % 4
+ UML_SHL(block, IREG(1), CR32(G_CRBB(op) / 4), IMM(G_CRBB(op) % 4)); // shl i1,cr(b / 4),b % 4
UML_XOR(block, IREG(1), IREG(1), IMM(~0)); // xor i1,~0
UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i1
- UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
- // rolins cr,i0,32-crbd,1<<crbd
+ UML_ROLINS(block, CR32(G_CRBD(op) / 4), IREG(0), IMM(32 - G_CRBD(op) % 4), IMM(8 >> (G_CRBD(op) % 4)));
+ // rolins cr(d / 4),i0,32-(d % 4),8 >> (d % 4)
return TRUE;
case 0x021: /* CRNOR */
- UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op))); // shl i0,cr,crba(op)
- UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op))); // shl i1,cr,crbb(op)
+ UML_SHL(block, IREG(0), CR32(G_CRBA(op) / 4), IMM(G_CRBA(op) % 4)); // shl i0,cr(a / 4),a % 4
+ UML_SHL(block, IREG(1), CR32(G_CRBB(op) / 4), IMM(G_CRBB(op) % 4)); // shl i1,cr(b / 4),b % 4
UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i1
UML_XOR(block, IREG(0), IREG(0), IMM(~0)); // xor i0,~0
- UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
- // rolins cr,i0,32-crbd,1<<crbd
+ UML_ROLINS(block, CR32(G_CRBD(op) / 4), IREG(0), IMM(32 - G_CRBD(op) % 4), IMM(8 >> (G_CRBD(op) % 4)));
+ // rolins cr(d / 4),i0,32-(d % 4),8 >> (d % 4)
return TRUE;
case 0x0c1: /* CRXOR */
- UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op))); // shl i0,cr,crba(op)
- UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op))); // shl i1,cr,crbb(op)
+ UML_SHL(block, IREG(0), CR32(G_CRBA(op) / 4), IMM(G_CRBA(op) % 4)); // shl i0,cr(a / 4),a % 4
+ UML_SHL(block, IREG(1), CR32(G_CRBB(op) / 4), IMM(G_CRBB(op) % 4)); // shl i1,cr(b / 4),b % 4
UML_XOR(block, IREG(0), IREG(0), IREG(1)); // xor i0,i1
- UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
- // rolins cr,i0,32-crbd,1<<crbd
+ UML_ROLINS(block, CR32(G_CRBD(op) / 4), IREG(0), IMM(32 - G_CRBD(op) % 4), IMM(8 >> (G_CRBD(op) % 4)));
+ // rolins cr(d / 4),i0,32-(d % 4),8 >> (d % 4)
return TRUE;
case 0x121: /* CREQV */
- UML_SHL(block, IREG(0), CR32, IMM(G_CRBA(op))); // shl i0,cr,crba(op)
- UML_SHL(block, IREG(1), CR32, IMM(G_CRBB(op))); // shl i1,cr,crbb(op)
+ UML_SHL(block, IREG(0), CR32(G_CRBA(op) / 4), IMM(G_CRBA(op) % 4)); // shl i0,cr(a / 4),a % 4
+ UML_SHL(block, IREG(1), CR32(G_CRBB(op) / 4), IMM(G_CRBB(op) % 4)); // shl i1,cr(b / 4),b % 4
UML_XOR(block, IREG(0), IREG(0), IREG(1)); // xor i0,i1
UML_XOR(block, IREG(0), IREG(0), IMM(~0)); // xor i0,~0
- UML_ROLINS(block, CR32, IREG(0), IMM(32 - G_CRBD(op)), IMM(0x80000000 >> G_CRBD(op)));
- // rolins cr,i0,32-crbd,1<<crbd
+ UML_ROLINS(block, CR32(G_CRBD(op) / 4), IREG(0), IMM(32 - G_CRBD(op) % 4), IMM(8 >> (G_CRBD(op) % 4)));
+ // rolins cr(d / 4),i0,32-(d % 4),8 >> (d % 4)
return TRUE;
case 0x032: /* RFI */
@@ -2980,19 +2969,15 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x000: /* CMP */
UML_CMP(block, R32(G_RA(op)), R32(G_RB(op))); // cmp ra,rb
UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C | DRCUML_FLAG_S); // getflgs i0,zcs
- UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), DWORD); // load i0,cmp_cr_table,i0,dword
- UML_ROLINS(block, IREG(0), SPR32(SPR_XER), IMM(32 - (3 + 4 * G_CRFD(op))), IMM(CRMASK(G_CRFD(op)) & 0x11111111));
- // rolins i0,[xer],32-(3+4*crfd),0x11111111 & crmask[cr]
- UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op)))); // rolins cr,i0,0,crmask[cr]
+ UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), BYTE); // load i0,cmp_cr_table,i0,byte
+ UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso]
return TRUE;
case 0x020: /* CMPL */
UML_CMP(block, R32(G_RA(op)), R32(G_RB(op))); // cmp ra,rb
UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C); // getflgs i0,zc
- UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), DWORD); // load i0,cmpl_cr_table,i0,dword
- UML_ROLINS(block, IREG(0), SPR32(SPR_XER), IMM(32 - (3 + 4 * G_CRFD(op))), IMM(CRMASK(G_CRFD(op)) & 0x11111111));
- // rolins i0,[xer],32-(3+4*crfd),0x11111111 & crmask[cr]
- UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op)))); // rolins cr,i0,0,crmask[cr]
+ UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), BYTE); // load i0,cmpl_cr_table,i0,byte
+ UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso]
return TRUE;
case 0x00b: /* MULHWUx */
@@ -3412,8 +3397,6 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
UML_MOV(block, IREG(1), R32(G_RS(op))); // mov i1,rs
UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op)
UML_CALLH(block, ppc->impstate->write32align[ppc->impstate->mode & 3]); // callh write32align
- UML_AND(block, IREG(0), CR32, IMM(~CRMASK(0))); // and i0,cr,~crmask(0)
- UML_ROLINS(block, IREG(0), SPR32(SPR_XER), IMM(29), IMM(0x10000000)); // rolins i0,[xer],29,0x10000000
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles>
UML_CMP(block, IREG(0), IREG(0)); // cmp i0,i0
generate_compute_flags(block, TRUE, 0, FALSE); // <update flags>
@@ -3485,7 +3468,21 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
return TRUE;
case 0x013: /* MFCR */
- UML_MOV(block, R32(G_RD(op)), CR32); // mov rd,cr
+ UML_SHL(block, IREG(0), CR32(0), IMM(28)); // shl i0,cr(0),28
+ UML_ROLAND(block, IREG(1), CR32(1), IMM(24), IMM(0x0f000000)); // roland i1,cr(1),24,0x0f000000
+ UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i0,i1
+ UML_ROLAND(block, IREG(1), CR32(2), IMM(20), IMM(0x00f00000)); // roland i1,cr(2),20,0x00f00000
+ UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i0,i1
+ UML_ROLAND(block, IREG(1), CR32(3), IMM(16), IMM(0x000f0000)); // roland i1,cr(3),16,0x000f0000
+ UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i0,i1
+ UML_ROLAND(block, IREG(1), CR32(4), IMM(12), IMM(0x0000f000)); // roland i1,cr(4),12,0x0000f000
+ UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i0,i1
+ UML_ROLAND(block, IREG(1), CR32(5), IMM(8), IMM(0x00000f00)); // roland i1,cr(5),8,0x00000f00
+ UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i0,i1
+ UML_ROLAND(block, IREG(1), CR32(6), IMM(4), IMM(0x000000f0)); // roland i1,cr(6),4,0x000000f0
+ UML_OR(block, IREG(0), IREG(0), IREG(1)); // or i0,i0,i1
+ UML_ROLAND(block, IREG(1), CR32(7), IMM(0), IMM(0x0000000f)); // roland i1,cr(7),0,0x0000000f
+ UML_OR(block, R32(G_RD(op)), IREG(0), IREG(1)); // or rd,i0,i1
return TRUE;
case 0x053: /* MFMSR */
@@ -3495,8 +3492,14 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x153: /* MFSPR */
{
UINT32 spr = compute_spr(G_SPR(op));
- if (spr == SPR_LR || spr == SPR_CTR || spr == SPR_XER || (spr >= SPROEA_SPRG0 && spr <= SPROEA_SPRG3))
+ if (spr == SPR_LR || spr == SPR_CTR || (spr >= SPROEA_SPRG0 && spr <= SPROEA_SPRG3))
UML_MOV(block, R32(G_RD(op)), SPR32(spr)); // mov rd,spr
+ else if (spr == SPR_XER)
+ {
+ UML_MOV(block, IREG(0), SPR32(spr)); // mov i0,spr
+ UML_SHL(block, IREG(1), XERSO32, IMM(31)); // shl i1,[xerso],31
+ UML_OR(block, R32(G_RD(op)), IREG(0), IREG(1)); // or [rd],i0,i1
+ }
else if (spr == SPROEA_PVR)
UML_MOV(block, R32(G_RD(op)), IMM(ppc->flavor)); // mov rd,flavor
else
@@ -3531,7 +3534,15 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
}
case 0x090: /* MTCRF */
- UML_ROLINS(block, CR32, R32(G_RS(op)), IMM(0), IMM(compute_crf_mask(G_CRM(op))));// rolins cr,rs,0,G_CRM
+ UML_MOV(block, IREG(0), R32(G_RS(op))); // mov i0,rs
+ if (G_CRM(op) & 0x80) UML_ROLAND(block, CR32(0), IREG(0), IMM(4), IMM(0xf)); // roland cr(0),i0,4,0x0f
+ if (G_CRM(op) & 0x40) UML_ROLAND(block, CR32(1), IREG(0), IMM(8), IMM(0xf)); // roland cr(1),i0,8,0x0f
+ if (G_CRM(op) & 0x20) UML_ROLAND(block, CR32(2), IREG(0), IMM(12), IMM(0xf)); // roland cr(2),i0,12,0x0f
+ if (G_CRM(op) & 0x10) UML_ROLAND(block, CR32(3), IREG(0), IMM(16), IMM(0xf)); // roland cr(3),i0,16,0x0f
+ if (G_CRM(op) & 0x08) UML_ROLAND(block, CR32(4), IREG(0), IMM(20), IMM(0xf)); // roland cr(4),i0,20,0x0f
+ if (G_CRM(op) & 0x04) UML_ROLAND(block, CR32(5), IREG(0), IMM(24), IMM(0xf)); // roland cr(5),i0,24,0x0f
+ if (G_CRM(op) & 0x02) UML_ROLAND(block, CR32(6), IREG(0), IMM(28), IMM(0xf)); // roland cr(6),i0,28,0x0f
+ if (G_CRM(op) & 0x01) UML_ROLAND(block, CR32(7), IREG(0), IMM(0), IMM(0xf)); // roland cr(7),i0,0,0x0f
return TRUE;
case 0x092: /* MTMSR */
@@ -3549,8 +3560,13 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x1d3: /* MTSPR */
{
UINT32 spr = compute_spr(G_SPR(op));
- if (spr == SPR_LR || spr == SPR_CTR || spr == SPR_XER || (spr >= SPROEA_SPRG0 && spr <= SPROEA_SPRG3))
+ if (spr == SPR_LR || spr == SPR_CTR || (spr >= SPROEA_SPRG0 && spr <= SPROEA_SPRG3))
UML_MOV(block, SPR32(spr), R32(G_RS(op))); // mov spr,rs
+ else if (spr == SPR_XER)
+ {
+ UML_AND(block, SPR32(spr), R32(G_RS(op)), IMM(~XER_SO)); // and spr,rs,~XER_SO
+ UML_SHR(block, XERSO32, R32(G_RS(op)), IMM(31)); // shr [xerso],rs,31
+ }
else if (spr == SPROEA_PVR)
; // read only
else
@@ -3577,9 +3593,11 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
return TRUE;
case 0x200: /* MCRXR */
- UML_ROLINS(block, CR32, SPR32(SPR_XER), IMM(32 - 4 * G_CRFD(op)), IMM(CRMASK(G_CRFD(op))));
- // rolins cr,[xer],32-4*crfd,crmask(crfd)
+ UML_ROLAND(block, IREG(0), SPR32(SPR_XER), IMM(28), IMM(0x0f)); // roland i0,[xer],28,0x0f
+ UML_SHL(block, IREG(1), XERSO32, IMM(3)); // shl i1,[xerso],3
+ UML_OR(block, CR32(G_CRFD(op)), IREG(0), IREG(1)); // or [crd],i0,i1
UML_AND(block, SPR32(SPR_XER), SPR32(SPR_XER), IMM(~0xf0000000)); // and [xer],[xer],~0xf0000000
+ UML_MOV(block, XERSO32, IMM(0)); // mov [xerso],0
return TRUE;
case 0x106: /* ICBT */
@@ -3797,8 +3815,8 @@ static int generate_instruction_3f(drcuml_block *block, compiler_state *compiler
case 0x020: /* FCMPO */
UML_FDCMP(block, F64(G_RA(op)), F64(G_RB(op))); // fdcmp ra,rb
UML_GETFLGS(block, IREG(0), DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_U); // getflgs i0,czu
- UML_LOAD(block, IREG(0), ppc->impstate->fcmp_cr_table, IREG(0), DWORD); // load i0,fcmp_cr_table,i0,dword
- UML_ROLINS(block, CR32, IREG(0), IMM(0), IMM(CRMASK(G_CRFD(op)))); // rolins cr,i0,0,crmask[cr]
+ UML_LOAD(block, IREG(0), ppc->impstate->fcmp_cr_table, IREG(0), BYTE); // load i0,fcmp_cr_table,i0,byte
+ UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso]
return TRUE;
case 0x00c: /* FRSPx */
@@ -3843,8 +3861,8 @@ static int generate_instruction_3f(drcuml_block *block, compiler_state *compiler
return TRUE;
case 0x040: /* MCRFS */
- UML_ROLINS(block, CR32, FPSCR32, IMM(((G_CRFS(op) - G_CRFD(op)) & 7) * 4), IMM(CRMASK(G_CRFD(op))));
- // rolins cr,fpscr,shift,crmask[crfd]
+ UML_ROLAND(block, CR32(G_CRFD(op)), FPSCR32, IMM(((G_CRFS(op) - 7) & 7) * 4), IMM(0x0f));
+ // roland [crd],[fpscr],shift,0x0f
UML_AND(block, FPSCR32, FPSCR32, IMM(~CRMASK(G_CRFS(op)))); // and fpscr,fpscr,~crmask[crfs]
return TRUE;