emith_read_r_r_offs_c(cond, r, rs, offs)
#define emith_read_r_r_r_c(cond, r, rs, rm) \
EOP_LDR_REG_LSL(cond, r, rs, rm, 0)
+#define emith_read_r_r_offs(r, rs, offs) \
+ emith_read_r_r_offs_c(A_COND_AL, r, rs, offs)
#define emith_read_r_r_r(r, rs, rm) \
EOP_LDR_REG_LSL(A_COND_AL, r, rs, rm, 0)
EOP_LDRB_IMM2(cond, r, rs, offs)
#define emith_read8_r_r_r_c(cond, r, rs, rm) \
EOP_LDRB_REG_LSL(cond, r, rs, rm, 0)
+#define emith_read8_r_r_offs(r, rs, offs) \
+ emith_read8_r_r_offs_c(A_COND_AL, r, rs, offs)
#define emith_read8_r_r_r(r, rs, rm) \
- EOP_LDRB_REG_LSL(A_COND_AL, r, rs, rm, 0)
+ emith_read8_r_r_r_c(A_COND_AL, r, rs, rm)
#define emith_read16_r_r_offs_c(cond, r, rs, offs) \
EOP_LDRH_IMM2(cond, r, rs, offs)
#define emith_read16_r_r_r_c(cond, r, rs, rm) \
EOP_LDRH_REG2(cond, r, rs, rm)
+#define emith_read16_r_r_offs(r, rs, offs) \
+ emith_read16_r_r_offs_c(A_COND_AL, r, rs, offs)
#define emith_read16_r_r_r(r, rs, rm) \
- EOP_LDRH_REG2(A_COND_AL, r, rs, rm)
-
-#define emith_read_r_r_offs(r, rs, offs) \
- emith_read_r_r_offs_c(A_COND_AL, r, rs, offs)
+ emith_read16_r_r_r_c(A_COND_AL, r, rs, rm)
+#define emith_read8s_r_r_offs_c(cond, r, rs, offs) \
+ EOP_LDRSB_IMM2(cond, r, rs, offs)
+#define emith_read8s_r_r_r_c(cond, r, rs, rm) \
+ EOP_LDRSB_REG2(cond, r, rs, rm)
#define emith_read8s_r_r_offs(r, rs, offs) \
- EOP_LDRSB_IMM2(A_COND_AL, r, rs, offs)
-#define emith_read8_r_r_offs(r, rs, offs) \
- emith_read8_r_r_offs_c(A_COND_AL, r, rs, offs)
-
+ emith_read8s_r_r_offs_c(A_COND_AL, r, rs, offs)
+#define emith_read8s_r_r_r(r, rs, rm) \
+ emith_read8s_r_r_r_c(A_COND_AL, r, rs, rm)
+
+#define emith_read16s_r_r_offs_c(cond, r, rs, offs) \
+ EOP_LDRSH_IMM2(cond, r, rs, offs)
+#define emith_read16s_r_r_r_c(cond, r, rs, rm) \
+ EOP_LDRSH_REG2(cond, r, rs, rm)
#define emith_read16s_r_r_offs(r, rs, offs) \
- EOP_LDRSH_IMM2(A_COND_AL, r, rs, offs)
-#define emith_read16_r_r_offs(r, rs, offs) \
- emith_read16_r_r_offs_c(A_COND_AL, r, rs, offs)
+ emith_read16s_r_r_offs_c(A_COND_AL, r, rs, offs)
+#define emith_read16s_r_r_r(r, rs, rm) \
+ emith_read16s_r_r_r_c(A_COND_AL, r, rs, rm)
#define emith_write_r_r_offs_c(cond, r, rs, offs) \
EOP_STR_IMM2(cond, r, rs, offs)
#define emith_call(target) \
emith_call_cond(A_COND_AL, target)
+#define emith_call_reg(r) { \
+ emith_move_r_r(14, 15); \
+ EOP_C_BX(A_COND_AL, r); \
+}
+
#define emith_call_ctx(offs) { \
emith_move_r_r(14, 15); \
emith_jump_ctx(offs); \
} while (0)
/* mh:ml += rn*rm, does saturation if required by S bit. rn, rm must be TEMP */
-#define emith_sh2_macw(ml, mh, rn, rm, sr) do { \
- emith_sext(rn, rn, 16); \
- emith_sext(rm, rm, 16); \
+#define emith_sh2_macw(ml, mh, rn, rm, sr) do { \
emith_tst_r_imm(sr, S); \
EMITH_SJMP2_START(DCOND_NE); \
emith_mula_s64_c(DCOND_EQ, ml, mh, rn, rm); \
#define emith_read8_r_r_r_c(cond, r, rs, rm) \
emith_read8_r_r_r(r, rs, rm)
+#define emith_read8s_r_r_r_c(cond, r, rs, rm) \
+ emith_read8s_r_r_r(r, rs, rm)
#define emith_read16_r_r_r_c(cond, r, rs, rm) \
emith_read16_r_r_r(r, rs, rm)
+#define emith_read16s_r_r_r_c(cond, r, rs, rm) \
+ emith_read16s_r_r_r(r, rs, rm)
#define emith_read_r_r_r_c(cond, r, rs, rm) \
emith_read_r_r_r(r, rs, rm)
EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
} while (0)
+#define emith_read8s_r_r_r(r, rs, rm) do { \
+ EMIT(0x0f, u8); \
+ EMIT_OP_MODRM(0xbe, 0, r, 4); \
+ EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
+} while (0)
+
#define emith_read16_r_r_r(r, rs, rm) do { \
EMIT(0x0f, u8); \
EMIT_OP_MODRM(0xb7, 0, r, 4); \
EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
} while (0)
+#define emith_read16s_r_r_r(r, rs, rm) do { \
+ EMIT(0x0f, u8); \
+ EMIT_OP_MODRM(0xbf, 0, r, 4); \
+ EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
+} while (0)
+
#define emith_read_r_r_r(r, rs, rm) do { \
EMIT_OP_MODRM(0x8b, 0, r, 4); \
EMIT_SIB(0, rs, rm); /* mov r, [rm + rs * 1] */ \
EMIT(offs, u32); \
} while (0)
-#define emith_push_ret()
+#define emith_push_ret() \
+ emith_push(xSI); /* to align */
#define emith_pop_and_ret() \
+ emith_pop(xSI); \
emith_ret()
#define EMITH_JMP_START(cond) { \
/* mh:ml += rn*rm, does saturation if required by S bit. rn, rm must be TEMP */
#define emith_sh2_macw(ml, mh, rn, rm, sr) do { \
- emith_sext(rn, rn, 16); \
- emith_sext(rm, rm, 16); \
emith_tst_r_imm(sr, S); \
EMITH_SJMP_START(DCOND_EQ); \
/* XXX: MACH should be untouched when S is set? */ \
hr2 = hr;
else
#if REMAP_REGISTER
- hr2 = rcache_map_reg(rd, hr, size != 2 ? RC_GR_RMW : RC_GR_WRITE);
+ hr2 = rcache_map_reg(rd, hr, RC_GR_WRITE);
#else
hr2 = rcache_get_reg(rd, RC_GR_WRITE, NULL);
#endif
- if (rd != SHR_TMP && size != 2) { // 16, 8
- emith_sext(hr2, hr, size ? 16 : 8);
- } else if (hr != hr2) // 32
+ if (hr != hr2) {
emith_move_r_r(hr2, hr);
- if (hr != hr2)
rcache_free_tmp(hr);
+ }
return hr2;
}
hr = emit_memhandler_read(size);
size &= MF_SIZEMASK;
- if (rd != SHR_TMP)
+ if (rd == SHR_TMP)
+ hr2 = hr;
+ else
#if REMAP_REGISTER
- hr2 = rcache_map_reg(rd, hr, size != 2 ? RC_GR_RMW : RC_GR_WRITE);
+ hr2 = rcache_map_reg(rd, hr, RC_GR_WRITE);
#else
hr2 = rcache_get_reg(rd, RC_GR_WRITE, NULL);
#endif
- else
- hr2 = hr;
- if (rd != SHR_TMP && size != 2) { // 16, 8
- emith_sext(hr2, hr, size ? 16 : 8);
- } else if (hr != hr2) // 32
+ if (hr != hr2) {
emith_move_r_r(hr2, hr);
- if (hr != hr2)
rcache_free_tmp(hr);
+ }
return hr2;
}
}
tmp2 = emit_memhandler_read(opd->size);
#if REMAP_REGISTER
- tmp3 = rcache_map_reg(GET_Rn(), tmp2, opd->size != 2 ? RC_GR_RMW : RC_GR_WRITE);
+ tmp3 = rcache_map_reg(GET_Rn(), tmp2, RC_GR_WRITE);
#else
tmp3 = rcache_get_reg(GET_Rn(), RC_GR_WRITE, NULL);
#endif
- if (opd->size != 2) {
- emith_sext(tmp3, tmp2, 16);
- } else if (tmp3 != tmp2)
+ if (tmp3 != tmp2) {
emith_move_r_r(tmp3, tmp2);
- if (tmp3 != tmp2)
rcache_free_tmp(tmp2);
+ }
}
goto end_op;
EMITH_SJMP_START(DCOND_CS);
emith_and_r_r_c(DCOND_CC, arg0, arg3);
emith_eor_r_imm_c(DCOND_CC, arg0, 1);
- emith_read8_r_r_r_c(DCOND_CC, RET_REG, arg0, arg2);
+ emith_read8s_r_r_r_c(DCOND_CC, RET_REG, arg0, arg2);
emith_ret_c(DCOND_CC);
EMITH_SJMP_END(DCOND_CS);
emith_move_r_r_ptr(arg1, CONTEXT_REG);
emith_sh2_rcall(arg0, arg1, arg2, arg3);
EMITH_SJMP_START(DCOND_CS);
emith_and_r_r_c(DCOND_CC, arg0, arg3);
- emith_read16_r_r_r_c(DCOND_CC, RET_REG, arg0, arg2);
+ emith_read16s_r_r_r_c(DCOND_CC, RET_REG, arg0, arg2);
emith_ret_c(DCOND_CC);
EMITH_SJMP_END(DCOND_CS);
emith_move_r_r_ptr(arg1, CONTEXT_REG);
#define _DRC_DECLARE_SR(SR) __DRC_DECLARE_SR(SR)
#define DRC_DECLARE_SR _DRC_DECLARE_SR(DRC_SR_REG)
#define DRC_SAVE_SR(sh2) \
- if ((sh2->state & (SH2_STATE_RUN)) == SH2_STATE_RUN) \
+ if ((sh2->state & (SH2_STATE_RUN|SH2_STATE_SLEEP)) == SH2_STATE_RUN) \
sh2->sr = sh2_sr;
#define DRC_RESTORE_SR(sh2) \
- if ((sh2->state & (SH2_STATE_RUN)) == SH2_STATE_RUN) \
+ if ((sh2->state & (SH2_STATE_RUN|SH2_STATE_SLEEP)) == SH2_STATE_RUN) \
sh2_sr = sh2->sr;
#else
#define DRC_DECLARE_SR
#if BUSY_LOOP_HACKS\r
if (disp == -2)\r
{\r
- UINT32 next_opcode = RW( sh2, sh2->ppc & AM );\r
+ UINT32 next_opcode = (UINT32)(UINT16)RW( sh2, sh2->ppc & AM );\r
/* BRA $\r
* NOP\r
*/\r
sh2->sr &= ~T;\r
#if BUSY_LOOP_HACKS\r
{\r
- UINT32 next_opcode = RW( sh2, sh2->ppc & AM );\r
+ UINT32 next_opcode = (UINT32)(UINT16)RW( sh2, sh2->ppc & AM );\r
/* DT Rn\r
* BF $-2\r
*/\r
INT32 tempm, tempn, dest, src, ans;\r
UINT32 templ;\r
\r
- tempn = (INT32) RW( sh2, sh2->r[n] );\r
+ tempn = (INT32)(INT16) RW( sh2, sh2->r[n] );\r
sh2->r[n] += 2;\r
- tempm = (INT32) RW( sh2, sh2->r[m] );\r
+ tempm = (INT32)(INT16) RW( sh2, sh2->r[m] );\r
sh2->r[m] += 2;\r
templ = sh2->macl;\r
- tempm = ((INT32) (short) tempn * (INT32) (short) tempm);\r
+ tempm = (tempn * tempm);\r
if ((INT32) sh2->macl >= 0)\r
dest = 0;\r
else\r
if (sh2->delay)
{
sh2->ppc = sh2->delay;
- opcode = RW(sh2, sh2->delay);
+ opcode = (UINT32)(UINT16)RW(sh2, sh2->delay);
// TODO: more branch types
if ((opcode >> 13) == 5) { // BRA/BSR
else
{
sh2->ppc = sh2->pc;
- opcode = RW(sh2, sh2->pc);
+ opcode = (UINT32)(UINT16)RW(sh2, sh2->pc);
}
sh2->delay = 0;
if (sh2->delay)
{
sh2->ppc = sh2->delay;
- opcode = RW(sh2, sh2->delay);
+ opcode = (UINT32)(UINT16)RW(sh2, sh2->delay);
sh2->pc -= 2;
}
else
{
sh2->ppc = sh2->pc;
- opcode = RW(sh2, sh2->pc);
+ opcode = (UINT32)(UINT16)RW(sh2, sh2->pc);
}
sh2->delay = 0;
elprintf_sh2(sh2, EL_32X, "r8 [%08x] %02x @%06x",
a, d, sh2_pc(sh2));
DRC_RESTORE_SR(sh2);
- return d;
+ return (s8)d;
}
static u32 REGPARM(2) sh2_read8_da(u32 a, SH2 *sh2)
{
- return sh2->data_array[(a & 0xfff) ^ 1];
+ return (s8)sh2->data_array[(a & 0xfff) ^ 1];
}
// for ssf2
static u32 REGPARM(2) sh2_read8_rom(u32 a, SH2 *sh2)
{
u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
- u8 *p = sh2->p_rom;
+ s8 *p = sh2->p_rom;
return p[(bank + (a & 0x7ffff)) ^ 1];
}
a, d, sh2_pc(sh2));
out_noprint:
DRC_RESTORE_SR(sh2);
- return d;
+ return (s16)d;
}
static u32 REGPARM(2) sh2_read16_da(u32 a, SH2 *sh2)
{
- return ((u16 *)sh2->data_array)[(a & 0xffe) / 2];
+ return ((s16 *)sh2->data_array)[(a & 0xffe) / 2];
}
static u32 REGPARM(2) sh2_read16_rom(u32 a, SH2 *sh2)
{
u32 bank = carthw_ssf2_banks[(a >> 19) & 7] << 19;
- u16 *p = sh2->p_rom;
+ s16 *p = sh2->p_rom;
return p[(bank + (a & 0x7fffe)) / 2];
}
static u32 REGPARM(2) sh2_read32_cs0(u32 a, SH2 *sh2)
{
- return (sh2_read16_cs0(a, sh2) << 16) | sh2_read16_cs0(a + 2, sh2);
+ u32 d1 = sh2_read16_cs0(a, sh2) << 16, d2 = sh2_read16_cs0(a + 2, sh2) << 16;
+ return d1 | (d2 >> 16);
}
static u32 REGPARM(2) sh2_read32_da(u32 a, SH2 *sh2)
if (map_flag_set(p))
return ((sh2_read_handler *)(p << 1))(a, sh2);
else
- return *(u8 *)((p << 1) + ((a & sh2_map->mask) ^ 1));
+ return *(s8 *)((p << 1) + ((a & sh2_map->mask) ^ 1));
}
u32 REGPARM(2) p32x_sh2_read16(u32 a, SH2 *sh2)
if (map_flag_set(p))
return ((sh2_read_handler *)(p << 1))(a, sh2);
else
- return *(u16 *)((p << 1) + (a & sh2_map->mask));
+ return *(s16 *)((p << 1) + (a & sh2_map->mask));
}
u32 REGPARM(2) p32x_sh2_read32(u32 a, SH2 *sh2)