static void gen_sse(CPUX86State *env, DisasContext *s, int b, target_ulong pc_start, int rex_r) { int b1, op1_offset, op2_offset, is_xmm, val; int modrm, mod, rm, reg; SSEFunc_0_epp sse_fn_epp; SSEFunc_0_eppi sse_fn_eppi; SSEFunc_0_ppi sse_fn_ppi; SSEFunc_0_eppt sse_fn_eppt; TCGMemOp ot; b &= 0xff; if (s->prefix & PREFIX_DATA) b1 = 1; else if (s->prefix & PREFIX_REPZ) b1 = 2; else if (s->prefix & PREFIX_REPNZ) b1 = 3; else b1 = 0; sse_fn_epp = sse_op_table1[b][b1]; if (!sse_fn_epp) { goto unknown_op; } if ((b <= 0x5f && b >= 0x10) || b == 0xc6 || b == 0xc2) { is_xmm = 1; } else { if (b1 == 0) { /* MMX case */ is_xmm = 0; } else { is_xmm = 1; } } /* simple MMX/SSE operation */ if (s->flags & HF_TS_MASK) { gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); return; } if (s->flags & HF_EM_MASK) { illegal_op: gen_illegal_opcode(s); return; } if (is_xmm && !(s->flags & HF_OSFXSR_MASK) && ((b != 0x38 && b != 0x3a) || (s->prefix & PREFIX_DATA))) { goto unknown_op; } if (b == 0x0e) { if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) { /* If we were fully decoding this we might use illegal_op. */ goto unknown_op; } /* femms */ gen_helper_emms(cpu_env); return; } if (b == 0x77) { /* emms */ gen_helper_emms(cpu_env); return; } /* prepare MMX state (XXX: optimize by storing fptt and fptags in the static cpu state) */ if (!is_xmm) { gen_helper_enter_mmx(cpu_env); } modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7); if (is_xmm) reg |= rex_r; mod = (modrm >> 6) & 3; if (sse_fn_epp == SSE_SPECIAL) { b |= (b1 << 8); switch(b) { case 0x0e7: /* movntq */ if (mod == 3) { goto illegal_op; } gen_lea_modrm(env, s, modrm); gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); break; case 0x1e7: /* movntdq */ case 0x02b: /* movntps */ case 0x12b: /* movntps */ if (mod == 3) goto illegal_op; gen_lea_modrm(env, s, modrm); gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); break; case 0x3f0: /* lddqu */ if (mod == 3) goto illegal_op; gen_lea_modrm(env, s, modrm); gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); break; case 0x22b: /* movntss */ case 0x32b: /* movntsd */ if (mod == 3) goto illegal_op; gen_lea_modrm(env, s, modrm); if (b1 & 1) { gen_stq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0))); } else { tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0))); gen_op_st_v(s, MO_32, cpu_T0, cpu_A0); } break; case 0x6e: /* movd mm, ea */ #ifdef TARGET_X86_64 if (s->dflag == MO_64) { gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0); tcg_gen_st_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); } else #endif { gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0); gen_helper_movl_mm_T0_mmx(cpu_ptr0, cpu_tmp2_i32); } break; case 0x16e: /* movd xmm, ea */ #ifdef TARGET_X86_64 if (s->dflag == MO_64) { gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 0); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[reg])); gen_helper_movq_mm_T0_xmm(cpu_ptr0, cpu_T0); } else #endif { gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 0); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[reg])); tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0); gen_helper_movl_mm_T0_xmm(cpu_ptr0, cpu_tmp2_i32); } break; case 0x6f: /* movq mm, ea */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); } else { rm = (modrm & 7); tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx)); tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); } break; case 0x010: /* movups */ case 0x110: /* movupd */ case 0x028: /* movaps */ case 0x128: /* movapd */ case 0x16f: /* movdqa xmm, ea */ case 0x26f: /* movdqu xmm, ea */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { rm = (modrm & 7) | REX_B(s); gen_op_movo(offsetof(CPUX86State,xmm_regs[reg]), offsetof(CPUX86State,xmm_regs[rm])); } break; case 0x210: /* movss xmm, ea */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0))); tcg_gen_movi_tl(cpu_T0, 0); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1))); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2))); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)), offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0))); } break; case 0x310: /* movsd xmm, ea */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0))); tcg_gen_movi_tl(cpu_T0, 0); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2))); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)), offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); } break; case 0x012: /* movlps */ case 0x112: /* movlpd */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0))); } else { /* movhlps */ rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)), offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1))); } break; case 0x212: /* movsldup */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)), offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0))); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)), offsetof(CPUX86State,xmm_regs[rm].ZMM_L(2))); } gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)), offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0))); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)), offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2))); break; case 0x312: /* movddup */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)), offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); } gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)), offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0))); break; case 0x016: /* movhps */ case 0x116: /* movhpd */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1))); } else { /* movlhps */ rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1)), offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); } break; case 0x216: /* movshdup */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldo_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1)), offsetof(CPUX86State,xmm_regs[rm].ZMM_L(1))); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3)), offsetof(CPUX86State,xmm_regs[rm].ZMM_L(3))); } gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0)), offsetof(CPUX86State,xmm_regs[reg].ZMM_L(1))); gen_op_movl(offsetof(CPUX86State,xmm_regs[reg].ZMM_L(2)), offsetof(CPUX86State,xmm_regs[reg].ZMM_L(3))); break; case 0x178: case 0x378: { int bit_index, field_length; if (b1 == 1 && reg != 0) goto illegal_op; field_length = cpu_ldub_code(env, s->pc++) & 0x3F; bit_index = cpu_ldub_code(env, s->pc++) & 0x3F; tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[reg])); if (b1 == 1) gen_helper_extrq_i(cpu_env, cpu_ptr0, tcg_const_i32(bit_index), tcg_const_i32(field_length)); else gen_helper_insertq_i(cpu_env, cpu_ptr0, tcg_const_i32(bit_index), tcg_const_i32(field_length)); } break; case 0x7e: /* movd ea, mm */ #ifdef TARGET_X86_64 if (s->dflag == MO_64) { tcg_gen_ld_i64(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx)); gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1); } else #endif { tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx.MMX_L(0))); gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1); } break; case 0x17e: /* movd ea, xmm */ #ifdef TARGET_X86_64 if (s->dflag == MO_64) { tcg_gen_ld_i64(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0))); gen_ldst_modrm(env, s, modrm, MO_64, OR_TMP0, 1); } else #endif { tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0))); gen_ldst_modrm(env, s, modrm, MO_32, OR_TMP0, 1); } break; case 0x27e: /* movq xmm, ea */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)), offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); } gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1))); break; case 0x7f: /* movq ea, mm */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_stq_env_A0(s, offsetof(CPUX86State, fpregs[reg].mmx)); } else { rm = (modrm & 7); gen_op_movq(offsetof(CPUX86State,fpregs[rm].mmx), offsetof(CPUX86State,fpregs[reg].mmx)); } break; case 0x011: /* movups */ case 0x111: /* movupd */ case 0x029: /* movaps */ case 0x129: /* movapd */ case 0x17f: /* movdqa ea, xmm */ case 0x27f: /* movdqu ea, xmm */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_sto_env_A0(s, offsetof(CPUX86State, xmm_regs[reg])); } else { rm = (modrm & 7) | REX_B(s); gen_op_movo(offsetof(CPUX86State,xmm_regs[rm]), offsetof(CPUX86State,xmm_regs[reg])); } break; case 0x211: /* movss ea, xmm */ if (mod != 3) { gen_lea_modrm(env, s, modrm); tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0))); gen_op_st_v(s, MO_32, cpu_T0, cpu_A0); } else { rm = (modrm & 7) | REX_B(s); gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].ZMM_L(0)), offsetof(CPUX86State,xmm_regs[reg].ZMM_L(0))); } break; case 0x311: /* movsd ea, xmm */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_stq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)), offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0))); } break; case 0x013: /* movlps */ case 0x113: /* movlpd */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_stq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0))); } else { goto illegal_op; } break; case 0x017: /* movhps */ case 0x117: /* movhpd */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_stq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(1))); } else { goto illegal_op; } break; case 0x71: /* shift mm, im */ case 0x72: case 0x73: case 0x171: /* shift xmm, im */ case 0x172: case 0x173: if (b1 >= 2) { goto unknown_op; } val = cpu_ldub_code(env, s->pc++); if (is_xmm) { tcg_gen_movi_tl(cpu_T0, val); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0))); tcg_gen_movi_tl(cpu_T0, 0); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(1))); op1_offset = offsetof(CPUX86State,xmm_t0); } else { tcg_gen_movi_tl(cpu_T0, val); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(0))); tcg_gen_movi_tl(cpu_T0, 0); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,mmx_t0.MMX_L(1))); op1_offset = offsetof(CPUX86State,mmx_t0); } sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 + (((modrm >> 3)) & 7)][b1]; if (!sse_fn_epp) { goto unknown_op; } if (is_xmm) { rm = (modrm & 7) | REX_B(s); op2_offset = offsetof(CPUX86State,xmm_regs[rm]); } else { rm = (modrm & 7); op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); } tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op1_offset); sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); break; case 0x050: /* movmskps */ rm = (modrm & 7) | REX_B(s); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm])); gen_helper_movmskps(cpu_tmp2_i32, cpu_env, cpu_ptr0); tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32); break; case 0x150: /* movmskpd */ rm = (modrm & 7) | REX_B(s); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm])); gen_helper_movmskpd(cpu_tmp2_i32, cpu_env, cpu_ptr0); tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32); break; case 0x02a: /* cvtpi2ps */ case 0x12a: /* cvtpi2pd */ gen_helper_enter_mmx(cpu_env); if (mod != 3) { gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,mmx_t0); gen_ldq_env_A0(s, op2_offset); } else { rm = (modrm & 7); op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); } op1_offset = offsetof(CPUX86State,xmm_regs[reg]); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); switch(b >> 8) { case 0x0: gen_helper_cvtpi2ps(cpu_env, cpu_ptr0, cpu_ptr1); break; default: case 0x1: gen_helper_cvtpi2pd(cpu_env, cpu_ptr0, cpu_ptr1); break; } break; case 0x22a: /* cvtsi2ss */ case 0x32a: /* cvtsi2sd */ ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); op1_offset = offsetof(CPUX86State,xmm_regs[reg]); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); if (ot == MO_32) { SSEFunc_0_epi sse_fn_epi = sse_op_table3ai[(b >> 8) & 1]; tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0); sse_fn_epi(cpu_env, cpu_ptr0, cpu_tmp2_i32); } else { #ifdef TARGET_X86_64 SSEFunc_0_epl sse_fn_epl = sse_op_table3aq[(b >> 8) & 1]; sse_fn_epl(cpu_env, cpu_ptr0, cpu_T0); #else goto illegal_op; #endif } break; case 0x02c: /* cvttps2pi */ case 0x12c: /* cvttpd2pi */ case 0x02d: /* cvtps2pi */ case 0x12d: /* cvtpd2pi */ gen_helper_enter_mmx(cpu_env); if (mod != 3) { gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,xmm_t0); gen_ldo_env_A0(s, op2_offset); } else { rm = (modrm & 7) | REX_B(s); op2_offset = offsetof(CPUX86State,xmm_regs[rm]); } op1_offset = offsetof(CPUX86State,fpregs[reg & 7].mmx); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); switch(b) { case 0x02c: gen_helper_cvttps2pi(cpu_env, cpu_ptr0, cpu_ptr1); break; case 0x12c: gen_helper_cvttpd2pi(cpu_env, cpu_ptr0, cpu_ptr1); break; case 0x02d: gen_helper_cvtps2pi(cpu_env, cpu_ptr0, cpu_ptr1); break; case 0x12d: gen_helper_cvtpd2pi(cpu_env, cpu_ptr0, cpu_ptr1); break; } break; case 0x22c: /* cvttss2si */ case 0x32c: /* cvttsd2si */ case 0x22d: /* cvtss2si */ case 0x32d: /* cvtsd2si */ ot = mo_64_32(s->dflag); if (mod != 3) { gen_lea_modrm(env, s, modrm); if ((b >> 8) & 1) { gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_Q(0))); } else { gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0))); } op2_offset = offsetof(CPUX86State,xmm_t0); } else { rm = (modrm & 7) | REX_B(s); op2_offset = offsetof(CPUX86State,xmm_regs[rm]); } tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op2_offset); if (ot == MO_32) { SSEFunc_i_ep sse_fn_i_ep = sse_op_table3bi[((b >> 7) & 2) | (b & 1)]; sse_fn_i_ep(cpu_tmp2_i32, cpu_env, cpu_ptr0); tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32); } else { #ifdef TARGET_X86_64 SSEFunc_l_ep sse_fn_l_ep = sse_op_table3bq[((b >> 7) & 2) | (b & 1)]; sse_fn_l_ep(cpu_T0, cpu_env, cpu_ptr0); #else goto illegal_op; #endif } gen_op_mov_reg_v(ot, reg, cpu_T0); break; case 0xc4: /* pinsrw */ case 0x1c4: s->rip_offset = 1; gen_ldst_modrm(env, s, modrm, MO_16, OR_TMP0, 0); val = cpu_ldub_code(env, s->pc++); if (b1) { val &= 7; tcg_gen_st16_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[reg].ZMM_W(val))); } else { val &= 3; tcg_gen_st16_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[reg].mmx.MMX_W(val))); } break; case 0xc5: /* pextrw */ case 0x1c5: if (mod != 3) goto illegal_op; ot = mo_64_32(s->dflag); val = cpu_ldub_code(env, s->pc++); if (b1) { val &= 7; rm = (modrm & 7) | REX_B(s); tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_regs[rm].ZMM_W(val))); } else { val &= 3; rm = (modrm & 7); tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx.MMX_W(val))); } reg = ((modrm >> 3) & 7) | rex_r; gen_op_mov_reg_v(ot, reg, cpu_T0); break; case 0x1d6: /* movq ea, xmm */ if (mod != 3) { gen_lea_modrm(env, s, modrm); gen_stq_env_A0(s, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(0))); } else { rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0)), offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0))); gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(1))); } break; case 0x2d6: /* movq2dq */ gen_helper_enter_mmx(cpu_env); rm = (modrm & 7); gen_op_movq(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(0)), offsetof(CPUX86State,fpregs[rm].mmx)); gen_op_movq_env_0(offsetof(CPUX86State,xmm_regs[reg].ZMM_Q(1))); break; case 0x3d6: /* movdq2q */ gen_helper_enter_mmx(cpu_env); rm = (modrm & 7) | REX_B(s); gen_op_movq(offsetof(CPUX86State,fpregs[reg & 7].mmx), offsetof(CPUX86State,xmm_regs[rm].ZMM_Q(0))); break; case 0xd7: /* pmovmskb */ case 0x1d7: if (mod != 3) goto illegal_op; if (b1) { rm = (modrm & 7) | REX_B(s); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,xmm_regs[rm])); gen_helper_pmovmskb_xmm(cpu_tmp2_i32, cpu_env, cpu_ptr0); } else { rm = (modrm & 7); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, offsetof(CPUX86State,fpregs[rm].mmx)); gen_helper_pmovmskb_mmx(cpu_tmp2_i32, cpu_env, cpu_ptr0); } reg = ((modrm >> 3) & 7) | rex_r; tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp2_i32); break; case 0x138: case 0x038: b = modrm; if ((b & 0xf0) == 0xf0) { goto do_0f_38_fx; } modrm = cpu_ldub_code(env, s->pc++); rm = modrm & 7; reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; if (b1 >= 2) { goto unknown_op; } sse_fn_epp = sse_op_table6[b].op[b1]; if (!sse_fn_epp) { goto unknown_op; } if (!(s->cpuid_ext_features & sse_op_table6[b].ext_mask)) goto illegal_op; if (b1) { op1_offset = offsetof(CPUX86State,xmm_regs[reg]); if (mod == 3) { op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]); } else { op2_offset = offsetof(CPUX86State,xmm_t0); gen_lea_modrm(env, s, modrm); switch (b) { case 0x20: case 0x30: /* pmovsxbw, pmovzxbw */ case 0x23: case 0x33: /* pmovsxwd, pmovzxwd */ case 0x25: case 0x35: /* pmovsxdq, pmovzxdq */ gen_ldq_env_A0(s, op2_offset + offsetof(ZMMReg, ZMM_Q(0))); break; case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */ case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */ tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL); tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset + offsetof(ZMMReg, ZMM_L(0))); break; case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */ tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0, s->mem_index, MO_LEUW); tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset + offsetof(ZMMReg, ZMM_W(0))); break; case 0x2a: /* movntqda */ gen_ldo_env_A0(s, op1_offset); return; default: gen_ldo_env_A0(s, op2_offset); } } } else { op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); if (mod == 3) { op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); } else { op2_offset = offsetof(CPUX86State,mmx_t0); gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, op2_offset); } } if (sse_fn_epp == SSE_SPECIAL) { goto unknown_op; } tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); if (b == 0x17) { set_cc_op(s, CC_OP_EFLAGS); } break; case 0x238: case 0x338: do_0f_38_fx: /* Various integer extensions at 0f 38 f[0-f]. */ b = modrm | (b1 << 8); modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; switch (b) { case 0x3f0: /* crc32 Gd,Eb */ case 0x3f1: /* crc32 Gd,Ey */ do_crc32: if (!(s->cpuid_ext_features & CPUID_EXT_SSE42)) { goto illegal_op; } if ((b & 0xff) == 0xf0) { ot = MO_8; } else if (s->dflag != MO_64) { ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32); } else { ot = MO_64; } tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[reg]); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); gen_helper_crc32(cpu_T0, cpu_tmp2_i32, cpu_T0, tcg_const_i32(8 << ot)); ot = mo_64_32(s->dflag); gen_op_mov_reg_v(ot, reg, cpu_T0); break; case 0x1f0: /* crc32 or movbe */ case 0x1f1: /* For these insns, the f3 prefix is supposed to have priority over the 66 prefix, but that's not what we implement above setting b1. */ if (s->prefix & PREFIX_REPNZ) { goto do_crc32; } /* FALLTHRU */ case 0x0f0: /* movbe Gy,My */ case 0x0f1: /* movbe My,Gy */ if (!(s->cpuid_ext_features & CPUID_EXT_MOVBE)) { goto illegal_op; } if (s->dflag != MO_64) { ot = (s->prefix & PREFIX_DATA ? MO_16 : MO_32); } else { ot = MO_64; } gen_lea_modrm(env, s, modrm); if ((b & 1) == 0) { tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0, s->mem_index, ot | MO_BE); gen_op_mov_reg_v(ot, reg, cpu_T0); } else { tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0, s->mem_index, ot | MO_BE); } break; case 0x0f2: /* andn Gy, By, Ey */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); tcg_gen_andc_tl(cpu_T0, cpu_regs[s->vex_v], cpu_T0); gen_op_mov_reg_v(ot, reg, cpu_T0); gen_op_update1_cc(); set_cc_op(s, CC_OP_LOGICB + ot); break; case 0x0f7: /* bextr Gy, Ey, By */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); { TCGv bound, zero; gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); /* Extract START, and shift the operand. Shifts larger than operand size get zeros. */ tcg_gen_ext8u_tl(cpu_A0, cpu_regs[s->vex_v]); tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_A0); bound = tcg_const_tl(ot == MO_64 ? 63 : 31); zero = tcg_const_tl(0); tcg_gen_movcond_tl(TCG_COND_LEU, cpu_T0, cpu_A0, bound, cpu_T0, zero); tcg_temp_free(zero); /* Extract the LEN into a mask. Lengths larger than operand size get all ones. */ tcg_gen_extract_tl(cpu_A0, cpu_regs[s->vex_v], 8, 8); tcg_gen_movcond_tl(TCG_COND_LEU, cpu_A0, cpu_A0, bound, cpu_A0, bound); tcg_temp_free(bound); tcg_gen_movi_tl(cpu_T1, 1); tcg_gen_shl_tl(cpu_T1, cpu_T1, cpu_A0); tcg_gen_subi_tl(cpu_T1, cpu_T1, 1); tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); gen_op_mov_reg_v(ot, reg, cpu_T0); gen_op_update1_cc(); set_cc_op(s, CC_OP_LOGICB + ot); } break; case 0x0f5: /* bzhi Gy, Ey, By */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); tcg_gen_ext8u_tl(cpu_T1, cpu_regs[s->vex_v]); { TCGv bound = tcg_const_tl(ot == MO_64 ? 63 : 31); /* Note that since we're using BMILG (in order to get O cleared) we need to store the inverse into C. */ tcg_gen_setcond_tl(TCG_COND_LT, cpu_cc_src, cpu_T1, bound); tcg_gen_movcond_tl(TCG_COND_GT, cpu_T1, cpu_T1, bound, bound, cpu_T1); tcg_temp_free(bound); } tcg_gen_movi_tl(cpu_A0, -1); tcg_gen_shl_tl(cpu_A0, cpu_A0, cpu_T1); tcg_gen_andc_tl(cpu_T0, cpu_T0, cpu_A0); gen_op_mov_reg_v(ot, reg, cpu_T0); gen_op_update1_cc(); set_cc_op(s, CC_OP_BMILGB + ot); break; case 0x3f6: /* mulx By, Gy, rdx, Ey */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); switch (ot) { default: tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0); tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]); tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32, cpu_tmp2_i32, cpu_tmp3_i32); tcg_gen_extu_i32_tl(cpu_regs[s->vex_v], cpu_tmp2_i32); tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32); break; #ifdef TARGET_X86_64 case MO_64: tcg_gen_mulu2_i64(cpu_T0, cpu_T1, cpu_T0, cpu_regs[R_EDX]); tcg_gen_mov_i64(cpu_regs[s->vex_v], cpu_T0); tcg_gen_mov_i64(cpu_regs[reg], cpu_T1); break; #endif } break; case 0x3f5: /* pdep Gy, By, Ey */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); /* Note that by zero-extending the mask operand, we automatically handle zero-extending the result. */ if (ot == MO_64) { tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]); } else { tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]); } gen_helper_pdep(cpu_regs[reg], cpu_T0, cpu_T1); break; case 0x2f5: /* pext Gy, By, Ey */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); /* Note that by zero-extending the mask operand, we automatically handle zero-extending the result. */ if (ot == MO_64) { tcg_gen_mov_tl(cpu_T1, cpu_regs[s->vex_v]); } else { tcg_gen_ext32u_tl(cpu_T1, cpu_regs[s->vex_v]); } gen_helper_pext(cpu_regs[reg], cpu_T0, cpu_T1); break; case 0x1f6: /* adcx Gy, Ey */ case 0x2f6: /* adox Gy, Ey */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_ADX)) { goto illegal_op; } else { TCGv carry_in, carry_out, zero; int end_op; ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); /* Re-use the carry-out from a previous round. */ TCGV_UNUSED(carry_in); carry_out = (b == 0x1f6 ? cpu_cc_dst : cpu_cc_src2); switch (s->cc_op) { case CC_OP_ADCX: if (b == 0x1f6) { carry_in = cpu_cc_dst; end_op = CC_OP_ADCX; } else { end_op = CC_OP_ADCOX; } break; case CC_OP_ADOX: if (b == 0x1f6) { end_op = CC_OP_ADCOX; } else { carry_in = cpu_cc_src2; end_op = CC_OP_ADOX; } break; case CC_OP_ADCOX: end_op = CC_OP_ADCOX; carry_in = carry_out; break; default: end_op = (b == 0x1f6 ? CC_OP_ADCX : CC_OP_ADOX); break; } /* If we can't reuse carry-out, get it out of EFLAGS. */ if (TCGV_IS_UNUSED(carry_in)) { if (s->cc_op != CC_OP_ADCX && s->cc_op != CC_OP_ADOX) { gen_compute_eflags(s); } carry_in = cpu_tmp0; tcg_gen_extract_tl(carry_in, cpu_cc_src, ctz32(b == 0x1f6 ? CC_C : CC_O), 1); } switch (ot) { #ifdef TARGET_X86_64 case MO_32: /* If we know TL is 64-bit, and we want a 32-bit result, just do everything in 64-bit arithmetic. */ tcg_gen_ext32u_i64(cpu_regs[reg], cpu_regs[reg]); tcg_gen_ext32u_i64(cpu_T0, cpu_T0); tcg_gen_add_i64(cpu_T0, cpu_T0, cpu_regs[reg]); tcg_gen_add_i64(cpu_T0, cpu_T0, carry_in); tcg_gen_ext32u_i64(cpu_regs[reg], cpu_T0); tcg_gen_shri_i64(carry_out, cpu_T0, 32); break; #endif default: /* Otherwise compute the carry-out in two steps. */ zero = tcg_const_tl(0); tcg_gen_add2_tl(cpu_T0, carry_out, cpu_T0, zero, carry_in, zero); tcg_gen_add2_tl(cpu_regs[reg], carry_out, cpu_regs[reg], carry_out, cpu_T0, zero); tcg_temp_free(zero); break; } set_cc_op(s, end_op); } break; case 0x1f7: /* shlx Gy, Ey, By */ case 0x2f7: /* sarx Gy, Ey, By */ case 0x3f7: /* shrx Gy, Ey, By */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); if (ot == MO_64) { tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 63); } else { tcg_gen_andi_tl(cpu_T1, cpu_regs[s->vex_v], 31); } if (b == 0x1f7) { tcg_gen_shl_tl(cpu_T0, cpu_T0, cpu_T1); } else if (b == 0x2f7) { if (ot != MO_64) { tcg_gen_ext32s_tl(cpu_T0, cpu_T0); } tcg_gen_sar_tl(cpu_T0, cpu_T0, cpu_T1); } else { if (ot != MO_64) { tcg_gen_ext32u_tl(cpu_T0, cpu_T0); } tcg_gen_shr_tl(cpu_T0, cpu_T0, cpu_T1); } gen_op_mov_reg_v(ot, reg, cpu_T0); break; case 0x0f3: case 0x1f3: case 0x2f3: case 0x3f3: /* Group 17 */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI1) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); switch (reg & 7) { case 1: /* blsr By,Ey */ tcg_gen_neg_tl(cpu_T1, cpu_T0); tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_T1); gen_op_mov_reg_v(ot, s->vex_v, cpu_T0); gen_op_update2_cc(); set_cc_op(s, CC_OP_BMILGB + ot); break; case 2: /* blsmsk By,Ey */ tcg_gen_mov_tl(cpu_cc_src, cpu_T0); tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); tcg_gen_xor_tl(cpu_T0, cpu_T0, cpu_cc_src); tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); set_cc_op(s, CC_OP_BMILGB + ot); break; case 3: /* blsi By, Ey */ tcg_gen_mov_tl(cpu_cc_src, cpu_T0); tcg_gen_subi_tl(cpu_T0, cpu_T0, 1); tcg_gen_and_tl(cpu_T0, cpu_T0, cpu_cc_src); tcg_gen_mov_tl(cpu_cc_dst, cpu_T0); set_cc_op(s, CC_OP_BMILGB + ot); break; default: goto unknown_op; } break; default: goto unknown_op; } break; case 0x03a: case 0x13a: b = modrm; modrm = cpu_ldub_code(env, s->pc++); rm = modrm & 7; reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; if (b1 >= 2) { goto unknown_op; } sse_fn_eppi = sse_op_table7[b].op[b1]; if (!sse_fn_eppi) { goto unknown_op; } if (!(s->cpuid_ext_features & sse_op_table7[b].ext_mask)) goto illegal_op; s->rip_offset = 1; if (sse_fn_eppi == SSE_SPECIAL) { ot = mo_64_32(s->dflag); rm = (modrm & 7) | REX_B(s); if (mod != 3) gen_lea_modrm(env, s, modrm); reg = ((modrm >> 3) & 7) | rex_r; val = cpu_ldub_code(env, s->pc++); switch (b) { case 0x14: /* pextrb */ tcg_gen_ld8u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_B(val & 15))); if (mod == 3) { gen_op_mov_reg_v(ot, rm, cpu_T0); } else { tcg_gen_qemu_st_tl(cpu_T0, cpu_A0, s->mem_index, MO_UB); } break; case 0x15: /* pextrw */ tcg_gen_ld16u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_W(val & 7))); if (mod == 3) { gen_op_mov_reg_v(ot, rm, cpu_T0); } else { tcg_gen_qemu_st_tl(cpu_T0, cpu_A0, s->mem_index, MO_LEUW); } break; case 0x16: if (ot == MO_32) { /* pextrd */ tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(val & 3))); if (mod == 3) { tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32); } else { tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL); } } else { /* pextrq */ #ifdef TARGET_X86_64 tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(val & 1))); if (mod == 3) { tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64); } else { tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ); } #else goto illegal_op; #endif } break; case 0x17: /* extractps */ tcg_gen_ld32u_tl(cpu_T0, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(val & 3))); if (mod == 3) { gen_op_mov_reg_v(ot, rm, cpu_T0); } else { tcg_gen_qemu_st_tl(cpu_T0, cpu_A0, s->mem_index, MO_LEUL); } break; case 0x20: /* pinsrb */ if (mod == 3) { gen_op_mov_v_reg(MO_32, cpu_T0, rm); } else { tcg_gen_qemu_ld_tl(cpu_T0, cpu_A0, s->mem_index, MO_UB); } tcg_gen_st8_tl(cpu_T0, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_B(val & 15))); break; case 0x21: /* insertps */ if (mod == 3) { tcg_gen_ld_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State,xmm_regs[rm] .ZMM_L((val >> 6) & 3))); } else { tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL); } tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State,xmm_regs[reg] .ZMM_L((val >> 4) & 3))); if ((val >> 0) & 1) tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(0))); if ((val >> 1) & 1) tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(1))); if ((val >> 2) & 1) tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(2))); if ((val >> 3) & 1) tcg_gen_st_i32(tcg_const_i32(0 /*float32_zero*/), cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(3))); break; case 0x22: if (ot == MO_32) { /* pinsrd */ if (mod == 3) { tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]); } else { tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUL); } tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_L(val & 3))); } else { /* pinsrq */ #ifdef TARGET_X86_64 if (mod == 3) { gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm); } else { tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ); } tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offsetof(CPUX86State, xmm_regs[reg].ZMM_Q(val & 1))); #else goto illegal_op; #endif } break; } return; } if (b1) { op1_offset = offsetof(CPUX86State,xmm_regs[reg]); if (mod == 3) { op2_offset = offsetof(CPUX86State,xmm_regs[rm | REX_B(s)]); } else { op2_offset = offsetof(CPUX86State,xmm_t0); gen_lea_modrm(env, s, modrm); gen_ldo_env_A0(s, op2_offset); } } else { op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); if (mod == 3) { op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); } else { op2_offset = offsetof(CPUX86State,mmx_t0); gen_lea_modrm(env, s, modrm); gen_ldq_env_A0(s, op2_offset); } } val = cpu_ldub_code(env, s->pc++); if ((b & 0xfc) == 0x60) { /* pcmpXstrX */ set_cc_op(s, CC_OP_EFLAGS); if (s->dflag == MO_64) { /* The helper must use entire 64-bit gp registers */ val |= 1 << 8; } } tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); sse_fn_eppi(cpu_env, cpu_ptr0, cpu_ptr1, tcg_const_i32(val)); break; case 0x33a: /* Various integer extensions at 0f 3a f[0-f]. */ b = modrm | (b1 << 8); modrm = cpu_ldub_code(env, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; switch (b) { case 0x3f0: /* rorx Gy,Ey, Ib */ if (!(s->cpuid_7_0_ebx_features & CPUID_7_0_EBX_BMI2) || !(s->prefix & PREFIX_VEX) || s->vex_l != 0) { goto illegal_op; } ot = mo_64_32(s->dflag); gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0); b = cpu_ldub_code(env, s->pc++); if (ot == MO_64) { tcg_gen_rotri_tl(cpu_T0, cpu_T0, b & 63); } else { tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0); tcg_gen_rotri_i32(cpu_tmp2_i32, cpu_tmp2_i32, b & 31); tcg_gen_extu_i32_tl(cpu_T0, cpu_tmp2_i32); } gen_op_mov_reg_v(ot, reg, cpu_T0); break; default: goto unknown_op; } break; default: unknown_op: gen_unknown_opcode(env, s); return; } } else { /* generic MMX or SSE operation */ switch(b) { case 0x70: /* pshufx insn */ case 0xc6: /* pshufx insn */ case 0xc2: /* compare insns */ s->rip_offset = 1; break; default: break; } if (is_xmm) { op1_offset = offsetof(CPUX86State,xmm_regs[reg]); if (mod != 3) { int sz = 4; gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,xmm_t0); switch (b) { case 0x50 ... 0x5a: case 0x5c ... 0x5f: case 0xc2: /* Most sse scalar operations. */ if (b1 == 2) { sz = 2; } else if (b1 == 3) { sz = 3; } break; case 0x2e: /* ucomis[sd] */ case 0x2f: /* comis[sd] */ if (b1 == 0) { sz = 2; } else { sz = 3; } break; } switch (sz) { case 2: /* 32 bit access */ gen_op_ld_v(s, MO_32, cpu_T0, cpu_A0); tcg_gen_st32_tl(cpu_T0, cpu_env, offsetof(CPUX86State,xmm_t0.ZMM_L(0))); break; case 3: /* 64 bit access */ gen_ldq_env_A0(s, offsetof(CPUX86State, xmm_t0.ZMM_D(0))); break; default: /* 128 bit access */ gen_ldo_env_A0(s, op2_offset); break; } } else { rm = (modrm & 7) | REX_B(s); op2_offset = offsetof(CPUX86State,xmm_regs[rm]); } } else { op1_offset = offsetof(CPUX86State,fpregs[reg].mmx); if (mod != 3) { gen_lea_modrm(env, s, modrm); op2_offset = offsetof(CPUX86State,mmx_t0); gen_ldq_env_A0(s, op2_offset); } else { rm = (modrm & 7); op2_offset = offsetof(CPUX86State,fpregs[rm].mmx); } } switch(b) { case 0x0f: /* 3DNow! data insns */ val = cpu_ldub_code(env, s->pc++); sse_fn_epp = sse_op_table5[val]; if (!sse_fn_epp) { goto unknown_op; } if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) { goto illegal_op; } tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); break; case 0x70: /* pshufx insn */ case 0xc6: /* pshufx insn */ val = cpu_ldub_code(env, s->pc++); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); /* XXX: introduce a new table? */ sse_fn_ppi = (SSEFunc_0_ppi)sse_fn_epp; sse_fn_ppi(cpu_ptr0, cpu_ptr1, tcg_const_i32(val)); break; case 0xc2: /* compare insns */ val = cpu_ldub_code(env, s->pc++); if (val >= 8) goto unknown_op; sse_fn_epp = sse_op_table4[val][b1]; tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); break; case 0xf7: /* maskmov : we must prepare A0 */ if (mod != 3) goto illegal_op; tcg_gen_mov_tl(cpu_A0, cpu_regs[R_EDI]); gen_extu(s->aflag, cpu_A0); gen_add_A0_ds_seg(s); tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); /* XXX: introduce a new table? */ sse_fn_eppt = (SSEFunc_0_eppt)sse_fn_epp; sse_fn_eppt(cpu_env, cpu_ptr0, cpu_ptr1, cpu_A0); break; default: tcg_gen_addi_ptr(cpu_ptr0, cpu_env, op1_offset); tcg_gen_addi_ptr(cpu_ptr1, cpu_env, op2_offset); sse_fn_epp(cpu_env, cpu_ptr0, cpu_ptr1); break; } if (b == 0x2e || b == 0x2f) { set_cc_op(s, CC_OP_EFLAGS); } } }


void kvmppc_check_papr_resize_hpt(Error **errp) { if (!kvm_enabled()) { return; } /* TODO: Check for resize-capable KVM implementations */ error_setg(errp, "Hash page table resizing not available with this KVM version"); }


static void v9fs_walk(void *opaque) { int name_idx; V9fsQID *qids = NULL; int i, err = 0; V9fsPath dpath, path; uint16_t nwnames; struct stat stbuf; size_t offset = 7; int32_t fid, newfid; V9fsString *wnames = NULL; V9fsFidState *fidp; V9fsFidState *newfidp = NULL; V9fsPDU *pdu = opaque; V9fsState *s = pdu->s; offset += pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames); trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames); if (nwnames && nwnames <= P9_MAXWELEM) { wnames = g_malloc0(sizeof(wnames[0]) * nwnames); qids = g_malloc0(sizeof(qids[0]) * nwnames); for (i = 0; i < nwnames; i++) { offset += pdu_unmarshal(pdu, offset, "s", &wnames[i]); } } else if (nwnames > P9_MAXWELEM) { err = -EINVAL; goto out_nofid; } fidp = get_fid(pdu, fid); if (fidp == NULL) { err = -ENOENT; goto out_nofid; } v9fs_path_init(&dpath); v9fs_path_init(&path); /* * Both dpath and path initially poin to fidp. * Needed to handle request with nwnames == 0 */ v9fs_path_copy(&dpath, &fidp->path); v9fs_path_copy(&path, &fidp->path); for (name_idx = 0; name_idx < nwnames; name_idx++) { err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path); if (err < 0) { goto out; } err = v9fs_co_lstat(pdu, &path, &stbuf); if (err < 0) { goto out; } stat_to_qid(&stbuf, &qids[name_idx]); v9fs_path_copy(&dpath, &path); } if (fid == newfid) { BUG_ON(fidp->fid_type != P9_FID_NONE); v9fs_path_copy(&fidp->path, &path); } else { newfidp = alloc_fid(s, newfid); if (newfidp == NULL) { err = -EINVAL; goto out; } newfidp->uid = fidp->uid; v9fs_path_copy(&newfidp->path, &path); } err = v9fs_walk_marshal(pdu, nwnames, qids); trace_v9fs_walk_return(pdu->tag, pdu->id, nwnames, qids); out: put_fid(pdu, fidp); if (newfidp) { put_fid(pdu, newfidp); } v9fs_path_free(&dpath); v9fs_path_free(&path); out_nofid: complete_pdu(s, pdu, err); if (nwnames && nwnames <= P9_MAXWELEM) { for (name_idx = 0; name_idx < nwnames; name_idx++) { v9fs_string_free(&wnames[name_idx]); } g_free(wnames); g_free(qids); } return; }


static int mmu_translate_pte(CPUS390XState *env, target_ulong vaddr, uint64_t asc, uint64_t pt_entry, target_ulong *raddr, int *flags, int rw, bool exc) { if (pt_entry & _PAGE_INVALID) { DPRINTF("%s: PTE=0x%" PRIx64 " invalid\n", __func__, pt_entry); trigger_page_fault(env, vaddr, PGM_PAGE_TRANS, asc, rw, exc); return -1; } if (pt_entry & _PAGE_RO) { *flags &= ~PAGE_WRITE; } *raddr = pt_entry & _ASCE_ORIGIN; PTE_DPRINTF("%s: PTE=0x%" PRIx64 "\n", __func__, pt_entry); return 0; }


static void dbdma_cmdptr_load(DBDMA_channel *ch) { DBDMA_DPRINTF("dbdma_cmdptr_load 0x%08x\n", be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO])); cpu_physical_memory_read(be32_to_cpu(ch->regs[DBDMA_CMDPTR_LO]), (uint8_t*)&ch->current, sizeof(dbdma_cmd)); }


static int img_check(int argc, char **argv) { int c, ret; const char *filename, *fmt; BlockDriverState *bs; BdrvCheckResult result; int fix = 0; int flags = BDRV_O_FLAGS; fmt = NULL; for(;;) { c = getopt(argc, argv, "f:hr:"); if (c == -1) { break; } switch(c) { case '?': case 'h': help(); break; case 'f': fmt = optarg; break; case 'r': flags |= BDRV_O_RDWR; if (!strcmp(optarg, "leaks")) { fix = BDRV_FIX_LEAKS; } else if (!strcmp(optarg, "all")) { fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS; } else { help(); } break; } } if (optind >= argc) { help(); } filename = argv[optind++]; bs = bdrv_new_open(filename, fmt, flags); if (!bs) { return 1; } ret = bdrv_check(bs, &result, fix); if (ret == -ENOTSUP) { error_report("This image format does not support checks"); bdrv_delete(bs); return 1; } if (result.corruptions_fixed || result.leaks_fixed) { printf("The following inconsistencies were found and repaired:\n\n" " %d leaked clusters\n" " %d corruptions\n\n" "Double checking the fixed image now...\n", result.leaks_fixed, result.corruptions_fixed); ret = bdrv_check(bs, &result, 0); } if (!(result.corruptions || result.leaks || result.check_errors)) { printf("No errors were found on the image.\n"); } else { if (result.corruptions) { printf("\n%d errors were found on the image.\n" "Data may be corrupted, or further writes to the image " "may corrupt it.\n", result.corruptions); } if (result.leaks) { printf("\n%d leaked clusters were found on the image.\n" "This means waste of disk space, but no harm to data.\n", result.leaks); } if (result.check_errors) { printf("\n%d internal errors have occurred during the check.\n", result.check_errors); } } if (result.bfi.total_clusters != 0 && result.bfi.allocated_clusters != 0) { printf("%" PRId64 "/%" PRId64 "= %0.2f%% allocated, %0.2f%% fragmented\n", result.bfi.allocated_clusters, result.bfi.total_clusters, result.bfi.allocated_clusters * 100.0 / result.bfi.total_clusters, result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters); } bdrv_delete(bs); if (ret < 0 || result.check_errors) { printf("\nAn error has occurred during the check: %s\n" "The check is not complete and may have missed error.\n", strerror(-ret)); return 1; } if (result.corruptions) { return 2; } else if (result.leaks) { return 3; } else { return 0; } }


static void decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx, PTLCommon *ptl) { int i; ptl->profile_space = get_bits(gb, 2); ptl->tier_flag = get_bits1(gb); ptl->profile_idc = get_bits(gb, 5); if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN) av_log(avctx, AV_LOG_DEBUG, "Main profile bitstream\n"); else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10) av_log(avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n"); else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE) av_log(avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n"); else av_log(avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc); for (i = 0; i < 32; i++) ptl->profile_compatibility_flag[i] = get_bits1(gb); ptl->progressive_source_flag = get_bits1(gb); ptl->interlaced_source_flag = get_bits1(gb); ptl->non_packed_constraint_flag = get_bits1(gb); ptl->frame_only_constraint_flag = get_bits1(gb); skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15] skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31] skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43] }


xen_igd_passthrough_isa_bridge_create(XenPCIPassthroughState *s, XenHostPCIDevice *dev) { uint16_t gpu_dev_id; PCIDevice *d = &s->dev; gpu_dev_id = dev->device_id; igd_passthrough_isa_bridge_create(d->bus, gpu_dev_id); }


qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num, enum xics_irq_type type) { uint32_t irq; qemu_irq qirq; if (hint) { irq = hint; /* FIXME: we should probably check for collisions somehow */ } else { irq = spapr->next_irq++; } qirq = xics_assign_irq(spapr->icp, irq, type); if (!qirq) { return NULL; } if (irq_num) { *irq_num = irq; } return qirq; }


static void omap_mcbsp_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size) { switch (size) { case 2: return omap_mcbsp_writeh(opaque, addr, value); case 4: return omap_mcbsp_writew(opaque, addr, value); default: return omap_badwidth_write16(opaque, addr, value); } }


vnc_display_setup_auth(VncDisplay *vs, bool password, bool sasl, bool tls, bool x509) { /* * We have a choice of 3 authentication options * * 1. none * 2. vnc * 3. sasl * * The channel can be run in 2 modes * * 1. clear * 2. tls * * And TLS can use 2 types of credentials * * 1. anon * 2. x509 * * We thus have 9 possible logical combinations * * 1. clear + none * 2. clear + vnc * 3. clear + sasl * 4. tls + anon + none * 5. tls + anon + vnc * 6. tls + anon + sasl * 7. tls + x509 + none * 8. tls + x509 + vnc * 9. tls + x509 + sasl * * These need to be mapped into the VNC auth schemes * in an appropriate manner. In regular VNC, all the * TLS options get mapped into VNC_AUTH_VENCRYPT * sub-auth types. */ if (password) { if (tls) { vs->auth = VNC_AUTH_VENCRYPT; if (x509) { VNC_DEBUG("Initializing VNC server with x509 password auth\n"); vs->subauth = VNC_AUTH_VENCRYPT_X509VNC; } else { VNC_DEBUG("Initializing VNC server with TLS password auth\n"); vs->subauth = VNC_AUTH_VENCRYPT_TLSVNC; } } else { VNC_DEBUG("Initializing VNC server with password auth\n"); vs->auth = VNC_AUTH_VNC; vs->subauth = VNC_AUTH_INVALID; } } else if (sasl) { if (tls) { vs->auth = VNC_AUTH_VENCRYPT; if (x509) { VNC_DEBUG("Initializing VNC server with x509 SASL auth\n"); vs->subauth = VNC_AUTH_VENCRYPT_X509SASL; } else { VNC_DEBUG("Initializing VNC server with TLS SASL auth\n"); vs->subauth = VNC_AUTH_VENCRYPT_TLSSASL; } } else { VNC_DEBUG("Initializing VNC server with SASL auth\n"); vs->auth = VNC_AUTH_SASL; vs->subauth = VNC_AUTH_INVALID; } } else { if (tls) { vs->auth = VNC_AUTH_VENCRYPT; if (x509) { VNC_DEBUG("Initializing VNC server with x509 no auth\n"); vs->subauth = VNC_AUTH_VENCRYPT_X509NONE; } else { VNC_DEBUG("Initializing VNC server with TLS no auth\n"); vs->subauth = VNC_AUTH_VENCRYPT_TLSNONE; } } else { VNC_DEBUG("Initializing VNC server with no auth\n"); vs->auth = VNC_AUTH_NONE; vs->subauth = VNC_AUTH_INVALID; } } }


void usb_info(Monitor *mon) { USBBus *bus; USBDevice *dev; USBPort *port; if (TAILQ_EMPTY(&busses)) { monitor_printf(mon, "USB support not enabled\n"); return; } TAILQ_FOREACH(bus, &busses, next) { TAILQ_FOREACH(port, &bus->used, next) { dev = port->dev; if (!dev) continue; monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n", bus->busnr, dev->addr, usb_speed(dev->speed), dev->devname); } } }


void tcg_gen_brcond_i64(TCGCond cond, TCGv_i64 arg1, TCGv_i64 arg2, int label) { if (cond == TCG_COND_ALWAYS) { tcg_gen_br(label); } else if (cond != TCG_COND_NEVER) { if (TCG_TARGET_REG_BITS == 32) { tcg_gen_op6ii_i32(INDEX_op_brcond2_i32, TCGV_LOW(arg1), TCGV_HIGH(arg1), TCGV_LOW(arg2), TCGV_HIGH(arg2), cond, label); } else { tcg_gen_op4ii_i64(INDEX_op_brcond_i64, arg1, arg2, cond, label); } } }


static QList *channel_list_get(void) { return NULL; }


static int ssd0323_init(SSISlave *dev) { ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev); s->col_end = 63; s->row_end = 79; s->con = graphic_console_init(ssd0323_update_display, ssd0323_invalidate_display, NULL, NULL, s); qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY); qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1); register_savevm(&dev->qdev, "ssd0323_oled", -1, 1, ssd0323_save, ssd0323_load, s); return 0; }


static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors, int sector_size) { s->lba = lba; s->packet_transfer_size = nb_sectors * sector_size; s->elementary_transfer_size = 0; s->io_buffer_index = sector_size; s->cd_sector_size = sector_size; s->status = READY_STAT; ide_atapi_cmd_reply_end(s); }


static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val) { PCIXenPlatformState *s = opaque; switch (addr) { case 0: { PCIDevice *pci_dev = PCI_DEVICE(s); /* Unplug devices. Value is a bitmask of which devices to unplug, with bit 0 the disk devices, bit 1 the network devices, and bit 2 the non-primary-master IDE devices. */ if (val & UNPLUG_ALL_DISKS) { DPRINTF("unplug disks\n"); pci_unplug_disks(pci_dev->bus); } if (val & UNPLUG_ALL_NICS) { DPRINTF("unplug nics\n"); pci_unplug_nics(pci_dev->bus); } if (val & UNPLUG_AUX_IDE_DISKS) { DPRINTF("unplug auxiliary disks not supported\n"); } break; } case 2: switch (val) { case 1: DPRINTF("Citrix Windows PV drivers loaded in guest\n"); break; case 0: DPRINTF("Guest claimed to be running PV product 0?\n"); break; default: DPRINTF("Unknown PV product %d loaded in guest\n", val); break; } s->driver_product_version = val; break; } }


static int xen_pt_msgctrl_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry, uint16_t *val, uint16_t dev_value, uint16_t valid_mask) { XenPTRegInfo *reg = cfg_entry->reg; XenPTMSI *msi = s->msi; uint16_t writable_mask = 0; uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); /* Currently no support for multi-vector */ if (*val & PCI_MSI_FLAGS_QSIZE) { XEN_PT_WARN(&s->dev, "Tries to set more than 1 vector ctrl %x\n", *val); } /* modify emulate register */ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE; /* create value for writing to I/O device register */ *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); /* update MSI */ if (*val & PCI_MSI_FLAGS_ENABLE) { /* setup MSI pirq for the first time */ if (!msi->initialized) { /* Init physical one */ XEN_PT_LOG(&s->dev, "setup MSI (register: %x).\n", *val); if (xen_pt_msi_setup(s)) { /* We do not broadcast the error to the framework code, so * that MSI errors are contained in MSI emulation code and * QEMU can go on running. * Guest MSI would be actually not working. */ *val &= ~PCI_MSI_FLAGS_ENABLE; XEN_PT_WARN(&s->dev, "Can not map MSI (register: %x)!\n", *val); return 0; } if (xen_pt_msi_update(s)) { *val &= ~PCI_MSI_FLAGS_ENABLE; XEN_PT_WARN(&s->dev, "Can not bind MSI (register: %x)!\n", *val); return 0; } msi->initialized = true; msi->mapped = true; } msi->flags |= PCI_MSI_FLAGS_ENABLE; } else if (msi->mapped) { xen_pt_msi_disable(s); } return 0; }


static void qcow2_refresh_limits(BlockDriverState *bs, Error **errp) { BDRVQcow2State *s = bs->opaque; if (bs->encrypted) { /* Encryption works on a sector granularity */ bs->request_alignment = BDRV_SECTOR_SIZE; } bs->bl.pwrite_zeroes_alignment = s->cluster_size; }


static void set_string(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); Property *prop = opaque; char **ptr = qdev_get_prop_ptr(dev, prop); Error *local_err = NULL; char *str; if (dev->realized) { qdev_prop_set_after_realize(dev, name, errp); return; } visit_type_str(v, &str, name, &local_err); if (local_err) { error_propagate(errp, local_err); return; } if (*ptr) { g_free(*ptr); } *ptr = str; }


void OPPROTO op_idivb_AL_T0(void) { int num, den, q, r; num = (int16_t)EAX; den = (int8_t)T0; if (den == 0) { raise_exception(EXCP00_DIVZ); } q = (num / den) & 0xff; r = (num % den) & 0xff; EAX = (EAX & ~0xffff) | (r << 8) | q; }


static int print_uint8(DeviceState *dev, Property *prop, char *dest, size_t len) { uint8_t *ptr = qdev_get_prop_ptr(dev, prop); return snprintf(dest, len, "%" PRIu8, *ptr); }


static int init_image(TiffContext *s, ThreadFrame *frame) { int ret; switch (s->planar * 1000 + s->bpp * 10 + s->bppcount) { case 11: if (!s->palette_is_set) { s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; break; } case 21: case 41: case 81: s->avctx->pix_fmt = s->palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8; break; case 243: if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) { if (s->subsampling[0] == 1 && s->subsampling[1] == 1) { s->avctx->pix_fmt = AV_PIX_FMT_YUV444P; } else if (s->subsampling[0] == 2 && s->subsampling[1] == 1) { s->avctx->pix_fmt = AV_PIX_FMT_YUV422P; } else if (s->subsampling[0] == 4 && s->subsampling[1] == 1) { s->avctx->pix_fmt = AV_PIX_FMT_YUV411P; } else if (s->subsampling[0] == 1 && s->subsampling[1] == 2) { s->avctx->pix_fmt = AV_PIX_FMT_YUV440P; } else if (s->subsampling[0] == 2 && s->subsampling[1] == 2) { s->avctx->pix_fmt = AV_PIX_FMT_YUV420P; } else if (s->subsampling[0] == 4 && s->subsampling[1] == 4) { s->avctx->pix_fmt = AV_PIX_FMT_YUV410P; } else { av_log(s->avctx, AV_LOG_ERROR, "Unsupported YCbCr subsampling\n"); return AVERROR_PATCHWELCOME; } } else s->avctx->pix_fmt = AV_PIX_FMT_RGB24; break; case 161: s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GRAY16LE : AV_PIX_FMT_GRAY16BE; break; case 162: s->avctx->pix_fmt = AV_PIX_FMT_YA8; break; case 322: s->avctx->pix_fmt = s->le ? AV_PIX_FMT_YA16LE : AV_PIX_FMT_YA16BE; break; case 324: s->avctx->pix_fmt = AV_PIX_FMT_RGBA; break; case 483: s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE; break; case 644: s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE; break; case 1243: s->avctx->pix_fmt = AV_PIX_FMT_GBRP; break; case 1324: s->avctx->pix_fmt = AV_PIX_FMT_GBRAP; break; case 1483: s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE; break; case 1644: s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE; break; default: av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, bppcount=%d)\n", s->bpp, s->bppcount); return AVERROR_INVALIDDATA; } if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); if((desc->flags & AV_PIX_FMT_FLAG_RGB) || desc->nb_components < 3) { av_log(s->avctx, AV_LOG_ERROR, "Unsupported YCbCr variant\n"); return AVERROR_INVALIDDATA; } } if (s->width != s->avctx->width || s->height != s->avctx->height) { ret = ff_set_dimensions(s->avctx, s->width, s->height); if (ret < 0) return ret; } if ((ret = ff_thread_get_buffer(s->avctx, frame, 0)) < 0) return ret; if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) { memcpy(frame->f->data[1], s->palette, sizeof(s->palette)); } return 0; }


static int connect_to_sdog(const char *addr, const char *port) { char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; int fd, ret; struct addrinfo hints, *res, *res0; if (!addr) { addr = SD_DEFAULT_ADDR; port = SD_DEFAULT_PORT; } memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; ret = getaddrinfo(addr, port, &hints, &res0); if (ret) { error_report("unable to get address info %s, %s", addr, strerror(errno)); return -errno; } for (res = res0; res; res = res->ai_next) { ret = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV); if (ret) { continue; } fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd < 0) { continue; } reconnect: ret = connect(fd, res->ai_addr, res->ai_addrlen); if (ret < 0) { if (errno == EINTR) { goto reconnect; } break; } dprintf("connected to %s:%s\n", addr, port); goto success; } fd = -errno; error_report("failed connect to %s:%s", addr, port); success: freeaddrinfo(res0); return fd; }


int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, AVPacket *avpkt) { AVFrame frame; int ret, got_frame = 0; if (avctx->get_buffer != avcodec_default_get_buffer) { av_log(avctx, AV_LOG_ERROR, "A custom get_buffer() cannot be used with " "avcodec_decode_audio3()\n"); return AVERROR(EINVAL); } ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt); if (ret >= 0 && got_frame) { int ch, plane_size; int planar = av_sample_fmt_is_planar(avctx->sample_fmt); int data_size = av_samples_get_buffer_size(&plane_size, avctx->channels, frame.nb_samples, avctx->sample_fmt, 1); if (*frame_size_ptr < data_size) { av_log(avctx, AV_LOG_ERROR, "output buffer size is too small for " "the current frame (%d < %d)\n", *frame_size_ptr, data_size); return AVERROR(EINVAL); } memcpy(samples, frame.extended_data[0], plane_size); if (planar && avctx->channels > 1) { uint8_t *out = ((uint8_t *)samples) + plane_size; for (ch = 1; ch < avctx->channels; ch++) { memcpy(out, frame.extended_data[ch], plane_size); out += plane_size; } } *frame_size_ptr = data_size; } else { *frame_size_ptr = 0; } return ret; }


static int qemu_chr_open_win_con(QemuOpts *opts, CharDriverState **chr) { return qemu_chr_open_win_file(GetStdHandle(STD_OUTPUT_HANDLE), chr); }


static void dca_exss_parse_header(DCAContext *s) { int asset_size[8]; int ss_index; int blownup; int num_audiop = 1; int num_assets = 1; int active_ss_mask[8]; int i, j; int start_posn; int hdrsize; uint32_t mkr; if (get_bits_left(&s->gb) < 52) return; start_posn = get_bits_count(&s->gb) - 32; skip_bits(&s->gb, 8); // user data ss_index = get_bits(&s->gb, 2); blownup = get_bits1(&s->gb); hdrsize = get_bits(&s->gb, 8 + 4 * blownup) + 1; // header_size skip_bits(&s->gb, 16 + 4 * blownup); // hd_size s->static_fields = get_bits1(&s->gb); if (s->static_fields) { skip_bits(&s->gb, 2); // reference clock code skip_bits(&s->gb, 3); // frame duration code if (get_bits1(&s->gb)) skip_bits_long(&s->gb, 36); // timestamp /* a single stream can contain multiple audio assets that can be * combined to form multiple audio presentations */ num_audiop = get_bits(&s->gb, 3) + 1; if (num_audiop > 1) { avpriv_request_sample(s->avctx, "Multiple DTS-HD audio presentations"); /* ignore such streams for now */ return; } num_assets = get_bits(&s->gb, 3) + 1; if (num_assets > 1) { avpriv_request_sample(s->avctx, "Multiple DTS-HD audio assets"); /* ignore such streams for now */ return; } for (i = 0; i < num_audiop; i++) active_ss_mask[i] = get_bits(&s->gb, ss_index + 1); for (i = 0; i < num_audiop; i++) for (j = 0; j <= ss_index; j++) if (active_ss_mask[i] & (1 << j)) skip_bits(&s->gb, 8); // active asset mask s->mix_metadata = get_bits1(&s->gb); if (s->mix_metadata) { int mix_out_mask_size; skip_bits(&s->gb, 2); // adjustment level mix_out_mask_size = (get_bits(&s->gb, 2) + 1) << 2; s->num_mix_configs = get_bits(&s->gb, 2) + 1; for (i = 0; i < s->num_mix_configs; i++) { int mix_out_mask = get_bits(&s->gb, mix_out_mask_size); s->mix_config_num_ch[i] = dca_exss_mask2count(mix_out_mask); } } } for (i = 0; i < num_assets; i++) asset_size[i] = get_bits_long(&s->gb, 16 + 4 * blownup); for (i = 0; i < num_assets; i++) { if (dca_exss_parse_asset_header(s)) return; } /* not parsed further, we were only interested in the extensions mask * from the asset header */ j = get_bits_count(&s->gb); if (start_posn + hdrsize * 8 > j) skip_bits_long(&s->gb, start_posn + hdrsize * 8 - j); for (i = 0; i < num_assets; i++) { start_posn = get_bits_count(&s->gb); mkr = get_bits_long(&s->gb, 32); /* parse extensions that we know about */ if (mkr == 0x655e315e) { dca_xbr_parse_frame(s); } else if (mkr == 0x47004a03) { dca_xxch_decode_frame(s); s->core_ext_mask |= DCA_EXT_XXCH; /* xxx use for chan reordering */ } else { av_log(s->avctx, AV_LOG_DEBUG, "DTS-ExSS: unknown marker = 0x%08x\n", mkr); } /* skip to end of block */ j = get_bits_count(&s->gb); if (start_posn + asset_size[i] * 8 > j) skip_bits_long(&s->gb, start_posn + asset_size[i] * 8 - j); } }


static int idcin_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; IdcinDemuxContext *idcin = s->priv_data; AVStream *st; unsigned int width, height; unsigned int sample_rate, bytes_per_sample, channels; /* get the 5 header parameters */ width = avio_rl32(pb); height = avio_rl32(pb); sample_rate = avio_rl32(pb); bytes_per_sample = avio_rl32(pb); channels = avio_rl32(pb); st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 33, 1, IDCIN_FPS); idcin->video_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_IDCIN; st->codec->codec_tag = 0; /* no fourcc */ st->codec->width = width; st->codec->height = height; /* load up the Huffman tables into extradata */ st->codec->extradata_size = HUFFMAN_TABLE_SIZE; st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE); if (avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) != HUFFMAN_TABLE_SIZE) return AVERROR(EIO); /* if sample rate is 0, assume no audio */ if (sample_rate) { idcin->audio_present = 1; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); avpriv_set_pts_info(st, 33, 1, IDCIN_FPS); idcin->audio_stream_index = st->index; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = 1; st->codec->channels = channels; st->codec->sample_rate = sample_rate; st->codec->bits_per_coded_sample = bytes_per_sample * 8; st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels; st->codec->block_align = bytes_per_sample * channels; if (bytes_per_sample == 1) st->codec->codec_id = AV_CODEC_ID_PCM_U8; else st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; if (sample_rate % 14 != 0) { idcin->audio_chunk_size1 = (sample_rate / 14) * bytes_per_sample * channels; idcin->audio_chunk_size2 = (sample_rate / 14 + 1) * bytes_per_sample * channels; } else { idcin->audio_chunk_size1 = idcin->audio_chunk_size2 = (sample_rate / 14) * bytes_per_sample * channels; idcin->current_audio_chunk = 0; } else idcin->audio_present = 1; idcin->next_chunk_is_video = 1; idcin->pts = 0; return 0;


static void xilinx_enet_init(Object *obj) { XilinxAXIEnet *s = XILINX_AXI_ENET(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); object_property_add_link(obj, "axistream-connected", TYPE_STREAM_SLAVE, (Object **) &s->tx_data_dev, &error_abort); object_property_add_link(obj, "axistream-control-connected", TYPE_STREAM_SLAVE, (Object **) &s->tx_control_dev, &error_abort); object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev), TYPE_XILINX_AXI_ENET_DATA_STREAM); object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev), TYPE_XILINX_AXI_ENET_CONTROL_STREAM); object_property_add_child(OBJECT(s), "axistream-connected-target", (Object *)&s->rx_data_dev, &error_abort); object_property_add_child(OBJECT(s), "axistream-control-connected-target", (Object *)&s->rx_control_dev, &error_abort); sysbus_init_irq(sbd, &s->irq); memory_region_init_io(&s->iomem, OBJECT(s), &enet_ops, s, "enet", 0x40000); sysbus_init_mmio(sbd, &s->iomem); }


static int update_size(AVCodecContext *ctx, int w, int h, enum AVPixelFormat fmt) { VP9Context *s = ctx->priv_data; uint8_t *p; int bytesperpixel = s->bytesperpixel; av_assert0(w > 0 && h > 0); if (s->intra_pred_data[0] && w == ctx->width && h == ctx->height && ctx->pix_fmt == fmt) return 0; ctx->width = w; ctx->height = h; ctx->pix_fmt = fmt; s->sb_cols = (w + 63) >> 6; s->sb_rows = (h + 63) >> 6; s->cols = (w + 7) >> 3; s->rows = (h + 7) >> 3; #define assign(var, type, n) var = (type) p; p += s->sb_cols * (n) * sizeof(*var) av_freep(&s->intra_pred_data[0]); // FIXME we slightly over-allocate here for subsampled chroma, but a little // bit of padding shouldn't affect performance... p = av_malloc(s->sb_cols * (128 + 192 * bytesperpixel + sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx))); if (!p) return AVERROR(ENOMEM); assign(s->intra_pred_data[0], uint8_t *, 64 * bytesperpixel); assign(s->intra_pred_data[1], uint8_t *, 64 * bytesperpixel); assign(s->intra_pred_data[2], uint8_t *, 64 * bytesperpixel); assign(s->above_y_nnz_ctx, uint8_t *, 16); assign(s->above_mode_ctx, uint8_t *, 16); assign(s->above_mv_ctx, VP56mv(*)[2], 16); assign(s->above_uv_nnz_ctx[0], uint8_t *, 16); assign(s->above_uv_nnz_ctx[1], uint8_t *, 16); assign(s->above_partition_ctx, uint8_t *, 8); assign(s->above_skip_ctx, uint8_t *, 8); assign(s->above_txfm_ctx, uint8_t *, 8); assign(s->above_segpred_ctx, uint8_t *, 8); assign(s->above_intra_ctx, uint8_t *, 8); assign(s->above_comp_ctx, uint8_t *, 8); assign(s->above_ref_ctx, uint8_t *, 8); assign(s->above_filter_ctx, uint8_t *, 8); assign(s->lflvl, struct VP9Filter *, 1); #undef assign // these will be re-allocated a little later av_freep(&s->b_base); av_freep(&s->block_base); if (s->bpp != s->last_bpp) { ff_vp9dsp_init(&s->dsp, s->bpp); ff_videodsp_init(&s->vdsp, s->bpp); s->last_bpp = s->bpp; } return 0; }


static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid, unsigned int epid) { XHCISlot *slot; XHCIEPContext *epctx; USBDevice *dev; trace_usb_xhci_ep_reset(slotid, epid); assert(slotid >= 1 && slotid <= xhci->numslots); if (epid < 1 || epid > 31) { fprintf(stderr, "xhci: bad ep %d\n", epid); return CC_TRB_ERROR; } slot = &xhci->slots[slotid-1]; if (!slot->eps[epid-1]) { DPRINTF("xhci: slot %d ep %d not enabled\n", slotid, epid); return CC_EP_NOT_ENABLED_ERROR; } epctx = slot->eps[epid-1]; if (epctx->state != EP_HALTED) { fprintf(stderr, "xhci: reset EP while EP %d not halted (%d)\n", epid, epctx->state); return CC_CONTEXT_STATE_ERROR; } if (xhci_ep_nuke_xfers(xhci, slotid, epid) > 0) { fprintf(stderr, "xhci: FIXME: endpoint reset w/ xfers running, " "data might be lost\n"); } uint8_t ep = epid>>1; if (epid & 1) { ep |= 0x80; } dev = xhci->slots[slotid-1].uport->dev; if (!dev) { return CC_USB_TRANSACTION_ERROR; } xhci_set_ep_state(xhci, epctx, NULL, EP_STOPPED); if (epctx->nr_pstreams) { xhci_reset_streams(epctx); } return CC_SUCCESS; }


static int64_t mmsh_seek(URLContext *h, int64_t pos, int whence) { MMSHContext *mmsh = h->priv_data; MMSContext *mms = &mmsh->mms; if(pos == 0 && whence == SEEK_CUR) return mms->asf_header_read_size + mms->remaining_in_len + mmsh->chunk_seq * mms->asf_packet_len; return AVERROR(ENOSYS); }


static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h) { BitBuf bb; int res, val; int i, j; int bx, by; int l0x, l1x, l0y, l1y; int mx, my; kmvc_init_getbits(bb, src); for (by = 0; by < h; by += 8) for (bx = 0; bx < w; bx += 8) { kmvc_getbit(bb, src, res); if (!res) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 8x8 block val = *src++; for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; } else { // copy block from previous frame for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = BLK(ctx->prev, bx + (i & 0x7), by + (i >> 3)); } } else { // handle four 4x4 subblocks for (i = 0; i < 4; i++) { l0x = bx + (i & 1) * 4; l0y = by + (i & 2) * 2; kmvc_getbit(bb, src, res); if (!res) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 4x4 block val = *src++; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; } else { // copy block val = *src++; mx = (val & 0xF) - 8; my = (val >> 4) - 8; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my); } } else { // descend to 2x2 sub-sub-blocks for (j = 0; j < 4; j++) { l1x = l0x + (j & 1) * 2; l1y = l0y + (j & 2); kmvc_getbit(bb, src, res); if (!res) { kmvc_getbit(bb, src, res); if (!res) { // fill whole 2x2 block val = *src++; BLK(ctx->cur, l1x, l1y) = val; BLK(ctx->cur, l1x + 1, l1y) = val; BLK(ctx->cur, l1x, l1y + 1) = val; BLK(ctx->cur, l1x + 1, l1y + 1) = val; } else { // copy block val = *src++; mx = (val & 0xF) - 8; my = (val >> 4) - 8; BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my); BLK(ctx->cur, l1x + 1, l1y) = BLK(ctx->prev, l1x + 1 + mx, l1y + my); BLK(ctx->cur, l1x, l1y + 1) = BLK(ctx->prev, l1x + mx, l1y + 1 + my); BLK(ctx->cur, l1x + 1, l1y + 1) = BLK(ctx->prev, l1x + 1 + mx, l1y + 1 + my); } } else { // read values for block BLK(ctx->cur, l1x, l1y) = *src++; BLK(ctx->cur, l1x + 1, l1y) = *src++; BLK(ctx->cur, l1x, l1y + 1) = *src++; BLK(ctx->cur, l1x + 1, l1y + 1) = *src++; } } } } } } }


static void tlb_flush_by_mmuidx_async_work(CPUState *cpu, run_on_cpu_data data) { CPUArchState *env = cpu->env_ptr; unsigned long mmu_idx_bitmask = data.host_int; int mmu_idx; assert_cpu_is_self(cpu); tb_lock(); tlb_debug("start: mmu_idx:0x%04lx\n", mmu_idx_bitmask); for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { if (test_bit(mmu_idx, &mmu_idx_bitmask)) { tlb_debug("%d\n", mmu_idx); memset(env->tlb_table[mmu_idx], -1, sizeof(env->tlb_table[0])); memset(env->tlb_v_table[mmu_idx], -1, sizeof(env->tlb_v_table[0])); } } memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache)); tlb_debug("done\n"); tb_unlock(); }


static int encode_hq_slice(AVCodecContext *avctx, void *arg) { SliceArgs *slice_dat = arg; VC2EncContext *s = slice_dat->ctx; PutBitContext *pb = &slice_dat->pb; const int slice_x = slice_dat->x; const int slice_y = slice_dat->y; const int quant_idx = slice_dat->quant_idx; const int slice_bytes_max = slice_dat->bytes; uint8_t quants[MAX_DWT_LEVELS][4]; int p, level, orientation; /* The reference decoder ignores it, and its typical length is 0 */ memset(put_bits_ptr(pb), 0, s->prefix_bytes); skip_put_bytes(pb, s->prefix_bytes); put_bits(pb, 8, quant_idx); /* Slice quantization (slice_quantizers() in the specs) */ for (level = 0; level < s->wavelet_depth; level++) for (orientation = !!level; orientation < 4; orientation++) quants[level][orientation] = FFMAX(quant_idx - s->quant[level][orientation], 0); /* Luma + 2 Chroma planes */ for (p = 0; p < 3; p++) { int bytes_start, bytes_len, pad_s, pad_c; bytes_start = put_bits_count(pb) >> 3; put_bits(pb, 8, 0); for (level = 0; level < s->wavelet_depth; level++) { for (orientation = !!level; orientation < 4; orientation++) { encode_subband(s, pb, slice_x, slice_y, &s->plane[p].band[level][orientation], quants[level][orientation]); } } avpriv_align_put_bits(pb); bytes_len = (put_bits_count(pb) >> 3) - bytes_start - 1; if (p == 2) { int len_diff = slice_bytes_max - (put_bits_count(pb) >> 3); pad_s = FFALIGN((bytes_len + len_diff), s->size_scaler)/s->size_scaler; pad_c = (pad_s*s->size_scaler) - bytes_len; } else { pad_s = FFALIGN(bytes_len, s->size_scaler)/s->size_scaler; pad_c = (pad_s*s->size_scaler) - bytes_len; } pb->buf[bytes_start] = pad_s; flush_put_bits(pb); skip_put_bytes(pb, pad_c); } return 0; }


int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr) { RTSPState *rt = s->priv_data; RTSPMessageHeader reply1, *reply = &reply1; int i; char *sdp; AVFormatContext sdp_ctx, *ctx_array[1]; s->start_time_realtime = av_gettime(); /* Announce the stream */ sdp = av_mallocz(SDP_MAX_SIZE); if (sdp == NULL) return AVERROR(ENOMEM); /* We create the SDP based on the RTSP AVFormatContext where we * aren't allowed to change the filename field. (We create the SDP * based on the RTSP context since the contexts for the RTP streams * don't exist yet.) In order to specify a custom URL with the actual * peer IP instead of the originally specified hostname, we create * a temporary copy of the AVFormatContext, where the custom URL is set. * * FIXME: Create the SDP without copying the AVFormatContext. * This either requires setting up the RTP stream AVFormatContexts * already here (complicating things immensely) or getting a more * flexible SDP creation interface. */ sdp_ctx = *s; ff_url_join(sdp_ctx.filename, sizeof(sdp_ctx.filename), "rtsp", NULL, addr, -1, NULL); ctx_array[0] = &sdp_ctx; if (avf_sdp_create(ctx_array, 1, sdp, SDP_MAX_SIZE)) { av_free(sdp); return AVERROR_INVALIDDATA; } av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp); ff_rtsp_send_cmd_with_content(s, "ANNOUNCE", rt->control_uri, "Content-Type: application/sdp\r\n", reply, NULL, sdp, strlen(sdp)); av_free(sdp); if (reply->status_code != RTSP_STATUS_OK) return AVERROR_INVALIDDATA; /* Set up the RTSPStreams for each AVStream */ for (i = 0; i < s->nb_streams; i++) { RTSPStream *rtsp_st; AVStream *st = s->streams[i]; rtsp_st = av_mallocz(sizeof(RTSPStream)); if (!rtsp_st) return AVERROR(ENOMEM); dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st); st->priv_data = rtsp_st; rtsp_st->stream_index = i; av_strlcpy(rtsp_st->control_url, rt->control_uri, sizeof(rtsp_st->control_url)); /* Note, this must match the relative uri set in the sdp content */ av_strlcatf(rtsp_st->control_url, sizeof(rtsp_st->control_url), "/streamid=%d", i); } return 0; }


static int smjpeg_read_packet(AVFormatContext *s, AVPacket *pkt) { SMJPEGContext *sc = s->priv_data; uint32_t dtype, ret, size, timestamp; int64_t pos; if (s->pb->eof_reached) return AVERROR_EOF; pos = avio_tell(s->pb); dtype = avio_rl32(s->pb); switch (dtype) { case SMJPEG_SNDD: timestamp = avio_rb32(s->pb); size = avio_rb32(s->pb); ret = av_get_packet(s->pb, pkt, size); pkt->stream_index = sc->audio_stream_index; pkt->pts = timestamp; pkt->pos = pos; break; case SMJPEG_VIDD: timestamp = avio_rb32(s->pb); size = avio_rb32(s->pb); ret = av_get_packet(s->pb, pkt, size); pkt->stream_index = sc->video_stream_index; pkt->pts = timestamp; pkt->pos = pos; break; case SMJPEG_DONE: ret = AVERROR_EOF; break; default: av_log(s, AV_LOG_ERROR, "unknown chunk %x\n", dtype); ret = AVERROR_INVALIDDATA; break; } return ret; }


static void apic_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) { }


static void write_dt(void *ptr, unsigned long addr, unsigned long limit, int flags) { unsigned int e1, e2; uint32_t *p; e1 = (addr << 16) | (limit & 0xffff); e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000); e2 |= flags; p = ptr; p[0] = tswapl(e1); p[1] = tswapl(e2); }


static int vdi_co_write(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors) { BDRVVdiState *s = bs->opaque; uint32_t bmap_entry; uint32_t block_index; uint32_t sector_in_block; uint32_t n_sectors; uint32_t bmap_first = VDI_UNALLOCATED; uint32_t bmap_last = VDI_UNALLOCATED; uint8_t *block = NULL; int ret; logout("\n"); restart: block_index = sector_num / s->block_sectors; sector_in_block = sector_num % s->block_sectors; n_sectors = s->block_sectors - sector_in_block; if (n_sectors > nb_sectors) { n_sectors = nb_sectors; } logout("will write %u sectors starting at sector %" PRIu64 "\n", n_sectors, sector_num); /* prepare next AIO request */ bmap_entry = le32_to_cpu(s->bmap[block_index]); if (!VDI_IS_ALLOCATED(bmap_entry)) { /* Allocate new block and write to it. */ uint64_t offset; bmap_entry = s->header.blocks_allocated; s->bmap[block_index] = cpu_to_le32(bmap_entry); s->header.blocks_allocated++; offset = s->header.offset_data / SECTOR_SIZE + (uint64_t)bmap_entry * s->block_sectors; if (block == NULL) { block = g_malloc(s->block_size); bmap_first = block_index; } bmap_last = block_index; /* Copy data to be written to new block and zero unused parts. */ memset(block, 0, sector_in_block * SECTOR_SIZE); memcpy(block + sector_in_block * SECTOR_SIZE, buf, n_sectors * SECTOR_SIZE); memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0, (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE); ret = bdrv_write(bs->file, offset, block, s->block_sectors); } else { uint64_t offset = s->header.offset_data / SECTOR_SIZE + (uint64_t)bmap_entry * s->block_sectors + sector_in_block; ret = bdrv_write(bs->file, offset, buf, n_sectors); } nb_sectors -= n_sectors; sector_num += n_sectors; buf += n_sectors * SECTOR_SIZE; logout("%u sectors written\n", n_sectors); if (ret >= 0 && nb_sectors > 0) { goto restart; } logout("finished data write\n"); if (ret < 0) { return ret; } if (block) { /* One or more new blocks were allocated. */ VdiHeader *header = (VdiHeader *) block; uint8_t *base; uint64_t offset; logout("now writing modified header\n"); assert(VDI_IS_ALLOCATED(bmap_first)); *header = s->header; vdi_header_to_le(header); ret = bdrv_write(bs->file, 0, block, 1); g_free(block); block = NULL; if (ret < 0) { return ret; } logout("now writing modified block map entry %u...%u\n", bmap_first, bmap_last); /* Write modified sectors from block map. */ bmap_first /= (SECTOR_SIZE / sizeof(uint32_t)); bmap_last /= (SECTOR_SIZE / sizeof(uint32_t)); n_sectors = bmap_last - bmap_first + 1; offset = s->bmap_sector + bmap_first; base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE; logout("will write %u block map sectors starting from entry %u\n", n_sectors, bmap_first); ret = bdrv_write(bs->file, offset, base, n_sectors); } return ret; }


static void vga_screen_dump(void *opaque, const char *filename, bool cswitch, Error **errp) { VGACommonState *s = opaque; DisplaySurface *surface = qemu_console_surface(s->con); if (cswitch) { vga_invalidate_display(s); } graphic_hw_update(s->con); ppm_save(filename, surface, errp); }


static uint64_t omap_tcmi_read(void *opaque, target_phys_addr_t addr, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; uint32_t ret; if (size != 4) { return omap_badwidth_read32(opaque, addr); } switch (addr) { case 0x00: /* IMIF_PRIO */ case 0x04: /* EMIFS_PRIO */ case 0x08: /* EMIFF_PRIO */ case 0x0c: /* EMIFS_CONFIG */ case 0x10: /* EMIFS_CS0_CONFIG */ case 0x14: /* EMIFS_CS1_CONFIG */ case 0x18: /* EMIFS_CS2_CONFIG */ case 0x1c: /* EMIFS_CS3_CONFIG */ case 0x24: /* EMIFF_MRS */ case 0x28: /* TIMEOUT1 */ case 0x2c: /* TIMEOUT2 */ case 0x30: /* TIMEOUT3 */ case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */ case 0x40: /* EMIFS_CFG_DYN_WAIT */ return s->tcmi_regs[addr >> 2]; case 0x20: /* EMIFF_SDRAM_CONFIG */ ret = s->tcmi_regs[addr >> 2]; s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */ /* XXX: We can try using the VGA_DIRTY flag for this */ return ret; } OMAP_BAD_REG(addr); return 0; }


static int vc1_decode_p_mb(VC1Context *v) { MpegEncContext *s = &v->s; GetBitContext *gb = &s->gb; int i, j; int mb_pos = s->mb_x + s->mb_y * s->mb_stride; int cbp; /* cbp decoding stuff */ int mqdiff, mquant; /* MB quantization */ int ttmb = v->ttfrm; /* MB Transform type */ int mb_has_coeffs = 1; /* last_flag */ int dmv_x, dmv_y; /* Differential MV components */ int index, index1; /* LUT indexes */ int val, sign; /* temp values */ int first_block = 1; int dst_idx, off; int skipped, fourmv; int block_cbp = 0, pat; int apply_loop_filter; mquant = v->pq; /* Loosy initialization */ if (v->mv_type_is_raw) fourmv = get_bits1(gb); else fourmv = v->mv_type_mb_plane[mb_pos]; if (v->skip_is_raw) skipped = get_bits1(gb); else skipped = v->s.mbskip_table[mb_pos]; s->dsp.clear_blocks(s->block[0]); apply_loop_filter = s->loop_filter && !(s->avctx->skip_loop_filter >= AVDISCARD_NONKEY); if (!fourmv) /* 1MV mode */ { if (!skipped) { GET_MVDATA(dmv_x, dmv_y); if (s->mb_intra) { s->current_picture.motion_val[1][s->block_index[0]][0] = 0; s->current_picture.motion_val[1][s->block_index[0]][1] = 0; } s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16; vc1_pred_mv(s, 0, dmv_x, dmv_y, 1, v->range_x, v->range_y, v->mb_type[0]); /* FIXME Set DC val for inter block ? */ if (s->mb_intra && !mb_has_coeffs) { GET_MQUANT(); s->ac_pred = get_bits1(gb); cbp = 0; } else if (mb_has_coeffs) { if (s->mb_intra) s->ac_pred = get_bits1(gb); cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); GET_MQUANT(); } else { mquant = v->pq; cbp = 0; } s->current_picture.qscale_table[mb_pos] = mquant; if (!v->ttmbf && !s->mb_intra && mb_has_coeffs) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); if(!s->mb_intra) vc1_mc_1mv(v, 0); dst_idx = 0; for (i=0; i<6; i++) { s->dc_val[0][s->block_index[i]] = 0; dst_idx += i >> 2; val = ((cbp >> (5 - i)) & 1); off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); v->mb_type[0][s->block_index[i]] = s->mb_intra; if(s->mb_intra) { /* check if prediction blocks A and C are available */ v->a_avail = v->c_avail = 0; if(i == 2 || i == 3 || !s->first_slice_line) v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]]; if(i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset); if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; s->dsp.vc1_inv_trans_8x8(s->block[i]); if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); if(v->pq >= 9 && v->overlap) { if(v->c_avail) s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); if(v->a_avail) s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); } if(apply_loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ int left_cbp, top_cbp; if(i & 4){ left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); }else{ left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); } if(left_cbp & 0xC) s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); if(top_cbp & 0xA) s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); } block_cbp |= 0xF << (i << 2); } else if(val) { int left_cbp = 0, top_cbp = 0, filter = 0; if(apply_loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ filter = 1; if(i & 4){ left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); }else{ left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); } if(left_cbp & 0xC) s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); if(top_cbp & 0xA) s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); } pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); block_cbp |= pat << (i << 2); if(!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; } } } else //Skipped { s->mb_intra = 0; for(i = 0; i < 6; i++) { v->mb_type[0][s->block_index[i]] = 0; s->dc_val[0][s->block_index[i]] = 0; } s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP; s->current_picture.qscale_table[mb_pos] = 0; vc1_pred_mv(s, 0, 0, 0, 1, v->range_x, v->range_y, v->mb_type[0]); vc1_mc_1mv(v, 0); return 0; } } //1MV mode else //4MV mode { if (!skipped /* unskipped MB */) { int intra_count = 0, coded_inter = 0; int is_intra[6], is_coded[6]; /* Get CBPCY */ cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2); for (i=0; i<6; i++) { val = ((cbp >> (5 - i)) & 1); s->dc_val[0][s->block_index[i]] = 0; s->mb_intra = 0; if(i < 4) { dmv_x = dmv_y = 0; s->mb_intra = 0; mb_has_coeffs = 0; if(val) { GET_MVDATA(dmv_x, dmv_y); } vc1_pred_mv(s, i, dmv_x, dmv_y, 0, v->range_x, v->range_y, v->mb_type[0]); if(!s->mb_intra) vc1_mc_4mv_luma(v, i); intra_count += s->mb_intra; is_intra[i] = s->mb_intra; is_coded[i] = mb_has_coeffs; } if(i&4){ is_intra[i] = (intra_count >= 3); is_coded[i] = val; } if(i == 4) vc1_mc_4mv_chroma(v); v->mb_type[0][s->block_index[i]] = is_intra[i]; if(!coded_inter) coded_inter = !is_intra[i] & is_coded[i]; } // if there are no coded blocks then don't do anything more if(!intra_count && !coded_inter) return 0; dst_idx = 0; GET_MQUANT(); s->current_picture.qscale_table[mb_pos] = mquant; /* test if block is intra and has pred */ { int intrapred = 0; for(i=0; i<6; i++) if(is_intra[i]) { if(((!s->first_slice_line || (i==2 || i==3)) && v->mb_type[0][s->block_index[i] - s->block_wrap[i]]) || ((s->mb_x || (i==1 || i==3)) && v->mb_type[0][s->block_index[i] - 1])) { intrapred = 1; break; } } if(intrapred)s->ac_pred = get_bits1(gb); else s->ac_pred = 0; } if (!v->ttmbf && coded_inter) ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2); for (i=0; i<6; i++) { dst_idx += i >> 2; off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize); s->mb_intra = is_intra[i]; if (is_intra[i]) { /* check if prediction blocks A and C are available */ v->a_avail = v->c_avail = 0; if(i == 2 || i == 3 || !s->first_slice_line) v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]]; if(i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; vc1_decode_intra_block(v, s->block[i], i, is_coded[i], mquant, (i&4)?v->codingset2:v->codingset); if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue; s->dsp.vc1_inv_trans_8x8(s->block[i]); if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1; s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize); if(v->pq >= 9 && v->overlap) { if(v->c_avail) s->dsp.vc1_h_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); if(v->a_avail) s->dsp.vc1_v_overlap(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2)); } if(v->s.loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ int left_cbp, top_cbp; if(i & 4){ left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); }else{ left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); } if(left_cbp & 0xC) s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); if(top_cbp & 0xA) s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); } block_cbp |= 0xF << (i << 2); } else if(is_coded[i]) { int left_cbp = 0, top_cbp = 0, filter = 0; if(v->s.loop_filter && s->mb_x && s->mb_x != (s->mb_width - 1) && s->mb_y && s->mb_y != (s->mb_height - 1)){ filter = 1; if(i & 4){ left_cbp = v->cbp[s->mb_x - 1] >> (i * 4); top_cbp = v->cbp[s->mb_x - s->mb_stride] >> (i * 4); }else{ left_cbp = (i & 1) ? (cbp >> ((i-1)*4)) : (v->cbp[s->mb_x - 1] >> ((i+1)*4)); top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4)); } if(left_cbp & 0xC) s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant); if(top_cbp & 0xA) s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant); } pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp); block_cbp |= pat << (i << 2); if(!v->ttmbf && ttmb < 8) ttmb = -1; first_block = 0; } } return 0; } else //Skipped MB { s->mb_intra = 0; s->current_picture.qscale_table[mb_pos] = 0; for (i=0; i<6; i++) { v->mb_type[0][s->block_index[i]] = 0; s->dc_val[0][s->block_index[i]] = 0; } for (i=0; i<4; i++) { vc1_pred_mv(s, i, 0, 0, 0, v->range_x, v->range_y, v->mb_type[0]); vc1_mc_4mv_luma(v, i); } vc1_mc_4mv_chroma(v); s->current_picture.qscale_table[mb_pos] = 0; return 0; } } v->cbp[s->mb_x] = block_cbp; /* Should never happen */ return -1; }


static void s390_pcihost_init_as(S390pciState *s) { int i; S390PCIBusDevice *pbdev; for (i = 0; i < PCI_SLOT_MAX; i++) { pbdev = &s->pbdev[i]; memory_region_init(&pbdev->mr, OBJECT(s), "iommu-root-s390", UINT64_MAX); address_space_init(&pbdev->as, &pbdev->mr, "iommu-pci"); } memory_region_init_io(&s->msix_notify_mr, OBJECT(s), &s390_msi_ctrl_ops, s, "msix-s390", UINT64_MAX); address_space_init(&s->msix_notify_as, &s->msix_notify_mr, "msix-pci"); }


static uint64_t tmu2_read(void *opaque, target_phys_addr_t addr, unsigned size) { MilkymistTMU2State *s = opaque; uint32_t r = 0; addr >>= 2; switch (addr) { case R_CTL: case R_HMESHLAST: case R_VMESHLAST: case R_BRIGHTNESS: case R_CHROMAKEY: case R_VERTICESADDR: case R_TEXFBUF: case R_TEXHRES: case R_TEXVRES: case R_TEXHMASK: case R_TEXVMASK: case R_DSTFBUF: case R_DSTHRES: case R_DSTVRES: case R_DSTHOFFSET: case R_DSTVOFFSET: case R_DSTSQUAREW: case R_DSTSQUAREH: case R_ALPHA: r = s->regs[addr]; break; default: error_report("milkymist_tmu2: read access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } trace_milkymist_tmu2_memory_read(addr << 2, r); return r; }


static void icount_adjust_vm(void *opaque) { timer_mod(icount_vm_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + NANOSECONDS_PER_SECOND / 10); icount_adjust(); }


static int qcow_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { BDRVQcowState *s = bs->opaque; int index_in_cluster, n; uint64_t cluster_offset; cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0); index_in_cluster = sector_num & (s->cluster_sectors - 1); n = s->cluster_sectors - index_in_cluster; if (n > nb_sectors) n = nb_sectors; *pnum = n; return (cluster_offset != 0); }


static uint64_t mv88w8618_eth_read(void *opaque, target_phys_addr_t offset, unsigned size) { mv88w8618_eth_state *s = opaque; switch (offset) { case MP_ETH_SMIR: if (s->smir & MP_ETH_SMIR_OPCODE) { switch (s->smir & MP_ETH_SMIR_ADDR) { case MP_ETH_PHY1_BMSR: return MP_PHY_BMSR_LINK | MP_PHY_BMSR_AUTONEG | MP_ETH_SMIR_RDVALID; case MP_ETH_PHY1_PHYSID1: return (MP_PHY_88E3015 >> 16) | MP_ETH_SMIR_RDVALID; case MP_ETH_PHY1_PHYSID2: return (MP_PHY_88E3015 & 0xFFFF) | MP_ETH_SMIR_RDVALID; default: return MP_ETH_SMIR_RDVALID; } } return 0; case MP_ETH_ICR: return s->icr; case MP_ETH_IMR: return s->imr; case MP_ETH_FRDP0 ... MP_ETH_FRDP3: return s->frx_queue[(offset - MP_ETH_FRDP0)/4]; case MP_ETH_CRDP0 ... MP_ETH_CRDP3: return s->rx_queue[(offset - MP_ETH_CRDP0)/4]; case MP_ETH_CTDP0 ... MP_ETH_CTDP3: return s->tx_queue[(offset - MP_ETH_CTDP0)/4]; default: return 0; } }


static void blockdev_backup_prepare(BlkActionState *common, Error **errp) { BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common); BlockdevBackup *backup; BlockBackend *blk, *target; Error *local_err = NULL; assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP); backup = common->action->u.blockdev_backup; blk = blk_by_name(backup->device); if (!blk) { error_setg(errp, "Device '%s' not found", backup->device); return; } if (!blk_is_available(blk)) { error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, backup->device); return; } target = blk_by_name(backup->target); if (!target) { error_setg(errp, "Device '%s' not found", backup->target); return; } /* AioContext is released in .clean() */ state->aio_context = blk_get_aio_context(blk); if (state->aio_context != blk_get_aio_context(target)) { state->aio_context = NULL; error_setg(errp, "Backup between two IO threads is not implemented"); return; } aio_context_acquire(state->aio_context); state->bs = blk_bs(blk); bdrv_drained_begin(state->bs); do_blockdev_backup(backup->device, backup->target, backup->sync, backup->has_speed, backup->speed, backup->has_on_source_error, backup->on_source_error, backup->has_on_target_error, backup->on_target_error, common->block_job_txn, &local_err); if (local_err) { error_propagate(errp, local_err); return; } state->job = state->bs->job; }


static ExitStatus gen_call_pal(DisasContext *ctx, int palcode) { /* We're emulating OSF/1 PALcode. Many of these are trivial access to internal cpu registers. */ /* Unprivileged PAL call */ if (palcode >= 0x80 && palcode < 0xC0) { switch (palcode) { case 0x86: /* IMB */ /* No-op inside QEMU. */ break; case 0x9E: /* RDUNIQUE */ tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_unique); break; case 0x9F: /* WRUNIQUE */ tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]); break; default: return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xbf); } return NO_EXIT; } #ifndef CONFIG_USER_ONLY /* Privileged PAL code */ if (palcode < 0x40 && (ctx->tb->flags & TB_FLAGS_USER_MODE) == 0) { switch (palcode) { case 0x01: /* CFLUSH */ /* No-op inside QEMU. */ break; case 0x02: /* DRAINA */ /* No-op inside QEMU. */ break; case 0x2D: /* WRVPTPTR */ tcg_gen_st_i64(cpu_ir[IR_A0], cpu_env, offsetof(CPUAlphaState, vptptr)); break; case 0x31: /* WRVAL */ tcg_gen_mov_i64(cpu_sysval, cpu_ir[IR_A0]); break; case 0x32: /* RDVAL */ tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_sysval); break; case 0x35: { /* SWPIPL */ TCGv tmp; /* Note that we already know we're in kernel mode, so we know that PS only contains the 3 IPL bits. */ tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUAlphaState, ps)); /* But make sure and store only the 3 IPL bits from the user. */ tmp = tcg_temp_new(); tcg_gen_andi_i64(tmp, cpu_ir[IR_A0], PS_INT_MASK); tcg_gen_st8_i64(tmp, cpu_env, offsetof(CPUAlphaState, ps)); tcg_temp_free(tmp); break; } case 0x36: /* RDPS */ tcg_gen_ld8u_i64(cpu_ir[IR_V0], cpu_env, offsetof(CPUAlphaState, ps)); break; case 0x38: /* WRUSP */ tcg_gen_mov_i64(cpu_usp, cpu_ir[IR_A0]); break; case 0x3A: /* RDUSP */ tcg_gen_mov_i64(cpu_ir[IR_V0], cpu_usp); break; case 0x3C: /* WHAMI */ tcg_gen_ld32s_i64(cpu_ir[IR_V0], cpu_env, -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index)); break; default: return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3f); } return NO_EXIT; } #endif return gen_invalid(ctx); }


static void tcg_out_ri32(TCGContext *s, int const_arg, TCGArg arg) { if (const_arg) { assert(const_arg == 1); tcg_out8(s, TCG_CONST); tcg_out32(s, arg); } else { tcg_out_r(s, arg); } }


static int qsort_strcmp(const void *a, const void *b) { return strcmp(a, b); }


static uint32_t mb_add_cmdline(MultibootState *s, const char *cmdline) { target_phys_addr_t p = s->offset_cmdlines; char *b = (char *)s->mb_buf + p; get_opt_value(b, strlen(cmdline) + 1, cmdline); s->offset_cmdlines += strlen(b) + 1; return s->mb_buf_phys + p; }


static void RENAME(yuv2yuv1)(SwsContext *c, const int16_t *lumSrc, const int16_t *chrUSrc, const int16_t *chrVSrc, const int16_t *alpSrc, uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, int dstW, int chrDstW) { int p= 4; const int16_t *src[4]= { alpSrc + dstW, lumSrc + dstW, chrUSrc + chrDstW, chrVSrc + chrDstW }; uint8_t *dst[4]= { aDest, dest, uDest, vDest }; x86_reg counter[4]= { dstW, dstW, chrDstW, chrDstW }; while (p--) { if (dst[p]) { __asm__ volatile( "mov %2, %%"REG_a" \n\t" ".p2align 4 \n\t" /* FIXME Unroll? */ "1: \n\t" "movq (%0, %%"REG_a", 2), %%mm0 \n\t" "movq 8(%0, %%"REG_a", 2), %%mm1 \n\t" "psraw $7, %%mm0 \n\t" "psraw $7, %%mm1 \n\t" "packuswb %%mm1, %%mm0 \n\t" MOVNTQ(%%mm0, (%1, %%REGa)) "add $8, %%"REG_a" \n\t" "jnc 1b \n\t" :: "r" (src[p]), "r" (dst[p] + counter[p]), "g" (-counter[p]) : "%"REG_a ); } } }


static int vp3_decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size) { Vp3DecodeContext *s = avctx->priv_data; GetBitContext gb; static int counter = 0; int i; init_get_bits(&gb, buf, buf_size * 8); if (s->theora && get_bits1(&gb)) { av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n"); return -1; } s->keyframe = !get_bits1(&gb); if (!s->theora) skip_bits(&gb, 1); s->last_quality_index = s->quality_index; s->nqis=0; do{ s->qis[s->nqis++]= get_bits(&gb, 6); } while(s->theora >= 0x030200 && s->nqis<3 && get_bits1(&gb)); s->quality_index= s->qis[0]; if (s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%d: Q index = %d\n", s->keyframe?"key":"", counter, s->quality_index); counter++; if (s->quality_index != s->last_quality_index) { init_dequantizer(s); init_loop_filter(s); } if (s->keyframe) { if (!s->theora) { skip_bits(&gb, 4); /* width code */ skip_bits(&gb, 4); /* height code */ if (s->version) { s->version = get_bits(&gb, 5); if (counter == 1) av_log(s->avctx, AV_LOG_DEBUG, "VP version: %d\n", s->version); } } if (s->version || s->theora) { if (get_bits1(&gb)) av_log(s->avctx, AV_LOG_ERROR, "Warning, unsupported keyframe coding type?!\n"); skip_bits(&gb, 2); /* reserved? */ } if (s->last_frame.data[0] == s->golden_frame.data[0]) { if (s->golden_frame.data[0]) avctx->release_buffer(avctx, &s->golden_frame); s->last_frame= s->golden_frame; /* ensure that we catch any access to this released frame */ } else { if (s->golden_frame.data[0]) avctx->release_buffer(avctx, &s->golden_frame); if (s->last_frame.data[0]) avctx->release_buffer(avctx, &s->last_frame); } s->golden_frame.reference = 3; if(avctx->get_buffer(avctx, &s->golden_frame) < 0) { av_log(s->avctx, AV_LOG_ERROR, "vp3: get_buffer() failed\n"); return -1; } /* golden frame is also the current frame */ s->current_frame= s->golden_frame; /* time to figure out pixel addresses? */ if (!s->pixel_addresses_inited) { if (!s->flipped_image) vp3_calculate_pixel_addresses(s); else theora_calculate_pixel_addresses(s); s->pixel_addresses_inited = 1; } } else { /* allocate a new current frame */ s->current_frame.reference = 3; if (!s->pixel_addresses_inited) { av_log(s->avctx, AV_LOG_ERROR, "vp3: first frame not a keyframe\n"); return -1; } if(avctx->get_buffer(avctx, &s->current_frame) < 0) { av_log(s->avctx, AV_LOG_ERROR, "vp3: get_buffer() failed\n"); return -1; } } s->current_frame.qscale_table= s->qscale_table; //FIXME allocate individual tables per AVFrame s->current_frame.qstride= 0; {START_TIMER init_frame(s, &gb); STOP_TIMER("init_frame")} #if KEYFRAMES_ONLY if (!s->keyframe) { memcpy(s->current_frame.data[0], s->golden_frame.data[0], s->current_frame.linesize[0] * s->height); memcpy(s->current_frame.data[1], s->golden_frame.data[1], s->current_frame.linesize[1] * s->height / 2); memcpy(s->current_frame.data[2], s->golden_frame.data[2], s->current_frame.linesize[2] * s->height / 2); } else { #endif {START_TIMER if (unpack_superblocks(s, &gb)){ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n"); return -1; } STOP_TIMER("unpack_superblocks")} {START_TIMER if (unpack_modes(s, &gb)){ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n"); return -1; } STOP_TIMER("unpack_modes")} {START_TIMER if (unpack_vectors(s, &gb)){ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n"); return -1; } STOP_TIMER("unpack_vectors")} {START_TIMER if (unpack_dct_coeffs(s, &gb)){ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n"); return -1; } STOP_TIMER("unpack_dct_coeffs")} {START_TIMER reverse_dc_prediction(s, 0, s->fragment_width, s->fragment_height); if ((avctx->flags & CODEC_FLAG_GRAY) == 0) { reverse_dc_prediction(s, s->fragment_start[1], s->fragment_width / 2, s->fragment_height / 2); reverse_dc_prediction(s, s->fragment_start[2], s->fragment_width / 2, s->fragment_height / 2); } STOP_TIMER("reverse_dc_prediction")} {START_TIMER for (i = 0; i < s->macroblock_height; i++) render_slice(s, i); STOP_TIMER("render_fragments")} {START_TIMER apply_loop_filter(s); STOP_TIMER("apply_loop_filter")} #if KEYFRAMES_ONLY } #endif *data_size=sizeof(AVFrame); *(AVFrame*)data= s->current_frame; /* release the last frame, if it is allocated and if it is not the * golden frame */ if ((s->last_frame.data[0]) && (s->last_frame.data[0] != s->golden_frame.data[0])) avctx->release_buffer(avctx, &s->last_frame); /* shuffle frames (last = current) */ s->last_frame= s->current_frame; s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */ return buf_size; }


static char *ts_value_string (char *buf, int buf_size, int64_t ts) { if (ts == AV_NOPTS_VALUE) { snprintf(buf, buf_size, "N/A"); } else { snprintf(buf, buf_size, "%"PRId64, ts); } return buf; }


void pci_ne2000_init(PCIBus *bus, NICInfo *nd) { PCINE2000State *d; NE2000State *s; uint8_t *pci_conf; d = (PCINE2000State *)pci_register_device(bus, "NE2000", sizeof(PCINE2000State), -1, NULL, NULL); pci_conf = d->dev.config; pci_conf[0x00] = 0xec; // Realtek 8029 pci_conf[0x01] = 0x10; pci_conf[0x02] = 0x29; pci_conf[0x03] = 0x80; pci_conf[0x0a] = 0x00; // ethernet network controller pci_conf[0x0b] = 0x02; pci_conf[0x0e] = 0x00; // header_type pci_conf[0x3d] = 1; // interrupt pin 0 pci_register_io_region(&d->dev, 0, 0x100, PCI_ADDRESS_SPACE_IO, ne2000_map); s = &d->ne2000; s->irq = 16; // PCI interrupt s->pci_dev = (PCIDevice *)d; memcpy(s->macaddr, nd->macaddr, 6); ne2000_reset(s); s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s); snprintf(s->vc->info_str, sizeof(s->vc->info_str), "ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x", s->macaddr[0], s->macaddr[1], s->macaddr[2], s->macaddr[3], s->macaddr[4], s->macaddr[5]); /* XXX: instance number ? */ register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s); register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load, &d->dev); }


static int decode_bdlt(uint8_t *frame, int width, int height, const uint8_t *src, const uint8_t *src_end) { const uint8_t *frame_end = frame + width * height; uint8_t *line_ptr; int count, lines, segments; count = bytestream_get_le16(&src); if (count >= height || width * count < 0) return -1; frame += width * count; lines = bytestream_get_le16(&src); if (frame + lines * width > frame_end || src >= src_end) return -1; while (lines--) { line_ptr = frame; frame += width; segments = *src++; while (segments--) { if (src_end - src < 3) return -1; line_ptr += *src++; if (line_ptr >= frame) return -1; count = (int8_t)*src++; if (count >= 0) { if (line_ptr + count > frame || src_end - src < count) return -1; bytestream_get_buffer(&src, line_ptr, count); } else { count = -count; if (line_ptr + count > frame || src >= src_end) return -1; memset(line_ptr, *src++, count); } line_ptr += count; } } return 0; }