1 // 2 // rsp/vfunctions.c: RSP vector execution functions. 3 // 4 // CEN64: Cycle-Accurate Nintendo 64 Emulator. 5 // Copyright (C) 2015, Tyler J. Stachecki. 6 // 7 // This file is subject to the terms and conditions defined in 8 // 'LICENSE', which is part of this source code package. 9 // 10 11 #include "../state.hpp" 12 #include "../rsp_op.hpp" 13 #include "rsp_impl.h" 14 #include <stdio.h> 15 16 #define LOAD_VS() rsp_vect_load_unshuffled_operand(rsp->cp2.regs[vs].e) 17 #define LOAD_VT() rsp_vect_load_and_shuffle_operand(rsp->cp2.regs[vt].e, e) 18 #define STORE_RESULT() rsp_vect_write_operand(rsp->cp2.regs[vd].e, result) 19 20 #ifdef TRACE_COP2 21 #define TRACE_VU(op) printf(#op " v%u, v%u, v%u[%u]\n", vd, vs, vt, e) 22 #else 23 #define TRACE_VU(op) ((void)0) 24 #endif 25 26 extern "C" 27 { 28 // 29 // VABS 30 // RSP_VABS(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)31 void RSP_VABS(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 32 { 33 TRACE_VU(VABS); 34 uint16_t *acc = rsp->cp2.acc.e; 35 rsp_vect_t acc_lo; 36 rsp_vect_t result = rsp_vabs(LOAD_VS(), LOAD_VT(), &acc_lo); 37 write_acc_lo(acc, acc_lo); 38 rsp_vect_write_operand(rsp->cp2.regs[vd].e, result); 39 } 40 41 // 42 // VADD 43 // RSP_VADD(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)44 void RSP_VADD(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 45 { 46 TRACE_VU(VADD); 47 uint16_t *acc = rsp->cp2.acc.e; 48 rsp_vect_t carry, acc_lo; 49 50 carry = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e); 51 rsp_vect_t result = rsp_vadd(LOAD_VS(), LOAD_VT(), carry, &acc_lo); 52 53 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 54 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 55 write_acc_lo(acc, acc_lo); 56 STORE_RESULT(); 57 } 58 59 // 60 // VADDC 61 // RSP_VADDC(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)62 void RSP_VADDC(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 63 { 64 TRACE_VU(VADDC); 65 uint16_t *acc = rsp->cp2.acc.e; 66 rsp_vect_t sn; 67 68 rsp_vect_t result = rsp_vaddc(LOAD_VS(), LOAD_VT(), rsp_vzero(), &sn); 69 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); // TODO: Confirm. 70 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, sn); 71 write_acc_lo(acc, result); 72 STORE_RESULT(); 73 } 74 75 // 76 // VAND 77 // VNAND 78 // RSP_VAND(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)79 void RSP_VAND(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 80 { 81 TRACE_VU(VAND); 82 uint16_t *acc = rsp->cp2.acc.e; 83 rsp_vect_t result = rsp_vand(LOAD_VS(), LOAD_VT()); 84 write_acc_lo(acc, result); 85 STORE_RESULT(); 86 } 87 RSP_VNAND(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)88 void RSP_VNAND(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 89 { 90 TRACE_VU(VNAND); 91 uint16_t *acc = rsp->cp2.acc.e; 92 rsp_vect_t result = rsp_vnand(LOAD_VS(), LOAD_VT()); 93 write_acc_lo(acc, result); 94 STORE_RESULT(); 95 } 96 97 // 98 // VCH 99 // RSP_VCH(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)100 void RSP_VCH(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 101 { 102 TRACE_VU(VCH); 103 uint16_t *acc = rsp->cp2.acc.e; 104 rsp_vect_t ge, le, sign, eq, vce; 105 106 rsp_vect_t result = rsp_vch(LOAD_VS(), LOAD_VT(), rsp_vzero(), &ge, &le, &eq, &sign, &vce); 107 108 write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, ge); 109 write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le); 110 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, eq); 111 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, sign); 112 write_vce(rsp->cp2.flags[RSP::RSP_VCE].e, vce); 113 write_acc_lo(acc, result); 114 STORE_RESULT(); 115 } 116 117 // 118 // VCL 119 // RSP_VCL(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)120 void RSP_VCL(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 121 { 122 TRACE_VU(VCL); 123 uint16_t *acc = rsp->cp2.acc.e; 124 rsp_vect_t ge, le, eq, sign, vce; 125 126 ge = read_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e); 127 le = read_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e); 128 eq = read_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e); 129 sign = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e); 130 vce = read_vce(rsp->cp2.flags[RSP::RSP_VCE].e); 131 132 rsp_vect_t result = rsp_vcl(LOAD_VS(), LOAD_VT(), rsp_vzero(), &ge, &le, eq, sign, vce); 133 134 write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, ge); 135 write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le); 136 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 137 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 138 write_vce(rsp->cp2.flags[RSP::RSP_VCE].e, rsp_vzero()); 139 write_acc_lo(acc, result); 140 STORE_RESULT(); 141 } 142 143 // 144 // VCR 145 // RSP_VCR(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)146 void RSP_VCR(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 147 { 148 TRACE_VU(VCR); 149 uint16_t *acc = rsp->cp2.acc.e; 150 rsp_vect_t ge, le; 151 152 rsp_vect_t result = rsp_vcr(LOAD_VS(), LOAD_VT(), rsp_vzero(), &ge, &le); 153 154 #ifdef INTENSE_DEBUG 155 for (unsigned i = 0; i < 8; i++) 156 fprintf(stderr, "VD[%d] = %d\n", i, reinterpret_cast<int16_t *>(&result)[i]); 157 #endif 158 159 write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, ge); 160 write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le); 161 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 162 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 163 write_vce(rsp->cp2.flags[RSP::RSP_VCE].e, rsp_vzero()); 164 write_acc_lo(acc, result); 165 STORE_RESULT(); 166 } 167 168 // 169 // VEQ 170 // VGE 171 // VLT 172 // VNE 173 // RSP_VEQ(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)174 void RSP_VEQ(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 175 { 176 TRACE_VU(VEQ); 177 uint16_t *acc = rsp->cp2.acc.e; 178 rsp_vect_t le, eq, sign; 179 180 eq = read_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e); 181 sign = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e); 182 183 rsp_vect_t result = rsp_veq(LOAD_VS(), LOAD_VT(), rsp_vzero(), &le, eq, sign); 184 185 write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, rsp_vzero()); 186 write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le); 187 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 188 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 189 write_acc_lo(acc, result); 190 STORE_RESULT(); 191 } 192 RSP_VGE(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)193 void RSP_VGE(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 194 { 195 TRACE_VU(VGE); 196 uint16_t *acc = rsp->cp2.acc.e; 197 rsp_vect_t le, eq, sign; 198 199 eq = read_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e); 200 sign = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e); 201 202 rsp_vect_t result = rsp_vge(LOAD_VS(), LOAD_VT(), rsp_vzero(), &le, eq, sign); 203 204 write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, rsp_vzero()); 205 write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le); 206 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 207 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 208 write_acc_lo(acc, result); 209 STORE_RESULT(); 210 } 211 RSP_VLT(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)212 void RSP_VLT(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 213 { 214 TRACE_VU(VLT); 215 uint16_t *acc = rsp->cp2.acc.e; 216 rsp_vect_t le, eq, sign; 217 218 eq = read_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e); 219 sign = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e); 220 221 rsp_vect_t result = rsp_vlt(LOAD_VS(), LOAD_VT(), rsp_vzero(), &le, eq, sign); 222 223 write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, rsp_vzero()); 224 write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le); 225 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 226 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 227 write_acc_lo(acc, result); 228 STORE_RESULT(); 229 } 230 RSP_VNE(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)231 void RSP_VNE(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 232 { 233 TRACE_VU(VNE); 234 uint16_t *acc = rsp->cp2.acc.e; 235 rsp_vect_t le, eq, sign; 236 237 eq = read_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e); 238 sign = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e); 239 240 rsp_vect_t result = rsp_vne(LOAD_VS(), LOAD_VT(), rsp_vzero(), &le, eq, sign); 241 #ifdef INTENSE_DEBUG 242 for (unsigned i = 0; i < 8; i++) 243 fprintf(stderr, "VD[%d] = %d\n", i, reinterpret_cast<int16_t *>(&result)[i]); 244 #endif 245 246 write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, rsp_vzero()); 247 write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le); 248 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 249 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 250 write_acc_lo(acc, result); 251 STORE_RESULT(); 252 } 253 254 // 255 // VINVALID 256 // RSP_VINVALID(RSP::CPUState *,unsigned,unsigned,unsigned,unsigned)257 void RSP_VINVALID(RSP::CPUState *, unsigned, unsigned, unsigned, unsigned) 258 { 259 fprintf(stderr, "Unimplemented ...\n"); 260 } 261 262 // 263 // VMACF 264 // VMACU 265 // RSP_VMACF(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)266 void RSP_VMACF(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 267 { 268 TRACE_VU(VMACF); 269 uint16_t *acc = rsp->cp2.acc.e; 270 rsp_vect_t acc_lo, acc_md, acc_hi, result; 271 acc_lo = read_acc_lo(acc); 272 acc_md = read_acc_md(acc); 273 acc_hi = read_acc_hi(acc); 274 275 result = rsp_vmacf_vmacu<false>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 276 277 write_acc_lo(acc, acc_lo); 278 write_acc_md(acc, acc_md); 279 write_acc_hi(acc, acc_hi); 280 STORE_RESULT(); 281 } 282 RSP_VMACU(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)283 void RSP_VMACU(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 284 { 285 TRACE_VU(VMACU); 286 uint16_t *acc = rsp->cp2.acc.e; 287 rsp_vect_t acc_lo, acc_md, acc_hi, result; 288 acc_lo = read_acc_lo(acc); 289 acc_md = read_acc_md(acc); 290 acc_hi = read_acc_hi(acc); 291 292 result = rsp_vmacf_vmacu<true>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 293 294 write_acc_lo(acc, acc_lo); 295 write_acc_md(acc, acc_md); 296 write_acc_hi(acc, acc_hi); 297 STORE_RESULT(); 298 } 299 300 // 301 // VMADH 302 // VMUDH 303 // RSP_VMADH(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)304 void RSP_VMADH(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 305 { 306 TRACE_VU(VMADH); 307 uint16_t *acc = rsp->cp2.acc.e; 308 rsp_vect_t acc_lo, acc_md, acc_hi, result; 309 310 acc_lo = read_acc_lo(acc); 311 acc_md = read_acc_md(acc); 312 acc_hi = read_acc_hi(acc); 313 314 result = rsp_vmadh_vmudh<true>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 315 316 write_acc_lo(acc, acc_lo); 317 write_acc_md(acc, acc_md); 318 write_acc_hi(acc, acc_hi); 319 STORE_RESULT(); 320 } 321 RSP_VMUDH(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)322 void RSP_VMUDH(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 323 { 324 TRACE_VU(VMUDH); 325 uint16_t *acc = rsp->cp2.acc.e; 326 rsp_vect_t acc_lo, acc_md, acc_hi, result; 327 328 acc_lo = read_acc_lo(acc); 329 acc_md = read_acc_md(acc); 330 acc_hi = read_acc_hi(acc); 331 332 result = rsp_vmadh_vmudh<false>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 333 334 write_acc_lo(acc, acc_lo); 335 write_acc_md(acc, acc_md); 336 write_acc_hi(acc, acc_hi); 337 STORE_RESULT(); 338 } 339 340 // 341 // VMADL 342 // VMUDL 343 // RSP_VMADL(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)344 void RSP_VMADL(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 345 { 346 TRACE_VU(VMADL); 347 uint16_t *acc = rsp->cp2.acc.e; 348 rsp_vect_t acc_lo, acc_md, acc_hi, result; 349 350 acc_lo = read_acc_lo(acc); 351 acc_md = read_acc_md(acc); 352 acc_hi = read_acc_hi(acc); 353 354 result = rsp_vmadl_vmudl<true>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 355 356 write_acc_lo(acc, acc_lo); 357 write_acc_md(acc, acc_md); 358 write_acc_hi(acc, acc_hi); 359 STORE_RESULT(); 360 } 361 RSP_VMUDL(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)362 void RSP_VMUDL(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 363 { 364 TRACE_VU(VMUDL); 365 uint16_t *acc = rsp->cp2.acc.e; 366 rsp_vect_t acc_lo, acc_md, acc_hi, result; 367 368 acc_lo = read_acc_lo(acc); 369 acc_md = read_acc_md(acc); 370 acc_hi = read_acc_hi(acc); 371 372 result = rsp_vmadl_vmudl<false>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 373 374 write_acc_lo(acc, acc_lo); 375 write_acc_md(acc, acc_md); 376 write_acc_hi(acc, acc_hi); 377 STORE_RESULT(); 378 } 379 380 // 381 // VMADM 382 // VMUDM 383 // RSP_VMADM(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)384 void RSP_VMADM(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 385 { 386 TRACE_VU(VMADM); 387 uint16_t *acc = rsp->cp2.acc.e; 388 rsp_vect_t acc_lo, acc_md, acc_hi, result; 389 390 acc_lo = read_acc_lo(acc); 391 acc_md = read_acc_md(acc); 392 acc_hi = read_acc_hi(acc); 393 394 result = rsp_vmadm_vmudm<true>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 395 396 write_acc_lo(acc, acc_lo); 397 write_acc_md(acc, acc_md); 398 write_acc_hi(acc, acc_hi); 399 STORE_RESULT(); 400 } 401 RSP_VMUDM(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)402 void RSP_VMUDM(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 403 { 404 TRACE_VU(VMUDM); 405 uint16_t *acc = rsp->cp2.acc.e; 406 rsp_vect_t acc_lo, acc_md, acc_hi, result; 407 408 acc_lo = read_acc_lo(acc); 409 acc_md = read_acc_md(acc); 410 acc_hi = read_acc_hi(acc); 411 412 result = rsp_vmadm_vmudm<false>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 413 414 write_acc_lo(acc, acc_lo); 415 write_acc_md(acc, acc_md); 416 write_acc_hi(acc, acc_hi); 417 STORE_RESULT(); 418 } 419 420 // 421 // VMADN 422 // VMUDN 423 // RSP_VMADN(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)424 void RSP_VMADN(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 425 { 426 TRACE_VU(VMADN); 427 uint16_t *acc = rsp->cp2.acc.e; 428 rsp_vect_t acc_lo, acc_md, acc_hi, result; 429 430 acc_lo = read_acc_lo(acc); 431 acc_md = read_acc_md(acc); 432 acc_hi = read_acc_hi(acc); 433 434 result = rsp_vmadn_vmudn<true>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 435 436 write_acc_lo(acc, acc_lo); 437 write_acc_md(acc, acc_md); 438 write_acc_hi(acc, acc_hi); 439 STORE_RESULT(); 440 } 441 RSP_VMUDN(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)442 void RSP_VMUDN(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 443 { 444 TRACE_VU(VMUDN); 445 uint16_t *acc = rsp->cp2.acc.e; 446 rsp_vect_t acc_lo, acc_md, acc_hi, result; 447 448 acc_lo = read_acc_lo(acc); 449 acc_md = read_acc_md(acc); 450 acc_hi = read_acc_hi(acc); 451 452 result = rsp_vmadn_vmudn<false>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 453 454 write_acc_lo(acc, acc_lo); 455 write_acc_md(acc, acc_md); 456 write_acc_hi(acc, acc_hi); 457 STORE_RESULT(); 458 } 459 460 // 461 // VMOV 462 // RSP_VMOV(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)463 void RSP_VMOV(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 464 { 465 TRACE_VU(VMOV); 466 uint16_t *acc = rsp->cp2.acc.e; 467 unsigned de = vs & 0x7; 468 write_acc_lo(acc, LOAD_VT()); 469 __m128i result = rsp_vmov(rsp, vt, e, vd, de); 470 STORE_RESULT(); 471 } 472 473 // 474 // VMRG 475 // RSP_VMRG(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)476 void RSP_VMRG(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 477 { 478 TRACE_VU(VMRG); 479 uint16_t *acc = rsp->cp2.acc.e; 480 rsp_vect_t le; 481 482 le = read_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e); 483 rsp_vect_t result = rsp_vmrg(LOAD_VS(), LOAD_VT(), le); 484 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 485 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 486 write_acc_lo(acc, result); 487 STORE_RESULT(); 488 } 489 490 // 491 // VMULF 492 // VMULU 493 // RSP_VMULF(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)494 void RSP_VMULF(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 495 { 496 TRACE_VU(VMULF); 497 uint16_t *acc = rsp->cp2.acc.e; 498 rsp_vect_t acc_lo, acc_md, acc_hi, result; 499 500 result = rsp_vmulf_vmulu<false>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 501 502 write_acc_lo(acc, acc_lo); 503 write_acc_md(acc, acc_md); 504 write_acc_hi(acc, acc_hi); 505 STORE_RESULT(); 506 } 507 RSP_VMULU(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)508 void RSP_VMULU(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 509 { 510 TRACE_VU(VMULU); 511 uint16_t *acc = rsp->cp2.acc.e; 512 rsp_vect_t acc_lo, acc_md, acc_hi, result; 513 514 result = rsp_vmulf_vmulu<true>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi); 515 516 write_acc_lo(acc, acc_lo); 517 write_acc_md(acc, acc_md); 518 write_acc_hi(acc, acc_hi); 519 STORE_RESULT(); 520 } 521 522 // 523 // VNOP 524 // RSP_VNOP(RSP::CPUState *,unsigned,unsigned,unsigned,unsigned)525 void RSP_VNOP(RSP::CPUState *, unsigned, unsigned, unsigned, unsigned) 526 { 527 } 528 529 // 530 // VOR 531 // VNOR 532 // RSP_VOR(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)533 void RSP_VOR(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 534 { 535 TRACE_VU(VOR); 536 uint16_t *acc = rsp->cp2.acc.e; 537 538 rsp_vect_t result = rsp_vor(LOAD_VS(), LOAD_VT()); 539 540 write_acc_lo(acc, result); 541 STORE_RESULT(); 542 } 543 RSP_VNOR(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)544 void RSP_VNOR(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 545 { 546 TRACE_VU(VNOR); 547 uint16_t *acc = rsp->cp2.acc.e; 548 549 rsp_vect_t result = rsp_vnor(LOAD_VS(), LOAD_VT()); 550 551 write_acc_lo(acc, result); 552 STORE_RESULT(); 553 } 554 555 // 556 // VRCP 557 // VRCPL 558 // VRSQ 559 // VRSQL 560 // RSP_VRCP(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)561 void RSP_VRCP(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 562 { 563 TRACE_VU(VRCP); 564 uint16_t *acc = rsp->cp2.acc.e; 565 unsigned de = vs & 0x7; 566 e &= 0x7; 567 568 write_acc_lo(acc, LOAD_VT()); 569 570 rsp->cp2.dp_flag = 0; 571 rsp_vect_t result = rsp_vrcp_vrsq<false>(rsp, 0, vt, e, vd, de); 572 STORE_RESULT(); 573 } 574 RSP_VRCPL(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)575 void RSP_VRCPL(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 576 { 577 TRACE_VU(VRCPL); 578 uint16_t *acc = rsp->cp2.acc.e; 579 unsigned de = vs & 0x7; 580 e &= 0x7; 581 582 write_acc_lo(acc, LOAD_VT()); 583 584 int dp = rsp->cp2.dp_flag & 1; 585 rsp->cp2.dp_flag = 0; 586 587 rsp_vect_t result = rsp_vrcp_vrsq<false>(rsp, dp, vt, e, vd, de); 588 STORE_RESULT(); 589 } 590 RSP_VRSQ(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)591 void RSP_VRSQ(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 592 { 593 TRACE_VU(VRSQ); 594 uint16_t *acc = rsp->cp2.acc.e; 595 unsigned de = vs & 0x7; 596 e &= 0x7; 597 598 write_acc_lo(acc, LOAD_VT()); 599 600 rsp->cp2.dp_flag = 0; 601 rsp_vect_t result = rsp_vrcp_vrsq<true>(rsp, 0, vt, e, vd, de); 602 STORE_RESULT(); 603 } 604 RSP_VRSQL(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)605 void RSP_VRSQL(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 606 { 607 TRACE_VU(VRSQL); 608 uint16_t *acc = rsp->cp2.acc.e; 609 unsigned de = vs & 0x7; 610 e &= 0x7; 611 612 write_acc_lo(acc, LOAD_VT()); 613 614 int dp = rsp->cp2.dp_flag & 1; 615 rsp->cp2.dp_flag = 0; 616 617 rsp_vect_t result = rsp_vrcp_vrsq<true>(rsp, dp, vt, e, vd, de); 618 STORE_RESULT(); 619 } 620 621 // 622 // VRCPH 623 // VRSQH 624 // RSP_VRCPH(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)625 void RSP_VRCPH(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 626 { 627 TRACE_VU(VRCPH); 628 uint16_t *acc = rsp->cp2.acc.e; 629 unsigned de = vs & 0x7; 630 e &= 0x7; 631 632 write_acc_lo(acc, LOAD_VT()); 633 634 // Specify double-precision for VRCPL on the next pass. 635 rsp->cp2.dp_flag = 1; 636 637 rsp_vect_t result = rsp_vdivh(rsp, vt, e, vd, de); 638 STORE_RESULT(); 639 } 640 RSP_VRSQH(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)641 void RSP_VRSQH(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 642 { 643 TRACE_VU(VRSQH); 644 uint16_t *acc = rsp->cp2.acc.e; 645 unsigned de = vs & 0x7; 646 e &= 0x7; 647 648 write_acc_lo(acc, LOAD_VT()); 649 650 // Specify double-precision for VRCPL on the next pass. 651 rsp->cp2.dp_flag = 1; 652 653 rsp_vect_t result = rsp_vdivh(rsp, vt, e, vd, de); 654 STORE_RESULT(); 655 } 656 657 // 658 // VSAR 659 // RSP_VSAR(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)660 void RSP_VSAR(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 661 { 662 TRACE_VU(VSAR); 663 uint16_t *acc = rsp->cp2.acc.e; 664 rsp_vect_t result; 665 666 switch (e) 667 { 668 case 8: 669 result = read_acc_hi(acc); 670 break; 671 case 9: 672 result = read_acc_md(acc); 673 break; 674 case 10: 675 result = read_acc_lo(acc); 676 break; 677 default: 678 result = rsp_vzero(); 679 break; 680 } 681 682 STORE_RESULT(); 683 } 684 685 // 686 // VSUB 687 // RSP_VSUB(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)688 void RSP_VSUB(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 689 { 690 TRACE_VU(VSUB); 691 uint16_t *acc = rsp->cp2.acc.e; 692 rsp_vect_t carry, acc_lo; 693 694 carry = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e); 695 696 rsp_vect_t result = rsp_vsub(LOAD_VS(), LOAD_VT(), carry, &acc_lo); 697 698 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 699 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); 700 write_acc_lo(acc, acc_lo); 701 STORE_RESULT(); 702 } 703 704 // 705 // VSUBC 706 // RSP_VSUBC(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)707 void RSP_VSUBC(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 708 { 709 TRACE_VU(VSUBC); 710 uint16_t *acc = rsp->cp2.acc.e; 711 rsp_vect_t eq, sn; 712 713 rsp_vect_t result = rsp_vsubc(LOAD_VS(), LOAD_VT(), rsp_vzero(), &eq, &sn); 714 715 write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, eq); 716 write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, sn); 717 write_acc_lo(acc, result); 718 STORE_RESULT(); 719 } 720 721 // 722 // VXOR 723 // VNXOR 724 // RSP_VXOR(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)725 void RSP_VXOR(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 726 { 727 TRACE_VU(VXOR); 728 uint16_t *acc = rsp->cp2.acc.e; 729 730 rsp_vect_t result = rsp_vxor(LOAD_VS(), LOAD_VT()); 731 732 write_acc_lo(acc, result); 733 STORE_RESULT(); 734 } 735 RSP_VNXOR(RSP::CPUState * rsp,unsigned vd,unsigned vs,unsigned vt,unsigned e)736 void RSP_VNXOR(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e) 737 { 738 TRACE_VU(VXNOR); 739 uint16_t *acc = rsp->cp2.acc.e; 740 741 rsp_vect_t result = rsp_vnxor(LOAD_VS(), LOAD_VT()); 742 743 write_acc_lo(acc, result); 744 STORE_RESULT(); 745 } 746 747 // RESERVED RSP_RESERVED(RSP::CPUState * rsp,unsigned vd,unsigned,unsigned,unsigned)748 void RSP_RESERVED(RSP::CPUState *rsp, unsigned vd, unsigned, unsigned, unsigned) 749 { 750 rsp_vect_t result = rsp_vzero(); 751 STORE_RESULT(); 752 } 753 } 754