diff options
author | 2010-12-31 07:29:47 +0000 | |
---|---|---|
committer | 2010-12-31 07:29:47 +0000 | |
commit | 0ea11333c6ce2c62b5bf624e51aa1a446d08062f (patch) | |
tree | a4ce5e454965bddbf64cff6da8611b2c8df52069 /src/emu/cpu/rsp | |
parent | de94242bcc9479ef0230c776500ef2a9cd47769f (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.c | 1425 | ||||
-rw-r--r-- | src/emu/cpu/rsp/rsp.h | 54 | ||||
-rw-r--r-- | src/emu/cpu/rsp/rspdiv.h | 1027 | ||||
-rw-r--r-- | src/emu/cpu/rsp/rspdrc.c | 5808 |
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) |