]> git.proxmox.com Git - qemu.git/blobdiff - target-s390x/translate.c
target-s390: Convert STORE
[qemu.git] / target-s390x / translate.c
index ba154f73d9ba931941b5c4cdb3e1877b348dd09e..f17fa2f74eaef8f5736028c2825631c6ede2f5cb 100644 (file)
@@ -570,42 +570,12 @@ static void set_cc_addu64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2,
     gen_op_update3_cc_i64(s, CC_OP_ADDU_64, v1, v2, vr);
 }
 
-static void set_cc_abs64(DisasContext *s, TCGv_i64 v1)
-{
-    gen_op_update1_cc_i64(s, CC_OP_ABS_64, v1);
-}
-
-static void set_cc_nabs64(DisasContext *s, TCGv_i64 v1)
-{
-    gen_op_update1_cc_i64(s, CC_OP_NABS_64, v1);
-}
-
 static void set_cc_addu32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2,
                           TCGv_i32 vr)
 {
     gen_op_update3_cc_i32(s, CC_OP_ADDU_32, v1, v2, vr);
 }
 
-static void set_cc_abs32(DisasContext *s, TCGv_i32 v1)
-{
-    gen_op_update1_cc_i32(s, CC_OP_ABS_32, v1);
-}
-
-static void set_cc_nabs32(DisasContext *s, TCGv_i32 v1)
-{
-    gen_op_update1_cc_i32(s, CC_OP_NABS_32, v1);
-}
-
-static void set_cc_comp32(DisasContext *s, TCGv_i32 v1)
-{
-    gen_op_update1_cc_i32(s, CC_OP_COMP_32, v1);
-}
-
-static void set_cc_comp64(DisasContext *s, TCGv_i64 v1)
-{
-    gen_op_update1_cc_i64(s, CC_OP_COMP_64, v1);
-}
-
 static void set_cc_icm(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2)
 {
     gen_op_update2_cc_i32(s, CC_OP_ICM, v1, v2);
@@ -1349,23 +1319,6 @@ static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
               op, r1, x2, b2, d2);
     addr = get_address(s, x2, b2, d2);
     switch (op) {
-    case 0x2: /* LTG R1,D2(X2,B2) [RXY] */
-    case 0x4: /* lg r1,d2(x2,b2) */
-        tcg_gen_qemu_ld64(regs[r1], addr, get_mem_index(s));
-        if (op == 0x2) {
-            set_cc_s64(s, regs[r1]);
-        }
-        break;
-    case 0x12: /* LT R1,D2(X2,B2) [RXY] */
-        tmp2 = tcg_temp_new_i64();
-        tmp32_1 = tcg_temp_new_i32();
-        tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
-        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
-        store_reg32(r1, tmp32_1);
-        set_cc_s32(s, tmp32_1);
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i32(tmp32_1);
-        break;
     case 0xd: /* DSG      R1,D2(X2,B2)     [RXY] */
     case 0x1d: /* DSGF      R1,D2(X2,B2)     [RXY] */
         tmp2 = tcg_temp_new_i64();
@@ -1391,22 +1344,6 @@ static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
         store_reg(r1, tmp2);
         tcg_temp_free_i64(tmp2);
         break;
-    case 0x14: /* LGF      R1,D2(X2,B2)     [RXY] */
-    case 0x16: /* LLGF      R1,D2(X2,B2)     [RXY] */
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
-        if (op == 0x14) {
-            tcg_gen_ext32s_i64(tmp2, tmp2);
-        }
-        store_reg(r1, tmp2);
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x15: /* LGH     R1,D2(X2,B2)     [RXY] */
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld16s(tmp2, addr, get_mem_index(s));
-        store_reg(r1, tmp2);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0x17: /* LLGT      R1,D2(X2,B2)     [RXY] */
         tmp2 = tcg_temp_new_i64();
         tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
@@ -1434,42 +1371,6 @@ static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
         store_reg16(r1, tmp32_1);
         tcg_temp_free_i32(tmp32_1);
         break;
-    case 0x20: /* CG      R1,D2(X2,B2)     [RXY] */
-    case 0x21: /* CLG      R1,D2(X2,B2) */
-    case 0x30: /* CGF       R1,D2(X2,B2)     [RXY] */
-    case 0x31: /* CLGF      R1,D2(X2,B2)     [RXY] */
-        tmp2 = tcg_temp_new_i64();
-        switch (op) {
-        case 0x20:
-        case 0x21:
-            tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
-            break;
-        case 0x30:
-            tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
-            break;
-        case 0x31:
-            tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
-            break;
-        default:
-            tcg_abort();
-        }
-        switch (op) {
-        case 0x20:
-        case 0x30:
-            cmp_s64(s, regs[r1], tmp2);
-            break;
-        case 0x21:
-        case 0x31:
-            cmp_u64(s, regs[r1], tmp2);
-            break;
-        default:
-            tcg_abort();
-        }
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x24: /* stg r1, d2(x2,b2) */
-        tcg_gen_qemu_st64(regs[r1], addr, get_mem_index(s));
-        break;
     case 0x3e: /* STRV R1,D2(X2,B2) [RXY] */
         tmp32_1 = load_reg32(r1);
         tmp2 = tcg_temp_new_i64();
@@ -1479,61 +1380,12 @@ static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
         tcg_gen_qemu_st32(tmp2, addr, get_mem_index(s));
         tcg_temp_free_i64(tmp2);
         break;
-    case 0x50: /* STY  R1,D2(X2,B2) [RXY] */
-        tmp32_1 = load_reg32(r1);
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_extu_i32_i64(tmp2, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        tcg_gen_qemu_st32(tmp2, addr, get_mem_index(s));
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x58: /* LY R1,D2(X2,B2) [RXY] */
-        tmp3 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld32u(tmp3, addr, get_mem_index(s));
-        store_reg32_i64(r1, tmp3);
-        tcg_temp_free_i64(tmp3);
-        break;
-    case 0x71: /* LAY R1,D2(X2,B2) [RXY] */
-        store_reg(r1, addr);
-        break;
-    case 0x72: /* STCY R1,D2(X2,B2) [RXY] */
-        tmp32_1 = load_reg32(r1);
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_ext_i32_i64(tmp2, tmp32_1);
-        tcg_gen_qemu_st8(tmp2, addr, get_mem_index(s));
-        tcg_temp_free_i32(tmp32_1);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0x73: /* ICY R1,D2(X2,B2) [RXY] */
         tmp3 = tcg_temp_new_i64();
         tcg_gen_qemu_ld8u(tmp3, addr, get_mem_index(s));
         store_reg8(r1, tmp3);
         tcg_temp_free_i64(tmp3);
         break;
-    case 0x76: /* LB R1,D2(X2,B2) [RXY] */
-    case 0x77: /* LGB R1,D2(X2,B2) [RXY] */
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld8s(tmp2, addr, get_mem_index(s));
-        switch (op) {
-        case 0x76:
-            tcg_gen_ext8s_i64(tmp2, tmp2);
-            store_reg32_i64(r1, tmp2);
-            break;
-        case 0x77:
-            tcg_gen_ext8s_i64(tmp2, tmp2);
-            store_reg(r1, tmp2);
-            break;
-        default:
-            tcg_abort();
-        }
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x78: /* LHY R1,D2(X2,B2) [RXY] */
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld16s(tmp2, addr, get_mem_index(s));
-        store_reg32_i64(r1, tmp2);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0x87: /* DLG      R1,D2(X2,B2)     [RXY] */
         tmp2 = tcg_temp_new_i64();
         tmp32_1 = tcg_const_i32(r1);
@@ -1569,24 +1421,6 @@ static void disas_e3(CPUS390XState *env, DisasContext* s, int op, int r1,
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32_1);
         break;
-    case 0x90: /* LLGC      R1,D2(X2,B2)     [RXY] */
-        tcg_gen_qemu_ld8u(regs[r1], addr, get_mem_index(s));
-        break;
-    case 0x91: /* LLGH      R1,D2(X2,B2)     [RXY] */
-        tcg_gen_qemu_ld16u(regs[r1], addr, get_mem_index(s));
-        break;
-    case 0x94: /* LLC     R1,D2(X2,B2)     [RXY] */
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld8u(tmp2, addr, get_mem_index(s));
-        store_reg32_i64(r1, tmp2);
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x95: /* LLH     R1,D2(X2,B2)     [RXY] */
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld16u(tmp2, addr, get_mem_index(s));
-        store_reg32_i64(r1, tmp2);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0x97: /* DL     R1,D2(X2,B2)     [RXY] */
         /* reg(r1) = reg(r1, r1+1) % ld32(addr) */
         /* reg(r1+1) = reg(r1, r1+1) / ld32(addr) */
@@ -1881,17 +1715,6 @@ do_mh:
         tcg_temp_free_i64(tmp);
         tcg_temp_free_i64(tmp2);
         break;
-    case 0x55: /* CLIY D1(B1),I2 [SIY] */
-        tmp3 = get_address(s, 0, b2, d2); /* SIY -> this is the 1st operand */
-        tmp = tcg_temp_new_i64();
-        tmp32_1 = tcg_temp_new_i32();
-        tcg_gen_qemu_ld8u(tmp, tmp3, get_mem_index(s));
-        tcg_gen_trunc_i64_i32(tmp32_1, tmp);
-        cmp_u32c(s, tmp32_1, (r1 << 4) | r3);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp3);
-        tcg_temp_free_i32(tmp32_1);
-        break;
     case 0x80: /* ICMH      R1,M3,D2(B2)     [RSY] */
         tmp = get_address(s, 0, b2, d2);
         tmp32_1 = tcg_const_i32(r1);
@@ -2033,161 +1856,6 @@ static void disas_ed(CPUS390XState *env, DisasContext *s, int op, int r1,
     tcg_temp_free_i64(addr);
 }
 
-static void disas_a5(CPUS390XState *env, DisasContext *s, int op, int r1,
-                     int i2)
-{
-    TCGv_i64 tmp, tmp2;
-    TCGv_i32 tmp32;
-    LOG_DISAS("disas_a5: op 0x%x r1 %d i2 0x%x\n", op, r1, i2);
-    switch (op) {
-    case 0x0: /* IIHH     R1,I2     [RI] */
-        tmp = tcg_const_i64(i2);
-        tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 48, 16);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x1: /* IIHL     R1,I2     [RI] */
-        tmp = tcg_const_i64(i2);
-        tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 32, 16);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x2: /* IILH     R1,I2     [RI] */
-        tmp = tcg_const_i64(i2);
-        tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 16, 16);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x3: /* IILL     R1,I2     [RI] */
-        tmp = tcg_const_i64(i2);
-        tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 0, 16);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x4: /* NIHH     R1,I2     [RI] */
-    case 0x8: /* OIHH     R1,I2     [RI] */
-        tmp = load_reg(r1);
-        tmp32 = tcg_temp_new_i32();
-        switch (op) {
-        case 0x4:
-            tmp2 = tcg_const_i64((((uint64_t)i2) << 48)
-                               | 0x0000ffffffffffffULL);
-            tcg_gen_and_i64(tmp, tmp, tmp2);
-            break;
-        case 0x8:
-            tmp2 = tcg_const_i64(((uint64_t)i2) << 48);
-            tcg_gen_or_i64(tmp, tmp, tmp2);
-            break;
-        default:
-            tcg_abort();
-        }
-        store_reg(r1, tmp);
-        tcg_gen_shri_i64(tmp2, tmp, 48);
-        tcg_gen_trunc_i64_i32(tmp32, tmp2);
-        set_cc_nz_u32(s, tmp32);
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i32(tmp32);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x5: /* NIHL     R1,I2     [RI] */
-    case 0x9: /* OIHL     R1,I2     [RI] */
-        tmp = load_reg(r1);
-        tmp32 = tcg_temp_new_i32();
-        switch (op) {
-        case 0x5:
-            tmp2 = tcg_const_i64((((uint64_t)i2) << 32)
-                               | 0xffff0000ffffffffULL);
-            tcg_gen_and_i64(tmp, tmp, tmp2);
-            break;
-        case 0x9:
-            tmp2 = tcg_const_i64(((uint64_t)i2) << 32);
-            tcg_gen_or_i64(tmp, tmp, tmp2);
-            break;
-        default:
-            tcg_abort();
-        }
-        store_reg(r1, tmp);
-        tcg_gen_shri_i64(tmp2, tmp, 32);
-        tcg_gen_trunc_i64_i32(tmp32, tmp2);
-        tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
-        set_cc_nz_u32(s, tmp32);
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i32(tmp32);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x6: /* NILH     R1,I2     [RI] */
-    case 0xa: /* OILH     R1,I2     [RI] */
-        tmp = load_reg(r1);
-        tmp32 = tcg_temp_new_i32();
-        switch (op) {
-        case 0x6:
-            tmp2 = tcg_const_i64((((uint64_t)i2) << 16)
-                               | 0xffffffff0000ffffULL);
-            tcg_gen_and_i64(tmp, tmp, tmp2);
-            break;
-        case 0xa:
-            tmp2 = tcg_const_i64(((uint64_t)i2) << 16);
-            tcg_gen_or_i64(tmp, tmp, tmp2);
-            break;
-        default:
-            tcg_abort();
-        }
-        store_reg(r1, tmp);
-        tcg_gen_shri_i64(tmp, tmp, 16);
-        tcg_gen_trunc_i64_i32(tmp32, tmp);
-        tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
-        set_cc_nz_u32(s, tmp32);
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i32(tmp32);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x7: /* NILL     R1,I2     [RI] */
-    case 0xb: /* OILL     R1,I2     [RI] */
-        tmp = load_reg(r1);
-        tmp32 = tcg_temp_new_i32();
-        switch (op) {
-        case 0x7:
-            tmp2 = tcg_const_i64(i2 | 0xffffffffffff0000ULL);
-            tcg_gen_and_i64(tmp, tmp, tmp2);
-            break;
-        case 0xb:
-            tmp2 = tcg_const_i64(i2);
-            tcg_gen_or_i64(tmp, tmp, tmp2);
-            break;
-        default:
-            tcg_abort();
-        }
-        store_reg(r1, tmp);
-        tcg_gen_trunc_i64_i32(tmp32, tmp);
-        tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
-        set_cc_nz_u32(s, tmp32);        /* signedness should not matter here */
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i32(tmp32);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0xc: /* LLIHH     R1,I2     [RI] */
-        tmp = tcg_const_i64( ((uint64_t)i2) << 48 );
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0xd: /* LLIHL     R1,I2     [RI] */
-        tmp = tcg_const_i64( ((uint64_t)i2) << 32 );
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0xe: /* LLILH     R1,I2     [RI] */
-        tmp = tcg_const_i64( ((uint64_t)i2) << 16 );
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0xf: /* LLILL     R1,I2     [RI] */
-        tmp = tcg_const_i64(i2);
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
-    default:
-        LOG_DISAS("illegal a5 operation 0x%x\n", op);
-        gen_illegal_opcode(s);
-        return;
-    }
-}
-
 static void disas_a7(CPUS390XState *env, DisasContext *s, int op, int r1,
                      int i2)
 {
@@ -2257,26 +1925,6 @@ static void disas_a7(CPUS390XState *env, DisasContext *s, int op, int r1,
         s->is_jmp = DISAS_TB_JUMP;
         tcg_temp_free_i64(tmp);
         break;
-    case 0x8: /* lhi r1, i2 */
-        tmp32_1 = tcg_const_i32(i2);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x9: /* lghi r1, i2 */
-        tmp = tcg_const_i64(i2);
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0xe: /* CHI     R1,I2     [RI] */
-        tmp32_1 = load_reg32(r1);
-        cmp_s32c(s, tmp32_1, i2);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0xf: /* CGHI     R1,I2     [RI] */
-        tmp = load_reg(r1);
-        cmp_s64c(s, tmp, i2);
-        tcg_temp_free_i64(tmp);
-        break;
     default:
         LOG_DISAS("illegal a7 operation 0x%x\n", op);
         gen_illegal_opcode(s);
@@ -2947,52 +2595,6 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
 
     LOG_DISAS("disas_b9: op 0x%x r1 %d r2 %d\n", op, r1, r2);
     switch (op) {
-    case 0x0: /* LPGR     R1,R2     [RRE] */
-    case 0x1: /* LNGR     R1,R2     [RRE] */
-    case 0x2: /* LTGR R1,R2 [RRE] */
-    case 0x3: /* LCGR     R1,R2     [RRE] */
-    case 0x10: /* LPGFR R1,R2 [RRE] */
-    case 0x11: /* LNFGR     R1,R2     [RRE] */
-    case 0x12: /* LTGFR R1,R2 [RRE] */
-    case 0x13: /* LCGFR    R1,R2     [RRE] */
-        if (op & 0x10) {
-            tmp = load_reg32_i64(r2);
-        } else {
-            tmp = load_reg(r2);
-        }
-        switch (op & 0xf) {
-        case 0x0: /* LP?GR */
-            set_cc_abs64(s, tmp);
-            gen_helper_abs_i64(tmp, tmp);
-            store_reg(r1, tmp);
-            break;
-        case 0x1: /* LN?GR */
-            set_cc_nabs64(s, tmp);
-            gen_helper_nabs_i64(tmp, tmp);
-            store_reg(r1, tmp);
-            break;
-        case 0x2: /* LT?GR */
-            if (r1 != r2) {
-                store_reg(r1, tmp);
-            }
-            set_cc_s64(s, tmp);
-            break;
-        case 0x3: /* LC?GR */
-            tcg_gen_neg_i64(regs[r1], tmp);
-            set_cc_comp64(s, regs[r1]);
-            break;
-        }
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x4: /* LGR R1,R2 [RRE] */
-        store_reg(r1, regs[r2]);
-        break;
-    case 0x6: /* LGBR R1,R2 [RRE] */
-        tmp2 = load_reg(r2);
-        tcg_gen_ext8s_i64(tmp2, tmp2);
-        store_reg(r1, tmp2);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0xd: /* DSGR      R1,R2     [RRE] */
     case 0x1d: /* DSGFR      R1,R2     [RRE] */
         tmp = load_reg(r1 + 1);
@@ -3013,22 +2615,6 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i64(tmp3);
         break;
-    case 0x14: /* LGFR     R1,R2     [RRE] */
-        tmp32_1 = load_reg32(r2);
-        tmp = tcg_temp_new_i64();
-        tcg_gen_ext_i32_i64(tmp, tmp32_1);
-        store_reg(r1, tmp);
-        tcg_temp_free_i32(tmp32_1);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x16: /* LLGFR      R1,R2     [RRE] */
-        tmp32_1 = load_reg32(r2);
-        tmp = tcg_temp_new_i64();
-        tcg_gen_extu_i32_i64(tmp, tmp32_1);
-        store_reg(r1, tmp);
-        tcg_temp_free_i32(tmp32_1);
-        tcg_temp_free_i64(tmp);
-        break;
     case 0x17: /* LLGTR      R1,R2     [RRE] */
         tmp32_1 = load_reg32(r2);
         tmp = tcg_temp_new_i64();
@@ -3047,40 +2633,6 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
         store_reg32(r1, tmp32_1);
         tcg_temp_free_i32(tmp32_1);
         break;
-    case 0x20: /* CGR      R1,R2     [RRE] */
-    case 0x30: /* CGFR     R1,R2     [RRE] */
-        tmp2 = load_reg(r2);
-        if (op == 0x30) {
-            tcg_gen_ext32s_i64(tmp2, tmp2);
-        }
-        tmp = load_reg(r1);
-        cmp_s64(s, tmp, tmp2);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x21: /* CLGR     R1,R2     [RRE] */
-    case 0x31: /* CLGFR    R1,R2     [RRE] */
-        tmp2 = load_reg(r2);
-        if (op == 0x31) {
-            tcg_gen_ext32u_i64(tmp2, tmp2);
-        }
-        tmp = load_reg(r1);
-        cmp_u64(s, tmp, tmp2);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x26: /* LBR R1,R2 [RRE] */
-        tmp32_1 = load_reg32(r2);
-        tcg_gen_ext8s_i32(tmp32_1, tmp32_1);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x27: /* LHR R1,R2 [RRE] */
-        tmp32_1 = load_reg32(r2);
-        tcg_gen_ext16s_i32(tmp32_1, tmp32_1);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
     case 0x83: /* FLOGR R1,R2 [RRE] */
         tmp = load_reg(r2);
         tmp32_1 = tcg_const_i32(r1);
@@ -3089,24 +2641,12 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
         tcg_temp_free_i64(tmp);
         tcg_temp_free_i32(tmp32_1);
         break;
-    case 0x84: /* LLGCR R1,R2 [RRE] */
+    case 0x87: /* DLGR      R1,R2     [RRE] */
+        tmp32_1 = tcg_const_i32(r1);
         tmp = load_reg(r2);
-        tcg_gen_andi_i64(tmp, tmp, 0xff);
-        store_reg(r1, tmp);
+        gen_helper_dlg(cpu_env, tmp32_1, tmp);
         tcg_temp_free_i64(tmp);
-        break;
-    case 0x85: /* LLGHR R1,R2 [RRE] */
-        tmp = load_reg(r2);
-        tcg_gen_andi_i64(tmp, tmp, 0xffff);
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x87: /* DLGR      R1,R2     [RRE] */
-        tmp32_1 = tcg_const_i32(r1);
-        tmp = load_reg(r2);
-        gen_helper_dlg(cpu_env, tmp32_1, tmp);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i32(tmp32_1);
+        tcg_temp_free_i32(tmp32_1);
         break;
     case 0x88: /* ALCGR     R1,R2     [RRE] */
         tmp = load_reg(r1);
@@ -3135,18 +2675,6 @@ static void disas_b9(CPUS390XState *env, DisasContext *s, int op, int r1,
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32_1);
         break;
-    case 0x94: /* LLCR R1,R2 [RRE] */
-        tmp32_1 = load_reg32(r2);
-        tcg_gen_andi_i32(tmp32_1, tmp32_1, 0xff);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x95: /* LLHR R1,R2 [RRE] */
-        tmp32_1 = load_reg32(r2);
-        tcg_gen_andi_i32(tmp32_1, tmp32_1, 0xffff);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
     case 0x97: /* DLR     R1,R2     [RRE] */
         /* reg(r1) = reg(r1, r1+1) % reg(r2) */
         /* reg(r1+1) = reg(r1, r1+1) / reg(r2) */
@@ -3205,16 +2733,6 @@ static void disas_c0(CPUS390XState *env, DisasContext *s, int op, int r1, int i2
     LOG_DISAS("disas_c0: op 0x%x r1 %d i2 %d\n", op, r1, i2);
 
     switch (op) {
-    case 0: /* larl r1, i2 */
-        tmp = tcg_const_i64(target);
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x1: /* LGFI R1,I2 [RIL] */
-        tmp = tcg_const_i64((int64_t)i2);
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
     case 0x4: /* BRCL     M1,I2     [RIL] */
         if (r1 == 15) { /* m1 == r1 */
             gen_goto_tb(s, 0, target);
@@ -3246,54 +2764,6 @@ static void disas_c0(CPUS390XState *env, DisasContext *s, int op, int r1, int i2
         gen_goto_tb(s, 0, target);
         s->is_jmp = DISAS_TB_JUMP;
         break;
-    case 0x7: /* XILF R1,I2 [RIL] */
-    case 0xb: /* NILF R1,I2 [RIL] */
-    case 0xd: /* OILF R1,I2 [RIL] */
-        tmp32_1 = load_reg32(r1);
-        switch (op) {
-        case 0x7:
-            tcg_gen_xori_i32(tmp32_1, tmp32_1, (uint32_t)i2);
-            break;
-        case 0xb:
-            tcg_gen_andi_i32(tmp32_1, tmp32_1, (uint32_t)i2);
-            break;
-        case 0xd:
-            tcg_gen_ori_i32(tmp32_1, tmp32_1, (uint32_t)i2);
-            break;
-        default:
-            tcg_abort();
-        }
-        store_reg32(r1, tmp32_1);
-        set_cc_nz_u32(s, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x9: /* IILF R1,I2 [RIL] */
-        tmp32_1 = tcg_const_i32((uint32_t)i2);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0xa: /* NIHF R1,I2 [RIL] */
-        tmp = load_reg(r1);
-        tmp32_1 = tcg_temp_new_i32();
-        tcg_gen_andi_i64(tmp, tmp, (((uint64_t)((uint32_t)i2)) << 32)
-                                   | 0xffffffffULL);
-        store_reg(r1, tmp);
-        tcg_gen_shri_i64(tmp, tmp, 32);
-        tcg_gen_trunc_i64_i32(tmp32_1, tmp);
-        set_cc_nz_u32(s, tmp32_1);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0xe: /* LLIHF R1,I2 [RIL] */
-        tmp = tcg_const_i64(((uint64_t)(uint32_t)i2) << 32);
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0xf: /* LLILF R1,I2 [RIL] */
-        tmp = tcg_const_i64((uint32_t)i2);
-        store_reg(r1, tmp);
-        tcg_temp_free_i64(tmp);
-        break;
     default:
         LOG_DISAS("illegal c0 operation 0x%x\n", op);
         gen_illegal_opcode(s);
@@ -3301,40 +2771,6 @@ static void disas_c0(CPUS390XState *env, DisasContext *s, int op, int r1, int i2
     }
 }
 
-static void disas_c2(CPUS390XState *env, DisasContext *s, int op, int r1,
-                     int i2)
-{
-    TCGv_i64 tmp;
-    TCGv_i32 tmp32_1;
-
-    switch (op) {
-    case 0xc: /* CGFI R1,I2 [RIL] */
-        tmp = load_reg(r1);
-        cmp_s64c(s, tmp, (int64_t)i2);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0xe: /* CLGFI R1,I2 [RIL] */
-        tmp = load_reg(r1);
-        cmp_u64c(s, tmp, (uint64_t)(uint32_t)i2);
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0xd: /* CFI R1,I2 [RIL] */
-        tmp32_1 = load_reg32(r1);
-        cmp_s32c(s, tmp32_1, i2);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0xf: /* CLFI R1,I2 [RIL] */
-        tmp32_1 = load_reg32(r1);
-        cmp_u32c(s, tmp32_1, i2);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    default:
-        LOG_DISAS("illegal c2 operation 0x%x\n", op);
-        gen_illegal_opcode(s);
-        break;
-    }
-}
-
 static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
 {
     TCGv_i64 tmp, tmp2, tmp3, tmp4;
@@ -3432,64 +2868,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
         tcg_temp_free_i32(tmp32_1);
         tcg_temp_free_i32(tmp32_2);
         break;
-    case 0x10: /* LPR    R1,R2     [RR] */
-        insn = ld_code2(env, s->pc);
-        decode_rr(s, insn, &r1, &r2);
-        tmp32_1 = load_reg32(r2);
-        set_cc_abs32(s, tmp32_1);
-        gen_helper_abs_i32(tmp32_1, tmp32_1);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x11: /* LNR    R1,R2     [RR] */
-        insn = ld_code2(env, s->pc);
-        decode_rr(s, insn, &r1, &r2);
-        tmp32_1 = load_reg32(r2);
-        set_cc_nabs32(s, tmp32_1);
-        gen_helper_nabs_i32(tmp32_1, tmp32_1);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x12: /* LTR    R1,R2     [RR] */
-        insn = ld_code2(env, s->pc);
-        decode_rr(s, insn, &r1, &r2);
-        tmp32_1 = load_reg32(r2);
-        if (r1 != r2) {
-            store_reg32(r1, tmp32_1);
-        }
-        set_cc_s32(s, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x13: /* LCR    R1,R2     [RR] */
-        insn = ld_code2(env, s->pc);
-        decode_rr(s, insn, &r1, &r2);
-        tmp32_1 = load_reg32(r2);
-        tcg_gen_neg_i32(tmp32_1, tmp32_1);
-        store_reg32(r1, tmp32_1);
-        set_cc_comp32(s, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x18: /* LR     R1,R2     [RR] */
-        insn = ld_code2(env, s->pc);
-        decode_rr(s, insn, &r1, &r2);
-        tmp32_1 = load_reg32(r2);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x15: /* CLR    R1,R2     [RR] */
-    case 0x19: /* CR     R1,R2     [RR] */
-        insn = ld_code2(env, s->pc);
-        decode_rr(s, insn, &r1, &r2);
-        tmp32_1 = load_reg32(r1);
-        tmp32_2 = load_reg32(r2);
-        if (opc == 0x15) {
-            cmp_u32(s, tmp32_1, tmp32_2);
-        } else {
-            cmp_s32(s, tmp32_1, tmp32_2);
-        }
-        tcg_temp_free_i32(tmp32_1);
-        tcg_temp_free_i32(tmp32_2);
-        break;
     case 0x1d: /* DR     R1,R2               [RR] */
         insn = ld_code2(env, s->pc);
         decode_rr(s, insn, &r1, &r2);
@@ -3539,28 +2917,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
         store_freg32(r1, tmp32_1);
         tcg_temp_free_i32(tmp32_1);
         break;
-    case 0x40: /* STH    R1,D2(X2,B2)     [RX] */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp2 = load_reg(r1);
-        tcg_gen_qemu_st16(tmp2, tmp, get_mem_index(s));
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x41:        /* la */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        store_reg(r1, tmp); /* FIXME: 31/24-bit addressing */
-        tcg_temp_free_i64(tmp);
-        break;
-    case 0x42: /* STC    R1,D2(X2,B2)     [RX] */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp2 = load_reg(r1);
-        tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0x43: /* IC     R1,D2(X2,B2)     [RX] */
         insn = ld_code4(env, s->pc);
         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
@@ -3614,29 +2970,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
         tcg_temp_free_i64(tmp);
         s->is_jmp = DISAS_TB_JUMP;
         break;
-    case 0x48: /* LH     R1,D2(X2,B2)     [RX] */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s));
-        store_reg32_i64(r1, tmp2);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x49: /* CH     R1,D2(X2,B2)     [RX] */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp32_1 = load_reg32(r1);
-        tmp32_2 = tcg_temp_new_i32();
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s));
-        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
-        cmp_s32(s, tmp32_1, tmp32_2);
-        tcg_temp_free_i32(tmp32_1);
-        tcg_temp_free_i32(tmp32_2);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0x4d: /* BAS    R1,D2(X2,B2)     [RX] */
         insn = ld_code4(env, s->pc);
         tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
@@ -3659,54 +2992,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
         tcg_temp_free_i64(tmp2);
         tcg_temp_free_i32(tmp32_1);
         break;
-    case 0x50: /* st r1, d2(x2, b2) */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp2 = load_reg(r1);
-        tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
-    case 0x55: /* CL     R1,D2(X2,B2)     [RX] */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp2 = tcg_temp_new_i64();
-        tmp32_1 = tcg_temp_new_i32();
-        tmp32_2 = load_reg32(r1);
-        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
-        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
-        cmp_u32(s, tmp32_2, tmp32_1);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i32(tmp32_1);
-        tcg_temp_free_i32(tmp32_2);
-        break;
-    case 0x58: /* l r1, d2(x2, b2) */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp2 = tcg_temp_new_i64();
-        tmp32_1 = tcg_temp_new_i32();
-        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
-        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
-        store_reg32(r1, tmp32_1);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i32(tmp32_1);
-        break;
-    case 0x59: /* C      R1,D2(X2,B2)     [RX] */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
-        tmp2 = tcg_temp_new_i64();
-        tmp32_1 = tcg_temp_new_i32();
-        tmp32_2 = load_reg32(r1);
-        tcg_gen_qemu_ld32s(tmp2, tmp, get_mem_index(s));
-        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
-        cmp_s32(s, tmp32_2, tmp32_1);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        tcg_temp_free_i32(tmp32_1);
-        tcg_temp_free_i32(tmp32_2);
-        break;
     case 0x5d: /* D      R1,D2(X2,B2)        [RX] */
         insn = ld_code4(env, s->pc);
         tmp3 = decode_rx(s, insn, &r1, &x2, &b2, &d2);
@@ -3962,15 +3247,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
         tcg_temp_free_i64(tmp);
         tcg_temp_free_i64(tmp2);
         break;
-    case 0x95: /* CLI    D1(B1),I2        [SI] */
-        insn = ld_code4(env, s->pc);
-        tmp = decode_si(s, insn, &i2, &b1, &d1);
-        tmp2 = tcg_temp_new_i64();
-        tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
-        cmp_u64c(s, tmp2, i2);
-        tcg_temp_free_i64(tmp);
-        tcg_temp_free_i64(tmp2);
-        break;
     case 0x9a: /* LAM      R1,R3,D2(B2)     [RS] */
         insn = ld_code4(env, s->pc);
         decode_rs(s, insn, &r1, &r3, &b2, &d2);
@@ -3995,13 +3271,6 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
         tcg_temp_free_i32(tmp32_1);
         tcg_temp_free_i32(tmp32_2);
         break;
-    case 0xa5:
-        insn = ld_code4(env, s->pc);
-        r1 = (insn >> 20) & 0xf;
-        op = (insn >> 16) & 0xf;
-        i2 = insn & 0xffff;
-        disas_a5(env, s, op, r1, i2);
-        break;
     case 0xa7:
         insn = ld_code4(env, s->pc);
         r1 = (insn >> 20) & 0xf;
@@ -4239,21 +3508,11 @@ static void disas_s390_insn(CPUS390XState *env, DisasContext *s)
         }
         break;
     case 0xc0:
-    case 0xc2:
         insn = ld_code6(env, s->pc);
         r1 = (insn >> 36) & 0xf;
         op = (insn >> 32) & 0xf;
         i2 = (int)insn;
-        switch (opc) {
-        case 0xc0:
-            disas_c0(env, s, op, r1, i2);
-            break;
-        case 0xc2:
-            disas_c2(env, s, op, r1, i2);
-            break;
-        default:
-            tcg_abort();
-        }
+        disas_c0(env, s, op, r1, i2);
         break;
     case 0xd2: /* MVC    D1(L,B1),D2(B2)         [SS] */
     case 0xd4: /* NC     D1(L,B1),D2(B2)         [SS] */
@@ -4612,6 +3871,12 @@ struct DisasInsn {
 /* The operations.  These perform the bulk of the work for any insn,
    usually after the operands have been loaded and output initialized.  */
 
+static ExitStatus op_abs(DisasContext *s, DisasOps *o)
+{
+    gen_helper_abs_i64(o->out, o->in2);
+    return NO_EXIT;
+}
+
 static ExitStatus op_add(DisasContext *s, DisasOps *o)
 {
     tcg_gen_add_i64(o->out, o->in1, o->in2);
@@ -4624,6 +3889,82 @@ static ExitStatus op_and(DisasContext *s, DisasOps *o)
     return NO_EXIT;
 }
 
+static ExitStatus op_andi(DisasContext *s, DisasOps *o)
+{
+    int shift = s->insn->data & 0xff;
+    int size = s->insn->data >> 8;
+    uint64_t mask = ((1ull << size) - 1) << shift;
+
+    assert(!o->g_in2);
+    tcg_gen_shli_i64(o->in2, o->in2, shift);
+    tcg_gen_ori_i64(o->in2, o->in2, ~mask);
+    tcg_gen_and_i64(o->out, o->in1, o->in2);
+
+    /* Produce the CC from only the bits manipulated.  */
+    tcg_gen_andi_i64(cc_dst, o->out, mask);
+    set_cc_nz_u64(s, cc_dst);
+    return NO_EXIT;
+}
+
+static ExitStatus op_insi(DisasContext *s, DisasOps *o)
+{
+    int shift = s->insn->data & 0xff;
+    int size = s->insn->data >> 8;
+    tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size);
+    return NO_EXIT;
+}
+
+static ExitStatus op_ld8s(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_ld8u(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_ld8u(o->out, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_ld16s(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_ld16s(o->out, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_ld16u(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_ld16u(o->out, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_ld32s(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_ld32u(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_ld64(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_mov2(DisasContext *s, DisasOps *o)
+{
+    o->out = o->in2;
+    o->g_out = o->g_in2;
+    TCGV_UNUSED_I64(o->in2);
+    o->g_in2 = false;
+    return NO_EXIT;
+}
+
 static ExitStatus op_mul(DisasContext *s, DisasOps *o)
 {
     tcg_gen_mul_i64(o->out, o->in1, o->in2);
@@ -4637,12 +3978,64 @@ static ExitStatus op_mul128(DisasContext *s, DisasOps *o)
     return NO_EXIT;
 }
 
+static ExitStatus op_nabs(DisasContext *s, DisasOps *o)
+{
+    gen_helper_nabs_i64(o->out, o->in2);
+    return NO_EXIT;
+}
+
+static ExitStatus op_neg(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_neg_i64(o->out, o->in2);
+    return NO_EXIT;
+}
+
 static ExitStatus op_or(DisasContext *s, DisasOps *o)
 {
     tcg_gen_or_i64(o->out, o->in1, o->in2);
     return NO_EXIT;
 }
 
+static ExitStatus op_ori(DisasContext *s, DisasOps *o)
+{
+    int shift = s->insn->data & 0xff;
+    int size = s->insn->data >> 8;
+    uint64_t mask = ((1ull << size) - 1) << shift;
+
+    assert(!o->g_in2);
+    tcg_gen_shli_i64(o->in2, o->in2, shift);
+    tcg_gen_or_i64(o->out, o->in1, o->in2);
+
+    /* Produce the CC from only the bits manipulated.  */
+    tcg_gen_andi_i64(cc_dst, o->out, mask);
+    set_cc_nz_u64(s, cc_dst);
+    return NO_EXIT;
+}
+
+static ExitStatus op_st8(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_st8(o->in1, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_st16(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_st16(o->in1, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_st32(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
+static ExitStatus op_st64(DisasContext *s, DisasOps *o)
+{
+    tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
+    return NO_EXIT;
+}
+
 static ExitStatus op_sub(DisasContext *s, DisasOps *o)
 {
     tcg_gen_sub_i64(o->out, o->in1, o->in2);
@@ -4655,11 +4048,37 @@ static ExitStatus op_xor(DisasContext *s, DisasOps *o)
     return NO_EXIT;
 }
 
+static ExitStatus op_xori(DisasContext *s, DisasOps *o)
+{
+    int shift = s->insn->data & 0xff;
+    int size = s->insn->data >> 8;
+    uint64_t mask = ((1ull << size) - 1) << shift;
+
+    assert(!o->g_in2);
+    tcg_gen_shli_i64(o->in2, o->in2, shift);
+    tcg_gen_xor_i64(o->out, o->in1, o->in2);
+
+    /* Produce the CC from only the bits manipulated.  */
+    tcg_gen_andi_i64(cc_dst, o->out, mask);
+    set_cc_nz_u64(s, cc_dst);
+    return NO_EXIT;
+}
+
 /* ====================================================================== */
 /* The "Cc OUTput" generators.  Given the generated output (and in some cases
    the original inputs), update the various cc data structures in order to
    be able to compute the new condition code.  */
 
+static void cout_abs32(DisasContext *s, DisasOps *o)
+{
+    gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
+}
+
+static void cout_abs64(DisasContext *s, DisasOps *o)
+{
+    gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
+}
+
 static void cout_adds32(DisasContext *s, DisasOps *o)
 {
     gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
@@ -4680,6 +4099,46 @@ static void cout_addu64(DisasContext *s, DisasOps *o)
     gen_op_update3_cc_i64(s, CC_OP_ADDU_64, o->in1, o->in2, o->out);
 }
 
+static void cout_cmps32(DisasContext *s, DisasOps *o)
+{
+    gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2);
+}
+
+static void cout_cmps64(DisasContext *s, DisasOps *o)
+{
+    gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2);
+}
+
+static void cout_cmpu32(DisasContext *s, DisasOps *o)
+{
+    gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2);
+}
+
+static void cout_cmpu64(DisasContext *s, DisasOps *o)
+{
+    gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2);
+}
+
+static void cout_nabs32(DisasContext *s, DisasOps *o)
+{
+    gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out);
+}
+
+static void cout_nabs64(DisasContext *s, DisasOps *o)
+{
+    gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out);
+}
+
+static void cout_neg32(DisasContext *s, DisasOps *o)
+{
+    gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out);
+}
+
+static void cout_neg64(DisasContext *s, DisasOps *o)
+{
+    gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out);
+}
+
 static void cout_nz32(DisasContext *s, DisasOps *o)
 {
     tcg_gen_ext32u_i64(cc_dst, o->out);
@@ -4691,6 +4150,16 @@ static void cout_nz64(DisasContext *s, DisasOps *o)
     gen_op_update1_cc_i64(s, CC_OP_NZ, o->out);
 }
 
+static void cout_s32(DisasContext *s, DisasOps *o)
+{
+    gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out);
+}
+
+static void cout_s64(DisasContext *s, DisasOps *o)
+{
+    gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out);
+}
+
 static void cout_subs32(DisasContext *s, DisasOps *o)
 {
     gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out);
@@ -4743,6 +4212,11 @@ static void prep_r1_P(DisasContext *s, DisasFields *f, DisasOps *o)
    generally handled by having a "prep" generator install the TCG global
    as the destination of the operation.  */
 
+static void wout_r1(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    store_reg(get_field(f, r1), o->out);
+}
+
 static void wout_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
 {
     store_reg32_i64(get_field(f, r1), o->out);
@@ -4757,6 +4231,13 @@ static void wout_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
     store_reg32_i64(r1, o->out);
 }
 
+static void wout_cond_r1r2_32(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    if (get_field(f, r1) != get_field(f, r2)) {
+        store_reg32_i64(get_field(f, r1), o->out);
+    }
+}
+
 static void wout_m1_32(DisasContext *s, DisasFields *f, DisasOps *o)
 {
     tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s));
@@ -4819,6 +4300,27 @@ static void in1_la1(DisasContext *s, DisasFields *f, DisasOps *o)
     o->addr1 = get_address(s, 0, get_field(f, b1), get_field(f, d1));
 }
 
+static void in1_m1_8u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    in1_la1(s, f, o);
+    o->in1 = tcg_temp_new_i64();
+    tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s));
+}
+
+static void in1_m1_16s(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    in1_la1(s, f, o);
+    o->in1 = tcg_temp_new_i64();
+    tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s));
+}
+
+static void in1_m1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    in1_la1(s, f, o);
+    o->in1 = tcg_temp_new_i64();
+    tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s));
+}
+
 static void in1_m1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
 {
     in1_la1(s, f, o);
@@ -4854,6 +4356,30 @@ static void in2_r2_o(DisasContext *s, DisasFields *f, DisasOps *o)
     o->g_in2 = true;
 }
 
+static void in2_r2_8s(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    o->in2 = tcg_temp_new_i64();
+    tcg_gen_ext8s_i64(o->in2, regs[get_field(f, r2)]);
+}
+
+static void in2_r2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    o->in2 = tcg_temp_new_i64();
+    tcg_gen_ext8u_i64(o->in2, regs[get_field(f, r2)]);
+}
+
+static void in2_r2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    o->in2 = tcg_temp_new_i64();
+    tcg_gen_ext16s_i64(o->in2, regs[get_field(f, r2)]);
+}
+
+static void in2_r2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    o->in2 = tcg_temp_new_i64();
+    tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r2)]);
+}
+
 static void in2_r3(DisasContext *s, DisasFields *f, DisasOps *o)
 {
     o->in2 = load_reg(get_field(f, r3));
@@ -4877,6 +4403,11 @@ static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o)
     o->in2 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
 }
 
+static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    o->in2 = tcg_const_i64(s->pc + (int64_t)get_field(f, i2) * 2);
+}
+
 static void in2_m2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
 {
     in2_a2(s, f, o);
@@ -4901,16 +4432,62 @@ static void in2_m2_64(DisasContext *s, DisasFields *f, DisasOps *o)
     tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
 }
 
+static void in2_mri2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    in2_ri2(s, f, o);
+    tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
+}
+
+static void in2_mri2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    in2_ri2(s, f, o);
+    tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
+}
+
+static void in2_mri2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    in2_ri2(s, f, o);
+    tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
+}
+
+static void in2_mri2_64(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    in2_ri2(s, f, o);
+    tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
+}
+
 static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o)
 {
     o->in2 = tcg_const_i64(get_field(f, i2));
 }
 
+static void in2_i2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    o->in2 = tcg_const_i64((uint8_t)get_field(f, i2));
+}
+
+static void in2_i2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    o->in2 = tcg_const_i64((uint16_t)get_field(f, i2));
+}
+
 static void in2_i2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
 {
     o->in2 = tcg_const_i64((uint32_t)get_field(f, i2));
 }
 
+static void in2_i2_16u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    uint64_t i2 = (uint16_t)get_field(f, i2);
+    o->in2 = tcg_const_i64(i2 << s->insn->data);
+}
+
+static void in2_i2_32u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
+{
+    uint64_t i2 = (uint32_t)get_field(f, i2);
+    o->in2 = tcg_const_i64(i2 << s->insn->data);
+}
+
 /* ====================================================================== */
 
 /* Find opc within the table of insns.  This is formulated as a switch