static void disas_arm_insn(CPUState * env, DisasContext *s) { unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; TCGv tmp; TCGv tmp2; TCGv tmp3; TCGv addr; TCGv_i64 tmp64; insn = ldl_code(s->pc); s->pc += 4; /* M variants do not implement ARM mode. */ if (IS_M(env)) goto illegal_op; cond = insn >> 28; if (cond == 0xf){ /* Unconditional instructions. */ if (((insn >> 25) & 7) == 1) { /* NEON Data processing. */ if (!arm_feature(env, ARM_FEATURE_NEON)) goto illegal_op; if (disas_neon_data_insn(env, s, insn)) goto illegal_op; return; } if ((insn & 0x0f100000) == 0x04000000) { /* NEON load/store. */ if (!arm_feature(env, ARM_FEATURE_NEON)) goto illegal_op; if (disas_neon_ls_insn(env, s, insn)) goto illegal_op; return; } if (((insn & 0x0f30f000) == 0x0510f000) || ((insn & 0x0f30f010) == 0x0710f000)) { if ((insn & (1 << 22)) == 0) { /* PLDW; v7MP */ if (!arm_feature(env, ARM_FEATURE_V7MP)) { goto illegal_op; } } /* Otherwise PLD; v5TE+ */ return; } if (((insn & 0x0f70f000) == 0x0450f000) || ((insn & 0x0f70f010) == 0x0650f000)) { ARCH(7); return; /* PLI; V7 */ } if (((insn & 0x0f700000) == 0x04100000) || ((insn & 0x0f700010) == 0x06100000)) { if (!arm_feature(env, ARM_FEATURE_V7MP)) { goto illegal_op; } return; /* v7MP: Unallocated memory hint: must NOP */ } if ((insn & 0x0ffffdff) == 0x01010000) { ARCH(6); /* setend */ if (insn & (1 << 9)) { /* BE8 mode not implemented. */ goto illegal_op; } return; } else if ((insn & 0x0fffff00) == 0x057ff000) { switch ((insn >> 4) & 0xf) { case 1: /* clrex */ ARCH(6K); gen_clrex(s); return; case 4: /* dsb */ case 5: /* dmb */ case 6: /* isb */ ARCH(7); /* We don't emulate caches so these are a no-op. */ return; default: goto illegal_op; } } else if ((insn & 0x0e5fffe0) == 0x084d0500) { /* srs */ int32_t offset; if (IS_USER(s)) goto illegal_op; ARCH(6); op1 = (insn & 0x1f); addr = tcg_temp_new_i32(); tmp = tcg_const_i32(op1); gen_helper_get_r13_banked(addr, cpu_env, tmp); tcg_temp_free_i32(tmp); i = (insn >> 23) & 3; switch (i) { case 0: offset = -4; break; /* DA */ case 1: offset = 0; break; /* IA */ case 2: offset = -8; break; /* DB */ case 3: offset = 4; break; /* IB */ default: abort(); } if (offset) tcg_gen_addi_i32(addr, addr, offset); tmp = load_reg(s, 14); gen_st32(tmp, addr, 0); tmp = load_cpu_field(spsr); tcg_gen_addi_i32(addr, addr, 4); gen_st32(tmp, addr, 0); if (insn & (1 << 21)) { /* Base writeback. */ switch (i) { case 0: offset = -8; break; case 1: offset = 4; break; case 2: offset = -4; break; case 3: offset = 0; break; default: abort(); } if (offset) tcg_gen_addi_i32(addr, addr, offset); tmp = tcg_const_i32(op1); gen_helper_set_r13_banked(cpu_env, tmp, addr); tcg_temp_free_i32(tmp); tcg_temp_free_i32(addr); } else { tcg_temp_free_i32(addr); } return; } else if ((insn & 0x0e50ffe0) == 0x08100a00) { /* rfe */ int32_t offset; if (IS_USER(s)) goto illegal_op; ARCH(6); rn = (insn >> 16) & 0xf; addr = load_reg(s, rn); i = (insn >> 23) & 3; switch (i) { case 0: offset = -4; break; /* DA */ case 1: offset = 0; break; /* IA */ case 2: offset = -8; break; /* DB */ case 3: offset = 4; break; /* IB */ default: abort(); } if (offset) tcg_gen_addi_i32(addr, addr, offset); /* Load PC into tmp and CPSR into tmp2. */ tmp = gen_ld32(addr, 0); tcg_gen_addi_i32(addr, addr, 4); tmp2 = gen_ld32(addr, 0); if (insn & (1 << 21)) { /* Base writeback. */ switch (i) { case 0: offset = -8; break; case 1: offset = 4; break; case 2: offset = -4; break; case 3: offset = 0; break; default: abort(); } if (offset) tcg_gen_addi_i32(addr, addr, offset); store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } gen_rfe(s, tmp, tmp2); return; } else if ((insn & 0x0e000000) == 0x0a000000) { /* branch link and change to thumb (blx <offset>) */ int32_t offset; val = (uint32_t)s->pc; tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); store_reg(s, 14, tmp); /* Sign-extend the 24-bit offset */ offset = (((int32_t)insn) << 8) >> 8; /* offset * 4 + bit24 * 2 + (thumb bit) */ val += (offset << 2) | ((insn >> 23) & 2) | 1; /* pipeline offset */ val += 4; gen_bx_im(s, val); return; } else if ((insn & 0x0e000f00) == 0x0c000100) { if (arm_feature(env, ARM_FEATURE_IWMMXT)) { /* iWMMXt register transfer. */ if (env->cp15.c15_cpar & (1 << 1)) if (!disas_iwmmxt_insn(env, s, insn)) return; } } else if ((insn & 0x0fe00000) == 0x0c400000) { /* Coprocessor double register transfer. */ } else if ((insn & 0x0f000010) == 0x0e000010) { /* Additional coprocessor register transfer. */ } else if ((insn & 0x0ff10020) == 0x01000000) { uint32_t mask; uint32_t val; /* cps (privileged) */ if (IS_USER(s)) return; mask = val = 0; if (insn & (1 << 19)) { if (insn & (1 << 8)) mask |= CPSR_A; if (insn & (1 << 7)) mask |= CPSR_I; if (insn & (1 << 6)) mask |= CPSR_F; if (insn & (1 << 18)) val |= mask; } if (insn & (1 << 17)) { mask |= CPSR_M; val |= (insn & 0x1f); } if (mask) { gen_set_psr_im(s, mask, 0, val); } return; } goto illegal_op; } if (cond != 0xe) { /* if not always execute, we generate a conditional jump to next instruction */ s->condlabel = gen_new_label(); gen_test_cc(cond ^ 1, s->condlabel); s->condjmp = 1; } if ((insn & 0x0f900000) == 0x03000000) { if ((insn & (1 << 21)) == 0) { ARCH(6T2); rd = (insn >> 12) & 0xf; val = ((insn >> 4) & 0xf000) | (insn & 0xfff); if ((insn & (1 << 22)) == 0) { /* MOVW */ tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); } else { /* MOVT */ tmp = load_reg(s, rd); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_ori_i32(tmp, tmp, val << 16); } store_reg(s, rd, tmp); } else { if (((insn >> 12) & 0xf) != 0xf) goto illegal_op; if (((insn >> 16) & 0xf) == 0) { gen_nop_hint(s, insn & 0xff); } else { /* CPSR = immediate */ val = insn & 0xff; shift = ((insn >> 8) & 0xf) * 2; if (shift) val = (val >> shift) | (val << (32 - shift)); i = ((insn & (1 << 22)) != 0); if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val)) goto illegal_op; } } } else if ((insn & 0x0f900000) == 0x01000000 && (insn & 0x00000090) != 0x00000090) { /* miscellaneous instructions */ op1 = (insn >> 21) & 3; sh = (insn >> 4) & 0xf; rm = insn & 0xf; switch (sh) { case 0x0: /* move program status register */ if (op1 & 1) { /* PSR = reg */ tmp = load_reg(s, rm); i = ((op1 & 2) != 0); if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp)) goto illegal_op; } else { /* reg = PSR */ rd = (insn >> 12) & 0xf; if (op1 & 2) { if (IS_USER(s)) goto illegal_op; tmp = load_cpu_field(spsr); } else { tmp = tcg_temp_new_i32(); gen_helper_cpsr_read(tmp); } store_reg(s, rd, tmp); } break; case 0x1: if (op1 == 1) { /* branch/exchange thumb (bx). */ tmp = load_reg(s, rm); gen_bx(s, tmp); } else if (op1 == 3) { /* clz */ rd = (insn >> 12) & 0xf; tmp = load_reg(s, rm); gen_helper_clz(tmp, tmp); store_reg(s, rd, tmp); } else { goto illegal_op; } break; case 0x2: if (op1 == 1) { ARCH(5J); /* bxj */ /* Trivial implementation equivalent to bx. */ tmp = load_reg(s, rm); gen_bx(s, tmp); } else { goto illegal_op; } break; case 0x3: if (op1 != 1) goto illegal_op; /* branch link/exchange thumb (blx) */ tmp = load_reg(s, rm); tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc); store_reg(s, 14, tmp2); gen_bx(s, tmp); break; case 0x5: /* saturating add/subtract */ rd = (insn >> 12) & 0xf; rn = (insn >> 16) & 0xf; tmp = load_reg(s, rm); tmp2 = load_reg(s, rn); if (op1 & 2) gen_helper_double_saturate(tmp2, tmp2); if (op1 & 1) gen_helper_sub_saturate(tmp, tmp, tmp2); else gen_helper_add_saturate(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 7: /* SMC instruction (op1 == 3) and undefined instructions (op1 == 0 || op1 == 2) will trap */ if (op1 != 1) { goto illegal_op; } /* bkpt */ gen_exception_insn(s, 4, EXCP_BKPT); break; case 0x8: /* signed multiply */ case 0xa: case 0xc: case 0xe: rs = (insn >> 8) & 0xf; rn = (insn >> 12) & 0xf; rd = (insn >> 16) & 0xf; if (op1 == 1) { /* (32 * 16) >> 16 */ tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); if (sh & 4) tcg_gen_sari_i32(tmp2, tmp2, 16); else gen_sxth(tmp2); tmp64 = gen_muls_i64_i32(tmp, tmp2); tcg_gen_shri_i64(tmp64, tmp64, 16); tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); if ((sh & 2) == 0) { tmp2 = load_reg(s, rn); gen_helper_add_setq(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); } else { /* 16 * 16 */ tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); gen_mulxy(tmp, tmp2, sh & 2, sh & 4); tcg_temp_free_i32(tmp2); if (op1 == 2) { tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rn, rd); gen_storeq_reg(s, rn, rd, tmp64); tcg_temp_free_i64(tmp64); } else { if (op1 == 0) { tmp2 = load_reg(s, rn); gen_helper_add_setq(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); } } break; default: goto illegal_op; } } else if (((insn & 0x0e000000) == 0 && (insn & 0x00000090) != 0x90) || ((insn & 0x0e000000) == (1 << 25))) { int set_cc, logic_cc, shiftop; op1 = (insn >> 21) & 0xf; set_cc = (insn >> 20) & 1; logic_cc = table_logic_cc[op1] & set_cc; /* data processing instruction */ if (insn & (1 << 25)) { /* immediate operand */ val = insn & 0xff; shift = ((insn >> 8) & 0xf) * 2; if (shift) { val = (val >> shift) | (val << (32 - shift)); } tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, val); if (logic_cc && shift) { gen_set_CF_bit31(tmp2); } } else { /* register */ rm = (insn) & 0xf; tmp2 = load_reg(s, rm); shiftop = (insn >> 5) & 3; if (!(insn & (1 << 4))) { shift = (insn >> 7) & 0x1f; gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); } else { rs = (insn >> 8) & 0xf; tmp = load_reg(s, rs); gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc); } } if (op1 != 0x0f && op1 != 0x0d) { rn = (insn >> 16) & 0xf; tmp = load_reg(s, rn); } else { TCGV_UNUSED(tmp); } rd = (insn >> 12) & 0xf; switch(op1) { case 0x00: tcg_gen_and_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x01: tcg_gen_xor_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x02: if (set_cc && rd == 15) { /* SUBS r15, ... is used for exception return. */ if (IS_USER(s)) { goto illegal_op; } gen_helper_sub_cc(tmp, tmp, tmp2); gen_exception_return(s, tmp); } else { if (set_cc) { gen_helper_sub_cc(tmp, tmp, tmp2); } else { tcg_gen_sub_i32(tmp, tmp, tmp2); } store_reg_bx(env, s, rd, tmp); } break; case 0x03: if (set_cc) { gen_helper_sub_cc(tmp, tmp2, tmp); } else { tcg_gen_sub_i32(tmp, tmp2, tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x04: if (set_cc) { gen_helper_add_cc(tmp, tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); } store_reg_bx(env, s, rd, tmp); break; case 0x05: if (set_cc) { gen_helper_adc_cc(tmp, tmp, tmp2); } else { gen_add_carry(tmp, tmp, tmp2); } store_reg_bx(env, s, rd, tmp); break; case 0x06: if (set_cc) { gen_helper_sbc_cc(tmp, tmp, tmp2); } else { gen_sub_carry(tmp, tmp, tmp2); } store_reg_bx(env, s, rd, tmp); break; case 0x07: if (set_cc) { gen_helper_sbc_cc(tmp, tmp2, tmp); } else { gen_sub_carry(tmp, tmp2, tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x08: if (set_cc) { tcg_gen_and_i32(tmp, tmp, tmp2); gen_logic_CC(tmp); } tcg_temp_free_i32(tmp); break; case 0x09: if (set_cc) { tcg_gen_xor_i32(tmp, tmp, tmp2); gen_logic_CC(tmp); } tcg_temp_free_i32(tmp); break; case 0x0a: if (set_cc) { gen_helper_sub_cc(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp); break; case 0x0b: if (set_cc) { gen_helper_add_cc(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp); break; case 0x0c: tcg_gen_or_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x0d: if (logic_cc && rd == 15) { /* MOVS r15, ... is used for exception return. */ if (IS_USER(s)) { goto illegal_op; } gen_exception_return(s, tmp2); } else { if (logic_cc) { gen_logic_CC(tmp2); } store_reg_bx(env, s, rd, tmp2); } break; case 0x0e: tcg_gen_andc_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } store_reg_bx(env, s, rd, tmp); break; default: case 0x0f: tcg_gen_not_i32(tmp2, tmp2); if (logic_cc) { gen_logic_CC(tmp2); } store_reg_bx(env, s, rd, tmp2); break; } if (op1 != 0x0f && op1 != 0x0d) { tcg_temp_free_i32(tmp2); } } else { /* other instructions */ op1 = (insn >> 24) & 0xf; switch(op1) { case 0x0: case 0x1: /* multiplies, extra load/stores */ sh = (insn >> 5) & 3; if (sh == 0) { if (op1 == 0x0) { rd = (insn >> 16) & 0xf; rn = (insn >> 12) & 0xf; rs = (insn >> 8) & 0xf; rm = (insn) & 0xf; op1 = (insn >> 20) & 0xf; switch (op1) { case 0: case 1: case 2: case 3: case 6: /* 32 bit mul */ tmp = load_reg(s, rs); tmp2 = load_reg(s, rm); tcg_gen_mul_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); if (insn & (1 << 22)) { /* Subtract (mls) */ ARCH(6T2); tmp2 = load_reg(s, rn); tcg_gen_sub_i32(tmp, tmp2, tmp); tcg_temp_free_i32(tmp2); } else if (insn & (1 << 21)) { /* Add */ tmp2 = load_reg(s, rn); tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } if (insn & (1 << 20)) gen_logic_CC(tmp); store_reg(s, rd, tmp); break; case 4: /* 64 bit mul double accumulate (UMAAL) */ ARCH(6); tmp = load_reg(s, rs); tmp2 = load_reg(s, rm); tmp64 = gen_mulu_i64_i32(tmp, tmp2); gen_addq_lo(s, tmp64, rn); gen_addq_lo(s, tmp64, rd); gen_storeq_reg(s, rn, rd, tmp64); tcg_temp_free_i64(tmp64); break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */ tmp = load_reg(s, rs); tmp2 = load_reg(s, rm); if (insn & (1 << 22)) { tmp64 = gen_muls_i64_i32(tmp, tmp2); } else { tmp64 = gen_mulu_i64_i32(tmp, tmp2); } if (insn & (1 << 21)) { /* mult accumulate */ gen_addq(s, tmp64, rn, rd); } if (insn & (1 << 20)) { gen_logicq_cc(tmp64); } gen_storeq_reg(s, rn, rd, tmp64); tcg_temp_free_i64(tmp64); break; default: goto illegal_op; } } else { rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; if (insn & (1 << 23)) { /* load/store exclusive */ op1 = (insn >> 21) & 0x3; if (op1) ARCH(6K); else ARCH(6); addr = tcg_temp_local_new_i32(); load_reg_var(s, addr, rn); if (insn & (1 << 20)) { switch (op1) { case 0: /* ldrex */ gen_load_exclusive(s, rd, 15, addr, 2); break; case 1: /* ldrexd */ gen_load_exclusive(s, rd, rd + 1, addr, 3); break; case 2: /* ldrexb */ gen_load_exclusive(s, rd, 15, addr, 0); break; case 3: /* ldrexh */ gen_load_exclusive(s, rd, 15, addr, 1); break; default: abort(); } } else { rm = insn & 0xf; switch (op1) { case 0: /* strex */ gen_store_exclusive(s, rd, rm, 15, addr, 2); break; case 1: /* strexd */ gen_store_exclusive(s, rd, rm, rm + 1, addr, 3); break; case 2: /* strexb */ gen_store_exclusive(s, rd, rm, 15, addr, 0); break; case 3: /* strexh */ gen_store_exclusive(s, rd, rm, 15, addr, 1); break; default: abort(); } } tcg_temp_free(addr); } else { /* SWP instruction */ rm = (insn) & 0xf; /* ??? This is not really atomic. However we know we never have multiple CPUs running in parallel, so it is good enough. */ addr = load_reg(s, rn); tmp = load_reg(s, rm); if (insn & (1 << 22)) { tmp2 = gen_ld8u(addr, IS_USER(s)); gen_st8(tmp, addr, IS_USER(s)); } else { tmp2 = gen_ld32(addr, IS_USER(s)); gen_st32(tmp, addr, IS_USER(s)); } tcg_temp_free_i32(addr); store_reg(s, rd, tmp2); } } } else { int address_offset; int load; /* Misc load/store */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; addr = load_reg(s, rn); if (insn & (1 << 24)) gen_add_datah_offset(s, insn, 0, addr); address_offset = 0; if (insn & (1 << 20)) { /* load */ switch(sh) { case 1: tmp = gen_ld16u(addr, IS_USER(s)); break; case 2: tmp = gen_ld8s(addr, IS_USER(s)); break; default: case 3: tmp = gen_ld16s(addr, IS_USER(s)); break; } load = 1; } else if (sh & 2) { /* doubleword */ if (sh & 1) { /* store */ tmp = load_reg(s, rd); gen_st32(tmp, addr, IS_USER(s)); tcg_gen_addi_i32(addr, addr, 4); tmp = load_reg(s, rd + 1); gen_st32(tmp, addr, IS_USER(s)); load = 0; } else { /* load */ tmp = gen_ld32(addr, IS_USER(s)); store_reg(s, rd, tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = gen_ld32(addr, IS_USER(s)); rd++; load = 1; } address_offset = -4; } else { /* store */ tmp = load_reg(s, rd); gen_st16(tmp, addr, IS_USER(s)); load = 0; } /* Perform base writeback before the loaded value to ensure correct behavior with overlapping index registers. ldrd with base writeback is is undefined if the destination and index registers overlap. */ if (!(insn & (1 << 24))) { gen_add_datah_offset(s, insn, address_offset, addr); store_reg(s, rn, addr); } else if (insn & (1 << 21)) { if (address_offset) tcg_gen_addi_i32(addr, addr, address_offset); store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } if (load) { /* Complete the load. */ store_reg(s, rd, tmp); } } break; case 0x4: case 0x5: goto do_ldst; case 0x6: case 0x7: if (insn & (1 << 4)) { ARCH(6); /* Armv6 Media instructions. */ rm = insn & 0xf; rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; rs = (insn >> 8) & 0xf; switch ((insn >> 23) & 3) { case 0: /* Parallel add/subtract. */ op1 = (insn >> 20) & 7; tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); sh = (insn >> 5) & 7; if ((op1 & 3) == 0 || sh == 5 || sh == 6) goto illegal_op; gen_arm_parallel_addsub(op1, sh, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 1: if ((insn & 0x00700020) == 0) { /* Halfword pack. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); shift = (insn >> 7) & 0x1f; if (insn & (1 << 6)) { /* pkhtb */ if (shift == 0) shift = 31; tcg_gen_sari_i32(tmp2, tmp2, shift); tcg_gen_andi_i32(tmp, tmp, 0xffff0000); tcg_gen_ext16u_i32(tmp2, tmp2); } else { /* pkhbt */ if (shift) tcg_gen_shli_i32(tmp2, tmp2, shift); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); } tcg_gen_or_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x00200020) == 0x00200000) { /* [us]sat */ tmp = load_reg(s, rm); shift = (insn >> 7) & 0x1f; if (insn & (1 << 6)) { if (shift == 0) shift = 31; tcg_gen_sari_i32(tmp, tmp, shift); } else { tcg_gen_shli_i32(tmp, tmp, shift); } sh = (insn >> 16) & 0x1f; tmp2 = tcg_const_i32(sh); if (insn & (1 << 22)) gen_helper_usat(tmp, tmp, tmp2); else gen_helper_ssat(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x00300fe0) == 0x00200f20) { /* [us]sat16 */ tmp = load_reg(s, rm); sh = (insn >> 16) & 0x1f; tmp2 = tcg_const_i32(sh); if (insn & (1 << 22)) gen_helper_usat16(tmp, tmp, tmp2); else gen_helper_ssat16(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x00700fe0) == 0x00000fa0) { /* Select bytes. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); tmp3 = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE)); gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); tcg_temp_free_i32(tmp3); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x000003e0) == 0x00000060) { tmp = load_reg(s, rm); shift = (insn >> 10) & 3; /* ??? In many cases it's not neccessary to do a rotate, a shift is sufficient. */ if (shift != 0) tcg_gen_rotri_i32(tmp, tmp, shift * 8); op1 = (insn >> 20) & 7; switch (op1) { case 0: gen_sxtb16(tmp); break; case 2: gen_sxtb(tmp); break; case 3: gen_sxth(tmp); break; case 4: gen_uxtb16(tmp); break; case 6: gen_uxtb(tmp); break; case 7: gen_uxth(tmp); break; default: goto illegal_op; } if (rn != 15) { tmp2 = load_reg(s, rn); if ((op1 & 3) == 0) { gen_add16(tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } } store_reg(s, rd, tmp); } else if ((insn & 0x003f0f60) == 0x003f0f20) { /* rev */ tmp = load_reg(s, rm); if (insn & (1 << 22)) { if (insn & (1 << 7)) { gen_revsh(tmp); } else { ARCH(6T2); gen_helper_rbit(tmp, tmp); } } else { if (insn & (1 << 7)) gen_rev16(tmp); else tcg_gen_bswap32_i32(tmp, tmp); } store_reg(s, rd, tmp); } else { goto illegal_op; } break; case 2: /* Multiplies (Type 3). */ tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); if (insn & (1 << 20)) { /* Signed multiply most significant [accumulate]. (SMMUL, SMMLA, SMMLS) */ tmp64 = gen_muls_i64_i32(tmp, tmp2); if (rd != 15) { tmp = load_reg(s, rd); if (insn & (1 << 6)) { tmp64 = gen_subq_msw(tmp64, tmp); } else { tmp64 = gen_addq_msw(tmp64, tmp); } } if (insn & (1 << 5)) { tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); } tcg_gen_shri_i64(tmp64, tmp64, 32); tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); store_reg(s, rn, tmp); } else { if (insn & (1 << 5)) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); if (insn & (1 << 6)) { /* This subtraction cannot overflow. */ tcg_gen_sub_i32(tmp, tmp, tmp2); } else { /* This addition cannot overflow 32 bits; * however it may overflow considered as a signed * operation, in which case we must set the Q flag. */ gen_helper_add_setq(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp2); if (insn & (1 << 22)) { /* smlald, smlsld */ tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rd, rn); gen_storeq_reg(s, rd, rn, tmp64); tcg_temp_free_i64(tmp64); } else { /* smuad, smusd, smlad, smlsd */ if (rd != 15) { tmp2 = load_reg(s, rd); gen_helper_add_setq(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } store_reg(s, rn, tmp); } } break; case 3: op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7); switch (op1) { case 0: /* Unsigned sum of absolute differences. */ ARCH(6); tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); gen_helper_usad8(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); if (rd != 15) { tmp2 = load_reg(s, rd); tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } store_reg(s, rn, tmp); break; case 0x20: case 0x24: case 0x28: case 0x2c: /* Bitfield insert/clear. */ ARCH(6T2); shift = (insn >> 7) & 0x1f; i = (insn >> 16) & 0x1f; i = i + 1 - shift; if (rm == 15) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rm); } if (i != 32) { tmp2 = load_reg(s, rd); gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1); tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); break; case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */ case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */ ARCH(6T2); tmp = load_reg(s, rm); shift = (insn >> 7) & 0x1f; i = ((insn >> 16) & 0x1f) + 1; if (shift + i > 32) goto illegal_op; if (i < 32) { if (op1 & 0x20) { gen_ubfx(tmp, shift, (1u << i) - 1); } else { gen_sbfx(tmp, shift, i); } } store_reg(s, rd, tmp); break; default: goto illegal_op; } break; } break; } do_ldst: /* Check for undefined extension instructions * per the ARM Bible IE: * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx */ sh = (0xf << 20) | (0xf << 4); if (op1 == 0x7 && ((insn & sh) == sh)) { goto illegal_op; } /* load/store byte/word */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; tmp2 = load_reg(s, rn); i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000); if (insn & (1 << 24)) gen_add_data_offset(s, insn, tmp2); if (insn & (1 << 20)) { /* load */ if (insn & (1 << 22)) { tmp = gen_ld8u(tmp2, i); } else { tmp = gen_ld32(tmp2, i); } } else { /* store */ tmp = load_reg(s, rd); if (insn & (1 << 22)) gen_st8(tmp, tmp2, i); else gen_st32(tmp, tmp2, i); } if (!(insn & (1 << 24))) { gen_add_data_offset(s, insn, tmp2); store_reg(s, rn, tmp2); } else if (insn & (1 << 21)) { store_reg(s, rn, tmp2); } else { tcg_temp_free_i32(tmp2); } if (insn & (1 << 20)) { /* Complete the load. */ if (rd == 15) gen_bx(s, tmp); else store_reg(s, rd, tmp); } break; case 0x08: case 0x09: { int j, n, user, loaded_base; TCGv loaded_var; /* load/store multiple words */ /* XXX: store correct base if write back */ user = 0; if (insn & (1 << 22)) { if (IS_USER(s)) goto illegal_op; /* only usable in supervisor mode */ if ((insn & (1 << 15)) == 0) user = 1; } rn = (insn >> 16) & 0xf; addr = load_reg(s, rn); /* compute total size */ loaded_base = 0; TCGV_UNUSED(loaded_var); n = 0; for(i=0;i<16;i++) { if (insn & (1 << i)) n++; } /* XXX: test invalid n == 0 case ? */ if (insn & (1 << 23)) { if (insn & (1 << 24)) { /* pre increment */ tcg_gen_addi_i32(addr, addr, 4); } else { /* post increment */ } } else { if (insn & (1 << 24)) { /* pre decrement */ tcg_gen_addi_i32(addr, addr, -(n * 4)); } else { /* post decrement */ if (n != 1) tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); } } j = 0; for(i=0;i<16;i++) { if (insn & (1 << i)) { if (insn & (1 << 20)) { /* load */ tmp = gen_ld32(addr, IS_USER(s)); if (i == 15) { gen_bx(s, tmp); } else if (user) { tmp2 = tcg_const_i32(i); gen_helper_set_user_reg(tmp2, tmp); tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp); } else if (i == rn) { loaded_var = tmp; loaded_base = 1; } else { store_reg(s, i, tmp); } } else { /* store */ if (i == 15) { /* special case: r15 = PC + 8 */ val = (long)s->pc + 4; tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); } else if (user) { tmp = tcg_temp_new_i32(); tmp2 = tcg_const_i32(i); gen_helper_get_user_reg(tmp, tmp2); tcg_temp_free_i32(tmp2); } else { tmp = load_reg(s, i); } gen_st32(tmp, addr, IS_USER(s)); } j++; /* no need to add after the last transfer */ if (j != n) tcg_gen_addi_i32(addr, addr, 4); } } if (insn & (1 << 21)) { /* write back */ if (insn & (1 << 23)) { if (insn & (1 << 24)) { /* pre increment */ } else { /* post increment */ tcg_gen_addi_i32(addr, addr, 4); } } else { if (insn & (1 << 24)) { /* pre decrement */ if (n != 1) tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); } else { /* post decrement */ tcg_gen_addi_i32(addr, addr, -(n * 4)); } } store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } if (loaded_base) { store_reg(s, rn, loaded_var); } if ((insn & (1 << 22)) && !user) { /* Restore CPSR from SPSR. */ tmp = load_cpu_field(spsr); gen_set_cpsr(tmp, 0xffffffff); tcg_temp_free_i32(tmp); s->is_jmp = DISAS_UPDATE; } } break; case 0xa: case 0xb: { int32_t offset; /* branch (and link) */ val = (int32_t)s->pc; if (insn & (1 << 24)) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); store_reg(s, 14, tmp); } offset = (((int32_t)insn << 8) >> 8); val += (offset << 2) + 4; gen_jmp(s, val); } break; case 0xc: case 0xd: case 0xe: /* Coprocessor. */ if (disas_coproc_insn(env, s, insn)) goto illegal_op; break; case 0xf: /* swi */ gen_set_pc_im(s->pc); s->is_jmp = DISAS_SWI; break; default: illegal_op: gen_exception_insn(s, 4, EXCP_UDEF); break; } } }


static int ppc_hash64_translate(CPUPPCState *env, struct mmu_ctx_hash64 *ctx, target_ulong eaddr, int rwx) { int ret; ppc_slb_t *slb; hwaddr pte_offset; ppc_hash_pte64_t pte; int target_page_bits; assert((rwx == 0) || (rwx == 1) || (rwx == 2)); /* 1. Handle real mode accesses */ if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) { /* Translation is off */ /* In real mode the top 4 effective address bits are ignored */ ctx->raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL; ctx->prot = PAGE_READ | PAGE_EXEC | PAGE_WRITE; return 0; } /* 2. Translation is on, so look up the SLB */ slb = slb_lookup(env, eaddr); if (!slb) { return -5; } /* 3. Check for segment level no-execute violation */ if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) { return -3; } /* 4. Locate the PTE in the hash table */ pte_offset = ppc_hash64_htab_lookup(env, slb, eaddr, &pte); if (pte_offset == -1) { return -1; } LOG_MMU("found PTE at offset %08" HWADDR_PRIx "\n", pte_offset); /* 5. Check access permissions */ ctx->key = !!(msr_pr ? (slb->vsid & SLB_VSID_KP) : (slb->vsid & SLB_VSID_KS)); int access, pp; bool nx; pp = (pte.pte1 & HPTE64_R_PP) | ((pte.pte1 & HPTE64_R_PP0) >> 61); /* No execute if either noexec or guarded bits set */ nx = (pte.pte1 & HPTE64_R_N) || (pte.pte1 & HPTE64_R_G); /* Compute access rights */ access = ppc_hash64_pp_check(ctx->key, pp, nx); /* Keep the matching PTE informations */ ctx->raddr = pte.pte1; ctx->prot = access; ret = ppc_hash64_check_prot(ctx->prot, rwx); if (ret) { /* Access right violation */ LOG_MMU("PTE access rejected\n"); return ret; } LOG_MMU("PTE access granted !\n"); /* 6. Update PTE referenced and changed bits if necessary */ if (ppc_hash64_pte_update_flags(ctx, &pte.pte1, ret, rwx) == 1) { ppc_hash64_store_hpte1(env, pte_offset, pte.pte1); } /* We have a TLB that saves 4K pages, so let's * split a huge page to 4k chunks */ target_page_bits = (slb->vsid & SLB_VSID_L) ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS; if (target_page_bits != TARGET_PAGE_BITS) { ctx->raddr |= (eaddr & ((1 << target_page_bits) - 1)) & TARGET_PAGE_MASK; } return ret; }


void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi, ISADevice **rtc_state, ISADevice **floppy, bool no_vmport) { int i; DriveInfo *fd[MAX_FD]; DeviceState *hpet = NULL; int pit_isa_irq = 0; qemu_irq pit_alt_irq = NULL; qemu_irq rtc_irq = NULL; qemu_irq *a20_line; ISADevice *i8042, *port92, *vmmouse, *pit; qemu_irq *cpu_exit_irq; register_ioport_write(0x80, 1, 1, ioport80_write, NULL); register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); /* * Check if an HPET shall be created. * * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT * when the HPET wants to take over. Thus we have to disable the latter. */ if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { hpet = sysbus_try_create_simple("hpet", HPET_BASE, NULL); if (hpet) { for (i = 0; i < GSI_NUM_PINS; i++) { sysbus_connect_irq(sysbus_from_qdev(hpet), i, gsi[i]); } pit_isa_irq = -1; pit_alt_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_PIT_INT); rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT); } } *rtc_state = rtc_init(isa_bus, 2000, rtc_irq); qemu_register_boot_set(pc_boot_set, *rtc_state); if (kvm_irqchip_in_kernel()) { pit = kvm_pit_init(isa_bus, 0x40); } else { pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq); } if (hpet) { /* connect PIT to output control line of the HPET */ qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(&pit->qdev, 0)); } pcspk_init(isa_bus, pit); for(i = 0; i < MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { serial_isa_init(isa_bus, i, serial_hds[i]); } } for(i = 0; i < MAX_PARALLEL_PORTS; i++) { if (parallel_hds[i]) { parallel_init(isa_bus, i, parallel_hds[i]); } } a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2); i8042 = isa_create_simple(isa_bus, "i8042"); i8042_setup_a20_line(i8042, &a20_line[0]); if (!no_vmport) { vmport_init(isa_bus); vmmouse = isa_try_create(isa_bus, "vmmouse"); } else { vmmouse = NULL; } if (vmmouse) { qdev_prop_set_ptr(&vmmouse->qdev, "ps2_mouse", i8042); qdev_init_nofail(&vmmouse->qdev); } port92 = isa_create_simple(isa_bus, "port92"); port92_init(port92, &a20_line[1]); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } *floppy = fdctrl_init_isa(isa_bus, fd); }


void stream_start(BlockDriverState *bs, BlockDriverState *base, const char *base_id, BlockDriverCompletionFunc *cb, void *opaque, Error **errp) { StreamBlockJob *s; Coroutine *co; s = block_job_create(&stream_job_type, bs, cb, opaque, errp); if (!s) { return; } s->base = base; if (base_id) { pstrcpy(s->backing_file_id, sizeof(s->backing_file_id), base_id); } co = qemu_coroutine_create(stream_run); trace_stream_start(bs, base, s, co, opaque); qemu_coroutine_enter(co, s); }


static int decode_subframe(WMAProDecodeCtx *s) { int offset = s->samples_per_frame; int subframe_len = s->samples_per_frame; int i; int total_samples = s->samples_per_frame * s->num_channels; int transmit_coeffs = 0; int cur_subwoofer_cutoff; s->subframe_offset = get_bits_count(&s->gb); /** reset channel context and find the next block offset and size == the next block of the channel with the smallest number of decoded samples */ for (i = 0; i < s->num_channels; i++) { s->channel[i].grouped = 0; if (offset > s->channel[i].decoded_samples) { offset = s->channel[i].decoded_samples; subframe_len = s->channel[i].subframe_len[s->channel[i].cur_subframe]; } } av_dlog(s->avctx, "processing subframe with offset %i len %i\n", offset, subframe_len); /** get a list of all channels that contain the estimated block */ s->channels_for_cur_subframe = 0; for (i = 0; i < s->num_channels; i++) { const int cur_subframe = s->channel[i].cur_subframe; /** substract already processed samples */ total_samples -= s->channel[i].decoded_samples; /** and count if there are multiple subframes that match our profile */ if (offset == s->channel[i].decoded_samples && subframe_len == s->channel[i].subframe_len[cur_subframe]) { total_samples -= s->channel[i].subframe_len[cur_subframe]; s->channel[i].decoded_samples += s->channel[i].subframe_len[cur_subframe]; s->channel_indexes_for_cur_subframe[s->channels_for_cur_subframe] = i; ++s->channels_for_cur_subframe; } } /** check if the frame will be complete after processing the estimated block */ if (!total_samples) s->parsed_all_subframes = 1; av_dlog(s->avctx, "subframe is part of %i channels\n", s->channels_for_cur_subframe); /** calculate number of scale factor bands and their offsets */ s->table_idx = av_log2(s->samples_per_frame/subframe_len); s->num_bands = s->num_sfb[s->table_idx]; s->cur_sfb_offsets = s->sfb_offsets[s->table_idx]; cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx]; /** configure the decoder for the current subframe */ for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) + offset]; } s->subframe_len = subframe_len; s->esc_len = av_log2(s->subframe_len - 1) + 1; /** skip extended header if any */ if (get_bits1(&s->gb)) { int num_fill_bits; if (!(num_fill_bits = get_bits(&s->gb, 2))) { int len = get_bits(&s->gb, 4); num_fill_bits = get_bits(&s->gb, len) + 1; } if (num_fill_bits >= 0) { if (get_bits_count(&s->gb) + num_fill_bits > s->num_saved_bits) { av_log(s->avctx, AV_LOG_ERROR, "invalid number of fill bits\n"); return AVERROR_INVALIDDATA; } skip_bits_long(&s->gb, num_fill_bits); } } /** no idea for what the following bit is used */ if (get_bits1(&s->gb)) { av_log_ask_for_sample(s->avctx, "reserved bit set\n"); return AVERROR_INVALIDDATA; } if (decode_channel_transform(s) < 0) return AVERROR_INVALIDDATA; for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; if ((s->channel[c].transmit_coefs = get_bits1(&s->gb))) transmit_coeffs = 1; } if (transmit_coeffs) { int step; int quant_step = 90 * s->bits_per_sample >> 4; /** decode number of vector coded coefficients */ if ((s->transmit_num_vec_coeffs = get_bits1(&s->gb))) { int num_bits = av_log2((s->subframe_len + 3)/4) + 1; for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; } } else { for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; s->channel[c].num_vec_coeffs = s->subframe_len; } } /** decode quantization step */ step = get_sbits(&s->gb, 6); quant_step += step; if (step == -32 || step == 31) { const int sign = (step == 31) - 1; int quant = 0; while (get_bits_count(&s->gb) + 5 < s->num_saved_bits && (step = get_bits(&s->gb, 5)) == 31) { quant += 31; } quant_step += ((quant + step) ^ sign) - sign; } if (quant_step < 0) { av_log(s->avctx, AV_LOG_DEBUG, "negative quant step\n"); } /** decode quantization step modifiers for every channel */ if (s->channels_for_cur_subframe == 1) { s->channel[s->channel_indexes_for_cur_subframe[0]].quant_step = quant_step; } else { int modifier_len = get_bits(&s->gb, 3); for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; s->channel[c].quant_step = quant_step; if (get_bits1(&s->gb)) { if (modifier_len) { s->channel[c].quant_step += get_bits(&s->gb, modifier_len) + 1; } else ++s->channel[c].quant_step; } } } /** decode scale factors */ if (decode_scale_factors(s) < 0) return AVERROR_INVALIDDATA; } av_dlog(s->avctx, "BITSTREAM: subframe header length was %i\n", get_bits_count(&s->gb) - s->subframe_offset); /** parse coefficients */ for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; if (s->channel[c].transmit_coefs && get_bits_count(&s->gb) < s->num_saved_bits) { decode_coeffs(s, c); } else memset(s->channel[c].coeffs, 0, sizeof(*s->channel[c].coeffs) * subframe_len); } av_dlog(s->avctx, "BITSTREAM: subframe length was %i\n", get_bits_count(&s->gb) - s->subframe_offset); if (transmit_coeffs) { FFTContext *mdct = &s->mdct_ctx[av_log2(subframe_len) - WMAPRO_BLOCK_MIN_BITS]; /** reconstruct the per channel data */ inverse_channel_transform(s); for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; const int* sf = s->channel[c].scale_factors; int b; if (c == s->lfe_channel) memset(&s->tmp[cur_subwoofer_cutoff], 0, sizeof(*s->tmp) * (subframe_len - cur_subwoofer_cutoff)); /** inverse quantization and rescaling */ for (b = 0; b < s->num_bands; b++) { const int end = FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len); const int exp = s->channel[c].quant_step - (s->channel[c].max_scale_factor - *sf++) * s->channel[c].scale_factor_step; const float quant = pow(10.0, exp / 20.0); int start = s->cur_sfb_offsets[b]; s->dsp.vector_fmul_scalar(s->tmp + start, s->channel[c].coeffs + start, quant, end - start); } /** apply imdct (imdct_half == DCTIV with reverse) */ mdct->imdct_half(mdct, s->channel[c].coeffs, s->tmp); } } /** window and overlapp-add */ wmapro_window(s); /** handled one subframe */ for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; if (s->channel[c].cur_subframe >= s->channel[c].num_subframes) { av_log(s->avctx, AV_LOG_ERROR, "broken subframe\n"); return AVERROR_INVALIDDATA; } ++s->channel[c].cur_subframe; } return 0; }


int kvm_vm_ioctl(KVMState *s, int type, ...) { int ret; void *arg; va_list ap; va_start(ap, type); arg = va_arg(ap, void *); va_end(ap); ret = ioctl(s->vmfd, type, arg); if (ret == -1) ret = -errno; return ret; }


void kqemu_cpu_interrupt(CPUState *env) { #if defined(_WIN32) /* cancelling the I/O request causes KQEMU to finish executing the current block and successfully returning. */ CancelIo(kqemu_fd); #endif }


target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg) { target_ulong arg1; switch (reg) { case 0: arg1 = (int32_t)env->active_fpu.fcr0; break; case 25: arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | ((env->active_fpu.fcr31 >> 23) & 0x1); break; case 26: arg1 = env->active_fpu.fcr31 & 0x0003f07c; break; case 28: arg1 = (env->active_fpu.fcr31 & 0x00000f83) | ((env->active_fpu.fcr31 >> 22) & 0x4); break; default: arg1 = (int32_t)env->active_fpu.fcr31; break; } return arg1; }


static void setup_frame(int sig, struct target_sigaction *ka, target_sigset_t *set, CPUSH4State *regs) { struct target_sigframe *frame; abi_ulong frame_addr; int i; int err = 0; int signal; frame_addr = get_sigframe(ka, regs->gregs[15], sizeof(*frame)); if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) goto give_sigsegv; signal = current_exec_domain_sig(sig); err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) { __put_user(set->sig[i + 1], &frame->extramask[i]); } /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa_flags & TARGET_SA_RESTORER) { regs->pr = (unsigned long) ka->sa_restorer; } else { /* Generate return code (system call to sigreturn) */ __put_user(MOVW(2), &frame->retcode[0]); __put_user(TRAP_NOARG, &frame->retcode[1]); __put_user((TARGET_NR_sigreturn), &frame->retcode[2]); regs->pr = (unsigned long) frame->retcode; } if (err) goto give_sigsegv; /* Set up registers for signal handler */ regs->gregs[15] = frame_addr; regs->gregs[4] = signal; /* Arg for signal handler */ regs->gregs[5] = 0; regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc); regs->pc = (unsigned long) ka->_sa_handler; unlock_user_struct(frame, frame_addr, 1); return; give_sigsegv: unlock_user_struct(frame, frame_addr, 1); force_sig(TARGET_SIGSEGV); }


static int qcow_open(BlockDriverState *bs, const char *filename, int flags) { BDRVQcowState *s = bs->opaque; int len, i, shift, ret; QCowHeader header; uint64_t ext_end; ret = bdrv_file_open(&s->hd, filename, flags); if (ret < 0) return ret; if (bdrv_pread(s->hd, 0, &header, sizeof(header)) != sizeof(header)) goto fail; be32_to_cpus(&header.magic); be32_to_cpus(&header.version); be64_to_cpus(&header.backing_file_offset); be32_to_cpus(&header.backing_file_size); be64_to_cpus(&header.size); be32_to_cpus(&header.cluster_bits); be32_to_cpus(&header.crypt_method); be64_to_cpus(&header.l1_table_offset); be32_to_cpus(&header.l1_size); be64_to_cpus(&header.refcount_table_offset); be32_to_cpus(&header.refcount_table_clusters); be64_to_cpus(&header.snapshots_offset); be32_to_cpus(&header.nb_snapshots); if (header.magic != QCOW_MAGIC || header.version != QCOW_VERSION) goto fail; if (header.size <= 1 || header.cluster_bits < MIN_CLUSTER_BITS || header.cluster_bits > MAX_CLUSTER_BITS) goto fail; if (header.crypt_method > QCOW_CRYPT_AES) goto fail; s->crypt_method_header = header.crypt_method; if (s->crypt_method_header) bs->encrypted = 1; s->cluster_bits = header.cluster_bits; s->cluster_size = 1 << s->cluster_bits; s->cluster_sectors = 1 << (s->cluster_bits - 9); s->l2_bits = s->cluster_bits - 3; /* L2 is always one cluster */ s->l2_size = 1 << s->l2_bits; bs->total_sectors = header.size / 512; s->csize_shift = (62 - (s->cluster_bits - 8)); s->csize_mask = (1 << (s->cluster_bits - 8)) - 1; s->cluster_offset_mask = (1LL << s->csize_shift) - 1; s->refcount_table_offset = header.refcount_table_offset; s->refcount_table_size = header.refcount_table_clusters << (s->cluster_bits - 3); s->snapshots_offset = header.snapshots_offset; s->nb_snapshots = header.nb_snapshots; /* read the level 1 table */ s->l1_size = header.l1_size; shift = s->cluster_bits + s->l2_bits; s->l1_vm_state_index = (header.size + (1LL << shift) - 1) >> shift; /* the L1 table must contain at least enough entries to put header.size bytes */ if (s->l1_size < s->l1_vm_state_index) goto fail; s->l1_table_offset = header.l1_table_offset; s->l1_table = qemu_mallocz( align_offset(s->l1_size * sizeof(uint64_t), 512)); if (bdrv_pread(s->hd, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) != s->l1_size * sizeof(uint64_t)) goto fail; for(i = 0;i < s->l1_size; i++) { be64_to_cpus(&s->l1_table[i]); } /* alloc L2 cache */ s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)); s->cluster_cache = qemu_malloc(s->cluster_size); /* one more sector for decompressed data alignment */ s->cluster_data = qemu_malloc(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size + 512); s->cluster_cache_offset = -1; if (qcow2_refcount_init(bs) < 0) goto fail; LIST_INIT(&s->cluster_allocs); /* read qcow2 extensions */ if (header.backing_file_offset) ext_end = header.backing_file_offset; else ext_end = s->cluster_size; if (qcow_read_extensions(bs, sizeof(header), ext_end)) goto fail; /* read the backing file name */ if (header.backing_file_offset != 0) { len = header.backing_file_size; if (len > 1023) len = 1023; if (bdrv_pread(s->hd, header.backing_file_offset, bs->backing_file, len) != len) goto fail; bs->backing_file[len] = '\0'; } if (qcow2_read_snapshots(bs) < 0) goto fail; #ifdef DEBUG_ALLOC qcow2_check_refcounts(bs); #endif return 0; fail: qcow2_free_snapshots(bs); qcow2_refcount_close(bs); qemu_free(s->l1_table); qemu_free(s->l2_cache); qemu_free(s->cluster_cache); qemu_free(s->cluster_data); bdrv_delete(s->hd); return -1; }


static void get_enum(Object *obj, Visitor *v, void *opaque, const char *name, Error **errp) { DeviceState *dev = DEVICE(obj); Property *prop = opaque; int *ptr = qdev_get_prop_ptr(dev, prop); visit_type_enum(v, ptr, prop->info->enum_table, prop->info->name, prop->name, errp); }


QapiDeallocVisitor *qapi_dealloc_visitor_new(void) { QapiDeallocVisitor *v; v = g_malloc0(sizeof(*v)); v->visitor.type = VISITOR_DEALLOC; v->visitor.start_struct = qapi_dealloc_start_struct; v->visitor.end_struct = qapi_dealloc_end_struct; v->visitor.start_alternate = qapi_dealloc_start_alternate; v->visitor.end_alternate = qapi_dealloc_end_alternate; v->visitor.start_list = qapi_dealloc_start_list; v->visitor.next_list = qapi_dealloc_next_list; v->visitor.end_list = qapi_dealloc_end_list; v->visitor.type_int64 = qapi_dealloc_type_int64; v->visitor.type_uint64 = qapi_dealloc_type_uint64; v->visitor.type_bool = qapi_dealloc_type_bool; v->visitor.type_str = qapi_dealloc_type_str; v->visitor.type_number = qapi_dealloc_type_number; v->visitor.type_any = qapi_dealloc_type_anything; v->visitor.type_null = qapi_dealloc_type_null; return v; }


static uint32_t dp8393x_readb(void *opaque, target_phys_addr_t addr) { uint16_t v = dp8393x_readw(opaque, addr & ~0x1); return (v >> (8 * (addr & 0x1))) & 0xff; }


int tcg_global_mem_new_internal(TCGType type, TCGv_ptr base, intptr_t offset, const char *name) { TCGContext *s = &tcg_ctx; TCGTemp *ts, *base_ts = &s->temps[GET_TCGV_PTR(base)]; int idx, reg = base_ts->reg; idx = s->nb_globals; #if TCG_TARGET_REG_BITS == 32 if (type == TCG_TYPE_I64) { char buf[64]; tcg_temp_alloc(s, s->nb_globals + 2); ts = &s->temps[s->nb_globals]; ts->base_type = type; ts->type = TCG_TYPE_I32; ts->fixed_reg = 0; ts->mem_allocated = 1; ts->mem_reg = reg; #ifdef HOST_WORDS_BIGENDIAN ts->mem_offset = offset + 4; #else ts->mem_offset = offset; #endif pstrcpy(buf, sizeof(buf), name); pstrcat(buf, sizeof(buf), "_0"); ts->name = strdup(buf); ts++; ts->base_type = type; ts->type = TCG_TYPE_I32; ts->fixed_reg = 0; ts->mem_allocated = 1; ts->mem_reg = reg; #ifdef HOST_WORDS_BIGENDIAN ts->mem_offset = offset; #else ts->mem_offset = offset + 4; #endif pstrcpy(buf, sizeof(buf), name); pstrcat(buf, sizeof(buf), "_1"); ts->name = strdup(buf); s->nb_globals += 2; } else #endif { tcg_temp_alloc(s, s->nb_globals + 1); ts = &s->temps[s->nb_globals]; ts->base_type = type; ts->type = type; ts->fixed_reg = 0; ts->mem_allocated = 1; ts->mem_reg = reg; ts->mem_offset = offset; ts->name = name; s->nb_globals++; } return idx; }


hwaddr sparc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { SPARCCPU *cpu = SPARC_CPU(cs); CPUSPARCState *env = &cpu->env; hwaddr phys_addr; int mmu_idx = cpu_mmu_index(env, false); MemoryRegionSection section; if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 2, mmu_idx) != 0) { if (cpu_sparc_get_phys_page(env, &phys_addr, addr, 0, mmu_idx) != 0) { return -1; } } section = memory_region_find(get_system_memory(), phys_addr, 1); memory_region_unref(section.mr); if (!int128_nz(section.size)) { return -1; } return phys_addr; }


int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset) { int ret; qed_unref_l2_cache_entry(request->l2_table); /* Check for cached L2 entry */ request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, offset); if (request->l2_table) { return 0; } request->l2_table = qed_alloc_l2_cache_entry(&s->l2_cache); request->l2_table->table = qed_alloc_table(s); BLKDBG_EVENT(s->bs->file, BLKDBG_L2_LOAD); ret = qed_read_table(s, offset, request->l2_table->table); qed_acquire(s); if (ret) { /* can't trust loaded L2 table anymore */ qed_unref_l2_cache_entry(request->l2_table); request->l2_table = NULL; } else { request->l2_table->offset = offset; qed_commit_l2_cache_entry(&s->l2_cache, request->l2_table); /* This is guaranteed to succeed because we just committed the entry * to the cache. */ request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, offset); assert(request->l2_table != NULL); } qed_release(s); return ret; }


static int audio_pcm_info_eq (struct audio_pcm_info *info, audsettings_t *as) { int bits = 8, sign = 0; switch (as->fmt) { case AUD_FMT_S8: sign = 1; case AUD_FMT_U8: break; case AUD_FMT_S16: sign = 1; case AUD_FMT_U16: bits = 16; break; case AUD_FMT_S32: sign = 1; case AUD_FMT_U32: bits = 32; break; } return info->freq == as->freq && info->nchannels == as->nchannels && info->sign == sign && info->bits == bits && info->swap_endianness == (as->endianness != AUDIO_HOST_ENDIANNESS); }


static int parse_adaptation_sets(AVFormatContext *s) { WebMDashMuxContext *w = s->priv_data; char *p = w->adaptation_sets; char *q; enum { new_set, parsed_id, parsing_streams } state; // syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on state = new_set; while (p < w->adaptation_sets + strlen(w->adaptation_sets)) { if (*p == ' ') continue; else if (state == new_set && !strncmp(p, "id=", 3)) { w->as = av_realloc(w->as, sizeof(*w->as) * ++w->nb_as); if (w->as == NULL) return -1; w->as[w->nb_as - 1].nb_streams = 0; w->as[w->nb_as - 1].streams = NULL; p += 3; // consume "id=" q = w->as[w->nb_as - 1].id; while (*p != ',') *q++ = *p++; *q = 0; p++; state = parsed_id; } else if (state == parsed_id && !strncmp(p, "streams=", 8)) { p += 8; // consume "streams=" state = parsing_streams; } else if (state == parsing_streams) { struct AdaptationSet *as = &w->as[w->nb_as - 1]; q = p; while (*q != '\0' && *q != ',' && *q != ' ') q++; as->streams = av_realloc(as->streams, sizeof(*as->streams) * ++as->nb_streams); if (as->streams == NULL) return -1; as->streams[as->nb_streams - 1] = to_integer(p, q - p); if (as->streams[as->nb_streams - 1] < 0) return -1; if (*q == '\0') break; if (*q == ' ') state = new_set; p = ++q; } else { return -1; } } return 0; }


static int filter_frame(AVFilterLink *link, AVFrame *picref) { AVFilterContext *ctx = link->dst; IDETContext *idet = ctx->priv; if (idet->prev) av_frame_free(&idet->prev); idet->prev = idet->cur; idet->cur = idet->next; idet->next = picref; if (!idet->cur) return 0; if (!idet->prev) idet->prev = av_frame_clone(idet->cur); if (!idet->csp) idet->csp = av_pix_fmt_desc_get(link->format); if (idet->csp->comp[0].depth_minus1 / 8 == 1){ idet->filter_line = (ff_idet_filter_func)ff_idet_filter_line_c_16bit; if (ARCH_X86) ff_idet_init_x86(idet, 1); } filter(ctx); return ff_filter_frame(ctx->outputs[0], av_frame_clone(idet->cur)); }


void ff_dsputil_init_arm(DSPContext* c, AVCodecContext *avctx) { const int high_bit_depth = avctx->bits_per_raw_sample > 8; int cpu_flags = av_get_cpu_flags(); ff_put_pixels_clamped = c->put_pixels_clamped; ff_add_pixels_clamped = c->add_pixels_clamped; if (avctx->bits_per_raw_sample <= 8) { if(avctx->idct_algo == FF_IDCT_AUTO || avctx->idct_algo == FF_IDCT_ARM){ c->idct_put = j_rev_dct_arm_put; c->idct_add = j_rev_dct_arm_add; c->idct = ff_j_rev_dct_arm; c->idct_permutation_type = FF_LIBMPEG2_IDCT_PERM; } else if (avctx->idct_algo == FF_IDCT_SIMPLEARM){ c->idct_put = simple_idct_arm_put; c->idct_add = simple_idct_arm_add; c->idct = ff_simple_idct_arm; c->idct_permutation_type = FF_NO_IDCT_PERM; } } c->add_pixels_clamped = ff_add_pixels_clamped_arm; if (!high_bit_depth) { c->put_pixels_tab[0][0] = ff_put_pixels16_arm; c->put_pixels_tab[0][1] = ff_put_pixels16_x2_arm; c->put_pixels_tab[0][2] = ff_put_pixels16_y2_arm; c->put_pixels_tab[0][3] = ff_put_pixels16_xy2_arm; c->put_pixels_tab[1][0] = ff_put_pixels8_arm; c->put_pixels_tab[1][1] = ff_put_pixels8_x2_arm; c->put_pixels_tab[1][2] = ff_put_pixels8_y2_arm; c->put_pixels_tab[1][3] = ff_put_pixels8_xy2_arm; c->put_no_rnd_pixels_tab[0][0] = ff_put_pixels16_arm; c->put_no_rnd_pixels_tab[0][1] = ff_put_no_rnd_pixels16_x2_arm; c->put_no_rnd_pixels_tab[0][2] = ff_put_no_rnd_pixels16_y2_arm; c->put_no_rnd_pixels_tab[0][3] = ff_put_no_rnd_pixels16_xy2_arm; c->put_no_rnd_pixels_tab[1][0] = ff_put_pixels8_arm; c->put_no_rnd_pixels_tab[1][1] = ff_put_no_rnd_pixels8_x2_arm; c->put_no_rnd_pixels_tab[1][2] = ff_put_no_rnd_pixels8_y2_arm; c->put_no_rnd_pixels_tab[1][3] = ff_put_no_rnd_pixels8_xy2_arm; } if (have_armv5te(cpu_flags)) ff_dsputil_init_armv5te(c, avctx); if (have_armv6(cpu_flags)) ff_dsputil_init_armv6(c, avctx); if (have_vfp(cpu_flags)) ff_dsputil_init_vfp(c, avctx); if (have_neon(cpu_flags)) ff_dsputil_init_neon(c, avctx); }


static void fft(AC3MDCTContext *mdct, IComplex *z, int ln) { int j, l, np, np2; int nblocks, nloops; register IComplex *p,*q; int tmp_re, tmp_im; np = 1 << ln; /* reverse */ for (j = 0; j < np; j++) { int k = av_reverse[j] >> (8 - ln); if (k < j) FFSWAP(IComplex, z[k], z[j]); } /* pass 0 */ p = &z[0]; j = np >> 1; do { BF(p[0].re, p[0].im, p[1].re, p[1].im, p[0].re, p[0].im, p[1].re, p[1].im); p += 2; } while (--j); /* pass 1 */ p = &z[0]; j = np >> 2; do { BF(p[0].re, p[0].im, p[2].re, p[2].im, p[0].re, p[0].im, p[2].re, p[2].im); BF(p[1].re, p[1].im, p[3].re, p[3].im, p[1].re, p[1].im, p[3].im, -p[3].re); p+=4; } while (--j); /* pass 2 .. ln-1 */ nblocks = np >> 3; nloops = 1 << 2; np2 = np >> 1; do { p = z; q = z + nloops; for (j = 0; j < nblocks; j++) { BF(p->re, p->im, q->re, q->im, p->re, p->im, q->re, q->im); p++; q++; for(l = nblocks; l < np2; l += nblocks) { CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im, 15); BF(p->re, p->im, q->re, q->im, p->re, p->im, tmp_re, tmp_im); p++; q++; } p += nloops; q += nloops; } nblocks = nblocks >> 1; nloops = nloops << 1; } while (nblocks); }


static inline void gen_lookup_tb(DisasContext *s) { tcg_gen_movi_i32(cpu_R[15], s->pc & ~1); s->is_jmp = DISAS_UPDATE; }


static int parse_interval(Interval *interval, int interval_count, const char **buf, void *log_ctx) { char *intervalstr; int ret; *buf += strspn(*buf, SPACES); if (!**buf) return 0; /* reset data */ memset(interval, 0, sizeof(Interval)); interval->index = interval_count; /* format: INTERVAL COMMANDS */ /* parse interval */ intervalstr = av_get_token(buf, DELIMS); if (intervalstr && intervalstr[0]) { char *start, *end; start = av_strtok(intervalstr, "-", &end); if ((ret = av_parse_time(&interval->start_ts, start, 1)) < 0) { "Invalid start time specification '%s' in interval #%d\n", start, interval_count); if (end) { if ((ret = av_parse_time(&interval->end_ts, end, 1)) < 0) { "Invalid end time specification '%s' in interval #%d\n", end, interval_count); } else { interval->end_ts = INT64_MAX; if (interval->end_ts < interval->start_ts) { "Invalid end time '%s' in interval #%d: " "cannot be lesser than start time '%s'\n", end, interval_count, start); } else { "No interval specified for interval #%d\n", interval_count); /* parse commands */ ret = parse_commands(&interval->commands, &interval->nb_commands, interval_count, buf, log_ctx); end: av_free(intervalstr); return ret;


static void gen_load_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp) { TCGv tmp; TCGv_i64 t64; int index = IS_USER(s); t64 = tcg_temp_new_i64(); tmp = tcg_temp_new(); switch (opsize) { case OS_BYTE: tcg_gen_qemu_ld8s(tmp, addr, index); gen_helper_exts32(cpu_env, fp, tmp); break; case OS_WORD: tcg_gen_qemu_ld16s(tmp, addr, index); gen_helper_exts32(cpu_env, fp, tmp); break; case OS_LONG: tcg_gen_qemu_ld32u(tmp, addr, index); gen_helper_exts32(cpu_env, fp, tmp); break; case OS_SINGLE: tcg_gen_qemu_ld32u(tmp, addr, index); gen_helper_extf32(cpu_env, fp, tmp); break; case OS_DOUBLE: tcg_gen_qemu_ld64(t64, addr, index); gen_helper_extf64(cpu_env, fp, t64); tcg_temp_free_i64(t64); break; case OS_EXTENDED: if (m68k_feature(s->env, M68K_FEATURE_CF_FPU)) { gen_exception(s, s->insn_pc, EXCP_FP_UNIMP); break; } tcg_gen_qemu_ld32u(tmp, addr, index); tcg_gen_shri_i32(tmp, tmp, 16); tcg_gen_st16_i32(tmp, fp, offsetof(FPReg, l.upper)); tcg_gen_addi_i32(tmp, addr, 4); tcg_gen_qemu_ld64(t64, tmp, index); tcg_gen_st_i64(t64, fp, offsetof(FPReg, l.lower)); break; case OS_PACKED: /* unimplemented data type on 68040/ColdFire * FIXME if needed for another FPU */ gen_exception(s, s->insn_pc, EXCP_FP_UNIMP); break; default: g_assert_not_reached(); } tcg_temp_free(tmp); tcg_temp_free_i64(t64); }


static av_cold int j2kenc_init(AVCodecContext *avctx) { int i, ret; Jpeg2000EncoderContext *s = avctx->priv_data; Jpeg2000CodingStyle *codsty = &s->codsty; Jpeg2000QuantStyle *qntsty = &s->qntsty; s->avctx = avctx; av_log(s->avctx, AV_LOG_DEBUG, "init\n"); // defaults: // TODO: implement setting non-standard precinct size memset(codsty->log2_prec_widths , 15, sizeof(codsty->log2_prec_widths )); memset(codsty->log2_prec_heights, 15, sizeof(codsty->log2_prec_heights)); codsty->nreslevels2decode= codsty->nreslevels = 7; codsty->log2_cblk_width = 4; codsty->log2_cblk_height = 4; codsty->transform = avctx->prediction_method ? FF_DWT53 : FF_DWT97_INT; qntsty->nguardbits = 1; s->tile_width = 256; s->tile_height = 256; if (codsty->transform == FF_DWT53) qntsty->quantsty = JPEG2000_QSTY_NONE; else qntsty->quantsty = JPEG2000_QSTY_SE; s->width = avctx->width; s->height = avctx->height; for (i = 0; i < 3; i++) s->cbps[i] = 8; if (avctx->pix_fmt == AV_PIX_FMT_RGB24){ s->ncomponents = 3; } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY8){ s->ncomponents = 1; } else{ // planar YUV s->planar = 1; s->ncomponents = 3; avcodec_get_chroma_sub_sample(avctx->pix_fmt, s->chroma_shift, s->chroma_shift + 1); } ff_jpeg2000_init_tier1_luts(); init_luts(); init_quantization(s); if (ret=init_tiles(s)) return ret; av_log(s->avctx, AV_LOG_DEBUG, "after init\n"); return 0; }


static int vp9_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_vp9_ctx, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags) { int has_pic_id, has_layer_idc, has_ref_idc, has_ss_data, has_su_data; av_unused int pic_id = 0, non_key_frame = 0; av_unused int layer_temporal = -1, layer_spatial = -1, layer_quality = -1; int ref_fields = 0, has_ref_field_ext_pic_id = 0; int first_fragment, last_fragment; int rtp_m; int res = 0; /* drop data of previous packets in case of non-continuous (lossy) packet stream */ if (rtp_vp9_ctx->buf && rtp_vp9_ctx->timestamp != *timestamp) ffio_free_dyn_buf(&rtp_vp9_ctx->buf); /* sanity check for size of input packet: 1 byte payload at least */ if (len < RTP_VP9_DESC_REQUIRED_SIZE + 1) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet, got %d bytes\n", len); return AVERROR_INVALIDDATA; } /* * decode the required VP9 payload descriptor according to section 4.2 of the spec.: * * 0 1 2 3 4 5 6 7 * +-+-+-+-+-+-+-+-+ * |I|L|F|B|E|V|U|-| (REQUIRED) * +-+-+-+-+-+-+-+-+ * * I: PictureID present * L: Layer indices present * F: Reference indices present * B: Start of VP9 frame * E: End of picture * V: Scalability Structure (SS) present * U: Scalability Structure Update (SU) present */ has_pic_id = !!(buf[0] & 0x80); has_layer_idc = !!(buf[0] & 0x40); has_ref_idc = !!(buf[0] & 0x20); first_fragment = !!(buf[0] & 0x10); last_fragment = !!(buf[0] & 0x08); has_ss_data = !!(buf[0] & 0x04); has_su_data = !!(buf[0] & 0x02); rtp_m = !!(flags & RTP_FLAG_MARKER); /* sanity check for markers: B should always be equal to the RTP M marker */ if (last_fragment != rtp_m) { av_log(ctx, AV_LOG_ERROR, "Invalid combination of B and M marker (%d != %d)\n", last_fragment, rtp_m); return AVERROR_INVALIDDATA; } /* pass the extensions field */ buf += RTP_VP9_DESC_REQUIRED_SIZE; len -= RTP_VP9_DESC_REQUIRED_SIZE; /* * decode the 1-byte/2-byte picture ID: * * 0 1 2 3 4 5 6 7 * +-+-+-+-+-+-+-+-+ * I: |M|PICTURE ID | (RECOMMENDED) * +-+-+-+-+-+-+-+-+ * M: | EXTENDED PID | (RECOMMENDED) * +-+-+-+-+-+-+-+-+ * * M: The most significant bit of the first octet is an extension flag. * PictureID: 8 or 16 bits including the M bit. */ if (has_pic_id) { if (len < 1) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n"); return AVERROR_INVALIDDATA; } /* check for 1-byte or 2-byte picture index */ if (buf[0] & 0x80) { if (len < 2) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n"); return AVERROR_INVALIDDATA; } pic_id = AV_RB16(buf) & 0x7fff; buf += 2; len -= 2; } else { pic_id = buf[0] & 0x7f; buf++; len--; } } /* * decode layer indices * * 0 1 2 3 4 5 6 7 * +-+-+-+-+-+-+-+-+ * L: | T | S | Q | R | (CONDITIONALLY RECOMMENDED) * +-+-+-+-+-+-+-+-+ * * T, S and Q are 2-bit indices for temporal, spatial, and quality layers. * If "F" is set in the initial octet, R is 2 bits representing the number * of reference fields this frame refers to. */ if (has_layer_idc) { if (len < 1) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n"); return AVERROR_INVALIDDATA; } layer_temporal = buf[0] & 0xC0; layer_spatial = buf[0] & 0x30; layer_quality = buf[0] & 0x0C; if (has_ref_idc) { ref_fields = buf[0] & 0x03; if (ref_fields) non_key_frame = 1; } buf++; len--; } /* * decode the reference fields * * 0 1 2 3 4 5 6 7 * +-+-+-+-+-+-+-+-+ -\ * F: | PID |X| RS| RQ| (OPTIONAL) . * +-+-+-+-+-+-+-+-+ . - R times * X: | EXTENDED PID | (OPTIONAL) . * +-+-+-+-+-+-+-+-+ -/ * * PID: The relative Picture ID referred to by this frame. * RS and RQ: The spatial and quality layer IDs. * X: 1 if this layer index has an extended relative Picture ID. */ if (has_ref_idc) { while (ref_fields) { if (len < 1) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n"); return AVERROR_INVALIDDATA; } has_ref_field_ext_pic_id = buf[0] & 0x10; /* pass ref. field */ if (has_ref_field_ext_pic_id) { if (len < 2) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n"); return AVERROR_INVALIDDATA; } /* ignore ref. data */ buf += 2; len -= 2; } else { /* ignore ref. data */ buf++; len--; } ref_fields--; } } /* * decode the scalability structure (SS) * * 0 1 2 3 4 5 6 7 * +-+-+-+-+-+-+-+-+ * V: | PATTERN LENGTH| * +-+-+-+-+-+-+-+-+ -\ * | T | S | Q | R | (OPTIONAL) . * +-+-+-+-+-+-+-+-+ -\ . * | PID |X| RS| RQ| (OPTIONAL) . . - PAT. LEN. times * +-+-+-+-+-+-+-+-+ . - R times . * X: | EXTENDED PID | (OPTIONAL) . . * +-+-+-+-+-+-+-+-+ -/ -/ * * PID: The relative Picture ID referred to by this frame. * RS and RQ: The spatial and quality layer IDs. * X: 1 if this layer index has an extended relative Picture ID. */ if (has_ss_data) { avpriv_report_missing_feature(ctx, "VP9 scalability structure data"); return AVERROR(ENOSYS); } /* * decode the scalability update structure (SU) * * spec. is tbd */ if (has_su_data) { avpriv_report_missing_feature(ctx, "VP9 scalability update structure data"); return AVERROR(ENOSYS); } /* * decode the VP9 payload header * * spec. is tbd */ //XXX: implement when specified /* sanity check: 1 byte payload as minimum */ if (len < 1) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/VP9 packet\n"); return AVERROR_INVALIDDATA; } /* start frame buffering with new dynamic buffer */ if (!rtp_vp9_ctx->buf) { /* sanity check: a new frame should have started */ if (first_fragment) { res = avio_open_dyn_buf(&rtp_vp9_ctx->buf); if (res < 0) return res; /* update the timestamp in the frame packet with the one from the RTP packet */ rtp_vp9_ctx->timestamp = *timestamp; } else { /* frame not started yet, need more packets */ return AVERROR(EAGAIN); } } /* write the fragment to the dyn. buffer */ avio_write(rtp_vp9_ctx->buf, buf, len); /* do we need more fragments? */ if (!last_fragment) return AVERROR(EAGAIN); /* close frame buffering and create resulting A/V packet */ res = ff_rtp_finalize_packet(pkt, &rtp_vp9_ctx->buf, st->index); if (res < 0) return res; return 0; }


int nbd_client_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { NBDRequest request = { .type = NBD_CMD_READ, .from = offset, .len = bytes, }; assert(bytes <= NBD_MAX_BUFFER_SIZE); assert(!flags); return nbd_co_request(bs, &request, qiov); }


writev_f(int argc, char **argv) { struct timeval t1, t2; int Cflag = 0, qflag = 0; int c, cnt; char *buf; int64_t offset; int total; int nr_iov; int pattern = 0xcd; QEMUIOVector qiov; while ((c = getopt(argc, argv, "CqP:")) != EOF) { switch (c) { case 'C': Cflag = 1; break; case 'q': qflag = 1; break; case 'P': pattern = atoi(optarg); break; default: return command_usage(&writev_cmd); } } if (optind > argc - 2) return command_usage(&writev_cmd); offset = cvtnum(argv[optind]); if (offset < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } optind++; if (offset & 0x1ff) { printf("offset %lld is not sector aligned\n", (long long)offset); return 0; } nr_iov = argc - optind; buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern); gettimeofday(&t1, NULL); cnt = do_aio_writev(&qiov, offset, &total); gettimeofday(&t2, NULL); if (cnt < 0) { printf("writev failed: %s\n", strerror(-cnt)); return 0; } if (qflag) return 0; /* Finally, report back -- -C gives a parsable format */ t2 = tsub(t2, t1); print_report("wrote", &t2, offset, qiov.size, total, cnt, Cflag); qemu_io_free(buf); return 0; }


static off_t read_off(BlockDriverState *bs, int64_t offset) { uint64_t buffer; if (bdrv_pread(bs->file, offset, &buffer, 8) < 8) return 0; return be64_to_cpu(buffer); }


static void qmp_input_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp) { QmpInputVisitor *qiv = to_qiv(v); QObject *qobj = qmp_input_get_object(qiv, name, true); if (!qobj || qobject_type(qobj) != QTYPE_QINT) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "integer"); return; } *obj = qint_get_int(qobject_to_qint(qobj)); }


static void emulated_push_type(EmulatedState *card, uint32_t type) { EmulEvent *event = (EmulEvent *)g_malloc(sizeof(EmulEvent)); assert(event); event->p.gen.type = type; emulated_push_event(card, event); }


static target_ulong h_protect(CPUPPCState *env, sPAPREnvironment *spapr, target_ulong opcode, target_ulong *args) { target_ulong flags = args[0]; target_ulong pte_index = args[1]; target_ulong avpn = args[2]; uint8_t *hpte; target_ulong v, r, rb; if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) { return H_PARAMETER; } hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64); while (!lock_hpte(hpte, HPTE_V_HVLOCK)) { /* We have no real concurrency in qemu soft-emulation, so we * will never actually have a contested lock */ assert(0); } v = ldq_p(hpte); r = ldq_p(hpte + (HASH_PTE_SIZE_64/2)); if ((v & HPTE_V_VALID) == 0 || ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) { stq_p(hpte, v & ~HPTE_V_HVLOCK); assert(!(ldq_p(hpte) & HPTE_V_HVLOCK)); return H_NOT_FOUND; } r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_HI | HPTE_R_KEY_LO); r |= (flags << 55) & HPTE_R_PP0; r |= (flags << 48) & HPTE_R_KEY_HI; r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO); rb = compute_tlbie_rb(v, r, pte_index); stq_p(hpte, v & ~HPTE_V_VALID); ppc_tlb_invalidate_one(env, rb); stq_p(hpte + (HASH_PTE_SIZE_64/2), r); /* Don't need a memory barrier, due to qemu's global lock */ stq_p(hpte, v & ~HPTE_V_HVLOCK); assert(!(ldq_p(hpte) & HPTE_V_HVLOCK)); return H_SUCCESS; }


static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst, int pitch, const uint8_t *table) { int j; int out = 0; int c; int t; if (width & 1) for (j = 0; j < height; j++) { out = 0; while (out < width) { c = ir2_get_code(&ctx->gb); if (c >= 0x80) { /* we have a skip */ c -= 0x7F; out += c * 2; } else { /* add two deltas from table */ t = dst[out] + (((table[c * 2] - 128)*3) >> 2); t = av_clip_uint8(t); dst[out] = t; out++; t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2); t = av_clip_uint8(t); dst[out] = t; out++; } } dst += pitch; } return 0; }


static ExitStatus op_ex(DisasContext *s, DisasOps *o) { /* ??? Perhaps a better way to implement EXECUTE is to set a bit in tb->flags, (ab)use the tb->cs_base field as the address of the template in memory, and grab 8 bits of tb->flags/cflags for the contents of the register. We would then recognize all this in gen_intermediate_code_internal, generating code for exactly one instruction. This new TB then gets executed normally. On the other hand, this seems to be mostly used for modifying MVC inside of memcpy, which needs a helper call anyway. So perhaps this doesn't bear thinking about any further. */ TCGv_i64 tmp; update_psw_addr(s); update_cc_op(s); tmp = tcg_const_i64(s->next_pc); gen_helper_ex(cc_op, cpu_env, cc_op, o->in1, o->in2, tmp); tcg_temp_free_i64(tmp); set_cc_static(s); return NO_EXIT; }


static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc, int srcW, int dstW, int filterAlign, int one, int flags, int cpu_flags, SwsVector *srcFilter, SwsVector *dstFilter, double param[2]) { int i; int filterSize; int filter2Size; int minFilterSize; int64_t *filter=NULL; int64_t *filter2=NULL; const int64_t fone= 1LL<<54; int ret= -1; emms_c(); //FIXME this should not be required but it IS (even for non-MMX versions) // NOTE: the +3 is for the MMX(+1)/SSE(+3) scaler which reads over the end FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+3)*sizeof(int16_t), fail); if (FFABS(xInc - 0x10000) <10) { // unscaled int i; filterSize= 1; FF_ALLOCZ_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); for (i=0; i<dstW; i++) { filter[i*filterSize]= fone; (*filterPos)[i]=i; } } else if (flags&SWS_POINT) { // lame looking point sampling mode int i; int xDstInSrc; filterSize= 1; FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); xDstInSrc= xInc/2 - 0x8000; for (i=0; i<dstW; i++) { int xx= (xDstInSrc - ((filterSize-1)<<15) + (1<<15))>>16; (*filterPos)[i]= xx; filter[i]= fone; xDstInSrc+= xInc; } } else if ((xInc <= (1<<16) && (flags&SWS_AREA)) || (flags&SWS_FAST_BILINEAR)) { // bilinear upscale int i; int xDstInSrc; filterSize= 2; FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); xDstInSrc= xInc/2 - 0x8000; for (i=0; i<dstW; i++) { int xx= (xDstInSrc - ((filterSize-1)<<15) + (1<<15))>>16; int j; (*filterPos)[i]= xx; //bilinear upscale / linear interpolate / area averaging for (j=0; j<filterSize; j++) { int64_t coeff= fone - FFABS((xx<<16) - xDstInSrc)*(fone>>16); if (coeff<0) coeff=0; filter[i*filterSize + j]= coeff; xx++; } xDstInSrc+= xInc; } } else { int xDstInSrc; int sizeFactor; if (flags&SWS_BICUBIC) sizeFactor= 4; else if (flags&SWS_X) sizeFactor= 8; else if (flags&SWS_AREA) sizeFactor= 1; //downscale only, for upscale it is bilinear else if (flags&SWS_GAUSS) sizeFactor= 8; // infinite ;) else if (flags&SWS_LANCZOS) sizeFactor= param[0] != SWS_PARAM_DEFAULT ? ceil(2*param[0]) : 6; else if (flags&SWS_SINC) sizeFactor= 20; // infinite ;) else if (flags&SWS_SPLINE) sizeFactor= 20; // infinite ;) else if (flags&SWS_BILINEAR) sizeFactor= 2; else { sizeFactor= 0; //GCC warning killer assert(0); } if (xInc <= 1<<16) filterSize= 1 + sizeFactor; // upscale else filterSize= 1 + (sizeFactor*srcW + dstW - 1)/ dstW; if (filterSize > srcW-2) filterSize=srcW-2; FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); xDstInSrc= xInc - 0x10000; for (i=0; i<dstW; i++) { int xx= (xDstInSrc - ((filterSize-2)<<16)) / (1<<17); int j; (*filterPos)[i]= xx; for (j=0; j<filterSize; j++) { int64_t d= ((int64_t)FFABS((xx<<17) - xDstInSrc))<<13; double floatd; int64_t coeff; if (xInc > 1<<16) d= d*dstW/srcW; floatd= d * (1.0/(1<<30)); if (flags & SWS_BICUBIC) { int64_t B= (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1<<24); int64_t C= (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1<<24); if (d >= 1LL<<31) { coeff = 0.0; } else { int64_t dd = (d * d) >> 30; int64_t ddd = (dd * d) >> 30; if (d < 1LL<<30) coeff = (12*(1<<24)-9*B-6*C)*ddd + (-18*(1<<24)+12*B+6*C)*dd + (6*(1<<24)-2*B)*(1<<30); else coeff = (-B-6*C)*ddd + (6*B+30*C)*dd + (-12*B-48*C)*d + (8*B+24*C)*(1<<30); } coeff *= fone>>(30+24); } /* else if (flags & SWS_X) { double p= param ? param*0.01 : 0.3; coeff = d ? sin(d*M_PI)/(d*M_PI) : 1.0; coeff*= pow(2.0, - p*d*d); }*/ else if (flags & SWS_X) { double A= param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0; double c; if (floatd<1.0) c = cos(floatd*M_PI); else c=-1.0; if (c<0.0) c= -pow(-c, A); else c= pow( c, A); coeff= (c*0.5 + 0.5)*fone; } else if (flags & SWS_AREA) { int64_t d2= d - (1<<29); if (d2*xInc < -(1LL<<(29+16))) coeff= 1.0 * (1LL<<(30+16)); else if (d2*xInc < (1LL<<(29+16))) coeff= -d2*xInc + (1LL<<(29+16)); else coeff=0.0; coeff *= fone>>(30+16); } else if (flags & SWS_GAUSS) { double p= param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0; coeff = (pow(2.0, - p*floatd*floatd))*fone; } else if (flags & SWS_SINC) { coeff = (d ? sin(floatd*M_PI)/(floatd*M_PI) : 1.0)*fone; } else if (flags & SWS_LANCZOS) { double p= param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0; coeff = (d ? sin(floatd*M_PI)*sin(floatd*M_PI/p)/(floatd*floatd*M_PI*M_PI/p) : 1.0)*fone; if (floatd>p) coeff=0; } else if (flags & SWS_BILINEAR) { coeff= (1<<30) - d; if (coeff<0) coeff=0; coeff *= fone >> 30; } else if (flags & SWS_SPLINE) { double p=-2.196152422706632; coeff = getSplineCoeff(1.0, 0.0, p, -p-1.0, floatd) * fone; } else { coeff= 0.0; //GCC warning killer assert(0); } filter[i*filterSize + j]= coeff; xx++; } xDstInSrc+= 2*xInc; } } /* apply src & dst Filter to filter -> filter2 av_free(filter); */ assert(filterSize>0); filter2Size= filterSize; if (srcFilter) filter2Size+= srcFilter->length - 1; if (dstFilter) filter2Size+= dstFilter->length - 1; assert(filter2Size>0); FF_ALLOCZ_OR_GOTO(NULL, filter2, filter2Size*dstW*sizeof(*filter2), fail); for (i=0; i<dstW; i++) { int j, k; if(srcFilter) { for (k=0; k<srcFilter->length; k++) { for (j=0; j<filterSize; j++) filter2[i*filter2Size + k + j] += srcFilter->coeff[k]*filter[i*filterSize + j]; } } else { for (j=0; j<filterSize; j++) filter2[i*filter2Size + j]= filter[i*filterSize + j]; } //FIXME dstFilter (*filterPos)[i]+= (filterSize-1)/2 - (filter2Size-1)/2; } av_freep(&filter); /* try to reduce the filter-size (step1 find size and shift left) */ // Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not). minFilterSize= 0; for (i=dstW-1; i>=0; i--) { int min= filter2Size; int j; int64_t cutOff=0.0; /* get rid of near zero elements on the left by shifting left */ for (j=0; j<filter2Size; j++) { int k; cutOff += FFABS(filter2[i*filter2Size]); if (cutOff > SWS_MAX_REDUCE_CUTOFF*fone) break; /* preserve monotonicity because the core can't handle the filter otherwise */ if (i<dstW-1 && (*filterPos)[i] >= (*filterPos)[i+1]) break; // move filter coefficients left for (k=1; k<filter2Size; k++) filter2[i*filter2Size + k - 1]= filter2[i*filter2Size + k]; filter2[i*filter2Size + k - 1]= 0; (*filterPos)[i]++; } cutOff=0; /* count near zeros on the right */ for (j=filter2Size-1; j>0; j--) { cutOff += FFABS(filter2[i*filter2Size + j]); if (cutOff > SWS_MAX_REDUCE_CUTOFF*fone) break; min--; } if (min>minFilterSize) minFilterSize= min; } if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) { // we can handle the special case 4, // so we don't want to go to the full 8 if (minFilterSize < 5) filterAlign = 4; // We really don't want to waste our time // doing useless computation, so fall back on // the scalar C code for very small filters. // Vectorizing is worth it only if you have a // decent-sized vector. if (minFilterSize < 3) filterAlign = 1; } if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) { // special case for unscaled vertical filtering if (minFilterSize == 1 && filterAlign == 2) filterAlign= 1; } assert(minFilterSize > 0); filterSize= (minFilterSize +(filterAlign-1)) & (~(filterAlign-1)); assert(filterSize > 0); filter= av_malloc(filterSize*dstW*sizeof(*filter)); if (filterSize >= MAX_FILTER_SIZE*16/((flags&SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter) goto fail; *outFilterSize= filterSize; if (flags&SWS_PRINT_INFO) av_log(NULL, AV_LOG_VERBOSE, "SwScaler: reducing / aligning filtersize %d -> %d\n", filter2Size, filterSize); /* try to reduce the filter-size (step2 reduce it) */ for (i=0; i<dstW; i++) { int j; for (j=0; j<filterSize; j++) { if (j>=filter2Size) filter[i*filterSize + j]= 0; else filter[i*filterSize + j]= filter2[i*filter2Size + j]; if((flags & SWS_BITEXACT) && j>=minFilterSize) filter[i*filterSize + j]= 0; } } //FIXME try to align filterPos if possible //fix borders for (i=0; i<dstW; i++) { int j; if ((*filterPos)[i] < 0) { // move filter coefficients left to compensate for filterPos for (j=1; j<filterSize; j++) { int left= FFMAX(j + (*filterPos)[i], 0); filter[i*filterSize + left] += filter[i*filterSize + j]; filter[i*filterSize + j]=0; } (*filterPos)[i]= 0; } if ((*filterPos)[i] + filterSize > srcW) { int shift= (*filterPos)[i] + filterSize - srcW; // move filter coefficients right to compensate for filterPos for (j=filterSize-2; j>=0; j--) { int right= FFMIN(j + shift, filterSize-1); filter[i*filterSize +right] += filter[i*filterSize +j]; filter[i*filterSize +j]=0; } (*filterPos)[i]= srcW - filterSize; } } // Note the +1 is for the MMX scaler which reads over the end /* align at 16 for AltiVec (needed by hScale_altivec_real) */ FF_ALLOCZ_OR_GOTO(NULL, *outFilter, *outFilterSize*(dstW+3)*sizeof(int16_t), fail); /* normalize & store in outFilter */ for (i=0; i<dstW; i++) { int j; int64_t error=0; int64_t sum=0; for (j=0; j<filterSize; j++) { sum+= filter[i*filterSize + j]; } sum= (sum + one/2)/ one; for (j=0; j<*outFilterSize; j++) { int64_t v= filter[i*filterSize + j] + error; int intV= ROUNDED_DIV(v, sum); (*outFilter)[i*(*outFilterSize) + j]= intV; error= v - intV*sum; } } (*filterPos)[dstW+0] = (*filterPos)[dstW+1] = (*filterPos)[dstW+2] = (*filterPos)[dstW-1]; // the MMX/SSE scaler will read over the end for (i=0; i<*outFilterSize; i++) { int k= (dstW - 1) * (*outFilterSize) + i; (*outFilter)[k + 1 * (*outFilterSize)] = (*outFilter)[k + 2 * (*outFilterSize)] = (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k]; } ret=0; fail: av_free(filter); av_free(filter2); return ret; }


int update_dimensions(VP8Context *s, int width, int height, int is_vp7) { AVCodecContext *avctx = s->avctx; int i, ret; if (width != s->avctx->width || height != s->avctx->height) { vp8_decode_flush_impl(s->avctx, 1); ret = ff_set_dimensions(s->avctx, width, height); if (ret < 0) return ret; } s->mb_width = (s->avctx->coded_width + 15) / 16; s->mb_height = (s->avctx->coded_height + 15) / 16; s->mb_layout = is_vp7 || avctx->active_thread_type == FF_THREAD_SLICE && FFMIN(s->num_coeff_partitions, avctx->thread_count) > 1; if (!s->mb_layout) { // Frame threading and one thread s->macroblocks_base = av_mallocz((s->mb_width + s->mb_height * 2 + 1) * sizeof(*s->macroblocks)); s->intra4x4_pred_mode_top = av_mallocz(s->mb_width * 4); } else // Sliced threading s->macroblocks_base = av_mallocz((s->mb_width + 2) * (s->mb_height + 2) * sizeof(*s->macroblocks)); s->top_nnz = av_mallocz(s->mb_width * sizeof(*s->top_nnz)); s->top_border = av_mallocz((s->mb_width + 1) * sizeof(*s->top_border)); s->thread_data = av_mallocz(MAX_THREADS * sizeof(VP8ThreadData)); for (i = 0; i < MAX_THREADS; i++) { s->thread_data[i].filter_strength = av_mallocz(s->mb_width * sizeof(*s->thread_data[0].filter_strength)); #if HAVE_THREADS pthread_mutex_init(&s->thread_data[i].lock, NULL); pthread_cond_init(&s->thread_data[i].cond, NULL); #endif } if (!s->macroblocks_base || !s->top_nnz || !s->top_border || (!s->intra4x4_pred_mode_top && !s->mb_layout)) return AVERROR(ENOMEM); s->macroblocks = s->macroblocks_base + 1; return 0; }


static int decode_main_header(NUTContext *nut){ AVFormatContext *s= nut->avf; ByteIOContext *bc = &s->pb; uint64_t tmp; int i, j; get_packetheader(nut, bc, 8, 1); tmp = get_v(bc); if (tmp != 1){ av_log(s, AV_LOG_ERROR, "bad version (%Ld)\n", tmp); return -1; } nut->stream_count = get_v(bc); get_v(bc); //checksum threshold for(i=0; i<256;){ int tmp_flags = get_v(bc); int tmp_stream= get_v(bc); int tmp_mul = get_v(bc); int tmp_size = get_v(bc); int count = get_v(bc); if(count == 0 || i+count > 256){ av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i); return -1; } if((tmp_flags & FLAG_FRAME_TYPE) && tmp_flags != 1){ if(tmp_flags & FLAG_PRED_KEY_FRAME){ av_log(s, AV_LOG_ERROR, "keyframe prediction in non 0 frame type\n"); return -1; } if(!(tmp_flags & FLAG_PTS) || !(tmp_flags & FLAG_FULL_PTS) ){ av_log(s, AV_LOG_ERROR, "no full pts in non 0 frame type\n"); return -1; } } for(j=0; j<count; j++,i++){ if(tmp_stream > nut->stream_count + 1){ av_log(s, AV_LOG_ERROR, "illegal stream number\n"); return -1; } nut->frame_code[i].flags = tmp_flags ; nut->frame_code[i].stream_id_plus1 = tmp_stream; nut->frame_code[i].size_mul = tmp_mul ; nut->frame_code[i].size_lsb = tmp_size ; if(++tmp_size >= tmp_mul){ tmp_size=0; tmp_stream++; } } } if(nut->frame_code['N'].flags != 1){ av_log(s, AV_LOG_ERROR, "illegal frame_code table\n"); return -1; } if(check_checksum(bc)){ av_log(s, AV_LOG_ERROR, "Main header checksum missmatch\n"); return -1; } return 0; }


void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem) { /* see similar ffmpeg.c:grow_array() */ int nb, nb_alloc; intptr_t *tab; nb = *nb_ptr; tab = *(intptr_t**)tab_ptr; if ((nb & (nb - 1)) == 0) { if (nb == 0) nb_alloc = 1; else nb_alloc = nb * 2; tab = av_realloc(tab, nb_alloc * sizeof(intptr_t)); *(intptr_t**)tab_ptr = tab; } tab[nb++] = (intptr_t)elem; *nb_ptr = nb; }


static void write_long(unsigned char *p,uint32_t v) { p[0] = v>>24; p[1] = v>>16; p[2] = v>>8; p[3] = v; }


static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1, int w, int prefs, int mrefs, int parity, int mode) { uint16_t *dst = dst1; uint16_t *prev = prev1; uint16_t *cur = cur1; uint16_t *next = next1; int x; uint16_t *prev2 = parity ? prev : cur ; uint16_t *next2 = parity ? cur : next; mrefs /= 2; prefs /= 2; FILTER(0, 3, 0) dst = (uint16_t*)dst1 + w - 3; prev = (uint16_t*)prev1 + w - 3; cur = (uint16_t*)cur1 + w - 3; next = (uint16_t*)next1 + w - 3; prev2 = (uint16_t*)(parity ? prev : cur); next2 = (uint16_t*)(parity ? cur : next); FILTER(w - 3, w, 0) }


int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM ) { flag aSign; int16 aExp, shiftCount; uint32_t aSig; int32 z; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); aExp = extractFloat32Exp( a ); aSign = extractFloat32Sign( a ); shiftCount = aExp - 0x9E; if ( 0 <= shiftCount ) { if ( float32_val(a) != 0xCF000000 ) { float_raise( float_flag_invalid STATUS_VAR); if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF; } return (int32_t) 0x80000000; } else if ( aExp <= 0x7E ) { if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact; return 0; } aSig = ( aSig | 0x00800000 )<<8; z = aSig>>( - shiftCount ); if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) { STATUS(float_exception_flags) |= float_flag_inexact; } if ( aSign ) z = - z; return z; }


static int avi_load_index(AVFormatContext *s) { AVIContext *avi = s->priv_data; ByteIOContext *pb = s->pb; uint32_t tag, size; int64_t pos= url_ftell(pb); url_fseek(pb, avi->movi_end, SEEK_SET); #ifdef DEBUG_SEEK printf("movi_end=0x%"PRIx64"\n", avi->movi_end); #endif for(;;) { if (url_feof(pb)) break; tag = get_le32(pb); size = get_le32(pb); #ifdef DEBUG_SEEK printf("tag=%c%c%c%c size=0x%x\n", tag & 0xff, (tag >> 8) & 0xff, (tag >> 16) & 0xff, (tag >> 24) & 0xff, size); #endif switch(tag) { case MKTAG('i', 'd', 'x', '1'): if (avi_read_idx1(s, size) < 0) goto skip; else goto the_end; break; default: skip: size += (size & 1); url_fskip(pb, size); break; } } the_end: url_fseek(pb, pos, SEEK_SET); return 0; }


int usb_desc_handle_control(USBDevice *dev, USBPacket *p, int request, int value, int index, int length, uint8_t *data) { const USBDesc *desc = usb_device_get_usb_desc(dev); int ret = -1; assert(desc != NULL); switch(request) { case DeviceOutRequest | USB_REQ_SET_ADDRESS: dev->addr = value; trace_usb_set_addr(dev->addr); ret = 0; break; case DeviceRequest | USB_REQ_GET_DESCRIPTOR: ret = usb_desc_get_descriptor(dev, value, data, length); break; case DeviceRequest | USB_REQ_GET_CONFIGURATION: data[0] = dev->config->bConfigurationValue; ret = 1; break; case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: ret = usb_desc_set_config(dev, value); trace_usb_set_config(dev->addr, value, ret); break; case DeviceRequest | USB_REQ_GET_STATUS: data[0] = 0; if (dev->config->bmAttributes & 0x40) { data[0] |= 1 << USB_DEVICE_SELF_POWERED; } if (dev->remote_wakeup) { data[0] |= 1 << USB_DEVICE_REMOTE_WAKEUP; } data[1] = 0x00; ret = 2; break; case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: if (value == USB_DEVICE_REMOTE_WAKEUP) { dev->remote_wakeup = 0; ret = 0; } trace_usb_clear_device_feature(dev->addr, value, ret); break; case DeviceOutRequest | USB_REQ_SET_FEATURE: if (value == USB_DEVICE_REMOTE_WAKEUP) { dev->remote_wakeup = 1; ret = 0; } trace_usb_set_device_feature(dev->addr, value, ret); break; case InterfaceRequest | USB_REQ_GET_INTERFACE: if (index < 0 || index >= dev->ninterfaces) { break; } data[0] = dev->altsetting[index]; ret = 1; break; case InterfaceOutRequest | USB_REQ_SET_INTERFACE: ret = usb_desc_set_interface(dev, index, value); trace_usb_set_interface(dev->addr, index, value, ret); break; } return ret; }


static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { IMXFECState *s = IMX_FEC(opaque); uint32_t index = offset >> 2; FEC_PRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_eth_reg_name(s, index), (uint32_t)value); switch (index) { case ENET_EIR: s->regs[index] &= ~value; break; case ENET_EIMR: s->regs[index] = value; break; case ENET_RDAR: if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) { if (!s->regs[index]) { s->regs[index] = ENET_RDAR_RDAR; imx_eth_enable_rx(s); } } else { s->regs[index] = 0; } break; case ENET_TDAR: if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) { s->regs[index] = ENET_TDAR_TDAR; imx_eth_do_tx(s); } s->regs[index] = 0; break; case ENET_ECR: if (value & ENET_ECR_RESET) { return imx_eth_reset(DEVICE(s)); } s->regs[index] = value; if ((s->regs[index] & ENET_ECR_ETHEREN) == 0) { s->regs[ENET_RDAR] = 0; s->rx_descriptor = s->regs[ENET_RDSR]; s->regs[ENET_TDAR] = 0; s->tx_descriptor = s->regs[ENET_TDSR]; } break; case ENET_MMFR: s->regs[index] = value; if (extract32(value, 29, 1)) { /* This is a read operation */ s->regs[ENET_MMFR] = deposit32(s->regs[ENET_MMFR], 0, 16, do_phy_read(s, extract32(value, 18, 10))); } else { /* This a write operation */ do_phy_write(s, extract32(value, 18, 10), extract32(value, 0, 16)); } /* raise the interrupt as the PHY operation is done */ s->regs[ENET_EIR] |= ENET_INT_MII; break; case ENET_MSCR: s->regs[index] = value & 0xfe; break; case ENET_MIBC: /* TODO: Implement MIB. */ s->regs[index] = (value & 0x80000000) ? 0xc0000000 : 0; break; case ENET_RCR: s->regs[index] = value & 0x07ff003f; /* TODO: Implement LOOP mode. */ break; case ENET_TCR: /* We transmit immediately, so raise GRA immediately. */ s->regs[index] = value; if (value & 1) { s->regs[ENET_EIR] |= ENET_INT_GRA; } break; case ENET_PALR: s->regs[index] = value; s->conf.macaddr.a[0] = value >> 24; s->conf.macaddr.a[1] = value >> 16; s->conf.macaddr.a[2] = value >> 8; s->conf.macaddr.a[3] = value; break; case ENET_PAUR: s->regs[index] = (value | 0x0000ffff) & 0xffff8808; s->conf.macaddr.a[4] = value >> 24; s->conf.macaddr.a[5] = value >> 16; break; case ENET_OPD: s->regs[index] = (value & 0x0000ffff) | 0x00010000; break; case ENET_IAUR: case ENET_IALR: case ENET_GAUR: case ENET_GALR: /* TODO: implement MAC hash filtering. */ break; case ENET_TFWR: if (s->is_fec) { s->regs[index] = value & 0x3; } else { s->regs[index] = value & 0x13f; } break; case ENET_RDSR: if (s->is_fec) { s->regs[index] = value & ~3; } else { s->regs[index] = value & ~7; } s->rx_descriptor = s->regs[index]; break; case ENET_TDSR: if (s->is_fec) { s->regs[index] = value & ~3; } else { s->regs[index] = value & ~7; } s->tx_descriptor = s->regs[index]; break; case ENET_MRBR: s->regs[index] = value & 0x00003ff0; break; default: if (s->is_fec) { imx_fec_write(s, index, value); } else { imx_enet_write(s, index, value); } return; } imx_eth_update(s); }


int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; SpiceCharDriver *s; const char* name = qemu_opt_get(opts, "name"); uint32_t debug = qemu_opt_get_number(opts, "debug", 0); const char** psubtype = spice_server_char_device_recognized_subtypes(); const char *subtype = NULL; if (name == NULL) { fprintf(stderr, "spice-qemu-char: missing name parameter\n"); print_allowed_subtypes(); return -EINVAL; } for(;*psubtype != NULL; ++psubtype) { if (strcmp(name, *psubtype) == 0) { subtype = *psubtype; break; } } if (subtype == NULL) { fprintf(stderr, "spice-qemu-char: unsupported name\n"); print_allowed_subtypes(); return -EINVAL; } chr = g_malloc0(sizeof(CharDriverState)); s = g_malloc0(sizeof(SpiceCharDriver)); s->chr = chr; s->debug = debug; s->active = false; s->sin.subtype = subtype; chr->opaque = s; chr->chr_write = spice_chr_write; chr->chr_close = spice_chr_close; chr->chr_guest_open = spice_chr_guest_open; chr->chr_guest_close = spice_chr_guest_close; #if SPICE_SERVER_VERSION < 0x000901 /* See comment in vmc_state() */ if (strcmp(subtype, "vdagent") == 0) { qemu_chr_generic_open(chr); } #endif *_chr = chr; return 0; }


static char *get_content_url(xmlNodePtr *baseurl_nodes, int n_baseurl_nodes, char *rep_id_val, char *rep_bandwidth_val, char *val) { int i; char *text; char *url = NULL; char tmp_str[MAX_URL_SIZE]; char tmp_str_2[MAX_URL_SIZE]; memset(tmp_str, 0, sizeof(tmp_str)); for (i = 0; i < n_baseurl_nodes; ++i) { if (baseurl_nodes[i] && baseurl_nodes[i]->children && baseurl_nodes[i]->children->type == XML_TEXT_NODE) { text = xmlNodeGetContent(baseurl_nodes[i]->children); if (text) { memset(tmp_str, 0, sizeof(tmp_str)); memset(tmp_str_2, 0, sizeof(tmp_str_2)); ff_make_absolute_url(tmp_str_2, MAX_URL_SIZE, tmp_str, text); av_strlcpy(tmp_str, tmp_str_2, sizeof(tmp_str)); xmlFree(text); } } } if (val) av_strlcat(tmp_str, (const char*)val, sizeof(tmp_str)); if (rep_id_val) { url = av_strireplace(tmp_str, "$RepresentationID$", (const char*)rep_id_val); if (!url) { return NULL; } av_strlcpy(tmp_str, url, sizeof(tmp_str)); av_free(url); } if (rep_bandwidth_val && tmp_str[0] != '\0') { url = av_strireplace(tmp_str, "$Bandwidth$", (const char*)rep_bandwidth_val); if (!url) { return NULL; } } return url; }


av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx) { const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8; if (avctx->lowres==1) { c->idct_put = ff_jref_idct4_put; c->idct_add = ff_jref_idct4_add; c->idct = ff_j_rev_dct4; c->perm_type = FF_IDCT_PERM_NONE; } else if (avctx->lowres==2) { c->idct_put = ff_jref_idct2_put; c->idct_add = ff_jref_idct2_add; c->idct = ff_j_rev_dct2; c->perm_type = FF_IDCT_PERM_NONE; } else if (avctx->lowres==3) { c->idct_put = ff_jref_idct1_put; c->idct_add = ff_jref_idct1_add; c->idct = ff_j_rev_dct1; c->perm_type = FF_IDCT_PERM_NONE; } else { if (avctx->bits_per_raw_sample == 10 || avctx->bits_per_raw_sample == 9) { c->idct_put = ff_simple_idct_put_10; c->idct_add = ff_simple_idct_add_10; c->idct = ff_simple_idct_10; c->perm_type = FF_IDCT_PERM_NONE; } else if (avctx->bits_per_raw_sample == 12) { c->idct_put = ff_simple_idct_put_12; c->idct_add = ff_simple_idct_add_12; c->idct = ff_simple_idct_12; c->perm_type = FF_IDCT_PERM_NONE; } else { if (avctx->idct_algo == FF_IDCT_INT) { c->idct_put = ff_jref_idct_put; c->idct_add = ff_jref_idct_add; c->idct = ff_j_rev_dct; c->perm_type = FF_IDCT_PERM_LIBMPEG2; #if CONFIG_FAANIDCT } else if (avctx->idct_algo == FF_IDCT_FAAN) { c->idct_put = ff_faanidct_put; c->idct_add = ff_faanidct_add; c->idct = ff_faanidct; c->perm_type = FF_IDCT_PERM_NONE; #endif /* CONFIG_FAANIDCT */ } else { // accurate/default c->idct_put = ff_simple_idct_put_8; c->idct_add = ff_simple_idct_add_8; c->idct = ff_simple_idct_8; c->perm_type = FF_IDCT_PERM_NONE; } } } c->put_pixels_clamped = put_pixels_clamped_c; c->put_signed_pixels_clamped = put_signed_pixels_clamped_c; c->add_pixels_clamped = add_pixels_clamped_c; if (CONFIG_MPEG4_DECODER && avctx->idct_algo == FF_IDCT_XVID) ff_xvid_idct_init(c, avctx); if (ARCH_AARCH64) ff_idctdsp_init_aarch64(c, avctx, high_bit_depth); if (ARCH_ALPHA) ff_idctdsp_init_alpha(c, avctx, high_bit_depth); if (ARCH_ARM) ff_idctdsp_init_arm(c, avctx, high_bit_depth); if (ARCH_PPC) ff_idctdsp_init_ppc(c, avctx, high_bit_depth); if (ARCH_X86) ff_idctdsp_init_x86(c, avctx, high_bit_depth); if (ARCH_MIPS) ff_idctdsp_init_mips(c, avctx, high_bit_depth); ff_put_pixels_clamped = c->put_pixels_clamped; ff_add_pixels_clamped = c->add_pixels_clamped; ff_init_scantable_permutation(c->idct_permutation, c->perm_type); }


static void vnc_display_close(VncDisplay *vs) { if (!vs) return; vs->enabled = false; vs->is_unix = false; if (vs->lsock != NULL) { if (vs->lsock_tag) { g_source_remove(vs->lsock_tag); } object_unref(OBJECT(vs->lsock)); vs->lsock = NULL; } vs->ws_enabled = false; if (vs->lwebsock != NULL) { if (vs->lwebsock_tag) { g_source_remove(vs->lwebsock_tag); } object_unref(OBJECT(vs->lwebsock)); vs->lwebsock = NULL; } vs->auth = VNC_AUTH_INVALID; vs->subauth = VNC_AUTH_INVALID; if (vs->tlscreds) { object_unparent(OBJECT(vs->tlscreds)); } g_free(vs->tlsaclname); vs->tlsaclname = NULL; }


void cpu_reset(CPUX86State *env) { int i; memset(env, 0, offsetof(CPUX86State, breakpoints)); tlb_flush(env, 1); env->old_exception = -1; /* init to reset state */ #ifdef CONFIG_SOFTMMU env->hflags |= HF_SOFTMMU_MASK; #endif env->hflags2 |= HF2_GIF_MASK; cpu_x86_update_cr0(env, 0x60000010); env->a20_mask = ~0x0; env->smbase = 0x30000; env->idt.limit = 0xffff; env->gdt.limit = 0xffff; env->ldt.limit = 0xffff; env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT); env->tr.limit = 0xffff; env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT); cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK); cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, DESC_P_MASK | DESC_S_MASK | DESC_W_MASK); env->eip = 0xfff0; env->regs[R_EDX] = env->cpuid_version; env->eflags = 0x2; /* FPU init */ for(i = 0;i < 8; i++) env->fptags[i] = 1; env->fpuc = 0x37f; env->mxcsr = 0x1f80; memset(env->dr, 0, sizeof(env->dr)); env->dr[6] = DR6_FIXED_1; env->dr[7] = DR7_FIXED_1; cpu_breakpoint_remove_all(env, BP_CPU); cpu_watchpoint_remove_all(env, BP_CPU);


static int get_cod(J2kDecoderContext *s, J2kCodingStyle *c, uint8_t *properties) { J2kCodingStyle tmp; int compno; if (s->buf_end - s->buf < 5) return AVERROR(EINVAL); tmp.log2_prec_width = tmp.log2_prec_height = 15; tmp.csty = bytestream_get_byte(&s->buf); if (bytestream_get_byte(&s->buf)){ // progression level av_log(s->avctx, AV_LOG_ERROR, "only LRCP progression supported\n"); return -1; } tmp.nlayers = bytestream_get_be16(&s->buf); tmp.mct = bytestream_get_byte(&s->buf); // multiple component transformation get_cox(s, &tmp); for (compno = 0; compno < s->ncomponents; compno++){ if (!(properties[compno] & HAD_COC)) memcpy(c + compno, &tmp, sizeof(J2kCodingStyle)); } return 0; }


static void create_cps(MaltaState *s, const char *cpu_model, qemu_irq *cbus_irq, qemu_irq *i8259_irq) { Error *err = NULL; s->cps = g_new0(MIPSCPSState, 1); object_initialize(s->cps, sizeof(MIPSCPSState), TYPE_MIPS_CPS); qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default()); object_property_set_str(OBJECT(s->cps), cpu_model, "cpu-model", &err); object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", &err); object_property_set_bool(OBJECT(s->cps), true, "realized", &err); if (err != NULL) { error_report("%s", error_get_pretty(err)); exit(1); } sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1); /* FIXME: When GIC is present then we should use GIC's IRQ 3. Until then CPS exposes CPU's IRQs thus use the default IRQ 2. */ *i8259_irq = get_cps_irq(s->cps, 2); *cbus_irq = NULL; }


void qmp_change_backing_file(const char *device, const char *image_node_name, const char *backing_file, Error **errp) { BlockBackend *blk; BlockDriverState *bs = NULL; AioContext *aio_context; BlockDriverState *image_bs = NULL; Error *local_err = NULL; bool ro; int open_flags; int ret; blk = blk_by_name(device); if (!blk) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found", device); return; } aio_context = blk_get_aio_context(blk); aio_context_acquire(aio_context); if (!blk_is_available(blk)) { error_setg(errp, "Device '%s' has no medium", device); goto out; } bs = blk_bs(blk); image_bs = bdrv_lookup_bs(NULL, image_node_name, &local_err); if (local_err) { error_propagate(errp, local_err); goto out; } if (!image_bs) { error_setg(errp, "image file not found"); goto out; } if (bdrv_find_base(image_bs) == image_bs) { error_setg(errp, "not allowing backing file change on an image " "without a backing file"); goto out; } /* even though we are not necessarily operating on bs, we need it to * determine if block ops are currently prohibited on the chain */ if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_CHANGE, errp)) { goto out; } /* final sanity check */ if (!bdrv_chain_contains(bs, image_bs)) { error_setg(errp, "'%s' and image file are not in the same chain", device); goto out; } /* if not r/w, reopen to make r/w */ open_flags = image_bs->open_flags; ro = bdrv_is_read_only(image_bs); if (ro) { bdrv_reopen(image_bs, open_flags | BDRV_O_RDWR, &local_err); if (local_err) { error_propagate(errp, local_err); goto out; } } ret = bdrv_change_backing_file(image_bs, backing_file, image_bs->drv ? image_bs->drv->format_name : ""); if (ret < 0) { error_setg_errno(errp, -ret, "Could not change backing file to '%s'", backing_file); /* don't exit here, so we can try to restore open flags if * appropriate */ } if (ro) { bdrv_reopen(image_bs, open_flags, &local_err); if (local_err) { error_propagate(errp, local_err); /* will preserve prior errp */ } } out: aio_context_release(aio_context); }


int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned int *slotp, unsigned int *funcp) { const char *p; char *e; unsigned long val; unsigned long dom = 0, bus = 0; unsigned int slot = 0; unsigned int func = 0; p = addr; val = strtoul(p, &e, 16); if (e == p) return -1; if (*e == ':') { bus = val; p = e + 1; val = strtoul(p, &e, 16); if (e == p) return -1; if (*e == ':') { dom = bus; bus = val; p = e + 1; val = strtoul(p, &e, 16); if (e == p) return -1; } } slot = val; if (funcp != NULL) { if (*e != '.') return -1; p = e + 1; val = strtoul(p, &e, 16); if (e == p) return -1; func = val; } /* if funcp == NULL func is 0 */ if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) return -1; if (*e) return -1; /* Note: QEMU doesn't implement domains other than 0 */ if (!pci_find_bus(pci_find_root_bus(dom), bus)) return -1; *domp = dom; *busp = bus; *slotp = slot; if (funcp != NULL) *funcp = func; return 0; }