qemu/target/mips/tcg/mips16e_translate.c.inc
<<
>>
Prefs
   1/*
   2 *  MIPS16 extension (Code Compaction) ASE 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 *
   9 * SPDX-License-Identifier: LGPL-2.1-or-later
  10 */
  11
  12/* MIPS16 major opcodes */
  13enum {
  14  M16_OPC_ADDIUSP = 0x00,
  15  M16_OPC_ADDIUPC = 0x01,
  16  M16_OPC_B = 0x02,
  17  M16_OPC_JAL = 0x03,
  18  M16_OPC_BEQZ = 0x04,
  19  M16_OPC_BNEQZ = 0x05,
  20  M16_OPC_SHIFT = 0x06,
  21  M16_OPC_LD = 0x07,
  22  M16_OPC_RRIA = 0x08,
  23  M16_OPC_ADDIU8 = 0x09,
  24  M16_OPC_SLTI = 0x0a,
  25  M16_OPC_SLTIU = 0x0b,
  26  M16_OPC_I8 = 0x0c,
  27  M16_OPC_LI = 0x0d,
  28  M16_OPC_CMPI = 0x0e,
  29  M16_OPC_SD = 0x0f,
  30  M16_OPC_LB = 0x10,
  31  M16_OPC_LH = 0x11,
  32  M16_OPC_LWSP = 0x12,
  33  M16_OPC_LW = 0x13,
  34  M16_OPC_LBU = 0x14,
  35  M16_OPC_LHU = 0x15,
  36  M16_OPC_LWPC = 0x16,
  37  M16_OPC_LWU = 0x17,
  38  M16_OPC_SB = 0x18,
  39  M16_OPC_SH = 0x19,
  40  M16_OPC_SWSP = 0x1a,
  41  M16_OPC_SW = 0x1b,
  42  M16_OPC_RRR = 0x1c,
  43  M16_OPC_RR = 0x1d,
  44  M16_OPC_EXTEND = 0x1e,
  45  M16_OPC_I64 = 0x1f
  46};
  47
  48/* I8 funct field */
  49enum {
  50  I8_BTEQZ = 0x0,
  51  I8_BTNEZ = 0x1,
  52  I8_SWRASP = 0x2,
  53  I8_ADJSP = 0x3,
  54  I8_SVRS = 0x4,
  55  I8_MOV32R = 0x5,
  56  I8_MOVR32 = 0x7
  57};
  58
  59/* RRR f field */
  60enum {
  61  RRR_DADDU = 0x0,
  62  RRR_ADDU = 0x1,
  63  RRR_DSUBU = 0x2,
  64  RRR_SUBU = 0x3
  65};
  66
  67/* RR funct field */
  68enum {
  69  RR_JR = 0x00,
  70  RR_SDBBP = 0x01,
  71  RR_SLT = 0x02,
  72  RR_SLTU = 0x03,
  73  RR_SLLV = 0x04,
  74  RR_BREAK = 0x05,
  75  RR_SRLV = 0x06,
  76  RR_SRAV = 0x07,
  77  RR_DSRL = 0x08,
  78  RR_CMP = 0x0a,
  79  RR_NEG = 0x0b,
  80  RR_AND = 0x0c,
  81  RR_OR = 0x0d,
  82  RR_XOR = 0x0e,
  83  RR_NOT = 0x0f,
  84  RR_MFHI = 0x10,
  85  RR_CNVT = 0x11,
  86  RR_MFLO = 0x12,
  87  RR_DSRA = 0x13,
  88  RR_DSLLV = 0x14,
  89  RR_DSRLV = 0x16,
  90  RR_DSRAV = 0x17,
  91  RR_MULT = 0x18,
  92  RR_MULTU = 0x19,
  93  RR_DIV = 0x1a,
  94  RR_DIVU = 0x1b,
  95  RR_DMULT = 0x1c,
  96  RR_DMULTU = 0x1d,
  97  RR_DDIV = 0x1e,
  98  RR_DDIVU = 0x1f
  99};
 100
 101/* I64 funct field */
 102enum {
 103  I64_LDSP = 0x0,
 104  I64_SDSP = 0x1,
 105  I64_SDRASP = 0x2,
 106  I64_DADJSP = 0x3,
 107  I64_LDPC = 0x4,
 108  I64_DADDIU5 = 0x5,
 109  I64_DADDIUPC = 0x6,
 110  I64_DADDIUSP = 0x7
 111};
 112
 113/* RR ry field for CNVT */
 114enum {
 115  RR_RY_CNVT_ZEB = 0x0,
 116  RR_RY_CNVT_ZEH = 0x1,
 117  RR_RY_CNVT_ZEW = 0x2,
 118  RR_RY_CNVT_SEB = 0x4,
 119  RR_RY_CNVT_SEH = 0x5,
 120  RR_RY_CNVT_SEW = 0x6,
 121};
 122
 123static int xlat(int r)
 124{
 125  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
 126
 127  return map[r];
 128}
 129
 130static void gen_mips16_save(DisasContext *ctx,
 131                            int xsregs, int aregs,
 132                            int do_ra, int do_s0, int do_s1,
 133                            int framesize)
 134{
 135    TCGv t0 = tcg_temp_new();
 136    TCGv t1 = tcg_temp_new();
 137    TCGv t2 = tcg_temp_new();
 138    int args, astatic;
 139
 140    switch (aregs) {
 141    case 0:
 142    case 1:
 143    case 2:
 144    case 3:
 145    case 11:
 146        args = 0;
 147        break;
 148    case 4:
 149    case 5:
 150    case 6:
 151    case 7:
 152        args = 1;
 153        break;
 154    case 8:
 155    case 9:
 156    case 10:
 157        args = 2;
 158        break;
 159    case 12:
 160    case 13:
 161        args = 3;
 162        break;
 163    case 14:
 164        args = 4;
 165        break;
 166    default:
 167        gen_reserved_instruction(ctx);
 168        return;
 169    }
 170
 171    switch (args) {
 172    case 4:
 173        gen_base_offset_addr(ctx, t0, 29, 12);
 174        gen_load_gpr(t1, 7);
 175        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
 176        /* Fall through */
 177    case 3:
 178        gen_base_offset_addr(ctx, t0, 29, 8);
 179        gen_load_gpr(t1, 6);
 180        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
 181        /* Fall through */
 182    case 2:
 183        gen_base_offset_addr(ctx, t0, 29, 4);
 184        gen_load_gpr(t1, 5);
 185        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
 186        /* Fall through */
 187    case 1:
 188        gen_base_offset_addr(ctx, t0, 29, 0);
 189        gen_load_gpr(t1, 4);
 190        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
 191    }
 192
 193    gen_load_gpr(t0, 29);
 194
 195#define DECR_AND_STORE(reg) do {                                 \
 196        tcg_gen_movi_tl(t2, -4);                                 \
 197        gen_op_addr_add(ctx, t0, t0, t2);                        \
 198        gen_load_gpr(t1, reg);                                   \
 199        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
 200    } while (0)
 201
 202    if (do_ra) {
 203        DECR_AND_STORE(31);
 204    }
 205
 206    switch (xsregs) {
 207    case 7:
 208        DECR_AND_STORE(30);
 209        /* Fall through */
 210    case 6:
 211        DECR_AND_STORE(23);
 212        /* Fall through */
 213    case 5:
 214        DECR_AND_STORE(22);
 215        /* Fall through */
 216    case 4:
 217        DECR_AND_STORE(21);
 218        /* Fall through */
 219    case 3:
 220        DECR_AND_STORE(20);
 221        /* Fall through */
 222    case 2:
 223        DECR_AND_STORE(19);
 224        /* Fall through */
 225    case 1:
 226        DECR_AND_STORE(18);
 227    }
 228
 229    if (do_s1) {
 230        DECR_AND_STORE(17);
 231    }
 232    if (do_s0) {
 233        DECR_AND_STORE(16);
 234    }
 235
 236    switch (aregs) {
 237    case 0:
 238    case 4:
 239    case 8:
 240    case 12:
 241    case 14:
 242        astatic = 0;
 243        break;
 244    case 1:
 245    case 5:
 246    case 9:
 247    case 13:
 248        astatic = 1;
 249        break;
 250    case 2:
 251    case 6:
 252    case 10:
 253        astatic = 2;
 254        break;
 255    case 3:
 256    case 7:
 257        astatic = 3;
 258        break;
 259    case 11:
 260        astatic = 4;
 261        break;
 262    default:
 263        gen_reserved_instruction(ctx);
 264        return;
 265    }
 266
 267    if (astatic > 0) {
 268        DECR_AND_STORE(7);
 269        if (astatic > 1) {
 270            DECR_AND_STORE(6);
 271            if (astatic > 2) {
 272                DECR_AND_STORE(5);
 273                if (astatic > 3) {
 274                    DECR_AND_STORE(4);
 275                }
 276            }
 277        }
 278    }
 279#undef DECR_AND_STORE
 280
 281    tcg_gen_movi_tl(t2, -framesize);
 282    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
 283    tcg_temp_free(t0);
 284    tcg_temp_free(t1);
 285    tcg_temp_free(t2);
 286}
 287
 288static void gen_mips16_restore(DisasContext *ctx,
 289                               int xsregs, int aregs,
 290                               int do_ra, int do_s0, int do_s1,
 291                               int framesize)
 292{
 293    int astatic;
 294    TCGv t0 = tcg_temp_new();
 295    TCGv t1 = tcg_temp_new();
 296    TCGv t2 = tcg_temp_new();
 297
 298    tcg_gen_movi_tl(t2, framesize);
 299    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
 300
 301#define DECR_AND_LOAD(reg) do {                            \
 302        tcg_gen_movi_tl(t2, -4);                           \
 303        gen_op_addr_add(ctx, t0, t0, t2);                  \
 304        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
 305        gen_store_gpr(t1, reg);                            \
 306    } while (0)
 307
 308    if (do_ra) {
 309        DECR_AND_LOAD(31);
 310    }
 311
 312    switch (xsregs) {
 313    case 7:
 314        DECR_AND_LOAD(30);
 315        /* Fall through */
 316    case 6:
 317        DECR_AND_LOAD(23);
 318        /* Fall through */
 319    case 5:
 320        DECR_AND_LOAD(22);
 321        /* Fall through */
 322    case 4:
 323        DECR_AND_LOAD(21);
 324        /* Fall through */
 325    case 3:
 326        DECR_AND_LOAD(20);
 327        /* Fall through */
 328    case 2:
 329        DECR_AND_LOAD(19);
 330        /* Fall through */
 331    case 1:
 332        DECR_AND_LOAD(18);
 333    }
 334
 335    if (do_s1) {
 336        DECR_AND_LOAD(17);
 337    }
 338    if (do_s0) {
 339        DECR_AND_LOAD(16);
 340    }
 341
 342    switch (aregs) {
 343    case 0:
 344    case 4:
 345    case 8:
 346    case 12:
 347    case 14:
 348        astatic = 0;
 349        break;
 350    case 1:
 351    case 5:
 352    case 9:
 353    case 13:
 354        astatic = 1;
 355        break;
 356    case 2:
 357    case 6:
 358    case 10:
 359        astatic = 2;
 360        break;
 361    case 3:
 362    case 7:
 363        astatic = 3;
 364        break;
 365    case 11:
 366        astatic = 4;
 367        break;
 368    default:
 369        gen_reserved_instruction(ctx);
 370        return;
 371    }
 372
 373    if (astatic > 0) {
 374        DECR_AND_LOAD(7);
 375        if (astatic > 1) {
 376            DECR_AND_LOAD(6);
 377            if (astatic > 2) {
 378                DECR_AND_LOAD(5);
 379                if (astatic > 3) {
 380                    DECR_AND_LOAD(4);
 381                }
 382            }
 383        }
 384    }
 385#undef DECR_AND_LOAD
 386
 387    tcg_gen_movi_tl(t2, framesize);
 388    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
 389    tcg_temp_free(t0);
 390    tcg_temp_free(t1);
 391    tcg_temp_free(t2);
 392}
 393
 394#if defined(TARGET_MIPS64)
 395static void decode_i64_mips16(DisasContext *ctx,
 396                              int ry, int funct, int16_t offset,
 397                              int extended)
 398{
 399    switch (funct) {
 400    case I64_LDSP:
 401        check_insn(ctx, ISA_MIPS3);
 402        check_mips_64(ctx);
 403        offset = extended ? offset : offset << 3;
 404        gen_ld(ctx, OPC_LD, ry, 29, offset);
 405        break;
 406    case I64_SDSP:
 407        check_insn(ctx, ISA_MIPS3);
 408        check_mips_64(ctx);
 409        offset = extended ? offset : offset << 3;
 410        gen_st(ctx, OPC_SD, ry, 29, offset);
 411        break;
 412    case I64_SDRASP:
 413        check_insn(ctx, ISA_MIPS3);
 414        check_mips_64(ctx);
 415        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
 416        gen_st(ctx, OPC_SD, 31, 29, offset);
 417        break;
 418    case I64_DADJSP:
 419        check_insn(ctx, ISA_MIPS3);
 420        check_mips_64(ctx);
 421        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
 422        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
 423        break;
 424    case I64_LDPC:
 425        check_insn(ctx, ISA_MIPS3);
 426        check_mips_64(ctx);
 427        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
 428            gen_reserved_instruction(ctx);
 429        } else {
 430            offset = extended ? offset : offset << 3;
 431            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
 432        }
 433        break;
 434    case I64_DADDIU5:
 435        check_insn(ctx, ISA_MIPS3);
 436        check_mips_64(ctx);
 437        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
 438        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
 439        break;
 440    case I64_DADDIUPC:
 441        check_insn(ctx, ISA_MIPS3);
 442        check_mips_64(ctx);
 443        offset = extended ? offset : offset << 2;
 444        gen_addiupc(ctx, ry, offset, 1, extended);
 445        break;
 446    case I64_DADDIUSP:
 447        check_insn(ctx, ISA_MIPS3);
 448        check_mips_64(ctx);
 449        offset = extended ? offset : offset << 2;
 450        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
 451        break;
 452    }
 453}
 454#endif
 455
 456static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
 457{
 458    int extend = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
 459    int op, rx, ry, funct, sa;
 460    int16_t imm, offset;
 461
 462    ctx->opcode = (ctx->opcode << 16) | extend;
 463    op = (ctx->opcode >> 11) & 0x1f;
 464    sa = (ctx->opcode >> 22) & 0x1f;
 465    funct = (ctx->opcode >> 8) & 0x7;
 466    rx = xlat((ctx->opcode >> 8) & 0x7);
 467    ry = xlat((ctx->opcode >> 5) & 0x7);
 468    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
 469                              | ((ctx->opcode >> 21) & 0x3f) << 5
 470                              | (ctx->opcode & 0x1f));
 471
 472    /*
 473     * The extended opcodes cleverly reuse the opcodes from their 16-bit
 474     * counterparts.
 475     */
 476    switch (op) {
 477    case M16_OPC_ADDIUSP:
 478        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
 479        break;
 480    case M16_OPC_ADDIUPC:
 481        gen_addiupc(ctx, rx, imm, 0, 1);
 482        break;
 483    case M16_OPC_B:
 484        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
 485        /* No delay slot, so just process as a normal instruction */
 486        break;
 487    case M16_OPC_BEQZ:
 488        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
 489        /* No delay slot, so just process as a normal instruction */
 490        break;
 491    case M16_OPC_BNEQZ:
 492        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
 493        /* No delay slot, so just process as a normal instruction */
 494        break;
 495    case M16_OPC_SHIFT:
 496        switch (ctx->opcode & 0x3) {
 497        case 0x0:
 498            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
 499            break;
 500        case 0x1:
 501#if defined(TARGET_MIPS64)
 502            check_mips_64(ctx);
 503            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
 504#else
 505            gen_reserved_instruction(ctx);
 506#endif
 507            break;
 508        case 0x2:
 509            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
 510            break;
 511        case 0x3:
 512            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
 513            break;
 514        }
 515        break;
 516#if defined(TARGET_MIPS64)
 517    case M16_OPC_LD:
 518        check_insn(ctx, ISA_MIPS3);
 519        check_mips_64(ctx);
 520        gen_ld(ctx, OPC_LD, ry, rx, offset);
 521        break;
 522#endif
 523    case M16_OPC_RRIA:
 524        imm = ctx->opcode & 0xf;
 525        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
 526        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
 527        imm = (int16_t) (imm << 1) >> 1;
 528        if ((ctx->opcode >> 4) & 0x1) {
 529#if defined(TARGET_MIPS64)
 530            check_mips_64(ctx);
 531            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
 532#else
 533            gen_reserved_instruction(ctx);
 534#endif
 535        } else {
 536            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
 537        }
 538        break;
 539    case M16_OPC_ADDIU8:
 540        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
 541        break;
 542    case M16_OPC_SLTI:
 543        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
 544        break;
 545    case M16_OPC_SLTIU:
 546        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
 547        break;
 548    case M16_OPC_I8:
 549        switch (funct) {
 550        case I8_BTEQZ:
 551            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
 552            break;
 553        case I8_BTNEZ:
 554            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
 555            break;
 556        case I8_SWRASP:
 557            gen_st(ctx, OPC_SW, 31, 29, imm);
 558            break;
 559        case I8_ADJSP:
 560            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
 561            break;
 562        case I8_SVRS:
 563            check_insn(ctx, ISA_MIPS_R1);
 564            {
 565                int xsregs = (ctx->opcode >> 24) & 0x7;
 566                int aregs = (ctx->opcode >> 16) & 0xf;
 567                int do_ra = (ctx->opcode >> 6) & 0x1;
 568                int do_s0 = (ctx->opcode >> 5) & 0x1;
 569                int do_s1 = (ctx->opcode >> 4) & 0x1;
 570                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
 571                                 | (ctx->opcode & 0xf)) << 3;
 572
 573                if (ctx->opcode & (1 << 7)) {
 574                    gen_mips16_save(ctx, xsregs, aregs,
 575                                    do_ra, do_s0, do_s1,
 576                                    framesize);
 577                } else {
 578                    gen_mips16_restore(ctx, xsregs, aregs,
 579                                       do_ra, do_s0, do_s1,
 580                                       framesize);
 581                }
 582            }
 583            break;
 584        default:
 585            gen_reserved_instruction(ctx);
 586            break;
 587        }
 588        break;
 589    case M16_OPC_LI:
 590        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
 591        break;
 592    case M16_OPC_CMPI:
 593        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
 594        break;
 595#if defined(TARGET_MIPS64)
 596    case M16_OPC_SD:
 597        check_insn(ctx, ISA_MIPS3);
 598        check_mips_64(ctx);
 599        gen_st(ctx, OPC_SD, ry, rx, offset);
 600        break;
 601#endif
 602    case M16_OPC_LB:
 603        gen_ld(ctx, OPC_LB, ry, rx, offset);
 604        break;
 605    case M16_OPC_LH:
 606        gen_ld(ctx, OPC_LH, ry, rx, offset);
 607        break;
 608    case M16_OPC_LWSP:
 609        gen_ld(ctx, OPC_LW, rx, 29, offset);
 610        break;
 611    case M16_OPC_LW:
 612        gen_ld(ctx, OPC_LW, ry, rx, offset);
 613        break;
 614    case M16_OPC_LBU:
 615        gen_ld(ctx, OPC_LBU, ry, rx, offset);
 616        break;
 617    case M16_OPC_LHU:
 618        gen_ld(ctx, OPC_LHU, ry, rx, offset);
 619        break;
 620    case M16_OPC_LWPC:
 621        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
 622        break;
 623#if defined(TARGET_MIPS64)
 624    case M16_OPC_LWU:
 625        check_insn(ctx, ISA_MIPS3);
 626        check_mips_64(ctx);
 627        gen_ld(ctx, OPC_LWU, ry, rx, offset);
 628        break;
 629#endif
 630    case M16_OPC_SB:
 631        gen_st(ctx, OPC_SB, ry, rx, offset);
 632        break;
 633    case M16_OPC_SH:
 634        gen_st(ctx, OPC_SH, ry, rx, offset);
 635        break;
 636    case M16_OPC_SWSP:
 637        gen_st(ctx, OPC_SW, rx, 29, offset);
 638        break;
 639    case M16_OPC_SW:
 640        gen_st(ctx, OPC_SW, ry, rx, offset);
 641        break;
 642#if defined(TARGET_MIPS64)
 643    case M16_OPC_I64:
 644        decode_i64_mips16(ctx, ry, funct, offset, 1);
 645        break;
 646#endif
 647    default:
 648        gen_reserved_instruction(ctx);
 649        break;
 650    }
 651
 652    return 4;
 653}
 654
 655static int decode_ase_mips16e(CPUMIPSState *env, DisasContext *ctx)
 656{
 657    int rx, ry;
 658    int sa;
 659    int op, cnvt_op, op1, offset;
 660    int funct;
 661    int n_bytes;
 662
 663    op = (ctx->opcode >> 11) & 0x1f;
 664    sa = (ctx->opcode >> 2) & 0x7;
 665    sa = sa == 0 ? 8 : sa;
 666    rx = xlat((ctx->opcode >> 8) & 0x7);
 667    cnvt_op = (ctx->opcode >> 5) & 0x7;
 668    ry = xlat((ctx->opcode >> 5) & 0x7);
 669    op1 = offset = ctx->opcode & 0x1f;
 670
 671    n_bytes = 2;
 672
 673    switch (op) {
 674    case M16_OPC_ADDIUSP:
 675        {
 676            int16_t imm = ((uint8_t) ctx->opcode) << 2;
 677
 678            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
 679        }
 680        break;
 681    case M16_OPC_ADDIUPC:
 682        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
 683        break;
 684    case M16_OPC_B:
 685        offset = (ctx->opcode & 0x7ff) << 1;
 686        offset = (int16_t)(offset << 4) >> 4;
 687        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
 688        /* No delay slot, so just process as a normal instruction */
 689        break;
 690    case M16_OPC_JAL:
 691        offset = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
 692        offset = (((ctx->opcode & 0x1f) << 21)
 693                  | ((ctx->opcode >> 5) & 0x1f) << 16
 694                  | offset) << 2;
 695        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
 696        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
 697        n_bytes = 4;
 698        break;
 699    case M16_OPC_BEQZ:
 700        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
 701                           ((int8_t)ctx->opcode) << 1, 0);
 702        /* No delay slot, so just process as a normal instruction */
 703        break;
 704    case M16_OPC_BNEQZ:
 705        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
 706                           ((int8_t)ctx->opcode) << 1, 0);
 707        /* No delay slot, so just process as a normal instruction */
 708        break;
 709    case M16_OPC_SHIFT:
 710        switch (ctx->opcode & 0x3) {
 711        case 0x0:
 712            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
 713            break;
 714        case 0x1:
 715#if defined(TARGET_MIPS64)
 716            check_insn(ctx, ISA_MIPS3);
 717            check_mips_64(ctx);
 718            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
 719#else
 720            gen_reserved_instruction(ctx);
 721#endif
 722            break;
 723        case 0x2:
 724            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
 725            break;
 726        case 0x3:
 727            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
 728            break;
 729        }
 730        break;
 731#if defined(TARGET_MIPS64)
 732    case M16_OPC_LD:
 733        check_insn(ctx, ISA_MIPS3);
 734        check_mips_64(ctx);
 735        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
 736        break;
 737#endif
 738    case M16_OPC_RRIA:
 739        {
 740            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
 741
 742            if ((ctx->opcode >> 4) & 1) {
 743#if defined(TARGET_MIPS64)
 744                check_insn(ctx, ISA_MIPS3);
 745                check_mips_64(ctx);
 746                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
 747#else
 748                gen_reserved_instruction(ctx);
 749#endif
 750            } else {
 751                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
 752            }
 753        }
 754        break;
 755    case M16_OPC_ADDIU8:
 756        {
 757            int16_t imm = (int8_t) ctx->opcode;
 758
 759            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
 760        }
 761        break;
 762    case M16_OPC_SLTI:
 763        {
 764            int16_t imm = (uint8_t) ctx->opcode;
 765            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
 766        }
 767        break;
 768    case M16_OPC_SLTIU:
 769        {
 770            int16_t imm = (uint8_t) ctx->opcode;
 771            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
 772        }
 773        break;
 774    case M16_OPC_I8:
 775        {
 776            int reg32;
 777
 778            funct = (ctx->opcode >> 8) & 0x7;
 779            switch (funct) {
 780            case I8_BTEQZ:
 781                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
 782                                   ((int8_t)ctx->opcode) << 1, 0);
 783                break;
 784            case I8_BTNEZ:
 785                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
 786                                   ((int8_t)ctx->opcode) << 1, 0);
 787                break;
 788            case I8_SWRASP:
 789                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
 790                break;
 791            case I8_ADJSP:
 792                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
 793                              ((int8_t)ctx->opcode) << 3);
 794                break;
 795            case I8_SVRS:
 796                check_insn(ctx, ISA_MIPS_R1);
 797                {
 798                    int do_ra = ctx->opcode & (1 << 6);
 799                    int do_s0 = ctx->opcode & (1 << 5);
 800                    int do_s1 = ctx->opcode & (1 << 4);
 801                    int framesize = ctx->opcode & 0xf;
 802
 803                    if (framesize == 0) {
 804                        framesize = 128;
 805                    } else {
 806                        framesize = framesize << 3;
 807                    }
 808
 809                    if (ctx->opcode & (1 << 7)) {
 810                        gen_mips16_save(ctx, 0, 0,
 811                                        do_ra, do_s0, do_s1, framesize);
 812                    } else {
 813                        gen_mips16_restore(ctx, 0, 0,
 814                                           do_ra, do_s0, do_s1, framesize);
 815                    }
 816                }
 817                break;
 818            case I8_MOV32R:
 819                {
 820                    int rz = xlat(ctx->opcode & 0x7);
 821
 822                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
 823                        ((ctx->opcode >> 5) & 0x7);
 824                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
 825                }
 826                break;
 827            case I8_MOVR32:
 828                reg32 = ctx->opcode & 0x1f;
 829                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
 830                break;
 831            default:
 832                gen_reserved_instruction(ctx);
 833                break;
 834            }
 835        }
 836        break;
 837    case M16_OPC_LI:
 838        {
 839            int16_t imm = (uint8_t) ctx->opcode;
 840
 841            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
 842        }
 843        break;
 844    case M16_OPC_CMPI:
 845        {
 846            int16_t imm = (uint8_t) ctx->opcode;
 847            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
 848        }
 849        break;
 850#if defined(TARGET_MIPS64)
 851    case M16_OPC_SD:
 852        check_insn(ctx, ISA_MIPS3);
 853        check_mips_64(ctx);
 854        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
 855        break;
 856#endif
 857    case M16_OPC_LB:
 858        gen_ld(ctx, OPC_LB, ry, rx, offset);
 859        break;
 860    case M16_OPC_LH:
 861        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
 862        break;
 863    case M16_OPC_LWSP:
 864        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
 865        break;
 866    case M16_OPC_LW:
 867        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
 868        break;
 869    case M16_OPC_LBU:
 870        gen_ld(ctx, OPC_LBU, ry, rx, offset);
 871        break;
 872    case M16_OPC_LHU:
 873        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
 874        break;
 875    case M16_OPC_LWPC:
 876        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
 877        break;
 878#if defined(TARGET_MIPS64)
 879    case M16_OPC_LWU:
 880        check_insn(ctx, ISA_MIPS3);
 881        check_mips_64(ctx);
 882        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
 883        break;
 884#endif
 885    case M16_OPC_SB:
 886        gen_st(ctx, OPC_SB, ry, rx, offset);
 887        break;
 888    case M16_OPC_SH:
 889        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
 890        break;
 891    case M16_OPC_SWSP:
 892        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
 893        break;
 894    case M16_OPC_SW:
 895        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
 896        break;
 897    case M16_OPC_RRR:
 898        {
 899            int rz = xlat((ctx->opcode >> 2) & 0x7);
 900            int mips32_op;
 901
 902            switch (ctx->opcode & 0x3) {
 903            case RRR_ADDU:
 904                mips32_op = OPC_ADDU;
 905                break;
 906            case RRR_SUBU:
 907                mips32_op = OPC_SUBU;
 908                break;
 909#if defined(TARGET_MIPS64)
 910            case RRR_DADDU:
 911                mips32_op = OPC_DADDU;
 912                check_insn(ctx, ISA_MIPS3);
 913                check_mips_64(ctx);
 914                break;
 915            case RRR_DSUBU:
 916                mips32_op = OPC_DSUBU;
 917                check_insn(ctx, ISA_MIPS3);
 918                check_mips_64(ctx);
 919                break;
 920#endif
 921            default:
 922                gen_reserved_instruction(ctx);
 923                goto done;
 924            }
 925
 926            gen_arith(ctx, mips32_op, rz, rx, ry);
 927        done:
 928            ;
 929        }
 930        break;
 931    case M16_OPC_RR:
 932        switch (op1) {
 933        case RR_JR:
 934            {
 935                int nd = (ctx->opcode >> 7) & 0x1;
 936                int link = (ctx->opcode >> 6) & 0x1;
 937                int ra = (ctx->opcode >> 5) & 0x1;
 938
 939                if (nd) {
 940                    check_insn(ctx, ISA_MIPS_R1);
 941                }
 942
 943                if (link) {
 944                    op = OPC_JALR;
 945                } else {
 946                    op = OPC_JR;
 947                }
 948
 949                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
 950                                   (nd ? 0 : 2));
 951            }
 952            break;
 953        case RR_SDBBP:
 954            if (is_uhi(ctx, extract32(ctx->opcode, 5, 6))) {
 955                ctx->base.is_jmp = DISAS_SEMIHOST;
 956            } else {
 957                /*
 958                 * XXX: not clear which exception should be raised
 959                 *      when in debug mode...
 960                 */
 961                check_insn(ctx, ISA_MIPS_R1);
 962                generate_exception_end(ctx, EXCP_DBp);
 963            }
 964            break;
 965        case RR_SLT:
 966            gen_slt(ctx, OPC_SLT, 24, rx, ry);
 967            break;
 968        case RR_SLTU:
 969            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
 970            break;
 971        case RR_BREAK:
 972            generate_exception_break(ctx, extract32(ctx->opcode, 5, 6));
 973            break;
 974        case RR_SLLV:
 975            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
 976            break;
 977        case RR_SRLV:
 978            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
 979            break;
 980        case RR_SRAV:
 981            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
 982            break;
 983#if defined(TARGET_MIPS64)
 984        case RR_DSRL:
 985            check_insn(ctx, ISA_MIPS3);
 986            check_mips_64(ctx);
 987            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
 988            break;
 989#endif
 990        case RR_CMP:
 991            gen_logic(ctx, OPC_XOR, 24, rx, ry);
 992            break;
 993        case RR_NEG:
 994            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
 995            break;
 996        case RR_AND:
 997            gen_logic(ctx, OPC_AND, rx, rx, ry);
 998            break;
 999        case RR_OR:
1000            gen_logic(ctx, OPC_OR, rx, rx, ry);
1001            break;
1002        case RR_XOR:
1003            gen_logic(ctx, OPC_XOR, rx, rx, ry);
1004            break;
1005        case RR_NOT:
1006            gen_logic(ctx, OPC_NOR, rx, ry, 0);
1007            break;
1008        case RR_MFHI:
1009            gen_HILO(ctx, OPC_MFHI, 0, rx);
1010            break;
1011        case RR_CNVT:
1012            check_insn(ctx, ISA_MIPS_R1);
1013            switch (cnvt_op) {
1014            case RR_RY_CNVT_ZEB:
1015                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
1016                break;
1017            case RR_RY_CNVT_ZEH:
1018                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
1019                break;
1020            case RR_RY_CNVT_SEB:
1021                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
1022                break;
1023            case RR_RY_CNVT_SEH:
1024                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
1025                break;
1026#if defined(TARGET_MIPS64)
1027            case RR_RY_CNVT_ZEW:
1028                check_insn(ctx, ISA_MIPS_R1);
1029                check_mips_64(ctx);
1030                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
1031                break;
1032            case RR_RY_CNVT_SEW:
1033                check_insn(ctx, ISA_MIPS_R1);
1034                check_mips_64(ctx);
1035                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
1036                break;
1037#endif
1038            default:
1039                gen_reserved_instruction(ctx);
1040                break;
1041            }
1042            break;
1043        case RR_MFLO:
1044            gen_HILO(ctx, OPC_MFLO, 0, rx);
1045            break;
1046#if defined(TARGET_MIPS64)
1047        case RR_DSRA:
1048            check_insn(ctx, ISA_MIPS3);
1049            check_mips_64(ctx);
1050            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
1051            break;
1052        case RR_DSLLV:
1053            check_insn(ctx, ISA_MIPS3);
1054            check_mips_64(ctx);
1055            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
1056            break;
1057        case RR_DSRLV:
1058            check_insn(ctx, ISA_MIPS3);
1059            check_mips_64(ctx);
1060            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
1061            break;
1062        case RR_DSRAV:
1063            check_insn(ctx, ISA_MIPS3);
1064            check_mips_64(ctx);
1065            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
1066            break;
1067#endif
1068        case RR_MULT:
1069            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
1070            break;
1071        case RR_MULTU:
1072            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
1073            break;
1074        case RR_DIV:
1075            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
1076            break;
1077        case RR_DIVU:
1078            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
1079            break;
1080#if defined(TARGET_MIPS64)
1081        case RR_DMULT:
1082            check_insn(ctx, ISA_MIPS3);
1083            check_mips_64(ctx);
1084            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
1085            break;
1086        case RR_DMULTU:
1087            check_insn(ctx, ISA_MIPS3);
1088            check_mips_64(ctx);
1089            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
1090            break;
1091        case RR_DDIV:
1092            check_insn(ctx, ISA_MIPS3);
1093            check_mips_64(ctx);
1094            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
1095            break;
1096        case RR_DDIVU:
1097            check_insn(ctx, ISA_MIPS3);
1098            check_mips_64(ctx);
1099            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
1100            break;
1101#endif
1102        default:
1103            gen_reserved_instruction(ctx);
1104            break;
1105        }
1106        break;
1107    case M16_OPC_EXTEND:
1108        decode_extended_mips16_opc(env, ctx);
1109        n_bytes = 4;
1110        break;
1111#if defined(TARGET_MIPS64)
1112    case M16_OPC_I64:
1113        funct = (ctx->opcode >> 8) & 0x7;
1114        decode_i64_mips16(ctx, ry, funct, offset, 0);
1115        break;
1116#endif
1117    default:
1118        gen_reserved_instruction(ctx);
1119        break;
1120    }
1121
1122    return n_bytes;
1123}
1124