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_ld64(tval, taddr, ctx->mem_idx); 1002 if (cpu_is_bigendian(ctx)) { 1003 tcg_gen_extr_i64_tl(tmp2, tmp1, tval); 1004 } else { 1005 tcg_gen_extr_i64_tl(tmp1, tmp2, tval); 1006 } 1007 gen_store_gpr(tmp1, reg1); 1008 gen_store_gpr(tmp2, reg2); 1009 tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp)); 1010 tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr)); 1011} 1012 1013static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset, 1014 uint32_t reg1, uint32_t reg2, bool eva) 1015{ 1016 TCGv taddr = tcg_temp_new(); 1017 TCGv lladdr = tcg_temp_new(); 1018 TCGv_i64 tval = tcg_temp_new_i64(); 1019 TCGv_i64 llval = tcg_temp_new_i64(); 1020 TCGv_i64 val = tcg_temp_new_i64(); 1021 TCGv tmp1 = tcg_temp_new(); 1022 TCGv tmp2 = tcg_temp_new(); 1023 TCGLabel *lab_fail = gen_new_label(); 1024 TCGLabel *lab_done = gen_new_label(); 1025 1026 gen_base_offset_addr(ctx, taddr, base, offset); 1027 1028 tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr)); 1029 tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail); 1030 1031 gen_load_gpr(tmp1, reg1); 1032 gen_load_gpr(tmp2, reg2); 1033 1034 if (cpu_is_bigendian(ctx)) { 1035 tcg_gen_concat_tl_i64(tval, tmp2, tmp1); 1036 } else { 1037 tcg_gen_concat_tl_i64(tval, tmp1, tmp2); 1038 } 1039 1040 tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp)); 1041 tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval, 1042 eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64); 1043 if (reg1 != 0) { 1044 tcg_gen_movi_tl(cpu_gpr[reg1], 1); 1045 } 1046 tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done); 1047 1048 gen_set_label(lab_fail); 1049 1050 if (reg1 != 0) { 1051 tcg_gen_movi_tl(cpu_gpr[reg1], 0); 1052 } 1053 gen_set_label(lab_done); 1054 tcg_gen_movi_tl(lladdr, -1); 1055 tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr)); 1056} 1057 1058static void gen_adjust_sp(DisasContext *ctx, int u) 1059{ 1060 gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u); 1061} 1062 1063static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count, 1064 uint8_t gp, uint16_t u) 1065{ 1066 int counter = 0; 1067 TCGv va = tcg_temp_new(); 1068 TCGv t0 = tcg_temp_new(); 1069 1070 while (counter != count) { 1071 bool use_gp = gp && (counter == count - 1); 1072 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f); 1073 int this_offset = -((counter + 1) << 2); 1074 gen_base_offset_addr(ctx, va, 29, this_offset); 1075 gen_load_gpr(t0, this_rt); 1076 tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx, 1077 (MO_TEUL | ctx->default_tcg_memop_mask)); 1078 counter++; 1079 } 1080 1081 /* adjust stack pointer */ 1082 gen_adjust_sp(ctx, -u); 1083} 1084 1085static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count, 1086 uint8_t gp, uint16_t u) 1087{ 1088 int counter = 0; 1089 TCGv va = tcg_temp_new(); 1090 TCGv t0 = tcg_temp_new(); 1091 1092 while (counter != count) { 1093 bool use_gp = gp && (counter == count - 1); 1094 int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f); 1095 int this_offset = u - ((counter + 1) << 2); 1096 gen_base_offset_addr(ctx, va, 29, this_offset); 1097 tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL | 1098 ctx->default_tcg_memop_mask); 1099 tcg_gen_ext32s_tl(t0, t0); 1100 gen_store_gpr(t0, this_rt); 1101 counter++; 1102 } 1103 1104 /* adjust stack pointer */ 1105 gen_adjust_sp(ctx, u); 1106} 1107 1108static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc, 1109 int insn_bytes, 1110 int rs, int rt, int32_t offset) 1111{ 1112 target_ulong btgt = -1; 1113 int bcond_compute = 0; 1114 TCGv t0 = tcg_temp_new(); 1115 TCGv t1 = tcg_temp_new(); 1116 1117 /* Load needed operands */ 1118 switch (opc) { 1119 case OPC_BEQ: 1120 case OPC_BNE: 1121 /* Compare two registers */ 1122 if (rs != rt) { 1123 gen_load_gpr(t0, rs); 1124 gen_load_gpr(t1, rt); 1125 bcond_compute = 1; 1126 } 1127 btgt = ctx->base.pc_next + insn_bytes + offset; 1128 break; 1129 case OPC_BGEZAL: 1130 /* Compare to zero */ 1131 if (rs != 0) { 1132 gen_load_gpr(t0, rs); 1133 bcond_compute = 1; 1134 } 1135 btgt = ctx->base.pc_next + insn_bytes + offset; 1136 break; 1137 case OPC_BPOSGE32: 1138 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F); 1139 bcond_compute = 1; 1140 btgt = ctx->base.pc_next + insn_bytes + offset; 1141 break; 1142 case OPC_JR: 1143 case OPC_JALR: 1144 /* Jump to register */ 1145 if (offset != 0 && offset != 16) { 1146 /* 1147 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the 1148 * others are reserved. 1149 */ 1150 MIPS_INVAL("jump hint"); 1151 gen_reserved_instruction(ctx); 1152 goto out; 1153 } 1154 gen_load_gpr(btarget, rs); 1155 break; 1156 default: 1157 MIPS_INVAL("branch/jump"); 1158 gen_reserved_instruction(ctx); 1159 goto out; 1160 } 1161 if (bcond_compute == 0) { 1162 /* No condition to be computed */ 1163 switch (opc) { 1164 case OPC_BEQ: /* rx == rx */ 1165 /* Always take */ 1166 ctx->hflags |= MIPS_HFLAG_B; 1167 break; 1168 case OPC_BGEZAL: /* 0 >= 0 */ 1169 /* Always take and link */ 1170 tcg_gen_movi_tl(cpu_gpr[31], 1171 ctx->base.pc_next + insn_bytes); 1172 ctx->hflags |= MIPS_HFLAG_B; 1173 break; 1174 case OPC_BNE: /* rx != rx */ 1175 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8); 1176 /* Skip the instruction in the delay slot */ 1177 ctx->base.pc_next += 4; 1178 goto out; 1179 case OPC_JR: 1180 ctx->hflags |= MIPS_HFLAG_BR; 1181 break; 1182 case OPC_JALR: 1183 if (rt > 0) { 1184 tcg_gen_movi_tl(cpu_gpr[rt], 1185 ctx->base.pc_next + insn_bytes); 1186 } 1187 ctx->hflags |= MIPS_HFLAG_BR; 1188 break; 1189 default: 1190 MIPS_INVAL("branch/jump"); 1191 gen_reserved_instruction(ctx); 1192 goto out; 1193 } 1194 } else { 1195 switch (opc) { 1196 case OPC_BEQ: 1197 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1); 1198 goto not_likely; 1199 case OPC_BNE: 1200 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1); 1201 goto not_likely; 1202 case OPC_BGEZAL: 1203 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0); 1204 tcg_gen_movi_tl(cpu_gpr[31], 1205 ctx->base.pc_next + insn_bytes); 1206 goto not_likely; 1207 case OPC_BPOSGE32: 1208 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32); 1209 not_likely: 1210 ctx->hflags |= MIPS_HFLAG_BC; 1211 break; 1212 default: 1213 MIPS_INVAL("conditional branch/jump"); 1214 gen_reserved_instruction(ctx); 1215 goto out; 1216 } 1217 } 1218 1219 ctx->btarget = btgt; 1220 1221 out: 1222 if (insn_bytes == 2) { 1223 ctx->hflags |= MIPS_HFLAG_B16; 1224 } 1225} 1226 1227static void gen_pool16c_nanomips_insn(DisasContext *ctx) 1228{ 1229 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); 1230 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 1231 1232 switch (extract32(ctx->opcode, 2, 2)) { 1233 case NM_NOT16: 1234 gen_logic(ctx, OPC_NOR, rt, rs, 0); 1235 break; 1236 case NM_AND16: 1237 gen_logic(ctx, OPC_AND, rt, rt, rs); 1238 break; 1239 case NM_XOR16: 1240 gen_logic(ctx, OPC_XOR, rt, rt, rs); 1241 break; 1242 case NM_OR16: 1243 gen_logic(ctx, OPC_OR, rt, rt, rs); 1244 break; 1245 } 1246} 1247 1248static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) 1249{ 1250 int rt = extract32(ctx->opcode, 21, 5); 1251 int rs = extract32(ctx->opcode, 16, 5); 1252 int rd = extract32(ctx->opcode, 11, 5); 1253 1254 switch (extract32(ctx->opcode, 3, 7)) { 1255 case NM_P_TRAP: 1256 switch (extract32(ctx->opcode, 10, 1)) { 1257 case NM_TEQ: 1258 check_nms(ctx); 1259 gen_trap(ctx, OPC_TEQ, rs, rt, -1, rd); 1260 break; 1261 case NM_TNE: 1262 check_nms(ctx); 1263 gen_trap(ctx, OPC_TNE, rs, rt, -1, rd); 1264 break; 1265 } 1266 break; 1267 case NM_RDHWR: 1268 check_nms(ctx); 1269 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3)); 1270 break; 1271 case NM_SEB: 1272 check_nms(ctx); 1273 gen_bshfl(ctx, OPC_SEB, rs, rt); 1274 break; 1275 case NM_SEH: 1276 gen_bshfl(ctx, OPC_SEH, rs, rt); 1277 break; 1278 case NM_SLLV: 1279 gen_shift(ctx, OPC_SLLV, rd, rt, rs); 1280 break; 1281 case NM_SRLV: 1282 gen_shift(ctx, OPC_SRLV, rd, rt, rs); 1283 break; 1284 case NM_SRAV: 1285 gen_shift(ctx, OPC_SRAV, rd, rt, rs); 1286 break; 1287 case NM_ROTRV: 1288 gen_shift(ctx, OPC_ROTRV, rd, rt, rs); 1289 break; 1290 case NM_ADD: 1291 gen_arith(ctx, OPC_ADD, rd, rs, rt); 1292 break; 1293 case NM_ADDU: 1294 gen_arith(ctx, OPC_ADDU, rd, rs, rt); 1295 break; 1296 case NM_SUB: 1297 check_nms(ctx); 1298 gen_arith(ctx, OPC_SUB, rd, rs, rt); 1299 break; 1300 case NM_SUBU: 1301 gen_arith(ctx, OPC_SUBU, rd, rs, rt); 1302 break; 1303 case NM_P_CMOVE: 1304 switch (extract32(ctx->opcode, 10, 1)) { 1305 case NM_MOVZ: 1306 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt); 1307 break; 1308 case NM_MOVN: 1309 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt); 1310 break; 1311 } 1312 break; 1313 case NM_AND: 1314 gen_logic(ctx, OPC_AND, rd, rs, rt); 1315 break; 1316 case NM_OR: 1317 gen_logic(ctx, OPC_OR, rd, rs, rt); 1318 break; 1319 case NM_NOR: 1320 gen_logic(ctx, OPC_NOR, rd, rs, rt); 1321 break; 1322 case NM_XOR: 1323 gen_logic(ctx, OPC_XOR, rd, rs, rt); 1324 break; 1325 case NM_SLT: 1326 gen_slt(ctx, OPC_SLT, rd, rs, rt); 1327 break; 1328 case NM_P_SLTU: 1329 if (rd == 0) { 1330 /* P_DVP */ 1331#ifndef CONFIG_USER_ONLY 1332 TCGv t0 = tcg_temp_new(); 1333 switch (extract32(ctx->opcode, 10, 1)) { 1334 case NM_DVP: 1335 if (ctx->vp) { 1336 check_cp0_enabled(ctx); 1337 gen_helper_dvp(t0, cpu_env); 1338 gen_store_gpr(t0, rt); 1339 } 1340 break; 1341 case NM_EVP: 1342 if (ctx->vp) { 1343 check_cp0_enabled(ctx); 1344 gen_helper_evp(t0, cpu_env); 1345 gen_store_gpr(t0, rt); 1346 } 1347 break; 1348 } 1349#endif 1350 } else { 1351 gen_slt(ctx, OPC_SLTU, rd, rs, rt); 1352 } 1353 break; 1354 case NM_SOV: 1355 { 1356 TCGv t0 = tcg_temp_new(); 1357 TCGv t1 = tcg_temp_new(); 1358 TCGv t2 = tcg_temp_new(); 1359 1360 gen_load_gpr(t1, rs); 1361 gen_load_gpr(t2, rt); 1362 tcg_gen_add_tl(t0, t1, t2); 1363 tcg_gen_ext32s_tl(t0, t0); 1364 tcg_gen_xor_tl(t1, t1, t2); 1365 tcg_gen_xor_tl(t2, t0, t2); 1366 tcg_gen_andc_tl(t1, t2, t1); 1367 1368 /* operands of same sign, result different sign */ 1369 tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0); 1370 gen_store_gpr(t0, rd); 1371 } 1372 break; 1373 case NM_MUL: 1374 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt); 1375 break; 1376 case NM_MUH: 1377 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt); 1378 break; 1379 case NM_MULU: 1380 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt); 1381 break; 1382 case NM_MUHU: 1383 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt); 1384 break; 1385 case NM_DIV: 1386 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt); 1387 break; 1388 case NM_MOD: 1389 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt); 1390 break; 1391 case NM_DIVU: 1392 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt); 1393 break; 1394 case NM_MODU: 1395 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt); 1396 break; 1397#ifndef CONFIG_USER_ONLY 1398 case NM_MFC0: 1399 check_cp0_enabled(ctx); 1400 if (rt == 0) { 1401 /* Treat as NOP. */ 1402 break; 1403 } 1404 gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3)); 1405 break; 1406 case NM_MTC0: 1407 check_cp0_enabled(ctx); 1408 { 1409 TCGv t0 = tcg_temp_new(); 1410 1411 gen_load_gpr(t0, rt); 1412 gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3)); 1413 } 1414 break; 1415 case NM_D_E_MT_VPE: 1416 { 1417 uint8_t sc = extract32(ctx->opcode, 10, 1); 1418 TCGv t0 = tcg_temp_new(); 1419 1420 switch (sc) { 1421 case 0: 1422 if (rs == 1) { 1423 /* DMT */ 1424 check_cp0_mt(ctx); 1425 gen_helper_dmt(t0); 1426 gen_store_gpr(t0, rt); 1427 } else if (rs == 0) { 1428 /* DVPE */ 1429 check_cp0_mt(ctx); 1430 gen_helper_dvpe(t0, cpu_env); 1431 gen_store_gpr(t0, rt); 1432 } else { 1433 gen_reserved_instruction(ctx); 1434 } 1435 break; 1436 case 1: 1437 if (rs == 1) { 1438 /* EMT */ 1439 check_cp0_mt(ctx); 1440 gen_helper_emt(t0); 1441 gen_store_gpr(t0, rt); 1442 } else if (rs == 0) { 1443 /* EVPE */ 1444 check_cp0_mt(ctx); 1445 gen_helper_evpe(t0, cpu_env); 1446 gen_store_gpr(t0, rt); 1447 } else { 1448 gen_reserved_instruction(ctx); 1449 } 1450 break; 1451 } 1452 } 1453 break; 1454 case NM_FORK: 1455 check_mt(ctx); 1456 { 1457 TCGv t0 = tcg_temp_new(); 1458 TCGv t1 = tcg_temp_new(); 1459 1460 gen_load_gpr(t0, rt); 1461 gen_load_gpr(t1, rs); 1462 gen_helper_fork(t0, t1); 1463 } 1464 break; 1465 case NM_MFTR: 1466 case NM_MFHTR: 1467 check_cp0_enabled(ctx); 1468 if (rd == 0) { 1469 /* Treat as NOP. */ 1470 return; 1471 } 1472 gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), 1473 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1)); 1474 break; 1475 case NM_MTTR: 1476 case NM_MTHTR: 1477 check_cp0_enabled(ctx); 1478 gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1), 1479 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1)); 1480 break; 1481 case NM_YIELD: 1482 check_mt(ctx); 1483 { 1484 TCGv t0 = tcg_temp_new(); 1485 1486 gen_load_gpr(t0, rs); 1487 gen_helper_yield(t0, cpu_env, t0); 1488 gen_store_gpr(t0, rt); 1489 } 1490 break; 1491#endif 1492 default: 1493 gen_reserved_instruction(ctx); 1494 break; 1495 } 1496} 1497 1498/* dsp */ 1499static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc, 1500 int ret, int v1, int v2) 1501{ 1502 TCGv_i32 t0; 1503 TCGv v0_t; 1504 TCGv v1_t; 1505 1506 t0 = tcg_temp_new_i32(); 1507 1508 v0_t = tcg_temp_new(); 1509 v1_t = tcg_temp_new(); 1510 1511 tcg_gen_movi_i32(t0, v2 >> 3); 1512 1513 gen_load_gpr(v0_t, ret); 1514 gen_load_gpr(v1_t, v1); 1515 1516 switch (opc) { 1517 case NM_MAQ_S_W_PHR: 1518 check_dsp(ctx); 1519 gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env); 1520 break; 1521 case NM_MAQ_S_W_PHL: 1522 check_dsp(ctx); 1523 gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env); 1524 break; 1525 case NM_MAQ_SA_W_PHR: 1526 check_dsp(ctx); 1527 gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env); 1528 break; 1529 case NM_MAQ_SA_W_PHL: 1530 check_dsp(ctx); 1531 gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env); 1532 break; 1533 default: 1534 gen_reserved_instruction(ctx); 1535 break; 1536 } 1537} 1538 1539 1540static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc, 1541 int ret, int v1, int v2) 1542{ 1543 int16_t imm; 1544 TCGv t0 = tcg_temp_new(); 1545 TCGv t1 = 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 tcg_gen_movi_tl(t0, v2 >> 3); 1573 gen_helper_mthlip(t0, v0_t, cpu_env); 1574 break; 1575 case NM_SHILOV: 1576 tcg_gen_movi_tl(t0, v2 >> 3); 1577 gen_helper_shilo(t0, v0_t, cpu_env); 1578 break; 1579 default: 1580 gen_reserved_instruction(ctx); 1581 break; 1582 } 1583 break; 1584 case NM_POOL32AXF_1_3: 1585 check_dsp(ctx); 1586 imm = extract32(ctx->opcode, 14, 7); 1587 switch (extract32(ctx->opcode, 12, 2)) { 1588 case NM_RDDSP: 1589 tcg_gen_movi_tl(t0, imm); 1590 gen_helper_rddsp(t0, t0, cpu_env); 1591 gen_store_gpr(t0, ret); 1592 break; 1593 case NM_WRDSP: 1594 gen_load_gpr(t0, ret); 1595 tcg_gen_movi_tl(t1, imm); 1596 gen_helper_wrdsp(t0, t1, cpu_env); 1597 break; 1598 case NM_EXTP: 1599 tcg_gen_movi_tl(t0, v2 >> 3); 1600 tcg_gen_movi_tl(t1, v1); 1601 gen_helper_extp(t0, t0, t1, cpu_env); 1602 gen_store_gpr(t0, ret); 1603 break; 1604 case NM_EXTPDP: 1605 tcg_gen_movi_tl(t0, v2 >> 3); 1606 tcg_gen_movi_tl(t1, v1); 1607 gen_helper_extpdp(t0, t0, t1, cpu_env); 1608 gen_store_gpr(t0, ret); 1609 break; 1610 } 1611 break; 1612 case NM_POOL32AXF_1_4: 1613 check_dsp(ctx); 1614 tcg_gen_movi_tl(t0, v2 >> 2); 1615 switch (extract32(ctx->opcode, 12, 1)) { 1616 case NM_SHLL_QB: 1617 gen_helper_shll_qb(t0, t0, v0_t, cpu_env); 1618 gen_store_gpr(t0, ret); 1619 break; 1620 case NM_SHRL_QB: 1621 gen_helper_shrl_qb(t0, t0, v0_t); 1622 gen_store_gpr(t0, ret); 1623 break; 1624 } 1625 break; 1626 case NM_POOL32AXF_1_5: 1627 opc = extract32(ctx->opcode, 12, 2); 1628 gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2); 1629 break; 1630 case NM_POOL32AXF_1_7: 1631 check_dsp(ctx); 1632 tcg_gen_movi_tl(t0, v2 >> 3); 1633 tcg_gen_movi_tl(t1, v1); 1634 switch (extract32(ctx->opcode, 12, 2)) { 1635 case NM_EXTR_W: 1636 gen_helper_extr_w(t0, t0, t1, cpu_env); 1637 gen_store_gpr(t0, ret); 1638 break; 1639 case NM_EXTR_R_W: 1640 gen_helper_extr_r_w(t0, t0, t1, cpu_env); 1641 gen_store_gpr(t0, ret); 1642 break; 1643 case NM_EXTR_RS_W: 1644 gen_helper_extr_rs_w(t0, t0, t1, cpu_env); 1645 gen_store_gpr(t0, ret); 1646 break; 1647 case NM_EXTR_S_H: 1648 gen_helper_extr_s_h(t0, t0, t1, cpu_env); 1649 gen_store_gpr(t0, ret); 1650 break; 1651 } 1652 break; 1653 default: 1654 gen_reserved_instruction(ctx); 1655 break; 1656 } 1657} 1658 1659static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc, 1660 TCGv v0, TCGv v1, int rd) 1661{ 1662 TCGv_i32 t0; 1663 1664 t0 = tcg_temp_new_i32(); 1665 1666 tcg_gen_movi_i32(t0, rd >> 3); 1667 1668 switch (opc) { 1669 case NM_POOL32AXF_2_0_7: 1670 switch (extract32(ctx->opcode, 9, 3)) { 1671 case NM_DPA_W_PH: 1672 check_dsp_r2(ctx); 1673 gen_helper_dpa_w_ph(t0, v1, v0, cpu_env); 1674 break; 1675 case NM_DPAQ_S_W_PH: 1676 check_dsp(ctx); 1677 gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env); 1678 break; 1679 case NM_DPS_W_PH: 1680 check_dsp_r2(ctx); 1681 gen_helper_dps_w_ph(t0, v1, v0, cpu_env); 1682 break; 1683 case NM_DPSQ_S_W_PH: 1684 check_dsp(ctx); 1685 gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env); 1686 break; 1687 default: 1688 gen_reserved_instruction(ctx); 1689 break; 1690 } 1691 break; 1692 case NM_POOL32AXF_2_8_15: 1693 switch (extract32(ctx->opcode, 9, 3)) { 1694 case NM_DPAX_W_PH: 1695 check_dsp_r2(ctx); 1696 gen_helper_dpax_w_ph(t0, v0, v1, cpu_env); 1697 break; 1698 case NM_DPAQ_SA_L_W: 1699 check_dsp(ctx); 1700 gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env); 1701 break; 1702 case NM_DPSX_W_PH: 1703 check_dsp_r2(ctx); 1704 gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env); 1705 break; 1706 case NM_DPSQ_SA_L_W: 1707 check_dsp(ctx); 1708 gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env); 1709 break; 1710 default: 1711 gen_reserved_instruction(ctx); 1712 break; 1713 } 1714 break; 1715 case NM_POOL32AXF_2_16_23: 1716 switch (extract32(ctx->opcode, 9, 3)) { 1717 case NM_DPAU_H_QBL: 1718 check_dsp(ctx); 1719 gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env); 1720 break; 1721 case NM_DPAQX_S_W_PH: 1722 check_dsp_r2(ctx); 1723 gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env); 1724 break; 1725 case NM_DPSU_H_QBL: 1726 check_dsp(ctx); 1727 gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env); 1728 break; 1729 case NM_DPSQX_S_W_PH: 1730 check_dsp_r2(ctx); 1731 gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env); 1732 break; 1733 case NM_MULSA_W_PH: 1734 check_dsp_r2(ctx); 1735 gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env); 1736 break; 1737 default: 1738 gen_reserved_instruction(ctx); 1739 break; 1740 } 1741 break; 1742 case NM_POOL32AXF_2_24_31: 1743 switch (extract32(ctx->opcode, 9, 3)) { 1744 case NM_DPAU_H_QBR: 1745 check_dsp(ctx); 1746 gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env); 1747 break; 1748 case NM_DPAQX_SA_W_PH: 1749 check_dsp_r2(ctx); 1750 gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env); 1751 break; 1752 case NM_DPSU_H_QBR: 1753 check_dsp(ctx); 1754 gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env); 1755 break; 1756 case NM_DPSQX_SA_W_PH: 1757 check_dsp_r2(ctx); 1758 gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env); 1759 break; 1760 case NM_MULSAQ_S_W_PH: 1761 check_dsp(ctx); 1762 gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env); 1763 break; 1764 default: 1765 gen_reserved_instruction(ctx); 1766 break; 1767 } 1768 break; 1769 default: 1770 gen_reserved_instruction(ctx); 1771 break; 1772 } 1773} 1774 1775static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc, 1776 int rt, int rs, int rd) 1777{ 1778 int ret = rt; 1779 TCGv t0 = tcg_temp_new(); 1780 TCGv t1 = tcg_temp_new(); 1781 TCGv v0_t = tcg_temp_new(); 1782 TCGv v1_t = tcg_temp_new(); 1783 1784 gen_load_gpr(v0_t, rt); 1785 gen_load_gpr(v1_t, rs); 1786 1787 switch (opc) { 1788 case NM_POOL32AXF_2_0_7: 1789 switch (extract32(ctx->opcode, 9, 3)) { 1790 case NM_DPA_W_PH: 1791 case NM_DPAQ_S_W_PH: 1792 case NM_DPS_W_PH: 1793 case NM_DPSQ_S_W_PH: 1794 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 1795 break; 1796 case NM_BALIGN: 1797 check_dsp_r2(ctx); 1798 if (rt != 0) { 1799 gen_load_gpr(t0, rs); 1800 rd &= 3; 1801 if (rd != 0 && rd != 2) { 1802 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd); 1803 tcg_gen_ext32u_tl(t0, t0); 1804 tcg_gen_shri_tl(t0, t0, 8 * (4 - rd)); 1805 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0); 1806 } 1807 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]); 1808 } 1809 break; 1810 case NM_MADD: 1811 check_dsp(ctx); 1812 { 1813 int acc = extract32(ctx->opcode, 14, 2); 1814 TCGv_i64 t2 = tcg_temp_new_i64(); 1815 TCGv_i64 t3 = tcg_temp_new_i64(); 1816 1817 gen_load_gpr(t0, rt); 1818 gen_load_gpr(t1, rs); 1819 tcg_gen_ext_tl_i64(t2, t0); 1820 tcg_gen_ext_tl_i64(t3, t1); 1821 tcg_gen_mul_i64(t2, t2, t3); 1822 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 1823 tcg_gen_add_i64(t2, t2, t3); 1824 gen_move_low32(cpu_LO[acc], t2); 1825 gen_move_high32(cpu_HI[acc], t2); 1826 } 1827 break; 1828 case NM_MULT: 1829 check_dsp(ctx); 1830 { 1831 int acc = extract32(ctx->opcode, 14, 2); 1832 TCGv_i32 t2 = tcg_temp_new_i32(); 1833 TCGv_i32 t3 = tcg_temp_new_i32(); 1834 1835 if (acc || ctx->insn_flags & ISA_MIPS_R6) { 1836 check_dsp_r2(ctx); 1837 } 1838 gen_load_gpr(t0, rs); 1839 gen_load_gpr(t1, rt); 1840 tcg_gen_trunc_tl_i32(t2, t0); 1841 tcg_gen_trunc_tl_i32(t3, t1); 1842 tcg_gen_muls2_i32(t2, t3, t2, t3); 1843 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 1844 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 1845 } 1846 break; 1847 case NM_EXTRV_W: 1848 check_dsp(ctx); 1849 gen_load_gpr(v1_t, rs); 1850 tcg_gen_movi_tl(t0, rd >> 3); 1851 gen_helper_extr_w(t0, t0, v1_t, cpu_env); 1852 gen_store_gpr(t0, ret); 1853 break; 1854 } 1855 break; 1856 case NM_POOL32AXF_2_8_15: 1857 switch (extract32(ctx->opcode, 9, 3)) { 1858 case NM_DPAX_W_PH: 1859 case NM_DPAQ_SA_L_W: 1860 case NM_DPSX_W_PH: 1861 case NM_DPSQ_SA_L_W: 1862 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 1863 break; 1864 case NM_MADDU: 1865 check_dsp(ctx); 1866 { 1867 int acc = extract32(ctx->opcode, 14, 2); 1868 TCGv_i64 t2 = tcg_temp_new_i64(); 1869 TCGv_i64 t3 = tcg_temp_new_i64(); 1870 1871 gen_load_gpr(t0, rs); 1872 gen_load_gpr(t1, rt); 1873 tcg_gen_ext32u_tl(t0, t0); 1874 tcg_gen_ext32u_tl(t1, t1); 1875 tcg_gen_extu_tl_i64(t2, t0); 1876 tcg_gen_extu_tl_i64(t3, t1); 1877 tcg_gen_mul_i64(t2, t2, t3); 1878 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 1879 tcg_gen_add_i64(t2, t2, t3); 1880 gen_move_low32(cpu_LO[acc], t2); 1881 gen_move_high32(cpu_HI[acc], t2); 1882 } 1883 break; 1884 case NM_MULTU: 1885 check_dsp(ctx); 1886 { 1887 int acc = extract32(ctx->opcode, 14, 2); 1888 TCGv_i32 t2 = tcg_temp_new_i32(); 1889 TCGv_i32 t3 = tcg_temp_new_i32(); 1890 1891 if (acc || ctx->insn_flags & ISA_MIPS_R6) { 1892 check_dsp_r2(ctx); 1893 } 1894 gen_load_gpr(t0, rs); 1895 gen_load_gpr(t1, rt); 1896 tcg_gen_trunc_tl_i32(t2, t0); 1897 tcg_gen_trunc_tl_i32(t3, t1); 1898 tcg_gen_mulu2_i32(t2, t3, t2, t3); 1899 tcg_gen_ext_i32_tl(cpu_LO[acc], t2); 1900 tcg_gen_ext_i32_tl(cpu_HI[acc], t3); 1901 } 1902 break; 1903 case NM_EXTRV_R_W: 1904 check_dsp(ctx); 1905 tcg_gen_movi_tl(t0, rd >> 3); 1906 gen_helper_extr_r_w(t0, t0, v1_t, cpu_env); 1907 gen_store_gpr(t0, ret); 1908 break; 1909 default: 1910 gen_reserved_instruction(ctx); 1911 break; 1912 } 1913 break; 1914 case NM_POOL32AXF_2_16_23: 1915 switch (extract32(ctx->opcode, 9, 3)) { 1916 case NM_DPAU_H_QBL: 1917 case NM_DPAQX_S_W_PH: 1918 case NM_DPSU_H_QBL: 1919 case NM_DPSQX_S_W_PH: 1920 case NM_MULSA_W_PH: 1921 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 1922 break; 1923 case NM_EXTPV: 1924 check_dsp(ctx); 1925 tcg_gen_movi_tl(t0, rd >> 3); 1926 gen_helper_extp(t0, t0, v1_t, cpu_env); 1927 gen_store_gpr(t0, ret); 1928 break; 1929 case NM_MSUB: 1930 check_dsp(ctx); 1931 { 1932 int acc = extract32(ctx->opcode, 14, 2); 1933 TCGv_i64 t2 = tcg_temp_new_i64(); 1934 TCGv_i64 t3 = tcg_temp_new_i64(); 1935 1936 gen_load_gpr(t0, rs); 1937 gen_load_gpr(t1, rt); 1938 tcg_gen_ext_tl_i64(t2, t0); 1939 tcg_gen_ext_tl_i64(t3, t1); 1940 tcg_gen_mul_i64(t2, t2, t3); 1941 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 1942 tcg_gen_sub_i64(t2, t3, t2); 1943 gen_move_low32(cpu_LO[acc], t2); 1944 gen_move_high32(cpu_HI[acc], t2); 1945 } 1946 break; 1947 case NM_EXTRV_RS_W: 1948 check_dsp(ctx); 1949 tcg_gen_movi_tl(t0, rd >> 3); 1950 gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env); 1951 gen_store_gpr(t0, ret); 1952 break; 1953 } 1954 break; 1955 case NM_POOL32AXF_2_24_31: 1956 switch (extract32(ctx->opcode, 9, 3)) { 1957 case NM_DPAU_H_QBR: 1958 case NM_DPAQX_SA_W_PH: 1959 case NM_DPSU_H_QBR: 1960 case NM_DPSQX_SA_W_PH: 1961 case NM_MULSAQ_S_W_PH: 1962 gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd); 1963 break; 1964 case NM_EXTPDPV: 1965 check_dsp(ctx); 1966 tcg_gen_movi_tl(t0, rd >> 3); 1967 gen_helper_extpdp(t0, t0, v1_t, cpu_env); 1968 gen_store_gpr(t0, ret); 1969 break; 1970 case NM_MSUBU: 1971 check_dsp(ctx); 1972 { 1973 int acc = extract32(ctx->opcode, 14, 2); 1974 TCGv_i64 t2 = tcg_temp_new_i64(); 1975 TCGv_i64 t3 = tcg_temp_new_i64(); 1976 1977 gen_load_gpr(t0, rs); 1978 gen_load_gpr(t1, rt); 1979 tcg_gen_ext32u_tl(t0, t0); 1980 tcg_gen_ext32u_tl(t1, t1); 1981 tcg_gen_extu_tl_i64(t2, t0); 1982 tcg_gen_extu_tl_i64(t3, t1); 1983 tcg_gen_mul_i64(t2, t2, t3); 1984 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); 1985 tcg_gen_sub_i64(t2, t3, t2); 1986 gen_move_low32(cpu_LO[acc], t2); 1987 gen_move_high32(cpu_HI[acc], t2); 1988 } 1989 break; 1990 case NM_EXTRV_S_H: 1991 check_dsp(ctx); 1992 tcg_gen_movi_tl(t0, rd >> 3); 1993 gen_helper_extr_s_h(t0, t0, v1_t, cpu_env); 1994 gen_store_gpr(t0, ret); 1995 break; 1996 } 1997 break; 1998 default: 1999 gen_reserved_instruction(ctx); 2000 break; 2001 } 2002} 2003 2004static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc, 2005 int rt, int rs) 2006{ 2007 int ret = rt; 2008 TCGv t0 = tcg_temp_new(); 2009 TCGv v0_t = tcg_temp_new(); 2010 2011 gen_load_gpr(v0_t, rs); 2012 2013 switch (opc) { 2014 case NM_ABSQ_S_QB: 2015 check_dsp_r2(ctx); 2016 gen_helper_absq_s_qb(v0_t, v0_t, cpu_env); 2017 gen_store_gpr(v0_t, ret); 2018 break; 2019 case NM_ABSQ_S_PH: 2020 check_dsp(ctx); 2021 gen_helper_absq_s_ph(v0_t, v0_t, cpu_env); 2022 gen_store_gpr(v0_t, ret); 2023 break; 2024 case NM_ABSQ_S_W: 2025 check_dsp(ctx); 2026 gen_helper_absq_s_w(v0_t, v0_t, cpu_env); 2027 gen_store_gpr(v0_t, ret); 2028 break; 2029 case NM_PRECEQ_W_PHL: 2030 check_dsp(ctx); 2031 tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000); 2032 tcg_gen_ext32s_tl(v0_t, v0_t); 2033 gen_store_gpr(v0_t, ret); 2034 break; 2035 case NM_PRECEQ_W_PHR: 2036 check_dsp(ctx); 2037 tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF); 2038 tcg_gen_shli_tl(v0_t, v0_t, 16); 2039 tcg_gen_ext32s_tl(v0_t, v0_t); 2040 gen_store_gpr(v0_t, ret); 2041 break; 2042 case NM_PRECEQU_PH_QBL: 2043 check_dsp(ctx); 2044 gen_helper_precequ_ph_qbl(v0_t, v0_t); 2045 gen_store_gpr(v0_t, ret); 2046 break; 2047 case NM_PRECEQU_PH_QBR: 2048 check_dsp(ctx); 2049 gen_helper_precequ_ph_qbr(v0_t, v0_t); 2050 gen_store_gpr(v0_t, ret); 2051 break; 2052 case NM_PRECEQU_PH_QBLA: 2053 check_dsp(ctx); 2054 gen_helper_precequ_ph_qbla(v0_t, v0_t); 2055 gen_store_gpr(v0_t, ret); 2056 break; 2057 case NM_PRECEQU_PH_QBRA: 2058 check_dsp(ctx); 2059 gen_helper_precequ_ph_qbra(v0_t, v0_t); 2060 gen_store_gpr(v0_t, ret); 2061 break; 2062 case NM_PRECEU_PH_QBL: 2063 check_dsp(ctx); 2064 gen_helper_preceu_ph_qbl(v0_t, v0_t); 2065 gen_store_gpr(v0_t, ret); 2066 break; 2067 case NM_PRECEU_PH_QBR: 2068 check_dsp(ctx); 2069 gen_helper_preceu_ph_qbr(v0_t, v0_t); 2070 gen_store_gpr(v0_t, ret); 2071 break; 2072 case NM_PRECEU_PH_QBLA: 2073 check_dsp(ctx); 2074 gen_helper_preceu_ph_qbla(v0_t, v0_t); 2075 gen_store_gpr(v0_t, ret); 2076 break; 2077 case NM_PRECEU_PH_QBRA: 2078 check_dsp(ctx); 2079 gen_helper_preceu_ph_qbra(v0_t, v0_t); 2080 gen_store_gpr(v0_t, ret); 2081 break; 2082 case NM_REPLV_PH: 2083 check_dsp(ctx); 2084 tcg_gen_ext16u_tl(v0_t, v0_t); 2085 tcg_gen_shli_tl(t0, v0_t, 16); 2086 tcg_gen_or_tl(v0_t, v0_t, t0); 2087 tcg_gen_ext32s_tl(v0_t, v0_t); 2088 gen_store_gpr(v0_t, ret); 2089 break; 2090 case NM_REPLV_QB: 2091 check_dsp(ctx); 2092 tcg_gen_ext8u_tl(v0_t, v0_t); 2093 tcg_gen_shli_tl(t0, v0_t, 8); 2094 tcg_gen_or_tl(v0_t, v0_t, t0); 2095 tcg_gen_shli_tl(t0, v0_t, 16); 2096 tcg_gen_or_tl(v0_t, v0_t, t0); 2097 tcg_gen_ext32s_tl(v0_t, v0_t); 2098 gen_store_gpr(v0_t, ret); 2099 break; 2100 case NM_BITREV: 2101 check_dsp(ctx); 2102 gen_helper_bitrev(v0_t, v0_t); 2103 gen_store_gpr(v0_t, ret); 2104 break; 2105 case NM_INSV: 2106 check_dsp(ctx); 2107 { 2108 TCGv tv0 = tcg_temp_new(); 2109 2110 gen_load_gpr(tv0, rt); 2111 gen_helper_insv(v0_t, cpu_env, v0_t, tv0); 2112 gen_store_gpr(v0_t, ret); 2113 } 2114 break; 2115 case NM_RADDU_W_QB: 2116 check_dsp(ctx); 2117 gen_helper_raddu_w_qb(v0_t, v0_t); 2118 gen_store_gpr(v0_t, ret); 2119 break; 2120 case NM_BITSWAP: 2121 gen_bitswap(ctx, OPC_BITSWAP, ret, rs); 2122 break; 2123 case NM_CLO: 2124 check_nms(ctx); 2125 gen_cl(ctx, OPC_CLO, ret, rs); 2126 break; 2127 case NM_CLZ: 2128 check_nms(ctx); 2129 gen_cl(ctx, OPC_CLZ, ret, rs); 2130 break; 2131 case NM_WSBH: 2132 gen_bshfl(ctx, OPC_WSBH, ret, rs); 2133 break; 2134 default: 2135 gen_reserved_instruction(ctx); 2136 break; 2137 } 2138} 2139 2140static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc, 2141 int rt, int rs, int rd) 2142{ 2143 TCGv t0 = tcg_temp_new(); 2144 TCGv rs_t = tcg_temp_new(); 2145 2146 gen_load_gpr(rs_t, rs); 2147 2148 switch (opc) { 2149 case NM_SHRA_R_QB: 2150 check_dsp_r2(ctx); 2151 tcg_gen_movi_tl(t0, rd >> 2); 2152 switch (extract32(ctx->opcode, 12, 1)) { 2153 case 0: 2154 /* NM_SHRA_QB */ 2155 gen_helper_shra_qb(t0, t0, rs_t); 2156 gen_store_gpr(t0, rt); 2157 break; 2158 case 1: 2159 /* NM_SHRA_R_QB */ 2160 gen_helper_shra_r_qb(t0, t0, rs_t); 2161 gen_store_gpr(t0, rt); 2162 break; 2163 } 2164 break; 2165 case NM_SHRL_PH: 2166 check_dsp_r2(ctx); 2167 tcg_gen_movi_tl(t0, rd >> 1); 2168 gen_helper_shrl_ph(t0, t0, rs_t); 2169 gen_store_gpr(t0, rt); 2170 break; 2171 case NM_REPL_QB: 2172 check_dsp(ctx); 2173 { 2174 int16_t imm; 2175 target_long result; 2176 imm = extract32(ctx->opcode, 13, 8); 2177 result = (uint32_t)imm << 24 | 2178 (uint32_t)imm << 16 | 2179 (uint32_t)imm << 8 | 2180 (uint32_t)imm; 2181 result = (int32_t)result; 2182 tcg_gen_movi_tl(t0, result); 2183 gen_store_gpr(t0, rt); 2184 } 2185 break; 2186 default: 2187 gen_reserved_instruction(ctx); 2188 break; 2189 } 2190} 2191 2192 2193static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx) 2194{ 2195 int rt = extract32(ctx->opcode, 21, 5); 2196 int rs = extract32(ctx->opcode, 16, 5); 2197 int rd = extract32(ctx->opcode, 11, 5); 2198 2199 switch (extract32(ctx->opcode, 6, 3)) { 2200 case NM_POOL32AXF_1: 2201 { 2202 int32_t op1 = extract32(ctx->opcode, 9, 3); 2203 gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd); 2204 } 2205 break; 2206 case NM_POOL32AXF_2: 2207 { 2208 int32_t op1 = extract32(ctx->opcode, 12, 2); 2209 gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd); 2210 } 2211 break; 2212 case NM_POOL32AXF_4: 2213 { 2214 int32_t op1 = extract32(ctx->opcode, 9, 7); 2215 gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs); 2216 } 2217 break; 2218 case NM_POOL32AXF_5: 2219 switch (extract32(ctx->opcode, 9, 7)) { 2220#ifndef CONFIG_USER_ONLY 2221 case NM_TLBP: 2222 gen_cp0(env, ctx, OPC_TLBP, 0, 0); 2223 break; 2224 case NM_TLBR: 2225 gen_cp0(env, ctx, OPC_TLBR, 0, 0); 2226 break; 2227 case NM_TLBWI: 2228 gen_cp0(env, ctx, OPC_TLBWI, 0, 0); 2229 break; 2230 case NM_TLBWR: 2231 gen_cp0(env, ctx, OPC_TLBWR, 0, 0); 2232 break; 2233 case NM_TLBINV: 2234 gen_cp0(env, ctx, OPC_TLBINV, 0, 0); 2235 break; 2236 case NM_TLBINVF: 2237 gen_cp0(env, ctx, OPC_TLBINVF, 0, 0); 2238 break; 2239 case NM_DI: 2240 check_cp0_enabled(ctx); 2241 { 2242 TCGv t0 = tcg_temp_new(); 2243 2244 save_cpu_state(ctx, 1); 2245 gen_helper_di(t0, cpu_env); 2246 gen_store_gpr(t0, rt); 2247 /* Stop translation as we may have switched the execution mode */ 2248 ctx->base.is_jmp = DISAS_STOP; 2249 } 2250 break; 2251 case NM_EI: 2252 check_cp0_enabled(ctx); 2253 { 2254 TCGv t0 = tcg_temp_new(); 2255 2256 save_cpu_state(ctx, 1); 2257 gen_helper_ei(t0, cpu_env); 2258 gen_store_gpr(t0, rt); 2259 /* Stop translation as we may have switched the execution mode */ 2260 ctx->base.is_jmp = DISAS_STOP; 2261 } 2262 break; 2263 case NM_RDPGPR: 2264 check_cp0_enabled(ctx); 2265 gen_load_srsgpr(rs, rt); 2266 break; 2267 case NM_WRPGPR: 2268 check_cp0_enabled(ctx); 2269 gen_store_srsgpr(rs, rt); 2270 break; 2271 case NM_WAIT: 2272 gen_cp0(env, ctx, OPC_WAIT, 0, 0); 2273 break; 2274 case NM_DERET: 2275 gen_cp0(env, ctx, OPC_DERET, 0, 0); 2276 break; 2277 case NM_ERETX: 2278 gen_cp0(env, ctx, OPC_ERET, 0, 0); 2279 break; 2280#endif 2281 default: 2282 gen_reserved_instruction(ctx); 2283 break; 2284 } 2285 break; 2286 case NM_POOL32AXF_7: 2287 { 2288 int32_t op1 = extract32(ctx->opcode, 9, 3); 2289 gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd); 2290 } 2291 break; 2292 default: 2293 gen_reserved_instruction(ctx); 2294 break; 2295 } 2296} 2297 2298/* Immediate Value Compact Branches */ 2299static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc, 2300 int rt, int32_t imm, int32_t offset) 2301{ 2302 TCGCond cond = TCG_COND_ALWAYS; 2303 TCGv t0 = tcg_temp_new(); 2304 TCGv t1 = tcg_temp_new(); 2305 2306 gen_load_gpr(t0, rt); 2307 tcg_gen_movi_tl(t1, imm); 2308 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2309 2310 /* Load needed operands and calculate btarget */ 2311 switch (opc) { 2312 case NM_BEQIC: 2313 if (rt == 0 && imm == 0) { 2314 /* Unconditional branch */ 2315 } else if (rt == 0 && imm != 0) { 2316 /* Treat as NOP */ 2317 return; 2318 } else { 2319 cond = TCG_COND_EQ; 2320 } 2321 break; 2322 case NM_BBEQZC: 2323 case NM_BBNEZC: 2324 check_nms(ctx); 2325 if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) { 2326 gen_reserved_instruction(ctx); 2327 return; 2328 } else if (rt == 0 && opc == NM_BBEQZC) { 2329 /* Unconditional branch */ 2330 } else if (rt == 0 && opc == NM_BBNEZC) { 2331 /* Treat as NOP */ 2332 return; 2333 } else { 2334 tcg_gen_shri_tl(t0, t0, imm); 2335 tcg_gen_andi_tl(t0, t0, 1); 2336 tcg_gen_movi_tl(t1, 0); 2337 if (opc == NM_BBEQZC) { 2338 cond = TCG_COND_EQ; 2339 } else { 2340 cond = TCG_COND_NE; 2341 } 2342 } 2343 break; 2344 case NM_BNEIC: 2345 if (rt == 0 && imm == 0) { 2346 /* Treat as NOP */ 2347 return; 2348 } else if (rt == 0 && imm != 0) { 2349 /* Unconditional branch */ 2350 } else { 2351 cond = TCG_COND_NE; 2352 } 2353 break; 2354 case NM_BGEIC: 2355 if (rt == 0 && imm == 0) { 2356 /* Unconditional branch */ 2357 } else { 2358 cond = TCG_COND_GE; 2359 } 2360 break; 2361 case NM_BLTIC: 2362 cond = TCG_COND_LT; 2363 break; 2364 case NM_BGEIUC: 2365 if (rt == 0 && imm == 0) { 2366 /* Unconditional branch */ 2367 } else { 2368 cond = TCG_COND_GEU; 2369 } 2370 break; 2371 case NM_BLTIUC: 2372 cond = TCG_COND_LTU; 2373 break; 2374 default: 2375 MIPS_INVAL("Immediate Value Compact branch"); 2376 gen_reserved_instruction(ctx); 2377 return; 2378 } 2379 2380 /* branch completion */ 2381 clear_branch_hflags(ctx); 2382 ctx->base.is_jmp = DISAS_NORETURN; 2383 2384 if (cond == TCG_COND_ALWAYS) { 2385 /* Uncoditional compact branch */ 2386 gen_goto_tb(ctx, 0, ctx->btarget); 2387 } else { 2388 /* Conditional compact branch */ 2389 TCGLabel *fs = gen_new_label(); 2390 2391 tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs); 2392 2393 gen_goto_tb(ctx, 1, ctx->btarget); 2394 gen_set_label(fs); 2395 2396 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); 2397 } 2398} 2399 2400/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */ 2401static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs, 2402 int rt) 2403{ 2404 TCGv t0 = tcg_temp_new(); 2405 TCGv t1 = tcg_temp_new(); 2406 2407 /* load rs */ 2408 gen_load_gpr(t0, rs); 2409 2410 /* link */ 2411 if (rt != 0) { 2412 tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4); 2413 } 2414 2415 /* calculate btarget */ 2416 tcg_gen_shli_tl(t0, t0, 1); 2417 tcg_gen_movi_tl(t1, ctx->base.pc_next + 4); 2418 gen_op_addr_add(ctx, btarget, t1, t0); 2419 2420 /* branch completion */ 2421 clear_branch_hflags(ctx); 2422 ctx->base.is_jmp = DISAS_NORETURN; 2423 2424 /* unconditional branch to register */ 2425 tcg_gen_mov_tl(cpu_PC, btarget); 2426 tcg_gen_lookup_and_goto_ptr(); 2427} 2428 2429/* nanoMIPS Branches */ 2430static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc, 2431 int rs, int rt, int32_t offset) 2432{ 2433 int bcond_compute = 0; 2434 TCGv t0 = tcg_temp_new(); 2435 TCGv t1 = tcg_temp_new(); 2436 2437 /* Load needed operands and calculate btarget */ 2438 switch (opc) { 2439 /* compact branch */ 2440 case OPC_BGEC: 2441 case OPC_BLTC: 2442 gen_load_gpr(t0, rs); 2443 gen_load_gpr(t1, rt); 2444 bcond_compute = 1; 2445 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2446 break; 2447 case OPC_BGEUC: 2448 case OPC_BLTUC: 2449 if (rs == 0 || rs == rt) { 2450 /* OPC_BLEZALC, OPC_BGEZALC */ 2451 /* OPC_BGTZALC, OPC_BLTZALC */ 2452 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4); 2453 } 2454 gen_load_gpr(t0, rs); 2455 gen_load_gpr(t1, rt); 2456 bcond_compute = 1; 2457 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2458 break; 2459 case OPC_BC: 2460 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2461 break; 2462 case OPC_BEQZC: 2463 if (rs != 0) { 2464 /* OPC_BEQZC, OPC_BNEZC */ 2465 gen_load_gpr(t0, rs); 2466 bcond_compute = 1; 2467 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2468 } else { 2469 /* OPC_JIC, OPC_JIALC */ 2470 TCGv tbase = tcg_temp_new(); 2471 TCGv toffset = tcg_temp_new(); 2472 2473 gen_load_gpr(tbase, rt); 2474 tcg_gen_movi_tl(toffset, offset); 2475 gen_op_addr_add(ctx, btarget, tbase, toffset); 2476 } 2477 break; 2478 default: 2479 MIPS_INVAL("Compact branch/jump"); 2480 gen_reserved_instruction(ctx); 2481 return; 2482 } 2483 2484 if (bcond_compute == 0) { 2485 /* Uncoditional compact branch */ 2486 switch (opc) { 2487 case OPC_BC: 2488 gen_goto_tb(ctx, 0, ctx->btarget); 2489 break; 2490 default: 2491 MIPS_INVAL("Compact branch/jump"); 2492 gen_reserved_instruction(ctx); 2493 return; 2494 } 2495 } else { 2496 /* Conditional compact branch */ 2497 TCGLabel *fs = gen_new_label(); 2498 2499 switch (opc) { 2500 case OPC_BGEUC: 2501 if (rs == 0 && rt != 0) { 2502 /* OPC_BLEZALC */ 2503 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 2504 } else if (rs != 0 && rt != 0 && rs == rt) { 2505 /* OPC_BGEZALC */ 2506 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 2507 } else { 2508 /* OPC_BGEUC */ 2509 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs); 2510 } 2511 break; 2512 case OPC_BLTUC: 2513 if (rs == 0 && rt != 0) { 2514 /* OPC_BGTZALC */ 2515 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 2516 } else if (rs != 0 && rt != 0 && rs == rt) { 2517 /* OPC_BLTZALC */ 2518 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 2519 } else { 2520 /* OPC_BLTUC */ 2521 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs); 2522 } 2523 break; 2524 case OPC_BGEC: 2525 if (rs == 0 && rt != 0) { 2526 /* OPC_BLEZC */ 2527 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs); 2528 } else if (rs != 0 && rt != 0 && rs == rt) { 2529 /* OPC_BGEZC */ 2530 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs); 2531 } else { 2532 /* OPC_BGEC */ 2533 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs); 2534 } 2535 break; 2536 case OPC_BLTC: 2537 if (rs == 0 && rt != 0) { 2538 /* OPC_BGTZC */ 2539 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs); 2540 } else if (rs != 0 && rt != 0 && rs == rt) { 2541 /* OPC_BLTZC */ 2542 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs); 2543 } else { 2544 /* OPC_BLTC */ 2545 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs); 2546 } 2547 break; 2548 case OPC_BEQZC: 2549 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs); 2550 break; 2551 default: 2552 MIPS_INVAL("Compact conditional branch/jump"); 2553 gen_reserved_instruction(ctx); 2554 return; 2555 } 2556 2557 /* branch completion */ 2558 clear_branch_hflags(ctx); 2559 ctx->base.is_jmp = DISAS_NORETURN; 2560 2561 /* Generating branch here as compact branches don't have delay slot */ 2562 gen_goto_tb(ctx, 1, ctx->btarget); 2563 gen_set_label(fs); 2564 2565 gen_goto_tb(ctx, 0, ctx->base.pc_next + 4); 2566 } 2567} 2568 2569 2570/* nanoMIPS CP1 Branches */ 2571static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op, 2572 int32_t ft, int32_t offset) 2573{ 2574 target_ulong btarget; 2575 TCGv_i64 t0 = tcg_temp_new_i64(); 2576 2577 gen_load_fpr64(ctx, t0, ft); 2578 tcg_gen_andi_i64(t0, t0, 1); 2579 2580 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset); 2581 2582 switch (op) { 2583 case NM_BC1EQZC: 2584 tcg_gen_xori_i64(t0, t0, 1); 2585 ctx->hflags |= MIPS_HFLAG_BC; 2586 break; 2587 case NM_BC1NEZC: 2588 /* t0 already set */ 2589 ctx->hflags |= MIPS_HFLAG_BC; 2590 break; 2591 default: 2592 MIPS_INVAL("cp1 cond branch"); 2593 gen_reserved_instruction(ctx); 2594 return; 2595 } 2596 2597 tcg_gen_trunc_i64_tl(bcond, t0); 2598 2599 ctx->btarget = btarget; 2600} 2601 2602 2603static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt) 2604{ 2605 TCGv t0, t1; 2606 t0 = tcg_temp_new(); 2607 t1 = tcg_temp_new(); 2608 2609 gen_load_gpr(t0, rs); 2610 gen_load_gpr(t1, rt); 2611 2612 if ((extract32(ctx->opcode, 6, 1)) == 1) { 2613 /* PP.LSXS instructions require shifting */ 2614 switch (extract32(ctx->opcode, 7, 4)) { 2615 case NM_SHXS: 2616 check_nms(ctx); 2617 /* fall through */ 2618 case NM_LHXS: 2619 case NM_LHUXS: 2620 tcg_gen_shli_tl(t0, t0, 1); 2621 break; 2622 case NM_SWXS: 2623 check_nms(ctx); 2624 /* fall through */ 2625 case NM_LWXS: 2626 case NM_LWC1XS: 2627 case NM_SWC1XS: 2628 tcg_gen_shli_tl(t0, t0, 2); 2629 break; 2630 case NM_LDC1XS: 2631 case NM_SDC1XS: 2632 tcg_gen_shli_tl(t0, t0, 3); 2633 break; 2634 default: 2635 gen_reserved_instruction(ctx); 2636 return; 2637 } 2638 } 2639 gen_op_addr_add(ctx, t0, t0, t1); 2640 2641 switch (extract32(ctx->opcode, 7, 4)) { 2642 case NM_LBX: 2643 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 2644 MO_SB); 2645 gen_store_gpr(t0, rd); 2646 break; 2647 case NM_LHX: 2648 /*case NM_LHXS:*/ 2649 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 2650 MO_TESW); 2651 gen_store_gpr(t0, rd); 2652 break; 2653 case NM_LWX: 2654 /*case NM_LWXS:*/ 2655 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 2656 MO_TESL); 2657 gen_store_gpr(t0, rd); 2658 break; 2659 case NM_LBUX: 2660 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 2661 MO_UB); 2662 gen_store_gpr(t0, rd); 2663 break; 2664 case NM_LHUX: 2665 /*case NM_LHUXS:*/ 2666 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, 2667 MO_TEUW); 2668 gen_store_gpr(t0, rd); 2669 break; 2670 case NM_SBX: 2671 check_nms(ctx); 2672 gen_load_gpr(t1, rd); 2673 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 2674 MO_8); 2675 break; 2676 case NM_SHX: 2677 /*case NM_SHXS:*/ 2678 check_nms(ctx); 2679 gen_load_gpr(t1, rd); 2680 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 2681 MO_TEUW); 2682 break; 2683 case NM_SWX: 2684 /*case NM_SWXS:*/ 2685 check_nms(ctx); 2686 gen_load_gpr(t1, rd); 2687 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, 2688 MO_TEUL); 2689 break; 2690 case NM_LWC1X: 2691 /*case NM_LWC1XS:*/ 2692 case NM_LDC1X: 2693 /*case NM_LDC1XS:*/ 2694 case NM_SWC1X: 2695 /*case NM_SWC1XS:*/ 2696 case NM_SDC1X: 2697 /*case NM_SDC1XS:*/ 2698 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { 2699 check_cp1_enabled(ctx); 2700 switch (extract32(ctx->opcode, 7, 4)) { 2701 case NM_LWC1X: 2702 /*case NM_LWC1XS:*/ 2703 gen_flt_ldst(ctx, OPC_LWC1, rd, t0); 2704 break; 2705 case NM_LDC1X: 2706 /*case NM_LDC1XS:*/ 2707 gen_flt_ldst(ctx, OPC_LDC1, rd, t0); 2708 break; 2709 case NM_SWC1X: 2710 /*case NM_SWC1XS:*/ 2711 gen_flt_ldst(ctx, OPC_SWC1, rd, t0); 2712 break; 2713 case NM_SDC1X: 2714 /*case NM_SDC1XS:*/ 2715 gen_flt_ldst(ctx, OPC_SDC1, rd, t0); 2716 break; 2717 } 2718 } else { 2719 generate_exception_err(ctx, EXCP_CpU, 1); 2720 } 2721 break; 2722 default: 2723 gen_reserved_instruction(ctx); 2724 break; 2725 } 2726} 2727 2728static void gen_pool32f_nanomips_insn(DisasContext *ctx) 2729{ 2730 int rt, rs, rd; 2731 2732 rt = extract32(ctx->opcode, 21, 5); 2733 rs = extract32(ctx->opcode, 16, 5); 2734 rd = extract32(ctx->opcode, 11, 5); 2735 2736 if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) { 2737 gen_reserved_instruction(ctx); 2738 return; 2739 } 2740 check_cp1_enabled(ctx); 2741 switch (extract32(ctx->opcode, 0, 3)) { 2742 case NM_POOL32F_0: 2743 switch (extract32(ctx->opcode, 3, 7)) { 2744 case NM_RINT_S: 2745 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0); 2746 break; 2747 case NM_RINT_D: 2748 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0); 2749 break; 2750 case NM_CLASS_S: 2751 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0); 2752 break; 2753 case NM_CLASS_D: 2754 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0); 2755 break; 2756 case NM_ADD_S: 2757 gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0); 2758 break; 2759 case NM_ADD_D: 2760 gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0); 2761 break; 2762 case NM_SUB_S: 2763 gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0); 2764 break; 2765 case NM_SUB_D: 2766 gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0); 2767 break; 2768 case NM_MUL_S: 2769 gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0); 2770 break; 2771 case NM_MUL_D: 2772 gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0); 2773 break; 2774 case NM_DIV_S: 2775 gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0); 2776 break; 2777 case NM_DIV_D: 2778 gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0); 2779 break; 2780 case NM_SELEQZ_S: 2781 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs); 2782 break; 2783 case NM_SELEQZ_D: 2784 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs); 2785 break; 2786 case NM_SELNEZ_S: 2787 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs); 2788 break; 2789 case NM_SELNEZ_D: 2790 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs); 2791 break; 2792 case NM_SEL_S: 2793 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs); 2794 break; 2795 case NM_SEL_D: 2796 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs); 2797 break; 2798 case NM_MADDF_S: 2799 gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0); 2800 break; 2801 case NM_MADDF_D: 2802 gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0); 2803 break; 2804 case NM_MSUBF_S: 2805 gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0); 2806 break; 2807 case NM_MSUBF_D: 2808 gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0); 2809 break; 2810 default: 2811 gen_reserved_instruction(ctx); 2812 break; 2813 } 2814 break; 2815 case NM_POOL32F_3: 2816 switch (extract32(ctx->opcode, 3, 3)) { 2817 case NM_MIN_FMT: 2818 switch (extract32(ctx->opcode, 9, 1)) { 2819 case FMT_SDPS_S: 2820 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0); 2821 break; 2822 case FMT_SDPS_D: 2823 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0); 2824 break; 2825 } 2826 break; 2827 case NM_MAX_FMT: 2828 switch (extract32(ctx->opcode, 9, 1)) { 2829 case FMT_SDPS_S: 2830 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0); 2831 break; 2832 case FMT_SDPS_D: 2833 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0); 2834 break; 2835 } 2836 break; 2837 case NM_MINA_FMT: 2838 switch (extract32(ctx->opcode, 9, 1)) { 2839 case FMT_SDPS_S: 2840 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0); 2841 break; 2842 case FMT_SDPS_D: 2843 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0); 2844 break; 2845 } 2846 break; 2847 case NM_MAXA_FMT: 2848 switch (extract32(ctx->opcode, 9, 1)) { 2849 case FMT_SDPS_S: 2850 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0); 2851 break; 2852 case FMT_SDPS_D: 2853 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0); 2854 break; 2855 } 2856 break; 2857 case NM_POOL32FXF: 2858 switch (extract32(ctx->opcode, 6, 8)) { 2859 case NM_CFC1: 2860 gen_cp1(ctx, OPC_CFC1, rt, rs); 2861 break; 2862 case NM_CTC1: 2863 gen_cp1(ctx, OPC_CTC1, rt, rs); 2864 break; 2865 case NM_MFC1: 2866 gen_cp1(ctx, OPC_MFC1, rt, rs); 2867 break; 2868 case NM_MTC1: 2869 gen_cp1(ctx, OPC_MTC1, rt, rs); 2870 break; 2871 case NM_MFHC1: 2872 gen_cp1(ctx, OPC_MFHC1, rt, rs); 2873 break; 2874 case NM_MTHC1: 2875 gen_cp1(ctx, OPC_MTHC1, rt, rs); 2876 break; 2877 case NM_CVT_S_PL: 2878 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0); 2879 break; 2880 case NM_CVT_S_PU: 2881 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0); 2882 break; 2883 default: 2884 switch (extract32(ctx->opcode, 6, 9)) { 2885 case NM_CVT_L_S: 2886 gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0); 2887 break; 2888 case NM_CVT_L_D: 2889 gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0); 2890 break; 2891 case NM_CVT_W_S: 2892 gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0); 2893 break; 2894 case NM_CVT_W_D: 2895 gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0); 2896 break; 2897 case NM_RSQRT_S: 2898 gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0); 2899 break; 2900 case NM_RSQRT_D: 2901 gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0); 2902 break; 2903 case NM_SQRT_S: 2904 gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0); 2905 break; 2906 case NM_SQRT_D: 2907 gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0); 2908 break; 2909 case NM_RECIP_S: 2910 gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0); 2911 break; 2912 case NM_RECIP_D: 2913 gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0); 2914 break; 2915 case NM_FLOOR_L_S: 2916 gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0); 2917 break; 2918 case NM_FLOOR_L_D: 2919 gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0); 2920 break; 2921 case NM_FLOOR_W_S: 2922 gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0); 2923 break; 2924 case NM_FLOOR_W_D: 2925 gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0); 2926 break; 2927 case NM_CEIL_L_S: 2928 gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0); 2929 break; 2930 case NM_CEIL_L_D: 2931 gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0); 2932 break; 2933 case NM_CEIL_W_S: 2934 gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0); 2935 break; 2936 case NM_CEIL_W_D: 2937 gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0); 2938 break; 2939 case NM_TRUNC_L_S: 2940 gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0); 2941 break; 2942 case NM_TRUNC_L_D: 2943 gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0); 2944 break; 2945 case NM_TRUNC_W_S: 2946 gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0); 2947 break; 2948 case NM_TRUNC_W_D: 2949 gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0); 2950 break; 2951 case NM_ROUND_L_S: 2952 gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0); 2953 break; 2954 case NM_ROUND_L_D: 2955 gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0); 2956 break; 2957 case NM_ROUND_W_S: 2958 gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0); 2959 break; 2960 case NM_ROUND_W_D: 2961 gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0); 2962 break; 2963 case NM_MOV_S: 2964 gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0); 2965 break; 2966 case NM_MOV_D: 2967 gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0); 2968 break; 2969 case NM_ABS_S: 2970 gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0); 2971 break; 2972 case NM_ABS_D: 2973 gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0); 2974 break; 2975 case NM_NEG_S: 2976 gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0); 2977 break; 2978 case NM_NEG_D: 2979 gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0); 2980 break; 2981 case NM_CVT_D_S: 2982 gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0); 2983 break; 2984 case NM_CVT_D_W: 2985 gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0); 2986 break; 2987 case NM_CVT_D_L: 2988 gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0); 2989 break; 2990 case NM_CVT_S_D: 2991 gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0); 2992 break; 2993 case NM_CVT_S_W: 2994 gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0); 2995 break; 2996 case NM_CVT_S_L: 2997 gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0); 2998 break; 2999 default: 3000 gen_reserved_instruction(ctx); 3001 break; 3002 } 3003 break; 3004 } 3005 break; 3006 } 3007 break; 3008 case NM_POOL32F_5: 3009 switch (extract32(ctx->opcode, 3, 3)) { 3010 case NM_CMP_CONDN_S: 3011 gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); 3012 break; 3013 case NM_CMP_CONDN_D: 3014 gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd); 3015 break; 3016 default: 3017 gen_reserved_instruction(ctx); 3018 break; 3019 } 3020 break; 3021 default: 3022 gen_reserved_instruction(ctx); 3023 break; 3024 } 3025} 3026 3027static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc, 3028 int rd, int rs, int rt) 3029{ 3030 int ret = rd; 3031 TCGv t0 = tcg_temp_new(); 3032 TCGv v1_t = tcg_temp_new(); 3033 TCGv v2_t = tcg_temp_new(); 3034 3035 gen_load_gpr(v1_t, rs); 3036 gen_load_gpr(v2_t, rt); 3037 3038 switch (opc) { 3039 case NM_CMP_EQ_PH: 3040 check_dsp(ctx); 3041 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env); 3042 break; 3043 case NM_CMP_LT_PH: 3044 check_dsp(ctx); 3045 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env); 3046 break; 3047 case NM_CMP_LE_PH: 3048 check_dsp(ctx); 3049 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env); 3050 break; 3051 case NM_CMPU_EQ_QB: 3052 check_dsp(ctx); 3053 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env); 3054 break; 3055 case NM_CMPU_LT_QB: 3056 check_dsp(ctx); 3057 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env); 3058 break; 3059 case NM_CMPU_LE_QB: 3060 check_dsp(ctx); 3061 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env); 3062 break; 3063 case NM_CMPGU_EQ_QB: 3064 check_dsp(ctx); 3065 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); 3066 gen_store_gpr(v1_t, ret); 3067 break; 3068 case NM_CMPGU_LT_QB: 3069 check_dsp(ctx); 3070 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); 3071 gen_store_gpr(v1_t, ret); 3072 break; 3073 case NM_CMPGU_LE_QB: 3074 check_dsp(ctx); 3075 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); 3076 gen_store_gpr(v1_t, ret); 3077 break; 3078 case NM_CMPGDU_EQ_QB: 3079 check_dsp_r2(ctx); 3080 gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t); 3081 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 3082 gen_store_gpr(v1_t, ret); 3083 break; 3084 case NM_CMPGDU_LT_QB: 3085 check_dsp_r2(ctx); 3086 gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t); 3087 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 3088 gen_store_gpr(v1_t, ret); 3089 break; 3090 case NM_CMPGDU_LE_QB: 3091 check_dsp_r2(ctx); 3092 gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t); 3093 tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4); 3094 gen_store_gpr(v1_t, ret); 3095 break; 3096 case NM_PACKRL_PH: 3097 check_dsp(ctx); 3098 gen_helper_packrl_ph(v1_t, v1_t, v2_t); 3099 gen_store_gpr(v1_t, ret); 3100 break; 3101 case NM_PICK_QB: 3102 check_dsp(ctx); 3103 gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env); 3104 gen_store_gpr(v1_t, ret); 3105 break; 3106 case NM_PICK_PH: 3107 check_dsp(ctx); 3108 gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env); 3109 gen_store_gpr(v1_t, ret); 3110 break; 3111 case NM_ADDQ_S_W: 3112 check_dsp(ctx); 3113 gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env); 3114 gen_store_gpr(v1_t, ret); 3115 break; 3116 case NM_SUBQ_S_W: 3117 check_dsp(ctx); 3118 gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env); 3119 gen_store_gpr(v1_t, ret); 3120 break; 3121 case NM_ADDSC: 3122 check_dsp(ctx); 3123 gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env); 3124 gen_store_gpr(v1_t, ret); 3125 break; 3126 case NM_ADDWC: 3127 check_dsp(ctx); 3128 gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env); 3129 gen_store_gpr(v1_t, ret); 3130 break; 3131 case NM_ADDQ_S_PH: 3132 check_dsp(ctx); 3133 switch (extract32(ctx->opcode, 10, 1)) { 3134 case 0: 3135 /* ADDQ_PH */ 3136 gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env); 3137 gen_store_gpr(v1_t, ret); 3138 break; 3139 case 1: 3140 /* ADDQ_S_PH */ 3141 gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env); 3142 gen_store_gpr(v1_t, ret); 3143 break; 3144 } 3145 break; 3146 case NM_ADDQH_R_PH: 3147 check_dsp_r2(ctx); 3148 switch (extract32(ctx->opcode, 10, 1)) { 3149 case 0: 3150 /* ADDQH_PH */ 3151 gen_helper_addqh_ph(v1_t, v1_t, v2_t); 3152 gen_store_gpr(v1_t, ret); 3153 break; 3154 case 1: 3155 /* ADDQH_R_PH */ 3156 gen_helper_addqh_r_ph(v1_t, v1_t, v2_t); 3157 gen_store_gpr(v1_t, ret); 3158 break; 3159 } 3160 break; 3161 case NM_ADDQH_R_W: 3162 check_dsp_r2(ctx); 3163 switch (extract32(ctx->opcode, 10, 1)) { 3164 case 0: 3165 /* ADDQH_W */ 3166 gen_helper_addqh_w(v1_t, v1_t, v2_t); 3167 gen_store_gpr(v1_t, ret); 3168 break; 3169 case 1: 3170 /* ADDQH_R_W */ 3171 gen_helper_addqh_r_w(v1_t, v1_t, v2_t); 3172 gen_store_gpr(v1_t, ret); 3173 break; 3174 } 3175 break; 3176 case NM_ADDU_S_QB: 3177 check_dsp(ctx); 3178 switch (extract32(ctx->opcode, 10, 1)) { 3179 case 0: 3180 /* ADDU_QB */ 3181 gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env); 3182 gen_store_gpr(v1_t, ret); 3183 break; 3184 case 1: 3185 /* ADDU_S_QB */ 3186 gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env); 3187 gen_store_gpr(v1_t, ret); 3188 break; 3189 } 3190 break; 3191 case NM_ADDU_S_PH: 3192 check_dsp_r2(ctx); 3193 switch (extract32(ctx->opcode, 10, 1)) { 3194 case 0: 3195 /* ADDU_PH */ 3196 gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env); 3197 gen_store_gpr(v1_t, ret); 3198 break; 3199 case 1: 3200 /* ADDU_S_PH */ 3201 gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env); 3202 gen_store_gpr(v1_t, ret); 3203 break; 3204 } 3205 break; 3206 case NM_ADDUH_R_QB: 3207 check_dsp_r2(ctx); 3208 switch (extract32(ctx->opcode, 10, 1)) { 3209 case 0: 3210 /* ADDUH_QB */ 3211 gen_helper_adduh_qb(v1_t, v1_t, v2_t); 3212 gen_store_gpr(v1_t, ret); 3213 break; 3214 case 1: 3215 /* ADDUH_R_QB */ 3216 gen_helper_adduh_r_qb(v1_t, v1_t, v2_t); 3217 gen_store_gpr(v1_t, ret); 3218 break; 3219 } 3220 break; 3221 case NM_SHRAV_R_PH: 3222 check_dsp(ctx); 3223 switch (extract32(ctx->opcode, 10, 1)) { 3224 case 0: 3225 /* SHRAV_PH */ 3226 gen_helper_shra_ph(v1_t, v1_t, v2_t); 3227 gen_store_gpr(v1_t, ret); 3228 break; 3229 case 1: 3230 /* SHRAV_R_PH */ 3231 gen_helper_shra_r_ph(v1_t, v1_t, v2_t); 3232 gen_store_gpr(v1_t, ret); 3233 break; 3234 } 3235 break; 3236 case NM_SHRAV_R_QB: 3237 check_dsp_r2(ctx); 3238 switch (extract32(ctx->opcode, 10, 1)) { 3239 case 0: 3240 /* SHRAV_QB */ 3241 gen_helper_shra_qb(v1_t, v1_t, v2_t); 3242 gen_store_gpr(v1_t, ret); 3243 break; 3244 case 1: 3245 /* SHRAV_R_QB */ 3246 gen_helper_shra_r_qb(v1_t, v1_t, v2_t); 3247 gen_store_gpr(v1_t, ret); 3248 break; 3249 } 3250 break; 3251 case NM_SUBQ_S_PH: 3252 check_dsp(ctx); 3253 switch (extract32(ctx->opcode, 10, 1)) { 3254 case 0: 3255 /* SUBQ_PH */ 3256 gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env); 3257 gen_store_gpr(v1_t, ret); 3258 break; 3259 case 1: 3260 /* SUBQ_S_PH */ 3261 gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env); 3262 gen_store_gpr(v1_t, ret); 3263 break; 3264 } 3265 break; 3266 case NM_SUBQH_R_PH: 3267 check_dsp_r2(ctx); 3268 switch (extract32(ctx->opcode, 10, 1)) { 3269 case 0: 3270 /* SUBQH_PH */ 3271 gen_helper_subqh_ph(v1_t, v1_t, v2_t); 3272 gen_store_gpr(v1_t, ret); 3273 break; 3274 case 1: 3275 /* SUBQH_R_PH */ 3276 gen_helper_subqh_r_ph(v1_t, v1_t, v2_t); 3277 gen_store_gpr(v1_t, ret); 3278 break; 3279 } 3280 break; 3281 case NM_SUBQH_R_W: 3282 check_dsp_r2(ctx); 3283 switch (extract32(ctx->opcode, 10, 1)) { 3284 case 0: 3285 /* SUBQH_W */ 3286 gen_helper_subqh_w(v1_t, v1_t, v2_t); 3287 gen_store_gpr(v1_t, ret); 3288 break; 3289 case 1: 3290 /* SUBQH_R_W */ 3291 gen_helper_subqh_r_w(v1_t, v1_t, v2_t); 3292 gen_store_gpr(v1_t, ret); 3293 break; 3294 } 3295 break; 3296 case NM_SUBU_S_QB: 3297 check_dsp(ctx); 3298 switch (extract32(ctx->opcode, 10, 1)) { 3299 case 0: 3300 /* SUBU_QB */ 3301 gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env); 3302 gen_store_gpr(v1_t, ret); 3303 break; 3304 case 1: 3305 /* SUBU_S_QB */ 3306 gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env); 3307 gen_store_gpr(v1_t, ret); 3308 break; 3309 } 3310 break; 3311 case NM_SUBU_S_PH: 3312 check_dsp_r2(ctx); 3313 switch (extract32(ctx->opcode, 10, 1)) { 3314 case 0: 3315 /* SUBU_PH */ 3316 gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env); 3317 gen_store_gpr(v1_t, ret); 3318 break; 3319 case 1: 3320 /* SUBU_S_PH */ 3321 gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env); 3322 gen_store_gpr(v1_t, ret); 3323 break; 3324 } 3325 break; 3326 case NM_SUBUH_R_QB: 3327 check_dsp_r2(ctx); 3328 switch (extract32(ctx->opcode, 10, 1)) { 3329 case 0: 3330 /* SUBUH_QB */ 3331 gen_helper_subuh_qb(v1_t, v1_t, v2_t); 3332 gen_store_gpr(v1_t, ret); 3333 break; 3334 case 1: 3335 /* SUBUH_R_QB */ 3336 gen_helper_subuh_r_qb(v1_t, v1_t, v2_t); 3337 gen_store_gpr(v1_t, ret); 3338 break; 3339 } 3340 break; 3341 case NM_SHLLV_S_PH: 3342 check_dsp(ctx); 3343 switch (extract32(ctx->opcode, 10, 1)) { 3344 case 0: 3345 /* SHLLV_PH */ 3346 gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env); 3347 gen_store_gpr(v1_t, ret); 3348 break; 3349 case 1: 3350 /* SHLLV_S_PH */ 3351 gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env); 3352 gen_store_gpr(v1_t, ret); 3353 break; 3354 } 3355 break; 3356 case NM_PRECR_SRA_R_PH_W: 3357 check_dsp_r2(ctx); 3358 switch (extract32(ctx->opcode, 10, 1)) { 3359 case 0: 3360 /* PRECR_SRA_PH_W */ 3361 { 3362 TCGv_i32 sa_t = tcg_constant_i32(rd); 3363 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t, 3364 cpu_gpr[rt]); 3365 gen_store_gpr(v1_t, rt); 3366 } 3367 break; 3368 case 1: 3369 /* PRECR_SRA_R_PH_W */ 3370 { 3371 TCGv_i32 sa_t = tcg_constant_i32(rd); 3372 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t, 3373 cpu_gpr[rt]); 3374 gen_store_gpr(v1_t, rt); 3375 } 3376 break; 3377 } 3378 break; 3379 case NM_MULEU_S_PH_QBL: 3380 check_dsp(ctx); 3381 gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env); 3382 gen_store_gpr(v1_t, ret); 3383 break; 3384 case NM_MULEU_S_PH_QBR: 3385 check_dsp(ctx); 3386 gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env); 3387 gen_store_gpr(v1_t, ret); 3388 break; 3389 case NM_MULQ_RS_PH: 3390 check_dsp(ctx); 3391 gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env); 3392 gen_store_gpr(v1_t, ret); 3393 break; 3394 case NM_MULQ_S_PH: 3395 check_dsp_r2(ctx); 3396 gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env); 3397 gen_store_gpr(v1_t, ret); 3398 break; 3399 case NM_MULQ_RS_W: 3400 check_dsp_r2(ctx); 3401 gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env); 3402 gen_store_gpr(v1_t, ret); 3403 break; 3404 case NM_MULQ_S_W: 3405 check_dsp_r2(ctx); 3406 gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env); 3407 gen_store_gpr(v1_t, ret); 3408 break; 3409 case NM_APPEND: 3410 check_dsp_r2(ctx); 3411 gen_load_gpr(t0, rs); 3412 if (rd != 0) { 3413 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd); 3414 } 3415 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 3416 break; 3417 case NM_MODSUB: 3418 check_dsp(ctx); 3419 gen_helper_modsub(v1_t, v1_t, v2_t); 3420 gen_store_gpr(v1_t, ret); 3421 break; 3422 case NM_SHRAV_R_W: 3423 check_dsp(ctx); 3424 gen_helper_shra_r_w(v1_t, v1_t, v2_t); 3425 gen_store_gpr(v1_t, ret); 3426 break; 3427 case NM_SHRLV_PH: 3428 check_dsp_r2(ctx); 3429 gen_helper_shrl_ph(v1_t, v1_t, v2_t); 3430 gen_store_gpr(v1_t, ret); 3431 break; 3432 case NM_SHRLV_QB: 3433 check_dsp(ctx); 3434 gen_helper_shrl_qb(v1_t, v1_t, v2_t); 3435 gen_store_gpr(v1_t, ret); 3436 break; 3437 case NM_SHLLV_QB: 3438 check_dsp(ctx); 3439 gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env); 3440 gen_store_gpr(v1_t, ret); 3441 break; 3442 case NM_SHLLV_S_W: 3443 check_dsp(ctx); 3444 gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env); 3445 gen_store_gpr(v1_t, ret); 3446 break; 3447 case NM_SHILO: 3448 check_dsp(ctx); 3449 { 3450 TCGv tv0 = tcg_temp_new(); 3451 TCGv tv1 = tcg_temp_new(); 3452 int16_t imm = extract32(ctx->opcode, 16, 7); 3453 3454 tcg_gen_movi_tl(tv0, rd >> 3); 3455 tcg_gen_movi_tl(tv1, imm); 3456 gen_helper_shilo(tv0, tv1, cpu_env); 3457 } 3458 break; 3459 case NM_MULEQ_S_W_PHL: 3460 check_dsp(ctx); 3461 gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env); 3462 gen_store_gpr(v1_t, ret); 3463 break; 3464 case NM_MULEQ_S_W_PHR: 3465 check_dsp(ctx); 3466 gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env); 3467 gen_store_gpr(v1_t, ret); 3468 break; 3469 case NM_MUL_S_PH: 3470 check_dsp_r2(ctx); 3471 switch (extract32(ctx->opcode, 10, 1)) { 3472 case 0: 3473 /* MUL_PH */ 3474 gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env); 3475 gen_store_gpr(v1_t, ret); 3476 break; 3477 case 1: 3478 /* MUL_S_PH */ 3479 gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env); 3480 gen_store_gpr(v1_t, ret); 3481 break; 3482 } 3483 break; 3484 case NM_PRECR_QB_PH: 3485 check_dsp_r2(ctx); 3486 gen_helper_precr_qb_ph(v1_t, v1_t, v2_t); 3487 gen_store_gpr(v1_t, ret); 3488 break; 3489 case NM_PRECRQ_QB_PH: 3490 check_dsp(ctx); 3491 gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t); 3492 gen_store_gpr(v1_t, ret); 3493 break; 3494 case NM_PRECRQ_PH_W: 3495 check_dsp(ctx); 3496 gen_helper_precrq_ph_w(v1_t, v1_t, v2_t); 3497 gen_store_gpr(v1_t, ret); 3498 break; 3499 case NM_PRECRQ_RS_PH_W: 3500 check_dsp(ctx); 3501 gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env); 3502 gen_store_gpr(v1_t, ret); 3503 break; 3504 case NM_PRECRQU_S_QB_PH: 3505 check_dsp(ctx); 3506 gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env); 3507 gen_store_gpr(v1_t, ret); 3508 break; 3509 case NM_SHRA_R_W: 3510 check_dsp(ctx); 3511 tcg_gen_movi_tl(t0, rd); 3512 gen_helper_shra_r_w(v1_t, t0, v1_t); 3513 gen_store_gpr(v1_t, rt); 3514 break; 3515 case NM_SHRA_R_PH: 3516 check_dsp(ctx); 3517 tcg_gen_movi_tl(t0, rd >> 1); 3518 switch (extract32(ctx->opcode, 10, 1)) { 3519 case 0: 3520 /* SHRA_PH */ 3521 gen_helper_shra_ph(v1_t, t0, v1_t); 3522 gen_store_gpr(v1_t, rt); 3523 break; 3524 case 1: 3525 /* SHRA_R_PH */ 3526 gen_helper_shra_r_ph(v1_t, t0, v1_t); 3527 gen_store_gpr(v1_t, rt); 3528 break; 3529 } 3530 break; 3531 case NM_SHLL_S_PH: 3532 check_dsp(ctx); 3533 tcg_gen_movi_tl(t0, rd >> 1); 3534 switch (extract32(ctx->opcode, 10, 2)) { 3535 case 0: 3536 /* SHLL_PH */ 3537 gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env); 3538 gen_store_gpr(v1_t, rt); 3539 break; 3540 case 2: 3541 /* SHLL_S_PH */ 3542 gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env); 3543 gen_store_gpr(v1_t, rt); 3544 break; 3545 default: 3546 gen_reserved_instruction(ctx); 3547 break; 3548 } 3549 break; 3550 case NM_SHLL_S_W: 3551 check_dsp(ctx); 3552 tcg_gen_movi_tl(t0, rd); 3553 gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env); 3554 gen_store_gpr(v1_t, rt); 3555 break; 3556 case NM_REPL_PH: 3557 check_dsp(ctx); 3558 { 3559 int16_t imm; 3560 imm = sextract32(ctx->opcode, 11, 11); 3561 imm = (int16_t)(imm << 6) >> 6; 3562 if (rt != 0) { 3563 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm)); 3564 } 3565 } 3566 break; 3567 default: 3568 gen_reserved_instruction(ctx); 3569 break; 3570 } 3571} 3572 3573static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) 3574{ 3575 uint16_t insn; 3576 uint32_t op; 3577 int rt, rs, rd; 3578 int offset; 3579 int imm; 3580 3581 insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2); 3582 ctx->opcode = (ctx->opcode << 16) | insn; 3583 3584 rt = extract32(ctx->opcode, 21, 5); 3585 rs = extract32(ctx->opcode, 16, 5); 3586 rd = extract32(ctx->opcode, 11, 5); 3587 3588 op = extract32(ctx->opcode, 26, 6); 3589 switch (op) { 3590 case NM_P_ADDIU: 3591 if (rt == 0) { 3592 /* P.RI */ 3593 switch (extract32(ctx->opcode, 19, 2)) { 3594 case NM_SIGRIE: 3595 default: 3596 gen_reserved_instruction(ctx); 3597 break; 3598 case NM_P_SYSCALL: 3599 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) { 3600 generate_exception_end(ctx, EXCP_SYSCALL); 3601 } else { 3602 gen_reserved_instruction(ctx); 3603 } 3604 break; 3605 case NM_BREAK: 3606 generate_exception_end(ctx, EXCP_BREAK); 3607 break; 3608 case NM_SDBBP: 3609 if (is_uhi(ctx, extract32(ctx->opcode, 0, 19))) { 3610 ctx->base.is_jmp = DISAS_SEMIHOST; 3611 } else { 3612 if (ctx->hflags & MIPS_HFLAG_SBRI) { 3613 gen_reserved_instruction(ctx); 3614 } else { 3615 generate_exception_end(ctx, EXCP_DBp); 3616 } 3617 } 3618 break; 3619 } 3620 } else { 3621 /* NM_ADDIU */ 3622 imm = extract32(ctx->opcode, 0, 16); 3623 if (rs != 0) { 3624 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm); 3625 } else { 3626 tcg_gen_movi_tl(cpu_gpr[rt], imm); 3627 } 3628 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 3629 } 3630 break; 3631 case NM_ADDIUPC: 3632 if (rt != 0) { 3633 offset = sextract32(ctx->opcode, 0, 1) << 21 | 3634 extract32(ctx->opcode, 1, 20) << 1; 3635 target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset); 3636 tcg_gen_movi_tl(cpu_gpr[rt], addr); 3637 } 3638 break; 3639 case NM_POOL32A: 3640 switch (ctx->opcode & 0x07) { 3641 case NM_POOL32A0: 3642 gen_pool32a0_nanomips_insn(env, ctx); 3643 break; 3644 case NM_POOL32A5: 3645 { 3646 int32_t op1 = extract32(ctx->opcode, 3, 7); 3647 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt); 3648 } 3649 break; 3650 case NM_POOL32A7: 3651 switch (extract32(ctx->opcode, 3, 3)) { 3652 case NM_P_LSX: 3653 gen_p_lsx(ctx, rd, rs, rt); 3654 break; 3655 case NM_LSA: 3656 /* 3657 * In nanoMIPS, the shift field directly encodes the shift 3658 * amount, meaning that the supported shift values are in 3659 * the range 0 to 3 (instead of 1 to 4 in MIPSR6). 3660 */ 3661 gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2) - 1); 3662 break; 3663 case NM_EXTW: 3664 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5)); 3665 break; 3666 case NM_POOL32AXF: 3667 gen_pool32axf_nanomips_insn(env, ctx); 3668 break; 3669 default: 3670 gen_reserved_instruction(ctx); 3671 break; 3672 } 3673 break; 3674 default: 3675 gen_reserved_instruction(ctx); 3676 break; 3677 } 3678 break; 3679 case NM_P_GP_W: 3680 switch (ctx->opcode & 0x03) { 3681 case NM_ADDIUGP_W: 3682 if (rt != 0) { 3683 offset = extract32(ctx->opcode, 0, 21); 3684 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset); 3685 } 3686 break; 3687 case NM_LWGP: 3688 gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); 3689 break; 3690 case NM_SWGP: 3691 gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2); 3692 break; 3693 default: 3694 gen_reserved_instruction(ctx); 3695 break; 3696 } 3697 break; 3698 case NM_P48I: 3699 { 3700 insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 4); 3701 target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16; 3702 switch (extract32(ctx->opcode, 16, 5)) { 3703 case NM_LI48: 3704 check_nms(ctx); 3705 if (rt != 0) { 3706 tcg_gen_movi_tl(cpu_gpr[rt], addr_off); 3707 } 3708 break; 3709 case NM_ADDIU48: 3710 check_nms(ctx); 3711 if (rt != 0) { 3712 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off); 3713 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]); 3714 } 3715 break; 3716 case NM_ADDIUGP48: 3717 check_nms(ctx); 3718 if (rt != 0) { 3719 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off); 3720 } 3721 break; 3722 case NM_ADDIUPC48: 3723 check_nms(ctx); 3724 if (rt != 0) { 3725 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 3726 addr_off); 3727 3728 tcg_gen_movi_tl(cpu_gpr[rt], addr); 3729 } 3730 break; 3731 case NM_LWPC48: 3732 check_nms(ctx); 3733 if (rt != 0) { 3734 TCGv t0; 3735 t0 = tcg_temp_new(); 3736 3737 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 3738 addr_off); 3739 3740 tcg_gen_movi_tl(t0, addr); 3741 tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL); 3742 } 3743 break; 3744 case NM_SWPC48: 3745 check_nms(ctx); 3746 { 3747 TCGv t0, t1; 3748 t0 = tcg_temp_new(); 3749 t1 = tcg_temp_new(); 3750 3751 target_long addr = addr_add(ctx, ctx->base.pc_next + 6, 3752 addr_off); 3753 3754 tcg_gen_movi_tl(t0, addr); 3755 gen_load_gpr(t1, rt); 3756 3757 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); 3758 } 3759 break; 3760 default: 3761 gen_reserved_instruction(ctx); 3762 break; 3763 } 3764 return 6; 3765 } 3766 case NM_P_U12: 3767 switch (extract32(ctx->opcode, 12, 4)) { 3768 case NM_ORI: 3769 gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12)); 3770 break; 3771 case NM_XORI: 3772 gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12)); 3773 break; 3774 case NM_ANDI: 3775 gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12)); 3776 break; 3777 case NM_P_SR: 3778 switch (extract32(ctx->opcode, 20, 1)) { 3779 case NM_PP_SR: 3780 switch (ctx->opcode & 3) { 3781 case NM_SAVE: 3782 gen_save(ctx, rt, extract32(ctx->opcode, 16, 4), 3783 extract32(ctx->opcode, 2, 1), 3784 extract32(ctx->opcode, 3, 9) << 3); 3785 break; 3786 case NM_RESTORE: 3787 case NM_RESTORE_JRC: 3788 gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4), 3789 extract32(ctx->opcode, 2, 1), 3790 extract32(ctx->opcode, 3, 9) << 3); 3791 if ((ctx->opcode & 3) == NM_RESTORE_JRC) { 3792 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); 3793 } 3794 break; 3795 default: 3796 gen_reserved_instruction(ctx); 3797 break; 3798 } 3799 break; 3800 case NM_P_SR_F: 3801 gen_reserved_instruction(ctx); 3802 break; 3803 } 3804 break; 3805 case NM_SLTI: 3806 gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12)); 3807 break; 3808 case NM_SLTIU: 3809 gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12)); 3810 break; 3811 case NM_SEQI: 3812 { 3813 TCGv t0 = tcg_temp_new(); 3814 3815 imm = extract32(ctx->opcode, 0, 12); 3816 gen_load_gpr(t0, rs); 3817 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm); 3818 gen_store_gpr(t0, rt); 3819 } 3820 break; 3821 case NM_ADDIUNEG: 3822 imm = (int16_t) extract32(ctx->opcode, 0, 12); 3823 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm); 3824 break; 3825 case NM_P_SHIFT: 3826 { 3827 int shift = extract32(ctx->opcode, 0, 5); 3828 switch (extract32(ctx->opcode, 5, 4)) { 3829 case NM_P_SLL: 3830 if (rt == 0 && shift == 0) { 3831 /* NOP */ 3832 } else if (rt == 0 && shift == 3) { 3833 /* EHB - treat as NOP */ 3834 } else if (rt == 0 && shift == 5) { 3835 /* PAUSE - treat as NOP */ 3836 } else if (rt == 0 && shift == 6) { 3837 /* SYNC */ 3838 gen_sync(extract32(ctx->opcode, 16, 5)); 3839 } else { 3840 /* SLL */ 3841 gen_shift_imm(ctx, OPC_SLL, rt, rs, 3842 extract32(ctx->opcode, 0, 5)); 3843 } 3844 break; 3845 case NM_SRL: 3846 gen_shift_imm(ctx, OPC_SRL, rt, rs, 3847 extract32(ctx->opcode, 0, 5)); 3848 break; 3849 case NM_SRA: 3850 gen_shift_imm(ctx, OPC_SRA, rt, rs, 3851 extract32(ctx->opcode, 0, 5)); 3852 break; 3853 case NM_ROTR: 3854 gen_shift_imm(ctx, OPC_ROTR, rt, rs, 3855 extract32(ctx->opcode, 0, 5)); 3856 break; 3857 default: 3858 gen_reserved_instruction(ctx); 3859 break; 3860 } 3861 } 3862 break; 3863 case NM_P_ROTX: 3864 check_nms(ctx); 3865 if (rt != 0) { 3866 TCGv t0 = tcg_temp_new(); 3867 TCGv_i32 shift = 3868 tcg_constant_i32(extract32(ctx->opcode, 0, 5)); 3869 TCGv_i32 shiftx = 3870 tcg_constant_i32(extract32(ctx->opcode, 7, 4) << 1); 3871 TCGv_i32 stripe = 3872 tcg_constant_i32(extract32(ctx->opcode, 6, 1)); 3873 3874 gen_load_gpr(t0, rs); 3875 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe); 3876 } 3877 break; 3878 case NM_P_INS: 3879 switch (((ctx->opcode >> 10) & 2) | 3880 (extract32(ctx->opcode, 5, 1))) { 3881 case NM_INS: 3882 check_nms(ctx); 3883 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5), 3884 extract32(ctx->opcode, 6, 5)); 3885 break; 3886 default: 3887 gen_reserved_instruction(ctx); 3888 break; 3889 } 3890 break; 3891 case NM_P_EXT: 3892 switch (((ctx->opcode >> 10) & 2) | 3893 (extract32(ctx->opcode, 5, 1))) { 3894 case NM_EXT: 3895 check_nms(ctx); 3896 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5), 3897 extract32(ctx->opcode, 6, 5)); 3898 break; 3899 default: 3900 gen_reserved_instruction(ctx); 3901 break; 3902 } 3903 break; 3904 default: 3905 gen_reserved_instruction(ctx); 3906 break; 3907 } 3908 break; 3909 case NM_POOL32F: 3910 gen_pool32f_nanomips_insn(ctx); 3911 break; 3912 case NM_POOL32S: 3913 break; 3914 case NM_P_LUI: 3915 switch (extract32(ctx->opcode, 1, 1)) { 3916 case NM_LUI: 3917 if (rt != 0) { 3918 tcg_gen_movi_tl(cpu_gpr[rt], 3919 sextract32(ctx->opcode, 0, 1) << 31 | 3920 extract32(ctx->opcode, 2, 10) << 21 | 3921 extract32(ctx->opcode, 12, 9) << 12); 3922 } 3923 break; 3924 case NM_ALUIPC: 3925 if (rt != 0) { 3926 offset = sextract32(ctx->opcode, 0, 1) << 31 | 3927 extract32(ctx->opcode, 2, 10) << 21 | 3928 extract32(ctx->opcode, 12, 9) << 12; 3929 target_long addr; 3930 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset); 3931 tcg_gen_movi_tl(cpu_gpr[rt], addr); 3932 } 3933 break; 3934 } 3935 break; 3936 case NM_P_GP_BH: 3937 { 3938 uint32_t u = extract32(ctx->opcode, 0, 18); 3939 3940 switch (extract32(ctx->opcode, 18, 3)) { 3941 case NM_LBGP: 3942 gen_ld(ctx, OPC_LB, rt, 28, u); 3943 break; 3944 case NM_SBGP: 3945 gen_st(ctx, OPC_SB, rt, 28, u); 3946 break; 3947 case NM_LBUGP: 3948 gen_ld(ctx, OPC_LBU, rt, 28, u); 3949 break; 3950 case NM_ADDIUGP_B: 3951 if (rt != 0) { 3952 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u); 3953 } 3954 break; 3955 case NM_P_GP_LH: 3956 u &= ~1; 3957 switch (ctx->opcode & 1) { 3958 case NM_LHGP: 3959 gen_ld(ctx, OPC_LH, rt, 28, u); 3960 break; 3961 case NM_LHUGP: 3962 gen_ld(ctx, OPC_LHU, rt, 28, u); 3963 break; 3964 } 3965 break; 3966 case NM_P_GP_SH: 3967 u &= ~1; 3968 switch (ctx->opcode & 1) { 3969 case NM_SHGP: 3970 gen_st(ctx, OPC_SH, rt, 28, u); 3971 break; 3972 default: 3973 gen_reserved_instruction(ctx); 3974 break; 3975 } 3976 break; 3977 case NM_P_GP_CP1: 3978 u &= ~0x3; 3979 switch (ctx->opcode & 0x3) { 3980 case NM_LWC1GP: 3981 gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u); 3982 break; 3983 case NM_LDC1GP: 3984 gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u); 3985 break; 3986 case NM_SWC1GP: 3987 gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u); 3988 break; 3989 case NM_SDC1GP: 3990 gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u); 3991 break; 3992 } 3993 break; 3994 default: 3995 gen_reserved_instruction(ctx); 3996 break; 3997 } 3998 } 3999 break; 4000 case NM_P_LS_U12: 4001 { 4002 uint32_t u = extract32(ctx->opcode, 0, 12); 4003 4004 switch (extract32(ctx->opcode, 12, 4)) { 4005 case NM_P_PREFU12: 4006 if (rt == 31) { 4007 /* SYNCI */ 4008 /* 4009 * Break the TB to be able to sync copied instructions 4010 * immediately. 4011 */ 4012 ctx->base.is_jmp = DISAS_STOP; 4013 } else { 4014 /* PREF */ 4015 /* Treat as NOP. */ 4016 } 4017 break; 4018 case NM_LB: 4019 gen_ld(ctx, OPC_LB, rt, rs, u); 4020 break; 4021 case NM_LH: 4022 gen_ld(ctx, OPC_LH, rt, rs, u); 4023 break; 4024 case NM_LW: 4025 gen_ld(ctx, OPC_LW, rt, rs, u); 4026 break; 4027 case NM_LBU: 4028 gen_ld(ctx, OPC_LBU, rt, rs, u); 4029 break; 4030 case NM_LHU: 4031 gen_ld(ctx, OPC_LHU, rt, rs, u); 4032 break; 4033 case NM_SB: 4034 gen_st(ctx, OPC_SB, rt, rs, u); 4035 break; 4036 case NM_SH: 4037 gen_st(ctx, OPC_SH, rt, rs, u); 4038 break; 4039 case NM_SW: 4040 gen_st(ctx, OPC_SW, rt, rs, u); 4041 break; 4042 case NM_LWC1: 4043 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u); 4044 break; 4045 case NM_LDC1: 4046 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u); 4047 break; 4048 case NM_SWC1: 4049 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u); 4050 break; 4051 case NM_SDC1: 4052 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u); 4053 break; 4054 default: 4055 gen_reserved_instruction(ctx); 4056 break; 4057 } 4058 } 4059 break; 4060 case NM_P_LS_S9: 4061 { 4062 int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) | 4063 extract32(ctx->opcode, 0, 8); 4064 4065 switch (extract32(ctx->opcode, 8, 3)) { 4066 case NM_P_LS_S0: 4067 switch (extract32(ctx->opcode, 11, 4)) { 4068 case NM_LBS9: 4069 gen_ld(ctx, OPC_LB, rt, rs, s); 4070 break; 4071 case NM_LHS9: 4072 gen_ld(ctx, OPC_LH, rt, rs, s); 4073 break; 4074 case NM_LWS9: 4075 gen_ld(ctx, OPC_LW, rt, rs, s); 4076 break; 4077 case NM_LBUS9: 4078 gen_ld(ctx, OPC_LBU, rt, rs, s); 4079 break; 4080 case NM_LHUS9: 4081 gen_ld(ctx, OPC_LHU, rt, rs, s); 4082 break; 4083 case NM_SBS9: 4084 gen_st(ctx, OPC_SB, rt, rs, s); 4085 break; 4086 case NM_SHS9: 4087 gen_st(ctx, OPC_SH, rt, rs, s); 4088 break; 4089 case NM_SWS9: 4090 gen_st(ctx, OPC_SW, rt, rs, s); 4091 break; 4092 case NM_LWC1S9: 4093 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s); 4094 break; 4095 case NM_LDC1S9: 4096 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s); 4097 break; 4098 case NM_SWC1S9: 4099 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s); 4100 break; 4101 case NM_SDC1S9: 4102 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s); 4103 break; 4104 case NM_P_PREFS9: 4105 if (rt == 31) { 4106 /* SYNCI */ 4107 /* 4108 * Break the TB to be able to sync copied instructions 4109 * immediately. 4110 */ 4111 ctx->base.is_jmp = DISAS_STOP; 4112 } else { 4113 /* PREF */ 4114 /* Treat as NOP. */ 4115 } 4116 break; 4117 default: 4118 gen_reserved_instruction(ctx); 4119 break; 4120 } 4121 break; 4122 case NM_P_LS_S1: 4123 switch (extract32(ctx->opcode, 11, 4)) { 4124 case NM_UALH: 4125 case NM_UASH: 4126 check_nms(ctx); 4127 { 4128 TCGv t0 = tcg_temp_new(); 4129 TCGv t1 = tcg_temp_new(); 4130 4131 gen_base_offset_addr(ctx, t0, rs, s); 4132 4133 switch (extract32(ctx->opcode, 11, 4)) { 4134 case NM_UALH: 4135 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW | 4136 MO_UNALN); 4137 gen_store_gpr(t0, rt); 4138 break; 4139 case NM_UASH: 4140 gen_load_gpr(t1, rt); 4141 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW | 4142 MO_UNALN); 4143 break; 4144 } 4145 } 4146 break; 4147 case NM_P_LL: 4148 switch (ctx->opcode & 0x03) { 4149 case NM_LL: 4150 gen_ld(ctx, OPC_LL, rt, rs, s); 4151 break; 4152 case NM_LLWP: 4153 check_xnp(ctx); 4154 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5)); 4155 break; 4156 default: 4157 gen_reserved_instruction(ctx); 4158 break; 4159 } 4160 break; 4161 case NM_P_SC: 4162 switch (ctx->opcode & 0x03) { 4163 case NM_SC: 4164 gen_st_cond(ctx, rt, rs, s, MO_TESL, false); 4165 break; 4166 case NM_SCWP: 4167 check_xnp(ctx); 4168 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5), 4169 false); 4170 break; 4171 default: 4172 gen_reserved_instruction(ctx); 4173 break; 4174 } 4175 break; 4176 case NM_CACHE: 4177 check_cp0_enabled(ctx); 4178 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) { 4179 gen_cache_operation(ctx, rt, rs, s); 4180 } 4181 break; 4182 default: 4183 gen_reserved_instruction(ctx); 4184 break; 4185 } 4186 break; 4187 case NM_P_LS_E0: 4188 switch (extract32(ctx->opcode, 11, 4)) { 4189 case NM_LBE: 4190 check_eva(ctx); 4191 check_cp0_enabled(ctx); 4192 gen_ld(ctx, OPC_LBE, rt, rs, s); 4193 break; 4194 case NM_SBE: 4195 check_eva(ctx); 4196 check_cp0_enabled(ctx); 4197 gen_st(ctx, OPC_SBE, rt, rs, s); 4198 break; 4199 case NM_LBUE: 4200 check_eva(ctx); 4201 check_cp0_enabled(ctx); 4202 gen_ld(ctx, OPC_LBUE, rt, rs, s); 4203 break; 4204 case NM_P_PREFE: 4205 if (rt == 31) { 4206 /* case NM_SYNCIE */ 4207 check_eva(ctx); 4208 check_cp0_enabled(ctx); 4209 /* 4210 * Break the TB to be able to sync copied instructions 4211 * immediately. 4212 */ 4213 ctx->base.is_jmp = DISAS_STOP; 4214 } else { 4215 /* case NM_PREFE */ 4216 check_eva(ctx); 4217 check_cp0_enabled(ctx); 4218 /* Treat as NOP. */ 4219 } 4220 break; 4221 case NM_LHE: 4222 check_eva(ctx); 4223 check_cp0_enabled(ctx); 4224 gen_ld(ctx, OPC_LHE, rt, rs, s); 4225 break; 4226 case NM_SHE: 4227 check_eva(ctx); 4228 check_cp0_enabled(ctx); 4229 gen_st(ctx, OPC_SHE, rt, rs, s); 4230 break; 4231 case NM_LHUE: 4232 check_eva(ctx); 4233 check_cp0_enabled(ctx); 4234 gen_ld(ctx, OPC_LHUE, rt, rs, s); 4235 break; 4236 case NM_CACHEE: 4237 check_eva(ctx); 4238 check_cp0_enabled(ctx); 4239 check_nms_dl_il_sl_tl_l2c(ctx); 4240 gen_cache_operation(ctx, rt, rs, s); 4241 break; 4242 case NM_LWE: 4243 check_eva(ctx); 4244 check_cp0_enabled(ctx); 4245 gen_ld(ctx, OPC_LWE, rt, rs, s); 4246 break; 4247 case NM_SWE: 4248 check_eva(ctx); 4249 check_cp0_enabled(ctx); 4250 gen_st(ctx, OPC_SWE, rt, rs, s); 4251 break; 4252 case NM_P_LLE: 4253 switch (extract32(ctx->opcode, 2, 2)) { 4254 case NM_LLE: 4255 check_xnp(ctx); 4256 check_eva(ctx); 4257 check_cp0_enabled(ctx); 4258 gen_ld(ctx, OPC_LLE, rt, rs, s); 4259 break; 4260 case NM_LLWPE: 4261 check_xnp(ctx); 4262 check_eva(ctx); 4263 check_cp0_enabled(ctx); 4264 gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5)); 4265 break; 4266 default: 4267 gen_reserved_instruction(ctx); 4268 break; 4269 } 4270 break; 4271 case NM_P_SCE: 4272 switch (extract32(ctx->opcode, 2, 2)) { 4273 case NM_SCE: 4274 check_xnp(ctx); 4275 check_eva(ctx); 4276 check_cp0_enabled(ctx); 4277 gen_st_cond(ctx, rt, rs, s, MO_TESL, true); 4278 break; 4279 case NM_SCWPE: 4280 check_xnp(ctx); 4281 check_eva(ctx); 4282 check_cp0_enabled(ctx); 4283 gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5), 4284 true); 4285 break; 4286 default: 4287 gen_reserved_instruction(ctx); 4288 break; 4289 } 4290 break; 4291 default: 4292 gen_reserved_instruction(ctx); 4293 break; 4294 } 4295 break; 4296 case NM_P_LS_WM: 4297 case NM_P_LS_UAWM: 4298 check_nms(ctx); 4299 { 4300 int count = extract32(ctx->opcode, 12, 3); 4301 int counter = 0; 4302 4303 offset = sextract32(ctx->opcode, 15, 1) << 8 | 4304 extract32(ctx->opcode, 0, 8); 4305 TCGv va = tcg_temp_new(); 4306 TCGv t1 = tcg_temp_new(); 4307 MemOp memop = (extract32(ctx->opcode, 8, 3)) == 4308 NM_P_LS_UAWM ? MO_UNALN : 0; 4309 4310 count = (count == 0) ? 8 : count; 4311 while (counter != count) { 4312 int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10); 4313 int this_offset = offset + (counter << 2); 4314 4315 gen_base_offset_addr(ctx, va, rs, this_offset); 4316 4317 switch (extract32(ctx->opcode, 11, 1)) { 4318 case NM_LWM: 4319 tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx, 4320 memop | MO_TESL); 4321 gen_store_gpr(t1, this_rt); 4322 if ((this_rt == rs) && 4323 (counter != (count - 1))) { 4324 /* UNPREDICTABLE */ 4325 } 4326 break; 4327 case NM_SWM: 4328 this_rt = (rt == 0) ? 0 : this_rt; 4329 gen_load_gpr(t1, this_rt); 4330 tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx, 4331 memop | MO_TEUL); 4332 break; 4333 } 4334 counter++; 4335 } 4336 } 4337 break; 4338 default: 4339 gen_reserved_instruction(ctx); 4340 break; 4341 } 4342 } 4343 break; 4344 case NM_MOVE_BALC: 4345 check_nms(ctx); 4346 { 4347 TCGv t0 = tcg_temp_new(); 4348 int32_t s = sextract32(ctx->opcode, 0, 1) << 21 | 4349 extract32(ctx->opcode, 1, 20) << 1; 4350 rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5; 4351 rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 | 4352 extract32(ctx->opcode, 21, 3)); 4353 gen_load_gpr(t0, rt); 4354 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4355 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); 4356 } 4357 break; 4358 case NM_P_BAL: 4359 { 4360 int32_t s = sextract32(ctx->opcode, 0, 1) << 25 | 4361 extract32(ctx->opcode, 1, 24) << 1; 4362 4363 if ((extract32(ctx->opcode, 25, 1)) == 0) { 4364 /* BC */ 4365 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s); 4366 } else { 4367 /* BALC */ 4368 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s); 4369 } 4370 } 4371 break; 4372 case NM_P_J: 4373 switch (extract32(ctx->opcode, 12, 4)) { 4374 case NM_JALRC: 4375 case NM_JALRC_HB: 4376 gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0); 4377 break; 4378 case NM_P_BALRSC: 4379 gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt); 4380 break; 4381 default: 4382 gen_reserved_instruction(ctx); 4383 break; 4384 } 4385 break; 4386 case NM_P_BR1: 4387 { 4388 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 | 4389 extract32(ctx->opcode, 1, 13) << 1; 4390 switch (extract32(ctx->opcode, 14, 2)) { 4391 case NM_BEQC: 4392 check_nms(ctx); 4393 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s); 4394 break; 4395 case NM_P_BR3A: 4396 s = sextract32(ctx->opcode, 0, 1) << 14 | 4397 extract32(ctx->opcode, 1, 13) << 1; 4398 switch (extract32(ctx->opcode, 16, 5)) { 4399 case NM_BC1EQZC: 4400 check_cp1_enabled(ctx); 4401 gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s); 4402 break; 4403 case NM_BC1NEZC: 4404 check_cp1_enabled(ctx); 4405 gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s); 4406 break; 4407 case NM_BPOSGE32C: 4408 check_dsp_r3(ctx); 4409 { 4410 int32_t imm = extract32(ctx->opcode, 1, 13) | 4411 extract32(ctx->opcode, 0, 1) << 13; 4412 4413 gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2, 4414 imm << 1); 4415 } 4416 break; 4417 default: 4418 gen_reserved_instruction(ctx); 4419 break; 4420 } 4421 break; 4422 case NM_BGEC: 4423 if (rs == rt) { 4424 gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s); 4425 } else { 4426 gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s); 4427 } 4428 break; 4429 case NM_BGEUC: 4430 if (rs == rt || rt == 0) { 4431 gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s); 4432 } else if (rs == 0) { 4433 gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s); 4434 } else { 4435 gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s); 4436 } 4437 break; 4438 } 4439 } 4440 break; 4441 case NM_P_BR2: 4442 { 4443 int32_t s = sextract32(ctx->opcode, 0, 1) << 14 | 4444 extract32(ctx->opcode, 1, 13) << 1; 4445 switch (extract32(ctx->opcode, 14, 2)) { 4446 case NM_BNEC: 4447 check_nms(ctx); 4448 if (rs == rt) { 4449 /* NOP */ 4450 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 4451 } else { 4452 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s); 4453 } 4454 break; 4455 case NM_BLTC: 4456 if (rs != 0 && rt != 0 && rs == rt) { 4457 /* NOP */ 4458 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 4459 } else { 4460 gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s); 4461 } 4462 break; 4463 case NM_BLTUC: 4464 if (rs == 0 || rs == rt) { 4465 /* NOP */ 4466 ctx->hflags |= MIPS_HFLAG_FBNSLOT; 4467 } else { 4468 gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s); 4469 } 4470 break; 4471 default: 4472 gen_reserved_instruction(ctx); 4473 break; 4474 } 4475 } 4476 break; 4477 case NM_P_BRI: 4478 { 4479 int32_t s = sextract32(ctx->opcode, 0, 1) << 11 | 4480 extract32(ctx->opcode, 1, 10) << 1; 4481 uint32_t u = extract32(ctx->opcode, 11, 7); 4482 4483 gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3), 4484 rt, u, s); 4485 } 4486 break; 4487 default: 4488 gen_reserved_instruction(ctx); 4489 break; 4490 } 4491 return 4; 4492} 4493 4494static int decode_isa_nanomips(CPUMIPSState *env, DisasContext *ctx) 4495{ 4496 uint32_t op; 4497 int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4498 int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 4499 int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode)); 4500 int offset; 4501 int imm; 4502 4503 /* make sure instructions are on a halfword boundary */ 4504 if (ctx->base.pc_next & 0x1) { 4505 TCGv tmp = tcg_constant_tl(ctx->base.pc_next); 4506 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); 4507 generate_exception_end(ctx, EXCP_AdEL); 4508 return 2; 4509 } 4510 4511 op = extract32(ctx->opcode, 10, 6); 4512 switch (op) { 4513 case NM_P16_MV: 4514 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 4515 if (rt != 0) { 4516 /* MOVE */ 4517 rs = NANOMIPS_EXTRACT_RS5(ctx->opcode); 4518 gen_arith(ctx, OPC_ADDU, rt, rs, 0); 4519 } else { 4520 /* P16.RI */ 4521 switch (extract32(ctx->opcode, 3, 2)) { 4522 case NM_P16_SYSCALL: 4523 if (extract32(ctx->opcode, 2, 1) == 0) { 4524 generate_exception_end(ctx, EXCP_SYSCALL); 4525 } else { 4526 gen_reserved_instruction(ctx); 4527 } 4528 break; 4529 case NM_BREAK16: 4530 generate_exception_end(ctx, EXCP_BREAK); 4531 break; 4532 case NM_SDBBP16: 4533 if (is_uhi(ctx, extract32(ctx->opcode, 0, 3))) { 4534 ctx->base.is_jmp = DISAS_SEMIHOST; 4535 } else { 4536 if (ctx->hflags & MIPS_HFLAG_SBRI) { 4537 gen_reserved_instruction(ctx); 4538 } else { 4539 generate_exception_end(ctx, EXCP_DBp); 4540 } 4541 } 4542 break; 4543 default: 4544 gen_reserved_instruction(ctx); 4545 break; 4546 } 4547 } 4548 break; 4549 case NM_P16_SHIFT: 4550 { 4551 int shift = extract32(ctx->opcode, 0, 3); 4552 uint32_t opc = 0; 4553 shift = (shift == 0) ? 8 : shift; 4554 4555 switch (extract32(ctx->opcode, 3, 1)) { 4556 case NM_SLL16: 4557 opc = OPC_SLL; 4558 break; 4559 case NM_SRL16: 4560 opc = OPC_SRL; 4561 break; 4562 } 4563 gen_shift_imm(ctx, opc, rt, rs, shift); 4564 } 4565 break; 4566 case NM_P16C: 4567 switch (ctx->opcode & 1) { 4568 case NM_POOL16C_0: 4569 gen_pool16c_nanomips_insn(ctx); 4570 break; 4571 case NM_LWXS16: 4572 gen_ldxs(ctx, rt, rs, rd); 4573 break; 4574 } 4575 break; 4576 case NM_P16_A1: 4577 switch (extract32(ctx->opcode, 6, 1)) { 4578 case NM_ADDIUR1SP: 4579 imm = extract32(ctx->opcode, 0, 6) << 2; 4580 gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm); 4581 break; 4582 default: 4583 gen_reserved_instruction(ctx); 4584 break; 4585 } 4586 break; 4587 case NM_P16_A2: 4588 switch (extract32(ctx->opcode, 3, 1)) { 4589 case NM_ADDIUR2: 4590 imm = extract32(ctx->opcode, 0, 3) << 2; 4591 gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm); 4592 break; 4593 case NM_P_ADDIURS5: 4594 rt = extract32(ctx->opcode, 5, 5); 4595 if (rt != 0) { 4596 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */ 4597 imm = (sextract32(ctx->opcode, 4, 1) << 3) | 4598 (extract32(ctx->opcode, 0, 3)); 4599 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm); 4600 } 4601 break; 4602 } 4603 break; 4604 case NM_P16_ADDU: 4605 switch (ctx->opcode & 0x1) { 4606 case NM_ADDU16: 4607 gen_arith(ctx, OPC_ADDU, rd, rs, rt); 4608 break; 4609 case NM_SUBU16: 4610 gen_arith(ctx, OPC_SUBU, rd, rs, rt); 4611 break; 4612 } 4613 break; 4614 case NM_P16_4X4: 4615 rt = (extract32(ctx->opcode, 9, 1) << 3) | 4616 extract32(ctx->opcode, 5, 3); 4617 rs = (extract32(ctx->opcode, 4, 1) << 3) | 4618 extract32(ctx->opcode, 0, 3); 4619 rt = decode_gpr_gpr4(rt); 4620 rs = decode_gpr_gpr4(rs); 4621 switch ((extract32(ctx->opcode, 7, 2) & 0x2) | 4622 (extract32(ctx->opcode, 3, 1))) { 4623 case NM_ADDU4X4: 4624 check_nms(ctx); 4625 gen_arith(ctx, OPC_ADDU, rt, rs, rt); 4626 break; 4627 case NM_MUL4X4: 4628 check_nms(ctx); 4629 gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt); 4630 break; 4631 default: 4632 gen_reserved_instruction(ctx); 4633 break; 4634 } 4635 break; 4636 case NM_LI16: 4637 { 4638 int imm = extract32(ctx->opcode, 0, 7); 4639 imm = (imm == 0x7f ? -1 : imm); 4640 if (rt != 0) { 4641 tcg_gen_movi_tl(cpu_gpr[rt], imm); 4642 } 4643 } 4644 break; 4645 case NM_ANDI16: 4646 { 4647 uint32_t u = extract32(ctx->opcode, 0, 4); 4648 u = (u == 12) ? 0xff : 4649 (u == 13) ? 0xffff : u; 4650 gen_logic_imm(ctx, OPC_ANDI, rt, rs, u); 4651 } 4652 break; 4653 case NM_P16_LB: 4654 offset = extract32(ctx->opcode, 0, 2); 4655 switch (extract32(ctx->opcode, 2, 2)) { 4656 case NM_LB16: 4657 gen_ld(ctx, OPC_LB, rt, rs, offset); 4658 break; 4659 case NM_SB16: 4660 rt = decode_gpr_gpr3_src_store( 4661 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4662 gen_st(ctx, OPC_SB, rt, rs, offset); 4663 break; 4664 case NM_LBU16: 4665 gen_ld(ctx, OPC_LBU, rt, rs, offset); 4666 break; 4667 default: 4668 gen_reserved_instruction(ctx); 4669 break; 4670 } 4671 break; 4672 case NM_P16_LH: 4673 offset = extract32(ctx->opcode, 1, 2) << 1; 4674 switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) { 4675 case NM_LH16: 4676 gen_ld(ctx, OPC_LH, rt, rs, offset); 4677 break; 4678 case NM_SH16: 4679 rt = decode_gpr_gpr3_src_store( 4680 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4681 gen_st(ctx, OPC_SH, rt, rs, offset); 4682 break; 4683 case NM_LHU16: 4684 gen_ld(ctx, OPC_LHU, rt, rs, offset); 4685 break; 4686 default: 4687 gen_reserved_instruction(ctx); 4688 break; 4689 } 4690 break; 4691 case NM_LW16: 4692 offset = extract32(ctx->opcode, 0, 4) << 2; 4693 gen_ld(ctx, OPC_LW, rt, rs, offset); 4694 break; 4695 case NM_LWSP16: 4696 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 4697 offset = extract32(ctx->opcode, 0, 5) << 2; 4698 gen_ld(ctx, OPC_LW, rt, 29, offset); 4699 break; 4700 case NM_LW4X4: 4701 check_nms(ctx); 4702 rt = (extract32(ctx->opcode, 9, 1) << 3) | 4703 extract32(ctx->opcode, 5, 3); 4704 rs = (extract32(ctx->opcode, 4, 1) << 3) | 4705 extract32(ctx->opcode, 0, 3); 4706 offset = (extract32(ctx->opcode, 3, 1) << 3) | 4707 (extract32(ctx->opcode, 8, 1) << 2); 4708 rt = decode_gpr_gpr4(rt); 4709 rs = decode_gpr_gpr4(rs); 4710 gen_ld(ctx, OPC_LW, rt, rs, offset); 4711 break; 4712 case NM_SW4X4: 4713 check_nms(ctx); 4714 rt = (extract32(ctx->opcode, 9, 1) << 3) | 4715 extract32(ctx->opcode, 5, 3); 4716 rs = (extract32(ctx->opcode, 4, 1) << 3) | 4717 extract32(ctx->opcode, 0, 3); 4718 offset = (extract32(ctx->opcode, 3, 1) << 3) | 4719 (extract32(ctx->opcode, 8, 1) << 2); 4720 rt = decode_gpr_gpr4_zero(rt); 4721 rs = decode_gpr_gpr4(rs); 4722 gen_st(ctx, OPC_SW, rt, rs, offset); 4723 break; 4724 case NM_LWGP16: 4725 offset = extract32(ctx->opcode, 0, 7) << 2; 4726 gen_ld(ctx, OPC_LW, rt, 28, offset); 4727 break; 4728 case NM_SWSP16: 4729 rt = NANOMIPS_EXTRACT_RD5(ctx->opcode); 4730 offset = extract32(ctx->opcode, 0, 5) << 2; 4731 gen_st(ctx, OPC_SW, rt, 29, offset); 4732 break; 4733 case NM_SW16: 4734 rt = decode_gpr_gpr3_src_store( 4735 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4736 rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode)); 4737 offset = extract32(ctx->opcode, 0, 4) << 2; 4738 gen_st(ctx, OPC_SW, rt, rs, offset); 4739 break; 4740 case NM_SWGP16: 4741 rt = decode_gpr_gpr3_src_store( 4742 NANOMIPS_EXTRACT_RT3(ctx->opcode)); 4743 offset = extract32(ctx->opcode, 0, 7) << 2; 4744 gen_st(ctx, OPC_SW, rt, 28, offset); 4745 break; 4746 case NM_BC16: 4747 gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0, 4748 (sextract32(ctx->opcode, 0, 1) << 10) | 4749 (extract32(ctx->opcode, 1, 9) << 1)); 4750 break; 4751 case NM_BALC16: 4752 gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0, 4753 (sextract32(ctx->opcode, 0, 1) << 10) | 4754 (extract32(ctx->opcode, 1, 9) << 1)); 4755 break; 4756 case NM_BEQZC16: 4757 gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0, 4758 (sextract32(ctx->opcode, 0, 1) << 7) | 4759 (extract32(ctx->opcode, 1, 6) << 1)); 4760 break; 4761 case NM_BNEZC16: 4762 gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0, 4763 (sextract32(ctx->opcode, 0, 1) << 7) | 4764 (extract32(ctx->opcode, 1, 6) << 1)); 4765 break; 4766 case NM_P16_BR: 4767 switch (ctx->opcode & 0xf) { 4768 case 0: 4769 /* P16.JRC */ 4770 switch (extract32(ctx->opcode, 4, 1)) { 4771 case NM_JRC: 4772 gen_compute_branch_nm(ctx, OPC_JR, 2, 4773 extract32(ctx->opcode, 5, 5), 0, 0); 4774 break; 4775 case NM_JALRC16: 4776 gen_compute_branch_nm(ctx, OPC_JALR, 2, 4777 extract32(ctx->opcode, 5, 5), 31, 0); 4778 break; 4779 } 4780 break; 4781 default: 4782 { 4783 /* P16.BRI */ 4784 uint32_t opc = extract32(ctx->opcode, 4, 3) < 4785 extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE; 4786 gen_compute_branch_nm(ctx, opc, 2, rs, rt, 4787 extract32(ctx->opcode, 0, 4) << 1); 4788 } 4789 break; 4790 } 4791 break; 4792 case NM_P16_SR: 4793 { 4794 int count = extract32(ctx->opcode, 0, 4); 4795 int u = extract32(ctx->opcode, 4, 4) << 4; 4796 4797 rt = 30 + extract32(ctx->opcode, 9, 1); 4798 switch (extract32(ctx->opcode, 8, 1)) { 4799 case NM_SAVE16: 4800 gen_save(ctx, rt, count, 0, u); 4801 break; 4802 case NM_RESTORE_JRC16: 4803 gen_restore(ctx, rt, count, 0, u); 4804 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0); 4805 break; 4806 } 4807 } 4808 break; 4809 case NM_MOVEP: 4810 case NM_MOVEPREV: 4811 check_nms(ctx); 4812 { 4813 static const int gpr2reg1[] = {4, 5, 6, 7}; 4814 static const int gpr2reg2[] = {5, 6, 7, 8}; 4815 int re; 4816 int rd2 = extract32(ctx->opcode, 3, 1) << 1 | 4817 extract32(ctx->opcode, 8, 1); 4818 int r1 = gpr2reg1[rd2]; 4819 int r2 = gpr2reg2[rd2]; 4820 int r3 = extract32(ctx->opcode, 4, 1) << 3 | 4821 extract32(ctx->opcode, 0, 3); 4822 int r4 = extract32(ctx->opcode, 9, 1) << 3 | 4823 extract32(ctx->opcode, 5, 3); 4824 TCGv t0 = tcg_temp_new(); 4825 TCGv t1 = tcg_temp_new(); 4826 if (op == NM_MOVEP) { 4827 rd = r1; 4828 re = r2; 4829 rs = decode_gpr_gpr4_zero(r3); 4830 rt = decode_gpr_gpr4_zero(r4); 4831 } else { 4832 rd = decode_gpr_gpr4(r3); 4833 re = decode_gpr_gpr4(r4); 4834 rs = r1; 4835 rt = r2; 4836 } 4837 gen_load_gpr(t0, rs); 4838 gen_load_gpr(t1, rt); 4839 tcg_gen_mov_tl(cpu_gpr[rd], t0); 4840 tcg_gen_mov_tl(cpu_gpr[re], t1); 4841 } 4842 break; 4843 default: 4844 return decode_nanomips_32_48_opc(env, ctx); 4845 } 4846 4847 return 2; 4848} 4849