4 * Copyright (C) 2007 ziggy
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "rsp_opinfo.h"
24 static const int vector_elements_2[16][8] =
26 { 0, 1, 2, 3, 4, 5, 6, 7 }, // none
27 { 0, 1, 2, 3, 4, 5, 6, 7 }, // ???
28 { 0, 0, 2, 2, 4, 4, 6, 6 }, // 0q
29 { 1, 1, 3, 3, 5, 5, 7, 7 }, // 1q
30 { 0, 0, 0, 0, 4, 4, 4, 4 }, // 0h
31 { 1, 1, 1, 1, 5, 5, 5, 5 }, // 1h
32 { 2, 2, 2, 2, 6, 6, 6, 6 }, // 2h
33 { 3, 3, 3, 3, 7, 7, 7, 7 }, // 3h
34 { 0, 0, 0, 0, 0, 0, 0, 0 }, // 0
35 { 1, 1, 1, 1, 1, 1, 1, 1 }, // 1
36 { 2, 2, 2, 2, 2, 2, 2, 2 }, // 2
37 { 3, 3, 3, 3, 3, 3, 3, 3 }, // 3
38 { 4, 4, 4, 4, 4, 4, 4, 4 }, // 4
39 { 5, 5, 5, 5, 5, 5, 5, 5 }, // 5
40 { 6, 6, 6, 6, 6, 6, 6, 6 }, // 6
41 { 7, 7, 7, 7, 7, 7, 7, 7 }, // 7
44 void rsp_get_opinfo(UINT32 op, rsp_opinfo_t * info)
51 op2 = RSP_SPECIAL_OFFS + (op&0x3f);
54 if (((op>>21)&0x1f) >= 0x10)
55 op2 = RSP_COP2_2_OFFS + (op & 0x3f);
57 op2 = RSP_COP2_1_OFFS + ((op >> 21) & 0x1f);
60 op2 = RSP_LWC2_OFFS + ((op>>11)&0x1f);
63 op2 = RSP_SWC2_OFFS + ((op>>11)&0x1f);
66 op2 = RSP_BASIC_OFFS + (op>>26);
67 if (op2 == RSP_REGIMM) {
76 case 0x11: /* BGEZAL */
84 memset(&info->used, 0, sizeof(info->used));
85 memset(&info->set, 0, sizeof(info->set));
86 info->used.accu = info->used.flag = 0;
87 info->set.accu = info->set.flag = 0;
90 int dest = (op >> 16) & 0x1f;
91 int index = (op >> 7) & 0xf;
92 int offset = (op & 0x7f);
99 info->flags = RSP_OPINFO_JUMP | RSP_OPINFO_COND | RSP_OPINFO_USEPC;
102 info->flags = RSP_OPINFO_JUMP | RSP_OPINFO_COND | RSP_OPINFO_USEPC;
105 info->flags = RSP_OPINFO_JUMP | RSP_OPINFO_COND | RSP_OPINFO_LINK | RSP_OPINFO_USEPC;
108 info->flags = RSP_OPINFO_JUMP;
111 info->flags = RSP_OPINFO_JUMP | RSP_OPINFO_LINK | RSP_OPINFO_USEPC;
117 info->flags = RSP_OPINFO_JUMP | RSP_OPINFO_COND | RSP_OPINFO_USEPC;
147 info->flags = RSP_OPINFO_JUMP;
150 info->flags = RSP_OPINFO_JUMP | RSP_OPINFO_LINK | RSP_OPINFO_USEPC;
153 info->flags = RSP_OPINFO_BREAK;
171 RSP_SET_VEC_I(info->used, VS1REG, ((el+0)&0xf)>>1);
172 RSP_SET_VEC_I(info->used, VS1REG, ((el+1)&0xf)>>1);
176 RSP_SET_FLAG_I(info->used, RDREG & 3);
181 RSP_SET_VEC_I(info->set, VS1REG, ((el+0)&0xf)>>1);
182 RSP_SET_VEC_I(info->set, VS1REG, ((el+1)&0xf)>>1);
186 RSP_SET_FLAG_I(info->set, RDREG & 3);
191 RSP_SET_VEC_I(info->set, dest, index>>1);
194 for (i=index; i<index+2; i++)
195 RSP_SET_VEC_I(info->set, dest, (i>>1)&7);
198 for (i=index; i<index+4; i++)
199 RSP_SET_VEC_I(info->set, dest, (i>>1)&7);
202 for (i=index; i<index+8; i++)
203 RSP_SET_VEC_I(info->set, dest, (i>>1)&7);
207 // WARNING WARNING WARNING
208 // we assume this instruction always used to load the full vector
209 // i.e. the address is always 16 bytes aligned
210 // for (i=0; i<8; i++)
211 // RSP_SET_VEC_I(info->set, dest, i);
218 RSP_SET_VEC_I(info->set, dest, i);
221 for (i=(index>>1); i<(index>>1)+4; i++)
222 RSP_SET_VEC_I(info->set, dest, i);
226 // 31 25 20 15 10 6 0
227 // --------------------------------------------------
228 // | 110010 | BBBBB | TTTTT | 01011 | IIII | Offset |
229 // --------------------------------------------------
231 // Loads one element to maximum of 8 vectors, while incrementing element index
233 // FIXME: has a small problem with odd indices
241 element = 7 - (index >> 1);
244 log(M64MSG_ERROR, "RSP: LTV: index = %d\n", index);
246 for (i=vs; i < ve; i++)
248 element = ((8 - (index >> 1) + (i-vs)) << 1);
249 RSP_SET_VEC_I(info->set, i, (element & 0xf)>>1);
250 RSP_SET_VEC_I(info->set, i, ((element+1) & 0xf)>>1);
256 RSP_SET_VEC_I(info->used, dest, index>>1);
259 for (i=index; i<index+2; i++)
260 RSP_SET_VEC_I(info->used, dest, (i>>1)&7);
263 for (i=index; i<index+4; i++)
264 RSP_SET_VEC_I(info->used, dest, (i>>1)&7);
267 for (i=index; i<index+8; i++)
268 RSP_SET_VEC_I(info->used, dest, (i>>1)&7);
272 // WARNING WARNING WARNING
273 // we assume this instruction always used to store the full vector
274 // i.e. the address is always 16 bytes aligned
276 RSP_SET_VEC_I(info->used, dest, i);
283 RSP_SET_VEC_I(info->used, dest, i);
286 for (i=(index>>1); i<(index>>1)+4; i++)
287 RSP_SET_VEC_I(info->used, dest, i);
291 // 31 25 20 15 10 6 0
292 // --------------------------------------------------
293 // | 111010 | BBBBB | TTTTT | 01011 | IIII | Offset |
294 // --------------------------------------------------
296 // Stores one element from maximum of 8 vectors, while incrementing element index
304 element = 8 - (index >> 1);
306 log(M64MSG_ERROR, "RSP: STV: index = %d at %08X\n", index, rsp.ppc);
308 for (i=vs; i < ve; i++)
310 RSP_SET_VEC_I(info->used, i, element & 0x7);
323 for (i=0; i < 8; i++)
325 int sel = VEC_EL_2(EL, i);
326 RSP_SET_VEC_I(info->used, VS1REG, i);
327 RSP_SET_VEC_I(info->used, VS2REG, sel);
328 RSP_SET_VEC_I(info->set, VDREG, i);
329 RSP_SET_ACCU_I(info->set, i, 14);
340 for (i=0; i < 8; i++)
342 int sel = VEC_EL_2(EL, i);
343 RSP_SET_VEC_I(info->used, VS1REG, i);
344 RSP_SET_VEC_I(info->used, VS2REG, sel);
345 RSP_SET_VEC_I(info->set, VDREG, i);
346 RSP_SET_ACCU_I(info->used, i, 14);
347 RSP_SET_ACCU_I(info->set, i, 14);
354 for (i=0; i < 8; i++)
356 int sel = VEC_EL_2(EL, i);
357 RSP_SET_VEC_I(info->used, VS1REG, i);
358 RSP_SET_VEC_I(info->used, VS2REG, sel);
359 RSP_SET_VEC_I(info->set, VDREG, i);
360 RSP_SET_ACCU_I(info->set, i, 2);
362 RSP_SET_FLAG_I(info->used, 0);
363 RSP_SET_FLAG_I(info->set, 0);
368 for (i=0; i < 8; i++)
370 int sel = VEC_EL_2(EL, i);
371 RSP_SET_VEC_I(info->used, VS1REG, i);
372 RSP_SET_VEC_I(info->used, VS2REG, sel);
373 RSP_SET_VEC_I(info->set, VDREG, i);
374 RSP_SET_ACCU_I(info->set, i, 2);
381 for (i=0; i < 8; i++)
383 int sel = VEC_EL_2(EL, i);
384 RSP_SET_VEC_I(info->used, VS1REG, i);
385 RSP_SET_VEC_I(info->used, VS2REG, sel);
386 RSP_SET_VEC_I(info->set, VDREG, i);
387 RSP_SET_ACCU_I(info->set, i, 2);
389 RSP_SET_FLAG_I(info->set, 0);
397 for (i=0; i < 8; i++)
399 RSP_SET_VEC_I(info->set, VDREG, i);
400 RSP_SET_ACCU_I(info->used, i, 8);
406 for (i=0; i < 8; i++)
408 RSP_SET_VEC_I(info->set, VDREG, i);
409 RSP_SET_ACCU_I(info->used, i, 4);
415 for (i=0; i < 8; i++)
417 RSP_SET_VEC_I(info->set, VDREG, i);
418 RSP_SET_ACCU_I(info->used, i, 2);
423 log(M64MSG_ERROR, "RSP: VSAW: el = %d\n", EL);
428 for (i=0; i < 8; i++)
430 int sel = VEC_EL_2(EL, i);
431 RSP_SET_VEC_I(info->used, VS1REG, i);
432 RSP_SET_VEC_I(info->used, VS2REG, sel);
433 RSP_SET_VEC_I(info->set, VDREG, i);
434 RSP_SET_ACCU_I(info->set, i, 2);
436 RSP_SET_FLAG_I(info->set, 0);
437 RSP_SET_FLAG_I(info->set, 1);
444 for (i=0; i < 8; i++)
446 int sel = VEC_EL_2(EL, i);
447 RSP_SET_VEC_I(info->used, VS1REG, i);
448 RSP_SET_VEC_I(info->used, VS2REG, sel);
449 RSP_SET_VEC_I(info->set, VDREG, i);
450 RSP_SET_ACCU_I(info->set, i, 2);
452 RSP_SET_FLAG_I(info->used, 0);
453 RSP_SET_FLAG_I(info->set, 0);
454 RSP_SET_FLAG_I(info->set, 1);
459 for (i=0; i < 8; i++)
461 int sel = VEC_EL_2(EL, i);
462 RSP_SET_VEC_I(info->used, VS1REG, i);
463 RSP_SET_VEC_I(info->used, VS2REG, sel);
464 RSP_SET_VEC_I(info->set, VDREG, i);
465 RSP_SET_ACCU_I(info->set, i, 2);
467 RSP_SET_FLAG_I(info->used, 0);
468 RSP_SET_FLAG_I(info->used, 1);
469 RSP_SET_FLAG_I(info->set, 0);
470 RSP_SET_FLAG_I(info->set, 1);
471 RSP_SET_FLAG_I(info->set, 2);
477 for (i=0; i < 8; i++)
479 int sel = VEC_EL_2(EL, i);
480 RSP_SET_VEC_I(info->used, VS1REG, i);
481 RSP_SET_VEC_I(info->used, VS2REG, sel);
482 RSP_SET_VEC_I(info->set, VDREG, i);
483 RSP_SET_ACCU_I(info->set, i, 2);
485 RSP_SET_FLAG_I(info->set, 0);
486 RSP_SET_FLAG_I(info->set, 1);
487 RSP_SET_FLAG_I(info->set, 2);
492 for (i=0; i < 8; i++)
494 int sel = VEC_EL_2(EL, i);
495 RSP_SET_VEC_I(info->used, VS1REG, i);
496 RSP_SET_VEC_I(info->used, VS2REG, sel);
497 RSP_SET_VEC_I(info->set, VDREG, i);
498 RSP_SET_ACCU_I(info->set, i, 2);
500 RSP_SET_FLAG_I(info->used, 1);
510 for (i=0; i < 8; i++)
512 int sel = VEC_EL_2(EL, i);
513 RSP_SET_VEC_I(info->used, VS1REG, i);
514 RSP_SET_VEC_I(info->used, VS2REG, sel);
515 RSP_SET_VEC_I(info->set, VDREG, i);
516 RSP_SET_ACCU_I(info->set, i, 2);
526 int del = (VS1REG & 7);
527 int sel = VEC_EL_2(EL, del);
529 RSP_SET_VEC_I(info->used, VS2REG, sel);
531 for (i=0; i < 8; i++)
533 int element = VEC_EL_2(EL, i);
534 RSP_SET_VEC_I(info->used, VS2REG, element);
535 RSP_SET_ACCU_I(info->set, i, 2);
538 RSP_SET_VEC_I(info->set, VDREG, del);
543 int element = VS1REG & 7;
544 RSP_SET_VEC_I(info->used, VS2REG, VEC_EL_2(EL, 7-element));
545 RSP_SET_VEC_I(info->set, VDREG, element);
552 // rsp_dasm_one(string, 0x800, op);
553 // if (strcmp(string, "???")) {
554 // printf("%s\n", string);
555 // printf("unimplemented opcode\n");