1// -*- C -*- 2 3// Simulator definition for the MIPS DSP ASE. 4// Copyright (C) 2005, 2007 Free Software Foundation, Inc. 5// Contributed by MIPS Technologies, Inc. Written by Chao-ying Fu. 6// 7// This file is part of GDB, the GNU debugger. 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 signed32 h0 = 0; 29 signed16 h1, h2; 30 unsigned32 v1 = GPR[rs]; 31 unsigned32 v2 = GPR[rt]; 32 unsigned32 result = 0; 33 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 34 { 35 h1 = (signed16)(v1 & 0xffff); 36 h2 = (signed16)(v2 & 0xffff); 37 if (op == 0) // ADD 38 h0 = (signed32)h1 + (signed32)h2; 39 else if (op == 1) // SUB 40 h0 = (signed32)h1 - (signed32)h2; 41 else // MUL 42 h0 = (signed32)h1 * (signed32)h2; 43 if (h0 > (signed32)0x7fff || h0 < (signed32)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 > (signed32)0x7fff) 52 h0 = 0x7fff; 53 else 54 h0 = 0x8000; 55 } 56 } 57 result |= ((unsigned32)((unsigned16)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 signed64 h0; 66 signed32 h1, h2; 67 unsigned32 v1 = GPR[rs]; 68 unsigned32 v2 = GPR[rt]; 69 unsigned32 result = 0; 70 h1 = (signed32)v1; 71 h2 = (signed32)v2; 72 if (op == 0) // ADD 73 h0 = (signed64)h1 + (signed64)h2; 74 else // SUB 75 h0 = (signed64)h1 - (signed64)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 unsigned32 h0; 93 unsigned8 h1, h2; 94 unsigned32 v1 = GPR[rs]; 95 unsigned32 v2 = GPR[rt]; 96 unsigned32 result = 0; 97 for (i = 0; i < 32; i += 8, v1 >>= 8, v2 >>= 8) 98 { 99 h1 = (unsigned8)(v1 & 0xff); 100 h2 = (unsigned8)(v2 & 0xff); 101 if (op == 0) // ADD 102 h0 = (unsigned32)h1 + (unsigned32)h2; 103 else // SUB 104 h0 = (unsigned32)h1 - (unsigned32)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 |= ((unsigned32)((unsigned8)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 unsigned8 h0; 126 unsigned32 v1 = GPR[rt]; 127 unsigned32 result = 0; 128 for (i = 0; i < 32; i += 8, v1 >>= 8) 129 { 130 h0 = (unsigned8)(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 |= ((unsigned32)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 signed16 h0; 156 unsigned32 v1 = GPR[rt]; 157 unsigned32 result = 0; 158 int setcond; 159 for (i = 0; i < 32; i += 16, v1 >>= 16) 160 { 161 h0 = (signed16)(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 |= ((unsigned32)((unsigned16)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 unsigned32 v1 = GPR[rt]; 215 unsigned32 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_w_shra:int rd, int rt, int shift 251{ 252 unsigned32 result = GPR[rt]; 253 signed32 h0 = (signed32)result; 254 if (shift != 0 && (h0 & (1 << (shift-1)))) 255 h0 = (h0 >> shift) + 1; 256 else 257 h0 = h0 >> shift; 258 GPR[rd] = EXTEND32 (h0); 259} 260 261011111,5.RS,5.RT,5.RD,01010,010000:SPECIAL3:32::ADDQ.PH 262"addq.ph r<RD>, r<RS>, r<RT>" 263*dsp: 264{ 265 do_ph_op (SD_, RD, RS, RT, 0, 0); 266} 267 268011111,5.RS,5.RT,5.RD,01110,010000:SPECIAL3:32::ADDQ_S.PH 269"addq_s.ph r<RD>, r<RS>, r<RT>" 270*dsp: 271{ 272 do_ph_op (SD_, RD, RS, RT, 0, 1); 273} 274 275011111,5.RS,5.RT,5.RD,10110,010000:SPECIAL3:32::ADDQ_S.W 276"addq_s.w r<RD>, r<RS>, r<RT>" 277*dsp: 278{ 279 do_w_op (SD_, RD, RS, RT, 0); 280} 281 282011111,5.RS,5.RT,5.RD,00000,010000:SPECIAL3:32::ADDU.QB 283"addu.qb r<RD>, r<RS>, r<RT>" 284*dsp: 285{ 286 do_qb_op (SD_, RD, RS, RT, 0, 0); 287} 288 289011111,5.RS,5.RT,5.RD,00100,010000:SPECIAL3:32::ADDU_S.QB 290"addu_s.qb r<RD>, r<RS>, r<RT>" 291*dsp: 292{ 293 do_qb_op (SD_, RD, RS, RT, 0, 1); 294} 295 296011111,5.RS,5.RT,5.RD,01011,010000:SPECIAL3:32::SUBQ.PH 297"subq.ph r<RD>, r<RS>, r<RT>" 298*dsp: 299{ 300 do_ph_op (SD_, RD, RS, RT, 1, 0); 301} 302 303011111,5.RS,5.RT,5.RD,01111,010000:SPECIAL3:32::SUBQ_S.PH 304"subq_s.ph r<RD>, r<RS>, r<RT>" 305*dsp: 306{ 307 do_ph_op (SD_, RD, RS, RT, 1, 1); 308} 309 310011111,5.RS,5.RT,5.RD,10111,010000:SPECIAL3:32::SUBQ_S.W 311"subq_s.w r<RD>, r<RS>, r<RT>" 312*dsp: 313{ 314 do_w_op (SD_, RD, RS, RT, 1); 315} 316 317011111,5.RS,5.RT,5.RD,00001,010000:SPECIAL3:32::SUBU.QB 318"subu.qb r<RD>, r<RS>, r<RT>" 319*dsp: 320{ 321 do_qb_op (SD_, RD, RS, RT, 1, 0); 322} 323 324011111,5.RS,5.RT,5.RD,00101,010000:SPECIAL3:32::SUBU_S.QB 325"subu_s.qb r<RD>, r<RS>, r<RT>" 326*dsp: 327{ 328 do_qb_op (SD_, RD, RS, RT, 1, 1); 329} 330 331011111,5.RS,5.RT,5.RD,10000,010000:SPECIAL3:32::ADDSC 332"addsc r<RD>, r<RS>, r<RT>" 333*dsp: 334{ 335 unsigned32 v1 = GPR[RS]; 336 unsigned32 v2 = GPR[RT]; 337 unsigned64 h0; 338 h0 = (unsigned64)v1 + (unsigned64)v2; 339 if (h0 & 0x100000000LL) 340 DSPCR |= DSPCR_CARRY; 341 GPR[RD] = EXTEND32 (h0); 342} 343 344011111,5.RS,5.RT,5.RD,10001,010000:SPECIAL3:32::ADDWC 345"addwc r<RD>, r<RS>, r<RT>" 346*dsp: 347{ 348 unsigned32 v1 = GPR[RS]; 349 unsigned32 v2 = GPR[RT]; 350 unsigned64 h0; 351 signed32 h1 = (signed32) v1; 352 signed32 h2 = (signed32) v2; 353 h0 = (signed64)h1 + (signed64)h2 354 + (signed64)((DSPCR >> DSPCR_CARRY_SHIFT) & DSPCR_CARRY_MASK); 355 if (((h0 & 0x100000000LL) >> 1) != (h0 & 0x80000000)) 356 DSPCR |= DSPCR_OUFLAG4; 357 GPR[RD] = EXTEND32 (h0); 358} 359 360011111,5.RS,5.RT,5.RD,10010,010000:SPECIAL3:32::MODSUB 361"modsub r<RD>, r<RS>, r<RT>" 362*dsp: 363{ 364 unsigned32 result = 0; 365 unsigned32 v1 = GPR[RS]; 366 unsigned32 v2 = GPR[RT]; 367 unsigned32 decr = v2 & 0xff; 368 unsigned32 lastindex = (v2 & 0xffff00) >> 8; 369 if (v1 == 0) 370 result = lastindex; 371 else 372 result = v1 - decr; 373 GPR[RD] = EXTEND32 (result); 374} 375 376011111,5.RS,00000,5.RD,10100,010000:SPECIAL3:32::RADDU.W.QB 377"raddu.w.qb r<RD>, r<RS>" 378*dsp: 379{ 380 int i; 381 unsigned8 h0; 382 unsigned32 v1 = GPR[RS]; 383 unsigned32 result = 0; 384 for (i = 0; i < 32; i += 8, v1 >>= 8) 385 { 386 h0 = (unsigned8)(v1 & 0xff); 387 result += (unsigned32)h0; 388 } 389 GPR[RD] = EXTEND32 (result); 390} 391 392011111,00000,5.RT,5.RD,01001,010010:SPECIAL3:32::ABSQ_S.PH 393"absq_s.ph r<RD>, r<RT>" 394*dsp: 395{ 396 int i; 397 signed16 h0; 398 unsigned32 v1 = GPR[RT]; 399 unsigned32 result = 0; 400 for (i = 0; i < 32; i += 16, v1 >>= 16) 401 { 402 h0 = (signed16)(v1 & 0xffff); 403 if (h0 == (signed16)0x8000) 404 { 405 DSPCR |= DSPCR_OUFLAG4; 406 h0 = 0x7fff; 407 } 408 else if (h0 & 0x8000) 409 h0 = -h0; 410 result |= ((unsigned32)((unsigned16)h0) << i); 411 } 412 GPR[RD] = EXTEND32 (result); 413} 414 415011111,00000,5.RT,5.RD,10001,010010:SPECIAL3:32::ABSQ_S.W 416"absq_s.w r<RD>, r<RT>" 417*dsp: 418{ 419 unsigned32 v1 = GPR[RT]; 420 signed32 h0 = (signed32)v1; 421 if (h0 == (signed32)0x80000000) 422 { 423 DSPCR |= DSPCR_OUFLAG4; 424 h0 = 0x7fffffff; 425 } 426 else if (h0 & 0x80000000) 427 h0 = -h0; 428 GPR[RD] = EXTEND32 (h0); 429} 430 431011111,5.RS,5.RT,5.RD,01100,010001:SPECIAL3:32::PRECRQ.QB.PH 432"precrq.qb.ph r<RD>, r<RS>, r<RT>" 433*dsp: 434{ 435 unsigned32 v1 = GPR[RS]; 436 unsigned32 v2 = GPR[RT]; 437 unsigned32 tempu = (v1 & 0xff000000) >> 24; 438 unsigned32 tempv = (v1 & 0xff00) >> 8; 439 unsigned32 tempw = (v2 & 0xff000000) >> 24; 440 unsigned32 tempx = (v2 & 0xff00) >> 8; 441 GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx); 442} 443 444011111,5.RS,5.RT,5.RD,10100,010001:SPECIAL3:32::PRECRQ.PH.W 445"precrq.ph.w r<RD>, r<RS>, r<RT>" 446*dsp: 447{ 448 unsigned32 v1 = GPR[RS]; 449 unsigned32 v2 = GPR[RT]; 450 unsigned32 tempu = (v1 & 0xffff0000) >> 16; 451 unsigned32 tempv = (v2 & 0xffff0000) >> 16; 452 GPR[RD] = EXTEND32 ((tempu << 16) | tempv); 453} 454 455011111,5.RS,5.RT,5.RD,10101,010001:SPECIAL3:32::PRECRQ_RS.PH.W 456"precrq_rs.ph.w r<RD>, r<RS>, r<RT>" 457*dsp: 458{ 459 unsigned32 v1 = GPR[RS]; 460 unsigned32 v2 = GPR[RT]; 461 signed32 h1 = (signed32)v1; 462 signed32 h2 = (signed32)v2; 463 signed64 temp1 = (signed64)h1 + (signed64)0x8000; 464 signed32 temp2; 465 signed64 temp3 = (signed64)h2 + (signed64)0x8000; 466 signed32 temp4; 467 if (((temp1 & 0x100000000LL) >> 1) != (temp1 & 0x80000000)) 468 { 469 DSPCR |= DSPCR_OUFLAG6; 470 temp2 = 0x7fff; 471 } 472 else 473 temp2 = (signed32)((temp1 & 0xffff0000) >> 16); 474 if (((temp3 & 0x100000000LL) >> 1) != (temp3 & 0x80000000)) 475 { 476 DSPCR |= DSPCR_OUFLAG6; 477 temp4 = 0x7fff; 478 } 479 else 480 temp4 = (signed32)((temp3 & 0xffff0000) >> 16); 481 GPR[RD] = EXTEND32 ((temp2 << 16) | temp4); 482} 483 484011111,5.RS,5.RT,5.RD,01111,010001:SPECIAL3:32::PRECRQU_S.QB.PH 485"precrqu_s.qb.ph r<RD>, r<RS>, r<RT>" 486*dsp: 487{ 488 unsigned32 v1 = GPR[RS]; 489 unsigned32 v2 = GPR[RT]; 490 unsigned32 tempu, tempv, tempw, tempx; 491 if (v1 & 0x80000000) 492 { 493 DSPCR |= DSPCR_OUFLAG6; 494 tempu = 0; 495 } 496 else if (!(v1 & 0x80000000) && ((v1 >> 16) > (unsigned32)0x7f80)) 497 { 498 DSPCR |= DSPCR_OUFLAG6; 499 tempu = 0xff; 500 } 501 else 502 tempu = (v1 & 0x7f800000) >> 23; 503 if (v1 & 0x8000) 504 { 505 DSPCR |= DSPCR_OUFLAG6; 506 tempv = 0; 507 } 508 else if (!(v1 & 0x8000) && ((v1 & 0xffff) > (unsigned32)0x7f80)) 509 { 510 DSPCR |= DSPCR_OUFLAG6; 511 tempv = 0xff; 512 } 513 else 514 tempv = (v1 & 0x7f80) >> 7; 515 if (v2 & 0x80000000) 516 { 517 DSPCR |= DSPCR_OUFLAG6; 518 tempw = 0; 519 } 520 else if (!(v2 & 0x80000000) && ((v2 >> 16) > (unsigned32)0x7f80)) 521 { 522 DSPCR |= DSPCR_OUFLAG6; 523 tempw = 0xff; 524 } 525 else 526 tempw = (v2 & 0x7f800000) >> 23; 527 if (v2 & 0x8000) 528 { 529 DSPCR |= DSPCR_OUFLAG6; 530 tempx = 0; 531 } 532 else if (!(v2 & 0x8000) && ((v2 & 0xffff) > (unsigned32)0x7f80)) 533 { 534 DSPCR |= DSPCR_OUFLAG6; 535 tempx = 0xff; 536 } 537 else 538 tempx = (v2 & 0x7f80) >> 7; 539 GPR[RD] = EXTEND32 ((tempu << 24) | (tempv << 16) | (tempw << 8) | tempx); 540} 541 542011111,00000,5.RT,5.RD,01100,010010:SPECIAL3:32::PRECEQ.W.PHL 543"preceq.w.phl r<RD>, r<RT>" 544*dsp: 545{ 546 unsigned32 v1 = GPR[RT]; 547 GPR[RD] = EXTEND32 (v1 & 0xffff0000); 548} 549 550011111,00000,5.RT,5.RD,01101,010010:SPECIAL3:32::PRECEQ.W.PHR 551"preceq.w.phr r<RD>, r<RT>" 552*dsp: 553{ 554 unsigned32 v1 = GPR[RT]; 555 GPR[RD] = EXTEND32 ((v1 & 0xffff) << 16); 556} 557 558011111,00000,5.RT,5.RD,00100,010010:SPECIAL3:32::PRECEQU.PH.QBL 559"precequ.ph.qbl r<RD>, r<RT>" 560*dsp: 561{ 562 unsigned32 v1 = GPR[RT]; 563 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff0000) >> 9); 564} 565 566011111,00000,5.RT,5.RD,00101,010010:SPECIAL3:32::PRECEQU.PH.QBR 567"precequ.ph.qbr r<RD>, r<RT>" 568*dsp: 569{ 570 unsigned32 v1 = GPR[RT]; 571 GPR[RD] = EXTEND32 ((v1 & 0xff00) << 15) | ((v1 & 0xff) << 7); 572} 573 574011111,00000,5.RT,5.RD,00110,010010:SPECIAL3:32::PRECEQU.PH.QBLA 575"precequ.ph.qbla r<RD>, r<RT>" 576*dsp: 577{ 578 unsigned32 v1 = GPR[RT]; 579 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 1) | ((v1 & 0xff00) >> 1); 580} 581 582011111,00000,5.RT,5.RD,00111,010010:SPECIAL3:32::PRECEQU.PH.QBRA 583"precequ.ph.qbra r<RD>, r<RT>" 584*dsp: 585{ 586 unsigned32 v1 = GPR[RT]; 587 GPR[RD] = EXTEND32 ((v1 & 0xff0000) << 7) | ((v1 & 0xff) << 7); 588} 589 590011111,00000,5.RT,5.RD,11100,010010:SPECIAL3:32::PRECEU.PH.QBL 591"preceu.ph.qbl r<RD>, r<RT>" 592*dsp: 593{ 594 unsigned32 v1 = GPR[RT]; 595 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff0000) >> 16); 596} 597 598011111,00000,5.RT,5.RD,11101,010010:SPECIAL3:32::PRECEU.PH.QBR 599"preceu.ph.qbr r<RD>, r<RT>" 600*dsp: 601{ 602 unsigned32 v1 = GPR[RT]; 603 GPR[RD] = EXTEND32 ((v1 & 0xff00) << 8) | (v1 & 0xff); 604} 605 606011111,00000,5.RT,5.RD,11110,010010:SPECIAL3:32::PRECEU.PH.QBLA 607"preceu.ph.qbla r<RD>, r<RT>" 608*dsp: 609{ 610 unsigned32 v1 = GPR[RT]; 611 GPR[RD] = EXTEND32 ((v1 & 0xff000000) >> 8) | ((v1 & 0xff00) >> 8); 612} 613 614011111,00000,5.RT,5.RD,11111,010010:SPECIAL3:32::PRECEU.PH.QBRA 615"preceu.ph.qbra r<RD>, r<RT>" 616*dsp: 617{ 618 unsigned32 v1 = GPR[RT]; 619 GPR[RD] = EXTEND32 ((v1 & 0xff0000) | (v1 & 0xff)); 620} 621 622011111,00,3.SHIFT3,5.RT,5.RD,00000,010011:SPECIAL3:32::SHLL.QB 623"shll.qb r<RD>, r<RT>, <SHIFT3>" 624*dsp: 625{ 626 do_qb_shift (SD_, RD, RT, SHIFT3, 0); 627} 628 629011111,5.RS,5.RT,5.RD,00010,010011:SPECIAL3:32::SHLLV.QB 630"shllv.qb r<RD>, r<RT>, r<RS>" 631*dsp: 632{ 633 unsigned32 shift = GPR[RS] & 0x7; 634 do_qb_shift (SD_, RD, RT, shift, 0); 635} 636 637011111,0,4.SHIFT4,5.RT,5.RD,01000,010011:SPECIAL3:32::SHLL.PH 638"shll.ph r<RD>, r<RT>, <SHIFT4>" 639*dsp: 640{ 641 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 0); 642} 643 644011111,5.RS,5.RT,5.RD,01010,010011:SPECIAL3:32::SHLLV.PH 645"shllv.ph r<RD>, r<RT>, r<RS>" 646*dsp: 647{ 648 unsigned32 shift = GPR[RS] & 0xf; 649 do_ph_shift (SD_, RD, RT, shift, 0, 0); 650} 651 652011111,0,4.SHIFT4,5.RT,5.RD,01100,010011:SPECIAL3:32::SHLL_S.PH 653"shll_s.ph r<RD>, r<RT>, <SHIFT4>" 654*dsp: 655{ 656 do_ph_shift (SD_, RD, RT, SHIFT4, 0, 1); 657} 658 659011111,5.RS,5.RT,5.RD,01110,010011:SPECIAL3:32::SHLLV_S.PH 660"shllv_s.ph r<RD>, r<RT>, r<RS>" 661*dsp: 662{ 663 unsigned32 shift = GPR[RS] & 0xf; 664 do_ph_shift (SD_, RD, RT, shift, 0, 1); 665} 666 667011111,5.SHIFT5,5.RT,5.RD,10100,010011:SPECIAL3:32::SHLL_S.W 668"shll_s.w r<RD>, r<RT>, <SHIFT5>" 669*dsp: 670{ 671 do_w_shll (SD_, RD, RT, SHIFT5); 672} 673 674011111,5.RS,5.RT,5.RD,10110,010011:SPECIAL3:32::SHLLV_S.W 675"shllv_s.w r<RD>, r<RT>, r<RS>" 676*dsp: 677{ 678 unsigned32 shift = GPR[RS] & 0x1f; 679 do_w_shll (SD_, RD, RT, shift); 680} 681 682011111,00,3.SHIFT3,5.RT,5.RD,00001,010011:SPECIAL3:32::SHRL.QB 683"shrl.qb r<RD>, r<RT>, <SHIFT3>" 684*dsp: 685{ 686 do_qb_shift (SD_, RD, RT, SHIFT3, 1); 687} 688 689011111,5.RS,5.RT,5.RD,00011,010011:SPECIAL3:32::SHRLV.QB 690"shrlv.qb r<RD>, r<RT>, r<RS>" 691*dsp: 692{ 693 unsigned32 shift = GPR[RS] & 0x7; 694 do_qb_shift (SD_, RD, RT, shift, 1); 695} 696 697011111,0,4.SHIFT4,5.RT,5.RD,01001,010011:SPECIAL3:32::SHRA.PH 698"shra.ph r<RD>, r<RT>, <SHIFT4>" 699*dsp: 700{ 701 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 0); 702} 703 704011111,5.RS,5.RT,5.RD,01011,010011:SPECIAL3:32::SHRAV.PH 705"shrav.ph r<RD>, r<RT>, r<RS>" 706*dsp: 707{ 708 unsigned32 shift = GPR[RS] & 0xf; 709 do_ph_shift (SD_, RD, RT, shift, 1, 0); 710} 711 712011111,0,4.SHIFT4,5.RT,5.RD,01101,010011:SPECIAL3:32::SHRA_R.PH 713"shra_r.ph r<RD>, r<RT>, <SHIFT4>" 714*dsp: 715{ 716 do_ph_shift (SD_, RD, RT, SHIFT4, 1, 1); 717} 718 719011111,5.RS,5.RT,5.RD,01111,010011:SPECIAL3:32::SHRAV_R.PH 720"shrav_r.ph r<RD>, r<RT>, r<RS>" 721*dsp: 722{ 723 unsigned32 shift = GPR[RS] & 0xf; 724 do_ph_shift (SD_, RD, RT, shift, 1, 1); 725} 726 727011111,5.SHIFT5,5.RT,5.RD,10101,010011:SPECIAL3:32::SHRA_R.W 728"shra_r.w r<RD>, r<RT>, <SHIFT5>" 729*dsp: 730{ 731 do_w_shra (SD_, RD, RT, SHIFT5); 732} 733 734011111,5.RS,5.RT,5.RD,10111,010011:SPECIAL3:32::SHRAV_R.W 735"shrav_r.w r<RD>, r<RT>, r<RS>" 736*dsp: 737{ 738 unsigned32 shift = GPR[RS] & 0x1f; 739 do_w_shra (SD_, RD, RT, shift); 740} 741 742// loc: 0 = qhl, 1 = qhr 743:function:::void:do_qb_muleu:int rd, int rs, int rt, int loc 744{ 745 int i; 746 unsigned32 result = 0; 747 unsigned32 v1 = GPR[rs]; 748 unsigned32 v2 = GPR[rt]; 749 unsigned16 h1, h2; 750 unsigned32 prod; 751 if (loc == 0) 752 v1 >>= 16; 753 for (i = 0; i < 32; i += 16, v1 >>= 8, v2 >>= 16) 754 { 755 h1 = (unsigned16)(v1 & 0xff); 756 h2 = (unsigned16)(v2 & 0xffff); 757 prod = (unsigned32)h1 * (unsigned32)h2; 758 if (prod > 0xffff) 759 { 760 DSPCR |= DSPCR_OUFLAG5; 761 prod = 0xffff; 762 } 763 result |= ((unsigned32)prod << i); 764 } 765 GPR[rd] = EXTEND32 (result); 766} 767 768011111,5.RS,5.RT,5.RD,00110,010000:SPECIAL3:32::MULEU_S.PH.QBL 769"muleu_s.ph.qbl r<RD>, r<RS>, r<RT>" 770*dsp: 771{ 772 do_qb_muleu (SD_, RD, RS, RT, 0); 773} 774 775011111,5.RS,5.RT,5.RD,00111,010000:SPECIAL3:32::MULEU_S.PH.QBR 776"muleu_s.ph.qbr r<RD>, r<RS>, r<RT>" 777*dsp: 778{ 779 do_qb_muleu (SD_, RD, RS, RT, 1); 780} 781 782// round: 0 = no rounding, 1 = rounding 783:function:::void:do_ph_mulq:int rd, int rs, int rt, int round 784{ 785 int i; 786 unsigned32 result = 0; 787 unsigned32 v1 = GPR[rs]; 788 unsigned32 v2 = GPR[rt]; 789 signed16 h1, h2; 790 signed32 prod; 791 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 792 { 793 h1 = (signed16)(v1 & 0xffff); 794 h2 = (signed16)(v2 & 0xffff); 795 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000) 796 { 797 DSPCR |= DSPCR_OUFLAG5; 798 prod = 0x7fffffff; 799 } 800 else 801 { 802 prod = ((signed32)h1 * (signed32)h2) << 1; 803 if (round == 1) 804 prod += (signed32)0x8000; 805 } 806 result |= (((unsigned32)prod >> 16) << i); 807 } 808 GPR[rd] = EXTEND32 (result); 809} 810 811011111,5.RS,5.RT,5.RD,11111,010000:SPECIAL3:32::MULQ_RS.PH 812"mulq_rs.ph r<RD>, r<RS>, r<RT>" 813*dsp: 814{ 815 do_ph_mulq (SD_, RD, RS, RT, 1); 816} 817 818// loc: 0 = phl, 1 = phr 819:function:::void:do_ph_muleq:int rd, int rs, int rt, int loc 820{ 821 unsigned32 v1 = GPR[rs]; 822 unsigned32 v2 = GPR[rt]; 823 signed16 h1, h2; 824 signed32 prod; 825 if (loc == 0) 826 { 827 h1 = (signed16)(v1 >> 16); 828 h2 = (signed16)(v2 >> 16); 829 } 830 else 831 { 832 h1 = (signed16)(v1 & 0xffff); 833 h2 = (signed16)(v2 & 0xffff); 834 } 835 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000) 836 { 837 DSPCR |= DSPCR_OUFLAG5; 838 prod = 0x7fffffff; 839 } 840 else 841 prod = ((signed32)h1 * (signed32)h2) << 1; 842 GPR[rd] = EXTEND32 (prod); 843} 844 845011111,5.RS,5.RT,5.RD,11100,010000:SPECIAL3:32::MULEQ_S.W.PHL 846"muleq_s.w.phl r<RD>, r<RS>, r<RT>" 847*dsp: 848{ 849 do_ph_muleq (SD_, RD, RS, RT, 0); 850} 851 852011111,5.RS,5.RT,5.RD,11101,010000:SPECIAL3:32::MULEQ_S.W.PHR 853"muleq_s.w.phr r<RD>, r<RS>, r<RT>" 854*dsp: 855{ 856 do_ph_muleq (SD_, RD, RS, RT, 1); 857} 858 859// op: 0 = DPAU 1 = DPSU 860// loc: 0 = qbl, 1 = qbr 861:function:::void:do_qb_dot_product:int ac, int rs, int rt, int op, int loc 862{ 863 int i; 864 unsigned32 v1 = GPR[rs]; 865 unsigned32 v2 = GPR[rt]; 866 unsigned8 h1, h2; 867 unsigned32 lo = DSPLO(ac); 868 unsigned32 hi = DSPHI(ac); 869 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo; 870 if (loc == 0) 871 { 872 v1 >>= 16; 873 v2 >>= 16; 874 } 875 for (i = 0; i < 16; i += 8, v1 >>= 8, v2 >>= 8) 876 { 877 h1 = (unsigned8)(v1 & 0xff); 878 h2 = (unsigned8)(v2 & 0xff); 879 if (op == 0) // DPAU 880 prod += (unsigned64)h1 * (unsigned64)h2; 881 else // DPSU 882 prod -= (unsigned64)h1 * (unsigned64)h2; 883 } 884 DSPLO(ac) = EXTEND32 (prod); 885 DSPHI(ac) = EXTEND32 (prod >> 32); 886} 887 888011111,5.RS,5.RT,000,2.AC,00011,110000:SPECIAL3:32::DPAU.H.QBL 889"dpau.h.qbl ac<AC>, r<RS>, r<RT>" 890*dsp: 891{ 892 do_qb_dot_product (SD_, AC, RS, RT, 0, 0); 893} 894 895011111,5.RS,5.RT,000,2.AC,00111,110000:SPECIAL3:32::DPAU.H.QBR 896"dpau.h.qbr ac<AC>, r<RS>, r<RT>" 897*dsp: 898{ 899 do_qb_dot_product (SD_, AC, RS, RT, 0, 1); 900} 901 902011111,5.RS,5.RT,000,2.AC,01011,110000:SPECIAL3:32::DPSU.H.QBL 903"dpsu.h.qbl ac<AC>, r<RS>, r<RT>" 904*dsp: 905{ 906 do_qb_dot_product (SD_, AC, RS, RT, 1, 0); 907} 908 909011111,5.RS,5.RT,000,2.AC,01111,110000:SPECIAL3:32::DPSU.H.QBR 910"dpsu.h.qbr ac<AC>, r<RS>, r<RT>" 911*dsp: 912{ 913 do_qb_dot_product (SD_, AC, RS, RT, 1, 1); 914} 915 916// op: 0 = DPAQ 1 = DPSQ 917:function:::void:do_ph_dot_product:int ac, int rs, int rt, int op 918{ 919 int i; 920 unsigned32 v1 = GPR[rs]; 921 unsigned32 v2 = GPR[rt]; 922 signed16 h1, h2; 923 signed32 result; 924 unsigned32 lo = DSPLO(ac); 925 unsigned32 hi = DSPHI(ac); 926 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo); 927 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 928 { 929 h1 = (signed16)(v1 & 0xffff); 930 h2 = (signed16)(v2 & 0xffff); 931 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000) 932 { 933 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 934 result = (signed32)0x7fffffff; 935 } 936 else 937 result = ((signed32)h1 * (signed32)h2) << 1; 938 939 if (op == 0) // DPAQ 940 prod += (signed64)result; 941 else // DPSQ 942 prod -= (signed64)result; 943 } 944 DSPLO(ac) = EXTEND32 (prod); 945 DSPHI(ac) = EXTEND32 (prod >> 32); 946} 947 948011111,5.RS,5.RT,000,2.AC,00100,110000:SPECIAL3:32::DPAQ_S.W.PH 949"dpaq_s.w.ph ac<AC>, r<RS>, r<RT>" 950*dsp: 951{ 952 do_ph_dot_product (SD_, AC, RS, RT, 0); 953} 954 955011111,5.RS,5.RT,000,2.AC,00101,110000:SPECIAL3:32::DPSQ_S.W.PH 956"dpsq_s.w.ph ac<AC>, r<RS>, r<RT>" 957*dsp: 958{ 959 do_ph_dot_product (SD_, AC, RS, RT, 1); 960} 961 962011111,5.RS,5.RT,000,2.AC,00110,110000:SPECIAL3:32::MULSAQ_S.W.PH 963"mulsaq_s.w.ph ac<AC>, r<RS>, r<RT>" 964*dsp: 965{ 966 int i; 967 unsigned32 v1 = GPR[RS]; 968 unsigned32 v2 = GPR[RT]; 969 signed16 h1, h2; 970 signed32 result; 971 unsigned32 lo = DSPLO(AC); 972 unsigned32 hi = DSPHI(AC); 973 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo); 974 for (i = 0; i < 32; i += 16, v1 >>= 16, v2 >>= 16) 975 { 976 h1 = (signed16)(v1 & 0xffff); 977 h2 = (signed16)(v2 & 0xffff); 978 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000) 979 { 980 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + AC)); 981 result = (signed32) 0x7fffffff; 982 } 983 else 984 result = ((signed32)h1 * (signed32)h2) << 1; 985 986 if (i == 0) 987 prod -= (signed64) result; 988 else 989 prod += (signed64) result; 990 } 991 DSPLO(AC) = EXTEND32 (prod); 992 DSPHI(AC) = EXTEND32 (prod >> 32); 993} 994 995// op: 0 = DPAQ 1 = DPSQ 996:function:::void:do_w_dot_product:int ac, int rs, int rt, int op 997{ 998 unsigned32 v1 = GPR[rs]; 999 unsigned32 v2 = GPR[rt]; 1000 signed32 h1, h2; 1001 signed64 result; 1002 unsigned32 lo = DSPLO(ac); 1003 unsigned32 hi = DSPHI(ac); 1004 unsigned32 resultlo; 1005 unsigned32 resulthi; 1006 unsigned32 carry; 1007 unsigned64 temp1; 1008 signed64 temp2; 1009 h1 = (signed32) v1; 1010 h2 = (signed32) v2; 1011 if (h1 == 0x80000000 && h2 == 0x80000000) 1012 { 1013 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1014 result = (signed64) 0x7fffffffffffffffLL; 1015 } 1016 else 1017 result = ((signed64)h1 * (signed64)h2) << 1; 1018 resultlo = (unsigned32)(result); 1019 resulthi = (unsigned32)(result >> 32); 1020 if (op ==0) // DPAQ 1021 { 1022 temp1 = (unsigned64)lo + (unsigned64)resultlo; 1023 carry = (unsigned32)((temp1 >> 32) & 1); 1024 temp2 = (signed64)((signed32)hi) + (signed64)((signed32)resulthi) + 1025 (signed64)((signed32)carry); 1026 } 1027 else // DPSQ 1028 { 1029 temp1 = (unsigned64)lo - (unsigned64)resultlo; 1030 carry = (unsigned32)((temp1 >> 32) & 1); 1031 temp2 = (signed64)((signed32)hi) - (signed64)((signed32)resulthi) - 1032 (signed64)((signed32)carry); 1033 } 1034 if (((temp2 & 0x100000000LL) >> 1) != (temp2 & 0x80000000LL)) 1035 { 1036 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1037 if (temp2 & 0x100000000LL) 1038 { 1039 DSPLO(ac) = EXTEND32 (0x00000000); 1040 DSPHI(ac) = EXTEND32 (0x80000000); 1041 } 1042 else 1043 { 1044 DSPLO(ac) = EXTEND32 (0xffffffff); 1045 DSPHI(ac) = EXTEND32 (0x7fffffff); 1046 } 1047 } 1048 else 1049 { 1050 DSPLO(ac) = EXTEND32 (temp1); 1051 DSPHI(ac) = EXTEND32 (temp2); 1052 } 1053} 1054 1055011111,5.RS,5.RT,000,2.AC,01100,110000:SPECIAL3:32::DPAQ_SA.L.W 1056"dpaq_sa.l.w ac<AC>, r<RS>, r<RT>" 1057*dsp: 1058{ 1059 do_w_dot_product (SD_, AC, RS, RT, 0); 1060} 1061 1062011111,5.RS,5.RT,000,2.AC,01101,110000:SPECIAL3:32::DPSQ_SA.L.W 1063"dpsq_sa.l.w ac<AC>, r<RS>, r<RT>" 1064*dsp: 1065{ 1066 do_w_dot_product (SD_, AC, RS, RT, 1); 1067} 1068 1069// op: 0 = MAQ_S 1 = MAQ_SA 1070// loc: 0 = phl, 1 = phr 1071:function:::void:do_ph_maq:int ac, int rs, int rt, int op, int loc 1072{ 1073 int i; 1074 unsigned32 v1 = GPR[rs]; 1075 unsigned32 v2 = GPR[rt]; 1076 signed16 h1, h2; 1077 signed32 result; 1078 unsigned32 lo = DSPLO(ac); 1079 unsigned32 hi = DSPHI(ac); 1080 signed64 prod = (signed64)((((unsigned64)hi) << 32) + (unsigned64)lo); 1081 if (loc == 0) 1082 { 1083 h1 = (signed16)(v1 >> 16); 1084 h2 = (signed16)(v2 >> 16); 1085 } 1086 else 1087 { 1088 h1 = (signed16)(v1 & 0xffff); 1089 h2 = (signed16)(v2 & 0xffff); 1090 } 1091 if (h1 == (signed16)0x8000 && h2 == (signed16)0x8000) 1092 { 1093 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1094 result = (signed32)0x7fffffff; 1095 } 1096 else 1097 result = ((signed32)h1 * (signed32)h2) << 1; 1098 prod += (signed64)result; 1099 if (op == 1) // MAQ_SA 1100 { 1101 if (prod & 0x8000000000000000LL) 1102 { 1103 for (i = 62; i >= 31; i--) 1104 { 1105 if (!(prod & ((signed64)1 << i))) 1106 { 1107 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1108 prod = 0xffffffff80000000LL; 1109 break; 1110 } 1111 } 1112 } 1113 else 1114 { 1115 for (i = 62; i >= 31; i--) 1116 { 1117 if (prod & ((signed64)1 << i)) 1118 { 1119 DSPCR |= (1 << (DSPCR_OUFLAG_SHIFT + ac)); 1120 prod = 0x7fffffff; 1121 break; 1122 } 1123 } 1124 } 1125 } 1126 DSPLO(ac) = EXTEND32 (prod); 1127 DSPHI(ac) = EXTEND32 (prod >> 32); 1128} 1129 1130011111,5.RS,5.RT,000,2.AC,10100,110000:SPECIAL3:32::MAQ_S.W.PHL 1131"maq_s.w.phl ac<AC>, r<RS>, r<RT>" 1132*dsp: 1133{ 1134 do_ph_maq (SD_, AC, RS, RT, 0, 0); 1135} 1136 1137011111,5.RS,5.RT,000,2.AC,10110,110000:SPECIAL3:32::MAQ_S.W.PHR 1138"maq_s.w.phr ac<AC>, r<RS>, r<RT>" 1139*dsp: 1140{ 1141 do_ph_maq (SD_, AC, RS, RT, 0, 1); 1142} 1143 1144011111,5.RS,5.RT,000,2.AC,10000,110000:SPECIAL3:32::MAQ_SA.W.PHL 1145"maq_sa.w.phl ac<AC>, r<RS>, r<RT>" 1146*dsp: 1147{ 1148 do_ph_maq (SD_, AC, RS, RT, 1, 0); 1149} 1150 1151011111,5.RS,5.RT,000,2.AC,10010,110000:SPECIAL3:32::MAQ_SA.W.PHR 1152"maq_sa.w.phr ac<AC>, r<RS>, r<RT>" 1153*dsp: 1154{ 1155 do_ph_maq (SD_, AC, RS, RT, 1, 1); 1156} 1157 1158011111,00000,5.RT,5.RD,11011,010010:SPECIAL3:32::BITREV 1159"bitrev r<RD>, r<RT>" 1160*dsp: 1161{ 1162 int i; 1163 unsigned32 v1 = GPR[RT]; 1164 unsigned32 h1 = 0; 1165 for (i = 0; i < 16; i++) 1166 { 1167 if (v1 & (1 << i)) 1168 h1 |= (1 << (15 - i)); 1169 } 1170 GPR[RD] = EXTEND32 (h1); 1171} 1172 1173011111,5.RS,5.RT,00000,00000,001100:SPECIAL3:32::INSV 1174"insv r<RT>, r<RS>" 1175*dsp: 1176{ 1177 unsigned32 v1 = GPR[RS]; 1178 unsigned32 v2 = GPR[RT]; 1179 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 1180 unsigned32 size = (DSPCR >> DSPCR_SCOUNT_SHIFT) & DSPCR_SCOUNT_MASK; 1181 unsigned32 mask1, mask2, mask3, result; 1182 if (size < 32) 1183 mask1 = (1 << size) - 1; 1184 else 1185 mask1 = 0xffffffff; 1186 mask2 = (1 << pos) - 1; 1187 if (pos + size < 32) 1188 mask3 = ~((1 << (pos + size)) - 1); 1189 else 1190 mask3 = 0; 1191 result = (v2 & mask3) | ((v1 & mask1) << pos) | (v2 & mask2); 1192 GPR[RT] = EXTEND32 (result); 1193} 1194 1195011111,00,8.IMM8,5.RD,00010,010010:SPECIAL3:32::REPL.QB 1196"repl.qb r<RD>, <IMM8>" 1197*dsp: 1198{ 1199 GPR[RD] = EXTEND32 ((IMM8 << 24) | (IMM8 << 16) | (IMM8 << 8) | IMM8); 1200} 1201 1202011111,00000,5.RT,5.RD,00011,010010:SPECIAL3:32::REPLV.QB 1203"replv.qb r<RD>, r<RT>" 1204*dsp: 1205{ 1206 unsigned32 v1 = GPR[RT]; 1207 v1 = v1 & 0xff; 1208 GPR[RD] = EXTEND32 ((v1 << 24) | (v1 << 16) | (v1 << 8) | v1); 1209} 1210 1211011111,10.IMM10,5.RD,01010,010010:SPECIAL3:32::REPL.PH 1212"repl.ph r<RD>, <IMM10>" 1213*dsp: 1214{ 1215 signed32 v1 = IMM10; 1216 if (v1 & 0x200) 1217 v1 |= 0xfffffc00; 1218 GPR[RD] = EXTEND32 ((v1 << 16) | (v1 & 0xffff)); 1219} 1220 1221011111,00000,5.RT,5.RD,01011,010010:SPECIAL3:32::REPLV.PH 1222"replv.ph r<RD>, r<RT>" 1223*dsp: 1224{ 1225 unsigned32 v1 = GPR[RT]; 1226 v1 = v1 & 0xffff; 1227 GPR[RD] = EXTEND32 ((v1 << 16) | v1); 1228} 1229 1230// op: 0 = EQ, 1 = LT, 2 = LE 1231:function:::void:do_qb_cmpu:int rs, int rt, int op 1232{ 1233 int i, j; 1234 unsigned32 v1 = GPR[rs]; 1235 unsigned32 v2 = GPR[rt]; 1236 unsigned8 h1, h2; 1237 unsigned32 mask; 1238 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 1239 { 1240 h1 = (unsigned8)(v1 & 0xff); 1241 h2 = (unsigned8)(v2 & 0xff); 1242 mask = ~(1 << (DSPCR_CCOND_SHIFT + j)); 1243 DSPCR &= mask; 1244 if (op == 0) // EQ 1245 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j)); 1246 else if (op == 1) // LT 1247 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j)); 1248 else // LE 1249 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j)); 1250 } 1251} 1252 1253011111,5.RS,5.RT,00000,00000,010001:SPECIAL3:32::CMPU.EQ.QB 1254"cmpu.eq.qb r<RS>, r<RT>" 1255*dsp: 1256{ 1257 do_qb_cmpu (SD_, RS, RT, 0); 1258} 1259 1260011111,5.RS,5.RT,00000,00001,010001:SPECIAL3:32::CMPU.LT.QB 1261"cmpu.lt.qb r<RS>, r<RT>" 1262*dsp: 1263{ 1264 do_qb_cmpu (SD_, RS, RT, 1); 1265} 1266 1267011111,5.RS,5.RT,00000,00010,010001:SPECIAL3:32::CMPU.LE.QB 1268"cmpu.le.qb r<RS>, r<RT>" 1269*dsp: 1270{ 1271 do_qb_cmpu (SD_, RS, RT, 2); 1272} 1273 1274// op: 0 = EQ, 1 = LT, 2 = LE 1275:function:::void:do_qb_cmpgu:int rd, int rs, int rt, int op 1276{ 1277 int i, j; 1278 unsigned32 v1 = GPR[rs]; 1279 unsigned32 v2 = GPR[rt]; 1280 unsigned8 h1, h2; 1281 unsigned32 result = 0; 1282 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 1283 { 1284 h1 = (unsigned8)(v1 & 0xff); 1285 h2 = (unsigned8)(v2 & 0xff); 1286 if (op == 0) // EQ 1287 result |= ((h1 == h2) << j); 1288 else if (op == 1) // LT 1289 result |= ((h1 < h2) << j); 1290 else // LE 1291 result |= ((h1 <= h2) << j); 1292 } 1293 GPR[rd] = EXTEND32 (result); 1294} 1295 1296011111,5.RS,5.RT,5.RD,00100,010001:SPECIAL3:32::CMPGU.EQ.QB 1297"cmpgu.eq.qb r<RD>, r<RS>, r<RT>" 1298*dsp: 1299{ 1300 do_qb_cmpgu (SD_, RD, RS, RT, 0); 1301} 1302 1303011111,5.RS,5.RT,5.RD,00101,010001:SPECIAL3:32::CMPGU.LT.QB 1304"cmpgu.lt.qb r<RD>, r<RS>, r<RT>" 1305*dsp: 1306{ 1307 do_qb_cmpgu (SD_, RD, RS, RT, 1); 1308} 1309 1310011111,5.RS,5.RT,5.RD,00110,010001:SPECIAL3:32::CMPGU.LE.QB 1311"cmpgu.le.qb r<RD>, r<RS>, r<RT>" 1312*dsp: 1313{ 1314 do_qb_cmpgu (SD_, RD, RS, RT, 2); 1315} 1316 1317// op: 0 = EQ, 1 = LT, 2 = LE 1318:function:::void:do_ph_cmpu:int rs, int rt, int op 1319{ 1320 int i, j; 1321 unsigned32 v1 = GPR[rs]; 1322 unsigned32 v2 = GPR[rt]; 1323 signed16 h1, h2; 1324 unsigned32 mask; 1325 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16) 1326 { 1327 h1 = (signed16)(v1 & 0xffff); 1328 h2 = (signed16)(v2 & 0xffff); 1329 mask = ~(1 << (DSPCR_CCOND_SHIFT + j)); 1330 DSPCR &= mask; 1331 if (op == 0) // EQ 1332 DSPCR |= ((h1 == h2) << (DSPCR_CCOND_SHIFT + j)); 1333 else if (op == 1) // LT 1334 DSPCR |= ((h1 < h2) << (DSPCR_CCOND_SHIFT + j)); 1335 else // LE 1336 DSPCR |= ((h1 <= h2) << (DSPCR_CCOND_SHIFT + j)); 1337 } 1338} 1339 1340011111,5.RS,5.RT,00000,01000,010001:SPECIAL3:32::CMP.EQ.PH 1341"cmp.eq.ph r<RS>, r<RT>" 1342*dsp: 1343{ 1344 do_ph_cmpu (SD_, RS, RT, 0); 1345} 1346 1347011111,5.RS,5.RT,00000,01001,010001:SPECIAL3:32::CMP.LT.PH 1348"cmp.lt.ph r<RS>, r<RT>" 1349*dsp: 1350{ 1351 do_ph_cmpu (SD_, RS, RT, 1); 1352} 1353 1354011111,5.RS,5.RT,00000,01010,010001:SPECIAL3:32::CMP.LE.PH 1355"cmp.le.ph r<RS>, r<RT>" 1356*dsp: 1357{ 1358 do_ph_cmpu (SD_, RS, RT, 2); 1359} 1360 1361011111,5.RS,5.RT,5.RD,00011,010001:SPECIAL3:32::PICK.QB 1362"pick.qb r<RD>, r<RS>, r<RT>" 1363*dsp: 1364{ 1365 int i, j; 1366 unsigned32 v1 = GPR[RS]; 1367 unsigned32 v2 = GPR[RT]; 1368 unsigned8 h1, h2; 1369 unsigned32 result = 0; 1370 for (i = 0, j = 0; i < 32; i += 8, j++, v1 >>= 8, v2 >>= 8) 1371 { 1372 h1 = (unsigned8)(v1 & 0xff); 1373 h2 = (unsigned8)(v2 & 0xff); 1374 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j))) 1375 result |= (unsigned32)(h1 << i); 1376 else 1377 result |= (unsigned32)(h2 << i); 1378 } 1379 GPR[RD] = EXTEND32 (result); 1380} 1381 1382011111,5.RS,5.RT,5.RD,01011,010001:SPECIAL3:32::PICK.PH 1383"pick.ph r<RD>, r<RS>, r<RT>" 1384*dsp: 1385{ 1386 int i, j; 1387 unsigned32 v1 = GPR[RS]; 1388 unsigned32 v2 = GPR[RT]; 1389 unsigned16 h1, h2; 1390 unsigned32 result = 0; 1391 for (i = 0, j = 0; i < 32; i += 16, j++, v1 >>= 16, v2 >>= 16) 1392 { 1393 h1 = (unsigned16)(v1 & 0xffff); 1394 h2 = (unsigned16)(v2 & 0xffff); 1395 if (DSPCR & (1 << (DSPCR_CCOND_SHIFT + j))) 1396 result |= (unsigned32)(h1 << i); 1397 else 1398 result |= (unsigned32)(h2 << i); 1399 } 1400 GPR[RD] = EXTEND32 (result); 1401} 1402 1403011111,5.RS,5.RT,5.RD,01110,010001:SPECIAL3:32::PACKRL.PH 1404"packrl.ph r<RD>, r<RS>, r<RT>" 1405*dsp: 1406{ 1407 unsigned32 v1 = GPR[RS]; 1408 unsigned32 v2 = GPR[RT]; 1409 GPR[RD] = EXTEND32 ((v1 << 16) + (v2 >> 16)); 1410} 1411 1412// op: 0 = EXTR, 1 = EXTR_R, 2 = EXTR_RS 1413:function:::void:do_w_extr:int rt, int ac, int shift, int op 1414{ 1415 int i; 1416 unsigned32 lo = DSPLO(ac); 1417 unsigned32 hi = DSPHI(ac); 1418 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo; 1419 signed64 result = (signed64)prod; 1420 int setcond = 0; 1421 if (!(prod & 0x8000000000000000LL)) 1422 { 1423 for (i = 62; i >= (shift + 31); i--) 1424 { 1425 if (prod & ((unsigned64)1 << i)) 1426 { 1427 DSPCR |= DSPCR_OUFLAG7; 1428 setcond = 1; 1429 break; 1430 } 1431 } 1432 if (((prod >> (shift - 1)) & 0xffffffffLL) == 0xffffffffLL) 1433 { 1434 DSPCR |= DSPCR_OUFLAG7; 1435 setcond = 1; 1436 } 1437 } 1438 else 1439 { 1440 for (i = 62; i >= (shift + 31); i--) 1441 { 1442 if (!(prod & ((unsigned64)1 << i))) 1443 { 1444 DSPCR |= DSPCR_OUFLAG7; 1445 setcond = 2; 1446 break; 1447 } 1448 } 1449 } 1450 if (op == 0) // EXTR 1451 result = result >> shift; 1452 else if (op == 1) // EXTR_R 1453 { 1454 if (shift != 0) 1455 result = ((result >> (shift - 1)) + 1) >> 1; 1456 else 1457 result = result >> shift; 1458 } 1459 else // EXTR_RS 1460 { 1461 if (setcond == 1) 1462 result = 0x7fffffff; 1463 else if (setcond == 2) 1464 result = 0x80000000; 1465 else 1466 { 1467 if (shift != 0) 1468 result = ((result >> (shift - 1)) + 1) >> 1; 1469 else 1470 result = result >> shift; 1471 } 1472 } 1473 GPR[rt] = EXTEND32 (result); 1474} 1475 1476011111,5.SHIFT,5.RT,000,2.AC,00000,111000:SPECIAL3:32::EXTR.W 1477"extr.w r<RT>, ac<AC>, <SHIFT>" 1478*dsp: 1479{ 1480 do_w_extr (SD_, RT, AC, SHIFT, 0); 1481} 1482 1483011111,5.RS,5.RT,000,2.AC,00001,111000:SPECIAL3:32::EXTRV.W 1484"extrv.w r<RT>, ac<AC>, r<RS>" 1485*dsp: 1486{ 1487 unsigned32 shift = GPR[RS] & 0x1f; 1488 do_w_extr (SD_, RT, AC, shift, 0); 1489} 1490 1491011111,5.SHIFT,5.RT,000,2.AC,00100,111000:SPECIAL3:32::EXTR_R.W 1492"extr_r.w r<RT>, ac<AC>, <SHIFT>" 1493*dsp: 1494{ 1495 do_w_extr (SD_, RT, AC, SHIFT, 1); 1496} 1497 1498011111,5.RS,5.RT,000,2.AC,00101,111000:SPECIAL3:32::EXTRV_R.W 1499"extrv_r.w r<RT>, ac<AC>, r<RS>" 1500*dsp: 1501{ 1502 unsigned32 shift = GPR[RS] & 0x1f; 1503 do_w_extr (SD_, RT, AC, shift, 1); 1504} 1505 1506011111,5.SHIFT,5.RT,000,2.AC,00110,111000:SPECIAL3:32::EXTR_RS.W 1507"extr_rs.w r<RT>, ac<AC>, <SHIFT>" 1508*dsp: 1509{ 1510 do_w_extr (SD_, RT, AC, SHIFT, 2); 1511} 1512 1513011111,5.RS,5.RT,000,2.AC,00111,111000:SPECIAL3:32::EXTRV_RS.W 1514"extrv_rs.w r<RT>, ac<AC>, r<RS>" 1515*dsp: 1516{ 1517 unsigned32 shift = GPR[RS] & 0x1f; 1518 do_w_extr (SD_, RT, AC, shift, 2); 1519} 1520 1521:function:::void:do_h_extr:int rt, int ac, int shift 1522{ 1523 int i; 1524 unsigned32 lo = DSPLO(ac); 1525 unsigned32 hi = DSPHI(ac); 1526 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo; 1527 signed64 result = (signed64)prod; 1528 signed64 value = 0xffffffffffff8000LL; 1529 result >>= shift; 1530 if (result > 0x7fff) 1531 { 1532 result = 0x7fff; 1533 DSPCR |= DSPCR_OUFLAG7; 1534 } 1535 else if (result < value) 1536 { 1537 result = value; 1538 DSPCR |= DSPCR_OUFLAG7; 1539 } 1540 GPR[rt] = EXTEND32 (result); 1541} 1542 1543011111,5.SHIFT,5.RT,000,2.AC,01110,111000:SPECIAL3:32::EXTR_S.H 1544"extr_s.h r<RT>, ac<AC>, <SHIFT>" 1545*dsp: 1546{ 1547 do_h_extr (SD_, RT, AC, SHIFT); 1548} 1549 1550011111,5.RS,5.RT,000,2.AC,01111,111000:SPECIAL3:32::EXTRV_S.H 1551"extrv_s.h r<RT>, ac<AC>, r<RS>" 1552*dsp: 1553{ 1554 unsigned32 shift = GPR[RS] & 0x1f; 1555 do_h_extr (SD_, RT, AC, shift); 1556} 1557 1558// op: 0 = EXTP, 1 = EXTPDP 1559:function:::void:do_extp:int rt, int ac, int size, int op 1560{ 1561 signed32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 1562 unsigned32 lo = DSPLO(ac); 1563 unsigned32 hi = DSPHI(ac); 1564 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo; 1565 unsigned64 result = 0; 1566 if (pos - (size + 1) >= -1) 1567 { 1568 prod >>= (pos - size); 1569 result = prod & (((unsigned64)1 << (size + 1)) - 1); 1570 DSPCR &= (~DSPCR_EFI_SMASK); 1571 if (op == 1) // EXTPDP 1572 { 1573 if (pos - (size + 1) >= 0) 1574 { 1575 DSPCR &= (~DSPCR_POS_SMASK); 1576 DSPCR |= ((pos - (size + 1)) & DSPCR_POS_MASK) << DSPCR_POS_SHIFT; 1577 } 1578 else if (pos - (size + 1) == -1) 1579 { 1580 DSPCR |= DSPCR_POS_SMASK; 1581 } 1582 } 1583 } 1584 else 1585 { 1586 DSPCR |= DSPCR_EFI; 1587 Unpredictable (); 1588 } 1589 GPR[rt] = EXTEND32 (result); 1590} 1591 1592011111,5.SIZE,5.RT,000,2.AC,00010,111000:SPECIAL3:32::EXTP 1593"extp r<RT>, ac<AC>, <SIZE>" 1594*dsp: 1595{ 1596 do_extp (SD_, RT, AC, SIZE, 0); 1597} 1598 1599011111,5.RS,5.RT,000,2.AC,00011,111000:SPECIAL3:32::EXTPV 1600"extpv r<RT>, ac<AC>, r<RS>" 1601*dsp: 1602{ 1603 unsigned32 size = GPR[RS] & 0x1f; 1604 do_extp (SD_, RT, AC, size, 0); 1605} 1606 1607011111,5.SIZE,5.RT,000,2.AC,01010,111000:SPECIAL3:32::EXTPDP 1608"extpdp r<RT>, ac<AC>, <SIZE>" 1609*dsp: 1610{ 1611 do_extp (SD_, RT, AC, SIZE, 1); 1612} 1613 1614011111,5.RS,5.RT,000,2.AC,01011,111000:SPECIAL3:32::EXTPDPV 1615"extpdpv r<RT>, ac<AC>, r<RS>" 1616*dsp: 1617{ 1618 unsigned32 size = GPR[RS] & 0x1f; 1619 do_extp (SD_, RT, AC, size, 1); 1620} 1621 1622:function:::void:do_shilo:int ac, int shift 1623{ 1624 unsigned32 lo = DSPLO(ac); 1625 unsigned32 hi = DSPHI(ac); 1626 unsigned64 prod = (((unsigned64)hi) << 32) + (unsigned64)lo; 1627 if (shift > 31) 1628 shift = shift - 64; 1629 if (shift >= 0) 1630 prod >>= shift; 1631 else 1632 prod <<= (-shift); 1633 DSPLO(ac) = EXTEND32 (prod); 1634 DSPHI(ac) = EXTEND32 (prod >> 32); 1635} 1636 1637011111,6.SHIFT6,0000,000,2.AC,11010,111000:SPECIAL3:32::SHILO 1638"shilo ac<AC>, <SHIFT6>" 1639*dsp: 1640{ 1641 do_shilo (SD_, AC, SHIFT6); 1642} 1643 1644011111,5.RS,00000,000,2.AC,11011,111000:SPECIAL3:32::SHILOV 1645"shilov ac<AC>, r<RS>" 1646*dsp: 1647{ 1648 signed32 shift = GPR[RS] & 0x3f; 1649 do_shilo (SD_, AC, shift); 1650} 1651 1652011111,5.RS,00000,000,2.AC,11111,111000:SPECIAL3:32::MTHLIP 1653"mthlip r<RS>, ac<AC>" 1654*dsp: 1655{ 1656 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 1657 DSPHI(AC) = DSPLO(AC); 1658 DSPLO(AC) = GPR[RS]; 1659 if (pos >= 32) 1660 Unpredictable (); 1661 else 1662 pos += 32; 1663 DSPCR &= (~DSPCR_POS_SMASK); 1664 DSPCR |= (pos & DSPCR_POS_MASK) << DSPCR_POS_SHIFT; 1665} 1666 1667011111,5.RS,10.MASK10,10011,111000:SPECIAL3:32::WRDSP 1668"wrdsp r<RS>":MASK10 == 1111111111 1669"wrdsp r<RS>, <MASK10>" 1670*dsp: 1671{ 1672 unsigned32 v1 = GPR[RS]; 1673 if (MASK10 & 0x1) 1674 { 1675 DSPCR &= (~DSPCR_POS_SMASK); 1676 DSPCR |= (v1 & DSPCR_POS_SMASK); 1677 } 1678 if (MASK10 & 0x2) 1679 { 1680 DSPCR &= (~DSPCR_SCOUNT_SMASK); 1681 DSPCR |= (v1 & DSPCR_SCOUNT_SMASK); 1682 } 1683 if (MASK10 & 0x4) 1684 { 1685 DSPCR &= (~DSPCR_CARRY_SMASK); 1686 DSPCR |= (v1 & DSPCR_CARRY_SMASK); 1687 } 1688 if (MASK10 & 0x8) 1689 { 1690 DSPCR &= (~DSPCR_OUFLAG_SMASK); 1691 DSPCR |= (v1 & DSPCR_OUFLAG_SMASK); 1692 } 1693 if (MASK10 & 0x10) 1694 { 1695 DSPCR &= (~DSPCR_CCOND_SMASK); 1696 DSPCR |= (v1 & DSPCR_CCOND_SMASK); 1697 } 1698 if (MASK10 & 0x20) 1699 { 1700 DSPCR &= (~DSPCR_EFI_SMASK); 1701 DSPCR |= (v1 & DSPCR_EFI_SMASK); 1702 } 1703} 1704 1705011111,10.MASK10,5.RD,10010,111000:SPECIAL3:32::RDDSP 1706"rddsp r<RD>":MASK10 == 1111111111 1707"rddsp r<RD>, <MASK10>" 1708*dsp: 1709{ 1710 unsigned32 result = 0; 1711 if (MASK10 & 0x1) 1712 { 1713 result &= (~DSPCR_POS_SMASK); 1714 result |= (DSPCR & DSPCR_POS_SMASK); 1715 } 1716 if (MASK10 & 0x2) 1717 { 1718 result &= (~DSPCR_SCOUNT_SMASK); 1719 result |= (DSPCR & DSPCR_SCOUNT_SMASK); 1720 } 1721 if (MASK10 & 0x4) 1722 { 1723 result &= (~DSPCR_CARRY_SMASK); 1724 result |= (DSPCR & DSPCR_CARRY_SMASK); 1725 } 1726 if (MASK10 & 0x8) 1727 { 1728 result &= (~DSPCR_OUFLAG_SMASK); 1729 result |= (DSPCR & DSPCR_OUFLAG_SMASK); 1730 } 1731 if (MASK10 & 0x10) 1732 { 1733 result &= (~DSPCR_CCOND_SMASK); 1734 result |= (DSPCR & DSPCR_CCOND_SMASK); 1735 } 1736 if (MASK10 & 0x20) 1737 { 1738 result &= (~DSPCR_EFI_SMASK); 1739 result |= (DSPCR & DSPCR_EFI_SMASK); 1740 } 1741 GPR[RD] = EXTEND32 (result); 1742} 1743 1744011111,5.BASE,5.INDEX,5.RD,00110,001010:SPECIAL3:32::LBUX 1745"lbux r<RD>, r<INDEX>(r<BASE>)" 1746*dsp: 1747{ 1748 GPR[RD] = do_load (SD_, AccessLength_BYTE, GPR[BASE], GPR[INDEX]); 1749} 1750 1751011111,5.BASE,5.INDEX,5.RD,00100,001010:SPECIAL3:32::LHX 1752"lhx r<RD>, r<INDEX>(r<BASE>)" 1753*dsp: 1754{ 1755 GPR[RD] = EXTEND16 (do_load (SD_, AccessLength_HALFWORD, GPR[BASE], GPR[INDEX])); 1756} 1757 1758011111,5.BASE,5.INDEX,5.RD,00000,001010:SPECIAL3:32::LWX 1759"lwx r<RD>, r<INDEX>(r<BASE>)" 1760*dsp: 1761{ 1762 GPR[RD] = EXTEND32 (do_load (SD_, AccessLength_WORD, GPR[BASE], GPR[INDEX])); 1763} 1764 1765000001,00000,11100,16.OFFSET:REGIMM:32::BPOSGE32 1766"bposge32 <OFFSET>" 1767*dsp: 1768{ 1769 unsigned32 pos = (DSPCR >> DSPCR_POS_SHIFT) & DSPCR_POS_MASK; 1770 address_word offset = EXTEND16 (OFFSET) << 2; 1771 if (pos >= 32) 1772 { 1773 DELAY_SLOT (NIA + offset); 1774 } 1775} 1776