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