summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/rsp
diff options
context:
space:
mode:
author Ryan Holtz <rholtz@batcountryentertainment.com>2010-12-31 07:29:47 +0000
committer Ryan Holtz <rholtz@batcountryentertainment.com>2010-12-31 07:29:47 +0000
commit0ea11333c6ce2c62b5bf624e51aa1a446d08062f (patch)
treea4ce5e454965bddbf64cff6da8611b2c8df52069 /src/emu/cpu/rsp
parentde94242bcc9479ef0230c776500ef2a9cd47769f (diff)
Updated the RSP and RDP implementations to be largely bit-perfect and pixel-accurate. [angrylion, Harmony]
Diffstat (limited to 'src/emu/cpu/rsp')
-rw-r--r--src/emu/cpu/rsp/rsp.c1425
-rw-r--r--src/emu/cpu/rsp/rsp.h54
-rw-r--r--src/emu/cpu/rsp/rspdiv.h1027
-rw-r--r--src/emu/cpu/rsp/rspdrc.c5808
4 files changed, 2824 insertions, 5490 deletions
diff --git a/src/emu/cpu/rsp/rsp.c b/src/emu/cpu/rsp/rsp.c
index 5cedb6ea410..6a7274ac241 100644
--- a/src/emu/cpu/rsp/rsp.c
+++ b/src/emu/cpu/rsp/rsp.c
@@ -7,6 +7,7 @@
#include "emu.h"
#include "debugger.h"
#include "rsp.h"
+#include "rspdiv.h"
CPU_DISASSEMBLE( rsp );
@@ -18,10 +19,10 @@ CPU_DISASSEMBLE( rsp );
#define RSP_TEST_SYNC 0
#define PRINT_VECREG(x) mame_printf_debug("V%d: %04X|%04X|%04X|%04X|%04X|%04X|%04X|%04X\n", (x), \
- (UINT16)R_VREG_S((x),0), (UINT16)R_VREG_S((x),1), \
- (UINT16)R_VREG_S((x),2), (UINT16)R_VREG_S((x),3), \
- (UINT16)R_VREG_S((x),4), (UINT16)R_VREG_S((x),5), \
- (UINT16)R_VREG_S((x),6), (UINT16)R_VREG_S((x),7))
+ (UINT16)VREG_S((x),0), (UINT16)VREG_S((x),1), \
+ (UINT16)VREG_S((x),2), (UINT16)VREG_S((x),3), \
+ (UINT16)VREG_S((x),4), (UINT16)VREG_S((x),5), \
+ (UINT16)VREG_S((x),6), (UINT16)VREG_S((x),7))
#define PRINT_ACCUM(x) mame_printf_debug("A%d: %08X|%08X\n", (x), \
(UINT32)( ( ACCUM(x) >> 32 ) & 0x00000000ffffffff ), \
@@ -46,48 +47,26 @@ INLINE rsp_state *get_safe_token(running_device *device)
#define JUMP_REL_L(offset,l) { rsp->nextpc = 0x04001000 | ((rsp->pc + ((offset) << 2)) & 0xfff); rsp->r[l] = rsp->pc + 4; }
#define JUMP_PC(addr) { rsp->nextpc = 0x04001000 | ((addr) & 0xfff); }
#define JUMP_PC_L(addr,l) { rsp->nextpc = 0x04001000 | ((addr) & 0xfff); rsp->r[l] = rsp->pc + 4; }
+#define LINK(l) { rsp->r[l] = rsp->pc + 4; }
-#define VDREG ((op >> 6) & 0x1f)
-#define VS1REG ((op >> 11) & 0x1f)
-#define VS2REG ((op >> 16) & 0x1f)
-#define EL ((op >> 21) & 0xf)
+#define VREG_B(reg, offset) rsp->v[(reg)].b[(offset)^1]
+#define VREG_S(reg, offset) rsp->v[(reg)].s[(offset)]
+#define VREG_L(reg, offset) rsp->v[(reg)].l[(offset)]
-#define S_VREG_B(offset) (((15 - (offset)) & 0x07) << 3)
-#define S_VREG_S(offset) (((7 - (offset)) & 0x03) << 4)
-#define S_VREG_L(offset) (((3 - (offset)) & 0x01) << 5)
+#define R_VREG_B(reg, offset) rsp->v[(reg)].b[(offset)^1]
+#define R_VREG_S(reg, offset) (INT16)rsp->v[(reg)].s[(offset)]
+#define R_VREG_L(reg, offset) rsp->v[(reg)].l[(offset)]
-#define M_VREG_B(offset) ((UINT64)0x00FF << S_VREG_B(offset))
-#define M_VREG_S(offset) ((UINT64)0x0000FFFFul << S_VREG_S(offset))
-#define M_VREG_L(offset) ((UINT64)0x00000000FFFFFFFFull << S_VREG_L(offset))
+#define W_VREG_B(reg, offset, val) (rsp->v[(reg)].b[(offset)^1] = val)
+#define W_VREG_S(reg, offset, val) (rsp->v[(reg)].s[(offset)] = val)
+#define W_VREG_L(reg, offset, val) (rsp->v[(reg)].l[(offset)] = val)
-#define R_VREG_B(reg, offset) ((rsp->v[(reg)].d[(15 - (offset)) >> 3] >> S_VREG_B(offset)) & 0x00FF)
-#define R_VREG_S(reg, offset) (INT16)((rsp->v[(reg)].d[(7 - (offset)) >> 2] >> S_VREG_S(offset)) & 0x0000FFFFul)
-#define R_VREG_L(reg, offset) ((rsp->v[(reg)].d[(3 - (offset)) >> 1] >> S_VREG_L(offset)) & 0x00000000FFFFFFFFull)
+#define VEC_EL_2(x,z) (vector_elements[(x)][(z)])
-#define W_VREG_B(reg, offset, val) (rsp->v[(reg)].d[(15 - (offset)) >> 3] = (rsp->v[(reg)].d[(15 - (offset)) >> 3] & ~M_VREG_B(offset)) | (M_VREG_B(offset) & ((UINT64)(val) << S_VREG_B(offset))))
-#define W_VREG_S(reg, offset, val) (rsp->v[(reg)].d[(7 - (offset)) >> 2] = (rsp->v[(reg)].d[(7 - (offset)) >> 2] & ~M_VREG_S(offset)) | (M_VREG_S(offset) & ((UINT64)(val) << S_VREG_S(offset))))
-#define W_VREG_L(reg, offset, val) (rsp->v[(reg)].d[(3 - (offset)) >> 1] = (rsp->v[(reg)].d[(3 - (offset)) >> 1] & ~M_VREG_L(offset)) | (M_VREG_L(offset) & ((UINT64)(val) << S_VREG_L(offset))))
-
-#define VEC_EL_1(x,z) (vector_elements_1[(x)][(z)])
-#define VEC_EL_2(x,z) (vector_elements_2[(x)][(z)])
-
-#define ACCUM(x) (rsp->accum[(7-(x))].l)
-
-#define S_ACCUM_H (3 << 4)
-#define S_ACCUM_M (2 << 4)
-#define S_ACCUM_L (1 << 4)
-
-#define M_ACCUM_H (((INT64)0x0000FFFF) << S_ACCUM_H)
-#define M_ACCUM_M (((INT64)0x0000FFFF) << S_ACCUM_M)
-#define M_ACCUM_L (((INT64)0x0000FFFF) << S_ACCUM_L)
-
-#define R_ACCUM_H(x) ((INT16)((ACCUM(x) >> S_ACCUM_H) & 0x00FFFF))
-#define R_ACCUM_M(x) ((INT16)((ACCUM(x) >> S_ACCUM_M) & 0x00FFFF))
-#define R_ACCUM_L(x) ((INT16)((ACCUM(x) >> S_ACCUM_L) & 0x00FFFF))
-
-#define W_ACCUM_H(x, y) (ACCUM(x) = (ACCUM(x) & ~M_ACCUM_H) | (M_ACCUM_H & ((INT64)(y) << S_ACCUM_H)))
-#define W_ACCUM_M(x, y) (ACCUM(x) = (ACCUM(x) & ~M_ACCUM_M) | (M_ACCUM_M & ((INT64)(y) << S_ACCUM_M)))
-#define W_ACCUM_L(x, y) (ACCUM(x) = (ACCUM(x) & ~M_ACCUM_L) | (M_ACCUM_L & ((INT64)(y) << S_ACCUM_L)))
+#define ACCUM(x) rsp->accum[((x))].q
+#define ACCUM_H(x) rsp->accum[((x))].w[3]
+#define ACCUM_M(x) rsp->accum[((x))].w[2]
+#define ACCUM_L(x) rsp->accum[((x))].w[1]
#define CARRY_FLAG(x) ((rsp->flag[0] & (1 << ((x)))) ? 1 : 0)
#define CLEAR_CARRY_FLAGS() { rsp->flag[0] &= ~0xff; }
@@ -104,56 +83,73 @@ INLINE rsp_state *get_safe_token(running_device *device)
#define SET_ZERO_FLAG(x) { rsp->flag[0] |= (1 << (8+(x))); }
#define CLEAR_ZERO_FLAG(x) { rsp->flag[0] &= ~(1 << (8+(x))); }
-#define ROPCODE(pc) memory_decrypted_read_dword(rsp->program, pc)
+#define EXTENSION_FLAG(x) ((rsp.flag[2] & (1 << ((x)))) ? 1 : 0)
+
+#define ROPCODE(pc) rsp->program->read_dword(pc)
INLINE UINT8 READ8(rsp_state *rsp, UINT32 address)
{
+ UINT8 ret;
address = 0x04000000 | (address & 0xfff);
- return rsp->program->read_byte(address);
+ ret = rsp->program->read_byte(address);
+ printf("%04xr%02x\n", address & 0x0000ffff, ret);
+ return ret;
}
INLINE UINT16 READ16(rsp_state *rsp, UINT32 address)
{
+ UINT16 ret;
address = 0x04000000 | (address & 0xfff);
- if (address & 1)
+ if(address & 1)
{
- //osd_die("RSP: READ16: unaligned %08X at %08X\n", address, rsp->ppc);
- return ((rsp->program->read_byte(address+0) & 0xff) << 8) | (rsp->program->read_byte(address+1) & 0xff);
+ ret = ((rsp->program->read_byte(address + 0) & 0xff) << 8) | (rsp->program->read_byte(address + 1) & 0xff);
}
+ else
+ {
+ ret = rsp->program->read_word(address);
+ }
+
+ printf("%04xr%04x\n", address & 0x0000ffff, ret);
- return rsp->program->read_word(address);
+ return ret;
}
INLINE UINT32 READ32(rsp_state *rsp, UINT32 address)
{
+ UINT32 ret;
address = 0x04000000 | (address & 0xfff);
- if (address & 3)
+ if(address & 3)
{
- //osd_die("RSP: READ32: unaligned %08X at %08X\n", address, rsp->ppc);
- return ((rsp->program->read_byte(address + 0) & 0xff) << 24) |
+ ret = ((rsp->program->read_byte(address + 0) & 0xff) << 24) |
((rsp->program->read_byte(address + 1) & 0xff) << 16) |
((rsp->program->read_byte(address + 2) & 0xff) << 8) |
((rsp->program->read_byte(address + 3) & 0xff) << 0);
}
+ else
+ {
+ ret = rsp->program->read_dword(address);
+ }
- return rsp->program->read_dword(address);
+ printf("%04xr%08x\n", address & 0x0000ffff, ret);
+ return ret;
}
INLINE void WRITE8(rsp_state *rsp, UINT32 address, UINT8 data)
{
address = 0x04000000 | (address & 0xfff);
+ printf("%04x:%02x\n", address & 0x0000ffff, data);
rsp->program->write_byte(address, data);
}
INLINE void WRITE16(rsp_state *rsp, UINT32 address, UINT16 data)
{
address = 0x04000000 | (address & 0xfff);
+ printf("%04x:%04x\n", address & 0x0000ffff, data);
- if (address & 1)
+ if(address & 1)
{
- //fatalerror("RSP: WRITE16: unaligned %08X, %04X at %08X\n", address, data, rsp->ppc);
rsp->program->write_byte(address + 0, (data >> 8) & 0xff);
rsp->program->write_byte(address + 1, (data >> 0) & 0xff);
return;
@@ -165,10 +161,10 @@ INLINE void WRITE16(rsp_state *rsp, UINT32 address, UINT16 data)
INLINE void WRITE32(rsp_state *rsp, UINT32 address, UINT32 data)
{
address = 0x04000000 | (address & 0xfff);
+ printf("%04x:%08x\n", address & 0x0000ffff, data);
- if (address & 3)
+ if(address & 3)
{
- //osd_die("RSP: WRITE32: unaligned %08X, %08X at %08X\n", address, data, rsp->ppc);
rsp->program->write_byte(address + 0, (data >> 24) & 0xff);
rsp->program->write_byte(address + 1, (data >> 16) & 0xff);
rsp->program->write_byte(address + 2, (data >> 8) & 0xff);
@@ -183,7 +179,8 @@ INLINE void WRITE32(rsp_state *rsp, UINT32 address, UINT32 data)
static UINT32 get_cop0_reg(rsp_state *rsp, int reg)
{
- if (reg >= 0 && reg < 8)
+ reg &= 0xf;
+ if (reg < 8)
{
return (rsp->config->sp_reg_r)(rsp->device, reg, 0x00000000);
}
@@ -191,15 +188,14 @@ static UINT32 get_cop0_reg(rsp_state *rsp, int reg)
{
return (rsp->config->dp_reg_r)(rsp->device, reg - 8, 0x00000000);
}
- else
- {
- fatalerror("RSP: get_cop0_reg: %d", reg);
- }
+
+ return 0;
}
static void set_cop0_reg(rsp_state *rsp, int reg, UINT32 data)
{
- if (reg >= 0 && reg < 8)
+ reg &= 0xf;
+ if (reg < 8)
{
(rsp->config->sp_reg_w)(rsp->device, reg, data, 0x00000000);
}
@@ -207,10 +203,6 @@ static void set_cop0_reg(rsp_state *rsp, int reg, UINT32 data)
{
(rsp->config->dp_reg_w)(rsp->device, reg - 8, data, 0x00000000);
}
- else
- {
- fatalerror("RSP: set_cop0_reg: %d, %08X\n", reg, data);
- }
}
static void unimplemented_opcode(rsp_state *rsp, UINT32 op)
@@ -257,27 +249,7 @@ static void unimplemented_opcode(rsp_state *rsp, UINT32 op)
/*****************************************************************************/
-static const int vector_elements_1[16][8] =
-{
- { 0, 1, 2, 3, 4, 5, 6, 7 }, // none
- { 0, 1, 2, 3, 4, 5, 6 ,7 }, // ???
- { 1, 3, 5, 7, 0, 2, 4, 6 }, // 0q
- { 0, 2, 4, 6, 1, 3, 5, 7 }, // 1q
- { 1, 2, 3, 5, 6, 7, 0, 4 }, // 0h
- { 0, 2, 3, 4, 6, 7, 1, 5 }, // 1h
- { 0, 1, 3, 4, 5, 7, 2, 6 }, // 2h
- { 0, 1, 2, 4, 5, 6, 3, 7 }, // 3h
- { 1, 2, 3, 4, 5, 6, 7, 0 }, // 0
- { 0, 2, 3, 4, 5, 6, 7, 1 }, // 1
- { 0, 1, 3, 4, 5, 6, 7, 2 }, // 2
- { 0, 1, 2, 4, 5, 6, 7, 3 }, // 3
- { 0, 1, 2, 3, 5, 6, 7, 4 }, // 4
- { 0, 1, 2, 3, 4, 6, 7, 5 }, // 5
- { 0, 1, 2, 3, 4, 5, 7, 6 }, // 6
- { 0, 1, 2, 3, 4, 5, 6, 7 }, // 7
-};
-
-static const int vector_elements_2[16][8] =
+static const int vector_elements[16][8] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7 }, // none
{ 0, 1, 2, 3, 4, 5, 6, 7 }, // ???
@@ -335,7 +307,7 @@ static CPU_INIT( rsp )
// makes me retch uncontrollably.
for(accumIdx = 0; accumIdx < 8; accumIdx++ )
{
- rsp->accum[accumIdx].l = 0;
+ rsp->accum[accumIdx].q = 0;
}
rsp->sr = RSP_STATUS_HALT;
@@ -419,7 +391,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
// Load 1 byte to vector byte index
ea = (base) ? rsp->r[base] + offset : offset;
- W_VREG_B(dest, index, READ8(rsp, ea));
+ VREG_B(dest, index) = READ8(rsp, ea);
break;
}
case 0x01: /* LSV */
@@ -437,7 +409,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- W_VREG_B(dest, i, READ8(rsp, ea));
+ VREG_B(dest, i) = READ8(rsp, ea);
ea++;
}
break;
@@ -457,7 +429,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- W_VREG_B(dest, i, READ8(rsp, ea));
+ VREG_B(dest, i) = READ8(rsp, ea);
ea++;
}
break;
@@ -477,7 +449,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- W_VREG_B(dest, i, READ8(rsp, ea));
+ VREG_B(dest, i) = READ8(rsp, ea);
ea++;
}
break;
@@ -498,7 +470,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- W_VREG_B(dest, i, READ8(rsp, ea));
+ VREG_B(dest, i) = READ8(rsp, ea);
ea++;
}
break;
@@ -520,7 +492,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- W_VREG_B(dest, i, READ8(rsp, ea));
+ VREG_B(dest, i) = READ8(rsp, ea);
ea++;
}
break;
@@ -538,7 +510,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=0; i < 8; i++)
{
- W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 8);
+ VREG_S(dest, i) = READ8(rsp, ea + (((16-index) + i) & 0xf)) << 8;
}
break;
}
@@ -555,7 +527,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=0; i < 8; i++)
{
- W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 7);
+ VREG_S(dest, i) = READ8(rsp, ea + (((16-index) + i) & 0xf)) << 7;
}
break;
}
@@ -572,7 +544,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=0; i < 8; i++)
{
- W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + (i<<1)) & 0xf)) << 7);
+ VREG_S(dest, i) = READ8(rsp, ea + (((16-index) + (i<<1)) & 0xf)) << 7;
}
break;
}
@@ -585,20 +557,15 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
//
// Loads a byte as the bits 14-7 of upper or lower quad, with 4-byte stride
- fatalerror("RSP: LFV\n");
-
- if (index & 0x7) fatalerror("RSP: LFV: index = %d at %08X\n", index, rsp->ppc);
-
ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
// not sure what happens if 16-byte boundary is crossed...
- if ((ea & 0xf) > 0) fatalerror("RSP: LFV: 16-byte boundary crossing at %08X, recheck this!\n", rsp->ppc);
end = (index >> 1) + 4;
for (i=index >> 1; i < end; i++)
{
- W_VREG_S(dest, i, READ8(rsp, ea) << 7);
+ VREG_S(dest, i) = READ8(rsp, ea) << 7;
ea += 4;
}
break;
@@ -622,7 +589,7 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=(16 - index); i < end; i++)
{
- W_VREG_B(dest, i & 0xf, READ8(rsp, ea));
+ VREG_B(dest, i & 0xf) = READ8(rsp, ea);
ea += 4;
}
break;
@@ -654,8 +621,8 @@ static void handle_lwc2(rsp_state *rsp, UINT32 op)
for (i=vs; i < ve; i++)
{
element = ((8 - (index >> 1) + (i-vs)) << 1);
- W_VREG_B(i, (element & 0xf), READ8(rsp, ea));
- W_VREG_B(i, ((element+1) & 0xf), READ8(rsp, ea+1));
+ VREG_B(i, (element & 0xf)) = READ8(rsp, ea);
+ VREG_B(i, ((element + 1) & 0xf)) = READ8(rsp, ea + 1);
ea += 2;
}
@@ -694,7 +661,7 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
// Stores 1 byte from vector byte index
ea = (base) ? rsp->r[base] + offset : offset;
- WRITE8(rsp, ea, R_VREG_B(dest, index));
+ WRITE8(rsp, ea, VREG_B(dest, index));
break;
}
case 0x01: /* SSV */
@@ -712,7 +679,7 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- WRITE8(rsp, ea, R_VREG_B(dest, i));
+ WRITE8(rsp, ea, VREG_B(dest, i));
ea++;
}
break;
@@ -732,7 +699,7 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- WRITE8(rsp, ea, R_VREG_B(dest, i));
+ WRITE8(rsp, ea, VREG_B(dest, i));
ea++;
}
break;
@@ -752,7 +719,7 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- WRITE8(rsp, ea, R_VREG_B(dest, i));
+ WRITE8(rsp, ea, VREG_B(dest, i));
ea++;
}
break;
@@ -772,7 +739,7 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- WRITE8(rsp, ea, R_VREG_B(dest, i & 0xf));
+ WRITE8(rsp, ea, VREG_B(dest, i & 0xf));
ea++;
}
break;
@@ -795,7 +762,7 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- WRITE8(rsp, ea, R_VREG_B(dest, ((i + o) & 0xf)));
+ WRITE8(rsp, ea, VREG_B(dest, ((i + o) & 0xf)));
ea++;
}
break;
@@ -816,11 +783,11 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
{
if ((i & 0xf) < 8)
{
- WRITE8(rsp, ea, R_VREG_B(dest, ((i & 0xf) << 1)));
+ WRITE8(rsp, ea, VREG_B(dest, ((i & 0xf) << 1)));
}
else
{
- WRITE8(rsp, ea, R_VREG_S(dest, (i & 0x7)) >> 7);
+ WRITE8(rsp, ea, VREG_S(dest, (i & 0x7)) >> 7);
}
ea++;
}
@@ -842,11 +809,11 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
{
if ((i & 0xf) < 8)
{
- WRITE8(rsp, ea, R_VREG_S(dest, (i & 0x7)) >> 7);
+ WRITE8(rsp, ea, VREG_S(dest, (i & 0x7)) >> 7);
}
else
{
- WRITE8(rsp, ea, R_VREG_B(dest, ((i & 0x7) << 1)));
+ WRITE8(rsp, ea, VREG_B(dest, ((i & 0x7) << 1)));
}
ea++;
}
@@ -865,8 +832,8 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
for (i=0; i < 8; i++)
{
- UINT8 d = ((R_VREG_B(dest, ((index + (i << 1) + 0) & 0xf))) << 1) |
- ((R_VREG_B(dest, ((index + (i << 1) + 1) & 0xf))) >> 7);
+ UINT8 d = ((VREG_B(dest, ((index + (i << 1) + 0) & 0xf))) << 1) |
+ ((VREG_B(dest, ((index + (i << 1) + 1) & 0xf))) >> 7);
WRITE8(rsp, ea, d);
ea += 2;
@@ -895,7 +862,7 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
for (i=index >> 1; i < end; i++)
{
- WRITE8(rsp, ea + (eaoffset & 0xf), R_VREG_S(dest, i) >> 7);
+ WRITE8(rsp, ea + (eaoffset & 0xf), VREG_S(dest, i) >> 7);
eaoffset += 4;
}
break;
@@ -919,7 +886,7 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
for (i=index; i < end; i++)
{
- WRITE8(rsp, ea + (eaoffset & 0xf), R_VREG_B(dest, i & 0xf));
+ WRITE8(rsp, ea + (eaoffset & 0xf), VREG_B(dest, i & 0xf));
eaoffset++;
}
break;
@@ -940,18 +907,15 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
ve = 32;
element = 8 - (index >> 1);
- if (index & 0x1) fatalerror("RSP: STV: index = %d at %08X\n", index, rsp->ppc);
ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
- if (ea & 0x1) fatalerror("RSP: STV: ea = %08X at %08X\n", ea, rsp->ppc);
-
eaoffset = (ea & 0xf) + (element * 2);
ea &= ~0xf;
for (i=vs; i < ve; i++)
{
- WRITE16(rsp, ea + (eaoffset & 0xf), R_VREG_S(i, element & 0x7));
+ WRITE16(rsp, ea + (eaoffset & 0xf), VREG_S(i, element & 0x7));
eaoffset += 2;
element++;
}
@@ -968,15 +932,15 @@ static void handle_swc2(rsp_state *rsp, UINT32 op)
INLINE UINT16 SATURATE_ACCUM(rsp_state *rsp, int accum, int slice, UINT16 negative, UINT16 positive)
{
- if ((INT16)R_ACCUM_H(accum) < 0)
+ if ((INT16)ACCUM_H(accum) < 0)
{
- if ((UINT16)(R_ACCUM_H(accum)) != 0xffff)
+ if ((UINT16)(ACCUM_H(accum)) != 0xffff)
{
return negative;
}
else
{
- if ((INT16)R_ACCUM_M(accum) >= 0)
+ if ((INT16)ACCUM_M(accum) >= 0)
{
return negative;
}
@@ -984,24 +948,24 @@ INLINE UINT16 SATURATE_ACCUM(rsp_state *rsp, int accum, int slice, UINT16 negati
{
if (slice == 0)
{
- return R_ACCUM_L(accum);
+ return ACCUM_L(accum);
}
else if (slice == 1)
{
- return R_ACCUM_M(accum);
+ return ACCUM_M(accum);
}
}
}
}
else
{
- if ((UINT16)(R_ACCUM_H(accum)) != 0)
+ if ((UINT16)(ACCUM_H(accum)) != 0)
{
return positive;
}
else
{
- if ((INT16)R_ACCUM_M(accum) < 0)
+ if ((INT16)ACCUM_M(accum) < 0)
{
return positive;
}
@@ -1009,11 +973,11 @@ INLINE UINT16 SATURATE_ACCUM(rsp_state *rsp, int accum, int slice, UINT16 negati
{
if (slice == 0)
{
- return R_ACCUM_L(accum);
+ return ACCUM_L(accum);
}
else
{
- return R_ACCUM_M(accum);
+ return ACCUM_M(accum);
}
}
}
@@ -1022,17 +986,49 @@ INLINE UINT16 SATURATE_ACCUM(rsp_state *rsp, int accum, int slice, UINT16 negati
return 0;
}
-#define WRITEBACK_RESULT() \
- do { \
- W_VREG_S(VDREG, 0, vres[0]); \
- W_VREG_S(VDREG, 1, vres[1]); \
- W_VREG_S(VDREG, 2, vres[2]); \
- W_VREG_S(VDREG, 3, vres[3]); \
- W_VREG_S(VDREG, 4, vres[4]); \
- W_VREG_S(VDREG, 5, vres[5]); \
- W_VREG_S(VDREG, 6, vres[6]); \
- W_VREG_S(VDREG, 7, vres[7]); \
- } while(0)
+INLINE UINT16 SATURATE_ACCUM1(rsp_state *rsp, int accum, UINT16 negative, UINT16 positive)
+{
+ if ((INT16)ACCUM_H(accum) < 0)
+ {
+ if ((UINT16)(ACCUM_H(accum)) != 0xffff)
+ {
+ return negative;
+ }
+ else
+ {
+ if ((INT16)ACCUM_M(accum) >= 0)
+ {
+ return negative;
+ }
+ else
+ {
+ return ACCUM_M(accum);
+ }
+ }
+ }
+ else
+ {
+ if ((UINT16)(ACCUM_H(accum)) != 0)
+ {
+ return positive;
+ }
+ else
+ {
+ if ((INT16)ACCUM_M(accum) < 0)
+ {
+ return positive;
+ }
+ else
+ {
+ return ACCUM_M(accum);
+ }
+ }
+ }
+
+ return 0;
+}
+
+#define WRITEBACK_RESULT() {memcpy(&rsp->v[VDREG].s[0], &vres[0], 16);}
#if 0
static float float_round(float input)
@@ -1055,6 +1051,10 @@ static float float_round(float input)
static void handle_vector_ops(rsp_state *rsp, UINT32 op)
{
int i;
+ UINT32 VS1REG = (op >> 11) & 0x1f;
+ UINT32 VS2REG = (op >> 16) & 0x1f;
+ UINT32 VDREG = (op >> 6) & 0x1f;
+ UINT32 EL = (op >> 21) & 0xf;
INT16 vres[8];
// Opcode legend:
@@ -1074,28 +1074,30 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Multiplies signed integer by signed integer * 2
+ int sel;
+ INT32 s1, s2;
+ INT64 r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
if (s1 == -32768 && s2 == -32768)
{
// overflow
- W_ACCUM_H(del, 0);
- W_ACCUM_M(del, -32768);
- W_ACCUM_L(del, -32768);
- vres[del] = 0x7fff;
+ ACCUM_H(i) = 0;
+ ACCUM_M(i) = -32768;
+ ACCUM_L(i) = -32768;
+ vres[i] = 0x7fff;
}
else
{
- INT64 r = s1 * s2 * 2;
+ r = s1 * s2 * 2;
r += 0x8000; // rounding ?
- W_ACCUM_H(del, (r < 0) ? 0xffff : 0); // sign-extend to 48-bit
- W_ACCUM_M(del, (INT16)(r >> 16));
- W_ACCUM_L(del, (UINT16)(r));
- vres[del] = R_ACCUM_M(del);
+ ACCUM_H(i) = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
+ ACCUM_M(i) = (INT16)(r >> 16);
+ ACCUM_L(i) = (UINT16)(r);
+ vres[i] = ACCUM_M(i);
}
}
WRITEBACK_RESULT();
@@ -1111,30 +1113,32 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// ------------------------------------------------------
//
+ int sel;
+ INT32 s1, s2;
+ INT64 r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT64 r = s1 * s2 * 2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 * s2 * 2;
r += 0x8000; // rounding ?
- W_ACCUM_H(del, (UINT16)(r >> 32));
- W_ACCUM_M(del, (UINT16)(r >> 16));
- W_ACCUM_L(del, (UINT16)(r));
+ ACCUM_H(i) = (UINT16)(r >> 32);
+ ACCUM_M(i) = (UINT16)(r >> 16);
+ ACCUM_L(i) = (UINT16)(r);
if (r < 0)
{
- vres[del] = 0;
+ vres[i] = 0;
}
- else if (((INT16)(R_ACCUM_H(del)) ^ (INT16)(R_ACCUM_M(del))) < 0)
+ else if (((INT16)(ACCUM_H(i)) ^ (INT16)(ACCUM_M(i))) < 0)
{
- vres[del] = -1;
+ vres[i] = -1;
}
else
{
- vres[del] = R_ACCUM_M(del);
+ vres[i] = ACCUM_M(i);
}
}
WRITEBACK_RESULT();
@@ -1152,19 +1156,21 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// Stores the higher 16 bits of the 32-bit result to accumulator
// The low slice of accumulator is stored into destination element
+ int sel;
+ UINT32 s1, s2;
+ UINT32 r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- UINT32 s1 = (UINT32)(UINT16)R_VREG_S(VS1REG, del);
- UINT32 s2 = (UINT32)(UINT16)R_VREG_S(VS2REG, sel);
- UINT32 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
+ s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
+ r = s1 * s2;
- W_ACCUM_H(del, 0);
- W_ACCUM_M(del, 0);
- W_ACCUM_L(del, (UINT16)(r >> 16));
+ ACCUM_H(i) = 0;
+ ACCUM_M(i) = 0;
+ ACCUM_L(i) = (UINT16)(r >> 16);
- vres[del] = R_ACCUM_L(del);
+ vres[i] = ACCUM_L(i);
}
WRITEBACK_RESULT();
break;
@@ -1181,19 +1187,21 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// The result is stored into accumulator
// The middle slice of accumulator is stored into destination element
+ int sel;
+ INT32 s1, s2;
+ INT32 r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (UINT16)R_VREG_S(VS2REG, sel); // not sign-extended
- INT32 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (UINT16)VREG_S(VS2REG, sel); // not sign-extended
+ r = s1 * s2;
- W_ACCUM_H(del, (r < 0) ? 0xffff : 0); // sign-extend to 48-bit
- W_ACCUM_M(del, (INT16)(r >> 16));
- W_ACCUM_L(del, (UINT16)(r));
+ ACCUM_H(i) = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
+ ACCUM_M(i) = (INT16)(r >> 16);
+ ACCUM_L(i) = (UINT16)(r);
- vres[del] = R_ACCUM_M(del);
+ vres[i] = ACCUM_M(i);
}
WRITEBACK_RESULT();
break;
@@ -1211,19 +1219,21 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// The result is stored into accumulator
// The low slice of accumulator is stored into destination element
+ int sel;
+ INT32 s1, s2;
+ INT32 r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (UINT16)R_VREG_S(VS1REG, del); // not sign-extended
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT16)VREG_S(VS1REG, i); // not sign-extended
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 * s2;
- W_ACCUM_H(del, (r < 0) ? 0xffff : 0); // sign-extend to 48-bit
- W_ACCUM_M(del, (INT16)(r >> 16));
- W_ACCUM_L(del, (UINT16)(r));
+ ACCUM_H(i) = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
+ ACCUM_M(i) = (INT16)(r >> 16);
+ ACCUM_L(i) = (UINT16)(r);
- vres[del] = R_ACCUM_L(del);
+ vres[i] = ACCUM_L(i);
}
WRITEBACK_RESULT();
break;
@@ -1240,21 +1250,23 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// The result is stored into highest 32 bits of accumulator, the low slice is zero
// The highest 32 bits of accumulator is saturated into destination element
+ int sel;
+ INT32 s1, s2;
+ INT32 r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 * s2;
- W_ACCUM_H(del, (INT16)(r >> 16));
- W_ACCUM_M(del, (UINT16)(r));
- W_ACCUM_L(del, 0);
+ ACCUM_H(i) = (INT16)(r >> 16);
+ ACCUM_M(i) = (UINT16)(r);
+ ACCUM_L(i) = 0;
if (r < -32768) r = -32768;
if (r > 32767) r = 32767;
- vres[del] = (INT16)(r);
+ vres[i] = (INT16)(r);
}
WRITEBACK_RESULT();
break;
@@ -1270,19 +1282,21 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// Multiplies signed integer by signed integer * 2
// The result is added to accumulator
+ int sel;
+ INT32 s1, s2;
+ INT32 r;
+ UINT16 res;
for (i=0; i < 8; i++)
{
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 * s2;
- ACCUM(del) += (INT64)(r) << 17;
- res = SATURATE_ACCUM(rsp, del, 1, 0x8000, 0x7fff);
+ ACCUM(i) += (INT64)(r) << 17;
+ res = SATURATE_ACCUM(rsp, i, 1, 0x8000, 0x7fff);
- vres[del] = res;
+ vres[i] = res;
}
WRITEBACK_RESULT();
break;
@@ -1296,46 +1310,48 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// ------------------------------------------------------
//
- for (i=0; i < 8; i++)
- {
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r1 = s1 * s2;
- UINT32 r2 = (UINT16)R_ACCUM_L(del) + ((UINT16)(r1) * 2);
- UINT32 r3 = (UINT16)R_ACCUM_M(del) + (UINT16)((r1 >> 16) * 2) + (UINT16)(r2 >> 16);
-
- W_ACCUM_L(del, (UINT16)(r2));
- W_ACCUM_M(del, (UINT16)(r3));
- W_ACCUM_H(del, (UINT16)R_ACCUM_H(del) + (UINT16)(r3 >> 16) + (UINT16)(r1 >> 31));
-
- //res = SATURATE_ACCUM(rsp, del, 1, 0x0000, 0xffff);
- if ((INT16)R_ACCUM_H(del) < 0)
+ UINT16 res;
+ int sel;
+ INT32 s1, s2, r1;
+ UINT32 r2, r3;
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r1 = s1 * s2;
+ r2 = (UINT16)ACCUM_L(i) + ((UINT16)(r1) * 2);
+ r3 = (UINT16)ACCUM_M(i) + (UINT16)((r1 >> 16) * 2) + (UINT16)(r2 >> 16);
+
+ ACCUM_L(i) = (UINT16)(r2);
+ ACCUM_M(i) = (UINT16)(r3);
+ ACCUM_H(i) += (UINT16)(r3 >> 16) + (UINT16)(r1 >> 31);
+
+ //res = SATURATE_ACCUM(i, 1, 0x0000, 0xffff);
+ if ((INT16)ACCUM_H(i) < 0)
{
res = 0;
}
else
{
- if (R_ACCUM_H(del) != 0)
+ if (ACCUM_H(i) != 0)
{
res = 0xffff;
}
else
{
- if ((INT16)R_ACCUM_M(del) < 0)
+ if ((INT16)ACCUM_M(i) < 0)
{
res = 0xffff;
}
else
{
- res = R_ACCUM_M(del);
+ res = ACCUM_M(i);
}
}
}
- vres[del] = res;
+ vres[i] = res;
}
WRITEBACK_RESULT();
break;
@@ -1352,24 +1368,26 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// Adds the higher 16 bits of the 32-bit result to accumulator
// The low slice of accumulator is stored into destination element
- for (i=0; i < 8; i++)
+ UINT16 res;
+ int sel;
+ UINT32 s1, s2, r1;
+ UINT32 r2, r3;
+ for (i = 0; i < 8; i++)
{
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- UINT32 s1 = (UINT32)(UINT16)R_VREG_S(VS1REG, del);
- UINT32 s2 = (UINT32)(UINT16)R_VREG_S(VS2REG, sel);
- UINT32 r1 = s1 * s2;
- UINT32 r2 = (UINT16)R_ACCUM_L(del) + (r1 >> 16);
- UINT32 r3 = (UINT16)R_ACCUM_M(del) + (r2 >> 16);
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
+ s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
+ r1 = s1 * s2;
+ r2 = (UINT16)ACCUM_L(i) + (r1 >> 16);
+ r3 = (UINT16)ACCUM_M(i) + (r2 >> 16);
- W_ACCUM_L(del, (UINT16)(r2));
- W_ACCUM_M(del, (UINT16)(r3));
- W_ACCUM_H(del, (INT16)R_ACCUM_H(del) + (INT16)(r3 >> 16));
+ ACCUM_L(i) = (UINT16)(r2);
+ ACCUM_M(i) = (UINT16)(r3);
+ ACCUM_H(i) += (INT16)(r3 >> 16);
- res = SATURATE_ACCUM(rsp, del, 0, 0x0000, 0xffff);
+ res = SATURATE_ACCUM(rsp, i, 0, 0x0000, 0xffff);
- vres[del] = res;
+ vres[i] = res;
}
WRITEBACK_RESULT();
break;
@@ -1386,26 +1404,28 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// The result is added into accumulator
// The middle slice of accumulator is stored into destination element
+ UINT16 res;
+ int sel;
+ UINT32 s1, s2, r1;
+ UINT32 r2, r3;
for (i=0; i < 8; i++)
{
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- UINT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- UINT32 s2 = (UINT16)R_VREG_S(VS2REG, sel); // not sign-extended
- UINT32 r1 = s1 * s2;
- UINT32 r2 = (UINT16)R_ACCUM_L(del) + (UINT16)(r1);
- UINT32 r3 = (UINT16)R_ACCUM_M(del) + (r1 >> 16) + (r2 >> 16);
-
- W_ACCUM_L(del, (UINT16)(r2));
- W_ACCUM_M(del, (UINT16)(r3));
- W_ACCUM_H(del, (UINT16)R_ACCUM_H(del) + (UINT16)(r3 >> 16));
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (UINT16)VREG_S(VS2REG, sel); // not sign-extended
+ r1 = s1 * s2;
+ r2 = (UINT16)ACCUM_L(i) + (UINT16)(r1);
+ r3 = (UINT16)ACCUM_M(i) + (r1 >> 16) + (r2 >> 16);
+
+ ACCUM_L(i) = (UINT16)(r2);
+ ACCUM_M(i) = (UINT16)(r3);
+ ACCUM_H(i) += (UINT16)(r3 >> 16);
if ((INT32)(r1) < 0)
- W_ACCUM_H(del, (UINT16)R_ACCUM_H(del) - 1);
+ ACCUM_H(i) -= 1;
- res = SATURATE_ACCUM(rsp, del, 1, 0x8000, 0x7fff);
+ res = SATURATE_ACCUM(rsp, i, 1, 0x8000, 0x7fff);
- vres[del] = res;
+ vres[i] = res;
}
WRITEBACK_RESULT();
break;
@@ -1422,28 +1442,22 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// The result is added into accumulator
// The low slice of accumulator is stored into destination element
+ INT32 s1, s2;
+ UINT16 res;
+ int sel;
for (i=0; i < 8; i++)
{
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (UINT16)R_VREG_S(VS1REG, del); // not sign-extended
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- UINT32 r1 = s1 * s2;
- UINT32 r2 = (UINT16)R_ACCUM_L(del) + (UINT16)(r1);
- UINT32 r3 = (UINT16)R_ACCUM_M(del) + (r1 >> 16) + (r2 >> 16);
-
- W_ACCUM_L(del, (UINT16)(r2));
- W_ACCUM_M(del, (UINT16)(r3));
- W_ACCUM_H(del, (UINT16)R_ACCUM_H(del) + (UINT16)(r3 >> 16));
- if ((INT32)(r1) < 0)
- W_ACCUM_H(del, (UINT16)R_ACCUM_H(del) - 1);
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT16)VREG_S(VS1REG, i); // not sign-extended
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
- res = SATURATE_ACCUM(rsp, del, 0, 0x0000, 0xffff);
+ ACCUM(i) += (INT64)(s1*s2)<<16;
- vres[del] = res;
+ res = SATURATE_ACCUM(rsp, i, 0, 0x0000, 0xffff);
+ vres[i] = res;
}
WRITEBACK_RESULT();
+
break;
}
@@ -1458,22 +1472,23 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// The result is added into highest 32 bits of accumulator, the low slice is zero
// The highest 32 bits of accumulator is saturated into destination element
- for (i=0; i < 8; i++)
+ UINT16 res;
+ int sel;
+ INT32 s1, s2;
+ for (i = 0; i < 8; i++)
{
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT64 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
- ACCUM(del) += (INT64)(r) << 32;
+ rsp->accum[i].l[1] += s1*s2;
- res = SATURATE_ACCUM(rsp, del, 1, 0x8000, 0x7fff);
+ res = SATURATE_ACCUM1(rsp, i, 0x8000, 0x7fff);
- vres[del] = res;
+ vres[i] = res;
}
WRITEBACK_RESULT();
+
break;
}
@@ -1488,19 +1503,20 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// TODO: check VS2REG == VDREG
+ int sel;
+ INT32 s1, s2, r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 + s2 + CARRY_FLAG(del);
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 + s2 + CARRY_FLAG(i);
- W_ACCUM_L(del, (INT16)(r));
+ ACCUM_L(i) = (INT16)(r);
if (r > 32767) r = 32767;
if (r < -32768) r = -32768;
- vres[del] = (INT16)(r);
+ vres[i] = (INT16)(r);
}
CLEAR_ZERO_FLAGS();
CLEAR_CARRY_FLAGS();
@@ -1519,20 +1535,21 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// TODO: check VS2REG == VDREG
- for (i=0; i < 8; i++)
+ int sel;
+ INT32 s1, s2, r;
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 - s2 - CARRY_FLAG(del);
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 - s2 - CARRY_FLAG(i);
- W_ACCUM_L(del, (INT16)(r));
+ ACCUM_L(i) = (INT16)(r);
if (r > 32767) r = 32767;
if (r < -32768) r = -32768;
- vres[del] = (INT16)(r);
+ vres[i] = (INT16)(r);
}
CLEAR_ZERO_FLAGS();
CLEAR_CARRY_FLAGS();
@@ -1550,34 +1567,35 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// Changes the sign of source register 2 if source register 1 is negative and stores
// the result to destination register
+ int sel;
+ INT16 s1, s2;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT16 s1 = (INT16)R_VREG_S(VS1REG, del);
- INT16 s2 = (INT16)R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT16)VREG_S(VS1REG, i);
+ s2 = (INT16)VREG_S(VS2REG, sel);
if (s1 < 0)
{
if (s2 == -32768)
{
- vres[del] = 32767;
+ vres[i] = 32767;
}
else
{
- vres[del] = -s2;
+ vres[i] = -s2;
}
}
else if (s1 > 0)
{
- vres[del] = s2;
+ vres[i] = s2;
}
else
{
- vres[del] = 0;
+ vres[i] = 0;
}
- W_ACCUM_L(del, vres[del]);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -1594,23 +1612,24 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// TODO: check VS2REG = VDREG
+ int sel;
+ INT32 s1, s2, r;
CLEAR_ZERO_FLAGS();
CLEAR_CARRY_FLAGS();
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (UINT32)(UINT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (UINT32)(UINT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 + s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
+ s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
+ r = s1 + s2;
- vres[del] = (INT16)(r);
- W_ACCUM_L(del, (INT16)(r));
+ vres[i] = (INT16)(r);
+ ACCUM_L(i) = (INT16)(r);
if (r & 0xffff0000)
{
- SET_CARRY_FLAG(del);
+ SET_CARRY_FLAG(i);
}
}
WRITEBACK_RESULT();
@@ -1628,27 +1647,28 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// TODO: check VS2REG = VDREG
+ int sel;
+ INT32 s1, s2, r;
CLEAR_ZERO_FLAGS();
CLEAR_CARRY_FLAGS();
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (UINT32)(UINT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (UINT32)(UINT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 - s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
+ s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
+ r = s1 - s2;
- vres[del] = (INT16)(r);
- W_ACCUM_L(del, (UINT16)(r));
+ vres[i] = (INT16)(r);
+ ACCUM_L(i) = (UINT16)(r);
if ((UINT16)(r) != 0)
{
- SET_ZERO_FLAG(del);
+ SET_ZERO_FLAG(i);
}
if (r & 0xffff0000)
{
- SET_CARRY_FLAG(del);
+ SET_CARRY_FLAG(i);
}
}
WRITEBACK_RESULT();
@@ -1670,7 +1690,7 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
{
for (i=0; i < 8; i++)
{
- W_VREG_S(VDREG, i, R_ACCUM_H(i));
+ VREG_S(VDREG, i) = ACCUM_H(i);
}
break;
}
@@ -1678,7 +1698,7 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
{
for (i=0; i < 8; i++)
{
- W_VREG_S(VDREG, i, R_ACCUM_M(i));
+ VREG_S(VDREG, i) = ACCUM_M(i);
}
break;
}
@@ -1686,11 +1706,13 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
{
for (i=0; i < 8; i++)
{
- W_VREG_S(VDREG, i, R_ACCUM_L(i));
+ VREG_S(VDREG, i) = ACCUM_L(i);
}
break;
}
- default: fatalerror("RSP: VSAW: el = %d\n", EL);
+ default: //fatalerror("RSP: VSAW: el = %d\n", EL);//ïîòóïèì
+ printf("RSP: VSAW: el = %d\n", EL);//ìîé êîä
+ exit(0);
}
break;
}
@@ -1705,36 +1727,38 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// Sets compare flags if elements in VS1 are less than VS2
// Moves the element in VS2 to destination vector
+ int sel;
rsp->flag[1] = 0;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
+ sel = VEC_EL_2(EL, i);
- if (R_VREG_S(VS1REG, del) < R_VREG_S(VS2REG, sel))
+ if (VREG_S(VS1REG, i) < VREG_S(VS2REG, sel))
{
- vres[del] = R_VREG_S(VS1REG, del);
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
- else if (R_VREG_S(VS1REG, del) == R_VREG_S(VS2REG, sel))
+ else if (VREG_S(VS1REG, i) == VREG_S(VS2REG, sel))
{
- vres[del] = R_VREG_S(VS1REG, del);
- if (ZERO_FLAG(del) != 0 && CARRY_FLAG(del) != 0)
+ if (ZERO_FLAG(i) == 1 && CARRY_FLAG(i) != 0)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
}
+
+ if (COMPARE_FLAG(i))
+ {
+ vres[i] = VREG_S(VS1REG, i);
+ }
else
{
- vres[del] = R_VREG_S(VS2REG, sel);
+ vres[i] = VREG_S(VS2REG, sel);
}
- W_ACCUM_L(del, vres[del]);
+ ACCUM_L(i) = vres[i];
}
- CLEAR_ZERO_FLAGS();
- CLEAR_CARRY_FLAGS();
+ rsp->flag[0] = 0;
WRITEBACK_RESULT();
break;
}
@@ -1749,27 +1773,26 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// Sets compare flags if elements in VS1 are equal with VS2
// Moves the element in VS2 to destination vector
+ int sel;
rsp->flag[1] = 0;
- for (i=0; i < 8; i++)
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
+ sel = VEC_EL_2(EL, i);
- vres[del] = R_VREG_S(VS2REG, sel);
- W_ACCUM_L(del, vres[del]);
-
- if (R_VREG_S(VS1REG, del) == R_VREG_S(VS2REG, sel))
+ if ((VREG_S(VS1REG, i) == VREG_S(VS2REG, sel)) && ZERO_FLAG(i) == 0)
{
- if (ZERO_FLAG(del) == 0)
- {
- SET_COMPARE_FLAG(del);
- }
+ SET_COMPARE_FLAG(i);
+ vres[i] = VREG_S(VS1REG, i);
+ }
+ else
+ {
+ vres[i] = VREG_S(VS2REG, sel);
}
+ ACCUM_L(i) = vres[i];
}
- CLEAR_ZERO_FLAGS();
- CLEAR_CARRY_FLAGS();
+ rsp->flag[0] = 0;
WRITEBACK_RESULT();
break;
}
@@ -1784,31 +1807,36 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// Sets compare flags if elements in VS1 are not equal with VS2
// Moves the element in VS2 to destination vector
+ int sel;
rsp->flag[1] = 0;
- for (i=0; i < 8; i++)
+ for (i=0; i < 8; i++)//ïåðåïèñàíî ìíîé
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
-
- vres[del] = R_VREG_S(VS1REG, del);
- W_ACCUM_L(del, vres[del]);
+ sel = VEC_EL_2(EL, i);
- if (R_VREG_S(VS1REG, del) != R_VREG_S(VS2REG, sel))
+ if (VREG_S(VS1REG, i) != VREG_S(VS2REG, sel))
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
else
{
- if (ZERO_FLAG(del) != 0)
+ if (ZERO_FLAG(i) == 1)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
}
+ if (COMPARE_FLAG(i))
+ {
+ vres[i] = VREG_S(VS1REG, i);
+ }
+ else
+ {
+ vres[i] = VREG_S(VS2REG, sel);
+ }
+ ACCUM_L(i) = vres[i];
}
- CLEAR_ZERO_FLAGS();
- CLEAR_CARRY_FLAGS();
+ rsp->flag[0] = 0;
WRITEBACK_RESULT();
break;
}
@@ -1823,39 +1851,38 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// Sets compare flags if elements in VS1 are greater or equal with VS2
// Moves the element in VS2 to destination vector
+ int sel;
rsp->flag[1] = 0;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
+ sel = VEC_EL_2(EL, i);
- if (R_VREG_S(VS1REG, del) == R_VREG_S(VS2REG, sel))
+ if (VREG_S(VS1REG, i) == VREG_S(VS2REG, sel))
{
- if (ZERO_FLAG(del) == 0 || CARRY_FLAG(del) == 0)
+ if (ZERO_FLAG(i) == 0 || CARRY_FLAG(i) == 0)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
}
- else if (R_VREG_S(VS1REG, del) > R_VREG_S(VS2REG, sel))
+ else if (VREG_S(VS1REG, i) > VREG_S(VS2REG, sel))
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
- if (COMPARE_FLAG(del) != 0)
+ if (COMPARE_FLAG(i) != 0)
{
- vres[del] = R_VREG_S(VS1REG, del);
+ vres[i] = VREG_S(VS1REG, i);
}
else
{
- vres[del] = R_VREG_S(VS2REG, sel);
+ vres[i] = VREG_S(VS2REG, sel);
}
- W_ACCUM_L(del, vres[del]);
+ ACCUM_L(i) = vres[i];
}
- CLEAR_ZERO_FLAGS();
- CLEAR_CARRY_FLAGS();
+ rsp->flag[0] = 0;
WRITEBACK_RESULT();
break;
}
@@ -1869,88 +1896,96 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Vector clip low
- for (i=0; i < 8; i++)
+ int sel;
+ INT16 s1, s2;
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT16 s1 = R_VREG_S(VS1REG, del);
- INT16 s2 = R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = VREG_S(VS1REG, i);
+ s2 = VREG_S(VS2REG, sel);
- if (CARRY_FLAG(del) != 0)
+ if (CARRY_FLAG(i) != 0)
{
- if (ZERO_FLAG(del) != 0)
+
+ if (ZERO_FLAG(i) != 0)
{
- if (COMPARE_FLAG(del) != 0)
+
+ if (COMPARE_FLAG(i) != 0)
{
- W_ACCUM_L(del, -(UINT16)s2);
+ ACCUM_L(i) = -(UINT16)s2;
}
else
{
- W_ACCUM_L(del, s1);
+ ACCUM_L(i) = s1;
}
}
- else
+ else//ZERO_FLAG(i)==0
{
- if (rsp->flag[2] & (1 << (del)))
+
+ if (rsp->flag[2] & (1 << (i)))
{
+
if (((UINT32)(UINT16)(s1) + (UINT32)(UINT16)(s2)) > 0x10000)
- {
- W_ACCUM_L(del, s1);
- CLEAR_COMPARE_FLAG(del);
+ {//proper fix for Harvest Moon 64, r4
+
+ ACCUM_L(i) = s1;
+ CLEAR_COMPARE_FLAG(i);
}
else
{
- W_ACCUM_L(del, -((UINT16)s2));
- SET_COMPARE_FLAG(del);
+
+ ACCUM_L(i) = -((UINT16)s2);
+ SET_COMPARE_FLAG(i);
}
}
else
{
- if (((UINT32)(INT16)(s1) + (UINT32)(INT16)(s2)) != 0)
+ if (((UINT32)(UINT16)(s1) + (UINT32)(UINT16)(s2)) != 0)
{
- W_ACCUM_L(del, s1);
- CLEAR_COMPARE_FLAG(del);
+ ACCUM_L(i) = s1;
+ CLEAR_COMPARE_FLAG(i);
}
else
{
- W_ACCUM_L(del, -((UINT16)s2));
- SET_COMPARE_FLAG(del);
+ ACCUM_L(i) = -((UINT16)s2);
+ SET_COMPARE_FLAG(i);
}
}
}
- }
- else
+ }//
+ else//CARRY_FLAG(i)==0
{
- if (ZERO_FLAG(del) != 0)
+
+ if (ZERO_FLAG(i) != 0)
{
- if (rsp->flag[1] & (1 << (8+del)))
+
+ if (rsp->flag[1] & (1 << (8+i)))
{
- W_ACCUM_L(del, s2);
+ ACCUM_L(i) = s2;
}
else
{
- W_ACCUM_L(del, s1);
+ ACCUM_L(i) = s1;
}
}
else
{
if (((INT32)(UINT16)s1 - (INT32)(UINT16)s2) >= 0)
{
- W_ACCUM_L(del, s2);
- rsp->flag[1] |= (1 << (8+del));
+ ACCUM_L(i) = s2;
+ rsp->flag[1] |= (1 << (8+i));
}
else
{
- W_ACCUM_L(del, s1);
- rsp->flag[1] &= ~(1 << (8+del));
+ ACCUM_L(i) = s1;
+ rsp->flag[1] &= ~(1 << (8+i));
}
}
}
- vres[del] = R_ACCUM_L(del);
+ vres[i] = ACCUM_L(i);
}
- CLEAR_ZERO_FLAGS();
- CLEAR_CARRY_FLAGS();
+ rsp->flag[0] = 0;
rsp->flag[2] = 0;
WRITEBACK_RESULT();
break;
@@ -1965,74 +2000,73 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Vector clip high
- CLEAR_ZERO_FLAGS();
- CLEAR_CARRY_FLAGS();
+ int sel;
+ INT16 s1, s2;
+ rsp->flag[0] = 0;
rsp->flag[1] = 0;
rsp->flag[2] = 0;
+ UINT32 vce = 0;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT16 s1 = R_VREG_S(VS1REG, del);
- INT16 s2 = R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = VREG_S(VS1REG, i);
+ s2 = VREG_S(VS2REG, sel);
if ((s1 ^ s2) < 0)
{
- SET_CARRY_FLAG(del);
+ vce = (s1 + s2 == -1);
+ SET_CARRY_FLAG(i);
if (s2 < 0)
{
- rsp->flag[1] |= (1 << (8+del));
+ rsp->flag[1] |= (1 << (8+i));
}
if (s1 + s2 <= 0)
{
- if (s1 + s2 == -1)
- {
- rsp->flag[2] |= (1 << (del));
- }
- SET_COMPARE_FLAG(del);
- vres[del] = -((UINT16)s2);
+ SET_COMPARE_FLAG(i);
+ vres[i] = -((UINT16)s2);
}
else
{
- vres[del] = s1;
+ vres[i] = s1;
}
if (s1 + s2 != 0)
{
if (s1 != ~s2)
{
- SET_ZERO_FLAG(del);
+ SET_ZERO_FLAG(i);
}
}
- }
+ }//sign
else
{
+ vce = 0;
if (s2 < 0)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
if (s1 - s2 >= 0)
{
- rsp->flag[1] |= (1 << (8+del));
- vres[del] = s2;
+ rsp->flag[1] |= (1 << (8+i));
+ vres[i] = s2;
}
else
{
- vres[del] = s1;
+ vres[i] = s1;
}
if ((s1 - s2) != 0)
{
if (s1 != ~s2)
{
- SET_ZERO_FLAG(del);
+ SET_ZERO_FLAG(i);
}
}
}
-
- W_ACCUM_L(del, vres[del]);
+ rsp->flag[2] |= (vce << (i));
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -2047,51 +2081,52 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Vector clip reverse
+ int sel;
+ INT16 s1, s2;
rsp->flag[0] = 0;
rsp->flag[1] = 0;
rsp->flag[2] = 0;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT16 s1 = R_VREG_S(VS1REG, del);
- INT16 s2 = R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = VREG_S(VS1REG, i);
+ s2 = VREG_S(VS2REG, sel);
if ((INT16)(s1 ^ s2) < 0)
{
if (s2 < 0)
{
- rsp->flag[1] |= (1 << (8+del));
+ rsp->flag[1] |= (1 << (8+i));
}
if ((s1 + s2) <= 0)
{
- W_ACCUM_L(del, ~((UINT16)s2));
- SET_COMPARE_FLAG(del);
+ ACCUM_L(i) = ~((UINT16)s2);
+ SET_COMPARE_FLAG(i);
}
else
{
- W_ACCUM_L(del, s1);
+ ACCUM_L(i) = s1;
}
}
else
{
if (s2 < 0)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
if ((s1 - s2) >= 0)
{
- W_ACCUM_L(del, s2);
- rsp->flag[1] |= (1 << (8+del));
+ ACCUM_L(i) = s2;
+ rsp->flag[1] |= (1 << (8+i));
}
else
{
- W_ACCUM_L(del, s1);
+ ACCUM_L(i) = s1;
}
}
- vres[del] = R_ACCUM_L(del);
+ vres[i] = ACCUM_L(i);
}
WRITEBACK_RESULT();
break;
@@ -2106,20 +2141,20 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Merges two vectors according to compare flags
- for (i=0; i < 8; i++)
+ int sel;
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- if (COMPARE_FLAG(del) != 0)
+ sel = VEC_EL_2(EL, i);
+ if (COMPARE_FLAG(i) != 0)
{
- vres[del] = R_VREG_S(VS1REG, del);
+ vres[i] = VREG_S(VS1REG, i);
}
else
{
- vres[del] = R_VREG_S(VS2REG, VEC_EL_2(EL, sel));
+ vres[i] = VREG_S(VS2REG, sel);//ìî¸ èñïðàâëåíèå
}
- W_ACCUM_L(del, vres[del]);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -2133,12 +2168,12 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Bitwise AND of two vector registers
- for (i=0; i < 8; i++)
+ int sel;
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- vres[del] = R_VREG_S(VS1REG, del) & R_VREG_S(VS2REG, sel);
- W_ACCUM_L(del, vres[del]);
+ sel = VEC_EL_2(EL, i);
+ vres[i] = VREG_S(VS1REG, i) & VREG_S(VS2REG, sel);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -2152,12 +2187,12 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Bitwise NOT AND of two vector registers
- for (i=0; i < 8; i++)
+ int sel;
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- vres[del] = ~((R_VREG_S(VS1REG, del) & R_VREG_S(VS2REG, sel)));
- W_ACCUM_L(del, vres[del]);
+ sel = VEC_EL_2(EL, i);
+ vres[i] = ~((VREG_S(VS1REG, i) & VREG_S(VS2REG, sel)));
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -2171,12 +2206,12 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Bitwise OR of two vector registers
- for (i=0; i < 8; i++)
+ int sel;
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- vres[del] = R_VREG_S(VS1REG, del) | R_VREG_S(VS2REG, sel);
- W_ACCUM_L(del, vres[del]);
+ sel = VEC_EL_2(EL, i);
+ vres[i] = VREG_S(VS1REG, i) | VREG_S(VS2REG, sel);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -2190,12 +2225,12 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Bitwise NOT OR of two vector registers
+ int sel;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- vres[del] = ~((R_VREG_S(VS1REG, del) | R_VREG_S(VS2REG, sel)));
- W_ACCUM_L(del, vres[del]);
+ sel = VEC_EL_2(EL, i);
+ vres[i] = ~((VREG_S(VS1REG, i) | VREG_S(VS2REG, sel)));
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -2209,12 +2244,12 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Bitwise XOR of two vector registers
+ int sel;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- vres[del] = R_VREG_S(VS1REG, del) ^ R_VREG_S(VS2REG, sel);
- W_ACCUM_L(del, vres[del]);
+ sel = VEC_EL_2(EL, i);
+ vres[i] = VREG_S(VS1REG, i) ^ VREG_S(VS2REG, sel);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -2228,12 +2263,12 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Bitwise NOT XOR of two vector registers
+ int sel;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- vres[del] = ~((R_VREG_S(VS1REG, del) ^ R_VREG_S(VS2REG, sel)));
- W_ACCUM_L(del, vres[del]);
+ sel = VEC_EL_2(EL, i);
+ vres[i] = ~((VREG_S(VS1REG, i) ^ VREG_S(VS2REG, sel)));
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
break;
@@ -2247,85 +2282,57 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
// ------------------------------------------------------
//
// Calculates reciprocal
-
- int del = (VS1REG & 7);
+ int del = VS1REG & 7;
int sel = EL & 7;
- INT32 rec;
-
- rec = (INT16)(R_VREG_S(VS2REG, sel));
+ INT32 shifter = 0;
- if (rec == 0)
+ INT32 rec = (INT16)(VREG_S(VS2REG, sel));
+ INT32 datainput = (rec < 0) ? (-rec) : rec;
+ if (datainput)
{
- // divide by zero -> overflow
- rec = 0x7fffffff;
- }
- else
- {
- int sign = 0;
- int exp = 0;
- int mantissa = 0;
-
- if (rec < 0)
+ for (i = 0; i < 32; i++)
{
- rec = -rec; // rec = MINUS rec
- sign = 1;
- }
-
- // restrict to 10-bit mantissa
- for (i = 15; i >= 0; i--)
- {
- if (rec & (1 << i))
+ if (datainput & (1 << ((~i) & 0x1f)))//ò.æ.÷òî 31 - i
{
- exp = i;
- mantissa = (rec << (15 - i)) >> 6;
+ shifter = i;
break;
}
}
+ }
+ else
+ {
+ shifter = 0x10;
+ }
- if (mantissa == 0x200)
- {
- rec = 0x7fffffff;
- }
- else
- {
- rec = 0xffffffffU / mantissa;
-
- //
- // simulate rounding error
- //
- // This has been verified on the real hardware.
- //
- // I was able to replicate this exact behaviour by using a five-round
- // Newton reciprocal method using floorf() on intermediate results
- // to force the use of IEEE 754 32bit floats.
- // However, for the sake of portability, we'll use integer arithmetic.
- //
- if (rec & 0x800)
- rec += 1;
-
- rec <<= 8;
- }
-
- // restrict result to 17 significant bits
- rec &= 0x7fffc000;
+ INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
+ INT32 fetchval = rsp_divtable[address];
+ INT32 temp = (0x40000000 | (fetchval << 14)) >> ((~shifter) & 0x1f);
+ if (rec < 0)
+ {
+ temp = ~temp;
+ }
+ if (!rec)
+ {
+ temp = 0x7fffffff;
+ }
+ else if (rec == 0xffff8000)
+ {
+ temp = 0xffff0000;
+ }
+ rec = temp;
- rec >>= exp;
+ rsp->reciprocal_res = rec;
+ rsp->dp_allowed = 0;
- if (sign)
- {
- rec = ~rec; // rec = BITWISE NOT rec
- }
- }
+ VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
- for (i=0; i < 8; i++)
+ for (i = 0; i < 8; i++)
{
- int element = VEC_EL_2(EL, i);
- W_ACCUM_L(i, R_VREG_S(VS2REG, element));
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
}
- rsp->reciprocal_res = rec;
- W_VREG_S(VDREG, del, (UINT16)(rsp->reciprocal_res)); // store low part
break;
}
@@ -2338,64 +2345,85 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Calculates reciprocal low part
- int del = (VS1REG & 7);
- int sel = VEC_EL_2(EL, del);
- INT32 rec;
+ int del = VS1REG & 7;
+ int sel = EL & 7;
+ INT32 shifter = 0;
- rec = ((UINT16)(R_VREG_S(VS2REG, sel)) | ((UINT32)(rsp->reciprocal_high) << 16));
+ INT32 rec = ((UINT16)(VREG_S(VS2REG, sel)) | ((UINT32)(rsp->reciprocal_high) & 0xffff0000));
- if (rec == 0)
- {
- // divide by zero -> overflow
- rec = 0x7fffffff;
- }
- else
+ INT32 datainput = rec;
+
+ if (rec < 0)
{
- int negative = 0;
- if (rec < 0)
+ if (rsp->dp_allowed)
{
- if (((UINT32)(rec & 0xffff0000) == 0xffff0000) && ((INT16)(rec & 0xffff) < 0))
+ if (rec < -32768)
{
- rec = ~rec+1;
+ datainput = ~datainput;
}
else
{
- rec = ~rec;
+ datainput = -datainput;
}
- negative = 1;
}
- for (i = 31; i > 0; i--)
+ else
{
- if (rec & (1 << i))
- {
- rec &= ((0xffc00000) >> (31 - i));
- i = 0;
- }
+ datainput = -datainput;
}
- rec = (0x7fffffff / rec);
- for (i = 31; i > 0; i--)
+ }
+
+
+ if (datainput)
+ {
+ for (i = 0; i < 32; i++)
{
- if (rec & (1 << i))
+ if (datainput & (1 << ((~i) & 0x1f)))//ò.æ.÷òî 31 - i
{
- rec &= ((0xffff8000) >> (31 - i));
- i = 0;
+ shifter = i;
+ break;
}
}
- if (negative)
+ }
+ else
+ {
+ if (rsp->dp_allowed)
{
- rec = ~rec;
+ shifter = 0;
+ }
+ else
+ {
+ shifter = 0x10;
}
}
- for (i=0; i < 8; i++)
+ INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
+ INT32 fetchval = rsp_divtable[address];
+ INT32 temp = (0x40000000 | (fetchval << 14)) >> ((~shifter) & 0x1f);
+ if (rec < 0)
+ {
+ temp = ~temp;
+ }
+ if (!rec)
{
- int element = VEC_EL_2(EL, i);
- W_ACCUM_L(i, R_VREG_S(VS2REG, element));
+ temp = 0x7fffffff;
}
+ else if (rec == 0xffff8000)
+ {
+ temp = 0xffff0000;
+ }
+ rec = temp;
rsp->reciprocal_res = rec;
+ rsp->dp_allowed = 0;
+
+ VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
+
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
- W_VREG_S(VDREG, del, (UINT16)(rsp->reciprocal_res)); // store low part
break;
}
@@ -2408,18 +2436,20 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Calculates reciprocal high part
- int del = (VS1REG & 7);
- int sel = VEC_EL_2(EL, del);
+ int del = VS1REG & 7;
+ int sel = EL & 7;
- rsp->reciprocal_high = R_VREG_S(VS2REG, sel);
+ rsp->reciprocal_high = (VREG_S(VS2REG, sel)) << 16;
+ rsp->dp_allowed = 1;
- for (i=0; i < 8; i++)
+ for (i = 0; i < 8; i++)
{
- int element = VEC_EL_2(EL, i);
- W_ACCUM_L(i, R_VREG_S(VS2REG, element)); // perhaps accumulator is used to store the intermediate values ?
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
}
- W_VREG_S(VDREG, del, (INT16)(rsp->reciprocal_res >> 16)); // store high part
+ VREG_S(VDREG, del) = (INT16)(rsp->reciprocal_res >> 16);
+
break;
}
@@ -2432,83 +2462,171 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Moves element from vector to destination vector
- int element = VS1REG & 7;
- W_VREG_S(VDREG, element, R_VREG_S(VS2REG, VEC_EL_2(EL, 7-element)));
+ int del = VS1REG & 7;
+ int sel = EL & 7;
+
+ VREG_S(VDREG, del) = VREG_S(VS2REG, sel);
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
break;
}
- case 0x35: /* VRSQL */
+ case 0x34: /* VRSQ */
{
// 31 25 24 20 15 10 5 0
// ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | ?FFFF | DDDDD | 110101 |
+ // | 010010 | 1 | EEEE | SSSSS | ?FFFF | DDDDD | 110100 |
// ------------------------------------------------------
//
- // Calculates reciprocal square-root low part
+ // Calculates reciprocal square-root
- int del = (VS1REG & 7);
- int sel = VEC_EL_2(EL, del);
- INT32 sqr;
+ int del = VS1REG & 7;
+ int sel = EL & 7;
+ INT32 shifter = 0;
- sqr = (UINT16)(R_VREG_S(VS2REG, sel)) | ((UINT32)(rsp->square_root_high) << 16);
+ INT32 rec = (INT16)(VREG_S(VS2REG, sel));
+ INT32 datainput = (rec < 0) ? (-rec) : rec;
+ if (datainput)
+ {
+ for (i = 0; i < 32; i++)
+ {
+ if (datainput & (1 << ((~i) & 0x1f)))//ò.æ.÷òî 31 - i
+ {
+ shifter = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ shifter = 0x10;
+ }
+
+ INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
+ address = ((address | 0x200) & 0x3fe) | (shifter & 1);
- if (sqr == 0)
+ INT32 fetchval = rsp_divtable[address];
+ INT32 temp = (0x40000000 | (fetchval << 14)) >> (((~shifter) & 0x1f) >> 1);
+ if (rec < 0)
{
- // square root on 0 -> overflow
- sqr = 0x7fffffff;
+ temp = ~temp;
}
- else if (sqr == 0xffff8000)
+ if (!rec)
{
- // overflow ?
- sqr = 0xffff8000;
+ temp = 0x7fffffff;
}
- else
+ else if (rec == 0xffff8000)
+ {
+ temp = 0xffff0000;
+ }
+ rec = temp;
+
+ rsp->reciprocal_res = rec;
+ rsp->dp_allowed = 0;
+
+ VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
+
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
+
+ break;
+ }
+
+ case 0x35: /* VRSQL */
+ {
+ // 31 25 24 20 15 10 5 0
+ // ------------------------------------------------------
+ // | 010010 | 1 | EEEE | SSSSS | ?FFFF | DDDDD | 110101 |
+ // ------------------------------------------------------
+ //
+ // Calculates reciprocal square-root low part
+
+ int del = VS1REG & 7;
+ int sel = EL & 7;
+ INT32 shifter = 0;
+
+ INT32 rec = ((UINT16)(VREG_S(VS2REG, sel)) | ((UINT32)(rsp->reciprocal_high) & 0xffff0000));
+
+ INT32 datainput = rec;
+
+ if (rec < 0)
{
- int negative = 0;
- if (sqr < 0)
+ if (rsp->dp_allowed)
{
- if (((UINT32)(sqr & 0xffff0000) == 0xffff0000) && ((INT16)(sqr & 0xffff) < 0))
+ if (rec < -32768)//VDIV.C,208
{
- sqr = ~sqr+1;
+ datainput = ~datainput;
}
else
{
- sqr = ~sqr;
+ datainput = -datainput;
}
- negative = 1;
}
- for (i = 31; i > 0; i--)
+ else
{
- if (sqr & (1 << i))
- {
- sqr &= (0xff800000 >> (31 - i));
- i = 0;
- }
+ datainput = -datainput;
}
- sqr = (INT32)(0x7fffffff / sqrt((double)sqr));
- for (i = 31; i > 0; i--)
+ }
+
+ if (datainput)
+ {
+ for (i = 0; i < 32; i++)
{
- if (sqr & (1 << i))
+ if (datainput & (1 << ((~i) & 0x1f)))
{
- sqr &= (0xffff8000 >> (31 - i));
- i = 0;
+ shifter = i;
+ break;
}
}
- if (negative)
+ }
+ else
+ {
+ if (rsp->dp_allowed)
{
- sqr = ~sqr;
+ shifter = 0;
+ }
+ else
+ {
+ shifter = 0x10;
}
}
- for (i=0; i < 8; i++)
+ INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
+ address = ((address | 0x200) & 0x3fe) | (shifter & 1);
+
+ INT32 fetchval = rsp_divtable[address];
+ INT32 temp = (0x40000000 | (fetchval << 14)) >> (((~shifter) & 0x1f) >> 1);
+ if (rec < 0)
+ {
+ temp = ~temp;
+ }
+ if (!rec)
{
- int element = VEC_EL_2(EL, i);
- W_ACCUM_L(i, R_VREG_S(VS2REG, element));
+ temp = 0x7fffffff;
}
+ else if (rec == 0xffff8000)
+ {
+ temp = 0xffff0000;
+ }
+ rec = temp;
+
+ rsp->reciprocal_res = rec;
+ rsp->dp_allowed = 0;
+
+ VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
- rsp->square_root_res = sqr;
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
- W_VREG_S(VDREG, del, (UINT16)(rsp->square_root_res)); // store low part
break;
}
@@ -2521,18 +2639,31 @@ static void handle_vector_ops(rsp_state *rsp, UINT32 op)
//
// Calculates reciprocal square-root high part
- int del = (VS1REG & 7);
- int sel = VEC_EL_2(EL, del);
+ int del = VS1REG & 7;
+ int sel = EL & 7;
- rsp->square_root_high = R_VREG_S(VS2REG, sel);
+ rsp->reciprocal_high = (VREG_S(VS2REG, sel)) << 16;
+ rsp->dp_allowed = 1;
for (i=0; i < 8; i++)
{
- int element = VEC_EL_2(EL, i);
- W_ACCUM_L(i, R_VREG_S(VS2REG, element)); // perhaps accumulator is used to store the intermediate values ?
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
}
- W_VREG_S(VDREG, del, (INT16)(rsp->square_root_res >> 16)); // store high part
+ VREG_S(VDREG, del) = (INT16)(rsp->reciprocal_res >> 16); // store high part
+ break;
+ }
+
+ case 0x37: /* VNOP */
+ {
+ // 31 25 24 20 15 10 5 0
+ // ------------------------------------------------------
+ // | 010010 | 1 | EEEE | SSSSS | ?FFFF | DDDDD | 110111 |
+ // ------------------------------------------------------
+ //
+ // Vector null instruction
+
break;
}
@@ -2658,8 +2789,8 @@ static CPU_EXECUTE( rsp )
//
int el = (op >> 7) & 0xf;
- UINT16 b1 = R_VREG_B(VS1REG, (el+0) & 0xf);
- UINT16 b2 = R_VREG_B(VS1REG, (el+1) & 0xf);
+ UINT16 b1 = VREG_B(RDREG, (el+0) & 0xf);
+ UINT16 b2 = VREG_B(RDREG, (el+1) & 0xf);
if (RTREG) RTVAL = (INT32)(INT16)((b1 << 8) | (b2));
break;
}
@@ -2695,8 +2826,8 @@ static CPU_EXECUTE( rsp )
//
int el = (op >> 7) & 0xf;
- W_VREG_B(VS1REG, (el+0) & 0xf, (RTVAL >> 8) & 0xff);
- W_VREG_B(VS1REG, (el+1) & 0xf, (RTVAL >> 0) & 0xff);
+ W_VREG_B(RDREG, (el+0) & 0xf, (RTVAL >> 8) & 0xff);
+ W_VREG_B(RDREG, (el+1) & 0xf, (RTVAL >> 0) & 0xff);
break;
}
case 0x06: /* CTC2 */
@@ -2776,7 +2907,7 @@ static CPU_EXECUTE( rsp )
if (rsp->v[i].d[0] != prev_vecs[i].d[0] || rsp->v[i].d[1] != prev_vecs[i].d[1])
{
fprintf(rsp->exec_output, "V%d: %04X|%04X|%04X|%04X|%04X|%04X|%04X|%04X ", i,
- (UINT16)R_VREG_S(i,0), (UINT16)R_VREG_S(i,1), (UINT16)R_VREG_S(i,2), (UINT16)R_VREG_S(i,3), (UINT16)R_VREG_S(i,4), (UINT16)R_VREG_S(i,5), (UINT16)R_VREG_S(i,6), (UINT16)R_VREG_S(i,7));
+ (UINT16)VREG_S(i,0), (UINT16)VREG_S(i,1), (UINT16)VREG_S(i,2), (UINT16)VREG_S(i,3), (UINT16)VREG_S(i,4), (UINT16)VREG_S(i,5), (UINT16)VREG_S(i,6), (UINT16)VREG_S(i,7));
}
prev_vecs[i].d[0] = rsp->v[i].d[0];
prev_vecs[i].d[1] = rsp->v[i].d[1];
@@ -2868,10 +2999,10 @@ CPU_GET_INFO( rsp )
switch(state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
- case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(rsp_state); break;
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(rsp_state); break;
case CPUINFO_INT_INPUT_LINES: info->i = 1; break;
case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
- case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_LITTLE; break;
+ case DEVINFO_INT_ENDIANNESS: info->i = ENDIANNESS_BIG; break;
case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 4; break;
diff --git a/src/emu/cpu/rsp/rsp.h b/src/emu/cpu/rsp/rsp.h
index efeeb023429..105c5f3c2c4 100644
--- a/src/emu/cpu/rsp/rsp.h
+++ b/src/emu/cpu/rsp/rsp.h
@@ -139,51 +139,20 @@ void rspdrc_add_dmem(running_device *device, void *base);
#define RSPDRC_STRICT_VERIFY 0x0001 /* verify all instructions */
-typedef struct
+typedef union
{
- union
- {
- UINT8 b[16];
- UINT16 s[8];
- UINT32 l[4];
- UINT64 d[2];
- };
+ UINT64 d[2];
+ UINT32 l[4];
+ INT16 s[8];
+ UINT8 b[16];
} VECTOR_REG;
-typedef struct
+typedef union
{
- union
- {
- INT64 l;
-#ifdef LSB_FIRST
- struct
- {
- INT16 z;
- INT16 low;
- INT16 mid;
- INT16 high;
- } h;
- struct
- {
- INT32 zl;
- INT32 mh;
- } w;
-#else
- struct
- {
- INT16 high;
- INT16 mid;
- INT16 low;
- INT16 z;
- } h;
- struct
- {
- INT32 mh;
- INT32 zl;
- } w;
-#endif
- };
-} ACCUMULATOR;
+ INT64 q;
+ INT32 l[2];
+ INT16 w[4];
+} ACCUMULATOR_REG;
typedef struct _rspimp_state rspimp_state;
typedef struct _rsp_state rsp_state;
@@ -199,11 +168,12 @@ struct _rsp_state
UINT32 sr;
UINT32 step_count;
- ACCUMULATOR accum[8];
+ ACCUMULATOR_REG accum[8];
INT32 square_root_res;
INT32 square_root_high;
INT32 reciprocal_res;
INT32 reciprocal_high;
+ INT32 dp_allowed;
UINT32 ppc;
UINT32 nextpc;
diff --git a/src/emu/cpu/rsp/rspdiv.h b/src/emu/cpu/rsp/rspdiv.h
new file mode 100644
index 00000000000..7f492c6f7fb
--- /dev/null
+++ b/src/emu/cpu/rsp/rspdiv.h
@@ -0,0 +1,1027 @@
+static const UINT16 rsp_divtable[1024] =
+{
+ 0xffff,
+ 0xff00,
+ 0xfe01,
+ 0xfd04,
+ 0xfc07,
+ 0xfb0c,
+ 0xfa11,
+ 0xf918,
+ 0xf81f,
+ 0xf727,
+ 0xf631,
+ 0xf53b,
+ 0xf446,
+ 0xf352,
+ 0xf25f,
+ 0xf16d,
+ 0xf07c,
+ 0xef8b,
+ 0xee9c,
+ 0xedae,
+ 0xecc0,
+ 0xebd3,
+ 0xeae8,
+ 0xe9fd,
+ 0xe913,
+ 0xe829,
+ 0xe741,
+ 0xe65a,
+ 0xe573,
+ 0xe48d,
+ 0xe3a9,
+ 0xe2c5,
+ 0xe1e1,
+ 0xe0ff,
+ 0xe01e,
+ 0xdf3d,
+ 0xde5d,
+ 0xdd7e,
+ 0xdca0,
+ 0xdbc2,
+ 0xdae6,
+ 0xda0a,
+ 0xd92f,
+ 0xd854,
+ 0xd77b,
+ 0xd6a2,
+ 0xd5ca,
+ 0xd4f3,
+ 0xd41d,
+ 0xd347,
+ 0xd272,
+ 0xd19e,
+ 0xd0cb,
+ 0xcff8,
+ 0xcf26,
+ 0xce55,
+ 0xcd85,
+ 0xccb5,
+ 0xcbe6,
+ 0xcb18,
+ 0xca4b,
+ 0xc97e,
+ 0xc8b2,
+ 0xc7e7,
+ 0xc71c,
+ 0xc652,
+ 0xc589,
+ 0xc4c0,
+ 0xc3f8,
+ 0xc331,
+ 0xc26b,
+ 0xc1a5,
+ 0xc0e0,
+ 0xc01c,
+ 0xbf58,
+ 0xbe95,
+ 0xbdd2,
+ 0xbd10,
+ 0xbc4f,
+ 0xbb8f,
+ 0xbacf,
+ 0xba10,
+ 0xb951,
+ 0xb894,
+ 0xb7d6,
+ 0xb71a,
+ 0xb65e,
+ 0xb5a2,
+ 0xb4e8,
+ 0xb42e,
+ 0xb374,
+ 0xb2bb,
+ 0xb203,
+ 0xb14b,
+ 0xb094,
+ 0xafde,
+ 0xaf28,
+ 0xae73,
+ 0xadbe,
+ 0xad0a,
+ 0xac57,
+ 0xaba4,
+ 0xaaf1,
+ 0xaa40,
+ 0xa98e,
+ 0xa8de,
+ 0xa82e,
+ 0xa77e,
+ 0xa6d0,
+ 0xa621,
+ 0xa574,
+ 0xa4c6,
+ 0xa41a,
+ 0xa36e,
+ 0xa2c2,
+ 0xa217,
+ 0xa16d,
+ 0xa0c3,
+ 0xa01a,
+ 0x9f71,
+ 0x9ec8,
+ 0x9e21,
+ 0x9d79,
+ 0x9cd3,
+ 0x9c2d,
+ 0x9b87,
+ 0x9ae2,
+ 0x9a3d,
+ 0x9999,
+ 0x98f6,
+ 0x9852,
+ 0x97b0,
+ 0x970e,
+ 0x966c,
+ 0x95cb,
+ 0x952b,
+ 0x948b,
+ 0x93eb,
+ 0x934c,
+ 0x92ad,
+ 0x920f,
+ 0x9172,
+ 0x90d4,
+ 0x9038,
+ 0x8f9c,
+ 0x8f00,
+ 0x8e65,
+ 0x8dca,
+ 0x8d30,
+ 0x8c96,
+ 0x8bfc,
+ 0x8b64,
+ 0x8acb,
+ 0x8a33,
+ 0x899c,
+ 0x8904,
+ 0x886e,
+ 0x87d8,
+ 0x8742,
+ 0x86ad,
+ 0x8618,
+ 0x8583,
+ 0x84f0,
+ 0x845c,
+ 0x83c9,
+ 0x8336,
+ 0x82a4,
+ 0x8212,
+ 0x8181,
+ 0x80f0,
+ 0x8060,
+ 0x7fd0,
+ 0x7f40,
+ 0x7eb1,
+ 0x7e22,
+ 0x7d93,
+ 0x7d05,
+ 0x7c78,
+ 0x7beb,
+ 0x7b5e,
+ 0x7ad2,
+ 0x7a46,
+ 0x79ba,
+ 0x792f,
+ 0x78a4,
+ 0x781a,
+ 0x7790,
+ 0x7706,
+ 0x767d,
+ 0x75f5,
+ 0x756c,
+ 0x74e4,
+ 0x745d,
+ 0x73d5,
+ 0x734f,
+ 0x72c8,
+ 0x7242,
+ 0x71bc,
+ 0x7137,
+ 0x70b2,
+ 0x702e,
+ 0x6fa9,
+ 0x6f26,
+ 0x6ea2,
+ 0x6e1f,
+ 0x6d9c,
+ 0x6d1a,
+ 0x6c98,
+ 0x6c16,
+ 0x6b95,
+ 0x6b14,
+ 0x6a94,
+ 0x6a13,
+ 0x6993,
+ 0x6914,
+ 0x6895,
+ 0x6816,
+ 0x6798,
+ 0x6719,
+ 0x669c,
+ 0x661e,
+ 0x65a1,
+ 0x6524,
+ 0x64a8,
+ 0x642c,
+ 0x63b0,
+ 0x6335,
+ 0x62ba,
+ 0x623f,
+ 0x61c5,
+ 0x614b,
+ 0x60d1,
+ 0x6058,
+ 0x5fdf,
+ 0x5f66,
+ 0x5eed,
+ 0x5e75,
+ 0x5dfd,
+ 0x5d86,
+ 0x5d0f,
+ 0x5c98,
+ 0x5c22,
+ 0x5bab,
+ 0x5b35,
+ 0x5ac0,
+ 0x5a4b,
+ 0x59d6,
+ 0x5961,
+ 0x58ed,
+ 0x5879,
+ 0x5805,
+ 0x5791,
+ 0x571e,
+ 0x56ac,
+ 0x5639,
+ 0x55c7,
+ 0x5555,
+ 0x54e3,
+ 0x5472,
+ 0x5401,
+ 0x5390,
+ 0x5320,
+ 0x52af,
+ 0x5240,
+ 0x51d0,
+ 0x5161,
+ 0x50f2,
+ 0x5083,
+ 0x5015,
+ 0x4fa6,
+ 0x4f38,
+ 0x4ecb,
+ 0x4e5e,
+ 0x4df1,
+ 0x4d84,
+ 0x4d17,
+ 0x4cab,
+ 0x4c3f,
+ 0x4bd3,
+ 0x4b68,
+ 0x4afd,
+ 0x4a92,
+ 0x4a27,
+ 0x49bd,
+ 0x4953,
+ 0x48e9,
+ 0x4880,
+ 0x4817,
+ 0x47ae,
+ 0x4745,
+ 0x46dc,
+ 0x4674,
+ 0x460c,
+ 0x45a5,
+ 0x453d,
+ 0x44d6,
+ 0x446f,
+ 0x4408,
+ 0x43a2,
+ 0x433c,
+ 0x42d6,
+ 0x4270,
+ 0x420b,
+ 0x41a6,
+ 0x4141,
+ 0x40dc,
+ 0x4078,
+ 0x4014,
+ 0x3fb0,
+ 0x3f4c,
+ 0x3ee8,
+ 0x3e85,
+ 0x3e22,
+ 0x3dc0,
+ 0x3d5d,
+ 0x3cfb,
+ 0x3c99,
+ 0x3c37,
+ 0x3bd6,
+ 0x3b74,
+ 0x3b13,
+ 0x3ab2,
+ 0x3a52,
+ 0x39f1,
+ 0x3991,
+ 0x3931,
+ 0x38d2,
+ 0x3872,
+ 0x3813,
+ 0x37b4,
+ 0x3755,
+ 0x36f7,
+ 0x3698,
+ 0x363a,
+ 0x35dc,
+ 0x357f,
+ 0x3521,
+ 0x34c4,
+ 0x3467,
+ 0x340a,
+ 0x33ae,
+ 0x3351,
+ 0x32f5,
+ 0x3299,
+ 0x323e,
+ 0x31e2,
+ 0x3187,
+ 0x312c,
+ 0x30d1,
+ 0x3076,
+ 0x301c,
+ 0x2fc2,
+ 0x2f68,
+ 0x2f0e,
+ 0x2eb4,
+ 0x2e5b,
+ 0x2e02,
+ 0x2da9,
+ 0x2d50,
+ 0x2cf8,
+ 0x2c9f,
+ 0x2c47,
+ 0x2bef,
+ 0x2b97,
+ 0x2b40,
+ 0x2ae8,
+ 0x2a91,
+ 0x2a3a,
+ 0x29e4,
+ 0x298d,
+ 0x2937,
+ 0x28e0,
+ 0x288b,
+ 0x2835,
+ 0x27df,
+ 0x278a,
+ 0x2735,
+ 0x26e0,
+ 0x268b,
+ 0x2636,
+ 0x25e2,
+ 0x258d,
+ 0x2539,
+ 0x24e5,
+ 0x2492,
+ 0x243e,
+ 0x23eb,
+ 0x2398,
+ 0x2345,
+ 0x22f2,
+ 0x22a0,
+ 0x224d,
+ 0x21fb,
+ 0x21a9,
+ 0x2157,
+ 0x2105,
+ 0x20b4,
+ 0x2063,
+ 0x2012,
+ 0x1fc1,
+ 0x1f70,
+ 0x1f1f,
+ 0x1ecf,
+ 0x1e7f,
+ 0x1e2e,
+ 0x1ddf,
+ 0x1d8f,
+ 0x1d3f,
+ 0x1cf0,
+ 0x1ca1,
+ 0x1c52,
+ 0x1c03,
+ 0x1bb4,
+ 0x1b66,
+ 0x1b17,
+ 0x1ac9,
+ 0x1a7b,
+ 0x1a2d,
+ 0x19e0,
+ 0x1992,
+ 0x1945,
+ 0x18f8,
+ 0x18ab,
+ 0x185e,
+ 0x1811,
+ 0x17c4,
+ 0x1778,
+ 0x172c,
+ 0x16e0,
+ 0x1694,
+ 0x1648,
+ 0x15fd,
+ 0x15b1,
+ 0x1566,
+ 0x151b,
+ 0x14d0,
+ 0x1485,
+ 0x143b,
+ 0x13f0,
+ 0x13a6,
+ 0x135c,
+ 0x1312,
+ 0x12c8,
+ 0x127f,
+ 0x1235,
+ 0x11ec,
+ 0x11a3,
+ 0x1159,
+ 0x1111,
+ 0x10c8,
+ 0x107f,
+ 0x1037,
+ 0x0fef,
+ 0x0fa6,
+ 0x0f5e,
+ 0x0f17,
+ 0x0ecf,
+ 0x0e87,
+ 0x0e40,
+ 0x0df9,
+ 0x0db2,
+ 0x0d6b,
+ 0x0d24,
+ 0x0cdd,
+ 0x0c97,
+ 0x0c50,
+ 0x0c0a,
+ 0x0bc4,
+ 0x0b7e,
+ 0x0b38,
+ 0x0af2,
+ 0x0aad,
+ 0x0a68,
+ 0x0a22,
+ 0x09dd,
+ 0x0998,
+ 0x0953,
+ 0x090f,
+ 0x08ca,
+ 0x0886,
+ 0x0842,
+ 0x07fd,
+ 0x07b9,
+ 0x0776,
+ 0x0732,
+ 0x06ee,
+ 0x06ab,
+ 0x0668,
+ 0x0624,
+ 0x05e1,
+ 0x059e,
+ 0x055c,
+ 0x0519,
+ 0x04d6,
+ 0x0494,
+ 0x0452,
+ 0x0410,
+ 0x03ce,
+ 0x038c,
+ 0x034a,
+ 0x0309,
+ 0x02c7,
+ 0x0286,
+ 0x0245,
+ 0x0204,
+ 0x01c3,
+ 0x0182,
+ 0x0141,
+ 0x0101,
+ 0x00c0,
+ 0x0080,
+ 0x0040,
+ 0x6a09,
+ 0xffff,
+ 0x6955,
+ 0xff00,
+ 0x68a1,
+ 0xfe02,
+ 0x67ef,
+ 0xfd06,
+ 0x673e,
+ 0xfc0b,
+ 0x668d,
+ 0xfb12,
+ 0x65de,
+ 0xfa1a,
+ 0x6530,
+ 0xf923,
+ 0x6482,
+ 0xf82e,
+ 0x63d6,
+ 0xf73b,
+ 0x632b,
+ 0xf648,
+ 0x6280,
+ 0xf557,
+ 0x61d7,
+ 0xf467,
+ 0x612e,
+ 0xf379,
+ 0x6087,
+ 0xf28c,
+ 0x5fe0,
+ 0xf1a0,
+ 0x5f3a,
+ 0xf0b6,
+ 0x5e95,
+ 0xefcd,
+ 0x5df1,
+ 0xeee5,
+ 0x5d4e,
+ 0xedff,
+ 0x5cac,
+ 0xed19,
+ 0x5c0b,
+ 0xec35,
+ 0x5b6b,
+ 0xeb52,
+ 0x5acb,
+ 0xea71,
+ 0x5a2c,
+ 0xe990,
+ 0x598f,
+ 0xe8b1,
+ 0x58f2,
+ 0xe7d3,
+ 0x5855,
+ 0xe6f6,
+ 0x57ba,
+ 0xe61b,
+ 0x5720,
+ 0xe540,
+ 0x5686,
+ 0xe467,
+ 0x55ed,
+ 0xe38e,
+ 0x5555,
+ 0xe2b7,
+ 0x54be,
+ 0xe1e1,
+ 0x5427,
+ 0xe10d,
+ 0x5391,
+ 0xe039,
+ 0x52fc,
+ 0xdf66,
+ 0x5268,
+ 0xde94,
+ 0x51d5,
+ 0xddc4,
+ 0x5142,
+ 0xdcf4,
+ 0x50b0,
+ 0xdc26,
+ 0x501f,
+ 0xdb59,
+ 0x4f8e,
+ 0xda8c,
+ 0x4efe,
+ 0xd9c1,
+ 0x4e6f,
+ 0xd8f7,
+ 0x4de1,
+ 0xd82d,
+ 0x4d53,
+ 0xd765,
+ 0x4cc6,
+ 0xd69e,
+ 0x4c3a,
+ 0xd5d7,
+ 0x4baf,
+ 0xd512,
+ 0x4b24,
+ 0xd44e,
+ 0x4a9a,
+ 0xd38a,
+ 0x4a10,
+ 0xd2c8,
+ 0x4987,
+ 0xd206,
+ 0x48ff,
+ 0xd146,
+ 0x4878,
+ 0xd086,
+ 0x47f1,
+ 0xcfc7,
+ 0x476b,
+ 0xcf0a,
+ 0x46e5,
+ 0xce4d,
+ 0x4660,
+ 0xcd91,
+ 0x45dc,
+ 0xccd6,
+ 0x4558,
+ 0xcc1b,
+ 0x44d5,
+ 0xcb62,
+ 0x4453,
+ 0xcaa9,
+ 0x43d1,
+ 0xc9f2,
+ 0x434f,
+ 0xc93b,
+ 0x42cf,
+ 0xc885,
+ 0x424f,
+ 0xc7d0,
+ 0x41cf,
+ 0xc71c,
+ 0x4151,
+ 0xc669,
+ 0x40d2,
+ 0xc5b6,
+ 0x4055,
+ 0xc504,
+ 0x3fd8,
+ 0xc453,
+ 0x3f5b,
+ 0xc3a3,
+ 0x3edf,
+ 0xc2f4,
+ 0x3e64,
+ 0xc245,
+ 0x3de9,
+ 0xc198,
+ 0x3d6e,
+ 0xc0eb,
+ 0x3cf5,
+ 0xc03f,
+ 0x3c7c,
+ 0xbf93,
+ 0x3c03,
+ 0xbee9,
+ 0x3b8b,
+ 0xbe3f,
+ 0x3b13,
+ 0xbd96,
+ 0x3a9c,
+ 0xbced,
+ 0x3a26,
+ 0xbc46,
+ 0x39b0,
+ 0xbb9f,
+ 0x393a,
+ 0xbaf8,
+ 0x38c5,
+ 0xba53,
+ 0x3851,
+ 0xb9ae,
+ 0x37dd,
+ 0xb90a,
+ 0x3769,
+ 0xb867,
+ 0x36f6,
+ 0xb7c5,
+ 0x3684,
+ 0xb723,
+ 0x3612,
+ 0xb681,
+ 0x35a0,
+ 0xb5e1,
+ 0x352f,
+ 0xb541,
+ 0x34bf,
+ 0xb4a2,
+ 0x344f,
+ 0xb404,
+ 0x33df,
+ 0xb366,
+ 0x3370,
+ 0xb2c9,
+ 0x3302,
+ 0xb22c,
+ 0x3293,
+ 0xb191,
+ 0x3226,
+ 0xb0f5,
+ 0x31b9,
+ 0xb05b,
+ 0x314c,
+ 0xafc1,
+ 0x30df,
+ 0xaf28,
+ 0x3074,
+ 0xae8f,
+ 0x3008,
+ 0xadf7,
+ 0x2f9d,
+ 0xad60,
+ 0x2f33,
+ 0xacc9,
+ 0x2ec8,
+ 0xac33,
+ 0x2e5f,
+ 0xab9e,
+ 0x2df6,
+ 0xab09,
+ 0x2d8d,
+ 0xaa75,
+ 0x2d24,
+ 0xa9e1,
+ 0x2cbc,
+ 0xa94e,
+ 0x2c55,
+ 0xa8bc,
+ 0x2bee,
+ 0xa82a,
+ 0x2b87,
+ 0xa799,
+ 0x2b21,
+ 0xa708,
+ 0x2abb,
+ 0xa678,
+ 0x2a55,
+ 0xa5e8,
+ 0x29f0,
+ 0xa559,
+ 0x298b,
+ 0xa4cb,
+ 0x2927,
+ 0xa43d,
+ 0x28c3,
+ 0xa3b0,
+ 0x2860,
+ 0xa323,
+ 0x27fd,
+ 0xa297,
+ 0x279a,
+ 0xa20b,
+ 0x2738,
+ 0xa180,
+ 0x26d6,
+ 0xa0f6,
+ 0x2674,
+ 0xa06c,
+ 0x2613,
+ 0x9fe2,
+ 0x25b2,
+ 0x9f59,
+ 0x2552,
+ 0x9ed1,
+ 0x24f2,
+ 0x9e49,
+ 0x2492,
+ 0x9dc2,
+ 0x2432,
+ 0x9d3b,
+ 0x23d3,
+ 0x9cb4,
+ 0x2375,
+ 0x9c2f,
+ 0x2317,
+ 0x9ba9,
+ 0x22b9,
+ 0x9b25,
+ 0x225b,
+ 0x9aa0,
+ 0x21fe,
+ 0x9a1c,
+ 0x21a1,
+ 0x9999,
+ 0x2145,
+ 0x9916,
+ 0x20e8,
+ 0x9894,
+ 0x208d,
+ 0x9812,
+ 0x2031,
+ 0x9791,
+ 0x1fd6,
+ 0x9710,
+ 0x1f7b,
+ 0x968f,
+ 0x1f21,
+ 0x960f,
+ 0x1ec7,
+ 0x9590,
+ 0x1e6d,
+ 0x9511,
+ 0x1e13,
+ 0x9492,
+ 0x1dba,
+ 0x9414,
+ 0x1d61,
+ 0x9397,
+ 0x1d09,
+ 0x931a,
+ 0x1cb1,
+ 0x929d,
+ 0x1c59,
+ 0x9221,
+ 0x1c01,
+ 0x91a5,
+ 0x1baa,
+ 0x9129,
+ 0x1b53,
+ 0x90af,
+ 0x1afc,
+ 0x9034,
+ 0x1aa6,
+ 0x8fba,
+ 0x1a50,
+ 0x8f40,
+ 0x19fa,
+ 0x8ec7,
+ 0x19a5,
+ 0x8e4f,
+ 0x1950,
+ 0x8dd6,
+ 0x18fb,
+ 0x8d5e,
+ 0x18a7,
+ 0x8ce7,
+ 0x1853,
+ 0x8c70,
+ 0x17ff,
+ 0x8bf9,
+ 0x17ab,
+ 0x8b83,
+ 0x1758,
+ 0x8b0d,
+ 0x1705,
+ 0x8a98,
+ 0x16b2,
+ 0x8a23,
+ 0x1660,
+ 0x89ae,
+ 0x160d,
+ 0x893a,
+ 0x15bc,
+ 0x88c6,
+ 0x156a,
+ 0x8853,
+ 0x1519,
+ 0x87e0,
+ 0x14c8,
+ 0x876d,
+ 0x1477,
+ 0x86fb,
+ 0x1426,
+ 0x8689,
+ 0x13d6,
+ 0x8618,
+ 0x1386,
+ 0x85a7,
+ 0x1337,
+ 0x8536,
+ 0x12e7,
+ 0x84c6,
+ 0x1298,
+ 0x8456,
+ 0x1249,
+ 0x83e7,
+ 0x11fb,
+ 0x8377,
+ 0x11ac,
+ 0x8309,
+ 0x115e,
+ 0x829a,
+ 0x1111,
+ 0x822c,
+ 0x10c3,
+ 0x81bf,
+ 0x1076,
+ 0x8151,
+ 0x1029,
+ 0x80e4,
+ 0x0fdc,
+ 0x8078,
+ 0x0f8f,
+ 0x800c,
+ 0x0f43,
+ 0x7fa0,
+ 0x0ef7,
+ 0x7f34,
+ 0x0eab,
+ 0x7ec9,
+ 0x0e60,
+ 0x7e5e,
+ 0x0e15,
+ 0x7df4,
+ 0x0dca,
+ 0x7d8a,
+ 0x0d7f,
+ 0x7d20,
+ 0x0d34,
+ 0x7cb6,
+ 0x0cea,
+ 0x7c4d,
+ 0x0ca0,
+ 0x7be5,
+ 0x0c56,
+ 0x7b7c,
+ 0x0c0c,
+ 0x7b14,
+ 0x0bc3,
+ 0x7aac,
+ 0x0b7a,
+ 0x7a45,
+ 0x0b31,
+ 0x79de,
+ 0x0ae8,
+ 0x7977,
+ 0x0aa0,
+ 0x7911,
+ 0x0a58,
+ 0x78ab,
+ 0x0a10,
+ 0x7845,
+ 0x09c8,
+ 0x77df,
+ 0x0981,
+ 0x777a,
+ 0x0939,
+ 0x7715,
+ 0x08f2,
+ 0x76b1,
+ 0x08ab,
+ 0x764d,
+ 0x0865,
+ 0x75e9,
+ 0x081e,
+ 0x7585,
+ 0x07d8,
+ 0x7522,
+ 0x0792,
+ 0x74bf,
+ 0x074d,
+ 0x745d,
+ 0x0707,
+ 0x73fa,
+ 0x06c2,
+ 0x7398,
+ 0x067d,
+ 0x7337,
+ 0x0638,
+ 0x72d5,
+ 0x05f3,
+ 0x7274,
+ 0x05af,
+ 0x7213,
+ 0x056a,
+ 0x71b3,
+ 0x0526,
+ 0x7152,
+ 0x04e2,
+ 0x70f2,
+ 0x049f,
+ 0x7093,
+ 0x045b,
+ 0x7033,
+ 0x0418,
+ 0x6fd4,
+ 0x03d5,
+ 0x6f76,
+ 0x0392,
+ 0x6f17,
+ 0x0350,
+ 0x6eb9,
+ 0x030d,
+ 0x6e5b,
+ 0x02cb,
+ 0x6dfd,
+ 0x0289,
+ 0x6da0,
+ 0x0247,
+ 0x6d43,
+ 0x0206,
+ 0x6ce6,
+ 0x01c4,
+ 0x6c8a,
+ 0x0183,
+ 0x6c2d,
+ 0x0142,
+ 0x6bd1,
+ 0x0101,
+ 0x6b76,
+ 0x00c0,
+ 0x6b1a,
+ 0x0080,
+ 0x6abf,
+ 0x0040,
+ 0x6a64
+};
diff --git a/src/emu/cpu/rsp/rspdrc.c b/src/emu/cpu/rsp/rspdrc.c
index 74814b0fa9e..1dab241ff76 100644
--- a/src/emu/cpu/rsp/rspdrc.c
+++ b/src/emu/cpu/rsp/rspdrc.c
@@ -22,6 +22,7 @@
#include "debugger.h"
#include "profiler.h"
#include "rsp.h"
+#include "rspdiv.h"
#include "rspfe.h"
#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
@@ -43,32 +44,6 @@ extern offs_t rsp_dasm_one(char *buffer, offs_t pc, UINT32 op);
#define SINGLE_INSTRUCTION_MODE (0)
-#define DRC_LSV (0)
-#define DRC_LLV (0)
-#define DRC_LDV (0)
-#define DRC_LQV (0)
-#define DRC_LPV (0)
-#define DRC_LUV (0)
-
-#define DRC_SSV (0)
-#define DRC_SLV (0)
-#define DRC_SDV (0)
-#define DRC_SQV (0)
-#define DRC_SPV (0) // Todo
-
-#define DRC_VMUDL (0)
-#define DRC_VMUDM (0)
-#define DRC_VMADM (0)
-#define DRC_VMADN (0)
-#define DRC_VMADH (0)
-#define DRC_VADD (0)
-#define DRC_VAND (0)
-#define DRC_VNAND (0)
-#define DRC_VOR (0)
-#define DRC_VNOR (0)
-#define DRC_VXOR (0)
-#define DRC_VNXOR (0)
-
/***************************************************************************
CONSTANTS
@@ -100,22 +75,6 @@ extern offs_t rsp_dasm_one(char *buffer, offs_t pc, UINT32 op);
***************************************************************************/
#define R32(reg) rsp->impstate->regmap[reg].type, rsp->impstate->regmap[reg].value
-#define VB(reg, el) rsp->impstate->regmap[16*reg+(15-el)+34].type, rsp->impstate->regmap[16*reg+(15-el)+34].value
-#define VS(reg, el) rsp->impstate->regmap[8*reg+(7-el)+546].type, rsp->impstate->regmap[8*reg+(7-el)+546].value
-#define VSX(reg, el) rsp->impstate->regmap[8*reg+el+546].type, rsp->impstate->regmap[8*reg+el+546].value
-#define VL(reg, el) rsp->impstate->regmap[4*reg+(3-el)+802].type, rsp->impstate->regmap[4*reg+(3-el)+802].value
-#define VLX(reg, el) rsp->impstate->regmap[4*reg+el+802].type, rsp->impstate->regmap[4*reg+el+802].value
-#define VFLAG(reg) rsp->impstate->regmap[930+reg].type, rsp->impstate->regmap[930+reg].value
-#define VACCUML(reg) rsp->impstate->regmap[934+reg].type, rsp->impstate->regmap[934+reg].value
-#define VACCUMHH(reg) rsp->impstate->regmap[942+reg].type, rsp->impstate->regmap[942+reg].value
-#define VACCUMHM(reg) rsp->impstate->regmap[950+reg].type, rsp->impstate->regmap[950+reg].value
-#define VACCUMHL(reg) rsp->impstate->regmap[958+reg].type, rsp->impstate->regmap[958+reg].value
-#define VACCUMHZ(reg) rsp->impstate->regmap[966+reg].type, rsp->impstate->regmap[966+reg].value
-#define VACCUMWMH(reg) rsp->impstate->regmap[974+reg].type, rsp->impstate->regmap[974+reg].value
-#define VACCUMWZL(reg) rsp->impstate->regmap[982+reg].type, rsp->impstate->regmap[982+reg].value
-#define VRES(reg) rsp->impstate->regmap[990+reg].type, rsp->impstate->regmap[990+reg].value
-
-
/***************************************************************************
STRUCTURES & TYPEDEFS
@@ -159,11 +118,12 @@ struct _rspimp_state
const char * format; /* format string for print_debug */
UINT32 arg0; /* print_debug argument 1 */
UINT32 arg1; /* print_debug argument 2 */
- UINT64 arg64; /* print_debug 64-bit argument */
+ UINT32 arg2; /* print_debug argument 3 */
+ UINT32 arg3; /* print_debug argument 4 */
UINT32 vres[8]; /* used for temporary vector results */
/* register mappings */
- drcuml_parameter regmap[998]; /* parameter to register mappings for all 32 integer registers, vector registers, flags, accumulators and temps */
+ drcuml_parameter regmap[34]; /* parameter to register mappings for all 32 integer registers */
/* subroutines */
drcuml_codehandle * entry; /* entry point */
@@ -200,47 +160,25 @@ static void cfunc_ctc2(void *param);
static void cfunc_sp_set_status_cb(void *param);
static void cfunc_rsp_lbv(void *param);
-#if !(DRC_LSV)
static void cfunc_rsp_lsv(void *param);
-#endif
-#if !(DRC_LLV)
static void cfunc_rsp_llv(void *param);
-#endif
-#if !(DRC_LDV)
static void cfunc_rsp_ldv(void *param);
-#endif
-#if !(DRC_LQV)
static void cfunc_rsp_lqv(void *param);
-#endif
static void cfunc_rsp_lrv(void *param);
-#if !(DRC_LPV)
static void cfunc_rsp_lpv(void *param);
-#endif
-#if !(DRC_LUV)
static void cfunc_rsp_luv(void *param);
-#endif
static void cfunc_rsp_lhv(void *param);
static void cfunc_rsp_lfv(void *param);
static void cfunc_rsp_lwv(void *param);
static void cfunc_rsp_ltv(void *param);
static void cfunc_rsp_sbv(void *param);
-#if !(DRC_SSV)
static void cfunc_rsp_ssv(void *param);
-#endif
-#if !(DRC_SLV)
static void cfunc_rsp_slv(void *param);
-#endif
-#if !(DRC_SDV)
static void cfunc_rsp_sdv(void *param);
-#endif
-#if !(DRC_SQV)
static void cfunc_rsp_sqv(void *param);
-#endif
static void cfunc_rsp_srv(void *param);
-#if !(DRC_SPV)
static void cfunc_rsp_spv(void *param);
-#endif
static void cfunc_rsp_suv(void *param);
static void cfunc_rsp_shv(void *param);
static void cfunc_rsp_sfv(void *param);
@@ -252,45 +190,6 @@ static void static_generate_nocode_handler(rsp_state *rsp);
static void static_generate_out_of_cycles(rsp_state *rsp);
static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrite, const char *name, drcuml_codehandle **handleptr);
-#if (DRC_VMADN)
-static void generate_saturate_accum_unsigned(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int accum);
-#endif
-#if (DRC_VMADH) || (DRC_VMADM)
-static void generate_saturate_accum_signed(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int accum);
-#endif
-#if (DRC_VMUDL)
-static int generate_vmudl(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vmudl
-#endif
-#if (DRC_VMADM)
-static int generate_vmadm(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vmadm
-#endif
-#if (DRC_VMADN)
-static int generate_vmadn(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vmadn
-#endif
-#if (DRC_VMADH)
-static int generate_vmadh(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vmadh
-#endif
-#if (DRC_VADD)
-static int generate_vadd(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vadd
-#endif
-#if (DRC_VAND)
-static int generate_vand(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vand
-#endif
-#if (DRC_VNAND)
-static int generate_vnand(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vand
-#endif
-#if (DRC_VOR)
-static int generate_vor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vand
-#endif
-#if (DRC_VNOR)
-static int generate_vnor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vand
-#endif
-#if (DRC_VXOR)
-static int generate_vxor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vand
-#endif
-#if (DRC_VNXOR)
-static int generate_vnxor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); // vand
-#endif
static int generate_lwc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
static int generate_swc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
static void generate_update_cycles(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception);
@@ -314,26 +213,15 @@ static void log_add_disasm_comment(rsp_state *rsp, drcuml_block *block, UINT32 p
#define VS2REG ((op >> 16) & 0x1f)
#define EL ((op >> 21) & 0xf)
-#define R_VREG_B(reg, offset) rsp->v[(reg)].b[15 - (offset)]
-#define R_VREG_S(reg, offset) (INT16)rsp->v[(reg)].s[7 - (offset)]
-#define R_VREG_S_X(reg, offset) (INT16)rsp->v[reg].s[offset]
-#define R_VREG_L(reg, offset) rsp->v[(reg)].l[3 - (offset)]
-#define R_VREG_D(reg, offset) rsp->v[(reg)].d[1 - (offset)]
+#define VREG_B(reg, offset) rsp->v[(reg)].b[BYTE4_XOR_BE(offset)]
+#define VREG_S(reg, offset) rsp->v[(reg)].s[(offset)^1]
-#define W_VREG_B(reg, offset, val) (rsp->v[(reg)].b[15 - (offset)] = val)
-#define W_VREG_S(reg, offset, val) (rsp->v[(reg)].s[7 - (offset)] = val)
-#define W_VREG_S_X(reg, offset, val) (rsp->v[reg].s[offset] = val)
-#define W_VREG_L(reg, offset, val) (rsp->v[(reg)].l[3 - (offset)] = val)
-#define W_VREG_D(reg, offset, val) (rsp->v[(reg)].d[1 - (offset)] = val)
-
-#define VEC_EL_1(x,z) (vector_elements_1[(x)][(z)])
#define VEC_EL_2(x,z) (vector_elements_2[(x)][(z)])
-#define ACCUM(x) (rsp->accum[x])
-
-#define W_ACCUM_H(x, y) (ACCUM(x).h.high = (INT16)((INT64)(y)))
-#define W_ACCUM_M(x, y) (ACCUM(x).h.mid = (INT16)((INT64)(y)))
-#define W_ACCUM_L(x, y) (ACCUM(x).h.low = (INT16)((INT64)(y)))
+#define ACCUM(x) rsp->accum[x].q
+#define ACCUM_H(x) rsp->accum[((x))].w[3]
+#define ACCUM_M(x) rsp->accum[((x))].w[2]
+#define ACCUM_L(x) rsp->accum[((x))].w[1]
#define CARRY_FLAG(x) ((rsp->flag[0] & (1 << (x))) ? 1 : 0)
#define CLEAR_CARRY_FLAGS() { rsp->flag[0] &= ~0xff; }
@@ -421,7 +309,9 @@ INLINE void save_fast_iregs(rsp_state *rsp, drcuml_block *block)
INLINE UINT8 READ8(rsp_state *rsp, UINT32 address)
{
UINT8* dmem = (UINT8*)rsp->impstate->dmem;
- return dmem[BYTE4_XOR_BE(address & 0x00000fff)];
+ UINT8 ret = dmem[BYTE4_XOR_BE(address & 0x00000fff)];
+ //printf("%04xr%02x\n", address & 0x00001fff, ret);
+ return ret;
}
/* Legacy. Needed for vector cfuncs. */
@@ -432,6 +322,7 @@ INLINE UINT16 READ16(rsp_state *rsp, UINT32 address)
address &= 0x00000fff;
ret = (UINT16)dmem[BYTE4_XOR_BE(address+0)] << 8;
ret |= (UINT16)dmem[BYTE4_XOR_BE(address+1)];
+ //printf("%04xr%04x\n", address & 0x00001fff, ret);
return ret;
}
@@ -445,23 +336,7 @@ INLINE UINT32 READ32(rsp_state *rsp, UINT32 address)
ret |= (UINT32)dmem[BYTE4_XOR_BE(address+1)] << 16;
ret |= (UINT32)dmem[BYTE4_XOR_BE(address+2)] << 8;
ret |= (UINT32)dmem[BYTE4_XOR_BE(address+3)];
- return ret;
-}
-
-/* Legacy. Needed for vector cfuncs. */
-INLINE UINT64 READ64(rsp_state *rsp, UINT32 address)
-{
- UINT8* dmem = (UINT8*)rsp->impstate->dmem;
- UINT64 ret = 0;
- address &= 0x00000fff;
- ret = (UINT64)dmem[BYTE4_XOR_BE(address+0)] << 56;
- ret |= (UINT64)dmem[BYTE4_XOR_BE(address+1)] << 48;
- ret |= (UINT64)dmem[BYTE4_XOR_BE(address+2)] << 40;
- ret |= (UINT64)dmem[BYTE4_XOR_BE(address+3)] << 32;
- ret |= (UINT64)dmem[BYTE4_XOR_BE(address+4)] << 24;
- ret |= (UINT64)dmem[BYTE4_XOR_BE(address+5)] << 16;
- ret |= (UINT64)dmem[BYTE4_XOR_BE(address+6)] << 8;
- ret |= (UINT64)dmem[BYTE4_XOR_BE(address+7)];
+ //printf("%04xr%08x\n", address & 0x00001fff, ret);
return ret;
}
@@ -470,6 +345,7 @@ INLINE void WRITE8(rsp_state *rsp, UINT32 address, UINT8 data)
{
UINT8* dmem = (UINT8*)rsp->impstate->dmem;
address &= 0x00000fff;
+ //printf("%04x:%02x\n", address & 0x00001fff, data);
dmem[BYTE4_XOR_BE(address)] = data;
}
@@ -478,6 +354,7 @@ INLINE void WRITE16(rsp_state *rsp, UINT32 address, UINT16 data)
{
UINT8* dmem = (UINT8*)rsp->impstate->dmem;
address &= 0x00000fff;
+ //printf("%04x:%04x\n", address & 0x00001fff, data);
dmem[BYTE4_XOR_BE(address+0)] = (UINT8)(data >> 8);
dmem[BYTE4_XOR_BE(address+1)] = (UINT8)(data >> 0);
}
@@ -487,27 +364,13 @@ INLINE void WRITE32(rsp_state *rsp, UINT32 address, UINT32 data)
{
UINT8* dmem = (UINT8*)rsp->impstate->dmem;
address &= 0x00000fff;
+ //printf("%04x:%08x\n", address & 0x00001fff, data);
dmem[BYTE4_XOR_BE(address+0)] = (UINT8)(data >> 24);
dmem[BYTE4_XOR_BE(address+1)] = (UINT8)(data >> 16);
dmem[BYTE4_XOR_BE(address+2)] = (UINT8)(data >> 8);
dmem[BYTE4_XOR_BE(address+3)] = (UINT8)(data >> 0);
}
-/* Legacy. Needed for vector cfuncs. */
-INLINE void WRITE64(rsp_state *rsp, UINT32 address, UINT64 data)
-{
- UINT8* dmem = (UINT8*)rsp->impstate->dmem;
- address &= 0x00000fff;
- dmem[BYTE4_XOR_BE(address+0)] = (UINT8)(data >> 56);
- dmem[BYTE4_XOR_BE(address+1)] = (UINT8)(data >> 48);
- dmem[BYTE4_XOR_BE(address+2)] = (UINT8)(data >> 40);
- dmem[BYTE4_XOR_BE(address+3)] = (UINT8)(data >> 32);
- dmem[BYTE4_XOR_BE(address+4)] = (UINT8)(data >> 24);
- dmem[BYTE4_XOR_BE(address+5)] = (UINT8)(data >> 16);
- dmem[BYTE4_XOR_BE(address+6)] = (UINT8)(data >> 8);
- dmem[BYTE4_XOR_BE(address+7)] = (UINT8)(data >> 0);
-}
-
/*****************************************************************************/
/*-------------------------------------------------
@@ -552,23 +415,30 @@ void rspdrc_add_dmem(running_device *device, void *base)
static void cfunc_printf_debug(void *param)
{
rsp_state *rsp = (rsp_state *)param;
- printf(rsp->impstate->format, rsp->impstate->arg0, rsp->impstate->arg1);
- logerror(rsp->impstate->format, rsp->impstate->arg0, rsp->impstate->arg1);
-}
-#endif
-
-
-/*-------------------------------------------------
- cfunc_printf_debug64 - generic printf for
- debugging 64-bit values
--------------------------------------------------*/
-
-#ifdef UNUSED_FUNCTION
-static void cfunc_printf_debug64(void *param)
-{
- rsp_state *rsp = (rsp_state *)param;
- printf(rsp->impstate->format, (UINT32)(rsp->impstate->arg64 >> 32), (UINT32)(rsp->impstate->arg64 & 0x00000000ffffffff));
- logerror(rsp->impstate->format, (UINT32)(rsp->impstate->arg64 >> 32), (UINT32)(rsp->impstate->arg64 & 0x00000000ffffffff));
+ switch(rsp->impstate->arg2)
+ {
+ case 0: // WRITE8
+ printf("%04x:%02x\n", rsp->impstate->arg0 & 0x0fff, (UINT8)rsp->impstate->arg1);
+ break;
+ case 1: // WRITE16
+ printf("%04x:%04x\n", rsp->impstate->arg0 & 0x0fff, (UINT16)rsp->impstate->arg1);
+ break;
+ case 2: // WRITE32
+ printf("%04x:%08x\n", rsp->impstate->arg0 & 0x0fff, rsp->impstate->arg1);
+ break;
+ case 3: // READ8
+ printf("%04xr%02x\n", rsp->impstate->arg0 & 0x0fff, (UINT8)rsp->impstate->arg1);
+ break;
+ case 4: // READ16
+ printf("%04xr%04x\n", rsp->impstate->arg0 & 0x0fff, (UINT16)rsp->impstate->arg1);
+ break;
+ case 5: // READ32
+ printf("%04xr%08x\n", rsp->impstate->arg0 & 0x0fff, rsp->impstate->arg1);
+ break;
+ default: // ???
+ printf("%08x %08x\n", rsp->impstate->arg0 & 0x0fff, rsp->impstate->arg1);
+ break;
+ }
}
#endif
@@ -722,7 +592,7 @@ static void rspcom_init(rsp_state *rsp, legacy_cpu_device *device, device_irq_ca
// ...except for the accumulators.
for(accumIdx = 0; accumIdx < 8; accumIdx++ )
{
- rsp->accum[accumIdx].l = 0;
+ rsp->accum[accumIdx].q = 0;
}
rsp->sr = RSP_STATUS_HALT;
@@ -742,7 +612,7 @@ static CPU_INIT( rsp )
drccache *cache;
UINT32 flags = 0;
int regnum;
- int elnum;
+ //int elnum;
/* allocate enough space for the cache and the core */
cache = (drccache *)drccache_alloc(CACHE_SIZE + sizeof(*rsp));
@@ -792,7 +662,8 @@ static CPU_INIT( rsp )
}
drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg0, sizeof(rsp->impstate->arg0), "arg0");
drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg1, sizeof(rsp->impstate->arg1), "arg1");
- drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg64, sizeof(rsp->impstate->arg1), "arg64");
+ drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg2, sizeof(rsp->impstate->arg2), "arg2");
+ drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg3, sizeof(rsp->impstate->arg3), "arg3");
drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->numcycles, sizeof(rsp->impstate->numcycles), "numcycles");
/* initialize the front-end helper */
@@ -808,48 +679,6 @@ static CPU_INIT( rsp )
rsp->impstate->regmap[regnum].type = (regnum == 0) ? DRCUML_PTYPE_IMMEDIATE : DRCUML_PTYPE_MEMORY;
rsp->impstate->regmap[regnum].value = (regnum == 0) ? 0 : (FPTR)&rsp->r[regnum];
}
- for (regnum = 0; regnum < 32; regnum++)
- {
- for(elnum = 0; elnum < 16; elnum++)
- {
- rsp->impstate->regmap[16*regnum+elnum+34].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[16*regnum+elnum+34].value = (FPTR)&rsp->v[regnum].b[15-elnum];
- }
- for(elnum = 0; elnum < 8; elnum++)
- {
- rsp->impstate->regmap[8*regnum+elnum+546].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[8*regnum+elnum+546].value = (FPTR)&rsp->v[regnum].s[7-elnum];
- }
- for(elnum = 0; elnum < 4; elnum++)
- {
- rsp->impstate->regmap[4*regnum+elnum+802].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[4*regnum+elnum+802].value = (FPTR)&rsp->v[regnum].l[3-elnum];
- }
- }
- for (regnum = 0; regnum < 4; regnum++)
- {
- rsp->impstate->regmap[930+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[930+regnum].value = (FPTR)&rsp->flag[regnum];
- }
- for (regnum = 0; regnum < 8; regnum++)
- {
- rsp->impstate->regmap[934+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[934+regnum].value = (FPTR)&rsp->accum[regnum].l;
- rsp->impstate->regmap[942+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[942+regnum].value = (FPTR)&rsp->accum[regnum].h.high;
- rsp->impstate->regmap[950+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[950+regnum].value = (FPTR)&rsp->accum[regnum].h.mid;
- rsp->impstate->regmap[958+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[958+regnum].value = (FPTR)&rsp->accum[regnum].h.low;
- rsp->impstate->regmap[966+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[966+regnum].value = (FPTR)&rsp->accum[regnum].h.z;
- rsp->impstate->regmap[974+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[974+regnum].value = (FPTR)&rsp->accum[regnum].w.mh;
- rsp->impstate->regmap[982+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[982+regnum].value = (FPTR)&rsp->accum[regnum].w.zl;
- rsp->impstate->regmap[990+regnum].type = DRCUML_PTYPE_MEMORY;
- rsp->impstate->regmap[990+regnum].value = (FPTR)&rsp->impstate->vres[regnum];
- }
/* mark the cache dirty so it is updated on next execute */
rsp->impstate->cache_dirty = TRUE;
@@ -872,6 +701,18 @@ static CPU_RESET( rsp )
rsp->nextpc = ~0;
}
+INLINE UINT32 IREAD32(rsp_state *rsp, UINT32 address)
+{
+ UINT8* imem = (UINT8*)rsp->impstate->imem;
+ UINT32 ret = 0;
+ address &= 0x00000fff;
+ ret = (UINT32)imem[address+0] << 24;
+ ret |= (UINT32)imem[address+1] << 16;
+ ret |= (UINT32)imem[address+2] << 8;
+ ret |= (UINT32)imem[address+3];
+ //printf("%04xr%08x\n", address & 0x00001fff, ret);
+ return ret;
+}
static void cfunc_rsp_lbv(void *param)
{
@@ -894,10 +735,9 @@ static void cfunc_rsp_lbv(void *param)
// Load 1 byte to vector byte index
ea = (base) ? rsp->r[base] + offset : offset;
- W_VREG_B(dest, index, READ8(rsp, ea));
+ VREG_B(dest, index) = READ8(rsp, ea);
}
-#if !(DRC_LSV)
static void cfunc_rsp_lsv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -920,11 +760,15 @@ static void cfunc_rsp_lsv(void *param)
ea = (base) ? rsp->r[base] + (offset * 2) : (offset * 2);
- W_VREG_S(dest, index >> 1, READ16(rsp, ea));
+ int end = index + 2;
+
+ for (int i = index; i < end; i++)
+ {
+ VREG_B(dest, i) = READ8(rsp, ea);
+ ea++;
+ }
}
-#endif
-#if !(DRC_LLV)
static void cfunc_rsp_llv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -947,11 +791,15 @@ static void cfunc_rsp_llv(void *param)
ea = (base) ? rsp->r[base] + (offset * 4) : (offset * 4);
- W_VREG_L(dest, index >> 2, READ32(rsp, ea));
+ int end = index + 4;
+
+ for (int i = index; i < end; i++)
+ {
+ VREG_B(dest, i) = READ8(rsp, ea);
+ ea++;
+ }
}
-#endif
-#if !(DRC_LDV)
static void cfunc_rsp_ldv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -974,13 +822,15 @@ static void cfunc_rsp_ldv(void *param)
ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
- index >>= 2;
- W_VREG_L(dest, index, READ32(rsp, ea));
- W_VREG_L(dest, index + 1, READ32(rsp, ea + 4));
+ int end = index + 8;
+
+ for (int i = index; i < end; i++)
+ {
+ VREG_B(dest, i) = READ8(rsp, ea);
+ ea++;
+ }
}
-#endif
-#if !(DRC_LQV)
static void cfunc_rsp_lqv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -1007,14 +857,12 @@ static void cfunc_rsp_lqv(void *param)
end = index + (16 - (ea & 0xf));
if (end > 16) end = 16;
-
for (i=index; i < end; i++)
{
- W_VREG_B(dest, i, READ8(rsp, ea));
+ VREG_B(dest, i) = READ8(rsp, ea);
ea++;
}
}
-#endif
static void cfunc_rsp_lrv(void *param)
{
@@ -1046,12 +894,11 @@ static void cfunc_rsp_lrv(void *param)
for (i=index; i < end; i++)
{
- W_VREG_B(dest, i, READ8(rsp, ea));
+ VREG_B(dest, i) = READ8(rsp, ea);
ea++;
}
}
-#if !(DRC_LPV)
static void cfunc_rsp_lpv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -1077,12 +924,10 @@ static void cfunc_rsp_lpv(void *param)
for (i=0; i < 8; i++)
{
- W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 8);
+ VREG_S(dest, i) = READ8(rsp, ea + (((16-index) + i) & 0xf)) << 8;
}
}
-#endif
-#if !(DRC_LUV)
static void cfunc_rsp_luv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -1108,10 +953,9 @@ static void cfunc_rsp_luv(void *param)
for (i=0; i < 8; i++)
{
- W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 7);
+ VREG_S(dest, i) = READ8(rsp, ea + (((16-index) + i) & 0xf)) << 7;
}
}
-#endif
static void cfunc_rsp_lhv(void *param)
{
@@ -1138,7 +982,7 @@ static void cfunc_rsp_lhv(void *param)
for (i=0; i < 8; i++)
{
- W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + (i<<1)) & 0xf)) << 7);
+ VREG_S(dest, i) = READ8(rsp, ea + (((16-index) + (i<<1)) & 0xf)) << 7;
}
}
@@ -1164,20 +1008,16 @@ static void cfunc_rsp_lfv(void *param)
//
// Loads a byte as the bits 14-7 of upper or lower quad, with 4-byte stride
- fatalerror("RSP: LFV\n");
-
- if (index & 0x7) fatalerror("RSP: LFV: index = %d at %08X\n", index, rsp->ppc);
ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
// not sure what happens if 16-byte boundary is crossed...
- if ((ea & 0xf) > 0) fatalerror("RSP: LFV: 16-byte boundary crossing at %08X, recheck this!\n", rsp->ppc);
end = (index >> 1) + 4;
for (i=index >> 1; i < end; i++)
{
- W_VREG_S(dest, i, READ8(rsp, ea) << 7);
+ VREG_S(dest, i) = READ8(rsp, ea) << 7;
ea += 4;
}
}
@@ -1207,14 +1047,11 @@ static void cfunc_rsp_lwv(void *param)
ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
- // not sure what happens if 16-byte boundary is crossed...
- if ((ea & 0xf) > 0) fatalerror("RSP: LWV: 16-byte boundary crossing at %08X, recheck this!\n", rsp->ppc);
-
end = (16 - index) + 16;
for (i=(16 - index); i < end; i++)
{
- W_VREG_B(dest, i & 0xf, READ8(rsp, ea));
+ VREG_B(dest, i & 0xf) = READ8(rsp, ea);
ea += 4;
}
}
@@ -1243,25 +1080,20 @@ static void cfunc_rsp_ltv(void *param)
int vs = dest;
int ve = dest + 8;
if (ve > 32)
- ve = 32;
-
- if (offset & 0x40)
{
- offset |= 0xffffffc0;
+ ve = 32;
}
element = 7 - (index >> 1);
- if (index & 1) fatalerror("RSP: LTV: index = %d\n", index);
-
ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
ea = ((ea + 8) & ~0xf) + (index & 1);
- for (i=vs; i < ve; i++)
+ for (i = vs; i < ve; i++)
{
- element = ((8 - (index >> 1) + (i-vs)) << 1);
- W_VREG_B(i, (element & 0xf), READ8(rsp, ea));
- W_VREG_B(i, ((element+1) & 0xf), READ8(rsp, ea+1));
+ element = ((8 - (index >> 1) + (i - vs)) << 1);
+ VREG_B(i, (element & 0xf)) = READ8(rsp, ea);
+ VREG_B(i, ((element + 1) & 0xf)) = READ8(rsp, ea + 1);
ea += 2;
}
@@ -1289,256 +1121,33 @@ static int generate_lwc2(rsp_state *rsp, drcuml_block *block, compiler_state *co
UML_CALLC(block, cfunc_rsp_lbv, rsp);
return TRUE;
case 0x01: /* LSV */
-#if (DRC_LSV)
- offset <<= 1;
- index >>= 1;
-
- index = 7 - index;
- UML_ADD(block, IREG(0), R32(RSREG), IMM(offset)); // add i0,<rsreg>,offset
- UML_CALLH(block, rsp->impstate->read16); // callh read32
- UML_STORE(block, &rsp->v[dest].s[index], IMM(0), IREG(0), WORD); // store v[dest][index],i0,word
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_lsv, rsp);
return TRUE;
-#endif
case 0x02: /* LLV */
-#if (DRC_LLV)
- offset <<= 2;
- index >>= 2;
-
- UML_ADD(block, IREG(0), R32(RSREG), IMM(offset)); // add i0,<rsreg>,offset
- UML_CALLH(block, rsp->impstate->read32); // callh read32
- UML_MOV(block, VLX(dest, index), IREG(0)); // mov v[dest][index].i0
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_llv, rsp);
return TRUE;
-#endif
case 0x03: /* LDV */
-#if (DRC_LDV)
- offset <<= 3;
- index >>= 2;
-
- UML_ADD(block, IREG(0), R32(RSREG), IMM(offset)); // add i0,<rsreg>,offset
- UML_CALLH(block, rsp->impstate->read32); // callh read32
- UML_MOV(block, VLX(dest, index), IREG(0)); // mov v[dest][index],i0
-
- UML_ADD(block, IREG(0), R32(RSREG), IMM(offset)); // add i0,<rsreg>,offset
- UML_ADD(block, IREG(0), IREG(0), IMM(4)); // add i0,i0,4
- UML_CALLH(block, rsp->impstate->read32); // callh read32
- UML_MOV(block, VLX(dest, index+1), IREG(0)); // mov v[dest][index+1],i0
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_ldv, rsp);
return TRUE;
-#endif
case 0x04: /* LQV */
-#if (DRC_LQV)
- offset <<= 4;
-
- UML_ADD(block, MEM(&rsp->impstate->arg0), R32(RSREG), IMM(offset)); // mov arg0,<rsreg>,offset
- UML_MOV(block, IREG(3), IMM(index)); // mov i3,index
- UML_MOV(block, IREG(2), MEM(&rsp->impstate->arg0)); // mov i2,arg0
- UML_AND(block, IREG(2), IREG(2), IMM(0x0000000f)); // and i2,i2,0x0000000f
- UML_SUB(block, IREG(2), IMM(16), IREG(2)); // sub i2,16,i2
- UML_ADD(block, IREG(2), IREG(2), IREG(3)); // add i2,i2,i3
- UML_CMP(block, IREG(2), IMM(16)); // cmp i2,16
- UML_TEST(block, IREG(2), IMM(0xfffffff0)); // test i2,0xfffffff0
- UML_MOVc(block, IF_NZ, IREG(2), IMM(16)); // mov NZ,i2,16
-
- UML_LABEL(block, loopdest = compiler->labelnum++); // loopdest:
- UML_MOV(block, IREG(0), MEM(&rsp->impstate->arg0)); // mov i0,arg0
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SUB(block, IREG(1), IMM(15), IREG(3)); // sub i1,15,i3
- UML_STORE(block, &rsp->v[dest].b[0], IREG(1), IREG(0), BYTE); // store v[dest][0]+i1,i0
-
- UML_ADD(block, MEM(&rsp->impstate->arg0), MEM(&rsp->impstate->arg0), IMM(1));
- UML_AND(block, MEM(&rsp->impstate->arg0), MEM(&rsp->impstate->arg0), IMM(0x00000fff));
- UML_ADD(block, IREG(3), IREG(3), IMM(1)); // add i3,i3,1
- UML_CMP(block, IREG(3), IREG(2)); // cmp i3,i2
- UML_JMPc(block, IF_L, loopdest); // jmp L,loopdest
- return TRUE;
-
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_lqv, rsp);
return TRUE;
-#endif
case 0x05: /* LRV */
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_lrv, rsp);
return TRUE;
case 0x06: /* LPV */
-#if (DRC_LPV)
- offset <<= 3;
-
- UML_ADD(block, IREG(2), R32(RSREG), IMM(offset)); // add i2,<rsreg>,offset
- UML_SUB(block, IREG(3), IMM(16), IMM(index)); // sub i3,16,index
-
- UML_AND(block, IREG(1), IREG(3), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0x00000fff
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(8)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[7], IMM(0), IREG(0), WORD); // store v[dest][7],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(1)); // add i1,i3,1
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0x00000fff
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(8)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[6], IMM(0), IREG(0), WORD); // store v[dest][6],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(2)); // add i1,i3,2
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0x00000fff
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(8)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[5], IMM(0), IREG(0), WORD); // store v[dest][5],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(3)); // add i1,i3,3
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0x00000fff
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(8)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[4], IMM(0), IREG(0), WORD); // store v[dest][4],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(4)); // add i1,i3,4
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0x00000fff
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(8)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[3], IMM(0), IREG(0), WORD); // store v[dest][3],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(5)); // add i1,i3,5
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0x00000fff
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(8)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[2], IMM(0), IREG(0), WORD); // store v[dest][2],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(6)); // add i1,i3,6
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0x00000fff
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(8)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[1], IMM(0), IREG(0), WORD); // store v[dest][1],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(7)); // add i1,i3,7
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0x00000fff
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(8)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[0], IMM(0), IREG(0), WORD); // store v[dest][0],i0,word
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_lpv, rsp);
return TRUE;
-#endif
case 0x07: /* LUV */
-#if (DRC_LUV)
-#ifdef UNUSED_CODE
- ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
-
- for (i=0; i < 8; i++)
- {
- W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 7);
- }
-#endif
- offset <<= 3;
-
- UML_ADD(block, IREG(2), R32(RSREG), IMM(offset)); // add i2,<rsreg>,offset
- UML_SUB(block, IREG(3), IMM(16), IMM(index)); // sub i3,16,index
-
- UML_AND(block, IREG(1), IREG(3), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(7)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[7], IMM(0), IREG(0), WORD); // store v[dest][7],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(1)); // add i1,i3,1
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(7)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[6], IMM(0), IREG(0), WORD); // store v[dest][6],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(2)); // add i1,i3,2
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(7)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[5], IMM(0), IREG(0), WORD); // store v[dest][5],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(3)); // add i1,i3,3
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(7)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[4], IMM(0), IREG(0), WORD); // store v[dest][4],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(4)); // add i1,i3,4
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(7)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[3], IMM(0), IREG(0), WORD); // store v[dest][3],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(5)); // add i1,i3,5
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(7)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[2], IMM(0), IREG(0), WORD); // store v[dest][2],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(6)); // add i1,i3,6
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(7)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[1], IMM(0), IREG(0), WORD); // store v[dest][1],i0,word
-
- UML_ADD(block, IREG(1), IREG(3), IMM(7)); // add i1,i3,7
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f)); // and i1,i1,0x0000000f
- UML_ADD(block, IREG(0), IREG(1), IREG(2)); // add i0,i1,i2
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,bytexor
- UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
- UML_SHL(block, IREG(0), IREG(0), IMM(7)); // shl i0,i0,8
- UML_STORE(block, &rsp->v[dest].s[0], IMM(0), IREG(0), WORD); // store v[dest][0],i0,word
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_luv, rsp);
return TRUE;
-#endif
case 0x08: /* LHV */
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_lhv, rsp);
@@ -1574,18 +1183,18 @@ static void cfunc_rsp_sbv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 00000 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores 1 byte from vector byte index
- ea = (base) ? rsp->r[base] + offset : offset;
- WRITE8(rsp, ea, R_VREG_B(dest, index));
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 00000 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores 1 byte from vector byte index
+
+ ea = (base) ? rsp->r[base] + offset : offset;
+ WRITE8(rsp, ea, VREG_B(dest, index));
}
-#if !(DRC_SSV)
static void cfunc_rsp_ssv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -1599,20 +1208,25 @@ static void cfunc_rsp_ssv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 00001 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores 2 bytes starting from vector byte index
- ea = (base) ? rsp->r[base] + (offset * 2) : (offset * 2);
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 00001 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores 2 bytes starting from vector byte index
- WRITE16(rsp, ea, R_VREG_S(dest, index >> 1));
+ ea = (base) ? rsp->r[base] + (offset * 2) : (offset * 2);
+
+ int end = index + 2;
+
+ for (int i = index; i < end; i++)
+ {
+ WRITE8(rsp, ea, VREG_B(dest, i));
+ ea++;
+ }
}
-#endif
-#if !(DRC_SLV)
static void cfunc_rsp_slv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -1626,20 +1240,24 @@ static void cfunc_rsp_slv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 00010 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores 4 bytes starting from vector byte index
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 00010 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores 4 bytes starting from vector byte index
- ea = (base) ? rsp->r[base] + (offset * 4) : (offset * 4);
+ ea = (base) ? rsp->r[base] + (offset * 4) : (offset * 4);
+
+ int end = index + 4;
- WRITE32(rsp, ea, R_VREG_L(dest, index >> 2));
+ for (int i = index; i < end; i++)
+ {
+ WRITE8(rsp, ea, VREG_B(dest, i));
+ ea++;
+ }
}
-#endif
-#if !(DRC_SDV)
static void cfunc_rsp_sdv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -1654,23 +1272,23 @@ static void cfunc_rsp_sdv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 00011 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores 8 bytes starting from vector byte index
- ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 00011 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores 8 bytes starting from vector byte index
+ ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
- end = index + 8;
+ end = index + 8;
- index >>= 2;
- WRITE32(rsp, ea, R_VREG_L(dest, index));
- WRITE32(rsp, ea + 4, R_VREG_L(dest, index + 1));
+ for (int i = index; i < end; i++)
+ {
+ WRITE8(rsp, ea, VREG_B(dest, i));
+ ea++;
+ }
}
-#endif
-#if !(DRC_SQV)
static void cfunc_rsp_sqv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -1686,33 +1304,28 @@ static void cfunc_rsp_sqv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 00100 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores up to 16 bytes starting from vector byte index until 16-byte boundary
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 00100 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores up to 16 bytes starting from vector byte index until 16-byte boundary
- ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
+ ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
- end = index + (16 - (ea & 0xf));
+ end = index + (16 - (ea & 0xf));
- for (i=index; i < end; i++)
- {
- WRITE8(rsp, ea, R_VREG_B(dest, i & 0xf));
- ea++;
- }
+ for (i=index; i < end; i++)
+ {
+ WRITE8(rsp, ea, VREG_B(dest, i & 0xf));
+ ea++;
+ }
}
-#endif
static void cfunc_rsp_srv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
UINT32 op = rsp->impstate->arg0;
- UINT32 ea = 0;
- int o;
- int i = 0;
- int end = 0;
int dest = (op >> 16) & 0x1f;
int base = (op >> 21) & 0x1f;
int index = (op >> 7) & 0xf;
@@ -1721,27 +1334,26 @@ static void cfunc_rsp_srv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 00101 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores up to 16 bytes starting from right side until 16-byte boundary
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 00101 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores up to 16 bytes starting from right side until 16-byte boundary
- ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
+ UINT32 ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
- end = index + (ea & 0xf);
- o = (16 - (ea & 0xf)) & 0xf;
- ea &= ~0xf;
+ int end = index + (ea & 0xf);
+ int o = (16 - (ea & 0xf)) & 0xf;
+ ea &= ~0xf;
- for (i=index; i < end; i++)
- {
- WRITE8(rsp, ea, R_VREG_B(dest, ((i + o) & 0xf)));
- ea++;
- }
+ for (int i = index; i < end; i++)
+ {
+ WRITE8(rsp, ea, VREG_B(dest, ((i + o) & 0xf)));
+ ea++;
+ }
}
-#if !(DRC_SPV)
static void cfunc_rsp_spv(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -1757,30 +1369,29 @@ static void cfunc_rsp_spv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 00110 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores upper 8 bits of each element
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 00110 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores upper 8 bits of each element
- ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
- end = index + 8;
+ ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
+ end = index + 8;
- for (i=index; i < end; i++)
- {
- if ((i & 0xf) < 8)
- {
- WRITE8(rsp, ea, R_VREG_B(dest, ((i & 0xf) << 1)));
- }
- else
- {
- WRITE8(rsp, ea, R_VREG_S(dest, (i & 0x7)) >> 7);
- }
- ea++;
- }
+ for (i=index; i < end; i++)
+ {
+ if ((i & 0xf) < 8)
+ {
+ WRITE8(rsp, ea, VREG_B(dest, ((i & 0xf) << 1)));
+ }
+ else
+ {
+ WRITE8(rsp, ea, VREG_S(dest, (i & 0x7)) >> 7);
+ }
+ ea++;
+ }
}
-#endif
static void cfunc_rsp_suv(void *param)
{
@@ -1797,28 +1408,28 @@ static void cfunc_rsp_suv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 00111 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores bits 14-7 of each element
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 00111 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores bits 14-7 of each element
- ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
- end = index + 8;
+ ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
+ end = index + 8;
- for (i=index; i < end; i++)
- {
- if ((i & 0xf) < 8)
- {
- WRITE8(rsp, ea, R_VREG_S(dest, (i & 0x7)) >> 7);
- }
- else
- {
- WRITE8(rsp, ea, R_VREG_B(dest, ((i & 0x7) << 1)));
- }
- ea++;
- }
+ for (i=index; i < end; i++)
+ {
+ if ((i & 0xf) < 8)
+ {
+ WRITE8(rsp, ea, VREG_S(dest, (i & 0x7)) >> 7);
+ }
+ else
+ {
+ WRITE8(rsp, ea, VREG_B(dest, ((i & 0x7) << 1)));
+ }
+ ea++;
+ }
}
static void cfunc_rsp_shv(void *param)
@@ -1835,23 +1446,23 @@ static void cfunc_rsp_shv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 01000 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores bits 14-7 of each element, with 2-byte stride
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 01000 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores bits 14-7 of each element, with 2-byte stride
- ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
+ ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
- for (i=0; i < 8; i++)
- {
- UINT8 d = ((R_VREG_B(dest, ((index + (i << 1) + 0) & 0xf))) << 1) |
- ((R_VREG_B(dest, ((index + (i << 1) + 1) & 0xf))) >> 7);
+ for (i=0; i < 8; i++)
+ {
+ UINT8 d = ((VREG_B(dest, ((index + (i << 1) + 0) & 0xf))) << 1) |
+ ((VREG_B(dest, ((index + (i << 1) + 1) & 0xf))) >> 7);
- WRITE8(rsp, ea, d);
- ea += 2;
- }
+ WRITE8(rsp, ea, d);
+ ea += 2;
+ }
}
static void cfunc_rsp_sfv(void *param)
@@ -1870,29 +1481,27 @@ static void cfunc_rsp_sfv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 01001 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores bits 14-7 of upper or lower quad, with 4-byte stride
-
- // FIXME: only works for index 0 and index 8
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 01001 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores bits 14-7 of upper or lower quad, with 4-byte stride
- if (index & 0x7) mame_printf_debug("RSP: SFV: index = %d at %08X\n", index, rsp->ppc);
+ if (index & 0x7) printf("RSP: SFV: index = %d at %08X\n", index, rsp->ppc);
- ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
+ ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
- eaoffset = ea & 0xf;
- ea &= ~0xf;
+ eaoffset = ea & 0xf;
+ ea &= ~0xf;
- end = (index >> 1) + 4;
+ end = (index >> 1) + 4;
- for (i=index >> 1; i < end; i++)
- {
- WRITE8(rsp, ea + (eaoffset & 0xf), R_VREG_S(dest, i) >> 7);
- eaoffset += 4;
- }
+ for (i=index >> 1; i < end; i++)
+ {
+ WRITE8(rsp, ea + (eaoffset & 0xf), VREG_S(dest, i) >> 7);
+ eaoffset += 4;
+ }
}
static void cfunc_rsp_swv(void *param)
@@ -1911,26 +1520,26 @@ static void cfunc_rsp_swv(void *param)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 01010 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores the full 128-bit vector starting from vector byte index and wrapping to index 0
- // after byte index 15
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 01010 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores the full 128-bit vector starting from vector byte index and wrapping to index 0
+ // after byte index 15
- ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
+ ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
- eaoffset = ea & 0xf;
- ea &= ~0xf;
+ eaoffset = ea & 0xf;
+ ea &= ~0xf;
- end = index + 16;
+ end = index + 16;
- for (i=index; i < end; i++)
- {
- WRITE8(rsp, ea + (eaoffset & 0xf), R_VREG_B(dest, i & 0xf));
- eaoffset++;
- }
+ for (i=index; i < end; i++)
+ {
+ WRITE8(rsp, ea + (eaoffset & 0xf), VREG_B(dest, i & 0xf));
+ eaoffset++;
+ }
}
static void cfunc_rsp_stv(void *param)
@@ -1943,40 +1552,38 @@ static void cfunc_rsp_stv(void *param)
int base = (op >> 21) & 0x1f;
int index = (op >> 7) & 0xf;
int offset = (op & 0x7f);
- int element;
- int eaoffset = 0;
- int vs = dest;
- int ve = dest + 8;
- if (ve > 32)
- ve = 32;
if (offset & 0x40)
{
offset |= 0xffffffc0;
}
- // 31 25 20 15 10 6 0
- // --------------------------------------------------
- // | 111010 | BBBBB | TTTTT | 01011 | IIII | Offset |
- // --------------------------------------------------
- //
- // Stores one element from maximum of 8 vectors, while incrementing element index
+ // 31 25 20 15 10 6 0
+ // --------------------------------------------------
+ // | 111010 | BBBBB | TTTTT | 01011 | IIII | Offset |
+ // --------------------------------------------------
+ //
+ // Stores one element from maximum of 8 vectors, while incrementing element index
- element = 8 - (index >> 1);
- if (index & 0x1) fatalerror("RSP: STV: index = %d at %08X\n", index, rsp->ppc);
+ int vs = dest;
+ int ve = dest + 8;
+ if (ve > 32)
+ {
+ ve = 32;
+ }
- ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
+ int element = 8 - (index >> 1);
- if (ea & 0x1) fatalerror("RSP: STV: ea = %08X at %08X\n", ea, rsp->ppc);
+ ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
- eaoffset = (ea & 0xf) + (element * 2);
- ea &= ~0xf;
+ int eaoffset = (ea & 0xf) + (element * 2);
+ ea &= ~0xf;
- for (i=vs; i < ve; i++)
- {
- WRITE16(rsp, ea + (eaoffset & 0xf), R_VREG_S(i, element & 0x7));
- eaoffset += 2;
- element++;
- }
+ for (i=vs; i < ve; i++)
+ {
+ WRITE16(rsp, ea + (eaoffset & 0xf), VREG_S(i, element & 0x7));
+ eaoffset += 2;
+ element++;
+ }
}
static int generate_swc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
@@ -2000,94 +1607,28 @@ static int generate_swc2(rsp_state *rsp, drcuml_block *block, compiler_state *co
UML_CALLC(block, cfunc_rsp_sbv, rsp);
return TRUE;
case 0x01: /* SSV */
-#if (DRC_SSV)
- offset <<= 1;
- index >>= 1;
-
- index = 7 - index;
- UML_ADD(block, IREG(0), R32(RSREG), IMM(offset)); // add i0,<rsreg>,offset
- UML_LOAD(block, IREG(1), &rsp->v[dest].s[index], IMM(0), WORD); // load i1,v[dest].b[0],0,byte
- UML_CALLH(block, rsp->impstate->write16); // callh read32
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_ssv, rsp);
return TRUE;
-#endif
case 0x02: /* SLV */
-#if (DRC_SLV)
- offset <<= 2;
- index >>= 2;
-
- UML_ADD(block, IREG(0), R32(RSREG), IMM(offset)); // add i0,<rsreg>,offset
- UML_MOV(block, IREG(1), VLX(dest, index)); // mov i1,v[dest].l[index]
- UML_CALLH(block, rsp->impstate->write32); // callh read32
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_slv, rsp);
return TRUE;
-#endif
case 0x03: /* SDV */
-#if (DRC_SDV)
- offset <<= 3;
- index >>= 2;
-
- UML_ADD(block, IREG(0), R32(RSREG), IMM(offset)); // add i0,<rsreg>,offset
- UML_MOV(block, IREG(1), VLX(dest, index)); // mov i1,v[dest].l[index]
- UML_CALLH(block, rsp->impstate->write32); // callh write32
-
- UML_ADD(block, IREG(0), R32(RSREG), IMM(offset)); // add i0,<rsreg>,offset
- UML_ADD(block, IREG(0), IREG(0), IMM(4)); // add i0,i0,4
- UML_MOV(block, IREG(1), VLX(dest, index+1)); // mov i1,v[dest].l[index+1]
- UML_CALLH(block, rsp->impstate->write32); // callh write32
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_sdv, rsp);
return TRUE;
-#endif
case 0x04: /* SQV */
-#if (DRC_SQV)
- offset <<= 4;
-
- UML_ADD(block, MEM(&rsp->impstate->arg0), R32(RSREG), IMM(offset)); // mov arg0,<rsreg>,offset
- UML_MOV(block, IREG(3), IMM(index)); // mov i3,index
- UML_MOV(block, IREG(2), MEM(&rsp->impstate->arg0)); // mov i2,arg0
- UML_AND(block, IREG(2), IREG(2), IMM(0x0000000f)); // and i2,i2,0x0000000f
- UML_SUB(block, IREG(2), IMM(16), IREG(2)); // sub i2,16,i2
- UML_ADD(block, IREG(2), IREG(2), IREG(3)); // add i2,i2,i3
- UML_CMP(block, IREG(2), IMM(16)); // cmp i2,16
- UML_TEST(block, IREG(2), IMM(0xfffffff0)); // test i2,0xfffffff0
- UML_MOVc(block, IF_NZ, IREG(2), IMM(16)); // mov NZ,i2,16
-
- UML_LABEL(block, loopdest = compiler->labelnum++); // loopdest:
- UML_MOV(block, IREG(0), MEM(&rsp->impstate->arg0)); // mov i0,arg0
- UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0))); // xor i0,i0,byte4xor
- UML_SUB(block, IREG(1), IMM(15), IREG(3)); // sub i1,15,i3
- UML_LOAD(block, IREG(1), &rsp->v[dest].b[0], IREG(1), BYTE); // load i1,v[dest].b[0],i1,byte
- UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE); // store dmem,i0,i1,byte
-
- UML_ADD(block, MEM(&rsp->impstate->arg0), MEM(&rsp->impstate->arg0), IMM(1));
- UML_ADD(block, IREG(3), IREG(3), IMM(1)); // add i3,i3,1
- UML_CMP(block, IREG(3), IREG(2)); // cmp i3,i2
- UML_JMPc(block, IF_L, loopdest); // jmp L,loopdest
- return TRUE;
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_sqv, rsp);
-#endif
return TRUE;
case 0x05: /* SRV */
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_srv, rsp);
return TRUE;
case 0x06: /* SPV */
-#if (DRC_SPV)
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_spv, rsp);
-#endif
return TRUE;
case 0x07: /* SUV */
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
@@ -2118,147 +1659,114 @@ static int generate_swc2(rsp_state *rsp, drcuml_block *block, compiler_state *co
return TRUE;
}
-#if (DRC_VMADN)
-static void generate_saturate_accum_unsigned(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int accum)
+INLINE UINT16 SATURATE_ACCUM(rsp_state *rsp, int accum, int slice, UINT16 negative, UINT16 positive)
{
-#ifdef UNUSED_CODE
- int skip, skip2;
-
- UML_CMP(block, VACCUMWMH(accum), IMM(-32768));
- UML_JMPc(block, IF_GE, skip = compiler->labelnum++);
- UML_MOV(block, IREG(0), IMM(0));
- UML_JMP(block, skip2 = compiler->labelnum++);
-
- UML_LABEL(block, skip);
- UML_CMP(block, VACCUMWMH(accum), IMM(32767));
- UML_JMPc(block, IF_L, skip = compiler->labelnum++);
- UML_MOV(block, IREG(0), IMM(0x0000ffff));
- UML_JMP(block, skip2);
-
- UML_LABEL(block, skip);
- UML_SEXT(block, IREG(0), VACCUMHL(accum), WORD);
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff));
- UML_LABEL(block, skip2);
-#endif
- UML_SEXT(block, IREG(0), VACCUMHL(accum), WORD);
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff));
- UML_CMP(block, VACCUMWMH(accum), IMM(-32768));
- UML_MOVc(block, IF_L, IREG(0), IMM(0));
- UML_CMP(block, VACCUMWMH(accum), IMM(32767));
- UML_MOVc(block, IF_GE, IREG(0), IMM(0x0000ffff));
-}
-#endif
-
-INLINE UINT16 SATURATE_ACCUM_UNSIGNED(rsp_state *rsp, int accum)
-{
- if (ACCUM(accum).w.mh < -32768)
- {
- return 0;
- }
- else if(ACCUM(accum).w.mh > 32767)
+ if ((INT16)ACCUM_H(accum) < 0)
{
- return 0xffff;
+ if ((UINT16)(ACCUM_H(accum)) != 0xffff)
+ {
+ return negative;
+ }
+ else
+ {
+ if ((INT16)ACCUM_M(accum) >= 0)
+ {
+ return negative;
+ }
+ else
+ {
+ if (slice == 0)
+ {
+ return ACCUM_L(accum);
+ }
+ else if (slice == 1)
+ {
+ return ACCUM_M(accum);
+ }
+ }
+ }
}
else
{
- return ACCUM(accum).h.low;
+ if ((UINT16)(ACCUM_H(accum)) != 0)
+ {
+ return positive;
+ }
+ else
+ {
+ if ((INT16)ACCUM_M(accum) < 0)
+ {
+ return positive;
+ }
+ else
+ {
+ if (slice == 0)
+ {
+ return ACCUM_L(accum);
+ }
+ else
+ {
+ return ACCUM_M(accum);
+ }
+ }
+ }
}
-}
-#if (DRC_VMADH) || (DRC_VMADM)
-static void generate_saturate_accum_signed(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int accum)
-{
- int skip, skip2;
-
- UML_CMP(block, VACCUMWMH(accum), IMM(-32768));
- UML_JMPc(block, IF_GE, skip = compiler->labelnum++);
- UML_MOV(block, IREG(0), IMM(0x00008000));
- UML_JMP(block, skip2 = compiler->labelnum++);
-
- UML_LABEL(block, skip);
- UML_CMP(block, VACCUMWMH(accum), IMM(32767));
- UML_JMPc(block, IF_L, skip = compiler->labelnum++);
- UML_MOV(block, IREG(0), IMM(0x00007fff));
- UML_JMP(block, skip2);
-
- UML_LABEL(block, skip);
- UML_SEXT(block, IREG(0), VACCUMHM(accum), WORD);
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff));
- UML_LABEL(block, skip2);
-}
-#endif
-
-INLINE UINT16 SATURATE_ACCUM_SIGNED(rsp_state *rsp, int accum)
-{
- if (ACCUM(accum).w.mh < -32768)
- {
- return 0x8000;
- }
- if(ACCUM(accum).w.mh > 32767)
- {
- return 0x7fff;
- }
- return ACCUM(accum).h.mid;
+ return 0;
}
-#define WRITEBACK_RESULT() \
- do { \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- } while(0)
-
-#if 0
-static float float_round(float input)
+INLINE UINT16 SATURATE_ACCUM1(rsp_state *rsp, int accum, UINT16 negative, UINT16 positive)
{
- INT32 integer = (INT32)input;
- float fraction = input - (float)integer;
- float output = 0.0f;
- if( fraction >= 0.5f )
+ if ((INT16)ACCUM_H(accum) < 0)
{
- output = (float)( integer + 1 );
+ if ((UINT16)(ACCUM_H(accum)) != 0xffff)
+ {
+ return negative;
+ }
+ else
+ {
+ if ((INT16)ACCUM_M(accum) >= 0)
+ {
+ return negative;
+ }
+ else
+ {
+ return ACCUM_M(accum);
+ }
+ }
}
else
{
- output = (float)integer;
+ if ((UINT16)(ACCUM_H(accum)) != 0)
+ {
+ return positive;
+ }
+ else
+ {
+ if ((INT16)ACCUM_M(accum) < 0)
+ {
+ return positive;
+ }
+ else
+ {
+ return ACCUM_M(accum);
+ }
+ }
}
- return output;
+
+ return 0;
}
-#endif
-#define RSP_VMULF(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- INT16 v1, v2; \
- v1 = R_VREG_S_X(VS1REG, I0); v2 = R_VREG_S_X(VS2REG, E20); \
- if (v1 == -32768 && v2 == -32768) { ACCUM(E10).l = 0x0000800080000000LL; vres[E10] = 0x7fff; } \
- else { ACCUM(E10).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E10] = ACCUM(E10).h.mid; } \
- v1 = R_VREG_S_X(VS1REG, I1); v2 = R_VREG_S_X(VS2REG, E21); \
- if (v1 == -32768 && v2 == -32768) { ACCUM(E11).l = 0x0000800080000000LL; vres[E11] = 0x7fff; } \
- else { ACCUM(E11).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E11] = ACCUM(E11).h.mid; } \
- v1 = R_VREG_S_X(VS1REG, I2); v2 = R_VREG_S_X(VS2REG, E22); \
- if (v1 == -32768 && v2 == -32768) { ACCUM(E12).l = 0x0000800080000000LL; vres[E12] = 0x7fff; } \
- else { ACCUM(E12).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E12] = ACCUM(E12).h.mid; } \
- v1 = R_VREG_S_X(VS1REG, I3); v2 = R_VREG_S_X(VS2REG, E23); \
- if (v1 == -32768 && v2 == -32768) { ACCUM(E13).l = 0x0000800080000000LL; vres[E13] = 0x7fff; } \
- else { ACCUM(E13).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E13] = ACCUM(E13).h.mid; } \
- v1 = R_VREG_S_X(VS1REG, I4); v2 = R_VREG_S_X(VS2REG, E24); \
- if (v1 == -32768 && v2 == -32768) { ACCUM(E14).l = 0x0000800080000000LL; vres[E14] = 0x7fff; } \
- else { ACCUM(E14).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E14] = ACCUM(E14).h.mid; } \
- v1 = R_VREG_S_X(VS1REG, I5); v2 = R_VREG_S_X(VS2REG, E25); \
- if (v1 == -32768 && v2 == -32768) { ACCUM(E15).l = 0x0000800080000000LL; vres[E15] = 0x7fff; } \
- else { ACCUM(E15).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E15] = ACCUM(E15).h.mid; } \
- v1 = R_VREG_S_X(VS1REG, I6); v2 = R_VREG_S_X(VS2REG, E26); \
- if (v1 == -32768 && v2 == -32768) { ACCUM(E16).l = 0x0000800080000000LL; vres[E16] = 0x7fff; } \
- else { ACCUM(E16).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E16] = ACCUM(E16).h.mid; } \
- v1 = R_VREG_S_X(VS1REG, I7); v2 = R_VREG_S_X(VS2REG, E27); \
- if (v1 == -32768 && v2 == -32768) { ACCUM(E17).l = 0x0000800080000000LL; vres[E17] = 0x7fff; } \
- else { ACCUM(E17).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E17] = ACCUM(E17).h.mid; } \
- }
+#define WRITEBACK_RESULT() { \
+ VREG_S(VDREG, 0) = vres[0]; \
+ VREG_S(VDREG, 1) = vres[1]; \
+ VREG_S(VDREG, 2) = vres[2]; \
+ VREG_S(VDREG, 3) = vres[3]; \
+ VREG_S(VDREG, 4) = vres[4]; \
+ VREG_S(VDREG, 5) = vres[5]; \
+ VREG_S(VDREG, 6) = vres[6]; \
+ VREG_S(VDREG, 7) = vres[7]; \
+}
INLINE void cfunc_rsp_vmulf(void *param)
{
@@ -2273,58 +1781,32 @@ INLINE void cfunc_rsp_vmulf(void *param)
//
// Multiplies signed integer by signed integer * 2
- switch(EL)
+ int sel;
+ INT32 s1, s2;
+ INT64 r;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMULF(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMULF(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMULF(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMULF(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMULF(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMULF(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMULF(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMULF(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMULF(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMULF(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMULF(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMULF(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMULF(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMULF(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMULF(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMULF(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ if (s1 == -32768 && s2 == -32768)
+ {
+ // overflow
+ ACCUM_H(i) = 0;
+ ACCUM_M(i) = -32768;
+ ACCUM_L(i) = -32768;
+ vres[i] = 0x7fff;
+ }
+ else
+ {
+ r = s1 * s2 * 2;
+ r += 0x8000; // rounding ?
+ ACCUM_H(i) = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
+ ACCUM_M(i) = (INT16)(r >> 16);
+ ACCUM_L(i) = (UINT16)(r);
+ vres[i] = ACCUM_M(i);
+ }
}
-
WRITEBACK_RESULT();
}
@@ -2340,218 +1822,37 @@ INLINE void cfunc_rsp_vmulu(void *param)
// ------------------------------------------------------
//
+ int sel;
+ INT32 s1, s2;
+ INT64 r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT64 r = s1 * s2;
- r += 0x4000; // rounding ?
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 * s2 * 2;
+ r += 0x8000; // rounding ?
- ACCUM(del).l = r << 17;
+ ACCUM_H(i) = (UINT16)(r >> 32);
+ ACCUM_M(i) = (UINT16)(r >> 16);
+ ACCUM_L(i) = (UINT16)(r);
if (r < 0)
{
- vres[del] = 0;
+ vres[i] = 0;
}
- else if ((ACCUM(del).h.high ^ ACCUM(del).h.mid) < 0)
+ else if (((INT16)(ACCUM_H(i)) ^ (INT16)(ACCUM_M(i))) < 0)
{
- vres[del] = -1;
-
+ vres[i] = -1;
}
else
{
- vres[del] = ACCUM(del).h.mid;
+ vres[i] = ACCUM_M(i);
}
}
WRITEBACK_RESULT();
}
-#if (DRC_VMUDL)
-/*------------------------------------------------------------------
- generate_vmudl
-------------------------------------------------------------------*/
-
-#define RSP_VMUDL_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(1), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E20), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
- UML_DMOV(block, VACCUML(E10), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E21), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
- UML_DMOV(block, VACCUML(E11), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E22), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
- UML_DMOV(block, VACCUML(E12), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E23), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
- UML_DMOV(block, VACCUML(E13), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E24), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
- UML_DMOV(block, VACCUML(E14), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E25), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
- UML_DMOV(block, VACCUML(E15), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E26), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
- UML_DMOV(block, VACCUML(E16), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E27), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
- UML_DMOV(block, VACCUML(E17), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VACCUMHL(E10), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHL(E11), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHL(E12), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHL(E13), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHL(E14), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHL(E15), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHL(E16), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHL(E17), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vmudl(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // vmudl
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
- // ------------------------------------------------------
- //
- // Multiplies signed integer by unsigned fraction
- // The result is added into accumulator
- // The middle slice of accumulator is stored into destination element
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMUDL_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMUDL_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMUDL_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMUDL_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMUDL_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMUDL_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMUDL_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMUDL_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMUDL_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMUDL_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMUDL_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMUDL_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMUDL_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMUDL_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMUDL_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMUDL_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- }
-
- return TRUE;
-}
-#else
-#define RSP_VMUDL(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- { \
- ACCUM(E10).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E10) * (UINT32)(UINT16)R_VREG_S(VS2REG, E20)) & 0xffff0000); \
- ACCUM(E11).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E11) * (UINT32)(UINT16)R_VREG_S(VS2REG, E21)) & 0xffff0000); \
- ACCUM(E12).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E12) * (UINT32)(UINT16)R_VREG_S(VS2REG, E22)) & 0xffff0000); \
- ACCUM(E13).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E13) * (UINT32)(UINT16)R_VREG_S(VS2REG, E23)) & 0xffff0000); \
- ACCUM(E14).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E14) * (UINT32)(UINT16)R_VREG_S(VS2REG, E24)) & 0xffff0000); \
- ACCUM(E15).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E15) * (UINT32)(UINT16)R_VREG_S(VS2REG, E25)) & 0xffff0000); \
- ACCUM(E16).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E16) * (UINT32)(UINT16)R_VREG_S(VS2REG, E26)) & 0xffff0000); \
- ACCUM(E17).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E17) * (UINT32)(UINT16)R_VREG_S(VS2REG, E27)) & 0xffff0000); \
- vres[E10] = ACCUM(E10).h.low; \
- vres[E11] = ACCUM(E11).h.low; \
- vres[E12] = ACCUM(E12).h.low; \
- vres[E13] = ACCUM(E13).h.low; \
- vres[E14] = ACCUM(E14).h.low; \
- vres[E15] = ACCUM(E15).h.low; \
- vres[E16] = ACCUM(E16).h.low; \
- vres[E17] = ACCUM(E17).h.low; \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- }
-
INLINE void cfunc_rsp_vmudl(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -2566,243 +1867,24 @@ INLINE void cfunc_rsp_vmudl(void *param)
// The result is added into accumulator
// The middle slice of accumulator is stored into destination element
- switch(EL)
+ int sel;
+ UINT32 s1, s2;
+ UINT32 r;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMUDL(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMUDL(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMUDL(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMUDL(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMUDL(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMUDL(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMUDL(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMUDL(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMUDL(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMUDL(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMUDL(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMUDL(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMUDL(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMUDL(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMUDL(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMUDL(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
- }
-}
-#endif
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
+ s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
+ r = s1 * s2;
-#if (DRC_VMUDM)
-/*------------------------------------------------------------------
- generate_vmudm
-------------------------------------------------------------------*/
+ ACCUM_H(i) = 0;
+ ACCUM_M(i) = 0;
+ ACCUM_L(i) = (UINT16)(r >> 16);
-#define RSP_VMUDM_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(1), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E20), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DMOV(block, VACCUML(E10), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E21), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DMOV(block, VACCUML(E11), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E22), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DMOV(block, VACCUML(E12), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E23), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DMOV(block, VACCUML(E13), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E24), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DMOV(block, VACCUML(E14), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E25), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DMOV(block, VACCUML(E15), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E26), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DMOV(block, VACCUML(E16), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E27), WORD); \
- UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DMOV(block, VACCUML(E17), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VACCUMHM(E10), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHM(E11), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHM(E12), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHM(E13), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHM(E14), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHM(E15), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHM(E16), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- UML_SEXT(block, IREG(0), VACCUMHM(E17), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vmudm(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // vmudl
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
- // ------------------------------------------------------
- //
- // Multiplies signed integer by unsigned fraction
- // The result is stored into accumulator
- // The middle slice of accumulator is stored into destination element
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMUDM_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMUDM_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMUDM_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMUDM_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMUDM_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMUDM_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMUDM_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMUDM_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMUDM_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMUDM_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMUDM_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMUDM_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMUDM_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMUDM_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMUDM_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMUDM_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
+ vres[i] = ACCUM_L(i);
}
-
- return TRUE;
+ WRITEBACK_RESULT();
}
-#else
-#define RSP_VMUDM(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- ACCUM(E10).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I0) * (UINT16)R_VREG_S_X(VS2REG, E20)) << 16; \
- ACCUM(E11).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I1) * (UINT16)R_VREG_S_X(VS2REG, E21)) << 16; \
- ACCUM(E12).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I2) * (UINT16)R_VREG_S_X(VS2REG, E22)) << 16; \
- ACCUM(E13).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I3) * (UINT16)R_VREG_S_X(VS2REG, E23)) << 16; \
- ACCUM(E14).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I4) * (UINT16)R_VREG_S_X(VS2REG, E24)) << 16; \
- ACCUM(E15).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I5) * (UINT16)R_VREG_S_X(VS2REG, E25)) << 16; \
- ACCUM(E16).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I6) * (UINT16)R_VREG_S_X(VS2REG, E26)) << 16; \
- ACCUM(E17).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I7) * (UINT16)R_VREG_S_X(VS2REG, E27)) << 16; \
- vres[E10] = ACCUM(E10).h.mid; \
- vres[E11] = ACCUM(E11).h.mid; \
- vres[E12] = ACCUM(E12).h.mid; \
- vres[E13] = ACCUM(E13).h.mid; \
- vres[E14] = ACCUM(E14).h.mid; \
- vres[E15] = ACCUM(E15).h.mid; \
- vres[E16] = ACCUM(E16).h.mid; \
- vres[E17] = ACCUM(E17).h.mid; \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- }
INLINE void cfunc_rsp_vmudm(void *param)
{
@@ -2819,102 +1901,31 @@ INLINE void cfunc_rsp_vmudm(void *param)
// The result is stored into accumulator
// The middle slice of accumulator is stored into destination element
- switch(EL)
+ int sel;
+ INT32 s1, s2;
+ INT32 r;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMUDM(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMUDM(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMUDM(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMUDM(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMUDM(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMUDM(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMUDM(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMUDM(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMUDM(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMUDM(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMUDM(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMUDM(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMUDM(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMUDM(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMUDM(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMUDM(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- }
-
-#ifdef UNUSED_CODE
- for (i=0; i < 8; i++)
- {
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (UINT16)R_VREG_S(VS2REG, sel); // not sign-extended
- INT32 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (UINT16)VREG_S(VS2REG, sel); // not sign-extended
+ r = s1 * s2;
- W_ACCUM_H(del, (r < 0) ? 0xffff : 0); // sign-extend to 48-bit
- W_ACCUM_M(del, (INT16)(r >> 16));
- W_ACCUM_L(del, (UINT16)(r));
+ ACCUM_H(i) = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
+ ACCUM_M(i) = (INT16)(r >> 16);
+ ACCUM_L(i) = (UINT16)(r);
- vres[del] = ACCUM(del).h.mid;
+ vres[i] = ACCUM_M(i);
}
WRITEBACK_RESULT();
-#endif
}
-#endif
-
-#define RSP_VMUDN(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- { \
- ACCUM(E10).l = ((UINT16)R_VREG_S(VS1REG, E10) * (INT64)(INT16)R_VREG_S(VS2REG, E20)) << 16; \
- ACCUM(E11).l = ((UINT16)R_VREG_S(VS1REG, E11) * (INT64)(INT16)R_VREG_S(VS2REG, E21)) << 16; \
- ACCUM(E12).l = ((UINT16)R_VREG_S(VS1REG, E12) * (INT64)(INT16)R_VREG_S(VS2REG, E22)) << 16; \
- ACCUM(E13).l = ((UINT16)R_VREG_S(VS1REG, E13) * (INT64)(INT16)R_VREG_S(VS2REG, E23)) << 16; \
- ACCUM(E14).l = ((UINT16)R_VREG_S(VS1REG, E14) * (INT64)(INT16)R_VREG_S(VS2REG, E24)) << 16; \
- ACCUM(E15).l = ((UINT16)R_VREG_S(VS1REG, E15) * (INT64)(INT16)R_VREG_S(VS2REG, E25)) << 16; \
- ACCUM(E16).l = ((UINT16)R_VREG_S(VS1REG, E16) * (INT64)(INT16)R_VREG_S(VS2REG, E26)) << 16; \
- ACCUM(E17).l = ((UINT16)R_VREG_S(VS1REG, E17) * (INT64)(INT16)R_VREG_S(VS2REG, E27)) << 16; \
- W_VREG_S(VDREG, E10, ACCUM(E10).h.low); \
- W_VREG_S(VDREG, E11, ACCUM(E11).h.low); \
- W_VREG_S(VDREG, E12, ACCUM(E12).h.low); \
- W_VREG_S(VDREG, E13, ACCUM(E13).h.low); \
- W_VREG_S(VDREG, E14, ACCUM(E14).h.low); \
- W_VREG_S(VDREG, E15, ACCUM(E15).h.low); \
- W_VREG_S(VDREG, E16, ACCUM(E16).h.low); \
- W_VREG_S(VDREG, E17, ACCUM(E17).h.low); \
- }
INLINE void cfunc_rsp_vmudn(void *param)
{
rsp_state *rsp = (rsp_state*)param;
int op = rsp->impstate->arg0;
+ INT16 vres[8] = { 0 };
+
// 31 25 24 20 15 10 5 0
// ------------------------------------------------------
// | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 000110 |
@@ -2924,57 +1935,23 @@ INLINE void cfunc_rsp_vmudn(void *param)
// The result is stored into accumulator
// The low slice of accumulator is stored into destination element
- switch(EL)
+ int sel;
+ INT32 s1, s2;
+ INT32 r;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMUDN(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMUDN(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMUDN(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMUDN(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMUDN(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMUDN(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMUDN(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMUDN(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMUDN(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMUDN(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMUDN(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMUDN(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMUDN(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMUDN(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMUDN(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMUDN(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT16)VREG_S(VS1REG, i); // not sign-extended
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 * s2;
+
+ ACCUM_H(i) = (r < 0) ? 0xffff : 0; // sign-extend to 48-bit
+ ACCUM_M(i) = (INT16)(r >> 16);
+ ACCUM_L(i) = (UINT16)(r);
+
+ vres[i] = ACCUM_L(i);
}
+ WRITEBACK_RESULT();
}
INLINE void cfunc_rsp_vmudh(void *param)
@@ -2992,135 +1969,50 @@ INLINE void cfunc_rsp_vmudh(void *param)
// The result is stored into highest 32 bits of accumulator, the low slice is zero
// The highest 32 bits of accumulator is saturated into destination element
+ int sel;
+ INT32 s1, s2;
+ INT32 r;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 * s2;
- W_ACCUM_H(del, (INT16)(r >> 16));
- W_ACCUM_M(del, (UINT16)(r));
- W_ACCUM_L(del, 0);
+ ACCUM_H(i) = (INT16)(r >> 16);
+ ACCUM_M(i) = (UINT16)(r);
+ ACCUM_L(i) = 0;
if (r < -32768) r = -32768;
if (r > 32767) r = 32767;
- vres[del] = (INT16)(r);
+ vres[i] = (INT16)(r);
}
WRITEBACK_RESULT();
}
-#define RSP_VMACF(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- { \
- ACCUM(E10).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E10) * (INT32)(INT16)R_VREG_S(VS2REG, E20)) << 17; \
- ACCUM(E11).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E11) * (INT32)(INT16)R_VREG_S(VS2REG, E21)) << 17; \
- ACCUM(E12).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E12) * (INT32)(INT16)R_VREG_S(VS2REG, E22)) << 17; \
- ACCUM(E13).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E13) * (INT32)(INT16)R_VREG_S(VS2REG, E23)) << 17; \
- ACCUM(E14).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E14) * (INT32)(INT16)R_VREG_S(VS2REG, E24)) << 17; \
- ACCUM(E15).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E15) * (INT32)(INT16)R_VREG_S(VS2REG, E25)) << 17; \
- ACCUM(E16).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E16) * (INT32)(INT16)R_VREG_S(VS2REG, E26)) << 17; \
- ACCUM(E17).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E17) * (INT32)(INT16)R_VREG_S(VS2REG, E27)) << 17; \
- vres[E10] = SATURATE_ACCUM_SIGNED(rsp, E10); \
- vres[E11] = SATURATE_ACCUM_SIGNED(rsp, E11); \
- vres[E12] = SATURATE_ACCUM_SIGNED(rsp, E12); \
- vres[E13] = SATURATE_ACCUM_SIGNED(rsp, E13); \
- vres[E14] = SATURATE_ACCUM_SIGNED(rsp, E14); \
- vres[E15] = SATURATE_ACCUM_SIGNED(rsp, E15); \
- vres[E16] = SATURATE_ACCUM_SIGNED(rsp, E16); \
- vres[E17] = SATURATE_ACCUM_SIGNED(rsp, E17); \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- }
-
INLINE void cfunc_rsp_vmacf(void *param)
{
rsp_state *rsp = (rsp_state*)param;
int op = rsp->impstate->arg0;
INT16 vres[8];
- //int i;
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001000 |
- // ------------------------------------------------------
- //
- // Multiplies signed integer by signed integer * 2
- // The result is added to accumulator
- switch(EL)
+ int sel;
+ INT32 s1, s2;
+ INT32 r;
+ UINT16 res;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMACF(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMACF(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMACF(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMACF(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMACF(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMACF(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMACF(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMACF(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMACF(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMACF(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMACF(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMACF(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMACF(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMACF(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMACF(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMACF(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
- }
-#if 0
- for (i=0; i < 8; i++)
- {
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 * s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 * s2;
- ACCUM(del).l += (INT64)(r) << 17;
- res = SATURATE_ACCUM_SIGNED(rsp, del);
+ ACCUM(i) += (INT64)(r) << 17;
+ res = SATURATE_ACCUM(rsp, i, 1, 0x8000, 0x7fff);
- vres[del] = res;
+ vres[i] = res;
}
WRITEBACK_RESULT();
-#endif
}
INLINE void cfunc_rsp_vmacu(void *param)
@@ -3135,45 +2027,48 @@ INLINE void cfunc_rsp_vmacu(void *param)
// ------------------------------------------------------
//
- for (i=0; i < 8; i++)
- {
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r1 = s1 * s2;
- UINT32 r2 = (UINT16)ACCUM(del).h.low + ((UINT16)(r1) * 2);
- UINT32 r3 = (UINT16)ACCUM(del).h.mid + (UINT16)((r1 >> 16) * 2) + (UINT16)(r2 >> 16);
-
- W_ACCUM_L(del, (UINT16)(r2));
- W_ACCUM_M(del, (UINT16)(r3));
- W_ACCUM_H(del, (UINT16)ACCUM(del).h.high + (UINT16)(r3 >> 16) + (UINT16)(r1 >> 31));
-
- if (ACCUM(del).h.high < 0)
+ UINT16 res;
+ int sel;
+ INT32 s1, s2, r1;
+ UINT32 r2, r3;
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r1 = s1 * s2;
+ r2 = (UINT16)ACCUM_L(i) + ((UINT16)(r1) * 2);
+ r3 = (UINT16)ACCUM_M(i) + (UINT16)((r1 >> 16) * 2) + (UINT16)(r2 >> 16);
+
+ ACCUM_L(i) = (UINT16)(r2);
+ ACCUM_M(i) = (UINT16)(r3);
+ ACCUM_H(i) += (UINT16)(r3 >> 16) + (UINT16)(r1 >> 31);
+
+ //res = SATURATE_ACCUM(i, 1, 0x0000, 0xffff);
+ if ((INT16)ACCUM_H(i) < 0)
{
res = 0;
}
else
{
- if (ACCUM(del).h.high != 0)
+ if (ACCUM_H(i) != 0)
{
res = 0xffff;
}
else
{
- if (ACCUM(del).h.mid < 0)
+ if ((INT16)ACCUM_M(i) < 0)
{
res = 0xffff;
}
else
{
- res = ACCUM(del).h.mid;
+ res = ACCUM_M(i);
}
}
}
- vres[del] = res;
+ vres[i] = res;
}
WRITEBACK_RESULT();
}
@@ -3193,690 +2088,84 @@ INLINE void cfunc_rsp_vmadl(void *param)
// Adds the higher 16 bits of the 32-bit result to accumulator
// The low slice of accumulator is stored into destination element
- for (i=0; i < 8; i++)
+ UINT16 res;
+ int sel;
+ UINT32 s1, s2, r1;
+ UINT32 r2, r3;
+ for (i = 0; i < 8; i++)
{
- UINT16 res;
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- UINT32 s1 = (UINT32)(UINT16)R_VREG_S(VS1REG, del);
- UINT32 s2 = (UINT32)(UINT16)R_VREG_S(VS2REG, sel);
- UINT32 r1 = s1 * s2;
- UINT32 r2 = (UINT16)ACCUM(del).h.low + (r1 >> 16);
- UINT32 r3 = (UINT16)ACCUM(del).h.mid + (r2 >> 16);
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
+ s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
+ r1 = s1 * s2;
+ r2 = (UINT16)ACCUM_L(i) + (r1 >> 16);
+ r3 = (UINT16)ACCUM_M(i) + (r2 >> 16);
- W_ACCUM_L(del, (UINT16)(r2));
- W_ACCUM_M(del, (UINT16)(r3));
- W_ACCUM_H(del, ACCUM(del).h.high + (INT16)(r3 >> 16));
+ ACCUM_L(i) = (UINT16)(r2);
+ ACCUM_M(i) = (UINT16)(r3);
+ ACCUM_H(i) += (INT16)(r3 >> 16);
- res = SATURATE_ACCUM_UNSIGNED(rsp, del);
+ res = SATURATE_ACCUM(rsp, i, 0, 0x0000, 0xffff);
- vres[del] = res;
+ vres[i] = res;
}
WRITEBACK_RESULT();
}
-#if (DRC_VMADM)
-/*------------------------------------------------------------------
- generate_vmadm
-------------------------------------------------------------------*/
-
-#define RSP_VMADM_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E10), VACCUML(E10), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E11), VACCUML(E11), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E12), VACCUML(E12), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E13), VACCUML(E13), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E14), VACCUML(E14), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E15), VACCUML(E15), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E16), VACCUML(E16), IREG(0)); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E17), VACCUML(E17), IREG(0)); \
- \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E10); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E11); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E12); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E13); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E14); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E15); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E16); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E17); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vmadm(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // vmadm
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
- // ------------------------------------------------------
- //
- // Multiplies signed integer by unsigned fraction
- // The result is added into accumulator
- // The middle slice of accumulator is stored into destination element
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMADM_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMADM_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMADM_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMADM_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMADM_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMADM_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMADM_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMADM_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMADM_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMADM_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMADM_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMADM_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMADM_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMADM_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMADM_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMADM_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- }
-
- return TRUE;
-}
-#else
-#define RSP_VMADM(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- { \
- ACCUM(E10).l += ((INT64)(INT16)R_VREG_S(VS1REG, E10) * (UINT16)R_VREG_S(VS2REG, E20)) << 16; \
- ACCUM(E11).l += ((INT64)(INT16)R_VREG_S(VS1REG, E11) * (UINT16)R_VREG_S(VS2REG, E21)) << 16; \
- ACCUM(E12).l += ((INT64)(INT16)R_VREG_S(VS1REG, E12) * (UINT16)R_VREG_S(VS2REG, E22)) << 16; \
- ACCUM(E13).l += ((INT64)(INT16)R_VREG_S(VS1REG, E13) * (UINT16)R_VREG_S(VS2REG, E23)) << 16; \
- ACCUM(E14).l += ((INT64)(INT16)R_VREG_S(VS1REG, E14) * (UINT16)R_VREG_S(VS2REG, E24)) << 16; \
- ACCUM(E15).l += ((INT64)(INT16)R_VREG_S(VS1REG, E15) * (UINT16)R_VREG_S(VS2REG, E25)) << 16; \
- ACCUM(E16).l += ((INT64)(INT16)R_VREG_S(VS1REG, E16) * (UINT16)R_VREG_S(VS2REG, E26)) << 16; \
- ACCUM(E17).l += ((INT64)(INT16)R_VREG_S(VS1REG, E17) * (UINT16)R_VREG_S(VS2REG, E27)) << 16; \
- vres[E10] = SATURATE_ACCUM_SIGNED(rsp, E10); \
- vres[E11] = SATURATE_ACCUM_SIGNED(rsp, E11); \
- vres[E12] = SATURATE_ACCUM_SIGNED(rsp, E12); \
- vres[E13] = SATURATE_ACCUM_SIGNED(rsp, E13); \
- vres[E14] = SATURATE_ACCUM_SIGNED(rsp, E14); \
- vres[E15] = SATURATE_ACCUM_SIGNED(rsp, E15); \
- vres[E16] = SATURATE_ACCUM_SIGNED(rsp, E16); \
- vres[E17] = SATURATE_ACCUM_SIGNED(rsp, E17); \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- }
-
INLINE void cfunc_rsp_vmadm(void *param)
{
rsp_state *rsp = (rsp_state*)param;
int op = rsp->impstate->arg0;
INT16 vres[8];
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001101 |
- // ------------------------------------------------------
- //
- // Multiplies signed integer by unsigned fraction
- // The result is added into accumulator
- // The middle slice of accumulator is stored into destination element
- switch(EL)
+ UINT16 res;
+ int sel;
+ UINT32 s1, s2, r1;
+ UINT32 r2, r3;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMADM(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMADM(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMADM(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMADM(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMADM(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMADM(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMADM(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMADM(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMADM(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMADM(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMADM(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMADM(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMADM(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMADM(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMADM(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMADM(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
- }
-}
-#endif
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (UINT16)VREG_S(VS2REG, sel); // not sign-extended
+ r1 = s1 * s2;
+ r2 = (UINT16)ACCUM_L(i) + (UINT16)(r1);
+ r3 = (UINT16)ACCUM_M(i) + (r1 >> 16) + (r2 >> 16);
-#if (DRC_VMADN)
-/*------------------------------------------------------------------
- generate_vmadn
-------------------------------------------------------------------*/
+ ACCUM_L(i) = (UINT16)(r2);
+ ACCUM_M(i) = (UINT16)(r3);
+ ACCUM_H(i) += (UINT16)(r3 >> 16);
+ if ((INT32)(r1) < 0)
+ ACCUM_H(i) -= 1;
-#define RSP_VMADN_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(1), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E20), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E10), VACCUML(E10), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E21), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E11), VACCUML(E11), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E22), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E12), VACCUML(E12), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E23), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E13), VACCUML(E13), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E24), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E14), VACCUML(E14), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E25), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E15), VACCUML(E15), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E26), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E16), VACCUML(E16), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E27), WORD); \
- UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
- UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
- UML_DADD(block, VACCUML(E17), VACCUML(E17), IREG(0)); \
- \
- generate_saturate_accum_unsigned(rsp, block, compiler, desc, E10); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_unsigned(rsp, block, compiler, desc, E11); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_unsigned(rsp, block, compiler, desc, E12); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_unsigned(rsp, block, compiler, desc, E13); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_unsigned(rsp, block, compiler, desc, E14); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_unsigned(rsp, block, compiler, desc, E15); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_unsigned(rsp, block, compiler, desc, E16); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_unsigned(rsp, block, compiler, desc, E17); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vmadn(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // vmadn
-{
- UINT32 op = desc->opptr.l[0];
+ res = SATURATE_ACCUM(rsp, i, 1, 0x8000, 0x7fff);
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
- // ------------------------------------------------------
- //
- // Multiplies unsigned fraction by signed integer
- // The result is added into accumulator
- // The low slice of accumulator is stored into destination element
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMADN_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMADN_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMADN_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMADN_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMADN_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMADN_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMADN_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMADN_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMADN_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMADN_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMADN_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMADN_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMADN_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMADN_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMADN_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMADN_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
+ vres[i] = res;
}
-
- return TRUE;
+ WRITEBACK_RESULT();
}
-#else
-#define RSP_VMADN(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- ACCUM(E10).l += ((UINT16)R_VREG_S_X(VS1REG, I0) * (INT64)R_VREG_S_X(VS2REG, E20)) << 16; \
- ACCUM(E11).l += ((UINT16)R_VREG_S_X(VS1REG, I1) * (INT64)R_VREG_S_X(VS2REG, E21)) << 16; \
- ACCUM(E12).l += ((UINT16)R_VREG_S_X(VS1REG, I2) * (INT64)R_VREG_S_X(VS2REG, E22)) << 16; \
- ACCUM(E13).l += ((UINT16)R_VREG_S_X(VS1REG, I3) * (INT64)R_VREG_S_X(VS2REG, E23)) << 16; \
- ACCUM(E14).l += ((UINT16)R_VREG_S_X(VS1REG, I4) * (INT64)R_VREG_S_X(VS2REG, E24)) << 16; \
- ACCUM(E15).l += ((UINT16)R_VREG_S_X(VS1REG, I5) * (INT64)R_VREG_S_X(VS2REG, E25)) << 16; \
- ACCUM(E16).l += ((UINT16)R_VREG_S_X(VS1REG, I6) * (INT64)R_VREG_S_X(VS2REG, E26)) << 16; \
- ACCUM(E17).l += ((UINT16)R_VREG_S_X(VS1REG, I7) * (INT64)R_VREG_S_X(VS2REG, E27)) << 16; \
- vres[E10] = SATURATE_ACCUM_UNSIGNED(rsp, E10); \
- vres[E11] = SATURATE_ACCUM_UNSIGNED(rsp, E11); \
- vres[E12] = SATURATE_ACCUM_UNSIGNED(rsp, E12); \
- vres[E13] = SATURATE_ACCUM_UNSIGNED(rsp, E13); \
- vres[E14] = SATURATE_ACCUM_UNSIGNED(rsp, E14); \
- vres[E15] = SATURATE_ACCUM_UNSIGNED(rsp, E15); \
- vres[E16] = SATURATE_ACCUM_UNSIGNED(rsp, E16); \
- vres[E17] = SATURATE_ACCUM_UNSIGNED(rsp, E17); \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- }
INLINE void cfunc_rsp_vmadn(void *param)
{
rsp_state *rsp = (rsp_state*)param;
int op = rsp->impstate->arg0;
INT16 vres[8];
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
- // ------------------------------------------------------
- //
- // Multiplies unsigned fraction by signed integer
- // The result is added into accumulator
- // The low slice of accumulator is stored into destination element
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMADN(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMADN(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMADN(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMADN(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMADN(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMADN(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMADN(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMADN(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMADN(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMADN(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMADN(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMADN(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMADN(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMADN(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMADN(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMADN(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- }
-}
-#endif
-#if (DRC_VMADH)
-/*------------------------------------------------------------------
- generate_vmadh
-------------------------------------------------------------------*/
+ INT32 s1, s2;
+ UINT16 res;
+ int sel;
+ for (int i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT16)VREG_S(VS1REG, i); // not sign-extended
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
-#define RSP_VMADH_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(1), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E20), WORD); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_ADD(block, VACCUMWMH(E10), VACCUMWMH(E10), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E21), WORD); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_ADD(block, VACCUMWMH(E11), VACCUMWMH(E11), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E22), WORD); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_ADD(block, VACCUMWMH(E12), VACCUMWMH(E12), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E23), WORD); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_ADD(block, VACCUMWMH(E13), VACCUMWMH(E13), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E24), WORD); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_ADD(block, VACCUMWMH(E14), VACCUMWMH(E14), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E25), WORD); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_ADD(block, VACCUMWMH(E15), VACCUMWMH(E15), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E26), WORD); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_ADD(block, VACCUMWMH(E16), VACCUMWMH(E16), IREG(0)); \
- \
- UML_SEXT(block, IREG(1), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(0), VS(VS2REG, E27), WORD); \
- UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
- UML_ADD(block, VACCUMWMH(E17), VACCUMWMH(E17), IREG(0)); \
- \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E10); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E11); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E12); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E13); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E14); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E15); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E16); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- generate_saturate_accum_signed(rsp, block, compiler, desc, E17); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vmadh(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // vmadh
-{
- UINT32 op = desc->opptr.l[0];
+ ACCUM(i) += (INT64)(s1*s2)<<16;
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
- // ------------------------------------------------------
- //
- // Multiplies unsigned fraction by signed integer
- // The result is added into accumulator
- // The low slice of accumulator is stored into destination element
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMADH_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMADH_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMADH_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMADH_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMADH_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMADH_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMADH_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMADH_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMADH_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMADH_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMADH_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMADH_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMADH_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMADH_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMADH_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMADH_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
+ res = SATURATE_ACCUM(rsp, i, 0, 0x0000, 0xffff);
+ vres[i] = res;
}
-
- return TRUE;
+ WRITEBACK_RESULT();
}
-#else
-#define RSP_VMADH(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- ACCUM(E10).w.mh += (INT32)R_VREG_S_X(VS1REG, I0) * (INT32)R_VREG_S_X(VS2REG, E20); \
- ACCUM(E11).w.mh += (INT32)R_VREG_S_X(VS1REG, I1) * (INT32)R_VREG_S_X(VS2REG, E21); \
- ACCUM(E12).w.mh += (INT32)R_VREG_S_X(VS1REG, I2) * (INT32)R_VREG_S_X(VS2REG, E22); \
- ACCUM(E13).w.mh += (INT32)R_VREG_S_X(VS1REG, I3) * (INT32)R_VREG_S_X(VS2REG, E23); \
- ACCUM(E14).w.mh += (INT32)R_VREG_S_X(VS1REG, I4) * (INT32)R_VREG_S_X(VS2REG, E24); \
- ACCUM(E15).w.mh += (INT32)R_VREG_S_X(VS1REG, I5) * (INT32)R_VREG_S_X(VS2REG, E25); \
- ACCUM(E16).w.mh += (INT32)R_VREG_S_X(VS1REG, I6) * (INT32)R_VREG_S_X(VS2REG, E26); \
- ACCUM(E17).w.mh += (INT32)R_VREG_S_X(VS1REG, I7) * (INT32)R_VREG_S_X(VS2REG, E27); \
- vres[E10] = SATURATE_ACCUM_SIGNED(rsp, E10); \
- vres[E11] = SATURATE_ACCUM_SIGNED(rsp, E11); \
- vres[E12] = SATURATE_ACCUM_SIGNED(rsp, E12); \
- vres[E13] = SATURATE_ACCUM_SIGNED(rsp, E13); \
- vres[E14] = SATURATE_ACCUM_SIGNED(rsp, E14); \
- vres[E15] = SATURATE_ACCUM_SIGNED(rsp, E15); \
- vres[E16] = SATURATE_ACCUM_SIGNED(rsp, E16); \
- vres[E17] = SATURATE_ACCUM_SIGNED(rsp, E17); \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- }
INLINE void cfunc_rsp_vmadh(void *param)
{
@@ -3892,390 +2181,23 @@ INLINE void cfunc_rsp_vmadh(void *param)
// The result is added into highest 32 bits of accumulator, the low slice is zero
// The highest 32 bits of accumulator is saturated into destination element
- switch(EL)
+ UINT16 res;
+ int sel;
+ INT32 s1, s2;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMADH(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMADH(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMADH(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMADH(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMADH(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMADH(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMADH(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMADH(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMADH(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMADH(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMADH(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMADH(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMADH(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMADH(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMADH(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMADH(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- }
-}
-#endif
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
-#if (DRC_VADD)
-/*------------------------------------------------------------------
- generate_vadd
-------------------------------------------------------------------*/
+ rsp->accum[i].l[1] += s1*s2;
-#define RSP_VADD_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- int inrange, outofrange; \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
- UML_SHL(block, IREG(2), IMM(1), IMM(E10)); \
- UML_AND(block, IREG(1), IREG(1), IREG(2)); \
- UML_SHR(block, IREG(1), IREG(1), IMM(E10)); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
- UML_CMP(block, IREG(0), IMM(32767)); \
- UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(32767)); \
- UML_JMP(block, outofrange = compiler->labelnum++); \
- \
- UML_LABEL(block, inrange); \
- \
- UML_CMP(block, IREG(0), IMM(-32768)); \
- UML_JMPc(block, IF_G, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(-32768)); \
- \
- UML_LABEL(block, inrange); \
- UML_LABEL(block, outofrange); \
- \
- UML_MOV(block, VRES(E10), IREG(0)); \
- \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
- UML_SHL(block, IREG(2), IMM(1), IMM(E11)); \
- UML_AND(block, IREG(1), IREG(1), IREG(2)); \
- UML_SHR(block, IREG(1), IREG(1), IMM(E11)); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
- UML_CMP(block, IREG(0), IMM(32767)); \
- UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(32767)); \
- UML_JMP(block, outofrange = compiler->labelnum++); \
- \
- UML_LABEL(block, inrange); \
- \
- UML_CMP(block, IREG(0), IMM(-32768)); \
- UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(-32768)); \
- \
- UML_LABEL(block, inrange); \
- UML_LABEL(block, outofrange); \
- \
- UML_MOV(block, VRES(E11), IREG(0)); \
- \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
- UML_SHL(block, IREG(2), IMM(1), IMM(E12)); \
- UML_AND(block, IREG(1), IREG(1), IREG(2)); \
- UML_SHR(block, IREG(1), IREG(1), IMM(E12)); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
- UML_CMP(block, IREG(0), IMM(32767)); \
- UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(32767)); \
- UML_JMP(block, outofrange = compiler->labelnum++); \
- \
- UML_LABEL(block, inrange); \
- \
- UML_CMP(block, IREG(0), IMM(-32768)); \
- UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(-32768)); \
- \
- UML_LABEL(block, inrange); \
- UML_LABEL(block, outofrange); \
- \
- UML_MOV(block, VRES(E12), IREG(0)); \
- \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
- UML_SHL(block, IREG(2), IMM(1), IMM(E13)); \
- UML_AND(block, IREG(1), IREG(1), IREG(2)); \
- UML_SHR(block, IREG(1), IREG(1), IMM(E13)); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
- UML_CMP(block, IREG(0), IMM(32767)); \
- UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(32767)); \
- UML_JMP(block, outofrange = compiler->labelnum++); \
- \
- UML_LABEL(block, inrange); \
- \
- UML_CMP(block, IREG(0), IMM(-32768)); \
- UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(-32768)); \
- \
- UML_LABEL(block, inrange); \
- UML_LABEL(block, outofrange); \
- \
- UML_MOV(block, VRES(E13), IREG(0)); \
- \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
- UML_SHL(block, IREG(2), IMM(1), IMM(E14)); \
- UML_AND(block, IREG(1), IREG(1), IREG(2)); \
- UML_SHR(block, IREG(1), IREG(1), IMM(E14)); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
- UML_CMP(block, IREG(0), IMM(32767)); \
- UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(32767)); \
- UML_JMP(block, outofrange = compiler->labelnum++); \
- \
- UML_LABEL(block, inrange); \
- \
- UML_CMP(block, IREG(0), IMM(-32768)); \
- UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(-32768)); \
- \
- UML_LABEL(block, inrange); \
- UML_LABEL(block, outofrange); \
- \
- UML_MOV(block, VRES(E14), IREG(0)); \
- \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
- UML_SHL(block, IREG(2), IMM(1), IMM(E15)); \
- UML_AND(block, IREG(1), IREG(1), IREG(2)); \
- UML_SHR(block, IREG(1), IREG(1), IMM(E15)); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
- UML_CMP(block, IREG(0), IMM(32767)); \
- UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(32767)); \
- UML_JMP(block, outofrange = compiler->labelnum++); \
- \
- UML_LABEL(block, inrange); \
- \
- UML_CMP(block, IREG(0), IMM(-32768)); \
- UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(-32768)); \
- \
- UML_LABEL(block, inrange); \
- UML_LABEL(block, outofrange); \
- \
- UML_MOV(block, VRES(E15), IREG(0)); \
- \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
- UML_SHL(block, IREG(2), IMM(1), IMM(E16)); \
- UML_AND(block, IREG(1), IREG(1), IREG(2)); \
- UML_SHR(block, IREG(1), IREG(1), IMM(E16)); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
- UML_CMP(block, IREG(0), IMM(32767)); \
- UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(32767)); \
- UML_JMP(block, outofrange = compiler->labelnum++); \
- \
- UML_LABEL(block, inrange); \
- \
- UML_CMP(block, IREG(0), IMM(-32768)); \
- UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(-32768)); \
- \
- UML_LABEL(block, inrange); \
- UML_LABEL(block, outofrange); \
- \
- UML_MOV(block, VRES(E16), IREG(0)); \
- \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
- UML_SHL(block, IREG(2), IMM(1), IMM(E17)); \
- UML_AND(block, IREG(1), IREG(1), IREG(2)); \
- UML_SHR(block, IREG(1), IREG(1), IMM(E17)); \
- UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
- UML_CMP(block, IREG(0), IMM(32767)); \
- UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(32767)); \
- UML_JMP(block, outofrange = compiler->labelnum++); \
- \
- UML_LABEL(block, inrange); \
- \
- UML_CMP(block, IREG(0), IMM(-32768)); \
- UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
- \
- UML_MOV(block, IREG(0), IMM(-32768)); \
- \
- UML_LABEL(block, inrange); \
- UML_LABEL(block, outofrange); \
- \
- UML_MOV(block, VRES(E17), IREG(0)); \
- \
- \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), VRES(E10), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), VRES(E11), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), VRES(E12), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), VRES(E13), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), VRES(E14), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), VRES(E15), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), VRES(E16), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), VRES(E17), WORD); \
- }
-
-static int generate_vadd(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // vadd
-{
- UINT32 op = desc->opptr.l[0];
+ res = SATURATE_ACCUM1(rsp, i, 0x8000, 0x7fff);
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
- // ------------------------------------------------------
- //
- // Multiplies unsigned fraction by signed integer
- // The result is added into accumulator
- // The low slice of accumulator is stored into destination element
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VADD_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VADD_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VADD_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VADD_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VADD_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VADD_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VADD_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VADD_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VADD_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VADD_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VADD_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VADD_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VADD_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VADD_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VADD_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VADD_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
+ vres[i] = res;
}
-
- return TRUE;
+ WRITEBACK_RESULT();
}
-#else
-#define RSP_VADD(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- INT32 r; \
- ACCUM(E10).h.low = (INT16)(r = (INT32)R_VREG_S_X(VS1REG, I0) + (INT32)R_VREG_S_X(VS2REG, E20) + ((rsp->flag[0] & (1 << E10)) >> E10)); \
- vres[E10] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E10).h.low); \
- ACCUM(E11).h.low = (INT16)(r = (INT32)R_VREG_S_X(VS1REG, I1) + (INT32)R_VREG_S_X(VS2REG, E21) + ((rsp->flag[0] & (1 << E11)) >> E11)); \
- vres[E11] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E11).h.low); \
- ACCUM(E12).h.low = (INT16)(r = (INT32)R_VREG_S_X(VS1REG, I2) + (INT32)R_VREG_S_X(VS2REG, E22) + ((rsp->flag[0] & (1 << E12)) >> E12)); \
- vres[E12] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E12).h.low); \
- ACCUM(E13).h.low = (INT16)(r = (INT32)R_VREG_S_X(VS1REG, I3) + (INT32)R_VREG_S_X(VS2REG, E23) + ((rsp->flag[0] & (1 << E13)) >> E13)); \
- vres[E13] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E13).h.low); \
- ACCUM(E14).h.low = (INT16)(r = (INT32)R_VREG_S_X(VS1REG, I4) + (INT32)R_VREG_S_X(VS2REG, E24) + ((rsp->flag[0] & (1 << E14)) >> E14)); \
- vres[E14] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E14).h.low); \
- ACCUM(E15).h.low = (INT16)(r = (INT32)R_VREG_S_X(VS1REG, I5) + (INT32)R_VREG_S_X(VS2REG, E25) + ((rsp->flag[0] & (1 << E15)) >> E15)); \
- vres[E15] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E15).h.low); \
- ACCUM(E16).h.low = (INT16)(r = (INT32)R_VREG_S_X(VS1REG, I6) + (INT32)R_VREG_S_X(VS2REG, E26) + ((rsp->flag[0] & (1 << E16)) >> E16)); \
- vres[E16] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E16).h.low); \
- ACCUM(E17).h.low = (INT16)(r = (INT32)R_VREG_S_X(VS1REG, I7) + (INT32)R_VREG_S_X(VS2REG, E27) + ((rsp->flag[0] & (1 << E17)) >> E17)); \
- vres[E17] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E17).h.low); \
- }
INLINE void cfunc_rsp_vadd(void *param)
{
@@ -4290,62 +2212,25 @@ INLINE void cfunc_rsp_vadd(void *param)
//
// Adds two vector registers and carry flag, the result is saturated to 32767
- // TODO: check VS2REG == VDREG
- switch(EL)
+ int sel;
+ INT32 s1, s2, r;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VADD(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VADD(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VADD(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VADD(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VADD(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VADD(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VADD(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VADD(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VADD(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VADD(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VADD(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VADD(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VADD(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VADD(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VADD(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VADD(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 + s2 + CARRY_FLAG(i);
+
+ ACCUM_L(i) = (INT16)(r);
+
+ if (r > 32767) r = 32767;
+ if (r < -32768) r = -32768;
+ vres[i] = (INT16)(r);
}
- rsp->flag[0] = 0;
+ CLEAR_ZERO_FLAGS();
+ CLEAR_CARRY_FLAGS();
WRITEBACK_RESULT();
}
-#endif
INLINE void cfunc_rsp_vsub(void *param)
{
@@ -4362,22 +2247,24 @@ INLINE void cfunc_rsp_vsub(void *param)
// TODO: check VS2REG == VDREG
- for (i=0; i < 8; i++)
+ int sel;
+ INT32 s1, s2, r;
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 - s2 - CARRY_FLAG(del);
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT32)(INT16)VREG_S(VS1REG, i);
+ s2 = (INT32)(INT16)VREG_S(VS2REG, sel);
+ r = s1 - s2 - CARRY_FLAG(i);
- W_ACCUM_L(del, (INT16)(r));
+ ACCUM_L(i) = (INT16)(r);
if (r > 32767) r = 32767;
if (r < -32768) r = -32768;
- vres[del] = (INT16)(r);
+ vres[i] = (INT16)(r);
}
- rsp->flag[0] = 0;
+ CLEAR_ZERO_FLAGS();
+ CLEAR_CARRY_FLAGS();
WRITEBACK_RESULT();
}
@@ -4395,34 +2282,35 @@ INLINE void cfunc_rsp_vabs(void *param)
// Changes the sign of source register 2 if source register 1 is negative and stores
// the result to destination register
+ int sel;
+ INT16 s1, s2;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT16 s1 = (INT16)R_VREG_S(VS1REG, del);
- INT16 s2 = (INT16)R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = (INT16)VREG_S(VS1REG, i);
+ s2 = (INT16)VREG_S(VS2REG, sel);
if (s1 < 0)
{
if (s2 == -32768)
{
- vres[del] = 32767;
+ vres[i] = 32767;
}
else
{
- vres[del] = -s2;
+ vres[i] = -s2;
}
}
else if (s1 > 0)
{
- vres[del] = s2;
+ vres[i] = s2;
}
else
{
- vres[del] = 0;
+ vres[i] = 0;
}
- W_ACCUM_L(del, vres[del]);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
}
@@ -4442,22 +2330,24 @@ INLINE void cfunc_rsp_vaddc(void *param)
// TODO: check VS2REG = VDREG
- rsp->flag[0] = 0;
+ int sel;
+ INT32 s1, s2, r;
+ CLEAR_ZERO_FLAGS();
+ CLEAR_CARRY_FLAGS();
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (UINT32)(UINT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (UINT32)(UINT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 + s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
+ s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
+ r = s1 + s2;
- vres[del] = (INT16)(r);
- W_ACCUM_L(del, (INT16)(r));
+ vres[i] = (INT16)(r);
+ ACCUM_L(i) = (INT16)(r);
if (r & 0xffff0000)
{
- SET_CARRY_FLAG(del);
+ SET_CARRY_FLAG(i);
}
}
WRITEBACK_RESULT();
@@ -4478,26 +2368,28 @@ INLINE void cfunc_rsp_vsubc(void *param)
// TODO: check VS2REG = VDREG
- rsp->flag[0] = 0;
+ int sel;
+ INT32 s1, s2, r;
+ CLEAR_ZERO_FLAGS();
+ CLEAR_CARRY_FLAGS();
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT32 s1 = (UINT32)(UINT16)R_VREG_S(VS1REG, del);
- INT32 s2 = (UINT32)(UINT16)R_VREG_S(VS2REG, sel);
- INT32 r = s1 - s2;
+ sel = VEC_EL_2(EL, i);
+ s1 = (UINT32)(UINT16)VREG_S(VS1REG, i);
+ s2 = (UINT32)(UINT16)VREG_S(VS2REG, sel);
+ r = s1 - s2;
- vres[del] = (INT16)(r);
- W_ACCUM_L(del, (UINT16)(r));
+ vres[i] = (INT16)(r);
+ ACCUM_L(i) = (UINT16)(r);
if ((UINT16)(r) != 0)
{
- SET_ZERO_FLAG(del);
+ SET_ZERO_FLAG(i);
}
if (r & 0xffff0000)
{
- SET_CARRY_FLAG(del);
+ SET_CARRY_FLAG(i);
}
}
WRITEBACK_RESULT();
@@ -4518,171 +2410,32 @@ INLINE void cfunc_rsp_vsaw(void *param)
{
case 0x08: // VSAWH
{
- W_VREG_S_X(VDREG, 7, ACCUM(0).h.high);
- W_VREG_S_X(VDREG, 6, ACCUM(1).h.high);
- W_VREG_S_X(VDREG, 5, ACCUM(2).h.high);
- W_VREG_S_X(VDREG, 4, ACCUM(3).h.high);
- W_VREG_S_X(VDREG, 3, ACCUM(4).h.high);
- W_VREG_S_X(VDREG, 2, ACCUM(5).h.high);
- W_VREG_S_X(VDREG, 1, ACCUM(6).h.high);
- W_VREG_S_X(VDREG, 0, ACCUM(7).h.high);
+ for (int i = 0; i < 8; i++)
+ {
+ VREG_S(VDREG, i) = ACCUM_H(i);
+ }
break;
}
case 0x09: // VSAWM
{
- W_VREG_S_X(VDREG, 7, ACCUM(0).h.mid);
- W_VREG_S_X(VDREG, 6, ACCUM(1).h.mid);
- W_VREG_S_X(VDREG, 5, ACCUM(2).h.mid);
- W_VREG_S_X(VDREG, 4, ACCUM(3).h.mid);
- W_VREG_S_X(VDREG, 3, ACCUM(4).h.mid);
- W_VREG_S_X(VDREG, 2, ACCUM(5).h.mid);
- W_VREG_S_X(VDREG, 1, ACCUM(6).h.mid);
- W_VREG_S_X(VDREG, 0, ACCUM(7).h.mid);
+ for (int i = 0; i < 8; i++)
+ {
+ VREG_S(VDREG, i) = ACCUM_M(i);
+ }
break;
}
case 0x0a: // VSAWL
{
- W_VREG_S_X(VDREG, 7, ACCUM(0).h.low);
- W_VREG_S_X(VDREG, 6, ACCUM(1).h.low);
- W_VREG_S_X(VDREG, 5, ACCUM(2).h.low);
- W_VREG_S_X(VDREG, 4, ACCUM(3).h.low);
- W_VREG_S_X(VDREG, 3, ACCUM(4).h.low);
- W_VREG_S_X(VDREG, 2, ACCUM(5).h.low);
- W_VREG_S_X(VDREG, 1, ACCUM(6).h.low);
- W_VREG_S_X(VDREG, 0, ACCUM(7).h.low);
+ for (int i = 0; i < 8; i++)
+ {
+ VREG_S(VDREG, i) = ACCUM_L(i);
+ }
break;
}
default: fatalerror("RSP: VSAW: el = %d\n", EL);
}
}
-#define RSP_VLT(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- rsp->flag[1] = 0; \
- \
- if (R_VREG_S_X(VS1REG, I0) > R_VREG_S_X(VS2REG, E20)) \
- { \
- ACCUM(E16).h.low = vres[E10] = R_VREG_S_X(VS2REG, E20); \
- } \
- else if (R_VREG_S_X(VS1REG, I0) < R_VREG_S_X(VS2REG, E20)) \
- { \
- ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS1REG, I0); \
- SET_COMPARE_FLAG(E10); \
- } \
- else if (R_VREG_S_X(VS1REG, I0) == R_VREG_S_X(VS2REG, E20)) \
- { \
- ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS1REG, I0); \
- if (ZERO_FLAG(E10) && CARRY_FLAG(E10)) SET_COMPARE_FLAG(E10); \
- } \
- if (R_VREG_S_X(VS1REG, I1) > R_VREG_S_X(VS2REG, E21)) \
- { \
- ACCUM(E16).h.low = vres[E11] = R_VREG_S_X(VS2REG, E21); \
- } \
- else if (R_VREG_S_X(VS1REG, I1) < R_VREG_S_X(VS2REG, E21)) \
- { \
- ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS1REG, I1); \
- SET_COMPARE_FLAG(E11); \
- } \
- else if (R_VREG_S_X(VS1REG, I1) == R_VREG_S_X(VS2REG, E21)) \
- { \
- ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS1REG, I1); \
- if (ZERO_FLAG(E11) && CARRY_FLAG(E11)) SET_COMPARE_FLAG(E11); \
- } \
- if (R_VREG_S_X(VS1REG, I2) > R_VREG_S_X(VS2REG, E22)) \
- { \
- ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS2REG, E22); \
- } \
- else if (R_VREG_S_X(VS1REG, I2) < R_VREG_S_X(VS2REG, E22)) \
- { \
- ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS1REG, I2); \
- SET_COMPARE_FLAG(E12); \
- } \
- else if (R_VREG_S_X(VS1REG, I2) == R_VREG_S_X(VS2REG, E22)) \
- { \
- ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS1REG, I2); \
- if (ZERO_FLAG(E12) && CARRY_FLAG(E12)) SET_COMPARE_FLAG(E12); \
- } \
- if (R_VREG_S_X(VS1REG, I3) > R_VREG_S_X(VS2REG, E23)) \
- { \
- ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS2REG, E23); \
- } \
- else if (R_VREG_S_X(VS1REG, I3) < R_VREG_S_X(VS2REG, E23)) \
- { \
- ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS1REG, I3); \
- SET_COMPARE_FLAG(E13); \
- } \
- else if (R_VREG_S_X(VS1REG, I3) == R_VREG_S_X(VS2REG, E23)) \
- { \
- ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS1REG, I3); \
- if (ZERO_FLAG(E10) && CARRY_FLAG(E13)) SET_COMPARE_FLAG(E13); \
- } \
- if (R_VREG_S_X(VS1REG, I4) > R_VREG_S_X(VS2REG, E24)) \
- { \
- ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS2REG, E24); \
- } \
- else if (R_VREG_S_X(VS1REG, I4) < R_VREG_S_X(VS2REG, E24)) \
- { \
- ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS1REG, I4); \
- SET_COMPARE_FLAG(E14); \
- } \
- else if (R_VREG_S_X(VS1REG, I4) == R_VREG_S_X(VS2REG, E24)) \
- { \
- ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS1REG, I4); \
- if (ZERO_FLAG(E14) && CARRY_FLAG(E14)) SET_COMPARE_FLAG(E14); \
- } \
- if (R_VREG_S_X(VS1REG, I5) > R_VREG_S_X(VS2REG, E25)) \
- { \
- ACCUM(E15).h.low = vres[5] = R_VREG_S_X(VS2REG, E25); \
- } \
- else if (R_VREG_S_X(VS1REG, I5) < R_VREG_S_X(VS2REG, E25)) \
- { \
- ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS1REG, I5); \
- SET_COMPARE_FLAG(E15); \
- } \
- else if (R_VREG_S_X(VS1REG, I5) == R_VREG_S_X(VS2REG, E25)) \
- { \
- ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS1REG, I5); \
- if (ZERO_FLAG(E15) && CARRY_FLAG(E15)) SET_COMPARE_FLAG(E15); \
- } \
- if (R_VREG_S_X(VS1REG, I6) > R_VREG_S_X(VS2REG, E26)) \
- { \
- ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS2REG, E26); \
- } \
- else if (R_VREG_S_X(VS1REG, I6) < R_VREG_S_X(VS2REG, E26)) \
- { \
- ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS1REG, I6); \
- SET_COMPARE_FLAG(E16); \
- } \
- else if (R_VREG_S_X(VS1REG, I6) == R_VREG_S_X(VS2REG, E26)) \
- { \
- ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS1REG, I6); \
- if (ZERO_FLAG(E16) && CARRY_FLAG(E16)) SET_COMPARE_FLAG(E16); \
- } \
- if (R_VREG_S_X(VS1REG, I7) > R_VREG_S_X(VS2REG, E27)) \
- { \
- ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS2REG, E27); \
- } \
- else if (R_VREG_S_X(VS1REG, I7) < R_VREG_S_X(VS2REG, E27)) \
- { \
- ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS1REG, I7); \
- SET_COMPARE_FLAG(E17); \
- } \
- else if (R_VREG_S_X(VS1REG, I7) == R_VREG_S_X(VS2REG, E27)) \
- { \
- ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS1REG, I7); \
- if (ZERO_FLAG(E17) && CARRY_FLAG(E17)) SET_COMPARE_FLAG(E17); \
- } \
- rsp->flag[0] = 0; \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- }
-
INLINE void cfunc_rsp_vlt(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -4697,58 +2450,39 @@ INLINE void cfunc_rsp_vlt(void *param)
// Sets compare flags if elements in VS1 are less than VS2
// Moves the element in VS2 to destination vector
- switch(EL)
+ int sel;
+ rsp->flag[1] = 0;
+
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VLT(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VLT(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VLT(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VLT(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VLT(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VLT(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VLT(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VLT(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VLT(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VLT(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VLT(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VLT(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VLT(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VLT(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VLT(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VLT(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
+ sel = VEC_EL_2(EL, i);
+
+ if (VREG_S(VS1REG, i) < VREG_S(VS2REG, sel))
+ {
+ SET_COMPARE_FLAG(i);
+ }
+ else if (VREG_S(VS1REG, i) == VREG_S(VS2REG, sel))
+ {
+ if (ZERO_FLAG(i) == 1 && CARRY_FLAG(i) != 0)
+ {
+ SET_COMPARE_FLAG(i);
+ }
+ }
+
+ if (COMPARE_FLAG(i))
+ {
+ vres[i] = VREG_S(VS1REG, i);
+ }
+ else
+ {
+ vres[i] = VREG_S(VS2REG, sel);
+ }
+
+ ACCUM_L(i) = vres[i];
}
+ rsp->flag[0] = 0;
+ WRITEBACK_RESULT();
}
INLINE void cfunc_rsp_veq(void *param)
@@ -4765,23 +2499,23 @@ INLINE void cfunc_rsp_veq(void *param)
// Sets compare flags if elements in VS1 are equal with VS2
// Moves the element in VS2 to destination vector
+ int sel;
rsp->flag[1] = 0;
- for (i=0; i < 8; i++)
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
+ sel = VEC_EL_2(EL, i);
- vres[del] = R_VREG_S(VS2REG, sel);
- W_ACCUM_L(del, vres[del]);
-
- if (R_VREG_S(VS1REG, del) == R_VREG_S(VS2REG, sel))
+ if ((VREG_S(VS1REG, i) == VREG_S(VS2REG, sel)) && ZERO_FLAG(i) == 0)
{
- if (ZERO_FLAG(del) == 0)
- {
- SET_COMPARE_FLAG(del);
- }
+ SET_COMPARE_FLAG(i);
+ vres[i] = VREG_S(VS1REG, i);
+ }
+ else
+ {
+ vres[i] = VREG_S(VS2REG, sel);
}
+ ACCUM_L(i) = vres[i];
}
rsp->flag[0] = 0;
@@ -4802,216 +2536,39 @@ INLINE void cfunc_rsp_vne(void *param)
// Sets compare flags if elements in VS1 are not equal with VS2
// Moves the element in VS2 to destination vector
+ int sel;
rsp->flag[1] = 0;
- for (i=0; i < 8; i++)
+ for (i=0; i < 8; i++)//ïåðåïèñàíî ìíîé
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
-
- vres[del] = R_VREG_S(VS1REG, del);
- W_ACCUM_L(del, vres[del]);
+ sel = VEC_EL_2(EL, i);
- if (R_VREG_S(VS1REG, del) != R_VREG_S(VS2REG, sel))
+ if (VREG_S(VS1REG, i) != VREG_S(VS2REG, sel))
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
else
{
- if (ZERO_FLAG(del) != 0)
+ if (ZERO_FLAG(i) == 1)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
}
+ if (COMPARE_FLAG(i))
+ {
+ vres[i] = VREG_S(VS1REG, i);
+ }
+ else
+ {
+ vres[i] = VREG_S(VS2REG, sel);
+ }
+ ACCUM_L(i) = vres[i];
}
rsp->flag[0] = 0;
WRITEBACK_RESULT();
}
-#define RSP_VGE(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- rsp->flag[1] = 0; \
- \
- if (R_VREG_S_X(VS1REG, I0) > R_VREG_S_X(VS2REG, E20)) \
- { \
- ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS1REG, I0); \
- SET_COMPARE_FLAG(E10); \
- } \
- else if (R_VREG_S_X(VS1REG, I0) == R_VREG_S_X(VS2REG, E20)) \
- { \
- if (!ZERO_FLAG(E10) || !CARRY_FLAG(E10)) \
- { \
- ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS1REG, I0); \
- SET_COMPARE_FLAG(E10); \
- } \
- else \
- { \
- ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS2REG, E20); \
- } \
- } \
- else \
- { \
- ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS2REG, E20); \
- } \
- if (R_VREG_S_X(VS1REG, I1) > R_VREG_S_X(VS2REG, E21)) \
- { \
- ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS1REG, I1); \
- SET_COMPARE_FLAG(E11); \
- } \
- else if (R_VREG_S_X(VS1REG, I1) == R_VREG_S_X(VS2REG, E21)) \
- { \
- if (!ZERO_FLAG(E11) || !CARRY_FLAG(E11)) \
- { \
- ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS1REG, I1); \
- SET_COMPARE_FLAG(E11); \
- } \
- else \
- { \
- ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS2REG, E21); \
- } \
- } \
- else \
- { \
- ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS2REG, E21); \
- } \
- if (R_VREG_S_X(VS1REG, I2) > R_VREG_S_X(VS2REG, E22)) \
- { \
- ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS1REG, I2); \
- SET_COMPARE_FLAG(E12); \
- } \
- else if (R_VREG_S_X(VS1REG, I2) == R_VREG_S_X(VS2REG, E22)) \
- { \
- if (!ZERO_FLAG(E12) || !CARRY_FLAG(E12)) \
- { \
- ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS1REG, I2); \
- SET_COMPARE_FLAG(E12); \
- } \
- else \
- { \
- ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS2REG, E22); \
- } \
- } \
- else \
- { \
- ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS2REG, E22); \
- } \
- if (R_VREG_S_X(VS1REG, I3) > R_VREG_S_X(VS2REG, E23)) \
- { \
- ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS1REG, I3); \
- SET_COMPARE_FLAG(E13); \
- } \
- else if (R_VREG_S_X(VS1REG, I3) == R_VREG_S_X(VS2REG, E23)) \
- { \
- if (!ZERO_FLAG(E13) || !CARRY_FLAG(E13)) \
- { \
- ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS1REG, I3); \
- SET_COMPARE_FLAG(E13); \
- } \
- else \
- { \
- ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS2REG, E23); \
- } \
- } \
- else \
- { \
- ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS2REG, E23); \
- } \
- if (R_VREG_S_X(VS1REG, I4) > R_VREG_S_X(VS2REG, E24)) \
- { \
- ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS1REG, I4); \
- SET_COMPARE_FLAG(E14); \
- } \
- else if (R_VREG_S_X(VS1REG, I4) == R_VREG_S_X(VS2REG, E24)) \
- { \
- if (!ZERO_FLAG(E14) || !CARRY_FLAG(E14)) \
- { \
- ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS1REG, I4); \
- SET_COMPARE_FLAG(E14); \
- } \
- else \
- { \
- ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS2REG, E24); \
- } \
- } \
- else \
- { \
- ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS2REG, E24); \
- } \
- if (R_VREG_S_X(VS1REG, I5) > R_VREG_S_X(VS2REG, E25)) \
- { \
- ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS1REG, I5); \
- SET_COMPARE_FLAG(E15); \
- } \
- else if (R_VREG_S_X(VS1REG, I5) == R_VREG_S_X(VS2REG, E25)) \
- { \
- if (!ZERO_FLAG(E15) || !CARRY_FLAG(E15)) \
- { \
- ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS1REG, I5); \
- SET_COMPARE_FLAG(E15); \
- } \
- else \
- { \
- ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS2REG, E25); \
- } \
- } \
- else \
- { \
- ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS2REG, E25); \
- } \
- if (R_VREG_S_X(VS1REG, I6) > R_VREG_S_X(VS2REG, E26)) \
- { \
- ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS1REG, I6); \
- SET_COMPARE_FLAG(E16); \
- } \
- else if (R_VREG_S_X(VS1REG, I6) == R_VREG_S_X(VS2REG, E26)) \
- { \
- if (!ZERO_FLAG(E16) || !CARRY_FLAG(E16)) \
- { \
- ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS1REG, I6); \
- SET_COMPARE_FLAG(E16); \
- } \
- else \
- { \
- ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS2REG, E26); \
- } \
- } \
- else \
- { \
- ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS2REG, E26); \
- } \
- if (R_VREG_S_X(VS1REG, I7) > R_VREG_S_X(VS2REG, E27)) \
- { \
- ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS1REG, I7); \
- SET_COMPARE_FLAG(E17); \
- } \
- else if (R_VREG_S_X(VS1REG, I7) == R_VREG_S_X(VS2REG, E27)) \
- { \
- if (!ZERO_FLAG(E17) || !CARRY_FLAG(E17)) \
- { \
- ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS1REG, I7); \
- SET_COMPARE_FLAG(E17); \
- } \
- else \
- { \
- ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS2REG, E27); \
- } \
- } \
- else \
- { \
- ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS2REG, E27); \
- } \
- rsp->flag[0] = 0; \
- W_VREG_S_X(VDREG, 7, vres[0]); \
- W_VREG_S_X(VDREG, 6, vres[1]); \
- W_VREG_S_X(VDREG, 5, vres[2]); \
- W_VREG_S_X(VDREG, 4, vres[3]); \
- W_VREG_S_X(VDREG, 3, vres[4]); \
- W_VREG_S_X(VDREG, 2, vres[5]); \
- W_VREG_S_X(VDREG, 1, vres[6]); \
- W_VREG_S_X(VDREG, 0, vres[7]); \
- }
-
INLINE void cfunc_rsp_vge(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -5026,93 +2583,39 @@ INLINE void cfunc_rsp_vge(void *param)
// Sets compare flags if elements in VS1 are greater or equal with VS2
// Moves the element in VS2 to destination vector
-#if 1
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VGE(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VGE(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VGE(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VGE(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VGE(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VGE(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VGE(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VGE(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VGE(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VGE(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- break;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VGE(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- break;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VGE(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- break;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VGE(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- break;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VGE(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- break;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VGE(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- break;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VGE(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- break;
- }
-#else
+ int sel;
rsp->flag[1] = 0;
- for (i=0; i < 8; i++)
+ for (int i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
+ sel = VEC_EL_2(EL, i);
- if (R_VREG_S(VS1REG, del) == R_VREG_S(VS2REG, sel))
+ if (VREG_S(VS1REG, i) == VREG_S(VS2REG, sel))
{
- if (ZERO_FLAG(del) == 0 || CARRY_FLAG(del) == 0)
+ if (ZERO_FLAG(i) == 0 || CARRY_FLAG(i) == 0)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
}
- else if (R_VREG_S(VS1REG, del) > R_VREG_S(VS2REG, sel))
+ else if (VREG_S(VS1REG, i) > VREG_S(VS2REG, sel))
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
- if (COMPARE_FLAG(del))
+ if (COMPARE_FLAG(i) != 0)
{
- vres[del] = R_VREG_S(VS1REG, del);
+ vres[i] = VREG_S(VS1REG, i);
}
else
{
- vres[del] = R_VREG_S(VS2REG, sel);
+ vres[i] = VREG_S(VS2REG, sel);
}
- W_ACCUM_L(del, vres[del]);
+ ACCUM_L(i) = vres[i];
}
rsp->flag[0] = 0;
WRITEBACK_RESULT();
-#endif
}
INLINE void cfunc_rsp_vcl(void *param)
@@ -5128,85 +2631,94 @@ INLINE void cfunc_rsp_vcl(void *param)
//
// Vector clip low
- for (i=0; i < 8; i++)
+ int sel;
+ INT16 s1, s2;
+ for (i = 0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT16 s1 = R_VREG_S(VS1REG, del);
- INT16 s2 = R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = VREG_S(VS1REG, i);
+ s2 = VREG_S(VS2REG, sel);
- if (CARRY_FLAG(del) != 0)
+ if (CARRY_FLAG(i) != 0)
{
- if (ZERO_FLAG(del) != 0)
+
+ if (ZERO_FLAG(i) != 0)
{
- if (COMPARE_FLAG(del) != 0)
+
+ if (COMPARE_FLAG(i) != 0)
{
- W_ACCUM_L(del, -(UINT16)s2);
+ ACCUM_L(i) = -(UINT16)s2;
}
else
{
- W_ACCUM_L(del, s1);
+ ACCUM_L(i) = s1;
}
}
- else
+ else//ZERO_FLAG(i)==0
{
- if (rsp->flag[2] & (1 << (del)))
+
+ if (rsp->flag[2] & (1 << (i)))
{
+
if (((UINT32)(UINT16)(s1) + (UINT32)(UINT16)(s2)) > 0x10000)
- {
- W_ACCUM_L(del, s1);
- CLEAR_COMPARE_FLAG(del);
+ {//proper fix for Harvest Moon 64, r4
+
+ ACCUM_L(i) = s1;
+ CLEAR_COMPARE_FLAG(i);
}
else
{
- W_ACCUM_L(del, -((UINT16)s2));
- SET_COMPARE_FLAG(del);
+
+ ACCUM_L(i) = -((UINT16)s2);
+ SET_COMPARE_FLAG(i);
}
}
else
{
- if (((UINT32)(INT16)(s1) + (UINT32)(INT16)(s2)) != 0)
+ if (((UINT32)(UINT16)(s1) + (UINT32)(UINT16)(s2)) != 0)
{
- W_ACCUM_L(del, s1);
- CLEAR_COMPARE_FLAG(del);
+ ACCUM_L(i) = s1;
+ CLEAR_COMPARE_FLAG(i);
}
else
{
- W_ACCUM_L(del, -((UINT16)s2));
- SET_COMPARE_FLAG(del);
+ ACCUM_L(i) = -((UINT16)s2);
+ SET_COMPARE_FLAG(i);
}
}
}
- }
- else
+ }//
+ else//CARRY_FLAG(i)==0
{
- if (ZERO_FLAG(del) != 0)
+
+ if (ZERO_FLAG(i) != 0)
{
- if (rsp->flag[1] & (0x100 << del))
+
+ if (rsp->flag[1] & (1 << (8+i)))
{
- W_ACCUM_L(del, s2);
+ ACCUM_L(i) = s2;
}
else
{
- W_ACCUM_L(del, s1);
+ ACCUM_L(i) = s1;
}
}
else
{
if (((INT32)(UINT16)s1 - (INT32)(UINT16)s2) >= 0)
{
- W_ACCUM_L(del, s2);
- rsp->flag[1] |= (0x100 << del);
+ ACCUM_L(i) = s2;
+ rsp->flag[1] |= (1 << (8+i));
}
else
{
- W_ACCUM_L(del, s1);
- rsp->flag[1] &= ~(0x100 << del);
+ ACCUM_L(i) = s1;
+ rsp->flag[1] &= ~(1 << (8+i));
}
}
}
- vres[del] = ACCUM(del).h.low;
+ vres[i] = ACCUM_L(i);
}
rsp->flag[0] = 0;
rsp->flag[2] = 0;
@@ -5226,73 +2738,73 @@ INLINE void cfunc_rsp_vch(void *param)
//
// Vector clip high
+ int sel;
+ INT16 s1, s2;
rsp->flag[0] = 0;
rsp->flag[1] = 0;
rsp->flag[2] = 0;
+ UINT32 vce = 0;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT16 s1 = R_VREG_S(VS1REG, del);
- INT16 s2 = R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = VREG_S(VS1REG, i);
+ s2 = VREG_S(VS2REG, sel);
if ((s1 ^ s2) < 0)
{
- SET_CARRY_FLAG(del);
+ vce = (s1 + s2 == -1);
+ SET_CARRY_FLAG(i);
if (s2 < 0)
{
- rsp->flag[1] |= (0x100 << del);
+ rsp->flag[1] |= (1 << (8+i));
}
if (s1 + s2 <= 0)
{
- if (s1 + s2 == -1)
- {
- rsp->flag[2] |= (1 << (del));
- }
- SET_COMPARE_FLAG(del);
- vres[del] = -((UINT16)s2);
+ SET_COMPARE_FLAG(i);
+ vres[i] = -((UINT16)s2);
}
else
{
- vres[del] = s1;
+ vres[i] = s1;
}
if (s1 + s2 != 0)
{
if (s1 != ~s2)
{
- SET_ZERO_FLAG(del);
+ SET_ZERO_FLAG(i);
}
}
- }
+ }//sign
else
{
+ vce = 0;
if (s2 < 0)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
if (s1 - s2 >= 0)
{
- rsp->flag[1] |= (0x100 << del);
- vres[del] = s2;
+ rsp->flag[1] |= (1 << (8+i));
+ vres[i] = s2;
}
else
{
- vres[del] = s1;
+ vres[i] = s1;
}
if ((s1 - s2) != 0)
{
if (s1 != ~s2)
{
- SET_ZERO_FLAG(del);
+ SET_ZERO_FLAG(i);
}
}
}
-
- W_ACCUM_L(del, vres[del]);
+ rsp->flag[2] |= (vce << (i));
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
}
@@ -5310,129 +2822,56 @@ INLINE void cfunc_rsp_vcr(void *param)
//
// Vector clip reverse
+ int sel;
+ INT16 s1, s2;
rsp->flag[0] = 0;
rsp->flag[1] = 0;
rsp->flag[2] = 0;
for (i=0; i < 8; i++)
{
- int del = VEC_EL_1(EL, i);
- int sel = VEC_EL_2(EL, del);
- INT16 s1 = R_VREG_S(VS1REG, del);
- INT16 s2 = R_VREG_S(VS2REG, sel);
+ sel = VEC_EL_2(EL, i);
+ s1 = VREG_S(VS1REG, i);
+ s2 = VREG_S(VS2REG, sel);
if ((INT16)(s1 ^ s2) < 0)
{
if (s2 < 0)
{
- rsp->flag[1] |= (0x100 << del);
+ rsp->flag[1] |= (1 << (8+i));
}
if ((s1 + s2) <= 0)
{
- W_ACCUM_L(del, ~((UINT16)s2));
- SET_COMPARE_FLAG(del);
+ ACCUM_L(i) = ~((UINT16)s2);
+ SET_COMPARE_FLAG(i);
}
else
{
- W_ACCUM_L(del, s1);
+ ACCUM_L(i) = s1;
}
}
else
{
if (s2 < 0)
{
- SET_COMPARE_FLAG(del);
+ SET_COMPARE_FLAG(i);
}
if ((s1 - s2) >= 0)
{
- W_ACCUM_L(del, s2);
- rsp->flag[1] |= (0x100 << del);
+ ACCUM_L(i) = s2;
+ rsp->flag[1] |= (1 << (8+i));
}
else
{
- W_ACCUM_L(del, s1);
+ ACCUM_L(i) = s1;
}
}
- vres[del] = ACCUM(del).h.low;
+ vres[i] = ACCUM_L(i);
}
WRITEBACK_RESULT();
}
-#define RSP_VMRG(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- if (COMPARE_FLAG(E10)) \
- { \
- vres[E10] = R_VREG_S(VS1REG, E10); \
- } \
- else \
- { \
- vres[E10] = R_VREG_S(VS2REG, E20); \
- } \
- if (COMPARE_FLAG(E11)) \
- { \
- vres[E11] = R_VREG_S(VS1REG, E11); \
- } \
- else \
- { \
- vres[E11] = R_VREG_S(VS2REG, E21); \
- } \
- if (COMPARE_FLAG(E12)) \
- { \
- vres[E12] = R_VREG_S(VS1REG, E12); \
- } \
- else \
- { \
- vres[E12] = R_VREG_S(VS2REG, E22); \
- } \
- if (COMPARE_FLAG(E13)) \
- { \
- vres[E13] = R_VREG_S(VS1REG, E13); \
- } \
- else \
- { \
- vres[E13] = R_VREG_S(VS2REG, E23); \
- } \
- if (COMPARE_FLAG(E14)) \
- { \
- vres[E14] = R_VREG_S(VS1REG, E14); \
- } \
- else \
- { \
- vres[E14] = R_VREG_S(VS2REG, E24); \
- } \
- if (COMPARE_FLAG(E15)) \
- { \
- vres[E15] = R_VREG_S(VS1REG, E15); \
- } \
- else \
- { \
- vres[E15] = R_VREG_S(VS2REG, E25); \
- } \
- if (COMPARE_FLAG(E16)) \
- { \
- vres[E16] = R_VREG_S(VS1REG, E16); \
- } \
- else \
- { \
- vres[E16] = R_VREG_S(VS2REG, E26); \
- } \
- if (COMPARE_FLAG(E17)) \
- { \
- vres[E17] = R_VREG_S(VS1REG, E17); \
- } \
- else \
- { \
- vres[E17] = R_VREG_S(VS2REG, E27); \
- } \
- W_ACCUM_L(E10, vres[E10]); \
- W_ACCUM_L(E11, vres[E11]); \
- W_ACCUM_L(E12, vres[E12]); \
- W_ACCUM_L(E13, vres[E13]); \
- W_ACCUM_L(E14, vres[E14]); \
- W_ACCUM_L(E15, vres[E15]); \
- W_ACCUM_L(E16, vres[E16]); \
- W_ACCUM_L(E17, vres[E17]); \
-
INLINE void cfunc_rsp_vmrg(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -5445,204 +2884,23 @@ INLINE void cfunc_rsp_vmrg(void *param)
//
// Merges two vectors according to compare flags
- switch(EL)
+ int sel;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VMRG(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VMRG(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VMRG(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VMRG(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VMRG(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VMRG(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VMRG(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VMRG(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VMRG(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VMRG(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10:/* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VMRG(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11:/* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VMRG(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12:/* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VMRG(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13:/* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VMRG(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14:/* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VMRG(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15:/* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VMRG(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
- }
- WRITEBACK_RESULT();
-}
-
-#if (DRC_VAND)
-#define RSP_VAND_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vand(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
- // ------------------------------------------------------
- //
- // Bitwise AND of two vector registers
+ sel = VEC_EL_2(EL, i);
+ if (COMPARE_FLAG(i) != 0)
+ {
+ vres[i] = VREG_S(VS1REG, i);
+ }
+ else
+ {
+ vres[i] = VREG_S(VS2REG, sel);//ìî¸ èñïðàâëåíèå
+ }
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VAND_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VAND_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VAND_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VAND_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VAND_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VAND_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VAND_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VAND_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VAND_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VAND_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VAND_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VAND_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VAND_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VAND_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VAND_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VAND_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
+ ACCUM_L(i) = vres[i];
}
-
- return TRUE;
+ WRITEBACK_RESULT();
}
-#else
-#define RSP_VAND(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- vres[E10] = R_VREG_S(VS1REG, E10) & R_VREG_S(VS2REG, E20); \
- vres[E11] = R_VREG_S(VS1REG, E11) & R_VREG_S(VS2REG, E21); \
- vres[E12] = R_VREG_S(VS1REG, E12) & R_VREG_S(VS2REG, E22); \
- vres[E13] = R_VREG_S(VS1REG, E13) & R_VREG_S(VS2REG, E23); \
- vres[E14] = R_VREG_S(VS1REG, E14) & R_VREG_S(VS2REG, E24); \
- vres[E15] = R_VREG_S(VS1REG, E15) & R_VREG_S(VS2REG, E25); \
- vres[E16] = R_VREG_S(VS1REG, E16) & R_VREG_S(VS2REG, E26); \
- vres[E17] = R_VREG_S(VS1REG, E17) & R_VREG_S(VS2REG, E27); \
- W_ACCUM_L(E10, vres[E10]); \
- W_ACCUM_L(E11, vres[E11]); \
- W_ACCUM_L(E12, vres[E12]); \
- W_ACCUM_L(E13, vres[E13]); \
- W_ACCUM_L(E14, vres[E14]); \
- W_ACCUM_L(E15, vres[E15]); \
- W_ACCUM_L(E16, vres[E16]); \
- W_ACCUM_L(E17, vres[E17]); \
INLINE void cfunc_rsp_vand(void *param)
{
@@ -5656,213 +2914,15 @@ INLINE void cfunc_rsp_vand(void *param)
//
// Bitwise AND of two vector registers
- switch(EL)
+ int sel;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VAND(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VAND(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VAND(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VAND(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VAND(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VAND(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VAND(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VAND(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VAND(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VAND(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10:/* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VAND(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11:/* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VAND(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12:/* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VAND(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13:/* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VAND(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14:/* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VAND(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15:/* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VAND(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
+ sel = VEC_EL_2(EL, i);
+ vres[i] = VREG_S(VS1REG, i) & VREG_S(VS2REG, sel);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
}
-#endif
-
-#if (DRC_VNAND)
-#define RSP_VNAND_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
- UML_AND(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vnand(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
- // ------------------------------------------------------
- //
- // Bitwise NOT AND of two vector registers
-
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VNAND_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VNAND_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VNAND_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VNAND_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VNAND_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VNAND_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VNAND_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VNAND_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VNAND_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VNAND_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VNAND_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VNAND_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VNAND_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VNAND_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VNAND_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VNAND_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- }
-
- return TRUE;
-}
-#else
-#define RSP_VNAND(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- vres[E10] = ~(R_VREG_S(VS1REG, E10) & R_VREG_S(VS2REG, E20)); \
- vres[E11] = ~(R_VREG_S(VS1REG, E11) & R_VREG_S(VS2REG, E21)); \
- vres[E12] = ~(R_VREG_S(VS1REG, E12) & R_VREG_S(VS2REG, E22)); \
- vres[E13] = ~(R_VREG_S(VS1REG, E13) & R_VREG_S(VS2REG, E23)); \
- vres[E14] = ~(R_VREG_S(VS1REG, E14) & R_VREG_S(VS2REG, E24)); \
- vres[E15] = ~(R_VREG_S(VS1REG, E15) & R_VREG_S(VS2REG, E25)); \
- vres[E16] = ~(R_VREG_S(VS1REG, E16) & R_VREG_S(VS2REG, E26)); \
- vres[E17] = ~(R_VREG_S(VS1REG, E17) & R_VREG_S(VS2REG, E27)); \
- W_ACCUM_L(E10, vres[E10]); \
- W_ACCUM_L(E11, vres[E11]); \
- W_ACCUM_L(E12, vres[E12]); \
- W_ACCUM_L(E13, vres[E13]); \
- W_ACCUM_L(E14, vres[E14]); \
- W_ACCUM_L(E15, vres[E15]); \
- W_ACCUM_L(E16, vres[E16]); \
- W_ACCUM_L(E17, vres[E17]); \
INLINE void cfunc_rsp_vnand(void *param)
{
@@ -5876,205 +2936,15 @@ INLINE void cfunc_rsp_vnand(void *param)
//
// Bitwise NOT AND of two vector registers
- switch(EL)
+ int sel;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VNAND(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VNAND(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VNAND(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VNAND(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VNAND(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VNAND(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VNAND(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VNAND(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VNAND(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VNAND(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10:/* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VNAND(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11:/* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VNAND(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12:/* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VNAND(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13:/* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VNAND(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14:/* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VNAND(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15:/* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VNAND(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
+ sel = VEC_EL_2(EL, i);
+ vres[i] = ~((VREG_S(VS1REG, i) & VREG_S(VS2REG, sel)));
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
}
-#endif
-
-#if (DRC_VOR)
-#define RSP_VOR_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
- // ------------------------------------------------------
- //
- // Bitwise OR of two vector registers
-
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VOR_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VOR_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VOR_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VOR_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VOR_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VOR_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VOR_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VOR_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VOR_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VOR_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VOR_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VOR_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VOR_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- }
-
- return TRUE;
-}
-#else
-#define RSP_VOR(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- vres[E10] = R_VREG_S(VS1REG, E10) | R_VREG_S(VS2REG, E20); \
- vres[E11] = R_VREG_S(VS1REG, E11) | R_VREG_S(VS2REG, E21); \
- vres[E12] = R_VREG_S(VS1REG, E12) | R_VREG_S(VS2REG, E22); \
- vres[E13] = R_VREG_S(VS1REG, E13) | R_VREG_S(VS2REG, E23); \
- vres[E14] = R_VREG_S(VS1REG, E14) | R_VREG_S(VS2REG, E24); \
- vres[E15] = R_VREG_S(VS1REG, E15) | R_VREG_S(VS2REG, E25); \
- vres[E16] = R_VREG_S(VS1REG, E16) | R_VREG_S(VS2REG, E26); \
- vres[E17] = R_VREG_S(VS1REG, E17) | R_VREG_S(VS2REG, E27); \
- W_ACCUM_L(E10, vres[E10]); \
- W_ACCUM_L(E11, vres[E11]); \
- W_ACCUM_L(E12, vres[E12]); \
- W_ACCUM_L(E13, vres[E13]); \
- W_ACCUM_L(E14, vres[E14]); \
- W_ACCUM_L(E15, vres[E15]); \
- W_ACCUM_L(E16, vres[E16]); \
- W_ACCUM_L(E17, vres[E17]); \
INLINE void cfunc_rsp_vor(void *param)
{
@@ -6088,213 +2958,15 @@ INLINE void cfunc_rsp_vor(void *param)
//
// Bitwise OR of two vector registers
- switch(EL)
+ int sel;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VOR(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VOR(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10:/* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VOR(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11:/* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VOR(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12:/* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VOR(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13:/* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VOR(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14:/* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VOR(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15:/* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VOR(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
+ sel = VEC_EL_2(EL, i);
+ vres[i] = VREG_S(VS1REG, i) | VREG_S(VS2REG, sel);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
}
-#endif
-
-#if (DRC_VNOR)
-#define RSP_VNOR_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
- UML_OR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vnor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
- // ------------------------------------------------------
- //
- // Bitwise NOT OR of two vector registers
-
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VNOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VNOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VNOR_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VNOR_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VNOR_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VNOR_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VNOR_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VNOR_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VNOR_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VNOR_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VNOR_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VNOR_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VNOR_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VNOR_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VNOR_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VNOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- }
-
- return TRUE;
-}
-#else
-#define RSP_VNOR(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- vres[E10] = ~(R_VREG_S(VS1REG, E10) | R_VREG_S(VS2REG, E20)); \
- vres[E11] = ~(R_VREG_S(VS1REG, E11) | R_VREG_S(VS2REG, E21)); \
- vres[E12] = ~(R_VREG_S(VS1REG, E12) | R_VREG_S(VS2REG, E22)); \
- vres[E13] = ~(R_VREG_S(VS1REG, E13) | R_VREG_S(VS2REG, E23)); \
- vres[E14] = ~(R_VREG_S(VS1REG, E14) | R_VREG_S(VS2REG, E24)); \
- vres[E15] = ~(R_VREG_S(VS1REG, E15) | R_VREG_S(VS2REG, E25)); \
- vres[E16] = ~(R_VREG_S(VS1REG, E16) | R_VREG_S(VS2REG, E26)); \
- vres[E17] = ~(R_VREG_S(VS1REG, E17) | R_VREG_S(VS2REG, E27)); \
- W_ACCUM_L(E10, vres[E10]); \
- W_ACCUM_L(E11, vres[E11]); \
- W_ACCUM_L(E12, vres[E12]); \
- W_ACCUM_L(E13, vres[E13]); \
- W_ACCUM_L(E14, vres[E14]); \
- W_ACCUM_L(E15, vres[E15]); \
- W_ACCUM_L(E16, vres[E16]); \
- W_ACCUM_L(E17, vres[E17]); \
INLINE void cfunc_rsp_vnor(void *param)
{
@@ -6308,205 +2980,15 @@ INLINE void cfunc_rsp_vnor(void *param)
//
// Bitwise NOT OR of two vector registers
- switch(EL)
+ int sel;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VNOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VNOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VNOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VNOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VNOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VNOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VNOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VNOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VNOR(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VNOR(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10:/* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VNOR(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11:/* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VNOR(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12:/* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VNOR(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13:/* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VNOR(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14:/* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VNOR(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15:/* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VNOR(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
+ sel = VEC_EL_2(EL, i);
+ vres[i] = ~((VREG_S(VS1REG, i) | VREG_S(VS2REG, sel)));
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
}
-#endif
-
-#if (DRC_VXOR)
-#define RSP_VXOR_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vxor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
- // ------------------------------------------------------
- //
- // Bitwise XOR of two vector registers
-
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VXOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VXOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VXOR_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VXOR_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VXOR_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VXOR_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VXOR_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VXOR_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VXOR_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VXOR_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VXOR_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VXOR_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VXOR_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VXOR_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VXOR_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VXOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- }
-
- return TRUE;
-}
-#else
-#define RSP_VXOR(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- vres[E10] = R_VREG_S(VS1REG, E10) ^ R_VREG_S(VS2REG, E20); \
- vres[E11] = R_VREG_S(VS1REG, E11) ^ R_VREG_S(VS2REG, E21); \
- vres[E12] = R_VREG_S(VS1REG, E12) ^ R_VREG_S(VS2REG, E22); \
- vres[E13] = R_VREG_S(VS1REG, E13) ^ R_VREG_S(VS2REG, E23); \
- vres[E14] = R_VREG_S(VS1REG, E14) ^ R_VREG_S(VS2REG, E24); \
- vres[E15] = R_VREG_S(VS1REG, E15) ^ R_VREG_S(VS2REG, E25); \
- vres[E16] = R_VREG_S(VS1REG, E16) ^ R_VREG_S(VS2REG, E26); \
- vres[E17] = R_VREG_S(VS1REG, E17) ^ R_VREG_S(VS2REG, E27); \
- W_ACCUM_L(E10, vres[E10]); \
- W_ACCUM_L(E11, vres[E11]); \
- W_ACCUM_L(E12, vres[E12]); \
- W_ACCUM_L(E13, vres[E13]); \
- W_ACCUM_L(E14, vres[E14]); \
- W_ACCUM_L(E15, vres[E15]); \
- W_ACCUM_L(E16, vres[E16]); \
- W_ACCUM_L(E17, vres[E17]); \
INLINE void cfunc_rsp_vxor(void *param)
{
@@ -6520,213 +3002,15 @@ INLINE void cfunc_rsp_vxor(void *param)
//
// Bitwise XOR of two vector registers
- switch(EL)
+ int sel;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VXOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VXOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VXOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VXOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VXOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VXOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VXOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VXOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VXOR(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VXOR(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10:/* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VXOR(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11:/* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VXOR(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12:/* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VXOR(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13:/* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VXOR(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14:/* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VXOR(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15:/* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VXOR(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
+ sel = VEC_EL_2(EL, i);
+ vres[i] = VREG_S(VS1REG, i) ^ VREG_S(VS2REG, sel);
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
}
-#endif
-
-#if (DRC_VNXOR)
-#define RSP_VNXOR_DRC(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27, I0, I1, I2, I3, I4, I5, I6, I7) \
- { \
- UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
- UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
- UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
- UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
- UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
- \
- UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
- UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
- UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
- }
-
-static int generate_vnxor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
-{
- UINT32 op = desc->opptr.l[0];
-
- // 31 25 24 20 15 10 5 0
- // ------------------------------------------------------
- // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
- // ------------------------------------------------------
- //
- // Bitwise NOT XOR of two vector registers
-
- switch(EL)
- {
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VNXOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VNXOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VNXOR_DRC(1, 3, 5, 7, 0, 2, 4, 6, 7, 5, 3, 1, 7, 5, 3, 1, 6, 4, 2, 0, 7, 5, 3, 1);
- return TRUE;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VNXOR_DRC(0, 2, 4, 6, 1, 3, 5, 7, 6, 4, 2, 0, 6, 4, 2, 0, 7, 5, 3, 1, 6, 4, 2, 0);
- return TRUE;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VNXOR_DRC(1, 2, 3, 5, 6, 7, 0, 4, 7, 7, 7, 3, 3, 3, 7, 3, 6, 5, 4, 2, 1, 0, 7, 3);
- return TRUE;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VNXOR_DRC(0, 2, 3, 4, 6, 7, 1, 5, 6, 6, 6, 2, 2, 2, 6, 2, 7, 5, 4, 3, 1, 0, 6, 2);
- return TRUE;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VNXOR_DRC(0, 1, 3, 4, 5, 7, 2, 6, 5, 5, 5, 1, 1, 1, 5, 1, 7, 6, 4, 3, 2, 0, 5, 1);
- return TRUE;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VNXOR_DRC(0, 1, 2, 4, 5, 6, 3, 7, 4, 4, 4, 0, 0, 0, 4, 0, 7, 6, 5, 3, 2, 1, 4, 0);
- return TRUE;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VNXOR_DRC(1, 2, 3, 4, 5, 6, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 2, 1, 0, 7);
- return TRUE;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VNXOR_DRC(0, 2, 3, 4, 5, 6, 7, 1, 6, 6, 6, 6, 6, 6, 6, 6, 7, 5, 4, 3, 2, 1, 0, 6);
- return TRUE;
- case 10: /* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VNXOR_DRC(0, 1, 3, 4, 5, 6, 7, 2, 5, 5, 5, 5, 5, 5, 5, 5, 7, 6, 4, 3, 2, 1, 0, 5);
- return TRUE;
- case 11: /* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VNXOR_DRC(0, 1, 2, 4, 5, 6, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 6, 5, 3, 2, 1, 0, 4);
- return TRUE;
- case 12: /* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VNXOR_DRC(0, 1, 2, 3, 5, 6, 7, 4, 3, 3, 3, 3, 3, 3, 3, 3, 7, 6, 5, 4, 2, 1, 0, 3);
- return TRUE;
- case 13: /* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VNXOR_DRC(0, 1, 2, 3, 4, 6, 7, 5, 2, 2, 2, 2, 2, 2, 2, 2, 7, 6, 5, 4, 3, 1, 0, 2);
- return TRUE;
- case 14: /* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VNXOR_DRC(0, 1, 2, 3, 4, 5, 7, 6, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 5, 4, 3, 2, 0, 1);
- return TRUE;
- case 15: /* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VNOR_DRC(0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 7, 6, 5, 4, 3, 2, 1, 0);
- return TRUE;
- }
-
- return TRUE;
-}
-#else
-#define RSP_VNXOR(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
- vres[E10] = ~(R_VREG_S(VS1REG, E10) ^ R_VREG_S(VS2REG, E20)); \
- vres[E11] = ~(R_VREG_S(VS1REG, E11) ^ R_VREG_S(VS2REG, E21)); \
- vres[E12] = ~(R_VREG_S(VS1REG, E12) ^ R_VREG_S(VS2REG, E22)); \
- vres[E13] = ~(R_VREG_S(VS1REG, E13) ^ R_VREG_S(VS2REG, E23)); \
- vres[E14] = ~(R_VREG_S(VS1REG, E14) ^ R_VREG_S(VS2REG, E24)); \
- vres[E15] = ~(R_VREG_S(VS1REG, E15) ^ R_VREG_S(VS2REG, E25)); \
- vres[E16] = ~(R_VREG_S(VS1REG, E16) ^ R_VREG_S(VS2REG, E26)); \
- vres[E17] = ~(R_VREG_S(VS1REG, E17) ^ R_VREG_S(VS2REG, E27)); \
- W_ACCUM_L(E10, vres[E10]); \
- W_ACCUM_L(E11, vres[E11]); \
- W_ACCUM_L(E12, vres[E12]); \
- W_ACCUM_L(E13, vres[E13]); \
- W_ACCUM_L(E14, vres[E14]); \
- W_ACCUM_L(E15, vres[E15]); \
- W_ACCUM_L(E16, vres[E16]); \
- W_ACCUM_L(E17, vres[E17]); \
INLINE void cfunc_rsp_vnxor(void *param)
{
@@ -6740,60 +3024,15 @@ INLINE void cfunc_rsp_vnxor(void *param)
//
// Bitwise NOT XOR of two vector registers
- switch(EL)
+ int sel;
+ for (int i = 0; i < 8; i++)
{
- case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */ /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
- RSP_VNXOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */ /* 0, 1, 2, 3, 4, 5, 6, 7 - ??? */
- RSP_VNXOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
- break;
- case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q */ /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q */
- RSP_VNXOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
- break;
- case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q */ /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q */
- RSP_VNXOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
- break;
- case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h */ /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h */
- RSP_VNXOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
- break;
- case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h */ /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h */
- RSP_VNXOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
- break;
- case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h */ /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h */
- RSP_VNXOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
- break;
- case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h */ /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h */
- RSP_VNXOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
- break;
- case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0 */ /* 0, 0, 0, 0, 0, 0, 0, 0 - 0 */
- RSP_VNXOR(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- break;
- case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1 */ /* 1, 1, 1, 1, 1, 1, 1, 1 - 0 */
- RSP_VNXOR(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
- break;
- case 10:/* 0, 1, 3, 4, 5, 6, 7, 2 - 2 */ /* 2, 2, 2, 2, 2, 2, 2, 2 - 0 */
- RSP_VNXOR(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
- break;
- case 11:/* 0, 1, 2, 4, 5, 6, 7, 3 - 3 */ /* 3, 3, 3, 3, 3, 3, 3, 3 - 0 */
- RSP_VNXOR(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
- break;
- case 12:/* 0, 1, 2, 3, 5, 6, 7, 4 - 4 */ /* 4, 4, 4, 4, 4, 4, 4, 4 - 0 */
- RSP_VNXOR(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
- break;
- case 13:/* 0, 1, 2, 3, 4, 6, 7, 5 - 5 */ /* 5, 5, 5, 5, 5, 5, 5, 5 - 0 */
- RSP_VNXOR(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
- break;
- case 14:/* 0, 1, 2, 3, 4, 5, 7, 6 - 6 */ /* 6, 6, 6, 6, 6, 6, 6, 6 - 0 */
- RSP_VNXOR(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
- break;
- case 15:/* 0, 1, 2, 3, 4, 5, 6, 7 - 7 */ /* 7, 7, 7, 7, 7, 7, 7, 7 - 0 */
- RSP_VNXOR(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
- break;
+ sel = VEC_EL_2(EL, i);
+ vres[i] = ~((VREG_S(VS1REG, i) ^ VREG_S(VS2REG, sel)));
+ ACCUM_L(i) = vres[i];
}
WRITEBACK_RESULT();
}
-#endif
INLINE void cfunc_rsp_vrcp(void *param)
{
@@ -6807,84 +3046,55 @@ INLINE void cfunc_rsp_vrcp(void *param)
//
// Calculates reciprocal
- int del = 7 - (VS1REG & 7);
- int sel = 7 - (EL & 7);
- INT32 rec;
-
- rec = (INT16)(R_VREG_S_X(VS2REG, sel));
+ int del = VS1REG & 7;
+ int sel = EL & 7;
+ INT32 shifter = 0;
- if (rec == 0)
- {
- // divide by zero -> overflow
- rec = 0x7fffffff;
- }
- else
+ INT32 rec = (INT16)(VREG_S(VS2REG, sel));
+ INT32 datainput = (rec < 0) ? (-rec) : rec;
+ if (datainput)
{
- int sign = 0;
- int exp = 0;
- int mantissa = 0;
-
- if (rec < 0)
+ for (i = 0; i < 32; i++)
{
- rec = -rec; // rec = MINUS rec
- sign = 1;
- }
-
- // restrict to 10-bit mantissa
- for (i = 15; i >= 0; i--)
- {
- if (rec & (1 << i))
+ if (datainput & (1 << ((~i) & 0x1f)))//ò.æ.÷òî 31 - i
{
- exp = i;
- mantissa = (rec << (15 - i)) >> 6;
+ shifter = i;
break;
}
}
-
- if (mantissa == 0x200)
- {
- rec = 0x7fffffff;
- }
- else
- {
- rec = 0xffffffffU / mantissa;
-
- //
- // simulate rounding error
- //
- // This has been verified on the real hardware.
- //
- // I was able to replicate this exact behaviour by using a five-round
- // Newton reciprocal method using floorf() on intermediate results
- // to force the use of IEEE 754 32bit floats.
- // However, for the sake of portability, we'll use integer arithmetic.
- //
- if (rec & 0x800)
- rec += 1;
-
- rec <<= 8;
- }
-
- // restrict result to 17 significant bits
- rec &= 0x7fffc000;
-
- rec >>= exp;
-
- if (sign)
- {
- rec = ~rec; // rec = BITWISE NOT rec
- }
+ }
+ else
+ {
+ shifter = 0x10;
}
- for (i=0; i < 8; i++)
+ INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
+ INT32 fetchval = rsp_divtable[address];
+ INT32 temp = (0x40000000 | (fetchval << 14)) >> ((~shifter) & 0x1f);
+ if (rec < 0)
{
- int element = VEC_EL_2(EL, i);
- W_ACCUM_L(i, R_VREG_S_X(VS2REG, element));
+ temp = ~temp;
}
+ if (!rec)
+ {
+ temp = 0x7fffffff;
+ }
+ else if (rec == 0xffff8000)
+ {
+ temp = 0xffff0000;
+ }
+ rec = temp;
rsp->reciprocal_res = rec;
+ rsp->dp_allowed = 0;
- W_VREG_S_X(VDREG, del, (UINT16)(rsp->reciprocal_res)); // store low part
+ VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
+
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
}
INLINE void cfunc_rsp_vrcpl(void *param)
@@ -6899,64 +3109,84 @@ INLINE void cfunc_rsp_vrcpl(void *param)
//
// Calculates reciprocal low part
- int del = 7 - (VS1REG & 7);
- int sel = 7 - VEC_EL_2(EL, 7-del);
- INT32 rec;
+ int del = VS1REG & 7;
+ int sel = EL & 7;
+ INT32 shifter = 0;
- rec = ((UINT16)(R_VREG_S_X(VS2REG, sel)) | ((UINT32)(rsp->reciprocal_high) << 16));
+ INT32 rec = ((UINT16)(VREG_S(VS2REG, sel)) | ((UINT32)(rsp->reciprocal_high) & 0xffff0000));
- if (rec == 0)
- {
- // divide by zero -> overflow
- rec = 0x7fffffff;
- }
- else
+ INT32 datainput = rec;
+
+ if (rec < 0)
{
- int negative = 0;
- if (rec < 0)
+ if (rsp->dp_allowed)
{
- if (((UINT32)(rec & 0xffff0000) == 0xffff0000) && ((INT16)(rec & 0xffff) < 0))
+ if (rec < -32768)
{
- rec = ~rec+1;
+ datainput = ~datainput;
}
else
{
- rec = ~rec;
+ datainput = -datainput;
}
- negative = 1;
}
- for (i = 31; i > 0; i--)
+ else
{
- if (rec & (1 << i))
- {
- rec &= ((0xffc00000) >> (31 - i));
- i = 0;
- }
+ datainput = -datainput;
}
- rec = (0x7fffffff / rec);
- for (i = 31; i > 0; i--)
+ }
+
+
+ if (datainput)
+ {
+ for (i = 0; i < 32; i++)
{
- if (rec & (1 << i))
+ if (datainput & (1 << ((~i) & 0x1f)))//ò.æ.÷òî 31 - i
{
- rec &= ((0xffff8000) >> (31 - i));
- i = 0;
+ shifter = i;
+ break;
}
}
- if (negative)
+ }
+ else
+ {
+ if (rsp->dp_allowed)
{
- rec = ~rec;
+ shifter = 0;
+ }
+ else
+ {
+ shifter = 0x10;
}
}
- for (i=0; i < 8; i++)
+ INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
+ INT32 fetchval = rsp_divtable[address];
+ INT32 temp = (0x40000000 | (fetchval << 14)) >> ((~shifter) & 0x1f);
+ if (rec < 0)
+ {
+ temp = ~temp;
+ }
+ if (!rec)
+ {
+ temp = 0x7fffffff;
+ }
+ else if (rec == 0xffff8000)
{
- int element = VEC_EL_2(EL, i);
- W_ACCUM_L(i, R_VREG_S_X(VS2REG, element));
+ temp = 0xffff0000;
}
+ rec = temp;
rsp->reciprocal_res = rec;
+ rsp->dp_allowed = 0;
- W_VREG_S_X(VDREG, del, (UINT16)(rsp->reciprocal_res)); // store low part
+ VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
+
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
}
INLINE void cfunc_rsp_vrcph(void *param)
@@ -6970,21 +3200,19 @@ INLINE void cfunc_rsp_vrcph(void *param)
//
// Calculates reciprocal high part
- int del = 7 - (VS1REG & 7);
- int sel = 7 - VEC_EL_2(EL, 7-del);
+ int del = VS1REG & 7;
+ int sel = EL & 7;
- rsp->reciprocal_high = R_VREG_S_X(VS2REG, sel);
+ rsp->reciprocal_high = (VREG_S(VS2REG, sel)) << 16;
+ rsp->dp_allowed = 1;
- W_ACCUM_L(0, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 0)));
- W_ACCUM_L(1, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 1)));
- W_ACCUM_L(2, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 2)));
- W_ACCUM_L(3, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 3)));
- W_ACCUM_L(4, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 4)));
- W_ACCUM_L(5, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 5)));
- W_ACCUM_L(6, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 6)));
- W_ACCUM_L(7, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 7)));
+ for (int i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
- W_VREG_S_X(VDREG, del, (INT16)(rsp->reciprocal_res >> 16)); // store high part
+ VREG_S(VDREG, del) = (INT16)(rsp->reciprocal_res >> 16);
}
INLINE void cfunc_rsp_vmov(void *param)
@@ -6998,8 +3226,15 @@ INLINE void cfunc_rsp_vmov(void *param)
//
// Moves element from vector to destination vector
- int element = 7 - (VS1REG & 7);
- W_VREG_S_X(VDREG, element, R_VREG_S_X(VS2REG, 7 - VEC_EL_2(EL, element)));
+ int del = VS1REG & 7;
+ int sel = EL & 7;
+
+ VREG_S(VDREG, del) = VREG_S(VS2REG, sel);
+ for (int i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
}
INLINE void cfunc_rsp_vrsql(void *param)
@@ -7014,72 +3249,57 @@ INLINE void cfunc_rsp_vrsql(void *param)
//
// Calculates reciprocal square-root low part
- int del = 7 - (VS1REG & 7);
- int sel = 7 - VEC_EL_2(EL, 7 - del);
- INT32 sqr;
+ int del = VS1REG & 7;
+ int sel = EL & 7;
+ INT32 shifter = 0;
+
+ INT32 rec = (INT16)(VREG_S(VS2REG, sel));
+ INT32 datainput = (rec < 0) ? (-rec) : rec;
+ if (datainput)
+ {
+ for (i = 0; i < 32; i++)
+ {
+ if (datainput & (1 << ((~i) & 0x1f)))//ò.æ.÷òî 31 - i
+ {
+ shifter = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ shifter = 0x10;
+ }
- sqr = (UINT16)(R_VREG_S_X(VS2REG, sel)) | ((UINT32)(rsp->square_root_high) << 16);
+ INT32 address = ((datainput << shifter) & 0x7fc00000) >> 22;
+ address = ((address | 0x200) & 0x3fe) | (shifter & 1);
- if (sqr == 0)
+ INT32 fetchval = rsp_divtable[address];
+ INT32 temp = (0x40000000 | (fetchval << 14)) >> (((~shifter) & 0x1f) >> 1);
+ if (rec < 0)
{
- // square root on 0 -> overflow
- sqr = 0x7fffffff;
+ temp = ~temp;
}
- else if (sqr == 0xffff8000)
+ if (!rec)
{
- // overflow ?
- sqr = 0xffff8000;
+ temp = 0x7fffffff;
}
- else
+ else if (rec == 0xffff8000)
{
- int negative = 0;
- if (sqr < 0)
- {
- if (((UINT32)(sqr & 0xffff0000) == 0xffff0000) && ((INT16)(sqr & 0xffff) < 0))
- {
- sqr = ~sqr+1;
- }
- else
- {
- sqr = ~sqr;
- }
- negative = 1;
- }
- for (i = 31; i > 0; i--)
- {
- if (sqr & (1 << i))
- {
- sqr &= (0xff800000 >> (31 - i));
- i = 0;
- }
- }
- sqr = (INT32)(0x7fffffff / sqrt((double)sqr));
- for (i = 31; i > 0; i--)
- {
- if (sqr & (1 << i))
- {
- sqr &= (0xffff8000 >> (31 - i));
- i = 0;
- }
- }
- if (negative)
- {
- sqr = ~sqr;
- }
+ temp = 0xffff0000;
}
+ rec = temp;
- W_ACCUM_L(0, R_VREG_S(VS2REG, VEC_EL_2(EL, 0)));
- W_ACCUM_L(1, R_VREG_S(VS2REG, VEC_EL_2(EL, 1)));
- W_ACCUM_L(2, R_VREG_S(VS2REG, VEC_EL_2(EL, 2)));
- W_ACCUM_L(3, R_VREG_S(VS2REG, VEC_EL_2(EL, 3)));
- W_ACCUM_L(4, R_VREG_S(VS2REG, VEC_EL_2(EL, 4)));
- W_ACCUM_L(5, R_VREG_S(VS2REG, VEC_EL_2(EL, 5)));
- W_ACCUM_L(6, R_VREG_S(VS2REG, VEC_EL_2(EL, 6)));
- W_ACCUM_L(7, R_VREG_S(VS2REG, VEC_EL_2(EL, 7)));
+ rsp->reciprocal_res = rec;
+ rsp->dp_allowed = 0;
- rsp->square_root_res = sqr;
+ VREG_S(VDREG, del) = (UINT16)(rec & 0xffff);
- W_VREG_S_X(VDREG, del, (UINT16)(rsp->square_root_res)); // store low part
+ for (i = 0; i < 8; i++)
+ {
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
+ }
}
INLINE void cfunc_rsp_vrsqh(void *param)
@@ -7094,19 +3314,21 @@ INLINE void cfunc_rsp_vrsqh(void *param)
//
// Calculates reciprocal square-root high part
- int del = (VS1REG & 7);
- int sel = VEC_EL_2(EL, del);
+ int del = VS1REG & 7;
+ int sel = EL & 7;
- rsp->square_root_high = R_VREG_S(VS2REG, sel);
+ rsp->reciprocal_high = (VREG_S(VS2REG, sel)) << 16;
+ rsp->dp_allowed = 1;
for (i=0; i < 8; i++)
{
- int element = VEC_EL_2(EL, i);
- W_ACCUM_L(i, R_VREG_S(VS2REG, element)); // perhaps accumulator is used to store the intermediate values ?
+ sel = VEC_EL_2(EL, i);
+ ACCUM_L(i) = VREG_S(VS2REG, sel);
}
- W_VREG_S(VDREG, del, (INT16)(rsp->square_root_res >> 16)); // store high part
+ VREG_S(VDREG, del) = (INT16)(rsp->reciprocal_res >> 16); // store high part
}
+
static void cfunc_sp_set_status_cb(void *param)
{
rsp_state *rsp = (rsp_state*)param;
@@ -7455,6 +3677,11 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
{
if (size == 1)
{
+ //UML_MOV(block, MEM(&rsp->impstate->arg0), IREG(0)); // mov [arg0],i0
+ //UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(1)); // mov [arg1],i1
+ //UML_MOV(block, MEM(&rsp->impstate->arg2), IMM(0)); // mov [arg2],0
+ //UML_MOV(block, MEM(&rsp->impstate->arg3), MEM(&rsp->pc)); // mov [arg3],pc
+ //UML_CALLC(block, cfunc_printf_debug, rsp); // callc cfunc_printf_debug
#ifdef LSB_FIRST
UML_XOR(block, IREG(0), IREG(0), IMM(3)); // xor i0,i0,3
#endif
@@ -7463,6 +3690,11 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
}
else if (size == 2)
{
+ //UML_MOV(block, MEM(&rsp->impstate->arg0), IREG(0)); // mov [arg0],i0
+ //UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(1)); // mov [arg1],i1
+ //UML_MOV(block, MEM(&rsp->impstate->arg2), IMM(1)); // mov [arg2],1
+ //UML_MOV(block, MEM(&rsp->impstate->arg3), MEM(&rsp->pc)); // mov [arg3],pc
+ //UML_CALLC(block, cfunc_printf_debug, rsp); // callc cfunc_printf_debug
#ifdef LSB_FIRST
UML_TEST(block, IREG(0), IMM(1)); // test i0,1
UML_JMPc(block, IF_NZ, unaligned_case); // jnz <unaligned_case>
@@ -7487,6 +3719,11 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
}
else if (size == 4)
{
+ //UML_MOV(block, MEM(&rsp->impstate->arg0), IREG(0)); // mov [arg0],i0
+ //UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(1)); // mov [arg1],i1
+ //UML_MOV(block, MEM(&rsp->impstate->arg2), IMM(2)); // mov [arg2],2
+ //UML_MOV(block, MEM(&rsp->impstate->arg3), MEM(&rsp->pc)); // mov [arg3],pc
+ //UML_CALLC(block, cfunc_printf_debug, rsp); // callc cfunc_printf_debug
#ifdef LSB_FIRST
UML_TEST(block, IREG(0), IMM(3)); // test i0,3
UML_JMPc(block, IF_NZ, unaligned_case); // jnz <unaligned_case>
@@ -7510,16 +3747,23 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
}
else
{
+ UML_MOV(block, MEM(&rsp->impstate->arg0), IREG(0)); // mov [arg0],i0
if (size == 1)
{
+ //UML_MOV(block, MEM(&rsp->impstate->arg2), IMM(3)); // mov [arg2],3
+ //UML_MOV(block, MEM(&rsp->impstate->arg3), MEM(&rsp->pc)); // mov [arg3],pc
#ifdef LSB_FIRST
UML_XOR(block, IREG(0), IREG(0), IMM(3)); // xor i0,i0,3
#endif
UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE); // load i0,dmem,i0,byte
+ //UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(0)); // mov [arg1],i0
+ //UML_CALLC(block, cfunc_printf_debug, rsp); // callc cfunc_printf_debug
}
else if (size == 2)
{
+ //UML_MOV(block, MEM(&rsp->impstate->arg2), IMM(4)); // mov [arg2],4
+ //UML_MOV(block, MEM(&rsp->impstate->arg3), MEM(&rsp->pc)); // mov [arg3],pc
#ifdef LSB_FIRST
UML_TEST(block, IREG(0), IMM(1)); // test i0,1
UML_JMPc(block, IF_NZ, unaligned_case); // jnz <unaligned_case>
@@ -7527,6 +3771,8 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
#endif
UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), WORD_x1); // load i0,dmem,i0,word_x1
+ //UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(0)); // mov [arg1],i0
+ //UML_CALLC(block, cfunc_printf_debug, rsp); // callc cfunc_printf_debug
UML_RET(block);
#ifdef LSB_FIRST
UML_LABEL(block, unaligned_case); // unaligned_case:
@@ -7537,15 +3783,21 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
UML_ADD(block, IREG(1), IREG(1), IMM(48)); // add i1,i1,48
UML_DROLAND(block, IREG(0), IREG(0), IREG(1), IMM(0xffff)); // droland i0,i0,i1,0xffff
#endif
+ //UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(0)); // mov [arg1],i0
+ //UML_CALLC(block, cfunc_printf_debug, rsp); // callc cfunc_printf_debug
}
else if (size == 4)
{
+ //UML_MOV(block, MEM(&rsp->impstate->arg2), IMM(5)); // mov [arg2],5
+ //UML_MOV(block, MEM(&rsp->impstate->arg3), MEM(&rsp->pc)); // mov [arg3],pc
#ifdef LSB_FIRST
UML_TEST(block, IREG(0), IMM(3)); // test i0,3
UML_JMPc(block, IF_NZ, unaligned_case); // jnz <unaligned_case>
#endif
UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff)); // and i0,i0,0xfff
UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), DWORD_x1); // load i0,dmem,i0,dword_x1
+ //UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(0)); // mov [arg1],i0
+ //UML_CALLC(block, cfunc_printf_debug, rsp); // callc cfunc_printf_debug
UML_RET(block);
#ifdef LSB_FIRST
UML_LABEL(block, unaligned_case); // unaligned_case:
@@ -7555,6 +3807,8 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit
UML_DLOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), QWORD_x1); // dload i0,dmem,i0,qword_x1
UML_DROL(block, IREG(0), IREG(0), IREG(1)); // drol i0,i0,i1
#endif
+ //UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(0)); // mov [arg1],i0
+ //UML_CALLC(block, cfunc_printf_debug, rsp); // callc cfunc_printf_debug
}
}
UML_RET(block);
@@ -7768,22 +4022,14 @@ static int generate_vector_opcode(rsp_state *rsp, drcuml_block *block, compiler_
return TRUE;
case 0x04: /* VMUDL */
-#if (DRC_VMUDL)
- return generate_vmudl(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vmudl, rsp);
return TRUE;
-#endif
case 0x05: /* VMUDM */
-#if (DRC_VMUDM)
- return generate_vmudm(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vmudm, rsp);
return TRUE;
-#endif
case 0x06: /* VMUDN */
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
@@ -7811,40 +4057,24 @@ static int generate_vector_opcode(rsp_state *rsp, drcuml_block *block, compiler_
return TRUE;
case 0x0d: /* VMADM */
-#if (DRC_VMADM)
- return generate_vmadm(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vmadm, rsp);
return TRUE;
-#endif
case 0x0e: /* VMADN */
-#if (DRC_VMADN)
- return generate_vmadn(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vmadn, rsp);
return TRUE;
-#endif
case 0x0f: /* VMADH */
-#if (DRC_VMADH)
- return generate_vmadh(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vmadh, rsp);
return TRUE;
-#endif
case 0x10: /* VADD */
-#if (DRC_VADD)
- return generate_vadd(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vadd, rsp);
return TRUE;
-#endif
case 0x11: /* VSUB */
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
@@ -7912,58 +4142,34 @@ static int generate_vector_opcode(rsp_state *rsp, drcuml_block *block, compiler_
return TRUE;
case 0x28: /* VAND */
-#if (DRC_VAND)
- return generate_vand(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vand, rsp);
return TRUE;
-#endif
case 0x29: /* VNAND */
-#if (DRC_VNAND)
- return generate_vnand(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vnand, rsp);
return TRUE;
-#endif
case 0x2a: /* VOR */
-#if (DRC_VOR)
- return generate_vor(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vor, rsp);
return TRUE;
-#endif
case 0x2b: /* VNOR */
-#if (DRC_VNOR)
- return generate_vnor(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vnor, rsp);
return TRUE;
-#endif
case 0x2c: /* VXOR */
-#if (DRC_VXOR)
- return generate_vxor(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vxor, rsp);
return TRUE;
-#endif
case 0x2d: /* VNXOR */
-#if (DRC_VNXOR)
- return generate_vnxor(rsp, block, compiler, desc);
-#else
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
UML_CALLC(block, cfunc_rsp_vnxor, rsp);
return TRUE;
-#endif
case 0x30: /* VRCP */
UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0])); // mov [arg0],desc->opptr.l
@@ -8490,8 +4696,8 @@ static void cfunc_mfc2(void *param)
rsp_state *rsp = (rsp_state*)param;
UINT32 op = rsp->impstate->arg0;
int el = (op >> 7) & 0xf;
- UINT16 b1 = R_VREG_B(VS1REG, (el+0) & 0xf);
- UINT16 b2 = R_VREG_B(VS1REG, (el+1) & 0xf);
+ UINT16 b1 = VREG_B(VS1REG, (el+0) & 0xf);
+ UINT16 b2 = VREG_B(VS1REG, (el+1) & 0xf);
if (RTREG) RTVAL = (INT32)(INT16)((b1 << 8) | (b2));
}
@@ -8519,8 +4725,8 @@ static void cfunc_mtc2(void *param)
rsp_state *rsp = (rsp_state*)param;
UINT32 op = rsp->impstate->arg0;
int el = (op >> 7) & 0xf;
- W_VREG_B(VS1REG, (el+0) & 0xf, (RTVAL >> 8) & 0xff);
- W_VREG_B(VS1REG, (el+1) & 0xf, (RTVAL >> 0) & 0xff);
+ VREG_B(VS1REG, (el+0) & 0xf) = (RTVAL >> 8) & 0xff;
+ VREG_B(VS1REG, (el+1) & 0xf) = (RTVAL >> 0) & 0xff;
}
static void cfunc_ctc2(void *param)