1// -*- C -*- 2 3// Simulator definition for the MIPS DSP ASE. 4// Copyright (C) 2005-2024 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 876011111,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 883011111,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 890011111,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 897011111,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 904011111,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 911011111,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 918011111,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 925011111,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 932011111,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 939011111,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 946011111,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 953011111,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 960011111,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 967011111,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 974011111,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 981011111,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 988011111,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 995011111,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 1002011111,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 1009011111,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 1016011111,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 1023011111,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 1030011111,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 1037011111,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 1044011111,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 1051011111,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 1058011111,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 1065011111,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 1072011111,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 1079011111,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 1086011111,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 1093011111,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 1100011111,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 1107011111,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 1114011111,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 1121011111,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 1128011111,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 1135011111,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 1142011111,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 1149011111,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 1156011111,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 1163011111,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 1170011111,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 1177011111,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 1184011111,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 1191011111,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 1224011111,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 1231011111,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 1267011111,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 1301011111,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 1308011111,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 1344011111,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 1351011111,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 1358011111,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 1365011111,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 1404011111,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 1411011111,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 1418011111,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 1485011111,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 1492011111,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 1560011111,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 1567011111,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 1574011111,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 1581011111,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 1588011111,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 1595011111,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 1602011111,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 1609011111,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 1616011111,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 1623011111,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 1653011111,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 1660011111,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 1667011111,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 1696011111,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 1703011111,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 1710011111,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 1740011111,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 1747011111,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 1754011111,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 1761011111,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 1768011111,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 1775011111,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 1846011111,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 1853011111,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 1860011111,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 1867011111,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 1874011111,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 1881011111,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 1909011111,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 1916011111,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 1957011111,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 1964011111,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 1971011111,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 1978011111,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 2000011111,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 2007011111,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 2014011111,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 2021011111,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 2029011111,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 2037011111,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 2044011111,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 2051011111,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 2058000001,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