void _decode_opc(DisasContext * ctx)

{

#if 0

    fprintf(stderr, "Translating opcode 0x%04x\n", ctx->opcode);

#endif

    switch (ctx->opcode) {

    case 0x0019:		/* div0u */

	tcg_gen_andi_i32(cpu_sr, cpu_sr, ~(SR_M | SR_Q | SR_T));

	return;

    case 0x000b:		/* rts */

	CHECK_NOT_DELAY_SLOT

	tcg_gen_mov_i32(cpu_delayed_pc, cpu_pr);

	ctx->flags |= DELAY_SLOT;

	ctx->delayed_pc = (uint32_t) - 1;

	return;

    case 0x0028:		/* clrmac */

	tcg_gen_movi_i32(cpu_mach, 0);

	tcg_gen_movi_i32(cpu_macl, 0);

	return;

    case 0x0048:		/* clrs */

	tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_S);

	return;

    case 0x0008:		/* clrt */

	gen_clr_t();

	return;

    case 0x0038:		/* ldtlb */

#if defined(CONFIG_USER_ONLY)

	assert(0);		/* XXXXX */

#else

	tcg_gen_helper_0_0(helper_ldtlb);

#endif

	return;

    case 0x002b:		/* rte */

	CHECK_NOT_DELAY_SLOT

	tcg_gen_mov_i32(cpu_sr, cpu_ssr);

	tcg_gen_mov_i32(cpu_delayed_pc, cpu_spc);

	ctx->flags |= DELAY_SLOT;

	ctx->delayed_pc = (uint32_t) - 1;

	return;

    case 0x0058:		/* sets */

	tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_S);

	return;

    case 0x0018:		/* sett */

	gen_set_t();

	return;

    case 0xfbfd:		/* frchg */

	tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_FR);

	ctx->bstate = BS_STOP;

	return;

    case 0xf3fd:		/* fschg */

	tcg_gen_xori_i32(cpu_fpscr, cpu_fpscr, FPSCR_SZ);

	ctx->bstate = BS_STOP;

	return;

    case 0x0009:		/* nop */

	return;

    case 0x001b:		/* sleep */

	if (ctx->memidx) {

		tcg_gen_helper_0_1(helper_sleep, tcg_const_i32(ctx->pc + 2));

	} else {

		tcg_gen_helper_0_0(helper_raise_illegal_instruction);

		ctx->bstate = BS_EXCP;

	}

	return;

    }

    switch (ctx->opcode & 0xf000) {

    case 0x1000:		/* mov.l Rm,@(disp,Rn) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, REG(B11_8), B3_0 * 4);

	    tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x5000:		/* mov.l @(disp,Rm),Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 4);

	    tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0xe000:		/* mov #imm,Rn */

	tcg_gen_movi_i32(REG(B11_8), B7_0s);

	return;

    case 0x9000:		/* mov.w @(disp,PC),Rn */

	{

	    TCGv addr = tcg_const_i32(ctx->pc + 4 + B7_0 * 2);

	    tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0xd000:		/* mov.l @(disp,PC),Rn */

	{

	    TCGv addr = tcg_const_i32((ctx->pc + 4 + B7_0 * 4) & ~3);

	    tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x7000:		/* add #imm,Rn */

	tcg_gen_addi_i32(REG(B11_8), REG(B11_8), B7_0s);

	return;

    case 0xa000:		/* bra disp */

	CHECK_NOT_DELAY_SLOT

	ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;

	tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);

	ctx->flags |= DELAY_SLOT;

	return;

    case 0xb000:		/* bsr disp */

	CHECK_NOT_DELAY_SLOT

	tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);

	ctx->delayed_pc = ctx->pc + 4 + B11_0s * 2;

	tcg_gen_movi_i32(cpu_delayed_pc, ctx->delayed_pc);

	ctx->flags |= DELAY_SLOT;

	return;

    }

    switch (ctx->opcode & 0xf00f) {

    case 0x6003:		/* mov Rm,Rn */

	tcg_gen_mov_i32(REG(B11_8), REG(B7_4));

	return;

    case 0x2000:		/* mov.b Rm,@Rn */

	tcg_gen_qemu_st8(REG(B7_4), REG(B11_8), ctx->memidx);

	return;

    case 0x2001:		/* mov.w Rm,@Rn */

	tcg_gen_qemu_st16(REG(B7_4), REG(B11_8), ctx->memidx);

	return;

    case 0x2002:		/* mov.l Rm,@Rn */

	tcg_gen_qemu_st32(REG(B7_4), REG(B11_8), ctx->memidx);

	return;

    case 0x6000:		/* mov.b @Rm,Rn */

	tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);

	return;

    case 0x6001:		/* mov.w @Rm,Rn */

	tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);

	return;

    case 0x6002:		/* mov.l @Rm,Rn */

	tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);

	return;

    case 0x2004:		/* mov.b Rm,@-Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_subi_i32(addr, REG(B11_8), 1);

	    tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);	/* might cause re-execution */

	    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);	/* modify register status */

	    tcg_temp_free(addr);

	}

	return;

    case 0x2005:		/* mov.w Rm,@-Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_subi_i32(addr, REG(B11_8), 2);

	    tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);

	    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 2);

	    tcg_temp_free(addr);

	}

	return;

    case 0x2006:		/* mov.l Rm,@-Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_subi_i32(addr, REG(B11_8), 4);

	    tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);

	    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);

	}

	return;

    case 0x6004:		/* mov.b @Rm+,Rn */

	tcg_gen_qemu_ld8s(REG(B11_8), REG(B7_4), ctx->memidx);

	if ( B11_8 != B7_4 )

		tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 1);

	return;

    case 0x6005:		/* mov.w @Rm+,Rn */

	tcg_gen_qemu_ld16s(REG(B11_8), REG(B7_4), ctx->memidx);

	if ( B11_8 != B7_4 )

		tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);

	return;

    case 0x6006:		/* mov.l @Rm+,Rn */

	tcg_gen_qemu_ld32s(REG(B11_8), REG(B7_4), ctx->memidx);

	if ( B11_8 != B7_4 )

		tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);

	return;

    case 0x0004:		/* mov.b Rm,@(R0,Rn) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(B11_8), REG(0));

	    tcg_gen_qemu_st8(REG(B7_4), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x0005:		/* mov.w Rm,@(R0,Rn) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(B11_8), REG(0));

	    tcg_gen_qemu_st16(REG(B7_4), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x0006:		/* mov.l Rm,@(R0,Rn) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(B11_8), REG(0));

	    tcg_gen_qemu_st32(REG(B7_4), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x000c:		/* mov.b @(R0,Rm),Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(B7_4), REG(0));

	    tcg_gen_qemu_ld8s(REG(B11_8), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x000d:		/* mov.w @(R0,Rm),Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(B7_4), REG(0));

	    tcg_gen_qemu_ld16s(REG(B11_8), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x000e:		/* mov.l @(R0,Rm),Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(B7_4), REG(0));

	    tcg_gen_qemu_ld32s(REG(B11_8), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x6008:		/* swap.b Rm,Rn */

	{

	    TCGv high, low;

	    high = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_ext8u_i32(high, REG(B7_4));

	    tcg_gen_shli_i32(high, high, 8);

	    low = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_shri_i32(low, REG(B7_4), 8);

	    tcg_gen_ext8u_i32(low, low);

	    tcg_gen_or_i32(REG(B11_8), high, low);

	    tcg_temp_free(low);

	    tcg_temp_free(high);

	}

	return;

    case 0x6009:		/* swap.w Rm,Rn */

	{

	    TCGv high, low;

	    high = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_ext16u_i32(high, REG(B7_4));

	    tcg_gen_shli_i32(high, high, 16);

	    low = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_shri_i32(low, REG(B7_4), 16);

	    tcg_gen_ext16u_i32(low, low);

	    tcg_gen_or_i32(REG(B11_8), high, low);

	    tcg_temp_free(low);

	    tcg_temp_free(high);

	}

	return;

    case 0x200d:		/* xtrct Rm,Rn */

	{

	    TCGv high, low;

	    high = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_ext16u_i32(high, REG(B7_4));

	    tcg_gen_shli_i32(high, high, 16);

	    low = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_shri_i32(low, REG(B11_8), 16);

	    tcg_gen_ext16u_i32(low, low);

	    tcg_gen_or_i32(REG(B11_8), high, low);

	    tcg_temp_free(low);

	    tcg_temp_free(high);

	}

	return;

    case 0x300c:		/* add Rm,Rn */

	tcg_gen_add_i32(REG(B11_8), REG(B11_8), REG(B7_4));

	return;

    case 0x300e:		/* addc Rm,Rn */

	tcg_gen_helper_1_2(helper_addc, REG(B11_8), REG(B7_4), REG(B11_8));

	return;

    case 0x300f:		/* addv Rm,Rn */

	tcg_gen_helper_1_2(helper_addv, REG(B11_8), REG(B7_4), REG(B11_8));

	return;

    case 0x2009:		/* and Rm,Rn */

	tcg_gen_and_i32(REG(B11_8), REG(B11_8), REG(B7_4));

	return;

    case 0x3000:		/* cmp/eq Rm,Rn */

	gen_cmp(TCG_COND_EQ, REG(B7_4), REG(B11_8));

	return;

    case 0x3003:		/* cmp/ge Rm,Rn */

	gen_cmp(TCG_COND_GE, REG(B7_4), REG(B11_8));

	return;

    case 0x3007:		/* cmp/gt Rm,Rn */

	gen_cmp(TCG_COND_GT, REG(B7_4), REG(B11_8));

	return;

    case 0x3006:		/* cmp/hi Rm,Rn */

	gen_cmp(TCG_COND_GTU, REG(B7_4), REG(B11_8));

	return;

    case 0x3002:		/* cmp/hs Rm,Rn */

	gen_cmp(TCG_COND_GEU, REG(B7_4), REG(B11_8));

	return;

    case 0x200c:		/* cmp/str Rm,Rn */

	{

	    int label1 = gen_new_label();

	    int label2 = gen_new_label();

	    TCGv cmp1 = tcg_temp_local_new(TCG_TYPE_I32);

	    TCGv cmp2 = tcg_temp_local_new(TCG_TYPE_I32);

	    tcg_gen_xor_i32(cmp1, REG(B7_4), REG(B11_8));

	    tcg_gen_andi_i32(cmp2, cmp1, 0xff000000);

	    tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);

	    tcg_gen_andi_i32(cmp2, cmp1, 0x00ff0000);

	    tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);

	    tcg_gen_andi_i32(cmp2, cmp1, 0x0000ff00);

	    tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);

	    tcg_gen_andi_i32(cmp2, cmp1, 0x000000ff);

	    tcg_gen_brcondi_i32(TCG_COND_EQ, cmp2, 0, label1);

	    tcg_gen_andi_i32(cpu_sr, cpu_sr, ~SR_T);

	    tcg_gen_br(label2);

	    gen_set_label(label1);

	    tcg_gen_ori_i32(cpu_sr, cpu_sr, SR_T);

	    gen_set_label(label2);

	    tcg_temp_free(cmp2);

	    tcg_temp_free(cmp1);

	}

	return;

    case 0x2007:		/* div0s Rm,Rn */

	{

	    gen_copy_bit_i32(cpu_sr, 8, REG(B11_8), 31);	/* SR_Q */

	    gen_copy_bit_i32(cpu_sr, 9, REG(B7_4), 31);		/* SR_M */

	    TCGv val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_xor_i32(val, REG(B7_4), REG(B11_8));

	    gen_copy_bit_i32(cpu_sr, 0, val, 31);		/* SR_T */

	    tcg_temp_free(val);

	}

	return;

    case 0x3004:		/* div1 Rm,Rn */

	tcg_gen_helper_1_2(helper_div1, REG(B11_8), REG(B7_4), REG(B11_8));

	return;

    case 0x300d:		/* dmuls.l Rm,Rn */

	{

	    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);

	    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);

	    tcg_gen_ext_i32_i64(tmp1, REG(B7_4));

	    tcg_gen_ext_i32_i64(tmp2, REG(B11_8));

	    tcg_gen_mul_i64(tmp1, tmp1, tmp2);

	    tcg_gen_trunc_i64_i32(cpu_macl, tmp1);

	    tcg_gen_shri_i64(tmp1, tmp1, 32);

	    tcg_gen_trunc_i64_i32(cpu_mach, tmp1);

	    tcg_temp_free(tmp2);

	    tcg_temp_free(tmp1);

	}

	return;

    case 0x3005:		/* dmulu.l Rm,Rn */

	{

	    TCGv tmp1 = tcg_temp_new(TCG_TYPE_I64);

	    TCGv tmp2 = tcg_temp_new(TCG_TYPE_I64);

	    tcg_gen_extu_i32_i64(tmp1, REG(B7_4));

	    tcg_gen_extu_i32_i64(tmp2, REG(B11_8));

	    tcg_gen_mul_i64(tmp1, tmp1, tmp2);

	    tcg_gen_trunc_i64_i32(cpu_macl, tmp1);

	    tcg_gen_shri_i64(tmp1, tmp1, 32);

	    tcg_gen_trunc_i64_i32(cpu_mach, tmp1);

	    tcg_temp_free(tmp2);

	    tcg_temp_free(tmp1);

	}

	return;

    case 0x600e:		/* exts.b Rm,Rn */

	tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));

	return;

    case 0x600f:		/* exts.w Rm,Rn */

	tcg_gen_ext16s_i32(REG(B11_8), REG(B7_4));

	return;

    case 0x600c:		/* extu.b Rm,Rn */

	tcg_gen_ext8u_i32(REG(B11_8), REG(B7_4));

	return;

    case 0x600d:		/* extu.w Rm,Rn */

	tcg_gen_ext16u_i32(REG(B11_8), REG(B7_4));

	return;

    case 0x000f:		/* mac.l @Rm+,@Rn+ */

	{

	    TCGv arg0, arg1;

	    arg0 = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);

	    arg1 = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);

	    tcg_gen_helper_0_2(helper_macl, arg0, arg1);

	    tcg_temp_free(arg1);

	    tcg_temp_free(arg0);

	    tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);

	    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);

	}

	return;

    case 0x400f:		/* mac.w @Rm+,@Rn+ */

	{

	    TCGv arg0, arg1;

	    arg0 = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(arg0, REG(B7_4), ctx->memidx);

	    arg1 = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(arg1, REG(B11_8), ctx->memidx);

	    tcg_gen_helper_0_2(helper_macw, arg0, arg1);

	    tcg_temp_free(arg1);

	    tcg_temp_free(arg0);

	    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 2);

	    tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 2);

	}

	return;

    case 0x0007:		/* mul.l Rm,Rn */

	tcg_gen_mul_i32(cpu_macl, REG(B7_4), REG(B11_8));

	return;

    case 0x200f:		/* muls.w Rm,Rn */

	{

	    TCGv arg0, arg1;

	    arg0 = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_ext16s_i32(arg0, REG(B7_4));

	    arg1 = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_ext16s_i32(arg1, REG(B11_8));

	    tcg_gen_mul_i32(cpu_macl, arg0, arg1);

	    tcg_temp_free(arg1);

	    tcg_temp_free(arg0);

	}

	return;

    case 0x200e:		/* mulu.w Rm,Rn */

	{

	    TCGv arg0, arg1;

	    arg0 = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_ext16u_i32(arg0, REG(B7_4));

	    arg1 = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_ext16u_i32(arg1, REG(B11_8));

	    tcg_gen_mul_i32(cpu_macl, arg0, arg1);

	    tcg_temp_free(arg1);

	    tcg_temp_free(arg0);

	}

	return;

    case 0x600b:		/* neg Rm,Rn */

	tcg_gen_neg_i32(REG(B11_8), REG(B7_4));

	return;

    case 0x600a:		/* negc Rm,Rn */

	tcg_gen_helper_1_1(helper_negc, REG(B11_8), REG(B7_4));

	return;

    case 0x6007:		/* not Rm,Rn */

	tcg_gen_not_i32(REG(B11_8), REG(B7_4));

	return;

    case 0x200b:		/* or Rm,Rn */

	tcg_gen_or_i32(REG(B11_8), REG(B11_8), REG(B7_4));

	return;

    case 0x400c:		/* shad Rm,Rn */

	{

	    int label1 = gen_new_label();

	    int label2 = gen_new_label();

	    int label3 = gen_new_label();

	    int label4 = gen_new_label();

	    TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);

	    tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);

	    /* Rm positive, shift to the left */

	    tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);

	    tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);

	    tcg_gen_br(label4);

	    /* Rm negative, shift to the right */

	    gen_set_label(label1);

	    tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);

	    tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);

	    tcg_gen_not_i32(shift, REG(B7_4));

	    tcg_gen_andi_i32(shift, shift, 0x1f);

	    tcg_gen_addi_i32(shift, shift, 1);

	    tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift);

	    tcg_gen_br(label4);

	    /* Rm = -32 */

	    gen_set_label(label2);

	    tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3);

	    tcg_gen_movi_i32(REG(B11_8), 0);

	    tcg_gen_br(label4);

	    gen_set_label(label3);

	    tcg_gen_movi_i32(REG(B11_8), 0xffffffff);

	    gen_set_label(label4);

	    tcg_temp_free(shift);

	}

	return;

    case 0x400d:		/* shld Rm,Rn */

	{

	    int label1 = gen_new_label();

	    int label2 = gen_new_label();

	    int label3 = gen_new_label();

	    TCGv shift = tcg_temp_local_new(TCG_TYPE_I32);

	    tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1);

	    /* Rm positive, shift to the left */

	    tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);

	    tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift);

	    tcg_gen_br(label3);

	    /* Rm negative, shift to the right */

	    gen_set_label(label1);

	    tcg_gen_andi_i32(shift, REG(B7_4), 0x1f);

	    tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2);

	    tcg_gen_not_i32(shift, REG(B7_4));

	    tcg_gen_andi_i32(shift, shift, 0x1f);

	    tcg_gen_addi_i32(shift, shift, 1);

	    tcg_gen_shr_i32(REG(B11_8), REG(B11_8), shift);

	    tcg_gen_br(label3);

	    /* Rm = -32 */

	    gen_set_label(label2);

	    tcg_gen_movi_i32(REG(B11_8), 0);

	    gen_set_label(label3);

	    tcg_temp_free(shift);

	}

	return;

    case 0x3008:		/* sub Rm,Rn */

	tcg_gen_sub_i32(REG(B11_8), REG(B11_8), REG(B7_4));

	return;

    case 0x300a:		/* subc Rm,Rn */

	tcg_gen_helper_1_2(helper_subc, REG(B11_8), REG(B7_4), REG(B11_8));

	return;

    case 0x300b:		/* subv Rm,Rn */

	tcg_gen_helper_1_2(helper_subv, REG(B11_8), REG(B7_4), REG(B11_8));

	return;

    case 0x2008:		/* tst Rm,Rn */

	{

	    TCGv val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_and_i32(val, REG(B7_4), REG(B11_8));

	    gen_cmp_imm(TCG_COND_EQ, val, 0);

	    tcg_temp_free(val);

	}

	return;

    case 0x200a:		/* xor Rm,Rn */

	tcg_gen_xor_i32(REG(B11_8), REG(B11_8), REG(B7_4));

	return;

    case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */

	if (ctx->fpscr & FPSCR_SZ) {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I64);

	    gen_load_fpr64(fp, XREG(B7_4));

	    gen_store_fpr64(fp, XREG(B11_8));

	    tcg_temp_free(fp);

	} else {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    gen_load_fpr32(fp, FREG(B7_4));

	    gen_store_fpr32(fp, FREG(B11_8));

	    tcg_temp_free(fp);

	}

	return;

    case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */

	if (ctx->fpscr & FPSCR_SZ) {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I64);

	    gen_load_fpr64(fp, XREG(B7_4));

	    tcg_gen_qemu_st64(fp, REG(B11_8), ctx->memidx);

	    tcg_temp_free(fp);

	} else {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    gen_load_fpr32(fp, FREG(B7_4));

	    tcg_gen_qemu_st32(fp, REG(B11_8), ctx->memidx);

	    tcg_temp_free(fp);

	}

	return;

    case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */

	if (ctx->fpscr & FPSCR_SZ) {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I64);

	    tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);

	    gen_store_fpr64(fp, XREG(B11_8));

	    tcg_temp_free(fp);

	} else {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);

	    gen_store_fpr32(fp, FREG(B11_8));

	    tcg_temp_free(fp);

	}

	return;

    case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */

	if (ctx->fpscr & FPSCR_SZ) {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I64);

	    tcg_gen_qemu_ld64(fp, REG(B7_4), ctx->memidx);

	    gen_store_fpr64(fp, XREG(B11_8));

	    tcg_temp_free(fp);

	    tcg_gen_addi_i32(REG(B7_4),REG(B7_4), 8);

	} else {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32u(fp, REG(B7_4), ctx->memidx);

	    gen_store_fpr32(fp, FREG(B11_8));

	    tcg_temp_free(fp);

	    tcg_gen_addi_i32(REG(B7_4), REG(B7_4), 4);

	}

	return;

    case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */

	if (ctx->fpscr & FPSCR_SZ) {

	    TCGv addr, fp;

	    addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_subi_i32(addr, REG(B11_8), 8);

	    fp = tcg_temp_new(TCG_TYPE_I64);

	    gen_load_fpr64(fp, XREG(B7_4));

	    tcg_gen_qemu_st64(fp, addr, ctx->memidx);

	    tcg_temp_free(fp);

	    tcg_temp_free(addr);

	    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 8);

	} else {

	    TCGv addr, fp;

	    addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_subi_i32(addr, REG(B11_8), 4);

	    fp = tcg_temp_new(TCG_TYPE_I32);

	    gen_load_fpr32(fp, FREG(B7_4));

	    tcg_gen_qemu_st32(fp, addr, ctx->memidx);

	    tcg_temp_free(fp);

	    tcg_temp_free(addr);

	    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);

	}

	return;

    case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(B7_4), REG(0));

	    if (ctx->fpscr & FPSCR_SZ) {

		TCGv fp = tcg_temp_new(TCG_TYPE_I64);

		tcg_gen_qemu_ld64(fp, addr, ctx->memidx);

		gen_store_fpr64(fp, XREG(B11_8));

		tcg_temp_free(fp);

	    } else {

		TCGv fp = tcg_temp_new(TCG_TYPE_I32);

		tcg_gen_qemu_ld32u(fp, addr, ctx->memidx);

		gen_store_fpr32(fp, FREG(B11_8));

		tcg_temp_free(fp);

	    }

	    tcg_temp_free(addr);

	}

	return;

    case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(B11_8), REG(0));

	    if (ctx->fpscr & FPSCR_SZ) {

		TCGv fp = tcg_temp_new(TCG_TYPE_I64);

		gen_load_fpr64(fp, XREG(B7_4));

		tcg_gen_qemu_st64(fp, addr, ctx->memidx);

		tcg_temp_free(fp);

	    } else {

		TCGv fp = tcg_temp_new(TCG_TYPE_I32);

		gen_load_fpr32(fp, FREG(B7_4));

		tcg_gen_qemu_st32(fp, addr, ctx->memidx);

		tcg_temp_free(fp);

	    }

	    tcg_temp_free(addr);

	}

	return;

    case 0xf000: /* fadd Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */

    case 0xf001: /* fsub Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */

    case 0xf002: /* fmul Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */

    case 0xf003: /* fdiv Rm,Rn - FPSCR: R[PR,Enable.O/U/I]/W[Cause,Flag] */

    case 0xf004: /* fcmp/eq Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */

    case 0xf005: /* fcmp/gt Rm,Rn - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */

	{

	    TCGv fp0, fp1;

	    if (ctx->fpscr & FPSCR_PR) {

		if (ctx->opcode & 0x0110)

		    break; /* illegal instruction */

		fp0 = tcg_temp_new(TCG_TYPE_I64);

		fp1 = tcg_temp_new(TCG_TYPE_I64);

		gen_load_fpr64(fp0, DREG(B11_8));

		gen_load_fpr64(fp1, DREG(B7_4));

	    }

	    else {

		fp0 = tcg_temp_new(TCG_TYPE_I32);

		fp1 = tcg_temp_new(TCG_TYPE_I32);

		gen_load_fpr32(fp0, FREG(B11_8));

		gen_load_fpr32(fp1, FREG(B7_4));

	    }

	    switch (ctx->opcode & 0xf00f) {

	    case 0xf000:		/* fadd Rm,Rn */

		if (ctx->fpscr & FPSCR_PR)

		    tcg_gen_helper_1_2(helper_fadd_DT, fp0, fp0, fp1);

		else

		    tcg_gen_helper_1_2(helper_fadd_FT, fp0, fp0, fp1);

		break;

	    case 0xf001:		/* fsub Rm,Rn */

		if (ctx->fpscr & FPSCR_PR)

		    tcg_gen_helper_1_2(helper_fsub_DT, fp0, fp0, fp1);

		else

		    tcg_gen_helper_1_2(helper_fsub_FT, fp0, fp0, fp1);

		break;

	    case 0xf002:		/* fmul Rm,Rn */

		if (ctx->fpscr & FPSCR_PR)

		    tcg_gen_helper_1_2(helper_fmul_DT, fp0, fp0, fp1);

		else

		    tcg_gen_helper_1_2(helper_fmul_FT, fp0, fp0, fp1);

		break;

	    case 0xf003:		/* fdiv Rm,Rn */

		if (ctx->fpscr & FPSCR_PR)

		    tcg_gen_helper_1_2(helper_fdiv_DT, fp0, fp0, fp1);

		else

		    tcg_gen_helper_1_2(helper_fdiv_FT, fp0, fp0, fp1);

		break;

	    case 0xf004:		/* fcmp/eq Rm,Rn */

		if (ctx->fpscr & FPSCR_PR)

		    tcg_gen_helper_0_2(helper_fcmp_eq_DT, fp0, fp1);

		else

		    tcg_gen_helper_0_2(helper_fcmp_eq_FT, fp0, fp1);

		return;

	    case 0xf005:		/* fcmp/gt Rm,Rn */

		if (ctx->fpscr & FPSCR_PR)

		    tcg_gen_helper_0_2(helper_fcmp_gt_DT, fp0, fp1);

		else

		    tcg_gen_helper_0_2(helper_fcmp_gt_FT, fp0, fp1);

		return;

	    }

	    if (ctx->fpscr & FPSCR_PR) {

		gen_store_fpr64(fp0, DREG(B11_8));

	    }

	    else {

		gen_store_fpr32(fp0, FREG(B11_8));

	    }

	    tcg_temp_free(fp1);

	    tcg_temp_free(fp0);

	}

	return;

    }

    switch (ctx->opcode & 0xff00) {

    case 0xc900:		/* and #imm,R0 */

	tcg_gen_andi_i32(REG(0), REG(0), B7_0);

	return;

    case 0xcd00:		/* and.b #imm,@(R0,GBR) */

	{

	    TCGv addr, val;

	    addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(0), cpu_gbr);

	    val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld8u(val, addr, ctx->memidx);

	    tcg_gen_andi_i32(val, val, B7_0);

	    tcg_gen_qemu_st8(val, addr, ctx->memidx);

	    tcg_temp_free(val);

	    tcg_temp_free(addr);

	}

	return;

    case 0x8b00:		/* bf label */

	CHECK_NOT_DELAY_SLOT

	    gen_conditional_jump(ctx, ctx->pc + 2,

				 ctx->pc + 4 + B7_0s * 2);

	ctx->bstate = BS_BRANCH;

	return;

    case 0x8f00:		/* bf/s label */

	CHECK_NOT_DELAY_SLOT

	gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 0);

	ctx->flags |= DELAY_SLOT_CONDITIONAL;

	return;

    case 0x8900:		/* bt label */

	CHECK_NOT_DELAY_SLOT

	    gen_conditional_jump(ctx, ctx->pc + 4 + B7_0s * 2,

				 ctx->pc + 2);

	ctx->bstate = BS_BRANCH;

	return;

    case 0x8d00:		/* bt/s label */

	CHECK_NOT_DELAY_SLOT

	gen_branch_slot(ctx->delayed_pc = ctx->pc + 4 + B7_0s * 2, 1);

	ctx->flags |= DELAY_SLOT_CONDITIONAL;

	return;

    case 0x8800:		/* cmp/eq #imm,R0 */

	gen_cmp_imm(TCG_COND_EQ, REG(0), B7_0s);

	return;

    case 0xc400:		/* mov.b @(disp,GBR),R0 */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, cpu_gbr, B7_0);

	    tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0xc500:		/* mov.w @(disp,GBR),R0 */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);

	    tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0xc600:		/* mov.l @(disp,GBR),R0 */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);

	    tcg_gen_qemu_ld32s(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0xc000:		/* mov.b R0,@(disp,GBR) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, cpu_gbr, B7_0);

	    tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0xc100:		/* mov.w R0,@(disp,GBR) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 2);

	    tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0xc200:		/* mov.l R0,@(disp,GBR) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, cpu_gbr, B7_0 * 4);

	    tcg_gen_qemu_st32(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x8000:		/* mov.b R0,@(disp,Rn) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, REG(B7_4), B3_0);

	    tcg_gen_qemu_st8(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x8100:		/* mov.w R0,@(disp,Rn) */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);

	    tcg_gen_qemu_st16(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x8400:		/* mov.b @(disp,Rn),R0 */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, REG(B7_4), B3_0);

	    tcg_gen_qemu_ld8s(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0x8500:		/* mov.w @(disp,Rn),R0 */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_addi_i32(addr, REG(B7_4), B3_0 * 2);

	    tcg_gen_qemu_ld16s(REG(0), addr, ctx->memidx);

	    tcg_temp_free(addr);

	}

	return;

    case 0xc700:		/* mova @(disp,PC),R0 */

	tcg_gen_movi_i32(REG(0), ((ctx->pc & 0xfffffffc) + 4 + B7_0 * 4) & ~3);

	return;

    case 0xcb00:		/* or #imm,R0 */

	tcg_gen_ori_i32(REG(0), REG(0), B7_0);

	return;

    case 0xcf00:		/* or.b #imm,@(R0,GBR) */

	{

	    TCGv addr, val;

	    addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(0), cpu_gbr);

	    val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld8u(val, addr, ctx->memidx);

	    tcg_gen_ori_i32(val, val, B7_0);

	    tcg_gen_qemu_st8(val, addr, ctx->memidx);

	    tcg_temp_free(val);

	    tcg_temp_free(addr);

	}

	return;

    case 0xc300:		/* trapa #imm */

	{

	    TCGv imm;

	    CHECK_NOT_DELAY_SLOT

	    tcg_gen_movi_i32(cpu_pc, ctx->pc);

	    imm = tcg_const_i32(B7_0);

	    tcg_gen_helper_0_1(helper_trapa, imm);

	    tcg_temp_free(imm);

	    ctx->bstate = BS_BRANCH;

	}

	return;

    case 0xc800:		/* tst #imm,R0 */

	{

	    TCGv val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_andi_i32(val, REG(0), B7_0);

	    gen_cmp_imm(TCG_COND_EQ, val, 0);

	    tcg_temp_free(val);

	}

	return;

    case 0xcc00:		/* tst.b #imm,@(R0,GBR) */

	{

	    TCGv val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(val, REG(0), cpu_gbr);

	    tcg_gen_qemu_ld8u(val, val, ctx->memidx);

	    tcg_gen_andi_i32(val, val, B7_0);

	    gen_cmp_imm(TCG_COND_EQ, val, 0);

	    tcg_temp_free(val);

	}

	return;

    case 0xca00:		/* xor #imm,R0 */

	tcg_gen_xori_i32(REG(0), REG(0), B7_0);

	return;

    case 0xce00:		/* xor.b #imm,@(R0,GBR) */

	{

	    TCGv addr, val;

	    addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_add_i32(addr, REG(0), cpu_gbr);

	    val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld8u(val, addr, ctx->memidx);

	    tcg_gen_xori_i32(val, val, B7_0);

	    tcg_gen_qemu_st8(val, addr, ctx->memidx);

	    tcg_temp_free(val);

	    tcg_temp_free(addr);

	}

	return;

    }

    switch (ctx->opcode & 0xf08f) {

    case 0x408e:		/* ldc Rm,Rn_BANK */

	tcg_gen_mov_i32(ALTREG(B6_4), REG(B11_8));

	return;

    case 0x4087:		/* ldc.l @Rm+,Rn_BANK */

	tcg_gen_qemu_ld32s(ALTREG(B6_4), REG(B11_8), ctx->memidx);

	tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);

	return;

    case 0x0082:		/* stc Rm_BANK,Rn */

	tcg_gen_mov_i32(REG(B11_8), ALTREG(B6_4));

	return;

    case 0x4083:		/* stc.l Rm_BANK,@-Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_subi_i32(addr, REG(B11_8), 4);

	    tcg_gen_qemu_st32(ALTREG(B6_4), addr, ctx->memidx);

	    tcg_temp_free(addr);

	    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);

	}

	return;

    }

    switch (ctx->opcode & 0xf0ff) {

    case 0x0023:		/* braf Rn */

	CHECK_NOT_DELAY_SLOT

	tcg_gen_addi_i32(cpu_delayed_pc, REG(B11_8), ctx->pc + 4);

	ctx->flags |= DELAY_SLOT;

	ctx->delayed_pc = (uint32_t) - 1;

	return;

    case 0x0003:		/* bsrf Rn */

	CHECK_NOT_DELAY_SLOT

	tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);

	tcg_gen_add_i32(cpu_delayed_pc, REG(B11_8), cpu_pr);

	ctx->flags |= DELAY_SLOT;

	ctx->delayed_pc = (uint32_t) - 1;

	return;

    case 0x4015:		/* cmp/pl Rn */

	gen_cmp_imm(TCG_COND_GT, REG(B11_8), 0);

	return;

    case 0x4011:		/* cmp/pz Rn */

	gen_cmp_imm(TCG_COND_GE, REG(B11_8), 0);

	return;

    case 0x4010:		/* dt Rn */

	tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 1);

	gen_cmp_imm(TCG_COND_EQ, REG(B11_8), 0);

	return;

    case 0x402b:		/* jmp @Rn */

	CHECK_NOT_DELAY_SLOT

	tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));

	ctx->flags |= DELAY_SLOT;

	ctx->delayed_pc = (uint32_t) - 1;

	return;

    case 0x400b:		/* jsr @Rn */

	CHECK_NOT_DELAY_SLOT

	tcg_gen_movi_i32(cpu_pr, ctx->pc + 4);

	tcg_gen_mov_i32(cpu_delayed_pc, REG(B11_8));

	ctx->flags |= DELAY_SLOT;

	ctx->delayed_pc = (uint32_t) - 1;

	return;

    case 0x400e:		/* lds Rm,SR */

	tcg_gen_andi_i32(cpu_sr, REG(B11_8), 0x700083f3);

	ctx->bstate = BS_STOP;

	return;

    case 0x4007:		/* lds.l @Rm+,SR */

	{

	    TCGv val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(val, REG(B11_8), ctx->memidx);

	    tcg_gen_andi_i32(cpu_sr, val, 0x700083f3);

	    tcg_temp_free(val);

	    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);

	    ctx->bstate = BS_STOP;

	}

	return;

    case 0x0002:		/* sts SR,Rn */

	tcg_gen_mov_i32(REG(B11_8), cpu_sr);

	return;

    case 0x4003:		/* sts SR,@-Rn */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_subi_i32(addr, REG(B11_8), 4);

	    tcg_gen_qemu_st32(cpu_sr, addr, ctx->memidx);

	    tcg_temp_free(addr);

	    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);

	}

	return;

#define LDST(reg,ldnum,ldpnum,stnum,stpnum)			\

  case ldnum:							\

    tcg_gen_mov_i32 (cpu_##reg, REG(B11_8));			\

    return;							\

  case ldpnum:							\

    tcg_gen_qemu_ld32s (cpu_##reg, REG(B11_8), ctx->memidx);	\

    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);		\

    return;							\

  case stnum:							\

    tcg_gen_mov_i32 (REG(B11_8), cpu_##reg);			\

    return;							\

  case stpnum:							\

    {								\

	TCGv addr = tcg_temp_new(TCG_TYPE_I32);			\

	tcg_gen_subi_i32(addr, REG(B11_8), 4);			\

	tcg_gen_qemu_st32 (cpu_##reg, addr, ctx->memidx);	\

	tcg_temp_free(addr);					\

	tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);		\

    }								\

    return;

	LDST(gbr,  0x401e, 0x4017, 0x0012, 0x4013)

	LDST(vbr,  0x402e, 0x4027, 0x0022, 0x4023)

	LDST(ssr,  0x403e, 0x4037, 0x0032, 0x4033)

	LDST(spc,  0x404e, 0x4047, 0x0042, 0x4043)

	LDST(dbr,  0x40fa, 0x40f6, 0x00fa, 0x40f2)

	LDST(mach, 0x400a, 0x4006, 0x000a, 0x4002)

	LDST(macl, 0x401a, 0x4016, 0x001a, 0x4012)

	LDST(pr,   0x402a, 0x4026, 0x002a, 0x4022)

	LDST(fpul, 0x405a, 0x4056, 0x005a, 0x4052)

    case 0x406a:		/* lds Rm,FPSCR */

	tcg_gen_helper_0_1(helper_ld_fpscr, REG(B11_8));

	ctx->bstate = BS_STOP;

	return;

    case 0x4066:		/* lds.l @Rm+,FPSCR */

	{

	    TCGv addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(addr, REG(B11_8), ctx->memidx);

	    tcg_gen_addi_i32(REG(B11_8), REG(B11_8), 4);

	    tcg_gen_helper_0_1(helper_ld_fpscr, addr);

	    tcg_temp_free(addr);

	    ctx->bstate = BS_STOP;

	}

	return;

    case 0x006a:		/* sts FPSCR,Rn */

	tcg_gen_andi_i32(REG(B11_8), cpu_fpscr, 0x003fffff);

	return;

    case 0x4062:		/* sts FPSCR,@-Rn */

	{

	    TCGv addr, val;

	    val = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_andi_i32(val, cpu_fpscr, 0x003fffff);

	    addr = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_subi_i32(addr, REG(B11_8), 4);

	    tcg_gen_qemu_st32(val, addr, ctx->memidx);

	    tcg_temp_free(addr);

	    tcg_temp_free(val);

	    tcg_gen_subi_i32(REG(B11_8), REG(B11_8), 4);

	}

	return;

    case 0x00c3:		/* movca.l R0,@Rm */

	tcg_gen_qemu_st32(REG(0), REG(B11_8), ctx->memidx);

	return;

    case 0x0029:		/* movt Rn */

	tcg_gen_andi_i32(REG(B11_8), cpu_sr, SR_T);

	return;

    case 0x0093:		/* ocbi @Rn */

	{

	    TCGv dummy = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);

	    tcg_temp_free(dummy);

	}

	return;

    case 0x00a3:		/* ocbp @Rn */

	{

	    TCGv dummy = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);

	    tcg_temp_free(dummy);

	}

	return;

    case 0x00b3:		/* ocbwb @Rn */

	{

	    TCGv dummy = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);

	    tcg_temp_free(dummy);

	}

	return;

    case 0x0083:		/* pref @Rn */

	return;

    case 0x4024:		/* rotcl Rn */

	{

	    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_mov_i32(tmp, cpu_sr);

	    gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);

	    tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);

	    gen_copy_bit_i32(REG(B11_8), 0, tmp, 0);

	    tcg_temp_free(tmp);

	}

	return;

    case 0x4025:		/* rotcr Rn */

	{

	    TCGv tmp = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_mov_i32(tmp, cpu_sr);

	    gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);

	    tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);

	    gen_copy_bit_i32(REG(B11_8), 31, tmp, 0);

	    tcg_temp_free(tmp);

	}

	return;

    case 0x4004:		/* rotl Rn */

	gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);

	tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);

	gen_copy_bit_i32(REG(B11_8), 0, cpu_sr, 0);

	return;

    case 0x4005:		/* rotr Rn */

	gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);

	tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);

	gen_copy_bit_i32(REG(B11_8), 31, cpu_sr, 0);

	return;

    case 0x4000:		/* shll Rn */

    case 0x4020:		/* shal Rn */

	gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 31);

	tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 1);

	return;

    case 0x4021:		/* shar Rn */

	gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);

	tcg_gen_sari_i32(REG(B11_8), REG(B11_8), 1);

	return;

    case 0x4001:		/* shlr Rn */

	gen_copy_bit_i32(cpu_sr, 0, REG(B11_8), 0);

	tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 1);

	return;

    case 0x4008:		/* shll2 Rn */

	tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 2);

	return;

    case 0x4018:		/* shll8 Rn */

	tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 8);

	return;

    case 0x4028:		/* shll16 Rn */

	tcg_gen_shli_i32(REG(B11_8), REG(B11_8), 16);

	return;

    case 0x4009:		/* shlr2 Rn */

	tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 2);

	return;

    case 0x4019:		/* shlr8 Rn */

	tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 8);

	return;

    case 0x4029:		/* shlr16 Rn */

	tcg_gen_shri_i32(REG(B11_8), REG(B11_8), 16);

	return;

    case 0x401b:		/* tas.b @Rn */

	{

	    TCGv addr, val;

	    addr = tcg_temp_local_new(TCG_TYPE_I32);

	    tcg_gen_mov_i32(addr, REG(B11_8));

	    val = tcg_temp_local_new(TCG_TYPE_I32);

	    tcg_gen_qemu_ld8u(val, addr, ctx->memidx);

	    gen_cmp_imm(TCG_COND_EQ, val, 0);

	    tcg_gen_ori_i32(val, val, 0x80);

	    tcg_gen_qemu_st8(val, addr, ctx->memidx);

	    tcg_temp_free(val);

	    tcg_temp_free(addr);

	}

	return;

    case 0xf00d: /* fsts FPUL,FRn - FPSCR: Nothing */

	{

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_mov_i32(fp, cpu_fpul);

	    gen_store_fpr32(fp, FREG(B11_8));

	    tcg_temp_free(fp);

	}

	return;

    case 0xf01d: /* flds FRm,FPUL - FPSCR: Nothing */

	{

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    gen_load_fpr32(fp, FREG(B11_8));

	    tcg_gen_mov_i32(cpu_fpul, fp);

	    tcg_temp_free(fp);

	}

	return;

    case 0xf02d: /* float FPUL,FRn/DRn - FPSCR: R[PR,Enable.I]/W[Cause,Flag] */

	if (ctx->fpscr & FPSCR_PR) {

	    TCGv fp;

	    if (ctx->opcode & 0x0100)

		break; /* illegal instruction */

	    fp = tcg_temp_new(TCG_TYPE_I64);

	    tcg_gen_helper_1_1(helper_float_DT, fp, cpu_fpul);

	    gen_store_fpr64(fp, DREG(B11_8));

	    tcg_temp_free(fp);

	}

	else {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    tcg_gen_helper_1_1(helper_float_FT, fp, cpu_fpul);

	    gen_store_fpr32(fp, FREG(B11_8));

	    tcg_temp_free(fp);

	}

	return;

    case 0xf03d: /* ftrc FRm/DRm,FPUL - FPSCR: R[PR,Enable.V]/W[Cause,Flag] */

	if (ctx->fpscr & FPSCR_PR) {

	    TCGv fp;

	    if (ctx->opcode & 0x0100)

		break; /* illegal instruction */

	    fp = tcg_temp_new(TCG_TYPE_I64);

	    gen_load_fpr64(fp, DREG(B11_8));

	    tcg_gen_helper_1_1(helper_ftrc_DT, cpu_fpul, fp);

	    tcg_temp_free(fp);

	}

	else {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    gen_load_fpr32(fp, FREG(B11_8));

	    tcg_gen_helper_1_1(helper_ftrc_FT, cpu_fpul, fp);

	    tcg_temp_free(fp);

	}

	return;

    case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */

	{

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    gen_load_fpr32(fp, FREG(B11_8));

	    tcg_gen_helper_1_1(helper_fneg_T, fp, fp);

	    gen_store_fpr32(fp, FREG(B11_8));

	    tcg_temp_free(fp);

	}

	return;

    case 0xf05d: /* fabs FRn/DRn */

	if (ctx->fpscr & FPSCR_PR) {

	    if (ctx->opcode & 0x0100)

		break; /* illegal instruction */

	    TCGv fp = tcg_temp_new(TCG_TYPE_I64);

	    gen_load_fpr64(fp, DREG(B11_8));

	    tcg_gen_helper_1_1(helper_fabs_DT, fp, fp);

	    gen_store_fpr64(fp, DREG(B11_8));

	    tcg_temp_free(fp);

	} else {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    gen_load_fpr32(fp, FREG(B11_8));

	    tcg_gen_helper_1_1(helper_fabs_FT, fp, fp);

	    gen_store_fpr32(fp, FREG(B11_8));

	    tcg_temp_free(fp);

	}

	return;

    case 0xf06d: /* fsqrt FRn */

	if (ctx->fpscr & FPSCR_PR) {

	    if (ctx->opcode & 0x0100)

		break; /* illegal instruction */

	    TCGv fp = tcg_temp_new(TCG_TYPE_I64);

	    gen_load_fpr64(fp, DREG(B11_8));

	    tcg_gen_helper_1_1(helper_fsqrt_DT, fp, fp);

	    gen_store_fpr64(fp, DREG(B11_8));

	    tcg_temp_free(fp);

	} else {

	    TCGv fp = tcg_temp_new(TCG_TYPE_I32);

	    gen_load_fpr32(fp, FREG(B11_8));

	    tcg_gen_helper_1_1(helper_fsqrt_FT, fp, fp);

	    gen_store_fpr32(fp, FREG(B11_8));

	    tcg_temp_free(fp);

	}

	return;

    case 0xf07d: /* fsrra FRn */

	break;

    case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */

	if (!(ctx->fpscr & FPSCR_PR)) {

	    TCGv val = tcg_const_i32(0);

	    gen_load_fpr32(val, FREG(B11_8));

	    tcg_temp_free(val);

	    return;

	}

	break;

    case 0xf09d: /* fldi1 FRn - FPSCR: R[PR] */

	if (!(ctx->fpscr & FPSCR_PR)) {

	    TCGv val = tcg_const_i32(0x3f800000);

	    gen_load_fpr32(val, FREG(B11_8));

	    tcg_temp_free(val);

	    return;

	}

	break;

    case 0xf0ad: /* fcnvsd FPUL,DRn */

	{

	    TCGv fp = tcg_temp_new(TCG_TYPE_I64);

	    tcg_gen_helper_1_1(helper_fcnvsd_FT_DT, fp, cpu_fpul);

	    gen_store_fpr64(fp, DREG(B11_8));

	    tcg_temp_free(fp);

	}

	return;

    case 0xf0bd: /* fcnvds DRn,FPUL */

	{

	    TCGv fp = tcg_temp_new(TCG_TYPE_I64);

	    gen_load_fpr64(fp, DREG(B11_8));

	    tcg_gen_helper_1_1(helper_fcnvds_DT_FT, cpu_fpul, fp);

	    tcg_temp_free(fp);

	}

	return;

    }

    fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n",

	    ctx->opcode, ctx->pc);

    tcg_gen_helper_0_0(helper_raise_illegal_instruction);

    ctx->bstate = BS_EXCP;

}


static void a9_scu_write(void *opaque, target_phys_addr_t offset,

                         uint64_t value, unsigned size)

{

    a9mp_priv_state *s = (a9mp_priv_state *)opaque;

    uint32_t mask;

    uint32_t shift;

    switch (size) {

    case 1:

        mask = 0xff;

        break;

    case 2:

        mask = 0xffff;

        break;

    case 4:

        mask = 0xffffffff;

        break;

    default:

        fprintf(stderr, "Invalid size %u in write to a9 scu register %x\n",

                size, (unsigned)offset);

        return;

    }

    switch (offset) {

    case 0x00: /* Control */

        s->scu_control = value & 1;

        break;

    case 0x4: /* Configuration: RO */

        break;

    case 0x08: case 0x09: case 0x0A: case 0x0B: /* Power Control */

        shift = (offset - 0x8) * 8;

        s->scu_status &= ~(mask << shift);

        s->scu_status |= ((value & mask) << shift);

        break;

    case 0x0c: /* Invalidate All Registers In Secure State */

        /* no-op as we do not implement caches */

        break;

    case 0x40: /* Filtering Start Address Register */

    case 0x44: /* Filtering End Address Register */

        /* RAZ/WI, like an implementation with only one AXI master */

        break;

    case 0x50: /* SCU Access Control Register */

    case 0x54: /* SCU Non-secure Access Control Register */

        /* unimplemented, fall through */

    default:

        break;

    }

}


static void s390_virtio_net_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    VirtIOS390DeviceClass *k = VIRTIO_S390_DEVICE_CLASS(klass);

    k->init = s390_virtio_net_init;

    dc->props = s390_virtio_net_properties;

    dc->alias = "virtio-net";

}


static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,

                         const float *exc, const float *isf, const float *isf_past)

{

    float hb_lpc[LP_ORDER_16k];

    enum Mode mode = ctx->fr_cur_mode;

    if (mode == MODE_6k60) {

        float e_isf[LP_ORDER_16k]; // ISF vector for extrapolation

        double e_isp[LP_ORDER_16k];

        ff_weighted_vector_sumf(e_isf, isf_past, isf, isfp_inter[subframe],

                                1.0 - isfp_inter[subframe], LP_ORDER);

        extrapolate_isf(e_isf, e_isf);

        e_isf[LP_ORDER_16k - 1] *= 2.0;

        ff_acelp_lsf2lspd(e_isp, e_isf, LP_ORDER_16k);

        ff_amrwb_lsp2lpc(e_isp, hb_lpc, LP_ORDER_16k);

        lpc_weighting(hb_lpc, hb_lpc, 0.9, LP_ORDER_16k);

    } else {

        lpc_weighting(hb_lpc, ctx->lp_coef[subframe], 0.6, LP_ORDER);

    }

    ff_celp_lp_synthesis_filterf(samples, hb_lpc, exc, AMRWB_SFR_SIZE_16k,

                                 (mode == MODE_6k60) ? LP_ORDER_16k : LP_ORDER);

}


static int qemu_savevm_state(QEMUFile *f, Error **errp)

{

    int ret;

    MigrationParams params = {

        .blk = 0,

        .shared = 0

    };

    MigrationState *ms = migrate_init(&params);

    ms->to_dst_file = f;

    if (qemu_savevm_state_blocked(errp)) {

        return -EINVAL;

    }

    qemu_mutex_unlock_iothread();

    qemu_savevm_state_header(f);

    qemu_savevm_state_begin(f, &params);

    qemu_mutex_lock_iothread();

    while (qemu_file_get_error(f) == 0) {

        if (qemu_savevm_state_iterate(f, false) > 0) {

            break;

        }

    }

    ret = qemu_file_get_error(f);

    if (ret == 0) {

        qemu_savevm_state_complete_precopy(f, false);

        ret = qemu_file_get_error(f);

    }

    qemu_savevm_state_cleanup();

    if (ret != 0) {

        error_setg_errno(errp, -ret, "Error while writing VM state");

    }

    return ret;

}


static always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi,

                                              const uint8_t* zigzag_scan, int bias)

{

    int i, area;

    int run;

    int classes[] = {12, 24, 36, 0xffff};

    run = 0;

    bi->mb[0] = blk[0];

    bi->cno = 0;

    for (area = 0; area < 4; area++) {

       bi->prev_run[area] = run;

       bi->bit_size[area] = 0;

       for (i=mb_area_start[area]; i<mb_area_start[area+1]; i++) {

          bi->mb[i] = (blk[zigzag_scan[i]] / 16);

          while ((bi->mb[i] ^ (bi->mb[i] >> 8)) > classes[bi->cno])

              bi->cno++;

          if (bi->mb[i]) {

              bi->bit_size[area] += dv_rl2vlc_size(run, bi->mb[i]);

	      run = 0;

          } else

              ++run;

       }

    }

    bi->bit_size[3] += 4; /* EOB marker */

    bi->cno += bias;

    if (bi->cno >= 3) { /* FIXME: we have to recreate bit_size[], prev_run[] */

        bi->cno = 3;

	for (i=1; i<64; i++)

	   bi->mb[i] /= 2;

    }

}


static void t_gen_lsl(TCGv d, TCGv a, TCGv b)

{

	TCGv t0, t_31;

	t0 = tcg_temp_new(TCG_TYPE_TL);

	t_31 = tcg_temp_new(TCG_TYPE_TL);

	tcg_gen_shl_tl(d, a, b);

	tcg_gen_movi_tl(t_31, 31);

	tcg_gen_sub_tl(t0, t_31, b);

	tcg_gen_sar_tl(t0, t0, t_31);

	tcg_gen_and_tl(t0, t0, d);

	tcg_gen_xor_tl(d, d, t0);

	tcg_temp_free(t0);

	tcg_temp_free(t_31);

}


bool virtio_scsi_handle_ctrl_vq(VirtIOSCSI *s, VirtQueue *vq)

{

    VirtIOSCSIReq *req;

    bool progress = false;

    virtio_scsi_acquire(s);

    while ((req = virtio_scsi_pop_req(s, vq))) {

        progress = true;

        virtio_scsi_handle_ctrl_req(s, req);

    }

    virtio_scsi_release(s);

    return progress;

}


static void gus_realizefn (DeviceState *dev, Error **errp)

{

    ISADevice *d = ISA_DEVICE(dev);

    GUSState *s = GUS (dev);

    IsaDmaClass *k;

    struct audsettings as;

    AUD_register_card ("gus", &s->card);

    as.freq = s->freq;

    as.nchannels = 2;

    as.fmt = AUD_FMT_S16;

    as.endianness = GUS_ENDIANNESS;

    s->voice = AUD_open_out (

        &s->card,

        NULL,

        "gus",

        s,

        GUS_callback,

        &as

        );

    if (!s->voice) {

        AUD_remove_card (&s->card);

        error_setg(errp, "No voice");

        return;

    }

    s->shift = 2;

    s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;

    s->mixbuf = g_malloc0 (s->samples << s->shift);

    isa_register_portio_list (d, s->port, gus_portio_list1, s, "gus");

    isa_register_portio_list (d, (s->port + 0x100) & 0xf00,

                              gus_portio_list2, s, "gus");

    s->isa_dma = isa_get_dma(isa_bus_from_device(d), s->emu.gusdma);

    k = ISADMA_GET_CLASS(s->isa_dma);

    k->register_channel(s->isa_dma, s->emu.gusdma, GUS_read_DMA, s);

    s->emu.himemaddr = s->himem;

    s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;

    s->emu.opaque = s;

    isa_init_irq (d, &s->pic, s->emu.gusirq);

    AUD_set_active_out (s->voice, 1);

}


static inline bool migration_bitmap_clear_dirty(RAMState *rs, ram_addr_t addr)

{

    bool ret;

    int nr = addr >> TARGET_PAGE_BITS;

    unsigned long *bitmap = atomic_rcu_read(&rs->ram_bitmap)->bmap;

    ret = test_and_clear_bit(nr, bitmap);

    if (ret) {

        rs->migration_dirty_pages--;

    }

    return ret;

}


static int test_vector_fmul_window(AVFloatDSPContext *fdsp, AVFloatDSPContext *cdsp,

                                   const float *v1, const float *v2, const float *v3)

{

    LOCAL_ALIGNED(32, float, cdst, [LEN]);

    LOCAL_ALIGNED(32, float, odst, [LEN]);

    int ret;

    cdsp->vector_fmul_window(cdst, v1, v2, v3, LEN / 2);

    fdsp->vector_fmul_window(odst, v1, v2, v3, LEN / 2);

    if (ret = compare_floats(cdst, odst, LEN, ARBITRARY_FMUL_WINDOW_CONST))

        av_log(NULL, AV_LOG_ERROR, "vector_fmul_window failed\n");

    return ret;

}


static void unassign_storage(SCLPDevice *sclp, SCCB *sccb)

{

    MemoryRegion *mr = NULL;

    AssignStorage *assign_info = (AssignStorage *) sccb;

    sclpMemoryHotplugDev *mhd = get_sclp_memory_hotplug_dev();

    ram_addr_t unassign_addr;

    MemoryRegion *sysmem = get_system_memory();

    if (!mhd) {

        sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_SCLP_COMMAND);

        return;

    }

    unassign_addr = (assign_info->rn - 1) * mhd->rzm;

    /* if the addr is a multiple of 256 MB */

    if ((unassign_addr % MEM_SECTION_SIZE == 0) &&

        (unassign_addr >= mhd->padded_ram_size)) {

        mhd->standby_state_map[(unassign_addr -

                           mhd->padded_ram_size) / MEM_SECTION_SIZE] = 0;

        /* find the specified memory region and destroy it */

        mr = memory_region_find(sysmem, unassign_addr, 1).mr;

        memory_region_unref(mr);

        if (mr) {

            int i;

            int is_removable = 1;

            ram_addr_t map_offset = (unassign_addr - mhd->padded_ram_size -

                                     (unassign_addr - mhd->padded_ram_size)

                                     % mhd->standby_subregion_size);

            /* Mark all affected subregions as 'standby' once again */

            for (i = 0;

                 i < (mhd->standby_subregion_size / MEM_SECTION_SIZE);

                 i++) {

                if (mhd->standby_state_map[i + map_offset / MEM_SECTION_SIZE]) {

                    is_removable = 0;

                    break;

                }

            }

            if (is_removable) {

                memory_region_del_subregion(sysmem, mr);

                object_unref(OBJECT(mr));

            }

        }

    }

    sccb->h.response_code = cpu_to_be16(SCLP_RC_NORMAL_COMPLETION);

}


matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size,

                     int64_t pos, uint64_t cluster_time, uint64_t duration,

                     int is_keyframe, int is_bframe)

{

    int res = 0;

    int track;

    AVStream *st;

    AVPacket *pkt;

    uint8_t *origdata = data;

    int16_t block_time;

    uint32_t *lace_size = NULL;

    int n, flags, laces = 0;

    uint64_t num;

    int stream_index;

    /* first byte(s): tracknum */

    if ((n = matroska_ebmlnum_uint(data, size, &num)) < 0) {

        av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");

        av_free(origdata);

        return res;

    }

    data += n;

    size -= n;

    /* fetch track from num */

    track = matroska_find_track_by_num(matroska, num);

    if (size <= 3 || track < 0 || track >= matroska->num_tracks) {

        av_log(matroska->ctx, AV_LOG_INFO,

               "Invalid stream %d or size %u\n", track, size);

        av_free(origdata);

        return res;

    }

    stream_index = matroska->tracks[track]->stream_index;

    if (stream_index < 0 || stream_index >= matroska->ctx->nb_streams) {

        av_free(origdata);

        return res;

    }

    st = matroska->ctx->streams[stream_index];

    if (st->discard >= AVDISCARD_ALL) {

        av_free(origdata);

        return res;

    }

    if (duration == AV_NOPTS_VALUE)

        duration = matroska->tracks[track]->default_duration / matroska->time_scale;

    /* block_time (relative to cluster time) */

    block_time = AV_RB16(data);

    data += 2;

    flags = *data++;

    size -= 3;

    if (is_keyframe == -1)

        is_keyframe = flags & 0x80 ? PKT_FLAG_KEY : 0;

    if (matroska->skip_to_keyframe) {

        if (!is_keyframe || st != matroska->skip_to_stream) {

            av_free(origdata);

            return res;

        }

        matroska->skip_to_keyframe = 0;

    }

    switch ((flags & 0x06) >> 1) {

        case 0x0: /* no lacing */

            laces = 1;

            lace_size = av_mallocz(sizeof(int));

            lace_size[0] = size;

            break;

        case 0x1: /* xiph lacing */

        case 0x2: /* fixed-size lacing */

        case 0x3: /* EBML lacing */

            assert(size>0); // size <=3 is checked before size-=3 above

            laces = (*data) + 1;

            data += 1;

            size -= 1;

            lace_size = av_mallocz(laces * sizeof(int));

            switch ((flags & 0x06) >> 1) {

                case 0x1: /* xiph lacing */ {

                    uint8_t temp;

                    uint32_t total = 0;

                    for (n = 0; res == 0 && n < laces - 1; n++) {

                        while (1) {

                            if (size == 0) {

                                res = -1;

                                break;

                            }

                            temp = *data;

                            lace_size[n] += temp;

                            data += 1;

                            size -= 1;

                            if (temp != 0xff)

                                break;

                        }

                        total += lace_size[n];

                    }

                    lace_size[n] = size - total;

                    break;

                }

                case 0x2: /* fixed-size lacing */

                    for (n = 0; n < laces; n++)

                        lace_size[n] = size / laces;

                    break;

                case 0x3: /* EBML lacing */ {

                    uint32_t total;

                    n = matroska_ebmlnum_uint(data, size, &num);

                    if (n < 0) {

                        av_log(matroska->ctx, AV_LOG_INFO,

                               "EBML block data error\n");

                        break;

                    }

                    data += n;

                    size -= n;

                    total = lace_size[0] = num;

                    for (n = 1; res == 0 && n < laces - 1; n++) {

                        int64_t snum;

                        int r;

                        r = matroska_ebmlnum_sint (data, size, &snum);

                        if (r < 0) {

                            av_log(matroska->ctx, AV_LOG_INFO,

                                   "EBML block data error\n");

                            break;

                        }

                        data += r;

                        size -= r;

                        lace_size[n] = lace_size[n - 1] + snum;

                        total += lace_size[n];

                    }

                    lace_size[n] = size - total;

                    break;

                }

            }

            break;

    }

    if (res == 0) {

        uint64_t timecode = AV_NOPTS_VALUE;

        if (cluster_time != (uint64_t)-1

            && (block_time >= 0 || cluster_time >= -block_time))

            timecode = cluster_time + block_time;

        for (n = 0; n < laces; n++) {

            if (st->codec->codec_id == CODEC_ID_RA_288 ||

                st->codec->codec_id == CODEC_ID_COOK ||

                st->codec->codec_id == CODEC_ID_ATRAC3) {

                MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)matroska->tracks[track];

                int a = st->codec->block_align;

                int sps = audiotrack->sub_packet_size;

                int cfs = audiotrack->coded_framesize;

                int h = audiotrack->sub_packet_h;

                int y = audiotrack->sub_packet_cnt;

                int w = audiotrack->frame_size;

                int x;

                if (!audiotrack->pkt_cnt) {

                    if (st->codec->codec_id == CODEC_ID_RA_288)

                        for (x=0; x<h/2; x++)

                            memcpy(audiotrack->buf+x*2*w+y*cfs,

                                   data+x*cfs, cfs);

                    else

                        for (x=0; x<w/sps; x++)

                            memcpy(audiotrack->buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps);

                    if (++audiotrack->sub_packet_cnt >= h) {

                        audiotrack->sub_packet_cnt = 0;

                        audiotrack->pkt_cnt = h*w / a;

                    }

                }

                while (audiotrack->pkt_cnt) {

                    pkt = av_mallocz(sizeof(AVPacket));

                    av_new_packet(pkt, a);

                    memcpy(pkt->data, audiotrack->buf

                           + a * (h*w / a - audiotrack->pkt_cnt--), a);

                    pkt->pos = pos;

                    pkt->stream_index = stream_index;

                    matroska_queue_packet(matroska, pkt);

                }

            } else {

                int result, offset = 0, ilen, olen, pkt_size = lace_size[n];

                uint8_t *pkt_data = data;

                if (matroska->tracks[track]->encoding_scope & 1) {

                    switch (matroska->tracks[track]->encoding_algo) {

                    case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP:

                        offset = matroska->tracks[track]->encoding_settings_len;

                        break;

                    case MATROSKA_TRACK_ENCODING_COMP_LZO:

                        pkt_data = NULL;

                        do {

                            ilen = lace_size[n];

                            olen = pkt_size *= 3;

                            pkt_data = av_realloc(pkt_data,

                                                  pkt_size+LZO_OUTPUT_PADDING);

                            result = lzo1x_decode(pkt_data, &olen, data, &ilen);

                        } while (result==LZO_OUTPUT_FULL && pkt_size<10000000);

                        if (result) {

                            av_free(pkt_data);

                            continue;

                        }

                        pkt_size -= olen;

                        break;

#ifdef CONFIG_ZLIB

                    case MATROSKA_TRACK_ENCODING_COMP_ZLIB: {

                        z_stream zstream = {0};

                        pkt_data = NULL;

                        if (inflateInit(&zstream) != Z_OK)

                            continue;

                        zstream.next_in = data;

                        zstream.avail_in = lace_size[n];

                        do {

                            pkt_size *= 3;

                            pkt_data = av_realloc(pkt_data, pkt_size);

                            zstream.avail_out = pkt_size - zstream.total_out;

                            zstream.next_out = pkt_data + zstream.total_out;

                            result = inflate(&zstream, Z_NO_FLUSH);

                        } while (result==Z_OK && pkt_size<10000000);

                        pkt_size = zstream.total_out;

                        inflateEnd(&zstream);

                        if (result != Z_STREAM_END) {

                            av_free(pkt_data);

                            continue;

                        }

                        break;

                    }

#endif

#ifdef CONFIG_BZLIB

                    case MATROSKA_TRACK_ENCODING_COMP_BZLIB: {

                        bz_stream bzstream = {0};

                        pkt_data = NULL;

                        if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK)

                            continue;

                        bzstream.next_in = data;

                        bzstream.avail_in = lace_size[n];

                        do {

                            pkt_size *= 3;

                            pkt_data = av_realloc(pkt_data, pkt_size);

                            bzstream.avail_out = pkt_size - bzstream.total_out_lo32;

                            bzstream.next_out = pkt_data + bzstream.total_out_lo32;

                            result = BZ2_bzDecompress(&bzstream);

                        } while (result==BZ_OK && pkt_size<10000000);

                        pkt_size = bzstream.total_out_lo32;

                        BZ2_bzDecompressEnd(&bzstream);

                        if (result != BZ_STREAM_END) {

                            av_free(pkt_data);

                            continue;

                        }

                        break;

                    }

#endif

                    }

                }

                pkt = av_mallocz(sizeof(AVPacket));

                /* XXX: prevent data copy... */

                if (av_new_packet(pkt, pkt_size+offset) < 0) {

                    res = AVERROR(ENOMEM);

                    n = laces-1;

                    break;

                }

                if (offset)

                    memcpy (pkt->data, matroska->tracks[track]->encoding_settings, offset);

                memcpy (pkt->data+offset, pkt_data, pkt_size);

                if (n == 0)

                    pkt->flags = is_keyframe;

                pkt->stream_index = stream_index;

                pkt->pts = timecode;

                pkt->pos = pos;

                pkt->duration = duration;

                matroska_queue_packet(matroska, pkt);

            }

            if (timecode != AV_NOPTS_VALUE)

                timecode = duration ? timecode + duration : AV_NOPTS_VALUE;

            data += lace_size[n];

        }

    }

    av_free(lace_size);

    av_free(origdata);

    return res;

}


static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,

                                 VirtIODevice *vdev)

{

    VirtIOSerialPortClass *vsc;

    assert(port);

    assert(virtio_queue_ready(vq));

    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);

    while (!port->throttled) {

        unsigned int i;

        /* Pop an elem only if we haven't left off a previous one mid-way */

        if (!port->elem) {

            port->elem = virtqueue_pop(vq, sizeof(VirtQueueElement));

            if (!port->elem) {

                break;

            port->iov_idx = 0;

            port->iov_offset = 0;

        for (i = port->iov_idx; i < port->elem->out_num; i++) {

            size_t buf_size;

            ssize_t ret;

            buf_size = port->elem->out_sg[i].iov_len - port->iov_offset;

            ret = vsc->have_data(port,

                                  port->elem->out_sg[i].iov_base

                                  + port->iov_offset,

                                  buf_size);

            if (port->throttled) {

                port->iov_idx = i;

                if (ret > 0) {

                    port->iov_offset += ret;

                break;

            port->iov_offset = 0;

        if (port->throttled) {

            break;

        virtqueue_push(vq, port->elem, 0);

        g_free(port->elem);

        port->elem = NULL;

    virtio_notify(vdev, vq);


yuv2planeX_16_c_template(const int16_t *filter, int filterSize,

                         const int32_t **src, uint16_t *dest, int dstW,

                         int big_endian, int output_bits)

{

    int i;

    int shift = 15;

    av_assert0(output_bits == 16);

    for (i = 0; i < dstW; i++) {

        int val = 1 << (shift - 1);

        int j;

        /* range of val is [0,0x7FFFFFFF], so 31 bits, but with lanczos/spline

         * filters (or anything with negative coeffs, the range can be slightly

         * wider in both directions. To account for this overflow, we subtract

         * a constant so it always fits in the signed range (assuming a

         * reasonable filterSize), and re-add that at the end. */

        val -= 0x40000000;

        for (j = 0; j < filterSize; j++)

            val += src[j][i] * filter[j];

        output_pixel(&dest[i], val, 0x8000, int);

    }

}


static int generate_coupling_coordinates(AC3DecodeContext * ctx)

{

    ac3_audio_block *ab = &ctx->audio_block;

    uint8_t exp, mstrcplco;

    int16_t mant;

    uint32_t cplbndstrc = (1 << ab->ncplsubnd) >> 1;

    int ch, bnd, sbnd;

    float cplco;

    if (ab->cplcoe)

        for (ch = 0; ch < ctx->bsi.nfchans; ch++)

            if (ab->cplcoe & (1 << ch)) {

                mstrcplco = 3 * ab->mstrcplco[ch];

                sbnd = ab->cplbegf;

                for (bnd = 0; bnd < ab->ncplbnd; bnd++) {

                    exp = ab->cplcoexp[ch][bnd];

                    if (exp == 15)

                        mant = ab->cplcomant[ch][bnd] <<= 14;

                    else

                        mant = (ab->cplcomant[ch][bnd] | 0x10) << 13;

                    cplco = to_float(exp + mstrcplco, mant);

                    if (ctx->bsi.acmod == 0x02 && (ab->flags & AC3_AB_PHSFLGINU) && ch == 1

                            && (ab->phsflg & (1 << bnd)))

                        cplco = -cplco; /* invert the right channel */

                    ab->cplco[ch][sbnd++] = cplco;

                    while (cplbndstrc & ab->cplbndstrc) {

                        cplbndstrc >>= 1;

                        ab->cplco[ch][sbnd++] = cplco;

                    }

                    cplbndstrc >>= 1;

                }

            }

    return 0;

}


static void fifo_deinit(AVFormatContext *avf)

{

    FifoContext *fifo = avf->priv_data;

    av_dict_free(&fifo->format_options);

    avformat_free_context(fifo->avf);

    av_thread_message_queue_free(&fifo->queue);

    pthread_mutex_destroy(&fifo->overflow_flag_lock);

}


static int v9fs_receive_response(V9fsProxy *proxy, int type,

                                 int *status, void *response)

{

    int retval;

    ProxyHeader header;

    struct iovec *reply = &proxy->in_iovec;

    *status = 0;

    reply->iov_len = 0;

    retval = socket_read(proxy->sockfd, reply->iov_base, PROXY_HDR_SZ);

    if (retval < 0) {

        return retval;

    }

    reply->iov_len = PROXY_HDR_SZ;

    proxy_unmarshal(reply, 0, "dd", &header.type, &header.size);

    /*

     * if response size > PROXY_MAX_IO_SZ, read the response but ignore it and

     * return -ENOBUFS

     */

    if (header.size > PROXY_MAX_IO_SZ) {

        int count;

        while (header.size > 0) {

            count = MIN(PROXY_MAX_IO_SZ, header.size);

            count = socket_read(proxy->sockfd, reply->iov_base, count);

            if (count < 0) {

                return count;

            }

            header.size -= count;

        }

        *status = -ENOBUFS;

        return 0;

    }

    retval = socket_read(proxy->sockfd,

                         reply->iov_base + PROXY_HDR_SZ, header.size);

    if (retval < 0) {

        return retval;

    }

    reply->iov_len += header.size;

    /* there was an error during processing request */

    if (header.type == T_ERROR) {

        int ret;

        ret = proxy_unmarshal(reply, PROXY_HDR_SZ, "d", status);

        if (ret < 0) {

            *status = ret;

        }

        return 0;

    }

    switch (type) {

    case T_LSTAT: {

        ProxyStat prstat;

        retval = proxy_unmarshal(reply, PROXY_HDR_SZ,

                                 "qqqdddqqqqqqqqqq", &prstat.st_dev,

                                 &prstat.st_ino, &prstat.st_nlink,

                                 &prstat.st_mode, &prstat.st_uid,

                                 &prstat.st_gid, &prstat.st_rdev,

                                 &prstat.st_size, &prstat.st_blksize,

                                 &prstat.st_blocks,

                                 &prstat.st_atim_sec, &prstat.st_atim_nsec,

                                 &prstat.st_mtim_sec, &prstat.st_mtim_nsec,

                                 &prstat.st_ctim_sec, &prstat.st_ctim_nsec);

        prstat_to_stat(response, &prstat);

        break;

    }

    case T_STATFS: {

        ProxyStatFS prstfs;

        retval = proxy_unmarshal(reply, PROXY_HDR_SZ,

                                 "qqqqqqqqqqq", &prstfs.f_type,

                                 &prstfs.f_bsize, &prstfs.f_blocks,

                                 &prstfs.f_bfree, &prstfs.f_bavail,

                                 &prstfs.f_files, &prstfs.f_ffree,

                                 &prstfs.f_fsid[0], &prstfs.f_fsid[1],

                                 &prstfs.f_namelen, &prstfs.f_frsize);

        prstatfs_to_statfs(response, &prstfs);

        break;

    }

    case T_READLINK: {

        V9fsString target;

        v9fs_string_init(&target);

        retval = proxy_unmarshal(reply, PROXY_HDR_SZ, "s", &target);

        strcpy(response, target.data);

        v9fs_string_free(&target);

        break;

    }

    case T_LGETXATTR:

    case T_LLISTXATTR: {

        V9fsString xattr;

        v9fs_string_init(&xattr);

        retval = proxy_unmarshal(reply, PROXY_HDR_SZ, "s", &xattr);

        memcpy(response, xattr.data, xattr.size);

        v9fs_string_free(&xattr);

        break;

    }

    case T_GETVERSION:

        proxy_unmarshal(reply, PROXY_HDR_SZ, "q", response);

        break;

    default:

        return -1;

    }

    if (retval < 0) {

        *status  = retval;

    }

    return 0;

}


static av_cold int vpx_init(AVCodecContext *avctx,
                            const struct vpx_codec_iface *iface)
{
    VP8Context *ctx = avctx->priv_data;
    struct vpx_codec_enc_cfg enccfg;
    int res;
    av_log(avctx, AV_LOG_INFO, "%s\n", vpx_codec_version_str());
    av_log(avctx, AV_LOG_VERBOSE, "%s\n", vpx_codec_build_config());
    if ((res = vpx_codec_enc_config_default(iface, &enccfg, 0)) != VPX_CODEC_OK) {
        av_log(avctx, AV_LOG_ERROR, "Failed to get config: %s\n",
               vpx_codec_err_to_string(res));
    if(!avctx->bit_rate)
        if(avctx->rc_max_rate || avctx->rc_buffer_size || avctx->rc_initial_buffer_occupancy) {
            av_log( avctx, AV_LOG_ERROR, "Rate control parameters set without a bitrate\n");
    dump_enc_cfg(avctx, &enccfg);
    enccfg.g_w            = avctx->width;
    enccfg.g_h            = avctx->height;
    enccfg.g_timebase.num = avctx->time_base.num;
    enccfg.g_timebase.den = avctx->time_base.den;
    enccfg.g_threads      = avctx->thread_count;
    enccfg.g_lag_in_frames= ctx->lag_in_frames;
    if (avctx->flags & CODEC_FLAG_PASS1)
        enccfg.g_pass = VPX_RC_FIRST_PASS;
    else if (avctx->flags & CODEC_FLAG_PASS2)
        enccfg.g_pass = VPX_RC_LAST_PASS;
    else
        enccfg.g_pass = VPX_RC_ONE_PASS;
    if (avctx->rc_min_rate == avctx->rc_max_rate &&
        avctx->rc_min_rate == avctx->bit_rate && avctx->bit_rate)
        enccfg.rc_end_usage = VPX_CBR;
    else if (ctx->crf)
        enccfg.rc_end_usage = VPX_CQ;
    if (avctx->bit_rate) {
        enccfg.rc_target_bitrate = av_rescale_rnd(avctx->bit_rate, 1, 1000,
                                                AV_ROUND_NEAR_INF);
    } else {
            enccfg.rc_target_bitrate = 1000000;
        } else {
            avctx->bit_rate = enccfg.rc_target_bitrate * 1000;
            av_log(avctx, AV_LOG_WARNING,
                   "Neither bitrate nor constrained quality specified, using default bitrate of %dkbit/sec\n",
                   enccfg.rc_target_bitrate);
    if (avctx->qmin >= 0)
        enccfg.rc_min_quantizer = avctx->qmin;
    if (avctx->qmax > 0)
        enccfg.rc_max_quantizer = avctx->qmax;
    enccfg.rc_dropframe_thresh = avctx->frame_skip_threshold;
    //0-100 (0 => CBR, 100 => VBR)
    enccfg.rc_2pass_vbr_bias_pct           = round(avctx->qcompress * 100);
    if (avctx->bit_rate)
        enccfg.rc_2pass_vbr_minsection_pct     =
            avctx->rc_min_rate * 100LL / avctx->bit_rate;
    if (avctx->rc_max_rate)
        enccfg.rc_2pass_vbr_maxsection_pct =
            avctx->rc_max_rate * 100LL / avctx->bit_rate;
    if (avctx->rc_buffer_size)
        enccfg.rc_buf_sz         =
            avctx->rc_buffer_size * 1000LL / avctx->bit_rate;
    if (avctx->rc_initial_buffer_occupancy)
        enccfg.rc_buf_initial_sz =
            avctx->rc_initial_buffer_occupancy * 1000LL / avctx->bit_rate;
    enccfg.rc_buf_optimal_sz     = enccfg.rc_buf_sz * 5 / 6;
    enccfg.rc_undershoot_pct     = round(avctx->rc_buffer_aggressivity * 100);
    //_enc_init() will balk if kf_min_dist differs from max w/VPX_KF_AUTO
    if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
        enccfg.kf_min_dist = avctx->keyint_min;
    if (avctx->gop_size >= 0)
        enccfg.kf_max_dist = avctx->gop_size;
    if (enccfg.g_pass == VPX_RC_FIRST_PASS)
        enccfg.g_lag_in_frames = 0;
    else if (enccfg.g_pass == VPX_RC_LAST_PASS) {
        int decode_size;
        if (!avctx->stats_in) {
            av_log(avctx, AV_LOG_ERROR, "No stats file for second pass\n");
            return AVERROR_INVALIDDATA;
        ctx->twopass_stats.sz  = strlen(avctx->stats_in) * 3 / 4;
        ctx->twopass_stats.buf = av_malloc(ctx->twopass_stats.sz);
        if (!ctx->twopass_stats.buf) {
                   "Stat buffer alloc (%zu bytes) failed\n",
                   ctx->twopass_stats.sz);
            return AVERROR(ENOMEM);
        decode_size = av_base64_decode(ctx->twopass_stats.buf, avctx->stats_in,
                                       ctx->twopass_stats.sz);
        if (decode_size < 0) {
            av_log(avctx, AV_LOG_ERROR, "Stat buffer decode failed\n");
            return AVERROR_INVALIDDATA;
        ctx->twopass_stats.sz      = decode_size;
        enccfg.rc_twopass_stats_in = ctx->twopass_stats;
    /* 0-3: For non-zero values the encoder increasingly optimizes for reduced
       complexity playback on low powered devices at the expense of encode
       quality. */
   if (avctx->profile != FF_PROFILE_UNKNOWN)
       enccfg.g_profile = avctx->profile;
    enccfg.g_error_resilient = ctx->error_resilient || ctx->flags & VP8F_ERROR_RESILIENT;
    dump_enc_cfg(avctx, &enccfg);
    /* Construct Encoder Context */
    res = vpx_codec_enc_init(&ctx->encoder, iface, &enccfg, 0);
    if (res != VPX_CODEC_OK) {
        log_encoder_error(avctx, "Failed to initialize encoder");
    //codec control failures are currently treated only as warnings
    av_log(avctx, AV_LOG_DEBUG, "vpx_codec_control\n");
    if (ctx->cpu_used != INT_MIN)
        codecctl_int(avctx, VP8E_SET_CPUUSED,          ctx->cpu_used);
    if (ctx->flags & VP8F_AUTO_ALT_REF)
        ctx->auto_alt_ref = 1;
    if (ctx->auto_alt_ref >= 0)
        codecctl_int(avctx, VP8E_SET_ENABLEAUTOALTREF, ctx->auto_alt_ref);
    if (ctx->arnr_max_frames >= 0)
        codecctl_int(avctx, VP8E_SET_ARNR_MAXFRAMES,   ctx->arnr_max_frames);
    if (ctx->arnr_strength >= 0)
        codecctl_int(avctx, VP8E_SET_ARNR_STRENGTH,    ctx->arnr_strength);
    if (ctx->arnr_type >= 0)
        codecctl_int(avctx, VP8E_SET_ARNR_TYPE,        ctx->arnr_type);
    codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction);
    codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS,  av_log2(avctx->slices));
    codecctl_int(avctx, VP8E_SET_STATIC_THRESHOLD,  avctx->mb_threshold);
    codecctl_int(avctx, VP8E_SET_CQ_LEVEL,          ctx->crf);
    if (ctx->max_intra_rate >= 0)
        codecctl_int(avctx, VP8E_SET_MAX_INTRA_BITRATE_PCT, ctx->max_intra_rate);
    av_log(avctx, AV_LOG_DEBUG, "Using deadline: %d\n", ctx->deadline);
    //provide dummy value to initialize wrapper, values will be updated each _encode()
    vpx_img_wrap(&ctx->rawimg, VPX_IMG_FMT_I420, avctx->width, avctx->height, 1,
                 (unsigned char*)1);
    avctx->coded_frame = avcodec_alloc_frame();
    if (!avctx->coded_frame) {
        av_log(avctx, AV_LOG_ERROR, "Error allocating coded frame\n");
        vp8_free(avctx);
        return AVERROR(ENOMEM);
    return 0;


static int get_metadata_size(const uint8_t *buf, int buf_size)

{

    int metadata_last, metadata_size;

    const uint8_t *buf_end = buf + buf_size;

    buf += 4;

    do {

        ff_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);

        buf += 4;

        if (buf + metadata_size > buf_end) {

            /* need more data in order to read the complete header */

            return 0;

        }

        buf += metadata_size;

    } while (!metadata_last);

    return buf_size - (buf_end - buf);

}


static int usbredir_handle_interrupt_data(USBRedirDevice *dev,

                                           USBPacket *p, uint8_t ep)

{

    if (ep & USB_DIR_IN) {

        /* Input interrupt endpoint, buffered packet input */

        struct buf_packet *intp;

        int status, len;

        if (!dev->endpoint[EP2I(ep)].interrupt_started &&

                !dev->endpoint[EP2I(ep)].interrupt_error) {

            struct usb_redir_start_interrupt_receiving_header start_int = {

                .endpoint = ep,

            };

            /* No id, we look at the ep when receiving a status back */

            usbredirparser_send_start_interrupt_receiving(dev->parser, 0,

                                                          &start_int);

            usbredirparser_do_write(dev->parser);

            DPRINTF("interrupt recv started ep %02X\n", ep);

            dev->endpoint[EP2I(ep)].interrupt_started = 1;

        }

        intp = QTAILQ_FIRST(&dev->endpoint[EP2I(ep)].bufpq);

        if (intp == NULL) {

            DPRINTF2("interrupt-token-in ep %02X, no intp\n", ep);

            /* Check interrupt_error for stream errors */

            status = dev->endpoint[EP2I(ep)].interrupt_error;

            dev->endpoint[EP2I(ep)].interrupt_error = 0;

            return usbredir_handle_status(dev, status, 0);

        }

        DPRINTF("interrupt-token-in ep %02X status %d len %d\n", ep,

                intp->status, intp->len);

        status = intp->status;

        if (status != usb_redir_success) {

            bufp_free(dev, intp, ep);

            return usbredir_handle_status(dev, status, 0);

        }

        len = intp->len;

        if (len > p->len) {

            ERROR("received int data is larger then packet ep %02X\n", ep);

            bufp_free(dev, intp, ep);

            return USB_RET_NAK;

        }

        memcpy(p->data, intp->data, len);

        bufp_free(dev, intp, ep);

        return len;

    } else {

        /* Output interrupt endpoint, normal async operation */

        AsyncURB *aurb = async_alloc(dev, p);

        struct usb_redir_interrupt_packet_header interrupt_packet;

        DPRINTF("interrupt-out ep %02X len %d id %u\n", ep, p->len,

                aurb->packet_id);

        interrupt_packet.endpoint  = ep;

        interrupt_packet.length    = p->len;

        aurb->interrupt_packet     = interrupt_packet;

        usbredir_log_data(dev, "interrupt data out:", p->data, p->len);

        usbredirparser_send_interrupt_packet(dev->parser, aurb->packet_id,

                                        &interrupt_packet, p->data, p->len);

        usbredirparser_do_write(dev->parser);

        return USB_RET_ASYNC;

    }

}


static av_cold int msrle_decode_init(AVCodecContext *avctx)

{

    MsrleContext *s = avctx->priv_data;

    int i;

    s->avctx = avctx;

    switch (avctx->bits_per_coded_sample) {

    case 1:

        avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;

        break;

    case 4:

    case 8:

        avctx->pix_fmt = AV_PIX_FMT_PAL8;

        break;

    case 24:

        avctx->pix_fmt = AV_PIX_FMT_BGR24;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "unsupported bits per sample\n");

        return -1;

    }

    avcodec_get_frame_defaults(&s->frame);

    s->frame.data[0] = NULL;

    if (avctx->extradata_size >= AVPALETTE_SIZE)

        for (i = 0; i < AVPALETTE_SIZE/4; i++)

            s->pal[i] = 0xFF<<24 | AV_RL32(avctx->extradata+4*i);

    return 0;

}


static void nvme_clear_ctrl(NvmeCtrl *n)

{

    int i;

    for (i = 0; i < n->num_queues; i++) {

        if (n->sq[i] != NULL) {

            nvme_free_sq(n->sq[i], n);

        }

    }

    for (i = 0; i < n->num_queues; i++) {

        if (n->cq[i] != NULL) {

            nvme_free_cq(n->cq[i], n);

        }

    }

    bdrv_flush(n->conf.bs);

    n->bar.cc = 0;

}


void r4k_helper_tlbwi(CPUMIPSState *env)

{

    r4k_tlb_t *tlb;

    int idx;

    target_ulong VPN;

    uint16_t ASID;

    bool G, V0, D0, V1, D1;

    idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;

    tlb = &env->tlb->mmu.r4k.tlb[idx];

    VPN = env->CP0_EntryHi & (TARGET_PAGE_MASK << 1);

#if defined(TARGET_MIPS64)

    VPN &= env->SEGMask;

#endif

    ASID = env->CP0_EntryHi & env->CP0_EntryHi_ASID_mask;

    G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1;

    V0 = (env->CP0_EntryLo0 & 2) != 0;

    D0 = (env->CP0_EntryLo0 & 4) != 0;

    V1 = (env->CP0_EntryLo1 & 2) != 0;

    D1 = (env->CP0_EntryLo1 & 4) != 0;

    /* Discard cached TLB entries, unless tlbwi is just upgrading access

       permissions on the current entry. */

    if (tlb->VPN != VPN || tlb->ASID != ASID || tlb->G != G ||

        (tlb->V0 && !V0) || (tlb->D0 && !D0) ||

        (tlb->V1 && !V1) || (tlb->D1 && !D1)) {

        r4k_mips_tlb_flush_extra(env, env->tlb->nb_tlb);

    }

    r4k_invalidate_tlb(env, idx, 0);

    r4k_fill_tlb(env, idx);

}


static void an5206_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    M68kCPU *cpu;

    CPUM68KState *env;

    int kernel_size;

    uint64_t elf_entry;

    hwaddr entry;

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    MemoryRegion *sram = g_new(MemoryRegion, 1);

    if (!cpu_model) {

        cpu_model = "m5206";

    }

    cpu = M68K_CPU(cpu_generic_init(TYPE_M68K_CPU, cpu_model));

    env = &cpu->env;

    /* Initialize CPU registers.  */

    env->vbr = 0;

    /* TODO: allow changing MBAR and RAMBAR.  */

    env->mbar = AN5206_MBAR_ADDR | 1;

    env->rambar0 = AN5206_RAMBAR_ADDR | 1;

    /* DRAM at address zero */

    memory_region_allocate_system_memory(ram, NULL, "an5206.ram", ram_size);

    memory_region_add_subregion(address_space_mem, 0, ram);

    /* Internal SRAM.  */

    memory_region_init_ram(sram, NULL, "an5206.sram", 512, &error_fatal);

    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);

    mcf5206_init(address_space_mem, AN5206_MBAR_ADDR, cpu);

    /* Load kernel.  */

    if (!kernel_filename) {

        if (qtest_enabled()) {

            return;

        }

        fprintf(stderr, "Kernel image must be specified\n");

        exit(1);

    }

    kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry,

                           NULL, NULL, 1, EM_68K, 0, 0);

    entry = elf_entry;

    if (kernel_size < 0) {

        kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL,

                                  NULL, NULL);

    }

    if (kernel_size < 0) {

        kernel_size = load_image_targphys(kernel_filename, KERNEL_LOAD_ADDR,

                                          ram_size - KERNEL_LOAD_ADDR);

        entry = KERNEL_LOAD_ADDR;

    }

    if (kernel_size < 0) {

        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);

        exit(1);

    }

    env->pc = entry;

}


static inline int ape_decode_value(APEContext *ctx, APERice *rice)

{

    int x, overflow;

    if (ctx->fileversion < 3990) {

        int tmpk;

        overflow = range_get_symbol(ctx, counts_3970, counts_diff_3970);

        if (overflow == (MODEL_ELEMENTS - 1)) {

            tmpk = range_decode_bits(ctx, 5);

            overflow = 0;

        } else

            tmpk = (rice->k < 1) ? 0 : rice->k - 1;

        if (tmpk <= 16)

            x = range_decode_bits(ctx, tmpk);

        else {

            x = range_decode_bits(ctx, 16);

            x |= (range_decode_bits(ctx, tmpk - 16) << 16);

        }

        x += overflow << tmpk;

    } else {

        int base, pivot;

        pivot = rice->ksum >> 5;

        if (pivot == 0)

            pivot = 1;

        overflow = range_get_symbol(ctx, counts_3980, counts_diff_3980);

        if (overflow == (MODEL_ELEMENTS - 1)) {

            overflow  = range_decode_bits(ctx, 16) << 16;

            overflow |= range_decode_bits(ctx, 16);

        }

        if (pivot < 0x10000) {

            base = range_decode_culfreq(ctx, pivot);

            range_decode_update(ctx, 1, base);

        } else {

            int base_hi = pivot, base_lo;

            int bbits = 0;

            while (base_hi & ~0xFFFF) {

                base_hi >>= 1;

                bbits++;

            }

            base_hi = range_decode_culfreq(ctx, base_hi + 1);

            range_decode_update(ctx, 1, base_hi);

            base_lo = range_decode_culfreq(ctx, 1 << bbits);

            range_decode_update(ctx, 1, base_lo);

            base = (base_hi << bbits) + base_lo;

        }

        x = base + overflow * pivot;

    }

    update_rice(rice, x);

    /* Convert to signed */

    if (x & 1)

        return (x >> 1) + 1;

    else

        return -(x >> 1);

}


int ffio_ensure_seekback(AVIOContext *s, int buf_size)

{

    uint8_t *buffer;

    int max_buffer_size = s->max_packet_size ?

                          s->max_packet_size : IO_BUFFER_SIZE;

    buf_size += s->buf_ptr - s->buffer + max_buffer_size;

    if (buf_size < s->buffer_size || s->seekable)

        return 0;

    av_assert0(!s->write_flag);

    buffer = av_malloc(buf_size);

    if (!buffer)

        return AVERROR(ENOMEM);

    memcpy(buffer, s->buffer, s->buffer_size);

    av_free(s->buffer);

    s->buf_ptr = buffer + (s->buf_ptr - s->buffer);

    s->buf_end = buffer + (s->buf_end - s->buffer);

    s->buffer = buffer;

    s->buffer_size = buf_size;

    return 0;

}


static int film_probe(AVProbeData *p)
{
    if (AV_RB32(&p->buf[0]) != FILM_TAG)
    return AVPROBE_SCORE_MAX;
}


static uint8_t ide_wait_clear(uint8_t flag)

{

    QPCIDevice *dev;

    QPCIBar bmdma_bar, ide_bar;

    uint8_t data;

    time_t st;

    dev = get_pci_device(&bmdma_bar, &ide_bar);

    /* Wait with a 5 second timeout */

    time(&st);

    while (true) {

        data = qpci_io_readb(dev, ide_bar, reg_status);

        if (!(data & flag)) {

            return data;

        }

        if (difftime(time(NULL), st) > 5.0) {

            break;

        }

        nsleep(400);

    }

    g_assert_not_reached();

}


static void perf_lifecycle(void)

{

    Coroutine *coroutine;

    unsigned int i, max;

    double duration;

    max = 1000000;

    g_test_timer_start();

    for (i = 0; i < max; i++) {

        coroutine = qemu_coroutine_create(empty_coroutine);

        qemu_coroutine_enter(coroutine, NULL);

    }

    duration = g_test_timer_elapsed();

    g_test_message("Lifecycle %u iterations: %f s\n", max, duration);

}


static int plot_cqt(AVFilterLink *inlink)

{

    AVFilterContext *ctx = inlink->dst;

    ShowCQTContext *s = ctx->priv;

    AVFilterLink *outlink = ctx->outputs[0];

    int fft_len = 1 << s->fft_bits;

    FFTSample result[VIDEO_WIDTH][4];

    int x, y, ret = 0;

    int linesize = s->outpicref->linesize[0];

    int video_scale = s->fullhd ? 2 : 1;

    int video_width = (VIDEO_WIDTH/2) * video_scale;

    int spectogram_height = (SPECTOGRAM_HEIGHT/2) * video_scale;

    int spectogram_start = (SPECTOGRAM_START/2) * video_scale;

    int font_height = (FONT_HEIGHT/2) * video_scale;

    /* real part contains left samples, imaginary part contains right samples */

    memcpy(s->fft_result, s->fft_data, fft_len * sizeof(*s->fft_data));

    av_fft_permute(s->fft_context, s->fft_result);

    av_fft_calc(s->fft_context, s->fft_result);

    s->fft_result[fft_len] = s->fft_result[0];

    /* calculating cqt */

    for (x = 0; x < VIDEO_WIDTH; x++) {

        int u;

        FFTComplex v = {0,0};

        FFTComplex w = {0,0};

        FFTComplex l, r;

        for (u = 0; u < s->coeffs[x].len; u++) {

            FFTSample value = s->coeffs[x].values[u];

            int index = s->coeffs[x].start + u;

            v.re += value * s->fft_result[index].re;

            v.im += value * s->fft_result[index].im;

            w.re += value * s->fft_result[fft_len - index].re;

            w.im += value * s->fft_result[fft_len - index].im;

        }

        /* separate left and right, (and multiply by 2.0) */

        l.re = v.re + w.re;

        l.im = v.im - w.im;

        r.re = w.im + v.im;

        r.im = w.re - v.re;

        /* result is power, not amplitude */

        result[x][0] = l.re * l.re + l.im * l.im;

        result[x][2] = r.re * r.re + r.im * r.im;

        result[x][1] = 0.5f * (result[x][0] + result[x][2]);

        if (s->gamma2 == 1.0f)

            result[x][3] = result[x][1];

        else if (s->gamma2 == 2.0f)

            result[x][3] = sqrtf(result[x][1]);

        else if (s->gamma2 == 3.0f)

            result[x][3] = cbrtf(result[x][1]);

        else if (s->gamma2 == 4.0f)

            result[x][3] = sqrtf(sqrtf(result[x][1]));

        else

            result[x][3] = expf(logf(result[x][1]) * (1.0f / s->gamma2));

        result[x][0] = FFMIN(1.0f, result[x][0]);

        result[x][1] = FFMIN(1.0f, result[x][1]);

        result[x][2] = FFMIN(1.0f, result[x][2]);

        if (s->gamma == 1.0f) {

            result[x][0] = 255.0f * result[x][0];

            result[x][1] = 255.0f * result[x][1];

            result[x][2] = 255.0f * result[x][2];

        } else if (s->gamma == 2.0f) {

            result[x][0] = 255.0f * sqrtf(result[x][0]);

            result[x][1] = 255.0f * sqrtf(result[x][1]);

            result[x][2] = 255.0f * sqrtf(result[x][2]);

        } else if (s->gamma == 3.0f) {

            result[x][0] = 255.0f * cbrtf(result[x][0]);

            result[x][1] = 255.0f * cbrtf(result[x][1]);

            result[x][2] = 255.0f * cbrtf(result[x][2]);

        } else if (s->gamma == 4.0f) {

            result[x][0] = 255.0f * sqrtf(sqrtf(result[x][0]));

            result[x][1] = 255.0f * sqrtf(sqrtf(result[x][1]));

            result[x][2] = 255.0f * sqrtf(sqrtf(result[x][2]));

        } else {

            result[x][0] = 255.0f * expf(logf(result[x][0]) * (1.0f / s->gamma));

            result[x][1] = 255.0f * expf(logf(result[x][1]) * (1.0f / s->gamma));

            result[x][2] = 255.0f * expf(logf(result[x][2]) * (1.0f / s->gamma));

        }

    }

    if (!s->fullhd) {

        for (x = 0; x < video_width; x++) {

            result[x][0] = 0.5f * (result[2*x][0] + result[2*x+1][0]);

            result[x][1] = 0.5f * (result[2*x][1] + result[2*x+1][1]);

            result[x][2] = 0.5f * (result[2*x][2] + result[2*x+1][2]);

            result[x][3] = 0.5f * (result[2*x][3] + result[2*x+1][3]);

        }

    }

    for (x = 0; x < video_width; x++) {

        s->spectogram[s->spectogram_index*linesize + 3*x] = result[x][0] + 0.5f;

        s->spectogram[s->spectogram_index*linesize + 3*x + 1] = result[x][1] + 0.5f;

        s->spectogram[s->spectogram_index*linesize + 3*x + 2] = result[x][2] + 0.5f;

    }

    /* drawing */

    if (!s->spectogram_count) {

        uint8_t *data = (uint8_t*) s->outpicref->data[0];

        float rcp_result[VIDEO_WIDTH];

        int total_length = linesize * spectogram_height;

        int back_length = linesize * s->spectogram_index;

        for (x = 0; x < video_width; x++)

            rcp_result[x] = 1.0f / (result[x][3]+0.0001f);

        /* drawing bar */

        for (y = 0; y < spectogram_height; y++) {

            float height = (spectogram_height - y) * (1.0f/spectogram_height);

            uint8_t *lineptr = data + y * linesize;

            for (x = 0; x < video_width; x++) {

                float mul;

                if (result[x][3] <= height) {

                    *lineptr++ = 0;

                    *lineptr++ = 0;

                    *lineptr++ = 0;

                } else {

                    mul = (result[x][3] - height) * rcp_result[x];

                    *lineptr++ = mul * result[x][0] + 0.5f;

                    *lineptr++ = mul * result[x][1] + 0.5f;

                    *lineptr++ = mul * result[x][2] + 0.5f;

                }

            }

        }

        /* drawing font */

        if (s->font_alpha && s->draw_text) {

            for (y = 0; y < font_height; y++) {

                uint8_t *lineptr = data + (spectogram_height + y) * linesize;

                uint8_t *spectogram_src = s->spectogram + s->spectogram_index * linesize;

                uint8_t *fontcolor_value = s->fontcolor_value;

                for (x = 0; x < video_width; x++) {

                    uint8_t alpha = s->font_alpha[y*video_width+x];

                    lineptr[3*x] = (spectogram_src[3*x] * (255-alpha) + fontcolor_value[0] * alpha + 255) >> 8;

                    lineptr[3*x+1] = (spectogram_src[3*x+1] * (255-alpha) + fontcolor_value[1] * alpha + 255) >> 8;

                    lineptr[3*x+2] = (spectogram_src[3*x+2] * (255-alpha) + fontcolor_value[2] * alpha + 255) >> 8;

                    fontcolor_value += 3;

                }

            }

        } else if (s->draw_text) {

            for (y = 0; y < font_height; y++) {

                uint8_t *lineptr = data + (spectogram_height + y) * linesize;

                memcpy(lineptr, s->spectogram + s->spectogram_index * linesize, video_width*3);

            }

            for (x = 0; x < video_width; x += video_width/10) {

                int u;

                static const char str[] = "EF G A BC D ";

                uint8_t *startptr = data + spectogram_height * linesize + x * 3;

                for (u = 0; str[u]; u++) {

                    int v;

                    for (v = 0; v < 16; v++) {

                        uint8_t *p = startptr + v * linesize * video_scale + 8 * 3 * u * video_scale;

                        int ux = x + 8 * u * video_scale;

                        int mask;

                        for (mask = 0x80; mask; mask >>= 1) {

                            if (mask & avpriv_vga16_font[str[u] * 16 + v]) {

                                p[0] = s->fontcolor_value[3*ux];

                                p[1] = s->fontcolor_value[3*ux+1];

                                p[2] = s->fontcolor_value[3*ux+2];

                                if (video_scale == 2) {

                                    p[linesize] = p[0];

                                    p[linesize+1] = p[1];

                                    p[linesize+2] = p[2];

                                    p[3] = p[linesize+3] = s->fontcolor_value[3*ux+3];

                                    p[4] = p[linesize+4] = s->fontcolor_value[3*ux+4];

                                    p[5] = p[linesize+5] = s->fontcolor_value[3*ux+5];

                                }

                            }

                            p  += 3 * video_scale;

                            ux += video_scale;

                        }

                    }

                }

            }

        } else {

            for (y = 0; y < font_height; y++) {

                uint8_t *lineptr = data + (spectogram_height + y) * linesize;

                uint8_t *spectogram_src = s->spectogram + s->spectogram_index * linesize;

                for (x = 0; x < video_width; x++) {

                    lineptr[3*x] = spectogram_src[3*x];

                    lineptr[3*x+1] = spectogram_src[3*x+1];

                    lineptr[3*x+2] = spectogram_src[3*x+2];

                }

            }

        }

        /* drawing spectogram/sonogram */

        data += spectogram_start * linesize;

        memcpy(data, s->spectogram + s->spectogram_index*linesize, total_length - back_length);

        data += total_length - back_length;

        if (back_length)

            memcpy(data, s->spectogram, back_length);

        s->outpicref->pts = s->frame_count;

        ret = ff_filter_frame(outlink, av_frame_clone(s->outpicref));

        s->req_fullfilled = 1;

        s->frame_count++;

    }

    s->spectogram_count = (s->spectogram_count + 1) % s->count;

    s->spectogram_index = (s->spectogram_index + spectogram_height - 1) % spectogram_height;

    return ret;

}


void do_4xx_tlbsx_ (void)

{

    int tmp = xer_ov;

    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]);

    if (T0 != -1)

        tmp |= 0x02;

    env->crf[0] = tmp;

}


static void decode_bol_opc(CPUTriCoreState *env, DisasContext *ctx, int32_t op1)

{

    int r1, r2;

    int32_t address;

    TCGv temp;

    r1 = MASK_OP_BOL_S1D(ctx->opcode);

    r2 = MASK_OP_BOL_S2(ctx->opcode);

    address = MASK_OP_BOL_OFF16_SEXT(ctx->opcode);

    switch (op1) {

    case OPC1_32_BOL_LD_A_LONGOFF:

        temp = tcg_temp_new();

        tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);

        tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LEUL);

        tcg_temp_free(temp);

        break;

    case OPC1_32_BOL_LD_W_LONGOFF:

        temp = tcg_temp_new();

        tcg_gen_addi_tl(temp, cpu_gpr_a[r2], address);

        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUL);

        tcg_temp_free(temp);

        break;

    case OPC1_32_BOL_LEA_LONGOFF:

        tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], address);

        break;

    case OPC1_32_BOL_ST_A_LONGOFF:

        if (tricore_feature(env, TRICORE_FEATURE_16)) {

            gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], address, MO_LEUL);

        } else {

            /* raise illegal opcode trap */

        }

        break;

    case OPC1_32_BOL_ST_W_LONGOFF:

        gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUL);

        break;

    case OPC1_32_BOL_LD_B_LONGOFF:

        if (tricore_feature(env, TRICORE_FEATURE_16)) {

            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);

        } else {

            /* raise illegal opcode trap */

        }

        break;

    case OPC1_32_BOL_LD_BU_LONGOFF:

        if (tricore_feature(env, TRICORE_FEATURE_16)) {

            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_UB);

        } else {

            /* raise illegal opcode trap */

        }

        break;

    case OPC1_32_BOL_LD_H_LONGOFF:

        if (tricore_feature(env, TRICORE_FEATURE_16)) {

            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);

        } else {

            /* raise illegal opcode trap */

        }

        break;

    case OPC1_32_BOL_LD_HU_LONGOFF:

        if (tricore_feature(env, TRICORE_FEATURE_16)) {

            gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LEUW);

        } else {

            /* raise illegal opcode trap */

        }

        break;

    case OPC1_32_BOL_ST_B_LONGOFF:

        if (tricore_feature(env, TRICORE_FEATURE_16)) {

            gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_SB);

        } else {

            /* raise illegal opcode trap */

        }

        break;

    case OPC1_32_BOL_ST_H_LONGOFF:

        if (tricore_feature(env, TRICORE_FEATURE_16)) {

            gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], address, MO_LESW);

        } else {

            /* raise illegal opcode trap */

        }

        break;

    }

}


static void virtconsole_realize(DeviceState *dev, Error **errp)

{

    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);

    VirtConsole *vcon = VIRTIO_CONSOLE(dev);

    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);

    if (port->id == 0 && !k->is_console) {

        error_setg(errp, "Port number 0 on virtio-serial devices reserved "

                   "for virtconsole devices for backward compatibility.");

        return;

    }

    if (vcon->chr) {

        vcon->chr->explicit_fe_open = 1;

        qemu_chr_add_handlers(vcon->chr, chr_can_read, chr_read, chr_event,

                              vcon);

    }

}