1/* 2 * MIPS emulation for QEMU - nanoMIPS translation routines 3 * 4 * Copyright (c) 2004-2005 Jocelyn Mayer 5 * Copyright (c) 2006 Marius Groeger (FPU operations) 6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support) 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support) 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support) 9 * 10 * SPDX-License-Identifier: LGPL-2.1-or-later 11 */ 12 13/* MAJOR, P16, and P32 pools opcodes */ 14enum { 15 NM_P_ADDIU = 0x00, 16 NM_ADDIUPC = 0x01, 17 NM_MOVE_BALC = 0x02, 18 NM_P16_MV = 0x04, 19 NM_LW16 = 0x05, 20 NM_BC16 = 0x06, 21 NM_P16_SR = 0x07, 22 23 NM_POOL32A = 0x08, 24 NM_P_BAL = 0x0a, 25 NM_P16_SHIFT = 0x0c, 26 NM_LWSP16 = 0x0d, 27 NM_BALC16 = 0x0e, 28 NM_P16_4X4 = 0x0f, 29 30 NM_P_GP_W = 0x10, 31 NM_P_GP_BH = 0x11, 32 NM_P_J = 0x12, 33 NM_P16C = 0x14, 34 NM_LWGP16 = 0x15, 35 NM_P16_LB = 0x17, 36 37 NM_P48I = 0x18, 38 NM_P16_A1 = 0x1c, 39 NM_LW4X4 = 0x1d, 40 NM_P16_LH = 0x1f, 41 42 NM_P_U12 = 0x20, 43 NM_P_LS_U12 = 0x21, 44 NM_P_BR1 = 0x22, 45 NM_P16_A2 = 0x24, 46 NM_SW16 = 0x25, 47 NM_BEQZC16 = 0x26, 48 49 NM_POOL32F = 0x28, 50 NM_P_LS_S9 = 0x29, 51 NM_P_BR2 = 0x2a, 52 53 NM_P16_ADDU = 0x2c, 54 NM_SWSP16 = 0x2d, 55 NM_BNEZC16 = 0x2e, 56 NM_MOVEP = 0x2f, 57 58 NM_POOL32S = 0x30, 59 NM_P_BRI = 0x32, 60 NM_LI16 = 0x34, 61 NM_SWGP16 = 0x35, 62 NM_P16_BR = 0x36, 63 64 NM_P_LUI = 0x38, 65 NM_ANDI16 = 0x3c, 66 NM_SW4X4 = 0x3d, 67 NM_MOVEPREV = 0x3f, 68}; 69 70/* POOL32A instruction pool */ 71enum { 72 NM_POOL32A0 = 0x00, 73 NM_SPECIAL2 = 0x01, 74 NM_COP2_1 = 0x02, 75 NM_UDI = 0x03, 76 NM_POOL32A5 = 0x05, 77 NM_POOL32A7 = 0x07, 78}; 79 80/* P.GP.W instruction pool */ 81enum { 82 NM_ADDIUGP_W = 0x00, 83 NM_LWGP = 0x02, 84 NM_SWGP = 0x03, 85}; 86 87/* P48I instruction pool */ 88enum { 89 NM_LI48 = 0x00, 90 NM_ADDIU48 = 0x01, 91 NM_ADDIUGP48 = 0x02, 92 NM_ADDIUPC48 = 0x03, 93 NM_LWPC48 = 0x0b, 94 NM_SWPC48 = 0x0f, 95}; 96 97/* P.U12 instruction pool */ 98enum { 99 NM_ORI = 0x00, 100 NM_XORI = 0x01, 101 NM_ANDI = 0x02, 102 NM_P_SR = 0x03, 103 NM_SLTI = 0x04, 104 NM_SLTIU = 0x05, 105 NM_SEQI = 0x06, 106 NM_ADDIUNEG = 0x08, 107 NM_P_SHIFT = 0x0c, 108 NM_P_ROTX = 0x0d, 109 NM_P_INS = 0x0e, 110 NM_P_EXT = 0x0f, 111}; 112 113/* POOL32F instruction pool */ 114enum { 115 NM_POOL32F_0 = 0x00, 116 NM_POOL32F_3 = 0x03, 117 NM_POOL32F_5 = 0x05, 118}; 119 120/* POOL32S instruction pool */ 121enum { 122 NM_POOL32S_0 = 0x00, 123 NM_POOL32S_4 = 0x04, 124}; 125 126/* P.LUI instruction pool */ 127enum { 128 NM_LUI = 0x00, 129 NM_ALUIPC = 0x01, 130}; 131 132/* P.GP.BH instruction pool */ 133enum { 134 NM_LBGP = 0x00, 135 NM_SBGP = 0x01, 136 NM_LBUGP = 0x02, 137 NM_ADDIUGP_B = 0x03, 138 NM_P_GP_LH = 0x04, 139 NM_P_GP_SH = 0x05, 140 NM_P_GP_CP1 = 0x06, 141}; 142 143/* P.LS.U12 instruction pool */ 144enum { 145 NM_LB = 0x00, 146 NM_SB = 0x01, 147 NM_LBU = 0x02, 148 NM_P_PREFU12 = 0x03, 149 NM_LH = 0x04, 150 NM_SH = 0x05, 151 NM_LHU = 0x06, 152 NM_LWU = 0x07, 153 NM_LW = 0x08, 154 NM_SW = 0x09, 155 NM_LWC1 = 0x0a, 156 NM_SWC1 = 0x0b, 157 NM_LDC1 = 0x0e, 158 NM_SDC1 = 0x0f, 159}; 160 161/* P.LS.S9 instruction pool */ 162enum { 163 NM_P_LS_S0 = 0x00, 164 NM_P_LS_S1 = 0x01, 165 NM_P_LS_E0 = 0x02, 166 NM_P_LS_WM = 0x04, 167 NM_P_LS_UAWM = 0x05, 168}; 169 170/* P.BAL instruction pool */ 171enum { 172 NM_BC = 0x00, 173 NM_BALC = 0x01, 174}; 175 176/* P.J instruction pool */ 177enum { 178 NM_JALRC = 0x00, 179 NM_JALRC_HB = 0x01, 180 NM_P_BALRSC = 0x08, 181}; 182 183/* P.BR1 instruction pool */ 184enum { 185 NM_BEQC = 0x00, 186 NM_P_BR3A = 0x01, 187 NM_BGEC = 0x02, 188 NM_BGEUC = 0x03, 189}; 190 191/* P.BR2 instruction pool */ 192enum { 193 NM_BNEC = 0x00, 194 NM_BLTC = 0x02, 195 NM_BLTUC = 0x03, 196}; 197 198/* P.BRI instruction pool */ 199enum { 200 NM_BEQIC = 0x00, 201 NM_BBEQZC = 0x01, 202 NM_BGEIC = 0x02, 203 NM_BGEIUC = 0x03, 204 NM_BNEIC = 0x04, 205 NM_BBNEZC = 0x05, 206 NM_BLTIC = 0x06, 207 NM_BLTIUC = 0x07, 208}; 209 210/* P16.SHIFT instruction pool */ 211enum { 212 NM_SLL16 = 0x00, 213 NM_SRL16 = 0x01, 214}; 215 216/* POOL16C instruction pool */ 217enum { 218 NM_POOL16C_0 = 0x00, 219 NM_LWXS16 = 0x01, 220}; 221 222/* P16.A1 instruction pool */ 223enum { 224 NM_ADDIUR1SP = 0x01, 225}; 226 227/* P16.A2 instruction pool */ 228enum { 229 NM_ADDIUR2 = 0x00, 230 NM_P_ADDIURS5 = 0x01, 231}; 232 233/* P16.ADDU instruction pool */ 234enum { 235 NM_ADDU16 = 0x00, 236 NM_SUBU16 = 0x01, 237}; 238 239/* P16.SR instruction pool */ 240enum { 241 NM_SAVE16 = 0x00, 242 NM_RESTORE_JRC16 = 0x01, 243}; 244 245/* P16.4X4 instruction pool */ 246enum { 247 NM_ADDU4X4 = 0x00, 248 NM_MUL4X4 = 0x01, 249}; 250 251/* P16.LB instruction pool */ 252enum { 253 NM_LB16 = 0x00, 254 NM_SB16 = 0x01, 255 NM_LBU16 = 0x02, 256}; 257 258/* P16.LH instruction pool */ 259enum { 260 NM_LH16 = 0x00, 261 NM_SH16 = 0x01, 262 NM_LHU16 = 0x02, 263}; 264 265/* P.RI instruction pool */ 266enum { 267 NM_SIGRIE = 0x00, 268 NM_P_SYSCALL = 0x01, 269 NM_BREAK = 0x02, 270 NM_SDBBP = 0x03, 271}; 272 273/* POOL32A0 instruction pool */ 274enum { 275 NM_P_TRAP = 0x00, 276 NM_SEB = 0x01, 277 NM_SLLV = 0x02, 278 NM_MUL = 0x03, 279 NM_MFC0 = 0x06, 280 NM_MFHC0 = 0x07, 281 NM_SEH = 0x09, 282 NM_SRLV = 0x0a, 283 NM_MUH = 0x0b, 284 NM_MTC0 = 0x0e, 285 NM_MTHC0 = 0x0f, 286 NM_SRAV = 0x12, 287 NM_MULU = 0x13, 288 NM_ROTRV = 0x1a, 289 NM_MUHU = 0x1b, 290 NM_ADD = 0x22, 291 NM_DIV = 0x23, 292 NM_ADDU = 0x2a, 293 NM_MOD = 0x2b, 294 NM_SUB = 0x32, 295 NM_DIVU = 0x33, 296 NM_RDHWR = 0x38, 297 NM_SUBU = 0x3a, 298 NM_MODU = 0x3b, 299 NM_P_CMOVE = 0x42, 300 NM_FORK = 0x45, 301 NM_MFTR = 0x46, 302 NM_MFHTR = 0x47, 303 NM_AND = 0x4a, 304 NM_YIELD = 0x4d, 305 NM_MTTR = 0x4e, 306 NM_MTHTR = 0x4f, 307 NM_OR = 0x52, 308 NM_D_E_MT_VPE = 0x56, 309 NM_NOR = 0x5a, 310 NM_XOR = 0x62, 311 NM_SLT = 0x6a, 312 NM_P_SLTU = 0x72, 313 NM_SOV = 0x7a, 314}; 315 316/* CRC32 instruction pool */ 317enum { 318 NM_CRC32B = 0x00, 319 NM_CRC32H = 0x01, 320 NM_CRC32W = 0x02, 321 NM_CRC32CB = 0x04, 322 NM_CRC32CH = 0x05, 323 NM_CRC32CW = 0x06, 324}; 325 326/* POOL32A5 instruction pool */ 327enum { 328 NM_CMP_EQ_PH = 0x00, 329 NM_CMP_LT_PH = 0x08, 330 NM_CMP_LE_PH = 0x10, 331 NM_CMPGU_EQ_QB = 0x18, 332 NM_CMPGU_LT_QB = 0x20, 333 NM_CMPGU_LE_QB = 0x28, 334 NM_CMPGDU_EQ_QB = 0x30, 335 NM_CMPGDU_LT_QB = 0x38, 336 NM_CMPGDU_LE_QB = 0x40, 337 NM_CMPU_EQ_QB = 0x48, 338 NM_CMPU_LT_QB = 0x50, 339 NM_CMPU_LE_QB = 0x58, 340 NM_ADDQ_S_W = 0x60, 341 NM_SUBQ_S_W = 0x68, 342 NM_ADDSC = 0x70, 343 NM_ADDWC = 0x78, 344 345 NM_ADDQ_S_PH = 0x01, 346 NM_ADDQH_R_PH = 0x09, 347 NM_ADDQH_R_W = 0x11, 348 NM_ADDU_S_QB = 0x19, 349 NM_ADDU_S_PH = 0x21, 350 NM_ADDUH_R_QB = 0x29, 351 NM_SHRAV_R_PH = 0x31, 352 NM_SHRAV_R_QB = 0x39, 353 NM_SUBQ_S_PH = 0x41, 354 NM_SUBQH_R_PH = 0x49, 355 NM_SUBQH_R_W = 0x51, 356 NM_SUBU_S_QB = 0x59, 357 NM_SUBU_S_PH = 0x61, 358 NM_SUBUH_R_QB = 0x69, 359 NM_SHLLV_S_PH = 0x71, 360 NM_PRECR_SRA_R_PH_W = 0x79, 361 362 NM_MULEU_S_PH_QBL = 0x12, 363 NM_MULEU_S_PH_QBR = 0x1a, 364 NM_MULQ_RS_PH = 0x22, 365 NM_MULQ_S_PH = 0x2a, 366 NM_MULQ_RS_W = 0x32, 367 NM_MULQ_S_W = 0x3a, 368 NM_APPEND = 0x42, 369 NM_MODSUB = 0x52, 370 NM_SHRAV_R_W = 0x5a, 371 NM_SHRLV_PH = 0x62, 372 NM_SHRLV_QB = 0x6a, 373 NM_SHLLV_QB = 0x72, 374 NM_SHLLV_S_W = 0x7a, 375 376 NM_SHILO = 0x03, 377 378 NM_MULEQ_S_W_PHL = 0x04, 379 NM_MULEQ_S_W_PHR = 0x0c, 380 381 NM_MUL_S_PH = 0x05, 382 NM_PRECR_QB_PH = 0x0d, 383 NM_PRECRQ_QB_PH = 0x15, 384 NM_PRECRQ_PH_W = 0x1d, 385 NM_PRECRQ_RS_PH_W = 0x25, 386 NM_PRECRQU_S_QB_PH = 0x2d, 387 NM_PACKRL_PH = 0x35, 388 NM_PICK_QB = 0x3d, 389 NM_PICK_PH = 0x45, 390 391 NM_SHRA_R_W = 0x5e, 392 NM_SHRA_R_PH = 0x66, 393 NM_SHLL_S_PH = 0x76, 394 NM_SHLL_S_W = 0x7e, 395 396 NM_REPL_PH = 0x07 397}; 398 399/* POOL32A7 instruction pool */ 400enum { 401 NM_P_LSX = 0x00, 402 NM_LSA = 0x01, 403 NM_EXTW = 0x03, 404 NM_POOL32AXF = 0x07, 405}; 406 407/* P.SR instruction pool */ 408enum { 409 NM_PP_SR = 0x00, 410 NM_P_SR_F = 0x01, 411}; 412 413/* P.SHIFT instruction pool */ 414enum { 415 NM_P_SLL = 0x00, 416 NM_SRL = 0x02, 417 NM_SRA = 0x04, 418 NM_ROTR = 0x06, 419}; 420 421/* P.ROTX instruction pool */ 422enum { 423 NM_ROTX = 0x00, 424}; 425 426/* P.INS instruction pool */ 427enum { 428 NM_INS = 0x00, 429}; 430 431/* P.EXT instruction pool */ 432enum { 433 NM_EXT = 0x00, 434}; 435 436/* POOL32F_0 (fmt) instruction pool */ 437enum { 438 NM_RINT_S = 0x04, 439 NM_RINT_D = 0x44, 440 NM_ADD_S = 0x06, 441 NM_SELEQZ_S = 0x07, 442 NM_SELEQZ_D = 0x47, 443 NM_CLASS_S = 0x0c, 444 NM_CLASS_D = 0x4c, 445 NM_SUB_S = 0x0e, 446 NM_SELNEZ_S = 0x0f, 447 NM_SELNEZ_D = 0x4f, 448 NM_MUL_S = 0x16, 449 NM_SEL_S = 0x17, 450 NM_SEL_D = 0x57, 451 NM_DIV_S = 0x1e, 452 NM_ADD_D = 0x26, 453 NM_SUB_D = 0x2e, 454 NM_MUL_D = 0x36, 455 NM_MADDF_S = 0x37, 456 NM_MADDF_D = 0x77, 457 NM_DIV_D = 0x3e, 458 NM_MSUBF_S = 0x3f, 459 NM_MSUBF_D = 0x7f, 460}; 461 462/* POOL32F_3 instruction pool */ 463enum { 464 NM_MIN_FMT = 0x00, 465 NM_MAX_FMT = 0x01, 466 NM_MINA_FMT = 0x04, 467 NM_MAXA_FMT = 0x05, 468 NM_POOL32FXF = 0x07, 469}; 470 471/* POOL32F_5 instruction pool */ 472enum { 473 NM_CMP_CONDN_S = 0x00, 474 NM_CMP_CONDN_D = 0x02, 475}; 476 477/* P.GP.LH instruction pool */ 478enum { 479 NM_LHGP = 0x00, 480 NM_LHUGP = 0x01, 481}; 482 483/* P.GP.SH instruction pool */ 484enum { 485 NM_SHGP = 0x00, 486}; 487 488/* P.GP.CP1 instruction pool */ 489enum { 490 NM_LWC1GP = 0x00, 491 NM_SWC1GP = 0x01, 492 NM_LDC1GP = 0x02, 493 NM_SDC1GP = 0x03, 494}; 495 496/* P.LS.S0 instruction pool */ 497enum { 498 NM_LBS9 = 0x00, 499 NM_LHS9 = 0x04, 500 NM_LWS9 = 0x08, 501 NM_LDS9 = 0x0c, 502 503 NM_SBS9 = 0x01, 504 NM_SHS9 = 0x05, 505 NM_SWS9 = 0x09, 506 NM_SDS9 = 0x0d, 507 508 NM_LBUS9 = 0x02, 509 NM_LHUS9 = 0x06, 510 NM_LWC1S9 = 0x0a, 511 NM_LDC1S9 = 0x0e, 512 513 NM_P_PREFS9 = 0x03, 514 NM_LWUS9 = 0x07, 515 NM_SWC1S9 = 0x0b, 516 NM_SDC1S9 = 0x0f, 517}; 518 519/* P.LS.S1 instruction pool */ 520enum { 521 NM_ASET_ACLR = 0x02, 522 NM_UALH = 0x04, 523 NM_UASH = 0x05, 524 NM_CACHE = 0x07, 525 NM_P_LL = 0x0a, 526 NM_P_SC = 0x0b, 527}; 528 529/* P.LS.E0 instruction pool */ 530enum { 531 NM_LBE = 0x00, 532 NM_SBE = 0x01, 533 NM_LBUE = 0x02, 534 NM_P_PREFE = 0x03, 535 NM_LHE = 0x04, 536 NM_SHE = 0x05, 537 NM_LHUE = 0x06, 538 NM_CACHEE = 0x07, 539 NM_LWE = 0x08, 540 NM_SWE = 0x09, 541 NM_P_LLE = 0x0a, 542 NM_P_SCE = 0x0b, 543}; 544 545/* P.PREFE instruction pool */ 546enum { 547 NM_SYNCIE = 0x00, 548 NM_PREFE = 0x01, 549}; 550 551/* P.LLE instruction pool */ 552enum { 553 NM_LLE = 0x00, 554 NM_LLWPE = 0x01, 555}; 556 557/* P.SCE instruction pool */ 558enum { 559 NM_SCE = 0x00, 560 NM_SCWPE = 0x01, 561}; 562 563/* P.LS.WM instruction pool */ 564enum { 565 NM_LWM = 0x00, 566 NM_SWM = 0x01, 567}; 568 569/* P.LS.UAWM instruction pool */ 570enum { 571 NM_UALWM = 0x00, 572 NM_UASWM = 0x01, 573}; 574 575/* P.BR3A instruction pool */ 576enum { 577 NM_BC1EQZC = 0x00, 578 NM_BC1NEZC = 0x01, 579 NM_BC2EQZC = 0x02, 580 NM_BC2NEZC = 0x03, 581 NM_BPOSGE32C = 0x04, 582}; 583 584/* P16.RI instruction pool */ 585enum { 586 NM_P16_SYSCALL = 0x01, 587 NM_BREAK16 = 0x02, 588 NM_SDBBP16 = 0x03, 589}; 590 591/* POOL16C_0 instruction pool */ 592enum { 593 NM_POOL16C_00 = 0x00, 594}; 595 596/* P16.JRC instruction pool */ 597enum { 598 NM_JRC = 0x00, 599 NM_JALRC16 = 0x01, 600}; 601 602/* P.SYSCALL instruction pool */ 603enum { 604 NM_SYSCALL = 0x00, 605 NM_HYPCALL = 0x01, 606}; 607 608/* P.TRAP instruction pool */ 609enum { 610 NM_TEQ = 0x00, 611 NM_TNE = 0x01, 612}; 613 614/* P.CMOVE instruction pool */ 615enum { 616 NM_MOVZ = 0x00, 617 NM_MOVN = 0x01, 618}; 619 620/* POOL32Axf instruction pool */ 621enum { 622 NM_POOL32AXF_1 = 0x01, 623 NM_POOL32AXF_2 = 0x02, 624 NM_POOL32AXF_4 = 0x04, 625 NM_POOL32AXF_5 = 0x05, 626 NM_POOL32AXF_7 = 0x07, 627}; 628 629/* POOL32Axf_1 instruction pool */ 630enum { 631 NM_POOL32AXF_1_0 = 0x00, 632 NM_POOL32AXF_1_1 = 0x01, 633 NM_POOL32AXF_1_3 = 0x03, 634 NM_POOL32AXF_1_4 = 0x04, 635 NM_POOL32AXF_1_5 = 0x05, 636 NM_POOL32AXF_1_7 = 0x07, 637}; 638 639/* POOL32Axf_2 instruction pool */ 640enum { 641 NM_POOL32AXF_2_0_7 = 0x00, 642 NM_POOL32AXF_2_8_15 = 0x01, 643 NM_POOL32AXF_2_16_23 = 0x02, 644 NM_POOL32AXF_2_24_31 = 0x03, 645}; 646 647/* POOL32Axf_7 instruction pool */ 648enum { 649 NM_SHRA_R_QB = 0x0, 650 NM_SHRL_PH = 0x1, 651 NM_REPL_QB = 0x2, 652}; 653 654/* POOL32Axf_1_0 instruction pool */ 655enum { 656 NM_MFHI = 0x0, 657 NM_MFLO = 0x1, 658 NM_MTHI = 0x2, 659 NM_MTLO = 0x3, 660}; 661 662/* POOL32Axf_1_1 instruction pool */ 663enum { 664 NM_MTHLIP = 0x0, 665 NM_SHILOV = 0x1, 666}; 667 668/* POOL32Axf_1_3 instruction pool */ 669enum { 670 NM_RDDSP = 0x0, 671 NM_WRDSP = 0x1, 672 NM_EXTP = 0x2, 673 NM_EXTPDP = 0x3, 674}; 675 676/* POOL32Axf_1_4 instruction pool */ 677enum { 678 NM_SHLL_QB = 0x0, 679 NM_SHRL_QB = 0x1, 680}; 681 682/* POOL32Axf_1_5 instruction pool */ 683enum { 684 NM_MAQ_S_W_PHR = 0x0, 685 NM_MAQ_S_W_PHL = 0x1, 686 NM_MAQ_SA_W_PHR = 0x2, 687 NM_MAQ_SA_W_PHL = 0x3, 688}; 689 690/* POOL32Axf_1_7 instruction pool */ 691enum { 692 NM_EXTR_W = 0x0, 693 NM_EXTR_R_W = 0x1, 694 NM_EXTR_RS_W = 0x2, 695 NM_EXTR_S_H = 0x3, 696}; 697 698/* POOL32Axf_2_0_7 instruction pool */ 699enum { 700 NM_DPA_W_PH = 0x0, 701 NM_DPAQ_S_W_PH = 0x1, 702 NM_DPS_W_PH = 0x2, 703 NM_DPSQ_S_W_PH = 0x3, 704 NM_BALIGN = 0x4, 705 NM_MADD = 0x5, 706 NM_MULT = 0x6, 707 NM_EXTRV_W = 0x7, 708}; 709 710/* POOL32Axf_2_8_15 instruction pool */ 711enum { 712 NM_DPAX_W_PH = 0x0, 713 NM_DPAQ_SA_L_W = 0x1, 714 NM_DPSX_W_PH = 0x2, 715 NM_DPSQ_SA_L_W = 0x3, 716 NM_MADDU = 0x5, 717 NM_MULTU = 0x6, 718 NM_EXTRV_R_W = 0x7, 719}; 720 721/* POOL32Axf_2_16_23 instruction pool */ 722enum { 723 NM_DPAU_H_QBL = 0x0, 724 NM_DPAQX_S_W_PH = 0x1, 725 NM_DPSU_H_QBL = 0x2, 726 NM_DPSQX_S_W_PH = 0x3, 727 NM_EXTPV = 0x4, 728 NM_MSUB = 0x5, 729 NM_MULSA_W_PH = 0x6, 730 NM_EXTRV_RS_W = 0x7, 731}; 732 733/* POOL32Axf_2_24_31 instruction pool */ 734enum { 735 NM_DPAU_H_QBR = 0x0, 736 NM_DPAQX_SA_W_PH = 0x1, 737 NM_DPSU_H_QBR = 0x2, 738 NM_DPSQX_SA_W_PH = 0x3, 739 NM_EXTPDPV = 0x4, 740 NM_MSUBU = 0x5, 741 NM_MULSAQ_S_W_PH = 0x6, 742 NM_EXTRV_S_H = 0x7, 743}; 744 745/* POOL32Axf_{4, 5} instruction pool */ 746enum { 747 NM_CLO = 0x25, 748 NM_CLZ = 0x2d, 749 750 NM_TLBP = 0x01, 751 NM_TLBR = 0x09, 752 NM_TLBWI = 0x11, 753 NM_TLBWR = 0x19, 754 NM_TLBINV = 0x03, 755 NM_TLBINVF = 0x0b, 756 NM_DI = 0x23, 757 NM_EI = 0x2b, 758 NM_RDPGPR = 0x70, 759 NM_WRPGPR = 0x78, 760 NM_WAIT = 0x61, 761 NM_DERET = 0x71, 762 NM_ERETX = 0x79, 763 764 /* nanoMIPS DSP instructions */ 765 NM_ABSQ_S_QB = 0x00, 766 NM_ABSQ_S_PH = 0x08, 767 NM_ABSQ_S_W = 0x10, 768 NM_PRECEQ_W_PHL = 0x28, 769 NM_PRECEQ_W_PHR = 0x30, 770 NM_PRECEQU_PH_QBL = 0x38, 771 NM_PRECEQU_PH_QBR = 0x48, 772 NM_PRECEU_PH_QBL = 0x58, 773 NM_PRECEU_PH_QBR = 0x68, 774 NM_PRECEQU_PH_QBLA = 0x39, 775 NM_PRECEQU_PH_QBRA = 0x49, 776 NM_PRECEU_PH_QBLA = 0x59, 777 NM_PRECEU_PH_QBRA = 0x69, 778 NM_REPLV_PH = 0x01, 779 NM_REPLV_QB = 0x09, 780 NM_BITREV = 0x18, 781 NM_INSV = 0x20, 782 NM_RADDU_W_QB = 0x78, 783 784 NM_BITSWAP = 0x05, 785 NM_WSBH = 0x3d, 786}; 787 788/* PP.SR instruction pool */ 789enum { 790 NM_SAVE = 0x00, 791 NM_RESTORE = 0x02, 792 NM_RESTORE_JRC = 0x03, 793}; 794 795/* P.SR.F instruction pool */ 796enum { 797 NM_SAVEF = 0x00, 798 NM_RESTOREF = 0x01, 799}; 800 801/* P16.SYSCALL instruction pool */ 802enum { 803 NM_SYSCALL16 = 0x00, 804 NM_HYPCALL16 = 0x01, 805}; 806 807/* POOL16C_00 instruction pool */ 808enum { 809 NM_NOT16 = 0x00, 810 NM_XOR16 = 0x01, 811 NM_AND16 = 0x02, 812 NM_OR16 = 0x03, 813}; 814 815/* PP.LSX and PP.LSXS instruction pool */ 816enum { 817 NM_LBX = 0x00, 818 NM_LHX = 0x04, 819 NM_LWX = 0x08, 820 NM_LDX = 0x0c, 821 822 NM_SBX = 0x01, 823 NM_SHX = 0x05, 824 NM_SWX = 0x09, 825 NM_SDX = 0x0d, 826 827 NM_LBUX = 0x02, 828 NM_LHUX = 0x06, 829 NM_LWC1X = 0x0a, 830 NM_LDC1X = 0x0e, 831 832 NM_LWUX = 0x07, 833 NM_SWC1X = 0x0b, 834 NM_SDC1X = 0x0f, 835 836 NM_LHXS = 0x04, 837 NM_LWXS = 0x08, 838 NM_LDXS = 0x0c, 839 840 NM_SHXS = 0x05, 841 NM_SWXS = 0x09, 842 NM_SDXS = 0x0d, 843 844 NM_LHUXS = 0x06, 845 NM_LWC1XS = 0x0a, 846 NM_LDC1XS = 0x0e, 847 848 NM_LWUXS = 0x07, 849 NM_SWC1XS = 0x0b, 850 NM_SDC1XS = 0x0f, 851}; 852 853/* ERETx instruction pool */ 854enum { 855 NM_ERET = 0x00, 856 NM_ERETNC = 0x01, 857}; 858 859/* POOL32FxF_{0, 1} insturction pool */ 860enum { 861 NM_CFC1 = 0x40, 862 NM_CTC1 = 0x60, 863 NM_MFC1 = 0x80, 864 NM_MTC1 = 0xa0, 865 NM_MFHC1 = 0xc0, 866 NM_MTHC1 = 0xe0, 867 868 NM_CVT_S_PL = 0x84, 869 NM_CVT_S_PU = 0xa4, 870 871 NM_CVT_L_S = 0x004, 872 NM_CVT_L_D = 0x104, 873 NM_CVT_W_S = 0x024, 874 NM_CVT_W_D = 0x124, 875 876 NM_RSQRT_S = 0x008, 877 NM_RSQRT_D = 0x108, 878 879 NM_SQRT_S = 0x028, 880 NM_SQRT_D = 0x128, 881 882 NM_RECIP_S = 0x048, 883 NM_RECIP_D = 0x148, 884 885 NM_FLOOR_L_S = 0x00c, 886 NM_FLOOR_L_D = 0x10c, 887 888 NM_FLOOR_W_S = 0x02c, 889 NM_FLOOR_W_D = 0x12c, 890 891 NM_CEIL_L_S = 0x04c, 892 NM_CEIL_L_D = 0x14c, 893 NM_CEIL_W_S = 0x06c, 894 NM_CEIL_W_D = 0x16c, 895 NM_TRUNC_L_S = 0x08c, 896 NM_TRUNC_L_D = 0x18c, 897 NM_TRUNC_W_S = 0x0ac, 898 NM_TRUNC_W_D = 0x1ac, 899 NM_ROUND_L_S = 0x0cc, 900 NM_ROUND_L_D = 0x1cc, 901 NM_ROUND_W_S = 0x0ec, 902 NM_ROUND_W_D = 0x1ec, 903 904 NM_MOV_S = 0x01, 905 NM_MOV_D = 0x81, 906 NM_ABS_S = 0x0d, 907 NM_ABS_D = 0x8d, 908 NM_NEG_S = 0x2d, 909 NM_NEG_D = 0xad, 910 NM_CVT_D_S = 0x04d, 911 NM_CVT_D_W = 0x0cd, 912 NM_CVT_D_L = 0x14d, 913 NM_CVT_S_D = 0x06d, 914 NM_CVT_S_W = 0x0ed, 915 NM_CVT_S_L = 0x16d, 916}; 917 918/* P.LL instruction pool */ 919enum { 920 NM_LL = 0x00, 921 NM_LLWP = 0x01, 922}; 923 924/* P.SC instruction pool */ 925enum { 926 NM_SC = 0x00, 927 NM_SCWP = 0x01, 928}; 929 930/* P.DVP instruction pool */ 931enum { 932 NM_DVP = 0x00, 933 NM_EVP = 0x01, 934}; 935 936 937/* 938 * 939 * nanoMIPS decoding engine 940 * 941 */ 942 943 944/* extraction utilities */ 945 946#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7) 947#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7) 948#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7) 949#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f) 950#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f) 951 952/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */ 953static inline int decode_gpr_gpr3(int r) 954{ 955 static const int map[] = { 16, 17, 18, 19, 4, 5, 6, 7 }; 956 957 return map[r & 0x7]; 958} 959 960/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */ 961static inline int decode_gpr_gpr3_src_store(int r) 962{ 963 static const int map[] = { 0, 17, 18, 19, 4, 5, 6, 7 }; 964 965 return map[r & 0x7]; 966} 967 968/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */ 969static inline int decode_gpr_gpr4(int r) 970{ 971 static const int map[] = { 8, 9, 10, 11, 4, 5, 6, 7, 972 16, 17, 18, 19, 20, 21, 22, 23 }; 973 974 return map[r & 0xf]; 975} 976 977/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */ 978static inline int decode_gpr_gpr4_zero(int r) 979{ 980 static const int map[] = { 8, 9, 10, 0, 4, 5, 6, 7, 981 16, 17, 18, 19, 20, 21, 22, 23 }; 982 983 return map[r & 0xf]; 984} 985 986static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt, 987 int shift) 988{ 989 gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift); 990} 991 992static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset, 993 uint32_t reg1, uint32_t reg2) 994{ 995 TCGv taddr = tcg_temp_new(); 996 TCGv_i64 tval = tcg_temp_new_i64(); 997 TCGv tmp1 = tcg_temp_new(); 998 TCGv tmp2 = tcg_temp_new(); 999 1000 gen_base_offset_addr(ctx, taddr, base, offset); 1001 tcg_gen_qemu_ld_i64(tval, taddr, ctx->mem_idx, 1002 mo_endian(ctx) | MO_UQ | MO_ALIGN); 1003 if (disas_is_bigendian(ctx)) { 1004 tcg_gen_extr_i64_tl(tmp2, tmp1, tval); 1005 } else { 1006 tcg_gen_extr_i64_tl(tmp1, tmp2, tval); 1007 } 1008 gen_store_gpr(tmp1, reg1); 1009 gen_store_gpr(tmp2, reg2); 1010 tcg_gen_st_i64(tval, tcg_env, offsetof(CPUMIPSState, llval_wp)); 1011 tcg_gen_st_tl(taddr, tcg_env, offsetof(CPUMIPSState, lladdr)); 1012} 1013 1014static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset, 1015 uint32_t reg1, uint32_t reg2, bool eva) 1016{ 1017 TCGv taddr = tcg_temp_new(); 1018 TCGv lladdr = tcg_temp_new(); 1019 TCGv_i64 tval = tcg_temp_new_i64(); 1020 TCGv_i64 llval = tcg_temp_new_i64(); 1021 TCGv_i64 val = tcg_temp_new_i64(); 1022 TCGv tmp1 = tcg_temp_new(); 1023 TCGv tmp2 = tcg_temp_new(); 1024 TCGLabel *lab_fail = gen_new_label(); 1025 TCGLabel *lab_done = gen_new_label(); 1026 1027 gen_base_offset_addr(ctx, taddr, base, offset); 1028 1029 tcg_gen_ld_tl(lladdr, tcg_env, offsetof(CPUMIPSState, lladdr)); 1030 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail); 1031 1032 gen_load_gpr(tmp1, reg1); 1033 gen_load_gpr(tmp2, reg2); 1034 1035 if (disas_is_bigendian(ctx)) { 1036 tcg_gen_concat_tl_i64(tval, tmp2, tmp1); 1037 } else { 1038 tcg_gen_concat_tl_i64(tval, tmp1, tmp2); 1039 } 1040 1041 tcg_gen_ld_i64(llval, tcg_env, offsetof(CPUMIPSState, llval_wp)); 1042 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval, 1043 eva ? MIPS_HFLAG_UM : ctx->mem_idx, 1044 MO_64 | MO_ALIGN); 1045 if (reg1 != 0) { 1046 tcg_gen_movi_tl(cpu_gpr[reg1], 1); 1047 } 1048 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done); 1049 1050 gen_set_label(lab_fail); 1051 1052 if (reg1 != 0) { 1053 tcg_gen_movi_tl(cpu_gpr[reg1], 0); 1054 } 1055 gen_set_label(lab_done); 1056 tcg_gen_st_tl(tcg_constant_tl(-1), tcg_env, offsetof(CPUMIPSState, lladdr)); 1057} 1058 1059static void gen_adjust_sp(DisasContext *ctx, int u) 1060{ 1061 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u); 1062} 1063 1064static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count, 1065 uint8_t gp, uint16_t u) 1066{ 1067 int counter = 0; 1068 TCGv va = tcg_temp_new(); 1069 TCGv t0 = tcg_temp_new(); 1070 1071 while (counter != count) { 1072 bool use_gp = gp && (counter == count - 1); 1073 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f); 1074 int this_offset = -((counter + 1) << 2); 1075 gen_base_offset_addr(ctx, va, 29, this_offset); 1076 gen_load_gpr(t0, this_rt); 1077 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx, 1078 mo_endian(ctx) | MO_UL | ctx->default_tcg_memop_mask); 1079 counter++; 1080 } 1081 1082 /* adjust stack pointer */ 1083 gen_adjust_sp(ctx, -u); 1084} 1085 1086static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count, 1087 uint8_t gp, uint16_t u) 1088{ 1089 int counter = 0; 1090 TCGv va = tcg_temp_new(); 1091 TCGv t0 = tcg_temp_new(); 1092 1093 while (counter != count) { 1094 bool use_gp = gp && (counter == count - 1); 1095 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f); 1096 int this_offset = u - ((counter + 1) << 2); 1097 gen_base_offset_addr(ctx, va, 29, this_offset); 1098 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, 1099 mo_endian(ctx) | MO_SL | ctx->default_tcg_memop_mask); 1100 tcg_gen_ext32s_tl(t0, t0); 1101 gen_store_gpr(t0, this_rt); 1102 counter++; 1103 } 1104 1105 /* adjust stack pointer */ 1106 gen_adjust_sp(ctx, u); 1107} 1108 1109static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc, 1110 int insn_bytes, 1111 int rs, int rt, int32_t offset) 1112{ 1113 target_ulong btgt = -1; 1114 int bcond_compute = 0; 1115 TCGv t0 = tcg_temp_new(); 1116 TCGv t1 = tcg_temp_new(); 1117 1118 /* Load needed operands */ 1119 switch (opc) { 1120 case OPC_BEQ: 1121 case OPC_BNE: 1122 /* Compare two registers */ 1123 if (rs != rt) { 1124 gen_load_gpr(t0, rs); 1125 gen_load_gpr(t1, rt); 1126 bcond_compute = 1; 1127 } 1128 btgt = ctx->base.pc_next + insn_bytes + offset; 1129 break; 1130 case OPC_BGEZAL: 1131 /* Compare to zero */ 1132 if (rs != 0) { 1133 gen_load_gpr(t0, rs); 1134 bcond_compute = 1; 1135 } 1136 btgt = ctx->base.pc_next + insn_bytes + offset; 1137 break; 1138 case OPC_BPOSGE32: 1139 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 1140 bcond_compute = 1; 1141 btgt = ctx->base.pc_next + insn_bytes + offset; 1142 break; 1143 case OPC_JR: 1144 case OPC_JALR: 1145 /* Jump to register */ 1146 if (offset != 0 && offset != 16) { 1147 /* 1148 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 1149 * others are reserved. 1150 */ 1151 MIPS_INVAL("jump hint"); 1152 gen_reserved_instruction(ctx); 1153 goto out; 1154 } 1155 gen_load_gpr(btarget, rs); 1156 break; 1157 default: 1158 MIPS_INVAL("branch/jump"); 1159 gen_reserved_instruction(ctx); 1160 goto out; 1161 } 1162 if (bcond_compute == 0) { 1163 /* No condition to be computed */ 1164 switch (opc) { 1165 case OPC_BEQ: /* rx == rx */ 1166 /* Always take */ 1167 ctx->hflags |= MIPS_HFLAG_B; 1168 break; 1169 case OPC_BGEZAL: /* 0 >= 0 */ 1170 /* Always take and link */ 1171 tcg_gen_movi_tl(cpu_gpr[31], 1172 ctx->base.pc_next + insn_bytes); 1173 ctx->hflags |= MIPS_HFLAG_B; 1174 break; 1175 case OPC_BNE: /* rx != rx */ 1176 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 1177 /* Skip the instruction in the delay slot */ 1178 ctx->base.pc_next += 4; 1179 goto out; 1180 case OPC_JR: 1181 ctx->hflags |= MIPS_HFLAG_BR; 1182 break; 1183 case OPC_JALR: 1184 if (rt > 0) { 1185 tcg_gen_movi_tl(cpu_gpr[rt], 1186 ctx->base.pc_next + insn_bytes); 1187 } 1188 ctx->hflags |= MIPS_HFLAG_BR; 1189 break; 1190 default: 1191 MIPS_INVAL("branch/jump"); 1192 gen_reserved_instruction(ctx); 1193 goto out; 1194 } 1195 } else { 1196 switch (opc) { 1197 case OPC_BEQ: 1198 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 1199 goto not_likely; 1200 case OPC_BNE: 1201 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 1202 goto not_likely; 1203 case OPC_BGEZAL: 1204 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 1205 tcg_gen_movi_tl(cpu_gpr[31], 1206 ctx->base.pc_next + insn_bytes); 1207 goto not_likely; 1208 case OPC_BPOSGE32: 1209 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 1210 not_likely: 1211 ctx->hflags |= MIPS_HFLAG_BC; 1212 break; 1213 default: 1214 MIPS_INVAL("conditional branch/jump"); 1215 gen_reserved_instruction(ctx); 1216 goto out; 1217 } 1218 } 1219 1220 ctx->btarget = btgt; 1221 1222 out: 1223 if (insn_bytes == 2) { 1224 ctx->hflags |= MIPS_HFLAG_B16; 1225 } 1226} 1227 1228static void gen_pool16c_nanomips_insn(DisasContext *ctx) 1229{ 1230 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); 1231 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 1232 1233 switch (extract32(ctx->opcode, 2, 2)) { 1234 case NM_NOT16: 1235 gen_logic(ctx, OPC_NOR, rt, rs, 0); 1236 break; 1237 case NM_AND16: 1238 gen_logic(ctx, OPC_AND, rt, rt, rs); 1239 break; 1240 case NM_XOR16: 1241 gen_logic(ctx, OPC_XOR, rt, rt, rs); 1242 break; 1243 case NM_OR16: 1244 gen_logic(ctx, OPC_OR, rt, rt, rs); 1245 break; 1246 } 1247} 1248 1249static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) 1250{ 1251 int rt = extract32(ctx->opcode, 21, 5); 1252 int rs = extract32(ctx->opcode, 16, 5); 1253 int rd = extract32(ctx->opcode, 11, 5); 1254 1255 switch (extract32(ctx->opcode, 3, 7)) { 1256 case NM_P_TRAP: 1257 switch (extract32(ctx->opcode, 10, 1)) { 1258 case NM_TEQ: 1259 check_nms(ctx); 1260 gen_trap(ctx, OPC_TEQ, rs, rt, -1, rd); 1261 break; 1262 case NM_TNE: 1263 check_nms(ctx); 1264 gen_trap(ctx, OPC_TNE, rs, rt, -1, rd); 1265 break; 1266 } 1267 break; 1268 case NM_RDHWR: 1269 check_nms(ctx); 1270 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); 1271 break; 1272 case NM_SEB: 1273 check_nms(ctx); 1274 gen_bshfl(ctx, OPC_SEB, rs, rt); 1275 break; 1276 case NM_SEH: 1277 gen_bshfl(ctx, OPC_SEH, rs, rt); 1278 break; 1279 case NM_SLLV: 1280 gen_shift(ctx, OPC_SLLV, rd, rt, rs); 1281 break; 1282 case NM_SRLV: 1283 gen_shift(ctx, OPC_SRLV, rd, rt, rs); 1284 break; 1285 case NM_SRAV: 1286 gen_shift(ctx, OPC_SRAV, rd, rt, rs); 1287 break; 1288 case NM_ROTRV: 1289 gen_shift(ctx, OPC_ROTRV, rd, rt, rs); 1290 break; 1291 case NM_ADD: 1292 gen_arith(ctx, OPC_ADD, rd, rs, rt); 1293 break; 1294 case NM_ADDU: 1295 gen_arith(ctx, OPC_ADDU, rd, rs, rt); 1296 break; 1297 case NM_SUB: 1298 check_nms(ctx); 1299 gen_arith(ctx, OPC_SUB, rd, rs, rt); 1300 break; 1301 case NM_SUBU: 1302 gen_arith(ctx, OPC_SUBU, rd, rs, rt); 1303 break; 1304 case NM_P_CMOVE: 1305 switch (extract32(ctx->opcode, 10, 1)) { 1306 case NM_MOVZ: 1307 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); 1308 break; 1309 case NM_MOVN: 1310 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); 1311 break; 1312 } 1313 break; 1314 case NM_AND: 1315 gen_logic(ctx, OPC_AND, rd, rs, rt); 1316 break; 1317 case NM_OR: 1318 gen_logic(ctx, OPC_OR, rd, rs, rt); 1319 break; 1320 case NM_NOR: 1321 gen_logic(ctx, OPC_NOR, rd, rs, rt); 1322 break; 1323 case NM_XOR: 1324 gen_logic(ctx, OPC_XOR, rd, rs, rt); 1325 break; 1326 case NM_SLT: 1327 gen_slt(ctx, OPC_SLT, rd, rs, rt); 1328 break; 1329 case NM_P_SLTU: 1330 if (rd == 0) { 1331 /* P_DVP */ 1332#ifndef CONFIG_USER_ONLY 1333 TCGv t0 = tcg_temp_new(); 1334 switch (extract32(ctx->opcode, 10, 1)) { 1335 case NM_DVP: 1336 if (ctx->vp) { 1337 check_cp0_enabled(ctx); 1338 gen_helper_dvp(t0, tcg_env); 1339 gen_store_gpr(t0, rt); 1340 } 1341 break; 1342 case NM_EVP: 1343 if (ctx->vp) { 1344 check_cp0_enabled(ctx); 1345 gen_helper_evp(t0, tcg_env); 1346 gen_store_gpr(t0, rt); 1347 } 1348 break; 1349 } 1350#endif 1351 } else { 1352 gen_slt(ctx, OPC_SLTU, rd, rs, rt); 1353 } 1354 break; 1355 case NM_SOV: 1356 { 1357 TCGv t0 = tcg_temp_new(); 1358 TCGv t1 = tcg_temp_new(); 1359 TCGv t2 = tcg_temp_new(); 1360 1361 gen_load_gpr(t1, rs); 1362 gen_load_gpr(t2, rt); 1363 tcg_gen_add_tl(t0, t1, t2); 1364 tcg_gen_ext32s_tl(t0, t0); 1365 tcg_gen_xor_tl(t1, t1, t2); 1366 tcg_gen_xor_tl(t2, t0, t2); 1367 tcg_gen_andc_tl(t1, t2, t1); 1368 1369 /* operands of same sign, result different sign */ 1370 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0); 1371 gen_store_gpr(t0, rd); 1372 } 1373 break; 1374 case NM_MUL: 1375 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); 1376 break; 1377 case NM_MUH: 1378 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); 1379 break; 1380 case NM_MULU: 1381 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); 1382 break; 1383 case NM_MUHU: 1384 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); 1385 break; 1386 case NM_DIV: 1387 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); 1388 break; 1389 case NM_MOD: 1390 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); 1391 break; 1392 case NM_DIVU: 1393 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); 1394 break; 1395 case NM_MODU: 1396 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); 1397 break; 1398#ifndef CONFIG_USER_ONLY 1399 case NM_MFC0: 1400 check_cp0_enabled(ctx); 1401 if (rt == 0) { 1402 /* Treat as NOP. */ 1403 break; 1404 } 1405 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3)); 1406 break; 1407 case NM_MTC0: 1408 check_cp0_enabled(ctx); 1409 { 1410 TCGv t0 = tcg_temp_new(); 1411 1412 gen_load_gpr(t0, rt); 1413 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3)); 1414 } 1415 break; 1416 case NM_D_E_MT_VPE: 1417 { 1418 uint8_t sc = extract32(ctx->opcode, 10, 1); 1419 TCGv t0 = tcg_temp_new(); 1420 1421 switch (sc) { 1422 case 0: 1423 if (rs == 1) { 1424 /* DMT */ 1425 check_cp0_mt(ctx); 1426 gen_helper_dmt(t0); 1427 gen_store_gpr(t0, rt); 1428 } else if (rs == 0) { 1429 /* DVPE */ 1430 check_cp0_mt(ctx); 1431 gen_helper_dvpe(t0, tcg_env); 1432 gen_store_gpr(t0, rt); 1433 } else { 1434 gen_reserved_instruction(ctx); 1435 } 1436 break; 1437 case 1: 1438 if (rs == 1) { 1439 /* EMT */ 1440 check_cp0_mt(ctx); 1441 gen_helper_emt(t0); 1442 gen_store_gpr(t0, rt); 1443 } else if (rs == 0) { 1444 /* EVPE */ 1445 check_cp0_mt(ctx); 1446 gen_helper_evpe(t0, tcg_env); 1447 gen_store_gpr(t0, rt); 1448 } else { 1449 gen_reserved_instruction(ctx); 1450 } 1451 break; 1452 } 1453 } 1454 break; 1455 case NM_FORK: 1456 check_mt(ctx); 1457 { 1458 TCGv t0 = tcg_temp_new(); 1459 TCGv t1 = tcg_temp_new(); 1460 1461 gen_load_gpr(t0, rt); 1462 gen_load_gpr(t1, rs); 1463 gen_helper_fork(t0, t1); 1464 } 1465 break; 1466 case NM_MFTR: 1467 case NM_MFHTR: 1468 check_cp0_enabled(ctx); 1469 if (rd == 0) { 1470 /* Treat as NOP. */ 1471 return; 1472 } 1473 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), 1474 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1)); 1475 break; 1476 case NM_MTTR: 1477 case NM_MTHTR: 1478 check_cp0_enabled(ctx); 1479 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), 1480 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1)); 1481 break; 1482 case NM_YIELD: 1483 check_mt(ctx); 1484 { 1485 TCGv t0 = tcg_temp_new(); 1486 1487 gen_load_gpr(t0, rs); 1488 gen_helper_yield(t0, tcg_env, t0); 1489 gen_store_gpr(t0, rt); 1490 } 1491 break; 1492#endif 1493 default: 1494 gen_reserved_instruction(ctx); 1495 break; 1496 } 1497} 1498 1499/* dsp */ 1500static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc, 1501 int ret, int v1, int v2) 1502{ 1503 TCGv_i32 t0; 1504 TCGv v0_t; 1505 TCGv v1_t; 1506 1507 t0 = tcg_temp_new_i32(); 1508 1509 v0_t = tcg_temp_new(); 1510 v1_t = tcg_temp_new(); 1511 1512 tcg_gen_movi_i32(t0, v2 >> 3); 1513 1514 gen_load_gpr(v0_t, ret); 1515 gen_load_gpr(v1_t, v1); 1516 1517 switch (opc) { 1518 case NM_MAQ_S_W_PHR: 1519 check_dsp(ctx); 1520 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, tcg_env); 1521 break; 1522 case NM_MAQ_S_W_PHL: 1523 check_dsp(ctx); 1524 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, tcg_env); 1525 break; 1526 case NM_MAQ_SA_W_PHR: 1527 check_dsp(ctx); 1528 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, tcg_env); 1529 break; 1530 case NM_MAQ_SA_W_PHL: 1531 check_dsp(ctx); 1532 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, tcg_env); 1533 break; 1534 default: 1535 gen_reserved_instruction(ctx); 1536 break; 1537 } 1538} 1539 1540 1541static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, 1542 int ret, int v1, int v2) 1543{ 1544 int16_t imm; 1545 TCGv t0 = tcg_temp_new(); 1546 TCGv v0_t = tcg_temp_new(); 1547 1548 gen_load_gpr(v0_t, v1); 1549 1550 switch (opc) { 1551 case NM_POOL32AXF_1_0: 1552 check_dsp(ctx); 1553 switch (extract32(ctx->opcode, 12, 2)) { 1554 case NM_MFHI: 1555 gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret); 1556 break; 1557 case NM_MFLO: 1558 gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret); 1559 break; 1560 case NM_MTHI: 1561 gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1); 1562 break; 1563 case NM_MTLO: 1564 gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1); 1565 break; 1566 } 1567 break; 1568 case NM_POOL32AXF_1_1: 1569 check_dsp(ctx); 1570 switch (extract32(ctx->opcode, 12, 2)) { 1571 case NM_MTHLIP: 1572 gen_helper_mthlip(tcg_constant_tl(v2 >> 3), v0_t, tcg_env); 1573 break; 1574 case NM_SHILOV: 1575 gen_helper_shilo(tcg_constant_tl(v2 >> 3), v0_t, tcg_env); 1576 break; 1577 default: 1578 gen_reserved_instruction(ctx); 1579 break; 1580 } 1581 break; 1582 case NM_POOL32AXF_1_3: 1583 check_dsp(ctx); 1584 imm = extract32(ctx->opcode, 14, 7); 1585 switch (extract32(ctx->opcode, 12, 2)) { 1586 case NM_RDDSP: 1587 gen_helper_rddsp(t0, tcg_constant_tl(imm), tcg_env); 1588 gen_store_gpr(t0, ret); 1589 break; 1590 case NM_WRDSP: 1591 gen_load_gpr(t0, ret); 1592 gen_helper_wrdsp(t0, tcg_constant_tl(imm), tcg_env); 1593 break; 1594 case NM_EXTP: 1595 gen_helper_extp(t0, tcg_constant_tl(v2 >> 3), 1596 tcg_constant_tl(v1), tcg_env); 1597 gen_store_gpr(t0, ret); 1598 break; 1599 case NM_EXTPDP: 1600 gen_helper_extpdp(t0, tcg_constant_tl(v2 >> 3), 1601 tcg_constant_tl(v1), tcg_env); 1602 gen_store_gpr(t0, ret); 1603 break; 1604 } 1605 break; 1606 case NM_POOL32AXF_1_4: 1607 check_dsp(ctx); 1608 switch (extract32(ctx->opcode, 12, 1)) { 1609 case NM_SHLL_QB: 1610 gen_helper_shll_qb(t0, tcg_constant_tl(v2 >> 2), v0_t, tcg_env); 1611 gen_store_gpr(t0, ret); 1612 break; 1613 case NM_SHRL_QB: 1614 gen_helper_shrl_qb(t0, tcg_constant_tl(v2 >> 2), v0_t); 1615 gen_store_gpr(t0, ret); 1616 break; 1617 } 1618 break; 1619 case NM_POOL32AXF_1_5: 1620 opc = extract32(ctx->opcode, 12, 2); 1621 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2); 1622 break; 1623 case NM_POOL32AXF_1_7: 1624 check_dsp(ctx); 1625 switch (extract32(ctx->opcode, 12, 2)) { 1626 case NM_EXTR_W: 1627 gen_helper_extr_w(t0, tcg_constant_tl(v2 >> 3), 1628 tcg_constant_tl(v1), tcg_env); 1629 gen_store_gpr(t0, ret); 1630 break; 1631 case NM_EXTR_R_W: 1632 gen_helper_extr_r_w(t0, tcg_constant_tl(v2 >> 3), 1633 tcg_constant_tl(v1), tcg_env); 1634 gen_store_gpr(t0, ret); 1635 break; 1636 case NM_EXTR_RS_W: 1637 gen_helper_extr_rs_w(t0, tcg_constant_tl(v2 >> 3), 1638 tcg_constant_tl(v1), tcg_env); 1639 gen_store_gpr(t0, ret); 1640 break; 1641 case NM_EXTR_S_H: 1642 gen_helper_extr_s_h(t0, tcg_constant_tl(v2 >> 3), 1643 tcg_constant_tl(v1), tcg_env); 1644 gen_store_gpr(t0, ret); 1645 break; 1646 } 1647 break; 1648 default: 1649 gen_reserved_instruction(ctx); 1650 break; 1651 } 1652} 1653 1654static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, 1655 TCGv v0, TCGv v1, int rd) 1656{ 1657 TCGv_i32 t0; 1658 1659 t0 = tcg_temp_new_i32(); 1660 1661 tcg_gen_movi_i32(t0, rd >> 3); 1662 1663 switch (opc) { 1664 case NM_POOL32AXF_2_0_7: 1665 switch (extract32(ctx->opcode, 9, 3)) { 1666 case NM_DPA_W_PH: 1667 check_dsp_r2(ctx); 1668 gen_helper_dpa_w_ph(t0, v1, v0, tcg_env); 1669 break; 1670 case NM_DPAQ_S_W_PH: 1671 check_dsp(ctx); 1672 gen_helper_dpaq_s_w_ph(t0, v1, v0, tcg_env); 1673 break; 1674 case NM_DPS_W_PH: 1675 check_dsp_r2(ctx); 1676 gen_helper_dps_w_ph(t0, v1, v0, tcg_env); 1677 break; 1678 case NM_DPSQ_S_W_PH: 1679 check_dsp(ctx); 1680 gen_helper_dpsq_s_w_ph(t0, v1, v0, tcg_env); 1681 break; 1682 default: 1683 gen_reserved_instruction(ctx); 1684 break; 1685 } 1686 break; 1687 case NM_POOL32AXF_2_8_15: 1688 switch (extract32(ctx->opcode, 9, 3)) { 1689 case NM_DPAX_W_PH: 1690 check_dsp_r2(ctx); 1691 gen_helper_dpax_w_ph(t0, v0, v1, tcg_env); 1692 break; 1693 case NM_DPAQ_SA_L_W: 1694 check_dsp(ctx); 1695 gen_helper_dpaq_sa_l_w(t0, v0, v1, tcg_env); 1696 break; 1697 case NM_DPSX_W_PH: 1698 check_dsp_r2(ctx); 1699 gen_helper_dpsx_w_ph(t0, v0, v1, tcg_env); 1700 break; 1701 case NM_DPSQ_SA_L_W: 1702 check_dsp(ctx); 1703 gen_helper_dpsq_sa_l_w(t0, v0, v1, tcg_env); 1704 break; 1705 default: 1706 gen_reserved_instruction(ctx); 1707 break; 1708 } 1709 break; 1710 case NM_POOL32AXF_2_16_23: 1711 switch (extract32(ctx->opcode, 9, 3)) { 1712 case NM_DPAU_H_QBL: 1713 check_dsp(ctx); 1714 gen_helper_dpau_h_qbl(t0, v0, v1, tcg_env); 1715 break; 1716 case NM_DPAQX_S_W_PH: 1717 check_dsp_r2(ctx); 1718 gen_helper_dpaqx_s_w_ph(t0, v0, v1, tcg_env); 1719 break; 1720 case NM_DPSU_H_QBL: 1721 check_dsp(ctx); 1722 gen_helper_dpsu_h_qbl(t0, v0, v1, tcg_env); 1723 break; 1724 case NM_DPSQX_S_W_PH: 1725 check_dsp_r2(ctx); 1726 gen_helper_dpsqx_s_w_ph(t0, v0, v1, tcg_env); 1727 break; 1728 case NM_MULSA_W_PH: 1729 check_dsp_r2(ctx); 1730 gen_helper_mulsa_w_ph(t0, v0, v1, tcg_env); 1731 break; 1732 default: 1733 gen_reserved_instruction(ctx); 1734 break; 1735 } 1736 break; 1737 case NM_POOL32AXF_2_24_31: 1738 switch (extract32(ctx->opcode, 9, 3)) { 1739 case NM_DPAU_H_QBR: 1740 check_dsp(ctx); 1741 gen_helper_dpau_h_qbr(t0, v1, v0, tcg_env); 1742 break; 1743 case NM_DPAQX_SA_W_PH: 1744 check_dsp_r2(ctx); 1745 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, tcg_env); 1746 break; 1747 case NM_DPSU_H_QBR: 1748 check_dsp(ctx); 1749 gen_helper_dpsu_h_qbr(t0, v1, v0, tcg_env); 1750 break; 1751 case NM_DPSQX_SA_W_PH: 1752 check_dsp_r2(ctx); 1753 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, tcg_env); 1754 break; 1755 case NM_MULSAQ_S_W_PH: 1756 check_dsp(ctx); 1757 gen_helper_mulsaq_s_w_ph(t0, v1, v0, tcg_env); 1758 break; 1759 default: 1760 gen_reserved_instruction(ctx); 1761 break; 1762 } 1763 break; 1764 default: 1765 gen_reserved_instruction(ctx); 1766 break; 1767 } 1768} 1769 1770static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, 1771 int rt, int rs, int rd) 1772{ 1773 int ret = rt; 1774 TCGv t0 = tcg_temp_new(); 1775 TCGv t1 = tcg_temp_new(); 1776 TCGv v0_t = tcg_temp_new(); 1777 TCGv v1_t = tcg_temp_new(); 1778 1779 gen_load_gpr(v0_t, rt); 1780 gen_load_gpr(v1_t, rs); 1781 1782 switch (opc) { 1783 case NM_POOL32AXF_2_0_7: 1784 switch (extract32(ctx->opcode, 9, 3)) { 1785 case NM_DPA_W_PH: 1786 case NM_DPAQ_S_W_PH: 1787 case NM_DPS_W_PH: 1788 case NM_DPSQ_S_W_PH: 1789 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 1790 break; 1791 case NM_BALIGN: 1792 check_dsp_r2(ctx); 1793 if (rt != 0) { 1794 gen_load_gpr(t0, rs); 1795 rd &= 3; 1796 if (rd != 0 && rd != 2) { 1797 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd); 1798 tcg_gen_ext32u_tl(t0, t0); 1799 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd)); 1800 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 1801 } 1802 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 1803 } 1804 break; 1805 case NM_MADD: 1806 check_dsp(ctx); 1807 { 1808 int acc = extract32(ctx->opcode, 14, 2); 1809 TCGv_i64 t2 = tcg_temp_new_i64(); 1810 TCGv_i64 t3 = tcg_temp_new_i64(); 1811 1812 gen_load_gpr(t0, rt); 1813 gen_load_gpr(t1, rs); 1814 tcg_gen_ext_tl_i64(t2, t0); 1815 tcg_gen_ext_tl_i64(t3, t1); 1816 tcg_gen_mul_i64(t2, t2, t3); 1817 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 1818 tcg_gen_add_i64(t2, t2, t3); 1819 gen_move_low32(cpu_LO[acc], t2); 1820 gen_move_high32(cpu_HI[acc], t2); 1821 } 1822 break; 1823 case NM_MULT: 1824 check_dsp(ctx); 1825 { 1826 int acc = extract32(ctx->opcode, 14, 2); 1827 TCGv_i32 t2 = tcg_temp_new_i32(); 1828 TCGv_i32 t3 = tcg_temp_new_i32(); 1829 1830 if (acc || ctx->insn_flags & ISA_MIPS_R6) { 1831 check_dsp_r2(ctx); 1832 } 1833 gen_load_gpr(t0, rs); 1834 gen_load_gpr(t1, rt); 1835 tcg_gen_trunc_tl_i32(t2, t0); 1836 tcg_gen_trunc_tl_i32(t3, t1); 1837 tcg_gen_muls2_i32(t2, t3, t2, t3); 1838 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 1839 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 1840 } 1841 break; 1842 case NM_EXTRV_W: 1843 check_dsp(ctx); 1844 gen_load_gpr(v1_t, rs); 1845 gen_helper_extr_w(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env); 1846 gen_store_gpr(t0, ret); 1847 break; 1848 } 1849 break; 1850 case NM_POOL32AXF_2_8_15: 1851 switch (extract32(ctx->opcode, 9, 3)) { 1852 case NM_DPAX_W_PH: 1853 case NM_DPAQ_SA_L_W: 1854 case NM_DPSX_W_PH: 1855 case NM_DPSQ_SA_L_W: 1856 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 1857 break; 1858 case NM_MADDU: 1859 check_dsp(ctx); 1860 { 1861 int acc = extract32(ctx->opcode, 14, 2); 1862 TCGv_i64 t2 = tcg_temp_new_i64(); 1863 TCGv_i64 t3 = tcg_temp_new_i64(); 1864 1865 gen_load_gpr(t0, rs); 1866 gen_load_gpr(t1, rt); 1867 tcg_gen_ext32u_tl(t0, t0); 1868 tcg_gen_ext32u_tl(t1, t1); 1869 tcg_gen_extu_tl_i64(t2, t0); 1870 tcg_gen_extu_tl_i64(t3, t1); 1871 tcg_gen_mul_i64(t2, t2, t3); 1872 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 1873 tcg_gen_add_i64(t2, t2, t3); 1874 gen_move_low32(cpu_LO[acc], t2); 1875 gen_move_high32(cpu_HI[acc], t2); 1876 } 1877 break; 1878 case NM_MULTU: 1879 check_dsp(ctx); 1880 { 1881 int acc = extract32(ctx->opcode, 14, 2); 1882 TCGv_i32 t2 = tcg_temp_new_i32(); 1883 TCGv_i32 t3 = tcg_temp_new_i32(); 1884 1885 if (acc || ctx->insn_flags & ISA_MIPS_R6) { 1886 check_dsp_r2(ctx); 1887 } 1888 gen_load_gpr(t0, rs); 1889 gen_load_gpr(t1, rt); 1890 tcg_gen_trunc_tl_i32(t2, t0); 1891 tcg_gen_trunc_tl_i32(t3, t1); 1892 tcg_gen_mulu2_i32(t2, t3, t2, t3); 1893 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 1894 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 1895 } 1896 break; 1897 case NM_EXTRV_R_W: 1898 check_dsp(ctx); 1899 gen_helper_extr_r_w(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env); 1900 gen_store_gpr(t0, ret); 1901 break; 1902 default: 1903 gen_reserved_instruction(ctx); 1904 break; 1905 } 1906 break; 1907 case NM_POOL32AXF_2_16_23: 1908 switch (extract32(ctx->opcode, 9, 3)) { 1909 case NM_DPAU_H_QBL: 1910 case NM_DPAQX_S_W_PH: 1911 case NM_DPSU_H_QBL: 1912 case NM_DPSQX_S_W_PH: 1913 case NM_MULSA_W_PH: 1914 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 1915 break; 1916 case NM_EXTPV: 1917 check_dsp(ctx); 1918 gen_helper_extp(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env); 1919 gen_store_gpr(t0, ret); 1920 break; 1921 case NM_MSUB: 1922 check_dsp(ctx); 1923 { 1924 int acc = extract32(ctx->opcode, 14, 2); 1925 TCGv_i64 t2 = tcg_temp_new_i64(); 1926 TCGv_i64 t3 = tcg_temp_new_i64(); 1927 1928 gen_load_gpr(t0, rs); 1929 gen_load_gpr(t1, rt); 1930 tcg_gen_ext_tl_i64(t2, t0); 1931 tcg_gen_ext_tl_i64(t3, t1); 1932 tcg_gen_mul_i64(t2, t2, t3); 1933 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 1934 tcg_gen_sub_i64(t2, t3, t2); 1935 gen_move_low32(cpu_LO[acc], t2); 1936 gen_move_high32(cpu_HI[acc], t2); 1937 } 1938 break; 1939 case NM_EXTRV_RS_W: 1940 check_dsp(ctx); 1941 gen_helper_extr_rs_w(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env); 1942 gen_store_gpr(t0, ret); 1943 break; 1944 } 1945 break; 1946 case NM_POOL32AXF_2_24_31: 1947 switch (extract32(ctx->opcode, 9, 3)) { 1948 case NM_DPAU_H_QBR: 1949 case NM_DPAQX_SA_W_PH: 1950 case NM_DPSU_H_QBR: 1951 case NM_DPSQX_SA_W_PH: 1952 case NM_MULSAQ_S_W_PH: 1953 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 1954 break; 1955 case NM_EXTPDPV: 1956 check_dsp(ctx); 1957 gen_helper_extpdp(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env); 1958 gen_store_gpr(t0, ret); 1959 break; 1960 case NM_MSUBU: 1961 check_dsp(ctx); 1962 { 1963 int acc = extract32(ctx->opcode, 14, 2); 1964 TCGv_i64 t2 = tcg_temp_new_i64(); 1965 TCGv_i64 t3 = tcg_temp_new_i64(); 1966 1967 gen_load_gpr(t0, rs); 1968 gen_load_gpr(t1, rt); 1969 tcg_gen_ext32u_tl(t0, t0); 1970 tcg_gen_ext32u_tl(t1, t1); 1971 tcg_gen_extu_tl_i64(t2, t0); 1972 tcg_gen_extu_tl_i64(t3, t1); 1973 tcg_gen_mul_i64(t2, t2, t3); 1974 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 1975 tcg_gen_sub_i64(t2, t3, t2); 1976 gen_move_low32(cpu_LO[acc], t2); 1977 gen_move_high32(cpu_HI[acc], t2); 1978 } 1979 break; 1980 case NM_EXTRV_S_H: 1981 check_dsp(ctx); 1982 gen_helper_extr_s_h(t0, tcg_constant_tl(rd >> 3), v1_t, tcg_env); 1983 gen_store_gpr(t0, ret); 1984 break; 1985 } 1986 break; 1987 default: 1988 gen_reserved_instruction(ctx); 1989 break; 1990 } 1991} 1992 1993static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc, 1994 int rt, int rs) 1995{ 1996 int ret = rt; 1997 TCGv t0 = tcg_temp_new(); 1998 TCGv v0_t = tcg_temp_new(); 1999 2000 gen_load_gpr(v0_t, rs); 2001 2002 switch (opc) { 2003 case NM_ABSQ_S_QB: 2004 check_dsp_r2(ctx); 2005 gen_helper_absq_s_qb(v0_t, v0_t, tcg_env); 2006 gen_store_gpr(v0_t, ret); 2007 break; 2008 case NM_ABSQ_S_PH: 2009 check_dsp(ctx); 2010 gen_helper_absq_s_ph(v0_t, v0_t, tcg_env); 2011 gen_store_gpr(v0_t, ret); 2012 break; 2013 case NM_ABSQ_S_W: 2014 check_dsp(ctx); 2015 gen_helper_absq_s_w(v0_t, v0_t, tcg_env); 2016 gen_store_gpr(v0_t, ret); 2017 break; 2018 case NM_PRECEQ_W_PHL: 2019 check_dsp(ctx); 2020 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000); 2021 tcg_gen_ext32s_tl(v0_t, v0_t); 2022 gen_store_gpr(v0_t, ret); 2023 break; 2024 case NM_PRECEQ_W_PHR: 2025 check_dsp(ctx); 2026 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF); 2027 tcg_gen_shli_tl(v0_t, v0_t, 16); 2028 tcg_gen_ext32s_tl(v0_t, v0_t); 2029 gen_store_gpr(v0_t, ret); 2030 break; 2031 case NM_PRECEQU_PH_QBL: 2032 check_dsp(ctx); 2033 gen_helper_precequ_ph_qbl(v0_t, v0_t); 2034 gen_store_gpr(v0_t, ret); 2035 break; 2036 case NM_PRECEQU_PH_QBR: 2037 check_dsp(ctx); 2038 gen_helper_precequ_ph_qbr(v0_t, v0_t); 2039 gen_store_gpr(v0_t, ret); 2040 break; 2041 case NM_PRECEQU_PH_QBLA: 2042 check_dsp(ctx); 2043 gen_helper_precequ_ph_qbla(v0_t, v0_t); 2044 gen_store_gpr(v0_t, ret); 2045 break; 2046 case NM_PRECEQU_PH_QBRA: 2047 check_dsp(ctx); 2048 gen_helper_precequ_ph_qbra(v0_t, v0_t); 2049 gen_store_gpr(v0_t, ret); 2050 break; 2051 case NM_PRECEU_PH_QBL: 2052 check_dsp(ctx); 2053 gen_helper_preceu_ph_qbl(v0_t, v0_t); 2054 gen_store_gpr(v0_t, ret); 2055 break; 2056 case NM_PRECEU_PH_QBR: 2057 check_dsp(ctx); 2058 gen_helper_preceu_ph_qbr(v0_t, v0_t); 2059 gen_store_gpr(v0_t, ret); 2060 break; 2061 case NM_PRECEU_PH_QBLA: 2062 check_dsp(ctx); 2063 gen_helper_preceu_ph_qbla(v0_t, v0_t); 2064 gen_store_gpr(v0_t, ret); 2065 break; 2066 case NM_PRECEU_PH_QBRA: 2067 check_dsp(ctx); 2068 gen_helper_preceu_ph_qbra(v0_t, v0_t); 2069 gen_store_gpr(v0_t, ret); 2070 break; 2071 case NM_REPLV_PH: 2072 check_dsp(ctx); 2073 tcg_gen_ext16u_tl(v0_t, v0_t); 2074 tcg_gen_shli_tl(t0, v0_t, 16); 2075 tcg_gen_or_tl(v0_t, v0_t, t0); 2076 tcg_gen_ext32s_tl(v0_t, v0_t); 2077 gen_store_gpr(v0_t, ret); 2078 break; 2079 case NM_REPLV_QB: 2080 check_dsp(ctx); 2081 tcg_gen_ext8u_tl(v0_t, v0_t); 2082 tcg_gen_shli_tl(t0, v0_t, 8); 2083 tcg_gen_or_tl(v0_t, v0_t, t0); 2084 tcg_gen_shli_tl(t0, v0_t, 16); 2085 tcg_gen_or_tl(v0_t, v0_t, t0); 2086 tcg_gen_ext32s_tl(v0_t, v0_t); 2087 gen_store_gpr(v0_t, ret); 2088 break; 2089 case NM_BITREV: 2090 check_dsp(ctx); 2091 gen_helper_bitrev(v0_t, v0_t); 2092 gen_store_gpr(v0_t, ret); 2093 break; 2094 case NM_INSV: 2095 check_dsp(ctx); 2096 { 2097 TCGv tv0 = tcg_temp_new(); 2098 2099 gen_load_gpr(tv0, rt); 2100 gen_helper_insv(v0_t, tcg_env, v0_t, tv0); 2101 gen_store_gpr(v0_t, ret); 2102 } 2103 break; 2104 case NM_RADDU_W_QB: 2105 check_dsp(ctx); 2106 gen_helper_raddu_w_qb(v0_t, v0_t); 2107 gen_store_gpr(v0_t, ret); 2108 break; 2109 case NM_BITSWAP: 2110 gen_bitswap(ctx, OPC_BITSWAP, ret, rs); 2111 break; 2112 case NM_CLO: 2113 check_nms(ctx); 2114 gen_cl(ctx, OPC_CLO, ret, rs); 2115 break; 2116 case NM_CLZ: 2117 check_nms(ctx); 2118 gen_cl(ctx, OPC_CLZ, ret, rs); 2119 break; 2120 case NM_WSBH: 2121 gen_bshfl(ctx, OPC_WSBH, ret, rs); 2122 break; 2123 default: 2124 gen_reserved_instruction(ctx); 2125 break; 2126 } 2127} 2128 2129static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc, 2130 int rt, int rs, int rd) 2131{ 2132 TCGv t0 = tcg_temp_new(); 2133 TCGv rs_t = tcg_temp_new(); 2134 2135 gen_load_gpr(rs_t, rs); 2136 2137 switch (opc) { 2138 case NM_SHRA_R_QB: 2139 check_dsp_r2(ctx); 2140 switch (extract32(ctx->opcode, 12, 1)) { 2141 case 0: 2142 /* NM_SHRA_QB */ 2143 gen_helper_shra_qb(t0, tcg_constant_tl(rd >> 2), rs_t); 2144 gen_store_gpr(t0, rt); 2145 break; 2146 case 1: 2147 /* NM_SHRA_R_QB */ 2148 gen_helper_shra_r_qb(t0, tcg_constant_tl(rd >> 2), rs_t); 2149 gen_store_gpr(t0, rt); 2150 break; 2151 } 2152 break; 2153 case NM_SHRL_PH: 2154 check_dsp_r2(ctx); 2155 gen_helper_shrl_ph(t0, tcg_constant_tl(rd >> 1), rs_t); 2156 gen_store_gpr(t0, rt); 2157 break; 2158 case NM_REPL_QB: 2159 check_dsp(ctx); 2160 { 2161 int16_t imm; 2162 target_long result; 2163 imm = extract32(ctx->opcode, 13, 8); 2164 result = (uint32_t)imm << 24 | 2165 (uint32_t)imm << 16 | 2166 (uint32_t)imm << 8 | 2167 (uint32_t)imm; 2168 result = (int32_t)result; 2169 gen_store_gpr(tcg_constant_tl(result), rt); 2170 } 2171 break; 2172 default: 2173 gen_reserved_instruction(ctx); 2174 break; 2175 } 2176} 2177 2178 2179static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) 2180{ 2181 int rt = extract32(ctx->opcode, 21, 5); 2182 int rs = extract32(ctx->opcode, 16, 5); 2183 int rd = extract32(ctx->opcode, 11, 5); 2184 2185 switch (extract32(ctx->opcode, 6, 3)) { 2186 case NM_POOL32AXF_1: 2187 { 2188 int32_t op1 = extract32(ctx->opcode, 9, 3); 2189 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd); 2190 } 2191 break; 2192 case NM_POOL32AXF_2: 2193 { 2194 int32_t op1 = extract32(ctx->opcode, 12, 2); 2195 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd); 2196 } 2197 break; 2198 case NM_POOL32AXF_4: 2199 { 2200 int32_t op1 = extract32(ctx->opcode, 9, 7); 2201 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs); 2202 } 2203 break; 2204 case NM_POOL32AXF_5: 2205 switch (extract32(ctx->opcode, 9, 7)) { 2206#ifndef CONFIG_USER_ONLY 2207 case NM_TLBP: 2208 gen_cp0(env, ctx, OPC_TLBP, 0, 0); 2209 break; 2210 case NM_TLBR: 2211 gen_cp0(env, ctx, OPC_TLBR, 0, 0); 2212 break; 2213 case NM_TLBWI: 2214 gen_cp0(env, ctx, OPC_TLBWI, 0, 0); 2215 break; 2216 case NM_TLBWR: 2217 gen_cp0(env, ctx, OPC_TLBWR, 0, 0); 2218 break; 2219 case NM_TLBINV: 2220 gen_cp0(env, ctx, OPC_TLBINV, 0, 0); 2221 break; 2222 case NM_TLBINVF: 2223 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0); 2224 break; 2225 case NM_DI: 2226 check_cp0_enabled(ctx); 2227 { 2228 TCGv t0 = tcg_temp_new(); 2229 2230 save_cpu_state(ctx, 1); 2231 gen_helper_di(t0, tcg_env); 2232 gen_store_gpr(t0, rt); 2233 /* Stop translation as we may have switched the execution mode */ 2234 ctx->base.is_jmp = DISAS_STOP; 2235 } 2236 break; 2237 case NM_EI: 2238 check_cp0_enabled(ctx); 2239 { 2240 TCGv t0 = tcg_temp_new(); 2241 2242 save_cpu_state(ctx, 1); 2243 gen_helper_ei(t0, tcg_env); 2244 gen_store_gpr(t0, rt); 2245 /* Stop translation as we may have switched the execution mode */ 2246 ctx->base.is_jmp = DISAS_STOP; 2247 } 2248 break; 2249 case NM_RDPGPR: 2250 check_cp0_enabled(ctx); 2251 gen_load_srsgpr(rs, rt); 2252 break; 2253 case NM_WRPGPR: 2254 check_cp0_enabled(ctx); 2255 gen_store_srsgpr(rs, rt); 2256 break; 2257 case NM_WAIT: 2258 gen_cp0(env, ctx, OPC_WAIT, 0, 0); 2259 break; 2260 case NM_DERET: 2261 gen_cp0(env, ctx, OPC_DERET, 0, 0); 2262 break; 2263 case NM_ERETX: 2264 gen_cp0(env, ctx, OPC_ERET, 0, 0); 2265 break; 2266#endif 2267 default: 2268 gen_reserved_instruction(ctx); 2269 break; 2270 } 2271 break; 2272 case NM_POOL32AXF_7: 2273 { 2274 int32_t op1 = extract32(ctx->opcode, 9, 3); 2275 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd); 2276 } 2277 break; 2278 default: 2279 gen_reserved_instruction(ctx); 2280 break; 2281 } 2282} 2283 2284/* Immediate Value Compact Branches */ 2285static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, 2286 int rt, int32_t imm, int32_t offset) 2287{ 2288 TCGCond cond = TCG_COND_ALWAYS; 2289 TCGv t0 = tcg_temp_new(); 2290 TCGv timm = tcg_constant_tl(imm); 2291 2292 gen_load_gpr(t0, rt); 2293 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2294 2295 /* Load needed operands and calculate btarget */ 2296 switch (opc) { 2297 case NM_BEQIC: 2298 if (rt == 0 && imm == 0) { 2299 /* Unconditional branch */ 2300 } else if (rt == 0 && imm != 0) { 2301 /* Treat as NOP */ 2302 return; 2303 } else { 2304 cond = TCG_COND_EQ; 2305 } 2306 break; 2307 case NM_BBEQZC: 2308 case NM_BBNEZC: 2309 check_nms(ctx); 2310 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) { 2311 gen_reserved_instruction(ctx); 2312 return; 2313 } else if (rt == 0 && opc == NM_BBEQZC) { 2314 /* Unconditional branch */ 2315 } else if (rt == 0 && opc == NM_BBNEZC) { 2316 /* Treat as NOP */ 2317 return; 2318 } else { 2319 tcg_gen_shri_tl(t0, t0, imm); 2320 tcg_gen_andi_tl(t0, t0, 1); 2321 timm = tcg_constant_tl(0); 2322 if (opc == NM_BBEQZC) { 2323 cond = TCG_COND_EQ; 2324 } else { 2325 cond = TCG_COND_NE; 2326 } 2327 } 2328 break; 2329 case NM_BNEIC: 2330 if (rt == 0 && imm == 0) { 2331 /* Treat as NOP */ 2332 return; 2333 } else if (rt == 0 && imm != 0) { 2334 /* Unconditional branch */ 2335 } else { 2336 cond = TCG_COND_NE; 2337 } 2338 break; 2339 case NM_BGEIC: 2340 if (rt == 0 && imm == 0) { 2341 /* Unconditional branch */ 2342 } else { 2343 cond = TCG_COND_GE; 2344 } 2345 break; 2346 case NM_BLTIC: 2347 cond = TCG_COND_LT; 2348 break; 2349 case NM_BGEIUC: 2350 if (rt == 0 && imm == 0) { 2351 /* Unconditional branch */ 2352 } else { 2353 cond = TCG_COND_GEU; 2354 } 2355 break; 2356 case NM_BLTIUC: 2357 cond = TCG_COND_LTU; 2358 break; 2359 default: 2360 MIPS_INVAL("Immediate Value Compact branch"); 2361 gen_reserved_instruction(ctx); 2362 return; 2363 } 2364 2365 /* branch completion */ 2366 clear_branch_hflags(ctx); 2367 ctx->base.is_jmp = DISAS_NORETURN; 2368 2369 if (cond == TCG_COND_ALWAYS) { 2370 /* Uncoditional compact branch */ 2371 gen_goto_tb(ctx, 0, ctx->btarget); 2372 } else { 2373 /* Conditional compact branch */ 2374 TCGLabel *fs = gen_new_label(); 2375 2376 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, timm, fs); 2377 2378 gen_goto_tb(ctx, 1, ctx->btarget); 2379 gen_set_label(fs); 2380 2381 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); 2382 } 2383} 2384 2385/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */ 2386static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs, 2387 int rt) 2388{ 2389 TCGv t0 = tcg_temp_new(); 2390 2391 /* load rs */ 2392 gen_load_gpr(t0, rs); 2393 2394 /* link */ 2395 if (rt != 0) { 2396 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4); 2397 } 2398 2399 /* calculate btarget */ 2400 tcg_gen_shli_tl(t0, t0, 1); 2401 gen_op_addr_add(ctx, btarget, tcg_constant_tl(ctx->base.pc_next + 4), t0); 2402 2403 /* branch completion */ 2404 clear_branch_hflags(ctx); 2405 ctx->base.is_jmp = DISAS_NORETURN; 2406 2407 /* unconditional branch to register */ 2408 tcg_gen_mov_tl(cpu_PC, btarget); 2409 tcg_gen_lookup_and_goto_ptr(); 2410} 2411 2412/* nanoMIPS Branches */ 2413static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc, 2414 int rs, int rt, int32_t offset) 2415{ 2416 int bcond_compute = 0; 2417 TCGv t0 = tcg_temp_new(); 2418 TCGv t1 = tcg_temp_new(); 2419 2420 /* Load needed operands and calculate btarget */ 2421 switch (opc) { 2422 /* compact branch */ 2423 case OPC_BGEC: 2424 case OPC_BLTC: 2425 gen_load_gpr(t0, rs); 2426 gen_load_gpr(t1, rt); 2427 bcond_compute = 1; 2428 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2429 break; 2430 case OPC_BGEUC: 2431 case OPC_BLTUC: 2432 if (rs == 0 || rs == rt) { 2433 /* OPC_BLEZALC, OPC_BGEZALC */ 2434 /* OPC_BGTZALC, OPC_BLTZALC */ 2435 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4); 2436 } 2437 gen_load_gpr(t0, rs); 2438 gen_load_gpr(t1, rt); 2439 bcond_compute = 1; 2440 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2441 break; 2442 case OPC_BC: 2443 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2444 break; 2445 case OPC_BEQZC: 2446 if (rs != 0) { 2447 /* OPC_BEQZC, OPC_BNEZC */ 2448 gen_load_gpr(t0, rs); 2449 bcond_compute = 1; 2450 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2451 } else { 2452 /* OPC_JIC, OPC_JIALC */ 2453 TCGv tbase = tcg_temp_new(); 2454 2455 gen_load_gpr(tbase, rt); 2456 gen_op_addr_addi(ctx, btarget, tbase, offset); 2457 } 2458 break; 2459 default: 2460 MIPS_INVAL("Compact branch/jump"); 2461 gen_reserved_instruction(ctx); 2462 return; 2463 } 2464 2465 if (bcond_compute == 0) { 2466 /* Uncoditional compact branch */ 2467 switch (opc) { 2468 case OPC_BC: 2469 gen_goto_tb(ctx, 0, ctx->btarget); 2470 break; 2471 default: 2472 MIPS_INVAL("Compact branch/jump"); 2473 gen_reserved_instruction(ctx); 2474 return; 2475 } 2476 } else { 2477 /* Conditional compact branch */ 2478 TCGLabel *fs = gen_new_label(); 2479 2480 switch (opc) { 2481 case OPC_BGEUC: 2482 if (rs == 0 && rt != 0) { 2483 /* OPC_BLEZALC */ 2484 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 2485 } else if (rs != 0 && rt != 0 && rs == rt) { 2486 /* OPC_BGEZALC */ 2487 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 2488 } else { 2489 /* OPC_BGEUC */ 2490 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 2491 } 2492 break; 2493 case OPC_BLTUC: 2494 if (rs == 0 && rt != 0) { 2495 /* OPC_BGTZALC */ 2496 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 2497 } else if (rs != 0 && rt != 0 && rs == rt) { 2498 /* OPC_BLTZALC */ 2499 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 2500 } else { 2501 /* OPC_BLTUC */ 2502 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 2503 } 2504 break; 2505 case OPC_BGEC: 2506 if (rs == 0 && rt != 0) { 2507 /* OPC_BLEZC */ 2508 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 2509 } else if (rs != 0 && rt != 0 && rs == rt) { 2510 /* OPC_BGEZC */ 2511 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 2512 } else { 2513 /* OPC_BGEC */ 2514 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 2515 } 2516 break; 2517 case OPC_BLTC: 2518 if (rs == 0 && rt != 0) { 2519 /* OPC_BGTZC */ 2520 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 2521 } else if (rs != 0 && rt != 0 && rs == rt) { 2522 /* OPC_BLTZC */ 2523 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 2524 } else { 2525 /* OPC_BLTC */ 2526 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 2527 } 2528 break; 2529 case OPC_BEQZC: 2530 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 2531 break; 2532 default: 2533 MIPS_INVAL("Compact conditional branch/jump"); 2534 gen_reserved_instruction(ctx); 2535 return; 2536 } 2537 2538 /* branch completion */ 2539 clear_branch_hflags(ctx); 2540 ctx->base.is_jmp = DISAS_NORETURN; 2541 2542 /* Generating branch here as compact branches don't have delay slot */ 2543 gen_goto_tb(ctx, 1, ctx->btarget); 2544 gen_set_label(fs); 2545 2546 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); 2547 } 2548} 2549 2550 2551/* nanoMIPS CP1 Branches */ 2552static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op, 2553 int32_t ft, int32_t offset) 2554{ 2555 target_ulong btarget; 2556 TCGv_i64 t0 = tcg_temp_new_i64(); 2557 2558 gen_load_fpr64(ctx, t0, ft); 2559 tcg_gen_andi_i64(t0, t0, 1); 2560 2561 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2562 2563 switch (op) { 2564 case NM_BC1EQZC: 2565 tcg_gen_xori_i64(t0, t0, 1); 2566 ctx->hflags |= MIPS_HFLAG_BC; 2567 break; 2568 case NM_BC1NEZC: 2569 /* t0 already set */ 2570 ctx->hflags |= MIPS_HFLAG_BC; 2571 break; 2572 default: 2573 MIPS_INVAL("cp1 cond branch"); 2574 gen_reserved_instruction(ctx); 2575 return; 2576 } 2577 2578 tcg_gen_trunc_i64_tl(bcond, t0); 2579 2580 ctx->btarget = btarget; 2581} 2582 2583 2584static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt) 2585{ 2586 TCGv t0, t1; 2587 t0 = tcg_temp_new(); 2588 t1 = tcg_temp_new(); 2589 2590 gen_load_gpr(t0, rs); 2591 gen_load_gpr(t1, rt); 2592 2593 if ((extract32(ctx->opcode, 6, 1)) == 1) { 2594 /* PP.LSXS instructions require shifting */ 2595 switch (extract32(ctx->opcode, 7, 4)) { 2596 case NM_SHXS: 2597 check_nms(ctx); 2598 /* fall through */ 2599 case NM_LHXS: 2600 case NM_LHUXS: 2601 tcg_gen_shli_tl(t0, t0, 1); 2602 break; 2603 case NM_SWXS: 2604 check_nms(ctx); 2605 /* fall through */ 2606 case NM_LWXS: 2607 case NM_LWC1XS: 2608 case NM_SWC1XS: 2609 tcg_gen_shli_tl(t0, t0, 2); 2610 break; 2611 case NM_LDC1XS: 2612 case NM_SDC1XS: 2613 tcg_gen_shli_tl(t0, t0, 3); 2614 break; 2615 default: 2616 gen_reserved_instruction(ctx); 2617 return; 2618 } 2619 } 2620 gen_op_addr_add(ctx, t0, t0, t1); 2621 2622 switch (extract32(ctx->opcode, 7, 4)) { 2623 case NM_LBX: 2624 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB); 2625 gen_store_gpr(t0, rd); 2626 break; 2627 case NM_LHX: 2628 /*case NM_LHXS:*/ 2629 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 2630 mo_endian(ctx) | MO_SW | ctx->default_tcg_memop_mask); 2631 gen_store_gpr(t0, rd); 2632 break; 2633 case NM_LWX: 2634 /*case NM_LWXS:*/ 2635 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 2636 mo_endian(ctx) | MO_SL | ctx->default_tcg_memop_mask); 2637 gen_store_gpr(t0, rd); 2638 break; 2639 case NM_LBUX: 2640 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB); 2641 gen_store_gpr(t0, rd); 2642 break; 2643 case NM_LHUX: 2644 /*case NM_LHUXS:*/ 2645 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 2646 mo_endian(ctx) | MO_UW | ctx->default_tcg_memop_mask); 2647 gen_store_gpr(t0, rd); 2648 break; 2649 case NM_SBX: 2650 check_nms(ctx); 2651 gen_load_gpr(t1, rd); 2652 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8); 2653 break; 2654 case NM_SHX: 2655 /*case NM_SHXS:*/ 2656 check_nms(ctx); 2657 gen_load_gpr(t1, rd); 2658 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 2659 mo_endian(ctx) | MO_UW | ctx->default_tcg_memop_mask); 2660 break; 2661 case NM_SWX: 2662 /*case NM_SWXS:*/ 2663 check_nms(ctx); 2664 gen_load_gpr(t1, rd); 2665 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 2666 mo_endian(ctx) | MO_UL | ctx->default_tcg_memop_mask); 2667 break; 2668 case NM_LWC1X: 2669 /*case NM_LWC1XS:*/ 2670 case NM_LDC1X: 2671 /*case NM_LDC1XS:*/ 2672 case NM_SWC1X: 2673 /*case NM_SWC1XS:*/ 2674 case NM_SDC1X: 2675 /*case NM_SDC1XS:*/ 2676 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2677 check_cp1_enabled(ctx); 2678 switch (extract32(ctx->opcode, 7, 4)) { 2679 case NM_LWC1X: 2680 /*case NM_LWC1XS:*/ 2681 gen_flt_ldst(ctx, OPC_LWC1, rd, t0); 2682 break; 2683 case NM_LDC1X: 2684 /*case NM_LDC1XS:*/ 2685 gen_flt_ldst(ctx, OPC_LDC1, rd, t0); 2686 break; 2687 case NM_SWC1X: 2688 /*case NM_SWC1XS:*/ 2689 gen_flt_ldst(ctx, OPC_SWC1, rd, t0); 2690 break; 2691 case NM_SDC1X: 2692 /*case NM_SDC1XS:*/ 2693 gen_flt_ldst(ctx, OPC_SDC1, rd, t0); 2694 break; 2695 } 2696 } else { 2697 generate_exception_err(ctx, EXCP_CpU, 1); 2698 } 2699 break; 2700 default: 2701 gen_reserved_instruction(ctx); 2702 break; 2703 } 2704} 2705 2706static void gen_pool32f_nanomips_insn(DisasContext *ctx) 2707{ 2708 int rt, rs, rd; 2709 2710 rt = extract32(ctx->opcode, 21, 5); 2711 rs = extract32(ctx->opcode, 16, 5); 2712 rd = extract32(ctx->opcode, 11, 5); 2713 2714 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) { 2715 gen_reserved_instruction(ctx); 2716 return; 2717 } 2718 check_cp1_enabled(ctx); 2719 switch (extract32(ctx->opcode, 0, 3)) { 2720 case NM_POOL32F_0: 2721 switch (extract32(ctx->opcode, 3, 7)) { 2722 case NM_RINT_S: 2723 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); 2724 break; 2725 case NM_RINT_D: 2726 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); 2727 break; 2728 case NM_CLASS_S: 2729 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); 2730 break; 2731 case NM_CLASS_D: 2732 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); 2733 break; 2734 case NM_ADD_S: 2735 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0); 2736 break; 2737 case NM_ADD_D: 2738 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0); 2739 break; 2740 case NM_SUB_S: 2741 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0); 2742 break; 2743 case NM_SUB_D: 2744 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0); 2745 break; 2746 case NM_MUL_S: 2747 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0); 2748 break; 2749 case NM_MUL_D: 2750 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0); 2751 break; 2752 case NM_DIV_S: 2753 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0); 2754 break; 2755 case NM_DIV_D: 2756 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0); 2757 break; 2758 case NM_SELEQZ_S: 2759 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); 2760 break; 2761 case NM_SELEQZ_D: 2762 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); 2763 break; 2764 case NM_SELNEZ_S: 2765 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); 2766 break; 2767 case NM_SELNEZ_D: 2768 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); 2769 break; 2770 case NM_SEL_S: 2771 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); 2772 break; 2773 case NM_SEL_D: 2774 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); 2775 break; 2776 case NM_MADDF_S: 2777 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0); 2778 break; 2779 case NM_MADDF_D: 2780 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0); 2781 break; 2782 case NM_MSUBF_S: 2783 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0); 2784 break; 2785 case NM_MSUBF_D: 2786 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0); 2787 break; 2788 default: 2789 gen_reserved_instruction(ctx); 2790 break; 2791 } 2792 break; 2793 case NM_POOL32F_3: 2794 switch (extract32(ctx->opcode, 3, 3)) { 2795 case NM_MIN_FMT: 2796 switch (extract32(ctx->opcode, 9, 1)) { 2797 case FMT_SDPS_S: 2798 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); 2799 break; 2800 case FMT_SDPS_D: 2801 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); 2802 break; 2803 } 2804 break; 2805 case NM_MAX_FMT: 2806 switch (extract32(ctx->opcode, 9, 1)) { 2807 case FMT_SDPS_S: 2808 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); 2809 break; 2810 case FMT_SDPS_D: 2811 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); 2812 break; 2813 } 2814 break; 2815 case NM_MINA_FMT: 2816 switch (extract32(ctx->opcode, 9, 1)) { 2817 case FMT_SDPS_S: 2818 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); 2819 break; 2820 case FMT_SDPS_D: 2821 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); 2822 break; 2823 } 2824 break; 2825 case NM_MAXA_FMT: 2826 switch (extract32(ctx->opcode, 9, 1)) { 2827 case FMT_SDPS_S: 2828 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); 2829 break; 2830 case FMT_SDPS_D: 2831 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); 2832 break; 2833 } 2834 break; 2835 case NM_POOL32FXF: 2836 switch (extract32(ctx->opcode, 6, 8)) { 2837 case NM_CFC1: 2838 gen_cp1(ctx, OPC_CFC1, rt, rs); 2839 break; 2840 case NM_CTC1: 2841 gen_cp1(ctx, OPC_CTC1, rt, rs); 2842 break; 2843 case NM_MFC1: 2844 gen_cp1(ctx, OPC_MFC1, rt, rs); 2845 break; 2846 case NM_MTC1: 2847 gen_cp1(ctx, OPC_MTC1, rt, rs); 2848 break; 2849 case NM_MFHC1: 2850 gen_cp1(ctx, OPC_MFHC1, rt, rs); 2851 break; 2852 case NM_MTHC1: 2853 gen_cp1(ctx, OPC_MTHC1, rt, rs); 2854 break; 2855 case NM_CVT_S_PL: 2856 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0); 2857 break; 2858 case NM_CVT_S_PU: 2859 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0); 2860 break; 2861 default: 2862 switch (extract32(ctx->opcode, 6, 9)) { 2863 case NM_CVT_L_S: 2864 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0); 2865 break; 2866 case NM_CVT_L_D: 2867 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0); 2868 break; 2869 case NM_CVT_W_S: 2870 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0); 2871 break; 2872 case NM_CVT_W_D: 2873 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0); 2874 break; 2875 case NM_RSQRT_S: 2876 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0); 2877 break; 2878 case NM_RSQRT_D: 2879 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0); 2880 break; 2881 case NM_SQRT_S: 2882 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0); 2883 break; 2884 case NM_SQRT_D: 2885 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0); 2886 break; 2887 case NM_RECIP_S: 2888 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0); 2889 break; 2890 case NM_RECIP_D: 2891 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0); 2892 break; 2893 case NM_FLOOR_L_S: 2894 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0); 2895 break; 2896 case NM_FLOOR_L_D: 2897 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0); 2898 break; 2899 case NM_FLOOR_W_S: 2900 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0); 2901 break; 2902 case NM_FLOOR_W_D: 2903 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0); 2904 break; 2905 case NM_CEIL_L_S: 2906 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0); 2907 break; 2908 case NM_CEIL_L_D: 2909 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0); 2910 break; 2911 case NM_CEIL_W_S: 2912 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0); 2913 break; 2914 case NM_CEIL_W_D: 2915 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0); 2916 break; 2917 case NM_TRUNC_L_S: 2918 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0); 2919 break; 2920 case NM_TRUNC_L_D: 2921 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0); 2922 break; 2923 case NM_TRUNC_W_S: 2924 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0); 2925 break; 2926 case NM_TRUNC_W_D: 2927 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0); 2928 break; 2929 case NM_ROUND_L_S: 2930 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0); 2931 break; 2932 case NM_ROUND_L_D: 2933 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0); 2934 break; 2935 case NM_ROUND_W_S: 2936 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0); 2937 break; 2938 case NM_ROUND_W_D: 2939 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0); 2940 break; 2941 case NM_MOV_S: 2942 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0); 2943 break; 2944 case NM_MOV_D: 2945 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0); 2946 break; 2947 case NM_ABS_S: 2948 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0); 2949 break; 2950 case NM_ABS_D: 2951 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0); 2952 break; 2953 case NM_NEG_S: 2954 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0); 2955 break; 2956 case NM_NEG_D: 2957 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0); 2958 break; 2959 case NM_CVT_D_S: 2960 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0); 2961 break; 2962 case NM_CVT_D_W: 2963 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0); 2964 break; 2965 case NM_CVT_D_L: 2966 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0); 2967 break; 2968 case NM_CVT_S_D: 2969 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0); 2970 break; 2971 case NM_CVT_S_W: 2972 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0); 2973 break; 2974 case NM_CVT_S_L: 2975 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0); 2976 break; 2977 default: 2978 gen_reserved_instruction(ctx); 2979 break; 2980 } 2981 break; 2982 } 2983 break; 2984 } 2985 break; 2986 case NM_POOL32F_5: 2987 switch (extract32(ctx->opcode, 3, 3)) { 2988 case NM_CMP_CONDN_S: 2989 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); 2990 break; 2991 case NM_CMP_CONDN_D: 2992 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); 2993 break; 2994 default: 2995 gen_reserved_instruction(ctx); 2996 break; 2997 } 2998 break; 2999 default: 3000 gen_reserved_instruction(ctx); 3001 break; 3002 } 3003} 3004 3005static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, 3006 int rd, int rs, int rt) 3007{ 3008 int ret = rd; 3009 TCGv t0 = tcg_temp_new(); 3010 TCGv v1_t = tcg_temp_new(); 3011 TCGv v2_t = tcg_temp_new(); 3012 3013 gen_load_gpr(v1_t, rs); 3014 gen_load_gpr(v2_t, rt); 3015 3016 switch (opc) { 3017 case NM_CMP_EQ_PH: 3018 check_dsp(ctx); 3019 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env); 3020 break; 3021 case NM_CMP_LT_PH: 3022 check_dsp(ctx); 3023 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env); 3024 break; 3025 case NM_CMP_LE_PH: 3026 check_dsp(ctx); 3027 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env); 3028 break; 3029 case NM_CMPU_EQ_QB: 3030 check_dsp(ctx); 3031 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env); 3032 break; 3033 case NM_CMPU_LT_QB: 3034 check_dsp(ctx); 3035 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env); 3036 break; 3037 case NM_CMPU_LE_QB: 3038 check_dsp(ctx); 3039 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env); 3040 break; 3041 case NM_CMPGU_EQ_QB: 3042 check_dsp(ctx); 3043 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); 3044 gen_store_gpr(v1_t, ret); 3045 break; 3046 case NM_CMPGU_LT_QB: 3047 check_dsp(ctx); 3048 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); 3049 gen_store_gpr(v1_t, ret); 3050 break; 3051 case NM_CMPGU_LE_QB: 3052 check_dsp(ctx); 3053 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); 3054 gen_store_gpr(v1_t, ret); 3055 break; 3056 case NM_CMPGDU_EQ_QB: 3057 check_dsp_r2(ctx); 3058 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); 3059 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 3060 gen_store_gpr(v1_t, ret); 3061 break; 3062 case NM_CMPGDU_LT_QB: 3063 check_dsp_r2(ctx); 3064 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); 3065 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 3066 gen_store_gpr(v1_t, ret); 3067 break; 3068 case NM_CMPGDU_LE_QB: 3069 check_dsp_r2(ctx); 3070 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); 3071 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 3072 gen_store_gpr(v1_t, ret); 3073 break; 3074 case NM_PACKRL_PH: 3075 check_dsp(ctx); 3076 gen_helper_packrl_ph(v1_t, v1_t, v2_t); 3077 gen_store_gpr(v1_t, ret); 3078 break; 3079 case NM_PICK_QB: 3080 check_dsp(ctx); 3081 gen_helper_pick_qb(v1_t, v1_t, v2_t, tcg_env); 3082 gen_store_gpr(v1_t, ret); 3083 break; 3084 case NM_PICK_PH: 3085 check_dsp(ctx); 3086 gen_helper_pick_ph(v1_t, v1_t, v2_t, tcg_env); 3087 gen_store_gpr(v1_t, ret); 3088 break; 3089 case NM_ADDQ_S_W: 3090 check_dsp(ctx); 3091 gen_helper_addq_s_w(v1_t, v1_t, v2_t, tcg_env); 3092 gen_store_gpr(v1_t, ret); 3093 break; 3094 case NM_SUBQ_S_W: 3095 check_dsp(ctx); 3096 gen_helper_subq_s_w(v1_t, v1_t, v2_t, tcg_env); 3097 gen_store_gpr(v1_t, ret); 3098 break; 3099 case NM_ADDSC: 3100 check_dsp(ctx); 3101 gen_helper_addsc(v1_t, v1_t, v2_t, tcg_env); 3102 gen_store_gpr(v1_t, ret); 3103 break; 3104 case NM_ADDWC: 3105 check_dsp(ctx); 3106 gen_helper_addwc(v1_t, v1_t, v2_t, tcg_env); 3107 gen_store_gpr(v1_t, ret); 3108 break; 3109 case NM_ADDQ_S_PH: 3110 check_dsp(ctx); 3111 switch (extract32(ctx->opcode, 10, 1)) { 3112 case 0: 3113 /* ADDQ_PH */ 3114 gen_helper_addq_ph(v1_t, v1_t, v2_t, tcg_env); 3115 gen_store_gpr(v1_t, ret); 3116 break; 3117 case 1: 3118 /* ADDQ_S_PH */ 3119 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, tcg_env); 3120 gen_store_gpr(v1_t, ret); 3121 break; 3122 } 3123 break; 3124 case NM_ADDQH_R_PH: 3125 check_dsp_r2(ctx); 3126 switch (extract32(ctx->opcode, 10, 1)) { 3127 case 0: 3128 /* ADDQH_PH */ 3129 gen_helper_addqh_ph(v1_t, v1_t, v2_t); 3130 gen_store_gpr(v1_t, ret); 3131 break; 3132 case 1: 3133 /* ADDQH_R_PH */ 3134 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t); 3135 gen_store_gpr(v1_t, ret); 3136 break; 3137 } 3138 break; 3139 case NM_ADDQH_R_W: 3140 check_dsp_r2(ctx); 3141 switch (extract32(ctx->opcode, 10, 1)) { 3142 case 0: 3143 /* ADDQH_W */ 3144 gen_helper_addqh_w(v1_t, v1_t, v2_t); 3145 gen_store_gpr(v1_t, ret); 3146 break; 3147 case 1: 3148 /* ADDQH_R_W */ 3149 gen_helper_addqh_r_w(v1_t, v1_t, v2_t); 3150 gen_store_gpr(v1_t, ret); 3151 break; 3152 } 3153 break; 3154 case NM_ADDU_S_QB: 3155 check_dsp(ctx); 3156 switch (extract32(ctx->opcode, 10, 1)) { 3157 case 0: 3158 /* ADDU_QB */ 3159 gen_helper_addu_qb(v1_t, v1_t, v2_t, tcg_env); 3160 gen_store_gpr(v1_t, ret); 3161 break; 3162 case 1: 3163 /* ADDU_S_QB */ 3164 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, tcg_env); 3165 gen_store_gpr(v1_t, ret); 3166 break; 3167 } 3168 break; 3169 case NM_ADDU_S_PH: 3170 check_dsp_r2(ctx); 3171 switch (extract32(ctx->opcode, 10, 1)) { 3172 case 0: 3173 /* ADDU_PH */ 3174 gen_helper_addu_ph(v1_t, v1_t, v2_t, tcg_env); 3175 gen_store_gpr(v1_t, ret); 3176 break; 3177 case 1: 3178 /* ADDU_S_PH */ 3179 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, tcg_env); 3180 gen_store_gpr(v1_t, ret); 3181 break; 3182 } 3183 break; 3184 case NM_ADDUH_R_QB: 3185 check_dsp_r2(ctx); 3186 switch (extract32(ctx->opcode, 10, 1)) { 3187 case 0: 3188 /* ADDUH_QB */ 3189 gen_helper_adduh_qb(v1_t, v1_t, v2_t); 3190 gen_store_gpr(v1_t, ret); 3191 break; 3192 case 1: 3193 /* ADDUH_R_QB */ 3194 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t); 3195 gen_store_gpr(v1_t, ret); 3196 break; 3197 } 3198 break; 3199 case NM_SHRAV_R_PH: 3200 check_dsp(ctx); 3201 switch (extract32(ctx->opcode, 10, 1)) { 3202 case 0: 3203 /* SHRAV_PH */ 3204 gen_helper_shra_ph(v1_t, v1_t, v2_t); 3205 gen_store_gpr(v1_t, ret); 3206 break; 3207 case 1: 3208 /* SHRAV_R_PH */ 3209 gen_helper_shra_r_ph(v1_t, v1_t, v2_t); 3210 gen_store_gpr(v1_t, ret); 3211 break; 3212 } 3213 break; 3214 case NM_SHRAV_R_QB: 3215 check_dsp_r2(ctx); 3216 switch (extract32(ctx->opcode, 10, 1)) { 3217 case 0: 3218 /* SHRAV_QB */ 3219 gen_helper_shra_qb(v1_t, v1_t, v2_t); 3220 gen_store_gpr(v1_t, ret); 3221 break; 3222 case 1: 3223 /* SHRAV_R_QB */ 3224 gen_helper_shra_r_qb(v1_t, v1_t, v2_t); 3225 gen_store_gpr(v1_t, ret); 3226 break; 3227 } 3228 break; 3229 case NM_SUBQ_S_PH: 3230 check_dsp(ctx); 3231 switch (extract32(ctx->opcode, 10, 1)) { 3232 case 0: 3233 /* SUBQ_PH */ 3234 gen_helper_subq_ph(v1_t, v1_t, v2_t, tcg_env); 3235 gen_store_gpr(v1_t, ret); 3236 break; 3237 case 1: 3238 /* SUBQ_S_PH */ 3239 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, tcg_env); 3240 gen_store_gpr(v1_t, ret); 3241 break; 3242 } 3243 break; 3244 case NM_SUBQH_R_PH: 3245 check_dsp_r2(ctx); 3246 switch (extract32(ctx->opcode, 10, 1)) { 3247 case 0: 3248 /* SUBQH_PH */ 3249 gen_helper_subqh_ph(v1_t, v1_t, v2_t); 3250 gen_store_gpr(v1_t, ret); 3251 break; 3252 case 1: 3253 /* SUBQH_R_PH */ 3254 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t); 3255 gen_store_gpr(v1_t, ret); 3256 break; 3257 } 3258 break; 3259 case NM_SUBQH_R_W: 3260 check_dsp_r2(ctx); 3261 switch (extract32(ctx->opcode, 10, 1)) { 3262 case 0: 3263 /* SUBQH_W */ 3264 gen_helper_subqh_w(v1_t, v1_t, v2_t); 3265 gen_store_gpr(v1_t, ret); 3266 break; 3267 case 1: 3268 /* SUBQH_R_W */ 3269 gen_helper_subqh_r_w(v1_t, v1_t, v2_t); 3270 gen_store_gpr(v1_t, ret); 3271 break; 3272 } 3273 break; 3274 case NM_SUBU_S_QB: 3275 check_dsp(ctx); 3276 switch (extract32(ctx->opcode, 10, 1)) { 3277 case 0: 3278 /* SUBU_QB */ 3279 gen_helper_subu_qb(v1_t, v1_t, v2_t, tcg_env); 3280 gen_store_gpr(v1_t, ret); 3281 break; 3282 case 1: 3283 /* SUBU_S_QB */ 3284 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, tcg_env); 3285 gen_store_gpr(v1_t, ret); 3286 break; 3287 } 3288 break; 3289 case NM_SUBU_S_PH: 3290 check_dsp_r2(ctx); 3291 switch (extract32(ctx->opcode, 10, 1)) { 3292 case 0: 3293 /* SUBU_PH */ 3294 gen_helper_subu_ph(v1_t, v1_t, v2_t, tcg_env); 3295 gen_store_gpr(v1_t, ret); 3296 break; 3297 case 1: 3298 /* SUBU_S_PH */ 3299 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, tcg_env); 3300 gen_store_gpr(v1_t, ret); 3301 break; 3302 } 3303 break; 3304 case NM_SUBUH_R_QB: 3305 check_dsp_r2(ctx); 3306 switch (extract32(ctx->opcode, 10, 1)) { 3307 case 0: 3308 /* SUBUH_QB */ 3309 gen_helper_subuh_qb(v1_t, v1_t, v2_t); 3310 gen_store_gpr(v1_t, ret); 3311 break; 3312 case 1: 3313 /* SUBUH_R_QB */ 3314 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t); 3315 gen_store_gpr(v1_t, ret); 3316 break; 3317 } 3318 break; 3319 case NM_SHLLV_S_PH: 3320 check_dsp(ctx); 3321 switch (extract32(ctx->opcode, 10, 1)) { 3322 case 0: 3323 /* SHLLV_PH */ 3324 gen_helper_shll_ph(v1_t, v1_t, v2_t, tcg_env); 3325 gen_store_gpr(v1_t, ret); 3326 break; 3327 case 1: 3328 /* SHLLV_S_PH */ 3329 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, tcg_env); 3330 gen_store_gpr(v1_t, ret); 3331 break; 3332 } 3333 break; 3334 case NM_PRECR_SRA_R_PH_W: 3335 check_dsp_r2(ctx); 3336 switch (extract32(ctx->opcode, 10, 1)) { 3337 case 0: 3338 /* PRECR_SRA_PH_W */ 3339 { 3340 TCGv_i32 sa_t = tcg_constant_i32(rd); 3341 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t, 3342 cpu_gpr[rt]); 3343 gen_store_gpr(v1_t, rt); 3344 } 3345 break; 3346 case 1: 3347 /* PRECR_SRA_R_PH_W */ 3348 { 3349 TCGv_i32 sa_t = tcg_constant_i32(rd); 3350 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t, 3351 cpu_gpr[rt]); 3352 gen_store_gpr(v1_t, rt); 3353 } 3354 break; 3355 } 3356 break; 3357 case NM_MULEU_S_PH_QBL: 3358 check_dsp(ctx); 3359 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, tcg_env); 3360 gen_store_gpr(v1_t, ret); 3361 break; 3362 case NM_MULEU_S_PH_QBR: 3363 check_dsp(ctx); 3364 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, tcg_env); 3365 gen_store_gpr(v1_t, ret); 3366 break; 3367 case NM_MULQ_RS_PH: 3368 check_dsp(ctx); 3369 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, tcg_env); 3370 gen_store_gpr(v1_t, ret); 3371 break; 3372 case NM_MULQ_S_PH: 3373 check_dsp_r2(ctx); 3374 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, tcg_env); 3375 gen_store_gpr(v1_t, ret); 3376 break; 3377 case NM_MULQ_RS_W: 3378 check_dsp_r2(ctx); 3379 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, tcg_env); 3380 gen_store_gpr(v1_t, ret); 3381 break; 3382 case NM_MULQ_S_W: 3383 check_dsp_r2(ctx); 3384 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, tcg_env); 3385 gen_store_gpr(v1_t, ret); 3386 break; 3387 case NM_APPEND: 3388 check_dsp_r2(ctx); 3389 gen_load_gpr(t0, rs); 3390 if (rd != 0) { 3391 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd); 3392 } 3393 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 3394 break; 3395 case NM_MODSUB: 3396 check_dsp(ctx); 3397 gen_helper_modsub(v1_t, v1_t, v2_t); 3398 gen_store_gpr(v1_t, ret); 3399 break; 3400 case NM_SHRAV_R_W: 3401 check_dsp(ctx); 3402 gen_helper_shra_r_w(v1_t, v1_t, v2_t); 3403 gen_store_gpr(v1_t, ret); 3404 break; 3405 case NM_SHRLV_PH: 3406 check_dsp_r2(ctx); 3407 gen_helper_shrl_ph(v1_t, v1_t, v2_t); 3408 gen_store_gpr(v1_t, ret); 3409 break; 3410 case NM_SHRLV_QB: 3411 check_dsp(ctx); 3412 gen_helper_shrl_qb(v1_t, v1_t, v2_t); 3413 gen_store_gpr(v1_t, ret); 3414 break; 3415 case NM_SHLLV_QB: 3416 check_dsp(ctx); 3417 gen_helper_shll_qb(v1_t, v1_t, v2_t, tcg_env); 3418 gen_store_gpr(v1_t, ret); 3419 break; 3420 case NM_SHLLV_S_W: 3421 check_dsp(ctx); 3422 gen_helper_shll_s_w(v1_t, v1_t, v2_t, tcg_env); 3423 gen_store_gpr(v1_t, ret); 3424 break; 3425 case NM_SHILO: 3426 check_dsp(ctx); 3427 { 3428 int16_t imm = extract32(ctx->opcode, 16, 7); 3429 3430 gen_helper_shilo(tcg_constant_tl(rd >> 3), 3431 tcg_constant_tl(imm), tcg_env); 3432 } 3433 break; 3434 case NM_MULEQ_S_W_PHL: 3435 check_dsp(ctx); 3436 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, tcg_env); 3437 gen_store_gpr(v1_t, ret); 3438 break; 3439 case NM_MULEQ_S_W_PHR: 3440 check_dsp(ctx); 3441 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, tcg_env); 3442 gen_store_gpr(v1_t, ret); 3443 break; 3444 case NM_MUL_S_PH: 3445 check_dsp_r2(ctx); 3446 switch (extract32(ctx->opcode, 10, 1)) { 3447 case 0: 3448 /* MUL_PH */ 3449 gen_helper_mul_ph(v1_t, v1_t, v2_t, tcg_env); 3450 gen_store_gpr(v1_t, ret); 3451 break; 3452 case 1: 3453 /* MUL_S_PH */ 3454 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, tcg_env); 3455 gen_store_gpr(v1_t, ret); 3456 break; 3457 } 3458 break; 3459 case NM_PRECR_QB_PH: 3460 check_dsp_r2(ctx); 3461 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t); 3462 gen_store_gpr(v1_t, ret); 3463 break; 3464 case NM_PRECRQ_QB_PH: 3465 check_dsp(ctx); 3466 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t); 3467 gen_store_gpr(v1_t, ret); 3468 break; 3469 case NM_PRECRQ_PH_W: 3470 check_dsp(ctx); 3471 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t); 3472 gen_store_gpr(v1_t, ret); 3473 break; 3474 case NM_PRECRQ_RS_PH_W: 3475 check_dsp(ctx); 3476 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, tcg_env); 3477 gen_store_gpr(v1_t, ret); 3478 break; 3479 case NM_PRECRQU_S_QB_PH: 3480 check_dsp(ctx); 3481 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, tcg_env); 3482 gen_store_gpr(v1_t, ret); 3483 break; 3484 case NM_SHRA_R_W: 3485 check_dsp(ctx); 3486 gen_helper_shra_r_w(v1_t, tcg_constant_tl(rd), v1_t); 3487 gen_store_gpr(v1_t, rt); 3488 break; 3489 case NM_SHRA_R_PH: 3490 check_dsp(ctx); 3491 tcg_gen_movi_tl(t0, rd >> 1); 3492 switch (extract32(ctx->opcode, 10, 1)) { 3493 case 0: 3494 /* SHRA_PH */ 3495 gen_helper_shra_ph(v1_t, t0, v1_t); 3496 gen_store_gpr(v1_t, rt); 3497 break; 3498 case 1: 3499 /* SHRA_R_PH */ 3500 gen_helper_shra_r_ph(v1_t, t0, v1_t); 3501 gen_store_gpr(v1_t, rt); 3502 break; 3503 } 3504 break; 3505 case NM_SHLL_S_PH: 3506 check_dsp(ctx); 3507 tcg_gen_movi_tl(t0, rd >> 1); 3508 switch (extract32(ctx->opcode, 10, 2)) { 3509 case 0: 3510 /* SHLL_PH */ 3511 gen_helper_shll_ph(v1_t, t0, v1_t, tcg_env); 3512 gen_store_gpr(v1_t, rt); 3513 break; 3514 case 2: 3515 /* SHLL_S_PH */ 3516 gen_helper_shll_s_ph(v1_t, t0, v1_t, tcg_env); 3517 gen_store_gpr(v1_t, rt); 3518 break; 3519 default: 3520 gen_reserved_instruction(ctx); 3521 break; 3522 } 3523 break; 3524 case NM_SHLL_S_W: 3525 check_dsp(ctx); 3526 gen_helper_shll_s_w(v1_t, tcg_constant_tl(rd), v1_t, tcg_env); 3527 gen_store_gpr(v1_t, rt); 3528 break; 3529 case NM_REPL_PH: 3530 check_dsp(ctx); 3531 { 3532 int16_t imm; 3533 imm = sextract32(ctx->opcode, 11, 11); 3534 imm = (int16_t)(imm << 6) >> 6; 3535 if (rt != 0) { 3536 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm)); 3537 } 3538 } 3539 break; 3540 default: 3541 gen_reserved_instruction(ctx); 3542 break; 3543 } 3544} 3545 3546static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) 3547{ 3548 uint16_t insn; 3549 uint32_t op; 3550 int rt, rs, rd; 3551 int offset; 3552 int imm; 3553 3554 insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2); 3555 ctx->opcode = (ctx->opcode << 16) | insn; 3556 3557 rt = extract32(ctx->opcode, 21, 5); 3558 rs = extract32(ctx->opcode, 16, 5); 3559 rd = extract32(ctx->opcode, 11, 5); 3560 3561 op = extract32(ctx->opcode, 26, 6); 3562 switch (op) { 3563 case NM_P_ADDIU: 3564 if (rt == 0) { 3565 /* P.RI */ 3566 switch (extract32(ctx->opcode, 19, 2)) { 3567 case NM_SIGRIE: 3568 default: 3569 gen_reserved_instruction(ctx); 3570 break; 3571 case NM_P_SYSCALL: 3572 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) { 3573 generate_exception_end(ctx, EXCP_SYSCALL); 3574 } else { 3575 gen_reserved_instruction(ctx); 3576 } 3577 break; 3578 case NM_BREAK: 3579 generate_exception_end(ctx, EXCP_BREAK); 3580 break; 3581 case NM_SDBBP: 3582 if (is_uhi(ctx, extract32(ctx->opcode, 0, 19))) { 3583 ctx->base.is_jmp = DISAS_SEMIHOST; 3584 } else { 3585 if (ctx->hflags & MIPS_HFLAG_SBRI) { 3586 gen_reserved_instruction(ctx); 3587 } else { 3588 generate_exception_end(ctx, EXCP_DBp); 3589 } 3590 } 3591 break; 3592 } 3593 } else { 3594 /* NM_ADDIU */ 3595 imm = extract32(ctx->opcode, 0, 16); 3596 if (rs != 0) { 3597 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm); 3598 } else { 3599 tcg_gen_movi_tl(cpu_gpr[rt], imm); 3600 } 3601 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 3602 } 3603 break; 3604 case NM_ADDIUPC: 3605 if (rt != 0) { 3606 offset = sextract32(ctx->opcode, 0, 1) << 21 | 3607 extract32(ctx->opcode, 1, 20) << 1; 3608 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset); 3609 tcg_gen_movi_tl(cpu_gpr[rt], addr); 3610 } 3611 break; 3612 case NM_POOL32A: 3613 switch (ctx->opcode & 0x07) { 3614 case NM_POOL32A0: 3615 gen_pool32a0_nanomips_insn(env, ctx); 3616 break; 3617 case NM_POOL32A5: 3618 { 3619 int32_t op1 = extract32(ctx->opcode, 3, 7); 3620 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt); 3621 } 3622 break; 3623 case NM_POOL32A7: 3624 switch (extract32(ctx->opcode, 3, 3)) { 3625 case NM_P_LSX: 3626 gen_p_lsx(ctx, rd, rs, rt); 3627 break; 3628 case NM_LSA: 3629 /* 3630 * In nanoMIPS, the shift field directly encodes the shift 3631 * amount, meaning that the supported shift values are in 3632 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). 3633 */ 3634 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2) - 1); 3635 break; 3636 case NM_EXTW: 3637 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5)); 3638 break; 3639 case NM_POOL32AXF: 3640 gen_pool32axf_nanomips_insn(env, ctx); 3641 break; 3642 default: 3643 gen_reserved_instruction(ctx); 3644 break; 3645 } 3646 break; 3647 default: 3648 gen_reserved_instruction(ctx); 3649 break; 3650 } 3651 break; 3652 case NM_P_GP_W: 3653 switch (ctx->opcode & 0x03) { 3654 case NM_ADDIUGP_W: 3655 if (rt != 0) { 3656 offset = extract32(ctx->opcode, 0, 21); 3657 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset); 3658 } 3659 break; 3660 case NM_LWGP: 3661 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); 3662 break; 3663 case NM_SWGP: 3664 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); 3665 break; 3666 default: 3667 gen_reserved_instruction(ctx); 3668 break; 3669 } 3670 break; 3671 case NM_P48I: 3672 { 3673 insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 4); 3674 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16; 3675 switch (extract32(ctx->opcode, 16, 5)) { 3676 case NM_LI48: 3677 check_nms(ctx); 3678 if (rt != 0) { 3679 tcg_gen_movi_tl(cpu_gpr[rt], addr_off); 3680 } 3681 break; 3682 case NM_ADDIU48: 3683 check_nms(ctx); 3684 if (rt != 0) { 3685 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off); 3686 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 3687 } 3688 break; 3689 case NM_ADDIUGP48: 3690 check_nms(ctx); 3691 if (rt != 0) { 3692 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off); 3693 } 3694 break; 3695 case NM_ADDIUPC48: 3696 check_nms(ctx); 3697 if (rt != 0) { 3698 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 3699 addr_off); 3700 3701 tcg_gen_movi_tl(cpu_gpr[rt], addr); 3702 } 3703 break; 3704 case NM_LWPC48: 3705 check_nms(ctx); 3706 if (rt != 0) { 3707 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 3708 addr_off); 3709 3710 tcg_gen_qemu_ld_tl(cpu_gpr[rt], tcg_constant_tl(addr), 3711 ctx->mem_idx, 3712 mo_endian(ctx) | MO_SL 3713 | ctx->default_tcg_memop_mask); 3714 } 3715 break; 3716 case NM_SWPC48: 3717 check_nms(ctx); 3718 { 3719 TCGv t1; 3720 t1 = tcg_temp_new(); 3721 3722 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 3723 addr_off); 3724 3725 gen_load_gpr(t1, rt); 3726 3727 tcg_gen_qemu_st_tl(t1, tcg_constant_tl(addr), ctx->mem_idx, 3728 mo_endian(ctx) | MO_UL 3729 | ctx->default_tcg_memop_mask); 3730 } 3731 break; 3732 default: 3733 gen_reserved_instruction(ctx); 3734 break; 3735 } 3736 return 6; 3737 } 3738 case NM_P_U12: 3739 switch (extract32(ctx->opcode, 12, 4)) { 3740 case NM_ORI: 3741 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12)); 3742 break; 3743 case NM_XORI: 3744 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12)); 3745 break; 3746 case NM_ANDI: 3747 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12)); 3748 break; 3749 case NM_P_SR: 3750 switch (extract32(ctx->opcode, 20, 1)) { 3751 case NM_PP_SR: 3752 switch (ctx->opcode & 3) { 3753 case NM_SAVE: 3754 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4), 3755 extract32(ctx->opcode, 2, 1), 3756 extract32(ctx->opcode, 3, 9) << 3); 3757 break; 3758 case NM_RESTORE: 3759 case NM_RESTORE_JRC: 3760 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4), 3761 extract32(ctx->opcode, 2, 1), 3762 extract32(ctx->opcode, 3, 9) << 3); 3763 if ((ctx->opcode & 3) == NM_RESTORE_JRC) { 3764 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); 3765 } 3766 break; 3767 default: 3768 gen_reserved_instruction(ctx); 3769 break; 3770 } 3771 break; 3772 case NM_P_SR_F: 3773 gen_reserved_instruction(ctx); 3774 break; 3775 } 3776 break; 3777 case NM_SLTI: 3778 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12)); 3779 break; 3780 case NM_SLTIU: 3781 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12)); 3782 break; 3783 case NM_SEQI: 3784 { 3785 TCGv t0 = tcg_temp_new(); 3786 3787 imm = extract32(ctx->opcode, 0, 12); 3788 gen_load_gpr(t0, rs); 3789 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm); 3790 gen_store_gpr(t0, rt); 3791 } 3792 break; 3793 case NM_ADDIUNEG: 3794 imm = (int16_t) extract32(ctx->opcode, 0, 12); 3795 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm); 3796 break; 3797 case NM_P_SHIFT: 3798 { 3799 int shift = extract32(ctx->opcode, 0, 5); 3800 switch (extract32(ctx->opcode, 5, 4)) { 3801 case NM_P_SLL: 3802 if (rt == 0 && shift == 0) { 3803 /* NOP */ 3804 } else if (rt == 0 && shift == 3) { 3805 /* EHB - treat as NOP */ 3806 } else if (rt == 0 && shift == 5) { 3807 /* PAUSE - treat as NOP */ 3808 } else if (rt == 0 && shift == 6) { 3809 /* SYNC */ 3810 gen_sync(extract32(ctx->opcode, 16, 5)); 3811 } else { 3812 /* SLL */ 3813 gen_shift_imm(ctx, OPC_SLL, rt, rs, 3814 extract32(ctx->opcode, 0, 5)); 3815 } 3816 break; 3817 case NM_SRL: 3818 gen_shift_imm(ctx, OPC_SRL, rt, rs, 3819 extract32(ctx->opcode, 0, 5)); 3820 break; 3821 case NM_SRA: 3822 gen_shift_imm(ctx, OPC_SRA, rt, rs, 3823 extract32(ctx->opcode, 0, 5)); 3824 break; 3825 case NM_ROTR: 3826 gen_shift_imm(ctx, OPC_ROTR, rt, rs, 3827 extract32(ctx->opcode, 0, 5)); 3828 break; 3829 default: 3830 gen_reserved_instruction(ctx); 3831 break; 3832 } 3833 } 3834 break; 3835 case NM_P_ROTX: 3836 check_nms(ctx); 3837 if (rt != 0) { 3838 TCGv t0 = tcg_temp_new(); 3839 TCGv_i32 shift = 3840 tcg_constant_i32(extract32(ctx->opcode, 0, 5)); 3841 TCGv_i32 shiftx = 3842 tcg_constant_i32(extract32(ctx->opcode, 7, 4) << 1); 3843 TCGv_i32 stripe = 3844 tcg_constant_i32(extract32(ctx->opcode, 6, 1)); 3845 3846 gen_load_gpr(t0, rs); 3847 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe); 3848 } 3849 break; 3850 case NM_P_INS: 3851 switch (((ctx->opcode >> 10) & 2) | 3852 (extract32(ctx->opcode, 5, 1))) { 3853 case NM_INS: 3854 check_nms(ctx); 3855 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5), 3856 extract32(ctx->opcode, 6, 5)); 3857 break; 3858 default: 3859 gen_reserved_instruction(ctx); 3860 break; 3861 } 3862 break; 3863 case NM_P_EXT: 3864 switch (((ctx->opcode >> 10) & 2) | 3865 (extract32(ctx->opcode, 5, 1))) { 3866 case NM_EXT: 3867 check_nms(ctx); 3868 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5), 3869 extract32(ctx->opcode, 6, 5)); 3870 break; 3871 default: 3872 gen_reserved_instruction(ctx); 3873 break; 3874 } 3875 break; 3876 default: 3877 gen_reserved_instruction(ctx); 3878 break; 3879 } 3880 break; 3881 case NM_POOL32F: 3882 gen_pool32f_nanomips_insn(ctx); 3883 break; 3884 case NM_POOL32S: 3885 break; 3886 case NM_P_LUI: 3887 switch (extract32(ctx->opcode, 1, 1)) { 3888 case NM_LUI: 3889 if (rt != 0) { 3890 tcg_gen_movi_tl(cpu_gpr[rt], 3891 sextract32(ctx->opcode, 0, 1) << 31 | 3892 extract32(ctx->opcode, 2, 10) << 21 | 3893 extract32(ctx->opcode, 12, 9) << 12); 3894 } 3895 break; 3896 case NM_ALUIPC: 3897 if (rt != 0) { 3898 offset = sextract32(ctx->opcode, 0, 1) << 31 | 3899 extract32(ctx->opcode, 2, 10) << 21 | 3900 extract32(ctx->opcode, 12, 9) << 12; 3901 target_long addr; 3902 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset); 3903 tcg_gen_movi_tl(cpu_gpr[rt], addr); 3904 } 3905 break; 3906 } 3907 break; 3908 case NM_P_GP_BH: 3909 { 3910 uint32_t u = extract32(ctx->opcode, 0, 18); 3911 3912 switch (extract32(ctx->opcode, 18, 3)) { 3913 case NM_LBGP: 3914 gen_ld(ctx, OPC_LB, rt, 28, u); 3915 break; 3916 case NM_SBGP: 3917 gen_st(ctx, OPC_SB, rt, 28, u); 3918 break; 3919 case NM_LBUGP: 3920 gen_ld(ctx, OPC_LBU, rt, 28, u); 3921 break; 3922 case NM_ADDIUGP_B: 3923 if (rt != 0) { 3924 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u); 3925 } 3926 break; 3927 case NM_P_GP_LH: 3928 u &= ~1; 3929 switch (ctx->opcode & 1) { 3930 case NM_LHGP: 3931 gen_ld(ctx, OPC_LH, rt, 28, u); 3932 break; 3933 case NM_LHUGP: 3934 gen_ld(ctx, OPC_LHU, rt, 28, u); 3935 break; 3936 } 3937 break; 3938 case NM_P_GP_SH: 3939 u &= ~1; 3940 switch (ctx->opcode & 1) { 3941 case NM_SHGP: 3942 gen_st(ctx, OPC_SH, rt, 28, u); 3943 break; 3944 default: 3945 gen_reserved_instruction(ctx); 3946 break; 3947 } 3948 break; 3949 case NM_P_GP_CP1: 3950 u &= ~0x3; 3951 switch (ctx->opcode & 0x3) { 3952 case NM_LWC1GP: 3953 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u); 3954 break; 3955 case NM_LDC1GP: 3956 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u); 3957 break; 3958 case NM_SWC1GP: 3959 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u); 3960 break; 3961 case NM_SDC1GP: 3962 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u); 3963 break; 3964 } 3965 break; 3966 default: 3967 gen_reserved_instruction(ctx); 3968 break; 3969 } 3970 } 3971 break; 3972 case NM_P_LS_U12: 3973 { 3974 uint32_t u = extract32(ctx->opcode, 0, 12); 3975 3976 switch (extract32(ctx->opcode, 12, 4)) { 3977 case NM_P_PREFU12: 3978 if (rt == 31) { 3979 /* SYNCI */ 3980 /* 3981 * Break the TB to be able to sync copied instructions 3982 * immediately. 3983 */ 3984 ctx->base.is_jmp = DISAS_STOP; 3985 } else { 3986 /* PREF */ 3987 /* Treat as NOP. */ 3988 } 3989 break; 3990 case NM_LB: 3991 gen_ld(ctx, OPC_LB, rt, rs, u); 3992 break; 3993 case NM_LH: 3994 gen_ld(ctx, OPC_LH, rt, rs, u); 3995 break; 3996 case NM_LW: 3997 gen_ld(ctx, OPC_LW, rt, rs, u); 3998 break; 3999 case NM_LBU: 4000 gen_ld(ctx, OPC_LBU, rt, rs, u); 4001 break; 4002 case NM_LHU: 4003 gen_ld(ctx, OPC_LHU, rt, rs, u); 4004 break; 4005 case NM_SB: 4006 gen_st(ctx, OPC_SB, rt, rs, u); 4007 break; 4008 case NM_SH: 4009 gen_st(ctx, OPC_SH, rt, rs, u); 4010 break; 4011 case NM_SW: 4012 gen_st(ctx, OPC_SW, rt, rs, u); 4013 break; 4014 case NM_LWC1: 4015 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u); 4016 break; 4017 case NM_LDC1: 4018 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u); 4019 break; 4020 case NM_SWC1: 4021 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u); 4022 break; 4023 case NM_SDC1: 4024 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u); 4025 break; 4026 default: 4027 gen_reserved_instruction(ctx); 4028 break; 4029 } 4030 } 4031 break; 4032 case NM_P_LS_S9: 4033 { 4034 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) | 4035 extract32(ctx->opcode, 0, 8); 4036 4037 switch (extract32(ctx->opcode, 8, 3)) { 4038 case NM_P_LS_S0: 4039 switch (extract32(ctx->opcode, 11, 4)) { 4040 case NM_LBS9: 4041 gen_ld(ctx, OPC_LB, rt, rs, s); 4042 break; 4043 case NM_LHS9: 4044 gen_ld(ctx, OPC_LH, rt, rs, s); 4045 break; 4046 case NM_LWS9: 4047 gen_ld(ctx, OPC_LW, rt, rs, s); 4048 break; 4049 case NM_LBUS9: 4050 gen_ld(ctx, OPC_LBU, rt, rs, s); 4051 break; 4052 case NM_LHUS9: 4053 gen_ld(ctx, OPC_LHU, rt, rs, s); 4054 break; 4055 case NM_SBS9: 4056 gen_st(ctx, OPC_SB, rt, rs, s); 4057 break; 4058 case NM_SHS9: 4059 gen_st(ctx, OPC_SH, rt, rs, s); 4060 break; 4061 case NM_SWS9: 4062 gen_st(ctx, OPC_SW, rt, rs, s); 4063 break; 4064 case NM_LWC1S9: 4065 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s); 4066 break; 4067 case NM_LDC1S9: 4068 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s); 4069 break; 4070 case NM_SWC1S9: 4071 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s); 4072 break; 4073 case NM_SDC1S9: 4074 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s); 4075 break; 4076 case NM_P_PREFS9: 4077 if (rt == 31) { 4078 /* SYNCI */ 4079 /* 4080 * Break the TB to be able to sync copied instructions 4081 * immediately. 4082 */ 4083 ctx->base.is_jmp = DISAS_STOP; 4084 } else { 4085 /* PREF */ 4086 /* Treat as NOP. */ 4087 } 4088 break; 4089 default: 4090 gen_reserved_instruction(ctx); 4091 break; 4092 } 4093 break; 4094 case NM_P_LS_S1: 4095 switch (extract32(ctx->opcode, 11, 4)) { 4096 case NM_UALH: 4097 case NM_UASH: 4098 check_nms(ctx); 4099 { 4100 TCGv t0 = tcg_temp_new(); 4101 TCGv t1 = tcg_temp_new(); 4102 4103 gen_base_offset_addr(ctx, t0, rs, s); 4104 4105 switch (extract32(ctx->opcode, 11, 4)) { 4106 case NM_UALH: 4107 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 4108 mo_endian(ctx) | MO_SW | MO_UNALN); 4109 gen_store_gpr(t0, rt); 4110 break; 4111 case NM_UASH: 4112 gen_load_gpr(t1, rt); 4113 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 4114 mo_endian(ctx) | MO_UW | MO_UNALN); 4115 break; 4116 } 4117 } 4118 break; 4119 case NM_P_LL: 4120 switch (ctx->opcode & 0x03) { 4121 case NM_LL: 4122 gen_ld(ctx, OPC_LL, rt, rs, s); 4123 break; 4124 case NM_LLWP: 4125 check_xnp(ctx); 4126 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5)); 4127 break; 4128 default: 4129 gen_reserved_instruction(ctx); 4130 break; 4131 } 4132 break; 4133 case NM_P_SC: 4134 switch (ctx->opcode & 0x03) { 4135 case NM_SC: 4136 gen_st_cond(ctx, rt, rs, s, mo_endian(ctx) | MO_SL, 4137 false); 4138 break; 4139 case NM_SCWP: 4140 check_xnp(ctx); 4141 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5), 4142 false); 4143 break; 4144 default: 4145 gen_reserved_instruction(ctx); 4146 break; 4147 } 4148 break; 4149 case NM_CACHE: 4150 check_cp0_enabled(ctx); 4151 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 4152 gen_cache_operation(ctx, rt, rs, s); 4153 } 4154 break; 4155 default: 4156 gen_reserved_instruction(ctx); 4157 break; 4158 } 4159 break; 4160 case NM_P_LS_E0: 4161 switch (extract32(ctx->opcode, 11, 4)) { 4162 case NM_LBE: 4163 check_eva(ctx); 4164 check_cp0_enabled(ctx); 4165 gen_ld(ctx, OPC_LBE, rt, rs, s); 4166 break; 4167 case NM_SBE: 4168 check_eva(ctx); 4169 check_cp0_enabled(ctx); 4170 gen_st(ctx, OPC_SBE, rt, rs, s); 4171 break; 4172 case NM_LBUE: 4173 check_eva(ctx); 4174 check_cp0_enabled(ctx); 4175 gen_ld(ctx, OPC_LBUE, rt, rs, s); 4176 break; 4177 case NM_P_PREFE: 4178 if (rt == 31) { 4179 /* case NM_SYNCIE */ 4180 check_eva(ctx); 4181 check_cp0_enabled(ctx); 4182 /* 4183 * Break the TB to be able to sync copied instructions 4184 * immediately. 4185 */ 4186 ctx->base.is_jmp = DISAS_STOP; 4187 } else { 4188 /* case NM_PREFE */ 4189 check_eva(ctx); 4190 check_cp0_enabled(ctx); 4191 /* Treat as NOP. */ 4192 } 4193 break; 4194 case NM_LHE: 4195 check_eva(ctx); 4196 check_cp0_enabled(ctx); 4197 gen_ld(ctx, OPC_LHE, rt, rs, s); 4198 break; 4199 case NM_SHE: 4200 check_eva(ctx); 4201 check_cp0_enabled(ctx); 4202 gen_st(ctx, OPC_SHE, rt, rs, s); 4203 break; 4204 case NM_LHUE: 4205 check_eva(ctx); 4206 check_cp0_enabled(ctx); 4207 gen_ld(ctx, OPC_LHUE, rt, rs, s); 4208 break; 4209 case NM_CACHEE: 4210 check_eva(ctx); 4211 check_cp0_enabled(ctx); 4212 check_nms_dl_il_sl_tl_l2c(ctx); 4213 gen_cache_operation(ctx, rt, rs, s); 4214 break; 4215 case NM_LWE: 4216 check_eva(ctx); 4217 check_cp0_enabled(ctx); 4218 gen_ld(ctx, OPC_LWE, rt, rs, s); 4219 break; 4220 case NM_SWE: 4221 check_eva(ctx); 4222 check_cp0_enabled(ctx); 4223 gen_st(ctx, OPC_SWE, rt, rs, s); 4224 break; 4225 case NM_P_LLE: 4226 switch (extract32(ctx->opcode, 2, 2)) { 4227 case NM_LLE: 4228 check_xnp(ctx); 4229 check_eva(ctx); 4230 check_cp0_enabled(ctx); 4231 gen_ld(ctx, OPC_LLE, rt, rs, s); 4232 break; 4233 case NM_LLWPE: 4234 check_xnp(ctx); 4235 check_eva(ctx); 4236 check_cp0_enabled(ctx); 4237 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5)); 4238 break; 4239 default: 4240 gen_reserved_instruction(ctx); 4241 break; 4242 } 4243 break; 4244 case NM_P_SCE: 4245 switch (extract32(ctx->opcode, 2, 2)) { 4246 case NM_SCE: 4247 check_xnp(ctx); 4248 check_eva(ctx); 4249 check_cp0_enabled(ctx); 4250 gen_st_cond(ctx, rt, rs, s, mo_endian(ctx) | MO_SL, 4251 true); 4252 break; 4253 case NM_SCWPE: 4254 check_xnp(ctx); 4255 check_eva(ctx); 4256 check_cp0_enabled(ctx); 4257 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5), 4258 true); 4259 break; 4260 default: 4261 gen_reserved_instruction(ctx); 4262 break; 4263 } 4264 break; 4265 default: 4266 gen_reserved_instruction(ctx); 4267 break; 4268 } 4269 break; 4270 case NM_P_LS_WM: 4271 case NM_P_LS_UAWM: 4272 check_nms(ctx); 4273 { 4274 int count = extract32(ctx->opcode, 12, 3); 4275 int counter = 0; 4276 4277 offset = sextract32(ctx->opcode, 15, 1) << 8 | 4278 extract32(ctx->opcode, 0, 8); 4279 TCGv va = tcg_temp_new(); 4280 TCGv t1 = tcg_temp_new(); 4281 MemOp memop = (extract32(ctx->opcode, 8, 3)) == 4282 NM_P_LS_UAWM ? MO_UNALN : MO_ALIGN; 4283 4284 count = (count == 0) ? 8 : count; 4285 while (counter != count) { 4286 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10); 4287 int this_offset = offset + (counter << 2); 4288 4289 gen_base_offset_addr(ctx, va, rs, this_offset); 4290 4291 switch (extract32(ctx->opcode, 11, 1)) { 4292 case NM_LWM: 4293 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx, 4294 memop | mo_endian(ctx) | MO_SL); 4295 gen_store_gpr(t1, this_rt); 4296 if ((this_rt == rs) && 4297 (counter != (count - 1))) { 4298 /* UNPREDICTABLE */ 4299 } 4300 break; 4301 case NM_SWM: 4302 this_rt = (rt == 0) ? 0 : this_rt; 4303 gen_load_gpr(t1, this_rt); 4304 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx, 4305 memop | mo_endian(ctx) | MO_UL); 4306 break; 4307 } 4308 counter++; 4309 } 4310 } 4311 break; 4312 default: 4313 gen_reserved_instruction(ctx); 4314 break; 4315 } 4316 } 4317 break; 4318 case NM_MOVE_BALC: 4319 check_nms(ctx); 4320 { 4321 TCGv t0 = tcg_temp_new(); 4322 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 | 4323 extract32(ctx->opcode, 1, 20) << 1; 4324 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5; 4325 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 | 4326 extract32(ctx->opcode, 21, 3)); 4327 gen_load_gpr(t0, rt); 4328 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4329 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); 4330 } 4331 break; 4332 case NM_P_BAL: 4333 { 4334 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 | 4335 extract32(ctx->opcode, 1, 24) << 1; 4336 4337 if ((extract32(ctx->opcode, 25, 1)) == 0) { 4338 /* BC */ 4339 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s); 4340 } else { 4341 /* BALC */ 4342 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); 4343 } 4344 } 4345 break; 4346 case NM_P_J: 4347 switch (extract32(ctx->opcode, 12, 4)) { 4348 case NM_JALRC: 4349 case NM_JALRC_HB: 4350 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0); 4351 break; 4352 case NM_P_BALRSC: 4353 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt); 4354 break; 4355 default: 4356 gen_reserved_instruction(ctx); 4357 break; 4358 } 4359 break; 4360 case NM_P_BR1: 4361 { 4362 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 | 4363 extract32(ctx->opcode, 1, 13) << 1; 4364 switch (extract32(ctx->opcode, 14, 2)) { 4365 case NM_BEQC: 4366 check_nms(ctx); 4367 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s); 4368 break; 4369 case NM_P_BR3A: 4370 s = sextract32(ctx->opcode, 0, 1) << 14 | 4371 extract32(ctx->opcode, 1, 13) << 1; 4372 switch (extract32(ctx->opcode, 16, 5)) { 4373 case NM_BC1EQZC: 4374 check_cp1_enabled(ctx); 4375 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s); 4376 break; 4377 case NM_BC1NEZC: 4378 check_cp1_enabled(ctx); 4379 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s); 4380 break; 4381 case NM_BPOSGE32C: 4382 check_dsp_r3(ctx); 4383 { 4384 imm = extract32(ctx->opcode, 1, 13) 4385 | extract32(ctx->opcode, 0, 1) << 13; 4386 4387 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2, 4388 imm << 1); 4389 } 4390 break; 4391 default: 4392 gen_reserved_instruction(ctx); 4393 break; 4394 } 4395 break; 4396 case NM_BGEC: 4397 if (rs == rt) { 4398 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s); 4399 } else { 4400 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s); 4401 } 4402 break; 4403 case NM_BGEUC: 4404 if (rs == rt || rt == 0) { 4405 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s); 4406 } else if (rs == 0) { 4407 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s); 4408 } else { 4409 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s); 4410 } 4411 break; 4412 } 4413 } 4414 break; 4415 case NM_P_BR2: 4416 { 4417 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 | 4418 extract32(ctx->opcode, 1, 13) << 1; 4419 switch (extract32(ctx->opcode, 14, 2)) { 4420 case NM_BNEC: 4421 check_nms(ctx); 4422 if (rs == rt) { 4423 /* NOP */ 4424 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 4425 } else { 4426 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s); 4427 } 4428 break; 4429 case NM_BLTC: 4430 if (rs != 0 && rt != 0 && rs == rt) { 4431 /* NOP */ 4432 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 4433 } else { 4434 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s); 4435 } 4436 break; 4437 case NM_BLTUC: 4438 if (rs == 0 || rs == rt) { 4439 /* NOP */ 4440 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 4441 } else { 4442 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s); 4443 } 4444 break; 4445 default: 4446 gen_reserved_instruction(ctx); 4447 break; 4448 } 4449 } 4450 break; 4451 case NM_P_BRI: 4452 { 4453 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 | 4454 extract32(ctx->opcode, 1, 10) << 1; 4455 uint32_t u = extract32(ctx->opcode, 11, 7); 4456 4457 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3), 4458 rt, u, s); 4459 } 4460 break; 4461 default: 4462 gen_reserved_instruction(ctx); 4463 break; 4464 } 4465 return 4; 4466} 4467 4468static int decode_isa_nanomips(CPUMIPSState *env, DisasContext *ctx) 4469{ 4470 uint32_t op; 4471 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4472 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 4473 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode)); 4474 int offset; 4475 int imm; 4476 4477 /* make sure instructions are on a halfword boundary */ 4478 if (ctx->base.pc_next & 0x1) { 4479 TCGv tmp = tcg_constant_tl(ctx->base.pc_next); 4480 tcg_gen_st_tl(tmp, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 4481 generate_exception_end(ctx, EXCP_AdEL); 4482 return 2; 4483 } 4484 4485 op = extract32(ctx->opcode, 10, 6); 4486 switch (op) { 4487 case NM_P16_MV: 4488 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 4489 if (rt != 0) { 4490 /* MOVE */ 4491 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode); 4492 gen_arith(ctx, OPC_ADDU, rt, rs, 0); 4493 } else { 4494 /* P16.RI */ 4495 switch (extract32(ctx->opcode, 3, 2)) { 4496 case NM_P16_SYSCALL: 4497 if (extract32(ctx->opcode, 2, 1) == 0) { 4498 generate_exception_end(ctx, EXCP_SYSCALL); 4499 } else { 4500 gen_reserved_instruction(ctx); 4501 } 4502 break; 4503 case NM_BREAK16: 4504 generate_exception_end(ctx, EXCP_BREAK); 4505 break; 4506 case NM_SDBBP16: 4507 if (is_uhi(ctx, extract32(ctx->opcode, 0, 3))) { 4508 ctx->base.is_jmp = DISAS_SEMIHOST; 4509 } else { 4510 if (ctx->hflags & MIPS_HFLAG_SBRI) { 4511 gen_reserved_instruction(ctx); 4512 } else { 4513 generate_exception_end(ctx, EXCP_DBp); 4514 } 4515 } 4516 break; 4517 default: 4518 gen_reserved_instruction(ctx); 4519 break; 4520 } 4521 } 4522 break; 4523 case NM_P16_SHIFT: 4524 { 4525 int shift = extract32(ctx->opcode, 0, 3); 4526 uint32_t opc = 0; 4527 shift = (shift == 0) ? 8 : shift; 4528 4529 switch (extract32(ctx->opcode, 3, 1)) { 4530 case NM_SLL16: 4531 opc = OPC_SLL; 4532 break; 4533 case NM_SRL16: 4534 opc = OPC_SRL; 4535 break; 4536 } 4537 gen_shift_imm(ctx, opc, rt, rs, shift); 4538 } 4539 break; 4540 case NM_P16C: 4541 switch (ctx->opcode & 1) { 4542 case NM_POOL16C_0: 4543 gen_pool16c_nanomips_insn(ctx); 4544 break; 4545 case NM_LWXS16: 4546 gen_ldxs(ctx, rt, rs, rd); 4547 break; 4548 } 4549 break; 4550 case NM_P16_A1: 4551 switch (extract32(ctx->opcode, 6, 1)) { 4552 case NM_ADDIUR1SP: 4553 imm = extract32(ctx->opcode, 0, 6) << 2; 4554 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm); 4555 break; 4556 default: 4557 gen_reserved_instruction(ctx); 4558 break; 4559 } 4560 break; 4561 case NM_P16_A2: 4562 switch (extract32(ctx->opcode, 3, 1)) { 4563 case NM_ADDIUR2: 4564 imm = extract32(ctx->opcode, 0, 3) << 2; 4565 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm); 4566 break; 4567 case NM_P_ADDIURS5: 4568 rt = extract32(ctx->opcode, 5, 5); 4569 if (rt != 0) { 4570 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */ 4571 imm = (sextract32(ctx->opcode, 4, 1) << 3) | 4572 (extract32(ctx->opcode, 0, 3)); 4573 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm); 4574 } 4575 break; 4576 } 4577 break; 4578 case NM_P16_ADDU: 4579 switch (ctx->opcode & 0x1) { 4580 case NM_ADDU16: 4581 gen_arith(ctx, OPC_ADDU, rd, rs, rt); 4582 break; 4583 case NM_SUBU16: 4584 gen_arith(ctx, OPC_SUBU, rd, rs, rt); 4585 break; 4586 } 4587 break; 4588 case NM_P16_4X4: 4589 rt = (extract32(ctx->opcode, 9, 1) << 3) | 4590 extract32(ctx->opcode, 5, 3); 4591 rs = (extract32(ctx->opcode, 4, 1) << 3) | 4592 extract32(ctx->opcode, 0, 3); 4593 rt = decode_gpr_gpr4(rt); 4594 rs = decode_gpr_gpr4(rs); 4595 switch ((extract32(ctx->opcode, 7, 2) & 0x2) | 4596 (extract32(ctx->opcode, 3, 1))) { 4597 case NM_ADDU4X4: 4598 check_nms(ctx); 4599 gen_arith(ctx, OPC_ADDU, rt, rs, rt); 4600 break; 4601 case NM_MUL4X4: 4602 check_nms(ctx); 4603 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt); 4604 break; 4605 default: 4606 gen_reserved_instruction(ctx); 4607 break; 4608 } 4609 break; 4610 case NM_LI16: 4611 { 4612 imm = extract32(ctx->opcode, 0, 7); 4613 imm = (imm == 0x7f ? -1 : imm); 4614 if (rt != 0) { 4615 tcg_gen_movi_tl(cpu_gpr[rt], imm); 4616 } 4617 } 4618 break; 4619 case NM_ANDI16: 4620 { 4621 uint32_t u = extract32(ctx->opcode, 0, 4); 4622 u = (u == 12) ? 0xff : 4623 (u == 13) ? 0xffff : u; 4624 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u); 4625 } 4626 break; 4627 case NM_P16_LB: 4628 offset = extract32(ctx->opcode, 0, 2); 4629 switch (extract32(ctx->opcode, 2, 2)) { 4630 case NM_LB16: 4631 gen_ld(ctx, OPC_LB, rt, rs, offset); 4632 break; 4633 case NM_SB16: 4634 rt = decode_gpr_gpr3_src_store( 4635 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4636 gen_st(ctx, OPC_SB, rt, rs, offset); 4637 break; 4638 case NM_LBU16: 4639 gen_ld(ctx, OPC_LBU, rt, rs, offset); 4640 break; 4641 default: 4642 gen_reserved_instruction(ctx); 4643 break; 4644 } 4645 break; 4646 case NM_P16_LH: 4647 offset = extract32(ctx->opcode, 1, 2) << 1; 4648 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) { 4649 case NM_LH16: 4650 gen_ld(ctx, OPC_LH, rt, rs, offset); 4651 break; 4652 case NM_SH16: 4653 rt = decode_gpr_gpr3_src_store( 4654 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4655 gen_st(ctx, OPC_SH, rt, rs, offset); 4656 break; 4657 case NM_LHU16: 4658 gen_ld(ctx, OPC_LHU, rt, rs, offset); 4659 break; 4660 default: 4661 gen_reserved_instruction(ctx); 4662 break; 4663 } 4664 break; 4665 case NM_LW16: 4666 offset = extract32(ctx->opcode, 0, 4) << 2; 4667 gen_ld(ctx, OPC_LW, rt, rs, offset); 4668 break; 4669 case NM_LWSP16: 4670 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 4671 offset = extract32(ctx->opcode, 0, 5) << 2; 4672 gen_ld(ctx, OPC_LW, rt, 29, offset); 4673 break; 4674 case NM_LW4X4: 4675 check_nms(ctx); 4676 rt = (extract32(ctx->opcode, 9, 1) << 3) | 4677 extract32(ctx->opcode, 5, 3); 4678 rs = (extract32(ctx->opcode, 4, 1) << 3) | 4679 extract32(ctx->opcode, 0, 3); 4680 offset = (extract32(ctx->opcode, 3, 1) << 3) | 4681 (extract32(ctx->opcode, 8, 1) << 2); 4682 rt = decode_gpr_gpr4(rt); 4683 rs = decode_gpr_gpr4(rs); 4684 gen_ld(ctx, OPC_LW, rt, rs, offset); 4685 break; 4686 case NM_SW4X4: 4687 check_nms(ctx); 4688 rt = (extract32(ctx->opcode, 9, 1) << 3) | 4689 extract32(ctx->opcode, 5, 3); 4690 rs = (extract32(ctx->opcode, 4, 1) << 3) | 4691 extract32(ctx->opcode, 0, 3); 4692 offset = (extract32(ctx->opcode, 3, 1) << 3) | 4693 (extract32(ctx->opcode, 8, 1) << 2); 4694 rt = decode_gpr_gpr4_zero(rt); 4695 rs = decode_gpr_gpr4(rs); 4696 gen_st(ctx, OPC_SW, rt, rs, offset); 4697 break; 4698 case NM_LWGP16: 4699 offset = extract32(ctx->opcode, 0, 7) << 2; 4700 gen_ld(ctx, OPC_LW, rt, 28, offset); 4701 break; 4702 case NM_SWSP16: 4703 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 4704 offset = extract32(ctx->opcode, 0, 5) << 2; 4705 gen_st(ctx, OPC_SW, rt, 29, offset); 4706 break; 4707 case NM_SW16: 4708 rt = decode_gpr_gpr3_src_store( 4709 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4710 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 4711 offset = extract32(ctx->opcode, 0, 4) << 2; 4712 gen_st(ctx, OPC_SW, rt, rs, offset); 4713 break; 4714 case NM_SWGP16: 4715 rt = decode_gpr_gpr3_src_store( 4716 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4717 offset = extract32(ctx->opcode, 0, 7) << 2; 4718 gen_st(ctx, OPC_SW, rt, 28, offset); 4719 break; 4720 case NM_BC16: 4721 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0, 4722 (sextract32(ctx->opcode, 0, 1) << 10) | 4723 (extract32(ctx->opcode, 1, 9) << 1)); 4724 break; 4725 case NM_BALC16: 4726 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0, 4727 (sextract32(ctx->opcode, 0, 1) << 10) | 4728 (extract32(ctx->opcode, 1, 9) << 1)); 4729 break; 4730 case NM_BEQZC16: 4731 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0, 4732 (sextract32(ctx->opcode, 0, 1) << 7) | 4733 (extract32(ctx->opcode, 1, 6) << 1)); 4734 break; 4735 case NM_BNEZC16: 4736 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0, 4737 (sextract32(ctx->opcode, 0, 1) << 7) | 4738 (extract32(ctx->opcode, 1, 6) << 1)); 4739 break; 4740 case NM_P16_BR: 4741 switch (ctx->opcode & 0xf) { 4742 case 0: 4743 /* P16.JRC */ 4744 switch (extract32(ctx->opcode, 4, 1)) { 4745 case NM_JRC: 4746 gen_compute_branch_nm(ctx, OPC_JR, 2, 4747 extract32(ctx->opcode, 5, 5), 0, 0); 4748 break; 4749 case NM_JALRC16: 4750 gen_compute_branch_nm(ctx, OPC_JALR, 2, 4751 extract32(ctx->opcode, 5, 5), 31, 0); 4752 break; 4753 } 4754 break; 4755 default: 4756 { 4757 /* P16.BRI */ 4758 uint32_t opc = extract32(ctx->opcode, 4, 3) < 4759 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE; 4760 gen_compute_branch_nm(ctx, opc, 2, rs, rt, 4761 extract32(ctx->opcode, 0, 4) << 1); 4762 } 4763 break; 4764 } 4765 break; 4766 case NM_P16_SR: 4767 { 4768 int count = extract32(ctx->opcode, 0, 4); 4769 int u = extract32(ctx->opcode, 4, 4) << 4; 4770 4771 rt = 30 + extract32(ctx->opcode, 9, 1); 4772 switch (extract32(ctx->opcode, 8, 1)) { 4773 case NM_SAVE16: 4774 gen_save(ctx, rt, count, 0, u); 4775 break; 4776 case NM_RESTORE_JRC16: 4777 gen_restore(ctx, rt, count, 0, u); 4778 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); 4779 break; 4780 } 4781 } 4782 break; 4783 case NM_MOVEP: 4784 case NM_MOVEPREV: 4785 check_nms(ctx); 4786 { 4787 static const int gpr2reg1[] = {4, 5, 6, 7}; 4788 static const int gpr2reg2[] = {5, 6, 7, 8}; 4789 int re; 4790 int rd2 = extract32(ctx->opcode, 3, 1) << 1 | 4791 extract32(ctx->opcode, 8, 1); 4792 int r1 = gpr2reg1[rd2]; 4793 int r2 = gpr2reg2[rd2]; 4794 int r3 = extract32(ctx->opcode, 4, 1) << 3 | 4795 extract32(ctx->opcode, 0, 3); 4796 int r4 = extract32(ctx->opcode, 9, 1) << 3 | 4797 extract32(ctx->opcode, 5, 3); 4798 TCGv t0 = tcg_temp_new(); 4799 TCGv t1 = tcg_temp_new(); 4800 if (op == NM_MOVEP) { 4801 rd = r1; 4802 re = r2; 4803 rs = decode_gpr_gpr4_zero(r3); 4804 rt = decode_gpr_gpr4_zero(r4); 4805 } else { 4806 rd = decode_gpr_gpr4(r3); 4807 re = decode_gpr_gpr4(r4); 4808 rs = r1; 4809 rt = r2; 4810 } 4811 gen_load_gpr(t0, rs); 4812 gen_load_gpr(t1, rt); 4813 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4814 tcg_gen_mov_tl(cpu_gpr[re], t1); 4815 } 4816 break; 4817 default: 4818 return decode_nanomips_32_48_opc(env, ctx); 4819 } 4820 4821 return 2; 4822} 4823