qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

mips16e_translate.c.inc (30578B)


      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 */
     13 enum {
     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 */
     49 enum {
     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 */
     60 enum {
     61   RRR_DADDU = 0x0,
     62   RRR_ADDU = 0x1,
     63   RRR_DSUBU = 0x2,
     64   RRR_SUBU = 0x3
     65 };
     66 
     67 /* RR funct field */
     68 enum {
     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 */
    102 enum {
    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 */
    114 enum {
    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 
    123 static int xlat(int r)
    124 {
    125   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
    126 
    127   return map[r];
    128 }
    129 
    130 static 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 
    288 static 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)
    395 static 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 
    456 static 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 
    655 static 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 }