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