Previous 15994 Revisions Next

r6795 Monday 28th December, 2009 at 02:39:56 UTC by Harmony
[N64] RSP DRC improvements: [Harmony]
- Added DRC versions of load ops LSV, LLV, LDV, LQV, LPV and LUV
- Added DRC versions of store ops SSV, SLV, SDV and SWV
- Added DRC versions of vector arithmetic / boolean ops VMUDL, VMUDM, VMADM, VMADN, VMADH, VAND, VNAND, VOR, VNOR, VXOR and VNXOR
- DRC versions of VMUDL, VMUDM, VMADM, VMADN, VMADH and VADD are disabled by default because they are slower than the interpreter versions.
- Unrolled and optimized interpreter versions of VMULF, VMUDL, VMUDM, VMUDN, VMACF, VMADM, VMADN, VMADH, VADD, VSAW*, VLT, VGE, VMRG, VAND, VNAND, VOR, VNOR, VXOR, and VNXOR
- Tweaked parameter ordering for LE targets to be slightly faster; BE is are TODO.
[src/emu/cpu/rsp]rsp.h rspdrc.c

src/emu/cpu/rsp/rsp.h
r6794r6795
11/***************************************************************************
22
3    mips3.h
3    rsp.h
44
55    Interface file for the universal machine language-based
66    Reality Signal Processor (RSP) emulator.
77
8    Copyright the MESS etam
8    Copyright the MESS team
99    Released for general non-commercial use under the MAME license
1010    Visit http://mamedev.org for licensing and usage restrictions.
1111
r6794r6795
164164         INT16 mid;
165165         INT16 high;
166166      } h;
167      struct
168      {
169         INT32 zl;
170         INT32 mh;
171      } w;
167172#else
168173      struct
169174      {
r6794r6795
172177         INT16 low;
173178         INT16 z;
174179      } h;
180      struct
181      {
182         INT32 mh;
183         INT32 zl;
184      } w;
175185#endif
176186   };
177187} ACCUMULATOR;
src/emu/cpu/rsp/rspdrc.c
r6794r6795
22
33    rspdrc.c
44
5    Universal machine language-based Nintendo/SGI RSP emulator.
6    Written by Harmony of the MESS team.
5   Universal machine language-based Nintendo/SGI RSP emulator.
6   Written by Harmony of the MESS team.
77
88    Copyright the MESS team.
99    Released for general non-commercial use under the MAME license
r6794r6795
4242#define DISABLE_FAST_REGISTERS         (0)
4343#define SINGLE_INSTRUCTION_MODE         (0)
4444
45#define DRC_LSV                     (1)
46#define DRC_LLV                     (1)
47#define DRC_LDV                     (1)
48#define DRC_LQV                     (1)
49#define DRC_LPV                     (1)
50#define DRC_LUV                     (1)
4551
52#define DRC_SSV                     (1)
53#define DRC_SLV                     (1)
54#define DRC_SDV                     (1)
55#define DRC_SQV                     (1)
4656
57#define DRC_VMUDL                  (0)
58#define DRC_VMUDM                  (0)
59#define DRC_VMADM                  (0)
60#define DRC_VMADN                  (0)
61#define DRC_VMADH                  (0)
62#define DRC_VADD                  (0)
63#define DRC_VAND                  (1)
64#define DRC_VNAND                  (1)
65#define DRC_VOR                     (1)
66#define DRC_VNOR                  (1)
67#define DRC_VXOR                  (1)
68#define DRC_VNXOR                  (1)
69
70
4771/***************************************************************************
4872    CONSTANTS
4973***************************************************************************/
r6794r6795
7498***************************************************************************/
7599
76100#define R32(reg)            rsp->impstate->regmap[reg].type, rsp->impstate->regmap[reg].value
101#define VB(reg, el)            rsp->impstate->regmap[16*reg+(15-el)+34].type, rsp->impstate->regmap[16*reg+(15-el)+34].value
102#define VS(reg, el)            rsp->impstate->regmap[8*reg+(7-el)+546].type, rsp->impstate->regmap[8*reg+(7-el)+546].value
103#define VSX(reg, el)         rsp->impstate->regmap[8*reg+el+546].type, rsp->impstate->regmap[8*reg+el+546].value
104#define VL(reg, el)            rsp->impstate->regmap[4*reg+(3-el)+802].type, rsp->impstate->regmap[4*reg+(3-el)+802].value
105#define VLX(reg, el)         rsp->impstate->regmap[4*reg+el+802].type, rsp->impstate->regmap[4*reg+el+802].value
106#define VFLAG(reg)            rsp->impstate->regmap[930+reg].type, rsp->impstate->regmap[930+reg].value
107#define VACCUML(reg)         rsp->impstate->regmap[934+reg].type, rsp->impstate->regmap[934+reg].value
108#define VACCUMHH(reg)         rsp->impstate->regmap[942+reg].type, rsp->impstate->regmap[942+reg].value
109#define VACCUMHM(reg)         rsp->impstate->regmap[950+reg].type, rsp->impstate->regmap[950+reg].value
110#define VACCUMHL(reg)         rsp->impstate->regmap[958+reg].type, rsp->impstate->regmap[958+reg].value
111#define VACCUMHZ(reg)         rsp->impstate->regmap[966+reg].type, rsp->impstate->regmap[966+reg].value
112#define VACCUMWMH(reg)         rsp->impstate->regmap[974+reg].type, rsp->impstate->regmap[974+reg].value
113#define VACCUMWZL(reg)         rsp->impstate->regmap[982+reg].type, rsp->impstate->regmap[982+reg].value
114#define VRES(reg)            rsp->impstate->regmap[990+reg].type, rsp->impstate->regmap[990+reg].value
77115
78116
79117
r6794r6795
119157   const char *      format;                  /* format string for print_debug */
120158   UINT32            arg0;                  /* print_debug argument 1 */
121159   UINT32            arg1;                  /* print_debug argument 2 */
160   UINT64            arg64;                  /* print_debug 64-bit argument */
161   UINT32            vres[8];               /* used for temporary vector results */
122162
123163   /* register mappings */
124   drcuml_parameter   regmap[34];               /* parameter to register mappings for all 32 integer registers */
164   drcuml_parameter   regmap[998];            /* parameter to register mappings for all 32 integer registers, vector registers, flags, accumulators and temps */
125165
126166   /* subroutines */
127167   drcuml_codehandle *   entry;                  /* entry point */
r6794r6795
153193static void cfunc_cfc2(void *param);
154194static void cfunc_mtc2(void *param);
155195static void cfunc_ctc2(void *param);
156static void cfunc_swc2(void *param);
157static void cfunc_lwc2(void *param);
158static void cfunc_handle_vector_ops(void *param);
196//static void cfunc_swc2(void *param);
197//static void cfunc_lwc2(void *param);
159198static void cfunc_sp_set_status_cb(void *param);
160199
200static void cfunc_rsp_lbv(void *param);
201#if !(DRC_LSV)
202static void cfunc_rsp_lsv(void *param);
203#endif
204#if !(DRC_LLV)
205static void cfunc_rsp_llv(void *param);
206#endif
207#if !(DRC_LDV)
208static void cfunc_rsp_ldv(void *param);
209#endif
210#if !(DRC_LQV)
211static void cfunc_rsp_lqv(void *param);
212#endif
213static void cfunc_rsp_lrv(void *param);
214#if !(DRC_LPV)
215static void cfunc_rsp_lpv(void *param);
216#endif
217#if !(DRC_LUV)
218static void cfunc_rsp_luv(void *param);
219#endif
220static void cfunc_rsp_lhv(void *param);
221static void cfunc_rsp_lfv(void *param);
222static void cfunc_rsp_lwv(void *param);
223static void cfunc_rsp_ltv(void *param);
224
225static void cfunc_rsp_sbv(void *param);
226#if !(DRC_SSV)
227static void cfunc_rsp_ssv(void *param);
228#endif
229#if !(DRC_SLV)
230static void cfunc_rsp_slv(void *param);
231#endif
232#if !(DRC_SDV)
233static void cfunc_rsp_sdv(void *param);
234#endif
235#if !(DRC_SQV)
236static void cfunc_rsp_sqv(void *param);
237#endif
238static void cfunc_rsp_srv(void *param);
239static void cfunc_rsp_spv(void *param);
240static void cfunc_rsp_suv(void *param);
241static void cfunc_rsp_shv(void *param);
242static void cfunc_rsp_sfv(void *param);
243static void cfunc_rsp_swv(void *param);
244static void cfunc_rsp_stv(void *param);
245
161246static void static_generate_entry_point(rsp_state *rsp);
162247static void static_generate_nocode_handler(rsp_state *rsp);
163248static void static_generate_out_of_cycles(rsp_state *rsp);
164249static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrite, const char *name, drcuml_codehandle **handleptr);
165250
251#if (DRC_VMADN)
252static void generate_saturate_accum_unsigned(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int accum);
253#endif
254#if (DRC_VMADH) || (DRC_VMADM)
255static void generate_saturate_accum_signed(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int accum);
256#endif
257#if (DRC_VMUDL)
258static int generate_vmudl(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vmudl
259#endif
260#if (DRC_VMADM)
261static int generate_vmadm(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vmadm
262#endif
263#if (DRC_VMADN)
264static int generate_vmadn(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vmadn
265#endif
266#if (DRC_VMADH)
267static int generate_vmadh(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vmadh
268#endif
269#if (DRC_VADD)
270static int generate_vadd(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vadd
271#endif
272#if (DRC_VAND)
273static int generate_vand(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vand
274#endif
275#if (DRC_VNAND)
276static int generate_vnand(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vand
277#endif
278#if (DRC_VOR)
279static int generate_vor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vand
280#endif
281#if (DRC_VNOR)
282static int generate_vnor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vand
283#endif
284#if (DRC_VXOR)
285static int generate_vxor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vand
286#endif
287#if (DRC_VNXOR)
288static int generate_vnxor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);   // vand
289#endif
290static int generate_lwc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
291static int generate_swc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
166292static void generate_update_cycles(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception);
167293static void generate_checksum_block(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast);
168294static void generate_sequence_instruction(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
r6794r6795
186312
187313#define R_VREG_B(reg, offset)      rsp->v[(reg)].b[15 - (offset)]
188314#define R_VREG_S(reg, offset)      (INT16)rsp->v[(reg)].s[7 - (offset)]
315#define R_VREG_S_X(reg, offset)      (INT16)rsp->v[reg].s[offset]
189316#define R_VREG_L(reg, offset)      rsp->v[(reg)].l[3 - (offset)]
190317#define R_VREG_D(reg, offset)      rsp->v[(reg)].d[1 - (offset)]
191318
192319#define W_VREG_B(reg, offset, val)   (rsp->v[(reg)].b[15 - (offset)] = val)
193320#define W_VREG_S(reg, offset, val)   (rsp->v[(reg)].s[7 - (offset)] = val)
321#define W_VREG_S_X(reg, offset, val) (rsp->v[reg].s[offset] = val)
194322#define W_VREG_L(reg, offset, val)   (rsp->v[(reg)].l[3 - (offset)] = val)
195323#define W_VREG_D(reg, offset, val)   (rsp->v[(reg)].d[1 - (offset)] = val)
196324
r6794r6795
418546    debugging
419547-------------------------------------------------*/
420548
421#ifndef LSB_FIRST
422549static void cfunc_printf_debug(void *param)
423550{
424551   rsp_state *rsp = (rsp_state *)param;
425552   printf(rsp->impstate->format, rsp->impstate->arg0, rsp->impstate->arg1);
426553   logerror(rsp->impstate->format, rsp->impstate->arg0, rsp->impstate->arg1);
427554}
428#endif
429555
430556
557/*-------------------------------------------------
558    cfunc_printf_debug64 - generic printf for
559    debugging 64-bit values
560-------------------------------------------------*/
561
562//static void cfunc_printf_debug64(void *param)
563//{
564//   rsp_state *rsp = (rsp_state *)param;
565//   printf(rsp->impstate->format, (UINT32)(rsp->impstate->arg64 >> 32), (UINT32)(rsp->impstate->arg64 & 0x00000000ffffffff));
566//   logerror(rsp->impstate->format, (UINT32)(rsp->impstate->arg64 >> 32), (UINT32)(rsp->impstate->arg64 & 0x00000000ffffffff));
567//}
568
569
431570static void cfunc_get_cop0_reg(void *param)
432571{
433572   rsp_state *rsp = (rsp_state*)param;
r6794r6795
474613   }
475614}
476615
616static void cfunc_unimplemented_opcode(void *param)
617{
618   rsp_state *rsp = (rsp_state*)param;
619   int op = rsp->impstate->arg0;
620   if ((rsp->device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
621   {
622      char string[200];
623      rsp_dasm_one(string, rsp->ppc, op);
624      mame_printf_debug("%08X: %s\n", rsp->ppc, string);
625   }
626
627   fatalerror("RSP: unknown opcode %02X (%08X) at %08X\n", op >> 26, op, rsp->ppc);
628}
629
477630static void unimplemented_opcode(rsp_state *rsp, UINT32 op)
478631{
479632   if ((rsp->device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
r6794r6795
583736   drccache *cache;
584737   UINT32 flags = 0;
585738   int regnum;
739   int elnum;
586740
587741   /* allocate enough space for the cache and the core */
588742   cache = (drccache *)drccache_alloc(CACHE_SIZE + sizeof(*rsp));
r6794r6795
632786   }
633787   drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg0, sizeof(rsp->impstate->arg0), "arg0");
634788   drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg1, sizeof(rsp->impstate->arg1), "arg1");
789   drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg64, sizeof(rsp->impstate->arg1), "arg64");
635790   drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->numcycles, sizeof(rsp->impstate->numcycles), "numcycles");
636791
637792   /* initialize the front-end helper */
r6794r6795
647802      rsp->impstate->regmap[regnum].type = (regnum == 0) ? DRCUML_PTYPE_IMMEDIATE : DRCUML_PTYPE_MEMORY;
648803      rsp->impstate->regmap[regnum].value = (regnum == 0) ? 0 : (FPTR)&rsp->r[regnum];
649804   }
805   for (regnum = 0; regnum < 32; regnum++)
806   {
807      for(elnum = 0; elnum < 16; elnum++)
808      {
809         rsp->impstate->regmap[16*regnum+elnum+34].type = DRCUML_PTYPE_MEMORY;
810         rsp->impstate->regmap[16*regnum+elnum+34].value = (FPTR)&rsp->v[regnum].b[15-elnum];
811      }
812      for(elnum = 0; elnum < 8; elnum++)
813      {
814         rsp->impstate->regmap[8*regnum+elnum+546].type = DRCUML_PTYPE_MEMORY;
815         rsp->impstate->regmap[8*regnum+elnum+546].value = (FPTR)&rsp->v[regnum].s[7-elnum];
816      }
817      for(elnum = 0; elnum < 4; elnum++)
818      {
819         rsp->impstate->regmap[4*regnum+elnum+802].type = DRCUML_PTYPE_MEMORY;
820         rsp->impstate->regmap[4*regnum+elnum+802].value = (FPTR)&rsp->v[regnum].l[3-elnum];
821      }
822   }
823   for (regnum = 0; regnum < 4; regnum++)
824   {
825      rsp->impstate->regmap[930+regnum].type = DRCUML_PTYPE_MEMORY;
826      rsp->impstate->regmap[930+regnum].value = (FPTR)&rsp->flag[regnum];
827   }
828   for (regnum = 0; regnum < 8; regnum++)
829   {
830      rsp->impstate->regmap[934+regnum].type = DRCUML_PTYPE_MEMORY;
831      rsp->impstate->regmap[934+regnum].value = (FPTR)&rsp->accum[regnum].l;
832      rsp->impstate->regmap[942+regnum].type = DRCUML_PTYPE_MEMORY;
833      rsp->impstate->regmap[942+regnum].value = (FPTR)&rsp->accum[regnum].h.high;
834      rsp->impstate->regmap[950+regnum].type = DRCUML_PTYPE_MEMORY;
835      rsp->impstate->regmap[950+regnum].value = (FPTR)&rsp->accum[regnum].h.mid;
836      rsp->impstate->regmap[958+regnum].type = DRCUML_PTYPE_MEMORY;
837      rsp->impstate->regmap[958+regnum].value = (FPTR)&rsp->accum[regnum].h.low;
838      rsp->impstate->regmap[966+regnum].type = DRCUML_PTYPE_MEMORY;
839      rsp->impstate->regmap[966+regnum].value = (FPTR)&rsp->accum[regnum].h.z;
840      rsp->impstate->regmap[974+regnum].type = DRCUML_PTYPE_MEMORY;
841      rsp->impstate->regmap[974+regnum].value = (FPTR)&rsp->accum[regnum].w.mh;
842      rsp->impstate->regmap[982+regnum].type = DRCUML_PTYPE_MEMORY;
843      rsp->impstate->regmap[982+regnum].value = (FPTR)&rsp->accum[regnum].w.zl;
844      rsp->impstate->regmap[990+regnum].type = DRCUML_PTYPE_MEMORY;
845      rsp->impstate->regmap[990+regnum].value = (FPTR)&rsp->impstate->vres[regnum];
846   }
650847
651848   /* mark the cache dirty so it is updated on next execute */
652849   rsp->impstate->cache_dirty = TRUE;
r6794r6795
669866   rsp->nextpc = ~0;
670867}
671868
672static void cfunc_lwc2(void *param)
869
870static void cfunc_rsp_lbv(void *param)
673871{
674872   rsp_state *rsp = (rsp_state*)param;
675873   UINT32 op = rsp->impstate->arg0;
676   int i;
677   int end;
678   UINT32 ea;
874   UINT32 ea = 0;
679875   int dest = (op >> 16) & 0x1f;
680876   int base = (op >> 21) & 0x1f;
681877   int index = (op >> 7) & 0xf;
r6794r6795
684880   {
685881      offset |= 0xffffffc0;
686882   }
883   // 31       25      20      15      10     6        0
884   // --------------------------------------------------
885   // | 110010 | BBBBB | TTTTT | 00000 | IIII | Offset |
886   // --------------------------------------------------
887   //
888   // Load 1 byte to vector byte index
687889
688   switch ((op >> 11) & 0x1f)
890   ea = (base) ? rsp->r[base] + offset : offset;
891   W_VREG_B(dest, index, READ8(rsp, ea));
892}
893
894#if !(DRC_LSV)
895static void cfunc_rsp_lsv(void *param)
896{
897   rsp_state *rsp = (rsp_state*)param;
898   UINT32 op = rsp->impstate->arg0;
899   UINT32 ea = 0;
900   int dest = (op >> 16) & 0x1f;
901   int base = (op >> 21) & 0x1f;
902   int index = (op >> 7) & 0xf;
903   int offset = (op & 0x7f);
904   if (offset & 0x40)
689905   {
690      case 0x00:      /* LBV */
691      {
692         // 31       25      20      15      10     6        0
693         // --------------------------------------------------
694         // | 110010 | BBBBB | TTTTT | 00000 | IIII | Offset |
695         // --------------------------------------------------
696         //
697         // Load 1 byte to vector byte index
906      offset |= 0xffffffc0;
907   }
908   // 31       25      20      15      10     6        0
909   // --------------------------------------------------
910   // | 110010 | BBBBB | TTTTT | 00001 | IIII | Offset |
911   // --------------------------------------------------
912   //
913   // Loads 2 bytes starting from vector byte index
698914
699         ea = (base) ? rsp->r[base] + offset : offset;
700         W_VREG_B(dest, index, READ8(rsp, ea));
701         break;
702      }
703      case 0x01:      /* LSV */
704      {
705         // 31       25      20      15      10     6        0
706         // --------------------------------------------------
707         // | 110010 | BBBBB | TTTTT | 00001 | IIII | Offset |
708         // --------------------------------------------------
709         //
710         // Loads 2 bytes starting from vector byte index
915   ea = (base) ? rsp->r[base] + (offset * 2) : (offset * 2);
711916
712         ea = (base) ? rsp->r[base] + (offset * 2) : (offset * 2);
917   W_VREG_S(dest, index >> 1, READ16(rsp, ea));
918}
919#endif
713920
714         W_VREG_S(dest, index >> 1, READ16(rsp, ea));
715         break;
716      }
717      case 0x02:      /* LLV */
718      {
719         // 31       25      20      15      10     6        0
720         // --------------------------------------------------
721         // | 110010 | BBBBB | TTTTT | 00010 | IIII | Offset |
722         // --------------------------------------------------
723         //
724         // Loads 4 bytes starting from vector byte index
921#if !(DRC_LLV)
922static void cfunc_rsp_llv(void *param)
923{
924   rsp_state *rsp = (rsp_state*)param;
925   UINT32 op = rsp->impstate->arg0;
926   UINT32 ea = 0;
927   int dest = (op >> 16) & 0x1f;
928   int base = (op >> 21) & 0x1f;
929   int index = (op >> 7) & 0xf;
930   int offset = (op & 0x7f);
931   if (offset & 0x40)
932   {
933      offset |= 0xffffffc0;
934   }
935   // 31       25      20      15      10     6        0
936   // --------------------------------------------------
937   // | 110010 | BBBBB | TTTTT | 00010 | IIII | Offset |
938   // --------------------------------------------------
939   //
940   // Loads 4 bytes starting from vector byte index
725941
726         ea = (base) ? rsp->r[base] + (offset * 4) : (offset * 4);
942   ea = (base) ? rsp->r[base] + (offset * 4) : (offset * 4);
727943
728         W_VREG_L(dest, index >> 2, READ32(rsp, ea));
729         break;
730      }
731      case 0x03:      /* LDV */
732      {
733         // 31       25      20      15      10     6        0
734         // --------------------------------------------------
735         // | 110010 | BBBBB | TTTTT | 00011 | IIII | Offset |
736         // --------------------------------------------------
737         //
738         // Loads 8 bytes starting from vector byte index
944   W_VREG_L(dest, index >> 2, READ32(rsp, ea));
945}
946#endif
739947
740         ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
948#if !(DRC_LDV)
949static void cfunc_rsp_ldv(void *param)
950{
951   rsp_state *rsp = (rsp_state*)param;
952   UINT32 op = rsp->impstate->arg0;
953   UINT32 ea = 0;
954   int dest = (op >> 16) & 0x1f;
955   int base = (op >> 21) & 0x1f;
956   int index = (op >> 7) & 0xf;
957   int offset = (op & 0x7f);
958   if (offset & 0x40)
959   {
960      offset |= 0xffffffc0;
961   }
962   // 31       25      20      15      10     6        0
963   // --------------------------------------------------
964   // | 110010 | BBBBB | TTTTT | 00011 | IIII | Offset |
965   // --------------------------------------------------
966   //
967   // Loads 8 bytes starting from vector byte index
741968
742         index >>= 2;
743         W_VREG_L(dest, index, READ32(rsp, ea));
744         W_VREG_L(dest, index + 1, READ32(rsp, ea + 4));
745         break;
746      }
747      case 0x04:      /* LQV */
748      {
749         // 31       25      20      15      10     6        0
750         // --------------------------------------------------
751         // | 110010 | BBBBB | TTTTT | 00100 | IIII | Offset |
752         // --------------------------------------------------
753         //
754         // Loads up to 16 bytes starting from vector byte index
969   ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
755970
756         ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
971   index >>= 2;
972   W_VREG_L(dest, index, READ32(rsp, ea));
973   W_VREG_L(dest, index + 1, READ32(rsp, ea + 4));
974}
975#endif
757976
758         end = index + (16 - (ea & 0xf));
759         if (end > 16) end = 16;
977#if !(DRC_LQV)
978static void cfunc_rsp_lqv(void *param)
979{
980   rsp_state *rsp = (rsp_state*)param;
981   UINT32 op = rsp->impstate->arg0;
982   int i = 0;
983   int end = 0;
984   UINT32 ea = 0;
985   int dest = (op >> 16) & 0x1f;
986   int base = (op >> 21) & 0x1f;
987   int index = (op >> 7) & 0xf;
988   int offset = (op & 0x7f);
989   if (offset & 0x40)
990   {
991      offset |= 0xffffffc0;
992   }
993   // 31       25      20      15      10     6        0
994   // --------------------------------------------------
995   // | 110010 | BBBBB | TTTTT | 00100 | IIII | Offset |
996   // --------------------------------------------------
997   //
998   // Loads up to 16 bytes starting from vector byte index
760999
761         for (i=index; i < end; i++)
762         {
763            W_VREG_B(dest, i, READ8(rsp, ea));
764            ea++;
765         }
766         break;
767      }
768      case 0x05:      /* LRV */
769      {
770         // 31       25      20      15      10     6        0
771         // --------------------------------------------------
772         // | 110010 | BBBBB | TTTTT | 00101 | IIII | Offset |
773         // --------------------------------------------------
774         //
775         // Stores up to 16 bytes starting from right side until 16-byte boundary
1000   ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
7761001
777         ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
1002   end = index + (16 - (ea & 0xf));
1003   if (end > 16) end = 16;
7781004
779         index = 16 - ((ea & 0xf) - index);
780         end = 16;
781         ea &= ~0xf;
1005   for (i=index; i < end; i++)
1006   {
1007      W_VREG_B(dest, i, READ8(rsp, ea));
1008      ea++;
1009   }
1010}
1011#endif
7821012
783         for (i=index; i < end; i++)
784         {
785            W_VREG_B(dest, i, READ8(rsp, ea));
786            ea++;
787         }
788         break;
789      }
790      case 0x06:      /* LPV */
791      {
792         // 31       25      20      15      10     6        0
793         // --------------------------------------------------
794         // | 110010 | BBBBB | TTTTT | 00110 | IIII | Offset |
795         // --------------------------------------------------
796         //
797         // Loads a byte as the upper 8 bits of each element
1013static void cfunc_rsp_lrv(void *param)
1014{
1015   rsp_state *rsp = (rsp_state*)param;
1016   UINT32 op = rsp->impstate->arg0;
1017   int i = 0;
1018   int end = 0;
1019   UINT32 ea = 0;
1020   int dest = (op >> 16) & 0x1f;
1021   int base = (op >> 21) & 0x1f;
1022   int index = (op >> 7) & 0xf;
1023   int offset = (op & 0x7f);
1024   if (offset & 0x40)
1025   {
1026      offset |= 0xffffffc0;
1027   }
1028   // 31       25      20      15      10     6        0
1029   // --------------------------------------------------
1030   // | 110010 | BBBBB | TTTTT | 00101 | IIII | Offset |
1031   // --------------------------------------------------
1032   //
1033   // Stores up to 16 bytes starting from right side until 16-byte boundary
7981034
799         ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
1035   ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
8001036
801         for (i=0; i < 8; i++)
802         {
803            W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 8);
804         }
805         break;
806      }
807      case 0x07:      /* LUV */
808      {
809         // 31       25      20      15      10     6        0
810         // --------------------------------------------------
811         // | 110010 | BBBBB | TTTTT | 00111 | IIII | Offset |
812         // --------------------------------------------------
813         //
814         // Loads a byte as the bits 14-7 of each element
1037   index = 16 - ((ea & 0xf) - index);
1038   end = 16;
1039   ea &= ~0xf;
8151040
816         ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
1041   for (i=index; i < end; i++)
1042   {
1043      W_VREG_B(dest, i, READ8(rsp, ea));
1044      ea++;
1045   }
1046}
8171047
818         for (i=0; i < 8; i++)
819         {
820            W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 7);
821         }
822         break;
823      }
824      case 0x08:      /* LHV */
825      {
826         // 31       25      20      15      10     6        0
827         // --------------------------------------------------
828         // | 110010 | BBBBB | TTTTT | 01000 | IIII | Offset |
829         // --------------------------------------------------
830         //
831         // Loads a byte as the bits 14-7 of each element, with 2-byte stride
1048#if !(DRC_LPV)
1049static void cfunc_rsp_lpv(void *param)
1050{
1051   rsp_state *rsp = (rsp_state*)param;
1052   UINT32 op = rsp->impstate->arg0;
1053   int i = 0;
1054   UINT32 ea = 0;
1055   int dest = (op >> 16) & 0x1f;
1056   int base = (op >> 21) & 0x1f;
1057   int index = (op >> 7) & 0xf;
1058   int offset = (op & 0x7f);
1059   if (offset & 0x40)
1060   {
1061      offset |= 0xffffffc0;
1062   }
1063   // 31       25      20      15      10     6        0
1064   // --------------------------------------------------
1065   // | 110010 | BBBBB | TTTTT | 00110 | IIII | Offset |
1066   // --------------------------------------------------
1067   //
1068   // Loads a byte as the upper 8 bits of each element
8321069
833         ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
1070   ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
8341071
835         for (i=0; i < 8; i++)
836         {
837            W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + (i<<1)) & 0xf)) << 7);
838         }
839         break;
840      }
841      case 0x09:      /* LFV */
842      {
843         // 31       25      20      15      10     6        0
844         // --------------------------------------------------
845         // | 110010 | BBBBB | TTTTT | 01001 | IIII | Offset |
846         // --------------------------------------------------
847         //
848         // Loads a byte as the bits 14-7 of upper or lower quad, with 4-byte stride
1072   for (i=0; i < 8; i++)
1073   {
1074      printf("%08x ", READ8(rsp, ea + (((16-index) + i) & 0xf)) << 8);
1075      W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 8);
1076   }
1077   printf("\n");
1078}
1079#endif
8491080
850         fatalerror("RSP: LFV\n");
1081#if !(DRC_LUV)
1082static void cfunc_rsp_luv(void *param)
1083{
1084   rsp_state *rsp = (rsp_state*)param;
1085   UINT32 op = rsp->impstate->arg0;
1086   int i = 0;
1087   UINT32 ea = 0;
1088   int dest = (op >> 16) & 0x1f;
1089   int base = (op >> 21) & 0x1f;
1090   int index = (op >> 7) & 0xf;
1091   int offset = (op & 0x7f);
1092   if (offset & 0x40)
1093   {
1094      offset |= 0xffffffc0;
1095   }
1096   // 31       25      20      15      10     6        0
1097   // --------------------------------------------------
1098   // | 110010 | BBBBB | TTTTT | 00111 | IIII | Offset |
1099   // --------------------------------------------------
1100   //
1101   // Loads a byte as the bits 14-7 of each element
8511102
852         if (index & 0x7)   fatalerror("RSP: LFV: index = %d at %08X\n", index, rsp->ppc);
1103   ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
8531104
854         ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
1105   for (i=0; i < 8; i++)
1106   {
1107      W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 7);
1108   }
1109}
1110#endif
8551111
856         // not sure what happens if 16-byte boundary is crossed...
857         if ((ea & 0xf) > 0)   fatalerror("RSP: LFV: 16-byte boundary crossing at %08X, recheck this!\n", rsp->ppc);
1112static void cfunc_rsp_lhv(void *param)
1113{
1114   rsp_state *rsp = (rsp_state*)param;
1115   UINT32 op = rsp->impstate->arg0;
1116   int i = 0;
1117   UINT32 ea = 0;
1118   int dest = (op >> 16) & 0x1f;
1119   int base = (op >> 21) & 0x1f;
1120   int index = (op >> 7) & 0xf;
1121   int offset = (op & 0x7f);
1122   if (offset & 0x40)
1123   {
1124      offset |= 0xffffffc0;
1125   }
1126   // 31       25      20      15      10     6        0
1127   // --------------------------------------------------
1128   // | 110010 | BBBBB | TTTTT | 01000 | IIII | Offset |
1129   // --------------------------------------------------
1130   //
1131   // Loads a byte as the bits 14-7 of each element, with 2-byte stride
8581132
859         end = (index >> 1) + 4;
1133   ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
8601134
861         for (i=index >> 1; i < end; i++)
862         {
863            W_VREG_S(dest, i, READ8(rsp, ea) << 7);
864            ea += 4;
865         }
866         break;
867      }
868      case 0x0a:      /* LWV */
869      {
870         // 31       25      20      15      10     6        0
871         // --------------------------------------------------
872         // | 110010 | BBBBB | TTTTT | 01010 | IIII | Offset |
873         // --------------------------------------------------
874         //
875         // Loads the full 128-bit vector starting from vector byte index and wrapping to index 0
876         // after byte index 15
1135   for (i=0; i < 8; i++)
1136   {
1137      W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + (i<<1)) & 0xf)) << 7);
1138   }
1139}
8771140
878         ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
1141static void cfunc_rsp_lfv(void *param)
1142{
1143   rsp_state *rsp = (rsp_state*)param;
1144   UINT32 op = rsp->impstate->arg0;
1145   int i = 0;
1146   int end = 0;
1147   UINT32 ea = 0;
1148   int dest = (op >> 16) & 0x1f;
1149   int base = (op >> 21) & 0x1f;
1150   int index = (op >> 7) & 0xf;
1151   int offset = (op & 0x7f);
1152   if (offset & 0x40)
1153   {
1154      offset |= 0xffffffc0;
1155   }
1156   // 31       25      20      15      10     6        0
1157   // --------------------------------------------------
1158   // | 110010 | BBBBB | TTTTT | 01001 | IIII | Offset |
1159   // --------------------------------------------------
1160   //
1161   // Loads a byte as the bits 14-7 of upper or lower quad, with 4-byte stride
8791162
880         // not sure what happens if 16-byte boundary is crossed...
881         if ((ea & 0xf) > 0) fatalerror("RSP: LWV: 16-byte boundary crossing at %08X, recheck this!\n", rsp->ppc);
1163   fatalerror("RSP: LFV\n");
8821164
883         end = (16 - index) + 16;
1165   if (index & 0x7)   fatalerror("RSP: LFV: index = %d at %08X\n", index, rsp->ppc);
8841166
885         for (i=(16 - index); i < end; i++)
886         {
887            //printf("%d",i);
888            W_VREG_B(dest, i & 0xf, READ8(rsp, ea));
889            ea += 4;
890         }
891         //printf("\n");
892         break;
893      }
894      case 0x0b:      /* LTV */
895      {
896         // 31       25      20      15      10     6        0
897         // --------------------------------------------------
898         // | 110010 | BBBBB | TTTTT | 01011 | IIII | Offset |
899         // --------------------------------------------------
900         //
901         // Loads one element to maximum of 8 vectors, while incrementing element index
1167   ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
9021168
903         // FIXME: has a small problem with odd indices
1169   // not sure what happens if 16-byte boundary is crossed...
1170   if ((ea & 0xf) > 0)   fatalerror("RSP: LFV: 16-byte boundary crossing at %08X, recheck this!\n", rsp->ppc);
9041171
905         int element;
906         int vs = dest;
907         int ve = dest + 8;
908         if (ve > 32)
909            ve = 32;
1172   end = (index >> 1) + 4;
9101173
911         element = 7 - (index >> 1);
1174   for (i=index >> 1; i < end; i++)
1175   {
1176      W_VREG_S(dest, i, READ8(rsp, ea) << 7);
1177      ea += 4;
1178   }
1179}
9121180
913         if (index & 1)   fatalerror("RSP: LTV: index = %d\n", index);
1181static void cfunc_rsp_lwv(void *param)
1182{
1183   rsp_state *rsp = (rsp_state*)param;
1184   UINT32 op = rsp->impstate->arg0;
1185   int i = 0;
1186   int end = 0;
1187   UINT32 ea = 0;
1188   int dest = (op >> 16) & 0x1f;
1189   int base = (op >> 21) & 0x1f;
1190   int index = (op >> 7) & 0xf;
1191   int offset = (op & 0x7f);
1192   if (offset & 0x40)
1193   {
1194      offset |= 0xffffffc0;
1195   }
1196   // 31       25      20      15      10     6        0
1197   // --------------------------------------------------
1198   // | 110010 | BBBBB | TTTTT | 01010 | IIII | Offset |
1199   // --------------------------------------------------
1200   //
1201   // Loads the full 128-bit vector starting from vector byte index and wrapping to index 0
1202   // after byte index 15
9141203
915         ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
1204   ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
9161205
917         ea = ((ea + 8) & ~0xf) + (index & 1);
918         for (i=vs; i < ve; i++)
919         {
920            element = ((8 - (index >> 1) + (i-vs)) << 1);
921            W_VREG_B(i, (element & 0xf), READ8(rsp, ea));
922            W_VREG_B(i, ((element+1) & 0xf), READ8(rsp, ea+1));
1206   // not sure what happens if 16-byte boundary is crossed...
1207   if ((ea & 0xf) > 0) fatalerror("RSP: LWV: 16-byte boundary crossing at %08X, recheck this!\n", rsp->ppc);
9231208
924            ea += 2;
925         }
926         break;
927      }
1209   end = (16 - index) + 16;
9281210
929      default:
930      {
931         unimplemented_opcode(rsp, op);
932         break;
933      }
1211   for (i=(16 - index); i < end; i++)
1212   {
1213      W_VREG_B(dest, i & 0xf, READ8(rsp, ea));
1214      ea += 4;
9341215   }
9351216}
9361217
937static void cfunc_swc2(void *param)
1218static void cfunc_rsp_ltv(void *param)
9381219{
9391220   rsp_state *rsp = (rsp_state*)param;
9401221   UINT32 op = rsp->impstate->arg0;
941   int i;
942   int end;
943   int eaoffset;
944   UINT32 ea;
1222   int i = 0;
1223   UINT32 ea = 0;
9451224   int dest = (op >> 16) & 0x1f;
9461225   int base = (op >> 21) & 0x1f;
9471226   int index = (op >> 7) & 0xf;
9481227   int offset = (op & 0x7f);
1228
1229   // 31       25      20      15      10     6        0
1230   // --------------------------------------------------
1231   // | 110010 | BBBBB | TTTTT | 01011 | IIII | Offset |
1232   // --------------------------------------------------
1233   //
1234   // Loads one element to maximum of 8 vectors, while incrementing element index
1235
1236   // FIXME: has a small problem with odd indices
1237
1238   int element;
1239   int vs = dest;
1240   int ve = dest + 8;
1241   if (ve > 32)
1242      ve = 32;
1243
9491244   if (offset & 0x40)
9501245   {
9511246      offset |= 0xffffffc0;
9521247   }
9531248
1249   element = 7 - (index >> 1);
1250
1251   if (index & 1)   fatalerror("RSP: LTV: index = %d\n", index);
1252
1253   ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
1254
1255   ea = ((ea + 8) & ~0xf) + (index & 1);
1256   for (i=vs; i < ve; i++)
1257   {
1258      element = ((8 - (index >> 1) + (i-vs)) << 1);
1259      W_VREG_B(i, (element & 0xf), READ8(rsp, ea));
1260      W_VREG_B(i, ((element+1) & 0xf), READ8(rsp, ea+1));
1261
1262      ea += 2;
1263   }
1264}
1265
1266static int generate_lwc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1267{
1268   int loopdest;
1269   UINT32 op = desc->opptr.l[0];
1270   int dest = (op >> 16) & 0x1f;
1271   //int base = (op >> 21) & 0x1f;
1272   int index = (op >> 7) & 0xf;
1273   int offset = (op & 0x7f);
1274   //int skip;
1275   if (offset & 0x40)
1276   {
1277      offset |= 0xffffffc0;
1278   }
1279
9541280   switch ((op >> 11) & 0x1f)
9551281   {
956      case 0x00:      /* SBV */
957      {
1282      case 0x00:      /* LBV */
1283         //UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));
1284         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1285         UML_CALLC(block, cfunc_rsp_lbv, rsp);
1286         return TRUE;
1287      case 0x01:      /* LSV */
1288#if (DRC_LSV)
1289         offset <<= 1;
1290         index >>= 1;
1291
1292         index = 7 - index;
1293         UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));                  // add     i0,<rsreg>,offset
1294         UML_SHR(block, IREG(0), IREG(0), IMM(1));                        // shr     i0,i0,1
1295         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE_XOR_BE(0)));               // xor     i0,i0,bytexor
1296         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), WORD);         // load    i0,dmem,i0,word
1297         UML_STORE(block, &rsp->v[dest].s[index], IMM(0), IREG(0), WORD);      // store   v[dest][index],i0,word
1298         return TRUE;
1299#else
1300         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1301         UML_CALLC(block, cfunc_rsp_lsv, rsp);
1302         return TRUE;
1303#endif
1304      case 0x02:      /* LLV */
1305#if (DRC_LLV)
1306         offset <<= 2;
1307         index >>= 2;
1308
1309         UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));                  // add     i0,<rsreg>,offset
1310         UML_CALLH(block, rsp->impstate->read32);                        // callh   read32
1311         UML_MOV(block, VLX(dest, index), IREG(0));                        // mov     v[dest]index].i0
1312         return TRUE;
1313#else
1314         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1315         UML_CALLC(block, cfunc_rsp_llv, rsp);
1316         return TRUE;
1317#endif
1318      case 0x03:      /* LDV */
1319#if (DRC_LDV)
1320         offset <<= 3;
1321         index >>= 2;
1322
1323         UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));                  // add     i0,<rsreg>,offset
1324         UML_CALLH(block, rsp->impstate->read32);                        // callh   read32
1325         UML_MOV(block, VLX(dest, index), IREG(0));                        // mov     v[dest][index-1],i0
1326
1327         UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));                  // add     i0,<rsreg>,offset
1328         UML_ADD(block, IREG(0), IREG(0), IMM(4));                        // add     i0,i0,4
1329         UML_CALLH(block, rsp->impstate->read32);                        // callh   read32
1330         UML_MOV(block, VLX(dest, index+1), IREG(0));                        // mov     v[dest][index],i0
1331         return TRUE;
1332#else
1333         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1334         UML_CALLC(block, cfunc_rsp_ldv, rsp);
1335         return TRUE;
1336#endif
1337      case 0x04:      /* LQV */
1338#if (DRC_LQV)
1339         offset <<= 4;
1340
1341         UML_ADD(block, MEM(&rsp->impstate->arg0), R32(RSREG), IMM(offset));      // mov     arg0,<rsreg>,offset
1342         UML_MOV(block, IREG(3), IMM(index));                           // mov     i3,index
1343         UML_MOV(block, IREG(2), MEM(&rsp->impstate->arg0));                  // mov     i2,arg0
1344         UML_AND(block, IREG(2), IREG(2), IMM(0x0000000f));                  // and     i2,i2,0x0000000f
1345         UML_SUB(block, IREG(2), IMM(16), IREG(2));                        // sub     i2,16,i2
1346         UML_ADD(block, IREG(2), IREG(2), IREG(3));                        // add     i2,i2,i3
1347         UML_CMP(block, IREG(2), IMM(16));                              // cmp     i2,16
1348         UML_TEST(block, IREG(2), IMM(0xfffffff0));                        // test    i2,0xfffffff0
1349         UML_MOVc(block, IF_NZ, IREG(2), IMM(16));                        // mov     NZ,i2,16
1350
1351      UML_LABEL(block, loopdest = compiler->labelnum++);                     // loopdest:
1352         UML_MOV(block, IREG(0), MEM(&rsp->impstate->arg0));                  // mov     i0,arg0
1353         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1354         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1355         UML_SUB(block, IREG(1), IMM(15), IREG(3));                        // sub     i1,15,i3
1356         UML_STORE(block, &rsp->v[dest].b[0], IREG(1), IREG(0), BYTE);         // store   v[dest][0]+i1,i0
1357
1358         UML_ADD(block, MEM(&rsp->impstate->arg0), MEM(&rsp->impstate->arg0), IMM(1));
1359         UML_AND(block, MEM(&rsp->impstate->arg0), MEM(&rsp->impstate->arg0), IMM(0x00000fff));
1360         UML_ADD(block, IREG(3), IREG(3), IMM(1));                        // add     i3,i3,1
1361         UML_CMP(block, IREG(3), IREG(2));                              // cmp     i3,i2
1362         UML_JMPc(block, IF_L, loopdest);                              // jmp     L,loopdest
1363         return TRUE;
1364
1365#else
1366         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1367         UML_CALLC(block, cfunc_rsp_lqv, rsp);
1368         return TRUE;
1369#endif
1370      case 0x05:      /* LRV */
1371         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1372         UML_CALLC(block, cfunc_rsp_lrv, rsp);
1373         return TRUE;
1374      case 0x06:      /* LPV */
1375#if (DRC_LPV)
1376         offset <<= 3;
1377
1378         UML_ADD(block, IREG(2), R32(RSREG), IMM(offset));                  // add     i2,<rsreg>,offset
1379         UML_SUB(block, IREG(3), IMM(16), IMM(index));                     // sub     i3,16,index
1380
1381         UML_AND(block, IREG(1), IREG(3), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1382         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1383         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                  // and     i0,i0,0x00000fff
1384         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1385         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1386         UML_SHL(block, IREG(0), IREG(0), IMM(8));                        // shl     i0,i0,8
1387         UML_STORE(block, &rsp->v[dest].s[7], IMM(0), IREG(0), WORD);         // store   v[dest][7],i0,word
1388
1389         UML_ADD(block, IREG(1), IREG(3), IMM(1));                        // add     i1,i3,1
1390         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1391         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1392         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                  // and     i0,i0,0x00000fff
1393         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1394         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1395         UML_SHL(block, IREG(0), IREG(0), IMM(8));                        // shl     i0,i0,8
1396         UML_STORE(block, &rsp->v[dest].s[6], IMM(0), IREG(0), WORD);         // store   v[dest][6],i0,word
1397
1398         UML_ADD(block, IREG(1), IREG(3), IMM(2));                        // add     i1,i3,2
1399         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1400         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1401         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                  // and     i0,i0,0x00000fff
1402         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1403         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1404         UML_SHL(block, IREG(0), IREG(0), IMM(8));                        // shl     i0,i0,8
1405         UML_STORE(block, &rsp->v[dest].s[5], IMM(0), IREG(0), WORD);         // store   v[dest][5],i0,word
1406
1407         UML_ADD(block, IREG(1), IREG(3), IMM(3));                        // add     i1,i3,3
1408         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1409         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1410         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                  // and     i0,i0,0x00000fff
1411         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1412         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1413         UML_SHL(block, IREG(0), IREG(0), IMM(8));                        // shl     i0,i0,8
1414         UML_STORE(block, &rsp->v[dest].s[4], IMM(0), IREG(0), WORD);         // store   v[dest][4],i0,word
1415
1416         UML_ADD(block, IREG(1), IREG(3), IMM(4));                        // add     i1,i3,4
1417         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1418         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1419         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                  // and     i0,i0,0x00000fff
1420         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1421         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1422         UML_SHL(block, IREG(0), IREG(0), IMM(8));                        // shl     i0,i0,8
1423         UML_STORE(block, &rsp->v[dest].s[3], IMM(0), IREG(0), WORD);         // store   v[dest][3],i0,word
1424
1425         UML_ADD(block, IREG(1), IREG(3), IMM(5));                        // add     i1,i3,5
1426         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1427         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1428         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                  // and     i0,i0,0x00000fff
1429         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1430         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1431         UML_SHL(block, IREG(0), IREG(0), IMM(8));                        // shl     i0,i0,8
1432         UML_STORE(block, &rsp->v[dest].s[2], IMM(0), IREG(0), WORD);         // store   v[dest][2],i0,word
1433
1434         UML_ADD(block, IREG(1), IREG(3), IMM(6));                        // add     i1,i3,6
1435         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1436         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1437         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                  // and     i0,i0,0x00000fff
1438         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1439         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1440         UML_SHL(block, IREG(0), IREG(0), IMM(8));                        // shl     i0,i0,8
1441         UML_STORE(block, &rsp->v[dest].s[1], IMM(0), IREG(0), WORD);         // store   v[dest][1],i0,word
1442
1443         UML_ADD(block, IREG(1), IREG(3), IMM(7));                        // add     i1,i3,7
1444         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1445         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1446         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                  // and     i0,i0,0x00000fff
1447         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));               // xor     i0,i0,bytexor
1448         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);         // load    i0,dmem,i0,byte
1449         UML_SHL(block, IREG(0), IREG(0), IMM(8));                        // shl     i0,i0,8
1450         UML_STORE(block, &rsp->v[dest].s[0], IMM(0), IREG(0), WORD);         // store   v[dest][0],i0,word
1451         return TRUE;
1452#else
1453         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1454         UML_CALLC(block, cfunc_rsp_lpv, rsp);
1455         return TRUE;
1456#endif
1457      case 0x07:      /* LUV */
1458#if (DRC_LUV)
1459   /*
1460   ea = (base) ? rsp->r[base] + (offset * 8) : (offset * 8);
1461
1462   for (i=0; i < 8; i++)
1463   {
1464      W_VREG_S(dest, i, READ8(rsp, ea + (((16-index) + i) & 0xf)) << 7);
1465   }
1466   */
1467         offset <<= 3;
1468
1469         UML_ADD(block, IREG(2), R32(RSREG), IMM(offset));                  // add     i2,<rsreg>,offset
1470         UML_SUB(block, IREG(3), IMM(16), IMM(index));                     // sub     i3,16,index
1471
1472         UML_AND(block, IREG(1), IREG(3), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1473         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1474         UML_CALLH(block, rsp->impstate->read8);                           // callh   read8
1475         UML_SHL(block, IREG(0), IREG(0), IMM(7));                        // shl     i0,i0,8
1476         UML_STORE(block, &rsp->v[dest].s[7], IMM(0), IREG(0), WORD);         // store   v[dest][7],i0,word
1477
1478         UML_ADD(block, IREG(1), IREG(3), IMM(1));                        // add     i1,i3,1
1479         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1480         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1481         UML_CALLH(block, rsp->impstate->read8);                           // callh   read8
1482         UML_SHL(block, IREG(0), IREG(0), IMM(7));                        // shl     i0,i0,8
1483         UML_STORE(block, &rsp->v[dest].s[6], IMM(0), IREG(0), WORD);         // store   v[dest][6],i0,word
1484
1485         UML_ADD(block, IREG(1), IREG(3), IMM(2));                        // add     i1,i3,2
1486         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1487         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1488         UML_CALLH(block, rsp->impstate->read8);                           // callh   read8
1489         UML_SHL(block, IREG(0), IREG(0), IMM(7));                        // shl     i0,i0,8
1490         UML_STORE(block, &rsp->v[dest].s[5], IMM(0), IREG(0), WORD);         // store   v[dest][5],i0,word
1491
1492         UML_ADD(block, IREG(1), IREG(3), IMM(3));                        // add     i1,i3,3
1493         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1494         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1495         UML_CALLH(block, rsp->impstate->read8);                           // callh   read8
1496         UML_SHL(block, IREG(0), IREG(0), IMM(7));                        // shl     i0,i0,8
1497         UML_STORE(block, &rsp->v[dest].s[4], IMM(0), IREG(0), WORD);         // store   v[dest][4],i0,word
1498
1499         UML_ADD(block, IREG(1), IREG(3), IMM(4));                        // add     i1,i3,4
1500         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1501         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1502         UML_CALLH(block, rsp->impstate->read8);                           // callh   read8
1503         UML_SHL(block, IREG(0), IREG(0), IMM(7));                        // shl     i0,i0,8
1504         UML_STORE(block, &rsp->v[dest].s[3], IMM(0), IREG(0), WORD);         // store   v[dest][3],i0,word
1505
1506         UML_ADD(block, IREG(1), IREG(3), IMM(5));                        // add     i1,i3,5
1507         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1508         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1509         UML_CALLH(block, rsp->impstate->read8);                           // callh   read8
1510         UML_SHL(block, IREG(0), IREG(0), IMM(7));                        // shl     i0,i0,8
1511         UML_STORE(block, &rsp->v[dest].s[2], IMM(0), IREG(0), WORD);         // store   v[dest][2],i0,word
1512
1513         UML_ADD(block, IREG(1), IREG(3), IMM(6));                        // add     i1,i3,6
1514         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1515         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1516         UML_CALLH(block, rsp->impstate->read8);                           // callh   read8
1517         UML_SHL(block, IREG(0), IREG(0), IMM(7));                        // shl     i0,i0,8
1518         UML_STORE(block, &rsp->v[dest].s[1], IMM(0), IREG(0), WORD);         // store   v[dest][1],i0,word
1519
1520         UML_ADD(block, IREG(1), IREG(3), IMM(7));                        // add     i1,i3,7
1521         UML_AND(block, IREG(1), IREG(1), IMM(0x0000000f));                  // and     i1,i1,0x0000000f
1522         UML_ADD(block, IREG(0), IREG(1), IREG(2));                        // add     i0,i1,i2
1523         UML_CALLH(block, rsp->impstate->read8);                           // callh   read8
1524         UML_SHL(block, IREG(0), IREG(0), IMM(7));                        // shl     i0,i0,8
1525         UML_STORE(block, &rsp->v[dest].s[0], IMM(0), IREG(0), WORD);         // store   v[dest][0],i0,word
1526         return TRUE;
1527#else
1528         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1529         UML_CALLC(block, cfunc_rsp_luv, rsp);
1530         return TRUE;
1531#endif
1532      case 0x08:      /* LHV */
1533         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1534         UML_CALLC(block, cfunc_rsp_lhv, rsp);
1535         return TRUE;
1536      case 0x09:      /* LFV */
1537         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1538         UML_CALLC(block, cfunc_rsp_lfv, rsp);
1539         return TRUE;
1540      case 0x0a:      /* LWV */
1541         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1542         UML_CALLC(block, cfunc_rsp_lwv, rsp);
1543         return TRUE;
1544      case 0x0b:      /* LTV */
1545         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1546         UML_CALLC(block, cfunc_rsp_ltv, rsp);
1547         return TRUE;
1548
1549      default:
1550         return FALSE;
1551   }
1552}
1553
1554static void cfunc_rsp_sbv(void *param)
1555{
1556   rsp_state *rsp = (rsp_state*)param;
1557   UINT32 op = rsp->impstate->arg0;
1558   UINT32 ea = 0;
1559   int dest = (op >> 16) & 0x1f;
1560   int base = (op >> 21) & 0x1f;
1561   int index = (op >> 7) & 0xf;
1562   int offset = (op & 0x7f);
1563   if (offset & 0x40)
1564   {
1565      offset |= 0xffffffc0;
1566   }
9581567         // 31       25      20      15      10     6        0
9591568         // --------------------------------------------------
9601569         // | 111010 | BBBBB | TTTTT | 00000 | IIII | Offset |
r6794r6795
9641573
9651574         ea = (base) ? rsp->r[base] + offset : offset;
9661575         WRITE8(rsp, ea, R_VREG_B(dest, index));
967         break;
968      }
969      case 0x01:      /* SSV */
970      {
1576}
1577
1578#if !(DRC_SSV)
1579static void cfunc_rsp_ssv(void *param)
1580{
1581   rsp_state *rsp = (rsp_state*)param;
1582   UINT32 op = rsp->impstate->arg0;
1583   UINT32 ea = 0;
1584   int dest = (op >> 16) & 0x1f;
1585   int base = (op >> 21) & 0x1f;
1586   int index = (op >> 7) & 0xf;
1587   int offset = (op & 0x7f);
1588   if (offset & 0x40)
1589   {
1590      offset |= 0xffffffc0;
1591   }
9711592         // 31       25      20      15      10     6        0
9721593         // --------------------------------------------------
9731594         // | 111010 | BBBBB | TTTTT | 00001 | IIII | Offset |
r6794r6795
9781599         ea = (base) ? rsp->r[base] + (offset * 2) : (offset * 2);
9791600
9801601         WRITE16(rsp, ea, R_VREG_S(dest, index >> 1));
981         break;
982      }
983      case 0x02:      /* SLV */
984      {
1602}
1603#endif
1604
1605#if !(DRC_SLV)
1606static void cfunc_rsp_slv(void *param)
1607{
1608   rsp_state *rsp = (rsp_state*)param;
1609   UINT32 op = rsp->impstate->arg0;
1610   UINT32 ea = 0;
1611   int dest = (op >> 16) & 0x1f;
1612   int base = (op >> 21) & 0x1f;
1613   int index = (op >> 7) & 0xf;
1614   int offset = (op & 0x7f);
1615   if (offset & 0x40)
1616   {
1617      offset |= 0xffffffc0;
1618   }
9851619         // 31       25      20      15      10     6        0
9861620         // --------------------------------------------------
9871621         // | 111010 | BBBBB | TTTTT | 00010 | IIII | Offset |
r6794r6795
9921626         ea = (base) ? rsp->r[base] + (offset * 4) : (offset * 4);
9931627
9941628         WRITE32(rsp, ea, R_VREG_L(dest, index >> 2));
995         break;
996      }
997      case 0x03:      /* SDV */
998      {
1629}
1630#endif
1631
1632#if !(DRC_SDV)
1633static void cfunc_rsp_sdv(void *param)
1634{
1635   rsp_state *rsp = (rsp_state*)param;
1636   UINT32 op = rsp->impstate->arg0;
1637   UINT32 ea = 0;
1638   int end = 0;
1639   int dest = (op >> 16) & 0x1f;
1640   int base = (op >> 21) & 0x1f;
1641   int index = (op >> 7) & 0xf;
1642   int offset = (op & 0x7f);
1643   if (offset & 0x40)
1644   {
1645      offset |= 0xffffffc0;
1646   }
9991647         // 31       25      20      15      10     6        0
10001648         // --------------------------------------------------
10011649         // | 111010 | BBBBB | TTTTT | 00011 | IIII | Offset |
r6794r6795
10091657         index >>= 2;
10101658         WRITE32(rsp, ea, R_VREG_L(dest, index));
10111659         WRITE32(rsp, ea + 4, R_VREG_L(dest, index + 1));
1012         break;
1013      }
1014      case 0x04:      /* SQV */
1015      {
1660}
1661#endif
1662
1663#if !(DRC_SQV)
1664static void cfunc_rsp_sqv(void *param)
1665{
1666   rsp_state *rsp = (rsp_state*)param;
1667   UINT32 op = rsp->impstate->arg0;
1668   UINT32 ea = 0;
1669   int i = 0;
1670   int end = 0;
1671   int dest = (op >> 16) & 0x1f;
1672   int base = (op >> 21) & 0x1f;
1673   int index = (op >> 7) & 0xf;
1674   int offset = (op & 0x7f);
1675   if (offset & 0x40)
1676   {
1677      offset |= 0xffffffc0;
1678   }
10161679         // 31       25      20      15      10     6        0
10171680         // --------------------------------------------------
10181681         // | 111010 | BBBBB | TTTTT | 00100 | IIII | Offset |
r6794r6795
10291692            WRITE8(rsp, ea, R_VREG_B(dest, i & 0xf));
10301693            ea++;
10311694         }
1032         break;
1033      }
1034      case 0x05:      /* SRV */
1035      {
1695}
1696#endif
1697
1698static void cfunc_rsp_srv(void *param)
1699{
1700   rsp_state *rsp = (rsp_state*)param;
1701   UINT32 op = rsp->impstate->arg0;
1702   UINT32 ea = 0;
1703   int o;
1704   int i = 0;
1705   int end = 0;
1706   int dest = (op >> 16) & 0x1f;
1707   int base = (op >> 21) & 0x1f;
1708   int index = (op >> 7) & 0xf;
1709   int offset = (op & 0x7f);
1710   if (offset & 0x40)
1711   {
1712      offset |= 0xffffffc0;
1713   }
10361714         // 31       25      20      15      10     6        0
10371715         // --------------------------------------------------
10381716         // | 111010 | BBBBB | TTTTT | 00101 | IIII | Offset |
r6794r6795
10401718         //
10411719         // Stores up to 16 bytes starting from right side until 16-byte boundary
10421720
1043         int o;
10441721         ea = (base) ? rsp->r[base] + (offset * 16) : (offset * 16);
10451722
10461723         end = index + (ea & 0xf);
r6794r6795
10521729            WRITE8(rsp, ea, R_VREG_B(dest, ((i + o) & 0xf)));
10531730            ea++;
10541731         }
1055         break;
1056      }
1057      case 0x06:      /* SPV */
1058      {
1732}
1733
1734static void cfunc_rsp_spv(void *param)
1735{
1736   rsp_state *rsp = (rsp_state*)param;
1737   UINT32 op = rsp->impstate->arg0;
1738   UINT32 ea = 0;
1739   int i = 0;
1740   int end = 0;
1741   int dest = (op >> 16) & 0x1f;
1742   int base = (op >> 21) & 0x1f;
1743   int index = (op >> 7) & 0xf;
1744   int offset = (op & 0x7f);
1745   if (offset & 0x40)
1746   {
1747      offset |= 0xffffffc0;
1748   }
10591749         // 31       25      20      15      10     6        0
10601750         // --------------------------------------------------
10611751         // | 111010 | BBBBB | TTTTT | 00110 | IIII | Offset |
r6794r6795
10781768            }
10791769            ea++;
10801770         }
1081         break;
1082      }
1083      case 0x07:      /* SUV */
1084      {
1771}
1772
1773static void cfunc_rsp_suv(void *param)
1774{
1775   rsp_state *rsp = (rsp_state*)param;
1776   UINT32 op = rsp->impstate->arg0;
1777   UINT32 ea = 0;
1778   int i = 0;
1779   int end = 0;
1780   int dest = (op >> 16) & 0x1f;
1781   int base = (op >> 21) & 0x1f;
1782   int index = (op >> 7) & 0xf;
1783   int offset = (op & 0x7f);
1784   if (offset & 0x40)
1785   {
1786      offset |= 0xffffffc0;
1787   }
10851788         // 31       25      20      15      10     6        0
10861789         // --------------------------------------------------
10871790         // | 111010 | BBBBB | TTTTT | 00111 | IIII | Offset |
r6794r6795
11041807            }
11051808            ea++;
11061809         }
1107         break;
1108      }
1109      case 0x08:      /* SHV */
1110      {
1810}
1811
1812static void cfunc_rsp_shv(void *param)
1813{
1814   rsp_state *rsp = (rsp_state*)param;
1815   UINT32 op = rsp->impstate->arg0;
1816   UINT32 ea = 0;
1817   int i = 0;
1818   int dest = (op >> 16) & 0x1f;
1819   int base = (op >> 21) & 0x1f;
1820   int index = (op >> 7) & 0xf;
1821   int offset = (op & 0x7f);
1822   if (offset & 0x40)
1823   {
1824      offset |= 0xffffffc0;
1825   }
11111826         // 31       25      20      15      10     6        0
11121827         // --------------------------------------------------
11131828         // | 111010 | BBBBB | TTTTT | 01000 | IIII | Offset |
r6794r6795
11251840            WRITE8(rsp, ea, d);
11261841            ea += 2;
11271842         }
1128         break;
1129      }
1130      case 0x09:      /* SFV */
1131      {
1843}
1844
1845static void cfunc_rsp_sfv(void *param)
1846{
1847   rsp_state *rsp = (rsp_state*)param;
1848   UINT32 op = rsp->impstate->arg0;
1849   UINT32 ea = 0;
1850   int i = 0;
1851   int end = 0;
1852   int eaoffset = 0;
1853   int dest = (op >> 16) & 0x1f;
1854   int base = (op >> 21) & 0x1f;
1855   int index = (op >> 7) & 0xf;
1856   int offset = (op & 0x7f);
1857   if (offset & 0x40)
1858   {
1859      offset |= 0xffffffc0;
1860   }
11321861         // 31       25      20      15      10     6        0
11331862         // --------------------------------------------------
11341863         // | 111010 | BBBBB | TTTTT | 01001 | IIII | Offset |
r6794r6795
11521881            WRITE8(rsp, ea + (eaoffset & 0xf), R_VREG_S(dest, i) >> 7);
11531882            eaoffset += 4;
11541883         }
1155         break;
1156      }
1157      case 0x0a:      /* SWV */
1158      {
1884}
1885
1886static void cfunc_rsp_swv(void *param)
1887{
1888   rsp_state *rsp = (rsp_state*)param;
1889   UINT32 op = rsp->impstate->arg0;
1890   UINT32 ea = 0;
1891   int i = 0;
1892   int end = 0;
1893   int eaoffset = 0;
1894   int dest = (op >> 16) & 0x1f;
1895   int base = (op >> 21) & 0x1f;
1896   int index = (op >> 7) & 0xf;
1897   int offset = (op & 0x7f);
1898   if (offset & 0x40)
1899   {
1900      offset |= 0xffffffc0;
1901   }
11591902         // 31       25      20      15      10     6        0
11601903         // --------------------------------------------------
11611904         // | 111010 | BBBBB | TTTTT | 01010 | IIII | Offset |
r6794r6795
11761919            WRITE8(rsp, ea + (eaoffset & 0xf), R_VREG_B(dest, i & 0xf));
11771920            eaoffset++;
11781921         }
1179         break;
1180      }
1181      case 0x0b:      /* STV */
1182      {
1922}
1923
1924static void cfunc_rsp_stv(void *param)
1925{
1926   rsp_state *rsp = (rsp_state*)param;
1927   UINT32 op = rsp->impstate->arg0;
1928   UINT32 ea = 0;
1929   int i = 0;
1930   int dest = (op >> 16) & 0x1f;
1931   int base = (op >> 21) & 0x1f;
1932   int index = (op >> 7) & 0xf;
1933   int offset = (op & 0x7f);
1934   int element;
1935   int eaoffset = 0;
1936   int vs = dest;
1937   int ve = dest + 8;
1938   if (ve > 32)
1939      ve = 32;
1940
1941   if (offset & 0x40)
1942   {
1943      offset |= 0xffffffc0;
1944   }
11831945         // 31       25      20      15      10     6        0
11841946         // --------------------------------------------------
11851947         // | 111010 | BBBBB | TTTTT | 01011 | IIII | Offset |
r6794r6795
11871949         //
11881950         // Stores one element from maximum of 8 vectors, while incrementing element index
11891951
1190         int element;
1191         int vs = dest;
1192         int ve = dest + 8;
1193         if (ve > 32)
1194            ve = 32;
1195
11961952         element = 8 - (index >> 1);
11971953         if (index & 0x1)   fatalerror("RSP: STV: index = %d at %08X\n", index, rsp->ppc);
11981954
r6794r6795
12091965            eaoffset += 2;
12101966            element++;
12111967         }
1212         break;
1213      }
1968}
12141969
1970static int generate_swc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1971{
1972   int loopdest;
1973   UINT32 op = desc->opptr.l[0];
1974   int dest = (op >> 16) & 0x1f;
1975   //int base = (op >> 21) & 0x1f;
1976   int index = (op >> 7) & 0xf;
1977   int offset = (op & 0x7f);
1978   //int skip;
1979   if (offset & 0x40)
1980   {
1981      offset |= 0xffffffc0;
1982   }
1983
1984   switch ((op >> 11) & 0x1f)
1985   {
1986      case 0x00:      /* SBV */
1987         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
1988         UML_CALLC(block, cfunc_rsp_sbv, rsp);
1989         return TRUE;
1990      case 0x01:      /* SSV */
1991#if (DRC_SSV)
1992         offset <<= 1;
1993         index >>= 1;
1994
1995         UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));                  // add     i0,<rsreg>,offset
1996         UML_SHR(block, IREG(0), IREG(0), IMM(1));                        // shr     i0,i0,1
1997         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE_XOR_BE(0)));               // xor     i0,i0,byte4xor
1998         UML_STORE(block, rsp->impstate->dmem, IREG(0), VSX(dest, index), WORD);   // store   dmem,i0,v[dest].s[index],word
1999         return TRUE;
2000#else
2001         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2002         UML_CALLC(block, cfunc_rsp_ssv, rsp);
2003         return TRUE;
2004#endif
2005      case 0x02:      /* SLV */
2006#if (DRC_SLV)
2007         offset <<= 2;
2008         index >>= 2;
2009
2010         UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));                  // add     i0,<rsreg>,offset
2011         UML_MOV(block, IREG(1), VLX(dest, index));                        // mov     i1,<rtreg>
2012         UML_CALLH(block, rsp->impstate->write32);                        // callh   write32
2013         return TRUE;
2014#else
2015         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2016         UML_CALLC(block, cfunc_rsp_slv, rsp);
2017         return TRUE;
2018#endif
2019      case 0x03:      /* SDV */
2020#if (DRC_SDV)
2021         offset <<= 3;
2022         index >>= 2;
2023
2024         UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));                  // add     i0,<rsreg>,offset
2025         UML_MOV(block, IREG(1), VLX(dest, index));                        // mov     i1,<rtreg>
2026         UML_CALLH(block, rsp->impstate->write32);                        // callh   write32
2027
2028         UML_ADD(block, IREG(0), R32(RSREG), IMM(offset));                  // add     i0,<rsreg>,offset
2029         UML_ADD(block, IREG(0), IREG(0), IMM(4));                        // add     i0,i0,4
2030         UML_MOV(block, IREG(1), VLX(dest, index+1));                        // mov     i1,<rtreg>
2031         UML_CALLH(block, rsp->impstate->write32);                        // callh   write32
2032         return TRUE;
2033#else
2034         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2035         UML_CALLC(block, cfunc_rsp_sdv, rsp);
2036         return TRUE;
2037#endif
2038      case 0x04:      /* SQV */
2039#if (DRC_SQV)
2040         offset <<= 4;
2041
2042         UML_ADD(block, MEM(&rsp->impstate->arg0), R32(RSREG), IMM(offset));      // mov     arg0,<rsreg>,offset
2043         UML_MOV(block, IREG(3), IMM(index));                           // mov     i3,index
2044         UML_MOV(block, IREG(2), MEM(&rsp->impstate->arg0));                  // mov     i2,arg0
2045         UML_AND(block, IREG(2), IREG(2), IMM(0x0000000f));                  // and     i2,i2,0x0000000f
2046         UML_SUB(block, IREG(2), IMM(16), IREG(2));                        // sub     i2,16,i2
2047         UML_ADD(block, IREG(2), IREG(2), IREG(3));                        // add     i2,i2,i3
2048         UML_CMP(block, IREG(2), IMM(16));                              // cmp     i2,16
2049         UML_TEST(block, IREG(2), IMM(0xfffffff0));                        // test    i2,0xfffffff0
2050         UML_MOVc(block, IF_NZ, IREG(2), IMM(16));                        // mov     NZ,i2,16
2051
2052      UML_LABEL(block, loopdest = compiler->labelnum++);                     // loopdest:
2053         UML_MOV(block, IREG(0), MEM(&rsp->impstate->arg0));                  // mov     i0,arg0
2054         UML_SUB(block, IREG(1), IMM(15), IREG(3));                        // sub     i1,15,i3
2055         UML_LOAD(block, IREG(1), &rsp->v[dest].b[0], IREG(1), BYTE);         // load    i1,v[dest].b[0],i1,byte
2056         UML_CALLH(block, rsp->impstate->write8);                        // callh   read8
2057
2058         UML_ADD(block, MEM(&rsp->impstate->arg0), MEM(&rsp->impstate->arg0), IMM(1));
2059         UML_ADD(block, IREG(3), IREG(3), IMM(1));                        // add     i3,i3,1
2060         UML_CMP(block, IREG(3), IREG(2));                              // cmp     i3,i2
2061         UML_JMPc(block, IF_L, loopdest);                              // jmp     L,loopdest
2062         return TRUE;
2063#else
2064         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2065         UML_CALLC(block, cfunc_rsp_sqv, rsp);
2066#endif
2067         return TRUE;
2068      case 0x05:      /* SRV */
2069         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2070         UML_CALLC(block, cfunc_rsp_srv, rsp);
2071         return TRUE;
2072      case 0x06:      /* SPV */
2073         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2074         UML_CALLC(block, cfunc_rsp_spv, rsp);
2075         return TRUE;
2076      case 0x07:      /* SUV */
2077         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2078         UML_CALLC(block, cfunc_rsp_suv, rsp);
2079         return TRUE;
2080      case 0x08:      /* SHV */
2081         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2082         UML_CALLC(block, cfunc_rsp_shv, rsp);
2083         return TRUE;
2084      case 0x09:      /* SFV */
2085         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2086         UML_CALLC(block, cfunc_rsp_sfv, rsp);
2087         return TRUE;
2088      case 0x0a:      /* SWV */
2089         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2090         UML_CALLC(block, cfunc_rsp_swv, rsp);
2091         return TRUE;
2092      case 0x0b:      /* STV */
2093         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
2094         UML_CALLC(block, cfunc_rsp_stv, rsp);
2095         return TRUE;
2096
12152097      default:
1216      {
12172098         unimplemented_opcode(rsp, op);
1218         break;
1219      }
2099         return FALSE;
12202100   }
2101
2102   return TRUE;
12212103}
12222104
1223INLINE UINT16 SATURATE_ACCUM_SIGNED(rsp_state *rsp, int accum, int slice)
2105#if (DRC_VMADN)
2106static void generate_saturate_accum_unsigned(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int accum)
12242107{
1225   if (ACCUM(accum).h.high < 0)
2108   int skip, skip2;
2109
2110   UML_CMP(block, VACCUMWMH(accum), IMM(-32768));
2111   UML_JMPc(block, IF_GE, skip = compiler->labelnum++);
2112   UML_MOV(block, IREG(0), IMM(0));
2113   UML_JMP(block, skip2 = compiler->labelnum++);
2114
2115   UML_LABEL(block, skip);
2116   UML_CMP(block, VACCUMWMH(accum), IMM(32767));
2117   UML_JMPc(block, IF_L, skip = compiler->labelnum++);
2118   UML_MOV(block, IREG(0), IMM(0x0000ffff));
2119   UML_JMP(block, skip2);
2120
2121   UML_LABEL(block, skip);
2122   UML_SEXT(block, IREG(0), VACCUMHL(accum), WORD);
2123   UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff));
2124   UML_LABEL(block, skip2);
2125}
2126#endif
2127
2128INLINE UINT16 SATURATE_ACCUM_UNSIGNED(rsp_state *rsp, int accum)
2129{
2130   if (ACCUM(accum).w.mh < -32768)
12262131   {
1227      if ((UINT16)ACCUM(accum).h.high != 0xffff)
1228      {
1229         return 0x8000;
1230      }
1231      else
1232      {
1233         if (ACCUM(accum).h.mid >= 0)
1234         {
1235            return 0x8000;
1236         }
1237         else
1238         {
1239            if (slice == 0)
1240            {
1241               return ACCUM(accum).h.low;
1242            }
1243            else if (slice == 1)
1244            {
1245               return ACCUM(accum).h.mid;
1246            }
1247         }
1248      }
2132      return 0;
12492133   }
2134   else if(ACCUM(accum).w.mh > 32767)
2135   {
2136      return 0xffff;
2137   }
12502138   else
12512139   {
1252      if ((UINT16)ACCUM(accum).h.high != 0)
1253      {
1254         return 0x7fff;
1255      }
1256      else
1257      {
1258         if (ACCUM(accum).h.mid < 0)
1259         {
1260            return 0x7fff;
1261         }
1262         else
1263         {
1264            if (slice == 0)
1265            {
1266               return ACCUM(accum).h.low;
1267            }
1268            else
1269            {
1270               return ACCUM(accum).h.mid;
1271            }
1272         }
1273      }
2140      return ACCUM(accum).h.low;
12742141   }
2142}
12752143
1276   return 0;
2144#if (DRC_VMADH) || (DRC_VMADM)
2145static void generate_saturate_accum_signed(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, int accum)
2146{
2147   int skip, skip2;
2148
2149   UML_CMP(block, VACCUMWMH(accum), IMM(-32768));
2150   UML_JMPc(block, IF_GE, skip = compiler->labelnum++);
2151   UML_MOV(block, IREG(0), IMM(0x00008000));
2152   UML_JMP(block, skip2 = compiler->labelnum++);
2153
2154   UML_LABEL(block, skip);
2155   UML_CMP(block, VACCUMWMH(accum), IMM(32767));
2156   UML_JMPc(block, IF_L, skip = compiler->labelnum++);
2157   UML_MOV(block, IREG(0), IMM(0x00007fff));
2158   UML_JMP(block, skip2);
2159
2160   UML_LABEL(block, skip);
2161   UML_SEXT(block, IREG(0), VACCUMHM(accum), WORD);
2162   UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff));
2163   UML_LABEL(block, skip2);
12772164}
2165#endif
12782166
1279INLINE UINT16 SATURATE_ACCUM_UNSIGNED(rsp_state *rsp, int accum, int slice)
2167INLINE UINT16 SATURATE_ACCUM_SIGNED(rsp_state *rsp, int accum)
12802168{
1281   if (ACCUM(accum).h.high < 0)
2169   if (ACCUM(accum).w.mh < -32768)
12822170   {
1283      if ((UINT16)ACCUM(accum).h.high != 0xffff)
1284      {
1285         return 0;
1286      }
1287      else
1288      {
1289         if (ACCUM(accum).h.mid >= 0)
1290         {
1291            return 0;
1292         }
1293         else
1294         {
1295            if (slice == 0)
1296            {
1297               return ACCUM(accum).h.low;
1298            }
1299            else if (slice == 1)
1300            {
1301               return ACCUM(accum).h.mid;
1302            }
1303         }
1304      }
2171      return 0x8000;
13052172   }
1306   else
2173   if(ACCUM(accum).w.mh > 32767)
13072174   {
1308      if ((UINT16)ACCUM(accum).h.high != 0)
1309      {
1310         return 0xffff;
1311      }
1312      else
1313      {
1314         if (ACCUM(accum).h.mid < 0)
1315         {
1316            return 0xffff;
1317         }
1318         else
1319         {
1320            if (slice == 0)
1321            {
1322               return ACCUM(accum).h.low;
1323            }
1324            else
1325            {
1326               return ACCUM(accum).h.mid;
1327            }
1328         }
1329      }
2175      return 0x7fff;
13302176   }
1331
1332   return 0;
2177   return ACCUM(accum).h.mid;
13332178}
13342179
13352180#define WRITEBACK_RESULT()                \
13362181   do {                           \
1337      W_VREG_S(VDREG, 0, vres[0]);         \
1338      W_VREG_S(VDREG, 1, vres[1]);         \
1339      W_VREG_S(VDREG, 2, vres[2]);         \
1340      W_VREG_S(VDREG, 3, vres[3]);         \
1341      W_VREG_S(VDREG, 4, vres[4]);         \
1342      W_VREG_S(VDREG, 5, vres[5]);         \
1343      W_VREG_S(VDREG, 6, vres[6]);         \
1344      W_VREG_S(VDREG, 7, vres[7]);         \
2182      W_VREG_S_X(VDREG, 7, vres[0]);         \
2183      W_VREG_S_X(VDREG, 6, vres[1]);         \
2184      W_VREG_S_X(VDREG, 5, vres[2]);         \
2185      W_VREG_S_X(VDREG, 4, vres[3]);         \
2186      W_VREG_S_X(VDREG, 3, vres[4]);         \
2187      W_VREG_S_X(VDREG, 2, vres[5]);         \
2188      W_VREG_S_X(VDREG, 1, vres[6]);         \
2189      W_VREG_S_X(VDREG, 0, vres[7]);         \
13452190   } while(0)
13462191
13472192#if 0
r6794r6795
13622207}
13632208#endif
13642209
1365INLINE void rsp_vmulf(rsp_state *rsp, UINT32 op, INT16 *vres)
2210#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) \
2211   { \
2212      INT16 v1, v2; \
2213      v1 = R_VREG_S_X(VS1REG, I0); v2 = R_VREG_S_X(VS2REG, E20); \
2214      if (v1 == -32768 && v2 == -32768) { ACCUM(E10).l = 0x0000800080000000LL; vres[E10] = 0x7fff; } \
2215      else { ACCUM(E10).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E10] = ACCUM(E10).h.mid; } \
2216      v1 = R_VREG_S_X(VS1REG, I1); v2 = R_VREG_S_X(VS2REG, E21); \
2217      if (v1 == -32768 && v2 == -32768) { ACCUM(E11).l = 0x0000800080000000LL; vres[E11] = 0x7fff; } \
2218      else { ACCUM(E11).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E11] = ACCUM(E11).h.mid; } \
2219      v1 = R_VREG_S_X(VS1REG, I2); v2 = R_VREG_S_X(VS2REG, E22); \
2220      if (v1 == -32768 && v2 == -32768) { ACCUM(E12).l = 0x0000800080000000LL; vres[E12] = 0x7fff; } \
2221      else { ACCUM(E12).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E12] = ACCUM(E12).h.mid; } \
2222      v1 = R_VREG_S_X(VS1REG, I3); v2 = R_VREG_S_X(VS2REG, E23); \
2223      if (v1 == -32768 && v2 == -32768) { ACCUM(E13).l = 0x0000800080000000LL; vres[E13] = 0x7fff; } \
2224      else { ACCUM(E13).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E13] = ACCUM(E13).h.mid; } \
2225      v1 = R_VREG_S_X(VS1REG, I4); v2 = R_VREG_S_X(VS2REG, E24); \
2226      if (v1 == -32768 && v2 == -32768) { ACCUM(E14).l = 0x0000800080000000LL; vres[E14] = 0x7fff; } \
2227      else { ACCUM(E14).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E14] = ACCUM(E14).h.mid; } \
2228      v1 = R_VREG_S_X(VS1REG, I5); v2 = R_VREG_S_X(VS2REG, E25); \
2229      if (v1 == -32768 && v2 == -32768) { ACCUM(E15).l = 0x0000800080000000LL; vres[E15] = 0x7fff; } \
2230      else { ACCUM(E15).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E15] = ACCUM(E15).h.mid; } \
2231      v1 = R_VREG_S_X(VS1REG, I6); v2 = R_VREG_S_X(VS2REG, E26); \
2232      if (v1 == -32768 && v2 == -32768) { ACCUM(E16).l = 0x0000800080000000LL; vres[E16] = 0x7fff; } \
2233      else { ACCUM(E16).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E16] = ACCUM(E16).h.mid; } \
2234      v1 = R_VREG_S_X(VS1REG, I7); v2 = R_VREG_S_X(VS2REG, E27); \
2235      if (v1 == -32768 && v2 == -32768) { ACCUM(E17).l = 0x0000800080000000LL; vres[E17] = 0x7fff; } \
2236      else { ACCUM(E17).l = ((INT64)((INT32)v1 * (INT32)v2) * 0x20000 + 0x80000000); vres[E17] = ACCUM(E17).h.mid; } \
2237   }
2238
2239INLINE void cfunc_rsp_vmulf(void *param)
13662240{
1367   int i;
2241   rsp_state *rsp = (rsp_state*)param;
2242   int op = rsp->impstate->arg0;
2243   INT16 vres[8] = { 0 };
2244   //int i;
13682245   // 31       25  24     20      15      10      5        0
13692246   // ------------------------------------------------------
13702247   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 000000 |
r6794r6795
13722249   //
13732250   // Multiplies signed integer by signed integer * 2
13742251
1375   for (i=0; i < 8; i++)
2252   switch(EL)
13762253   {
1377      int del = VEC_EL_1(EL, i);
1378      int sel = VEC_EL_2(EL, del);
1379      INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
1380      INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
1381      if (s1 == -32768 && s2 == -32768)
1382      {
1383         // overflow
1384         ACCUM(del).l = 0x0000800080000000LL;
1385         //W_ACCUM_H(del, 0);
1386         //W_ACCUM_M(del, -32768);
1387         //W_ACCUM_L(del, -32768);
1388         vres[del] = 0x7fff;
1389      }
1390      else
1391      {
1392         INT64 r =  s1 * s2 * 2;
1393         r += 0x8000;   // rounding ?
1394         W_ACCUM_H(del, (r < 0) ? 0xffff : 0);      // sign-extend to 48-bit
1395         W_ACCUM_M(del, (INT16)(r >> 16));
1396         W_ACCUM_L(del, (UINT16)(r));
1397         vres[del] = ACCUM(del).h.mid;
1398      }
2254        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
2255           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);
2256           break;
2257        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
2258           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);
2259           break;
2260        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2261           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);
2262           break;
2263        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2264           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);
2265           break;
2266        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2267           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);
2268           break;
2269        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2270           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);
2271           break;
2272        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2273           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);
2274           break;
2275        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2276           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);
2277           break;
2278        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
2279           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);
2280           break;
2281        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
2282           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);
2283           break;
2284        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
2285           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);
2286           break;
2287        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
2288           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);
2289           break;
2290        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
2291           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);
2292           break;
2293        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
2294           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);
2295           break;
2296        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
2297           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);
2298           break;
2299        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
2300           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);
2301           break;
13992302   }
2303
14002304   WRITEBACK_RESULT();
1401
14022305}
14032306
1404INLINE void rsp_vmulu(rsp_state *rsp, UINT32 op, INT16 *vres)
2307INLINE void cfunc_rsp_vmulu(void *param)
14052308{
2309   rsp_state *rsp = (rsp_state*)param;
2310   int op = rsp->impstate->arg0;
2311   INT16 vres[8];
14062312   int i;
14072313   // 31       25  24     20      15      10      5        0
14082314   // ------------------------------------------------------
r6794r6795
14162322      int sel = VEC_EL_2(EL, del);
14172323      INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
14182324      INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
1419      INT64 r = s1 * s2 * 2;
1420      r += 0x8000;   // rounding ?
2325      INT64 r = s1 * s2;
2326      r += 0x4000;   // rounding ?
14212327
1422      W_ACCUM_H(del, (UINT16)(r >> 32));
1423      W_ACCUM_M(del, (UINT16)(r >> 16));
1424      W_ACCUM_L(del, (UINT16)(r));
2328      ACCUM(del).l = r << 17;
14252329
14262330      if (r < 0)
14272331      {
r6794r6795
14302334      else if ((ACCUM(del).h.high ^ ACCUM(del).h.mid) < 0)
14312335      {
14322336         vres[del] = -1;
2337
14332338      }
14342339      else
14352340      {
r6794r6795
14392344   WRITEBACK_RESULT();
14402345}
14412346
1442INLINE void rsp_vmudl(rsp_state *rsp, UINT32 op, INT16 *vres)
2347#if (DRC_VMUDL)
2348/*------------------------------------------------------------------
2349    generate_vmudl
2350------------------------------------------------------------------*/
2351
2352#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) \
2353   { \
2354       UML_SEXT(block, IREG(1), VS(VS1REG, I0), WORD); \
2355       UML_SEXT(block, IREG(0), VS(VS2REG, E20), WORD); \
2356       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2357       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
2358      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2359      UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
2360      UML_DMOV(block, VACCUML(E10), IREG(0)); \
2361 \
2362       UML_SEXT(block, IREG(1), VS(VS1REG, I1), WORD); \
2363       UML_SEXT(block, IREG(0), VS(VS2REG, E21), WORD); \
2364       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2365       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
2366      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2367      UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
2368      UML_DMOV(block, VACCUML(E11), IREG(0)); \
2369 \
2370       UML_SEXT(block, IREG(1), VS(VS1REG, I2), WORD); \
2371       UML_SEXT(block, IREG(0), VS(VS2REG, E22), WORD); \
2372       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2373       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
2374      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2375      UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
2376      UML_DMOV(block, VACCUML(E12), IREG(0)); \
2377 \
2378       UML_SEXT(block, IREG(1), VS(VS1REG, I3), WORD); \
2379       UML_SEXT(block, IREG(0), VS(VS2REG, E23), WORD); \
2380       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2381       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
2382      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2383      UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
2384      UML_DMOV(block, VACCUML(E13), IREG(0)); \
2385 \
2386       UML_SEXT(block, IREG(1), VS(VS1REG, I4), WORD); \
2387       UML_SEXT(block, IREG(0), VS(VS2REG, E24), WORD); \
2388       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2389       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
2390      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2391      UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
2392      UML_DMOV(block, VACCUML(E14), IREG(0)); \
2393 \
2394       UML_SEXT(block, IREG(1), VS(VS1REG, I5), WORD); \
2395       UML_SEXT(block, IREG(0), VS(VS2REG, E25), WORD); \
2396       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2397       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
2398      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2399      UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
2400      UML_DMOV(block, VACCUML(E15), IREG(0)); \
2401 \
2402       UML_SEXT(block, IREG(1), VS(VS1REG, I6), WORD); \
2403       UML_SEXT(block, IREG(0), VS(VS2REG, E26), WORD); \
2404       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2405       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
2406      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2407      UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
2408      UML_DMOV(block, VACCUML(E16), IREG(0)); \
2409 \
2410       UML_SEXT(block, IREG(1), VS(VS1REG, I7), WORD); \
2411       UML_SEXT(block, IREG(0), VS(VS2REG, E27), WORD); \
2412       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2413       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
2414      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2415      UML_DAND(block, IREG(0), IREG(0), IMM(0x00000000ffff0000)); \
2416      UML_DMOV(block, VACCUML(E17), IREG(0)); \
2417 \
2418       UML_SEXT(block, IREG(0), VACCUMHL(E10), WORD); \
2419       UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
2420       UML_SEXT(block, IREG(0), VACCUMHL(E11), WORD); \
2421       UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
2422       UML_SEXT(block, IREG(0), VACCUMHL(E12), WORD); \
2423       UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
2424       UML_SEXT(block, IREG(0), VACCUMHL(E13), WORD); \
2425       UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
2426       UML_SEXT(block, IREG(0), VACCUMHL(E14), WORD); \
2427       UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
2428       UML_SEXT(block, IREG(0), VACCUMHL(E15), WORD); \
2429       UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
2430       UML_SEXT(block, IREG(0), VACCUMHL(E16), WORD); \
2431       UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
2432       UML_SEXT(block, IREG(0), VACCUMHL(E17), WORD); \
2433       UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
2434   }
2435
2436static int generate_vmudl(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)   // vmudl
14432437{
1444   int i;
2438   UINT32 op = desc->opptr.l[0];
2439
14452440   // 31       25  24     20      15      10      5        0
14462441   // ------------------------------------------------------
1447   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 000100 |
2442   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
14482443   // ------------------------------------------------------
14492444   //
1450   // Multiplies unsigned fraction by unsigned fraction
1451   // Stores the higher 16 bits of the 32-bit result to accumulator
1452   // The low slice of accumulator is stored into destination element
2445   // Multiplies signed integer by unsigned fraction
2446   // The result is added into accumulator
2447   // The middle slice of accumulator is stored into destination element
2448   switch(EL)
2449   {
2450        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
2451           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);
2452           return TRUE;
2453        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
2454           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);
2455           return TRUE;
2456        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2457           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);
2458           return TRUE;
2459        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2460           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);
2461           return TRUE;
2462        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2463           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);
2464           return TRUE;
2465        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2466           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);
2467           return TRUE;
2468        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2469           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);
2470           return TRUE;
2471        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2472           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);
2473           return TRUE;
2474        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
2475           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);
2476           return TRUE;
2477        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
2478           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);
2479           return TRUE;
2480        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
2481           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);
2482           return TRUE;
2483        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
2484           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);
2485           return TRUE;
2486        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
2487           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);
2488           return TRUE;
2489        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
2490           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);
2491           return TRUE;
2492        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
2493           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);
2494           return TRUE;
2495        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
2496           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);
2497           return TRUE;
2498   }
14532499
1454   for (i=0; i < 8; i++)
2500   return TRUE;
2501}
2502#else
2503#define RSP_VMUDL(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
2504   { \
2505      ACCUM(E10).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E10) * (UINT32)(UINT16)R_VREG_S(VS2REG, E20)) & 0xffff0000); \
2506      ACCUM(E11).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E11) * (UINT32)(UINT16)R_VREG_S(VS2REG, E21)) & 0xffff0000); \
2507      ACCUM(E12).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E12) * (UINT32)(UINT16)R_VREG_S(VS2REG, E22)) & 0xffff0000); \
2508      ACCUM(E13).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E13) * (UINT32)(UINT16)R_VREG_S(VS2REG, E23)) & 0xffff0000); \
2509      ACCUM(E14).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E14) * (UINT32)(UINT16)R_VREG_S(VS2REG, E24)) & 0xffff0000); \
2510      ACCUM(E15).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E15) * (UINT32)(UINT16)R_VREG_S(VS2REG, E25)) & 0xffff0000); \
2511      ACCUM(E16).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E16) * (UINT32)(UINT16)R_VREG_S(VS2REG, E26)) & 0xffff0000); \
2512      ACCUM(E17).l = (((UINT32)(UINT16)R_VREG_S(VS1REG, E17) * (UINT32)(UINT16)R_VREG_S(VS2REG, E27)) & 0xffff0000); \
2513      W_VREG_S(VDREG, E10, ACCUM(E10).h.low);         \
2514      W_VREG_S(VDREG, E11, ACCUM(E11).h.low);         \
2515      W_VREG_S(VDREG, E12, ACCUM(E12).h.low);         \
2516      W_VREG_S(VDREG, E13, ACCUM(E13).h.low);         \
2517      W_VREG_S(VDREG, E14, ACCUM(E14).h.low);         \
2518      W_VREG_S(VDREG, E15, ACCUM(E15).h.low);         \
2519      W_VREG_S(VDREG, E16, ACCUM(E16).h.low);         \
2520      W_VREG_S(VDREG, E17, ACCUM(E17).h.low);         \
2521   }
2522
2523INLINE void cfunc_rsp_vmudl(void *param)
2524{
2525   rsp_state *rsp = (rsp_state*)param;
2526   int op = rsp->impstate->arg0;
2527   // 31       25  24     20      15      10      5        0
2528   // ------------------------------------------------------
2529   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001101 |
2530   // ------------------------------------------------------
2531   //
2532   // Multiplies signed integer by unsigned fraction
2533   // The result is added into accumulator
2534   // The middle slice of accumulator is stored into destination element
2535
2536   switch(EL)
14552537   {
1456      int del = VEC_EL_1(EL, i);
1457      int sel = VEC_EL_2(EL, del);
1458      UINT32 s1 = (UINT32)(UINT16)R_VREG_S(VS1REG, del);
1459      UINT32 s2 = (UINT32)(UINT16)R_VREG_S(VS2REG, sel);
1460      UINT32 r = s1 * s2;
2538        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
2539           RSP_VMUDL(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
2540           break;
2541        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
2542           RSP_VMUDL(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
2543           break;
2544        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2545           RSP_VMUDL(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
2546           break;
2547        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2548           RSP_VMUDL(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
2549           break;
2550        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2551           RSP_VMUDL(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
2552           break;
2553        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2554           RSP_VMUDL(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
2555           break;
2556        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2557           RSP_VMUDL(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
2558           break;
2559        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2560           RSP_VMUDL(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
2561           break;
2562        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
2563           RSP_VMUDL(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2564           break;
2565        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
2566           RSP_VMUDL(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2567           break;
2568        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
2569           RSP_VMUDL(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
2570           break;
2571        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
2572           RSP_VMUDL(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
2573           break;
2574        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
2575           RSP_VMUDL(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
2576           break;
2577        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
2578           RSP_VMUDL(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
2579           break;
2580        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
2581           RSP_VMUDL(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
2582           break;
2583        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
2584           RSP_VMUDL(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
2585           break;
2586   }
2587}
2588#endif
14612589
1462      W_ACCUM_H(del, 0);
1463      W_ACCUM_M(del, 0);
1464      W_ACCUM_L(del, (UINT16)(r >> 16));
2590#if (DRC_VMUDM)
2591/*------------------------------------------------------------------
2592    generate_vmudm
2593------------------------------------------------------------------*/
14652594
1466      vres[del] = ACCUM(del).h.low;
2595#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) \
2596   { \
2597       UML_SEXT(block, IREG(1), VS(VS1REG, I0), WORD); \
2598       UML_SEXT(block, IREG(0), VS(VS2REG, E20), WORD); \
2599       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2600      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2601      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
2602      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
2603      UML_DMOV(block, VACCUML(E10), IREG(0)); \
2604 \
2605       UML_SEXT(block, IREG(1), VS(VS1REG, I1), WORD); \
2606       UML_SEXT(block, IREG(0), VS(VS2REG, E21), WORD); \
2607       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2608      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2609      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
2610      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
2611      UML_DMOV(block, VACCUML(E11), IREG(0)); \
2612 \
2613       UML_SEXT(block, IREG(1), VS(VS1REG, I2), WORD); \
2614       UML_SEXT(block, IREG(0), VS(VS2REG, E22), WORD); \
2615       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2616      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2617      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
2618      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
2619      UML_DMOV(block, VACCUML(E12), IREG(0)); \
2620 \
2621       UML_SEXT(block, IREG(1), VS(VS1REG, I3), WORD); \
2622       UML_SEXT(block, IREG(0), VS(VS2REG, E23), WORD); \
2623       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2624      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2625      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
2626      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
2627      UML_DMOV(block, VACCUML(E13), IREG(0)); \
2628 \
2629       UML_SEXT(block, IREG(1), VS(VS1REG, I4), WORD); \
2630       UML_SEXT(block, IREG(0), VS(VS2REG, E24), WORD); \
2631       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2632      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2633      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
2634      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
2635      UML_DMOV(block, VACCUML(E14), IREG(0)); \
2636 \
2637       UML_SEXT(block, IREG(1), VS(VS1REG, I5), WORD); \
2638       UML_SEXT(block, IREG(0), VS(VS2REG, E25), WORD); \
2639       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2640      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2641      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
2642      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
2643      UML_DMOV(block, VACCUML(E15), IREG(0)); \
2644 \
2645       UML_SEXT(block, IREG(1), VS(VS1REG, I6), WORD); \
2646       UML_SEXT(block, IREG(0), VS(VS2REG, E26), WORD); \
2647       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2648      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2649      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
2650      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
2651      UML_DMOV(block, VACCUML(E16), IREG(0)); \
2652 \
2653       UML_SEXT(block, IREG(1), VS(VS1REG, I7), WORD); \
2654       UML_SEXT(block, IREG(0), VS(VS2REG, E27), WORD); \
2655       UML_AND(block, IREG(0), IREG(0), IMM(0x0000ffff)); \
2656      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
2657      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
2658      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
2659      UML_DMOV(block, VACCUML(E17), IREG(0)); \
2660 \
2661       UML_SEXT(block, IREG(0), VACCUMHM(E10), WORD); \
2662       UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
2663       UML_SEXT(block, IREG(0), VACCUMHM(E11), WORD); \
2664       UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
2665       UML_SEXT(block, IREG(0), VACCUMHM(E12), WORD); \
2666       UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
2667       UML_SEXT(block, IREG(0), VACCUMHM(E13), WORD); \
2668       UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
2669       UML_SEXT(block, IREG(0), VACCUMHM(E14), WORD); \
2670       UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
2671       UML_SEXT(block, IREG(0), VACCUMHM(E15), WORD); \
2672       UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
2673       UML_SEXT(block, IREG(0), VACCUMHM(E16), WORD); \
2674       UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
2675       UML_SEXT(block, IREG(0), VACCUMHM(E17), WORD); \
2676       UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
14672677   }
1468   WRITEBACK_RESULT();
2678
2679static int generate_vmudm(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)   // vmudl
2680{
2681   UINT32 op = desc->opptr.l[0];
2682
2683   // 31       25  24     20      15      10      5        0
2684   // ------------------------------------------------------
2685   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
2686   // ------------------------------------------------------
2687   //
2688   // Multiplies signed integer by unsigned fraction
2689   // The result is stored into accumulator
2690   // The middle slice of accumulator is stored into destination element
2691   switch(EL)
2692   {
2693        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
2694           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);
2695           return TRUE;
2696        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
2697           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);
2698           return TRUE;
2699        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2700           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);
2701           return TRUE;
2702        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2703           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);
2704           return TRUE;
2705        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2706           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);
2707           return TRUE;
2708        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2709           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);
2710           return TRUE;
2711        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2712           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);
2713           return TRUE;
2714        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2715           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);
2716           return TRUE;
2717        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
2718           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);
2719           return TRUE;
2720        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
2721           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);
2722           return TRUE;
2723        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
2724           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);
2725           return TRUE;
2726        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
2727           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);
2728           return TRUE;
2729        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
2730           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);
2731           return TRUE;
2732        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
2733           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);
2734           return TRUE;
2735        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
2736           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);
2737           return TRUE;
2738        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
2739           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);
2740           return TRUE;
2741   }
2742
2743   return TRUE;
14692744}
2745#else
2746#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) \
2747   { \
2748      ACCUM(E10).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I0) * (UINT16)R_VREG_S_X(VS2REG, E20)) << 16; \
2749      ACCUM(E11).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I1) * (UINT16)R_VREG_S_X(VS2REG, E21)) << 16; \
2750      ACCUM(E12).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I2) * (UINT16)R_VREG_S_X(VS2REG, E22)) << 16; \
2751      ACCUM(E13).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I3) * (UINT16)R_VREG_S_X(VS2REG, E23)) << 16; \
2752      ACCUM(E14).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I4) * (UINT16)R_VREG_S_X(VS2REG, E24)) << 16; \
2753      ACCUM(E15).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I5) * (UINT16)R_VREG_S_X(VS2REG, E25)) << 16; \
2754      ACCUM(E16).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I6) * (UINT16)R_VREG_S_X(VS2REG, E26)) << 16; \
2755      ACCUM(E17).l = (INT64)((INT32)(INT16)R_VREG_S_X(VS1REG, I7) * (UINT16)R_VREG_S_X(VS2REG, E27)) << 16; \
2756      W_VREG_S_X(VDREG, I0, ACCUM(E10).h.mid);         \
2757      W_VREG_S_X(VDREG, I1, ACCUM(E11).h.mid);         \
2758      W_VREG_S_X(VDREG, I2, ACCUM(E12).h.mid);         \
2759      W_VREG_S_X(VDREG, I3, ACCUM(E13).h.mid);         \
2760      W_VREG_S_X(VDREG, I4, ACCUM(E14).h.mid);         \
2761      W_VREG_S_X(VDREG, I5, ACCUM(E15).h.mid);         \
2762      W_VREG_S_X(VDREG, I6, ACCUM(E16).h.mid);         \
2763      W_VREG_S_X(VDREG, I7, ACCUM(E17).h.mid);         \
2764   }
14702765
1471INLINE void rsp_vmudm(rsp_state *rsp, UINT32 op, INT16 *vres)
2766INLINE void cfunc_rsp_vmudm(void *param)
14722767{
1473   int i;
2768   rsp_state *rsp = (rsp_state*)param;
2769   int op = rsp->impstate->arg0;
2770   //int i;
14742771   // 31       25  24     20      15      10      5        0
14752772   // ------------------------------------------------------
14762773   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 000101 |
r6794r6795
14802777   // The result is stored into accumulator
14812778   // The middle slice of accumulator is stored into destination element
14822779
2780   switch(EL)
2781   {
2782        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
2783           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);
2784           break;
2785        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
2786           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);
2787           break;
2788        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2789           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);
2790           break;
2791        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2792           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);
2793           break;
2794        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2795           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);
2796           break;
2797        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2798           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);
2799           break;
2800        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2801           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);
2802           break;
2803        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2804           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);
2805           break;
2806        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
2807           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);
2808           break;
2809        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
2810           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);
2811           break;
2812        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
2813           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);
2814           break;
2815        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
2816           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);
2817           break;
2818        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
2819           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);
2820           break;
2821        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
2822           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);
2823           break;
2824        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
2825           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);
2826           break;
2827        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
2828           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);
2829           break;
2830   }
2831
2832   /*
14832833   for (i=0; i < 8; i++)
14842834   {
14852835      int del = VEC_EL_1(EL, i);
r6794r6795
14952845      vres[del] = ACCUM(del).h.mid;
14962846   }
14972847   WRITEBACK_RESULT();
1498
2848   */
14992849}
2850#endif
15002851
1501INLINE void rsp_vmudn(rsp_state *rsp, UINT32 op, INT16 *vres)
2852#define RSP_VMUDN(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
2853   { \
2854      ACCUM(E10).l = ((UINT16)R_VREG_S(VS1REG, E10) * (INT64)(INT16)R_VREG_S(VS2REG, E20)) << 16; \
2855      ACCUM(E11).l = ((UINT16)R_VREG_S(VS1REG, E11) * (INT64)(INT16)R_VREG_S(VS2REG, E21)) << 16; \
2856      ACCUM(E12).l = ((UINT16)R_VREG_S(VS1REG, E12) * (INT64)(INT16)R_VREG_S(VS2REG, E22)) << 16; \
2857      ACCUM(E13).l = ((UINT16)R_VREG_S(VS1REG, E13) * (INT64)(INT16)R_VREG_S(VS2REG, E23)) << 16; \
2858      ACCUM(E14).l = ((UINT16)R_VREG_S(VS1REG, E14) * (INT64)(INT16)R_VREG_S(VS2REG, E24)) << 16; \
2859      ACCUM(E15).l = ((UINT16)R_VREG_S(VS1REG, E15) * (INT64)(INT16)R_VREG_S(VS2REG, E25)) << 16; \
2860      ACCUM(E16).l = ((UINT16)R_VREG_S(VS1REG, E16) * (INT64)(INT16)R_VREG_S(VS2REG, E26)) << 16; \
2861      ACCUM(E17).l = ((UINT16)R_VREG_S(VS1REG, E17) * (INT64)(INT16)R_VREG_S(VS2REG, E27)) << 16; \
2862      W_VREG_S(VDREG, E10, ACCUM(E10).h.low);         \
2863      W_VREG_S(VDREG, E11, ACCUM(E11).h.low);         \
2864      W_VREG_S(VDREG, E12, ACCUM(E12).h.low);         \
2865      W_VREG_S(VDREG, E13, ACCUM(E13).h.low);         \
2866      W_VREG_S(VDREG, E14, ACCUM(E14).h.low);         \
2867      W_VREG_S(VDREG, E15, ACCUM(E15).h.low);         \
2868      W_VREG_S(VDREG, E16, ACCUM(E16).h.low);         \
2869      W_VREG_S(VDREG, E17, ACCUM(E17).h.low);         \
2870   }
2871
2872INLINE void cfunc_rsp_vmudn(void *param)
15022873{
1503   int i;
2874   rsp_state *rsp = (rsp_state*)param;
2875   int op = rsp->impstate->arg0;
15042876   // 31       25  24     20      15      10      5        0
15052877   // ------------------------------------------------------
15062878   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 000110 |
r6794r6795
15102882   // The result is stored into accumulator
15112883   // The low slice of accumulator is stored into destination element
15122884
1513   for (i=0; i < 8; i++)
2885   switch(EL)
15142886   {
1515      int del = VEC_EL_1(EL, i);
1516      int sel = VEC_EL_2(EL, del);
1517      INT32 s1 = (UINT16)R_VREG_S(VS1REG, del);      // not sign-extended
1518      INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
1519      INT32 r = s1 * s2;
1520
1521      W_ACCUM_H(del, (r < 0) ? 0xffff : 0);      // sign-extend to 48-bit
1522      W_ACCUM_M(del, (INT16)(r >> 16));
1523      W_ACCUM_L(del, (UINT16)(r));
1524
1525      vres[del] = ACCUM(del).h.low;
2887        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
2888           RSP_VMUDN(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
2889           break;
2890        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
2891           RSP_VMUDN(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
2892           break;
2893        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2894           RSP_VMUDN(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
2895           break;
2896        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2897           RSP_VMUDN(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
2898           break;
2899        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2900           RSP_VMUDN(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
2901           break;
2902        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2903           RSP_VMUDN(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
2904           break;
2905        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2906           RSP_VMUDN(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
2907           break;
2908        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2909           RSP_VMUDN(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
2910           break;
2911        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
2912           RSP_VMUDN(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
2913           break;
2914        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
2915           RSP_VMUDN(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
2916           break;
2917        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
2918           RSP_VMUDN(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
2919           break;
2920        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
2921           RSP_VMUDN(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
2922           break;
2923        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
2924           RSP_VMUDN(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
2925           break;
2926        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
2927           RSP_VMUDN(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
2928           break;
2929        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
2930           RSP_VMUDN(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
2931           break;
2932        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
2933           RSP_VMUDN(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
2934           break;
15262935   }
1527   WRITEBACK_RESULT();
15282936}
15292937
1530INLINE void rsp_vmudh(rsp_state *rsp, UINT32 op, INT16 *vres)
2938INLINE void cfunc_rsp_vmudh(void *param)
15312939{
2940   rsp_state *rsp = (rsp_state*)param;
2941   int op = rsp->impstate->arg0;
2942   INT16 vres[8];
15322943   int i;
15332944   // 31       25  24     20      15      10      5        0
15342945   // ------------------------------------------------------
r6794r6795
15582969   WRITEBACK_RESULT();
15592970}
15602971
1561INLINE void rsp_vmacf(rsp_state *rsp, UINT32 op, INT16 *vres)
2972#define RSP_VMACF(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
2973   { \
2974      ACCUM(E10).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E10) * (INT32)(INT16)R_VREG_S(VS2REG, E20)) << 17; \
2975      ACCUM(E11).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E11) * (INT32)(INT16)R_VREG_S(VS2REG, E21)) << 17; \
2976      ACCUM(E12).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E12) * (INT32)(INT16)R_VREG_S(VS2REG, E22)) << 17; \
2977      ACCUM(E13).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E13) * (INT32)(INT16)R_VREG_S(VS2REG, E23)) << 17; \
2978      ACCUM(E14).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E14) * (INT32)(INT16)R_VREG_S(VS2REG, E24)) << 17; \
2979      ACCUM(E15).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E15) * (INT32)(INT16)R_VREG_S(VS2REG, E25)) << 17; \
2980      ACCUM(E16).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E16) * (INT32)(INT16)R_VREG_S(VS2REG, E26)) << 17; \
2981      ACCUM(E17).l += (INT64)((INT32)(INT16)R_VREG_S(VS1REG, E17) * (INT32)(INT16)R_VREG_S(VS2REG, E27)) << 17; \
2982      vres[E10] = SATURATE_ACCUM_SIGNED(rsp, E10); \
2983      vres[E11] = SATURATE_ACCUM_SIGNED(rsp, E11); \
2984      vres[E12] = SATURATE_ACCUM_SIGNED(rsp, E12); \
2985      vres[E13] = SATURATE_ACCUM_SIGNED(rsp, E13); \
2986      vres[E14] = SATURATE_ACCUM_SIGNED(rsp, E14); \
2987      vres[E15] = SATURATE_ACCUM_SIGNED(rsp, E15); \
2988      vres[E16] = SATURATE_ACCUM_SIGNED(rsp, E16); \
2989      vres[E17] = SATURATE_ACCUM_SIGNED(rsp, E17); \
2990      W_VREG_S_X(VDREG, 7, vres[0]);         \
2991      W_VREG_S_X(VDREG, 6, vres[1]);         \
2992      W_VREG_S_X(VDREG, 5, vres[2]);         \
2993      W_VREG_S_X(VDREG, 4, vres[3]);         \
2994      W_VREG_S_X(VDREG, 3, vres[4]);         \
2995      W_VREG_S_X(VDREG, 2, vres[5]);         \
2996      W_VREG_S_X(VDREG, 1, vres[6]);         \
2997      W_VREG_S_X(VDREG, 0, vres[7]);         \
2998   }
2999
3000INLINE void cfunc_rsp_vmacf(void *param)
15623001{
1563   int i;
3002   rsp_state *rsp = (rsp_state*)param;
3003   int op = rsp->impstate->arg0;
3004   INT16 vres[8];
3005   //int i;
15643006   // 31       25  24     20      15      10      5        0
15653007   // ------------------------------------------------------
15663008   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001000 |
r6794r6795
15693011   // Multiplies signed integer by signed integer * 2
15703012   // The result is added to accumulator
15713013
3014   switch(EL)
3015   {
3016        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
3017           RSP_VMACF(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
3018           break;
3019        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
3020           RSP_VMACF(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
3021           break;
3022        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
3023           RSP_VMACF(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
3024           break;
3025        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
3026           RSP_VMACF(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
3027           break;
3028        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
3029           RSP_VMACF(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
3030           break;
3031        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
3032           RSP_VMACF(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
3033           break;
3034        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
3035           RSP_VMACF(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
3036           break;
3037        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
3038           RSP_VMACF(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
3039           break;
3040        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
3041           RSP_VMACF(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3042           break;
3043        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
3044           RSP_VMACF(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
3045           break;
3046        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
3047           RSP_VMACF(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
3048           break;
3049        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
3050           RSP_VMACF(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
3051           break;
3052        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
3053           RSP_VMACF(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
3054           break;
3055        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
3056           RSP_VMACF(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
3057           break;
3058        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
3059           RSP_VMACF(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
3060           break;
3061        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
3062           RSP_VMACF(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
3063           break;
3064   }
3065#if 0
15723066   for (i=0; i < 8; i++)
15733067   {
15743068      UINT16 res;
r6794r6795
15793073      INT32 r = s1 * s2;
15803074
15813075      ACCUM(del).l += (INT64)(r) << 17;
1582      //ACCUM(del) += (INT64)(r) << 17;
1583      res = SATURATE_ACCUM_SIGNED(rsp, del, 1);
3076      res = SATURATE_ACCUM_SIGNED(rsp, del);
15843077
15853078      vres[del] = res;
15863079   }
15873080   WRITEBACK_RESULT();
3081#endif
15883082}
15893083
1590INLINE void rsp_vmacu(rsp_state *rsp, UINT32 op, INT16 *vres)
3084INLINE void cfunc_rsp_vmacu(void *param)
15913085{
3086   rsp_state *rsp = (rsp_state*)param;
3087   int op = rsp->impstate->arg0;
3088   INT16 vres[8];
15923089   int i;
15933090   // 31       25  24     20      15      10      5        0
15943091   // ------------------------------------------------------
r6794r6795
16113108      W_ACCUM_M(del, (UINT16)(r3));
16123109      W_ACCUM_H(del, (UINT16)ACCUM(del).h.high + (UINT16)(r3 >> 16) + (UINT16)(r1 >> 31));
16133110
1614      //res = SATURATE_ACCUM(rsp, del, 1, 0x0000, 0xffff);
16153111      if (ACCUM(del).h.high < 0)
16163112      {
16173113         res = 0;
r6794r6795
16403136   WRITEBACK_RESULT();
16413137}
16423138
1643INLINE void rsp_vmadl(rsp_state *rsp, UINT32 op, INT16 *vres)
3139INLINE void cfunc_rsp_vmadl(void *param)
16443140{
3141   rsp_state *rsp = (rsp_state*)param;
3142   int op = rsp->impstate->arg0;
3143   INT16 vres[8];
16453144   int i;
16463145   // 31       25  24     20      15      10      5        0
16473146   // ------------------------------------------------------
r6794r6795
16673166      W_ACCUM_M(del, (UINT16)(r3));
16683167      W_ACCUM_H(del, ACCUM(del).h.high + (INT16)(r3 >> 16));
16693168
1670      res = SATURATE_ACCUM_UNSIGNED(rsp, del, 0);
3169      res = SATURATE_ACCUM_UNSIGNED(rsp, del);
16713170
16723171      vres[del] = res;
16733172   }
16743173   WRITEBACK_RESULT();
16753174}
16763175
1677INLINE void rsp_vmadm(rsp_state *rsp, UINT32 op, INT16 *vres)
3176#if (DRC_VMADM)
3177/*------------------------------------------------------------------
3178    generate_vmadm
3179------------------------------------------------------------------*/
3180
3181#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) \
3182   { \
3183       UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
3184       UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
3185       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3186      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3187      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3188      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3189      UML_DADD(block, VACCUML(E10), VACCUML(E10), IREG(0)); \
3190 \
3191       UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
3192       UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
3193       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3194      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3195      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3196      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3197      UML_DADD(block, VACCUML(E11), VACCUML(E11), IREG(0)); \
3198 \
3199       UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
3200       UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
3201       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3202      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3203      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3204      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3205      UML_DADD(block, VACCUML(E12), VACCUML(E12), IREG(0)); \
3206 \
3207       UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
3208       UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
3209       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3210      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3211      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3212      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3213      UML_DADD(block, VACCUML(E13), VACCUML(E13), IREG(0)); \
3214 \
3215       UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
3216       UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
3217       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3218      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3219      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3220      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3221      UML_DADD(block, VACCUML(E14), VACCUML(E14), IREG(0)); \
3222 \
3223       UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
3224       UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
3225       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3226      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3227      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3228      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3229      UML_DADD(block, VACCUML(E15), VACCUML(E15), IREG(0)); \
3230 \
3231       UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
3232       UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
3233       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3234      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3235      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3236      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3237      UML_DADD(block, VACCUML(E16), VACCUML(E16), IREG(0)); \
3238 \
3239       UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
3240       UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
3241       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3242      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3243      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3244      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3245      UML_DADD(block, VACCUML(E17), VACCUML(E17), IREG(0)); \
3246 \
3247       generate_saturate_accum_signed(rsp, block, compiler, desc, E10); \
3248       UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
3249       generate_saturate_accum_signed(rsp, block, compiler, desc, E11); \
3250       UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
3251       generate_saturate_accum_signed(rsp, block, compiler, desc, E12); \
3252       UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
3253       generate_saturate_accum_signed(rsp, block, compiler, desc, E13); \
3254       UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
3255       generate_saturate_accum_signed(rsp, block, compiler, desc, E14); \
3256       UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
3257       generate_saturate_accum_signed(rsp, block, compiler, desc, E15); \
3258       UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
3259       generate_saturate_accum_signed(rsp, block, compiler, desc, E16); \
3260       UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
3261       generate_saturate_accum_signed(rsp, block, compiler, desc, E17); \
3262       UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
3263   }
3264
3265static int generate_vmadm(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)   // vmadm
16783266{
1679   int i;
3267   UINT32 op = desc->opptr.l[0];
3268
16803269   // 31       25  24     20      15      10      5        0
16813270   // ------------------------------------------------------
3271   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
3272   // ------------------------------------------------------
3273   //
3274   // Multiplies signed integer by unsigned fraction
3275   // The result is added into accumulator
3276   // The middle slice of accumulator is stored into destination element
3277   switch(EL)
3278   {
3279        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
3280           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);
3281           return TRUE;
3282        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
3283           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);
3284           return TRUE;
3285        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
3286           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);
3287           return TRUE;
3288        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
3289           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);
3290           return TRUE;
3291        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
3292           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);
3293           return TRUE;
3294        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
3295           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);
3296           return TRUE;
3297        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
3298           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);
3299           return TRUE;
3300        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
3301           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);
3302           return TRUE;
3303        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
3304           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);
3305           return TRUE;
3306        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
3307           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);
3308           return TRUE;
3309        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
3310           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);
3311           return TRUE;
3312        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
3313           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);
3314           return TRUE;
3315        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
3316           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);
3317           return TRUE;
3318        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
3319           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);
3320           return TRUE;
3321        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
3322           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);
3323           return TRUE;
3324        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
3325           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);
3326           return TRUE;
3327   }
3328
3329   return TRUE;
3330}
3331#else
3332#define RSP_VMADM(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
3333   { \
3334      ACCUM(E10).l += ((INT64)(INT16)R_VREG_S(VS1REG, E10) * (UINT16)R_VREG_S(VS2REG, E20)) << 16; \
3335      ACCUM(E11).l += ((INT64)(INT16)R_VREG_S(VS1REG, E11) * (UINT16)R_VREG_S(VS2REG, E21)) << 16; \
3336      ACCUM(E12).l += ((INT64)(INT16)R_VREG_S(VS1REG, E12) * (UINT16)R_VREG_S(VS2REG, E22)) << 16; \
3337      ACCUM(E13).l += ((INT64)(INT16)R_VREG_S(VS1REG, E13) * (UINT16)R_VREG_S(VS2REG, E23)) << 16; \
3338      ACCUM(E14).l += ((INT64)(INT16)R_VREG_S(VS1REG, E14) * (UINT16)R_VREG_S(VS2REG, E24)) << 16; \
3339      ACCUM(E15).l += ((INT64)(INT16)R_VREG_S(VS1REG, E15) * (UINT16)R_VREG_S(VS2REG, E25)) << 16; \
3340      ACCUM(E16).l += ((INT64)(INT16)R_VREG_S(VS1REG, E16) * (UINT16)R_VREG_S(VS2REG, E26)) << 16; \
3341      ACCUM(E17).l += ((INT64)(INT16)R_VREG_S(VS1REG, E17) * (UINT16)R_VREG_S(VS2REG, E27)) << 16; \
3342      vres[E10] = SATURATE_ACCUM_SIGNED(rsp, E10); \
3343      vres[E11] = SATURATE_ACCUM_SIGNED(rsp, E11); \
3344      vres[E12] = SATURATE_ACCUM_SIGNED(rsp, E12); \
3345      vres[E13] = SATURATE_ACCUM_SIGNED(rsp, E13); \
3346      vres[E14] = SATURATE_ACCUM_SIGNED(rsp, E14); \
3347      vres[E15] = SATURATE_ACCUM_SIGNED(rsp, E15); \
3348      vres[E16] = SATURATE_ACCUM_SIGNED(rsp, E16); \
3349      vres[E17] = SATURATE_ACCUM_SIGNED(rsp, E17); \
3350      W_VREG_S_X(VDREG, 7, vres[0]);         \
3351      W_VREG_S_X(VDREG, 6, vres[1]);         \
3352      W_VREG_S_X(VDREG, 5, vres[2]);         \
3353      W_VREG_S_X(VDREG, 4, vres[3]);         \
3354      W_VREG_S_X(VDREG, 3, vres[4]);         \
3355      W_VREG_S_X(VDREG, 2, vres[5]);         \
3356      W_VREG_S_X(VDREG, 1, vres[6]);         \
3357      W_VREG_S_X(VDREG, 0, vres[7]);         \
3358   }
3359
3360INLINE void cfunc_rsp_vmadm(void *param)
3361{
3362   rsp_state *rsp = (rsp_state*)param;
3363   int op = rsp->impstate->arg0;
3364   INT16 vres[8];
3365   // 31       25  24     20      15      10      5        0
3366   // ------------------------------------------------------
16823367   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001101 |
16833368   // ------------------------------------------------------
16843369   //
r6794r6795
16863371   // The result is added into accumulator
16873372   // The middle slice of accumulator is stored into destination element
16883373
1689   for (i=0; i < 8; i++)
3374   switch(EL)
16903375   {
1691      UINT16 res;
1692      int del = VEC_EL_1(EL, i);
1693      int sel = VEC_EL_2(EL, del);
1694      UINT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
1695      UINT32 s2 = (UINT16)R_VREG_S(VS2REG, sel);   // not sign-extended
1696      UINT32 r1 = s1 * s2;
1697      UINT32 r2 = (UINT16)ACCUM(del).h.low + (UINT16)(r1);
1698      UINT32 r3 = (UINT16)ACCUM(del).h.mid + (r1 >> 16) + (r2 >> 16);
3376        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
3377           RSP_VMADM(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
3378           break;
3379        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
3380           RSP_VMADM(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
3381           break;
3382        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
3383           RSP_VMADM(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
3384           break;
3385        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
3386           RSP_VMADM(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
3387           break;
3388        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
3389           RSP_VMADM(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
3390           break;
3391        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
3392           RSP_VMADM(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
3393           break;
3394        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
3395           RSP_VMADM(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
3396           break;
3397        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
3398           RSP_VMADM(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
3399           break;
3400        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
3401           RSP_VMADM(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3402           break;
3403        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
3404           RSP_VMADM(0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1);
3405           break;
3406        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
3407           RSP_VMADM(0, 1, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2);
3408           break;
3409        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
3410           RSP_VMADM(0, 1, 2, 4, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3);
3411           break;
3412        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
3413           RSP_VMADM(0, 1, 2, 3, 5, 6, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4);
3414           break;
3415        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
3416           RSP_VMADM(0, 1, 2, 3, 4, 6, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5);
3417           break;
3418        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
3419           RSP_VMADM(0, 1, 2, 3, 4, 5, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6);
3420           break;
3421        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
3422           RSP_VMADM(0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7);
3423           break;
3424   }
3425}
3426#endif
16993427
1700      W_ACCUM_L(del, (UINT16)(r2));
1701      W_ACCUM_M(del, (UINT16)(r3));
1702      W_ACCUM_H(del, (UINT16)ACCUM(del).h.high + (UINT16)(r3 >> 16));
1703      if ((INT32)(r1) < 0)
1704         W_ACCUM_H(del, (UINT16)ACCUM(del).h.high - 1);
3428#if (DRC_VMADN)
3429/*------------------------------------------------------------------
3430    generate_vmadn
3431------------------------------------------------------------------*/
17053432
1706      res = SATURATE_ACCUM_SIGNED(rsp, del, 1);
3433#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) \
3434   { \
3435       UML_SEXT(block, IREG(1), VS(VS1REG, I0), WORD); \
3436       UML_SEXT(block, IREG(0), VS(VS2REG, E20), WORD); \
3437       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3438      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3439      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3440      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3441      UML_DADD(block, VACCUML(E10), VACCUML(E10), IREG(0)); \
3442 \
3443       UML_SEXT(block, IREG(1), VS(VS1REG, I1), WORD); \
3444       UML_SEXT(block, IREG(0), VS(VS2REG, E21), WORD); \
3445       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3446      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3447      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3448      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3449      UML_DADD(block, VACCUML(E11), VACCUML(E11), IREG(0)); \
3450 \
3451       UML_SEXT(block, IREG(1), VS(VS1REG, I2), WORD); \
3452       UML_SEXT(block, IREG(0), VS(VS2REG, E22), WORD); \
3453       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3454      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3455      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3456      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3457      UML_DADD(block, VACCUML(E12), VACCUML(E12), IREG(0)); \
3458 \
3459       UML_SEXT(block, IREG(1), VS(VS1REG, I3), WORD); \
3460       UML_SEXT(block, IREG(0), VS(VS2REG, E23), WORD); \
3461       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3462      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3463      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3464      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3465      UML_DADD(block, VACCUML(E13), VACCUML(E13), IREG(0)); \
3466 \
3467       UML_SEXT(block, IREG(1), VS(VS1REG, I4), WORD); \
3468       UML_SEXT(block, IREG(0), VS(VS2REG, E24), WORD); \
3469       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3470      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3471      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3472      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3473      UML_DADD(block, VACCUML(E14), VACCUML(E14), IREG(0)); \
3474 \
3475       UML_SEXT(block, IREG(1), VS(VS1REG, I5), WORD); \
3476       UML_SEXT(block, IREG(0), VS(VS2REG, E25), WORD); \
3477       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3478      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3479      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3480      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3481      UML_DADD(block, VACCUML(E15), VACCUML(E15), IREG(0)); \
3482 \
3483       UML_SEXT(block, IREG(1), VS(VS1REG, I6), WORD); \
3484       UML_SEXT(block, IREG(0), VS(VS2REG, E26), WORD); \
3485       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3486      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3487      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3488      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3489      UML_DADD(block, VACCUML(E16), VACCUML(E16), IREG(0)); \
3490 \
3491       UML_SEXT(block, IREG(1), VS(VS1REG, I7), WORD); \
3492       UML_SEXT(block, IREG(0), VS(VS2REG, E27), WORD); \
3493       UML_AND(block, IREG(1), IREG(1), IMM(0x0000ffff)); \
3494      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3495      UML_DSEXT(block, IREG(0), IREG(0), DWORD); \
3496      UML_DSHL(block, IREG(0), IREG(0), IMM(16)); \
3497      UML_DADD(block, VACCUML(E17), VACCUML(E17), IREG(0)); \
3498 \
3499       generate_saturate_accum_unsigned(rsp, block, compiler, desc, E10); \
3500       UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
3501       generate_saturate_accum_unsigned(rsp, block, compiler, desc, E11); \
3502       UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
3503       generate_saturate_accum_unsigned(rsp, block, compiler, desc, E12); \
3504       UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
3505       generate_saturate_accum_unsigned(rsp, block, compiler, desc, E13); \
3506       UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
3507       generate_saturate_accum_unsigned(rsp, block, compiler, desc, E14); \
3508       UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
3509       generate_saturate_accum_unsigned(rsp, block, compiler, desc, E15); \
3510       UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
3511       generate_saturate_accum_unsigned(rsp, block, compiler, desc, E16); \
3512       UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
3513       generate_saturate_accum_unsigned(rsp, block, compiler, desc, E17); \
3514       UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
3515   }
17073516
1708      vres[del] = res;
3517static int generate_vmadn(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)   // vmadn
3518{
3519   UINT32 op = desc->opptr.l[0];
3520
3521   // 31       25  24     20      15      10      5        0
3522   // ------------------------------------------------------
3523   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
3524   // ------------------------------------------------------
3525   //
3526   // Multiplies unsigned fraction by signed integer
3527   // The result is added into accumulator
3528   // The low slice of accumulator is stored into destination element
3529   switch(EL)
3530   {
3531        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
3532           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);
3533           return TRUE;
3534        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
3535           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);
3536           return TRUE;
3537        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
3538           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);
3539           return TRUE;
3540        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
3541           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);
3542           return TRUE;
3543        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
3544           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);
3545           return TRUE;
3546        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
3547           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);
3548           return TRUE;
3549        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
3550           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);
3551           return TRUE;
3552        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
3553           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);
3554           return TRUE;
3555        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
3556           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);
3557           return TRUE;
3558        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
3559           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);
3560           return TRUE;
3561        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
3562           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);
3563           return TRUE;
3564        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
3565           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);
3566           return TRUE;
3567        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
3568           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);
3569           return TRUE;
3570        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
3571           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);
3572           return TRUE;
3573        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
3574           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);
3575           return TRUE;
3576        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
3577           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);
3578           return TRUE;
17093579   }
1710   WRITEBACK_RESULT();
3580
3581   return TRUE;
17113582}
3583#else
3584#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) \
3585   { \
3586      ACCUM(E10).l += ((UINT16)R_VREG_S_X(VS1REG, I0) * (INT64)R_VREG_S_X(VS2REG, E20)) << 16; \
3587      ACCUM(E11).l += ((UINT16)R_VREG_S_X(VS1REG, I1) * (INT64)R_VREG_S_X(VS2REG, E21)) << 16; \
3588      ACCUM(E12).l += ((UINT16)R_VREG_S_X(VS1REG, I2) * (INT64)R_VREG_S_X(VS2REG, E22)) << 16; \
3589      ACCUM(E13).l += ((UINT16)R_VREG_S_X(VS1REG, I3) * (INT64)R_VREG_S_X(VS2REG, E23)) << 16; \
3590      ACCUM(E14).l += ((UINT16)R_VREG_S_X(VS1REG, I4) * (INT64)R_VREG_S_X(VS2REG, E24)) << 16; \
3591      ACCUM(E15).l += ((UINT16)R_VREG_S_X(VS1REG, I5) * (INT64)R_VREG_S_X(VS2REG, E25)) << 16; \
3592      ACCUM(E16).l += ((UINT16)R_VREG_S_X(VS1REG, I6) * (INT64)R_VREG_S_X(VS2REG, E26)) << 16; \
3593      ACCUM(E17).l += ((UINT16)R_VREG_S_X(VS1REG, I7) * (INT64)R_VREG_S_X(VS2REG, E27)) << 16; \
3594      vres[E10] = SATURATE_ACCUM_UNSIGNED(rsp, E10); \
3595      vres[E11] = SATURATE_ACCUM_UNSIGNED(rsp, E11); \
3596      vres[E12] = SATURATE_ACCUM_UNSIGNED(rsp, E12); \
3597      vres[E13] = SATURATE_ACCUM_UNSIGNED(rsp, E13); \
3598      vres[E14] = SATURATE_ACCUM_UNSIGNED(rsp, E14); \
3599      vres[E15] = SATURATE_ACCUM_UNSIGNED(rsp, E15); \
3600      vres[E16] = SATURATE_ACCUM_UNSIGNED(rsp, E16); \
3601      vres[E17] = SATURATE_ACCUM_UNSIGNED(rsp, E17); \
3602      W_VREG_S_X(VDREG, 7, vres[0]);         \
3603      W_VREG_S_X(VDREG, 6, vres[1]);         \
3604      W_VREG_S_X(VDREG, 5, vres[2]);         \
3605      W_VREG_S_X(VDREG, 4, vres[3]);         \
3606      W_VREG_S_X(VDREG, 3, vres[4]);         \
3607      W_VREG_S_X(VDREG, 2, vres[5]);         \
3608      W_VREG_S_X(VDREG, 1, vres[6]);         \
3609      W_VREG_S_X(VDREG, 0, vres[7]);         \
3610   }
17123611
1713INLINE void rsp_vmadn(rsp_state *rsp, UINT32 op, INT16 *vres)
3612INLINE void cfunc_rsp_vmadn(void *param)
17143613{
1715   int i;
3614   rsp_state *rsp = (rsp_state*)param;
3615   int op = rsp->impstate->arg0;
3616   INT16 vres[8];
17163617   // 31       25  24     20      15      10      5        0
17173618   // ------------------------------------------------------
17183619   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
r6794r6795
17213622   // Multiplies unsigned fraction by signed integer
17223623   // The result is added into accumulator
17233624   // The low slice of accumulator is stored into destination element
1724
1725   for (i=0; i < 8; i++)
3625   switch(EL)
17263626   {
1727      int del = VEC_EL_1(EL, i);
1728      int sel = VEC_EL_2(EL, del);
1729      INT32 s1 = (UINT16)R_VREG_S(VS1REG, del);      // not sign-extended
1730      INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
1731      UINT32 r1 = s1 * s2;
1732      UINT32 r2 = (UINT16)ACCUM(del).h.low + (UINT16)(r1);
1733      UINT32 r3 = (UINT16)ACCUM(del).h.mid + (r1 >> 16) + (r2 >> 16);
3627        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
3628           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);
3629           break;
3630        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
3631           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);
3632           break;
3633        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
3634           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);
3635           break;
3636        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
3637           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);
3638           break;
3639        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
3640           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);
3641           break;
3642        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
3643           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);
3644           break;
3645        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
3646           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);
3647           break;
3648        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
3649           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);
3650           break;
3651        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
3652           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);
3653           break;
3654        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
3655           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);
3656           break;
3657        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
3658           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);
3659           break;
3660        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
3661           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);
3662           break;
3663        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
3664           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);
3665           break;
3666        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
3667           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);
3668           break;
3669        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
3670           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);
3671           break;
3672        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
3673           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);
3674           break;
3675   }
3676}
3677#endif
17343678
1735      W_ACCUM_L(del, (UINT16)(r2));
1736      W_ACCUM_M(del, (UINT16)(r3));
1737      W_ACCUM_H(del, (UINT16)ACCUM(del).h.high + (UINT16)(r3 >> 16));
1738      if ((INT32)(r1) < 0)
1739         W_ACCUM_H(del, (UINT16)ACCUM(del).h.high - 1);
3679#if (DRC_VMADH)
3680/*------------------------------------------------------------------
3681    generate_vmadh
3682------------------------------------------------------------------*/
17403683
1741      vres[del] = SATURATE_ACCUM_UNSIGNED(rsp, del, 0);
3684#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) \
3685   { \
3686       UML_SEXT(block, IREG(1), VS(VS1REG, I0), WORD); \
3687       UML_SEXT(block, IREG(0), VS(VS2REG, E20), WORD); \
3688      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3689      UML_ADD(block, VACCUMWMH(E10), VACCUMWMH(E10), IREG(0)); \
3690 \
3691       UML_SEXT(block, IREG(1), VS(VS1REG, I1), WORD); \
3692       UML_SEXT(block, IREG(0), VS(VS2REG, E21), WORD); \
3693      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3694      UML_ADD(block, VACCUMWMH(E11), VACCUMWMH(E11), IREG(0)); \
3695 \
3696       UML_SEXT(block, IREG(1), VS(VS1REG, I2), WORD); \
3697       UML_SEXT(block, IREG(0), VS(VS2REG, E22), WORD); \
3698      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3699      UML_ADD(block, VACCUMWMH(E12), VACCUMWMH(E12), IREG(0)); \
3700 \
3701       UML_SEXT(block, IREG(1), VS(VS1REG, I3), WORD); \
3702       UML_SEXT(block, IREG(0), VS(VS2REG, E23), WORD); \
3703      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3704      UML_ADD(block, VACCUMWMH(E13), VACCUMWMH(E13), IREG(0)); \
3705 \
3706       UML_SEXT(block, IREG(1), VS(VS1REG, I4), WORD); \
3707       UML_SEXT(block, IREG(0), VS(VS2REG, E24), WORD); \
3708      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3709      UML_ADD(block, VACCUMWMH(E14), VACCUMWMH(E14), IREG(0)); \
3710 \
3711       UML_SEXT(block, IREG(1), VS(VS1REG, I5), WORD); \
3712       UML_SEXT(block, IREG(0), VS(VS2REG, E25), WORD); \
3713      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3714      UML_ADD(block, VACCUMWMH(E15), VACCUMWMH(E15), IREG(0)); \
3715 \
3716       UML_SEXT(block, IREG(1), VS(VS1REG, I6), WORD); \
3717       UML_SEXT(block, IREG(0), VS(VS2REG, E26), WORD); \
3718      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3719      UML_ADD(block, VACCUMWMH(E16), VACCUMWMH(E16), IREG(0)); \
3720 \
3721       UML_SEXT(block, IREG(1), VS(VS1REG, I7), WORD); \
3722       UML_SEXT(block, IREG(0), VS(VS2REG, E27), WORD); \
3723      UML_MULS(block, IREG(0), IREG(1), IREG(0), IREG(1)); \
3724      UML_ADD(block, VACCUMWMH(E17), VACCUMWMH(E17), IREG(0)); \
3725 \
3726       generate_saturate_accum_signed(rsp, block, compiler, desc, E10); \
3727       UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
3728       generate_saturate_accum_signed(rsp, block, compiler, desc, E11); \
3729       UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
3730       generate_saturate_accum_signed(rsp, block, compiler, desc, E12); \
3731       UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
3732       generate_saturate_accum_signed(rsp, block, compiler, desc, E13); \
3733       UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
3734       generate_saturate_accum_signed(rsp, block, compiler, desc, E14); \
3735       UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
3736       generate_saturate_accum_signed(rsp, block, compiler, desc, E15); \
3737       UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
3738       generate_saturate_accum_signed(rsp, block, compiler, desc, E16); \
3739       UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
3740       generate_saturate_accum_signed(rsp, block, compiler, desc, E17); \
3741       UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
17423742   }
1743   WRITEBACK_RESULT();
3743
3744static int generate_vmadh(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)   // vmadh
3745{
3746   UINT32 op = desc->opptr.l[0];
3747
3748   // 31       25  24     20      15      10      5        0
3749   // ------------------------------------------------------
3750   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
3751   // ------------------------------------------------------
3752   //
3753   // Multiplies unsigned fraction by signed integer
3754   // The result is added into accumulator
3755   // The low slice of accumulator is stored into destination element
3756   switch(EL)
3757   {
3758        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
3759           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);
3760           return TRUE;
3761        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
3762           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);
3763           return TRUE;
3764        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
3765           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);
3766           return TRUE;
3767        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
3768           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);
3769           return TRUE;
3770        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
3771           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);
3772           return TRUE;
3773        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
3774           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);
3775           return TRUE;
3776        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
3777           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);
3778           return TRUE;
3779        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
3780           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);
3781           return TRUE;
3782        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
3783           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);
3784           return TRUE;
3785        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
3786           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);
3787           return TRUE;
3788        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
3789           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);
3790           return TRUE;
3791        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
3792           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);
3793           return TRUE;
3794        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
3795           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);
3796           return TRUE;
3797        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
3798           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);
3799           return TRUE;
3800        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
3801           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);
3802           return TRUE;
3803        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
3804           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);
3805           return TRUE;
3806   }
3807
3808   return TRUE;
17443809}
3810#else
3811#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) \
3812   { \
3813      ACCUM(E10).w.mh += (INT32)R_VREG_S_X(VS1REG, I0) * (INT32)R_VREG_S_X(VS2REG, E20); \
3814      ACCUM(E11).w.mh += (INT32)R_VREG_S_X(VS1REG, I1) * (INT32)R_VREG_S_X(VS2REG, E21); \
3815      ACCUM(E12).w.mh += (INT32)R_VREG_S_X(VS1REG, I2) * (INT32)R_VREG_S_X(VS2REG, E22); \
3816      ACCUM(E13).w.mh += (INT32)R_VREG_S_X(VS1REG, I3) * (INT32)R_VREG_S_X(VS2REG, E23); \
3817      ACCUM(E14).w.mh += (INT32)R_VREG_S_X(VS1REG, I4) * (INT32)R_VREG_S_X(VS2REG, E24); \
3818      ACCUM(E15).w.mh += (INT32)R_VREG_S_X(VS1REG, I5) * (INT32)R_VREG_S_X(VS2REG, E25); \
3819      ACCUM(E16).w.mh += (INT32)R_VREG_S_X(VS1REG, I6) * (INT32)R_VREG_S_X(VS2REG, E26); \
3820      ACCUM(E17).w.mh += (INT32)R_VREG_S_X(VS1REG, I7) * (INT32)R_VREG_S_X(VS2REG, E27); \
3821      vres[E10] = SATURATE_ACCUM_SIGNED(rsp, E10); \
3822      vres[E11] = SATURATE_ACCUM_SIGNED(rsp, E11); \
3823      vres[E12] = SATURATE_ACCUM_SIGNED(rsp, E12); \
3824      vres[E13] = SATURATE_ACCUM_SIGNED(rsp, E13); \
3825      vres[E14] = SATURATE_ACCUM_SIGNED(rsp, E14); \
3826      vres[E15] = SATURATE_ACCUM_SIGNED(rsp, E15); \
3827      vres[E16] = SATURATE_ACCUM_SIGNED(rsp, E16); \
3828      vres[E17] = SATURATE_ACCUM_SIGNED(rsp, E17); \
3829      W_VREG_S_X(VDREG, 7, vres[0]);         \
3830      W_VREG_S_X(VDREG, 6, vres[1]);         \
3831      W_VREG_S_X(VDREG, 5, vres[2]);         \
3832      W_VREG_S_X(VDREG, 4, vres[3]);         \
3833      W_VREG_S_X(VDREG, 3, vres[4]);         \
3834      W_VREG_S_X(VDREG, 2, vres[5]);         \
3835      W_VREG_S_X(VDREG, 1, vres[6]);         \
3836      W_VREG_S_X(VDREG, 0, vres[7]);         \
3837   }
17453838
1746INLINE void rsp_vmadh(rsp_state *rsp, UINT32 op, INT16 *vres)
3839INLINE void cfunc_rsp_vmadh(void *param)
17473840{
1748   int i;
3841   rsp_state *rsp = (rsp_state*)param;
3842   int op = rsp->impstate->arg0;
3843   INT16 vres[8];
17493844   // 31       25  24     20      15      10      5        0
17503845   // ------------------------------------------------------
17513846   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001111 |
r6794r6795
17553850   // The result is added into highest 32 bits of accumulator, the low slice is zero
17563851   // The highest 32 bits of accumulator is saturated into destination element
17573852
1758   for (i=0; i < 8; i++)
3853   switch(EL)
17593854   {
1760      UINT16 res;
1761      int del = VEC_EL_1(EL, i);
1762      int sel = VEC_EL_2(EL, del);
1763      INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
1764      INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
1765      INT64 r = s1 * s2;
3855        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
3856           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);
3857           break;
3858        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
3859           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);
3860           break;
3861        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
3862           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);
3863           break;
3864        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
3865           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);
3866           break;
3867        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
3868           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);
3869           break;
3870        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
3871           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);
3872           break;
3873        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
3874           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);
3875           break;
3876        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
3877           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);
3878           break;
3879        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
3880           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);
3881           break;
3882        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
3883           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);
3884           break;
3885        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
3886           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);
3887           break;
3888        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
3889           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);
3890           break;
3891        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
3892           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);
3893           break;
3894        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
3895           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);
3896           break;
3897        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
3898           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);
3899           break;
3900        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
3901           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);
3902           break;
3903   }
3904}
3905#endif
17663906
1767      ACCUM(del).l += (INT64)(r) << 32;
3907#if (DRC_VADD)
3908/*------------------------------------------------------------------
3909    generate_vadd
3910------------------------------------------------------------------*/
17683911
1769      res = SATURATE_ACCUM_SIGNED(rsp, del, 1);
3912#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) \
3913   { \
3914      int inrange, outofrange; \
3915 \
3916      UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
3917      UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
3918      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
3919      UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
3920      UML_SHL(block, IREG(2), IMM(1), IMM(E10)); \
3921      UML_AND(block, IREG(1), IREG(1), IREG(2)); \
3922      UML_SHR(block, IREG(1), IREG(1), IMM(E10)); \
3923      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
3924      UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
3925      UML_CMP(block, IREG(0), IMM(32767)); \
3926      UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
3927 \
3928      UML_MOV(block, IREG(0), IMM(32767)); \
3929      UML_JMP(block, outofrange = compiler->labelnum++); \
3930 \
3931   UML_LABEL(block, inrange); \
3932 \
3933      UML_CMP(block, IREG(0), IMM(-32768)); \
3934      UML_JMPc(block, IF_G, inrange = compiler->labelnum++); \
3935 \
3936       UML_MOV(block, IREG(0), IMM(-32768)); \
3937 \
3938   UML_LABEL(block, inrange); \
3939   UML_LABEL(block, outofrange); \
3940 \
3941       UML_MOV(block, VRES(E10), IREG(0)); \
3942 \
3943 \
3944      UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
3945      UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
3946      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
3947      UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
3948      UML_SHL(block, IREG(2), IMM(1), IMM(E11)); \
3949      UML_AND(block, IREG(1), IREG(1), IREG(2)); \
3950      UML_SHR(block, IREG(1), IREG(1), IMM(E11)); \
3951      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
3952      UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
3953      UML_CMP(block, IREG(0), IMM(32767)); \
3954      UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
3955 \
3956      UML_MOV(block, IREG(0), IMM(32767)); \
3957      UML_JMP(block, outofrange = compiler->labelnum++); \
3958 \
3959   UML_LABEL(block, inrange); \
3960 \
3961      UML_CMP(block, IREG(0), IMM(-32768)); \
3962      UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
3963 \
3964       UML_MOV(block, IREG(0), IMM(-32768)); \
3965 \
3966   UML_LABEL(block, inrange); \
3967   UML_LABEL(block, outofrange); \
3968 \
3969       UML_MOV(block, VRES(E11), IREG(0)); \
3970 \
3971 \
3972      UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
3973      UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
3974      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
3975      UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
3976      UML_SHL(block, IREG(2), IMM(1), IMM(E12)); \
3977      UML_AND(block, IREG(1), IREG(1), IREG(2)); \
3978      UML_SHR(block, IREG(1), IREG(1), IMM(E12)); \
3979      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
3980      UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
3981      UML_CMP(block, IREG(0), IMM(32767)); \
3982      UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
3983 \
3984      UML_MOV(block, IREG(0), IMM(32767)); \
3985      UML_JMP(block, outofrange = compiler->labelnum++); \
3986 \
3987   UML_LABEL(block, inrange); \
3988 \
3989      UML_CMP(block, IREG(0), IMM(-32768)); \
3990      UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
3991 \
3992       UML_MOV(block, IREG(0), IMM(-32768)); \
3993 \
3994   UML_LABEL(block, inrange); \
3995   UML_LABEL(block, outofrange); \
3996 \
3997       UML_MOV(block, VRES(E12), IREG(0)); \
3998 \
3999 \
4000      UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
4001      UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
4002      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4003      UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
4004      UML_SHL(block, IREG(2), IMM(1), IMM(E13)); \
4005      UML_AND(block, IREG(1), IREG(1), IREG(2)); \
4006      UML_SHR(block, IREG(1), IREG(1), IMM(E13)); \
4007      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4008      UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
4009      UML_CMP(block, IREG(0), IMM(32767)); \
4010      UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
4011 \
4012      UML_MOV(block, IREG(0), IMM(32767)); \
4013      UML_JMP(block, outofrange = compiler->labelnum++); \
4014 \
4015   UML_LABEL(block, inrange); \
4016 \
4017      UML_CMP(block, IREG(0), IMM(-32768)); \
4018      UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
4019 \
4020       UML_MOV(block, IREG(0), IMM(-32768)); \
4021 \
4022   UML_LABEL(block, inrange); \
4023   UML_LABEL(block, outofrange); \
4024 \
4025       UML_MOV(block, VRES(E13), IREG(0)); \
4026 \
4027 \
4028      UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
4029      UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
4030      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4031      UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
4032      UML_SHL(block, IREG(2), IMM(1), IMM(E14)); \
4033      UML_AND(block, IREG(1), IREG(1), IREG(2)); \
4034      UML_SHR(block, IREG(1), IREG(1), IMM(E14)); \
4035      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4036      UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
4037      UML_CMP(block, IREG(0), IMM(32767)); \
4038      UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
4039 \
4040      UML_MOV(block, IREG(0), IMM(32767)); \
4041      UML_JMP(block, outofrange = compiler->labelnum++); \
4042 \
4043   UML_LABEL(block, inrange); \
4044 \
4045      UML_CMP(block, IREG(0), IMM(-32768)); \
4046      UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
4047 \
4048       UML_MOV(block, IREG(0), IMM(-32768)); \
4049 \
4050   UML_LABEL(block, inrange); \
4051   UML_LABEL(block, outofrange); \
4052 \
4053       UML_MOV(block, VRES(E14), IREG(0)); \
4054 \
4055 \
4056      UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
4057      UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
4058      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4059      UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
4060      UML_SHL(block, IREG(2), IMM(1), IMM(E15)); \
4061      UML_AND(block, IREG(1), IREG(1), IREG(2)); \
4062      UML_SHR(block, IREG(1), IREG(1), IMM(E15)); \
4063      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4064      UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
4065      UML_CMP(block, IREG(0), IMM(32767)); \
4066      UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
4067 \
4068      UML_MOV(block, IREG(0), IMM(32767)); \
4069      UML_JMP(block, outofrange = compiler->labelnum++); \
4070 \
4071   UML_LABEL(block, inrange); \
4072 \
4073      UML_CMP(block, IREG(0), IMM(-32768)); \
4074      UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
4075 \
4076       UML_MOV(block, IREG(0), IMM(-32768)); \
4077 \
4078   UML_LABEL(block, inrange); \
4079   UML_LABEL(block, outofrange); \
4080 \
4081       UML_MOV(block, VRES(E15), IREG(0)); \
4082 \
4083 \
4084      UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
4085      UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
4086      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4087      UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
4088      UML_SHL(block, IREG(2), IMM(1), IMM(E16)); \
4089      UML_AND(block, IREG(1), IREG(1), IREG(2)); \
4090      UML_SHR(block, IREG(1), IREG(1), IMM(E16)); \
4091      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4092      UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
4093      UML_CMP(block, IREG(0), IMM(32767)); \
4094      UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
4095 \
4096      UML_MOV(block, IREG(0), IMM(32767)); \
4097      UML_JMP(block, outofrange = compiler->labelnum++); \
4098 \
4099   UML_LABEL(block, inrange); \
4100 \
4101      UML_CMP(block, IREG(0), IMM(-32768)); \
4102      UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
4103 \
4104       UML_MOV(block, IREG(0), IMM(-32768)); \
4105 \
4106   UML_LABEL(block, inrange); \
4107   UML_LABEL(block, outofrange); \
4108 \
4109       UML_MOV(block, VRES(E16), IREG(0)); \
4110 \
4111 \
4112      UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
4113      UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
4114      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4115      UML_SEXT(block, IREG(1), VFLAG(0), WORD); \
4116      UML_SHL(block, IREG(2), IMM(1), IMM(E17)); \
4117      UML_AND(block, IREG(1), IREG(1), IREG(2)); \
4118      UML_SHR(block, IREG(1), IREG(1), IMM(E17)); \
4119      UML_ADD(block, IREG(0), IREG(0), IREG(1)); \
4120      UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
4121      UML_CMP(block, IREG(0), IMM(32767)); \
4122      UML_JMPc(block, IF_LE, inrange = compiler->labelnum++); \
4123 \
4124      UML_MOV(block, IREG(0), IMM(32767)); \
4125      UML_JMP(block, outofrange = compiler->labelnum++); \
4126 \
4127   UML_LABEL(block, inrange); \
4128 \
4129      UML_CMP(block, IREG(0), IMM(-32768)); \
4130      UML_JMPc(block, IF_GE, inrange = compiler->labelnum++); \
4131 \
4132       UML_MOV(block, IREG(0), IMM(-32768)); \
4133 \
4134   UML_LABEL(block, inrange); \
4135   UML_LABEL(block, outofrange); \
4136 \
4137       UML_MOV(block, VRES(E17), IREG(0)); \
4138 \
4139 \
4140       UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), VRES(E10), WORD); \
4141       UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), VRES(E11), WORD); \
4142       UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), VRES(E12), WORD); \
4143       UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), VRES(E13), WORD); \
4144       UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), VRES(E14), WORD); \
4145       UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), VRES(E15), WORD); \
4146       UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), VRES(E16), WORD); \
4147       UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), VRES(E17), WORD); \
4148   }
17704149
1771      vres[del] = res;
4150static int generate_vadd(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)   // vadd
4151{
4152   UINT32 op = desc->opptr.l[0];
4153
4154   // 31       25  24     20      15      10      5        0
4155   // ------------------------------------------------------
4156   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 001110 |
4157   // ------------------------------------------------------
4158   //
4159   // Multiplies unsigned fraction by signed integer
4160   // The result is added into accumulator
4161   // The low slice of accumulator is stored into destination element
4162   switch(EL)
4163   {
4164        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
4165           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);
4166           return TRUE;
4167        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
4168           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);
4169           return TRUE;
4170        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
4171           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);
4172           return TRUE;
4173        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
4174           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);
4175           return TRUE;
4176        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
4177           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);
4178           return TRUE;
4179        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
4180           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);
4181           return TRUE;
4182        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
4183           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);
4184           return TRUE;
4185        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
4186           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);
4187           return TRUE;
4188        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
4189           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);
4190           return TRUE;
4191        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
4192           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);
4193           return TRUE;
4194        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
4195           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);
4196           return TRUE;
4197        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
4198           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);
4199           return TRUE;
4200        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
4201           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);
4202           return TRUE;
4203        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
4204           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);
4205           return TRUE;
4206        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
4207           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);
4208           return TRUE;
4209        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
4210           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);
4211           return TRUE;
17724212   }
1773   WRITEBACK_RESULT();
4213
4214   return TRUE;
17744215}
4216#else
4217#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) \
4218   {                                                                  \
4219      INT32 r;                                                         \
4220      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)); \
4221      vres[E10] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E10).h.low);      \
4222      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)); \
4223      vres[E11] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E11).h.low);      \
4224      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)); \
4225      vres[E12] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E12).h.low);      \
4226      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)); \
4227      vres[E13] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E13).h.low);      \
4228      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)); \
4229      vres[E14] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E14).h.low);      \
4230      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)); \
4231      vres[E15] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E15).h.low);      \
4232      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)); \
4233      vres[E16] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E16).h.low);      \
4234      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)); \
4235      vres[E17] = (r > 32767) ? 32767 : ((r < -32768) ? -32768 : ACCUM(E17).h.low);      \
4236   }
17754237
1776INLINE void rsp_vadd(rsp_state *rsp, UINT32 op, INT16 *vres)
4238INLINE void cfunc_rsp_vadd(void *param)
17774239{
1778   int i;
4240   rsp_state *rsp = (rsp_state*)param;
4241   int op = rsp->impstate->arg0;
4242   INT16 vres[8] = { 0 };
4243   //int i;
17794244   // 31       25  24     20      15      10      5        0
17804245   // ------------------------------------------------------
17814246   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 010000 |
r6794r6795
17844249   // Adds two vector registers and carry flag, the result is saturated to 32767
17854250
17864251   // TODO: check VS2REG == VDREG
1787
1788   for (i=0; i < 8; i++)
1789   {
1790      int del = VEC_EL_1(EL, i);
1791      int sel = VEC_EL_2(EL, del);
1792      INT32 s1 = (INT32)(INT16)R_VREG_S(VS1REG, del);
1793      INT32 s2 = (INT32)(INT16)R_VREG_S(VS2REG, sel);
1794      INT32 r = s1 + s2 + CARRY_FLAG(del);
1795
1796      W_ACCUM_L(del, (INT16)(r));
1797
1798      if (r > 32767) r = 32767;
1799      if (r < -32768) r = -32768;
1800      vres[del] = (INT16)(r);
1801   }
1802   CLEAR_ZERO_FLAGS();
1803   CLEAR_CARRY_FLAGS();
4252     switch(EL)
4253     {
4254        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
4255           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);
4256           break;
4257        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
4258           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);
4259           break;
4260        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
4261           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);
4262           break;
4263        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
4264           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);
4265           break;
4266        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
4267           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);
4268           break;
4269        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
4270           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);
4271           break;
4272        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
4273           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);
4274           break;
4275        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
4276           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);
4277           break;
4278        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
4279           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);
4280           break;
4281        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
4282           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);
4283           break;
4284        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
4285           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);
4286           break;
4287        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
4288           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);
4289           break;
4290        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
4291           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);
4292           break;
4293        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
4294           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);
4295           break;
4296        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
4297           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);
4298           break;
4299        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
4300           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);
4301           break;
4302     }
4303   rsp->flag[0] = 0;
18044304   WRITEBACK_RESULT();
18054305}
4306#endif
18064307
1807INLINE void rsp_vsub(rsp_state *rsp, UINT32 op, INT16 *vres)
4308INLINE void cfunc_rsp_vsub(void *param)
18084309{
4310   rsp_state *rsp = (rsp_state*)param;
4311   int op = rsp->impstate->arg0;
4312   INT16 vres[8];
18094313   int i;
18104314   // 31       25  24     20      15      10      5        0
18114315   // ------------------------------------------------------
r6794r6795
18314335
18324336      vres[del] = (INT16)(r);
18334337   }
1834   CLEAR_ZERO_FLAGS();
1835   CLEAR_CARRY_FLAGS();
4338   rsp->flag[0] = 0;
18364339   WRITEBACK_RESULT();
18374340}
18384341
1839INLINE void rsp_vabs(rsp_state *rsp, UINT32 op, INT16 *vres)
4342INLINE void cfunc_rsp_vabs(void *param)
18404343{
4344   rsp_state *rsp = (rsp_state*)param;
4345   int op = rsp->impstate->arg0;
4346   INT16 vres[8];
18414347   int i;
18424348   // 31       25  24     20      15      10      5        0
18434349   // ------------------------------------------------------
r6794r6795
18794385   WRITEBACK_RESULT();
18804386}
18814387
1882INLINE void rsp_vaddc(rsp_state *rsp, UINT32 op, INT16 *vres)
4388INLINE void cfunc_rsp_vaddc(void *param)
18834389{
4390   rsp_state *rsp = (rsp_state*)param;
4391   int op = rsp->impstate->arg0;
4392   INT16 vres[8];
18844393   int i;
18854394   // 31       25  24     20      15      10      5        0
18864395   // ------------------------------------------------------
r6794r6795
18914400
18924401   // TODO: check VS2REG = VDREG
18934402
1894   CLEAR_ZERO_FLAGS();
1895   CLEAR_CARRY_FLAGS();
4403   rsp->flag[0] = 0;
18964404
18974405   for (i=0; i < 8; i++)
18984406   {
r6794r6795
19134421   WRITEBACK_RESULT();
19144422}
19154423
1916INLINE void rsp_vsubc(rsp_state *rsp, UINT32 op, INT16 *vres)
4424INLINE void cfunc_rsp_vsubc(void *param)
19174425{
4426   rsp_state *rsp = (rsp_state*)param;
4427   int op = rsp->impstate->arg0;
4428   INT16 vres[8];
19184429   int i;
19194430   // 31       25  24     20      15      10      5        0
19204431   // ------------------------------------------------------
r6794r6795
19254436
19264437   // TODO: check VS2REG = VDREG
19274438
1928   CLEAR_ZERO_FLAGS();
1929   CLEAR_CARRY_FLAGS();
4439   rsp->flag[0] = 0;
19304440
19314441   for (i=0; i < 8; i++)
19324442   {
r6794r6795
19514461   WRITEBACK_RESULT();
19524462}
19534463
1954INLINE void rsp_vsaw(rsp_state *rsp, UINT32 op, INT16 *vres)
4464INLINE void cfunc_rsp_vsaw(void *param)
19554465{
1956   int i;
4466   rsp_state *rsp = (rsp_state*)param;
4467   int op = rsp->impstate->arg0;
19574468   // 31       25  24     20      15      10      5        0
19584469   // ------------------------------------------------------
19594470   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 011101 |
r6794r6795
19654476   {
19664477      case 0x08:      // VSAWH
19674478      {
1968         for (i=0; i < 8; i++)
1969         {
1970            W_VREG_S(VDREG, i, ACCUM(i).h.high);
1971         }
4479         W_VREG_S_X(VDREG, 7, ACCUM(0).h.high);
4480         W_VREG_S_X(VDREG, 6, ACCUM(1).h.high);
4481         W_VREG_S_X(VDREG, 5, ACCUM(2).h.high);
4482         W_VREG_S_X(VDREG, 4, ACCUM(3).h.high);
4483         W_VREG_S_X(VDREG, 3, ACCUM(4).h.high);
4484         W_VREG_S_X(VDREG, 2, ACCUM(5).h.high);
4485         W_VREG_S_X(VDREG, 1, ACCUM(6).h.high);
4486         W_VREG_S_X(VDREG, 0, ACCUM(7).h.high);
19724487         break;
19734488      }
19744489      case 0x09:      // VSAWM
19754490      {
1976         for (i=0; i < 8; i++)
1977         {
1978            W_VREG_S(VDREG, i, ACCUM(i).h.mid);
1979         }
4491         W_VREG_S_X(VDREG, 7, ACCUM(0).h.mid);
4492         W_VREG_S_X(VDREG, 6, ACCUM(1).h.mid);
4493         W_VREG_S_X(VDREG, 5, ACCUM(2).h.mid);
4494         W_VREG_S_X(VDREG, 4, ACCUM(3).h.mid);
4495         W_VREG_S_X(VDREG, 3, ACCUM(4).h.mid);
4496         W_VREG_S_X(VDREG, 2, ACCUM(5).h.mid);
4497         W_VREG_S_X(VDREG, 1, ACCUM(6).h.mid);
4498         W_VREG_S_X(VDREG, 0, ACCUM(7).h.mid);
19804499         break;
19814500      }
19824501      case 0x0a:      // VSAWL
19834502      {
1984         for (i=0; i < 8; i++)
1985         {
1986            W_VREG_S(VDREG, i, ACCUM(i).h.low);
1987         }
4503         W_VREG_S_X(VDREG, 7, ACCUM(0).h.low);
4504         W_VREG_S_X(VDREG, 6, ACCUM(1).h.low);
4505         W_VREG_S_X(VDREG, 5, ACCUM(2).h.low);
4506         W_VREG_S_X(VDREG, 4, ACCUM(3).h.low);
4507         W_VREG_S_X(VDREG, 3, ACCUM(4).h.low);
4508         W_VREG_S_X(VDREG, 2, ACCUM(5).h.low);
4509         W_VREG_S_X(VDREG, 1, ACCUM(6).h.low);
4510         W_VREG_S_X(VDREG, 0, ACCUM(7).h.low);
19884511         break;
19894512      }
19904513      default:   fatalerror("RSP: VSAW: el = %d\n", EL);
19914514   }
19924515}
19934516
1994INLINE void rsp_vlt(rsp_state *rsp, UINT32 op, INT16 *vres)
4517#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) \
4518   { \
4519      rsp->flag[1] = 0; \
4520 \
4521      if (R_VREG_S_X(VS1REG, I0) > R_VREG_S_X(VS2REG, E20)) \
4522      { \
4523         ACCUM(E16).h.low = vres[E10] = R_VREG_S_X(VS2REG, E20); \
4524      } \
4525      else if (R_VREG_S_X(VS1REG, I0) < R_VREG_S_X(VS2REG, E20)) \
4526      { \
4527         ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS1REG, I0); \
4528         SET_COMPARE_FLAG(E10); \
4529      } \
4530      else if (R_VREG_S_X(VS1REG, I0) == R_VREG_S_X(VS2REG, E20)) \
4531      { \
4532         ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS1REG, I0); \
4533         if (ZERO_FLAG(E10) && CARRY_FLAG(E10)) SET_COMPARE_FLAG(E10); \
4534      } \
4535      if (R_VREG_S_X(VS1REG, I1) > R_VREG_S_X(VS2REG, E21)) \
4536      { \
4537         ACCUM(E16).h.low = vres[E11] = R_VREG_S_X(VS2REG, E21); \
4538      } \
4539      else if (R_VREG_S_X(VS1REG, I1) < R_VREG_S_X(VS2REG, E21)) \
4540      { \
4541         ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS1REG, I1); \
4542         SET_COMPARE_FLAG(E11); \
4543      } \
4544      else if (R_VREG_S_X(VS1REG, I1) == R_VREG_S_X(VS2REG, E21)) \
4545      { \
4546         ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS1REG, I1); \
4547         if (ZERO_FLAG(E11) && CARRY_FLAG(E11)) SET_COMPARE_FLAG(E11); \
4548      } \
4549      if (R_VREG_S_X(VS1REG, I2) > R_VREG_S_X(VS2REG, E22)) \
4550      { \
4551         ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS2REG, E22); \
4552      } \
4553      else if (R_VREG_S_X(VS1REG, I2) < R_VREG_S_X(VS2REG, E22)) \
4554      { \
4555         ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS1REG, I2); \
4556         SET_COMPARE_FLAG(E12); \
4557      } \
4558      else if (R_VREG_S_X(VS1REG, I2) == R_VREG_S_X(VS2REG, E22)) \
4559      { \
4560         ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS1REG, I2); \
4561         if (ZERO_FLAG(E12) && CARRY_FLAG(E12)) SET_COMPARE_FLAG(E12); \
4562      } \
4563      if (R_VREG_S_X(VS1REG, I3) > R_VREG_S_X(VS2REG, E23)) \
4564      { \
4565         ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS2REG, E23); \
4566      } \
4567      else if (R_VREG_S_X(VS1REG, I3) < R_VREG_S_X(VS2REG, E23)) \
4568      { \
4569         ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS1REG, I3); \
4570         SET_COMPARE_FLAG(E13); \
4571      } \
4572      else if (R_VREG_S_X(VS1REG, I3) == R_VREG_S_X(VS2REG, E23)) \
4573      { \
4574         ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS1REG, I3); \
4575         if (ZERO_FLAG(E10) && CARRY_FLAG(E13)) SET_COMPARE_FLAG(E13); \
4576      } \
4577      if (R_VREG_S_X(VS1REG, I4) > R_VREG_S_X(VS2REG, E24)) \
4578      { \
4579         ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS2REG, E24); \
4580      } \
4581      else if (R_VREG_S_X(VS1REG, I4) < R_VREG_S_X(VS2REG, E24)) \
4582      { \
4583         ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS1REG, I4); \
4584         SET_COMPARE_FLAG(E14); \
4585      } \
4586      else if (R_VREG_S_X(VS1REG, I4) == R_VREG_S_X(VS2REG, E24)) \
4587      { \
4588         ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS1REG, I4); \
4589         if (ZERO_FLAG(E14) && CARRY_FLAG(E14)) SET_COMPARE_FLAG(E14); \
4590      } \
4591      if (R_VREG_S_X(VS1REG, I5) > R_VREG_S_X(VS2REG, E25)) \
4592      { \
4593         ACCUM(E15).h.low = vres[5] = R_VREG_S_X(VS2REG, E25); \
4594      } \
4595      else if (R_VREG_S_X(VS1REG, I5) < R_VREG_S_X(VS2REG, E25)) \
4596      { \
4597         ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS1REG, I5); \
4598         SET_COMPARE_FLAG(E15); \
4599      } \
4600      else if (R_VREG_S_X(VS1REG, I5) == R_VREG_S_X(VS2REG, E25)) \
4601      { \
4602         ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS1REG, I5); \
4603         if (ZERO_FLAG(E15) && CARRY_FLAG(E15)) SET_COMPARE_FLAG(E15); \
4604      } \
4605      if (R_VREG_S_X(VS1REG, I6) > R_VREG_S_X(VS2REG, E26)) \
4606      { \
4607         ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS2REG, E26); \
4608      } \
4609      else if (R_VREG_S_X(VS1REG, I6) < R_VREG_S_X(VS2REG, E26)) \
4610      { \
4611         ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS1REG, I6); \
4612         SET_COMPARE_FLAG(E16); \
4613      } \
4614      else if (R_VREG_S_X(VS1REG, I6) == R_VREG_S_X(VS2REG, E26)) \
4615      { \
4616         ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS1REG, I6); \
4617         if (ZERO_FLAG(E16) && CARRY_FLAG(E16)) SET_COMPARE_FLAG(E16); \
4618      } \
4619      if (R_VREG_S_X(VS1REG, I7) > R_VREG_S_X(VS2REG, E27)) \
4620      { \
4621         ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS2REG, E27); \
4622      } \
4623      else if (R_VREG_S_X(VS1REG, I7) < R_VREG_S_X(VS2REG, E27)) \
4624      { \
4625         ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS1REG, I7); \
4626         SET_COMPARE_FLAG(E17); \
4627      } \
4628      else if (R_VREG_S_X(VS1REG, I7) == R_VREG_S_X(VS2REG, E27)) \
4629      { \
4630         ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS1REG, I7); \
4631         if (ZERO_FLAG(E17) && CARRY_FLAG(E17)) SET_COMPARE_FLAG(E17); \
4632      } \
4633      rsp->flag[0] = 0; \
4634      W_VREG_S_X(VDREG, 7, vres[0]);         \
4635      W_VREG_S_X(VDREG, 6, vres[1]);         \
4636      W_VREG_S_X(VDREG, 5, vres[2]);         \
4637      W_VREG_S_X(VDREG, 4, vres[3]);         \
4638      W_VREG_S_X(VDREG, 3, vres[4]);         \
4639      W_VREG_S_X(VDREG, 2, vres[5]);         \
4640      W_VREG_S_X(VDREG, 1, vres[6]);         \
4641      W_VREG_S_X(VDREG, 0, vres[7]);         \
4642   }
4643
4644INLINE void cfunc_rsp_vlt(void *param)
19954645{
1996   int i;
4646   rsp_state *rsp = (rsp_state*)param;
4647   int op = rsp->impstate->arg0;
4648   INT16 vres[8] = { 0 };
4649   //int i;
19974650   // 31       25  24     20      15      10      5        0
19984651   // ------------------------------------------------------
19994652   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 100000 |
r6794r6795
20024655   // Sets compare flags if elements in VS1 are less than VS2
20034656   // Moves the element in VS2 to destination vector
20044657
2005   rsp->flag[1] = 0;
2006
2007   for (i=0; i < 8; i++)
4658   switch(EL)
20084659   {
2009      int del = VEC_EL_1(EL, i);
2010      int sel = VEC_EL_2(EL, del);
2011
2012      if (R_VREG_S(VS1REG, del) < R_VREG_S(VS2REG, sel))
2013      {
2014         vres[del] = R_VREG_S(VS1REG, del);
2015         SET_COMPARE_FLAG(del);
2016      }
2017      else if (R_VREG_S(VS1REG, del) == R_VREG_S(VS2REG, sel))
2018      {
2019         vres[del] = R_VREG_S(VS1REG, del);
2020         if (ZERO_FLAG(del) != 0 && CARRY_FLAG(del) != 0)
2021         {
2022            SET_COMPARE_FLAG(del);
2023         }
2024      }
2025      else
2026      {
2027         vres[del] = R_VREG_S(VS2REG, sel);
2028      }
2029
2030      W_ACCUM_L(del, vres[del]);
4660        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
4661           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);
4662           break;
4663        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
4664           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);
4665           break;
4666        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
4667           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);
4668           break;
4669        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
4670           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);
4671           break;
4672        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
4673           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);
4674           break;
4675        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
4676           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);
4677           break;
4678        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
4679           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);
4680           break;
4681        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
4682           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);
4683           break;
4684        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
4685           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);
4686           break;
4687        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
4688           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);
4689           break;
4690        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
4691           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);
4692           break;
4693        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
4694           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);
4695           break;
4696        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
4697           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);
4698           break;
4699        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
4700           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);
4701           break;
4702        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
4703           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);
4704           break;
4705        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
4706           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);
4707           break;
20314708   }
20324709
2033   CLEAR_ZERO_FLAGS();
2034   CLEAR_CARRY_FLAGS();
2035   WRITEBACK_RESULT();
20364710}
20374711
2038INLINE void rsp_veq(rsp_state *rsp, UINT32 op, INT16 *vres)
4712INLINE void cfunc_rsp_veq(void *param)
20394713{
4714   rsp_state *rsp = (rsp_state*)param;
4715   int op = rsp->impstate->arg0;
4716   INT16 vres[8];
20404717   int i;
20414718   // 31       25  24     20      15      10      5        0
20424719   // ------------------------------------------------------
r6794r6795
20654742      }
20664743   }
20674744
2068   CLEAR_ZERO_FLAGS();
2069   CLEAR_CARRY_FLAGS();
4745   rsp->flag[0] = 0;
20704746   WRITEBACK_RESULT();
20714747}
20724748
2073INLINE void rsp_vne(rsp_state *rsp, UINT32 op, INT16 *vres)
4749INLINE void cfunc_rsp_vne(void *param)
20744750{
4751   rsp_state *rsp = (rsp_state*)param;
4752   int op = rsp->impstate->arg0;
4753   INT16 vres[8];
20754754   int i;
20764755   // 31       25  24     20      15      10      5        0
20774756   // ------------------------------------------------------
r6794r6795
21044783      }
21054784   }
21064785
2107   CLEAR_ZERO_FLAGS();
2108   CLEAR_CARRY_FLAGS();
4786   rsp->flag[0] = 0;
21094787   WRITEBACK_RESULT();
21104788}
21114789
2112INLINE void rsp_vge(rsp_state *rsp, UINT32 op, INT16 *vres)
4790#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) \
4791   { \
4792      rsp->flag[1] = 0; \
4793 \
4794      if (R_VREG_S_X(VS1REG, I0) > R_VREG_S_X(VS2REG, E20)) \
4795      { \
4796         ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS1REG, I0); \
4797         SET_COMPARE_FLAG(E10); \
4798      } \
4799      else if (R_VREG_S_X(VS1REG, I0) == R_VREG_S_X(VS2REG, E20)) \
4800      { \
4801         if (!ZERO_FLAG(E10) || !CARRY_FLAG(E10)) \
4802         { \
4803            ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS1REG, I0); \
4804            SET_COMPARE_FLAG(E10); \
4805         } \
4806         else \
4807         { \
4808            ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS2REG, E20); \
4809         } \
4810      } \
4811      else \
4812      { \
4813         ACCUM(E10).h.low = vres[E10] = R_VREG_S_X(VS2REG, E20); \
4814      } \
4815      if (R_VREG_S_X(VS1REG, I1) > R_VREG_S_X(VS2REG, E21)) \
4816      { \
4817         ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS1REG, I1); \
4818         SET_COMPARE_FLAG(E11); \
4819      } \
4820      else if (R_VREG_S_X(VS1REG, I1) == R_VREG_S_X(VS2REG, E21)) \
4821      { \
4822         if (!ZERO_FLAG(E11) || !CARRY_FLAG(E11)) \
4823         { \
4824            ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS1REG, I1); \
4825            SET_COMPARE_FLAG(E11); \
4826         } \
4827         else \
4828         { \
4829            ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS2REG, E21); \
4830         } \
4831      } \
4832      else \
4833      { \
4834         ACCUM(E11).h.low = vres[E11] = R_VREG_S_X(VS2REG, E21); \
4835      } \
4836      if (R_VREG_S_X(VS1REG, I2) > R_VREG_S_X(VS2REG, E22)) \
4837      { \
4838         ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS1REG, I2); \
4839         SET_COMPARE_FLAG(E12); \
4840      } \
4841      else if (R_VREG_S_X(VS1REG, I2) == R_VREG_S_X(VS2REG, E22)) \
4842      { \
4843         if (!ZERO_FLAG(E12) || !CARRY_FLAG(E12)) \
4844         { \
4845            ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS1REG, I2); \
4846            SET_COMPARE_FLAG(E12); \
4847         } \
4848         else \
4849         { \
4850            ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS2REG, E22); \
4851         } \
4852      } \
4853      else \
4854      { \
4855         ACCUM(E12).h.low = vres[E12] = R_VREG_S_X(VS2REG, E22); \
4856      } \
4857      if (R_VREG_S_X(VS1REG, I3) > R_VREG_S_X(VS2REG, E23)) \
4858      { \
4859         ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS1REG, I3); \
4860         SET_COMPARE_FLAG(E13); \
4861      } \
4862      else if (R_VREG_S_X(VS1REG, I3) == R_VREG_S_X(VS2REG, E23)) \
4863      { \
4864         if (!ZERO_FLAG(E13) || !CARRY_FLAG(E13)) \
4865         { \
4866            ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS1REG, I3); \
4867            SET_COMPARE_FLAG(E13); \
4868         } \
4869         else \
4870         { \
4871            ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS2REG, E23); \
4872         } \
4873      } \
4874      else \
4875      { \
4876         ACCUM(E13).h.low = vres[E13] = R_VREG_S_X(VS2REG, E23); \
4877      } \
4878      if (R_VREG_S_X(VS1REG, I4) > R_VREG_S_X(VS2REG, E24)) \
4879      { \
4880         ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS1REG, I4); \
4881         SET_COMPARE_FLAG(E14); \
4882      } \
4883      else if (R_VREG_S_X(VS1REG, I4) == R_VREG_S_X(VS2REG, E24)) \
4884      { \
4885         if (!ZERO_FLAG(E14) || !CARRY_FLAG(E14)) \
4886         { \
4887            ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS1REG, I4); \
4888            SET_COMPARE_FLAG(E14); \
4889         } \
4890         else \
4891         { \
4892            ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS2REG, E24); \
4893         } \
4894      } \
4895      else \
4896      { \
4897         ACCUM(E14).h.low = vres[E14] = R_VREG_S_X(VS2REG, E24); \
4898      } \
4899      if (R_VREG_S_X(VS1REG, I5) > R_VREG_S_X(VS2REG, E25)) \
4900      { \
4901         ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS1REG, I5); \
4902         SET_COMPARE_FLAG(E15); \
4903      } \
4904      else if (R_VREG_S_X(VS1REG, I5) == R_VREG_S_X(VS2REG, E25)) \
4905      { \
4906         if (!ZERO_FLAG(E15) || !CARRY_FLAG(E15)) \
4907         { \
4908            ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS1REG, I5); \
4909            SET_COMPARE_FLAG(E15); \
4910         } \
4911         else \
4912         { \
4913            ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS2REG, E25); \
4914         } \
4915      } \
4916      else \
4917      { \
4918         ACCUM(E15).h.low = vres[E15] = R_VREG_S_X(VS2REG, E25); \
4919      } \
4920      if (R_VREG_S_X(VS1REG, I6) > R_VREG_S_X(VS2REG, E26)) \
4921      { \
4922         ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS1REG, I6); \
4923         SET_COMPARE_FLAG(E16); \
4924      } \
4925      else if (R_VREG_S_X(VS1REG, I6) == R_VREG_S_X(VS2REG, E26)) \
4926      { \
4927         if (!ZERO_FLAG(E16) || !CARRY_FLAG(E16)) \
4928         { \
4929            ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS1REG, I6); \
4930            SET_COMPARE_FLAG(E16); \
4931         } \
4932         else \
4933         { \
4934            ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS2REG, E26); \
4935         } \
4936      } \
4937      else \
4938      { \
4939         ACCUM(E16).h.low = vres[E16] = R_VREG_S_X(VS2REG, E26); \
4940      } \
4941      if (R_VREG_S_X(VS1REG, I7) > R_VREG_S_X(VS2REG, E27)) \
4942      { \
4943         ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS1REG, I7); \
4944         SET_COMPARE_FLAG(E17); \
4945      } \
4946      else if (R_VREG_S_X(VS1REG, I7) == R_VREG_S_X(VS2REG, E27)) \
4947      { \
4948         if (!ZERO_FLAG(E17) || !CARRY_FLAG(E17)) \
4949         { \
4950            ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS1REG, I7); \
4951            SET_COMPARE_FLAG(E17); \
4952         } \
4953         else \
4954         { \
4955            ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS2REG, E27); \
4956         } \
4957      } \
4958      else \
4959      { \
4960         ACCUM(E17).h.low = vres[E17] = R_VREG_S_X(VS2REG, E27); \
4961      } \
4962      rsp->flag[0] = 0; \
4963      W_VREG_S_X(VDREG, 7, vres[0]);         \
4964      W_VREG_S_X(VDREG, 6, vres[1]);         \
4965      W_VREG_S_X(VDREG, 5, vres[2]);         \
4966      W_VREG_S_X(VDREG, 4, vres[3]);         \
4967      W_VREG_S_X(VDREG, 3, vres[4]);         \
4968      W_VREG_S_X(VDREG, 2, vres[5]);         \
4969      W_VREG_S_X(VDREG, 1, vres[6]);         \
4970      W_VREG_S_X(VDREG, 0, vres[7]);         \
4971   }
4972
4973INLINE void cfunc_rsp_vge(void *param)
21134974{
2114   int i;
4975   rsp_state *rsp = (rsp_state*)param;
4976   int op = rsp->impstate->arg0;
4977   INT16 vres[8] = { 0 };
4978   //int i;
21154979   // 31       25  24     20      15      10      5        0
21164980   // ------------------------------------------------------
21174981   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 100011 |
r6794r6795
21204984   // Sets compare flags if elements in VS1 are greater or equal with VS2
21214985   // Moves the element in VS2 to destination vector
21224986
4987#if 1
4988   switch(EL)
4989   {
4990        case 0:    /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
4991           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);
4992           break;
4993        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
4994           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);
4995           break;
4996        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
4997           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);
4998           break;
4999        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
5000           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);
5001           break;
5002        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
5003           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);
5004           break;
5005        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
5006           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);
5007           break;
5008        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
5009           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);
5010           break;
5011        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
5012           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);
5013           break;
5014        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
5015           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);
5016           break;
5017        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
5018           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);
5019           break;
5020        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
5021           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);
5022           break;
5023        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
5024           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);
5025           break;
5026        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
5027           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);
5028           break;
5029        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
5030           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);
5031           break;
5032        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
5033           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);
5034           break;
5035        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
5036           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);
5037           break;
5038   }
5039#else
21235040   rsp->flag[1] = 0;
21245041
21255042   for (i=0; i < 8; i++)
r6794r6795
21515068      W_ACCUM_L(del, vres[del]);
21525069   }
21535070
2154   CLEAR_ZERO_FLAGS();
2155   CLEAR_CARRY_FLAGS();
5071   rsp->flag[0] = 0;
21565072   WRITEBACK_RESULT();
2157
5073#endif
21585074}
21595075
2160INLINE void rsp_vcl(rsp_state *rsp, UINT32 op, INT16 *vres)
5076INLINE void cfunc_rsp_vcl(void *param)
21615077{
5078   rsp_state *rsp = (rsp_state*)param;
5079   int op = rsp->impstate->arg0;
5080   INT16 vres[8];
21625081   int i;
21635082   // 31       25  24     20      15      10      5        0
21645083   // ------------------------------------------------------
r6794r6795
22475166
22485167      vres[del] = ACCUM(del).h.low;
22495168   }
2250   CLEAR_ZERO_FLAGS();
2251   CLEAR_CARRY_FLAGS();
5169   rsp->flag[0] = 0;
22525170   rsp->flag[2] = 0;
22535171   WRITEBACK_RESULT();
22545172}
22555173
2256INLINE void rsp_vch(rsp_state *rsp, UINT32 op, INT16 *vres)
5174INLINE void cfunc_rsp_vch(void *param)
22575175{
5176   rsp_state *rsp = (rsp_state*)param;
5177   int op = rsp->impstate->arg0;
5178   INT16 vres[8];
22585179   int i;
22595180   // 31       25  24     20      15      10      5        0
22605181   // ------------------------------------------------------
r6794r6795
22635184   //
22645185   // Vector clip high
22655186
2266   CLEAR_ZERO_FLAGS();
2267   CLEAR_CARRY_FLAGS();
5187   rsp->flag[0] = 0;
22685188   rsp->flag[1] = 0;
22695189   rsp->flag[2] = 0;
22705190
r6794r6795
23355255   WRITEBACK_RESULT();
23365256}
23375257
2338INLINE void rsp_vcr(rsp_state *rsp, UINT32 op, INT16 *vres)
5258INLINE void cfunc_rsp_vcr(void *param)
23395259{
5260   rsp_state *rsp = (rsp_state*)param;
5261   int op = rsp->impstate->arg0;
5262   INT16 vres[8];
23405263   int i;
23415264   // 31       25  24     20      15      10      5        0
23425265   // ------------------------------------------------------
r6794r6795
23945317   WRITEBACK_RESULT();
23955318}
23965319
2397//  switch(EL)
2398//  {
2399//      case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */     /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
2400//          break;
2401//      case 1: /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */     /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
2402//          break;
2403//      case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */     /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2404//          break;
2405//      case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */     /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2406//          break;
2407//      case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */     /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2408//          break;
2409//      case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */     /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2410//          break;
2411//      case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */     /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2412//          break;
2413//      case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */     /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2414//          break;
2415//      case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */     /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
2416//          break;
2417//      case 9: /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */     /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
2418//          break;
2419//      case 10:/* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */     /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
2420//          break;
2421//      case 11:/* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */     /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
2422//          break;
2423//      case 12:/* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */     /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
2424//          break;
2425//      case 13:/* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */     /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
2426//          break;
2427//      case 14:/* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */     /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
2428//          break;
2429//      case 15:/* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */     /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
2430//          break;
2431//  }
2432
24335320#define RSP_VMRG(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
24345321   if (COMPARE_FLAG(E10))               \
24355322   {                              \
r6794r6795
25045391   W_ACCUM_L(E16, vres[E16]);            \
25055392   W_ACCUM_L(E17, vres[E17]);            \
25065393
2507INLINE void rsp_vmrg(rsp_state *rsp, UINT32 op, INT16 *vres)
5394INLINE void cfunc_rsp_vmrg(void *param)
25085395{
5396   rsp_state *rsp = (rsp_state*)param;
5397   int op = rsp->impstate->arg0;
5398   INT16 vres[8] = { 0 };
25095399   // 31       25  24     20      15      10      5        0
25105400   // ------------------------------------------------------
25115401   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 100111 |
r6794r6795
25225412           RSP_VMRG(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
25235413           break;
25245414        case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2525           RSP_VMRG(1, 3, 5, 7, 0, 2, 4, 6, 0, 0, 2, 2, 4, 4, 6, 6);
5415           RSP_VMRG(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
25265416           break;
25275417        case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2528           RSP_VMRG(0, 2, 4, 6, 1, 3, 5, 7, 1, 1, 3, 3, 5, 5, 7, 7);
5418           RSP_VMRG(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
25295419           break;
25305420        case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2531           RSP_VMRG(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 0, 4, 4, 4, 4);
5421           RSP_VMRG(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
25325422           break;
25335423        case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2534           RSP_VMRG(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 1, 5, 5, 5, 5);
5424           RSP_VMRG(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
25355425           break;
25365426        case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2537           RSP_VMRG(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6);
5427           RSP_VMRG(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
25385428           break;
25395429        case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2540           RSP_VMRG(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 3, 7, 7, 7, 7);
5430           RSP_VMRG(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
25415431           break;
25425432        case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
25435433           RSP_VMRG(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
r6794r6795
25675457     WRITEBACK_RESULT();
25685458}
25695459
5460#if (DRC_VAND)
5461#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) \
5462   { \
5463      UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
5464      UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
5465      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5466      UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
5467 \
5468      UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
5469      UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
5470      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5471      UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
5472 \
5473      UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
5474      UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
5475      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5476      UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
5477 \
5478      UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
5479      UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
5480      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5481      UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
5482 \
5483      UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
5484      UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
5485      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5486      UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
5487 \
5488      UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
5489      UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
5490      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5491      UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
5492 \
5493      UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
5494      UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
5495      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5496      UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
5497 \
5498      UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
5499      UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
5500      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5501      UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
5502 \
5503      UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
5504      UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
5505      UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
5506      UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
5507      UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
5508      UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
5509      UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
5510      UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
5511      UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
5512      UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
5513      UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
5514      UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
5515      UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
5516      UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
5517      UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
5518      UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
5519   }
5520
5521static int generate_vand(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
5522{
5523   UINT32 op = desc->opptr.l[0];
5524
5525   // 31       25  24     20      15      10      5        0
5526   // ------------------------------------------------------
5527   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
5528   // ------------------------------------------------------
5529   //
5530   // Bitwise AND of two vector registers
5531
5532     switch(EL)
5533     {
5534        case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
5535           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);
5536           return TRUE;
5537        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
5538           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);
5539           return TRUE;
5540        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
5541           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);
5542           return TRUE;
5543        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
5544           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);
5545           return TRUE;
5546        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
5547           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);
5548           return TRUE;
5549        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
5550           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);
5551           return TRUE;
5552        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
5553           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);
5554           return TRUE;
5555        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
5556           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);
5557           return TRUE;
5558        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
5559           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);
5560           return TRUE;
5561        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
5562           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);
5563           return TRUE;
5564        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
5565           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);
5566           return TRUE;
5567        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
5568           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);
5569           return TRUE;
5570        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
5571           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);
5572           return TRUE;
5573        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
5574           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);
5575           return TRUE;
5576        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
5577           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);
5578           return TRUE;
5579        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
5580           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);
5581           return TRUE;
5582     }
5583
5584     return TRUE;
5585}
5586#else
25705587#define RSP_VAND(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
25715588   vres[E10] = R_VREG_S(VS1REG, E10) & R_VREG_S(VS2REG, E20);   \
25725589   vres[E11] = R_VREG_S(VS1REG, E11) & R_VREG_S(VS2REG, E21);   \
r6794r6795
25855602   W_ACCUM_L(E16, vres[E16]);            \
25865603   W_ACCUM_L(E17, vres[E17]);            \
25875604
2588INLINE void rsp_vand(rsp_state *rsp, UINT32 op, INT16 *vres)
5605INLINE void cfunc_rsp_vand(void *param)
25895606{
5607   rsp_state *rsp = (rsp_state*)param;
5608   int op = rsp->impstate->arg0;
5609   INT16 vres[8] = { 0 };
25905610   // 31       25  24     20      15      10      5        0
25915611   // ------------------------------------------------------
25925612   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
r6794r6795
26035623           RSP_VAND(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
26045624           break;
26055625        case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2606           RSP_VAND(1, 3, 5, 7, 0, 2, 4, 6, 0, 0, 2, 2, 4, 4, 6, 6);
5626           RSP_VAND(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
26075627           break;
26085628        case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2609           RSP_VAND(0, 2, 4, 6, 1, 3, 5, 7, 1, 1, 3, 3, 5, 5, 7, 7);
5629           RSP_VAND(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
26105630           break;
26115631        case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2612           RSP_VAND(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 0, 4, 4, 4, 4);
5632           RSP_VAND(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
26135633           break;
26145634        case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2615           RSP_VAND(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 1, 5, 5, 5, 5);
5635           RSP_VAND(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
26165636           break;
26175637        case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2618           RSP_VAND(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6);
5638           RSP_VAND(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
26195639           break;
26205640        case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2621           RSP_VAND(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 3, 7, 7, 7, 7);
5641           RSP_VAND(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
26225642           break;
26235643        case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
26245644           RSP_VAND(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
r6794r6795
26475667     }
26485668     WRITEBACK_RESULT();
26495669}
5670#endif
26505671
5672#if (DRC_VNAND)
5673#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) \
5674   { \
5675      UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
5676      UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
5677      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5678      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
5679      UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
5680 \
5681      UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
5682      UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
5683      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5684      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
5685      UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
5686 \
5687      UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
5688      UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
5689      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5690      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
5691      UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
5692 \
5693      UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
5694      UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
5695      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5696      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
5697      UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
5698 \
5699      UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
5700      UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
5701      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5702      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
5703      UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
5704 \
5705      UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
5706      UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
5707      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5708      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
5709      UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
5710 \
5711      UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
5712      UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
5713      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5714      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
5715      UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
5716 \
5717      UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
5718      UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
5719      UML_AND(block, IREG(0), IREG(0), IREG(1)); \
5720      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
5721      UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
5722 \
5723      UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
5724      UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
5725      UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
5726      UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
5727      UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
5728      UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
5729      UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
5730      UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
5731      UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
5732      UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
5733      UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
5734      UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
5735      UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
5736      UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
5737      UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
5738      UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
5739   }
5740
5741static int generate_vnand(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
5742{
5743   UINT32 op = desc->opptr.l[0];
5744
5745   // 31       25  24     20      15      10      5        0
5746   // ------------------------------------------------------
5747   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
5748   // ------------------------------------------------------
5749   //
5750   // Bitwise NOT AND of two vector registers
5751
5752     switch(EL)
5753     {
5754        case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
5755           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);
5756           return TRUE;
5757        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
5758           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);
5759           return TRUE;
5760        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
5761           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);
5762           return TRUE;
5763        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
5764           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);
5765           return TRUE;
5766        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
5767           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);
5768           return TRUE;
5769        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
5770           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);
5771           return TRUE;
5772        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
5773           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);
5774           return TRUE;
5775        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
5776           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);
5777           return TRUE;
5778        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
5779           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);
5780           return TRUE;
5781        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
5782           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);
5783           return TRUE;
5784        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
5785           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);
5786           return TRUE;
5787        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
5788           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);
5789           return TRUE;
5790        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
5791           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);
5792           return TRUE;
5793        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
5794           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);
5795           return TRUE;
5796        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
5797           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);
5798           return TRUE;
5799        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
5800           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);
5801           return TRUE;
5802     }
5803
5804     return TRUE;
5805}
5806#else
26515807#define RSP_VNAND(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
26525808   vres[E10] = ~(R_VREG_S(VS1REG, E10) & R_VREG_S(VS2REG, E20));   \
26535809   vres[E11] = ~(R_VREG_S(VS1REG, E11) & R_VREG_S(VS2REG, E21));   \
r6794r6795
26665822   W_ACCUM_L(E16, vres[E16]);            \
26675823   W_ACCUM_L(E17, vres[E17]);            \
26685824
2669INLINE void rsp_vnand(rsp_state *rsp, UINT32 op, INT16 *vres)
5825INLINE void cfunc_rsp_vnand(void *param)
26705826{
5827   rsp_state *rsp = (rsp_state*)param;
5828   int op = rsp->impstate->arg0;
5829   INT16 vres[8] = { 0 };
26715830   // 31       25  24     20      15      10      5        0
26725831   // ------------------------------------------------------
26735832   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101001 |
r6794r6795
26845843           RSP_VNAND(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
26855844           break;
26865845        case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2687           RSP_VNAND(1, 3, 5, 7, 0, 2, 4, 6, 0, 0, 2, 2, 4, 4, 6, 6);
5846           RSP_VNAND(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
26885847           break;
26895848        case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2690           RSP_VNAND(0, 2, 4, 6, 1, 3, 5, 7, 1, 1, 3, 3, 5, 5, 7, 7);
5849           RSP_VNAND(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
26915850           break;
26925851        case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2693           RSP_VNAND(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 0, 4, 4, 4, 4);
5852           RSP_VNAND(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
26945853           break;
26955854        case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2696           RSP_VNAND(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 1, 5, 5, 5, 5);
5855           RSP_VNAND(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
26975856           break;
26985857        case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2699           RSP_VNAND(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6);
5858           RSP_VNAND(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
27005859           break;
27015860        case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2702           RSP_VNAND(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 3, 7, 7, 7, 7);
5861           RSP_VNAND(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
27035862           break;
27045863        case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
27055864           RSP_VNAND(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
r6794r6795
27285887     }
27295888     WRITEBACK_RESULT();
27305889}
5890#endif
27315891
5892#if (DRC_VOR)
5893#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) \
5894   { \
5895      UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
5896      UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
5897      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
5898      UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
5899 \
5900      UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
5901      UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
5902      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
5903      UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
5904 \
5905      UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
5906      UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
5907      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
5908      UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
5909 \
5910      UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
5911      UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
5912      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
5913      UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
5914 \
5915      UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
5916      UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
5917      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
5918      UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
5919 \
5920      UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
5921      UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
5922      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
5923      UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
5924 \
5925      UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
5926      UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
5927      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
5928      UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
5929 \
5930      UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
5931      UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
5932      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
5933      UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
5934 \
5935      UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
5936      UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
5937      UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
5938      UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
5939      UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
5940      UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
5941      UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
5942      UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
5943      UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
5944      UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
5945      UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
5946      UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
5947      UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
5948      UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
5949      UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
5950      UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
5951   }
5952
5953static int generate_vor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
5954{
5955   UINT32 op = desc->opptr.l[0];
5956
5957   // 31       25  24     20      15      10      5        0
5958   // ------------------------------------------------------
5959   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
5960   // ------------------------------------------------------
5961   //
5962   // Bitwise OR of two vector registers
5963
5964     switch(EL)
5965     {
5966        case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
5967           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);
5968           return TRUE;
5969        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
5970           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);
5971           return TRUE;
5972        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
5973           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);
5974           return TRUE;
5975        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
5976           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);
5977           return TRUE;
5978        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
5979           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);
5980           return TRUE;
5981        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
5982           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);
5983           return TRUE;
5984        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
5985           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);
5986           return TRUE;
5987        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
5988           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);
5989           return TRUE;
5990        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
5991           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);
5992           return TRUE;
5993        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
5994           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);
5995           return TRUE;
5996        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
5997           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);
5998           return TRUE;
5999        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
6000           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);
6001           return TRUE;
6002        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
6003           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);
6004           return TRUE;
6005        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
6006           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);
6007           return TRUE;
6008        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
6009           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);
6010           return TRUE;
6011        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
6012           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);
6013           return TRUE;
6014     }
6015
6016     return TRUE;
6017}
6018#else
27326019#define RSP_VOR(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
27336020   vres[E10] = R_VREG_S(VS1REG, E10) | R_VREG_S(VS2REG, E20);   \
27346021   vres[E11] = R_VREG_S(VS1REG, E11) | R_VREG_S(VS2REG, E21);   \
r6794r6795
27476034   W_ACCUM_L(E16, vres[E16]);                           \
27486035   W_ACCUM_L(E17, vres[E17]);                           \
27496036
2750INLINE void rsp_vor(rsp_state *rsp, UINT32 op, INT16 *vres)
6037INLINE void cfunc_rsp_vor(void *param)
27516038{
6039   rsp_state *rsp = (rsp_state*)param;
6040   int op = rsp->impstate->arg0;
6041   INT16 vres[8] = { 0 };;
27526042   // 31       25  24     20      15      10      5        0
27536043   // ------------------------------------------------------
27546044   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101010 |
r6794r6795
27656055           RSP_VOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
27666056           break;
27676057        case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2768           RSP_VOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 0, 2, 2, 4, 4, 6, 6);
6058           RSP_VOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
27696059           break;
27706060        case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2771           RSP_VOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 1, 3, 3, 5, 5, 7, 7);
6061           RSP_VOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
27726062           break;
27736063        case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2774           RSP_VOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 0, 4, 4, 4, 4);
6064           RSP_VOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
27756065           break;
27766066        case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2777           RSP_VOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 1, 5, 5, 5, 5);
6067           RSP_VOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
27786068           break;
27796069        case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2780           RSP_VOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6);
6070           RSP_VOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
27816071           break;
27826072        case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2783           RSP_VOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 3, 7, 7, 7, 7);
6073           RSP_VOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
27846074           break;
27856075        case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
27866076           RSP_VOR(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
r6794r6795
28096099     }
28106100     WRITEBACK_RESULT();
28116101}
6102#endif
28126103
6104#if (DRC_VNOR)
6105#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) \
6106   { \
6107      UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
6108      UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
6109      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
6110      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6111      UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
6112 \
6113      UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
6114      UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
6115      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
6116      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6117      UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
6118 \
6119      UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
6120      UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
6121      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
6122      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6123      UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
6124 \
6125      UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
6126      UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
6127      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
6128      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6129      UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
6130 \
6131      UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
6132      UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
6133      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
6134      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6135      UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
6136 \
6137      UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
6138      UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
6139      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
6140      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6141      UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
6142 \
6143      UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
6144      UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
6145      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
6146      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6147      UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
6148 \
6149      UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
6150      UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
6151      UML_OR(block, IREG(0), IREG(0), IREG(1)); \
6152      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6153      UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
6154 \
6155      UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
6156      UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
6157      UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
6158      UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
6159      UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
6160      UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
6161      UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
6162      UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
6163      UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
6164      UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
6165      UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
6166      UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
6167      UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
6168      UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
6169      UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
6170      UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
6171   }
6172
6173static int generate_vnor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
6174{
6175   UINT32 op = desc->opptr.l[0];
6176
6177   // 31       25  24     20      15      10      5        0
6178   // ------------------------------------------------------
6179   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
6180   // ------------------------------------------------------
6181   //
6182   // Bitwise NOT OR of two vector registers
6183
6184     switch(EL)
6185     {
6186        case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
6187           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);
6188           return TRUE;
6189        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
6190           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);
6191           return TRUE;
6192        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
6193           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);
6194           return TRUE;
6195        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
6196           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);
6197           return TRUE;
6198        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
6199           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);
6200           return TRUE;
6201        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
6202           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);
6203           return TRUE;
6204        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
6205           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);
6206           return TRUE;
6207        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
6208           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);
6209           return TRUE;
6210        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
6211           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);
6212           return TRUE;
6213        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
6214           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);
6215           return TRUE;
6216        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
6217           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);
6218           return TRUE;
6219        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
6220           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);
6221           return TRUE;
6222        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
6223           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);
6224           return TRUE;
6225        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
6226           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);
6227           return TRUE;
6228        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
6229           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);
6230           return TRUE;
6231        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
6232           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);
6233           return TRUE;
6234     }
6235
6236     return TRUE;
6237}
6238#else
28136239#define RSP_VNOR(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
28146240   vres[E10] = ~(R_VREG_S(VS1REG, E10) | R_VREG_S(VS2REG, E20));   \
28156241   vres[E11] = ~(R_VREG_S(VS1REG, E11) | R_VREG_S(VS2REG, E21));   \
r6794r6795
28286254   W_ACCUM_L(E16, vres[E16]);                              \
28296255   W_ACCUM_L(E17, vres[E17]);                              \
28306256
2831INLINE void rsp_vnor(rsp_state *rsp, UINT32 op, INT16 *vres)
6257INLINE void cfunc_rsp_vnor(void *param)
28326258{
6259   rsp_state *rsp = (rsp_state*)param;
6260   int op = rsp->impstate->arg0;
6261   INT16 vres[8] = { 0 };;
28336262   // 31       25  24     20      15      10      5        0
28346263   // ------------------------------------------------------
28356264   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101011 |
r6794r6795
28466275           RSP_VNOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
28476276           break;
28486277        case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2849           RSP_VNOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 0, 2, 2, 4, 4, 6, 6);
6278           RSP_VNOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
28506279           break;
28516280        case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2852           RSP_VNOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 1, 3, 3, 5, 5, 7, 7);
6281           RSP_VNOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
28536282           break;
28546283        case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2855           RSP_VNOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 0, 4, 4, 4, 4);
6284           RSP_VNOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
28566285           break;
28576286        case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2858           RSP_VNOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 1, 5, 5, 5, 5);
6287           RSP_VNOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
28596288           break;
28606289        case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2861           RSP_VNOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6);
6290           RSP_VNOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
28626291           break;
28636292        case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2864           RSP_VNOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 3, 7, 7, 7, 7);
6293           RSP_VNOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
28656294           break;
28666295        case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
28676296           RSP_VNOR(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
r6794r6795
28906319     }
28916320     WRITEBACK_RESULT();
28926321}
6322#endif
28936323
6324#if (DRC_VXOR)
6325#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) \
6326   { \
6327      UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
6328      UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
6329      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6330      UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
6331 \
6332      UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
6333      UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
6334      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6335      UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
6336 \
6337      UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
6338      UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
6339      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6340      UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
6341 \
6342      UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
6343      UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
6344      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6345      UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
6346 \
6347      UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
6348      UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
6349      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6350      UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
6351 \
6352      UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
6353      UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
6354      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6355      UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
6356 \
6357      UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
6358      UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
6359      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6360      UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
6361 \
6362      UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
6363      UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
6364      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6365      UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
6366 \
6367      UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
6368      UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
6369      UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
6370      UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
6371      UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
6372      UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
6373      UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
6374      UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
6375      UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
6376      UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
6377      UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
6378      UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
6379      UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
6380      UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
6381      UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
6382      UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
6383   }
6384
6385static int generate_vxor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
6386{
6387   UINT32 op = desc->opptr.l[0];
6388
6389   // 31       25  24     20      15      10      5        0
6390   // ------------------------------------------------------
6391   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
6392   // ------------------------------------------------------
6393   //
6394   // Bitwise XOR of two vector registers
6395
6396     switch(EL)
6397     {
6398        case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
6399           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);
6400           return TRUE;
6401        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
6402           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);
6403           return TRUE;
6404        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
6405           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);
6406           return TRUE;
6407        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
6408           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);
6409           return TRUE;
6410        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
6411           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);
6412           return TRUE;
6413        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
6414           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);
6415           return TRUE;
6416        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
6417           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);
6418           return TRUE;
6419        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
6420           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);
6421           return TRUE;
6422        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
6423           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);
6424           return TRUE;
6425        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
6426           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);
6427           return TRUE;
6428        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
6429           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);
6430           return TRUE;
6431        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
6432           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);
6433           return TRUE;
6434        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
6435           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);
6436           return TRUE;
6437        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
6438           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);
6439           return TRUE;
6440        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
6441           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);
6442           return TRUE;
6443        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
6444           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);
6445           return TRUE;
6446     }
6447
6448     return TRUE;
6449}
6450#else
28946451#define RSP_VXOR(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
28956452   vres[E10] = R_VREG_S(VS1REG, E10) ^ R_VREG_S(VS2REG, E20);   \
28966453   vres[E11] = R_VREG_S(VS1REG, E11) ^ R_VREG_S(VS2REG, E21);   \
r6794r6795
29096466   W_ACCUM_L(E16, vres[E16]);                           \
29106467   W_ACCUM_L(E17, vres[E17]);                           \
29116468
2912INLINE void rsp_vxor(rsp_state *rsp, UINT32 op, INT16 *vres)
6469INLINE void cfunc_rsp_vxor(void *param)
29136470{
6471   rsp_state *rsp = (rsp_state*)param;
6472   int op = rsp->impstate->arg0;
6473   INT16 vres[8] = { 0 };;
29146474   // 31       25  24     20      15      10      5        0
29156475   // ------------------------------------------------------
29166476   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101100 |
r6794r6795
29276487           RSP_VXOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
29286488           break;
29296489        case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
2930           RSP_VXOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 0, 2, 2, 4, 4, 6, 6);
6490           RSP_VXOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
29316491           break;
29326492        case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
2933           RSP_VXOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 1, 3, 3, 5, 5, 7, 7);
6493           RSP_VXOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
29346494           break;
29356495        case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
2936           RSP_VXOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 0, 4, 4, 4, 4);
6496           RSP_VXOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
29376497           break;
29386498        case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
2939           RSP_VXOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 1, 5, 5, 5, 5);
6499           RSP_VXOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
29406500           break;
29416501        case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
2942           RSP_VXOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6);
6502           RSP_VXOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
29436503           break;
29446504        case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
2945           RSP_VXOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 3, 7, 7, 7, 7);
6505           RSP_VXOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
29466506           break;
29476507        case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
29486508           RSP_VXOR(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
r6794r6795
29716531     }
29726532     WRITEBACK_RESULT();
29736533}
6534#endif
29746535
6536#if (DRC_VNXOR)
6537#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) \
6538   { \
6539      UML_SEXT(block, IREG(0), VS(VS1REG, I0), WORD); \
6540      UML_SEXT(block, IREG(1), VS(VS2REG, E20), WORD); \
6541      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6542      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6543      UML_STORE(block, &rsp->accum[E10].h.low, IMM(0), IREG(0), WORD); \
6544 \
6545      UML_SEXT(block, IREG(0), VS(VS1REG, I1), WORD); \
6546      UML_SEXT(block, IREG(1), VS(VS2REG, E21), WORD); \
6547      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6548      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6549      UML_STORE(block, &rsp->accum[E11].h.low, IMM(0), IREG(0), WORD); \
6550 \
6551      UML_SEXT(block, IREG(0), VS(VS1REG, I2), WORD); \
6552      UML_SEXT(block, IREG(1), VS(VS2REG, E22), WORD); \
6553      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6554      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6555      UML_STORE(block, &rsp->accum[E12].h.low, IMM(0), IREG(0), WORD); \
6556 \
6557      UML_SEXT(block, IREG(0), VS(VS1REG, I3), WORD); \
6558      UML_SEXT(block, IREG(1), VS(VS2REG, E23), WORD); \
6559      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6560      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6561      UML_STORE(block, &rsp->accum[E13].h.low, IMM(0), IREG(0), WORD); \
6562 \
6563      UML_SEXT(block, IREG(0), VS(VS1REG, I4), WORD); \
6564      UML_SEXT(block, IREG(1), VS(VS2REG, E24), WORD); \
6565      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6566      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6567      UML_STORE(block, &rsp->accum[E14].h.low, IMM(0), IREG(0), WORD); \
6568 \
6569      UML_SEXT(block, IREG(0), VS(VS1REG, I5), WORD); \
6570      UML_SEXT(block, IREG(1), VS(VS2REG, E25), WORD); \
6571      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6572      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6573      UML_STORE(block, &rsp->accum[E15].h.low, IMM(0), IREG(0), WORD); \
6574 \
6575      UML_SEXT(block, IREG(0), VS(VS1REG, I6), WORD); \
6576      UML_SEXT(block, IREG(1), VS(VS2REG, E26), WORD); \
6577      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6578      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6579      UML_STORE(block, &rsp->accum[E16].h.low, IMM(0), IREG(0), WORD); \
6580 \
6581      UML_SEXT(block, IREG(0), VS(VS1REG, I7), WORD); \
6582      UML_SEXT(block, IREG(1), VS(VS2REG, E27), WORD); \
6583      UML_XOR(block, IREG(0), IREG(0), IREG(1)); \
6584      UML_XOR(block, IREG(0), IREG(0), IMM(0xffffffff)); \
6585      UML_STORE(block, &rsp->accum[E17].h.low, IMM(0), IREG(0), WORD); \
6586 \
6587      UML_LOAD(block, IREG(0), &rsp->accum[E10].h.low, IMM(0), WORD); \
6588      UML_STORE(block, &rsp->v[VDREG].s[I0], IMM(0), IREG(0), WORD); \
6589      UML_LOAD(block, IREG(0), &rsp->accum[E11].h.low, IMM(0), WORD); \
6590      UML_STORE(block, &rsp->v[VDREG].s[I1], IMM(0), IREG(0), WORD); \
6591      UML_LOAD(block, IREG(0), &rsp->accum[E12].h.low, IMM(0), WORD); \
6592      UML_STORE(block, &rsp->v[VDREG].s[I2], IMM(0), IREG(0), WORD); \
6593      UML_LOAD(block, IREG(0), &rsp->accum[E13].h.low, IMM(0), WORD); \
6594      UML_STORE(block, &rsp->v[VDREG].s[I3], IMM(0), IREG(0), WORD); \
6595      UML_LOAD(block, IREG(0), &rsp->accum[E14].h.low, IMM(0), WORD); \
6596      UML_STORE(block, &rsp->v[VDREG].s[I4], IMM(0), IREG(0), WORD); \
6597      UML_LOAD(block, IREG(0), &rsp->accum[E15].h.low, IMM(0), WORD); \
6598      UML_STORE(block, &rsp->v[VDREG].s[I5], IMM(0), IREG(0), WORD); \
6599      UML_LOAD(block, IREG(0), &rsp->accum[E16].h.low, IMM(0), WORD); \
6600      UML_STORE(block, &rsp->v[VDREG].s[I6], IMM(0), IREG(0), WORD); \
6601      UML_LOAD(block, IREG(0), &rsp->accum[E17].h.low, IMM(0), WORD); \
6602      UML_STORE(block, &rsp->v[VDREG].s[I7], IMM(0), IREG(0), WORD); \
6603   }
6604
6605static int generate_vnxor(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
6606{
6607   UINT32 op = desc->opptr.l[0];
6608
6609   // 31       25  24     20      15      10      5        0
6610   // ------------------------------------------------------
6611   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101000 |
6612   // ------------------------------------------------------
6613   //
6614   // Bitwise NOT XOR of two vector registers
6615
6616     switch(EL)
6617     {
6618        case 0: /* 0, 1, 2, 3, 4, 5, 6, 7 - none */      /* 0, 1, 2, 3, 4, 5, 6, 7 - none */
6619           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);
6620           return TRUE;
6621        case 1:    /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */      /* 0, 1, 2, 3, 4, 5, 6, 7 - ???  */
6622           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);
6623           return TRUE;
6624        case 2:    /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
6625           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);
6626           return TRUE;
6627        case 3:    /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
6628           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);
6629           return TRUE;
6630        case 4:    /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
6631           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);
6632           return TRUE;
6633        case 5:    /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
6634           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);
6635           return TRUE;
6636        case 6:    /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
6637           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);
6638           return TRUE;
6639        case 7:    /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
6640           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);
6641           return TRUE;
6642        case 8:    /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
6643           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);
6644           return TRUE;
6645        case 9:    /* 0, 2, 3, 4, 5, 6, 7, 1 - 1    */      /*  1, 1, 1, 1, 1, 1, 1, 1 - 0    */
6646           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);
6647           return TRUE;
6648        case 10:   /* 0, 1, 3, 4, 5, 6, 7, 2 - 2    */      /*  2, 2, 2, 2, 2, 2, 2, 2 - 0    */
6649           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);
6650           return TRUE;
6651        case 11:   /* 0, 1, 2, 4, 5, 6, 7, 3 - 3    */      /*  3, 3, 3, 3, 3, 3, 3, 3 - 0    */
6652           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);
6653           return TRUE;
6654        case 12:   /* 0, 1, 2, 3, 5, 6, 7, 4 - 4    */      /*  4, 4, 4, 4, 4, 4, 4, 4 - 0    */
6655           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);
6656           return TRUE;
6657        case 13:   /* 0, 1, 2, 3, 4, 6, 7, 5 - 5    */      /*  5, 5, 5, 5, 5, 5, 5, 5 - 0    */
6658           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);
6659           return TRUE;
6660        case 14:   /* 0, 1, 2, 3, 4, 5, 7, 6 - 6    */      /*  6, 6, 6, 6, 6, 6, 6, 6 - 0    */
6661           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);
6662           return TRUE;
6663        case 15:   /* 0, 1, 2, 3, 4, 5, 6, 7 - 7    */      /*  7, 7, 7, 7, 7, 7, 7, 7 - 0    */
6664           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);
6665           return TRUE;
6666     }
6667
6668     return TRUE;
6669}
6670#else
29756671#define RSP_VNXOR(E10, E11, E12, E13, E14, E15, E16, E17, E20, E21, E22, E23, E24, E25, E26, E27) \
29766672   vres[E10] = ~(R_VREG_S(VS1REG, E10) ^ R_VREG_S(VS2REG, E20));   \
29776673   vres[E11] = ~(R_VREG_S(VS1REG, E11) ^ R_VREG_S(VS2REG, E21));   \
r6794r6795
29906686   W_ACCUM_L(E16, vres[E16]);                              \
29916687   W_ACCUM_L(E17, vres[E17]);                              \
29926688
2993INLINE void rsp_vnxor(rsp_state *rsp, UINT32 op, INT16 *vres)
6689INLINE void cfunc_rsp_vnxor(void *param)
29946690{
6691   rsp_state *rsp = (rsp_state*)param;
6692   int op = rsp->impstate->arg0;
6693   INT16 vres[8] = { 0 };;
29956694   // 31       25  24     20      15      10      5        0
29966695   // ------------------------------------------------------
29976696   // | 010010 | 1 | EEEE | SSSSS | TTTTT | DDDDD | 101101 |
r6794r6795
30086707           RSP_VNXOR(0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7);
30096708           break;
30106709        case 2: /* 1, 3, 5, 7, 0, 2, 4, 6 - 0q   */      /* 0, 0, 2, 2, 4, 4, 6, 6 - 0q   */
3011           RSP_VNXOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 0, 2, 2, 4, 4, 6, 6);
6710           RSP_VNXOR(1, 3, 5, 7, 0, 2, 4, 6, 0, 2, 4, 6, 0, 2, 4, 6);
30126711           break;
30136712        case 3: /* 0, 2, 4, 6, 1, 3, 5, 7 - 1q   */      /* 1, 1, 3, 3, 5, 5, 7, 7 - 1q   */
3014           RSP_VNXOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 1, 3, 3, 5, 5, 7, 7);
6713           RSP_VNXOR(0, 2, 4, 6, 1, 3, 5, 7, 1, 3, 5, 7, 1, 3, 5, 7);
30156714           break;
30166715        case 4: /* 1, 2, 3, 5, 6, 7, 0, 4 - 0h   */      /* 0, 0, 0, 0, 4, 4, 4, 4 - 0h   */
3017           RSP_VNXOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 0, 4, 4, 4, 4);
6716           RSP_VNXOR(1, 2, 3, 5, 6, 7, 0, 4, 0, 0, 0, 4, 4, 4, 0, 4);
30186717           break;
30196718        case 5: /* 0, 2, 3, 4, 6, 7, 1, 5 - 1h   */      /* 1, 1, 1, 1, 5, 5, 5, 5 - 1h   */
3020           RSP_VNXOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 1, 5, 5, 5, 5);
6719           RSP_VNXOR(0, 2, 3, 4, 6, 7, 1, 5, 1, 1, 1, 5, 5, 5, 1, 5);
30216720           break;
30226721        case 6: /* 0, 1, 3, 4, 5, 7, 2, 6 - 2h   */      /* 2, 2, 2, 2, 6, 6, 6, 6 - 2h   */
3023           RSP_VNXOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 2, 6, 6, 6, 6);
6722           RSP_VNXOR(0, 1, 3, 4, 5, 7, 2, 6, 2, 2, 2, 6, 6, 6, 2, 6);
30246723           break;
30256724        case 7: /* 0, 1, 2, 4, 5, 6, 3, 7 - 3h   */      /* 3, 3, 3, 3, 7, 7, 7, 7 - 3h   */
3026           RSP_VNXOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 3, 7, 7, 7, 7);
6725           RSP_VNXOR(0, 1, 2, 4, 5, 6, 3, 7, 3, 3, 3, 7, 7, 7, 3, 7);
30276726           break;
30286727        case 8: /* 1, 2, 3, 4, 5, 6, 7, 0 - 0    */      /*  0, 0, 0, 0, 0, 0, 0, 0 - 0    */
30296728           RSP_VNXOR(1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0);
r6794r6795
30526751     }
30536752     WRITEBACK_RESULT();
30546753}
6754#endif
30556755
3056INLINE void rsp_vrcp(rsp_state *rsp, UINT32 op, INT16 *vres)
6756INLINE void cfunc_rsp_vrcp(void *param)
30576757{
6758   rsp_state *rsp = (rsp_state*)param;
6759   int op = rsp->impstate->arg0;
30586760   int i;
30596761   // 31       25  24     20      15      10      5        0
30606762   // ------------------------------------------------------
r6794r6795
30636765   //
30646766   // Calculates reciprocal
30656767
3066   int del = (VS1REG & 7);
3067   int sel = EL & 7;
6768   int del = 7 - (VS1REG & 7);
6769   int sel = 7 - (EL & 7);
30686770   INT32 rec;
30696771
3070   rec = (INT16)(R_VREG_S(VS2REG, sel));
6772   rec = (INT16)(R_VREG_S_X(VS2REG, sel));
30716773
30726774   if (rec == 0)
30736775   {
r6794r6795
31356837   for (i=0; i < 8; i++)
31366838   {
31376839      int element = VEC_EL_2(EL, i);
3138      W_ACCUM_L(i, R_VREG_S(VS2REG, element));
6840      W_ACCUM_L(i, R_VREG_S_X(VS2REG, element));
31396841   }
31406842
31416843   rsp->reciprocal_res = rec;
31426844
3143   W_VREG_S(VDREG, del, (UINT16)(rsp->reciprocal_res));         // store low part
6845   W_VREG_S_X(VDREG, del, (UINT16)(rsp->reciprocal_res));         // store low part
31446846}
31456847
3146INLINE void rsp_vrcpl(rsp_state *rsp, UINT32 op, INT16 *vres)
6848INLINE void cfunc_rsp_vrcpl(void *param)
31476849{
6850   rsp_state *rsp = (rsp_state*)param;
6851   int op = rsp->impstate->arg0;
31486852   int i;
31496853   // 31       25  24     20      15      10      5        0
31506854   // ------------------------------------------------------
r6794r6795
31536857   //
31546858   // Calculates reciprocal low part
31556859
3156   int del = (VS1REG & 7);
3157   int sel = VEC_EL_2(EL, del);
6860   int del = 7 - (VS1REG & 7);
6861   int sel = 7 - VEC_EL_2(EL, 7-del);
31586862   INT32 rec;
31596863
3160   rec = ((UINT16)(R_VREG_S(VS2REG, sel)) | ((UINT32)(rsp->reciprocal_high) << 16));
6864   rec = ((UINT16)(R_VREG_S_X(VS2REG, sel)) | ((UINT32)(rsp->reciprocal_high) << 16));
31616865
31626866   if (rec == 0)
31636867   {
r6794r6795
32056909   for (i=0; i < 8; i++)
32066910   {
32076911      int element = VEC_EL_2(EL, i);
3208      W_ACCUM_L(i, R_VREG_S(VS2REG, element));
6912      W_ACCUM_L(i, R_VREG_S_X(VS2REG, element));
32096913   }
32106914
32116915   rsp->reciprocal_res = rec;
32126916
3213   W_VREG_S(VDREG, del, (UINT16)(rsp->reciprocal_res));         // store low part
6917   W_VREG_S_X(VDREG, del, (UINT16)(rsp->reciprocal_res));         // store low part
32146918}
32156919
3216INLINE void rsp_vrcph(rsp_state *rsp, UINT32 op, INT16 *vres)
6920INLINE void cfunc_rsp_vrcph(void *param)
32176921{
3218   int i;
6922   rsp_state *rsp = (rsp_state*)param;
6923   int op = rsp->impstate->arg0;
32196924   // 31       25  24     20      15      10      5        0
32206925   // ------------------------------------------------------
32216926   // | 010010 | 1 | EEEE | SSSSS | ?FFFF | DDDDD | 110010 |
r6794r6795
32236928   //
32246929   // Calculates reciprocal high part
32256930
3226   int del = (VS1REG & 7);
3227   int sel = VEC_EL_2(EL, del);
6931   int del = 7 - (VS1REG & 7);
6932   int sel = 7 - VEC_EL_2(EL, 7-del);
32286933
3229   rsp->reciprocal_high = R_VREG_S(VS2REG, sel);
6934   rsp->reciprocal_high = R_VREG_S_X(VS2REG, sel);
32306935
3231   for (i=0; i < 8; i++)
3232   {
3233      int element = VEC_EL_2(EL, i);
3234      W_ACCUM_L(i, R_VREG_S(VS2REG, element));      // perhaps accumulator is used to store the intermediate values ?
3235   }
6936   W_ACCUM_L(0, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 0)));
6937   W_ACCUM_L(1, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 1)));
6938   W_ACCUM_L(2, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 2)));
6939   W_ACCUM_L(3, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 3)));
6940   W_ACCUM_L(4, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 4)));
6941   W_ACCUM_L(5, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 5)));
6942   W_ACCUM_L(6, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 6)));
6943   W_ACCUM_L(7, R_VREG_S_X(VS2REG, VEC_EL_2(EL, 7)));
32366944
3237   W_VREG_S(VDREG, del, (INT16)(rsp->reciprocal_res >> 16));   // store high part
6945   W_VREG_S_X(VDREG, del, (INT16)(rsp->reciprocal_res >> 16));   // store high part
32386946}
32396947
3240INLINE void rsp_vmov(rsp_state *rsp, UINT32 op, INT16 *vres)
6948INLINE void cfunc_rsp_vmov(void *param)
32416949{
6950   rsp_state *rsp = (rsp_state*)param;
6951   int op = rsp->impstate->arg0;
32426952   // 31       25  24     20      15      10      5        0
32436953   // ------------------------------------------------------
32446954   // | 010010 | 1 | EEEE | SSSSS | ?FFFF | DDDDD | 110011 |
r6794r6795
32466956   //
32476957   // Moves element from vector to destination vector
32486958
3249   int element = VS1REG & 7;
3250   W_VREG_S(VDREG, element, R_VREG_S(VS2REG, VEC_EL_2(EL, 7-element)));
6959   int element = 7 - (VS1REG & 7);
6960   W_VREG_S_X(VDREG, element, R_VREG_S_X(VS2REG, 7 - VEC_EL_2(EL, element)));
32516961}
32526962
3253INLINE void rsp_vrsql(rsp_state *rsp, UINT32 op, INT16 *vres)
6963INLINE void cfunc_rsp_vrsql(void *param)
32546964{
6965   rsp_state *rsp = (rsp_state*)param;
6966   int op = rsp->impstate->arg0;
32556967   int i;
32566968   // 31       25  24     20      15      10      5        0
32576969   // ------------------------------------------------------
r6794r6795
32606972   //
32616973   // Calculates reciprocal square-root low part
32626974
3263   int del = (VS1REG & 7);
3264   int sel = VEC_EL_2(EL, del);
6975   int del = 7 - (VS1REG & 7);
6976   int sel = 7 - VEC_EL_2(EL, 7 - del);
32656977   INT32 sqr;
32666978
3267   sqr = (UINT16)(R_VREG_S(VS2REG, sel)) | ((UINT32)(rsp->square_root_high) << 16);
6979   sqr = (UINT16)(R_VREG_S_X(VS2REG, sel)) | ((UINT32)(rsp->square_root_high) << 16);
32686980
32696981   if (sqr == 0)
32706982   {
r6794r6795
33147026      }
33157027   }
33167028
3317   for (i=0; i < 8; i++)
3318   {
3319      int element = VEC_EL_2(EL, i);
3320      W_ACCUM_L(i, R_VREG_S(VS2REG, element));
3321   }
7029   W_ACCUM_L(0, R_VREG_S(VS2REG, VEC_EL_2(EL, 0)));
7030   W_ACCUM_L(1, R_VREG_S(VS2REG, VEC_EL_2(EL, 1)));
7031   W_ACCUM_L(2, R_VREG_S(VS2REG, VEC_EL_2(EL, 2)));
7032   W_ACCUM_L(3, R_VREG_S(VS2REG, VEC_EL_2(EL, 3)));
7033   W_ACCUM_L(4, R_VREG_S(VS2REG, VEC_EL_2(EL, 4)));
7034   W_ACCUM_L(5, R_VREG_S(VS2REG, VEC_EL_2(EL, 5)));
7035   W_ACCUM_L(6, R_VREG_S(VS2REG, VEC_EL_2(EL, 6)));
7036   W_ACCUM_L(7, R_VREG_S(VS2REG, VEC_EL_2(EL, 7)));
33227037
33237038   rsp->square_root_res = sqr;
33247039
3325   W_VREG_S(VDREG, del, (UINT16)(rsp->square_root_res));         // store low part
7040   W_VREG_S_X(VDREG, del, (UINT16)(rsp->square_root_res));         // store low part
33267041}
33277042
3328INLINE void rsp_vrsqh(rsp_state *rsp, UINT32 op, INT16 *vres)
7043INLINE void cfunc_rsp_vrsqh(void *param)
33297044{
7045   rsp_state *rsp = (rsp_state*)param;
7046   int op = rsp->impstate->arg0;
33307047   int i;
33317048   // 31       25  24     20      15      10      5        0
33327049   // ------------------------------------------------------
r6794r6795
33487065
33497066   W_VREG_S(VDREG, del, (INT16)(rsp->square_root_res >> 16));   // store high part
33507067}
3351
3352static void cfunc_handle_vector_ops(void *param)
3353{
3354   rsp_state *rsp = (rsp_state*)param;
3355   int op = rsp->impstate->arg0;
3356   INT16 vres[8];
3357
3358   // Opcode legend:
3359   //    E = VS2 element type
3360   //    S = VS1, Source vector 1
3361   //    T = VS2, Source vector 2
3362   //    D = Destination vector
3363
3364   switch (op & 0x3f)
3365   {
3366      case 0x00:      /* VMULF */
3367         rsp_vmulf(rsp, op, vres);
3368         break;
3369
3370      case 0x01:      /* VMULU */
3371         rsp_vmulu(rsp, op, vres);
3372         break;
3373
3374      case 0x04:      /* VMUDL */
3375         rsp_vmudl(rsp, op, vres);
3376         break;
3377
3378      case 0x05:      /* VMUDM */
3379         rsp_vmudm(rsp, op, vres);
3380         break;
3381
3382      case 0x06:      /* VMUDN */
3383         rsp_vmudn(rsp, op, vres);
3384         break;
3385
3386      case 0x07:      /* VMUDH */
3387         rsp_vmudh(rsp, op, vres);
3388         break;
3389
3390      case 0x08:      /* VMACF */
3391         rsp_vmacf(rsp, op, vres);
3392         break;
3393
3394      case 0x09:      /* VMACU */
3395         rsp_vmacu(rsp, op, vres);
3396         break;
3397
3398      case 0x0c:      /* VMADL */
3399         rsp_vmadl(rsp, op, vres);
3400         break;
3401
3402      case 0x0d:      /* VMADM */
3403         rsp_vmadm(rsp, op, vres);
3404         break;
3405
3406      case 0x0e:      /* VMADN */
3407         rsp_vmadn(rsp, op, vres);
3408         break;
3409
3410      case 0x0f:      /* VMADH */
3411         rsp_vmadh(rsp, op, vres);
3412         break;
3413
3414      case 0x10:      /* VADD */
3415         rsp_vadd(rsp, op, vres);
3416         break;
3417
3418      case 0x11:      /* VSUB */
3419         rsp_vsub(rsp, op, vres);
3420         break;
3421
3422      case 0x13:      /* VABS */
3423         rsp_vabs(rsp, op, vres);
3424         break;
3425
3426      case 0x14:      /* VADDC */
3427         rsp_vaddc(rsp, op, vres);
3428         break;
3429
3430      case 0x15:      /* VSUBC */
3431         rsp_vsubc(rsp, op, vres);
3432         break;
3433
3434      case 0x1d:      /* VSAW */
3435         rsp_vsaw(rsp, op, vres);
3436         break;
3437
3438      case 0x20:      /* VLT */
3439         rsp_vlt(rsp, op, vres);
3440         break;
3441
3442      case 0x21:      /* VEQ */
3443         rsp_veq(rsp, op, vres);
3444         break;
3445
3446      case 0x22:      /* VNE */
3447         rsp_vne(rsp, op, vres);
3448         break;
3449
3450      case 0x23:      /* VGE */
3451         rsp_vge(rsp, op, vres);
3452         break;
3453
3454      case 0x24:      /* VCL */
3455         rsp_vcl(rsp, op, vres);
3456         break;
3457
3458      case 0x25:      /* VCH */
3459         rsp_vch(rsp, op, vres);
3460         break;
3461
3462      case 0x26:      /* VCR */
3463         rsp_vcr(rsp, op, vres);
3464         break;
3465
3466      case 0x27:      /* VMRG */
3467         rsp_vmrg(rsp, op, vres);
3468         break;
3469
3470      case 0x2a:      /* VOR */
3471         rsp_vor(rsp, op, vres);
3472         break;
3473
3474      case 0x28:      /* VAND */
3475         rsp_vand(rsp, op, vres);
3476         break;
3477
3478      case 0x29:      /* VNAND */
3479         rsp_vnand(rsp, op, vres);
3480         break;
3481
3482      case 0x2b:      /* VNOR */
3483         rsp_vnor(rsp, op, vres);
3484         break;
3485
3486      case 0x2d:      /* VNXOR */
3487         rsp_vnxor(rsp, op, vres);
3488         break;
3489
3490      case 0x2c:      /* VXOR */
3491         rsp_vxor(rsp, op, vres);
3492         break;
3493
3494      case 0x30:      /* VRCP */
3495         rsp_vrcp(rsp, op, vres);
3496         break;
3497
3498      case 0x31:      /* VRCPL */
3499         rsp_vrcpl(rsp, op, vres);
3500         break;
3501
3502      case 0x32:      /* VRCPH */
3503         rsp_vrcph(rsp, op, vres);
3504         break;
3505
3506      case 0x33:      /* VMOV */
3507         rsp_vmov(rsp, op, vres);
3508         break;
3509
3510      case 0x35:      /* VRSQL */
3511         rsp_vrsql(rsp, op, vres);
3512         break;
3513
3514      case 0x36:      /* VRSQH */
3515         rsp_vrsqh(rsp, op, vres);
3516         break;
3517
3518      default:   unimplemented_opcode(rsp, op); break;
3519   }
3520}
3521
35227068static void cfunc_sp_set_status_cb(void *param)
35237069{
35247070   rsp_state *rsp = (rsp_state*)param;
r6794r6795
36237169   drcuml_block *block;
36247170   jmp_buf errorbuf;
36257171
3626   profiler_mark_start(PROFILER_DRC_COMPILE);
7172   profiler_mark_start(PROFILER_DRC_COMPILER);
36277173
36287174   /* get a description of this sequence */
36297175   desclist = drcfe_describe_code(rsp->impstate->drcfe, pc);
r6794r6795
36357181   }
36367182
36377183   /* start the block */
3638   block = drcuml_block_begin(drcuml, 4096, &errorbuf);
7184   block = drcuml_block_begin(drcuml, 8192, &errorbuf);
36397185
36407186   /* loop until we get through all instruction sequences */
36417187   for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next)
r6794r6795
37287274    cfunc_fatalerror - a generic fatalerror call
37297275-------------------------------------------------*/
37307276
3731#ifndef LSB_FIRST
37327277static void cfunc_fatalerror(void *param)
37337278{
37347279   //fatalerror("fatalerror");
37357280}
3736#endif
37377281
37387282
37397283/***************************************************************************
r6794r6795
37417285***************************************************************************/
37427286
37437287/*-------------------------------------------------
3744    static_generate_entry_point - generate a
7288    ferate_entry_point - generate a
37457289    static entry point
37467290-------------------------------------------------*/
37477291
r6794r6795
38497393   drcuml_state *drcuml = rsp->impstate->drcuml;
38507394   drcuml_block *block;
38517395   jmp_buf errorbuf;
3852   int unaligned_case = 1;
7396   int unaligned_w2 = 1;
7397   int aligned_w2 = 2;
7398   int unaligned_w4 = 1;
7399   int unaligned_r2 = 1;
7400   int unaligned_r4 = 1;
38537401
38547402   /* if we get an error back, we're screwed */
38557403   if (setjmp(errorbuf) != 0)
r6794r6795
38647412   alloc_handle(drcuml, handleptr, name);
38657413   UML_HANDLE(block, *handleptr);                                       // handle  *handleptr
38667414
7415   UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));
38677416
38687417   // write:
38697418   if (iswrite)
38707419   {
38717420      if (size == 1)
38727421      {
3873#ifdef LSB_FIRST
3874         UML_XOR(block, IREG(0), IREG(0), IMM(3));                           // xor     i0,i0,3
3875#endif
3876         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                     // and     i0,i0,0xfff
3877         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE);            // store   dmem,i0,i1,byte
7422         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));         // xor     i0,i0,bytexor
7423         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE);   // store   dmem,i0,i1,byte
38787424      }
38797425      else if (size == 2)
38807426      {
3881#ifdef LSB_FIRST
7427         static const char text[] = "%08x: Unaligned word write to %08x\n";
38827428         UML_TEST(block, IREG(0), IMM(1));                                 // test    i0,1
3883         UML_JMPc(block, IF_NZ, unaligned_case);                              // jnz     <unaligned_case>
3884         UML_XOR(block, IREG(0), IREG(0), IMM(2));                           // xor     i0,i0,2
3885#endif
3886         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                     // and     i0,i0,0xfff
3887         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), WORD_x1);         // store   dmem,i0,i1,word_x1
3888         UML_RET(block);
3889#ifdef LSB_FIRST
3890         UML_LABEL(block, unaligned_case);                              // unaligned_case:
3891         UML_ROLAND(block, IREG(2), IREG(0), IMM(3), IMM(0x18));                  // roland  i2,i0,3,0x18
3892         UML_AND(block, IREG(0), IREG(0), IMM(0xffc));                        // and     i0,i0,0xffc
3893         UML_DLOAD(block, IREG(3), rsp->impstate->dmem, IREG(0), QWORD_x1);          // dload   i3,dmem,i0,qword_x1
3894         UML_DROL(block, IREG(3), IREG(3), IREG(2));                           // drol    i3,i3,i2
3895         UML_DAND(block, IREG(1), IREG(1), IMM(0xffff));                        // dand    i1,i1,0xffff
3896         UML_DAND(block, IREG(3), IREG(3), IMM(U64(0xffffffffffff0000)));         // dand    i3,i3,~0xffff
3897         UML_DOR(block, IREG(1), IREG(1), IREG(3));                           // dor     i1,i1,i3
3898         UML_DROR(block, IREG(1), IREG(1), IREG(2));                           // dror    i1,i1,i2
3899         UML_DSTORE(block, rsp->impstate->dmem, IREG(0), IREG(1), QWORD_x1);       // dstore  dmem,i0,i1,qword_x1
3900#endif
7429         UML_JMPc(block, IF_NZ, unaligned_w2);                              // jnz     <unaligned_w2>
7430         UML_JMP(block, aligned_w2);                                       // jmp     <aligned_w2>
7431
7432         UML_LABEL(block, unaligned_w2);                                    // <unaligned_w2>:
7433         UML_MOV(block, MEM(&rsp->impstate->format), IMM((FPTR)text));            // mov     [format],text
7434         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(rsp->pc));               // mov     [arg0],rsp->pc
7435         UML_MOV(block, MEM(&rsp->impstate->arg1), IREG(0));                     // mov     [arg1],i0
7436         UML_CALLC(block, cfunc_printf_debug, rsp);                           // callc   printf_debug
7437         UML_CALLC(block, cfunc_fatalerror, rsp);
7438
7439         UML_LABEL(block, aligned_w2);                                    // <aligned_w2>:
7440         UML_SHR(block, IREG(0), IREG(0), IMM(1));                           // shr     i0,i0,1
7441         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE_XOR_BE(0)));                  // xor     i0,i0,bytexor
7442         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), WORD);            // store   dmem,i0,i1,word
39017443      }
39027444      else if (size == 4)
39037445      {
3904#ifdef LSB_FIRST
39057446         UML_TEST(block, IREG(0), IMM(3));                                 // test    i0,3
3906         UML_JMPc(block, IF_NZ, unaligned_case);                              // jnz     <unaligned_case>
3907#endif
3908         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                     // and     i0,i0,0xfff
7447         UML_JMPc(block, IF_NZ, unaligned_w4);                              // jnz     <unaligned_w4>
7448
39097449         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), DWORD_x1);         // store   dmem,i0,i1,dword_x1
39107450         UML_RET(block);
3911#ifdef LSB_FIRST
3912         UML_LABEL(block, unaligned_case);                              // unaligned_case:
3913         UML_ROLAND(block, IREG(2), IREG(0), IMM(3), IMM(0x18));                  // roland  i2,i0,3,0x18
3914         UML_AND(block, IREG(0), IREG(0), IMM(0xffc));                        // and     i0,i0,0xffc
3915         UML_DLOAD(block, IREG(3), rsp->impstate->dmem, IREG(0), QWORD_x1);          // dload   i3,dmem,i0,qword_x1
3916         UML_DROL(block, IREG(3), IREG(3), IREG(2));                           // drol    i3,i3,i2
3917         UML_DAND(block, IREG(1), IREG(1), IMM(0xffffffff));                     // dand    i1,i1,0xffffffff
3918         UML_DAND(block, IREG(3), IREG(3), IMM(U64(0xffffffff00000000)));         // dand    i3,i3,~0xffffffff
3919         UML_DOR(block, IREG(1), IREG(1), IREG(3));                           // dor     i1,i1,i3
3920         UML_DROR(block, IREG(1), IREG(1), IREG(2));                           // dror    i1,i1,i2
3921         UML_DSTORE(block, rsp->impstate->dmem, IREG(0), IREG(1), QWORD_x1);       // dstore  dmem,i0,i1,qword_x1
3922#endif
7451
7452         UML_LABEL(block, unaligned_w4);
7453         UML_ADD(block, IREG(0), IREG(0), IMM(3));
7454
7455         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7456         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE);
7457
7458         UML_SHR(block, IREG(1), IREG(1), IMM(8));
7459         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7460         UML_SUB(block, IREG(0), IREG(0), IMM(1));
7461         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7462         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE);
7463
7464         UML_SHR(block, IREG(1), IREG(1), IMM(8));
7465         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7466         UML_SUB(block, IREG(0), IREG(0), IMM(1));
7467         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7468         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE);
7469
7470         UML_SHR(block, IREG(1), IREG(1), IMM(8));
7471         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7472         UML_SUB(block, IREG(0), IREG(0), IMM(1));
7473         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7474         UML_STORE(block, rsp->impstate->dmem, IREG(0), IREG(1), BYTE);
39237475      }
39247476   }
39257477   else
39267478   {
39277479      if (size == 1)
39287480      {
3929#ifdef LSB_FIRST
3930         UML_XOR(block, IREG(0), IREG(0), IMM(3));                           // xor     i0,i0,3
3931#endif
3932         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                     // and     i0,i0,0xfff
7481         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));                  // xor     i0,i0,bytexor
39337482         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), BYTE);            // load    i0,dmem,i0,byte
39347483      }
39357484      else if (size == 2)
39367485      {
3937#ifdef LSB_FIRST
3938         UML_TEST(block, IREG(0), IMM(1));                                 // test    i0,1
3939         UML_JMPc(block, IF_NZ, unaligned_case);                              // jnz     <unaligned_case>
3940         UML_XOR(block, IREG(0), IREG(0), IMM(2));                           // xor     i0,i0,2
3941#endif
3942         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                     // and     i0,i0,0xfff
3943         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), WORD_x1);         // load    i0,dmem,i0,word_x1
7486         UML_TEST(block, IREG(0), IMM(1));                                 // test    i0,3
7487         UML_JMPc(block, IF_NZ, unaligned_r2);                              // jnz     <unaligned_r2>
7488
7489         UML_SHR(block, IREG(0), IREG(0), IMM(1));                           // shr     i0,i0,1
7490         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE_XOR_BE(0)));                  // xor     i0,i0,bytexor
7491         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), WORD);            // load    i0,dmem,i0,word
39447492         UML_RET(block);
3945#ifdef LSB_FIRST
3946         UML_LABEL(block, unaligned_case);                              // unaligned_case:
3947         UML_ROLAND(block, IREG(1), IREG(0), IMM(3), IMM(0x18));                  // roland  i1,i0,3,0x18
3948         UML_AND(block, IREG(0), IREG(0), IMM(0xffc));                        // and     i0,i0,0xffc
3949         UML_DLOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), QWORD_x1);          // dload   i0,dmem,i0,qword_x1
3950         UML_DROL(block, IREG(0), IREG(0), IREG(1));                           // drol    i0,i0,i1
3951         UML_AND(block, IREG(0), IREG(0), IMM(0xffff));                        // and     i0,i0,0xffff
3952#endif
7493
7494         UML_LABEL(block, unaligned_r2);
7495         UML_MOV(block, IREG(2), IMM(0));
7496         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7497
7498         UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(0), BYTE);
7499         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7500         UML_ADD(block, IREG(0), IREG(0), IMM(1));
7501         UML_XOR(block, IREG(0), IREG(0), IMM(BYTE4_XOR_BE(0)));
7502         UML_OR(block, IREG(2), IREG(2), IREG(3));
7503
7504         UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(0), BYTE);
7505         UML_ADD(block, IREG(0), IREG(0), IMM(1));
7506         UML_SHL(block, IREG(2), IREG(2), IMM(8));
7507         UML_OR(block, IREG(2), IREG(2), IREG(3));
7508
7509         UML_MOV(block, IREG(0), IREG(2));
39537510      }
39547511      else if (size == 4)
39557512      {
3956#ifdef LSB_FIRST
39577513         UML_TEST(block, IREG(0), IMM(3));                                 // test    i0,3
3958         UML_JMPc(block, IF_NZ, unaligned_case);                              // jnz     <unaligned_case>
3959#endif
3960         UML_AND(block, IREG(0), IREG(0), IMM(0x00000fff));                     // and     i0,i0,0xfff
3961         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), DWORD_x1);         // load    i0,dmem,i0,dword_x1
7514         UML_JMPc(block, IF_NZ, unaligned_r4);                              // jnz     <unaligned_r4>
7515
7516         UML_LOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), DWORD_x1);         // load    i0,dmem,i0,dword
39627517         UML_RET(block);
3963#ifdef LSB_FIRST
3964         UML_LABEL(block, unaligned_case);                              // unaligned_case:
3965         UML_ROLAND(block, IREG(1), IREG(0), IMM(3), IMM(0x18));                  // roland  i1,i0,3,0x18
3966         UML_AND(block, IREG(0), IREG(0), IMM(0xffc));                        // and     i0,i0,0xffc
3967         UML_DLOAD(block, IREG(0), rsp->impstate->dmem, IREG(0), QWORD_x1);          // dload   i0,dmem,i0,qword_x1
3968         UML_DROL(block, IREG(0), IREG(0), IREG(1));                           // drol    i0,i0,i1
3969#endif
7518
7519         UML_LABEL(block, unaligned_r4);
7520
7521         UML_XOR(block, IREG(1), IREG(0), IMM(BYTE4_XOR_BE(0)));
7522         UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(1), BYTE);
7523         UML_SHL(block, IREG(2), IREG(3), IMM(24));
7524
7525         UML_ADD(block, IREG(1), IREG(0), IMM(1));
7526         UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));
7527         UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(1), BYTE);
7528         UML_SHL(block, IREG(3), IREG(3), IMM(16));
7529         UML_OR(block, IREG(2), IREG(2), IREG(3));
7530
7531         UML_ADD(block, IREG(1), IREG(0), IMM(2));
7532         UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));
7533         UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(1), BYTE);
7534         UML_SHL(block, IREG(3), IREG(3), IMM(8));
7535         UML_OR(block, IREG(2), IREG(2), IREG(3));
7536
7537         UML_ADD(block, IREG(1), IREG(0), IMM(3));
7538         UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0)));
7539         UML_LOAD(block, IREG(3), rsp->impstate->dmem, IREG(1), BYTE);
7540         UML_OR(block, IREG(0), IREG(2), IREG(3));
39707541      }
39717542   }
39727543   UML_RET(block);
r6794r6795
40767647   /* if we hit an unmapped address, fatal error */
40777648   //if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
40787649   //{
4079   //  UML_MOV(block, MEM(&rsp->pc), IMM(desc->pc));                               // mov     [pc],desc->pc
4080   //  save_fast_iregs(rsp, block);
4081   //  UML_EXIT(block, IMM(EXECUTE_UNMAPPED_CODE));                                // exit    EXECUTE_UNMAPPED_CODE
7650   //   UML_MOV(block, MEM(&rsp->pc), IMM(desc->pc));                        // mov     [pc],desc->pc
7651   //   save_fast_iregs(rsp, block);
7652   //   UML_EXIT(block, IMM(EXECUTE_UNMAPPED_CODE));                        // exit    EXECUTE_UNMAPPED_CODE
40827653   //}
40837654
40847655   /* otherwise, unless this is a virtual no-op, it's a regular instruction */
r6794r6795
40947665   }
40957666}
40967667
4097
40987668/*------------------------------------------------------------------
40997669    generate_delay_slot_and_branch
41007670------------------------------------------------------------------*/
r6794r6795
41077677   /* fetch the target register if dynamic, in case it is modified by the delay slot */
41087678   if (desc->targetpc == BRANCH_TARGET_DYNAMIC)
41097679   {
4110      UML_MOV(block, MEM(&rsp->impstate->jmpdest), R32(RSREG));               // mov     [jmpdest],<rsreg>
41117680      UML_AND(block, MEM(&rsp->impstate->jmpdest), R32(RSREG), IMM(0x00000fff));
41127681      UML_OR(block, MEM(&rsp->impstate->jmpdest), MEM(&rsp->impstate->jmpdest), IMM(0x1000));
41137682   }
r6794r6795
41157684   /* set the link if needed -- before the delay slot */
41167685   if (linkreg != 0)
41177686   {
4118      UML_MOV(block, R32(linkreg), IMM((INT32)(desc->pc + 8)));               // dmov    <linkreg>,desc->pc + 8
7687      UML_MOV(block, R32(linkreg), IMM((INT32)(desc->pc + 8)));               // mov    <linkreg>,desc->pc + 8
41197688   }
41207689
41217690   /* compile the delay slot using temporary compiler state */
r6794r6795
41587727    opcode
41597728-------------------------------------------------*/
41607729
7730static int generate_vector_opcode(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
7731{
7732   UINT32 op = desc->opptr.l[0];
7733   // Opcode legend:
7734   //    E = VS2 element type
7735   //    S = VS1, Source vector 1
7736   //    T = VS2, Source vector 2
7737   //    D = Destination vector
7738
7739   switch (op & 0x3f)
7740   {
7741      case 0x00:      /* VMULF */
7742         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7743         UML_CALLC(block, cfunc_rsp_vmulf, rsp);
7744         return TRUE;
7745
7746      case 0x01:      /* VMULU */
7747         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7748         UML_CALLC(block, cfunc_rsp_vmulu, rsp);
7749         return TRUE;
7750
7751      case 0x04:      /* VMUDL */
7752#if (DRC_VMUDL)
7753         return generate_vmudl(rsp, block, compiler, desc);
7754#else
7755         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7756         UML_CALLC(block, cfunc_rsp_vmudl, rsp);
7757         return TRUE;
7758#endif
7759
7760      case 0x05:      /* VMUDM */
7761#if (DRC_VMUDM)
7762         return generate_vmudm(rsp, block, compiler, desc);
7763#else
7764         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7765         UML_CALLC(block, cfunc_rsp_vmudm, rsp);
7766         return TRUE;
7767#endif
7768
7769      case 0x06:      /* VMUDN */
7770         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7771         UML_CALLC(block, cfunc_rsp_vmudn, rsp);
7772         return TRUE;
7773
7774      case 0x07:      /* VMUDH */
7775         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7776         UML_CALLC(block, cfunc_rsp_vmudh, rsp);
7777         return TRUE;
7778
7779      case 0x08:      /* VMACF */
7780         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7781         UML_CALLC(block, cfunc_rsp_vmacf, rsp);
7782         return TRUE;
7783
7784      case 0x09:      /* VMACU */
7785         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7786         UML_CALLC(block, cfunc_rsp_vmacu, rsp);
7787         return TRUE;
7788
7789      case 0x0c:      /* VMADL */
7790         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7791         UML_CALLC(block, cfunc_rsp_vmadl, rsp);
7792         return TRUE;
7793
7794      case 0x0d:      /* VMADM */
7795#if (DRC_VMADM)
7796         return generate_vmadm(rsp, block, compiler, desc);
7797#else
7798         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7799         UML_CALLC(block, cfunc_rsp_vmadm, rsp);
7800         return TRUE;
7801#endif
7802
7803      case 0x0e:      /* VMADN */
7804#if (DRC_VMADN)
7805         return generate_vmadn(rsp, block, compiler, desc);
7806#else
7807         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7808         UML_CALLC(block, cfunc_rsp_vmadn, rsp);
7809         return TRUE;
7810#endif
7811
7812      case 0x0f:      /* VMADH */
7813#if (DRC_VMADH)
7814         return generate_vmadh(rsp, block, compiler, desc);
7815#else
7816         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7817         UML_CALLC(block, cfunc_rsp_vmadh, rsp);
7818         return TRUE;
7819#endif
7820
7821      case 0x10:      /* VADD */
7822#if (DRC_VADD)
7823         return generate_vadd(rsp, block, compiler, desc);
7824#else
7825         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7826         UML_CALLC(block, cfunc_rsp_vadd, rsp);
7827         return TRUE;
7828#endif
7829
7830      case 0x11:      /* VSUB */
7831         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7832         UML_CALLC(block, cfunc_rsp_vsub, rsp);
7833         return TRUE;
7834
7835      case 0x13:      /* VABS */
7836         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7837         UML_CALLC(block, cfunc_rsp_vabs, rsp);
7838         return TRUE;
7839
7840      case 0x14:      /* VADDC */
7841         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7842         UML_CALLC(block, cfunc_rsp_vaddc, rsp);
7843         return TRUE;
7844
7845      case 0x15:      /* VSUBC */
7846         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7847         UML_CALLC(block, cfunc_rsp_vsubc, rsp);
7848         return TRUE;
7849
7850      case 0x1d:      /* VSAW */
7851         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7852         UML_CALLC(block, cfunc_rsp_vsaw, rsp);
7853         return TRUE;
7854
7855      case 0x20:      /* VLT */
7856         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7857         UML_CALLC(block, cfunc_rsp_vlt, rsp);
7858         return TRUE;
7859
7860      case 0x21:      /* VEQ */
7861         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7862         UML_CALLC(block, cfunc_rsp_veq, rsp);
7863         return TRUE;
7864
7865      case 0x22:      /* VNE */
7866         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7867         UML_CALLC(block, cfunc_rsp_vne, rsp);
7868         return TRUE;
7869
7870      case 0x23:      /* VGE */
7871         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7872         UML_CALLC(block, cfunc_rsp_vge, rsp);
7873         return TRUE;
7874
7875      case 0x24:      /* VCL */
7876         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7877         UML_CALLC(block, cfunc_rsp_vcl, rsp);
7878         return TRUE;
7879
7880      case 0x25:      /* VCH */
7881         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7882         UML_CALLC(block, cfunc_rsp_vch, rsp);
7883         return TRUE;
7884
7885      case 0x26:      /* VCR */
7886         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7887         UML_CALLC(block, cfunc_rsp_vcr, rsp);
7888         return TRUE;
7889
7890      case 0x27:      /* VMRG */
7891         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7892         UML_CALLC(block, cfunc_rsp_vmrg, rsp);
7893         return TRUE;
7894
7895      case 0x28:      /* VAND */
7896#if (DRC_VAND)
7897         return generate_vand(rsp, block, compiler, desc);
7898#else
7899         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7900         UML_CALLC(block, cfunc_rsp_vand, rsp);
7901         return TRUE;
7902#endif
7903
7904      case 0x29:      /* VNAND */
7905#if (DRC_VNAND)
7906         return generate_vnand(rsp, block, compiler, desc);
7907#else
7908         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7909         UML_CALLC(block, cfunc_rsp_vnand, rsp);
7910         return TRUE;
7911#endif
7912
7913      case 0x2a:      /* VOR */
7914#if (DRC_VOR)
7915         return generate_vor(rsp, block, compiler, desc);
7916#else
7917         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7918         UML_CALLC(block, cfunc_rsp_vor, rsp);
7919         return TRUE;
7920#endif
7921
7922      case 0x2b:      /* VNOR */
7923#if (DRC_VNOR)
7924         return generate_vnor(rsp, block, compiler, desc);
7925#else
7926         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7927         UML_CALLC(block, cfunc_rsp_vnor, rsp);
7928         return TRUE;
7929#endif
7930
7931      case 0x2c:      /* VXOR */
7932#if (DRC_VXOR)
7933         return generate_vxor(rsp, block, compiler, desc);
7934#else
7935         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7936         UML_CALLC(block, cfunc_rsp_vxor, rsp);
7937         return TRUE;
7938#endif
7939
7940      case 0x2d:      /* VNXOR */
7941#if (DRC_VNXOR)
7942         return generate_vnxor(rsp, block, compiler, desc);
7943#else
7944         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7945         UML_CALLC(block, cfunc_rsp_vnxor, rsp);
7946         return TRUE;
7947#endif
7948
7949      case 0x30:      /* VRCP */
7950         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7951         UML_CALLC(block, cfunc_rsp_vrcp, rsp);
7952         return TRUE;
7953
7954      case 0x31:      /* VRCPL */
7955         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7956         UML_CALLC(block, cfunc_rsp_vrcpl, rsp);
7957         return TRUE;
7958
7959      case 0x32:      /* VRCPH */
7960         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7961         UML_CALLC(block, cfunc_rsp_vrcph, rsp);
7962         return TRUE;
7963
7964      case 0x33:      /* VMOV */
7965         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7966         UML_CALLC(block, cfunc_rsp_vmov, rsp);
7967         return TRUE;
7968
7969      case 0x35:      /* VRSQL */
7970         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7971         UML_CALLC(block, cfunc_rsp_vrsql, rsp);
7972         return TRUE;
7973
7974      case 0x36:      /* VRSQH */
7975         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7976         UML_CALLC(block, cfunc_rsp_vrsqh, rsp);
7977         return TRUE;
7978
7979      default:
7980         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
7981         UML_CALLC(block, cfunc_unimplemented_opcode, rsp);
7982         return FALSE;
7983   }
7984}
7985
41617986static int generate_opcode(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
41627987{
41637988   int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
r6794r6795
42308055      case 0x09:   /* ADDIU - MIPS I */
42318056         if (RTREG != 0)
42328057         {
4233            UML_ADD(block, R32(RTREG), R32(RSREG), IMM(SIMMVAL));         // add     i0,<rsreg>,SIMMVAL,V
8058            UML_ADD(block, R32(RTREG), R32(RSREG), IMM(SIMMVAL));            // add     i0,<rsreg>,SIMMVAL,V
42348059         }
42358060         return TRUE;
42368061
r6794r6795
42908115         UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL));                  // add     i0,<rsreg>,SIMMVAL
42918116         UML_CALLH(block, rsp->impstate->read32);                        // callh   read32
42928117         if (RTREG != 0)
4293            UML_MOV(block, R32(RTREG), IREG(0));                     // mov   <rtreg>,i0
8118            UML_MOV(block, R32(RTREG), IREG(0));
42948119         if (!in_delay_slot)
42958120            generate_update_cycles(rsp, block, compiler, IMM(desc->pc + 4), TRUE);
42968121         return TRUE;
r6794r6795
43148139         return TRUE;
43158140
43168141      case 0x32:   /* LWC2 - MIPS I */
4317         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
4318         UML_CALLC(block, cfunc_lwc2, rsp);                              // callc   cfunc_mfc2
4319         return TRUE;
4320         //return generate_lwc2(rsp, block, compiler, desc);
8142         return generate_lwc2(rsp, block, compiler, desc);
43218143
43228144
43238145      /* ----- memory store operations ----- */
r6794r6795
43478169         return TRUE;
43488170
43498171      case 0x3a:   /* SWC2 - MIPS I */
4350         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
4351         UML_CALLC(block, cfunc_swc2, rsp);                              // callc   cfunc_mfc2
4352         return TRUE;
8172         return generate_swc2(rsp, block, compiler, desc);
8173         //UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
8174         //UML_CALLC(block, cfunc_swc2, rsp);                              // callc   cfunc_mfc2
8175         //return TRUE;
43538176
43548177      /* ----- coprocessor instructions ----- */
43558178
r6794r6795
43898212      case 0x00:   /* SLL - MIPS I */
43908213         if (RDREG != 0)
43918214         {
4392            UML_SHL(block, R32(RDREG), R32(RTREG), IMM(SHIFT));               // shl     i0,<rtreg>,<shift>
8215            UML_SHL(block, R32(RDREG), R32(RTREG), IMM(SHIFT));
43938216         }
43948217         return TRUE;
43958218
43968219      case 0x02:   /* SRL - MIPS I */
43978220         if (RDREG != 0)
43988221         {
4399            UML_SHR(block, R32(RDREG), R32(RTREG), IMM(SHIFT));               // shr     i0,<rtreg>,<shift>
8222            UML_SHR(block, R32(RDREG), R32(RTREG), IMM(SHIFT));
44008223         }
44018224         return TRUE;
44028225
44038226      case 0x03:   /* SRA - MIPS I */
44048227         if (RDREG != 0)
44058228         {
4406            UML_SAR(block, R32(RDREG), R32(RTREG), IMM(SHIFT));               // sar     i0,<rtreg>,<shift>
8229            UML_SAR(block, R32(RDREG), R32(RTREG), IMM(SHIFT));
44078230         }
44088231         return TRUE;
44098232
44108233      case 0x04:   /* SLLV - MIPS I */
44118234         if (RDREG != 0)
44128235         {
4413            UML_SHL(block, R32(RDREG), R32(RTREG), R32(RSREG));               // shl     i0,<rtreg>,<rsreg>
8236            UML_SHL(block, R32(RDREG), R32(RTREG), R32(RSREG));
44148237         }
44158238         return TRUE;
44168239
44178240      case 0x06:   /* SRLV - MIPS I */
44188241         if (RDREG != 0)
44198242         {
4420            UML_SHR(block, R32(RDREG), R32(RTREG), R32(RSREG));               // shr     i0,<rtreg>,<rsreg>
8243            UML_SHR(block, R32(RDREG), R32(RTREG), R32(RSREG));
44218244         }
44228245         return TRUE;
44238246
44248247      case 0x07:   /* SRAV - MIPS I */
44258248         if (RDREG != 0)
44268249         {
4427            UML_SAR(block, R32(RDREG), R32(RTREG), R32(RSREG));               // sar     i0,<rtreg>,<rsreg>
8250            UML_SAR(block, R32(RDREG), R32(RTREG), R32(RSREG));
44288251         }
44298252         return TRUE;
44308253
44318254      /* ----- basic arithmetic ----- */
44328255
44338256      case 0x20:   /* ADD - MIPS I */
4434         if (RDREG != 0)
4435         {
4436            UML_ADD(block, R32(RDREG), R32(RSREG), R32(RTREG));               // add     i0,<rsreg>,<rtreg>
4437         }
4438         return TRUE;
4439
44408257      case 0x21:   /* ADDU - MIPS I */
44418258         if (RDREG != 0)
44428259         {
4443            UML_ADD(block, R32(RDREG), R32(RSREG), R32(RTREG));               // add     i0,<rsreg>,<rtreg>
8260            UML_ADD(block, R32(RDREG), R32(RSREG), R32(RTREG));
44448261         }
44458262         return TRUE;
44468263
44478264      case 0x22:   /* SUB - MIPS I */
4448         if (RDREG != 0)
4449         {
4450            UML_SUB(block, R32(RDREG), R32(RSREG), R32(RTREG));               // sub     i0,<rsreg>,<rtreg>
4451         }
4452         return TRUE;
4453
44548265      case 0x23:   /* SUBU - MIPS I */
44558266         if (RDREG != 0)
44568267         {
4457            UML_SUB(block, R32(RDREG), R32(RSREG), R32(RTREG));               // sub     i0,<rsreg>,<rtreg>
8268            UML_SUB(block, R32(RDREG), R32(RSREG), R32(RTREG));
44588269         }
44598270         return TRUE;
44608271
r6794r6795
44628273
44638274      case 0x24:   /* AND - MIPS I */
44648275         if (RDREG != 0)
8276         {
44658277            UML_AND(block, R32(RDREG), R32(RSREG), R32(RTREG));            // dand     <rdreg>,<rsreg>,<rtreg>
8278         }
44668279         return TRUE;
44678280
44688281      case 0x25:   /* OR - MIPS I */
44698282         if (RDREG != 0)
8283         {
44708284            UML_OR(block, R32(RDREG), R32(RSREG), R32(RTREG));               // dor      <rdreg>,<rsreg>,<rtreg>
8285         }
44718286         return TRUE;
44728287
44738288      case 0x26:   /* XOR - MIPS I */
44748289         if (RDREG != 0)
8290         {
44758291            UML_XOR(block, R32(RDREG), R32(RSREG), R32(RTREG));            // dxor     <rdreg>,<rsreg>,<rtreg>
8292         }
44768293         return TRUE;
44778294
44788295      case 0x27:   /* NOR - MIPS I */
r6794r6795
45278344   return FALSE;
45288345}
45298346
8347
8348
45308349/*-------------------------------------------------
45318350    generate_regimm - compile opcodes in the
45328351    'REGIMM' group
r6794r6795
45878406         {
45888407            UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));   // mov     [arg0],desc->opptr.l
45898408            UML_CALLC(block, cfunc_mfc2, rsp);                           // callc   cfunc_mfc2
4590            //UML_SEXT(block, R32(RTREG), IREG(0), DWORD);                      // dsext   <rtreg>,i0,dword
8409            //UML_SEXT(block, R32(RTREG), IREG(0), DWORD);                  // dsext   <rtreg>,i0,dword
45918410         }
45928411         return TRUE;
45938412
r6794r6795
45968415         {
45978416            UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));   // mov     [arg0],desc->opptr.l
45988417            UML_CALLC(block, cfunc_cfc2, rsp);                           // callc   cfunc_cfc2
4599            //UML_SEXT(block, R32(RTREG), IREG(0), DWORD);                      // dsext   <rtreg>,i0,dword
8418            //UML_SEXT(block, R32(RTREG), IREG(0), DWORD);                  // dsext   <rtreg>,i0,dword
46008419         }
46018420         return TRUE;
46028421
r6794r6795
46128431
46138432      case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
46148433      case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
4615         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(desc->opptr.l[0]));      // mov     [arg0],desc->opptr.l
4616         UML_CALLC(block, cfunc_handle_vector_ops, rsp);                     // callc   cfunc_mfc2
4617         return TRUE;
8434         return generate_vector_opcode(rsp, block, compiler, desc);
46188435   }
46198436   return FALSE;
46208437}
r6794r6795
46338450      case 0x00:   /* MFCz */
46348451         if (RTREG != 0)
46358452         {
4636            UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(RDREG));            // mov     [arg0],<rtreg>,dword
4637            UML_MOV(block, MEM(&rsp->impstate->arg1), IMM(RTREG));            // mov     [arg1],<rdval>,dword
8453            UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(RDREG));            // mov     [arg0],<rdreg>
8454            UML_MOV(block, MEM(&rsp->impstate->arg1), IMM(RTREG));            // mov     [arg1],<rtreg>
46388455            UML_CALLC(block, cfunc_get_cop0_reg, rsp);                     // callc   cfunc_get_cop0_reg
46398456         }
46408457         return TRUE;
46418458
46428459      case 0x04:   /* MTCz */
4643         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(RDREG));               // mov     [arg0],<rtreg>,dword
4644         UML_MOV(block, MEM(&rsp->impstate->arg1), R32(RTREG));               // mov     [arg1],<rdval>,dword
8460         UML_MOV(block, MEM(&rsp->impstate->arg0), IMM(RDREG));               // mov     [arg0],<rdreg>
8461         UML_MOV(block, MEM(&rsp->impstate->arg1), R32(RTREG));               // mov     [arg1],rtreg
46458462         UML_CALLC(block, cfunc_set_cop0_reg, rsp);                        // callc   cfunc_set_cop0_reg
46468463         return TRUE;
46478464   }

Previous 15994 Revisions Next


© 1998-2018 The MESS Team