1 // -*- C -*- 2 3 // Simulator definition for the MIPS DSP ASE. 4 // Copyright (C) 2005-2025 Free Software Foundation, Inc. 5 // Contributed by MIPS Technologies, Inc. Written by Chao-ying Fu. 6 // 7 // This file is part of the MIPS sim 8 // 9 // This program is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation; either version 3 of the License, or 12 // (at your option) any later version. 13 // 14 // This program is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with this program. If not, see <http://www.gnu.org/licenses/>. 21 22 23 // op: 0 = ADD, 1 = SUB, 2 = MUL 24 // sat: 0 = no saturation, 1 = saturation 25 :function:::void:do_ph_op:int rd, int rs, int rt, int op, int sat 26 { 27 int i; 28 int32_t h0 = 0; 29 int16_t h1, h2; 30 uint32_t v1 = GPR[rs]; 31 uint32_t v2 = GPR[rt]; 32 uint32_t result = 0; 33 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 34 { 35 h1 = (int16_t)(v1 & 0xffff); 36 h2 = (int16_t)(v2 & 0xffff); 37 if (op == 0) // ADD 38 h0 = (int32_t)h1 + (int32_t)h2; 39 else if (op == 1) // SUB 40 h0 = (int32_t)h1 - (int32_t)h2; 41 else // MUL 42 h0 = (int32_t)h1 * (int32_t)h2; 43 if (h0 > (int32_t)0x7fff || h0 < (int32_t)0xffff8000) 44 { 45 if (op == 0 || op == 1) // ADD, SUB 46 DSPCR |= DSPCR_OUFLAG4; 47 else if (op == 2) // MUL 48 DSPCR |= DSPCR_OUFLAG5; 49 if (sat == 1) 50 { 51 if (h0 > (int32_t)0x7fff) 52 h0 = 0x7fff; 53 else 54 h0 = 0x8000; 55 } 56 } 57 result |= ((uint32_t)((uint16_t)h0) << i); 58 } 59 GPR[rd] = EXTEND32 (result); 60 } 61 62 // op: 0 = ADD, 1 = SUB 63 :function:::void:do_w_op:int rd, int rs, int rt, int op 64 { 65 int64_t h0; 66 int32_t h1, h2; 67 uint32_t v1 = GPR[rs]; 68 uint32_t v2 = GPR[rt]; 69 h1 = (int32_t)v1; 70 h2 = (int32_t)v2; 71 if (op == 0) // ADD 72 h0 = (int64_t)h1 + (int64_t)h2; 73 else // SUB 74 h0 = (int64_t)h1 - (int64_t)h2; 75 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000)) 76 { 77 DSPCR |= DSPCR_OUFLAG4; 78 if (h0 & 0x100000000LL) 79 h0 = 0x80000000; 80 else 81 h0 = 0x7fffffff; 82 } 83 GPR[rd] = EXTEND32 (h0); 84 } 85 86 // op: 0 = ADD, 1 = SUB 87 // sat: 0 = no saturation, 1 = saturation 88 :function:::void:do_qb_op:int rd, int rs, int rt, int op, int sat 89 { 90 int i; 91 uint32_t h0; 92 uint8_t h1, h2; 93 uint32_t v1 = GPR[rs]; 94 uint32_t v2 = GPR[rt]; 95 uint32_t result = 0; 96 for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8) 97 { 98 h1 = (uint8_t)(v1 & 0xff); 99 h2 = (uint8_t)(v2 & 0xff); 100 if (op == 0) // ADD 101 h0 = (uint32_t)h1 + (uint32_t)h2; 102 else // SUB 103 h0 = (uint32_t)h1 - (uint32_t)h2; 104 if (h0 & 0x100) 105 { 106 DSPCR |= DSPCR_OUFLAG4; 107 if (sat == 1) 108 { 109 if (op == 0) // ADD 110 h0 = 0xff; 111 else // SUB 112 h0 = 0; 113 } 114 } 115 result |= ((uint32_t)((uint8_t)h0) << i); 116 } 117 GPR[rd] = EXTEND32 (result); 118 } 119 120 // op: 0 = left, 1 = right 121 :function:::void:do_qb_shift:int rd, int rt, int shift, int op 122 { 123 int i, j; 124 uint8_t h0; 125 uint32_t v1 = GPR[rt]; 126 uint32_t result = 0; 127 for (i = 0; i < 32; i += 8, v1 >>= 8) 128 { 129 h0 = (uint8_t)(v1 & 0xff); 130 if (op == 0) // left 131 { 132 for (j = 7; j >= 8 - shift; j--) 133 { 134 if (h0 & (1<<j)) 135 { 136 DSPCR |= DSPCR_OUFLAG6; 137 break; 138 } 139 } 140 h0 = h0 << shift; 141 } 142 else // right 143 h0 = h0 >> shift; 144 result |= ((uint32_t)h0 << i); 145 } 146 GPR[rd] = EXTEND32 (result); 147 } 148 149 // op: 0 = left, 1 = right 150 // sat: 0 = no saturation/rounding, 1 = saturation/rounding 151 :function:::void:do_ph_shift:int rd, int rt, int shift, int op, int sat 152 { 153 int i, j; 154 int16_t h0; 155 uint32_t v1 = GPR[rt]; 156 uint32_t result = 0; 157 int setcond; 158 for (i = 0; i < 32; i += 16, v1 >>= 16) 159 { 160 h0 = (int16_t)(v1 & 0xffff); 161 if (op == 0) // left 162 { 163 setcond = 0; 164 if (h0 & (1<<15)) 165 { 166 for (j = 14; j >= 15 - shift; j--) 167 { 168 if (!(h0 & (1 << j))) 169 { 170 DSPCR |= DSPCR_OUFLAG6; 171 setcond = 1; 172 break; 173 } 174 } 175 } 176 else 177 { 178 for (j = 14; j >= 15 - shift; j--) 179 { 180 if (h0 & (1 << j)) 181 { 182 DSPCR |= DSPCR_OUFLAG6; 183 setcond = 2; 184 break; 185 } 186 } 187 } 188 h0 = h0 << shift; 189 if (sat == 1) 190 { 191 if (setcond == 2) 192 h0 = 0x7fff; 193 else if (setcond == 1) 194 h0 = 0x8000; 195 } 196 } 197 else // right 198 { 199 if (sat == 1 && shift != 0 && (h0 & (1 << (shift-1)))) 200 h0 = (h0 >> shift) + 1; 201 else 202 h0 = h0 >> shift; 203 } 204 205 result |= ((uint32_t)((uint16_t)h0) << i); 206 } 207 GPR[rd] = EXTEND32 (result); 208 } 209 210 :function:::void:do_w_shll:int rd, int rt, int shift 211 { 212 int i; 213 uint32_t v1 = GPR[rt]; 214 uint32_t result = 0; 215 int setcond = 0; 216 if (v1 & (1 << 31)) 217 { 218 for (i = 30; i >= 31 - shift; i--) 219 { 220 if (!(v1 & (1 << i))) 221 { 222 DSPCR |= DSPCR_OUFLAG6; 223 setcond = 1; 224 break; 225 } 226 } 227 } 228 else 229 { 230 for (i = 30; i >= 31 - shift; i--) 231 { 232 if (v1 & (1 << i)) 233 { 234 DSPCR |= DSPCR_OUFLAG6; 235 setcond = 2; 236 break; 237 } 238 } 239 } 240 if (setcond == 2) 241 result = 0x7fffffff; 242 else if (setcond == 1) 243 result = 0x80000000; 244 else 245 result = v1 << shift; 246 GPR[rd] = EXTEND32 (result); 247 } 248 249 :function:::void:do_ph_s_absq:int rd, int rt 250 { 251 int i; 252 int16_t h0; 253 uint32_t v1 = GPR[rt]; 254 uint32_t result = 0; 255 for (i = 0; i < 32; i += 16, v1 >>= 16) 256 { 257 h0 = (int16_t)(v1 & 0xffff); 258 if (h0 == (int16_t)0x8000) 259 { 260 DSPCR |= DSPCR_OUFLAG4; 261 h0 = 0x7fff; 262 } 263 else if (h0 & 0x8000) 264 h0 = -h0; 265 result |= ((uint32_t)((uint16_t)h0) << i); 266 } 267 GPR[rd] = EXTEND32 (result); 268 } 269 270 :function:::void:do_w_s_absq:int rd, int rt 271 { 272 uint32_t v1 = GPR[rt]; 273 int32_t h0 = (int32_t)v1; 274 if (h0 == (int32_t)0x80000000) 275 { 276 DSPCR |= DSPCR_OUFLAG4; 277 h0 = 0x7fffffff; 278 } 279 else if (h0 & 0x80000000) 280 h0 = -h0; 281 GPR[rd] = EXTEND32 (h0); 282 } 283 284 :function:::void:do_qb_s_absq:int rd, int rt 285 { 286 int i; 287 int8_t q0; 288 uint32_t v1 = GPR[rt]; 289 uint32_t result = 0; 290 for (i = 0; i < 32; i += 8, v1 >>= 8) 291 { 292 q0 = (int8_t)(v1 & 0xff); 293 if (q0 == (int8_t)0x80) 294 { 295 DSPCR |= DSPCR_OUFLAG4; 296 q0 = 0x7f; 297 } 298 else if (q0 & 0x80) 299 q0 = -q0; 300 result |= ((uint32_t)((uint8_t)q0) << i); 301 } 302 GPR[rd] = EXTEND32 (result); 303 } 304 305 :function:::void:do_addsc:int rd, int rs, int rt 306 { 307 uint32_t v1 = GPR[rs]; 308 uint32_t v2 = GPR[rt]; 309 uint64_t h0; 310 h0 = (uint64_t)v1 + (uint64_t)v2; 311 if (h0 & 0x100000000LL) 312 DSPCR |= DSPCR_CARRY; 313 GPR[rd] = EXTEND32 (h0); 314 } 315 316 :function:::void:do_addwc:int rd, int rs, int rt 317 { 318 uint32_t v1 = GPR[rs]; 319 uint32_t v2 = GPR[rt]; 320 uint64_t h0; 321 int32_t h1 = (int32_t) v1; 322 int32_t h2 = (int32_t) v2; 323 h0 = (int64_t)h1 + (int64_t)h2 324 + (int64_t)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK); 325 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000)) 326 DSPCR |= DSPCR_OUFLAG4; 327 GPR[rd] = EXTEND32 (h0); 328 } 329 330 :function:::void:do_bitrev:int rd, int rt 331 { 332 int i; 333 uint32_t v1 = GPR[rt]; 334 uint32_t h1 = 0; 335 for (i = 0; i < 16; i++) 336 { 337 if (v1 & (1 << i)) 338 h1 |= (1 << (15 - i)); 339 } 340 GPR[rd] = EXTEND32 (h1); 341 } 342 343 // op: 0 = EXTPV, 1 = EXTPDPV 344 :function:::void:do_extpv:int rt, int ac, int rs, int op 345 { 346 uint32_t size = GPR[rs] & 0x1f; 347 do_extp (SD_, rt, ac, size, op); 348 } 349 350 // op: 0 = EXTRV, 1 = EXTRV_R, 2 = EXTRV_RS 351 :function:::void:do_extrv:int rt, int ac, int rs, int op 352 { 353 uint32_t shift = GPR[rs] & 0x1f; 354 do_w_extr (SD_, rt, ac, shift, op); 355 } 356 357 :function:::void:do_extrv_s_h:int rt, int ac, int rs 358 { 359 uint32_t shift = GPR[rs] & 0x1f; 360 do_h_extr (SD_, rt, ac, shift); 361 } 362 363 :function:::void:do_insv:int rt, int rs 364 { 365 uint32_t v1 = GPR[rs]; 366 uint32_t v2 = GPR[rt]; 367 uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 368 uint32_t size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK; 369 uint32_t mask1, mask2, mask3, result; 370 if (size < 32) 371 mask1 = (1 << size) - 1; 372 else 373 mask1 = 0xffffffff; 374 mask2 = (1 << pos) - 1; 375 if (pos + size < 32) 376 mask3 = ~((1 << (pos + size)) - 1); 377 else 378 mask3 = 0; 379 result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2); 380 GPR[rt] = EXTEND32 (result); 381 } 382 383 // op: 0 = NORMAL, 1 = EXTEND16, 2 = EXTEND32 384 :function:::void:do_lxx:int rd, int base, int index, int op 385 { 386 if (op == 0) 387 GPR[rd] = do_load (SD_, AccessLength_BYTE, GPR[base], GPR[index]); 388 else if (op == 1) 389 GPR[rd] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[base], GPR[index])); 390 else if (op == 2) 391 GPR[rd] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[base], GPR[index])); 392 } 393 394 :function:::void:do_modsub:int rd, int rs, int rt 395 { 396 uint32_t result = 0; 397 uint32_t v1 = GPR[rs]; 398 uint32_t v2 = GPR[rt]; 399 uint32_t decr = v2 & 0xff; 400 uint32_t lastindex = (v2 & 0xffff00) >> 8; 401 if (v1 == 0) 402 result = lastindex; 403 else 404 result = v1 - decr; 405 GPR[rd] = EXTEND32 (result); 406 } 407 408 :function:::void:do_mthlip:int rs, int ac 409 { 410 uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 411 DSPHI(ac) = DSPLO(ac); 412 DSPLO(ac) = GPR[rs]; 413 if (pos >= 32) 414 Unpredictable (); 415 else 416 pos += 32; 417 DSPCR &= (~DSPCR_POS_SMASK); 418 DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT; 419 } 420 421 :function:::void:do_mulsaq_s_w_ph:int ac, int rs, int rt 422 { 423 int i; 424 uint32_t v1 = GPR[rs]; 425 uint32_t v2 = GPR[rt]; 426 int16_t h1, h2; 427 int32_t result; 428 uint32_t lo = DSPLO(ac); 429 uint32_t hi = DSPHI(ac); 430 int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo); 431 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 432 { 433 h1 = (int16_t)(v1 & 0xffff); 434 h2 = (int16_t)(v2 & 0xffff); 435 if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 436 { 437 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 438 result = (int32_t) 0x7fffffff; 439 } 440 else 441 result = ((int32_t)h1 * (int32_t)h2) << 1; 442 443 if (i == 0) 444 prod -= (int64_t) result; 445 else 446 prod += (int64_t) result; 447 } 448 DSPLO(ac) = EXTEND32 (prod); 449 DSPHI(ac) = EXTEND32 (prod >> 32); 450 } 451 452 :function:::void:do_ph_packrl:int rd, int rs, int rt 453 { 454 455 uint32_t v1 = GPR[rs]; 456 uint32_t v2 = GPR[rt]; 457 GPR[rd] = EXTEND32 ((v1 << 16) + (v2 >> 16)); 458 } 459 460 :function:::void:do_qb_pick:int rd, int rs, int rt 461 { 462 int i, j; 463 uint32_t v1 = GPR[rs]; 464 uint32_t v2 = GPR[rt]; 465 uint8_t h1, h2; 466 uint32_t result = 0; 467 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 468 { 469 h1 = (uint8_t)(v1 & 0xff); 470 h2 = (uint8_t)(v2 & 0xff); 471 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j))) 472 result |= (uint32_t)(h1 << i); 473 else 474 result |= (uint32_t)(h2 << i); 475 } 476 GPR[rd] = EXTEND32 (result); 477 } 478 479 :function:::void:do_ph_pick:int rd, int rs, int rt 480 { 481 int i, j; 482 uint32_t v1 = GPR[rs]; 483 uint32_t v2 = GPR[rt]; 484 uint16_t h1, h2; 485 uint32_t result = 0; 486 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16) 487 { 488 h1 = (uint16_t)(v1 & 0xffff); 489 h2 = (uint16_t)(v2 & 0xffff); 490 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j))) 491 result |= (uint32_t)(h1 << i); 492 else 493 result |= (uint32_t)(h2 << i); 494 } 495 GPR[rd] = EXTEND32 (result); 496 } 497 498 // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA 499 :function:::void:do_qb_ph_precequ:int rd, int rt, int op 500 { 501 uint32_t v1 = GPR[rt]; 502 if (op == 0) 503 GPR[rd] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7); 504 else if (op == 1) 505 GPR[rd] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7); 506 else if (op == 2) 507 GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9); 508 else if (op == 3) 509 GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1); 510 } 511 512 // op: 0 = QBR, 1 = QBRA, 2 = QBL, 3 = QBLA 513 :function:::void:do_qb_ph_preceu:int rd, int rt, int op 514 { 515 uint32_t v1 = GPR[rt]; 516 if (op == 0) 517 GPR[rd] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff); 518 else if (op == 1) 519 GPR[rd] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff)); 520 else if (op == 2) 521 GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16); 522 else if (op == 3) 523 GPR[rd] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8); 524 } 525 526 // op: 0 = .PHL, 1 = PHR 527 :function:::void:do_w_preceq:int rd, int rt, int op 528 { 529 uint32_t v1 = GPR[rt]; 530 if (op == 0) 531 GPR[rd] = EXTEND32 (v1 & 0xffff0000); 532 else if (op == 1) 533 GPR[rd] = EXTEND32 ((v1 & 0xffff) << 16); 534 } 535 536 :function:::void:do_w_ph_precrq:int rd, int rs, int rt 537 { 538 uint32_t v1 = GPR[rs]; 539 uint32_t v2 = GPR[rt]; 540 uint32_t tempu = (v1 & 0xffff0000) >> 16; 541 uint32_t tempv = (v2 & 0xffff0000) >> 16; 542 GPR[rd] = EXTEND32 ((tempu << 16) | tempv); 543 } 544 545 // sat: 0 = PRECRQ.QB.PH, 1 = PRECRQU_S.QB.PH 546 :function:::void:do_ph_qb_precrq:int rd, int rs, int rt, int sat 547 { 548 uint32_t v1 = GPR[rs]; 549 uint32_t v2 = GPR[rt]; 550 uint32_t tempu = 0, tempv = 0, tempw = 0, tempx = 0; 551 if (sat == 0) 552 { 553 tempu = (v1 & 0xff000000) >> 24; 554 tempv = (v1 & 0xff00) >> 8; 555 tempw = (v2 & 0xff000000) >> 24; 556 tempx = (v2 & 0xff00) >> 8; 557 } 558 else if (sat == 1) 559 { 560 if (v1 & 0x80000000) 561 { 562 DSPCR |= DSPCR_OUFLAG6; 563 tempu = 0; 564 } 565 else if (!(v1 & 0x80000000) && ((v1 >> 16) > (uint32_t)0x7f80)) 566 { 567 DSPCR |= DSPCR_OUFLAG6; 568 tempu = 0xff; 569 } 570 else 571 tempu = (v1 & 0x7f800000) >> 23; 572 if (v1 & 0x8000) 573 { 574 DSPCR |= DSPCR_OUFLAG6; 575 tempv = 0; 576 } 577 else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (uint32_t)0x7f80)) 578 { 579 DSPCR |= DSPCR_OUFLAG6; 580 tempv = 0xff; 581 } 582 else 583 tempv = (v1 & 0x7f80) >> 7; 584 if (v2 & 0x80000000) 585 { 586 DSPCR |= DSPCR_OUFLAG6; 587 tempw = 0; 588 } 589 else if (!(v2 & 0x80000000) && ((v2 >> 16) > (uint32_t)0x7f80)) 590 { 591 DSPCR |= DSPCR_OUFLAG6; 592 tempw = 0xff; 593 } 594 else 595 tempw = (v2 & 0x7f800000) >> 23; 596 if (v2 & 0x8000) 597 { 598 DSPCR |= DSPCR_OUFLAG6; 599 tempx = 0; 600 } 601 else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (uint32_t)0x7f80)) 602 { 603 DSPCR |= DSPCR_OUFLAG6; 604 tempx = 0xff; 605 } 606 else 607 tempx = (v2 & 0x7f80) >> 7; 608 } 609 GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx); 610 } 611 612 :function:::void:do_w_ph_rs_precrq:int rd, int rs, int rt 613 { 614 uint32_t v1 = GPR[rs]; 615 uint32_t v2 = GPR[rt]; 616 int32_t h1 = (int32_t)v1; 617 int32_t h2 = (int32_t)v2; 618 int64_t temp1 = (int64_t)h1 + (int64_t)0x8000; 619 int32_t temp2; 620 int64_t temp3 = (int64_t)h2 + (int64_t)0x8000; 621 int32_t temp4; 622 if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000)) 623 { 624 DSPCR |= DSPCR_OUFLAG6; 625 temp2 = 0x7fff; 626 } 627 else 628 temp2 = (int32_t)((temp1 & 0xffff0000) >> 16); 629 if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000)) 630 { 631 DSPCR |= DSPCR_OUFLAG6; 632 temp4 = 0x7fff; 633 } 634 else 635 temp4 = (int32_t)((temp3 & 0xffff0000) >> 16); 636 GPR[rd] = EXTEND32 ((temp2 << 16) | temp4); 637 } 638 639 :function:::void:do_qb_w_raddu:int rd, int rs 640 { 641 int i; 642 uint8_t h0; 643 uint32_t v1 = GPR[rs]; 644 uint32_t result = 0; 645 for (i = 0; i < 32; i += 8, v1 >>= 8) 646 { 647 h0 = (uint8_t)(v1 & 0xff); 648 result += (uint32_t)h0; 649 } 650 GPR[rd] = EXTEND32 (result); 651 } 652 653 :function:::void:do_rddsp:int rd, int mask 654 { 655 uint32_t result = 0; 656 if (mask & 0x1) 657 { 658 result &= (~DSPCR_POS_SMASK); 659 result |= (DSPCR & DSPCR_POS_SMASK); 660 } 661 if (mask & 0x2) 662 { 663 result &= (~DSPCR_SCOUNT_SMASK); 664 result |= (DSPCR & DSPCR_SCOUNT_SMASK); 665 } 666 if (mask & 0x4) 667 { 668 result &= (~DSPCR_CARRY_SMASK); 669 result |= (DSPCR & DSPCR_CARRY_SMASK); 670 } 671 if (mask & 0x8) 672 { 673 result &= (~DSPCR_OUFLAG_SMASK); 674 result |= (DSPCR & DSPCR_OUFLAG_SMASK); 675 } 676 if (mask & 0x10) 677 { 678 result &= (~DSPCR_CCOND_SMASK); 679 result |= (DSPCR & DSPCR_CCOND_SMASK); 680 } 681 if (mask & 0x20) 682 { 683 result &= (~DSPCR_EFI_SMASK); 684 result |= (DSPCR & DSPCR_EFI_SMASK); 685 } 686 GPR[rd] = EXTEND32 (result); 687 } 688 689 // op: 0 = REPL.QB, 1 = REPLV.QB, 2 = REPL.PH, 3 = REPLV.PH 690 :function:::void:do_repl:int rd, int p2, int op 691 { 692 if (op == 0) 693 GPR[rd] = EXTEND32 ((p2 << 24) | (p2 << 16) | (p2 << 8) | p2); 694 else if (op == 1) 695 { 696 uint32_t v1 = GPR[p2] & 0xff; 697 GPR[rd] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1); 698 } 699 else if (op == 2) 700 { 701 int32_t v1 = p2; 702 if (v1 & 0x200) 703 v1 |= 0xfffffc00; 704 GPR[rd] = EXTEND32 ((v1 << 16) | (v1 & 0xffff)); 705 } 706 else if (op == 3) 707 { 708 uint32_t v1 = GPR[p2]; 709 v1 = v1 & 0xffff; 710 GPR[rd] = EXTEND32 ((v1 << 16) | v1); 711 } 712 } 713 714 :function:::void:do_shilov:int ac, int rs 715 { 716 int32_t shift = GPR[rs] & 0x3f; 717 do_shilo (SD_, ac, shift); 718 } 719 720 // op: 0 = SHLLV, 1 = SHRAV 721 // sat: 0 = normal, 1 = saturate/rounding 722 :function:::void:do_ph_shl:int rd, int rt, int rs, int op, int sat 723 { 724 uint32_t shift = GPR[rs] & 0xf; 725 do_ph_shift (SD_, rd, rt, shift, op, sat); 726 } 727 728 // op: 0 = SHLLV, 1 = SHRLV 729 :function:::void:do_qb_shl:int rd, int rt, int rs, int op 730 { 731 uint32_t shift = GPR[rs] & 0x7; 732 do_qb_shift (SD_, rd, rt, shift, op); 733 } 734 735 :function:::void:do_w_s_shllv:int rd, int rt, int rs 736 { 737 uint32_t shift = GPR[rs] & 0x1f; 738 do_w_shll (SD_, rd, rt, shift); 739 } 740 741 :function:::void:do_ph_shrlv:int rd, int rt, int rs 742 { 743 uint32_t shift = GPR[rs] & 0xf; 744 do_ph_shrl (SD_, rd, rt, shift); 745 } 746 747 :function:::void:do_w_r_shrav:int rd, int rt, int rs 748 { 749 uint32_t shift = GPR[rs] & 0x1f; 750 do_w_shra (SD_, rd, rt, shift); 751 } 752 753 :function:::void:do_wrdsp:int rs, int mask 754 { 755 uint32_t v1 = GPR[rs]; 756 if (mask & 0x1) 757 { 758 DSPCR &= (~DSPCR_POS_SMASK); 759 DSPCR |= (v1 & DSPCR_POS_SMASK); 760 } 761 if (mask & 0x2) 762 { 763 DSPCR &= (~DSPCR_SCOUNT_SMASK); 764 DSPCR |= (v1 & DSPCR_SCOUNT_SMASK); 765 } 766 if (mask & 0x4) 767 { 768 DSPCR &= (~DSPCR_CARRY_SMASK); 769 DSPCR |= (v1 & DSPCR_CARRY_SMASK); 770 } 771 if (mask & 0x8) 772 { 773 DSPCR &= (~DSPCR_OUFLAG_SMASK); 774 DSPCR |= (v1 & DSPCR_OUFLAG_SMASK); 775 } 776 if (mask & 0x10) 777 { 778 DSPCR &= (~DSPCR_CCOND_SMASK); 779 DSPCR |= (v1 & DSPCR_CCOND_SMASK); 780 } 781 if (mask & 0x20) 782 { 783 DSPCR &= (~DSPCR_EFI_SMASK); 784 DSPCR |= (v1 & DSPCR_EFI_SMASK); 785 } 786 } 787 788 // round: 0 = no rounding, 1 = rounding 789 :function:::void:do_qb_shrav:int rd, int rt, int rs, int round 790 { 791 uint32_t shift = GPR[rs] & 0x7; 792 do_qb_shra (SD_, rd, rt, shift, round); 793 } 794 795 :function:::void:do_append:int rt, int rs, int sa 796 { 797 uint32_t v0 = GPR[rs]; 798 uint32_t v1 = GPR[rt]; 799 uint32_t result; 800 uint32_t mask = (1 << sa) - 1; 801 result = (v1 << sa) | (v0 & mask); 802 GPR[rt] = EXTEND32 (result); 803 } 804 805 :function:::void:do_balign:int rt, int rs, int bp 806 { 807 uint32_t v0 = GPR[rs]; 808 uint32_t v1 = GPR[rt]; 809 uint32_t result; 810 if (bp == 0) 811 result = v1; 812 else 813 result = (v1 << 8 * bp) | (v0 >> 8 * (4 - bp)); 814 GPR[rt] = EXTEND32 (result); 815 } 816 817 :function:::void:do_ph_w_mulsa:int ac, int rs, int rt 818 { 819 int i; 820 uint32_t v1 = GPR[rs]; 821 uint32_t v2 = GPR[rt]; 822 int16_t h1, h2; 823 int32_t result; 824 uint32_t lo = DSPLO(ac); 825 uint32_t hi = DSPHI(ac); 826 int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo); 827 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 828 { 829 h1 = (int16_t)(v1 & 0xffff); 830 h2 = (int16_t)(v2 & 0xffff); 831 result = (int32_t)h1 * (int32_t)h2; 832 833 if (i == 0) 834 prod -= (int64_t) result; 835 else 836 prod += (int64_t) result; 837 } 838 DSPLO(ac) = EXTEND32 (prod); 839 DSPHI(ac) = EXTEND32 (prod >> 32); 840 } 841 842 :function:::void:do_ph_qb_precr:int rd, int rs, int rt 843 { 844 uint32_t v1 = GPR[rs]; 845 uint32_t v2 = GPR[rt]; 846 uint32_t tempu = (v1 & 0xff0000) >> 16; 847 uint32_t tempv = (v1 & 0xff); 848 uint32_t tempw = (v2 & 0xff0000) >> 16; 849 uint32_t tempx = (v2 & 0xff); 850 GPR[rd] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx); 851 } 852 853 :function:::void:do_prepend:int rt, int rs, int sa 854 { 855 uint32_t v0 = GPR[rs]; 856 uint32_t v1 = GPR[rt]; 857 uint32_t result; 858 if (sa == 0) 859 result = v1; 860 else 861 result = (v0 << (32 - sa)) | (v1 >> sa); 862 GPR[rt] = EXTEND32 (result); 863 } 864 865 :function:::void:do_w_shra:int rd, int rt, int shift 866 { 867 uint32_t result = GPR[rt]; 868 int32_t h0 = (int32_t)result; 869 if (shift != 0 && (h0 & (1 << (shift-1)))) 870 h0 = (h0 >> shift) + 1; 871 else 872 h0 = h0 >> shift; 873 GPR[rd] = EXTEND32 (h0); 874 } 875 876 011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH 877 "addq.ph r<RD>, r<RS>, r<RT>" 878 *dsp: 879 { 880 do_ph_op (SD_, RD, RS, RT, 0, 0); 881 } 882 883 011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH 884 "addq_s.ph r<RD>, r<RS>, r<RT>" 885 *dsp: 886 { 887 do_ph_op (SD_, RD, RS, RT, 0, 1); 888 } 889 890 011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W 891 "addq_s.w r<RD>, r<RS>, r<RT>" 892 *dsp: 893 { 894 do_w_op (SD_, RD, RS, RT, 0); 895 } 896 897 011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB 898 "addu.qb r<RD>, r<RS>, r<RT>" 899 *dsp: 900 { 901 do_qb_op (SD_, RD, RS, RT, 0, 0); 902 } 903 904 011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB 905 "addu_s.qb r<RD>, r<RS>, r<RT>" 906 *dsp: 907 { 908 do_qb_op (SD_, RD, RS, RT, 0, 1); 909 } 910 911 011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH 912 "subq.ph r<RD>, r<RS>, r<RT>" 913 *dsp: 914 { 915 do_ph_op (SD_, RD, RS, RT, 1, 0); 916 } 917 918 011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH 919 "subq_s.ph r<RD>, r<RS>, r<RT>" 920 *dsp: 921 { 922 do_ph_op (SD_, RD, RS, RT, 1, 1); 923 } 924 925 011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W 926 "subq_s.w r<RD>, r<RS>, r<RT>" 927 *dsp: 928 { 929 do_w_op (SD_, RD, RS, RT, 1); 930 } 931 932 011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB 933 "subu.qb r<RD>, r<RS>, r<RT>" 934 *dsp: 935 { 936 do_qb_op (SD_, RD, RS, RT, 1, 0); 937 } 938 939 011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB 940 "subu_s.qb r<RD>, r<RS>, r<RT>" 941 *dsp: 942 { 943 do_qb_op (SD_, RD, RS, RT, 1, 1); 944 } 945 946 011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC 947 "addsc r<RD>, r<RS>, r<RT>" 948 *dsp: 949 { 950 do_addsc (SD_, RD, RS, RT); 951 } 952 953 011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC 954 "addwc r<RD>, r<RS>, r<RT>" 955 *dsp: 956 { 957 do_addwc (SD_, RD, RS, RT); 958 } 959 960 011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB 961 "modsub r<RD>, r<RS>, r<RT>" 962 *dsp: 963 { 964 do_modsub (SD_, RD, RS, RT); 965 } 966 967 011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB 968 "raddu.w.qb r<RD>, r<RS>" 969 *dsp: 970 { 971 do_qb_w_raddu (SD_, RD, RS); 972 } 973 974 011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH 975 "absq_s.ph r<RD>, r<RT>" 976 *dsp: 977 { 978 do_ph_s_absq (SD_, RD, RT); 979 } 980 981 011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W 982 "absq_s.w r<RD>, r<RT>" 983 *dsp: 984 { 985 do_w_s_absq (SD_, RD, RT); 986 } 987 988 011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH 989 "precrq.qb.ph r<RD>, r<RS>, r<RT>" 990 *dsp: 991 { 992 do_ph_qb_precrq (SD_, RD, RS, RT, 0); 993 } 994 995 011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W 996 "precrq.ph.w r<RD>, r<RS>, r<RT>" 997 *dsp: 998 { 999 do_w_ph_precrq (SD_, RD, RS, RT); 1000 } 1001 1002 011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W 1003 "precrq_rs.ph.w r<RD>, r<RS>, r<RT>" 1004 *dsp: 1005 { 1006 do_w_ph_rs_precrq (SD_, RD, RS, RT); 1007 } 1008 1009 011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH 1010 "precrqu_s.qb.ph r<RD>, r<RS>, r<RT>" 1011 *dsp: 1012 { 1013 do_ph_qb_precrq (SD_, RD, RS, RT, 1); 1014 } 1015 1016 011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL 1017 "preceq.w.phl r<RD>, r<RT>" 1018 *dsp: 1019 { 1020 do_w_preceq (SD_, RD, RT, 0); 1021 } 1022 1023 011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR 1024 "preceq.w.phr r<RD>, r<RT>" 1025 *dsp: 1026 { 1027 do_w_preceq (SD_, RD, RT, 1); 1028 } 1029 1030 011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL 1031 "precequ.ph.qbl r<RD>, r<RT>" 1032 *dsp: 1033 { 1034 do_qb_ph_precequ (SD_, RD, RT, 2); 1035 } 1036 1037 011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR 1038 "precequ.ph.qbr r<RD>, r<RT>" 1039 *dsp: 1040 { 1041 do_qb_ph_precequ (SD_, RD, RT, 0); 1042 } 1043 1044 011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA 1045 "precequ.ph.qbla r<RD>, r<RT>" 1046 *dsp: 1047 { 1048 do_qb_ph_precequ (SD_, RD, RT, 3); 1049 } 1050 1051 011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA 1052 "precequ.ph.qbra r<RD>, r<RT>" 1053 *dsp: 1054 { 1055 do_qb_ph_precequ (SD_, RD, RT, 1); 1056 } 1057 1058 011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL 1059 "preceu.ph.qbl r<RD>, r<RT>" 1060 *dsp: 1061 { 1062 do_qb_ph_preceu (SD_, RD, RT, 2); 1063 } 1064 1065 011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR 1066 "preceu.ph.qbr r<RD>, r<RT>" 1067 *dsp: 1068 { 1069 do_qb_ph_preceu (SD_, RD, RT, 0); 1070 } 1071 1072 011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA 1073 "preceu.ph.qbla r<RD>, r<RT>" 1074 *dsp: 1075 { 1076 do_qb_ph_preceu (SD_, RD, RT, 3); 1077 } 1078 1079 011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA 1080 "preceu.ph.qbra r<RD>, r<RT>" 1081 *dsp: 1082 { 1083 do_qb_ph_preceu (SD_, RD, RT, 1); 1084 } 1085 1086 011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB 1087 "shll.qb r<RD>, r<RT>, <SHIFT3>" 1088 *dsp: 1089 { 1090 do_qb_shift (SD_, RD, RT, SHIFT3, 0); 1091 } 1092 1093 011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB 1094 "shllv.qb r<RD>, r<RT>, r<RS>" 1095 *dsp: 1096 { 1097 do_qb_shl (SD_, RD, RT, RS, 0); 1098 } 1099 1100 011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH 1101 "shll.ph r<RD>, r<RT>, <SHIFT4>" 1102 *dsp: 1103 { 1104 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0); 1105 } 1106 1107 011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH 1108 "shllv.ph r<RD>, r<RT>, r<RS>" 1109 *dsp: 1110 { 1111 do_ph_shl (SD_, RD, RT, RS, 0, 0); 1112 } 1113 1114 011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH 1115 "shll_s.ph r<RD>, r<RT>, <SHIFT4>" 1116 *dsp: 1117 { 1118 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1); 1119 } 1120 1121 011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH 1122 "shllv_s.ph r<RD>, r<RT>, r<RS>" 1123 *dsp: 1124 { 1125 do_ph_shl (SD_, RD, RT, RS, 0, 1); 1126 } 1127 1128 011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W 1129 "shll_s.w r<RD>, r<RT>, <SHIFT5>" 1130 *dsp: 1131 { 1132 do_w_shll (SD_, RD, RT, SHIFT5); 1133 } 1134 1135 011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W 1136 "shllv_s.w r<RD>, r<RT>, r<RS>" 1137 *dsp: 1138 { 1139 do_w_s_shllv (SD_, RD, RT, RS); 1140 } 1141 1142 011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB 1143 "shrl.qb r<RD>, r<RT>, <SHIFT3>" 1144 *dsp: 1145 { 1146 do_qb_shift (SD_, RD, RT, SHIFT3, 1); 1147 } 1148 1149 011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB 1150 "shrlv.qb r<RD>, r<RT>, r<RS>" 1151 *dsp: 1152 { 1153 do_qb_shl (SD_, RD, RT, RS, 1); 1154 } 1155 1156 011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH 1157 "shra.ph r<RD>, r<RT>, <SHIFT4>" 1158 *dsp: 1159 { 1160 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0); 1161 } 1162 1163 011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH 1164 "shrav.ph r<RD>, r<RT>, r<RS>" 1165 *dsp: 1166 { 1167 do_ph_shl (SD_, RD, RT, RS, 1, 0); 1168 } 1169 1170 011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH 1171 "shra_r.ph r<RD>, r<RT>, <SHIFT4>" 1172 *dsp: 1173 { 1174 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1); 1175 } 1176 1177 011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH 1178 "shrav_r.ph r<RD>, r<RT>, r<RS>" 1179 *dsp: 1180 { 1181 do_ph_shl (SD_, RD, RT, RS, 1, 1); 1182 } 1183 1184 011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W 1185 "shra_r.w r<RD>, r<RT>, <SHIFT5>" 1186 *dsp: 1187 { 1188 do_w_shra (SD_, RD, RT, SHIFT5); 1189 } 1190 1191 011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W 1192 "shrav_r.w r<RD>, r<RT>, r<RS>" 1193 *dsp: 1194 { 1195 do_w_r_shrav (SD_, RD, RT, RS); 1196 } 1197 1198 // loc: 0 = qhl, 1 = qhr 1199 :function:::void:do_qb_muleu:int rd, int rs, int rt, int loc 1200 { 1201 int i; 1202 uint32_t result = 0; 1203 uint32_t v1 = GPR[rs]; 1204 uint32_t v2 = GPR[rt]; 1205 uint16_t h1, h2; 1206 uint32_t prod; 1207 if (loc == 0) 1208 v1 >>= 16; 1209 for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16) 1210 { 1211 h1 = (uint16_t)(v1 & 0xff); 1212 h2 = (uint16_t)(v2 & 0xffff); 1213 prod = (uint32_t)h1 * (uint32_t)h2; 1214 if (prod > 0xffff) 1215 { 1216 DSPCR |= DSPCR_OUFLAG5; 1217 prod = 0xffff; 1218 } 1219 result |= ((uint32_t)prod << i); 1220 } 1221 GPR[rd] = EXTEND32 (result); 1222 } 1223 1224 011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL 1225 "muleu_s.ph.qbl r<RD>, r<RS>, r<RT>" 1226 *dsp: 1227 { 1228 do_qb_muleu (SD_, RD, RS, RT, 0); 1229 } 1230 1231 011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR 1232 "muleu_s.ph.qbr r<RD>, r<RS>, r<RT>" 1233 *dsp: 1234 { 1235 do_qb_muleu (SD_, RD, RS, RT, 1); 1236 } 1237 1238 // round: 0 = no rounding, 1 = rounding 1239 :function:::void:do_ph_mulq:int rd, int rs, int rt, int round 1240 { 1241 int i; 1242 uint32_t result = 0; 1243 uint32_t v1 = GPR[rs]; 1244 uint32_t v2 = GPR[rt]; 1245 int16_t h1, h2; 1246 int32_t prod; 1247 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 1248 { 1249 h1 = (int16_t)(v1 & 0xffff); 1250 h2 = (int16_t)(v2 & 0xffff); 1251 if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 1252 { 1253 DSPCR |= DSPCR_OUFLAG5; 1254 prod = 0x7fffffff; 1255 } 1256 else 1257 { 1258 prod = ((int32_t)h1 * (int32_t)h2) << 1; 1259 if (round == 1) 1260 prod += (int32_t)0x8000; 1261 } 1262 result |= (((uint32_t)prod >> 16) << i); 1263 } 1264 GPR[rd] = EXTEND32 (result); 1265 } 1266 1267 011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH 1268 "mulq_rs.ph r<RD>, r<RS>, r<RT>" 1269 *dsp: 1270 { 1271 do_ph_mulq (SD_, RD, RS, RT, 1); 1272 } 1273 1274 // loc: 0 = phl, 1 = phr 1275 :function:::void:do_ph_muleq:int rd, int rs, int rt, int loc 1276 { 1277 uint32_t v1 = GPR[rs]; 1278 uint32_t v2 = GPR[rt]; 1279 int16_t h1, h2; 1280 int32_t prod; 1281 if (loc == 0) 1282 { 1283 h1 = (int16_t)(v1 >> 16); 1284 h2 = (int16_t)(v2 >> 16); 1285 } 1286 else 1287 { 1288 h1 = (int16_t)(v1 & 0xffff); 1289 h2 = (int16_t)(v2 & 0xffff); 1290 } 1291 if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 1292 { 1293 DSPCR |= DSPCR_OUFLAG5; 1294 prod = 0x7fffffff; 1295 } 1296 else 1297 prod = ((int32_t)h1 * (int32_t)h2) << 1; 1298 GPR[rd] = EXTEND32 (prod); 1299 } 1300 1301 011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL 1302 "muleq_s.w.phl r<RD>, r<RS>, r<RT>" 1303 *dsp: 1304 { 1305 do_ph_muleq (SD_, RD, RS, RT, 0); 1306 } 1307 1308 011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR 1309 "muleq_s.w.phr r<RD>, r<RS>, r<RT>" 1310 *dsp: 1311 { 1312 do_ph_muleq (SD_, RD, RS, RT, 1); 1313 } 1314 1315 // op: 0 = DPAU 1 = DPSU 1316 // loc: 0 = qbl, 1 = qbr 1317 :function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc 1318 { 1319 int i; 1320 uint32_t v1 = GPR[rs]; 1321 uint32_t v2 = GPR[rt]; 1322 uint8_t h1, h2; 1323 uint32_t lo = DSPLO(ac); 1324 uint32_t hi = DSPHI(ac); 1325 uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1326 if (loc == 0) 1327 { 1328 v1 >>= 16; 1329 v2 >>= 16; 1330 } 1331 for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8) 1332 { 1333 h1 = (uint8_t)(v1 & 0xff); 1334 h2 = (uint8_t)(v2 & 0xff); 1335 if (op == 0) // DPAU 1336 prod += (uint64_t)h1 * (uint64_t)h2; 1337 else // DPSU 1338 prod -= (uint64_t)h1 * (uint64_t)h2; 1339 } 1340 DSPLO(ac) = EXTEND32 (prod); 1341 DSPHI(ac) = EXTEND32 (prod >> 32); 1342 } 1343 1344 011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL 1345 "dpau.h.qbl ac<AC>, r<RS>, r<RT>" 1346 *dsp: 1347 { 1348 do_qb_dot_product (SD_, AC, RS, RT, 0, 0); 1349 } 1350 1351 011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR 1352 "dpau.h.qbr ac<AC>, r<RS>, r<RT>" 1353 *dsp: 1354 { 1355 do_qb_dot_product (SD_, AC, RS, RT, 0, 1); 1356 } 1357 1358 011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL 1359 "dpsu.h.qbl ac<AC>, r<RS>, r<RT>" 1360 *dsp: 1361 { 1362 do_qb_dot_product (SD_, AC, RS, RT, 1, 0); 1363 } 1364 1365 011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR 1366 "dpsu.h.qbr ac<AC>, r<RS>, r<RT>" 1367 *dsp: 1368 { 1369 do_qb_dot_product (SD_, AC, RS, RT, 1, 1); 1370 } 1371 1372 // op: 0 = DPAQ 1 = DPSQ 1373 :function:::void:do_ph_dot_product:int ac, int rs, int rt, int op 1374 { 1375 int i; 1376 uint32_t v1 = GPR[rs]; 1377 uint32_t v2 = GPR[rt]; 1378 int16_t h1, h2; 1379 int32_t result; 1380 uint32_t lo = DSPLO(ac); 1381 uint32_t hi = DSPHI(ac); 1382 int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo); 1383 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 1384 { 1385 h1 = (int16_t)(v1 & 0xffff); 1386 h2 = (int16_t)(v2 & 0xffff); 1387 if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 1388 { 1389 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1390 result = (int32_t)0x7fffffff; 1391 } 1392 else 1393 result = ((int32_t)h1 * (int32_t)h2) << 1; 1394 1395 if (op == 0) // DPAQ 1396 prod += (int64_t)result; 1397 else // DPSQ 1398 prod -= (int64_t)result; 1399 } 1400 DSPLO(ac) = EXTEND32 (prod); 1401 DSPHI(ac) = EXTEND32 (prod >> 32); 1402 } 1403 1404 011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH 1405 "dpaq_s.w.ph ac<AC>, r<RS>, r<RT>" 1406 *dsp: 1407 { 1408 do_ph_dot_product (SD_, AC, RS, RT, 0); 1409 } 1410 1411 011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH 1412 "dpsq_s.w.ph ac<AC>, r<RS>, r<RT>" 1413 *dsp: 1414 { 1415 do_ph_dot_product (SD_, AC, RS, RT, 1); 1416 } 1417 1418 011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH 1419 "mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>" 1420 *dsp: 1421 { 1422 do_mulsaq_s_w_ph (SD_, AC, RS, RT); 1423 } 1424 1425 // op: 0 = DPAQ 1 = DPSQ 1426 :function:::void:do_w_dot_product:int ac, int rs, int rt, int op 1427 { 1428 uint32_t v1 = GPR[rs]; 1429 uint32_t v2 = GPR[rt]; 1430 int32_t h1, h2; 1431 int64_t result; 1432 uint32_t lo = DSPLO(ac); 1433 uint32_t hi = DSPHI(ac); 1434 uint32_t resultlo; 1435 uint32_t resulthi; 1436 uint32_t carry; 1437 uint64_t temp1; 1438 int64_t temp2; 1439 h1 = (int32_t) v1; 1440 h2 = (int32_t) v2; 1441 if (h1 == 0x80000000 && h2 == 0x80000000) 1442 { 1443 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1444 result = (int64_t) 0x7fffffffffffffffLL; 1445 } 1446 else 1447 result = ((int64_t)h1 * (int64_t)h2) << 1; 1448 resultlo = (uint32_t)(result); 1449 resulthi = (uint32_t)(result >> 32); 1450 if (op ==0) // DPAQ 1451 { 1452 temp1 = (uint64_t)lo + (uint64_t)resultlo; 1453 carry = (uint32_t)((temp1 >> 32) & 1); 1454 temp2 = (int64_t)((int32_t)hi) + (int64_t)((int32_t)resulthi) + 1455 (int64_t)((int32_t)carry); 1456 } 1457 else // DPSQ 1458 { 1459 temp1 = (uint64_t)lo - (uint64_t)resultlo; 1460 carry = (uint32_t)((temp1 >> 32) & 1); 1461 temp2 = (int64_t)((int32_t)hi) - (int64_t)((int32_t)resulthi) - 1462 (int64_t)((int32_t)carry); 1463 } 1464 if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL)) 1465 { 1466 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1467 if (temp2 & 0x100000000LL) 1468 { 1469 DSPLO(ac) = EXTEND32 (0x00000000); 1470 DSPHI(ac) = EXTEND32 (0x80000000); 1471 } 1472 else 1473 { 1474 DSPLO(ac) = EXTEND32 (0xffffffff); 1475 DSPHI(ac) = EXTEND32 (0x7fffffff); 1476 } 1477 } 1478 else 1479 { 1480 DSPLO(ac) = EXTEND32 (temp1); 1481 DSPHI(ac) = EXTEND32 (temp2); 1482 } 1483 } 1484 1485 011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W 1486 "dpaq_sa.l.w ac<AC>, r<RS>, r<RT>" 1487 *dsp: 1488 { 1489 do_w_dot_product (SD_, AC, RS, RT, 0); 1490 } 1491 1492 011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W 1493 "dpsq_sa.l.w ac<AC>, r<RS>, r<RT>" 1494 *dsp: 1495 { 1496 do_w_dot_product (SD_, AC, RS, RT, 1); 1497 } 1498 1499 // op: 0 = MAQ_S 1 = MAQ_SA 1500 // loc: 0 = phl, 1 = phr 1501 :function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc 1502 { 1503 int i; 1504 uint32_t v1 = GPR[rs]; 1505 uint32_t v2 = GPR[rt]; 1506 int16_t h1, h2; 1507 int32_t result; 1508 uint32_t lo = DSPLO(ac); 1509 uint32_t hi = DSPHI(ac); 1510 int64_t prod = (int64_t)((((uint64_t)hi) << 32) + (uint64_t)lo); 1511 if (loc == 0) 1512 { 1513 h1 = (int16_t)(v1 >> 16); 1514 h2 = (int16_t)(v2 >> 16); 1515 } 1516 else 1517 { 1518 h1 = (int16_t)(v1 & 0xffff); 1519 h2 = (int16_t)(v2 & 0xffff); 1520 } 1521 if (h1 == (int16_t)0x8000 && h2 == (int16_t)0x8000) 1522 { 1523 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1524 result = (int32_t)0x7fffffff; 1525 } 1526 else 1527 result = ((int32_t)h1 * (int32_t)h2) << 1; 1528 prod += (int64_t)result; 1529 if (op == 1) // MAQ_SA 1530 { 1531 if (prod & 0x8000000000000000LL) 1532 { 1533 for (i = 62; i >= 31; i--) 1534 { 1535 if (!(prod & ((int64_t)1 << i))) 1536 { 1537 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1538 prod = 0xffffffff80000000LL; 1539 break; 1540 } 1541 } 1542 } 1543 else 1544 { 1545 for (i = 62; i >= 31; i--) 1546 { 1547 if (prod & ((int64_t)1 << i)) 1548 { 1549 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1550 prod = 0x7fffffff; 1551 break; 1552 } 1553 } 1554 } 1555 } 1556 DSPLO(ac) = EXTEND32 (prod); 1557 DSPHI(ac) = EXTEND32 (prod >> 32); 1558 } 1559 1560 011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL 1561 "maq_s.w.phl ac<AC>, r<RS>, r<RT>" 1562 *dsp: 1563 { 1564 do_ph_maq (SD_, AC, RS, RT, 0, 0); 1565 } 1566 1567 011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR 1568 "maq_s.w.phr ac<AC>, r<RS>, r<RT>" 1569 *dsp: 1570 { 1571 do_ph_maq (SD_, AC, RS, RT, 0, 1); 1572 } 1573 1574 011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL 1575 "maq_sa.w.phl ac<AC>, r<RS>, r<RT>" 1576 *dsp: 1577 { 1578 do_ph_maq (SD_, AC, RS, RT, 1, 0); 1579 } 1580 1581 011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR 1582 "maq_sa.w.phr ac<AC>, r<RS>, r<RT>" 1583 *dsp: 1584 { 1585 do_ph_maq (SD_, AC, RS, RT, 1, 1); 1586 } 1587 1588 011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV 1589 "bitrev r<RD>, r<RT>" 1590 *dsp: 1591 { 1592 do_bitrev (SD_, RD, RT); 1593 } 1594 1595 011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV 1596 "insv r<RT>, r<RS>" 1597 *dsp: 1598 { 1599 do_insv (SD_, RT, RS); 1600 } 1601 1602 011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB 1603 "repl.qb r<RD>, <IMM8>" 1604 *dsp: 1605 { 1606 do_repl (SD_, RD, IMM8, 0); 1607 } 1608 1609 011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB 1610 "replv.qb r<RD>, r<RT>" 1611 *dsp: 1612 { 1613 do_repl (SD_, RD, RT, 1); 1614 } 1615 1616 011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH 1617 "repl.ph r<RD>, <IMM10>" 1618 *dsp: 1619 { 1620 do_repl (SD_, RD, IMM10, 2); 1621 } 1622 1623 011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH 1624 "replv.ph r<RD>, r<RT>" 1625 *dsp: 1626 { 1627 do_repl (SD_, RD, RT, 3); 1628 } 1629 1630 // op: 0 = EQ, 1 = LT, 2 = LE 1631 :function:::void:do_qb_cmpu:int rs, int rt, int op 1632 { 1633 int i, j; 1634 uint32_t v1 = GPR[rs]; 1635 uint32_t v2 = GPR[rt]; 1636 uint8_t h1, h2; 1637 uint32_t mask; 1638 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 1639 { 1640 h1 = (uint8_t)(v1 & 0xff); 1641 h2 = (uint8_t)(v2 & 0xff); 1642 mask = ~(1 << (DSPCR_CCOND_SHIFT + j)); 1643 DSPCR &= mask; 1644 if (op == 0) // EQ 1645 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j)); 1646 else if (op == 1) // LT 1647 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j)); 1648 else // LE 1649 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j)); 1650 } 1651 } 1652 1653 011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB 1654 "cmpu.eq.qb r<RS>, r<RT>" 1655 *dsp: 1656 { 1657 do_qb_cmpu (SD_, RS, RT, 0); 1658 } 1659 1660 011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB 1661 "cmpu.lt.qb r<RS>, r<RT>" 1662 *dsp: 1663 { 1664 do_qb_cmpu (SD_, RS, RT, 1); 1665 } 1666 1667 011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB 1668 "cmpu.le.qb r<RS>, r<RT>" 1669 *dsp: 1670 { 1671 do_qb_cmpu (SD_, RS, RT, 2); 1672 } 1673 1674 // op: 0 = EQ, 1 = LT, 2 = LE 1675 :function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op 1676 { 1677 int i, j; 1678 uint32_t v1 = GPR[rs]; 1679 uint32_t v2 = GPR[rt]; 1680 uint8_t h1, h2; 1681 uint32_t result = 0; 1682 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 1683 { 1684 h1 = (uint8_t)(v1 & 0xff); 1685 h2 = (uint8_t)(v2 & 0xff); 1686 if (op == 0) // EQ 1687 result |= ((h1 == h2) << j); 1688 else if (op == 1) // LT 1689 result |= ((h1 < h2) << j); 1690 else // LE 1691 result |= ((h1 <= h2) << j); 1692 } 1693 GPR[rd] = EXTEND32 (result); 1694 } 1695 1696 011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB 1697 "cmpgu.eq.qb r<RD>, r<RS>, r<RT>" 1698 *dsp: 1699 { 1700 do_qb_cmpgu (SD_, RD, RS, RT, 0); 1701 } 1702 1703 011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB 1704 "cmpgu.lt.qb r<RD>, r<RS>, r<RT>" 1705 *dsp: 1706 { 1707 do_qb_cmpgu (SD_, RD, RS, RT, 1); 1708 } 1709 1710 011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB 1711 "cmpgu.le.qb r<RD>, r<RS>, r<RT>" 1712 *dsp: 1713 { 1714 do_qb_cmpgu (SD_, RD, RS, RT, 2); 1715 } 1716 1717 // op: 0 = EQ, 1 = LT, 2 = LE 1718 :function:::void:do_ph_cmpu:int rs, int rt, int op 1719 { 1720 int i, j; 1721 uint32_t v1 = GPR[rs]; 1722 uint32_t v2 = GPR[rt]; 1723 int16_t h1, h2; 1724 uint32_t mask; 1725 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16) 1726 { 1727 h1 = (int16_t)(v1 & 0xffff); 1728 h2 = (int16_t)(v2 & 0xffff); 1729 mask = ~(1 << (DSPCR_CCOND_SHIFT + j)); 1730 DSPCR &= mask; 1731 if (op == 0) // EQ 1732 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j)); 1733 else if (op == 1) // LT 1734 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j)); 1735 else // LE 1736 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j)); 1737 } 1738 } 1739 1740 011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH 1741 "cmp.eq.ph r<RS>, r<RT>" 1742 *dsp: 1743 { 1744 do_ph_cmpu (SD_, RS, RT, 0); 1745 } 1746 1747 011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH 1748 "cmp.lt.ph r<RS>, r<RT>" 1749 *dsp: 1750 { 1751 do_ph_cmpu (SD_, RS, RT, 1); 1752 } 1753 1754 011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH 1755 "cmp.le.ph r<RS>, r<RT>" 1756 *dsp: 1757 { 1758 do_ph_cmpu (SD_, RS, RT, 2); 1759 } 1760 1761 011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB 1762 "pick.qb r<RD>, r<RS>, r<RT>" 1763 *dsp: 1764 { 1765 do_qb_pick (SD_, RD, RS, RT); 1766 } 1767 1768 011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH 1769 "pick.ph r<RD>, r<RS>, r<RT>" 1770 *dsp: 1771 { 1772 do_ph_pick (SD_, RD, RS, RT); 1773 } 1774 1775 011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH 1776 "packrl.ph r<RD>, r<RS>, r<RT>" 1777 *dsp: 1778 { 1779 do_ph_packrl (SD_, RD, RS, RT); 1780 } 1781 1782 // op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS 1783 :function:::void:do_w_extr:int rt, int ac, int shift, int op 1784 { 1785 int i; 1786 uint32_t lo = DSPLO(ac); 1787 uint32_t hi = DSPHI(ac); 1788 uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1789 int64_t result = (int64_t)prod; 1790 int setcond = 0; 1791 if (!(prod & 0x8000000000000000LL)) 1792 { 1793 for (i = 62; i >= (shift + 31); i--) 1794 { 1795 if (prod & ((uint64_t)1 << i)) 1796 { 1797 DSPCR |= DSPCR_OUFLAG7; 1798 setcond = 1; 1799 break; 1800 } 1801 } 1802 if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL) 1803 { 1804 DSPCR |= DSPCR_OUFLAG7; 1805 setcond = 1; 1806 } 1807 } 1808 else 1809 { 1810 for (i = 62; i >= (shift + 31); i--) 1811 { 1812 if (!(prod & ((uint64_t)1 << i))) 1813 { 1814 DSPCR |= DSPCR_OUFLAG7; 1815 setcond = 2; 1816 break; 1817 } 1818 } 1819 } 1820 if (op == 0) // EXTR 1821 result = result >> shift; 1822 else if (op == 1) // EXTR_R 1823 { 1824 if (shift != 0) 1825 result = ((result >> (shift - 1)) + 1) >> 1; 1826 else 1827 result = result >> shift; 1828 } 1829 else // EXTR_RS 1830 { 1831 if (setcond == 1) 1832 result = 0x7fffffff; 1833 else if (setcond == 2) 1834 result = 0x80000000; 1835 else 1836 { 1837 if (shift != 0) 1838 result = ((result >> (shift - 1)) + 1) >> 1; 1839 else 1840 result = result >> shift; 1841 } 1842 } 1843 GPR[rt] = EXTEND32 (result); 1844 } 1845 1846 011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W 1847 "extr.w r<RT>, ac<AC>, <SHIFT>" 1848 *dsp: 1849 { 1850 do_w_extr (SD_, RT, AC, SHIFT, 0); 1851 } 1852 1853 011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W 1854 "extrv.w r<RT>, ac<AC>, r<RS>" 1855 *dsp: 1856 { 1857 do_extrv (SD_, RT, AC, RS, 0); 1858 } 1859 1860 011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W 1861 "extr_r.w r<RT>, ac<AC>, <SHIFT>" 1862 *dsp: 1863 { 1864 do_w_extr (SD_, RT, AC, SHIFT, 1); 1865 } 1866 1867 011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W 1868 "extrv_r.w r<RT>, ac<AC>, r<RS>" 1869 *dsp: 1870 { 1871 do_extrv (SD_, RT, AC, RS, 1); 1872 } 1873 1874 011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W 1875 "extr_rs.w r<RT>, ac<AC>, <SHIFT>" 1876 *dsp: 1877 { 1878 do_w_extr (SD_, RT, AC, SHIFT, 2); 1879 } 1880 1881 011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W 1882 "extrv_rs.w r<RT>, ac<AC>, r<RS>" 1883 *dsp: 1884 { 1885 do_extrv (SD_, RT, AC, RS, 2); 1886 } 1887 1888 :function:::void:do_h_extr:int rt, int ac, int shift 1889 { 1890 uint32_t lo = DSPLO(ac); 1891 uint32_t hi = DSPHI(ac); 1892 uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1893 int64_t result = (int64_t)prod; 1894 int64_t value = 0xffffffffffff8000LL; 1895 result >>= shift; 1896 if (result > 0x7fff) 1897 { 1898 result = 0x7fff; 1899 DSPCR |= DSPCR_OUFLAG7; 1900 } 1901 else if (result < value) 1902 { 1903 result = value; 1904 DSPCR |= DSPCR_OUFLAG7; 1905 } 1906 GPR[rt] = EXTEND32 (result); 1907 } 1908 1909 011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H 1910 "extr_s.h r<RT>, ac<AC>, <SHIFT>" 1911 *dsp: 1912 { 1913 do_h_extr (SD_, RT, AC, SHIFT); 1914 } 1915 1916 011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H 1917 "extrv_s.h r<RT>, ac<AC>, r<RS>" 1918 *dsp: 1919 { 1920 do_extrv_s_h (SD_, RT, AC, RS); 1921 } 1922 1923 // op: 0 = EXTP, 1 = EXTPDP 1924 :function:::void:do_extp:int rt, int ac, int size, int op 1925 { 1926 int32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 1927 uint32_t lo = DSPLO(ac); 1928 uint32_t hi = DSPHI(ac); 1929 uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1930 uint64_t result = 0; 1931 if (pos - (size + 1) >= -1) 1932 { 1933 prod >>= (pos - size); 1934 result = prod & (((uint64_t)1 << (size + 1)) - 1); 1935 DSPCR &= (~DSPCR_EFI_SMASK); 1936 if (op == 1) // EXTPDP 1937 { 1938 if (pos - (size + 1) >= 0) 1939 { 1940 DSPCR &= (~DSPCR_POS_SMASK); 1941 DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT; 1942 } 1943 else if (pos - (size + 1) == -1) 1944 { 1945 DSPCR |= DSPCR_POS_SMASK; 1946 } 1947 } 1948 } 1949 else 1950 { 1951 DSPCR |= DSPCR_EFI; 1952 Unpredictable (); 1953 } 1954 GPR[rt] = EXTEND32 (result); 1955 } 1956 1957 011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP 1958 "extp r<RT>, ac<AC>, <SIZE>" 1959 *dsp: 1960 { 1961 do_extp (SD_, RT, AC, SIZE, 0); 1962 } 1963 1964 011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV 1965 "extpv r<RT>, ac<AC>, r<RS>" 1966 *dsp: 1967 { 1968 do_extpv (SD_, RT, AC, RS, 0); 1969 } 1970 1971 011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP 1972 "extpdp r<RT>, ac<AC>, <SIZE>" 1973 *dsp: 1974 { 1975 do_extp (SD_, RT, AC, SIZE, 1); 1976 } 1977 1978 011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV 1979 "extpdpv r<RT>, ac<AC>, r<RS>" 1980 *dsp: 1981 { 1982 do_extpv (SD_, RT, AC, RS, 1); 1983 } 1984 1985 :function:::void:do_shilo:int ac, int shift 1986 { 1987 uint32_t lo = DSPLO(ac); 1988 uint32_t hi = DSPHI(ac); 1989 uint64_t prod = (((uint64_t)hi) << 32) + (uint64_t)lo; 1990 if (shift > 31) 1991 shift = shift - 64; 1992 if (shift >= 0) 1993 prod >>= shift; 1994 else 1995 prod <<= (-shift); 1996 DSPLO(ac) = EXTEND32 (prod); 1997 DSPHI(ac) = EXTEND32 (prod >> 32); 1998 } 1999 2000 011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO 2001 "shilo ac<AC>, <SHIFT6>" 2002 *dsp: 2003 { 2004 do_shilo (SD_, AC, SHIFT6); 2005 } 2006 2007 011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV 2008 "shilov ac<AC>, r<RS>" 2009 *dsp: 2010 { 2011 do_shilov (SD_, AC, RS); 2012 } 2013 2014 011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP 2015 "mthlip r<RS>, ac<AC>" 2016 *dsp: 2017 { 2018 do_mthlip (SD_, RS, AC); 2019 } 2020 2021 011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP 2022 "wrdsp r<RS>":MASK10 == 1111111111 2023 "wrdsp r<RS>, <MASK10>" 2024 *dsp: 2025 { 2026 do_wrdsp (SD_, RS, MASK10); 2027 } 2028 2029 011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP 2030 "rddsp r<RD>":MASK10 == 1111111111 2031 "rddsp r<RD>, <MASK10>" 2032 *dsp: 2033 { 2034 do_rddsp (SD_, RD, MASK10); 2035 } 2036 2037 011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX 2038 "lbux r<RD>, r<INDEX>(r<BASE>)" 2039 *dsp: 2040 { 2041 do_lxx (SD_, RD, BASE, INDEX, 0); 2042 } 2043 2044 011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX 2045 "lhx r<RD>, r<INDEX>(r<BASE>)" 2046 *dsp: 2047 { 2048 do_lxx (SD_, RD, BASE, INDEX, 1); 2049 } 2050 2051 011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX 2052 "lwx r<RD>, r<INDEX>(r<BASE>)" 2053 *dsp: 2054 { 2055 do_lxx (SD_, RD, BASE, INDEX, 2); 2056 } 2057 2058 000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32 2059 "bposge32 <OFFSET>" 2060 *dsp: 2061 { 2062 uint32_t pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 2063 address_word offset = EXTEND16 (OFFSET) << 2; 2064 if (pos >= 32) 2065 { 2066 DELAY_SLOT (NIA + offset); 2067 } 2068 } 2069